CPSC 420-502 Read-Only Bulletin Board

Last modified: 11/12/03, 06:02PM (Wed)

This page will have all relevant email transactions with the students regarding the AI course, so that everyone has equal information regarding the course material.

Newest transactions will be posted on the top. Regularly view this page to see what's going on between other students and the instructor.

All sensitive material such as your name, email address, etc. will be removed, and also any part of code that is not relevant to the discussion will not be uploaded here.


Article List

Date: 12/11 Title: Final exam questions (unification)
Date: 12/11 Title: Final exam questions (general)
Date: 12/11 Title: Clarifications (final review, and slide08)
Date: 11/04 Title: Manhattan distance and how to select heuristic functions
Date: 10/31 Title: Search works only for the first time I call, and never the 2nd time around
Date: 10/28 Title: (expand ...) always returns NIL
Date: 10/28 Title: Some Lisp idioms (sorting, list reversal, and while loops)
Date: 10/26 Title: Debugging Depth First Search
Date: 10/25 Title: Understanding error messages
Date: 10/25 Title: Program 2 tips
Date: 10/25 Title: Program 2 guideline
Date: 10/14 Title: Program 2 skeleton codes
Date: 10/13 Title: Homework 2 Q and A
Date: 10/1 Title: Homework 1 more clarifications
Date: 9/30 Title: Homework 1 clarifications
Date: 9/30 Title: Typos in slide06 / Prog2 due date change
Date: 9/25 Title: Using TRACE to debug recursion
Date: 9/25 Title: Problem with simplification
Date: 9/25 Title: Example expressions and a problem with SMINUS
Date: 9/24 Title: How to check if something contains a single symbol or not?
Date: 9/24 Title: Division by zero
Date: 9/23 Title: Why do we need splus?
Date: 9/22 Title: How to use the "turnin" command
Date: 9/16 Title: Downloading the skeleton file
Date: 9/16 Title: Error loading a lsp file
Date: 9/11 Title: Writing program files and loading
Date: 9/11 Title: Typos in the slide
Date: 9/11 Title: List of functions
Date: 9/3 Title: Unix basics
Date: 9/3 Title: Lisp starter
Date: 9/1 Title: No articles


Articles

Date: 12/11 Title: Final exam questions (unification)
> When using Unification and I think substitution as well, how do you simply
> it.  I don't understand what it means to say Sigma = {x | y} o {y | B} = {x
> | a, y | b}.  How is this done.  I was reading about the section about
> composition of substitutions and I just didn't understand it at all.  It
> says that you have two substitutions.  Theta = {x1|t1, x2|t2, etc} and
> Lambda = {y1|u1, y2|u2, etc} And then somehow there are terms that are
> deemed meaningless.  This just doesn't make sense to me so if you could try
> and help me clear this up before the test, that'd be great.  Talk to you
> soon hopefully.
>
>

        Say you have {x|y} and want to compose that with {y|B}.

        Simply

                1. apply the 2nd substitution {y|B} to the
                   previous (i.e. {x|y}), only to the term part
                   (as in v|t) to get

                        {x|B},

                   and then

                2. append the 2nd substitution {y|B} to the 1st:

                        {x|B, y|B}.


        Let's take another example.

                {x|y,z|f(y)}o{y|B,z|C}

                1. apply {y|B,z|C} to {x|y,z|f(y)}

                        {x|B,z|f(B)}

                 (note that z stays the same!!)


                2. then append {y|B,z|C}.


                        {x|b,z|f(B),y|B,z|C}.

                   But wait! z|f(B) would have already replaced
                   all z's so there won't be any more z left by the
                   time you want to apply z|C. So, z|C is meaningless,
                   so you get rid of it. So, the final result is:

                        {x|b,z|f(B),y|B}.


        It's easier to think of it in this way. First you apply the
        1st subst, and then on that result, you apply the 2nd subst.

        [1st subst] o [2nd subst] is just a convenient way of
        summarizing the final effect it takes.

Date: 12/11 Title: Final exam questions (general)
> 
> XXXX and I were wondering if you could give us some clarification as far as
> the format of the exam goes.  We've listed some questions below.
> 
>   1 - How long is it going to be/how many questions?

        About 1:30 would be enough.                         

        Similar to the midterm.

		30% First-order Logic
		30% Uncertainty
		40% Learning

>   2 - Will the format be similar to the first test?

        Yes.

