我正在尝试创建一个谓词,它会生成一个带数字的复合词的所有可能的评估,例如: assign_distinct_values([A-B], E).
应该会产生99个结果。
然而,我目前的努力中找不到不确定性:
assign_distinct_values(E, A) :-
term_variables(E, V),
assign_distinct_values(E, V, [0,1,2,3,4,5,6,7,8,9], A).
assign_distinct_values(E, [], [], E).
assign_distinct_values(E, [], _, E).
assign_distinct_values(E, V, N, A) :-
select(Num, N, N2),
select(Var, V, V2),
Var is Num,
assign_distinct_values(E, V2, N2, A).
生成对称结果,副本如:
答案 0 :(得分:2)
L是值列表,E是输出变量
assign_distinct_values(E, A, L) :-
member(E,L),
delete(L,E,L1),
member(A,L1).
使用prolog谓词要快得多。 member(X,L)
检查X是否在L中,如果是,我们创建一个新的列表L1,不包含带有delete(L,X,L1)
的X,并再次以相同的方式检查第二个成员。
另一个版本:
assign_distinct_values(E, A) :-
L = [0,1,2,3,4,5,6,7,8,9],
member(E,L),
delete(L,E,L1),
member(A,L1).
有用吗?我的机器上没有安装prolog。
此致
答案 1 :(得分:2)
首先考虑使用更有意义的命名约定:我建议在表示列表的变量名称后附加一个“s”,并更系统地对它们进行编号(从0开始),并使用更具说明性和意义的谓词名称: / p>
with_distinct_integers(E0, E) :-
term_variables(E0, Vs),
with_distinct_integers(E0, Vs, [0,1,2,3,4,5,6,7,8,9], E).
with_distinct_integers(E, [], [], E).
with_distinct_integers(E, [], _, E).
with_distinct_integers(E0, Vs0, Ns0, E) :-
select(Num, Ns0, Ns),
select(Var, Vs0, Vs),
Var is Num,
with_distinct_integers(E0, Vs, Ns, E).
现在关注with_distinct_integers/4
。您会看到第一个子句被第二个子句包含在内,因此您可以省略第一个子句而不会丢失解决方案。变量Var
仅用于将其与Num
统一,因此您可以立即使用单个变量:
with_distinct_integers(E, [], _, E).
with_distinct_integers(E0, Vs0, Ns0, E) :-
select(Num, Ns0, Ns),
select(Num, Vs0, Vs),
with_distinct_integers(E0, Vs, Ns, E).
您仍然会发现这个简化版本的非预期重复解决方案,我将其作为一个简单的练习,以找出导致此问题的原因:
?- with_distinct_integers(X-Y, [X,Y], [0,1], A).
..., A = 0-1 ;
..., A = 1-0 ;
..., A = 1-0 ;
..., A = 0-1 ;
false.
提示:只是在声明上明确了简化定义。继续简化:当你已经拥有所需的一切,即它的变量可用时,为什么要绕过原始术语?考虑:
with_distinct_integers(E) :-
term_variables(E, Vs),
numlist(0, 9, Ns),
with_distinct_integers(Vs, Ns).
with_distinct_integers([], _).
with_distinct_integers([V|Vs], Ns0) :-
select(V, Ns0, Ns),
with_distinct_integers(Vs, Ns).
查询示例,计算所有解决方案:
?- findall(., with_distinct_integers([X-Y]), Ls), length(Ls, L).
Ls = ['.', '.', '.', '.', '.', '.', '.', '.', '.'|...],
L = 90.
方面的惊喜:只有90个解决方案,而不是99个。
还要考虑使用有限域约束,它是整数关系,可以让你轻松地制定这样的任务:
:- use_module(library(clpfd)).
with_distinct_integers(E) :-
term_variables(E, Vs),
Vs ins 0..9,
all_different(Vs),
label(Vs).
示例查询:
?- with_distinct_integers(X-Y).
X = 0,
Y = 1 ;
X = 0,
Y = 2 ;
X = 0,
Y = 3 .