Package jmathexpr.op

Source Code of jmathexpr.op.BinaryOperation

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package jmathexpr.op;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

import jmathexpr.AbstractExpression;
import jmathexpr.Expression;
import jmathexpr.util.pattern.ExpressionPattern;
import jmathexpr.util.rule.Rule;

/**
*
* @author Elemér Furka
*
* @param <L> the left hand side operand
* @param <R> the right hand side operand
*/
public abstract class BinaryOperation<L extends Expression, R extends Expression>
        extends AbstractExpression implements Operation, ExpressionPattern {
   
    protected final L lhs;
    protected final R rhs;
   
    protected final Sign sign;
   
    protected BinaryOperation(L lhs, R rhs, Sign sign) {
        if (lhs == null || rhs == null) throw new IllegalArgumentException(
                String.format("new BinaryOperation(%s, %s)", lhs, rhs));
       
        this.lhs = lhs;
        this.rhs = rhs;
       
        this.sign = sign;
    }
   
    protected abstract Operation create(Expression lhs, Expression rhs);
   
    public L lhs() {
        return lhs;
    }
   
    public R rhs () {
        return rhs;
    }

    @Override
    public List<Expression> operands() {
        List<Expression> operands = new ArrayList();
       
        operands.add(lhs);
        operands.add(rhs);
       
        return Collections.unmodifiableList(operands);
    }

    @Override
    public List<Expression> getChildren() {
        return operands();
    }
   
    /**
     * Tests if this binary operation is commutative. A binary operation o is
     * commutative if for all possible operands a and b: a o b = b o a.
     *
     * @return if this operation is commutative
     */
    public abstract boolean isCommutative();
   
    @Override
    public boolean equals(Object object) {
        if (object == null) return false;
        if (this == object) return true;
        if (object instanceof BinaryOperation && getClass().equals(object.getClass())) {
            BinaryOperation other = (BinaryOperation) object;
           
            if (sign != other.sign) return false;
           
            return lhs.equals(other.lhs) && rhs.equals(other.rhs);
        }
       
        return false;
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 37 * hash + Objects.hashCode(this.lhs);
        hash = 37 * hash + Objects.hashCode(this.rhs);
        hash = 37 * hash + Objects.hashCode(this.sign);
        return hash;
    }
   
    @Override
    public String toString() {
        String l = lhs.getPrecedence().le(getPrecedence()) ? String.format("(%s)", lhs)
                : lhs.toString();
        String r = rhs.getPrecedence().le(getPrecedence()) ? String.format("(%s)", rhs)
                : rhs.toString();
       
        return String.format("%s %s %s", l, sign, r);
    }
   
    @Override
    public String toUnicode() {
        return String.format("%s %s %s", lhs, sign.toUnicode(), rhs);
    }

    @Override
    public int getArity() {
        return 2;
    }

    @Override
    public boolean isConstant() {
        return lhs.isConstant() && rhs.isConstant();
    }
   
    @Override
    public boolean contains(ExpressionPattern pattern) {
        if (getClass().isAssignableFrom(pattern.getClass())) {
            BinaryOperation p = (BinaryOperation) pattern;
           
            if (lhs.contains((ExpressionPattern) p.lhs)
                    && rhs.contains((ExpressionPattern) p.rhs)) {
                return true;
            }
        }
       
        return lhs.contains(pattern) || rhs.contains(pattern);
    }
   
    @Override
    public boolean isApplicable(Rule rule) {
        boolean isApplicable = false;
        Expression transformed = this;
       
        if (rule.isRecursive()) {
            Expression l = lhs, r = rhs;
           
            if (lhs.isApplicable(rule)) {
                isApplicable = true;
                if (rule.isRecursive()) l = rule.subapply();
            }
            if (rhs.isApplicable(rule)) {
                isApplicable = true;
                if (rule.isRecursive()) r = rule.subapply();
            }

            transformed = isApplicable ? create(l, r) : this;
        }
       
        if (rule.matches(transformed)) {
            return true;
        } else if (isApplicable) {
            rule.register(transformed);
        }
       
        return isApplicable;
    }

    @Override
    public boolean matches(Expression expr) {
        if (expr.getClass().isAssignableFrom(getClass())) {
            BinaryOperation other = (BinaryOperation) expr;
           
            if (((ExpressionPattern) lhs).matches(other.lhs)
                    && ((ExpressionPattern) rhs).matches(other.rhs)) {
                return true;
            } else if (isCommutative() && ((ExpressionPattern) lhs).matches(other.rhs)
                    && ((ExpressionPattern) rhs).matches(other.lhs)) {
                return true;
            }
        }
       
        return false;
    }
}
TOP

Related Classes of jmathexpr.op.BinaryOperation

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.