#include "Demodulation.hpp"
#include "Kernel/EqHelper.hpp"
#include "Lib/StringUtils.hpp"
namespace Inferences {
namespace ALASCA {
Option<Clause*> Demodulation::apply(
AlascaState& shared,
Lhs lhs, Rhs rhs) {
TIME_TRACE("alasca demodulation")
auto nothing = [&]() { return Option<Clause*>(); };
{
TIME_TRACE("sort check")
RobSubstitution sortUnif;
if (!sortUnif.match(SortHelper::getEqualityArgumentSort(lhs.literal()), 0, rhs.sort(), 1))
return nothing();
}
ASS(lhs.clause()->size() == 1)
ASS(lhs.literal()->isEquality())
ASS(lhs.literal()->isPositive())
unsigned lBank = 0, rBank = 1;
RobSubstitution subs;
{
TIME_TRACE("extra unification that makes implementation much easier but maybe sacrifices some performance")
ALWAYS(subs.match(lhs.biggerSide(), lBank, rhs.term, rBank));
}
auto sigmaL = [&](auto t) { return subs.apply(t, lBank); };
auto sigmaR = [&](auto t) { return subs.apply(t, rBank); }; ASS_EQ(sigmaL(lhs.biggerSide()), sigmaR(rhs.term));
{
TIME_TRACE("checking C[sσ] ≻ (±ks + t ≈ 0)σ")
auto lhs_sigma = sigmaL(lhs.literal());
auto optimized_greater = rhs.ordOptimization;
auto greater = optimized_greater || iterTraits(rhs.clause->iterLits())
.any([&](auto lit)
{ return shared.greater(sigmaR(lit), lhs_sigma); });
if (!greater) {
return nothing();
}
}
auto replacement = sigmaL(lhs.smallerSide());
auto altered = false;
auto lits = iterTraits(rhs.clause->iterLits())
.map([&](auto lit) {
auto repl = EqHelper::replace(sigmaR(lit), sigmaR(rhs.term), replacement);
altered |= repl != lit;
return repl;
})
.template collect<Stack>();
ASS_REP(altered, outputToString("\n", lhs, "\n", rhs))
Inference inf(SimplifyingInference2(Kernel::InferenceRule::ALASCA_FWD_DEMODULATION, lhs.clause(), rhs.clause));
return Option<Clause*>(Clause::fromStack(lits, inf));
}
} }