ここに問題があります。count(a*b*c, * , N)
をカウントし*
て a*b*c
返す プロローグプログラムを実行したいN=2
。
どうすればこれを達成できますか?
私はそれを文字列として渡すか、リストを使用してを区切るかのいずれかで、いくつかの調査を行いましたa*b*c
。
しかし、これまでのところ何も成功していません。
式a*b*c
は簡略化された複合用語です。
?- write_canonical(a*b*c).
*(*(a,b),c)
これは二項関係のファンクターにすぎないことがわかります。式ツリーへのアクセスは、 univビルトイン*
を使用して実行できます。
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
).
これは、任意の二項演算子を使用したツリー式を受け入れますが、たとえば
?- count(e(a,e(b,c)),e,N).
N = 2.
*のみをカウントしますが、他のものをカウントするように変更するのは非常に難しいはずです。
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).
編集これはあなたが調べたいキャラクターのパラメータを持つバージョンです:
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).