Правильное управление потоком в Прологе без использования не декларативного синтаксиса 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, которые представляют состояние. Чисто, однообразно и работает во всех направлениях.