使用Prolog,我想简化表示为列表列表的algebra expression:
代数方程
f = 3x+2
列表列表
[[3,1],[2,0]]
3
和2
是系数
1
和0
是指数
应该很明显。
我正在寻找有关此示例的简化代码的一些提示或建议:
f = 3x+2x+1+2
[[3,1],[2,1],[1,0],[2,0]]
简化:
f = 5x+3
[[5,1],[3,0]]
我尝试了一些内置函数,但是对如何使用它们没有正确的认识。
答案 0 :(得分:3)
一个衬纸,类似于joel76的建议:
simplify(I,O) :-
bagof([S,E],L^(bagof(C,member([C,E],I),L),sum_list(L,S)),O).
在给定C
(指数)的情况下,内部bagof收集E
(系数),结果列表L
汇总到S
中,并与E
配对成为[S,E]
,是O的元素(单项)。
如果您省略通用量化说明符(即L^
),则在回溯时会得到单个单体。
答案 1 :(得分:2)
您可以通过以下方式解决您的问题:
simplify(_,_,S,S,[]):- !.
simplify(L,I,Sum,NTot,[[I,S]|T]):-
Sum =< NTot,
findall(X,member([X,I],L),LO),
length(LO,N),
S1 is Sum + N,
sum_list(LO,S),
I1 is I+1,
simplify(L,I1,S1,NTot,T).
write_function([]).
write_function([[D,V]|T]):-
write(' + '),write(V),write('x^'),write(D),
write_function(T).
test:-
L = [[3,1],[2,1],[1,0],[2,0]],
length(L,N),
simplify(L,0,0,N,LO),
LO = [[D,V]|T],
write('f='),write(V),write('x^'),write(D),
write_function(T).
主要谓词为simplify/5
,它使用findall/3
查找具有相同度数的所有系数,然后使用sum_list/2
将它们求和。然后,您可以使用write_function/1
以一种奇特的方式写结果。
答案 2 :(得分:2)
在SWI-Prolog中,您可以使用聚合:
pred(>, [_,X], [_,Y]) :- X > Y.
pred(<, [_,X], [_,Y]) :- X < Y.
pred(=, [_,X], [_,X]).
simplify(In, Out) :-
aggregate(set([S,X]), aggregate(sum(P), member([P,X], In), S), Temp),
predsort(pred, Temp, Out).
例如:
?- simplify([[3,1],[2,1],[1,0],[2,0]], Out).
Out = [[5, 1], [3, 0]] ;
false.