The assignment was worth 10 pts overall.
No, the existence of intractable or undecidable problems does not mean that AI is impossible. However, it does mean that AI systems should avoid tackling intractable problems "head-on" -- don't try to build an AI system that optimally solves the traveling salesman problem (TSP). Instead, look for a good approximation, perhaps using heuristic rules. Note that people generally don't solve intractable problems either. If it's reasonable to model the brain as a Turing machine (even if that means every neuron is modeled by a Turing machine), then brains are of course bound by the same limitations as Turing machines.
If we take tell quite literally, then it's true that computers can only do what their programmers tell them. Of course, their programmers might tell them to adapt to new situations, or learn by observing others, and thus they could behave in unexpected ways.
You can either have your cake, or you can eat it. Pick one. Perhaps there was confusion because essentially all animals are adaptable to their surroundings (and profoundly so), but many (most?) computer programs do not incorporate adaptability beyond simple branching. You could give different answers to 1.9 and 1.10 if you argued that the mechanism for encodng instructions make a difference, but nobody did.
Although genes specify how animals are constructed, they encode adaptability as well. Thus, animals (including people) are endowed with the ability to adapt to their environment. This ability is so strongly expressed that their often substantial differences between animals with identical genes.
(defun summit (lst)
(apply #'+
(remove nil lst)))
(Why use apply() here? Why not just + ?)
A very common problem here was that people said, "The list isn't actually changed by remove(), so apply() is working with the original (nil's included) list." This isn't actuallywrong, but it hints that people are taking the wrong perspective. Thiws furer evidenced by the proposed solution -- just setf the list to the value of the remove function:
(setf lst (remove nil lst))
Yikes. This is not all functional, and not really necessary becuase you can just the pass the value of the remove() function directly to apply(), as in the solution. This time, I didn't dock anybody points for this. Next time....
The problem in a nutshell is this: nil is a list, and its car() and cdr() are both nil. Thus, there is no base case for the recursion. The code "cdr's down the list" (to use the Lisp terminology), but doesn't recognize that it eventually cdr's to the null list, and so loops forever. The correct function is:
(defun summit (lst)
(if (null lst)
0
(let ((x (car lst)))
(if (null x)
(summit (cdr lst))
(+ x (summit (cdr lst)))))))
Some people moved the check for a null list into the body of the let, but this has two problems. First, it goes against the standard recursion template where one handles the base case before taking the recursive step. Second, it wastes time and resources. If the list is null, there's no sense assigning the car of the list to a variable for possible later testing.