Reputation: 803
Here is the problem. I want to do a prolog program on count(a*b*c, * , N)
which will count the *
in a*b*c
and return N=2
.
How can i achieve this?
I have done some research, either passing it as s string or using a list to separate a*b*c
.
However, so far nothing is successful.
Upvotes: 2
Views: 168
Reputation: 15916
It will only count * but modifying it to count other things should be so hard:
main :-
atom_chars('a*b*c', CharList),
star_counter(CharList, Count),
write(Count).
star_counter([], 0).
star_counter(['*'|R], Count) :-
star_counter(R, Sum),
Count is Sum + 1.
star_counter([H|R], Count) :-
star_counter(R, Count).
EDIT Here's a version with a parameter for the character you want to look up:
main :-
atom_chars('a*b*c', CharList),
star_counter('*',CharList, Count),
write(Count).
star_counter(_,[], 0).
star_counter(X,[X|R], Count) :-
star_counter(X,R, Sum),
Count is Sum + 1.
star_counter(X,[_|R], Count) :-
star_counter(X,R, Count).
Upvotes: 2
Reputation: 60004
The expression a*b*c
is a simplified compound term:
?- write_canonical(a*b*c).
*(*(a,b),c)
You can see that *
is just the functor of a binary relation, and the visit of the expression tree can be done using the univ builtin:
count(Expression, Request, N) :-
( Expression =.. [Op, Left, Right]
-> count(Left, Request, NLeft),
count(Right, Request, NRight),
( Request == Op
-> N is NLeft + NRight + 1
; N is NLeft + NRight
)
; N = 0
).
This accepts trees expressions with any binary operator, but also, for instance
?- count(e(a,e(b,c)),e,N).
N = 2.
Upvotes: 2