Пролог - объединение двух списков с / без переменных - PullRequest
0 голосов
/ 29 октября 2018

Этот код Пролога возвращает:

?- [a,b,c,d]  =  [a|[b,c,d]].

правда

и этот

?- [X,Y] = [a|[b,c,d]].

возвращает false.

Я не совсем понимаю, почему [X, Y] ложно. Трассировка здесь не помогает. Я ожидаю, что следующее задание будет содержать

X = a
Y = [b,c,d]

и утверждение будет верным.

Что делает | помимо расщепления на голове и хвосте?

1 Ответ

0 голосов
/ 29 октября 2018

Список в Прологе реализован как связанный список функторов. Если вы напишите список, как [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)))). Это только немного громоздко писать. На самом деле обозначение через запятую - это больше «волшебная» часть. Пролог просто выполняет объединение для списков, как и для других функторов и констант.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...