Почему эти два предложения пролога имеют разные результаты? - PullRequest
0 голосов
/ 01 декабря 2018

Я недавно начал изучать Пролог, и есть кое-что, чего я не понимаю.

Почему эти два предложения дают разные результаты?
Я понимаю, что все слева от [|] выражение должно быть главой списка, а справа мы располагаем хвостом списка.
Я подозреваю, что это должно быть тривиально, но в конце я не понимаю, почему, как в первом случае, во второмне объединяет обе части в один список.

?- X = [2|[1]].
   X = [2,1].

?- X = [[1]|2].
   X = [[1]|2].

1 Ответ

0 голосов
/ 01 декабря 2018

Ну, во-вторых, это не список, или, по крайней мере, то, что «сообщество Прологов» считает списком.

Если мы посмотрим на то, что вы написали, первое выражение можно рассматривать как нечто похожееto:

+-------+
|  cons |
+---+---+  +-------+
| o | o--->|  cons |
+-|-+---+  +---+---+
  v        | o | o---> nil
  2        +-|-+---+
             v
             1

Итак, это список: вы в основном строите «минусы», используя head 2 и, как хвост, другой список.Обратите внимание, что заголовком списка является элемент, а хвостом списка является список с оставшимися элементами.

Во втором примере вы, вероятно, сделали опечатку, возможно, вы написали:

?- X = [[1]|2].
X = [[1]|2].

В этом случае «список» выглядит следующим образом:

+-------+
|  cons |
+---+---+
| o | o---> 2
+-|-+---+
  v        
+-------+
|  cons |
+---+---+
| o | o---> []
+-|-+---+
  v
  1

Обратите внимание, что на самом деле это не список: глава минусов, это элемент, и, конечно, такой элементможет быть списком (поскольку мы можем создавать списки списков и т. д.), но хвост здесь - просто элемент.

Это означает, что можно не применять синтаксический сахар, итаким образом замените это чем-то вроде [1,2].Обратите внимание, что [1] на самом деле является синтаксическим сахаром для [1|[]], а [2,1] является синтаксическим сахаром для [2|[1|[]]] (как показано на первом изображении).Но [[1]|2] не имеет такого синтаксического сахарного эквивалента.

Большинство интерпретаторов Prolog позволяют писать списки каноническим способом, например, в GNU Prolog:

| ?- write_canonical([1]).
'.'(1,[])

(1 ms) yes
| ?- write_canonical([1,2]).
'.'(1,'.'(2,[]))

(1 ms) yes
| ?- write_canonical([[1]|2]).
'.'('.'(1,[]),2)

yes

Здесь мы видим, чтофункция "cons" - это точка '.', которая является функтором).

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