2016-02-02 4 views
3

J'ai écrit une fonction dans Racket pour produire quelque chose de similaire à la fractale suivante.Corecursion ne se termine pas après un petit changement

Circle Fractal

(define CUT-OFF 5) 
(define CIRCLE-MODE "outline") 

(define (circle-fractal size colour) 
    (local [(define full-circle (circle size CIRCLE-MODE colour))] 

    (cond [(<= size CUT-OFF) full-circle] 
      [else 
      (overlay/align "middle" "middle" 
          full-circle 
          (beside (circle-fractal (/ size 2) colour) 
            (circle-fractal (/ size 2) colour)))]))) 

Il passe mes tests.

J'ai changé le code, pensant que ce qui suit serait plus lisible.

(define (circle-fractal size colour) 
    (local [(define full-circle (circle size CIRCLE-MODE colour)) 
      (define half-circle (circle-fractal (/ size 2) colour))] 

    (cond [(<= size CUT-OFF) full-circle] 
      [else 
      (overlay/align "middle" "middle" 
          full-circle 
          (beside half-circle half-circle))]))) 

Maintenant, la fonction ne se termine pas. La raquette atteint sa limite de mémoire sans sortie.

Est-ce que chaque appel corecursif approche d'une manière ou d'une autre le cas trivial après ce changement?

Répondre

2

Dans la première version (circle-fractal (/ size 2) colour) est évaluée seulement si size > CUT-OFF. Dans la seconde, il est appelé indépendamment de la taille. De cette façon, vous avez perdu votre cas de base de récursivité.

Essayez:

(define (circle-fractal size colour) 
    (define full-circle (circle size CIRCLE-MODE colour)) 
    (cond [(<= size CUT-OFF) full-circle] 
     [else 
     (define half-circle (circle-fractal (/ size 2) colour)) 
     (overlay/align "middle" "middle" 
         full-circle 
         (beside half-circle half-circle))])) 
+2

Remarque: si vous utilisez une langue d'enseignement, ajouter 'local' que vous avez fait (et souvenez-vous préciser * que l'on * dans vos questions à venir). En full Racket 'local' n'est jamais utilisé afaik. – uselpa

+0

Merci! J'utilise la langue d'enseignement. Je vais me souvenir de préciser la prochaine fois. C'est aussi 'size <= CUT-OFF' juste pour clarifier aux autres lecteurs. Très appréciée. –

+1

De rien. En ce qui concerne la condition ... votre code est dans la clause 'else', donc il est évalué quand le * contraire * de' size <= CUT-OFF' est vrai. Par conséquent, il est évalué lorsque 'size> CUT-OFF'. – uselpa