【问题标题】:Prolog methods not calling base caseProlog 方法不调用基本情况
【发布时间】:2017-02-25 06:17:20
【问题描述】:

我正在尝试构建一个程序,它接受两个整数(例如,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 &gt; 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.

【问题讨论】:

标签: prolog


【解决方案1】:

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

基本情况是

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 将不起作用,因此无法调用谓词。

【讨论】:

  • 哦,呵呵。好的,非常感谢,我不知道为什么我以前没有看到。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-06
  • 2015-07-10
  • 1970-01-01
  • 2023-02-07
  • 1970-01-01
相关资源
最近更新 更多