chnging
chnging

Reputation: 775

Prolog: how to check if a word is contained in a list

Let's say I have these rules:

rule([a,t,e],[8]).
rule([f,o,r],[4]).

I have to check if in a word (for example [f,o,r,t,r,e,s,s]) there is a word that is in the list of rules and if there is to remove that word and replace it with the number it represents.(so it becomes [4,t,r,e,s,s]).

Any ideas?

Upvotes: 0

Views: 487

Answers (1)

false
false

Reputation: 10102

Assuming you want a single replacement:

text_l33t(W, L33t) :-
   rule(A, B),
   phrase( ( seq(Pre), seq(A), seq(Post) ), W),
   phrase( ( seq(Pre), seq(B), seq(Post) ), L33t).

seq([]) -->
   [].
seq([E|Es]) -->
   [E],
   seq(Es).

Alternatively, you could express that relation with append/3, but with even minimally more complex examples, append/3 will make things much more difficult to handle.

Consider also to use the Prolog flag double_quotes as described in this answer because it permits you to use double quotes. You could then write rule("to","2"). rule("ight","ite"). and get back nice answer substitutions, like so:

?- text_l33t("right", L).
   L = "rite".

If you want optionally more than one replacement, things become a bit more complex to specify. What about overlapping different rewrites? What about rewrites that get longer and longer? The following definition incorporates all possible rewrites:

text_xl33t(W, W).
text_xl33t(W, L33t) :-
   text_l33t(W, L0),
   text_xl33t(L0, L33t).

What you probably want is a maximal rewrite. While you can write this down in Prolog, I would not do this as a beginner: You are leaving the pure monotonic part of Prolog for that.


Edit: It seems you are still not happy with what I described. So here is text_maxl33t/2:

text_maxl33t(W, L33t) :-
   text_xl33t(W, L33t),
   \+ text_l33t(L33t, _).

Note that this predicate is still a relation. That is, for a single word you might have several independent maxl33ts since rewriting is not necessarily confluent.

Upvotes: 2

Related Questions