To work through these exercises, refer to the above material for more information.
;; HINT: A typical print expression (print "Here is some text")
Note that in the REPL, you can recall your last command with Alt+P (P stands for previous) and that tab completion works on most lisp symbols.
;; HINT: Declaring and calling a function taking one parameter and printing it (defun my-func (param1) (print param1)) (my-func "hello")
Note that in the REPL, you will see the printed output as well as the return value of the function. The return value is (as you should know by now) the result of the last expression of the function body. Since the
'(1 2 3)) works.
;; HINT: Lists as data are created using the following syntax (quote (item1 item2 item3 item4 ...)) (quote (1 2 3)) ;; or using the abbreviation '(1 2 3) ;; Keyword lists are created with the following syntax '(:keyword1 numberfield1 :keyword2 numberfield2 :keyword3 numberfield3 ...) '(:a 1 :b 2 :c 3)
You can access the fields of a keyword list with the GETF function:
CL-USER> (getf '(:a 1 :b 2 :c 3) :b) 2
You can read more about keyword lists in chapter 2 of Practical Common Lisp. For more information about quoting, see this page of the Lisp Primer, and remember that quoting simply prevents a list from being evaluated and instead treats it as data.
Symbols are simply short strings, except they are case-insensitive (the REPL always prints them in uppercase) and cannot be changed or manipulated. Like with lists, quoting a symbol simply stops it from being evaluated (i.e. treated as a variable) and instead treats the symbol itself as data.
Write a function called lookup-test that takes a keyword list of numbers, looks up the number with key :test and returns the symbol YES if it is less than 10, and NO otherwise.
;; HINT: declaration and use of a keyword list CL-USER> (setf my-list '(:x 10 :y 33 :z 9)) (:X 10 :Y 33 :Z 9) CL-USER> (getf my-list :y) 33
;; HINT: using the conditional statement and returning a Symbol CL-USER> (if (< a b) 'SMALLER 'BIGGER)
,(comma); this invokes the command mode of the REPL. You should have now the focus on the lower window with the prompt changed into
cdand press ENTER. Emacs will prompt you for a file path, enter the file path to the folder where you saved the file (you can use TAB for useful auto-completion).
EXAMPLE-AGENT-PROGRAMgives an example of how to create a program to control an agent in the vacuum-cleaner world assuming a 2×1 environment as shown in the figure:
perceptkeyword list looks like this:
'(:x 0 :y 0 :dirty T)
:y are the location of the agent and
:dirty tells us if the current square has dirt or not.
random-agent-program, that has two options: Walk around the environment randomly or remain idle when it finds a clean square; Suck up dirt when it finds it.
IDLE. You can either write your function directly in the REPL or add it to the file. If you add it to the file, you have to save the file (keyboard shortcut is Ctrl+X, Ctrl+S in emacs) and then reload the file in the REPL (recommended option).
;; HINT: Getting a random value. ;; This function returns a random nonnegative number less than number, and of the same type (either integer or floating-point) (random number)
;; HINT: cond is a powerful generalization of case. It takes the form: (cond (test1 expr expr ... ) (test2 expr expr ... ) (test3 expr expr ... ) ... ) ;; cond works like this. First, test1 is evaluated. If this is true, the following expressions are evaluated and the last one is returned. ;; If not, then test2 is evaluated. If this is true, its following expressions are evaluated and the last one is true. And so on. ;; If no test evaluates to true, then nil is returned.
;; HINT: you don't have to worry about the action (UP, DOWN, ...) and environment boundaries, ;; (i.e. giving as input a 10x20 environment and having the agent at [0,0] performing the UP action) ;; since the update-env function already takes care of this when receiving boundaries coordinates.
;; HINT: Remember to initialize the environment first! ;; Init example where 10 and 20 are the width and height, respectively, and .5 is the probability ;; of a square containing dirt (init-env 10 20 .5)
SIMULATE-QUIETfunctions from the last step to test your new agent program. Remember to Does it give better performance evaluation than the old one?
EXAMPLE-MEASUREshows how simple performance evaluation functions look. This function takes an environment and an agent as parameters, and returns a number indicating the performance of the agent so far.
structures. Their fields are defined in the file
agents.lispwith calls to the
DEFSTRUCTmacro. This macro defines a function for constructing an instance of the structure, e.g. for the
ENVstructure, this function is called
widthfield of an
ENVstructure in the variable
envcan be accessed using
random-agent-measurethat awards 10 points for every clean square but deducts one point for every move the agent makes. The number of moves is stored in the
moves-so-farfield. Now run the simulations again.
;; HINT: counting the number of times an object appears in a sequence: (count object sequence keywords...) ;; For example, we can count the number of times the character 'l' appears in the Sequence "Hello World" (count #\l "hello world")
;; The count function also has count-if and count-if-not variants. ;; (count-if test-predicate sequence keywords...) counts the number of times in which test-predicate (a function pointer) returns true ;; for the elements in the sequence. ;; Counting the number of clean squares (in agents.lisp) ;; Note: the not function has the following syntax (not x) and returns T if x is NIL, otherwise returns NIL (count-if #'not (env-dirt-vector env)))
How does this change the evaluation score? Can you think of ways to change the agent program so that it scores better with this new evaluation function?