// FILE. . . . . d:/hak/hlt/src/hlt/fot/Functor.java
// EDIT BY . . . Hassan Ait-Kaci
// ON MACHINE. . Hak-Laptop
// STARTED ON. . Sat Jul 14 07:23:44 2018

package hlt.fot;

import hlt.language.util.ArrayList;

/**
 * This is a class for a term-constructor functor (element of a <a
 * href="Signature.html"><tt>Signature</tt></a>).
 *
 * @see         Signature
 *
 * @version     Last modified on Tue Apr 30 06:36:23 2019 by hak
 * @author      <a href="mailto:hak@acm.org">Hassan A&iuml;t-Kaci</a>
 * @copyright   &copy; <a href="http://www.hassan-ait-kaci.net/">by the author</a>
 */

public class Functor
{ /* ************************************************************************ */

  /**
   * Name of this functor.
   */
  protected String name;

  /**
   * Returns the name of this functor.
   */
  public String name ()
  {
    return this.name;
  }

  // The following method is commented out since setting the name of a
  // functor is only done in the Functor constructor (and this make no
  // sense anyway).
  //
  // /**
  //  * Sets the name of this functor to the given string and returns this functor.
  //  */
  // public Functor setName (String name)
  // {
  //   this.name = name;
  //   return this;
  // }

  /* ************************************************************************ */
  
  /**
   * Number of arguments for a term with this functor as root symbol.
   */
  protected int arity;

  /**
   * Returns the number of arguments taken by this functor.
   */
  public int arity ()
  {
    return this.arity;
  }

  // The following method is commented out since setting the arity of a
  // functor is only done in the Functor constructor (and this make no
  // sense anyway).
  //
  // /**
  //  * Sets the arity of this functor to the given <tt>int</tt> and
  //  * returns this functor.
  //  */
  // public Functor setArity (int arity)
  // {
  //   this.arity = arity;
  //   return this;
  // }

  /* ************************************************************************ */
  
  /**
   * Signature where this functor belongs.
   */
  protected Signature signature;

  /**
   * Returns the signature where this functor belongs.
   */
  public Signature signature ()
  {
    return signature;
  }

  /**
   * Index of this functor in its signature (starting at <tt>0</tt> and
   * at most <tt>signature.size()</tt>); <i>i.e.</i>, <tt>this.index</tt> =
   * <tt>signature.functor(index)</tt>.
   */
  protected int index;

  /**
   * Returns the index of this functor in its signature (starting at
   * <tt>0</tt> and at most <tt>signature.size()-1</tt>) and is equal to
   * <tt>signature.functor(index())</tt>.
   */
  public int index ()
  {
    return index;
  }

  /**
   * Returns the position of this functor in its signature (starting at
   * <tt>1</tt> and at most <tt>signature.size()</tt>) that is such that
   * <tt>this.position()</tt> = <tt>this.index()+1</tt>.
   */
  public int position ()
  {
    return index+1;
  }

  /* ************************************************************************ */

  /**
   * Constructs a functor object <tt>name</tt>/<tt>arity</tt> at
   * position <tt>index</tt> in <tt>signature</tt>.
   */
  public Functor (int index, String name, int arity, Signature signature)
  {
    this.index = index;
    this.name = name;
    this.arity = arity;
    this.signature = signature;
  }

  /* ************************************************************************ */

  public boolean equal (Functor functor)
  {
    return this == functor;
  }

  /* ************************************************************************ */

  public String toString ()
  {
    return name; // +"/"+arity;
  }

  /* ************************************************************************ */

  /**
   * Static facilities.
   */

  /**
   * This is an <tt>ArrayList</tt>, initially empty, of
   * <tt>ArrayList</tt>s of <tt>Integer</tt> objects of the form
   * <tt>[1,...,n]</tt>, <tt>0 &\le; n</tt>, denoting the list of
   * argument positions of a functor of arity <tt>n</tt>. Such a list is
   * to serve as a unique reference list for a <a
   * href="../language/util/SetOf.html"><tt>SetOf</tt></a> positions
   * denoting a partial argument map between the arguments of two
   * functors.
   */
  static private ArrayList argumentLists = new ArrayList();

  /**
   * This returns the unique list of <tt>ArrayList</tt>s of
   * <tt>Integer</tt> objects denoting argument positions for the
   * specified arity. It is defined such that each list
   * <tt>[1,...,arity]</tt> is created by need, stored in
   * <tt>argumentLists</tt> at index <tt>arity</tt>, and will never
   * change once created.
   */
  static public ArrayList argumentList (int arity)
  {
    ArrayList argumentList = (ArrayList)argumentLists.get(arity);

    if (argumentList != null)
      return argumentList;

    argumentLists.set(arity,argumentList = new ArrayList(arity));

    for (int i = 0; i < arity; i++)
      // i+1 because argument positions go from 1 to arity
      argumentList.set(i,Integer.valueOf(i+1));

    return argumentList;      
  }

}
