// FILE. . . . . d:/hak/hlt/src/hlt/fot/fuz/ArgumentPositionMaps.java
// EDIT BY . . . Hassan Ait-Kaci
// ON MACHINE. . Hak-Laptop
// STARTED ON. . Sun Jul 15 07:37:57 2018

package hlt.fot.fuz;

/**
 * @version     Last modified on Fri Aug 23 11:54:07 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>
 */

import hlt.fot.Functor;

import hlt.language.util.ArrayList;
import hlt.language.util.IntArrayList;
import hlt.language.util.DoubleArrayList;

/**
 * This class represents a fuzzy set of <a
 * href="ArgumentPositionMaps.html"><tt>ArgumentPositionMapping</tt></a>
 * objects.  Given <tt>sim</tt>, a <a
 * href="SignatureSimilarity.html"><tt>SignatureSimilarity</tt></a> on
 * <tt>sig</tt> a <a
 * href="SimilarFunctorSignature.html"><tt>SimilarFunctorSignature</tt></a>,
 * an instance of this class (call it <tt>maps</tt>) specifies, for each
 * approximation degree <tt>&alpha;</tt> in <tt>sim.degrees()</tt></a>,
 * the following information:
 *
 * <ul>
 *
 * <li> for each pair of distinct but <tt>&alpha;</tt>-similar
 * <tt>Functor</tt>s <tt>f</tt> and <tt>g</tt> in <tt>sig</tt>, it
 * specifies a set of elements of the form <tt>i:j</tt>, where
 * <tt>i</tt> and <tt>j</tt> are positive natural numbers such that
 * <tt>1 &le; i &le; f.arity()</tt> and <tt>1 &le; j &le;
 * g.arity()</tt>;</li></p>
 *
 * <p><li>each <tt>i:j</tt> indicates that <tt>f</tt>'s argument position
 * <tt>i</tt> is mapped to <tt>g</tt>'s argument position <tt>j</tt>
 * (and <i>vice versa</i>);</li></p>
 *
 * <p><li>the number of such pairs per mapping may not exceed the
 * minimum of <tt>f</tt>'s arity and <tt>g</tt>'s arity, and determines
 * the size of the mapping;</li></p>
 *
 * <p><li> at any approximation degree <tt>&alpha;</tt> in
 * <tt>sim.degrees()</tt>, for any functor <tt>f</tt>, the
 * <tt>&alpha;</tt>-similarity class <tt>[f]<sub>&alpha;</tt></tt> (a
 * set of functors) is constant and can only increase in size as
 * <tt>&alpha;</tt> decreases; in particular, <tt>[f]<sub>0</sub></tt> =
 * <tt>sim.signature()</tt> (<a
 * href="http://hassan-ait-kaci.net/pdf/partial-non-aligned-maps-prelim-june-2018.pdf">click
 * here</a> for details);</li></p>
 *
 * <p><li>the information <tt>[f,g,&alpha;,pairs]</tt> is represented as
 * an <a
 * href="ArgumentPositionMapping.html"><tt>ArgumentPositionMapping</tt></a>
 * object.</li></p>
 *
 * </ul>
 *
 * @see         ../Functor
 * @see         ../Signature
 * @see         SignatureSimilarity
 * @see         SimilarFunctorSignature
 * @see         ArgumentPositionMapping
 */

public class ArgumentPositionMaps
{
  /**
   * The signature similarity of this <tt>ArgumentPositionMaps</tt> object.
   */
  private SignatureSimilarity similarity;

  /**
   * Returns the signature similarity of this <tt>ArgumentPositionMaps</tt> object.
   */
  public SignatureSimilarity similarity ()
  {
    return similarity;
  }

  /**
   * Returns this <tt>ArgumentPositionMaps</tt> object's similarity's signature.
   */
  public SimilarFunctorSignature signature ()
  {
    return similarity.signature();
  }

