在prolog中减少问题

时间:2016-11-23 15:56:42

标签: prolog polynomials

我试图在prolog中做练习。我做了很多切(我知道。太多了,其中一些是有用的,我将来会讨论删除其中一些),否则程序不会自行停止。这是我的代码:

as_monomial(X, m(X, 0, [])) :- number(X), !.
as_monomial(^(Y, Z), m(1, Z, [v(Z, Y)])) :- !.
as_monomial(*(X, ^(Y, Z)), m(G, K, Q)) :- as_monomial(X, m(G, TD, Vars)), K is (TD + Z), ordina_m([v(Z, Y)| Vars], Q), !.
as_monomial(*(X, Y), m(G, K, Q)) :- as_monomial(X, m(G, TD, Vars)), K is (TD + 1), ordina_m([v(1, Y)| Vars], Q), !.
as_monomial(-(X), m(-A, Y, L)) :- as_monomial(X, m(A, Y, L)).
as_monomial(X, m(1, 1, [v(1, X)])).



ordina_m(List, Sorted) :- sort(2, @=<, List,  Sorted).

ordina_poly1(List, Sorted) :- sort(2, @>=, List,  Sorted).
ordina_poly2(List, Sorted) :- sort(3, @=<, List,  Sorted).


is_monomial(m(_C, TD, VPs)) :- integer(TD), TD >= 0, is_list(VPs).

is_polynomial(poly(M)) :- is_list(M), foreach(member(Monomio, M), is_monomial(Monomio)).


as_polynomial(+(X, Y), poly(C)) :- as_monomial(Y, G), as_polynomial(X, poly(Gs)), inverti(G, H), inverti2(Gs, Hs), ordina_poly2([H| Hs], D), inverti2(D, F), ordina_poly1(F, C), !.
as_polynomial(-(X, Y), poly(C)) :- as_monomial(-Y, G), as_polynomial(X, poly(Gs)), inverti(G, H), inverti2(Gs, Hs), ordina_poly2([H| Hs], D), inverti2(D, F), ordina_poly1(F, C), !.
as_polynomial(X, poly([X])) :- is_monomial(X), !.
as_polynomial(X, poly([Q])) :- as_monomial(X, Q), is_monomial(Q).

/* coefficienti */
coefficients(Poly1, Result) :- is_polynomial(Poly1), coefficienti(Poly1, Result), !.
coefficients(Poly1, Result) :- as_polynomial(Poly1, Result1), coefficienti(Result1, Result), !.

coefficienti(poly([]), []) :- !.
coefficienti(poly([m(X, _, _)|Xs]), [X|Ys]) :- coefficienti(poly(Xs), Ys), !.

/* variabili */
variables(Poly1, Result) :- is_polynomial(Poly1), variabili(Poly1, Result), !.
variables(Poly1, Result) :- as_polynomial(Poly1, Result1), variabili(Result1, Result), !.

variabili(poly([]), []) :- !.
variabili(poly([m(_, _, X)|Xs]), [X|Ys]) :- variabili(poly(Xs), Ys), !.

/* monomi */
monomials(Poly1, Result) :- is_polynomial(Poly1), monomi(Poly1, Result), !.
monomials(Poly1, Result) :- as_polynomial(Poly1, Result1), monomi(Result1, Result), !.

monomi(poly([]), []) :- !.
monomi(poly([X|Xs]), [X|Ys]) :- monomi(poly(Xs), Ys), !.

/* somma */
polyplus(Poly1, Poly2, Result) :- is_polynomial(Poly1), is_polynomial(Poly2), poly_plus(Poly1, Poly2, Result), !.
polyplus(Poly1, Poly2, Result) :- is_polynomial(Poly1), as_polynomial(Poly2, Q), poly_plus(Poly1, Q, Result), !.
polyplus(Poly1, Poly2, Result) :- as_polynomial(Poly1, Q), is_polynomial(Poly2), poly_plus(Q, Poly2, Result), !.
polyplus(Poly1, Poly2, Result) :- as_polynomial(Poly1, Q1), as_polynomial(Poly2, Q2), poly_plus(Q1, Q2, Result).

