Prolog 序言:创建一个空列表列表

Prolog 序言:创建一个空列表列表,prolog,Prolog,我正在创建一个用于的董事会,我试图将董事会表示为列表列表 我需要创建一个空列表列表,例如[]、[]、[]、[]、[]],但问题是我需要输入中提供的空列表的确切数量。因此,例如,如果我给create_board(4,X),它应该返回X=[]、[]、[]、[]、[]、[]] 这是我到目前为止所拥有的 generate_board(0, [[]]) :- ! generate_board(N, [[] | T]) :- N =< 12, N >= 1, N is N-1. g

我正在创建一个用于的董事会,我试图将董事会表示为列表列表

我需要创建一个空列表列表,例如
[]、[]、[]、[]、[]]
,但问题是我需要输入中提供的空列表的确切数量。因此,例如,如果我给create_board(4,X),它应该返回
X=[]、[]、[]、[]、[]、[]]

这是我到目前为止所拥有的

generate_board(0, [[]]) :- ! 
generate_board(N, [[] | T]) :-
  N =< 12, N >= 1,
  N is N-1.
  generate_board(N, T).
生成电路板(0,[[]):-!
生成电路板(N,[[]T]):-
N=<12,N>=1,
N是N-1。
生成_板(N,T)。

除了几个语法错误外,代码的主要问题是行
N是N-1
。在Prolog中,不能“重新分配”变量。一个变量在整个谓词中只有一个值。”N是N-1`只能对一个等于其自身减去1的值成功,这显然永远不会是这种情况

解决方法很简单:只需为减少的值使用不同的变量:

generate_board(0, [[]]) :- !.
generate_board(N, [[] | T]) :-
  N =< 12, N >= 1,
  N2 is N-1,
  generate_board(N2, T).

?- generate_board(4, X).
X = [[], [], [], [], []]
生成电路板(0,[[]):-!。
生成电路板(N,[[]T]):-
N=<12,N>=1,
N2是N-1,
生成_板(N2,T)。
?生成_板(4,X)。
X=[]、[]、[]、[]、[]、[]

这给出了一个结果,但它比预期的多了一个元素。您能自己解决这个问题吗(提示:查看输入0的基本大小写返回的内容)

创建给定长度的列表的简单方法是使用
maplist2

 generate_board(Length, Board) :-
     length(Board, Length),
     maplist(=([]), Board).
这里,
maplist(([]),Board
将为
Board
中的每个
元素
调用
=([],Element)
[]=Element
的规范形式),从而将每个元素与
[]
统一起来:

| ?- generate_board(4, L).

L = [[],[],[],[]]

yes
| ?-
您可以将此概念扩展为二维空板。将电路板视为行列表(长度<代码>长度),每行视为元素列表(长度<代码>宽度):


下面是您的程序无法运行的原因(除了用
代替
)。因为这个片段失败了,所以您的原始程序也失败了。你必须以某种方式概括可见部分

:- op(950,fy,*). *_. generate_board(0, [[]]) :- ! generate_board(N, _/*[[] | T]*/) :- % 2nd * N =< 12, % 2nd * N >= 1, % 2nd N is N-1, * generate_board(N, T). % 1st generalization ?- generate_board(4, B). :-op(950财年*)。 *_. 生成_板(0,[[]):-! 生成电路板(N,T]*/):-%2 *N=<12%,第二 *N>=1,%2 N是N-1, *生成电路板(N,T)。%第一次推广 ?生成_板(4,B)。 这种方法适用于纯单调的Prolog程序。但是,您使用了限制泛化的剪切。在这种情况下,我们真的必须注意在切割之前不要泛化任何东西。因此,第一个泛化是递归目标。这是条款中的最后一个目标。只有到那时,其他的概括才可能发生

在您的程序中,如果没有剪切,我们可以进一步推广您的程序:

generate_board(0, _/*[[]]*/). ... 生成电路板(0,\/*[[]]*/)。 ... 一个简单的解决方案:

generate_board(N, Board) :-
    findall([], between(1, N, _), Board).

漂亮的拼图!谢谢你的链接
generate_board(N, Board) :-
    findall([], between(1, N, _), Board).