  /**
   * Returns the list of <tt>double</tt>s that are the fuzzy
   * approximation degrees of the mappings that constitute this
   * <tt>ArgumentPositionMaps</tt> object as a
   * <tt>DoubleArrayList</tt>. By construction, it will always be sorted
   * in strictly increasing order; <i>i.e.</i>, if <tt>0</tt> &le;
   * <tt>i</tt> &lt; <tt>j</tt> &lt; <tt>size()</tt>, then
   * <tt>degrees().get(i)</tt> &lt; <tt>degrees().get(j)</tt>.
   */
  public DoubleArrayList degrees ()
  {
    return similarity.degrees();
  }

  /**
   * Returns the number of maps.
   */
  public int size ()
  {
    return degrees().size();
  }

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

  /**
   * The list <tt>argumentMappings</tt> is an <tt>ArrayList</tt> of
   * <tt>ArgumentPositionMapping</tt> objects. It has the same size as
   * <tt>degrees()</tt></a>.  For each fuzzy degree <tt>&alpha;</tt> in
   * <tt>degrees()</tt>, it associates to each pair
   * &lang;<tt>f</tt>,<tt>g</tt>&rang; of distinct but
   * <tt>&alpha;</tt>-similar functors an argument position mapping in
   * the form of a list of pairs of argument positions <tt>i:j</tt>,
   * where <tt>1</tt> &le; <tt>i</tt> &le; <tt>f.arity()</tt> and
   * <tt>1</tt> &le; <tt>j</tt> &le; <tt>g.arity()</tt>.
   */
  private ArrayList argumentMappings = new ArrayList(size());

  /**
   * Returns the list of <tt>ArgumentPositionMapping</tt> objects. This
   * is an <tt>ArrayList</tt> that has the same size as the
   * <tt>DoubleArrayList</tt> <tt>degrees()</tt>. An
   * <tt>ArgumentPositionMapping</tt> specifies a set of pairs of
   * argument positions for a given approximation degree
   * <tt>&alpha;</tt> in <tt>degrees()</tt> and a pair of distinct but
   * <tt>&alpha;</tt>-similar functors
   * &lang;<tt>f</tt>,<tt>g</tt>&rang;.
   */
  public ArrayList argumentMappings ()
  {
    return argumentMappings;
  }

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

  /**
   * This defines an argument position mapping for the approximation
   * degree at specified index, functors, and list of position pairs.

   * In order to take into account a signature similarity during
   * unification and generalization, for each similarity degree
   * <tt>&alpha;</tt> in <tt>degrees()</tt> (<i>i.e.</i>, in
   * <tt>similarity().degrees()</tt> inherited from <a
   * href="../../math/fuzzy/FuzzyMatrix.html"><tt>hlt.math.fuzzy.FuzzyMatrix</tt></a>
   * that returns them as a <tt>DoubleArrayList</tt> sorted in
   * increasing order), we must specify for any pair of distinct but
   * <tt>&alpha;</tt>-similar functors &lang;<tt>f</tt>,<tt>g</tt>&rang;
   * the number and order of argument positions to take into account to
   * propagate the unification or generalization operations to their
   * respective corresponding subterms. There are conditions that must
   * be verified such that these mappings be consistent with the
   * reflexivity, symmetry, and transitivity of the similarity (<a
   * href="http://hassan-ait-kaci.net/pdf/partial-non-aligned-maps-prelim-june-2018.pdf">click
   * here</a> for details). This is done by the
   * <tt>ArgumentPositionMapping</tt> which throws a
   * <tt>BadArgumentPositionMappingException</tt> when these conditions
   * are violated. If the constructor is verified, this means that the
   * mapping is consistent and complete, or was completed as necessary
   * to the least consistent reflexive, symmetric, and transitive
   * argument-position mapping containing the specified pairs. If the
   * mapping is found inconsistent, an exception is raised and no
   * mapping is defined.
   */
  public void defineArgumentMapping (int index,
				     Functor f, Functor g,
				     IntArrayList positionPairs)
  {
    try
      {
	ArgumentPositionMapping map
	  = new ArgumentPositionMapping(this,index,f,g,positionPairs);

	// set the index of this mapping in the set of ArgumentPositionMaps containing this map:
	map.setMappingIndex(index);
	// and add map to this set of argument maps
	argumentMappings.add(map);
      }
    catch (BadArgumentPositionMappingException e)
      {
	System.err.println(e+" (ignored)");
      }
      
  }

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

