#ifndef __ClauseCodeTree__
#define __ClauseCodeTree__
#include "Forwards.hpp"
#include "Lib/Allocator.hpp"
#include "Lib/DArray.hpp"
#include "Lib/Stack.hpp"
#include "CodeTree.hpp"
namespace Indexing {
using namespace Lib;
using namespace Kernel;
class ClauseCodeTree : public CodeTree
{
protected:
static void onCodeOpDestroying(CodeOp* op);
public:
ClauseCodeTree();
void insert(Clause* cl);
void remove(Clause* cl);
private:
struct InitialLiteralOrderingComparator;
void optimizeLiteralOrder(DArray<Literal*>& lits);
void evalSharing(Literal* lit, CodeOp* startOp, size_t& sharedLen, size_t& unsharedLen, CodeOp*& nextOp);
static void matchCode(CodeStack& code, CodeOp* startOp, size_t& matchedCnt, CodeOp*& nextOp);
bool removeOneOfAlternatives(CodeOp* op, Clause* cl, Stack<CodeOp*>* firstsInBlocks);
struct RemovingLiteralMatcher
: public RemovingMatcher<false>
{
void init(CodeOp* entry_, LitInfo* linfos_, size_t linfoCnt_,
ClauseCodeTree* tree_, Stack<CodeOp*>* firstsInBlocks_);
USE_ALLOCATOR(RemovingLiteralMatcher);
};
struct LiteralMatcher
: public Matcher
{
void init(CodeTree* tree, CodeOp* entry_, LitInfo* linfos_, size_t linfoCnt_, bool seekOnlySuccess=false);
bool next();
bool doEagerMatching();
inline bool eagerlyMatched() const { return _eagerlyMatched; }
inline ILStruct* getILS() { ASS(matched()); return op->getILS(); }
USE_ALLOCATOR(LiteralMatcher);
private:
bool _eagerlyMatched;
Stack<CodeOp*> eagerResults;
void recordMatch();
};
public:
struct ClauseMatcher
{
void init(ClauseCodeTree* tree_, Clause* query_, bool sres_);
void reset();
bool keepRecycled() const { return lInfos.keepRecycled(); }
Clause* next(int& resolvedQueryLit);
bool matched() { return lms.isNonEmpty() && lms.top()->success(); }
CodeOp* getSuccessOp() { ASS(matched()); return lms.top()->op; }
USE_ALLOCATOR(ClauseMatcher);
private:
void enterLiteral(CodeOp* entry, bool seekOnlySuccess);
void leaveLiteral();
bool canEnterLiteral(CodeOp* op);
bool checkCandidate(Clause* cl, int& resolvedQueryLit);
bool matchGlobalVars(int& resolvedQueryLit);
bool compatible(ILStruct* bi, MatchInfo* bq, ILStruct* ni, MatchInfo* nq);
bool existsCompatibleMatch(ILStruct* si, MatchInfo* sq, ILStruct* oi);
Clause* query;
ClauseCodeTree* tree;
bool sres;
static const unsigned sresNoLiteral=static_cast<unsigned>(-1);
unsigned sresLiteral;
DArray<LitInfo> lInfos;
Stack<Recycled<LiteralMatcher, NoReset>> lms;
};
private:
#if VDEBUG
unsigned _clauseMatcherCounter;
#endif
};
};
#endif