(define Gu '( (c1 n) (c1 y) (n  y) 
              (c2 n) (c2 y) (y  e)
              (e  u) (u  i) (i  l)
              (l  e) (c1 s)  ) )

(define (nodes G)
  (remove-duplicates (foldr append '() G)))

(define (remove-duplicates L)
  (cond
    ((null? L) L)
    ((member (first L) (rest L)) (remove-duplicates (rest L)))
    (else (cons (first L) (remove-duplicates (rest L))))))

(define (kids n G)
  (map second (filter (lambda (e) (equal? n (first e))) G)))

(define (parents n G)
  (kids n (map reverse G)))

(define (gkid gp gk G)
  (let ((ks (kids gp G)))
    (if (member gk (foldr append '() (map (lambda (n) (kids n G)) ks)))
        #t
        #f)))

(define (reach a b G)
  (reach-help b (list (list a)) G))

(define (reach-help dst path-list G)
  (if (null? path-list)
      #f
      (let ((active-path (first path-list))
            (remaining-paths (rest path-list)))
        (if (equal? (first active-path) dst)
            #t
            (let ((new-pl (append remaining-paths 
                                  (build-p active-path G))))
              (reach-help dst new-pl G))))))

(define (build-p path G)
  (let* ((ks (kids (first path) G))
         (new-paths (map (lambda (n) (cons n path)) ks)))
    (filter (lambda (path) (not (member (first path) (rest path))))
            new-paths)))

      