// $Id: Argument.java,v 1.6 2004/02/27 16:30:00 m31 Exp $
//
// This file is part of the program suite "Principia Mathematica II"
// which is a working prototype for the main project:
// "Hilbert II" - http://www.qedeq.org
//
// Copyright 2001-2004  Michael Meyling <mime@qedeq.org>.
//
// "Principia Mathematica II" is free software; you can redistribute
// it and/or modify it under the terms of the GNU General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

package com.meyling.principia.argument;


/**
 * Every Operator must implement this interface. Each operator deals with
 * arguments.
 * These arguments form an ordered list. So there is the number of
 * arguments,
 * which is told by {@link #getArgumentSize} and the <code>i</code>-th
 * argument,
 * accessible by {@link #getArgument}.
 * @version $Revision: 1.6 $
 * @author  Michael Meyling
 */
public interface Argument {


    /**
     * Get the number of arguments.
     *
     * @return number of arguments
     */
    public abstract int getArgumentSize();


    /**
     * Get the requested argument.
     *
     * @param   i   number of argument (starting with <code>0</code>)
     * @return  <code>i</code>-th part formula
     * @throws  IllegalArgumentException    if <code>i</code> is not inbetween
     *           <code>0</code> and <code>{@link #getArgumentSize} - 1</code>
     */
    public abstract Argument getArgument(int i)
        throws IllegalArgumentException;


    /**
     * Is this object equal to the given one? This is true iff
     * <code>object</code> is an instance of {@link Argument} and
     * both arguments have the same
     * {@link #getArgumentSize} and each {@link #getArgument} {@link #equals}.
     *
     * @param   object     to compare with
     * @return  is <code>object</code> equal to this one?
     */
    public boolean equals(Object object);


    /**
     * Calculates the hashcode. Returns the hashcode of the representing string.
     *
     * @return  hashcode of this object
     */
    public int hashCode();


    /**
     * Returns an identical object (maybe "this").
     *
     * @return copy of this object
     */
    public Argument copy();


    /**
     * Creates and returns a copy of this object, but
     * replaces anything that {@link #equals} <code>argument</code>
     * with a {@link #copy} of <code>replacement</code>.
     *
     * @param   search      check for occurrence of this
     * @param   replacement replace with this
     * @return  copy with replacements
     * @throws  ArgumentException   if creation failed
     */
    public Argument replace(Argument search, Argument replacement)
        throws ArgumentException;


    /**
     * Replace every pattern variable that occurs in
     * <code>variables</code> with its content.
     *
     * @param   variables   List of (filled) pattern variables
     * @return  argument, where all pattern variables (in
     *          <code>variables</code>) are replaced with
     *          its content
     * @throws  ArgumentException   if creation failed
     */
    public Argument replace(PatternVariables variables)
        throws ArgumentException;


    /**
     * Replace the <code>occurrence</code>-th occurence of
     * <code>searchPattern</code> with <code>replacePattern</code>.
     *
     * @param   counter         number of matches so far
     * @param   occurrence      number of matches to act on
     * @param   searchPattern   pattern for matching
     * @param   replacePattern  pattern for replacing matched pattern with
     * @return  replaced argument
     * @throws  ArgumentException   if creation failed
     */
    public Argument replace(Enumerator counter, int occurrence,
        Argument searchPattern, Argument replacePattern)
        throws ArgumentException;



    /**
     * Get a children parents list for the <code>occurrence</code>-th
     * occurence of <code>searchPattern</code>.
     *
     * @param   counter         number of matches so far
     * @param   occurrence      number of matches to act on
     * @param   searchPattern   pattern for matching
     * @throws  FoundException  if creation succeded
     */
    public void getSearchParents(final Enumerator counter,
        final int occurence,
        final Argument searchPattern)
        throws FoundException;

    /**
     * Get a children parents list for the <code>occurrence</code>-th
     * occurence of <code>searchPattern</code> replaced by
     * <code>replacementPattern</code>.
     *
     * @param   counter         number of matches so far
     * @param   occurrence      number of matches to act on
     * @param   searchPattern   pattern for matching
     * @param   replacementPattern   replacement pattern
     * @throws  FoundException  if creation succeded
     */
    public void getReplacementParents(final Enumerator counter,
        final int occurence,
        final Argument searchPattern,
        final Argument replacementPattern)
        throws FoundException, ArgumentException;

    /**
     * Replace all occurrences of <code>searchPattern</code> with
     * <code>replacePattern</code>.
     *
     * @param   searchPattern   pattern for matching
     * @param   replacePattern  pattern for replacing matched pattern with
     * @return  replaced argument
     * @throws  ArgumentException   if creation failed
     */
    public Argument replaceMatches(Argument searchPattern,
        Argument replacePattern)
        throws ArgumentException;


    /**
     * Does this argument match the <code>pattern</code>?
     * For example: "A1 n A1" matches the pattern "@0 n @1" with resulting
     * variables {@0(A1), @1(A1)}.
     * Be carefull, after an unsuccessful matching, some pattern
     * variables could have been found, so <code>variables</code>
     * might contain some filled pattern variables.
     * @param   pattern argument build of pattern variables
     * @param   variables   already known pattern variables
     * @return  successfull matching
     */
    public boolean matches(Argument pattern, PatternVariables variables);


    /**
     * Does any part of this argument match the <code>pattern</code>?
     * For example: "A1 n A1" matches the pattern "@0 n @1",
     * "A1 v A2 matches the pattern "A2".
     *
     * @param   pattern     argument build of pattern variables
     * @return  successfull matching somewhere
     */
    public boolean matches(Argument pattern);


    /**
     * Does this argument contain any PatternVariable?
     *
     * @return  does one part of this argument is an
     * {@link PatternVariable}
     */
    public boolean containsPatternVariables();


    /**
     * Get all pattern variables that occur in this argument.
     *
     * @return  all pattern variables
     */
    public PatternVariables getPatternVariables();



    /**
     * Create a new Argument with given arguments.
     *
     * @param   arguments   with these arguments the operator should
     *                      be created
     * @return  new constructed Argument
     * @throws  ArgumentException   if creation failed
     */
    public Argument create(Argument[] arguments)
        throws ArgumentException;


    /**
     * Get the argument in <code>String</code> form.
     *
     * @return  readable formula
     */
    public String toString();

}
