Remember that Sussman's goal for that text was not necessarily physics but this:
> "The task of formulating a method as a computer-executable program and debugging that program is a powerful exercise in the learning process. Also, once formalized procedurally, a mathematical idea becomes a tool that can be used directly to compute results." Sussman and Wisdom, with Meinhard Mayer, have produced a textbook, Structure and Interpretation of Classical Mechanics, to capture these new ideas."
I do most of my work in Prolog but of course Sussman prefers Lisp or Scheme deriving from the Abelson&Sussman text on Lisp programming.
Here is a comparison of a Sussman algorithm in Lisp and then my version in Prolog
> The [following puzzle](https://mitpress.mit.edu/sicp/full-text/sicp/book/node90.html) (taken from Dinesman 1968) is typical of a large class of simple logic puzzles:
> Baker, Cooper, Fletcher, Miller, and Smith live on different floors of an apartment house that contains only five floors. Baker does not live on the top floor. Cooper does not live on the bottom floor. Fletcher does not live on either the top or the bottom floor. Miller lives on a higher floor than does Cooper. Smith does not live on a floor adjacent to Fletcher's. Fletcher does not live on a floor adjacent to Cooper's. Where does everyone live?
We can determine who lives on each floor in a straightforward way by enumerating all the possibilities and imposing the given restrictions: [*]
(let ((baker (amb 1 2 3 4 5))
(cooper (amb 1 2 3 4 5))
(fletcher (amb 1 2 3 4 5))
(miller (amb 1 2 3 4 5))
(smith (amb 1 2 3 4 5)))
(distinct? (list baker cooper fletcher miller smith)))
(require (not (= baker 5)))
(require (not (= cooper 1)))
(require (not (= fletcher 5)))
(require (not (= fletcher 1)))
(require (> miller cooper))
(require (not (= (abs (- smith fletcher)) 1)))
(require (not (= (abs (- fletcher cooper)) 1)))
(list (list 'baker baker)
(list 'cooper cooper)
(list 'fletcher fletcher)
(list 'miller miller)
(list 'smith smith))))
Evaluating the expression (multiple-dwelling) produces the result
((baker 3) (cooper 2) (fletcher 4) (miller 5) (smith 1))
And here is my version in Prolog, which I didn't transcribe from his Lisp but directly from the textual description of the problem.
floors_live(Baker, Cooper, Fletcher, Miller, Smith) :-
all_distinct([Baker, Cooper, Fletcher, Miller, Smith]),
Baker \= 5,
Cooper \= 1,
Fletcher \= 5, Fletcher \= 1,
Miller > Cooper,
abs(Smith - Fletcher) > 1,
abs(Fletcher - Cooper) > 1.