ade887b23ec0e0bb7c0c92bf67df59b364927c11
[cvc5.git] / src / parser / smt / smt.cpp
1 /********************* */
2 /*! \file smt.cpp
3 ** \verbatim
4 ** Original author: cconway
5 ** Major contributors: mdeters
6 ** Minor contributors (to current version): dejan
7 ** This file is part of the CVC4 prototype.
8 ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys)
9 ** Courant Institute of Mathematical Sciences
10 ** New York University
11 ** See the file COPYING in the top-level source directory for licensing
12 ** information.\endverbatim
13 **
14 ** Definitions of SMT constants.
15 **/
16
17 #include <ext/hash_map>
18 namespace std {
19 using namespace __gnu_cxx;
20 }
21
22 #include "expr/type.h"
23 #include "expr/command.h"
24 #include "parser/parser.h"
25 #include "parser/smt/smt.h"
26
27 namespace CVC4 {
28 namespace parser {
29
30 std::hash_map<const std::string, Smt::Logic, CVC4::StringHashFunction> Smt::newLogicMap() {
31 std::hash_map<const std::string, Smt::Logic, CVC4::StringHashFunction> logicMap;
32 logicMap["QF_AX"] = QF_AX;
33 logicMap["QF_BV"] = QF_BV;
34 logicMap["QF_IDL"] = QF_IDL;
35 logicMap["QF_LIA"] = QF_LIA;
36 logicMap["QF_LRA"] = QF_LRA;
37 logicMap["QF_NIA"] = QF_NIA;
38 logicMap["QF_NRA"] = QF_NRA;
39 logicMap["QF_RDL"] = QF_RDL;
40 logicMap["QF_SAT"] = QF_SAT;
41 logicMap["QF_UF"] = QF_UF;
42 logicMap["QF_UFIDL"] = QF_UFIDL;
43 logicMap["QF_UFBV"] = QF_UFBV;
44 logicMap["QF_UFLRA"] = QF_UFLRA;
45 logicMap["QF_UFLIA"] = QF_UFLIA;
46 logicMap["QF_UFLIRA"] = QF_UFLIRA;
47 logicMap["QF_UFNIA"] = QF_UFNIA;
48 logicMap["QF_UFNIRA"] = QF_UFNIRA;
49 logicMap["QF_UFNRA"] = QF_UFNRA;
50 logicMap["QF_ABV"] = QF_ABV;
51 logicMap["QF_AUFBV"] = QF_AUFBV;
52 logicMap["QF_UFNIRA"] = QF_UFNIRA;
53 logicMap["QF_AUFLIA"] = QF_AUFLIA;
54 logicMap["QF_AUFLIRA"] = QF_AUFLIRA;
55 return logicMap;
56 }
57
58 Smt::Logic Smt::toLogic(const std::string& name) {
59 static std::hash_map<const std::string, Smt::Logic, CVC4::StringHashFunction> logicMap = newLogicMap();
60 return logicMap[name];
61 }
62
63 Smt::Smt(ExprManager* exprManager, Input* input, bool strictMode, bool parseOnly) :
64 Parser(exprManager,input,strictMode,parseOnly),
65 d_logicSet(false) {
66
67 // Boolean symbols are always defined
68 addOperator(kind::AND);
69 addOperator(kind::EQUAL);
70 addOperator(kind::IFF);
71 addOperator(kind::IMPLIES);
72 addOperator(kind::ITE);
73 addOperator(kind::NOT);
74 addOperator(kind::OR);
75 addOperator(kind::XOR);
76
77 }
78
79 void Smt::addArithmeticOperators() {
80 addOperator(kind::PLUS);
81 addOperator(kind::MINUS);
82 addOperator(kind::UMINUS);
83 addOperator(kind::MULT);
84 addOperator(kind::LT);
85 addOperator(kind::LEQ);
86 addOperator(kind::GT);
87 addOperator(kind::GEQ);
88 }
89
90 void Smt::addTheory(Theory theory) {
91 switch(theory) {
92 case THEORY_ARRAYS:
93 case THEORY_ARRAYS_EX: {
94 Type indexType = mkSort("Index");
95 Type elementType = mkSort("Element");
96 DeclarationSequence* seq = new DeclarationSequence();
97 seq->addCommand(new DeclareTypeCommand("Index", 0, indexType));
98 seq->addCommand(new DeclareTypeCommand("Element", 0, elementType));
99 preemptCommand(seq);
100
101 defineType("Array", getExprManager()->mkArrayType(indexType, elementType));
102
103 addOperator(kind::SELECT);
104 addOperator(kind::STORE);
105 break;
106 }
107
108 case THEORY_INT_ARRAYS_EX: {
109 defineType("Array", getExprManager()->mkArrayType(getExprManager()->integerType(), getExprManager()->integerType()));
110
111 addOperator(kind::SELECT);
112 addOperator(kind::STORE);
113 break;
114 }
115
116 case THEORY_EMPTY: {
117 Type sort = mkSort("U");
118 preemptCommand(new DeclareTypeCommand("U", 0, sort));
119 break;
120 }
121
122 case THEORY_REALS_INTS:
123 defineType("Real", getExprManager()->realType());
124 // falling-through on purpose, to add Ints part of RealsInts
125
126 case THEORY_INTS:
127 defineType("Int", getExprManager()->integerType());
128 addArithmeticOperators();
129 break;
130
131 case THEORY_REALS:
132 defineType("Real", getExprManager()->realType());
133 addArithmeticOperators();
134 break;
135
136 case THEORY_BITVECTORS:
137 break;
138
139 default:
140 Unhandled(theory);
141 }
142 }
143
144 bool Smt::logicIsSet() {
145 return d_logicSet;
146 }
147
148 inline void Smt::addUf() {
149 addTheory(Smt::THEORY_EMPTY);
150 addOperator(kind::APPLY_UF);
151 }
152
153 void Smt::setLogic(const std::string& name) {
154 d_logicSet = true;
155 d_logic = toLogic(name);
156
157 switch(d_logic) {
158 case QF_AX:
159 addTheory(THEORY_ARRAYS_EX);
160 break;
161
162 case QF_IDL:
163 case QF_LIA:
164 case QF_NIA:
165 addTheory(THEORY_INTS);
166 break;
167
168 case QF_RDL:
169 case QF_LRA:
170 case QF_NRA:
171 addTheory(THEORY_REALS);
172 break;
173
174 case QF_SAT:
175 /* no extra symbols needed */
176 break;
177
178 case QF_UFIDL:
179 case QF_UFLIA:
180 case QF_UFNIA:// nonstandard logic
181 addTheory(THEORY_INTS);
182 addUf();
183 break;
184
185 case QF_UFLRA:
186 case QF_UFNRA:
187 addTheory(THEORY_REALS);
188 addUf();
189 break;
190
191 case QF_UFLIRA:// nonstandard logic
192 case QF_UFNIRA:// nonstandard logic
193 addTheory(THEORY_INTS);
194 addTheory(THEORY_REALS);
195 addUf();
196 break;
197
198 case QF_UF:
199 addUf();
200 break;
201
202 case QF_BV:
203 addTheory(THEORY_BITVECTORS);
204 break;
205
206 case QF_ABV:
207 addTheory(THEORY_ARRAYS_EX);
208 addTheory(THEORY_BITVECTORS);
209 break;
210
211 case QF_UFBV:
212 addUf();
213 addTheory(THEORY_BITVECTORS);
214 break;
215
216 case QF_AUFBV:
217 addUf();
218 addTheory(THEORY_ARRAYS_EX);
219 addTheory(THEORY_BITVECTORS);
220 break;
221
222 case QF_AUFLIA:
223 addTheory(THEORY_INT_ARRAYS_EX);
224 addUf();
225 addTheory(THEORY_INTS);
226 break;
227
228 case QF_AUFLIRA:
229 addTheory(THEORY_ARRAYS_EX);
230 addUf();
231 addTheory(THEORY_INTS);
232 addTheory(THEORY_REALS);
233 break;
234
235 case AUFLIA:
236 case AUFLIRA:
237 case AUFNIRA:
238 case LRA:
239 case UFLRA:
240 case UFNIA:
241 Unhandled(name);
242 }
243 }
244
245 }/* CVC4::parser namespace */
246 }/* CVC4 namespace */