我是Prolog的初学者,所以我仍然对如何在Prolog中形成递归函数感到困惑。
假设我有一个矩阵:
S:
[ 5 6
3 4 ]
在序言中表示为:S = [[5,6],[3,4]]。
我正在尝试编写一个递归函数以获取一个单元格值,这样cell_values(单元格,矩阵,值)将从单元格列表中返回值列表。
示例:单元格值([[0,0],[0,1]],S,值)->值= [5、6]。其中S是上面的矩阵。
我正在考虑使用nth0来获取值。到目前为止,这是我的工作。
:- use_module(library(clpfd)).
cell_values([], [], []).
cell_values([X|T], S, Values) :-
nth0(X, S, Row),
nth0(T, Row, Values).
不确定如何解决此问题。你能为我指出正确的方向吗?
答案 0 :(得分:2)
谓词在这里有一些问题:
S
和T
作为行号和列号,但是S
是列表的开头,T
是列表的结尾。由于索引列表是列表列表,因此意味着S
将是列表,而T
将是列表; 因此,如果我们重写谓词,则有两个规则:
基本情况:如果索引列表为空,则无论矩阵如何,值列表也为空:
cell_values([], _, []).
在递归cass中,我们将第一个列表与[[R, C] | T]
匹配,因此R
是行号,而C
是列号,T
是要处理的其余列表的列表,因此我们按照问题中的说明执行nth0/3
,但使用R
和C
,并将单元格值V
放在结果列表[V|VT]
的前面,然后在递归调用中使用VT
以获得更多元素:
cell_values([[R, C]| T], M, [V|VT]) :-
nth0(R, M, Row),
nth0(C, Row, V),
cell_values(T, M, VT).
或将它们放在一起:
cell_values([], _, []).
cell_values([[R, C]| T], M, [V|VT]) :-
nth0(R, M, Row),
nth0(C, Row, V),
cell_values(T, M, VT).
maplist/3
处理列表是一件很平常的事情,因此我们可能对使用maplist/3
感兴趣,并编写了只处理单个子列表的谓词,例如:
cell_value(M, [R, C], V) :-
nth0(R, M, Row),
nth0(C, Row, V).
然后我们可以像这样定义谓词cell_values
:
cell_values(Ixs, M, Vs) :-
maplist(cell_value(M), Ixs, Vs).