In tro duction to F unctional Programming: Lecture 9 1 In - - PDF document

in tro duction to f unctional programming lecture 9 1 in
SMART_READER_LITE
LIVE PREVIEW

In tro duction to F unctional Programming: Lecture 9 1 In - - PDF document

In tro duction to F unctional Programming: Lecture 9 1 In tro duction to F unctional Programming John Harrison Univ ersit y of Cam bridge Lecture 9 ML examples I: Sym b olic Dieren tiation T opics co v ered:


slide-1
SLIDE 1 In tro duction to F unctional Programming: Lecture 9 1 In tro duction to F unctional Programming John Harrison Univ ersit y
  • f
Cam bridge Lecture 9 ML examples I: Sym b
  • lic
Dieren tiation T
  • pics
co v ered:
  • Sym
b
  • lic
computation
  • Data
represen tation
  • Prett
yprin ting
  • Dieren
tiation
  • Simplication
b y rewriting John Harrison Univ ersit y
  • f
Cam bridge, 3 F ebruary 1998
slide-2
SLIDE 2 In tro duction to F unctional Programming: Lecture 9 2 Sym b
  • lic
computation This co v ers applications where manipulation
  • f
mathematical expr essions, in general con taining v ariables, is emphasized at the exp ense
  • f
actual n umerical calculation. There are sev eral successful `computer algebra systems' suc h as Axiom, Maple and Mathematica, whic h can do certain sym b
  • lic
  • p
erations that are useful in mathematics. Examples include factorizing p
  • lynomials
and dieren tiating and in tegrating expressions. W e will sho w ho w ML can b e used for suc h applications. Our example will b e sym b
  • lic
dieren tiation. This will illustrate all the t ypical comp
  • nen
ts
  • f
sym b
  • lic
computation systems: data represen tation, in ternal algorithms, parsing and prett yprin ting. John Harrison Univ ersit y
  • f
Cam bridge, 3 F ebruary 1998
slide-3
SLIDE 3 In tro duction to F unctional Programming: Lecture 9 3 Data represen tation W e will allo w mathematical expressions to b e built up from v ariables and constan ts b y the application
  • f
n-ary
  • p
erators. Therefore w e dene a recursiv e t yp e as follo ws:
  • datatype
term = Var
  • f
string | Const
  • f
string | Fn
  • f
string * (term list); F
  • r
example the expression sin(x + y )=cos(x
  • exp(y
))
  • l
n(1 + x) is represen ted b y: Fn("-", [Fn("/",[Fn("sin",[Fn("+",[Var "x", Var "y"])]), Fn("cos",[Fn("-",[Var "x", Fn("exp", [Var "y"])])])]), Fn("ln",[Fn("+",[Const "1", Var "x"])])]); John Harrison Univ ersit y
  • f
Cam bridge, 3 F ebruary 1998
slide-4
SLIDE 4 In tro duction to F unctional Programming: Lecture 9 4 The need for parsing and prin ting Reading and writing expressions in their ra w form is rather unpleasan t. This is a general problem in all sym b
  • lic
computation systems. T ypically
  • ne
w an ts:
  • A
p arser to accept input in h uman-readable form and translate it in to the in ternal represen tation
  • A
pr ettyprinter to translate
  • utput
from the in ternal represen tation bac k to a h uman-readable form. W e will use parsing as another ma jor example
  • f
functional programming, so w e will defer that for no w. Ho w ev er w e will no w write a simple prin ter for
  • ur
expressions. John Harrison Univ ersit y
  • f
Cam bridge, 3 F ebruary 1998
slide-5
SLIDE 5 In tro duction to F unctional Programming: Lecture 9 5 Prett yprin ting expressions Ho w do w e w an t to prin t expressions?
  • V
ariables and constan ts are just written as their names.
  • Ordinary
n-ary functions applied to argumen ts are written b y juxtap
  • sing
the function and a brac k eted list
  • f
argumen ts, e.g. f (x 1 ; : : : ; x n ).
  • Inx
binary functions lik e + are written in b et w een their argumen ts.
  • Brac
k ets are used where necessary for disam biguation.
  • Inx
  • p
erators ha v e a notion
  • f
precedence to reduce the need for brac k ets. John Harrison Univ ersit y
  • f
Cam bridge, 3 F ebruary 1998
slide-6
SLIDE 6 In tro duction to F unctional Programming: Lecture 9 6 Storing precedences W e can ha v e a list
  • f
binary
  • p
erators together with their precedences, e.g.
  • val
infixes = [("+",10), ("-",10), ("*",20), ("/",20)]; This sort
  • f
list, asso ciating data with k eys, is called an asso ciation list. T
  • get
the data asso ciated with a k ey w e use the follo wing:
  • fun
assoc a ((x,y)::rest) = if a = x then y else assoc a rest; In
  • ur
case, w e dene:
  • fun
get_precedence s = assoc s infixes; This pro cedure
  • f
linear searc h is inecien t, but it is simple and adequate for small examples. T ec hniques lik e hashing are b etter for hea vyw eigh t applications. John Harrison Univ ersit y
  • f
Cam bridge, 3 F ebruary 1998
slide-7
SLIDE 7 In tro duction to F unctional Programming: Lecture 9 7 Making precedences mo diable Because
  • f
static binding, c hanging the list
  • f
inxes do es not c hange get precedence. Ho w ev er w e can mak e infixes a reference instead and then it is mo diable:
  • val
infixes = ref [("+",10), ("-",10), ("*",20), ("/",20)]; ...
  • fun
get_precedence s = assoc s (!infixes); > val get_precedence = fn : string
  • >
int
  • get_precedence
"^"; ! Uncaught exception: ! Match
  • infixes
:= ("^",30)::(!infix es ); > val it = () : unit
  • get_precedence
"^"; > val it = 30 : int This setup is not purely functional, but is p erhaps more natural. John Harrison Univ ersit y
  • f
Cam bridge, 3 F ebruary 1998
slide-8
SLIDE 8 In tro duction to F unctional Programming: Lecture 9 8 Finding if an
  • p
erator is inx W e will treat an
  • p
erator as inx just if it app ears in the list
  • f
inxes with a precedence. W e can do:
  • fun
is_infix s = (get_precedence s; true) handle _ => false; b ecause get_precedence fails
  • n
non-inxes. An alternativ e co ding is to use an auxiliary function can whic h nds
  • ut
whether the application
  • f
its rst argumen t to its seconds succeeds::
  • fun
can f x = (f x; true) handle _ => false; > val can = fn : ('a
  • >
'b)
  • >
'a
  • >
bool
  • val
is_infix = can get_precedence; > val is_infix = fn : string
  • >
bool John Harrison Univ ersit y
  • f
Cam bridge, 3 F ebruary 1998
slide-9
SLIDE 9 In tro duction to F unctional Programming: Lecture 9 9 The prin ter: explanation The prin ter consists
  • f
t w
  • m
utually recursiv e functions. The function string_of_term tak es t w
  • argumen
ts. The rst is a `curren tly activ e precedence', and the second is the term. F
  • r
