1 /********************* */
4 ** Top contributors (to current version):
5 ** Andrew Reynolds, Tianyi Liang
6 ** This file is part of the CVC4 project.
7 ** Copyright (c) 2009-2020 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.\endverbatim
12 ** \brief Implementation of equivalence class info for the theory of strings
15 #include "theory/strings/eqc_info.h"
17 #include "theory/strings/theory_strings_utils.h"
18 #include "theory/strings/word.h"
21 using namespace CVC4::context
;
22 using namespace CVC4::kind
;
28 EqcInfo::EqcInfo(context::Context
* c
)
32 d_normalizedLength(c
),
38 Node
EqcInfo::addEndpointConst(Node t
, Node c
, bool isSuf
)
41 Node prev
= isSuf
? d_suffixC
: d_prefixC
;
44 Trace("strings-eager-pconf-debug") << "Check conflict " << prev
<< ", " << t
45 << " post=" << isSuf
<< std::endl
;
46 Node prevC
= utils::getConstantEndpoint(prev
, isSuf
);
47 Assert(!prevC
.isNull());
48 Assert(prevC
.isConst());
51 c
= utils::getConstantEndpoint(t
, isSuf
);
55 bool conflict
= false;
56 // if the constant prefixes are different
59 // conflicts between constants should be handled by equality engine
60 Assert(!t
.isConst() || !prev
.isConst());
61 Trace("strings-eager-pconf-debug")
62 << "Check conflict constants " << prevC
<< ", " << c
<< std::endl
;
63 size_t pvs
= Word::getLength(prevC
);
64 size_t cvs
= Word::getLength(c
);
65 if (pvs
== cvs
|| (pvs
> cvs
&& t
.isConst())
66 || (cvs
> pvs
&& prev
.isConst()))
68 // If equal length, cannot be equal due to node check above.
69 // If one is fully constant and has less length than the other, then the
70 // other will not fit and we are in conflict.
75 Node larges
= pvs
> cvs
? prevC
: c
;
76 Node smalls
= pvs
> cvs
? c
: prevC
;
79 conflict
= !Word::hasSuffix(larges
, smalls
);
83 conflict
= !Word::hasPrefix(larges
, smalls
);
86 if (!conflict
&& (pvs
> cvs
|| prev
.isConst()))
88 // current is subsumed, either shorter prefix or the other is a full
93 else if (!t
.isConst())
95 // current is subsumed since the other may be a full constant
100 Trace("strings-eager-pconf")
101 << "Conflict for " << prevC
<< ", " << c
<< std::endl
;
102 std::vector
<Node
> ccs
;
104 for (unsigned i
= 0; i
< 2; i
++)
106 Node tp
= i
== 0 ? t
: prev
;
107 if (tp
.getKind() == STRING_IN_REGEXP
)
119 ccs
.push_back(r
[0].eqNode(r
[1]));
121 Assert(!ccs
.empty());
123 ccs
.size() == 1 ? ccs
[0] : NodeManager::currentNM()->mkNode(AND
, ccs
);
124 Trace("strings-eager-pconf")
125 << "String: eager prefix conflict: " << ret
<< std::endl
;
140 } // namespace strings
141 } // namespace theory