为什么 sorto 的这个实现不会终止?
Why does this implementation of sorto does not terminate?
我是逻辑编程的初学者。
我正在尝试实现这样的排序关系:
(sorto [3 2 1][1 2 3]) -> #s
我正在使用 clojure 并且 core.logic:
我不明白为什么这在大多数情况下不能终止。
任何想法都会有帮助,谢谢。
(require '[clojure.core.logic :refer :all]
'[clojure.core.logic.fd :as fd])
首先定义几个小帮手:
一个简单的计数关系:(counto [a b] 2) -> #s
(defne counto [list n]
([() 0])
([[fl . rl] _]
(fresh [nnxt]
(fd/- n 1 nnxt)
(counto rl nnxt))))
减少每个?关系等价物:
(defne reduceo [rel acc x y]
([_ _ () _] (== acc y))
([_ _ [fx . rx] _]
(fresh [nacc]
(rel acc fx nacc)
(reduceo rel nacc rx y))))
(defne everyo [g list]
([_ ()])
([_ [fl . rl]]
(g fl)
(everyo g rl)))
最小关系:(mino 1 2 1) -> #s
(defn mino [x y z]
(conde
[(fd/<= x y) (== x z)]
[(fd/> x y) (== y z)]))
列表与其最小元素之间的关系:(mino* [1 2 3 0] 0) -> #s
(defne mino* [xs y]
([[fxs . rxs] _]
(reduceo mino fxs rxs y)))
主要关系:(sorto [2 3 1 4] [1 2 3 4]) -> #s
(defne sorto [x y]
([() ()])
([[fx . rx] [fy . ry]]
(fresh [x* c]
(counto rx c)
(counto ry c)
(mino* x fy)
(rembero fy x x*)
(sorto x* ry))))
下面的运行没有终止,我想知道为什么。
(run* [q]
(sorto q [1 2]))
; does not terminate
(run* [q]
(sorto [2 1] q))
; does not terminate
(run* [a b]
(everyo #(fd/in % (fd/interval 10)) a)
(everyo #(fd/in % (fd/interval 10)) b)
(sorto a b))
;neither
高层次的答案是因为连词是按顺序尝试的。对它们重新排序有时可能会使程序终止——但在一般情况下,可能不存在 "good" 顺序。
查看https://scholarworks.iu.edu/dspace/bitstream/handle/2022/8777/Byrd_indiana_0093A_10344.pdf
中的第 5 章
我是逻辑编程的初学者。
我正在尝试实现这样的排序关系:
(sorto [3 2 1][1 2 3]) -> #s
我正在使用 clojure 并且 core.logic:
我不明白为什么这在大多数情况下不能终止。
任何想法都会有帮助,谢谢。
(require '[clojure.core.logic :refer :all]
'[clojure.core.logic.fd :as fd])
首先定义几个小帮手:
一个简单的计数关系:(counto [a b] 2) -> #s
(defne counto [list n]
([() 0])
([[fl . rl] _]
(fresh [nnxt]
(fd/- n 1 nnxt)
(counto rl nnxt))))
减少每个?关系等价物:
(defne reduceo [rel acc x y]
([_ _ () _] (== acc y))
([_ _ [fx . rx] _]
(fresh [nacc]
(rel acc fx nacc)
(reduceo rel nacc rx y))))
(defne everyo [g list]
([_ ()])
([_ [fl . rl]]
(g fl)
(everyo g rl)))
最小关系:(mino 1 2 1) -> #s
(defn mino [x y z]
(conde
[(fd/<= x y) (== x z)]
[(fd/> x y) (== y z)]))
列表与其最小元素之间的关系:(mino* [1 2 3 0] 0) -> #s
(defne mino* [xs y]
([[fxs . rxs] _]
(reduceo mino fxs rxs y)))
主要关系:(sorto [2 3 1 4] [1 2 3 4]) -> #s
(defne sorto [x y]
([() ()])
([[fx . rx] [fy . ry]]
(fresh [x* c]
(counto rx c)
(counto ry c)
(mino* x fy)
(rembero fy x x*)
(sorto x* ry))))
下面的运行没有终止,我想知道为什么。
(run* [q]
(sorto q [1 2]))
; does not terminate
(run* [q]
(sorto [2 1] q))
; does not terminate
(run* [a b]
(everyo #(fd/in % (fd/interval 10)) a)
(everyo #(fd/in % (fd/interval 10)) b)
(sorto a b))
;neither
高层次的答案是因为连词是按顺序尝试的。对它们重新排序有时可能会使程序终止——但在一般情况下,可能不存在 "good" 顺序。
查看https://scholarworks.iu.edu/dspace/bitstream/handle/2022/8777/Byrd_indiana_0093A_10344.pdf
中的第 5 章