Package jmathexpr.arithmetic.equation

Source Code of jmathexpr.arithmetic.equation.Equation

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

import java.util.ArrayList;
import java.util.List;

import jmathexpr.Expression;
import jmathexpr.Variable;
import jmathexpr.arithmetic.ANumber;
import jmathexpr.bool.TruthValue;
import jmathexpr.arithmetic.equation.rule.RuleMachine;
import jmathexpr.arithmetic.func.UnivariateNumberFunction;
import jmathexpr.arithmetic.op.Multiplication;
import jmathexpr.arithmetic.op.Negation;
import jmathexpr.arithmetic.op.Subtraction;
import jmathexpr.relation.Equality;
import jmathexpr.set.EmptySet;
import jmathexpr.set.FiniteSet;
import jmathexpr.set.Set;
import jmathexpr.util.context.ExpressionContext;
import jmathexpr.util.context.Statement;
import jmathexpr.util.context.Statement.Command;

/**
* Equation in one unknown. This class is immutable.
*
* @author Elemér Furka
*/
public abstract class Equation extends Equality {
   
    /**
     * The rule machine used to solve this equation.
     */
    protected RuleMachine rules;
   
    /**
     * The variable this equation can be solved for.
     */
    protected final Variable x;
   
    /**
     * Creates a new radical equation specifying the two sides of the equality.
     *
     * @param lhs left hand side of the equality
     * @param rhs right hand side of the equality
     * @param x the indeterminate in the equation
     */
    protected Equation(Expression lhs, Expression rhs, Variable x) {
        super(lhs, rhs);
       
        this.x = x;
    }

    /**
     * Creates a new equation instance using an existing equality.
     *
     * @param equality the equality to be transformed into an equation
     * @param x the indeterminate in the equation
     */
    protected Equation(Equality equality, Variable x) {
        this(equality.lhs(), equality.rhs(), x);
    }

    /**
     * Solves this equation step by step. The steps are stored internally.
     *
     * @return a set of zero or one or infinite number of elements: the solutions of this equation
     * @throws EquationSolveException if the equation cannot be solved
     */
    public abstract Set solve() throws EquationSolveException;

    @Override
    public Expression evaluate() {
        Expression evaluated = super.evaluate();
       
        if (evaluated instanceof TruthValue) {
            return evaluated;
        } else {
            Expression reduced =
                    new Subtraction(((Equality) evaluated).lhs(), ((Equality) evaluated).rhs()).evaluate();
            TruthValue isZero = isZero(reduced);
           
            if (isZero != null) {
                return isZero;
            }
        }
       
        return evaluated;
    }
   
    private static TruthValue isZero(Expression expr) {
        if (expr instanceof ANumber) {
            return TruthValue.valueOf(((ANumber) expr).isZero());
        } else if (expr instanceof Multiplication) {
            TruthValue leftIsZero = isZero(((Multiplication) expr).lhs());
            TruthValue rightIsZero = isZero(((Multiplication) expr).rhs());
           
            if (leftIsZero == TruthValue.True) {
                return TruthValue.True;
            } else if (rightIsZero == TruthValue.True) {
                return TruthValue.True;
            } else if (leftIsZero == TruthValue.False && rightIsZero == TruthValue.False) {
                return TruthValue.False;
            }
        } else if (expr instanceof Negation) {
            return isZero(((Negation) expr).getChild());
        } else if (expr instanceof UnivariateNumberFunction) {
            return TruthValue.False;
        }
       
        return null;
    }
   
    /**
     * Converts the equality into an appropriate equation.
     *
     * @param eq an equality
     * @param x a variable
     * @return the equality converted into an equation
     */
    public static Equation convert(Equality eq, Variable x) {
        if (AbsoluteValueEquation.isA(eq, x)) {
            return new AbsoluteValueEquation(eq, x);
        } else if (RadicalEquation.isA(eq, x)) {
            return new RadicalEquation(eq, x);
        } else if (QuadraticEquation.isConvertible(eq, x)) {
            return new QuadraticEquation(eq, x);
        } else {
            return new LinearEquation(eq, x);
        }
    }

    /**
     * Returns the variable this equation is solved for.
     *
     * @return this equation's variable
     */
    public Variable variable() {
        return x;
    }

    @Override
    public Set domain() {
        return x.domain();
    }
   
    protected Set check(Set result) {
        List<Expression> checked = new ArrayList();
       
        if (result instanceof FiniteSet) {
            for (Expression e : ((FiniteSet) result)) {
                if (satisfies(e)) {
                    checked.add(e);
                }
            }
           
            return new FiniteSet(checked);
        } else if (result instanceof EmptySet) {
            return result;
        } else {
            throw new IllegalStateException("Set type not yet supported: " + result);
        }
    }
   
    private boolean satisfies(Expression expr) {
        try {
            x.setValue(expr);

            Expression evaluated = evaluate();

            if (evaluated instanceof TruthValue) {
                boolean satisfied = ((TruthValue) evaluated).toBoolean();
               
                System.out.printf("    check: %s at %s = %s: %s%n",
                        this, x.name(), expr, satisfied);
                if (!satisfied) {
                    Equality eq = new Equality(lhs.evaluate(), rhs.evaluate());
                   
                    ExpressionContext.getInstance().addStatement(
                            new Statement(Command.Expression, eq));
                }
               
                return satisfied;
            } else {
                Equality eq = (Equality) evaluated;
                throw new IllegalStateException(String.format(
                        "Cannot check equality: %s = %s (%s %s), %s = %s ",
                        eq.lhs(), eq.rhs(), eq.lhs().getClass().getSimpleName(), eq.rhs().getClass().getSimpleName(), x.name(), expr));
            }
        } finally {
            x.reset();
        }
    }
}
TOP

Related Classes of jmathexpr.arithmetic.equation.Equation

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.