/********************* */ /*! \file quantifiers_attributes.cpp ** \verbatim ** Top contributors (to current version): ** Andrew Reynolds, Paul Meng, Morgan Deters ** This file is part of the CVC4 project. ** Copyright (c) 2009-2021 by the authors listed in the file AUTHORS ** in the top-level source directory and their institutional affiliations. ** All rights reserved. See the file COPYING in the top-level source ** directory for licensing information.\endverbatim ** ** \brief Implementation of QuantifiersAttributes class **/ #include "theory/quantifiers/quantifiers_attributes.h" #include "options/quantifiers_options.h" #include "theory/arith/arith_msum.h" #include "theory/quantifiers/sygus/synth_engine.h" #include "theory/quantifiers/term_util.h" using namespace std; using namespace cvc5::kind; using namespace cvc5::context; namespace cvc5 { namespace theory { namespace quantifiers { bool QAttributes::isStandard() const { return !d_sygus && !d_quant_elim && !isFunDef() && d_name.isNull() && !d_isInternal; } QuantAttributes::QuantAttributes() {} void QuantAttributes::setUserAttribute( const std::string& attr, Node n, std::vector< Node >& node_values, std::string str_value ){ Trace("quant-attr-debug") << "Set " << attr << " " << n << std::endl; if (attr == "fun-def") { Trace("quant-attr-debug") << "Set function definition " << n << std::endl; FunDefAttribute fda; n.setAttribute( fda, true ); } else if (attr == "qid") { // using z3 syntax "qid" Trace("quant-attr-debug") << "Set quant-name " << n << std::endl; QuantNameAttribute qna; n.setAttribute(qna, true); }else if( attr=="quant-inst-max-level" ){ Assert(node_values.size() == 1); uint64_t lvl = node_values[0].getConst().getNumerator().getLong(); Trace("quant-attr-debug") << "Set instantiation level " << n << " to " << lvl << std::endl; QuantInstLevelAttribute qila; n.setAttribute( qila, lvl ); }else if( attr=="quant-elim" ){ Trace("quant-attr-debug") << "Set quantifier elimination " << n << std::endl; QuantElimAttribute qea; n.setAttribute( qea, true ); }else if( attr=="quant-elim-partial" ){ Trace("quant-attr-debug") << "Set partial quantifier elimination " << n << std::endl; QuantElimPartialAttribute qepa; n.setAttribute( qepa, true ); } } bool QuantAttributes::checkFunDef( Node q ) { return !getFunDefHead( q ).isNull(); } bool QuantAttributes::checkFunDefAnnotation( Node ipl ) { if( !ipl.isNull() ){ for( unsigned i=0; i msum; if (ArithMSum::getMonomialSumLit(q[1], msum)) { Node veq; int res = ArithMSum::isolate(h, msum, veq, EQUAL); if (res != 0) { Assert(veq.getKind() == EQUAL); return res == 1 ? veq[1] : veq[0]; } } } }else{ Node atom = q[1].getKind()==NOT ? q[1][0] : q[1]; bool pol = q[1].getKind()!=NOT; if( atom==h ){ return NodeManager::currentNM()->mkConst( pol ); } } } return Node::null(); } bool QuantAttributes::checkSygusConjecture( Node q ) { return ( q.getKind()==FORALL && q.getNumChildren()==3 ) ? checkSygusConjectureAnnotation( q[2] ) : false; } bool QuantAttributes::checkSygusConjectureAnnotation( Node ipl ){ if( !ipl.isNull() ){ for( unsigned i=0; i::iterator it = d_qattr.find( q ); if( it==d_qattr.end() ){ return false; }else{ return it->second.isFunDef(); } } bool QuantAttributes::isSygus( Node q ) { std::map< Node, QAttributes >::iterator it = d_qattr.find( q ); if( it==d_qattr.end() ){ return false; }else{ return it->second.d_sygus; } } int64_t QuantAttributes::getQuantInstLevel(Node q) { std::map< Node, QAttributes >::iterator it = d_qattr.find( q ); if( it==d_qattr.end() ){ return -1; }else{ return it->second.d_qinstLevel; } } bool QuantAttributes::isQuantElim( Node q ) { std::map< Node, QAttributes >::iterator it = d_qattr.find( q ); if( it==d_qattr.end() ){ return false; }else{ return it->second.d_quant_elim; } } bool QuantAttributes::isQuantElimPartial( Node q ) { std::map< Node, QAttributes >::iterator it = d_qattr.find( q ); if( it==d_qattr.end() ){ return false; }else{ return it->second.d_quant_elim_partial; } } bool QuantAttributes::isInternal(Node q) const { std::map::const_iterator it = d_qattr.find(q); if (it != d_qattr.end()) { return it->second.d_isInternal; } return false; } Node QuantAttributes::getQuantName(Node q) const { std::map::const_iterator it = d_qattr.find(q); if (it != d_qattr.end()) { return it->second.d_name; } return Node::null(); } std::string QuantAttributes::quantToString(Node q) const { std::stringstream ss; Node name = getQuantName(q); ss << (name.isNull() ? q : name); return ss.str(); } int QuantAttributes::getQuantIdNum( Node q ) { std::map< Node, QAttributes >::iterator it = d_qattr.find( q ); if( it!=d_qattr.end() ){ if( !it->second.d_qid_num.isNull() ){ return it->second.d_qid_num.getAttribute(QuantIdNumAttribute()); } } return -1; } Node QuantAttributes::getQuantIdNumNode( Node q ) { std::map< Node, QAttributes >::iterator it = d_qattr.find( q ); if( it==d_qattr.end() ){ return Node::null(); }else{ return it->second.d_qid_num; } } void QuantAttributes::setInstantiationLevelAttr(Node n, Node qn, uint64_t level) { Trace("inst-level-debug2") << "IL : " << n << " " << qn << " " << level << std::endl; // if not from the vector of terms we instantiatied if (qn.getKind() != BOUND_VARIABLE && n != qn) { // if this is a new term, without an instantiation level if (!n.hasAttribute(InstLevelAttribute())) { InstLevelAttribute ila; n.setAttribute(ila, level); Trace("inst-level-debug") << "Set instantiation level " << n << " to " << level << std::endl; Assert(n.getNumChildren() == qn.getNumChildren()); for (unsigned i = 0; i < n.getNumChildren(); i++) { setInstantiationLevelAttr(n[i], qn[i], level); } } } } void QuantAttributes::setInstantiationLevelAttr(Node n, uint64_t level) { if (!n.hasAttribute(InstLevelAttribute())) { InstLevelAttribute ila; n.setAttribute(ila, level); Trace("inst-level-debug") << "Set instantiation level " << n << " to " << level << std::endl; for (unsigned i = 0; i < n.getNumChildren(); i++) { setInstantiationLevelAttr(n[i], level); } } } } // namespace quantifiers } // namespace theory } // namespace cvc5