a9ced55f33917a540f981487235b202768f6be38
1 /********************* */
2 /*! \file theory_strings_type_rules.h
4 ** Top contributors (to current version):
5 ** Tianyi Liang, Tim King, Andrew Reynolds
6 ** This file is part of the CVC4 project.
7 ** Copyright (c) 2009-2018 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 Typing and cardinality rules for the theory of arrays
14 ** Typing and cardinality rules for the theory of arrays.
17 #include "cvc4_private.h"
18 #include "options/strings_options.h"
20 #ifndef __CVC4__THEORY__STRINGS__THEORY_STRINGS_TYPE_RULES_H
21 #define __CVC4__THEORY__STRINGS__THEORY_STRINGS_TYPE_RULES_H
27 class StringConstantTypeRule
{
29 inline static TypeNode
computeType(NodeManager
* nodeManager
, TNode n
, bool check
)
31 return nodeManager
->stringType();
35 class StringConcatTypeRule
{
37 inline static TypeNode
computeType(NodeManager
* nodeManager
, TNode n
, bool check
)
40 TNode::iterator it
= n
.begin();
41 TNode::iterator it_end
= n
.end();
43 for (; it
!= it_end
; ++ it
) {
44 TypeNode t
= (*it
).getType(check
);
46 throw TypeCheckingExceptionPrivate(n
, "expecting string terms in string concat");
51 throw TypeCheckingExceptionPrivate(n
, "expecting at least 2 terms in string concat");
54 return nodeManager
->stringType();
58 class StringLengthTypeRule
{
60 inline static TypeNode
computeType(NodeManager
* nodeManager
, TNode n
, bool check
)
63 TypeNode t
= n
[0].getType(check
);
65 throw TypeCheckingExceptionPrivate(n
, "expecting string terms in string length");
68 return nodeManager
->integerType();
72 class StringSubstrTypeRule
{
74 inline static TypeNode
computeType(NodeManager
* nodeManager
, TNode n
, bool check
)
77 TypeNode t
= n
[0].getType(check
);
79 throw TypeCheckingExceptionPrivate(n
, "expecting a string term in substr");
81 t
= n
[1].getType(check
);
83 throw TypeCheckingExceptionPrivate(n
, "expecting a start int term in substr");
85 t
= n
[2].getType(check
);
87 throw TypeCheckingExceptionPrivate(n
, "expecting a length int term in substr");
90 return nodeManager
->stringType();
94 class StringRelationTypeRule
97 inline static TypeNode
computeType(NodeManager
* nodeManager
, TNode n
, bool check
)
100 TypeNode t
= n
[0].getType(check
);
102 throw TypeCheckingExceptionPrivate(
103 n
, "expecting a string term in string relation");
105 t
= n
[1].getType(check
);
107 throw TypeCheckingExceptionPrivate(
108 n
, "expecting a string term in string relation");
111 return nodeManager
->booleanType();
115 class StringCharAtTypeRule
{
117 inline static TypeNode
computeType(NodeManager
* nodeManager
, TNode n
, bool check
)
120 TypeNode t
= n
[0].getType(check
);
122 throw TypeCheckingExceptionPrivate(n
, "expecting a string term in string char at 0");
124 t
= n
[1].getType(check
);
125 if (!t
.isInteger()) {
126 throw TypeCheckingExceptionPrivate(n
, "expecting an integer term in string char at 1");
129 return nodeManager
->stringType();
133 class StringIndexOfTypeRule
{
135 inline static TypeNode
computeType(NodeManager
* nodeManager
, TNode n
, bool check
)
138 TypeNode t
= n
[0].getType(check
);
140 throw TypeCheckingExceptionPrivate(n
, "expecting a string term in string indexof 0");
142 t
= n
[1].getType(check
);
144 throw TypeCheckingExceptionPrivate(n
, "expecting a string term in string indexof 1");
146 t
= n
[2].getType(check
);
147 if (!t
.isInteger()) {
148 throw TypeCheckingExceptionPrivate(n
, "expecting an integer term in string indexof 2");
151 return nodeManager
->integerType();
155 class StringReplaceTypeRule
{
157 inline static TypeNode
computeType(NodeManager
* nodeManager
, TNode n
, bool check
)
160 TypeNode t
= n
[0].getType(check
);
162 throw TypeCheckingExceptionPrivate(n
, "expecting a string term in string replace 0");
164 t
= n
[1].getType(check
);
166 throw TypeCheckingExceptionPrivate(n
, "expecting a string term in string replace 1");
168 t
= n
[2].getType(check
);
170 throw TypeCheckingExceptionPrivate(n
, "expecting a string term in string replace 2");
173 return nodeManager
->stringType();
177 class StringPrefixOfTypeRule
{
179 inline static TypeNode
computeType(NodeManager
* nodeManager
, TNode n
, bool check
)
182 TypeNode t
= n
[0].getType(check
);
184 throw TypeCheckingExceptionPrivate(n
, "expecting a string term in string prefixof 0");
186 t
= n
[1].getType(check
);
188 throw TypeCheckingExceptionPrivate(n
, "expecting a string term in string prefixof 1");
191 return nodeManager
->booleanType();
195 class StringSuffixOfTypeRule
{
197 inline static TypeNode
computeType(NodeManager
* nodeManager
, TNode n
, bool check
)
200 TypeNode t
= n
[0].getType(check
);
202 throw TypeCheckingExceptionPrivate(n
, "expecting a string term in string suffixof 0");
204 t
= n
[1].getType(check
);
206 throw TypeCheckingExceptionPrivate(n
, "expecting a string term in string suffixof 1");
209 return nodeManager
->booleanType();
213 class StringIntToStrTypeRule
{
215 inline static TypeNode
computeType(NodeManager
* nodeManager
, TNode n
, bool check
)
218 TypeNode t
= n
[0].getType(check
);
219 if (!t
.isInteger()) {
220 throw TypeCheckingExceptionPrivate(n
, "expecting an integer term in int to string 0");
223 return nodeManager
->stringType();
227 class StringStrToIntTypeRule
{
229 inline static TypeNode
computeType(NodeManager
* nodeManager
, TNode n
, bool check
)
232 TypeNode t
= n
[0].getType(check
);
234 std::stringstream ss
;
235 ss
<< "expecting a string term in argument of " << n
.getKind();
236 throw TypeCheckingExceptionPrivate(n
, ss
.str());
239 return nodeManager
->integerType();
243 class RegExpConcatTypeRule
{
245 inline static TypeNode
computeType(NodeManager
* nodeManager
, TNode n
, bool check
)
248 TNode::iterator it
= n
.begin();
249 TNode::iterator it_end
= n
.end();
251 for (; it
!= it_end
; ++ it
) {
252 TypeNode t
= (*it
).getType(check
);
254 throw TypeCheckingExceptionPrivate(n
, "expecting regexp terms in regexp concat");
259 throw TypeCheckingExceptionPrivate(n
, "expecting at least 2 terms in regexp concat");
262 return nodeManager
->regExpType();
266 class RegExpUnionTypeRule
{
268 inline static TypeNode
computeType(NodeManager
* nodeManager
, TNode n
, bool check
)
271 TNode::iterator it
= n
.begin();
272 TNode::iterator it_end
= n
.end();
273 for (; it
!= it_end
; ++ it
) {
274 TypeNode t
= (*it
).getType(check
);
276 throw TypeCheckingExceptionPrivate(n
, "expecting regexp terms");
280 return nodeManager
->regExpType();
284 class RegExpInterTypeRule
{
286 inline static TypeNode
computeType(NodeManager
* nodeManager
, TNode n
, bool check
)
289 TNode::iterator it
= n
.begin();
290 TNode::iterator it_end
= n
.end();
291 for (; it
!= it_end
; ++ it
) {
292 TypeNode t
= (*it
).getType(check
);
294 throw TypeCheckingExceptionPrivate(n
, "expecting regexp terms");
298 return nodeManager
->regExpType();
302 class RegExpStarTypeRule
{
304 inline static TypeNode
computeType(NodeManager
* nodeManager
, TNode n
, bool check
)
307 TypeNode t
= n
[0].getType(check
);
309 throw TypeCheckingExceptionPrivate(n
, "expecting regexp terms");
312 return nodeManager
->regExpType();
316 class RegExpPlusTypeRule
{
318 inline static TypeNode
computeType(NodeManager
* nodeManager
, TNode n
, bool check
)
321 TypeNode t
= n
[0].getType(check
);
323 throw TypeCheckingExceptionPrivate(n
, "expecting regexp terms");
326 return nodeManager
->regExpType();
330 class RegExpOptTypeRule
{
332 inline static TypeNode
computeType(NodeManager
* nodeManager
, TNode n
, bool check
)
335 TypeNode t
= n
[0].getType(check
);
337 throw TypeCheckingExceptionPrivate(n
, "expecting regexp terms");
340 return nodeManager
->regExpType();
344 class RegExpRangeTypeRule
{
346 inline static TypeNode
computeType(NodeManager
* nodeManager
, TNode n
, bool check
)
349 TNode::iterator it
= n
.begin();
352 for(int i
=0; i
<2; ++i
) {
353 TypeNode t
= (*it
).getType(check
);
355 throw TypeCheckingExceptionPrivate(n
, "expecting a string term in regexp range");
357 if( (*it
).getKind() != kind::CONST_STRING
) {
358 throw TypeCheckingExceptionPrivate(n
, "expecting a constant string term in regexp range");
360 if( (*it
).getConst
<String
>().size() != 1 ) {
361 throw TypeCheckingExceptionPrivate(n
, "expecting a single constant string term in regexp range");
363 ch
[i
] = (*it
).getConst
<String
>().getFirstChar();
367 throw TypeCheckingExceptionPrivate(n
, "expecting the first constant is less or equal to the second one in regexp range");
369 if (options::stdPrintASCII() && ch
[1] > '\x7f')
371 throw TypeCheckingExceptionPrivate(n
,
372 "expecting standard ASCII "
373 "characters in regexp range when "
374 "strings-print-ascii is true");
377 return nodeManager
->regExpType();
381 class RegExpLoopTypeRule
{
383 inline static TypeNode
computeType(NodeManager
* nodeManager
, TNode n
, bool check
)
386 TNode::iterator it
= n
.begin();
387 TNode::iterator it_end
= n
.end();
388 TypeNode t
= (*it
).getType(check
);
390 throw TypeCheckingExceptionPrivate(n
, "expecting a regexp term in regexp loop 1");
392 ++it
; t
= (*it
).getType(check
);
393 if (!t
.isInteger()) {
394 throw TypeCheckingExceptionPrivate(n
, "expecting an integer term in regexp loop 2");
396 //if(!(*it).isConst()) {
397 //throw TypeCheckingExceptionPrivate(n, "expecting an const integer term in regexp loop 2");
401 t
= (*it
).getType(check
);
402 if (!t
.isInteger()) {
403 throw TypeCheckingExceptionPrivate(n
, "expecting an integer term in regexp loop 3");
405 //if(!(*it).isConst()) {
406 //throw TypeCheckingExceptionPrivate(n, "expecting an const integer term in regexp loop 3");
408 //if(++it != it_end) {
409 // throw TypeCheckingExceptionPrivate(n, "too many regexp");
413 return nodeManager
->regExpType();
417 class StringToRegExpTypeRule
{
419 inline static TypeNode
computeType(NodeManager
* nodeManager
, TNode n
, bool check
)
422 TypeNode t
= n
[0].getType(check
);
424 throw TypeCheckingExceptionPrivate(n
, "expecting string terms");
426 //if( (*it).getKind() != kind::CONST_STRING ) {
427 // throw TypeCheckingExceptionPrivate(n, "expecting constant string terms");
430 return nodeManager
->regExpType();
434 class StringInRegExpTypeRule
{
436 inline static TypeNode
computeType(NodeManager
* nodeManager
, TNode n
, bool check
)
439 TNode::iterator it
= n
.begin();
440 TypeNode t
= (*it
).getType(check
);
442 throw TypeCheckingExceptionPrivate(n
, "expecting string terms");
445 t
= (*it
).getType(check
);
447 throw TypeCheckingExceptionPrivate(n
, "expecting regexp terms");
450 return nodeManager
->booleanType();
454 class EmptyRegExpTypeRule
{
456 inline static TypeNode
computeType(NodeManager
* nodeManager
, TNode n
, bool check
)
458 Assert(n
.getKind() == kind::REGEXP_EMPTY
);
459 return nodeManager
->regExpType();
463 class SigmaRegExpTypeRule
{
465 inline static TypeNode
computeType(NodeManager
* nodeManager
, TNode n
, bool check
)
467 Assert(n
.getKind() == kind::REGEXP_SIGMA
);
468 return nodeManager
->regExpType();
472 class RegExpRVTypeRule
{
474 inline static TypeNode
computeType(NodeManager
* nodeManager
, TNode n
, bool check
)
477 TypeNode t
= n
[0].getType(check
);
478 if (!t
.isInteger()) {
479 throw TypeCheckingExceptionPrivate(n
, "expecting an integer term in RV");
482 return nodeManager
->regExpType();
487 }/* CVC4::theory::strings namespace */
488 }/* CVC4::theory namespace */
489 }/* CVC4 namespace */
491 #endif /* __CVC4__THEORY__STRINGS__THEORY_STRINGS_TYPE_RULES_H */