renatov
renatov

Reputation: 5095

Delete character from string in Prolog

I need to remove a character from a string. For example:

?- remove_char('abcde', 'c', X).
X = 'abde'

?- remove_char('abcdefgh', 'f', X).
X = 'abcdegh'

I'm looking for a concise way of accomplishing this, but I have no success. I'm new to Prolog and I'm having a very hard time dealing with strings if I don't want to convert them to lists. Is there a built in function for this, or at least a parsimonious way?

Upvotes: 1

Views: 3471

Answers (2)

Nicholas Carey
Nicholas Carey

Reputation: 74197

You're not dealing with string in your code: 'abcde' is an atom. "abcde" is a prolog string (aka list of characters). However, this seems pretty concise to me, if you want to play with atoms:

remove_chars( X , C , Y ) :-
  atom_chars( X , Xs ) ,
  strip( Xs , C , Ys ) ,
  atom_chars( Y , Ys )
  .

strip( []     , _ , []     ) .
strip( [Y|Cs] , C , [Y|Ys] ) :- Y \= C , strip(Cs,C,Ys) .
strip( [Y|Cs] , C ,    Ys  ) :- Y  = C , strip(Cs,C,Ys) .

Or, using the built-in select/3, even more concise:

remove_chars( X , C , Y ) :-
  atom_chars( X , Xs ) ,
  select( C, Xs , Ys ) ,
  atom_chars( Y , Ys )
  .

Upvotes: 1

CapelliC
CapelliC

Reputation: 60004

sub_atom/5 could help, anyway here is an alternative.

remove_char(S,C,X) :- atom_concat(L,R,S), atom_concat(C,W,R), atom_concat(L,W,X).

Since atom_concat is well implemented, remove_char it's more general than its name suggests:

2 ?- remove_char(abcabcd,bc,X).
X = aabcd ;
X = abcad ;
false.

A good exercise would be to try to implement the same logic (for 'fragments' extraction) with sub_atom/5.

Upvotes: 2

Related Questions