Почему я не могу получить данные массива по имени массива в Прологе? - PullRequest
0 голосов
/ 03 февраля 2020

Я пытаюсь построить шахматную игру в Прологе, и я начал с изучения этой статьи о переполнении стека Как получить доступ к двумерному массиву в прологе и как l oop каждый элемент в нем , потому что я думаю, что игра в шахматы включает в себя данные доски и фигур в виде двумерного массива. Поэтому сейчас я пытаюсь поэкспериментировать с более простым массивом, чтобы понять, как он работает в первую очередь.

Используя большинство примеров кода, приведенных в ссылке выше, я написал предикат print_array(Array) вместе с код ниже.

arraysample([[[1],[2],[3]],[[4],[5],[6]],[[7],[8],[9]]]).

array1([[1],[2],[3],[4],[5]]).

print_array(Array):-
    print_rows(Array).

print_rows([]):-
    write(''),nl.    % trying to create a new line before moving on to the next row, 
                     % but at this moment it's not working
print_rows([Row|Rows]):-
    print_row(Row),
    print_rows(Rows).

print_row([]).
print_row([Cell|Columns]):-
    print_cell(Cell),
    print_row(Columns).

print_cell(Cell):-
    write(Cell),
    write(' ').

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

?- print_array([[[1],[2],[3]],[[4],[5],[6]],[[7],[8],[9]]]).
[1] [2] [3] [4] [5] [6] [7] [8] [9] 
true.

Но когда я использую имя массива, он терпит неудачу.

?- print_array(array1).
false.

И когда я использовал trace, чтобы увидеть, что происходит, мне показалось только что-то вроде этого.

?- trace(print_array(array1)).
%         print_array/1: [call,redo,exit,fail]
true.

Почему сбой вызова предиката с именем массива в то время как он работает с жестко закодированным массивом? Как мне заставить его работать с именем массива?

ПРИМЕЧАНИЕ. Пожалуйста, предоставьте мне несколько конкретных примеров, показывая мне код, когда вы отвечаете на мой вопрос, так же, как я вставил свой код в свой вопрос. Если вы думаете о публикации абстрактного комментария типа «Прочитайте документацию Пролога, точка.», Который вообще не является ответом ни на один конкретный c вопрос, не пишите ничего в первую очередь. Заранее спасибо.

1 Ответ

2 голосов
/ 03 февраля 2020

Вы неправильно понимаете фундаментальный аспект Пролога. array1([[1],[2],[3],[4],[5]]). утверждает факт array1 с аргументом, [[1],[2],[3],[4],[5]]. array1 не является переменной, представляющей значение [[1], [2], [3], [4], [5]]. Таким образом, вызов print_array(array1) не заменяет [[1],[2],[3],[4],[5]] на array1 в вызове. print_array просто видит атом, array1, который не является списком, поэтому он сразу выходит из строя.

В запросе print_array(array1) Пролог пытается объединить этот термин с любыми print_array/1 фактами или заголовками предикатов. у тебя есть. Он находит print_array(Array) и может объединить его с Array = array1.

Затем он вызывает print_rows(array1). Это следует тому же процессу. Однако в этом случае каждый заголовок предиката для print_rows/1 включает список:

print_rows([]):- ...
print_rows([Row|Rows]):- ...

Пролог пытается объединить атом array1 с [] и завершается неудачно (попробуйте array1 = []. в приглашении Пролога и это не удастся). Затем он пытается объединить array1 с [Row|Rows] и терпит неудачу (попробуйте array1 = [Row|Rows]. в приглашении Prolog, и он потерпит неудачу).

Весь этот вызов print_array(array1) завершится неудачей, так как больше нет альтернатив .

Вместо print_array(array1)., сделайте это в приглашении Prolog:

:- array1(Array), print_array(Array).

array1(Array) запросит факты array1/1 и приведет к решению, инстанцируя Array с [[1],[2],[3],[4],[5]]. Тогда print_array(Array) будет print_array([[1],[2],[3],[4],[5]]).

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