unsigned depth,
unsigned& n_pairs)
{
+ Trace("dt-cg") << "Process at depth " << depth << "/" << arity << std::endl;
if( depth==arity ){
- if( t2!=NULL ){
- Node f1 = t1->getData();
- Node f2 = t2->getData();
- if( !areEqual( f1, f2 ) ){
- Trace("dt-cg") << "Check " << f1 << " and " << f2 << std::endl;
- vector< pair<TNode, TNode> > currentPairs;
- for (unsigned k = 0; k < f1.getNumChildren(); ++ k) {
- TNode x = f1[k];
- TNode y = f2[k];
- Assert(d_equalityEngine->hasTerm(x));
- Assert(d_equalityEngine->hasTerm(y));
- Assert(!areDisequal(x, y));
- Assert(!areCareDisequal(x, y));
- if (!d_equalityEngine->areEqual(x, y))
+ Assert(t2 != nullptr);
+ Node f1 = t1->getData();
+ Node f2 = t2->getData();
+ if (!areEqual(f1, f2))
+ {
+ Trace("dt-cg") << "Check " << f1 << " and " << f2 << std::endl;
+ std::vector<std::pair<TNode, TNode> > currentPairs;
+ for (size_t k = 0, nchild = f1.getNumChildren(); k < nchild; ++k)
+ {
+ TNode x = f1[k];
+ TNode y = f2[k];
+ Assert(d_equalityEngine->hasTerm(x));
+ Assert(d_equalityEngine->hasTerm(y));
+ Assert(!areDisequal(x, y));
+ Assert(!areCareDisequal(x, y));
+ if (!d_equalityEngine->areEqual(x, y))
+ {
+ Trace("dt-cg") << "Arg #" << k << " is " << x << " " << y
+ << std::endl;
+ if (d_equalityEngine->isTriggerTerm(x, THEORY_DATATYPES)
+ && d_equalityEngine->isTriggerTerm(y, THEORY_DATATYPES))
{
- Trace("dt-cg") << "Arg #" << k << " is " << x << " " << y << std::endl;
- if (d_equalityEngine->isTriggerTerm(x, THEORY_DATATYPES)
- && d_equalityEngine->isTriggerTerm(y, THEORY_DATATYPES))
- {
- TNode x_shared = d_equalityEngine->getTriggerTermRepresentative(
- x, THEORY_DATATYPES);
- TNode y_shared = d_equalityEngine->getTriggerTermRepresentative(
- y, THEORY_DATATYPES);
- currentPairs.push_back(make_pair(x_shared, y_shared));
- }
+ TNode x_shared = d_equalityEngine->getTriggerTermRepresentative(
+ x, THEORY_DATATYPES);
+ TNode y_shared = d_equalityEngine->getTriggerTermRepresentative(
+ y, THEORY_DATATYPES);
+ currentPairs.push_back(make_pair(x_shared, y_shared));
}
}
- for (unsigned c = 0; c < currentPairs.size(); ++ c) {
- Trace("dt-cg-pair") << "Pair : " << currentPairs[c].first << " " << currentPairs[c].second << std::endl;
- addCarePair(currentPairs[c].first, currentPairs[c].second);
- n_pairs++;
- }
+ }
+ for (std::pair<TNode, TNode>& p : currentPairs)
+ {
+ Trace("dt-cg-pair")
+ << "Pair : " << p.first << " " << p.second << std::endl;
+ addCarePair(p.first, p.second);
+ n_pairs++;
}
}
- }else{
- if( t2==NULL ){
- if( depth<(arity-1) ){
- //add care pairs internal to each child
- for (std::pair<const TNode, TNodeTrie>& tt : t1->d_data)
- {
- addCarePairs(&tt.second, nullptr, arity, depth + 1, n_pairs);
- }
+ return;
+ }
+ if (t2 == nullptr)
+ {
+ if (depth + 1 < arity)
+ {
+ // add care pairs internal to each child
+ for (std::pair<const TNode, TNodeTrie>& tt : t1->d_data)
+ {
+ Trace("dt-cg-debug") << "Traverse into arg " << tt.first << " at depth "
+ << depth << std::endl;
+ addCarePairs(&tt.second, nullptr, arity, depth + 1, n_pairs);
}
- //add care pairs based on each pair of non-disequal arguments
- for (std::map<TNode, TNodeTrie>::iterator it = t1->d_data.begin();
- it != t1->d_data.end();
- ++it)
+ }
+ // add care pairs based on each pair of non-disequal arguments
+ for (std::map<TNode, TNodeTrie>::iterator it = t1->d_data.begin();
+ it != t1->d_data.end();
+ ++it)
+ {
+ std::map<TNode, TNodeTrie>::iterator it2 = it;
+ ++it2;
+ for (; it2 != t1->d_data.end(); ++it2)
{
- std::map<TNode, TNodeTrie>::iterator it2 = it;
- ++it2;
- for( ; it2 != t1->d_data.end(); ++it2 ){
- if (!d_equalityEngine->areDisequal(it->first, it2->first, false))
+ if (!d_equalityEngine->areDisequal(it->first, it2->first, false))
+ {
+ if (!areCareDisequal(it->first, it2->first))
{
- if( !areCareDisequal(it->first, it2->first) ){
- addCarePairs( &it->second, &it2->second, arity, depth+1, n_pairs );
- }
+ addCarePairs(&it->second, &it2->second, arity, depth + 1, n_pairs);
}
}
}
- }else{
- //add care pairs based on product of indices, non-disequal arguments
- for (std::pair<const TNode, TNodeTrie>& tt1 : t1->d_data)
+ }
+ return;
+ }
+ // add care pairs based on product of indices, non-disequal arguments
+ for (std::pair<const TNode, TNodeTrie>& tt1 : t1->d_data)
+ {
+ for (std::pair<const TNode, TNodeTrie>& tt2 : t2->d_data)
+ {
+ if (!d_equalityEngine->areDisequal(tt1.first, tt2.first, false))
{
- for (std::pair<const TNode, TNodeTrie>& tt2 : t2->d_data)
+ if (!areCareDisequal(tt1.first, tt2.first))
{
- if (!d_equalityEngine->areDisequal(tt1.first, tt2.first, false))
- {
- if (!areCareDisequal(tt1.first, tt2.first))
- {
- addCarePairs(&tt1.second, &tt2.second, arity, depth + 1, n_pairs);
- }
- }
+ Trace("dt-cg-debug")
+ << "Traverse into " << tt1.first << " " << tt2.first
+ << " at depth " << depth << std::endl;
+ addCarePairs(&tt1.second, &tt2.second, arity, depth + 1, n_pairs);
}
}
}
TNode f1 = d_functionTerms[i];
Assert(d_equalityEngine->hasTerm(f1));
Trace("dt-cg-debug") << "...build for " << f1 << std::endl;
- //break into index based on operator, and type of first argument (since some operators are parametric)
+ // Break into index based on operator.
+ // To handle parameteric datatypes, we also indexed based on the overall
+ // type if a constructor, or the type of the argument (e.g. if a selector)
+ // otherwise
Node op = f1.getOperator();
- TypeNode tn = f1[0].getType();
+ TypeNode tn =
+ f1.getKind() == APPLY_CONSTRUCTOR ? f1.getType() : f1[0].getType();
std::vector< TNode > reps;
bool has_trigger_arg = false;
for( unsigned j=0; j<f1.getNumChildren(); j++ ){
has_trigger_arg = true;
}
}
+ Trace("dt-cg-debug") << "...has trigger arg = " << has_trigger_arg
+ << std::endl;
//only may contribute to care pairs if has at least one trigger argument
if( has_trigger_arg ){
index[tn][op].addTerm( f1, reps );
Trace("dt-cg") << "Process index " << tt.first << ", " << t.first << "..."
<< std::endl;
addCarePairs(&t.second, nullptr, arity[t.first], 0, n_pairs);
+ Trace("dt-cg") << "...finish" << std::endl;
}
}
Trace("dt-cg-summary") << "...done, # pairs = " << n_pairs << std::endl;