package models.formulas.meta;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import exceptions.IllegalTypeException;
import lombok.Getter;
import models.algebra.Variable;
import models.formulas.DependencyFormula;
import models.formulas.Formula;
import models.terms.Dependency;
import models.terms.RDLTerm;
import models.terms.meta.MatchConstraint;
import models.terms.meta.MetaDependency;
import models.terms.meta.MetaDependencyVariable;
import models.terms.meta.MetaDynamicDependency;
import models.terms.meta.MetaRDLTerm;
import models.terms.meta.MetaTermGenerator;
@Getter
public class MetaDependencyFormula extends MetaFormula {
private MetaRDLTerm dependency;
public MetaDependencyFormula(MetaRDLTerm term) {
if (! term.isDependency()) {
throw new IllegalTypeException();
}
this.dependency = term;
}
public MetaDependencyFormula(MetaDependencyVariable dependency) {
this.dependency = dependency;
}
public MetaDependencyFormula(MetaRDLTerm dependingTerm, List<MetaRDLTerm> dependedTerms) {
this.dependency = new MetaDependency(dependingTerm, dependedTerms);
}
public MetaDependencyFormula(MetaRDLTerm dependingTerm, MetaRDLTerm ...dependedTerms) {
this(dependingTerm, Arrays.asList(dependedTerms));
}
public MetaDependencyFormula(MetaRDLTerm dependingTerm, MetaTermGenerator generator) {
this.dependency = new MetaDynamicDependency(generator, dependingTerm);
}
@Override
public Set<MatchConstraint> isMatchedBy(Formula formula, MatchConstraint constraint) {
if (! (formula instanceof DependencyFormula)) {
return new HashSet<>();
}
DependencyFormula dep = (DependencyFormula) formula;
return dependency.isMatchedBy(dep.getDependency(), constraint);
}
@Override
public DependencyFormula substitution(Map<Variable, RDLTerm> binding) {
return new DependencyFormula((Dependency) dependency.substitute(binding));
}
public String toString() {
return dependency.toString();
}
public boolean equals(Object another) {
if (! (another instanceof MetaDependencyFormula)) {
return false;
}
MetaDependencyFormula anohterFormula = (MetaDependencyFormula) another;
return dependency.equals(anohterFormula.getDependency());
}
public int hashCode() {
return ("MDF" + toString()).hashCode();
}
@Override
public <T extends RDLTerm> Set<T> getSubTerms(Class<T> clazz) {
return new HashSet<>(dependency.getSubTerms(clazz).values());
}
}