Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

7,8 лаба зі Ш.І / L8_Дифференцирование

.doc
Скачиваний:
5
Добавлен:
19.02.2016
Размер:
50.18 Кб
Скачать

Лабораторная работа № 8

Дифференцирование аналитических выражений

Представление выражений

Выражение состоит из констант, переменных, знаков операций. Для упрощения будем представлять выражение в виде вложенных функторов:

domains

expr = int(integer); представление числовых констант

var(symbol); представление переменных

sum(expr, expr); сумма выражений

sub(expr, expr); разность выражений

mult(expr, expr); произведение выражений

div(expr, expr); деление выражений

ln(expr); логарифм

sin(expr); синус

cos(expr) косинус

Запишем правила дифференцирования выражений. Этот блок правил простой и является представлением правил дифференцирования на языке Пролог.

Первая группа правил:

dif_expr(int(_),_,int(0)).

dif_expr(var(A),B,int(0)):-A<>B.

dif_expr(var(X),X,int(1)).

Первое правило указывает, что производная от константы равна нулю. В случае, когда дифференцирование производится по переменной, которая не входит в выражение, производная тоже равна нулю (2 правило). Третье правило это запись на прологе факта .

Запишем основные правила дифференцирования:

Производная суммы

dif_expr(sum(U,V),X,R):- dif_expr(U,X,U1), dif_expr(V,X,V1)

R:=sum(U1,V1).

Производная разности аналогична (записать самостоятельно)

Производная произведения

dif_expr(mult(U,V),X,R):- dif_expr(U,X,U1), dif_expr(V,X,V1)

R:=sum(mult(U1,V), mult(U,V1)).

Производная частного

dif_expr(div(U,V),X,R):- dif_expr(U,X,U1), dif_expr(U,X,U1)

R=div(sub(mult(U1,V), mult(U,V1)),mult(V,V)).

Производная логарифму

dif_expr(ln(U),X,R):- dif_expr(U,X,U1), R=div(U1,V).

Производная степени

Производные тригонометрических функций

dif_expr(sin(U), X, cos(U)).

dif_expr(cos(U), X, mult(int(-1),sin(U)).

Правило дифференцирования сложных функций

dif_expr(funct(U(X))

После дифференцирование выражение имеет некрасивый вид – содержит нули. Единицы, которые при ручном дифференцировании обычно автоматически опускаются. Например, выражение

X*0+ln(0+x) – ln(x+0)*1 фактически равно нулю

Для этой цели введем предикат reduce(expr,expr), в котором первый аргумент это выражение до упрощения а второй – после упрощения.

В нижеследующем правиле осуществляется упрощение суммы.

reduce(sum(X,Y),R);-reduce((X,X1), reduce((Y,Y1), sum_r(X1,Y1,R)

Первые две цели необходимы для упрощения слагаемых, а предикат sum_r(expr, expr) предназначен для упрощения суммы и является набором очевидных фактов и правил для этой операции.

sum_r(int(0), E, E).

sum_r(E, int(0), E).

ноль слева или справа в слагаемом можно опустить

sum_r(int(K), int(M) int(R)):-R=K+M.

Константы в сумме складываются.

sum_r(X, Y, sum(X,Y)). Предикат - ловушка

Упрощение разности

reduce(sub(X,Y),R);-reduce((X,X1), reduce((Y,Y1), sub_r(X1,Y1,R)

sub_r (E, E, int(0)). Разность одинаковых выражений

ноль слева и справа

sub_r(int(K), int(M) int(R)):-R=K–M. как учесть знак –

sub_r(X, Y, sub(X,Y)). Предикат - ловушка

Упрощение произведения

mult_r (int(0), _, int(0)). Умножение на ноль слева

mult_reduce (_, int(0), int(0)). Умножение на ноль справа

mult_reduce (int(1), E, E). Умножение на 1 слева

mult_reduce (E, int(1), E )). Умножение на 1 справа

mult_r(int(K), int(M) int(R)):-R=K*M.

mult_r(X, Y, mult(X,Y)). Предикат - ловушка

Упрощение частного

Поскольку упрощение не всегда возможно, последним предикатом в каждой группе должен быть предикат – ловушка.

Продифференцированное и упрощенное выражение представлено в префиксной форме записи. Естественнее выводить выражения в инфиксном виде. Введем предикат вывода выражения write_expr(expr).

Если аргумент – целое число или переменная, выводится значение константы или имя переменной.

write_expr(int(X) :-X>=0, write(X).

write_expr(var(X) :- write(X).

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

Составим предикат write_par(expr ), который действует следующим образом

write_par(E):-write(“(“),write_expr(E), write(“)“).

Вывод функции логарифм

write_expr(ln(X) :- write(“ln”),.write_par(X).

Правило вывода суммы, разности произведения, частного и возведения в степень различаются только знаком вывода знака

write_expr(sum(X,Y)):- write_expr(X), write(“+”), write_expr(Y).

write_expr(sub(X,Y)):- write_expr(X), write(“–”), write_expr(Y).

write_expr(mult(X,Y)):- write_expr(X), write(“*”), write_expr(Y).

write_expr(div(X,Y)):- write_expr(X), write(“/”), write_expr(Y).

write_expr(st(X,Y)):- write_expr(X), write(“^”), write_expr(Y).

Составим предикат специальной печати, имеющий следующую структуру

write_old(yun(X,Y)):-write_par(yun(X.Y)) *

write_old(yun(E):-write_yun(E)

здесь old- операция, приоритет, которой на единицу больше чем операции yun.

Первое из этих правил непосредственно расставляет скобки, второе обеспечивает поиск в базе знаний до тех пор, пока не встретиться ситуация, которая отвечает общим правилам вывода либо правилу (*). Для этого введем предикаты write_plus(expr), write_minus(expr) и т.д. Тогда эта предикатная группа имеет вид

write_minus(plus(X,Y)):-write_par(plus(X,Y)).

write_minus(E):-write_expr(E).

write_mult(minus(X,Y)):-write_par(minus(X,Y)).

write_minus(E):-write_expr(E);

write_div(mult(X,Y)):-write_ par (mult(E)).

write_div(E):-write_mult(E);

write_div(mult(X,Y)):-write_ par(mult(E)).

write_div(E):-write_mult(E);

Тогда группа правил для печати операций имеет вид

write_expr(minus(X,Y)):- write_expr(X), write(“–”), write_minus(Y).

write_expr(mult(X,Y)):- write_minus(X), write(“*”), write_minus(Y).

write_expr(div(X,Y)):- write_mult(X), write(“/”), write_div(Y).

write_expr(potens(X,Y)):- write_div(X), write(“^”), write_potens(Y).

Наибольшая вероятность возникновения ошибки в этой задаче может быть при формировании выражения из списка, поэтому целесообразно после того, как выражение получено проверить работу предиката s_expr в целом. Очевидно, что при нормальном завершении его работы исходный список должен быть пустым. В противном случае допущена ошибка и для ее анализа хорошо было бы иметь значение полученного выражения. Предикатная группа правил проверки check(list, expr) имеет следующий вид

check([],_):-!.

check(_,S):-write(S),write(“Error”).

Тогда цель будет иметь следующий вид

write(“Enter funcnion”), write(”f=”), readln(S), convert(S, Li),

s_expr(Li,Lo,E), check(Lo,E),

dif_expr(E,E_dif), reduce(E_dif, E_r), write”\n df/dx=”),

write_expr ( E_r).

Соседние файлы в папке 7,8 лаба зі Ш.І