}\r
\r
\r
-void QuantInfo::initialize( Node q ) {\r
+void QuantInfo::initialize( Node q, Node qn ) {\r
d_q = q;\r
for( unsigned i=0; i<q[0].getNumChildren(); i++ ){\r
d_match.push_back( TNode::null() );\r
d_match_term.push_back( TNode::null() );\r
}\r
+\r
+ //register the variables\r
+ for( unsigned i=0; i<q[0].getNumChildren(); i++ ){\r
+ d_var_num[q[0][i]] = i;\r
+ d_vars.push_back( q[0][i] );\r
+ }\r
+\r
+ registerNode( qn, true, true );\r
+\r
+\r
+ Trace("qcf-qregister") << "- Make match gen structure..." << std::endl;\r
+ d_mg = new MatchGen( this, qn, true );\r
+\r
+ if( d_mg->isValid() ){\r
+ for( unsigned j=q[0].getNumChildren(); j<d_vars.size(); j++ ){\r
+ d_var_mg[j] = new MatchGen( this, d_vars[j], false, true );\r
+ if( !d_var_mg[j]->isValid() ){\r
+ d_mg->setInvalid();\r
+ break;\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
+ }\r
+ }\r
+ */\r
+ }\r
}\r
\r
+void QuantInfo::registerNode( Node n, bool hasPol, bool pol ) {\r
+ if( n.getKind()==FORALL ){\r
+ //do nothing\r
+ }else{\r
+ if( n.getKind()!=OR && n.getKind()!=AND && n.getKind()!=IFF && n.getKind()!=ITE && n.getKind()!=NOT ){\r
+ if( quantifiers::TermDb::hasBoundVarAttr( n ) ){\r
+ //literals\r
+ if( n.getKind()==APPLY_UF ){\r
+ flatten( n );\r
+ }else if( n.getKind()==EQUAL ){\r
+ for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
+ flatten( n[i] );\r
+ }\r
+ }\r
+ }\r
+ }\r
+ if( n.getKind()==BOUND_VARIABLE ){\r
+ d_has_var[n] = true;\r
+ }\r
+ for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
+ bool newHasPol;\r
+ bool newPol;\r
+ QuantPhaseReq::getPolarity( n, i, hasPol, pol, newHasPol, newPol );\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
+ }\r
+ }\r
+}\r
+\r
+void QuantInfo::flatten( Node n ) {\r
+ if( quantifiers::TermDb::hasBoundVarAttr( n ) && n.getKind()!=BOUND_VARIABLE ){\r
+ if( d_var_num.find( n )==d_var_num.end() ){\r
+ //Trace("qcf-qregister") << " Flatten term " << n[i] << std::endl;\r
+ d_var_num[n] = d_vars.size();\r
+ d_vars.push_back( n );\r
+ d_match.push_back( TNode::null() );\r
+ d_match_term.push_back( TNode::null() );\r
+ for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
+ flatten( n[i] );\r
+ }\r
+ }\r
+ }\r
+}\r
+\r
+\r
void QuantInfo::reset_round( QuantConflictFind * p ) {\r
for( unsigned i=0; i<d_match.size(); i++ ){\r
d_match[i] = TNode::null();\r
std::vector< int > eqc_count;\r
bool doFail = false;\r
do {\r
+ if( doFail ){\r
+ Trace("qcf-check-unassign") << "Failure, try again..." << std::endl;\r
+ }\r
bool invalidMatch = false;\r
while( ( index>=0 && (int)index<(int)unassigned[r].size() ) || invalidMatch || doFail ){\r
invalidMatch = false;\r
}while( index>=0 && eqc_count[index]==-1 );\r
}\r
}else{\r
- Assert( index==(int)eqc_count.size()-1 );\r
+ Assert( doFail || index==(int)eqc_count.size()-1 );\r
if( !doFail && eqc_count[index]<(int)p->d_eqcs[unassigned_tn[r][index]].size() ){\r
int currIndex = eqc_count[index];\r
eqc_count[index]++;\r
}\r
}\r
\r
+\r
/*\r
struct MatchGenSort {\r
MatchGen * d_mg;\r
};\r
*/\r
\r
-MatchGen::MatchGen( QuantConflictFind * p, Node q, Node n, bool isTop, bool isVar ){\r
+MatchGen::MatchGen( QuantInfo * qi, Node n, bool isTop, bool isVar ){\r
Trace("qcf-qregister-debug") << "Make match gen for " << n << ", top/var = " << isTop << " " << isVar << std::endl;\r
std::vector< Node > qni_apps;\r
d_qni_size = 0;\r
if( isVar ){\r
- Assert( p->d_qinfo[q].d_var_num.find( n )!=p->d_qinfo[q].d_var_num.end() );\r
- if( p->isHandledUfTerm( n ) ){\r
- d_qni_var_num[0] = p->d_qinfo[q].getVarNum( n );\r
+ Assert( qi->d_var_num.find( n )!=qi->d_var_num.end() );\r
+ if( isHandledUfTerm( n ) ){\r
+ d_qni_var_num[0] = qi->getVarNum( n );\r
d_qni_size++;\r
d_type = typ_var;\r
d_type_not = false;\r
for( unsigned j=0; j<d_n.getNumChildren(); j++ ){\r
Node nn = d_n[j];\r
Trace("qcf-qregister-debug") << " " << d_qni_size;\r
- if( p->d_qinfo[q].isVar( nn ) ){\r
- Trace("qcf-qregister-debug") << " is var #" << p->d_qinfo[q].d_var_num[nn] << std::endl;\r
- d_qni_var_num[d_qni_size] = p->d_qinfo[q].d_var_num[nn];\r
+ if( qi->isVar( nn ) ){\r
+ Trace("qcf-qregister-debug") << " is var #" << qi->d_var_num[nn] << std::endl;\r
+ d_qni_var_num[d_qni_size] = qi->d_var_num[nn];\r
}else{\r
Trace("qcf-qregister-debug") << " is gterm " << nn << std::endl;\r
d_qni_gterm[d_qni_size] = nn;\r
//non-literals\r
d_type = typ_formula;\r
for( unsigned i=0; i<d_n.getNumChildren(); i++ ){\r
- d_children.push_back( MatchGen( p, q, d_n[i] ) );\r
+ d_children.push_back( MatchGen( qi, d_n[i] ) );\r
if( d_children[d_children.size()-1].d_type==typ_invalid ){\r
setInvalid();\r
break;\r
d_type = typ_invalid;\r
//literals\r
if( d_n.getKind()==APPLY_UF ){\r
- Assert( p->d_qinfo[q].isVar( d_n ) );\r
+ Assert( qi->isVar( d_n ) );\r
d_type = typ_pred;\r
}else if( d_n.getKind()==EQUAL ){\r
for( unsigned i=0; i<2; i++ ){\r
if( quantifiers::TermDb::hasBoundVarAttr( d_n[i] ) ){\r
- Assert( p->d_qinfo[q].isVar( d_n[i] ) );\r
+ Assert( qi->isVar( d_n[i] ) );\r
+ }else{\r
+ d_qni_gterm[i] = d_n[i];\r
}\r
}\r
d_type = typ_eq;\r
\r
//set up processing matches\r
if( d_type==typ_invalid ){\r
- //d_child_counter = 0;\r
+ if( p->d_effort>QuantConflictFind::effort_conflict ){\r
+ d_child_counter = 0;\r
+ }\r
}else if( d_type==typ_ground ){\r
if( d_ground_eval[0]==( d_tgt ? p->d_true : p->d_false ) ){\r
d_child_counter = 0;\r
}\r
}else if( d_type==typ_var ){\r
- Assert( p->isHandledUfTerm( d_n ) );\r
+ Assert( isHandledUfTerm( d_n ) );\r
Node f = d_n.getOperator();\r
Debug("qcf-match-debug") << " reset: Var will match operators of " << f << std::endl;\r
QcfNodeIndex * qni = p->getQcfNodeIndex( Node::null(), f );\r
d_tgt = true;\r
}else{\r
for( unsigned i=0; i<2; i++ ){\r
- nn[i] = qi->getCurrentValue( d_n[i] );\r
+ TNode nc;\r
+ std::map< int, TNode >::iterator it = d_qni_gterm_rep.find( i );\r
+ if( it!=d_qni_gterm_rep.end() ){\r
+ nc = it->second;\r
+ }else{\r
+ nc = d_n[i];\r
+ }\r
+ nn[i] = qi->getCurrentValue( nc );\r
vn[i] = qi->getCurrentRepVar( qi->getVarNum( nn[i] ) );\r
}\r
}\r
d_children.clear();\r
}\r
\r
+bool MatchGen::isHandledUfTerm( TNode n ) {\r
+ return n.getKind()==APPLY_UF;\r
+}\r
+\r
+Node MatchGen::getFunction( Node n ) {\r
+ if( isHandledUfTerm( n ) ){\r
+ return n.getOperator();\r
+ }else{\r
+ return Node::null();\r
+ }\r
+}\r
\r
\r
QuantConflictFind::QuantConflictFind( QuantifiersEngine * qe, context::Context* c ) :\r
d_false = NodeManager::currentNM()->mkConst<bool>(false);\r
}\r
\r
-Node QuantConflictFind::getFunction( Node n, int& index, bool isQuant ) {\r
- if( isQuant && !quantifiers::TermDb::hasBoundVarAttr( n ) ){\r
- index = 0;\r
- return n;\r
- }else if( isHandledUfTerm( n ) ){\r
- /*\r
- std::map< Node, Node >::iterator it = d_op_node.find( n.getOperator() );\r
- if( it==d_op_node.end() ){\r
- std::vector< Node > children;\r
- children.push_back( n.getOperator() );\r
- for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
- children.push_back( getFv( n[i].getType() ) );\r
- }\r
- Node nn = NodeManager::currentNM()->mkNode( n.getKind(), children );\r
- d_op_node[n.getOperator()] = nn;\r
- return nn;\r
- }else{\r
- return it->second;\r
- }*/\r
- index = 1;\r
- return n.getOperator();\r
- }else{\r
- return Node::null();\r
- }\r
-}\r
-\r
Node QuantConflictFind::mkEqNode( Node a, Node b ) {\r
if( a.getType().isBoolean() ){\r
return a.iffNode( b );\r
\r
//-------------------------------------------------- registration\r
\r
-void QuantConflictFind::registerNode( Node q, Node n, bool hasPol, bool pol ) {\r
- if( n.getKind()==FORALL ){\r
- //do nothing\r
- }else{\r
- //qcf->d_node = n;\r
- bool recurse = true;\r
- if( n.getKind()!=OR && n.getKind()!=AND && n.getKind()!=IFF && n.getKind()!=ITE && n.getKind()!=NOT ){\r
- if( quantifiers::TermDb::hasBoundVarAttr( n ) ){\r
- //literals\r
-\r
- /*\r
- if( n.getKind()==APPLY_UF || ( n.getKind()==EQUAL && ( n[0].getKind()==BOUND_VARIABLE || n[1].getKind()==BOUND_VARIABLE ) ) ){\r
- for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
- flatten( q, n[i] );\r
- }\r
- }else if( n.getKind()==EQUAL ){\r
- for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
- for( unsigned j=0; j<n[i].getNumChildren(); j++ ){\r
- flatten( q, n[i][j] );\r
- }\r
- }\r
- }\r
-\r
- */\r
-\r
- if( n.getKind()==APPLY_UF ){\r
- flatten( q, n );\r
- }else if( n.getKind()==EQUAL ){\r
- for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
- flatten( q, n[i] );\r
- }\r
- }\r
-\r
- }else{\r
- Trace("qcf-qregister") << " RegisterGroundLit : " << n;\r
- }\r
- recurse = false;\r
- }\r
- if( recurse ){\r
- for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
- bool newHasPol;\r
- bool newPol;\r
- QuantPhaseReq::getPolarity( n, i, hasPol, pol, newHasPol, newPol );\r
- //QcfNode * qcfc = new QcfNode( d_c );\r
- //qcfc->d_parent = qcf;\r
- //qcf->d_child[i] = qcfc;\r
- registerNode( q, n[i], newHasPol, newPol );\r
- }\r
- }\r
- }\r
-}\r
-\r
-void QuantConflictFind::flatten( Node q, Node n ) {\r
- if( quantifiers::TermDb::hasBoundVarAttr( n ) && n.getKind()!=BOUND_VARIABLE ){\r
- if( d_qinfo[q].d_var_num.find( n )==d_qinfo[q].d_var_num.end() ){\r
- //Trace("qcf-qregister") << " Flatten term " << n[i] << std::endl;\r
- d_qinfo[q].d_var_num[n] = d_qinfo[q].d_vars.size();\r
- d_qinfo[q].d_vars.push_back( n );\r
- d_qinfo[q].d_match.push_back( TNode::null() );\r
- d_qinfo[q].d_match_term.push_back( TNode::null() );\r
- }\r
- for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
- flatten( q, n[i] );\r
- }\r
- }\r
-}\r
-\r
void QuantConflictFind::registerQuantifier( Node q ) {\r
d_quants.push_back( q );\r
d_quant_id[q] = d_quants.size();\r
- d_qinfo[q].initialize( q );\r
Trace("qcf-qregister") << "Register ";\r
debugPrintQuant( "qcf-qregister", q );\r
Trace("qcf-qregister") << " : " << q << std::endl;\r
-\r
- //register the variables\r
- for( unsigned i=0; i<q[0].getNumChildren(); i++ ){\r
- d_qinfo[q].d_var_num[q[0][i]] = i;\r
- d_qinfo[q].d_vars.push_back( q[0][i] );\r
- }\r
-\r
//make QcfNode structure\r
Trace("qcf-qregister") << "- Get relevant equality/disequality pairs, calculate flattening..." << std::endl;\r
- //d_qinfo[q].d_cf = new QcfNode( d_c );\r
- registerNode( q, q[1], true, true );\r
+ d_qinfo[q].initialize( q, q[1] );\r
\r
//debug print\r
Trace("qcf-qregister") << "- Flattened structure is :" << std::endl;\r
}\r
}\r
\r
- Trace("qcf-qregister") << "- Make match gen structure..." << std::endl;\r
- d_qinfo[q].d_mg = new MatchGen( this, q, q[1], true );\r
-\r
- for( unsigned j=q[0].getNumChildren(); j<d_qinfo[q].d_vars.size(); j++ ){\r
- d_qinfo[q].d_var_mg[j] = new MatchGen( this, q, d_qinfo[q].d_vars[j], false, true );\r
- if( !d_qinfo[q].d_var_mg[j]->isValid() ){\r
- d_qinfo[q].d_mg->setInvalid();\r
- break;\r
- }\r
- }\r
-\r
Trace("qcf-qregister") << "Done registering quantifier." << std::endl;\r
}\r
\r
}\r
}\r
Node QuantConflictFind::evaluateTerm( Node n ) {\r
- if( isHandledUfTerm( n ) ){\r
+ if( MatchGen::isHandledUfTerm( n ) ){\r
Node nn;\r
if( getEqualityEngine()->hasTerm( n ) ){\r
computeArgReps( n );\r
bool isRedundant;\r
std::map< TNode, std::vector< TNode > >::iterator it_na;\r
TNode fn;\r
- if( isHandledUfTerm( n ) ){\r
+ if( MatchGen::isHandledUfTerm( n ) ){\r
computeArgReps( n );\r
it_na = d_arg_reps.find( n );\r
Assert( it_na!=d_arg_reps.end() );\r
Node nadd = d_eqc_uf_terms[n.getOperator()].d_children[r].addTerm( n, d_arg_reps[n] );\r
isRedundant = (nadd!=n);\r
d_uf_terms[n.getOperator()].addTerm( n, d_arg_reps[n] );\r
- if( !isRedundant ){\r
- int jindex;\r
- fn = getFunction( n, jindex );\r
- }\r
}else{\r
isRedundant = false;\r
}\r
\r
void QuantConflictFind::computeArgReps( TNode n ) {\r
if( d_arg_reps.find( n )==d_arg_reps.end() ){\r
- Assert( isHandledUfTerm( n ) );\r
+ Assert( MatchGen::isHandledUfTerm( n ) );\r
for( unsigned j=0; j<n.getNumChildren(); j++ ){\r
d_arg_reps[n].push_back( getRepresentative( n[j] ) );\r
}\r
}\r
}\r
-bool QuantConflictFind::isHandledUfTerm( TNode n ) {\r
- return n.getKind()==APPLY_UF;\r
-}\r
-\r
\r
//-------------------------------------------------- debugging\r
\r