Пролог, возвращающий пустой список, проблема с базовым регистром для рекурсивного предиката - PullRequest
1 голос
/ 06 июня 2019

Так что в основном я работаю со списком списков, которые создают сетку 100x100. Ниже я создаю предикат, который принимает сетку, заменяет ячейки строк на все и возвращает новую доску. Пока что все другие предикаты, которые я сделал, работали так, как задумано, поэтому я просто покажу проблемную часть:

generationRow(L,_,0,L).
generationRow(Board,X,Y,New) :-
    Y > 0, 
    X1 is X-1, % account for 0 indexed array
    Y1 is Y-1,
    replaceCell(Board,X1,Y1,1,NewBoard),
    generationRow(NewBoard,X,Y1,NewBoard).

Когда я выполняю строку генерации как таковую: generationRow (совет, 10100, NewBoard) написать (Newboard).

Возвращает Newboard = [], что поражает меня, потому что replacecell возвращает правильный массив при вызове. Таким образом, я думаю, что проблема должна быть в моем базовом случае. Основываясь на алгоритме, базовый случай должен быть, когда Y = 0, X никогда не изменится, и доска должна быть равна Newboard. Я думал, что сделал это правильно.

1 Ответ

1 голос
/ 06 июня 2019

Вы, вероятно, допустили ошибку в своем последнем звонке:

generationRow(L,_,0,L).
generationRow(Board, X, Y, <b>New</b>) :-
    Y > 0, 
    X1 is X-1, % account for 0 indexed array
    Y1 is Y-1,
    replaceCell(Board,X1,Y1,1, NewBoard),
    generationRow(NewBoard, X, Y1, <b>New</b>).

В исходном фрагменте кода вы сделали вызов с generationRow(NewBoard,X,Y1,NewBoard), это означает, что вы искали способ к generateRow/4, где начальная и конечная доски - это одинаковые , так что это гарантирует, что ни один рекурсивный вызов не сможет сделать дальнейшую «прогрессию» после того, как вы сгенерировали newBoard.

В конце концов, replaceCell (хорошо, если я правильно понял) меняет одну ячейку доски, и вы хотите сделать рекурсивный вызов, чтобы изменить ячейки в оставшихся строках.

Большинство интерпретаторов Пролога предупреждают вас, если переменная встречается только один раз в предложении. Например, в SWI Prolog мы получаем:

Warning: /tmp/pl.pl:6:
    <b>Singleton variables</b>: [New]

Таким образом, это означает, что вы определили New в голове, но никогда в теле не связали его должным образом. Это как минимум странно. Если вы действительно не интересуетесь этой переменной, вы обычно используете подчеркивание (тогда интерпретатор не покажет эту ошибку).

...