package models.terms;
import lombok.Getter;
import models.algebra.Symbol;
@Getter
public class DependencyTerm extends EvaluatableTerm{
private EvaluatableTerm dependingTerm;
private ResourceVariable dependedVariable;
private EvaluatableTerm argumentTerm;
// public DependencyTerm(int order) {
// super(new Symbol(":", 3), order);
// }
public DependencyTerm(EvaluatableTerm dependingTerm, ResourceVariable dependedVariable, EvaluatableTerm argumentTerm) {
super(
new Symbol(":", 3),
dependedVariable.getOrder() == argumentTerm.getOrder() ? dependedVariable.getOrder() : dependedVariable.getOrder() - 1,
dependedVariable.getSize() + argumentTerm.getSize() + dependedVariable.getSize()
);
this.dependingTerm = dependingTerm;
this.dependedVariable = dependedVariable;
this.argumentTerm = argumentTerm;
addChild(dependingTerm);
addChild(dependedVariable);
addChild(argumentTerm);
}
@Override
public boolean isLinearRightNormalized() {
return isLinearRightNormaled(0);
}
@Override
public EvaluatableTerm linearRightNormalize() {
DependencyTerm newTerm = (DependencyTerm) clone();
newTerm.selfLinearRightNormalize();
return newTerm;
}
@Override
public void selfLinearRightNormalize() {
if(dependingTerm instanceof ResourceVariable || dependingTerm instanceof SetEvaluatableTerm) {
argumentTerm.selfLinearRightNormalize();
return;
}
DependencyTerm dependencyTerm = (DependencyTerm) dependingTerm;
if(! dependencyTerm.isLinearRightNormalized()) {
dependencyTerm.selfLinearRightNormalize();
}
if(! isLinearRightNormalized()) {
EvaluatableTerm childArgumentTerm = dependencyTerm.getArgumentTerm();
DependencyTerm nextDependencyTerm = new DependencyTerm(childArgumentTerm, dependedVariable, argumentTerm);
this.dependingTerm = dependencyTerm.getDependingTerm();
this.dependedVariable = dependencyTerm.getDependedVariable();
this.argumentTerm = nextDependencyTerm;
this.setChild(2, nextDependencyTerm);
this.setChild(0, dependencyTerm.getDependingTerm());
this.setChild(1, dependencyTerm.getDependedVariable());
}
argumentTerm.selfLinearRightNormalize();
}
private boolean isLinearRightNormaled(int depth) {
if(dependingTerm instanceof ResourceVariable || dependingTerm instanceof SetEvaluatableTerm) {
return dependingTerm.getOrder() == dependedVariable.getOrder();
}
DependencyTerm dependencyTerm = (DependencyTerm) dependingTerm;
if(
dependencyTerm.isLinearRightNormaled(depth + 1) &&
dependencyTerm.getDependedVariable().getOrder() - 1 == dependedVariable.getOrder() &&
dependencyTerm.getOrder() == dependedVariable.getOrder() &&
argumentTerm.getOrder() <= dependencyTerm.getOrder() &&
depth == 0
) {
return true;
}
if(
dependencyTerm.isLinearRightNormaled(depth + 1) &&
dependencyTerm.getDependedVariable().getOrder() - 1 == dependedVariable.getOrder() &&
dependencyTerm.getOrder() == dependedVariable.getOrder() &&
argumentTerm.getOrder() < dependencyTerm.getOrder()
) {
return true;
}
return false;
}
public void setDependingTerm(EvaluatableTerm newTerm) {
setChild(0, newTerm);
this.dependingTerm = newTerm;
}
public void setDependedVariable(ResourceVariable newVariable) {
setChild(1, newVariable);
this.dependedVariable = newVariable;
}
public void setArgumentTerm(EvaluatableTerm newTerm) {
setChild(2, newTerm);
this.argumentTerm = newTerm;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append('[');
sb.append(getDependingTerm().toString());
sb.append(" : ");
sb.append(getDependedVariable().toString());
sb.append(" -> ");
sb.append(argumentTerm.toString());
sb.append(']');
return sb.toString();
}
@Override
public String toStringWithOrder() {
StringBuilder sb = new StringBuilder();
sb.append('[');
sb.append(getDependingTerm().toStringWithOrder());
sb.append(" : ");
sb.append(getDependedVariable().toStringWithOrder());
sb.append(" -> ");
sb.append(argumentTerm.toStringWithOrder());
sb.append(']');
sb.append('(');
sb.append(order);
sb.append(')');
return sb.toString();
}
@Override
public boolean equals(Object another) {
if(! (another instanceof DependencyTerm)) {
return false;
}
DependencyTerm term = (DependencyTerm) another;
return dependingTerm.equals(term.getDependingTerm()) &&
dependedVariable.equals(term.getDependedVariable()) &&
argumentTerm.equals(term.getArgumentTerm());
}
@Override
public int hashCode() {
return ("DT" + toString()).hashCode();
}
@Override
public Object clone() {
return new DependencyTerm(
(EvaluatableTerm) dependingTerm.clone(),
(ResourceVariable) dependedVariable.clone(),
(EvaluatableTerm) argumentTerm.clone()
);
}
}