2

我是 Prolog 的初学者,我想我可以尝试编写一个简单的测试来检查一组整数 mod K (L) 是否是一个组。我首先试图找出上述集合是否是加法的,即。如果 L 的每两个元素之和也是 L 的一个元素。

我写了以下内容:

group(A,K):-member(B,A),member(C,A),As is B+C, Bs is mod(As,K), member(Bs,A).

然后我尝试了这个:

trace. group([0,1,2],3).

这自然会产生所有可能的总和,并且正确地回答答案对所有这些都是正确的。

但在所有这些情况之后,它最终打印出以下内容:

  1    1  Redo: group([0,1,2],3) ? 
  6    2  Redo: member(1,[0,1,2]) ? 
  6    2  Fail: member(1,[0,1,2]) ? 
  1    1  Fail: group([0,1,2],3) ?
  no

为什么程序会检查最后一个案例,在我看来,这似乎是荒谬的?

在此之前的最后一个案例是:

  1    1  Redo: group([0,1,2],3) ? 
  6    2  Redo: member(0,[0,1,2]) ? 
  6    2  Fail: member(0,[0,1,2]) ? 
  3    2  Redo: member(1,[0,1,2]) ? 
  3    2  Exit: member(2,[0,1,2]) ? 
  4    2  Call: _158 is 2+2 ? 
  4    2  Exit: 4 is 2+2 ? 
  5    2  Call: _186 is 4 mod 3 ? 
  5    2  Exit: 1 is 4 mod 3 ? 
  6    2  Call: member(1,[0,1,2]) ? 
  6    2  Exit: member(1,[0,1,2]) ? 
  1    1  Exit: group([0,1,2],3) ? 

  true

哪个做它应该做的。

4

2 回答 2

1

为此目的使用示踪剂并不是很有帮助。它向您展示了许多无关紧要的细节。相反,专注于对问题的良好表述。专注于有意义的名称。用于A集合BC元素。那是可以改进的!

你目前测试的是这样的:

一个集合中存在两个元素,其和模 K 在同一个集合中。

您要测试的是:

对于 S 中的所有 X、Y:( (X+Y) mod K ) 在 S 中。

操作本身可以写成:Z is (X+Y) mod K

示踪剂如何向您解释这一点?

组(S,K):-
   \+ (
         成员(X,S), 成员(Y,S), Z 是 (X+Y) mod K,
         \+ 成员(Z,S)
   )。

?- 组([0,1,2],3)。
真的。

?- 组([0,2],3)。
错误的。
于 2012-11-16T00:26:52.737 回答
0

我认为追踪器向您展示了回溯追踪器所遵循的所有不同分支。为此,它似乎否定了它尝试的最后一个分支中的一个成功语句,所以这一次它将采用不同的解决方案。

看看整个执行过程,你肯定会看到失败的谓词是真的,就像Fail: (7) lists:member(0, [0, 1, 2])在第二次评估中一样。

[trace]  ?- group([0, 1, 2], 3).
   Call: (6) group([0, 1, 2], 3) ? creep
   Call: (7) lists:member(_G718, [0, 1, 2]) ? creep
   Exit: (7) lists:member(0, [0, 1, 2]) ? creep
   Call: (7) lists:member(_G718, [0, 1, 2]) ? creep
   Exit: (7) lists:member(0, [0, 1, 2]) ? creep
^  Call: (7) _G721 is 0+0 ? creep
^  Exit: (7) 0 is 0+0 ? creep
^  Call: (7) _G724 is 0 mod 3 ? creep
^  Exit: (7) 0 is 0 mod 3 ? creep
   Call: (7) lists:member(0, [0, 1, 2]) ? creep
   Exit: (7) lists:member(0, [0, 1, 2]) ? creep
   Exit: (6) group([0, 1, 2], 3) ? creep
true ;
   Redo: (7) lists:member(0, [0, 1, 2]) ? creep
   Fail: (7) lists:member(0, [0, 1, 2]) ? creep
   Redo: (7) lists:member(_G718, [0, 1, 2]) ? creep
   Exit: (7) lists:member(1, [0, 1, 2]) ? creep
^  Call: (7) _G721 is 0+1 ? creep
^  Exit: (7) 1 is 0+1 ? creep
^  Call: (7) _G724 is 1 mod 3 ? creep
^  Exit: (7) 1 is 1 mod 3 ? creep
   Call: (7) lists:member(1, [0, 1, 2]) ? creep
   Exit: (7) lists:member(1, [0, 1, 2]) ? creep
   Exit: (6) group([0, 1, 2], 3) ? creep
true ;
   Redo: (7) lists:member(1, [0, 1, 2]) ? creep
   Fail: (7) lists:member(1, [0, 1, 2]) ? creep
   Redo: (7) lists:member(_G718, [0, 1, 2]) ? creep
   Exit: (7) lists:member(2, [0, 1, 2]) ? creep
