Given a new implementation of tree in Scheme using list:
(define make-tree list)
(define add-subtree cons)
(define make-leaf (lambda (x) x))
(define empty-tree? empty?)
(define first-subtree car)
(define rest-tree cdr)
(define composite-tree? list?)
(define leaf? (lambda (x) (not (composite-tree? x))))
Implement the CPS procedure equal-tree$ which receives a pair of leaf-valued trees, t1 and t2, and two continuations: succ and fail and determines their structure identity as follows:
if
t1andt2have the same structure, equal-tree$ returns a tree with the same structure, but where each leaf contains a pair with the leaves of the original two trees at this position(no matter whether their values agree or not).Otherwise, equal-tree$ returns a pair with the first conflicting sub-trees in depth-first traversal of the trees.
for example:
(define id (lambda (x) x))
(equal-trees$ '(1 (2) (3 9)) '(7 (2) (3 5)) id id) ---> '((1 . 7) ((2 . 2)) ((3 . 3) (9 . 5)))
I tried my best to solve this question but I encountered a bug and hopefully some can help me fixing it.
This is my try:
(define equal-tree$
(lambda (tree1 tree2 succ fail)
(if (and (empty? tree1) (empty? tree2))
'()
(if (or (empty? tree1) (empty? tree2))
(fail '())
(if (and (leaf? tree1) (leaf? tree2))
(succ (cons tree1 tree2))
(if (or (leaf? tree1) (leaf? tree2))
(fail (cons (car tree1) (car tree2)))
(equal-tree$ (car tree1) (car tree2)
(lambda (X) cons(cons (car tree1) (car tree2)) x) fail)))))
)
)
And here is the output for the example above (I just don't know why it prints '(1 . 7) ... :
'(1 . 7)
You have a reasonable-looking sequence of
iftests (though usingcondinstead would be more idiomatic Scheme). But the values you return do not generally look correct.The first problem I see is in your first
ifclause. If both trees are empty, you return'(). But according to the spec, you should be calling thesuccfunction with that result. This may look unimportant if you useidas your continuation, but note that each recursive step builds up a more detailedsucccontinuation, so in generalsuccmay be a quite impactful function.The second
ifis also a problem. Again you return'(), when you are supposed to return the first conflicting subtrees. It's not clear to me what that means, but it would be reasonable to pass a pair oftree1andtree2tofail.The third and fourth clause look fine. You call
succwith a pair of the two leaves, as expected.The recursive call is clearly wrong: you have mis-parenthesized calls to
cons, and your lambda variable is namedXbut you refer to it asx. The series ofconscalls doesn't really look right either, but you can experiment with that once your more pressing syntactic issues are resolved and your base cases work properly.Lastly, you are doing a lot of low-level work with
cons,car,'(), and so on. You should be using the abstract functions provided to you, such asadd-subtreeand(make-tree), instead of using the low-level primitives they are built on.