Prolog方法不调用基本情况

时间:2017-02-25 06:17:21

标签: prolog

我正在尝试构建一个带有两个整数的程序(例如,4和15)并返回分成第二个整数的第一个整数的倍数。

我的计划如下:

divisible(D,U,X):-
   divisible_ext(D,U,D,X).

divisible_ext(D,U,D,X):-
   U < D,
   !.
divisible_ext(D,U,S,X):-
   U > D,
   D1 is D + S,
   divisible_ext(D1,U,S,X1),
   X is D.

据我所知,我的程序在每次调用时应该使基本情况失败,直到D值大于U(所以4和15,16> 15)。但是在跟踪中,我可以看到基本情况只是第一次调用,然后再也不会调用。因此,当D = 16时,U > D调用失败,整个程序失败。

为什么基本情况只被调用一次?是否有一些我不了解Prolog的东西我需要知道,或者我的代码是否有变化?

编辑:这是我的追踪:

[trace] 20 ?- divisible(4,15,X).
   Call: (7) divisible(4, 15, _G9543) ? creep
   Call: (8) divisible_ext(4, 15, 4, _G9543) ? creep
   Call: (9) 15<4 ? creep
   Fail: (9) 15<4 ? creep
   Redo: (8) divisible_ext(4, 15, 4, _G9543) ? creep
   Call: (9) 15>4 ? creep
   Exit: (9) 15>4 ? creep
   Call: (9) _G9622 is 4+4 ? creep
   Exit: (9) 8 is 4+4 ? creep
   Call: (9) divisible_ext(8, 15, 4, _G9625) ? creep
   Call: (10) 15>8 ? creep
   Exit: (10) 15>8 ? creep
   Call: (10) _G9625 is 8+4 ? creep
   Exit: (10) 12 is 8+4 ? creep
   Call: (10) divisible_ext(12, 15, 4, _G9628) ? creep
   Call: (11) 15>12 ? creep
   Exit: (11) 15>12 ? creep
   Call: (11) _G9628 is 12+4 ? creep
   Exit: (11) 16 is 12+4 ? creep
   Call: (11) divisible_ext(16, 15, 4, _G9631) ? creep
   Call: (12) 15>16 ? creep
   Fail: (12) 15>16 ? creep
   Fail: (11) divisible_ext(16, 15, 4, _G9631) ? creep
   Fail: (10) divisible_ext(12, 15, 4, _G9628) ? creep
   Fail: (9) divisible_ext(8, 15, 4, _G9625) ? creep
   Fail: (8) divisible_ext(4, 15, 4, _G9543) ? creep
   Fail: (7) divisible(4, 15, _G9543) ? creep
false.

1 个答案:

答案 0 :(得分:0)

  

为什么基本情况只被调用一次?

基本案例是

divisible_ext(D,U,D,X) :-

另一种情况是

 divisible_ext(D,U,S,X) :-

请注意第一次通话

Call: (8) divisible_ext(4, 15, 4, _G9543) ? creep
          divisible_ext(D,  U, D,     X) :-                 <-- Base case
          divisible_ext(D,  U, S,     X) :-                 <-- Other case

对于D = 4
的基本案例D 对于其他案例D = 4S = 4
所以可以调用两个谓词。

第二次电话通知

Call: (9) divisible_ext(8, 15, 4, _G9625) ? creep
          divisible_ext(D,  U, D,      X) :-                 <-- Base case
          divisible_ext(D,  U, S,      X) :-                 <-- Other case

对于基本案例D = 8D = 4以及
对于其他案例D = 4S = 4
因此,无法调用基数,因为第一个D现在是8而第二个D4,这意味着unification将无效,因此谓词无法召唤。