Замена элементов в матрице в прологе

#matrix #prolog

Вопрос:

Я новичок в прологе и пытаюсь создать конкретную матрицу. То, что у меня уже есть:

  • матрица, заполненная всеми 0-ми
  • список пар чисел, например. [1-1, 2-3, 2-4]

Что я хочу сделать, так это заменить 0-е на 1-е в матрице в позициях, которые обозначены парами чисел. У меня уже есть предикат, который, учитывая матрицу, номер строки и столбца, переключается с 0 на 1, но я застрял при повторении списка пар. Я пытаюсь это сделать:

 %replace(Mx, RowId, ColumnId, Value, ResultMx) %generateMx(Mx, ListOfPairs, ResMx) generateMx(_, [], _). generateMx(Mx, [I-J|Tail], Res) :-  generateMx(Mx, Tail, Res1),  replace(Res1, I, J, 1, Res).  

Но по какой-то причине это дает странные результаты.

Я тоже пытался:

 generateMx(Mx, [], Res) :- Res is Mx. generateMx(Mx, [I-J|Tail], Res) :-  replace(Mx, I, J, 1, Res1),  (Tail == []) -gt; Res is Res1 ; generateMx(Res1, Tail, Res2).  

Для этого я получаю ошибку, но я, по крайней мере, вижу, что он пытается сравнить правильную матрицу результатов с некоторым значением в условии «как есть». Я предполагаю, что он не прекращает повторяться, когда должен?

Может ли кто-нибудь помочь разобраться в моей ошибке и как мне это сделать?

Ответ №1:

generateMx(_, [], _). это неправильно. Если вы хотите, чтобы входные и выходные данные были одинаковыми, вы должны явно сказать так: generateMx(X, [], X). или как generateMx(X, [], Y) :- X = Y. . Оба они эквивалентны, но первый более идиоматичен.

Используя _ в обоих местах, вы говорите generateMx , что добьетесь успеха для любого ввода с любым выводом, пока список пар пуст. Это увенчается успехом, когда этого не должно быть.

 ?- generateMx([[0, 0], [0, 0]], [], [[1, 1], [1, 1]]). true   

Что касается второй части:

  • Я не знаю, как представлена ваша матрица, но is/2 ее можно использовать только для арифметики. Это не универсальный оператор равенства. Вы должны использовать = .
  • -gt; приоритет неправильный. Если вы пишете A, B -gt; C; D , вы на самом деле имеете в виду (A, B) -gt; C; D
  • Если вы проверяете наличие пустого Tail , первое предложение немного избыточно. Ваш первый ответ имеет лучший подход.
 generateMx(Mx, [I-J|Tail], Res) :-  replace(Mx, I, J, 1, Res1),  ( Tail == [] -gt; Res = Res1 ; generateMx(Res1, Tail, Res) ).  

Комментарии:

1. Спасибо, это решило проблему! Я был так уверен, что где-то еще что-то не так, поэтому мне было важно это узнать