package org.matheclipse.core.interfaces;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

import javax.annotation.Nullable;

import org.matheclipse.core.eval.EvalEngine;
import org.matheclipse.core.visit.IVisitor;
import org.matheclipse.core.visit.IVisitorBoolean;
import org.matheclipse.core.visit.IVisitorInt;

import com.google.common.base.Function;
import com.google.common.base.Predicate;

import edu.jas.structure.RingElem;

/**
 * 
 * (I)nterface for a mathematical (Expr)ession
 * 
 */
public interface IExpr extends Comparable, RingElem, Serializable {

	public final static int ASTID = 256;

	public final static int COMPLEXID = 32;

	public final static int DOUBLECOMPLEXID = 4;

	public final static int DOUBLEID = 2;

	public final static int FRACTIONID = 16;

	public final static int INTEGERID = 8;

	public final static int METHODSYMBOLID = 1024;

	public final static int PATTERNID = 512;

	public final static int STRINGID = 64;

	public final static int SYMBOLID = 128;

	/**
	 * Accept a visitor with return type T
	 */
	public  T accept(IVisitor visitor);

	/**
	 * Accept a visitor with return type boolean
	 */
	public boolean accept(IVisitorBoolean visitor);

	/**
	 * Accept a visitor with return type int
	 * 
	 * @param visitor
	 * @return
	 */
	public int accept(IVisitorInt visitor);

	public IExpr and(final IExpr that);

	/**
	 * @param leaves
	 * @return an IExpr instance with the current expression as head(), and leaves as leaves().
	 */
	public IExpr apply(IExpr... leaves);

	/**
	 * @param leaves
	 * @return an IExpr instance with the current expression as head(), and leaves as leaves().
	 */
	public IExpr apply(List leaves);

	public Object asType(Class clazz);

	/**
	 * Compares this expression with the specified expression for order. Returns a negative integer, zero, or a positive integer as
	 * this expression is canonical less than, equal to, or greater than the specified expression.
	 */
	@Override
	public int compareTo(IExpr obj);

	/**
	 * Evaluate an expression
	 * 
	 * @param engine
	 *            the evaluation engine
	 * @return the evaluated Object or null if the evaluation is not possible (i.e. the evaluation doesn't change the
	 *         object).
	 */
	public IExpr evaluate(EvalEngine engine);

	// public IExpr div(final IExpr that);

	/**
	 * Return the FullForm of this expression
	 */
	public String fullFormString();

	/**
	 * 
	 * Get the element at the specified index if this object is of type IAST.
	 * 
	 * @param index
	 * @return
	 */
	public IExpr getAt(final int index);

	/**
	 * If this object is an instance of IAST get the first element (offset 0) of the IAST list (i.e.
	 * get(0) ).
	 * 
	 * @return the head of the expression, which must not be null.
	 */
	public IExpr head();

	/**
	 * A unique integer ID for the implementation of this expression
	 * 
	 * @return a unique integer id for the implementation of this expression
	 */
	public int hierarchy();

	/**
	 * Return the internal Java form of this expression.
	 * 
	 * @param symbolsAsFactoryMethod
	 *            if true use the F.symbol() method, otherwise print the symbol name.
	 * @param depth
	 *            the recursion depth of this call. 0 indicates "recurse without a limit".
	 */
	public String internalFormString(boolean symbolsAsFactoryMethod, int depth);

	/**
	 * Returns the multiplicative inverse of this object. It is the object such as this.times(this.inverse()) == ONE ,
	 * with ONE being the multiplicative identity.
	 * 
	 * @return ONE / this.
	 */
	@Override
	IExpr inverse();

	/**
	 * Test if this expression is the function And[<arg>,...]
	 * 
	 */
	public boolean isAnd();

	/**
	 * Test if this expression is the function ArcCos[<arg>]
	 * 
	 */
	public boolean isArcCos();

	/**
	 * Test if this expression is the function ArcCosh[<arg>]
	 * 
	 */
	public boolean isArcCosh();

	/**
	 * Test if this expression is the function ArcSin[<arg>]
	 * 
	 */
	public boolean isArcSin();

	/**
	 * Test if this expression is the function ArcSinh[<arg>]
	 * 
	 */
	public boolean isArcSinh();

	/**
	 * Test if this expression is the function ArcTan[<arg>]
	 * 
	 */
	public boolean isArcTan();

	/**
	 * Test if this expression is the function ArcTanh[<arg>]
	 * 
	 */
	public boolean isArcTanh();

