繁体   English   中英

Clojure的`core.logic`中的目标排序

[英]Goal ordering in Clojure's `core.logic`

以下Clojure代码使用core.logic来解决两个不同顺序中具有相同目标的相同逻辑问题。 这种订购选择导致一个快速完成而另一个挂起。

(use `clojure.core.logic)

;; Runs quickly.  Prints (1 2 3).
(clojure.pprint/pprint (run* [q] (fresh [x] (== x [1,2,3]) 
                                            (membero q x))))

;; Hangs
(clojure.pprint/pprint (run* [q] (fresh [x] (membero q x) 
                                            (== x [1,2,3]))))

是否有一般解决方案或通常的做法来避免这个问题?

这是我的理解:

使用core.logic ,您希望尽早减少搜索空间。 如果首先放置membero约束,则运行将通过搜索membero空间开始,并回溯由==约束生成的失败。 但是membero空间是巨大的,因为qx都不是统一的或至少是有界的。

但是如果你先把==约束放在一边,你就用[1 2 3]直接统一x ,现在membero的搜索空间显然与x的元素有关。

如果您打算使用membero ,则没有针对此问题的通用解决方案。 使用新变量调用membero将使其生成q为其成员的所有(读取,无限)可能列表。 当然,大于3的列表不适用 - 但是由于你已经使用了run* ,它将继续盲目地尝试大于计数3的列表,即使每个列表都会失败。

可以使用约束基础membero在较新版本的core.logic中编写更好的membero版本,但是在未来几个月内,人们可能会如何做到这一点的细节可能会发生变化。 直到有一个坚实的公共api来定义约束,你才会遇到那些让Prolog陷入困境的微妙排序和非终止问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM