Как использовать Ground/1?
Я начинающий с Пролога, и я хотел знать, как использовать ground/1
,
На данный момент у меня есть этот код:
intertwine([], [], []).
intertwine([E|Es], Fs, [E|Gs]) :- intertwine(Es, Fs, Gs).
intertwine(Es, [F|Fs], [F|Gs]) :- intertwine(Es, Fs, Gs).
Но когда я пытаюсь вызвать это в оболочке:
intertwine([1,2],X,[1,a,2,b]).
Я получаю правильный ответ X=[a,b]
, но запрос не заканчивается, как будто он думает, что остался другой ответ. Итак, я нажимаю ";" и я получаю "ложь" в качестве вывода. Я прочитал в ответе на другой вопрос, что я должен использовать ground/1
проверить, полностью ли создан третий список для обработки дела.
Дело в том, что, будучи полным новичком, я понятия не имею, как это сделать. Так есть ли кто-то достаточно любезный, чтобы объяснить мне, как работает основание и как я могу использовать его для проверки создания экземпляра определенного параметра и использовать его, чтобы не проверять код для ответа, которого там нет?
3 ответа
Это поведение вполне нормально. Иногда Пролог способен выяснить, что нет дальнейшего решения, а иногда нет. Детали не имеют значения к тому, что описано. Рассматривать:
?- X = 1 ; 2 = 3.
X = 1 ;
false.
Здесь для нас очевидно, что 2 = 3
Это не решение, но Пролог просит нас продолжать.
Кстати, вместо; Вы также можете нажать пробел, чтобы получить следующее решение.
Вместо ground / 1, чтобы проверить установку параметра, вы должны рассмотреть использование var / 1 (или связанного с ним nonvar/1). var/1 это фундаментальный метапредикат, который расширяет возможности Пролога за пределы того, что известно как чистое подмножество языка. Это позволяет рассуждать о самой программе, выбирая подходящее поведение в зависимости от "состояния" таких фундаментальных объектов как переменные.
(Очень) простое использование этих метапредикатов из практического программирования POV позволяет реализовать значения по умолчанию для определенных параметров: например,
%% gunzip(+Gz, ?Ex) is det.
%
% uncompress the file Gz in Ex
% if Ex is var strip .gz extension
%
gunzip(Gz, Ex) :-
( nonvar(Ex)
-> true
; atom_codes(Gz, Cs),
phrase(string(ExCs), Cs, ".gz"),
atom_codes(Ex, ExCs)
),
gzopen(Gz, read, I, [type(binary)]),
setup_call_cleanup(open(Ex, write, O, [type(binary)]),
copy_stream_data(I, O),
( close(I), close(O) )
).
если мы вызываем gunzip('file.gz', F), F получает экземпляр (надеюсь) с именем завышенных данных.
Как сказал ложный, это поведение действительно хорошо. ground/1
предикат на самом деле не связан с этим вопросом.
не иметь проверки кода для ответа, которого там нет?
Cut может быть полезным, если я правильно понял ваш вопрос.
intertwine([], [], []).
intertwine([E|Es], Fs, [E|Gs]) :- intertwine(Es, Fs, Gs), !.
intertwine(Es, [F|Fs], [F|Gs]) :- intertwine(Es, Fs, Gs), !.
Итак, вы получили свой единственный ответ.
?- intertwine([1,2],X,[1,a,2,b]).
X = [a, b].
?-