1 /********************* */
4 ** Original author: Christopher L. Conway
5 ** Major contributors: Kshitij Bansal, Morgan Deters
6 ** Minor contributors (to current version): Andrew Reynolds, Clark Barrett, Tianyi Liang
7 ** This file is part of the CVC4 project.
8 ** Copyright (c) 2009-2014 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 Definitions of SMT2 constants.
14 ** Definitions of SMT2 constants.
17 #include "expr/type.h"
18 #include "expr/command.h"
19 #include "parser/parser.h"
20 #include "parser/smt1/smt1.h"
21 #include "parser/smt2/smt2.h"
22 #include "parser/antlr_input.h"
24 // ANTLR defines these, which is really bad!
31 Smt2::Smt2(ExprManager
* exprManager
, Input
* input
, bool strictMode
, bool parseOnly
) :
32 Parser(exprManager
,input
,strictMode
,parseOnly
),
34 d_unsatCoreNames
.push(std::map
<Expr
, std::string
>());
35 if( !strictModeEnabled() ) {
36 addTheory(Smt2::THEORY_CORE
);
40 void Smt2::addArithmeticOperators() {
41 Parser::addOperator(kind::PLUS
);
42 Parser::addOperator(kind::MINUS
);
43 Parser::addOperator(kind::UMINUS
);
44 Parser::addOperator(kind::MULT
);
45 Parser::addOperator(kind::LT
);
46 Parser::addOperator(kind::LEQ
);
47 Parser::addOperator(kind::GT
);
48 Parser::addOperator(kind::GEQ
);
51 void Smt2::addBitvectorOperators() {
52 Parser::addOperator(kind::BITVECTOR_CONCAT
);
53 Parser::addOperator(kind::BITVECTOR_AND
);
54 Parser::addOperator(kind::BITVECTOR_OR
);
55 Parser::addOperator(kind::BITVECTOR_XOR
);
56 Parser::addOperator(kind::BITVECTOR_NOT
);
57 Parser::addOperator(kind::BITVECTOR_NAND
);
58 Parser::addOperator(kind::BITVECTOR_NOR
);
59 Parser::addOperator(kind::BITVECTOR_XNOR
);
60 Parser::addOperator(kind::BITVECTOR_COMP
);
61 Parser::addOperator(kind::BITVECTOR_MULT
);
62 Parser::addOperator(kind::BITVECTOR_PLUS
);
63 Parser::addOperator(kind::BITVECTOR_SUB
);
64 Parser::addOperator(kind::BITVECTOR_NEG
);
65 Parser::addOperator(kind::BITVECTOR_UDIV
);
66 Parser::addOperator(kind::BITVECTOR_UREM
);
67 Parser::addOperator(kind::BITVECTOR_SDIV
);
68 Parser::addOperator(kind::BITVECTOR_SREM
);
69 Parser::addOperator(kind::BITVECTOR_SMOD
);
70 Parser::addOperator(kind::BITVECTOR_SHL
);
71 Parser::addOperator(kind::BITVECTOR_LSHR
);
72 Parser::addOperator(kind::BITVECTOR_ASHR
);
73 Parser::addOperator(kind::BITVECTOR_ULT
);
74 Parser::addOperator(kind::BITVECTOR_ULE
);
75 Parser::addOperator(kind::BITVECTOR_UGT
);
76 Parser::addOperator(kind::BITVECTOR_UGE
);
77 Parser::addOperator(kind::BITVECTOR_SLT
);
78 Parser::addOperator(kind::BITVECTOR_SLE
);
79 Parser::addOperator(kind::BITVECTOR_SGT
);
80 Parser::addOperator(kind::BITVECTOR_SGE
);
81 Parser::addOperator(kind::BITVECTOR_BITOF
);
82 Parser::addOperator(kind::BITVECTOR_EXTRACT
);
83 Parser::addOperator(kind::BITVECTOR_REPEAT
);
84 Parser::addOperator(kind::BITVECTOR_ZERO_EXTEND
);
85 Parser::addOperator(kind::BITVECTOR_SIGN_EXTEND
);
86 Parser::addOperator(kind::BITVECTOR_ROTATE_LEFT
);
87 Parser::addOperator(kind::BITVECTOR_ROTATE_RIGHT
);
89 Parser::addOperator(kind::INT_TO_BITVECTOR
);
90 Parser::addOperator(kind::BITVECTOR_TO_NAT
);
93 void Smt2::addStringOperators() {
94 Parser::addOperator(kind::STRING_CONCAT
);
95 Parser::addOperator(kind::STRING_LENGTH
);
98 void Smt2::addFloatingPointOperators() {
99 Parser::addOperator(kind::FLOATINGPOINT_FP
);
100 Parser::addOperator(kind::FLOATINGPOINT_EQ
);
101 Parser::addOperator(kind::FLOATINGPOINT_ABS
);
102 Parser::addOperator(kind::FLOATINGPOINT_NEG
);
103 Parser::addOperator(kind::FLOATINGPOINT_PLUS
);
104 Parser::addOperator(kind::FLOATINGPOINT_SUB
);
105 Parser::addOperator(kind::FLOATINGPOINT_MULT
);
106 Parser::addOperator(kind::FLOATINGPOINT_DIV
);
107 Parser::addOperator(kind::FLOATINGPOINT_FMA
);
108 Parser::addOperator(kind::FLOATINGPOINT_SQRT
);
109 Parser::addOperator(kind::FLOATINGPOINT_REM
);
110 Parser::addOperator(kind::FLOATINGPOINT_RTI
);
111 Parser::addOperator(kind::FLOATINGPOINT_MIN
);
112 Parser::addOperator(kind::FLOATINGPOINT_MAX
);
113 Parser::addOperator(kind::FLOATINGPOINT_LEQ
);
114 Parser::addOperator(kind::FLOATINGPOINT_LT
);
115 Parser::addOperator(kind::FLOATINGPOINT_GEQ
);
116 Parser::addOperator(kind::FLOATINGPOINT_GT
);
117 Parser::addOperator(kind::FLOATINGPOINT_ISN
);
118 Parser::addOperator(kind::FLOATINGPOINT_ISSN
);
119 Parser::addOperator(kind::FLOATINGPOINT_ISZ
);
120 Parser::addOperator(kind::FLOATINGPOINT_ISINF
);
121 Parser::addOperator(kind::FLOATINGPOINT_ISNAN
);
122 Parser::addOperator(kind::FLOATINGPOINT_TO_FP_IEEE_BITVECTOR
);
123 Parser::addOperator(kind::FLOATINGPOINT_TO_FP_FLOATINGPOINT
);
124 Parser::addOperator(kind::FLOATINGPOINT_TO_FP_REAL
);
125 Parser::addOperator(kind::FLOATINGPOINT_TO_FP_SIGNED_BITVECTOR
);
126 Parser::addOperator(kind::FLOATINGPOINT_TO_FP_UNSIGNED_BITVECTOR
);
127 Parser::addOperator(kind::FLOATINGPOINT_TO_UBV
);
128 Parser::addOperator(kind::FLOATINGPOINT_TO_SBV
);
129 Parser::addOperator(kind::FLOATINGPOINT_TO_REAL
);
133 void Smt2::addTheory(Theory theory
) {
136 Parser::addOperator(kind::SELECT
);
137 Parser::addOperator(kind::STORE
);
140 case THEORY_BITVECTORS
:
141 addBitvectorOperators();
145 defineType("Bool", getExprManager()->booleanType());
146 defineVar("true", getExprManager()->mkConst(true));
147 defineVar("false", getExprManager()->mkConst(false));
148 Parser::addOperator(kind::AND
);
149 Parser::addOperator(kind::DISTINCT
);
150 Parser::addOperator(kind::EQUAL
);
151 Parser::addOperator(kind::IFF
);
152 Parser::addOperator(kind::IMPLIES
);
153 Parser::addOperator(kind::ITE
);
154 Parser::addOperator(kind::NOT
);
155 Parser::addOperator(kind::OR
);
156 Parser::addOperator(kind::XOR
);
159 case THEORY_REALS_INTS
:
160 defineType("Real", getExprManager()->realType());
161 Parser::addOperator(kind::DIVISION
);
162 Parser::addOperator(kind::TO_INTEGER
);
163 Parser::addOperator(kind::IS_INTEGER
);
164 Parser::addOperator(kind::TO_REAL
);
165 // falling through on purpose, to add Ints part of Reals_Ints
167 defineType("Int", getExprManager()->integerType());
168 addArithmeticOperators();
169 Parser::addOperator(kind::INTS_DIVISION
);
170 Parser::addOperator(kind::INTS_MODULUS
);
171 Parser::addOperator(kind::ABS
);
172 Parser::addOperator(kind::DIVISIBLE
);
176 defineType("Real", getExprManager()->realType());
177 addArithmeticOperators();
178 Parser::addOperator(kind::DIVISION
);
181 case THEORY_QUANTIFIERS
:
185 addOperator(kind::UNION
, "union");
186 addOperator(kind::INTERSECTION
, "intersection");
187 addOperator(kind::SETMINUS
, "setminus");
188 addOperator(kind::SUBSET
, "subset");
189 addOperator(kind::MEMBER
, "member");
190 addOperator(kind::SINGLETON
, "singleton");
191 addOperator(kind::INSERT
, "insert");
194 case THEORY_DATATYPES
:
195 Parser::addOperator(kind::APPLY_CONSTRUCTOR
);
196 Parser::addOperator(kind::APPLY_TESTER
);
197 Parser::addOperator(kind::APPLY_SELECTOR
);
198 Parser::addOperator(kind::APPLY_SELECTOR_TOTAL
);
202 defineType("String", getExprManager()->stringType());
203 addStringOperators();
207 Parser::addOperator(kind::APPLY_UF
);
211 defineType("RoundingMode", getExprManager()->roundingModeType());
212 defineType("Float16", getExprManager()->mkFloatingPointType(5, 11));
213 defineType("Float32", getExprManager()->mkFloatingPointType(8, 24));
214 defineType("Float64", getExprManager()->mkFloatingPointType(11, 53));
215 defineType("Float128", getExprManager()->mkFloatingPointType(15, 113));
216 addFloatingPointOperators();
220 std::stringstream ss
;
221 ss
<< "internal error: unsupported theory " << theory
;
222 throw ParserException(ss
.str());
226 void Smt2::addOperator(Kind kind
, const std::string
& name
) {
227 Debug("parser") << "Smt2::addOperator( " << kind
<< ", " << name
<< " )"
229 Parser::addOperator(kind
);
230 operatorKindMap
[name
] = kind
;
233 Kind
Smt2::getOperatorKind(const std::string
& name
) const {
234 // precondition: isOperatorEnabled(name)
235 return operatorKindMap
.find(name
)->second
;
238 bool Smt2::isOperatorEnabled(const std::string
& name
) const {
239 return operatorKindMap
.find(name
) != operatorKindMap
.end();
242 bool Smt2::isTheoryEnabled(Theory theory
) const {
245 return d_logic
.isTheoryEnabled(theory::THEORY_ARRAY
);
246 case THEORY_BITVECTORS
:
247 return d_logic
.isTheoryEnabled(theory::THEORY_BV
);
250 case THEORY_DATATYPES
:
251 return d_logic
.isTheoryEnabled(theory::THEORY_DATATYPES
);
253 return d_logic
.isTheoryEnabled(theory::THEORY_ARITH
) &&
254 d_logic
.areIntegersUsed() && ( !d_logic
.areRealsUsed() );
256 return d_logic
.isTheoryEnabled(theory::THEORY_ARITH
) &&
257 ( !d_logic
.areIntegersUsed() ) && d_logic
.areRealsUsed();
258 case THEORY_REALS_INTS
:
259 return d_logic
.isTheoryEnabled(theory::THEORY_ARITH
) &&
260 d_logic
.areIntegersUsed() && d_logic
.areRealsUsed();
261 case THEORY_QUANTIFIERS
:
262 return d_logic
.isQuantified();
264 return d_logic
.isTheoryEnabled(theory::THEORY_SETS
);
266 return d_logic
.isTheoryEnabled(theory::THEORY_STRINGS
);
268 return d_logic
.isTheoryEnabled(theory::THEORY_UF
);
270 return d_logic
.isTheoryEnabled(theory::THEORY_FP
);
272 std::stringstream ss
;
273 ss
<< "internal error: unsupported theory " << theory
;
274 throw ParserException(ss
.str());
278 bool Smt2::logicIsSet() {
284 d_logic
= LogicInfo();
285 operatorKindMap
.clear();
286 d_lastNamedTerm
= std::pair
<Expr
, std::string
>();
287 d_unsatCoreNames
= std::stack
< std::map
<Expr
, std::string
> >();
288 this->Parser::reset();
290 d_unsatCoreNames
.push(std::map
<Expr
, std::string
>());
291 if( !strictModeEnabled() ) {
292 addTheory(Smt2::THEORY_CORE
);
296 void Smt2::resetAssertions() {
297 this->Parser::reset();
300 void Smt2::setLogic(const std::string
& name
) {
302 if(logicIsForced()) {
303 d_logic
= getForcedLogic();
308 // Core theory belongs to every logic
309 addTheory(THEORY_CORE
);
311 if(d_logic
.isTheoryEnabled(theory::THEORY_UF
)) {
312 addTheory(THEORY_UF
);
315 if(d_logic
.isTheoryEnabled(theory::THEORY_ARITH
)) {
316 if(d_logic
.areIntegersUsed()) {
317 if(d_logic
.areRealsUsed()) {
318 addTheory(THEORY_REALS_INTS
);
320 addTheory(THEORY_INTS
);
322 } else if(d_logic
.areRealsUsed()) {
323 addTheory(THEORY_REALS
);
327 if(d_logic
.isTheoryEnabled(theory::THEORY_ARRAY
)) {
328 addTheory(THEORY_ARRAYS
);
331 if(d_logic
.isTheoryEnabled(theory::THEORY_BV
)) {
332 addTheory(THEORY_BITVECTORS
);
335 if(d_logic
.isTheoryEnabled(theory::THEORY_DATATYPES
)) {
336 addTheory(THEORY_DATATYPES
);
339 if(d_logic
.isTheoryEnabled(theory::THEORY_SETS
)) {
340 addTheory(THEORY_SETS
);
343 if(d_logic
.isTheoryEnabled(theory::THEORY_STRINGS
)) {
344 addTheory(THEORY_STRINGS
);
347 if(d_logic
.isQuantified()) {
348 addTheory(THEORY_QUANTIFIERS
);
351 if (d_logic
.isTheoryEnabled(theory::THEORY_FP
)) {
352 addTheory(THEORY_FP
);
355 }/* Smt2::setLogic() */
357 void Smt2::setInfo(const std::string
& flag
, const SExpr
& sexpr
) {
361 void Smt2::setOption(const std::string
& flag
, const SExpr
& sexpr
) {
365 void Smt2::checkThatLogicIsSet() {
366 if( ! logicIsSet() ) {
367 if( strictModeEnabled() ) {
368 parseError("set-logic must appear before this point.");
370 warning("No set-logic command was given before this point.");
371 warning("CVC4 will assume the non-standard ALL_SUPPORTED logic.");
372 warning("Consider setting a stricter logic for (likely) better performance.");
373 warning("To suppress this warning in the future use (set-logic ALL_SUPPORTED).");
375 setLogic("ALL_SUPPORTED");
377 Command
* c
= new SetBenchmarkLogicCommand("ALL_SUPPORTED");
384 /* The include are managed in the lexer but called in the parser */
385 // Inspired by http://www.antlr3.org/api/C/interop.html
387 static bool newInputStream(const std::string
& filename
, pANTLR3_LEXER lexer
) {
388 Debug("parser") << "Including " << filename
<< std::endl
;
389 // Create a new input stream and take advantage of built in stream stacking
390 // in C target runtime.
392 pANTLR3_INPUT_STREAM in
;
393 #ifdef CVC4_ANTLR3_OLD_INPUT_STREAM
394 in
= antlr3AsciiFileStreamNew((pANTLR3_UINT8
) filename
.c_str());
395 #else /* CVC4_ANTLR3_OLD_INPUT_STREAM */
396 in
= antlr3FileStreamNew((pANTLR3_UINT8
) filename
.c_str(), ANTLR3_ENC_8BIT
);
397 #endif /* CVC4_ANTLR3_OLD_INPUT_STREAM */
399 Debug("parser") << "Can't open " << filename
<< std::endl
;
402 // Same thing as the predefined PUSHSTREAM(in);
403 lexer
->pushCharStream(lexer
, in
);
405 //lexer->rec->state->tokenStartCharIndex = -10;
406 //lexer->emit(lexer);
408 // Note that the input stream is not closed when it EOFs, I don't bother
409 // to do it here, but it is up to you to track streams created like this
410 // and destroy them when the whole parse session is complete. Remember that you
411 // don't want to do this until all tokens have been manipulated all the way through
412 // your tree parsers etc as the token does not store the text it just refers
413 // back to the input stream and trying to get the text for it will abort if you
414 // close the input stream too early.
416 //TODO what said before
420 void Smt2::includeFile(const std::string
& filename
) {
421 // security for online version
422 if(!canIncludeFile()) {
423 parseError("include-file feature was disabled for this run.");
427 AntlrInput
* ai
= static_cast<AntlrInput
*>(getInput());
428 pANTLR3_LEXER lexer
= ai
->getAntlr3Lexer();
429 // get the name of the current stream "Does it work inside an include?"
430 const std::string inputName
= ai
->getInputStreamName();
432 // Find the directory of the current input file
434 size_t pos
= inputName
.rfind('/');
435 if(pos
!= std::string::npos
) {
436 path
= std::string(inputName
, 0, pos
+ 1);
438 path
.append(filename
);
439 if(!newInputStream(path
, lexer
)) {
440 parseError("Couldn't open include file `" + path
+ "'");
444 }/* CVC4::parser namespace */
445 }/* CVC4 namespace */