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).