谓词检查矩阵NxN的对角线的每个元素

时间:2012-02-15 05:13:49

标签: prolog

我需要编写一个Prolog谓词来检查矩阵NxN的对角线上的所有元素是否等于同一行中所有其他元素的总和。

例如:

check([[1, 0, 1], [1, 2, 1], [7, 8, 15]]) => true

非常感谢任何帮助(提示,阅读资源......)。

2 个答案:

答案 0 :(得分:1)

好吧,以声明的方式思考并打破问题。你需要将矩阵分解为一个列表列表并逐一考虑每一行,所以你可能需要一个辅助函数来传递当前索引,如下所示:

check(Xs) :- check_all(Xs, 0).
check_all([X|Xs], Index) :- 
  /* do work */
  Index1 is Index + 1, check_all(Xs, Index1).

check_all可能需要一个基本案例,它可能看起来像这样:

check_all([], _).

所以现在你需要弄清楚如何基于拥有它和索引来检查给定的行,所以你现在需要一个谓词来检查一行:

check_row(Row, Index) :-
  ...

此谓词必须拆分列表并将值相加,然后将它们与索引处的值进行比较,以便获得所需的值:

  nth0(Index, Row, Desired),

你需要一些方法来删除该索引处的项目并考虑余数的总和。事实上,你知道如果剩下的项目加起来你想要的值,那就通过测试:

  nth0(Index, Row, _, Remainder), sumlist(Remainder, Desired)

因此总共产生:

check_row(Row, Index) :-
  nth0(Index, Row, Desired, Remainder), sumlist(Remainder, Desired).
check_all([], _).
check_all([Row|Rows], Index) :-
  check_row(Row, Index),
  Index1 is Index + 1, check_all(Rows, Index1).
check(Xs) :- check_all(Xs, 0).

我没有测试过这段代码所以我不知道它是否有效,而且我当然依赖于SWI-Prolog的列表库,但我希望这能说明一下声明式编程过程。

答案 1 :(得分:1)

SWI-Prolog'库(列表)实现了nth1 / 3和sumlist / 2.

Nth1可以充当枚举器,产生两个索引和元素,因此解决方案可以非常紧凑。

另一个关键元素forall/2,请参阅页面以获得启发性示例。

我会让你把这些元素组合起来作为一个有用的练习:填写省略号...,会有另一个nth1,一个sumlist,以及一个算术来检查summed是对角元素的2倍。

   check(M) :-
      forall(nth1(I, M, Row), (...)).

如果您需要代码,请删除备注。