Prolog 输出在 True 之后给出 False

Prolog Output Gives False After True

我有一个 prolog 程序来表示两个州之间的航班及其成本。

我的程序是这样的:

flight(newyork,washington,7). %its mean that there is a flight between both washington and newyork, newyork and washington with cost 7. 
flight(lasvegas,losangeles,4).
flight(california,arizona,8).

route(A,B,C):-
    flight(A,B,C);flight(B,A,C). %there is a route if there is a flight between A and B with cost C `OR` B and A with cost C.

现在,当我编写这样的查询时:

?-route(washington,newyork,7).

它给我 true。这个查询对我很有用。

但是当我写这个查询时:

?-route(newyork,washington,7).

它首先给了我 true,然后 false。但我不想要这个。我只想要true,为什么在true之后给出false?为什么它给出两个输出?

您对 route/2 谓词的定义不是确定性的。如果析取中的左目标成功,则右目标也有可能成功。 IE。析取意味着一个选择点:

?- route(newyork,washington,7).
true ;
false.

当您键入 ; 时,您是在向 Prolog 寻求替代解决方案。 Prolog 引擎回溯到选择点并尝试正确的目标。由于此目标失败,Prolog 顶层打印 false 让您知道找不到替代解决方案。

Its gives me firtsly true and after false. But I don't want this. I want only true, why it gives false after the true? Why it gives two outputs?

因为 Prolog 内置了回溯。在它提出第一个解决方案后,它会报告该解决方案,但随后它会回溯以寻找另一个解决方案。

根据具体的查询,Prolog可以提前知道没有回溯选项。 Prolog 自上而下地评估谓词的 facts/clauses,这意味着如果它在最后一个子句中成功(并且没有递归调用),它肯定知道它已经穷尽搜索了所有选项。

在这里写:

route(A, B, C):-
    flight(A, B, C);
    flight(B, A, C).

所以这意味着如果你调用 route(newyork, washington, 7).,它会首先调用 flight(newyork, washington, 7)。然后成功(它甚至是第一个 flight/3 事实),但仍然有选择如何它可能会成功:也许还有另一个 flight(newyork, washington, 7) 事实,所以这可能会给 true 第二次。

然而,大多数 Prolog 系统都具有高级查找策略,以查看这是唯一以 newyork 作为第一个参数的 flight/3 事实,因此现代 Prolog 系统通常会提前知道存在没有希望找到另一个 flight/3 事实,但这并不意味着我们已经完成了。

您在 route/3 子句的正文中定义了 flight(B, A, C),因此 Prolog 将开始搜索 flight/3,但会交换位置。因此,它将在报告第一个解决方案后继续查询,并调用 flight(washington, newyork, 7) 希望找到另一个解决方案。

如果查询使用变量,这将非常有用,因为在建议的解决方案中,分配给变量的值可以(通常 )不同,所以这可以用作搜索工具。

您可以使用 once/1 [swi-doc] 元谓词对调用求值一次。在那种情况下,谓词要么成功(并统一变量),要么不成功(并失败)。此外,谓词当然仍然有可能引发错误,或者陷入无限循环。