Ввод-вывод
Для ввода термов с консоли используется встроенных унарный предикат 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