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

fr.boreal.model.logicalElements.api.Substitution Maven / Gradle / Ivy

The newest version!
package fr.boreal.model.logicalElements.api;

import java.util.*;

/**
 * A substitution is an application from a set of variables into a set of terms.
 * 
 * @author Florent Tornil
 *
 */
public interface Substitution {

	/**
	 * Get the image of the given term by this substitution, if there is no image
	 * specified return the term itself.
	 * 
	 * @param term a term
	 * @return the image of the specified term.
	 */
	Term createImageOf(Term term);

	/**
	 * Get the domain of this substitution.
	 * 
	 * @return the domain of this substitution.
	 */
	Collection keys();

	/**
	 * Adds a mapping from the specified variable into the specified image to this
	 * substitution.
	 * 
	 * @param v the key
	 * @param t the image
	 * 
	 */
	void add(Variable v, Term t);

	/**
	 * Apply this substitution on an atom.
	 * 
	 * @param atom an atom
	 * @return an Atom which is the image of specified one by this substitution.
	 */
	Atom createImageOf(Atom atom);

	/**
	 * Two substitutions can be merged iff for each key in common, the image is the
	 * same
	 * 
	 * @param other a substitution
	 * @return a new substitution being the merge of this one and the other one or
	 *         an empty optional if the substitutions are not compatible
	 */
	Optional merged(Substitution other);

	/**
	 * @param vars variables to limit to
	 * @return a new substitution identical to this one but limited to a subset of
	 *         variables
	 */
	Substitution limitedTo(Collection vars);

	/**
	 * @param other a substitution
	 * @return true iff the other substitution is included into this one
	 */
	boolean isExtensionOf(Substitution other);

	/**
	 * The aggregation of a substitution is more complex that just add a new
	 * mapping for a new variable. Especially, it does not conserve the domain and
	 * codomain. It chooses a representative term for each connected component by
	 * successive application of the mapping. For example, if the current
	 * substitution is {X -> Y, Z -> U} and you add a mapping {Y -> 'a', Z -> V},
	 * the result is {Y -> 'a', X -> 'a', Z -> V, U -> V} or {Y -> 'a', X -> 'a', U
	 * -> Z, V -> Z} or {Y -> 'a', X -> 'a', Z -> U, V -> U}.
	 * 
	 * @param s the substitution to aggregate with
	 * @return the aggregated substitution or an empty optional if it is not
	 *         possible
	 */
	Optional aggregated(Substitution s);

	/**
	 * Remove the given variable affectation from this substitution
	 * 
	 * @param v a variable
	 */
	void remove(Variable v);

	/**
	 * @return true iff this substitution is empty
	 */
	boolean isEmpty();

	/**
	 * 
	 * @return true if the image of variables in this substitution are constants
	 */
	default boolean mapsToConstantsOnly() {

		return keys().stream().allMatch(variable -> createImageOf(variable).isFrozen(null));

	}

    /**
	 * 
	 * @param variableSet of variables which must map to constants only
	 * @return true if the image of variables in this substitution are constants
	 */
	default boolean mapsToConstantsOnly(Collection variableSet) {

		return keys().stream()
				.allMatch(variable -> (!variableSet.contains(variable)) || createImageOf(variable).isFrozen(null));

	}

	/**
	 * @return true iff this substitution is injective
	 */
	boolean isInjective();

	/**
	 * @return true iff the inverse of this substitution is a substitution
	 */
	boolean isInvertible();

	/**
	 * @return all range term of the substitution
	 */
	Set rangeTerms();

	/**
	 * Remove the variables that are sent into themselves
	 */
	default void removeIdentity() {
		new ArrayList<>(this.keys()).stream().filter(v -> v.equals(this.createImageOf(v))).forEach(this::remove);
	}

	/**
	 * Convert the substitution to a map
	 * @return A map that represents the substitution
	 */
	Map toMap();
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy