Как упростить уравнения алгебры, представленные в виде списка - PullRequest
0 голосов
/ 29 января 2019

С помощью Пролога я хочу упростить выражение алгебры , представленное в виде списка списка:

уравнение алгебры

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]]

Я пробовал некоторые встроенные функции, но не получил правильного представления о том, как их использовать.

Ответы [ 3 ]

0 голосов
/ 30 января 2019

В 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.
0 голосов
/ 30 января 2019

Один вкладыш, аналогичный тому, что предложил joel76:

simplify(I,O) :-
    bagof([S,E],L^(bagof(C,member([C,E],I),L),sum_list(L,S)),O).

Внутренний пакет собирает C (коэффициенты), заданные E (показатели), результирующий список L суммируется в S и в паре с E становится [S,E] элементом (мономом) O. Если вы опустите универсальный спецификатор количественного определения (то есть L^), вы получите одиночные мономы при обратном отслеживании.

0 голосов
/ 30 января 2019

Вы можете решить свою проблему следующим образом:

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.

...