3

我想知道在序言中是否有可能让它暴力破解所有可能的计算,如下所示:

6 is Z + Q

Z = 1 Q = 5
Z = 2 Q = 4
Z = 3 Q = 3
4

2 回答 2

3

如果您的 Prolog 支持,我建议使用有限域求解器。

我通常使用 GProlog,我可以通过类似的方式获得您的要求

fd_domain([A, B], 1, 100),
6 #= A + B,
fd_labeling([A, B]),

其中fd_domain/3设置变量的域AB(从1100),6 #= A + B设置约束(A + B为 6)并fd_labelling/1获得所有可能的计算。

在 Swi-Prolog 中有点不同。

首先,您必须加载 CLP(FD) 库

:- use_module(library(clpfd)).

要设置变量和域,您可以编写

Vars = [A, B],
Vars ins 1..100,

设置约束是相等的

6 #= A + B,

并获得所有可能的组合,你可以写

label(Vars),
于 2016-11-23T01:05:26.017 回答
2

生成和测试方法也有效。当然,你仍然需要一些约束,例如:

?- between(1, 6, X), % X is an integer between 1 and 6
   between(1, 6, Y), % Y is an integer between 1 and 6
   X =< Y,           % X is not larger than Y
   X + Y =:= 6.      % the sum is 6
X = 1, Y = 5 ;
X = 2, Y = 4 ;
X = Y, Y = 3 ;
false.

子查询的顺序很重要,因此您也可以将其称为先生成后测试。如果您不害怕对某些约束进行硬编码,则可能有一些方法可以避免生成某些值,并使某些测试变得不必要,例如:

?- between(1, 6, X), % X is an integer between 1 and 6
   between(X, 6, Y), % Y is an integer between X and 6
   X + Y =:= 6.      % the sum is 6
X = 1, Y = 5 ;
X = 2, Y = 4 ;
X = Y, Y = 3 ;
false.

您应该意识到,沿着这条路走得足够远与实现约束求解器(例如 CLP(FD))大致相同。

于 2016-11-23T07:50:36.780 回答