Added persistence

This commit is contained in:
Abhinav Sarkar 2011-04-17 00:11:42 +05:30
parent be8347e45b
commit ccb689744b

View File

@ -1,16 +1,18 @@
(ns marvin.core (ns marvin.core
(:import [java.text BreakIterator] (:import [java.text BreakIterator]
[java.io File]
[marvin Bot]) [marvin Bot])
(:use [clojure.string :only (lower-case, join, trim)] (:use [clojure.string :only (lower-case, join, trim)]
[clojure.contrib.string :only (split, replace-str)]) [clojure.java.io :only (file, reader)]
[clojure.contrib.string :only (split, replace-str)]
[clojure.contrib.io :only (pwd, write-lines)])
(:gen-class)) (:gen-class))
(def non-char-pattern (re-pattern "[\\p{Z}\\p{C}\\p{P}]+"))
(defn log [o] (do (println o) o)) (defn log [o] (do (println o) o))
(defn tokenize-line [line] (defn tokenize-line [line]
(let [tokenize (let [non-char-pattern (re-pattern "[\\p{Z}\\p{C}\\p{P}]+")
tokenize
(fn tokenize [text bi idx tokens] (fn tokenize [text bi idx tokens]
(lazy-seq (lazy-seq
(if (= (.next bi) BreakIterator/DONE) (if (= (.next bi) BreakIterator/DONE)
@ -98,9 +100,11 @@
(>= (count sentence) max-length))) (>= (count sentence) max-length)))
(join " " sentence) (join " " sentence)
(let [next-word (rand-nth (trained-map current-phrase))] (let [next-word (rand-nth (trained-map current-phrase))]
(recur (if (nil? next-word)
(conj sentence next-word) (join " " sentence)
(conj (subvec current-phrase 1) next-word)))))) (recur
(conj sentence next-word)
(conj (subvec current-phrase 1) next-word)))))))
([trained-map ([trained-map
startphrase-list startphrase-list
endphrase-set endphrase-set
@ -114,11 +118,36 @@
min-length min-length
max-length))) max-length)))
(defn recall-memory
[bot
trained-map-atom
startphrase-list-atom
endphrase-set-atom
line-list-atom
key-size
history-size]
(let [filename (str (pwd) File/separator (.getName bot) ".mem")]
(when (.exists (file filename))
(with-open [rdr (reader filename)]
(doseq [line (line-seq rdr)]
(process-line
line
trained-map-atom
startphrase-list-atom
endphrase-set-atom
line-list-atom
key-size
history-size))))))
(defn save-memory [bot line-list]
(let [filename (str (pwd) File/separator (.getName bot) ".mem")]
(write-lines filename line-list)))
(defn send-message [bot channel message] (defn send-message [bot channel message]
(.sendMessage bot channel message)) (.sendMessage bot channel message))
(defn make-bot (defn make-bot
[name [bot-name
on-message-callback on-message-callback
on-action-callback on-action-callback
on-connect-callback on-connect-callback
@ -135,7 +164,7 @@
(onKick [channel kicker-nick kicker-login kicker-hostname recipient-nick reason] (onKick [channel kicker-nick kicker-login kicker-hostname recipient-nick reason]
(on-kick-callback (on-kick-callback
this channel kicker-nick kicker-login kicker-hostname recipient-nick reason))) this channel kicker-nick kicker-login kicker-hostname recipient-nick reason)))
(.setBotName name))) (.setBotName bot-name)))
(defn create-on-message-callback (defn create-on-message-callback
[trained-map-atom [trained-map-atom
@ -144,6 +173,7 @@
line-list-atom line-list-atom
key-size key-size
history-size history-size
save-interval
speak-interval speak-interval
min-sentence-length min-sentence-length
max-sentence-length] max-sentence-length]
@ -159,7 +189,8 @@
@trained-map-atom @trained-map-atom
@startphrase-list-atom @startphrase-list-atom
@endphrase-set-atom @endphrase-set-atom
min-sentence-length max-sentence-length)] min-sentence-length
max-sentence-length)]
(println ">> Sending message:" sentence) (println ">> Sending message:" sentence)
(send-message bot channel sentence))) (send-message bot channel sentence)))
([start] ([start]
@ -169,10 +200,12 @@
@trained-map-atom @trained-map-atom
@startphrase-list-atom @startphrase-list-atom
@endphrase-set-atom @endphrase-set-atom
min-sentence-length max-sentence-length)] min-sentence-length
max-sentence-length)]
(println ">> Sending message:" sentence) (println ">> Sending message:" sentence)
(send-message bot channel sentence)))) ] (send-message bot channel sentence)))) ]
(try (try
(swap! msg-count inc)
(cond (cond
(= message (str "speak " (.getName bot))) (= message (str "speak " (.getName bot)))
(do (println "Replying to speak command:" message) (do (println "Replying to speak command:" message)
@ -188,29 +221,53 @@
lower-case lower-case
create-statement-and-send)) create-statement-and-send))
:else :else
(doseq [line (sentencize-text message)] (do
(when-not (= 1 (count (tokenize-line line))) (doseq [line (sentencize-text message)]
(do (when-not (= 1 (count (tokenize-line line)))
(println ">" sender ":" line) (do
(process-line (println ">" sender ":" line)
line (process-line
trained-map-atom line
startphrase-list-atom trained-map-atom
endphrase-set-atom startphrase-list-atom
line-list-atom endphrase-set-atom
key-size history-size) line-list-atom
(swap! msg-count inc) key-size
(when (zero? (mod @msg-count speak-interval)) history-size)
(create-statement-and-send)))))) (when (<= (rand) (/ 1 speak-interval))
(create-statement-and-send)))))
(when (zero? (mod @msg-count save-interval))
(println "Saving memory")
(save-memory bot @line-list-atom))))
(catch Exception e (.printStackTrace e))))))) (catch Exception e (.printStackTrace e)))))))
(defn -main [& args] (defn run-bot
(let [server "A4E.Immortal-Anime.net" [server
channel "#animestan" channel
bot-name
key-size
history-size
save-interval
speak-interval
min-sentence-length
max-sentence-length]
(let [trained-map-atom (atom {})
startphrase-list-atom (atom [])
endphrase-set-atom (atom #{})
line-list-atom (atom [])
on-message-callback on-message-callback
(create-on-message-callback (create-on-message-callback
(atom {}) (atom []) (atom #{}) (atom []) 1 500 10 6 15) trained-map-atom
bot (make-bot "marvin" startphrase-list-atom
endphrase-set-atom
line-list-atom
key-size
history-size
save-interval
speak-interval
min-sentence-length
max-sentence-length)
bot (make-bot bot-name
on-message-callback on-message-callback
(fn [bot sender login hostname target action] (fn [bot sender login hostname target action]
(on-message-callback (on-message-callback
@ -224,13 +281,22 @@
(fn [bot _ _ _ _ _ _] (fn [bot _ _ _ _ _ _]
(do (println "Kicked. Rejoining.") (do (println "Kicked. Rejoining.")
(.joinChannel bot channel))))] (.joinChannel bot channel))))]
(println "Running" bot-name "on" server channel)
(doto bot (doto bot
(recall-memory
trained-map-atom
startphrase-list-atom
endphrase-set-atom
line-list-atom
key-size
history-size)
(.connect server) (.connect server)
(.joinChannel channel)))) (.joinChannel channel))))
(defn -main [& args]
(run-bot "A4E.Immortal-Anime.net" "#animestan" "marvin" 1 500 50 10 6 15))
;;filter out links ;;filter out links
;;switch to pircbotx ;;switch to pircbotx
;;add persistence
;;pronoun substitution ;;pronoun substitution
;;externalize parameters ;;externalize parameters
;;add random behaviour