Джон Харрисон
Университет Кембриджа
10 сентября 2008 г.
Темы
Символьные вычисления
Представление данных
Система вывода
Дифференцирование
Упрощение посредством переписывания
Символьные вычисления
Представление данных
Мы будем рассматривать выражения, которые строятся из
переменных, констант и n-арных операторов.
Следовательно, мы определяем рекурсивный тип следующим
образом:
#type term = Var o f s t r i n g
| Const of s t r i n g
| Fn o f s t r i n g ∗ ( term l i s t ) ; ;
Type term d e f i n e d .
Вывод выражений
Сохранение приоритета
Мы можем завести список бинарных операторов с их приоритетами,
вроде следующего:
#l e t i n f i x e s =
[ "+" , 1 0 ; "−" , 1 0 ; " ∗" , 2 0 ; " / " , 2 0 ] ; ;
Печать: обсуждение
Печать: код
#l e t r e c s t r i n g _ o f _ t e r m p r e c =
fun ( Var s ) −> s
| ( C ons t c ) −> c
| ( Fn ( f , a r g s ) ) −>
i f l e n g t h a r g s = 2 & i s _ i n f i x f then
l e t prec ’ = get_precedence f in
l e t s1 = string_of_term prec ’
( hd a r g s )
and s 2 = s t r i n g _ o f _ t e r m p r e c ’
( hd ( t l a r g s ) ) i n
l e t s s = s 1^" ␣ "^ f ^" ␣ "^ s 2 i n
i f p r e c ’ <= p r e c then " ( "^ s s ^" ) " e l s e s s
else
f ^" ( " ^( s t r i n g _ o f _ t e r m s a r g s )^ " ) "
and s t r i n g _ o f _ t e r m s t =
match t with
[ ] −> ""
| [ t ] −> s t r i n g _ o f _ t e r m 0 t
| ( h : : t ) −> ( s t r i n g _ o f _ t e r m 0 h )^ " , "^
( string_of_terms t ) ; ;
Джон Харрисон Введение в Функциональное программирование
Лекция 9. Примеры на ML: Символьное Дифференцирование
Печать: установка
#t ; ;
t : term =
Fn
( "−" ,
[ Fn
( "/ " ,
[ Fn ( " s i n " , [ Fn ( "+" , [ Var " x " ; Var " y " ] ) ] ) ;
Fn ( " c o s " , [ Fn ( "−" , [ Var " x " ; Fn ( " exp " ,
[ Var " y " ] ) ] ) ] ) ] ) ;
Fn ( " l n " , [ Fn ( "+" , [ C o n s t " 1 " ; Var " x " ] ) ] ) ] )
#i n s t a l l _ p r i n t e r " p r i n t _ t e r m " ; ;
− : unit = ()
#t ; ;
t : term = ‘ s i n ( x + y ) / c o s ( x − exp ( y ) ) − l n ( 1 + x ) ‘
#l e t x = t ; ;
x : term = ‘ s i n ( x + y ) / c o s ( x − exp ( y ) ) − l n ( 1 + x ) ‘
#(x , t ) ; ;
− : term ∗ term =
‘ s i n ( x + y ) / c o s ( x − exp ( y ) ) − l n ( 1 + x ) ‘ ,
‘ s i n ( x + y ) / c o s ( x − exp ( y ) ) − l n ( 1 + x ) ‘
#[x ; t ; x ] ; ;
− : term l i s t =
[ ‘ s i n ( x + y ) / c o s ( x − exp ( y ) ) − l n ( 1 + x ) ‘ ;
‘ s i n ( x + y ) / c o s ( x − exp ( y ) ) − l n ( 1 + x ) ‘ ;
‘ s i n ( x + y ) / c o s ( x − exp ( y ) ) − l n ( 1 + x ) ‘ ]
Дифференцирование: алгоритм
l e t r e c d i f f e r e n t i a t e x tm = match tm with
Var y −> i f y = x then C o n s t " 1 " e l s e C o n s t " 0 "
| Co n s t c −> C o n s t " 0"
| Fn ( "−" , [ t ] ) −> Fn ( "−" , [ d i f f e r e n t i a t e x t ] )
| Fn ( "+" , [ t 1 ; t 2 ] ) −> Fn ( "+" , [ d i f f e r e n t i a t e x t 1 ;
d i f f e r e n t i a t e x t2 ] )
| Fn ( "−" , [ t 1 ; t 2 ] ) −> Fn ( "−" , [ d i f f e r e n t i a t e x t 1 ;
d i f f e r e n t i a t e x t2 ] )
| Fn ( "∗" , [ t 1 ; t 2 ] ) −>
Fn ( "+" , [ Fn ( " ∗" , [ d i f f e r e n t i a t e x t 1 ; t 2 ] ) ;
Fn ( "∗" , [ t 1 ; d i f f e r e n t i a t e x t 2 ] ) ] )
| Fn ( " i n v " , [ t ] ) −> c h a i n x t
( Fn ( "−" , [ Fn ( " i n v " , [ Fn ( "^" , [ t ; C o n s t " 2 " ] ) ] ) ] ) )
| Fn ( "^" , [ t ; n ] ) −> c h a i n x t
( Fn ( " ∗" , [ n ;
Fn ( "^" , [ t ;
Fn ( "−" , [ n ; C o n s t " 1 " ] ) ] ) ] ) )
| Fn ( " exp " , [ t ] ) −> c h a i n x t tm
| Fn ( " l n " , [ t ] ) −> c h a i n x t ( Fn ( " i n v " , [ t ] ) )
| Fn ( " s i n " , [ t ] ) −> c h a i n x t ( Fn ( " c o s " , [ t ] ) )
| Fn ( " c o s " , [ t ] ) −> c h a i n x t
( Fn ( "−" , [ Fn ( " s i n " , [ t ] ) ] ) )
| Fn ( " / " , [ t 1 ; t 2 ] ) −> d i f f e r e n t i a t e x
( Fn ( " ∗" , [ t 1 ; Fn ( " i n v " , [ t 2 ] ) ] ) )
| Fn ( " t a n " , [ t ] ) −> d i f f e r e n t i a t e x
( Fn ( " / " , [ Fn ( " s i n " , [ t ] ) ; Fn ( " c o s " , [ t ] ) ] ) )
and c h a i n x t u = Fn ( "∗" , [ d i f f e r e n t i a t e x t ; u ] ) ; ;
Примеры дифференцирования
Попробуем несколько примеров:
#l e t t 1 = Fn ( " s i n " , [ Fn ( "∗" , [ C o n s t " 2 " ;
Var " x " ] ) ] ) ; ;
t 1 : term = ‘ s i n ( 2 ∗ x ) ‘
#d i f f e r e n t i a t e " x " t 1 ; ;
− : term = ‘ ( 0 ∗ x + 2 ∗ 1 ) ∗ c o s ( 2 ∗ x ) ‘
#l e t t 2 = Fn ( " t a n " , [ Var " x " ] ) ; ;
t 2 : term = ‘ t a n ( x ) ‘
#d i f f e r e n t i a t e " x " t 2 ; ;
− : term =
‘(1 ∗ cos ( x )) ∗ inv ( cos ( x )) +
s i n ( x ) ∗ ( ( 1 ∗ −( s i n ( x ) ) ) ∗
−( i n v ( c o s ( x ) ^ 2 ) ) ) ‘
#d i f f e r e n t i a t e " y " t 2 ; ;
− : term =
‘(0 ∗ cos ( x )) ∗ inv ( cos ( x )) +
s i n ( x ) ∗ ( ( 0 ∗ −( s i n ( x ) ) ) ∗
−( i n v ( c o s ( x ) ^ 2 ) ) ) ‘
Упрощение выражений
Примеры упрощения
Мы должны применить simp рекурсивно, по индукции:
#l e t r e c dsimp = fun
( Fn ( fn , a r g s ) ) −>
simp ( Fn ( fn , map dsimp a r g s ) )
| t −> simp t ; ;