example, in prin ting the righ t-hand argumen t
  • f
x * (y + z), the curren tly activ e precedence is the precedence
  • f
*. If the function prin ts an application
  • f
an inx
  • p
erator (here +), it puts brac k ets round it unless its
  • wn
precedence is higher. W e ha v e a second, m utually recursiv e, function, to prin t a list
  • f
terms separated b y commas. This is for the argumen t lists
  • f
non-unary and non-inx functions
  • f
the form f (x 1 ; : : : ; x n ). John Harrison Univ ersit y
  • f
Cam bridge, 3 F ebruary 1998
slide-10
SLIDE 10 In tro duction to F unctional Programming: Lecture 9 10 The prin ter: co de
  • fun
string_of_term prec = fn (Var s) => s | (Const c) => c | (Fn(f,args)) => if length args = 2 andalso is_infix f then let val prec' = get_precedence f val s1 = string_of_term prec' (hd args) val s2 = string_of_term prec' (hd(tl args)) val ss = s1^" "^f^" "^s2 in if prec' <= prec then "("^ss^")" else ss end else f^"("^(string_of_terms args)^")" and string_of_terms tms = case tms
  • f
[] => "" | [t] => string_of_term t | (h::t) => (string_of_term h)^","^ (string_of_terms t); John Harrison Univ ersit y
  • f
