Why does SWI-Prolog unify a quoted and unquoted string (without spaces) to the same rule?
Asked Answered
W

2

5

Assume I have the following rules:

unify('test', 'this is a test').
run :- write('Enter something: '), 
       read(X), 
       unify(X, Y), 
       write('The answer is '), write(Y).

And then I run it as follows:

?- ['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.

Why does SWI-Prolog unify both test and 'test' to unify('test', 'this is a test').? I came across this while answering a Prolog question on SO. While I was able to answer the person's question, I couldn't explain this particular behavior, and I was wondering if any one else could.

Willingham answered 4/11, 2010 at 20:18 Comment(0)
Y
5

While atoms in SWI-PROLOG can be denoted using single quotes, e.g, 'This is an atom', single quotes are not needed when the SWI-PROLOG parser can identify an atom from a sequence of characters, usually starting with a lowercase alphabetic character, such as test. If the sequence contained whitespace (or some other characters), you'd need the single quotes to denote an atom properly. Alphanumeric characters and certain punctuation characters like underscore _ are fine, e.g., test5_6.

If the character sequence without single quotes were to start with anything else, such as a number 6k, the parser will treat it as a number; if it were an uppercase alphabetic character such as Test, the parser will treat it as a variable.

Yulandayule answered 4/11, 2010 at 20:36 Comment(2)
Ah, is this SWI-Prolog-specific behavior?Willingham
@Vivin Paliath: Perhaps, at least with SWI-PROLOG, though it seems typical of other PROLOG implementations I have seen as well. But nevertheless, yes, it is something the SWI-PROLOG parser will do in particular, perhaps if only to save you from having to single-quote all your atoms :-)Yulandayule
P
3

This is not SWI specific behavior - it is required by the standard. There is a simple way to see this. You can use this also for any other term whose syntax is not evident. Either type at the toplevel:

?- X = 'test'.
   X = test.
?- X = 'this is a test'.
   X = 'this is a test'.

The answer is always valid Prolog text - this is specific to SWI but also to many other Prolog systems like YAP, GNU, B, IF, SICStus.

Another way to see this is to use 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)),[]))))
Perorate answered 4/11, 2010 at 22:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.