Предикат проверить каждый элемент диагонали матрицы NxN - PullRequest
1 голос
/ 15 февраля 2012

Мне нужно написать предикат Prolog, чтобы проверить, все ли элементы на диагонали матрицы NxN равны сумме всех других элементов в той же строке.

Например:

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

Любая помощь (совет, ресурс для чтения, ...) очень ценится.

Ответы [ 2 ]

1 голос
/ 15 февраля 2012

SWI-Prolog ' библиотека (списки) реализует nth1 / 3 и sumlist / 2.

Nth1 может действовать как перечислитель, давая и индекс и элементы,поэтому решение может быть очень компактным.

Еще один ключевой элемент - это forall / 2 , см. наглядный пример на странице.

Я позволю вам объединить эти элементыкак полезное упражнение: заполните многоточие ..., будет еще nth1, сумма и арифметика, чтобы проверить, что сумма в 2 раза больше диагонального элемента.

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

Оставьте записку, если вынужен код.

1 голос
/ 15 февраля 2012

Ну, думай декларативно и разбери проблему. Вам нужно разбить матрицу на список списков и рассмотреть каждую строку по очереди, поэтому вам, вероятно, понадобится вспомогательная функция для передачи текущего индекса, например, так:

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, но я надеюсь, что это немного иллюстрирует процесс декларативного программирования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...