Reputation: 42967
I have some doubt related to the declarative interpretation of this simple Prolog example that read a sentence from the current input stream and output the same sentence reformatted so that multiple blanks between words are replaced by a single blank character.
This is the code of my program:
squeeze :- get0(C), % Legge un carattere dallo standard input(anche blank)
put(C), % Scrive il carattere sullo standard output
dorest(C). % Fà tutto il resto.
dorest(46) :- !. % 46 è il carattere ASCII per lo stop: tutto completato.
dorest(32) :- !, % 32 è il carattere ACII per blank, impedisci backtrack
get(C), % Legge un carattere dallo standard input (non blank)
put(C), % Scrive il carattere sullo standard output
dorest(C). % Fà tutto il resto.
dorest(Letter) :- squeeze.
I have some doubts related to it's declarative reading and the use of the cut...can you say me if my interpretation is it correct or if am I missing something?
All begin when I call the squeeze predicate in the Prolog Shell so, in logic, I have to verify squeeze predicate as TRUE or FALSE...
squeze predicate is TRUE when all that is in the rule body it is TRUE: it must have read a character (also blank) AND put this character on the output and verify if dorest(C) predicate is TRUE (where C is the read character)
dorest(C) is the core of the program.
IF C is the ASCII code character 46 that correspond a . (full stop): prevents backtracking (the program can't try other dorest rule) and verify dorest as true, so the squeeze predicate is in its turn verified as TRUE and the program will end
IF C is the ASCII code character 32 that correspond at a blank character: prevents backtracking (the program can't try other dorest rule) verify the get predicate that will cause the skipping over of all blank character, write C on the current output stream and verify squeeze
IF C is a common character, simply verify squeeze (and this induce something like a cycle in the reading of the string)
So, in this case, I can see the use of the CUT operator ! as a way to iduce something like an IF because create a mutual exclusion between the dorest rules
Is it right or am I missing something?
Upvotes: 0
Views: 122
Reputation: 71075
Yes you are right, indeed cut is used here to create an IF construct. This code can be re-written with the '->'
construct explicitly:
squeeze :- get0(C), put(C), dorest(C).
dorest(C):-
( C = 46 -> true ;
C = 32 -> get(C), put(C), dorest(C) ;
squeeze
).
As can be seen, squeeze
and dorest
are mutually recursive procedures. squeeze
does something and then calls dorest
, which either stops, does something, or calls squeeze
back.
This program describes, thus, a loop, that reads user input until a dot is encountered, and echoes each character back, except that for any sequence of white space characters only the very first of them is echoed back, which makes it look like "squeezing" several consecutive spaces into just one space:
9 ?- squeeze.
|: 12 34 56
12 34 56
|: asd 432 123-432 56.
asd 432 123-432 56.
Yes
10 ?- squeeze.
|: 123 43 23 .rewe ew wew ew e
123 43 23 .
Yes
This is an operational interpretation, not a declarative one. I/O is about "doing", not about "being". This is why I used the word "procedure" in place of "predicate", above.
Upvotes: 1