Following code from http://htdp.org/2003-09-26/Book/curriculum-Z-H-38.html#node_chap_30 does'nt seem to be working (I have added println statements for debugging)
(define (neighbor a-node sg)
(println "in neighbor fn")
(cond
[(empty? sg) (error "neighbor: impossible")]
[else (cond
[(symbol=? (first (first sg)) a-node)
(second (first sg))]
[else (neighbor a-node (rest sg))])]))
(define (route-exists? orig dest sg)
(println "in route-exits? fn")
(cond
[(symbol=? orig dest) true]
[else (route-exists? (neighbor orig sg) dest sg)]))
I also tried the second version (I have added contains fn):
(define (contains item sl)
(ormap (lambda (x) (equal? item x)) sl) )
(define (route-exists2? orig dest sg)
(local ((define (re-accu? orig dest sg accu-seen)
(cond
[(symbol=? orig dest) true]
[(contains orig accu-seen) false]
[else (re-accu? (neighbor orig sg) dest sg (cons orig accu-seen))])))
(re-accu? orig dest sg empty)))
Following example from that page itself creates infinite loop:
(route-exists? 'C 'D '((A B) (B C) (C E) (D E) (E B) (F F)))
Following produces #f even though solution is clearly possible:
(route-exists2? 'C 'D '((A B) (B C) (C E) (D E) (E B) (F F)))
Following tests (lists are mine) produce errors here also even though solution is clearly possible:
(route-exists?
'A 'C
'('('A 'B) '('B 'C) '('A 'C) '('A 'D) '('B 'E) '('E 'F) '('B 'F) '('F 'G) )
)
(route-exists2?
'A 'C
'('('A 'B) '('B 'C) '('A 'C) '('A 'D) '('B 'E) '('E 'F) '('B 'F) '('F 'G) )
)
Where is the problem and how can this be solved?
Edit:
Even after choosing the new function and remove excess quotes, following does not work (even though there is a direct path between A and D):
(route-exists2?
'A 'D
'((A B) (B C) (A C) (A D) (B E) (E F) (B F) (F G) ) )
It outputs an error:
neighbor: impossible
For the first case:
Following example from that page itself creates infinite loop:
(route-exists? 'C 'D '((A B) (B C) (C E) (D E) (E B) (F F)))
In the page you linked, ten lines after the definition of the function, it is clearly said:
The hand-evaluation confirms that as the function recurs, it calls itself with the exact same arguments again and again. In other words, the evaluation never stops.
So, it is exactly the behaviour that you have observed.
For the second case:
Following produces #f even though solution is clearly possible:
(route-exists2? 'C 'D '((A B) (B C) (C E) (D E) (E B) (F F)))
Four lines after the definition of the first function, it is clearly said:
Take another look at figure 85. In this simple graph there is no route from C to D.
So, the function must return correctly #f
, as it does, since there is no route from C to D (remember that the arcs are oriented, in fact, before the example, it is clearly said: “... each node has exactly one (one-directional) connection to another node”).
Finally, in your last two examples:
Following tests (lists are mine) produce errors here also even though solution is clearly possible:
(route-exists? 'A 'C '('('A 'B) '('B 'C) '('A 'C) '('A 'D) '('B 'E) '('E 'F) '('B 'F) '('F 'G) ) )
(route-exists2? 'A 'C '('('A 'B) '('B 'C) '('A 'C) '('A 'D) '('B 'E) '('E 'F) '('B 'F) '('F 'G) ) )
Your are quoting too much, so that you are giving to the function a data which is different from what is required.
Remember that 'X
is an abbreviation for (quote X)
. This means that your last parameter is not a correct graph, since it is equal to:
((quote (quote A) (quote B)) (quote (quote B) (quote C)) ...)
and not to
((A B) (B C) ...)
Added
This is the answer to the last question:
Even after choosing the new function and remove excess quotes, following does not work (even though there is a direct path between A and D):
(route-exists2? 'A 'D '((A B) (B C) (A C) (A D) (B E) (E F) (B F) (F G) ) )
It outputs an error:
neighbor: impossible
In the page that you linked, in the first paragraph of section “A Problem with Generative Recursion", it is clearly said:
Here we study the slightly simpler version of the problem of simple graphs where each node has exactly one (one-directional) connection to another node.
Since your graph has more than one connection from a node (for instance A is connected to B, C, and D, etc.), in this case the program does not work.
You can see immediately the reason if you consider the function neighbor
: it finds the first node connected to a certain node, without considering all the other nodes. So, for instance, from A
the only neighbor
returned is B
, which is not connect directly or indirectly to D
, and so the function route-exists2?
replies (correctly, according to the specification) that there is no such route.