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),
!. % cut -- see text
Apparently, Ciao has neither a a get/1 nor a get0/1 predicate. As far as I can tell, the original get0/1 predicate parses a return character, unifies it with an anonymous variable (resulting in yes), and then procedes to the predicate interpret().
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. get_char(_) is similarly incorrect. Is there a predicate that is exactly equivalent to get0(_), or is there a more complex solution involving streams?
Thanks in advance.
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.
On Sat, Jul 12, 2014 at 11:29 PM, GreyHat LispHacker <greyhatlisphacker(a)gmail.com> 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), !. % cut -- see text
Apparently, Ciao has neither a a get/1 nor a get0/1 predicate. As far as I can tell, the original get0/1 predicate parses a return character, unifies it with an anonymous variable (resulting in yes), and then procedes to the predicate interpret().
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. get_char(_) is similarly incorrect. Is there a predicate that is exactly equivalent to get0(_), or is there a more complex solution involving streams?
Thanks in advance.
[sorry for duplicates, my previous email was not CCed correctly to the list; I've made some minor changes in this one]
Dear GreyHat LispHacker,
In addition to the other replies, you can also replace get0/1 by get_code/1 and get/1 by get1_code/1 (reads the next non-layout character). I attach below a patch that makes car.pl work.
It would be possible (and a good exercise) to port all the examples in the book to either Ciao or ISO standard predicates. However I'm not sure if we could (re)distribute them.
---------------------------------------------------------------------------
diff --git a/car.pl b/car.pl index 36e2cd8..90d9580 100644 --- a/car.pl +++ b/car.pl @@ -1,3 +1,5 @@ +:- module(car, [main/0]). + % From the book % PROLOG PROGRAMMING IN DEPTH % by Michael A. Covington, Donald Nute, and Andre Vellino @@ -8,7 +10,7 @@ % File CAR.PL % Simple automotive expert system
-:- reconsult('getyesno.pl'). % Use ensure_loaded if available. +:- use_module(.(getyesno)).
% % Main control procedures diff --git a/getyesno.pl b/getyesno.pl index 69d4549..0057b3e 100644 --- a/getyesno.pl +++ b/getyesno.pl @@ -1,3 +1,5 @@ : +:- module(getyesno, [get_yes_or_no/1]). + % From the book % PROLOG PROGRAMMING IN DEPTH % by Michael A. Covington, Donald Nute, and Andre Vellino @@ -8,8 +10,8 @@ % File GETYESNO.PL % Menu that obtains 'yes' or 'no' answer
-get_yes_or_no(Result) :- get(Char), % read a character - get0(_), % consume the Return after it +get_yes_or_no(Result) :- get1_code(Char), % read a character + get_code(_), % consume the Return after it interpret(Char,Result), !. % cut -- see text