1 |
|
/****************************************************************************** |
2 |
|
* Top contributors (to current version): |
3 |
|
* Andrew Reynolds, Tianyi Liang, Andres Noetzli |
4 |
|
* |
5 |
|
* This file is part of the cvc5 project. |
6 |
|
* |
7 |
|
* Copyright (c) 2009-2021 by the authors listed in the file AUTHORS |
8 |
|
* in the top-level source directory and their institutional affiliations. |
9 |
|
* All rights reserved. See the file COPYING in the top-level source |
10 |
|
* directory for licensing information. |
11 |
|
* **************************************************************************** |
12 |
|
* |
13 |
|
* The eager solver. |
14 |
|
*/ |
15 |
|
|
16 |
|
#include "theory/strings/eager_solver.h" |
17 |
|
|
18 |
|
#include "theory/strings/theory_strings_utils.h" |
19 |
|
|
20 |
|
using namespace cvc5::kind; |
21 |
|
|
22 |
|
namespace cvc5 { |
23 |
|
namespace theory { |
24 |
|
namespace strings { |
25 |
|
|
26 |
9838 |
EagerSolver::EagerSolver(SolverState& state) : d_state(state) {} |
27 |
|
|
28 |
9838 |
EagerSolver::~EagerSolver() {} |
29 |
|
|
30 |
114667 |
void EagerSolver::eqNotifyNewClass(TNode t) |
31 |
|
{ |
32 |
114667 |
Kind k = t.getKind(); |
33 |
114667 |
if (k == STRING_LENGTH || k == STRING_TO_CODE) |
34 |
|
{ |
35 |
32337 |
eq::EqualityEngine* ee = d_state.getEqualityEngine(); |
36 |
64674 |
Node r = ee->getRepresentative(t[0]); |
37 |
32337 |
EqcInfo* ei = d_state.getOrMakeEqcInfo(r); |
38 |
32337 |
if (k == STRING_LENGTH) |
39 |
|
{ |
40 |
29957 |
ei->d_lengthTerm = t[0]; |
41 |
|
} |
42 |
|
else |
43 |
|
{ |
44 |
2380 |
ei->d_codeTerm = t[0]; |
45 |
32337 |
} |
46 |
|
} |
47 |
82330 |
else if (t.isConst()) |
48 |
|
{ |
49 |
24488 |
if (t.getType().isStringLike()) |
50 |
|
{ |
51 |
10155 |
EqcInfo* ei = d_state.getOrMakeEqcInfo(t); |
52 |
10155 |
ei->d_prefixC = t; |
53 |
10155 |
ei->d_suffixC = t; |
54 |
|
} |
55 |
|
} |
56 |
57842 |
else if (k == STRING_CONCAT) |
57 |
|
{ |
58 |
9185 |
addEndpointsToEqcInfo(t, t, t); |
59 |
|
} |
60 |
114667 |
} |
61 |
|
|
62 |
1151653 |
void EagerSolver::eqNotifyMerge(TNode t1, TNode t2) |
63 |
|
{ |
64 |
1151653 |
EqcInfo* e2 = d_state.getOrMakeEqcInfo(t2, false); |
65 |
1151653 |
if (e2 == nullptr) |
66 |
|
{ |
67 |
854540 |
return; |
68 |
|
} |
69 |
297113 |
Assert(t1.getType().isStringLike()); |
70 |
297113 |
EqcInfo* e1 = d_state.getOrMakeEqcInfo(t1); |
71 |
|
// add information from e2 to e1 |
72 |
297113 |
if (!e2->d_lengthTerm.get().isNull()) |
73 |
|
{ |
74 |
296937 |
e1->d_lengthTerm.set(e2->d_lengthTerm); |
75 |
|
} |
76 |
297113 |
if (!e2->d_codeTerm.get().isNull()) |
77 |
|
{ |
78 |
10854 |
e1->d_codeTerm.set(e2->d_codeTerm); |
79 |
|
} |
80 |
297113 |
if (!e2->d_prefixC.get().isNull()) |
81 |
|
{ |
82 |
62538 |
d_state.setPendingPrefixConflictWhen( |
83 |
62538 |
e1->addEndpointConst(e2->d_prefixC, Node::null(), false)); |
84 |
|
} |
85 |
297113 |
if (!e2->d_suffixC.get().isNull()) |
86 |
|
{ |
87 |
89846 |
d_state.setPendingPrefixConflictWhen( |
88 |
89846 |
e1->addEndpointConst(e2->d_suffixC, Node::null(), true)); |
89 |
|
} |
90 |
297113 |
if (e2->d_cardinalityLemK.get() > e1->d_cardinalityLemK.get()) |
91 |
|
{ |
92 |
|
e1->d_cardinalityLemK.set(e2->d_cardinalityLemK); |
93 |
|
} |
94 |
297113 |
if (!e2->d_normalizedLength.get().isNull()) |
95 |
|
{ |
96 |
102 |
e1->d_normalizedLength.set(e2->d_normalizedLength); |
97 |
|
} |
98 |
|
} |
99 |
|
|
100 |
159877 |
void EagerSolver::eqNotifyDisequal(TNode t1, TNode t2, TNode reason) |
101 |
|
{ |
102 |
159877 |
if (t1.getType().isStringLike()) |
103 |
|
{ |
104 |
|
// store disequalities between strings, may need to check if their lengths |
105 |
|
// are equal/disequal |
106 |
64552 |
d_state.addDisequality(t1, t2); |
107 |
|
} |
108 |
159877 |
} |
109 |
|
|
110 |
14212 |
void EagerSolver::addEndpointsToEqcInfo(Node t, Node concat, Node eqc) |
111 |
|
{ |
112 |
14212 |
Assert(concat.getKind() == STRING_CONCAT |
113 |
|
|| concat.getKind() == REGEXP_CONCAT); |
114 |
14212 |
EqcInfo* ei = nullptr; |
115 |
|
// check each side |
116 |
42636 |
for (unsigned r = 0; r < 2; r++) |
117 |
|
{ |
118 |
28424 |
unsigned index = r == 0 ? 0 : concat.getNumChildren() - 1; |
119 |
56848 |
Node c = utils::getConstantComponent(concat[index]); |
120 |
28424 |
if (!c.isNull()) |
121 |
|
{ |
122 |
8931 |
if (ei == nullptr) |
123 |
|
{ |
124 |
7124 |
ei = d_state.getOrMakeEqcInfo(eqc); |
125 |
|
} |
126 |
17862 |
Trace("strings-eager-pconf-debug") |
127 |
8931 |
<< "New term: " << concat << " for " << t << " with prefix " << c |
128 |
8931 |
<< " (" << (r == 1) << ")" << std::endl; |
129 |
8931 |
d_state.setPendingPrefixConflictWhen(ei->addEndpointConst(t, c, r == 1)); |
130 |
|
} |
131 |
|
} |
132 |
14212 |
} |
133 |
|
|
134 |
846331 |
void EagerSolver::notifyFact(TNode atom, |
135 |
|
bool polarity, |
136 |
|
TNode fact, |
137 |
|
bool isInternal) |
138 |
|
{ |
139 |
846331 |
if (atom.getKind() == STRING_IN_REGEXP) |
140 |
|
{ |
141 |
23842 |
if (polarity && atom[1].getKind() == REGEXP_CONCAT) |
142 |
|
{ |
143 |
5027 |
eq::EqualityEngine* ee = d_state.getEqualityEngine(); |
144 |
10054 |
Node eqc = ee->getRepresentative(atom[0]); |
145 |
5027 |
addEndpointsToEqcInfo(atom, atom[1], eqc); |
146 |
|
} |
147 |
|
} |
148 |
846331 |
} |
149 |
|
|
150 |
|
} // namespace strings |
151 |
|
} // namespace theory |
152 |
29280 |
} // namespace cvc5 |