如何简化以列表列表表示的代数方程

时间:2019-01-29 19:21:06

标签: list prolog algebra

使用Prolog,我想简化表示为列表列表的algebra expression

代数方程

f = 3x+2

列表列表

[[3,1],[2,0]]

32是系数
10是指数

应该很明显。

我正在寻找有关此示例的简化代码的一些提示或建议:

f = 3x+2x+1+2
[[3,1],[2,1],[1,0],[2,0]]

简化:

f = 5x+3
[[5,1],[3,0]]

我尝试了一些内置函数,但是对如何使用它们没有正确的认识。

3 个答案:

答案 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.