我有一个简单的Datalog程序,我正在尝试使用Closure在Datomic中表达。这个想法是可以选择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查询返回相同的内容而无需求和呢?
谢谢
西奥
答案 0 :(得分:0)
虽然我无法回答“他们是否相等”的问题,但在观看https://www.youtube.com/watch?v=bAilFQdaiHk&feature=youtu.be&t=464之后,我仍然可以得到类似的效果。它指出具有相同名称的多个规则与隐式OR组合。这似乎类似于Datalog。
将代码切换为:
(def rules '[
[(selected ?a)
[?a :assertion/name ?assertion_name]
[_ :select_assertion/assertion ?a]]
[(selected ?a)
[?a :assertion/name "1.1"]
[?ap :assertion/name "1"]
[_ :select_assertion/assertion ?ap]]])
(def selected '[:find ?a ?n
:in $ %
:where
(selected ?a)
[?a :assertion/name ?n]])
给出正确的答案。在这里,第一个selected
返回具有名称并且也已选择的实体的ID。如果第二个selected
的名称为“ 1.1”,并且还有另一个名称为“ 1”的实体,则该实体返回ID。
我认为我的困惑围绕着entity
的想法。在Datomic中,您可以拥有具有属性任意组合的实体。但是,在Datalog中,他们有atoms
,其名称为predicate
。在Datomic中,您可以通过创建返回所需属性的规则来获得与predicates
相同的效果。