Extend the expression simplification presented in class. You are to add the following two simplifications.
First, you must
combine all the constants in an
expression into a single constant by applying the
proper operation. This final constant should be placed in
the front of the list. The other parts of the expression
should remain unchanged and in their same relative position.
(+ y 5 x 2 10)
(+ 17 y x).
(* 4 3 a (+ 3 y) 2) becomes
(* 24 a (+ 3 y)). Note that a single constant
is moved to the front of the list:
(+ x 3 y) becomes
(+ 3 x y).
Apply this transformation from
simpl after running flatten.
Since you must
apply it to both sums and products, you will have to add
an argument to
simpl to which you will pass
either the function
'*. You can use this
reduce to do the needed arithmetic.
Note that when we combine all the constants, we are not
including constants which are not at the top level.
For instance, in
(+ 5 (* 4 x) 6), we combine 5 and 6, but
not the 4. The 4 is part of a multiplication, so it is not
considered a "constant" for this purpose. Hence,
the simplification produces
(+ 11 (* 4 x)). Within subexpressions,
constants will be combined
by the recursion that already exists in
within sums, combine identical sub-expressions (other than
Leave the multiplication in place of the first of the repeated items.
(+ 3 x (* 2 z) y 3 x x t)
(+ 3 (* 3 x) (* 2 z) y 3 t).
When the transform creates a multiplication, it
flatten on it, then call the constant combiner mentioned above.
(+ (* 2 x) y y (* 2 x) z (* 2 x))
(+ (* 6 x) (* 2 y) z).
You must use the functions
reduce at least once each.
The constant combination can be written without recursion. Use
remove-if to separate the make one lists of constants and one list of
other arguments. Use
reduce to combine the list of constants, then
cons the result back on the front of the other list.
The second one is a bit longer. I created a function called
collect-like-first which takes a list of arguments and
searches for any members which match the first one.
If it finds none, it simply returns the original list.
Otherwise, it uses
remove-if to eliminate the duplicates,
then adds the multiplication and calls
I then built a second function that uses a simple recursion to
collect-like-first on the each
member of the list. I made my recursive call with the
cdr of the list returned from
Both of these transforms will be called from
Simpl must be modified to call the second one only in case when
processing an add. This may require an additional parameter, and will
certainly make it less elegant.
Submit the modified simplification file. I will test it by loading the differential file first, then the file you send me, then running test expressions. Submit your program using the form here.