fr.boreal.model.logicalElements.impl.ComputedAtomImpl Maven / Gradle / Ivy
The newest version!
package fr.boreal.model.logicalElements.impl;
import java.util.*;
import fr.boreal.model.functions.Invoker;
import fr.boreal.model.logicalElements.api.Atom;
import fr.boreal.model.logicalElements.api.ComputedAtom;
import fr.boreal.model.logicalElements.api.Constant;
import fr.boreal.model.logicalElements.api.Literal;
import fr.boreal.model.logicalElements.api.Predicate;
import fr.boreal.model.logicalElements.api.Substitution;
import fr.boreal.model.logicalElements.api.Term;
/**
* Default implementation of a ComputedAtom
*
* @author Florent Tornil
*
*/
public class ComputedAtomImpl extends AtomImpl implements ComputedAtom {
private final Invoker invoker;
/////////////////////////////////////////////////
// Constructors
/////////////////////////////////////////////////
/**
* Constructor using a list of terms
* @param invoker the invoker
* @param predicate the predicate
* @param terms the list of terms
*/
public ComputedAtomImpl(Invoker invoker, Predicate predicate, List terms) {
super(predicate, terms);
this.invoker = invoker;
this.checkInvoker();
}
/**
* Constructor using an array of terms
* @param invoker the invoker
* @param predicate the predicate
* @param terms the array of terms
*/
public ComputedAtomImpl(Invoker invoker, Predicate predicate, Term... terms) {
super(predicate, terms);
this.invoker = invoker;
this.checkInvoker();
}
/////////////////////////////////////////////////
// Public methods
/////////////////////////////////////////////////
@Override
public Atom eval(Substitution s) {
boolean evaluable = true;
ArrayList sub_terms_images = new ArrayList<>();
for (Term t : this.getTerms()) {
Term image = s.createImageOf(t);
if(!image.isLiteral()) {
evaluable = false;
}
sub_terms_images.add(image);
}
if(!evaluable) {
return new ComputedAtomImpl(this.invoker, this.getPredicate(), sub_terms_images);
}
Optional result = this.invoker.invoke(sub_terms_images.toArray(new Term[sub_terms_images.size()]));
Atom top = new AtomImpl(Predicate.TOP);
Atom bottom = new AtomImpl(Predicate.BOTTOM);
/*
* According to the type of the result we return the correct TOP or BOTTOM atom.
*
* If the result is a Constant, we return TOP
*
* If the result is a Boolean, we return TOP if the boolean is true, BOTTOM
* otherwise
*
* If the result is an Integer, we return TOP if the Integer value is (strictly)
* greater than 0, BOTTOM otherwise
*
* If the result is a String, we return TOP if the String is (case insensitive)
* "true", BOTTOM otherwise
*
* If it is something else, we return BOTTOM
*/
if (result.isPresent()) {
Term res = result.get();
if (res instanceof Constant) {
return top;
} else if (res instanceof Literal>) {
Literal> l = (Literal>)res;
Object value = l.value();
if (value instanceof Boolean) {
Boolean b = (Boolean)value;
return b.booleanValue() ? top : bottom;
} else if (value instanceof Integer) {
Integer i = (Integer)value;
return i.intValue() > 0 ? top : bottom;
} else if (value instanceof String) {
String str = (String)value;
return str.equalsIgnoreCase("true") ? top : bottom;
} else {
return bottom;
}
} else {
return bottom;
}
} else {
return bottom;
//throw new RuntimeException(String.format("Could not evaluate computed atom %s with substitution %s", this, s));
}
}
/////////////////////////////////////////////////
// Getters
/////////////////////////////////////////////////
/////////////////////////////////////////////////
// Object methods
/////////////////////////////////////////////////
@Override
public int hashCode() {
return Objects.hash(this.getTerms(), this.getPredicate(), this.invoker);
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
} else if (o == null) {
return false;
} else if (o instanceof ComputedAtom) {
ComputedAtom c = (ComputedAtom)o;
if (this.getPredicate().equals(c.getPredicate())) {
for (int i = 0; i < this.getTerms().length; i++) {
if (!this.getTerm(i).equals(c.getTerm(i))) {
return false;
}
}
return true;
} else {
return false;
}
} else {
return false;
}
}
private void checkInvoker() {
if (this.invoker == null) {
throw new IllegalStateException(
String.format(
"The invoker in ComputedAtomImpl is null: [predicate: %s, terms: %s]",
this.getPredicate(),
Arrays.toString(this.getTerms())));
}
}
}