package models.terms;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.IntStream;
import lombok.Getter;
import models.algebra.Symbol;
@Getter
public class DependencyTerm extends EvaluatableTerm{
private EvaluatableTerm dependingTerm;
private List<Resource> dependedResources = new ArrayList<>();
private List<EvaluatableTerm> argumentTerms = new ArrayList<>();
// public DependencyTerm(EvaluatableTerm dependingTerm, EvaluatableTerm dependedTerm, EvaluatableTerm argumentTerm) {
// super(
// new Symbol(":", 3),
// dependedTerm.getOrder() == argumentTerm.getOrder() ? dependedTerm.getOrder() : dependedTerm.getOrder() - 1,
// dependingTerm.getSize() + argumentTerm.getSize() + dependedTerm.getSize()
// );
// this.dependingTerm = dependingTerm;
// this.dependedTerms.add(dependedTerm);
// this.argumentTerms.add(argumentTerm);
// addChild(dependingTerm);
// addChild(dependedTerm);
// addChild(argumentTerm);
// }
public DependencyTerm(EvaluatableTerm dependingTerm, List<Resource> dependedTerms, List<EvaluatableTerm> argumentTerms) {
super(
new Symbol(":", 1 + dependedTerms.size() + argumentTerms.size()),
dependedTerms.get(0).getOrder() == argumentTerms.get(0).getOrder() ? dependedTerms.get(0).getOrder() : argumentTerms.get(0).getOrder() - 1,
dependingTerm.getSize() + argumentTerms.get(0).getSize() + dependedTerms.get(0).getSize()
);
boolean dependedTermsOrderCheck = dependedTerms.stream().allMatch(e -> e.getOrder() == dependedTerms.get(0).getOrder());
// boolean argumentTermsOrderCheck = argumentTerms.stream().allMatch(e -> e.getOrder() == argumentTerms.get(0).getOrder());
if (! (dependedTermsOrderCheck)) {
throw new RuntimeException("Orders are not all equals");
}
if (dependedTerms.size() != argumentTerms.size()) {
throw new RuntimeException("Size not equals");
}
this.dependingTerm = dependingTerm;
this.dependedResources = new ArrayList<>(dependedTerms);
this.argumentTerms = new ArrayList<>(argumentTerms);
addChild(dependingTerm);
for (int i = 0; i < dependedTerms.size(); i++) {
addChild(dependedTerms.get(i));
addChild(argumentTerms.get(i));
}
}
public DependencyTerm(EvaluatableTerm dependingTerm, EvaluatableTerm ...terms) {
this(
dependingTerm,
IntStream.range(0, terms.length).filter(i -> i % 2 == 0).mapToObj(i -> (Resource) terms[i]).toList(),
IntStream.range(0, terms.length).filter(i -> i % 2 == 1).mapToObj(i -> terms[i]).toList()
);
}
@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;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append('[');
sb.append(getDependingTerm().toString());
sb.append(" : ");
for (int i = 0; i < dependedResources.size(); i++) {
sb.append(dependedResources.get(i).toString());
sb.append(" -> ");
sb.append(argumentTerms.get(i).toString());
sb.append(", ");
}
sb.deleteCharAt(sb.length() - 1);
sb.deleteCharAt(sb.length() - 1);
sb.append(']');
return sb.toString();
}
@Override
public String toStringWithOrder() {
StringBuilder sb = new StringBuilder();
sb.append('[');
sb.append(getDependingTerm().toStringWithOrder());
sb.append(" : ");
for (int i = 0; i < dependedResources.size(); i++) {
sb.append(dependedResources.get(i).toStringWithOrder());
sb.append(" -> ");
sb.append(argumentTerms.get(i).toStringWithOrder());
sb.append(", ");
}
sb.deleteCharAt(sb.length() - 1);
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()) &&
dependedResources.stream().sorted().toList().equals(term.getDependedResources().stream().sorted().toList()) &&
argumentTerms.stream().sorted().toList().equals(term.getArgumentTerms().stream().sorted().toList());
}
@Override
public int hashCode() {
return ("DT" + toString()).hashCode();
}
@Override
public Object clone() {
return new DependencyTerm(
(EvaluatableTerm) dependingTerm.clone(),
new ArrayList<>(dependedResources),
new ArrayList<>(argumentTerms)
);
}
}