	/**
	 * Test if this expression is an AST list, which contains a header element (i.e. the function name) at index position
	 * 0 and some optional argument elements at the index positions 1..n. Therefore this expression
	 * is no atomic expression.
	 * 
	 * @see #isAtom()
	 */
	public boolean isAST();

	/**
	 * Test if this expression is an AST list, which contains a header element (i.e. a function symbol like for example
	 * Plus or Times) with attribute Orderless at index position 0 and some optional
	 * argument elements at the index positions 1..n. Examples for Orderless functions are
	 * Plus[] or Times[]. Therefore this expression is no atomic expression.
	 * 
	 * @see #isAtom()
	 */
	public boolean isOrderlessAST();

	/**
	 * Test if this expression is an AST list, which contains a header element (i.e. a function symbol like for example
	 * Dot, Plus or Times) with attribute Flat at index position 0 and some optional
	 * argument elements at the index positions 1..(size()-1). Examples for Flat functions are
	 * Dot[], Plus[] or Times[]. Therefore this expression is no atomic expression.
	 * 
	 * @see #isAtom()
	 * 
	 */
	public boolean isFlatAST();

	/**
	 * Test if this expression is an AST list, which contains the given header element at index position 0 and
	 * some optional argument elements at the index positions 1..(size()-1). Therefore this expression is not an
	 * atomic expression.
	 * 
	 * @see #isAtom()
	 * 
	 */
	public boolean isAST(IExpr header);

	/**
	 * Test if this expression is an AST list, which contains the given header element at index position 0 and
	 * optional argument elements at the index positions 1..(length-1). Therefore this expression is not an
	 * atomic expression.
	 * 
	 * @see #isAtom()
	 */
	public boolean isAST(IExpr header, int length);

	/**
	 * Test if this expression is an AST list, which contains the given header element at index position 0 and
	 * optional argument elements at the index positions 1..(length-1). Therefore this expression is not an
	 * atomic expression.
	 * 
	 * @param args
	 *            the arguments of this AST which should be tested, if they are equal, a null value argument skips the
	 *            equals chack.
	 * @see #isAtom()
	 */
	public boolean isAST(IExpr header, int length, IExpr... args);

	/**
	 * Test if this expression is an AST list, where the string representation of the header element at index position
	 * 0 equals the given symbol and some optional argument elements at the index positions
	 * 1..(size()-1). Therefore this expression is no atomic expression. Example: isAST("Sin")
	 * gives true for Sin[Pi/2].
	 * 
	 * @see #isAtom()
	 * 
	 */
	public boolean isAST(String symbol);

	/**
	 * Test if this expression is an AST list, where the string representation of the header element at index position
	 * 0 equals the given symbol and some optional argument elements at the index positions
	 * 1..(length-1). Therefore this expression is no atomic expression. Example: isAST("Sin", 2)
	 * gives true for Sin[0].
	 * 
	 * @see #isAtom()
	 */
	public boolean isAST(String symbol, int length);

	/**
	 * Test if this expression is an AST (i.e. no atomic expression) with the given head expression and size of elements greater
	 * equal than the AST#size()
	 * 
	 * Test if this expression is an AST list, which contains the given header element at index position 0 and
	 * optional argument elements at the index positions 1..n. n must be greater equal than the
	 * given length. Therefore this expression is no atomic expression.
	 * 
	 * @see #isAtom()
	 */
	public boolean isASTSizeGE(IExpr header, int length);

	/**
	 * Test if this expression is an atomic expression (i.e. no AST expression)
	 * 
	 */
	public boolean isAtom();

	/**
	 * Test if this expression is a symbolic complex number
	 * 
	 */
	public boolean isComplex();

	/**
	 * Test if this expression is a numeric complex number
	 * 
	 */
	public boolean isComplexNumeric();

	/**
	 * Test if this expression is a symbol with attribute Constant. Therefore numbers return false for
	 * this method!
	 * 
	 * @see #isRealFunction()
	 * @see #isNumericFunction()
	 */
	public boolean isConstant();

	/**
	 * Test if this expression is representing ComplexInfinity (i.e. DirectedInfinity[])
	 * 
	 */
	public boolean isComplexInfinity();

	/**
	 * Test if this expression is representing a DirectedInfinity (i.e. Infinity->DirectedInfinity[1],
	 * -Infinity->DirectedInfinity[-1], ComplexInfinity->DirectedInfinity[])
	 * 
	 */
	public boolean isDirectedInfinity();

