Kiley
Kiley

Reputation: 39

first: contract violation error in racket/scheme for printing out a combination of list procedures

I was writing a procedure that takes 2 expressions, and if there is a way for exp1 to be created through exp2 (when we replace exp2 with 'sss) using first, rest, cons, it then returns the code needed to produce exp1.

For example, this is what I would want to produce.

(find-in '(e r t) '(e t) ) => '(cons (first sss) (rest (rest sss)))

My code works for a lot of the test cases but when I ran through

(find-in '(a '(((v)) l) (f g)) '( (v g) l a))

It returns this error:

first: contract violation
  expected: (and/c list? (not/c empty?))
  given: 'g

The same error shows up when I try running this test case:

(find-in '(x a (x y)) '(z a (b))) 
;supposed to return #f

This is my code so far:

(define find-in
  (lambda (exp2 exp1)
    (cond
      ((equal? exp2 exp1) 'sss)
      ((null? exp2) #f)
      ((not (list? exp2)) #f)
      ((find-in (first exp2) exp1) (repl 'sss '(first sss) (find-in (first exp2) exp1)))
      ((find-in (rest exp2) exp1) (repl 'sss '(rest sss) (find-in (rest exp2) exp1)))
      (else (list? exp1)
            (if
             (and (find-in exp2 (first exp1)) (find-in exp2 (rest exp1)))
             (list 'cons (find-in exp2 (first exp1)) (find-in exp2 (rest exp1)))
             #f) #f))))

I am confused as to which condition I missed when I coded or if there was a logic error. What could have gone wrong?

Upvotes: 0

Views: 1289

Answers (1)

amalloy
amalloy

Reputation: 91837

Your last clause doesn't look right to me. When you use the special else token for your last clause, you are saying "There's nothing to test here, execute the body of this unconditionally if you've made it this far". Thus, your next expression, (list? exp1), is not a test as far as cond is concerned: it is evaluated for side effects, and the results discarded. Then the next expression is also evaluated, whether exp1 was a list or not.

If you want to make this conditional on whether exp1 is a list, you should remove the excess else at the beginning (and probably add an else clause to the end to return #f if none of your cases matched).

Upvotes: 1

Related Questions