>   3 - How much of the test will be workout vs. definitions?

        About 40% would require verbal answers. About 60% would require
        workout.

        Verbal questions will test your "understanding" of the 
        concept rather than asking what is the definition.


>   4 - Are all the workout problems going to be similar to the homework
> problems?  Or are there going to be additional types of workout questions as

        Yes.

> well?
 
        You may want to practice a bit on English sentence to
        first order logic.
 
Date: 12/11 Title: Clarifications (final review, and slide08)
I. final-review.pdf

* general:

        - the laws of FOL and probability listed in

                http://courses.cs.tamu.edu/choe/03fall/lectures/laws.pdf

          will be included in the exam for your reference.

* p 11, 3rd bullet

        - you don't need to know details about neurotransmitter
          molecules, etc.


II. slide08.pdf

* p 83

        (3)             Ax (D(x) -> ~V(x))
           {rm ->} =    Ax (~D(x) \/ ~V(x))

                                     ^
                                     |
                                   add negation here!

* p 84

        (3) ~D(x) \/ ~V(x)

                     ^
                     |
                  add negation here!

After fixing these, you will be able to derive False from
the clauses on p 84.

Date: 11/04 Title: Manhattan distance and how to select heuristic functions
[Q1] What is Manhattan distance?

[A1] Here's an approximate algorithm.

1. Pick a tile, say n.

2. Find it's current location in the given state: use the (location ...)
   function.

3. Calculate its desired location (from the goal state).

4. Get the x and y location for the current and desired location. Let's
   call them x_c, y_c, and x_d, y_d.

5. The manhattan distance for this tile n is

        manhattan(n) = abs(x_c-x_d) + abs(y_c-y_d).

6. Get the sum for all tiles

                        n=8
        sum_manhattan = Sum manhattan(n)
                        n=0

[Q2] How do I select different heuristics for a* and heuristic search?

[A2] It'e easier to have a global variable that holds the heuristic function name, let's say *heuristic-func*.

Your heuristic search function should take in the function to use as an argument:

	(defun heuristic (state h-func)

		...
		(setq *heuristic-func* h-func)

		...

	)
which can be called as:
	(heuristic '( 1 2 3 ... ) 'h1)
supposing that you defined your heuristic functions as
	(defun h1 (state) 		; tiles out of place
		...
	)

	(defun h2 (state)		; sum of Manhattan distance
		...
	)

In (expand ...) or in (apply-op ...), you should call a heuristic wrapper (h state)


	(defun apply-op (op node)
		...

		...  (h state) ...

	)

	(defun h (state)
		(funcall *heuristic-func* state)
	)
so that the apply-op function should call the heuristic that you selected in your main search wrapper function.

