我认为你的主要问题是使用 member/2 你产生的尝试比以后丢弃的要多得多。您可以改为使用 permutation/2:
poppler0(Nums, Plate, Tastiness):-
Plate = [A, B, C, D, E, F, G, H, I],
permutation(Nums, Plate),
is_equal([A, B, C], [D, E, F], Tastiness),
is_equal([A, B, C], [G, H, I], Tastiness),
is_equal([G, H, I], [D, E, F], Tastiness),
is_equal([A, D, G], [B, E, H], Tastiness),
is_equal([A, D, G], [C, F, I], Tastiness),
is_equal([B, E, H], [C, F, I], Tastiness),
is_equal([A, E, I], [C, E, G], Tastiness).
产量
?- numlist(1,9,L),poppler0(L,X,15).
L = [1, 2, 3, 4, 5, 6, 7, 8, 9],
X = [2, 7, 6, 9, 5, 1, 4, 3, 8] ;
L = [1, 2, 3, 4, 5, 6, 7, 8, 9],
X = [2, 9, 4, 7, 5, 3, 6, 1, 8] ;
...
而不是 member/3,select/3 将不重复:
poppler1(Nums, Plate, Tastiness):-
Plate = [A, B, C, D, E, F, G, H, I],
%permutation(Nums, Plate),
select(A, Nums, Num1),
select(B, Num1, Num2),
select(C, Num2, Num3),
select(D, Num3, Num4),
select(E, Num4, Num5),
select(F, Num5, Num6),
select(G, Num6, Num7),
select(H, Num7, Num8),
select(I, Num8, []),
is_equal([A, B, C], [D, E, F], Tastiness),
is_equal([A, B, C], [G, H, I], Tastiness),
is_equal([G, H, I], [D, E, F], Tastiness),
is_equal([A, D, G], [B, E, H], Tastiness),
is_equal([A, D, G], [C, F, I], Tastiness),
is_equal([B, E, H], [C, F, I], Tastiness),
is_equal([A, E, I], [C, E, G], Tastiness).
此外,由于现在的排列是“切片”的,我们可以提前“推送”一些测试,以使整体更快:
poppler2(Nums, Plate, Tastiness):-
Plate = [A, B, C, D, E, F, G, H, I],
select(A, Nums, Num1),
select(B, Num1, Num2),
select(C, Num2, Num3),
select(D, Num3, Num4),
select(E, Num4, Num5),
select(F, Num5, Num6),
is_equal([A, B, C], [D, E, F], Tastiness),
select(G, Num6, Num7),
select(H, Num7, Num8),
select(I, Num8, []),
is_equal([A, B, C], [G, H, I], Tastiness),
is_equal([G, H, I], [D, E, F], Tastiness),
is_equal([A, D, G], [B, E, H], Tastiness),
is_equal([A, D, G], [C, F, I], Tastiness),
is_equal([B, E, H], [C, F, I], Tastiness),
is_equal([A, E, I], [C, E, G], Tastiness).
?- numlist(1,9,L),time(poppler0(L,X,15)).
% 642,293 inferences, 0.253 CPU in 0.256 seconds (99% CPU, 2540589 Lips)
L = [1, 2, 3, 4, 5, 6, 7, 8, 9],
X = [2, 7, 6, 9, 5, 1, 4, 3, 8]
.
8 ?- numlist(1,9,L),time(poppler1(L,X,15)).
% 385,446 inferences, 0.217 CPU in 0.217 seconds (100% CPU, 1777885 Lips)
L = [1, 2, 3, 4, 5, 6, 7, 8, 9],
X = [2, 7, 6, 9, 5, 1, 4, 3, 8]
.
9 ?- numlist(1,9,L),time(poppler2(L,X,15)).
% 48,409 inferences, 0.029 CPU in 0.029 seconds (100% CPU, 1643812 Lips)
L = [1, 2, 3, 4, 5, 6, 7, 8, 9],
X = [2, 7, 6, 9, 5, 1, 4, 3, 8]
另一个小问题是某些总和被多次评估,这可能是由于您选择使用 is_equal/3 对测试进行编码。我会写
poppler3(Nums, Plate, Tastiness):-
Plate = [A, B, C, D, E, F, G, H, I],
select(A, Nums, Num1),
select(B, Num1, Num2),
select(C, Num2, Num3),
sumlist([A, B, C], Tastiness),
select(D, Num3, Num4),
select(E, Num4, Num5),
select(F, Num5, Num6),
sumlist([D, E, F], Tastiness),
select(G, Num6, Num7),
sumlist([A, D, G], Tastiness),
sumlist([C, E, G], Tastiness),
select(H, Num7, Num8),
sumlist([B, E, H], Tastiness),
select(I, Num8, []),
sumlist([G, H, I], Tastiness),
sumlist([C, F, I], Tastiness),
sumlist([A, E, I], Tastiness).
产生
?- numlist(1,9,L),time(poppler3(L,X,15)).
% 14,371 inferences, 0.004 CPU in 0.004 seconds (99% CPU, 3359784 Lips)
L = [1, 2, 3, 4, 5, 6, 7, 8, 9],
X = [2, 7, 6, 9, 5, 1, 4, 3, 8]
.
但同样, sumlist/2 比要求的更通用,并且内联总和还有进一步的好处:
poppler4(Nums, Plate, Tastiness):-
Plate = [A, B, C, D, E, F, G, H, I],
select(A, Nums, Num1),
select(B, Num1, Num2),
select(C, Num2, Num3),
A+B+C =:= Tastiness,
select(D, Num3, Num4),
select(E, Num4, Num5),
select(F, Num5, Num6),
D+E+F =:= Tastiness,
select(G, Num6, Num7),
A+D+G =:= Tastiness,
C+E+G =:= Tastiness,
select(H, Num7, Num8),
B+E+H =:= Tastiness,
select(I, Num8, []),
G+H+I =:= Tastiness,
C+F+I =:= Tastiness,
A+E+I =:= Tastiness.
产量
?- numlist(1,9,L),time(poppler4(L,X,15)).
% 3,394 inferences, 0.002 CPU in 0.002 seconds (100% CPU, 1827856 Lips)
L = [1, 2, 3, 4, 5, 6, 7, 8, 9],
X = [2, 7, 6, 9, 5, 1, 4, 3, 8]
.