All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.lsmp.djep.xjep.XOperator Maven / Gradle / Ivy

Go to download

JEP is a Java library for parsing and evaluating mathematical expressions.

There is a newer version: 2.4.2
Show newest version
/* @author rich
 * Created on 03-Aug-2003
 */
package org.lsmp.djep.xjep;

import org.nfunk.jep.function.PostfixMathCommandI;
import org.nfunk.jep.*;

/**
 * An Operator with additional information about its commutativity etc.
 * 

* Operators have a number of properties: *

    *
  • A symbol or name of the operator "+". *
  • The number of arguments NO_ARGS 0, UNARY 1 (eg UMINUS -x), * BINARY 2 (eq x+y), and NARY either 3 ( a>b ? a : b) or * unspecified like a list [x,y,z,w]. *
  • The binging of the operator, LEFT 1+2+3 -> (1+2)+3 or RIGHT 1=2=3 -> 1=(2=3). *
  • Whether the operator is ASSOCIATIVE or COMMUTATIVE. *
  • The precedence of the operators + has a higher precedence than *. *
  • For unary opperators they can either be PREFIX like -x or SUFIX like x%. *
  • Comparative operators can be REFLEXIVE, SYMMETRIC, TRANSITIVE or EQUIVILENCE which has all three properties. *
  • A reference to a PostfixtMathCommandI object which is used to evaluate an equation containing the operator. *
* various is... and get... methods are provided to query the properties of the opperator. * * @author Rich Morris * Created on 19-Oct-2003 */ public class XOperator extends Operator { /** No arguments to operator */ public static final int NO_ARGS=0; /** Unary operators, such as -x !x ~x */ public static final int UNARY=1; /** Binary operators, such as x+y, x>y */ public static final int BINARY=2; /** Trinary ops such as ?: and or higher like [x,y,z,w] */ public static final int NARY=3; /** Left binding like +: 1+2+3 -> (1+2)+3 */ public static final int LEFT=4; /** Right binding like =: 1=2=3 -> 1=(2=3) */ public static final int RIGHT=8; /** Associative operators x*(y*z) == (x*y)*z . */ public static final int ASSOCIATIVE=16; /** Commutative operators x*y = y*x. */ public static final int COMMUTATIVE=32; /** Reflecive relations x=x for all x. */ public static final int REFLEXIVE=64; /** Symmetric relation x=y implies y=x. */ public static final int SYMMETRIC=128; /** Transative relations x=y and y=z implies x=z */ public static final int TRANSITIVE=256; /** Equivilence relations = reflexive, transative and symetric. */ public static final int EQUIVILENCE=TRANSITIVE+REFLEXIVE+SYMMETRIC; /** prefix operators -x **/ public static final int PREFIX=512; /** postfix operators x%, if neiter prefix and postif then infix, if both trifix like x?y:z **/ public static final int SUFIX=1024; /** self inverse operators like -(-x) !(!x) **/ public static final int SELF_INVERSE=2048; /** composite operators, like a-b which is a+(-b) **/ public static final int COMPOSITE=4096; /** For non commutative operators printing can be determined by the left or right binding. * For example (a-b)-c is printed as a-b-c. * But a/b/c could be ambiguous so (a/b)/c is printed with brackets. */ public static final int USE_BINDING_FOR_PRINT=8192; /** flags for type of operator */ private int flags; /** construct a new operator. * * @param name printable name of operator * @param pfmc postfix math command for opperator * @param flags set of flags defining the porperties of the operator. */ public XOperator(String name,PostfixMathCommandI pfmc,int flags) { super(name,pfmc); this.flags = flags; } /** * Allows a given precedent to be set. * @param name * @param pfmc * @param flags * @param precedence */ public XOperator(String name,PostfixMathCommandI pfmc,int flags,int precedence) { this(name,pfmc,flags); this.precedence=precedence; } /** construct a new operator, with a different name and symbol * * @param name name of operator, must be unique, used when describing operator * @param symbol printable name of operator, used for printing equations * @param pfmc postfix math command for opperator * @param flags set of flags defining the porperties of the operator. */ public XOperator(String name,String symbol,PostfixMathCommandI pfmc,int flags) { super(name,symbol,pfmc); this.flags = flags; } /** * Allows a given precedent to be set. * @param name * @param pfmc * @param flags * @param precedence */ public XOperator(String name,String symbol,PostfixMathCommandI pfmc,int flags,int precedence) { super(name,symbol,pfmc); this.precedence=precedence; this.flags=flags; } public XOperator(Operator op,int flags,int precedence) { this(op.getName(),op.getSymbol(),op.getPFMC(),flags,precedence); } public XOperator(Operator op,int flags) { this(op.getName(),op.getSymbol(),op.getPFMC(),flags); } /** Creates a new XOperators with same flags and precedance as argument. */ // public XOperator(XOperator op,PostfixMathCommandI pfmc) // { // this(op.getName(),op.getSymbol(),op.getPFMC(),op.flags,op.precedence); // } /** precedence of operator, 0 is most tightly bound, so prec("*") < prec("+"). */ private int precedence = -1; public final int getPrecedence() {return precedence;} protected final void setPrecedence(int i) {precedence = i;} /** Operators this is distributative over **/ private Operator distribOver[] = new Operator[0]; protected final void setDistributiveOver(Operator op) { int len = distribOver.length; Operator temp[] = new Operator[len+1]; for(int i=0;i (x+y)+z or * Operator.RIGHT x=y=z -> x=(y=z). */ public final int getBinding() { return (flags & (LEFT | RIGHT)); } public final boolean isAssociative() {return ((flags & ASSOCIATIVE) == ASSOCIATIVE);} public final boolean isCommutative() { return ((flags & COMMUTATIVE) == COMMUTATIVE);} public final boolean isBinary() { return ((flags & 3) == BINARY); } public final boolean isUnary() { return ((flags & 3) == UNARY); } public final boolean isNary() { return ((flags & 3) == NARY); } public final int numArgs() { return (flags & 3); } public final boolean isTransitive() { return ((flags & TRANSITIVE) == TRANSITIVE); } public final boolean isSymmetric() { return ((flags & SYMMETRIC) == SYMMETRIC); } public final boolean isReflexive() { return ((flags & REFLEXIVE) == REFLEXIVE); } public final boolean isEquivilence() {return ((flags & EQUIVILENCE) == EQUIVILENCE); } public final boolean isPrefix() {return ((flags & PREFIX) == PREFIX); } public final boolean isSufix() {return ((flags & SUFIX) == SUFIX); } public final boolean isComposite() {return ((flags & COMPOSITE) == COMPOSITE); } public final boolean isSelfInverse() {return ((flags & SELF_INVERSE) == SELF_INVERSE); } public final boolean useBindingForPrint() {return ((flags & USE_BINDING_FOR_PRINT) == USE_BINDING_FOR_PRINT); } /** returns a verbose representation of the operator and all its properties. **/ public String toFullString() { StringBuffer sb = new StringBuffer(); sb.append("Operator: \""+getSymbol()+"\""); if(!getName().equals(getSymbol())) sb.append(" "+getName()); switch(numArgs()){ case 0: sb.append(" no arguments,"); break; case 1: sb.append(" unary,"); break; case 2: sb.append(" binary,"); break; case 3: sb.append(" variable number of arguments,"); break; } if(isPrefix() && isSufix()) sb.append(" trifix,"); else if(isPrefix()) sb.append(" prefix,"); else if(isSufix()) sb.append(" sufix,"); else sb.append(" infix,"); if(getBinding()==LEFT) sb.append(" left binding,"); else if(getBinding()==RIGHT) sb.append(" right binding,"); if(isAssociative()) sb.append(" associative,"); if(isCommutative()) sb.append(" commutative,"); sb.append(" precedence "+getPrecedence()+","); if(isEquivilence()) sb.append(" equivilence relation,"); else { if(isReflexive()) sb.append(" reflexive,"); if(isSymmetric()) sb.append(" symmetric,"); if(isTransitive()) sb.append(" transitive,"); } sb.setCharAt(sb.length()-1,'.'); return sb.toString(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy