这是问题所在。我想在count(a*b*c, * , N)
上做一个prolog程序,它将计算*
的a*b*c
并返回N=2
。prolog解析操作问题
我该如何做到这一点?
我已经做了一些研究,要么将它作为字符串传递,要么使用列表来分开a*b*c
。
但是,到目前为止没有任何成功。
这是问题所在。我想在count(a*b*c, * , N)
上做一个prolog程序,它将计算*
的a*b*c
并返回N=2
。prolog解析操作问题
我该如何做到这一点?
我已经做了一些研究,要么将它作为字符串传递,要么使用列表来分开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).
嗨,你介意为什么使用第二条规则:star_counter([H | R],Count): - star_counter(R,Count)。如果现在我想改变*到任何数学运算符像+或 - 我怎么修改这部分 – onegun
当然:)第一个增加计数值,如果找到一颗星星。但是对于我想要保持不变的任何其他角色而言,仍然在列表中前进。 [H | R]表示H拥有列表头(第一个元素),R表示列表的其余部分。我希望它更清楚一点。 – Borgleader
是的,我有你的想法,非常感谢,然后对于不同的数学运算符部分。我怎样才能做到这一点。我很难写出基本案例。 – onegun
谢谢,但我认为这不是递归的。如果我有更多的术语像z * b * d * e,那么我需要添加更多的条件。 – onegun
它是递归的,在count(Left,...),count(Right,...) – CapelliC
oos,我的错误,你是对的,它是递归的。经过多次检查后,我认为这个答案更好。 – onegun