Cam bridge, 3 F ebruary 1998
slide-11
SLIDE 11 In tro duction to F unctional Programming: Lecture 9 11 The prin ter: installing Mosco w ML has sp ecial facilities for installing user-dened prin ters in the toplev el read-ev al-prin t lo
  • p.
Once
  • ur
prin ter is installed, an ything
  • f
t yp e term will b e prin ted using it.
  • load
"PP"; > val it = () : unit
  • fun
print_term pps s = let
  • pen
PP in begin_block pps INCONSISTENT 0; add_string pps ("`"^(string_of_te rm s)^"`"); end_block pps end; > val print_term = fn : ppstream
  • >
term
  • >
unit
  • installPP
print_term; > val it = () : unit John Harrison Univ ersit y
  • f
Cam bridge, 3 F ebruary 1998
slide-12
SLIDE 12 In tro duction to F unctional Programming: Lecture 9 12 Before and after
  • t;
> val it = Fn ("-", [Fn ("/", [Fn ("sin", [Fn ("+", [Var "x", Var "y"])]), Fn ("cos", [Fn ("-", [Var "x", Fn ("exp", [Var "y"])])])]), Fn ("ln", [Fn ("+", [Const "1", Var "x"])])]) :term
  • installPP
print_term; > val it = () : unit
  • t;
> val it = `sin(x + y) / cos(x
  • exp(y))
  • ln(1
+ x)` : term
  • val
x = t; > val x = `sin(x + y) / cos(x
  • exp(y))
  • ln(1
+ x)` : term
  • [x,t,x];
> val it = [`sin(x + y) / cos(x
  • exp(y))
  • ln(1
+ x)`, `sin(x + y) / cos(x
  • exp(y))
  • ln(1
+ x)`, `sin(x + y) / cos(x
  • exp(y))
  • ln(1
+ x)`] : term list John Harrison Univ ersit y
  • f
Cam bridge, 3 F ebruary 1998
slide-13
SLIDE 13 In tro duction to F unctional Programming: Lecture 9 13 Dieren tiation: algorithm There is a w ell-kno wn metho d (taugh t in sc ho
  • ls)
to dieren tiate complicated expressions.
  • If
the expression is
  • ne
  • f
the standard functions applied to an argumen t, e.g. sin(x), return the kno wn deriv ativ e.
  • If
the expression is
  • f
the form f (x) + g (x) then apply the rule for sums, returning f (x) + g (x). Lik ewise for subtraction etc.
  • If
the expression is
  • f
the form f (x)
  • g
(x) then apply the pro duct rule, i.e. return f (x)
  • g
(x) + f (x)
  • g
(x).
  • If
the expression is
  • ne
  • f
the standard functions applied to a comp
  • site
argumen t, sa y f (g (x)) then apply the Chain Rule and so giv e g (x)
  • f
(g (x)). This translates v ery easily in to a recursiv e computer algorithm. John Harrison Univ ersit y
  • f
Cam bridge, 3 F ebruary 1998
slide-14
SLIDE 14 In tro duction to F unctional Programming: Lecture 9 14 Dieren tiation: co de fun differentiate x = fn Var y => if y = x then Const "1" else Const "0" | Const c => Const "0" | Fn("-",[t]) => Fn("-",[differentiate x t]) | Fn("+",[t1,t2]) => Fn("+",[differentiate x t1, differentiate x t2]) | Fn("-",[t1,t2]) => Fn("-",[differentiate x t1, differentiate x t2]) | Fn("*",[t1,t2]) => Fn("+",[Fn("*",[differentiate x t1, t2]), Fn("*",[t1, differentiate x t2])]) | Fn("inv",[t]) => chain x t (Fn("-",[Fn("inv",[Fn("^",[t,Const "2"])])])) | Fn("^",[t,n]) => chain x t (Fn("*",[n, Fn("^",[t, Fn("-",[n, Const "1"])])])) | (tm as Fn("exp",[t])) => chain x t tm | Fn("ln",[t]) => chain x t (Fn("inv",[t])) | Fn("sin",[t]) => chain x t (Fn("cos",[t])) | Fn("cos",[t]) => chain x t (Fn("-",[Fn("sin",[t])])) | Fn("/",[t1,t2]) => differentiate x (Fn("*",[t1, Fn("inv",[t2])])) | Fn("tan",[t]) => differentiate x (Fn("/",[Fn("sin",[t]), Fn("cos",[t])])) and chain x t u = Fn("*",[differentiate x t, u]); John Harrison Univ ersit y
  • f
