谓词顺序改变导致无限循环
Predicate order change causes infinite loop
所以我有一个适用于未实例化变量的谓词 nat_cset(N,Cs)
,它将自然数与计数集 Sn = {1,2,...,N}
相关联。
nat_cset_(0,Acc,Acc).
nat_cset_(N,Acc,Cs) :- N #> 0, N_1 #= N - 1, nat_cset_(N_1, [N|Acc], Cs).
nat_cset(N,Cs) :- nat_cset_(N,[],Cs).
我注意到的一件事是以下查询 nat_cset(N,Cs), N = 6.
进入无限循环而 N = 6, nat_cset(N,Cs).
没有:
?- nat_cset(N,Cs), N = 6, false.
...
?- N = 6, nat_cset(N,Cs), false.
false
发生这种情况是因为在第二个查询中,prolog 应该只寻找 N = 6 的解决方案,而在第一个查询中,prolog 将搜索无限的解决方案,使得 N = 6。
我的问题是,这是 nat_cset/2
的 'adequate' 行为还是不需要的行为?我在某处读到,改变解决方案的谓词顺序使它不单调并消除了它的纯度,但与此同时我想不出一种方法来使 nat_cset/2
有任何不同。
抱歉这个菜鸟问题,很多概念对我来说都是新概念,我仍在尝试处理所有这些概念。
查询
?- nat_cset(N,Cs), N = 6, false.
与
具有完全相同的终止属性
?- nat_cset(N,Cs), false, N = 6.
所以目标 N = 6
在这种情况下对终止没有任何影响,1。只有加在前面才能影响终止。
作为 said, rather start with programs using successor-arithmetics 而不是 clpfd
/clpz
。它们要简单得多,并且仍然公开了理解故障切片所需的相关属性。
1 这假设 N = 6
总是终止,就像 Scryer 中的 clpz
和 SWI 中的 clpfd
一样。对于一般的协程,情况不一定如此。想想freeze(N, inf), N = 6
.
所以我有一个适用于未实例化变量的谓词 nat_cset(N,Cs)
,它将自然数与计数集 Sn = {1,2,...,N}
相关联。
nat_cset_(0,Acc,Acc).
nat_cset_(N,Acc,Cs) :- N #> 0, N_1 #= N - 1, nat_cset_(N_1, [N|Acc], Cs).
nat_cset(N,Cs) :- nat_cset_(N,[],Cs).
我注意到的一件事是以下查询 nat_cset(N,Cs), N = 6.
进入无限循环而 N = 6, nat_cset(N,Cs).
没有:
?- nat_cset(N,Cs), N = 6, false.
...
?- N = 6, nat_cset(N,Cs), false.
false
发生这种情况是因为在第二个查询中,prolog 应该只寻找 N = 6 的解决方案,而在第一个查询中,prolog 将搜索无限的解决方案,使得 N = 6。
我的问题是,这是 nat_cset/2
的 'adequate' 行为还是不需要的行为?我在某处读到,改变解决方案的谓词顺序使它不单调并消除了它的纯度,但与此同时我想不出一种方法来使 nat_cset/2
有任何不同。
抱歉这个菜鸟问题,很多概念对我来说都是新概念,我仍在尝试处理所有这些概念。
查询
?- nat_cset(N,Cs), N = 6, false.
与
具有完全相同的终止属性?- nat_cset(N,Cs), false,N = 6.
所以目标 N = 6
在这种情况下对终止没有任何影响,1。只有加在前面才能影响终止。
作为 clpfd
/clpz
。它们要简单得多,并且仍然公开了理解故障切片所需的相关属性。
1 这假设 N = 6
总是终止,就像 Scryer 中的 clpz
和 SWI 中的 clpfd
一样。对于一般的协程,情况不一定如此。想想freeze(N, inf), N = 6
.