【问题标题】:Prolog tries to find other solutions but I don't know why (there is only one)Prolog 试图找到其他解决方案,但我不知道为什么(只有一个)
【发布时间】:2019-10-26 13:44:11
【问题描述】:

我阅读 Learn Prolog Now 网站并尝试做以下练习:

6.5 编写一个谓词 swapfl(List1,List2) 检查 List1 是否与 List2 相同,只是交换了第一个和最后一个元素。在这里 append/3 可以再次派上用场,但也可以编写递归定义而不诉诸 append/3(或任何其他)谓词。

我已经编写了它并且它工作正常,但它试图找到多个解决方案。

swapfl([HL1|TL1],[HL2|TL2]):-
   swpfl(TL1,TL2,HL2,HL1).

swpfl([HL1|TL1],[HL2|TL2],AccEL1,AccEL2):-
   swpfl(TL1,TL2,AccEL1,AccEL2),
   HL1=HL2.
swpfl([H1],[H2],H1,H2).

我看代码和踪迹

[trace] [5]  ?- swapfl([1,2,3],[3,2,1]).
   Call: (51) swapfl([1, 2, 3], [3, 2, 1]) ? creep
   Call: (52) swpfl([2, 3], [2, 1], 3, 1) ? creep
   Call: (53) swpfl([3], [1], 3, 1) ? creep
   Exit: (53) swpfl([3], [1], 3, 1) ? creep
   Call: (53) 2=2 ? creep
   Exit: (53) 2=2 ? creep
   Exit: (52) swpfl([2, 3], [2, 1], 3, 1) ? creep
   Exit: (51) swapfl([1, 2, 3], [3, 2, 1]) ? creep
true ;
   Redo: (52) swpfl([2, 3], [2, 1], 3, 1) ? creep
   Fail: (52) swpfl([2, 3], [2, 1], 3, 1) ? creep
   Fail: (51) swapfl([1, 2, 3], [3, 2, 1]) ? creep
false.

我不明白为什么 prolog 认为开始重做部分可能是值得的。

有人可以解释为什么解决方案树有一个未搜索的分支吗?

【问题讨论】:

  • 这只是一个效率问题。 Prolog 无法立即确定 swpfl([2,3],... 不适合仅用于单元素列表的第二个子句。所以它需要尝试第二个子句然后失败。
  • 历史上对效率和消除选择点的痴迷是逻辑编程的祸根

标签: prolog


【解决方案1】:

Prolog 将始终探索所有选项,然后再做出最终决定。

尝试查看以下堆栈溢出问题: Prolog: stop condition?

错误的响应对于 Prolog 初学者来说可能看起来不一致,并且“感觉”像是错误或警告,但它实际上是一个完全正常的 Prolog 响应。 Prolog 在尝试寻找解决方案的行为方面非常一致,并且当没有更多选择存在时,将返回 false。如果 Prolog 在找到最终解决方案之前已经用尽了所有其他选择,它会显示解决方案并且不会返回 false。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-30
    • 2015-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-15
    相关资源
    最近更新 更多