1
2 /*
3 * File Sorts.cpp.
4 *
5 * This file is part of the source code of the software program
6 * Vampire. It is protected by applicable
7 * copyright laws.
8 *
9 * This source code is distributed under the licence found here
10 * https://vprover.github.io/license.html
11 * and in the source directory
12 *
13 * In summary, you are allowed to use Vampire for non-commercial
14 * purposes but not allowed to distribute, modify, copy, create derivatives,
15 * or use in competitions.
16 * For other uses of Vampire please contact developers for a different
17 * licence, which we will make an effort to provide.
18 */
19 /**
20 * @file Sorts.cpp
21 * Implements class Sorts for handling collections of sorts.
22 */
23
24 #include "Sorts.hpp"
25
26 #include "Lib/Environment.hpp"
27 #include "Kernel/Theory.hpp"
28 #include "Shell/Options.hpp"
29
30 #include "Signature.hpp"
31
32 using namespace Kernel;
33
34 /**
35 * Initialise sorts by adding the default sort
36 * @since 04/05/2013 Manchester, updated with the new built-in sorts
37 * @author Andrei Voronkov
38 */
Sorts()39 Sorts::Sorts()
40 {
41 CALL("Sorts::Sorts");
42
43 unsigned aux;
44
45 aux = addSort("$i",true);
46 ASS_EQ(aux, SRT_DEFAULT);
47
48 aux = addSort("$o",true);
49 ASS_EQ(aux, SRT_BOOL);
50
51 aux = addSort("$int",true);
52 ASS_EQ(aux, SRT_INTEGER);
53
54 aux = addSort("$rat",true);
55 ASS_EQ(aux, SRT_RATIONAL);
56
57 aux = addSort("$real",true);
58 ASS_EQ(aux, SRT_REAL);
59
60 _hasSort = false;
61 } // Sorts::Sorts
62
63 /**
64 * Destroy the object and delete all sorts in it.
65 * @author Andrei Voronkov
66 */
~Sorts()67 Sorts::~Sorts()
68 {
69 CALL("Sorts::~Sorts");
70
71 while(_sorts.isNonEmpty()) {
72 delete _sorts.pop();
73 }
74 } // Sorts::~Sorts
75
76 /**
77 * Add a new or existing sort and return its number.
78 * @author Andrei Voronkov
79 */
addSort(const vstring & name,bool interpreted)80 unsigned Sorts::addSort(const vstring& name, bool interpreted)
81 {
82 CALL("Sorts::addSort/2");
83 bool dummy;
84 return addSort(name, dummy, interpreted);
85 } // Sorts::addSort
86
SortInfo(const vstring & name,const unsigned id,bool interpreted)87 Sorts::SortInfo::SortInfo(const vstring& name,const unsigned id, bool interpreted)
88 {
89 CALL("Sorts::SortInfo::SortInfo");
90
91 if (Signature::symbolNeedsQuoting(name,interpreted,0)) { // arity does not make sense for sorts, but the code still should
92 _name = "'" + name + "'";
93 } else {
94 _name = name;
95 }
96
97 _id = id;
98 }
99
100 /**
101 * Add a new or exising sort named @c name. Set @c added to true iff
102 * the sort turned out to be new.
103 * @author Andrei Voronkov
104 */
addSort(const vstring & name,bool & added,bool interpreted)105 unsigned Sorts::addSort(const vstring& name, bool& added, bool interpreted)
106 {
107 CALL("Sorts::addSort/3");
108
109 unsigned result;
110 if (_sortNames.find(name,result)) {
111 added = false;
112 return result;
113 }
114 _hasSort = true;
115 result = _sorts.length();
116 _sorts.push(new SortInfo(name, result,interpreted));
117 _sortNames.insert(name, result);
118 added = true;
119 return result;
120 } // Sorts::addSort
121
122
123 /**
124 *
125 * @author Giles
126 */
addArraySort(const unsigned indexSort,const unsigned innerSort)127 unsigned Sorts::addArraySort(const unsigned indexSort, const unsigned innerSort)
128 {
129 CALL("Sorts::addArraySort");
130
131 vstring name = "$array(";
132 name+=env.sorts->sortName(indexSort);
133 name+=",";
134 name+=env.sorts->sortName(innerSort);
135 name+=")";
136 unsigned result;
137 if(_sortNames.find(name,result)){
138 return result;
139 }
140
141 _hasSort = true;
142 result = _sorts.length();
143
144 ArraySort* sort = new ArraySort(name,indexSort,innerSort,result);
145 _sorts.push(sort);
146 _sortNames.insert(name,result);
147
148 return result;
149 }
150
151 struct SortInfoToInt{
152 DECL_RETURN_TYPE(unsigned);
operator ()SortInfoToInt153 unsigned operator()(Sorts::SortInfo* s){ return s->id(); }
154 };
155
156 /**
157 * @authors Giles, Evgeny
158 */
getStructuredSorts(const StructuredSort ss)159 VirtualIterator<unsigned> Sorts::getStructuredSorts(const StructuredSort ss)
160 {
161 CALL("Sorts::getStructuredSorts");
162 Stack<SortInfo*>::Iterator all(_sorts);
163 VirtualIterator<SortInfo*> structuredSorts = pvi(getFilteredIterator(all,
164 [ss](SortInfo* s){ return s->isOfStructuredSort(ss);}));
165 return pvi(getMappingIterator(structuredSorts,SortInfoToInt()));
166 }
167
addTupleSort(unsigned arity,unsigned sorts[])168 unsigned Sorts::addTupleSort(unsigned arity, unsigned sorts[])
169 {
170 CALL("Sorts::addTupleSort");
171
172 vstring name = "[";
173 for (unsigned i = 0; i < arity; i++) {
174 name += env.sorts->sortName(sorts[i]);
175 if (i != arity - 1) {
176 name += ",";
177 }
178 }
179 name += "]";
180 unsigned result;
181 if(_sortNames.find(name, result)) {
182 return result;
183 }
184
185 _hasSort = true;
186 result = _sorts.length();
187
188 _sorts.push(new TupleSort(name,result,arity,sorts));
189 _sortNames.insert(name, result);
190
191 return result;
192 }
193
194 /**
195 * True if this collection contains the sort @c name.
196 * @author Andrei Voronkov
197 */
haveSort(const vstring & name)198 bool Sorts::haveSort(const vstring& name)
199 {
200 CALL("Sorts::haveSort");
201 return _sortNames.find(name);
202 } // haveSort
203
204 /**
205 * Find a sort with the name @c name. If the sort is found, return true and set @c idx
206 * to the sort number. Otherwise, return false.
207 * @author Andrei Voronkov
208 */
findSort(const vstring & name,unsigned & idx)209 bool Sorts::findSort(const vstring& name, unsigned& idx)
210 {
211 CALL("Sorts::findSort");
212 return _sortNames.find(name, idx);
213 } // Sorts::findSort
214
sortName(unsigned idx) const215 const vstring& Sorts::sortName(unsigned idx) const
216 {
217 CALL("Sorts::sortName");
218 if (env.options->showFOOL() && idx == SRT_BOOL) {
219 static vstring name("$bool");
220 return name;
221 }
222 return _sorts[idx]->name();
223 } // Sorts::sortName
224
225 /**
226 * Pre-initialise an OperatorKey.
227 *
228 * If @c sorts is is NULL, all arguments will be initalized by the default sort,
229 * otherwise, by sorts from the array @c sorts
230 * @author Andrei Voronkov
231 */
setupKey(unsigned arity,const unsigned * sorts)232 OperatorType::OperatorKey* OperatorType::setupKey(unsigned arity, const unsigned* sorts)
233 {
234 CALL("OperatorType::setupKey(unsigned,const unsigned*)");
235
236 OperatorKey* key = OperatorKey::allocate(arity+1);
237
238 if (!sorts) {
239 // initialise all argument types to the default type
240 for (unsigned i = 0; i < arity; i++) {
241 (*key)[i] = Sorts::SRT_DEFAULT;
242 }
243 } else {
244 // initialise all the argument types to those taken from sorts
245 for (unsigned i = 0; i < arity; i++) {
246 (*key)[i] = sorts[i];
247 }
248 }
249 return key;
250 }
251
252 /**
253 * Pre-initialise an OperatorKey from an initializer list of sorts.
254 */
setupKey(std::initializer_list<unsigned> sorts)255 OperatorType::OperatorKey* OperatorType::setupKey(std::initializer_list<unsigned> sorts)
256 {
257 CALL("OperatorType::setupKey(std::initializer_list<unsigned>)");
258
259 OperatorKey* key = OperatorKey::allocate(sorts.size()+1);
260
261 // initialise all the argument types to those taken from sorts
262 unsigned i = 0;
263 for (auto sort : sorts) {
264 (*key)[i++] = sort;
265 }
266
267 return key;
268 }
269
270 /**
271 * Pre-initialise an OperatorKey from using a uniform range.
272 */
setupKeyUniformRange(unsigned arity,unsigned argsSort)273 OperatorType::OperatorKey* OperatorType::setupKeyUniformRange(unsigned arity, unsigned argsSort)
274 {
275 CALL("OperatorType::setupKeyUniformRange");
276
277 OperatorKey* key = OperatorKey::allocate(arity+1);
278
279 for (unsigned i=0; i<arity; i++) {
280 (*key)[i] = argsSort;
281 }
282
283 return key;
284 }
285
operatorTypes()286 OperatorType::OperatorTypes& OperatorType::operatorTypes() {
287 // we should delete all the stored OperatorTypes inside at the end of the world, when this get destroyed
288 static OperatorType::OperatorTypes _operatorTypes;
289 return _operatorTypes;
290 }
291
292 /**
293 * Check if OperatorType corresponding to the given key
294 * already exists. If so return it, if not create new,
295 * store it for future retrieval and return it.
296 *
297 * Release key if not needed.
298 */
getTypeFromKey(OperatorType::OperatorKey * key)299 OperatorType* OperatorType::getTypeFromKey(OperatorType::OperatorKey* key)
300 {
301 CALL("OperatorType::getTypeFromKey");
302
303 /*
304 cout << "getTypeFromKey(" << key->length() << "): ";
305 for (unsigned i = 0; i < key->length(); i++) {
306 cout << (((*key)[i] == PREDICATE_FLAG) ? "FFFF" : env.sorts->sortName((*key)[i])) << ",";
307 }
308 */
309
310 OperatorType* resultType;
311 if (operatorTypes().find(key,resultType)) {
312 key->deallocate();
313
314 // cout << " Found " << resultType << endl;
315
316 return resultType;
317 }
318
319 resultType = new OperatorType(key);
320 operatorTypes().insert(key,resultType);
321
322 // cout << " Created new " << resultType << endl;
323
324 return resultType;
325 }
326
327 /**
328 * Return the string representation of arguments of a non-atomic
329 * functional or a predicate sort in the form (t1 * ... * tn)
330 * @since 04/05/2013 bug fix (comma was used instead of *)
331 * @author Andrei Voronkov
332 */
argsToString() const333 vstring OperatorType::argsToString() const
334 {
335 CALL("OperatorType::argsToString");
336
337 vstring res = "(";
338 unsigned ar = arity();
339 ASS(ar);
340 for (unsigned i = 0; i < ar; i++) {
341 res += env.sorts->sortName(arg(i));
342 if (i != ar-1) {
343 res += " * ";
344 }
345 }
346 res += ')';
347 return res;
348 } // OperatorType::argsToString()
349
350 /**
351 * Return the TPTP string representation of the OpertorType.
352 */
toString() const353 vstring OperatorType::toString() const
354 {
355 CALL("OperatorType::toString");
356
357 return (arity() ? argsToString() + " > " : "") +
358 (isPredicateType() ? "$o" : env.sorts->sortName(result()));
359 }
360
361 /**
362 * True if all arguments of this type have sort @c str
363 * and so is the result sort if we are talking about a function type.
364 * @author Andrei Voronkov
365 */
isSingleSortType(unsigned srt) const366 bool OperatorType::isSingleSortType(unsigned srt) const
367 {
368 CALL("OperatorType::isAllDefault");
369
370 unsigned len = arity();
371 for (unsigned i = 0; i <len; i++) {
372 if (arg(i) != srt) {
373 return false;
374 }
375 }
376
377 if (isFunctionType() && result() != srt) {
378 return false;
379 }
380
381 return true;
382 } // isSingleSortType
383