#ifndef __OperatorType__
#define __OperatorType__
#include "Forwards.hpp"
#include "Lib/Set.hpp"
#include "Lib/Vector.hpp"
#include "Term.hpp"
namespace Kernel {
class OperatorType
{
public:
class TypeHash {
public:
static bool equals(OperatorType* t1, OperatorType* t2)
{ return (*t1) == (*t2); }
static unsigned hash(OperatorType* ot)
{
OperatorKey& key = *ot->key();
unsigned typeArgsArity = ot->numTypeArguments();
return HashUtils::combine(
DefaultHash::hash(key),
DefaultHash::hash(typeArgsArity)
);
}
};
private:
typedef Vector<TermList> OperatorKey; OperatorKey* _key;
unsigned _typeArgsArity;
OperatorType(OperatorKey* key, unsigned vLength) : _key(key), _typeArgsArity(vLength) {}
static OperatorKey* setupKey(unsigned arity, const TermList* sorts);
static OperatorKey* setupKey(std::initializer_list<TermList> sorts);
static OperatorKey* setupKeyUniformRange(unsigned arity, TermList argsSort);
typedef Set<OperatorType*,TypeHash> OperatorTypes;
static OperatorTypes& operatorTypes();
static OperatorType* getTypeFromKey(OperatorKey* key, unsigned taArity);
public:
~OperatorType() { _key->deallocate(); }
inline bool operator==(const OperatorType& t) const
{ return *_key==*t._key &&
_typeArgsArity==t._typeArgsArity; }
static OperatorType* getPredicateType(unsigned arity, const TermList* sorts=0, unsigned taArity = 0) {
OperatorKey* key = setupKey(arity,sorts);
(*key)[arity] = TermList::empty();
return getTypeFromKey(key,taArity);
}
static OperatorType* getPredicateType(std::initializer_list<TermList> sorts, unsigned taArity = 0) {
OperatorKey* key = setupKey(sorts);
(*key)[sorts.size()] = TermList::empty();
return getTypeFromKey(key,taArity);
}
static OperatorType* getPredicateTypeUniformRange(unsigned arity, TermList argsSort, unsigned taArity = 0) {
OperatorKey* key = setupKeyUniformRange(arity,argsSort);
(*key)[arity] = TermList::empty();
return getTypeFromKey(key, taArity);
}
static OperatorType* getFunctionType(unsigned arity, const TermList* sorts, TermList resultSort, unsigned taArity = 0) {
OperatorKey* key = setupKey(arity,sorts);
(*key)[arity] = resultSort;
return getTypeFromKey(key, taArity);
}
static OperatorType* getFunctionType(std::initializer_list<TermList> sorts, TermList resultSort, unsigned taArity = 0) {
OperatorKey* key = setupKey(sorts);
(*key)[sorts.size()] = resultSort;
return getTypeFromKey(key,taArity);
}
static OperatorType* getFunctionTypeUniformRange(unsigned arity, TermList argsSort, TermList resultSort, unsigned taArity = 0) {
OperatorKey* key = setupKeyUniformRange(arity,argsSort);
(*key)[arity] = resultSort;
return getTypeFromKey(key,taArity);
}
static OperatorType* getConstantsType(TermList resultSort, unsigned taArity = 0) {
return getFunctionType(0,nullptr,resultSort, taArity);
}
static OperatorType* getTypeConType(unsigned arity) {
return getFunctionTypeUniformRange(arity, AtomicSort::superSort(), AtomicSort::superSort());
}
OperatorKey* key() const { return _key; }
unsigned numTypeArguments() const { return _typeArgsArity; }
unsigned arity() const { return _typeArgsArity + _key->length()-1; }
TermList quantifiedVar(unsigned idx) const
{
ASS(idx < _typeArgsArity);
return TermList(idx, false);
}
TermList arg(unsigned idx) const
{
if(idx < _typeArgsArity){
return AtomicSort::superSort();
}
return (*_key)[idx - _typeArgsArity];
}
bool isPredicateType() const { return (*_key)[arity() - numTypeArguments()].isEmpty(); };
bool isFunctionType() const { return !(*_key)[arity() - numTypeArguments()].isEmpty(); };
TermList result() const {
return (*_key)[arity() - numTypeArguments()];
}
friend std::ostream& operator<<(std::ostream& out, OperatorType const& self)
{ return out << self.toString(); }
std::string toString() const;
bool isSingleSortType(TermList sort) const;
bool isAllDefault() const { return isSingleSortType(AtomicSort::defaultSort()); }
private:
std::string argsToString() const;
};
}
#endif