Вырезать задачу в прологе

Я пытаюсь сделать упражнение на прологе. Я вырезал много (знаю. Слишком много, и некоторые из них полезны, и я обсужу в будущем, чтобы удалить некоторые из них), иначе программа не останавливается. Вот мой код:

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]), !. 

Программа дает мне в качестве вывода правильный, но вместо того, чтобы дать мне конец процедуры, она выглядит так, как будто она чего-то ждет, и мне нужно «принудительно» завершить ее с помощью «ввода». Есть какие-то проблемы или это должно быть нормально? Ты можешь мне как-то помочь? Спасибо всем


person Anna    schedule 23.11.2016    source источник
comment
Приведите простой пример ввода, где вы получаете такое поведение вашей программы, чтобы лучше понять ее...   -  person coder    schedule 23.11.2016
comment
Проклятие. Ты так прав. Пример вот этот as_polinomial(x+y, P1), as_polinomial(-y, P2), polyplus(P1,P2,R).   -  person Anna    schedule 23.11.2016
comment
Вы не дали никакого определения as_polinomial/2 выше....   -  person coder    schedule 23.11.2016
comment
Я помещаю весь код в редактирование   -  person Anna    schedule 23.11.2016
comment
Хорошо. Я положил весь код на него   -  person Anna    schedule 23.11.2016
comment
Это очень обычно, ваша программа не возвращает только одно решение нажмите ; чтобы увидеть другое возможное решение, пока оно не остановится (или введите, если вы не хотите видеть другие решения)   -  person coder    schedule 23.11.2016
comment
Хорошо, но мне не нужно другое решение. Мне нужен только тот, который он показывает мне   -  person Anna    schedule 23.11.2016
comment
Тогда я не уверен, так как не могу изучить всю вашу программу, но я думаю, что это сработает, если написать: as_polynomial(X, poly([Q])) :- as_monomial(X, Q), is_monomial(Q), !. в последнем предложении as_polynomial/2 (просто добавьте еще один!).   -  person coder    schedule 23.11.2016
comment
Я редактирую ответ, включая вас в качестве помощника. Большое спасибо вам за все   -  person Anna    schedule 24.11.2016
comment
рад что помог!!   -  person coder    schedule 24.11.2016


Ответы (1)


Хорошо. Я решаю свою проблему благодаря @coder. Чтобы решить эту проблему, я добавил еще один разрез (возможно, хороший) в одну строку замыкания «as_polynomial»:

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), потому что это было бесполезно

person Anna    schedule 24.11.2016