#ifndef __LFP_RULE_HPP__
#define __LFP_RULE_HPP__
#include "InferenceEngine.hpp"
namespace Inferences {
template<class Rule>
class LfpISE
: public ImmediateSimplificationEngine
{
Rule _inner;
public:
LfpISE(Rule rule) : _inner(std::move(rule)) {}
Clause* simplify(Clause* c) override {
auto c0 = c;
auto c1 = c;
do {
c0 = c1;
c1 = _inner.simplify(c0);
if (c1 == nullptr) {
return c1;
}
if (c0->splits())
c1->setSplits(c0->splits());
} while (c1 != c0);
return c1;
}
};
template<class Rule>
LfpISE<Rule> lfpISE(Rule rule) { return LfpISE<Rule>(std::move(rule)); }
template<class Rule>
class LfpRule
: public SimplifyingGeneratingInference1
{
Rule _inner;
public:
LfpRule(Rule rule);
LfpRule();
SimplifyingGeneratingInference1::Result simplify(Clause *cl, bool doCheckOrdering) override;
void attach(SaturationAlgorithm* alg) override { SimplifyingGeneratingInference1::attach(alg); _inner.attach(alg); }
void detach() override { SimplifyingGeneratingInference1::detach(); _inner.detach(); }
};
template<class Rule>
LfpRule<Rule>::LfpRule(Rule rule) : _inner(std::move(rule)) {}
template<class Rule>
LfpRule<Rule>::LfpRule() : _inner() {}
template<class Rule>
SimplifyingGeneratingInference1::Result LfpRule<Rule>::simplify(Clause *cl, bool doCheckOrdering)
{
auto splits = cl->splits();
auto c0 = cl; auto _c1 = _inner.simplify(c0, doCheckOrdering);
auto c1 = _c1.simplified; auto originalRedundant = _c1.premiseRedundant;
while (c0 != c1) {
auto c2 = _inner.simplify(c1, doCheckOrdering); if (c2.simplified != c1) {
if (splits) {
c1->setSplits(cl->splits());
}
originalRedundant = originalRedundant && c2.premiseRedundant;
}
c0 = c1;
c1 = c2.simplified;
}
return Result {
.simplified = c1,
.premiseRedundant = originalRedundant,
};
}
}
#endif