summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Reynolds <andrew.j.reynolds@gmail.com>2019-07-01 16:33:34 -0500
committerGitHub <noreply@github.com>2019-07-01 16:33:34 -0500
commitc3b5f9d57eaf17612170b7401465b75053b07985 (patch)
treeaeef3125d045a21bda899a7f2be22a1da50ebbc3
parentc365521b91520cf05739c7df6f2ae99f273c98d4 (diff)
Support sygus version 2 format (#3066)
-rw-r--r--src/expr/datatype.cpp5
-rw-r--r--src/options/language.cpp22
-rw-r--r--src/options/language.h6
-rw-r--r--src/options/language.i2
-rw-r--r--src/parser/antlr_input.cpp3
-rw-r--r--src/parser/parser_builder.cpp1
-rw-r--r--src/parser/smt2/Smt2.g344
-rw-r--r--src/parser/smt2/smt2.cpp147
-rw-r--r--src/parser/smt2/smt2.h49
-rw-r--r--src/printer/printer.cpp6
-rw-r--r--src/smt/smt_engine.cpp6
-rw-r--r--src/util/result.cpp3
12 files changed, 487 insertions, 107 deletions
diff --git a/src/expr/datatype.cpp b/src/expr/datatype.cpp
index 3b925d0b1..5e1343bb0 100644
--- a/src/expr/datatype.cpp
+++ b/src/expr/datatype.cpp
@@ -180,7 +180,10 @@ void Datatype::addSygusConstructor(Expr op,
{
Debug("dt-sygus") << "--> Add constructor " << cname << " to " << getName() << std::endl;
Debug("dt-sygus") << " sygus op : " << op << std::endl;
- std::string name = getName() + "_" + cname;
+ // avoid name clashes
+ std::stringstream ss;
+ ss << getName() << "_" << getNumConstructors() << "_" << cname;
+ std::string name = ss.str();
std::string testerId("is-");
testerId.append(name);
unsigned cweight = weight >= 0 ? weight : (cargs.empty() ? 0 : 1);
diff --git a/src/options/language.cpp b/src/options/language.cpp
index 4aefd742c..0bd1e144a 100644
--- a/src/options/language.cpp
+++ b/src/options/language.cpp
@@ -79,6 +79,7 @@ InputLanguage toInputLanguage(OutputLanguage language) {
case output::LANG_CVC4:
case output::LANG_Z3STR:
case output::LANG_SYGUS:
+ case output::LANG_SYGUS_V2:
// these entries directly correspond (by design)
return InputLanguage(int(language));
@@ -103,6 +104,7 @@ OutputLanguage toOutputLanguage(InputLanguage language) {
case input::LANG_CVC4:
case input::LANG_Z3STR:
case input::LANG_SYGUS:
+ case input::LANG_SYGUS_V2:
// these entries directly correspond (by design)
return OutputLanguage(int(language));
@@ -155,9 +157,17 @@ OutputLanguage toOutputLanguage(std::string language) {
return output::LANG_Z3STR;
} else if(language == "sygus" || language == "LANG_SYGUS") {
return output::LANG_SYGUS;
- } else if(language == "ast" || language == "LANG_AST") {
+ }
+ else if (language == "sygus2" || language == "LANG_SYGUS_V2")
+ {
+ return output::LANG_SYGUS_V2;
+ }
+ else if (language == "ast" || language == "LANG_AST")
+ {
return output::LANG_AST;
- } else if(language == "auto" || language == "LANG_AUTO") {
+ }
+ else if (language == "auto" || language == "LANG_AUTO")
+ {
return output::LANG_AUTO;
}
@@ -195,7 +205,13 @@ InputLanguage toInputLanguage(std::string language) {
return input::LANG_Z3STR;
} else if(language == "sygus" || language == "LANG_SYGUS") {
return input::LANG_SYGUS;
- } else if(language == "auto" || language == "LANG_AUTO") {
+ }
+ else if (language == "sygus2" || language == "LANG_SYGUS_V2")
+ {
+ return input::LANG_SYGUS_V2;
+ }
+ else if (language == "auto" || language == "LANG_AUTO")
+ {
return input::LANG_AUTO;
}
diff --git a/src/options/language.h b/src/options/language.h
index 4d213c305..eec5ad158 100644
--- a/src/options/language.h
+++ b/src/options/language.h
@@ -64,6 +64,8 @@ enum CVC4_PUBLIC Language
LANG_Z3STR,
/** The SyGuS input language */
LANG_SYGUS,
+ /** The SyGuS input language version 2.0 */
+ LANG_SYGUS_V2,
// START OUTPUT-ONLY LANGUAGES AT ENUM VALUE 10
// THESE ARE IN PRINCIPLE NOT POSSIBLE INPUT LANGUAGES
@@ -103,6 +105,7 @@ inline std::ostream& operator<<(std::ostream& out, Language lang) {
case LANG_SYGUS:
out << "LANG_SYGUS";
break;
+ case LANG_SYGUS_V2: out << "LANG_SYGUS_V2"; break;
default:
out << "undefined_input_language";
}
@@ -147,6 +150,8 @@ enum CVC4_PUBLIC Language
LANG_Z3STR = input::LANG_Z3STR,
/** The sygus output language */
LANG_SYGUS = input::LANG_SYGUS,
+ /** The sygus output language version 2.0 */
+ LANG_SYGUS_V2 = input::LANG_SYGUS_V2,
// START OUTPUT-ONLY LANGUAGES AT ENUM VALUE 10
// THESE ARE IN PRINCIPLE NOT POSSIBLE INPUT LANGUAGES
@@ -186,6 +191,7 @@ inline std::ostream& operator<<(std::ostream& out, Language lang) {
case LANG_SYGUS:
out << "LANG_SYGUS";
break;
+ case LANG_SYGUS_V2: out << "LANG_SYGUS_V2"; break;
case LANG_AST:
out << "LANG_AST";
break;
diff --git a/src/options/language.i b/src/options/language.i
index 177e590f5..59c204400 100644
--- a/src/options/language.i
+++ b/src/options/language.i
@@ -30,6 +30,7 @@ namespace CVC4 {
%rename(INPUT_LANG_MAX) CVC4::language::input::LANG_MAX;
%rename(INPUT_LANG_Z3STR) CVC4::language::input::LANG_Z3STR;
%rename(INPUT_LANG_SYGUS) CVC4::language::input::LANG_SYGUS;
+%rename(INPUT_LANG_SYGUS_V2) CVC4::language::input::LANG_SYGUS_V2;
%rename(OUTPUT_LANG_AUTO) CVC4::language::output::LANG_AUTO;
%rename(OUTPUT_LANG_SMTLIB_V1) CVC4::language::output::LANG_SMTLIB_V1;
@@ -44,5 +45,6 @@ namespace CVC4 {
%rename(OUTPUT_LANG_MAX) CVC4::language::output::LANG_MAX;
%rename(OUTPUT_LANG_Z3STR) CVC4::language::output::LANG_Z3STR;
%rename(OUTPUT_LANG_SYGUS) CVC4::language::output::LANG_SYGUS;
+%rename(OUTPUT_LANG_SYGUS_V2) CVC4::language::output::LANG_SYGUS_V2;
%include "options/language.h"
diff --git a/src/parser/antlr_input.cpp b/src/parser/antlr_input.cpp
index 3e7e86446..69cac434a 100644
--- a/src/parser/antlr_input.cpp
+++ b/src/parser/antlr_input.cpp
@@ -252,8 +252,7 @@ AntlrInput* AntlrInput::newInput(InputLanguage lang, AntlrInputStream& inputStre
break;
case LANG_SYGUS:
- input = new SygusInput(inputStream);
- break;
+ case LANG_SYGUS_V2: input = new SygusInput(inputStream); break;
case LANG_TPTP:
input = new TptpInput(inputStream);
diff --git a/src/parser/parser_builder.cpp b/src/parser/parser_builder.cpp
index f0e6ad284..4ce99ce9d 100644
--- a/src/parser/parser_builder.cpp
+++ b/src/parser/parser_builder.cpp
@@ -94,6 +94,7 @@ Parser* ParserBuilder::build()
parser = new Smt1(d_solver, input, d_strictMode, d_parseOnly);
break;
case language::input::LANG_SYGUS:
+ case language::input::LANG_SYGUS_V2:
parser = new Smt2(d_solver, input, d_strictMode, d_parseOnly);
break;
case language::input::LANG_TPTP:
diff --git a/src/parser/smt2/Smt2.g b/src/parser/smt2/Smt2.g
index b49b62604..d72188c6c 100644
--- a/src/parser/smt2/Smt2.g
+++ b/src/parser/smt2/Smt2.g
@@ -183,8 +183,8 @@ static bool isClosed(const Expr& e, std::set<Expr>& free, std::unordered_set<Exp
static inline bool isClosed(const Expr& e, std::set<Expr>& free) {
std::unordered_set<Expr, ExprHashFunction> cache;
return isClosed(e, free, cache);
-}
-
+}
+
}/* parser::postinclude */
/**
@@ -344,12 +344,17 @@ command [std::unique_ptr<CVC4::Command>* cmd]
"be declared in logic ");
}
// we allow overloading for function declarations
- if (PARSER_STATE->sygus())
+ if (PARSER_STATE->sygus_v1())
{
// it is a higher-order universal variable
Expr func = PARSER_STATE->mkBoundVar(name, t);
cmd->reset(new DeclareSygusFunctionCommand(name, func, t));
}
+ else if( PARSER_STATE->sygus() )
+ {
+ PARSER_STATE->parseErrorLogic("declare-fun are not allowed in sygus "
+ "version 2.0");
+ }
else
{
Expr func = PARSER_STATE->mkVar(name, t, ExprManager::VAR_FLAG_NONE, true);
@@ -416,10 +421,6 @@ command [std::unique_ptr<CVC4::Command>* cmd]
{ cmd->reset(new GetAssignmentCommand()); }
| /* assertion */
ASSERT_TOK { PARSER_STATE->checkThatLogicIsSet(); }
- /* { if( PARSER_STATE->sygus() ){
- * PARSER_STATE->parseError("Sygus does not support assert command.");
- * }
- * } */
{ PARSER_STATE->clearLastNamedTerm(); }
term[expr, expr2]
{ bool inUnsatCore = PARSER_STATE->lastNamedTerm().first == expr;
@@ -624,6 +625,58 @@ sygusCommand [std::unique_ptr<CVC4::Command>* cmd]
}
| /* synth-fun */
+ ( SYNTH_FUN_V1_TOK { isInv = false; }
+ | SYNTH_INV_V1_TOK { isInv = true; range = EXPR_MANAGER->booleanType(); }
+ )
+ { PARSER_STATE->checkThatLogicIsSet(); }
+ symbol[fun,CHECK_UNDECLARED,SYM_VARIABLE]
+ LPAREN_TOK sortedVarList[sortedVarNames] RPAREN_TOK
+ ( sortSymbol[range,CHECK_DECLARED] )?
+ {
+ if (range.isNull())
+ {
+ PARSER_STATE->parseError("Must supply return type for synth-fun.");
+ }
+ if (range.isFunction())
+ {
+ PARSER_STATE->parseError(
+ "Cannot use synth-fun with function return type.");
+ }
+ std::vector<Type> var_sorts;
+ for (const std::pair<std::string, CVC4::Type>& p : sortedVarNames)
+ {
+ var_sorts.push_back(p.second);
+ }
+ Debug("parser-sygus") << "Define synth fun : " << fun << std::endl;
+ Type synth_fun_type = var_sorts.size() > 0
+ ? EXPR_MANAGER->mkFunctionType(var_sorts, range)
+ : range;
+ // we do not allow overloading for synth fun
+ synth_fun = PARSER_STATE->mkBoundVar(fun, synth_fun_type);
+ // set the sygus type to be range by default, which is overwritten below
+ // if a grammar is provided
+ sygus_type = range;
+ // create new scope for parsing the grammar, if any
+ PARSER_STATE->pushScope(true);
+ for (const std::pair<std::string, CVC4::Type>& p : sortedVarNames)
+ {
+ sygus_vars.push_back(PARSER_STATE->mkBoundVar(p.first, p.second));
+ }
+ }
+ (
+ // optionally, read the sygus grammar
+ //
+ // the sygus type specifies the required grammar for synth_fun, expressed
+ // as a type
+ sygusGrammarV1[sygus_type, sygus_vars, fun]
+ )?
+ {
+ PARSER_STATE->popScope();
+ Debug("parser-sygus") << "...read synth fun " << fun << std::endl;
+ cmd->reset(
+ new SynthFunCommand(fun, synth_fun, sygus_type, isInv, sygus_vars));
+ }
+ | /* synth-fun */
( SYNTH_FUN_TOK { isInv = false; }
| SYNTH_INV_TOK { isInv = true; range = EXPR_MANAGER->booleanType(); }
)
@@ -726,7 +779,7 @@ sygusCommand [std::unique_ptr<CVC4::Command>* cmd]
* The argument fun is a unique identifier to avoid naming clashes for the
* datatypes constructed by this call.
*/
-sygusGrammar[CVC4::Type & ret,
+sygusGrammarV1[CVC4::Type & ret,
std::vector<CVC4::Expr>& sygus_vars,
std::string& fun]
@declarations
@@ -889,16 +942,16 @@ sygusGTerm[CVC4::SygusGTerm& sgt, std::string& fun]
PARSER_STATE->pushScope(true);
readingLet = true;
}
- ( LPAREN_TOK
- symbol[sname,CHECK_NONE,SYM_VARIABLE]
- sortSymbol[t,CHECK_DECLARED] {
- Expr v = PARSER_STATE->mkBoundVar(sname,t);
- sgt.d_let_vars.push_back( v );
+ ( LPAREN_TOK
+ symbol[sname,CHECK_NONE,SYM_VARIABLE]
+ sortSymbol[t,CHECK_DECLARED] {
+ Expr v = PARSER_STATE->mkBoundVar(sname,t);
+ sgt.d_let_vars.push_back( v );
sgt.addChild();
- }
+ }
sygusGTerm[sgt.d_children.back(), fun]
RPAREN_TOK )+ RPAREN_TOK
- | SYGUS_CONSTANT_TOK sortSymbol[t,CHECK_DECLARED]
+ | SYGUS_CONSTANT_TOK sortSymbol[t,CHECK_DECLARED]
{ sgt.d_gterm_type = SygusGTerm::gterm_constant;
sgt.d_type = t;
Debug("parser-sygus") << "Sygus grammar constant." << std::endl;
@@ -920,7 +973,7 @@ sygusGTerm[CVC4::SygusGTerm& sgt, std::string& fun]
Debug("parser-sygus") << "Sygus grammar (input) variable."
<< std::endl;
}
- | symbol[name,CHECK_NONE,SYM_VARIABLE] {
+ | symbol[name,CHECK_NONE,SYM_VARIABLE] {
bool isBuiltinOperator = PARSER_STATE->isOperatorEnabled(name);
if(isBuiltinOperator) {
Debug("parser-sygus") << "Sygus grammar " << fun << " : builtin op : "
@@ -959,10 +1012,10 @@ sygusGTerm[CVC4::SygusGTerm& sgt, std::string& fun]
<< sgt.d_children.size() << "..." << std::endl;
sgt.addChild();
}
- )*
+ )*
RPAREN_TOK {
- //pop last child index
- sgt.d_children.pop_back();
+ //pop last child index
+ sgt.d_children.pop_back();
if( readingLet ){
PARSER_STATE->popScope();
}
@@ -978,7 +1031,7 @@ sygusGTerm[CVC4::SygusGTerm& sgt, std::string& fun]
sgt.d_gterm_type = SygusGTerm::gterm_op;
}
| symbol[name,CHECK_NONE,SYM_VARIABLE]
- {
+ {
if( name[0] == '-' ){ //hack for unary minus
Debug("parser-sygus") << "Sygus grammar " << fun
<< " : unary minus integer literal " << name
@@ -1013,6 +1066,138 @@ sygusGTerm[CVC4::SygusGTerm& sgt, std::string& fun]
}
;
+
+/** Reads a sygus grammar in the sygus version 2 format
+ *
+ * The resulting sygus datatype encoding the grammar is stored in ret.
+ * The argument sygusVars indicates the sygus bound variable list, which is
+ * the argument list of the function-to-synthesize (or null if the grammar
+ * has bound variables).
+ * The argument fun is a unique identifier to avoid naming clashes for the
+ * datatypes constructed by this call.
+ */
+sygusGrammar[CVC4::Type & ret,
+ std::vector<CVC4::Expr>& sygusVars,
+ std::string& fun]
+@declarations
+{
+ // the pre-declaration
+ std::vector<std::pair<std::string, Type> > sortedVarNames;
+ // non-terminal symbols of the grammar
+ std::vector<Expr> ntSyms;
+ Type t;
+ std::string name;
+ Expr e, e2;
+ std::vector<CVC4::Datatype> datatypes;
+ std::vector<Type> unresTypes;
+ std::map<Expr, CVC4::Type> ntsToUnres;
+ unsigned dtProcessed = 0;
+ std::unordered_set<unsigned> allowConst;
+}
+ :
+ // predeclaration
+ LPAREN_TOK sortedVarList[sortedVarNames] RPAREN_TOK
+ {
+ // non-terminal symbols in the pre-declaration are locally scoped
+ PARSER_STATE->pushScope(true);
+ for (std::pair<std::string, CVC4::Type>& i : sortedVarNames)
+ {
+ Trace("parser-sygus2") << "Declare datatype " << i.first << std::endl;
+ // make the datatype, which encodes terms generated by this non-terminal
+ std::stringstream ss;
+ ss << "dt_" << fun << "_" << i.first;
+ std::string dname = ss.str();
+ datatypes.push_back(Datatype(dname));
+ // make its unresolved type, used for referencing the final version of
+ // the datatype
+ PARSER_STATE->checkDeclaration(dname, CHECK_UNDECLARED, SYM_SORT);
+ Type urt = PARSER_STATE->mkUnresolvedType(dname);
+ unresTypes.push_back(urt);
+ // make the non-terminal symbol, which will be parsed as an ordinary
+ // free variable.
+ Expr nts = PARSER_STATE->mkBoundVar(i.first, i.second);
+ ntSyms.push_back(nts);
+ ntsToUnres[nts] = urt;
+ }
+ }
+ // the grouped rule listing
+ LPAREN_TOK
+ (
+ LPAREN_TOK
+ symbol[name, CHECK_DECLARED, SYM_VARIABLE] sortSymbol[t, CHECK_DECLARED]
+ {
+ // check that it matches sortedVarNames
+ if (sortedVarNames[dtProcessed].first != name)
+ {
+ std::stringstream sse;
+ sse << "Grouped rule listing " << name
+ << " does not match the name (in order) from the predeclaration ("
+ << sortedVarNames[dtProcessed].first << ")." << std::endl;
+ PARSER_STATE->parseError(sse.str().c_str());
+ }
+ if (sortedVarNames[dtProcessed].second != t)
+ {
+ std::stringstream sse;
+ sse << "Type for grouped rule listing " << name
+ << " does not match the type (in order) from the predeclaration ("
+ << sortedVarNames[dtProcessed].second << ")." << std::endl;
+ PARSER_STATE->parseError(sse.str().c_str());
+ }
+ }
+ LPAREN_TOK
+ (
+ term[e,e2] {
+ // add term as constructor to datatype
+ PARSER_STATE->addSygusConstructorTerm(
+ datatypes[dtProcessed], e, ntsToUnres);
+ }
+ | LPAREN_TOK SYGUS_CONSTANT_TOK sortSymbol[t, CHECK_DECLARED] RPAREN_TOK {
+ // allow constants in datatypes[dtProcessed]
+ allowConst.insert(dtProcessed);
+ }
+ | LPAREN_TOK SYGUS_VARIABLE_TOK sortSymbol[t, CHECK_DECLARED] RPAREN_TOK {
+ // add variable constructors to datatype
+ PARSER_STATE->addSygusConstructorVariables(
+ datatypes[dtProcessed], sygusVars, t);
+ }
+ )*
+ RPAREN_TOK
+ RPAREN_TOK
+ {
+ dtProcessed++;
+ }
+ )*
+ RPAREN_TOK
+ {
+ if (dtProcessed != sortedVarNames.size())
+ {
+ PARSER_STATE->parseError(
+ "Number of grouped rule listings does not match "
+ "number of symbols in predeclaration.");
+ }
+ Expr bvl;
+ if (!sygusVars.empty())
+ {
+ bvl = MK_EXPR(kind::BOUND_VAR_LIST, sygusVars);
+ }
+ Trace("parser-sygus2") << "Process " << dtProcessed << " sygus datatypes..." << std::endl;
+ for (unsigned i = 0; i < dtProcessed; i++)
+ {
+ bool aci = allowConst.find(i)!=allowConst.end();
+ Type btt = sortedVarNames[i].second;
+ datatypes[i].setSygus(btt, bvl, aci, false);
+ }
+ // pop scope from the pre-declaration
+ PARSER_STATE->popScope();
+ // now, make the sygus datatype
+ Trace("parser-sygus2") << "Make the sygus datatypes..." << std::endl;
+ std::vector<DatatypeType> datatypeTypes =
+ PARSER_STATE->mkMutualDatatypeTypes(datatypes);
+ // return is the first datatype
+ ret = datatypeTypes[0];
+ }
+;
+
// Separate this into its own rule (can be invoked by set-info or meta-info)
metaInfoInternal[std::unique_ptr<CVC4::Command>* cmd]
@declarations {
@@ -1109,7 +1294,7 @@ smt25Command[std::unique_ptr<CVC4::Command>* cmd]
PARSER_STATE->pushDefineFunRecScope(sortedVarNames, func, flattenVars, bvs, true );
}
term[expr, expr2]
- { PARSER_STATE->popScope();
+ { PARSER_STATE->popScope();
if( !flattenVars.empty() ){
expr = PARSER_STATE->mkHoApply( expr, flattenVars );
}
@@ -1140,8 +1325,8 @@ smt25Command[std::unique_ptr<CVC4::Command>* cmd]
)+
RPAREN_TOK
LPAREN_TOK
- {
- //set up the first scope
+ {
+ //set up the first scope
if( sortedVarNamesList.empty() ){
PARSER_STATE->parseError("Must define at least one function in "
"define-funs-rec");
@@ -1152,7 +1337,7 @@ smt25Command[std::unique_ptr<CVC4::Command>* cmd]
}
(
term[expr,expr2]
- {
+ {
unsigned j = func_defs.size();
if( !flattenVarsList[j].empty() ){
expr = PARSER_STATE->mkHoApply( expr, flattenVarsList[j] );
@@ -1160,11 +1345,11 @@ smt25Command[std::unique_ptr<CVC4::Command>* cmd]
func_defs.push_back( expr );
formals.push_back(bvs);
j++;
- //set up the next scope
+ //set up the next scope
PARSER_STATE->popScope();
if( func_defs.size()<funcs.size() ){
bvs.clear();
- PARSER_STATE->pushDefineFunRecScope( sortedVarNamesList[j], funcs[j],
+ PARSER_STATE->pushDefineFunRecScope( sortedVarNamesList[j], funcs[j],
flattenVarsList[j], bvs, true);
}
}
@@ -1246,7 +1431,7 @@ extendedCommand[std::unique_ptr<CVC4::Command>* cmd]
}
)+
RPAREN_TOK
- { cmd->reset(seq.release()); }
+ { cmd->reset(seq.release()); }
| DECLARE_PREDS_TOK { PARSER_STATE->checkThatLogicIsSet(); }
{ seq.reset(new CVC4::CommandSequence()); }
LPAREN_TOK
@@ -1344,8 +1529,8 @@ extendedCommand[std::unique_ptr<CVC4::Command>* cmd]
| GET_QE_DISJUNCT_TOK { PARSER_STATE->checkThatLogicIsSet(); }
term[e,e2]
{ cmd->reset(new GetQuantifierEliminationCommand(e, false)); }
- | DECLARE_HEAP LPAREN_TOK
- sortSymbol[t,CHECK_DECLARED]
+ | DECLARE_HEAP LPAREN_TOK
+ sortSymbol[t,CHECK_DECLARED]
sortSymbol[t, CHECK_DECLARED]
// We currently do nothing with the type information declared for the heap.
{ cmd->reset(new EmptyCommand()); }
@@ -1374,8 +1559,8 @@ datatypes_2_5_DefCommand[bool isCo, std::unique_ptr<CVC4::Command>* cmd]
cmd->reset(new DatatypeDeclarationCommand(PARSER_STATE->mkMutualDatatypeTypes(dts, true)));
}
;
-
-datatypeDefCommand[bool isCo, std::unique_ptr<CVC4::Command>* cmd]
+
+datatypeDefCommand[bool isCo, std::unique_ptr<CVC4::Command>* cmd]
@declarations {
std::vector<CVC4::Datatype> dts;
std::string name;
@@ -1390,7 +1575,7 @@ datatypeDefCommand[bool isCo, std::unique_ptr<CVC4::Command>* cmd]
}
datatypesDef[isCo, dnames, arities, cmd]
;
-
+
datatypesDefCommand[bool isCo, std::unique_ptr<CVC4::Command>* cmd]
@declarations {
std::vector<CVC4::Datatype> dts;
@@ -1407,8 +1592,8 @@ datatypesDefCommand[bool isCo, std::unique_ptr<CVC4::Command>* cmd]
arities.push_back( static_cast<int>(arity) );
}
)*
- RPAREN_TOK
- LPAREN_TOK
+ RPAREN_TOK
+ LPAREN_TOK
datatypesDef[isCo, dnames, arities, cmd]
RPAREN_TOK
;
@@ -1429,7 +1614,7 @@ datatypesDef[bool isCo,
}
: { PARSER_STATE->pushScope(true); }
( LPAREN_TOK {
- params.clear();
+ params.clear();
Debug("parser-dt") << "Processing datatype #" << dts.size() << std::endl;
if( dts.size()>=dnames.size() ){
PARSER_STATE->parseError("Too many datatypes defined in this block.");
@@ -1449,7 +1634,7 @@ datatypesDef[bool isCo,
}
LPAREN_TOK
( LPAREN_TOK constructorDef[dts.back()] RPAREN_TOK )+
- RPAREN_TOK { PARSER_STATE->popScope(); }
+ RPAREN_TOK { PARSER_STATE->popScope(); }
| { // if the arity was fixed by prelude and is not equal to 0
if( arities[dts.size()]>0 ){
PARSER_STATE->parseError("No parameters given for datatype.");
@@ -1463,7 +1648,7 @@ datatypesDef[bool isCo,
)+
{
PARSER_STATE->popScope();
- cmd->reset(new DatatypeDeclarationCommand(PARSER_STATE->mkMutualDatatypeTypes(dts, true)));
+ cmd->reset(new DatatypeDeclarationCommand(PARSER_STATE->mkMutualDatatypeTypes(dts, true)));
}
;
@@ -1661,7 +1846,7 @@ term[CVC4::Expr& expr, CVC4::Expr& expr2]
: termNonVariable[expr, expr2]
/* a variable */
| symbol[name,CHECK_DECLARED,SYM_VARIABLE]
- { expr = PARSER_STATE->getExpressionForName(name);
+ { expr = PARSER_STATE->getExpressionForName(name);
assert( !expr.isNull() );
}
;
@@ -1701,7 +1886,7 @@ termNonVariable[CVC4::Expr& expr, CVC4::Expr& expr2]
if(readVariable) {
Trace("parser-overloading") << "Getting variable expression of type " << name << " with type " << type << std::endl;
// get the variable expression for the type
- f = PARSER_STATE->getExpressionForNameAndType(name, type);
+ f = PARSER_STATE->getExpressionForNameAndType(name, type);
assert( !f.isNull() );
}
if(f.getKind() == CVC4::kind::APPLY_CONSTRUCTOR && type.isDatatype()) {
@@ -1784,10 +1969,6 @@ termNonVariable[CVC4::Expr& expr, CVC4::Expr& expr2]
PARSER_STATE->checkDeclaration(name, CHECK_DECLARED, SYM_VARIABLE);
expr = PARSER_STATE->getVariable(name);
if(!expr.isNull()) {
- //hack to allow constants with parentheses (disabled for now)
- //if( PARSER_STATE->sygus() && !PARSER_STATE->isFunctionLike(expr) ){
- // op = PARSER_STATE->getVariable(name);
- //}else{
PARSER_STATE->checkFunctionLike(expr);
kind = PARSER_STATE->getKindForFunction(expr);
args.push_back(expr);
@@ -1907,7 +2088,7 @@ termNonVariable[CVC4::Expr& expr, CVC4::Expr& expr2]
}
| LPAREN_TOK
( /* An indexed function application */
- indexedFunctionName[op, kind] termList[args,expr] RPAREN_TOK {
+ indexedFunctionName[op, kind] termList[args,expr] RPAREN_TOK {
if(kind==CVC4::kind::APPLY_SELECTOR) {
//tuple selector case
Integer x = op.getConst<CVC4::Rational>().getNumerator();
@@ -1969,7 +2150,7 @@ termNonVariable[CVC4::Expr& expr, CVC4::Expr& expr2]
}
)
| /* a let or sygus let binding */
- LPAREN_TOK (
+ LPAREN_TOK (
LET_TOK LPAREN_TOK
{ PARSER_STATE->pushScope(true); }
( LPAREN_TOK symbol[name,CHECK_NONE,SYM_VARIABLE]
@@ -2022,19 +2203,19 @@ termNonVariable[CVC4::Expr& expr, CVC4::Expr& expr2]
}
}
LPAREN_TOK
- (
+ (
/* match cases */
- LPAREN_TOK INDEX_TOK term[f, f2] {
+ LPAREN_TOK INDEX_TOK term[f, f2] {
if( match_vindex==-1 ){
- match_vindex = (int)patexprs.size();
+ match_vindex = (int)patexprs.size();
}
- patexprs.push_back( f );
+ patexprs.push_back( f );
patconds.push_back(MK_CONST(bool(true)));
}
RPAREN_TOK
- | LPAREN_TOK LPAREN_TOK term[f, f2] {
- args.clear();
- PARSER_STATE->pushScope(true);
+ | LPAREN_TOK LPAREN_TOK term[f, f2] {
+ args.clear();
+ PARSER_STATE->pushScope(true);
//f should be a constructor
type = f.getType();
Debug("parser-dt") << "Pattern head : " << f << " " << f.getType() << std::endl;
@@ -2057,7 +2238,7 @@ termNonVariable[CVC4::Expr& expr, CVC4::Expr& expr2]
}
)*
RPAREN_TOK
- term[f3, f2] {
+ term[f3, f2] {
const DatatypeConstructor& dtc = Datatype::datatypeOf(f)[Datatype::indexOf(f)];
if( args.size()!=dtc.getNumArgs() ){
PARSER_STATE->parseError("Bad number of arguments for application of constructor in pattern.");
@@ -2077,7 +2258,7 @@ termNonVariable[CVC4::Expr& expr, CVC4::Expr& expr2]
patexprs.push_back( MK_EXPR( CVC4::kind::APPLY_UF, aargs ) );
patconds.push_back( MK_EXPR( CVC4::kind::APPLY_TESTER, dtc.getTester(), expr ) );
}
- RPAREN_TOK
+ RPAREN_TOK
{ PARSER_STATE->popScope(); }
| LPAREN_TOK symbol[name,CHECK_DECLARED,SYM_VARIABLE] {
f = PARSER_STATE->getVariable(name);
@@ -2093,7 +2274,7 @@ termNonVariable[CVC4::Expr& expr, CVC4::Expr& expr2]
}
RPAREN_TOK
)+
- RPAREN_TOK RPAREN_TOK {
+ RPAREN_TOK RPAREN_TOK {
if( match_vindex==-1 ){
const Datatype& dt = ((DatatypeType)expr.getType()).getDatatype();
std::map< unsigned, bool > processed;
@@ -2153,7 +2334,7 @@ termNonVariable[CVC4::Expr& expr, CVC4::Expr& expr2]
args.push_back(f2);
}
- if( body.getKind()==kind::IMPLIES ){
+ if( body.getKind()==kind::IMPLIES ){
kind = kind::RR_DEDUCTION;
}else if( body.getKind()==kind::EQUAL ){
kind = body[0].getType().isBoolean() ? kind::RR_REDUCTION : kind::RR_REWRITE;
@@ -2240,7 +2421,7 @@ termAtomic[CVC4::api::Term& atomTerm]
// Constants using indexed identifiers, e.g. (_ +oo 8 24) (positive infinity
// as a 32-bit floating-point constant)
- | LPAREN_TOK INDEX_TOK
+ | LPAREN_TOK INDEX_TOK
( EMP_TOK
sortSymbol[type,CHECK_DECLARED]
sortSymbol[type2,CHECK_DECLARED]
@@ -2277,7 +2458,7 @@ termAtomic[CVC4::api::Term& atomTerm]
| str[s,false] { atomTerm = SOLVER->mkString(s, true); }
// NOTE: Theory constants go here
-
+
// Empty tuple constant
| TUPLE_CONST_TOK
{
@@ -2285,7 +2466,7 @@ termAtomic[CVC4::api::Term& atomTerm]
std::vector<api::Term>());
}
;
-
+
/**
* Read attribute
*/
@@ -2453,7 +2634,7 @@ indexedFunctionName[CVC4::Expr& op, CVC4::Kind& kind]
kind = CVC4::kind::APPLY_SELECTOR;
//put m in op so that the caller (termNonVariable) can deal with this case
op = MK_CONST(Rational(AntlrInput::tokenToUnsigned($m)));
- }
+ }
| sym=SIMPLE_SYMBOL nonemptyNumeralList[numerals]
{
op = PARSER_STATE->mkIndexedOp(AntlrInput::tokenText($sym), numerals)
@@ -2604,7 +2785,7 @@ sortSymbol[CVC4::Type& t, CVC4::parser::DeclarationCheck check]
symbol[name,CHECK_NONE,SYM_SORT]
( nonemptyNumeralList[numerals]
{ // allow sygus inputs to elide the `_'
- if( !indexed && !PARSER_STATE->sygus() ) {
+ if( !indexed && !PARSER_STATE->sygus_v1() ) {
std::stringstream ss;
ss << "SMT-LIB requires use of an indexed sort here, e.g. (_ " << name
<< " ...)";
@@ -2658,7 +2839,7 @@ sortSymbol[CVC4::Type& t, CVC4::parser::DeclarationCheck check]
}
t = EXPR_MANAGER->mkSetType( args[0] );
} else if(name == "Tuple") {
- t = EXPR_MANAGER->mkTupleType(args);
+ t = EXPR_MANAGER->mkTupleType(args);
} else if(check == CHECK_DECLARED ||
PARSER_STATE->isDeclared(name, SYM_SORT)) {
t = PARSER_STATE->getSort(name, args);
@@ -2719,19 +2900,6 @@ symbol[std::string& id,
PARSER_STATE->checkDeclaration(id, check, type);
}
}
- |
- /* these are keywords in SyGuS but we don't want to inhibit their
- * use as symbols in SMT-LIB */
- ( SET_OPTIONS_TOK { id = "set-options"; }
- | DECLARE_VAR_TOK { id = "declare-var"; }
- | DECLARE_PRIMED_VAR_TOK { id = "declare-primed-var"; }
- | SYNTH_FUN_TOK { id = "synth-fun"; }
- | SYNTH_INV_TOK { id = "synth-inv"; }
- | CONSTRAINT_TOK { id = "constraint"; }
- | INV_CONSTRAINT_TOK { id = "inv-constraint"; }
- | CHECK_SYNTH_TOK { id = "check-synth"; }
- )
- { PARSER_STATE->checkDeclaration(id, check, type); }
| QUOTED_SYMBOL
{ id = AntlrInput::tokenText($QUOTED_SYMBOL);
/* strip off the quotes */
@@ -2845,8 +3013,8 @@ GET_UNSAT_CORE_TOK : 'get-unsat-core';
EXIT_TOK : 'exit';
RESET_TOK : { PARSER_STATE->v2_5() }? 'reset';
RESET_ASSERTIONS_TOK : 'reset-assertions';
-LET_TOK : { !PARSER_STATE->sygus() }? 'let';
-SYGUS_LET_TOK : { PARSER_STATE->sygus() }? 'let';
+LET_TOK : { !PARSER_STATE->sygus_v1() }? 'let';
+SYGUS_LET_TOK : { PARSER_STATE->sygus_v1() }? 'let';
ATTRIBUTE_TOK : '!';
LPAREN_TOK : '(';
RPAREN_TOK : ')';
@@ -2890,18 +3058,20 @@ GET_QE_DISJUNCT_TOK : 'get-qe-disjunct';
DECLARE_HEAP : 'declare-heap';
// SyGuS commands
-SYNTH_FUN_TOK : { PARSER_STATE->sygus() }? 'synth-fun';
-SYNTH_INV_TOK : { PARSER_STATE->sygus() }? 'synth-inv';
-CHECK_SYNTH_TOK : { PARSER_STATE->sygus() }? 'check-synth';
-DECLARE_VAR_TOK : { PARSER_STATE->sygus() }? 'declare-var';
-DECLARE_PRIMED_VAR_TOK : { PARSER_STATE->sygus() }? 'declare-primed-var';
-CONSTRAINT_TOK : { PARSER_STATE->sygus() }? 'constraint';
-INV_CONSTRAINT_TOK : { PARSER_STATE->sygus() }? 'inv-constraint';
+SYNTH_FUN_V1_TOK : { PARSER_STATE->sygus_v1() }?'synth-fun';
+SYNTH_FUN_TOK : { PARSER_STATE->sygus() && !PARSER_STATE->sygus_v1() }?'synth-fun';
+SYNTH_INV_V1_TOK : { PARSER_STATE->sygus_v1()}?'synth-inv';
+SYNTH_INV_TOK : { PARSER_STATE->sygus() && !PARSER_STATE->sygus_v1()}?'synth-inv';
+CHECK_SYNTH_TOK : { PARSER_STATE->sygus()}?'check-synth';
+DECLARE_VAR_TOK : { PARSER_STATE->sygus()}?'declare-var';
+DECLARE_PRIMED_VAR_TOK : { PARSER_STATE->sygus_v1() }?'declare-primed-var';
+CONSTRAINT_TOK : { PARSER_STATE->sygus()}?'constraint';
+INV_CONSTRAINT_TOK : { PARSER_STATE->sygus()}?'inv-constraint';
SET_OPTIONS_TOK : { PARSER_STATE->sygus() }? 'set-options';
SYGUS_CONSTANT_TOK : { PARSER_STATE->sygus() }? 'Constant';
SYGUS_VARIABLE_TOK : { PARSER_STATE->sygus() }? 'Variable';
-SYGUS_INPUT_VARIABLE_TOK : { PARSER_STATE->sygus() }? 'InputVariable';
-SYGUS_LOCAL_VARIABLE_TOK : { PARSER_STATE->sygus() }? 'LocalVariable';
+SYGUS_INPUT_VARIABLE_TOK : { PARSER_STATE->sygus_v1() }? 'InputVariable';
+SYGUS_LOCAL_VARIABLE_TOK : { PARSER_STATE->sygus_v1() }? 'LocalVariable';
// attributes
ATTRIBUTE_PATTERN_TOK : ':pattern';
@@ -3031,7 +3201,7 @@ STRING_LITERAL
| { PARSER_STATE->escapeDupDblQuote() }?=>
'"' (~('"') | '""')* '"'
;
-
+
/**
* Matches the comments and ignores them
*/
diff --git a/src/parser/smt2/smt2.cpp b/src/parser/smt2/smt2.cpp
index c072c535f..54dfa51c9 100644
--- a/src/parser/smt2/smt2.cpp
+++ b/src/parser/smt2/smt2.cpp
@@ -497,15 +497,17 @@ bool Smt2::logicIsSet() {
}
Expr Smt2::getExpressionForNameAndType(const std::string& name, Type t) {
- if(sygus() && name[0]=='-' &&
- name.find_first_not_of("0123456789", 1) == std::string::npos) {
- //allow unary minus in sygus
+ if (sygus_v1() && name[0] == '-'
+ && name.find_first_not_of("0123456789", 1) == std::string::npos)
+ {
+ // allow unary minus in sygus version 1
return getExprManager()->mkConst(Rational(name));
- }else if(isAbstractValue(name)) {
+ }
+ else if (isAbstractValue(name))
+ {
return mkAbstractValue(name);
- }else{
- return Parser::getExpressionForNameAndType(name, t);
}
+ return Parser::getExpressionForNameAndType(name, t);
}
api::Term Smt2::mkIndexedConstant(const std::string& name,
@@ -644,7 +646,8 @@ Command* Smt2::setLogic(std::string name, bool fromCommand)
}
}
- if(sygus()) {
+ if (sygus_v1())
+ {
// non-smt2-standard sygus logic names go here (http://sygus.seas.upenn.edu/files/sygus.pdf Section 3.2)
if(name == "Arrays") {
name = "A";
@@ -741,6 +744,17 @@ Command* Smt2::setLogic(std::string name, bool fromCommand)
}
} /* Smt2::setLogic() */
+bool Smt2::sygus() const
+{
+ InputLanguage ilang = getLanguage();
+ return ilang == language::input::LANG_SYGUS
+ || ilang == language::input::LANG_SYGUS_V2;
+}
+bool Smt2::sygus_v1() const
+{
+ return getLanguage() == language::input::LANG_SYGUS;
+}
+
void Smt2::setInfo(const std::string& flag, const SExpr& sexpr) {
// TODO: ???
}
@@ -1431,6 +1445,125 @@ Expr Smt2::makeSygusBoundVarList(Datatype& dt,
return getExprManager()->mkExpr(kind::BOUND_VAR_LIST, lvars);
}
+void Smt2::addSygusConstructorTerm(Datatype& dt,
+ Expr term,
+ std::map<Expr, Type>& ntsToUnres) const
+{
+ Trace("parser-sygus2") << "Add sygus cons term " << term << std::endl;
+ // purify each occurrence of a non-terminal symbol in term, replace by
+ // free variables. These become arguments to constructors. Notice we must do
+ // a tree traversal in this function, since unique paths to the same term
+ // should be treated as distinct terms.
+ // Notice that let expressions are forbidden in the input syntax of term, so
+ // this does not lead to exponential behavior with respect to input size.
+ std::vector<Expr> args;
+ std::vector<Type> cargs;
+ Expr op = purifySygusGTerm(term, ntsToUnres, args, cargs);
+ Trace("parser-sygus2") << "Purified operator " << op
+ << ", #args/cargs=" << args.size() << "/"
+ << cargs.size() << std::endl;
+ std::shared_ptr<SygusPrintCallback> spc;
+ // callback prints as the expression
+ spc = std::make_shared<printer::SygusExprPrintCallback>(op, args);
+ if (!args.empty())
+ {
+ bool pureVar = false;
+ if (op.getNumChildren() == args.size())
+ {
+ pureVar = true;
+ for (unsigned i = 0, nchild = op.getNumChildren(); i < nchild; i++)
+ {
+ if (op[i] != args[i])
+ {
+ pureVar = false;
+ break;
+ }
+ }
+ }
+ Trace("parser-sygus2") << "Pure var is " << pureVar
+ << ", hasOp=" << op.hasOperator() << std::endl;
+ if (pureVar && op.hasOperator())
+ {
+ // optimization: use just the operator if it an application to only vars
+ op = op.getOperator();
+ }
+ else
+ {
+ Expr lbvl = getExprManager()->mkExpr(kind::BOUND_VAR_LIST, args);
+ // its operator is a lambda
+ op = getExprManager()->mkExpr(kind::LAMBDA, lbvl, op);
+ }
+ }
+ Trace("parser-sygus2") << "Generated operator " << op << std::endl;
+ std::stringstream ss;
+ ss << op.getKind();
+ dt.addSygusConstructor(op, ss.str(), cargs, spc);
+}
+
+Expr Smt2::purifySygusGTerm(Expr term,
+ std::map<Expr, Type>& ntsToUnres,
+ std::vector<Expr>& args,
+ std::vector<Type>& cargs) const
+{
+ Trace("parser-sygus2-debug")
+ << "purifySygusGTerm: " << term << " #nchild=" << term.getNumChildren()
+ << std::endl;
+ std::map<Expr, Type>::iterator itn = ntsToUnres.find(term);
+ if (itn != ntsToUnres.end())
+ {
+ Expr ret = getExprManager()->mkBoundVar(term.getType());
+ Trace("parser-sygus2-debug")
+ << "...unresolved non-terminal, intro " << ret << std::endl;
+ args.push_back(ret);
+ cargs.push_back(itn->second);
+ return ret;
+ }
+ std::vector<Expr> pchildren;
+ // To test whether the operator should be passed to mkExpr below, we check
+ // whether this term has an operator which is not constant. This includes
+ // APPLY_UF terms, but excludes applications of interpreted symbols.
+ if (term.hasOperator() && !term.getOperator().isConst())
+ {
+ pchildren.push_back(term.getOperator());
+ }
+ bool childChanged = false;
+ for (unsigned i = 0, nchild = term.getNumChildren(); i < nchild; i++)
+ {
+ Trace("parser-sygus2-debug")
+ << "......purify child " << i << " : " << term[i] << std::endl;
+ Expr ptermc = purifySygusGTerm(term[i], ntsToUnres, args, cargs);
+ pchildren.push_back(ptermc);
+ childChanged = childChanged || ptermc != term[i];
+ }
+ if (!childChanged)
+ {
+ Trace("parser-sygus2-debug") << "...no child changed" << std::endl;
+ return term;
+ }
+ Expr nret = getExprManager()->mkExpr(term.getKind(), pchildren);
+ Trace("parser-sygus2-debug")
+ << "...child changed, return " << nret << std::endl;
+ return nret;
+}
+
+void Smt2::addSygusConstructorVariables(Datatype& dt,
+ std::vector<Expr>& sygusVars,
+ Type type) const
+{
+ // each variable of appropriate type becomes a sygus constructor in dt.
+ for (unsigned i = 0, size = sygusVars.size(); i < size; i++)
+ {
+ Expr v = sygusVars[i];
+ if (v.getType() == type)
+ {
+ std::stringstream ss;
+ ss << v;
+ std::vector<CVC4::Type> cargs;
+ dt.addSygusConstructor(v, ss.str(), cargs);
+ }
+ }
+}
+
InputLanguage Smt2::getLanguage() const
{
ExprManager* em = getExprManager();
diff --git a/src/parser/smt2/smt2.h b/src/parser/smt2/smt2.h
index 2ac796166..3afbcd61a 100644
--- a/src/parser/smt2/smt2.h
+++ b/src/parser/smt2/smt2.h
@@ -233,8 +233,10 @@ class Smt2 : public Parser
{
return language::isInputLang_smt2_6(getLanguage(), exact);
}
-
- bool sygus() const { return getLanguage() == language::input::LANG_SYGUS; }
+ /** Are we using a sygus language? */
+ bool sygus() const;
+ /** Are we using the sygus version 1.0 format? */
+ bool sygus_v1() const;
/**
* Returns true if the language that we are parsing (SMT-LIB version >=2.5
@@ -332,6 +334,30 @@ class Smt2 : public Parser
std::vector<std::string>& unresolved_gterm_sym,
std::map< CVC4::Type, CVC4::Type >& sygus_to_builtin );
+ /**
+ * Adds a constructor to sygus datatype dt whose sygus operator is term.
+ *
+ * ntsToUnres contains a mapping from non-terminal symbols to the unresolved
+ * types they correspond to. This map indicates how the argument term should
+ * be interpreted (instances of symbols from the domain of ntsToUnres
+ * correspond to constructor arguments).
+ *
+ * The sygus operator that is actually added to dt corresponds to replacing
+ * each occurrence of non-terminal symbols from the domain of ntsToUnres
+ * with bound variables via purifySygusGTerm, and binding these variables
+ * via a lambda.
+ */
+ void addSygusConstructorTerm(Datatype& dt,
+ Expr term,
+ std::map<Expr, Type>& ntsToUnres) const;
+ /**
+ * This adds constructors to dt for sygus variables in sygusVars whose
+ * type is argument type. This method should be called when the sygus grammar
+ * term (Variable type) is encountered.
+ */
+ void addSygusConstructorVariables(Datatype& dt,
+ std::vector<Expr>& sygusVars,
+ Type type) const;
/**
* Smt2 parser provides its own checkDeclaration, which does the
@@ -351,7 +377,8 @@ class Smt2 : public Parser
return;
}else{
//it is allowable in sygus
- if( sygus() && name[0]=='-' ){
+ if (sygus_v1() && name[0] == '-')
+ {
//do not check anything
return;
}
@@ -449,6 +476,22 @@ private:
const std::vector<Type>& ltypes,
std::vector<Expr>& lvars);
+ /** Purify sygus grammar term
+ *
+ * This returns a term where all occurrences of non-terminal symbols (those
+ * in the domain of ntsToUnres) are replaced by fresh variables. For each
+ * variable replaced in this way, we add the fresh variable it is replaced
+ * with to args, and the unresolved type corresponding to the non-terminal
+ * symbol to cargs (constructor args). In other words, args contains the
+ * free variables in the term returned by this method (which should be bound
+ * by a lambda), and cargs contains the types of the arguments of the
+ * sygus constructor.
+ */
+ Expr purifySygusGTerm(Expr term,
+ std::map<Expr, Type>& ntsToUnres,
+ std::vector<Expr>& args,
+ std::vector<Type>& cargs) const;
+
void addArithmeticOperators();
void addTranscendentalOperators();
diff --git a/src/printer/printer.cpp b/src/printer/printer.cpp
index 51888addd..cacdd6694 100644
--- a/src/printer/printer.cpp
+++ b/src/printer/printer.cpp
@@ -64,6 +64,12 @@ unique_ptr<Printer> Printer::makePrinter(OutputLanguage lang)
return unique_ptr<Printer>(
new printer::smt2::Smt2Printer(printer::smt2::sygus_variant));
+ case LANG_SYGUS_V2:
+ // sygus version 2.0 does not have discrepancies with smt2, hence we use
+ // a normal smt2 variant here.
+ return unique_ptr<Printer>(
+ new printer::smt2::Smt2Printer(printer::smt2::smt2_6_1_variant));
+
case LANG_AST:
return unique_ptr<Printer>(new printer::ast::AstPrinter());
diff --git a/src/smt/smt_engine.cpp b/src/smt/smt_engine.cpp
index 5cf690147..5e8540348 100644
--- a/src/smt/smt_engine.cpp
+++ b/src/smt/smt_engine.cpp
@@ -1158,10 +1158,12 @@ void SmtEngine::setDefaults() {
// option if we are sygus, since we assume SMT LIB 2.6 semantics for sygus.
options::bitvectorDivByZeroConst.set(
language::isInputLang_smt2_6(options::inputLanguage())
- || options::inputLanguage() == language::input::LANG_SYGUS);
+ || options::inputLanguage() == language::input::LANG_SYGUS
+ || options::inputLanguage() == language::input::LANG_SYGUS_V2);
}
bool is_sygus = false;
- if (options::inputLanguage() == language::input::LANG_SYGUS)
+ if (options::inputLanguage() == language::input::LANG_SYGUS
+ || options::inputLanguage() == language::input::LANG_SYGUS_V2)
{
is_sygus = true;
}
diff --git a/src/util/result.cpp b/src/util/result.cpp
index e76f428a5..e6390cd41 100644
--- a/src/util/result.cpp
+++ b/src/util/result.cpp
@@ -350,8 +350,7 @@ void Result::toStreamTptp(std::ostream& out) const {
void Result::toStream(std::ostream& out, OutputLanguage language) const {
switch (language) {
case language::output::LANG_SYGUS:
- toStreamSmt2(out);
- break;
+ case language::output::LANG_SYGUS_V2: toStreamSmt2(out); break;
case language::output::LANG_TPTP:
toStreamTptp(out);
break;
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback