gpt4 book ai didi

Prolog - 参数未实例化

转载 作者:行者123 更新时间:2023-12-04 13:56:36 25 4
gpt4 key购买 nike

我试图了解 Prolog 的工作原理。我正在使用 SWI-Prolog。
这是一些代码:

forall(C1,C2) :- \+ (C1, \+ C2).

foo(N) :- N < 10.

bar(N) :- N > 5.

foobar(N) :- forall(foo(N),bar(N)).

如果我执行以下操作,它会产生所需的输出:
?- foobar(5).
false.

但是当我尝试查看所有可能的值时,我收到一个错误:
?- foobar(N).
ERROR: </2: Arguments are not sufficiently instantiated

这里发生了什么?

最佳答案

基本上你正在编写一个程序来检查全局含义:

forall N, if N < 10 then N > 5

并且您想知道 N 的哪个域那成立。

现在你在 prolog 中正确地将其重写为:
\+ ( N < 10, \+ ( N > 5 ) ).

但是,如果您尝试将该查询提供给 prolog 解释器,它将输出错误:
?- \+ ( N < 10, \+ ( N > 5 ) ).
ERROR: </2: Arguments are not sufficiently instantiated

因为 < 的参数没有被实例化。使用简单的查询(例如 N < 3)也会发生同样的事情。 .当然,如果你在查询之前实例化它,问题就会消失:
?- N=5, \+ ( N < 10, \+ ( N > 5 ) ).
false.

(该语句不适用于 N=5)
?- N=6, \+ ( N < 10, \+ ( N > 5 ) ).
N = 6.

(但它适用于 N=6)。

您还可以放置一个为 N 生成多个赋值的谓词。通过回溯,代替 N=6 :
?- between(1, 12, N), \+ ( N < 10, \+ ( N > 5 ) ).
N = 6 ;
N = 7 ;
N = 8 ;
N = 9 ;
N = 10 ;
N = 11 ;
N = 12.

但是对于大型域,这将是非常低效的(它将需要对域的每个元素进行回溯)。

如果你想推理有限域(即整数),你可以使用 CLPFD @lurker 建议的库。这种方法更有效,因为它具有推理区间、区间交集等的规则。

您必须更换 < , > , , , \+与 CLP 运营商合作 #< , #> , #/\ , #\ .让我们试试看:
?- use_module(library(clpfd)).
?- #\ ( N #< 10 #/\ #\ ( N #> 5 ) ).
N+1#=_G11193,
N#>=6#<==>_G11205,
10#>=_G11193#<==>_G11217,
_G11217 in 0..1,
_G11217#/\_G11244#<==>0,
_G11244 in 0..1,
#\_G11205#<==>_G11244,
_G11205 in 0..1.

这可能有点难以阅读,但除此之外,它还告诉您正在寻找的答案,即 N 的域: N #>= 6 .

关于Prolog - 参数未实例化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29130650/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com