Из приведенной диаграммы ясно видно, что каждый ее горизонтальный уровень является списком, состоящим из некоторого числа элементов. Верхний уровень на приведенной диаграмме представляет список, содержащий четыре элемента, один из которых сам является списком. Второй уровень, содержащий два элемента, представляет четвертый элемент списка верхнего уровня. Работа со списками основана на расщеплении их
Список | Голова | Хвост |
[а, b, с] | а | [b, с] |
[а,] | а | [] |
[] | ||
[[эта, кошка], сидела] | [эта, кошка] | [сидела] |
[эта, [кошка, сидела]] | эта | [кошка, сидела]] |
[эта, [кошка, села], на пол] | эта | [кошка, села], на пол] |
[X+Y, х + y] | X + Y | [x + y] |
Заметим, что пустой список не имеет ни головы, ни хвоста. В последнем примере оператор ± используется как функтор для структур +(Х, Y)и +(х,у).
Так как операция расщепления списка на голову и хвост очень широко используется, то в Прологе введена специальная форма для представления списка с головой Xи хвостом Y. Это записывается как [X|Y], где для разделения Xи Yиспользуется вертикальная черта. При конкретизации структуры подобного вида Xсопоставляется с головой списка, a Y– с хвостом списка, как это показано в следующем примере:
p([1, 2, 3]).
p([эта, кошка, сидела, [на, этой, подстилке]]).
?- p([X|Y]).
X = 1 Y=[2,3]
X=эта Y=[кошка, сидела, [на, этой, подстилке]]
?- p([_,_,_,[_|X]]).
X=[этой, подстилке]
Ниже приведено еще несколько примеров с использованием различных синтаксических возможностей записи списков, показывающих, каким образом производится сопоставление списков. В этих примерах делается попытка сопоставить два заданных списка, конкретизируя переменные, если это возможно.
Список 1 | Список 2 | Конкретизация |
[X, Y, Z] | [джону,нравится,рыба] | X=джону Y= нравится Z = рыба |
[кошка] | [X| Y] | X= кошка |
[X, Y | Z] | [мэри,нравится,вино] | X = мэри Y = нравится Z = [вино] |
[[этот, Y]|Z] | [[X, заяц], [находится, здесь]] | X = этот Y = заяц Z = [[находится_ здесь]] |
[X, Y|Z, W] | (синтаксически некорректная конструкция списка) | |
[золотистый | T] | [золотистый, норфолк] | T= [норфолк] |
[лошадь, X] | [белая, лошадь] | (сопоставление невозможно) |
[белая | Q] | [P | лошадь] | P= белая Q= лошадь |
Как видно из последнего примера, используя скобочную форму записи списков, можно создавать структуры, похожие на списки, но не заканчивающиеся пустым списком. Одна из таких структур, [белая|лошадь],обозначает структуру, головой которой является белая,а хвостом – лошадь.Константа лошадьне является ни списком, ни пустым списком, и, как мы увидим далее, обработка таких структур требует большой осторожности, когда они используются в качестве хвоста списка.
Существует еще одна область применения списков – это представление строк литер. Иногда возникает необходимость в использовании строк литер для печати или ввода текста. Если строка литер заключена в двойные кавычки, то эта строка представляется как список кодов, соответствующих литерам строки. Для кодировки литер используется код ASCII, который обсуждался в разд. 2.2. Например, строка "system"преобразуется в Прологе в следующий список: [115, 121, 115, 116, 101, 109].
3.3. Принадлежность элементов списку
Предположим, что имеется некоторый список, в котором Xобозначает его голову, a Y– хвост списка. Напомним, что такой список мы можем записать так: [X|Y]. Этот список мог бы содержать, например, клички тех лошадей потомков жеребца Coriander,которые все выиграли скачки в Великобритании в 1927 году:
[curragh_tip, music_star, park_mill, portland]
Теперь предположим, что мы хотим определить, содержится ли некоторая кличка в указанном списке. В Прологе это можно сделать, определив, совпадает ли данная кличка с головой списка.