Как использовать землю / 1? - PullRequest
2 голосов
/ 02 декабря 2011

Я начинающий с Пролога, и я хотел знать, как использовать 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 ]

2 голосов
/ 02 декабря 2011

Это поведение полностью в порядке.Иногда Пролог может выяснить, что нет дальнейшего решения, а иногда нет.Детали не имеют значения к тому, что описано.Рассмотрим:

?- X = 1 ; 2 = 3.
X = 1 ;
false.

Здесь для нас очевидно, что 2 = 3 не является решением, однако Пролог просит нас продолжать.

Кстати, вместо;Вы также можете нажать ПРОБЕЛ, чтобы получить следующее решение.

0 голосов
/ 02 декабря 2011

Вместо 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 получит экземпляр (как мы надеемся) с именем завышенных данных.

0 голосов
/ 02 декабря 2011

Как сказал ложь, это поведение действительно нормально.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].

?- 
...