#lang racket (require redex) (provide list-machine red var-lookup var-set program-lookup different) (define-language list-machine (a nil (cons a a)) (v variable-not-otherwise-mentioned) (r empty (r v ↦ a)) (l variable-not-otherwise-mentioned) (ι (jump l) (branch-if-nil v l) (fetch-field v 0 v) (fetch-field v 1 v) (cons v v v) halt (begin ι ι)) (p (l : ι p) end)) (define-judgment-form list-machine #:contract (var-lookup r v a) #:mode (var-lookup I I O) [----- (var-lookup (r v ↦ a) v a)] [(where #t (different v_1 v_2)) (var-lookup r v_2 a_2) ----- (var-lookup (r v_1 ↦ a_1) v_2 a_2)]) (define-judgment-form list-machine #:contract (var-set r v a r) #:mode (var-set I I I O) [----- (var-set (r v ↦ a) v a_2 (r v ↦ a_2))] [(where #t (different v v_2)) (var-set r v_2 a_2 r_2) ----- (var-set (r v ↦ a) v_2 a_2 (r_2 v ↦ a))] [----- (var-set empty v a (empty v ↦ a))]) (define-judgment-form list-machine #:contract (program-lookup p l ι) #:mode (program-lookup I I O) [----- (program-lookup (l : ι p) l ι)] [(where #t (different l l_2)) (program-lookup p l_2 ι_2) ----- (program-lookup (l : ι p) l_2 ι_2)]) (define red (reduction-relation list-machine #:domain (p r ι) (--> (p r (begin (begin ι_1 ι_2) ι_3)) (p r (begin ι_1 (begin ι_2 ι_3))) "step-seq") (--> (p r (begin (fetch-field v 0 v_2) ι)) (p r_2 ι) "step-fetch-field-0" (judgment-holds (var-lookup r v (cons a_0 a_1))) (judgment-holds (var-set r v_2 a_0 r_2))) (--> (p r (begin (fetch-field v 1 v_2) ι)) (p r_2 ι) "step-fetch-field-1" (judgment-holds (var-lookup r v (cons a_0 a_1))) (judgment-holds (var-set r v_2 a_1 r_2))) (--> (p r (begin (cons v_0 v_1 v_2) ι)) (p r_2 ι) "step-cons" (judgment-holds (var-lookup r v_0 a_0)) (judgment-holds (var-lookup r v_1 a_1)) (judgment-holds (var-set r v_2 (cons a_0 a_1) r_2))) (--> (p r (begin (branch-if-nil v l) ι)) (p r ι) "step-branch-not-taken" (judgment-holds (var-lookup r v (cons a_0 a_1)))) (--> (p r (begin (branch-if-nil v l) ι)) (p r ι_2) "step-branch-taken" (judgment-holds (var-lookup r v nil)) (judgment-holds (program-lookup p l ι_2))) (--> (p r (jump l)) (p r ι_2) "step-jump" (judgment-holds (program-lookup p l ι_2))))) (define-metafunction list-machine different : any any -> any [(different any_1 any_2) ,(not (equal? (term any_1) (term any_2)))])