我一直在玩miniKanren,试图通过将非常基本的Prolog教程转换成它来理解它。
我习惯使用Python,所以我开始使用LogPy库,这个库后来被作为一个名为miniKanren的库进行了分叉和改进。
从库的自述文件中给出的示例中我们可以看到:
>>> 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 a la“推理的阴谋家”的一个特性?
我确实找到了这样的东西,这是在Clojure core.logic实现中找到的,其中有:https://github.com/clojure/core.logic/wiki/Features#simple-in-memory-database
它以非常类似的方式工作,尽管比python更好,因为db是一个不同的实体,而不是lib中的全局变量。
python是从core.logic借用了一个非kanren的想法吗?是否有其他MiniKanren实现具有类似的东西?还是完全不同的方法?
发布于 2020-07-20 13:51:46
这是一个很棒的问题,我认为这是一个很好的例子。它是支持的,但可能没有你习惯的那么整洁和直接。我们可以在逐个关系的基础上描述事实db,其风格与您期望编写递归的Kanren关系的风格相同。我从推理的阴谋家那里借用了具体的语法,第二版。
(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)如果您的宿主语言有一个很好的宏系统,那么您可能可以简洁地编写它,并扩展成这样的形式。
这有用吗?
https://stackoverflow.com/questions/62962615
复制相似问题