Due: October 27, Midnight

70 Pts.

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.
For instance,
the expression
`(+ y 5 x 2 10)`

becomes
`(+ 17 y x)`

.
Likewise, `(* 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 `'+`

or `'*`

. You can use this
with `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 `simpl`

.

Secondly,
within sums, combine identical sub-expressions (other than
constants) into
a multiplication.
Leave the multiplication in place of the first of the repeated items.
For instance, `(+ 3 x (* 2 z) y 3 x x t)`

becomes `(+ 3 (* 3 x) (* 2 z) y 3 t)`

.
When the transform creates a multiplication, it
should run `flatten`

on it, then call the constant combiner mentioned above.
So, `(+ (* 2 x) y y (* 2 x) z (* 2 x))`

becomes `(+ (* 6 x) (* 2 y) z)`

.

**Requirement**

You must use the functions `remove-if`

and `reduce`

at least once each.

**Comments**

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 `flatten`

and `const-combine`

.

I then built a second function that uses a simple recursion to
repeatedly run `collect-like-first`

on the each
member of the list. I made my recursive call with the
`cdr`

of the list returned from `collect-like-first`

.

Both of these transforms will be called from `simpl`

.
`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.

**Submission**

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.