Package jmathexpr.relation

Source Code of jmathexpr.relation.BinaryRelation

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

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

import jmathexpr.AbstractExpression;
import jmathexpr.Expression;
import jmathexpr.set.Set;
import jmathexpr.set.op.CartesianProduct;
import jmathexpr.util.pattern.ExpressionPattern;
import jmathexpr.util.rule.Rule;

/**
* This class represents a binary relation R that connects two expressions l and
* r. Binary relations are used in their infix form l R r. Example l = r for equality.
*
* @author Elemér Furka
* @param <L> the left hand side expression
* @param <R> the right hand side expression
*/
public abstract class BinaryRelation<L extends Expression, R extends Expression>
        extends AbstractExpression implements ExpressionPattern {
   
    protected final L lhs;
   
    protected final R rhs;
   
    protected final RelationSymbol symbol;
   
    protected BinaryRelation(L lhs, R rhs, RelationSymbol symbol) {
        this.lhs = lhs;
        this.rhs = rhs;
        this.symbol = symbol;
    }
   
    /**
     * Tests whether this binary relation R is symmetric.
     *
     * @return true iff for every (a, b): aRb -> bRa
     */
    public abstract boolean isSymmetric();
   
    protected abstract BinaryRelation create(Expression lhs, Expression rhs);
   
    public L lhs() {
        return lhs;
    }
   
    public R rhs() {
        return rhs;
    }
   
    @Override
    public boolean equals(Object object) {
        if (object == null) return false;
        if (this == object) return true;
        if (object instanceof BinaryRelation && getClass().equals(object.getClass())) {
            BinaryRelation other = (BinaryRelation) object;
           
            if (symbol != other.symbol) return false;
           
            return lhs.equals(other.lhs) && rhs.equals(other.rhs);
        }
       
        return false;
    }

    @Override
    public Set domain() {
        return new CartesianProduct(lhs.domain(), rhs.domain());
    }

    @Override
    public Set codomain() {
        if (lhs.codomain().equals(rhs.codomain())) {
            return lhs.codomain();
        } else {
            throw new IllegalStateException("Missing operation: " + this);
        }
    }

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

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 67 * hash + Objects.hashCode(this.lhs);
        hash = 67 * hash + Objects.hashCode(this.rhs);
        hash = 67 * hash + Objects.hashCode(this.symbol);
        return hash;
    }
   
    @Override
    public String toString() {
        return toString(lhs.toString(), symbol.toString(), rhs.toString());
    }
   
    @Override
    public String toUnicode() {
        return toString(lhs.toUnicode(), symbol.toUnicode(), rhs.toUnicode());
    }
   
    @Override
    public String toAsciiMath() {
        return toString(lhs.toAsciiMath(), symbol.toAsciiMath(), rhs.toAsciiMath());
    }
   
    private static String toString(String lhs, String symbol, String rhs) {
        return String.format("%s %s %s", lhs, symbol, rhs);
    }

    @Override
    public boolean isConstant() {
        return lhs.isConstant() && rhs.isConstant();
    }
   
    @Override
    public boolean contains(ExpressionPattern pattern) {
        if (getClass().isAssignableFrom(pattern.getClass())) {
            BinaryRelation p = (BinaryRelation) 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;
                l = rule.subapply();
            }
            if (rhs.isApplicable(rule)) {
                isApplicable = true;
                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 (getClass().isAssignableFrom(expr.getClass())) {
            BinaryRelation other = (BinaryRelation) expr;
           
            if (((ExpressionPattern) lhs).matches(other.lhs)
                    && ((ExpressionPattern) rhs).matches(other.rhs)) {
                return true;
            } else if (isSymmetric()) {
                return ((ExpressionPattern) lhs).matches(other.rhs)
                    && ((ExpressionPattern) rhs).matches(other.lhs);
            }
        }
       
        return false;
    }
}
TOP

Related Classes of jmathexpr.relation.BinaryRelation

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.