#include "../simplifier/UseITEContext.h"
#include "../simplifier/AlwaysTrue.h"
#include "../simplifier/AIGSimplifyPropositionalCore.h"
+#include "../simplifier/TransformExtensionality.h"
#include <memory>
namespace BEEV {
NewSolver.setSeed(bm->UserFlags.random_seed);
}
+ TransformExtensionality t(bm);
+ original_input = t.topLevel(original_input);
+
+
+
SOLVER_RETURN_TYPE result;
result = TopLevelSTPAux(NewSolver,
original_input);
// invalid
if (ASTTrue == orig_result)
{
- if (bm->UserFlags.check_counterexample_flag)
- CheckCounterExample(SatSolver.okay());
+ //if (bm->UserFlags.check_counterexample_flag)
+ // CheckCounterExample(SatSolver.okay());
if (bm->UserFlags.stats_flag
|| bm->UserFlags.print_counterexample_flag)
vector<Entry> cache;
vector<vector<ASTNode> > symbols;
+ struct Function
+ {
+ ASTVec params;
+ ASTNode function;
+ string name;
+ };
+
+ HASHMAP <string, Function, BEEV::LETMgr::hashF<std::string> > functions;
+
void checkInvariant()
{
assert(bm.getAssertLevel() == cache.size());
return bm.LookupOrCreateSymbol(name);
}
+ void
+ removeSymbol(ASTNode s)
+ {
+ bool removed=false;
+
+ for (int i=0; i < symbols.back().size(); i++)
+ if (symbols.back()[i] == s)
+ {
+ symbols.back().erase(symbols.back().begin() + i);
+ removed = true;
+ }
+
+ if (!removed)
+ FatalError("Should have been removed...");
+
+ letMgr._parser_symbol_table.erase(s);
+ }
+
+ // Declare a function. We can't keep references to the declared variables though. So rename them..
+ void
+ storeFunction(const string name, const ASTVec& params, const ASTNode& function)
+ {
+ Function f;
+ f.name = name;
+
+ ASTNodeMap fromTo;
+ for (int i=0; i < params.size();i++)
+ {
+ ASTNode p = bm.CreateFreshVariable(params[i].GetIndexWidth(), params[i].GetValueWidth(), "STP_INTERNAL_FUNCTION_NAME");
+ fromTo.insert(make_pair(params[i], p));
+ f.params.push_back(p);
+ }
+ ASTNodeMap cache;
+ f.function = SubstitutionMap::replace(function,fromTo,cache, nf);
+ functions.insert(make_pair(f.name,f));
+ }
+
+ ASTNode
+ applyFunction(const string name, const ASTVec& params)
+ {
+ if (functions.find(name) == functions.end())
+ FatalError("Trying to apply function which has not been defined.");
+
+ Function f;
+ f = functions[string(name)];
+
+ ASTNodeMap fromTo;
+ for (int i=0; i < f.params.size();i++)
+ {
+ if (f.params[i].GetValueWidth() != params[i].GetValueWidth())
+ FatalError("Actual parameters differ from formal");
+
+ if (f.params[i].GetIndexWidth() != params[i].GetIndexWidth())
+ FatalError("Actual parameters differ from formal");
+
+ fromTo.insert(make_pair(f.params[i], params[i]));
+ }
+
+ ASTNodeMap cache;
+ return SubstitutionMap::replace(f.function,fromTo,cache, nf);
+ }
+
+ bool isFunction(const string name)
+ {
+ return (functions.find(name) != functions.end());
+ }
+
+
ASTNode
LookupOrCreateSymbol(string name)
{
//LET Management
class LETMgr
{
- private:
-
- // Hash function for the hash_map of a string..
+ public:
+ // Hash function for the hash_map of a string..
template <class T>
struct hashF {
size_t operator() (const T & x) const {
}
};
+ private:
const ASTNode ASTUndefined;
typedef hash_map<string,ASTNode, hashF<std::string> > MapType;
nptr = BEEV::parserInterface->letMgr.resolveLet(str);
found = true;
}
+ else if (BEEV::parserInterface->isFunction(str))
+ {
+ smt2lval.str = new std::string(str);
+ return FUNCTIONID_TOK;
+ }
+
+
if (found)
{
"set-info" { return NOTES_TOK; }
"set-option" { return OPTION_TOK; }
"declare-fun" { return DECLARE_FUNCTION_TOK; }
+"define-fun" { return DEFINE_FUNCTION_TOK; }
"push" { return PUSH_TOK;}
"pop" { return POP_TOK;}
%start cmd
%type <node> status
-%type <vec> an_formulas an_terms
+%type <vec> an_formulas an_terms function_params an_mixed
-%type <node> an_term an_formula
+
+%type <node> an_term an_formula function_param
%token <uintval> NUMERAL_TOK
%token <str> BVCONST_DECIMAL_TOK
/* We have this so we can parse :smt-lib-version 2.0 */
%token DECIMAL_TOK
-%token <node> FORMID_TOK TERMID_TOK
-%token <str> STRING_TOK
+%token <node> FORMID_TOK TERMID_TOK
+%token <str> STRING_TOK FUNCTIONID_TOK
/* set-info tokens */
%token NOTES_TOK
%token OPTION_TOK
%token DECLARE_FUNCTION_TOK
+%token DEFINE_FUNCTION_TOK
%token FORMULA_TOK
%token PUSH_TOK
%token POP_TOK
{
parserInterface->success();
}
+| LPAREN_TOK DEFINE_FUNCTION_TOK function_decl RPAREN_TOK
+ {
+ parserInterface->success();
+ }
| LPAREN_TOK FORMULA_TOK an_formula RPAREN_TOK
{
parserInterface->AddAssert(*$3);
}
;
+
+function_param:
+LPAREN_TOK STRING_TOK LPAREN_TOK UNDERSCORE_TOK BITVEC_TOK NUMERAL_TOK RPAREN_TOK RPAREN_TOK
+{
+ $$ = new ASTNode(BEEV::parserInterface->LookupOrCreateSymbol($2->c_str()));
+ parserInterface->addSymbol(*$$);
+ $$->SetIndexWidth(0);
+ $$->SetValueWidth($6);
+ delete $2;
+};
+
+/* Returns a vector of parameters.*/
+function_params:
+function_param
+{
+ $$ = new ASTVec;
+ $$->push_back(*$1);
+ delete $1;
+}
+| function_params function_param
+{
+ $$ = $1;
+ $$->push_back(*$2);
+ delete $2;
+};
+
+
+function_decl:
+STRING_TOK LPAREN_TOK function_params RPAREN_TOK LPAREN_TOK UNDERSCORE_TOK BITVEC_TOK NUMERAL_TOK RPAREN_TOK LPAREN_TOK an_term RPAREN_TOK
+{
+ if ($11->GetValueWidth() != $8)
+ {
+ char msg [100];
+ sprintf(msg, "Different bit-widths specified: %d %d", $11->GetValueWidth(), $8);
+ yyerror(msg);
+ }
+
+ BEEV::parserInterface->storeFunction(*$1, *$3, *$11);
+
+ // Next time the variable is used, we want it to be fresh.
+ for (int i = 0; i < $3->size(); i++)
+ BEEV::parserInterface->removeSymbol((*$3)[i]);
+
+ delete $1;
+ delete $3;
+ delete $11;
+}
+|
+STRING_TOK LPAREN_TOK function_params RPAREN_TOK BOOL_TOK an_formula
+{
+ // Check the bitwidth defined/ and actually are the same.
+ BEEV::parserInterface->storeFunction(*$1, *$3, *$6);
+
+ // Next time the variable is used, we want it to be fresh.
+ for (int i = 0; i < $3->size(); i++)
+ BEEV::parserInterface->removeSymbol((*$3)[i]);
+
+ delete $1;
+ delete $3;
+ delete $6;
+}
+;
+
+
status:
STRING_TOK {
{
parserInterface->setPrintSuccess(false);
}
-
;
+
+
var_decl:
STRING_TOK LPAREN_TOK RPAREN_TOK LPAREN_TOK UNDERSCORE_TOK BITVEC_TOK NUMERAL_TOK RPAREN_TOK
{
}
;
+an_mixed:
+an_formula
+{
+ $$ = new ASTVec;
+ if ($1 != NULL) {
+ $$->push_back(*$1);
+ parserInterface->deleteNode($1);
+ }
+}
+|
+an_term
+{
+ $$ = new ASTVec;
+ if ($1 != NULL) {
+ $$->push_back(*$1);
+ parserInterface->deleteNode($1);
+ }
+}
+|
+an_mixed an_formula
+{
+ if ($1 != NULL && $2 != NULL) {
+ $1->push_back(*$2);
+ $$ = $1;
+ parserInterface->deleteNode($2);
+ }
+}
+|
+an_mixed an_term
+{
+ if ($1 != NULL && $2 != NULL) {
+ $1->push_back(*$2);
+ $$ = $1;
+ parserInterface->deleteNode($2);
+ }
+};
+
+
+
an_formulas:
an_formula
{
//Cleanup the LetIDToExprMap
parserInterface->letMgr.CleanupLetIDMap();
}
+| LPAREN_TOK FUNCTIONID_TOK an_mixed RPAREN_TOK
+{
+ $$ = parserInterface->newNode(parserInterface->applyFunction(*$2,*$3));
+ if ($$->GetType() != BOOLEAN_TYPE)
+ yyerror("Must be boolean type");
+ delete $2;
+ delete $3;
+}
;
lets: let lets
$$->SetValueWidth(width);
delete $1;
}
+| LPAREN_TOK FUNCTIONID_TOK an_mixed RPAREN_TOK
+{
+ $$ = parserInterface->newNode(parserInterface->applyFunction(*$2,*$3));
+
+ if ($$->GetType() != BITVECTOR_TYPE)
+ yyerror("Must be bitvector type");
+
+ delete $2;
+ delete $3;
+}
+
;
%%