	/**
	 * Test if this expression is representing Infinity (i.e. Infinity->DirectedInfinity[1])
	 * 
	 */
	public boolean isInfinity();

	/**
	 * Test if this object is a negative signed number.
	 * 
	 * @return true, if this < 0; false in all other case.
	 */
	public boolean isNegative();

	/**
	 * Test if this expression is representing -Infinity (i.e. -Infinity->DirectedInfinity[-1])
	 * 
	 */
	public boolean isNegativeInfinity();

	/**
	 * Test if this expression is the function Cos[<arg>]
	 * 
	 */
	public boolean isCos();

	/**
	 * Test if this expression is the function Cosh[<arg>]
	 * 
	 */
	public boolean isCosh();

	/**
	 * Test if this expression equals the symbol "False"
	 * 
	 */
	public boolean isFalse();

	/**
	 * Test if this expression is a fractional number, but no integer number.
	 * 
	 */
	public boolean isFraction();

	/**
	 * Returns true, if all of the elements in the subexpressions or the expression itself, did not match the
	 * given pattern.
	 * 
	 * @param pattern
	 *            a pattern-matching expression
	 * @param heads
	 *            if set to false, only the arguments of an IAST should be tested and not the Head[]
	 *            element.
	 * 
	 */
	public boolean isFree(IExpr pattern, boolean heads);

	/**
	 * Returns true, if all of the elements in the subexpressions or the expression itself, did not satisfy the
	 * given unary predicate.
	 * 
	 * @param predicate
	 *            a unary predicate
	 * @param heads
	 *            if set to false, only the arguments of an IAST should be tested and not the Head[]
	 *            element.
	 * 
	 */
	public boolean isFree(Predicate predicate, boolean heads);

	/**
	 * Returns true, if at least one of the elements in the subexpressions or the expression itself, match the
	 * given pattern.
	 * 
	 * 
	 * @param pattern
	 *            a pattern-matching expression
	 * @param heads
	 *            if set to false, only the arguments of an IAST should be tested and not the Head[]
	 *            element.
	 * 
	 */
	public boolean isMember(IExpr pattern, boolean heads);

	/**
	 * Returns true, if at least one of the elements in the subexpressions or the expression itself, satisfy the
	 * given unary predicate.
	 * 
	 * @param predicate
	 *            a unary predicate
	 * @param heads
	 *            if set to false, only the arguments of an IAST should be tested and not the Head[]
	 *            element.
	 * 
	 */
	public boolean isMember(Predicate predicate, boolean heads);

	/**
	 * Test if this expression is a Funtion[ arg1 ] expression with at least 1 argument.
	 * 
	 */
	public boolean isFunction();

	/**
	 * Compares this expression with the specified expression for order. Returns true if this expression is canonical greater than
	 * or equal to the specified expression (<= relation).
	 * 
	 * @param expr
	 *            an expression to compare with
	 * @return true if this expression is canonical greater than or equal to the specified expression.
	 */
	public boolean isGEOrdered(IExpr obj);

	/**
	 * Compares this expression with the specified expression for order. Returns true if this expression is canonical greater than
	 * the specified expression (< relation).
	 * 
	 * @param expr
	 *            an expression to compare with
	 * @return true if this expression is canonical greater than the specified expression.
	 */
	public boolean isGTOrdered(IExpr expr);

	/**
	 * Test if this expression is a integer number
	 * 
	 */
	public boolean isInteger();

	/**
	 * Check if this expression represents an int value. The value of an INum object can be an
	 * int value.
	 * 
	 * @return
	 */
	public boolean isNumIntValue();

	/**
	 * Check if this expression equals an IInteger value. The value of an INum or the value of an
	 * IInteger object can be an IInteger value.
	 * 
	 * @return
	 */
	public boolean isNumEqualInteger(IInteger ii) throws ArithmeticException;

	/**
	 * Compares this expression with the specified expression for order. Returns true if this expression is canonical less than or
	 * equal to the specified expression (<= relation).
	 * 
	 * @param expr
	 *            an expression to compare with
	 * @return true if this expression is canonical less than or equal to the specified expression.
	 */
	public boolean isLEOrdered(IExpr obj);

	/**
	 * Test if this expression is a list (i.e. an AST with head List)
	 * 
	 */
	public boolean isList();

	/**
	 * Test if this expression is a sequence (i.e. an AST with head Sequence)
	 * 
	 */
	public boolean isSequence();

	/**
	 * Test if this expression is a list of lists
	 * 
	 * @see #isList()
	 * @see #isMatrix()
	 * @see #isVector()
	 */
	public boolean isListOfLists();

