From 3a2dacba0ab802166ee5b0a7efd5ec0d505748f3 Mon Sep 17 00:00:00 2001 From: Marton Hajdu Date: Wed, 26 Jun 2024 14:16:17 +0200 Subject: [PATCH 01/19] Use KBO state in KBOComparator instead of computing weight and variable counts again --- Kernel/KBO.cpp | 76 --------------------------------------- Kernel/KBO.hpp | 78 +++++++++++++++++++++++++++++++++++++++- Kernel/KBOComparator.cpp | 35 ++++-------------- Kernel/KBOComparator.hpp | 3 -- 4 files changed, 83 insertions(+), 109 deletions(-) diff --git a/Kernel/KBO.cpp b/Kernel/KBO.cpp index f0aa1e26e..2aa4258fb 100644 --- a/Kernel/KBO.cpp +++ b/Kernel/KBO.cpp @@ -38,82 +38,6 @@ using namespace std; using namespace Lib; using namespace Shell; - -/** - * Class to represent the current state of the KBO comparison. - * Based on Bernd Loechner's "Things to Know when Implementing KBO" - * (https://doi.org/10.1007/s10817-006-9031-4) - * @since 30/04/2008 flight Brussels-Tel Aviv - */ -class KBO::State -{ -public: - /** Initialise the state */ - State(KBO* kbo) - : _kbo(*kbo) - {} - - void init() - { - _weightDiff=0; - _posNum=0; - _negNum=0; - _lexResult=EQUAL; - _varDiffs.reset(); - } - - /** - * Lexicographic traversal of two terms with same top symbol, - * i.e. traversing their symbols in lockstep, as descibed in - * the Loechner et al. paper above. It performs a bidirectional - * comparison between the two terms, i.e. we can get any value - * of @b Result. - */ - Result traverseLexBidir(AppliedTerm t1, AppliedTerm t2); - /** - * Optimised, unidirectional version of @b traverseLexBidir - * where we only care about @b GREATER and @b EQUAL, otherwise - * it returns as early as possible with @b INCOMPARABLE. - */ - Result traverseLexUnidir(AppliedTerm t1, AppliedTerm t2); - /** - * Performs a non-lexicographic (i.e. non-lockstep) traversal - * of two terms in case their top symbols are not the same. - */ - template - Result traverseNonLex(AppliedTerm t1, AppliedTerm t2); - - template void traverse(AppliedTerm tt); - - Result result(AppliedTerm t1, AppliedTerm t2); -protected: - template void recordVariable(unsigned var); - - bool checkVars() const { return _negNum <= 0; } - Result innerResult(TermList t1, TermList t2); - Result applyVariableCondition(Result res) - { - if(_posNum>0 && (res==LESS || res==LESS_EQ || res==EQUAL)) { - res=INCOMPARABLE; - } else if(_negNum>0 && (res==GREATER || res==GREATER_EQ || res==EQUAL)) { - res=INCOMPARABLE; - } - return res; - } - - int _weightDiff; - /** The variable counters */ - DHMap _varDiffs; - /** Number of variables, that occur more times in the first literal */ - int _posNum; - /** Number of variables, that occur more times in the second literal */ - int _negNum; - /** First comparison result */ - Result _lexResult; - /** The ordering used */ - KBO& _kbo; -}; // class KBO::State - /** * Return result of comparison between @b l1 and @b l2 under * an assumption, that @b traverse method have been called diff --git a/Kernel/KBO.hpp b/Kernel/KBO.hpp index d6dd15c1a..cb892e731 100644 --- a/Kernel/KBO.hpp +++ b/Kernel/KBO.hpp @@ -166,7 +166,6 @@ class KBO Result comparePredicates(Literal* l1, Literal* l2) const override; - class State; friend class KBOComparator; // int functionSymbolWeight(unsigned fun) const; @@ -186,6 +185,83 @@ class KBO template void showConcrete_(std::ostream&) const; + /** + * Class to represent the current state of the KBO comparison. + * Based on Bernd Loechner's "Things to Know when Implementing KBO" + * (https://doi.org/10.1007/s10817-006-9031-4) + * @since 30/04/2008 flight Brussels-Tel Aviv + */ + class State + { + public: + /** Initialise the state */ + State(KBO* kbo) + : _kbo(*kbo) + {} + + void init() + { + _weightDiff=0; + _posNum=0; + _negNum=0; + _lexResult=EQUAL; + _varDiffs.reset(); + } + + /** + * Lexicographic traversal of two terms with same top symbol, + * i.e. traversing their symbols in lockstep, as descibed in + * the Loechner et al. paper above. It performs a bidirectional + * comparison between the two terms, i.e. we can get any value + * of @b Result. + */ + Result traverseLexBidir(AppliedTerm t1, AppliedTerm t2); + /** + * Optimised, unidirectional version of @b traverseLexBidir + * where we only care about @b GREATER and @b EQUAL, otherwise + * it returns as early as possible with @b INCOMPARABLE. + */ + Result traverseLexUnidir(AppliedTerm t1, AppliedTerm t2); + /** + * Performs a non-lexicographic (i.e. non-lockstep) traversal + * of two terms in case their top symbols are not the same. + */ + template + Result traverseNonLex(AppliedTerm t1, AppliedTerm t2); + + template void traverse(AppliedTerm tt); + + Result result(AppliedTerm t1, AppliedTerm t2); + protected: + template void recordVariable(unsigned var); + + bool checkVars() const { return _negNum <= 0; } + Result innerResult(TermList t1, TermList t2); + Result applyVariableCondition(Result res) + { + if(_posNum>0 && (res==LESS || res==LESS_EQ || res==EQUAL)) { + res=INCOMPARABLE; + } else if(_negNum>0 && (res==GREATER || res==GREATER_EQ || res==EQUAL)) { + res=INCOMPARABLE; + } + return res; + } + + friend class KBOComparator; + + int _weightDiff; + /** The variable counters */ + DHMap _varDiffs; + /** Number of variables, that occur more times in the first literal */ + int _posNum; + /** Number of variables, that occur more times in the second literal */ + int _negNum; + /** First comparison result */ + Result _lexResult; + /** The ordering used */ + KBO& _kbo; + }; // class KBO::State + /** * State used for comparing terms and literals */ diff --git a/Kernel/KBOComparator.cpp b/Kernel/KBOComparator.cpp index 12c87e3bf..b2e13e370 100644 --- a/Kernel/KBOComparator.cpp +++ b/Kernel/KBOComparator.cpp @@ -83,14 +83,14 @@ KBOComparator::KBOComparator(TermList tl1, TermList tl2, const KBO& kbo) // if both are proper terms, we calculate // weight and variable balances first - DHMap vars; - int w = 0; - countSymbols(kbo, vars, w, lhs, 1); - countSymbols(kbo, vars, w, rhs, -1); // we only care about the non-zero weights and counts bool varInbalance = false; - DHMap::Iterator vit(vars); + // TODO _kbo.state could be nulled out until this + // to make sure no one overwrites the values + auto state = _kbo._state; + auto w = _kbo._state->_weightDiff; + decltype(state->_varDiffs)::Iterator vit(state->_varDiffs); Stack> nonzeros; while (vit.hasNext()) { unsigned v; @@ -98,6 +98,7 @@ KBOComparator::KBOComparator(TermList tl1, TermList tl2, const KBO& kbo) vit.next(v,cnt); if (cnt!=0) { nonzeros.push(make_pair(v,cnt)); + w-=cnt; // we have to remove the variable weights from w } if (cnt<0) { varInbalance = true; @@ -246,30 +247,6 @@ bool KBOComparator::check(const SubstApplicator* applicator) const return false; } - -void KBOComparator::countSymbols(const KBO& kbo, DHMap& vars, int& w, TermList t, int coeff) -{ - if (t.isVar()) { - int* vcnt; - vars.getValuePtr(t.var(), vcnt, 0); - (*vcnt) += coeff; - return; - } - - w += coeff*kbo.symbolWeight(t.term()); - SubtermIterator sti(t.term()); - while (sti.hasNext()) { - auto st = sti.next(); - if (st.isVar()) { - int* vcnt; - vars.getValuePtr(st.var(), vcnt, 0); - (*vcnt) += coeff; - } else { - w += coeff*kbo.symbolWeight(st.term()); - } - } -} - vstring KBOComparator::toString() const { vstringstream str; diff --git a/Kernel/KBOComparator.hpp b/Kernel/KBOComparator.hpp index a75f8819a..4281863a1 100644 --- a/Kernel/KBOComparator.hpp +++ b/Kernel/KBOComparator.hpp @@ -41,9 +41,6 @@ class KBOComparator vstring toString() const override; private: - // TODO this could be done with KBO::State - static void countSymbols(const KBO& kbo, DHMap& vars, int& w, TermList t, int coeff); - enum InstructionTag { DATA = 0u, WEIGHT = 1u, From 7a48a0b0b9e6a6ceeedd26ace9237c3cdd2aa29a Mon Sep 17 00:00:00 2001 From: Marton Hajdu Date: Wed, 26 Jun 2024 17:54:49 +0200 Subject: [PATCH 02/19] Perform instance redundancy check at the beginning of superposition --- Inferences/Superposition.cpp | 24 +++++----- Shell/InstanceRedundancyHandler.cpp | 71 ++++++++++++++++++++++++----- Shell/InstanceRedundancyHandler.hpp | 5 +- 3 files changed, 76 insertions(+), 24 deletions(-) diff --git a/Inferences/Superposition.cpp b/Inferences/Superposition.cpp index 1503d8b74..eaa49f3d2 100644 --- a/Inferences/Superposition.cpp +++ b/Inferences/Superposition.cpp @@ -350,20 +350,17 @@ Clause* Superposition::performSuperposition( } } + if (!_instanceRedundancyHandler.checkSuperposition(eqClause, rwClause, eqIsResult, subst.ptr())) { + return 0; + } + const Ordering& ordering = _salg->getOrdering(); - TermList eqLHSS = subst->apply(eqLHS, eqIsResult); TermList tgtTermS = subst->apply(tgtTerm, eqIsResult); Literal* rwLitS = subst->apply(rwLit, !eqIsResult); TermList rwTermS = subst->apply(rwTerm, !eqIsResult); -#if VDEBUG - if(!unifier->usesUwa()){ - ASS_EQ(rwTermS,eqLHSS); - } -#endif - //cout << "Check ordering on " << tgtTermS.toString() << " and " << rwTermS.toString() << endl; //check that we're not rewriting smaller subterm with larger @@ -388,6 +385,9 @@ Clause* Superposition::performSuperposition( } } + _instanceRedundancyHandler.insertSuperposition( + eqClause, rwClause, rwTermS, tgtTermS, eqLHS, rwLitS, comp, eqIsResult, subst.ptr()); + Literal* tgtLitS = EqHelper::replace(rwLitS,rwTermS,tgtTermS); static bool doSimS = getOptions().simulatenousSuperposition(); @@ -397,11 +397,13 @@ Clause* Superposition::performSuperposition( return 0; } - if (!_instanceRedundancyHandler.handleSuperposition( - eqClause, rwClause, rwTermS, tgtTermS, eqLHS, rwLitS, comp, eqIsResult, subst.ptr())) - { - return 0; + TermList eqLHSS = subst->apply(eqLHS, eqIsResult); + +#if VDEBUG + if(!unifier->usesUwa()){ + ASS_EQ(rwTermS,eqLHSS); } +#endif Recycled> res; res->reserve(rwLength + eqLength - 1 + unifier->maxNumberOfConstraints()); diff --git a/Shell/InstanceRedundancyHandler.cpp b/Shell/InstanceRedundancyHandler.cpp index abd52ae68..de70d4b4f 100644 --- a/Shell/InstanceRedundancyHandler.cpp +++ b/Shell/InstanceRedundancyHandler.cpp @@ -41,6 +41,38 @@ class InstanceRedundancyHandler::SubstitutionCoverTree } } + bool check(const Ordering* ord, ResultSubstitution* subst, bool result) + { + if (_varSorts.isEmpty()) { + return true; + } + auto ts = getInstances([subst,result](unsigned v) { return subst->applyTo(TermList::var(v),result); }); + return !check(ts, ord); + } + + void insert(const Ordering* ord, ResultSubstitution* subst, bool result, Term* lhs=nullptr, Term* rhs=nullptr) + { + auto ts = getInstances([subst,result](unsigned v) { return subst->applyTo(TermList::var(v),result); }); + auto ld = new LeafData(); + if (lhs) { + ASS(rhs); + ASS(lhs->containsAllVariablesOf(rhs)); + Renaming r; + // normalize lhs and rhs, the same way as + // terms from ts are normalized upon insertion + for (const auto t : ts) { + r.normalizeVariables(t); + } + ld->lhs = r.apply(lhs); + ld->rhs = r.apply(rhs); + } else { + ASS(!rhs); + ld->lhs = nullptr; + ld->rhs = nullptr; + } + insert(ts,ld); + } + bool checkAndInsert(const Ordering* ord, ResultSubstitution* subst, bool result, bool doInsert=false, Term* lhs=nullptr, Term* rhs=nullptr) { if (_varSorts.isEmpty()) { @@ -209,20 +241,35 @@ InstanceRedundancyHandler::SubstitutionCoverTree** InstanceRedundancyHandler::ge return ptr; } -bool InstanceRedundancyHandler::handleSuperposition(Clause* eqClause, Clause* rwClause, - TermList rwTermS, TermList tgtTermS, TermList eqLHS, Literal* rwLitS, Ordering::Result eqComp, - bool eqIsResult, ResultSubstitution* subs) const +bool InstanceRedundancyHandler::checkSuperposition(Clause* eqClause, Clause* rwClause, bool eqIsResult, ResultSubstitution* subs) const { if (_optVal==Options::InstanceRedundancyCheck::OFF) { return true; } auto eqClDataPtr = getDataPtr(eqClause, /*doAllocate=*/false); - if (eqClDataPtr && !(*eqClDataPtr)->checkAndInsert(_ord, subs, eqIsResult, /*doInsert=*/false)) { + if (eqClDataPtr && !(*eqClDataPtr)->check(_ord, subs, eqIsResult)) { + env.statistics->skippedSuperposition++; + return false; + } + + auto rwClDataPtr = getDataPtr(rwClause, /*doAllocate=*/false); + if (rwClDataPtr && !(*rwClDataPtr)->check(_ord, subs, !eqIsResult)) { env.statistics->skippedSuperposition++; return false; } + return true; +} + +void InstanceRedundancyHandler::insertSuperposition(Clause* eqClause, Clause* rwClause, + TermList rwTermS, TermList tgtTermS, TermList eqLHS, Literal* rwLitS, Ordering::Result eqComp, + bool eqIsResult, ResultSubstitution* subs) const +{ + if (_optVal==Options::InstanceRedundancyCheck::OFF) { + return; + } + struct Applicator : SubstApplicator { Applicator(ResultSubstitution* subst, bool result) : subst(subst) {} TermList operator()(unsigned v) const override { @@ -240,16 +287,16 @@ bool InstanceRedundancyHandler::handleSuperposition(Clause* eqClause, Clause* rw // TODO for rwClause->length()!=1 the function isPremiseRedundant does not work yet (rwClause->length()==1 && _demodulationHelper.isPremiseRedundant(rwClause, rwLitS, rwTermS, tgtTermS, eqLHS, &appl))); + if (!doInsert) { + return; + } + bool incompInserted = doInsert && eqComp != Ordering::LESS; - auto rwClDataPtr = getDataPtr(rwClause, /*doAllocate=*/doInsert); + auto rwClDataPtr = getDataPtr(rwClause, /*doAllocate=*/true); - if (rwClDataPtr && !(*rwClDataPtr)->checkAndInsert(_ord, subs, !eqIsResult, doInsert, - incompInserted ? rwTermS.term() : nullptr, incompInserted ? tgtTermS.term() : nullptr)) - { - env.statistics->skippedSuperposition++; - return false; - } - return true; + (*rwClDataPtr)->insert(_ord, subs, !eqIsResult, + incompInserted ? rwTermS.term() : nullptr, + incompInserted ? tgtTermS.term() : nullptr); } bool InstanceRedundancyHandler::handleResolution(Clause* queryCl, Literal* queryLit, diff --git a/Shell/InstanceRedundancyHandler.hpp b/Shell/InstanceRedundancyHandler.hpp index 1ce7ea796..6c89e331c 100644 --- a/Shell/InstanceRedundancyHandler.hpp +++ b/Shell/InstanceRedundancyHandler.hpp @@ -36,7 +36,10 @@ class InstanceRedundancyHandler : _optVal(opts.instanceRedundancyCheck()), _ord(ord), _demodulationHelper(opts,ord) {} /** Returns false if superposition should be skipped. */ - bool handleSuperposition( + bool checkSuperposition( + Clause* eqClause, Clause* rwClause, bool eqIsResult, ResultSubstitution* subs) const; + + void insertSuperposition( Clause* eqClause, Clause* rwClause, TermList rwTermS, TermList tgtTermS, TermList eqLHS, Literal* rwLitS, Ordering::Result eqComp, bool eqIsResult, ResultSubstitution* subs) const; From 2866dde4f349ed70a1eea993be93e56ee9e439a4 Mon Sep 17 00:00:00 2001 From: Marton Hajdu Date: Wed, 17 Jul 2024 09:15:02 +0200 Subject: [PATCH 03/19] Add leaf printing functionality to code trees --- Indexing/CodeTree.cpp | 14 ++++++++++++-- Indexing/CodeTree.hpp | 7 ++++++- Indexing/TermCodeTree.cpp | 5 +++++ Shell/InstanceRedundancyHandler.cpp | 14 ++++++++++++++ 4 files changed, 37 insertions(+), 3 deletions(-) diff --git a/Indexing/CodeTree.cpp b/Indexing/CodeTree.cpp index 31ab8f8da..5662ad5cb 100644 --- a/Indexing/CodeTree.cpp +++ b/Indexing/CodeTree.cpp @@ -555,6 +555,9 @@ inline bool CodeTree::BaseMatcher::doCheckGroundTerm() CodeTree::CodeTree() : _onCodeOpDestroying(0), _curTimeStamp(0), _maxVarCnt(1), _entryPoint(0) +#if LOG_LEAVES + , _printLeaf(0) +#endif { } @@ -655,11 +658,18 @@ void CodeTree::visitAllOps(Visitor visitor) const std::ostream& operator<<(std::ostream& out, const CodeTree& ct) { - ct.visitAllOps([&out](const CodeTree::CodeOp* op, unsigned depth) { + ct.visitAllOps([&out,&ct](const CodeTree::CodeOp* op, unsigned depth) { for (unsigned i = 0; i < depth; i++) { out << " "; } - out << *op << std::endl; + out << *op; +#if LOG_LEAVES + if (op->isSuccess() && ct._printLeaf) { + out << " "; + ct._printLeaf(out, op); + } +#endif + out << std::endl; }); return out; } diff --git a/Indexing/CodeTree.hpp b/Indexing/CodeTree.hpp index f9afa4233..035df872c 100644 --- a/Indexing/CodeTree.hpp +++ b/Indexing/CodeTree.hpp @@ -36,6 +36,8 @@ //#define LOG_OP(x) std::cout<(); } - template inline T* getSuccessResult() { ASS(isSuccess()); return _data(); } + template inline T* getSuccessResult() const { ASS(isSuccess()); return _data(); } inline ILStruct* getILS() { diff --git a/Indexing/TermCodeTree.cpp b/Indexing/TermCodeTree.cpp index e5f655f5c..878dd864d 100644 --- a/Indexing/TermCodeTree.cpp +++ b/Indexing/TermCodeTree.cpp @@ -45,6 +45,11 @@ TermCodeTree::TermCodeTree() { _clauseCodeTree=false; _onCodeOpDestroying = onCodeOpDestroying; +#if LOG_LEAVES + _printLeaf = [](std::ostream& str, const CodeOp* op) { + str << *op->getSuccessResult(); + }; +#endif } template diff --git a/Shell/InstanceRedundancyHandler.cpp b/Shell/InstanceRedundancyHandler.cpp index de70d4b4f..aa917e70a 100644 --- a/Shell/InstanceRedundancyHandler.cpp +++ b/Shell/InstanceRedundancyHandler.cpp @@ -26,6 +26,8 @@ #include "Statistics.hpp" +using namespace std; + namespace Indexing { @@ -36,6 +38,18 @@ class InstanceRedundancyHandler::SubstitutionCoverTree SubstitutionCoverTree(Clause* cl) : _varSorts() { _clauseCodeTree=false; +#if VDEBUG + _cl = cl; +#endif + +#if LOG_LEAVES + _printLeaf = [](ostream& str, const CodeOp* op) { + auto ld = op->getSuccessResult(); + if (ld->comp) { + str << " " << ld->comp->toString(); + } + }; +#endif for (unsigned i = 0; i < cl->length(); i++) { SortHelper::collectVariableSorts((*cl)[i], _varSorts); } From 09e01a0757e877608e0ecbf5b016a0f7d064f9a8 Mon Sep 17 00:00:00 2001 From: Marton Hajdu Date: Fri, 19 Jul 2024 10:48:50 +0200 Subject: [PATCH 04/19] Templatize InstanceRedundancyHandler (now ConditionalRedundancyHandler); add options for AVATAR and literal conditions --- Forwards.hpp | 1 + Inferences/BinaryResolution.cpp | 42 +++---- Inferences/BinaryResolution.hpp | 15 +-- Inferences/EqualityFactoring.cpp | 13 +-- Inferences/EqualityResolution.cpp | 13 +-- Inferences/Superposition.cpp | 7 +- Inferences/Superposition.hpp | 3 - Kernel/Clause.cpp | 2 +- Saturation/SaturationAlgorithm.cpp | 6 +- Saturation/SaturationAlgorithm.hpp | 2 + Saturation/Splitter.cpp | 2 +- Shell/InstanceRedundancyHandler.cpp | 165 +++++++++++++++++----------- Shell/InstanceRedundancyHandler.hpp | 80 ++++++++------ Shell/Options.cpp | 37 +++++-- Shell/Options.hpp | 16 +-- 15 files changed, 228 insertions(+), 176 deletions(-) diff --git a/Forwards.hpp b/Forwards.hpp index 90bf3b4f2..78cd6e377 100644 --- a/Forwards.hpp +++ b/Forwards.hpp @@ -195,5 +195,6 @@ class Options; class Property; class Statistics; class FunctionDefinitionHandler; +class ConditionalRedundancyHandler; } #endif /* __Forwards__ */ diff --git a/Inferences/BinaryResolution.cpp b/Inferences/BinaryResolution.cpp index 1b60deedb..e52b883b3 100644 --- a/Inferences/BinaryResolution.cpp +++ b/Inferences/BinaryResolution.cpp @@ -76,13 +76,15 @@ void BinaryResolution::detach() * Ordering aftercheck is performed iff ord is not 0, * in which case also ls is assumed to be not 0. */ -template -Clause* BinaryResolution::generateClause(Clause* queryCl, Literal* queryLit, Clause* resultCl, Literal* resultLit, - ResultSubstitutionSP subs, ComputeConstraints computeConstraints, const Options& opts, bool afterCheck, - PassiveClauseContainer* passiveClauseContainer, Ordering* ord, LiteralSelector* ls) +Clause* BinaryResolution::generateClause( + Clause* queryCl, Literal* queryLit, Clause* resultCl, Literal* resultLit, + ResultSubstitutionSP subs, AbstractingUnifier* absUnif) { ASS(resultCl->store()==Clause::ACTIVE);//Added to check that generation only uses active clauses + const auto& opts = getOptions(); + const bool afterCheck = getOptions().literalMaximalityAftercheck() && _salg->getLiteralSelector().isBGComplete(); + if(!ColorHelper::compatible(queryCl->color(),resultCl->color()) ) { env.statistics->inferencesSkippedDueToColors++; if(opts.showBlocked()) { @@ -110,11 +112,12 @@ Clause* BinaryResolution::generateClause(Clause* queryCl, Literal* queryLit, Cla Int::max(queryLit->isPositive() ? queryCl->numPositiveLiterals()-1 : queryCl->numPositiveLiterals(), resultLit->isPositive() ? resultCl->numPositiveLiterals()-1 : resultCl->numPositiveLiterals()); - auto constraints = computeConstraints(); + auto constraints = absUnif->computeConstraintLiterals(); auto nConstraints = constraints->size(); Inference inf(GeneratingInference2(nConstraints == 0 ? InferenceRule::RESOLUTION : InferenceRule::CONSTRAINED_RESOLUTION, queryCl, resultCl)); Inference::Destroyer inf_destroyer(inf); // will call destroy on inf when coming out of scope unless disabled + auto passiveClauseContainer = _salg->getPassiveClauseContainer(); bool needsToFulfilWeightLimit = passiveClauseContainer && !passiveClauseContainer->fulfilsAgeLimit(wlb, numPositiveLiteralsLowerBound, inf) && passiveClauseContainer->weightLimited(); if(needsToFulfilWeightLimit) { @@ -153,6 +156,8 @@ Clause* BinaryResolution::generateClause(Clause* queryCl, Literal* queryLit, Cla queryLitAfter = subs->applyToQuery(queryLit); } + auto& ls = _salg->getLiteralSelector(); + unsigned next = 0; for(Literal* c : *constraints){ (*res)[next++] = c; @@ -173,10 +178,10 @@ Clause* BinaryResolution::generateClause(Clause* queryCl, Literal* queryLit, Cla if (queryLitAfter && i < queryCl->numSelected()) { TIME_TRACE(TimeTrace::LITERAL_ORDER_AFTERCHECK); - Ordering::Result o = ord->compare(newLit,queryLitAfter); + Ordering::Result o = _salg->getOrdering().compare(newLit,queryLitAfter); if (o == Ordering::GREATER || - (ls->isPositiveForSelection(newLit) // strict maximimality for positive literals + (ls.isPositiveForSelection(newLit) // strict maximimality for positive literals && (o == Ordering::GREATER_EQ || o == Ordering::EQUAL))) { // where is GREATER_EQ ever coming from? env.statistics->inferencesBlockedForOrderingAftercheck++; res->destroy(); @@ -211,10 +216,10 @@ Clause* BinaryResolution::generateClause(Clause* queryCl, Literal* queryLit, Cla if (qrLitAfter && i < resultCl->numSelected()) { TIME_TRACE(TimeTrace::LITERAL_ORDER_AFTERCHECK); - Ordering::Result o = ord->compare(newLit,qrLitAfter); + Ordering::Result o = _salg->getOrdering().compare(newLit,qrLitAfter); if (o == Ordering::GREATER || - (ls->isPositiveForSelection(newLit) // strict maximimality for positive literals + (ls.isPositiveForSelection(newLit) // strict maximimality for positive literals && (o == Ordering::GREATER_EQ || o == Ordering::EQUAL))) { // where is GREATER_EQ ever coming from? env.statistics->inferencesBlockedForOrderingAftercheck++; res->destroy(); @@ -227,7 +232,7 @@ Clause* BinaryResolution::generateClause(Clause* queryCl, Literal* queryLit, Cla } } - if (!InstanceRedundancyHandler::handleResolution(queryCl, queryLit, resultCl, resultLit, subs.ptr(), opts, ord)) { + if (!_salg->condRedHandler()->handleResolution(queryCl, queryLit, resultCl, resultLit, subs.ptr())) { return 0; } @@ -249,14 +254,6 @@ Clause* BinaryResolution::generateClause(Clause* queryCl, Literal* queryLit, Cla return res; } -Clause* BinaryResolution::generateClause(Clause* queryCl, Literal* queryLit, Clause* resultCl, Literal* resultLit, - ResultSubstitutionSP subs, const Options& opts) -{ - return BinaryResolution::generateClause(queryCl, queryLit, resultCl, resultLit, subs, - /* computeConstraints */ []() { return recycledStack(); }, - opts); -} - ClauseIterator BinaryResolution::generateClauses(Clause* premise) { @@ -271,15 +268,10 @@ ClauseIterator BinaryResolution::generateClauses(Clause* premise) .map([this,lit,premise](auto qr) { // perform binary resolution on query results auto subs = ResultSubstitution::fromSubstitution(&qr.unifier->subs(), QUERY_BANK, RESULT_BANK); - bool doAfterCheck = getOptions().literalMaximalityAftercheck() && _salg->getLiteralSelector().isBGComplete(); - return BinaryResolution::generateClause(premise, lit, qr.data->clause, qr.data->literal, subs, - [&](){ return qr.unifier->computeConstraintLiterals(); }, - this->getOptions(), doAfterCheck, _salg->getPassiveClauseContainer(), - &_salg->getOrdering(), &_salg->getLiteralSelector()); - + return BinaryResolution::generateClause(premise, lit, qr.data->clause, qr.data->literal, subs, qr.unifier); }); }) - .filter([](auto c) { return c != nullptr; }) + .filter(NonzeroFn()) )); } diff --git a/Inferences/BinaryResolution.hpp b/Inferences/BinaryResolution.hpp index 58e0ca926..e5b095048 100644 --- a/Inferences/BinaryResolution.hpp +++ b/Inferences/BinaryResolution.hpp @@ -40,21 +40,12 @@ class BinaryResolution void attach(SaturationAlgorithm* salg); void detach(); - static Clause* generateClause(Clause* queryCl, Literal* queryLit, - Clause* resultCl, Literal* resultLit, - ResultSubstitutionSP subs, const Options& opts); - - template - static Clause* generateClause(Clause* queryCl, Literal* queryLit, - Clause* resultCl, Literal* resultLit, - ResultSubstitutionSP subs, ComputeConstraints constraints, const Options& opts, - bool afterCheck = false, PassiveClauseContainer* passive=0, Ordering* ord=0, LiteralSelector* ls = 0); - ClauseIterator generateClauses(Clause* premise); private: - struct UnificationsFn; - struct ResultFn; + Clause* generateClause( + Clause* queryCl, Literal* queryLit, Clause* resultCl, Literal* resultLit, + ResultSubstitutionSP subs, AbstractingUnifier* absUnif); BinaryResolutionIndex* _index; }; diff --git a/Inferences/EqualityFactoring.cpp b/Inferences/EqualityFactoring.cpp index c940468ed..4d35b0bd3 100644 --- a/Inferences/EqualityFactoring.cpp +++ b/Inferences/EqualityFactoring.cpp @@ -92,8 +92,8 @@ struct EqualityFactoring::FactorablePairsFn struct EqualityFactoring::ResultFn { - ResultFn(EqualityFactoring& self, Clause* cl, bool afterCheck, bool instanceRedundancyCheck, Ordering& ordering, bool fixedPointIteration) - : _self(self), _cl(cl), _cLen(cl->length()), _afterCheck(afterCheck), _instanceRedundancyCheck(instanceRedundancyCheck), _ordering(ordering), _fixedPointIteration(fixedPointIteration) {} + ResultFn(EqualityFactoring& self, Clause* cl, bool afterCheck, const ConditionalRedundancyHandler* condRedHandler, Ordering& ordering, bool fixedPointIteration) + : _self(self), _cl(cl), _cLen(cl->length()), _afterCheck(afterCheck), _condRedHandler(condRedHandler), _ordering(ordering), _fixedPointIteration(fixedPointIteration) {} Clause* operator() (pair,pair > arg) { auto absUnif = AbstractingUnifier::empty(_self._abstractionOracle); @@ -166,9 +166,7 @@ struct EqualityFactoring::ResultFn } } - if (_instanceRedundancyCheck && - !InstanceRedundancyHandler::handleReductiveUnaryInference(_cl, &absUnif.subs(), &_ordering)) - { + if (!_condRedHandler->handleReductiveUnaryInference(_cl, &absUnif.subs())) { env.statistics->skippedEqualityFactoring++; return 0; } @@ -187,7 +185,7 @@ struct EqualityFactoring::ResultFn Clause* _cl; unsigned _cLen; bool _afterCheck; - bool _instanceRedundancyCheck; + const ConditionalRedundancyHandler* _condRedHandler; const Ordering& _ordering; bool _fixedPointIteration; }; @@ -209,8 +207,7 @@ ClauseIterator EqualityFactoring::generateClauses(Clause* premise) auto it5 = getMappingIterator(it4,ResultFn(*this, premise, getOptions().literalMaximalityAftercheck() && _salg->getLiteralSelector().isBGComplete(), - getOptions().instanceRedundancyCheck()!=Options::InstanceRedundancyCheck::OFF, - _salg->getOrdering(), _uwaFixedPointIteration)); + _salg->condRedHandler(), _salg->getOrdering(), _uwaFixedPointIteration)); auto it6 = getFilteredIterator(it5,NonzeroFn()); diff --git a/Inferences/EqualityResolution.cpp b/Inferences/EqualityResolution.cpp index a9184a82f..1ba47db0c 100644 --- a/Inferences/EqualityResolution.cpp +++ b/Inferences/EqualityResolution.cpp @@ -60,8 +60,8 @@ struct EqualityResolution::IsNegativeEqualityFn struct EqualityResolution::ResultFn { - ResultFn(Clause* cl, bool afterCheck = false, bool instanceRedundancyCheck = false, Ordering* ord = nullptr) - : _afterCheck(afterCheck), _instanceRedundancyCheck(instanceRedundancyCheck), _ord(ord), _cl(cl), _cLen(cl->length()) {} + ResultFn(Clause* cl, bool afterCheck = false, const ConditionalRedundancyHandler* condRedHandler = nullptr, Ordering* ord = nullptr) + : _afterCheck(afterCheck), _condRedHandler(condRedHandler), _ord(ord), _cl(cl), _cLen(cl->length()) {} Clause* operator() (Literal* lit) { @@ -120,9 +120,7 @@ struct EqualityResolution::ResultFn } } - if (_instanceRedundancyCheck && - !InstanceRedundancyHandler::handleReductiveUnaryInference(_cl, &absUnif->subs(), _ord)) - { + if (_condRedHandler && !_condRedHandler->handleReductiveUnaryInference(_cl, &absUnif->subs())) { env.statistics->skippedEqualityResolution++; return 0; } @@ -138,7 +136,7 @@ struct EqualityResolution::ResultFn } private: bool _afterCheck; - bool _instanceRedundancyCheck; + const ConditionalRedundancyHandler* _condRedHandler; const Ordering* _ord; Clause* _cl; unsigned _cLen; @@ -157,8 +155,7 @@ ClauseIterator EqualityResolution::generateClauses(Clause* premise) auto it3 = getMappingIterator(it2,ResultFn(premise, getOptions().literalMaximalityAftercheck() && _salg->getLiteralSelector().isBGComplete(), - getOptions().instanceRedundancyCheck()!=Options::InstanceRedundancyCheck::OFF, - &_salg->getOrdering())); + _salg->condRedHandler(), &_salg->getOrdering())); auto it4 = getFilteredIterator(it3,NonzeroFn()); diff --git a/Inferences/Superposition.cpp b/Inferences/Superposition.cpp index eaa49f3d2..b03eeecc8 100644 --- a/Inferences/Superposition.cpp +++ b/Inferences/Superposition.cpp @@ -42,6 +42,7 @@ #include "Saturation/SaturationAlgorithm.hpp" #include "Shell/AnswerExtractor.hpp" +#include "Shell/InstanceRedundancyHandler.hpp" #include "Shell/Options.hpp" #include "Shell/Statistics.hpp" @@ -66,7 +67,6 @@ void Superposition::attach(SaturationAlgorithm* salg) _salg->getIndexManager()->request(SUPERPOSITION_SUBTERM_SUBST_TREE) ); _lhsIndex=static_cast ( _salg->getIndexManager()->request(SUPERPOSITION_LHS_SUBST_TREE) ); - _instanceRedundancyHandler = InstanceRedundancyHandler(getOptions(),&_salg->getOrdering()); } void Superposition::detach() @@ -350,7 +350,8 @@ Clause* Superposition::performSuperposition( } } - if (!_instanceRedundancyHandler.checkSuperposition(eqClause, rwClause, eqIsResult, subst.ptr())) { + auto condRedHandler = _salg->condRedHandler(); + if (!condRedHandler->checkSuperposition(eqClause, rwClause, eqIsResult, subst.ptr())) { return 0; } @@ -385,7 +386,7 @@ Clause* Superposition::performSuperposition( } } - _instanceRedundancyHandler.insertSuperposition( + condRedHandler->insertSuperposition( eqClause, rwClause, rwTermS, tgtTermS, eqLHS, rwLitS, comp, eqIsResult, subst.ptr()); Literal* tgtLitS = EqHelper::replace(rwLitS,rwTermS,tgtTermS); diff --git a/Inferences/Superposition.hpp b/Inferences/Superposition.hpp index 046774d88..f8d10be9c 100644 --- a/Inferences/Superposition.hpp +++ b/Inferences/Superposition.hpp @@ -22,8 +22,6 @@ #include "InferenceEngine.hpp" #include "Kernel/RobSubstitution.hpp" -#include "Shell/InstanceRedundancyHandler.hpp" - namespace Inferences { using namespace Kernel; @@ -61,7 +59,6 @@ class Superposition SuperpositionSubtermIndex* _subtermIndex; SuperpositionLHSIndex* _lhsIndex; - InstanceRedundancyHandler _instanceRedundancyHandler; }; diff --git a/Kernel/Clause.cpp b/Kernel/Clause.cpp index f21851df6..06c4c079f 100644 --- a/Kernel/Clause.cpp +++ b/Kernel/Clause.cpp @@ -124,7 +124,7 @@ void Clause::destroyExceptInferenceObject() delete _literalPositions; } - InstanceRedundancyHandler::destroyClauseData(this); + ConditionalRedundancyHandler::destroyClauseData(this); RSTAT_CTR_INC("clauses deleted"); diff --git a/Saturation/SaturationAlgorithm.cpp b/Saturation/SaturationAlgorithm.cpp index 2517d920d..b58576570 100644 --- a/Saturation/SaturationAlgorithm.cpp +++ b/Saturation/SaturationAlgorithm.cpp @@ -96,6 +96,7 @@ #include "Saturation/ExtensionalityClauseContainer.hpp" #include "Shell/AnswerExtractor.hpp" +#include "Shell/InstanceRedundancyHandler.hpp" #include "Shell/Options.hpp" #include "Shell/Statistics.hpp" #include "Shell/UIHelper.hpp" @@ -224,7 +225,7 @@ SaturationAlgorithm::SaturationAlgorithm(Problem& prb, const Options& opt) _fwSimplifiers(0), _simplifiers(0), _bwSimplifiers(0), _splitter(0), _consFinder(0), _labelFinder(0), _symEl(0), _answerLiteralManager(0), _instantiation(0), _fnDefHandler(prb.getFunctionDefinitionHandler()), - _generatedClauseCount(0), + _conditionalRedundancyHandler(), _generatedClauseCount(0), _activationLimit(0) { ASS_EQ(s_instance, 0); //there can be only one saturation algorithm at a time @@ -1720,6 +1721,9 @@ SaturationAlgorithm* SaturationAlgorithm::createFromOptions(Problem& prb, const } else if (opt.questionAnswering()==Options::QuestionAnsweringMode::SYNTHESIS) { res->_answerLiteralManager = SynthesisManager::getInstance(); } + + res->_conditionalRedundancyHandler.reset(ConditionalRedundancyHandler::create(opt, &ordering)); + return res; } // SaturationAlgorithm::createFromOptions diff --git a/Saturation/SaturationAlgorithm.hpp b/Saturation/SaturationAlgorithm.hpp index e32131958..2954c9eb0 100644 --- a/Saturation/SaturationAlgorithm.hpp +++ b/Saturation/SaturationAlgorithm.hpp @@ -107,6 +107,7 @@ class SaturationAlgorithm : public MainLoop IndexManager* getIndexManager() { return _imgr.ptr(); } Ordering& getOrdering() const { return *_ordering; } LiteralSelector& getLiteralSelector() const { return *_selector; } + const ConditionalRedundancyHandler* condRedHandler() const { return _conditionalRedundancyHandler.get(); } /** Return the number of clauses that entered the passive container */ unsigned getGeneratedClauseCount() { return _generatedClauseCount; } @@ -218,6 +219,7 @@ class SaturationAlgorithm : public MainLoop AnswerLiteralManager* _answerLiteralManager; Instantiation* _instantiation; FunctionDefinitionHandler& _fnDefHandler; + std::unique_ptr _conditionalRedundancyHandler; SubscriptionData _passiveContRemovalSData; SubscriptionData _activeContRemovalSData; diff --git a/Saturation/Splitter.cpp b/Saturation/Splitter.cpp index 72b37dfef..c353efd87 100644 --- a/Saturation/Splitter.cpp +++ b/Saturation/Splitter.cpp @@ -1524,7 +1524,7 @@ void Splitter::onNewClause(Clause* cl) // when using AVATAR, we could have performed // generating inferences on the clause previously, // so we need to reset the data. - InstanceRedundancyHandler::destroyClauseData(cl); + ConditionalRedundancyHandler::destroyClauseData(cl); if (cl->inference().rule() == InferenceRule::AVATAR_ASSERTION_REINTRODUCTION) { // Do not assign splits from premises if cl originated by re-introducing AVATAR assertions (avoids looping) diff --git a/Shell/InstanceRedundancyHandler.cpp b/Shell/InstanceRedundancyHandler.cpp index aa917e70a..7803a6b0e 100644 --- a/Shell/InstanceRedundancyHandler.cpp +++ b/Shell/InstanceRedundancyHandler.cpp @@ -8,8 +8,8 @@ * and in the source directory */ /** - * @file InstanceRedundancyHandler.cpp - * Implements class InstanceRedundancyHandler. + * @file ConditionalRedundancyHandler.cpp + * Implements class ConditionalRedundancyHandler. */ #include "InstanceRedundancyHandler.hpp" @@ -27,11 +27,12 @@ #include "Statistics.hpp" using namespace std; +using namespace Indexing; -namespace Indexing +namespace Shell { -class InstanceRedundancyHandler::SubstitutionCoverTree +class ConditionalRedundancyHandler::SubstitutionCoverTree : public CodeTree { public: @@ -67,28 +68,13 @@ class InstanceRedundancyHandler::SubstitutionCoverTree void insert(const Ordering* ord, ResultSubstitution* subst, bool result, Term* lhs=nullptr, Term* rhs=nullptr) { auto ts = getInstances([subst,result](unsigned v) { return subst->applyTo(TermList::var(v),result); }); - auto ld = new LeafData(); - if (lhs) { - ASS(rhs); - ASS(lhs->containsAllVariablesOf(rhs)); - Renaming r; - // normalize lhs and rhs, the same way as - // terms from ts are normalized upon insertion - for (const auto t : ts) { - r.normalizeVariables(t); - } - ld->lhs = r.apply(lhs); - ld->rhs = r.apply(rhs); - } else { - ASS(!rhs); - ld->lhs = nullptr; - ld->rhs = nullptr; - } + auto ld = createEntry(ts, lhs, rhs); insert(ts,ld); } bool checkAndInsert(const Ordering* ord, ResultSubstitution* subst, bool result, bool doInsert=false, Term* lhs=nullptr, Term* rhs=nullptr) { + // TODO if this correct if we allow non-unit simplifications? if (_varSorts.isEmpty()) { return true; } @@ -97,29 +83,17 @@ class InstanceRedundancyHandler::SubstitutionCoverTree return false; } if (doInsert) { - auto ld = new LeafData(); - if (lhs) { - ASS(rhs); - ASS(lhs->containsAllVariablesOf(rhs)); - Renaming r; - // normalize lhs and rhs, the same way as - // terms from ts are normalized upon insertion - for (const auto t : ts) { - r.normalizeVariables(t); - } - ld->lhs = r.apply(lhs); - ld->rhs = r.apply(rhs); - } else { - ASS(!rhs); - ld->lhs = nullptr; - ld->rhs = nullptr; - } + auto ld = createEntry(ts, lhs, rhs); insert(ts,ld); } return true; } private: +#if VDEBUG + Clause* _cl; +#endif + void insert(const TermStack& ts, void* ptr) { static CodeStack code; @@ -199,6 +173,28 @@ class InstanceRedundancyHandler::SubstitutionCoverTree OrderingComparatorUP comp; }; + LeafData* createEntry(const TermStack& ts, Term* lhs, Term* rhs) const + { + auto ld = new LeafData(); + if (lhs) { + ASS(rhs); + ASS(lhs->containsAllVariablesOf(rhs)); + Renaming r; + // normalize lhs and rhs, the same way as + // terms from ts are normalized upon insertion + for (const auto t : ts) { + r.normalizeVariables(t); + } + ld->lhs = r.apply(lhs); + ld->rhs = r.apply(rhs); + } else { + ASS(!rhs); + ld->lhs = nullptr; + ld->rhs = nullptr; + } + return ld; + } + struct SubstMatcher : public Matcher { @@ -238,11 +234,48 @@ class InstanceRedundancyHandler::SubstitutionCoverTree }; }; -// InstanceRedundancyHandler +// ConditionalRedundancyHandler + +ConditionalRedundancyHandler* ConditionalRedundancyHandler::create(const Options& opts, const Ordering* ord) +{ + if (!opts.conditionalRedundancyCheck()) { + return new ConditionalRedundancyHandlerImpl(opts,ord); + } + auto ordC = opts.conditionalRedundancyOrderingConstraints(); + auto avatarC = opts.conditionalRedundancyAvatarConstraints(); + auto litC = opts.conditionalRedundancyLiteralConstraints(); + if (ordC) { + if (avatarC) { + if (litC) { + return new ConditionalRedundancyHandlerImpl(opts,ord); + } + return new ConditionalRedundancyHandlerImpl(opts,ord); + } + if (litC) { + return new ConditionalRedundancyHandlerImpl(opts,ord); + } + return new ConditionalRedundancyHandlerImpl(opts,ord); + } + if (avatarC) { + if (litC) { + return new ConditionalRedundancyHandlerImpl(opts,ord); + } + return new ConditionalRedundancyHandlerImpl(opts,ord); + } + if (litC) { + return new ConditionalRedundancyHandlerImpl(opts,ord); + } + return new ConditionalRedundancyHandlerImpl(opts,ord); +} -DHMap InstanceRedundancyHandler::clauseData; +void ConditionalRedundancyHandler::destroyClauseData(Clause* cl) +{ + SubstitutionCoverTree* ptr = nullptr; + clauseData.pop(cl, ptr); + delete ptr; +} -InstanceRedundancyHandler::SubstitutionCoverTree** InstanceRedundancyHandler::getDataPtr(Clause* cl, bool doAllocate) +ConditionalRedundancyHandler::SubstitutionCoverTree** ConditionalRedundancyHandler::getDataPtr(Clause* cl, bool doAllocate) { if (!doAllocate) { return clauseData.findPtr(cl); @@ -255,9 +288,15 @@ InstanceRedundancyHandler::SubstitutionCoverTree** InstanceRedundancyHandler::ge return ptr; } -bool InstanceRedundancyHandler::checkSuperposition(Clause* eqClause, Clause* rwClause, bool eqIsResult, ResultSubstitution* subs) const +DHMap ConditionalRedundancyHandler::clauseData; + +// ConditionalRedundancyHandlerImpl + +template +bool ConditionalRedundancyHandlerImpl::checkSuperposition( + Clause* eqClause, Clause* rwClause, bool eqIsResult, ResultSubstitution* subs) const { - if (_optVal==Options::InstanceRedundancyCheck::OFF) { + if constexpr (!enabled) { return true; } @@ -276,11 +315,12 @@ bool InstanceRedundancyHandler::checkSuperposition(Clause* eqClause, Clause* rwC return true; } -void InstanceRedundancyHandler::insertSuperposition(Clause* eqClause, Clause* rwClause, - TermList rwTermS, TermList tgtTermS, TermList eqLHS, Literal* rwLitS, Ordering::Result eqComp, - bool eqIsResult, ResultSubstitution* subs) const +template +void ConditionalRedundancyHandlerImpl::insertSuperposition( + Clause* eqClause, Clause* rwClause, TermList rwTermS, TermList tgtTermS, TermList eqLHS, + Literal* rwLitS, Ordering::Result eqComp, bool eqIsResult, ResultSubstitution* subs) const { - if (_optVal==Options::InstanceRedundancyCheck::OFF) { + if constexpr (!enabled) { return; } @@ -296,7 +336,7 @@ void InstanceRedundancyHandler::insertSuperposition(Clause* eqClause, Clause* rw Applicator appl(subs, !eqIsResult); auto doInsert = eqClause->length()==1 && eqClause->noSplits() && - ((_optVal!=Options::InstanceRedundancyCheck::LAZY && rwTermS.containsAllVariablesOf(tgtTermS)) || eqComp == Ordering::LESS) && + ((!ordC && rwTermS.containsAllVariablesOf(tgtTermS)) || eqComp == Ordering::LESS) && (!_demodulationHelper.redundancyCheckNeededForPremise(rwClause, rwLitS, rwTermS) || // TODO for rwClause->length()!=1 the function isPremiseRedundant does not work yet (rwClause->length()==1 && _demodulationHelper.isPremiseRedundant(rwClause, rwLitS, rwTermS, tgtTermS, eqLHS, &appl))); @@ -313,11 +353,11 @@ void InstanceRedundancyHandler::insertSuperposition(Clause* eqClause, Clause* rw incompInserted ? tgtTermS.term() : nullptr); } -bool InstanceRedundancyHandler::handleResolution(Clause* queryCl, Literal* queryLit, - Clause* resultCl, Literal* resultLit, - ResultSubstitution* subs, const Options& opts, const Ordering* ord) +template +bool ConditionalRedundancyHandlerImpl::handleResolution( + Clause* queryCl, Literal* queryLit, Clause* resultCl, Literal* resultLit, ResultSubstitution* subs) const { - if (opts.instanceRedundancyCheck()==Options::InstanceRedundancyCheck::OFF) { + if constexpr (!enabled) { return true; } @@ -325,7 +365,7 @@ bool InstanceRedundancyHandler::handleResolution(Clause* queryCl, Literal* query { bool doInsert = resultLit->isPositive() && resultCl->size()==1 && resultCl->noSplits(); auto dataPtr = getDataPtr(queryCl, /*doAllocate=*/doInsert); - if (dataPtr && !(*dataPtr)->checkAndInsert(ord, subs, false, doInsert)) { + if (dataPtr && !(*dataPtr)->checkAndInsert(_ord, subs, false, doInsert)) { env.statistics->skippedResolution++; return false; } @@ -333,7 +373,7 @@ bool InstanceRedundancyHandler::handleResolution(Clause* queryCl, Literal* query { bool doInsert = queryLit->isPositive() && queryCl->size()==1 && queryCl->noSplits(); auto dataPtr = getDataPtr(resultCl, /*doAllocate=*/doInsert); - if (dataPtr && !(*dataPtr)->checkAndInsert(ord, subs, true, doInsert)) { + if (dataPtr && !(*dataPtr)->checkAndInsert(_ord, subs, true, doInsert)) { env.statistics->skippedResolution++; return false; } @@ -341,22 +381,19 @@ bool InstanceRedundancyHandler::handleResolution(Clause* queryCl, Literal* query return true; } -bool InstanceRedundancyHandler::handleReductiveUnaryInference( - Clause* premise, RobSubstitution* subs, const Ordering* ord) +template +bool ConditionalRedundancyHandlerImpl::handleReductiveUnaryInference( + Clause* premise, RobSubstitution* subs) const { + if constexpr (!enabled) { + return true; + } auto dataPtr = getDataPtr(premise, /*doAllocate=*/true); auto subst = ResultSubstitution::fromSubstitution(subs, 0, 0); - if (!(*dataPtr)->checkAndInsert(ord, subst.ptr(), false, /*doInsert=*/true)) { + if (!(*dataPtr)->checkAndInsert(_ord, subst.ptr(), false, /*doInsert=*/true)) { return false; } return true; } -void InstanceRedundancyHandler::destroyClauseData(Clause* cl) -{ - SubstitutionCoverTree* ptr = nullptr; - clauseData.pop(cl, ptr); - delete ptr; -} - } diff --git a/Shell/InstanceRedundancyHandler.hpp b/Shell/InstanceRedundancyHandler.hpp index 6c89e331c..dfc27ba0f 100644 --- a/Shell/InstanceRedundancyHandler.hpp +++ b/Shell/InstanceRedundancyHandler.hpp @@ -8,12 +8,12 @@ * and in the source directory */ /** - * @file InstanceRedundancyHandler.hpp - * Defines class InstanceRedundancyHandler. + * @file ConditionalRedundancyHandler.hpp + * Defines class ConditionalRedundancyHandler. */ -#ifndef __InstanceRedundancyHandler__ -#define __InstanceRedundancyHandler__ +#ifndef __ConditionalRedundancyHandler__ +#define __ConditionalRedundancyHandler__ #include "Forwards.hpp" @@ -22,53 +22,69 @@ #include "Options.hpp" -namespace Indexing { +namespace Shell { -using namespace Inferences; using namespace Lib; -using namespace Shell; +using namespace Indexing; -class InstanceRedundancyHandler +class ConditionalRedundancyHandler { public: - InstanceRedundancyHandler() = default; - InstanceRedundancyHandler(const Options& opts, const Ordering* ord) - : _optVal(opts.instanceRedundancyCheck()), _ord(ord), _demodulationHelper(opts,ord) {} + static ConditionalRedundancyHandler* create(const Options& opts, const Ordering* ord); + static void destroyClauseData(Clause* cl); + + virtual ~ConditionalRedundancyHandler() = default; + + virtual bool checkSuperposition( + Clause* eqClause, Clause* rwClause, bool eqIsResult, ResultSubstitution* subs) const = 0; + + virtual void insertSuperposition( + Clause* eqClause, Clause* rwClause, TermList rwTermS, TermList tgtTermS, TermList eqLHS, + Literal* rwLitS, Ordering::Result eqComp, bool eqIsResult, ResultSubstitution* subs) const = 0; + + virtual bool handleResolution( + Clause* queryCl, Literal* queryLit, Clause* resultCl, Literal* resultLit, ResultSubstitution* subs) const = 0; + + virtual bool handleReductiveUnaryInference(Clause* premise, RobSubstitution* subs) const = 0; + +protected: + class SubstitutionCoverTree; + + static SubstitutionCoverTree** getDataPtr(Clause* cl, bool doAllocate); + + // this contains the redundancy information associated with each clause + static DHMap clauseData; +}; + +template +class ConditionalRedundancyHandlerImpl + : public ConditionalRedundancyHandler +{ +public: + ConditionalRedundancyHandlerImpl() = default; + ConditionalRedundancyHandlerImpl(const Options& opts, const Ordering* ord) + : _ord(ord), _demodulationHelper(opts,ord) {} /** Returns false if superposition should be skipped. */ bool checkSuperposition( - Clause* eqClause, Clause* rwClause, bool eqIsResult, ResultSubstitution* subs) const; + Clause* eqClause, Clause* rwClause, bool eqIsResult, ResultSubstitution* subs) const override; void insertSuperposition( - Clause* eqClause, Clause* rwClause, - TermList rwTermS, TermList tgtTermS, TermList eqLHS, Literal* rwLitS, - Ordering::Result eqComp, bool eqIsResult, ResultSubstitution* subs) const; + Clause* eqClause, Clause* rwClause, TermList rwTermS, TermList tgtTermS, TermList eqLHS, + Literal* rwLitS, Ordering::Result eqComp, bool eqIsResult, ResultSubstitution* subs) const override; /** Returns false if resolution should be skipped. */ - static bool handleResolution( - Clause* queryCl, Literal* queryLit, - Clause* resultCl, Literal* resultLit, - ResultSubstitution* subs, const Options& opts, const Ordering* ord); + bool handleResolution( + Clause* queryCl, Literal* queryLit, Clause* resultCl, Literal* resultLit, ResultSubstitution* subs) const override; /** Returns false if inference should be skipped. */ - static bool handleReductiveUnaryInference( - Clause* premise, RobSubstitution* subs, const Ordering* ord); - - static void destroyClauseData(Clause* cl); + bool handleReductiveUnaryInference(Clause* premise, RobSubstitution* subs) const override; private: - Options::InstanceRedundancyCheck _optVal; const Ordering* _ord; Inferences::DemodulationHelper _demodulationHelper; - - class SubstitutionCoverTree; - - static SubstitutionCoverTree** getDataPtr(Clause* cl, bool doAllocate); - - // this contains the redundancy information associated with each clause - static DHMap clauseData; }; }; -#endif // __InstanceRedundancyHandler__ +#endif // __ConditionalRedundancyHandler__ diff --git a/Shell/Options.cpp b/Shell/Options.cpp index 16ce67f74..46ccacbbf 100644 --- a/Shell/Options.cpp +++ b/Shell/Options.cpp @@ -1706,13 +1706,33 @@ void Options::init() _equationalTautologyRemoval.onlyUsefulWith(ProperSaturationAlgorithm()); _equationalTautologyRemoval.tag(OptionTag::INFERENCES); - _instanceRedundancyCheck = ChoiceOptionValue("instance_redundancy_check","irc", - InstanceRedundancyCheck::OFF,{"lazy","eager","off"}); - _instanceRedundancyCheck.description= - "Skip generating inferences on clause instances on which we already performed a reductive inference."; - _lookup.insert(&_instanceRedundancyCheck); - _instanceRedundancyCheck.onlyUsefulWith(ProperSaturationAlgorithm()); - _instanceRedundancyCheck.tag(OptionTag::INFERENCES); + _conditionalRedundancyCheck = BoolOptionValue("conditional_redundancy_check","crc",false); + _conditionalRedundancyCheck.description= + "Skip generating inferences on clause instances on which we already performed a simplifying inference."; + _lookup.insert(&_conditionalRedundancyCheck); + _conditionalRedundancyCheck.onlyUsefulWith(ProperSaturationAlgorithm()); + _conditionalRedundancyCheck.tag(OptionTag::INFERENCES); + + _conditionalRedundancyOrderingConstraints = BoolOptionValue("conditional_redundancy_ordering_constraints","croc",false); + _conditionalRedundancyOrderingConstraints.description= + "Strengthen conditional redundancy with ordering constraints."; + _lookup.insert(&_conditionalRedundancyOrderingConstraints); + _conditionalRedundancyOrderingConstraints.addHardConstraint(If(equal(true)).then(_conditionalRedundancyCheck.is(equal(true)))); + _conditionalRedundancyOrderingConstraints.tag(OptionTag::INFERENCES); + + _conditionalRedundancyAvatarConstraints = BoolOptionValue("conditional_redundancy_avatar_constraints","crac",false); + _conditionalRedundancyAvatarConstraints.description= + "Strengthen conditional redundancy with AVATAR constraints."; + _lookup.insert(&_conditionalRedundancyAvatarConstraints); + _conditionalRedundancyAvatarConstraints.addHardConstraint(If(equal(true)).then(_conditionalRedundancyCheck.is(equal(true)))); + _conditionalRedundancyAvatarConstraints.tag(OptionTag::INFERENCES); + + _conditionalRedundancyLiteralConstraints = BoolOptionValue("conditional_redundancy_literal_constraints","crlc",false); + _conditionalRedundancyLiteralConstraints.description= + "Strengthen conditional redundancy with literals from clauses."; + _lookup.insert(&_conditionalRedundancyLiteralConstraints); + _conditionalRedundancyLiteralConstraints.addHardConstraint(If(equal(true)).then(_conditionalRedundancyCheck.is(equal(true)))); + _conditionalRedundancyLiteralConstraints.tag(OptionTag::INFERENCES); _unitResultingResolution = ChoiceOptionValue("unit_resulting_resolution","urr",URResolution::OFF,{"ec_only","off","on","full"}); _unitResultingResolution.description= @@ -3481,9 +3501,6 @@ bool Options::complete(const Problem& prb) const if (!_superpositionFromVariables.actualValue) { return false; } - if (_instanceRedundancyCheck.actualValue == InstanceRedundancyCheck::EAGER) { - return false; - } // only checking resolution rules remain bool pureEquality = (prop.atoms() == prop.equalityAtoms()); diff --git a/Shell/Options.hpp b/Shell/Options.hpp index cbea511f1..1e1727fb9 100644 --- a/Shell/Options.hpp +++ b/Shell/Options.hpp @@ -764,12 +764,6 @@ class Options OFF = 3 }; - enum class InstanceRedundancyCheck : unsigned int { - LAZY = 0, - EAGER = 1, - OFF = 2, - }; - //========================================================== // The Internals //========================================================== @@ -2084,7 +2078,10 @@ bool _hard; bool simulatenousSuperposition() const { return _simultaneousSuperposition.actualValue; } bool innerRewriting() const { return _innerRewriting.actualValue; } bool equationalTautologyRemoval() const { return _equationalTautologyRemoval.actualValue; } - InstanceRedundancyCheck instanceRedundancyCheck() const { return _instanceRedundancyCheck.actualValue; } + bool conditionalRedundancyCheck() const { return _conditionalRedundancyCheck.actualValue; } + bool conditionalRedundancyOrderingConstraints() const { return _conditionalRedundancyOrderingConstraints.actualValue; } + bool conditionalRedundancyAvatarConstraints() const { return _conditionalRedundancyAvatarConstraints.actualValue; } + bool conditionalRedundancyLiteralConstraints() const { return _conditionalRedundancyLiteralConstraints.actualValue; } bool arityCheck() const { return _arityCheck.actualValue; } //void setArityCheck(bool newVal) { _arityCheck=newVal; } Demodulation backwardDemodulation() const { return _backwardDemodulation.actualValue; } @@ -2506,7 +2503,10 @@ bool _hard; BoolOptionValue _simultaneousSuperposition; BoolOptionValue _innerRewriting; BoolOptionValue _equationalTautologyRemoval; - ChoiceOptionValue _instanceRedundancyCheck; + BoolOptionValue _conditionalRedundancyCheck; + BoolOptionValue _conditionalRedundancyOrderingConstraints; + BoolOptionValue _conditionalRedundancyAvatarConstraints; + BoolOptionValue _conditionalRedundancyLiteralConstraints; /** if true, then calling set() on non-existing options will not result in a user error */ ChoiceOptionValue _ignoreMissing; From b40279614577dd5770ab8321e09fa01b19846a88 Mon Sep 17 00:00:00 2001 From: Marton Hajdu Date: Fri, 19 Jul 2024 10:52:00 +0200 Subject: [PATCH 05/19] Rename InstanceRedundancyHandler files to ConditionalRedundancyHandler --- CMakeLists.txt | 4 ++-- Inferences/BinaryResolution.cpp | 2 +- Inferences/EqualityFactoring.cpp | 2 +- Inferences/EqualityResolution.cpp | 2 +- Inferences/Superposition.cpp | 2 +- Kernel/Clause.cpp | 2 +- Makefile | 2 +- Saturation/SaturationAlgorithm.cpp | 2 +- Saturation/Splitter.cpp | 2 +- ...RedundancyHandler.cpp => ConditionalRedundancyHandler.cpp} | 2 +- ...RedundancyHandler.hpp => ConditionalRedundancyHandler.hpp} | 0 11 files changed, 11 insertions(+), 11 deletions(-) rename Shell/{InstanceRedundancyHandler.cpp => ConditionalRedundancyHandler.cpp} (99%) rename Shell/{InstanceRedundancyHandler.hpp => ConditionalRedundancyHandler.hpp} (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index d9f6aa09b..ba6be8a00 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -548,7 +548,7 @@ set(VAMPIRE_SHELL_SOURCES Shell/GoalGuessing.cpp Shell/FunctionDefinitionHandler.cpp Shell/InequalitySplitting.cpp - Shell/InstanceRedundancyHandler.cpp + Shell/ConditionalRedundancyHandler.cpp Shell/InterpolantMinimizer.cpp Shell/Interpolants.cpp Shell/InterpretedNormalizer.cpp @@ -602,7 +602,7 @@ set(VAMPIRE_SHELL_SOURCES Shell/FunctionDefinitionHandler.hpp Shell/GeneralSplitting.hpp Shell/InequalitySplitting.hpp - Shell/InstanceRedundancyHandler.hpp + Shell/ConditionalRedundancyHandler.hpp Shell/InterpolantMinimizer.hpp Shell/Interpolants.hpp Shell/InterpretedNormalizer.hpp diff --git a/Inferences/BinaryResolution.cpp b/Inferences/BinaryResolution.cpp index e52b883b3..c34a29e90 100644 --- a/Inferences/BinaryResolution.cpp +++ b/Inferences/BinaryResolution.cpp @@ -39,7 +39,7 @@ #include "Saturation/SaturationAlgorithm.hpp" #include "Shell/AnswerExtractor.hpp" -#include "Shell/InstanceRedundancyHandler.hpp" +#include "Shell/ConditionalRedundancyHandler.hpp" #include "Shell/Options.hpp" #include "Shell/Statistics.hpp" diff --git a/Inferences/EqualityFactoring.cpp b/Inferences/EqualityFactoring.cpp index 4d35b0bd3..e523cf956 100644 --- a/Inferences/EqualityFactoring.cpp +++ b/Inferences/EqualityFactoring.cpp @@ -31,7 +31,7 @@ #include "Saturation/SaturationAlgorithm.hpp" -#include "Shell/InstanceRedundancyHandler.hpp" +#include "Shell/ConditionalRedundancyHandler.hpp" #include "Shell/Statistics.hpp" #include "EqualityFactoring.hpp" diff --git a/Inferences/EqualityResolution.cpp b/Inferences/EqualityResolution.cpp index 1ba47db0c..0ae1ebb2a 100644 --- a/Inferences/EqualityResolution.cpp +++ b/Inferences/EqualityResolution.cpp @@ -35,7 +35,7 @@ #include "Saturation/SaturationAlgorithm.hpp" -#include "Shell/InstanceRedundancyHandler.hpp" +#include "Shell/ConditionalRedundancyHandler.hpp" #include "EqualityResolution.hpp" diff --git a/Inferences/Superposition.cpp b/Inferences/Superposition.cpp index b03eeecc8..23426bb06 100644 --- a/Inferences/Superposition.cpp +++ b/Inferences/Superposition.cpp @@ -42,7 +42,7 @@ #include "Saturation/SaturationAlgorithm.hpp" #include "Shell/AnswerExtractor.hpp" -#include "Shell/InstanceRedundancyHandler.hpp" +#include "Shell/ConditionalRedundancyHandler.hpp" #include "Shell/Options.hpp" #include "Shell/Statistics.hpp" diff --git a/Kernel/Clause.cpp b/Kernel/Clause.cpp index 06c4c079f..9b9d8baff 100644 --- a/Kernel/Clause.cpp +++ b/Kernel/Clause.cpp @@ -31,7 +31,7 @@ #include "SAT/SATClause.hpp" -#include "Shell/InstanceRedundancyHandler.hpp" +#include "Shell/ConditionalRedundancyHandler.hpp" #include "Shell/Options.hpp" #include "Inference.hpp" diff --git a/Makefile b/Makefile index 70d4dfe7f..caac2dad4 100644 --- a/Makefile +++ b/Makefile @@ -339,7 +339,7 @@ VS_OBJ = Shell/AnswerExtractor.o\ Shell/GeneralSplitting.o\ Shell/GoalGuessing.o\ Shell/InequalitySplitting.o\ - Shell/InstanceRedundancyHandler.o\ + Shell/ConditionalRedundancyHandler.o\ Shell/InterpolantMinimizer.o\ Shell/Interpolants.o\ Shell/InterpretedNormalizer.o\ diff --git a/Saturation/SaturationAlgorithm.cpp b/Saturation/SaturationAlgorithm.cpp index b58576570..50ba3f4a4 100644 --- a/Saturation/SaturationAlgorithm.cpp +++ b/Saturation/SaturationAlgorithm.cpp @@ -96,7 +96,7 @@ #include "Saturation/ExtensionalityClauseContainer.hpp" #include "Shell/AnswerExtractor.hpp" -#include "Shell/InstanceRedundancyHandler.hpp" +#include "Shell/ConditionalRedundancyHandler.hpp" #include "Shell/Options.hpp" #include "Shell/Statistics.hpp" #include "Shell/UIHelper.hpp" diff --git a/Saturation/Splitter.cpp b/Saturation/Splitter.cpp index c353efd87..9f7c344d0 100644 --- a/Saturation/Splitter.cpp +++ b/Saturation/Splitter.cpp @@ -34,7 +34,7 @@ #include "Kernel/FormulaUnit.hpp" #include "Kernel/MainLoop.hpp" -#include "Shell/InstanceRedundancyHandler.hpp" +#include "Shell/ConditionalRedundancyHandler.hpp" #include "Shell/Options.hpp" #include "Shell/Statistics.hpp" #include "Shell/Shuffling.hpp" diff --git a/Shell/InstanceRedundancyHandler.cpp b/Shell/ConditionalRedundancyHandler.cpp similarity index 99% rename from Shell/InstanceRedundancyHandler.cpp rename to Shell/ConditionalRedundancyHandler.cpp index 7803a6b0e..e1d9fce44 100644 --- a/Shell/InstanceRedundancyHandler.cpp +++ b/Shell/ConditionalRedundancyHandler.cpp @@ -12,7 +12,7 @@ * Implements class ConditionalRedundancyHandler. */ -#include "InstanceRedundancyHandler.hpp" +#include "ConditionalRedundancyHandler.hpp" #include "Kernel/Clause.hpp" #include "Kernel/TermIterators.hpp" diff --git a/Shell/InstanceRedundancyHandler.hpp b/Shell/ConditionalRedundancyHandler.hpp similarity index 100% rename from Shell/InstanceRedundancyHandler.hpp rename to Shell/ConditionalRedundancyHandler.hpp From db98d89834a45b262accc58932a00e6b079afe5e Mon Sep 17 00:00:00 2001 From: Marton Hajdu Date: Fri, 19 Jul 2024 11:48:24 +0200 Subject: [PATCH 06/19] Fix ordering constraint check; modify schedules to new option values --- CASC/Schedules.cpp | 144 ++++++++++++------------- Shell/ConditionalRedundancyHandler.cpp | 12 ++- 2 files changed, 80 insertions(+), 76 deletions(-) diff --git a/CASC/Schedules.cpp b/CASC/Schedules.cpp index 2a830d26f..5dcafc7bf 100644 --- a/CASC/Schedules.cpp +++ b/CASC/Schedules.cpp @@ -6168,11 +6168,11 @@ void Schedules::getCasc2024Schedule(const Property& property, Schedule& quick, S propZsmall10.push("ott+10_4:13_drc=encompass:sil=256000:bsd=on:sp=reverse_frequency:urr=on:i=125345:rawr=on_0"); propZsmall10.push("lrs+10_25:89_sil=256000:tgt=ground:lwlo=on:s2a=on:i=224446:s2at=5.0:fsr=off:awrs=converge:awrsf=90_0"); - propZsmall10.push("lrs+10_1:1_to=lpo:drc=encompass:sil=2000:fde=unused:sp=const_min:i=107:bs=unit_only:bd=preordered:ins=1:rawr=on:irc=lazy:sfv=off:plsq=on:plsql=on:plsqc=1_0"); - propZsmall10.push("lrs+10_1:32_drc=encompass:sil=256000:i=140:irc=lazy_0"); + propZsmall10.push("lrs+10_1:1_to=lpo:drc=encompass:sil=2000:fde=unused:sp=const_min:i=107:bs=unit_only:bd=preordered:ins=1:rawr=on:crc=on:sfv=off:plsq=on:plsql=on:plsqc=1_0"); + propZsmall10.push("lrs+10_1:32_drc=encompass:sil=256000:i=140:crc=on_0"); propZsmall10.push("lrs+10_85441:1048576_drc=encompass:sil=64000:i=401:awrs=converge:sp=reverse_frequency:dpc=on:bd=preordered:fsr=off:ss=included:st=3.0:fde=none_0"); propZsmall10.push("dis+10_1:128_drc=encompass:sil=256000:sp=occurrence:i=1122:kws=precedence:fsr=off_0"); - propZsmall10.push("dis+10_1:24_drc=encompass:sil=256000:tgt=ground:spb=goal:i=313:bd=preordered:irc=eager_0"); + propZsmall10.push("dis+10_1:24_drc=encompass:sil=256000:tgt=ground:spb=goal:i=313:bd=preordered:crc=on:croc=on_0"); propZsmall10.push("dis+10_1:9_bsr=unit_only:slsqr=31,32:sil=256000:tgt=full:urr=on:slsqc=2:slsq=on:i=1149:s2at=5.0:slsql=off:ins=1:rawr=on:fd=preordered:drc=encompass_0"); propZsmall10.push("lrs+10_1:10_drc=encompass:sil=2000:tgt=ground:plsq=on:plsqr=92626939,1048576:sp=occurrence:fd=preordered:i=1914:kws=precedence:ins=8:rawr=on_0"); propZsmall10.push("lrs+10_16:1_bsr=on:drc=encompass:sil=64000:i=281:bd=off:to=lpo_0"); @@ -6186,83 +6186,83 @@ void Schedules::getCasc2024Schedule(const Property& property, Schedule& quick, S propZsmall10.push("lrs+10_1:512_sil=4000:tgt=ground:sp=reverse_frequency:s2a=on:i=702:bs=unit_only:bd=off:ss=axioms:rawr=on:slsq=on:slsqc=3:slsqr=19,8_0"); propZsmall10.push("lrs+10_1:4_drc=encompass:sil=16000:lwlo=on:st=-1.0:i=6272:ss=axioms_0"); propZsmall10.push("lrs+10_1:10_drc=encompass:sil=16000:tgt=ground:plsq=on:fd=preordered:i=10171:bd=preordered:ins=1:rawr=on:ss=axioms:sgt=16_0"); - propZsmall10.push("lrs+10_7:24_to=lpo:drc=encompass:sil=128000:fde=unused:sp=const_min:spb=goal:i=1061:irc=lazy:slsq=on:fdi=256:nwc=10.0:dpc=on:ss=included:st=2.0_0"); - propZsmall10.push("lrs+10_1:14_slsqr=3,4:drc=encompass:sil=4000:tgt=ground:sp=const_max:s2agt=16:slsqc=3:slsq=on:i=1157:kws=precedence:slsql=off:irc=lazy:rawr=on_0"); - propZsmall10.push("lrs+10_25:999_drc=encompass:sil=256000:tgt=full:spb=intro:i=1382:kws=precedence:awrs=converge:awrsf=53:irc=eager:bd=off:bs=unit_only_0"); - propZsmall10.push("ott+10_21691:1048576_drc=encompass:sil=256000:tgt=ground:sims=off:sp=occurrence:spb=goal_then_units:fd=preordered:i=2271:kws=precedence:av=off:fsr=off:uhcvi=on:fsd=on:fsdmm=2:slsq=on:slsql=off:slsqc=1:slsqr=320859,1048576:s2at=3.0:irc=lazy:rawr=on:ss=axioms:sd=2_0"); - propZsmall10.push("lrs+10_1:128_drc=encompass:sil=256000:tgt=full:sp=unary_frequency:spb=non_intro:i=2392:kws=precedence:irc=eager_0"); + propZsmall10.push("lrs+10_7:24_to=lpo:drc=encompass:sil=128000:fde=unused:sp=const_min:spb=goal:i=1061:crc=on:slsq=on:fdi=256:nwc=10.0:dpc=on:ss=included:st=2.0_0"); + propZsmall10.push("lrs+10_1:14_slsqr=3,4:drc=encompass:sil=4000:tgt=ground:sp=const_max:s2agt=16:slsqc=3:slsq=on:i=1157:kws=precedence:slsql=off:crc=on:rawr=on_0"); + propZsmall10.push("lrs+10_25:999_drc=encompass:sil=256000:tgt=full:spb=intro:i=1382:kws=precedence:awrs=converge:awrsf=53:crc=on:croc=on:bd=off:bs=unit_only_0"); + propZsmall10.push("ott+10_21691:1048576_drc=encompass:sil=256000:tgt=ground:sims=off:sp=occurrence:spb=goal_then_units:fd=preordered:i=2271:kws=precedence:av=off:fsr=off:uhcvi=on:fsd=on:fsdmm=2:slsq=on:slsql=off:slsqc=1:slsqr=320859,1048576:s2at=3.0:crc=on:rawr=on:ss=axioms:sd=2_0"); + propZsmall10.push("lrs+10_1:128_drc=encompass:sil=256000:tgt=full:sp=unary_frequency:spb=non_intro:i=2392:kws=precedence:crc=on:croc=on_0"); propZsmall10.push("ott+10_1:128_drc=encompass:sil=256000:plsq=on:s2a=on:i=2544:kws=precedence:dpc=on:bd=preordered:ss=axioms_0"); - propZsmall10.push("lrs+10_1:40_drc=encompass:sil=256000:tgt=full:sp=unary_frequency:spb=goal_then_units:i=5255:kws=frequency:rawr=on:irc=eager:fd=preordered_0"); + propZsmall10.push("lrs+10_1:40_drc=encompass:sil=256000:tgt=full:sp=unary_frequency:spb=goal_then_units:i=5255:kws=frequency:rawr=on:crc=on:croc=on:fd=preordered_0"); propZsmall10.push("ott+10_2:5_bsr=unit_only:to=lpo:drc=encompass:sil=256000:sp=reverse_frequency:i=2866:ins=1:dpc=on:rawr=on_0"); - propZsmall10.push("dis+10_1:1024_slsqr=5,2:sil=256000:tgt=ground:urr=on:slsqc=2:slsq=on:i=3253:ins=1:irc=lazy:rawr=on_0"); - propZsmall10.push("lrs+10_1:1024_slsqr=1,4:drc=encompass:sil=256000:tgt=full:sp=reverse_frequency:slsqc=4:slsq=on:s2a=on:i=7906:bd=off:irc=eager:ss=axioms:rawr=on:st=3.0:awrs=converge:foolp=on_0"); + propZsmall10.push("dis+10_1:1024_slsqr=5,2:sil=256000:tgt=ground:urr=on:slsqc=2:slsq=on:i=3253:ins=1:crc=on:rawr=on_0"); + propZsmall10.push("lrs+10_1:1024_slsqr=1,4:drc=encompass:sil=256000:tgt=full:sp=reverse_frequency:slsqc=4:slsq=on:s2a=on:i=7906:bd=off:crc=on:croc=on:ss=axioms:rawr=on:st=3.0:awrs=converge:foolp=on_0"); propZsmall10.push("ott+10_1:10_drc=encompass:sil=256000:sp=reverse_frequency:fd=preordered:i=4168:ins=2:bd=off:ss=axioms_0"); propZsmall10.push("lrs+10_1:6_drc=encompass:sil=32000:tgt=ground:s2agt=8:s2a=on:i=8705_0"); propZsmall10.push("dis+10_1:16_sil=256000:i=5821:bs=unit_only:rawr=on:plsq=on:to=lpo_0"); - propZsmall10.push("dis+10_8125:131072_drc=encompass:sil=256000:tgt=full:sp=occurrence:lma=on:fd=preordered:i=14311:kws=precedence:doe=on:awrs=decay:awrsf=50:dpc=on:uhcvi=on:ss=axioms:irc=lazy_0"); + propZsmall10.push("dis+10_8125:131072_drc=encompass:sil=256000:tgt=full:sp=occurrence:lma=on:fd=preordered:i=14311:kws=precedence:doe=on:awrs=decay:awrsf=50:dpc=on:uhcvi=on:ss=axioms:crc=on_0"); propZsmall10.push("ott+10_1:1_drc=encompass:sil=256000:plsq=on:fd=preordered:st=5.0:s2a=on:i=35818:ins=1:ss=axioms:rawr=on_0"); - propZsmall10.push("lrs+10_1:1_drc=encompass:sil=16000:fd=preordered:i=9154:bs=on:irc=lazy_0"); + propZsmall10.push("lrs+10_1:1_drc=encompass:sil=16000:fd=preordered:i=9154:bs=on:crc=on_0"); propZsmall10.push("lrs+10_1:16_drc=encompass:sil=16000:tgt=full:lwlo=on:s2pl=no:i=10003:av=off:rawr=on_0"); propZsmall10.push("ott+10_10:3_sil=256000:fde=unused:sp=frequency:spb=goal:i=11196:bs=on:kws=precedence:ins=1:dpc=on:rawr=on:nwc=3.0:drc=encompass_0"); - propZsmall10.push("lrs+10_1:1_drc=encompass:sil=256000:tgt=ground:sp=unary_first:sos=on:i=36276:kws=precedence:lwlo=on:irc=lazy_0"); - propZsmall10.push("lrs+10_13:1_bsr=on:drc=encompass:sil=64000:fd=preordered:i=12509:bd=off:irc=lazy_0"); - propZsmall10.push("lrs+10_3:14_drc=encompass:sil=128000:sp=const_frequency:spb=goal:lwlo=on:i=27445:kws=precedence:irc=lazy:nwc=5.0:awrs=decay:awrsf=255:s2pl=no:s2agt=32:fsd=on:fsr=off:lma=on_0"); + propZsmall10.push("lrs+10_1:1_drc=encompass:sil=256000:tgt=ground:sp=unary_first:sos=on:i=36276:kws=precedence:lwlo=on:crc=on_0"); + propZsmall10.push("lrs+10_13:1_bsr=on:drc=encompass:sil=64000:fd=preordered:i=12509:bd=off:crc=on_0"); + propZsmall10.push("lrs+10_3:14_drc=encompass:sil=128000:sp=const_frequency:spb=goal:lwlo=on:i=27445:kws=precedence:crc=on:nwc=5.0:awrs=decay:awrsf=255:s2pl=no:s2agt=32:fsd=on:fsr=off:lma=on_0"); propZsmall10.push("lrs+10_1:1024_sil=256000:lwlo=on:i=31665:kws=precedence:awrs=converge:awrsf=240:drc=encompass:fd=preordered:tgt=ground_0"); - propZsmall10.push("dis+10_1:256_to=lpo:drc=encompass:sil=256000:spb=goal:fd=preordered:i=18386:irc=eager:bs=unit_only_0"); - propZsmall10.push("dis+10_1:20_drc=encompass:sil=256000:tgt=full:sp=reverse_frequency:spb=intro:fd=preordered:i=22321:kws=precedence:irc=eager:ins=1_0"); + propZsmall10.push("dis+10_1:256_to=lpo:drc=encompass:sil=256000:spb=goal:fd=preordered:i=18386:crc=on:croc=on:bs=unit_only_0"); + propZsmall10.push("dis+10_1:20_drc=encompass:sil=256000:tgt=full:sp=reverse_frequency:spb=intro:fd=preordered:i=22321:kws=precedence:crc=on:croc=on:ins=1_0"); propZsmall10.push("dis+10_1:166_drc=encompass:sil=256000:tgt=full:i=26531:fsr=off:spb=non_intro:dpc=on:to=lpo:rawr=on_0"); propZsmall10.push("ott+10_1:4_drc=encompass:sil=256000:st=3.0:i=32454:ss=axioms:dpc=on:bd=preordered:slsq=on:slsqc=1:slsqr=1,2_0"); - propZsmall10.push("lrs+10_3:58_drc=encompass:sil=256000:tgt=full:bsd=on:sp=reverse_arity:lwlo=on:s2a=on:i=157761:s2at=2.0:kws=precedence:bsr=on:irw=on:dpc=on:doe=on:bs=on:br=off:erd=off:s2agt=20:nwc=8.95214440448525:cond=fast:foolp=on:spb=non_intro:sfv=off:irc=lazy:fde=unused:ins=3_0"); - propZsmall10.push("lrs+10_1:6_drc=encompass:sil=256000:tgt=full:spb=non_intro:i=82574:ins=2:irc=eager:ss=included:bd=preordered_0"); + propZsmall10.push("lrs+10_3:58_drc=encompass:sil=256000:tgt=full:bsd=on:sp=reverse_arity:lwlo=on:s2a=on:i=157761:s2at=2.0:kws=precedence:bsr=on:irw=on:dpc=on:doe=on:bs=on:br=off:erd=off:s2agt=20:nwc=8.95214440448525:cond=fast:foolp=on:spb=non_intro:sfv=off:crc=on:fde=unused:ins=3_0"); + propZsmall10.push("lrs+10_1:6_drc=encompass:sil=256000:tgt=full:spb=non_intro:i=82574:ins=2:crc=on:croc=on:ss=included:bd=preordered_0"); - propZsmall10.push("lrs+10_1:16_drc=encompass:sil=256000:tgt=full:spb=intro:i=58527:kws=precedence:awrs=converge:awrsf=200:ss=axioms:irc=eager:st=3.0:sp=unary_first_0"); - propZsmall10.push("lrs+10_1:12_drc=encompass:sil=256000:tgt=full:spb=intro:i=72339:kws=precedence:awrs=converge:awrsf=500:irc=lazy_0"); - propZsmall10.push("ott+10_11413117:1048576_drc=encompass:sil=256000:tgt=ground:fde=unused:plsqc=2:plsq=on:plsqr=1149513,1048576:sp=occurrence:nwc=9.10417:i=125323:kws=precedence:doe=on:awrs=converge:awrsf=286:bd=off:dpc=on:irc=eager:uhcvi=on:rawr=on:ss=included:st=2.0_0"); + propZsmall10.push("lrs+10_1:16_drc=encompass:sil=256000:tgt=full:spb=intro:i=58527:kws=precedence:awrs=converge:awrsf=200:ss=axioms:crc=on:croc=on:st=3.0:sp=unary_first_0"); + propZsmall10.push("lrs+10_1:12_drc=encompass:sil=256000:tgt=full:spb=intro:i=72339:kws=precedence:awrs=converge:awrsf=500:crc=on_0"); + propZsmall10.push("ott+10_11413117:1048576_drc=encompass:sil=256000:tgt=ground:fde=unused:plsqc=2:plsq=on:plsqr=1149513,1048576:sp=occurrence:nwc=9.10417:i=125323:kws=precedence:doe=on:awrs=converge:awrsf=286:bd=off:dpc=on:crc=on:croc=on:uhcvi=on:rawr=on:ss=included:st=2.0_0"); propZsmall10.push("lrs+10_54503:1048576_drc=encompass:sil=256000:tgt=ground:bsd=on:sp=reverse_frequency:lwlo=on:st=3.5:s2a=on:i=174981:s2at=5.5:kws=precedence:ss=included:sgt=50:bsr=unit_only:irw=on:dpc=on:uhcvi=on:doe=on:bs=on:br=off:erd=off_0"); // total_instr 1391316 // len(covered) 365 - propZbig10.push("lrs+10_1:12_drc=encompass:sil=256000:tgt=full:spb=intro:i=116130:kws=precedence:awrs=converge:awrsf=500:irc=lazy_0"); + propZbig10.push("lrs+10_1:12_drc=encompass:sil=256000:tgt=full:spb=intro:i=116130:kws=precedence:awrs=converge:awrsf=500:crc=on_0"); propZbig10.push("dis+10_5:2_drc=encompass:sil=256000:tgt=ground:sp=reverse_frequency:sos=all:i=207332:bd=off:fsr=off:dpc=on_0"); propZbig10.push("lrs+10_1:64_drc=encompass:sil=2000:i=105:plsq=on:ss=axioms_0"); - propZbig10.push("lrs+10_3:4_to=lpo:drc=encompass:sil=4000:sp=reverse_frequency:i=126:ss=axioms:sgt=16:s2a=on:s2at=3.0:irc=lazy:bd=off_0"); + propZbig10.push("lrs+10_3:4_to=lpo:drc=encompass:sil=4000:sp=reverse_frequency:i=126:ss=axioms:sgt=16:s2a=on:s2at=3.0:crc=on:bd=off_0"); propZbig10.push("ott+10_2:5_bsr=unit_only:to=lpo:drc=encompass:sil=256000:sp=reverse_frequency:i=150:ins=1:dpc=on:rawr=on_0"); propZbig10.push("lrs+10_1:8_drc=encompass:sil=16000:tgt=ground:i=123:bd=preordered:ss=axioms_0"); propZbig10.push("lrs+10_1:1_drc=encompass:sil=4000:i=209:ss=axioms:sgt=8:sp=occurrence_0"); propZbig10.push("lrs+10_1:4_drc=encompass:sil=16000:tgt=ground:lwlo=on:s2a=on:i=192:s2at=2.0_0"); propZbig10.push("lrs+10_1:7_drc=encompass:sil=64000:tgt=full:spb=non_intro:i=454:awrs=converge:awrsf=67:sp=reverse_frequency:nwc=1.5_0"); - propZbig10.push("lrs+10_1:2_sil=2000:tgt=ground:spb=goal:i=359:kws=precedence:irc=eager_0"); + propZbig10.push("lrs+10_1:2_sil=2000:tgt=ground:spb=goal:i=359:kws=precedence:crc=on:croc=on_0"); propZbig10.push("lrs+10_1:1_sil=4000:sp=occurrence:i=163:ss=axioms:st=3.0:sd=2_0"); propZbig10.push("lrs+10_1:1024_drc=encompass:sil=4000:tgt=full:i=1030:kws=inv_frequency:awrs=converge_0"); - propZbig10.push("lrs+10_3:1_sil=4000:tgt=ground:i=631:kws=frequency:bd=off:drc=encompass:irc=lazy_0"); + propZbig10.push("lrs+10_3:1_sil=4000:tgt=ground:i=631:kws=frequency:bd=off:drc=encompass:crc=on_0"); propZbig10.push("lrs+10_1:3_to=lpo:drc=encompass:sil=4000:tgt=full:i=901:rawr=on:ins=4:bd=off:fd=preordered_0"); - propZbig10.push("lrs+10_1:24_drc=encompass:sil=256000:tgt=full:sp=unary_frequency:spb=non_intro:i=312:ins=2:fsr=off:kws=precedence:irc=eager:bsr=unit_only:br=off:ss=included:sgt=16:bd=preordered_0"); + propZbig10.push("lrs+10_1:24_drc=encompass:sil=256000:tgt=full:sp=unary_frequency:spb=non_intro:i=312:ins=2:fsr=off:kws=precedence:crc=on:croc=on:bsr=unit_only:br=off:ss=included:sgt=16:bd=preordered_0"); propZbig10.push("lrs+10_1:1_drc=encompass:sil=2000:slsq=on:s2a=on:i=1363:s2at=7.0_0"); - propZbig10.push("ott+10_8:1_drc=encompass:sil=256000:i=471:rawr=on:irc=lazy_0"); + propZbig10.push("ott+10_8:1_drc=encompass:sil=256000:i=471:rawr=on:crc=on_0"); propZbig10.push("lrs+10_1:4_drc=encompass:sil=4000:tgt=full:sp=reverse_arity:st=-1.0:i=2897:kws=precedence:ss=included:lwlo=on:rawr=on:bd=off:urr=on:bsd=on_0"); propZbig10.push("lrs+10_1:12_sil=2000:tgt=full:sp=reverse_frequency:i=569:kws=inv_frequency:bd=off:fsr=off:rawr=on:awrs=converge_0"); - propZbig10.push("lrs+10_1:1_drc=encompass:sil=2000:st=5.0:s2a=on:i=577:s2at=5.0:sd=1:bd=preordered:irc=lazy:ss=axioms:sgt=10_0"); - propZbig10.push("lrs+10_8:1_drc=encompass:sil=4000:tgt=ground:spb=non_intro:i=843:bd=off:irc=lazy_0"); + propZbig10.push("lrs+10_1:1_drc=encompass:sil=2000:st=5.0:s2a=on:i=577:s2at=5.0:sd=1:bd=preordered:crc=on:ss=axioms:sgt=10_0"); + propZbig10.push("lrs+10_8:1_drc=encompass:sil=4000:tgt=ground:spb=non_intro:i=843:bd=off:crc=on_0"); propZbig10.push("lrs+10_1:1_drc=encompass:sil=2000:tgt=ground:st=5.0:i=1015:bd=off:ss=axioms_0"); - propZbig10.push("lrs+10_15:26_drc=encompass:sil=16000:i=4402:ins=4:irc=lazy_0"); - propZbig10.push("lrs+10_16:1_to=lpo:sil=32000:urr=ec_only:fd=preordered:nwc=10.0:i=1315:bd=off:irc=lazy:drc=encompass_0"); + propZbig10.push("lrs+10_15:26_drc=encompass:sil=16000:i=4402:ins=4:crc=on_0"); + propZbig10.push("lrs+10_16:1_to=lpo:sil=32000:urr=ec_only:fd=preordered:nwc=10.0:i=1315:bd=off:crc=on:drc=encompass_0"); propZbig10.push("lrs+10_8:1_drc=encompass:sil=256000:st=3.0:s2a=on:i=2957:s2at=1.2:ss=axioms:sd=15_0"); - propZbig10.push("lrs+10_3:1_drc=encompass:sil=4000:tgt=full:sp=unary_first:sos=all:lwlo=on:i=3869:irc=lazy_0"); + propZbig10.push("lrs+10_3:1_drc=encompass:sil=4000:tgt=full:sp=unary_first:sos=all:lwlo=on:i=3869:crc=on_0"); propZbig10.push("lrs+10_1:1_drc=encompass:sil=256000:tgt=ground:s2agt=8:s2a=on:i=2041_0"); propZbig10.push("ott+10_1:28_sil=256000:tgt=full:fd=preordered:i=6716:bd=off_0"); - propZbig10.push("ott+10_1:14_bsr=unit_only:sil=256000:i=2510:sp=weighted_frequency:irc=lazy_0"); + propZbig10.push("ott+10_1:14_bsr=unit_only:sil=256000:i=2510:sp=weighted_frequency:crc=on_0"); propZbig10.push("lrs+10_1:10_drc=encompass:sil=16000:tgt=ground:plsq=on:fd=preordered:i=3229:bd=preordered:ins=1:rawr=on:ss=axioms:sgt=16_0"); propZbig10.push("lrs+10_1:16_drc=encompass:sil=16000:sp=unary_frequency:i=7440:kws=precedence_0"); propZbig10.push("ott+10_1:64_sil=256000:tgt=full:i=10214:sp=reverse_frequency:bd=off:drc=encompass_0"); - propZbig10.push("lrs+10_3:14_drc=encompass:sil=128000:sp=const_frequency:spb=goal:lwlo=on:i=29852:kws=precedence:irc=lazy:ins=4_0"); + propZbig10.push("lrs+10_3:14_drc=encompass:sil=128000:sp=const_frequency:spb=goal:lwlo=on:i=29852:kws=precedence:crc=on:ins=4_0"); propZbig10.push("lrs+10_1:6_drc=encompass:sil=32000:tgt=ground:s2agt=8:s2a=on:i=24503_0"); - propZbig10.push("dis+10_1:4_to=lpo:sil=256000:tgt=full:sp=reverse_frequency:spb=goal:i=11902:awrs=converge:awrsf=500:fd=preordered:irc=lazy:bd=off_0"); + propZbig10.push("dis+10_1:4_to=lpo:sil=256000:tgt=full:sp=reverse_frequency:spb=goal:i=11902:awrs=converge:awrsf=500:fd=preordered:crc=on:bd=off_0"); propZbig10.push("dis+10_1:4_drc=encompass:sil=256000:tgt=ground:sos=all:i=13038:kws=inv_arity_squared:fsr=off:dpc=on_0"); propZbig10.push("lrs+10_1:16_drc=encompass:sil=32000:sp=reverse_frequency:spb=goal:i=28291:kws=inv_arity_squared_0"); propZbig10.push("dis+10_1:166_drc=encompass:sil=256000:tgt=full:i=19584:fsr=off:spb=non_intro:kws=inv_frequency_0"); - propZbig10.push("lrs+10_1:34_drc=encompass:sil=64000:tgt=ground:lwlo=on:i=37491:kws=frequency:irc=eager_0"); + propZbig10.push("lrs+10_1:34_drc=encompass:sil=64000:tgt=ground:lwlo=on:i=37491:kws=frequency:crc=on:croc=on_0"); propZbig10.push("dis+10_1:64_sil=256000:tgt=full:sp=const_frequency:sos=on:i=57866:bs=on_0"); propZbig10.push("lrs+10_1:1024_drc=encompass:sil=128000:tgt=ground:sp=frequency:i=58321:kws=precedence_0"); propZbig10.push("dis+10_1:166_drc=encompass:sil=256000:tgt=full:i=78078:fsr=off:spb=non_intro:dpc=on:to=lpo:rawr=on_0"); @@ -6284,20 +6284,20 @@ void Schedules::getCasc2024Schedule(const Property& property, Schedule& quick, S propNZsmall14.push("lrs+10_16:7_drc=encompass:sil=128000:sp=weighted_frequency:lwlo=on:i=118:bs=on:to=lpo:tgt=full:bd=off_0"); propNZsmall14.push("dis+10_1:1_sil=256000:nwc=10.0:s2agt=32:s2a=on:i=156:fde=none:fd=off_0"); propNZsmall14.push("lrs+10_1:1024_sil=2000:slsqc=1:slsq=on:i=167:rawr=on:bd=off_0"); - propNZsmall14.push("lrs+10_1:64_sil=32000:tgt=ground:spb=goal_then_units:urr=on:i=687:awrs=converge:awrsf=130:rawr=on:plsq=on:sp=const_frequency:bd=off:drc=encompass:irc=lazy:kws=precedence_0"); - propNZsmall14.push("dis+10_5:1_to=lpo:sil=256000:tgt=ground:spb=intro:i=187:bd=off:irc=lazy:rawr=on:fd=preordered:drc=encompass_0"); + propNZsmall14.push("lrs+10_1:64_sil=32000:tgt=ground:spb=goal_then_units:urr=on:i=687:awrs=converge:awrsf=130:rawr=on:plsq=on:sp=const_frequency:bd=off:drc=encompass:crc=on:kws=precedence_0"); + propNZsmall14.push("dis+10_5:1_to=lpo:sil=256000:tgt=ground:spb=intro:i=187:bd=off:crc=on:rawr=on:fd=preordered:drc=encompass_0"); propNZsmall14.push("lrs+10_2:1_to=lpo:drc=encompass:sil=8000:tgt=full:sp=const_frequency:i=189:lwlo=on:nwc=10.0:rawr=on_0"); - propNZsmall14.push("dis+10_1:50_sil=256000:nwc=4.1:i=315:bd=off:irc=eager:fd=off_0"); + propNZsmall14.push("dis+10_1:50_sil=256000:nwc=4.1:i=315:bd=off:crc=on:croc=on:fd=off_0"); propNZsmall14.push("ott+10_2:5_bsr=unit_only:to=lpo:drc=encompass:sil=256000:sp=reverse_frequency:i=323:ins=1:dpc=on:rawr=on_0"); propNZsmall14.push("lrs+10_1:16_drc=encompass:sil=32000:sp=reverse_frequency:spb=goal:i=252:kws=inv_arity_squared_0"); propNZsmall14.push("lrs+10_1:8_sil=2000:nwc=3.0:i=263:bd=off:fsr=off:rawr=on:sp=occurrence:fd=off:kws=inv_precedence_0"); propNZsmall14.push("ott+10_1:28_sil=256000:tgt=full:fd=preordered:i=1545:bd=off_0"); - propNZsmall14.push("lrs+10_1:1_drc=encompass:sil=2000:st=5.0:s2a=on:i=303:s2at=5.0:sd=1:bd=preordered:irc=lazy:ss=axioms:sgt=10_0"); + propNZsmall14.push("lrs+10_1:1_drc=encompass:sil=2000:st=5.0:s2a=on:i=303:s2at=5.0:sd=1:bd=preordered:crc=on:ss=axioms:sgt=10_0"); propNZsmall14.push("ott+10_1:4_drc=encompass:sil=256000:st=3.0:i=1804:ss=axioms:dpc=on:bd=preordered:slsq=on:slsqc=1:slsqr=1,2_0"); propNZsmall14.push("dis+10_1:12_slsqr=20,127:sil=256000:fd=off:slsqc=1:slsq=on:i=390:rawr=on:bsr=on_0"); propNZsmall14.push("dis+10_1:16_slsqr=167,244:drc=encompass:sil=256000:slsqc=1:slsq=on:i=480:kws=inv_arity:awrs=converge:slsql=off:awrsf=61:bd=off:ins=2:rawr=on_0"); - propNZsmall14.push("dis+10_1:2_to=lpo:sil=256000:i=1649:irc=eager:fd=preordered_0"); - propNZsmall14.push("dis+10_4:1_to=lpo:sil=256000:tgt=ground:spb=goal:fd=preordered:i=525:irc=lazy_0"); + propNZsmall14.push("dis+10_1:2_to=lpo:sil=256000:i=1649:crc=on:croc=on:fd=preordered_0"); + propNZsmall14.push("dis+10_4:1_to=lpo:sil=256000:tgt=ground:spb=goal:fd=preordered:i=525:crc=on_0"); propNZsmall14.push("lrs+10_8:1_drc=encompass:sil=256000:st=3.0:s2a=on:i=585:s2at=1.2:ss=axioms:sd=15_0"); propNZsmall14.push("lrs+10_16:1_bsr=on:drc=encompass:sil=64000:i=715:bd=off:to=lpo_0"); propNZsmall14.push("lrs+10_1:1_slsqr=455249,524288:drc=encompass:sil=2000:tgt=ground:bsd=on:plsq=on:plsqr=32,1:urr=ec_only:slsqc=1:slsq=on:s2a=on:i=770:kws=precedence:slsql=off:rawr=on_0"); @@ -6306,62 +6306,62 @@ void Schedules::getCasc2024Schedule(const Property& property, Schedule& quick, S propNZsmall14.push("dis+10_1:16_to=lpo:drc=encompass:sil=256000:tgt=ground:plsq=on:plsqr=1,32:sp=unary_frequency:s2a=on:i=939:awrs=converge:awrsf=340:rawr=on:s2at=2.0_0"); propNZsmall14.push("lrs+10_1:1024_sil=2000:tgt=ground:plsq=on:sp=frequency:s2a=on:i=1017:kws=precedence:rawr=on:bd=off:awrs=converge:awrsf=10:ins=2_0"); propNZsmall14.push("dis+10_1:14_bsr=unit_only:to=lpo:drc=encompass:sil=256000:tgt=ground:urr=on:slsq=on:i=1831:awrs=converge:awrsf=50:rawr=on:fsr=off_0"); - propNZsmall14.push("lrs+10_1:1_drc=encompass:sil=32000:tgt=ground:sp=unary_frequency:lwlo=on:i=22426:irc=eager:kws=precedence_0"); + propNZsmall14.push("lrs+10_1:1_drc=encompass:sil=32000:tgt=ground:sp=unary_frequency:lwlo=on:i=22426:crc=on:croc=on:kws=precedence_0"); propNZsmall14.push("ott+10_1:6_drc=encompass:sil=256000:tgt=ground:fde=none:plsq=on:sp=weighted_frequency:s2a=on:i=2595:s2at=2.0:kws=precedence:bd=off:ins=4:dpc=on:ss=axioms:sgt=16:rawr=on_0"); propNZsmall14.push("ott+10_1:128_slsqr=1,2:drc=encompass:sil=256000:fde=unused:sp=frequency:slsq=on:i=2907:slsql=off_0"); propNZsmall14.push("dis+10_35:501_sil=256000:tgt=ground:sp=const_max:i=28204:kws=precedence:awrs=decay:awrsf=300_0"); propNZsmall14.push("lrs+10_1:128_drc=encompass:sil=16000:sp=const_frequency:i=11308:kws=precedence:slsq=on_0"); propNZsmall14.push("dis+10_1:12_sil=256000:tgt=ground:fde=unused:i=6021:s2a=on:s2agt=8_0"); - propNZsmall14.push("lrs+10_16:1_to=lpo:sil=32000:urr=ec_only:fd=preordered:nwc=10.0:i=15430:bd=off:irc=lazy:drc=encompass_0"); + propNZsmall14.push("lrs+10_16:1_to=lpo:sil=32000:urr=ec_only:fd=preordered:nwc=10.0:i=15430:bd=off:crc=on:drc=encompass_0"); propNZsmall14.push("ott+10_2:9_drc=encompass:sil=128000:tgt=full:sp=frequency:nwc=5.0:st=3.0:i=57775:kws=precedence:bd=preordered:dpc=on:ss=axioms:rawr=on:rnwc=on_0"); propNZsmall14.push("dis+10_1:128_drc=encompass:sil=256000:nwc=6.0:i=21529:fsr=off_0"); propNZsmall14.push("dis+10_1:1_drc=encompass:sil=256000:tgt=full:i=76551:to=lpo:fde=unused_0"); propNZsmall14.push("dis+10_1:54_sil=256000:tgt=ground:plsq=on:plsqr=9145955,131072:sp=frequency:spb=goal_then_units:plsql=on:i=50725:doe=on:ins=3:rawr=on:slsq=on:slsqr=1,4:s2at=2.0:slsqc=1_0"); - propNZsmall14.push("lrs+10_1:28_drc=encompass:sil=256000:tgt=full:spb=intro:i=81856:kws=precedence:awrs=converge:awrsf=240:ss=axioms:rawr=on:irc=lazy:st=3.0:sp=const_frequency_0"); + propNZsmall14.push("lrs+10_1:28_drc=encompass:sil=256000:tgt=full:spb=intro:i=81856:kws=precedence:awrs=converge:awrsf=240:ss=axioms:rawr=on:crc=on:st=3.0:sp=const_frequency_0"); propNZsmall14.push("lrs+10_1:4_to=lpo:sil=256000:tgt=ground:sp=reverse_arity:spb=goal_then_units:i=106211:fdi=10:bs=unit_only:s2a=on_0"); // total_instr 925456 // len(covered) 301 - propNZbig14.push("dis+10_28091:1048576_to=lpo:drc=encompass:sil=128000:tgt=full:erd=off:cond=on:i=107869:doe=on:ins=2:av=off:dpc=on:irc=eager:s2pl=on:s2agt=5:s2at=4.0:foolp=on_0"); - propNZbig14.push("lrs+10_1:1_drc=encompass:sil=256000:tgt=ground:sp=unary_first:sos=on:i=220312:kws=precedence:lwlo=on:irc=lazy_0"); + propNZbig14.push("dis+10_28091:1048576_to=lpo:drc=encompass:sil=128000:tgt=full:erd=off:cond=on:i=107869:doe=on:ins=2:av=off:dpc=on:crc=on:croc=on:s2pl=on:s2agt=5:s2at=4.0:foolp=on_0"); + propNZbig14.push("lrs+10_1:1_drc=encompass:sil=256000:tgt=ground:sp=unary_first:sos=on:i=220312:kws=precedence:lwlo=on:crc=on_0"); - propNZbig14.push("lrs+10_16:1_sfv=off:sil=2000:sp=reverse_frequency:urr=ec_only:br=off:i=126:doe=on:irc=lazy:to=lpo:fd=preordered:bd=preordered:fsd=on:drc=encompass_0"); + propNZbig14.push("lrs+10_16:1_sfv=off:sil=2000:sp=reverse_frequency:urr=ec_only:br=off:i=126:doe=on:crc=on:to=lpo:fd=preordered:bd=preordered:fsd=on:drc=encompass_0"); propNZbig14.push("lrs+10_3:107_sil=64000:i=143:ss=axioms:sgt=16:rawr=on:to=lpo:drc=encompass_0"); propNZbig14.push("lrs+10_2:1_to=lpo:drc=encompass:sil=4000:tgt=full:sp=const_min:urr=on:nwc=5.0:i=129:rawr=on_0"); - propNZbig14.push("lrs+10_1:12_drc=encompass:sil=256000:tgt=full:spb=intro:i=735:kws=precedence:awrs=converge:awrsf=500:irc=lazy_0"); - propNZbig14.push("dis+10_577:524288_drc=encompass:sil=256000:sp=const_frequency:spb=units:i=214:doe=on:bd=off:av=off:dpc=on:irc=eager:uhcvi=on:ss=included:rawr=on:to=lpo:slsq=on:slsqr=8,31:s2agt=5:s2at=4.0:fdi=2_0"); - propNZbig14.push("lrs+10_1:64_sil=8000:tgt=full:spb=non_intro:i=204:kws=precedence:plsq=on:awrs=converge:awrsf=30:sp=weighted_frequency:drc=encompass:irc=eager_0"); - propNZbig14.push("lrs+10_1:1_to=lpo:drc=encompass:sil=2000:fde=unused:sp=const_min:i=444:fd=preordered:irc=eager:bd=preordered:ss=axioms_0"); - propNZbig14.push("lrs+10_3:58_drc=encompass:sil=256000:tgt=full:bsd=on:sp=reverse_arity:lwlo=on:s2a=on:i=365:s2at=2.0:kws=precedence:bsr=on:irw=on:dpc=on:doe=on:bs=on:br=off:erd=off:s2agt=20:nwc=8.95214440448525:cond=fast:foolp=on:spb=non_intro:sfv=off:irc=lazy:fde=unused:ins=3_0"); - propNZbig14.push("lrs+10_3:4_to=lpo:drc=encompass:sil=4000:sp=reverse_frequency:i=390:ss=axioms:sgt=16:s2a=on:s2at=3.0:irc=lazy:bd=off_0"); + propNZbig14.push("lrs+10_1:12_drc=encompass:sil=256000:tgt=full:spb=intro:i=735:kws=precedence:awrs=converge:awrsf=500:crc=on_0"); + propNZbig14.push("dis+10_577:524288_drc=encompass:sil=256000:sp=const_frequency:spb=units:i=214:doe=on:bd=off:av=off:dpc=on:crc=on:croc=on:uhcvi=on:ss=included:rawr=on:to=lpo:slsq=on:slsqr=8,31:s2agt=5:s2at=4.0:fdi=2_0"); + propNZbig14.push("lrs+10_1:64_sil=8000:tgt=full:spb=non_intro:i=204:kws=precedence:plsq=on:awrs=converge:awrsf=30:sp=weighted_frequency:drc=encompass:crc=on:croc=on_0"); + propNZbig14.push("lrs+10_1:1_to=lpo:drc=encompass:sil=2000:fde=unused:sp=const_min:i=444:fd=preordered:crc=on:croc=on:bd=preordered:ss=axioms_0"); + propNZbig14.push("lrs+10_3:58_drc=encompass:sil=256000:tgt=full:bsd=on:sp=reverse_arity:lwlo=on:s2a=on:i=365:s2at=2.0:kws=precedence:bsr=on:irw=on:dpc=on:doe=on:bs=on:br=off:erd=off:s2agt=20:nwc=8.95214440448525:cond=fast:foolp=on:spb=non_intro:sfv=off:crc=on:fde=unused:ins=3_0"); + propNZbig14.push("lrs+10_3:4_to=lpo:drc=encompass:sil=4000:sp=reverse_frequency:i=390:ss=axioms:sgt=16:s2a=on:s2at=3.0:crc=on:bd=off_0"); propNZbig14.push("lrs+10_1:4_to=lpo:drc=encompass:sil=4000:tgt=full:i=2789:bd=preordered:fd=preordered_0"); - propNZbig14.push("lrs+10_1:3_drc=encompass:sil=256000:tgt=ground:sp=unary_first:i=975:ss=axioms:sgt=10:rawr=on:urr=on:ins=1:plsq=on:dpc=on:spb=intro:sd=4:fsr=off:bs=on:kws=inv_arity:irc=lazy:nwc=5.0_0"); - propNZbig14.push("lrs+10_1:24_drc=encompass:sil=256000:tgt=full:sp=unary_frequency:spb=non_intro:i=6970:ins=2:fsr=off:kws=precedence:irc=eager:bsr=unit_only:br=off:ss=included:sgt=16:bd=preordered_0"); - propNZbig14.push("lrs+10_7:24_to=lpo:drc=encompass:sil=128000:fde=unused:sp=const_min:spb=goal:i=522:irc=lazy:slsq=on:fdi=256:nwc=10.0:dpc=on:ss=included:st=2.0_0"); - propNZbig14.push("lrs+10_1:1024_drc=encompass:sil=8000:tgt=ground:fde=unused:sp=const_min:spb=goal:kmz=on:i=1381:kws=inv_arity:awrs=converge:awrsf=200:irc=eager_0"); - propNZbig14.push("lrs+10_1:4_to=lpo:drc=encompass:sil=128000:fde=unused:sp=const_min:spb=goal:fd=preordered:i=589:irc=lazy:slsq=on:slsqr=1,4_0"); - propNZbig14.push("lrs+10_1:4_bsr=on:slsqr=2,7:to=lpo:drc=encompass:sil=16000:tgt=full:sp=unary_first:spb=goal:slsq=on:i=659:slsql=off:ins=2:irc=eager:rawr=on:nwc=8.7296035496261:erd=off:s2pl=no:cond=fast:plsq=on:sims=off_0"); + propNZbig14.push("lrs+10_1:3_drc=encompass:sil=256000:tgt=ground:sp=unary_first:i=975:ss=axioms:sgt=10:rawr=on:urr=on:ins=1:plsq=on:dpc=on:spb=intro:sd=4:fsr=off:bs=on:kws=inv_arity:crc=on:nwc=5.0_0"); + propNZbig14.push("lrs+10_1:24_drc=encompass:sil=256000:tgt=full:sp=unary_frequency:spb=non_intro:i=6970:ins=2:fsr=off:kws=precedence:crc=on:croc=on:bsr=unit_only:br=off:ss=included:sgt=16:bd=preordered_0"); + propNZbig14.push("lrs+10_7:24_to=lpo:drc=encompass:sil=128000:fde=unused:sp=const_min:spb=goal:i=522:crc=on:slsq=on:fdi=256:nwc=10.0:dpc=on:ss=included:st=2.0_0"); + propNZbig14.push("lrs+10_1:1024_drc=encompass:sil=8000:tgt=ground:fde=unused:sp=const_min:spb=goal:kmz=on:i=1381:kws=inv_arity:awrs=converge:awrsf=200:crc=on:croc=on_0"); + propNZbig14.push("lrs+10_1:4_to=lpo:drc=encompass:sil=128000:fde=unused:sp=const_min:spb=goal:fd=preordered:i=589:crc=on:slsq=on:slsqr=1,4_0"); + propNZbig14.push("lrs+10_1:4_bsr=on:slsqr=2,7:to=lpo:drc=encompass:sil=16000:tgt=full:sp=unary_first:spb=goal:slsq=on:i=659:slsql=off:ins=2:crc=on:croc=on:rawr=on:nwc=8.7296035496261:erd=off:s2pl=no:cond=fast:plsq=on:sims=off_0"); propNZbig14.push("lrs+10_1:1_sil=4000:sp=occurrence:i=1397:ss=axioms:st=3.0:sd=2_0"); propNZbig14.push("lrs+10_15:74_drc=encompass:sil=4000:tgt=full:fde=none:sp=const_min:i=856:kws=inv_frequency:awrs=converge:awrsf=120:rawr=on:nwc=0.9964432792968732:fsr=off:urr=on_0"); - propNZbig14.push("lrs+10_1:28_drc=encompass:sil=256000:tgt=full:spb=intro:i=918:kws=precedence:awrs=converge:awrsf=240:ss=axioms:rawr=on:irc=lazy:st=3.0:sp=const_frequency_0"); + propNZbig14.push("lrs+10_1:28_drc=encompass:sil=256000:tgt=full:spb=intro:i=918:kws=precedence:awrs=converge:awrsf=240:ss=axioms:rawr=on:crc=on:st=3.0:sp=const_frequency_0"); propNZbig14.push("lrs+10_1:25_to=lpo:drc=encompass:sil=2000:fde=none:sp=const_min:fd=preordered:i=1093_0"); - propNZbig14.push("ott+10_1:2_sil=256000:tgt=ground:sp=reverse_frequency:spb=goal:i=1333:kws=precedence:irc=lazy_0"); - propNZbig14.push("lrs+10_1:1_drc=encompass:sil=32000:tgt=ground:sp=unary_frequency:lwlo=on:i=23534:irc=eager:kws=precedence_0"); + propNZbig14.push("ott+10_1:2_sil=256000:tgt=ground:sp=reverse_frequency:spb=goal:i=1333:kws=precedence:crc=on_0"); + propNZbig14.push("lrs+10_1:1_drc=encompass:sil=32000:tgt=ground:sp=unary_frequency:lwlo=on:i=23534:crc=on:croc=on:kws=precedence_0"); propNZbig14.push("dis+10_1:1_sil=256000:nwc=10.0:s2agt=32:s2a=on:i=1724:fde=none:fd=off_0"); propNZbig14.push("lrs+10_11:1_sil=4000:fde=none:nwc=5.0:st=3.0:i=1762:bd=off:ss=axioms:fd=off_0"); propNZbig14.push("lrs+10_8:1_drc=encompass:sil=256000:st=3.0:s2a=on:i=3083:s2at=1.2:ss=axioms:sd=15_0"); - propNZbig14.push("lrs+10_1:64_drc=encompass:sil=16000:tgt=full:sp=reverse_frequency:slsq=on:i=4105:kws=precedence:slsql=off:ss=axioms:bs=unit_only:irc=lazy:spb=goal_0"); + propNZbig14.push("lrs+10_1:64_drc=encompass:sil=16000:tgt=full:sp=reverse_frequency:slsq=on:i=4105:kws=precedence:slsql=off:ss=axioms:bs=unit_only:crc=on:spb=goal_0"); propNZbig14.push("lrs+10_1:4_drc=encompass:sil=32000:tgt=full:fde=unused:sp=const_frequency:nwc=10.0:i=9762:dpc=on:rawr=on:bd=preordered:to=lpo_0"); - propNZbig14.push("lrs+10_1:27_bsr=unit_only:to=lpo:drc=encompass:sil=128000:fde=unused:sp=const_min:spb=goal:fd=preordered:i=9874:bs=on:dpc=on:uhcvi=on:rawr=on:irc=lazy:er=filter:erape=on:erml=3_0"); + propNZbig14.push("lrs+10_1:27_bsr=unit_only:to=lpo:drc=encompass:sil=128000:fde=unused:sp=const_min:spb=goal:fd=preordered:i=9874:bs=on:dpc=on:uhcvi=on:rawr=on:crc=on:er=filter:erape=on:erml=3_0"); propNZbig14.push("lrs+10_1:4_drc=encompass:sil=16000:tgt=ground:lwlo=on:s2a=on:i=7263:s2at=2.0_0"); propNZbig14.push("lrs+10_2:3_sil=128000:fde=none:s2a=on:i=13654:s2at=3.0:lwlo=on:bd=off_0"); - propNZbig14.push("lrs+10_1:16_drc=encompass:sil=256000:tgt=full:spb=intro:i=41528:kws=precedence:awrs=converge:awrsf=200:ss=axioms:irc=eager:st=3.0:sp=const_frequency_0"); - propNZbig14.push("dis+10_1:32_drc=encompass:sil=256000:tgt=ground:sp=const_frequency:spb=goal:i=32120:kws=precedence:bd=off:dpc=on:irc=lazy:s2a=on:s2at=3.0_0"); + propNZbig14.push("lrs+10_1:16_drc=encompass:sil=256000:tgt=full:spb=intro:i=41528:kws=precedence:awrs=converge:awrsf=200:ss=axioms:crc=on:croc=on:st=3.0:sp=const_frequency_0"); + propNZbig14.push("dis+10_1:32_drc=encompass:sil=256000:tgt=ground:sp=const_frequency:spb=goal:i=32120:kws=precedence:bd=off:dpc=on:crc=on:s2a=on:s2at=3.0_0"); propNZbig14.push("ott+10_1:6_drc=encompass:sil=512000:tgt=ground:fde=unused:sp=const_min:spb=goal:nwc=1.1:i=95210:kws=precedence:dpc=on_0"); - propNZbig14.push("lrs+10_1:32_sil=64000:tgt=full:sp=frequency:lwlo=on:i=51758:irc=eager_0"); - propNZbig14.push("lrs+10_2:23_drc=encompass:sil=256000:tgt=full:s2a=on:i=126830:s2at=2.0:irc=lazy:dpc=on_0"); - propNZbig14.push("lrs+10_1:24_bsr=unit_only:to=lpo:drc=encompass:sil=128000:fde=unused:sp=const_min:spb=goal:fd=preordered:i=67476:bs=on:dpc=on:rawr=on:irc=lazy:er=filter:erape=on:nwc=3.0:ss=axioms:st=6.0:urr=ec_only_0"); + propNZbig14.push("lrs+10_1:32_sil=64000:tgt=full:sp=frequency:lwlo=on:i=51758:crc=on:croc=on_0"); + propNZbig14.push("lrs+10_2:23_drc=encompass:sil=256000:tgt=full:s2a=on:i=126830:s2at=2.0:crc=on:dpc=on_0"); + propNZbig14.push("lrs+10_1:24_bsr=unit_only:to=lpo:drc=encompass:sil=128000:fde=unused:sp=const_min:spb=goal:fd=preordered:i=67476:bs=on:dpc=on:rawr=on:crc=on:er=filter:erape=on:nwc=3.0:ss=axioms:st=6.0:urr=ec_only_0"); propNZbig14.push("lrs+10_1:3_drc=encompass:sil=256000:tgt=full:fd=preordered:s2a=on:i=85601:s2at=4.0_0"); // total_instr 925697 diff --git a/Shell/ConditionalRedundancyHandler.cpp b/Shell/ConditionalRedundancyHandler.cpp index e1d9fce44..8d9c08821 100644 --- a/Shell/ConditionalRedundancyHandler.cpp +++ b/Shell/ConditionalRedundancyHandler.cpp @@ -336,7 +336,7 @@ void ConditionalRedundancyHandlerImpl::insertSuper Applicator appl(subs, !eqIsResult); auto doInsert = eqClause->length()==1 && eqClause->noSplits() && - ((!ordC && rwTermS.containsAllVariablesOf(tgtTermS)) || eqComp == Ordering::LESS) && + // TODO this demodulation redundancy check could be added as constraints (!_demodulationHelper.redundancyCheckNeededForPremise(rwClause, rwLitS, rwTermS) || // TODO for rwClause->length()!=1 the function isPremiseRedundant does not work yet (rwClause->length()==1 && _demodulationHelper.isPremiseRedundant(rwClause, rwLitS, rwTermS, tgtTermS, eqLHS, &appl))); @@ -345,12 +345,16 @@ void ConditionalRedundancyHandlerImpl::insertSuper return; } - bool incompInserted = doInsert && eqComp != Ordering::LESS; + // if the equation is not oriented, consider adding ordering constraints + if (eqComp != Ordering::LESS && !(ordC && rwTermS.containsAllVariablesOf(tgtTermS))) { + return; + } + auto rwClDataPtr = getDataPtr(rwClause, /*doAllocate=*/true); (*rwClDataPtr)->insert(_ord, subs, !eqIsResult, - incompInserted ? rwTermS.term() : nullptr, - incompInserted ? tgtTermS.term() : nullptr); + eqComp != Ordering::LESS ? rwTermS.term() : nullptr, + eqComp != Ordering::LESS ? tgtTermS.term() : nullptr); } template From 3390c94a38fbf86e2da7a97ad01fe0ab28522512 Mon Sep 17 00:00:00 2001 From: Marton Hajdu Date: Sun, 21 Jul 2024 16:00:30 +0200 Subject: [PATCH 07/19] Implement literal constraints --- Inferences/Superposition.cpp | 4 +- Kernel/SubstHelper.hpp | 1 + Kernel/Term.cpp | 2 +- Kernel/Term.hpp | 2 +- Lib/SharedSet.hpp | 2 +- Shell/ConditionalRedundancyHandler.cpp | 170 +++++++++++++++++++------ Shell/ConditionalRedundancyHandler.hpp | 8 +- Shell/Options.cpp | 7 +- 8 files changed, 145 insertions(+), 51 deletions(-) diff --git a/Inferences/Superposition.cpp b/Inferences/Superposition.cpp index 23426bb06..d08b4e8b6 100644 --- a/Inferences/Superposition.cpp +++ b/Inferences/Superposition.cpp @@ -351,7 +351,7 @@ Clause* Superposition::performSuperposition( } auto condRedHandler = _salg->condRedHandler(); - if (!condRedHandler->checkSuperposition(eqClause, rwClause, eqIsResult, subst.ptr())) { + if (!condRedHandler->checkSuperposition(eqClause, eqLit, rwClause, rwLit, eqIsResult, subst.ptr())) { return 0; } @@ -387,7 +387,7 @@ Clause* Superposition::performSuperposition( } condRedHandler->insertSuperposition( - eqClause, rwClause, rwTermS, tgtTermS, eqLHS, rwLitS, comp, eqIsResult, subst.ptr()); + eqClause, rwClause, rwTermS, tgtTermS, eqLHS, rwLitS, eqLit, comp, eqIsResult, subst.ptr()); Literal* tgtLitS = EqHelper::replace(rwLitS,rwTermS,tgtTermS); diff --git a/Kernel/SubstHelper.hpp b/Kernel/SubstHelper.hpp index ce11f1657..d2c9c5a8f 100644 --- a/Kernel/SubstHelper.hpp +++ b/Kernel/SubstHelper.hpp @@ -30,6 +30,7 @@ using namespace Lib; struct SubstApplicator { virtual ~SubstApplicator() = default; virtual TermList operator()(unsigned v) const = 0; + TermList apply(unsigned v) const { return (*this)(v); } }; /** diff --git a/Kernel/Term.cpp b/Kernel/Term.cpp index 39da64163..16c18a605 100644 --- a/Kernel/Term.cpp +++ b/Kernel/Term.cpp @@ -362,7 +362,7 @@ size_t Term::countSubtermOccurrences(TermList subterm) { return res; } -bool TermList::containsAllVariablesOf(TermList t) +bool TermList::containsAllVariablesOf(TermList t) const { Set vars; TermIterator oldVars=Term::getVariableIterator(*this); diff --git a/Kernel/Term.hpp b/Kernel/Term.hpp index 84e20aab6..5768b3d2e 100644 --- a/Kernel/Term.hpp +++ b/Kernel/Term.hpp @@ -231,7 +231,7 @@ class TermList { bool isTupleSort(); bool isApplication() const; bool containsSubterm(TermList v) const; - bool containsAllVariablesOf(TermList t); + bool containsAllVariablesOf(TermList t) const; bool ground() const; bool isSafe() const; diff --git a/Lib/SharedSet.hpp b/Lib/SharedSet.hpp index 9d7687e34..0a123b648 100644 --- a/Lib/SharedSet.hpp +++ b/Lib/SharedSet.hpp @@ -431,7 +431,7 @@ class SharedSet { } static unsigned hash(const T* arr, size_t len) { - static_assert(std::is_arithmetic::value, "T must be safely hashable"); + // static_assert(std::is_arithmetic::value, "T must be safely hashable"); return DefaultHash::hashBytes( reinterpret_cast(arr), sizeof(T) * len diff --git a/Shell/ConditionalRedundancyHandler.cpp b/Shell/ConditionalRedundancyHandler.cpp index 8d9c08821..91625b552 100644 --- a/Shell/ConditionalRedundancyHandler.cpp +++ b/Shell/ConditionalRedundancyHandler.cpp @@ -23,12 +23,15 @@ #include "Indexing/ResultSubstitution.hpp" #include "Lib/Environment.hpp" +#include "Lib/SharedSet.hpp" #include "Statistics.hpp" using namespace std; using namespace Indexing; +using LiteralSet = SharedSet; + namespace Shell { @@ -46,6 +49,9 @@ class ConditionalRedundancyHandler::SubstitutionCoverTree #if LOG_LEAVES _printLeaf = [](ostream& str, const CodeOp* op) { auto ld = op->getSuccessResult(); + ld->lits->iter().forEach([&str](Literal* lit) { + str << " " << *lit; + }); if (ld->comp) { str << " " << ld->comp->toString(); } @@ -56,34 +62,35 @@ class ConditionalRedundancyHandler::SubstitutionCoverTree } } - bool check(const Ordering* ord, ResultSubstitution* subst, bool result) + bool check(const Ordering* ord, ResultSubstitution* subst, bool result, const LiteralSet* lits) { if (_varSorts.isEmpty()) { return true; } auto ts = getInstances([subst,result](unsigned v) { return subst->applyTo(TermList::var(v),result); }); - return !check(ts, ord); + return !check(ts, ord, lits); } - void insert(const Ordering* ord, ResultSubstitution* subst, bool result, Term* lhs=nullptr, Term* rhs=nullptr) + void insert(const Ordering* ord, ResultSubstitution* subst, bool result, const LiteralSet* lits, Term* lhs=nullptr, Term* rhs=nullptr) { auto ts = getInstances([subst,result](unsigned v) { return subst->applyTo(TermList::var(v),result); }); - auto ld = createEntry(ts, lhs, rhs); + auto ld = createEntry(ts, lhs, rhs, lits); insert(ts,ld); } - bool checkAndInsert(const Ordering* ord, ResultSubstitution* subst, bool result, bool doInsert=false, Term* lhs=nullptr, Term* rhs=nullptr) + bool checkAndInsert(const Ordering* ord, ResultSubstitution* subst, bool result, const LiteralSet* lits, bool doInsert=false, Term* lhs=nullptr, Term* rhs=nullptr) { + ASS(lits); // TODO if this correct if we allow non-unit simplifications? if (_varSorts.isEmpty()) { return true; } auto ts = getInstances([subst,result](unsigned v) { return subst->applyTo(TermList(v,false),result); }); - if (check(ts, ord)) { + if (check(ts, ord, lits)) { return false; } if (doInsert) { - auto ld = createEntry(ts, lhs, rhs); + auto ld = createEntry(ts, lhs, rhs, lits); insert(ts,ld); } return true; @@ -124,29 +131,39 @@ class ConditionalRedundancyHandler::SubstitutionCoverTree incorporate(code); } - bool check(const TermStack& ts, const Ordering* ord) + bool check(const TermStack& ts, const Ordering* ord, const LiteralSet* lits) { if (isEmpty()) { return false; } static SubstMatcher matcher; + struct Applicator : public SubstApplicator { + TermList operator()(unsigned v) const override { return matcher.bindings[v]; } + } applicator; matcher.init(this, ts); LeafData* ld; while ((ld = matcher.next())) { - if (!ld->lhs) { - return true; + + // check literal conditions + auto subsetof = ld->lits->iter().all([lits,&applicator](Literal* lit) { + return lits->member(SubstHelper::apply(lit,applicator)); + }); + if (!subsetof) { + continue; } - if (ord) { - struct Applicator : public SubstApplicator { - TermList operator()(unsigned v) const override { return matcher.bindings[v]; } - } applicator; - if (ord->isGreater(TermList(ld->lhs),TermList(ld->rhs),&applicator,ld->comp)) { - return true; + // check ordering constraints + if (ld->lhs) { + if (!ord || !ord->isGreater(TermList(ld->lhs),TermList(ld->rhs),&applicator,ld->comp)) { + continue; } } + if (!ld->lits->isEmpty()) { + env.statistics->inductionApplication++; + } + return true; } matcher.reset(); @@ -171,27 +188,30 @@ class ConditionalRedundancyHandler::SubstitutionCoverTree Term* lhs = nullptr; Term* rhs = nullptr; OrderingComparatorUP comp; + const LiteralSet* lits; }; - LeafData* createEntry(const TermStack& ts, Term* lhs, Term* rhs) const + LeafData* createEntry(const TermStack& ts, Term* lhs, Term* rhs, const LiteralSet* lits) const { auto ld = new LeafData(); - if (lhs) { - ASS(rhs); - ASS(lhs->containsAllVariablesOf(rhs)); - Renaming r; - // normalize lhs and rhs, the same way as + Renaming r; + if (lhs || !lits->isEmpty()) { + // normalize constraints, the same way as // terms from ts are normalized upon insertion for (const auto t : ts) { r.normalizeVariables(t); } - ld->lhs = r.apply(lhs); - ld->rhs = r.apply(rhs); - } else { - ASS(!rhs); - ld->lhs = nullptr; - ld->rhs = nullptr; } + + ASS_EQ(!lhs,!rhs); + ASS(!lhs || lhs->containsAllVariablesOf(rhs)); + ld->lhs = lhs ? r.apply(lhs) : nullptr; + ld->rhs = lhs ? r.apply(rhs) : nullptr; + + ld->lits = LiteralSet::getFromIterator(lits->iter().map([&r](Literal* lit) { + return r.apply(lit); + })); + return ld; } @@ -294,20 +314,38 @@ DHMap Con template bool ConditionalRedundancyHandlerImpl::checkSuperposition( - Clause* eqClause, Clause* rwClause, bool eqIsResult, ResultSubstitution* subs) const + Clause* eqClause, Literal* eqLit, Clause* rwClause, Literal* rwLit, bool eqIsResult, ResultSubstitution* subs) const { if constexpr (!enabled) { return true; } + auto rwLits = LiteralSet::getEmpty(); + if constexpr (litC) { + rwLits = LiteralSet::getFromIterator(rwClause->iterLits().filter([rwLit](Literal* lit) { + return lit != rwLit && rwLit->containsAllVariablesOf(lit); + }).map([subs,eqIsResult](Literal* lit) { + return subs->applyTo(lit,!eqIsResult); + })); + } + auto eqClDataPtr = getDataPtr(eqClause, /*doAllocate=*/false); - if (eqClDataPtr && !(*eqClDataPtr)->check(_ord, subs, eqIsResult)) { + if (eqClDataPtr && !(*eqClDataPtr)->check(_ord, subs, eqIsResult, rwLits)) { env.statistics->skippedSuperposition++; return false; } + auto eqLits = LiteralSet::getEmpty(); + if constexpr (litC) { + eqLits = LiteralSet::getFromIterator(eqClause->iterLits().filter([eqLit](Literal* lit) { + return lit != eqLit && eqLit->containsAllVariablesOf(lit); + }).map([subs,eqIsResult](Literal* lit) { + return subs->applyTo(lit,eqIsResult); + })); + } + auto rwClDataPtr = getDataPtr(rwClause, /*doAllocate=*/false); - if (rwClDataPtr && !(*rwClDataPtr)->check(_ord, subs, !eqIsResult)) { + if (rwClDataPtr && !(*rwClDataPtr)->check(_ord, subs, !eqIsResult, eqLits)) { env.statistics->skippedSuperposition++; return false; } @@ -318,7 +356,7 @@ bool ConditionalRedundancyHandlerImpl::checkSuperp template void ConditionalRedundancyHandlerImpl::insertSuperposition( Clause* eqClause, Clause* rwClause, TermList rwTermS, TermList tgtTermS, TermList eqLHS, - Literal* rwLitS, Ordering::Result eqComp, bool eqIsResult, ResultSubstitution* subs) const + Literal* rwLitS, Literal* eqLit, Ordering::Result eqComp, bool eqIsResult, ResultSubstitution* subs) const { if constexpr (!enabled) { return; @@ -335,7 +373,7 @@ void ConditionalRedundancyHandlerImpl::insertSuper Applicator appl(subs, !eqIsResult); - auto doInsert = eqClause->length()==1 && eqClause->noSplits() && + auto doInsert = eqClause->noSplits() && // TODO this demodulation redundancy check could be added as constraints (!_demodulationHelper.redundancyCheckNeededForPremise(rwClause, rwLitS, rwTermS) || // TODO for rwClause->length()!=1 the function isPremiseRedundant does not work yet @@ -350,9 +388,28 @@ void ConditionalRedundancyHandlerImpl::insertSuper return; } + auto lits = LiteralSet::getEmpty(); + if constexpr (litC) { + if (eqClause->numSelected()!=1) { + return; + } + lits = LiteralSet::getFromIterator(eqClause->iterLits().filter([eqLit](Literal* lit) { + return lit != eqLit && eqLit->containsAllVariablesOf(lit); + }).map([subs,eqIsResult](Literal* lit) { + return subs->applyTo(lit,eqIsResult); + })); + if (eqClause->size()>lits->size()+1) { + return; + } + } else { + if (eqClause->length()!=1) { + return; + } + } + auto rwClDataPtr = getDataPtr(rwClause, /*doAllocate=*/true); - (*rwClDataPtr)->insert(_ord, subs, !eqIsResult, + (*rwClDataPtr)->insert(_ord, subs, !eqIsResult, lits, eqComp != Ordering::LESS ? rwTermS.term() : nullptr, eqComp != Ordering::LESS ? tgtTermS.term() : nullptr); } @@ -367,17 +424,51 @@ bool ConditionalRedundancyHandlerImpl::handleResol // Note that we're inserting into the data of one clause based on the *other* clause { - bool doInsert = resultLit->isPositive() && resultCl->size()==1 && resultCl->noSplits(); + bool doInsert = resultLit->isPositive() && resultCl->noSplits(); + + auto lits = LiteralSet::getEmpty(); + if constexpr (litC) { + lits = LiteralSet::getFromIterator(resultCl->iterLits().filter([resultLit](Literal* lit) { + return lit != resultLit && resultLit->containsAllVariablesOf(lit); + }).map([subs](Literal* lit) { + return subs->applyToResult(lit); + })); + if (resultCl->numSelected()>1 || resultCl->length()>lits->size()+1) { + doInsert = false; + } + } else { + if (resultCl->length()!=1) { + doInsert = false; + } + } + auto dataPtr = getDataPtr(queryCl, /*doAllocate=*/doInsert); - if (dataPtr && !(*dataPtr)->checkAndInsert(_ord, subs, false, doInsert)) { + if (dataPtr && !(*dataPtr)->checkAndInsert(_ord, subs, false, lits, doInsert)) { env.statistics->skippedResolution++; return false; } } { - bool doInsert = queryLit->isPositive() && queryCl->size()==1 && queryCl->noSplits(); + bool doInsert = queryLit->isPositive() && queryCl->noSplits(); + + auto lits = LiteralSet::getEmpty(); + if constexpr (litC) { + lits = LiteralSet::getFromIterator(queryCl->iterLits().filter([queryLit](Literal* lit) { + return lit != queryLit && queryLit->containsAllVariablesOf(lit); + }).map([subs](Literal* lit) { + return subs->applyToQuery(lit); + })); + if (queryCl->numSelected()>1 || queryCl->length()>lits->size()+1) { + doInsert = false; + } + } else { + if (queryCl->length()!=1) { + doInsert = false; + } + } + auto dataPtr = getDataPtr(resultCl, /*doAllocate=*/doInsert); - if (dataPtr && !(*dataPtr)->checkAndInsert(_ord, subs, true, doInsert)) { + if (dataPtr && !(*dataPtr)->checkAndInsert(_ord, subs, true, lits, doInsert)) { env.statistics->skippedResolution++; return false; } @@ -394,7 +485,8 @@ bool ConditionalRedundancyHandlerImpl::handleReduc } auto dataPtr = getDataPtr(premise, /*doAllocate=*/true); auto subst = ResultSubstitution::fromSubstitution(subs, 0, 0); - if (!(*dataPtr)->checkAndInsert(_ord, subst.ptr(), false, /*doInsert=*/true)) { + auto lits = LiteralSet::getEmpty(); + if (!(*dataPtr)->checkAndInsert(_ord, subst.ptr(), false, lits, /*doInsert=*/true)) { return false; } return true; diff --git a/Shell/ConditionalRedundancyHandler.hpp b/Shell/ConditionalRedundancyHandler.hpp index dfc27ba0f..193e77624 100644 --- a/Shell/ConditionalRedundancyHandler.hpp +++ b/Shell/ConditionalRedundancyHandler.hpp @@ -36,11 +36,11 @@ class ConditionalRedundancyHandler virtual ~ConditionalRedundancyHandler() = default; virtual bool checkSuperposition( - Clause* eqClause, Clause* rwClause, bool eqIsResult, ResultSubstitution* subs) const = 0; + Clause* eqClause, Literal* eqLit, Clause* rwClause, Literal* rwLit, bool eqIsResult, ResultSubstitution* subs) const = 0; virtual void insertSuperposition( Clause* eqClause, Clause* rwClause, TermList rwTermS, TermList tgtTermS, TermList eqLHS, - Literal* rwLitS, Ordering::Result eqComp, bool eqIsResult, ResultSubstitution* subs) const = 0; + Literal* rwLitS, Literal* eqLit, Ordering::Result eqComp, bool eqIsResult, ResultSubstitution* subs) const = 0; virtual bool handleResolution( Clause* queryCl, Literal* queryLit, Clause* resultCl, Literal* resultLit, ResultSubstitution* subs) const = 0; @@ -67,11 +67,11 @@ class ConditionalRedundancyHandlerImpl /** Returns false if superposition should be skipped. */ bool checkSuperposition( - Clause* eqClause, Clause* rwClause, bool eqIsResult, ResultSubstitution* subs) const override; + Clause* eqClause, Literal* eqLit, Clause* rwClause, Literal* rwLit, bool eqIsResult, ResultSubstitution* subs) const override; void insertSuperposition( Clause* eqClause, Clause* rwClause, TermList rwTermS, TermList tgtTermS, TermList eqLHS, - Literal* rwLitS, Ordering::Result eqComp, bool eqIsResult, ResultSubstitution* subs) const override; + Literal* rwLitS, Literal* eqLit, Ordering::Result eqComp, bool eqIsResult, ResultSubstitution* subs) const override; /** Returns false if resolution should be skipped. */ bool handleResolution( diff --git a/Shell/Options.cpp b/Shell/Options.cpp index 46ccacbbf..a59b56476 100644 --- a/Shell/Options.cpp +++ b/Shell/Options.cpp @@ -1717,21 +1717,22 @@ void Options::init() _conditionalRedundancyOrderingConstraints.description= "Strengthen conditional redundancy with ordering constraints."; _lookup.insert(&_conditionalRedundancyOrderingConstraints); - _conditionalRedundancyOrderingConstraints.addHardConstraint(If(equal(true)).then(_conditionalRedundancyCheck.is(equal(true)))); + _conditionalRedundancyOrderingConstraints.onlyUsefulWith(_conditionalRedundancyCheck.is(equal(true))); _conditionalRedundancyOrderingConstraints.tag(OptionTag::INFERENCES); _conditionalRedundancyAvatarConstraints = BoolOptionValue("conditional_redundancy_avatar_constraints","crac",false); _conditionalRedundancyAvatarConstraints.description= "Strengthen conditional redundancy with AVATAR constraints."; _lookup.insert(&_conditionalRedundancyAvatarConstraints); - _conditionalRedundancyAvatarConstraints.addHardConstraint(If(equal(true)).then(_conditionalRedundancyCheck.is(equal(true)))); + _conditionalRedundancyAvatarConstraints.onlyUsefulWith(_conditionalRedundancyCheck.is(equal(true))); + _conditionalRedundancyAvatarConstraints.onlyUsefulWith(_splitting.is(equal(true))); _conditionalRedundancyAvatarConstraints.tag(OptionTag::INFERENCES); _conditionalRedundancyLiteralConstraints = BoolOptionValue("conditional_redundancy_literal_constraints","crlc",false); _conditionalRedundancyLiteralConstraints.description= "Strengthen conditional redundancy with literals from clauses."; _lookup.insert(&_conditionalRedundancyLiteralConstraints); - _conditionalRedundancyLiteralConstraints.addHardConstraint(If(equal(true)).then(_conditionalRedundancyCheck.is(equal(true)))); + _conditionalRedundancyLiteralConstraints.onlyUsefulWith(_conditionalRedundancyCheck.is(equal(true))); _conditionalRedundancyLiteralConstraints.tag(OptionTag::INFERENCES); _unitResultingResolution = ChoiceOptionValue("unit_resulting_resolution","urr",URResolution::OFF,{"ec_only","off","on","full"}); From be9fd2993a94baba9a9bb2136e2ecd23c9738d48 Mon Sep 17 00:00:00 2001 From: Marton Hajdu Date: Tue, 23 Jul 2024 11:37:36 +0200 Subject: [PATCH 08/19] Add a somewhat experimental AVATAR extension; do some refactoring --- Inferences/BinaryResolution.cpp | 22 ++++- Inferences/EqualityFactoring.cpp | 4 +- Inferences/EqualityResolution.cpp | 3 +- Inferences/Induction.cpp | 3 - Inferences/Superposition.cpp | 39 +++++--- Inferences/Superposition.hpp | 2 +- Kernel/KBO.hpp | 4 +- Saturation/SaturationAlgorithm.cpp | 2 +- Saturation/Splitter.cpp | 44 ++++++++- Saturation/Splitter.hpp | 10 ++ Shell/ConditionalRedundancyHandler.cpp | 122 ++++++++++++++++++------- Shell/ConditionalRedundancyHandler.hpp | 26 ++++-- Shell/Statistics.cpp | 29 ++++-- Shell/Statistics.hpp | 16 ++-- 14 files changed, 244 insertions(+), 82 deletions(-) diff --git a/Inferences/BinaryResolution.cpp b/Inferences/BinaryResolution.cpp index 389c7e391..91675c8d7 100644 --- a/Inferences/BinaryResolution.cpp +++ b/Inferences/BinaryResolution.cpp @@ -21,6 +21,7 @@ #include "Lib/Metaiterators.hpp" #include "Lib/PairUtils.hpp" #include "Lib/VirtualIterator.hpp" +#include "Lib/SharedSet.hpp" #include "Kernel/Clause.hpp" #include "Kernel/ColorHelper.hpp" @@ -37,6 +38,7 @@ #include "Indexing/SubstitutionTree.hpp" #include "Saturation/SaturationAlgorithm.hpp" +#include "Saturation/Splitter.hpp" #include "Shell/AnswerLiteralManager.hpp" #include "Shell/ConditionalRedundancyHandler.hpp" @@ -218,7 +220,25 @@ Clause* BinaryResolution::generateClause( } } - if (!_salg->condRedHandler()->handleResolution(queryCl, queryLit, resultCl, resultLit, subs.ptr())) { + SplitSet* blockingSet = nullptr; + if (!_salg->condRedHandler()->handleResolution(queryCl, queryLit, resultCl, resultLit, subs.ptr(), blockingSet)) { + auto splitter = _salg->getSplitter(); + if (splitter) { + splitter->onRedundantInference([this,queryCl,queryLit,resultCl,resultLit]() -> Clause* { + if (queryCl->store()==Clause::NONE) { + return 0; + } + if (resultCl->store()==Clause::NONE) { + return 0; + } + auto unifier = AbstractingUnifier::unify( + TermList(queryLit), 0, TermList(resultLit), 1, AbstractionOracle(Options::UnificationWithAbstraction::OFF), false); + ASS(unifier); + auto subs = ResultSubstitution::fromSubstitution(&unifier->subs(), QUERY_BANK, RESULT_BANK); + + return generateClause(queryCl, queryLit, resultCl, resultLit, subs, &unifier.unwrap()); + }, queryCl, resultCl, blockingSet); + } return 0; } diff --git a/Inferences/EqualityFactoring.cpp b/Inferences/EqualityFactoring.cpp index b8d342fc3..f352723af 100644 --- a/Inferences/EqualityFactoring.cpp +++ b/Inferences/EqualityFactoring.cpp @@ -30,6 +30,7 @@ #include "Kernel/ApplicativeHelper.hpp" #include "Saturation/SaturationAlgorithm.hpp" +#include "Saturation/Splitter.hpp" #include "Shell/ConditionalRedundancyHandler.hpp" #include "Shell/Statistics.hpp" @@ -163,7 +164,8 @@ struct EqualityFactoring::ResultFn } } - if (!_condRedHandler->handleReductiveUnaryInference(_cl, &absUnif.subs())) { + SplitSet* blockingSet; + if (!_condRedHandler->handleReductiveUnaryInference(_cl, &absUnif.subs(), blockingSet)) { env.statistics->skippedEqualityFactoring++; return nullptr; } diff --git a/Inferences/EqualityResolution.cpp b/Inferences/EqualityResolution.cpp index 190f2c1ba..3a04284a2 100644 --- a/Inferences/EqualityResolution.cpp +++ b/Inferences/EqualityResolution.cpp @@ -116,7 +116,8 @@ struct EqualityResolution::ResultFn } } - if (_condRedHandler && !_condRedHandler->handleReductiveUnaryInference(_cl, &absUnif->subs())) { + SplitSet* blockingSet; + if (_condRedHandler && !_condRedHandler->handleReductiveUnaryInference(_cl, &absUnif->subs(), blockingSet)) { env.statistics->skippedEqualityResolution++; return nullptr; } diff --git a/Inferences/Induction.cpp b/Inferences/Induction.cpp index 625102709..7eb2f6f21 100644 --- a/Inferences/Induction.cpp +++ b/Inferences/Induction.cpp @@ -1038,17 +1038,14 @@ Clause* resolveClausesHelper(const InductionContext& context, const Stacklength(); auto premises = UnitList::singleton(cl); const auto& toResolve = context._cls; while (eIt.hasNext()) { auto other = cls[eIt.next()]; - ASS_EQ(other->length(),newLength); UnitList::push(other,premises); } for (const auto& kv : toResolve) { - newLength += kv.first->length() - kv.second.size() - 1; UnitList::push(kv.first, premises); } diff --git a/Inferences/Superposition.cpp b/Inferences/Superposition.cpp index c937a11fc..d9f9207d4 100644 --- a/Inferences/Superposition.cpp +++ b/Inferences/Superposition.cpp @@ -80,23 +80,22 @@ void Superposition::detach() struct Superposition::ForwardResultFn { - ForwardResultFn(Clause* cl, PassiveClauseContainer* passiveClauseContainer, Superposition& parent) : _cl(cl), _passiveClauseContainer(passiveClauseContainer), _parent(parent) {} + ForwardResultFn(Clause* cl, Superposition& parent) : _cl(cl), _parent(parent) {} Clause* operator()(pair, QueryRes> arg) { auto& qr = arg.second; return _parent.performSuperposition(_cl, arg.first.first, arg.first.second, - qr.data->clause, qr.data->literal, qr.data->term, qr.unifier, true, _passiveClauseContainer); + qr.data->clause, qr.data->literal, qr.data->term, qr.unifier, true); } private: Clause* _cl; - PassiveClauseContainer* _passiveClauseContainer; Superposition& _parent; }; struct Superposition::BackwardResultFn { - BackwardResultFn(Clause* cl, PassiveClauseContainer* passiveClauseContainer, Superposition& parent) : _cl(cl), _passiveClauseContainer(passiveClauseContainer), _parent(parent) {} + BackwardResultFn(Clause* cl, Superposition& parent) : _cl(cl), _parent(parent) {} Clause* operator()(pair, QueryRes> arg) { if(_cl==arg.second.data->clause) { @@ -105,19 +104,16 @@ struct Superposition::BackwardResultFn auto& qr = arg.second; return _parent.performSuperposition(qr.data->clause, qr.data->literal, qr.data->term, - _cl, arg.first.first, arg.first.second, qr.unifier, false, _passiveClauseContainer); + _cl, arg.first.first, arg.first.second, qr.unifier, false); } private: Clause* _cl; - PassiveClauseContainer* _passiveClauseContainer; Superposition& _parent; }; ClauseIterator Superposition::generateClauses(Clause* premise) { - PassiveClauseContainer* passiveClauseContainer = _salg->getPassiveClauseContainer(); - auto itf1 = premise->getSelectedLiteralIterator(); // Get an iterator of pairs of selected literals and rewritable subterms of those literals @@ -136,7 +132,7 @@ ClauseIterator Superposition::generateClauses(Clause* premise) { return pushPairIntoRightIterator(arg, _lhsIndex->getUwa(arg.second, env.options->unificationWithAbstraction(), env.options->unificationWithAbstractionFixedPointIteration())); }); //Perform forward superposition - auto itf4 = getMappingIterator(itf3,ForwardResultFn(premise, passiveClauseContainer, *this)); + auto itf4 = getMappingIterator(itf3,ForwardResultFn(premise, *this)); auto itb1 = premise->getSelectedLiteralIterator(); auto itb2 = getMapAndFlattenIterator(itb1,EqHelper::SuperpositionLHSIteratorFn(_salg->getOrdering(), _salg->getOptions())); @@ -147,7 +143,7 @@ ClauseIterator Superposition::generateClauses(Clause* premise) _subtermIndex->getUwa(TypedTermList(arg.second, SortHelper::getEqualityArgumentSort(arg.first)), env.options->unificationWithAbstraction(), env.options->unificationWithAbstractionFixedPointIteration())); }); //Perform backward superposition - auto itb4 = getMappingIterator(itb3,BackwardResultFn(premise, passiveClauseContainer, *this)); + auto itb4 = getMappingIterator(itb3,BackwardResultFn(premise, *this)); // Add the results of forward and backward together auto it5 = concatIters(itf4,itb4); @@ -306,7 +302,7 @@ bool Superposition::earlyWeightLimitCheck(Clause* eqClause, Literal* eqLit, Clause* Superposition::performSuperposition( Clause* rwClause, Literal* rwLit, TermList rwTerm, Clause* eqClause, Literal* eqLit, TermList eqLHS, - AbstractingUnifier* unifier, bool eqIsResult, PassiveClauseContainer* passiveClauseContainer) + AbstractingUnifier* unifier, bool eqIsResult) { TIME_TRACE("perform superposition"); // we want the rwClause and eqClause to be active @@ -343,6 +339,7 @@ Clause* Superposition::performSuperposition( Inference inf(GeneratingInference2(unifier->usesUwa() ? InferenceRule::CONSTRAINED_SUPERPOSITION : InferenceRule::SUPERPOSITION, rwClause, eqClause)); Inference::Destroyer inf_destroyer(inf); + auto passiveClauseContainer = _salg->getPassiveClauseContainer(); bool needsToFulfilWeightLimit = passiveClauseContainer && !passiveClauseContainer->fulfilsAgeLimit(0, numPositiveLiteralsLowerBound, inf) && passiveClauseContainer->weightLimited(); // 0 here denotes the current weight estimate if(needsToFulfilWeightLimit) { if(!earlyWeightLimitCheck(eqClause, eqLit, rwClause, rwLit, rwTerm, eqLHS, tgtTerm, subst, eqIsResult, passiveClauseContainer, numPositiveLiteralsLowerBound, inf)) { @@ -351,7 +348,25 @@ Clause* Superposition::performSuperposition( } auto condRedHandler = _salg->condRedHandler(); - if (!condRedHandler->checkSuperposition(eqClause, eqLit, rwClause, rwLit, eqIsResult, subst.ptr())) { + SplitSet* blockingSet; + if (!condRedHandler->checkSuperposition(eqClause, eqLit, rwClause, rwLit, eqIsResult, subst.ptr(), blockingSet)) { + auto splitter = _salg->getSplitter(); + if (splitter) { + splitter->onRedundantInference([this,rwClause,rwLit,rwTerm,eqClause,eqLit,eqLHS]() -> Clause* { + if (rwClause->store()==Clause::NONE) { + return 0; + } + if (eqClause->store()==Clause::NONE) { + return 0; + } + auto unifier = AbstractingUnifier::unify( + TermList(rwTerm), 0, TermList(eqLHS), 1, AbstractionOracle(Options::UnificationWithAbstraction::OFF), false); + ASS(unifier); + auto subs = ResultSubstitution::fromSubstitution(&unifier->subs(), QUERY_BANK, RESULT_BANK); + + return performSuperposition(rwClause, rwLit, rwTerm, eqClause, eqLit, eqLHS, &unifier.unwrap(), true); + }, rwClause, eqClause, blockingSet); + } return 0; } diff --git a/Inferences/Superposition.hpp b/Inferences/Superposition.hpp index f8d10be9c..2b22e578f 100644 --- a/Inferences/Superposition.hpp +++ b/Inferences/Superposition.hpp @@ -42,7 +42,7 @@ class Superposition Clause* performSuperposition( Clause* rwClause, Literal* rwLiteral, TermList rwTerm, Clause* eqClause, Literal* eqLiteral, TermList eqLHS, - AbstractingUnifier* unifier, bool eqIsResult, PassiveClauseContainer* passiveClauseContainer); + AbstractingUnifier* unifier, bool eqIsResult); bool checkClauseColorCompatibility(Clause* eqClause, Clause* rwClause); static bool earlyWeightLimitCheck(Clause* eqClause, Literal* eqLit, diff --git a/Kernel/KBO.hpp b/Kernel/KBO.hpp index 06eb4bda1..d07551943 100644 --- a/Kernel/KBO.hpp +++ b/Kernel/KBO.hpp @@ -239,9 +239,9 @@ class KBO Result innerResult(TermList t1, TermList t2); Result applyVariableCondition(Result res) { - if(_posNum>0 && (res==LESS || res==LESS_EQ || res==EQUAL)) { + if(_posNum>0 && (res==LESS || res==EQUAL)) { res=INCOMPARABLE; - } else if(_negNum>0 && (res==GREATER || res==GREATER_EQ || res==EQUAL)) { + } else if(_negNum>0 && (res==GREATER || res==EQUAL)) { res=INCOMPARABLE; } return res; diff --git a/Saturation/SaturationAlgorithm.cpp b/Saturation/SaturationAlgorithm.cpp index a2969b788..3cf91d2ec 100644 --- a/Saturation/SaturationAlgorithm.cpp +++ b/Saturation/SaturationAlgorithm.cpp @@ -1666,7 +1666,7 @@ SaturationAlgorithm *SaturationAlgorithm::createFromOptions(Problem& prb, const res->_symEl = new SymElOutput(); } - res->_conditionalRedundancyHandler.reset(ConditionalRedundancyHandler::create(opt, &ordering)); + res->_conditionalRedundancyHandler.reset(ConditionalRedundancyHandler::create(opt, &ordering, res->_splitter)); res->_answerLiteralManager = AnswerLiteralManager::getInstance(); // selects the right one, according to options! ASS(!res->_answerLiteralManager||opt.questionAnswering()!=Options::QuestionAnsweringMode::OFF); diff --git a/Saturation/Splitter.cpp b/Saturation/Splitter.cpp index 5766a778e..a2c1830bd 100644 --- a/Saturation/Splitter.cpp +++ b/Saturation/Splitter.cpp @@ -620,7 +620,7 @@ std::string Splitter::splPrefix = ""; Splitter::Splitter() : _deleteDeactivated(Options::SplittingDeleteDeactivated::ON), _branchSelector(*this), - _clausesAdded(false), _haveBranchRefutation(false) + _clausesAdded(false), _haveBranchRefutation(false), _activationTimestamp(0) { if(env.options->proof()==Options::Proof::TPTP){ unsigned spl = env.signature->addFreshFunction(0,"spl"); @@ -804,6 +804,7 @@ void Splitter::onAllProcessed() toRemove.reset(); _branchSelector.recomputeModel(toAdd, toRemove, flushing); + _activationTimestamp++; if (_showSplitting) { // TODO: this is just one of many ways Splitter could report about changes std::cout << "[AVATAR] recomputeModel: + "; @@ -1497,6 +1498,27 @@ void Splitter::onClauseReduction(Clause* cl, ClauseIterator premises, Clause* re } } +void Splitter::onRedundantInference(std::function fn, Clause* premise0, Clause* premise1, SplitSet* blockingSet) +{ + ASS(blockingSet); + + if (blockingSet->isEmpty()) { + // nothing to do + return; + } + + auto unionAll = premise0->splits()->getUnion(premise1->splits()); + SplitSet* diff = blockingSet->subtract(unionAll); + + ASS(allSplitLevelsActive(diff)); + + auto dit = diff->iter(); + while (dit.hasNext()) { + SplitLevel slev=dit.next(); + _db[slev]->addRedundantInference(fn); + } +} + bool Splitter::allSplitLevelsActive(SplitSet* s) { auto sit = s->iter(); @@ -1511,6 +1533,15 @@ bool Splitter::allSplitLevelsActive(SplitSet* s) return true; } +bool Splitter::allSplitLevelsActivatedBefore(SplitSet* splits, unsigned timestamp) const +{ + return splits->iter().all([this,timestamp](SplitLevel lev) { + ASS_REP(lev<_db.size(), lev); + ASS_REP(_db[lev]!=0, lev); + return _db[lev]->active && _db[lev]->active_ts <= timestamp; + }); +} + void Splitter::onNewClause(Clause* cl) { // when using AVATAR, we could have performed @@ -1660,6 +1691,7 @@ void Splitter::addComponents(const SplitLevelStack& toAdd) ASS(sr); ASS(!sr->active); sr->active = true; + sr->active_ts = _activationTimestamp; if (_deleteDeactivated == Options::SplittingDeleteDeactivated::ON) { ASS(sr->children.isEmpty()); @@ -1758,6 +1790,16 @@ void Splitter::removeComponents(const SplitLevelStack& toRemove) ASS(sr->active); sr->active = false; + + // note: this has to be done after the above deactivation + while (sr->redInfs.isNonEmpty()) { + // TODO make sure each function is called only once + auto fn = sr->redInfs.pop(); + auto cl = fn(); + if (cl) { + _sa->addNewClause(cl); + } + } } } diff --git a/Saturation/Splitter.hpp b/Saturation/Splitter.hpp index e09027391..6d1610bd7 100644 --- a/Saturation/Splitter.hpp +++ b/Saturation/Splitter.hpp @@ -163,11 +163,16 @@ class Splitter { ~SplitRecord(); void addReduced(Clause* cl); + void addRedundantInference(std::function fn) { + redInfs.push(fn); + } Clause* component; RCClauseStack children; Stack reduced; + Stack> redInfs; bool active; + unsigned active_ts; USE_ALLOCATOR(SplitRecord); }; @@ -184,6 +189,7 @@ class Splitter { bool doSplitting(Clause* cl); void onClauseReduction(Clause* cl, ClauseIterator premises, Clause* replacement); + void onRedundantInference(std::function fn, Clause* premise0, Clause* premise1, SplitSet* blockingSet); void onNewClause(Clause* cl); void onAllProcessed(); bool handleEmptyClause(Clause* cl); @@ -313,6 +319,8 @@ class Splitter { // not just optimisation: also prevents the SAT solver oscillating between two models in some cases Set> _already_added; + unsigned _activationTimestamp; + public: static std::string splPrefix; @@ -322,6 +330,8 @@ class Splitter { ASS_REP(lev<_db.size(), lev); return (_db[lev]!=0 && _db[lev]->active); } + unsigned getTimestamp() const { return _activationTimestamp; } + bool allSplitLevelsActivatedBefore(SplitSet* splits, unsigned timestamp) const; }; } diff --git a/Shell/ConditionalRedundancyHandler.cpp b/Shell/ConditionalRedundancyHandler.cpp index 91625b552..0014c2aff 100644 --- a/Shell/ConditionalRedundancyHandler.cpp +++ b/Shell/ConditionalRedundancyHandler.cpp @@ -49,6 +49,7 @@ class ConditionalRedundancyHandler::SubstitutionCoverTree #if LOG_LEAVES _printLeaf = [](ostream& str, const CodeOp* op) { auto ld = op->getSuccessResult(); + str << Splitter::splitsToString(ld->splits) << ", ts " << ld->splits_ts; ld->lits->iter().forEach([&str](Literal* lit) { str << " " << *lit; }); @@ -62,23 +63,23 @@ class ConditionalRedundancyHandler::SubstitutionCoverTree } } - bool check(const Ordering* ord, ResultSubstitution* subst, bool result, const LiteralSet* lits) + bool check(const Ordering* ord, ResultSubstitution* subst, bool result, const LiteralSet* lits, const Splitter* splitter, SplitSet*& blockingSplits) { if (_varSorts.isEmpty()) { return true; } auto ts = getInstances([subst,result](unsigned v) { return subst->applyTo(TermList::var(v),result); }); - return !check(ts, ord, lits); + return !check(ts, ord, lits, splitter, blockingSplits); } - void insert(const Ordering* ord, ResultSubstitution* subst, bool result, const LiteralSet* lits, Term* lhs=nullptr, Term* rhs=nullptr) + void insert(const Ordering* ord, ResultSubstitution* subst, bool result, const LiteralSet* lits, const Splitter* splitter, SplitSet* splits, Term* lhs=nullptr, Term* rhs=nullptr) { auto ts = getInstances([subst,result](unsigned v) { return subst->applyTo(TermList::var(v),result); }); - auto ld = createEntry(ts, lhs, rhs, lits); + auto ld = createEntry(ts, lhs, rhs, lits, splitter, splits); insert(ts,ld); } - bool checkAndInsert(const Ordering* ord, ResultSubstitution* subst, bool result, const LiteralSet* lits, bool doInsert=false, Term* lhs=nullptr, Term* rhs=nullptr) + bool checkAndInsert(const Ordering* ord, ResultSubstitution* subst, bool result, const LiteralSet* lits, const Splitter* splitter, SplitSet*& blockingSplits, bool doInsert, SplitSet* splits, Term* lhs=nullptr, Term* rhs=nullptr) { ASS(lits); // TODO if this correct if we allow non-unit simplifications? @@ -86,11 +87,11 @@ class ConditionalRedundancyHandler::SubstitutionCoverTree return true; } auto ts = getInstances([subst,result](unsigned v) { return subst->applyTo(TermList(v,false),result); }); - if (check(ts, ord, lits)) { + if (check(ts, ord, lits, splitter, blockingSplits)) { return false; } if (doInsert) { - auto ld = createEntry(ts, lhs, rhs, lits); + auto ld = createEntry(ts, lhs, rhs, lits, splitter, splits); insert(ts,ld); } return true; @@ -131,7 +132,7 @@ class ConditionalRedundancyHandler::SubstitutionCoverTree incorporate(code); } - bool check(const TermStack& ts, const Ordering* ord, const LiteralSet* lits) + bool check(const TermStack& ts, const Ordering* ord, const LiteralSet* lits, const Splitter* splitter, SplitSet*& blockingSplits) { if (isEmpty()) { return false; @@ -160,8 +161,22 @@ class ConditionalRedundancyHandler::SubstitutionCoverTree continue; } } + + // check AVATAR constraints + if (splitter && !splitter->allSplitLevelsActivatedBefore(ld->splits,ld->splits_ts)) { + continue; + } + blockingSplits = ld->splits; + + // collect statistics + if (ld->lhs) { + env.statistics->skippedInferencesDueToOrderingConstraints++; + } if (!ld->lits->isEmpty()) { - env.statistics->inductionApplication++; + env.statistics->skippedInferencesDueToLiteralConstraints++; + } + if (!ld->splits->isEmpty()) { + env.statistics->skippedInferencesDueToAvatarConstraints++; } return true; } @@ -189,9 +204,11 @@ class ConditionalRedundancyHandler::SubstitutionCoverTree Term* rhs = nullptr; OrderingComparatorUP comp; const LiteralSet* lits; + SplitSet* splits = nullptr; + unsigned splits_ts; }; - LeafData* createEntry(const TermStack& ts, Term* lhs, Term* rhs, const LiteralSet* lits) const + LeafData* createEntry(const TermStack& ts, Term* lhs, Term* rhs, const LiteralSet* lits, const Splitter* splitter, SplitSet* splits) const { auto ld = new LeafData(); Renaming r; @@ -203,7 +220,7 @@ class ConditionalRedundancyHandler::SubstitutionCoverTree } } - ASS_EQ(!lhs,!rhs); + ASS_EQ(!lhs,!rhs); // we are interested in the "null-ptrness" ASS(!lhs || lhs->containsAllVariablesOf(rhs)); ld->lhs = lhs ? r.apply(lhs) : nullptr; ld->rhs = lhs ? r.apply(rhs) : nullptr; @@ -211,6 +228,12 @@ class ConditionalRedundancyHandler::SubstitutionCoverTree ld->lits = LiteralSet::getFromIterator(lits->iter().map([&r](Literal* lit) { return r.apply(lit); })); + + ASS(splits); + ld->splits = splits; + if (splitter) { + ld->splits_ts = splitter->getTimestamp(); + } return ld; } @@ -256,10 +279,10 @@ class ConditionalRedundancyHandler::SubstitutionCoverTree // ConditionalRedundancyHandler -ConditionalRedundancyHandler* ConditionalRedundancyHandler::create(const Options& opts, const Ordering* ord) +ConditionalRedundancyHandler* ConditionalRedundancyHandler::create(const Options& opts, const Ordering* ord, const Splitter* splitter) { if (!opts.conditionalRedundancyCheck()) { - return new ConditionalRedundancyHandlerImpl(opts,ord); + return new ConditionalRedundancyHandlerImpl(opts,ord,splitter); } auto ordC = opts.conditionalRedundancyOrderingConstraints(); auto avatarC = opts.conditionalRedundancyAvatarConstraints(); @@ -267,25 +290,25 @@ ConditionalRedundancyHandler* ConditionalRedundancyHandler::create(const Options if (ordC) { if (avatarC) { if (litC) { - return new ConditionalRedundancyHandlerImpl(opts,ord); + return new ConditionalRedundancyHandlerImpl(opts,ord,splitter); } - return new ConditionalRedundancyHandlerImpl(opts,ord); + return new ConditionalRedundancyHandlerImpl(opts,ord,splitter); } if (litC) { - return new ConditionalRedundancyHandlerImpl(opts,ord); + return new ConditionalRedundancyHandlerImpl(opts,ord,splitter); } - return new ConditionalRedundancyHandlerImpl(opts,ord); + return new ConditionalRedundancyHandlerImpl(opts,ord,splitter); } if (avatarC) { if (litC) { - return new ConditionalRedundancyHandlerImpl(opts,ord); + return new ConditionalRedundancyHandlerImpl(opts,ord,splitter); } - return new ConditionalRedundancyHandlerImpl(opts,ord); + return new ConditionalRedundancyHandlerImpl(opts,ord,splitter); } if (litC) { - return new ConditionalRedundancyHandlerImpl(opts,ord); + return new ConditionalRedundancyHandlerImpl(opts,ord,splitter); } - return new ConditionalRedundancyHandlerImpl(opts,ord); + return new ConditionalRedundancyHandlerImpl(opts,ord,splitter); } void ConditionalRedundancyHandler::destroyClauseData(Clause* cl) @@ -314,7 +337,8 @@ DHMap Con template bool ConditionalRedundancyHandlerImpl::checkSuperposition( - Clause* eqClause, Literal* eqLit, Clause* rwClause, Literal* rwLit, bool eqIsResult, ResultSubstitution* subs) const + Clause* eqClause, Literal* eqLit, Clause* rwClause, Literal* rwLit, + bool eqIsResult, ResultSubstitution* subs, SplitSet*& blockingSplits) const { if constexpr (!enabled) { return true; @@ -330,7 +354,7 @@ bool ConditionalRedundancyHandlerImpl::checkSuperp } auto eqClDataPtr = getDataPtr(eqClause, /*doAllocate=*/false); - if (eqClDataPtr && !(*eqClDataPtr)->check(_ord, subs, eqIsResult, rwLits)) { + if (eqClDataPtr && !(*eqClDataPtr)->check(_ord, subs, eqIsResult, rwLits, _splitter, blockingSplits)) { env.statistics->skippedSuperposition++; return false; } @@ -345,7 +369,7 @@ bool ConditionalRedundancyHandlerImpl::checkSuperp } auto rwClDataPtr = getDataPtr(rwClause, /*doAllocate=*/false); - if (rwClDataPtr && !(*rwClDataPtr)->check(_ord, subs, !eqIsResult, eqLits)) { + if (rwClDataPtr && !(*rwClDataPtr)->check(_ord, subs, !eqIsResult, eqLits, _splitter, blockingSplits)) { env.statistics->skippedSuperposition++; return false; } @@ -373,7 +397,7 @@ void ConditionalRedundancyHandlerImpl::insertSuper Applicator appl(subs, !eqIsResult); - auto doInsert = eqClause->noSplits() && + auto doInsert = // TODO this demodulation redundancy check could be added as constraints (!_demodulationHelper.redundancyCheckNeededForPremise(rwClause, rwLitS, rwTermS) || // TODO for rwClause->length()!=1 the function isPremiseRedundant does not work yet @@ -407,16 +431,25 @@ void ConditionalRedundancyHandlerImpl::insertSuper } } + auto splits = SplitSet::getEmpty(); + if constexpr (avatarC) { + splits = eqClause->splits(); + } else { + if (!eqClause->noSplits()) { + return; + } + } + auto rwClDataPtr = getDataPtr(rwClause, /*doAllocate=*/true); - (*rwClDataPtr)->insert(_ord, subs, !eqIsResult, lits, + (*rwClDataPtr)->insert(_ord, subs, !eqIsResult, lits, _splitter, splits, eqComp != Ordering::LESS ? rwTermS.term() : nullptr, eqComp != Ordering::LESS ? tgtTermS.term() : nullptr); } template bool ConditionalRedundancyHandlerImpl::handleResolution( - Clause* queryCl, Literal* queryLit, Clause* resultCl, Literal* resultLit, ResultSubstitution* subs) const + Clause* queryCl, Literal* queryLit, Clause* resultCl, Literal* resultLit, ResultSubstitution* subs, SplitSet*& blockingSplits) const { if constexpr (!enabled) { return true; @@ -424,7 +457,7 @@ bool ConditionalRedundancyHandlerImpl::handleResol // Note that we're inserting into the data of one clause based on the *other* clause { - bool doInsert = resultLit->isPositive() && resultCl->noSplits(); + bool doInsert = resultLit->isPositive(); auto lits = LiteralSet::getEmpty(); if constexpr (litC) { @@ -442,14 +475,23 @@ bool ConditionalRedundancyHandlerImpl::handleResol } } + auto splits = SplitSet::getEmpty(); + if constexpr (avatarC) { + splits = resultCl->splits(); + } else { + if (!resultCl->noSplits()) { + doInsert = false; + } + } + auto dataPtr = getDataPtr(queryCl, /*doAllocate=*/doInsert); - if (dataPtr && !(*dataPtr)->checkAndInsert(_ord, subs, false, lits, doInsert)) { + if (dataPtr && !(*dataPtr)->checkAndInsert(_ord, subs, false, lits, _splitter, blockingSplits, doInsert, splits)) { env.statistics->skippedResolution++; return false; } } { - bool doInsert = queryLit->isPositive() && queryCl->noSplits(); + bool doInsert = queryLit->isPositive(); auto lits = LiteralSet::getEmpty(); if constexpr (litC) { @@ -467,8 +509,17 @@ bool ConditionalRedundancyHandlerImpl::handleResol } } + auto splits = SplitSet::getEmpty(); + if constexpr (avatarC) { + splits = queryCl->splits(); + } else { + if (!queryCl->noSplits()) { + doInsert = false; + } + } + auto dataPtr = getDataPtr(resultCl, /*doAllocate=*/doInsert); - if (dataPtr && !(*dataPtr)->checkAndInsert(_ord, subs, true, lits, doInsert)) { + if (dataPtr && !(*dataPtr)->checkAndInsert(_ord, subs, true, lits, _splitter, blockingSplits, doInsert, splits)) { env.statistics->skippedResolution++; return false; } @@ -478,7 +529,7 @@ bool ConditionalRedundancyHandlerImpl::handleResol template bool ConditionalRedundancyHandlerImpl::handleReductiveUnaryInference( - Clause* premise, RobSubstitution* subs) const + Clause* premise, RobSubstitution* subs, SplitSet*& blockingSplits) const { if constexpr (!enabled) { return true; @@ -486,7 +537,12 @@ bool ConditionalRedundancyHandlerImpl::handleReduc auto dataPtr = getDataPtr(premise, /*doAllocate=*/true); auto subst = ResultSubstitution::fromSubstitution(subs, 0, 0); auto lits = LiteralSet::getEmpty(); - if (!(*dataPtr)->checkAndInsert(_ord, subst.ptr(), false, lits, /*doInsert=*/true)) { + auto splits = SplitSet::getEmpty(); + if (!(*dataPtr)->checkAndInsert(_ord, subst.ptr(), false, lits, _splitter, blockingSplits, /*doInsert=*/true, splits)) { + // TODO fix this by calling Splitter from each calling inference + if (!blockingSplits->isEmpty()) { + return true; + } return false; } return true; diff --git a/Shell/ConditionalRedundancyHandler.hpp b/Shell/ConditionalRedundancyHandler.hpp index 619ee2c33..ef55bbafe 100644 --- a/Shell/ConditionalRedundancyHandler.hpp +++ b/Shell/ConditionalRedundancyHandler.hpp @@ -21,6 +21,8 @@ #include "Lib/Stack.hpp" #include "Inferences/DemodulationHelper.hpp" +#include "Saturation/Splitter.hpp" + #include "Options.hpp" namespace Shell { @@ -31,22 +33,25 @@ using namespace Indexing; class ConditionalRedundancyHandler { public: - static ConditionalRedundancyHandler* create(const Options& opts, const Ordering* ord); + static ConditionalRedundancyHandler* create(const Options& opts, const Ordering* ord, const Splitter* splitter); static void destroyClauseData(Clause* cl); virtual ~ConditionalRedundancyHandler() = default; virtual bool checkSuperposition( - Clause* eqClause, Literal* eqLit, Clause* rwClause, Literal* rwLit, bool eqIsResult, ResultSubstitution* subs) const = 0; + Clause* eqClause, Literal* eqLit, Clause* rwClause, Literal* rwLit, + bool eqIsResult, ResultSubstitution* subs, SplitSet*& blockingSplits) const = 0; virtual void insertSuperposition( Clause* eqClause, Clause* rwClause, TermList rwTermS, TermList tgtTermS, TermList eqLHS, Literal* rwLitS, Literal* eqLit, Ordering::Result eqComp, bool eqIsResult, ResultSubstitution* subs) const = 0; virtual bool handleResolution( - Clause* queryCl, Literal* queryLit, Clause* resultCl, Literal* resultLit, ResultSubstitution* subs) const = 0; + Clause* queryCl, Literal* queryLit, Clause* resultCl, Literal* resultLit, + ResultSubstitution* subs, SplitSet*& blockingSplits) const = 0; - virtual bool handleReductiveUnaryInference(Clause* premise, RobSubstitution* subs) const = 0; + virtual bool handleReductiveUnaryInference(Clause* premise, RobSubstitution* subs, + SplitSet*& blockingSplits) const = 0; protected: class SubstitutionCoverTree; @@ -63,12 +68,13 @@ class ConditionalRedundancyHandlerImpl { public: ConditionalRedundancyHandlerImpl() = default; - ConditionalRedundancyHandlerImpl(const Options& opts, const Ordering* ord) - : _ord(ord), _demodulationHelper(opts,ord) {} + ConditionalRedundancyHandlerImpl(const Options& opts, const Ordering* ord, const Splitter* splitter) + : _ord(ord), _splitter(splitter), _demodulationHelper(opts,ord) {} /** Returns false if superposition should be skipped. */ bool checkSuperposition( - Clause* eqClause, Literal* eqLit, Clause* rwClause, Literal* rwLit, bool eqIsResult, ResultSubstitution* subs) const override; + Clause* eqClause, Literal* eqLit, Clause* rwClause, Literal* rwLit, + bool eqIsResult, ResultSubstitution* subs, SplitSet*& blockingSplits) const override; void insertSuperposition( Clause* eqClause, Clause* rwClause, TermList rwTermS, TermList tgtTermS, TermList eqLHS, @@ -76,13 +82,15 @@ class ConditionalRedundancyHandlerImpl /** Returns false if resolution should be skipped. */ bool handleResolution( - Clause* queryCl, Literal* queryLit, Clause* resultCl, Literal* resultLit, ResultSubstitution* subs) const override; + Clause* queryCl, Literal* queryLit, Clause* resultCl, Literal* resultLit, + ResultSubstitution* subs, SplitSet*& blockingSplits) const override; /** Returns false if inference should be skipped. */ - bool handleReductiveUnaryInference(Clause* premise, RobSubstitution* subs) const override; + bool handleReductiveUnaryInference(Clause* premise, RobSubstitution* subs, SplitSet*& blockingSplits) const override; private: const Ordering* _ord; + const Splitter* _splitter; Inferences::DemodulationHelper _demodulationHelper; }; diff --git a/Shell/Statistics.cpp b/Shell/Statistics.cpp index a291e45ff..1a3918523 100644 --- a/Shell/Statistics.cpp +++ b/Shell/Statistics.cpp @@ -62,10 +62,6 @@ Statistics::Statistics() cForwardSuperposition(0), cBackwardSuperposition(0), selfSuperposition(0), - skippedSuperposition(0), - skippedResolution(0), - skippedEqualityResolution(0), - skippedEqualityFactoring(0), equalityFactoring(0), equalityResolution(0), forwardExtensionalityResolution(0), @@ -111,6 +107,13 @@ Statistics::Statistics() proxyEliminations(0), leibnizElims(0), booleanSimps(0), + skippedSuperposition(0), + skippedResolution(0), + skippedEqualityResolution(0), + skippedEqualityFactoring(0), + skippedInferencesDueToOrderingConstraints(0), + skippedInferencesDueToAvatarConstraints(0), + skippedInferencesDueToLiteralConstraints(0), duplicateLiterals(0), trivialInequalities(0), forwardSubsumptionResolution(0), @@ -360,7 +363,6 @@ void Statistics::print(ostream& out) HEADING("Generating Inferences",resolution+urResolution+cResolution+factoring+ forwardSuperposition+backwardSuperposition+selfSuperposition+ - skippedSuperposition+skippedResolution+skippedEqualityResolution+skippedEqualityFactoring+ cForwardSuperposition+cBackwardSuperposition+cSelfSuperposition+leibnizElims+ equalityFactoring+equalityResolution+forwardExtensionalityResolution+ backwardExtensionalityResolution+argumentCongruence+negativeExtensionality+ @@ -373,10 +375,6 @@ void Statistics::print(ostream& out) COND_OUT("Forward superposition", forwardSuperposition); COND_OUT("Backward superposition", backwardSuperposition); COND_OUT("Self superposition", selfSuperposition); - COND_OUT("Skipped superposition", skippedSuperposition); - COND_OUT("Skipped resolution", skippedResolution); - COND_OUT("Skipped equality resolution", skippedEqualityResolution); - COND_OUT("Skipped equality factoring", skippedEqualityFactoring); COND_OUT("Forward superposition with abstraction", cForwardSuperposition); COND_OUT("Backward superposition with abstraction", cBackwardSuperposition); COND_OUT("Self superposition with abstraction", cSelfSuperposition); @@ -425,6 +423,19 @@ void Statistics::print(ostream& out) COND_OUT("Self sub-variable superposition", selfSubVarSup); SEPARATOR; + HEADING("Redundant Inferences", + skippedSuperposition+skippedResolution+skippedEqualityResolution+skippedEqualityFactoring+ + skippedInferencesDueToOrderingConstraints+skippedInferencesDueToAvatarConstraints+ + skippedInferencesDueToLiteralConstraints); + COND_OUT("Skipped superposition", skippedSuperposition); + COND_OUT("Skipped resolution", skippedResolution); + COND_OUT("Skipped equality resolution", skippedEqualityResolution); + COND_OUT("Skipped equality factoring", skippedEqualityFactoring); + COND_OUT("Skipped inferences due to ordering constraints", skippedInferencesDueToOrderingConstraints); + COND_OUT("Skipped inferences due to AVATAR constraints", skippedInferencesDueToAvatarConstraints); + COND_OUT("Skipped inferences due to literal constraints", skippedInferencesDueToLiteralConstraints); + SEPARATOR; + HEADING("Term algebra simplifications",taDistinctnessSimplifications+ taDistinctnessTautologyDeletions+taInjectivitySimplifications+ taAcyclicityGeneratedDisequalities+taNegativeInjectivitySimplifications); diff --git a/Shell/Statistics.hpp b/Shell/Statistics.hpp index 772489328..7a1477e1c 100644 --- a/Shell/Statistics.hpp +++ b/Shell/Statistics.hpp @@ -98,14 +98,6 @@ class Statistics { unsigned cBackwardSuperposition; /** number of clauses generated by self superposition*/ unsigned selfSuperposition; - /** number of skipped superpositions */ - unsigned skippedSuperposition; - /** number of skipped binary resolutions */ - unsigned skippedResolution; - /** number of skipped equality resolutions */ - unsigned skippedEqualityResolution; - /** number of skipped equality factorings */ - unsigned skippedEqualityFactoring; /** number of clauses generated by equality factoring*/ unsigned equalityFactoring; /** number of clauses generated by equality resolution*/ @@ -162,6 +154,14 @@ class Statistics { unsigned proxyEliminations; unsigned leibnizElims; unsigned booleanSimps; + // Redundant inferences + unsigned skippedSuperposition; + unsigned skippedResolution; + unsigned skippedEqualityResolution; + unsigned skippedEqualityFactoring; + unsigned skippedInferencesDueToOrderingConstraints; + unsigned skippedInferencesDueToAvatarConstraints; + unsigned skippedInferencesDueToLiteralConstraints; // Simplifying inferences /** number of duplicate literals deleted */ unsigned duplicateLiterals; From 6219018ec83523c3e090fec46bfa862e01808914 Mon Sep 17 00:00:00 2001 From: Marton Hajdu Date: Wed, 24 Jul 2024 09:23:22 +0200 Subject: [PATCH 09/19] Check unification of equations initially for each clause --- Saturation/SaturationAlgorithm.cpp | 2 ++ Shell/ConditionalRedundancyHandler.cpp | 22 ++++++++++++++++++++-- Shell/ConditionalRedundancyHandler.hpp | 2 ++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/Saturation/SaturationAlgorithm.cpp b/Saturation/SaturationAlgorithm.cpp index 3cf91d2ec..d0c370b71 100644 --- a/Saturation/SaturationAlgorithm.cpp +++ b/Saturation/SaturationAlgorithm.cpp @@ -1152,6 +1152,8 @@ void SaturationAlgorithm::activate(Clause* cl) env.statistics->activeClauses++; _active->add(cl); + _conditionalRedundancyHandler->checkEquations(cl); + auto generated = TIME_TRACE_EXPR(TimeTrace::CLAUSE_GENERATION, _generator->generateSimplify(cl)); auto toAdd = TIME_TRACE_ITER(TimeTrace::CLAUSE_GENERATION, generated.clauses); diff --git a/Shell/ConditionalRedundancyHandler.cpp b/Shell/ConditionalRedundancyHandler.cpp index 0014c2aff..196667557 100644 --- a/Shell/ConditionalRedundancyHandler.cpp +++ b/Shell/ConditionalRedundancyHandler.cpp @@ -72,7 +72,7 @@ class ConditionalRedundancyHandler::SubstitutionCoverTree return !check(ts, ord, lits, splitter, blockingSplits); } - void insert(const Ordering* ord, ResultSubstitution* subst, bool result, const LiteralSet* lits, const Splitter* splitter, SplitSet* splits, Term* lhs=nullptr, Term* rhs=nullptr) + void insert(ResultSubstitution* subst, bool result, const LiteralSet* lits, const Splitter* splitter, SplitSet* splits, Term* lhs=nullptr, Term* rhs=nullptr) { auto ts = getInstances([subst,result](unsigned v) { return subst->applyTo(TermList::var(v),result); }); auto ld = createEntry(ts, lhs, rhs, lits, splitter, splits); @@ -318,6 +318,24 @@ void ConditionalRedundancyHandler::destroyClauseData(Clause* cl) delete ptr; } +void ConditionalRedundancyHandler::checkEquations(Clause* cl) const +{ + cl->iterLits().forEach([cl](Literal* lit){ + if (!lit->isEquality() || lit->isNegative()) { + return; + } + auto t0 = lit->termArg(0); + auto t1 = lit->termArg(1); + RobSubstitution subs; + if (!subs.unify(t0,0,t1,0)) { + return; + } + auto clDataPtr = getDataPtr(cl, /*doAllocate=*/true); + auto rsubs = ResultSubstitution::fromSubstitution(&subs, 0, 0); + (*clDataPtr)->insert(rsubs.ptr(), false, LiteralSet::getEmpty(), nullptr, SplitSet::getEmpty()); + }); +} + ConditionalRedundancyHandler::SubstitutionCoverTree** ConditionalRedundancyHandler::getDataPtr(Clause* cl, bool doAllocate) { if (!doAllocate) { @@ -442,7 +460,7 @@ void ConditionalRedundancyHandlerImpl::insertSuper auto rwClDataPtr = getDataPtr(rwClause, /*doAllocate=*/true); - (*rwClDataPtr)->insert(_ord, subs, !eqIsResult, lits, _splitter, splits, + (*rwClDataPtr)->insert(subs, !eqIsResult, lits, _splitter, splits, eqComp != Ordering::LESS ? rwTermS.term() : nullptr, eqComp != Ordering::LESS ? tgtTermS.term() : nullptr); } diff --git a/Shell/ConditionalRedundancyHandler.hpp b/Shell/ConditionalRedundancyHandler.hpp index ef55bbafe..4cb14679c 100644 --- a/Shell/ConditionalRedundancyHandler.hpp +++ b/Shell/ConditionalRedundancyHandler.hpp @@ -53,6 +53,8 @@ class ConditionalRedundancyHandler virtual bool handleReductiveUnaryInference(Clause* premise, RobSubstitution* subs, SplitSet*& blockingSplits) const = 0; + void checkEquations(Clause* cl) const; + protected: class SubstitutionCoverTree; From 751f6f301069cfbf90f16dd0bbd0ac4264f9383a Mon Sep 17 00:00:00 2001 From: Marton Hajdu Date: Wed, 24 Jul 2024 10:00:27 +0200 Subject: [PATCH 10/19] Use secondary ordering check when first is trivial when inserting superposition --- Inferences/DemodulationHelper.cpp | 5 ++- Inferences/DemodulationHelper.hpp | 2 +- Shell/ConditionalRedundancyHandler.cpp | 49 ++++++++++++++++++-------- 3 files changed, 40 insertions(+), 16 deletions(-) diff --git a/Inferences/DemodulationHelper.cpp b/Inferences/DemodulationHelper.cpp index 7ca47cdae..067049be7 100644 --- a/Inferences/DemodulationHelper.cpp +++ b/Inferences/DemodulationHelper.cpp @@ -74,12 +74,15 @@ bool isRenamingOn(const SubstApplicator* applicator, TermList t) } bool DemodulationHelper::isPremiseRedundant(Clause* rwCl, Literal* rwLit, TermList rwTerm, - TermList tgtTerm, TermList eqLHS, const SubstApplicator* eqApplicator) const + TermList tgtTerm, TermList eqLHS, const SubstApplicator* eqApplicator, Ordering::Result* comp) const { ASS(redundancyCheckNeededForPremise(rwCl, rwLit, rwTerm)); TermList other=EqHelper::getOtherEqualitySide(rwLit, rwTerm); Ordering::Result tord = _ord->compare(tgtTerm, other); + if (comp) { + *comp = tord; + } if (tord == Ordering::LESS) { return true; } diff --git a/Inferences/DemodulationHelper.hpp b/Inferences/DemodulationHelper.hpp index 3da7f8ae6..eda4e91f3 100644 --- a/Inferences/DemodulationHelper.hpp +++ b/Inferences/DemodulationHelper.hpp @@ -26,7 +26,7 @@ class DemodulationHelper { bool redundancyCheckNeededForPremise(Clause* rwCl, Literal* rwLit, TermList rwTerm) const; bool isPremiseRedundant(Clause* rwCl, Literal* rwLit, TermList rwTerm, TermList tgtTerm, - TermList eqLHS, const SubstApplicator* applicator) const; + TermList eqLHS, const SubstApplicator* applicator, Ordering::Result* comp = nullptr) const; private: bool _redundancyCheck; diff --git a/Shell/ConditionalRedundancyHandler.cpp b/Shell/ConditionalRedundancyHandler.cpp index 196667557..d744499bc 100644 --- a/Shell/ConditionalRedundancyHandler.cpp +++ b/Shell/ConditionalRedundancyHandler.cpp @@ -15,6 +15,7 @@ #include "ConditionalRedundancyHandler.hpp" #include "Kernel/Clause.hpp" +#include "Kernel/EqHelper.hpp" #include "Kernel/TermIterators.hpp" #include "Kernel/SortHelper.hpp" #include "Kernel/SubstHelper.hpp" @@ -414,22 +415,40 @@ void ConditionalRedundancyHandlerImpl::insertSuper }; Applicator appl(subs, !eqIsResult); + Ordering::Result otherComp; - auto doInsert = + auto redundancyCheck = // TODO this demodulation redundancy check could be added as constraints (!_demodulationHelper.redundancyCheckNeededForPremise(rwClause, rwLitS, rwTermS) || // TODO for rwClause->length()!=1 the function isPremiseRedundant does not work yet - (rwClause->length()==1 && _demodulationHelper.isPremiseRedundant(rwClause, rwLitS, rwTermS, tgtTermS, eqLHS, &appl))); - - if (!doInsert) { - return; - } - - // if the equation is not oriented, consider adding ordering constraints - if (eqComp != Ordering::LESS && !(ordC && rwTermS.containsAllVariablesOf(tgtTermS))) { - return; + (rwClause->length()==1 && _demodulationHelper.isPremiseRedundant(rwClause, rwLitS, rwTermS, tgtTermS, eqLHS, &appl, &otherComp))); + + // create ordering constraints + Term* ordLhs = nullptr; + Term* ordRhs = nullptr; + if constexpr (ordC) { + // TODO we cannot handle them together yet + if (eqComp != Ordering::LESS) { + if (!redundancyCheck || !rwTermS.containsAllVariablesOf(tgtTermS)) { + return; + } + ordLhs = rwTermS.term(); + ordRhs = tgtTermS.term(); + } else if (!redundancyCheck) { + TermList other = EqHelper::getOtherEqualitySide(rwLitS, rwTermS); + if (otherComp != Ordering::INCOMPARABLE || !other.containsAllVariablesOf(tgtTermS)) { + return; + } + ordLhs = other.term(); + ordRhs = tgtTermS.term(); + } + } else { + if (eqComp != Ordering::LESS || !redundancyCheck) { + return; + } } + // create literal constraints auto lits = LiteralSet::getEmpty(); if constexpr (litC) { if (eqClause->numSelected()!=1) { @@ -449,6 +468,7 @@ void ConditionalRedundancyHandlerImpl::insertSuper } } + // create AVATAR constraints auto splits = SplitSet::getEmpty(); if constexpr (avatarC) { splits = eqClause->splits(); @@ -459,10 +479,7 @@ void ConditionalRedundancyHandlerImpl::insertSuper } auto rwClDataPtr = getDataPtr(rwClause, /*doAllocate=*/true); - - (*rwClDataPtr)->insert(subs, !eqIsResult, lits, _splitter, splits, - eqComp != Ordering::LESS ? rwTermS.term() : nullptr, - eqComp != Ordering::LESS ? tgtTermS.term() : nullptr); + (*rwClDataPtr)->insert(subs, !eqIsResult, lits, _splitter, splits, ordLhs, ordRhs); } template @@ -477,6 +494,7 @@ bool ConditionalRedundancyHandlerImpl::handleResol { bool doInsert = resultLit->isPositive(); + // create literal constraints auto lits = LiteralSet::getEmpty(); if constexpr (litC) { lits = LiteralSet::getFromIterator(resultCl->iterLits().filter([resultLit](Literal* lit) { @@ -493,6 +511,7 @@ bool ConditionalRedundancyHandlerImpl::handleResol } } + // create AVATAR constraints auto splits = SplitSet::getEmpty(); if constexpr (avatarC) { splits = resultCl->splits(); @@ -511,6 +530,7 @@ bool ConditionalRedundancyHandlerImpl::handleResol { bool doInsert = queryLit->isPositive(); + // create literal constraints auto lits = LiteralSet::getEmpty(); if constexpr (litC) { lits = LiteralSet::getFromIterator(queryCl->iterLits().filter([queryLit](Literal* lit) { @@ -527,6 +547,7 @@ bool ConditionalRedundancyHandlerImpl::handleResol } } + // create AVATAR constraints auto splits = SplitSet::getEmpty(); if constexpr (avatarC) { splits = queryCl->splits(); From 7505da18f886475cd5486f6af1125779eae0aefe Mon Sep 17 00:00:00 2001 From: Marton Hajdu Date: Thu, 25 Jul 2024 10:53:01 +0200 Subject: [PATCH 11/19] Refactor CodeTree::Matcher --- Indexing/ClauseCodeTree.cpp | 11 +- Indexing/ClauseCodeTree.hpp | 4 +- Indexing/CodeTree.cpp | 626 ++++++++++--------------- Indexing/CodeTree.hpp | 238 ++++------ Indexing/TermCodeTree.cpp | 4 +- Indexing/TermCodeTree.hpp | 4 +- Shell/ConditionalRedundancyHandler.cpp | 5 +- 7 files changed, 360 insertions(+), 532 deletions(-) diff --git a/Indexing/ClauseCodeTree.cpp b/Indexing/ClauseCodeTree.cpp index 43ddf9ceb..34c9507af 100644 --- a/Indexing/ClauseCodeTree.cpp +++ b/Indexing/ClauseCodeTree.cpp @@ -258,7 +258,7 @@ void ClauseCodeTree::remove(Clause* cl) } iteration_restart: - if(!rlm->next()) { + if(!rlm->execute()) { if(depth==0) { ASSERTION_VIOLATION; INVALID_OPERATION("clause to be removed was not found"); @@ -299,7 +299,7 @@ void ClauseCodeTree::remove(Clause* cl) void ClauseCodeTree::RemovingLiteralMatcher::init(CodeOp* entry_, LitInfo* linfos_, size_t linfoCnt_, ClauseCodeTree* tree_, Stack* firstsInBlocks_) { - RemovingMatcher::init(entry_, linfos_, linfoCnt_, tree_, firstsInBlocks_); + Matcher::init(tree_, entry_, linfos_, linfoCnt_, firstsInBlocks_); ALWAYS(prepareLiteral()); } @@ -339,10 +339,7 @@ void ClauseCodeTree::LiteralMatcher::init(CodeTree* tree_, CodeOp* entry_, { ASS_G(linfoCnt_,0); - Matcher::init(tree_,entry_); - - linfos=linfos_; - linfoCnt=linfoCnt_; + Matcher::init(tree_,entry_,linfos_,linfoCnt_); _eagerlyMatched=false; eagerResults.reset(); @@ -354,7 +351,7 @@ void ClauseCodeTree::LiteralMatcher::init(CodeTree* tree_, CodeOp* entry_, //(and those must be at the entry point or its alternatives) _eagerlyMatched=true; - _fresh=false; + fresh=false; CodeOp* sop=entry; while(sop) { if(sop->isSuccess()) { diff --git a/Indexing/ClauseCodeTree.hpp b/Indexing/ClauseCodeTree.hpp index c9c2de4aa..7694da10c 100644 --- a/Indexing/ClauseCodeTree.hpp +++ b/Indexing/ClauseCodeTree.hpp @@ -58,7 +58,7 @@ class ClauseCodeTree : public CodeTree bool removeOneOfAlternatives(CodeOp* op, Clause* cl, Stack* firstsInBlocks); struct RemovingLiteralMatcher - : public RemovingMatcher + : public Matcher { void init(CodeOp* entry_, LitInfo* linfos_, size_t linfoCnt_, ClauseCodeTree* tree_, Stack* firstsInBlocks_); @@ -72,7 +72,7 @@ class ClauseCodeTree : public CodeTree * * Here the actual execution of the code of the tree takes place */ struct LiteralMatcher - : public Matcher + : public Matcher { void init(CodeTree* tree, CodeOp* entry_, LitInfo* linfos_, size_t linfoCnt_, bool seekOnlySuccess=false); bool next(); diff --git a/Indexing/CodeTree.cpp b/Indexing/CodeTree.cpp index 5662ad5cb..5d9015502 100644 --- a/Indexing/CodeTree.cpp +++ b/Indexing/CodeTree.cpp @@ -528,7 +528,243 @@ CodeTree::CodeOp*& CodeTree::SearchStructImpl::targetOp(const T& val) return targets[left]; } -inline bool CodeTree::BaseMatcher::doCheckGroundTerm() +//////////////// Matcher //////////////////// + +template +bool CodeTree::Matcher::execute() +{ + if(fresh) { + fresh=false; + } + else { + //we backtrack from what we found in the previous run + if(!backtrack()) { + return false; + } + } + + bool shouldBacktrack=false; + for(;;) { + if(op->alternative()) { + if constexpr (removing) { + btStack.push(BTPointRemoving(tp, op->alternative(), firstsInBlocks->size())); + } else { + btStack.push(BTPoint(tp, op->alternative())); + } + } + switch(op->_instruction()) { + case SUCCESS_OR_FAIL: + if(op->isFail()) { + shouldBacktrack=true; + break; + } + if constexpr (removing) { + if (matchingClauses) { + //we can succeed only in certain depth and that will be handled separately + shouldBacktrack=true; + } + else { + //we are matching terms in a TermCodeTree + return true; + } + } else { + //yield successes only in the first round (we don't want to yield the + //same thing for each query literal) + if(curLInfo==0) { + return true; + } + else { + shouldBacktrack=true; + } + } + break; + case LIT_END: + ASS(matchingClauses); + return true; + case CHECK_GROUND_TERM: + shouldBacktrack=!doCheckGroundTerm(); + break; + case CHECK_FUN: + shouldBacktrack=!doCheckFun(); + break; + case ASSIGN_VAR: + if constexpr (removing) { + shouldBacktrack=!doAssignVar(); + } else { + doAssignVar(); + } + break; + case CHECK_VAR: + shouldBacktrack=!doCheckVar(); + break; + case SEARCH_STRUCT: + if(doSearchStruct()) { + //a new value of @b op is assigned, so restart the loop + continue; + } + else { + shouldBacktrack=true; + } + break; + } + if(shouldBacktrack) { + if(!backtrack()) { + return false; + } + shouldBacktrack=false; + } + else { + //the SEARCH_STRUCT operation does not appear in CodeBlocks + ASS(!op->isSearchStruct()); + //In each CodeBlock there is always either operation LIT_END or FAIL. + //As we haven't encountered one yet, we may safely increase the + //operation pointer + op++; + } + } +} + +template +void CodeTree::Matcher::init(CodeTree* tree_, CodeOp* entry_, LitInfo* linfos_, size_t linfoCnt_, Stack* firstsInBlocks_) +{ + tree=tree_; + entry=entry_; + + linfos=linfos_; + linfoCnt=linfoCnt_; + + if constexpr (removing) { + firstsInBlocks=firstsInBlocks_; + initFIBDepth=firstsInBlocks->size(); + } + + fresh=true; + _matched=false; + curLInfo=0; + + bindings.ensure(tree->_maxVarCnt); + btStack.reset(); + + matchingClauses=tree->_clauseCodeTree; +} + +/** + * Is called when we need to retrieve a new result. + * It does not only backtrack to the next alternative to try, + * but if there are no more alternatives, it goes back to the + * entry point and starts evaluating new literal info (if there + * is some left). + */ +template +bool CodeTree::Matcher::backtrack() +{ + if(btStack.isEmpty()) { + curLInfo++; + return prepareLiteral(); + } + auto bp=btStack.pop(); + tp=bp.tp; + op=bp.op; + if constexpr (removing) { + firstsInBlocks->truncate(bp.fibDepth); + firstsInBlocks->push(op); + } + return true; +} + +template +bool CodeTree::Matcher::prepareLiteral() +{ + if constexpr (removing) { + firstsInBlocks->truncate(initFIBDepth); + } + if(curLInfo>=linfoCnt) { + return false; + } + ft=linfos[curLInfo].ft; + tp=0; + op=entry; + return true; +} + +template +inline bool CodeTree::Matcher::doAssignVar() +{ + ASS_EQ(op->_instruction(), ASSIGN_VAR); + + unsigned var=op->_arg(); + const FlatTerm::Entry* fte=&(*ft)[tp]; + if(fte->isVar()) { + bindings[var]=TermList::var(fte->_number()); + tp++; + } + else { + // in the removing case we are looking for variants + // and they match only other variables into variables + if constexpr (removing) { + return false; + } + ASS(fte->isFun()); + fte++; + ASS_EQ(fte->_tag(), FlatTerm::FUN_TERM_PTR); + ASS(fte->_term()); + bindings[var]=TermList(fte->_term()); + fte++; + ASS_EQ(fte->_tag(), FlatTerm::FUN_RIGHT_OFS); + tp+=fte->_number(); + } + return true; +} + +template +inline bool CodeTree::Matcher::doCheckVar() +{ + ASS_EQ(op->_instruction(), CHECK_VAR); + + unsigned var=op->_arg(); + const FlatTerm::Entry* fte=&(*ft)[tp]; + if (fte->isVar()) { + if(bindings[var]!=TermList::var(fte->_number())) { + return false; + } + tp++; + } + else { + // in the removing case we are looking for variants + // and they match only other variables into variables + if constexpr (removing) { + return false; + } + ASS(fte->isFun()); + fte++; + ASS_EQ(fte->_tag(), FlatTerm::FUN_TERM_PTR); + if(bindings[var]!=TermList(fte->_term())) { + return false; + } + fte++; + ASS_EQ(fte->_tag(), FlatTerm::FUN_RIGHT_OFS); + tp+=fte->_number(); + } + return true; +} + +template +inline bool CodeTree::Matcher::doCheckFun() +{ + ASS_EQ(op->_instruction(), CHECK_FUN); + + unsigned functor=op->_arg(); + FlatTerm::Entry& fte=(*ft)[tp]; + if(!fte.isFun(functor)) { + return false; + } + fte.expand(); + tp+=FlatTerm::FUNCTION_ENTRY_COUNT; + return true; +} + +template +inline bool CodeTree::Matcher::doCheckGroundTerm() { ASS_EQ(op->_instruction(), CHECK_GROUND_TERM); @@ -551,6 +787,27 @@ inline bool CodeTree::BaseMatcher::doCheckGroundTerm() return true; } +template +inline bool CodeTree::Matcher::doSearchStruct() +{ + ASS_EQ(op->_instruction(), SEARCH_STRUCT); + + const FlatTerm::Entry* fte=&(*ft)[tp]; + CodeOp* target=op->getSearchStruct()->getTargetOp(fte); + if(!target) { + return false; + } + op=target; + // TODO look at this if something crashes + if constexpr (removing) { + firstsInBlocks->push(op); + } + return true; +} + +template struct CodeTree::Matcher; +template struct CodeTree::Matcher; + //////////////// auxiliary //////////////////// CodeTree::CodeTree() @@ -1146,186 +1403,6 @@ void CodeTree::optimizeMemoryAfterRemoval(Stack* firstsInBlocks, CodeOp } } -void CodeTree::RemovingMatcher::init(CodeOp* entry_, LitInfo* linfos_, - size_t linfoCnt_, CodeTree* tree_, Stack* firstsInBlocks_) -{ - fresh=true; - entry=entry_; - linfos=linfos_; - linfoCnt=linfoCnt_; - tree=tree_; - firstsInBlocks=firstsInBlocks_; - - initFIBDepth=firstsInBlocks->size(); - - matchingClauses=tree->_clauseCodeTree; - bindings.ensure(tree->_maxVarCnt); - btStack.reset(); - - curLInfo=0; -} - -bool CodeTree::RemovingMatcher::next() -{ - if(fresh) { - fresh=false; - } - else { - //we backtrack from what we found in the previous run - if(!backtrack()) { - return false; - } - } - - - bool shouldBacktrack=false; - for(;;) { - if(op->alternative()) { - btStack.push(BTPoint(tp, op->alternative(), firstsInBlocks->size())); - } - switch(op->_instruction()) { - case SUCCESS_OR_FAIL: - if(op->isFail()) { - shouldBacktrack=true; - break; - } - if(matchingClauses) { - //we can succeed only in certain depth and that will be handled separately - shouldBacktrack=true; - } - else { - //we are matching terms in a TermCodeTree - return true; - } - break; - case LIT_END: - ASS(matchingClauses); - return true; - case CHECK_GROUND_TERM: - shouldBacktrack=!doCheckGroundTerm(); - break; - case CHECK_FUN: - shouldBacktrack=!doCheckFun(); - break; - case ASSIGN_VAR: - shouldBacktrack=!doAssignVar(); - break; - case CHECK_VAR: - shouldBacktrack=!doCheckVar(); - break; - case SEARCH_STRUCT: - if(doSearchStruct()) { - //a new value of @b op is assigned, so restart the loop - continue; - } - else { - shouldBacktrack=true; - } - break; - } - if(shouldBacktrack) { - if(!backtrack()) { - return false; - } - // dead store, left here in case it should have been a static? - // shouldBacktrack = false; - } - else { - //the SEARCH_STRUCT operation does not appear in CodeBlocks - ASS(!op->isSearchStruct()); - //In each CodeBlock there is always either operation LIT_END or FAIL. - //As we haven't encountered one yet, we may safely increase the - //operation pointer - op++; - } - } -} - -bool CodeTree::RemovingMatcher::backtrack() -{ - if(btStack.isEmpty()) { - curLInfo++; - return prepareLiteral(); - } - BTPoint bp=btStack.pop(); - tp=bp.tp; - op=bp.op; - firstsInBlocks->truncate(bp.fibDepth); - firstsInBlocks->push(op); - return true; -} - -bool CodeTree::RemovingMatcher::prepareLiteral() -{ - firstsInBlocks->truncate(initFIBDepth); - if(curLInfo>=linfoCnt) { - return false; - } - ft=linfos[curLInfo].ft; - tp=0; - op=entry; - return true; -} - -inline bool CodeTree::RemovingMatcher::doSearchStruct() -{ - ASS_EQ(op->_instruction(), SEARCH_STRUCT); - - const FlatTerm::Entry* fte=&(*ft)[tp]; - CodeOp* target=op->getSearchStruct()->getTargetOp(fte); - if(!target) { - return false; - } - op=target; - firstsInBlocks->push(op); - return true; -} - -inline bool CodeTree::RemovingMatcher::doCheckFun() -{ - ASS_EQ(op->_instruction(), CHECK_FUN); - - unsigned functor=op->_arg(); - FlatTerm::Entry& fte=(*ft)[tp]; - if(!fte.isFun(functor)) { - return false; - } - fte.expand(); - tp+=FlatTerm::FUNCTION_ENTRY_COUNT; - return true; -} - -inline bool CodeTree::RemovingMatcher::doAssignVar() -{ - ASS_EQ(op->_instruction(), ASSIGN_VAR); - - //we are looking for variants and they match only other variables into variables - unsigned var=op->_arg(); - const FlatTerm::Entry* fte=&(*ft)[tp]; - if(fte->_tag()!=FlatTerm::VAR) { - return false; - } - bindings[var]=fte->_number(); - tp++; - return true; -} - -inline bool CodeTree::RemovingMatcher::doCheckVar() -{ - ASS_EQ(op->_instruction(), CHECK_VAR); - - //we are looking for variants and they match only other variables into variables - unsigned var=op->_arg(); - const FlatTerm::Entry* fte=&(*ft)[tp]; - if(fte->_tag()!=FlatTerm::VAR || bindings[var]!=fte->_number()) { - return false; - } - tp++; - return true; -} - - - //////////////// retrieval //////////////////// void CodeTree::incTimeStamp() @@ -1337,191 +1414,4 @@ void CodeTree::incTimeStamp() } } -void CodeTree::Matcher::init(CodeTree* tree_, CodeOp* entry_) -{ - tree=tree_; - entry=entry_; - - _fresh=true; - _matched=false; - curLInfo=0; - btStack.reset(); - bindings.ensure(tree->_maxVarCnt); -} - -bool CodeTree::Matcher::execute() -{ - if(_fresh) { - _fresh=false; - } - else { - //we backtrack from what we found in the previous run - if(!backtrack()) { - return false; - } - } - - - bool shouldBacktrack=false; - for(;;) { - if(op->alternative()) { - btStack.push(BTPoint(tp, op->alternative())); - } - switch(op->_instruction()) { - case SUCCESS_OR_FAIL: - if(op->isFail()) { - shouldBacktrack=true; - break; - } - //yield successes only in the first round (we don't want to yield the - //same thing for each query literal) - if(curLInfo==0) { - return true; - } - else { - shouldBacktrack=true; - } - break; - case LIT_END: - return true; - case CHECK_GROUND_TERM: - shouldBacktrack=!doCheckGroundTerm(); - break; - case CHECK_FUN: - shouldBacktrack=!doCheckFun(); - break; - case ASSIGN_VAR: - doAssignVar(); - break; - case CHECK_VAR: - shouldBacktrack=!doCheckVar(); - break; - case SEARCH_STRUCT: - if(doSearchStruct()) { - //a new value of @b op is assigned, so restart the loop - continue; - } - else { - shouldBacktrack=true; - } - break; - } - if(shouldBacktrack) { - if(!backtrack()) { - return false; - } - shouldBacktrack=false; - } - else { - //the SEARCH_STRUCT operation does not appear in CodeBlocks - ASS(!op->isSearchStruct()); - //In each CodeBlock there is always either operation LIT_END or FAIL. - //As we haven't encountered one yet, we may safely increase the - //operation pointer - op++; - } - } -} - -/** - * Is called when we need to retrieve a new result. - * It does not only backtrack to the next alternative to try, - * but if there are no more alternatives, it goes back to the - * entry point and starts evaluating new literal info (if there - * is some left). - */ -bool CodeTree::Matcher::backtrack() -{ - if(btStack.isEmpty()) { - curLInfo++; - return prepareLiteral(); - } - BTPoint bp=btStack.pop(); - tp=bp.tp; - op=bp.op; - return true; -} - -bool CodeTree::Matcher::prepareLiteral() -{ - if(curLInfo>=linfoCnt) { - return false; - } - tp=0; - op=entry; - ft=linfos[curLInfo].ft; - return true; -} - -inline bool CodeTree::Matcher::doSearchStruct() -{ - ASS_EQ(op->_instruction(), SEARCH_STRUCT); - - const FlatTerm::Entry* fte=&(*ft)[tp]; - op=op->getSearchStruct()->getTargetOp(fte); - return op; -} - -inline bool CodeTree::Matcher::doCheckFun() -{ - ASS_EQ(op->_instruction(), CHECK_FUN); - - unsigned functor=op->_arg(); - FlatTerm::Entry& fte=(*ft)[tp]; - if(!fte.isFun(functor)) { - return false; - } - fte.expand(); - tp+=FlatTerm::FUNCTION_ENTRY_COUNT; - return true; -} - -inline void CodeTree::Matcher::doAssignVar() -{ - ASS_EQ(op->_instruction(), ASSIGN_VAR); - - unsigned var=op->_arg(); - const FlatTerm::Entry* fte=&(*ft)[tp]; - if(fte->_tag()==FlatTerm::VAR) { - bindings[var]=TermList(fte->_number(),false); - tp++; - } - else { - ASS(fte->isFun()); - fte++; - ASS_EQ(fte->_tag(), FlatTerm::FUN_TERM_PTR); - ASS(fte->_term()); - bindings[var]=TermList(fte->_term()); - fte++; - ASS_EQ(fte->_tag(), FlatTerm::FUN_RIGHT_OFS); - tp+=fte->_number(); - } -} - -inline bool CodeTree::Matcher::doCheckVar() -{ - ASS_EQ(op->_instruction(), CHECK_VAR); - - unsigned var=op->_arg(); - const FlatTerm::Entry* fte=&(*ft)[tp]; - if(fte->_tag()==FlatTerm::VAR) { - if(bindings[var]!=TermList(fte->_number(),false)) { - return false; - } - tp++; - } - else { - ASS(fte->isFun()); - fte++; - ASS_EQ(fte->_tag(), FlatTerm::FUN_TERM_PTR); - if(bindings[var]!=TermList(fte->_term())) { - return false; - } - fte++; - ASS_EQ(fte->_tag(), FlatTerm::FUN_RIGHT_OFS); - tp+=fte->_number(); - } - return true; -} - } diff --git a/Indexing/CodeTree.hpp b/Indexing/CodeTree.hpp index fbd5fc0a7..d16e9aaba 100644 --- a/Indexing/CodeTree.hpp +++ b/Indexing/CodeTree.hpp @@ -332,10 +332,51 @@ class CodeTree typedef Vector CodeBlock; typedef Stack CodeStack; + typedef DArray BindingArray; - struct BaseMatcher + /** + * Context for finding matches of literals + * + * Here the actual execution of the code of the tree takes place. + * + * The object is not initialized not only by constructor, but also by + * a call to the @b init function (inheritors should implement their + * own @b init function (possibly with other arguments) that will call + * this one. After use, the @b deinit function should be called (if + * present). This allows for reuse of a single object. + */ + template + struct Matcher { - public: + /** + * Backtracking point for the interpretation of the code tree. + */ + struct BTPoint + { + BTPoint(size_t tp, CodeOp* op) : tp(tp), op(op) {} + + /** Position in the flat term */ + size_t tp; + /** Pointer to the next operation */ + CodeOp* op; + }; + + struct BTPointRemoving + { + BTPointRemoving(size_t tp, CodeOp* op, size_t fibDepth) + : tp(tp), op(op), fibDepth(fibDepth) {} + + size_t tp; + CodeOp* op; + size_t fibDepth; + }; + + inline bool finished() const { return !fresh && !_matched; } + inline bool matched() const { return _matched && op->isLitEnd(); } + inline bool success() const { return _matched && op->isSuccess(); } + + bool execute(); + /** * Pointer to the current operation * @@ -343,9 +384,25 @@ class CodeTree * a call to the @b prepareLiteral function). */ CodeOp* op; + + BindingArray bindings; + + bool keepRecycled() const + { return bindings.keepRecycled() + || btStack.keepRecycled() + || (firstsInBlocks && firstsInBlocks->keepRecycled()); } + protected: + void init(CodeTree* tree_, CodeOp* entry_, LitInfo* linfos_ = 0, + size_t linfoCnt_ = 0, Stack* firstsInBlocks_ = 0); + bool backtrack(); + bool prepareLiteral(); + bool doAssignVar(); + bool doCheckVar(); + bool doCheckFun(); bool doCheckGroundTerm(); + bool doSearchStruct(); /** * Position in the flat term @@ -362,6 +419,38 @@ class CodeTree */ FlatTerm* ft; + /** the matcher object is initialized but no execution of code was done yet */ + bool fresh; + bool _matched; + + CodeOp* entry; + CodeTree* tree; + + /** + * Currently matched LitInfo object in case LitInfo objects + * are used (they are not in TermCodeTree::TermMatcher). + */ + size_t curLInfo; + /** + * Array of alternative LitInfo objects + * + * Must be initialized by inheritor. + */ + LitInfo* linfos; + /** + * Length of the @b linfos array + * + * Must be initialized by inheritor. + */ + size_t linfoCnt; + + /** Stack containing backtracking points */ + Stack> btStack; + + Stack* firstsInBlocks; + size_t initFIBDepth; + + bool matchingClauses; }; //////// auxiliary methods ////////// @@ -405,153 +494,10 @@ class CodeTree void optimizeMemoryAfterRemoval(Stack* firstsInBlocks, CodeOp* removedOp); - struct RemovingMatcher - : public BaseMatcher - { - public: - bool next(); - - bool keepRecycled() const - { return bindings.keepRecycled() - || btStack.keepRecycled() - || (firstsInBlocks && firstsInBlocks->keepRecycled()); } - - protected: - void init(CodeOp* entry_, LitInfo* linfos_, size_t linfoCnt_, - CodeTree* tree_, Stack* firstsInBlocks_); - - - bool prepareLiteral(); - bool backtrack(); - bool doSearchStruct(); - bool doCheckFun(); - bool doAssignVar(); - bool doCheckVar(); - - - struct BTPoint - { - BTPoint(size_t tp, CodeOp* op, size_t fibDepth) - : tp(tp), op(op), fibDepth(fibDepth) {} - - size_t tp; - CodeOp* op; - size_t fibDepth; - }; - - /** Variable bindings */ - DArray bindings; - - Stack btStack; - Stack* firstsInBlocks; - bool fresh; - size_t curLInfo; - - CodeOp* entry; - size_t initFIBDepth; - - LitInfo* linfos; - size_t linfoCnt; - - bool matchingClauses; - CodeTree* tree; - }; - - //////// retrieval ////////// - - /** - * Backtracking point for the interpretation of the code tree. - */ - struct BTPoint - { - BTPoint() {} - BTPoint(size_t tp, CodeOp* op) : tp(tp), op(op) {} - - /** Position in the flat term */ - size_t tp; - /** Pointer to the next operation */ - CodeOp* op; - }; - - typedef Stack BTStack; - typedef DArray BindingArray; - - /** - * Context for finding matches of literals - * - * Here the actual execution of the code of the tree takes place. - * - * The object is not initialized not only by constructor, but also by - * a call to the @b init function (inheritors should implement their - * own @b init function (possibly with other arguments) that will call - * this one. After use, the @b deinit function should be called (if - * present). This allows for reuse of a single object. - */ - struct Matcher - : public BaseMatcher - { - void init(CodeTree* tree, CodeOp* entry_); - - inline bool finished() const { return !_fresh && !_matched; } - inline bool matched() const { return _matched && op->isLitEnd(); } - inline bool success() const { return _matched && op->isSuccess(); } - - - - private: - bool backtrack(); - bool doSearchStruct(); - bool doCheckFun(); - void doAssignVar(); - bool doCheckVar(); - - protected: - bool execute(); - bool prepareLiteral(); - - public: - /** Variable bindings */ - BindingArray bindings; - bool keepRecycled() const { return bindings.keepRecycled(); } - - protected: - /** the matcher object is initialized but no execution of code was done yet */ - bool _fresh; - bool _matched; - - /** Stack containing backtracking points */ - BTStack btStack; - - CodeOp* entry; - - CodeTree* tree; - /** - * Array of alternative LitInfo objects - * - * Must be initialized by inheritor. - */ - LitInfo* linfos; - /** - * Length of the @b linfos array - * - * Must be initialized by inheritor. - */ - size_t linfoCnt; - - /** - * Currently matched LitInfo object in case LitInfo objects - * are used (they are not in TermCodeTree::TermMatcher). - */ - size_t curLInfo; - - }; - - void incTimeStamp(); //////// member variables ////////// - bool _clauseCodeTree; unsigned _curTimeStamp; @@ -559,10 +505,8 @@ class CodeTree unsigned _maxVarCnt; CodeBlock* _entryPoint; - }; } #endif // __CodeTree__ - diff --git a/Indexing/TermCodeTree.cpp b/Indexing/TermCodeTree.cpp index 878dd864d..ff0098629 100644 --- a/Indexing/TermCodeTree.cpp +++ b/Indexing/TermCodeTree.cpp @@ -91,7 +91,7 @@ void TermCodeTree::remove(const Data& data) Data* dptr = nullptr; for(;;) { - if (!rtm.next()) { + if (!rtm.execute()) { ASSERTION_VIOLATION; INVALID_OPERATION("term being removed was not found"); } @@ -135,7 +135,7 @@ template void TermCodeTree::RemovingTermMatcher::init(FlatTerm* ft_, TermCodeTree* tree_, Stack* firstsInBlocks_) { - RemovingMatcher::init(tree_->getEntryPoint(), 0, 0, tree_, firstsInBlocks_); + Matcher::init(tree_, tree_->getEntryPoint(), 0, 0, firstsInBlocks_); firstsInBlocks->push(entry); diff --git a/Indexing/TermCodeTree.hpp b/Indexing/TermCodeTree.hpp index 62e7ccf32..2ce694b83 100644 --- a/Indexing/TermCodeTree.hpp +++ b/Indexing/TermCodeTree.hpp @@ -52,7 +52,7 @@ class TermCodeTree : public CodeTree private: struct RemovingTermMatcher - : public RemovingMatcher + : public Matcher { public: void init(FlatTerm* ft_, TermCodeTree* tree_, Stack* firstsInBlocks_); @@ -61,7 +61,7 @@ class TermCodeTree : public CodeTree public: struct TermMatcher - : public Matcher + : public Matcher { TermMatcher(); diff --git a/Shell/ConditionalRedundancyHandler.cpp b/Shell/ConditionalRedundancyHandler.cpp index d744499bc..11470c091 100644 --- a/Shell/ConditionalRedundancyHandler.cpp +++ b/Shell/ConditionalRedundancyHandler.cpp @@ -240,15 +240,12 @@ class ConditionalRedundancyHandler::SubstitutionCoverTree } struct SubstMatcher - : public Matcher + : public Matcher { void init(CodeTree* tree, const TermStack& ts) { Matcher::init(tree,tree->getEntryPoint()); - linfos=0; - linfoCnt=0; - ft = FlatTerm::createUnexpanded(ts); op=entry; From 76494c6c8941fe32b5c46c2b032690f9da02985f Mon Sep 17 00:00:00 2001 From: Marton Hajdu Date: Thu, 25 Jul 2024 14:37:11 +0200 Subject: [PATCH 12/19] Resurrect code tree subsumption and subsumption resolution --- CMakeLists.txt | 2 + Indexing/CodeTree.cpp | 2 + Indexing/CodeTree.hpp | 4 +- Indexing/CodeTreeInterfaces.hpp | 1 + ...odeTreeForwardSubsumptionAndResolution.cpp | 73 +++++++++++++++++++ ...odeTreeForwardSubsumptionAndResolution.hpp | 43 +++++++++++ Saturation/SaturationAlgorithm.cpp | 14 +++- 7 files changed, 136 insertions(+), 3 deletions(-) create mode 100644 Inferences/CodeTreeForwardSubsumptionAndResolution.cpp create mode 100644 Inferences/CodeTreeForwardSubsumptionAndResolution.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index cfca57ab4..670c38842 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -382,6 +382,7 @@ set(VAMPIRE_INFERENCE_SOURCES Inferences/BackwardSubsumptionDemodulation.cpp Inferences/BackwardSubsumptionAndResolution.cpp Inferences/BinaryResolution.cpp + Inferences/CodeTreeForwardSubsumptionAndResolution.cpp Inferences/Condensation.cpp Inferences/DemodulationHelper.cpp Inferences/DistinctEqualitySimplifier.cpp @@ -420,6 +421,7 @@ set(VAMPIRE_INFERENCE_SOURCES Inferences/BackwardDemodulation.hpp Inferences/BackwardSubsumptionAndResolution.hpp Inferences/BinaryResolution.hpp + Inferences/CodeTreeForwardSubsumptionAndResolution.hpp Inferences/Condensation.hpp Inferences/DemodulationHelper.hpp Inferences/DistinctEqualitySimplifier.hpp diff --git a/Indexing/CodeTree.cpp b/Indexing/CodeTree.cpp index 5d9015502..2b5226dcf 100644 --- a/Indexing/CodeTree.cpp +++ b/Indexing/CodeTree.cpp @@ -303,6 +303,8 @@ CodeTree::CodeOp CodeTree::CodeOp::getLitEnd(ILStruct* ils) CodeOp res; res.setAlternative(0); res._setData(ils); + // order matters + res._setInstruction(LIT_END); ASS(res.isLitEnd()); return res; } diff --git a/Indexing/CodeTree.hpp b/Indexing/CodeTree.hpp index d16e9aaba..c5d55c9d0 100644 --- a/Indexing/CodeTree.hpp +++ b/Indexing/CodeTree.hpp @@ -214,11 +214,11 @@ class CodeTree inline ILStruct* getILS() { ASS(isLitEnd()); - return _data(); + return reinterpret_cast(reinterpret_cast(_data()) & ~(1UL << 1)); } inline const ILStruct* getILS() const { - return _data(); + return reinterpret_cast(reinterpret_cast(_data()) & ~(1UL << 1)); } const SearchStruct* getSearchStruct() const; diff --git a/Indexing/CodeTreeInterfaces.hpp b/Indexing/CodeTreeInterfaces.hpp index 25556e2cd..3ea4a9209 100644 --- a/Indexing/CodeTreeInterfaces.hpp +++ b/Indexing/CodeTreeInterfaces.hpp @@ -70,6 +70,7 @@ class CodeTreeSubsumptionIndex : public Index { public: + ClauseCodeTree* getClauseCodeTree() { return &_ct; } protected: void handleClause(Clause* c, bool adding) override; private: diff --git a/Inferences/CodeTreeForwardSubsumptionAndResolution.cpp b/Inferences/CodeTreeForwardSubsumptionAndResolution.cpp new file mode 100644 index 000000000..45424466f --- /dev/null +++ b/Inferences/CodeTreeForwardSubsumptionAndResolution.cpp @@ -0,0 +1,73 @@ +/* + * This file is part of the source code of the software program + * Vampire. It is protected by applicable + * copyright laws. + * + * This source code is distributed under the licence found here + * https://vprover.github.io/license.html + * and in the source directory + */ +/** + * @file CodeTreeForwardSubsumptionAndResolution.cpp + * Implements class CodeTreeForwardSubsumptionAndResolution. + */ + +#include "Saturation/SaturationAlgorithm.hpp" +#include "Shell/Statistics.hpp" + +#include "Inferences/CodeTreeForwardSubsumptionAndResolution.hpp" + +namespace Inferences { + +void CodeTreeForwardSubsumptionAndResolution::attach(SaturationAlgorithm *salg) +{ + ForwardSimplificationEngine::attach(salg); + auto index = static_cast( + _salg->getIndexManager()->request(FW_SUBSUMPTION_CODE_TREE)); + _ct = index->getClauseCodeTree(); +} + +void CodeTreeForwardSubsumptionAndResolution::detach() +{ + _ct = nullptr; + _salg->getIndexManager()->release(FW_SUBSUMPTION_CODE_TREE); + ForwardSimplificationEngine::detach(); +} + +bool CodeTreeForwardSubsumptionAndResolution::perform(Clause *cl, Clause *&replacement, ClauseIterator &premises) +{ + if (_ct->isEmpty()) { + return false; + } + + static ClauseCodeTree::ClauseMatcher cm; + + cm.init(_ct, cl, _subsumptionResolution); + + Clause* resultCl; + int resolvedQueryLit; + + while ((resultCl = cm.next(resolvedQueryLit))) { + if (resolvedQueryLit == -1) { + premises = pvi(getSingletonIterator(resultCl)); + env.statistics->forwardSubsumed++; + return true; + } + + LiteralStack res; + for (unsigned i = 0; i < cl->length(); i++) { + if (i == resolvedQueryLit) { + continue; + } + res.push((*cl)[i]); + } + replacement = Clause::fromStack(res, SimplifyingInference2(InferenceRule::SUBSUMPTION_RESOLUTION, cl, resultCl)); + premises = pvi(getSingletonIterator(resultCl)); + env.statistics->forwardSubsumptionResolution++; + return true; + } + + return false; +} + +} // namespace Inferences diff --git a/Inferences/CodeTreeForwardSubsumptionAndResolution.hpp b/Inferences/CodeTreeForwardSubsumptionAndResolution.hpp new file mode 100644 index 000000000..f93d5fffe --- /dev/null +++ b/Inferences/CodeTreeForwardSubsumptionAndResolution.hpp @@ -0,0 +1,43 @@ +/* + * This file is part of the source code of the software program + * Vampire. It is protected by applicable + * copyright laws. + * + * This source code is distributed under the licence found here + * https://vprover.github.io/license.html + * and in the source directory + */ +/** + * @file CodeTreeForwardSubsumptionAndResolution.hpp + * Defines class CodeTreeForwardSubsumptionAndResolution. + */ + +#ifndef __CodeTreeForwardSubsumptionAndResolution__ +#define __CodeTreeForwardSubsumptionAndResolution__ + +#include "Inferences/InferenceEngine.hpp" +#include "Indexing/CodeTreeInterfaces.hpp" + +namespace Inferences { + +class CodeTreeForwardSubsumptionAndResolution + : public ForwardSimplificationEngine +{ +public: + CodeTreeForwardSubsumptionAndResolution(bool subsumptionResolution) : _subsumptionResolution(subsumptionResolution) {} + + void attach(Saturation::SaturationAlgorithm *salg) override; + void detach() override; + + bool perform(Kernel::Clause *cl, + Kernel::Clause *&replacement, + Kernel::ClauseIterator &premises) override; + +private: + bool _subsumptionResolution; + Indexing::ClauseCodeTree* _ct; +}; + +}; // namespace Inferences + +#endif /* __CodeTreeForwardSubsumptionAndResolution__ */ diff --git a/Saturation/SaturationAlgorithm.cpp b/Saturation/SaturationAlgorithm.cpp index d0c370b71..1053eb73c 100644 --- a/Saturation/SaturationAlgorithm.cpp +++ b/Saturation/SaturationAlgorithm.cpp @@ -52,6 +52,7 @@ #include "Inferences/BackwardSubsumptionAndResolution.hpp" #include "Inferences/BackwardSubsumptionDemodulation.hpp" #include "Inferences/BinaryResolution.hpp" +#include "Inferences/CodeTreeForwardSubsumptionAndResolution.hpp" #include "Inferences/EqualityFactoring.hpp" #include "Inferences/EqualityResolution.hpp" #include "Inferences/BoolEqToDiseq.hpp" @@ -1620,7 +1621,16 @@ SaturationAlgorithm *SaturationAlgorithm::createFromOptions(Problem& prb, const } } +#define CODE_TREE_SUBSUMPTION 1 + if (opt.forwardSubsumption()) { +#if CODE_TREE_SUBSUMPTION + if (opt.forwardSubsumptionResolution()) { + res->addForwardSimplifierToFront(new CodeTreeForwardSubsumptionAndResolution(true)); + } else { + res->addForwardSimplifierToFront(new CodeTreeForwardSubsumptionAndResolution(false)); + } +#else if (opt.forwardSubsumptionResolution()) { ForwardSubsumptionAndResolution* fwd = new ForwardSubsumptionAndResolution(true); res->addForwardSimplifierToFront(fwd); @@ -1629,6 +1639,7 @@ SaturationAlgorithm *SaturationAlgorithm::createFromOptions(Problem& prb, const ForwardSubsumptionAndResolution* fwd = new ForwardSubsumptionAndResolution(false); res->addForwardSimplifierToFront(fwd); } +#endif } else if (opt.forwardSubsumptionResolution()) { USER_ERROR("Forward subsumption resolution requires forward subsumption to be enabled."); @@ -1668,7 +1679,8 @@ SaturationAlgorithm *SaturationAlgorithm::createFromOptions(Problem& prb, const res->_symEl = new SymElOutput(); } - res->_conditionalRedundancyHandler.reset(ConditionalRedundancyHandler::create(opt, &ordering, res->_splitter)); + res->_conditionalRedundancyHandler.reset(ConditionalRedundancyHandler::create(opt, &ordering, res->_splitter, + static_cast(res->_imgr->request(DEMODULATION_LHS_CODE_TREE)))); res->_answerLiteralManager = AnswerLiteralManager::getInstance(); // selects the right one, according to options! ASS(!res->_answerLiteralManager||opt.questionAnswering()!=Options::QuestionAnsweringMode::OFF); From 597b5a7b4f59c320f0771444c422920f62486714 Mon Sep 17 00:00:00 2001 From: Marton Hajdu Date: Tue, 30 Jul 2024 10:34:34 +0200 Subject: [PATCH 13/19] Add some functionality to the branch, variable orders, partial orders, confluence trees, mergable leaves in code trees --- CMakeLists.txt | 5 + Indexing/CodeTree.hpp | 155 ++++- ...odeTreeForwardSubsumptionAndResolution.cpp | 3 + Kernel/ConfluenceTree.hpp | 156 +++++ Kernel/Ordering.cpp | 16 + Kernel/Ordering.hpp | 1 + Kernel/PartialOrdering.cpp | 588 ++++++++++++++++++ Kernel/PartialOrdering.hpp | 96 +++ Kernel/VarOrder.cpp | 456 ++++++++++++++ Kernel/VarOrder.hpp | 74 +++ Lib/DHMap.hpp | 9 + Saturation/SaturationAlgorithm.cpp | 3 +- 12 files changed, 1558 insertions(+), 4 deletions(-) create mode 100644 Kernel/ConfluenceTree.hpp create mode 100644 Kernel/PartialOrdering.cpp create mode 100644 Kernel/PartialOrdering.hpp create mode 100644 Kernel/VarOrder.cpp create mode 100644 Kernel/VarOrder.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 670c38842..e893c8e35 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -248,6 +248,7 @@ set(VAMPIRE_KERNEL_SOURCES Kernel/Clause.hpp Kernel/ClauseQueue.hpp Kernel/ColorHelper.hpp + Kernel/ConfluenceTree.hpp Kernel/Connective.hpp Kernel/ELiteralSelector.hpp Kernel/EqHelper.hpp @@ -303,6 +304,10 @@ set(VAMPIRE_KERNEL_SOURCES Kernel/ApplicativeHelper.cpp Kernel/SKIKBO.hpp Kernel/SKIKBO.cpp + Kernel/VarOrder.cpp + Kernel/VarOrder.hpp + Kernel/PartialOrdering.cpp + Kernel/PartialOrdering.hpp Inferences/CNFOnTheFly.cpp Inferences/CNFOnTheFly.hpp Inferences/CombinatorDemodISE.cpp diff --git a/Indexing/CodeTree.hpp b/Indexing/CodeTree.hpp index c5d55c9d0..ba0c2e7bb 100644 --- a/Indexing/CodeTree.hpp +++ b/Indexing/CodeTree.hpp @@ -214,11 +214,11 @@ class CodeTree inline ILStruct* getILS() { ASS(isLitEnd()); - return reinterpret_cast(reinterpret_cast(_data()) & ~(1UL << 1)); + return reinterpret_cast(reinterpret_cast(_data()) & ~LIT_END); } inline const ILStruct* getILS() const { - return reinterpret_cast(reinterpret_cast(_data()) & ~(1UL << 1)); + return reinterpret_cast(reinterpret_cast(_data()) & ~LIT_END); } const SearchStruct* getSearchStruct() const; @@ -485,6 +485,11 @@ class CodeTree static CodeBlock* buildBlock(CodeStack& code, size_t cnt, ILStruct* prev); void incorporate(CodeStack& code); + template + static CodeBlock* buildBlock(CodeStack& code, size_t cnt, Data&& data); + template + void incorporate(CodeStack& code, Data&& data); + template void compressCheckOps(CodeOp* chainStart); @@ -507,6 +512,152 @@ class CodeTree CodeBlock* _entryPoint; }; +/** + * Build CodeBlock object from the last @b cnt instructions on the + * @b code stack. + * + * In this function is also set the value for the @b ILStruct::previous + * members. + */ +template +CodeTree::CodeBlock* CodeTree::buildBlock(CodeStack& code, size_t cnt, Data&& data) +{ + size_t clen=code.length(); + ASS_LE(cnt,clen); + + CodeBlock* res=CodeBlock::allocate(cnt+1); // one more for success + size_t sOfs=clen-cnt; + for(size_t i=0;iadd(std::move(data)); + (*res)[cnt] = CodeOp::getSuccess(ctr); + return res; +} + +/** + * Incorporate the code in @b code CodeStack into the tree, empty the + * stack, and make sure all no longer necessary structures are freed. + */ +template +void CodeTree::incorporate(CodeStack& code, Data&& data) +{ + ASS(!code.top().isSuccess()); + + if(isEmpty()) { + _entryPoint=buildBlock(code, code.length(), data); + code.reset(); + return; + } + + static const unsigned checkFunOpThreshold=5; //must be greater than 1 or it would cause loops + static const unsigned checkGroundTermOpThreshold=3; //must be greater than 1 or it would cause loops + + size_t clen=code.length(); + CodeOp** tailTarget; + size_t matchedCnt; + + { + CodeOp* treeOp = getEntryPoint(); + + for (size_t i = 0; i < clen; i++) { + ASS_NEQ(code[i]._instruction(),SUCCESS_OR_FAIL); + ASS_NEQ(code[i]._instruction(),LIT_END); + + CodeOp* chainStart = treeOp; + size_t checkFunOps = 0; + size_t checkGroundTermOps = 0; + for (;;) { + ASS_NEQ(treeOp->_instruction(),SUCCESS_OR_FAIL); + ASS_NEQ(treeOp->_instruction(),LIT_END); + + if (treeOp->isSearchStruct()) { + //handle the SEARCH_STRUCT + SearchStruct* ss = treeOp->getSearchStruct(); + CodeOp** toPtr; + if (ss->getTargetOpPtr(code[i], toPtr)) { + if (!*toPtr) { + tailTarget = toPtr; + matchedCnt = i; + goto matching_done; + } + treeOp = *toPtr; + continue; + } + } else if (code[i].equalsForOpMatching(*treeOp)) { + //matched, go to the next compiled instruction + break; + } + + if (treeOp->alternative()) { + //try alternative if there is some + treeOp = treeOp->alternative(); + } else { + //matching failed, we'll add the new branch here + tailTarget = &treeOp->alternative(); + matchedCnt = i; + goto matching_done; + } + + if (treeOp->isCheckFun()) { + checkFunOps++; + //if there were too many CHECK_FUN alternative operations, put them + //into a SEARCH_STRUCT + if (checkFunOps > checkFunOpThreshold) { + //we put CHECK_FUN ops into the SEARCH_STRUCT op, and + //restart with the chain + compressCheckOps(chainStart); + treeOp = chainStart; + checkFunOps = 0; + checkGroundTermOps = 0; + continue; + } + } + + if (treeOp->isCheckGroundTerm()) { + checkGroundTermOps++; + //if there were too many CHECK_GROUND_TERM alternative operations, put them + //into a SEARCH_STRUCT + if (checkGroundTermOps > checkGroundTermOpThreshold) { + //we put CHECK_GROUND_TERM ops into the SEARCH_STRUCT op, and + //restart with the chain + compressCheckOps(chainStart); + treeOp = chainStart; + checkFunOps = 0; + checkGroundTermOps = 0; + continue; + } + } + } // for(;;) + + //the SEARCH_STRUCT operation does not occur in a CodeBlock + ASS(!treeOp->isSearchStruct()); + //we can safely do increase because as long as we match and something + //remains in the @b code stack, we aren't at the end of the CodeBlock + //either (as each code block contains at least one FAIL or SUCCESS + //operation, and CodeStack contains at most one SUCCESS as the last + //operation) + treeOp++; + } + //We matched the whole CodeStack. If we are here, we are inserting an + //item multiple times. We will insert it anyway, because later we may + //be removing it multiple times as well. + matchedCnt = clen - 1; + ASS(treeOp->isSuccess()); + treeOp->getSuccessResult()->add(std::move(data)); + return; + } +matching_done: + ASS_L(matchedCnt,clen); + + CodeBlock* rem=buildBlock(code, clen-matchedCnt, data); + *tailTarget=&(*rem)[0]; + LOG_OP(rem->toString()<<" incorporated, mismatch caused by "<forwardSubsumed++; + cm.reset(); return true; } @@ -64,9 +65,11 @@ bool CodeTreeForwardSubsumptionAndResolution::perform(Clause *cl, Clause *&repla replacement = Clause::fromStack(res, SimplifyingInference2(InferenceRule::SUBSUMPTION_RESOLUTION, cl, resultCl)); premises = pvi(getSingletonIterator(resultCl)); env.statistics->forwardSubsumptionResolution++; + cm.reset(); return true; } + cm.reset(); return false; } diff --git a/Kernel/ConfluenceTree.hpp b/Kernel/ConfluenceTree.hpp new file mode 100644 index 000000000..d877bb280 --- /dev/null +++ b/Kernel/ConfluenceTree.hpp @@ -0,0 +1,156 @@ +/* + * This file is part of the source code of the software program + * Vampire. It is protected by applicable + * copyright laws. + * + * This source code is distributed under the licence found here + * https://vprover.github.io/license.html + * and in the source directory + */ +/** + * @file ConfluenceTree.hpp + */ + +#ifndef __ConfluenceTree__ +#define __ConfluenceTree__ + +#include "Forwards.hpp" + +#include "VarOrder.hpp" + +namespace Kernel { + +using namespace Lib; + +class ConfluenceTree +{ +public: + ~ConfluenceTree() + { + deleteNode(root); + } + + void add(const VarOrder& vo) { + auto tr = vo.transitive_reduction(); + // the location where we should add new nodes + Node** prevPtr = &root; + DHSet done; + auto curr = root; + while (curr) { + if (curr->success) { + // entirely covered, we can return + return; + } + auto c = vo.query(curr->x, curr->y); + auto i = Node::branchIndex(c); + if (c != PoComp::INCOMPARABLE) { + Edge e; + e.c = c; + e.x = curr->x; + e.y = curr->y; + done.insert(e); + + e.c = Ordering::reverse(c); + e.x = curr->y; + e.y = curr->x; + done.insert(e); + } + prevPtr = &curr->branches[i]; + curr = curr->branches[i]; + } + + while (tr) { + auto edge = tr->head(); + if (done.contains(edge)) { + tr = tr->tail(); + continue; + } + auto curr = new Node(); + curr->x = edge.x; + curr->y = edge.y; + + *prevPtr = curr; + prevPtr = &curr->branches[Node::branchIndex(edge.c)]; + tr = tr->tail(); + } + auto successNode = new Node(); + successNode->success = true; + *prevPtr = successNode; + } + + bool evaluate(const Ordering* ord, const SubstApplicator* applicator) const + { + auto curr = root; + while (curr) { + if (curr->success) { + return true; + } + auto comp = ord->compare(AppliedTerm(TermList::var(curr->x), applicator, true), AppliedTerm(TermList::var(curr->y), applicator, true)); + curr = curr->branches[Node::branchIndex(comp)]; + } + return false; + } + + std::string toString() const + { + std::string res; + Stack> todo; + todo.push(std::make_tuple(root,PoComp::INCOMPARABLE,0)); + + while (todo.isNonEmpty()) { + auto [curr,branch,depth] = todo.pop(); + std::stringstream str; + for (unsigned i = 0; i < depth; i++) { + str << " "; + } + str << Ordering::resultToStringInfix(branch) << " "; + if (!curr) { + str << "fail"; + } else if (curr->success) { + str << "success"; + } else { + str << "compare " << curr->x << " " << curr->y; + todo.push(std::make_tuple(curr->branches[3],PoComp::INCOMPARABLE,depth+1)); + todo.push(std::make_tuple(curr->branches[2],PoComp::EQUAL,depth+1)); + todo.push(std::make_tuple(curr->branches[1],PoComp::LESS,depth+1)); + todo.push(std::make_tuple(curr->branches[0],PoComp::GREATER,depth+1)); + } + str << std::endl; + res += str.str(); + } + return res; + } + +private: + struct Node { + bool success = false; + unsigned x; + unsigned y; + Node* branches[4]; + + static unsigned branchIndex(PoComp c) { + return static_cast(c)-1; + } + }; + + static void deleteNode(Node* n) { + Stack todo; + todo.push(n); + while (todo.isNonEmpty()) { + auto curr = todo.pop(); + if (!curr) { + continue; + } + todo.push(curr->branches[0]); + todo.push(curr->branches[1]); + todo.push(curr->branches[2]); + todo.push(curr->branches[3]); + delete curr; + } + } + + Node* root = nullptr; +}; + +} +#endif diff --git a/Kernel/Ordering.cpp b/Kernel/Ordering.cpp index 62380edac..c4054ede1 100644 --- a/Kernel/Ordering.cpp +++ b/Kernel/Ordering.cpp @@ -162,6 +162,22 @@ const char* Ordering::resultToString(Result r) } } +const char* Ordering::resultToStringInfix(Result r) +{ + switch(r) { + case GREATER: + return ">"; + case LESS: + return "<"; + case EQUAL: + return "="; + case INCOMPARABLE: + return "?"; + default: + ASSERTION_VIOLATION; + return 0; + } +} /** * Remove non-maximal literals from the list @b lits. The order * of remaining literals stays unchanged. diff --git a/Kernel/Ordering.hpp b/Kernel/Ordering.hpp index 9440e2a0a..223bbc49f 100644 --- a/Kernel/Ordering.hpp +++ b/Kernel/Ordering.hpp @@ -114,6 +114,7 @@ class Ordering } } static const char* resultToString(Result r); + static const char* resultToStringInfix(Result r); static Ordering* create(Problem& prb, const Options& opt); diff --git a/Kernel/PartialOrdering.cpp b/Kernel/PartialOrdering.cpp new file mode 100644 index 000000000..1d3f01414 --- /dev/null +++ b/Kernel/PartialOrdering.cpp @@ -0,0 +1,588 @@ +/* + * This file is part of the source code of the software program + * Vampire. It is protected by applicable + * copyright laws. + * + * This source code is distributed under the licence found here + * https://vprover.github.io/license.html + * and in the source directory + */ +/** + * @file PartialOrdering.cpp + * Implements class PartialOrdering. + */ + +#include + +#include "PartialOrdering.hpp" +#include "Lib/Stack.hpp" +#include "Lib/Metaiterators.hpp" + +#include "Debug/TimeProfiling.hpp" + +namespace Kernel { + +using namespace std; + +template +PartialOrdering::PartialOrdering() + : _nodes(), _inverse(), _size(0), _array(nullptr), _tr() +{ +} + +template +PartialOrdering::PartialOrdering(const PartialOrdering& other) + : _nodes(other._nodes), _inverse(other._inverse), _size(_nodes.size()), _array(nullptr), _tr() +{ + size_t arrSize = ((_size - 1) * _size / 2); + if (arrSize) { + void* mem = ALLOC_KNOWN(arrSize*sizeof(PoComp), "Kernel::PartialOrdering"); + _array = array_new(mem, arrSize); + // std::memset(_array, PoComp::INCOMPARABLE, arrSize*sizeof(PoComp)); + memcpy(_array,other._array,arrSize*sizeof(PoComp)); + } + _tr = List::copy(other._tr); +} + +template +PartialOrdering& PartialOrdering::operator=(const PartialOrdering& other) +{ + auto prevSize = ((_size - 1) * _size / 2); + if (prevSize) { + array_delete(_array, prevSize); + DEALLOC_KNOWN(_array, prevSize*sizeof(PoComp), "Kernel::PartialOrdering"); + } + _nodes.reset(); + _nodes.loadFromMap(other._nodes); + _inverse.reset(); + _inverse.loadFromMap(other._inverse); + _size = other._size; + size_t arrSize = ((_size - 1) * _size / 2); + if (arrSize) { + void* mem = ALLOC_KNOWN(arrSize*sizeof(PoComp), "Kernel::PartialOrdering"); + _array = array_new(mem, arrSize); + // std::memset(_array, PoComp::INCOMPARABLE, arrSize*sizeof(PoComp)); + memcpy(_array,other._array,arrSize*sizeof(PoComp)); + } + _tr = List::copy(other._tr); + return *this; +} + +template +PartialOrdering::~PartialOrdering() +{ + size_t arrSize = ((_size - 1) * _size / 2); + if (arrSize) { + array_delete(_array, arrSize); + DEALLOC_KNOWN(_array, arrSize*sizeof(PoComp), "Kernel::PartialOrdering"); + } + List::destroy(_tr); +} + +template +bool PartialOrdering::is_total() const +{ + size_t arrSize = ((_size - 1) * _size / 2); + for (size_t i = 0; i < arrSize; i++) { + if (_array[i]==PoComp::INCOMPARABLE) { + return false; + } + } + return true; +} + +template +PoComp PartialOrdering::get(const T& x, const T& y) const +{ + if (x == y) { + return PoComp::EQUAL; + } + if (!_nodes.find(x) || !_nodes.find(y)) { + return PoComp::INCOMPARABLE; + } + size_t idx_x = idx_of_elem(x); + size_t idx_y = idx_of_elem(y); + if (idx_x < idx_y) { + return idx_of(idx_x,idx_y); + } else if (idx_y < idx_x) { + return Ordering::reverse(idx_of(idx_y,idx_x)); + } + return PoComp::EQUAL; +} + +template +bool PartialOrdering::set(const T& x, const T& y, PoComp v) +{ + ASS_EQ(_size,_nodes.size()); + ASS(v != PoComp::INCOMPARABLE); + size_t idx_x = idx_of_elem_ext(x); + size_t idx_y = idx_of_elem_ext(y); + // cout << "setting " << x << "->" << idx_x << " " << y << "->" << idx_y << " to " << Ordering::resultToStringInfix(v) << endl; + if (idx_x == idx_y) { + return v==PoComp::EQUAL; + } + PoComp curr = PoComp::INCOMPARABLE; + if (idx_x < idx_y) { + curr = idx_of(idx_x,idx_y); + } else { + curr = Ordering::reverse(idx_of(idx_y,idx_x)); + } + // cout << "curr " << Ordering::resultToStringInfix(curr) << endl; + if (curr != PoComp::INCOMPARABLE && curr != v) { + return false; + } + set_idx_of_safe(idx_x,idx_y,v); + // if (idx_x < idx_y) { + // set_idx_of(idx_x,idx_y,v); + // } else { + // set_idx_of(idx_y,idx_x,Ordering::reverse(v)); + // } + if (curr == PoComp::INCOMPARABLE) { + set_inferred(idx_x,idx_y,v); + // add to transitive reduction + Edge e; + if (v == PoComp::EQUAL || v == PoComp::GREATER) { + e.x = x; + e.y = y; + e.c = v; + } else { + ASS(v != PoComp::INCOMPARABLE); + e.x = y; + e.y = x; + e.c = Ordering::reverse(v); + } + List::push(e, _tr); + } + // cout << "result " << to_string() << endl; + return true; +} + +template +const T& PartialOrdering::get_rep(const T& e) const +{ + const size_t* ptr = _nodes.findPtr(e); + if (!ptr) { + return e; + } + size_t idx_e = *ptr; + for (size_t idx_o = 0; idx_o < idx_e; idx_o++) { + if (idx_of(idx_o,idx_e) == PoComp::EQUAL) { + return _inverse.get(idx_o); + } + } + return e; +} + +template +size_t PartialOrdering::idx_of_elem(const T& e) const +{ + ASS(_nodes.find(e)); + return _nodes.get(e); +} + +template +size_t PartialOrdering::idx_of_elem_ext(const T& e) +{ + size_t *ptr; + // cout << "size " << _size << endl; + if (_nodes.getValuePtr(e, ptr, _size)) { + ALWAYS(_inverse.insert(_size, e)); + // cout << "extend" << endl; + // extend array + size_t prevSize = ((_size - 1) * _size / 2); + auto prevArray = _array; + _size++; + if (_size>1) { + size_t newSize = prevSize + _size; + void* mem = ALLOC_KNOWN(newSize*sizeof(PoComp), "Kernel::PartialOrdering"); + _array = array_new(mem, newSize); + std::memset(_array, 0, newSize*sizeof(PoComp)); + for (unsigned i = prevSize; i < newSize; i++) { + _array[i]=PoComp::INCOMPARABLE; + } + if (prevArray) { + memcpy(_array,prevArray,prevSize*sizeof(T)); + } + for (unsigned i = prevSize; i < newSize; i++) { + ASS(_array[i]==PoComp::INCOMPARABLE); + } + } + // remove previous array + if (prevSize) { + array_delete(prevArray, prevSize); + DEALLOC_KNOWN(prevArray, prevSize*sizeof(PoComp), "Kernel::PartialOrdering"); + } + } + // cout << "return " << *ptr << endl; + return *ptr; +} + +template +void PartialOrdering::set_idx_of(size_t idx_x, size_t idx_y, PoComp v) +{ + size_t idx = idx_y*(idx_y-1)/2 + idx_x; + ASS_L(idx,((_size - 1) * _size / 2)); + _array[idx] = v; +} + +template +void PartialOrdering::set_idx_of_safe(size_t idx_x, size_t idx_y, PoComp v) +{ + if (idx_x < idx_y) { + set_idx_of(idx_x,idx_y,v); + } else { + set_idx_of(idx_y,idx_x,Ordering::reverse(v)); + } +} + +template +PoComp PartialOrdering::idx_of(size_t idx_x, size_t idx_y) const +{ + size_t idx = idx_y*(idx_y-1)/2 + idx_x; + ASS_L(idx,((_size - 1) * _size / 2)); + return _array[idx]; +} + +template +void PartialOrdering::set_inferred_loop(size_t idx_x, size_t idx_y, PoComp gt, PoComp lt) +{ + ASS_NEQ(idx_x,idx_y); + + Stack above; + Stack below; + bool sort = idx_x < idx_y; + size_t idx_1 = sort ? idx_x : idx_y; + size_t idx_2 = sort ? idx_y : idx_x; + + // z +void PartialOrdering::set_inferred_loop_eq(size_t idx_x, size_t idx_y) +{ + ASS_NEQ(idx_x,idx_y); + + Stack> above; + Stack> below; + + bool sort = idx_x < idx_y; + size_t idx_1 = sort ? idx_x : idx_y; + size_t idx_2 = sort ? idx_y : idx_x; + + // z +void PartialOrdering::set_inferred(size_t idx_x, size_t idx_y, PoComp result) +{ + switch (result) { + /* x > y: then ∀z. y ≥ z, also x > z, + and ∀z. z ≥ x, also z > y */ + case PoComp::GREATER: + set_inferred_loop(idx_x, idx_y, PoComp::GREATER, PoComp::LESS); + break; + /* x < y: then ∀z. y ≤ z, also x < z, + and ∀z. z ≤ x, also z < y */ + case PoComp::LESS: + set_inferred_loop(idx_x, idx_y, PoComp::LESS, PoComp::GREATER); + break; + /* x = y: then ∀z. z = x, also z = y + and ∀z. z = y, also z = x + and ∀z. z > x, also z > y + and ∀z. z > y, also z > x + and ∀z. z < x, also z < y + and ∀z. z < y, also z < x */ + case PoComp::EQUAL: + set_inferred_loop_eq(idx_x, idx_y); + break; + /* if INC then nothing can be inferred */ + case PoComp::INCOMPARABLE: + break; + } +} + +template +string PartialOrdering::to_string() const +{ + if (_nodes.size()<2) { + return "{}"; + } + stringstream str; + typename DHMap::Iterator vit1(_nodes); + while (vit1.hasNext()) { + T t1; + size_t v1; + vit1.next(t1,v1); + typename DHMap::Iterator vit2(_nodes); + while (vit2.hasNext()) { + T t2; + size_t v2; + vit2.next(t2,v2); + if (v1 < v2) { + auto c = idx_of(v1,v2); + if (c == PoComp::INCOMPARABLE) { + continue; + } + str << t1 << " " << Ordering::resultToStringInfix(c) << " " << t2 << " "; + } + } + } + return str.str(); +} + +template +string PartialOrdering::to_string_raw() const +{ + stringstream str; + typename DHMap::Iterator vit(_nodes); + while (vit.hasNext()) { + T t; + size_t v; + vit.next(t,v); + str << t << " " << v << ", "; + } + str << "; "; + size_t arrSize = ((_size - 1) * _size / 2); + for (size_t i = 0; i < arrSize; i++) { + str << Ordering::resultToStringInfix(_array[i]) << " "; + } + return str.str(); +} + +template +VirtualIterator> PartialOrdering::iter_relations() const +{ + ASSERTION_VIOLATION; + // auto res = VirtualIterator>::getEmpty(); + // for (size_t idx_x = 0; idx_x < _size; idx_x++) { + // for (size_t idx_y = idx_x+1; idx_y < _size; idx_y++) { + // auto v = idx_of(idx_x,idx_y); + // if (v == PoComp::INCOMPARABLE) { + // continue; + // } + // res = pvi(getConcatenatedIterator(res,pvi(getSingletonIterator(make_tuple(_inverse.get(idx_x),_inverse.get(idx_y),v))))); + // } + // } + // return res; +} + +template +bool PartialOrdering::subseteq(const PartialOrdering& other) const +{ + for (size_t idx_x = 0; idx_x < _size; idx_x++) { + for (size_t idx_y = idx_x+1; idx_y < _size; idx_y++) { + auto v = idx_of(idx_x,idx_y); + if (v == PoComp::INCOMPARABLE) { + continue; + } + auto x = _inverse.get(idx_x); + auto y = _inverse.get(idx_y); + auto ptr_x = other._nodes.findPtr(x); + if (!ptr_x) { + return false; + } + auto ptr_y = other._nodes.findPtr(y); + if (!ptr_y) { + return false; + } + PoComp v_o; + if (*ptr_x < *ptr_y) { + v_o = other.idx_of(*ptr_x,*ptr_y); + } else { + v_o = Ordering::reverse(other.idx_of(*ptr_y,*ptr_x)); + } + if (v != v_o) { + return false; + } + } + } + return true; +} + +template class PartialOrdering; + +} \ No newline at end of file diff --git a/Kernel/PartialOrdering.hpp b/Kernel/PartialOrdering.hpp new file mode 100644 index 000000000..48a2b9103 --- /dev/null +++ b/Kernel/PartialOrdering.hpp @@ -0,0 +1,96 @@ +/* + * This file is part of the source code of the software program + * Vampire. It is protected by applicable + * copyright laws. + * + * This source code is distributed under the licence found here + * https://vprover.github.io/license.html + * and in the source directory + */ +/** + * @file PartialOrdering.hpp + * Defines class PartialOrdering. + */ + +#ifndef __PartialOrdering__ +#define __PartialOrdering__ + +#include "Forwards.hpp" + +#include "Lib/DHMap.hpp" +#include "Lib/VirtualIterator.hpp" + +#include "Ordering.hpp" + +namespace Kernel { + +using namespace Lib; + +using PoComp = Ordering::Result; + +// enum class PoComp { +// INC=0, +// EQ=1, +// GT=2, +// LT=3, +// }; + +// PoComp reverse(PoComp comp); +// std::string toString(PoComp comp); + +struct Edge { + unsigned x; + unsigned y; + PoComp c; + + std::tuple asTuple() const + { return std::make_tuple(x, y, c); } + + IMPL_COMPARISONS_FROM_TUPLE(Edge); + IMPL_HASH_FROM_TUPLE(Edge); +}; + +template +class PartialOrdering +{ +public: + PartialOrdering(); + PartialOrdering(const PartialOrdering& other); + ~PartialOrdering(); + + PartialOrdering& operator=(const PartialOrdering& other); + + bool is_total() const; + size_t size() const { return _size; } + const List* transitive_reduction() const { return _tr; } + PoComp get(const T& x, const T& y) const; + bool set(const T& x, const T& y, PoComp v); + const T& get_rep(const T& e) const; + + std::string to_string() const; + std::string to_string_raw() const; + + VirtualIterator> iter_relations() const; + bool subseteq(const PartialOrdering& other) const; + +private: + size_t idx_of_elem(const T& e) const; + size_t idx_of_elem_ext(const T& e); + PoComp idx_of(size_t idx_x, size_t idx_y) const; + void set_idx_of(size_t idx_x, size_t idx_y, PoComp v); + void set_idx_of_safe(size_t idx_x, size_t idx_y, PoComp v); + + void set_inferred(size_t idx_x, size_t idx_y, PoComp result); + void set_inferred_loop(size_t idx_x, size_t idx_y, PoComp gt, PoComp lt); + void set_inferred_loop_eq(size_t idx_x, size_t idx_y); + + DHMap _nodes; + DHMap _inverse; + size_t _size; + PoComp* _array; + List* _tr; // transitive reduction +}; + +}; + +#endif /* __PartialOrdering__ */ \ No newline at end of file diff --git a/Kernel/VarOrder.cpp b/Kernel/VarOrder.cpp new file mode 100644 index 000000000..61a38b464 --- /dev/null +++ b/Kernel/VarOrder.cpp @@ -0,0 +1,456 @@ +/* + * This file is part of the source code of the software program + * Vampire. It is protected by applicable + * copyright laws. + * + * This source code is distributed under the licence found here + * https://vprover.github.io/license.html + * and in the source directory + */ +/** + * @file VarOrder.cpp + */ + +#include "Forwards.hpp" +#include "Debug/TimeProfiling.hpp" +#include "Term.hpp" + +#include "VarOrder.hpp" + +namespace Kernel { + +using namespace std; + +bool VarOrder::add_gt(unsigned x, unsigned y) +{ + return _po.set(x, y, PoComp::GREATER); +} + +bool VarOrder::add_eq(unsigned x, unsigned y) +{ + return _po.set(x, y, PoComp::EQUAL); +} + +PoComp VarOrder::query(unsigned x, unsigned y) const +{ + return _po.get(x, y); +} + +bool VarOrder::is_total(size_t n) const +{ + return _po.size() == n && _po.is_total(); +} + +string VarOrder::to_string() const +{ + return _po.to_string(); +} + +const List* VarOrder::transitive_reduction() const +{ + return _po.transitive_reduction(); +} + +bool VarOrder::is_empty() const +{ + return _po.size() < 2; +} + +TermList VarOrder::EqApplicator::apply(unsigned v) +{ + return TermList(_vo._po.get_rep(v),false); +} + +VirtualIterator> VarOrder::iter_relations() const +{ + return _po.iter_relations(); +} + +size_t VarOrder::rel_size() const +{ + return _po.size(); +} + +bool VarOrder::subseteq(const VarOrder& other) const +{ + return _po.subseteq(other._po); +} + +bool VarOrder::tryExtendWith(const VarOrder& other) +{ + auto tr = other.transitive_reduction(); + while (List::isNonEmpty(tr)) { + auto e = tr->head(); + if (e.c == PoComp::EQUAL) { + if (!add_eq(e.x,e.y)) { + return false; + } + } else if (e.c == PoComp::GREATER) { + if (!add_gt(e.x,e.y)) { + return false; + } + } else if (e.c == PoComp::LESS) { + if (!add_gt(e.y,e.x)) { + return false; + } + } + tr = tr->tail(); + } + return true; +} + + +// void VarOrder::order_diff_helper(VarOrder& vo, const List* edges, Stack& res) +// { +// if (List::isEmpty(edges)) { +// return; +// } + +// auto e = edges->head(); + +// switch (e.c) { +// case PoComp::GT: +// if (vo.query(e.x,e.y) != PoComp::GT) { +// VarOrder eq = vo; +// VarOrder lt = vo; +// ALWAYS(eq.add_eq(e.x,e.y)); +// ALWAYS(lt.add_gt(e.y,e.x)); +// res.push(eq); +// res.push(lt); +// ALWAYS(vo.add_gt(e.x,e.y)); +// } +// break; +// case PoComp::EQ: +// if (vo.query(e.x,e.y) != PoComp::EQ) { +// VarOrder gt = vo; +// VarOrder lt = vo; +// ALWAYS(gt.add_gt(e.x,e.y)); +// ALWAYS(lt.add_gt(e.y,e.x)); +// res.push(gt); +// res.push(lt); +// ALWAYS(vo.add_eq(e.x,e.y)); +// } +// break; +// default: +// ASSERTION_VIOLATION; +// } + +// order_diff_helper(vo, edges->tail(), res); +// } + +Stack VarOrder::order_diff(const VarOrder* vo, const VarOrder* other) +{ + return order_diff_nonrecursive(vo,other); + // auto tr = other.transitive_reduction(); + + // Stack res; + // VarOrder temp = vo; + // order_diff_helper(temp, tr, res); + // return res; +} + +Stack VarOrder::order_diff_nonrecursive(const VarOrder* vo, const VarOrder* other) +{ + auto tr = other->transitive_reduction(); + + Stack res; + // VarOrder temp = vo; + + while (List::isNonEmpty(tr)) { + + auto e = tr->head(); + + switch (e.c) { + case PoComp::GREATER: + if (vo->query(e.x,e.y) != PoComp::GREATER) { + auto eq = VarOrder::add_eq(vo,e.x,e.y); + auto lt = VarOrder::add_gt(vo,e.y,e.x); + ASS(eq); + ASS(lt); + res.push(eq); + res.push(lt); + ALWAYS(vo = VarOrder::add_gt(vo,e.x,e.y)); + } + break; + case PoComp::EQUAL: + if (vo->query(e.x,e.y) != PoComp::EQUAL) { + auto gt = VarOrder::add_gt(vo,e.x,e.y); + auto lt = VarOrder::add_gt(vo,e.y,e.x); + ASS(gt); + ASS(lt); + res.push(gt); + res.push(lt); + ALWAYS(vo = VarOrder::add_eq(vo,e.x,e.y)); + } + break; + default: + ASSERTION_VIOLATION; + } + + tr = tr->tail(); + } + + return res; +} + +DHMap,const VarOrder*> VarOrder::_eqBank; +DHMap,const VarOrder*> VarOrder::_gtBank; + +const VarOrder* VarOrder::get_empty() +{ + static VarOrder empty; + return ∅ +} + +const VarOrder* VarOrder::add_gt(const VarOrder* vo, unsigned x, unsigned y) +{ + // cout << "querying " << vo->to_string() << " " << x << " > " << y << endl; + const VarOrder** ptr; + if (!_gtBank.getValuePtr(make_tuple(vo,x,y),ptr)) { + return *ptr; + } + if (vo->query(x,y)==PoComp::GREATER) { + *ptr = vo; + return vo; + } + auto res = new VarOrder(*vo); + if (!res->add_gt(x,y)) { + delete res; + *ptr = nullptr; + } else { + *ptr = res; + } + return *ptr; +} + +const VarOrder* VarOrder::add_eq(const VarOrder* vo, unsigned x, unsigned y) +{ + // cout << "querying " << vo->to_string() << " " << x << " = " << y << endl; + const VarOrder** ptr; + if (!_eqBank.getValuePtr(make_tuple(vo,x,y),ptr)) { + return *ptr; + } + if (vo->query(x,y)==PoComp::EQUAL) { + *ptr = vo; + return vo; + } + auto res = new VarOrder(*vo); + if (!res->add_eq(x,y)) { + delete res; + *ptr = nullptr; + } else { + *ptr = res; + } + return *ptr; +} + +const VarOrder* VarOrder::tryExtendWith(const VarOrder* vo, const VarOrder* other) +{ + static DHMap,const VarOrder*> cache; + const VarOrder** ptr; + if (!cache.getValuePtr(make_pair(vo,other),ptr,nullptr)) { + return *ptr; + } + // cout << cache.size() << endl; + + auto tr = other->transitive_reduction(); + while (List::isNonEmpty(tr)) { + auto e = tr->head(); + if (e.c == PoComp::EQUAL) { + vo = VarOrder::add_eq(vo,e.x,e.y); + if (!vo) { + break; + } + } else if (e.c == PoComp::GREATER) { + vo = VarOrder::add_gt(vo,e.x,e.y); + if (!vo) { + break; + } + } else if (e.c == PoComp::LESS) { + vo = VarOrder::add_gt(vo,e.y,e.x); + if (!vo) { + break; + } + } + tr = tr->tail(); + } + *ptr = vo; + return *ptr; + // return vo; +} + + +// bitvector operations + +// void setBit(unsigned x, unsigned y, PoComp c, VarOrderBV& bv) +// { +// if (x > 6 || y > 6) { +// return; +// } +// ASS(c!=PoComp::INC); +// if (x > y) { +// swap(x,y); +// c = reverse(c); +// } +// size_t idx = y*(y-1)/2 + x; +// size_t pos; +// switch (c) { +// case PoComp::GT: +// pos = 3*idx; +// break; +// case PoComp::EQ: +// pos = 3*idx+1; +// break; +// case PoComp::LT: +// pos = 3*idx+2; +// break; +// case PoComp::INC: +// return; +// } +// bv |= 1UL << pos; +// } + +// void unsetBit(unsigned x, unsigned y, PoComp c, VarOrderBV& bv) +// { +// if (x > 6 || y > 6) { +// return; +// } +// ASS(c!=PoComp::INC); +// if (x > y) { +// swap(x,y); +// c = reverse(c); +// } +// size_t idx = y*(y-1)/2 + x; +// size_t pos; +// switch (c) { +// case PoComp::GT: +// pos = 3*idx; +// break; +// case PoComp::EQ: +// pos = 3*idx+1; +// break; +// case PoComp::LT: +// pos = 3*idx+2; +// break; +// case PoComp::INC: +// return; +// } +// bv &= ~(1UL << pos); +// } + +// bool isBitSet(unsigned x, unsigned y, PoComp c, VarOrderBV bv) +// { +// if (x > 6 || y > 6) { +// return false; +// } +// ASS(c!=PoComp::INC); +// if (x > y) { +// swap(x,y); +// c = reverse(c); +// } +// size_t idx = y*(y-1)/2 + x; +// size_t pos; +// switch (c) { +// case PoComp::GT: +// pos = 3*idx; +// break; +// case PoComp::EQ: +// pos = 3*idx+1; +// break; +// case PoComp::LT: +// pos = 3*idx+2; +// break; +// case PoComp::INC: +// return false; +// } +// return (bv & (1UL << pos)); +// } + +// // ~000 & 111 -> 111 & 111 -> 1 +// // ~001 & 111 -> 110 & 111 -> 1 +// // ... +// // ~111 & 111 -> 000 & 111 -> 0 + +// bool isReducedUnderAny(VarOrderBV bv) +// { +// for (unsigned i = 0; i < 21; i++) { +// size_t pos = 3*i; +// if (!(~bv & (0b111UL << pos))) { +// return true; +// } +// } +// return false; +// } + +// VarOrderBV getRemaining(VarOrderBV bv) +// { +// return ~bv & ~(1UL << 63); +// } + +// PoComp oneRemains(VarOrderBV val, unsigned x, unsigned y) +// { +// ASS(x <= 6 && y <= 6); +// ASS(x < y); +// size_t idx = y*(y-1)/2 + x; +// bool gt = val & (1UL << (3*idx)); +// bool eq = val & (1UL << (3*idx+1)); +// bool lt = val & (1UL << (3*idx+2)); +// ASS(!gt || !eq || !lt); +// if (gt && eq) { +// return PoComp::LT; +// } +// if (gt && lt) { +// return PoComp::EQ; +// } +// if (eq && lt) { +// return PoComp::GT; +// } +// return PoComp::INC; +// } + +// bool addToVo(VarOrder& vo, unsigned x, unsigned y, PoComp c) +// { +// ASS(x <= 6 && y <= 6); +// switch (c) { +// case PoComp::GT: +// return vo.add_gt(x,y); +// case PoComp::EQ: +// return vo.add_eq(x,y); +// case PoComp::LT: +// return vo.add_gt(y,x); +// } +// return true; +// } + +// bool isRemainingUnsat(VarOrderBV val) +// { +// for (unsigned i = 0; i < 6; i++) { +// for (unsigned j = i+1; j < 6; j++) { +// auto c0 = oneRemains(val,i,j); +// if (c0 == PoComp::INC) { +// continue; +// } +// for (unsigned l = j+1; l < 6; l++) { +// auto c1 = oneRemains(val,i,l); +// auto c2 = oneRemains(val,j,l); +// if (c1 == PoComp::INC || c2 == PoComp::INC) { +// continue; +// } +// VarOrder vo; +// if (!addToVo(vo,i,j,c0)) { +// return true; +// } +// if (!addToVo(vo,i,l,c1)) { +// return true; +// } +// if (!addToVo(vo,j,l,c2)) { +// return true; +// } +// } +// } +// } +// return false; +// } + + +} \ No newline at end of file diff --git a/Kernel/VarOrder.hpp b/Kernel/VarOrder.hpp new file mode 100644 index 000000000..b50c4d310 --- /dev/null +++ b/Kernel/VarOrder.hpp @@ -0,0 +1,74 @@ +/* + * This file is part of the source code of the software program + * Vampire. It is protected by applicable + * copyright laws. + * + * This source code is distributed under the licence found here + * https://vprover.github.io/license.html + * and in the source directory + */ +/** + * @file VarOrder.hpp + */ + +#ifndef __VarOrder__ +#define __VarOrder__ + +#include "PartialOrdering.hpp" +#include + +namespace Kernel { + +class VarOrder { +public: + PoComp query(unsigned x, unsigned y) const; + bool is_total(size_t n) const; + std::string to_string() const; + const List* transitive_reduction() const; + bool is_empty() const; + size_t size() const { return _po.size(); } + VirtualIterator> iter_relations() const; + size_t rel_size() const; + bool subseteq(const VarOrder& other) const; + + static DHMap,const VarOrder*> _eqBank; + static DHMap,const VarOrder*> _gtBank; + static const VarOrder* get_empty(); + static const VarOrder* add_gt(const VarOrder* vo, unsigned x, unsigned y); + static const VarOrder* add_eq(const VarOrder* vo, unsigned x, unsigned y); + static const VarOrder* tryExtendWith(const VarOrder* vo, const VarOrder* other); + + class EqApplicator + { + public: + EqApplicator(const VarOrder& vo) : _vo(vo) {} + TermList apply(unsigned v); + + private: + const VarOrder& _vo; + }; + + // static void order_diff_helper(VarOrder& vo, const List* edges, Stack& res); + static Stack order_diff(const VarOrder* vo, const VarOrder* other); + static Stack order_diff_nonrecursive(const VarOrder* vo, const VarOrder* other); + +private: + bool add_gt(unsigned x, unsigned y); + bool add_eq(unsigned x, unsigned y); + bool tryExtendWith(const VarOrder& other); + + PartialOrdering _po; +}; + +// void setBit(unsigned x, unsigned y, PoComp c, VarOrderBV& val); +// void unsetBit(unsigned x, unsigned y, PoComp c, VarOrderBV& val); +// bool isBitSet(unsigned x, unsigned y, PoComp c, VarOrderBV val); +// bool isReducedUnderAny(VarOrderBV val); +// VarOrderBV getRemaining(VarOrderBV val); +// PoComp oneRemains(VarOrderBV val, unsigned x, unsigned y); +// bool addToVo(VarOrder& vo, unsigned x, unsigned y, PoComp c); +// bool isRemainingUnsat(VarOrderBV val); + +} + +#endif \ No newline at end of file diff --git a/Lib/DHMap.hpp b/Lib/DHMap.hpp index b47596105..70dcb2083 100644 --- a/Lib/DHMap.hpp +++ b/Lib/DHMap.hpp @@ -170,6 +170,15 @@ class DHMap return &e->_val; } + const Val* findPtr(Key key) const + { + const Entry* e=findEntry(key); + if(!e) { + return nullptr; + } + return &e->_val; + } + /** * Return value associated with given key. A pair with * this key has to be present. diff --git a/Saturation/SaturationAlgorithm.cpp b/Saturation/SaturationAlgorithm.cpp index 1053eb73c..53a95137a 100644 --- a/Saturation/SaturationAlgorithm.cpp +++ b/Saturation/SaturationAlgorithm.cpp @@ -1679,8 +1679,7 @@ SaturationAlgorithm *SaturationAlgorithm::createFromOptions(Problem& prb, const res->_symEl = new SymElOutput(); } - res->_conditionalRedundancyHandler.reset(ConditionalRedundancyHandler::create(opt, &ordering, res->_splitter, - static_cast(res->_imgr->request(DEMODULATION_LHS_CODE_TREE)))); + res->_conditionalRedundancyHandler.reset(ConditionalRedundancyHandler::create(opt, &ordering, res->_splitter)); res->_answerLiteralManager = AnswerLiteralManager::getInstance(); // selects the right one, according to options! ASS(!res->_answerLiteralManager||opt.questionAnswering()!=Options::QuestionAnsweringMode::OFF); From b860664475186b0df794b6a408581fb847a4a3af Mon Sep 17 00:00:00 2001 From: Marton Hajdu Date: Mon, 9 Sep 2024 16:54:00 +0200 Subject: [PATCH 14/19] Add some functionality to variable orderings --- Kernel/ConfluenceTree.hpp | 124 +++++++++++++++++++++++++------------ Kernel/KBOComparator.cpp | 40 ++++++++++-- Kernel/KBOComparator.hpp | 2 + Kernel/PartialOrdering.cpp | 23 ++++--- Kernel/VarOrder.cpp | 59 +++++++++++++----- Kernel/VarOrder.hpp | 5 +- 6 files changed, 176 insertions(+), 77 deletions(-) diff --git a/Kernel/ConfluenceTree.hpp b/Kernel/ConfluenceTree.hpp index d877bb280..684d04444 100644 --- a/Kernel/ConfluenceTree.hpp +++ b/Kernel/ConfluenceTree.hpp @@ -30,52 +30,94 @@ class ConfluenceTree deleteNode(root); } - void add(const VarOrder& vo) { - auto tr = vo.transitive_reduction(); + void add(const VarOrder* vo) { // the location where we should add new nodes - Node** prevPtr = &root; - DHSet done; - auto curr = root; - while (curr) { - if (curr->success) { - // entirely covered, we can return - return; - } - auto c = vo.query(curr->x, curr->y); - auto i = Node::branchIndex(c); - if (c != PoComp::INCOMPARABLE) { - Edge e; - e.c = c; - e.x = curr->x; - e.y = curr->y; - done.insert(e); - - e.c = Ordering::reverse(c); - e.x = curr->y; - e.y = curr->x; - done.insert(e); + struct State { + const VarOrder* toAdd; + const VarOrder* prefix; + Node* node; + Node* prev; + unsigned prevIndex; + }; + + Stack todo; + todo.push({ vo, VarOrder::get_empty(), root, nullptr, 0 }); + + while (todo.isNonEmpty()) { + auto st = todo.pop(); + + if (!st.node) { + // insert here + DHSet done; + auto prevTr = st.prefix->transitive_reduction(); + while (prevTr) { + done.insert(prevTr->head()); + prevTr = prevTr->tail(); + } + auto tr = st.toAdd->transitive_reduction(); + while (tr) { + auto edge = tr->head(); + if (done.contains(edge)) { + tr = tr->tail(); + continue; + } + auto curr = new Node(); + curr->x = edge.x; + curr->y = edge.y; + st.prefix = VarOrder::add_edge(st.prefix,edge); + + if (st.prev) { + st.prev->branches[st.prevIndex] = curr; + } else { + root = curr; + } + st.prev = curr; + st.prevIndex = Node::branchIndex(edge.c); + tr = tr->tail(); + } + auto successNode = new Node(); + successNode->success = true; + st.prev->branches[st.prevIndex] = successNode; + continue; } - prevPtr = &curr->branches[i]; - curr = curr->branches[i]; - } - while (tr) { - auto edge = tr->head(); - if (done.contains(edge)) { - tr = tr->tail(); + if (st.node->success) { + // this branch is covered, done continue; - } - auto curr = new Node(); - curr->x = edge.x; - curr->y = edge.y; - - *prevPtr = curr; - prevPtr = &curr->branches[Node::branchIndex(edge.c)]; - tr = tr->tail(); + } + auto c = st.toAdd->query(st.node->x, st.node->y); + // check if we intersect with current node + if (c != PoComp::INCOMPARABLE) { + auto i = Node::branchIndex(c); + auto prefix = VarOrder::add_edge(st.prefix,Edge{st.node->x,st.node->y,c}); + todo.push({ st.toAdd, prefix, st.node->branches[i], st.node, i }); + } else { + { // GREATER + auto ext = VarOrder::add_gt(st.toAdd, st.node->x, st.node->y); + auto prefix = VarOrder::add_gt(st.prefix, st.node->x, st.node->y); + if (ext) { + todo.push({ ext, prefix, st.node->branches[0], st.node, 0 }); + } + } + { // LESS + auto ext = VarOrder::add_gt(st.toAdd, st.node->y, st.node->x); + auto prefix = VarOrder::add_gt(st.prefix, st.node->y, st.node->x); + if (ext) { + todo.push({ ext, prefix, st.node->branches[1], st.node, 1 }); + } + } + { // EQUAL + auto ext = VarOrder::add_eq(st.toAdd, st.node->x, st.node->y); + auto prefix = VarOrder::add_eq(st.prefix, st.node->x, st.node->y); + if (ext) { + todo.push({ ext, prefix, st.node->branches[2], st.node, 2 }); + } + } + { // INCOMPARABLE + todo.push({ st.toAdd, st.prefix, st.node->branches[3], st.node, 3 }); + } + } } - auto successNode = new Node(); - successNode->success = true; - *prevPtr = successNode; } bool evaluate(const Ordering* ord, const SubstApplicator* applicator) const diff --git a/Kernel/KBOComparator.cpp b/Kernel/KBOComparator.cpp index 212e045de..ddf03b88f 100644 --- a/Kernel/KBOComparator.cpp +++ b/Kernel/KBOComparator.cpp @@ -249,9 +249,12 @@ std::string KBOComparator::toString() const unsigned cnt = 1; for (unsigned i = 0; i < _instructions.size();) { + if (cnt>1) { + str << ","; + } switch (static_cast(_instructions[i]._tag())) { case InstructionTag::SUCCESS: { - str << Int::toString(cnt++) << " success" << endl; + str << Int::toString(cnt++) << " success"; i += 1; break; } @@ -267,14 +270,13 @@ std::string KBOComparator::toString() const str << " w(X" << Int::toString(var) << ")*" << Int::toString(coeff); } - str << endl; i += 1+arity; break; } case InstructionTag::COMPARE_VV: { auto v1 = _instructions[i]._firstUint(); auto v2 = _instructions[i]._secondUint(); - str << Int::toString(cnt++) << " compare X" << Int::toString(v1) << " X" << Int::toString(v2) << endl; + str << Int::toString(cnt++) << " compare X" << Int::toString(v1) << " X" << Int::toString(v2); i++; break; } @@ -282,7 +284,7 @@ std::string KBOComparator::toString() const ASS(_instructions[i+1]._tag()==InstructionTag::DATA); auto v1 = _instructions[i]._firstUint(); auto t2 = _instructions[i+1]._term(); - str << Int::toString(cnt++) << " compare X" << Int::toString(v1) << " " << *t2 << endl; + str << Int::toString(cnt++) << " compare X" << Int::toString(v1) << " " << *t2; i += 2; break; } @@ -290,7 +292,7 @@ std::string KBOComparator::toString() const ASS(_instructions[i+1]._tag()==InstructionTag::DATA); auto t1 = _instructions[i+1]._term(); auto v2 = _instructions[i]._firstUint(); - str << Int::toString(cnt++) << " compare " << *t1 << " X" << Int::toString(v2) << endl; + str << Int::toString(cnt++) << " compare " << *t1 << " X" << Int::toString(v2); i += 2; break; } @@ -298,9 +300,35 @@ std::string KBOComparator::toString() const ASSERTION_VIOLATION; } } - str << endl; return str.str(); } +bool KBOComparator::extractVarOrders(const VarOrder* base, Stack& vos) const +{ + for (unsigned i = 0; i < _instructions.size();) { + switch (static_cast(_instructions[i]._tag())) { + case InstructionTag::COMPARE_VV: { + auto gt = VarOrder::add_gt(base,_instructions[i]._firstUint(),_instructions[i]._secondUint()); + if (gt) { + vos.push(gt); + } + base = VarOrder::add_eq(base,_instructions[i]._firstUint(),_instructions[i]._secondUint()); + if (base) { + i++; + break; + } + return false; + } + case InstructionTag::SUCCESS: { + vos.push(base); + return true; + } + default: { + return false; + } + } + } + return true; +} } diff --git a/Kernel/KBOComparator.hpp b/Kernel/KBOComparator.hpp index fc796435a..52094e765 100644 --- a/Kernel/KBOComparator.hpp +++ b/Kernel/KBOComparator.hpp @@ -18,6 +18,7 @@ #include "Forwards.hpp" #include "Lib/Stack.hpp" +#include "Kernel/VarOrder.hpp" #include "KBO.hpp" @@ -39,6 +40,7 @@ class KBOComparator /** Executes the runtime specialized instructions with concrete substitution. */ bool check(const SubstApplicator* applicator) const; std::string toString() const override; + bool extractVarOrders(const VarOrder* base, Stack& vos) const; private: enum InstructionTag { diff --git a/Kernel/PartialOrdering.cpp b/Kernel/PartialOrdering.cpp index 1d3f01414..90790a32e 100644 --- a/Kernel/PartialOrdering.cpp +++ b/Kernel/PartialOrdering.cpp @@ -536,18 +536,17 @@ string PartialOrdering::to_string_raw() const template VirtualIterator> PartialOrdering::iter_relations() const { - ASSERTION_VIOLATION; - // auto res = VirtualIterator>::getEmpty(); - // for (size_t idx_x = 0; idx_x < _size; idx_x++) { - // for (size_t idx_y = idx_x+1; idx_y < _size; idx_y++) { - // auto v = idx_of(idx_x,idx_y); - // if (v == PoComp::INCOMPARABLE) { - // continue; - // } - // res = pvi(getConcatenatedIterator(res,pvi(getSingletonIterator(make_tuple(_inverse.get(idx_x),_inverse.get(idx_y),v))))); - // } - // } - // return res; + auto res = VirtualIterator>::getEmpty(); + for (size_t idx_x = 0; idx_x < _size; idx_x++) { + for (size_t idx_y = idx_x+1; idx_y < _size; idx_y++) { + auto v = idx_of(idx_x,idx_y); + if (v == PoComp::INCOMPARABLE) { + continue; + } + res = pvi(concatIters(res,pvi(getSingletonIterator(make_tuple(_inverse.get(idx_x),_inverse.get(idx_y),v))))); + } + } + return res; } template diff --git a/Kernel/VarOrder.cpp b/Kernel/VarOrder.cpp index 61a38b464..3e8e84410 100644 --- a/Kernel/VarOrder.cpp +++ b/Kernel/VarOrder.cpp @@ -31,6 +31,24 @@ bool VarOrder::add_eq(unsigned x, unsigned y) return _po.set(x, y, PoComp::EQUAL); } +bool VarOrder::add_edge(Edge e) +{ + if (e.c == PoComp::EQUAL) { + if (!add_eq(e.x,e.y)) { + return false; + } + } else if (e.c == PoComp::GREATER) { + if (!add_gt(e.x,e.y)) { + return false; + } + } else if (e.c == PoComp::LESS) { + if (!add_gt(e.y,e.x)) { + return false; + } + } + return true; +} + PoComp VarOrder::query(unsigned x, unsigned y) const { return _po.get(x, y); @@ -81,18 +99,8 @@ bool VarOrder::tryExtendWith(const VarOrder& other) auto tr = other.transitive_reduction(); while (List::isNonEmpty(tr)) { auto e = tr->head(); - if (e.c == PoComp::EQUAL) { - if (!add_eq(e.x,e.y)) { - return false; - } - } else if (e.c == PoComp::GREATER) { - if (!add_gt(e.x,e.y)) { - return false; - } - } else if (e.c == PoComp::LESS) { - if (!add_gt(e.y,e.x)) { - return false; - } + if (!add_edge(e)) { + return false; } tr = tr->tail(); } @@ -193,8 +201,7 @@ Stack VarOrder::order_diff_nonrecursive(const VarOrder* vo, con return res; } -DHMap,const VarOrder*> VarOrder::_eqBank; -DHMap,const VarOrder*> VarOrder::_gtBank; +DHMap,const VarOrder*> VarOrder::_bank; const VarOrder* VarOrder::get_empty() { @@ -206,7 +213,7 @@ const VarOrder* VarOrder::add_gt(const VarOrder* vo, unsigned x, unsigned y) { // cout << "querying " << vo->to_string() << " " << x << " > " << y << endl; const VarOrder** ptr; - if (!_gtBank.getValuePtr(make_tuple(vo,x,y),ptr)) { + if (!_bank.getValuePtr(make_pair(vo,Edge{x,y,PoComp::GREATER}),ptr)) { return *ptr; } if (vo->query(x,y)==PoComp::GREATER) { @@ -227,7 +234,7 @@ const VarOrder* VarOrder::add_eq(const VarOrder* vo, unsigned x, unsigned y) { // cout << "querying " << vo->to_string() << " " << x << " = " << y << endl; const VarOrder** ptr; - if (!_eqBank.getValuePtr(make_tuple(vo,x,y),ptr)) { + if (!_bank.getValuePtr(make_pair(vo,Edge{x,y,PoComp::EQUAL}),ptr)) { return *ptr; } if (vo->query(x,y)==PoComp::EQUAL) { @@ -244,6 +251,26 @@ const VarOrder* VarOrder::add_eq(const VarOrder* vo, unsigned x, unsigned y) return *ptr; } +const VarOrder* VarOrder::add_edge(const VarOrder* vo, Edge e) +{ + const VarOrder** ptr; + if (!_bank.getValuePtr(make_pair(vo,e),ptr)) { + return *ptr; + } + if (vo->query(e.x,e.y)==e.c) { + *ptr = vo; + return vo; + } + auto res = new VarOrder(*vo); + if (!res->add_edge(e)) { + delete res; + *ptr = nullptr; + } else { + *ptr = res; + } + return *ptr; +} + const VarOrder* VarOrder::tryExtendWith(const VarOrder* vo, const VarOrder* other) { static DHMap,const VarOrder*> cache; diff --git a/Kernel/VarOrder.hpp b/Kernel/VarOrder.hpp index b50c4d310..0ccb2c651 100644 --- a/Kernel/VarOrder.hpp +++ b/Kernel/VarOrder.hpp @@ -31,11 +31,11 @@ class VarOrder { size_t rel_size() const; bool subseteq(const VarOrder& other) const; - static DHMap,const VarOrder*> _eqBank; - static DHMap,const VarOrder*> _gtBank; + static DHMap,const VarOrder*> _bank; static const VarOrder* get_empty(); static const VarOrder* add_gt(const VarOrder* vo, unsigned x, unsigned y); static const VarOrder* add_eq(const VarOrder* vo, unsigned x, unsigned y); + static const VarOrder* add_edge(const VarOrder* vo, Edge e); static const VarOrder* tryExtendWith(const VarOrder* vo, const VarOrder* other); class EqApplicator @@ -55,6 +55,7 @@ class VarOrder { private: bool add_gt(unsigned x, unsigned y); bool add_eq(unsigned x, unsigned y); + bool add_edge(Edge e); bool tryExtendWith(const VarOrder& other); PartialOrdering _po; From d9ea2b4883a2297ae1459eb09d5bb9ac162987a7 Mon Sep 17 00:00:00 2001 From: Marton Hajdu Date: Sat, 1 Feb 2025 16:01:22 +0100 Subject: [PATCH 15/19] Remove unused stuff --- CMakeLists.txt | 3 - Inferences/BinaryResolution.cpp | 2 - Inferences/EqualityFactoring.cpp | 1 - Kernel/ConfluenceTree.hpp | 198 ------------------------- Kernel/Ordering.cpp | 16 -- Kernel/Ordering.hpp | 1 - Lib/DHMap.hpp | 9 -- Saturation/SaturationAlgorithm.cpp | 2 +- Saturation/Splitter.cpp | 33 ++--- Saturation/Splitter.hpp | 10 +- Shell/ConditionalRedundancyHandler.cpp | 44 +++--- Shell/ConditionalRedundancyHandler.hpp | 18 +-- 12 files changed, 44 insertions(+), 293 deletions(-) delete mode 100644 Kernel/ConfluenceTree.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 2ec8b53e7..bc4af6b75 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -249,7 +249,6 @@ set(VAMPIRE_KERNEL_SOURCES Kernel/Clause.hpp Kernel/ClauseQueue.hpp Kernel/ColorHelper.hpp - Kernel/ConfluenceTree.hpp Kernel/Connective.hpp Kernel/ELiteralSelector.hpp Kernel/EqHelper.hpp @@ -308,8 +307,6 @@ set(VAMPIRE_KERNEL_SOURCES Kernel/ApplicativeHelper.cpp Kernel/SKIKBO.hpp Kernel/SKIKBO.cpp - Kernel/PartialOrdering.cpp - Kernel/PartialOrdering.hpp Inferences/CNFOnTheFly.cpp Inferences/CNFOnTheFly.hpp Inferences/CombinatorDemodISE.cpp diff --git a/Inferences/BinaryResolution.cpp b/Inferences/BinaryResolution.cpp index 0f138988f..ab49cde2c 100644 --- a/Inferences/BinaryResolution.cpp +++ b/Inferences/BinaryResolution.cpp @@ -21,7 +21,6 @@ #include "Lib/Metaiterators.hpp" #include "Lib/PairUtils.hpp" #include "Lib/VirtualIterator.hpp" -#include "Lib/SharedSet.hpp" #include "Kernel/Clause.hpp" #include "Kernel/ColorHelper.hpp" @@ -38,7 +37,6 @@ #include "Indexing/SubstitutionTree.hpp" #include "Saturation/SaturationAlgorithm.hpp" -#include "Saturation/Splitter.hpp" #include "Shell/AnswerLiteralManager.hpp" #include "Shell/ConditionalRedundancyHandler.hpp" diff --git a/Inferences/EqualityFactoring.cpp b/Inferences/EqualityFactoring.cpp index 190037f5b..00342beb4 100644 --- a/Inferences/EqualityFactoring.cpp +++ b/Inferences/EqualityFactoring.cpp @@ -30,7 +30,6 @@ #include "Kernel/ApplicativeHelper.hpp" #include "Saturation/SaturationAlgorithm.hpp" -#include "Saturation/Splitter.hpp" #include "Shell/ConditionalRedundancyHandler.hpp" #include "Shell/Statistics.hpp" diff --git a/Kernel/ConfluenceTree.hpp b/Kernel/ConfluenceTree.hpp deleted file mode 100644 index 684d04444..000000000 --- a/Kernel/ConfluenceTree.hpp +++ /dev/null @@ -1,198 +0,0 @@ -/* - * This file is part of the source code of the software program - * Vampire. It is protected by applicable - * copyright laws. - * - * This source code is distributed under the licence found here - * https://vprover.github.io/license.html - * and in the source directory - */ -/** - * @file ConfluenceTree.hpp - */ - -#ifndef __ConfluenceTree__ -#define __ConfluenceTree__ - -#include "Forwards.hpp" - -#include "VarOrder.hpp" - -namespace Kernel { - -using namespace Lib; - -class ConfluenceTree -{ -public: - ~ConfluenceTree() - { - deleteNode(root); - } - - void add(const VarOrder* vo) { - // the location where we should add new nodes - struct State { - const VarOrder* toAdd; - const VarOrder* prefix; - Node* node; - Node* prev; - unsigned prevIndex; - }; - - Stack todo; - todo.push({ vo, VarOrder::get_empty(), root, nullptr, 0 }); - - while (todo.isNonEmpty()) { - auto st = todo.pop(); - - if (!st.node) { - // insert here - DHSet done; - auto prevTr = st.prefix->transitive_reduction(); - while (prevTr) { - done.insert(prevTr->head()); - prevTr = prevTr->tail(); - } - auto tr = st.toAdd->transitive_reduction(); - while (tr) { - auto edge = tr->head(); - if (done.contains(edge)) { - tr = tr->tail(); - continue; - } - auto curr = new Node(); - curr->x = edge.x; - curr->y = edge.y; - st.prefix = VarOrder::add_edge(st.prefix,edge); - - if (st.prev) { - st.prev->branches[st.prevIndex] = curr; - } else { - root = curr; - } - st.prev = curr; - st.prevIndex = Node::branchIndex(edge.c); - tr = tr->tail(); - } - auto successNode = new Node(); - successNode->success = true; - st.prev->branches[st.prevIndex] = successNode; - continue; - } - - if (st.node->success) { - // this branch is covered, done - continue; - } - auto c = st.toAdd->query(st.node->x, st.node->y); - // check if we intersect with current node - if (c != PoComp::INCOMPARABLE) { - auto i = Node::branchIndex(c); - auto prefix = VarOrder::add_edge(st.prefix,Edge{st.node->x,st.node->y,c}); - todo.push({ st.toAdd, prefix, st.node->branches[i], st.node, i }); - } else { - { // GREATER - auto ext = VarOrder::add_gt(st.toAdd, st.node->x, st.node->y); - auto prefix = VarOrder::add_gt(st.prefix, st.node->x, st.node->y); - if (ext) { - todo.push({ ext, prefix, st.node->branches[0], st.node, 0 }); - } - } - { // LESS - auto ext = VarOrder::add_gt(st.toAdd, st.node->y, st.node->x); - auto prefix = VarOrder::add_gt(st.prefix, st.node->y, st.node->x); - if (ext) { - todo.push({ ext, prefix, st.node->branches[1], st.node, 1 }); - } - } - { // EQUAL - auto ext = VarOrder::add_eq(st.toAdd, st.node->x, st.node->y); - auto prefix = VarOrder::add_eq(st.prefix, st.node->x, st.node->y); - if (ext) { - todo.push({ ext, prefix, st.node->branches[2], st.node, 2 }); - } - } - { // INCOMPARABLE - todo.push({ st.toAdd, st.prefix, st.node->branches[3], st.node, 3 }); - } - } - } - } - - bool evaluate(const Ordering* ord, const SubstApplicator* applicator) const - { - auto curr = root; - while (curr) { - if (curr->success) { - return true; - } - auto comp = ord->compare(AppliedTerm(TermList::var(curr->x), applicator, true), AppliedTerm(TermList::var(curr->y), applicator, true)); - curr = curr->branches[Node::branchIndex(comp)]; - } - return false; - } - - std::string toString() const - { - std::string res; - Stack> todo; - todo.push(std::make_tuple(root,PoComp::INCOMPARABLE,0)); - - while (todo.isNonEmpty()) { - auto [curr,branch,depth] = todo.pop(); - std::stringstream str; - for (unsigned i = 0; i < depth; i++) { - str << " "; - } - str << Ordering::resultToStringInfix(branch) << " "; - if (!curr) { - str << "fail"; - } else if (curr->success) { - str << "success"; - } else { - str << "compare " << curr->x << " " << curr->y; - todo.push(std::make_tuple(curr->branches[3],PoComp::INCOMPARABLE,depth+1)); - todo.push(std::make_tuple(curr->branches[2],PoComp::EQUAL,depth+1)); - todo.push(std::make_tuple(curr->branches[1],PoComp::LESS,depth+1)); - todo.push(std::make_tuple(curr->branches[0],PoComp::GREATER,depth+1)); - } - str << std::endl; - res += str.str(); - } - return res; - } - -private: - struct Node { - bool success = false; - unsigned x; - unsigned y; - Node* branches[4]; - - static unsigned branchIndex(PoComp c) { - return static_cast(c)-1; - } - }; - - static void deleteNode(Node* n) { - Stack todo; - todo.push(n); - while (todo.isNonEmpty()) { - auto curr = todo.pop(); - if (!curr) { - continue; - } - todo.push(curr->branches[0]); - todo.push(curr->branches[1]); - todo.push(curr->branches[2]); - todo.push(curr->branches[3]); - delete curr; - } - } - - Node* root = nullptr; -}; - -} -#endif diff --git a/Kernel/Ordering.cpp b/Kernel/Ordering.cpp index ecd1e5866..4debf1a24 100644 --- a/Kernel/Ordering.cpp +++ b/Kernel/Ordering.cpp @@ -169,22 +169,6 @@ const char* Ordering::resultToString(Result r) } } -const char* Ordering::resultToStringInfix(Result r) -{ - switch(r) { - case GREATER: - return ">"; - case LESS: - return "<"; - case EQUAL: - return "="; - case INCOMPARABLE: - return "?"; - default: - ASSERTION_VIOLATION; - return 0; - } -} /** * Remove non-maximal literals from the list @b lits. The order * of remaining literals stays unchanged. diff --git a/Kernel/Ordering.hpp b/Kernel/Ordering.hpp index 846db812d..87e9d4e1a 100644 --- a/Kernel/Ordering.hpp +++ b/Kernel/Ordering.hpp @@ -130,7 +130,6 @@ class Ordering } } static const char* resultToString(Result r); - static const char* resultToStringInfix(Result r); static Ordering* create(Problem& prb, const Options& opt); diff --git a/Lib/DHMap.hpp b/Lib/DHMap.hpp index 70dcb2083..b47596105 100644 --- a/Lib/DHMap.hpp +++ b/Lib/DHMap.hpp @@ -170,15 +170,6 @@ class DHMap return &e->_val; } - const Val* findPtr(Key key) const - { - const Entry* e=findEntry(key); - if(!e) { - return nullptr; - } - return &e->_val; - } - /** * Return value associated with given key. A pair with * this key has to be present. diff --git a/Saturation/SaturationAlgorithm.cpp b/Saturation/SaturationAlgorithm.cpp index 591f1dcb0..8a8648873 100644 --- a/Saturation/SaturationAlgorithm.cpp +++ b/Saturation/SaturationAlgorithm.cpp @@ -1642,7 +1642,7 @@ SaturationAlgorithm *SaturationAlgorithm::createFromOptions(Problem& prb, const res->_symEl = new SymElOutput(); } - res->_conditionalRedundancyHandler.reset(ConditionalRedundancyHandler::create(opt, &ordering)); + res->_conditionalRedundancyHandler.reset(ConditionalRedundancyHandler::create(opt, &ordering, res->_splitter)); res->_answerLiteralManager = AnswerLiteralManager::getInstance(); // selects the right one, according to options! ASS(!res->_answerLiteralManager||opt.questionAnswering()!=Options::QuestionAnsweringMode::OFF); diff --git a/Saturation/Splitter.cpp b/Saturation/Splitter.cpp index 0705efa5c..69dc14ee4 100644 --- a/Saturation/Splitter.cpp +++ b/Saturation/Splitter.cpp @@ -619,7 +619,7 @@ std::string Splitter::splPrefix = ""; Splitter::Splitter() : _deleteDeactivated(Options::SplittingDeleteDeactivated::ON), _branchSelector(*this), - _clausesAdded(false), _haveBranchRefutation(false), _activationTimestamp(0) + _clausesAdded(false), _haveBranchRefutation(false) { if(env.options->proof()==Options::Proof::TPTP){ unsigned spl = env.signature->addFreshFunction(0,"spl"); @@ -803,7 +803,6 @@ void Splitter::onAllProcessed() toRemove.reset(); _branchSelector.recomputeModel(toAdd, toRemove, flushing); - _activationTimestamp++; if (_showSplitting) { // TODO: this is just one of many ways Splitter could report about changes std::cout << "[AVATAR] recomputeModel: + "; @@ -1497,6 +1496,16 @@ void Splitter::onClauseReduction(Clause* cl, ClauseIterator premises, Clause* re } } +void Splitter::addConditionalRedundancyEntry(SplitSet* splits, ConditionalRedundancyEntry* e) +{ + auto sit = splits->iter(); + while (sit.hasNext()) { + SplitLevel slev=sit.next(); + e->obtain(); + _db[slev]->conditionalRedundancyEntries.push(e); + } +} + bool Splitter::allSplitLevelsActive(SplitSet* s) { auto sit = s->iter(); @@ -1511,15 +1520,6 @@ bool Splitter::allSplitLevelsActive(SplitSet* s) return true; } -bool Splitter::allSplitLevelsActivatedBefore(SplitSet* splits, unsigned timestamp) const -{ - return splits->iter().all([this,timestamp](SplitLevel lev) { - ASS_REP(lev<_db.size(), lev); - ASS_REP(_db[lev]!=0, lev); - return _db[lev]->active && _db[lev]->active_ts <= timestamp; - }); -} - void Splitter::onNewClause(Clause* cl) { // when using AVATAR, we could have performed @@ -1669,7 +1669,6 @@ void Splitter::addComponents(const SplitLevelStack& toAdd) ASS(sr); ASS(!sr->active); sr->active = true; - sr->active_ts = _activationTimestamp; if (_deleteDeactivated == Options::SplittingDeleteDeactivated::ON) { ASS(sr->children.isEmpty()); @@ -1774,16 +1773,6 @@ void Splitter::removeComponents(const SplitLevelStack& toRemove) ASS(sr->active); sr->active = false; - - // note: this has to be done after the above deactivation - while (sr->redInfs.isNonEmpty()) { - // TODO make sure each function is called only once - auto fn = sr->redInfs.pop(); - auto cl = fn(); - if (cl) { - _sa->addNewClause(cl); - } - } } } diff --git a/Saturation/Splitter.hpp b/Saturation/Splitter.hpp index 139f424c7..309bc98c0 100644 --- a/Saturation/Splitter.hpp +++ b/Saturation/Splitter.hpp @@ -163,17 +163,12 @@ class Splitter { ~SplitRecord(); void addReduced(Clause* cl); - void addRedundantInference(std::function fn) { - redInfs.push(fn); - } Clause* component; RCClauseStack children; Stack reduced; - Stack> redInfs; Stack conditionalRedundancyEntries; bool active; - unsigned active_ts; USE_ALLOCATOR(SplitRecord); }; @@ -190,6 +185,7 @@ class Splitter { bool doSplitting(Clause* cl); void onClauseReduction(Clause* cl, ClauseIterator premises, Clause* replacement); + void addConditionalRedundancyEntry(SplitSet* splits, ConditionalRedundancyEntry* e); void onNewClause(Clause* cl); void onAllProcessed(); bool handleEmptyClause(Clause* cl); @@ -319,8 +315,6 @@ class Splitter { // not just optimisation: also prevents the SAT solver oscillating between two models in some cases Set> _already_added; - unsigned _activationTimestamp; - public: static std::string splPrefix; @@ -330,8 +324,6 @@ class Splitter { ASS_REP(lev<_db.size(), lev); return (_db[lev]!=0 && _db[lev]->active); } - unsigned getTimestamp() const { return _activationTimestamp; } - bool allSplitLevelsActivatedBefore(SplitSet* splits, unsigned timestamp) const; }; } diff --git a/Shell/ConditionalRedundancyHandler.cpp b/Shell/ConditionalRedundancyHandler.cpp index 7cca3f695..c571ba7a9 100644 --- a/Shell/ConditionalRedundancyHandler.cpp +++ b/Shell/ConditionalRedundancyHandler.cpp @@ -74,14 +74,14 @@ class ConditionalRedundancyHandler::ConstraintIndex return !check(ts, ord, lits, splits); } - void insert(ResultSubstitution* subst, bool result, + void insert(ResultSubstitution* subst, bool result, Splitter* splitter, OrderingConstraints&& ordCons, const LiteralSet* lits, SplitSet* splits) { auto ts = getInstances([subst,result](unsigned v) { return subst->applyTo(TermList::var(v),result); }); - insert(ts, createEntry(ts, std::move(ordCons), lits, splits)); + insert(ts, createEntry(ts, splitter, std::move(ordCons), lits, splits)); } - bool checkAndInsert(const Ordering* ord, ResultSubstitution* subst, bool result, bool doInsert, + bool checkAndInsert(const Ordering* ord, ResultSubstitution* subst, bool result, bool doInsert, Splitter* splitter, OrderingConstraints&& ordCons, const LiteralSet* lits, const SplitSet* splits) { ASS(lits); @@ -94,7 +94,7 @@ class ConditionalRedundancyHandler::ConstraintIndex return false; } if (doInsert) { - insert(ts, createEntry(ts, std::move(ordCons), lits, splits)); + insert(ts, createEntry(ts, splitter, std::move(ordCons), lits, splits)); } return true; } @@ -200,7 +200,7 @@ class ConditionalRedundancyHandler::ConstraintIndex DHMap _varSorts; - ConditionalRedundancyEntry* createEntry(const TermStack& ts, OrderingConstraints&& ordCons, const LiteralSet* lits, SplitSet* splits) const + ConditionalRedundancyEntry* createEntry(const TermStack& ts, Splitter* splitter, OrderingConstraints&& ordCons, const LiteralSet* lits, SplitSet* splits) const { auto e = new ConditionalRedundancyEntry(); Renaming r; @@ -235,6 +235,10 @@ class ConditionalRedundancyHandler::ConstraintIndex ASS(splits); e->splits = splits; + if (!splits->isEmpty()) { + splitter->addConditionalRedundancyEntry(splits, e); + } + return e; } @@ -282,10 +286,10 @@ class ConditionalRedundancyHandler::ConstraintIndex // ConditionalRedundancyHandler -ConditionalRedundancyHandler* ConditionalRedundancyHandler::create(const Options& opts, const Ordering* ord) +ConditionalRedundancyHandler* ConditionalRedundancyHandler::create(const Options& opts, const Ordering* ord, Splitter* splitter) { if (!opts.conditionalRedundancyCheck()) { - return new ConditionalRedundancyHandlerImpl(opts,ord); + return new ConditionalRedundancyHandlerImpl(opts,ord,splitter); } auto ordC = opts.conditionalRedundancyOrderingConstraints(); // check for av=on here as otherwise we would have to null-check splits inside the handler @@ -294,25 +298,25 @@ ConditionalRedundancyHandler* ConditionalRedundancyHandler::create(const Options if (ordC) { if (avatarC) { if (litC) { - return new ConditionalRedundancyHandlerImpl(opts,ord); + return new ConditionalRedundancyHandlerImpl(opts,ord,splitter); } - return new ConditionalRedundancyHandlerImpl(opts,ord); + return new ConditionalRedundancyHandlerImpl(opts,ord,splitter); } if (litC) { - return new ConditionalRedundancyHandlerImpl(opts,ord); + return new ConditionalRedundancyHandlerImpl(opts,ord,splitter); } - return new ConditionalRedundancyHandlerImpl(opts,ord); + return new ConditionalRedundancyHandlerImpl(opts,ord,splitter); } if (avatarC) { if (litC) { - return new ConditionalRedundancyHandlerImpl(opts,ord); + return new ConditionalRedundancyHandlerImpl(opts,ord,splitter); } - return new ConditionalRedundancyHandlerImpl(opts,ord); + return new ConditionalRedundancyHandlerImpl(opts,ord,splitter); } if (litC) { - return new ConditionalRedundancyHandlerImpl(opts,ord); + return new ConditionalRedundancyHandlerImpl(opts,ord,splitter); } - return new ConditionalRedundancyHandlerImpl(opts,ord); + return new ConditionalRedundancyHandlerImpl(opts,ord,splitter); } void ConditionalRedundancyHandler::destroyClauseData(Clause* cl) @@ -336,7 +340,7 @@ void ConditionalRedundancyHandler::checkEquations(Clause* cl) const } auto clDataPtr = getDataPtr(cl, /*doAllocate=*/true); auto rsubs = ResultSubstitution::fromSubstitution(&subs, 0, 0); - (*clDataPtr)->insert(rsubs.ptr(), /*result*/false, OrderingConstraints(), LiteralSet::getEmpty(), SplitSet::getEmpty()); + (*clDataPtr)->insert(rsubs.ptr(), /*result*/false, /*splitter*/nullptr, OrderingConstraints(), LiteralSet::getEmpty(), SplitSet::getEmpty()); }); } @@ -486,7 +490,7 @@ void ConditionalRedundancyHandlerImpl::insertSuper } auto rwClDataPtr = getDataPtr(rwClause, /*doAllocate=*/true); - (*rwClDataPtr)->insert(subs, !eqIsResult, std::move(ordCons), lits, splits); + (*rwClDataPtr)->insert(subs, !eqIsResult, _splitter, std::move(ordCons), lits, splits); } template @@ -530,7 +534,7 @@ bool ConditionalRedundancyHandlerImpl::handleResol auto dataPtr = getDataPtr(queryCl, /*doAllocate=*/doInsert); if (dataPtr && !(*dataPtr)->checkAndInsert( - _ord, subs, /*result*/false, doInsert, OrderingConstraints(), lits, splits)) + _ord, subs, /*result*/false, doInsert, _splitter, OrderingConstraints(), lits, splits)) { env.statistics->skippedResolution++; return false; @@ -568,7 +572,7 @@ bool ConditionalRedundancyHandlerImpl::handleResol auto dataPtr = getDataPtr(resultCl, /*doAllocate=*/doInsert); if (dataPtr && !(*dataPtr)->checkAndInsert( - _ord, subs, /*result*/true, doInsert, OrderingConstraints(), lits, splits)) + _ord, subs, /*result*/true, doInsert, _splitter, OrderingConstraints(), lits, splits)) { env.statistics->skippedResolution++; return false; @@ -589,7 +593,7 @@ bool ConditionalRedundancyHandlerImpl::handleReduc auto lits = LiteralSet::getEmpty(); auto splits = SplitSet::getEmpty(); if (!(*dataPtr)->checkAndInsert( - _ord, subst.ptr(), /*result*/false, /*doInsert=*/true, OrderingConstraints(), lits, splits)) + _ord, subst.ptr(), /*result*/false, /*doInsert=*/true, _splitter, OrderingConstraints(), lits, splits)) { return false; } diff --git a/Shell/ConditionalRedundancyHandler.hpp b/Shell/ConditionalRedundancyHandler.hpp index 6fc2d3ef2..3e9b06a4a 100644 --- a/Shell/ConditionalRedundancyHandler.hpp +++ b/Shell/ConditionalRedundancyHandler.hpp @@ -95,22 +95,20 @@ struct ConditionalRedundancyEntry { class ConditionalRedundancyHandler { public: - static ConditionalRedundancyHandler* create(const Options& opts, const Ordering* ord); + static ConditionalRedundancyHandler* create(const Options& opts, const Ordering* ord, Splitter* splitter); static void destroyClauseData(Clause* cl); virtual ~ConditionalRedundancyHandler() = default; virtual bool checkSuperposition( - Clause* eqClause, Literal* eqLit, Clause* rwClause, Literal* rwLit, - bool eqIsResult, ResultSubstitution* subs) const = 0; + Clause* eqClause, Literal* eqLit, Clause* rwClause, Literal* rwLit, bool eqIsResult, ResultSubstitution* subs) const = 0; virtual void insertSuperposition( Clause* eqClause, Clause* rwClause, TermList rwTermS, TermList tgtTermS, TermList eqLHS, Literal* rwLitS, Literal* eqLit, Ordering::Result eqComp, bool eqIsResult, ResultSubstitution* subs) const = 0; virtual bool handleResolution( - Clause* queryCl, Literal* queryLit, Clause* resultCl, Literal* resultLit, - ResultSubstitution* subs) const = 0; + Clause* queryCl, Literal* queryLit, Clause* resultCl, Literal* resultLit, ResultSubstitution* subs) const = 0; virtual bool handleReductiveUnaryInference(Clause* premise, RobSubstitution* subs) const = 0; @@ -130,15 +128,14 @@ class ConditionalRedundancyHandlerImpl : public ConditionalRedundancyHandler { public: - ConditionalRedundancyHandlerImpl(const Options& opts, const Ordering* ord) + ConditionalRedundancyHandlerImpl(const Options& opts, const Ordering* ord, Splitter* splitter) : _redundancyCheck(opts.demodulationRedundancyCheck() != Options::DemodulationRedundancyCheck::OFF), _encompassing(opts.demodulationRedundancyCheck() == Options::DemodulationRedundancyCheck::ENCOMPASS), - _ord(ord) {} + _ord(ord), _splitter(splitter) {} /** Returns false if superposition should be skipped. */ bool checkSuperposition( - Clause* eqClause, Literal* eqLit, Clause* rwClause, Literal* rwLit, - bool eqIsResult, ResultSubstitution* subs) const override; + Clause* eqClause, Literal* eqLit, Clause* rwClause, Literal* rwLit, bool eqIsResult, ResultSubstitution* subs) const override; void insertSuperposition( Clause* eqClause, Clause* rwClause, TermList rwTermS, TermList tgtTermS, TermList eqLHS, @@ -146,8 +143,7 @@ class ConditionalRedundancyHandlerImpl /** Returns false if resolution should be skipped. */ bool handleResolution( - Clause* queryCl, Literal* queryLit, Clause* resultCl, Literal* resultLit, - ResultSubstitution* subs) const override; + Clause* queryCl, Literal* queryLit, Clause* resultCl, Literal* resultLit, ResultSubstitution* subs) const override; /** Returns false if inference should be skipped. */ bool handleReductiveUnaryInference(Clause* premise, RobSubstitution* subs) const override; From f704aa34a0d7cb8b16f5dd4baaf84bfb8e9ea054 Mon Sep 17 00:00:00 2001 From: Marton Hajdu Date: Thu, 20 Mar 2025 15:26:35 +0100 Subject: [PATCH 16/19] Remove unnecessary changes --- Indexing/CodeTree.cpp | 14 +--- Indexing/CodeTree.hpp | 156 -------------------------------------- Indexing/TermCodeTree.cpp | 5 -- 3 files changed, 2 insertions(+), 173 deletions(-) diff --git a/Indexing/CodeTree.cpp b/Indexing/CodeTree.cpp index e8327aa51..3e1de6543 100644 --- a/Indexing/CodeTree.cpp +++ b/Indexing/CodeTree.cpp @@ -801,9 +801,6 @@ template struct CodeTree::Matcher; CodeTree::CodeTree() : _onCodeOpDestroying(0), _curTimeStamp(0), _maxVarCnt(1), _entryPoint(0) -#if LOG_LEAVES - , _printLeaf(0) -#endif { } @@ -904,18 +901,11 @@ void CodeTree::visitAllOps(Visitor visitor) const std::ostream& operator<<(std::ostream& out, const CodeTree& ct) { - ct.visitAllOps([&out,&ct](const CodeTree::CodeOp* op, unsigned depth) { + ct.visitAllOps([&out](const CodeTree::CodeOp* op, unsigned depth) { for (unsigned i = 0; i < depth; i++) { out << " "; } - out << *op; -#if LOG_LEAVES - if (op->isSuccess() && ct._printLeaf) { - out << " "; - ct._printLeaf(out, op); - } -#endif - out << std::endl; + out << *op << std::endl; }); return out; } diff --git a/Indexing/CodeTree.hpp b/Indexing/CodeTree.hpp index 07bf4f9b6..c08aed8a1 100644 --- a/Indexing/CodeTree.hpp +++ b/Indexing/CodeTree.hpp @@ -36,8 +36,6 @@ //#define LOG_OP(x) std::cout< - static CodeBlock* buildBlock(CodeStack& code, size_t cnt, Data&& data); - template - void incorporate(CodeStack& code, Data&& data); - template void compressCheckOps(CodeOp* chainStart); @@ -513,152 +503,6 @@ class CodeTree CodeBlock* _entryPoint; }; -/** - * Build CodeBlock object from the last @b cnt instructions on the - * @b code stack. - * - * In this function is also set the value for the @b ILStruct::previous - * members. - */ -template -CodeTree::CodeBlock* CodeTree::buildBlock(CodeStack& code, size_t cnt, Data&& data) -{ - size_t clen=code.length(); - ASS_LE(cnt,clen); - - CodeBlock* res=CodeBlock::allocate(cnt+1); // one more for success - size_t sOfs=clen-cnt; - for(size_t i=0;iadd(std::move(data)); - (*res)[cnt] = CodeOp::getSuccess(ctr); - return res; -} - -/** - * Incorporate the code in @b code CodeStack into the tree, empty the - * stack, and make sure all no longer necessary structures are freed. - */ -template -void CodeTree::incorporate(CodeStack& code, Data&& data) -{ - ASS(!code.top().isSuccess()); - - if(isEmpty()) { - _entryPoint=buildBlock(code, code.length(), data); - code.reset(); - return; - } - - static const unsigned checkFunOpThreshold=5; //must be greater than 1 or it would cause loops - static const unsigned checkGroundTermOpThreshold=3; //must be greater than 1 or it would cause loops - - size_t clen=code.length(); - CodeOp** tailTarget; - size_t matchedCnt; - - { - CodeOp* treeOp = getEntryPoint(); - - for (size_t i = 0; i < clen; i++) { - ASS_NEQ(code[i]._instruction(),SUCCESS_OR_FAIL); - ASS_NEQ(code[i]._instruction(),LIT_END); - - CodeOp* chainStart = treeOp; - size_t checkFunOps = 0; - size_t checkGroundTermOps = 0; - for (;;) { - ASS_NEQ(treeOp->_instruction(),SUCCESS_OR_FAIL); - ASS_NEQ(treeOp->_instruction(),LIT_END); - - if (treeOp->isSearchStruct()) { - //handle the SEARCH_STRUCT - SearchStruct* ss = treeOp->getSearchStruct(); - CodeOp** toPtr; - if (ss->getTargetOpPtr(code[i], toPtr)) { - if (!*toPtr) { - tailTarget = toPtr; - matchedCnt = i; - goto matching_done; - } - treeOp = *toPtr; - continue; - } - } else if (code[i].equalsForOpMatching(*treeOp)) { - //matched, go to the next compiled instruction - break; - } - - if (treeOp->alternative()) { - //try alternative if there is some - treeOp = treeOp->alternative(); - } else { - //matching failed, we'll add the new branch here - tailTarget = &treeOp->alternative(); - matchedCnt = i; - goto matching_done; - } - - if (treeOp->isCheckFun()) { - checkFunOps++; - //if there were too many CHECK_FUN alternative operations, put them - //into a SEARCH_STRUCT - if (checkFunOps > checkFunOpThreshold) { - //we put CHECK_FUN ops into the SEARCH_STRUCT op, and - //restart with the chain - compressCheckOps(chainStart); - treeOp = chainStart; - checkFunOps = 0; - checkGroundTermOps = 0; - continue; - } - } - - if (treeOp->isCheckGroundTerm()) { - checkGroundTermOps++; - //if there were too many CHECK_GROUND_TERM alternative operations, put them - //into a SEARCH_STRUCT - if (checkGroundTermOps > checkGroundTermOpThreshold) { - //we put CHECK_GROUND_TERM ops into the SEARCH_STRUCT op, and - //restart with the chain - compressCheckOps(chainStart); - treeOp = chainStart; - checkFunOps = 0; - checkGroundTermOps = 0; - continue; - } - } - } // for(;;) - - //the SEARCH_STRUCT operation does not occur in a CodeBlock - ASS(!treeOp->isSearchStruct()); - //we can safely do increase because as long as we match and something - //remains in the @b code stack, we aren't at the end of the CodeBlock - //either (as each code block contains at least one FAIL or SUCCESS - //operation, and CodeStack contains at most one SUCCESS as the last - //operation) - treeOp++; - } - //We matched the whole CodeStack. If we are here, we are inserting an - //item multiple times. We will insert it anyway, because later we may - //be removing it multiple times as well. - matchedCnt = clen - 1; - ASS(treeOp->isSuccess()); - treeOp->getSuccessResult()->add(std::move(data)); - return; - } -matching_done: - ASS_L(matchedCnt,clen); - - CodeBlock* rem=buildBlock(code, clen-matchedCnt, data); - *tailTarget=&(*rem)[0]; - LOG_OP(rem->toString()<<" incorporated, mismatch caused by "<::TermCodeTree() { _clauseCodeTree=false; _onCodeOpDestroying = onCodeOpDestroying; -#if LOG_LEAVES - _printLeaf = [](std::ostream& str, const CodeOp* op) { - str << *op->getSuccessResult(); - }; -#endif } template From 281b740b6b09fe3ba57d52fc11b1d9780e6fdc02 Mon Sep 17 00:00:00 2001 From: Marton Hajdu Date: Tue, 8 Apr 2025 20:16:09 +0200 Subject: [PATCH 17/19] Remove todo --- Indexing/CodeTree.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/Indexing/CodeTree.cpp b/Indexing/CodeTree.cpp index 73e7acc82..01924f930 100644 --- a/Indexing/CodeTree.cpp +++ b/Indexing/CodeTree.cpp @@ -792,7 +792,6 @@ inline bool CodeTree::Matcher::doSearchStruct() return false; } op=target; - // TODO look at this if something crashes if constexpr (removing) { firstsInBlocks->push(op); } From a34988dab5269fc085c916e5265984351000a8d8 Mon Sep 17 00:00:00 2001 From: Marton Hajdu Date: Wed, 9 Apr 2025 12:17:11 +0200 Subject: [PATCH 18/19] Remove remaining diff from original classes --- Indexing/CodeTree.cpp | 23 +++++++++++------------ Indexing/CodeTree.hpp | 43 +++++++++++++++++++++++++++---------------- 2 files changed, 38 insertions(+), 28 deletions(-) diff --git a/Indexing/CodeTree.cpp b/Indexing/CodeTree.cpp index 01924f930..f9c284698 100644 --- a/Indexing/CodeTree.cpp +++ b/Indexing/CodeTree.cpp @@ -536,7 +536,7 @@ bool CodeTree::Matcher::execute() for(;;) { if(op->alternative()) { if constexpr (removing) { - btStack.push(BTPointRemoving(tp, op->alternative(), firstsInBlocks->size())); + btStack.push(BTPointRemoving(tp, op->alternative(), RemovingBase::firstsInBlocks->size())); } else { btStack.push(BTPoint(tp, op->alternative())); } @@ -548,7 +548,7 @@ bool CodeTree::Matcher::execute() break; } if constexpr (removing) { - if (matchingClauses) { + if (RemovingBase::matchingClauses) { //we can succeed only in certain depth and that will be handled separately shouldBacktrack=true; } @@ -568,7 +568,7 @@ bool CodeTree::Matcher::execute() } break; case LIT_END: - ASS(matchingClauses); + ASS(RemovingBase::matchingClauses); return true; case CHECK_GROUND_TERM: shouldBacktrack=!doCheckGroundTerm(); @@ -623,8 +623,9 @@ void CodeTree::Matcher::init(CodeTree* tree_, CodeOp* entr linfoCnt=linfoCnt_; if constexpr (removing) { - firstsInBlocks=firstsInBlocks_; - initFIBDepth=firstsInBlocks->size(); + RemovingBase::firstsInBlocks=firstsInBlocks_; + RemovingBase::initFIBDepth=RemovingBase::firstsInBlocks->size(); + RemovingBase::matchingClauses=tree->_clauseCodeTree; } fresh=true; @@ -633,8 +634,6 @@ void CodeTree::Matcher::init(CodeTree* tree_, CodeOp* entr bindings.ensure(tree->_maxVarCnt); btStack.reset(); - - matchingClauses=tree->_clauseCodeTree; } /** @@ -655,8 +654,8 @@ bool CodeTree::Matcher::backtrack() tp=bp.tp; op=bp.op; if constexpr (removing) { - firstsInBlocks->truncate(bp.fibDepth); - firstsInBlocks->push(op); + RemovingBase::firstsInBlocks->truncate(bp.fibDepth); + RemovingBase::firstsInBlocks->push(op); } return true; } @@ -665,7 +664,7 @@ template bool CodeTree::Matcher::prepareLiteral() { if constexpr (removing) { - firstsInBlocks->truncate(initFIBDepth); + RemovingBase::firstsInBlocks->truncate(RemovingBase::initFIBDepth); } if(curLInfo>=linfoCnt) { return false; @@ -685,7 +684,7 @@ inline bool CodeTree::Matcher::doAssignVar() const FlatTerm::Entry* fte=&(*ft)[tp]; if(fte->isVar()) { if constexpr (checkRange) { - if (!range.insert(fte->_number())) { + if (!RemovingBase::range.insert(fte->_number())) { return false; } } @@ -793,7 +792,7 @@ inline bool CodeTree::Matcher::doSearchStruct() } op=target; if constexpr (removing) { - firstsInBlocks->push(op); + RemovingBase::firstsInBlocks->push(op); } return true; } diff --git a/Indexing/CodeTree.hpp b/Indexing/CodeTree.hpp index cd7c0e74f..457968bcd 100644 --- a/Indexing/CodeTree.hpp +++ b/Indexing/CodeTree.hpp @@ -323,6 +323,16 @@ class CodeTree typedef Stack CodeStack; typedef DArray BindingArray; + // This holds the parts relevant only for Matcher + struct RemovingBase { + Stack* firstsInBlocks; + size_t initFIBDepth; + bool matchingClauses; + DHSet range; + }; + + struct NonRemovingBase {}; + /** * Context for finding matches of literals * @@ -336,6 +346,7 @@ class CodeTree */ template struct Matcher + : public std::conditional::type { // we only want to enable checkRange if // removing, which works on variables @@ -379,12 +390,16 @@ class CodeTree CodeOp* op; BindingArray bindings; - DHSet range; bool keepRecycled() const - { return bindings.keepRecycled() - || btStack.keepRecycled() - || (firstsInBlocks && firstsInBlocks->keepRecycled()); } + { + if constexpr (removing) { + return bindings.keepRecycled() || btStack.keepRecycled() + || (RemovingBase::firstsInBlocks && RemovingBase::firstsInBlocks->keepRecycled()); + } else { + return bindings.keepRecycled() || btStack.keepRecycled(); + } + } protected: void init(CodeTree* tree_, CodeOp* entry_, LitInfo* linfos_ = 0, @@ -417,14 +432,12 @@ class CodeTree bool fresh; bool _matched; + /** Stack containing backtracking points */ + Stack> btStack; + CodeOp* entry; CodeTree* tree; - /** - * Currently matched LitInfo object in case LitInfo objects - * are used (they are not in TermCodeTree::TermMatcher). - */ - size_t curLInfo; /** * Array of alternative LitInfo objects * @@ -438,13 +451,11 @@ class CodeTree */ size_t linfoCnt; - /** Stack containing backtracking points */ - Stack> btStack; - - Stack* firstsInBlocks; - size_t initFIBDepth; - - bool matchingClauses; + /** + * Currently matched LitInfo object in case LitInfo objects + * are used (they are not in TermCodeTree::TermMatcher). + */ + size_t curLInfo; }; //////// auxiliary methods ////////// From 884347e3d27f42a187e6652177da1f65b01c6529 Mon Sep 17 00:00:00 2001 From: Marton Hajdu Date: Wed, 9 Apr 2025 12:43:21 +0200 Subject: [PATCH 19/19] Hide assertion behind constexpr condition --- Indexing/CodeTree.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Indexing/CodeTree.cpp b/Indexing/CodeTree.cpp index f9c284698..637f7f15a 100644 --- a/Indexing/CodeTree.cpp +++ b/Indexing/CodeTree.cpp @@ -568,7 +568,9 @@ bool CodeTree::Matcher::execute() } break; case LIT_END: - ASS(RemovingBase::matchingClauses); + if constexpr (removing) { + ASS(RemovingBase::matchingClauses); + } return true; case CHECK_GROUND_TERM: shouldBacktrack=!doCheckGroundTerm();