package de.uni_hamburg.fs;

import collections.CollectionEnumeration;


/**
 * Represents a type in the feature structure system.
 * Types define the structure and behavior of features,
 * including their relationships, constraints and operations.
 * Types can be unified, compared for subsumption, and used to create new nodes.
 */
public interface Type extends java.io.Serializable {

    /**
     * The most general Type.
     */
    public static final ConjunctiveType TOP = new ConjunctiveType(true);

    /**
     * The most general ANY-Type.
     */
    public static final ConjunctiveType ANY = new ConjunctiveType(false);

    /**
     * Anonymous (dummy) ANY-Type.
     */
    public static final ConjunctiveType NONE = new ConjunctiveType(false, false);

    /**
     * Gives the name of this Type.
     *
     * @return the name of this Type.
     */
    public String getName();

    /**
     * Return the fully qualified name of this Type.
     *
     * @return the name
     */
    public String getFullName();

    /**
     * Return whether this Type is extensional.
     *
     * @return true if extensional
     */
    public boolean isExtensional();

    /**
     * Return whether this Type represents an instance.
     *
     * @return true if it's an instance
     */
    public boolean isInstanceType();

    /**
     * Return the instantiated version of this Type.
     *
     * @return the instantiated Type
     */
    public Type getInstanceType();

    // Return whether this Type restricts which features are allowed.
    // A non-restricted Type is appropriate for every feature.
    //
    // public boolean isRestricted();

    /**
     * Returns whether the feature {@literal <feature>} is appropriate in this Type.
     *
     * @param featureName name of the feature.
     * @return true if it's appropriate in this Type.
     */
    public boolean isApprop(Name featureName);

    /**
     * Give the required Type of the Value found under the given feature.
     *
     * @param featureName The feature has to be appropriate for this Type.
     * @return the Type of the Value.
     * @throws NoSuchFeatureException - if the feature is not appropriate
     */
    public Type appropType(Name featureName) throws NoSuchFeatureException;

    /**
     * Return an Enumeration of all appropriate features.
     *
     * @return an Enumeration of features.
     */
    public CollectionEnumeration appropFeatureNames();

    /**
     * Give whether this Type subsumes {@literal <that>} Type.
     *
     * @param that the Type
     * @return true if the Type subsumes {@literal <that>} Type.
     * In other words, return whether this Type is more general than {@literal <that>} Type.
     */
    public boolean subsumes(Type that);

    /**
     * Return the unification of this Type and {@literal <that>} Type.
     * This Type is not modified!
     *
     * @param that the Type to unify
     * @return unified Type
     * @throws UnificationFailure if unification fails
     */
    public Type unify(Type that) throws UnificationFailure;

    /**
     * Return whether this Type and {@literal <that>} Type are compatible.
     *
     * @param that the Type
     * @return true compatible
     */
    public boolean canUnify(Type that);

    /**
     * Look for the most general common extensional supertype of this and {@literal <that>}.
     *
     * @param that the Type
     * @return the most general common extensional supertype
     */
    public Type mostGeneralExtensionalSupertype(Type that);

    /**
     * Return a new node from this type.
     *
     * @return Node
     */
    public Node newNode();

    /**
     * Return an Enumeration of all Concepts this Type is
     * composed of.
     */


    //  public ConceptEnumeration concepts();
    // should be unnecessary, Renew bug has to be fixed:
    @Override
    public boolean equals(Object that);
}