	/**
	 * Test if this expression is the function Log[<arg>]
	 * 
	 */
	public boolean isLog();

	/**
	 * Compares this expression with the specified expression for order. Returns true if this expression is canonical less than the
	 * specified expression (< relation).
	 * 
	 * @param expr
	 *            an expression to compare with
	 * @return true if this expression is canonical less than the specified expression.
	 */
	public boolean isLTOrdered(IExpr expr);

	/**
	 * Test if this expression is a matrix and return the dimensions as array [row-dimension, column-dimension]. This expression is
	 * only a matrix, if all elements are lists with the header List and have the same size.
	 * 
	 * @return null if the expression is not a matrix
	 */
	public int[] isMatrix();

	/**
	 * Test if this expression is the function Not[<arg>]
	 * 
	 */
	public boolean isNot();

	/**
	 * Test if this expression is a number
	 * 
	 */
	public boolean isNumber();

	/**
	 * Test if this expression equals 1 in symbolic or numeric mode.
	 * 
	 */
	public boolean isOne();

	/**
	 * Test if this expression is the function Or[<arg>,...]
	 * 
	 */
	public boolean isOr();

	/**
	 * Test if this expression equals -1 in symbolic or numeric mode.
	 * 
	 */
	public boolean isMinusOne();

	/**
	 * Test if this expression is the addition function Plus[<arg1>, <arg2>, ...]
	 * 
	 */
	public boolean isPlus();

	/**
	 * Test if this expression is a pattern object
	 * 
	 */
	public boolean isPattern();

	/**
	 * Test if this expression or a subexpression is a pattern object. Used in pattern-matching; checks flags in IAST
	 * with flag IAST.CONTAINS_PATTERN_EXPR.
	 * 
	 */
	public boolean isPatternExpr();

	/**
	 * Test if this expression is a pattern sequence object
	 * 
	 */
	public boolean isPatternSequence();

	/**
	 * Test if this object is a positive signed number.
	 * 
	 * @return true, if this > 0; false in all other case.
	 */
	public boolean isPositive();

	/**
	 * Test if this expression is the Condition function Condition[<arg1>, <arg2>]
	 * 
	 */
	public boolean isCondition();

	/**
	 * Test if this expression is the Module function Module[<arg1>, <arg2>]
	 * 
	 */
	public boolean isModule();

	/**
	 * Test if this expression is the function Power[<arg1>, <arg2>]
	 * 
	 */
	public boolean isPower();

	/**
	 * Test if this expression is a rational number, i.e. integer or fraction number.
	 * 
	 */
	public boolean isRational();

	/**
	 * Test if this expression is of the form Rule[<arg1>, <arg2>] or
	 * RuleDelayed[<arg1>, <arg2>].
	 * 
	 */
	public boolean isRuleAST();

	/**
	 * Test if this expression equals the given expression. If the compared expressions are of the same numeric type, they are equal
	 * to a given EPSILON
	 * 
	 */
	public boolean isSame(IExpr expression);

	/**
	 * Test if this expression equals the given expression. If the compared expressions are of the same numeric type, they are equal
	 * to a given EPSILON
	 * 
	 */
	public boolean isSame(IExpr expression, double epsilon);

	/**
	 * Test if this expression is a signed number
	 * 
	 */
	public boolean isSignedNumber();

	/**
	 * Test if this expression is a numeric number (i.e. of type INum or IComplexNum.
	 * 
	 */
	public boolean isNumeric();

	/**
	 * Test if this expression is a numeric function (i.e. a number, a symbolic constant or a function (with attribute
	 * NumericFunction) where all arguments are also "numeric functions")
	 * 
	 * @return true, if the given expression is a numeric function or value.
	 * @see #isRealFunction
	 */
	public boolean isNumericFunction();

	/**
	 * Test if this expression is a real (non-complex) value (i.e. a real number or a real symbolic constant or a
	 * Plus, Times expression with only real values)
	 * 
	 * @return true, if the given expression is a real (non-complex) value.
	 * @see #isConstant
	 * @see #isNumericFunction
	 */
	public boolean isRealFunction();

	/**
	 * Test if this expression is the function Sin[<arg>]
	 * 
	 */
	public boolean isSin();

	/**
	 * Test if this expression is the function Sinh[<arg>]
	 * 
	 */
	public boolean isSinh();

	/**
	 * Test if this expression is the function Slot[<integer-value>]
	 * 
	 */
	public boolean isSlot();

