22
Artificial Intelligence and Lisp Lecture 6 LiU Course TDDC65 Autumn Semester, 2010 http://www.ida.liu.se/ext/TDDC65/

Artificial Intelligence and Lisp Lecture 6 LiU Course TDDC65 Autumn Semester, 2010

  • View
    221

  • Download
    1

Embed Size (px)

Citation preview

Artificial Intelligence and LispLecture 6

LiU Course TDDC65Autumn Semester, 2010

http://www.ida.liu.se/ext/TDDC65/

List processing (in CEL)

Recursively nested sequences as the only composite expressions, with symbols, strings, numbers as elements

Functions on sequences (no side-effects!)

(e1 <a b c>) = a (e2 <a b c>) = b

(en 4 <a b c d e f>) = d

(t1 <a b c>) = <b c>

t2, tn similarly

(cons g <a b c>) = <g a b c>

Notice: (cons (e1 .x) (t1 .x)) = x

List processing (in CEL)

Predicates on lists

[equal <a b c> <a b c>] = true Control operators, for example

(if [equal .a <>] .b .a)

Other necessary function

(type-of .a)

The value is either symbol, string, integer, real, sequence

Other functions can be defined in terms of these, for example

and, or, not

List Processing - Recursive Functions

(length .s) ==

(if [equal .s <>] 0 (+ 1 (length (t1 .s))))

(replace .a .b .s) ==

(if [equal .s .a] .b

(if [atom .s] s

(cons (replace .a .b (e1 .s))

(replace .a .b (t1 .s)) )))

(append .a .b) ==

(if [equal .a <>] b

(cons (e1 .a)(append (t1 .a) b)) )

S-expression Style

Examples:

color.red "Yes or no: " 421

(walkto busstop-4) (walk :from home :to busstop-4)

(seq (walkto busstop-4)(takebus Lkp-C))

(set busstop-4 busstop-7 busstop-12)

(+ (timefor (walkto busstop-d)) (timefor (waitfor (some (and bus (going-to Lkp-C)) ))) (timefor (go bus busstop-4 Lkp-C)) )

S-expression Style

1. Nested parenthesized expressions (lists) 2. Convention: operator as first element in list 3. Convention: use of tags e.g. :from, :to 4. Convention, sometimes: variables as ?vbl Can be used for programming language, but also for plain

data, for logic, and for alternative languages S-expression-based programming languages: Lisp,

Scheme

Lisp Programming

Lisp uses S-expression style, all data are formed as recursively nested expressions with round parentheses

Using function names such as e1 and t1, rewrite as follows (e1 <a b c>) (e1 (quote (a b c))) ssv .a <red green> (setq a (quote (red green))) (e1 .a) (e1 a)

General rule: a list (g a b c) is considered as a term with g as a function and the rest as arguments, except for a small number of special operators, such as quote, if, ...

This results in the simplest possible system, but at some expense of readability. KRE / CEL is closer to the standard notation of logic and mathematics.

Lisp Recursive Function Definitions

(defun length (s)

(if (equal s nil) 0 (+ 1 (length (t1 s)))) )

(defun replace (a b s)

(if (equal s a) b

(if (atom s) s

(cons (replace a b (e1 s))

(replace a b (t1 s)) ))))

(defun append (a b)

(if (equal a nil) b

(cons (e1 a)(append (t1 a) b)) ))

Other Lisp Control Primitives

(cond (c1 v1)(c2 v2) ...)

same as (if c1 v1 (if c2 v2 ... ))

