Skip to content

Instantly share code, notes, and snippets.

View fffej's full-sized avatar

Jeff Foster fffej

View GitHub Profile
(defn contains-value?
[coll val]
(not (nil? (some (partial = val) coll))))
(defn executing?
[x]
"Is x of the form: (executing ...)?"
(and (seq? x) (= 'executing (first x))))
(defn convert-op
(deftest test-pattern-matching
(is (= fail (pat-match '(i need a ?X) '(i really need a vacation))))
(is (= no-bindings (pat-match '(this is easy) '(this is easy))))
(is (= fail (pat-match '(?X is ?X) '((2 + 2 is 4)))))
(is (= '{?X (2 + 2)} (pat-match '(?X is ?X) '((2 + 2) is (2 + 2)))))
(is (= '{?P (Mr Hulot and I) ?X (a vacation)} (pat-match '((?* ?P) need (?* ?X))
'(Mr Hulot and I need a vacation))))
(is (= '{?X (1 2 a b)} (pat-match '((?* ?X) a b (?* ?X)) '(1 2 a b a b 1 2 a b)))))
(defn read-symbol
"Read a single symbol from a string returning nil on failure"
[s]
(read s false nil))
(defn get-response
"Get a response from the given string"
[s]
(with-open [r (PushbackReader. (StringReader. s))]
(defn run-machine
"Run the virtual machine with the decoded instructions.
Reset the program counter when complete"
[vm ops update-input]
(update-input vm)
(doseq [[op args] ops]
(apply op (list vm args)) ;; dodgy side effect
(swap! (:counter vm) inc))
(swap! (:counter vm) (constantly 0))
(swap! (:firstrun vm) (constantly false))
(defstruct virtualmachine :mem :counter :inport :outport :status :firstrun :user)
(defn increment-counter
[vm]
(assoc vm :counter (inc (:counter vm))))
(defn memory-put
"Update the memory specified by the key with the address to the given value"
[vm key addr val]
(assoc vm key (assoc (key vm) addr val)))
(defn run-machine
"Run the virtual machine with the decoded instructions."
[vm ops update-input]
(reduce
(fn [v [op args]]
(increment-counter (op v args)))
(update-input vm)
ops))
(defn tree-search
"Find a state that satisfies goal? Start with states, and search
according to successors and combiner"
[states goal? successors combiner]
(dbg :search "Search %s" states)
(cond
(empty? states) nil
(goal? (first states)) (first states)
:else (recur
(combiner (successors (first states)) (rest states))
(defn depth-first-search
"Search new states first until goal is reached."
[start goal? successors]
(tree-search (list start) goal? successors concat))
(defn reverse-concat
"Prepend y to start of x"
[x y]
(concat y x))
(defn sorter
"Return a combiner function that sorts according to cost-fn"
[cost-fn]
(fn [new old]
(sort (fn [n o] (< (cost-fn n) (cost-fn o))) (concat new old))))
(defn best-first-search
"Search lowest cost states first until goal is reached"
[start goal? successors cost-fn]
(tree-search (list start) goal? successors (sorter cost-fn)))
(defn beam-search
"Search highest scoring states first until goal is reached"
[start goal? successors cost-fn beam-width]
(tree-search (list start) goal? successors
(fn [old new]
(let [sorted ((sorter cost-fn) old new)]
(if (> beam-width (count sorted))
sorted
(take beam-width sorted))))))