Currently we expand (sel_C_n x) to (ite (is-C x) (sel_C_n_total x) (uf x)) during ppRewrite. This introduces ITEs very eagerly and moreover is not necessary since we do congruence over selectors.
This makes it so that we don't do this expansion. The code changes to use APPLY_SELECTOR everywhere instead of APPLY_SELECTOR_TOTAL, which can be deleted in a followup PR. It makes some of the datatype utilities more robust and independent of options.
This required changing one detail of the sygus solver to not do evaluation unfolding in cases where a selector chain was wrongly applied, as this now will not rewrite to a constant.
int DTypeConstructor::getSelectorIndexInternal(Node sel) const
{
Assert(isResolved());
- if (options::dtSharedSelectors())
+ Assert(sel.getType().isSelector());
+ // might be a builtin selector
+ if (sel.hasAttribute(DTypeIndexAttr()))
{
- Assert(sel.getType().isSelector());
- TypeNode domainType = sel.getType().getSelectorDomainType();
- computeSharedSelectors(domainType);
- std::map<Node, unsigned>::iterator its =
- d_sharedSelectorIndex[domainType].find(sel);
- if (its != d_sharedSelectorIndex[domainType].end())
- {
- return (int)its->second;
- }
- }
- else
- {
- unsigned sindex = DType::indexOf(sel);
+ size_t sindex = DType::indexOf(sel);
if (getNumArgs() > sindex && d_args[sindex]->getSelector() == sel)
{
return static_cast<int>(sindex);
}
}
+ // otherwise, check shared selector
+ TypeNode domainType = sel.getType().getSelectorDomainType();
+ computeSharedSelectors(domainType);
+ std::map<Node, unsigned>::iterator its =
+ d_sharedSelectorIndex[domainType].find(sel);
+ if (its != d_sharedSelectorIndex[domainType].end())
+ {
+ return (int)its->second;
+ }
return -1;
}
<< std::endl;
// The argument that the selector extracts, or -1 if the selector is
// is wrongly applied.
- int selectorIndex = -1;
- if (k == kind::APPLY_SELECTOR_TOTAL)
- {
- // The argument index of internal selectors is obtained by
- // getSelectorIndexInternal.
- selectorIndex = c.getSelectorIndexInternal(selector);
- }
- else
- {
- // The argument index of external selectors (applications of
- // APPLY_SELECTOR) is given by an attribute and obtained via indexOf below
- // The argument is only valid if it is the proper constructor.
- selectorIndex = utils::indexOf(selector);
- if (selectorIndex < 0
- || selectorIndex >= static_cast<int>(c.getNumArgs()))
- {
- selectorIndex = -1;
- }
- else if (c[selectorIndex].getSelector() != selector)
- {
- selectorIndex = -1;
- }
- }
+ // The argument index of internal selectors is obtained by
+ // getSelectorIndexInternal.
+ int selectorIndex = c.getSelectorIndexInternal(selector);
Trace("datatypes-rewrite-debug") << "Internal selector index is "
<< selectorIndex << std::endl;
if (selectorIndex >= 0)
{
Assert(n.getKind() == APPLY_SELECTOR);
Node selector = n.getOperator();
+ if (!options::dtSharedSelectors()
+ || !selector.hasAttribute(DTypeConsIndexAttr()))
+ {
+ return n;
+ }
// APPLY_SELECTOR always applies to an external selector, cindexOf is
// legal here
size_t cindex = utils::cindexOf(selector);
const DType& dt = utils::datatypeOf(selector);
const DTypeConstructor& c = dt[cindex];
- Node selector_use;
TypeNode ndt = n[0].getType();
- if (options::dtSharedSelectors())
- {
- size_t selectorIndex = utils::indexOf(selector);
- Trace("dt-expand") << "...selector index = " << selectorIndex << std::endl;
- Assert(selectorIndex < c.getNumArgs());
- selector_use = c.getSelectorInternal(ndt, selectorIndex);
- }
- else
- {
- selector_use = selector;
- }
+ size_t selectorIndex = utils::indexOf(selector);
+ Trace("dt-expand") << "...selector index = " << selectorIndex << std::endl;
+ Assert(selectorIndex < c.getNumArgs());
+ Node selector_use = c.getSelectorInternal(ndt, selectorIndex);
NodeManager* nm = NodeManager::currentNM();
- Node sel = nm->mkNode(kind::APPLY_SELECTOR_TOTAL, selector_use, n[0]);
- if (options::dtRewriteErrorSel())
- {
- return sel;
- }
- Node tester = c.getTester();
- Node tst = nm->mkNode(APPLY_TESTER, tester, n[0]);
- SkolemManager* sm = nm->getSkolemManager();
- TypeNode tnw = nm->mkFunctionType(ndt, n.getType());
- Node f = sm->mkSkolemFunction(SkolemFunId::SELECTOR_WRONG, tnw, selector);
- Node sk = nm->mkNode(kind::APPLY_UF, f, n[0]);
- Node ret = nm->mkNode(kind::ITE, tst, sel, sk);
- Trace("dt-expand") << "Expand def : " << n << " to " << ret << std::endl;
- return ret;
+ Node sel = nm->mkNode(kind::APPLY_SELECTOR, selector_use, n[0]);
+ return sel;
}
TrustNode DatatypesRewriter::expandDefinition(Node n)
}
else
{
- b << nm->mkNode(
- APPLY_SELECTOR_TOTAL, dc.getSelectorInternal(tn, i), n[0]);
+ b << nm->mkNode(APPLY_SELECTOR, dc.getSelectorInternal(tn, i), n[0]);
}
}
ret = b;
* Expand an APPLY_SELECTOR term n, return its expanded form. If n is
* (APPLY_SELECTOR selC x)
* its expanded form is
- * (ITE (APPLY_TESTER is-C x)
- * (APPLY_SELECTOR_TOTAL selC' x)
- * (f x))
+ * (APPLY_SELECTOR selC' x)
* where f is a skolem function with id SELECTOR_WRONG, and selC' is the
* internal selector function for selC (possibly a shared selector).
+ * Note that we do not introduce an uninterpreted function here, e.g. to
+ * handle when the selector is misapplied. This is because it suffices to
+ * reason about the original selector term e.g. via congruence.
*/
static Node expandApplySelector(Node n);
/**
Node concAtom = concPol ? conc : conc[0];
concEq = concAtom.eqNode(nm->mkConst(concPol));
}
- if (concEq[0].getKind() != APPLY_SELECTOR_TOTAL)
+ if (concEq[0].getKind() != APPLY_SELECTOR)
{
// can happen for Boolean term variables, which are not currently
// supported.
{
Assert(exp[0].getType().isDatatype());
Node sop = concEq[0].getOperator();
- Node sl = nm->mkNode(APPLY_SELECTOR_TOTAL, sop, exp[0]);
- Node sr = nm->mkNode(APPLY_SELECTOR_TOTAL, sop, exp[1]);
+ Node sl = nm->mkNode(APPLY_SELECTOR, sop, exp[0]);
+ Node sr = nm->mkNode(APPLY_SELECTOR, sop, exp[1]);
// exp[0] = exp[1]
// --------------------- CONG ----------------- DT_COLLAPSE
// s(exp[0]) = s(exp[1]) s(exp[1]) = r
// --------------------------------------------------- TRANS
// s(exp[0]) = r
- Node asn = ProofRuleChecker::mkKindNode(APPLY_SELECTOR_TOTAL);
+ Node asn = ProofRuleChecker::mkKindNode(APPLY_SELECTOR);
Node seq = sl.eqNode(sr);
cdp->addStep(seq, PfRule::CONG, {exp}, {asn, sop});
Node sceq = sr.eqNode(concEq[1]);
Assert(children.empty());
Assert(args.size() == 1);
Node t = args[0];
- if (t.getKind() != kind::APPLY_SELECTOR_TOTAL
+ if (t.getKind() != kind::APPLY_SELECTOR
|| t[0].getKind() != kind::APPLY_CONSTRUCTOR)
{
return Node::null();
bool do_add = true;
if (options().datatypes.sygusSymBreakLazy)
{
- if( n.getKind()==kind::APPLY_SELECTOR_TOTAL ){
+ if (n.getKind() == kind::APPLY_SELECTOR)
+ {
NodeSet::const_iterator it = d_active_terms.find( n[0] );
if( it==d_active_terms.end() ){
do_add = false;
unsigned d = 0;
bool is_top_level = false;
bool success = false;
- if( n.getKind()==kind::APPLY_SELECTOR_TOTAL ){
+ if (n.getKind() == kind::APPLY_SELECTOR)
+ {
registerTerm(n[0]);
std::unordered_map<Node, Node>::iterator it = d_term_to_anchor.find(n[0]);
if( it!=d_term_to_anchor.end() ) {
is_top_level = computeTopLevel( tn, n[0] );
success = true;
}
- }else if( n.isVar() ){
+ }
+ else if (n.isVar())
+ {
registerSizeTerm(n);
if( d_register_st[n] ){
d_term_to_anchor[n] = n;
bool SygusExtension::computeTopLevel( TypeNode tn, Node n ){
if( n.getType()==tn ){
return false;
- }else if( n.getKind()==kind::APPLY_SELECTOR_TOTAL ){
+ }
+ else if (n.getKind() == kind::APPLY_SELECTOR)
+ {
return computeTopLevel( tn, n[0] );
- }else{
+ }
+ else
+ {
return true;
}
}
{
Trace("sygus-sb-debug") << "Do lazy symmetry breaking...\n";
for( unsigned j=0; j<dt[tindex].getNumArgs(); j++ ){
- Node sel = nm->mkNode(
- APPLY_SELECTOR_TOTAL, dt[tindex].getSelectorInternal(ntn, j), n);
+ Node sel =
+ nm->mkNode(APPLY_SELECTOR, dt[tindex].getSelectorInternal(ntn, j), n);
Trace("sygus-sb-debug2") << " activate child sel : " << sel << std::endl;
Assert(d_active_terms.find(sel) == d_active_terms.end());
IntMap::const_iterator itt = d_testers.find( sel );
std::map< Node, Node >::iterator itr = d_rlv_cond.find( n );
if( itr==d_rlv_cond.end() ){
Node cond;
- if (n.getKind() == APPLY_SELECTOR_TOTAL)
+ if (n.getKind() == APPLY_SELECTOR)
{
TypeNode ntn = n[0].getType();
const DType& dt = ntn.getDType();
{
Assert(cur.getType().isBoolean());
Assert(cur.getNumChildren() == 1
- && (cur[0].isVar() || cur[0].getKind() == APPLY_SELECTOR_TOTAL));
+ && (cur[0].isVar() || cur[0].getKind() == APPLY_SELECTOR));
ittb = d_traversal_bool.find(cur);
Node ret;
if (ittb == d_traversal_bool.end())
std::vector<Node> children;
for (unsigned j = 0; j < dt_index_nargs; j++)
{
- Node sel = nm->mkNode(
- APPLY_SELECTOR_TOTAL, dt[tindex].getSelectorInternal(tn, j), n);
+ Node sel =
+ nm->mkNode(APPLY_SELECTOR, dt[tindex].getSelectorInternal(tn, j), n);
Assert(sel.getType().isDatatype());
children.push_back(sel);
}
&& children[0].getType() == tn && children[1].getType() == tn)
{
// chainable
- Node child11 = nm->mkNode(APPLY_SELECTOR_TOTAL,
- dt[tindex].getSelectorInternal(tn, 1),
- children[0]);
+ Node child11 = nm->mkNode(
+ APPLY_SELECTOR, dt[tindex].getSelectorInternal(tn, 1), children[0]);
Assert(child11.getType() == children[1].getType());
Node order_pred_trans =
nm->mkNode(OR,
bool childrenChanged = false;
for (unsigned i = 0, nchild = nv.getNumChildren(); i < nchild; i++)
{
- Node sel = nm->mkNode(
- APPLY_SELECTOR_TOTAL, dt[cindex].getSelectorInternal(tn, i), n);
+ Node sel =
+ nm->mkNode(APPLY_SELECTOR, dt[cindex].getSelectorInternal(tn, i), n);
Node nvc = registerSearchValue(a,
sel,
nv[i],
}
}
for( unsigned i=0; i<vn.getNumChildren(); i++ ){
- Node sel = nm->mkNode(
- APPLY_SELECTOR_TOTAL, dt[cindex].getSelectorInternal(tn, i), n);
+ Node sel =
+ nm->mkNode(APPLY_SELECTOR, dt[cindex].getSelectorInternal(tn, i), n);
if (!checkValue(sel, vn[i], ind + 1))
{
return false;
children.push_back(dt[tindex].getConstructor());
for( unsigned i=0; i<dt[tindex].getNumArgs(); i++ ){
Node sel = NodeManager::currentNM()->mkNode(
- APPLY_SELECTOR_TOTAL, dt[tindex].getSelectorInternal(tn, i), n);
+ APPLY_SELECTOR, dt[tindex].getSelectorInternal(tn, i), n);
Node cc = getCurrentTemplate( sel, var_count );
children.push_back( cc );
}
Assert(d_equalityEngine != nullptr);
// The kinds we are treating as function application in congruence
d_equalityEngine->addFunctionKind(kind::APPLY_CONSTRUCTOR);
- d_equalityEngine->addFunctionKind(kind::APPLY_SELECTOR_TOTAL);
+ d_equalityEngine->addFunctionKind(kind::APPLY_SELECTOR);
d_equalityEngine->addFunctionKind(kind::APPLY_TESTER);
// We could but don't do congruence for DT_SIZE and DT_HEIGHT_BOUND here.
// It also could make sense in practice to do congruence for APPLY_UF, but
{
Trace("datatypes-prereg")
<< "TheoryDatatypes::preRegisterTerm() " << n << endl;
- // external selectors should be preprocessed away by now
- Assert(n.getKind() != APPLY_SELECTOR);
+ // should not use APPLY_SELECTOR_TOTAL
+ Assert(n.getKind() != APPLY_SELECTOR_TOTAL);
// must ensure the type is well founded and has no nested recursion if
// the option dtNestedRec is not set to true.
TypeNode tn = n.getType();
Node r;
bool wrong = false;
Node eq_exp = s[0].eqNode(c);
- if( s.getKind()==kind::APPLY_SELECTOR_TOTAL ){
+ if (s.getKind() == kind::APPLY_SELECTOR)
+ {
Node selector = s.getOperator();
size_t constructorIndex = utils::indexOf(c.getOperator());
const DType& dt = utils::datatypeOf(selector);
const DTypeConstructor& dtc = dt[constructorIndex];
int selectorIndex = dtc.getSelectorIndexInternal(selector);
+ Trace("dt-collapse-sel")
+ << "selector index is " << selectorIndex << std::endl;
wrong = selectorIndex<0;
- r = NodeManager::currentNM()->mkNode( kind::APPLY_SELECTOR_TOTAL, s.getOperator(), c );
+ r = NodeManager::currentNM()->mkNode(
+ kind::APPLY_SELECTOR, s.getOperator(), c);
}
if( !r.isNull() ){
Node rrs;
if (wrong)
{
- // Must use make ground term here instead of the rewriter, since we
- // do not want to introduce arbitrary values. This is important so that
- // we avoid constants for types that are not "closed enumerable", e.g.
- // uninterpreted sorts and arrays, where the solver does not fully
- // handle values of the sort. The call to mkGroundTerm does not introduce
- // values for these sorts.
- NodeManager* nm = NodeManager::currentNM();
- rrs = nm->mkGroundTerm(r.getType());
- Trace("datatypes-wrong-sel")
- << "Bad apply " << r << " term = " << rrs
- << ", value = " << nm->mkGroundValue(r.getType()) << std::endl;
+ // If the selector application was wrong, we do nothing. The selector
+ // term in this context will be unevaluated, and treated via congruence.
+ return;
}
else
{
}
return;
}
- if (nk == APPLY_SELECTOR_TOTAL || nk == DT_SIZE || nk == DT_HEIGHT_BOUND)
+ if (nk == APPLY_SELECTOR || nk == DT_SIZE || nk == DT_HEIGHT_BOUND)
{
d_functionTerms.push_back(n);
// we must also record which selectors exist
TypeNode tn = n.getType();
for (unsigned i = 0, nargs = dt[index].getNumArgs(); i < nargs; i++)
{
- Node nc = nm->mkNode(
- APPLY_SELECTOR_TOTAL, dt[index].getSelectorInternal(tn, i), n);
+ Node nc =
+ nm->mkNode(APPLY_SELECTOR, dt[index].getSelectorInternal(tn, i), n);
children.push_back(nc);
}
Node n_ic = mkApplyCons(tn, dt, index, children);
TypeNode tn = n.getType();
for (unsigned i = 0, size = n.getNumChildren(); i < size; i++)
{
- if (n[i].getKind() != APPLY_SELECTOR_TOTAL
+ if (n[i].getKind() != APPLY_SELECTOR
|| n[i].getOperator() != c.getSelectorInternal(tn, i) || n[i][0] != t)
{
return -1;
TypeNode tn = tuple.getType();
const DType& dt = tn.getDType();
return NodeManager::currentNM()->mkNode(
- APPLY_SELECTOR_TOTAL, dt[0].getSelectorInternal(tn, n_th), tuple);
+ APPLY_SELECTOR, dt[0].getSelectorInternal(tn, n_th), tuple);
}
std::vector<Node> TupleUtils::getTupleElements(Node tuple)
// now must solve for selectors applied to pv
for (unsigned j = 0, nargs = dt[cindex].getNumArgs(); j < nargs; j++)
{
- Node c = nm->mkNode(APPLY_SELECTOR_TOTAL,
- dt[cindex].getSelectorInternal(d_type, j),
- pv);
+ Node c = nm->mkNode(
+ APPLY_SELECTOR, dt[cindex].getSelectorInternal(d_type, j), pv);
ci->pushStackVariable(c);
children.push_back(c);
}
for (unsigned i = 0, nchild = a.getNumChildren(); i < nchild; i++)
{
Node nn = nm->mkNode(
- APPLY_SELECTOR_TOTAL, dt[cindex].getSelectorInternal(tn, i), sb);
+ APPLY_SELECTOR, dt[cindex].getSelectorInternal(tn, i), sb);
Node s = solve_dt(v, a[i], Node::null(), sa[i], nn);
if (!s.isNull())
{
d_prog_var[n].insert(d_prog_var[n[i]].begin(), d_prog_var[n[i]].end());
}
// selectors applied to program variables are also variables
- if (n.getKind() == APPLY_SELECTOR_TOTAL
+ if (n.getKind() == APPLY_SELECTOR
&& d_prog_var[n].find(n[0]) != d_prog_var[n].end())
{
d_prog_var[n].insert(n);
{
Node nn = dbl->d_list[0];
Trace("sg-rel-sig-debug") << "Check in signature : " << nn << std::endl;
- if( d_cg->isHandledTerm( nn ) && nn.getKind()!=APPLY_SELECTOR_TOTAL && !nn.getType().isBoolean() ){
+ if (d_cg->isHandledTerm(nn) && nn.getKind() != APPLY_SELECTOR
+ && !nn.getType().isBoolean())
+ {
bool do_enum = true;
//check if we have enumerated ground terms
if( nn.getKind()==APPLY_UF ){
for (unsigned i = 0, nargs = dt[0].getNumArgs(); i < nargs; i++)
{
Node sel = nm->mkNode(
- APPLY_SELECTOR_TOTAL, dt[0].getSelectorInternal(d_mpat_type, i), curr);
+ APPLY_SELECTOR, dt[0].getSelectorInternal(d_mpat_type, i), curr);
children.push_back(sel);
}
return nm->mkNode(APPLY_CONSTRUCTOR, children);
Trace("sel-trigger") << "Expands to: " << mpatExp << std::endl;
if (mpatExp.getKind() == ITE)
{
- Assert(mpatExp[1].getKind() == APPLY_SELECTOR_TOTAL);
+ Assert(mpatExp[1].getKind() == APPLY_SELECTOR);
Assert(mpatExp[2].getKind() == APPLY_UF);
d_selOp = d_treg.getTermDatabase()->getMatchOperator(mpatExp[1]);
d_ufOp = d_treg.getTermDatabase()->getMatchOperator(mpatExp[2]);
}
- else if (mpatExp.getKind() == APPLY_SELECTOR_TOTAL)
+ else if (mpatExp.getKind() == APPLY_SELECTOR)
{
// corner case of datatype with one constructor
d_selOp = d_treg.getTermDatabase()->getMatchOperator(mpatExp);
}
else if (mpk == INST_CONSTANT)
{
- if (d_pattern.getKind() == APPLY_SELECTOR_TOTAL)
+ if (d_pattern.getKind() == APPLY_SELECTOR)
{
Node selectorExpr = tdb->getMatchOperator(d_pattern);
size_t selectorIndex = datatypes::utils::cindexOf(selectorExpr);
bool TriggerTermInfo::isAtomicTriggerKind(Kind k)
{
- // we use both APPLY_SELECTOR and APPLY_SELECTOR_TOTAL since this
- // method is used both for trigger selection and for ground term registration,
- // where these two things require those kinds respectively.
return k == APPLY_UF || k == SELECT || k == STORE || k == APPLY_CONSTRUCTOR
- || k == APPLY_SELECTOR || k == APPLY_SELECTOR_TOTAL
- || k == APPLY_TESTER || k == SET_UNION || k == SET_INTER
- || k == SET_SUBSET || k == SET_MINUS || k == SET_MEMBER
- || k == SET_SINGLETON || k == SEP_PTO || k == BITVECTOR_TO_NAT
- || k == INT_TO_BITVECTOR || k == HO_APPLY || k == STRING_LENGTH
- || k == SEQ_NTH;
+ || k == APPLY_SELECTOR || k == APPLY_TESTER || k == SET_UNION
+ || k == SET_INTER || k == SET_SUBSET || k == SET_MINUS
+ || k == SET_MEMBER || k == SET_SINGLETON || k == SEP_PTO
+ || k == BITVECTOR_TO_NAT || k == INT_TO_BITVECTOR || k == HO_APPLY
+ || k == STRING_LENGTH || k == SEQ_NTH;
}
bool TriggerTermInfo::isRelationalTrigger(Node n)
if( e.getKind()==kind::APPLY_CONSTRUCTOR ){
u = matchBoundVar( v, t[i], e[i] );
}else{
- Node se = nm->mkNode(APPLY_SELECTOR_TOTAL,
- dt[index].getSelectorInternal(e.getType(), i),
- e);
+ Node se = nm->mkNode(
+ APPLY_SELECTOR, dt[index].getSelectorInternal(e.getType(), i), e);
u = matchBoundVar( v, t[i], se );
}
if( !u.isNull() ){
}
bool MatchGen::isHandledUfTerm( TNode n ) {
- //return n.getKind()==APPLY_UF || n.getKind()==STORE || n.getKind()==SELECT ||
- // n.getKind()==APPLY_CONSTRUCTOR || n.getKind()==APPLY_SELECTOR_TOTAL || n.getKind()==APPLY_TESTER;
- //TODO : treat APPLY_TESTER as a T-constraint instead of matching (currently leads to overabundance of instantiations)
- //return inst::Trigger::isAtomicTriggerKind( n.getKind() ) && ( !options::qcfTConstraint() || n.getKind()!=APPLY_TESTER );
return inst::TriggerTermInfo::isAtomicTriggerKind(n.getKind());
}
}
for (unsigned k = 0; k < ssc.size(); k++)
{
- Node ss = nm->mkNode(
- APPLY_SELECTOR_TOTAL, dc.getSelectorInternal(n.getType(), j), n);
+ Node ss =
+ nm->mkNode(APPLY_SELECTOR, dc.getSelectorInternal(n.getType(), j), n);
if (std::find(selfSel.begin(), selfSel.end(), ss) == selfSel.end())
{
selfSel.push_back(ss);
TNode vt = v;
Node vn = n.substitute(at, vt);
vn = rewrite(vn);
+ // it might be incorrectly applied
+ if (!vn.isConst())
+ {
+ continue;
+ }
unsigned start = d_node_mv_args_proc[n][vn];
// get explanation in terms of testers
std::vector<Node> antec_exp;
else
{
Node ret = nm->mkNode(
- APPLY_SELECTOR_TOTAL, dt[i].getSelectorInternal(headType, 0), en[0]);
+ APPLY_SELECTOR, dt[i].getSelectorInternal(headType, 0), en[0]);
Trace("sygus-eval-unfold-debug")
<< "...return (from constructor) " << ret << std::endl;
return ret;
else
{
s = nm->mkNode(
- APPLY_SELECTOR_TOTAL, dt[i].getSelectorInternal(headType, j), en[0]);
+ APPLY_SELECTOR, dt[i].getSelectorInternal(headType, j), en[0]);
}
cc.push_back(s);
if (track_exp)
if (cexc.find(j) == cexc.end())
{
Node sel = NodeManager::currentNM()->mkNode(
- kind::APPLY_SELECTOR_TOTAL, dt[i].getSelectorInternal(tn, j), n);
+ kind::APPLY_SELECTOR, dt[i].getSelectorInternal(tn, j), n);
getExplanationForEquality(sel, vn[j], exp);
}
}
for (unsigned i = 0; i < vn.getNumChildren(); i++)
{
Node sel = NodeManager::currentNM()->mkNode(
- kind::APPLY_SELECTOR_TOTAL, dt[cindex].getSelectorInternal(ntn, i), n);
+ kind::APPLY_SELECTOR, dt[cindex].getSelectorInternal(ntn, i), n);
Node vnr_c = vnr.isNull() ? vnr : (vn[i] == vnr[i] ? Node::null() : vnr[i]);
if (cexc.find(i) == cexc.end())
{
Trace("sygus-db-canon") << " CanonizeBuiltin : compute for " << n << "\n";
Node ret = n;
// it is symbolic if it represents "any constant"
- if (n.getKind() == APPLY_SELECTOR_TOTAL)
+ if (n.getKind() == APPLY_SELECTOR)
{
ret = getFreeVarInc(n[0].getType(), var_count, true);
}
}
Node TermDbSygus::getAnchor( Node n ) {
- if( n.getKind()==APPLY_SELECTOR_TOTAL ){
+ if (n.getKind() == APPLY_SELECTOR)
+ {
return getAnchor( n[0] );
- }else{
+ }
+ else
+ {
return n;
}
}
unsigned TermDbSygus::getAnchorDepth( Node n ) {
- if( n.getKind()==APPLY_SELECTOR_TOTAL ){
+ if (n.getKind() == APPLY_SELECTOR)
+ {
return 1+getAnchorDepth( n[0] );
- }else{
+ }
+ else
+ {
return 0;
}
}
//datatype operators may be parametric, always assume they are
if (k == SELECT || k == STORE || k == SET_UNION || k == SET_INTER
|| k == SET_SUBSET || k == SET_MINUS || k == SET_MEMBER
- || k == SET_SINGLETON || k == APPLY_SELECTOR_TOTAL || k == APPLY_SELECTOR
- || k == APPLY_TESTER || k == SEP_PTO || k == HO_APPLY || k == SEQ_NTH
- || k == STRING_LENGTH)
+ || k == SET_SINGLETON || k == APPLY_SELECTOR || k == APPLY_TESTER
+ || k == SEP_PTO || k == HO_APPLY || k == SEQ_NTH || k == STRING_LENGTH)
{
//since it is parametric, use a particular one as op
TypeNode tn = n[0].getType();
d_equalityEngine->addFunctionKind(kind::SELECT);
// d_equalityEngine->addFunctionKind(kind::STORE);
d_equalityEngine->addFunctionKind(kind::APPLY_CONSTRUCTOR);
- d_equalityEngine->addFunctionKind(kind::APPLY_SELECTOR_TOTAL);
+ d_equalityEngine->addFunctionKind(kind::APPLY_SELECTOR);
d_equalityEngine->addFunctionKind(kind::APPLY_TESTER);
d_equalityEngine->addFunctionKind(kind::SEQ_NTH);
d_equalityEngine->addFunctionKind(kind::SEQ_NTH_TOTAL);
bool TheoryEngineModelBuilder::isAssignable(TNode n)
{
- if (n.getKind() == kind::SELECT || n.getKind() == kind::APPLY_SELECTOR_TOTAL
+ if (n.getKind() == kind::SELECT || n.getKind() == kind::APPLY_SELECTOR
|| n.getKind() == kind::SEQ_NTH_TOTAL || n.getKind() == kind::SEQ_NTH)
{
// selectors are always assignable (where we guarantee that they are not
regress2/push-pop/DRAGON_4_e2_2799_e3_1915.lus.ic3.1.min.smt2
regress2/quantifiers/AdditiveMethods_AdditiveMethods..ctor.smt2
regress2/quantifiers/cee-event-wrong-sat.smt2
- regress2/quantifiers/exp-trivially-dd3.smt2
regress2/quantifiers/gn-wrong-091018.smt2
regress2/quantifiers/issue3481-unsat1.smt2
regress2/quantifiers/javafe.ast.StandardPrettyPrint.319.smt2
regress2/nl/nt-lemmas-bad.smt2
# timeout after refactoring justification heuristic
regress2/ho/SYO362^5.p
+ # timeout after refactoring selectors
+ regress2/quantifiers/exp-trivially-dd3.smt2
# time out
regress3/unifpi-solve-car_1.lus.sy
# unknown (is sat)
-
+; COMMAND-LINE: -q
+; EXPECT: sat
(set-logic QF_DTLIA)
(set-info :status sat)
+; COMMAND-LINE: -q
; EXPECT: sat
(set-logic ALL)
(set-option :incremental false)
-; COMMAND-LINE: --cegqi
+; COMMAND-LINE: --cegqi -q
; EXPECT: sat
(set-logic ALL)
(set-info :status sat)
-; COMMAND-LINE: --ee-mode=distributed
-; COMMAND-LINE: --ee-mode=central
+; COMMAND-LINE: --ee-mode=distributed -q
+; COMMAND-LINE: --ee-mode=central -q
; EXPECT: sat
(set-logic ALL)
(set-info :status sat)
-; COMMAND-LINE: --dt-nested-rec
+; COMMAND-LINE: --dt-nested-rec -q
; EXPECT: sat
(set-logic ALL)
(set-info :status sat)
-; COMMAND-LINE: --fmf-bound
+; COMMAND-LINE: --fmf-bound -q
; EXPECT: sat
(set-logic ALL)
(declare-datatypes ((list 0)) (((cons (head Int) (tail list)) (nil))))
-; COMMAND-LINE: --finite-model-find --fmf-inst-engine --uf-ss-fair-monotone
+; COMMAND-LINE: --finite-model-find --fmf-inst-engine --uf-ss-fair-monotone -q
; EXPECT: sat
(set-logic ALL)
(set-info :status sat)
-; COMMAND-LINE: --finite-model-find --fmf-inst-engine --uf-ss-fair-monotone
+; COMMAND-LINE: --finite-model-find --fmf-inst-engine --uf-ss-fair-monotone -q
; EXPECT: sat
(set-logic ALL)
(set-info :status sat)
-; COMMAND-LINE: --finite-model-find --dt-rewrite-error-sel
+; COMMAND-LINE: --finite-model-find --dt-rewrite-error-sel -q
; EXPECT: sat
(set-logic ALL)
(declare-datatypes ((Nat 0) (Lst 0)) (((succ (pred Nat)) (zero)) ((cons (hd Nat) (tl Lst)) (nil))))
-; COMMAND-LINE: --finite-model-find
+; COMMAND-LINE: --finite-model-find -q
; EXPECT: sat
(set-logic ALL)
(declare-sort b__ 0)
+; COMMAND-LINE: -q
+; EXPECT: sat
(set-logic ALL)
(set-option :strings-exp true)
(set-info :status sat)
-; COMMAND-LINE:
+; COMMAND-LINE: -q
; EXPECT: sat
(set-logic UFDTLIRA)
(set-option :fmf-bound true)
slv.push(4);
}
+TEST_F(TestApiBlackSolver, projIssue431)
+{
+ Solver slv;
+ slv.setOption("produce-abducts", "true");
+ Sort s2 = slv.mkBitVectorSort(22);
+ Sort s4 = slv.mkSetSort(s2);
+ Sort s5 = slv.getBooleanSort();
+ Sort s6 = slv.getRealSort();
+ Sort s7 = slv.mkFunctionSort({s6}, s5);
+ DatatypeDecl _dt46 = slv.mkDatatypeDecl("_dt46", {});
+ DatatypeConstructorDecl _cons64 = slv.mkDatatypeConstructorDecl("_cons64");
+ _cons64.addSelector("_sel62", s6);
+ _cons64.addSelector("_sel63", s4);
+ _dt46.addConstructor(_cons64);
+ Sort s14 = slv.mkDatatypeSorts({_dt46})[0];
+ Term t31 = slv.mkConst(s7, "_x100");
+ Term t47 = slv.mkConst(s14, "_x112");
+ Term sel =
+ t47.getSort().getDatatype().getConstructor("_cons64").getSelectorTerm(
+ "_sel62");
+ Term t274 = slv.mkTerm(APPLY_SELECTOR, sel, t47);
+ Term t488 = slv.mkTerm(Kind::APPLY_UF, {t31, t274});
+ slv.assertFormula({t488});
+ Term abduct;
+ slv.getAbduct(t488, abduct);
+}
+
} // namespace test
} // namespace cvc5