Почему не десугаред "." синтаксис функтора для списков работает так же, как []? - PullRequest
0 голосов
/ 21 апреля 2020

Я читаю Программирование на Прологе (5-е издание), а в главе 3 книга представляет списки с таким синтаксисом:

Пустой список записывается как [] ... Голова и хвост списка - это компоненты функтора с именем ".", который является точкой (называемой точкой или точкой). Таким образом, список, состоящий из одного элемента "a", равен ".(a,[])", ...

, список, состоящий из атомов a, b и c, записан .(a,.(b,.(c,[]))), ...

Затем на следующей странице она вводит обозначение в квадратных скобках, как если бы оно было эквивалентным предыдущему синтаксису:

В качестве точечного обозначения часто неудобно для написания сложных списков, есть другой синтаксис, который можно использовать для написания списков в программе Prolog. Это обозначение списка состоит из элементов списка, разделенных запятыми, а весь список заключен в квадратные скобки. Например, приведенные выше списки могут быть записаны в нотации списка как [a] и [a,b,c].

На странице после этого вводится синтаксис вертикальной черты [X|Y] для сопоставления по заголовкам списков / Хвосты.

Почему тогда, если я пишу эти факты:

a([1,2,3]).
b(.(1,.(2,.(3,[])))).

Это работает:

?- a([X|Y]).
X = 1,
Y = [2, 3].

Но не это?

?- b([X|Y]).
ERROR: Type error: `dict' expected, found `3' (an integer)
ERROR: In:
ERROR:   [11] throw(error(type_error(dict,3),_7636))
ERROR:    [9] '$dicts':'.'(3,[],_7676) at /usr/lib/swi-prolog/boot/dicts.pl:46
ERROR:    [8] b([_7704|_7706]) at /home/abe/code/programming_in_prolog/ch03/.scratch.pl:2
ERROR:    [7] <user>
ERROR: 
ERROR: Note: some frames are missing due to last-call optimization.
ERROR: Re-run your program in debug mode (:- debug.) to get more detail.

Редактировать: эта попытка также не работает:

?- b(.(X,Y)).
ERROR: Arguments are not sufficiently instantiated
ERROR: In:
ERROR:   [11] throw(error(instantiation_error,_7856))
ERROR:    [9] '$dicts':'.'(_7886,_7888,_7890) at /usr/lib/swi-prolog/boot/dicts.pl:46
ERROR:    [8] '<meta-call>'(user:(...,...)) <foreign>
ERROR:    [7] <user>
ERROR: 
ERROR: Note: some frames are missing due to last-call optimization.
ERROR: Re-run your program in debug mode (:- debug.) to get more detail.

Ответы [ 2 ]

1 голос
/ 21 апреля 2020

Чтобы дополнить ответ Капелли C, в SWI-Prolog атом . заменен [|] в качестве конструктора списка:

?- [user].
|: b('[|]'(1,'[|]'(2,'[|]'(3,[])))).
|: % user://2 compiled 0.00 sec, 1 clauses
true.

?- b(X).
X = [1, 2, 3].

?- b([X|Y]).
X = 1,
Y = [2, 3].

?- b([X,Y|Z]).
X = 1,
Y = 2,
Z = [3].
1 голос
/ 21 апреля 2020

После версии 7 вы должны написать такой громоздкий синтаксис:

?- [user].
|: b('[|]'(1,'[|]'(2,'[|]'(3,[])))).
|: ^D% user://1 compiled 0.01 sec, 1 clauses
true.

?- b([X|Y]).
X = 1,
Y = [2, 3].

Это потому, что, короче говоря, точечная нотация была «соединена» для поддержки средств доступа к словарям в функциональной нотации, например

?- write(_{a:1}.a).
1
true.

Подробнее см. c.

Весь раздел 5 руководства посвящен изменениям синтаксиса SWI-пролога WRT ISO пролог стандарт.

...