Cam bridge, 3 F ebruary 1998
slide-15
SLIDE 15 In tro duction to F unctional Programming: Lecture 9 15 Dieren tiation examples Let's try a few examples: > val t1 = `sin(2 * x)` : term
  • differentiate
"x" t1; > val it = `(0 * x + 2 * 1) * cos(2 * x)` : term
  • val
t2 = Fn("tan",[Var "x"]); > val t2 = `tan(x)` : term
  • differentiate
"x" t2; > val it = `(1 * cos(x)) * inv(cos(x)) + sin(x) * ((1 *
  • (sin(x)))
*
  • (inv(cos(x)
^ 2)))` : term
  • differentiate
"y" t2; > val it = `(0 * cos(x)) * inv(cos(x)) + sin(x) * ((0 *
  • (sin(x)))
*
  • (inv(cos(x)
^ 2)))` : term John Harrison Univ ersit y
  • f
Cam bridge, 3 F ebruary 1998
slide-16
SLIDE 16 In tro duction to F unctional Programming: Lecture 9 16 Simplication It seems to w
  • rk
OK, but it isn't making certain
  • b
vious simplications, lik e
  • x
= 0. These arise partly b ecause w e apply the recursiv e rules lik e the c hain rule ev en in trivial cases. W e'll write a simplier:
  • val
simp = fn (Fn("+",[Const "0", t])) => t | (Fn("+",[t, Const "0"])) => t | (Fn("-",[t, Const "0"])) => t | (Fn("-",[Const "0", t])) => Fn("-",[t]) | (Fn("+",[t1, Fn("-",[t2])])) => Fn("-",[t1, t2]) | (Fn("*",[Const "0", t])) => Const "0" | (Fn("*",[t, Const "0"])) => Const "0" | (Fn("*",[Const "1", t])) => t | (Fn("*",[t, Const "1"])) => t | (Fn("*",[Fn("-",[t1]), Fn("-",[t2])])) => Fn("*",[t1, t2]) | (Fn("*",[Fn("-",[t1]), t2])) => Fn("-",[Fn("*",[t1, t2])]) | (Fn("*",[t1, Fn("-",[t2])])) => Fn("-",[Fn("*",[t1, t2])]) | (Fn("-",[Fn("-",[t])])) => t | t => t; John Harrison Univ ersit y
  • f
Cam bridge, 3 F ebruary 1998
slide-17
SLIDE 17 In tro duction to F unctional Programming: Lecture 9 17 Simplication examples W e need to apply simp recursiv ely , b
  • ttom-up:
  • val
rec dsimp = fn (Fn(f,args)) => simp(Fn(f,map dsimp args)) | t => simp t; No w w e get b etter results:
  • dsimp(differentiat
e "x" t1); > val it = `2 * cos(2 * x)` : term
  • dsimp(differentiat
e "x" t2); > val it = `cos(x) * inv(cos(x)) + sin(x) * (sin(x) * inv(cos(x) ^ 2))` : term
  • dsimp(differentiat
e "y" t); > val it = `0` : term There are still
  • ther
simplications to b e made, e.g. cos(x)
  • inv
(cos(x)) = 1. Go
  • d
algebraic simplication is a dicult problem! John Harrison Univ ersit y
  • f
Cam bridge, 3 F ebruary 1998