The Scheme reports do not require that the procedure equal? terminate when the input is looped, as can happen with set-car! and such. Below is a simple implementation of an Equal? that is guaranteed to return #t or #f even for looped structures.

This algorithm occurs in the two level grammar for Algol 68 where it is used to test for equivalence of types.

(define (Equal? a b) 
  (let e ((a a)(b b)(h '()))(or (let be ((s h))(and (pair? s)
   (or (and (eq? a (caar s))(eq? b (cdar s)))(be (cdr s)))))
 (let ((h (cons (cons a b) h))) (or
  (eqv? a b)
  (and (pair? a)(pair? b) (e (car a)(car b) h)(e (cdr a)(cdr b) h))
  (and (vector? a)(vector? b) (let ((k (vector-length a)))(and
    (= k (vector-length b))
    (let x ((n (- k 1))) (or (negative? n)
     (and (e (vector-ref a n)(vector-ref b n) h) (x (- n 1)))))))))))))

; Trivial tests
(define a '(2 3 4))
(set-cdr! (cddr a) a)
; (2 3 4 2 3 4 ...)
(define b '(2 3 4 2 3 4))
(set-cdr! (cddr (cdddr b)) b) ; b -> (2 3 4 2 3 4 2 3 4 ...)
(Equal? a b)  ; -> #t

(define c '(2 2 2))
(define d '(2 2 3))
(set-cdr! (cddr c) c)
(set-cdr! (cdr d) d)
(Equal? c d)  ; -> #t
; both print as (2 2 2 2 2 ...)
(Equal? c (cdr c)) ; -> #t