Guest User

src http://haskell98.blogspot.ru/2014/08/blog-post_8.html

a guest
Aug 10th, 2014
313
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lisp 6.42 KB | None | 0 0
  1. (defpackage #:pochta
  2.   (:use :cl :iterate :metatilities)
  3.   (:shadowing-import-from :metatilities minimize finish))
  4.  
  5. (in-package :pochta)
  6.  
  7. (defun process-stream (fsm stream)
  8.   (iter (with acc = '())
  9.         (for row from 0)
  10.         (for line in-stream stream using #'read-line)
  11.         (iter (for col from 0)
  12.               (for char in-string line)
  13.               (setf acc (funcall fsm char row col acc)))))
  14.  
  15. (defun process-file (fsm filename)
  16.   (with-open-file (src filename) (process-stream fsm src)))
  17.  
  18. (defun make-fsm-queue (init-fsm)
  19.   (lambda (char row col fsm-queue)
  20.     (reduce (lambda (next-fsm-queue fsm)
  21.               (funcall fsm char row col (lambda (next-state) (cons next-state next-fsm-queue)) (constantly next-fsm-queue)))
  22.             (cons init-fsm fsm-queue)
  23.             :initial-value '())))
  24.  
  25. (defmacro deffsm (name &rest patterns)
  26.   (let ((fsm (iter main-loop
  27.                    (with max-height = (reduce #'max patterns :key (compose #'length #'second)))
  28.                    (with max-width = (reduce #'max patterns :key (compose (curry #'reduce #'max) (curry #'mapcar #'length) #'second)))
  29.                    (with state-index = 0)
  30.                    (with current-states = (list (cons state-index patterns)))
  31.                    (for row from 0 below max-height)
  32.                    (iter (for col from 0 below max-width)
  33.                          (iter states-loop
  34.                                (for (current-state-index . state-patterns) in current-states)
  35.                                (iter (with ht = (make-hash-table))
  36.                                      (for (target pattern) in state-patterns)
  37.                                      (if (and (< row (length pattern))
  38.                                               (< col (length (elt pattern row))))
  39.                                          (push (list target
  40.                                                      (and (= (1+ row) (length pattern)) (= (1+ col) (length (elt pattern row))))
  41.                                                      pattern)
  42.                                                (gethash (elt (elt pattern row) col) ht))
  43.                                          (push (list target nil pattern)
  44.                                                (gethash :default ht)))
  45.                                      (finally
  46.                                       (let ((trans (iter (for (key transition) in-hashtable ht)
  47.                                                          (for next-state-index = (incf state-index))
  48.                                                          (for (values stops next-patterns) =
  49.                                                               (iter (for (target stop-p pattern) in transition)
  50.                                                                     (if stop-p
  51.                                                                         (collect target into stops)
  52.                                                                         (collect (list target pattern) into next-patterns))
  53.                                                                     (finally (return (values stops next-patterns)))))
  54.                                                          (when next-patterns
  55.                                                            (in states-loop (collect (cons next-state-index next-patterns) into next-states)))
  56.                                                          (collect (cons key (cons (when next-patterns next-state-index) stops))))))
  57.                                         (in main-loop (collect (cons (list current-state-index row col) trans))))))
  58.                                (setf current-states next-states))))))
  59.     (flet ((state-label (state) (form-symbol 'state- state)))
  60.       `(defun ,name (char init-row init-col next reset)
  61.          (declare (optimize (debug 3)))
  62.          (labels ,(iter (for ((state row col) . transitions) in fsm)
  63.                         (collect `(,(state-label state) (char row col next reset)
  64.                                     (if (and (= row (+ init-row ,row)) (= col (+ init-col ,col)))
  65.                                         (cond ,@(iter (for (key next-state . stop-set) in (remove-if (curry #'eq :default) transitions :key #'car))
  66.                                                       (collect `((char= char ,key)
  67.                                                                  ,@(iter (for stop in stop-set)
  68.                                                                          (collect `(format t ,(format nil ";; found [ ~a ] @ (~~a, ~~a)~~%" stop)
  69.                                                                                            init-col init-row)))
  70.                                                                  ,(if next-state
  71.                                                                       `(funcall next (function ,(state-label next-state)))
  72.                                                                       `(funcall reset)))))
  73.                                               (t ,(let ((default (find :default transitions :key #'car)))
  74.                                                        (if (and default (second default))
  75.                                                            `(funcall next (function ,(state-label (second default))))
  76.                                                            `(funcall reset)))))
  77.                                         (if (and (>= row (+ init-row ,row)) (> col (+ init-col ,col)))
  78.                                             (funcall reset)
  79.                                             (funcall next (function ,(state-label state))))))))
  80.            (,(state-label 0) char init-row init-col next reset))))))
  81.  
  82. (deffsm mail-digits
  83.   (0 ((#\1 #\1 #\1) (#\1 #\0 #\1) (#\1 #\0 #\1) (#\1 #\0 #\1) (#\1 #\1 #\1)))
  84.   (1 ((#\1 #\1 #\0) (#\0 #\1 #\0) (#\0 #\1 #\0) (#\0 #\1 #\0) (#\1 #\1 #\1)))
  85.   (2 ((#\1 #\1 #\1) (#\0 #\0 #\1) (#\1 #\1 #\1) (#\1 #\0 #\0) (#\1 #\1 #\1)))
  86.   (3 ((#\1 #\1 #\1) (#\0 #\0 #\1) (#\1 #\1 #\1) (#\0 #\0 #\1) (#\1 #\1 #\1)))
  87.   (4 ((#\1 #\0 #\1) (#\1 #\0 #\1) (#\1 #\1 #\1) (#\0 #\0 #\1) (#\0 #\0 #\1)))
  88.   (5 ((#\1 #\1 #\1) (#\1 #\0 #\0) (#\1 #\1 #\1) (#\0 #\0 #\1) (#\1 #\1 #\1)))
  89.   (6 ((#\1 #\1 #\1) (#\1 #\0 #\0) (#\1 #\1 #\1) (#\1 #\0 #\1) (#\1 #\1 #\1)))
  90.   (7 ((#\1 #\1 #\1) (#\0 #\0 #\1) (#\0 #\1 #\1) (#\0 #\1 #\0) (#\0 #\1 #\0)))
  91.   (8 ((#\1 #\1 #\1) (#\1 #\0 #\1) (#\1 #\1 #\1) (#\1 #\0 #\1) (#\1 #\1 #\1)))
  92.   (9 ((#\1 #\1 #\1) (#\1 #\0 #\1) (#\1 #\1 #\1) (#\0 #\0 #\1) (#\1 #\1 #\1))))
Add Comment
Please, Sign In to add comment