package inference.axioms;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import exceptions.SubstituteFailedException;
import inference.InferenceRule;
import models.algebra.Variable;
import models.formulas.DependencyFormula;
import models.formulas.Formula;
import models.formulas.meta.MetaDependencyFormula;
import models.formulas.meta.MetaFormula;
import models.terms.meta.MatchConstraint;
import models.terms.meta.MetaDynamicDependency;
import models.terms.meta.MetaEvaluatableTermVariable;
import models.terms.meta.MetaRDLTerm;
import models.terms.meta.MetaRDLTermVariable;
import models.terms.meta.MetaTermGenerator;
public class RedundancyElimination extends InferenceRule {
public RedundancyElimination() {
super("Redundancy Elimination");
assumptions.add(
new MetaDependencyFormula(
new MetaDynamicDependency(
new MetaTermGenerator() {
@Override
public MetaRDLTerm generate(int curIndex, int curDepth, int maxIndex, int maxDepth, Map<String, Object> context) {
curIndex -= 1;
context.put("firstAssumptionIndex", curIndex + 1);
return new MetaEvaluatableTermVariable(new Variable("v" + curIndex));
}
},
new MetaEvaluatableTermVariable(new Variable("u"))
)
)
);
assumptions.add(
new MetaDependencyFormula(
new MetaDynamicDependency(
(ci, cd, mi, md, context) -> new MetaEvaluatableTermVariable(new Variable("v" + (ci - 2))),
new MetaRDLTermVariable(new Variable("s")),
new MetaEvaluatableTermVariable(new Variable("u"))
)
)
);
conclusion = new MetaDependencyFormula(
new MetaDynamicDependency(
new MetaTermGenerator() {
@Override
public MetaRDLTerm generate(int curIndex, int curDepth, int maxIndex, int maxDepth, Map<String, Object> context) {
curIndex -= 2;
int firstAssumptionIndex = (Integer) context.get("firstAssumptionIndex");
return new MetaEvaluatableTermVariable(new Variable("v" + (curIndex + firstAssumptionIndex)));
}},
new MetaRDLTermVariable(new Variable("s")),
new MetaEvaluatableTermVariable(new Variable("u"))
)
);
this.conclusionMaxIndexCalculator = (assumptions) -> ((DependencyFormula) assumptions.get(1)).getDependency().getMaxIndex() - ((DependencyFormula) assumptions.get(0)).getDependency().getMaxIndex() + 1;
}
protected Set<Formula> apply(List<Formula> assumptions, MatchConstraint constraint) {
Map<String, Object> context = new HashMap<>();
if (assumptions.size() < getAssumptionSize()) {
return new HashSet<>();
}
if (((DependencyFormula) assumptions.get(0)).getDependency().getMaxIndex() >= ((DependencyFormula) assumptions.get(1)).getDependency().getMaxIndex()) {
return new HashSet<>();
}
Set<MatchConstraint> result = new HashSet<>();
result.add(constraint);
for (int i = 0; i < getAssumptionSize(); i++) {
result = this.assumptions.get(i).isMatchedBy(assumptions.get(i), result, context);
if (result.isEmpty()) {
return new HashSet<>();
}
}
if (this.repetitionAssumptions.size() != 0 && (assumptions.size() - this.assumptions.size()) % this.repetitionAssumptions.size() != 0) {
return new HashSet<>();
}
if (this.repetitionAssumptions.size() != 0) {
for (int i = 0; i < (assumptions.size() - this.assumptions.size()) / this.repetitionAssumptions.size(); i++) {
List<MetaFormula> metaAssumptions = repetitionAssumptionGenerate(i);
for (int j = 0; j < this.repetitionAssumptions.size(); j++) {
Formula assumption = assumptions.get(this.assumptions.size() + i * this.repetitionAssumptions.size() + j);
MetaFormula metaAssumption = metaAssumptions.get(j);
result = metaAssumption.isMatchedBy(assumption, result, context);
if (result.isEmpty()) {
return new HashSet<>();
}
}
}
}
Set<Formula> subRes = new HashSet<>();
for (MatchConstraint con: result) {
try {
int maxIndex = conclusionMaxIndexCalculator != null ? conclusionMaxIndexCalculator.calculate(assumptions) : 0;
int maxDepth = conclusionMaxDepthCalculator != null ? conclusionMaxDepthCalculator.calculate(assumptions) : 1;
context.put("maxIndex", maxIndex);
context.put("maxDepth", maxDepth);
subRes.add(conclusion.substitution(con.getBinding(), context));
} catch (SubstituteFailedException e) {
continue;
}
}
return subRes;
}
}