如果只有一个合乎逻辑的答案,如何询问序言
How to ask prolog if there's only one logical answer
我试图在 Prolog 中提出一个查询,我在其中询问是否存在 x^2=25 的值。但是,我只想 return yes
如果在知识库中只有一种情况 x^2 是 25.
我的知识库中有这个:
squared(5,25)
squared((-5),25)
我希望程序 return no
因为 x
有两个答案,其中 x^2 =25,当我只想要一个。
到目前为止我有这个:
squared(x,25),squared(x,25), x=x.
您可以按如下方式使用forall/2
:
squared(X, 25), forall(squared(Y, 25), X = Y).
仅当 squared(X, 25)
的所有解都具有相同的值时,此查询才会成功。
详细一点:
squared(X, 25), % we have a single solution, X
forall(squared(Y, 25), X = Y). % we are asserting all solutions are equal to X
如果你不熟悉forall/2
:
forall(Condition, Action)
succeeds if for all alternative bindings of Condition, Action can be proven. It is equivalent to \+ (Condition, \+ Action)
.
因此这适用于具有多重性 > 1
根的谓词(这可能不是您想要的,在这种情况下 findall
可能会有所帮助)。以下将确保您只有一个根:
findall(X, squared(X, 25), [_]).
让我们看一个例子 X^2 = 0
,它在 0 处有双根:
squared(0, 0).
squared(0, 0).
所以你将拥有:
|?- findall(X, squared(X, 0), [_]). % check for exactly one root
no
|?- squared(X, 0), forall(squared(Y, 0), X = Y). % same root with any multiplicity
X = 0 ?
yes
序言中的变量也以大写字母(或 _)开头。
编辑:更优化的搜索
squared(X, 25), !, forall(squared(Y, 25), X = Y).
squared(X, 25)
之后的剪切确保我们只遍历所有根一次。如果 forall
迭代失败,则存在 Y
和 squared(Y, 25)
和 Y \= X
。所以我们不需要检查不同的 any different X
.
我试图在 Prolog 中提出一个查询,我在其中询问是否存在 x^2=25 的值。但是,我只想 return yes
如果在知识库中只有一种情况 x^2 是 25.
我的知识库中有这个:
squared(5,25)
squared((-5),25)
我希望程序 return no
因为 x
有两个答案,其中 x^2 =25,当我只想要一个。
到目前为止我有这个:
squared(x,25),squared(x,25), x=x.
您可以按如下方式使用forall/2
:
squared(X, 25), forall(squared(Y, 25), X = Y).
仅当 squared(X, 25)
的所有解都具有相同的值时,此查询才会成功。
详细一点:
squared(X, 25), % we have a single solution, X
forall(squared(Y, 25), X = Y). % we are asserting all solutions are equal to X
如果你不熟悉forall/2
:
forall(Condition, Action)
succeeds if for all alternative bindings of Condition, Action can be proven. It is equivalent to\+ (Condition, \+ Action)
.
因此这适用于具有多重性 > 1
根的谓词(这可能不是您想要的,在这种情况下 findall
可能会有所帮助)。以下将确保您只有一个根:
findall(X, squared(X, 25), [_]).
让我们看一个例子 X^2 = 0
,它在 0 处有双根:
squared(0, 0).
squared(0, 0).
所以你将拥有:
|?- findall(X, squared(X, 0), [_]). % check for exactly one root
no
|?- squared(X, 0), forall(squared(Y, 0), X = Y). % same root with any multiplicity
X = 0 ?
yes
序言中的变量也以大写字母(或 _)开头。
编辑:更优化的搜索
squared(X, 25), !, forall(squared(Y, 25), X = Y).
squared(X, 25)
之后的剪切确保我们只遍历所有根一次。如果 forall
迭代失败,则存在 Y
和 squared(Y, 25)
和 Y \= X
。所以我们不需要检查不同的 any different X
.