if( d_mg->isValid() ){\r
for( unsigned j=q[0].getNumChildren(); j<d_vars.size(); j++ ){\r
if( d_vars[j].getKind()!=BOUND_VARIABLE ){\r
- d_var_mg[j] = new MatchGen( this, d_vars[j], true );\r
- if( !d_var_mg[j]->isValid() ){\r
+ bool beneathQuant = d_nbeneathQuant.find( d_vars[j] )==d_nbeneathQuant.end();\r
+ d_var_mg[j] = new MatchGen( this, d_vars[j], true, beneathQuant );\r
+ if( !d_var_mg[j]->isValid() && options::qcfMode()<QCF_PARTIAL ){\r
d_mg->setInvalid();\r
break;\r
}else{\r
}\r
\r
//must also contain all variables?\r
- /*\r
- if( d_mg->isValid() ){\r
- for( unsigned i=0; i<q[0].getNumChildren(); i++ ){\r
- if( d_has_var.find( q[0][i] )==d_has_var.end() ){\r
- d_mg->setInvalid();\r
- break;\r
- }\r
+ if( d_isPartial ){\r
+ for( unsigned i=0; i<q[0].getNumChildren(); i++ ){\r
+ if( d_has_var.find( q[0][i] )==d_has_var.end() ){\r
+ d_isPartial = false;\r
+ d_mg->setInvalid();\r
+ break;\r
}\r
}\r
- */\r
+ }\r
}\r
- Trace("qcf-qregister-summary") << "QCF register : " << ( d_mg->isValid() ? "VALID " : "INVALID" ) << " : " << q << std::endl;\r
+ Trace("qcf-qregister-summary") << "QCF register : " << ( d_mg->isValid() ? ( isPartial() ? "PARTIAL " : "VALID " ) : "INVALID" ) << " : " << q << std::endl;\r
}\r
\r
-void QuantInfo::registerNode( Node n, bool hasPol, bool pol ) {\r
+void QuantInfo::registerNode( Node n, bool hasPol, bool pol, bool beneathQuant ) {\r
Trace("qcf-qregister-debug2") << "Register : " << n << std::endl;\r
if( n.getKind()==FORALL ){\r
- registerNode( n[1], hasPol, pol );\r
+ registerNode( n[1], hasPol, pol, true );\r
}else{\r
if( n.getKind()!=OR && n.getKind()!=AND && n.getKind()!=IFF && n.getKind()!=NOT ){\r
if( quantifiers::TermDb::hasBoundVarAttr( n ) ){\r
//literals\r
if( n.getKind()==EQUAL ){\r
for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
- flatten( n[i] );\r
+ flatten( n[i], beneathQuant );\r
}\r
}else if( MatchGen::isHandledUfTerm( n ) ){\r
- flatten( n );\r
- }else if( n.getKind()==ITE && !n[1].getType().isBoolean() ){\r
- for( unsigned i=1; i<=2; i++ ){\r
- flatten( n[i] );\r
+ flatten( n, beneathQuant );\r
+ }else if( n.getKind()==ITE ){\r
+ if( !n[1].getType().isBoolean() ){\r
+ for( unsigned i=1; i<=2; i++ ){\r
+ flatten( n[i], beneathQuant );\r
+ }\r
}\r
}\r
}\r
}\r
- if( n.getKind()==BOUND_VARIABLE ){\r
- d_has_var[n] = true;\r
+ if( isVar( n ) && !beneathQuant ){\r
+ d_nbeneathQuant[n] = true;\r
}\r
for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
bool newHasPol;\r
//QcfNode * qcfc = new QcfNode( d_c );\r
//qcfc->d_parent = qcf;\r
//qcf->d_child[i] = qcfc;\r
- registerNode( n[i], newHasPol, newPol );\r
+ registerNode( n[i], newHasPol, newPol, beneathQuant );\r
}\r
}\r
}\r
\r
-void QuantInfo::flatten( Node n ) {\r
+void QuantInfo::flatten( Node n, bool beneathQuant ) {\r
Trace("qcf-qregister-debug2") << "Flatten : " << n << std::endl;\r
if( quantifiers::TermDb::hasBoundVarAttr( n ) ){\r
if( d_var_num.find( n )==d_var_num.end() ){\r
registerNode( n, false, false );\r
}else{\r
for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
- flatten( n[i] );\r
+ flatten( n[i], beneathQuant );\r
}\r
}\r
+ if( !beneathQuant ){\r
+ d_nbeneathQuant[n] = true;\r
+ }\r
}else{\r
Trace("qcf-qregister-debug2") << "...already processed" << std::endl;\r
}\r
}\r
}\r
\r
-\r
//void QuantInfo::addFuncParent( int v, Node f, int arg ) {\r
// if( std::find( d_f_parent[v][f].begin(), d_f_parent[v][f].end(), arg )==d_f_parent[v][f].end() ){\r
// d_f_parent[v][f].push_back( arg );\r
// }\r
//}\r
\r
-MatchGen::MatchGen( QuantInfo * qi, Node n, bool isVar ){\r
- Trace("qcf-qregister-debug") << "Make match gen for " << n << ", isVar = " << isVar << std::endl;\r
+MatchGen::MatchGen( QuantInfo * qi, Node n, bool isVar, bool beneathQuant ){\r
+ Trace("qcf-qregister-debug") << "Make match gen for " << n << ", isVar = " << isVar << ", beneathQuant = " << beneathQuant << std::endl;\r
std::vector< Node > qni_apps;\r
d_qni_size = 0;\r
if( isVar ){\r
Trace("qcf-qregister-debug") << " is var #" << v << std::endl;\r
d_qni_var_num[d_qni_size] = v;\r
//qi->addFuncParent( v, f, j );\r
+ if( nn.getKind()==BOUND_VARIABLE && !beneathQuant ){\r
+ qi->d_has_var[nn] = true;\r
+ }\r
}else{\r
Trace("qcf-qregister-debug") << " is gterm " << nn << std::endl;\r
d_qni_gterm[d_qni_size] = nn;\r
Node nn = n.eqNode( n[i] );\r
d_children.push_back( MatchGen( qi, nn ) );\r
d_children[d_children.size()-1].d_qni_bound_except.push_back( 0 );\r
- if( !d_children[d_children.size()-1].isValid() ){\r
+ if( !d_children[d_children.size()-1].isValid() && options::qcfMode()<QCF_PARTIAL ){\r
setInvalid();\r
break;\r
}\r
if( d_n.getKind()==OR || d_n.getKind()==AND || d_n.getKind()==IFF || d_n.getKind()==ITE || d_n.getKind()==FORALL ){\r
//non-literals\r
d_type = typ_formula;\r
+ bool nBeneathQuant = beneathQuant || d_n.getKind()==FORALL;\r
for( unsigned i=0; i<d_n.getNumChildren(); i++ ){\r
if( d_n.getKind()!=FORALL || i==1 ){\r
- d_children.push_back( MatchGen( qi, d_n[i] ) );\r
- if( !d_children[d_children.size()-1].isValid() ){\r
+ d_children.push_back( MatchGen( qi, d_n[i], false, nBeneathQuant ) );\r
+ if( !d_children[d_children.size()-1].isValid() && options::qcfMode()<QCF_PARTIAL ){\r
setInvalid();\r
break;\r
}\r
if( quantifiers::TermDb::hasBoundVarAttr( d_n[i] ) ){\r
if( !qi->isVar( d_n[i] ) ){\r
Trace("qcf-qregister-debug") << "ERROR : not var " << d_n[i] << std::endl;\r
+ }else if( d_n[i].getKind()==BOUND_VARIABLE && !beneathQuant ){\r
+ qi->d_has_var[d_n[i]] = true;\r
}\r
Assert( qi->isVar( d_n[i] ) );\r
}else{\r
debugPrintType( "qcf-qregister-debug", d_type, true );\r
Trace("qcf-qregister-debug") << std::endl;\r
//Assert( d_children.size()==d_children_order.size() );\r
+\r
+ if( !isValid() && options::qcfMode()>=QCF_PARTIAL ){\r
+ qi->d_isPartial = true;\r
+ }\r
}\r
\r
void MatchGen::collectBoundVar( QuantInfo * qi, Node n, std::vector< int >& cbvars ) {\r
\r
//set up processing matches\r
if( d_type==typ_invalid ){\r
- if( p->d_effort>QuantConflictFind::effort_conflict ){\r
+ if( p->d_effort==QuantConflictFind::effort_partial ){\r
d_child_counter = 0;\r
}\r
}else if( d_type==typ_ground ){\r
d_qn.push_back( NULL );\r
}else{\r
if( d_tgt && d_n.getKind()==FORALL ){\r
- //TODO\r
+ //return success once\r
+ if( p->d_effort==QuantConflictFind::effort_partial ){\r
+ d_child_counter = -2;\r
+ }\r
}else{\r
//reset the first child to d_tgt\r
d_child_counter = 0;\r
//also need to create match for each variable we bound\r
success = true;\r
Debug("qcf-match-debug") << " Produce matches for bound variables by " << d_n << ", type = ";\r
- debugPrintType( "qcf-match", d_type );\r
+ debugPrintType( "qcf-match-debug", d_type );\r
Debug("qcf-match-debug") << "..." << std::endl;\r
\r
while( ( success && d_binding_it!=d_qni_bound.end() ) || doFail ){\r
Debug("qcf-match") << " ...finished matching for " << d_n << ", success = " << success << std::endl;\r
return success;\r
}else if( d_type==typ_formula || d_type==typ_ite_var ){\r
- if( d_child_counter!=-1 ){\r
- bool success = false;\r
+ bool success = false;\r
+ if( d_child_counter<0 ){\r
+ if( d_child_counter<-1 ){\r
+ success = true;\r
+ d_child_counter = -1;\r
+ }\r
+ }else{\r
while( !success && d_child_counter>=0 ){\r
//transition system based on d_child_counter\r
if( d_type==typ_top || d_n.getKind()==OR || d_n.getKind()==AND ){\r
}\r
}\r
}\r
- if( d_child_counter%2==1 ){\r
+ if( d_child_counter>=0 && d_child_counter%2==1 ){\r
if( getChild( 1 )->getNextMatch( p, qi ) ){\r
success = true;\r
}else{\r
d_child_counter++;\r
getChild( d_child_counter==5 ? 2 : (d_tgt==(d_child_counter==1) ? 1 : 2) )->reset( p, d_tgt, qi );\r
}else{\r
- if( d_child_counter==4 ){\r
+ if( d_child_counter==4 || ( d_type==typ_ite_var && d_child_counter==2 ) ){\r
d_child_counter = -1;\r
}else{\r
d_child_counter +=2;\r
- getChild( d_child_counter==4 ? 1 : 0 )->reset( p, d_child_counter==2 ? !d_tgt : d_tgt, qi );\r
+ getChild( d_child_counter==2 ? 0 : 1 )->reset( p, d_child_counter==2 ? !d_tgt : d_tgt, qi );\r
}\r
}\r
}\r
- if( d_child_counter%2==1 ){\r
+ if( d_child_counter>=0 && d_child_counter%2==1 ){\r
int index2 = d_child_counter==5 ? 2 : (d_tgt==(d_child_counter==1) ? 1 : 2);\r
if( getChild( index2 )->getNextMatch( p, qi ) ){\r
success = true;\r
}\r
}else if( d_n.getKind()==FORALL ){\r
if( getChild( d_child_counter )->getNextMatch( p, qi ) ){\r
- //TODO\r
success = true;\r
}else{\r
d_child_counter = -1;\r
debugPrint("qcf-debug");\r
Trace("qcf-debug") << std::endl;\r
}\r
- short end_e = options::qcfMode()==QCF_CONFLICT_ONLY ? effort_conflict : options::qcfMode()==QCF_PROP_EQ ? effort_prop_eq : effort_mc;\r
+ short end_e;\r
+ if( options::qcfMode()==QCF_CONFLICT_ONLY ){\r
+ end_e = effort_conflict;\r
+ }else if( options::qcfMode()==QCF_PROP_EQ ){\r
+ end_e = effort_prop_eq;\r
+ }else if( options::qcfMode()==QCF_PARTIAL ){\r
+ end_e = effort_partial;\r
+ }else{\r
+ end_e = effort_mc;\r
+ }\r
for( short e = effort_conflict; e<=end_e; e++ ){\r
d_effort = e;\r
Trace("qcf-check") << "Checking quantified formulas at effort " << e << "..." << std::endl;\r
for( unsigned j=0; j<qorder.size(); j++ ){\r
Node q = qorder[j];\r
QuantInfo * qi = &d_qinfo[q];\r
- Trace("qcf-check") << "Check quantified formula ";\r
- debugPrintQuant("qcf-check", q);\r
- Trace("qcf-check") << " : " << q << "..." << std::endl;\r
\r
Assert( d_qinfo.find( q )!=d_qinfo.end() );\r
if( qi->d_mg->isValid() ){\r
- Trace("qcf-check-debug") << "Reset round..." << std::endl;\r
- qi->reset_round( this );\r
- //try to make a matches making the body false\r
- Trace("qcf-check-debug") << "Reset..." << std::endl;\r
- qi->d_mg->reset( this, false, qi );\r
- Trace("qcf-check-debug") << "Get next match..." << std::endl;\r
- while( qi->d_mg->getNextMatch( this, qi ) ){\r
-\r
- Trace("qcf-check") << "*** Produced match at effort " << e << " : " << std::endl;\r
- qi->debugPrintMatch("qcf-check");\r
- Trace("qcf-check") << std::endl;\r
-\r
- if( !qi->isMatchSpurious( this ) ){\r
- std::vector< int > assigned;\r
- if( qi->completeMatch( this, assigned ) ){\r
- std::vector< Node > terms;\r
- for( unsigned i=0; i<q[0].getNumChildren(); i++ ){\r
- //Node cv = qi->getCurrentValue( qi->d_match[i] );\r
- int repVar = qi->getCurrentRepVar( i );\r
- Node cv;\r
- //std::map< int, TNode >::iterator itmt = qi->d_match_term.find( repVar );\r
- if( !qi->d_match_term[repVar].isNull() ){\r
- cv = qi->d_match_term[repVar];\r
+ if( qi->isPartial()==(e==effort_partial) ){\r
+ Trace("qcf-check") << "Check quantified formula ";\r
+ debugPrintQuant("qcf-check", q);\r
+ Trace("qcf-check") << " : " << q << "..." << std::endl;\r
+\r
+ Trace("qcf-check-debug") << "Reset round..." << std::endl;\r
+ qi->reset_round( this );\r
+ //try to make a matches making the body false\r
+ Trace("qcf-check-debug") << "Reset..." << std::endl;\r
+ qi->d_mg->reset( this, false, qi );\r
+ Trace("qcf-check-debug") << "Get next match..." << std::endl;\r
+ while( qi->d_mg->getNextMatch( this, qi ) ){\r
+\r
+ Trace("qcf-check") << "*** Produced match at effort " << e << " : " << std::endl;\r
+ qi->debugPrintMatch("qcf-check");\r
+ Trace("qcf-check") << std::endl;\r
+\r
+ if( !qi->isMatchSpurious( this ) ){\r
+ std::vector< int > assigned;\r
+ if( qi->completeMatch( this, assigned ) ){\r
+ std::vector< Node > terms;\r
+ for( unsigned i=0; i<q[0].getNumChildren(); i++ ){\r
+ //Node cv = qi->getCurrentValue( qi->d_match[i] );\r
+ int repVar = qi->getCurrentRepVar( i );\r
+ Node cv;\r
+ //std::map< int, TNode >::iterator itmt = qi->d_match_term.find( repVar );\r
+ if( !qi->d_match_term[repVar].isNull() ){\r
+ cv = qi->d_match_term[repVar];\r
+ }else{\r
+ cv = qi->d_match[repVar];\r
+ }\r
+ Debug("qcf-check-inst") << "INST : " << i << " -> " << cv << ", from " << qi->d_match[i] << std::endl;\r
+ terms.push_back( cv );\r
+ }\r
+ if( Debug.isOn("qcf-check-inst") ){\r
+ //if( e==effort_conflict ){\r
+ Node inst = d_quantEngine->getInstantiation( q, terms );\r
+ Debug("qcf-check-inst") << "Check instantiation " << inst << "..." << std::endl;\r
+ Assert( evaluate( inst )!=1 );\r
+ Assert( evaluate( inst )==-1 || e>effort_conflict );\r
+ //}\r
+ }\r
+ if( d_quantEngine->addInstantiation( q, terms ) ){\r
+ Trace("qcf-check") << " ... Added instantiation" << std::endl;\r
+ ++addedLemmas;\r
+ if( e==effort_conflict ){\r
+ d_quant_order.insert( d_quant_order.begin(), q );\r
+ d_conflict.set( true );\r
+ ++(d_statistics.d_conflict_inst);\r
+ break;\r
+ }else if( e==effort_prop_eq ){\r
+ ++(d_statistics.d_prop_inst);\r
+ }else if( e==effort_partial ){\r
+ ++(d_statistics.d_partial_inst);\r
+ }\r
}else{\r
- cv = qi->d_match[repVar];\r
+ Trace("qcf-check") << " ... Failed to add instantiation" << std::endl;\r
+ //Assert( false );\r
}\r
- Debug("qcf-check-inst") << "INST : " << i << " -> " << cv << ", from " << qi->d_match[i] << std::endl;\r
- terms.push_back( cv );\r
- }\r
- if( Debug.isOn("qcf-check-inst") ){\r
- //if( e==effort_conflict ){\r
- Node inst = d_quantEngine->getInstantiation( q, terms );\r
- Debug("qcf-check-inst") << "Check instantiation " << inst << "..." << std::endl;\r
- Assert( evaluate( inst )!=1 );\r
- Assert( evaluate( inst )==-1 || e>effort_conflict );\r
- //}\r
- }\r
- if( d_quantEngine->addInstantiation( q, terms ) ){\r
- Trace("qcf-check") << " ... Added instantiation" << std::endl;\r
- ++addedLemmas;\r
- if( e==effort_conflict ){\r
- d_quant_order.insert( d_quant_order.begin(), q );\r
- d_conflict.set( true );\r
- ++(d_statistics.d_conflict_inst);\r
- break;\r
- }else if( e==effort_prop_eq ){\r
- ++(d_statistics.d_prop_inst);\r
+ //clean up assigned\r
+ for( unsigned i=0; i<assigned.size(); i++ ){\r
+ qi->d_match[ assigned[i] ] = TNode::null();\r
}\r
}else{\r
- Trace("qcf-check") << " ... Failed to add instantiation" << std::endl;\r
- //Assert( false );\r
- }\r
- //clean up assigned\r
- for( unsigned i=0; i<assigned.size(); i++ ){\r
- qi->d_match[ assigned[i] ] = TNode::null();\r
+ Trace("qcf-check") << " ... Spurious instantiation (cannot assign unassigned variables)" << std::endl;\r
}\r
}else{\r
- Trace("qcf-check") << " ... Spurious instantiation (cannot assign unassigned variables)" << std::endl;\r
+ Trace("qcf-check") << " ... Spurious instantiation (does not meet variable constraints)" << std::endl;\r
}\r
- }else{\r
- Trace("qcf-check") << " ... Spurious instantiation (does not meet variable constraints)" << std::endl;\r
+ }\r
+ if( d_conflict ){\r
+ break;\r
}\r
}\r
}\r
- if( d_conflict ){\r
- break;\r
- }\r
}\r
if( addedLemmas>0 ){\r
d_quantEngine->flushLemmas();\r
double clSet2 = double(clock())/double(CLOCKS_PER_SEC);\r
Trace("qcf-engine") << "Finished conflict find engine, time = " << (clSet2-clSet);\r
if( addedLemmas>0 ){\r
- Trace("qcf-engine") << ", effort = " << ( d_effort==effort_conflict ? "conflict" : ( d_effort==effort_prop_eq ? "prop_eq" : "mc" ) );\r
+ Trace("qcf-engine") << ", effort = " << ( d_effort==effort_conflict ? "conflict" : ( d_effort==effort_prop_eq ? "prop_eq" : (d_effort==effort_partial ? "partial" : "mc" ) ) );\r
Trace("qcf-engine") << ", addedLemmas = " << addedLemmas;\r
}\r
Trace("qcf-engine") << std::endl;\r
}else{\r
d_eqcs[rtn].push_back( r );\r
}\r
+ eq::EqClassIterator eqc_i = eq::EqClassIterator( r, getEqualityEngine() );\r
+ while( !eqc_i.isFinished() ){\r
+ TNode n = (*eqc_i);\r
+ if( quantifiers::TermDb::hasBoundVarAttr( n ) ){\r
+ std::cout << "BAD TERM IN DB : " << n << std::endl;\r
+ exit( 199 );\r
+ }\r
+ ++eqc_i;\r
+ }\r
+\r
//if( r.getType().isInteger() ){\r
// Trace("qcf-mv") << "Model value for eqc(" << r << ") : " << d_quantEngine->getValuation().getModelValue( r ) << std::endl;\r
//}\r
QuantConflictFind::Statistics::Statistics():\r
d_inst_rounds("QuantConflictFind::Inst_Rounds", 0),\r
d_conflict_inst("QuantConflictFind::Instantiations_Conflict_Find", 0 ),\r
- d_prop_inst("QuantConflictFind::Instantiations_Prop", 0 )\r
+ d_prop_inst("QuantConflictFind::Instantiations_Prop", 0 ),\r
+ d_partial_inst("QuantConflictFind::Instantiations_Partial", 0 )\r
{\r
StatisticsRegistry::registerStat(&d_inst_rounds);\r
StatisticsRegistry::registerStat(&d_conflict_inst);\r
StatisticsRegistry::registerStat(&d_prop_inst);\r
+ StatisticsRegistry::registerStat(&d_partial_inst);\r
}\r
\r
QuantConflictFind::Statistics::~Statistics(){\r
StatisticsRegistry::unregisterStat(&d_inst_rounds);\r
StatisticsRegistry::unregisterStat(&d_conflict_inst);\r
StatisticsRegistry::unregisterStat(&d_prop_inst);\r
+ StatisticsRegistry::unregisterStat(&d_partial_inst);\r
}\r
\r
}
\ No newline at end of file