For Programmers: Free Programming Magazines  


Home > Archive > Prolog > May 2004 > simple list recursion









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author simple list recursion
Martin Fuchs

2004-04-14, 9:34 am

(I didn't use Prolog very often yet.)

I've got a predicate "conc" concatenating two strings (or lists in general).

conc("",B,B).
conc([H|T],B,[H|R]):- conc(T,B,R).

Now I want to define a predicate "filter" which removes single characters from
strings, e.g.

filter("A","OASIS","OSIS").

My idea was as follows, but it doesn't work...

filter(_,"","").
filter(A,[H|T],R):- conc("",A,H),filter(A,T,R).
filter(A,[H|T],[H|R]):- conc(A,T,R).


What's my stupid mistake?


Thanks
mf
Nick Wedd

2004-04-14, 1:42 pm

In message <c5jc3c$2a5db$1@ID-134512.news.uni-berlin.de>, Martin Fuchs
<usenet-ng@gmx.net> writes
>(I didn't use Prolog very often yet.)
>
>I've got a predicate "conc" concatenating two strings (or lists in general).
>
>conc("",B,B).
>conc([H|T],B,[H|R]):- conc(T,B,R).
>
>Now I want to define a predicate "filter" which removes single characters from
>strings, e.g.
>
>filter("A","OASIS","OSIS").
>
>My idea was as follows, but it doesn't work...
>
>filter(_,"","").
>filter(A,[H|T],R):- conc("",A,H),filter(A,T,R).
>filter(A,[H|T],[H|R]):- conc(A,T,R).
>
>
>What's my stupid mistake?


The one that causes your predicate not to work is typing "conc" when you
meant "filter" in the last clause.

Nick
--
Nick Wedd nick@maproom.co.uk
Bill Spight

2004-04-14, 1:42 pm

Xref: kermit comp.lang.prolog:18285

Dear Martin,

> Now I want to define a predicate "filter" which removes single characters from
> strings, e.g.
>
> filter("A","OASIS","OSIS").


What about

filter ("S", "OASIS", String)?

String = "OAIS" ?

String = "OASI" ?

String = "OAI" ?

All of the above? Some of the above?

Best,

Bill
Martin Fuchs

2004-04-14, 2:48 pm

> The one that causes your predicate not to work is typing "conc" when you
> meant "filter" in the last clause.


Of course not.
This was only a typing-error in my post.

mf
Martin Fuchs

2004-04-14, 2:48 pm

> What about
>
> filter ("S", "OASIS", String)?



Should be:
> String = "OAI" ?



mf
Georgios Tagalakis

2004-04-14, 2:48 pm


"Martin Fuchs" <usenet-ng@gmx.net> wrote in message
news:c5jc3c$2a5db$1@ID-134512.news.uni-berlin.de...
> (I didn't use Prolog very often yet.)
>
> I've got a predicate "conc" concatenating two strings (or lists in

general).
>
> conc("",B,B).
> conc([H|T],B,[H|R]):- conc(T,B,R).
>
> Now I want to define a predicate "filter" which removes single characters

from
> strings, e.g.
>
> filter("A","OASIS","OSIS").
>
> My idea was as follows, but it doesn't work...
>
> filter(_,"","").
> filter(A,[H|T],R):- conc("",A,H),filter(A,T,R).
> filter(A,[H|T],[H|R]):- conc(A,T,R).
>
>
> What's my stupid mistake?
>
>
> Thanks
> mf


Martin,

Your conc/3 is ok (concatenate, for instance, "stringone" "stringtwo" and
see what you get). To delete all occurrences of a character in a list of
characters try this.

delete_elms([Elem|Tail],Elem,Result) :- !,
delete_elms(Tail,Elem,Result).
delete_elms([Head|Tail],Elem,[Head|Rest]) :-
delete_elms(Tail,Elem,Rest).

If you're working with SWI-Prolog all predicates you need are built-in.

Here's an example that joins the strings "this" and "that", removes "t" and
outputs the final string that should be "hisha"

?- append("this","that",What), char_code(t,Code), delete(What,Code,Output),
atom_chars(FinalString,Output).

What = [116, 104, 105, 115, 116, 104, 97, 116]
Code = 116
Output = [104, 105, 115, 104, 97]
FinalString = hisha ;

No
?-

Cheers,

--- Georgios Tagalakis


Martin Fuchs

2004-04-14, 5:33 pm

> ?- append("this","that",What), char_code(t,Code), delete(What,Code,Output),

> atom_chars(FinalString,Output).


Thanks.

(My original code works. I've got only some problems understanding the
string / char-handling of GNU-Prolog, but when I saw your example, I understand. Sorry.)

mf


Georgios Tagalakis

2004-04-14, 6:35 pm



"Martin Fuchs" <usenet-ng@gmx.net> wrote in message
news:c5jc3c$2a5db$1@ID-134512.news.uni-berlin.de...
<snip>
> My idea was as follows, but it doesn't work...
>
> filter(_,"","").
> filter(A,[H|T],R):- conc("",A,H),filter(A,T,R).
> filter(A,[H|T],[H|R]):- conc(A,T,R).
>
> What's my stupid mistake?
> mf


"Martin Fuchs" <usenet-ng@gmx.net> wrote in message
news:c5k7nb$2m9ag$1@ID-134512.news.uni-berlin.de...
<snip>
> (My original code works. I've got only some problems understanding the
> string / char-handling of GNU-Prolog, but when I saw your example, I

understand. Sorry.)
>
> mf
>


Eh? So did your original code work or not? Well, it didn't. Anyway, if it
works now and you are happy I am happy :)

GNU Prolog (at least the latest release I have) also comes with all the
necessary predicates you will need.

append/3
char_code/2
delete/3
atom_codes/2

A few minutes spent reading the manual/libraries and a few simple examples
for each predicate at the terminal window before you start building larger
blocks of code will save you hours of difficulty and frustration later.

Cheers,
--- Georgios Tagalakis



W

2004-05-12, 9:20 pm

Your class is probably over, but the pedagogical purpose behind this was to
get you to realize that you need to add a condition to when you included the
head of the list: (the fact that strings are represented as lists should not
be the focus of your attention -- that is a pedagogical error):

filter(_,[],[]). % of course the base case.
filter(A,[A|T], R) :- filter(A,T,R). % notice the use of unification to
check ANY item in list, then just recurse on the rest of the list.
filter(A,[H|T], [H|R]) :- %this time put the head on
A \= H, %have to make sure they are not the same
(ie not unifiable)
filter(A,T,R).

for one simple condition where you are testing the case "unifies" or "does
not unify" you could use the if-then-else syntactic sugar, or throw in a cut
in clause 2 and leave out the check for "does not unify" in clause 3.

In your code, you did not check for non-unification, so you could backtrak
into your solution many times.
also, you don't need to append the empty list on front in clause2 since it
does nothing.

Hope you enjoyed the course.
W




"Martin Fuchs" <usenet-ng@gmx.net> wrote in message
news:c5jc3c$2a5db$1@ID-134512.news.uni-berlin.de...
> (I didn't use Prolog very often yet.)
>
> I've got a predicate "conc" concatenating two strings (or lists in

general).
>
> conc("",B,B).
> conc([H|T],B,[H|R]):- conc(T,B,R).
>
> Now I want to define a predicate "filter" which removes single characters

from
> strings, e.g.
>
> filter("A","OASIS","OSIS").
>
> My idea was as follows, but it doesn't work...
>
> filter(_,"","").
> filter(A,[H|T],R):- conc("",A,H),filter(A,T,R).
> filter(A,[H|T],[H|R]):- conc(A,T,R).
>
>
> What's my stupid mistake?
>
>
> Thanks
> mf



Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com