Как использовать 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].

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