我需要编写一个Prolog谓词来检查矩阵NxN的对角线上的所有元素是否等于同一行中所有其他元素的总和。
例如:
check([[1, 0, 1], [1, 2, 1], [7, 8, 15]]) => true
非常感谢任何帮助(提示,阅读资源......)。
答案 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), (...)).
如果您需要代码,请删除备注。