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