2017-07-07 90 views
2

我被困在这个问题2个小时了!我在序言中的问题是我在用声明的方式思考!
所以我的问题是让prolog生成一个等于N的列表!列表的大小为5列表总和必须是16

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第一个元素是2和3

+0

您的意思是在Prolog中以声明方式思考。所以这不是问题。 – Enigmativity

回答

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]. 
+0

谢谢。你拯救了我的一天。没有使用重复的另一种解决方案? –

+0

因为如果我想显示所有的结果我能在这种情况下做什么? –

+0

首先,不要使用随机/ 1,而应该使用确定性生成器,比如介于/ 3之间。否则 - 我认为 - 有没有简单的方法来打破*无限*生成过程 – CapelliC

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 

添加标签/ 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]] 
相关问题