Преобразование входного потока в ASCII: объяснение кода Prolog

Я пытаюсь прочитать и преобразовать строку в значение ASCII, используя предикат Prolog read_command/1.

Следующий код работает. Может ли кто-нибудь объяснить, как понять этот код ниже?

read_command(L) :-             % read_command/1
    get0(C),
    read_command(_, L, C).

read_command(_, [], X) :-      % auxiliary predicate read_command/3
    member(X, `.\n\t`),
    !.
read_command(X, [C|L], C) :-
    get0(C1),
    read_command(X, L, C1).

person Krishna Kalyan    schedule 03.01.2016    source источник
comment
@повторите, почему ваш ответ был удален?   -  person Krishna Kalyan    schedule 05.01.2016
comment
Мой ответ нуждается в доработке... он вернется!-)   -  person repeat    schedule 06.01.2016


Ответы (2)


read_command/1 считывает первый символ, доступный из текущего входного потока, и использует его как предварительный просмотр.

read_command/3 просто останавливается, когда опережающий просмотр представляет собой пробел или точку. В противном случае поместите просмотр вперед в список, получите новый просмотр вперед из потока и рекурсивно.

Я думаю, что первое предложение read_command/3 также должно обрабатывать случай, когда X равен -1, что означает конец файла (например, после нажатия Ctrl+D)

person CapelliC    schedule 03.01.2016

TL;DR: Не используйте get0/1!

get0/1 считается устаревшим даже процессорами Prolog, которые его реализуют (например, SWI).

Вместо этого используйте get_char/1 и представляйте строки в виде списков. символовне в виде списков кодов!

read_command(Chars) :-
   get_char(Next),
   read_command_aux(Chars, Next).

read_command_aux(Chars, Char) :-
   member(Char, ['.', '\t', '\n', end_of_file]),
   !,
   Chars = [].
read_command_aux([Char|Chars], Char) :-
   get_char(Next),
   read_command_aux(Chars, Next).

Вот несколько примеров запросов с использованием SWI-Prolog 7.3.15:

?- read_command(Chars).
|: abc
Chars = [a, b, c].

?- read_command(Chars).
|: abc.

Chars = [a, b, c].

?- read_command(Chars).
|: 123abc
Chars = ['1', '2', '3', a, b, c].

Для дальнейшего использования команд вы можете использовать атомы, например:

?- read_command(Chars), atom_chars(Command, Chars).
|: abcd.

Chars = [a, b, c, d],
Command = abcd.

Обратите внимание, что это работает не только с SWI, но и с SICStus Prolog 4.3.2 (и другими).

person repeat    schedule 22.01.2016