poly_plus(poly([]), poly(Q), poly(Q)) :- !.
poly_plus(poly([X|Xs]), poly(Q), poly([X|Z])) :- poly_plus(poly(Xs), poly(Q), poly(Ys)), compress_somma(X, Ys, Z), compara(Ys, Z).
poly_plus(poly([X|Xs]), poly(Q), poly(Z)) :- poly_plus(poly(Xs), poly(Q), poly(Ys)), compress_somma(X, Ys, Z).

compress_somma(_X, [], []) :- !.
compress_somma(m(X,Y,Z), [m(R,Y,Z)| List1], [m(K,Y,Z)| List2]) :- compress_somma(m(X,Y,Z), List1, List2), K is (R + X), !.
compress_somma(X, [Y| List], [Y| List]) :- compress_somma(X, List, List).


/* differenza */
polyminus(Poly1, Poly2, Result) :- is_polynomial(Poly1), is_polynomial(Poly2), poly_minus(Poly1, Poly2, Result), !.
polyminus(Poly1, Poly2, Result) :- is_polynomial(Poly1), as_polynomial(Poly2, X), poly_minus(Poly1, X, Result), !.
polyminus(Poly1, Poly2, Result) :- as_polynomial(Poly1, X), is_polynomial(Poly2), poly_minus(X, Poly2, Result), !.
polyminus(Poly1, Poly2, Result) :- as_polynomial(Poly1, Y), as_polynomial(Poly2, Z), poly_minus(Y, Z, Result).

poly_minus(poly([]), poly(X), poly(X)) :- !.
poly_minus(poly([X|Xs]), poly(Q), poly([X|Z])) :- poly_minus(poly(Xs), poly(Q), poly(Ys)), compress_differenza(X, Ys, Z), compara(Ys, Z).
poly_minus(poly([X|Xs]), poly(Q), poly(Z)) :- poly_minus(poly(Xs), poly(Q), poly(Ys)), compress_differenza(X, Ys, Z).

compress_differenza(_X, [], []) :- !.
compress_differenza(m(X,Y,Z), [m(R,Y,Z)| List1], [m(K,Y,Z)| List2]) :- compress_differenza(m(X,Y,Z), List1, List2), K is (X - R), !.
compress_differenza(X, [Y| List], [Y| List]) :- compress_differenza(X, List, List).



/*moltiplicazione */


compara([], []) :- !.
compara([X|Xs], [X|Ys]) :- compara(Xs, Ys).

inverti(m(_, _, []), m(_, _, [])) :- !.
inverti(m(X, Y, [v(W, Z)| Xs]), m(X, Y, [v(Z, W)| Ys])) :- inverti(m(X, Y, Xs), m(X, Y, Ys)), !.

inverti2([], []) :- !.
inverti2([m(X, Y, [])| Zs], [m(X, Y, [])| Ss]) :- inverti2(Zs, Ss), !.
inverti2([m(X, Y, [v(W, Z)| Xs])| Zs], [m(X, Y, [v(Z, W)| Ys])| Ss]) :- inverti2([m(X, Y, Xs)| Zs], [m(X, Y, Ys)| Ss]), !. 

该程序为我提供了正确的输出,但是,不是让我结束程序,它看起来像是在等待某些东西,我必须强迫&#34;强迫&#34;结束&#34;输入&#34;。有问题还是应该是正常的?你能帮助我吗?谢谢大家

1 个答案:

答案 0 :(得分:0)

好。由于@coder,我解决了我的问题。为了解决这个问题,我在封闭的一行中添加了另一个剪切(可能是好的剪切)&#34; as_polynomial&#34;:

as_polynomial(+(X, Y), poly(C)) :- as_monomial(Y, G), as_polynomial(X, poly(Gs)), inverti(G, H), inverti2(Gs, Hs), ordina_poly2([H| Hs], D), inverti2(D, F), ordina_poly1(F, C), !. as_polynomial(-(X, Y), poly(C)) :- as_monomial(-Y, G), as_polynomial(X, poly(Gs)), inverti(G, H), inverti2(Gs, Hs), ordina_poly2([H| Hs], D), inverti2(D, F), ordina_poly1(F, C), !. as_polynomial(X, poly([X])) :- is_monomial(X), **!**. as_polynomial(X, poly([Q])) :- as_monomial(X, Q), is_monomial(Q).

然后我也删除了is_monomial(Q),因为它无效