Improved SMT-LIBv2 language support for unsat cores.
authorMorgan Deters <mdeters@cs.nyu.edu>
Mon, 25 Aug 2014 22:40:06 +0000 (18:40 -0400)
committerMorgan Deters <mdeters@cs.nyu.edu>
Tue, 26 Aug 2014 19:20:32 +0000 (15:20 -0400)
12 files changed:
src/expr/command.cpp
src/expr/command.h
src/main/command_executor.cpp
src/parser/smt2/Smt2.g
src/parser/smt2/smt2.cpp
src/parser/smt2/smt2.h
src/printer/printer.cpp
src/printer/printer.h
src/printer/smt2/smt2_printer.cpp
src/printer/smt2/smt2_printer.h
src/util/unsat_core.cpp
src/util/unsat_core.h

index a070762810a7ab5668e2baa5617731fc898875c9..a3f5170fa5d60d567e8ebee017c1420e1d4b2c00 100644 (file)
@@ -1121,6 +1121,9 @@ std::string GetInstantiationsCommand::getCommandName() const throw() {
 GetUnsatCoreCommand::GetUnsatCoreCommand() throw() {
 }
 
+GetUnsatCoreCommand::GetUnsatCoreCommand(const std::map<Expr, std::string>& names) throw() : d_names(names) {
+}
+
 void GetUnsatCoreCommand::invoke(SmtEngine* smtEngine) throw() {
   try {
     d_result = smtEngine->getUnsatCore();
@@ -1134,18 +1137,23 @@ void GetUnsatCoreCommand::printResult(std::ostream& out, uint32_t verbosity) con
   if(! ok()) {
     this->Command::printResult(out, verbosity);
   } else {
-    d_result.toStream(out);
+    d_result.toStream(out, d_names);
   }
 }
 
+const UnsatCore& GetUnsatCoreCommand::getUnsatCore() const throw() {
+  // of course, this will be empty if the command hasn't been invoked yet
+  return d_result;
+}
+
 Command* GetUnsatCoreCommand::exportTo(ExprManager* exprManager, ExprManagerMapCollection& variableMap) {
-  GetUnsatCoreCommand* c = new GetUnsatCoreCommand();
+  GetUnsatCoreCommand* c = new GetUnsatCoreCommand(d_names);
   c->d_result = d_result;
   return c;
 }
 
 Command* GetUnsatCoreCommand::clone() const {
-  GetUnsatCoreCommand* c = new GetUnsatCoreCommand();
+  GetUnsatCoreCommand* c = new GetUnsatCoreCommand(d_names);
   c->d_result = d_result;
   return c;
 }
index e84c53d09a4faf421aa10b0ee6ad45c41a20a0ec..4d2957b7cd615c2318c98a8cbface18aeea3da50 100644 (file)
@@ -602,11 +602,14 @@ public:
 class CVC4_PUBLIC GetUnsatCoreCommand : public Command {
 protected:
   UnsatCore d_result;
+  std::map<Expr, std::string> d_names;
 public:
   GetUnsatCoreCommand() throw();
+  GetUnsatCoreCommand(const std::map<Expr, std::string>& names) throw();
   ~GetUnsatCoreCommand() throw() {}
   void invoke(SmtEngine* smtEngine) throw();
   void printResult(std::ostream& out, uint32_t verbosity = 2) const throw();
+  const UnsatCore& getUnsatCore() const throw();
   Command* exportTo(ExprManager* exprManager, ExprManagerMapCollection& variableMap);
   Command* clone() const;
   std::string getCommandName() const throw();
index 950728fabdcca3e1053dfaf6a6c6569bc2c8cfc0..fee7e23a2d8dab6b794fea6722900039ed6349f4 100644 (file)
@@ -165,12 +165,12 @@ bool smtEngineInvoke(SmtEngine* smt, Command* cmd, std::ostream *out)
 
 void printStatsIncremental(std::ostream& out, const std::string& prvsStatsString, const std::string& curStatsString) {
   if(prvsStatsString == "") {
-      out << curStatsString;
-      return;
+    out << curStatsString;
+    return;
   }
 
   // read each line
-  // if a number, subtract and add that to parantheses
+  // if a number, subtract and add that to parentheses
   std::istringstream issPrvs(prvsStatsString);
   std::istringstream issCur(curStatsString);
 
index e1547d23dfc4415984581667a0a925728844bd3c..2adad092e2b9a251c0b0870c5a52b785341c9ff5 100644 (file)
@@ -377,9 +377,13 @@ command returns [CVC4::Command* cmd = NULL]
     { cmd = new GetAssignmentCommand(); }
   | /* assertion */
     ASSERT_TOK { PARSER_STATE->checkThatLogicIsSet(); }
+    { PARSER_STATE->clearLastNamedTerm(); }
     term[expr, expr2]
-    { cmd = new AssertCommand(expr, /* inUnsatCore */ PARSER_STATE->lastNamedTerm() == expr);
-      PARSER_STATE->setLastNamedTerm(Expr());
+    { bool inUnsatCore = PARSER_STATE->lastNamedTerm().first == expr;
+      cmd = new AssertCommand(expr, inUnsatCore);
+      if(inUnsatCore) {
+        PARSER_STATE->registerUnsatCoreName(PARSER_STATE->lastNamedTerm());
+      }
     }
   | /* check-sat */
     CHECKSAT_TOK { PARSER_STATE->checkThatLogicIsSet(); }
@@ -398,7 +402,7 @@ command returns [CVC4::Command* cmd = NULL]
     { cmd = new GetProofCommand(); }
   | /* get-unsat-core */
     GET_UNSAT_CORE_TOK { PARSER_STATE->checkThatLogicIsSet(); }
-    { cmd = new GetUnsatCoreCommand(); }
+    { cmd = new GetUnsatCoreCommand(PARSER_STATE->getUnsatCoreNames()); }
   | /* push */
     PUSH_TOK { PARSER_STATE->checkThatLogicIsSet(); }
     ( k=INTEGER_LITERAL
@@ -407,11 +411,13 @@ command returns [CVC4::Command* cmd = NULL]
           cmd = new EmptyCommand();
         } else if(n == 1) {
           PARSER_STATE->pushScope();
+          PARSER_STATE->pushUnsatCoreNameScope();
           cmd = new PushCommand();
         } else {
           CommandSequence* seq = new CommandSequence();
           do {
             PARSER_STATE->pushScope();
+            PARSER_STATE->pushUnsatCoreNameScope();
             Command* c = new PushCommand();
             c->setMuted(n > 1);
             seq->addCommand(c);
@@ -434,11 +440,13 @@ command returns [CVC4::Command* cmd = NULL]
         if(n == 0) {
           cmd = new EmptyCommand();
         } else if(n == 1) {
+          PARSER_STATE->popUnsatCoreNameScope();
           PARSER_STATE->popScope();
           cmd = new PopCommand();
         } else {
           CommandSequence* seq = new CommandSequence();
           do {
+            PARSER_STATE->popUnsatCoreNameScope();
             PARSER_STATE->popScope();
             Command* c = new PopCommand();
             c->setMuted(n > 1);
@@ -1213,7 +1221,7 @@ attribute[CVC4::Expr& expr,CVC4::Expr& retExpr, std::string& attr]
       // define it
       Expr func = PARSER_STATE->mkFunction(name, expr.getType());
       // remember the last term to have been given a :named attribute
-      PARSER_STATE->setLastNamedTerm(expr);
+      PARSER_STATE->setLastNamedTerm(expr, name);
       // bind name to expr with define-fun
       Command* c =
         new DefineNamedFunctionCommand(name, func, std::vector<Expr>(), expr);
index fecccfa44c95adf658bd6eadc9ce0454416a4c0e..21b6a1e5b91e9879c4dd5008f628c8660b78c68a 100644 (file)
@@ -31,6 +31,7 @@ namespace parser {
 Smt2::Smt2(ExprManager* exprManager, Input* input, bool strictMode, bool parseOnly) :
   Parser(exprManager,input,strictMode,parseOnly),
   d_logicSet(false) {
+  d_unsatCoreNames.push(std::map<Expr, std::string>());
   if( !strictModeEnabled() ) {
     addTheory(Smt2::THEORY_CORE);
   }
index 7ecd2e5b182589a322f36dd386d8a922c7d83b5f..290bbc975e200ded0f27cb873cef239fc2f9a375 100644 (file)
 #include "theory/logic_info.h"
 #include "util/abstract_value.h"
 
+#include <string>
 #include <sstream>
+#include <utility>
+#include <stack>
 
 namespace CVC4 {
 
@@ -54,7 +57,9 @@ private:
   bool d_logicSet;
   LogicInfo d_logic;
   std::hash_map<std::string, Kind, StringHashFunction> operatorKindMap;
-  Expr d_lastNamedTerm;
+  std::pair<Expr, std::string> d_lastNamedTerm;
+  // this is a user-context stack
+  std::stack< std::map<Expr, std::string> > d_unsatCoreNames;
 
 protected:
   Smt2(ExprManager* exprManager, Input* input, bool strictMode = false, bool parseOnly = false);
@@ -106,14 +111,34 @@ public:
 
   void includeFile(const std::string& filename);
 
-  void setLastNamedTerm(Expr e) {
-    d_lastNamedTerm = e;
+  void setLastNamedTerm(Expr e, std::string name) {
+    d_lastNamedTerm = std::make_pair(e, name);
   }
 
-  Expr lastNamedTerm() {
+  void clearLastNamedTerm() {
+    d_lastNamedTerm = std::make_pair(Expr(), "");
+  }
+
+  std::pair<Expr, std::string> lastNamedTerm() {
     return d_lastNamedTerm;
   }
 
+  void pushUnsatCoreNameScope() {
+    d_unsatCoreNames.push(d_unsatCoreNames.top());
+  }
+
+  void popUnsatCoreNameScope() {
+    d_unsatCoreNames.pop();
+  }
+
+  void registerUnsatCoreName(std::pair<Expr, std::string> name) {
+    d_unsatCoreNames.top().insert(name);
+  }
+
+  std::map<Expr, std::string> getUnsatCoreNames() {
+    return d_unsatCoreNames.top();
+  }
+
   bool isAbstractValue(const std::string& name) {
     return name.length() >= 2 && name[0] == '@' && name[1] != '0' &&
       name.find_first_not_of("0123456789", 1) == std::string::npos;
index 7a90f5a498363e5306187426d169e93cd9f728b2..dd2e180e1d0d9db0a65d05f335ab59b158dda4d0 100644 (file)
@@ -154,10 +154,16 @@ void Printer::toStream(std::ostream& out, const Model& m) const throw() {
 }/* Printer::toStream(Model) */
 
 void Printer::toStream(std::ostream& out, const UnsatCore& core) const throw() {
+  std::map<Expr, std::string> names;
+  toStream(out, core, names);
+}/* Printer::toStream(UnsatCore) */
+
+void Printer::toStream(std::ostream& out, const UnsatCore& core, const std::map<Expr, std::string>& names) const throw() {
   for(UnsatCore::iterator i = core.begin(); i != core.end(); ++i) {
-    toStream(out, Node::fromExpr(*i), -1, false, -1);
+    AssertCommand cmd(*i);
+    toStream(out, &cmd, -1, false, -1);
     out << std::endl;
   }
-}/* Printer::toStream(UnsatCore) */
+}/* Printer::toStream(UnsatCore, std::map<Expr, std::string>) */
 
 }/* CVC4 namespace */
index 9a9ee19d1dd2e062b63c9d11e533193eec77773d..e0b80ddfc5def86201314a74fd2e49f16c328a25 100644 (file)
@@ -19,6 +19,9 @@
 #ifndef __CVC4__PRINTER__PRINTER_H
 #define __CVC4__PRINTER__PRINTER_H
 
+#include <map>
+#include <string>
+
 #include "util/language.h"
 #include "util/sexpr.h"
 #include "util/model.h"
@@ -106,6 +109,9 @@ public:
   /** Write an UnsatCore out to a stream with this Printer. */
   virtual void toStream(std::ostream& out, const UnsatCore& core) const throw();
 
+  /** Write an UnsatCore out to a stream with this Printer. */
+  virtual void toStream(std::ostream& out, const UnsatCore& core, const std::map<Expr, std::string>& names) const throw();
+
 };/* class Printer */
 
 /**
index 543079576236b22b1f5eb612b09525ccfc6defdc..cb1fe87b281721a5215af911dfdc869eacdd0678 100644 (file)
@@ -771,11 +771,18 @@ void Smt2Printer::toStream(std::ostream& out, const CommandStatus* s) const thro
 }/* Smt2Printer::toStream(CommandStatus*) */
 
 
-void Smt2Printer::toStream(std::ostream& out, const UnsatCore& core) const throw() {
-  out << "(" << endl;
-  this->Printer::toStream(out, core);
+void Smt2Printer::toStream(std::ostream& out, const UnsatCore& core, const std::map<Expr, std::string>& names) const throw() {
+  out << "(" << std::endl;
+  for(UnsatCore::const_iterator i = core.begin(); i != core.end(); ++i) {
+    map<Expr, string>::const_iterator j = names.find(*i);
+    if(j == names.end()) {
+      out << *i << endl;
+    } else {
+      out << (*j).second << endl;
+    }
+  }
   out << ")" << endl;
-}
+}/* Smt2Printer::toStream(UnsatCore, map<Expr, string>) */
 
 
 void Smt2Printer::toStream(std::ostream& out, const Model& m) const throw() {
index e825d3f4c65dad5b180a524061b63ed751216304..dbbc67fc24f0acb86d1afb821d9309822c64ae92 100644 (file)
@@ -46,7 +46,7 @@ public:
   void toStream(std::ostream& out, const Result& r) const throw();
   void toStream(std::ostream& out, const SExpr& sexpr) const throw();
   void toStream(std::ostream& out, const Model& m) const throw();
-  void toStream(std::ostream& out, const UnsatCore& core) const throw();
+  void toStream(std::ostream& out, const UnsatCore& core, const std::map<Expr, std::string>& names) const throw();
 };/* class Smt2Printer */
 
 }/* CVC4::printer::smt2 namespace */
index 6344b3eda8889132474e153ba3cfb8d901a59315..929d5e909c737ea851e703eb916587cd2f15cc24 100644 (file)
@@ -30,15 +30,19 @@ UnsatCore::const_iterator UnsatCore::end() const {
 }
 
 void UnsatCore::toStream(std::ostream& out) const {
-  for(UnsatCore::const_iterator i = begin(); i != end(); ++i) {
-    out << AssertCommand(*i) << std::endl;
-  }
+  smt::SmtScope smts(d_smt);
+  Expr::dag::Scope scope(out, false);
+  Printer::getPrinter(options::outputLanguage())->toStream(out, *this);
 }
 
-std::ostream& operator<<(std::ostream& out, const UnsatCore& core) {
-  smt::SmtScope smts(core.d_smt);
+void UnsatCore::toStream(std::ostream& out, const std::map<Expr, std::string>& names) const {
+  smt::SmtScope smts(d_smt);
   Expr::dag::Scope scope(out, false);
-  Printer::getPrinter(options::outputLanguage())->toStream(out, core);
+  Printer::getPrinter(options::outputLanguage())->toStream(out, *this, names);
+}
+
+std::ostream& operator<<(std::ostream& out, const UnsatCore& core) {
+  core.toStream(out);
   return out;
 }
 
index c67a6e4489056aacb28a8019c54a60f5da1942cc..27cf864886d481ef67dbb2700673f6e596fe6312 100644 (file)
@@ -57,6 +57,7 @@ public:
   const_iterator end() const;
 
   void toStream(std::ostream& out) const;
+  void toStream(std::ostream& out, const std::map<Expr, std::string>& names) const;
 
 };/* class UnsatCore */