Perché SWI-Prolog unificare una stringa quotate e non quotate (senza spazi) per la stessa regola?
-
29-09-2019 - |
Domanda
Si supponga che ho le seguenti regole:
unify('test', 'this is a test').
run :- write('Enter something: '),
read(X),
unify(X, Y),
write('The answer is '), write(Y).
E poi ho eseguito come segue:
?- ['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.
Perché SWI-Prolog unificare sia test
e 'test'
a unify('test', 'this is a test').
? Mi sono imbattuto in questo mentre rispondendo ad una domanda su SO Prolog. Mentre ero in grado di rispondere alla domanda di una persona, non ho potuto spiegare questo particolare comportamento, e mi chiedevo se qualcuno altro potrebbe.
Soluzione
Mentre atomi SWI-PROLOG possono essere denotati usando apici, ad esempio, 'This is an atom'
, apici sono non necessaria quando il parser SWI-PROLOG può identificare un atomo da una sequenza di caratteri, di solito a partire con un carattere alfabetico minuscolo, come test
. Se la sequenza conteneva spazi bianchi (o alcuni altri personaggi), avresti bisogno le virgolette singole per indicare un atomo correttamente. caratteri alfanumerici e alcuni caratteri di punteggiatura come sottolineatura _
vanno bene, per esempio, test5_6
.
Se la sequenza di caratteri senza virgolette singole dovesse iniziare con qualsiasi altra cosa, come ad esempio un numero di 6k
, il parser trattarlo come un number
; se fosse un carattere alfabetico maiuscolo come Test
, il parser trattano come una variabile.
Altri suggerimenti
Questo non è un comportamento specifico SWI - è richiesta dalla norma. C'è un modo semplice per vedere questo. È possibile utilizzare questo anche per qualsiasi altro termine cui sintassi non è evidente. Entrambi i tipi al toplevel:
?- X = 'test'. X = test. ?- X = 'this is a test'. X = 'this is a test'.
La risposta è sempre valida testo Prolog - questo è specifico per SWI ma anche a molti altri sistemi Prolog come YAP, GNU, B, SE, SICStus.
Un altro modo di vedere questo è quello di utilizzare 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)),[]))))