Jae
Jae

Reputation: 39

Why is this function returning true when it should be returning false?

So, I have this helper function that checks to see if there is a reflexive relationship between a list and a list of pairs.

(define helper
  (lambda (L S)
    (cond
      ((if (equal? L '()) #f ;; here, when L equals empty list, it should return #f, but somehow it returns #t even if L is '().
          (if (equal? S (car (car L)))
              (if (list-equal? (car L))#t
                  (helper (cdr L) S))
              (helper (cdr L) S))))
          )))

However, the part where it checks if L is an empty list returns true even if the list is an empty list, allowing my other function to return true. I've been stumped trying to figure out why its returning #t instead of #f for hours. Please help me figure out what's making this happen. Oh and I'm using Dr.Racket version 6.12.

EDIT: more clearly, I would like the function to return #f when L is '() as a base case so that the function doesn't need to do anymore recursion.

Upvotes: 0

Views: 542

Answers (2)

Sylwester
Sylwester

Reputation: 48745

You have nested if in cond. Lets rewrite you code som something identical:

(define helper
  (lambda (L S)
    (let ((result
           (if (equal? L '())
               #f
               (if (equal? S (car (car L)))
                   (if (list-equal? (car L))
                       #t
                       (helper (cdr L) S))
                   (helper (cdr L) S)))))
      (cond
        (result result)
        (else 'implementation-defined-value)))))

A cond will return a implementation defined value as the else clause should none of the previous predicates hit. Since your base casse returns #f it goes to the default else case.

Since the other answer show the code with cond, here is the same with if:

(define helper
  (lambda (L S)
    (if (equal? L '())
        #f 
        (if (and (equal? S (car (car L)))
                 (list-equal? (car L)))
            #t
            (helper (cdr L) S)))))

You can also write this only with and and or:

(define helper
  (lambda (L S)
    (and (pair? L)
         (or (and (equal? S (car (car L)))
                  (list-equal? (car L)))
             (helper (cdr L) S)))))

Upvotes: 0

Gwang-Jin Kim
Gwang-Jin Kim

Reputation: 9865

You put if forms within cond which is quite superfluous. So your mistake was for sure your lack of understanding of the cond syntax. Remember cond syntax goes like:

(cond (condition1 what-to-do-if-condition1-is-true)
      (condition2 what-to-do-if-condition2-is-true)
      ( ...       ...                             )
      (else what-to-do-if-none-of-the-conditions-listed-above-evaluated-to-true))

So I formed your expression accordingly to:

(define helper
  (lambda (L S)
    (cond ((equal? L '()) #f)
          ((and (equal? S (car (car L))) (list-equal? (car L))) #t)
          (else (helper (cdr L) S)))))

Since you didn't gave definition for list-equal? - I cannot run this code for testing.

Upvotes: 4

Related Questions