scope.tex 188 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358
  1. \documentstyle[11pt,reduce,makeidx]{article}
  2. \pagestyle{empty}
  3. \makeindex
  4. \title{{\bf SCOPE 1.5\\ A Source-Code Optimization PackagE\\ for\\ REDUCE 3.6\\
  5. \vspace{0.5cm}
  6. =====\\
  7. \vspace{0.5cm} User's Manual}}
  8. \date{}
  9. \author {\large
  10. \vspace{1cm} \\
  11. J.A. van Hulzen \\ University of Twente, Department of Computer Science\\
  12. P.O. Box 217, 7500 AE Enschede, The Netherlands \\
  13. Email: infhvh@cs.utwente.nl}
  14. \newcommand{\ad}{\mbox{$\rightarrow$}\hspace{-.30cm}{$/$}\hspace{.30cm}}
  15. \begin{document}
  16. \maketitle
  17. \vspace{3cm}
  18. \begin{center}
  19. {\bf Abstract}\\
  20. \end{center}
  21. The facilities, offered by SCOPE 1.5, a Source-Code Optimization PackagE
  22. for {\REDUCE} 3.6, are presented. We discuss the user aspects of the package.
  23. The algorithmic backgrounds are shortly summarized.
  24. Examples of straightforward and more advanced usage are shown,
  25. both in algebraic and symbolic mode.
  26. Possibilities for a combined use of GENTRAN and SCOPE are presented as well.
  27. \vspace{1.5cm}
  28. \copyright {\em \ \ } J.A. van Hulzen, University of Twente. All rights reserved.
  29. \newpage
  30. \tableofcontents
  31. \newpage
  32. \pagestyle{headings}
  33. \section{Introduction}\label{SCOPE:intro}
  34. \pagenumbering{arabic}
  35. An important application of computer algebra systems is the generation
  36. of code for numerical purposes via automatic or semi-automatic program
  37. generation or synthesis.
  38. GENTRAN~\cite{Gates:84,Gates:85,Gates:86,Gates:91}, a flexible general-purpose
  39. package, was especially developed to assist in such a task, when using
  40. MACSYMA or {\REDUCE}.
  41. \index{optimization}
  42. Attendant to {\bf automatic program generation} is the problem
  43. of {\bf automatic source-code optimization}.
  44. This is a crucial aspect because code
  45. generated from symbolic computations often tends to be made up of
  46. lengthy arithmetic expressions.
  47. Such lengthy codes are grouped together in
  48. blocks of straight-line code in a program for numerical purposes. The
  49. main objective of SCOPE, our source-code optimization package, has been
  50. minimization of the number of (elementary) arithmetic operations in such
  51. blocks. This can be accomplished by replacing repeatedly occuring
  52. subexpressions, called common subexpressions or cse's for short,
  53. \index{cse (common subexpression)}
  54. by placeholders. We further assume that new statements of the form
  55. "placeholder := cse" are inserted correctly in the code. This
  56. form of optimization is often helpful in reducing redundancy in (sets of)
  57. expressions. A recent application, code generation for an
  58. incompressible Navier-Stokes problem~\cite{Goldman:95}, showed reduction
  59. from 45.000 lines of FORTRAN code to 13.000 lines.
  60. \index{optimizing compilers}
  61. Optimizing compilers ought to deal effectively and efficiently with
  62. the average, hand coded program. The enormous, arithmetic intensive
  63. expressions, easily producable by a computer algebra system, fall
  64. outside the range of the FORTRAN programs, once analyzed and discussed
  65. by Knuth~\cite{Knuth:71}. He suggested that optimization of the arithmetic in
  66. such a program is slightly overdone. The usual compiler optimization strategy
  67. is based on easy detection of redundancy, without assuming the validity of
  68. (some) algebric laws (see for instance ~\cite{Gonzales})
  69. Our optimization strategy however, requires the validity of
  70. some elementary algebraic laws. We employ heuristic techniques to
  71. reduce the arithmetic complexity of the given representation of a set
  72. ${\rm E}_{in}$ of input statements, thus producing a set
  73. ${\rm E}_{out}$ of output assignment statements.
  74. ${\rm E}_{in}$ and ${\rm E}_{out}$ define blocks of
  75. code, which would compute the same exact values for the same exact
  76. inputs, thus implicitly proving the correctness of the underlying
  77. software. Obviously the use of ${\rm E}_{out}$ ought to save a considerable
  78. amount of execution time in comparison with the application of ${\rm
  79. E}_{in}$. Johnson et al~\cite{Johnson:79} suggest that such
  80. transformations do not destabilize the computations. However this is only
  81. apparent after a careful error analysis of both ${\rm E}_{in}$ and ${\rm
  82. E}_{out}$. In view of the size of both ${\rm E}_{in}$ and ${\rm E}_{out}$
  83. such an analysis has to be automatized as well. Work in this direction is
  84. in progress ~\cite{Hulshof,Molenkamp:91,Molenkamp:94}.
  85. \index{error analysis}
  86. \index{arithmetic complexity}
  87. Although the use of SCOPE can considaribly reduce the arithmetic complexity
  88. of a given piece of code,
  89. we have to be aware of possible numerical side effects. In addition we have
  90. to realize that a mapping is performed from one source language to another
  91. source language, seemingly without taking into account the platform the resulting
  92. numerical code has to be executed on. Seemingly, because we implemented some
  93. facilities for regulating minimal expression length and for producing
  94. vector code.
  95. \index{vector code}
  96. This manual is organized as follows. We begin with some preliminary remarks
  97. in section~\ref{SCOPE:prel}. The history and the present status,
  98. the optimization
  99. strategy and the interplay between GENTRAN and SCOPE are shortly summarized.
  100. The basic algebraic mode facilities are presented in
  101. section~\ref{SCOPE:basic}. Special SCOPE features are discussed in
  102. section~\ref{SCOPE:soph}. Besides facilities for Horner-rules and an extended
  103. version of the REDUCE function {\tt structr}, we introduce some tools for
  104. extending SCOPE with user defined specialties. File management follows in
  105. section~\ref{SCOPE:files}. In section~\ref{SCOPE:decl} declaration handling
  106. and related issues are discussed, before illustrating our strategy concerning
  107. data dependencies and generation of vector code in section~\ref{SCOPE:dda}.
  108. In section~\ref{SCOPE:gopt} is shown how a combined used of GENTRAN and SCOPE
  109. can be profitable for pro\-gram-ge\-ne\-ra\-ti\-on. The use of SCOPE in
  110. symbolic mode is presented in section~\ref{SCOPE:symb}. A SCOPE syntax
  111. summary is given in section~\ref{SCOPE:syntax}.
  112. For completeness we present guidelines for installing the
  113. package in the last section.\\
  114. {\bf Requests}
  115. \begin{itemize}
  116. \item Comment and complaints about possible bugs can be send to the author
  117. using the e-mail address infhvh@cs.utwente.nl. A compact piece with
  118. REDUCE code, illustrating the bug, is prefered.
  119. \item When SCOPE 1.5 is used in prepairing results, presented in some
  120. publication, reference to its use is highly appreciated. A copy of the
  121. published document as well.
  122. \end{itemize}
  123. \newpage
  124. \section{Preliminaries}\label{SCOPE:prel}
  125. For completeness we present a historical survey, a birds-eye view of the
  126. overall optimization strategy and the interplay between GENTRAN and SCOPE.
  127. \subsection{History and Present Status}\label{SCOPE:hito}
  128. The first version of the package was designed to optimize the
  129. description of {\REDUCE}-statements, generated by
  130. NETFORM~\cite{Smit:81,Smit:82}. This
  131. version was tailored to a restrictive class of problems, mainly occurring
  132. in electrical network theory, thus implying that the right-hand
  133. sides (rhs's) in the input were limited to elements of ${\rm {\bf Z_2}}$[V],
  134. where V is a set of identifiers. The second version~\cite{vanHulzen:83}
  135. allowed rhs's from {\bf Z}[V]. For both versions the validity of the
  136. commutative and the associative law was assumed. A third version
  137. evolved from the latter package by allowing to apply the distributive
  138. law, i.e. by replacing (sub)expressions like $a.b + a.c$ by $a.(b
  139. + c)$ whenever possible. But the range of possible applications of
  140. this version was really enlarged by redefining V as a set of kernels,
  141. implying that almost any proper {\REDUCE}
  142. expression could function as a rhs. The mathematical capabilities of
  143. this version are shortly summarized in~\cite{Wang:84}, in the context of code
  144. generation and optimization for finite-element analysis. This version
  145. was further extended~\cite{vanHulzen:89} with a declaration-module,
  146. in accordance with the strategy outlined in~\cite{Aho:86}, chapter 6.
  147. It is used \index{GENTRAN}
  148. in combination with GENTRAN, for
  149. the construction of Jacobians and Hessians~\cite{Heuvel:89,Berger:92} and
  150. also in experiments with strategies for code vectorization~\cite{Goldman:89}.
  151. In the meantime the Jacobian-Hessian production package, at present
  152. called GENJAC, is further extended with possibilities for global optimization
  153. and with some form of loop-differentiation. So in stead of optimizing
  154. separate blocks of arithmetic we are now able to optimize complete programs,
  155. albeit of a rather specific syntactical structure~\cite{Berger:92}.
  156. The present 1.5 version of SCOPE, is an intermediate between the distributed first
  157. version and the future, second version. Version 2 is currently in
  158. development and will contain, besides the already existing common sub
  159. expression (cse) searches, facilities for structure and pattern recognition.
  160. The 1.5 version permits -using the present REDUCE terminology- rounded
  161. coefficients, based on the domain features, described in~\cite{Bradford:86},
  162. discovery and adequate treatement of a variety of data dependencies, and
  163. quotient-optimization, besides a collection of other improvements and
  164. refinements for using the facilities in the algebraic mode.
  165. Furthermore, an increased flexibility in the interplay between
  166. GENTRAN and SCOPE is accomplished. It is used for experiments concerning
  167. automatic differentiation ~\cite{Goldman:91}, symbolic-numeric approaches to
  168. stability analysis ~\cite{Ganzha:92,Ganzha:94} and for code generation for
  169. numerically solving the Navier-Stokes equations for incompressible
  170. flows ~\cite{Goldman:95}. An interesting example of its use elsewhere can be found
  171. in ~\cite{Dyer:94}.
  172. \subsection{Acknowledgements}\label{SCOPE:ackn}
  173. Many discussions with Victor V. Goldman, Jaap Smit and Paul S. Wang
  174. have contributed to the present status of SCOPE. I express my
  175. gratitude to the many students, who have also
  176. contributed to SCOPE, either by assisting in designing and implementing new
  177. facilities, or by applying the package in automated program generation projects
  178. in and outside university, thus showing shortcomings and suggesting
  179. improvements and extensions. I mention explicitly
  180. Frits Berger, Johan de Boer, John Boers, Pim Borst, Barbara Gates,
  181. Marcel van Heerwaarden, Pim van den Heuvel, Ben Hulshof, Emiel Jongerius,
  182. Steffen Posthuma, Anco Smit, Bernard van Veelen and Jan Verheul.
  183. \subsection{The Optimization Strategy in a Birds-eye View}\label{SCOPE:bird}
  184. In~\cite{vanHulzen:81,vanHulzen:83} we described the overall
  185. optimization strategy used for
  186. \index{optimization strategy}
  187. SCOPE as a composite function ${{\rm R}^{-1}} \circ {{\rm T}}
  188. \circ {{\rm R}}$. The function R defines how to store the input
  189. ${{\rm E}}_{0}$ in an expression database ${{\rm D}}_{0}$.
  190. The inverse function ${{\rm R}}^{{-1}}$ defines the output production.
  191. The function T defines the
  192. optimization process itself. It essentially consists of a heuristic
  193. remodeling of the (extendable and modifiable) expression database
  194. in combination with storing information required for a fast
  195. retrieval and correct insertion of the detected cse's in the output.
  196. This is accomplished by an iteratively
  197. applied search, resulting in a stepwise reduction of the arithmetic
  198. complexity of the input set, using an extended version of Breuer's
  199. \index{Breuer's Algorithm}
  200. grow factor algorithm~\cite{Breuer:69,vanHulzen:81,vanHulzen:83}.
  201. It is applied until no further profit
  202. is gained, i.e. until the reduction in arithmetic complexity stops.
  203. Before producing output, a finishing touch can be performed to further
  204. \index{finishing touch}
  205. reduce the arithmetic complexity with some locally applied techniques.
  206. Hence T is also a composite function.
  207. The overall process can be summarized as follows:
  208. %\begin{eqnarray*}
  209. \[ \begin{array}{rcrcl}
  210. {\rm R} & : & {\rm E_{in}}~=~{\rm E_0} & \rightarrow & ({\rm D_0},{\rm profit_0}) \\
  211. {\rm T_{\beta}} & : & ({\rm D_i},{\rm profit_i}) & \rightarrow & ({\rm D_{i+1}},
  212. {\rm profit_{i+1}})~,~{\rm i}~=~0,...,~\lambda - 1. \\
  213. {\rm F} & : & ({\rm D_{\lambda}},{\rm profit_{\lambda}}) & \rightarrow & {D_{\lambda}}\\
  214. {\rm R^{-1}} & : & {D_{\lambda}} & \rightarrow & {\rm E_{\lambda}}~=~{\rm E_{out}}
  215. %\end{eqnarray*}
  216. \end{array} \]
  217. ${\rm D_0}$ is created as a result of an R-application performed on
  218. input ${\rm E_0}$. The termination condition depends on some profit criterion
  219. related to the arithmetic complexity of the latest version of the
  220. input, ${{{\rm D}}_i}$. Hence we assume ${{{\rm profit}}_i} = true$
  221. for $i =0,~\cdots , \lambda -1$ and ${{{\rm profit}}_\lambda} =
  222. false$. The function T is defined
  223. by ${\rm T} = {\rm F} \circ {\rm T_{\beta}^{\lambda}}$, where
  224. ${{\rm T}}_{\beta}$ defines one iteration step, i.e. one application of the
  225. extended version of Breuer's algorithm, and where F defines a
  226. \index{extended Breuer algorithm}
  227. finishing touch, resulting in the final version $D_{\lambda}$ of
  228. ${{\rm D}}_{0}$, used to produce the output ${{\rm E}}_{\lambda}$.
  229. It is stated in ~\cite{vanHulzen:83} that the computing time for
  230. ${\rm T_{\beta}^{\lambda}}$ is ${\rm O(n.m)}$, where n is the size
  231. of ${\rm E_{in}}$ and m the number of cse's found during this process.
  232. Practical experience showed that the finishing touch can take about
  233. 10 \% of the actual cpu-time and that its real profit is limited.
  234. Therefore its use is made optional.
  235. The wish to optimize source code, defining arithmetic, usually leads an attempt
  236. to minimize the arithmetic complexity. This can be accomplished by replacing
  237. cse's by placeholders, assuming a new assignment
  238. statement "placeholder $:=$ cse" is correctly inserted in the code.
  239. So most of the cse-searches are done in right hand sides of
  240. arithmetic assignment statements.
  241. The search strategy depends on the permissible structure of the arithmetic
  242. expressions. We assume these expressions to be multivariate polynomials
  243. or rational functions in a finite set of kernels, and presented in some
  244. normal form. Let us further assume that scalar placeholders are substituted
  245. for the non-scalar kernels, such that back-substitution remains possible,
  246. using an adequate information storage mechanism. Then we are left with
  247. the interesting question how to define a minimal set of constituents of
  248. multivariate polynomials in some normal form norm. Let us take as an
  249. example of such a polynomial or rational function $p = 3a + 2b + 3 {b^2} c
  250. (3a + 2b){(c + d)^2}$. We easily recognize linear forms, i.e. $3a + 2b$
  251. (twice) and $c + d$, possibly raised to some power (${(c + d)}^2$), power
  252. products, such as ${b^2} c$, or monomial parts of products, i.e. $3 {b^2} c$.
  253. Hence with some imagination, one realizes that every polynomial can be
  254. decomposed in a set of linear forms and a set of power products. When
  255. assuming the validity of the commutative and the associative law, one can also
  256. realize that we can associate a coefficient matrix with the linear forms and
  257. an exponent matrix with the power products. The rows can correspondent
  258. with (sub)\-ex\-pressions and the columns with scalar identifiers.
  259. The entries are either coefficients or exponents.
  260. It is therefore conceivable to make a parser, mapping a set of REDUCE
  261. expressions in a database, consisting of two
  262. incidence matrices and a function table, such that the original expressions
  263. can be retrieved. Taking a group of assignmemnt statements or a list of
  264. equations, where in both cases the lhs's function as right hand side
  265. recognizers, does not confuse this idea. This rather informal indication
  266. merely serves as a suggestion how ${\rm R}$ and its inverse operation are
  267. designed.
  268. So we suggest that we can consider any set of rhs's as being built with
  269. linear forms and power products only. An additional remark is worth being
  270. made: Non-scalar kernels will in general have non-commutable arguments.
  271. These arguments can in turn be arbitrary {\REDUCE}-expressions, which
  272. also have to be incorporated in the database. Hence the function table
  273. is created recursively.
  274. \index{cse (common subexpression)}
  275. What is a cse and how do we locate its occurrences? A (sub)expression
  276. is common when it occurs repeatedly in the input. The occurrences are,
  277. as part of the input, distributed over the matrices, and shown as
  278. equivalent (sub)patterns. In fact, we repeatedly search for
  279. completely dense (sub)matrices of rank 1. The expression $2a + 3c$
  280. is a cse of ${e_1} = 2a + 4b + 3c$ and ${e_2} = 4a + 6c + 5d$,
  281. representable by (2,4,3,0) and (4,0,6,5), respectively. We
  282. indeed have to assume commutativity, so as to be able to produce new
  283. patterns (2,0,3,0,0), (0,4,0,0,1) and (0,0,0,5,2), representing $s = 2a + 3c$,
  284. ${e_1} = 4b + s$ and ${e_2} = 5d + 2s$,
  285. respectivily, and thus saving one addition and one multiplication.
  286. Such an additive cse can be a factor in a (sub)product,
  287. which in turn can extend its monomial part, when replacing the cse
  288. by a new symbol. Therefore an essential part of an
  289. optimization step is regrouping of information. This migration of
  290. information between the matrices is performed if the Breuer-searches
  291. are temporarily completed. After this regrouping the distributive law
  292. is applied, possibly also leading to a further regrouping. If at
  293. least one of these actions leads to a rearrangement of information the
  294. function ${\rm T} _{\beta}$ is again applied. In view of the
  295. iterative character of the optimization process we always accept
  296. minimal profits.
  297. A similar search is performed to detect multiplicative cse's, for
  298. instance occuring in ${e_1} = {a^2} {b^4} {c^3}$ and ${e_2} =
  299. {a^4} {c^6} {d^5}$. However, given a power product $\prod_{i=1}^m
  300. {x_i}^{{a}_i}$, any product $\prod_{i=1}^m {x_i}^{{b}_i}$, such that
  301. some ${b_i} \leq {a_i}$, for i = 1(1)m, can function as a cse. We
  302. therefore extend the search for multiplicative cse's by employing this
  303. property, and as indicated in~\cite{vanHulzen:83}.
  304. The finishing touch F is made to perform one-row and/or
  305. one-column searches. Once the extended Breuer-searches do not lead to
  306. further reduction in the arithmetic complexity we try -applying it- to
  307. improve what is left. The coefficients in (sub)sums can have,
  308. possibly locally, a gcd, which can be factored out. One-column
  309. operations serve to discover and to replace properly constant multiples of
  310. identifiers. As part of the output-process we subject all
  311. exponentiations left - at most one for each identifier - to an
  312. addition chain algorithm.
  313. \subsection{The Interplay between GENTRAN and SCOPE 1.5}\label{SCOPE:inter}
  314. The current version of SCOPE is written in RLISP.
  315. Like GENTRAN, it can be used as an extension of {\REDUCE}.
  316. When SCOPE is loaded GENTRAN is also activated.
  317. If we start a REDUCE session, we create an initial algebraic mode
  318. programming environment. All switches get their initial value, such as
  319. {\tt ON EXP,PERIOD} and {\tt OFF FORT}.
  320. Certain REDUCE commands serve to modify or to enrich the current environment.
  321. Others are used to perform calculations, producing formulae. Such a
  322. calculation follows a standard pattern, although parts of this repertoire
  323. can be influenced by the user, for instance by changing the value of
  324. certain switches. Usually execution is a three-step process.
  325. First the infix text is parsed into a prefix form. Then the internal algebra
  326. is applied on this form, leading to a so-called standard quotient.
  327. This quotient is stored on the property list of the identifier
  328. functioning as assigned variable for this value. The last step
  329. defines the inverse route from internal existence to external presentation
  330. in infix form. Occurrences of identifiers are recursively
  331. replaced by their standard quotient representation when the internal algebra
  332. is applied. Hence the REDUCE simplification strategy follows the imperative
  333. programming paradigm.
  334. When loading SCOPE, and thus GENTRAN, the environment is enriched with
  335. features for program generation and program optimization.
  336. Evaluation of GENTRAN and SCOPE commands differs from the standard REDUCE
  337. approach to evaluation. Both packages employ their own storage mechanism.
  338. The output is normally produced as a side-effect of the command evaluation.
  339. The output is directed to some medium, a file or a screen. Command evaluation
  340. is similar in GENTRAN and in SCOPE.
  341. The code generation process of GENTRAN can be viewed as the application
  342. \index{GENTRAN ! code generation process}
  343. of a composite function to an argument, which is almost equivalent with a
  344. piece of REDUCE code. Almost, because some GENTRAN specific facilities
  345. can be used. We can distinguish between the preprocessing phase,
  346. the translation phase and the postprocessing phase.
  347. During preprocessing relevant parts of the input are evaluated prior to
  348. translation into prefix form. Such a locally performed evaluation can be
  349. accomplished through recognition of certain "evaluation markers", i.e.
  350. modifications of the traditional assignment symbol {\tt :=},
  351. such as {\tt ::=}, {\tt :=:} and {\tt ::=:}. The {\tt :=} operator
  352. "orders" GENTRAN to translate the statement literally. Addition of an extra
  353. colon to the left hand side orders subscript expression evaluation before
  354. translation. An extra colon to the right hand side leads to right hand side
  355. evaluation, but without application of the storage mechanism of REDUCE.
  356. Hence evaluations
  357. remain anonymous and are only incorporated in the translatable "text".
  358. Another aspect of preprocessing is initialization of the symbol table,
  359. using information provided by a {\tt DECLARE} statement.
  360. \index{GENTRAN ! {\tt DECLARE} statement}
  361. GENTRAN also allows to further rewrite (sets of) arithmetic assignment
  362. statements, using the switches {\tt GENTRANOPT} and {\tt GENTRANSEG},
  363. \index{{\tt GENTRANOPT} switch}
  364. \index{{\tt GENTRANSEG} switch}
  365. introduced for code optimization (using SCOPE) and segmentation, respectively.
  366. \index{GENTRAN ! code segmentation}
  367. It possibly leads to storage of additional information in the symbol table.
  368. During the translation phase the final internal form
  369. of the code is produced, in combination with formatting specifications and
  370. instructions to produce declarations.
  371. Postprocessing finally does produce formatted code strings. So essentially,
  372. each GENTRAN command has its own seperate translation process, implying that
  373. the symbol table, required for the production of declarations, is fresh
  374. at the beginning of a GENTRAN command evaluation.
  375. As stated before, a SCOPE command evaluation is also a composite operation.
  376. The role of the assignment operators in both GENTRAN and SCOPE is similar.
  377. In SCOPE, the locally performed evaluation provides
  378. information to be entered in the database ${\rm D_0}$.
  379. If the declaration feature is activated, the symbol table generation and
  380. maintenance mechanism is borrowed from GENTRAN.
  381. For output production, we can make a choice from
  382. GENTRAN's target language repertoire. When declarations are required, we simply
  383. obey the GENTRAN regime as well. ${D_{\lambda}}$ is used to update the symbol
  384. table. All cse-names, generated during the optimization process, are typed in
  385. accordance with the strategy for dynamic typing, which is discussed
  386. in~\cite{Aho:86}, chapter 6. We assume all relevant identifiers
  387. of ${\rm E_{in}}$ to be adequately typed, using SCOPE's {\tt DECLARE} facility,
  388. an equivalent of GENTRAN's {\tt DECLARE} statement. The
  389. \index{SCOPE ! {\tt DECLARE} facility}
  390. \index{GENTRAN ! {\tt DECLARE} statement}
  391. production of ${D_{\lambda}}$ is completely decoupled from the normal
  392. REDUCE simplification strategy, because we employ our own expression database.
  393. In principle, the status of REDUCE before and after a GENTRAN or SCOPE
  394. command execution is unaltered. In principle, because some minor modifications,
  395. although user controlable, may be necessary. The special assignment symbols
  396. -also usable in SCOPE- were only introduced as a syntactical instrument to
  397. allow internal algebraic actions, decoupled from the standard REDUCE
  398. expression processing.
  399. This short excursion into the different evaluation strategies is added to
  400. assist in understanding the functioning of the different SCOPE commands and
  401. facilities, to be introduced in the next sections.
  402. \newpage
  403. \section{The Basic SCOPE 1.5 Facilities in the Algebraic Mode}\label{SCOPE:basic}
  404. {\REDUCE} allows, roughly speaking, two modes of operation in algebraic
  405. mode: {\tt ON EXP} or {\tt OFF EXP}.
  406. The first is the default setting, leading to
  407. expanded forms. The latter gives unexpanded forms, as discussed by Hearn
  408. in some detail~\cite{Hearn:85,Hearn:86}. It is obvious that the {\tt OFF
  409. EXP} setting is in general preferable over the {\tt ON
  410. EXP} setting when attempting to optimize the description of a set of
  411. assignment statements.
  412. \index{{\tt ACINFO} switch}
  413. \index{{\tt ROUNDED} switch}
  414. \index{{\tt DOUBLE} switch}
  415. \index{{\tt INPUTC} switch}
  416. \index{{\tt PRIMAT} switch}
  417. \index{{\tt PRIALL} switch}
  418. \index{{\tt EXP} switch}
  419. \index{{\tt FORT} switch}
  420. \index{{\tt FTCH} switch}
  421. \index{{\tt AGAIN} switch}
  422. \index{{\tt SIDREL} switch}
  423. \index{{\tt VECTORC} switch}
  424. \index{{\tt NAT} switch}
  425. \index{{\tt PERIOD} switch}
  426. \index{{\tt GENTRANOPT} switch}
  427. \index{{\tt PREFIX} switch}
  428. \index{{\tt INTERN} switch}
  429. \index{{\tt EVALLHSEQP} switch}
  430. \index{{\tt ROUNDBF} switch}
  431. The result of an application of SCOPE can be influenced by the use of
  432. certain {\REDUCE}- or SCOPE-switches. The influence of {\tt EXP} is obvious:
  433. unexpanded input is more compact than expanded.
  434. {\tt ON ACINFO} serves to produce tables with the numbers of arithmetic
  435. operations, oc\-cu\-ring in ${{{\rm E}}_0}$ and ${{\rm E}}_{\lambda}$,
  436. respectively.
  437. {\tt ON INPUTC} serves to echo the input, processed by SCOPE. The actual
  438. form of the input can be the consequence of locally performed evaluations,
  439. before the actual parsing into the database takes place.
  440. {\tt ON PRIMAT} can be used to visualize
  441. both ${{\rm D}}_{0}$ and $D_{\lambda}$.
  442. {\tt ON PRIALL} finally, can be used instead of
  443. {\tt ON ACINFO,INPUTC,PRIMAT}. These SCOPE-switches are initially all turned
  444. {\tt OFF}. SCOPE has a facility to visualize the status of all
  445. SCOPE-switches and some relevant {\REDUCE}-switches. The current status
  446. of all relevant switches can be presented with the command
  447. \hspace*{1cm} {\tt SCOPE\_SWITCHES}\verb+$+
  448. \index{SCOPE function ! {\tt SCOPE\_SWITCHES}}
  449. \example\label{ex:3.1.1}
  450. \index{SCOPE ! example}
  451. The start of a {\REDUCE} session shows the initial state
  452. of {\REDUCE}, directly after loading the SCOPE package.
  453. The set of relevant switches is made visible.
  454. Besides the {\REDUCE} switches {\tt EVALLHSEQP}, {\tt EXP}, {\tt FORT},
  455. {\tt NAT}, {\tt PERIOD}, {\t ROUNDBF}
  456. and {\tt ROUNDED} six additional SCOPE switches, i.e. {\tt AGAIN}, {\tt FTCH},
  457. {\tt INTERN}, {\tt PREFIX}, {\tt SIDREL} and {\tt VECTORC}, and the GENTRAN
  458. switches {\tt DOUBLE} and {\tt GENTRANOPT} are thus presented.
  459. They all wil be discussed in more
  460. detail below.
  461. {\small
  462. \begin{verbatim}
  463. REDUCE 3.6, 15-Jul-95 ...
  464. 1: load_package nscope$
  465. 2: SCOPE_SWITCHES$
  466. ON : exp ftch nat period
  467. OFF : acinfo again double evallhseqp fort gentranopt inputc
  468. intern prefix priall primat roundbf rounded sidrel
  469. vectorc
  470. 3: % etc. ...
  471. \end{verbatim}
  472. \begin{flushright}
  473. $\Box$
  474. \end{flushright}}
  475. Output is by default given in {\REDUCE} syntax, but FORTRAN syntax is
  476. possible in the usual way, e.g. {\tt ON FORT} and {\tt OFF PERIOD}, for
  477. instance. The use of other target languages
  478. from the GENTRAN repertoire is discussed in section~\ref{SCOPE:decl}.
  479. \subsection{The {\tt OPTIMIZE} command: Straightforward use}\label{SCOPE:optim}
  480. \index{{\tt OPTIMIZE} command}
  481. \index{{\tt INAME} option}
  482. \index{REDUCE function ! {\tt gensym}}
  483. \index{SCOPE function ! {\tt SETLENGTH}}
  484. A SCOPE application is easily performed and based on the use of
  485. the following syntax:
  486. \begin{center}
  487. \begin{tabular}{lcl}
  488. $<$SCOPE\_application$>$ & $::=$ & {\tt OPTIMIZE} $<$object\_seq$>$
  489. [{\tt INAME} $<$cse\_prefix$>$]\\
  490. $<$object\_seq$>$ & $::=$ & $<$object$>$[,$<$object\_seq$>$]\\
  491. $<$object$>$ & $::=$ & $<$stat$>~\mid~<$alglist$>~\mid~<$alglist\_production$>$ \\
  492. $<$stat$>$ & $::=$ & $<$name$>~<$assignment operator$>~<$expression$>$\\
  493. $<$assignment operator$>$ & $::=$ & $:=~\mid~::=~\mid~::=:~\mid~:=:$\\
  494. $<$alglist$>$ & $::=$ & \{$<$eq\_seq$>$\}\\
  495. $<$eq\_seq$>$ & $::=$ & $<$name$>~=~<$expression$>$[,$<$eq\_seq$>$]\\
  496. $<$alglist\_production$>$ & $::=$ & $<$name$>~\mid~<$function\_application$>$\\
  497. $<$name$>$ & $::=$ & $<$id$>~\mid~<$id$>(<$a\_subscript\_seq$>)$\\
  498. $<$a\_subscript\_seq$>$ & $::=$ & $<$a\_subscript$>$[,$<$a\_subscript\_seq$>$]\\
  499. $<$a\_subscript$>$ & $::=$ & $<$integer$>~\mid~<$integer infix\_expression$>$\\
  500. $<$cse\_prefix$>$ & $::=$ & $<$id$>$
  501. \end{tabular}
  502. \end{center}
  503. A SCOPE action can be applied on one assignment statement.
  504. The assigned variable
  505. is either a scalar identifier, like {\tt z} in example~\ref{ex:3.1.2}, or a
  506. name with subscripts, such as {\tt a(1,1)} in example~\ref{ex:3.1.3}.
  507. In stead of one
  508. statement a sequence of such statements, separated by comma's, is possible.
  509. An alternative is provided by the use of an algebraic mode list, consisting
  510. of {\REDUCE} equations. An assigned variable, identifying such a list, is
  511. allowed as well. Examples are presented in section~\ref{SCOPE:algo}.
  512. The function\_application is introduced in section~\ref{SCOPE:soph}. Such an
  513. application ought to produce an alglist.
  514. The expressions, i.e. rhs's in assignments or equations are legal {\REDUCE}
  515. expressions or ought to evaluate to such expressions. Statements inside
  516. expressions are allowed, but only useful if these expressions are evaluated,
  517. before being optimized. Only integer or rounded coefficients are supported
  518. by SCOPE. So we either suppose the default integer setting or allow the switch
  519. {\tt ROUNDED} to be turned {\tt ON}.
  520. The optional use of the {\tt INAME} extension in an {\tt OPTIMIZE} command
  521. is introduced to allow the user to influence the generation of cse-names.
  522. The cse\_prefix is an identifier, used to generate cse-names, by
  523. extending it with an integer part. If the cse\_prefix consists of letters
  524. only, the initially selected integer part is 0. All following integer parts are
  525. obtained by incrementing the previous integer part by 1. If the user-supplied
  526. cse\_prefix ends with an integer its value functions as initial integer part.
  527. The {\tt gensym}-function is applied when the {\tt INAME}-extension is omitted.
  528. The three alternatives are illustrated in example~\ref{ex:3.1.2}.
  529. As stated before minimal profits are accepted during all stages of the
  530. optimization process: many small steps may lead to impressive final results.
  531. But it can also lead to unwanted details. Therefore, it can be desirable
  532. to rerun an optimization request with a restriction on the minimal size of
  533. the rhs's. The command
  534. \hspace*{1cm} {\tt SETLENGTH} $<$integer$>$\$
  535. can be used to produce rhs's with a minimal arithmetic complexity,
  536. dictated by the value of
  537. its integer argument. Statements, used to rename function applications, are
  538. not affected by the {\tt SETLENGTH} command. The default setting is restored
  539. with the command
  540. \hspace*{1cm} {\tt RESETLENGTH}\$
  541. \index{SCOPE function ! {\tt RESETLENGTH}}
  542. We now illustrate the use of the {\tt OPTIMIZE} command through a number of
  543. small examples, being parts of {\REDUCE} sessions. We show in
  544. example~\ref{ex:3.1.2} the effect of the different visualization switches,
  545. the use of {\tt SETLENGTH} and {\tt RESETLENGTH} and of the three {\tt INAME}
  546. alternatives. In example~\ref{ex:3.1.3} the effect of some of the GENTRAN and
  547. SCOPE input processing features is presented. Some finishing touch activities
  548. are illustrated in the examples ~\ref{ex:3.1.4} and ~\ref{ex:3.1.5}.
  549. The approach towards rational exponents is presented in
  550. example~\ref{ex:3.1.6}, while some form of quotient optimization is
  551. illustrated in example~\ref{ex:3.1.7}. Finally, we present the differences
  552. in {\tt ON/OFF EXP} processing in example~\ref{ex:3.1.8}.
  553. \example\label{ex:3.1.2}
  554. \index{SCOPE ! example}
  555. The multivariate polynomial {\tt z} is a sum of 6 terms. These
  556. terms, monomials, are constant multiples of power products. A
  557. picture of ${{\rm D}}_{0}$ is shown after the input echo. The
  558. sums-matrix consists of only one row, identifiable by its Fa(the)r {\tt z},
  559. the lhs. Its exponent is given in the EC (Exponent or Coefficient)
  560. field. The 6 monomials are stored in the products-matrix. The
  561. coefficients are stored in the EC-fields and the predecessor row
  562. index, 0, is given in the Far-field. Before the $D_{\lambda}$ picture
  563. is given the effect of the optimization process, the output and the
  564. operator counts are shown. The optimized form of {\tt z} is obtained by
  565. applying the distributive law. The output also shows applications of
  566. an addition chain algorithm (\cite{Knuth:80} 441-466) as part of ${{\rm
  567. R}}^{{-1}}$, although its use in example~\ref{ex:3.1.4} is more apparent.
  568. \index{addition chain algorithm}
  569. Observe that the output illustrates the heuristic character of the
  570. optimization process: In this particular case the rhs can be written
  571. as a polynomial in {\tt g4}, thus saving one extra multiplication.
  572. The {\tt SETLENGTH} command is illustrated too. See also example~\ref{ex:3.2.6}.
  573. Application of a Horner-rule may be profitable as well. See, for instance
  574. example~\ref{ex:4.1.3}.
  575. \index{{\tt PRIALL} switch}
  576. {\small
  577. \begin{verbatim}
  578. ON PRIALL$
  579. z:=a^2*b^2+10*a^2*m^6+a^2*m^2+2*a*b*m^4+2*b^2*m^6+b^2*m^2;
  580. 2 2 2 6 2 2 4 2 6 2 2
  581. z := a *b + 10*a *m + a *m + 2*a*b*m + 2*b *m + b *m
  582. OPTIMIZE z:=:z$
  583. 2 2 2 6 2 2 4 2 6 2 2
  584. z := a *b + 10*a *m + a *m + 2*a*b*m + 2*b *m + b *m
  585. Sumscheme :
  586. || EC|Far
  587. ------------
  588. 0|| 1| z
  589. ------------
  590. \end{verbatim}}
  591. \newpage
  592. {\small
  593. \begin{verbatim}
  594. Productscheme :
  595. | 0 1 2| EC|Far
  596. ---------------------
  597. 1| 2 2| 1| 0
  598. 2| 6 2| 10| 0
  599. 3| 2 2| 1| 0
  600. 4| 4 1 1| 2| 0
  601. 5| 6 2 | 2| 0
  602. 6| 2 2 | 1| 0
  603. ---------------------
  604. 0 : m
  605. 1 : b
  606. 2 : a
  607. Number of operations in the input is:
  608. Number of (+/-) operations : 5
  609. Number of unary - operations : 0
  610. Number of * operations : 10
  611. Number of integer ^ operations : 11
  612. Number of / operations : 0
  613. Number of function applications : 0
  614. g1 := b*a
  615. g5 := m*m
  616. g2 := g5*b*b
  617. g3 := g5*a*a
  618. g4 := g5*g5
  619. z := g2 + g3 + g1*(2*g4 + g1) + g4*(2*g2 + 10*g3)
  620. Number of operations after optimization is:
  621. Number of (+/-) operations : 5
  622. Number of unary - operations : 0
  623. Number of * operations : 12
  624. Number of integer ^ operations : 0
  625. Number of / operations : 0
  626. Number of function applications : 0
  627. Sumscheme :
  628. | 0 3 4 5| EC|Far
  629. ------------------------
  630. 0| 1 1| 1| z
  631. 15| 2 10| 1| 14
  632. 17| 2 1 | 1| 16
  633. ------------------------
  634. 0 : g4
  635. 3 : g1
  636. 4 : g2
  637. 5 : g3
  638. \end{verbatim}}
  639. \newpage
  640. {\small
  641. \begin{verbatim}
  642. Productscheme :
  643. | 8 9 10 11 17 18 19 20| EC|Far
  644. ------------------------------------
  645. 7| 1 1| 1| g1
  646. 8| 1 2 | 1| g2
  647. 9| 1 2| 1| g3
  648. 10| 2 | 1| g4
  649. 11| 2 | 1| g5
  650. 14| 1 | 1| 0
  651. 16| 1 | 1| 0
  652. ------------------------------------
  653. 8 : g5
  654. 9 : g4
  655. 10 : g3
  656. 11 : g2
  657. 17 : g1
  658. 18 : m
  659. 19 : b
  660. 20 : a
  661. OFF PRIALL$
  662. SETLENGTH 2$
  663. OPTIMIZE z:=:z INAME s$
  664. 2 2
  665. s1 := b *m
  666. 2 2
  667. s2 := a *m
  668. 4 4
  669. z := (a*b + 2*m )*a*b + 2*(s1 + 5*s2)*m + s1 + s2
  670. RESETLENGTH$
  671. OPTIMIZE z:=:z INAME s1$
  672. s1 := b*a
  673. s5 := m*m
  674. s2 := s5*b*b
  675. s3 := s5*a*a
  676. s4 := s5*s5
  677. z := s2 + s3 + s1*(2*s4 + s1) + s4*(2*s2 + 10*s3)
  678. \end{verbatim}
  679. \begin{flushright}
  680. $\Box$
  681. \end{flushright}}
  682. \index{SCOPE function ! {\tt SETLENGTH}}
  683. \index{SCOPE function ! {\tt RESETLENGTH}}
  684. \example\label{ex:3.1.3}
  685. \index{SCOPE ! example}
  686. The input echo below shows the literal copy of the first assignment.
  687. This is in accordance with role the GENTRAN assignment operator {\tt :=}
  688. ought to play. The second assignment, this time using the operator {\tt ::=:},
  689. leads to rhs evaluation (expansion) and lhs subscript-value substitution.
  690. Application of the distributive law is refected by the rhs of {\tt a(1,1)}
  691. in the presented result.
  692. \index{{\tt INPUTC} switch}
  693. {\small
  694. \begin{verbatim}
  695. OPERATOR a$ k:=j:=1$ u:=c*x+d$ v:=sin(u)$
  696. ON INPUTC$
  697. OPTIMIZE a(k,j):=v*(v^2*cos(u)^2+u), a(k,j)::=:v*(v^2*cos(u)^2+u) INAME s;
  698. 2 2
  699. a(k,j) := v*(v *cos(u) + u)
  700. 2 3
  701. a(1,1) := cos(c*x + d) *sin(c*x + d) + sin(c*x + d)*c*x + sin(c*x + d)*d
  702. s9 := cos(u)*v
  703. a(k,j) := v*(u + s9*s9)
  704. s6 := x*c + d
  705. s5 := sin(s6)
  706. s10 := s5*cos(s6)
  707. a(1,1) := s5*(s6 + s10*s10)
  708. \end{verbatim}
  709. \begin{flushright}
  710. $\Box$
  711. \end{flushright}}
  712. \example\label{ex:3.1.4}
  713. \index{SCOPE ! example}
  714. The effect is shown of a finishing touch application, in combination
  715. with FORTRAN output. The value of {\tt S0} is rewritten during output
  716. preparation, and the earlier mentioned addition chain algorithm is applied.
  717. When turning {\tt OFF} the switch {\tt FTCH} the latter activity is skipped.
  718. \index{{\tt FTCH} switch}
  719. \index{{\tt FORT} switch}
  720. \index{{\tt PERIOD} switch}
  721. {\small
  722. \begin{verbatim}
  723. ON FORT$ OFF PERIOD$
  724. OPTIMIZE z:=(6*a+18*b+9*c+3*d+6*f+18*g+6*h+5*j+5*k+3)^13 INAME s;
  725. S0=5*(J+K)+3*(3*C+D+1+6*(B+G)+2*(A+F+H))
  726. S3=S0*S0*S0
  727. S2=S3*S3
  728. Z=S0*S2*S2
  729. OFF FTCH$
  730. OPTIMIZE z:=(6*a+18*b+9*c+3*d+6*f+18*g+6*h+5*j+5*k+3)^13 INAME s;
  731. Z=(5*(J+K)+3*(3*C+D+1+6*(B+G)+2*(A+F+H)))**13
  732. \end{verbatim}
  733. \begin{flushright}
  734. $\Box$
  735. \end{flushright}}
  736. \example\label{ex:3.1.5}
  737. \index{SCOPE ! example}
  738. Recovery of repeatedly occurring integer multiples of identifiers,
  739. as part of the finishing touch, is illustrated. This facility is
  740. part of the finishing touch and will seemingly be neglected when
  741. using {\tt SETLENGTH} 2\verb+$+ instruction in stead of {\tt OFF FTCH}.
  742. \index{{\tt FTCH} switch}
  743. {\small
  744. \begin{verbatim}
  745. OPTIMIZE x:=3*a*p, y:=3*a*q, z:=6*a*r+2*b*p,
  746. u:=6*a*d+2*b*q, v:=9*a*c+4*b*d, w:=4*b INAME s;
  747. s2 := 3*a
  748. x := s2*p
  749. y := s2*q
  750. s0 := 2*b
  751. s3 := 6*a
  752. z := s0*p + s3*r
  753. u := s0*q + s3*d
  754. w := 4*b
  755. v := w*d + 9*c*a
  756. OFF FTCH$
  757. OPTIMIZE x:=3*a*p, y:=3*a*q, z:=6*a*r+2*b*p,
  758. u:=6*a*d+2*b*q, v:=9*a*c+4*b*d, w:=4*b INAME t;
  759. x := 3*p*a
  760. y := 3*q*a
  761. z := 2*b*p + 6*r*a
  762. u := 2*b*q + 6*d*a
  763. v := 4*d*b + 9*c*a
  764. w := 4*b
  765. ON FTCH$
  766. SETLENGTH 2$
  767. OPTIMIZE x:=3*a*p, y:=3*a*q, z:=6*a*r+2*b*p,
  768. u:=6*a*d+2*b*q, v:=9*a*c+4*b*d, w:=4*b INAME t;
  769. x := 3*p*a
  770. y := 3*q*a
  771. z := 2*b*p + 6*r*a
  772. u := 2*b*q + 6*d*a
  773. v := 4*d*b + 9*c*a
  774. w := 4*b
  775. \end{verbatim}
  776. \begin{flushright}
  777. $\Box$
  778. \end{flushright}}
  779. \index{{\tt FTCH} switch}
  780. \index{SCOPE function ! {\tt SETLENGTH}}
  781. \example\label{ex:3.1.6}
  782. \index{SCOPE ! example}
  783. This example serves to show how SCOPE deals with rational
  784. exponents. All rational exponents of an identifier are collected.
  785. \index{rational exponents}
  786. The least common
  787. multiple lcm of the denominators of these rationals is
  788. computed and the variable is replaced by a possibly newly selected
  789. variable name, denoting the variable raised to the power 1/lcm. This
  790. facility is only efficient for what we believe to be problems
  791. occurring in computational practice. That is easily verified by
  792. extending the sum we are elaborating here with some extra terms.
  793. \newpage
  794. {\small
  795. \begin{verbatim}
  796. ON INPUTC,FORT$
  797. OPTIMIZE z:=:FOR j:=2:6 SUM q^(1/j) INAME s;
  798. 1/6 1/5 1/4 1/3
  799. z := q + q + q + q + sqrt(q)
  800. S0=Q**(1.0/60.0)
  801. S8=S0*S0
  802. S7=S8*S0
  803. S5=S8*S7
  804. S3=S5*S5
  805. S2=S8*S3
  806. S1=S7*S2
  807. S4=S5*s1
  808. Z=S4+S1+S2+S3+S4*S3
  809. \end{verbatim}
  810. \begin{flushright}
  811. $\Box$
  812. \end{flushright}}
  813. \example\label{ex:3.1.7}
  814. \index{SCOPE ! example}
  815. \index{{\tt INPUTC} switch}
  816. \index{{\tt ROUNDED} switch}
  817. \index{{\tt FORT} switch}
  818. The special attention, given to rational exponents, is not extended to
  819. rational coefficients. The script in this example shows four different
  820. approaches for dealing with such coefficients using the expressions assigned to
  821. {\tt f} and {\tt g}. We start with a literal parsing of the two assignments,
  822. leading to a form of ${\rm D}_0$, which is based on the present REDUCE
  823. strategy for dealing with fixed float numbers in the default integer
  824. coefficient domain setting.
  825. The four rational numbers $\frac{31}{5} ,~ \frac{31}{10} ,~\frac{93}{5}~
  826. {\rm and}~\frac{93}{10}$ are just like ${\rm b}^{\frac{1}{5}}$, $\sqrt {\rm
  827. sin(\cdots)}$ and ${\rm sin(\cdots)}^{\frac{5}{3}}$ considered as kernels.
  828. The second approach illustrates the effect of simplification in
  829. an {\tt OFF ROUNDED} mode prior to parsing. The input expressions are
  830. remodeled into rational expressions, the usual internal standard quotient form.
  831. After turning {\tt ON} the switch {\tt ROUNDED} we repeat the previous
  832. commands. Again some differences in evaluation can be observed. Literally
  833. taken input, the third approach, shows rational exponent optimizations
  834. prior to the production of rounded exponents in the output.
  835. The last approach, simplification before parsing, leads to a float
  836. representation for the rational exponents. SCOPE's exponent optimization
  837. features are designed for integer and rational exponents only. Floating
  838. point exponentiation is therefore assumed to be a function application.
  839. Further illustrations of operations on quotients are shown in
  840. example~\ref{ex:8.2}.
  841. {\small
  842. \begin{verbatim}
  843. ON INPUTC$
  844. OPTIMIZE
  845. f:= cos(6.2*a+18.6*(b)^(1/5))/sqrt(sin(3.1*a+9.3*(b)^(1/5))),
  846. g:= sin(6.2*a+18.6*(b)^(1/5))/sin(3.1*a+9.3*(b)^(1/5))^(5/3)
  847. INAME s$
  848. \end{verbatim}}
  849. \newpage
  850. {\small
  851. \begin{verbatim}
  852. 31 93 1/5
  853. cos(----*a + ----*b )
  854. 5 5
  855. f := -------------------------------
  856. 31 93 1/5
  857. sqrt(sin(----*a + ----*b ))
  858. 10 10
  859. 31 93 1/5
  860. sin(----*a + ----*b )
  861. 5 5
  862. g := ----------------------------
  863. 31 93 1/5 5/3
  864. sin(----*a + ----*b )
  865. 10 10
  866. 1/5
  867. s15 := b
  868. 93 31
  869. s12 := s15*---- + a*----
  870. 5 5
  871. 93 31
  872. s6 := sin(----*s15 + ----*a)
  873. 10 10
  874. 1/6
  875. s14 := s6
  876. s5 := s14*s14*s14
  877. cos(s12)
  878. f := ----------
  879. s5
  880. sin(s12)
  881. g := -----------
  882. s5*s14*s6
  883. OPTIMIZE
  884. f:=: cos(6.2*a+18.6*(b)^(1/5))/sqrt(sin(3.1*a+9.3*(b)^(1/5))),
  885. g:=: sin(6.2*a+18.6*(b)^(1/5))/sin(3.1*a+9.3*(b)^(1/5))^(5/3)
  886. INAME t$
  887. 1/5
  888. 93*b + 31*a
  889. cos(----------------)
  890. 5
  891. f := -----------------------------
  892. 1/5
  893. 93*b + 31*a
  894. sqrt(sin(----------------))
  895. 10
  896. \end{verbatim}}
  897. \newpage
  898. {\small
  899. \begin{verbatim}
  900. 1/5
  901. 93*b + 31*a
  902. sin(----------------)
  903. 5
  904. g := ------------------------------------------------
  905. 1/5 1/5
  906. 93*b + 31*a 2/3 93*b + 31*a
  907. sin(----------------) *sin(----------------)
  908. 10 10
  909. 1/5
  910. t7 := 93*b + 31*a
  911. t7
  912. t2 := ----
  913. 5
  914. t7
  915. t5 := sin(----)
  916. 10
  917. 1/6
  918. t11 := t5
  919. t4 := t11*t11*t11
  920. cos(t2)
  921. f := ---------
  922. t4
  923. sin(t2)
  924. g := -----------
  925. t4*t11*t5
  926. ON ROUNDED$
  927. OPTIMIZE
  928. f:= cos(6.2*a+18.6*(b)^(1/5))/sqrt(sin(3.1*a+9.3*(b)^(1/5))),
  929. g:= sin(6.2*a+18.6*(b)^(1/5))/sin(3.1*a+9.3*(b)^(1/5))^(5/3)
  930. INAME s$
  931. 1/5
  932. cos(6.2*a + 18.6*b )
  933. f := -----------------------------
  934. 1/5
  935. sqrt(sin(3.1*a + 9.3*b ))
  936. 1/5
  937. sin(6.2*a + 18.6*b )
  938. g := --------------------------
  939. 1/5 5/3
  940. sin(3.1*a + 9.3*b )
  941. \end{verbatim}}
  942. \newpage
  943. {\small
  944. \begin{verbatim}
  945. 0.2
  946. s5 := 9.3*b + 3.1*a
  947. s8 := 2*s5
  948. s4 := sin(s5)
  949. 0.166666666667
  950. s10 := s4
  951. s3 := s10*s10*s10
  952. cos(s8)
  953. f := ---------
  954. s3
  955. sin(s8)
  956. g := -----------
  957. s3*s10*s4
  958. OPTIMIZE
  959. f:=: cos(6.2*a+18.6*(b)^(1/5))/sqrt(sin(3.1*a+9.3*(b)^(1/5))),
  960. g:=: sin(6.2*a+18.6*(b)^(1/5))/sin(3.1*a+9.3*(b)^(1/5))^(5/3)
  961. INAME t$
  962. 0.2
  963. cos(18.6*b + 6.2*a)
  964. f := --------------------------
  965. 0.2 0.5
  966. sin(9.3*b + 3.1*a)
  967. 0.2
  968. sin(18.6*b + 6.2*a)
  969. g := ------------------------------------
  970. 0.2 1.66666666667
  971. sin(9.3*b + 3.1*a)
  972. 0.2
  973. t6 := 9.3*b + 3.1*a
  974. t9 := 2*t6
  975. t5 := sin(t6)
  976. cos(t9)
  977. f := ---------
  978. 0.5
  979. t5
  980. sin(t9)
  981. g := -----------------
  982. 1.66666666667
  983. t5
  984. \end{verbatim}
  985. \begin{flushright}
  986. $\Box$
  987. \end{flushright}}
  988. \newpage
  989. \example\label{ex:3.1.8}
  990. \index{SCOPE ! example}
  991. \index{{\tt ACINFO} switch}
  992. \index{{\tt FORT} switch}
  993. \index{{\tt PERIOD} switch}
  994. \index{{\tt EXP} switch}
  995. The effect of {\tt ON EXP} or {\tt OFF EXP} on the result of a
  996. SCOPE-application is illustrated by optimi\-zing the representation of the
  997. determinant of a symmetric (3,3) matrix {\tt m}. Besides differences in
  998. computing time we also observe that the arithmetic complexity of the
  999. optimized version of the expanded representation of the determinant is
  1000. about the same as the not optimized form of the unexpanded representation.
  1001. {\small
  1002. \begin{verbatim}
  1003. MATRIX m(3,3)$
  1004. m(1,1):=18*cos(q3)*cos(q2)*m30*p^2-sin(q3)^2*j30y+sin(q3)^2*j30z-
  1005. 9*sin(q3)^2*m30*p^2+j1oy+j30y+m10*p^2+18*m30*p^2$
  1006. m(2,1):=
  1007. m(1,2):=9*cos(q3)*cos(q2)*m30*p^2-sin(q3)^2*j30y+sin(q3)^2*j30z-
  1008. 9*sin(q3)^2*m30*p^2+j30y+9*m30*p^2$
  1009. m(3,1):=
  1010. m(1,3):=-9*sin(q3)*sin(q2)*m30*p^2$
  1011. m(2,2):=-sin(q3)^2*j30y+sin(q3)^2*j30z-9*sin(q3)^2*m30*p^2+j30y+
  1012. 9*m30*p^2$
  1013. m(3,2):=
  1014. m(2,3):=0$
  1015. m(3,3):=9*m30*p^2+j30x$
  1016. ON ACINFO,FORT$ OFF PERIOD$
  1017. OPTIMIZE detm:=:det(m) INAME s;
  1018. Number of operations in the input is:
  1019. Number of (+/-) operations : 36
  1020. Number of unary - operations : 0
  1021. Number of * operations : 148
  1022. Number of integer ^ operations : 84
  1023. Number of / operations : 0
  1024. Number of function applications : 32
  1025. S2=SIN(REAL(Q2))
  1026. S30=S2*S2
  1027. S3=SIN(REAL(Q3))
  1028. S29=S3*S3
  1029. S31=P*P
  1030. S8=S31*M30
  1031. S32=S8*S8
  1032. S4=S32*J30Y
  1033. S28=S32*S8
  1034. S9=S29*M10
  1035. S10=S30*S29*S29
  1036. S44=COS(REAL(Q3))*COS(REAL(Q2))
  1037. S11=S44*S44
  1038. S20=S31*S8
  1039. S23=S31*J30X
  1040. S22=S29*J30X
  1041. S24=S8*J1OY
  1042. S19=M10*J30Y
  1043. S43=81*S32*J30X
  1044. S35=-S43-(81*S32*J1OY)
  1045. S36=-(729*S29*S28)-(81*S29*S4)
  1046. S37=J30Z-J30Y
  1047. S39=9*S37
  1048. S40=9*J30X
  1049. S41=81*S32*J30Z
  1050. S42=81*S4
  1051. DETM=S42+S36-S35+729*S28+S37*(S22*J1OY+9*S29*S24+S23*S9)+S10*(S42-
  1052. . S41)+S20*S8*81*(M10-S9)+S20*S9*(S39-S40)+S22*S8*(S39-(9*J1OY))+
  1053. . S20*(9*S19+S40*M10)+S24*(S40+9*J30Y)+J30Y*J30X*(J1OY+9*S8)+S28*
  1054. . 729*(S10-S11)+S29*(S41+S35)+S36*S30+S23*S19-(S43*S11)
  1055. Number of operations after optimization is:
  1056. Number of (+/-) operations : 30
  1057. Number of unary - operations : 0
  1058. Number of * operations : 59
  1059. Number of integer ^ operations : 0
  1060. Number of / operations : 0
  1061. Number of function applications : 4
  1062. OFF EXP$
  1063. OPTIMIZE detm:=:det(m) INAME t;
  1064. Number of operations in the input is:
  1065. Number of (+/-) operations : 23
  1066. Number of unary - operations : 1
  1067. Number of * operations : 38
  1068. Number of integer ^ operations : 21
  1069. Number of / operations : 0
  1070. Number of function applications : 10
  1071. T1=SIN(REAL(Q3))
  1072. T9=T1*T1
  1073. T8=P*P
  1074. T5=T8*M30
  1075. T16=9*T5
  1076. T10=-T16-(9*T5*COS(REAL(Q3))*COS(REAL(Q2)))
  1077. T13=(T16+J30Y-J30Z)*T9
  1078. T15=T13-J30Y
  1079. T0=T15+T10
  1080. T14=T13-T16-J30Y
  1081. T17=T5*SIN(REAL(Q2))
  1082. DETM=81*T17*T17*T14*T9-((T16+J30X)*(T0*T0-(T14*(T15+2*T10-J1OY-(T8
  1083. . *M10)))))
  1084. Number of operations after optimization is:
  1085. Number of (+/-) operations : 13
  1086. Number of unary - operations : 0
  1087. Number of * operations : 18
  1088. Number of integer ^ operations : 0
  1089. Number of / operations : 0
  1090. Number of function applications : 4
  1091. \end{verbatim}}
  1092. We can also use this example to show that correctness of results is
  1093. easily verified. When storing
  1094. the result of a SCOPE application in a file, it is of course possible
  1095. to read the result in again. Then we apply a normal {\REDUCE} evaluation
  1096. strategy. This implies that all references to cse-names are automatically
  1097. replaced by their values. We show the ``correctness'' of SCOPE by
  1098. storing the optimized version of the expanded form of the determinant
  1099. of {\tt M}, called {\tt detm1} in file {\tt out.1} and the result of a
  1100. SCOPE-application on the unexpanded form, {\tt detm2}, in file {\tt out.2},
  1101. followed by reading in both files and by subtracting {\tt detm2}
  1102. from {\tt detm1}, resulting in the value 0.
  1103. This is of course an ad hoc correctness-proof for one specific
  1104. example. It is in fact another way of testing the code of the package.
  1105. We show it as a direct continuation of the previous determinant calculations.
  1106. \index{{\tt NAT} switch}
  1107. This example also serves to show that the {\tt OPTIMIZE} command can be
  1108. extended with the {\tt OUT} option. The keyword {\tt OUT} has to be followed
  1109. \index{{\tt OUT} option}
  1110. by a file-name. This file is properly closed and left in a readable form,
  1111. assuming printing is produced in a {\tt OFF NAT} fashion.
  1112. SCOPE's file management features are discussed in more detail in
  1113. section~\ref{SCOPE:files}.
  1114. {\small
  1115. \begin{verbatim}
  1116. OFF ACINFO,FORT,NAT$ ON EXP$
  1117. OPTIMIZE detm1:=:det(M) OUT "out.1" INAME s;
  1118. OFF EXP$
  1119. OPTIMIZE detm2:=:det(M) OUT "out.2" INAME t;
  1120. ON NAT$
  1121. IN "out.1","out.2"$
  1122. detm1-detm2;
  1123. 0
  1124. \end{verbatim}
  1125. \begin{flushright}
  1126. $\Box$
  1127. \end{flushright}}
  1128. So far we presented via some examples straightforward
  1129. algebraic mode use. The output is produced as a side-effect. However,
  1130. optimization results can easily be made operational in algebraic mode.
  1131. The parameterless function
  1132. \hspace*{1cm} {\tt ARESULTS}
  1133. \index{SCOPE function ! {\tt ARESULTS}}
  1134. delivers the result of the directly
  1135. preceding {\tt OPTIMIZE} command in the form of a list of equations,
  1136. corresponding with the sequence of assignment statements, shown either in
  1137. {\REDUCE} syntax or in the syntax of one of GENTRAN's target languages.
  1138. But, we need to operate carefully. Application of a variety of assignment
  1139. operators can easily bring in identifiers, representing earlier produced
  1140. algebraic values. They will be substituted automatically, when referenced in
  1141. rhs's in the list, produced with an {\tt ARESULTS} application.
  1142. Therefore, we implemented a
  1143. protection mechanism. Before delivering output produced by {\tt ARESULTS},
  1144. we make the system temporarily deaf for such references. The
  1145. possibly game-spoiling algebraic values are stored at a seemingly
  1146. anonymous place. All
  1147. identifiers, subjected to this special treatement, can be made visible with
  1148. the command
  1149. \hspace*{1cm} {\tt RESTORABLES};
  1150. \index{SCOPE function ! {\tt RESTORABLES}}
  1151. Their original status can be restored, either globally with the command
  1152. \hspace*{1cm} {\tt RESTOREALL}\verb+$+
  1153. \index{SCOPE function ! {\tt RESTOREALL}}
  1154. or selectively with the instruction
  1155. \hspace*{1cm} {\tt ARESTORE} $<$subsequence$>$\verb+$+
  1156. \index{SCOPE function ! {\tt ARESTORE}}
  1157. This subsequence is built with names, selected from the list
  1158. of {\tt RESTORABLES}, and separated by comma's. Information restoration
  1159. is only possible before the next {\tt OPTIMIZE} command.
  1160. \example\label{ex:3.1.9}
  1161. \index{SCOPE ! example}
  1162. The use of these commands is now illustrated.
  1163. A further explanation is given in the form of comment in the script.
  1164. {\small
  1165. \begin{verbatim}
  1166. u:=a*x+2*b$ v:=sin(u)$ w:=cos(u)$ f:=v^2*w;
  1167. 2
  1168. f := cos(a*x + 2*b)*sin(a*x + 2*b)
  1169. OFF EXP$
  1170. OPTIMIZE f:=:f,g:=:f^2+f INAME s;
  1171. s3 := x*a + 2*b
  1172. s2 := sin(s3)
  1173. f := s2*s2*cos(s3)
  1174. g := f*(f + 1)
  1175. alst:=ARESULTS;
  1176. alst := {s3=a*x + 2*b,
  1177. s2=sin(s3),
  1178. 2
  1179. f=cos(s3)*s2 ,
  1180. g=(f + 1)*f}
  1181. % ---
  1182. % SCOPE is made deaf for the standard reference mechanism for algebraic
  1183. % variables. However the rhs's in the list alst are simplified before
  1184. % being shown. It explains the differences between the layout in the
  1185. % alst items and the results, presented by the OPTIMIZE-command itself.
  1186. % ---
  1187. RESTORABLES;
  1188. {f}
  1189. f;
  1190. f
  1191. ARESTORE f$
  1192. f;
  1193. 2
  1194. cos(a*x + 2*b)*sin(a*x + 2*b)
  1195. % ---
  1196. % f is re-associated with its original value. This can lead to a modified
  1197. % presentation of some of the rhs's of alst.
  1198. % ---
  1199. alst;
  1200. {s3=a*x + 2*b,
  1201. s2=sin(s3),
  1202. 2
  1203. f=cos(s3)*s2 ,
  1204. 2 2
  1205. g=(cos(a*x + 2*b)*sin(a*x + 2*b) + 1)*cos(a*x + 2*b)*sin(a*x + 2*b) }
  1206. OPTIMIZE f:=:f,g:=:f^2+f INAME s;
  1207. s3 := x*a + 2*b
  1208. s2 := sin(s3)
  1209. f := s2*s2*cos(s3)
  1210. g := f*(f + 1)
  1211. alst2:=ARESULTS$
  1212. OPTIMIZE f:=:f,g:=:f^2+f INAME s;
  1213. g := f*(f + 1)
  1214. % ---
  1215. % The algebraic value, which was associated with f, is permanently
  1216. % lost. It ought to be restored before a new OPTIMIZE command is given.
  1217. % Therefore f:=:f produced an identity, which is redundant in terms of
  1218. % code production. More details about removal of redundant code are
  1219. % given in section 7, when discussing data dependencies and related topics.
  1220. % ---
  1221. RESTOREALL$
  1222. f;
  1223. f
  1224. \end{verbatim}
  1225. \begin{flushright}
  1226. $\Box$
  1227. \end{flushright}}
  1228. \subsection{The function {\tt ALGOPT}: Straightforward use}\label{SCOPE:algo}
  1229. \index{SCOPE function ! {\tt ALGOPT}}
  1230. \index{SCOPE function ! {\tt RESTOREALL}}
  1231. \index{SCOPE function ! {\tt RESTORABLES}}
  1232. \index{SCOPE function ! {\tt ARESULTS}}
  1233. \index{SCOPE function ! {\tt ARESTORE}}
  1234. The function {\tt ALGOPT} accepts up to three arguments. It can be used in
  1235. stead of the {\tt OPTIMIZE} command. It returns the optimization result,
  1236. like {\tt ARESULTS}, in the form of a list of equations.
  1237. Since the {\tt ARESULTS} mechanism
  1238. is applied as well, the pre-{\tt ALGOPT}-application situation can be restored
  1239. with {\tt RESTOREALL} or partly and selective with {\tt ARESTORE}, using
  1240. information, providable by an application of the function {\tt RESTORABLES}.
  1241. The first argument of {\tt ALGOPT}, like the other two optional, is the
  1242. equivalent of the alglist or alglist\_production in the earlier introduced
  1243. syntax of a SCOPE\_application.
  1244. The second argument can be used to inform SCOPE
  1245. that input from file(s) have to be processed. We survey SCOPE's file
  1246. management features in section~\ref{SCOPE:files}. So we omit a further
  1247. discussion now. The last argument correspondents with the cse\_prefix
  1248. of the {\tt INAME } option of the {\tt OPTIMIZE} command. The extension
  1249. of the SCOPE\_application syntax, needed to include possible {\tt ALGOPT}
  1250. activities, is:
  1251. \begin{tabular}{lcl}
  1252. $<$SCOPE\_application$>$ & $::=$ & $\cdots~\mid~$\\
  1253. & & {\tt ALGOPT}($<$a\_object\_list$>$[,$<$string\_id\_list$>$][,$<$cse\_prefix$>$]) $\mid$\\
  1254. & & {\tt ALGOPT}([$<$a\_object\_list$>$,]$<$string\_id\_list$>$[,$<$cse\_prefix$>$])\\
  1255. \end{tabular}
  1256. \begin{tabular}{lcl}
  1257. $<$a\_object\_list$>$ & $::=$ & $<$a\_object$>~\mid$ \{$<$a\_object$>$[,$<$a\_object\_seq$>$]\}\\
  1258. $<$a\_object\_seq$>$ & $::=$ & $<$a\_object$>$[,$<$a\_object\_seq$>$]\\
  1259. $<$a\_object$>$ & $::=$ & $<$id$>~\mid~<$alglist$>~\mid~<$alglist\_production$>~\mid$
  1260. \{$<$a\_object$>$\}
  1261. \end{tabular}
  1262. We require at least one actual parameter, here the a\_object\_list. Its
  1263. syntactical structure allows to apply a GENTRAN-like repertoire in an
  1264. algebraic mode setting. The a\_object's can
  1265. either be an alglist identifier, an alglist producing function application,
  1266. or an alglist itself. An alglist identifier can be
  1267. either a scalar or a matrix or array entry. The alglist producing
  1268. functions will be discussed in section~\ref{SCOPE:soph}. An alglist has the
  1269. structure of an algebraic mode list; its elements are either a\_object's
  1270. or equations of the form lhs = rhs. Such equations correspondent
  1271. with the "take literal" GENTRAN operator {\tt :=} facility in the setting
  1272. of an {\tt OPTIMIZE} command (see also section~\ref{SCOPE:soph} for a further
  1273. discussion). The alternatives, i.e. uses of {\tt ::=}, {\tt :=:} or {\tt ::=:},
  1274. are also covered by the a\_object syntax.
  1275. The examples, given in this subsection, show that simplification of an algebraic
  1276. list of equations leads to right hand side simplification, corresponding with
  1277. the effect of the colon-added-to-the-right-extension of the assignment operator.
  1278. However, as illustrated by example~\ref{ex:3.2.7}, some care has to be taken
  1279. when operating in {\tt OFF EXP} mode.
  1280. Turning {\tt ON} the switch {\tt EVALLHSEXP}, can lead to lhs evaluations,
  1281. corresponding with the extra-colon-to-the-left strategy. But we have to
  1282. be aware of the instanteneous evaluation mechanism for matrix and
  1283. array entries, when referenced.
  1284. We present some examples of possible use of the {\tt ALGOPT} function.
  1285. In example~\ref{ex:3.2.4} a straightforward application is given.
  1286. In example~\ref{ex:3.2.5} follows an ilustration of a possible strategy
  1287. concerning optimizing sets of array- and/or matrix-entries. Then,
  1288. in example~\ref{ex:3.2.6}, possible SCOPE assistance in problem analysis is
  1289. shown. Finally in example~\ref{ex:3.2.7}
  1290. some differences in simplification and their influence on optimization are
  1291. discussed. We also introduce and explain the role of the SCOPE
  1292. switch {\tt SIDREL}.
  1293. \index{{\tt SIDREL} switch}
  1294. \index{{\tt EVALLHSEQP} switch}
  1295. \example\label{ex:3.2.4}
  1296. \index{SCOPE ! example}
  1297. A number of possible alglist elements is presented in the script.
  1298. The first three elements of the actual parameter define values, obtained
  1299. via the usual algebraic mode list evaluation mechanism. The last two will be
  1300. processed literally. So, the actual parameter for {\tt ALGOPT} is composed
  1301. of the scalar {\tt alist}, a list consisting of the matrix element {\tt m(1,1)},
  1302. the array element {\tt ar(2,2)}, nested even deeper, and two equations. Before
  1303. an {\tt ALGOPT} argument is optimized it is flattened by the SCOPE parser
  1304. into a list of equations, the algebraic mode equivalent of the sequence of
  1305. assignments in the {\tt OPTIMIZE} context. Evaluation of an {\tt ALGOPT}
  1306. application leads to an algebraic mode list of equations, with optimized rhs's.
  1307. The cse\_prefix was seemingly superfluous, because all its references
  1308. disappeared by back-substitution before output-processing started. See also
  1309. example~\ref{ex:3.2.7}.
  1310. \index{{\tt ALGOPT} application}
  1311. Since an {\tt ALGOPT} application always results in an algebraic mode list,
  1312. one can not use this feature for production of code in one of GENTRAN's target
  1313. languages. To facilitate the translation of the result of an {\tt ALGOPT}
  1314. application, we extended the syntax of the {\tt OPTIMIZE} input repertoire,
  1315. such that alglst\_production's are processable by {\tt OPTIMIZE}
  1316. as well, as illustrated in the script of this example and
  1317. in example~\ref{ex:3.2.7}
  1318. {\small
  1319. \begin{verbatim}
  1320. OFF EXP$
  1321. ARRAY ar(2,2)$ MATRIX m(2,2)$
  1322. alst:={p1=a+b,p2=(a+b)^2}$
  1323. m(1,1):={q1=c+d,q2=(c+d)^2}$
  1324. ar(2,2):={r1=(a+b)*(c+d),r2=(a+b)^2*(c+d)^2}$
  1325. optlst:=ALGOPT({alst,{m(1,1)},{{ar(2,2)}},
  1326. t1=(a+b)*(c+d)^2,t2=(c+d)*(a+b)^2},s);
  1327. optlst := {p1=a + b,
  1328. 2
  1329. p2=p1 ,
  1330. q1=c + d,
  1331. 2
  1332. q2=q1 ,
  1333. r1=p1*q1,
  1334. 2
  1335. r2=r1 ,
  1336. t1=q1*r1,
  1337. t2=p1*r1}
  1338. OPTIMIZE optlst$
  1339. p1 := a + b
  1340. p2 := p1*p1
  1341. q1 := c + d
  1342. q2 := q1*q1
  1343. r1 := q1*p1
  1344. r2 := r1*r1
  1345. t1 := r1*q1
  1346. t2 := r1*p1
  1347. \end{verbatim}
  1348. \begin{flushright}
  1349. $\Box$
  1350. \end{flushright}}
  1351. \example\label{ex:3.2.5}
  1352. \index{SCOPE ! example}
  1353. In example~\ref{ex:3.1.8} we introduced a symmetric (3,3)-matrix {\tt m}. We
  1354. present an alternative computation of its determinant. We start with building
  1355. a list of equations, with rhs's, being the non-zero entries of {\tt m},
  1356. relevant for the computation. The lhs's are produced with
  1357. the {\tt mkid} function. These
  1358. newly generated names are assigned to the matrix-entries as well. Finally
  1359. we add the definition of the computation of the determinant of {\tt m},
  1360. in terms of the redefined entries, to this list.
  1361. For the construction of the value of {\tt mlst} we applied both the lhs and
  1362. rhs evaluation mechanism. Observe also that, due to the redefinition process,
  1363. the original values of the entries of the matrix {\tt m} are lost.
  1364. We can optimize {\tt mlst}, using
  1365. either an {\tt OPTIMIZE} command or an {\tt ALGOPT} application. The reduction
  1366. in arithmetic is not yet impressive here, certainly comparing it with the
  1367. non-expanded, optimized form in the earlier example~\ref{ex:3.1.8}.
  1368. (See also example~\ref{ex:3.2.7} for additional comment).
  1369. However, working with larger and non-symmetric matrices will certainly
  1370. improve results, when applying a comparable strategy.
  1371. Observe that the syntax of permissible {\tt ALGOPT} a\_object's does not
  1372. allow to use matrix or array names to compactly identify the complete set
  1373. of their entries. The script in this example shows that such a facility is
  1374. easily made. This possibility exists already for matrices in a GENTRAN
  1375. setting (see also example~\ref{ex:8.2} in section~\ref{SCOPE:gopt}).
  1376. \index{{\tt EVALLHSEQP} switch}
  1377. {\small
  1378. \begin{verbatim}
  1379. % ---
  1380. % We assume the matrix m to be known already.
  1381. % ---
  1382. mlst:={}$ l:=-1$
  1383. OFF EXP$ ON EVALLHSEQP$
  1384. FOR j:=1:3 DO FOR k:=j:3 DO
  1385. IF m(j,k) neq 0 THEN
  1386. << s:=mkid(t,l:=l+1);
  1387. mlst:=append(mlst,{s=m(j,k)});
  1388. m(j,k):=m(k,j):=s
  1389. >>$
  1390. OFF EVALLHSEQP$
  1391. m;
  1392. [t0 t1 t2]
  1393. [ ]
  1394. [t1 t3 0 ]
  1395. [ ]
  1396. [t2 0 t4]
  1397. mlst:=append(mlst,{detm=det(m)});
  1398. 2 2
  1399. mlst := {t0= - (j30y - j30z + 9*m30*p )*sin(q3)
  1400. 2 2
  1401. + 18*cos(q2)*cos(q3)*m30*p + j10y + j30y + m10*p
  1402. 2
  1403. + 18*m30*p ,
  1404. 2 2
  1405. t1= - (j30y - j30z + 9*m30*p )*sin(q3)
  1406. 2 2
  1407. + 9*cos(q2)*cos(q3)*m30*p + j30y + 9*m30*p ,
  1408. 2
  1409. t2= - 9*sin(q2)*sin(q3)*m30*p ,
  1410. 2 2 2
  1411. t3= - (j30y - j30z + 9*m30*p )*sin(q3) + j30y + 9*m30*p ,
  1412. 2
  1413. t4=j30x + 9*m30*p ,
  1414. 2 2
  1415. detm=(t0*t3 - t1 )*t4 - t2 *t3}
  1416. ON ACINFO,FORT$ OFF PERIOD$
  1417. \end{verbatim}}
  1418. \index{{\tt ACINFO} switch}
  1419. \index{{\tt FORT} switch}
  1420. \index{{\tt PERIOD} switch}
  1421. {\small
  1422. \begin{verbatim}
  1423. OPTIMIZE mlst INAME s;
  1424. Number of operations in the input is:
  1425. Number of (+/-) operations : 19
  1426. Number of unary - operations : 1
  1427. Number of * operations : 33
  1428. Number of integer ^ operations : 16
  1429. Number of / operations : 0
  1430. Number of function applications : 9
  1431. S0=SIN(REAL(Q3))
  1432. S7=P*P
  1433. S5=S7*M30
  1434. S4=S5*COS(REAL(Q3))*COS(REAL(Q2))
  1435. S13=9*S5
  1436. S11=(S13+J30Y-J30Z)*S0*S0
  1437. T0=J30Y+J10Y+18*(S4+S5)+S7*M10-S11
  1438. T3=S13+J30Y-S11
  1439. T1=T3+9*S4
  1440. T2=-(S13*SIN(REAL(Q2))*S0)
  1441. T4=S13+J30X
  1442. DETM=T4*(T3*T0-(T1*T1))-(T2*T2*T3)
  1443. Number of operations after optimization is:
  1444. Number of (+/-) operations : 13
  1445. Number of unary - operations : 1
  1446. Number of * operations : 17
  1447. Number of integer ^ operations : 0
  1448. Number of / operations : 0
  1449. Number of function applications : 4
  1450. \end{verbatim}
  1451. \begin{flushright}
  1452. $\Box$
  1453. \end{flushright}}
  1454. \example\label{ex:3.2.6}
  1455. \index{SCOPE ! example}
  1456. We now illustrate that information, produced by SCOPE, can possibly also play
  1457. a role in computations in algebraic mode. Let ${\rm A.\vec{x}~=~\vec{b}}$
  1458. be given by
  1459. \[ \left[ \begin{array}{rrrrrr}
  1460. -1 & 2 & -2 & 1 & 3 & 2 \\
  1461. -2 & 4 & -4 & 2 & -2 & 3 \\
  1462. 1 & 1 & 1 & 1 & 2 & 4 \\
  1463. 2 & -2 & -1 & 1 & -1 & -2 \\
  1464. 3 & 1 & -4 & 1 & 1 & 2 \\
  1465. -1 & -5 & 1 & 1 & 3 & 6
  1466. \end{array}\right]~\cdot~\left[ \begin{array}{c}
  1467. x1 \\ x2 \\ x3 \\ x4 \\ x5 \\ x6
  1468. \end{array} \right]~=~
  1469. \left[ \begin{array}{r}
  1470. 5 \\ 1 \\ 10 \\ -3 \\ 4 \\ 5
  1471. \end{array} \right] \cdot \]
  1472. This artificial system is constructed for illustrative purposes.
  1473. Its solution is simply ${\rm x_i~=~1}$, ${\rm i~=~1,..,6}$.
  1474. But straightforward inspection shows that
  1475. \[ {\rm A}~=~\left[ \begin{array}{cc}
  1476. {\rm A}_1 & {\rm A}_2 \\
  1477. {\rm A}_3 & {\rm A}_4 \end{array}\right]~
  1478. {\rm where}~{\rm A}_1~=~\left[ \begin{array}{cccc}
  1479. -1 & 2 & -2 & 1\\
  1480. -2 & 4 & -4 & 2 \end{array}\right]~
  1481. {\rm and}~ {\rm A}_4~=~\left[ \begin{array}{rr}
  1482. 2 & 4 \\
  1483. -1 & -2 \\
  1484. 1 & 2 \\
  1485. 3 & 6 \end{array} \right] \cdot \]
  1486. We can use {\tt ALGOPT} to "discover" and thus to employ this information.
  1487. The system is introduced in the form of assignment statements
  1488. $e_i~=~(\sum_{j=1}^{6}~a_{ij}~\cdot~x_{j})~-~b_{i},~i~=~1, \cdots ,6$.
  1489. We use {\tt alst}, identifying the set of equations (see command 9),
  1490. as actual parameter for {\tt ALGOPT}, leading to an algebraic list,
  1491. identified by {\tt reslst} (see command 10). We recognize {\tt g2 = g6 + x5}
  1492. {\tt (= x5 + 2x6)} and {\tt g1 = g3 + g5 + -2x3} {\tt (= -x1 + 2x2 - 2x3 + x4)}.
  1493. Through command 12 we require
  1494. cse's to have an arithmetic complexity of a least 4. We then find {\tt g1}
  1495. directly, now called {\tt g8}, because we continue applying the
  1496. function {\tt gensym}; the cse\_prefix was left out as actual parameter.
  1497. The {\tt solve} function is applied (command 14) to obtain {\tt rootset1}, a list
  1498. of values for {\tt x5} and {\tt x6}, expressed in the parameter {\tt g8}.
  1499. After assigning {\tt g8} its value in algebraic mode and
  1500. resetting the algebraic values of {\tt ei}, $i~=~ 1, \cdots ,6$
  1501. with {\tt RESTOREALL} instructions (the commands 11 and 16),
  1502. we can obtain the solution
  1503. of the subsets, denoted by {\tt rootset1} and {\tt rootset2}.
  1504. \index{SCOPE function ! {\tt RESTOREALL}}
  1505. {\small
  1506. \begin{verbatim}
  1507. 1: LOAD_PACKAGE nscope$
  1508. 2: e1:=2*x6+3*x5+x4-2*x3+2*x2-x1-5$
  1509. 3: e2:=3*x6-2*x5+2*x4-4*x3+4*x2-2*x1-1$
  1510. 4: e3:=2*x5+4*x6+x1+x2+x3+x4-10$
  1511. 5: e4:=-x5-2*x6+2*x1-2*x2-x3+x4+3$
  1512. 6: e5:=x5+2*x6+3*x1+x2-4*x3+x4-4$
  1513. 7: e6:=3*x5+6*x6-x1-5*x2+x3+x4-5$
  1514. 8: solve({e1,e2,e3,e4,e5,e6},{x1,x2,x3,x4,x5,x6});
  1515. {{x1=1,x2=1,x3=1,x4=1,x5=1,x6=1}}
  1516. 9: alst:={e1=e1,e2=e2,e3=e3,e4=e4,e5=e5,e6=e6}$
  1517. 10: reslst:=ALGOPT alst;
  1518. reslst := {g3= - x1 + x4,
  1519. g5=2*x2,
  1520. g1=g3 + g5 - 2*x3,
  1521. g6=2*x6,
  1522. e1=g1 + g6 + 3*x5 - 5,
  1523. e2=2*g1 - 2*x5 + 3*x6 - 1,
  1524. g2=g6 + x5,
  1525. g4=x2 + x4,
  1526. e3=2*g2 + g4 + x1 + x3 - 10,
  1527. e4= - g2 - g5 + 2*x1 - x3 + x4 + 3,
  1528. e5=g2 + g4 + 3*x1 - 4*x3 - 4,
  1529. e6=3*g2 + g3 - 5*x2 + x3 - 5}
  1530. 11: RESTOREALL$
  1531. 12: SETLENGTH 4$
  1532. 13: reslst:=ALGOPT alst;
  1533. reslst := {g8= - x1 + 2*x2 - 2*x3 + x4,
  1534. e1=g8 + 3*x5 + 2*x6 - 5,
  1535. e2=2*g8 - 2*x5 + 3*x6 - 1,
  1536. e3=x1 + x2 + x3 + x4 + 2*x5 + 4*x6 - 10,
  1537. e4=2*x1 - 2*x2 - x3 + x4 - x5 - 2*x6 + 3,
  1538. e5=3*x1 + x2 - 4*x3 + x4 + x5 + 2*x6 - 4,
  1539. e6= - x1 - 5*x2 + x3 + x4 + 3*x5 + 6*x6 - 5}
  1540. 14: rootset1:=solve({part(reslst,2,2),part(reslst,3,2)},{x5,x6});
  1541. g8 + 13 - 8*g8 + 13
  1542. rootset1 := {{x5=---------,x6=--------------}}
  1543. 13 13
  1544. 15: g8:=part(reslst,1,2);
  1545. g8 := - x1 + 2*x2 - 2*x3 + x4
  1546. 16: RESTOREALL$
  1547. 17: rootset2:=solve(sub(rootset1,{e3,e4,e5,e6}),{x1,x2,x3,x4});
  1548. rootset2 := {{x1=1,x2=1,x3=1,x4=1}}
  1549. 18: rootset1:=sub(rootset2,rootset1);
  1550. rootset1 := {{x5=1,x6=1}}
  1551. \end{verbatim}
  1552. \begin{flushright}
  1553. $\Box$
  1554. \end{flushright}}
  1555. \index{SCOPE function ! {\tt SETLENGTH}}
  1556. \index{{\tt EXP} switch}
  1557. \example\label{ex:3.2.7}
  1558. \index{SCOPE ! example}
  1559. The script in example~\ref{ex:3.2.5} suggests that we can easily copy GENTRAN's
  1560. assignment features by some listprocessing in algebraic mode. However, we
  1561. have to operate carefully. In the script of the present example we introduce an
  1562. expression denoted by {\tt f}. Production of a number of its partial (higher)
  1563. derivatives is a straightforward mechanism to assist in constructing a set
  1564. of assignment statements, containing lots of cse's. Inspection of the values,
  1565. in {\tt OFF EXP} mode assigned to {\tt faa}, {\tt tst1} and {\tt tst2},
  1566. respectively, learns that the value of {\tt mlst} in example~\ref{ex:3.2.5}
  1567. may be improvable.
  1568. {\small
  1569. \begin{verbatim}
  1570. u:=a*x+2*b$ v:=sin(u)$ w:=cos(u)$ f:=v^2*w$
  1571. OFF EXP$
  1572. faa:=df(f,a,2);
  1573. 2 2 2
  1574. faa := (2*cos(a*x + 2*b) - 7*sin(a*x + 2*b) )*cos(a*x + 2*b)*x
  1575. tst1:={faa=df(f,a,2)};
  1576. 3 2 2 2
  1577. tst1 := {faa=2*cos(a*x + 2*b) *x - 7*cos(a*x + 2*b)*sin(a*x + 2*b) *x }
  1578. tst2:={faa=(faa:=df(f,a,2))};
  1579. 2 2 2
  1580. tst2 := {faa=(2*cos(a*x + 2*b) - 7*sin(a*x + 2*b) )*cos(a*x + 2*b)*x }
  1581. \end{verbatim}}
  1582. We produce an optimized version of the value of {\tt tlst}, using {\tt ALGOPT}.
  1583. Switching {\tt ON INPUTC} and {\tt PRIMAT} results in an input echo, indeed
  1584. showing expanded rhs's and a vizualized picture of the \verb+Sumscheme+ of
  1585. $D_{\lambda}$. We skipped the ${\rm D_0}$-picture and the rest of the
  1586. $D_{\lambda}$-picture from the script. The value of {\tt reslst} shows the
  1587. patterns {\tt s14 = -7.f.x + 2.s9.x} and {\tt fbb = -28.f + 8.s9}.
  1588. The presented \verb+Sumscheme+ of $D_{\lambda}$ suggests that {\tt fbb} and
  1589. {\tt s13} (see the Fa(the)r entries) seemingly have
  1590. nothing in common. But {\tt s14} stands for {\tt 2.s6 - 7.s7}, because,
  1591. column 8 has to be identified with {\tt s7}, etc. Since both {\tt S6} and
  1592. {\tt S7} occur only once in $D_{\lambda}$, their value replaces them in the
  1593. output.
  1594. It is an illustration of the heuristic character of the optimization process.
  1595. Optimization of the value of {\tt reslst} shows that the repeated pattern
  1596. is now recognized.
  1597. \index{{\tt INPUT} switch}
  1598. \index{{\tt PRIMAT} switch}
  1599. {\small
  1600. \begin{verbatim}
  1601. tlst:={f=f,fa=df(f,a),fb=df(f,b),faa=df(f,a,2),
  1602. fab=df(f,a,b),fba=df(f,b,a),fbb=df(f,b,2)}$
  1603. ON INPUTC,PRIMAT$
  1604. reslst:=ALGOPT(tlst,s);
  1605. 2
  1606. f := cos(a*x + 2*b)*sin(a*x + 2*b)
  1607. 2 3
  1608. fa := 2*cos(a*x + 2*b) *sin(a*x + 2*b)*x - sin(a*x + 2*b) *x
  1609. 2 3
  1610. fb := 4*cos(a*x + 2*b) *sin(a*x + 2*b) - 2*sin(a*x + 2*b)
  1611. 3 2 2 2
  1612. faa := 2*cos(a*x + 2*b) *x - 7*cos(a*x + 2*b)*sin(a*x + 2*b) *x
  1613. 3 2
  1614. fab := 4*cos(a*x + 2*b) *x - 14*cos(a*x + 2*b)*sin(a*x + 2*b) *x
  1615. 3 2
  1616. fba := 4*cos(a*x + 2*b) *x - 14*cos(a*x + 2*b)*sin(a*x + 2*b) *x
  1617. 3 2
  1618. fbb := 8*cos(a*x + 2*b) - 28*cos(a*x + 2*b)*sin(a*x + 2*b)
  1619. Sumscheme :
  1620. | 3 4 5 6 7 8 9 10 11 12 32| EC|Far
  1621. ---------------------------------------------
  1622. 3| 1 2| 1| s3
  1623. 20| -28 8 | 1| fbb
  1624. 37| -7 2 | 1| s14
  1625. 38| -1 2 | 1| s15
  1626. ---------------------------------------------
  1627. 3 : s3
  1628. 4 : s15
  1629. 5 : s14
  1630. 6 : s4
  1631. 7 : s9
  1632. 8 : s7
  1633. 9 : s6
  1634. 10 : s10
  1635. 11 : s5
  1636. 12 : s8
  1637. 32 : b
  1638. reslst := {s3=a*x + 2*b,
  1639. s0=cos(s3),
  1640. 3
  1641. s9=s0 ,
  1642. s2=sin(s3),
  1643. s12=s0*s2,
  1644. f=s12*s2,
  1645. 3
  1646. s15=2*s0*s12 - s2 ,
  1647. fa=s15*x,
  1648. fb=2*s15,
  1649. s14= - 7*f*x + 2*s9*x,
  1650. faa=s14*x,
  1651. fab=2*s14,
  1652. fba=fab,
  1653. fbb= - 28*f + 8*s9}
  1654. OFF INPUTC,PRIMAT$
  1655. OPTIMIZE reslst$
  1656. s3 := 2*b + x*a
  1657. s0 := cos(s3)
  1658. s9 := s0*s0*s0
  1659. s2 := sin(s3)
  1660. s12 := s2*s0
  1661. f := s12*s2
  1662. s15 := 2*s12*s0 - s2*s2*s2
  1663. fa := s15*x
  1664. fb := 2*s15
  1665. g3 := 2*s9 - 7*f
  1666. s14 := g3*x
  1667. faa := s14*x
  1668. fab := 2*s14
  1669. fba := fab
  1670. fbb := 4*g3
  1671. \end{verbatim}}
  1672. Repeating this process, this time with an {\tt OPTIMIZE} command to begin with,
  1673. learns that the {\tt OFF EXP} mode is now effective. But this time, and for
  1674. similar
  1675. reasons, the assignments {\tt fbb = 4.s9.s0} and {\tt s12 = s9.s0.x} still
  1676. have a subexpression in common. Now the \verb+Productscheme+ of $D_{\lambda}$
  1677. helps understanding the phenomenon; again we skipped for shortness the rest of
  1678. the information, provided by the {\tt ON PRIMAT} status of SCOPE.
  1679. Internally {\tt s12} denotes the product {\tt s4.s9},
  1680. where {\tt s4 = x.s0}. The cse {\tt s4} disappeared from the output.
  1681. An {\tt ALGOPT} application leads to the "discovery" of the
  1682. cse {\tt g10 = s0.s9}.
  1683. {\small
  1684. \begin{verbatim}
  1685. f:=v^2*w;
  1686. 2
  1687. f := cos(a*x + 2*b)*sin(a*x + 2*b)
  1688. ON INPUTC,PRIMAT$
  1689. OPTIMIZE f:=:f,fa:=:df(f,a),fb:=:df(f,b),faa:=:df(f,a,2),
  1690. fab:=:df(f,a,b),fba:=:df(f,b,a),fbb:=:df(f,b,2) INAME s$
  1691. 2
  1692. f := cos(a*x + 2*b)*sin(a*x + 2*b)
  1693. 2 2
  1694. fa := (2*cos(a*x + 2*b) - sin(a*x + 2*b) )*sin(a*x + 2*b)*x
  1695. 2 2
  1696. fb := 2*(2*cos(a*x + 2*b) - sin(a*x + 2*b) )*sin(a*x + 2*b)
  1697. 2 2 2
  1698. faa := (2*cos(a*x + 2*b) - 7*sin(a*x + 2*b) )*cos(a*x + 2*b)*x
  1699. 2 2
  1700. fab := 2*(2*cos(a*x + 2*b) - 7*sin(a*x + 2*b) )*cos(a*x + 2*b)*x
  1701. 2 2
  1702. fba := 2*(2*cos(a*x + 2*b) - 7*sin(a*x + 2*b) )*cos(a*x + 2*b)*x
  1703. 2 2
  1704. fbb := 4*(2*cos(a*x + 2*b) - 7*sin(a*x + 2*b) )*cos(a*x + 2*b)
  1705. s3 := x*a + 2*b
  1706. s0 := cos(s3)
  1707. s2 := sin(s3)
  1708. s6 := s2*s2
  1709. f := s6*s0
  1710. s14 := 2*s0*s0
  1711. s13 := (s14 - s6)*s2
  1712. fa := s13*x
  1713. fb := 2*s13
  1714. s9 := s14 - 7*s6
  1715. s12 := s9*s0*x
  1716. faa := s12*x
  1717. fab := 2*s12
  1718. fba := fab
  1719. fbb := 4*s9*s0
  1720. Productscheme :
  1721. | 0 2 3 4 5 12 14 18 19 20 21 22 23| EC|Far
  1722. ---------------------------------------------------
  1723. 0| 1 1 | 1| f
  1724. 5| 1 1 | 1| fa
  1725. 9| 1 | 2| fb
  1726. 13| 1 1 | 1| faa
  1727. 17| 1 | 1| fab
  1728. 21| 1 | 1| fba
  1729. 25| 1 1 | 4| fbb
  1730. 29| 1 1 | 1| s4
  1731. 30| 1 1| 1| s5
  1732. 31| 2 | 1| s6
  1733. 33| 2 | 1| s8
  1734. 37| 1 1 | 1| s12
  1735. 38| 1 1 | 1| s13
  1736. 39| 1 | 2| s14
  1737. 40| 1 | 2| s15
  1738. ---------------------------------------------------
  1739. 0 : s15
  1740. 2 : s13
  1741. 3 : s12
  1742. 4 : s9
  1743. 5 : s10
  1744. 12 : s8
  1745. 14 : s6
  1746. 18 : s5
  1747. 19 : s4
  1748. 20 : s2=sin(s3)
  1749. 21 : s0=cos(s3)
  1750. 22 : x
  1751. 23 : a
  1752. ALGOPT ARESULTS;
  1753. {s3=a*x + 2*b,
  1754. s0=cos(s3),
  1755. s2=sin(s3),
  1756. 2
  1757. s6=s2 ,
  1758. f=s0*s6,
  1759. 2
  1760. s14=2*s0 ,
  1761. s13=(s14 - s6)*s2,
  1762. fa=s13*x,
  1763. fb=2*s13,
  1764. s9=s14 - 7*s6,
  1765. g10=s0*s9,
  1766. s12=g10*x,
  1767. faa=s12*x,
  1768. fab=2*s12,
  1769. fba=fab,
  1770. fbb=4*g10}
  1771. \end{verbatim}}
  1772. This script is shown for different reasons. It illustrates the heuristic
  1773. character of the optimization process. We optimize, but do not guarantee
  1774. the optimal solution. It also shows how easily repeated SCOPE applications
  1775. can be accomplished. Hence commands like "{\tt ALGOPT} {\tt ARESULTS};",
  1776. "{\tt ALGOPT} {\tt ALGOPT} $\cdots$ ;"
  1777. or "{\tt OPTIMIZE} {\tt ALGOPT} $\cdots$ ;" are all possible.
  1778. However, it is sometimes better to avoid such a combination when a
  1779. {\tt RESTOREALL} instruction has to follow the first application.
  1780. A more detailed discussion about these possibilities is given in
  1781. section~\ref{SCOPE:soph}, and especially in section~\ref{SSF:Sl}.
  1782. An additional reason was, to stipulate that SCOPE's actual parameters
  1783. have to be built carefully.
  1784. \index{{\tt SIDREL} switch}
  1785. \index{SCOPE function ! {\tt SETLENGTH}}
  1786. This example is also used to illustrate the role, which the switch {\tt SIDREL}
  1787. can possibly play. When turned it {\tt ON} the finishing touch F (see
  1788. subsection~\ref{SCOPE:bird}) is omitted and all non-additive cse's
  1789. are substituted back, thus producing a possibly still rewritten input set,
  1790. which consists of toplevel input and additive cse's only. A simple
  1791. straightforward backsubstitution mechanism is applied on the optimization
  1792. result before it is presented to the user. Seemingly, it can lead to surprises
  1793. as shown below by the differences between the presentations of {\tt s15},
  1794. {\tt s14} and {\tt fbb} when again optimizing the contents of {\tt tlst}.
  1795. This effect disappeares when using {\tt SETLENGTH}.
  1796. The switch {\tt SIDREL} was introduced in SCOPE quite long ago. By that
  1797. time Hearn was wondering ~\cite{Hearn:85,Hearn:86} if (parts of) SCOPE output,
  1798. presented in algebraic mode, can be used as input for a Gr\"{o}bner-base
  1799. algorithm application, thus attempting to assist in expression restructuring
  1800. leading to improved expression representations.
  1801. {\small
  1802. \begin{verbatim}
  1803. ON SIDREL$
  1804. ALGOPT(tlst,s);
  1805. {s3=a*x + 2*b,
  1806. 2
  1807. f=cos(s3)*sin(s3) ,
  1808. 2 3
  1809. s15=2*cos(s3) *sin(s3) - sin(s3) ,
  1810. fa=s15*x,
  1811. fb=2*s15,
  1812. 2 3
  1813. s14= - 7*cos(a*x + 2*b)*sin(a*x + 2*b) *x + 2*cos(s3) *x,
  1814. faa=s14*x,
  1815. fab=2*s14,
  1816. fba=2*s14,
  1817. 2 3
  1818. fbb= - 28*cos(a*x + 2*b)*sin(a*x + 2*b) + 8*cos(s3) }
  1819. SETLENGTH 4$
  1820. ALGOPT(tlst,s);
  1821. 2
  1822. {f=cos(a*x + 2*b)*sin(a*x + 2*b) ,
  1823. 2 3
  1824. s15=2*cos(a*x + 2*b) *sin(a*x + 2*b) - sin(a*x + 2*b) ,
  1825. fa=s15*x,
  1826. fb=2*s15,
  1827. 3 2
  1828. s14=2*cos(a*x + 2*b) *x - 7*cos(a*x + 2*b)*sin(a*x + 2*b) *x,
  1829. faa=s14*x,
  1830. fab=2*s14,
  1831. fba=2*s14,
  1832. 3 2
  1833. fbb=8*cos(a*x + 2*b) - 28*cos(a*x + 2*b)*sin(a*x + 2*b) }
  1834. \end{verbatim}}
  1835. {\small
  1836. \begin{flushright}
  1837. $\Box$
  1838. \end{flushright}}
  1839. \newpage
  1840. \section{Special SCOPE 1.5 Features}\label{SCOPE:soph}
  1841. Part of the input syntax for the function {\tt ALGOPT} was left undiscussed
  1842. in section~\ref{SCOPE:algo}. It was the permissable form for (parts of)
  1843. the actual parameter, defining function applications, producing
  1844. an alglist. The alglist is an algebraic mode list, consisting
  1845. either of equations of the form lhs = rhs or of constructs
  1846. evaluating into an alglist or referencing an alglist.
  1847. In section~\ref{SSF:Sl} is explained which type of user defined
  1848. functions lead to permissable function applications as (part of an) actual
  1849. parameter for an {\tt OPTIMIZE} command or an {\tt ALGOPT} application.
  1850. Tools are provided for building a SCOPE library.
  1851. Already available facilities, designed along these lines, cover
  1852. {\bf structure recognition}, presented in section~\ref{SSF:sr} and
  1853. {\bf Horner-rule} based expression rewriting, surveyed in section~\ref{SSF:Hr}.
  1854. \subsection{Towards a SCOPE 1.5 Library}\label{SSF:Sl}
  1855. \index{REDUCE function ! {\tt ENDSTAT}-type}
  1856. \index{REDUCE function ! {\tt NORMAL}-type}
  1857. \index{REDUCE function ! {\tt PSOPFN}-type}
  1858. Design and implementation of an algebraic or symbolic procedure, returning
  1859. a list of equations in algebraic mode, is straightforward as long as the
  1860. number of formal parameters is exactly known. Let us call such procedures
  1861. functions of {\tt NORMAL}-type. When formal parameters are not required,
  1862. the so-called {\tt ENDSTAT}-variant can be used.
  1863. One simply associates an indicator {\tt stat}, with
  1864. value {\tt endstat}, with the function name {\tt f-name},
  1865. using \verb+lisp(put('f-name,'stat,'endstat))$+ as instruction.
  1866. Such a function will be said to be of {\tt ENDSTAT}-type.
  1867. The so-called {\tt PSOPFN}-type function is similar to the {\tt FEXPR}-type
  1868. function in symbolic mode. It may have an arbitrary number of unevaluated
  1869. parameters.
  1870. Special attention is made possible by modifying the function {\tt reval1}, used
  1871. in both {\tt reval} and {\tt aeval}. The relevant section of the evaluator is:
  1872. {\small
  1873. \begin{verbatim}
  1874. symbolic procedure aeval u; reval1(u,nil);
  1875. symbolic procedure reval u; reval1(u,t);
  1876. symbolic procedure reval1(u,v);
  1877. .......................
  1878. else if x:=get(car u,'psopfn)
  1879. then << u:=apply(x,list cdr u);
  1880. if x:=get(x,'cleanupfn) then u:=apply(x,list(u,v));
  1881. return u
  1882. >>
  1883. .......................
  1884. \end{verbatim}}
  1885. The actual parameter {\tt u} of {\tt reval1} is a function application in
  1886. prefixform: ({\tt function-name} {\tt arg1} ... {\tt argn}).
  1887. The {\tt function-name} is replaced by the value of the indicator {\tt psopfn}.
  1888. The thus modified S-expression is evaluated. This mechanism leaves control
  1889. over evaluation of (part of) the arguments, collected in {\tt cdr u}, to the
  1890. designer of the function hidden behind the {\tt psopfn} value. We employed
  1891. this simple mechanism to implement {\tt ALGOPT} and some of the features,
  1892. to be discussed in section~\ref{SSF:sr} and section~\ref{SSF:Hr}.
  1893. A possible re-evaluation step, based on the use of the
  1894. value of the indicator {\tt cleanupfn} was not necessary; it is not yet
  1895. allowed in the SCOPE context.
  1896. The different combinations, suggested in example~\ref{ex:3.2.7}, such as
  1897. {\tt ALGOPT} {\tt ALGOPT} or {\tt ALGOPT} {\tt ARESULTS}, are merely examples
  1898. of a general rule:
  1899. {\em {\tt ENDSTAT}-, {\tt NORMAL}- and {\tt PSOPFN}-type functions, delivering
  1900. an alglist when applied, are all applicable as actual parameter or
  1901. as element of an alglist, functioning as actual parameter in an
  1902. {\tt OPTIMIZE} command or an {\tt ALGOPT} application. }
  1903. \index{REDUCE function ! {\tt ENDSTAT}-type}
  1904. \index{REDUCE function ! {\tt NORMAL}-type}
  1905. \index{REDUCE function ! {\tt PSOPFN}-type}
  1906. So, in principle, special features, providing a form of preprocessing, can be
  1907. designed and implemented as extension of the default optimization repertoire.
  1908. Of course additional function types are conceivable.
  1909. We illustrate the potential of this facility with a simple example.
  1910. Further examples follow
  1911. in section~\ref{SSF:sr} and section~\ref{SSF:Hr}.
  1912. \example\label{ex:4.1.1}
  1913. \index{SCOPE ! example}
  1914. The procedures {\tt asquares} and {\tt repeated\_squaring}
  1915. define the production of
  1916. lists of equations. The lhs's function as name and the rhs's as
  1917. the computational rules.
  1918. Application of these functions shows how easy a user can provide new features,
  1919. usable in a SCOPE context.
  1920. The procedures {\tt asquares} and {\tt repeated\_squaring} are essentially
  1921. different The first has one parameter, a list of equations, while the latter
  1922. accepts an arbitrary number of such lists as actual parameters.
  1923. The {\tt psopfn} indicator value is
  1924. {\tt repeated\_squaringeval}, the name of the function, which is actually
  1925. introduced. {\tt asquares} is of {\tt NORMAL}-type and applicable in both
  1926. algebraic and symbolic mode.
  1927. {\small
  1928. \begin{verbatim}
  1929. OPERATOR square$
  1930. sq_rule:={square(~u) => u^2}$
  1931. ALGEBRAIC PROCEDURE asquare u;
  1932. square(u) WHERE sq_rule$
  1933. SYMBOLIC PROCEDURE rsquare u;
  1934. reval asquare aeval u$
  1935. SYMBOLIC PROCEDURE asquares u;
  1936. append(list('list),
  1937. FOREACH el IN cdr u COLLECT list('equal,cadr el,rsquare caddr el))$
  1938. SYMBOLIC OPERATOR asquares$
  1939. SYMBOLIC PROCEDURE repeated_squaringeval u;
  1940. BEGIN SCALAR res; INTEGER j;
  1941. j=0;
  1942. FOREACH el IN u DO
  1943. << j:=j+1; el:=asquares el;
  1944. FOR k:=2:j DO el:=asquares el;
  1945. res:= IF j=1 THEN el ELSE append(res,cdr el)
  1946. >>;
  1947. RETURN res
  1948. END$
  1949. LISP( put('repeated_squaring,'psopfn,'repeated_squaringeval))$
  1950. % ---
  1951. % Examples of the use of asquares and repeated_squaring.
  1952. % Although the psopfn-mechanism can be easily avoided,
  1953. % it is used for illustrative purposes here.
  1954. % ---
  1955. OFF EXP$
  1956. asquare sin(x);
  1957. 2
  1958. sin(x)
  1959. LISP(rsquare('(sin x)));
  1960. (expt (sin x) 2)
  1961. asq:=asquares {s1=a+b,s2=(a+b)^2,s3=(a+b)^3};
  1962. 2 4 6
  1963. asq := {s1=(a + b) ,s2=(a + b) ,s3=(a + b) }
  1964. repeated_squaring({s1=a+b,s2=(a+b)^2},{s3=(a+b)^3,s4=(a+b)^4},
  1965. {s5=(a+b)^5,s6=(a+b)^6});
  1966. 2
  1967. {s1=(a + b) ,
  1968. 4
  1969. s2=(a + b) ,
  1970. 12
  1971. s3=(a + b) ,
  1972. 16
  1973. s4=(a + b) ,
  1974. 40
  1975. s5=(a + b) ,
  1976. 48
  1977. s6=(a + b) }
  1978. % ---
  1979. % The "ALGOPT asquares ...;" application is similar to the "ALGOPT asq;"
  1980. % instruction.
  1981. % ---
  1982. ALGOPT(asquares {s1=a+b,s2=(a+b)^2,s3=(a+b)^3},t);
  1983. 2 2
  1984. {t2=a + b,s1=t2 ,s2=s1 ,s3=s1*s2}
  1985. ALGOPT asq;
  1986. \end{verbatim}}
  1987. \newpage
  1988. {\small
  1989. \begin{verbatim}
  1990. 2 2
  1991. {g6=a + b,s1=g6 ,s2=s1 ,s3=s1*s2}
  1992. % ---
  1993. % The OPTIMIZE variant is now applied on a repeated_squaring application.
  1994. % ---
  1995. OPTIMIZE repeated_squaring({s1=a+b,s2=(a+b)^2},{s3=(a+b)^3,s4=(a+b)^4},
  1996. {s5=(a+b)^5,s6=(a+b)^6}) INAME t;
  1997. t5 := a + b
  1998. s1 := t5*t5
  1999. s2 := s1*s1
  2000. t12 := s2*s2
  2001. s3 := s2*t12
  2002. s4 := s2*s3
  2003. s5 := t12*t12*t12*s4
  2004. s6 := t12*s5
  2005. \end{verbatim}
  2006. \begin{flushright}
  2007. $\Box$
  2008. \end{flushright}}
  2009. \subsection{Structure Recognition:
  2010. {\tt GSTRUCTR} and {\tt ALGSTRUCTR}} \label{SSF:sr}
  2011. \index{REDUCE function ! {\tt GSTRUCTR}}
  2012. \index{REDUCE function ! {\tt structr}}
  2013. \index{SCOPE function ! {\tt ALGSTRUCTR}}
  2014. The {\tt structr} command in REDUCE 3.6 (see the manual, section 8.3.8)
  2015. can be used
  2016. to display the skeletal structure of its evaluated argument, a single
  2017. expression. After setting {\tt ON SAVESTRUCTR} a {\tt structr} command
  2018. will return a list, whose first element is a presentation for the expression
  2019. and subsequent elements are the subexpression relations.\\
  2020. A special SCOPE feature provides an extended display facility, called
  2021. {\tt GSTRUCTR}. The syntax of this generalized command is:
  2022. \begin{center}
  2023. \begin{tabular}{lcl}
  2024. $<${\tt REDUCE}\_command$>$ & $::=$ & $\cdots~\mid$\\
  2025. & & {\tt GSTRUCTR} $<$stat\_group$>$ [{\tt NAME} $<$cse\_prefix$>$]\\
  2026. $<$stat\_group$>$ & $::=$ & $\ll~<$stat\_list$>~\gg$\\
  2027. $<$stat\_list$>$ & $::=$ & $<$gstat$>$ [; $<$stat\_list$>$]\\
  2028. $<$gstat$>$ & $::=$ & $<$name$>~:=~<$ expression$>~\mid~<$matrix\_id$>$
  2029. \end{tabular}
  2030. \end{center}
  2031. The stat\_group consists
  2032. of one assignment statement or a group of such statements. Application of
  2033. a {\tt GSTRUCTR} command provides a display of the structure of the whole
  2034. set of assignments. Such an assignment can be replaced by a matrix reference.
  2035. That leads to the display of all the non-zero entries of the referenced
  2036. matrix as well. The {\tt NAME} part is optional. The cse-name mechanism
  2037. is applied in the usual way.
  2038. The equivalent of a possible {\tt ON SAVESTRUCTR} setting is provided in the
  2039. form of a {\tt PSOPFN}-type function, called {\tt ALGSTRUCTR}.
  2040. Its syntax is:
  2041. \begin{center}
  2042. \begin{tabular}{lcl}
  2043. $<$function\_application$>$ & $::=$ &
  2044. {\tt ALGSTRUCTR} ($<$arg\_list$>$ [, $<$cse\_prefix$>$ ]) \\
  2045. $<$arg\_list$>$ & $::=$ & $<$arg\_list\_name$>~\mid~$\{$<$arg\_seq$>$\}\\
  2046. $<$arg\_seq$>$ & $::=$ & $<$arg$>$[,$<$arg\_seq$>$]\\
  2047. $<$arg$>$ & $::=$ & $<$matrix\_id$>~\mid~<$name$>$=$<$expression$>$\\
  2048. $<$arg\_list\_name$>$ & $::=$ & $<$id$>$
  2049. \end{tabular}
  2050. \end{center}
  2051. The result is presented in the form of an algebraic mode list.
  2052. Earlier SCOPE-versions allowed to use a {\tt GSTRUCTR} command as (part of an)
  2053. actual parameter for an {\tt OPTIMIZE} command. This facility is not longer
  2054. supported. In stead, an {\tt ALGSTRUCTR} application can now be used as (part
  2055. of an) actual parameter in both an {\tt OPTIMIZE} command or an {\tt ALGOPT}
  2056. application. We now illustrate these features in:
  2057. \index{REDUCE function ! {\tt GSTRUCTR}}
  2058. \index{SCOPE function ! {\tt ALGSTRUCTR}}
  2059. \example\label{ex:4.1.2}
  2060. \index{SCOPE ! example}
  2061. The script hardly requires explanation. However, observe
  2062. that {\tt v1}, {\tt v3}, {\tt v4}, {\tt v6} and {\tt v7} occur only once
  2063. in the result of the {\tt GSTRUCTR} application. When this application
  2064. is used as actual parameter for an {\tt OPTIMIZE} command
  2065. these redundancies are removed before the actual optimization process starts.
  2066. Likewise,
  2067. an {\tt ALGSTRUCTR} application only leads to identification of repeatedly
  2068. occuring sub-structures in its input.
  2069. {\tt ALGSTRUCTR}, {\tt ALGHORNER}, see the next subsection, and {\tt ALGOPT}
  2070. all apply the same output production strategy, i.e. it might be necessary to
  2071. restore the previous algebraic mode status by applying the
  2072. function {\tt RESTOREALL}.
  2073. {\small
  2074. \begin{verbatim}
  2075. OFF EXP,PERIOD$
  2076. MATRIX a(2,2);
  2077. a:=mat((x+y+z,x*y),((x+y)*x*y,(x+2*y+3)^3-x));
  2078. [ x + y + z x*y ]
  2079. [ ]
  2080. a := [ 3 ]
  2081. [(x + y)*x*y (x + 2*y + 3) - x]
  2082. GSTRUCTR <<a;b:=(x+y)^2;c:=(x+y)*(y+z);d:=(x+2*y)*(y+z)*(z+x)^2>> NAME v$
  2083. a(1,1) := v1
  2084. a(1,2) := x*y
  2085. a(2,1) := v2*x*y
  2086. a(2,2) := v4
  2087. 2
  2088. b := v2
  2089. c := v2*v5
  2090. 2
  2091. d := v6*v7 *v5
  2092. where
  2093. v7 := x + z
  2094. v6 := x + 2*y
  2095. v5 := y + z
  2096. 3
  2097. v4 := v3 - x
  2098. v3 := x + 2*y + 3
  2099. v2 := x + y
  2100. v1 := x + y + z
  2101. ALGSTRUCTR({a,b=(x+y)^2,c=(x+y)*(y+z),d=(x+2*y)*(y+z)*(z+x)^2},v);
  2102. {a(1,1)=x + y + z,
  2103. a(1,2)=x*y,
  2104. v2=x + y,
  2105. a(2,1)=v2*x*y,
  2106. 3
  2107. a(2,2)=(x + 2*y + 3) - x,
  2108. 2
  2109. b=v2 ,
  2110. v5=y + z,
  2111. c=v2*v5,
  2112. 2
  2113. d=(x + 2*y)*(x + z) *v5}
  2114. \end{verbatim}}
  2115. \index{SCOPE function ! {\tt RESTORABLES}}
  2116. \index{SCOPE function ! {\tt ARESTORE}}
  2117. {\small
  2118. \begin{verbatim}
  2119. RESTORABLES;
  2120. {a}
  2121. ARESTORE a$
  2122. alst:=
  2123. ALGOPT(ALGSTRUCTR({a,b=(x+y)^2,c=(x+y)*(y+z),d=(x+2*y)*(y+z)*(z+x)^2},v),s);
  2124. *** a declared operator
  2125. alst := {s5=x + z,
  2126. a(1,1)=s5 + y,
  2127. a(1,2)=x*y,
  2128. v2=x + y,
  2129. a(2,1)=a(1,2)*v2,
  2130. s6=x + 2*y,
  2131. s4=s6 + 3,
  2132. 3
  2133. a(2,2)=s4 - x,
  2134. 2
  2135. b=v2 ,
  2136. v5=y + z,
  2137. c=v2*v5,
  2138. 2
  2139. d=s5 *s6*v5}
  2140. % ---
  2141. % The above delivered warning is caused by the decloupling of a and its
  2142. % status as matrix. Therefore a(1,2) can function in the rhs of a(2,1).
  2143. % After an ARESTORE instruction a can restart its life as matrix_id.
  2144. % ---
  2145. a;
  2146. a
  2147. ARESTORE a$
  2148. a;
  2149. [ x + y + z x*y ]
  2150. [ ]
  2151. [ 3 ]
  2152. [(x + y)*x*y (x + 2*y + 3) - x]
  2153. \end{verbatim}
  2154. \begin{flushright}
  2155. $\Box$
  2156. \end{flushright}}
  2157. \subsection{Horner-rules: {\tt GHORNER} and {\tt ALGHORNER}} \label{SSF:Hr}
  2158. \index{Horner-rules}
  2159. \index{REDUCE function ! {\tt GHORNER}}
  2160. \index{SCOPE function ! {\tt ALGHORNER}}
  2161. Horner-rule based expression modification is a SCOPE facility,
  2162. called {\tt GHORNER}. The syntax of the command is similar to the
  2163. {\tt GSTRUCTR} syntax:
  2164. \begin{center}
  2165. \begin{tabular}{lcl}
  2166. $<${\tt REDUCE}\_command$>$ & $::=$ & $\cdots~\mid$\\
  2167. & & {\tt GHORNER} $<$stat\_group$>$ [{\tt VORDER} $<$id\_seq$>$];
  2168. \end{tabular}
  2169. \end{center}
  2170. The {\tt VORDER} part is optional. Application of
  2171. a (generalized) Horner-rule assumes an identifier ordering. The syntax
  2172. of the identifier sequence is:
  2173. \hspace{1cm} $<$id\_seq$>~::=~<$id$>$[,$<$id\_seq$>$].
  2174. We assume the rhs's in the stat\_group to be polynomials in
  2175. the identifiers, partly or completely given in the id\_seq. The
  2176. left-to-right ordering of this sequence replaces the existing system
  2177. identifier ordering. Identifiers, omitted from the {\tt vorder} sequence
  2178. have a lower preference and follow the existing system ordering. The
  2179. rewritten rhs's are presented as a side-effect. FORTRAN notation is of
  2180. course permitted. It is simply an extended print facility.
  2181. The {\tt PSOPFN}-type variant of the {\tt GHORNER} command is
  2182. called {\tt ALGHORNER}. Its syntax is:
  2183. \begin{center}
  2184. \begin{tabular}{lcl}
  2185. $<$function\_application$>$ & $::=$ & $\cdots~\mid$\\
  2186. & & {\tt ALGHORNER} ($<$arg\_list$>$ [,\{$<$id\_seq$>$\}]) \\
  2187. \end{tabular}
  2188. \end{center}
  2189. The syntax for the arg\_list can be found in subsection~\ref{SSF:sr}.
  2190. The result is presented in the form of an algebraic mode list.
  2191. An {\tt ALGHORNER} application can be used as (part of an) actual parameter
  2192. of either an {\tt OPTIMIZE} command or an {\tt ALGOPT} application.
  2193. \example\label{ex:4.1.3}
  2194. \index{SCOPE ! example}
  2195. We illustrate the Horner-facilities by rewriting the expression of
  2196. example~\ref{ex:3.1.2}, before optimizing it. Observe that
  2197. application of {\tt ALGHORNER} in the default algebraic mode setting
  2198. is useless. Due to the algebraic mode regime the rewritten expression
  2199. is expanded again. We also show some Taylor-series remodelling.
  2200. {\small
  2201. \begin{verbatim}
  2202. ON EXP$
  2203. z:=a^2*b^2+10*a^2*m^6+a^2*m^2+2*a*b*m^4+2*b^2*m^6+b^2*m^2;
  2204. 2 2 2 6 2 2 4 2 6 2 2
  2205. z := a *b + 10*a *m + a *m + 2*a*b*m + 2*b *m + b *m
  2206. GHORNER z:=z VORDER a;
  2207. 2 6 2 2 4 2 6 2
  2208. z := (2*b *m + b *m ) + a*(2*b*m + a*(b + 10*m + m ))
  2209. GHORNER z:=z VORDER b;
  2210. 2 6 2 2 4 2 6 2
  2211. z := (10*a *m + a *m ) + b*(2*a*m + b*(a + 2*m + m ))
  2212. hlst:={z=z}$
  2213. ALGHORNER(hlst,{a,b,m});
  2214. 2 2 2 6 2 2 4 2 6 2 2
  2215. {z=a *b + 10*a *m + a *m + 2*a*b*m + 2*b *m + b *m }
  2216. OPTIMIZE ALGHORNER(hlst,{a,b,m}) INAME s;
  2217. s1 := m*m
  2218. s0 := s1*s1
  2219. s2 := b*b
  2220. s4 := 2*s0
  2221. z := a*(a*(s2 + s1*(10*s0 + 1)) + s4*b) + s2*s1*(s4 + 1)
  2222. OPTIMIZE ALGHORNER(hlst,{b,m}) INAME s;
  2223. s2 := m*m
  2224. s0 := s2*s2
  2225. s1 := a*a
  2226. s4 := 2*s0
  2227. z := b*(b*(s1 + s2*(s4 + 1)) + s4*a) + s2*(s1 + 10*s1*s0)
  2228. \end{verbatim}}
  2229. \newpage
  2230. {\small
  2231. \begin{verbatim}
  2232. % Hornering Taylor-series:
  2233. PROCEDURE taylor(fx,x,x0,n);
  2234. sub(x=x0,fx)+(FOR k:=1:n SUM(sub(x=x0,df(fx,x,k))*(x-x0)^k/factorial(k)))$
  2235. hlst2:={f1=taylor(e^x,x,0,4),f2=taylor(cos x,x,0,6)};
  2236. 4 3 2
  2237. x + 4*x + 12*x + 24*x + 24
  2238. hlst2 := {f1=-------------------------------,
  2239. 24
  2240. 6 4 2
  2241. - x + 30*x - 360*x + 720
  2242. f2=------------------------------}
  2243. 720
  2244. OPTIMIZE ALGHORNER(hlst2,{x});
  2245. 24 + x*(24 + x*(12 + x*(4 + x)))
  2246. f1 := ----------------------------------
  2247. 24
  2248. g7 := x*x
  2249. 720 + g7*(g7*(30 - g7) - 360)
  2250. f2 := -------------------------------
  2251. 720
  2252. ON ROUNDED$
  2253. hlst2:=hlst2;
  2254. 4 3 2
  2255. hlst2 := {f1=0.0416666666667*x + 0.166666666667*x + 0.5*x + x + 1,
  2256. 6 4 2
  2257. f2= - 0.00138888888889*x + 0.0416666666667*x - 0.5*x + 1
  2258. }
  2259. OPTIMIZE ALGHORNER(hlst2,{x});
  2260. f1 := 1 + x*(1 + x*(0.5 + x*(0.0416666666667*x + 0.166666666667)))
  2261. g9 := x*x
  2262. f2 := 1 + g9*(g9*(0.0416666666667 - 0.00138888888889*g9) - 0.5)
  2263. \end{verbatim}
  2264. \begin{flushright}
  2265. $\Box$
  2266. \end{flushright}}
  2267. \index{{\tt ROUNDED} switch}
  2268. \newpage
  2269. \section{File Management and Optimization Strategies}\label{SCOPE:files}
  2270. Both the {\tt OPTIMIZE} command and the {\tt ALGOPT} function accept
  2271. input from file(s). Obviously, this input ought to obey the
  2272. usual syntactical rules, as introduced in the previous (sub)sections.
  2273. The {\tt OPTIMIZE} command is designed as a syntactical extension of {\REDUCE}
  2274. itself, i.e. the meaning of its actual parameters is understood from the
  2275. token-context in the command. However, an {\tt ALGOPT}
  2276. application requires one, two or three actual parameters without additional
  2277. provisions or conditions.
  2278. The {\tt ALGOPT} facility is added to provide a simple, user friendly,
  2279. algebraic mode tool. Therefore -in contrast with the {\tt OPTIMIZE} command-
  2280. it does not allow to direct output to a file; the default {\REDUCE} features
  2281. for dealing with output files can be applied.
  2282. \index{file management}
  2283. \index{{\tt IN} option}
  2284. \index{{\tt OUT} option}
  2285. \index{{\tt INAME} option}
  2286. \index{{\tt AGAIN} switch}
  2287. The previously given syntax requires some extensions:
  2288. $<$SCOPE\_application$>~::=$ $<${\tt OPTIMIZE} command$>~\mid~<${\tt ALGOPT} application$>$\\
  2289. $<${\tt OPTIMIZE} command$>~::=$\\
  2290. \hspace*{1cm} {\tt OPTIMIZE} $<$object\_seq$>$ [{\tt IN} $<$file\_id\_seq$>$] [{\tt OUT} $<$file\_id$>$] [{\tt INAME} $<$cse\_prefix$>$] $\mid$\\
  2291. \hspace*{1cm} {\tt OPTIMIZE} [$<$object\_seq$>$] {\tt IN} $<$file\_id\_seq$>$ [{\tt OUT} $<$file\_id$>$] [{\tt INAME} $<$cse\_prefix$>$]\\
  2292. $<${\tt ALGOPT} application$>~::=$\\
  2293. \hspace*{1cm} {\tt ALGOPT}($<$a\_object\_list$>$[,$<$string\_id\_list$>$][,$<$cse\_prefix$>$]) $\mid$\\
  2294. \hspace*{1cm} {\tt ALGOPT}([$<$a\_object\_list$>$,]$<$string\_id\_list$>$[,$<$cse\_prefix$>$])
  2295. The different variations for the object\_seq and
  2296. the a\_object\_list and the meaning of cse\_prefix are introduced
  2297. in the subsections ~\ref{SCOPE:optim} and ~\ref{SCOPE:algo}.
  2298. The syntax of the file handling features is:
  2299. \begin{center}
  2300. \begin{tabular}{lcl}
  2301. $<$file\_id\_seq$>$ & $::=$ & $<$file\_id$>$ [,$<$file\_id\_seq$>$]\\
  2302. $<$file\_id$>$ & $::=$ & $<$id$>$ $\mid$ $<$string\_id$>$\\
  2303. $<$string\_id\_list$>$ & $::=$ & $<$string\_id$>$ $\mid$
  2304. \{$<$string\_id\_seq$>$\}\\
  2305. $<$string\_id\_seq$>$ & $::=$ & $<$string\_id$>$ [,$<$string\_id\_seq$>$]\\
  2306. $<$string\_id$>$ & $::=$ & {\tt "}$<$id$>${\tt "} $\mid$
  2307. {\tt "}$<$id$>.<$f\_extension$>${\tt "}
  2308. \end{tabular}
  2309. \end{center}
  2310. The differences in input-file management are introduced for practical reasons.
  2311. As stated above, the {\tt ALGOPT} function can have up to three arguments.
  2312. To be able to distinguish the optional second argument from the first and the
  2313. last requires file-names to be given in the form of strings. The
  2314. {\tt OPTIMIZE} command follows the ordinary {\REDUCE} rules for file names.
  2315. File management can be used as a tool for input partioning. If $m>1$ then
  2316. $N^m>\sum_{i=1}^k {n^k}_i$ for positive integers $N$ and $n_i$ , such that
  2317. $N=\sum_{i=1}^k n_i$. In view of the time-complexity of the
  2318. optimization algorithm, it may be worth the effort to partition
  2319. SCOPE input of size $N$ in $k$ partitions, of sizes $n_i,~i=1,...,k$. We can
  2320. start optimizing the contents of file fi.1, containing the initial $n_1$-sized
  2321. piece of code, and store the result of this operation in file fo.1.
  2322. Consecutive steps provide an optimization of the combined contents of the
  2323. files fo.i and fi.(i+1), i=1,..., k-1.
  2324. During this iterative process, or during variations
  2325. of this strategy, it is better not to perform a finishing touch. The switch
  2326. {\tt AGAIN}, which is normally {\tt OFF}, can be used, when set {\tt ON}, to
  2327. avoid this. The switch serves an additional purpose. When switched {\tt ON}
  2328. storage of partly optimized code in a file will include all relevant
  2329. information, needed to restore the required status of system generated
  2330. sub-expression names.
  2331. We illustrate SCOPE's file management facilities with example.
  2332. \example\label{ex:5.1}
  2333. \index{SCOPE ! example}
  2334. We assume to have three files, called f1, f2 and f3. Each file contains only
  2335. one assignment. We simply show different variations of the use of these files.
  2336. \index{{\tt INPUTC} switch}
  2337. \index{{\tt IN} option}
  2338. With {\tt ON INPUTC} the contents of the files is made visible.
  2339. {\small
  2340. \begin{verbatim}
  2341. ON INPUTC$
  2342. OPTIMIZE IN f1,f2,f3 INAME s;
  2343. 2
  2344. 2 (x + y) 8 2 2
  2345. 2*(sin(x) - cos(e ) + 3*cos(x)) *(x + y) + 4*y + 4*y
  2346. e1 := ----------------------------------------------------------------
  2347. 3*x + 2*y
  2348. 2
  2349. 2 (x + y) 2 3
  2350. e2 := (4*(sin(x) - cos(e ) + 2*cos(x)) *(x + y)
  2351. 2 2
  2352. + (4*x - 4*y) - 6*x)/(8*x + 3*y - 2*x)
  2353. 2
  2354. (x + y) 2 2
  2355. 4*sin(cos(e )) + sin(x + y) + (4*x - x + 2*y)
  2356. e3 := --------------------------------------------------------
  2357. 3*y + f(x,g( - cos(x)))
  2358. s3 := sin(x)
  2359. s20 := x + y
  2360. s6 := s20*s20
  2361. s6
  2362. s4 := cos(e )
  2363. s8 := cos(x)
  2364. s31 := s3*s3 - s4
  2365. s2 := s31 + 3*s8
  2366. s44 := s2*s2
  2367. s43 := s44*s44
  2368. s36 := 4*y
  2369. s34 := 2*y
  2370. s10 := s34 + 3*x
  2371. s36 + s36*y + 2*s6*s43*s43
  2372. e1 := ----------------------------
  2373. s10
  2374. s13 := s31 + 2*s8
  2375. s33 := 4*x*x
  2376. s30 := s33 - x
  2377. s35 := 3*y
  2378. \end{verbatim}}
  2379. \newpage
  2380. {\small
  2381. \begin{verbatim}
  2382. s33 - 2*s10 + 4*s6*s20*s13*s13
  2383. e2 := --------------------------------
  2384. s35 + 2*s30
  2385. s21 := s34 + s30
  2386. 4*sin(s4) + sin(s20) + s21*s21
  2387. e3 := --------------------------------
  2388. s35 + f(x,g( - s8))
  2389. \end{verbatim}}
  2390. We repeat the same process. However, this time we apply input partitioning.
  2391. The switch {\tt AGAIN} is turned {\tt ON}. Output is redirected to the
  2392. output file {\tt fo.1} in an {\tt OFF NAT} fashion and ended with the required
  2393. {\tt ;end;} closure, thus made ready for re-use during a next step.
  2394. The default mode of operation is {\tt OFF AGAIN} and {\tt ON NAT}. If the
  2395. switch {\tt NAT} is turned {\tt OFF} file output is automatically ended
  2396. by {\tt ;end;}.
  2397. \index{{\tt AGAIN} switch}
  2398. \index{{\tt NAT} switch}
  2399. Due to the {\tt ON INPUTC} effect we can also observe that the identifiers
  2400. {\tt gsym} and {\tt cses} are apparently used to store relevant information
  2401. about cse names.
  2402. {\small
  2403. \begin{verbatim}
  2404. ON AGAIN,INPUTC$
  2405. OPTIMIZE IN f1 OUT "fo.1" INAME s$
  2406. 2
  2407. 2 (x + y) 8 2 2
  2408. 2*(sin(x) - cos(e ) + 3*cos(x)) *(x + y) + 4*y + 4*y
  2409. e1 := ----------------------------------------------------------------
  2410. 3*x + 2*y
  2411. OPTIMIZE IN "fo.1",f2 OUT "fo.2" INAME t$
  2412. gsym := g0001
  2413. cses := s6
  2414. 2
  2415. s6 := (x + y)
  2416. 2 2 s6 8
  2417. 4*y + 4*y + 2*s6*(3*cos(x) + sin(x) - cos(e ))
  2418. e1 := ----------------------------------------------------
  2419. 3*x + 2*y
  2420. 2
  2421. 2 (x + y) 2 3
  2422. e2 := (4*(sin(x) - cos(e ) + 2*cos(x)) *(x + y)
  2423. 2 2
  2424. + (4*x - 4*y) - 6*x)/(8*x + 3*y - 2*x)
  2425. OFF AGAIN$
  2426. ALGOPT({"fo.2","f3"},u);
  2427. gsym := g0002
  2428. cses := t23 + t11 + t26 + t7 + t17 + t19
  2429. t19 := x + y
  2430. 2
  2431. t17 := t19
  2432. t7 := cos(x)
  2433. 2 t17
  2434. t26 := sin(x) - cos(e )
  2435. t11 := 3*x + 2*y
  2436. 2 8
  2437. 4*y + 4*y + 2*(t26 + 3*t7) *t17
  2438. e1 := ----------------------------------
  2439. t11
  2440. 2
  2441. t23 := x
  2442. 2
  2443. 4*t23 - 2*t11 + 4*t19*(t26 + 2*t7) *t17
  2444. e2 := -----------------------------------------
  2445. 8*t23 - 2*x + 3*y
  2446. 2
  2447. (x + y) 2 2
  2448. 4*sin(cos(e )) + sin(x + y) + (4*x - x + 2*y)
  2449. e3 := --------------------------------------------------------
  2450. 3*y + f(x,g( - cos(x)))
  2451. *** f declared operator
  2452. *** g declared operator
  2453. {u23=x + y,
  2454. 2
  2455. u20=u23 ,
  2456. t7=cos(x),
  2457. u5=sin(x),
  2458. u20
  2459. u6=cos(e ),
  2460. \end{verbatim}}
  2461. \newpage
  2462. {\small
  2463. \begin{verbatim}
  2464. 2
  2465. t26=u5 - u6,
  2466. u33=2*y,
  2467. t11=u33 + 3*x,
  2468. u10=t26 + 3*t7,
  2469. 2
  2470. u46=u10 ,
  2471. 2
  2472. u45=u46 ,
  2473. u35=4*y,
  2474. 2
  2475. 2*u20*u45 + u35*y + u35
  2476. e1=--------------------------,
  2477. t11
  2478. 2
  2479. t23=x ,
  2480. u13=t26 + 2*t7,
  2481. u36=4*t23,
  2482. u31=u36 - x,
  2483. u34=3*y,
  2484. 2
  2485. - 2*t11 + 4*u13 *u20*u23 + u36
  2486. e2=---------------------------------,
  2487. 2*u31 + u34
  2488. u24=u31 + u33,
  2489. 2
  2490. sin(u23) + 4*sin(u6) + u24
  2491. e3=-----------------------------}
  2492. f(x,g( - t7)) + u34
  2493. \end{verbatim}}
  2494. \noindent
  2495. Observe that the initial characters of the sub-expression names indicate
  2496. their moment of generation. We used {\tt f} and {\tt g} as operators.
  2497. Therefore, a warning was produced ahead of the {\tt ALGOPT} output.
  2498. Since an {\tt OPTIMIZE} command produces output as a side-effect these warnings
  2499. were not given earlier.
  2500. {\small
  2501. \begin{flushright}
  2502. $\Box$
  2503. \end{flushright}}
  2504. \newpage
  2505. \section{Generation of Declarations}\label{SCOPE:decl}
  2506. GENTRAN's {\tt DECLARE} statement can be used as an optional extension of the
  2507. {\tt OPTIMIZE} command, and as ilustrated in example~\ref{ex:6.1}. The syntax
  2508. of such an extension is in accordance with the GENTRAN rules:
  2509. \index{GENTRAN ! {\tt DECLARE} statement}
  2510. \index{SCOPE ! {\tt DECLARE} facility}
  2511. \index{{\tt DECLARE} option}
  2512. \index{{\tt IN} option}
  2513. \index{{\tt OUT} option}
  2514. \index{{\tt INAME} option}
  2515. \index{{\tt IMPLICIT} type}
  2516. \index{{\tt integer} type}
  2517. \index{{\tt real} type}
  2518. \index{{\tt real*8} type}
  2519. \index{{\tt complex} type}
  2520. \index{{\tt complex*16} type}
  2521. \index{SCOPE function ! {\tt OPTLANG}}
  2522. \index{SCOPE target language ! {\tt fortran77}}
  2523. \index{SCOPE target language ! {\tt fortran90}}
  2524. \index{SCOPE target language ! {\tt f90}}
  2525. \index{SCOPE target language ! {\tt c}}
  2526. \index{SCOPE target language ! {\tt pascal}}
  2527. \index{SCOPE target language ! {\tt ratfor}}
  2528. \index{SCOPE target language ! {\tt nil}}
  2529. $<${\tt OPTIMIZE} command$>~::=$\\
  2530. \hspace*{1cm} {\tt OPTIMIZE} $<$object\_seq$>$ [{\tt IN} $<$file\_id\_seq$>$]
  2531. [{\tt OUT} $<$file\_id$>$]\\
  2532. \hspace*{3cm} [{\tt INAME} $<$cse\_prefix$>$]
  2533. [{\tt DECLARE} $<$declaration\_group$>$] $\mid$\\
  2534. \hspace*{1cm} {\tt OPTIMIZE} [$<$object\_seq$>$] {\tt IN} $<$file\_id\_seq$>$
  2535. [{\tt OUT} $<$file\_id$>$]\\
  2536. \hspace*{3cm} [{\tt INAME} $<$cse\_prefix$>$]
  2537. [{\tt DECLARE} $<$declaration\_group$>$]\\
  2538. The syntax of the declaration\_group is:
  2539. \begin{center}
  2540. \begin{tabular}{lcl}
  2541. $<$declaration\_group$>$ & $::=$ & $<$declaration$>~\mid~\ll~<$declaration\_list$>~\gg$\\
  2542. $<$declaration\_list$>$ & $::=$ & $<$declaration$>$[$;<$declaration\_list$>$]\\
  2543. $<$declaration$>$ & $::=$ & $<$range\_list$>:$ {\tt IMPLICIT} $<$type$>~\mid$
  2544. $<$id\_list$>:<$type$>$\\
  2545. $<$range\_list$>$& $::=$ & $<$range$>$[,$<$range\_list$>$]\\
  2546. $<$range$>$ & $::=$ & $<$id$>~\mid~<$id$>-<$id$>$\\
  2547. $<$id\_list$>$ & $::=$ & $<$id$>$[,$<$id\_list$>$]\\
  2548. $<$type$>$ & $::=$ & {\tt integer} $\mid$ {\tt real} $\mid$ {\tt complex} $\mid$ {\tt real*8} $\mid$ {\tt complex*16}
  2549. \end{tabular}
  2550. \end{center}
  2551. The symbol table features of GENTRAN are used. During the subtask
  2552. R (see subsection ~\ref{SCOPE:bird}) of an {\tt OPTIMIZE} command evaluation,
  2553. all typing information is installed in the symbol table. Once optimization
  2554. is ready all relevant information for completing the declarations ought to
  2555. be known, i.e. the contents of the symbol table and the result of the
  2556. optimization operations, collected in prefix form in a list,
  2557. called {\tt prefixlist}. This {\tt prefixlist} is employed do decide which not yet typed identifiers and system selected cse names have to be entered in the
  2558. symbol table. We make use of earlier provided information, delivered via the
  2559. {\tt DECLARE} option, (sub)expression structure and the normal hierarchy in data
  2560. types. The strategy to achieve this form of dynamic typing is based on
  2561. chapter 6 of ~\cite{Aho:86}.
  2562. Once the table is completed a list of declarations is produced and precedes the
  2563. other SCOPE output. SCOPE output is by default given in {\REDUCE} notation.
  2564. Therefore such lists of declarations are also given in {\REDUCE} text.
  2565. Incomplete initial typing information can lead to overtyping after
  2566. optimization, such as {\tt complex} in stead of {\tt real}, for instance.
  2567. It can therefore lead to erroneous results and even to an error message.
  2568. A safe procedure is to
  2569. use the {\tt DECLARE} option of the {\tt OPTIMIZE} command for typing
  2570. all identifiers, occuring in the input set ${\rm E}_0$
  2571. \index{dynamic typing}
  2572. Alternative output can be obtained via an application of the function
  2573. {\tt OPTLANG}. This function accepts one argument from the set \{{\tt fortran},
  2574. {\tt c}, {\tt ratfor}, {\tt pascal}\footnote{The {\tt pascal} module of
  2575. GENTRAN is not error free. Especially the template file features do not
  2576. function correctly.}, {\tt f90}, {\tt nil}\}.
  2577. The {\tt fortran}(77) choice can also be made by turning {\tt ON} the
  2578. switch {\tt FORT}. The {\tt nil} option is necessary if one wants to
  2579. switch back to the usual {\REDUCE} output.
  2580. not yet generally available. The output modules of GENTRAN are used for
  2581. producing formatted code in the user selected target language. The
  2582. {\tt f90} option, for the production of {\tt fortran90} code,
  2583. is not yet provided by the standard GENTRAN version ~\cite{Borst:94}.
  2584. Especially the above given syntax rules for typing require some additional
  2585. explanation:
  2586. \begin{itemize}
  2587. \item The corresponding types in Fortran are {\tt integer}, {\tt real},
  2588. {\tt complex}, {\tt double precision} and {\tt complex*16}.
  2589. \item The GENTRAN switch {\tt DOUBLE} is automatically turned {\tt ON},
  2590. when a type {\tt real*8} or type {\tt complex*16} is introduced in
  2591. a {\tt DECLARE} option. The same mode of operation is introduced when
  2592. floating point numbers appear in SCOPE input. Fixed floats do not produce
  2593. this side effect.
  2594. \item When generating {\tt fortran} code we have to be aware of a possibly
  2595. existing statement length limitation. If one is afraid that a declaration statement
  2596. will become
  2597. too long, for instance due to a huge number, dynamically added cse-names,
  2598. it may be better to use {\tt IMPLICIT} typing.
  2599. \item C neither supports {\tt IMPLICIT} types nor has the
  2600. types {\tt complex} and {\tt complex*16}. The remaining types are denoted
  2601. by {\tt int}, {\tt float} and {\tt double}, respectively.
  2602. \item Array and/or matrix definitions are also considered to be id's in
  2603. id\_list's in declarations.
  2604. However, we have to be aware of the instantaneous replacement of array-
  2605. and/or matrix entries, when expressions are simplified. Therefore, we have to
  2606. use operators, functioning as array and/or matrix names in code we want to
  2607. optimize. We return to this question in the sections ~\ref{SCOPE:dda} and
  2608. ~\ref{SCOPE:gopt}.
  2609. \end{itemize}
  2610. \index{{\tt ROUNDED} switch}
  2611. \index{{\tt DOUBLE} switch}
  2612. When the {\tt ON/OFF AGAIN} strategy is applied we have to be aware of the
  2613. above outlined declaration strategy. The last {\tt OPTIMIZE} command,
  2614. executed directly after choosing {\tt OFF AGAIN}, has to be extended
  2615. with the {\tt DECLARE} option.
  2616. Array and/or matrix names only occur in literally parsed information. In all
  2617. other situations we have to make use of {\REDUCE} {\tt operators}. Normally,
  2618. function applications inside SCOPE input are instantaneously replaced by
  2619. newly selected cse names after putting them in the function table.
  2620. Usually array and/or matrix entries are considered to be function applications.
  2621. However, when due to a {\tt DECLARE} option array and/or matrix names
  2622. are known via the contents of the symbol table, such entries are
  2623. substituted back before SCOPE produces output.
  2624. \index{{\tt IMPLICIT} type}
  2625. \index{{\tt integer} type}
  2626. \index{{\tt real} type}
  2627. \index{{\tt real*8} type}
  2628. \index{{\tt complex} type}
  2629. \index{{\tt double precision} type}
  2630. \index{{\tt int} type}
  2631. \index{{\tt float} type}
  2632. \index{{\tt double} type}
  2633. \index{{\tt DOUBLE} switch}
  2634. \index{{\tt AGAIN} switch}
  2635. \index{SCOPE function ! {\tt OPTLANG}}
  2636. \example\label{ex:6.1}
  2637. \index{SCOPE ! example}
  2638. A simple {\tt OPTIMIZE} command, extended with a {\tt DECLARE} option, is
  2639. executed for the various output options of GENTRAN, including the {\tt f90}
  2640. alternative.
  2641. {\small
  2642. \begin{verbatim}
  2643. OPTLANG fortran$
  2644. OPTIMIZE x(i+1):=a(i+1,i-1)+b(i),y(i-1):=a(i-1,i+1)-b(i)
  2645. INAME s
  2646. DECLARE << a(4,4),x(4),y(5):real; b(5):integer>>$
  2647. INTEGER B(5),I,S10,S9
  2648. REAL A(4,4),X(4),Y(5)
  2649. S10=I+1
  2650. S9=I-1
  2651. X(S10)=A(S10,S9)+B(I)
  2652. Y(S9)=A(S9,S10)-B(i)
  2653. OPTLANG ratfor$
  2654. OPTIMIZE x(i+1):=a(i+1,i-1)+b(i),y(i-1):=a(i-1,i+1)-b(i)
  2655. INAME s
  2656. DECLARE << a(4,4),x(4),y(5):real; b(5):integer>>$
  2657. integer b(5),i,s10,s9
  2658. real a(4,4),x(4),y(5)
  2659. {
  2660. s10=i+1
  2661. s9=i-1
  2662. x(s10)=a(s10,s9)+b(i)
  2663. y(s9)=a(s9,s10)-b(i)
  2664. }
  2665. OPTLANG c$
  2666. OPTIMIZE x(i+1):=a(i+1,i-1)+b(i),y(i-1):=a(i-1,i+1)-b(i)
  2667. INAME s
  2668. DECLARE << a(4,4),x(4),y(5):real; b(5):integer>>$
  2669. int b[6],i,s10,s9;
  2670. float a[5][5],x[5],y[6];
  2671. {
  2672. s10=i+1;
  2673. s9=i-1;
  2674. x[s10]=a[s10][s9]+b[i];
  2675. y[s9]=a[s9][s10]-b[i];
  2676. }
  2677. OPTLANG pascal$
  2678. OPTIMIZE x(i+1):=a(i+1,i-1)+b(i),y(i-1):=a(i-1,i+1)-b(i)
  2679. INAME s
  2680. DECLARE << a(4,4),x(4),y(5):real; b(5):integer>>$
  2681. var
  2682. s9,s10,i: integer;
  2683. b: array[0..5] of integer;
  2684. y: array[0..5] of real;
  2685. x: array[0..4] of real;
  2686. a: array[0..4,0..4] of real;
  2687. begin
  2688. s10:=i+1;
  2689. s9:=i-1;
  2690. x[s10]:=a[s10,s9]+b[i];
  2691. y[s9]:=a[s9,s10]-b[i]
  2692. end;
  2693. OPTLANG nil$
  2694. OPTIMIZE x(i+1):=a(i+1,i-1)+b(i),y(i-1):=a(i-1,i+1)-b(i)
  2695. INAME s
  2696. DECLARE << a(4,4),x(4),y(5):real; b(5):integer>>$
  2697. integer b(5),i,s10,s9
  2698. real a(4,4),x(4),y(5)
  2699. s10 := i + 1
  2700. s9 := i - 1
  2701. x(s10) := a(s10,s9) + b(i)
  2702. y(s9) := a(s9,s10) - b(i)
  2703. OPTLANG fortran$
  2704. OPTIMIZE x(i+1):=a(i+1,i-1)+b(i),y(i-1):=a(i-1,i+1)-b(i)
  2705. INAME s
  2706. DECLARE << a(4,4),x(4),y(5):real*8; b(5):integer>>$
  2707. INTEGER B(5),I,S10,S9
  2708. DOUBLE PRECISION A(4,4),X(4),Y(5)
  2709. S10=I+1
  2710. S9=I-1
  2711. X(S10)=A(S10,S9)+B(I)
  2712. Y(S9)=A(S9,S10)-B(I)
  2713. OPTIMIZE x(i+1):=a(i+1,i-1)+b(i),y(i-1):=a(i-1,i+1)-b(i)
  2714. INAME s
  2715. DECLARE << x(4),y(5):real; b(5):complex>>$
  2716. ***** Type error:
  2717. real x(4),y(5)
  2718. complex b(5)
  2719. (integer all) s9
  2720. integer s5,i
  2721. real := complex(all)
  2722. ***** Wrong typing
  2723. Cont? (Y or N)
  2724. \end{verbatim}}
  2725. We can restart \REDUCE and rerun the example with
  2726. the {\tt Fortran90} version of SCOPE. It results in:
  2727. \index{{\tt scope90}}
  2728. {\small
  2729. \begin{verbatim}
  2730. LOAD_PACKAGE scope90$
  2731. OPTLANG f90$
  2732. OPTIMIZE x(i+1):=a(i+1,i-1)+b(i),y(i-1):=a(i-1,i+1)-b(i)
  2733. INAME s
  2734. DECLARE << a(4,4),x(4),y(5):real; b(5):integer>>$
  2735. REAL,DIMENSION(4,4)::A
  2736. INTEGER,DIMENSION(5)::B
  2737. INTEGER::I,S10,S9
  2738. REAL,DIMENSION(4)::x
  2739. REAL,DIMENSION(5)::y
  2740. S10=I+1
  2741. S9=I-1
  2742. X(S10)=A(S10,S9)+B(I)
  2743. Y(S9)=A(S9,S10)-B(I)
  2744. \end{verbatim}
  2745. \begin{flushright}
  2746. $\Box$
  2747. \end{flushright}}
  2748. \subsection{Coefficient Arithmetic and Precision Handling}\label{SCOPE:caph}
  2749. {\REDUCE} knows a variety of coefficient domains, as presented in
  2750. subsection 9.11 of the {REDUCE} 3.6 manual ~\cite{Hearn:95}, entitled
  2751. {\em Polynomial Coefficient Arithmetic}. As stated in subsection~\ref{SCOPE:optim}
  2752. SCOPE supports integer and real coefficients. By turning {\tt ON} the switch
  2753. {\tt ROUNDED} we introduce float arithmetic for coefficients.
  2754. The operator {\tt PRECISION} can be applied to change the default,
  2755. machine dependent {\em precision}. Internally, {\REDUCE} uses floating point
  2756. numbers up to the precison supported by the underlying machine hardware, and
  2757. so-called {\em bigfloats} for higher precision. The internal precision is two decimals
  2758. greater than the exernal precision to guard against roundoff inaccuracies.
  2759. Rounded numbers are normally printed to the specified precision. If the user
  2760. wishes to print such numbers with less precision, the printing
  2761. precision can be set by the command {\tt PRINT\_PRECISION}. If a case
  2762. arises where use of the machine arithmetic leads to problems, a user can force
  2763. {\REDUCE} to use the bigfloat representation by turning {\tt ON} the switch
  2764. {\tt ROUNDBF}, which is normally {\tt OFF}. GENTRAN, and thus SCOPE as well,
  2765. support bigfloat notation. However the precision is a responsibility
  2766. of the user. A possibility is to use the {\tt PRINT\_PRECISION} command, both
  2767. for algebraic mode output and for output in a selected target language,
  2768. like {\tt fortran77}. SCOPE uses the given precision for selecting cse's.
  2769. Although complex arithmetic is not supported in SCOPE, a simple alternative
  2770. is provided. When using float arithmetic in {\REDUCE} the protected name
  2771. {\tt I} can be used to denote $\sqrt -1$. If the {\tt I} is included in a
  2772. declaration list as an identifier of type {\tt complex}({\tt !*}), its assumed value is
  2773. automatically put ahead of the resulting optimized code.
  2774. We illustrate the different possibilities in example ~\ref{ex:6.2}. Comment
  2775. is included.
  2776. \index{{\tt ROUNDBF} switch}
  2777. \index{REDUCE function ! {\tt PRECISION}}
  2778. \index{REDUCE function ! {\tt PRINT\_PRECISION}}
  2779. \index{bigfloats}
  2780. \index{coefficient arithmetic}
  2781. \index{machine precision}
  2782. \example\label{ex:6.2}
  2783. \index{SCOPE ! example}
  2784. {\small
  2785. \begin{verbatim}
  2786. OPTLANG fortran$
  2787. ON ROUNDED, DOUBLE$
  2788. % ---
  2789. % We start with precision 6. The returned value is the internal
  2790. % precision supported by the underlying machine hardware.
  2791. % ---
  2792. PRECISION 6;
  2793. 12
  2794. OPTIMIZE x1:= 2 *a + 10 * b,
  2795. x2:= 2.00001 *a + 10 * b,
  2796. x3:= 2 *a + 10.00001 * b,
  2797. x4:= 6 *a + 30 * b,
  2798. x5:= 2.0000001*a + 10.000001 * b
  2799. INAME s
  2800. DECLARE <<x1,x2,x3,x4,x5,a,b: real>>$
  2801. DOUBLE PRECISION A,B,S1,X1,X2,X3,X4,X5
  2802. S1=10*B
  2803. X1=S1+2*A
  2804. X2=S1+2.00001D0*A
  2805. X3=X1
  2806. X4=3*X1
  2807. X5=X1
  2808. % ---
  2809. % Explanation: X1 is a cse of X3, X4 and X5, but not of X2, because
  2810. % the coefficient 2.00001 is given in 6 decimal digits.
  2811. % Increase in precision will show this.
  2812. % ---
  2813. PRECISION 7$
  2814. OPTIMIZE x1:= 2 *a + 10 * b,
  2815. x2:= 2.00001 *a + 10 * b,
  2816. x3:= 2 *a + 10.00001 * b,
  2817. x4:= 6 *a + 30 * b,
  2818. x5:= 2.0000001*a + 10.000001 * b
  2819. INAME s
  2820. DECLARE <<x1,x2,x3,x4,x5,a,b: real>>$
  2821. DOUBLE PRECISION A,B,S1,S2,X1,X2,X3,X4,X5
  2822. S1=2*A
  2823. S2=10*B
  2824. X1=S2+S1
  2825. X2=S2+2.00001D0*A
  2826. X3=S1+1.000001D1*B
  2827. X4=3*X1
  2828. X5=X1
  2829. PRECISION 8$
  2830. OPTIMIZE x1:= 2 *a + 10 * b,
  2831. x2:= 2.00001 *a + 10 * b,
  2832. x3:= 2 *a + 10.00001 * b,
  2833. x4:= 6 *a + 30 * b,
  2834. x5:= 2.0000001*a + 10.000001 * b
  2835. INAME s
  2836. DECLARE <<x1,x2,x3,x4,x5,a,b: real>>$
  2837. DOUBLE PRECISION A,B,S1,S2,X1,X2,X3,X4,X5
  2838. S1=2*A
  2839. S2=10*B
  2840. X1=S2+S1
  2841. X2=S2+2.00001D0*A
  2842. X3=S1+1.000001D1*B
  2843. X4=3*X1
  2844. X5=2.0000001D0*A+1.0000001D1*B
  2845. % ---
  2846. % All rhs's were taken literally. Let us now increase precision and
  2847. % simplify the rhs's before optimization. It is in fact a repetition
  2848. % of the examples above, this time with a larger precision.
  2849. % ---
  2850. PRECISION 20$
  2851. OPTIMIZE x1:=:2 *a + 10 * b,
  2852. x2:=:2.0000000000000000001 *a + 10 * b,
  2853. x3:=:2 *a + 10.0000000000000000001 * b,
  2854. x4:=:6 *a + 30 * b,
  2855. x5:=:2.000000000000000000001*a + 10.000000000000000000001 * b
  2856. INAME s
  2857. DECLARE <<x1,x2,x3,x4,x5,a,b: real>>$
  2858. DOUBLE PRECISION A,B,S1,S2,X1,X2,X3,X4,X5
  2859. S1=2*A
  2860. S2=10*B
  2861. X1=S2+S1
  2862. X2=S2+2.0000000000000000001D0*A
  2863. X3=S1+1.0D1*B
  2864. X4=3*X1
  2865. X5=1.0D0*X1
  2866. PRECISION 21$
  2867. OPTIMIZE x1:=:2 *a + 10 * b,
  2868. x2:=:2.0000000000000000001 *a + 10 * b,
  2869. x3:=:2 *a + 10.0000000000000000001 * b,
  2870. x4:=:6 *a + 30 * b,
  2871. x5:=:2.000000000000000000001*a + 10.000000000000000000001 * b
  2872. INAME s
  2873. DECLARE <<x1,x2,x3,x4,x5,a,b: real>>$
  2874. DOUBLE PRECISION A,B,S1,S2,X1,X2,X3,X4,X5
  2875. S1=2*A
  2876. S2=10*B
  2877. X1=S2+S1
  2878. X2=S2+2.0000000000000000001D0*A
  2879. X3=S1+1.00000000000000000001D1*B
  2880. X4=3*X1
  2881. X5=2.0D0*A+1.0D1*B
  2882. PRECISION 22$
  2883. OPTIMIZE x1:=:2 *a + 10 * b,
  2884. x2:=:2.0000000000000000001 *a + 10 * b,
  2885. x3:=:2 *a + 10.0000000000000000001 * b,
  2886. x4:=:6 *a + 30 * b,
  2887. x5:=:2.000000000000000000001*a + 10.000000000000000000001 * b
  2888. INAME s
  2889. DECLARE <<x1,x2,x3,x4,x5,a,b: real>>$
  2890. DOUBLE PRECISION A,B,S1,S2,X1,X2,X3,X4,X5
  2891. S1=2*A
  2892. S2=10*B
  2893. X1=S2+S1
  2894. X2=S2+2.0000000000000000001D0*A
  2895. X3=S1+1.00000000000000000001D1*B
  2896. X4=3*X1
  2897. X5=2.000000000000000000001D0*A+1.0D1*B
  2898. % ---
  2899. % However, we can observe some differences in both modes of operation, when
  2900. % selecting a precision around the precision supported by the undelying
  2901. % machine hardware. Then the switch ROUNDBF can better be turned ON.
  2902. % ---
  2903. \end{verbatim}}
  2904. \index{{\tt ROUNDBF} switch}
  2905. \index{{\tt complex} type}
  2906. {\small
  2907. \begin{verbatim}
  2908. OFF ROUNDBF$
  2909. PRECISION 12$
  2910. OPTIMIZE x1:= 2.00 *a + 10.00 * b,
  2911. x2:= 2.00000000001*a + 10 * b,
  2912. x3:= 2 *a + 10.000000001* b,
  2913. x4:= 6 *a + 30 * b,
  2914. x5:= 2.0000000000001*a + 10.0000000000001 * b
  2915. INAME s
  2916. DECLARE <<x1,x2,x3,x4,x5,a,b: real>>$
  2917. DOUBLE PRECISION A,B,S1,S2,X1,X2,X3,X4,X5
  2918. S1=2*A
  2919. S2=10*B
  2920. X1=S2+S1
  2921. X2=S2+2.00000000001D0*A
  2922. X3=S1+1.0000000001D1*B
  2923. X4=3*X1
  2924. X5=X1
  2925. OPTIMIZE x1:=:2.00 *a + 10.00 * b,
  2926. x2:=:2.00000000001*a + 10 * b,
  2927. x3:=:2 *a + 10.000000001* b,
  2928. x4:=:6 *a + 30 * b,
  2929. x5:=:2.0000000000001*a + 10.0000000000001 * b
  2930. INAME s
  2931. DECLARE <<x1,x2,x3,x4,x5,a,b: real>>$
  2932. DOUBLE PRECISION A,B,S1,S2,X1,X2,X3,X4,X5
  2933. S1=2*A
  2934. S2=10*B
  2935. X1=S2+S1
  2936. X2=S2+2.0D0*A
  2937. X3=S1+10.0D0*B
  2938. X4=3*X1
  2939. X5=X1
  2940. % ---
  2941. % Observe that simplification prior to optimization leads to internal
  2942. % roundings, which differ from the rounding used for literally taken
  2943. % coefficients. This difference disappeares with ON ROUNDBF.
  2944. % ---
  2945. ON ROUNDBF$
  2946. OPTIMIZE x1:= 2.00 *a + 10.00 * b,
  2947. x2:= 2.00000000001*a + 10 * b,
  2948. x3:= 2 *a + 10.000000001* b,
  2949. x4:= 6 *a + 30 * b,
  2950. x5:= 2.0000000000001*a + 10.0000000000001 * b
  2951. INAME s
  2952. DECLARE <<x1,x2,x3,x4,x5,a,b: real>>$
  2953. DOUBLE PRECISION A,B,S1,S2,X1,X2,X3,X4,X5
  2954. S1=2*A
  2955. S2=10*B
  2956. X1=S2+S1
  2957. X2=S2+2.00000000001D0*A
  2958. X3=S1+1.0000000001D1*B
  2959. X4=3*X1
  2960. X5=X1
  2961. OPTIMIZE x1:=:2.00 *a + 10.00 * b,
  2962. x2:=:2.00000000001*a + 10 * b,
  2963. x3:=:2 *a + 10.000000001* b,
  2964. x4:=:6 *a + 30 * b,
  2965. x5:=:2.0000000000001*a + 10.0000000000001 * b
  2966. INAME s
  2967. DECLARE <<x1,x2,x3,x4,x5,a,b: real>>$
  2968. DOUBLE PRECISION A,B,S1,S2,X1,X2,X3,X4,X5
  2969. S1=2*A
  2970. S2=10*B
  2971. X1=S2+S1
  2972. X2=S2+2.00000000001D0*A
  2973. X3=S1+1.0000000001D1*B
  2974. X4=3*X1
  2975. X5=X1
  2976. % ---
  2977. % Complex arithmetic is not supported in SCOPE. However the Fortan equivalent
  2978. % of I, a protected name in REDUCE, is automatically created, ahead of the
  2979. % optimized code, whenever I is included in the declaration as a type complex
  2980. % or a type complex*16 identifier.
  2981. % ---
  2982. OPTIMIZE a:=b+c
  2983. INAME s
  2984. DECLARE <<a,b,i,c: complex>>;
  2985. COMPLEX*16 B,I,C,A
  2986. I=(0.0D0, 1.0D0)
  2987. A=B+C
  2988. OFF DOUBLE$
  2989. OPTIMIZE a:=b+c
  2990. INAME s
  2991. DECLARE <<a,b,i,c: complex>>;
  2992. COMPLEX B,I,C,A
  2993. I=(0.0, 1.0)
  2994. A=B+C
  2995. \end{verbatim}}
  2996. \begin{flushright}
  2997. $\Box$
  2998. \end{flushright}
  2999. \newpage
  3000. \section{Dealing with Data Dependencies}\label{SCOPE:dda}
  3001. \index{flow dependency}
  3002. \index{anti dependency}
  3003. \index{used identifiers}
  3004. \index{defined identifiers}
  3005. \index{dead code}
  3006. \index{data dependency analysis}
  3007. SCOPE is designed to optimize blocks $B$ of straight line code, i.e.
  3008. sequences of $n$ assignment statements $S_i$ of the
  3009. form ${\lambda}_i := {\rho}_i$, where $i = 1, \cdots , n$. If an identifier
  3010. occurs in ${\lambda}_i$, it is said to be {\em defined} in $S_i$. All
  3011. identifiers occuring in ${\rho}_i$ are said to be {\em used} in $S_i$.
  3012. The set DEF($S_i$)
  3013. is formed by the identifiers defining $S_i$, usually only one.
  3014. The set USE($S_i$) is formed by the identifiers, which are used in $S_i$.
  3015. The relation DEF($S_i$) $\in$ USE($S_j$), for $1 \leq i < j \leq n$, is
  3016. called a {\em flow dependency} and denoted by $S_i \rightarrow S_j$. The
  3017. relation DEF($S_i$) $\in$ USE($S_j$), for $1 \leq j \leq i \leq n$ is called
  3018. an {\em anti dependency} and denoted by $S_i$ \ad $S_j$. The {\em set of inputs}
  3019. of $B$, denoted by $I(B)$, consists of identifiers, which are used
  3020. in $B$, before being defined, if defined at all. The {\em set of outputs} of
  3021. $B$, denoted by $O(B)$, consists of the set of all last definitions of
  3022. identifiers, occuring in $B$. So a block of straight line code can be
  3023. introduced as a triple $B = \{ S, I, O \}$, where $S$ stands for the sequence
  3024. $S_1 ; S_2 ; \cdots ; S_{n-1} ; S_n$, and where $I$ and $O$ define the
  3025. inputs and outputs, respectively. When optimizing source code defined by $B$,
  3026. i.e. the sequence $S$, the intention is to mechanically produce an equivalent,
  3027. but computationally less complex sequence, preserving the relation between
  3028. inputs and outputs. Due to anti dependencies, i.e. redefinitions of the rules
  3029. for computing identifier values or stepwise computing such values,
  3030. $\mid O(B) \mid < n$ is possible. But that in turn implies that some of the
  3031. used identifiers, although being literally identical, represent different
  3032. values. Therefore, a mechanical search for cse's can only be maintained if
  3033. these critical identifiers are adequately renamed internally before the
  3034. optimization process itself is started. As long as the relation between
  3035. $I(B)$ and $O(B)$ is preserved it is even allowed to partly maintain these
  3036. additional names, when presenting the results of an optimization operation.
  3037. Furthermore it is worth noting that {\em dead code} can be left out, when
  3038. ever occuring. Such code can be introduced through redundant assignments.
  3039. The SCOPE features for dealing with data dependencies are illustrated, using
  3040. the following artificial piece of code:
  3041. \begin{center}
  3042. \[ \begin{array}{lclcl}
  3043. S_1 & : & a_{1,x+1} & := & g + h . r^f \\
  3044. S_2 & : & b_{y+1} & := & a_{1, 2.x+1} .(g + h . r^f) \\
  3045. S_3 & : & c1 & := & h.r. a_{2,1+x}/g \\
  3046. S_4 & : & c2 & := & c1 . a_{1,x+1} + sin(d) \\
  3047. S_5 & : & a_{1,x+1} & := & c1 + 2 \\
  3048. S_6 & : & d & := & b_{y+1} . a_{1,x+1} \\
  3049. S_7 & : & a_{1,1+2.x} & := & a_{1,x+1} . b_{y+1} . c/(d . g^2) \\
  3050. S_8 & : & b_{y+1} & := & a_{1.x+1} + b_{y+1} + sin(d) \\
  3051. S_9 & : & a_{1,x+1} & := & b_{y+1} . c + h/(g + sin(d))\\
  3052. S_{10} & : & d & := & k . e + d . (a_{1,1+x} + 3) \\
  3053. S_{11} & : & e & := & d . (a_{1,1+x} + 3) + sin(d) \\
  3054. S_{12} & : & f & := & d . (a_{1,1+x} + 3) + sin(d) \\
  3055. S_{13} & : & g & := & d . (3 + a_{1,1+x}) + f \\
  3056. \end{array}\]
  3057. \end{center}
  3058. The different flow and anti dependencies can be vizualized in the following way:
  3059. \begin{center}
  3060. \begin{tabular}{lcl}
  3061. $x$ & : & $\{ {\lambda}_1 , {\rho}_2 , {\rho}_3 , {\rho}_4 , {\lambda}_5 ,
  3062. {\rho}_6 , {\lambda}_7 , {\rho}_7 , {\rho}_8 ,{\lambda}_9 , {\rho}_{10} ,
  3063. {\rho}_{11} , {\rho}_{12} , {\rho}_{13} \}$ \\
  3064. $y$ & : & $\{ {\lambda}_2 , {\rho}_6 , {\rho}_7 , {\lambda}_8 , {\rho}_8 ,
  3065. {\rho}_9 \}$
  3066. \end{tabular}
  3067. \end{center}
  3068. The identifiers, occuring in the piece of code given above, can be defined,
  3069. can be used or can play both roles. Identifiers, used in one or more of the
  3070. $\lambda_i , i = 1 \cdots n$ figure in subscript expressions. The set
  3071. notation \{ $\cdots$ \} is used to explicitly describe USE sets. Since
  3072. all DEF sets consist of one element only, we omitted the set notation for the
  3073. DEF sets. This provides a simple tool to distinguish flow and anti dependencies:
  3074. \begin{center}
  3075. \begin{tabular}{lcl}
  3076. $a_{1,x+1}$ & : & ${\lambda}_1 \rightarrow \{ {\rho}_3 , {\rho}_4 \}$ \ad
  3077. ${\lambda}_5 \rightarrow \{ {\rho}_6 , {\rho}_7 , {\rho}_8 \}$ \ad
  3078. ${\lambda}_9 \rightarrow \{ {\rho}_{10} , {\rho}_{11} , {\rho}_{12} ,
  3079. {\rho}_{13} \}$ \\
  3080. $g$ & : & $\{ {\rho}_1 , {\rho}_2 , {\rho}_3 , {\rho}_7 , {\rho}_9 \}$ \ad
  3081. ${\lambda}_{13}$ \\
  3082. $h$ & : & $\{ {\rho}_1 , {\rho}_2 , {\rho}_3 , {\rho}_9 \}$ \\
  3083. $r$ & : & $\{ {\rho}_1 , {\rho}_2 , {\rho}_3 \}$ \\
  3084. $f$ & : & $\{ {\rho}_1 , {\rho}_2 \}$ \ad
  3085. ${\lambda}_{12} \rightarrow {\rho}_{13}$ \\
  3086. $b_{y+1}$ & : & ${\lambda}_2 \rightarrow \{ {\rho}_6 , {\rho}_7 , {\rho}_8 \}$ \ad ${\lambda}_8 \rightarrow \{ {\rho}_9 \}$ \\
  3087. $a_{1,2.x+1}$ & : & $\{ {\rho}_2 \}$ \ad ${\lambda}_7$ \\
  3088. $c1$ & : & ${\lambda}_3 \rightarrow \{ {\rho}_4 , {\rho}_5 \}$ \\
  3089. $a_{2,1+x}$ & : & $\{ {\rho}_3 \}$ \\
  3090. $c2$ & : & ${\lambda}_4$ \\
  3091. $d$ & : & $\{ {\rho}_4 \}$ \ad ${\lambda}_6 \rightarrow \{ {\rho}_7 ,
  3092. {\rho}_8 , {\rho}_9 , {\rho}_{10} \}$ \ad ${\lambda}_{10} \rightarrow
  3093. \{ {\rho}_{11} , {\rho}_{12} , {\rho}_{13} \}$ \\
  3094. $c$ & : & $\{ {\rho}_7 , {\rho}_9 \}$ \\
  3095. $k$ & : & $\{ {\rho}_{10} \}$ \\
  3096. $e$ & : & $\{ {\rho}_{10} \}$ \ad ${\lambda}_{12}$
  3097. \end{tabular}
  3098. \end{center}
  3099. We observe that
  3100. \[ I(B) = \{ x, y, g, h, r, f, a_{1,2.x+1} , a_{2,1+x} , d, c, k, e \} ,\]
  3101. \[ O(B) = \{ a_{1,x+1} , g, f, b_{y+1} , a_{1,2.x+1} , c1 , c2 , d, e\}\]
  3102. and thus, that
  3103. \[ I(B) \cap O(B) \neq \emptyset .\]
  3104. The identifiers $a_{1,1+x}$ and $d$ are redefined twice and the identifier
  3105. $b_{y+1}$ once. Only the input occurrences and the last
  3106. output definitions need to be preserved.
  3107. \index{output definition preservation}
  3108. \index{{\tt VECTORC} switch}
  3109. \index{SCOPE function ! {\tt VECTORCODE}}
  3110. We also observe that some of the identifiers are subscripted. In our example
  3111. the subscript expressions are constructed with input identifiers only. More
  3112. general situations are conceivable. The set of subscript expressions contains
  3113. cse's. Since our optimization strategy is based on an all level approach
  3114. expressions, like $1+x$ and $y+1$ are certainly discovered as cse's.
  3115. An {\tt OPTIMIZE} command can be extended with a {\tt DECLARE} option,
  3116. indicating that both $a$ and $b$ are array names. Their subscript expressions
  3117. are optimized. In addition, the $a$ and $b$ entries are considered to be
  3118. array entries, and not as function applications. The latter will happen when
  3119. the {\tt DECLARE} option is omitted. Vector architectures make often use of
  3120. machine specific optimizing compilers. Therefore it may be better not to
  3121. optimize the subset of subscript expressions. We implemented some facilities
  3122. to take such machine specific limitations into account. When turning {\tt ON}
  3123. the switch {\tt VECTORC} the finishing touch is omitted and subscript
  3124. expressions are not optimized. The function
  3125. \index{{\tt VECTORC} switch}
  3126. \hspace*{1cm} {\tt VECTORCODE} $<$a\_or\_m\_id\_seq$>$
  3127. can be used to operate more selectively. The a\_or\_m\_id\_seq consists of
  3128. one or more array and/or matrix names, separated by comma's. Only the
  3129. actual parameters of {\tt VECTORCODE} are assumed to be names of arrays. So
  3130. only their subscript expressions are disregarded during an optimization
  3131. process. We can undo the effect of the {\tt VECTORCODE} setting with a
  3132. command of the form:
  3133. \hspace*{1cm} {\tt VCLEAR} $<$a\_or\_m\_id\_(sub)seq$>$
  3134. \index{SCOPE function ! {\tt VCLEAR}}
  3135. The actual parameters are supposed to be taken from the sequence of actual
  3136. parameters of its counterpart, the function {\tt VECTORCODE}.
  3137. The different settings are now illustrated in:
  3138. \example\label{ex:7.1}
  3139. \index{SCOPE ! example}
  3140. The above given block of code $B = \{ S, I, O \}$ is optimized in five
  3141. different situations. To start with we hand it over to SCOPE, using an
  3142. {\tt OPTIMIZE} command, without using the {\tt DECLARE} option.
  3143. We observe, looking at the results, that some renaming of non significant
  3144. identifier
  3145. definitions have been performed. The first occurrence of $a_{1,1+x}$ is replaced
  3146. by {\tt s34}, the second by {\tt s4}. The first occurrence of $b_{y+1}$ is
  3147. replaced by {\tt s3}, but the occurrences of $d$, a scalar identifier,
  3148. are maintained.
  3149. Especially the role of the scalar $d$ is quite interesting. The first definition
  3150. of $d$ is given in $S_6$ In $S_7$ $d$ is used twice: explicitly in the
  3151. denominator and in a hidden way in the numerator as well. The optimized
  3152. version of $S_7$ shows a factor $d/d$. The reason is that $d$ locally replaces
  3153. an internally created cse name, substituted for ${\rho}_6$ and for part of the
  3154. numerator of ${\rho}_7$. Like illustrated in example~\ref{ex:3.2.7} a second
  3155. SCOPE application can further simplify ${\rho}_7$. The scalar $d$ is also used
  3156. as argument of the $sin$-function in $S_4 , S_8 , S_9 , S_{11}$ and $S_{12}$.
  3157. The $d$-values in $S_4$, in $\{ S_8 , S_9 \}$ and in $\{ S_{11} , S_{12} \}$
  3158. are all different, due to the redefinitions in $S_6$ and in $S_{10}$. Therefore
  3159. we recognize two different cse's, containing $sin(d)$: {\tt s24} and {\tt e}.
  3160. The role of $a_{1,x+1}$ is of course very similar, albeit less transparant,
  3161. due to the renamings.
  3162. The second run showes that adding a {\tt DECLARE}
  3163. option does not influence the form of the output in this particular case.
  3164. Besides the production of declarations, the result of both runs is identical.
  3165. All relevant input and output names are preserved in both runs.
  3166. {\small
  3167. \begin{verbatim}
  3168. OPTIMIZE a(1,x+1) := g+h*r^f,
  3169. b(y+1) := a(1,2*x+1)*(g+h*r^f),
  3170. c1 := (h*r)/g*a(2,1+x),
  3171. c2 := c1*a(1,x+1) + sin(d),
  3172. a(1,x+1) := c1^(5/2),
  3173. d := b(y+1)*a(1,x+1),
  3174. a(1,1+2*x):= (a(1,x+1)*b(y+1)*c)/(d*g^2),
  3175. b(y+1) := a(1,1+x)+b(y+1) + sin(d),
  3176. a(1,x+1) := b(y+1)*c+h/(g + sin(d)),
  3177. d := k*e+d*(a(1,1+x)+3),
  3178. e := d*(a(1,1+x)+3) + sin(d),
  3179. f := d*(3+a(1,x+1)) + sin(d),
  3180. g := d*(3+a(1,x+1))+f
  3181. INAME s$
  3182. s0 := x + 1
  3183. f
  3184. s34 := r *h + g
  3185. s2 := 1 + y
  3186. s6 := 2*x + 1
  3187. s3 := s34*a(1,s6)
  3188. r*h
  3189. c1 := a(2,s0)*-----
  3190. g
  3191. c2 := sin(d) + s34*c1
  3192. s4 := sqrt(c1)*c1*c1
  3193. d := s4*s3
  3194. d*c
  3195. a(1,s6) := -------
  3196. g*g*d
  3197. s24 := sin(d)
  3198. b(s2) := s4 + s3 + s24
  3199. h
  3200. a(1,s0) := --------- + b(s2)*c
  3201. g + s24
  3202. s29 := 3 + a(1,s0)
  3203. d := s29*d + e*k
  3204. s33 := s29*d
  3205. e := s33 + sin(d)
  3206. f := e
  3207. g := s33 + f
  3208. ON FORT$
  3209. OPTIMIZE a(1,x+1) := g+h*r^f,
  3210. b(y+1) := a(1,2*x+1)*(g+h*r^f),
  3211. c1 := (h*r)/g*a(2,1+x),
  3212. c2 := c1*a(1,x+1) + sin(d),
  3213. a(1,x+1) := c1^(5/2),
  3214. d := b(y+1)*a(1,x+1),
  3215. a(1,1+2*x):= (a(1,x+1)*b(y+1)*c)/(d*g^2),
  3216. b(y+1) := a(1,1+x)+b(y+1) + sin(d),
  3217. a(1,x+1) := b(y+1)*c+h/(g + sin(d)),
  3218. d := k*e+d*(a(1,1+x)+3),
  3219. e := d*(a(1,1+x)+3) + sin(d),
  3220. f := d*(3+a(1,x+1)) + sin(d),
  3221. g := d*(3+a(1,x+1))+f
  3222. INAME s
  3223. DECLARE <<a(5,5),b(7),c,c1,c2,d,f,g,h,r:real*8; x,y:integer>>$
  3224. INTEGER X,Y,S0,S2,S6
  3225. DOUBLE PRECISION C,H,R,S34,S3,C1,C2,S4,S24,B(7),A(5,5),S29,K,D,S33
  3226. . ,E,F,g
  3227. S0=X+1
  3228. S34=R**F*H+G
  3229. S2=1+Y
  3230. S6=2*X+1
  3231. S3=S34*A(1,S6)
  3232. C1=A(2,S0)*((R*H)/G)
  3233. C2=DSIN(D)+S34*C1
  3234. S4=DSQRT(C1)*C1*C1
  3235. D=S4*S3
  3236. A(1,S6)=(D*C)/(G*G*D)
  3237. S24=DSIN(D)
  3238. B(S2)=S4+S3+S24
  3239. A(1,S0)=H/(G+S24)+B(S2)*C
  3240. S29=3+A(1,S0)
  3241. D=S29*D+DEXP(1.0D0)*K
  3242. S33=S29*D
  3243. E=S33+DSIN(D)
  3244. F=DEXP(1.0D0)
  3245. G=S33+F
  3246. OFF FORT$
  3247. \end{verbatim}}
  3248. Observe the differences in the {\tt f} and {\tt F} assignments. When generating
  3249. {\tt fortran77} code all right hand side occurrences of {\tt e} are
  3250. automatically considered as appearances of the base of the natural logarithm
  3251. and are translated accordingly.
  3252. \index{{\tt VECTORC} switch}
  3253. \index{SCOPE function ! {\tt VECTORCODE}}
  3254. \index{SCOPE function ! {\tt VCLEAR}}
  3255. The third run is influenced by turning {\tt ON} the switch {\tt VECTORC}.
  3256. We observe that all array references are substituted back, without having
  3257. replaced repeatedly occuring identical subscript expressions by internally
  3258. selected cse names.
  3259. The fourth and the last run are governed by the functions {\tt VECTORCODE} and
  3260. {\tt VCLEAR}, after having turned {\tt OFF} the switch {\tt VECTORC}.
  3261. {\small
  3262. \begin{verbatim}
  3263. ON VECTORC$
  3264. OPTIMIZE a(1,x+1) := g+h*r^f,
  3265. b(y+1) := a(1,2*x+1)*(g+h*r^f),
  3266. c1 := (h*r)/g*a(2,1+x),
  3267. c2 := c1*a(1,x+1) + sin(d),
  3268. a(1,x+1) := c1^(5/2),
  3269. d := b(y+1)*a(1,x+1),
  3270. a(1,1+2*x):= (a(1,x+1)*b(y+1)*c)/(d*g^2),
  3271. b(y+1) := a(1,1+x)+b(y+1) + sin(d),
  3272. a(1,x+1) := b(y+1)*c+h/(g + sin(d)),
  3273. d := k*e+d*(a(1,1+x)+3),
  3274. e := d*(a(1,1+x)+3) + sin(d),
  3275. f := d*(3+a(1,x+1)) + sin(d),
  3276. g := d*(3+a(1,x+1))+f
  3277. INAME s$
  3278. f
  3279. a(1,x + 1) := r *h + g
  3280. b(y + 1) := a(1,x + 1)*a(1,2*x + 1)
  3281. r*h
  3282. c1 := a(2,x + 1)*-----
  3283. g
  3284. c2 := sin(d) + a(1,x + 1)*c1
  3285. 2
  3286. a(1,x + 1) := sqrt(c1)*c1
  3287. d := a(1,x + 1)*b(y + 1)
  3288. \end{verbatim}}
  3289. \newpage
  3290. {\small
  3291. \begin{verbatim}
  3292. d*c
  3293. a(1,1 + 2*x) := ------
  3294. 2
  3295. g *d
  3296. s20 := sin(d)
  3297. b(y + 1) := a(1,x + 1) + b(y + 1) + s20
  3298. h
  3299. a(1,x + 1) := --------- + b(y + 1)*c
  3300. g + s20
  3301. s25 := a(1,x + 1) + 3
  3302. d := s25*d + e*k
  3303. s28 := s25*d
  3304. e := s28 + sin(d)
  3305. f := e
  3306. g := s28 + f
  3307. OFF VECTORC$
  3308. VECTORCODE a,b$
  3309. OPTIMIZE a(1,x+1) := g+h*r^f,
  3310. b(y+1) := a(1,2*x+1)*(g+h*r^f),
  3311. c1 := (h*r)/g*a(2,1+x),
  3312. c2 := c1*a(1,x+1) + sin(d),
  3313. a(1,x+1) := c1^(5/2),
  3314. d := b(y+1)*a(1,x+1),
  3315. a(1,1+2*x):= (a(1,x+1)*b(y+1)*c)/(d*g^2),
  3316. b(y+1) := a(1,1+x)+b(y+1) + sin(d),
  3317. a(1,x+1) := b(y+1)*c+h/(g + sin(d)),
  3318. d := k*e+d*(a(1,1+x)+3),
  3319. e := d*(a(1,1+x)+3) + sin(d),
  3320. f := d*(3+a(1,x+1)) + sin(d),
  3321. g := d*(3+a(1,x+1))+f
  3322. INAME s$
  3323. f
  3324. a(1,x + 1) := r *h + g
  3325. b(y + 1) := a(1,x + 1)*a(1,2*x + 1)
  3326. r*h
  3327. c1 := a(2,x + 1)*-----
  3328. g
  3329. c2 := sin(d) + a(1,x + 1)*c1
  3330. a(1,x + 1) := sqrt(c1)*c1*c1
  3331. d := a(1,x + 1)*b(y + 1)
  3332. d*c
  3333. a(1,1 + 2*x) := -------
  3334. g*g*d
  3335. s22 := sin(d)
  3336. b(y + 1) := a(1,x + 1) + b(y + 1) + s22
  3337. h
  3338. a(1,x + 1) := --------- + b(y + 1)*c
  3339. g + s22
  3340. s27 := 3 + a(1,x + 1)
  3341. d := s27*d + e*k
  3342. s30 := s27*d
  3343. e := s30 + sin(d)
  3344. f := e
  3345. g := s30 + f
  3346. VCLEAR b$
  3347. OPTIMIZE a(1,x+1) := g+h*r^f,
  3348. b(y+1) := a(1,2*x+1)*(g+h*r^f),
  3349. c1 := (h*r)/g*a(2,1+x),
  3350. c2 := c1*a(1,x+1) + sin(d),
  3351. a(1,x+1) := c1^(5/2),
  3352. d := b(y+1)*a(1,x+1),
  3353. a(1,1+2*x):= (a(1,x+1)*b(y+1)*c)/(d*g^2),
  3354. b(y+1) := a(1,1+x)+b(y+1) + sin(d),
  3355. a(1,x+1) := b(y+1)*c+h/(g + sin(d)),
  3356. d := k*e+d*(a(1,1+x)+3),
  3357. e := d*(a(1,1+x)+3) + sin(d),
  3358. f := d*(3+a(1,x+1)) + sin(d),
  3359. g := d*(3+a(1,x+1))+f
  3360. INAME s$
  3361. f
  3362. a(1,x + 1) := r *h + g
  3363. s1 := y + 1
  3364. s2 := a(1,x + 1)*a(1,1 + 2*x)
  3365. r*h
  3366. c1 := a(2,1 + x)*-----
  3367. g
  3368. c2 := sin(d) + a(1,x + 1)*c1
  3369. a(1,x + 1) := sqrt(c1)*c1*c1
  3370. d := a(1,x + 1)*s2
  3371. d*c
  3372. a(1,1 + 2*x) := -------
  3373. g*g*d
  3374. s23 := sin(d)
  3375. b(s1) := a(1,x + 1) + s2 + s23
  3376. h
  3377. a(1,x + 1) := --------- + b(s1)*c
  3378. g + s23
  3379. s28 := 3 + a(1,x + 1)
  3380. d := s28*d + e*k
  3381. s31 := s28*d
  3382. e := s31 + sin(d)
  3383. f := e
  3384. g := s31 + f
  3385. \end{verbatim}
  3386. \begin{flushright}
  3387. $\Box$
  3388. \end{flushright}}
  3389. \newpage
  3390. \section{A Combined Use of GENTRAN and SCOPE 1.5}\label{SCOPE:gopt}
  3391. \index{{\tt GENTRANOPT} switch}
  3392. As already stated in subsection~\ref{SCOPE:inter} each GENTRAN command is
  3393. evaluated separately, implying that the symbol table, required
  3394. for the production of declarations, is fresh at the beginning of a GENTRAN
  3395. command evaluation. Turning {\tt ON} the switch {\tt GENTRANOPT} leads to
  3396. the optimization of the arithmetic code, defined in the GENTRAN command,
  3397. obeying the new {\tt GENTRANOPT} regime. In addition, we can observe that
  3398. each separate GENTRAN command can produce its own declarations.
  3399. \index{{\tt GENTRANOPT} switch}
  3400. To increase flexibility we introduced facilities for making declarations,
  3401. associated with a group of GENTRAN commands and for the optimization of
  3402. the arithmetic in such a group as well.
  3403. We implemented two function pairs of parameter-less functions:
  3404. \hspace{1cm} ({\tt DELAYDECS}, {\tt MAKEDECS})
  3405. \index{SCOPE function ! {\tt DELAYDECS}}
  3406. \index{SCOPE function ! {\tt MAKEDECS}}
  3407. and
  3408. \hspace{1cm} ({\tt DELAYOPTS}, {\tt MAKEOPTS}).
  3409. \index{SCOPE function ! {\tt DELAYOPTS}}
  3410. \index{SCOPE function ! {\tt MAKEOPTS}}
  3411. Both pairs function as "brackets" around groups of statements. The {\tt OPTS}
  3412. pair can be used (repeatedly) inside a {\tt DECS} pair. Both pairs achieve
  3413. an alterned GENTRAN mode of operation. All GENTRAN productions between such
  3414. a pair are collected in an internal format, say {\tt if\_list}.
  3415. The {\tt DELAY...} functions initialize the modified mode of operation.
  3416. The {\tt MAKE...} functions restore the previous mode of operation in
  3417. combination with the production either of declarations, associated with the
  3418. contents of {\tt if\_list}, or of an optimized representation of the
  3419. contents of {\tt if\_list}.
  3420. Example~\ref{ex:8.1} serves to introduce a variety of approaches to code
  3421. generation, based on the use of these pairs of brackets and of the
  3422. switch {\tt GENTRANOPT}. We illustrate a more realistic use in
  3423. example~\ref{ex:8.2}: generation of optimized fortran77 code for the
  3424. computation of the entries of the inverse of a symmetric (3,3) matrix.
  3425. It is a continuation of example~\ref{ex:3.1.8} in
  3426. subsection~\ref{SCOPE:optim} and example~\ref{ex:3.2.5} in
  3427. subsection ~\ref{SCOPE:algo}. It was also presented
  3428. in ~\cite{Gates:85}, albeit in a slightly different form.
  3429. \example\label{ex:8.1}
  3430. \index{SCOPE ! example}
  3431. The output of combined GENTRAN and SCOPE operations is by default given
  3432. in fortran77 notation. We illustrate the different possibilities in the
  3433. form of small pieces of code.
  3434. \begin{itemize}
  3435. \item The pair ({\tt DELAYDECS}, {\tt MAKEDECS}) encloses four GENTRAN commands.
  3436. The first is needed to initialize the symbol table. The literal translation in
  3437. internal format of the last three commands is stored in the {\tt if\_list}.
  3438. The application of {\tt MAKEDECS} leads to the restoration of the default
  3439. GENTRAN regime, applied to the {\tt if\_list} and leading to the result,
  3440. presented in the form of fortran77 code.
  3441. {\small
  3442. \begin{verbatim}
  3443. DELAYDECS$
  3444. GENTRAN DECLARE <<a,b,c,d,q,w:real>>$
  3445. GENTRAN a:=b+c$
  3446. GENTRAN d:=b+c$
  3447. GENTRAN <<q:=b+c;w:=b+c>>$
  3448. MAKEDECS$
  3449. REAL A,B,C,D,Q,W
  3450. A=B+C
  3451. D=B+C
  3452. Q=B+C
  3453. W=B+C
  3454. \end{verbatim}}
  3455. \item We repeat the previous commands, but execute them in a slightly different
  3456. setting by turning {\tt ON} the switch {\tt GENTRANOPT}. This time the
  3457. arithmetical rules in each of the three last GENTRAN commands are optimized
  3458. separately. This is illustrated by the form of the output. The last piece of
  3459. code contains the cse {\tt B+C}, which is presented under the name {\tt Q}
  3460. in the fortran77 output.
  3461. \index{{\tt GENTRANOPT} switch}
  3462. \index{SCOPE function ! {\tt DELAYDECS}}
  3463. \index{SCOPE function ! {\tt MAKEDECS}}
  3464. \index{SCOPE function ! {\tt DELAYOPTS}}
  3465. \index{SCOPE function ! {\tt MAKEOPTS}}
  3466. {\small
  3467. \begin{verbatim}
  3468. ON GENTRANOPT$
  3469. DELAYDECS$
  3470. GENTRAN DECLARE <<a,b,c,d,q,w:real>>$
  3471. GENTRAN a:=b+c$
  3472. GENTRAN d:=b+c$
  3473. GENTRAN <<q:=b+c;w:=b+c>>$
  3474. MAKEDECS$
  3475. REAL B,C,A,D,Q,W
  3476. A=B+C
  3477. D=B+C
  3478. Q=B+C
  3479. W=Q
  3480. OFF GENTRANOPT$
  3481. \end{verbatim}}
  3482. \item We can improve the optimization strategy by using the function pair
  3483. ({\tt DELAYOPTS}, {\tt MAKEOPTS}) in stead of the
  3484. pair ({\tt DELAYDECS}, {\tt MAKEDECS}). All blockwise combinable arithmetic
  3485. is collected. These blocks of straight line code are optimized as separate
  3486. input sets ${\rm E_{in}}$, when activating {\tt MAKEOPTS}.
  3487. {\small
  3488. \begin{verbatim}
  3489. DELAYOPTS$
  3490. GENTRAN a:=b+c$
  3491. GENTRAN d:=b+c$
  3492. GENTRAN <<q:=b+c;w:=b+c>>$
  3493. MAKEOPTS$
  3494. A=B+C
  3495. D=A
  3496. Q=A
  3497. W=A
  3498. \end{verbatim}}
  3499. \item We can furhter improve the optimization strategy by using the
  3500. function pair ({\tt DELAYOPTS}, {\tt MAKEOPTS}) inside the
  3501. pair ({\tt DELAYDECS}, {\tt MAKEDECS}). All blockwise combinable arithmetic
  3502. is collected. These blocks of straight line code are optimized as separate
  3503. input sets ${\rm E_{in}}$, when activating {\tt MAKEOPTS}. But this time the
  3504. results are added in internal format to the {\tt if\_list} version,
  3505. being maintained, as to obey the {\tt DELAYDECS} regime.
  3506. {\small
  3507. \begin{verbatim}
  3508. DELAYDECS$
  3509. GENTRAN DECLARE <<a,b,c,d,q,w:real>>$
  3510. DELAYOPTS$
  3511. GENTRAN a:=b+c$
  3512. GENTRAN d:=b+c$
  3513. GENTRAN <<q:=b+c;w:=b+c>>$
  3514. MAKEOPTS$
  3515. MAKEDECS$
  3516. REAL B,C,A,D,Q,W
  3517. A=B+C
  3518. D=A
  3519. Q=A
  3520. W=A
  3521. \end{verbatim}}
  3522. \item A slightly more realistic example suggests how easily optimized code
  3523. for sets of matrix entries can be obtained. We use two identical matrices
  3524. {\tt a} and {\tt d}. The latter is not introduced at the {\REDUCE} level,
  3525. but simply used inside a GENTRAN command. The entries of {\tt a} are
  3526. initialized inside a double for-loop. After each initialization a GENTRAN
  3527. command is applied, using the special assignment operator {\tt ::=:} for
  3528. correctly combining entry names and entry values. The REDUCE algebraic mode
  3529. assignments are again used, when identifying the matrix {\tt d} with the
  3530. matrix {\tt a}, applying the special assignment operator {\tt :=:} in a
  3531. separate GENTRAN command. The latter command is internally expanded into
  3532. separate GENTRAN commands for each entry assignment. By using the pair
  3533. ({\tt DELAYOPTS}, {\tt MAKEOPTS}) one block of straigt line code is
  3534. constructed and optimized. It consists of two sets of assignments, one
  3535. for the entries of the matrix {\tt a} and another for the entries of the
  3536. matrix {\tt d}. The presented output shows that both matrices are indeed
  3537. identical.
  3538. {\small
  3539. \begin{verbatim}
  3540. MATRIX a(4,4);
  3541. DELAYDECS$
  3542. GENTRAN DECLARE <<a(4,4),d(4,4),b,c:real>>$
  3543. DELAYOPTS$
  3544. FOR i:=1:4 DO FOR j:=1:4 DO << a(i,j):=(i+j)*(b+c)+i*b+j*c;
  3545. GENTRAN a(i,j)::=:a(i,j)>>$
  3546. GENTRAN d:=:a$
  3547. MAKEOPTS$
  3548. MAKEDECS$
  3549. REAL B,C,G56,G54,G57,G55,A(4,4),D(4,4)
  3550. A(1,1)=3.0*(B+C)
  3551. G56=5.0*C
  3552. A(1,2)=G56+4.0*B
  3553. G54=5.0*B
  3554. G57=7.0*C
  3555. A(1,3)=G57+G54
  3556. A(1,4)=6.0*B+9.0*C
  3557. A(2,1)=G54+4.0*c
  3558. A(2,2)=2.0*A(1,1)
  3559. G55=7.0*B
  3560. A(2,3)=G55+8.0*C
  3561. A(2,4)=2.0*A(1,2)
  3562. A(3,1)=G56+G55
  3563. A(3,2)=G57+8.0*B
  3564. A(3,3)=3.0*A(1,1)
  3565. A(3,4)=10.0*B+11.0*C
  3566. A(4,1)=9.0*B+6.0*C
  3567. A(4,2)=2.0*A(2,1)
  3568. A(4,3)=11.0*B+10.0*C
  3569. A(4,4)=4.0*A(1,1)
  3570. D(1,1)=A(1,1)
  3571. D(1,2)=A(1,2)
  3572. D(1,3)=A(1,3)
  3573. D(1,4)=A(1,4)
  3574. D(2,1)=A(2,1)
  3575. D(2,2)=A(2,2)
  3576. D(2,3)=A(2,3)
  3577. D(2,4)=A(2,4)
  3578. D(3,1)=A(3,1)
  3579. D(3,2)=A(3,2)
  3580. D(3,3)=A(3,3)
  3581. D(3,4)=A(3,4)
  3582. D(4,1)=A(4,1)
  3583. D(4,2)=A(4,2)
  3584. D(4,3)=A(4,3)
  3585. D(4,4)=A(4,4)
  3586. \end{verbatim}}
  3587. \item Finally, and again only for illustrative purposes the fifth piece of
  3588. code is again executed in an almost identical manner. We omit the declarations
  3589. and replace the instruction {\tt GENTRAN d:=:a}\verb+$+ by the command
  3590. {\tt GENTRAN a:=:a}\verb+$+. Hence the matrix a is simply redefined. As
  3591. stated in section~\ref{SCOPE:dda} redundant assignments --- producing dead
  3592. code, for instance by copying previous assignments --- are automatically
  3593. removed. as part of the optimization process. Therefore the optimized
  3594. entry values of the matrix {\tt a} are presented only once.
  3595. {\small
  3596. \begin{verbatim}
  3597. DELAYOPTS$
  3598. FOR i:=1:4 DO FOR j:=1:4 DO << a(i,j):=(i+j)*(b+c)+i*b+j*c;
  3599. GENTRAN a(i,j)::=:a(i,j)>>$
  3600. GENTRAN a:=:a$
  3601. MAKEOPTS$
  3602. A(1,1)=3.0*(B+C)
  3603. G111=5.0*C
  3604. A(1,2)=G111+4.0*B
  3605. G109=5.0*B
  3606. G112=7.0*C
  3607. A(1,3)=G112+G109
  3608. A(1,4)=6.0*B+9.0*C
  3609. A(2,1)=G109+4.0*C
  3610. A(2,2)=2.0*A(1,1)
  3611. G110=7.0*B
  3612. A(2,3)=G110+8.0*C
  3613. A(2,4)=2.0*A(1,2)
  3614. A(3,1)=G111+G110
  3615. A(3,2)=G112+8.0*B
  3616. A(3,3)=3.0*A(1,1)
  3617. A(3,4)=10.0*B+11.0*C
  3618. A(4,1)=9.0*B+6.0*C
  3619. A(4,2)=2.0*A(2,1)
  3620. A(4,3)=11.0*B+10.0*C
  3621. A(4,4)=4.0*A(1,1)
  3622. \end{verbatim}}
  3623. \end{itemize}
  3624. {\small
  3625. \begin{flushright}
  3626. $\Box$
  3627. \end{flushright}}
  3628. \example\label{ex:8.2}
  3629. \index{SCOPE ! example}
  3630. Let us now again look at the symmetric (3,3) matrix {\tt m}, already used in
  3631. the examples ~\ref{ex:3.1.8} and ~\ref{ex:3.2.5}. For completeness we begin
  3632. by showing the entry values. We generate optimized fortran77 code
  3633. for the inverse {\tt mnv} of {\tt m} and store it in a file,
  3634. named {\tt inverse.code}, using the function pair ({\tt GENTRANOUT},
  3635. {\tt GENTRANSHUT}). Inside this pair we apply the pair ({\tt DELAYDECS},
  3636. {\tt MAKEDECS}). The latter pair encloses in turn the pair ({\tt DELAYOPTS},
  3637. {\tt MAKEOPTS}). Inside these innermost brackets four different sections of
  3638. code can be distinguished. The first section consists of three {\tt LITERAL}
  3639. commands, for inserting comment in the target code. The second is formed by
  3640. a double for-loop. Essential are the applications of the GENTRAN functions
  3641. {\tt tempvar} and {\tt markvar} for assigning internal names to matrix entry
  3642. values. These applications are very similar to the approach, chosen in
  3643. example~\ref{ex:3.2.5}. The third section is again formed by {\tt LITERAL}
  3644. commands and the last orders the creation of the entries of the inverse
  3645. matrix {\tt mnv}. Before introducing the file {\tt inverse.code} we selected
  3646. {\tt S0} as initial cse name, using the function {\tt INAME}, and
  3647. turned {\tt ON} the switches {\tt ACINFO} and {\tt DOUBLE}.
  3648. \index{GENTRAN function ! {\tt GENTRANOUT}}
  3649. \index{GENTRAN function ! {\tt GENTRANSHUT}}
  3650. \index{{\tt ACINFO} switch}
  3651. \index{{\tt DOUBLE} switch}
  3652. \index{SCOPE function ! {\tt INAME}}
  3653. \index{GENTRAN's {\tt DECLARE} statement}
  3654. \index{GENTRAN's {\tt LITERAL} statement}
  3655. \index{REDUCE function ! {\tt gensym}}
  3656. Observe that directly after the {\tt MAKEOPTS} instruction two sets of tables
  3657. are printed with information about the arithmetic complexity of the two blocks
  3658. of code, which are generated in the second and the last section. We
  3659. activated {\tt ACINFO} to show this effect. The tables are printed as
  3660. a side effect. The output itself is directed to the file {\tt inverse.code}.
  3661. Looking at the contents of this file, given below, shows three different
  3662. kinds of internally generated names. A number of {\tt S}-names is created
  3663. during the optimization of the first block of straight line code, created with
  3664. the second section. In this piece of code we also notice {\tt T}-names,
  3665. generated by {\tt tempvar} applications. The intial {\tt T} character is the
  3666. default internal GENTRAN selection for {(temporarily needed) names.
  3667. And finally {\tt G}-names, introduced by
  3668. applications of {\tt gensym}, during the second optimization operation for
  3669. reducing the arithmetic complexity of the entries of {\tt mnv}. Because the
  3670. code splitting is internally performed, the second SCOPE application
  3671. is missing its {\tt INAME} initialisation, thus leading to the application of
  3672. {\tt gensym}. Observe as well that {\tt INAME} can be used as a separate
  3673. facility as well.
  3674. {\small
  3675. \begin{verbatim}
  3676. OFF EXP$
  3677. MATRIX m(3,3),mnv(3,3)$
  3678. IN "matrix.M"$
  3679. m(1,1) := - ((j30y - j30z + 9*m30*p )*sin(q3)
  3680. 2 2
  3681. - 18*cos(q2)*cos(q3)*m30*p - j10y - j30y - m10*p
  3682. 2
  3683. - 18*m30*p )
  3684. 2 2
  3685. m(2,1) := m(1,2) := - ((j30y - j30z + 9*m30*p )*sin(q3)
  3686. 2 2
  3687. - 9*cos(q2)*cos(q3)*m30*p - j30y - 9*m30*p )
  3688. 2
  3689. m(3,1) := m(1,3) := - 9*sin(q2)*sin(q3)*m30*p
  3690. 2 2 2
  3691. m(2,2) := - ((j30y - j30z + 9*m30*p )*sin(q3) - j30y - 9*m30*p )
  3692. m(3,2) := m(2,3) := 0
  3693. 2
  3694. m(3,3) := j30x + 9*m30*p
  3695. INAME s0$
  3696. ON ACINFO,DOUBLE$
  3697. GENTRANOUT "inverse.code"$
  3698. DELAYDECS$
  3699. GENTRAN DECLARE <<mnv(3,3),p,m30,j30y,j30z,q3,m10,q2,j10y,j30x:real>>$
  3700. DELAYOPTS$
  3701. GENTRAN LITERAL "C",tab!*," ",cr!*$
  3702. GENTRAN LITERAL "C",tab!*," -- Computation of relevant M-entries --",cr!*$
  3703. GENTRAN LITERAL "C",tab!*," ",cr!*$
  3704. FOR j:=1:3 DO FOR k:=j:3 DO
  3705. IF m(j,k) NEQ 0 THEN
  3706. << s:=tempvar('real); markvar s;
  3707. GENTRAN eval(s):=:m(j,k);
  3708. m(j,k):=m(k,j):=s
  3709. >>$
  3710. \end{verbatim}}
  3711. \index{GENTRAN function ! {\tt markvar}}
  3712. \index{GENTRAN function ! {\tt tempvar}}
  3713. {\small
  3714. \begin{verbatim}
  3715. GENTRAN LITERAL "C",tab!*," ",cr!*$
  3716. GENTRAN LITERAL "C",tab!*," -- Computation of the inverse of M --",cr!*$
  3717. GENTRAN LITERAL "C",tab!*," ",cr!*$
  3718. GENTRAN mnv:=:m^(-1)$
  3719. MAKEOPTS$
  3720. Number of operations in the input is:
  3721. Number of (+/-) operations : 17
  3722. Number of unary - operations : 4
  3723. Number of * operations : 30
  3724. Number of integer ^ operations : 14
  3725. Number of / operations : 0
  3726. Number of function applications : 9
  3727. Number of operations after optimization is:
  3728. Number of (+/-) operations : 11
  3729. Number of unary - operations : 1
  3730. Number of * operations : 12
  3731. Number of integer ^ operations : 0
  3732. Number of / operations : 0
  3733. Number of function applications : 4
  3734. Number of operations in the input is:
  3735. Number of (+/-) operations : 20
  3736. Number of unary - operations : 4
  3737. Number of * operations : 45
  3738. Number of integer ^ operations : 20
  3739. Number of / operations : 9
  3740. Number of function applications : 0
  3741. Number of operations after optimization is:
  3742. Number of (+/-) operations : 4
  3743. Number of unary - operations : 2
  3744. Number of * operations : 11
  3745. Number of integer ^ operations : 0
  3746. Number of / operations : 4
  3747. Number of function applications : 0
  3748. MAKEDECS$
  3749. GENTRANSHUT "inverse.code"$
  3750. \end{verbatim}}
  3751. The contents of the file {\tt inverse.code} is:
  3752. {\small
  3753. \begin{verbatim}
  3754. DOUBLE PRECISION P,M30,J30Y,J30Z,Q3,M10,Q2,J10Y,J30X,S0,S7,S5,S4,
  3755. . S13,S11,T0,T3,T1,T2,T4,G153,G152,G151,G147,G155,G156,MNV(3,3)
  3756. C
  3757. C -- Computation of relevant M-entries --
  3758. C
  3759. S0=DSIN(Q3)
  3760. S7=P*P
  3761. S5=S7*M30
  3762. S4=S5*DCOS(Q3)*DCOS(Q2)
  3763. S13=9.0D0*S5
  3764. S11=(S13+J30Y-J30Z)*S0*S0
  3765. T0=J30Y+J10Y+18.0D0*(S4+S5)+S7*M10-S11
  3766. T3=S13+J30Y-S11
  3767. T1=T3+9.0D0*S4
  3768. T2=-(S13*DSIN(Q2)*S0)
  3769. T4=S13+J30X
  3770. C
  3771. C -- Computation of the inverse of M --
  3772. C
  3773. G153=T2*T2
  3774. G152=T1*T1
  3775. G151=T0*T4
  3776. G147=G151*T3-(G153*T3)-(G152*T4)
  3777. G155=T4/G147
  3778. MNV(1,1)=G155*T3
  3779. MNV(1,2)=-(G155*T1)
  3780. G156=T2/G147
  3781. MNV(1,3)=-(G156*T3)
  3782. MNV(2,1)=MNV(1,2)
  3783. MNV(2,2)=(G151-G153)/G147
  3784. MNV(2,3)=G156*T1
  3785. MNV(3,1)=MNV(1,3)
  3786. MNV(3,2)=MNV(2,3)
  3787. MNV(3,3)=(T0*T3-G152)/G147
  3788. \end{verbatim}}
  3789. Let us now repeat the generation process in a slightly different setting.
  3790. We leave out the comment generating instructions, thus creating only one
  3791. block of straight line code to be optimized. We choose for an {\tt S}-name
  3792. selection based on {\tt tempvar} applications and for {\tt T}-names for cse's.
  3793. This time the default use of {\tt gensym} is not necessary.
  3794. The contents' of both output files illustrate quotient optimization.
  3795. All denominators, being the determinant of the matrix {\tt m}, are identical.
  3796. The set of rational entries of {\tt MNV} contains the cse's {\tt G155 (T45)}
  3797. and {\tt G156 (T46)}.
  3798. \index{GENTRAN identifier !{\tt TEMPVARNAME*}}
  3799. \index{GENTRAN identifier !{\tt TEMPVARNUM*}}
  3800. \index{GENTRAN function ! {\tt GENTRANOUT}}
  3801. \index{SCOPE function ! {\tt INAME}}
  3802. {\small
  3803. \begin{verbatim}
  3804. TEMPVARNAME!*:='s$
  3805. TEMPVARNUM!*:=0$
  3806. INAME t0$
  3807. GENTRANOUT "inverse.code2"$
  3808. DELAYDECS$
  3809. GENTRAN DECLARE <<mnv(3,3),p,m30,j30y,j30z,q3,m10,q2,j10y,j30x:real>>$
  3810. DELAYOPTS$
  3811. FOR j:=1:3 DO FOR k:=j:3 DO
  3812. IF m(j,k) NEQ 0 THEN
  3813. << s:=tempvar('real); markvar(s);
  3814. GENTRAN eval(s):=:m(j,k);
  3815. m(j,k):=m(k,j):=s
  3816. >>$
  3817. GENTRAN mnv:=:m^(-1)$
  3818. MAKEOPTS$
  3819. Number of operations in the input is:
  3820. Number of (+/-) operations : 37
  3821. Number of unary - operations : 8
  3822. Number of * operations : 75
  3823. Number of integer ^ operations : 34
  3824. Number of / operations : 9
  3825. Number of function applications : 9
  3826. Number of operations after optimization is:
  3827. Number of (+/-) operations : 15
  3828. Number of unary - operations : 3
  3829. Number of * operations : 23
  3830. Number of integer ^ operations : 0
  3831. Number of / operations : 4
  3832. Number of function applications : 4
  3833. MAKEDECS$
  3834. GENTRANSHUT "inverse.code2"$
  3835. \end{verbatim}}
  3836. The contents of the file {\tt inverse.code2} is:
  3837. {\small
  3838. \begin{verbatim}
  3839. DOUBLE PRECISION P,M30,J30Y,J30Z,Q3,M10,Q2,J10Y,J30X,T9,T40,T32,
  3840. . T31,T49,T47,S0,S3,S1,S2,S4,T39,T38,T36,T30,T45,T46,MNV(3,3)
  3841. T9=DSIN(Q3)
  3842. T40=P*P
  3843. T32=T40*M30
  3844. T31=T32*DCOS(Q3)*DCOS(Q2)
  3845. T49=9.0D0*T32
  3846. T47=(T49+J30Y-J30Z)*T9*T9
  3847. S0=J30Y+J10Y+18.0D0*(T31+T32)+T40*M10-T47
  3848. S3=T49+J30Y-T47
  3849. S1=S3+9.0D0*T31
  3850. S2=-(T49*DSIN(Q2)*T9)
  3851. S4=T49+J30X
  3852. T39=S2*S2
  3853. T38=S1*S1
  3854. T36=S0*S4
  3855. T30=T36*S3-(T39*S3)-(T38*S4)
  3856. T45=S4/T30
  3857. MNV(1,1)=T45*S3
  3858. MNV(1,2)=-(T45*S1)
  3859. T46=S2/T30
  3860. MNV(1,3)=-(T46*S3)
  3861. MNV(2,1)=MNV(1,2)
  3862. MNV(2,2)=(T36-T39)/T30
  3863. MNV(2,3)=T46*S1
  3864. MNV(3,1)=MNV(1,3)
  3865. MNV(3,2)=MNV(2,3)
  3866. MNV(3,3)=(S0*S3-T38)/T30
  3867. \end{verbatim}}
  3868. A comparison between the arithmetic complexities given here and in example
  3869. ~\ref{ex:3.2.5} shows that computing the entries of {\tt MNV}(=${\tt M}^{-1}$)
  3870. instead of the value of the determinant of {\tt M}, only requires 2
  3871. extra additions, 1 extra negation, 6 extra multilications and 4 extra
  3872. divisions.
  3873. {\small
  3874. \begin{flushright}
  3875. $\Box$
  3876. \end{flushright}}
  3877. Other examples of this combined use of GENTRAN and SCOPE can be found
  3878. in ~\cite{vanHulzen:95,Ganzha:94}. The symbolic-numeric strategy discussed in
  3879. ~\cite{Ganzha:94} also relies on the {\tt ALGOPT} facilities, which were
  3880. introduced earlier.
  3881. \newpage
  3882. \section{Symbolic Mode Use of SCOPE 1.5}~\label{SCOPE:symb}
  3883. Both the {\tt OPTIMIZE} command and the {\tt ALGOPT} function are transformed
  3884. into the same symbolic mode function, called {\tt SYMOPTIMIZE}. It is this
  3885. function, which governs the optimization process as a whole, delivering
  3886. the results of an optimization run as a side effect, for instance by making
  3887. it visible on a screen or by storing it in a file. Using {\tt SYMOPTIMIZE}
  3888. is straighforward, once the syntax for its five actual parameters is known.
  3889. If we set {\tt ON INTERN} a {\tt SYMOPTIMIZE} application will deliver a
  3890. list, containing the correctly ordered results of an optimization operation
  3891. in the form of assignment statements in prefix form in Lisp notation. The thus
  3892. provided results can function as one of the five actual parameters for
  3893. {\tt SYMOPTIMIZE} as well. This simple feature helps avoiding file traffic
  3894. when stepwise optimizing code and as illustrated earlier in example~\ref{ex:5.1}
  3895. in section ~\ref{SCOPE:files}. Before illustrating that in example~\ref{ex:9.1}
  3896. we present the syntax of the actual parameters for {\tt SYMOPTIMIZE}:
  3897. \index{{\tt INTERN} switch}
  3898. \index{SCOPE function ! {\tt SYMOPTIMIZE}}
  3899. $<$SCOPE\_application$>~::=~\cdots~\mid$\\
  3900. \hspace*{1cm} {\tt SYMOPTIMIZE}($<$ssetq\_list$>,<$infile\_list$>,<$outfile\_name$>,<$cse\_prefix$>,\\
  3901. \hspace*{6cm} <$declaration\_list$>$)
  3902. \begin{center}
  3903. \begin{tabular}{lcl}
  3904. $<$ssetq\_list$>$ & $::=$ & ($<$ssetq\_seq$>$)\\
  3905. $<$ssetq\_seq$>$ & $::=$ & $<$ssetq\_stat$>~[<$ssetq\_seq$>]$\\
  3906. $<$ssetq\_stat$>$ & $::=$ & ({\tt setq} $<$lhs\_id$>~<$rhs$>)~\mid$
  3907. ({\tt rsetq} $<$lhs\_id$>~<$rhs$>)~\mid$\\
  3908. & & ({\tt lsetq} $<$lhs\_id$>~<$rhs$>)~\mid$
  3909. ({\tt lrsetq} $<$lhs\_id$>~<$rhs$>)$\\
  3910. $<$lhs\_id$>$ & $::=$ & $<$id$>~\mid~<$subscripted\_id$>$\\
  3911. $<$subscripted\_id$>$ & $::=$ & $(<$id$>~<$s\_subscript\_seq$>)$\\
  3912. $<$s\_subscript\_seq$>$ & $::=$ & $<$s\_subscript$>[~<$s\_subscript\_seq$>$]\\
  3913. $<$s\_subscript$>$ & $::=$ & $<$integer$>~\mid~<$integer prefix\_expression$>$\\
  3914. $<$rhs$>$ & $::=$ & $<$prefix\_expression$>$\\
  3915. $<$infile\_list$>$ & $::=$ & $(<$infile\_seq$>)$\\
  3916. $<$infile\_seq$>$ & $::=$ & $<$infile\_name$>[~<$infile\_seq$>]$\\
  3917. $<$infile\_name$>$ & $::=$ & $<$string\_id$>$\\
  3918. $<$outfile\_name$>$ & $::=$ & $<$string\_id$>$\\
  3919. $<$declaration\_list$>$ & $::=$ & $(<$declaration\_seq$>)$\\
  3920. $<$declaration\_seq$>$ & $::=$ & $<$declaration$>~<$declaration\_seq$>$\\
  3921. $<$declaration$>$ & $::=$ & $(<$type$>~<$lhs\_id\_seq$>)$\\
  3922. $<$lhs\_id\_seq$>$ & $::=$ & $<$lhs\_id$>~<$lhs\_id\_seq$>$
  3923. \end{tabular}
  3924. \end{center}
  3925. The above given syntax requires some explanation:
  3926. \begin{itemize}
  3927. \item The presented ssetq syntax is incomplete. The prefix equivalent of
  3928. any object, introduced in subsection~\ref{SCOPE:optim} and of any a\_object,
  3929. defined in subsection~\ref{SCOPE:algo}, is accepted as ssetq item. Such prefix
  3930. equivalents can be obtained quite easily by using the function {\tt show}:
  3931. \hspace*{1cm} {\tt SYMBOLIC PROCEDURE show u; prettyprint u}\verb+$+ \\
  3932. \hspace*{1cm} {\tt SYMBOLIC OPERATOR show}\verb+$+
  3933. The explicit presentation of a subset of the syntax rules for ssetq
  3934. is given to suggest that local simplification in symbolic mode can be brought
  3935. in easily by using the assignment operators {\tt lsetq}, {\tt lrsetq}
  3936. and {\tt rsetq}. The algebraic mode equivalent of these operators is
  3937. {\tt ::=}, {\tt ::=:} and {\tt :=:}, respectively. Their effect on
  3938. simplification is discussed in subsection~\ref{SCOPE:inter} and already
  3939. shown in a number of examples. In addition it is worth noting that
  3940. any (sub)expression
  3941. in a lhs\_id or a rhs may contain any number of calls to {\tt eval}.
  3942. These calls lead to simplification of their arguments, prior to optimization.
  3943. Details about the use of {\tt eval} are presented in the
  3944. GENTRAN manual~\cite{Gates:91}.
  3945. \item Since we operate in symbolic mode the last four formal parameters
  3946. have possibly to be replaced by quoted actual parameters. This is illustrated
  3947. in example ~\ref{ex:9.1}.
  3948. \item The infile\_seq consists of file names in string notation. The contents'
  3949. of such input files may contain any form of infix input, obeying the syntax
  3950. rules for objects and/or a\_objects, as introduced in the subsections
  3951. ~\ref{SCOPE:optim} and ~\ref{SCOPE:algo}, respectively.
  3952. \item The single output file name outfile\_name ought to be given in string
  3953. notation as well. The outfile\_name is properly closed. The default output
  3954. is REDUCE infix in an {\tt ON NAT} fashion. Alternatives are discussed above:
  3955. {\tt ON AGAIN} or {\tt OFF NAT}, both leading to re-readable output, or an
  3956. application of {\tt OPTLANG} for a non {\tt nil} argument.
  3957. \item The declaration list presents declarations in prefix notation. The list
  3958. is used to initialize the symbol table prior to optimization. This
  3959. information is used for dynamically typing the result of an optimization
  3960. process. In addition it is used to determine wether subscripted names denote
  3961. array elements or a function call. The latter is replaced by a cse name in the
  3962. presented output, whereas the former is not.
  3963. \item The five parameters of {\tt SYMOPTIMIZE} correspondent with optional
  3964. extensions of the {\tt OPTIMIZE} command. When part of these options remains
  3965. unused, {\tt nil} has to taken as value for the corresponding actual parameters.
  3966. \end{itemize}
  3967. \index{{\tt AGAIN} switch}
  3968. \index{{\tt INPUTC} switch}
  3969. \index{{\tt INTERN} switch}
  3970. \index{{\tt NAT} switch}
  3971. \index{SCOPE function ! {\tt OPTLANG}}
  3972. \index{GENTRAN function ! {\tt lsetq}}
  3973. \index{GENTRAN function ! {\tt lrsetq}}
  3974. \index{GENTRAN function ! {\tt rsetq}}
  3975. We illustrate the symbolic mode variant of the {\tt OPTIMIZE} command by
  3976. repeating example~\ref{ex:5.1} from section~\ref{SCOPE:files}, albeit in
  3977. a modified setting.
  3978. \example\label{ex:9.1}
  3979. \index{SCOPE ! example}
  3980. The script explains itself.
  3981. {\small
  3982. \begin{verbatim}
  3983. LISP$
  3984. ON ACINFO,INPUTC,INTERN,AGAIN$
  3985. prettyprint(prefixlist:=SYMOPTIMIZE(nil,'("f1" "f2"),nil,'c,nil))$
  3986. 2
  3987. 2 (x + y) 8 2 2
  3988. 2*(sin(x) - cos(e ) + 3*cos(x)) *(x + y) + 4*y + 4*y
  3989. e1 := ----------------------------------------------------------------
  3990. 3*x + 2*y
  3991. 2
  3992. 2 (x + y) 2 3
  3993. e2 := (4*(sin(x) - cos(e ) + 2*cos(x)) *(x + y)
  3994. 2 2
  3995. + (4*x - 4*y) - 6*x)/(8*x + 3*y - 2*x)
  3996. Number of operations in the input is:
  3997. Number of (+/-) operations : 16
  3998. Number of unary - operations : 0
  3999. Number of * operations : 16
  4000. Number of integer ^ operations : 11
  4001. Number of / operations : 2
  4002. Number of function applications : 8
  4003. Number of operations after optimization is:
  4004. Number of (+/-) operations : 16
  4005. Number of unary - operations : 0
  4006. Number of * operations : 16
  4007. Number of integer ^ operations : 6
  4008. Number of / operations : 2
  4009. Number of function applications : 4
  4010. ((setq gsym c23)
  4011. (setq cses (plus c18 c10 c20 c8 c6 c14))
  4012. (setq c14 (plus x y))
  4013. (setq c6 (expt c14 2))
  4014. (setq c8 (cos x))
  4015. (setq c20 (plus (expt (sin x) 2) (minus (cos (expt e c6)))) )
  4016. (setq c10 (plus (times 3 x) (times 2 y)))
  4017. (setq e1
  4018. (quotient
  4019. (plus
  4020. (times 4 y)
  4021. (times 4 (expt y 2))
  4022. (times 2 c6 (expt (plus c20 (times 3 c8)) 8)))
  4023. c10))
  4024. (setq c18 (expt x 2))
  4025. (setq e2
  4026. (quotient
  4027. (plus
  4028. (times 4 c18)
  4029. (minus (times 2 c10))
  4030. (times 4 c6 c14 (expt (plus c20 (times 2 c8)) 2)))
  4031. (plus (times 8 c18) (minus (times 2 x)) (times 3 y)))) )
  4032. \end{verbatim}}
  4033. \index{{\tt DOUBLE} switch}
  4034. \index{{\tt FORT} switch}
  4035. {\small
  4036. \begin{verbatim}
  4037. OFF INTERN,AGAIN,PERIOD$
  4038. ON DOUBLE,FORT$
  4039. SYMOPTIMIZE(prefixlist,'("f3"), '"f7",'d,'((real e1 e2 e3 x y)))$
  4040. gsym := c23
  4041. cses := c18 + c10 + c20 + c8 + c6 + c14
  4042. c14 := x + y
  4043. 2
  4044. c6 := c14
  4045. c8 := cos(x)
  4046. 2 c6
  4047. c20 := sin(x) - cos(e )
  4048. c10 := 3*x + 2*y
  4049. 2 8
  4050. 4*y + 4*y + 2*c6*(c20 + 3*c8)
  4051. e1 := ---------------------------------
  4052. c10
  4053. 2
  4054. c18 := x
  4055. 2
  4056. 4*c18 - 2*c10 + 4*c6*c14*(c20 + 2*c8)
  4057. e2 := ----------------------------------------
  4058. 8*c18 - 2*x + 3*y
  4059. 2
  4060. (x + y) 2 2
  4061. 4*sin(cos(e )) + sin(x + y) + (4*x - x + 2*y)
  4062. e3 := --------------------------------------------------------
  4063. 3*y + f(x,g( - cos(x)))
  4064. Number of operations in the input is:
  4065. Number of (+/-) operations : 23
  4066. Number of unary - operations : 1
  4067. Number of * operations : 20
  4068. Number of integer ^ operations : 9
  4069. Number of / operations : 3
  4070. Number of function applications : 11
  4071. Number of operations after optimization is:
  4072. Number of (+/-) operations : 15
  4073. Number of unary - operations : 1
  4074. Number of * operations : 24
  4075. Number of integer ^ operations : 0
  4076. Number of / operations : 3
  4077. Number of function applications : 8
  4078. \end{verbatim}}
  4079. The contents of the output file {\tt f7} is:
  4080. {\small
  4081. \begin{verbatim}
  4082. DOUBLE PRECISION X,Y,D19,D16,C8,D1,D2,C20,D29,C10,D6,D38,D37,D31,
  4083. . E1,C18,D9,D32,D27,D30,E2,D20,E3
  4084. D19=X+Y
  4085. D16=D19*D19
  4086. C8=DCOS(X)
  4087. D1=DSIN(X)
  4088. D2=DCOS(DEXP(D16))
  4089. C20=D1*D1-D2
  4090. D29=2*Y
  4091. C10=D29+3*X
  4092. D6=C20+3*C8
  4093. D38=D6*D6
  4094. D37=D38*D38
  4095. D31=4*Y
  4096. E1=(D31+D31*Y+2.0D0*D16*D37*D37)/C10
  4097. C18=X*X
  4098. D9=C20+2*C8
  4099. D32=4*C18
  4100. D27=D32-X
  4101. D30=3*Y
  4102. E2=(D32-(2.0D0*C10)+4.0D0*D9*D9*D19*D16)/(D30+2.0D0*D27)
  4103. D20=D29+D27
  4104. E3=(4.0D0*DSIN(D2)+DSIN(D19)+D20*D20)/(D30+F(X,G(-C8)))
  4105. \end{verbatim}
  4106. \begin{flushright}
  4107. $\Box$
  4108. \end{flushright}}
  4109. We especially designed these symbolic mode facilities for our joint
  4110. research with Delft Hy\-draulics concerning code generation for an
  4111. incompressible Navier-Stokes problem ~\cite{Goldman:95}.
  4112. \index{{\tt PREFIX} switch}
  4113. \index{{\tt INTERN} switch}
  4114. A final remark: The {\tt ON PREFIX} mode of operation, in both
  4115. algebraic and symbolic mode causes the results of a SCOPE
  4116. application to be presented in the form of an association list,
  4117. called {\tt Prefixlist}. The pairs are formed by lhs\_id's and
  4118. rhs values in prefixform. This lisp S-expression can be used to
  4119. create an alternative version of the optimization results,
  4120. in whatever target language the user prefers to choose.
  4121. \example\label{ex:9.2}
  4122. \index{SCOPE ! example}
  4123. We show the {\tt ON PREFIX} effect. When switching to symbolic mode
  4124. (command 5) we can again obtain the output, assigned as value to the global
  4125. identifer {\tt prefixlist}. The {\tt ON PREFIX} facility allows storage
  4126. in a file for later use. When working in symbolic mode it is of course
  4127. possible to apply {\tt ON INTERN} in stead and to remove the {\tt setq}
  4128. extensions from the provided output value, if desired.
  4129. {\small
  4130. \begin{verbatim}
  4131. REDUCE 3.6, 15-Jul-95 ...
  4132. 1: LOAD_PACKAGE nscope$
  4133. 2: OPTIMIZE a:=b+c*sin(x), d:=c*sin(x)*cos(y);
  4134. g7 := sin(x)*c
  4135. a := g7 + b
  4136. d := g7*cos(y)
  4137. 3: ON PREFIX$
  4138. 4: input 2;
  4139. Prefixlist:=
  4140. ((g3 times (sin x) c) (a plus g3 b) (d times g3 (cos y)))
  4141. 5: LISP$
  4142. 6: prettyprint prefixlist$
  4143. ((g3 times (sin x) c) (a plus g3 b) (d times g3 (cos y)))
  4144. 7: caar prefixlist;
  4145. g3
  4146. 7: cdar prefixlist;
  4147. (times (sin x) c)
  4148. 9: BYE;
  4149. \end{verbatim}
  4150. \begin{flushright}
  4151. $\Box$
  4152. \end{flushright}}
  4153. \newpage
  4154. \section{ A Syntax Summary of SCOPE 1.5}~\label{SCOPE:syntax}
  4155. {\REDUCE} is extended with some commands, designed to apply the facilities
  4156. offered by SCOPE in a flexible way. The syntactical rules, defining how to
  4157. activate SCOPE in both algebraic and symbolic mode, are given in subsection
  4158. ~\ref{SCOPE:srules}. A short overview of the set of additional functions is
  4159. given in subsection~\ref{SCOPE:arules} and the relevant switches are again
  4160. presented in subsection~\ref{SCOPE:switches}.
  4161. \subsection{SCOPE's Toplevel Commands}~\label{SCOPE:srules}
  4162. We assume the syntax of {\tt id}'s, {\tt integer}'s and the like to be already
  4163. known. Hence we do not present an exhaustive description of the rules.\\
  4164. \index{SCOPE function ! {\tt OPTIMIZE}}
  4165. \index{SCOPE function ! {\tt ALGOPT}}
  4166. \index{SCOPE function ! {\tt SYMOPTIMIZE}}
  4167. \index{REDUCE function ! {\tt GSTRUCTR}}
  4168. \index{REDUCE function ! {\tt GHORNER}}
  4169. $<${\tt REDUCE}\_command$>~::=~ \cdots ~ \mid~<${\tt SCOPE}\_application$>$\\
  4170. \hspace*{1cm} $<${\tt GSTRUCTR}\_application$>~\mid$
  4171. $<${\tt GHORNER}\_application$>~\mid$\\
  4172. $<${\tt SCOPE}\_application$>~::=~<${\tt OPTIMIZE} command$>~\mid$\\
  4173. \hspace*{1cm}
  4174. $<${\tt ALGOPT} application$>~\mid$
  4175. $<${\tt SYMOPTIMIZE} application$>$\\
  4176. $<${\tt OPTIMIZE} command$>~::=$\\
  4177. \hspace*{1cm}{\tt OPTIMIZE} $<$object\_seq$>$ [{\tt IN} $<$file\_id\_seq$>$]
  4178. [{\tt OUT} $<$file\_id$>$]\\
  4179. \hspace*{3cm}[{\tt INAME} $<$cse\_prefix$>$]
  4180. [{\tt DECLARE} $<$declaration\_group$>$] $\mid$\\
  4181. \hspace*{1cm}{\tt OPTIMIZE} [$<$object\_seq$>$] {\tt IN} $<$file\_id\_seq$>$
  4182. [{\tt OUT} $<$file\_id$>$]\\
  4183. \hspace*{3cm}[{\tt INAME} $<$cse\_prefix$>$]
  4184. [{\tt DECLARE} $<$declaration\_group$>$]\\
  4185. $<${\tt ALGOPT} application$>~::=$\\
  4186. \hspace*{1cm}{\tt ALGOPT}($<$a\_object\_list$>$[,$<$string\_id\_list$>$][,$<$cse\_prefix$>$]) $\mid$\\
  4187. \hspace*{1cm}{\tt ALGOPT}([$<$a\_object\_list$>$,]$<$string\_id\_list$>$[,$<$cse\_prefix$>$])\\
  4188. $<${\tt SYMOPTIMIZE} application$>~::=$\\
  4189. \hspace*{0.3cm} {\tt SYMOPTIMIZE}($<$ssetq\_list$>,<$infile\_list$>,<$outfile\_name$>,<$cse\_prefix$>$,\\
  4190. \hspace*{2.3cm} $<$declaration\_list$>$)\\
  4191. \begin{tabular}{lcl}
  4192. $<${\tt GSTRUCTR}\_application$>$ & $::=$ &
  4193. {\tt GSTRUCTR} $<$stat\_group$>$ [{\tt NAME} $<$cse\_prefix$>$]\\
  4194. $<$stat\_group$>$ & $::=$ & $\ll~<$stat\_list$>~\gg$\\
  4195. $<$stat\_list$>$ & $::=$ & $<$gstat$>$ [; $<$stat\_list$>$]\\
  4196. $<$gstat$>$ & $::=$ & $<$name$>~:=~<$ expression$>~\mid~<$matrix\_id$>$\\
  4197. $<${\tt GHORHER}\_application$>$ & $::=$ &
  4198. {\tt GHORNER} $<$stat\_group$>$ [{\tt VORDER} $<$id\_seq$>$]\\
  4199. $<$id\_seq$>$ & $::=$ & $<$id$>$[,$<$id\_seq$>$]\\
  4200. \end{tabular}
  4201. \index{SCOPE ! {\tt DECLARE} facility}
  4202. \index{{\tt DECLARE} option}
  4203. \index{{\tt IN} option}
  4204. \index{{\tt OUT} option}
  4205. \index{{\tt INAME} option}
  4206. \newpage
  4207. \index{GENTRAN function ! {\tt lsetq}}
  4208. \index{GENTRAN function ! {\tt lrsetq}}
  4209. \index{GENTRAN function ! {\tt rsetq}}
  4210. \index{SCOPE function ! {\tt ALGSTRUCTR}}
  4211. \index{SCOPE function ! {\tt ALGHORNER}}
  4212. \index{{\tt IMPLICIT} type}
  4213. \index{{\tt integer} type}
  4214. \index{{\tt real} type}
  4215. \index{{\tt real*8} type}
  4216. \index{{\tt complex} type}
  4217. \index{{\tt complex*16} type}
  4218. \begin{center}
  4219. \begin{tabular}{lcl}
  4220. $<$object\_seq$>$ & $::=$ & $<$object$>$[,$<$object\_seq$>$]\\
  4221. $<$object$>$ & $::=$ & $<$stat$>~\mid~<$alglist$>~\mid~<$alglist\_production$>$ \\
  4222. $<$stat$>$ & $::=$ & $<$name$>~<$assignment operator$>~<$expression$>$\\
  4223. $<$assignment operator$>$ & $::=$ & $:=~\mid~::=~\mid~::=:~\mid~:=:$\\
  4224. $<$alglist$>$ & $::=$ & \{$<$eq\_seq$>$\}\\
  4225. $<$eq\_seq$>$ & $::=$ & $<$name$>~=~<$expression$>$[,$<$eq\_seq$>$]\\
  4226. $<$alglist\_production$>$ & $::=$ & $<$name$>~\mid~<$function\_application$>$\\
  4227. $<$name$>$ & $::=$ & $<$id$>~\mid~<$id$>(<$a\_subscript\_seq$>)$\\
  4228. $<$a\_subscript\_seq$>$ & $::=$ & $<$a\_subscript$>$[,$<$a\_subscript\_seq$>$]\\
  4229. $<$a\_subscript$>$ & $::=$ & $<$integer$>~\mid~<$integer infix\_expression$>$\\
  4230. $<$cse\_prefix$>$ & $::=$ & $<$id$>$\\
  4231. & & $\ \ $\\
  4232. $<$a\_object\_list$>$ & $::=$ & $<$a\_object$>~\mid$ \{$<$a\_object$>$[,$<$a\_object\_seq$>$]\}\\
  4233. $<$a\_object\_seq$>$ & $::=$ & $<$a\_object$>$[,$<$a\_object\_seq$>$]\\
  4234. $<$a\_object$>$ & $::=$ & $<$id$>~\mid~<$alglist$>~\mid~<$alglist\_production$>~\mid$\\
  4235. & & \{$<$a\_object$>$\}\\
  4236. & & $\ \ $\\
  4237. $<$function\_application$>$ & $::=$ &
  4238. {\tt ALGSTRUCTR} ($<$arg\_list$>$ [, $<$cse\_prefix$>$ ]) $\mid$\\
  4239. & & {\tt ALGHORNER} ($<$arg\_list$>$ [,\{$<$id\_seq$>$\}]) $\mid$ \\
  4240. & & $\cdots$\\
  4241. $<$arg\_list$>$ & $::=$ & $<$arg\_list\_name$>~\mid~$\{$<$arg\_seq$>$\}\\
  4242. $<$arg\_seq$>$ & $::=$ & $<$arg$>$[,$<$arg\_seq$>$]\\
  4243. $<$arg$>$ & $::=$ & $<$matrix\_id$>~\mid~<$name$>$=$<$expression$>$\\
  4244. $<$arg\_list\_name$>$ & $::=$ & $<$id$>$\\
  4245. & & $\ \ $\\
  4246. $<$file\_id\_seq$>$ & $::=$ & $<$file\_id$>$ [,$<$file\_id\_seq$>$]\\
  4247. $<$file\_id$>$ & $::=$ & $<$id$>$ $\mid$ $<$string\_id$>$\\
  4248. $<$string\_id\_list$>$ & $::=$ & $<$string\_id$>$ $\mid$
  4249. \{$<$string\_id\_seq$>$\}\\
  4250. $<$string\_id\_seq$>$ & $::=$ & $<$string\_id$>$ [,$<$string\_id\_seq$>$]\\
  4251. $<$string\_id$>$ & $::=$ & {\tt "}$<$id$>${\tt "} $\mid$
  4252. {\tt "}$<$id$>.<$f\_extension$>${\tt "}\\
  4253. & & $\ \ $\\
  4254. $<$declaration\_group$>$ & $::=$ & $<$declaration$>~\mid~\ll~<$declaration\_list$>~\gg$\\
  4255. $<$declaration\_list$>$ & $::=$ & $<$declaration$>$[$;<$declaration\_list$>$]\\
  4256. $<$declaration$>$ & $::=$ & $<$range\_list$>:$ {\tt IMPLICIT} $<$type$>~\mid$
  4257. $<$id\_list$>:<$type$>$\\
  4258. $<$range\_list$>$& $::=$ & $<$range$>$[,$<$range\_list$>$]\\
  4259. $<$range$>$ & $::=$ & $<$id$>~\mid~<$id$>-<$id$>$\\
  4260. $<$id\_list$>$ & $::=$ & $<$id$>$[,$<$id\_list$>$]\\
  4261. $<$type$>$ & $::=$ & {\tt integer} $\mid$ {\tt real} $\mid$ {\tt complex} $\mid$
  4262. {\tt real*8} $\mid$ {\tt complex*16}\\
  4263. & & $\ \ $\\
  4264. $<$ssetq\_list$>$ & $::=$ & ($<$ssetq\_seq$>$)\\
  4265. $<$ssetq\_seq$>$ & $::=$ & $<$ssetq\_stat$>~[<$ssetq\_seq$>]$\\
  4266. $<$ssetq\_stat$>$ & $::=$ & ({\tt setq} $<$lhs\_id$>~<$rhs$>)~\mid$
  4267. ({\tt rsetq} $<$lhs\_id$>~<$rhs$>)~\mid$\\
  4268. & & ({\tt lsetq} $<$lhs\_id$>~<$rhs$>)~\mid$
  4269. ({\tt lrsetq} $<$lhs\_id$>~<$rhs$>)$\\
  4270. \end{tabular}
  4271. \end{center}
  4272. \begin{center}
  4273. \begin{tabular}{lcl}
  4274. $<$lhs\_id$>$ & $::=$ & $<$id$>~\mid~<$subscripted\_id$>$\\
  4275. $<$subscripted\_id$>$ & $::=$ & $(<$id$>~<$s\_subscript\_seq$>)$\\
  4276. $<$s\_subscript\_seq$>$ & $::=$ & $<$s\_subscript$>[~<$s\_subscript\_seq$>$]\\
  4277. $<$s\_subscript$>$ & $::=$ & $<$integer$>~\mid~<$integer prefix\_expression$>$\\
  4278. $<$rhs$>$ & $::=$ & $<$prefix\_expression$>$\\
  4279. $<$infile\_list$>$ & $::=$ & $(<$infile\_seq$>)$\\
  4280. $<$infile\_seq$>$ & $::=$ & $<$infile\_name$>[~<$infile\_seq$>]$\\
  4281. $<$infile\_name$>$ & $::=$ & $<$string\_id$>$\\
  4282. $<$outfile\_name$>$ & $::=$ & $<$string\_id$>$\\
  4283. $<$declaration\_list$>$ & $::=$ & $(<$declaration\_seq$>)$\\
  4284. $<$declaration\_seq$>$ & $::=$ & $<$declaration$>~<$declaration\_seq$>$\\
  4285. $<$declaration$>$ & $::=$ & $(<$type$>~<$lhs\_id\_seq$>)$\\
  4286. $<$lhs\_id\_seq$>$ & $::=$ & $<$lhs\_id$>~<$lhs\_id\_seq$>$
  4287. \end{tabular}
  4288. \end{center}
  4289. \subsection{Additional SCOPE-functions}~\label{SCOPE:arules}
  4290. Fifteen additional functions can be used. We shortly summarize their name and use:
  4291. \begin{center}
  4292. \begin{tabular}{| l | l | l |} \hline
  4293. Name(s) & Introduced in & See the examples:\\ \hline \hline
  4294. {\tt SCOPE\_SWITCHES} & ~\ref{SCOPE:basic} & ~\ref{ex:3.1.1}\\
  4295. {\tt SETLENGTH, RESETLENGTH} & ~\ref{SCOPE:optim} & ~\ref{ex:3.1.2},
  4296. ~\ref{ex:3.1.5}, ~\ref{ex:3.2.6} and ~\ref{ex:3.2.7}\\
  4297. {\tt ARESULTS, RESTORABLES, ARESTORE, RESTOREALL} & ~\ref{SCOPE:optim} &
  4298. ~\ref{ex:3.1.9}, ~\ref{ex:3.2.6} and ~\ref{ex:4.1.2}\\
  4299. {\tt OPTLANG} & ~\ref{SCOPE:decl} & ~\ref{ex:6.1}\\
  4300. {\tt VECTORCODE, VCLEAR} & ~\ref{SCOPE:dda} & ~\ref{ex:7.1}\\
  4301. {\tt DELAYDECS, MAKEDECS, DELAYOPTS, MAKEOPTS} & ~\ref{SCOPE:gopt} &
  4302. ~\ref{ex:8.1} and ~\ref{ex:8.2}\\
  4303. {\tt INAME} & ~\ref{SCOPE:gopt} & ~\ref{ex:8.2}\\ \hline
  4304. \end{tabular}
  4305. \end{center}
  4306. \index{SCOPE function ! {\tt SCOPE\_SWITCHES}}
  4307. \index{SCOPE function ! {\tt SETLENGTH}}
  4308. \index{SCOPE function ! {\tt RESETLENGTH}}
  4309. \index{SCOPE function ! {\tt ARESULTS}}
  4310. \index{SCOPE function ! {\tt RESTORABLES}}
  4311. \index{SCOPE function ! {\tt ARESTORE}}
  4312. \index{SCOPE function ! {\tt RESTOREALL}}
  4313. \index{SCOPE function ! {\tt OPTLANG}}
  4314. \index{SCOPE function ! {\tt VECTORCODE}}
  4315. \index{SCOPE function ! {\tt VCLEAR}}
  4316. \index{SCOPE function ! {\tt DELAYDECS}}
  4317. \index{SCOPE function ! {\tt MAKEDECS}}
  4318. \index{SCOPE function ! {\tt DELAYOPTS}}
  4319. \index{SCOPE function ! {\tt MAKEOPTS}}
  4320. \index{SCOPE function ! {\tt INAME}}
  4321. \subsection{The relevant REDUCE, GENTRAN and SCOPE switches}~\label{SCOPE:switches}
  4322. We also shortly summarize the use of the switches, which were introduced
  4323. in section ~\ref{SCOPE:basic} in example~\ref{ex:3.1.1}:
  4324. \begin{center}
  4325. \begin{tabular}{| l | l | l |}\hline
  4326. Name & Origin & Illustrated in the examples:\\ \hline \hline
  4327. {\tt ACINFO} & SCOPE & ~\ref{ex:3.1.8}, ~\ref{ex:3.2.5}, ~\ref{ex:8.2}
  4328. and ~\ref{ex:9.1}\\
  4329. {\tt AGAIN} & SCOPE & ~\ref{ex:5.1} and ~\ref{ex:9.1}\\
  4330. {\tt DOUBLE} & GENTRAN & ~\ref{ex:9.1}\\
  4331. {\tt EVALLHSEQP} & REDUCE & ~\ref{ex:3.2.5}\\
  4332. {\tt EXP} & REDUCE & ~\ref{ex:3.1.8}, ~\ref{ex:3.2.7}, ~\ref{ex:4.1.3} and
  4333. ~\ref{ex:8.2}\\
  4334. {\tt FORT} & REDUCE & ~\ref{ex:3.1.4}, ~\ref{ex:3.1.6}, ~\ref{ex:3.1.8},
  4335. ~\ref{ex:3.2.5}, ~\ref{ex:7.1} and ~\ref{ex:9.1}\\
  4336. {\tt FTCH} & SCOPE & ~\ref{ex:3.1.4} and ~\ref{ex:3.1.5}\\ \hline
  4337. \end{tabular}
  4338. \end{center}
  4339. \index{{\tt ACINFO} switch}
  4340. \index{{\tt AGAIN} switch}
  4341. \index{{\tt DOUBLE} switch}
  4342. \index{{\tt EVALLHSEQP} switch}
  4343. \index{{\tt EXP} switch}
  4344. \index{{\tt FORT} switch}
  4345. \index{{\tt FTCH} switch}
  4346. \newpage
  4347. \index{{\tt GENTRANOPT} switch}
  4348. \index{{\tt INPUTC} switch}
  4349. \index{{\tt INTERN} switch}
  4350. \index{{\tt NAT} switch}
  4351. \index{{\tt PERIOD} switch}
  4352. \index{{\tt PREFIX} switch}
  4353. \index{{\tt PRIALL} switch}
  4354. \index{{\tt PRIMAT} switch}
  4355. \index{{\tt ROUNDBF} switch}
  4356. \index{{\tt ROUNDED} switch}
  4357. \index{{\tt SIDREL} switch}
  4358. \index{{\tt VECTORC} switch}
  4359. \begin{center}
  4360. \begin{tabular}{| l | l | l |}\hline
  4361. Name & Origin & Illustrated in the examples:\\ \hline \hline
  4362. {\tt GENTRANOPT} & GENTRAN & ~\ref{ex:8.1}\\
  4363. {\tt INPUTC} & SCOPE & ~\ref{ex:3.1.3}, ~\ref{ex:3.1.6}, ~\ref{ex:3.1.7},
  4364. ~\ref{ex:3.2.7}, ~\ref{ex:5.1} and ~\ref{ex:9.1}\\
  4365. {\tt INTERN} & SCOPE & ~\ref{ex:9.1}\\
  4366. {\tt NAT} & REDUCE & ~\ref{ex:3.1.8} and ~\ref{ex:5.1}\\
  4367. {\tt PERIOD} & REDUCE & ~\ref{ex:3.1.4}\\
  4368. {\tt PREFIX} & SCOPE & ~\ref{ex:9.2}\\
  4369. {\tt PRIALL} & SCOPE & ~\ref{ex:3.1.2}\\
  4370. {\tt PRIMAT} & SCOPE & ~\ref{ex:3.2.7}\\
  4371. {\tt POUNDBF} & REDUCE & ~\ref{ex:6.2}\\
  4372. {\tt ROUNDED} & REDUCE & ~\ref{ex:3.1.7} and ~\ref{ex:8.2}\\
  4373. {\tt SIDREL} & SCOPE & ~\ref{ex:3.2.7}\\
  4374. {\tt VECTORC} & SCOPE & ~\ref{ex:7.1}\\ \hline
  4375. \end{tabular}
  4376. \end{center}
  4377. \newpage
  4378. \section{SCOPE 1.5 Installation Guide}~\label{SCOPE:inst}
  4379. SCOPE 1.5 is easily installed. The usual code compilation facilities of {\REDUCE}
  4380. can be applied. In view of the frequent interaction between SCOPE and GENTRAN
  4381. a compiled version of GENTRAN is required during the creation of the load module
  4382. for SCOPE 1.5. The compilation process itself is vizualized below.
  4383. {\small
  4384. \begin{verbatim}
  4385. faslout "~infhvh/mkscope/scope_15";
  4386. lisp in "~infhvh/mkscope/cosmac.red"$
  4387. lisp in "~infhvh/mkscope/codctl.red"$
  4388. lisp in "~infhvh/mkscope/codmat.red"$
  4389. lisp in "~infhvh/mkscope/codopt.red"$
  4390. lisp in "~infhvh/mkscope/codad1.red"$
  4391. lisp in "~infhvh/mkscope/codad2.red"$
  4392. lisp in "~infhvh/mkscope/coddec.red"$
  4393. lisp in "~infhvh/mkscope/codpri.red"$
  4394. lisp in "~infhvh/mkscope/codgen.red"$
  4395. lisp in "~infhvh/mkscope/codhrn.red"$
  4396. lisp in "~infhvh/mkscope/codstr.red"$
  4397. lisp in "~infhvh/mkscope/coddom.red"$
  4398. %lisp in "~infhvh/mkscope/apatch.red"$
  4399. algebraic;
  4400. faslend ;
  4401. end;
  4402. \end{verbatim}}
  4403. The subdirectory {\tt mkscope} in the author's directory system
  4404. contains the files with the source code of SCOPE 1.5.
  4405. The order in which the files are read in is irrelevant except
  4406. the first and the last. The file {\tt cosmac.red} contains
  4407. one module, named {\tt cosmac}, which consists of a set of
  4408. smacro procedures, designed to simplify access to the lower
  4409. levels of the expression data base, employed during optimization.
  4410. These smacro's are used in all other code sections.
  4411. The last file in optional and usually executed to include new
  4412. patches into a recompilable version of the package.
  4413. Once it is stored in the {\tt fasl} directory of the local
  4414. REDUCE system it is available as a {\tt load\_package}.
  4415. In short, the files contain the following code sections:
  4416. \begin{itemize}
  4417. \item {\tt cosmac.red} contains the module {\tt cosmac}, consisting of
  4418. smacro procedures, allowing access to the expression data base.
  4419. \item {\tt codctl.red} consists of the three modules {\tt codctl},
  4420. {\tt restore} and {\tt minlenght}. The first is a large module,
  4421. containing the optimization process managing facilities. The second
  4422. module is added to regulate the interplay with the REDUCE simplifier,
  4423. when entering optimizer output in algebraic mode using functions like
  4424. {\tt ARESULTS}. The last module serves to vary the minimal length of
  4425. cse's using {\tt SETLENGTH} and {\tt RESETLENGTH}.
  4426. \item {\tt codmat.red} contains the module {\tt codmat}, definig the
  4427. parsing process and the expression data base setup and access facilities.
  4428. \item {\tt codopt.red}'s content is formed by the module {\tt codopt}.
  4429. It is the kernel of the optimization process, the implementation of the
  4430. extended Breuer algorithm.
  4431. \item {\tt codad1.red} contains the module {\tt codad1}, formed by additional
  4432. facilities for improving the lay-out of the overall result, for information
  4433. migration between different sections of the expression data base and for the
  4434. application of the distributive law to remodel and compactify (sub)expression
  4435. structure at any level.
  4436. \item {\tt codad2.red} contains the module {\tt codad2}. This module defines
  4437. five different possible activities during the optimization process. The first
  4438. four regulate the so called {\em finishing touch}. The last one is a new
  4439. section, defining how to optimize {\em rational forms} as part of the overall
  4440. optimization process.
  4441. \item {\tt coddec.red} covers the declaration facilities, presented in
  4442. section ~\ref{SCOPE:decl}, collected in the module {\tt coddec} and
  4443. based on chapter 6 of ~\cite{Aho:86}. The symbol table setup of GENTRAN is used.
  4444. \item {\tt codpri.red} is also formed by one module, called {\tt codpri}.
  4445. It covers all printing facilities. The first section is applied when the
  4446. switch {\tt PRIMAT} is turned {\tt ON}. The latter is used to produce
  4447. an internal list of pairs, consisting of the left hand side and the right
  4448. hand side of assignment statements in prefix notation, and defining the
  4449. output of the optimization process in sequential order. This prefix list is
  4450. delivered to GENTRAN or REDUCE to make the results visible in the user
  4451. prefered form. The intial version of this list, created directly
  4452. after the optimization process, is improved using a collection of functions,
  4453. also grouped together in the module {\tt codpri}. These improvements may
  4454. for instance be necessary to remove temporarily introduced names, internally
  4455. employed as a result of a data dependency analysis.
  4456. \item {\tt codgen.red} consists of the module {\tt codgen}. The interface
  4457. between GENTRAN and SCOPE 1.5, introduced in section ~\ref{SCOPE:gopt} of
  4458. this manual is defined in this module.
  4459. \item {\tt codhrn.red} is formed by the module {\tt ghorner}. It defines the
  4460. facilities, presented in section ~\ref{SSF:Hr} of this manual.
  4461. \item {\tt codstr.red} contains the module {\tt gstructr}. This module defines
  4462. the possibilities for expression structure recognition, as presented in section
  4463. ~\ref{SSF:sr} of this manual.
  4464. \item {\tt coddom.red} finally, consists of one module, called {\tt coddom}.
  4465. It covers additional coefficient domain functions, needed to make the
  4466. extended Breuere algorithm and the additional functions, collected in the
  4467. modules {\tt codad1} and {\tt codad2} for instance, applicable for
  4468. (multiple presicion) floating point coefficients.
  4469. \end{itemize}
  4470. A few additional remarks:
  4471. \begin{itemize}
  4472. \item GENTRAN plays an important role when creating declarations and output.
  4473. The package is automatically loaded when executing one of the first
  4474. instructions in the module {\tt codctl}. Hence it may be necessary to
  4475. look critically to the load instruction in {\tt codctl} before installing
  4476. SCOPE 1.5. By changing this load instruction we easily created a {\tt fortran90}
  4477. compatable SCOPE version ~\cite{Borst:94}. At present it is only available for our own
  4478. internal and experimental use.
  4479. \item We believe the code to be almost version independent. Over the past
  4480. years all uses of {\tt nil} have been critically reviewed. However
  4481. the {\tt coddom} module may require version based maintenance when
  4482. installing SCOPE 1.5.
  4483. \item The present size of the source code is given in the table below.
  4484. Comment is included in these figures
  4485. \begin{center}
  4486. \begin{tabular}{| c | r | r |} \hline
  4487. File naam & number of lines & number of characters \\ \hline \hline
  4488. {\tt cosmac.red} & 172 & 4761 \\
  4489. {\tt codctl.red} & 1439 & 61466 \\
  4490. {\tt codmat.red} & 1488 & 72733 \\
  4491. {\tt codopt.red} & 1243 & 68809\\
  4492. {\tt codad1.red} & 801 & 39175 \\
  4493. {\tt codad2.red} & 1314 & 59217 \\
  4494. {\tt coddec.red} & 928 & 41069\\
  4495. {\tt codpri.red} & 1371 & 62600\\
  4496. {\tt codgen.red} & 214 & 9120\\
  4497. {\tt codhrn.red} & 752 & 30549\\
  4498. {\tt codstr.red} & 308 & 11199\\
  4499. {\tt coddom.red} & 204 & 6638\\ \hline
  4500. \end{tabular}
  4501. \end{center}
  4502. \item The modules {\tt ghorner} and {\tt gstructr} can be left out without
  4503. harming the other facilities, presented in this manual.
  4504. \end{itemize}
  4505. \newpage
  4506. \addcontentsline{toc}{section}{References}
  4507. \bibliography{scope}
  4508. \bibliographystyle{plain}
  4509. \newpage
  4510. \addcontentsline{toc}{section}{Index}
  4511. \printindex
  4512. \end{document}