**Due Date:** 11:59pm, Tuesday 28/Sept/04, using

try c325 a1 your_fileYou should submit one file containing all your programs along with documentation. Your programs will be run against our solutions and results generated. This may provide feedback to your work. You can keep submitting, and the last one before the deadline will be retained as your submission. Questions on the try command can be directed to

**Assignment Marks:** There are a total of 65 marks possible on
this assignment. It is worth 8% of the total course grade.
Your programs must be readable and understandable as well as correct.
You should read the guidelines as given in programming
style and marking guideline.
You could lose up to 1/2 of the marks for bad style even if your
programs are correct.

**(25/Sept: Changed "penalty for bad style", from 1/3 to 1/2, to be
consistent with other documentation, and TA's earlier comments.)**

**Restrictions:**

You may only use the built-in Lisp functions and special forms shown here

You may write one or more functions to solve any given problem below. In some cases it is desirable to decompose a problem into smaller ones. However, if a problem has a straightforward single-function solution, it's a bad idea to solve it in a complex way by decomposition.

#1 (5 marks) Write the Lisp function

(my-min L)that returns the minimum value of the argument list-of-numbers L.

You may assume L is a list with at least 1 element, which includes only numeric values.

>(my-min '(3 1 -5 2)

-5

>(my-min '(1))

1

#2 (10 mark) Write the Lisp function

(deep-member x y)that returns T if the first argument

Examples:

>(deep-member '1 '(1) ) T >(deep-member '1 '( (1) 2 3) ) T >(deep-member '1 '( ((4 1)) 2 3) ) T >(deep-member '(1) '((1) 2 3) ) T >(deep-member nil nil) NIL >(deep-member nil '(nil) ) T >(deep-member nil '((nil) ) ) T >(deep-member '(nil) '(1 2 3 (nil)) ) T >(deep-member '(3) '(3) ) NIL

#3 (10 mark) Write the Lisp function:

(deep-subst x y L)that returns returns a list L1 formed by replacing, within the recursive-list L, each occurance of the atom x (at any level) with the atom y.

(You may assume that L is a recursive list, and that x and y are each atoms.)

>(deep-subst 4 t '(truth is 4))

(TRUTH IS T)

>(deep-subst

4 nil '(4 is not (4)))

(NIL IS not (NIL))

>(deep-subst 4 nil '(5 is not (22)))

(5 is not (22))

#4 (5 marks) Write the Lisp function

(lookup atom pair-list)that finds the "atom-entry" within the list of pairs pair-list, or NIL if atom does not match any of the entries in pair-list .

You may assume that atom is an atom and pair-list is a list whose entries are each 2-element lists, whose FIRST element is always an atom.

>(lookup '5 '((t frog) (5 what) (nil 1)))

(5 what)

>(lookup 5 '((1 this) (2 is) (3 a) (4 test)) )

nil

#5 (15 marks) In general, a "conjunctive normal form" (CNF) formula is a conjunction of clauses, where each clause is a disjunction of literals, and each literal is either a variable or its negation -- eg,

cnf1 = (-x1 v -x2 v +x3) & (+x2 v +x4 v -x5)(We will later see that

Given a set of variables, an assignment maps each variable to either true (T) or false (NIL) --

e.g., the assignment

assgn1 = ( (x1 t) (x2 nil) (x3 t) (x4 nil) (x5 t ) )maps x1 to T, x2 to NIL, x3 to T, x4 to NIL and x5 to T.

Given a specific assign assgn, the CNF formula cnf evaluates to T if each of its clauses evaluates to T (otherwise it evaluates NIL); and a clause evaluates to T if at least one of its literals evaluates to T (otherwise it evaluates to NIL), and a positive literal +X1 is T if it is assigned to T in assgn; and a negative literal -X3 is T if it is assigned to NIL in assgn.

Eg, using assgn1 , the first clause of cnf1,

` (-x1 v -x2 v +x3) `

evaluates to T as its 2nd literal, -x2, evaluates to T as assgn1 includes (x2 nil).

However, cnf1's second clause

(+x2 v +x4 v -x5)evaluates to NIL as each of its 3 literals evaluates to NIL.

Hence, the conjunction of these clauses, cnf1, evaluates to NIL.

Write the Lisp function

(eval-cnf cnf assgn)that evaluates the boolean CNF formula cnf formula, with respect to the assignment assgn, returning T if assgn satisfies cnf, and NIL otherwise.

We encode a CNF as a list of clauses, where each clause is represented as a list of literals, and each literal is a two element list of + or -, followed by variable-name. ("+" means the variable is true, "-" for false).

Hence we would write

(+x1 v -x2 v +x3) & (+x2 v +x4 v -x5)as

( ((+ x1) (- x2) (+ x3)) ((+ x2) (+ x4) (- x5)) )As shown above, we represent an assignment as a list of (variable value) pairs; see assgn1 above.

Note the empty CNF list is true, and the empty clause (within the list) is false.

> (eval-cnf '() '((a t))) T > (eval-cnf '(() ((+ a)) ) '((a t))) NIL > (eval-cnf '( ((+ a)) ) '((a t))) T > (eval-cnf '( ((+ a)) ) '((a nil))) NIL > (eval-cnf '( ((+ a) (- a)) ) '((a nil))) T > (eval-cnf '( ((+ a) (- b)) ) '((a nil)(b nil))) T > (eval-cnf '( ((+ a) (- b)) ((- a)) ) '((a nil)(b nil))) T > (eval-cnf '( ((+ a) (- b)) ((+ a)) ) '((a nil)(b nil))) NIL

#6 (20 mark) Satisfiability -- finding a satisfying assignment for a boolean formula -- is one of the core ideas in computing science. It is used for verifying hardware, verifying software, reasoning, planning, as well as other areas of artificial intelligence. And of course, all NP-hard problems reduce to satisfiability. We will later see it is the core procedure for proving arbitrary conclusions from known information.

Write a LISP function

(sat cnf)

that returns a satisfying assignment
if the CNF formula cnf
is satisfiable, and otherwise return NIL.

This function should use the simple "generate and test"
approach: successively generate each possible assignments to the
variables, then test if that assignment satisfies the CNF formula --
ie, if it makes the CNF true (hint: think eval-cnf).

Given a list of the variables in the formula, there is a simple
recursive way to walk through the set of all assignments. You
need only generate one assignment -- ie, your function should terminate
on finding a satisfying assignment.

> (sat '( ((+ a)) ) ) ((a t)) > (sat '( ((+ a)) ((- a)) ) ) NIL > (sat '( ((+ a)) ((- b)) ) ) ((a t) (b nil)) > (sat '( ((+ a) (+ b)) ((- b)) ) ) ((a t) (b nil)) ;; ORIG: (a->b) & (b->c) & (c->-a) ;; (~a v b) & (~b v c) & (~c v ~ a) ;; CNF + ( (~a b) (~b c) (~c ~a) ) > (sat '( ((- a) (+ b)) ((- b) (+ c)) ((- c) (- a)) ) ) ((A NIL) (B T) (C T)) ;; a->b, b->c, c-> d > (sat '( ((- a ) (+ b)) ((- b) (+ c)) ((- c) (+ d)) ) ) ( (a t) (b t) (c t) (d t)) ;; a <=> b, -a , b ;; a-> b, b->a, -a, b > (sat '( ((- a) (+ b)) ((- b) (+ a)) ((- a)) ((+ b)) ) ) nil

End of Assignment 1.