Prolog - 从列表列表中获取元素

时间:2011-10-27 07:18:59

标签: matrix prolog row backtracking

我无法确定如何在不使用递归的情况下从字符串列表中访问单个字符,而是回溯。

例如,我有这个字符串列表,我希望能够从这些字符串之一返回单个字符('。''o','*')。我正在处理的程序将其视为行和列。我的数据库中的事实如下所示:

matrix(["...o....",
        ".******.",
        "...o....",
        ".*...*..",
        "..o..*..",
        ".....*..",
        ".o...*..",
        "....o..o"].

我有谓词:

get(Row,Col,TheChar) :- 

获取行号和列号(索引从1开始)并返回该特定行和列的条目(TheEntry)。

我有一种感觉,我的谓词头可能无法正确构建,但我更专注于如何逐个字符地遍历列表中的每个字符串而不递归并返回。

我是prolog的新手,并且在这方面遇到了很大的困难。

任何帮助都将非常感谢!

谢谢!

2 个答案:

答案 0 :(得分:3)

get / 3的实现可能如下所示:

get(Row,Col,TheChar) :-    
   matrix(M),
   nth(Row,M,RowList),
   nth(Col,RowList,TheChar).

请注意,TheChar统一为字符代码,例如

| ?- get(1,4,X).
X = 111

如果你想看到你可以使用的字符,例如使用原子代码,例如

| ?- get(4,2,X), atom_codes(CharAtom,[X]).
X = 42
CharAtom = *

希望这会有所帮助。

答案 1 :(得分:1)

使用矩阵表示法,您可以执行以下操作:

细胞(X,Y,细胞): -     矩阵(行),     Matrix = .. [matrix | Rows],     arg(X,Matrix,Cols),     Row = .. [row | Cols],     精氨酸(Y,行,单元格)     

使用=..动态构建术语可能暗示您的矩阵表示不是最好的。您可以考虑对矩阵进行不同的表示。

假设具有固定长度行的“标准”矩阵,您可以表示矩阵

A B C D
E F G H
I J K L

以几种不同的方式:

  • 单个字符串,如果单元格值可以表示为单个字符,并且您的prolog支持真实字符串(而不是字符串作为char-atom列表):

    "ABCDEFGHIJKL"
    

    查找很简单,零相对(例如,第一行和第一列都编号为0):

    ( RowLength * RowOffset ) + ColOffset
    

    为您提供原子中相应字符的索引。 Retrieval由一个简单的子字符串操作组成。这具有速度和简单的优点。

  • 复合词是另一种选择:

    matrix( rows( row('A','B','C','D') ,
                  row('E','F','G','H') ,
                  row('I','J','K','L')
                )
          ).
    

    查找仍然很简单:

    单元格(X,Y,矩阵,值): -      arg(X,Matrix,Row),      精氨酸(Y,矩阵单元)      

  • 第三个选项可能是使用数据库更直接地使用数据库谓词assertaassertzretractretractall,{来代表您的矩阵{1}},recordarecordzrecorded。您可以构建事实结构,例如在数据库中按照以下方式构建:

    erase

    这样做的好处是允许稀疏(空单元格不需要表示)和锯齿状(行的长度可以变化)表示。

  • 另一个选择(你可能会说,最后的选择)是跳出一个过程语言,如果你的序言允许的话,并以更像矩阵的方式表示矩阵。我必须这样做一次:一旦数据模型超过一定大小,我们就会遇到内存和CPU的巨大性能问题。我们的解决方案是将所需的关系表示为一个巨大的位数组,这在C语言中是微不足道的(而不是在Prolog中)。

我相信你也可以提出其他表示矩阵的方法。

TMTOWTDI(Tim-Toady或“有多种方法可以做到这一点”)正如他们在Perl社区所说的那样。