1 
2 /*
3  * File Signature.hpp.
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 Signature.hpp
21  * Defines class Signature for handling signatures
22  *
23  * @since 07/05/2007 Manchester, created anew instead of the old overcomplicated
24  *        Signature
25  */
26 
27 #ifndef __Signature__
28 #define __Signature__
29 
30 #include "Forwards.hpp"
31 
32 #include "Debug/Assertion.hpp"
33 
34 #include "Lib/Allocator.hpp"
35 #include "Lib/Stack.hpp"
36 #include "Lib/Map.hpp"
37 #include "Lib/DHMap.hpp"
38 #include "Lib/VString.hpp"
39 #include "Lib/Environment.hpp"
40 #include "Lib/SmartPtr.hpp"
41 
42 #include "Shell/TermAlgebra.hpp"
43 #include "Shell/Options.hpp"
44 
45 #include "Sorts.hpp"
46 #include "Theory.hpp"
47 
48 
49 namespace Kernel {
50 
51 using namespace std;
52 using namespace Lib;
53 
54 /**
55  * Class implementing signatures
56  */
57 class Signature
58 {
59  public:
60   /** Function or predicate symbol */
61   class Symbol {
62   protected:
63     /** print name */
64     vstring _name;
65     /** arity */
66     unsigned _arity;
67     /** the object is of type InterpretedSymbol */
68     unsigned _interpreted : 1;
69     /** symbol that doesn't come from input problem, but was introduced by Vampire */
70     unsigned _introduced : 1;
71     /** protected symbols aren't subject to any kind of preprocessing elimination */
72     unsigned _protected : 1;
73     /** clauses with only skipped symbols will not be output as symbol eliminating */
74     unsigned _skip : 1;
75     /** marks propositional predicate symbols that are labels to
76         be used as names during consequence finding or function relationship finding */
77     unsigned _label : 1;
78     /** marks predicates that are equality proxy */
79     unsigned _equalityProxy : 1;
80     /** used in coloured proofs and interpolation */
81     unsigned _color : 2;
82     /** marks distinct string constants */
83     unsigned _stringConstant : 1;
84     /** marks numeric constants, they are only used in TPTP's fof declarations */
85     unsigned _numericConstant : 1;
86     /** predicate introduced for query answering */
87     unsigned _answerPredicate : 1;
88     /** marks numbers too large to represent natively */
89     unsigned _overflownConstant : 1;
90     /** marks term algebra constructors */
91     unsigned _termAlgebraCons : 1;
92     /** Either a FunctionType of a PredicateType object */
93     mutable OperatorType* _type;
94     /** List of distinct groups the constant is a member of, all members of a distinct group should be distinct from each other */
95     List<unsigned>* _distinctGroups;
96     /** number of times it is used in the problem */
97     unsigned _usageCount;
98     /** number of units it is used in in the problem */
99     unsigned _unitUsageCount;
100     /** if used in the goal **/
101     unsigned _inGoal : 1;
102     /** if used in a unit **/
103     unsigned _inUnit : 1;
104     /** if induction skolem **/
105     unsigned _inductionSkolem : 1;
106     /** if skolem function in general **/
107     unsigned _skolem : 1;
108 
109   public:
110     /** standard constructor */
111     Symbol(const vstring& nm,unsigned arity, bool interpreted=false, bool stringConstant=false,bool numericConstant=false,bool overflownConstant=false);
112     void destroyFnSymbol();
113     void destroyPredSymbol();
114 
115     void addColor(Color color);
116     /** mark symbol that doesn't come from input problem, but was introduced by Vampire */
markIntroduced()117     void markIntroduced() { _introduced=1; }
118     /** remove the marking that the symbol was introduced, it has now been found in the input
119         we should be careful that the previously introduced symbols are renamed elsewhere */
unmarkIntroduced()120     void unmarkIntroduced(){ _introduced=0; }
121     /** mark the symbol as protected so it is not being eliminated by preprocessing */
markProtected()122     void markProtected() { _protected=1; }
123     /** mark the symbol as skip for the purpose of symbol elimination */
markSkip()124     void markSkip() { _skip=1; }
125     /** mark the symbol as name for consequence finding */
markLabel()126     void markLabel() { ASS_EQ(arity(), 0); _label=1; markProtected(); }
127     /** mark symbol to be an answer predicate */
markAnswerPredicate()128     void markAnswerPredicate() { _answerPredicate=1; markProtected(); }
129     /** mark predicate to be an equality proxy */
markEqualityProxy()130     void markEqualityProxy() { _equalityProxy=1; }
131     /** mark constant as overflown */
markOverflownConstant()132     void markOverflownConstant() { _overflownConstant=1; }
133     /** mark symbol as a term algebra constructor */
markTermAlgebraCons()134     void markTermAlgebraCons() { _termAlgebraCons=1; }
135 
136     /** return true iff symbol is marked as skip for the purpose of symbol elimination */
skip() const137     bool skip() const { return _skip; }
138     /** return true iff the symbol is marked as name predicate
139         for consequence finding */
label() const140     bool label() const { return _label; }
141     /** return the colour of the symbol */
color() const142     Color color() const { return static_cast<Color>(_color); }
143     /** Return the arity of the symbol */
arity() const144     inline unsigned arity() const { return _arity; }
145     /** Return the name of the symbol */
name() const146     inline const vstring& name() const { return _name; }
147     /** Return true iff the object is of type InterpretedSymbol */
interpreted() const148     inline bool interpreted() const { return _interpreted; }
149     /** Return true iff the symbol doesn't come from input problem but was introduced by Vampire */
introduced() const150     inline bool introduced() const { return _introduced; }
151     /** Return true iff the symbol is must not be eliminated by proprocessing */
protectedSymbol() const152     inline bool protectedSymbol() const { return _protected; }
153     /** Return true iff symbol is a distinct string constant */
stringConstant() const154     inline bool stringConstant() const { return _stringConstant; }
155     /** Return true iff symbol is a numeric constant */
numericConstant() const156     inline bool numericConstant() const { return _numericConstant; }
157     /** Return true iff symbol is an answer predicate */
answerPredicate() const158     inline bool answerPredicate() const { return _answerPredicate; }
159     /** Return true iff symbol is an equality proxy */
equalityProxy() const160     inline bool equalityProxy() const { return _equalityProxy; }
161     /** Return true iff symbol is an overflown constant */
overflownConstant() const162     inline bool overflownConstant() const { return _overflownConstant; }
163     /** Return true iff symbol is a term algebra constructor */
termAlgebraCons() const164     inline bool termAlgebraCons() const { return _termAlgebraCons; }
165 
166     /** Increase the usage count of this symbol **/
incUsageCnt()167     inline void incUsageCnt(){ _usageCount++; }
168     /** Return the usage count of this symbol **/
usageCnt() const169     inline unsigned usageCnt() const { return _usageCount; }
170     /** Reset usage count to zero, to start again! **/
resetUsageCnt()171     inline void resetUsageCnt(){ _usageCount=0; }
172 
incUnitUsageCnt()173     inline void incUnitUsageCnt(){ _unitUsageCount++;}
unitUsageCnt() const174     inline unsigned unitUsageCnt() const { return _unitUsageCount; }
resetUnitUsageCnt()175     inline void resetUnitUsageCnt(){ _unitUsageCount=0;}
176 
markInGoal()177     inline void markInGoal(){ _inGoal=1; }
inGoal()178     inline bool inGoal(){ return _inGoal; }
markInUnit()179     inline void markInUnit(){ _inUnit=1; }
inUnit()180     inline bool inUnit(){ return _inUnit; }
181 
markSkolem()182     inline void markSkolem(){ _skolem = 1;}
skolem()183     inline bool skolem(){ return _skolem; }
184 
markInductionSkolem()185     inline void markInductionSkolem(){ _inductionSkolem=1; _skolem=1;}
inductionSkolem()186     inline bool inductionSkolem(){ return _inductionSkolem;}
187 
188     /** Return true if symbol is an integer constant */
integerConstant() const189     inline bool integerConstant() const
190     { return interpreted() && arity()==0 && fnType()->result()==Sorts::SRT_INTEGER; }
191     /** Return true if symbol is a rational constant */
rationalConstant() const192     inline bool rationalConstant() const
193     { return interpreted() && arity()==0 && fnType()->result()==Sorts::SRT_RATIONAL; }
194     /** Return true if symbol is a real constant */
realConstant() const195     inline bool realConstant() const
196     { return interpreted() && arity()==0 && fnType()->result()==Sorts::SRT_REAL; }
197 
198     /** return true if an interpreted number, note subtle but significant difference from numericConstant **/
interpretedNumber() const199     inline bool interpretedNumber() const
200     { return integerConstant() || rationalConstant() || realConstant(); }
201 
202     /** Return value of an integer constant */
integerValue() const203     inline IntegerConstantType integerValue() const
204     { ASS(integerConstant()); return static_cast<const IntegerSymbol*>(this)->_intValue; }
205     /** Return value of a rational constant */
rationalValue() const206     inline RationalConstantType rationalValue() const
207     { ASS(rationalConstant()); return static_cast<const RationalSymbol*>(this)->_ratValue; }
208     /** Return value of a real constant */
realValue() const209     inline RealConstantType realValue() const
210     { ASS(realConstant()); return static_cast<const RealSymbol*>(this)->_realValue; }
211 
distinctGroups() const212     const List<unsigned>* distinctGroups() const { return _distinctGroups; }
213     /** This takes the symbol number of this symbol as the symbol doesn't know it
214         Note that this should only be called on a constant **/
215     void addToDistinctGroup(unsigned group,unsigned this_number);
216 
217     void setType(OperatorType* type);
218     void forceType(OperatorType* type);
219     OperatorType* fnType() const;
220     OperatorType* predType() const;
221 
222     CLASS_NAME(Signature::Symbol);
223     USE_ALLOCATOR(Symbol);
224   }; // class Symbol
225 
226   class InterpretedSymbol
227   : public Symbol
228   {
229     friend class Signature;
230     friend class Symbol;
231   protected:
232     Interpretation _interp;
233 
234   public:
235 
InterpretedSymbol(const vstring & nm,Interpretation interp)236     InterpretedSymbol(const vstring& nm, Interpretation interp)
237     : Symbol(nm, Theory::getArity(interp), true), _interp(interp)
238     {
239       CALL("InterpretedSymbol");
240     }
241 
242     CLASS_NAME(Signature::InterpretedSymbol);
243     USE_ALLOCATOR(InterpretedSymbol);
244 
245     /** Return the interpreted function that corresponds to this symbol */
getInterpretation() const246     inline Interpretation getInterpretation() const { ASS_REP(interpreted(), _name); return _interp; }
247   };
248 
249   class IntegerSymbol
250   : public Symbol
251   {
252     friend class Signature;
253     friend class Symbol;
254   protected:
255     IntegerConstantType _intValue;
256 
257   public:
IntegerSymbol(const IntegerConstantType & val)258     IntegerSymbol(const IntegerConstantType& val)
259     : Symbol(val.toString(), 0, true), _intValue(val)
260     {
261       CALL("IntegerSymbol");
262 
263       setType(OperatorType::getConstantsType(Sorts::SRT_INTEGER));
264     }
265     CLASS_NAME(Signature::IntegerSymbol);
266     USE_ALLOCATOR(IntegerSymbol);
267   };
268 
269   class RationalSymbol
270   : public Symbol
271   {
272     friend class Signature;
273     friend class Symbol;
274   protected:
275     RationalConstantType _ratValue;
276 
277   public:
RationalSymbol(const RationalConstantType & val)278     RationalSymbol(const RationalConstantType& val)
279     : Symbol(val.toString(), 0, true), _ratValue(val)
280     {
281       CALL("RationalSymbol");
282 
283       setType(OperatorType::getConstantsType(Sorts::SRT_RATIONAL));
284     }
285     CLASS_NAME(Signature::RationalSymbol);
286     USE_ALLOCATOR(RationalSymbol);
287   };
288 
289   class RealSymbol
290   : public Symbol
291   {
292     friend class Signature;
293     friend class Symbol;
294   protected:
295     RealConstantType _realValue;
296 
297   public:
RealSymbol(const RealConstantType & val)298     RealSymbol(const RealConstantType& val)
299     : Symbol((env.options->proof() == Shell::Options::Proof::PROOFCHECK) ? "$to_real("+val.toString()+")" : val.toNiceString(), 0, true), _realValue(val)
300     {
301       CALL("RealSymbol");
302 
303       setType(OperatorType::getConstantsType(Sorts::SRT_REAL));
304     }
305     CLASS_NAME(Signature::RealSymbol);
306     USE_ALLOCATOR(RealSymbol);
307   };
308 
309   //////////////////////////////////////
310   // Uninterpreted symbol declarations
311   //
312 
313   unsigned addPredicate(const vstring& name,unsigned arity,bool& added);
314   unsigned addFunction(const vstring& name,unsigned arity,bool& added,bool overflowConstant = false);
315 
316   /**
317    * If a predicate with this name and arity exists, return its number.
318    * Otherwise, add a new one and return its number.
319    *
320    * @param name name of the symbol
321    * @param arity arity of the symbol
322    * @since 07/05/2007 Manchester
323    */
addPredicate(const vstring & name,unsigned arity)324   unsigned addPredicate(const vstring& name,unsigned arity)
325   {
326     bool added;
327     return addPredicate(name,arity,added);
328   }
329   /**
330    * If a function with this name and arity exists, return its number.
331    * Otherwise, add a new one and return its number.
332    *
333    * @since 28/12/2007 Manchester
334    */
addFunction(const vstring & name,unsigned arity)335   unsigned addFunction(const vstring& name,unsigned arity)
336   {
337     bool added;
338     return addFunction(name,arity,added);
339   }
340   /**
341    * If a unique string constant with this name and arity exists, return its number.
342    * Otherwise, add a new one and return its number.
343    *
344    * The added constant is of sort Sorts::SRT_DEFAULT.
345    */
346   unsigned addStringConstant(const vstring& name);
347   unsigned addFreshFunction(unsigned arity, const char* prefix, const char* suffix = 0);
348   unsigned addSkolemFunction(unsigned arity,const char* suffix = 0);
349   unsigned addFreshPredicate(unsigned arity, const char* prefix, const char* suffix = 0);
350   unsigned addSkolemPredicate(unsigned arity,const char* suffix = 0);
351   unsigned addNamePredicate(unsigned arity);
352 
353   // Interpreted symbol declarations
354   unsigned addIntegerConstant(const vstring& number,bool defaultSort);
355   unsigned addRationalConstant(const vstring& numerator, const vstring& denominator,bool defaultSort);
356   unsigned addRealConstant(const vstring& number,bool defaultSort);
357 
358   unsigned addIntegerConstant(const IntegerConstantType& number);
359   unsigned addRationalConstant(const RationalConstantType& number);
360   unsigned addRealConstant(const RealConstantType& number);
361 
362   unsigned addInterpretedFunction(Interpretation itp, OperatorType* type, const vstring& name);
addInterpretedFunction(Interpretation itp,const vstring & name)363   unsigned addInterpretedFunction(Interpretation itp, const vstring& name)
364   {
365     CALL("Signature::addInterpretedFunction(Interpretation,const vstring&)");
366     ASS(!Theory::isPolymorphic(itp));
367     return addInterpretedFunction(itp,Theory::getNonpolymorphicOperatorType(itp),name);
368   }
369 
370   unsigned addInterpretedPredicate(Interpretation itp, OperatorType* type, const vstring& name);
addInterpretedPredicate(Interpretation itp,const vstring & name)371   unsigned addInterpretedPredicate(Interpretation itp, const vstring& name)
372   {
373     CALL("Signature::addInterpretedPredicate(Interpretation,const vstring&)");
374     ASS(!Theory::isPolymorphic(itp));
375     return addInterpretedPredicate(itp,Theory::getNonpolymorphicOperatorType(itp),name);
376   }
377 
378   unsigned getInterpretingSymbol(Interpretation interp, OperatorType* type);
getInterpretingSymbol(Interpretation interp)379   unsigned getInterpretingSymbol(Interpretation interp)
380   {
381     CALL("Signature::getInterpretingSymbol(Interpretation)");
382     ASS(!Theory::isPolymorphic(interp));
383     return getInterpretingSymbol(interp,Theory::getNonpolymorphicOperatorType(interp));
384   }
385 
386   /** Return true iff there is a symbol interpreted by Interpretation @b interp */
haveInterpretingSymbol(Interpretation interp,OperatorType * type) const387   bool haveInterpretingSymbol(Interpretation interp, OperatorType* type) const {
388     CALL("Signature::haveInterpretingSymbol(Interpretation, OperatorType*)");
389     return _iSymbols.find(std::make_pair(interp,type));
390   }
haveInterpretingSymbol(Interpretation interp)391   bool haveInterpretingSymbol(Interpretation interp)
392   {
393     CALL("Signature::haveInterpretingSymbol(Interpretation)");
394     ASS(!Theory::isPolymorphic(interp));
395     return haveInterpretingSymbol(interp,Theory::getNonpolymorphicOperatorType(interp));
396   }
397 
398   /** return the name of a function with a given number */
399   const vstring& functionName(int number);
400   /** return the name of a predicate with a given number */
predicateName(int number)401   const vstring& predicateName(int number)
402   {
403     return _preds[number]->name();
404   }
405   /** return the arity of a function with a given number */
functionArity(int number)406   const unsigned functionArity(int number)
407   {
408     CALL("Signature::functionArity");
409     return _funs[number]->arity();
410   }
411   /** return the arity of a predicate with a given number */
predicateArity(int number)412   const unsigned predicateArity(int number)
413   {
414     CALL("Signature::predicateArity");
415     return _preds[number]->arity();
416   }
417 
predicateColored(int number)418   const bool predicateColored(int number)
419   {
420     return _preds[number]->color()!=COLOR_TRANSPARENT;
421   }
422 
functionColored(int number)423   const bool functionColored(int number)
424   {
425     return _funs[number]->color()!=COLOR_TRANSPARENT;
426   }
427 
428   /** return true iff predicate of given @b name and @b arity exists. */
isPredicateName(vstring name,unsigned arity)429   bool isPredicateName(vstring name, unsigned arity)
430   {
431     vstring symbolKey = key(name,arity);
432     unsigned tmp;
433     return _predNames.find(symbolKey,tmp);
434   }
435 
436   /** return the number of functions */
functions() const437   unsigned functions() const { return _funs.length(); }
438   /** return the number of predicates */
predicates() const439   unsigned predicates() const { return _preds.length(); }
440 
441   /** Return the function symbol by its number */
getFunction(unsigned n)442   inline Symbol* getFunction(unsigned n)
443   {
444     ASS_REP(n < _funs.length(),n);
445     return _funs[n];
446   } // getFunction
447   /** Return the predicate symbol by its number */
getPredicate(unsigned n)448   inline Symbol* getPredicate(unsigned n)
449   {
450     ASS(n < _preds.length());
451     return _preds[n];
452   } // getPredicate
453 
isEqualityPredicate(unsigned p)454   static inline bool isEqualityPredicate(unsigned p)
455   {
456     // we make sure equality is always 0
457     return (p == 0); // see the ASSERT in Signature::Signature
458   }
459 
460   Signature();
461   ~Signature();
462 
463   CLASS_NAME(Signature);
464   USE_ALLOCATOR(Signature);
465 
466   bool functionExists(const vstring& name,unsigned arity) const;
467   bool predicateExists(const vstring& name,unsigned arity) const;
468 
469   unsigned getFunctionNumber(const vstring& name, unsigned arity) const;
470   unsigned getPredicateNumber(const vstring& name, unsigned arity) const;
471 
472   typedef SmartPtr<Stack<unsigned>> DistinctGroupMembers;
473 
474   Unit* getDistinctGroupPremise(unsigned group);
475   unsigned createDistinctGroup(Unit* premise = 0);
476   void addToDistinctGroup(unsigned constantSymbol, unsigned groupId);
hasDistinctGroups()477   bool hasDistinctGroups(){ return _distinctGroupsAddedTo; }
noDistinctGroupsLeft()478   void noDistinctGroupsLeft(){ _distinctGroupsAddedTo=false; }
distinctGroupMembers()479   Stack<DistinctGroupMembers> &distinctGroupMembers(){ return _distinctGroupMembers; }
480 
hasTermAlgebras()481   bool hasTermAlgebras() { return !_termAlgebras.isEmpty(); }
482 
483   static vstring key(const vstring& name,int arity);
484 
485   /** the number of string constants */
strings() const486   unsigned strings() const {return _strings;}
487   /** the number of integer constants */
integers() const488   unsigned integers() const {return _integers;}
489   /** the number of rational constants */
rationals() const490   unsigned rationals() const {return _rationals;}
491   /** the number of real constants */
reals() const492   unsigned reals() const {return _reals;}
493 
494   static const unsigned STRING_DISTINCT_GROUP;
495 
getFoolConstantSymbol(bool isTrue)496   unsigned getFoolConstantSymbol(bool isTrue){
497     if(!_foolConstantsDefined){
498       _foolFalse = addFunction("$$false",0);
499       getFunction(_foolFalse)->setType(OperatorType::getConstantsType(Sorts::SRT_BOOL));
500       _foolTrue = addFunction("$$true",0);
501       getFunction(_foolTrue)->setType(OperatorType::getConstantsType(Sorts::SRT_BOOL));
502       _foolConstantsDefined=true;
503     }
504     return isTrue ? _foolTrue : _foolFalse;
505   }
isFoolConstantSymbol(bool isTrue,unsigned number)506   bool isFoolConstantSymbol(bool isTrue, unsigned number){
507     if(!_foolConstantsDefined) return false;
508     return isTrue ? number==_foolTrue : number==_foolFalse;
509   }
510 
isTermAlgebraSort(unsigned sort)511   bool isTermAlgebraSort(unsigned sort) { return _termAlgebras.find(sort); }
getTermAlgebraOfSort(unsigned sort)512   Shell::TermAlgebra *getTermAlgebraOfSort(unsigned sort) { return _termAlgebras.get(sort); }
addTermAlgebra(Shell::TermAlgebra * ta)513   void addTermAlgebra(Shell::TermAlgebra *ta) { _termAlgebras.insert(ta->sort(), ta); }
termAlgebrasIterator() const514   VirtualIterator<Shell::TermAlgebra*> termAlgebrasIterator() const { return _termAlgebras.range(); }
515   Shell::TermAlgebraConstructor* getTermAlgebraConstructor(unsigned functor);
516 
recordDividesNvalue(TermList n)517   void recordDividesNvalue(TermList n){
518     _dividesNvalues.push(n);
519   }
getDividesNvalues()520   Stack<TermList>& getDividesNvalues(){ return _dividesNvalues; }
521 
522   static bool symbolNeedsQuoting(vstring name, bool interpreted, unsigned arity);
523 
524 private:
525   Stack<TermList> _dividesNvalues;
526 
527   bool _foolConstantsDefined;
528   unsigned _foolTrue;
529   unsigned _foolFalse;
530 
531   static bool isProtectedName(vstring name);
532   static bool charNeedsQuoting(char c, bool first);
533   /** Stack of function symbols */
534   Stack<Symbol*> _funs;
535   /** Stack of predicate symbols */
536   Stack<Symbol*> _preds;
537   /**
538    * Map from vstring "name_arity" to their numbers
539    *
540    * String constants have key "value_c", integer constants "value_n",
541    * rational "numerator_denominator_q" and real "value_r".
542    */
543   SymbolMap _funNames;
544   /** Map from vstring "name_arity" to their numbers */
545   SymbolMap _predNames;
546   /** Map for the arity_check options: maps symbols to their arities */
547   SymbolMap _arityCheck;
548   /** Last number used for fresh functions and predicates */
549   int _nextFreshSymbolNumber;
550 
551   /** Number of Skolem functions (this is just for LaTeX output) */
552   unsigned _skolemFunctionCount;
553 
554   /** Map from symbol names to variable numbers*/
555   SymbolMap _varNames;
556 
557   // Store the premise of a distinct group for proof printing, if 0 then group is input
558   Stack<Unit*> _distinctGroupPremises;
559 
560   // We only store members up until a hard-coded limit i.e. the limit at which we will expand the group
561   Stack<DistinctGroupMembers> _distinctGroupMembers;
562   // Flag to indicate if any distinct groups have members
563   bool _distinctGroupsAddedTo;
564 
565   /**
566    * Map from MonomorphisedInterpretation values to function and predicate symbols representing them
567    *
568    * We mix here function and predicate symbols, but it is not a problem, as
569    * the MonomorphisedInterpretation value already determines whether we deal with a function
570    * or a predicate.
571    */
572   DHMap<Theory::MonomorphisedInterpretation, unsigned> _iSymbols;
573 
574   /** the number of string constants */
575   unsigned _strings;
576   /** the number of integer constants */
577   unsigned _integers;
578   /** the number of rational constants */
579   unsigned _rationals;
580   /** the number of real constants */
581   unsigned _reals;
582 
583   /**
584    * Map from sorts to the associated term algebra, if applicable for the sort
585    */
586   DHMap<unsigned, Shell::TermAlgebra*> _termAlgebras;
587 
588   void defineOptionTermAlgebra(unsigned optionSort);
589   void defineEitherTermAlgebra(unsigned eitherSort);
590 }; // class Signature
591 
592 }
593 
594 #endif // __Signature__
595