Вопрос пролога
Я новичок в прологе, и я должен написать программу о водных кувшинах. Моя проблема касается начального состояния кувшинов и формирования запросов. Запрос будет иметь вид:
?- myPredicate(args), filled(j1,1)
Значение j1 заполнено 1 галлоном воды. j1 представляет один из кувшинов; другой - j2. Изначально у меня есть
filled(j1,0)
filled(j2,5)
capacity(j1,2)
capacity(j2,5)
Буду очень признателен, если вы предоставите мне информацию относительно следующего:
Вопрос A: Должен ли я объявить начальное состояние j1 внутри моей программы? filled(j1,0)
Вопрос B: Мне нужно, чтобы моя программа нашла решение для заполненных (j1,1). Для этого у меня есть несколько идей, но я не уверен, как обновить заполненный (J,Volume) из запроса и myPredicate
,
Я очень смущен, так как у меня есть начальное состояние filled(j1,0)
и теперь я должен создать filled(j1,1)
в myPredicate
, Так что у меня должна быть какая-то форма filled(J,Volume)
в myPredicate
Таким образом, запрос возвращает true вместо false.
Как мне включить filled(J,Voume)
внутри myPredicate
поэтому, когда приведенный выше запрос выполняется, я могу показать правильный ответ?
1 ответ
Пример программы с переданным параметром, исходным фактом и итерационной задачей для выполнения. Итерация осуществляется с помощью рекурсии. Перед каждым повторным входом значение, связанное с определенным параметром, может быть эффективно обновлено для следующего прохода.
my_loop(N) :- N > 10.
my_loop(N) :- N =< 10,
write(N), nl,
Nextin is N + 1,
my_loop(Nextin).
:- my_loop(1).
A:
Данная информация (факты) нужна программе. Они могут быть доступны из ввода с клавиатуры, в качестве начальных аргументов для некоторого предиката или в виде фактов в базе данных, как вы предложили. Кроме того, факты, предложенные только для особых ситуаций, могут быть жестко закодированы в некоторый предикат или правило.
Ниже и выше приведены примеры передачи исходной информации в виде параметров: :- my_predicate(args...)
,
Если фактов много, база данных лучше. Несколько фактов, которые нужно менять каждый раз, лучше всего получать с клавиатуры. В противном случае, это, вероятно, не имеет значения.
:- my_predicate([fill(j1,0),fill(j2,5)], Answer),
write(Answer),
nl.
B:
Смотрите пример моегоцикла _:
В my_loop задача подсчета [1..10] решается итеративно. Givens: 1 передается в качестве параметра, главным образом потому, что программа делает то же самое снова и снова:
1. возьмите номер (N); выйти, если он слишком большой. Иначе...
2. распечатать его.
3. рассчитать следующее число (N + 1)
4. повторить
10 жестко запрограммирован. Это мог быть факт: stop_after(10)
,
Теперь данные для манипуляции, переменная N в my_loop и { j1,j2 } в myPredicate на самом деле не нуждаются в повторном назначении снова и снова: см. My_loop. Просто введите заново вычисления, когда придет время сделать то же самое, но с другими параметрами:
cap(j1,2).
cap(j2,5).
my_predicate(Status, Answer) :-
got_juice(Status,0),
Answer=Status.
%%% Instead of changing values, rerun comp. with new values
%%% based on a computation made from the old ones.
my_predicate([filled(j1,J1), filled(j2,J2)], Answer) :-
Used is J1 + J2,
got_juice(Used, J), J \= 0,
cap(j1,C1), cap(C2),
%% Use cap and filled to add more to filled..
NextJ1 is J1 + ...,
NextJ2 is J2 + ...,
my_predicate(filled(j1,NextJ1), filled(..., Answer).
НОТА:
Вышеприведенный предикат просто демонстрирует итерацию в Прологе, используя параметры "myProgaram". Для фактической реализации см. Программу, предложенную в комментарии от matcheek.