【问题标题】:Why can't I reach the array data by the array name in Prolog?为什么我无法通过 Prolog 中的数组名称访问数组数据?
【发布时间】:2020-02-03 09:48:46
【问题描述】:

我正在尝试在 Prolog 中构建一个国际象棋游戏,我首先研究了这篇 Stack Overflow 帖子How to access two dimensional array in prolog and how to loop each element in it,因为我认为国际象棋游戏涉及二维数组形式的棋盘和棋子数据。所以现在我正在尝试用一个更简单的数组来首先了解它是如何工作的。

通过充分利用上面链接中提供的示例代码,我编写了一个print_array(Array) 谓词以及下面的代码。

arraysample([[[1],[2],[3]],[[4],[5],[6]],[[7],[8],[9]]]).

array1([[1],[2],[3],[4],[5]]).

print_array(Array):-
    print_rows(Array).

print_rows([]):-
    write(''),nl.    % trying to create a new line before moving on to the next row, 
                     % but at this moment it's not working
print_rows([Row|Rows]):-
    print_row(Row),
    print_rows(Rows).

print_row([]).
print_row([Cell|Columns]):-
    print_cell(Cell),
    print_row(Columns).

print_cell(Cell):-
    write(Cell),
    write(' ').

当我使用这样的硬编码数组调用谓词时,它会正确打印出数组,结果为true

?- print_array([[[1],[2],[3]],[[4],[5],[6]],[[7],[8],[9]]]).
[1] [2] [3] [4] [5] [6] [7] [8] [9] 
true.

但是当我使用数组名时,它失败了。

?- print_array(array1).
false.

当我使用trace 查看发生了什么时,它只显示了这样的内容。

?- trace(print_array(array1)).
%         print_array/1: [call,redo,exit,fail]
true.

为什么在使用硬编码数组时调用带有数组名称的谓词会失败?我怎样才能让它与数组名称一起工作?

注意:请在回答我的问题时向我展示一些代码,为我提供一些具体的示例,就像我在我的问题中粘贴我的代码一样。如果您正在考虑发布诸如“阅读 Prolog 文档,期间。”之类的抽象评论,这根本不是任何特定问题的答案,首先不要写任何东西。提前致谢。

【问题讨论】:

  • 如果您先输入trace.,然后单独输入您的查询print_array(array1).,您将获得详细的查询步骤。
  • 您误解了 Prolog 的一个基本方面。 array1([[1],[2],[3],[4],[5]]). 用参数[[1],[2],[3],[4],[5]] 断言事实array1array1 不是表示值 [[1],[2],[3],[4],[5]] 的变量。所以调用print_array(array1) 不会在调用中用[[1],[2],[3],[4],[5]] 代替array1print_array 只看到一个原子,array1 这不是一个列表,所以它会立即失败。试试看,array1(X), print_array(X).

标签: prolog


【解决方案1】:

您误解了 Prolog 的一个基本方面。 array1([[1],[2],[3],[4],[5]]). 用参数[[1],[2],[3],[4],[5]] 断言事实array1array1 不是表示值 [[1],[2],[3],[4],[5]] 的变量。所以调用print_array(array1) 不会在调用中用[[1],[2],[3],[4],[5]] 代替array1print_array 只看到一个原子,array1 这不是一个列表,所以它会立即失败。

在查询print_array(array1) 中,Prolog 尝试将此术语与您拥有的任何print_array/1 事实或谓词头统一起来。它找到print_array(Array) 并能够将其与Array = array1 统一起来。

然后它调用print_rows(array1)。它遵循相同的过程。但是,在这种情况下,print_rows/1 的每个谓词头都包含一个列表:

print_rows([]):- ...
print_rows([Row|Rows]):- ...

Prolog 尝试将原子 array1[] 统一并失败(在 Prolog 提示符下尝试 array1 = []. 会失败)。然后它尝试将array1[Row|Rows] 统一并失败(在Prolog 提示符下尝试array1 = [Row|Rows].,它将失败)。

这整个调用 print_array(array1) 失败,因为没有更多的替代方案。

在 Prolog 提示符下执行此操作,而不是 print_array(array1).

:- array1(Array), print_array(Array).

array1(Array) 将查询array1/1 事实并产生解决方案,用[[1],[2],[3],[4],[5]] 实例化Array。那么print_array(Array) 将是print_array([[1],[2],[3],[4],[5]])

【讨论】:

  • 感谢您非常清楚的解释 :) 我按照您的建议进行了尝试,结果完全符合您的预期。
  • @Sean2014 很高兴你已经开始跑步了。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-06-30
  • 1970-01-01
  • 1970-01-01
  • 2020-04-09
  • 2011-12-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多