diff options
Diffstat (limited to 'src/theory/strings/regexp_operation.cpp')
-rw-r--r-- | src/theory/strings/regexp_operation.cpp | 66 |
1 files changed, 9 insertions, 57 deletions
diff --git a/src/theory/strings/regexp_operation.cpp b/src/theory/strings/regexp_operation.cpp index bf4c20f85..96351cda9 100644 --- a/src/theory/strings/regexp_operation.cpp +++ b/src/theory/strings/regexp_operation.cpp @@ -1017,16 +1017,7 @@ Node RegExpOpr::reduceRegExpPos(Node mem, { std::vector<Node> nvec; std::vector<Node> cc; - // get the (valid) existential for this membership - Node eform = getExistsForRegExpConcatMem(mem); SkolemManager* sm = nm->getSkolemManager(); - // Notice that this rule does not introduce witness terms, instead it - // uses skolems in the conclusion of the proof rule directly. Thus, - // the existential eform does not need to be explicitly justified by a - // proof here, since it is only being used as an intermediate formula in - // this inference. Hence we do not pass a proof generator to mkSkolemize. - sm->mkSkolemize(eform, newSkolems, "rc", "regexp concat skolem"); - Assert(newSkolems.size() == r.getNumChildren()); // Look up skolems for each of the components. If sc has optimizations // enabled, this will return arguments of str.to_re. for (unsigned i = 0, nchild = r.getNumChildren(); i < nchild; ++i) @@ -1034,17 +1025,22 @@ Node RegExpOpr::reduceRegExpPos(Node mem, if (r[i].getKind() == STRING_TO_REGEXP) { // optimization, just take the body - newSkolems[i] = r[i][0]; + newSkolems.push_back(r[i][0]); } else { + Node ivalue = nm->mkConst(Rational(i)); + Node sk = sm->mkSkolemFunction(SkolemFunId::RE_UNFOLD_POS_COMPONENT, + s.getType(), + {mem[0], mem[1], ivalue}); + newSkolems.push_back(sk); nvec.push_back(nm->mkNode(STRING_IN_REGEXP, newSkolems[i], r[i])); } } - // (str.in_re x (re.++ R1 .... Rn)) => - // (and (str.in_re k1 R1) ... (str.in_re kn Rn) (= x (str.++ k1 ... kn))) + // (str.in_re x (re.++ R0 .... Rn)) => + // (and (= x (str.++ k0 ... kn)) (str.in_re k0 R0) ... (str.in_re kn Rn) ) Node lem = s.eqNode(nm->mkNode(STRING_CONCAT, newSkolems)); - nvec.push_back(lem); + nvec.insert(nvec.begin(), lem); conc = nvec.size() == 1 ? nvec[0] : nm->mkNode(AND, nvec); } else if (k == REGEXP_STAR) @@ -1574,50 +1570,6 @@ bool RegExpOpr::regExpIncludes(Node r1, Node r2) return result; } -/** - * Associating formulas with their "exists form", or an existentially - * quantified formula that is equivalent to it. This is currently used - * for regular expression memberships in the method below. - */ -struct ExistsFormAttributeId -{ -}; -typedef expr::Attribute<ExistsFormAttributeId, Node> ExistsFormAttribute; - -Node RegExpOpr::getExistsForRegExpConcatMem(Node mem) -{ - // get or make the exists form of the membership - ExistsFormAttribute efa; - if (mem.hasAttribute(efa)) - { - // already computed - return mem.getAttribute(efa); - } - Assert(mem.getKind() == STRING_IN_REGEXP); - Node x = mem[0]; - Node r = mem[1]; - Assert(r.getKind() == REGEXP_CONCAT); - NodeManager* nm = NodeManager::currentNM(); - TypeNode xtn = x.getType(); - std::vector<Node> vars; - std::vector<Node> mems; - for (const Node& rc : r) - { - Node v = nm->mkBoundVar(xtn); - vars.push_back(v); - mems.push_back(nm->mkNode(STRING_IN_REGEXP, v, rc)); - } - Node sconcat = nm->mkNode(STRING_CONCAT, vars); - Node eq = x.eqNode(sconcat); - mems.insert(mems.begin(), eq); - Node bvl = nm->mkNode(BOUND_VAR_LIST, vars); - Node ebody = nm->mkNode(AND, mems); - Node eform = nm->mkNode(EXISTS, bvl, ebody); - mem.setAttribute(efa, eform); - Trace("regexp-opr") << "Exists form " << mem << " : " << eform << std::endl; - return eform; -} - } // namespace strings } // namespace theory } // namespace cvc5 |