2016-12-02 52 views
1

我怎樣才能讓我的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. 

感謝您的幫助。

回答

0

取決於序言你使用什麼。 SWI內置foldl/4,就像其他語言的「減少」一樣。所以,你可以簡化你的程序如下:

s(B,A,A*B). 

simplify([H|L],E):- foldl(s,L,H,E). 
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), 
+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. 

這樣做的一種方法是「從左側摺疊列表」,也就是說,計算列表的第一個元素的結果,與第二個元素結合,然後結合第三個元素等。這通常是使用累加器參數完成傳遞中間結果。相比之下,遞歸將「從右邊開始」列表(將尾列表的結果與第一個元素相結合,而不是將最初的列表與最後一個元素組合在一起)。

這裏是一個辦法(看得很輕測試):

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. 
相關問題