
22.4. Полиномиальные уравнения
Полиномиальные уравнения решаются решателем полиномиальных уравнений, в котором реализуются разные методы решения таких уравнений. Обе части уравнения проверяются, чтобы установить, являются ли они полиномами от переменной X.Если проверка успешна, то уравнение с помощью предиката polinomial_normal_formпреобразуется в полиномиальную нормальную форму и производится обращение к предикату solve_polynomial_equation,входящему в решатель полиномиальных уравнений:
solve_equation(Lhs=Rhs,X,Solution)
polynomial (Lhs, X),
polynomial (Rhs, X),
polynomial_normal_form(Lhs-Rhs, X, Poly),
solve_polynomial_equation (Poly, X, Solution).
Полиномиальная нормальная форма
представляет собой список пар вида
(A,N
),гдеA
- коэффициент при
X
,который должен быть не равен нулю. Пары
сортируются в порядке строгого убывания
N
,для каждой степени существует не больше
одной пары. Например, список[(1,2),
(-3,1), (2,0)]представляет
собой нормальную форму полиномах2
-Зх
+ 2.Старший член полинома является
головой списка. Классические алгоритмы
обработки полиномов применимы для
решения уравнений в нормальной форме.
Сведение уравнения к полиномиальной
нормальной форме производится в два
этапа:
polynomial_normal_..form(Polynomial, X, Normal Form)
polynomial_form (Polynomial, X, PolyForm),
remove_zero_terms (PolyForm, NormalForm).
Предикат polynomial_form (X, Polynomial, PolyForm)используется для декомпозиции полинома. Отсортированный список PolyFormсостоит из пар коэффициент-степень, среди которых могут быть и пары с нулевыми коэффициентами.
Для многих полиномиальных методов удобно полагать отсутствие в полиномиальной форме термов с нулевыми коэффициентами. Поэтому вторым этапом сведения к полиномиальной нормальной форме должно быть удаление тех термов, коэффициенты которых равны нулю. Удаление осуществляется простой рекурсивной процедурой remove_zero__terms.
Программа для предиката
polynomial_formнепосредственно отражает программу
предиката polynomial.Для каждого предложения, используемого
в процессе разбора. есть соответствующее
предложение, дающее результирующий
полином. Например, полиномиальной формой
термахбудет [(1,n)]. Эта форма
выражается предложением
polynomial_form (X N, X, [(1, N)]).
Для сохранения полиномиальной формы используются рекурсивные предложения polynomial form,манипулирующие полиномами. Рассмотрим предложение
polynomal_form(Polyl+Poly2, X, PolyForm)
polynomial_form (Poly1, X, PolyForm1),
polynomial_form(Poly2, X, PolyForm2),
add_polynomials (PolyForm1, PolyForm2, PolyForm).
Процедура add_polynomialsреализует алгоритм сложения полиномов, прсдставленных в нормальной форме. Соответствующая программа это непосредственный список возможностей, которые могут появиться.
add_polynomials ([ ], Poly, Poly).
add_polynomials ([P | Poly], [ ], [P | Poly]).
add_polynomials ([(Ai, Ni) | Polyl], [(Aj, Nj) | Poly2], [(Ai,Ni)| Poly])
Ni > Nj, add_polynomials (Polyl, [(Aj,Nj) | Poly2], Poly).
add_polynomials([(Ai, N) | Polyl],[(Aj, N)[Poly2],[(A, N)| Poly])
Ni =:= Nj, A:=Ai+Aj, add_polynomials(Polyl, Poly 2, Poly).
add_polynomials ([(Ai, Ni) | Polyl], [(Aj, Nj) | Poly2], [(Aj, Nj) | Poly])
Ni < Nj, add_polynomials ([(Ai, Ni) | Polyl], Poly2, Poly).
Подобным образом процедуры subtract_polynomials, multiply_polynomialsи binomialпредставляют алгоритмы вычитания, умножения и биномиального расширения полиномов, заданных в нормальной форме. Получаемые результаты также являются полиномами в нормальной форме. Вспомогательный предикат multiply_single(Polyl, Monomial, Poly2)умножает полином на одночлен (C, N)и в качестве результата образует новый полином.
Как только полином представлен в нормальной форме, вызывается решатель алгебраических уравнений. Структура решателя алгебраических уравнений совпадает со структурой общего решателя уравнений. В решателе уравнений реализован набор методов решения, которые поочередно испытываются с целью определения, какой из них применим для решения данного уравнения. Предикат solve_polynomial_equationаналогичен предикату solve_equation.
Второе уравнение на рис. 22.1является квадратным уравнением и может быть решено с помощью стандартной формулы. Решатель уравнений использует тот же метод, что и человек. Чтобы убедиться, подходит ли данный метод для решения уравнения, с помощью предиката quadraticпроверяется, имеет ли старший член полинома вторую степень. Поскольку нулевые члены исключаются при приведении полинома к нормальной форме, посредством предиката padтакие члены, если необходимо, добавляются. Следующие два шага хорошо знакомы: вычисление дискриминанта уравнения и в соответствии со значением дискриминанта определение корней уравнения. Вновь наличие нескольких решений требует учета соответствующих возможностей:
solve._polynomial_.equalion (Poly, X, Solution)
quadratic (Poly),
pad (Poly, [(A,2),(B,1),(C,0)]),
discriminant(А, В, С, Discriminant),
root(X,А, В, С, Discriminant, Solution).
discriminant (A, B, C, D) D:=(B*В-4*A*С).
root(X,А, В, С,0, X = -В/(2 *А)).
root (X,А, В, С, D, X) = (-В+sqrt (D))/(2 *А)) D > 0.
root(X,A,B,C,D,X)=(-В-sqrt(D))/(2*A)) D > 0.
Другие предложения solve_polynomial_equationпредставляют в программе отдельные методы для решения разных алгебраических уравнений. Так, линейные уравнения решаются с помощью простой формулы. В комплексе PRESSкубические уравнения решаются в предположении знания одного из корней факторизацией и сведением к квадратному уравнению. Другие приемы распознают очевидные множители или замаскированные квадратные уравнения с отсутствующими кубическим и линейным членами.