Правильное управление потоком в Прологе без использования не декларативного синтаксиса if-then-else

Я хотел бы проверить произвольный факт и сделать что-то, если оно есть в базе знаний, и что-то еще, если это не так, но без ( I -> T ; E)синтаксис.

У меня есть некоторые факты в моей базе знаний:

unexplored(1,1).
unexplored(2,1).
safe(1,1).

учитывая неполное правило

foo:- safe(A,B),
% do something if unexplored(A,B) is in the knowledge base
% do something else if unexplored(A,B) is not in the knowledge base

Какой правильный способ справиться с этим, не делая это так?

foo:-
   safe(A,B),
   ( unexplored(A,B) -> something ; something_else ).

2 ответа

Не ответ, но слишком длинный для комментария.

"Контроль потока" по определению не является декларативным. Изменение базы данных предикатов (определенных правил и фактов) во время выполнения также не декларативно: оно вводит состояние в вашу программу.

Вы должны очень внимательно рассмотреть вопрос о том, принадлежат ли ваши "данные" базе данных, или можете ли вы сохранить их как структуру данных. Но ваш вопрос не дает достаточно подробностей, чтобы можно было что-либо предложить.

Однако вы можете увидеть этот пример поиска путей через лабиринт. В этом решении база данных содержит информацию о проблеме, которая не изменяется. Сам поиск использует простейшую структуру данных, список. "Контроль потока", если вы хотите его назвать, это неявный: это всего лишь побочный эффект Пролога, ищущего доказательства. Что еще более важно, вы можете спорить о программе и о том, что она делает, не принимая во внимание точный поток управления (но вы принимаете во внимание стратегию разрешения Пролога).

Основная проблема с этим требованием состоит в том, что оно немонотонно:

Вещи, которые сохраняются без этого факта, могут внезапно перестать существовать после добавления такого факта

Это по своей сути противоречит важному и желательному декларативному свойству монотонности.

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

По этой причине ваше требование неразрывно связано с немонотонными конструкциями, такими как if-then-else, !/0 а также setof/3,

Декларативный способ рассуждать об этом - полностью избегать проверки свойств базы знаний. Вместо этого сосредоточьтесь на четком описании вещей, которые держатся, используя предложения Пролога для кодирования знаний.

В вашем случае, похоже, вам нужно рассуждать о состоянии какой-то проблемы поиска. Декларативный способ решения таких задач состоит в том, чтобы представлять государство в качестве термина Пролог и писать чисто монотонные правила с участием государства.

Например, скажем, что государство S0 связано с государством S если мы исследуем определенную позицию Pos что ранее не исследовалось:

state0_state(S0, S) :-
    select(Pos-unexplored, S0, S1),
    S = [Pos-explored|S1].

или короче:

state0_state(S0, [Pos-explored|S1) :-
    select(Pos-unexplored, S0, S1).

Я оставляю в качестве простого упражнения выяснение состояния штата, которое я использую здесь. Обратите внимание на удобное соглашение об использовании имен S0, S1,..., S связать разные штаты

Таким образом, вы кодируете явные отношения о терминах Prolog, которые представляют состояние. Чисто, однообразно и работает во всех направлениях.

Другие вопросы по тегам