  /**
   * The method invocation <tt>verifyConsistency()</tt> has for purpose
   * to verify the consistency of the declared argument-position
   * mappings that were declared for this
   * <tt>ArgumentPositionMaps</tt>. It ensures that the declared
   * mappings respect:
   *
   * <p>
   *
   * <center>
   * <table>
   *   <tr>
   *     <td><i>approximation consistency</i>:
   *     </td>
   *     <td>&forall; <tt>f</tt> &isin; &Sigma;<sub><tt>m</tt></sub> ,
   *         &forall; <tt>g</tt> &isin; &Sigma;<sub><tt>n</tt></sub> ,
   *         if <tt>&alpha;</tt> &leq; <tt>&beta;</tt> then
   *         &mu;<sup><tt>&alpha;</tt></sup><sub><tt>f,g</tt></sub>
   *         &sube; &mu;<sup><tt>&beta;</tt></sup><sub><tt>f,g</tt></sub>
   *         (as sets of pairs)
   *     </td>
   *   </tr>
   *   <tr>
   *     <td><i>reflexive consistency</i>:
   *     </td>
   *     <td>&forall; <tt>f</tt> &isin; &Sigma;<sub><tt>n</tt></sub> ,
   *         &mu;<sup><tt>&alpha;</tt></sup><sub><tt>f,f</tt></sub> =
   *         <b>Id</b><sub><tt>{1,...,n}</tt></sub>
   *     </td>
   *   </tr>
   *   <tr>
   *     <td><i>symmetric consistency</i>:
   *     </td>
   *     <td>&forall; <tt>f</tt> &isin; &Sigma;<sub><tt>m</tt></sub> ,
   *         &forall; <tt>g</tt> &isin; &Sigma;<sub><tt>n</tt></sub> ,
   *         &mu;<sup><tt>&alpha;</tt></sup><sub><tt>f,g</tt></sub> =
   *         (&mu;<sup><tt>&alpha;</tt></sup><sub><tt>g,f</tt></sub>)<sup>-1</sup>
   *     </td>
   *   </tr>
   *   <tr>
   *     <td><i>transitive consistency</i>:
   *     </td>
   *     <td>&forall; <tt>f</tt> &isin; &Sigma;<sub><tt>m</tt></sub> ,
   *         &forall; <tt>g</tt> &isin; &Sigma;<sub><tt>n</tt></sub> ,
   *         &forall; <tt>h</tt> &isin; &Sigma;<sub><tt>p</tt></sub> ,
   *         &mu;<sup><tt>&alpha;</tt></sup><sub><tt>h,f</tt></sub> =
   *         &mu;<sup><tt>&alpha;</tt></sup><sub><tt>g,f</tt></sub>
   *         &compfn; &mu;<sup><tt>&alpha;</tt></sup><sub><tt>h,g</tt></sub>
   *     </td>
   *   </tr>
   * </table>
   * </center>
   *
   * <p>
   * for all approximation degrees <tt>&alpha;</tt> and
   * <tt>&beta;</tt> in <tt>degrees()</tt> obtained from the pairs
   * declared in this <tt>ArgumentPositionMaps</tt> by completing the
   * declared set of mappings with their reflexive, symmetric, and
   * transitive closures.
   */

  public void verifyConsistency ()
  {
    try
      {
	System.out.println
	  ("+++ Verifying consistency of specified similar functor argument-position mappings");

	// verifyApproximationConsistency();

	// verifyReflexiveConsistency();

	// verifySymmetryConsistency();

	// verifyTransitiveConsistency();

      }
    catch (BadArgumentPositionMappingException e)
      {
	System.err.println(e+" (please fix before recompiling)");
      }
  }

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

}
