All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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())));
		}
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy