In this assignment you will add the class Negate
to the collection of classes
that implement the Expression
interface. It should
represent unary minus, which negates the Expression
referenced by
the single instance variable in the Negate
class. That is, its eval
method should call eval
on its expression (its unary operand) and
then return the negation
of the result. If the operand evaluates to 6, eval
should return -6.
If the operand evaluates to -5, eval
should return 5. Also,
the derivative of a Negate
will be the Negate
of
the derivative of its expression.
A unary minus
will let us represent expressions like "-x". Currently the only way to
express this would be "0-x" using the binary subtraction operation. With the
Negate
class
we could represent it by the Expression
created by calling
Negate.make(Variable.define("x"))
.
You need to modify and add to my code, all of which you can get
by downloading sa8src.zip
.
Negate
should implement the two required methods
(in the Expression
interface), along with
toString
and make
. Its constructor should be private,
like the Constructors of the classes that I provided.
After you get Negate
working you should modify the
make
methods of the other classes to take it into account.
One change that you are required to make is that all constants
be non-negative. For example, Constant.define(-6)
should return a Negate
object whose operand is a
Constant
whose value is 6. There are a number of other
changes that make sense. For instance, would you ever write:
"3 + (-x)" or "-(-x)" or "-x * (-y)" or "-0"? I am not expecting you to
implement every possible simplification, but you should be able to
come up with a half dozen or so simplifications.
You should also add a static method to ExpressionDriver.java
to allow the main program to call negate
rather than Negate.make
. You should not make changes to other classes except in their
make
or define
methods.
In the past this short assignment has caused some confusion. An expression is represented by a tree. This way we can use the expression as an operand in larger expressions and perform operations like taking the derivative of the expression. The tree is build up of objects whose classes implement the Expression
interface. In the code that you are given the nodes of type Expression
have either two children (the four binary operations) or no children (variables and constants).
Negate is a unary operator. It has one operand, unlike binary operators that have two operands. A Negate
object
is therefore a node in an Expression
tree with one child that is another Expression
. The make
method in Negate
should have one parameter that is an Expression
. You normally construct and return a Negate
object with the Expression
saved in its instance variable. In this case you should not modify the parameter at all. However, if the
parameter is a Negate
object you are negating a negated expression, e.g. (-(-x)). The two negations should cancel, so in this example you would want to just return a node representing the variable x. In general you would want to return the operand of the Negate
object that is the parameter.
Test your code by modifying the main
method of ExpressionDriver.java
. Try to create a convincing set of tests.
Submit via Canvas the zip file of a folder that contains all java files (including the ones that you didn't have to modify) and the screenshot (or copied file) of a test run.