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

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 + ")";
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy