#ifndef __TermOrderingDiagram__
#define __TermOrderingDiagram__
#include "Forwards.hpp"
#include "TermPartialOrdering.hpp"
#include "Ordering.hpp"
namespace Inferences {
class ForwardGroundJoinability;
}
namespace Kernel {
struct POStruct {
POStruct() = default;
POStruct(const TermPartialOrdering* tpo)
: tpo(tpo), cons() {}
const TermPartialOrdering* tpo = nullptr;
Stack<TermOrderingConstraint> cons;
};
struct TermOrderingDiagram
{
public:
static TermOrderingDiagram* createForSingleComparison(const Ordering& ord, TermList lhs, TermList rhs);
static bool extendVarsGreater(TermOrderingDiagram* tod, const SubstApplicator* appl, POStruct& po_struct);
static void resetStaticCaches();
TermOrderingDiagram(const Ordering& ord, bool ground);
virtual ~TermOrderingDiagram();
void init(const SubstApplicator* appl);
void* next();
void insert(const Stack<TermOrderingConstraint>& cons, void* data);
friend std::ostream& operator<<(std::ostream& out, const TermOrderingDiagram& tod);
private:
void processCurrentNode();
void processVarNode();
void processPolyNode();
protected:
virtual void processTermNode();
using Trace = TermPartialOrdering;
const Trace* getCurrentTrace();
struct Node;
struct Polynomial;
struct Branch {
Branch() = default;
Branch(void* data, Branch alt);
Branch(TermList lhs, TermList rhs);
Branch(const Polynomial* p);
~Branch();
Branch(const Branch& other);
Branch(Branch&& other);
Branch& operator=(Branch other);
Node* node() const;
void setNode(Node* node);
private:
Node* _node = nullptr;
};
struct Node {
enum Tag {
T_DATA = 0u,
T_TERM = 1u,
T_POLY = 2u,
} tag;
explicit Node(void* data, Branch alternative);
explicit Node(TermList lhs, TermList rhs);
explicit Node(const Polynomial* p);
~Node();
Node(const Node&) = delete;
Node& operator=(const Node&) = delete;
void incRefCnt();
void decRefCnt();
Branch& getBranch(Ordering::Result r);
static_assert(sizeof(uint64_t) == sizeof(Branch));
static_assert(sizeof(uint64_t) == sizeof(TermList));
static_assert(sizeof(uint64_t) == sizeof(void*));
static_assert(sizeof(uint64_t) == sizeof(int64_t));
union {
void* data = nullptr;
TermList lhs;
const Polynomial* poly;
};
union {
Branch alternative;
TermList rhs;
};
Branch gtBranch;
Branch eqBranch;
Branch ngeBranch;
bool ready = false;
int refcnt = 0;
const Trace* trace = nullptr;
};
using VarCoeffPair = std::pair<unsigned,int>;
struct Polynomial {
static const Polynomial* get(int constant, const Stack<VarCoeffPair>& varCoeffPairs);
auto asTuple() const { return std::make_tuple(constant, varCoeffPairs); }
IMPL_HASH_FROM_TUPLE(Polynomial);
IMPL_COMPARISONS_FROM_TUPLE(Polynomial);
int constant;
Stack<VarCoeffPair> varCoeffPairs;
};
friend std::ostream& operator<<(std::ostream& out, const Node::Tag& t);
friend std::ostream& operator<<(std::ostream& out, const Node& node);
friend std::ostream& operator<<(std::ostream& out, const Polynomial& poly);
const Ordering& _ord;
Branch _source;
Branch _sink;
Branch* _curr;
Branch* _prev;
const SubstApplicator* _appl;
bool _ground;
friend class Inferences::ForwardGroundJoinability;
public:
template<class Iterator, typename ...Args>
struct Traversal {
Traversal(TermOrderingDiagram* tod, const SubstApplicator* appl, Args... initial);
bool next(Branch*& b, Args&... args);
bool handleBranch(Branch* b, Args... args);
private:
TermOrderingDiagram* _tod;
const SubstApplicator* _appl;
Recycled<Stack<std::pair<Branch*,Iterator>>> _path;
bool _rootIsSuccess;
};
struct DefaultIterator {
DefaultIterator(const Ordering&, const SubstApplicator*, Node*) {}
bool next(Result& res) {
if (curr == Result::INCOMPARABLE) {
return false;
}
res = curr;
switch (curr) {
case Result::GREATER:
curr = Result::EQUAL;
break;
case Result::EQUAL:
curr = Result::LESS;
break;
case Result::LESS:
curr = Result::INCOMPARABLE;
break;
case Result::INCOMPARABLE:
ASSERTION_VIOLATION;
}
return true;
}
Result curr = Result::GREATER;
};
struct NodeIterator {
NodeIterator(const Ordering&, const SubstApplicator*, Node* node, POStruct initial);
bool next(Result& res, POStruct& pos);
private:
bool tryExtend(POStruct& po_struct, const Stack<TermOrderingConstraint>& cons);
POStruct initial;
struct BranchingPoint {
Stack<TermOrderingConstraint> cons;
Result r;
};
Stack<BranchingPoint> bps;
};
struct AppliedNodeIterator {
AppliedNodeIterator(const Ordering& ord, const SubstApplicator* appl, Node* node, POStruct initial);
bool next(Result& res, POStruct& pos);
private:
bool termNode;
Traversal<NodeIterator,POStruct> traversal;
};
};
}
#endif