#include <cstring>
#include <cstdlib>
#include <cerrno>
+#include "smt/smt_engine.h"
#include "util/language.h"
#include "expr/command.h"
#include "expr/expr.h"
OUTPUT_FILE = 'o',
HELP = 'h',
DEFAULT_DAG_THRESH,
+ EXPAND_DEFINITIONS,
+ COMBINE_ASSERTIONS,
};/* enum */
const struct option longopts[] = {
{ "output-lang", required_argument, NULL, OUTPUT_LANG },
{ "output-language", required_argument, NULL, OUTPUT_LANG },
+ { "expand-definitions", no_argument, NULL, EXPAND_DEFINITIONS },
+ { "combine-assertions", no_argument, NULL, COMBINE_ASSERTIONS },
{ "default-dag-thresh", required_argument, NULL, DEFAULT_DAG_THRESH },
{ "lang", required_argument, NULL, INPUT_LANG },
{ "language", required_argument, NULL, INPUT_LANG },
<< " --input-language | -L set input language (default auto)" << endl
<< " --out | -o set output file (- for stdout)" << endl
<< " --default-dag-thresh=N set DAG threshold" << endl
+ << " --expand-definitions expand define-funs" << endl
+ << " --combine-assertions combine all assertions into one" << endl
<< " --help | -h this help" << endl
<< "Options and input filenames can be intermixed, and order is important." << endl
<< "For instance, \"-O smt2 x -O cvc4 y\" reads file x in smt2 format and"
<< "Comments and formatting are not preserved." << endl;
}
-static void readFile(const char* filename, InputLanguage fromLang, OutputLanguage toLang, ostream* out) {
+static void readFile(const char* filename, InputLanguage fromLang, OutputLanguage toLang, bool expand_definitions, bool combine_assertions, ostream* out) {
if(fromLang == input::LANG_AUTO) {
unsigned len = strlen(filename);
if(len >= 5 && !strcmp(".smt2", filename + len - 5)) {
parserBuilder.withLineBufferedStreamInput(cin);
}
Parser *parser = parserBuilder.build();
+ // we only use the SmtEngine to do definition expansion for us
+ SmtEngine *smt = expand_definitions ? new SmtEngine(&exprMgr) : NULL;
+ // store up the assertions into one big conjunction
+ std::vector<Expr> assertions;
while(Command* cmd = parser->nextCommand()) {
- *out << cmd << endl;
+ if(expand_definitions && dynamic_cast<DefineFunctionCommand*>(cmd) != NULL) {
+ // tell the SmtEngine about the definition, but don't print it
+ cmd->invoke(smt);
+ } else {
+ // have to switch on the command and expand definitions inside it
+ if(expand_definitions && dynamic_cast<AssertCommand*>(cmd) != NULL) {
+ Expr e = static_cast<AssertCommand*>(cmd)->getExpr();
+ delete cmd;
+ cmd = new AssertCommand(smt->expandDefinitions(e));
+ } else if(expand_definitions && dynamic_cast<QueryCommand*>(cmd) != NULL) {
+ Expr e = static_cast<QueryCommand*>(cmd)->getExpr();
+ delete cmd;
+ cmd = new QueryCommand(smt->expandDefinitions(e));
+ } else if(expand_definitions && dynamic_cast<CheckSatCommand*>(cmd) != NULL) {
+ Expr e = static_cast<CheckSatCommand*>(cmd)->getExpr();
+ delete cmd;
+ cmd = new CheckSatCommand(smt->expandDefinitions(e));
+ } else if(expand_definitions && dynamic_cast<SimplifyCommand*>(cmd) != NULL) {
+ Expr e = static_cast<SimplifyCommand*>(cmd)->getTerm();
+ delete cmd;
+ cmd = new SimplifyCommand(smt->expandDefinitions(e));
+ } else if(expand_definitions && dynamic_cast<ExpandDefinitionsCommand*>(cmd) != NULL) {
+ Expr e = static_cast<ExpandDefinitionsCommand*>(cmd)->getTerm();
+ delete cmd;
+ cmd = new ExpandDefinitionsCommand(smt->expandDefinitions(e));
+ } else if(expand_definitions && dynamic_cast<GetValueCommand*>(cmd) != NULL) {
+ vector<Expr> terms = static_cast<GetValueCommand*>(cmd)->getTerms();
+ delete cmd;
+ for(size_t i = 0; i < terms.size(); ++i) {
+ terms[i] = smt->expandDefinitions(terms[i]);
+ }
+ cmd = new GetValueCommand(terms);
+ }
+
+ if(combine_assertions && dynamic_cast<AssertCommand*>(cmd) != NULL) {
+ // store up the assertion, don't print it yet
+ assertions.push_back(static_cast<AssertCommand*>(cmd)->getExpr());
+ } else {
+ if(combine_assertions &&
+ ( dynamic_cast<CheckSatCommand*>(cmd) != NULL ||
+ dynamic_cast<QueryCommand*>(cmd) != NULL ||
+ dynamic_cast<PushCommand*>(cmd) != NULL ||
+ dynamic_cast<PopCommand*>(cmd) != NULL ||
+ dynamic_cast<SimplifyCommand*>(cmd) != NULL ||
+ dynamic_cast<QuitCommand*>(cmd) != NULL )) {
+ // combine all the stored assertions and print them at this point
+ if(!assertions.empty()) {
+ if(assertions.size() > 1) {
+ *out << AssertCommand(exprMgr.mkExpr(kind::AND, assertions)) << endl;
+ } else {
+ *out << AssertCommand(assertions[0]) << endl;
+ }
+ assertions.clear();
+ }
+ }
+
+ // now print the cmd we just parsed
+ *out << cmd << endl;
+ }
+ }
if(dynamic_cast<QuitCommand*>(cmd) != NULL) {
delete cmd;
break;
}
delete cmd;
}
+ if(!assertions.empty()) {
+ if(assertions.size() > 1) {
+ *out << AssertCommand(exprMgr.mkExpr(kind::AND, assertions)) << endl;
+ } else {
+ *out << AssertCommand(assertions[0]) << endl;
+ }
+ assertions.clear();
+ }
*out << flush;
+ delete smt;
delete parser;
}
OutputLanguage toLang = output::LANG_SMTLIB_V2;
size_t files = 0;
int dag_thresh = 1;
+ bool expand_definitions = false;
+ bool combine_assertions = false;
try {
int c;
case 1:
++files;
*out << Expr::dag(dag_thresh);
- readFile(optarg, (!strcmp(optarg, "-") && fromLang == input::LANG_AUTO) ? input::LANG_CVC4 : fromLang, toLang, out);
+ readFile(optarg, (!strcmp(optarg, "-") && fromLang == input::LANG_AUTO) ? input::LANG_CVC4 : fromLang, toLang, expand_definitions, combine_assertions, out);
break;
case INPUT_LANG:
if(!strcmp(optarg, "help")) {
dag_thresh = ul > INT_MAX ? INT_MAX : int(ul);
}
break;
+ case EXPAND_DEFINITIONS:
+ expand_definitions = true;
+ break;
+ case COMBINE_ASSERTIONS:
+ combine_assertions = true;
+ break;
case 'h':
showHelp();
exit(0);
if(files == 0) {
*out << Expr::dag(dag_thresh);
- readFile("-", fromLang == input::LANG_AUTO ? input::LANG_CVC4 : fromLang, toLang, out);
+ readFile("-", fromLang == input::LANG_AUTO ? input::LANG_CVC4 : fromLang, toLang, expand_definitions, combine_assertions, out);
exit(0);
}
} catch(Exception& e) {
/**
* Expand definitions in n.
*/
- Node expandDefinitions(TNode n, hash_map<Node, Node, NodeHashFunction>& cache)
+ Node expandDefinitions(TNode n, hash_map<Node, Node, NodeHashFunction>& cache, bool expandOnly = false)
throw(TypeCheckingException, LogicException);
/**
d_definedFunctions->insert(funcNode, def);
}
-
-
-
-Node SmtEnginePrivate::expandDefinitions(TNode n, hash_map<Node, Node, NodeHashFunction>& cache)
+Node SmtEnginePrivate::expandDefinitions(TNode n, hash_map<Node, Node, NodeHashFunction>& cache, bool expandOnly)
throw(TypeCheckingException, LogicException) {
stack< triple<Node, Node, bool> > worklist;
n.begin(), n.end());
Debug("expand") << "made : " << instance << endl;
- Node expanded = expandDefinitions(instance, cache);
+ Node expanded = expandDefinitions(instance, cache, expandOnly);
cache[n] = (n == expanded ? Node::null() : expanded);
result.push(expanded);
continue;
- } else {
+ } else if(! expandOnly) {
+ // do not do any theory stuff if expandOnly is true
+
theory::Theory* t = d_smt.d_theoryEngine->theoryOf(node);
Assert(t != NULL);
Dump("benchmark") << ExpandDefinitionsCommand(e);
}
hash_map<Node, Node, NodeHashFunction> cache;
- Node n = d_private->expandDefinitions(Node::fromExpr(e), cache);
+ Node n = d_private->expandDefinitions(Node::fromExpr(e), cache, /* expandOnly = */ true);
n = postprocess(n, TypeNode::fromType(e.getType()));
return n.toExpr();