/* attributed expressions */
| LPAREN_TOK ATTRIBUTE_TOK term[expr, f2]
( attribute[expr, attexpr, attr]
- { if( ( attr == ":pattern" || attr == ":no-pattern" ) && ! attexpr.isNull()) {
+ { if( ! attexpr.isNull()) {
patexprs.push_back( attexpr );
}
}
}
std::string attr_name = attr;
attr_name.erase( attr_name.begin() );
- Command* c = new SetUserAttributeCommand( attr_name, expr );
+ //will set the attribute on auxiliary var (preserves attribute on formula through rewriting)
+ Type t = EXPR_MANAGER->booleanType();
+ Expr avar = PARSER_STATE->mkVar(attr_name, t);
+ retExpr = MK_EXPR(kind::INST_ATTRIBUTE, avar);
+ Command* c = new SetUserAttributeCommand( attr_name, avar );
c->setMuted(true);
PARSER_STATE->preemptCommand(c);
} else {
attr = std::string(":no-pattern");
retExpr = MK_EXPR(kind::INST_NO_PATTERN, patexpr);
}
- | ATTRIBUTE_INST_LEVEL INTEGER_LITERAL
+ | tok=( ATTRIBUTE_INST_LEVEL | ATTRIBUTE_RR_PRIORITY ) INTEGER_LITERAL
{
Expr n = MK_CONST( AntlrInput::tokenToInteger($INTEGER_LITERAL) );
std::vector<Expr> values;
values.push_back( n );
- std::string attr_name("quant-inst-max-level");
- Command* c = new SetUserAttributeCommand( attr_name, expr, values );
- c->setMuted(true);
- PARSER_STATE->preemptCommand(c);
- }
- | ATTRIBUTE_RR_PRIORITY_LEVEL INTEGER_LITERAL
- {
- Expr n = MK_CONST( AntlrInput::tokenToInteger($INTEGER_LITERAL) );
- std::vector<Expr> values;
- values.push_back( n );
- std::string attr_name("rr-priority");
- Command* c = new SetUserAttributeCommand( attr_name, expr, values );
+ std::string attr_name(AntlrInput::tokenText($tok));
+ attr_name.erase( attr_name.begin() );
+ Type t = EXPR_MANAGER->booleanType();
+ Expr avar = PARSER_STATE->mkVar(attr_name, t);
+ retExpr = MK_EXPR(kind::INST_ATTRIBUTE, avar);
+ Command* c = new SetUserAttributeCommand( attr_name, avar, values );
c->setMuted(true);
PARSER_STATE->preemptCommand(c);
}
goto next_worklist;
}
switch(k) {
+ case kind::INST_ATTRIBUTE:
case kind::BOUND_VAR_LIST:
result.top() << top;
worklist.pop();
}
int InstStrategyAutoGenTriggers::process( Node f, Theory::Effort effort, int e ){
- if( f.getNumChildren()==3 && options::userPatternsQuant()==USER_PAT_MODE_TRUST ){
+ if( hasUserPatterns( f ) && options::userPatternsQuant()==USER_PAT_MODE_TRUST ){
return STATUS_UNKNOWN;
}else{
- int peffort = ( f.getNumChildren()==3 && options::userPatternsQuant()!=USER_PAT_MODE_IGNORE ) ? 2 : 1;
+ int peffort = ( hasUserPatterns( f ) && options::userPatternsQuant()!=USER_PAT_MODE_IGNORE ) ? 2 : 1;
//int peffort = 1;
if( e<peffort ){
return STATUS_UNFINISHED;
}
}
+bool InstStrategyAutoGenTriggers::hasUserPatterns( Node f ) {
+ if( f.getNumChildren()==3 ){
+ std::map< Node, bool >::iterator it = d_hasUserPatterns.find( f );
+ if( it==d_hasUserPatterns.end() ){
+ bool hasPat = false;
+ for( unsigned i=0; i<f[2].getNumChildren(); i++ ){
+ if( f[2][i].getKind()==INST_PATTERN ){
+ hasPat = true;
+ break;
+ }
+ }
+ d_hasUserPatterns[f] = hasPat;
+ return hasPat;
+ }else{
+ return it->second;
+ }
+ }else{
+ return false;
+ }
+}
+
void InstStrategyAutoGenTriggers::addUserNoPattern( Node f, Node pat ) {
Assert( pat.getKind()==INST_NO_PATTERN && pat.getNumChildren()==1 );
if( std::find( d_user_no_gen[f].begin(), d_user_no_gen[f].end(), pat[0] )==d_user_no_gen[f].end() ){
int process( Node f, Theory::Effort effort, int e );
/** generate triggers */
void generateTriggers( Node f, Theory::Effort effort, int e, int & status );
+ /** has user patterns */
+ bool hasUserPatterns( Node f );
+ /** has user patterns */
+ std::map< Node, bool > d_hasUserPatterns;
public:
/** tstrt is the type of triggers to use (maximum depth, minimum depth, or all)
rstrt is the relevance setting for trigger (use only relevant triggers vs. use all)
# An instantiation pattern may have more than 1 child, in which case it specifies a multi-trigger.
operator INST_PATTERN 1: "instantiation pattern"
operator INST_NO_PATTERN 1 "instantiation no-pattern"
+operator INST_ATTRIBUTE 1 "instantiation attribute"
sort INST_PATTERN_LIST_TYPE \
Cardinality::INTEGERS \
typerule BOUND_VAR_LIST ::CVC4::theory::quantifiers::QuantifierBoundVarListTypeRule
typerule INST_PATTERN ::CVC4::theory::quantifiers::QuantifierInstPatternTypeRule
typerule INST_NO_PATTERN ::CVC4::theory::quantifiers::QuantifierInstNoPatternTypeRule
+typerule INST_ATTRIBUTE ::CVC4::theory::quantifiers::QuantifierInstAttributeTypeRule
typerule INST_PATTERN_LIST ::CVC4::theory::quantifiers::QuantifierInstPatternListTypeRule
# for rewrite rules
bool QModelBuilderIG::isQuantifierActive( Node f ){
return !TermDb::isRewriteRule( f ) &&
- ( d_considerAxioms || !f.getAttribute(AxiomAttribute()) ) && d_quant_sat.find( f )==d_quant_sat.end();
+ ( d_considerAxioms || !d_qe->getTermDatabase()->isQAttrAxiom( f ) ) && d_quant_sat.find( f )==d_quant_sat.end();
}
bool QModelBuilderIG::isTermActive( Node n ){
void QuantifiersAttributes::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( n.getKind()==FORALL ){
- if( attr=="axiom" ){
- Trace("quant-attr") << "Set axiom " << n << std::endl;
- AxiomAttribute aa;
- n.setAttribute( aa, true );
- }else if( attr=="conjecture" ){
- Trace("quant-attr") << "Set conjecture " << n << std::endl;
- ConjectureAttribute ca;
- n.setAttribute( ca, true );
- }else if( attr=="quant-inst-max-level" ){
- Assert( node_values.size()==1 );
- uint64_t lvl = node_values[0].getConst<Rational>().getNumerator().getLong();
- Trace("quant-attr") << "Set instantiation level " << n << " to " << lvl << std::endl;
- QuantInstLevelAttribute qila;
- n.setAttribute( qila, lvl );
- }else if( attr=="rr-priority" ){
- Assert( node_values.size()==1 );
- uint64_t lvl = node_values[0].getConst<Rational>().getNumerator().getLong();
- Trace("quant-attr") << "Set rewrite rule priority " << n << " to " << lvl << std::endl;
- RrPriorityAttribute rrpa;
- n.setAttribute( rrpa, lvl );
- }
- }else{
- for( size_t i=0; i<n.getNumChildren(); i++ ){
- setUserAttribute( attr, n[i], node_values, str_value );
- }
+ if( attr=="axiom" ){
+ Trace("quant-attr-debug") << "Set axiom " << n << std::endl;
+ AxiomAttribute aa;
+ n.setAttribute( aa, true );
+ }else if( attr=="conjecture" ){
+ Trace("quant-attr-debug") << "Set conjecture " << n << std::endl;
+ ConjectureAttribute ca;
+ n.setAttribute( ca, true );
+ }else if( attr=="quant-inst-max-level" ){
+ Assert( node_values.size()==1 );
+ uint64_t lvl = node_values[0].getConst<Rational>().getNumerator().getLong();
+ Trace("quant-attr-debug") << "Set instantiation level " << n << " to " << lvl << std::endl;
+ QuantInstLevelAttribute qila;
+ n.setAttribute( qila, lvl );
+ }else if( attr=="rr-priority" ){
+ Assert( node_values.size()==1 );
+ uint64_t lvl = node_values[0].getConst<Rational>().getNumerator().getLong();
+ Trace("quant-attr-debug") << "Set rewrite rule priority " << n << " to " << lvl << std::endl;
+ RrPriorityAttribute rrpa;
+ n.setAttribute( rrpa, lvl );
}
}
namespace theory {
namespace quantifiers {
-/** Attribute true for quantifiers that are axioms */
-struct AxiomAttributeId {};
-typedef expr::Attribute< AxiomAttributeId, bool > AxiomAttribute;
-
-/** Attribute true for quantifiers that are conjecture */
-struct ConjectureAttributeId {};
-typedef expr::Attribute< ConjectureAttributeId, bool > ConjectureAttribute;
-
/** Attribute priority for rewrite rules */
//struct RrPriorityAttributeId {};
//typedef expr::Attribute< RrPriorityAttributeId, uint64_t > RrPriorityAttribute;
return Node::null();
}
}
+
+
+void TermDb::computeAttributes( Node q ) {
+ if( q.getNumChildren()==3 ){
+ for( unsigned i=0; i<q[2].getNumChildren(); i++ ){
+ if( q[2][i].getKind()==INST_ATTRIBUTE ){
+ Node avar = q[2][i][0];
+ if( avar.getAttribute(AxiomAttribute()) ){
+ Trace("quant-attr") << "Attribute : axiom : " << q << std::endl;
+ d_qattr_axiom[q] = true;
+ }
+ if( avar.getAttribute(ConjectureAttribute()) ){
+ Trace("quant-attr") << "Attribute : conjecture : " << q << std::endl;
+ d_qattr_conjecture[q] = true;
+ }
+ if( avar.hasAttribute(QuantInstLevelAttribute()) ){
+ d_qattr_qinstLevel[q] = avar.getAttribute(QuantInstLevelAttribute());
+ Trace("quant-attr") << "Attribute : quant inst level " << d_qattr_qinstLevel[q] << " : " << q << std::endl;
+ }
+ if( avar.hasAttribute(RrPriorityAttribute()) ){
+ d_qattr_rr_priority[q] = avar.getAttribute(RrPriorityAttribute());
+ Trace("quant-attr") << "Attribute : rr priority " << d_qattr_rr_priority[q] << " : " << q << std::endl;
+ }
+ }
+ }
+ }
+}
+
+bool TermDb::isQAttrConjecture( Node q ) {
+ std::map< Node, bool >::iterator it = d_qattr_conjecture.find( q );
+ if( it==d_qattr_conjecture.end() ){
+ return false;
+ }else{
+ return it->second;
+ }
+}
+
+bool TermDb::isQAttrAxiom( Node q ) {
+ std::map< Node, bool >::iterator it = d_qattr_axiom.find( q );
+ if( it==d_qattr_axiom.end() ){
+ return false;
+ }else{
+ return it->second;
+ }
+}
+
+int TermDb::getQAttrQuantInstLevel( Node q ) {
+ std::map< Node, int >::iterator it = d_qattr_qinstLevel.find( q );
+ if( it==d_qattr_qinstLevel.end() ){
+ return -1;
+ }else{
+ return it->second;
+ }
+}
+
+int TermDb::getQAttrRewriteRulePriority( Node q ) {
+ std::map< Node, int >::iterator it = d_qattr_rr_priority.find( q );
+ if( it==d_qattr_rr_priority.end() ){
+ return -1;
+ }else{
+ return it->second;
+ }
+}
namespace CVC4 {
namespace theory {
+/** Attribute true for quantifiers that are axioms */
+struct AxiomAttributeId {};
+typedef expr::Attribute< AxiomAttributeId, bool > AxiomAttribute;
+
+/** Attribute true for quantifiers that are conjecture */
+struct ConjectureAttributeId {};
+typedef expr::Attribute< ConjectureAttributeId, bool > ConjectureAttribute;
+
/** Attribute true for nodes that should not be used for matching */
struct NoMatchAttributeId {};
/** use the special for boolean flag */
/** get the rewrite rule associated with the quanfied formula */
static Node getRewriteRule( Node q );
+//attributes
+private:
+ std::map< Node, bool > d_qattr_conjecture;
+ std::map< Node, bool > d_qattr_axiom;
+ std::map< Node, int > d_qattr_rr_priority;
+ std::map< Node, int > d_qattr_qinstLevel;
+ //record attributes
+ void computeAttributes( Node q );
+public:
+ /** is conjecture */
+ bool isQAttrConjecture( Node q );
+ /** is axiom */
+ bool isQAttrAxiom( Node q );
+ /** get instantiation level */
+ int getQAttrQuantInstLevel( Node q );
+ /** get rewrite rule priority */
+ int getQAttrRewriteRulePriority( Node q );
+
};/* class TermDb */
}/* CVC4::theory::quantifiers namespace */
d_baseDecLevel = -1;
out.handleUserAttribute( "axiom", this );
out.handleUserAttribute( "conjecture", this );
- out.handleUserAttribute( "inst-level", this );
+ out.handleUserAttribute( "quant-inst-max-level", this );
out.handleUserAttribute( "rr-priority", this );
}
}
};/* struct QuantifierInstNoPatternTypeRule */
+struct QuantifierInstAttributeTypeRule {
+ inline static TypeNode computeType(NodeManager* nodeManager, TNode n, bool check)
+ throw(TypeCheckingExceptionPrivate) {
+ Assert(n.getKind() == kind::INST_ATTRIBUTE );
+ return nodeManager->instPatternType();
+ }
+};/* struct QuantifierInstAttributeTypeRule */
+
struct QuantifierInstPatternListTypeRule {
inline static TypeNode computeType(NodeManager* nodeManager, TNode n, bool check)
throw(TypeCheckingExceptionPrivate) {
Assert(n.getKind() == kind::INST_PATTERN_LIST );
if( check ){
for( int i=0; i<(int)n.getNumChildren(); i++ ){
- if( n[i].getKind()!=kind::INST_PATTERN && n[i].getKind()!=kind::INST_NO_PATTERN ){
+ if( n[i].getKind()!=kind::INST_PATTERN && n[i].getKind()!=kind::INST_NO_PATTERN && n[i].getKind()!=kind::INST_ATTRIBUTE ){
throw TypeCheckingExceptionPrivate(n, "argument of inst pattern list is not inst pattern");
}
}
}
};/* class RewriteRuleTypeRule */
-
class RRRewriteTypeRule {
public:
Assert( f.getKind()==FORALL );
//make instantiation constants for f
d_term_db->makeInstantiationConstantsFor( f );
+ d_term_db->computeAttributes( f );
//register with quantifier relevance
if( d_quant_rel ){
d_quant_rel->registerQuantifier( f );
bool QuantifiersEngine::isTermEligibleForInstantiation( Node n, Node f, bool print ) {
if( n.hasAttribute(InstLevelAttribute()) ){
- unsigned ml = options::instMaxLevel();
- if( f.hasAttribute(QuantInstLevelAttribute()) ){
- ml = f.getAttribute(QuantInstLevelAttribute());
- }
+ int fml = d_term_db->getQAttrQuantInstLevel( f );
+ unsigned ml = fml>=0 ? fml : options::instMaxLevel();
+
if( n.getAttribute(InstLevelAttribute())>ml ){
Trace("inst-add-debug") << "Term " << n << " has instantiation level " << n.getAttribute(InstLevelAttribute());
Trace("inst-add-debug") << ", which is more than maximum allowed level " << ml << " for this quantified formula." << std::endl;