             (cons [word had-choice] (further-stream-of-shite (concat (rest prefix) [word]) t)))))
 (defn stream-of-shite [prefix t]
     (concat (map vector prefix (repeat false)) (further-stream-of-shite prefix t)))
+
+(defn sentence-from-seed [seed backward forward]
+    (concat
+        (drop-last prefix-length
+            (reverse (take 500 (stream-of-shite (reverse seed) backward))))
+        (take 500 (stream-of-shite seed forward))))
+
 (defn generate-sentence [state keywords]
-    (let [{:keys [table starters]} state]
-        (if (empty? keywords)
-            (drop-last (map first
-                (apply max-key #(count (filter true? (map second %)))
-                    (take retries (repeatedly #(take 1000 (stream-of-shite
-                        (nth starters (rand-int (count starters)))
-                        table)))))))
-            (let [filtered-starters
-                    (filter
-                        (fn [s] (not (empty? (filter
-                            (fn [k] (not (empty? (filter #(.contains % k) s))))
-                            keywords))))
-                        starters)]
-                (if (empty? filtered-starters)
-                    (generate-sentence state [])
-                    (generate-sentence
-                        (assoc state :starters filtered-starters)
-                        []))))))
+    (println "keywords: " keywords "\n")
+    (if (empty? keywords)
+        (remove keyword? (map first
+            (apply max-key #(count (filter true? (map second %)))
+                (take retries (repeatedly #(sentence-from-seed
+                    (rand-nth (:n-grams state))
+                    (:backwardtable state)
+                    (:forwardtable state)))))))
+        (let [filtered-grams
+                (remove
+                    (fn [s] (empty? (remove
+                        (fn [k] (empty? (filter #(.contains % k) (remove keyword? s))))
+                        keywords)))
+                    (:n-grams state))]
+            (if (empty? filtered-grams)
+                (generate-sentence state [])
+                (generate-sentence
+                    (assoc state :n-grams filtered-grams)
+                    [])))))
 
 (defn value-or-default [value default]
     (if (nil? value) default value))

        (let [[prefix remainder] (split-at prefix-length words)]
            (recur
                (update-transition
                    prefix
                    (first remainder)
                    table)
                (rest words)))
        table))
(defn update-state [message state]
    (let [words (split-sentence-to-words message)]
        (assoc state
            :table
                (update-table (:table state) (concat [:begin] words [:end]))
            :starters
                (if (>= (count words) prefix-length)
                    (conj (:starters state) (take prefix-length words))
                    (:starters state)))))
(defn log-sentence! [message]
    (with-open [out (writer corpus-file :append true)]
        (.write out (str message "\n"))))

        (send-message irc channel
            (join " " (generate-sentence
                @state-ref
                (let [keywords (set (remove #(.contains % (:name @irc)) (split-sentence-to-words message)))]
                    (if (<= (count keywords) 3) keywords #{}))))))
    (if (.startsWith message "!burrito")
        (send-message irc channel
