44
רררררLisp General Problem Solver רררר רררררררר ררר ררר

שיעור Lisp General Problem Solver בינה מלאכותית יעל נצר

  • View
    219

  • Download
    2

Embed Size (px)

Citation preview

Page 1: שיעור Lisp General Problem Solver בינה מלאכותית יעל נצר

Lisp שיעורGeneral Problem

Solver

בינה מלאכותית

יעל נצר

Page 2: שיעור Lisp General Problem Solver בינה מלאכותית יעל נצר

נושאים לפרוייקט

האם מכונות יכולות לחשוב?•מבחן טיורינג–החדר הסיני–מודעות של מכונות–

•Computation and representationסמלים ומערכות סמלים–AIייצוג ידע ב-–

mindמודל חישובי של ה-•האם המוח הוא מכונת חישוב?•

Page 3: שיעור Lisp General Problem Solver בינה מלאכותית יעל נצר

Antibugging Tools• error / continuable errors(defun average (numbers)

(if (null numbers)(error “Average of the empty list is undefined”)(/ (reduce #’+ numbers) (length numbers))))

• check-type:(defun sqr (x) (check-type x number) (* x x))• assert:(defun sqr (x) (assert (numberp x) (x)) (* x x))• Timing (defun f (n) (dotimes (i n) nil)) (time (f 100))

Page 4: שיעור Lisp General Problem Solver בינה מלאכותית יעל נצר

Closures

• Functions carry their environment with them.

(mapcar #'(lambda (x) (+ x x))'(1 2 3)) --> (2 4 6)

(defun adder (c) #'(lambda (x) (+ x c)))

(mapcar (adder 3) '(1 2 3)) --> (4 5 6)

(mapcar (adder 10) '(1 2 3)) --> (11 12 13)

Page 5: שיעור Lisp General Problem Solver בינה מלאכותית יעל נצר

Special Variables• Note scope is not the same thing as extent:

– scope as in other languages (part of code where variable is defined)

– Extent – lifetime of a variable: possible to exit from scope and have variable still alive in a closure.

• Ex:(defun bank-account (balance) #'(lambda (action amount) (case action (deposit

(setf balance (+ balance amount))) (withdraw (setf balance (- balance amount))))))

Page 6: שיעור Lisp General Problem Solver בינה מלאכותית יעל נצר

Special variables cont.

• Special variables: indefinite scope (like global variables).

• BUT: special variable can be shadowed by a local binding.

(defvar *counter* 0)

(defun report ()

(format t "Counter = ~d" *counter*))

(report) ==> Counter = 0

(let ((*counter* 100)) (report)) ==> Counter = 100

(report) ==> Counter = 0

Page 7: שיעור Lisp General Problem Solver בינה מלאכותית יעל נצר

• Let did not create a new local variable distinct from the special -

• instead it locally shadowed the binding of the same special var.

• Name of special variable is available at runtime:

(symbol-value '*counter*)• Lexical scoping: variables have lexical

scope and indefinite extent.• Dynamic (special) variables: indefinite

scope and dynamic extent.

Page 8: שיעור Lisp General Problem Solver בינה מלאכותית יעל נצר

Multiple Values

• Functions can return more than 1 value.(round 5.1) ==> 5 .1

(* 2 (round 5.1)) ==> 10

(defun show-both (x)

(multiple-value-bind (int rem)(round x)

(format t "~f = ~d + ~f" x int rem)))

(show-both 5.1) ==> 5.1 = 5 + 0.1

(values 1 2 3) ==> 1 2 3 ;; return 3 values.

(values) ==> ;; nothing is returned (procedures)

Page 9: שיעור Lisp General Problem Solver בינה מלאכותית יעל נצר

Equalities

XYeqeqlequalequalp

‘x‘xTTTT

‘0‘0?TTT

‘(x)‘(x)nilnilTT

‘”xy”‘”xy”nilnilTT

‘”Xy”‘”xY”nilnilnilT

‘0‘0.0nilnilnilT

‘0‘1nilnilnilnil

Exact same object

Either eq or same number

Either eql or lists/strings

with eql elements

equal and non case/type sensitive

Page 10: שיעור Lisp General Problem Solver בינה מלאכותית יעל נצר

Parameters

• optional, defaults, rest, by keyword.• Most CLisp functions have interesting

keyword arguments(find 6 '(1 2 3 4 5 6.0)) ==> nil (eql as default)

(find 6 '(1 2 3 4 5 6.0) :test #'equalp) ==> 6.0

(find 5 '(1 2 3 4 5 6.0) :test #'<) ==> 6.0

(find 5 '((a 1) (b 2) (c 3) (d 4) (e 5)) :key #'second) ==> (e 5)

• Common key arguments (on matching and sequence built-in functions):

:test, :key, :start, :end, :from-end

Page 11: שיעור Lisp General Problem Solver בינה מלאכותית יעל נצר

Example

• Define functions find-all and find-all-if that return all elts from a list matching condition.

• Note how similar to remove-if-not (built-in) and to remove.

(setf

(symbol-function find-all-if) #’remove-if-not)

Page 12: שיעור Lisp General Problem Solver בינה מלאכותית יעל נצר

• Not exactly the right thing to do find-all - need to add something:

(defun complement (fn)

"If fn returns y, then (complement fn) returns (not y)."

#'(lambda (&rest args)

(not (apply fn args))))

Page 13: שיעור Lisp General Problem Solver בינה מלאכותית יעל נצר

(defun find-all (item sequence &rest keyword-args

&key (test #'eql) test-not

&allow-other-keys)

"Find all those elements of sequence that match item, according to the keywords. Doesn't alter sequence."

(if test-not

(apply #'remove item sequence

:test-not (complement test-not) keyword-args)

(apply #'remove item sequence

:test (complement test) keyword-args)))

• Note: if same keyword appears twice, only first one is taken into account.

Page 14: שיעור Lisp General Problem Solver בינה מלאכותית יעל נצר

GPS: The General Problem Solver

• Developed in 1957 by Alan Newell and Herbert Simon.

• The "first AI program". General theory of problem solving.

• First to separate problem-solving strategy from knowledge (declarative).

Methodology:1. Describe problem in vague terms2. Specify problem in algorithmic terms3. Implement problem in a programming language4. Test the program on representative examples5. Debug and analyze the resulting program,

repeat the process.

Page 15: שיעור Lisp General Problem Solver בינה מלאכותית יעל נצר

Description: Means-end analysis and problem-solving.

I want to take my son to nursery school. What's the difference between what I have and what I want? One of distance. What changes distance? My automobile. My automobile won't work. What is needed to make it work? A new battery. What has new batteries? An auto repair shop. I want the repair shop to put in a new battery; but the shop doesn't know I need one. What is the problem? One of communication. What allows communication? A telephone...and so on. [Newell & Simon 72 - Human Problem Solving]

Page 16: שיעור Lisp General Problem Solver בינה מלאכותית יעל נצר

• Solve a problem = find a way to eliminate the difference between what I have and what I want.

• Other possibility: forward chaining from original situation.

• Some actions require solving preconditions as subproblems.

• Need description of allowable actions and their preconditions, plus description of situation.

Page 17: שיעור Lisp General Problem Solver בינה מלאכותית יעל נצר

Specification• Description of the world and of the goal: list of conditions.• List of allowable operators. Constant but a parameter.• Description of operators: action, preconditions, effects.• Effects can be simply described as add-list and delete-

list (STRIPS).• Calling form: (GPS init-state goal-state list-of-ops)• Output: sequence of operators.• To satisfy a list of goals: satisfy each goal.• To satisfy a single goal: either goal already in current

state, or find appropriate operator.• An operator is appropriate for a goal if it has goal in its

add-list.• Can apply operator if preconditions hold - that is, precond

becomes goal.

Page 18: שיעור Lisp General Problem Solver בינה מלאכותית יעל נצר

Implementation• Toplevel Functions: GPS: toplevel function.• Special Variables: *state*: current state - list of conditions *ops*: list of operators• Data Types: op: operation with preconds, add-list and del-list.• Functions:

achieve: achieve an individual goal.

appropriate-p: decide if operator is appropriate for a goal.

apply-op: apply operator to current state.• Utilities:

member, set-difference, union, every, some, find-all.

Page 19: שיעור Lisp General Problem Solver בינה מלאכותית יעל נצר

Code Version 1(defvar *state* nil "The current state: a list of conditions.")

(defvar *ops* nil "A list of available operators.")

(defstruct op "An operation" (action nil) (preconds nil) (add-list nil) (del-list nil))

(defun GPS (*state* goals *ops*) "General Problem Solver: achieve all goals using *ops*."

(if (every #'achieve goals) 'solved))

Page 20: שיעור Lisp General Problem Solver בינה מלאכותית יעל נצר

(defun achieve (goal) "A goal is achieved if it already holds, or if there is an appropriate op for it that is applicable." (or (member goal *state*) (some #'apply-op (find-all goal *ops* :test #'appropriate-p))))

(defun appropriate-p (goal op) "An op is appropriate to a goal if it is in its add list." (member goal (op-add-list op)))

(defun apply-op (op) "Print a message and update *state* if op is applicable." (when (every #'achieve (op-preconds op)) (print (list 'executing (op-action op))) (setf *state* (set-difference *state* (op-del-list op))) (setf *state* (union *state* (op-add-list op))) t))

Page 21: שיעור Lisp General Problem Solver בינה מלאכותית יעל נצר

(make-op :action 'drive-son-to-school :preconds '(son-at-home car-works) :add-list '(son-at-school) :del-list '(son-at-home))

;;; ==============================

Page 22: שיעור Lisp General Problem Solver בינה מלאכותית יעל נצר

(defparameter *school-ops* (list (make-op :action 'drive-son-to-school

:preconds '(son-at-home car-works) :add-list '(son-at-school) :del-list '(son-at-home))

(make-op :action 'shop-installs-battery :preconds '(car-needs-battery shop-knows-problem shop-has-money) :add-list '(car-works))

(make-op :action 'tell-shop-problem :preconds '(in-communication-with-shop) :add-list '(shop-knows-problem))

(make-op :action 'telephone-shop :preconds '(know-phone-number) :add-list '(in-communication-with-shop))

(make-op :action 'look-up-number :preconds '(have-phone-book) :add-list '(know-phone-number))

(make-op :action 'give-shop-money :preconds '(have-money) :add-list '(shop-has-money) :del-list '(have-money))))

Page 23: שיעור Lisp General Problem Solver בינה מלאכותית יעל נצר

(gps '(son-at-home car-needs-battery have-money have-phone-book) '(son-at-school) *school-ops*)

(EXECUTING LOOK-UP-NUMBER)(EXECUTING TELEPHONE-SHOP)(EXECUTING TELL-SHOP-PROBLEM)(EXECUTING GIVE-SHOP-MONEY)(EXECUTING SHOP-INSTALLS-BATTERY)(EXECUTING DRIVE-SON-TO-SCHOOL)SOLVED

(gps '(son-at-home cat-needs-battery have-money) '(son-at-school) *school-ops*)

NIL

(gps '(son-at-home car-works) '(son-at-school) *school-ops*)

(EXECUTING DRIVE-SON-TO-SCHOOL)SOLVED

Page 24: שיעור Lisp General Problem Solver בינה מלאכותית יעל נצר

Analysis: How General?• First version crucial to understand problem better.• Running around the block problem: limit of KR formalism.

– How to represent action "running around the block"? No add or delete.

• Clobbered Sibling Goal Problem: (gps '(son-at-home car-needs-battery have-money have-

phone-book) '(have-money son-at-school) *school-ops*)

(EXECUTING LOOK-UP-NUMBER)(EXECUTING TELEPHONE-SHOP)(EXECUTING TELL-SHOP-PROBLEM)(EXECUTING GIVE-SHOP-MONEY)(EXECUTING SHOP-INSTALLS-BATTERY)(EXECUTING DRIVE-SON-TO-SCHOOL)SOLVED

Page 25: שיעור Lisp General Problem Solver בינה מלאכותית יעל נצר

• But not true! Money is spent!(every #'achieve goals) --> each goal

have been satisfied in sequence, but not necessarily holds at the end!

• Fix:(defun achieve-all (goals) (and (every #'achieve goals)

(subsetp goals *state*)))• Checks that goal is reached, but does not

force backtracking to find a solution if not.•

Page 26: שיעור Lisp General Problem Solver בינה מלאכותית יעל נצר

Leaping before you look

• Same example, fixed function. Replies NIL after having spent the money!

(gps '()

'(jump-off-cliff land-safely) *ops*)

-->

(EXECUTING JUMP-OFF-CLIFF)

nil• Planning and execution are

interleaved.

Page 27: שיעור Lisp General Problem Solver בינה מלאכותית יעל נצר

Recursive Subgoal Problem

• How to get a phone number? Look up phone book

• Add option "Ask someone".(push

(make-op :action 'ask-phone-number

:preconds

'(in-communication-with-shop)

:add-list '(know-phone-number))

*school-ops*)

--> Infinite loop!

Page 28: שיעור Lisp General Problem Solver בינה מלאכותית יעל נצר

A More General Problem Solver

• Solve the problems: "running around the block", "prerequisite clobbers sibling goal", "leaping before you look" and "recursive subgoal" problems.

Page 29: שיעור Lisp General Problem Solver בינה מלאכותית יעל נצר

Implementation

• Top-level function: GPS• Special variables: *ops*• Data types: op• Major functions:

achieve-all - achieve a list of goalsachieve - achieve an individual goalappropriate-p - decide if an operator is

appropriate for a goalapply-op - apply operator to current state

Page 30: שיעור Lisp General Problem Solver בינה מלאכותית יעל נצר

• Auxiliary functions:executing-p: Is a condition an executing

form?starts-with: is the argument a list starting

with a given atom?convert-op: convert an operator to use the

executing conventionuse: use a list of operators

Page 31: שיעור Lisp General Problem Solver בינה מלאכותית יעל נצר

Improvement 1:

• Instead of just printing a message whenever executing an action, GPS returns the resulting state with a list of "messages" indicating which actions have been taken

• This solves the "running around the block" problem:

(GPS '((executing running-around-the-block)))

Page 32: שיעור Lisp General Problem Solver בינה מלאכותית יעל נצר

(defun executing-p (x)"Is x of the form (executing ...)?"(starts-with x 'executing))

(defun starts-with (list x)"Is this a list whose first element is x?"(and (consp list) (eql (first list) x)))

(defun convert-op (x)"Make op conform to the (EXECUTING op) convention."(unless (some #'executing-p (op-add-list op))

(push (list 'executing (op-action op)) (op-add-list op)))op)

(defun op (action &key preconds add-list del-list)"Make a new operator that obeys the (EXECUTING op) convention."(convert-op

(make-op :action action :preconds preconds :add-list add-list :del-list del-list)))

Page 33: שיעור Lisp General Problem Solver בינה מלאכותית יעל נצר

Improvement 2

• To solve the "leaping before you look" problem - do not update a global variable *state* before you know you will succeed.

(defun GPS

(state goals &optional (*ops* *ops*))

"From state, achieve goals using *ops*."

(remove-if #'atom

(achieve-all

(cons '(start) state) goals nil)))

Page 34: שיעור Lisp General Problem Solver בינה מלאכותית יעל נצר

• Semi-predicates: why do we add (start) in state?If GPS returns nil, is it because it failed or because it is an

emptystate? NIL is now ambiguous between failure and empty list

ofactions. Solve ambiguity by representing state with lists of

atleast one element.

• Why do we remove atoms? The executing convention means that we keep track of the

actions in the state as pairs (EXECUTING op), all the other elements are atoms.

In the result, we only want the plan of actions, not the state.

Page 35: שיעור Lisp General Problem Solver בינה מלאכותית יעל נצר

Improvement 3

• Use an explicit goal-stack• To solve the "recursive subgoal

problem": keep a stack of goals being solved, immediately fail if a goal appears as a subgoal of itself.

• To solve the "clobber sibling goal" problem, update achieve-all to test for final satisfaction.

Page 36: שיעור Lisp General Problem Solver בינה מלאכותית יעל נצר

(defun achieve-all (state goals goal-stack)

"Achieve each goal, and make sure they still hold at the end"

(let ((current-state state))

(if (and (every #'(lambda (g)

(setf current-state

(achieve current-state g goal-stack)))

goals)

(subsetp goals current-state :test #'equal))

current-state)))

(defun achieve (state goal goal-stack)

"A goal is achieved if it already holds, or if there is an

appropriate op for it that is applicable."

(dbg-indent :gps (length goal-stack) "Goal: ~a" goal)

(cond ((member-equal goal state) state)

((member-equal goal goal-stack) nil)

(t (some #'(lambda (op) (apply-op state goal op goal-stack))

(find-all goal *ops* :test #'appropriate-p)))))

Page 37: שיעור Lisp General Problem Solver בינה מלאכותית יעל נצר

• Why do we use member-equal?• Default test in member is eq. Must test for lists because of (executing op) convention.

(defun member-equal (item list)

(member item list

:test #'equal))

Page 38: שיעור Lisp General Problem Solver בינה מלאכותית יעל נצר

• Why can't we use union and set-difference in new apply-op?

(defun apply-op (state goal op goal-stack) "Return a new state if op is applicable." (dbg-indent :gps (length goal-stack) "Consider: ~a"

(op-action op)) (let ((state2 (achieve-all state (op-preconds op)

(cons goal goal-stack)))) (unless (null states) ;; Return updated state (dbg-indent :gps (length goal-stack) "Action:

~a" (op-action op)) (append (remove-if #'(lambda (x) (member-equal x

(op-del-list op))) state2) (op-add-list op)))))

Page 39: שיעור Lisp General Problem Solver בינה מלאכותית יעל נצר

• State is now an ordered list of actions (to preserve order of (EXECUTING op) elements).

• Functions union and set-difference do not preserve order of sets (they use sort). Functions append and remove-if are guaranteed to preserve order.

Page 40: שיעור Lisp General Problem Solver בינה מלאכותית יעל נצר

Improvement 4

• Make program environment a parameter that can be declared easily and switched.

• Do NOT depend on global state for any aspect.

(defun use (oplist)

"Use oplist as the default list of operators."

(length (setf *ops* oplist)))

Page 41: שיעור Lisp General Problem Solver בינה מלאכותית יעל נצר

The MAZE searching domain

12345

678910

1112131415

1617181920

2122232425

Page 42: שיעור Lisp General Problem Solver בינה מלאכותית יעל נצר

The MAZE searching domain

• We don't have variables... so we need many operators.• We still don't need to write them down ourselves...

(defun make-maze-ops (pair) "Make maze-op in both directions." (list (make-maze-op (first pair) (second pair)) (make-maze-op (second pair) (first pair))))

(defun make-maze-op (here there) "Make an operator to move between 2 places." (op `(move from ,here to ,there) :preconds `((at ,here)) :add-list `((at ,there)) :del-list `((at ,here))))

(defparameter *maze-ops* (mappend #'make-maze-ops '((1 2) (2 3) (3 4) (4 9) (9 14) (9 8) ...)))

Page 43: שיעור Lisp General Problem Solver בינה מלאכותית יעל נצר

(use *maze-ops*) ==> 48> (gps '((at 1)) '((at 25)))((START) (EXECUTING (MOVE FROM 1 TO 2)) ... (EXECUTING (MOVE FROM 20 TO 25)) (AT 25))

Also return the state: (AT 25) when we only wanted the actions!

(remove-if #'atom ...) is the culprit: use (find-all-if #'action-p...)

(defun action-p (x) (or (equal x '(start)) (executing-p x)))

Page 44: שיעור Lisp General Problem Solver בינה מלאכותית יעל נצר

(defun find-path (start end) "Search a maze for a path from start to end." (let ((result (GPS `((at ,start)) `((at ,end))))) (unless (null result) (cons start

(mapcar #'destination (remove '(start) results

:test #'equal))))))

(defun destination (action) "Find the Y in (executing (move from X to Y))" (fifth (second action)))

(use *maze-ops*) --> 48(find-path 1 25) --> (1 2 3 4 9 8 7 12 11 16 17 22 23

24 19 20 25)(find-path 1 1) --> (1)