1
votes

I'm new to Prolog and I'm facing some exercises, this one for example ask me to write a predicate histogram/1 to take a list as argument and print an horizontal histogram with the occurrences of numbers 0..9 in the list. For example:

?- histogram([1,3,4,1,1,4,7]).

0 

1 ***

2

3 *

4 **

5

6

7 *

8

9

true.

My program is the following, and works as requested, but I've a doubt: as you can see I used cut predicate and semicolon in that way (first line), only to obtain TRUE after the histogram (just to fit the example provided, I don't really care about it!), if you omit this you'll get always FALSE as N<10 will fail... My question is: is this a proper way to use the cut predicate? If not, how could I improve my program (any other suggestion will be appreciated)?

histogram(X):-
   valid(X),
   (  print(0,X)
   ;  !
   ).

print(N,X):-
   write(N) , tab(2), count(N,X) , nl,
   N1 is N+1,
   N1 < 10 ,
   print(N1,X).

count(_,[]).
count(E,[E|C]):-
   write('*') ,
   count(E,C).
count(E,[Y|C]):-
   E\=Y ,
   count(E,C).

valid([]).
valid([X|T]):-
   integer(X),
   X>=0,
   X<10,
   valid(T).
1
instead of (print(0,X) ; !) you can write (print(0,X) ; true) for the same effect.Will Ness

1 Answers

1
votes

maybe

print(N,X):- N < 10, write(N), tab(2), count(N,X), nl, N1 is N+1, print(N1,X).
print(10,_).

and the whole program can be made much shorter using SWI-Prolog library, for instance

histogram(X) :-
    forall(between(0,9,N), (findall(*,member(N,X),H), format('~d ~s~n', [N, H]))).