views:

439

answers:

2

I'm trying to write a function that will test to see if the word hello is contained in a list. If it is contained, i don't want it to say "true", i want it to say : "yes, the word hello is contained here", any ideas?

Here's my code :

contains_hello([hello|_]).
contains_hello([Head|Tail]):- Head \= hello, contains_hello(Tail).
+2  A: 

This is untested but try:

contains_hello([hello|_]) :-
  write('yes, the word hello is contained here'),
  nl.
contains_hello([Head|Tail]) :- Head \= hello, contains_hello(Tail).
Mark Pim
Works perfect - thank you!
rb58
Both solutions prints yes, the word hello is contained here true.
Juanjo Conti
+3  A: 

It is clear form your code that you only want the message to be printed once. Currently you solve this by adding Head \= hello to the second clause. This is not how one usually solves this in Prolog.

Observe that your second clause excludes precisely that situation which is matched by the first clause. So, it is much more convenient to cut in the first clause. This stops backtracking. I.e., if the first clause matches, then the second clause will not be considered.

A cut is signified by the exclamation mark (!). Thus:

contains_hello([hello|_]) :-
  write('yes, the word hello is contained here'), nl, !.

contains_hello([_|T]) :- contains_hello(T).
Stephan202