^  Call: (7) _G721 is 0+2 ? creep
^  Exit: (7) 2 is 0+2 ? creep
^  Call: (7) _G724 is 2 mod 3 ? creep
^  Exit: (7) 2 is 2 mod 3 ? creep
   Call: (7) lists:member(2, [0, 1, 2]) ? creep
   Exit: (7) lists:member(2, [0, 1, 2]) ? creep
   Exit: (6) group([0, 1, 2], 3) ? creep
true ;
   Redo: (7) lists:member(_G718, [0, 1, 2]) ? creep
   Exit: (7) lists:member(1, [0, 1, 2]) ? creep
   Call: (7) lists:member(_G718, [0, 1, 2]) ? creep
   Exit: (7) lists:member(0, [0, 1, 2]) ? creep
^  Call: (7) _G721 is 1+0 ? creep
^  Exit: (7) 1 is 1+0 ? creep
^  Call: (7) _G724 is 1 mod 3 ? creep
^  Exit: (7) 1 is 1 mod 3 ? creep
   Call: (7) lists:member(1, [0, 1, 2]) ? creep
   Exit: (7) lists:member(1, [0, 1, 2]) ? creep
   Exit: (6) group([0, 1, 2], 3) ? creep
true ;
   Redo: (7) lists:member(1, [0, 1, 2]) ? creep
   Fail: (7) lists:member(1, [0, 1, 2]) ? creep
   Redo: (7) lists:member(_G718, [0, 1, 2]) ? creep
   Exit: (7) lists:member(1, [0, 1, 2]) ? creep
^  Call: (7) _G721 is 1+1 ? creep
^  Exit: (7) 2 is 1+1 ? creep
^  Call: (7) _G724 is 2 mod 3 ? creep
^  Exit: (7) 2 is 2 mod 3 ? creep
   Call: (7) lists:member(2, [0, 1, 2]) ? creep
   Exit: (7) lists:member(2, [0, 1, 2]) ? creep
   Exit: (6) group([0, 1, 2], 3) ? creep
true ;
   Redo: (7) lists:member(_G718, [0, 1, 2]) ? creep
   Exit: (7) lists:member(2, [0, 1, 2]) ? creep
^  Call: (7) _G721 is 1+2 ? creep
^  Exit: (7) 3 is 1+2 ? creep
^  Call: (7) _G724 is 3 mod 3 ? creep
^  Exit: (7) 0 is 3 mod 3 ? creep
   Call: (7) lists:member(0, [0, 1, 2]) ? creep
   Exit: (7) lists:member(0, [0, 1, 2]) ? creep
   Exit: (6) group([0, 1, 2], 3) ? creep
true ;
   Redo: (7) lists:member(0, [0, 1, 2]) ? creep
   Fail: (7) lists:member(0, [0, 1, 2]) ? creep
   Redo: (7) lists:member(_G718, [0, 1, 2]) ? creep
   Exit: (7) lists:member(2, [0, 1, 2]) ? creep
   Call: (7) lists:member(_G718, [0, 1, 2]) ? creep
   Exit: (7) lists:member(0, [0, 1, 2]) ? creep
^  Call: (7) _G721 is 2+0 ? creep
^  Exit: (7) 2 is 2+0 ? creep
^  Call: (7) _G724 is 2 mod 3 ? creep
^  Exit: (7) 2 is 2 mod 3 ? creep
   Call: (7) lists:member(2, [0, 1, 2]) ? creep
   Exit: (7) lists:member(2, [0, 1, 2]) ? creep
   Exit: (6) group([0, 1, 2], 3) ? creep
true ;
   Redo: (7) lists:member(_G718, [0, 1, 2]) ? creep
   Exit: (7) lists:member(1, [0, 1, 2]) ? creep
^  Call: (7) _G721 is 2+1 ? creep
^  Exit: (7) 3 is 2+1 ? creep
^  Call: (7) _G724 is 3 mod 3 ? creep
^  Exit: (7) 0 is 3 mod 3 ? creep
   Call: (7) lists:member(0, [0, 1, 2]) ? creep
   Exit: (7) lists:member(0, [0, 1, 2]) ? creep
   Exit: (6) group([0, 1, 2], 3) ? creep
true ;
   Redo: (7) lists:member(0, [0, 1, 2]) ? creep
   Fail: (7) lists:member(0, [0, 1, 2]) ? creep
   Redo: (7) lists:member(_G718, [0, 1, 2]) ? creep
   Exit: (7) lists:member(2, [0, 1, 2]) ? creep
^  Call: (7) _G721 is 2+2 ? creep
^  Exit: (7) 4 is 2+2 ? creep
^  Call: (7) _G724 is 4 mod 3 ? creep
^  Exit: (7) 1 is 4 mod 3 ? creep
   Call: (7) lists:member(1, [0, 1, 2]) ? creep
   Exit: (7) lists:member(1, [0, 1, 2]) ? creep
   Exit: (6) group([0, 1, 2], 3) ? creep
true ;
   Redo: (7) lists:member(1, [0, 1, 2]) ? creep
   Fail: (7) lists:member(1, [0, 1, 2]) ? creep
   Fail: (6) group([0, 1, 2], 3) ? creep
false.
于 2012-11-16T00:36:43.510 回答