fr.boreal.model.logicalElements.impl.FunctionalTermImpl Maven / Gradle / Ivy
The newest version!
package fr.boreal.model.logicalElements.impl;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import fr.boreal.model.functions.Invoker;
import fr.boreal.model.logicalElements.api.FunctionalTerm;
import fr.boreal.model.logicalElements.api.Literal;
import fr.boreal.model.logicalElements.api.Substitution;
import fr.boreal.model.logicalElements.api.Term;
import fr.boreal.model.logicalElements.api.Variable;
/**
* Default implementation of FunctionalTerm
* @author Florent Tornil
*
*/
public class FunctionalTermImpl implements FunctionalTerm {
private final String function_name;
private final List sub_terms;
private final Invoker invoker;
/////////////////////////////////////////////////
// Constructors
/////////////////////////////////////////////////
/**
* Default constructor
* @param function_name the name of the function to call
* @param invoker the invoker object to use
* @param sub_terms the parameters of the function
*/
public FunctionalTermImpl(String function_name, Invoker invoker, List sub_terms) {
if (invoker == null) {
throw new IllegalArgumentException(String.format("invoker cannot be null - name: %s - sub_terms: %s", function_name, sub_terms));
}
this.function_name = function_name;
this.sub_terms = sub_terms;
this.invoker = invoker;
}
/////////////////////////////////////////////////
// Public methods
/////////////////////////////////////////////////
@Override
public Term eval(Substitution s) {
boolean evaluable = true;
List sub_terms_images = new ArrayList<>();
for (Term t : this.sub_terms) {
Term image = s.createImageOf(t);
if(!image.isLiteral()) {
evaluable = false;
}
sub_terms_images.add(image);
}
if(evaluable) {
Optional result = this.invoker.invoke(sub_terms_images.toArray(new Term[sub_terms_images.size()]));
return result.orElse(null);
} else {
return new FunctionalTermImpl(this.function_name, this.invoker, sub_terms_images);
}
}
@Override
public Substitution homomorphism(FunctionalTerm o, Substitution s) {
if(o instanceof FunctionalTermImpl) {
FunctionalTermImpl other = (FunctionalTermImpl)o;
if(this.function_name.equals(other.function_name)) {
Iterator fatherTermsIt = this.sub_terms.iterator();
Iterator sonTermsIt = other.sub_terms.iterator();
Substitution res = new SubstitutionImpl();
while(fatherTermsIt.hasNext() && sonTermsIt.hasNext()) {
Term fatherTerm = fatherTermsIt.next();
Term sonTerm = sonTermsIt.next();
if(fatherTerm.isFrozen(s)) {
if(!s.createImageOf(fatherTerm).equals(sonTerm)) {
return null;
}
} else if (fatherTerm.isFunctionalTerm()) {
if(sonTerm.isFunctionalTerm()) {
Substitution innerRes = ((FunctionalTerm)fatherTerm).homomorphism((FunctionalTerm)sonTerm, s);
if(innerRes == null) {
return null;
} else {
res = res.merged(innerRes).orElse(null);
if(res == null) {
return null;
}
}
} else {
return null;
}
} else if (!res.keys().contains(fatherTerm)) {
res.add((Variable) fatherTerm, sonTerm);
} else if (!s.createImageOf(fatherTerm).equals(sonTerm)) {
return null;
}
}
return res;
} else {
return null;
}
} else {
return null;
}
}
@Override
public String label() {
throw new IllegalArgumentException(
"Cannot get the label for a functional term. To get a String representation, please use toString");
}
@Override
public Set getVariables() {
Set variables = new HashSet<>();
for (Term t : sub_terms) {
if(t.isVariable()) {
variables.add((Variable) t);
} else if(t.isFunctionalTerm()) {
variables.addAll(((FunctionalTerm) t).getVariables());
}
}
return variables;
}
@Override
public Set> getLiterals() {
Set> literals = new HashSet<>();
for (Term t : sub_terms) {
if(t.isLiteral()) {
literals.add((Literal>) t);
} else if(t.isFunctionalTerm()) {
literals.addAll(((FunctionalTerm) t).getLiterals());
}
}
return literals;
}
/////////////////////////////////////////////////
// Object methods
/////////////////////////////////////////////////
@Override
public int hashCode() {
return Objects.hash(this.function_name, sub_terms, invoker);
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
} else if (o == null) {
return false;
} else if (o instanceof FunctionalTermImpl) {
FunctionalTermImpl other = (FunctionalTermImpl) o;
boolean staticEqual = this.function_name.equals(other.function_name);
if(staticEqual) {
Iterator thisTermIt = this.sub_terms.iterator();
Iterator otherTermIt = other.sub_terms.iterator();
boolean termEqual = true;
while(thisTermIt.hasNext()) {
if(!otherTermIt.hasNext() || !termEqual) {
return false;
} else {
termEqual = termEqual && thisTermIt.next().equals(otherTermIt.next());
}
}
return termEqual && !otherTermIt.hasNext();
} else {
return false;
}
} else {
return false;
}
}
@Override
public String toString() {
boolean first = true;
String res = this.function_name + "(";
for(Term t : this.sub_terms) {
if(!first) {
res += ", ";
} else {
first = false;
}
res += t;
}
return res + ")";
}
}