For example, try this to see what the main idea is:

	* (setq op '+)
	+

	* (funcall op 10 20)
	30

	* (setq op 'list)
	LIST

	* (funcall op 10 20 30)
	(10 20 30)

Date: 10/31 Title: Search works only for the first time I call, and never the 2nd time around
[Q] My search works the first time I call it, but it seems to go on forever the second time I call it. What's wrong?

[A] It must be the case that you are not refreshing your duplicate check node list. Suppose it is *all-nodes-expanded*, then for each search insert this line before you call the search core:


	(setq *all-nodes-expanded* nil)

Note that for Iterative Deepening Search, you have to reset the list to NIL before each iteration!
Date: 10/28 Title: (expand ...) always returns NIL
[Q] My (expand ...) function always returns NIL!?

[A] You are probably just doing (cons (apply-op ...) return-node-list) or (append (list (apply-op ...)) return-node-list). What you should do is to assign the result of that cons or append back into the temporary variable that holds the list of expanded nodes (i.e., the return-node-list variable).

	(setq return-node-list (cons (apply-op ...) return-node-list))
Also, at the end of the expand function, you must put return-node-list so that it will be returned as the function value.
(defun expand (...)

  (let (return-node-list) 		; <--- declare local variable
	
	...

		(setq return-node-list (cons (apply-op ...) return-node-list))

	...


	return-node-list		; <-- (let ...) will return this
					;     This must be the last line
					;     in the (let ....) form.

  )					; <-- and that will be again returned
					;     by your expand function.
)
Date: 10/28 Title: Some Lisp idioms (sorting, list reversal, and while loops)
Here are some lisp idioms that may help you folks:
  1. Sorting: sort using the heuristic function value only:
    * (setq node-list '(     ((1 2 3 4 5 6 7 8 0) 10 2 (up down))
                            ((1 3 2 6 5 4 8 7 0) 15 1 (left))
                            ((3 4 2 5 6 1 0 7 8) 2  3 (left right down)) ))
    
    (((1 2 3 4 5 6 7 8 0) 10 2 (UP DOWN)) ((1 3 2 6 5 4 8 7 0) 15 1 (LEFT))
     ((3 4 2 5 6 1 0 7 8) 2 3 (LEFT RIGHT DOWN)))
    
    * (sort node-list #'(lambda (x y) (< (second x) (second y))) )
    
    (((3 4 2 5 6 1 0 7 8) 2 3 (LEFT RIGHT DOWN))
     ((1 2 3 4 5 6 7 8 0) 10 2 (UP DOWN))
     ((1 3 2 6 5 4 8 7 0) 15 1 (LEFT)))
    
    >
    

    By changing

    #'(lambda (x y) (< (second x) (second y)))
    
    to
    #'(lambda (x y) (< (+ (second x) (third x))
    		      (+ (second y) (third y))
    		   )
         )
    
    you can make the nodes sort according to f(n) = g(n)+h(n).

  2. Reversing a list: simply use reverse.
    * (reverse '(left right up down right down))
    
    (DOWN RIGHT DOWN UP RIGHT LEFT)
    
    
  3. While loops: you can define a macro like this:
    * (defvar x 0)
    
    X
    * (defmacro while (test &rest forms) `(loop (unless ,test (return)) ,@forms))
    
    WHILE
    
    * (setq x 0)
    
    0
    * (while (< x 10)			
          (setq x (+ x 1))
          (print (format nil "~d~%" x))
      )
    
    "1
    "
    "2
    "
    "3
    "
    "4
    "
    "5
    "
    "6
    "
    "7
    "
    "8
    "
    "9
    "
    "10
    "
    NIL
    
Date: 10/26 Title: Debugging Depth First Search
Debugging Depth First Search (DFS) is no easy matter, because there does not seem to be a trivial case (4 to 5 moves to the goal) where DFS can actually find an answer. So, the problem is that you're never sure if your program is buggy or if DFS is slipping down the wrong branch.

One way of solving this issue is to test it with a bogus goal state, which can be reached by repeatedly applying one or two operators only.

For example, suppose you set your goal state to be

	1 2 3
	0 8 4
	7 5 6
and set your initial state as follows:
	1 2 3
	8 4 0
	7 5 6
The solution then is 'LEFT 'LEFT, thus if 'LEFT was the first operator you try among the four, DFS will find the solution.

Another way is to indirectly test it with Depth Limited Search. With a fixed depth limited, you can be sure that the search will not go infinitely deep.

Date: 10/25 Title: Understanding error messages
Some Lisp error messages can be enigmatic. Here are some common ones that may come up frequently:
  1. Error: Illegal function call
    You entered the bold part below, to put multiple statements in a code block, and got this strange error. (Note: * is the lisp prompt.)
    * (   
         (setq x 10)
         (setq y 20)
         (cons x (list y))
      )
    
    ; In: (SETQ X 10) (SETQ Y 20)
    
    ;   ((SETQ X 10) (SETQ Y 20) (CONS X #))
    ; Error: Illegal function call.		<--- this is your error message
    
    Execution of a form compiled with errors:
     ((SETQ X 10) (SETQ Y 20) (CONS X (LIST Y)))
       [Condition of type SIMPLE-PROGRAM-ERROR]
    
    Restarts:
      0: [ABORT] Return to Top-Level.
    
    Debug  (type H for help)
    
    ("Top-Level Form")[:TOP-LEVEL]
    Source: ((SETQ X 10) (SETQ Y 20) (CONS X (LIST Y)))
    0] 
    

    The reason for this is that lisp looks at the first item in a list like that as a function name. That is, it thinks (SETQ X 10) is a function name and balks because it is not a function (see the underlined part right above)!

    The proper way of doing what you wanted to do at first is to use (progn ...).

    * (progn   
         (setq x 10)
         (setq y 20)
         (cons x (list y))
      )
    
  2. End-of-File on #<Stream for file ...
    Suppose this was your program file:
    (defun hello-world ()
      (print "hello world!")
    
    
    
    and you tried to load it using (load ...), and got this error.
    * (load "test.lsp")
    
    ; Loading #p"/user/choe/web_project/420/test.lsp".
    
    End-of-File on # <----this is your error! 
       [Condition of type END-OF-FILE]   
    
    Restarts:
      0: [CONTINUE] Return NIL from load of "test.lsp".
      1: [ABORT   ] Return to Top-Level.
    
    Debug  (type H for help)
    
    (LISP::INPUT-CHARACTER #
                           T
                           NIL)
    Source: Error finding source: 
    Error in function DEBUG::GET-FILE-TOP-LEVEL-FORM:  Source file no longer exists:
      target:code/fd-stream.lisp.
    0] 
    
    This was because you didn't close the last parenthesis in your hello-world program file. (See above.)
Date: 10/25 Title: Program 2 tips
These are some scattered Lisp tips:
  1. To add a single item to a list, use (cons ...):
    	(let (node-list)
    
    	  (setq node-list '( a b c ))
    
    	  ...
    
    	  ; WRONG way: cons alone does NOT update node-list
    	  ; After the following operation, node-list will remain '(a b c)
    	  (cons 'x node-list)
    	
    	  ...
    
    	  ; RIGHT way: you have to use setq 
    	  ; so that node-list now contains '(x a b c)
    	  (setq node-list (cons 'x node-list))
    
    
    The same thing applies for sorting. When you sort, the list you give as an argument does not get updated. You have to make sure that you recover the result by using (setq ...).

  2. Checking for duplicates:
    Just keep a global variable *all-expanded-nodes*, and keep cons-ing to it when you bump into a state that you haven't seen so far. See the (dupe ...) function in the skeleton code for a clue. You first check if a given node is a dupelicate, and if not, add that to the *all-expanded-nodes* list.
    	(defvar *all-expanded-nodes* nil)
    
    	...
    
    	; if not dupe, add it to the *all-expanded-nodes* list
    	(setq *all-expanded-nodes* (cons given-node *all-expanded-nodes*))
    	
    	...
    

  3. [Q] I am confused about the (expand ....) function in the skeleton code!
    [A] It is just a wrapper. Because there can be different expand functions depending on whether you have to check for a depth limit or an f-limit, you may end up writing redundant code. Instead of doing that, you can take in the expand function name as an argument and use a generic expand as in the provided code.
    	(defvar *expand-func* 'vanilla-expand)
    
    	...
    	(defun general-search (state expand-func)
    		...
    
    		; note that we're setting the expand function to 
    		; the one supplied as an argument to general-search
    		(setq *expand-func* expand-func)
    		...
    		...
    		; call (expand ...) somewhere and it will use the
    		; desired (depth-check-expand ...) function.
    
    	)
    
    	....
    
    	(defun ids (state)
    		(general-search state 'depth-check-expand)
    	)
    
    	....
    
    	(defun dfs (state)
    		(general-search state 'vanilla-expand)
    	)
    
    	....
    
    
Date: 10/25 Title: Program 2 guideline
Here's a quick guide to get you started on program#2. Because you can work on so many different aspects of the provided problem, it may not be entirely clear where to begin. Following the steps given below will give you a head-start:
  1. Node vs. state:
    The first matter is to distinguish between a node and a state. A node is a super-structure, containing extra information in addition to the game-board's state. Look carefully the arguments of the function. If you see state, provide a state. If you see node, provide a node.
  2. Implement (expand ....):
    First, implement a simple expand function, where a node is taken as an argument. The result is a list of child nodes.

    For each operator in 'up, 'down, 'left, 'right, you should go through a series of tests before actually expanding:

    • Is the operator applicable?
    • Is the resulting state a duplicate state?
    • Does the child node go over the depth- or the f-limit? (only applies to DLS, IDS, and IDA*; ignore this at first).
    Collect the new nodes by running (apply-op ...) and putting those into a list:
    (setq return-list nil)
    ...
    ... run checks ...
    ; apply operator, and use cons to paste it to the return-list
    (setq return-list (cons (apply-op ....) return-list))
    ...
    Finally, return that list as a result of (expand ....).
  3. Using the expand function, either get dfs or bfs to work.
    BFS is easier to test. Modify dfs-core to use your expand function and to take in initial state as necessary. Provide input that would only take 2 to 3 moves to reach the goal. Start from the goal state, and move the blank 2 to 3 times, and use that resulting state as the initial state.
Date: 10/14 Title: Program 2 skeleton codes
See http://courses.cs.tamu.edu/choe/03fall/src/ for program 2 skeleton codes. There are four files:
  1. dfs.lsp: a simple depth-first search (fully functional). (Hint: Try modifying a single line in dfs-core to turn this into breadth-first. Answer is given in the code.)
  2. eight-util.lsp: eight-puzzle utility functions (apply operator, etc.)
  3. eight-util.txt: usage information for eight-util.lsp.
  4. eight-interface.lsp: a file outlining how the functions should be named for different search methods.
Date: 10/13 Title: Homework 2 Q and A
> hi, on the home work problem 1.2, when i assign alpha values to the nodes
> and its subsequent children, does the alpha value from the root trickle down
> to each level and does the beta value initialize at infinity for each level?

	Only at the root you initialize the alpha and beta values.
	You can only update your alpha if you're a max node, and
	this is based on your children's returned v values.
	If you're a min, you can update your beta value based on
	your children's return value. When you call upon your children,
	you provide them with your alpha and beta values.

	Note that the only way your parent can influence your
	alpha/beta value is when they call you and pass along
	their alpha/beta values.
>
> also, for question 2.2 question 1, i got the answer as  XXXXXXXXXX is this
> correct? and is question 2 just simply XXXXXXXXX?

	I cannot give out the answer.
	There are many logically equivalent forms and your
	expressions may be one of those. Try converting yours into
	logically equivalent forms (such as contrapositive:
	A->B <=> ~B->~A) and see if it makes sense given the
	natural language sentences.


> also, for question 2.3 number 1 (the one with the resolution) is it correct
> to have the negation of the desired conclusion be (not (D V E)) which is
> equal to (not D ^  not E)?

	~ (E \/ D) <=> ~E /\ ~D, so, yes, you're right.
	In this case, note that you have two clauses:

		~E
		~D


> also, will you be in your office in the morning?

	Not very likely.

Date: 10/1 Title: Homework 1 more clarifications
Some part of homework 1 was still unclear even after the clarification posted yesterday:

  1. Problem 2: Nodes (A), (B), (C), and (D) are the goal nodes.

  2. Problem 2: The depth of the root node is 0, thus the first level of children would be at depth 1. In all of the trees in Figure 1, since the last level is depth n, the height of the whole tree is n+1.

  3. Problem 2: For the third and the fourth bullets, you don't need to reduce the formula into a single number.

  4. Problem 3: In the graph, the numbers on each edge (the directed arrow) is the path cost from the source node to the destination node. For example, (b) to (e) costs 10. However, this is not the same as g(e). There are three ways to reach (e), and for these three cases, the path cost g(e) differs significantly:
    • (S) -> (a) -> (e) : g(e) = cost(S->a) + cost(a->e) = 12 + 6 = 18
    • (S) -> (b) -> (e) : g(e) = cost(S->b) + cost(b->e) = 15 + 10 = 25
    • (S) -> (c) -> (e) : g(e) = cost(S->c) + cost(c->e) = 1 + 25 = 26
    In these above cases, the corresponding f(e) values are then:
    • (S) -> (a) -> (e) : f(e) = g(S to a to e) + h(e) = 18 + 7 = 25
    • (S) -> (b) -> (e) : g(e) = g(S to b to e) + h(e) = 25 + 7 = 22
    • (S) -> (c) -> (e) : g(e) = g(S to c to e) + h(e) = 26 + 7 = 33.
    Note that h(e) are the same because there's only one (e) node.

  5. Problem 4:
    • [Q] How do I show how the node list was updated? I am not sure what you mean.
    • [A] The node list begins with (S) in it. You take it out, check whether it's the goal, and if not, you expand it and put the expanded nodes in the node list using whatever your queueing function is. Show the result of this node insertion operation whenever that happens. For example, if it was breadth-first:
      +-----------------------------------
      + (S)
      +-----------------------------------
      
      (S) taken out and expanded to (a), (b), (c)
      
      +-----------------------------------
      + (a) (b) (c)
      +-----------------------------------
      
      (a) taken out and expanded to (d) and (e)
      
      +-----------------------------------
      + (b) (c) (d) (e)
      +-----------------------------------
      
      ...
      
      
Date: 9/30 Title: Homework 1 clarifications
Some problems in homework 1 were unclear, so see below for clarifications.

  1. Problem 2, first bullet:
    • ... identical time and space complexity? (Tree 1, ...) should be fixed to identical time complexity? (Tree 1, ...) (i.e., drop space).

  2. Problem 2, third bullet:
    • Get rid of the 1st question: In which case do depth-first and breadth-first show the same time and space complexity? (Tree 1, 2, or 3) (4pts).
    • Solve the question for Tree 3.

  3. Problem 3, third bullet:
    • [Q] What is a dominant heuristic? It's not in the textbook.
    • [A] See slide04, page 17.

  4. Problem 3, regarding the Hint:
    • [Q] What do you mean by draw a full tree and why is that useful?
    • [A] If you look at the graph, you can reach a certain node through many different paths. However, for each path, the cost to reach that node differs, so it's not clear how which path cost to use as the g(n). For example, to reach node (e), you can either go through (S)->(a)->(e), (S)->(b)->(e), or (S)->(c)->(e), and the costs are 18, 25, and 26, respectively. You can avoid this problem by generating a tree from the graph, by duplicating the nodes. For example:
      
      		S
      	    /   |   \
      	  /     |     \
      	a	b	c
             / \     / \     / \ 
           d    e   d   e   e   f
        	  
      	  |       |   |
      	  v       v   v 
              g=18    g=26  g=26	: the (e) nodes will have different g(n).
      
      		...
      
      
Date: 9/30 Title: Typos in slide06 / Prog2 due date change
There were two typos in slide06.
  1. Page 5: Second bullet, first item
    Only Beta is updated with the MAX of succesors

    --> fix the underlined to MIN of succesors

  2. Page 20: Programming assignment 2 due date
    Due date is not 10/14, but 10/30 (see the weekly schedule, which had it listed correctly).
Date: 9/25 Title: Using TRACE to debug recursion
Here's an example of how you should use (trace ...) to track the function calls and the return values. It becomes very handy when you're debugging recursive functions.
CMU Common Lisp CVS Head 2003-07-01 16:23:01, running on unix
With core: /usr/local/lib/cmucl/lib/lisp.core
Dumped on: Tue, 2003-07-01 16:01:00-05:00 on empic5
See  for support information.
Loaded subsystems:
    Python 1.1, target UltraSparc/Solaris 7
    CLOS based on Gerd's PCL 2003/06/18 09:23:09
* (load "deriv.lsp")

; Loading #p"/user/choe/web_project/420/deriv.lsp".
T
* (trace deriv)			<--- Trace calls to deriv
; 

; Warning: This function is undefined:
;   DERIVMULT
; 
(DERIV)

* (trace derivplus)		<--- Trace calls to derivplus

(DERIVPLUS)
* (trace splus)			<--- Trace calls to splus

(SPLUS)
* (deriv '(+ (+ x 2) (+ 2 x)) 'x)   <---- Call deriv!

  0: (DERIV (+ (+ X 2) (+ 2 X)) X)	   <---- shows how the functions are
    1: (DERIVPLUS (+ (+ X 2) (+ 2 X)) X)	 called, with their full
    1: DERIVPLUS returned (+ (+ 1 0) (+ 0 1))	 arguments! You can easily
  0: DERIV returned (+ (+ 1 0) (+ 0 1))		 track what's going wrong
(+ (+ 1 0) (+ 0 1))				 by looking at the arguments
* (quit)					 and the returned values.
Date: 9/25 Title: Problem with simplification

Question

Some of my results never get simplified even though it works most of the case. What's wrong?

Answer

Most likely, your input expression itself contains some of the reducable expressions such as (+ 0 x) or (/ 0 x). If this is part of a multiplication, then the problem might occur. This is because unless (deriv ...) is called, recursively on that expression, (splus ...) etc. will never be called.

For example, consider the following expression:


(deriv '(* (+ 0 x) (+ x x)) 'x)

This is just

(+  (* (deriv '(+ 0 x) 'x) '(+ x x))
    (* '(+ 0 x) 'x) 	   (deriv '(+ x x) 'x))
) 

so the bold part will not go through (splus ...).

To avoid this, you may assume that all input expressions are maximally simplified. In the case above, the input should have been


(deriv '(* x (+ x x)) 'x) .

Date: 9/25 Title: Example expressions and a problem with SMINUS

Question 1:

What do you mean by "examples with at least four terms?"

Answer 1:

It was a bit unclear, so just replace "terms" with "operators". So, that should now read "examples with at least four operators". If you already submitted, then that's okay. You won't be penalized for deviating from this requirement, but you should have provided 10 examples in whatever form.

Question 2:

How do I simplify (- 0 (* x x))? That is, when the 1st argument 0 and the second argument is an expression (i.e., a list)?

Answer 2:

Well, it's difficult to reduce given the current spec. If unary minus was allowed, (- (* x x)) would be the answer, but since that is not specified in the program assignment, you may just return (- 0 (* x x)). On the other hand, you can simplify (- (* x x) 0) to (* x x), and you should do this.
Date: 9/24 Title: How to check if something contains a single symbol or not?

Question

How do I check whether something is a symbol or not? Say I want to check if the content of x is a number or an expression, etc.

Answer

Use the predicate (atom ....), which is already in the skeleton code.

	* (atom 1) 
	T
	
	* (atom 'x)
	T

	* (setq x '(1 2 3))
	(1 2 3)

	* (atom x)
	NIL
Date: 9/24 Title: Division by zero

Question

Do I need to handle division-by-zero errors when implementing deriv-div ?

Answer:

No, you don't need to. Assume that the inputs are well-behaved.
Date: 9/23 Title: Why do we need splus?

Question

>
> I have a question about our homework assignment.  I am confused about the
> purpose of the splus function.  Also, if the skeleton version of derivplus
> works without it, then why does it need to be added?  Thanks!
>

Answer

Splus is used to simplify the resulting expression.

The function deriv-plus returns

        (list '+   )

Let's say

        (list '+ 0 'x)

was returned, resulting in

        (+ 0 x) .

But this is actually just "x", so replacing (list ...) with (splus ...)
will get you a simpler expression. Think how you should replace (list ...)
with (splus ...).

Date: 9/22 Title: How to use the "turnin" command
How to use the turnin command:

The turnin folder 420-502 has been created.


unix$ turnin		<-- to print turnin usage
Usage:
To submit files:                   turnin foldername file1 file2 ...
To list your files in foldername:  turnin -c foldername
To list all possible folders:      turnin -f



unix$ turnin -c 420-502	<-- to list the files you submitted
Files in folder /pub/homework/420-502 belonging to choe:
(No files found)


unix$ turnin  420-502 test  <-- I submitted file "test"
test was copied.


unix$ turnin -c 420-502	   <-- now check if it got submitted
Files in folder /pub/homework/420-502 belonging to choe:
-rwx------   1 netadmin cpsc420        0 Sep 22 09:29 choe-test

Note that when you turn in a file, "your-username-" will be automatically added to the beginning of the file so that you won't accidentally overwrite someone else's file.
Date: 9/16 Title: Downloading the skeleton file
To download the skeleton file, follow the procedure below (unix$ is the unix prompt; you type in the commands in bold).
  1. Create a subdirectory where you will put your programs:
    	unix$ mkdir 420-prog1
    	unix$ cd 420-prog1
    
  2. Download the file using lynx, a text web browser (NOTE: this command will OVERWRITE deriv.lsp, if that file already exists, so be careful):
    unix$ lynx -source http://courses.cs.tamu.edu/choe/03fall/src/deriv-skel.lsp > deriv.lsp
    
  3. Run lisp, and load deriv.lsp:
    unix$ lisp
    ...
    * (load "deriv.lsp")
    ...
    * (deriv '(+ x (+ x 2)) 'x)
    ...
    *
    
Date: 9/16 Title: Error loading a lsp file
When you write a lisp program file and (load "filename.lsp"), sometimes it will cause an error message. This happens most likely when you miss one or more parentheses.

First, read the message, and try to figure out which function caused the error. If you cannot find out, you can start copy-and-pasting each function into an interactive lisp session:


+-----------Editor-----------+		+---------Lisp-------------+
|                            |          |                          |
|                            |          |* (defun ...              |
|; my square                 |\         |                          |
|(defun mysquare (x)         | }---->   |...                       |
|       (* x x))             |/         |                          |
|                            |          |                          |
|                            |          |MYSQUARE                  |
|                            |          |                          |
|                            |          |*                         |
|                            |          |                          |
+-----------Editor-----------+		+---------Lisp-------------+

If lisp does not echo back your function name (e.g., MYSQUARE above), then you know there's an error in that function.

In editors like emacs or vi, you can match the parentheses:

  1. In emacs, use M-x lisp-mode where M-x means [Alt]-[x]. Typing the matching pair at the end will automatically bring you to the beginning one and back to the last one you just typed.
  2. In vi, press on % on one parenthesis to go back and forth between the matching parenthesis.
Date: 9/11 Title: Writing program files and loading
[Q] How do I view the listing of my code in the lisp shell (or listner, in technical terms) and edit it?

[A] You don't edit it in the lisp shell -- you write a program file containing the function definitions, and use (load "filename") to load it, and test it.

File: test.lsp


	(defun mysqr (x) 
		(* x x)
	)

Save that in a file, and run lisp, and there type ('*' is the lisp prompt):


	* (load "test.lsp")

Then, type in:

	* (mysqr 10)

If there was a bug in your program, edit it, and reload it using


	* (load "test.lsp")

and test again by running
	* (mysqr 10)
Date: 9/11 Title: Typos in the slide
There were some typos in the slides:
  1. slide02.pdf, page 34: the bold part below should be added.
    (deriv '(+ (* x 10) (+ 25 x)) 'x)
       (list 
           '+ 
           (deriv '(* x 10) 'x) 
           (deriv '(+ 25 x) 'x)
       )
    
  2. slide02.pdf, page 35: the bold part below should be added.
    (deriv '(* (+ 14 x) (* x 17)) 'x)
      (list 
         '+ 
         (list '* (deriv '(* 14 x) 'x) '(* x 17))
         (list '* '(+ 14 x) (deriv '(* x 17) 'x)) 
      )
    
Date: 9/11 Title: List of functions
[Q] How do I view a list of all user defined functions and variables?

[A] I wasn't able to find out -- check out CMUCL Documentation page for a hint. I don't think such a command will be necessary though.

Date: 9/3 Title: Unix basics
I. Basic commands:

CSG helpdesk has a nice introduction to unix commands: UNIX - Basic Commands. If you're not familiar with the unix environment, take a look at this page.

For other useful information on unix, see the CSG Helpdesk, Unix section.

II. Editing:

The simplest editor you can use is Pico. See the helpdesk page on Pico. If you want to tackle the real thing, either use vi (helpdesk info) or emacs (helpdesk info).

Date: 9/3 Title: Lisp starter
Here's an example which will help you get started wetting your hands in Lisp. The commands in Bold are what you're supposed to type in. My comments are in Italics - YC.
  • CMU Common Lisp is installed in /usr/local/bin/lisp:
    Example:
    
    unix$ /usr/local/bin/lisp 	<-- 'unix$' is the unix prompt
    CMU Common Lisp CVS Head 2003-04-21 16:23:29, running on unix
    With core: /usr/local/lib/cmucl/lib/lisp.core
    Dumped on: Mon, 2003-04-21 15:40:49-05:00 on empic5
    See  for support information.
    Loaded subsystems:
        Python 1.1, target SPARCstation/Solaris 2
        CLOS based on Gerd's PCL 2003/03/22 16:15:17
    * 					<-- '*' is the lisp prompt
    
    
  • To quit from lisp, enter (quit)
    Example:
    
    CMU Common Lisp CVS Head 2003-04-21 16:23:29, running on unix
    With core: /usr/local/lib/cmucl/lib/lisp.core
    Dumped on: Mon, 2003-04-21 15:40:49-05:00 on empic5
    See  for support information.
    Loaded subsystems:
        Python 1.1, target SPARCstation/Solaris 2
        CLOS based on Gerd's PCL 2003/03/22 16:15:17
    * (quit)			<-- your input 
    unix$				<-- the unix prompt 
    
  • If you caused an error and it doesn't seem to work, enter q to go back up to the top-level.
    Example:
    
    CMU Common Lisp CVS Head 2003-04-21 16:23:29, running on unix
    With core: /usr/local/lib/cmucl/lib/lisp.core
    Dumped on: Mon, 2003-04-21 15:40:49-05:00 on empic5
    See  for support information.
    Loaded subsystems:
        Python 1.1, target SPARCstation/Solaris 2
        CLOS based on Gerd's PCL 2003/03/22 16:15:17
    * adf;lakjf		<--- your erroneous input
    
    Error in KERNEL::UNBOUND-SYMBOL-ERROR-HANDLER:  the variable ADF is unbound.
    
    Restarts:
      0: [ABORT] Return to Top-Level.
    
    Debug  (type H for help)
    
    (EVAL ADF)
    Source: Error finding source: 
    Error in function DEBUG::GET-FILE-TOP-LEVEL-FORM:  Source file no longer exists:
      target:code/eval.lisp.
    0] q			<--- '0]' is the prompt
    
    *				<--- lisp prompt  
    
    
    
Date: 9/1 Title: No articles
Nothing here yet.

$Id: board.php,v 1.4 2003/09/04 21:56:27 choe Exp $