dfa から nfa へ
整理。
(defmethod convert-to-dfa ((fa nfa-e)) (with-accessors ((alphabet alphabet-of) (start start-state-of) (accepts accept-states-of)) fa (let ((Dstates (make-hash-table :test #'equal)) (Di (sort-states (epsilon-closure fa (list start)))) (Dtable)) (labels ((goto* (n-set a) (loop for s in n-set with res = () do (loop for q in (transit fa s a) do (pushnew q res :test #'state=)) finally (return (sort-states res)))) (e-closure (s) (sort-states (epsilon-closure fa s))) (find-not-marked (states) (loop for s being the hash-keys in states if (eql (gethash s states) 'not-marked) return s)) (mark-state (s states) (setf (gethash s states) 'marked)) (add-not-marked (s states) (setf (gethash s states) 'not-marked))) ;; initialize (add-not-marked Di Dstates) ;; main (loop for s1 = (find-not-marked Dstates) while s1 do (mark-state s1 Dstates) (loop for a in alphabet for s2 = (e-closure (goto* s1 a)) do (when (and s2 (null (gethash s2 Dstates))) (add-not-marked s2 Dstates)) (setq Dtable (cons (list s1 a s2) Dtable)))) ;; finalize (loop for s being the hash-keys in Dstates collect s into Dstates* collect `(,s ,@(loop for (s1 a s2) in Dtable if (state= s s1) collect `(,a ,s2))) into transit if (find-if #'(lambda (q) (member q accepts :test #'state=)) s) collect s into Daccepts finally (return (make-dfa Dstates* alphabet transit Di Daccepts)))))))
Dragon Book 図3.32 部分集合構成法、とかの疑似コードとかなり近いコードだ、という自画自賛。