Являются ли правила Datalog и Datomic правилами эквивалентными - PullRequest
1 голос
/ 03 апреля 2019

У меня есть простая программа 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 возвращал ту же самую вещь, не прибегая к дизъюнкции?

1 Ответ

0 голосов
/ 04 апреля 2019

Хотя я не смог ответить на вопрос «они эквивалентны», я смог получить аналогичный эффект после просмотра https://www.youtube.com/watch?v=bAilFQdaiHk&feature=youtu.be&t=464. Это указывает на то, что несколько правил с одинаковым именем объединяются снеявное ИЛИ.Это похоже на 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 возвращает идентификатор сущностей, которые имеют имена и также выбраны.Вторая selected возвращает идентификатор сущности, если она имеет имя «1.1», и существует другая сущность, которая имеет имя «1» и также выбрана.

Я думаю, что моя путаница окружает идеюentity.В Datomic вы можете иметь сущность с любой комбинацией атрибутов.Однако в Datalog они имеют atoms, чье имя predicate.В Datomic вы можете получить тот же эффект, что и эти predicates, создав правило, которое возвращает нужные вам атрибуты.

...