Pourquoi SWI-Prolog unifie une chaîne entre guillemets ou non (sans espaces) à la même règle?
-
29-09-2019 - |
Question
Supposons que je les règles suivantes:
unify('test', 'this is a test').
run :- write('Enter something: '),
read(X),
unify(X, Y),
write('The answer is '), write(Y).
Et puis je cours comme suit:
?- ['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.
Pourquoi SWI-Prolog unifie les deux test
et 'test'
à unify('test', 'this is a test').
? Je suis tombé sur ce tout en répondant à une question sur le SO Prolog. Alors que j'ai pu répondre que je ne pouvais pas la question de la personne, expliquer ce comportement particulier, et je me demandais si quelqu'un d'autre pourrait.
La solution
Alors que les atomes dans SWI-Prolog peuvent être désignées à l'aide des guillemets simples, par exemple, 'This is an atom'
, guillemets simples sont pas nécessaire lorsque l'analyseur SWI-Prolog peut identifier un atome à partir d'une séquence de caractères, en commençant habituellement avec un caractère alphabétique minuscule, comme test
. Si la séquence contient des espaces (ou d'autres caractères), vous aurez besoin des guillemets simples pour désigner un atome correctement. Les caractères alphanumériques et certains caractères de ponctuation comme _
underscore sont très bien, par exemple, test5_6
.
Si la séquence de caractères sans les guillemets simples devaient commencer quoi que ce soit d'autre, comme un 6k
numéro, l'analyseur traitera comme un number
; si elle était un caractère alphabétique majuscule tels que Test
, l'analyseur traitera comme une variable.
Autres conseils
Ce n'est pas un comportement spécifique SWI - il est requis par la norme. Il existe un moyen simple de voir. Vous pouvez utiliser aussi pour tout autre terme dont la syntaxe est pas évidente. Les deux types au premier niveau:
?- X = 'test'. X = test. ?- X = 'this is a test'. X = 'this is a test'.
La réponse est toujours valide le texte Prolog - ceci est spécifique à SWI mais également à de nombreux autres systèmes Prolog comme YAP, GNU, B, IF, SICStus.
Une autre façon de voir est d'utiliser write_canonical / 1:
?- write_canonical('this is a test'). 'this is a test' true. ?- write_canonical([a,b,(c,d),{e,f}]). '.'(a,'.'(b,'.'(','(c,d),'.'({}(','(e,f)),[]))))