Workshop GK 334, April 2, 2003 Efficiency Improvement by Tree Transducer Composition Janis Voigtl¨ ander Dresden University of Technology http://wwwtcs.inf.tu-dresden.de/ ∼ voigt Supported by the “Deutsche Forschungsgemeinschaft” under grants KU 1290/2-1 and KU 1290/2-3.
Macro Tree Transducers [Engelfriet, 1980] data Term = Term × Term | Term + Term | A | B data List = ⊗ List | ⊕ List | � A List | � B List | Nil data Ins = Mul Ins | Add Ins | Load A Ins | Load B Ins | End pre :: Term → List → List pre ( u 1 × u 2 ) y = ⊗ ( pre u 1 ( pre u 2 y )) pre ( u 1 + u 2 ) y = ⊕ ( pre u 1 ( pre u 2 y )) A y = � pre A y y = � pre B B y ⊗ ⊗ ⊗ � pre A pre � A × ⊕ Nil pre ⇒ ⇒ pre ⇒ 3 A + � A B + Nil + Nil B A � A B A B A Nil rev :: List → Ins → Ins rev ( ⊗ v ) z = rev v ( Mul z ) rev ( ⊕ v ) z = rev v ( Add z ) rev ( � A v ) z = rev v ( Load A z ) rev ( � B v ) z = rev v ( Load B z ) z = z rev Nil main t = rev ( pre t Nil ) End 1
Modularity vs. Efficiency rev Load A ⊗ End rev Load B pre � A End Add × ⊕ ⇒ 5 ⇒ 6 Nil pre rev Load A + � A B Mul B A � A End Nil Deforestation techniques [Wadler, 1990; Gill et al. , 1993] fail to eliminate intermediate results inside accumulating parameters! 2
� ✁ � ✁ ✂ Composition Techniques for Tree Transducers T OP ; MAC ⊆ MAC [Engelfriet, 1981]: g f g f ❀ z 1 z · · · z 1 z u · · · u MAC ; T OP ⊆ MAC [Engelfriet & Vogler, 1985]: g f g f g 1 g ❀ u · · · y 1 y u y 1 y · · · MAC su ; MAC wsu ⊆ MAC [K¨ uhnemann, 1998]: MAC su ; MAC wsu ⊆ AT T su ; AT T ⊆ AT T ⊆ MAC 3
Generalized Construction [V., 2001] Replace compositions involving an intermediate result as fol- lows: prerev rev rev u z pre z ❀ 1 pre 1 rev u u z Rules of prerev : obtained by translating right-hand sides of pre with rules of rev . Rules of 1 pre 1 rev : obtained by “walking upwards” in right-hand sides of pre . 4
Translating Right-Hand Sides: Example prerev rev rev prerev ⊗ rev u 1 z Mul pre Mul pre = ⇒ × pre y rev 1 pre 1 rev z z ❀ pre u 1 z pre u 1 u 1 u 2 u 2 y u 1 Mul y u 2 y u 2 z prerev prerev prerev u 1 Mul prerev u 1 Mul 1 pre 1 rev rev u 2 z ⇒ 1 pre 1 rev u 2 y rev ❀ z . y u 1 u 1 . Mul Mul . z z 5
� Transformed Program prerev :: Term → Ins → Ins → Ins prerev ( u 1 × u 2 ) y rev z = prerev u 1 ( prerev u 2 y rev (1 pre 1 rev u 1 ( Mul z ))) ( Mul z ) prerev ( u 1 + u 2 ) y rev z = prerev u 1 ( prerev u 2 y rev (1 pre 1 rev u 1 ( Add z ))) ( Add z ) prerev A y rev z = y rev y rev z = y rev prerev B 1 pre 1 rev :: Term → Ins → Ins 1 pre 1 rev ( u 1 × u 2 ) z = 1 pre 1 rev u 2 (1 pre 1 rev u 1 ( Mul z )) 1 pre 1 rev ( u 1 + u 2 ) z = 1 pre 1 rev u 2 (1 pre 1 rev u 1 ( Add z )) 1 pre 1 rev z = Load A z A 1 pre 1 rev B z = Load B z t = prerev t (1 pre 1 rev t End ) End main How does efficiency of this program relate to the original one? 6
✆ � ✂ ✁ � ☎ ✄ ✂ ✁ ☎ � � � � � � � � � Possible Loss of Efficiency data Nat = S Nat | Z :: Nat → Nat div , div div ( S u ) = div u exp :: Nat → Nat → Nat divexp , div = Z div Z divexp ( S u ) z = div exp u z ( S u ) = S ( div u ) div Z z = S z divexp ❀ = Z div Z div exp ( S u ) z = divexp u ( divexp u z ) exp :: Nat → Nat → Nat z = S z div exp Z exp ( S v ) z = exp v ( exp v z ) t = divexp t Z main Z z = S z exp main t = exp ( div t ) Z exp divexp div Z S 2 S 2 , but ⇒ 2 2 +2 ⇒ 3 2 2 S 2 Z S 2 Z Z Z Z 7
Efficiency Analysis for Non-strict Evaluation is Difficult isort [] = [] ( x : xs ) = insert x ( isort xs ) isort [] = [ x ] insert x insert x ( y : ys ) = if x ≤ y then x : y : ys else y : insert x ys qsort [] = [] qsort ( x : xs ) = qsort ( filter ( ≤ x ) xs ) + + x : qsort ( filter ( > x ) xs ) head ( x : xs ) = x minimum xs = head ( isort xs ) • isort and qsort require quadratic worst-case complexity, but qsort is more efficient in average case • minimum has linear worst-case complexity, but replacing qsort for isort would make it quadratic 8
✄ ✁ ✁ ✂ ✁ ✁ ✁ ✁ ✁ ✁ ☎ ✁ ✂ ✄ ✄ ✄ ✂ ✄ ✄ ✂ ✄ ✁ ✁ � � � � � � � � “Ticking” of Original Program ( u 1 × u 2 ) y = ⋄ ( ⊗ ( pre u 1 ( pre u 2 y ))) pre ( u 1 + u 2 ) y = ⋄ ( ⊕ ( pre u 1 ( pre u 2 y ))) pre y = ⋄ ( � A y ) pre A y = ⋄ ( � B y ) pre B ( ⋄ v ) z = • ( rev v z ) rev ( ⊗ v ) z = • ( rev v ( Mul z )) rev ( ⊕ v ) z = • ( rev v ( Add z )) rev ( � A v ) z = • ( rev v ( Load A z )) rev ( � B v ) z = • ( rev v ( Load B z )) rev z = • z rev Nil • rev • • ⋄ End rev rev ⊗ End rev ⊗ End pre ⇒ ⇒ ⇒ · · · ⇒ Mul pre pre × End pre A End pre A pre A B A pre B End B End B End
✁ ✁ � � � � � � � � � � � � � � � ✁ � ✁ � ✁ ✁ � ✁ � ✁ � ✁ � � Ticking of Composed Program ( u 1 × u 2 ) y z = ◦ ( prerev u 1 ( prerev u 2 y (1 pre 1 rev u 1 ( Mul z ))) ( Mul z )) prerev ( u 1 + u 2 ) y z = ◦ ( prerev u 1 ( prerev u 2 y (1 pre 1 rev u 1 ( Add z ))) ( Add z )) prerev y z = ◦ y prerev A y z = ◦ y prerev B 1 pre 1 rev ( u 1 × u 2 ) z = ◦ (1 pre 1 rev u 2 (1 pre 1 rev u 1 ( Mul z ))) 1 pre 1 rev ( u 1 + u 2 ) z = ◦ (1 pre 1 rev u 2 (1 pre 1 rev u 1 ( Add z ))) 1 pre 1 rev z = ◦ ( Load A z ) A 1 pre 1 rev z = ◦ ( Load B z ) B t = prerev t (1 pre 1 rev t End ) End main ◦ ◦ ◦ ◦ ◦ ◦ ◦ ◦ ◦ ◦ prerev ◦ prerev ◦ ◦ ◦ ◦ ◦ ◦ . A prerev . ◦ . 1 pre 1 rev End × 1 pre 1 rev ⇒ ⇒ 2 ⇒ ⇒ ⇒ Load B 1 pre 1 rev Load B . 1 pre 1 rev B . A B End × . ◦ 1 pre 1 rev B × End 1 pre 1 rev A B Load A End × A B A Mul A Mul A B Mul End End End
✄ ✄ ✄ ✆ ✄ Annotation through Composition �✂✁ ( u 1 × u 2 ) y = ⋄ ( ⊗ ( pre �✂✁ u 1 ( pre �✂✁ u 2 ( ⋆ y )))) pre �✂✁ ( u 1 + u 2 ) y = ⋄ ( ⊕ ( pre �✂✁ u 1 ( pre �✂✁ u 2 ( ⋆ y )))) pre �✂✁ A y = ⋄ ( � A ( ⋆ y )) pre y = ⋄ ( � B ( ⋆ y )) pre �✂✁ B ✄ v z ) ( ⋄ v ) z = ◦ ( rev rev ✄ v ( ◦ z ) ( ⋆ v ) z = rev rev ✄ ( ⊗ v ) z = rev ✄ v ( Mul z ) rev ✄ ( ⊕ v ) z = rev ✄ v ( Add z ) rev ✄ ( � ✄ v ( Load A z ) A v ) z = rev rev ✄ ( � ✄ v ( Load B z ) B v ) z = rev rev z = z rev Nil Composes into the same program, hence the num- ber of ◦ -symbols in the reduction result of: rev pre �☎✁ End × End A B is equal to the number of call-by-name reduction steps of: prerev Load B 1 pre 1 rev × End Load A ⇒ × A B End Mul A B End 11
✄ � � � � � ✄ � � ✄ ✆ ✄ � ✁ � � � ✄ � � � ✄ � Combining Annotations �✂✁ ( u 1 × u 2 ) y = ⋄ ( ⊗ ( pre �✂✁ u 1 ( pre �✂✁ u 2 ( ⋆ y )))) pre �✂✁ ( u 1 + u 2 ) y = ⋄ ( ⊕ ( pre �✂✁ u 1 ( pre �✂✁ u 2 ( ⋆ y )))) pre �✂✁ y = ⋄ ( � A ( ⋆ y )) pre A �✂✁ y = ⋄ ( � B ( ⋆ y )) pre B ✄ v z )) rev ( ⋄ v ) z = • ( ◦ ( rev ✄ v ( ◦ z ) ( ⋆ v ) z = rev rev ✄ v ( Mul z )) ( ⊗ v ) z = • ( rev rev ✄ v ( Add z )) ( ⊕ v ) z = • ( rev rev ✄ ( � ✄ v ( Load A z )) A v ) z = • ( rev rev ✄ ( � ✄ v ( Load B z )) B v ) z = • ( rev rev z = • z rev Nil Relative efficiency of original vs. transformed pro- gram can be determined by comparing numbers of • - and ◦ -symbols produced by above program: • ◦ • • ◦ • rev • ◦ pre End • ⇒ • × End ◦ ◦ A B Load B ◦ Load A Mul End 12
✁ � � ✄ ✄ � ✂ ✄ ✄ ✄ ✄ ✄ � ✄ ✄ ✄ � ✄ ✄ � ✄ ☎ ✄ ☎ ✄ ✁ ✁ ✂ ✁ ✄ ✄ ✄ � � � ✄ � � � � � ✄ � An Example Criterion at Work ✄ ( u 1 × u 2 ) y = • ( ⊗ ( pre ✄ u 1 ( pre ✄ u 2 ( ◦ y )))) pre ✄ ( u 1 + u 2 ) y = • ( ⊕ ( pre ✄ u 1 ( pre ✄ u 2 ( ◦ y )))) pre y = • ( � A ( ◦ y )) pre A y = • ( � B ( ◦ y )) pre B � v z ) rev ( ◦ v ) z = ◦ ( rev � v ( Mul z ) ( ⊗ v ) z = rev rev � v ( Add z ) ( ⊕ v ) z = rev rev � ( � � v ( Load A z ) A v ) z = rev rev � ( � � v ( Load B z ) B v ) z = rev rev z = z rev Nil � v z ) ( • v ) z = • ( rev rev ✄ is context-linear and -nondeleting , and Since pre � is linear and nondeleting , the following rules rev may be used with the aim of eliminating all ◦ - ✄ : symbols in the right-hand sides of pre • f • f v u v 1 v ◦ ⇒ ⇒ · · · • · · · v u v 1 v v · · · f • ◦ f v • u v 1 v ⇒ ⇒ · · · • · · · v u v 1 v v · · · C C • • v v C v 1 v 1 C ⇒ ⇒ · · · • · · · · · · • · · · v v v 1 v 1 v v · · · · · · 13
Recommend
More recommend