On 13/07/2014, at 9:29 AM, GreyHat LispHacker wrote:
Hello,
Apologies for this rather elementary question. I'm learning prolog via Michael Covington's Prolog Programming in Depth and working through the examples using Ciao 1.14.2.
(The book, and source files can be found at: http://www.covingtoninnovations.com/books.html).
I'm having difficulty getting the car.pl example to work (pg 54-60). He uses the following to parse a single character input (Y or N):
get_yes_or_no(Result) :- get(Char), % read a character. get0(_), % consume the Return after it. interpret(Char,Result), !.
The layout here is seriously weird; what happened?
Historical background: get0(-Code) reads one character from the current input stream and unifies the code of that character with Code. If there isn't any next character, Code is unified with -1.
get(-Code) reads the next *visible* character from the current input stream. Except for skipping layout characters, it is like get0/1. On the DEC-10, where this comes from,
get(Code) :- get0(C), ( C =< 32, C >= 0 -> get(Code) ; Code = C ).
The DEC-10 used the ASCII character set with 7-bit bytes. On a byte-oriented machine, there is a possible distinction between reading a *byte* and reading a *character*, especially when you take into account the wide range of possible encodings, and the fact that some encodings (like UTF-8) may use more than one byte.
The ISO Prolog standard introduced
get_byte(-Byte) -- get0/1 interpreted as reading exactly one byte.
get_code(-Code) -- get0/1 interpreted as reading one character, possibly requiring several bytes
get_char(-Char) -- unifies Char with end_of_file instead of -1 or a one-character atom instead of a non-negative character code.
For the great majority of uses, it is sufficient either to replace get0(X) by get_code(X) or simply to add get0(Code) :- get_code(Code). to your file.
I changed get(Char) to get_char(Char), and get0 to get_code(_), but this puts me in an endless loop that calls get_yes_or_no again.
Absolutely wrong. get_char returns an ATOM. get returns an INTEGER. Use the definition of get/1 above.