Pregunta

Estoy tratando de implementar la búsqueda de seguimiento posterior en el esquema. Hasta ahora, tengo lo siguiente:

(define (backtrack n graph assignment)  
    (cond (assignment-complete n assignment) (assignment) )

    (define u (select-u graph assignment))

    (define c 1)
    (define result 0)

    (let forLoop ()
        (when (valid-choice graph assignment c)
             (hash-set! assignment u c)

             (set! result (backtrack n graph assignment))

             (cond ((not (eq? result #f)) result))

             (hash-remove! assignment u)            
        )

        (set! c (+ c 1))
        (when (>= n c) (forLoop))
    )

   #f ; I believe this is where I'm having problems
)

Mis funciones asignación-complete y seleccionar las pruebas unitarias de aprobación. La asignación de argumentos es una fabricación de la tabla de hash con (make-hash), por lo que debería estar bien.

Creo que el problema que tengo está relacionado con devolver falso al final del bucle, si ningún recursivo devuelve un valor no falso (que debería ser una tarea válida). ¿Existe un esquema equivalente a una declaración de devolución explícita?

¿Fue útil?

Solución

La respuesta a tu pregunta es :

(define (foo ...)
  (call-with-current-continuation
    (lambda (return)
      ...... ; here anywhere inside any sub-expression 
      ...... ; you can call (return 42)
      ...... ; to return 42 from `foo` right away
    )))

Esto establece un salida continuación para que pueda devolver un valor de resultado del cuerpo de una función. La forma habitual del esquema es poner su forma de devolución como el último, por lo que se devuelve su valor:

    (let forLoop ()
        (when (valid-choice graph assignment c)
             (hash-set! assignment u c)
             (set! result (backtrack n graph assignment))
             (cond
                 ((not (eq? result #f))
                   result))       ; the value of `cond` form is ignored
             (hash-remove! assignment u))
                                  ; the value of `when` form is ignored
        (set! c (+ c 1))
        (if (>= n c)     ; `if` must be the last form 
           (forLoop)     ; so that `forLoop` is tail-recursive
           ;; else:
           return-value) ; <<------ the last form's value 
    )                    ; is returned from `let` form

   ;; (let forLoop ...) must be the last form in your function
   ;;                   so its value is returned from the function
)

También tienes un problema aquí:

(cond (assignment-complete n assignment) (assignment) )

Este código lo hace no Haz una llamada (assignment-complete n assignment). Más bien, verifica si una variable assignment-complete tiene un valor no nulo, y si no se verifica assignment variable, pero en cualquier caso su valor devuelto se ignora de todos modos. Quizás faltan más paréntesis allí, y/o un else cláusula.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top