package de.renew.unify;

/**
 * This is an interface for checking if a calculation can actually be performed.
 * It provides methods to manage early and late variables, add calculated values,
 * and check the consistency of the calculation process.
 */
public interface ICalculationChecker {
    /**
     * Resets the state of the calculation checker.
     * <p>
     * Clears the sets of early and late variables.
     */
    void reset();

    /**
     * Adds a variable to the set of early variables.
     *
     * @param var the variable to add
     * @param recorder the state recorder to use
     * @throws Impossible if an impossible state is encountered
     */
    void addEarlyVariable(final Variable var, IStateRecorder recorder) throws Impossible;

    /**
     * Inserts a new {@link Calculator} into the unification data structure by
     * unifying it with the given target object.
     * The created calculator uses the given type.
     *
     * @param targetType the type of the target
     * @param target the target object
     * @param source the source object
     * @param recorder the state recorder to use
     * @throws Impossible if the unification fails
     */
    void addCalculated(Class<?> targetType, Object target, Object source, IStateRecorder recorder)
        throws Impossible;

    /**
     * Adds a variable to the set of late variables if it is not already contained.
     *
     * @param var the variable to add
     * @param recorder the state recorder to use
     * @throws Impossible if an impossible state is encountered
     */
    void addLateVariable(final Variable var, IStateRecorder recorder) throws Impossible;

    /**
     * The calculation process is consistent if all early variables are bound
     * and if all late variables are complete.
     *
     * @return if the calculation process is consistent
     */
    boolean isConsistent();
}
