diff options
author | Andrew Reynolds <andrew.j.reynolds@gmail.com> | 2021-01-26 14:11:10 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-01-26 14:11:10 -0600 |
commit | 06e367c39bf080b9a82dea82ebdf8b9fb79409d5 (patch) | |
tree | ae10b1a8241473bb88cabf205af5372fda57b9f4 /src/theory/quantifiers/equality_infer.cpp | |
parent | ca648afb2a7574991b1dc9817c1b8e2546548073 (diff) |
Remove deprecated quantifiers modules (#5820)
Diffstat (limited to 'src/theory/quantifiers/equality_infer.cpp')
-rw-r--r-- | src/theory/quantifiers/equality_infer.cpp | 440 |
1 files changed, 0 insertions, 440 deletions
diff --git a/src/theory/quantifiers/equality_infer.cpp b/src/theory/quantifiers/equality_infer.cpp deleted file mode 100644 index 63fecdd9e..000000000 --- a/src/theory/quantifiers/equality_infer.cpp +++ /dev/null @@ -1,440 +0,0 @@ -/********************* */ -/*! \file equality_infer.cpp - ** \verbatim - ** Top contributors (to current version): - ** Andrew Reynolds, Morgan Deters, Tianyi Liang - ** This file is part of the CVC4 project. - ** Copyright (c) 2009-2020 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 Method for inferring equalities between arithmetic equivalence classes, - ** inspired by "A generalization of Shostak's method for combining decision procedures" Barrett et al. Figure 1. - ** - **/ - -#include "theory/quantifiers/equality_infer.h" - -#include "context/context_mm.h" -#include "theory/rewriter.h" -#include "theory/arith/arith_msum.h" - -using namespace CVC4; -using namespace CVC4::kind; -using namespace CVC4::theory; -using namespace CVC4::theory::quantifiers; -using namespace std; - -namespace CVC4 { - -EqualityInference::EqcInfo::EqcInfo(context::Context* c) : d_rep( c ), d_valid( c, false ), d_solved( c, false ), d_master(c) -//, d_rep_exp(c), d_uselist(c) -{ - -} - -EqualityInference::EqualityInference( context::Context* c, bool trackExp ) : -d_c( c ), d_trackExplain( trackExp ), d_elim_vars( c ), -d_rep_to_eqc( c ), d_rep_exp( c ), d_uselist( c ), d_pending_merges( c ), d_pending_merge_exp( c ){ - d_one = NodeManager::currentNM()->mkConst( Rational( 1 ) ); - d_true = NodeManager::currentNM()->mkConst( true ); -} - -EqualityInference::~EqualityInference(){ - for( std::map< Node, EqcInfo * >::iterator it = d_eqci.begin(); it != d_eqci.end(); ++it ){ - delete it->second; - } -} - -void EqualityInference::addToExplanation( std::vector< Node >& exp, Node e ) { - if( std::find( exp.begin(), exp.end(), e )==exp.end() ){ - Trace("eq-infer-debug2") << "......add to explanation " << e << std::endl; - exp.push_back( e ); - } -} - -void EqualityInference::addToExplanationEqc( std::vector< Node >& exp, Node eqc ) { - NodeIntMap::iterator re_i = d_rep_exp.find( eqc ); - if( re_i!=d_rep_exp.end() ){ - for( int i=0; i<(*re_i).second; i++ ){ - addToExplanation( exp, d_rep_exp_data[eqc][i] ); - } - } - //for( unsigned i=0; i<d_eqci[n]->d_rep_exp.size(); i++ ){ - // addToExplanation( exp, d_eqci[n]->d_rep_exp[i] ); - //} -} - -void EqualityInference::addToExplanationEqc( Node eqc, std::vector< Node >& exp_to_add ) { - NodeIntMap::iterator re_i = d_rep_exp.find( eqc ); - int n_re = 0; - if( re_i != d_rep_exp.end() ){ - n_re = (*re_i).second; - } - d_rep_exp[eqc] = n_re + exp_to_add.size(); - for( unsigned i=0; i<exp_to_add.size(); i++ ){ - if( n_re<(int)d_rep_exp_data[eqc].size() ){ - d_rep_exp_data[eqc][n_re] = exp_to_add[i]; - }else{ - d_rep_exp_data[eqc].push_back( exp_to_add[i] ); - } - n_re++; - } - //for( unsigned i=0; i<exp_to_add.size(); i++ ){ - // eqci->d_rep_exp.push_back( exp_to_add[i] ); - //} -} - -Node EqualityInference::getMaster( Node t, EqcInfo * eqc, bool& updated, Node new_m ) { - if( !eqc->d_master.get().isNull() ){ - if( eqc->d_master.get()==t ){ - if( !new_m.isNull() && t!=new_m ){ - eqc->d_master = new_m; - updated = true; - return new_m; - }else{ - return t; - } - }else{ - Assert(d_eqci.find(eqc->d_master.get()) != d_eqci.end()); - EqcInfo * eqc_m = d_eqci[eqc->d_master.get()]; - Node m = getMaster( eqc->d_master.get(), eqc_m, updated, new_m ); - eqc->d_master = m; - return m; - } - }else{ - return Node::null(); - } -} - -//update the internal "master" representative of the equivalence class, return true if the merge was non-redundant -bool EqualityInference::updateMaster( Node t1, Node t2, EqcInfo * eqc1, EqcInfo * eqc2 ) { - bool updated = false; - Node m1 = getMaster( t1, eqc1, updated ); - if( m1.isNull() ){ - eqc1->d_master = t2; - if( eqc2->d_master.get().isNull() ){ - eqc2->d_master = t2; - } - return true; - }else{ - updated = false; - Node m2 = getMaster( t2, eqc2, updated, m1); - if( m2.isNull() ){ - eqc2->d_master = m1; - return true; - }else{ - return updated; - } - } -} - -void EqualityInference::eqNotifyNewClass(TNode t) { - if( t.getType().isReal() ){ - Trace("eq-infer") << "Notify equivalence class : " << t << std::endl; - EqcInfo * eqci; - std::map< Node, EqcInfo * >::iterator itec = d_eqci.find( t ); - if( itec==d_eqci.end() ){ - eqci = new EqcInfo( d_c ); - d_eqci[t] = eqci; - }else{ - eqci = itec->second; - } - Assert(!eqci->d_valid.get()); - if( !eqci->d_solved.get() ){ - //somewhat strange: t may not be in rewritten form - Node r = Rewriter::rewrite( t ); - std::map< Node, Node > msum; - if (ArithMSum::getMonomialSum(r, msum)) - { - Trace("eq-infer-debug2") << "...process monomial sum, size = " << msum.size() << std::endl; - eqci->d_valid = true; - bool changed = false; - std::vector< Node > exp; - std::vector< Node > children; - for( std::map< Node, Node >::iterator it = msum.begin(); it != msum.end(); ++it ) { - Trace("eq-infer-debug2") << "...process child " << it->first << ", " << it->second << std::endl; - if( !it->first.isNull() ){ - Node n = it->first; - BoolMap::const_iterator itv = d_elim_vars.find( n ); - if( itv!=d_elim_vars.end() ){ - changed = true; - Assert(d_eqci.find(n) != d_eqci.end()); - Assert(n != t); - Assert(d_eqci[n]->d_solved.get()); - Trace("eq-infer-debug2") << "......its solved form is " << d_eqci[n]->d_rep.get() << std::endl; - if( d_trackExplain ){ - //track the explanation: justified by explanation for each substitution - addToExplanationEqc( exp, n ); - } - n = d_eqci[n]->d_rep; - Assert(!n.isNull()); - } - if( it->second.isNull() ){ - children.push_back( n ); - }else{ - children.push_back( NodeManager::currentNM()->mkNode( MULT, it->second, n ) ); - } - }else{ - Assert(!it->second.isNull()); - children.push_back( it->second ); - } - } - Trace("eq-infer-debug2") << "...children size = " << children.size() << std::endl; - bool mvalid = true; - if( changed ){ - r = children.size()==1 ? children[0] : NodeManager::currentNM()->mkNode( PLUS, children ); - Trace("eq-infer-debug2") << "...pre-rewrite : " << r << std::endl; - r = Rewriter::rewrite( r ); - msum.clear(); - if (!ArithMSum::getMonomialSum(r, msum)) - { - mvalid = false; - } - } - Trace("eq-infer") << "...value is " << r << std::endl; - setEqcRep( t, r, exp, eqci ); - if( mvalid ){ - for( std::map< Node, Node >::iterator it = msum.begin(); it != msum.end(); ++it ){ - if( !it->first.isNull() ){ - addToUseList( it->first, t ); - } - } - } - }else{ - eqci->d_valid = false; - } - } - } -} - -void EqualityInference::addToUseList( Node used, Node eqc ) { -#if 1 - NodeIntMap::iterator ul_i = d_uselist.find( used ); - int n_ul = 0; - if( ul_i != d_uselist.end() ){ - n_ul = (*ul_i).second; - } - d_uselist[ used ] = n_ul + 1; - Trace("eq-infer-debug") << " add to use list : " << used << " -> " << eqc << std::endl; - if( n_ul<(int)d_uselist_data[used].size() ){ - d_uselist_data[used][n_ul] = eqc; - }else{ - d_uselist_data[used].push_back( eqc ); - } -#else - std::map< Node, EqcInfo * >::iterator itu = d_eqci.find( used ); - EqcInfo * eqci_used; - if( itu==d_eqci.end() ){ - eqci_used = new EqcInfo( d_c ); - d_eqci[used] = eqci_used; - }else{ - eqci_used = itu->second; - } - Trace("eq-infer-debug") << " add to use list : " << used << " -> " << eqc << std::endl; - eqci_used->d_uselist.push_back( eqc ); -#endif -} - -void EqualityInference::setEqcRep( Node t, Node r, std::vector< Node >& exp_to_add, EqcInfo * eqci ) { - eqci->d_rep = r; - if( d_trackExplain ){ - addToExplanationEqc( t, exp_to_add ); - } - //if this is an active equivalence class - if( eqci->d_valid.get() ){ - Trace("eq-infer-debug") << "Set eqc rep " << t << " -> " << r << std::endl; - NodeMap::const_iterator itr = d_rep_to_eqc.find( r ); - if( itr==d_rep_to_eqc.end() ){ - d_rep_to_eqc[r] = t; - }else{ - //merge two equivalence classes - Node t2 = (*itr).second; - //check if it is valid - std::map< Node, EqcInfo * >::iterator itc = d_eqci.find( t2 ); - if( itc!=d_eqci.end() && itc->second->d_valid.get() ){ - //if we haven't already determined they should be merged - if( updateMaster( t, t2, eqci, itc->second ) ){ - Trace("eq-infer") << "Infer two equivalence classes are equal : " << t << " " << t2 << std::endl; - Trace("eq-infer") << " since they both normalize to : " << r << std::endl; - d_pending_merges.push_back( t.eqNode( t2 ) ); - if( d_trackExplain ){ - std::vector< Node > exp; - for( unsigned j=0; j<2; j++ ){ - addToExplanationEqc( exp, j==0 ? t : t2 ); - } - Node exp_n = exp.empty() ? d_true : ( exp.size()==1 ? exp[0] : NodeManager::currentNM()->mkNode( AND, exp ) ); - Trace("eq-infer") << " explanation : " << exp_n << std::endl; - d_pending_merge_exp.push_back( exp_n ); - } - } - } - } - } -} - -void EqualityInference::eqNotifyMerge(TNode t1, TNode t2) { - Assert(!t1.isNull()); - Assert(!t2.isNull()); - std::map< Node, EqcInfo * >::iterator itv1 = d_eqci.find( t1 ); - if( itv1!=d_eqci.end() ){ - std::map< Node, EqcInfo * >::iterator itv2 = d_eqci.find( t2 ); - if( itv2!=d_eqci.end() ){ - Trace("eq-infer") << "Merge equivalence classes : " << t2 << " into " << t1 << std::endl; - Node tr1 = itv1->second->d_rep; - Node tr2 = itv2->second->d_rep; - itv2->second->d_valid = false; - Trace("eq-infer") << "Representatives : " << tr2 << " into " << tr1 << std::endl; - if( tr1!=tr2 ){ - Node eq = tr1.eqNode( tr2 ); - std::map< Node, Node > msum; - if (ArithMSum::getMonomialSumLit(eq, msum)) - { - Node v_solve; - //solve for variables with no coefficient - if( Trace.isOn("eq-infer-debug2") ){ - Trace("eq-infer-debug2") << "Monomial sum : " << std::endl; - for( std::map< Node, Node >::iterator it = msum.begin(); it != msum.end(); ++it ) { - Trace("eq-infer-debug2") << " " << it->first << " * " << it->second << std::endl; - } - } - for( std::map< Node, Node >::iterator it = msum.begin(); it != msum.end(); ++it ) { - Node n = it->first; - if( !n.isNull() ){ - bool canSolve = false; - if( it->second.isNull() ){ - canSolve = true; - }else{ - //Assert( it->second.isConst() ); - Rational r = it->second.getConst<Rational>(); - canSolve = r.isOne() || r.isNegativeOne(); - } - if( canSolve ){ - v_solve = n; - break; - } - } - } - Trace("eq-infer-debug") << "solve for variable : " << v_solve << std::endl; - if( !v_solve.isNull() ){ - //solve for v_solve - Node veq; - if (ArithMSum::isolate(v_solve, msum, veq, kind::EQUAL, true) == 1) - { - Node v_value = veq[1]; - Trace("eq-infer") << "...solved " << v_solve << " == " << v_value << std::endl; - Assert(d_elim_vars.find(v_solve) == d_elim_vars.end()); - d_elim_vars[v_solve] = true; - //store value in eqc info - EqcInfo * eqci_solved; - std::map< Node, EqcInfo * >::iterator itec = d_eqci.find( v_solve ); - if( itec==d_eqci.end() ){ - eqci_solved = new EqcInfo( d_c ); - d_eqci[v_solve] = eqci_solved; - }else{ - eqci_solved = itec->second; - } - eqci_solved->d_solved = true; - eqci_solved->d_rep = v_value; - //track the explanation - std::vector< Node > exp; - if( d_trackExplain ){ - //explanation is t1 = t2 + their explanations - exp.push_back( t1.eqNode( t2 ) ); - for( unsigned i=0; i<2; i++ ){ - addToExplanationEqc( exp, i==0 ? t1 : t2 ); - } - if( Trace.isOn("eq-infer-debug") ){ - Trace("eq-infer-debug") << " explanation for solving " << v_solve << " is "; - for( unsigned i=0; i<exp.size(); i++ ){ - Trace("eq-infer-debug") << exp[i] << " "; - } - Trace("eq-infer-debug") << std::endl; - } - addToExplanationEqc( v_solve, exp ); - } - - std::vector< Node > new_use; - for( std::map< Node, Node >::iterator itmm = msum.begin(); itmm != msum.end(); ++itmm ){ - Node n = itmm->first; - if( !n.isNull() && n!=v_solve ){ - new_use.push_back( n ); - addToUseList( n, v_solve ); - } - } - - //go through all equivalence classes that may refer to v_solve - std::map< Node, bool > processed; - processed[v_solve] = true; - NodeIntMap::iterator ul_i = d_uselist.find( v_solve ); - if( ul_i != d_uselist.end() ){ - int n_ul = (*ul_i).second; - Trace("eq-infer-debug") << " use list size = " << n_ul << std::endl; - for( int j=0; j<n_ul; j++ ){ - Node r = d_uselist_data[v_solve][j]; - //Trace("eq-infer-debug") << " use list size = " << eqci_solved->d_uselist.size() << std::endl; - //for( unsigned j=0; j<eqci_solved->d_uselist.size(); j++ ){ - // Node r = eqci_solved->d_uselist[j]; - if( processed.find( r )==processed.end() ){ - processed[r] = true; - std::map< Node, EqcInfo * >::iterator itt = d_eqci.find( r ); - if( itt!=d_eqci.end() && ( itt->second->d_valid || itt->second->d_solved ) ){ - std::map< Node, Node > msum2; - if (ArithMSum::getMonomialSum(itt->second->d_rep.get(), - msum2)) - { - std::map< Node, Node >::iterator itm = msum2.find( v_solve ); - if( itm!=msum2.end() ){ - //substitute in solved form - std::map< Node, Node >::iterator itm2 = msum2.find( v_value ); - if( itm2 == msum2.end() ){ - msum2[v_value] = itm->second; - }else{ - msum2[v_value] = NodeManager::currentNM()->mkNode( PLUS, itm2->second.isNull() ? d_one : itm2->second, - itm->second.isNull() ? d_one : itm->second ); - } - msum2.erase( itm ); - Node rr = ArithMSum::mkNode(msum2); - rr = Rewriter::rewrite( rr ); - Trace("eq-infer") << "......update " << itt->first << " => " << rr << std::endl; - setEqcRep( itt->first, rr, exp, itt->second ); - //update use list - for( unsigned i=0; i<new_use.size(); i++ ){ - addToUseList( new_use[i], r ); - } - } - }else{ - itt->second->d_valid = false; - } - } - } - } - } - Trace("eq-infer") << "...finished solved." << std::endl; - } - } - } - } - }else{ - //no information to merge - } - }else{ - //carry information (this might happen for non-linear t1 and linear t2?) - std::map< Node, EqcInfo * >::iterator itv2 = d_eqci.find( t2 ); - if( itv2!=d_eqci.end() ){ - d_eqci[t1] = d_eqci[t2]; - d_eqci[t2] = NULL; - } - } -} - -Node EqualityInference::getPendingMergeExplanation( unsigned i ) { - if( d_trackExplain ){ - return d_pending_merge_exp[i]; - }else{ - return d_pending_merges[i]; - } -} - -} |