|   #lang racket | 
|     | 
|   ;; solving towers of Hanoi by searching the solution space  | 
|     | 
|   (require redex) | 
|     | 
|   ;; ----------------------------------------------------------------------------- | 
|   ;; the state space of configurations  | 
|   (define-language L | 
|     [chunk *] | 
|     [tile (chunk ...)] | 
|     [stack (side-condition [tile_1 ...] | 
|                            (term (stacked [tile_1 ...])))] | 
|     [state (stack ...)]) | 
|     | 
|   ;; ----------------------------------------------------------------------------- | 
|   ;; checking the stacks | 
|     | 
|   (define-metafunction L | 
|     stacked : [tile ...] -> any | 
|     [(stacked []) #t] | 
|     [(stacked [tile_0 tile_1 ...]) | 
|      (stacked [tile_1 ...]) | 
|      (judgment-holds (accepts [tile_1 ...] tile_0 ))]) | 
|     | 
|   (define-judgment-form L | 
|     #:mode (accepts I I) | 
|     #:contract (accepts stack tile) | 
|     [----------------- | 
|      (accepts [] tile)] | 
|     [----------------- | 
|      (accepts [(chunk_0 ... chunk_1 ..._1) tile ...] | 
|               (chunk_1 ..._1))]) | 
|     | 
|   ;; ----------------------------------------------------------------------------- | 
|   ;; the redution system | 
|     | 
|   (module+ test | 
|     (test-->>∃ -->hanoi | 
|                (term ([(*) (* *) (* * *)] [] [])) | 
|                (term ([]                  [] [(*) (* *) (* * *)])))) | 
|     | 
|   (define -->hanoi | 
|     (reduction-relation | 
|      L | 
|      [--> (stack_0 ... [tile_0 tile_1 ...] | 
|            stack_1 ... [tile_2 ...] | 
|            stack_3 ...) | 
|           (stack_0 ... [tile_1 ...] | 
|            stack_1 ... [tile_0 tile_2 ...] | 
|            stack_3 ...) | 
|           (judgment-holds (accepts [tile_2 ...] tile_0))] | 
|      [--> (stack_0 ... [tile_1 ...] | 
|            stack_1 ... [tile_0 tile_2 ...] | 
|            stack_3 ...) | 
|           (stack_0 ... [tile_0 tile_1 ...] | 
|            stack_1 ... [tile_2 ...] | 
|            stack_3 ...) | 
|           (judgment-holds (accepts [tile_1 ...] tile_0))])) | 
|     | 
|   (module+ test | 
|     (test-results)) | 
|     | 
|   ;; rendering the search  | 
|   (module+ main | 
|     (traces -->hanoi (term ([(*) (* *) (* * *)] [] [])))) | 
|     |