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.EquationAxiom;
import models.algebra.Expression;
import models.algebra.Variable;
import models.formulas.Formula;
import models.formulas.meta.MetaDependencyFormula;
import models.formulas.meta.MetaEquationFormula;
import models.terms.meta.MatchConstraint;
import models.terms.meta.MetaDependency;
import models.terms.meta.MetaDependencyTerm;
import models.terms.meta.MetaDynamicDependency;
import models.terms.meta.MetaDynamicDependencyTerm;
import models.terms.meta.MetaEvaluatableTermVariable;
import models.terms.meta.MetaRDLTerm;
import models.terms.meta.MetaTermGenerator;
import utils.ExpressionUtils;
public class RightNormalization extends EquationAxiom {
private final Expression n1 = ExpressionUtils.parse("n-1");
public RightNormalization() {
super("RIght Normalization");
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), n1);
}
},
new MetaDependency(
new MetaEvaluatableTermVariable(new Variable("s"), new Variable("n")),
new MetaEvaluatableTermVariable(new Variable("t"), new Variable("n"))
)
)
)
);
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("secondAssumptionIndex", curIndex + 1);
return new MetaEvaluatableTermVariable(new Variable("w" + curIndex), n1);
}
},
new MetaEvaluatableTermVariable(new Variable("u"), n1)
)
)
);
assumptions.add(
new MetaEquationFormula(
new MetaDependencyTerm(
new MetaEvaluatableTermVariable(new Variable("t"), new Variable("n")),
new MetaEvaluatableTermVariable(new Variable("xxx")),
new MetaEvaluatableTermVariable(new Variable("yyy"))
),
new MetaEvaluatableTermVariable(new Variable("u"), n1)
)
);
conclusion = new MetaEquationFormula(
new MetaDynamicDependencyTerm(
new MetaTermGenerator() {
@Override
public MetaRDLTerm generate(int curIndex, int curDepth, int maxIndex, int maxDepth, Map<String, Object> context) {
curIndex -= 1;
int firstAssumptionIndex = (Integer) context.get("firstAssumptionIndex");
int secondAssumptionIndex = (Integer) context.get("secondAssumptionIndex");
if (curIndex >= (firstAssumptionIndex + secondAssumptionIndex) * 2) {
return null;
}
if (curIndex < firstAssumptionIndex * 2) {
if (curIndex % 2 == 0) {
return new MetaEvaluatableTermVariable(new Variable("v" + curIndex / 2), n1);
}
return new MetaEvaluatableTermVariable(new Variable("x" + curIndex / 2));
}
curIndex -= firstAssumptionIndex * 2;
if (curIndex % 2 == 0) {
return new MetaEvaluatableTermVariable(new Variable("w" + curIndex / 2), n1);
}
return new MetaEvaluatableTermVariable(new Variable("y" + curIndex / 2));
}
},
new MetaDependencyTerm(
new MetaEvaluatableTermVariable(new Variable("s"), new Variable("n")),
new MetaEvaluatableTermVariable(new Variable("t"), new Variable("n")),
new MetaEvaluatableTermVariable(new Variable("u"), n1)
)
),
new MetaDynamicDependencyTerm(
new MetaTermGenerator() {
@Override
public MetaRDLTerm generate(int curIndex, int curDepth, int maxIndex, int maxDepth, Map<String, Object> context) {
curIndex -= 1;
int firstAssumptionIndex = (Integer) context.get("firstAssumptionIndex");
if (curIndex >= firstAssumptionIndex * 2) {
return null;
}
if (curIndex % 2 == 0) {
return new MetaEvaluatableTermVariable(new Variable("v" + curIndex / 2), n1);
}
return new MetaEvaluatableTermVariable(new Variable("x" + curIndex / 2));
}
},
new MetaDependencyTerm(
new MetaEvaluatableTermVariable(new Variable("s"), new Variable("n")),
new MetaEvaluatableTermVariable(new Variable("t"), new Variable("n")),
new MetaDynamicDependencyTerm(
new MetaTermGenerator() {
@Override
public MetaRDLTerm generate(int curIndex, int curDepth, int maxIndex, int maxDepth, Map<String, Object> context) {
curIndex -= 1;
int secondAssumptionIndex = (Integer) context.get("secondAssumptionIndex");
if (curIndex >= secondAssumptionIndex * 2) {
return null;
}
if (curIndex % 2 == 0) {
return new MetaEvaluatableTermVariable(new Variable("w" + curIndex / 2), n1);
}
return new MetaEvaluatableTermVariable(new Variable("y" + curIndex / 2));
}
},
new MetaEvaluatableTermVariable(new Variable("u"), n1)
)
)
)
);
}
@Override
protected Set<Formula> apply(List<Formula> assumptions, MatchConstraint constraint) {
if (assumptions.size() < 3) {
return new HashSet<>();
}
Set<MatchConstraint> result = new HashSet<>();
result.add(constraint);
Map<String, Object> context = new HashMap<>();
for (int i = 0; i < 3; i++) {
result = this.assumptions.get(i).isMatchedBy(assumptions.get(i), result);
if (result.isEmpty()) {
return new HashSet<>();
}
}
int firstAssumptionIndex = (Integer) context.get("firstAssumptionIndex");
int secondAssumptionIndex = (Integer) context.get("secondAssumptionIndex");
if (assumptions.size() < 3 + firstAssumptionIndex + secondAssumptionIndex) {
return new HashSet<>();
}
for (int i = 0; i < firstAssumptionIndex; i++) {
Formula assumption = assumptions.get(i + 3);
MetaEquationFormula mef = new MetaEquationFormula(
new MetaDependencyTerm(
new MetaEvaluatableTermVariable(new Variable("v" + i), n1),
new MetaEvaluatableTermVariable(new Variable("xxxx" + i)),
new MetaEvaluatableTermVariable(new Variable("yyyy" + i))
),
new MetaEvaluatableTermVariable(new Variable("x" + i))
);
result = mef.isMatchedBy(assumption, result);
if (result.isEmpty()) {
return new HashSet<>();
}
}
for(int i = 0; i < secondAssumptionIndex; i++) {
Formula assumption = assumptions.get(i + 3 + firstAssumptionIndex);
MetaEquationFormula mef = new MetaEquationFormula(
new MetaDependencyTerm(
new MetaEvaluatableTermVariable(new Variable("w" + i), n1),
new MetaEvaluatableTermVariable(new Variable("xxyy" + i)),
new MetaEvaluatableTermVariable(new Variable("yyxx" + i))
),
new MetaEvaluatableTermVariable(new Variable("y" + i))
);
result = mef.isMatchedBy(assumption, result);
if (result.isEmpty()) {
return new HashSet<>();
}
}
Set<Formula> subRes = new HashSet<>();
for (MatchConstraint con: result) {
try {
int maxIndex = 10000;
int maxDepth = 1;
context.put("maxIndex", maxIndex);
context.put("maxDepth", maxDepth);
subRes.add(conclusion.substitution(con.getBinding(), context));
} catch (SubstituteFailedException e) {
continue;
}
}
return subRes;
}
}