Last active
December 13, 2015 22:18
-
-
Save senior/4983149 to your computer and use it in GitHub Desktop.
gmatche from Practical core.logic - ClojureWest 2012
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| (defn lvarify | |
| "Using _ for don't care types of values works fine when using the matche and conde | |
| macros directly, but not as well when other macros wrap it. This will walk a list, | |
| looking for _ values and swapping them for new logic variables. This translates into | |
| the same don't care values when using conde/matche directly." | |
| [sym-list] | |
| (vec (map #(if (= % '_) | |
| `(lvar) | |
| %) | |
| sym-list))) | |
| (defn qmark-sym? [x] | |
| (= \? (first (name x)))) | |
| (defn- freshen | |
| "Searches vectors of the form [x y z] looking for ?x types of variables" | |
| [spo-vecs] | |
| (vec (filter qmark-sym? (set (apply concat spo-vecs))))) | |
| (defmacro gmatche | |
| "Matches one or more resources in a graph. where all of the spo-vecs are matched in the graph. | |
| spo-vecs is a triple of the form [x y z]. Values of _ will not matter and values of ?sym will | |
| have a new logic var created (scoped at the gmatche level over multiple tiple-matches). An example | |
| triple pattern [:a _ ?f] [?f _ :a] would find values for ?f where :a is subject, ?f is object and | |
| ?f is subject and :a is object." | |
| [graph & spo-vecs] | |
| (let [graph-sym (gensym "graph")] | |
| `(let [~graph-sym ~graph] | |
| (fresh ~(freshen spo-vecs) | |
| ~@(map (fn [x#] | |
| `(membero ~(lvarify x#) ~graph-sym)) spo-vecs))))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment