Разве "база данных фактов" не является основной особенностью miniKanren?

Я играл с miniKanren, пытаясь понять его, конвертируя в него очень простые учебные пособия по Prolog.

Обычно я использую Python, поэтому я начал с библиотеки LogPy, которая с тех пор была разветвлена ​​и усовершенствована, поскольку на самом деле библиотека называется miniKanren.

Из примера, приведенного в README библиотеки, мы можем увидеть:

>>> from kanren import Relation, facts
>>> parent = Relation()
>>> facts(parent, ("Homer", "Bart"),
...               ("Homer", "Lisa"),
...               ("Abe",  "Homer"))

>>> run(1, x, parent(x, "Bart"))
('Homer',)

Это тривиально соответствует тому, что вы могли увидеть в начале руководства по Prolog, например:

% facts.pl
parent(homer, bart).
parent(homer, lisa).
parent(abe, homer).

?- consult('facts')
true.

?- parent(X, bart).
X = homer

Я был доволен этим. Позже я обнаружил, что читаю все больше и больше литературы по MiniKanren (в общем смысле, а не библиотеки Python) и понял, что не видел ни одного примера, использующего базу данных фактов таким образом или упоминания о ней.

Я это пропустил? Или это на самом деле не особенность MiniKanren а-ля "Разумный интриган"?

Где я нашел такое, так это в Clojure core.logicреализация, где есть это: https://github.com/clojure/core.logic/wiki/Features

Он работает очень похожим образом, хотя и лучше, чем у Python, потому что db - это отдельный объект, а не глобальная переменная в библиотеке.

Python lib просто заимствовал идею, отличную от канрена, из core.logic? Есть ли другие реализации MiniKanren, которые имеют что-то подобное? Или совсем другой подход?

1 ответ

Решение

Это отличный вопрос, и я думаю, что это отличный пример, который стоит иметь под рукой. Он поддерживается, но, возможно, не так четко и просто, как вы привыкли. Мы можем описать базу данных фактов на основе отношения за отношением в том же стиле, в котором вы ожидаете написать рекурсивное отношение Канрена. Я заимствую конкретный синтаксис изTRS 2/e

(defrel (parento f c)
  (conde
    ((== f 'homer) (== c 'bart))
    ((== f 'homer) (== c 'lisa))
    ((== f 'abe)   (== c 'homer))))

(defrel (stonecuttero p)
  (conde 
    ((== p 'abe))
    ((== p 'lenny))
    ((== p 'carl))
    ((== p 'glumplich))))

> (run* p (fresh (o) (stonecuttero p) (parento p o)))
(abe)

Если у вашего основного языка есть хорошая макросистема, вы, вероятно, могли бы написать ее кратко и развернуть до такой формы.

Это помогает?

Другие вопросы по тегам