Ввод-вывод

Для ввода термов с консоли используется встроенных унарный предикат read. Этот предикат выполняется не более одного раза; вводимый терм унифицируется с аргументом; вводимый терм может заканчиваться точкой и может занимать несколько строк. Примеры (вводимые данные подчеркнуты):

?- read(X). |: atom. X = atom.

?- read(X). |: 123. X = 123.

?- read(X). |: 1+ |: 2+ |: 3. X = 1+2+3.

?- read(X). |: .(1, []). X = [1].

?- read([X, Y]). |: [1, 2]. X = 1, Y = 2.

?- read([X, Y]). |: 1. false.

?- read(E), X is E. |: 1 + 2. E = 1+2, X = 3.

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

?- write(atom). atom true.

?- write('Hello World!'). Hello World! true.

?- write('Hello'), write(' World!'). Hello World! true.

?- write(1 + 2 * 3). 1+2*3 true.

?- write(X). _G283 true.

Также для вывода термов можно использовать унарный предикат write_canonical. Примеры:

?- write_canonical(atom). atom true.

?- write_canonical('Hello World!'). 'Hello World!' true.

?- write_canonical('Hello'), write_canonical(' World!'). 'Hello'' World!' true.

?- write_canonical(1 + 2 * 3). +(1,*(2,3)) true.

?- write_canonical(X). _ true.

Помимо высокоуровневых предикатов для ввода-вывода термов в Прологе есть низкоуровневые предикаты, позволяющие вводить и выводить отдельные символы; при этом сами символы представляются атомами, состоящими из одного символа. Так для ввода отдельных символов используется встроенный унарный предикат get_char. Этот предикат удовлетворяется в точности один раз. Примеры:

?- get_char(X). |: a X = a

?- get_char(X). |: A X = 'A'.

?- get_char(X). |: abc X = a.

?- get_char(X). |: 123 X = '1'.

?- get_char(X), get_char(Y). |: abc X = a, Y = b.

?- get_char(X), get_char(Y). |: a X = a, Y = '\n'.

Если при попытке выполнить предикат get_char обнаруживается конец файла, то предикат get_char унифицирует свой аргумент со специальным атомом end_of_file (работая с консолью конец файла можно смоделировать, нажав Control + D).

Для вывода символов используется унарный предикат put_char. Аргумент этого предиката должен быть атомом, состоящим из одного символа. Примеры:

?- put_char(a). a true.

?- put_char(A). ERROR: put_char/1: Arguments are not sufficiently instantiated

?- put_char('A'). A true.

?- put_char(abc). ERROR: put_char/1: Type error: `character' expected, found `abc'

?- put_char('\n'). true.

?- put_char(65). A true.

Для перевода строки можно использовать предикат nl, не имеющий аргументов.

Пример процедуры для ввода строки (определение предиката подчеркнуто сплошной линией):

get_line(L) :- get_char(C), get_rest_of_line(C, L).

get_rest_of_line(C, L) :- C = '\n', !, L = [].

get_rest_of_line(C, L) :- get_line(M), L = [C | M].

?- get_line(L). |: Hello! L = ['H', e, l, l, o, !].

?- get_line(L). |: L = [].

Пример процедуры для вывода строки:

put_line([]) :- nl.

put_line([C | L]) :- put_char(C), put_line(L).

?- put_line(['H', e, l, l, o, !]). Hello! true.

?- put_line([]). true.

При использовании посимвольного ввода-вывода может оказаться необходимым преобразовать список символов в атом или число, либо, наоборот атом или число в список символов. Для этого используются бинарные предикаты atom_chars и number_chars соответственно. Примеры:

?- atom_chars(abc, X). X = [a, b, c].

?- atom_chars(X, [a, b, c]). X = abc.

?- atom_chars(X, ['A', b, c]). X = 'Abc'.

?- atom_chars(X, [a, 'B', c]). X = aBc.

?- atom_chars(X, a). ERROR: atom_chars/2: Type error: `list' expected, found `a'

?- number_chars(12.3, X). X = ['1', '2', '.', '3'].

?- number_chars(X, ['1', '2', '.', '3']). X = 12.3.

?- number_chars(X, ['a', 'b', 'c']). ERROR: number_chars/2: Syntax error: Illegal number