Рекурсия с несколькими переменными - PullRequest
0 голосов
/ 27 декабря 2018

Я новичок в Прологе, извините за тривиальный вопрос.

Давайте рассмотрим следующий код:

at(X, Y, 0) :- 
  X =:=1, 
  Y =:=1,
  !.
at(X, Y, S) :- 
  S \== 0, 
  at(XP, Y, SP), 
  S is SP + 1, 
  X is XP + 1.

При запуске at(1, 1, 1) я получаю следующую ошибку:

ОШИБКА: недостаточно аргументированы аргументы
ОШИБКА: В:
ОШИБКА: [10] _2090 =: = 1
ОШИБКА: [9] в (_2116,2,0)в /tmp/d.pl:1
ОШИБКА: [8] в (1,2,1) в /tmp/d.pl:2
ОШИБКА: [7]

Я понимаю ошибку, но не могу найти решение этой проблемы.

Я также использовал at(1, 1, 0)., но в этом случае это переполняет стек.

Очевидно, фрагмент кода являетсяупрощенная версия моего проекта.По этой причине я не могу просто переосмыслить предикат at следующим образом:

at(X, Y, S) :- 
  Y =:= 1, 
  X =:= S + 1.

Как исправить предикат at без полного переосмысления реализации при условии, что это возможно?

Спасибо за вашу помощь.

По просьбе @lurker я добавляю более подробную информацию об исходной проблеме, с которой я столкнулся.По сути, я пытаюсь реализовать систему рассуждений, используя Prolog для решения Wumpus world .Я наложил ограничение на то, какие функции я мог бы использовать в Прологе: нет assert* и соответствующие инструкции.

Основная идея состояла в том, чтобы определить переменную S, которая является состоянием системыи это вход для большинства функций.Затем я попытался реализовать функцию, которая определяет , где агент находится в определенном состоянии системы .

Это моя последняя (глючная) версия моей функции at:

at(1, 1, S) :- S =:= 0, !.
at(X, Y, S) :-
    writef('Am I at %w, %w at status %w?\n', [X, Y, S]),
    (
        S \== 0,
        (
            at(XP, Y, SP), forwarded(XP, Y, SP), direction(XP, Y, 0, SP), S is SP + 1, X is XP + 1, X > 0, !;
            at(X, YP, SP), forwarded(X, YP, SP), direction(X, YP, 1, SP), S is SP + 1, Y > 0, Y is YP + 1, !;
            at(XP, Y, SP), forwarded(XP, Y, SP), direction(XP, Y, 2, SP), S is SP + 1, X is XP - 1, !;
            at(X, YP, SP), forwarded(X, YP, SP), direction(X, YP, 3, SP), S is SP + 1, Y is YP - 1, !
        ),
        writef('--------> I am at %w, %w, status %w\n', [X, Y, S])
    );
    (writef('--------> I am NOT at %w, %w, status %w\n', [X, Y, S]), fail).

Приведенный выше фрагмент относится к двум дополнительным функциям:

  1. forwarded/3: верно, если агент с определенным статусом решил двигаться в направлении текущего направления
  2. direction/4: это правда, если агент с определенным статусом (и позицией ... ну, возможно, я мог бы удалить такие переменные из этой функции. Не уверен, действительно ...) имеет конкретное направление

Таким образом, основная идея, например, заключается в том, что если агент находится в (1, 1), направление 0 в состоянии 0 (направление может быть 0, 1, 2, 3 соответственно, вправо, вверх,влево, вниз), затем в статусе 1 он находится в (2, 1).

Поскольку агент выигрывает, если у него есть золото, и он находится в начальной точке, моя целевая функция:

win(S) :- hold_gold(S), X is 1, Y is 1, at(X, Y, S).

Если я вызову переводчика и напишу win(S) (хотелось бы знать, в каком статусе победит агентs), это идет к бесконечной рекурсии.Как написано выше, я понимаю причину, но не могу найти способ смоделировать проблему в Прологе.Я бы не знал, как определить всю структуру рассуждений, поскольку она оказалась довольно простой.

Спасибо.

...