Scott
Scott

Reputation: 41

Prolog : Remove extra spaces in a stream of characters

Total newb to Prolog. This one is frustrating me a bit. My 'solution' below is me trying to make Prolog procedural...

This will remove spaces or insert a space after a comma if needed, that is, until a period is encountered:

squish:-get0(C),put(C),rest(C).  
rest(46):-!.  
rest(32):-get(C),put(C),rest(C).  
rest(44):-put(32), get(C), put(C), rest(C).  
rest(Letter):-squish. 

GOAL: I'm wondering how to remove any whitespace BEFORE the comma as well.

The following works, but it is so wrong on so many levels, especially the 'exit'!

squish:-  
  get0(C),  
  get0(D),  
  iteratesquish(C,D).  

iteratesquish(C,D):-  
  squishing(C,D),  
  get0(E),  
  iteratesquish(D,E).  

squishing(46,X):-put(46),write('end.'),!,exit.  

squishing(32,32):-!.  
squishing(32,44):-!.  
squishing(32,X):-put(32),!.   

squishing(44,32):-put(44),!.  
squishing(44,44):-put(44), put(32),!.  
squishing(44,46):-put(44), put(32),!.  
squishing(44,X):-put(44), put(32),!.  

squishing(X,32):-put(X),!.  
squishing(X,44):-put(X),!.  
squishing(X,46):-put(X),!.  

squishing(X,Y):-put(X),!.  

Upvotes: 4

Views: 1598

Answers (1)

mat
mat

Reputation: 40768

Since you are describing lists (in this case: of character codes), consider using DCG notation. For example, to let any comma be followed by a single whitespace, consider using code similar to:

squish([])                 --> [].
squish([(0',),(0' )|Rest]) --> [0',], spaces, !, squish(Rest).
squish([L|Ls])             --> [L], squish(Ls).

spaces --> [0' ], spaces.
spaces --> [].

Example query:

?- phrase(squish(Ls), "a,   b,c"), format("~s", [Ls]).
a, b, c

So, first focus on a clear declarative description of the relation between character sequences and the desired "clean" string. You can then use SWI-Prolog's library(pio) to read from files via these grammar rules. To remove all spaces preceding commas, you only have to add a single rule to the DCG above (to squish//1), which I leave as exercise to you. A corner case of course is if a comma is followed by another comma, in which case the requirements are contradictory :-)

Upvotes: 4

Related Questions