2012-09-14 59 views
3

这是问题所在。我想在count(a*b*c, * , N)上做一个prolog程序,它将计算*a*b*c并返回N=2prolog解析操作问题

我该如何做到这一点?

我已经做了一些研究,要么将它作为字符串传递,要么使用列表来分开a*b*c

但是,到目前为止没有任何成功。

回答

3

表达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. 
+0

谢谢,但我认为这不是递归的。如果我有更多的术语像z * b * d * e,那么我需要添加更多的条件。 – onegun

+0

它是递归的,在count(Left,...),count(Right,...) – CapelliC

+0

oos,我的错误,你是对的,它是递归的。经过多次检查后,我认为这个答案更好。 – onegun

3

它只能算*,但修改它来计算其他的事情应该是这么难:

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). 
+0

嗨,你介意为什么使用第二条规则:star_counter([H | R],Count): - star_counter(R,Count)。如果现在我想改变*到任何数学运算符像+或 - 我怎么修改这部分 – onegun

+0

当然:)第一个增加计数值,如果找到一颗星星。但是对于我想要保持不变的任何其他角色而言,仍然在列表中前进。 [H | R]表示H拥有列表头(第一个元素),R表示列表的其余部分。我希望它更清楚一点。 – Borgleader

+0

是的,我有你的想法,非常感谢,然后对于不同的数学运算符部分。我怎样才能做到这一点。我很难写出基本案例。 – onegun