(dolist (x '(a b c)) (...))

allows x to range over a, b, c and performs (...)

(dotimes (n 10) (...))

allows n to range from 0 to 9 and performs (...)

(let ((a 5)(b 10)) (...))

binds a and b and evaluates (...) with those bindings

(let* ((a 5)(b (- a 1))) (...))

binds a and b successively and then evaluates (...)

The expressions in (...) may read, print, assign, etc.

Lisp Systems - Data Structure

(red green blue) represented as

red

nil

bluegreen

The e1 and t1 operations follow a pointer (but they are actually called car and cdr in Lisp)The cons operation constructs a new 'yellow' cellThis was the origin of the method of garbage collection.

Performance in Alternative Definitions

(defun reverse (a) (if (null a) nil (append (reverse (t1 a)) (list (e1 a))) ))

Note: nil is the same as (), (null a) is (equal a nil),(list a b c...) forms a list, (list a) is (cons a nil)

(defun reverse (a)(rev2 a nil))(defun rev2 (a b) (if (null a) b (rev2 (t1 a)(cons (e1 a) b))) )

Compare the number of allocated cons cells for thecomputation as a function of the length of the argument

Definitions as Propositions in Logic

(defun reverse (a) (if (null a) nil (append (reverse (t1 a)) (list (e1 a))) ))

Compare:

(reverse nil) = nil(reverse (cons a b)) = (append (reverse b)(list a))

Evaluation of (reverse '(red green blue))Rewrite as (reverse (cons 'red '(green blue)))Rewrite as (append (reverse '(green blue)) (list 'red)) and so on... (append '(blue green) (list 'red))

Then apply the function append directly, or evaluate itin the same way. -- Possible but inefficient (?)

Program Correctness Proof

Specification of the reverse function:(reverse nil) = nil(reverse (cons a b)) = (append (reverse b)(list a))

Implementation of that specification:(defun reverse1 (a)(rev2 a nil))(defun rev2 (a b) (if (null a) b (rev2 (t1 a)(cons (e1 a) b))) )

Desired to prove:(reverse a) = (reverse1 a) for all aMake proof by induction over a:1. (reverse nil) = nil (reverse1 nil) = (rev2 nil nil) = nil2. (reverse (cons x y)) = (append (reverse y)(list x)) = (append (reverse1 y)(list x)) according to ind.hyp. (reverse1 (cons x y)) = (rev2 (cons x y) nil) = (rev2 y (list x))

Program Correctness Proof

Specification of the reverse function:(reverse nil) = nil(reverse (cons a b)) = (append (reverse b)(list a))

Implementation of that specification:(defun reverse1 (a)(rev2 a nil))(defun rev2 (a b) (if (null a) b (rev2 (t1 a)(cons (e1 a) b))) )

Desired to prove:(append (reverse y)(list x)) = (rev2 y (list x))Try for more general: (append (reverse y) x) = (rev2 y x)Make proof by induction over y:1. (append (reverse nil) x) = x (rev2 nil x) = x2. (append (reverse (cons u v)) x) = ... (rev2 (cons u v) x) = (rev2 v (cons u x))

Program Correctness ProofSpecification of the reverse function:(reverse nil) = nil(reverse (cons a b)) = (append (reverse b)(list a))

Implementation of that specification:(defun reverse1 (a)(rev2 a nil))(defun rev2 (a b) (if (null a) b (rev2 (t1 a)(cons (e1 a) b))) )

Desired to prove:(append (reverse y)(list x)) = (rev2 y (list x))Try for more general: (append (reverse y) x) = (rev2 y x)

Make proof by induction over y:1. (append (reverse nil) x) = x (rev2 nil x) = x2. (append (reverse (cons u v)) x) = (append (append (reverse v) (list u)) x) = (append (reverse v) (list u) x) = (append (reverse v) (append (list u) x)) = (rev2 v (append (list u) x)) = (rev2 v (cons u x)) (rev2 (cons u v) x) = (rev2 v (cons u x))

Program Property Proof

Specification of the append function:(append nil c) = c(append (cons a b) c) = (cons a (append b c))

Desired to prove:(append (append a b) c) = (append a (append b c))

Make proof by induction over a:1. (append (append nil b) c), (append b c) (append nil (append b c)), (append b c)2. (append (append (cons x y) b) c) (append (cons x (append y b)) c) (cons x (append (append y b) c)) (append (cons x y)(append b c)) (cons x (append y (append b c))) Equality is obtained using the induction hypothesis.

Principles illustrated by this proof example

Use the combination of a specification (clean, simple, expressed in logic, has recursive counterpart that is often quite inefficient) and an implementation (takes performance into account, therefore often more complex, requires correctness proof using the specification)

Correctness proofs are almost always induction proofs

Finding the induction proof sometimes comes naturally from the structure of the two definitions, but sometimes it requires some thinking to find the right induction hypothesis

Side-Effect Functions in Lisp

red

nil

bluegreen

(rplaca a b) assumes a is a cons cell. It replaces the e1 pointerin a so that (e1 a) becomes b, and returns a.(rplacd a b) is similar but with respect to the t1 pointer.

Here rplaca is “replace car”, rplacd is “replace cdr”.

Side-effect Oriented Functions

(setq vbl value) Used above

(prog2 a b) Evaluates a and b and returns

the value of b

(progn a b ... d) Evaluates arguments in order

and returns value of last arg

Example (“destructive append”):

(defun nconc (a b)(if (null a) b (nconc2 a a b)))

(defun nconc2 (aa a b)

(if (null (t1 a))

(progn (rplacd a b) aa)

(nconc2 aa (t1 a) b) ))

Iterative Function Definitions

The definitions of rev2 and nconc2 are examples of recursive definitions that are iterative

A recursive function definition is iterative if the function itself only occurs on the top level of then and else branches (second and third argument of if), recursively, but not in subexpressions of these branches and not in the if branch (first argument of the if operator)

For systems of several recursive functions that invoke each other, this must hold for all the definitions

Iterative function definitions can be executed particularly efficiently since there is no need to build the execution stack. This applies in both interpreted and compiled mode.

Notice that the definitions above that avoid unnecessary cons operations also happen to be iterative. (This is a tendency but not a general rule).

The implicit progn

(defun foo (a b) (fie a)(fum b))

is the same as

(defun foo (a b)(progn (fie a)(fum b)))

(cond ((foo a b)(fie a)(fum b))

(t (fie b)(fum a)) )

is the same as

(cond ((foo a b)(progn (fie a)(fum b)))

(t (progn (fie b)(fum a))) )

Similar implicit progn is used e.g. in let expressions

Evaluation order for and and or

The Lisp functions and and or consider nil as 'false' and everything else as 'true'

Therefore (and a b) is nil if some argument is nil

and (or a b) is nil if all arguments are nil

These functions evaluate their arguments in order, and only as many as are needed

Therefore (and a b) is not necessarily the same as (and b a), if a and b are subexpressions, and similarly for or

Example: (or (progn (setq a 5) t) (setq a 6))

Example: Suppose (faculty -1) goes into infinite loop, and compare (or (faculty 1)(faculty -1)) with (or (faculty -1)(faculty 1))