MC logo

CS 231 Assignment 3


CS 231 Programming Assignments

CSC 231

Assignment 3
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.