Rule
Определение эквивалентности управляет для математических выражений
Блокноты MuPAD® будут демонтированы в будущем релизе. Используйте live скрипты MATLAB® вместо этого.
Live скрипты MATLAB поддерживают большую часть функциональности MuPAD, хотя существуют некоторые различия. Для получения дополнительной информации смотрите, Преобразовывают Notebook MuPAD в Live скрипты MATLAB.
Rule(pattern
,replacement
, <conditions
>) Rule(procedure
, <condProc
>)
Rule
является типом данных. Каждый объект Rule
– правила – описывает эквивалентность между математическими выражениями. Аргументы правила являются двумя выражениями шаблона, которые являются эквивалентными, и дополнительными некоторые условия для валидности эквивалентности.
Правило может быть применено к любому выражению и возвращает выражение, эквивалентное входу или FAIL
.
Кроме того, правило может состоять из процедуры, которая возвращает эквивалентное выражение в данное выражение или FAIL
, не используя сопоставителя.
Правила, созданные с Rule
, в основном использованы, чтобы создать основу правила для нового Simplify
. См. документацию Simplify
и Примера 8 для действительного приложения Rule
. Пример 3 показывает, как реализовать правила перезаписи через Rule
.
Все другие примеры только даны, чтобы объяснить поведение правил. На практике одно правила и их ручное приложение необычны.
Существует два вида правил: Используйте сопоставителя библиотеки, чтобы определить, подходит ли правило, или используйте определяемую пользователем процедуру, чтобы анализировать данное выражение и возвратить эквивалентное выражение.
Rule(pattern, replacement, conditions)
задает правило, которое описывает эквивалентность выражений pattern
и replacement
.
Когда это правило применяется к данному выражению ex
, сопоставитель вызван аргументами
match(ex, pattern, Cond = conditions)
и возвращает набор замен S:={var = ex_var, ...}
для каждой переменной var
pattern
, и ex_var
является соответствующим подвыражением ex
(см. match
для подробного описания).
В этом случае результат замены subs(replacement, S)
возвращен как эквивалентное выражение в ex
.
Вызов match
может также возвратить FAIL
, когда ex
не имеет той же структуры как pattern
. Затем возвращаемым значением приложения правила является FAIL
, также.
Смотрите match
для описания допустимых условий.
Также правило может состоять из процедуры, которая вызвана данным выражением и должна возвратить эквивалентное выражение или FAIL
. “Сопоставитель” не называется.
Rule(procedure, condProc)
задает такое правило, которое возвращает эквивалентное выражение в любой данный вход как возвращаемое значение procedure
или FAIL
.
Дополнительное условие condProc
должно быть процедурой, также. Эта процедура называется перед процедурой, которая производит эквивалентные выражения с данным выражением ex
. Когда на звонок, condProc(ex)
возвращает TRUE
, затем возвращаемое значение вызова procedure(ex)
, отвечают как результат приложения правила, в противном случае FAIL
.
С правилом, которое состоит из процедуры, несколько отношений, pattern <=> result
может быть выражен. Это в основном более эффективно, чем использование match
для каждой эквивалентности.
Правила с выражениями в качестве аргументов должны использовать идентификаторы, которые защищены от любого присвоения. Те идентификаторы должны иметь форму #X
, где X
может быть любым допустимым именем переменной. Все переменные, которые запускаются с #
на их имена, защищены ядром от любого присвоения.
Первое правило представляет упрощение sin(X)^2 + cos(X)^2 = 1
. Первый аргумент правила является выражением sin(X)^2 + cos(X)^2
. Каждое выражение, которое имеет ту же структуру, найдено match
и вторым аргументом правила, 1
возвращен как результат. Нет никаких условий для валидности этой эквивалентности. Идентификаторы, используемые для определения правила, защищаются от записи, потому что у них есть имена, начинающиеся с #
:
r := Rule(sin(`#X`)^2 + cos(`#X`)^2, 1): Rule::apply(r, sin(2*x - 1)^2 + cos(2*x - 1)^2)
Следующее выражение не имеет правильной формы, приложения сбоев правила:
Rule::apply(r, sin(2*x - 1)^2 + cos(2*x + 1)^2)
Следующее правило представляет теорему сложения sin(X + Y) = sin(X)*cos(Y) + sin(Y)*cos(X)
. Первый аргумент правила является выражением sin(X + Y)
. Каждое выражение, которое является вызовом sin
с суммой в качестве аргумента, идентифицировано match
и суммой, sin(X)*cos(Y) + sin(Y)*cos(X)
возвращен, где X
и Y
заменяются соответствующими частями данного выражения. Нет никаких условий для валидности этой эквивалентности. Вторая часть правила предотвращена от оценки с hold
. Идентификаторы, используемые для определения правила, защищаются от записи, потому что у них есть имена, начинающиеся с #
:
r := Rule(sin(`#X` + `#Y`), hold(sin(`#X`)*cos(`#Y`) + sin(`#Y`)*cos(`#X`))): Rule::apply(r, sin(tan(x) + tan(y)))
matcher идентифицирует различие двух выражений a
и b
как сумма a + -b
, поэтому также следующий пример работает:
Rule::apply(r, sin(tan(x) - tan(y)))
Мы задаем два правила на основе тригонометрического identies sin (x) 2 = 1 - cos (x) 2 и:
myrules := [Rule(sin(`#X`)^`#n`, (1 - cos(`#X`)^2)^(`#n`/2), {`#n` -> is(`#n`, Type::Even)}), Rule(tan(`#X`)^`#n`, (1/cos(`#X`)^2 - 1)^(`#n`/2), {`#n` -> is(`#n`, Type::Even)}) ]:
Мы хотим применить эти правила как переписывающие правила к различным выражениям. Мы передаем Rule::apply
всем подвыражениям выражения через misc::maprec
. Для удобства функция интерфейса myrewrite
реализован, который вызывает misc::maprec
:
myrewrite:= proc(f, rules) local _rewrite; begin _rewrite:= proc(x) local r, tmp; begin for r in rules do tmp:= Rule::apply(r, x); if tmp <> FAIL then x:= tmp; end; end; return(x) end; misc::maprec(f, TRUE = _rewrite); end:
Теперь мы можем вызвать myrewrite(f, myrules)
, чтобы применить правила перезаписи к выражению f
:
f:= tan(x) + sin(2*x) - tan(y)^2*sin(x + 3)^6 + sin(x)^2 * tan(23)^4: myrewrite(f, myrules);
delete myrules, myrewrite, f:
Другое правило представляет упрощение sin(X) = 0
, который только верен, когда X
является целочисленным кратным PI
:
r := Rule(sin(`#X`), 0, {`#X` -> is(`#X`/PI, Type::Integer)}): Rule::apply(r, sin(2*x*PI))
В последней возможности аргумент sin
не имеет необходимого свойства, таким образом, приложение сбоев правила.
После предположения x
выражение имеет правильную форму:
assume(x, Type::Integer): Rule::apply(r, sin(2*x*PI))
Следующее приложение правила проверяет константное выражение:
Rule::apply(r, sin(2*PI))
Почему FAIL
? Проблема, sin
упрощает постоянный вход 2*PI
до самого 0
, таким образом, правило получает 0
, как введено. Однако 0
не имеет необходимой формы, таким образом, FAIL
возвращен.
Другое правило представляет упрощение ln(neg^even*r) = even*ln(-neg) + ln(r)
, который только верен, когда neg
отрицателен, и even
является четным числом:
r := Rule(ln(`#Neg`^`#Even`*`#X`), `#Even`*ln(-`#Neg`) + ln(`#X`), {`#Neg` -> is(`#Neg`, Type::Negative) = TRUE, `#Even` -> is(`#Even`, Type::Even) = TRUE}): delete e, n, x: Rule::apply(r, ln(n^e*x))
Сбои приложения правила, потому что переменные не имеют необходимых свойств.
С предположением n
должен быть отрицательной переменной, и e
должен быть ровным:
assume(n < 0): assume(e, Type::Even): Rule::apply(r, ln(n^e*x))
Это правило представляет приложение rewrite
к выражению с целевым exp
, когда выражение имеет подвыражения типа "sin"
или "cos"
. Первый аргумент правила является процедурой, которая вызывает rewrite
с любым выражением и целевым exp
и возвращает выражение, эквивалентное входу (потому что rewrite
делает это). Второй аргумент является процедурой, которая проверяет, или sin
, или cos
содержится во входном выражении:
r := Rule(X -> rewrite(X, exp), X -> has(X, sin) or has(X, cos)): Rule::apply(r, sin(2*x - 1)^2 + cos(2*x - 1)^2)
Следующее выражение не имеет sin
или cos
, таким образом, приложение сбоев правила:
Rule::apply(r, tan(2*I*x))
Это правило представляет приложение rewrite
к выражению с несколькими целями. Первый аргумент правила является процедурой, которая применяет rewrite
к данному выражению с целью в зависимости от входа. Это правило не имеет процедуры условия:
rewProc := proc(ex) begin rewrite(ex, (if has(ex, exp) then tan elif has(ex, sin) or has(ex, cos) then cot elif has(ex, tan) or has(ex, cot) then sincos else exp end_if)) end_proc: r := Rule(rewProc): Rule::apply(r, exp(2*x))
Правило применяется снова к последнему результату:
Rule::apply(r, %)
Последний результат должен быть упрощен назад до первого выражения:
Simplify(%)
Новый Simplify
использует основу правила для применения большой перезаписи правил для нахождения самой простой формы любого данного выражения.
Мы хотим переписать только некоторые степени и принять, что все используемые переменные действительны (не используя свойства).
Список PowerRules
состоит из нескольких правил. Процедура powerRules
возвращает все это, управляет в списке.
Из-за лучшей удобочитаемости имена используемых идентификаторов коротки и не защищенные имена:
PowerRules := [Rule(A^m*A^n, hold(A^(m + n))), Rule(A^m/A^n, hold(A^(m - n))), Rule(A^n*B^n, hold((A*B)^n)), Rule(A^n/B^n, hold((A/B)^n)), Rule(A^n/B^n, hold((B/A)^-n)), Rule((A^m)^n, hold(A^(m*n)))]: powerRules := proc() begin PowerRules end_proc:
Simplify
вызван опцией SelectRules
и ожидает процедуру, которая возвращает список правил, применимых к данному выражению. В этом случае все правила возвращены в каждом случае.
Simplify
применяет все правила к данному выражению и также к переписанным результатам и пытается найти самую легкую форму выражения относительно процедуры оценки по умолчанию Simplify::complexity
.
Из-за аргумента SelectRules = powerRules
только данные правила использованы Simplify
:
Simplify(T^(1/2)*(R*T)^(-1/2), SelectRules = powerRules)
Другие выражения не могут быть упрощены с той же основой правила:
Simplify(sin(x)^2 + cos(x)^2, SelectRules = powerRules)
delete r, x, powerRules, PowerRules:
|
Выражение MuPAD®; все идентификаторы используются в качестве переменных шаблона для сопоставителя |
|
Выражение MuPAD с теми же идентификаторами, как |
|
Набор (типа |
|
Процедура MuPAD, которая вызвана выражением и должна возвратить эквивалентное выражение или |
|
Процедура, которая вызвана выражением перед |