Skip to content

Instantly share code, notes, and snippets.

@swannodette
Forked from jamii/gist:2400297
Created April 16, 2012 17:53
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save swannodette/2400319 to your computer and use it in GitHub Desktop.
Save swannodette/2400319 to your computer and use it in GitHub Desktop.
Very crude (monotonic) datalog interpreter
(ns mist.logic.datalog
(:use clojure.core.logic
[clojure.set :only [union, difference]])
(:require clojure.walk))
(defne allo [goal args]
([_ ()])
([_ [arg . rest]]
(goal arg)
(allo goal rest)))
(defn reify-rule [rule]
(let [binding {:a (lvar :a) :b (lvar :b) :c (lvar :c)}]
(clojure.walk/prewalk-replace binding rule)))
(defn is-rule [rule-var rules]
(fn [substitutions]
(to-stream
(->> (for [rule rules]
(unify substitutions rule-var (reify-rule rule)))
(remove not)))))
(defn is-fact [rules facts]
(with-local-vars [is-fact* nil]
(var-set is-fact*
(tabled [postulate]
(conde
[(membero postulate facts)]
[(fresh [rule rule-body]
(is-rule rule rules)
(conso postulate rule-body rule)
(allo is-fact* rule-body))])))
(run* [fact] (is-fact* fact))))
(is-fact
[[[:path :a :b] [:edge :a :b]]
[[:path :a :b] [:edge :a :c] [:path :c :b]]]
[[:edge :a :b] [:edge :b :c]])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment