Почему SWI-Prolog объединяет строку в кавычках и без кавычек (без пробелов) в одно правило?
Предположим, у меня есть следующие правила:
unify('test', 'this is a test').
run :- write('Enter something: '),
read(X),
unify(X, Y),
write('The answer is '), write(Y).
И тогда я запускаю это следующим образом:
?- ['unify.pl'].
% unify.pl compiled 0.00 sec, -48 bytes
true.
?- run.
Enter something: test.
The answer is this is a test
true.
?- run.
Enter something: 'test'.
The answer is this is a test
true.
Почему SWI-Prolog объединяет оба test
а также 'test'
в unify('test', 'this is a test').
? Я сталкивался с этим, отвечая на вопрос Пролога о SO. Хотя я был в состоянии ответить на вопрос человека, я не мог объяснить это конкретное поведение, и мне было интересно, может ли кто-то еще.
2 ответа
В то время как атомы в SWI-PROLOG могут быть обозначены с помощью одинарных кавычек, например, 'This is an atom'
одинарные кавычки не нужны, когда синтаксический анализатор SWI-PROLOG может идентифицировать атом по последовательности символов, обычно начинающейся со строчного буквенного символа, такого как test
, Если последовательность содержит пробел (или некоторые другие символы), вам понадобятся одинарные кавычки для правильного обозначения атома. Буквенно-цифровые символы и некоторые знаки пунктуации, такие как подчеркивание _
в порядке, например, test5_6
,
Если последовательность символов без одинарных кавычек должна начинаться с чего-либо еще, например с числа 6k
парсер будет воспринимать это как number
; если бы это был заглавный буквенный символ, такой как Test
парсер будет рассматривать его как переменную.
Это не специфическое поведение SWI - это требуется стандартом. Есть простой способ увидеть это. Вы можете использовать это также для любого другого термина, синтаксис которого не очевиден. Либо введите на верхнем уровне:
? - X = "тест". Х = тест.?- X = "это тест". Х = "это тест".
Ответом всегда является действительный текст Пролога - это специфично для SWI, но также и для многих других систем Пролога, таких как YAP, GNU, B, IF, SICStus.
Другой способ убедиться в этом - использовать write_canonical / 1:
? - write_canonical ("это тест"). 'Это тест' правда.?- write_canonical([a,b,(c,d),{e,f}]). ' '(А'. '(Ь,'. '(', '(В, г),'.'({}(','(Д, е)),[]))))