#ifndef __Clause__
#define __Clause__
#include <iosfwd>
#include "Debug/Assertion.hpp"
#include "Forwards.hpp"
#include "Lib/InverseLookup.hpp"
#include "Lib/Metaiterators.hpp"
#include "Lib/Reflection.hpp"
#include "Lib/Stack.hpp"
#include "Unit.hpp"
#include "Kernel/Inference.hpp"
namespace Kernel {
using namespace Lib;
class Clause
: public Unit
{
private:
~Clause() { ASSERTION_VIOLATION; }
void operator delete(void* ptr) { ASSERTION_VIOLATION; }
template<class VarIt>
void collectVars2(DHSet<unsigned>& acc);
public:
DECL_ELEMENT_TYPE(Literal*);
enum Store {
PASSIVE = 0u,
ACTIVE = 1u,
UNPROCESSED = 2u,
NONE = 3u,
SELECTED = 4u
};
friend std::ostream& operator<<(std::ostream& out, Store const& self)
{ switch (self) {
case Clause::PASSIVE: return out << "passive";
case Clause::ACTIVE: return out << "active";
case Clause::UNPROCESSED: return out << "unprocessed";
case Clause::NONE: return out << "none";
case Clause::SELECTED: return out << "selected";
} ASSERTION_VIOLATION }
private:
Clause(Literal* const* lits, unsigned length, Inference inf);
void* operator new(size_t,unsigned length);
public:
void operator delete(void* ptr,unsigned length);
static Clause* fromArray(Literal*const* lits, unsigned size, Inference inf)
{ return new(size) Clause(lits, size, std::move(inf)); }
static Clause* fromLiterals(std::initializer_list<Literal*> lits, Inference inf)
{ return fromArray(std::data(lits), lits.size(), std::move(inf)); }
static Clause* empty(Inference inf)
{ return fromLiterals({}, inf); }
static Clause* fromStack(const Stack<Literal*>& lits, Inference inf)
{ return new(lits.size()) Clause(lits.begin(), lits.size(), std::move(inf)); }
template<class Iter>
static Clause* fromIterator(Iter litit, const Inference& inf)
{
static Stack<Literal*> st;
st.reset();
st.loadFromIterator(std::move(litit));
return fromStack(st, inf);
}
static Clause* fromClause(Clause* c);
Literal*& operator[] (int n)
{ return _literals[n]; }
Literal*const& operator[] (int n) const
{ return _literals[n]; }
unsigned length() const { return _length; }
unsigned size() const { return _length; }
Literal** literals() { return _literals; }
Literal **begin() { return _literals; }
Literal *const *begin() const { return _literals; }
Literal **end() { return _literals + _length; }
Literal *const *end() const { return _literals + _length; }
bool isEmpty() const { return _length == 0; }
void destroy();
void destroyExceptInferenceObject();
std::string literalsOnlyToString() const;
std::string toString() const;
std::string toTPTPString() const;
std::string toNiceString() const;
friend std::ostream& operator<<(std::ostream& out, Clause const& self);
Store store() const { return _store; }
void setStore(Store s);
unsigned age() const { return inference().age(); }
void setAge(unsigned a) { inference().setAge(a); }
unsigned numSelected() const { return _numSelected; }
void setSelected(unsigned s)
{
ASS(s >= 0);
ASS(s <= _length);
_numSelected = s;
notifyLiteralReorder();
}
unsigned weight() const
{
if(!_weight) {
_weight = computeWeight();
}
return _weight;
}
unsigned computeWeight() const;
unsigned weightForClauseSelection(const Shell::Options& opt)
{
if(!_weightForClauseSelection) {
_weightForClauseSelection = computeWeightForClauseSelection(opt);
}
return _weightForClauseSelection;
}
unsigned computeWeightForClauseSelection(const Shell::Options& opt) const;
static unsigned computeWeightForClauseSelection(unsigned w, unsigned splitWeight, unsigned numeralWeight, bool derivedFromGoal, const Shell::Options& opt);
Color color() const
{
if(static_cast<Color>(_color)==COLOR_INVALID) {
computeColor();
}
return static_cast<Color>(_color);
}
void computeColor() const;
void updateColor(Color c) {
_color = c;
}
bool isExtensionality() const { return _extensionality; }
bool isTaggedExtensionality() const { return _extensionalityTag; }
void setExtensionality(bool e) { _extensionality = e; }
bool isComponent() const { return _component; }
void setComponent(bool c) { _component = c; }
bool skip() const;
unsigned getLiteralPosition(Literal* lit);
void notifyLiteralReorder();
bool shouldBeDestroyed();
void destroyIfUnnecessary();
void incRefCnt() { _refCnt++; }
void decRefCnt()
{
ASS_G(_refCnt,0);
_refCnt--;
destroyIfUnnecessary();
}
unsigned getReductionTimestamp() { return _reductionTimestamp; }
void invalidateMyReductionRecords()
{
_reductionTimestamp++;
if(_reductionTimestamp==0) {
INVALID_OPERATION("Clause reduction timestamp overflow!");
}
}
bool validReductionRecord(unsigned savedTimestamp) {
return savedTimestamp == _reductionTimestamp;
}
auto getSelectedLiteralIterator() { return arrayIter(*this,numSelected()); }
auto iterLits() { return arrayIter(*this,size()); }
auto iterLits() const { return arrayIter(*this,size()); }
auto getLiteralIterator() { return arrayIter(*this,size()); }
bool isGround();
bool isPropositional();
bool isHorn();
VirtualIterator<unsigned> getVariableIterator() const;
bool contains(Literal* lit);
#if VDEBUG
void assertValid();
#endif
SplitSet* splits() const { return _inference.splits(); }
bool noSplits() const;
void setSplits(SplitSet* splits) {
ASS(_weight == 0);
_inference.setSplits(splits);
}
int getNumActiveSplits() const { return _numActiveSplits; }
void setNumActiveSplits(int newVal) { _numActiveSplits = newVal; }
void incNumActiveSplits() { _numActiveSplits++; }
void decNumActiveSplits() { _numActiveSplits--; }
VirtualIterator<std::string> toSimpleClauseStrings();
void setAux()
{
ASS(_auxInUse);
_auxTimestamp=_auxCurrTimestamp;
}
void setAux(void* ptr)
{
ASS(_auxInUse);
_auxTimestamp=_auxCurrTimestamp;
_auxData=ptr;
}
template<typename T>
bool tryGetAux(T*& ptr)
{
ASS(_auxInUse);
if(_auxTimestamp==_auxCurrTimestamp) {
ptr=static_cast<T*>(_auxData);
return true;
}
return false;
}
template<typename T>
T* getAux()
{
ASS(_auxInUse);
ASS(_auxTimestamp==_auxCurrTimestamp);
return static_cast<T*>(_auxData);
}
bool hasAux()
{
return _auxTimestamp==_auxCurrTimestamp;
}
static void requestAux()
{
#if VDEBUG
ASS(!_auxInUse);
_auxInUse=true;
#endif
_auxCurrTimestamp++;
if(_auxCurrTimestamp==0) {
INVALID_OPERATION("Auxiliary clause value timestamp overflow!");
}
}
static void releaseAux()
{
#if VDEBUG
ASS(_auxInUse);
_auxInUse=false;
#endif
}
unsigned splitWeight() const;
unsigned getNumeralWeight() const;
void collectVars(DHSet<unsigned>& acc);
unsigned varCnt();
unsigned maxVar();
unsigned numPositiveLiterals();
Literal* getAnswerLiteral();
bool hasAnswerLiteral() {
return getAnswerLiteral() != nullptr;
}
protected:
unsigned _length : 20;
mutable unsigned _color : 2;
unsigned _extensionality : 1;
unsigned _extensionalityTag : 1;
unsigned _component : 1;
Store _store : 3;
unsigned _numSelected : 20;
mutable unsigned _weight;
unsigned _weightForClauseSelection;
unsigned _refCnt;
unsigned _reductionTimestamp;
InverseLookup<Literal>* _literalPositions;
int _numActiveSplits;
size_t _auxTimestamp;
void* _auxData;
static size_t _auxCurrTimestamp;
#if VDEBUG
static bool _auxInUse;
#endif
Literal* _literals[1];
};
std::ostream& operator<<(std::ostream& out, Clause::Store const& clause);
}
#endif