#ifndef __KBO__
#define __KBO__
#include "Forwards.hpp"
#include "Lib/DArray.hpp"
#include "Ordering.hpp"
#include "Debug/Tracer.hpp"
#include <memory>
#define SPECIAL_WEIGHT_IDENT_VAR "$var"
#define SPECIAL_WEIGHT_IDENT_INTRODUCED "$introduced"
#define SPECIAL_WEIGHT_IDENT_DEFAULT_WEIGHT "$default"
#define SPECIAL_WEIGHT_IDENT_NUM_INT "$int"
#define SPECIAL_WEIGHT_IDENT_NUM_RAT "$rat"
#define SPECIAL_WEIGHT_IDENT_NUM_REAL "$real"
#define __KBO__CUSTOM_PREDICATE_WEIGHTS__ 0
namespace Kernel {
using namespace Lib;
#if __KBO__CUSTOM_PREDICATE_WEIGHTS__
struct PredSigTraits;
#endif
struct FuncSigTraits;
using KboWeight = unsigned;
template<class SigTraits>
struct KboSpecialWeights;
#if __KBO__CUSTOM_PREDICATE_WEIGHTS__
template<>
struct KboSpecialWeights<PredSigTraits>
{
inline bool tryAssign(const std::string& name, unsigned weight)
{ return false; }
inline static KboSpecialWeights dflt(bool qkbo)
{ return { }; }
bool tryGetWeight(unsigned functor, unsigned& weight) const;
};
#endif
template<>
struct KboSpecialWeights<FuncSigTraits>
{
KboWeight _variableWeight;
KboWeight _numInt;
KboWeight _numRat;
KboWeight _numReal;
bool _qkbo;
inline bool tryAssign(const std::string& name, unsigned weight)
{
if (name == SPECIAL_WEIGHT_IDENT_VAR ) { _variableWeight = weight; return true; }
if (name == SPECIAL_WEIGHT_IDENT_NUM_INT ) { if (_qkbo) { WARN("ignoring numeral weight in QKBO") } _numInt = weight; return true; }
if (name == SPECIAL_WEIGHT_IDENT_NUM_REAL) { if (_qkbo) { WARN("ignoring numeral weight in QKBO") } _numReal = weight; return true; }
if (name == SPECIAL_WEIGHT_IDENT_NUM_RAT ) { if (_qkbo) { WARN("ignoring numeral weight in QKBO") } _numRat = weight; return true; }
return false;
}
inline static KboSpecialWeights dflt(bool qkbo)
{
return {
._variableWeight = 1,
._numInt = 1,
._numRat = 1,
._numReal = 1,
._qkbo = qkbo,
};
}
bool tryGetWeight(unsigned functor, unsigned& weight) const;
};
template<class SigTraits>
struct KboWeightMap {
friend class KBO;
DArray<KboWeight> _weights;
KboWeight _introducedSymbolWeight;
KboSpecialWeights<SigTraits> _specialWeights;
KboWeight symbolWeight(const Term* t) const;
KboWeight symbolWeight(unsigned functor) const;
static KboWeightMap dflt(bool qkbo);
template<class Extractor, class Fml>
static KboWeightMap fromSomeUnsigned(Extractor ex, Fml fml, bool qkbo);
private:
static KboWeightMap randomized(bool qkbo);
template<class Random> static KboWeightMap randomized(unsigned maxWeight, Random random, bool qkbo);
};
class KBO
: public PrecedenceOrdering
{
public:
KBO(KBO&&) = default;
KBO& operator=(KBO&&) = default;
KBO(Problem& prb, const Options& opt, bool qkbo = false);
KBO(
KboWeightMap<FuncSigTraits> funcWeights,
#if __KBO__CUSTOM_PREDICATE_WEIGHTS__
KboWeightMap<PredSigTraits> predWeights,
#endif
DArray<int> funcPrec,
DArray<int> typeConPrec,
DArray<int> predPrec,
DArray<int> predLevels,
bool reverseLCM,
bool qkbo = false);
static KBO testKBO(bool rand = false, bool qkbo = false);
void showConcrete(std::ostream&) const override;
template<class HandleError>
void checkAdmissibility(HandleError handle) const;
void zeroWeightForMaximalFunc();
using PrecedenceOrdering::compare;
Result compare(TermList tl1, TermList tl2) const override;
Result compare(AppliedTerm t1, AppliedTerm t2) const override;
Result compareUnidirectional(AppliedTerm t1, AppliedTerm t2) const override;
TermOrderingDiagramUP createTermOrderingDiagram(bool ground = false) const override;
protected:
unsigned computeWeight(AppliedTerm tt) const;
Result comparePredicates(Literal* l1, Literal* l2) const override;
friend struct TermOrderingDiagram;
friend class TermOrderingDiagramKBO;
int symbolWeight(const Term* t) const;
private:
KboWeightMap<FuncSigTraits> _funcWeights;
#if __KBO__CUSTOM_PREDICATE_WEIGHTS__
KboWeightMap<PredSigTraits> _predWeights;
#endif
template<class SigTraits> const KboWeightMap<SigTraits>& getWeightMap() const;
template<class SigTraits> KboWeightMap<SigTraits> weightsFromOpts(const Options& opts, const DArray<int>& rawPrecedence) const;
template<class SigTraits> KboWeightMap<SigTraits> weightsFromFile(const Options& opts) const;
template<class SigTraits>
void showConcrete_(std::ostream&) const;
class State
{
int _weightDiff;
DHMap<unsigned, int, IdentityHash, DefaultHash> _varDiffs;
int _posNum;
int _negNum;
Result _lexResult;
public:
State() {}
void init()
{
_weightDiff=0;
_posNum=0;
_negNum=0;
_lexResult=EQUAL;
_varDiffs.reset();
}
Result traverseLexBidir(KBO const& kbo, AppliedTerm t1, AppliedTerm t2);
Result traverseLexUnidir(KBO const& kbo, AppliedTerm t1, AppliedTerm t2);
template<bool unidirectional>
Result traverseNonLex(KBO const& kbo, AppliedTerm t1, AppliedTerm t2);
template<int coef, bool varsOnly> void traverse(KBO const& kbo, AppliedTerm tt);
Result result(KBO const& kbo, AppliedTerm t1, AppliedTerm t2);
protected:
template<int coef> void recordVariable(unsigned var);
bool checkVars() const { return _negNum <= 0; }
Result innerResult(KBO const& kbo, TermList t1, TermList t2);
Result applyVariableCondition(Result res)
{
if(_posNum>0 && (res==LESS || res==EQUAL)) {
res=INCOMPARABLE;
} else if(_negNum>0 && (res==GREATER || res==EQUAL)) {
res=INCOMPARABLE;
}
return res;
}
friend class TermOrderingDiagramKBO;
};
mutable std::unique_ptr<State> _state;
};
} #endif