【问题标题】:Select Redoing Until Failure, Why?选择重做直到失败,为什么?
【发布时间】:2013-02-23 16:21:27
【问题描述】:

我有以下功能:

fillNonDrivers(Car, Pmd, Plo, ListOfPassengers) :-
  select(Passenger, Pmd, Plo1),
  Passenger = [_,n,_],
  /* etc */

我通过以下方式使用 trace on 调用它:

fillNonDrivers([hello, 2], [[david, n, punk]], PLO, LOP).
 1    1  Call: fillNonDrivers([hello,2],[[david,n,punk]],_29,_30) ? c
 2    2  Call: select(_111,[[david,n,punk]],_112) ? c
 2    2  Exit: select([david,n,punk],[[david,n,punk]],[]) ? c
 2    2  Redo: select([david,n,punk],[[david,n,punk]],[]) ? c
 2    2  Fail: select(_99,[[david,n,punk]],_100) ? c
 1    1  Fail: fillNonDrivers([hello,2],[[david,n,punk]],_29,_30) ? c
 no

我不明白为什么在上面的跟踪中调用了 Redo。不应该选择“工作”,因此调用的下一行是

 Passenger = [_,n,_],

有人可以在这里帮助解释重做的外观吗?提前谢谢你。

【问题讨论】:

  • 确实很奇怪。您使用的是什么 Prolog 实现?谓词的定义是什么?

标签: prolog backtracking gnu-prolog redo


【解决方案1】:

这意味着您的规则在绑定到乘客之前立即失败,鉴于测试用例,这永远不会发生。跟踪应该报告失败的原因,实际上是在 SWI-Prolog 中:

fillNonDrivers(Car, Pmd, Plo, ListOfPassengers) :-
  select(Passenger, Pmd, Plo1),
  Passenger = [_,n,_],
  /* etc */
  length(Plo1, 1). % expect a failure

4 ?- fillNonDrivers([hello, 2], [[david, n, punk]], PLO, LOP).
Call: (6) fillNonDrivers([hello, 2], [[david, n, punk]], _G995, _G996)
Call: (7) lists:select(_G1100, [[david, n, punk]], _G1102)
Exit: (7) lists:select([david, n, punk], [[david, n, punk]], [])
Call: (7) [david, n, punk]=[_G1093, n, _G1099]
Exit: (7) [david, n, punk]=[david, n, punk]
Call: (7) length([], 1)
Fail: (7) length([], 1)
Redo: (7) lists:select(_G1100, [[david, n, punk]], _G1102)
Fail: (7) lists:select(_G1100, [[david, n, punk]], _G1102)
Fail: (6) fillNonDrivers([hello, 2], [[david, n, punk]], _G995, _G996)
false.

可能是您的 Prolog 调试器的错误?

【讨论】:

    【解决方案2】:

    GNU Prolog 似乎没有在跟踪中显示统一目标 (=)。另请参阅此简化示例:

    GNU Prolog 1.4.2
    By Daniel Diaz
    Copyright (C) 1999-2012 Daniel Diaz
    | ?- [user].
    compiling user for byte code...
    f(X) :- X=3.
    
    user compiled, 2 lines read - 182 bytes written, 12539 ms
    
    (266 ms) yes
    | ?- trace.
    The debugger will first creep -- showing everything (trace)
    
    yes
    {trace}
    | ?- f(N).
          1    1  Call: f(_17) ? 
          1    1  Exit: f(3) ? 
    
    N = 3
    
    yes
    {trace}
    | ?- 
    

    请注意,与 CappeliC 给出的 SWI 跟踪步骤 7 相比,没有像 X=3 这样的步骤。

    所以这只是意味着Passenger = ...之后的下一个目标失败了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-02-02
      • 2018-11-11
      • 2015-10-01
      • 2018-05-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多