Note: partnering is not permitted.
clisp exercise-N.lsp >! exercise-N.test
You can submit the report to your instructor in class or to the assignment boxes accessible outside the main Computer Science office.
submit 3401 r2 report2
While you can develop your functions on your personal computer, be sure your file will load correctly and all your functions execute properly on Prism.
solver()which solves arithmetic equations containing a single variable, occuring once in the left-hand side of an equation. The variable is represented in a Lisp expression as a list of one element -- for example, (zz).
Write solver as a tail-recursive function that uses the READ function to read in and solve an equation entered at the terminal, prints the solution (if there is one), and repeats until the input is NIL.An equation is to be represented as a pair of arithmetic expressions expressed in Lisp. For example, the equation
2*sqrt(x)/7 = 53is represented by
((/ (* 2 (SQRT (x))) 7) (EXPT 5 3))solver should at least validate that the input has the form of a list of two lists, before trying to solve the equation. How you handle the case in which the input is not an equation or is unsolvable is up to you. Make sure you document this in your report.
The solver function successively transforms an equation by eliminating arithmetic operators on the left side while building up the right side of the equation until the equation has the form:
(variable expression).If the expression is purely numeric, it should be evaluated to give the solution (variable value), i. e. variable = value. For example, solver should successively transform ((/ (* 2 (SQRT (x)) 7) (EXPT 5 3)) to:
--> ((* 2 (SQRT (x))) (* (EXPT 5 3) 7)) --> ((SQRT (x))) (/ (* (EXPT 5 3) 7) 2)) --> ((x) (EXPT (/ (* 7 (EXPT 5 3)) 2) 2))which evaluates to ((x) 765625/4). Your function should be able to handle the following arithmetic operations in the left-hand side of the equation:
(Log functions come in different flavours - natural, base 10, etc. It's up to you to decide how you want to handle this - just make sure it's documented in your report.)
(- x y)) *
You are free to use LET-scopes, LAMBDA-blocks and additional support functions to simplify your code. Built-in functions which may be useful are
((+ a (zz)) (/ (+ 2 3) q))has the solution
((zz) (- (/ 5 q) a))
A term in a multinomial consists of a coefficient and zero or more variables, each with an exponent. (In ordinary mathematical notation, coefficients and exponents which are 0 or 1 are not shown.) To represent a term in Lisp, we can use the following format:
1 - xy2 + 3z.
coefficientis a numeric or algebraic expression (but does not contain any variables), and
factorsis a (possibly empty) list of factors, each of which are in the form
The variableis an atom whose name begins with a letter and the
exponentis a numeric or algebraic expression. Thus the term
would be represented by the Lisp expression:
As in ordinary mathematical notation, the multiplication operation in a term is not explicitly represented.
((+ a 3) ((x (* 2 n)) (z 1)))
A constant term has no variables--it would be represented by
A multinomial is a list of terms interpreted as a sum. To simplify matters, we express a difference between terms as a sum using a negative coefficient. Thus
ax - b is represented as
((a (x 1)) ((- b) ())).
term-multwhich multiplies a multinomial by a term. For example, in ordinary notation, the product of
(ax2 + ya + 1)
2ax3y + 2xy(a+1) + 2xy.
Your function is to produce a Lisp presentation of the product multinomial, given Lisp representations of a term and multinomial as arguments.
Suggestion: sort the factor lists in each argument to make it easier to detect if there is a common variable whose exponents need to be summed. See page 93 in the text for details on comparing atoms by name.
multi-multwhich multiplies two multinomials, and collects like terms (like terms have identical factor lists and the coefficents should be added.)
DEFUNform since it doesn't match the way the function being defined is actually called. Define a macro
deffunwhich uses the back-quote, comma and splice operators to transform
(function-name arg1 . . . argn) body
(DEFUN function-name (arg1 . . . argn) body)
deffun, the symbol
&RESTwill be useful. See "Macro Examples" for an example. (Chapter 5 of Peter Seibel's Practical Common Lisp is also recommended reading.)
MACROEXPANDto give an example of what a call to the
deffunmacro expands to, and use
DESCRIBEto show that
deffundoes what it is supposed to do.