1 /********************* */
2 /*! \file theory_strings_type_rules.h
4 ** Original author: Tianyi Liang
5 ** Major contributors: none
6 ** Minor contributors (to current version): none
7 ** This file is part of the CVC4 project.
8 ** Copyright (c) 2009-2013 New York University and The University of Iowa
9 ** See the file COPYING in the top-level source directory for licensing
10 ** 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"
19 #ifndef __CVC4__THEORY__STRINGS__THEORY_STRINGS_TYPE_RULES_H
20 #define __CVC4__THEORY__STRINGS__THEORY_STRINGS_TYPE_RULES_H
26 class StringConstantTypeRule
{
28 inline static TypeNode
computeType(NodeManager
* nodeManager
, TNode n
, bool check
)
29 throw (TypeCheckingExceptionPrivate
, AssertionException
) {
30 return nodeManager
->stringType();
34 class StringConcatTypeRule
{
36 inline static TypeNode
computeType(NodeManager
* nodeManager
, TNode n
, bool check
)
37 throw (TypeCheckingExceptionPrivate
, AssertionException
) {
39 TNode::iterator it
= n
.begin();
40 TNode::iterator it_end
= n
.end();
42 for (; it
!= it_end
; ++ it
) {
43 TypeNode t
= (*it
).getType(check
);
45 throw TypeCheckingExceptionPrivate(n
, "expecting string terms in string concat");
50 throw TypeCheckingExceptionPrivate(n
, "expecting at least 2 terms in string concat");
53 return nodeManager
->stringType();
57 class StringLengthTypeRule
{
59 inline static TypeNode
computeType(NodeManager
* nodeManager
, TNode n
, bool check
)
60 throw (TypeCheckingExceptionPrivate
, AssertionException
) {
62 TypeNode t
= n
[0].getType(check
);
64 throw TypeCheckingExceptionPrivate(n
, "expecting string terms in string length");
67 return nodeManager
->integerType();
71 class StringSubstrTypeRule
{
73 inline static TypeNode
computeType(NodeManager
* nodeManager
, TNode n
, bool check
)
74 throw (TypeCheckingExceptionPrivate
, AssertionException
) {
76 TypeNode t
= n
[0].getType(check
);
78 throw TypeCheckingExceptionPrivate(n
, "expecting a string term in substr");
80 t
= n
[1].getType(check
);
82 throw TypeCheckingExceptionPrivate(n
, "expecting a start int term in substr");
84 t
= n
[2].getType(check
);
86 throw TypeCheckingExceptionPrivate(n
, "expecting a length int term in substr");
89 return nodeManager
->stringType();
93 class StringContainTypeRule
{
95 inline static TypeNode
computeType(NodeManager
* nodeManager
, TNode n
, bool check
)
96 throw (TypeCheckingExceptionPrivate
, AssertionException
) {
98 TypeNode t
= n
[0].getType(check
);
100 throw TypeCheckingExceptionPrivate(n
, "expecting an orginal string term in string contain");
102 t
= n
[1].getType(check
);
104 throw TypeCheckingExceptionPrivate(n
, "expecting a target string term in string contain");
107 return nodeManager
->booleanType();
111 class StringCharAtTypeRule
{
113 inline static TypeNode
computeType(NodeManager
* nodeManager
, TNode n
, bool check
)
114 throw (TypeCheckingExceptionPrivate
, AssertionException
) {
116 TypeNode t
= n
[0].getType(check
);
118 throw TypeCheckingExceptionPrivate(n
, "expecting a string term in string char at 0");
120 t
= n
[1].getType(check
);
121 if (!t
.isInteger()) {
122 throw TypeCheckingExceptionPrivate(n
, "expecting an integer term in string char at 1");
125 return nodeManager
->stringType();
129 class StringIndexOfTypeRule
{
131 inline static TypeNode
computeType(NodeManager
* nodeManager
, TNode n
, bool check
)
132 throw (TypeCheckingExceptionPrivate
, AssertionException
) {
134 TypeNode t
= n
[0].getType(check
);
136 throw TypeCheckingExceptionPrivate(n
, "expecting a string term in string indexof 0");
138 t
= n
[1].getType(check
);
140 throw TypeCheckingExceptionPrivate(n
, "expecting a string term in string indexof 1");
142 t
= n
[2].getType(check
);
143 if (!t
.isInteger()) {
144 throw TypeCheckingExceptionPrivate(n
, "expecting an integer term in string indexof 2");
147 return nodeManager
->integerType();
151 class StringReplaceTypeRule
{
153 inline static TypeNode
computeType(NodeManager
* nodeManager
, TNode n
, bool check
)
154 throw (TypeCheckingExceptionPrivate
, AssertionException
) {
156 TypeNode t
= n
[0].getType(check
);
158 throw TypeCheckingExceptionPrivate(n
, "expecting a string term in string replace 0");
160 t
= n
[1].getType(check
);
162 throw TypeCheckingExceptionPrivate(n
, "expecting a string term in string replace 1");
164 t
= n
[2].getType(check
);
166 throw TypeCheckingExceptionPrivate(n
, "expecting a string term in string replace 2");
169 return nodeManager
->stringType();
173 class StringPrefixOfTypeRule
{
175 inline static TypeNode
computeType(NodeManager
* nodeManager
, TNode n
, bool check
)
176 throw (TypeCheckingExceptionPrivate
, AssertionException
) {
178 TypeNode t
= n
[0].getType(check
);
180 throw TypeCheckingExceptionPrivate(n
, "expecting a string term in string prefixof 0");
182 t
= n
[1].getType(check
);
184 throw TypeCheckingExceptionPrivate(n
, "expecting a string term in string prefixof 1");
187 return nodeManager
->booleanType();
191 class StringSuffixOfTypeRule
{
193 inline static TypeNode
computeType(NodeManager
* nodeManager
, TNode n
, bool check
)
194 throw (TypeCheckingExceptionPrivate
, AssertionException
) {
196 TypeNode t
= n
[0].getType(check
);
198 throw TypeCheckingExceptionPrivate(n
, "expecting a string term in string suffixof 0");
200 t
= n
[1].getType(check
);
202 throw TypeCheckingExceptionPrivate(n
, "expecting a string term in string suffixof 1");
205 return nodeManager
->booleanType();
209 class StringIntToStrTypeRule
{
211 inline static TypeNode
computeType(NodeManager
* nodeManager
, TNode n
, bool check
)
212 throw (TypeCheckingExceptionPrivate
, AssertionException
) {
214 TypeNode t
= n
[0].getType(check
);
215 if (!t
.isInteger()) {
216 throw TypeCheckingExceptionPrivate(n
, "expecting an integer term in int to string 0");
219 return nodeManager
->stringType();
223 class StringStrToIntTypeRule
{
225 inline static TypeNode
computeType(NodeManager
* nodeManager
, TNode n
, bool check
)
226 throw (TypeCheckingExceptionPrivate
, AssertionException
) {
228 TypeNode t
= n
[0].getType(check
);
230 throw TypeCheckingExceptionPrivate(n
, "expecting a string term in string to int 0");
233 return nodeManager
->integerType();
237 class RegExpConstantTypeRule
{
239 inline static TypeNode
computeType(NodeManager
* nodeManager
, TNode n
, bool check
)
240 throw (TypeCheckingExceptionPrivate
, AssertionException
) {
241 return nodeManager
->regexpType();
245 class RegExpConcatTypeRule
{
247 inline static TypeNode
computeType(NodeManager
* nodeManager
, TNode n
, bool check
)
248 throw (TypeCheckingExceptionPrivate
, AssertionException
) {
250 TNode::iterator it
= n
.begin();
251 TNode::iterator it_end
= n
.end();
253 for (; it
!= it_end
; ++ it
) {
254 TypeNode t
= (*it
).getType(check
);
256 throw TypeCheckingExceptionPrivate(n
, "expecting regexp terms in regexp concat");
261 throw TypeCheckingExceptionPrivate(n
, "expecting at least 2 terms in regexp concat");
264 return nodeManager
->regexpType();
268 class RegExpUnionTypeRule
{
270 inline static TypeNode
computeType(NodeManager
* nodeManager
, TNode n
, bool check
)
271 throw (TypeCheckingExceptionPrivate
, AssertionException
) {
273 TNode::iterator it
= n
.begin();
274 TNode::iterator it_end
= n
.end();
275 for (; it
!= it_end
; ++ it
) {
276 TypeNode t
= (*it
).getType(check
);
278 throw TypeCheckingExceptionPrivate(n
, "expecting regexp terms");
282 return nodeManager
->regexpType();
286 class RegExpInterTypeRule
{
288 inline static TypeNode
computeType(NodeManager
* nodeManager
, TNode n
, bool check
)
289 throw (TypeCheckingExceptionPrivate
, AssertionException
) {
291 TNode::iterator it
= n
.begin();
292 TNode::iterator it_end
= n
.end();
293 for (; it
!= it_end
; ++ it
) {
294 TypeNode t
= (*it
).getType(check
);
296 throw TypeCheckingExceptionPrivate(n
, "expecting regexp terms");
300 return nodeManager
->regexpType();
304 class RegExpStarTypeRule
{
306 inline static TypeNode
computeType(NodeManager
* nodeManager
, TNode n
, bool check
)
307 throw (TypeCheckingExceptionPrivate
, AssertionException
) {
309 TNode::iterator it
= n
.begin();
310 TypeNode t
= (*it
).getType(check
);
312 throw TypeCheckingExceptionPrivate(n
, "expecting regexp terms");
315 return nodeManager
->regexpType();
319 class RegExpPlusTypeRule
{
321 inline static TypeNode
computeType(NodeManager
* nodeManager
, TNode n
, bool check
)
322 throw (TypeCheckingExceptionPrivate
, AssertionException
) {
324 TNode::iterator it
= n
.begin();
325 TypeNode t
= (*it
).getType(check
);
327 throw TypeCheckingExceptionPrivate(n
, "expecting regexp terms");
330 return nodeManager
->regexpType();
334 class RegExpOptTypeRule
{
336 inline static TypeNode
computeType(NodeManager
* nodeManager
, TNode n
, bool check
)
337 throw (TypeCheckingExceptionPrivate
, AssertionException
) {
339 TNode::iterator it
= n
.begin();
340 TypeNode t
= (*it
).getType(check
);
342 throw TypeCheckingExceptionPrivate(n
, "expecting regexp terms");
345 return nodeManager
->regexpType();
349 class RegExpRangeTypeRule
{
351 inline static TypeNode
computeType(NodeManager
* nodeManager
, TNode n
, bool check
)
352 throw (TypeCheckingExceptionPrivate
, AssertionException
) {
354 TNode::iterator it
= n
.begin();
357 for(int i
=0; i
<2; ++i
) {
358 TypeNode t
= (*it
).getType(check
);
360 throw TypeCheckingExceptionPrivate(n
, "expecting a string term in regexp range");
362 if( (*it
).getKind() != kind::CONST_STRING
) {
363 throw TypeCheckingExceptionPrivate(n
, "expecting a constant string term in regexp range");
365 if( (*it
).getConst
<String
>().size() != 1 ) {
366 throw TypeCheckingExceptionPrivate(n
, "expecting a single constant string term in regexp range");
368 ch
[i
] = (*it
).getConst
<String
>().getFirstChar();
372 throw TypeCheckingExceptionPrivate(n
, "expecting the first constant is less or equal to the second one in regexp range");
375 return nodeManager
->regexpType();
379 class RegExpLoopTypeRule
{
381 inline static TypeNode
computeType(NodeManager
* nodeManager
, TNode n
, bool check
)
382 throw (TypeCheckingExceptionPrivate
, AssertionException
) {
384 TNode::iterator it
= n
.begin();
385 TNode::iterator it_end
= n
.end();
386 TypeNode t
= (*it
).getType(check
);
388 throw TypeCheckingExceptionPrivate(n
, "expecting a regexp term in regexp loop 1");
390 ++it
; t
= (*it
).getType(check
);
391 if (!t
.isInteger()) {
392 throw TypeCheckingExceptionPrivate(n
, "expecting an integer term in regexp loop 2");
394 if(!(*it
).isConst()) {
395 throw TypeCheckingExceptionPrivate(n
, "expecting an const integer term in regexp loop 2");
399 t
= (*it
).getType(check
);
400 if (!t
.isInteger()) {
401 throw TypeCheckingExceptionPrivate(n
, "expecting an integer term in regexp loop 3");
403 if(!(*it
).isConst()) {
404 throw TypeCheckingExceptionPrivate(n
, "expecting an const integer term in regexp loop 3");
406 //if(++it != it_end) {
407 // throw TypeCheckingExceptionPrivate(n, "too many regexp");
411 return nodeManager
->regexpType();
415 class StringToRegExpTypeRule
{
417 inline static TypeNode
computeType(NodeManager
* nodeManager
, TNode n
, bool check
)
418 throw (TypeCheckingExceptionPrivate
, AssertionException
) {
420 TNode::iterator it
= n
.begin();
421 TypeNode t
= (*it
).getType(check
);
423 throw TypeCheckingExceptionPrivate(n
, "expecting string terms");
425 //if( (*it).getKind() != kind::CONST_STRING ) {
426 // throw TypeCheckingExceptionPrivate(n, "expecting constant string terms");
429 return nodeManager
->regexpType();
433 class StringInRegExpTypeRule
{
435 inline static TypeNode
computeType(NodeManager
* nodeManager
, TNode n
, bool check
)
436 throw (TypeCheckingExceptionPrivate
, AssertionException
) {
438 TNode::iterator it
= n
.begin();
439 TypeNode t
= (*it
).getType(check
);
441 throw TypeCheckingExceptionPrivate(n
, "expecting string terms");
444 t
= (*it
).getType(check
);
446 throw TypeCheckingExceptionPrivate(n
, "expecting regexp terms");
449 return nodeManager
->booleanType();
453 class EmptyRegExpTypeRule
{
455 inline static TypeNode
computeType(NodeManager
* nodeManager
, TNode n
, bool check
)
456 throw (TypeCheckingExceptionPrivate
, AssertionException
) {
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
)
466 throw (TypeCheckingExceptionPrivate
, AssertionException
) {
468 Assert(n
.getKind() == kind::REGEXP_SIGMA
);
469 return nodeManager
->regexpType();
473 }/* CVC4::theory::strings namespace */
474 }/* CVC4::theory namespace */
475 }/* CVC4 namespace */
477 #endif /* __CVC4__THEORY__STRINGS__THEORY_STRINGS_TYPE_RULES_H */