AndreaNobili
AndreaNobili

Reputation: 42967

Some doubts about the use of the cut in a program that read and format an input text in Prolog

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

Answers (1)

Will Ness
Will Ness

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

Related Questions