#lang racket (require redex) (define-language Lon (l (n ...)) (n natural)) ;; convert list of relative distances into absolute distances (define-metafunction Lon rel->abs : l -> l [(rel->abs ()) ()] [(rel->abs (n_head n_rest ...)) (n_head n_2 ...) (where (n_1 ...) (rel->abs (n_rest ...))) (where (n_2 ...) (+/all n_head (n_1 ...)))]) (module+ test (test-equal (term (rel->abs ())) (term ())) (test-equal (term (rel->abs (4 2 7))) (term (4 6 13)))) ;; add n to each number in l (define-metafunction Lon +/all : n l -> l [(+/all n ()) ()] [(+/all n (n_head n_rest ...)) (,(+ (term n) (term n_head)) n_2 ...) (where (n_2 ...) (+/all n (n_rest ...)))]) (module+ test (test-equal (term (+/all 4 (20 4 10))) (term (24 8 14)))) ;; ------------------------------------------------------ (define-metafunction Lon SortedConjecture : l -> boolean [(SortedConjecture l) (sorted (rel->abs l))]) (module+ test (test-equal (term (SortedConjecture (7))) #t) (test-equal (term (SortedConjecture (7 2 1))) #t)) (define-metafunction Lon sorted : l -> boolean [(sorted ()) #t] [(sorted (n)) #t] [(sorted (n_head n_1 n_2 ...)) (sorted (n_1 n_2 ...)) (side-condition (<= (term n_head) (term n_1)))] [(sorted (n_head n_1 n_2 ...)) #f]) (redex-check Lon l (term (SortedConjecture l)))