	/**
	 * Test if this expression is the function SlotSequence[<integer-value>]
	 * 
	 */
	public boolean isSlotSequence();

	/**
	 * Test if this expression is a symbol
	 * 
	 */
	public boolean isSymbol();

	/**
	 * Test if this expression is the function TAn[<arg>]
	 * 
	 */
	public boolean isTan();

	/**
	 * Test if this expression is the function Tanh[<arg>]
	 * 
	 */
	public boolean isTanh();

	/**
	 * Test if this expression is the multiplication function Times[<arg1>, <arg2>, ...]
	 * 
	 */
	public boolean isTimes();

	/**
	 * Test if this expression equals the symbol "True"
	 * 
	 */
	public boolean isTrue();

	/**
	 * Returns true, if this symbol or ast expression is bound to a value (i.e. the evaluation returns an
	 * assigned value).
	 * 
	 */
	public boolean isValue();

	/**
	 * Test if this expression is a vector and return the dimension of the vector. This expression is only a vector, if the
	 * expression is a List(...) and no element is itself a List(...).
	 * 
	 * @return -1 if the expression is no vector or size()-1 of the corresponding IAST.
	 */
	public int isVector();

	/**
	 * Test if this expression equals 0 in symbolic or numeric mode.
	 * 
	 */
	public boolean isZero();

	/**
	 * @return a list of the the leaf expressions. Instances of ExprImpl should return null, while any other expression may not
	 *         return null (but can return an empty list).
	 */
	public List leaves();

	public IExpr minus(final IExpr that);

	public IExpr mod(final IExpr that);

	@Override
	public IExpr multiply(final IExpr that);

	//
	// Groovy operator overloading
	//
	public IExpr negative();

	public IExpr or(final IExpr that);

	public IExpr plus(final IExpr that);

	public IExpr power(final IExpr that);

	public IExpr power(final Integer n);

	/**
	 * Replace all (sub-) expressions with the given unary function. If no substitution matches, the method returns
	 * null.
	 * 
	 * @param function
	 *            if the unary functions apply() method returns null the expression isn't substituted.
	 * @return null if no substitution of a (sub-)expression was possible.
	 */
	@Nullable
	public IExpr replaceAll(final Function function);

	/**
	 * Replace all (sub-) expressions with the given rule set. If no substitution matches, the method returns null.
	 * 
	 * @param astRules
	 *            rules of the form x->y or {a->b, c->d}; the left-hand-side of the rule can
	 *            contain pattern objects.
	 * @return null if no substitution of a (sub-)expression was possible.
	 */
	@Nullable
	public IExpr replaceAll(final IAST astRules);

	public IExpr replacePart(final IAST astRules);

	/**
	 * Repeatedly replace all (sub-) expressions with the given unary function. If no substitution matches, the method returns
	 * this.
	 * 
	 * @param function
	 *            if the unary functions apply() method returns null the expression isn't substituted.
	 * @return this if no substitution of a (sub-)expression was possible.
	 */
	public IExpr replaceRepeated(final Function function);

	/**
	 * Repeatedly replace all (sub-) expressions with the given rule set. If no substitution matches, the method returns
	 * this.
	 * 
	 * @param astRules
	 *            rules of the form x->y or {a->b, c->d}; the left-hand-side of the rule can
	 *            contain pattern objects.
	 * @return this if no substitution of a (sub-)expression was possible.
	 */
	public IExpr replaceRepeated(final IAST astRules);

	public IExpr replaceSlots(final IAST astSlots);

	/**
	 * Signum functionality is used in JAS toString() method, don't use it as math signum function.
	 * 
	 * @deprecated
	 */
	@Deprecated
	@Override
	public int signum();

	/**
	 * Returns the product of this object with the one specified.
	 * 
	 * @param that
	 *            the object multiplier.
	 * @return this ยท that.
	 */
	IExpr times(IExpr that);

	/**
	 * @return the 'highest level' head of the expression, before Symbol, Integer, Real or String. for example while the head of
	 *         a[b][c] is a[b], the top head is a.
	 */
	public ISymbol topHead();

	/**
	 * Convert the variables (i.e. ISymbol's with lower case character in the 0-th position of their name) in this expression into
	 * Slot[] s.
	 * 
	 * @return null if the expression contains a variable with a '$' character in the 0-th position of its name and the
	 *         math engine runs in server mode.
	 */
	public IExpr variables2Slots(Map map, List variableList);
}

 

Ads help maintain this website.