#ifndef __SimpleCongruenceClosure__
#define __SimpleCongruenceClosure__
#include "Forwards.hpp"
#include "Lib/DArray.hpp"
#include "Lib/Deque.hpp"
#include "Lib/DHMap.hpp"
#include "Lib/Stack.hpp"
#include "Kernel/Term.hpp"
#include "Kernel/Ordering.hpp"
#include "DecisionProcedure.hpp"
namespace DP {
using namespace Lib;
using namespace Kernel;
class SimpleCongruenceClosure : public DecisionProcedure
{
public:
SimpleCongruenceClosure(Ordering* ord);
void addLiterals(LiteralIterator lits, bool onlyEqualites) override;
Status getStatus(bool retrieveMultipleCores) override;
unsigned getUnsatCoreCount() override { return _unsatEqs.size(); }
void getUnsatCore(LiteralStack& res, unsigned coreIndex) override;
void getModel(LiteralStack& model) override;
void reset() override;
void addLiteral(Literal* lit);
unsigned getClassID(TermList t) {
return deref(_termNames.get(t));
}
private:
Ordering* _ord;
typedef std::pair<unsigned,unsigned> CPair;
struct CEq
{
CEq() : c1(0), c2(0), foOrigin(false), foPremise(nullptr) {}
CEq(unsigned c1, unsigned c2, Literal* lit)
: c1(c1), c2(c2), foOrigin(true), foPremise(lit) {}
CEq(unsigned c1, unsigned c2)
: c1(c1), c2(c2), foOrigin(false), foPremise(nullptr) {}
bool isInvalid() const { ASS_EQ(c1==0, c2==0); return c1==0; }
std::string toString() const;
std::string toString(SimpleCongruenceClosure& parent) const;
unsigned c1;
unsigned c2;
bool foOrigin;
Literal* foPremise;
};
enum class SignatureKind {
PREDICATE,
FUNCTION,
TYPECON,
VARIABLE
};
unsigned getMaxConst() const { return _cInfos.size()-1; }
unsigned getFreshConst();
unsigned getSignatureConst(unsigned symbol, SignatureKind kind);
unsigned getPairName(CPair p);
struct FOConversionWorker;
static bool isDistinctPred(Literal* l);
CEq convertFOEquality(Literal* equality);
unsigned convertFONonEquality(Literal* lit);
unsigned convertFO(TermList trm);
void readDistinct(Literal* lit);
unsigned deref(unsigned c) const {
unsigned repr = _cInfos[c].reprConst;
unsigned res = (repr==0) ? c : repr;
ASS_REP2(_cInfos[res].reprConst==0, _cInfos[res].reprConst, c);
return res;
}
CPair deref(CPair p) const { return CPair(deref(p.first), deref(p.second)); }
CPair deref(CEq p) const { return CPair(deref(p.c1), deref(p.c2)); }
unsigned getClassSize(unsigned c) const {
return _cInfos[c].classList.size();
}
bool checkPositiveDistincts(bool retrieveMultipleCores);
Status checkNegativeDistincts(bool retrieveMultipleCores);
void addPendingEquality(CEq eq);
void makeProofRepresentant(unsigned c);
void propagate();
unsigned getProofDepth(unsigned c);
void collectUnifyingPath(unsigned c1, unsigned c2, Stack<unsigned>& path);
static const unsigned NO_SIG_SYMBOL;
struct ConstInfo
{
void init();
void resetEquivalences(SimpleCongruenceClosure& parent, unsigned selfIndex);
#if VDEBUG
void assertValid(SimpleCongruenceClosure& parent, unsigned selfIndex) const;
#endif
unsigned sigSymbol;
SignatureKind sigSymKind;
TermList term;
Literal* lit;
CPair namedPair;
unsigned reprConst;
unsigned proofPredecessor;
CEq predecessorPremise;
Stack<unsigned> classList;
Stack<unsigned> useList;
bool processed;
Stack<unsigned> upEdges;
bool half_normalized;
TermList normalForm;
};
struct ConstOrderingComparator;
typedef DHMap<unsigned,TermList> NFMap;
void computeConstsNormalForm(unsigned c, NFMap& normalForms);
#if VDEBUG
void assertModelInfoClean() const;
#endif
DArray<ConstInfo> _cInfos;
unsigned _posLitConst;
unsigned _negLitConst;
DHMap<std::pair<unsigned,SignatureKind>,unsigned> _sigConsts;
typedef DHMap<CPair,unsigned> PairMap;
PairMap _pairNames;
DHMap<TermList,unsigned> _termNames;
DHMap<Literal*,unsigned> _litNames;
Stack<CEq> _unsatEqs;
Deque<CEq> _pendingEqualities;
Stack<CEq> _negEqualities;
struct DistinctEntry
{
DistinctEntry(Literal* l) : _lit(l) {}
Literal* _lit;
Stack<unsigned> _consts;
};
typedef Stack<DistinctEntry> DistinctStack;
DistinctStack _distinctConstraints;
DistinctStack _negDistinctConstraints;
bool _hadPropagated;
};
}
#endif