我正在尝试构建一个带有两个整数的程序(例如,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.
答案 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 = 4
和S = 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 = 8
和D = 4
以及
对于其他案例D = 4
和S = 4
因此,无法调用基数,因为第一个D
现在是8
而第二个D
是4
,这意味着unification将无效,因此谓词无法召唤。