Question

J'essaie d'implémenter la recherche de back-suivi dans le schéma. Jusqu'à présent, j'ai ce qui suit:

(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
)

Mes fonctions Affectation-Complete et SELECT-U Pass Unit Tests. L'attribution d'argument est une marque de table de hash avec (make-hash), donc ça devrait être bien.

Je crois que le problème que j'ai est lié au retour false à la fin de la boucle, si aucun récursive ne renvoie une valeur non-fondation (qui devrait être une affectation valide). Existe-t-il un schéma équivalent d'une instruction de retour explicite?

Était-ce utile?

La solution

La réponse à votre question est oui:

(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
    )))

Cela met en place un sortir continuation afin que vous puissiez renvoyer une valeur de résultat de l'intérieur du corps d'une fonction. Le moyen habituel du schéma consiste à mettre votre formulaire de retour comme le dernier, donc sa valeur est renvoyée:

    (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
)

Vous avez également un problème ici:

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

Ce code fait ne pas passer un coup de téléphone (assignment-complete n assignment). Il vérifie plutôt si une variable assignment-complete a une valeur non nul, et sinon il vérifie assignment variable, mais dans tous les cas, sa valeur renvoyée est tout simplement ignorée de toute façon. Peut-être que des parenthèses supplémentaires sont manquantes là-bas et / ou un else clause.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top