Expr func = PARSER_STATE->mkFunction(name, t, ExprManager::VAR_FLAG_DEFINED);
$cmd = new DefineFunctionCommand(name, func, terms, expr);
}
+ | DECLARE_DATATYPES_TOK datatypesDefCommand[false, cmd]
+ | DECLARE_CODATATYPES_TOK datatypesDefCommand[true, cmd]
| /* synth-fun */
( SYNTH_FUN_TOK | SYNTH_INV_TOK { range = EXPR_MANAGER->booleanType(); } ) { PARSER_STATE->checkThatLogicIsSet(); }
symbol[fun,CHECK_UNDECLARED,SYM_VARIABLE]
// fail, but we need an operator to continue here..
Debug("parser-sygus") << "Sygus grammar " << fun;
Debug("parser-sygus") << " : op (declare=" << PARSER_STATE->isDeclared(name) << ", define=" << PARSER_STATE->isDefinedFunction(name) << ") : " << name << std::endl;
- if( !PARSER_STATE->isDefinedFunction(name) ){
+ if( !PARSER_STATE->isDeclared(name) && !PARSER_STATE->isDefinedFunction(name) ){
PARSER_STATE->parseError(std::string("Functions in sygus grammars must be defined."));
}
sgt.d_name = name;
for( unsigned i=0; i<sygus_vars.size(); i++ ){
Type t = sygus_vars[i].getType();
if( !t.isBoolean() && std::find( types.begin(), types.end(), t )==types.end() ){
+ Debug("parser-sygus") << "...will make grammar for " << t << std::endl;
types.push_back( t );
}
}
+ if( !range.isBoolean() && !range.isInteger() && !range.isBitVector() ){
+ parseError("No default grammar for type.");
+ }
//name of boolean sort
std::stringstream ssb;
std::stringstream ss;
ss << datatypes[index].getName() << "_let";
Expr let_func = mkFunction(ss.str(), ft, ExprManager::VAR_FLAG_DEFINED);
+ d_sygus_defined_funs.push_back( let_func );
preemptCommand( new DefineFunctionCommand(ss.str(), let_func, let_define_args, let_body) );
ops[index].pop_back();
//replace operator and name
ops[i] = mkFunction(ss.str(), ft, ExprManager::VAR_FLAG_DEFINED);
cnames[i] = ss.str();
+ d_sygus_defined_funs.push_back( ops[i] );
preemptCommand( new DefineFunctionCommand(ss.str(), ops[i], let_args, let_body) );
addSygusDatatypeConstructor( dt, ops[i], cnames[i], cargs[i], let_body, let_args, 0 );
}else{
std::stringstream ssid;
ssid << unresolved_gterm_sym[i] << "_id";
Expr id_op = mkFunction(ss.str(), ft, ExprManager::VAR_FLAG_DEFINED);
+ d_sygus_defined_funs.push_back( id_op );
preemptCommand( new DefineFunctionCommand(ssid.str(), id_op, let_args, let_body) );
//make the sygus argument list
std::vector< Type > id_carg;
for(size_t k = 0; k < builtApply.size(); ++k) {
}
Expr builtTerm;
- //if( ops[i][j].getKind() == kind::BUILTIN ){
- if( !builtApply.empty() ){
- if( ops[i][j].getKind() != kind::BUILTIN ){
- builtTerm = getExprManager()->mkExpr(kind::APPLY, ops[i][j], builtApply);
+ Debug("parser-sygus") << "...operator is : " << ops[i][j] << ", type = " << ops[i][j].getType() << ", kind = " << ops[i][j].getKind() << ", is defined = " << isDefinedFunction( ops[i][j] ) << std::endl;
+ if( ops[i][j].getKind() != kind::BUILTIN ){
+ Kind ok = kind::UNDEFINED_KIND;
+ if( isDefinedFunction( ops[i][j] ) || std::find( d_sygus_defined_funs.begin(), d_sygus_defined_funs.end(), ops[i][j] )!=d_sygus_defined_funs.end() ){
+ ok = kind::APPLY;
}else{
- builtTerm = getExprManager()->mkExpr(ops[i][j], builtApply);
+ Type t = ops[i][j].getType();
+ if( t.isConstructor() ){
+ ok = kind::APPLY_CONSTRUCTOR;
+ }else if( t.isSelector() ){
+ ok = kind::APPLY_SELECTOR;
+ }else if( t.isTester() ){
+ ok = kind::APPLY_TESTER;
+ }else{
+ ok = getExprManager()->operatorToKind( ops[i][j] );
+ }
+ }
+ Debug("parser-sygus") << "...processed operator kind : " << ok << std::endl;
+ if( ok!=kind::UNDEFINED_KIND ){
+ builtTerm = getExprManager()->mkExpr(ok, ops[i][j], builtApply);
+ }else{
+ builtTerm = ops[i][j];
}
}else{
- builtTerm = ops[i][j];
+ if( !builtApply.empty() ){
+ builtTerm = getExprManager()->mkExpr(ops[i][j], builtApply);
+ }else{
+ builtTerm = ops[i][j];
+ }
}
Debug("parser-sygus") << "...made built term " << builtTerm << std::endl;
Expr assertion = getExprManager()->mkExpr(evalApply.getType().isBoolean() ? kind::IFF : kind::EQUAL, evalApply, builtTerm);
class SExpr;
namespace parser {
-
+
class Smt2 : public Parser {
friend class ParserBuilder;
void mkSygusConstantsForType( const Type& type, std::vector<CVC4::Expr>& ops );
- void processSygusGTerm( CVC4::SygusGTerm& sgt, int index,
+ void processSygusGTerm( CVC4::SygusGTerm& sgt, int index,
std::vector< CVC4::Datatype >& datatypes,
std::vector< CVC4::Type>& sorts,
std::vector< std::vector<CVC4::Expr> >& ops,
std::vector< std::vector< std::vector< CVC4::Type > > >& cargs,
std::vector< bool >& allow_const,
std::vector< std::vector< std::string > >& unresolved_gterm_sym,
- std::vector<CVC4::Expr>& sygus_vars,
- std::map< CVC4::Type, CVC4::Type >& sygus_to_builtin, std::map< CVC4::Type, CVC4::Expr >& sygus_to_builtin_expr,
+ std::vector<CVC4::Expr>& sygus_vars,
+ std::map< CVC4::Type, CVC4::Type >& sygus_to_builtin, std::map< CVC4::Type, CVC4::Expr >& sygus_to_builtin_expr,
CVC4::Type& ret, bool isNested = false );
-
+
static bool pushSygusDatatypeDef( Type t, std::string& dname,
std::vector< CVC4::Datatype >& datatypes,
std::vector< CVC4::Type>& sorts,
std::vector< std::vector< std::vector< CVC4::Type > > >& cargs,
std::vector< bool >& allow_const,
std::vector< std::vector< std::string > >& unresolved_gterm_sym );
-
- void setSygusStartIndex( std::string& fun, int startIndex,
+
+ void setSygusStartIndex( std::string& fun, int startIndex,
std::vector< CVC4::Datatype >& datatypes,
std::vector< CVC4::Type>& sorts,
std::vector< std::vector<CVC4::Expr> >& ops );
-
+
void addSygusFun(const std::string& fun, Expr eval) {
d_sygusFuns.push_back(std::make_pair(fun, eval));
}
void mkSygusDatatype( CVC4::Datatype& dt, std::vector<CVC4::Expr>& ops,
std::vector<std::string>& cnames, std::vector< std::vector< CVC4::Type > >& cargs,
- std::vector<std::string>& unresolved_gterm_sym,
+ std::vector<std::string>& unresolved_gterm_sym,
std::map< CVC4::Type, CVC4::Type >& sygus_to_builtin );
// i is index in datatypes/ops
Expr getSygusAssertion( std::vector<DatatypeType>& datatypeTypes, std::vector< std::vector<Expr> >& ops,
std::map<DatatypeType, Expr>& evals, std::vector<Expr>& terms,
Expr eval, const Datatype& dt, size_t i, size_t j );
-
+
void addSygusConstraint(Expr constraint) {
std::map< CVC4::Expr, std::vector< CVC4::Expr > > d_sygus_let_func_to_vars;
std::map< CVC4::Expr, CVC4::Expr > d_sygus_let_func_to_body;
std::map< CVC4::Expr, unsigned > d_sygus_let_func_to_num_input_vars;
-
+ //auxiliary define-fun functions introduced for production rules
+ std::vector< CVC4::Expr > d_sygus_defined_funs;
+
void collectSygusLetArgs( CVC4::Expr e, std::vector< CVC4::Type >& sygusArgs, std::vector< CVC4::Expr >& builtinArgs );
-
+
void addSygusDatatypeConstructor( CVC4::Datatype& dt, CVC4::Expr op, std::string& cname, std::vector< CVC4::Type >& cargs,
CVC4::Expr& let_body, std::vector< CVC4::Expr >& let_args, unsigned let_num_input_args );
std::map< CVC4::Type, CVC4::Type >& sygus_to_builtin,
std::map< CVC4::Type, CVC4::Expr >& sygus_to_builtin_expr, Type sub_ret );
- void processSygusLetConstructor( std::vector< CVC4::Expr >& let_vars, int index,
+ void processSygusLetConstructor( std::vector< CVC4::Expr >& let_vars, int index,
std::vector< CVC4::Datatype >& datatypes,
std::vector< CVC4::Type>& sorts,
std::vector< std::vector<CVC4::Expr> >& ops,
std::vector< std::vector<std::string> >& cnames,
std::vector< std::vector< std::vector< CVC4::Type > > >& cargs,
- std::vector<CVC4::Expr>& sygus_vars,
+ std::vector<CVC4::Expr>& sygus_vars,
std::map< CVC4::Type, CVC4::Type >& sygus_to_builtin,
std::map< CVC4::Type, CVC4::Expr >& sygus_to_builtin_expr );
-
+
void addArithmeticOperators();
void addBitvectorOperators();
d_definedFunctions->insert(funcNode, def);
}
+bool SmtEngine::isDefinedFunction( Expr func ){
+ Node nf = Node::fromExpr( func );
+ Debug("smt") << "isDefined function " << nf << "?" << std::endl;
+ return d_definedFunctions->find(nf) != d_definedFunctions->end();
+}
+
Node SmtEnginePrivate::expandDefinitions(TNode n, hash_map<Node, Node, NodeHashFunction>& cache, bool expandOnly)
throw(TypeCheckingException, LogicException, UnsafeInterruptException) {
*A vector of command definitions to be imported in the new
*SmtEngine when checking unsat-cores.
*/
-#ifdef CVC4_PROOF
+#ifdef CVC4_PROOF
std::vector<Command*> d_defineCommands;
-#endif
+#endif
/**
* The logic we're in.
*/
const std::vector<Expr>& formals,
Expr formula);
+ /** is defined function */
+ bool isDefinedFunction(Expr func);
+
/**
* Add a formula to the current context: preprocess, do per-theory
* setup, use processAssertionList(), asserting to T-solver for
* Print solution for synthesis conjectures found by ce_guided_instantiation module
*/
void printSynthSolution( std::ostream& out );
-
+
/**
* Get an unsatisfiable core (only if immediately preceded by an
* UNSAT or VALID query). Only permitted if CVC4 was built with
* Set print function in model
*/
void setPrintFuncInModel(Expr f, bool p);
-
+
};/* class SmtEngine */
}/* CVC4 namespace */
d_vts_delta = NodeManager::currentNM()->mkSkolem( "delta", NodeManager::currentNM()->realType(), "delta for virtual term substitution" );
}
}
- return isFree ? d_vts_delta_free : d_vts_delta;
+ return isFree ? d_vts_delta_free : d_vts_delta;
}
Node TermDb::getVtsInfinity( bool isFree, bool create ) {
if( op.getKind()==BUILTIN ){
ret = NodeManager::currentNM()->mkNode( op, children );
}else{
- if( children.size()==1 ){
+ Kind ok = getOperatorKind( op );
+ Trace("sygus-db") << "Operator kind is " << ok << std::endl;
+ if( children.size()==1 && ok==kind::UNDEFINED_KIND ){
ret = children[0];
}else{
- ret = NodeManager::currentNM()->mkNode( APPLY, children );
+ ret = NodeManager::currentNM()->mkNode( ok, children );
/*
Node n = NodeManager::currentNM()->mkNode( APPLY, children );
//must expand definitions
}
}
+Kind TermDbSygus::getOperatorKind( Node op ) {
+ Assert( op.getKind()!=BUILTIN );
+ if( smt::currentSmtEngine()->isDefinedFunction( op.toExpr() ) ){
+ return APPLY;
+ }else{
+ TypeNode tn = op.getType();
+ if( tn.isConstructor() ){
+ return APPLY_CONSTRUCTOR;
+ }else if( tn.isSelector() ){
+ return APPLY_SELECTOR;
+ }else if( tn.isTester() ){
+ return APPLY_TESTER;
+ }else{
+ return NodeManager::operatorToKind( op );
+ }
+ }
+}
+
void TermDbSygus::printSygusTerm( std::ostream& out, Node n, std::vector< Node >& lvs ) {
if( n.getKind()==APPLY_CONSTRUCTOR ){
TypeNode tn = n.getType();
Kind getComparisonKind( TypeNode tn );
Kind getPlusKind( TypeNode tn, bool is_neg = false );
bool doCompare( Node a, Node b, Kind k );
+ /** get operator kind */
+ static Kind getOperatorKind( Node op );
/** print sygus term */
static void printSygusTerm( std::ostream& out, Node n, std::vector< Node >& lvs );
};
enum-test.sy \
no-syntax-test-bool.sy \
inv-example.sy \
- uminus_one.sy
+ uminus_one.sy \
+ sygus-dt.sy
# sygus tests currently taking too long for make regress
EXTRA_DIST = $(TESTS) \
--- /dev/null
+; EXPECT: unsat
+; COMMAND-LINE: --cegqi --no-dump-synth
+
+(set-logic LIA)
+
+(declare-datatypes () ((List (cons (head Int) (tail List)) (nil))))
+(define-fun g ((x Int)) List (cons (+ x 1) nil))
+(define-fun i () List (cons 3 nil))
+
+(synth-fun f ((x Int)) List ((Start List ((g StartInt) i (cons StartInt Start) (nil) (tail Start)))
+ (StartInt Int (x 0 1 (+ StartInt StartInt)))))
+
+(declare-var x Int)
+
+(constraint (= (f x) (cons x nil)))
+(check-synth)
\ No newline at end of file