Я думаю, что смысл упражнения не в том, чтобы программа говорила «Спасибо», когда вводится предложение [прописной, швейцария, bern], а в том, чтобы использовать переменные, утверждать и запрашиватьчтобы заставить его учиться и вспоминать вещи, и делать что-то смутно умное.
Заголовок вашего правила должен выглядеть примерно так: say([the, capital, of, Subj, is, Obj])
, где Subj
и Obj
- переменные для субъекта и объектаэто отношение, так что ваше правило может соответствовать нескольким предложениям.
Динамический предикат не должен быть say/1
.Это созданный вручную предикат, который хранит / вызывает знания.У вас должен быть другой предикат для хранения ваших знаний, назовем его capital/2
.
:- dynamic capital/2.
. Вы будете использовать assertz(capital(a, b)).
, чтобы вставить факт в базу знаний, и capital(X, Y)
, чтобы запросить его..
В первом случае использования проверьте, являются ли переменные заземленными (это означает, что нас проинструктировали о чем-то), а также проверьте, не знаем ли мы уже тот же факт, и затем вставьте этот факт вбаза знаний:
say([the, capital, of, Subj, is, Obj]) :-
ground((Subj, Obj)),
\+ capital(Subj, Obj), !,
assertz(capital(Subj, Obj)),
write([thank, you]).
Во втором случае мы снова проверяем, что переменные заземлены, но затем мы делаем противоположную проверку и говорим, что мы уже знаем, что:
say([the, capital, of, Subj, is, Obj]) :-
ground((Subj, Obj)),
capital(Subj, Obj), !,
write([i, already, know, that]).
Третий и четвертый случаи работают аналогичным образом, с основными переменными, но ищут несоответствие между инструкцией и тем, что находится в базе знаний:
say([the, capital, of, Subj, is, Obj]) :-
ground((Subj, Obj)),
capital(Subj, Obj1),
Obj1 \= Obj, !,
write([no, you, said, the, capital, of, Subj, is, Obj1]).
say([the, capital, of, Subj, is, Obj]) :-
ground((Subj, Obj)),
capital(Subj1, Obj),
Subj1 \= Subj, !,
write([no, you, said, Obj, is, the, capital, of, Subj1]).
Наконец, последний случай - для ответа на запрос, поэтомуSubj
или Obj
(или оба) должны быть неосновными переменными, и мы печатаем то, что находится в базе знаний:
say([the, capital, of, Subj, is, Obj]) :-
(var(Subj) ; var(Obj)),
capital(Subj, Obj), !,
write([the, capital, of, Subj, is, Obj]).
Обратите внимание, что, поскольку в программе используются сокращения (!
) и assertz/1
, заказиз правил важно.Изменение порядка даст неверные результаты.
Вот полная программа:
:- dynamic capital/2.
say([the, capital, of, Subj, is, Obj]) :-
ground((Subj, Obj)),
capital(Subj, Obj1),
Obj1 \= Obj, !,
write([no, you, said, the, capital, of, Subj, is, Obj1]).
say([the, capital, of, Subj, is, Obj]) :-
ground((Subj, Obj)),
capital(Subj1, Obj),
Subj1 \= Subj, !,
write([no, you, said, Obj, is, the, capital, of, Subj1]).
say([the, capital, of, Subj, is, Obj]) :-
ground((Subj, Obj)),
\+ capital(Subj, Obj), !,
assertz(capital(Subj, Obj)),
write([thank, you]).
say([the, capital, of, Subj, is, Obj]) :-
ground((Subj, Obj)),
capital(Subj, Obj), !,
write([i, already, know, that]).
say([the, capital, of, Subj, is, Obj]) :-
(var(Subj) ; var(Obj)),
capital(Subj, Obj), !,
write([the, capital, of, Subj, is, Obj]).
и тестовый прогон:
?- say([the, capital, of, switzerland, is, bern]).
[thank,you]
true.
?- say([the, capital, of, switzerland, is, bern]).
[i,already,know,that]
true.
?- say([the, capital, of, switzerland, is, zurich]).
[no,you,said,the,capital,of,switzerland,is,bern]
true.
?- say([the, capital, of, france, is, bern]).
[no,you,said,bern,is,the,capital,of,switzerland]
true.
?- say([the, capital, of, What, is, bern]).
[the,capital,of,switzerland,is,bern]
What = switzerland.
?- say([the, capital, of, switzerland, is, What]).
[the,capital,of,switzerland,is,bern]
What = bern.