user3129475
user3129475

Reputation: 95

Scheme function doesn't return value

Here is what the function should do:

I am giving it list of "pairs" that look like (((a . b) . c) ((a . b) . c) ((a. b) . c) ...) where:

a means if the vertex is visited 1 for yes 0 for no

b means what is the value of the shortest path to the vertex so far (if it is -1 it is infinity)

c is the number of the parent (if it has so far if it doesn't it is the number of the pair if you count the first pair for 1 second for 2 and etc.)

The function should return the number of the next unvisited pair (vertex) with the lowest cost of the path so far. Example: (((0 . 10) . 1) ((0 . 4) . 2) ((1 . 3) . 5) ...) here it should return the number 2.

Here is the code

(define (chooseNextLowest pairs num retV pointer)
  (if (null? pairs)
      retV
      (if (checkIfPairVis (caar pairs)) 
          (chooseNextLowest (cdr pairs) num retV (+ 1 pointer))
          (if (= -1 num) 
              (chooseNextLowest (cdr pairs) (cdaar pairs) pointer (+ 1 pointer))
              (if (not (= -1 (cdaar pairs)))
                  (if (< (cdaar pairs) num) 
                      (chooseNextLowest (cdr pairs) (cdaar pairs) pointer (+ 1 pointer))
                      (chooseNextLowest (cdr pairs) num retV (+ 1 pointer))))))))

I have used some function that are predefined but I think it's clear by their names what they do. I call it with num = -1 , retV = -1 and pointer = 1, since I use -1 for infinity and I am sure retV will be changed at least 1 time because everytime I call this function will be at least 1 unvisited pair.

They work fine also this function seems to work fine when I use it with some testPairs but when I use pairs that are returned from other function (since I have to choose everytime the lowest cost unvisited vertex after I update the information in the pairs) it doesnt return any value.

Maybe you will ask to see the other function too but I can't give it at the moment since if I give it I have to give the whole sorce code to make sense so I hope the mistake is somewhere here but I can't find it.

The other function return normal pairs in the type I want them ((a . b ) . c) and etc.

Thank you very much. I am sure I didn't make some things clear so If you have questions feel free to ask me.

Upvotes: 0

Views: 398

Answers (2)

GoZoner
GoZoner

Reputation: 70135

Your conditional at (if (not (= -1 (cdaar pairs))) ... only has a consequent clause. Without an alternate clause the return of if is undefined (officially). Specifically:

      (if (not (= -1 (cdaar pairs)))
          (if (< (cdaar pairs) num) 
              (chooseNextLowest (cdr pairs) (cdaar pairs) pointer (+ 1 pointer))
              (chooseNextLowest (cdr pairs) num retV (+ 1 pointer)))
           <something here>)))))

Illustrating how if has an undefined return:

> (if #f 'yes 'no)
no
> (if #f 'yes)
>                      ; <= nothing printed as a return, just a prompt displayed.

Upvotes: 0

Sylwester
Sylwester

Reputation: 48745

After formatting the code it's obvious that in the second deepest if you are lacking a alternative. if without alternative is very new in Scheme but:

(if #f 'true) ;; ==> #undefined

Looking at your code, specially checkIfPairVis it seems you do caar and that's ok for the object, but not for the list with an object. The best way to eliminate such things would be to make accessors in your code which also will make your code easier to read:

(define (choose-next-lowest pairs num ret-v pointer)
  ;; accessor based on object
  (define vertex-visited caar)
  (define vertex-shortest cdar)
  (define vertex-parents cdr)

  (if (null? pairs)
      ret-v
      (let ((obj (car pairs)))
        (cond 
          ((check-if-pair-vis (vertex-visited obj))
           (choose-next-lowest (cdr pairs) num ret-v (+ 1 pointer)))
          ...))))

After fixing that accessor I get 2 as you predicted. It could be other things wrong of course. Seems to me you need to debug. In DrRacket IDE you could step through your code to ensure it works as designed.

PS: A named let will add accumulators and variables you don't need to expose:

(define (choose-next-lowest pairs)
  (define vertex-visited caar)
  (define vertex-shortest cdar)
  (define vertex-parents cdr)
  (define (vertex-visited? v)
    (= 1 (vertex-visited v)))

  (let rec ((pairs pairs) (num -1) (ret-v -1) (pointer 1))
    (if (null? pairs)
        ret-v
        (let ((obj (car pairs)))
          (cond 
            ((vertex-visited? obj) (rec (cdr pairs) num ret-v (+ 1 pointer)))            
            ((= -1 num) (rec (cdr pairs) (vertex-shortest obj) pointer (+ 1 pointer)))            
            ((= -1 (vertex-shortest obj)) 'undefined) ;; something wrong here?            
            ((< (vertex-shortest obj) num) (rec (cdr pairs) (vertex-shortest obj) pointer (+ 1 pointer)))
            (else (rec (cdr pairs) num ret-v (+ 1 pointer))))))))


(choose-next-lowest '(((0 . 10) . 1) ((0 . 4) . 2) ((1 . 3) . 5))) ; ==> 2

Upvotes: 2

Related Questions