Clojure 数据日志规则和Datomic规则等效吗

Clojure 数据日志规则和Datomic规则等效吗,clojure,datomic,datalog,Clojure,Datomic,Datalog,我有一个简单的数据记录程序,我正试图用闭包用Datomic表示。想法是可以选择断言,选择一些断言也会选择其他断言。以下是数据日志程序: % Facts assertion("id1", "1"). assertion("id11", "1.1"). assertion("id2", "2"). assertion("id3", "3"). select_assertion("id1"). % Rules: selected(Id, Name) :- assertion(Id, Name),

我有一个简单的数据记录程序,我正试图用闭包用Datomic表示。想法是可以选择
断言
,选择一些断言也会选择其他断言。以下是数据日志程序:

% 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来表达这一点,但发现很难让
规则
看起来与
事实
相同,这样查询就可以区分它们。就我所知:

% ... 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查询返回相同的内容而不使用析取?

虽然我无法回答“它们是否等效”的问题,但在观看之后,我能够获得类似的效果。它指出,同名的多个规则与隐式或。这似乎类似于数据日志

将代码切换为:

(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]])
给出了正确的答案。此处,第一个选中的
返回具有名称且也被选中的实体的ID。如果一个实体的名称为“1.1”,并且另一个实体的名称为“1”,并且该实体也被选中,则第二个选中的
将返回该实体的ID


我想我的困惑围绕着
实体的概念。在Datomic中,您可以拥有具有任意属性组合的实体。然而,在这些元素中有原子,其名称是谓词。在Datomic中,通过创建一个返回所需属性的规则,您可以获得与这些谓词相同的效果。

虽然我无法回答“它们是否等效”的问题,但在观看之后,我能够获得类似的效果。它指出,同名的多个规则与隐式或。这似乎类似于数据日志

将代码切换为:

(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]])
给出了正确的答案。此处,第一个选中的
返回具有名称且也被选中的实体的ID。如果一个实体的名称为“1.1”,并且另一个实体的名称为“1”,并且该实体也被选中,则第二个选中的
将返回该实体的ID


我想我的困惑围绕着
实体的概念。在Datomic中,您可以拥有具有任意属性组合的实体。然而,在这些元素中有原子,其名称是谓词。在Datomic中,通过创建返回所需属性的规则,您可以获得与这些
谓词相同的效果。

听起来您对逻辑编程比对数据库更感兴趣?如果是这样,您可能会想:您不是指Clojure而不是闭包吗?如果是这样的话,你可能想修复标签。听起来你对逻辑编程比对数据库更感兴趣?如果是这样,您可能会想:您不是指Clojure而不是闭包吗?如果是这样,您可能需要修复标记。