Sync
This commit is contained in:
parent
6f050a029e
commit
776bba907c
3887 changed files with 59894 additions and 7280 deletions
|
|
@ -0,0 +1,68 @@
|
|||
;;; Keeps track of all our rules
|
||||
(defclass markov ()
|
||||
((rules :initarg :rules :initform nil :accessor rules)))
|
||||
|
||||
;;; Definition of a rule
|
||||
(defclass rule ()
|
||||
((pattern :initarg :pattern :accessor pattern)
|
||||
(replacement :initarg :replacement :accessor replacement)
|
||||
(terminal :initform nil :initarg :terminal :accessor terminal)))
|
||||
|
||||
;;; Parse a rule with this regular expression
|
||||
(defparameter *rex->* (compile-re "^(.+)(?: |\\t)->(?: |\\t)(\\.?)(.*)$"))
|
||||
|
||||
;;; Create a rule and add it to the markov object
|
||||
(defmethod update-markov ((mkv markov) lhs terminating rhs)
|
||||
(setf (rules mkv) (cons
|
||||
(make-instance 'rule :pattern lhs :replacement rhs :terminal terminating)
|
||||
(rules mkv))))
|
||||
|
||||
;;; Parse a line and add it to the markov object
|
||||
(defmethod parse-line ((mkv markov) line)
|
||||
(let ((trimmed (string-trim #(#\Space #\Tab) line)))
|
||||
(if (not (or
|
||||
(eql #\# (aref trimmed 0))
|
||||
(equal "" trimmed)))
|
||||
(let ((vals (multiple-value-list (match-re *rex->* line))))
|
||||
(if (not (car vals))
|
||||
(progn
|
||||
(format t "syntax error in ~A" line)
|
||||
(throw 'fail t)))
|
||||
(update-markov mkv (nth 2 vals) (equal "." (nth 3 vals)) (nth 4 vals))))))
|
||||
|
||||
;;; Make a markov object from the string of rules
|
||||
(defun make-markov (rules-text)
|
||||
(catch 'fail
|
||||
(let ((mkv (make-instance 'markov)))
|
||||
(with-input-from-string (s rules-text)
|
||||
(loop for line = (read-line s nil)
|
||||
while line do
|
||||
(parse-line mkv line)))
|
||||
(setf (rules mkv) (reverse (rules mkv)))
|
||||
mkv)))
|
||||
|
||||
;;; Given a rule and bounds where it applies, apply it to the input text
|
||||
(defun adjust (rule-info text)
|
||||
(let* ((rule (car rule-info))
|
||||
(index-start (cadr rule-info))
|
||||
(index-end (caddr rule-info))
|
||||
(prefix (subseq text 0 index-start))
|
||||
(suffix (subseq text index-end))
|
||||
(replace (replacement rule)))
|
||||
(concatenate 'string prefix replace suffix)))
|
||||
|
||||
;;; Get the next applicable rule or nil if none
|
||||
(defmethod get-rule ((markov markov) text)
|
||||
(dolist (rule (rules markov) nil)
|
||||
(let ((index (search (pattern rule) text)))
|
||||
(if index
|
||||
(return (list rule index (+ index (length (pattern rule)))))))))
|
||||
|
||||
;;; Interpret text using a markov object
|
||||
(defmethod interpret ((markov markov) text)
|
||||
(let ((rule-info (get-rule markov text))
|
||||
(ret text))
|
||||
(loop (if (not rule-info) (return ret))
|
||||
(setf ret (adjust rule-info ret))
|
||||
(if (terminal (car rule-info)) (return ret))
|
||||
(setf rule-info (get-rule markov ret)))))
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
(defparameter
|
||||
*rules1*
|
||||
"# This rules file is extracted from Wikipedia:
|
||||
# http://en.wikipedia.org/wiki/Markov_Algorithm
|
||||
A -> apple
|
||||
B -> bag
|
||||
S -> shop
|
||||
T -> the
|
||||
the shop -> my brother
|
||||
a never used -> .terminating rule")
|
||||
|
||||
;;; Lots of other defparameters for rules omitted here...
|
||||
|
||||
(defun test ()
|
||||
(format t "~A~%" (interpret (make-markov *rules1*) "I bought a B of As from T S."))
|
||||
(format t "~A~%" (interpret (make-markov *rules2*) "I bought a B of As from T S."))
|
||||
(format t "~A~%" (interpret (make-markov *rules3*) "I bought a B of As W my Bgage from T S."))
|
||||
(format t "~A~%" (interpret (make-markov *rules4*) "_1111*11111_"))
|
||||
(format t "~A~%" (interpret (make-markov *rules5*) "000000A000000"))
|
||||
)
|
||||
(test)
|
||||
I bought a bag of apples from my brother.
|
||||
I bought a bag of apples from T shop.
|
||||
I bought a bag of apples with my money from T shop.
|
||||
11111111111111111111
|
||||
00011H1111000
|
||||
NIL
|
||||
Loading…
Add table
Add a link
Reference in a new issue