列表总和必须为16

时间:2017-07-07 03:37:35

标签: prolog

我现在被困在这个问题上2个小时了!我在prolog中的问题是我以一种声明的方式思考! 所以我的问题是让prolog生成一个等于N的列表!列表的大小为5。

somme([],0) :- !.
somme([X|L],S) :- somme(L,S1), S is S1+X.


generateList(L,RES) :- C1 is random(4)+1, 
              C2 is random(5)+1,
              C3 is random(6)+1,
              append(L,[C1,C2,C3],RES).


go(L) :- generateList([2,3],L), somme(L,S), S \==16, go(L).
go(L) :- generateList([2,3],L), somme(L,S), S == 16,write(L).

我们假设第一个元素是2和3。

2 个答案:

答案 0 :(得分:4)

您也可以使用CLP(FD)来描述此类列表:

:- use_module(library(clpfd)).

numbers(L) :-
   L=[2,3,_A,_B,_C],   % list has 5 elements and begins with 2,3
   L ins 0..16,        % the list elements are between 0 and 16
   sum(L, #=, 16).     % the sum of the list elements is 16

如果您查询此谓词,则会将剩余目标作为答案,因为谓词没有唯一的解决方案:

   ?- numbers(L).
L = [2,3,_A,_B,_C],
_A in 0..11,
_A+_B+_C#=11,
_B in 0..11,
_C in 0..11

在查询中添加label / 1,您将获得所有78个解决方案:

   ?- numbers(L), label(L).
L = [2,3,0,0,11] ? ;
L = [2,3,0,1,10] ? ;
L = [2,3,0,2,9] ? ;
...

您可以使用bagof / 3收集所有解决方案,如下所示:

   ?- bagof(L,(numbers(L), label(L)),Xs).
Xs = [[2,3,0,0,11],[2,3,0,1,10],[2,3,0,2,9],[2,3,0,3,8],[2,3,0,4,7],[2,3,0,5,6],[2,3,0,6,5],[2,3,0,7,4],[2,3,0,8,3],[2,3,0,9,2],[2,3,0,10,1],[2,3,0,11,0],[2,3,1,0,10],[2,3,1,1,9],[2,3,1,2,8],[2,3,1,3,7],[2,3,1,4,6],[2,3,1,5,5],[2,3,1,6,4],[2,3,1,7,3],[2,3,1,8,2],[2,3,1,9,1],[2,3,1,10,0],[2,3,2,0,9],[2,3,2,1,8],[2,3,2,2,7],[2,3,2,3,6],[2,3,2,4,5],[2,3,2,5,4],[2,3,2,6,3],[2,3,2,7,2],[2,3,2,8,1],[2,3,2,9,0],[2,3,3,0,8],[2,3,3,1,7],[2,3,3,2,6],[2,3,3,3,5],[2,3,3,4,4],[2,3,3,5,3],[2,3,3,6,2],[2,3,3,7,1],[2,3,3,8,0],[2,3,4,0,7],[2,3,4,1,6],[2,3,4,2,5],[2,3,4,3,4],[2,3,4,4,3],[2,3,4,5,2],[2,3,4,6,1],[2,3,4,7,0],[2,3,5,0,6],[2,3,5,1,5],[2,3,5,2,4],[2,3,5,3,3],[2,3,5,4,2],[2,3,5,5,1],[2,3,5,6,0],[2,3,6,0,5],[2,3,6,1,4],[2,3,6,2,3],[2,3,6,3,2],[2,3,6,4,1],[2,3,6,5,0],[2,3,7,0,4],[2,3,7,1,3],[2,3,7,2,2],[2,3,7,3,1],[2,3,7,4,0],[2,3,8,0,3],[2,3,8,1,2],[2,3,8,2,1],[2,3,8,3,0],[2,3,9,0,2],[2,3,9,1,1],[2,3,9,2,0],[2,3,10,0,1],[2,3,10,1,0],[2,3,11,0,0]]

如果有额外的目标长度/ 2,您可以计算收集的解决方案的数量:

   ?- bagof(L,(numbers(L), label(L)),Xs), length(Xs,Len).
Len = 78,
Xs = [[2,3,0,0,11],[2,3,0,1,10],[2,3,0,2,9],[2,3,0,3,8],[2,3,0,4,7],[2,3,0,5,6],[2,3,0,6,5],[2,3,0,7,4],[2,3,0,8,3],[2,3,0,9,2],[2,3,0,10,1],[2,3,0,11,0],[2,3,1,0,10],[2,3,1,1,9],[2,3,1,2,8],[2,3,1,3,7],[2,3,1,4,6],[2,3,1,5,5],[2,3,1,6,4],[2,3,1,7,3],[2,3,1,8,2],[2,3,1,9,1],[2,3,1,10,0],[2,3,2,0,9],[2,3,2,1,8],[2,3,2,2,7],[2,3,2,3,6],[2,3,2,4,5],[2,3,2,5,4],[2,3,2,6,3],[2,3,2,7,2],[2,3,2,8,1],[2,3,2,9,0],[2,3,3,0,8],[2,3,3,1,7],[2,3,3,2,6],[2,3,3,3,5],[2,3,3,4,4],[2,3,3,5,3],[2,3,3,6,2],[2,3,3,7,1],[2,3,3,8,0],[2,3,4,0,7],[2,3,4,1,6],[2,3,4,2,5],[2,3,4,3,4],[2,3,4,4,3],[2,3,4,5,2],[2,3,4,6,1],[2,3,4,7,0],[2,3,5,0,6],[2,3,5,1,5],[2,3,5,2,4],[2,3,5,3,3],[2,3,5,4,2],[2,3,5,5,1],[2,3,5,6,0],[2,3,6,0,5],[2,3,6,1,4],[2,3,6,2,3],[2,3,6,3,2],[2,3,6,4,1],[2,3,6,5,0],[2,3,7,0,4],[2,3,7,1,3],[2,3,7,2,2],[2,3,7,3,1],[2,3,7,4,0],[2,3,8,0,3],[2,3,8,1,2],[2,3,8,2,1],[2,3,8,3,0],[2,3,9,0,2],[2,3,9,1,1],[2,3,9,2,0],[2,3,10,0,1],[2,3,10,1,0],[2,3,11,0,0]]

答案 1 :(得分:1)

你的计划,修改过:

somme([],0).  /* the cut is useless, since [] and [X|L] are distinguished */
somme([X|L],S) :- somme(L,S1), S is S1+X.

generateList(L,RES) :- C1 is random(4)+1, 
              C2 is random(5)+1,
              C3 is random(6)+1,
              append(L,[C1,C2,C3],RES).

/* A variable can be assigned only once, then you must backtrack. */
/* So: repeat/0 introduces a backtrack point, going into a "failure driven loop" */
/* until the test succeeds */
go(L) :- repeat, generateList([2,3],L), somme(L,S), S == 16, !.

试运行

?- go(L).
L = [2, 3, 2, 4, 5].

?- go(L).
L = [2, 3, 2, 3, 6].