如何从Prolog矩阵中获取价值?

时间:2018-09-27 04:33:52

标签: prolog

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

不确定如何解决此问题。你能为我指出正确的方向吗?

1 个答案:

答案 0 :(得分:2)

谓词在这里有一些问题:

  1. 您使用ST作为行号和列号,但是S是列表的开头,T是列表的结尾。由于索引列表是列表列表,因此意味着S将是列表,而T将是列表;
  2. 您不使用递归来生成值的列表,因此,如果我们修复了上述问题,那么它最多仍会产生特定的值;和
  3. 基本谓词是限制性的,因为它假定矩阵(第二个参数)应该为空。这没有任何意义,因为通常情况下,矩阵将不加任何更改地传递。无论矩阵如何,如果索引列表为空,则值列表也为空。

显式递归

因此,如果我们重写谓词,则有两个规则:

  1. 基本情况:如果索引列表为空,则无论矩阵如何,值列表也为空:

    cell_values([], _, []).
    
  2. 在递归cass中,我们将第一个列表与[[R, C] | T]匹配,因此R行号,而C列号T是要处理的其余列表的列表,因此我们按照问题中的说明执行nth0/3,但使用RC ,并将单元格值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).