Prolog乘以列表的元素

时间:2016-12-02 21:03:34

标签: prolog

如何让我的Prolog程序输出

  

1*a*b*c

如果我输入simplify([1,a,b,c],S).? 目前结果将是

  

1 *(A *(B * C))。

simplify(S,S1):-
   s(S,S1).

s([H|T],C) :- T\=[],s(H,SA), s(T,SB), s0(SA*SB,C).
s([H|T],H) :- T==[].
s(A,A).

s0(A*B,S):-
   S = A*B.

感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

1*a*b*c1*(a*(b*c))之间的区别是关联性,即括号的位置:

?- X = 1*a*b*c, X = ((One * A) * B) * C.
X = 1*a*b*c,
One = 1,
A = a,
B = b,
C = c.

这样做的一种方法是"折叠左边的列表",也就是说,计算列表的第一个元素的结果,与第二个元素组合,然后是第三个元素这通常使用累加器参数来传递中间结果。相比之下,你的递归折叠了右边的#34;和#34; (将尾部列表的结果与第一个元素组合,而不是将最后一个元素与初始列表组合在一起。)

这是一种方式(非常轻微的测试):

list_multexp([X|Xs], Multexp) :-
    list_multexp(Xs, X, Multexp).  % use first element as initial acc

list_multexp([X], Acc, Acc * X).
list_multexp([X|Xs], Acc, Multexp) :-
    dif(Xs, []),
    list_multexp(Xs, Acc * X, Multexp).

这适用于您的示例:

?- list_multexp([1,a,b,c], Multexp).
Multexp = 1*a*b*c ;
false.

答案 1 :(得分:0)

不确定这是你想要的,但......使用atom_concat/3 ...

simplify([H],H).

simplify([A | T], D) :-
  simplify(T,B),
  atom_concat(A, '*', C),
  atom_concat(C, B, D).

但你必须使用1作为“原子”,所以

simplify(['1',a,b,c], S),