I’m trying to write a polynomial in prolog where I study the grade of each variable. My problem is that when I do the validation, the problem doesn’t consider the minus as sign of the coefficient. For example, -4*x is considered as 4*x and the minus expired. I put the code where I also study a simple monomial. Can you help me?
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(1, 1, [v(1, X)])).
ordina_m(List, Sorted) :- sort(2, @=<, List, Sorted).
ordina_poly(List, Sorted) :- sort(2, @>=, List, Sorted).
is_monomial(m(_C, TD, VPs)) :- integer(TD), TD >= 0, is_list(VPs).
as_polynomial(+(X, Y), poly(D)) :- as_monomial(Y, Q), is_monomial(Q), as_polynomial(X, poly(Qs)), ordina_poly([Q| Qs], D), !.
as_polynomial(-(X, Y), poly(D)) :- as_monomial(Y, Q), is_monomial(Q), as_polynomial(X, poly(Qs)), ordina_poly([Q| Qs], D), !.
as_polynomial(X, poly([Q])) :- as_monomial(X, Q), is_monomial(Q).
Example:
?- as_polynomial(4*y^6-4*d,Q).
Output:
Q = poly([m(4, 6, [v(6, y)]), m(4, 1, [v(1, d)])]).
Real output:
Q = poly([m(4, 6, [v(6, y)]), m(-4, 1, [v(1, d)])]).
Where "-4" is the coefficient, "1" is totaldegree, and the list is the other variables.
Thanks for all.
You "expired" the minus yourself in the second clause of as_polynomial/2
. Do you notice that the bodies of:
as_polynomial(+(X, Y), poly(D)) :- ...
and
as_polynomial(-(X, Y), poly(D)) :- ...
are identical?
You probably need to pass the minus to your as_monomial(-Y, Q)
instead of as_monomial(Y, Q)
and treat the term -X
in another clause of as_monomial/2
.
There is a whole bunch of cuts and I have the feeling most of them are not necessary, esp. if you know that in *(A, B)
, A
is a number and B
and atom, or that in ^(A, B)
, A
is an atom and B
is a number.