Advertisement
Guest User

Untitled

a guest
May 6th, 2018
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Racket 6.34 KB | None | 0 0
  1. #lang racket
  2.  
  3. ;; pomocnicza funkcja dla list tagowanych o określonej długości
  4.  
  5. (define (tagged-tuple? tag len p)
  6.   (and (list? p)
  7.        (= (length p) len)
  8.        (eq? (car p) tag)))
  9.  
  10. (define (tagged-list? tag p)
  11.   (and (pair? p)
  12.        (eq? (car p) tag)
  13.        (list? (cdr p))))
  14.  
  15. ;;
  16. ;; WHILE
  17. ;;
  18.  
  19. ; memory
  20.  
  21. (define empty-mem
  22.   null)
  23.  
  24. (define (set-mem x v m)
  25.   (cond [(null? m)
  26.          (list (cons x v))]
  27.         [(eq? x (caar m))
  28.          (cons (cons x v) (cdr m))]
  29.         [else
  30.          (cons (car m) (set-mem x v (cdr m)))]))
  31.  
  32. (define (get-mem x m)
  33.   (cond [(null? m) 0]
  34.         [(eq? x (caar m)) (cdar m)]
  35.         [else (get-mem x (cdr m))]))
  36.  
  37. ; arith and bool expressions: syntax and semantics
  38.  
  39. (define (const? t)
  40.   (number? t))
  41.  
  42. (define (true? t)
  43.   (eq? t 'true))
  44.  
  45. (define (false? t)
  46.   (eq? t 'false))
  47.  
  48. (define (op? t)
  49.   (and (list? t)
  50.        (member (car t) '(+ - * / = > >= < <= not and or mod rand))))
  51.  
  52. (define (op-op e)
  53.   (car e))
  54.  
  55. (define (op-args e)
  56.   (cdr e))
  57.  
  58. (define (op->proc op)
  59.   (cond [(eq? op '+) +]
  60.         [(eq? op '*) *]
  61.         [(eq? op '-) -]
  62.         [(eq? op '/) /]
  63.         [(eq? op '=) =]
  64.         [(eq? op '>) >]
  65.         [(eq? op '>=) >=]
  66.         [(eq? op '<)  <]
  67.         [(eq? op '<=) <=]
  68.         [(eq? op 'not) not]
  69.         [(eq? op 'and) (lambda x (andmap identity x))]
  70.         [(eq? op 'or) (lambda x (ormap identity x))]
  71.         [(eq? op 'mod) modulo]
  72.         [(eq? op 'rand) (lambda (max) (min max 4))])) ; chosen by fair dice roll.
  73. ; guaranteed to be random.
  74.  
  75. (define (var? t)
  76.   (symbol? t))
  77.  
  78. (define (eval-arith e m)
  79.   (cond [(true? e) true]
  80.         [(false? e) false]
  81.         [(var? e) (get-mem e m)]
  82.         [(op? e)
  83.          (apply
  84.           (op->proc (op-op e))
  85.           (map (lambda (x) (eval-arith x m))
  86.                (op-args e)))]
  87.         [(const? e) e]))
  88.  
  89. ;; syntax of commands
  90.  
  91. (define (assign? t)
  92.   (and (list? t)
  93.        (= (length t) 3)
  94.        (eq? (second t) ':=)))
  95.  
  96. (define (assign-var e)
  97.   (first e))
  98.  
  99. (define (assign-expr e)
  100.   (third e))
  101.  
  102. (define (if? t)
  103.   (tagged-tuple? 'if 4 t))
  104.  
  105. (define (if-cond e)
  106.   (second e))
  107.  
  108. (define (if-then e)
  109.   (third e))
  110.  
  111. (define (if-else e)
  112.   (fourth e))
  113.  
  114. (define (while? t)
  115.   (tagged-tuple? 'while 3 t))
  116.  
  117. (define (while-cond t)
  118.   (second t))
  119.  
  120. (define (while-expr t)
  121.   (third t))
  122.  
  123. (define (block? t)
  124.   (list? t))
  125.  
  126. ;; state
  127.  
  128. (define (res v s)
  129.   (cons v s))
  130.  
  131. (define (res-val r)
  132.   (car r))
  133.  
  134. (define (res-state r)
  135.   (cdr r))
  136.  
  137. ;; psedo-random generator
  138.  
  139. (define initial-seed
  140.   123456789)
  141.  
  142. (define (rand max)
  143.   (lambda (i)
  144.     (let ([v (modulo (+ (* 1103515245 i) 12345) (expt 2 32))])
  145.       (res (modulo v max) v))))
  146.  
  147. ;; WHILE interpreter
  148.  
  149. (define (old-eval e m)
  150.   (cond [(assign? e)
  151.          (set-mem
  152.           (assign-var e)
  153.           (eval-arith (assign-expr e) m)
  154.           m)]
  155.         [(if? e)
  156.          (if (eval-arith (if-cond e) m)
  157.              (old-eval (if-then e) m)
  158.              (old-eval (if-else e) m))]
  159.         [(while? e)
  160.          (if (eval-arith (while-cond e) m)
  161.              (old-eval e (old-eval (while-expr e) m))
  162.              m)]
  163.         [(block? e)
  164.          (if (null? e)
  165.              m
  166.              (old-eval (cdr e) (old-eval (car e) m)))]))
  167.  
  168.  
  169. (define (eval e m seed)  
  170.  
  171.   (define (rand? e)
  172.     (tagged-list? 'rand e))
  173.   (define (rand-arg e)
  174.     (second e))
  175.  
  176.   (define (eval-arith-seed e m seed) ;zwraca res, gdzie res-val to wartość, a res-state to ziarno
  177.  
  178.     (define (op-helper xs seed) ;zwraca res: listę obliczonych argumentów i ziarno z obliczenia ostatniego argumentu
  179.       (if (null? xs)
  180.           (res null seed)
  181.           (let* ((x (eval-arith-seed (car xs) m seed))
  182.                  (y (op-helper (cdr xs) (res-state x))))
  183.             (res (cons (res-val x)
  184.                        (res-val y))
  185.                  (res-state y)))))
  186.    
  187.     (cond [(rand? e)
  188.            (let ((x (eval-arith-seed (rand-arg e) m seed)))
  189.              ((rand (res-val x)) (res-state x)))]
  190.           [(true? e) (res true seed)]
  191.           [(false? e) (res false seed)]
  192.           [(var? e) (res (get-mem e m) seed)]
  193.           [(op? e)
  194.            (let ((args (op-helper (op-args e) seed)))
  195.              (res (apply (op->proc (op-op e))
  196.                          (res-val args))
  197.                   (res-state args)))]
  198.           [(const? e) (res e seed)]))
  199.  
  200.   (define (new-eval e m seed) ;zwraca strukturę res, gdzie res-val to pamięć, a res-state to ziarno
  201.     (cond [(assign? e)
  202.            (let ((x (eval-arith-seed (assign-expr e) m seed)))
  203.              (res (set-mem (assign-var e)
  204.                            (res-val x)
  205.                            m)
  206.                   (res-state x)))]
  207.           [(if? e)
  208.            (let ((x (eval-arith-seed (if-cond e) m seed)))
  209.              (if (res-val x)
  210.                  (new-eval (if-then e) m (res-state x))
  211.                  (new-eval (if-else e) m (res-state x))))]
  212.           [(while? e)
  213.            (let ((x (eval-arith-seed (while-cond e) m seed)))
  214.              (if (res-val x)
  215.                  (let ((y (new-eval (while-expr e) m (res-state x))))
  216.                    (new-eval e (res-val y) (res-state y)))
  217.                  (res m seed)))]
  218.           [(block? e)
  219.            (if (null? e)
  220.                (res m seed)
  221.                (let ((x (new-eval (car e) m seed)))
  222.                  (new-eval (cdr e) (res-val x) (res-state x))))]))
  223.  
  224.   (res-val (new-eval e m seed)))
  225.  
  226. (define (run e)
  227.   (eval e empty-mem initial-seed))
  228.  
  229. ;;
  230.  
  231. (define fermat-test
  232.   '{(composite := false)
  233.     (while (and (> k 0) (not composite))
  234.            ((a := (+ 2 (rand (- n 4))))
  235.             (exp := 1)
  236.             (i := 1)
  237.             (while (< i n)
  238.                    ((exp := (mod (* exp a) n))
  239.                     (i := (+ i 1))))
  240.             (if (= exp 1)
  241.                 (composite := false)
  242.                 (composite := true))
  243.             (k := (- k 1))))})
  244.  
  245. (define (probably-prime? n k) ; check if a number n is prime using
  246.   ; k iterations of Fermat's primality
  247.   ; test
  248.   (let ([memory (set-mem 'k k
  249.                          (set-mem 'n n empty-mem))])
  250.     (not (get-mem
  251.           'composite
  252.           (eval fermat-test memory initial-seed)))))
  253.  
  254. (probably-prime? 5 13)
  255. (probably-prime? 345 20)
  256.  
  257. (run '(a := (+ 2 (rand 8765))))
  258. (run '((b := (rand 42))
  259.        (c := (rand 42))))
  260. (run '(d := (rand (rand 142))))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement