Список в Прологе реализован как связанный список функторов. Если вы напишите список, как [a, b, c, d]
. на самом деле это выглядит так:
+-------+
| (|)/2 |
+---+---+ +-------+
| o | o---->| (|)/2 |
+-|-+---+ +---+---+ +-------+
v | o | o---->| (|)/2 |
a +-|-+---+ +---+---+ +-------+
v | o | o---->| (|)/2 |
b +-|-+---+ +---+---+
v | o | o----> []
c +-|-+---+
v
d
или в нотации Пролога [a | [b | c | [d | [] ] ] ]
. Список через запятую: синтаксический сахар : если вы напишите [a, b, c, d]
, интерпретатор Prolog преобразует его в представление, как указано выше.
Так как [b, c, d]
равно:
[ b | [ c | [ d | [] ] ] ]
и, таким образом, [ a | [b, c, d] ]
, таким образом, равен
[a | [b | c | [d | [] ] ] ]
Но список [X, Y]
просто равен
[X, Y] == [ X | [ Y | [] ] ]
или конструктивно:
+-------+
| (|)/2 |
+---+---+ +-------+
| o | o---->| (|)/2 |
+-|-+---+ +---+---+
v | o | o----> []
X +-|-+---+
v
Y
Если мы затем сопоставим его с [a | [b | c | [d | [] ] ] ]
, это означает, что «внешняя» оболочка может быть сопоставлена, то есть X = a
, но затем Y = b
и [] = [ c | [ d | [] ] ]
. Последняя часть не совпадает, и поэтому возвращает false
. Таким образом, X
и Y
не являются проблемой. Проблема в том, что []
является константой, и она не совпадает с функтором, который представляет [ c | [d] ]
.
Если мы, например, объединим [ X | Y ] == [a, b, c, d]
, мы получим:
?- [ X | Y ] = [a, b, c, d].
X = a,
Y = [b, c, d].
Итак, в заключение можно сказать, что |
сам "ничего" не делает. Это функтор, как и f(1, 2)
. В Лиспе они использовали cons
[wiki] для этого и nil
для пустого списка. Так что [1, 4, 2, 5]
выглядит в Лиспе как cons 1 (cons 4 (cons 2 (cons 5 nil)))
, или в Прологе это будет выглядеть как cons(1, cons(4, cons(2, cons(5, nil))))
. Это только немного громоздко писать. На самом деле обозначение через запятую - это больше «волшебная» часть. Пролог просто выполняет объединение для списков, как и для других функторов и констант.