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] 元谓词对调用求值一次。在那种情况下,谓词要么成功(并统一变量),要么不成功(并失败)。此外,谓词当然仍然有可能引发错误,或者陷入无限循环。
我有一个 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 afterfalse
. But I don't want this. I want onlytrue
, why it givesfalse
after thetrue
? 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] 元谓词对调用求值一次。在那种情况下,谓词要么成功(并统一变量),要么不成功(并失败)。此外,谓词当然仍然有可能引发错误,或者陷入无限循环。