У меня есть простая программа Datalog, которую я пытаюсь выразить в Datomic, используя Closure. Идея в том, что assertions
можно выбрать, и выбор некоторых утверждений также выбирает другие. Вот программа Datalog:
% Facts
assertion("id1", "1").
assertion("id11", "1.1").
assertion("id2", "2").
assertion("id3", "3").
select_assertion("id1").
% Rules:
selected(Id, Name) :- assertion(Id, Name), select_assertion(Id).
select_assertion(IdChild) :-
assertion(IdChild, "1.1"),
assertion(IdParent, "1"),
select_assertion(IdParent).
Выполнение запроса:
selected(A,B)?
=>
selected(id1, 1).
selected(id11, "1.1").
При выборе «1» также выбирается «1.1». Я пытался выразить это в Datomic, но мне было трудно заставить rules
выглядеть так же, как facts
, так что запрос различает их. Это насколько я получил:
% ... connection stuff
(def schema [{:db/ident :assertion/name
:db/valueType :db.type/string
:db/cardinality :db.cardinality/one
:db/doc "The name of an assertion"}
{:db/ident :select_assertion/assertion
:db/valueType :db.type/ref
:db/cardinality :db.cardinality/one
:db/doc "The ID of an assertion to be selected"}
])
(def data [
{:db/id "id-1" :assertion/name "1"}
{:assertion/name "1.1"}
{:assertion/name "2"}
{:assertion/name "3"}
{:select_assertion/assertion "id-1"}
])
(def rules '[
[(selected ?assertion_name)
[?a :assertion/name ?assertion_name]
[_ :select_assertion/assertion ?a]]
[(select_assertion "1.1")
[?a :assertion/name "1"]
[_ :select_assertion/assertion ?a]]])
(def selected '[:find ?c
:in $ %
:where
(selected ?c)])
(defn reload-dbs []
(d/transact conn {:tx-data schema})
(d/transact conn {:tx-data data}))
(defn query []
(d/q selected db rules))
Как сделать так, чтобы запрос Datomic возвращал ту же самую вещь, не прибегая к дизъюнкции?