12.07.2015 Views

Notes - Dyalog APL - D-functions

Notes - Dyalog APL - D-functions

Notes - Dyalog APL - D-functions

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

DFNS.DWS<strong>Notes</strong>2014-12-10 09:58:48


IntroductionThe dfns.dws workspace has accumulated code samples for well over a decade. Itwould be unfair to single out any of the many contributors for special mention,but the Person Index towards the end of this document gives an idea of just howmany people have pitched in.To quote Ben Schott:"To them my thanks are due for suggestions, advice, encouragement, expertopinions, and other such things. If glaring errors exist within this book,it's probably their fault." :-)Dfns.dws will continue to be a work-in-progress, which means that if you printthese notes (316 double-sided sheets), your copy may differ slightly from thatof your friend, who prints it tomorrow. This might seem uncomfortable in that aprinted copy is soon out-of-date. However the same is true of, say, a printedroad atlas.References to notes in the contents and index pages have the form: note.pageno,for example dfnsnotes.364 means that the notes for the dfnsnotes function, whichproduced the lay-out for this document, start on page 364.pageContents · · · 1<strong>Notes</strong> · · · · · 9Person index · 611Function index 615Topic Index · · 619You can find the source code for these <strong>functions</strong> and operators in a separateappendix:www.dyalog.com/dfnsdws/DfnsCode.pdfIf any of what you see in the following pages takes your fancy, you might liketo take part in the "Functional Programming" forum at http://forums.dyalog.com.Better yet, if you install <strong>Dyalog</strong> <strong>APL</strong>, you can experiment with and modify any ofthe code detailed in these pages. See: www.dyalog.com/download-zone.htm.John Scholesjohn@dyalog.com


ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ C o n t e n t s ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙ1


Structures.·· Arrays.· · alists.8 © Association lists.· · acc.10 © Accumulating reduction.· · bags.12 © Multisets / bags.· · box.14 © Box the simple text array ¾.· · chksum.18 © Simple ¸-digit checksum.· · cmat.19 © ¸-combination matrix of ¼¾.· · cols.26 © Multi-column display.· · disp.31 © Boxed sketch of nested array.· · display.35 © Boxed display of array.· · displays.35 © Boxed display of array with axis lengths.· · displayr.35 © Boxed display of array with subarray depths.· · dist.36 © Levenshtein distance.· · enlist.37 © List ¸-leaves of nested array.· · enss.39 © Emulate (¹¸)„¾.· · find.40 © Lines containing string(s) ¾.· · from.42 © Select (1‡½¾)-cells from array.· · foldl.45 © Fold (reduce) from the left.· · iotag.47 © Generalized iota.· · key.48 © Key operator.· · le.49 © Total array ordering (TAO) comparison.· · lex.53 © Lexicographical comparison of arrays ¸ and ¾.· · list.54 © List from vector ¾.· · ltrav.54 © List traversal.· · match.58 © find with wildcards.· · merge.61 © Suggestion for a merge operator.· · merge2.61 © Alternative for a merge operator.· · mns.66 © Make NS from association list ¾.· · nlines.67 © Number of display lines for simple array.· · pack.69 © Saves WS by sharing identical subarrays.· · perv.70 © Scalar pervasion, apply function between scalars.· · pmat.71 © Permutation matrix of ¼¾.· · pred.72 © Partitioned reduction.· · rank.73 © Apply function to/between subarrays.· · rows.74 © Operand function applied to argument rows.· · sam.75 © Select and modify.· · saw.78 © Operand function applied Simple-Array-Wise.· · scan.79 © Variations on primitive scan.· · select.81 © ¸-selection of items from vector ¾.· · subvec.83 © Is ¸ a subvector of ¾?· · squad.84 © IBM <strong>APL</strong>2 Indexing function.· · subs.85 © Vector substitution.· · type.86 © Array of type ¸.· Trees.87· · BST.88 © Binary Search Trees.· · · avl.96 © Adelson-Velskii, Landis (AVL) trees.· · · sbst.105 © Simple binary search trees.· · · redblack.110 © Red-black trees.· · · splay.120 © Splay trees.· · dft.125 © Display of function tree.· · tfmt.130 © Char matrix from tree(s).· · tnest.130 © Array from TreeView style tree.· · trav.130 © Generic depth-first tree traversal.· · tree.135 © Display of namespace tree.· · tview.137 © TreeView style tree from nested array.2


· Graphs.137· · assign.144 © Hungarian method cost assignment.· · scc.148 © Strongly connected components of directed graph ¾.· · insnode.150 © Insert vertex ¾ in graph ¸.· · remnode.150 © Remove vertex ¾ from graph ¸.· · inslink.151 © Insert edge ¾ in graph ¸.· · remlink.152 © Remove edge ¾ from graph ¸.· · popnode.152 © Pop vertex ¾ to head of graph ¸.· · search.153 © Breadth-first search of graph ¸.· · path.153 © Shortest path from/to ¾ in graph ¸.· · span.155 © Breadth-first spanning tree for graph ¸.· · dfspan.156 © Depth-first spanning tree for graph ¸.· · stdists.158 © Spanning tree path lengths.· · stpath.159 © Path through spanning tree ¸ to vertex ¾.· · stpaths.160 © Spanning tree paths.· · X.160 © Exact cover: Knuth's Algorithm X.· wGraphs.163 © Weighted graphs.· · wcost.165 © Cost vector for path ¾ through _weighted_ graph ¸.· · wpath.165 © Quickest path from/to ¾ in _weighted_ graph ¸.· · wspan.167 © Spanning tree for _weighted_ graph ¸ from ¾.· · wmst.167 © Minimum Spanning Tree for _weighted_ graph ¸.· Words.· · ssword.169 © Approx alternative to xutils' ss.· · words.169 © Source vector split into words.· · tokens.170 © Lex of <strong>APL</strong> source line.· · von.173 © Capitalise first letters of names.· Strings.· · base64.174 © Base64 encoding and decoding as used in MIME.· · dist.36 © Levenshtein distance.· · find.40 © Search for string ¾ in vars, fns and ops.· · just.175 © Justify text array.· · lcase.176 © Lower-casification.· · ucase.176 © Upper-casification.· · mtrim.177 © Trim trailing blank columns from matrix.· · ss.177 © Approx alternative to xutils' string replacement.· · ssmat.178 © Matrix search/replace.· · ssword.169 © Approx alternative to xutils' word replacement.· · subs.85 © Vector substitution.· · subvec.83 © Is ¸ a subvector of ¾?· · squeeze.178 © Compress multiple blanks.· · timestamp.178 © Time-stamped message.· · xtabs.179 © Expand/compress HT chars.· · htx.180 © Extract html segments.· Line_vectors.182· · htx.180 © Extract html segments.· · ltov.184 © Lines to nested vector.· · vtol.184 © Nested vector to lines.· · wrap.185 © Wrap word vector at ¸ columns.· · unwrap.185 © Replace [LF] with blanks.· · justify.185 © Justify line-vector to ¸ columns.· · squeeze.178 © Compress multiple blanks.· · vtrim.186 © Trim trailing blanks from line-vector.· · wrapnote.186 © Wrap text paragraphs in note vector.· · xtabs.179 © Expand/compress HT chars.3


· Blank_removal.187· · dlb.189 © Drop Leading Blanks.· · dtb.189 © Drop Trailing Blanks.· · deb.189 © Drop Ending Blanks.· · dxb.189 © Drop eXtraneous Blanks.· · dmb.190 © Drop Multiple Blanks.· · dab.190 © Drop All Blanks.· Data_compression.190· · base64.174 © Base64 encoding and decoding as used in MIME.· · pack4.193 © Quad-tree packing.· · packB.195 © Pack a simple array.· · packD.195 © Pack char array to boolean vector.· · packH.197 © Huffman packing.· · packN.202 © Zero packing.· · packQ.202 © Assorted uniQues packer.· · packR.203 © RLE packing.· · packS.204 © Shannon-Fano packing.· · packT.204 © Simple text vector packager.· · packU.204 © Unique packer.· · packX.205 © TeXt packer.· · packZ.205 © Lempel-Ziv-Welch.· Power.operators· · cond.208 © Conditional function application.· · do.211 © Apply no-result function "en passant".· · else.212 © Condition f else g ...· · for.214 © Multiple selection of function list.· · invr.214 © Approx inverse of real-valued function.· · limit.215 © Function power limit (fixpoint).· · pow.218 © Explicit function power.· · traj.220 © Function limit "trajectory".· · while.221 © Conditional function power.· · until.222 © Conditional function power.· Function_arrays.222· · case.224 © select statement.· · for.214 © Multiple selection of function list.· · of.225 © pick'th fn applied to arg.· · lof.226 © List of <strong>functions</strong>.· · logic.227 © logical function array.· · vof.229 © Vector of <strong>functions</strong>.· · fnarray.232 © Array of <strong>functions</strong>.· Syntax.operators· · and.233 © Sequential test.· · cond.208 © Conditional function application.· · do.211 © Apply no-result function "en passant".· · fork.234 © Function fork.· · or.233 © Sequential test.· · rank.73 © Apply function to/between subarrays.· Expressions.· · dft.125 © Display of function tree.· · htx.180 © Extract html segments.· · lisp.236 © Evaluator for a subset of Scheme.· · parse.237 © Bunda-Gerth parsing.· · rmcm.247 © Remove comment from line of <strong>APL</strong>.· · unify.249 © Unification of expressions.4


Numbers.·· Whole.numbers· · adic.253 © Bijective base-¸ numeration.· · apportion.256 © Huntington-Hill apportionment.· · big.257 © Arithmetic on large integers.· · bsearch.258 © Binary search: least n in range ¾ such that ¸¸ n.· · bt.258 © Balanced Ternary Arithmetic.· · cfract.266 © Continued fraction approximation of real number.· · colsum.272 © Sum of (default decimal) columns.· · dec.286 © Decimal from hexadecimal.· · efract.274 © Egyptian fraction for ¸÷¾.· · esh.275 © Shell for Eide-number sums.· · factorial.279 © Tail-recursive factorial.· · fibonacci.279 © Tail-recursive Fibonacci.· · factors.282 © Prime factors of ¾.· · gcd.284 © Greatest common divisor.· · k6174.286 © Kaprekar's operation.· · lcm © Least common multiple.· · hex.286 © Hexadecimal from decimal.· · hexf.288 © IEEE 754/854 binary floating point.· · int.289 © Signed from unsigned integers.· · nats.290 © Natural number arithmetic.· · nicediv.295 © ¾ similar integers with sum ¸.· · osc.296 © Oscillate - probably returns 1.· · pco.296 © Prime numbers.· · range.298 © Numeric range classification.· · rational.298 © Rational approximation to real ¾.· · rats.302 © Rational arithmetic.· · ratsum.308 © ¸¸-rational sum of ¸ and ¾.· · stamps.314 © Postage stamps to the value of ¾.· · sieve.315 © Sieve of Eratosthenes.· · to.316 © Sequence ¸ .. ¾· · uns.289 © Unsigned from signed integers.· Rational.numbers· · ary.317 © ¸-ary representation of rational ¾.· · cfract.266 © Continued fraction approximation of real number.· · efract.274 © Egyptian fraction for ¸÷¾.· · esh.275 © Shell for Eide-number sums.· · gcd.284 © Greatest common divisor.· · lcm © Least common multiple.· · rational.298 © Rational approximation to real ¾.· · rats.302 © Rational arithmetic.· · ratsum.308 © ¸¸-rational sum of ¸ and ¾.· Real.numbers· · abc.320 © Arithmetic Boundary Checking.· · birthday.324 © Probability of same birthday.· · cfract.266 © Continued fraction approximation of real number.· · Cholesky.325 © decomposition of a Hermitian +ive-definite matrix.· · det.326 © Determinant of square numeric matrix.· · efract.274 © Egyptian fraction for ¸÷¾.· · gauss_jordan.327 © Gauss-Jordan elimination.· · invr.214 © Approx inverse of real-valued function.· · kcell.335 © Relationship between point and k-cell.· · kball.336 © Relationship between point and k-ball.· · ksphere.337 © Hypersphere surface and volume.· · mean.340 © Arithmetic mean.· · NormRand.341 © Random numbers with a normal distribution.· · phinary.341 © Phinary rep of scalar number ¾.· · root.345 © ¸'th root.· · roots.346 © Real roots of quadratic.5


· Complex.numbers· · Cholesky.325 © decomposition of a Hermitian +ive-definite matrix.· · cxdraw.346 © Complex function drawing.· · polar.348 © Polar from cartesian coordinates.· · xpower.350 © Fast multi-digit power using FFT.· · xtimes.350 © Fast multi-digit product using FFT.· Dates.353· · birthday.324 © Probability of same birthday.· · cal.354 © Calendar.· · compidn.356 © Component timestamp in IDN format.· · days.356 © Day number from ŒTS format.· · date.358 © ŒTS format from day number.· · easter.359 © Easter Day in year ¾.· · timestamp.178 © Time-stamped message.Workspace.administration·· Workspaces.361· · dfnscode.361 © Formatted dfns code.· · dfnsnotes.362 © Formatted dfns notes.· · exit.363 © Return to calling environment.· · fndiff.363 © Defined function differences.· · index.364 © ¾-index of notes in space ¸.· · refws.365 © Ref to "saved" ws ¾.· · test.367 © Run test script: no news => good news.· · utf8.370 © ŒAV „… UTF-8 translation.· · wsdiff.371 © Workspace differences.· · wsmerge.373 © {protected} merge from saved ws.· · xhtml.374 © Export this WS to ¾\*.htm.· · xws.376 © Execute expr ¸ in saved ws ¾.· Namespaces.377· · index.364 © ¾-index of notes in space ¸.· · mns.66 © Make NS from association list ¾.· · nspack.378 © Share arrays across space tree.· · refs.380 © Vector of sub-space references.· · refmatch.382 © Space reference match.· · tree.135 © Display of namespace tree.· · up.383 © Ref to ¾-parent of space ¸.· · vwise.383 © Variable-wise: apply ¸¸ to each var in space ¾.· · xrefs.384 © Extract refs vector from array ¾.· Functions.and.operators· · ambiv.385 © Ambivalize traditional <strong>functions</strong>: ¾.· · attrib.385 © Function/operator attributes.· · din.388 © Evaluation of multi-line D-expression.· · dots.389 © Show dfn with "white dots".· · find.40 © Search for string ¾ in vars, fns and ops.· · fix.393 © Fix function/operator rep.· · fndiff.363 © Defined function differences.· · fnrefs.394 © External refs from function ¾.· · fnrepl.394 © Function string replacement.· · isdfn.395 © Test for D function.· · nc.399 © Extended ŒNC for ojects named in ¾.· · ncpath.400 © Œpath-aware Œnc.· · refmt.401 © Reformat dfn/op.· · rep.402 © Representation of function/operator.· · trace.403 © Trace function application.· · UndoRedo.405 © Derive undo/redo function.6


Files.·· Native.files· · file.408 © Apply operand function to native file tie.· · getfile.409 © Get text file ¾ as nested vector.· · hexdump.410 © Hex dump of native file.· · putfile.425 © Put rows to text-file.· · utf8.370 © ŒAV „… UTF-8 translation.· · utf8get.426 © Char vector from UTF-8 file ¾.· · utf8put.426 © Char vector ¸ to UTF-8 file ¾.· · xtabs.179 © Expand/compress HT chars.· Component.files· · filefind.426 © Find 'string' ¾ in component file ¸.Diversions.·· · baby.427 © The Manchester Small Scale Experimental Machine.· · bf.439 © Brainfuck.· · birthday.324 © Probability of same birthday.· · dice.445 © Interpret a throw of dice.· · draw.445 © Draw over '*'s.· · life.446 © John Conway's "Game of Life".· · keyboards.451 © <strong>APL</strong> keyboard layouts.· · kt.457 © Knight's Tour chess problem.· · mac.464 © Simple Macro Processor for bf.· · mayan.465 © Mayan numbers.· · maze.474 © Kidz maze.· · mmind.477 © Mastermind or "cows and bulls".· · morse.479 © Conversion to/from Morse code.· · mp3.480 © Create playlist(s) for mp3 directories.· · queens.481 © N-queens chess problem.· · quzzle.486 © A hard, simple problem.· · ripple.488 © Perfect Ripple Shuffle.· · rr.489 © Round-robin tournament.· · roman.490 © Roman numeral arithmetic.· · sudoku.491 © Solution vector for Sudoku problem ¾.Performance.·· · cf.497 © Ratio of operand timings.· · cmpx.500 © Approx expression timings.· · mdf.501 © Monitor D function.· · memo.503 © Function memoization.· · ticks.509 © Sample Dfn execution clock ticks.· · time.515 © Time function application.· · wsreq.515 © WS required to execute expression ¾.7


ÚÎÎÎÎÎÎÎÎÎÎÎÌÛ N o t e s ÛÀÎÎÎÎÎÎÎÎÎÎÎÙ9


ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎalistsvalue „ alist ##.alval name © Value of name ¾ in assoc list ¸.alist „ alist ##.alext (name value) © Assoc list ¸ extended with pair ¾.alist „ alist ##.alrem name© Assoc list ¸ with name ¾ removed.values „ alist ##.alvals names © Values of names ¾ in assoc list ¸.alist „ alist ##.alrems names© Assoc list ¸ with names ¾ removed.An association list (AKA: symbol table, dictionary, look-up table) is a classicand generally useful structure. It is implemented as a pair of (names values)vectors. Each item in the names vector would typically be a character vector butit could be anything.An example might be an object owned by each of a number of people:stuff „ ('milly' 'molly' 'may') ('star' 'thing' 'stone')stuff alval 'may'stonestuff alvals 'may' 'milly'stone star© thing associated with May.© May and Milly's things.[alext] and [alrem] extend and remove names from the list, respectively.stuff „ stuff alext 'maggie' 'shell'© add Maggie and her thing.disp stuffÚ…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛÚ…ÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÌÛÚ…ÎÎÎÎÂÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÌÛÛÛmaggieÛmillyÛmollyÛmayÛÛÛshellÛstarÛthingÛstoneÛÛÛÀÎÎÎÎÎ…ÁÎÎÎÎ…ÁÎÎÎÎ…ÁÎÎ…ÙÛÀÎÎÎÎ…ÁÎÎÎ…ÁÎÎÎÎ…ÁÎÎÎÎ…ÙÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…Ùstuff „ stuff alrem'molly'© remove Molly and her thing.disp stuffÚ…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛÚ…ÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÌÛÚ…ÎÎÎÎÂÎÎÎÎÂÎÎÎÎÎÌÛÛÛmaggieÛmillyÛmayÛÛÛshellÛstarÛstoneÛÛÛÀÎÎÎÎÎ…ÁÎÎÎÎ…ÁÎÎ…ÙÛÀÎÎÎÎ…ÁÎÎÎ…ÁÎÎÎÎ…ÙÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÙMultiple names may be removed using [alrems]:disp stuff alrems'may' 'maggie'Ú…ÎÎÎÎÎÎÂÎÎÎÎÎÎÌÛÚ…ÎÎÎÎÌÛÚ…ÎÎÎÌÛÛÛmillyÛÛÛstarÛÛÛÀÎÎÎÎ…ÙÛÀÎÎÎ…ÙÛÀÎÎÎÎÎÎ…ÁÎÎÎÎÎ…ÙDuplicate Names---------------[alext] _prefixes_ a new value to the list. This means that a new association"shadows" an existing one of the same name as far as [alval] and [alvals] areconcerned. [alrem] removes the most recently prefixed name, thus "unshadowing"it.In contrast, [alrems] removes _all_ values associated with the given names.alist alrem 'n1' © pop leftmost n1.alist alrem 'n1'© pop leftmost remaining n1 (if any).alist alrem 'n2' © pop leftmost n2.10alist alrems 'n1' 'n2'© expunge ALL n1s and ALL n2s.


To unshadow, as opposed to expunge, a number of names, use [alrem] with reduction:or†alremþ/²alist 'n1' 'n1' 'n2' ...alist alrem foldl 'n1' 'n1' 'n2' ...© unshadow (pop) several names.© unshadow (pop) several names.Technical notes:[alval] is coded:alval„{names vals„¸ ª (names¼›¾)œvals}it could be coded with the more obscure (and marginally slower):alval„{†¾{(¸¼›¸¸)œ¾}/¸}If the sought name is not in the list, both codings generate INDEX ERROR. It iseasy to tweak the <strong>functions</strong> to return a special "not found" value instead:alval„{names vals„¸ ª (names¼›¾)œvals,›'Eh?'}or:¯¯¯¯¯¯¯alval„{†¾{(¸¼›¸¸)œ¾,›'Eh?'}/¸}¯¯¯¯¯¯¯Destructive Assignment----------------------No function is provided to replace the value of an association. If such an operationwere needed, it could be coded:alrep„{© Assoc list ¸ with (name value) ¾ replaced.names vals„¸© old alist.name val„¾© new value.vals[names¼›name]„›val © replace alist value.names vals© new alist.} © alist „ alist :: (name value)Note that, in the case of duplicate names, [alrep] will replace the value of themost recently associated pair.Graphs------An association list might be used to implement a directed graph. In this case,each name is a vertex of the graph and the corresponding value is a vector ofthe vertices of connecting edges. For example:Graph "a".ÚÎÎÎÎÎA„ÎÎÎÎÌÛ Û Û 5 vertices: A B C D E‡ ‡ ÛB„ÎÎÎ…CÎÎÎÎ…D 8 edges: A…B A…C B…C C…B† Û C…D D…A D…E E…CÛ ‡ÀÎÎÎÎÎECorresponding association list:alist „ 'ABCDE' ('BC' 'C' 'BD' 'AE' 'C')© alist for graph "a" above.BDalist alval 'C'© vertices 1 step from 'C'steps„{†{ž†,/alist alvals ¾}/(¼¸),¾} © vertices ¸ steps from ¾.11


0 steps 'C'C1 steps 'C'BD2 steps 'C'CAE3 steps 'C'BDCExamples:stuff„('milly' 'molly' 'may')('star' 'thing' 'stone')stuff alval 'may'stonestuff alvals 'may' 'milly'stone starstuff „ stuff alext 'maggie' 'shell'© thing associated with May.© May and Milly's things.© add Maggie and her thing.disp stuffÚ…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛÚ…ÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÌÛÚ…ÎÎÎÎÂÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÌÛÛÛmaggieÛmillyÛmollyÛmayÛÛÛshellÛstarÛthingÛstoneÛÛÛÀÎÎÎÎÎ…ÁÎÎÎÎ…ÁÎÎÎÎ…ÁÎÎ…ÙÛÀÎÎÎÎ…ÁÎÎÎ…ÁÎÎÎÎ…ÁÎÎÎÎ…ÙÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…Ùstuff „ stuff alrem'molly'© remove Molly and her thing.disp stuffÚ…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛÚ…ÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÌÛÚ…ÎÎÎÎÂÎÎÎÎÂÎÎÎÎÎÌÛÛÛmaggieÛmillyÛmayÛÛÛshellÛstarÛstoneÛÛÛÀÎÎÎÎÎ…ÁÎÎÎÎ…ÁÎÎ…ÙÛÀÎÎÎÎ…ÁÎÎÎ…ÁÎÎÎÎ…ÙÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…Ùdisp stuff alrems'may' 'maggie'Ú…ÎÎÎÎÎÎÂÎÎÎÎÎÎÌÛÚ…ÎÎÎÎÌÛÚ…ÎÎÎÌÛÛÛmillyÛÛÛstarÛÛÛÀÎÎÎÎ…ÙÛÀÎÎÎ…ÙÛÀÎÎÎÎÎÎ…ÁÎÎÎÎÎ…Ù© remove May and Maggie.See also: Graphs.137 list.54 key.48 foldl.45ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎaccrslt „ (func ##.acc) argt© Accumulating reduction.Phil Last's operator applies its function operand cumulatively between pairs ofitems in its vector argument.Technical note:For a side-effect-free associative operand function, this operator _could_ becoded in terms of primitive scan. However, this scan would be evaluated using(0.5××/0 ¯1+½¾) reductions, resulting in an O(n*2) algorithm.acc„{²¸¸þ\²¾}© slow O(n*2) coding.12


Gianluigi Quario adds this nice surprise:(A few months ago I received some helpful suggestions about polynomial evaluationwhen the polynomial P(Y) is represented (in ascending order) by a vector"poly".P(Y) : poly[0] + Y×poly[1] + Y×poly[2] + ..... +Y×poly[N]I was impressed by this idiom:value „ point {¸+¸¸×¾}/polywhich calculates the value of a real polynomial "poly" at point "point" bymeans of Ruffini's rule and Horner's {¸+¸¸×¾}/ algorithm.I think that this idiom has a greater semantic clarity than the primitive"base value":value „ point ƒ ²polywhich internally uses Horner's algorithm.Over and above it can easily be extended to rectangular arrays by means ofthe following D-fn:PolyEval „ {œ¾{¸+¸¸×¾}/¸}In fact we can play:values „ poly PolyEval pointseven when "points" is an array .But I had another surprise when I matched the Horner's algorithm with [acc].If we write:point {¸+¸¸×¾} acc polyinstead ofpoint {¸+¸¸×¾} / polywe obtain not only the value of the polynomial at point "point", i.e. theremainder of division of poly with monomial "Y-point" , but also the quotientpolynomial according to Ruffini's rule, which we studied at school.If P(Y) is a polynomial and "Y - point" a monomial, then substituting"{¸+¸¸×¾}/" with "{¸+¸¸×¾} acc" returns the quotient polynomial Q(Y) and theremainder polynomial R(Y) of the polynomial division.By means of the simple idiom {¸+¸¸×¾} and operator "acc" it is possible toimplement the Ruffini simple_division_rule between a polynomial and a monomialwith neither iterations nor recursions.The use of operator "acc" is performing something similar to:Œ„poly[0] + point׌„poly[1] +point׌„poly[2] + ..... + point׌„poly[N]Now we are the masters of a holistic window on Ruffini's rule for simpledivision.13


)"** <strong>APL</strong> is an actual tool for supporting the chains of reasoning andcreating knowledge **" - Gianluigi Quario.Examples:disp {¸,'f',¾}acc'abcd'Ú…ÎÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÂÎÌÛafbfcfdÛbfcfdÛcfdÛdÛÀÎÎÎÎÎÎ…ÁÎÎÎÎ…ÁÎÎ…ÁÎÙdisp ,acc ¼4Ú…ÎÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÂÎÌÛ1 2 3 4Û2 3 4Û3 4Û4ÛÀ~ÎÎÎÎÎ…Á~ÎÎÎ…Á~Î…ÁÎÙslow„{²¸¸þ\²¾}disp ,slow ¼4Ú…ÎÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÂÎÌÛ1 2 3 4Û2 3 4Û3 4Û4ÛÀ~ÎÎÎÎÎ…Á~ÎÎÎ…Á~Î…ÁÎÙŠacc 1 0 00 1 0Šslow 1 0 01 1 0© O(n*2) coding.© slow coding concurs for associative operand fn.© Š is non-associative (although it is commutative).© slow coding differs for non-associative operand.See also: pred.72 scan.79 traj.220 while.221 foldl.45 trav.130ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎbagsz „ l (fn ##.bags) r© Multisets/bags.Operator [bags] models the Parks-Smith proposal for a $ operator, which addsMultisets to <strong>APL</strong>.A "Multiset" or "bag" has attributes of both a vector and a set in that, like avector, it may have duplicate items and, like a set, the order of its items isnot significant.[bags] is an operator, which treats its arguments as if they were multisets.101 2 2 3 ­bags 2 1 3 2 © multiset item-order is not significant.1 2 2 3 ­bags 1 2 3 3 © multiset duplicate count is significant.Illustration------------Given two vectors, which we want to view as multisets:A „ 2 1 2 1 3 2 5B „ 3 4 2 1 2 3By permuting the vector items and indenting the second one, we can arrange thatall coincident items (if any) are aligned:14ÚÎÎÎÎÎÎÎÎÎ © coincident items 1 2 2 3ÚÎÎÁÎÎÌA „ 1 2 5 1 2 2 3 © permutation of 1st vector.B „ 1 2 2 3 4 3 © .. 2nd ..ÀÎÎÎÎÎÙ


now various multiset <strong>functions</strong> can be illustrated so:ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ A ~bags B … 1 2 5 © asymmetric difference.Û ÚÎÎÎÎÎÎÎÎÎÎ A •bags B … 1 2 2 3 © intersection.ÚÎÁÎÌ ÚÎÎÁÎÎÌ ÚÎÎÎÎ B ~bags A … 4 3 © asymmetric difference.A „ 1 2 5 1 2 2 3 ÚÁÌB „ Û Û 1 2 2 3 4 3ÀÎÂÎÙ ÀÎÎÎÎÎÙ ÀÂÙÛ ÀÎÎÎÎÎÎÎÎÎÎÎÎÁÎÎ A('§'bags)B … 1 2 5 4 3 © symmetric difference.ÀÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÙÀÎÎÎÎÎÎÎÎÎÎÎ A žbags B … 1 2 5 1 2 2 3 4 3 © union.Searching <strong>functions</strong> ¼ and ¹ take account of duplicate items in multisets:8 7 8 ¼bags 8 8 8 81 3 4 48 8 8 8 ¹bags 8 7 81 1 0 0In all, bags is defined for operands:­ match.» natch.~ multiset asymmetric difference (MAD)'§' multiset symmetric difference (MSD) *ž unique/union.• intersection.¹ progressive membership. Smith [2]¼ progressive dyadic iota. Finn<strong>APL</strong> Idiom List [3][*] operand § must be enclosed in quotes, see example below. Note also that thederived function ('§'bags) must be parenthesised in order to prevent operand '§'from binding with the left argument: larg('§'bags)rarg. Alternatively, we mightprefer to name '§'bags:1 41 41 2 3 ('§'bags) 2 3 4msd „ '§'bags1 2 3 msd 2 3 4To allow for extending this operand set in the future, operands not in this listgenerate a NONCE ERROR.Refs:[0] Parks-Smith paper "Proposal for Multiset Features in <strong>APL</strong>"[1] http://en.wikipedia.org/wiki/Multiset[2] http://www.sudleyplace.com/<strong>APL</strong>/AnatomyOfAnIdiom.ahtml[3] http://nsg.upor.net/jpage/finnapl.pdfExamples:2 2 31 2 3 1 2 3 ~bags 1 1 3 1 © multiset asymmetric difference (MAD)1 1 1 2 2 3 ('§'bags) 1 2 2 3 3 3 © multiset symmetric difference (MSD)1 1 3 31 2 3 1 2 3 ¼bags 1 1 3 1 © progressive dyadic iota (PDI)1 4 3 73 1 3 ¹bags 3 1 1 2 © progressive dyadic epsilon (PDE)1 1 015


(›1 2 2) ­bags¨ (1 2)(2 2 1)(1 1 2) © match0 1 0(›1 2 2) »bags¨ (1 2)(2 2 1)(1 1 2) © natch1 0 11 2 2 3 žbags 2 3 3 © union1 2 2 3 3žbags 1 1 2 21 1 2 2© unique is a no-op1 2 2 3 •bags 2 3 3 2 © intersection2 2 31 2 3 3 1 2 3 ,bags 3 1 3 © non-multiset function1 2 3 3 1 2 3 3 1 31'tick' 'tock' ­bags 'tock' 'tick'A„?10/5 ª B„?10/5© nested args.© vectors with repeated items.1111(A žbags B) ­bags (B žbags A) © multiset-union is commutative.(A •bags B) ­bags (B •bags A) © multiset-intersection is commutative.msd„'§'bags ª (A msd B) ­bags (B msd A) © MSD is commutative.(¼½A) ­ A ¼bags A© progressive dyadic iota.ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎboxcmat „ {h v t„« « 0} ##.box text © Box the simple text array ¾.Supplied by Veli-Matti Jantunen, [box] applies borders and horizontal and verticaldividers to simple character matrix [text].Optional left argument (default « « 0) determines whether to draw borders andwhere to draw dividers.¸: [1] = horizontal lines[2] = vertical linesAn optional 3rd item specifies line type:[3] = type: 0 = box drawing chars, 1 = raw boxingFor example:box 6 10½ŒaÚÎÎÎÎÎÎÎÎÎÎÌÛABCDEFGHIJÛÛKLMNOPQRSTÛÛUVWXYZABCDÛÛEFGHIJKLMNÛÛOPQRSTUVWXÛÛYZABCDEFGHÛÀÎÎÎÎÎÎÎÎÎÎÙ© Borders but no dividers, by default.16


ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ Horizontal dividers after 2nd and 4th row.Û ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ Vertical dividers after 3rd, 6th and 7th column.Û Û(2 4)(3 6 7)box 6 10½ŒaÚÎÎÎÂÎÎÎÂÎÂÎÎÎÌÛABCÛDEFÛGÛHIJÛÛKLMÛNOPÛQÛRSTÛÃÎÎÎÏÎÎÎÏÎÏÎÎÎÝÛUVWÛXYZÛAÛBCDÛÛEFGÛHIJÛKÛLMNÛÃÎÎÎÏÎÎÎÏÎÏÎÎÎÝÛOPQÛRSTÛUÛVWXÛÛYZAÛBCDÛEÛFGHÛÀÎÎÎÁÎÎÎÁÎÁÎÎÎÙÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ No horizontal dividers.Û ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ Vertical dividers after each column.Û Û«(¼5) box 5 5½ŒaÚÎÂÎÂÎÂÎÂÎÌÛAÛBÛCÛDÛEÛÛFÛGÛHÛIÛJÛÛKÛLÛMÛNÛOÛÛPÛQÛRÛSÛTÛÛUÛVÛWÛXÛYÛÀÎÁÎÁÎÁÎÁÎÙThe horizontal or vertical border may be switched off by prefixing ¯1 to thefirst or second control item, respectively.ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ Horizontal dividers after 2nd and 3rd rows.Û ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ Vertical dividers after 1st and 4th cols.Û Û(2 3)(1 4) box 5 5½ŒaÚÎÂÎÎÎÂÎÌÛAÛBCDÛEÛÛFÛGHIÛJÛÃÎÏÎÎÎÏÎÝÛKÛLMNÛOÛÃÎÏÎÎÎÏÎÝÛPÛQRSÛTÛÛUÛVWXÛYÛÀÎÁÎÎÎÁÎÙÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ Same again but with no horizontal border.Û(¯1 2 3)(1 4) box 5 5½ŒaÛAÛBCDÛEÛÛFÛGHIÛJÛÃÎÏÎÎÎÏÎÝÛKÛLMNÛOÛÃÎÏÎÎÎÏÎÝÛPÛQRSÛTÛÛUÛVWXÛYÛ17


ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎ Same again but with no vertical border.Û(2 3)(¯1 1 4) box 5 5½ŒaÎÂÎÎÎÂÎAÛBCDÛEFÛGHIÛJÎÏÎÎÎÏÎKÛLMNÛOÎÏÎÎÎÏÎPÛQRSÛTUÛVWXÛYÎÁÎÎÎÁÎÚÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎ Same again but with no vertical border.Û Û(¯1 2 3)(¯1 1 4) box 5 5½ŒaAÛBCDÛEFÛGHIÛJÎÏÎÎÎÏÎKÛLMNÛOÎÏÎÎÎÏÎPÛQRSÛTUÛVWXÛYA divider index of 0 or the number of rows or columns is interpreted as specifyingthe border and so overrides a ¯1 border supressor.ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ Dividers after 1st and 2nd row.Û(1 2)« box 3 10½ŒaÚÎÎÎÎÎÎÎÎÎÎÌÛABCDEFGHIJÛÃÎÎÎÎÎÎÎÎÎÎÝÛKLMNOPQRSTÛÃÎÎÎÎÎÎÎÎÎÎÝÛUVWXYZABCDÛÀÎÎÎÎÎÎÎÎÎÎÙÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ Same again, with horizontal borders supressed.Û(¯1 1 2)« box 3 10½ŒaÛABCDEFGHIJÛÃÎÎÎÎÎÎÎÎÎÎÝÛKLMNOPQRSTÛÃÎÎÎÎÎÎÎÎÎÎÝÛUVWXYZABCDÛÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ Same again, with explicit upper border (dividerÛafter 0th row).Û(¯1 0 1 2)« box 3 10½ŒaÚÎÎÎÎÎÎÎÎÎÎÌÛABCDEFGHIJÛÃÎÎÎÎÎÎÎÎÎÎÝÛKLMNOPQRSTÛÃÎÎÎÎÎÎÎÎÎÎÝÛUVWXYZABCDÛ18


ÚÎÎÎÎÎÎÎÎÎÎÎÎÎ Same again, with explicit lower border (dividerÛafter 3rd row).Û(¯1 1 2 3)« box 3 10½ŒaÛABCDEFGHIJÛÃÎÎÎÎÎÎÎÎÎÎÝÛKLMNOPQRSTÛÃÎÎÎÎÎÎÎÎÎÎÝÛUVWXYZABCDÛÀÎÎÎÎÎÎÎÎÎÎÙFinally, a third item of the left argument may be given to specify the type ofthe border and divider lines:0 (default) "smooth" box drawing characters1 · · "raw" characters, which are more suitable for printing.Examples:a„3 10½Œa © Simple array.box aÚÎÎÎÎÎÎÎÎÎÎÌÛABCDEFGHIJÛÛKLMNOPQRSTÛÛUVWXYZABCDÛÀÎÎÎÎÎÎÎÎÎÎÙ© simple case1 box a © draw a row..ÚÎÎÎÎÎÎÎÎÎÎÌÛABCDEFGHIJÛÃÎÎÎÎÎÎÎÎÎÎÝÛKLMNOPQRSTÛÛUVWXYZABCDÛÀÎÎÎÎÎÎÎÎÎÎÙ« (¼5) box a © ..and columnsÚÎÂÎÂÎÂÎÂÎÂÎÎÎÎÎÌÛAÛBÛCÛDÛEÛFGHIJÛÛKÛLÛMÛNÛOÛPQRSTÛÛUÛVÛWÛXÛYÛZABCDÛÀÎÁÎÁÎÁÎÁÎÁÎÎÎÎÎÙ(1 2) (2+¼3) box a © bothÚÎÎÎÂÎÂÎÂÎÎÎÎÎÌÛABCÛDÛEÛFGHIJÛÃÎÎÎÏÎÏÎÏÎÎÎÎÎÝÛKLMÛNÛOÛPQRSTÛÃÎÎÎÏÎÏÎÏÎÎÎÎÎÝÛUVWÛXÛYÛZABCDÛÀÎÎÎÁÎÁÎÁÎÎÎÎÎÙ2 « 1 box a © raw case+----------+|ABCDEFGHIJ||KLMNOPQRST|+----------+|UVWXYZABCD|+----------+(¯1) (2+¼5) box a © no horiz linesÛABCÛDÛEÛFÛGÛHIJÛÛKLMÛNÛOÛPÛQÛRSTÛÛUVWÛXÛYÛZÛAÛBCDÛ19


(¯1 1 3) (2+¼5) box a © draw bottomÛABCÛDÛEÛFÛGÛHIJÛÃÎÎÎÏÎÏÎÏÎÏÎÏÎÎÎÝÛKLMÛNÛOÛPÛQÛRSTÛÛUVWÛXÛYÛZÛAÛBCDÛÀÎÎÎÁÎÁÎÁÎÁÎÁÎÎÎÙ(¯1 0 1) (¯1 9 10) box a © variantÎÎÎÎÎÎÎÎÎÂÎÌABCDEFGHIÛJÛÎÎÎÎÎÎÎÎÎÏÎÝKLMNOPQRSÛTÛUVWXYZABCÛDÛOÛOÛXÎÏÎÏÎOÛXÛOÎÏÎÏÎXÛXÛ(¯1 1 2) (¯1 1 2) box †'OOX' 'OXO' 'XX ' © I won!See also: disp.31 display.35 draw.445ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎchksumsum „ {digs„6} ##.chksum array© Simple ¸-digit checksum.A checksum can be considered as a "signature" for a set of data and so may beused to verify that the data has not been modified or corrupted.[chksum] returns a (by default 6-digit-) checksum for its argument array ¾.NB: Check-summing and hashing systems typically map a large set of data valuesonto a significantly smaller set of sums. It is therefore inevitable that therebe "clashes", where different values map to the same sum.This means that a good checksum algorithm guarantees that:- If the checksum has changed, then the array has _certainly_ changed.- If the checksum has not changed, then the array has _probably_ not changed.The art of creating useful checksums is to balance the conflicting requirementsto:- Produce a fast-enough summing function for large volumes of data.- Maximise sensitivity to typical changes in the data.For example, a simple approach might be an ¸-residue sum of the data bytes. However,this would not detect added or removed 0-values or reordering of dataitems. For this reason, a "weighted sum" is often used.There is a large body of literature devoted to the subject. See, for example:http://en.wikipedia.org/wiki/ChecksumBug: [chksum] ignores array items that are namespace references (refs).Bug: [chksum] ignores ŒNULL.Bug: [chksum] crashes (DOMAIN ERROR) on encountering a ŒOR item.Technical notes:[chksum] returns the weighted sum of the:the byte vector of: the shape followed by a ¯1 separatorfollowed bythe byte vector of the ravel of the array.20


where byte vectors for various item (ŒDR) types are the:nested:concatenation of the byte vectors of subarrays.boolean:(0 and 1) items themselves.numeric:(256|83 ŒDR) byte-values.ŒAV-vector: origin-0 ŒAV-indices.Unicode vector: (256|83 ŒDR) byte-values of ŒUCS unicode indices.Separating the last two cases above ensures that [chksum] returns the same resultfor character arrays in Unicode and Classic versions of <strong>Dyalog</strong>.In order to distinguish null arrays of differing types, such arrays are representedby their prototypical items.Note that in versions of <strong>Dyalog</strong> <strong>APL</strong> prior to V10.1, we must explicitly "squeeze"integer arrays prior to (ŒDR-) converting them to byte-values. This is so thatidentical integers, whose internal representations differ, produce the samechecksum.Examples:chksum Œcr'chksum'314685© simple char arraychksum Œnr'chksum' © nested .. ..930686chksum 1 2 3 °.± 4 5 6412967chksum¨(1 3 2)(2 1 3)538 538chksum¨'' «1295 1275© simple numeric array.© clash: values with same chksum.© distinct nulls.© Checksumming the notes in this workspace is reasonably quick:chksum time notes.(–¨‡Œnl 2)00.16© time checksumming of notes namespace.0chksum # © checksum of ref is 0.See also: time.515ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎcmatmat „ m ##.cmat n© ¸-combination matrix of ¼¾.Returns an m!n-row, m-column, matrix of the m-item combination vectors of ¼n.Both rows and row items of the result are in ascending order, thus for any¸ ¾‰0:{¾­¼½¾}“¸ cmat ¾^/{{¾­¼½¾}“¾}¨‡¸ cmat ¾© Rows in ascending order.© Items in each row in ascending order.Technical notes:Notice that a combination matrix can be divided into sections, some of which arethemselves, combination matrices. For example:21


ÚÎÂÎÎÎÌ ÚÎÎÎÌ1 2 3 Û1Û2 3Û Û1 2Û1 2 4 Û1Û2 4Û Û1 3Û1 2 5 Û1Û2 5Û 1 , 1 + Û1 4Û 1 , 1 + 2 cmat 41 3 4 Û1Û3 4Û Û2 3Û3 cmat 5 => 1 3 5 => Û1Û3 5Û => ® Û2 4Û => ®1 4 5 Û1Û4 5Û Û3 4Û2 3 4 ÃÎÁÎÎÎÝ ÀÎÎÎÙ2 3 5 Û2 3 4Û ÚÎÎÎÎÎÌ2 4 5 Û2 3 5Û 1 + Û1 2 3Û 1 + 3 cmat 43 4 5 Û2 4 5Û Û1 2 4ÛÛ3 4 5ÛÀÎÎÎÎÎÙÛ1 3 4ÛÛ2 3 4ÛÀÎÎÎÎÎÙThis observation leads to the recurrence relationship:¸ cmat ¾ „… (1,1+(¸-1)cmat ¾-1)®1+¸ cmat ¾-1Successive transformations of the expression on the right, produce:ExpressionTransformation---------- --------------(1,1+(¸-1)cmat ¾-1)®1+¸ cmat ¾-1 [0] cmat … ’¯¯¯¯¯¯¯¯… (1,1+(¸-1)’¾-1)®1+¸ ’¾-1 [1] ¸®¾ … †®/¸ ¾¯… †®/(1,1+(¸-1)’ ¾-1)(1+¸ ’ ¾-1) [2] ¸ ¾ … ² ¾ ¸¯¯¯¯¯¯¯¯¯¯¯¯¯¯ ¯¯¯¯¯¯¯¯¯… †®/²(1+¸ ’ ¾-1)(1,1+(¸-1)’¾-1) [3] ¸({}¾) … {}\¸ ¾¯¯… †®/²{1,¾}\(1+¸ ’ ¾-1)(1+(¸-1)’¾-1) [4] (1+¸)(1+¾) … 1+¸ ¾¯¯¯¯… †®/²{1,¾}\1+(¸ ’ ¾-1)((¸-1)’¾-1) [5] (¸{}¾)(ß{}¾) … ¸ ß{}¨›¾¯¯¯ ¯¯¯¯¯¯… †®/²{1,¾}\1+(¸-0 1)¨’¾-1 [6]Notice transformation[3]: ¸({}¾) … {}\¸ ¾, which applies a function to the_second_ item of a 2-vector. Using this technique, we can avoid temporary localnames in situations such as:lft rgt„pair ª lft({···¾}rgt){···¾}\pair© clumsier.© neater.The base cases for the recursion are:0 cmat ¾ … 1 0½0¸ cmat 0 … 0 ¸½0or:0¹¸ ¾:(¸=0)¸½0The (index-origin independent) code is therefore:cmat„{© ¸-combination matrix of ¼¾.0¹¸ ¾:(¸=0)¸½0 © done if zero ¸ or ¾, otherwise,†®/²{ŒIO,¾}\1+(¸-0 1)’¨¾-1 © catenate sub-combinations.}Notice however, that the algorithm is inefficient in the same way as a naïvecoding of …fibonacci„, in that the function is applied to the _same_ argumentsmany times over. If we display the arguments for the function calls as a tree,by injecting:22


Œ„(,†(½ŒLC)½›'· '),'[',(•¸ ¾),']'as the first line of the function, we see the following "dependency tree", where[¸ ¾] stands for (¸ cmat ¾):2 cmat 4· [2 4]· · [2 3]· · · [2 2]· · · · [2 1]· · · · · [2 0]· · · · · [1 0]· · · · [1 1]· · · · · [1 0]· · · · · [0 0]· · · [1 2]· · · · [1 1]· · · · · [1 0]· · · · · [0 0]· · · · [0 1]· · [1 3]· · · [1 2]· · · · [1 1]· · · · · [1 0]· · · · · [0 0]· · · · [0 1]· · · [0 2]This is interpreted:[2 4] depends on· [2 3] which depends on· · [2 2] which depends on· · ···and· · [1 2] which depends on © [1 2] evaluated here.· · ···and· [1 3] which depends on· · [1 2] which depends on © [1 2] evaluated again here.· · ······ and so on.Notice how [1 2], together with its whole sub tree, is evaluated twice. In thiscase, [2 4] generates 21 function calls. This number increases very rapidly andin general, [¾ ¾] generates (¯1+2*¾+1) calls.ÚÎÌ ÚÎÎÎÌThe dependencies are better represented as a _lattice_, where Û†Û and Û„--Û mean"depends on": Û|Û ÀÎÎÎÙÀÎÙ[2 4]„--[2 3]„--[2 2]„--[2 1]„--[2 0]† † † †| | | |[1 3]„--[1 2]„--[1 1]„--[1 0]† † †| | |[0 2] [0 1] [0 0]This expresses exactly the same recurrence relationship as the tree, except thatin this representation, the nodes are _shared_. Notice how the lattice has only12, as opposed to the tree's 21 nodes. If we can find a way to evaluate each ofits nodes only once, a significant performance benefit should result.23


In fact, we can do a little better than this. We chose [¸ 0] and [0 ¾] as basecases for the recursion, because we can "conjure these results out of thin air".Looking at the lattice, we see a column at the base of the "ramp", which hasvalues [2 2] [1 1] [0 0]. As we know that [¾ ¾] = (1 ¾½¼¾) for all ¾, we canequally easily use [¾ ¾] and [0 ¾] as base cases, as long as we make specialprovision for starting values from _inside_ the ramp where ¸>¾. This enables usto trim the lattice to:[2 4]„--[2 3]„--[2 2]† †| |[1 3]„--[1 2]„--[1 1]† †| |[0 2] [0 1]A slightly larger example (4 cmat 8), shows more clearly what's going on. Noticethat this lattice has 24 nodes, while its corresponding dependency _tree_ wouldhave 325.[4 8]„--[4 7]„--[4 6]„--[4 5]„--[4 4]† † † †| | | |[3 7]„--[3 6]„--[3 5]„--[3 4]„--[3 3]† † † †| | | |[2 6]„--[2 5]„--[2 4]„--[2 3]„--[2 2]† † † †| | | |[1 5]„--[1 4]„--[1 3]„--[1 2]„--[1 1]† † † †| | | |[0 4] [0 3] [0 2] [0 1]The diagram suggests using right-to-left or bottom-to-top _reduction_ toaccumulate values towards the top left corner which is the required result. Forreasons that will become apparent, reduction from the right turns out to be aslightly better bet. Using ŒML„2, so that "†" means "first":††{¸···¾}/ [0 4] ··· [0 2] [0 1] ,› [4 4] ··· [2 2] [1 1]Now, as the [0 ¾]'s all have the same value: (1 0½0), we can substitute thisvalue for ¸ _inside_ the reduction's operand and ignore the value that is passedinto the operand function as left argument. This means that we may replace thevector [0 4] ··· [0 2] [0 1] by _any_ vector providing it has the same number ofitems: (¼¾-¸) will suffice.††{(1 0½0)···¾}/ (¼¾-¸),› [4 4] ··· [2 2] [1 1]Finally, to squeeze out the last drop of refinement, we can compute the littlearray (1 0½0) just once and bind it as an operand to the reduction's operand,where it becomes "¸¸".††(1 0½0){¸¸···¾}/ (¼¾-¸),› [4 4] ··· [2 2] [1 1]The base cases: [4 4] ··· [2 2] [1 1], evaluate to ({1 ¾½¼¾}¨+\¸½1), noting that(+\¸½1) is an origin independent expression for "1 to ¸", which gives:††(1 0½0){¸¸···¾}/ (¼¾-¸),›{1 ¾½¼¾}¨+\¸½1At this point, we can cover the "special provision" for the null case where ¸>¾.The result is a matrix of shape (0 ¸), so the reshape becomes: (¸ˆ¾){¸ ¾½¼¾}.24††(1 0½0){¸¸···¾}/ (¼¾-¸),›(¸ˆ¾){¸ ¾½¼¾}¨+\¸½1


Now all that remains, is to code the workings of the reduction's operand:{¸¸···¾}. Each application of the operand will take a _column_ of the lattice asright argument and a nominal [0 ¾] as left operand.Transposing the rightmost column of the lattice above, the operand will beapplied to: ¾: [4 4] [3 3] [2 2] [1 1] ¸¸: [0 1]‡ ‡ ‡ ‡ ‡with result: [4 5]„--[3 4]„--[2 3]„--[1 2]„-----'To achieve this result, we need to do a further, but this time, _cumulative_reduction. Without accumulation, the result of the "inner" reduction in the caseabove would be [4 5], whereas we need the whole vector [4 5] ··· [1 2], but excludingthe initial base case ¸¸:[0 1], to pass back to the outer reduction. Thetemplate for such a reduction is:¯1‡†{(¸ ··· †¾),¾}/(›···),···,(›···),(››···)ÛÛ Û Û Û Û Û ÀÎÎÎÎÎÎ _Extra_ rightmost enclosure,ÛÛ Û Û Û Û Û for accumulation.ÛÛ Û Û Û ÀÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎ Items of reduction argument.ÛÛ Û Û ÀÎÎÎ Prefix new result item to accumulation.ÛÛ Û ÀÎÎÎÎÎÎ First item of accumulated result.ÛÛ ÀÎÎÎÎÎÎÎÎÎ Operation between successive left and right args.ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ Disclose vector result of vector reduction.ÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ Discard initial base case ¸¸:[0 1].Substituting our specific cases:¯1‡†{(¸ ··· †¾),¾}/¾,››¸¸The remaining "···" is exactly the expression developed right back at the startfor the "tree" algorithm: ®/²{ŒIO,¾}\1+···, so the complete operand function is:¯1‡†{(®/²{ŒIO,¾}\1+¸(†¾)),¾}/¾,››¸¸A last tweak is to "factor out" (››¸¸) to where ¸¸ is generated, so that:···(1 0½0){···{···}/¾,››¸¸}/···becomes: __ ¯¯···(››1 0½0){···{···}/¾,¸¸}/···The final code looks like this. Notice that apart from the specification of ŒML,it's a one-liner. More to the point, there are no assignments, tests or controlbranches; it is a single expression:cmat„{ŒML„2© ¸-combination matrix of ¼¾.††(››1 0½0){ © base-case: [0 ¾].¯1‡†{© removing base case from,(®/²{ŒIO,¾}\1+¸(†¾)),¾ © accumulation of,}/¾,¸¸© sub- (¸ ¾-1) combinations,}/(¼0—¾-¸),›(¸ˆ¾){¸ ¾½¼¾}¨²+\¸½1 © with base cases [¸ 0].}Alternative codings-------------------John Niss Hansen suggests the following much simpler coding. Effectively,the function generates all binary numbers of width ¾ and selects those with ¸bits set. Each binary "mask" is then used to select a different ¸ combination ofnumbers from 0 to ¾-1. This works well for small values of ¾ but the subexpression(¼¾½2) uses an exponential amount of space (and time) as ¾ getslarger. The function assumes Œio=0 and Œml


VMJ suggests the following one-line speedy alternative for small-to-medium sizedresults.and also:cmat„{ŒML„3 ª œœ{{(wd:¾a„2œ¾b„mx-a+wd-¸ ª q„¹a+¼¨b(¸+1)’((b/†¾),¨q)q}2½›¼¾-¸-1This version is based on Ken Gradney's code, which was published in Vector Vol18.1:cmat„{ŒML„3 ª n„1+¾-¸ ª c„(¸-1)+¼n}c{ŒIO‰†¸:†¾m„²+\²†1‡¾(¸-1)’((m/¸-1),(†¾)[¹((†m)-m)+¼¨m;])m}((n,1)½c)(n½1)Roger Hui proposes this short coding:cmat„{´œ®/{k,¨®\1+¾}ÿ¸€(›³®«),d½›0 0½k„²¼1+d„¾-¸}which is faster than the others except on really large arguments (when it is abit slower).Roger says: The ´ is needed because <strong>Dyalog</strong> does not have "suffix scan" (´f´¾).I am led to doing the regular <strong>APL</strong> scan on the reversed argument, then reversingthe whole thing at the end.Examples:ڴ̇0ÛÀ~Ùڅ̇1ÛÛ2ÛÛ3ÛÛ4ÛÛ5ÛÀ~Ùdisplay 0 cmat 5display 1 cmat 526


Ú…ÎÎ̇1 2ÛÛ1 3ÛÛ1 4ÛÛ1 5ÛÛ2 3ÛÛ2 4ÛÛ2 5ÛÛ3 4ÛÛ3 5ÛÛ4 5ÛÀ~ÎÎÙdisplay 2 cmat 5display 3 cmat 5Ú…ÎÎÎÎ̇1 2 3ÛÛ1 2 4ÛÛ1 2 5ÛÛ1 3 4ÛÛ1 3 5ÛÛ1 4 5ÛÛ2 3 4ÛÛ2 3 5ÛÛ2 4 5ÛÛ3 4 5ÛÀ~ÎÎÎÎÙdisplay 4 cmat 5Ú…ÎÎÎÎÎÎ̇1 2 3 4ÛÛ1 2 3 5ÛÛ1 2 4 5ÛÛ1 3 4 5ÛÛ2 3 4 5ÛÀ~ÎÎÎÎÎÎÙdisplay 5 cmat 5Ú…ÎÎÎÎÎÎÎÎ̇1 2 3 4 5ÛÀ~ÎÎÎÎÎÎÎÎÙdisplay 6 cmat 5Ú…ÎÎÎÎÎÎÎÎÎÎ̲0 0 0 0 0 0ÛÀ~ÎÎÎÎÎÎÎÎÎÎÙ³†{½¾ cmat 5}¨0 to 61 5 10 10 5 1 00 1 2 3 4 5 6© Row and column sizes.2{¾[¸ cmat½¾]}'scissors' 'paper' 'stone' © 2-combos of nested vector.scissors paperscissors stonepaper stone‡3{¾[¸ cmat½¾]}'abcde'© 3-combos of char vector.abc abd abe acd ace ade bcd bce bde cde27


display¨0 1 2 3°.cmat 0 1 2 3 © Combos of small vectors.Ú´Ì Ú´Ì Ú´Ì Ú´Ì‡0Û ‡0Û ‡0Û ‡0ÛÀ~Ù À~Ù À~Ù À~ÙÚ…Ì Ú…Ì Ú…Ì Ú…Ì²0Û ‡1Û ‡1Û ‡1ÛÀ~Ù À~Ù Û2Û Û2ÛÀ~ÙÛ3ÛÀ~ÙÚ…ÎÎÌ Ú…ÎÎÌ Ú…ÎÎÌ Ú…ÎÎ̲0 0Û ²0 0Û ‡1 2Û ‡1 2ÛÀ~ÎÎÙ À~ÎÎÙ À~ÎÎÙ Û1 3ÛÛ2 3ÛÀ~ÎÎÙÚ…ÎÎÎÎÌ Ú…ÎÎÎÎÌ Ú…ÎÎÎÎÌ Ú…ÎÎÎÎ̲0 0 0Û ²0 0 0Û ²0 0 0Û ‡1 2 3ÛÀ~ÎÎÎÎÙ À~ÎÎÎÎÙ À~ÎÎÎÎÙ À~ÎÎÎÎÙ0 10 20 31 21 32 3Œio„0 ª 2 cmat 4© Code is "origin sensitive".³ °.{«½½¸ cmat ¾}þ 0 to 12 © Pascal's triangle.1 0 0 0 0 0 0 0 0 0 0 0 01 1 0 0 0 0 0 0 0 0 0 0 01 2 1 0 0 0 0 0 0 0 0 0 01 3 3 1 0 0 0 0 0 0 0 0 01 4 6 4 1 0 0 0 0 0 0 0 01 5 10 10 5 1 0 0 0 0 0 0 01 6 15 20 15 6 1 0 0 0 0 0 01 7 21 35 35 21 7 1 0 0 0 0 01 8 28 56 70 56 28 8 1 0 0 0 01 9 36 84 126 126 84 36 9 1 0 0 01 10 45 120 210 252 210 120 45 10 1 0 01 11 55 165 330 462 462 330 165 55 11 1 01 12 66 220 495 792 924 792 495 220 66 12 1See also: pmat.71 fibonacci.279 rr.489ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎcolscmat „ {gap„1 {max„Œpw}} ##.cols items © Multi-column display.Sometimes it's easier to peruse an alphabetic list of items if they are arrangedvertically in columns (where typically, the last column will be incomplete).[cols] returns a multi-column character-matrix format of the items in its rightargument.[items] may be a vector or a matrix. In the latter case, _rows_ of the matrix,with trailing blanks removed, are taken as the items of the list.Optional left arguments [gap] (default 1) and [max] (default Œpw) specify theinter-column-gap and maximum "print width" of the display respectively.If any of the items are wider than [max], the result is a single column, withlonger items truncated to [max] characters.Cols is similar to the Unix shell commmand "c -v".28


1 20 cols ¼26 © width ˆ 20-column format of vector.1 5 9 13 17 21 252 6 10 14 18 22 263 7 11 15 19 234 8 12 16 20 240 8 cols Œa © width ˆ 8-column format of vector.AEIMQUYBFJNRVZCGKOSWDHLPTXcols ŒNL 4© width ˆ ŒPW-column format of char matrix._fk bags cond file invr logic nats rank rows ticks vofacc big cx fk kcell loop of rats sam time vwiseand bsearch dft fk_ key ltrav or ratsum saw trace whileascan bt do fnarray lex mdf perv ravt sbst traj UndoRedoascana case each foldl limit memo pow redblack splay travavl cf else for lof merge pred roman squad untilTechnical note:There is a circular problem in deciding the optimal number of columns in whichto arrange our vector: until the columns are arranged, we don't know which willbe the widest item in each column and so how wide the column as a whole will be;and until we know the width of each column, we don't know how many columns touse.Here is an example of a vector whose 2-column arrangement is wider than its 3-column arrangement:vec „ 1 1 1000000 1000000 1 1³2 3½vec © 2 cols … width 15.1 10000001 11000000 1³3 2½vec © 3 cols … width 11.1 1000000 11 1000000 1For this reason, it is not easy to "home in" on an optimal solution using, forexample, a binary search (…bsearch„) technique. Instead, we search one column ata time. We could equally well search a row at a time, but for large lists, whereperformance might be a consideration, the number of rows would, typically, farexceed the maximum "print width".The not-very-subtle solution adopted here is to start with the maximum possiblenumber of columns and to keep reducing this number until the gap-separated columnswould fit within the required width. We don't need to use the items themselvesfor this exploration; a vector of their lengths will suffice.Inner function "maxcols" calculates the maximum number of columns. It employsa small optimisation, which allows us to avoid some of the calculation. For example,trying to arrange 9 items down 4 columns is infeasible because 2 rowswould require 5 columns and 3 rows would need only 3.Given "ni", the number of items and ¾, the number of columns to attempt, wecalculate the implied number of rows together with the "excess" number of unusedrows in the final, right-most, column. Notice the use of <strong>APL</strong>'s encode "‚" functionwith a negative argument:nr xs„|0 ¾‚-nixs‰nr:’ ¾-1© number of rows and excess.© one or more empty columns: ignore.29


For example, to see if we can arrange 9 items along 4 rows, we might first thinkto code:2 10 4‚9 © 2 complete rows, remainder 1 item.But this is not quite right; we need to know how many rows (complete or not) areoccupied, together with how many rows would be left unoccupied in the final column(s).If the excess is equal to or greater than the number of rows, then wecan ignore this (¾-columns) case as it is identical to a smaller value of ¾,which we will encounter later. Instead, we code:3 3|0 4‚-9 © 3 used rows, with 3 free rows in the final column (no good).... representing an infeasible arrangement, which may be ignored.Examples:cols ¼123© default multi-column display of vector.1 6 11 16 21 26 31 36 41 46 51 56 61 66 71 76 81 86 91 96 101 106 111 116 1212 7 12 17 22 27 32 37 42 47 52 57 62 67 72 77 82 87 92 97 102 107 112 117 1223 8 13 18 23 28 33 38 43 48 53 58 63 68 73 78 83 88 93 98 103 108 113 118 1234 9 14 19 24 29 34 39 44 49 54 59 64 69 74 79 84 89 94 99 104 109 114 1195 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 85 90 95 100 105 110 115 1202 cols ¼123 © .. .. with 2-blank inter-column gap.1 8 15 22 29 36 43 50 57 64 71 78 85 92 99 106 113 1202 9 16 23 30 37 44 51 58 65 72 79 86 93 100 107 114 1213 10 17 24 31 38 45 52 59 66 73 80 87 94 101 108 115 1224 11 18 25 32 39 46 53 60 67 74 81 88 95 102 109 116 1235 12 19 26 33 40 47 54 61 68 75 82 89 96 103 110 1176 13 20 27 34 41 48 55 62 69 76 83 90 97 104 111 1187 14 21 28 35 42 49 56 63 70 77 84 91 98 105 112 1192 50 cols ¼123 © .. .. restricted to 50 columns.1 12 23 34 45 56 67 78 89 100 111 1222 13 24 35 46 57 68 79 90 101 112 1233 14 25 36 47 58 69 80 91 102 1134 15 26 37 48 59 70 81 92 103 1145 16 27 38 49 60 71 82 93 104 1156 17 28 39 50 61 72 83 94 105 1167 18 29 40 51 62 73 84 95 106 1178 19 30 41 52 63 74 85 96 107 1189 20 31 42 53 64 75 86 97 108 11910 21 32 43 54 65 76 87 98 109 12011 22 33 44 55 66 77 88 99 110 12130


cols Œnl 3 4 © multi-column display of character matrix._fk cmpx each insnode mns polar search unifyacc cols easter int morse popnode segs unsadic colsum efract invr mp3 pow select untilalext compidn else iotag mscan pred sieve unwrapalrem cond enlist isdfn mtrim putfile span upalrems cx enss just nats queens splay utf8alval cxdraw esh justify nc quzzle squad utf8getalvals cxsh exit kball ncpath range squeeze utf8putambiv dab factorial kcell nicediv rank ss vofand date factors key nlines rational ssmat vonapportion days fibonacci ksphere nspack rats ssword vtolary deb file kt of ratsum stamps vtrimascan dec filefind k6174 or ravt stdists vwiseascana det find lcase osc redblack stpath wcostassign dfnscode fix le pack refmatch stpaths whileattrib dfnsnotes fk lex pack4 refmt subs wmstavl dfspan fk_ life packB refpath subvec wordsbaby dft fnarray limit packD refs sudoku wpathbags dice fndiff list packH refws test wrapbase64 din fnrefs lof packN remlink tfmt wrapnotebf disp fnrepl logic packQ remnode ticks wsdiffbig display foldl loop packR rep time wsmergebirthday displayr for ltov packS ripple timestamp wspanbox displays from ltrav packT rmcm tnest wsreqbsearch dist gauss_jordan mac packU roman to xhtmlbt dlb gcd match packX root tokens xpowercache dmb getfile mayan packZ roots trace xrefscal do hex maze parse rows traj xtabscase dots hexdump mdf path rr trav xtimescf draw hexf mean pco sam tree xwscfract dscan htx memo perv saw tview UndoRedochksum dtb index merge phinary sbst type Xcmat dxb inslink mmind pmat scc ucaseclass„{' '~þ¾,'.',•Œnc ¾}class¨ 'display' 'memo'display.3 memo.4© name classification.© fns.3 ops.4.31


cols class¨ ‡Œnl 3 4 © classified names._fk.4 cxdraw.3 factors.3 ksphere.3 packD.3 ripple.3 traj.4acc.4 cxsh.3 fibonacci.3 kt.3 packH.3 rmcm.3 tree.3adic.3 dab.3 file.4 lcase.3 packN.3 roman.4 tview.3alext.3 date.3 filefind.3 lex.4 packQ.3 root.3 type.3alrem.3 days.3 find.3 life.3 packR.3 roots.3 ucase.3alrems.3 dft.4 fix.3 limit.4 packS.3 rows.4 unify.3alval.3 deb.3 fk_.4 list.3 packT.3 sam.4 uns.3alvals.3 dec.3 fnarray.4 lof.4 packU.3 saw.4 until.4ambiv.3 defn.3 fndiff.3 logic.4 packX.3 sbst.4 unwrap.3and.4 det.3 fnrefs.3 ltov.3 packZ.3 search.3 up.3ary.3 dfnscode.3 fnrepl.3 ltrav.4 path.3 select.3 utf8.3ascan.4 dfnsnotes.3 foldl.4 mac.3 pco.3 sieve.3 utf8get.3ascana.4 dfspan.3 for.4 mayan.3 perv.4 span.3 utf8put.3assign.3 dice.3 from.3 maze.3 phinary.3 splay.4 vof.4attrib.3 disp.3 gauss_jordan.3 mdf.4 pmat.3 squad.4 von.3avl.4 display.3 gcd.3 mean.3 polar.3 squeeze.3 vtol.3baby.3 displayr.3 getfile.3 memo.4 popnode.3 ss.3 vtrim.3bf.3 displays.3 hex.3 merge.4 pow.4 ssmat.3 vwise.4big.4 dlb.3 hexdump.3 mmind.3 pred.4 ssword.3 wcost.3box.3 dmb.3 hexf.3 mns.3 putfile.3 stamps.3 while.4bsearch.4 do.4 htx.3 morse.3 queens.3 stdists.3 wmst.3bt.4 dots.3 index.3 mp3.3 quzzle.3 stpath.3 words.3cache.3 draw.3 inslink.3 mscan.3 range.3 stpaths.3 wpath.3cal.3 dscan.3 insnode.3 mtrim.3 rank.4 subs.3 wrap.3case.4 dtb.3 int.3 nats.4 rational.3 subvec.3 wrapnote.3cf.4 dxb.3 inverse.4 nc.3 rats.4 sudoku.3 wsdiff.3cfract.3 each.4 invr.4 ncpath.3 ratsum.4 test.3 wsmerge.3chksum.3 easter.3 invs.4 nicediv.3 redblack.4 tfmt.3 wspan.3class.3 efract.3 iotag.3 nlines.3 refmatch.3 ticks.4 wsreq.3cmat.3 else.4 isdfn.3 nspack.3 refmt.3 time.4 xhtml.3cmpx.3 enlist.3 just.3 of.4 refs.3 timestamp.3 xrefs.3cols.3 enss.3 justify.3 or.4 refws.3 tnest.3 xtabs.3colsum.3 esh.3 kball.3 osc.3 remlink.3 to.3 xws.3cond.4 exit.3 kcell.4 pack.3 remnode.3 tokens.3 UndoRedo.4cx.4 factorial.3 key.4 packB.3 rep.3 trace.41 1 0 disp ž{1 ¾ cols ¼10}¨0 to 20 © all possible wrappings of 1 .. 10.Ú…ÂÎÂÎÎÂÎÎÎÎÂÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ Û Û 1Û1 6Û1 5 9Û1 4 7 10Û1 3 5 7 9Û1 2 3 4 5 6 7 8 9 10ÛÛ Û Û 2Û2 7Û2 6 10Û2 5 8 Û2 4 6 8 10Û ÛÛ Û Û 3Û3 8Û3 7 Û3 6 9 Û Û ÛÛ Û Û 4Û4 9Û4 8 Û Û Û ÛÛ Û Û 5Û5 10Û Û Û Û ÛÛ Û Û 6Û Û Û Û Û ÛÛ Û Û 7Û Û Û Û Û ÛÛ Û Û 8Û Û Û Û Û ÛÛ Û Û 9Û Û Û Û Û ÛÛ ‡1‡10‡ ‡ ‡ ‡ ‡ ‡À´Á…ÁÎ…ÁÎÎÎ…ÁÎÎÎÎÎ…ÁÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…Ù1 12 cols 2/10*0 6 0 © tricky case.1 1000000 11 1000000 1See also: wrap.185 tree.13532


ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎdispcmat „ {opts} ##.disp array© Boxed sketch of nested array.opts „ {dec„1 {box„1 {cen„1 {sep„0}}}} © optional parameters.A compact alternative to the …display„ function for nested arrays. By default,the shape of the containing array is shown in its top-left corner and for eachsubarray, item type is shown lower-left and shape is shown lower-right.Although in general, all of the information provided by …display„ is present,the type (~) of a single digit number may be obscured by its shape (Î/…) decoration.The optional left argument of 1-4 boolean flags (default 1 1 1 0) controls:ÚÎÎÎÎÎÎÎ dec: type and shape decoration:· · decorated (otherwise, plain)Û ÚÎÎÎÎÎ box: box-drawing chars:· · · · · · smooth (otherwise, clunky)Û Û ÚÎÎÎ cen: items within boxes aligned: · centred (otherwise, top-left)Û Û Û ÚÎ sep: rank-2 planes separated:· · · separated (otherwise, merged)Û Û Û Û1 1 1 0 disp ..With decoration turned off (0 disp ..) the function can be used to format simpletables for display in the session; see example below.Examples:disp 2 2½'Tea'(2 1½4 2)'&'(2 40)Ú…ÎÎÂÎÎÎÎ̇TeaÛ 4 ÛÛ Û 2 ‡ÃÎÎ…Ï~ÎÎ…ÝÛ & Û2 40ÛÀÎÎÎÁ~ÎÎ…Ùdisplay 2 2½'Tea'(2 1½4 2)'&'(2 40)Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÎ̇ Ú…ÎÎÌ Ú…Ì ÛÛ ÛTeaÛ ‡4Û ÛÛ ÀÎÎÎÙ Û2Û ÛÛ À~Ù ÛÛ Ú…ÎÎÎÌ ÛÛ & Û2 40Û ÛÛ - À~ÎÎÎÙ ÛÀ¹ÎÎÎÎÎÎÎÎÎÎÎÎÎÙdisp arrayÚ…ÎÎÂÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎ̇3.1Û Vector Û Matrix ‡ Array ”Ã~ÎÎÏÎÎÎÎÎÎÎÎ…ÏÎÎÎÎÎÎÎÎ…ÏÎÎÎÎÎÎÎ…ÝÛÚÎÌÛÚ…ÎÎÂÎÎÎÌÛÚ…ÎÎÂÎÎÎÌÛÚ…ÎÎÎÎÎÌÛÛÛ0ÛÛÛQ 8ÛK 9ÛÛ²0 0Û0 0ÛÛ” # # ÛÛÛÀ´ÙÛÀ+Î…Á+Î…ÙÛÀ~Î…Á~Î…Ù²À#ÎÎÎÎ…Ù”ÀÎÎÎÁÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎ…Ù© [disp] form of nested array.© Compare with [display] form.© [disp] sketch of array.display array© Compare with full [display].Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ̇ Ú…ÎÎÎÎÎÌ Ú…ÎÎÎÎÎÌ ÚÚ…ÎÎÎÎÌ ÛÛ 3.1 ÛVectorÛ ‡MatrixÛ ‡‡ArrayÛ ÛÛ ÀÎÎÎÎÎÎÙ ÀÎÎÎÎÎÎÙ ÀÀÎÎÎÎÎÙ ÛÛ ÚÎÎÎÎÎÌ Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÌ Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÌ ÚÚ…ÎÎÎÎÎÎÎÎÎÌ ÛÛ Û Ú´Ì Û Û Ú…ÎÎÌ Ú…ÎÎÌ Û ² Ú…ÎÎÌ Ú…ÎÎÌ Û ‡‡ Ú…ÎÎÎÎÎÌ Û ÛÛ Û Û0Û Û Û ÛQ 8Û ÛK 9Û Û Û Û0 0Û Û0 0Û Û ÛÛ Û # # Û Û ÛÛ Û À~Ù Û Û À+ÎÎÙ À+ÎÎÙ Û Û À~ÎÎÙ À~ÎÎÙ Û ÛÛ À#ÎÎÎÎÎÙ Û ÛÛ À¹ÎÎÎÎÙ À¹ÎÎÎÎÎÎÎÎÎÎÎÎÙ À¹ÎÎÎÎÎÎÎÎÎÎÎÎÙ ÀÀ¹ÎÎÎÎÎÎÎÎÎÙ ÛÀ¹ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙ33


© Simple table in session:0 disp'%' 'Eye Poke' 'Kumquat'®†('Guys' 60 40)('Gals' 20 80)ÚÎÎÎÎÂÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÌÛ % ÛEye PokeÛKumquatÛÃÎÎÎÎÏÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÝÛGuysÛ 60 Û 40 ÛÃÎÎÎÎÏÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÝÛGalsÛ 20 Û 80 ÛÀÎÎÎÎÁÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÙ© The 4th left-argument parameter [sep], default 0, controls whether leading© sub-planes of higher-rank nested arrays are to be presented in separate boxes© or to be merged with a '”' decorator, which indicates the presence of leading© axes. Notice in the following example that, in common with simple (unboxed)© output, the size of the gap between subarrays increases with their rank.dec „ 1 1 1 0°disp © rely on '”' decorator.gap „ 1 1 1 1°disp © use inter-plane gaps.oid „ ¼2 2 2 2© rank-4 array.(dec oid)(gap oid) © comparison:Ú…ÎÎÎÎÎÎÂÎÎÎÎÎÎÎÌ Ú…ÎÎÎÎÎÎÂÎÎÎÎÎÎÎÌ”1 1 1 1Û1 1 1 2Û ‡1 1 1 1Û1 1 1 2ÛÃ~ÎÎÎÎÎ…Ï~ÎÎÎÎÎ…Ý Ã~ÎÎÎÎÎ…Ï~ÎÎÎÎÎ…ÝÛ1 1 2 1Û1 1 2 2Û Û1 1 2 1Û1 1 2 2ÛÃ~ÎÎÎÎÎ…Ï~ÎÎÎÎÎ…Ý À~ÎÎÎÎÎ…Á~ÎÎÎÎÎ…ÙÛ1 2 1 1Û1 2 1 2Û Ú…ÎÎÎÎÎÎÂÎÎÎÎÎÎÎÌÃ~ÎÎÎÎÎ…Ï~ÎÎÎÎÎ…Ý ‡1 2 1 1Û1 2 1 2ÛÛ1 2 2 1Û1 2 2 2Û Ã~ÎÎÎÎÎ…Ï~ÎÎÎÎÎ…ÝÃ~ÎÎÎÎÎ…Ï~ÎÎÎÎÎ…Ý Û1 2 2 1Û1 2 2 2ÛÛ2 1 1 1Û2 1 1 2Û À~ÎÎÎÎÎ…Á~ÎÎÎÎÎ…ÙÃ~ÎÎÎÎÎ…Ï~ÎÎÎÎÎ…ÝÛ2 1 2 1Û2 1 2 2Û Ú…ÎÎÎÎÎÎÂÎÎÎÎÎÎÎÌÃ~ÎÎÎÎÎ…Ï~ÎÎÎÎÎ…Ý ‡2 1 1 1Û2 1 1 2ÛÛ2 2 1 1Û2 2 1 2Û Ã~ÎÎÎÎÎ…Ï~ÎÎÎÎÎ…ÝÃ~ÎÎÎÎÎ…Ï~ÎÎÎÎÎ…Ý Û2 1 2 1Û2 1 2 2ÛÛ2 2 2 1Û2 2 2 2Û À~ÎÎÎÎÎ…Á~ÎÎÎÎÎ…ÙÀ~ÎÎÎÎÎ…Á~ÎÎÎÎÎ…Ù Ú…ÎÎÎÎÎÎÂÎÎÎÎÎÎÎ̇2 2 1 1Û2 2 1 2ÛÃ~ÎÎÎÎÎ…Ï~ÎÎÎÎÎ…ÝÛ2 2 2 1Û2 2 2 2ÛÀ~ÎÎÎÎÎ…Á~ÎÎÎÎÎ…Ù© The following example shows the effect of all permutations of left-argument© options:©© dec: type and shape decorations off/on,© box: smooth borders off/on,© cen: centre-alignment within box off/on.© sep: high rank subarray separation off/on.opts„ Œio¬¼2 2 2 2© all permutations of left-argument options.r c s„(1 9)(3 1)(1 1)½¨' ' © row, column and single matrices.34


0 1 0 1 disp {¾ disp 2 2 2½¾ c r s « '' « ''}¨ optsÚÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ.---------.. Û.---------.. ÛÛ|0 0 0 0 || Û|0 0 0 1 || ÛÛ| || Û| || ÛÛ| || Û| || ÛÛ|---------+| Û|---------+| ÛÛ|---------+| Û'---------'' ÛÛ| || Û.---------.. ÛÛ|---------+| Û||| ÛÛ| || Û|---------+| ÛÛ'---------'' Û||| ÛÛÛ'---------'' ÛÃÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÝÛ.---------.. Û.---------.. ÛÛ| || Û| || ÛÛ| 0 0 1 0 || Û| 0 0 1 1 || ÛÛ| || Û| || ÛÛ|---------+| Û|---------+| ÛÛ|---------+| Û'---------'' ÛÛ| || Û.---------.. ÛÛ|---------+| Û||| ÛÛ| || Û|---------+| ÛÛ'---------'' Û||| ÛÛÛ'---------'' ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÙÚÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛÚÎÎÎÎÎÎÎÎÎÂÌ ÛÚÎÎÎÎÎÎÎÎÎÂÌ ÛÛÛ0 1 0 0 ÛÛ ÛÛ0 1 0 1 ÛÛ ÛÛÛ ÛÛ ÛÛ ÛÛ ÛÛÛ ÛÛ ÛÛ ÛÛ ÛÛÃÎÎÎÎÎÎÎÎÎÏÝ ÛÃÎÎÎÎÎÎÎÎÎÏÝ ÛÛÃÎÎÎÎÎÎÎÎÎÏÝ ÛÀÎÎÎÎÎÎÎÎÎÁÙ ÛÛÛÛÛ ÛÚÎÎÎÎÎÎÎÎÎÂÌ ÛÛÃÎÎÎÎÎÎÎÎÎÏÝ ÛÛÛÛ ÛÛÛÛÛ ÛÃÎÎÎÎÎÎÎÎÎÏÝ ÛÛÀÎÎÎÎÎÎÎÎÎÁÙ ÛÛÛÛ ÛÛÛÀÎÎÎÎÎÎÎÎÎÁÙ ÛÃÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÝÛÚÎÎÎÎÎÎÎÎÎÂÌ ÛÚÎÎÎÎÎÎÎÎÎÂÌ ÛÛÛ ÛÛ ÛÛ ÛÛ ÛÛÛ 0 1 1 0 ÛÛ ÛÛ 0 1 1 1 ÛÛ ÛÛÛ ÛÛ ÛÛ ÛÛ ÛÛÃÎÎÎÎÎÎÎÎÎÏÝ ÛÃÎÎÎÎÎÎÎÎÎÏÝ ÛÛÃÎÎÎÎÎÎÎÎÎÏÝ ÛÀÎÎÎÎÎÎÎÎÎÁÙ ÛÛÛÛÛ ÛÚÎÎÎÎÎÎÎÎÎÂÌ ÛÛÃÎÎÎÎÎÎÎÎÎÏÝ ÛÛÛÛ ÛÛÛÛÛ ÛÃÎÎÎÎÎÎÎÎÎÏÝ ÛÛÀÎÎÎÎÎÎÎÎÎÁÙ ÛÛÛÛ ÛÛÛÀÎÎÎÎÎÎÎÎÎÁÙ ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÙ35


ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ.…--------.-.Û.…--------.-.ÛÛ”1 0 0 0 | |Û‡1 0 0 1 | |ÛÛ| | |Û| | |ÛÛ| | ‡Û| | ‡ÛÛ|~-------…+´|Û|~-------…+´|ÛÛ| ² ²Û| ² ²ÛÛ|--------…+´|Û'--------…'´'ÛÛ|0 | |Û.…--------.-.ÛÛ|~-------´+´|Û‡0 | |ÛÛ|0 | |Û|~-------´+´|ÛÛ'~-------´'´'Û|0 | |ÛÛÛ'~-------´'´'ÛÃÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÝÛ.…--------.-.Û.…--------.-.ÛÛ” | |Û‡ | |ÛÛ| 1 0 1 0 | |Û| 1 0 1 1 | |ÛÛ| | ‡Û| | ‡ÛÛ|~-------…+´|Û|~-------…+´|ÛÛ| ² ²Û| ² ²ÛÛ|--------…+´|Û'--------…'´'ÛÛ| 0 | |Û.…--------.-.ÛÛ|~-------´+´|Û‡ 0 | |ÛÛ| 0 | |Û|~-------´+´|ÛÛ'~-------´'´'Û| 0 | |ÛÛÛ'~-------´'´'ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÙÚÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛÚ…ÎÎÎÎÎÎÎÎÂÎÌÛÚ…ÎÎÎÎÎÎÎÎÂÎÌÛÛ”1 1 0 0 Û ÛÛ‡1 1 0 1 Û ÛÛÛÛ Û ÛÛÛ Û ÛÛÛÛ Û ‡ÛÛ Û ‡ÛÛÃ~ÎÎÎÎÎÎÎ…Ï´ÝÛÃ~ÎÎÎÎÎÎÎ…Ï´ÝÛÛÛ ² ²ÛÛ ² ²ÛÛÃÎÎÎÎÎÎÎÎ…Ï´ÝÛÀÎÎÎÎÎÎÎÎ…Á´ÙÛÛÛ0 Û ÛÛÚ…ÎÎÎÎÎÎÎÎÂÎÌÛÛÃ~ÎÎÎÎÎÎδϴÝÛ‡0 Û ÛÛÛÛ0 Û ÛÛÃ~ÎÎÎÎÎÎδϴÝÛÛÀ~ÎÎÎÎÎÎδÁ´ÙÛÛ0 Û ÛÛÛÛÀ~ÎÎÎÎÎÎδÁ´ÙÛÃÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÝÛÚ…ÎÎÎÎÎÎÎÎÂÎÌÛÚ…ÎÎÎÎÎÎÎÎÂÎÌÛÛ” Û ÛÛ‡ Û ÛÛÛÛ 1 1 1 0 Û ÛÛÛ 1 1 1 1 Û ÛÛÛÛ Û ‡ÛÛ Û ‡ÛÛÃ~ÎÎÎÎÎÎÎ…Ï´ÝÛÃ~ÎÎÎÎÎÎÎ…Ï´ÝÛÛÛ ² ²ÛÛ ² ²ÛÛÃÎÎÎÎÎÎÎÎ…Ï´ÝÛÀÎÎÎÎÎÎÎÎ…Á´ÙÛÛÛ 0 Û ÛÛÚ…ÎÎÎÎÎÎÎÎÂÎÌÛÛÃ~ÎÎÎÎÎÎδϴÝÛ‡ 0 Û ÛÛÛÛ 0 Û ÛÛÃ~ÎÎÎÎÎÎδϴÝÛÛÀ~ÎÎÎÎÎÎδÁ´ÙÛÛ 0 Û ÛÛÛÛÀ~ÎÎÎÎÎÎδÁ´ÙÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÙSee also: display.35 box.1436


ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎdisplaycmat „ {boxstyle„1} ##.display array © Boxed display of array.cmat „ {boxstyle„1} ##.displays array © .. with axis lengths.cmat „ {boxstyle„1} ##.displayr array © .. .. and subarray depths.The argument array is displayed with boxes bordering each subarray. Charactersembedded in the borders indicate subarray shape and type.Shape: ‡ … Non-zero axis.² ´ Zero axis.Type:¹ Nested array.~ Numeric.- Character.# Namespace reference.’ ŒOR object.+ Mixed type.Prototypical items of empty arrays (² ´) are exposed.With one exception, [display] perfectly distinguishes arrays. That is to say,distinct arrays have distinct display forms. The exception, signalled by a '+'character in its left lower border, is a depth-1 (sub) array containing bothcharacters and numbers. For example: display 88,'99'.The optional left argument (default 1) selects the character set for the boxesthat enclose subarrays:ÚÎÎÎÌ1 selects "smooth" box-drawing characters: Û Û and.---. ÀÎÎÎÙ0 selects "clunky" characters: | | which are available in all fonts.'---'Variations----------Inspired by David Rabenhorst's 1988 paper, Dick Bowman supplies two furtherversions of the display functiondisplaysdisplayr© display with shape along top border.© display with shape along axis borders and with depth.Compare the output from Dick's <strong>functions</strong> with the original:display 1 'a' 'abc' (2 3½¼6)Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ Ú…ÎÎÌ Ú…ÎÎÎÎÌ ÛÛ 1 a ÛabcÛ ‡1 2 3Û ÛÛ - ÀÎÎÎÙ Û4 5 6Û ÛÛÀ~ÎÎÎÎÙ ÛÀ¹ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙdisplays 1 'a' 'abc' (2 3½¼6)Ú…Î4ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ Ú…Î3Ì Ú…Î2 3Ì ÛÛ 1 a ÛabcÛ ‡1 2 3Û ÛÛ - ÀÎÎÎÙ Û4 5 6Û ÛÛÀ~ÎÎÎÎÙ ÛÀ¹ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙdisplayr 1 'a' 'abc' (2 3½¼6)Ú4ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ Ú3ÎÎÎÌ Ú3ÎÎÎÎÎÌ ÛÛ 1 a Û abcÛ 2 1 2 3Û ÛÛ - ÀÎÎÎÎÙ Û 4 5 6Û ÛÛÀ~ÎÎÎÎÎÙ ÛÀ¯2ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙ© "standard" display.© with shape along top border.© with shape per axis and depth.37


Ref: "The Compact Display of Arbitrary Nested Arrays" D. A. Rabenhorst (IBM),<strong>APL</strong>88 Conference Proceedings, pp 272-277, ACM - 0-89791-253-5/88/0002/0272Examples:display 'ABC'(1 4½1 2 3 4)(0 1 0½0)(ŒSE #)('88',99)Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ Ú…ÎÎÌ Ú…ÎÎÎÎÎÎÌ ÚÚ´Ì Ú…ÎÎÎÎÎÎÎÌ Ú…ÎÎÎÎÌ ÛÛ ÛABCÛ ‡1 2 3 4Û ²‡0Û Û ŒSE # Û Û88 99Û ÛÛ ÀÎÎÎÙ À~ÎÎÎÎÎÎÙ ÀÀ~Ù À#ÎÎÎÎÎÎÎÙ À+ÎÎÎÎÙ ÛÀ¹ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙ0 1 display¨'clunky' 'smooth'.…-----. Ú…ÎÎÎÎÎÌ|clunky| ÛsmoothÛ'------' ÀÎÎÎÎÎÎÙSee also: disp.31 box.14ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎdistd „ L ##.dist R© Levenshtein distance.From Jay Foad, [dist] returns the "distance" between simple vectors L and R.The O(m×n) algorithm compares sequences, calculating the minimum number of editsrequired to transform one into the other. The notional costs of the edit operationsare:Insert item: 1Delete item: 1Replace item: 1Copy item: 0For example, comparing vectors 'Sunday' and 'Saturday' implies the followingtable, where each item is:0 + its NW neighbour, if the corresponding items match.1 + the minimum of its N, W and NW neighbours, otherwise.S a t u r d a yS 0 1 2 3 4 5 6 7u 1 1 2 2 3 4 5 6n 2 2 2 3 3 4 5 6d 3 3 3 3 4 3 4 5a 4 3 4 4 4 4 3 4y 5 4 4 5 5 5 4 3Each number in the table is the edit distance between the sub-strings above andto its left. For example, the 2 in the second row, fourth column, is the distancefrom 'Su' to 'Satu': two copies and two insertions.Note that, as the cost of insertion and deletion is the same, the function iscommutative. 'Satu' … 'Su' : two copies and two deletions.The Levenshtein distance between the two sequences is thus the lower-right tableitem (3 in the above example).See: http://en.wikipedia.org/wiki/Levenshtein_distance38


Technical note:dist„{ŒML„0© Levenshtein distance.a„(n+1)½(½¸)+n„½¾© first row of matrixf„¾{˜\¾˜(œ¾),(¯1‡¾)-1+¸=¸¸} © iteration stepz„œf/(²¸),›a© last row of matrixœ²z}[dist] calculates a row of the matrix at a time. The / iterates over successivecharacters from ¸, generating a new matrix row each time. The ˜\ is key to calculatinga whole row quickly.Examples33'Sunday' dist 'Saturday''sitting' dist 'kitten'mons „ 'January' 'February' 'March'mons,„ 'April' 'May' 'June'mons,„ 'July' 'August' 'September'mons,„ 'October' 'November' 'December'© distance between strings.© examples from Wikipedia.mons °.dist mons0 4 6 7 5 5 4 6 9 7 8 84 0 7 7 6 7 6 7 8 7 8 76 7 0 4 3 5 5 6 9 7 8 87 7 4 0 5 5 5 5 8 7 8 85 6 3 5 0 4 3 6 9 7 8 85 7 5 5 4 0 2 5 8 6 7 74 6 5 5 3 2 0 5 9 7 8 86 7 6 5 6 5 5 0 9 7 8 89 8 9 8 9 8 9 9 0 5 4 37 7 7 7 7 6 7 7 5 0 5 48 8 8 8 8 7 8 8 4 5 0 38 7 8 8 8 7 8 8 3 4 3 0© distances between monthsfuzzy„{({¾¼˜/¾}(lcase ¸)°dist°lcase¨¾)œ¾}fuzzy°mons¨ 'dcmbr' 'marching' 'febury'December March February© fuzzy selection© fuzzy matchesSee also: lcase.176ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎenlistlist „ {leaves} ##.enlist array© List ¸-leaves of nested array.Suggested by Yves Bopp, this function generalises primitive enlist (¹¾), to returna list of the (at most) depth-¸ leaves of its array argument.Technical note:The function uses †,/ to concatenate array items. If the array were empty, thiswould cause an error as the primitive catenate function has no associated identityitem. This situation is avoided by prefixing an item before the reductionand removing it afterwards. In this null case, the correct prototypical item ismaintained by using the first item of the array itself as the dummy item.39


Examples:disp vecs© uniform depth 4 array.Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛÚ…ÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛÚ…ÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÌÛÛÛÚ…ÎÎÎÎÂÎÎÎÎÎÌÛÚ…ÎÎÎÎÎÎÂÎÎÎÎÎÌÛÛÛÚ…ÎÎÎÂÎÎÎÎÎÌÛÚ…ÎÎÂÎÎÎÎÌÛÛÛÛÛhelloÛworldÛÛÛbonjourÛmondeÛÛÛÛÛgoodÛnightÛÛÛbonÛsoirÛÛÛÛÛÀÎÎÎÎ…ÁÎÎÎÎ…ÙÛÀÎÎÎÎÎÎ…ÁÎÎÎÎ…ÙÛÛÛÀÎÎÎ…ÁÎÎÎÎ…ÙÛÀÎÎ…ÁÎÎÎ…ÙÛÛÛÀÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÙÛÀÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎ…ÙÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…Ùdisp 0 enlist vecs © list (vector) of depth-0 leaves.helloworldbonjourmondegoodnightbonsoirdisp 1 enlist vecs © list of depth-1 leaves.Ú…ÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÂÎÎÎÎÎÂÎÎÎÂÎÎÎÎÌÛhelloÛworldÛbonjourÛmondeÛgoodÛnightÛbonÛsoirÛÀÎÎÎÎ…ÁÎÎÎÎ…ÁÎÎÎÎÎÎ…ÁÎÎÎÎ…ÁÎÎÎ…ÁÎÎÎÎ…ÁÎÎ…ÁÎÎÎ…Ùdisp 2 enlist vecs © list of depth-2 leaves.Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÌÛÚ…ÎÎÎÎÂÎÎÎÎÎÌÛÚ…ÎÎÎÎÎÎÂÎÎÎÎÎÌÛÚ…ÎÎÎÂÎÎÎÎÎÌÛÚ…ÎÎÂÎÎÎÎÌÛÛÛhelloÛworldÛÛÛbonjourÛmondeÛÛÛgoodÛnightÛÛÛbonÛsoirÛÛÛÀÎÎÎÎ…ÁÎÎÎÎ…ÙÛÀÎÎÎÎÎÎ…ÁÎÎÎÎ…ÙÛÀÎÎÎ…ÁÎÎÎÎ…ÙÛÀÎÎ…ÁÎÎÎ…ÙÛÀÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎ…Ùdisp 3 enlist vecs © list of depth-3 leaves.Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛÚ…ÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛÚ…ÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÌÛÛÛÚ…ÎÎÎÎÂÎÎÎÎÎÌÛÚ…ÎÎÎÎÎÎÂÎÎÎÎÎÌÛÛÛÚ…ÎÎÎÂÎÎÎÎÎÌÛÚ…ÎÎÂÎÎÎÎÌÛÛÛÛÛhelloÛworldÛÛÛbonjourÛmondeÛÛÛÛÛgoodÛnightÛÛÛbonÛsoirÛÛÛÛÛÀÎÎÎÎ…ÁÎÎÎÎ…ÙÛÀÎÎÎÎÎÎ…ÁÎÎÎÎ…ÙÛÛÛÀÎÎÎ…ÁÎÎÎÎ…ÙÛÀÎÎ…ÁÎÎÎ…ÙÛÛÛÀÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÙÛÀÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎ…ÙÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…Ùdisp teaÚ…ÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎ̇څÎÎÂÎÂÎÎÎÌÛÚ…ÂÎÎÎÂÎÌ ÛÛÛteaÛ4ÛtwoÛÛÛ2ÛforÛTÛ ÛÛÀÎÎ…ÁÎÁÎÎ…ÙÛÀÎÁÎÎ…ÁÎÙ ÛÃÎÎÎÎÎÎÎÎÎÎ…ÏÎÎÎÎÎÎÎÎÎ…ÝÛÚ…ÎÂÎÂÎÎÎÌ ÛÚ…ÂÎÎÎÂÎÎÌÛÛÛmeÛ&ÛyouÛ ÛÛuÛandÛmeÛÛÛÀÎ…ÁÎÁÎÎ…Ù ÛÀÎÁÎÎ…ÁÎ…ÙÛÀÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎ…Ùdisp 0 enlist teatea 4 two 2 forTme&youuandme© non-uniform depth-3 array.© list of depth-0 leaves.disp 1 enlist tea© list of (at most) depth-1 leaves.Ú…ÎÎÂÎÂÎÎÎÂÎÂÎÎÎÂÎÂÎÎÂÎÂÎÎÎÂÎÂÎÎÎÂÎÎÌÛteaÛ4ÛtwoÛ2ÛforÛTÛmeÛ&ÛyouÛuÛandÛmeÛÀÎÎ…ÁÎÁÎÎ…ÁÎÁÎÎ…ÁÎÁÎ…ÁÎÁÎÎ…ÁÎÁÎÎ…ÁÎ…Ùdisp 2 enlist tea© list of depth-2 leaves.Ú…ÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÌÛÚ…ÎÎÂÎÂÎÎÎÌÛÚ…ÂÎÎÎÂÎÌÛÚ…ÎÂÎÂÎÎÎÌÛÚ…ÂÎÎÎÂÎÎÌÛÛÛteaÛ4ÛtwoÛÛÛ2ÛforÛTÛÛÛmeÛ&ÛyouÛÛÛuÛandÛmeÛÛÛÀÎÎ…ÁÎÁÎÎ…ÙÛÀÎÁÎÎ…ÁÎÙÛÀÎ…ÁÎÁÎÎ…ÙÛÀÎÁÎÎ…ÁÎ…ÙÛÀÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎ…Ù1 1{Œml„1 ª (enlist ¾)­¹¾}¨vecs tea© 0°enlist agrees with primitive fn.See also: saw.78 perv.70 enss.3940


ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎenssnew „ old ##.enss reps© Emulate (¹¸)„¾.NB: From <strong>Dyalog</strong> V13.1, primitive enlist can be part of a selective assignmentexpression, so this emulation is superseded.Result [new] has the same nesting structure as left argument [old] but withitems replaced in enlist order from the (possibly reshaped) array [reps].[enss] emulates enlisted selected specification in that (var„var enss reps) isthe same as (¹var)„reps, where ¹ is enlist (Œml>0).This function was supplied by Veli-Matti Jantunen.[enss] is permissive about the shape of its right argment. A stricter versionmight be:enss„{© Emulate (¹¸)„¾.ŒML„2© (¹ is enlist).«­½¾:¸ ’(½¹¸)½¾© extend scalar.(½¹¸)»½¾:ŒSIGNAL 5© conformability check.¸{ © inner dfn for speed.2>­¸:(½¸)½¾© simple: shaped values.q„¹{(½¹¾)†1}¨¸© nested: partition vector.¸ ’¨(½¸)½(~¹0¹¨½¨¸)\q›¾ © substitute partitioned values.}¾}Examples:var„1 2,2+›2 3½(¼2),(›2+2 3½¼6),9 10,10+,°›/¼5disp varÚ…ÂÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ Û ÛÚ…ÎÂÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛÛ Û Û‡3 Û4 Û 5 6 7 ÛÛÛ Û ÛÛ Û Û 8 9 10 ‡ÛÛ Û ÛÃ~ÎÏ~ÎÏ~ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÝÛÛ Û ÛÛ Û ÛÚ…ÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛÛÛ1Û2ÛÛ Û ÛÛ ÛÚ…ÎÂÎÎÎÎÎÎÎÎÎÎÌÛÛÛÛ Û ÛÛ Û ÛÛ ÛÛ ÛÚ…ÎÂÎÎÎÎÎÌÛÛÛÛÛ Û ÛÛ11Û12ÛÛ13ÛÛ14ÛÛ15Û16 17ÛÛÛÛÛÛ Û ÛÛ Û ÛÛ ÛÛ ÛÀ~ÎÁ~ÎÎÎ…ÙÛÛÛÛÛ Û ÛÛ Û ÛÛ ÛÀ~ÎÁÎÎÎÎÎÎÎÎÎ…ÙÛÛÛÛ Û ÛÛ Û ÛÀ~ÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÙÛÛÛ Û ÛÀ~ÎÁ~ÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…Ù‡ÀÎÁÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…Ùdisp var enss 17†ŒaÚ…ÂÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ Û ÛÚ…ÂÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛÛ Û Û‡CÛDÛ EFG ÛÛÛ Û ÛÛ Û Û HIJ ‡ÛÛ Û ÛÃÎÏÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÝÛÛ Û ÛÛ Û ÛÚ…ÂÎÎÎÎÎÎÎÎÎÎÌÛÛÛAÛBÛÛ Û ÛÛ ÛÚ…ÂÎÎÎÎÎÎÌÛÛÛÛ Û ÛÛ Û ÛÛ ÛÛ ÛÚ…ÂÎÎÌÛÛÛÛÛ Û ÛÛKÛLÛÛMÛÛNÛÛOÛPQÛÛÛÛÛÛ Û ÛÛ Û ÛÛ ÛÛ ÛÀÎÁÎ…ÙÛÛÛÛÛ Û ÛÛ Û ÛÛ ÛÀÎÁÎÎÎÎÎ…ÙÛÛÛÛ Û ÛÛ Û ÛÀÎÁÎÎÎÎÎÎÎÎÎ…ÙÛÛÛ Û ÛÀÎÁÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎ…Ù‡ÀÎÁÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…Ù© nastily nested variable.© emulate: (¹var)„17†Œa41


disp var enss 0 © scalar 0 extends.Ú…ÂÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ Û ÛÚ…ÂÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛÛ Û Û‡0Û0Û 0 0 0 ÛÛÛ Û ÛÛ Û Û 0 0 0 ‡ÛÛ Û ÛÃÎÏÎÏ~ÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÝÛÛ Û ÛÛ Û ÛÚ…ÂÎÎÎÎÎÎÎÎÎÎÎÌÛÛÛ0Û0ÛÛ Û ÛÛ ÛÚ…ÂÎÎÎÎÎÎÎÌÛÛÛÛ Û ÛÛ Û ÛÛ ÛÛ ÛÚ…ÂÎÎÎÌÛÛÛÛÛ Û ÛÛ0Û0ÛÛ0ÛÛ0ÛÛ0Û0 0ÛÛÛÛÛÛ Û ÛÛ Û ÛÛ ÛÛ ÛÀÎÁ~Î…ÙÛÛÛÛÛ Û ÛÛ Û ÛÛ ÛÀÎÁÎÎÎÎÎÎ…ÙÛÛÛÛ Û ÛÛ Û ÛÀÎÁÎÎÎÎÎÎÎÎÎÎ…ÙÛÛÛ Û ÛÀÎÁÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…Ù‡ÀÎÁÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…Ùdisp var enss 2/¨17†Œa© right arg nesting preserved.Ú…ÎÎÎÂÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ Û ÛÚ…ÎÎÎÂÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛÛ Û Û‡ Û Û Ú…ÎÂÎÎÂÎÎÌ ÛÛÛ Û ÛÛÚÎÎÌÛÚÎÎÌÛ ‡EEÛFFÛGGÛ ÛÛÛ Û ÛÛÛCCÛÛÛDDÛÛ ÃÎ…ÏÎ…ÏÎ…Ý ÛÛÛ Û ÛÛÀÎ…ÙÛÀÎ…ÙÛ ÛHHÛIIÛJJÛ ÛÛÛ Û ÛÛ Û Û ÀÎ…ÁÎ…ÁÎ…Ù ‡ÛÛ Û ÛÃÎÎÎÎÏÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÝÛÛÚÎÎÌÛÚÎÎÌÛÛ Û ÛÚ…ÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛÛÛÛAAÛÛÛBBÛÛÛ Û ÛÛ ÛÚ…ÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛÛÛÛÀÎ…ÙÛÀÎ…ÙÛÛ Û ÛÛ ÛÛ ÛÚ…ÎÎÎÂÎÎÎÎÎÎÎÌÛÛÛÛÛ Û ÛÛÚÎÎÌÛÚÎÎÌÛÛÚÎÎÌÛÛÚÎÎÌÛÛÚÎÎÌÛÚ…ÎÂÎÎÌÛÛÛÛÛÛ Û ÛÛÛKKÛÛÛLLÛÛÛÛMMÛÛÛÛNNÛÛÛÛOOÛÛÛPPÛQQÛÛÛÛÛÛÛ Û ÛÛÀÎ…ÙÛÀÎ…ÙÛÛÀÎ…ÙÛÛÀÎ…ÙÛÛÀÎ…ÙÛÀÎ…ÁÎ…ÙÛÛÛÛÛÛ Û ÛÛ Û ÛÛ ÛÛ ÛÀÎÎÎÎÁÎÎÎÎÎÎ…ÙÛÛÛÛÛ Û ÛÛ Û ÛÛ ÛÀÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÙÛÛÛÛ Û ÛÛ Û ÛÀÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÙÛÛÛ Û ÛÀÎÎÎÎÁÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…Ù‡ÀÎÎÎÎÁÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÙSee also: select.81 enlist.37 sam.75 each.543ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎfindcvex „ {space„Œthis} ##.find string © Lines containing string(s) ¾.Find returns a 2-column matrix of character vectors, one row for each occurrenceof [string] in each variable, function or operator in [space]. If the left argumentis omitted, the current space is assumed.If [string] is a nested vector, those lines containing each of the substrings inorder are reported. For example: (find '') would find lines containingsequences such as but not those containing >>that


Examples:find'½½'#.ambiv[8] 2>½½cr:shy„'' © derived or primitive: quit.#.disp[60] 0=opt×½½¾:hz © undecorated or scalar •¾: char,#.disp[68] 0=opt×½½¾:vt hz © scalar or no decoration.#.disp[71] rows„(¯1+3˜½½¾)œvt rsig'”' © high rank decorator overrides.#.display[17] axes„{(-2—½½¾)†1+×½¾}© Array axis types.#.subs[2] 0=½½¾:œ(¾­fm)²¾(›to) © special case scalar argt.#.subs[5] 1


See also: refs.380 saw.78 filefind.426 rows.74ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎfromrslt „ indx ##.from array © Select (1‡½¾)-cells from array ¾.Gianluigi Quario suggests [from], an alternative to "square-bracket" indexing:array[···;···;···].[indx] is a vector of simple indices, each item of which selects along an axisof [array]. In other words:(inx1 inx2 ···) from array ­­ array[inx1;inx2;···]The number of items in [indx] must equal the rank of [array]:(½indx) ­ ½½arrayThe shape of [rslt] is the concatenation of the shapes of the items of [indx]:(½rslt) ­ †,/½¨indxA special short-hand "null": (,›«) may be used for any item of the index vectorto mean "all items along this axis". It is equivalent to an elided subscript ;;in conventional square-bracket indexing.Technical notes:Apart from the expansion of null indices, this function could be coded succinctlyby converting to "choose" indexing, using an outer product reduction of theindex arrays:from„{¾[†°.,/¸]}As selecting from a scalar array requires a zero-length index, we must pad thereduction's argument with a dummy item to avoid a domain error:from„{¾[1‡¨†°.,/0,¸]} Û Û ÛÛÃÎÙ ÃÙÛ ÀÎÎÎÎ prefix dummy item.ÀÎÎÎÎÎÎÎÎÎÎÎÎ remove dummy items.42« from 42 © null select from scalar.Purists who find square bracket indexing offensive (gnomoparenthiphobes? tetraclaustrophobes?),might prefer to use the "pick each enclose" (chipmunk) idiom:from„{(›¨1‡¨†°.,/0,¸)œ¨›¾}We could extend our function to accommodate null indices by borrowing from the…select„ function, although this would complicate and slow down the coding, considerably.44


from„{(›¨1‡¨†°.,/0,(ŒIO+¸¹›,›«)œ¨†,¨/›¨¨¸(¼¨½¾))œ¨›¾} ÃÎÎÎÎÎÎÎÎÙ ÃÎÎÎÎÎÎÎÙÛ ÃÎÎÙÛ Û Û ÀÎÎÎÎ full index vector per axis.Û Û ÀÎÎÎÎÎÎ supplied index vector.ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ select expanded nulls.ÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ nulls in index vector.Examples:_„,›«Œ„a3„³10ƒ³†¼3 4 5111 112 113 114 115121 122 123 124 125131 132 133 134 135141 142 143 144 145© special value: select all items along axis.© a3 is a rank-3 array.211 212 213 214 215221 222 223 224 225231 232 233 234 235241 242 243 244 245311 312 313 314 315321 322 323 324 325331 332 333 334 335341 342 343 344 3451231 2 3 from a3 © a3[1;2;3]1 2 _ from a3 © a3[1;2;]121 122 123 124 1251 _ _ from a3 © a3[1;;]111 112 113 114 115121 122 123 124 125131 132 133 134 135141 142 143 144 145_ 2 _ from a3121 122 123 124 125221 222 223 224 225321 322 323 324 325© a3[;2;](2 1)_ _ from a3 © a3[2 1;;]211 212 213 214 215221 222 223 224 225231 232 233 234 235241 242 243 244 245111 112 113 114 115121 122 123 124 125131 132 133 134 135141 142 143 144 145(2 2½2 1)_ _from a3 © a3[2 2½2 1;;]211 212 213 214 215221 222 223 224 225231 232 233 234 235241 242 243 244 24545


111 112 113 114 115121 122 123 124 125131 132 133 134 135141 142 143 144 145211 212 213 214 215221 222 223 224 225231 232 233 234 235241 242 243 244 245111 112 113 114 115121 122 123 124 125131 132 133 134 135141 142 143 144 145_ 2 _ from a3121 122 123 124 125221 222 223 224 225321 322 323 324 325_ _ 2 from a3112 122 132 142212 222 232 242312 322 332 342© a3[;2;]© a3[;;2]_ _ (2 2½2 1)from a3 © a3[;;2 2½2 1]112 111112 111122 121122 121132 131132 131142 141142 141212 211212 211222 221222 221232 231232 231242 241242 241312 311312 311322 321322 321332 331332 331342 341342 34146


½(,1)(,2)(,3) from a3 © rank-3 result.1 1 1½(,1)( 2)(,3) from a3 © rank-2 result.1 11½( 1)( 2)(,3) from a3 © rank-1 result.½( 1)( 2)( 3) from a3 © rank-0 result.(›2 2½2 1 1)from'hello' 'world' © works for nested arg.world hellohello worldSee also: select.81 squad.84ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎfoldlrslt „ ival (func ##.foldl) vals© Fold (reduce) from the left.Phil Last's operator uses dyadic operand function [func] to accumulate itemsfrom vector right argument [vals] starting with initial value [ival]. In effect:a f foldl i j k ··· … (((a f i)f j)f k) ···[foldl] is equivalent to, but faster than, the traditional operator:’ rslt„ival(func foldl)vals;val[1] rslt„ival[2] :For val :In vals[3] rslt„rslt func val © accumulate result.[4] :End’A related cumulative left-to-right scan operator might look like this:scanl„{ŒML„02>œ²½¾:¾© Scan from the left.© few items: done.}²†¸¸{(›(œ¾)¸¸ ¸),¾}/(²¾),››¸disp 'hello' ²þ scanl 1 1 0 ¯1 ¯1Ú…ÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÌÛhelloÛellohÛlloheÛlloheÛellohÛhelloÛÀÎÎÎÎ…ÁÎÎÎÎ…ÁÎÎÎÎ…ÁÎÎÎÎ…ÁÎÎÎÎ…ÁÎÎÎÎ…Ù© cf ascan in …scan„Technical note:The domain or "type" of left argument [ival] is in general distinct from that ofthe items of right argument vector [vals]. In the text replacement examplebelow, the left argument is a character vector (text string) and the right, avector of from/to pairs.To show what's going on, we could invent a type notation:Then::: "is of type",¸, ¾, ¹, ¼, ½, ··· arbitrary types ("type variables"),’, ’’ place marker for function, operator,… ··· "to a ···" result type ···[¸]vector of ¸s[¸;]matrix of ¸s.foldl :: ¸ (¸ ’ ¾ … ¸) ’’ [¾] … ¸47


From this we can see that:- the type of the result of the derived function is the same as the type of itsleft argument, which is also ¯¯¯¯¯¯¯- the type of the result of the operand function and the type of its left argument;¯¯¯¯¯¯¯- the type of the right argument of the operand function is the same as the typeof each item of the derived function's right argument array.This topic is explored in a little more depth in supplied workspace Max; searchfor "type of" and "foldl" in max.dws/Introduction.Similarly, the type of scanl, above, is:scanl :: ¸ (¸ ’ ¾ … ¸) ’’ [¾] … [¸]Comparison with primitive (vector) reduction:If the right argument of a primitive reduction is "homogeneous", in that all ofits items are of the same type, the type of a vector reduction is:/ :: (¸ ’ ¸ … ¸) ’’ [¸] … ¸ © homogeneous vector reduction¯¯¯¯However, <strong>APL</strong> allows vectors to be "heterogeneous". In particular, if the rightmostitem is of a distinct type, we could say the argument is of type [¸],›¾ andthe type of primitive reduction is:/ :: (¸ ’ ¾ … ¾) ’’ [¸],›¾ … ›¾ © heterogeneous vector reduction¯¯¯¯¯¯Composition of types:f :: {x} ’ ¾ … ¹g :: ’ ¸ … ¾=> f°g :: {x} ’ ¸ … ¹© optional left argument {x}Variations¯¯¯¯¯¯¯¯¯¯A monadic version of foldl might take the prototypical item of its argumentarray as an initial value:foldl„{ŒML„1© Fold (reduce) from the left.†¸¸þ/(²¾),›œ0½¾ © ival is prototypical item.} ¯¯¯¯ © :: (¸ ’ ¸ … ¸) ’’ [¸] … ¸Alternatively, we could _default_ the initial value to the prototypical item ofthe right argument by inserting an ¸„··· line like this:foldl„{ŒML„1¸„œ0½¾†¸¸þ/(²¾),›¸}© Fold (reduce) from the left.© default initial value.© :: {¸} (¸ ’ ¾ … ¸) ’’ [¾] … ¸Examples:repl„subsþ'I dare not' repl 'dare' 'would'I would not© ¸ with ¾ replacement.© single word replacement.'many a mickle'repl foldl 'nk'('y' 'es')'iu' © multiple letter replacement.makes a muckle48


0 ,foldl 2 3½¼6 © higher rank arrays.0 1 2 30 4 5 6© For more examples, see …remnode„ and …Graphs„See also: acc.10 trav.130 pred.72 scan.79 remnode.150 Graphs.137ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎiotagrslt „ {array} ##.iotag array© Generalized iota.Supplied by Steve Mansour:Monadic form produces generalized Index Generator function.Dyadic form with simple scalar left argument produces interval function.Dyadic form with rank 1 or higher left argument produces generalized Index Offunction.The following table describes the function in detail:ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ Left Argument Û Right Argument Û Function/Result ÛÃÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÝÛ Û Scalar integer Û Index Generator: iotag ¾ „… (×¾)×¼|¾ÛÛ Û ŒIO„0, ¾‰0 Û 0 1 2 ... ¾-1 ÛÛ Û ŒIO„0, ¾z Û ¸ (¸-s) (¸-s×2) ... (z—¸-s×n) ÛÃÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÝÛ Character scalar Û Character scalar Û Character Interval (ŒIO independent) ÛÛ (0=½½¸) Û Û ¸ iotag ¾ „… ŒAV[†iotag/ŒAV¼¸ ¾] ÛÛ Û Û 'B' iotag 'F' „… 'BCDEF' ÛÛ Û Û 'z' iotag 'w' „… 'zyxw' ÛÃÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÝÛ Vector (1=½½¸) Û Any array Û Index of (traditional dyadic ¼) ÛÃÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÝÛ Matrix (2=½½¸) Û Vector Û Generalized Index of ÛÛ Û (1=½½¾) Û Index of row (ignore trailing blanks) ÛÛÃÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÝÛ Û Matrix (2=½½¾) Û Index of each row ÛÛÃÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÝÛ Û Array (3ˆ½½¾) Û Index of each row ÛÃÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÝÛ Array (3ˆ½½¸) Û Matrix (2=½½¾) Û Index of (hyper)plane ÛÛÃÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÝÛ Û Array (3ˆ½½¾) Û Index of each (hyper)plane ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙNote that inner function "ischar" accepts Unicode characters from <strong>Dyalog</strong> 11.1.49


Examples:disp Beatles <strong>APL</strong>ers NamesÚ…ÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÎÌÛJOHN ÛSTEVEÛPAUL ÛÛPAUL ÛPAUL ÛSTEVE ÛÛGEORGEÛJOHN ÛBILL ÛÛRINGO ‡PETE ‡GEORGE‡ÀÎÎÎÎÎ…ÁÎÎÎÎ…ÁÎÎÎÎÎ…Ù<strong>APL</strong>ers iotag 'STEVE' © Find row of matrix0½<strong>APL</strong>ers iotag 1 5½'STEVE' © One-row matrix results in 1-item vector result1Beatles iotag 'GEORGE ' © Ignores trailing blanks (and trailing 0's)2<strong>APL</strong>ers iotag Beatles © Find multiple rows of matrix2 1 4 4½Rank3„œ<strong>APL</strong>ers Beatles © Rank 3 array2 4 6Rank3 iotag Beatles © Find matrix in Rank-3 array1Beatles iotag Rank34 1 0 40 1 2 3© Find Vectors in matrix3 iotag 5 .5 © Step of 0.53 3.5 4 4.5 512 iotag 3 3 © Step of 312 9 6 3ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎkeyres „ keys (fn ##.key) vals© key operatorres „ (fn ##.key) keysFrom Roger Hui, this operator was inspired by the "key" adverb of J (u/.).NB: From <strong>Dyalog</strong> V14, key is primitive operator Œ=.[fn] is any result-returning dyadic function.Dyadic case:[keys] is an array whose major cells specify keys for corresponding major cellsof [vals]. [key] applies operand function [fn] between each unique key in [keys]and the major cells of [vals] having that key.Monadic case:In this case, [key] applies the function [fn] between each unique key in [keys]and the items of ¼œ½[keys] having that key (fn key keys „… keys fn key•¼œ½keys).Key is similar to the GROUP BY clause in SQL.Examples:abc „ 'abracadabra'{œ½¾}key'abracadabra'5 2 2 1 150


€key abc © indices of each key1 4 6 8 112 9 0 0 03 10 0 0 05 0 0 0 07 0 0 0 0display {›¾}key abc© ditto, nestedÚ…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ Ú…ÎÎÎÎÎÎÎÎÎÌ Ú…ÎÎÌ Ú…ÎÎÎÌ Ú…Ì Ú…Ì ÛÛ Û1 4 6 8 11Û Û2 9Û Û3 10Û Û5Û Û7Û ÛÛ À~ÎÎÎÎÎÎÎÎÎÙ À~ÎÎÙ À~ÎÎÎÙ À~Ù À~Ù ÛÀ¹ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙdisplay {¸,½¾}key abcÚ…ÎÎ̇a 5ÛÛb 2ÛÛr 2ÛÛc 1ÛÛd 1ÛÀ+ÎÎÙ© key frequenciesdisplay €keyþ 5 4½'JohnMaryJohn'ÚÚ…ÎÎÎ̇‡JohnÛÛÛJohnÛÛÛJohnÛÛÛ ÛÛÛMaryÛÛÛMaryÛÛÛ ÛÀÀÎÎÎÎÙ© higher rank example (dyadic)See also: alists.8ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎleprecedes „ this ##.le that© Total array ordering (TAO) comparison.Inspired by Roger Hui, [le] "less than or equal" defines a Total Order on <strong>APL</strong>arrays. For any arrays A, B and C:(A le B) ^ (B le A) : A eq B © antisymmetry(A le B) ^ (B le C) : A le C © transitivity(A le B) Ÿ (B le A) © totality.See: http://en.wikipedia.org/wiki/Total_orderSee: http://www.jsoftware.com/jwiki/Essays/The_TAO_of_JGiven any two arrays, [le] tells us which "precedes or is equal to" the other.In particular it may be used to compare arrays of:- differing type: '6' le 6- differing rank: 3 le ,3- differing shape: 5 4 le 5 4 3- differing depth: (›¼2)le ››¼2- complex numbers: 7j8 le 8j7- namespace references: # le ŒSE- objects: le/{Œnew'Form'(›'Caption'¾)}¨'Hello' 'World'The comparison proceeds in the following order:- If the ranks differ, the lesser array is extended with leading 1-axes.If the resulting arrays match, the original ranks are used as a tie-breaker.51


- If the shapes differ, the arrays are extended to conform with fill items.If the resulting arrays match, the original shapes are used as a tie-breaker.- Non-atomic arrays are compared item-wise, pervasively, in ravel order.- Atomic items are compared by category: le le le .- Otherwise, if the categories match:Characters are compared using “,Numbers are compared on their real part, followed by their imaginary part,Namespaces are compared recursively in order of their:Type property,Symbol table (name class value) triples,Functions and operators are compared on their ŒNR values,ŒORs are compared using their fixed <strong>functions</strong> or namepaces.The values of namespace-scope system variables,Property names and values.Regarding the antisymmetry condition:(A le B) ^ (B le A) : A eq B © antisymmetryWhen comparing refs, "eq" is not the same as primitive function match (­): tworefs match _only_ if they reference the _same_ namespace, while [le] would judgethem equal if their contents and properties match:A B „ Œns¨ '' ''© two namespaces.10(A le B) ^ (B le A) © A eq BA ­ B© A » BRationale:The order that [le] imposes on arrays is to some extent arbitrary but is intendedto be intuitive. Here are the choices implicit in the coding:[1] Item value is more significant than shape. For example:'abc ' le 'xyz' © even though (½¸)>½¾'abc' le 'z'© even though (½½¸)>½½¾(1 3½'abc') le 'xyz' © .. .. ..[2] Characters sort beforenumbers, which sort beforerefs, which sort beforeŒORs.[3] When comparing complex numbers, real part is more significant than imaginarypart.[4] Within a namespace,user-specified names and values are more significant thansystem variable values, which are more significant thanproperty values.[5] Within a namespace, (name class value) triples are compared with each other,rather than having names, classes and values compared consecutively:x.a„8© x.a„8 ª y.a„3y.(a b)„3 4 © y.b„452


01x le y © because (a:8) >> (a:3)x.(Œnl 2) le y.(Œnl 2) © notwithstanding the order of namelists.[6] "Reference cycles" are broken by ignoring previously-visited references,which are deemed to compare less than any other value. For example:0x.(ref„Œns'')y.(ref„##.x)x le y© inward-pointing ref© outward-pointing ref© because x.ref >> y.refExamples:100111014 le 5 © simple scalar comparison: 4ˆ5.3 le ,2 © differing rank: compare items.(,3) le 3 © matching items: compare rank.'3' le 3© chars precede numbers.3j4 le 4j3© real-part trumps imaginary-part# le Œse © #.Type ˆ Œse.Type'xy'Œns¨›''© two namespaces.x.(a c)„1 3© with names a cy.(a b)„1 4© ... and a bx le y © (a c ...) supersedes (a b ...)x.b„2© new name b in xx le y © (a:1 b:2 ...) precedes (a:1 b:4 ...)qsort„{© quicksort.1‰½¾:¾© single item or null: done.head tail„(1†¾)(1‡¾)© first and remaining items.le gt„1 0=›tail ¸¸¨head© comparison with first item.(’ le/tail),head,’ gt/tail © sorted vector.}display le qsort 3(,3)'3'(,'3')Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÌÛ Ú…Ì Ú…Ì ÛÛ 3 Û3Û 3 Û3Û ÛÛ - ÀÎÙ À~Ù ÛÀ¹ÎÎÎÎÎÎÎÎÎÎÎÎÙip„+.×stuff „ ŒSE « # (Œor'ip') '' «© char


ge „ ‰cmp © greater or equaleq „ =cmp© equalne „ ¬cmp© not equallt „ cmp© greater than(Œns'') ­ Œns''© distinct spaces don't match.0(Œns'') eq Œns''© distinct spaces deemed equal.1°.geþ 0 1© truth-table for ge.1 01 1grade„{| œ² ‡³† ¸¸ qsort ¾ {¸ ¾}¨ ¾¾ ¼½¾} © grade up/down. €/†gu „ le grade + © grade-up “gd „ ge grade - © grade-down ”gu 3 1 4 1 52 4 1 3 5gd 3 1 4 1 55 3 1 2 4gu 3j5 3j4 4j3 3j42 4 1 3display stuffÚ…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ Ú´Ì ÚÎÎÎÌ Ú´Ì Ú´Ì ÛÛ ŒSE Û0Û # Û+.×Û Û Û Û0Û ÛÛ À~Ù À’ÎÎÙ ÀÎÙ À~Ù ÛÀ¹ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙgu stuff5 2 6 3 1 4gd stuff4 1 3 2 6 5q „ 'to' 'be' 'or' 'not' 'to' 'be'© grade-up of numeric vector.© grade-down of numeric vector.© complex number grade-up.© assorted stuff.© grade-up of stuff.© grade-down of stuff.© that is the question.gu q © grade-up of char vectors ...2 6 4 3 1 5“°† q © ... concurs with “°†2 6 4 3 1 5nvs „ (1 1) (2 3 4) (1 1) (3 1) (1 2)© numeric vectors.gd nvs © grade-down ...4 2 5 1 3”°† nvs © ... concurs with ”°†4 2 5 1 3See also: refmatch.382 logic.227 truth_tables.59354


ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎlexcmp „ ¸ (relat ##.lex) ¾ © Lexicographical comparison of arrays ¸ and ¾.Comparison of arrays ¸ and ¾ using relational function < ˆ = ‰ > ¬. Result [cmp]is a boolean scalar 0 or 1.Lex imposes an ordering on the set of all arrays in the sense that if ¸»¾, theneither (¸lex ¾) but not both. Compare this with a more naïve approach,which compared the enlist of each of its arguments; in this case neither(1cmp,1) so the strong ordering property would not hold.Lexicographical comparison might be useful, for example, when storing arrays onfile in a binary tree.Bug: Lex can not compare (arrays containing) namespace refs or ŒOR objects. Suchcomparisons generate NONCE and DOMAIN ERROR, respectively.The criteria for considering one array "greater" or "less than" another are opento debate. The following rules are intended to provide an intuitive ordering onarrays of arbitrary shape and depth.In the following:


1 2 3


In general, a list has many of the properties of an <strong>APL</strong> vector, except that:However,Separating the first from any remaining items in a list:head tail„¾is quicker and more elegant than the vector equivalent:head tail„(œ¾)(1‡¾)A list has no prototypical item, so "overtake" must be coded explicitly.There is an overhead of around 40 bytes per item, compared with a simplevector but this overhead is diluted when compared with a nested vector.size„{omega„¾ ª Œsize'omega'}© size in bytes.size 1e3½Œa © size of 1000-vector of bytes.1016size list 1e3½Œa © size of 1000-list of bytes.39980size ,¨1e3½Œa © size of 1000-vector of 1-vectors.24016size list ,¨1e3½Œa © size of 1000-list of 1-vectors.44016To access the ¸'th item of a list takes ¸ iterations, as opposed to thevector's 1. In other words, list-item-access is O(n), whereas vector-itemaccessis O(1). However, in both cases, access-each-item is O(n).To process all of the items in a list, a common operation, there is no equivalentof the array's primitive operator ¨ (each). Instead, an explicit loopmust be coded.()However, in defence of the list: splitting a problem into what-to-dowith-the-headtogether with what-to-do-with-the-tail is a powerful decompositiontechnique. Proponents of the list argue that, in situationswhere a vector can not be treated as a whole, recurring on a list as opposedto iterating on the vector leads to many fewer "plus-or-minus-one"problems.The following function counts the number of items in a list.litems„{© No. of list items.¸„0 © initial count is 0.¾­'°':¸© null list: accumulated count.head tail„¾© head item and tail.(¸+1)’ tail© accumulate with tail.}and this function converts a list to its equivalent vector:vect„{© Vector from list.¸„« © initial vector is «.¾­'°':¸© null list: accumulated vector.head tail„¾© head item and tail.(¸,›head)’ tail © accumulate with tail.}57


leading to operator [ltrav], which abstracts the essence of traversing a list:ltrav„{© List traversal.¾­'°':¸© null list : accumulator.head tail„¾© head item and tail.(¸ ¸¸ head)’ tail © accumulated with tail.}Note that in this general case, the initial accumulator ¸ must be supplied explicitlyas the operator can not know its type.Using such techniques we can show that, in some circumstances, the processing ofa list can outpace the equivalent (naïvely coded) vector version:vsum„{© vector summation.¸„0 © initial accumulator.0=½¾:¸© null vector: finished.head tail„(œ¾)(1‡¾) © first and remaining items.(¸+head)’ tail© accumulated sum.}lsum„{© list summation.¸„0 © initial accumulator.¾­'°':¸© null list: finished.head tail„¾© first and remaining items.(¸+head)’ tail© accumulated sum.}cmpx'vsum¼1e4' 'lsum list¼1e4'vsum¼1e4 2.2E¯1 0% ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒlsum list¼1e4 6.5E¯2 -72% ŒŒŒŒŒŒŒŒŒŒŒThe reason why vsum is so much slower is that (1‡¾), which is executed ½¾ times,makes a copy of all but the first item of the vector ¾.NB: Of course, there are better ways to sum a numeric vector!Technical note:The coding for list is simply:list„{ © list from vector ¾.†{¸ ¾}/¾,'°' © with '°' as null.}As {¸ ¾} is an idiom, the list function is relatively fast.Naming leading items--------------------We can name more than one item at the head of the list by using "structure assignment"(head tail) „ ¾© name first item and remainder.(head (next tail)) „ ¾© name first two items and remainder.(a (b (c (d (e ... ))))) „ ¾ © name first umpteen items and remainder.A rather contrived example of the use of this technique might be to remove adjacentduplicate values from a list:58


mdups„{ © remove adjacent duplicates.¸„'°'© null accumulator.(a(b tail))„¾© a and b are first two items.b­'°':'°'{¸ ¾}þltrav a ¸ © b null: list-reversed accumulator.a­b:¸ ’ b tail© two items match: drop first one.a ¸ ’ b tail© accumulate first, continue.}vect rmdups list 'Mississippi' © removal of adjacent duplicates.MisisipiExamples:ltrav„{© List traversal.¾­'°':¸© null list : accumulator.head tail„¾© head item and tail.(¸ ¸¸ head)’ tail © accumulated with tail.}50 {¸+1} ltrav list'hello' © length of list.length„0°( {¸+1} ltrav )© named list-length function.26length list Œavect„«°( {¸,›¾} ltrav )© vector from list.vect list 'hello'hellorevl„'°'°( {¸ ¾}þ ltrav )vect revl list 'hello'olleh© round-trip vector.© reverse of list.© vector reverse.© A more substantial example is this little "lambda expression" parser:parse„{© Right-to-left lambda expr parser.†{ © Œ„¸'Û'¾ © (uncomment to see trace).(toks a)(b(c accs))„¸ ¾ © aÛb c : aÛb c 3-item window.'•'­a:b © •Û* : * finished'()'­a c:toks ’ b accs © (Û* ) : Û* ·'(…'­a b:¸ ’ c accs © (Û… * : (Û*· ·'……'­a b:toks ’ ¾ © …Û… * : Û… *'…'­b:toks ’ b(('…'a c)accs) © vÛ… b : Û… v…b lambda node.'…)'­a c:toks ’ a ¾ © …Û* ) : Û… * )a¹'…(':¸ ’('@'b c)accs © (Ûf a : (Ûfa apply node.toks ’ a ¾ © *Û* · : Û* *}/†{¸ ¾}þ/²'•(',¾,')' © parse of token list ¾.}© Notice that, apart from the last line, there are very few <strong>APL</strong> primitive funct-© ions in the code; most of the action takes place using structure construction© and deconstruction by assembling and naming parts of the ¸ and ¾ lists.)copy min trees© borrow Min's expression tree display.59


trees parse '(t…ttt)(fx…f(fx))+0' © parse tree for lambda expression.ÚÎ@ÌÚÎÎ@Ì 0ÚÎÎÎÎ@ÎÌ +Ú…ÎÎÌ Ú…ÎÌt ÚÎ@Ì f Ú…ÎÌÚ@Ì tt tx Ú@ÎÌf Ú@Ìf xSee also: alists.8 parse.237 lisp.236ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎmatchhits „ patn {w„'*'} ##.match array© find with wildcards.A generalisation of º, which takes account of "wildcard" items in its left argumentpattern vector. The result is a boolean array, the same shape as the rightargument, showing where each occurrence of [patn] is found.By default, the wildcard is character '*' but an alternative scalar may be suppliedas a second item of a left argument pair. See example below.In common with primitive function find (º), overlapping strings are matched.NB: From <strong>Dyalog</strong> v13.0, this functionality is provided by system operator ŒS.Technical notes:Notice in the following that the subject array ¾ may be of higher rank.The first two lines:p x„{¾'*'}ÿ(1=­,¸),¸v„1‡¨{(x­¨¾)›¾}x,p© pattern and wildcard.© wildcard-separated segments.establish the pattern and wildcard items before splitting the pattern into wildcard-separatedvectors. For example:'red*green*blue' match 'credit green bored blues' © tracing ......disp vÚ…ÎÎÂÎÎÎÎÎÂÎÎÎÎÌÛredÛgreenÛblueÛÀÎÎ…ÁÎÎÎÎ…ÁÎÎÎ…ÙThe third line:h„†vº¨›¾© hits, one row (leading subarray) per segment.produces a simple boolean "hits array" of rank one more than the subject array ¾where subarrays along the leading axis are hits per pattern segment.¾®hc r e d i t g r e e n b o r e d b l u e s0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 „ hits for 'red'0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 „ .. .. 'green'0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 „ .. .. 'blue'Using reduction along the vector of trailing axes, the hits arrays are refinedright-to-left so that at each step of the reduction, the right argument representshits of trailing pattern segments. For example,60


c r e d i t g r e e n b o r e d b l u e s0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 00 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 01 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 „ mask for 'blue'c r e d i t g r e e n b o r e d b l u e s0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 00 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 „ hits for green*blue1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0c r e d i t g r e e n b o r e d b l u e s0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 00 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 „ hits for green*blue· · · · · · · · · · · · · · · · · · · · · · · ·c r e d i t g r e e n b o r e d b l u e s0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 „ second occurrence ignored1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 „ mask for green*blue· · · · · · · · · · · · · · · · · · · · · · · ·c r e d i t g r e e n b o r e d b l u e s0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 „ hits for red*green*blue1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0· · · · · · · · · · · · · · · · · · · · · · · ·A slight complication arises with overlapping patterns:'ban*and' match 'abandon' © tracing ......disp v© pattern segments.Ú…ÎÎÂÎÎÎÌÛbanÛandÛÀÎÎ…ÁÎÎ…Ù...¾®h© pattern segment hits.a b a n d o n0 1 0 0 0 0 00 0 1 0 0 0 0In this case, the string 'ban*and' does not occur within 'abandon'. The upperrow of the hits matrix should really be shifted, so that the start of the secondhit coincides with the end of the first:a b a n d o n0 0 0 0 1 0 0 „ shifted hit after 'ban'0 0 1 0 0 0 0 „ 'and' does not follow 'ban'We could do this inside the reduction by shifting the left argument right; applyingthe mask; and then shifting the result back again for the next step. However,a more efficient way is to shift the right argument left, which doesn'trequire a second shift back again.a b a n d o n0 1 0 0 0 0 0 „ hit for 'ban'0 0 0 0 0 0 0 „ hit for 'and' shifted off left-hand side.We can't just use <strong>Dyalog</strong>'s primitive rotatation function ² for the shifting as1s rotated off the left hand side would reappear on the right. To avoid this, weappend a sufficient number of columns of zeros to the right of the array; rotateand then drop the same number of colums from the right. This means that any 1sshifted beyond the left edge of the array are lost, as required:61


sl„{ © array shifted left.a„¯1‡½¾© leading axes.x„—/¸© maximum shift.p„¾,(a,x)½0© 0-padded on right.s„³a½¸© subarray of vector rotations.(-(0×a),x)‡s²p © shifted array.} © :: a „ r ’ aNote that this shifting and the following propogation of 1s to the left, to formthe mask, may be done outside the reduction.m„²Ÿ\²r sl h © shifted mask 1 .. 1 0 .. 0Then hit/mask pairs form the items of the vector to be reduced:}/‡³†vec¨h m© hits and masks.Examples:botter „ 3 13½'betty botter bought a bit better butter'betty botterbought a bitbetter butter'b*t' match botter1 0 0 0 0 0 1 0 0 0 0 0 01 0 0 0 0 0 0 0 0 1 0 0 01 0 0 0 0 0 0 1 0 0 0 0 0(2 ¯1 1 8)¯1 match 2 7 1 8 2 8 1 8 2 8 © ¯1 is wildcard1 0 0 0 1 0 0 0 0 0'12*56*9'match ŒD0 1 0 0 0 0 0 0 0 0(2½¨¨ '12*56*9' '*') match 2½¨ŒD0 1 0 0 0 0 0 0 0 0© multiple wildcards© nested arguments.display A „ 2 2 20½' ' © Higher rank argument ...ÚÚ…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ̇‡ ÛÛÛ


ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎmerge‘ „ new (select ##.merge) subject © Suggestion for a merge operator.‘ „ new (select ##.merge2) subject © Alternative for a merge operator.[subject] array but with [new] items at [select]ed positions.There are three cases:1. [select] is a simple array of indices: ¾[¸¸;;...]„¸¯¯¯¯¯¯¯¯¯¯¯¯Simple indexing along first axis. Use the rank operator to select alongother axes. See examples below.2. [select] is a nested array of index vectors: ¾[¸¸]„¸¯¯¯¯¯¯¯¯¯¯¯¯Choose/reach indexing. Index vectors in ¸¸ select items scattered at pointsin the subject array.3. [select] is a function: ¾[¸¸ ¼½¾]„¸¯¯¯¯¯¯¯¯Function ¸¸ selects from the subject's index array: ¼½¾.'¹³´' (2 5 8 merge) 'Hello world'H¹ll³ w´rld© case 1: simple-indexing merge1 ((2 2)(3 4)merge)4 5½0 © case 2: choose-indexing merge0 0 0 0 00 1 0 0 00 0 0 1 00 0 0 0 0'ABCD' (1 1°³ merge) 4 4½¼16A 2 3 45 B 7 89 10 C 1213 14 15 D© case 3: using selection functionBackground----------Classic <strong>APL</strong> lacks a general, non-procedural way to express the "triadic" function:"THESE items at THOSE positions in THIS array". For example: "Stars at thevowel positions in the alphabet".Rather, it compels us to use a 3-stage _procedure_ and forces us to name thesubject array:(muse:[1] Name the subject array, © THIS „ ¾[2] Update the array, using its name, © THIS[THOSE]„THESE[3] Dereference the name for the result. © THISIdeally, the language should never force us into naming the results of expressions.Better that we choose to name things only in order to create mentalabstractions that are easier for us to work with. For example, the followingthree code fragments are equivalent and each reducible by the language evaluatorto the syntax tree on the right:(+/¾)÷½¾ ©© ÚÎÎÎÏÎÌsum„+/¾ ª num„½¾ ª sum÷num © ÃÎÌ ÷ ÃÎÌ© ÚÎÝ ¾ ½ ¾sum„+/ ª num„½ ª (sum ¾)÷num ¾ © + /63


)Sound bite: Names allow us to chop up our program into mind-sized chunks.Larg vs Rarg------------With indexed assignment, the "old" array is on the left and the "new" values areon the right:OLD[¼3]„'NEW'With [merge], we save on parentheses if we arrange for the value which would,more often than not be named or literal, to occur on the left. Here are examplesof both cases:MAT (... merge) lcase MAT © Lower-casification of selected chars in MAT.© old (sel merge) new © say: "Old with sel[ected items] set to new".vs:¯¯¯¯'*' (... merge) 5 5½ŒA © Stars for selected chars in matrix.© new (sel merge) old © say: "New for sel[ection] in old".¯¯¯¯Arguably more important than saving parentheses, is the impact of argument orderon the notation as tool-of-thought. It seems (to JMS) to be less distracting ifthe modification (new value) is on the left; merges are applied as refinementsto the result of the expression developed on the right."<strong>APL</strong> may be evaluated from right to left but people read it from left to right".- Floy Ivie, in a discussion in the late 1970s about the relative merits of ';'and 'ª' as statement separators.Further:- Functional programming uses a notation: [new/old]expr "new for old in expr",where "new" and "old" are strings. "old" specifies positions of matches within"expr". [merge]'s left operand is simply a generalisation: [new/expr¹old]expr.- Looking at the vocalisation (say:) above, the first seems more procedural andthe second more declarative. Declarative is, in general, easier on the mind.Merge is closely related to J's "amend":http://www.jsoftware.com/help/dictionary/d530n.htmNomenclature------------"Amend" or "Replace" might be better names for this operator, as "merge" carriesa connotation of preserving both old and new items (merging streams of traffic).Even better would be a word that is a noun (or forms a noun-phrase with itsoperand), which is why merge(n) is attractive as it leads us away from proceduralthinking. "0œ…vec" does not amend vec nor replace its first item; it leavesit alone and denotes a distinct array, which may differ from vec in its firstitem.(muse:64The above may seem a trivial point and not worth agonising about. However,(JMS feels that) many of us are trapped in the procedural mindset, which waspervasive when we learned to program. Some languages are "variable-centric":to achieve anything we need to declare some variables and then mutate theminto the result we require. In contrast, the style in which mathematiciansappear to think, in terms of equivalent expressions, seems (to JMS) to carrymuch less mental baggage: results are just refined step-wise from arguments.A less cumbersome tool-of-thought.So any little nudge in the right direction, by encouraging declarative terminology,helps.


The word "at" would be just the ticket if its operand appeared to its right:'*' at 2 5 € 'hello'. The transliteraion of Arthur Whitney's sudoku solver…sudoku_bfs„ ignores this awkwardness and uses "at":)at „ {¾+¸×(¼½¾)¹›¸¸}© puzzle ¾ with ¸ at position ¸¸An Alternative Definition-------------------------Parentheses are needed to prevent an _array_ operand from binding with the leftargument. This is not the case for a _function_ operand:'*' œmerge 'abc' © no parens :-)*bc'*'(1 merge)'abc' © parens needed :-(*bcIf the array operand is itself the result of an expression, we need additionalparentheses and the expression soon starts to look cluttered:a**'*' ((1+¼2)merge) 'abc' © more parens :-((It would be nice if we could move some functionality from the array-operand caseinto the less parenthesis-hungry function-operand case.A survey of customer code suggests that boolean compression accounts for around70% of selective specification (with pick (œ) making up half of the remainder).With this in mind, it might produce less overall clutter if instead of applyinga structural function († ‡ ...) to the subject's index array, [merge] expected amonadic boolean-valued function to be applied directly to the subject, producinga mask of which items are to be replaced. Then we could have:a*c'*' =°'b' merge2 'abc'© merge2: look, no parensand even if the operand function itself needed an array left operand, the parenswould be more localised and somehow less obtrusive:ab*'*' ('c'°=) merge2 'abc'© tigher parensThe downside of this definition is that (the 30% of) selection <strong>functions</strong> otherthan compression would need to generate _explicit_ indices, so instead of:'*' (¯2°†) merge 'abc'a**'H' œmerge 'hello'Hello© merge: function operand: neg two take© merge: function operand: firstmerge2 would need:'*' ((¯2†¼3)merge2) 'abc'a**'H' (Œio merge2) 'hello'© merge2: array operand© merge2: array operandThe change in implementation from merge to merge2 is simple:merge[2] 3=ŒNC'¸¸':A•A[ ¸¸ ¼½A„¾]„¸ © fn operand: index selection.¯¯merge2[2] 3=ŒNC'¸¸':A•A[(,¸¸ ¾)/,¼½A„¾]„¸ © fn operand: bool selection.¯¯¯¯¯¯¯¯¯65


Examples:©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©© With an array operand:vec„11 to 19© vector of numbers.vec11 12 13 14 15 16 17 18 19'x' ((4?9) merge) vecx 12 x 14 xx 17 18 19© random merge of 'x'0 (4 merge) vec © 4th item replaced with 0.11 12 13 0 15 16 17 18 190 (3 4 5 merge) vec © 3rd-5th items replaced with 0s.11 12 0 0 0 16 17 18 191 2 3 (4 3 2 merge) vec © 4th-2nd items replaced with 1-3.11 3 2 1 15 16 17 18 19'R' ((›2 3) merge) 'hello' 'world'hello woRld© reach-indexing example.mat„10ƒ¨¼4 5© matrix of numbers.mat11 12 13 14 1521 22 23 24 2531 32 33 34 3541 42 43 44 450 (2 merge) mat © 2nd row replaced with 0s.11 12 13 14 150 0 0 0 031 32 33 34 3541 42 43 44 450 (4 merge rank 1) mat © 4th col replaced with 0s.11 12 13 0 1521 22 23 0 2531 32 33 0 3541 42 43 0 450 (2 3 merge) mat © 2nd & 3rd rows replaced with 0s.11 12 13 14 150 0 0 0 00 0 0 0 041 42 43 44 45(2 5½¼10) ((›3 2)merge) mat © 3rd & 2nd rows replaced with numbers.11 12 13 14 156 7 8 9 101 2 3 4 541 42 43 44 450 ((2 3°.,2 4)merge) mat © 2nd 3rd rows, 2nd 4th cols „ 0.11 12 13 14 1521 0 23 0 2531 0 33 0 3541 42 43 44 4566


(2 3½¼4) ((1+¼2 3)merge) mat © numbers in the middle.11 12 13 14 1521 1 2 3 2531 4 5 6 3541 42 43 44 45cube„10ƒ¨¼2 3 4© cuboid of numbers.cube111 112 113 114121 122 123 124131 132 133 134211 212 213 214221 222 223 224231 232 233 2340 (2 merge) cube © 2nd plane replaced with 0s.111 112 113 114121 122 123 124131 132 133 1340 0 0 00 0 0 00 0 0 00 (2 merge rank 2) cube © 2nd rows replaced with 0.111 112 113 1140 0 0 0131 132 133 134211 212 213 2140 0 0 0231 232 233 2340 (2 merge rank 1) cube © 2nd cols replaced with 0s.111 0 113 114121 0 123 124131 0 133 134211 0 213 214221 0 223 224231 0 233 234(3 4½¼12) (2 merge) cube © 2nd plane replaced with matrix.111 112 113 114121 122 123 124131 132 133 1341 2 3 45 6 7 89 10 11 129999 ((›«)merge) 88 © scalar case.© Here's a handy derived function:atfirst „ Œio merge © merge with first cell (row, plane, ...).'µ' atfirst 4½ŒaµBCD© first item of vector.67


'this' atfirst 3 4½Œa © first row of matrix.thisEFGHIJKL'Œ' atfirst 2 3 4½ŒaŒŒŒŒŒŒŒŒŒŒŒŒ© first plane of cube.MNOPQRSTUVWX0 disp 'HW' atfirst¨ 'hello' 'world' © nested (reach) merging.ÚÎÎÎÎÎÂÎÎÎÎÎÌÛHelloÛWorldÛÀÎÎÎÎÎÁÎÎÎÎÎÙ©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©© With a function operand:Hello'H' œmerge 'hello'© first item'HW' œmerge¨ 'hello' 'world'ÚÎÎÎÎÎÂÎÎÎÎÎÌÛHelloÛWorldÛÀÎÎÎÎÎÁÎÎÎÎÎÙ'*' {4†,¾}merge 2 3½¼6* * ** 5 6'ABCD' (1 1°³ merge) 4 4½¼16A 2 3 45 B 7 89 10 C 1213 14 15 D© first each© first four of ravel© diagonal©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©© merge2: Alternative definition.'*' ¹°'AEIOU' merge2 ŒA*BCD*FGH*JKLMN*PQRST*VWXYZ'HW'((1 1)(2 1)merge2)'hello' 'world'Hello World'twas' 'ever' 'thus' =/¨merge2 ¼3 4twas 1 2 1 3 1 42 1 ever 2 3 2 43 1 3 2 thus 3 4© more beautiful than merge© less beatiful than œmerge¨© bool mask and rarg ravelled.See also: squad.84 select.81 rank.73ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎmnsref „ ##.mns defn © Make Namespace from association list ¾.[defn] is a "name association list" of the form ('name' class value), ···. Theresult is a reference to a new namespace in which each name in the list has beeninstantiated with its given class. The list may contain nested items with class=9 to represent sub-spaces. The [mns] function was suggested by Paul Mansour.68


Technical note:As [mns] is a utility function, it should be able to operate in an environmentwith any migration level and either index origin. However, the code may notlocalise and specify ŒML or ŒIO as these values would be inherited by the namespacesit created. For this reason, the code is written in an origin and migrationlevel independent way.Examples:disp alist© show assoc. listÚ…ÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÛÛÚ…ÎÎÂÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛÛ ÛÛ Û ÛÚ…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛÛÛÚ…ÎÎÂÎÂÎÎÎÎÎÌÛÛ Û ÛÛÚ…ÎÎÂÎÂÎÎÎÎÎÎÎÎÎÎÎÌÛÚ…ÎÎÎÂÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛÛÛÚ…ÎÎÎÂÎÂÎÎÎÎÛÛmatÛ2Û1 2 3ÛÛÛ Û ÛÛÛ Û ÛÚ…ÎÎÎÎÎÎÎÎÌÛÛÛ Û ÛÚ…ÎÎÎÎÎÎÎÎÎÎÌÛÛÛÛÛ Û ÛÚ…ÎÎÛÛ Û Û4 5 6‡ÛÛsubÛ9ÛÛÛdupÛ3ÛÛdup„{¾ ¾}ÛÛÛÛoperÛ4ÛÛoper„{¸¸ ¾}ÛÛÛÛÛÛspinÛ3ÛÛspiÛÀÎÎ…ÁÎÁ~ÎÎÎ…ÙÛÛ Û ÛÛÛ Û ÛÀÎÎÎÎÎÎÎÎ…ÙÛÛÛ Û ÛÀÎÎÎÎÎÎÎÎÎÎ…ÙÛÛÛÛÛ Û ÛÀÎÎÎÛ ÛÛ Û ÛÛÀÎÎ…ÁÎÁÎÎÎÎÎÎÎÎÎÎ…ÙÛÀÎÎÎ…ÁÎÁÎÎÎÎÎÎÎÎÎÎÎÎ…ÙÛÛÛÀÎÎÎ…ÁÎÁÎÎÎÎÛ ÛÛ Û ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÙÛÛÛÛÀÎÎ…ÁÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÙÛÀÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎtree mns alist#.[Namespace]· ~ mat· ’ spin· sub· · ’ dup· · ° oper(mns alist).(spin sub.(dup oper) mat)1 4 1 42 5 2 53 6 3 6© show fixed ns.© check it out.See also: rep.402ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎnlinesn „ ##.nlines simple© Number of display lines for simple array.Default display of <strong>APL</strong> arrays is arranged with items along the last axis acrossthe page and items along leading axes downwards. Planes of items are separatedby successively higher numbers of blank lines: trailing rank-2 arrays are separatedby 1 line; rank-3 arrays by 2 lines; ...; rank-¾ arrays by (0—¾-1) lines.69


display {Œfmt 2 ¾ 2 2½¼24}¨3 2 1 0 © format of some rank-4 arrays.Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ Ú…ÎÎÎÎÌ Ú…ÎÎÎÎÌ Ú…ÎÎÌ Ú…ÎÎÌ ÛÛ ‡ 1 2Û ‡ 1 2Û ‡1 2Û ‡ Û ÛÛ Û 3 4Û Û 3 4Û Û3 4Û Û Û ÛÛ Û Û Û Û Û Û ÀÎÎÎÙ ÛÛ Û 5 6Û Û 5 6Û Û Û ÛÛ Û 7 8Û Û 7 8Û Û5 6Û ÛÛ Û Û Û Û Û7 8Û ÛÛ Û 9 10Û Û Û ÀÎÎÎÙ ÛÛ Û11 12Û Û 9 10ÛÛÛ Û Û Û11 12Û ÛÛ Û Û Û Û ÛÛ Û13 14Û Û13 14ÛÛÛ Û15 16Û Û15 16ÛÛÛ Û Û ÀÎÎÎÎÎÙ ÛÛ Û17 18ÛÛÛ Û19 20ÛÛÛ Û Û ÛÛ Û21 22ÛÛÛ Û23 24ÛÛÛ ÀÎÎÎÎÎÙÛÀ¹ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙJay Foad's function returns the number of lines of output that its simple argumentarray would produce.This function is presented as a programming challenge, rather than as having anypractical application. In fact a sneaky alternative coding could be: «°½°½°Œfmt.Note that the occurrence of a newline character in the argument array will displaymore lines than [nlines] predicts.It is left as an "exercise for the student" to extend this function to nestedarrays :-).Examples:2 3 4½¼24 © default output of rank-3 array ...1 2 3 45 6 7 89 10 11 1213 14 15 1617 18 19 2021 22 23 247nlines 2 3 4½¼24© ... produces 1+2×3 lines of output2 22 22 2 2 2½2 © rank-4 array ...2 22 22 22 270


2 22 212165907nlines 2 2 2 2½2nlines 2 0 3½4nlines 2 3 0 0½0nlines 1 2 3 4 5 6 7 8½9cfmt„{(nlines ¾)­œŒfmt ¾}shapes„0 1 2 3°adic¨¼1000© ... 12 lines.© null array.© null array.© rank-8 array.© compare with output from monadic Œfmt.© selection of shapes1^/ cfmt¨ shapes ½¨ 0 © compare selection of arraysSee also: adic.253ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎpackarray „ ##.pack array© Saves WS by sharing subarrays.Pack attempts to increase the amount of workspace available by sharing identicalsubarrays in its argument. For a sizeable argument, this takes a very long timeas each subarray is compared with every other one (n*2 comparisons). It isworth doing only when workspace availability is at a premium, perhaps prior toshipping an application containing complex nested variables. Notice that subarrayscan be shared _among_ distinct variables - see example below. Note thatin this context, system function ŒSIZE can be misleading as it ignores arraysharing.NB: [pack] shares items at _and_ _between_ all depths in its argument array. Forsharing of subarrays at any particular level, the following simple function isconsiderably faster. Note that it may be applied under each (¨) to share itemsat (but not between) greater depths.pack1 „ {(ž,¾){¸[¸¼¾]}¾}© share top level items.ditty „ ('Dime' 'cuándo' 'serás' 'mia') ('Dime' 'cuándo' 'cuándo' 'cuándo')All recent versions of <strong>Dyalog</strong> share literal constants, such as 'cuándo' above.To emulate a more real situation, where array items are typically created byfunction application, let's make sure we start with an array of unshared items:unsh „ ²°²ditty „ unsh¨ ditty© reversal creates a new vector.© force unsharing.Now pack:ditty „ pack1¨ ditty© share inside, but not among, sub vectors.ditty „ pack ditty © share _all_ subarrays.NB: Related function …nspack„ shares all subarrays within a given namespace.Technical note:Pack uses (6¬10|ŒDR ¾:) to determine whether a subarray is homogeneous or heterogeneous.In the latter case, the array's items may be shared as well as thearray itself. Compare the following two depth-1 arrays:1 0 6 6 © hom: try to share whole array.71


Examples:'1' 0 6 6 © het: try to share array _and_ its subarrays.wa„Œwa ª cvecs„(¼1e3)²¨›Œa ª wa-Œwa© WS used by distinct char vectors,48032wa„Œwa ª cvecs„pack cvecs ª wa-Œwa © sharing recovers most of it.¯428560144A „ ²°²¨ 'Scissors' 'Paper' 'Stone'B „ ²°²¨ 'Paper' 'Stone' 'Scissors'C „ ²°²¨ 'Stone' 'Scissors' 'Paper'wa„ŒwaŒwa-waA B C„pack A B CŒwa-wanested„¼¨°¼¨°¼¨°¼¨°¼3 3© Sharing subarrays _among_ variables,© ... releases some workspace.© complex nested array:17936wa„Œwa ª nested„pack nested ª Œwa-wa© significant saving.See also: nspack.378 Data_compression.190ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎpervrslt „ lft (fun ##.perv) rgt© Scalar pervasion.The function operand is applied between corresponding simple scalars in eachargument.Technical note:[perv] is closely related to the dyadic form of operator …saw„ (simple-arraywise).The only difference is that [perv] applies its function operand betweendepth-0 arrays and …saw„, between depth-(0 or 1) arrays.We could parameterize the maximum depth at which the function is applied bypassing it as a right operand:wwaw„{© Function operand applied ¾¾-Array-Wise.¾¾‰¯1+|­¸ ¾:¸ ¸¸ ¾ © Both shallow enough: apply operand.¾¾‰|­¾:’°¾¨¸ © ¾ shallow: traverse ¸.¾¾‰|­¸:¸°’¨¾ © ¸ shallow: traverse ¾.¸ ’¨¾© Both deep: traverse both.}Remember that in <strong>Dyalog</strong>, vector strands bind tighter than operands. This meansthat it may be necessary to separate the right operand from the argument:aaa (, wwaw 0) bbbaaa , wwaw 0 ² bbb© operand 0 separated from argument bbb.© parentheses unnecessary in this case.Example:disp 1(2 3),perv(4 5)6Ú…ÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÌÛÚ…ÎÎÂÎÎÎÌÛÚ…ÎÎÂÎÎÎÌÛÛÛ1 4Û1 5ÛÛÛ2 6Û3 6ÛÛÛÀ~Î…Á~Î…ÙÛÀ~Î…Á~Î…ÙÛÀÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎ…ÙSee also: saw.78 rows.74 truth_tables.59372


ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎpmatmat „ ##.pmat n© Permutation matrix of ¼¾.[pmat] takes an integer scalar [n] and returns a !n row matrix of the permutationsof ¼n.Technical notes:The method used here is to take each item of ¼n in turn and append all subpermutationsof the remaining (n-1) items. This produces result items in ascendingorder. Thus, for any ¾: {¾­¼½¾}“pmat ¾.The code looks like this:pmat„{ŒML„0© Permutation matrix of ¼¾.{ © perms of ¼¾:1‰½¾:†,‡¾ © short vector: done.†®/¾,°’¨¾°~¨¾ © items prefix sub-perms of remainder.}¼¾© permutations of identity perm.}Perttu Pakarinen suggests the following _much faster_ version. It produces rowsin non-ascending order but could easily be modified: {¾[“¾;]}.prm„{(ŒIO ŒML)„1 3(×\¼¾){0¹½¸:¾ ª (r c)„½¾(1‡¸)’(r/0,¼c)²(¸[1],c+1)½(†½¸),¾}1 0½0}For large values of ¾, the resulting permutation matrix takes a large amount ofworkspace. In this case, it might be better to apply an auxiliary function toeach permutation as it is generated. The following operator does the trick:perms„{© Apply ¸¸ to each perm of ¼¾« ¸¸{ © null accumulator1‰½¾:¸¸ ¸,¾ © short tail: apply operand to perm(¸°,¨¾)’¨¾°~¨¾ © transfer each tail item to head}¼¾© for initial vector.}Roger Hui provides this even faster version:pmat2„{{,[¼2]†(››Œio,1+¾)¦¨”¨‡°.=þ¼1+1‡½¾}ÿ¾³®«}translated from perm2 in http://www.jsoftware.com/jwiki/Essays/Permutationsitself a translation from <strong>APL</strong>.Examples:1 2 31 3 22 1 32 3 13 1 23 2 1pmat 3© 3-perms.{¾[pmat½¾]}'tic' 'tac' 'toe'tic tac toetic toe tactac tic toetac toe tictoe tic tactoe tac tic© Perms of nested vector.73


4 3 2½‡{¾[pmat½¾]}'abcd' © Folded perms of simple 4-vector.abcd abdcacbd acdbadbc adcbbacd badcbcad bcdabdac bdcacabd cadbcbad cbdacdab cdbadabc dacbdbac dbcadcab dcba½pmat 103628800 10display°pmat¨2 1 0Ú…ÎÎÌ Ú…Ì Ú´Ì‡1 2Û ‡1Û ‡0ÛÛ2 1Û À~Ù À~ÙÀ~ÎÎÙ© !¾ rows.© Limiting cases1(!0 to 5) ­ œ°½°pmat¨0 to 5 © Result lengths.{¾¼¾°.{¸œ¨›¾}¾}‡pmat 31 2 3 4 5 62 1 4 3 6 53 5 1 6 2 44 6 2 5 1 35 3 6 1 4 26 4 5 2 3 1© Rows of the permutation matrix form© a group under œ¨°› with identity ¼¾.Œ°„ perms 31 2 31 3 22 1 32 3 13 1 23 2 1© show each permutation.See also: cmat.19ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎpredrslt „ part (redn ##.pred) rarg© Partitioned reduction.Suggested by Michael Baas, pred returns a partitioned reduction of its argumentarray. [part] is a vector of partition sizes, such that (+/part)=¯1†½rarg.Ways to code this operator include:pred„{Œml„1 ª ¸¸/¨(¹¸†¨1)›¾} © --3 SLpred„{(Œio Œml)„1 3 ª ¸¸/¨(¸/¼½¸)›¾} © 1-3 VMJ/MJpred„{(Œio Œml)„1 3 ª ¸¸/œ(¸/¼½¸)›¾} © 12- GQpred„{res„(½¸)½¸¸/« ª res[¸/¼œ½¸]¸¸„¾ ª res} © -2- BT74pred„{Œml„3 ª ¸¸ nz/œ(¸/¼½¸)›¾} © 12- SMpred„{Œio„0 ª (¼½¾)¸¸ nz.×¾} © -2- SMpred„{Œio„0 ª ³(¼¯1†½¾)¸¸ nz.׳¾} © 12- SM, where:nz„{0¬¸×¾: ¸ ¸¸ ¾ ª ¸=0:¾ ª ¸}© auxiliary op.


Note:1. Works for matrix (and higher rank) rarg.2. "Each-less" solution.3. Unrestricted operand function (eg: ',').Examples:2 3 3 2 +pred ¼103 12 21 191 2 1 ×pred 2 3 4½¼241 6 45 42 89 110 1213 210 1617 342 2021 506 24disp 1 2 1,pred 3 4½¼12Ú…ÂÎÎÎÎÎÂÎÎ̇1Û 2 3 Û4 ÛÃÎÏ~ÎÎÎ…Ï~ÎÝÛ5Û 6 7 Û8 ÛÃÎÏ~ÎÎÎ…Ï~ÎÝÛ9Û10 11Û12ÛÀÎÁ~ÎÎÎ…Á~ÎÙSee also: acc.10 foldl.45 trav.130ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎrankleft fn ##.rank{ranks} right © Apply function to/between rank-¾¾ subarrays.left fn ##.rank ranks € rightfn ##.rank{ranks} rightfn ##.rank ranks € rightNB: From <strong>Dyalog</strong> V14, rank is primitive operator °¨.Supplied by Phil Last, who says: "This pretty much follows Iverson's definition.The right operand is used in such a way that the value(s) for monadic, left &right ranks can be placed in braces or to the left of a convenient identity."I'm not sure that negative ranks are treated correctly. It does something but itmay not be what Iverson (or I) intended!Technical notes:Notice Phil's technique of allowing the right operand of rank to be a ranks_vector_ or _function_. For example, either (1 2) or {1 2}. In either case, theranks are extracted by the expression ¾¾,« in the following:g„²3½²¾¾,«¯¯¯¯This (constant function) device is handy in <strong>Dyalog</strong>, as the binding of adjacentarrays is stronger than the binding of an operator to its operand _array_. Forexample, if [op] is a dyadic operator, and if [rand] is the operator's _array_operand and [rarg] is the derived function's array argument, then:land op rand rarg land op (rand rarg)land op {rand} rarg (land op {rand}) rargland op rand € rarg (land op rand) € rarg75


Notice also the technique of determining whether the (derived) function wascalled in a monadic or dyadic context (left argument missing or present).m„0 ª ¸„m„1The second phrase ¸„m„1 is evaluated only if the function is called with no leftargument. An alternative coding, which is possible since the enhancement to theinterpreter (2001-05-31) to allow '¸', '¾', '¸¸', '¾¾' as arguments to ŒNC,would be:Examples:m„0=Œnc'¸'(2 2½1 2 2 1)³rank{1 2}2 3 4½¼99 © (using ranks _function_)1 2 3 45 6 7 89 10 11 120 0 0 013 17 21 014 18 22 015 19 23 016 20 24 0(2 2½1 2 2 1)³rank 1 2 €2 3 4½¼99 © (using ranks _vector_)1 2 3 45 6 7 89 10 11 120 0 0 013 17 21 014 18 22 015 19 23 016 20 24 0ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎrowsrslt „ (fun ##.rows) {array} © Operand function applied to argument rows.Many <strong>functions</strong> expect a simple vector or scalar, such as a "name", as argument.This operator accepts any rank or depth array and applies its function operandto each simple vector or scalar therein.Examples:1 1 1isdfn rows 'a'Œnl 3© Fn applied to each row of matrix.{''} rows 'ten' 'a' 'penny' disp matsÚ…ÎÎÎÎÂÎÎÎÎÎÎÂÎÎÎÎÎÎÎÌÛeightÛhoveraÛhickoryÛÛnine ÛdoveraÛdickoryÛÛten ‡dik ‡dock ‡ÀÎÎÎÎ…ÁÎÎÎÎÎ…ÁÎÎÎÎÎÎ…Ùdisp {½¾~' '} rows matsÚ…ÂÎÂÎÌÛ5Û6Û7ÛÛ4Û6Û7ÛÛ3‡3‡4‡À…Á…Á…Ù76© Scalars are OK, too.© A vector of matrices.© Fn applied to each matrix row.


disp {+/¾¬' '} rows mats © Rows collapse to scalars.Ú…ÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÌÛ5 4 3Û6 6 3Û7 7 4ÛÀ~ÎÎÎ…Á~ÎÎÎ…Á~ÎÎÎ…Ùdisp {¾[“¾]} rows matsÚ…ÎÎÎÎÂÎÎÎÎÎÎÂÎÎÎÎÎÎÎÌÛeghitÛaehorvÛchikoryÛÛ einnÛadeorvÛcdikoryÛÛ ent‡ dik‡ cdko‡ÀÎÎÎÎ…ÁÎÎÎÎÎ…ÁÎÎÎÎÎÎ…Ùdisplay rows matsÚ…ÎÎÎÎÌ Ú…ÎÎÎÎÎÌ Ú…ÎÎÎÎÎÎÌÛeightÛ ÛhoveraÛ ÛhickoryÛÀÎÎÎÎÎÙ ÀÎÎÎÎÎÎÙ ÀÎÎÎÎÎÎÎÙ© Sort each row.© Display each row.Ú…ÎÎÎÎÌ Ú…ÎÎÎÎÎÌ Ú…ÎÎÎÎÎÎÌÛnine Û ÛdoveraÛ ÛdickoryÛÀÎÎÎÎÎÙ ÀÎÎÎÎÎÎÙ ÀÎÎÎÎÎÎÎÙÚ…ÎÎÎÎÌ Ú…ÎÎÎÎÎÌ Ú…ÎÎÎÎÎÎÌÛten Û Ûdik Û Ûdock ÛÀÎÎÎÎÎÙ ÀÎÎÎÎÎÎÙ ÀÎÎÎÎÎÎÎÙcuboid1 2 3 4 56 7 8 9 1011 12 13 14 1516 17 18 19 20© Numeric 3×4×5-array.21 22 23 24 2526 27 28 29 3031 32 33 34 3536 37 38 39 4041 42 43 44 4546 47 48 49 5051 52 53 54 5556 57 58 59 60{+/¾÷½¾} rows cuboid3 8 13 1823 28 33 3843 48 53 58© Row-averages.See also: saw.78 perv.70ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎsamnew „ {larg} (sel ##.sam mod) old© Select and modify.[sel]ected items of the [old] array are [mod]ified. [larg] is an optional leftargument to [sel], which is a primitive function suitable for selective specification.[mod] is a monadic function that is applied to the selected items ofthe array. Application of the operator, bound with its function operands, isequivalent to the selective specification:new„old(larg sel new)„mod larg sel oldnew77


Technical note:Suggested by Paul Mansour, [sam] can be used to avoid, or at least hide, the"destructive assignment" that is anathema to the functional programming purist.Having said this, the selective specification, which is used to implement [sam],is a prime example of such destruction. There are "pure" ways to code this operatorbut none are as efficient.Examples:Œio Œml„1 0© environment for examples:disp vex© depth-3 array.Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛÚ…ÎÎÂÎÎÎÂÎÎÎÎÎÌÛÚ…ÎÎÎÎÂÎÎÎÎÂÎÎÎÎÎÌÛÚ…ÎÎÂÎÎÎÎÂÎÎÎÎÎÌÛÛÛoneÛtwoÛthreeÛÛÛalphaÛbetaÛgammaÛÛÛredÛblueÛgreenÛÛÛÀÎÎ…ÁÎÎ…ÁÎÎÎÎ…ÙÛÀÎÎÎÎ…ÁÎÎÎ…ÁÎÎÎÎ…ÙÛÀÎÎ…ÁÎÎÎ…ÁÎÎÎÎ…ÙÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…Ùdisp 2 †sam² vex© first two items reversed.Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛÚ…ÎÎÎÎÂÎÎÎÎÂÎÎÎÎÎÌÛÚ…ÎÎÂÎÎÎÂÎÎÎÎÎÌÛÚ…ÎÎÂÎÎÎÎÂÎÎÎÎÎÌÛÛÛalphaÛbetaÛgammaÛÛÛoneÛtwoÛthreeÛÛÛredÛblueÛgreenÛÛÛÀÎÎÎÎ…ÁÎÎÎ…ÁÎÎÎÎ…ÙÛÀÎÎ…ÁÎÎ…ÁÎÎÎÎ…ÙÛÀÎÎ…ÁÎÎÎ…ÁÎÎÎÎ…ÙÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…Ùdisp 2 †sam²¨ vex© each of first 2 items reversed.Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛÚ…ÎÎÂÎÎÎÂÎÎÎÎÎÌÛÚ…ÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÌÛÚ…ÎÎÎÂÎÎÎÂÎÎÎÎÎÌÛÛÛtwoÛoneÛthreeÛÛÛbetaÛalphaÛgammaÛÛÛblueÛredÛgreenÛÛÛÀÎÎ…ÁÎÎ…ÁÎÎÎÎ…ÙÛÀÎÎÎ…ÁÎÎÎÎ…ÁÎÎÎÎ…ÙÛÀÎÎÎ…ÁÎÎ…ÁÎÎÎÎ…ÙÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…Ùdisp 2 †sam²¨¨ vex © each of each of .. ..Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛÚ…ÎÎÂÎÎÎÂÎÎÎÎÎÌÛÚ…ÎÎÎÎÂÎÎÎÎÂÎÎÎÎÎÌÛÚ…ÎÎÂÎÎÎÎÂÎÎÎÎÎÌÛÛÛnoeÛwtoÛhtreeÛÛÛlaphaÛebtaÛagmmaÛÛÛerdÛlbueÛrgeenÛÛÛÀÎÎ…ÁÎÎ…ÁÎÎÎÎ…ÙÛÀÎÎÎÎ…ÁÎÎÎ…ÁÎÎÎÎ…ÙÛÀÎÎ…ÁÎÎÎ…ÁÎÎÎÎ…ÙÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…Ùdisp œsam® vex© first item flipped.Ú…ÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛÚ…ÎÎÎÎÌÛ Û ÛÛ‡ one ÛÛ Û ÛÛÃÎÎÎÎ…ÝÛÚ…ÎÎÎÎÂÎÎÎÎÂÎÎÎÎÎÌÛÚ…ÎÎÂÎÎÎÎÂÎÎÎÎÎÌÛÛÛ two ÛÛÛalphaÛbetaÛgammaÛÛÛredÛblueÛgreenÛÛÛÃÎÎÎÎ…ÝÛÀÎÎÎÎ…ÁÎÎÎ…ÁÎÎÎÎ…ÙÛÀÎÎ…ÁÎÎÎ…ÁÎÎÎÎ…ÙÛÛÛthreeÛÛ Û ÛÛÀÎÎÎÎ…Ù‡ Û ÛÀÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…Ùdisp 2 œsam® vex© middle item flipped.Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ ÛÚ…ÎÎÎÎÌÛ ÛÛ Û‡alphaÛÛ ÛÛÚ…ÎÎÂÎÎÎÂÎÎÎÎÎÌÛÃÎÎÎÎ…ÝÛÚ…ÎÎÂÎÎÎÎÂÎÎÎÎÎÌÛÛÛoneÛtwoÛthreeÛÛÛbeta ÛÛÛredÛblueÛgreenÛÛÛÀÎÎ…ÁÎÎ…ÁÎÎÎÎ…ÙÛÃÎÎÎÎ…ÝÛÀÎÎ…ÁÎÎÎ…ÁÎÎÎÎ…ÙÛÛ ÛÛgammaÛÛ ÛÛ ÛÀÎÎÎÎ…Ù‡ ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…Ù78


disp 1 2 3 œsam®¨ vex © one vector of each item flipped.Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÌÛÛÚ…ÎÎÎÎÂÎÂÎÎÎÎÎÌÛÚ…ÎÎÂÎÎÎÎÂÎÌÛÛÚ…ÂÎÎÎÂÎÎÎÎÎÌÛÛ ÛbÛ ÛÛÛ Û ÛgÛÛÛÛoÛ Û ÛÛÛalphaÛeÛgammaÛÛÛ Û ÛrÛÛÛÛnÛtwoÛthreeÛÛÛ ÛtÛ ÛÛÛredÛblueÛeÛÛÛÛe‡ Û ÛÛÛ Ûa‡ ÛÛÛ Û ÛeÛÛÛÀ…ÁÎÎ…ÁÎÎÎÎ…ÙÛÀÎÎÎÎ…Á…ÁÎÎÎÎ…ÙÛÛ Û Ûn‡ÛÛ Û ÛÀÎÎ…ÁÎÎÎ…Á…ÙÛÀÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎ…Ùdisp 1 2 3 œsam{''}¨ vex © one vector of each item bracketed.Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛÚ…ÎÎÎÎÂÎÎÎÂÎÎÎÎÎÌÛÚ…ÎÎÎÎÂÎÎÎÎÎÎÂÎÎÎÎÎÌÛÚ…ÎÎÂÎÎÎÎÂÎÎÎÎÎÎÎÌÛÛÛÛtwoÛthreeÛÛÛalphaÛÛgammaÛÛÛredÛblueÛÛÛÛÀÎÎÎÎ…ÁÎÎ…ÁÎÎÎÎ…ÙÛÀÎÎÎÎ…ÁÎÎÎÎÎ…ÁÎÎÎÎ…ÙÛÀÎÎ…ÁÎÎÎ…ÁÎÎÎÎÎÎ…ÙÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…Ùdisp 1 0 1 /sam{›'---'} vexÚ…ÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÌÛ ÛÚ…ÎÎÎÎÂÎÎÎÎÂÎÎÎÎÎÌÛ ÛÛ---ÛÛalphaÛbetaÛgammaÛÛ---ÛÛ ÛÀÎÎÎÎ…ÁÎÎÎ…ÁÎÎÎÎ…ÙÛ ÛÀÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎ…Ù© outside items replaced.disp (›1 0 1) /sam{›'---'}¨ vex © outside vectors of each item replaced.Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛÚ…ÎÎÂÎÎÎÂÎÎÎÌÛÚ…ÎÎÂÎÎÎÎÂÎÎÎÌÛÚ…ÎÎÂÎÎÎÎÂÎÎÎÌÛÛÛ---ÛtwoÛ---ÛÛÛ---ÛbetaÛ---ÛÛÛ---ÛblueÛ---ÛÛÛÀÎÎ…ÁÎÎ…ÁÎÎ…ÙÛÀÎÎ…ÁÎÎÎ…ÁÎÎ…ÙÛÀÎÎ…ÁÎÎÎ…ÁÎÎ…ÙÛÀÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎ…Ùdisp 1 0 1 /sam{›'---'}¨ vex © each vector of outside items replaced.Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛÚ…ÎÎÂÎÎÎÂÎÎÎÌÛÚ…ÎÎÎÎÂÎÎÎÎÂÎÎÎÎÎÌÛÚ…ÎÎÂÎÎÎÂÎÎÎÌÛÛÛ---Û---Û---ÛÛÛalphaÛbetaÛgammaÛÛÛ---Û---Û---ÛÛÛÀÎÎ…ÁÎÎ…ÁÎÎ…ÙÛÀÎÎÎÎ…ÁÎÎÎ…ÁÎÎÎÎ…ÙÛÀÎÎ…ÁÎÎ…ÁÎÎ…ÙÛÀÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎ…Ùdisp †vexÚ…ÎÎÎÎÂÎÎÎÎÂÎÎÎÎÎ̇ one Ûtwo ÛthreeÛÃÎÎÎÎ…ÏÎÎÎ…ÏÎÎÎÎ…ÝÛalphaÛbetaÛgammaÛÃÎÎÎÎ…ÏÎÎÎ…ÏÎÎÎÎ…ÝÛ red ÛblueÛgreenÛÀÎÎÎÎ…ÁÎÎÎ…ÁÎÎÎÎ…Ùdisp 1 1 ³sam² †vexÚ…ÎÎÎÎÂÎÎÎÎÂÎÎÎÎÎ̇greenÛtwo ÛthreeÛÃÎÎÎÎ…ÏÎÎÎ…ÏÎÎÎÎ…ÝÛalphaÛbetaÛgammaÛÃÎÎÎÎ…ÏÎÎÎ…ÏÎÎÎÎ…ÝÛ red ÛblueÛ one ÛÀÎÎÎÎ…ÁÎÎÎ…ÁÎÎÎÎ…Ùdisp 1 1 ³sam(²¨) †vexÚ…ÎÎÎÎÂÎÎÎÎÂÎÎÎÎÎ̇ eno Ûtwo ÛthreeÛÃÎÎÎÎ…ÏÎÎÎ…ÏÎÎÎÎ…ÝÛalphaÛatebÛgammaÛÃÎÎÎÎ…ÏÎÎÎ…ÏÎÎÎÎ…ÝÛ red ÛblueÛneergÛÀÎÎÎÎ…ÁÎÎÎ…ÁÎÎÎÎ…Ù© matrix of vectors.© diagonal reversed.© each vector on diagonal reversed.79


disp 1 1 ³sam{ucase¨¾} †vex © diagonal vectors upper-cased.Ú…ÎÎÎÎÂÎÎÎÎÂÎÎÎÎÎ̇ ONE Ûtwo ÛthreeÛÃÎÎÎÎ…ÏÎÎÎ…ÏÎÎÎÎ…ÝÛalphaÛBETAÛgammaÛÃÎÎÎÎ…ÏÎÎÎ…ÏÎÎÎÎ…ÝÛ red ÛblueÛGREENÛÀÎÎÎÎ…ÁÎÎÎ…ÁÎÎÎÎ…Ùdisp †¨vexÚ…ÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÌÛone ÛalphaÛred ÛÛtwo Ûbeta Ûblue ÛÛthree‡gamma‡green‡ÀÎÎÎÎ…ÁÎÎÎÎ…ÁÎÎÎÎ…Ù© vector of matrices.disp (›1 1) ³sam{ucase ¾}¨ †¨vex © diagonals upper-cased.Ú…ÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÌÛOne ÛAlphaÛRed ÛÛtWo ÛbEta ÛbLue ÛÛthRee‡gaMma‡grEen‡ÀÎÎÎÎ…ÁÎÎÎÎ…ÁÎÎÎÎ…Ùdisp (›1 1) ³sam{'·'}¨ †¨vexÚ…ÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÌÛ·ne Û·lphaÛ·ed ÛÛt·o Ûb·ta Ûb·ue ÛÛth·ee‡ga·ma‡gr·en‡ÀÎÎÎÎ…ÁÎÎÎÎ…ÁÎÎÎÎ…Ù© diagonals zapped.See also: select.81 enss.39 each.543ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎsawrslt „ {left} (fun ##.saw) {right}© Apply function Simple-Array-Wise.The function operand is applied to or between each simple (depth 0 or 1) subarrayin the argument(s). [saw] is thought to have been published first by IBM'sEd Eusebi, who remarked that "It's good to have a saw in your toolbox".Technical notes:A monadic version of the operator tests the depth of its argument and appliesthe operand function if it is simple. Otherwise, it recursively applies thederived function '’' (function operand bound with operator), to each sub array.saw„{© Function operand applied Simple-Array-Wise.1‰|­¾:¸¸ ¾ © Simple: apply operand.’¨¾ © Nested: visit each subarray.}Phil Last suggested this (Œio- and Œml-independent) one-liner:saw„{œ«½€°’¨/(1‡1 0~­¾),€°¸¸/(1 0•­¾),›¾}A dyadic version, suggested by Paul Mansour, looks like this:saw„{© Function operand applied Simple-Array-Wise.2‰|­¸ ¾:¸ ¸¸ ¾ © Both simple: apply operand.1‰|­¾:’°¾¨¸ © ¾ simple: traverse ¸.1‰|­¸:¸°’¨¾ © ¸ simple: traverse ¾.¸ ’¨¾© Both nested: traverse both.}80


Dyadic [saw] is a close relative of the pervasion operator …perv„. See the technicalnotes in …perv„ for a generalisation that includes both.Finally, we can produce an ambi-valent version, by defaulting a missing leftargument to the identity function €.saw„{© Function operand applied Simple-Array-Wise.¸„€© default left arg.2‰|­¸ ¾ ¾:¸ ¸¸ ¾ © Both simple: apply operand.1‰|­¾:¸ ’¨›¾ © ¾ simple: traverse ¸.2‰|­¸ 1:¸°’¨¾ © ¸ simple: traverse ¾.¸ ’¨¾© Both nested: traverse both.}Example:disp¨eng espÚ…ÎÎÂÎÂÎÂÎÂÎÎÎÎÌ Ú…ÎÎÂÎÎÎÂÎÎÎÎÂÎÂÎÌÛOneÛ Û Û ÛFiveÛ ÛUnoÛDosÛTresÛ Û ÛÀÎÎ…Á´Á´Á´ÁÎÎÎ…Ù ÀÎÎ…ÁÎÎ…ÁÎÎÎ…Á´Á´Ùdisp ²saw eng espÚ…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛÚ…ÎÎÂÎÂÎÂÎÂÎÎÎÎÌÛÚ…ÎÎÂÎÎÎÂÎÎÎÎÂÎÂÎÌÛÛÛenOÛ Û Û ÛeviFÛÛÛonUÛsoDÛserTÛ Û ÛÛÛÀÎÎ…Á´Á´Á´ÁÎÎÎ…ÙÛÀÎÎ…ÁÎÎ…ÁÎÎÎ…Á´Á´ÙÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…Ùdisp eng {¸,'=',¾}saw espÚ…ÎÎÎÎÎÎÂÎÎÎÎÂÎÎÎÎÎÂÎÂÎÎÎÎÎÌÛOne=UnoÛ=DosÛ=TresÛ=ÛFive=ÛÀÎÎÎÎÎÎ…ÁÎÎÎ…ÁÎÎÎÎ…Á…ÁÎÎÎÎ…Ùfnb„{' '^.=¸:¾ ª ¸}sawdisp eng fnb espÚ…ÎÎÂÎÎÎÂÎÎÎÎÂÎÂÎÎÎÎÌÛOneÛDosÛTresÛ ÛFiveÛÀÎÎ…ÁÎÎ…ÁÎÎÎ…Á´ÁÎÎÎ…Ùdisp †fnb/ eng esp '¿?'Ú…ÎÎÂÎÎÎÂÎÎÎÎÂÎÎÂÎÎÎÎÌÛOneÛDosÛTresÛ¿?ÛFiveÛÀÎÎ…ÁÎÎ…ÁÎÎÎ…ÁÎ…ÁÎÎÎ…Ù© two nested vectors.© _monadic_ saw on depth-3 array.© _dyadic_ saw between depth-2 arrays.© Paul Mansour's [fnb] function.© eng replaces esp simple-array-wise.© eng replaces esp with default: '¿?'.See also: perv.70 rows.74ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎscan© Variations on primitive scan:nvec „ {axis} ##.mscan nvec © Minus scan.nvec „ {axis} ##.dscan nvec © Divide scan.vect „ (fn ##.ascan) vect © Associative vector scan.array „ {ascan} (fn ##.ascana) array© Associative higher rank scan.Provided by Phil Last and Nicolas Delcros, these operators out-perform theirprimitive counterparts by scanning cumulatively from left to right.The primitive scan operator is defined as a vector of reductions:¯¯¯¯¯¯¯¯¯¸¸\¾ … ¸¸/¨(1 to ½¾)†¨›¾81


For example:+\3 1 4 1 6… +/¨(1 to 5)†¨›3 1 4 1 6… +/¨(3)(3 1)(3 1 4)(3 1 4 1)(3 1 4 1 6)… (+/3)(+/3 1)(+/3 1 4)(+/3 1 4 1)(+/3 1 4 1 6)… 3 4 8 9 15Defn: An associative dyadic function f is one where: (A f B) f C „… A f (B f C).¯¯¯¯¯¯¯¯¯¯¯For associative operand <strong>functions</strong>, such as + and ×, the interpreter can "cheat"by accumulating the result in a single left-to-right pass of the vector argument,but for non-associative <strong>functions</strong>, it is obliged to do it the slow way usingreductions of increasingly longer sequences as above, resulting in an O(n×n)algorithm.Mscan and dscan provide linear O(n) <strong>functions</strong> to simulate -\ and ÷\ respectively.-\¼10001 ¯1 2 ¯2 3 ¯3 4 ¯4 5 ¯5 ...mscan ¼10001 ¯1 2 ¯2 3 ¯3 4 ¯4 5 ¯5 ...© slow primitive minus-scan.© quick minus-scan.÷\¼10001 0.5 1.5 0.375 1.875 0.3125 ...dscan ¼10001 0.5 1.5 0.375 1.875 0.3125 ...© slow primitive divide-scan.© quick divide-scan.In general, the interpreter can "cheat" only if it can determine that scan's operandfunction is associative. For example, even though dfn {¸+¾} is clearly associative,the interpreter cannot know this and so uses the slow O(n×n) method.In cases such as these, where it is known that the operand function is associative,ascan can be used to force a left-to-right cumulative O(n) scan.{¸+¾}\¼100001 3 6 10 15 21 28 36 45 55 ...{¸+¾}ascan¼10001 3 6 10 15 21 28 36 45 55 ...© slow primitive scan.© quick associative scan.Note that if the operand turns out to be non-associative, ascan will return aresult that differs from primitive scan.{¸-¾}\¼101 ¯1 2 ¯2 3 ¯3 4 ¯4 5 ¯5{¸-¾}ascan¼101 ¯1 ¯4 ¯8 ¯13 ¯19 ¯26 ¯34 ¯43 ¯53© slow primitive scan.© quick left to right accumulation.nums„ †('one' 'two' 'three')('un' 'deux' 'trois')('yan' 'tan' 'tethera')disp {¸,'-',¾} ascan numsÚ…ÎÎÂÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ̇oneÛone-twoÛ one-two-three ÛÃÎÎ…ÏÎÎÎÎÎÎ…ÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÝÛun Ûun-deuxÛ un-deux-trois ÛÃÎÎ…ÏÎÎÎÎÎÎ…ÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÝÛyanÛyan-tanÛyan-tan-tetheraÛÀÎÎ…ÁÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…Ù82© left-to-right scan along rows


See also: acc.10ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎselectrslt „ indx ##.select avec © ¸-selection of items from vector ¾.[indx] is an S-array (an array of shape S), each item of which is an index intothe vector of S-arrays [avec]. An item of avec may also be a single item array,in which case it is notionally S-reshaped.The resulting S-array is an item-wise selection of corresponding elements fromthe items of avec.Note that in origin-0, the left argument may be a boolean array to select itemsfrom a pair of false-true arrays on the right.Select may often be used as a pure, though expensive, alternative to partial assignments]„ and )„.(Bob Bernecky points us to Ken Iverson's "mask":"The MASK operation is defined formally as follows:c „ /a,u,b/ (~u)/c = (~u)/a, and u/c = u/b.The vectors c, a, u, and b are clearly of a common dimension andc[i]= a[i] or b[i], according as u[i] = 0 or u[i] = 1."Ref: Kenneth E. Iverson, "A Programming Language", p21, Wiley, 1962.)http://www.jsoftware.com/papers/<strong>APL</strong>.htmTechnical note:Note that in the coding for select:select„{ © ¸-selection of items of vector ¾.¸œ¨†,¨/›¨¨¾}¸ and ¾ appear just once at each end of the selection expression. This meansthat, if we bound adjacent _<strong>functions</strong>_ in the expression using compose operatorswe could express select as a single derived function. See …derive„select „ œ¨°†°(,¨/)°(›¨¨)select dft 1°ÚÎÎÎÎÎÁÎÎÎÎÎÌ° ¨ÚÎÎÎÁÎÎÎÌ ÚÎÙ° / ¨ÚÎÁÎÌ ÚÎÙ ÚÎÙ¨ † ¨ ›ÚÎÙ ÚÎÙœ ,© derived function for select.© show derived function tree.However, there is not much of a case for doing so. Although the resulting functionis arguably "cute", it runs no quicker and is harder to maintain.83


Examples:2 1 2 2 1 select (1 2 3 4 5)(10 20 30 40 50) © selection from vectors10 2 30 40 5mats„5 5°½¨Œa(lcase Œa)Œd© vector of matricesdisp matsÚ…ÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÌÛABCDEÛabcdeÛ01234ÛÛFGHIJÛfghijÛ56789ÛÛKLMNOÛklmnoÛ01234ÛÛPQRSTÛpqrstÛ56789ÛÛUVWXY‡uvwxy‡01234‡ÀÎÎÎÎ…ÁÎÎÎÎ…ÁÎÎÎÎ…ÙŒ„indx„5 5½¼31 2 3 1 23 1 2 3 12 3 1 2 31 2 3 1 23 1 2 3 1© selection matrix.Ab2De5Gh8Jk1Mn4Pq7St0Vw3Yindx select mats© selection from matrices.charsnow isthe time(Œio+chars=' ')select chars '.'now.is..the.time© character matrix.© dots for blanks.© This function swaps box-drawing characters for printer-friendly equivalents:clunk„{fm„'ÚÂÌÃÏÝÀÁÙÛÎ'to„'...|+|''''''|-'(fm¼¾)select to,›¾}disp ¼¨¼2 2Ú…ÎÎÎÎÂÎÎÎÎÎÎÎÎÎ̇څÎÎÌÛÚ…ÎÎÂÎÎÎÌÛÛ‡1 1ÛÛ‡1 1Û1 2ÛÛÛÀ~Î…Ù‡À~Î…Á~Î…Ù‡ÃÎÎÎÎ…ÏÎÎÎÎÎÎÎÎ…ÝÛÚ…ÎÎÌÛÚ…ÎÎÂÎÎÎÌÛÛ‡1 1ÛÛ‡1 1Û1 2ÛÛÛÃ~Î…ÝÛÃ~Î…Ï~Î…ÝÛÛÛ2 1ÛÛÛ2 1Û2 2ÛÛÛÀ~Î…Ù‡À~Î…Á~Î…Ù‡ÀÎÎÎÎ…ÁÎÎÎÎÎÎÎÎ…Ù© Printer friendly characters.© box drawing characters.© equivalent clunky chars.© printer-friendly substitution.© char mat with box-drawing characters84


clunk disp ¼¨¼2 2 © clunky equivalents..…----.---------.‡.…--.|.…--.---.||‡1 1||‡1 1|1 2|||'~-…'‡'~-…'~-…'‡|----…+--------…||.…--.|.…--.---.||‡1 1||‡1 1|1 2||||~-…|||~-…+~-…||||2 1|||2 1|2 2|||'~-…'‡'~-…'~-…'‡'----…'--------…'cubes„1 10 100×›2 3 4½¼24© vector of higher-rank arrays.disp cubesÚ…ÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ 1 2 3 4Û 10 20 30 40Û 100 200 300 400ÛÛ 5 6 7 8Û 50 60 70 80Û 500 600 700 800ÛÛ 9 10 11 12Û 90 100 110 120Û 900 1000 1100 1200ÛÛ Û Û ÛÛ13 14 15 16Û130 140 150 160Û1300 1400 1500 1600ÛÛ17 18 19 20Û170 180 190 200Û1700 1800 1900 2000ÛÛ21 22 23 24”210 220 230 240”2100 2200 2300 2400”À~ÎÎÎÎÎÎÎÎÎ…Á~ÎÎÎÎÎÎÎÎÎÎÎÎÎ…Á~ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÙŒ„indx„2 3 4½¼31 2 3 12 3 1 23 1 2 3© higher-rank index array.1 2 3 12 3 1 23 1 2 3indx select cubes1 20 300 450 600 7 80900 10 110 1200© selection of higher rank arrays.13 140 1500 16170 1800 19 2002100 22 230 2400See also: from.42 enss.39 dft.125 merge.61 derive.535ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎsubvecyes „ larg ##.subvec rarg © Is ¸ a subvector of ¾?Supplied by Michael Kassler, with suggestions from Dag Dittmer, this functionanswers the question:Is there a boolean vector bv, such that ¸­bv/¾ ?[rarg] is a vector and [larg] is a scalar or vector.85


Examples:1110110011'abba' subvec 'babba''abba' subvec 'abbas''abba' subvec 'ababa''abba' subvec 'baab'3 3 2 1 subvec 4 3 5 6 3 2 8 1 91 2 3 4 subvec 1 3 4 2 1 2 3 41 2 3 subvec 3 2 13 3 2 1 subvec 3 2 13 3 2 1 subvec 4 3 5 6 3 2 8 1 9'nested' 'too' subvec 'nested' 'arrays' 'work' 'too'See also: ss.177 subs.85ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎsquadrslt „ indices (axis ##.squad) array © IBM <strong>APL</strong>2 Indexing function.Supplied by Steve Mansour, this operator simulates IBM <strong>APL</strong>2's Indexing function:Ref: <strong>APL</strong>2 at a Glance, Appendix F: <strong>APL</strong>2 Release Functions - Indexing pp. 395-397Indices:A (possibly) nested vector, each item containing the indices of thecorresponding axis in the operand.Axis:A list of axes corresponding to the items of the left argument (indices)If the operand is the empty vector, all axes are included.Array: Any array whose rank is greater than 0.NB: <strong>Dyalog</strong> V11 implements squad indexing ¦ as a primitive function.Examples:ŒIO„1B„2 3 4½¼24(2 1)1(3 1)('' squad)B © Equivalent to B[2 1;1;3 1]15 133 1(1 1 1)(2 1 3)('' squad)¨›B1 15(›(2 1)1(3 1))('' squad)¨B(10×B)(100×B)15 13 150 130 1500 13003 1 30 10 300 100V„'ABCDEFGHI'86


3 ('' squad)V © Equilvalent to V[3]C(›3 4) ('' squad)V © Equivalent to V[3 4]CD(2 1)(3 1) (1 3 squad) B © Equivalent to B[2 1;;1 3]15 1319 1723 213 17 511 95BŒio ŒML„0 32 ('' squad) 3 4 51 (0 squad) 'ABCD'NAMES„œ'STEVE' 'PAUL' 'GEORGE'© Check origin 0 and ML>0.1(0 squad) NAMES © Equivalent to NAMES[1;]PAULSPGUEO0(1 squad) NAMES © Equivalent to NAMES[;0]1 2('' squad) NAMES © Equivalent to NAMES[1;2]2(1 2)(0 1 squad) NAMES © Equivalent to NAMES[2;1 2]See also: from.42 merge.61ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎsubsarray „ (from repl) ##.subs array© Vector substitution.The left argument is a 2-item vector of 'find' and 'replace' vectors or scalars.Occurrences of [from] along the last axis of the right argument are replacedwith [repl]. When [from] and [repl] are of differing lengths, shorter vectorsalong the last axis are padded on the right with prototypical items.Subs is an alternative to …ss„ and …ssmat„ with the following advantages:- The right argument may be of any rank.- It is a slightly quicker in many cases.- Having the substitution pair on the left allows:- Composition of a substition pair to form a new monadic function.- Multiple substitutions using the primitive reduce operator (/).- [from] and [repl] may be nested arrays.Note that regular expressions are not used; there are no special characters, so'*', '[]', etc. are taken literally. Notice also that in the case of overlappingstrings, both strings are identified and both are replaced.Examples:dots„' ·'°subs© Composition.dots 2 12½'Many a time and oft. ' © Single char substitution.Many·a·time·and·oft.····87


(6 7)(666 777)subs 2 3 4½¼12 © High rank argument.1 2 3 45 666 777 89 10 11 121 2 3 45 666 777 89 10 11 12(7 8 9) 'repl' subs 3 5½¼15 © Replace with longer string.1 2 3 4 5 06 r e p l 1011 12 13 14 15 0(7 8 9) 'r' subs 3 5½¼15 © Replace with shorter string.1 2 3 4 56 r 10 0 011 12 13 14 15© Multiple substitutions:†subs/('Mr' 'Mrs')('his' 'her')'Mr Green and his daughter, Theresa.'Mrs Green and her daughter, Theresa.(3,¨2 3 4)('peek' 'a' 'boo') subs ¼5 51 1 1 2 1 3 1 4 1 52 1 2 2 2 3 2 4 2 53 1 peek a boo 3 54 1 4 2 4 3 4 4 4 55 1 5 2 5 3 5 4 5 5© Nested substitution.(1 1)(2 3)subs 0 1 1 1 0 © Overlapping strings.0 2 3 2 3 0See also: ss.177 ssmat.178 select.81ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎtyperslt „ code ##.type array © Widen ¾ to type ¸.The width of each item in the (simple) array argument is set to code, where codeis a ŒDR specification such as 83, 163, ···. The result is pegged at this widthso it won't be demoted (squeezed) in the event of a workspace compaction. If anyitem in the array cannot assume the requested width, no value is returned.Technical note:In <strong>Dyalog</strong>, simple arrays of whole numbers may be represented internally using 1,8, 16 or 32 bits. When a compaction occurs, such arrays are squeezed to thenarrowest possible type. For example, the result of the expression 3 2-2 will beinitially of type 323 but may be demoted to type 11 during a compaction as allof its values are in the range 0 l.In additon to compaction, system function ŒSIZE squeezes its argument before reportingits size.If we are sure that all values fall within the required type, we can simplifythe function still further by removing the check:type„{ © Widen ¾ to type ¸.ŒIOœ(ŒDR ¾)¸ ŒDR ¾}88


Example:{²(Œdr ¾)(œ'…' Œwa)(Œdr ¾)} 1‡1e6,¼10 © Œwa squeezes type.323 … 83{²(Œdr ¾)(œ'…' Œwa)(Œdr ¾)}163 type 1‡1e6,¼10163 … 163© Type survives Œwa.ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎTreesÎÎÎÎÎTreesÎÎÎÎÎTree structures can be represented in <strong>APL</strong> in many ways. Two popular methods areto use array nesting, or "TreeView" style depth and leaf vectors. Functions…tview„ and …tnest„ swap between these two styles and …tfmt„ takes the nestedrepresentation and renders it as an indented character matrix suitable for displayin the session.We can represent a tree as a vector, where at each level, the first item is thetree node and subsequent items are sub-trees. Leaves are identified by havingdepth=1. For example, the following tree:drinkÚÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÌhotcoldÚÎÎÎÁÎÎÎÌÚÎÎÎÁÎÎÎÌtea coffee milk beer... might be represented thus:nested„'drink'('hot' 'tea' 'coffee')('cold' 'milk' 'beer')disp nestedÚ…ÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ ÛÚ…ÎÎÂÎÎÎÂÎÎÎÎÎÎÌÛÚ…ÎÎÎÂÎÎÎÎÂÎÎÎÎÌÛÛdrinkÛÛhotÛteaÛcoffeeÛÛÛcoldÛmilkÛbeerÛÛÛ ÛÀÎÎ…ÁÎÎ…ÁÎÎÎÎÎ…ÙÛÀÎÎÎ…ÁÎÎÎ…ÁÎÎÎ…ÙÛÀÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…Ù© Nested format.disp tview nested© TreeView format.Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛÛÚ…ÎÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÌÛÛ0 1 2 2 1 2 2ÛÛdrinkÛhotÛteaÛcoffeeÛcoldÛmilkÛbeerÛÛÛÛÀÎÎÎÎ…ÁÎÎ…ÁÎÎ…ÁÎÎÎÎÎ…ÁÎÎÎ…ÁÎÎÎ…ÁÎÎÎ…ÙÛÀ~ÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…Ùdisplay tfmt nestedÚ…ÎÎÎÎÎÎÎÎÎÎÎÎÎ̇drinkÛÛ· hot ÛÛ· · tea ÛÛ· · coffeeÛÛ· cold ÛÛ· · milk ÛÛ· · beer ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙ© Indented format.1nested ­ tnest tview nested© Full circleSee also: tnest.130 tview.137 tfmt.130 span.155 dft.125 BST.88 trav.13089


ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎBSTBinary Search Trees-------------------Binary search trees provide a way to store ordered information so that access isreasonably fast. An example of an application might be the storing of name=valuepairs in a symbol table.ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ Binary Search Trees have an elegant structure and are interesting ÛÛ to study. They are _almost_never_ the best way to store key=value ÛÛ pairs in <strong>APL</strong>. For a more practical <strong>APL</strong> alternative, see …alists„. ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙThese notes cannot do justice to the vast technical literature dealing with theproperties of binary trees, see below for some links.()NB: A previous coding of these operators used character vector tags as operands('put' 'rem' 'get' 'fmt' 'vec' 'chk') to distinguish the cases. Usingprimitive <strong>functions</strong> as operands is (arguably) more suggestive about what'sgoing on and reduces the need for parentheses to prevent the binding of theoperand with a left argument. Note that the operand function is interpretedonly as a label and is never applied as a function.Defn: A Binary Tree is either Null or is a Node, containing some information,together with a left and a right subtree.Tree ::= Null | Node info (Tree lft) (Tree rgt)Defn: A Binary Search Tree (BST) is a binary tree whose node information includesa search key. Each node in the tree has the property that its key is greaterthan any of those in its left subtree and less than any of those in its rightsubtree.In addition, the node typically carries a "value" associated with the key. Inother words, the nodes contain key=value pairs.B=2 key=val pairs stored in a BST/ \/ \ Note that for each key K,A=1 E=5 Lft subtree keys < K,/ \ Rgt subtree keys > K./ \D=4 F=6//C=3If we are interested only in the structure and beauty of BSTs, the value for anode may be of little interest. For this reason, operators …sbst„, …splay„,…avl„ and …redblack„ take either a key=value pair or just a scalar (character ornumeric) key. In the latter case, only the key is stored and is returned as valueby derived function [get]. This frees us to type simple expressions such as:0 put foldl ¼7 © tree with 1=1, 2=2, 3=3, ...90


Some terminology----------------This tree has a "height" of 4 (a null tree has height 0).B=2 This tree has a "size" of 6 (a null tree has size 0)./ \ B is the "root"./ \ Nodes A B and C are at "depth" 1 0 and 3, respectively.A=1 E=5 A is B's "left child"./ \ E is B's "right child"./ \ D is E's "inner" (parent-side) child.D=4 F=6 F is E's "outer" child./ E is D's (and F's) "parent"./ B is D's (and F's) "grandparent".C=3 A is D's (and F's) "uncle". *D is F's "sibling".D and F are A's (inner and outer) "nephews". *The size-2 tree D-C is E's left or inner "subtree".* Most treatments of trees appear to favour male relatives onthe parent's sibling's side. Of course, trees populated withaunts and nieces would work just as well :-)Nulls-----When drawing BSTs, although it uses a little more space, it is sometimes convenientto show nulls explicitly. Using '°' as null, the above example becomes:B=2/ \/ \/ \A=1 E=5 BST showing Nulls (°)/ \ / \° ° / \/ \D=4 F=6/ \ / \/ ° ° °/C=3/ \° °Rotation--------BSTs are transformed using left or right "rotation" of the edge that connects anode to one of its subtrees. Rotation is an elementary operation, which preservesthe search-order of nodes.By convention, this rotation of an edge is more usually termed a rotation of itsupper node (vertex). For example, in the following diagram, upper node A is saidto be rotated leftwards or counter-clockwise.Notice how the rising node's inner subtree (q) is reconnected as the fallingnode's inner subtree.Left Rotation of Node A (rotation of edge A-+-B):‡A B/ š \p B A-+-B A-+-B† A r/ \ => / „/ \ => / \ \ => / \q r p q r p q r p q91


Right Rotation of Node B (rotation of edge A-+-B):B‡ Aš \ š \A r A-+-B †A-+-B p B/ \ => / \… \ => / / \ => / \p q p q r p q r q rBalance-------Using rotation, we can see that a given set of search keys may be stored in anumber of different tree configurations. This number increases rapidly with thesize of the tree. Taking just 4 keys:A A A A A\ \ \ \ \B B C D D\ \ / \ / /C D B D B C\ / \ /D C C BB B C C/ \ / \ / \ / \ All possible BSTsA C A D A D B D for keys A B C D.\ / \ /D C B AD D D D D/ / / / /A A B C C\ \ / \ / /B C A C A B\ / \ /C B B AThe number of distinct ¾-node binary trees is the Catalan number, which can begenerated by:catalan „ {(¾!2×¾)÷¾+1}© ¾th Catalan number.catalan¨ 0 to 151 1 2 5 14 42 132 429 1430 4862 16796 58786 208012 742900 2674440 9694845or with this equivalent fork from <strong>Dyalog</strong> V14 onwards:catalan „ 1°+÷þ€!+þJay Foad suggests this coding of Segner's Recurrence Formula: Cn = C2×Cn-1 + C3×Cn-2 + ... + Cn-1×C2{¾,+/¾×²¾}ÿ9€11 1 2 5 14 42 132 429 1430 4862© first 10 Catalan numbersSee: http://mathworld.wolfram.com/CatalanNumber.htmlThe "height" of the tree is defined to be the number of edges in the path fromthe root to the furthest Null. In the diagrams above (which don't show nulls),the first and second trees have height 4 and the third, height 3.Common Operations=================Search, Insert/Replace and Remove operations, common to all of the BST operatorsare as follows.92


We can express the methods simply in a pseudo-code using "A ’ B … ..." as shorthandfor "{A B„¸ ¾ ª ...}" and "°" as shorthand for Null.In addition, ";", pronounced "where", introduces a definition, which is _local_to the first preceding line that contains fewer semicolons. This idea, datingfrom 1966 [ref 3], is known as "the off-side rule".Finally, '·' is used as a white-space character, to make it easier to keep trackof indentation levels.In the following example, notice how the commentary corresponds very closely tothe function tokens. This means that this "language" is sufficiently high-levelto render commentary at this level of detail superfluous, leaving the commentfield free for more abstract (higher-level) commentary.avg „ ’ vec …© "avg ia a function which maps vec to· tot ÷ num © tot divided by num,· ; tot „ sum/vec © where tot is the sum reduction of vec,· ; ; sum „ + © where sum is plus· ; num „ ½vec © and where num is the shape of vec."Search------We compare the sought key at each node, going left or right until we find it orreach a null, in which case, the key is not in the tree:T ’ K … © value associated with key K in tree T:· T ­ °: error! © null T: K not in tree => error.· (Key Val)(Lft Rgt) „ T © naming of parts of node.· K = Key: Val © match: value from this node.· K < Key: Lft ’ K © lower: value from left subtree,· K > Key: Rgt ’ K © higher: value from right subtree.Insertion-Replacement---------------------As with searching, we compare the key at each node, going left or right. If wefind the key, we replace an existing value. Otherwise, we reach a null and insertthe key=value pair as a new leaf of the tree.T ’ K V …© tree T with key(K)=value(V):· T ­ °: (K V)(° °) © null T: new leaf node.· (Key Val)(Lft Rgt) „ T © naming of parts of node.· K = Key: (K V)(Lft Rgt) © match: node with new value.· K < Key: (Key Val)(Lft‘ Rgt) © lower: put in left subtree, where· ; Lft‘ „ Lft ’ K V © Lft‘ is left subtree with K=V· K > Key: (Key Val)(Lft Rgt‘) © higher: put in right subtree, where· ; Rgt‘ „ Rgt ’ K V © Rgt‘ is right subtree with K=VRemoval-------Again, we search left or right for the key to be removed. If we reach a null,then the key wasn't in the tree and we have finished. Otherwise, if we find thenode and it has 0 or 1 non-null children, we replace it with it's child (ornull). Otherwise, if the node has two non-null children, we have two options:Option-s (simpler): Push the node to be removed deeper down the tree by repeatedrotation until it has only 1 or 0 children, then proceed as above. It would bebetter to rotate towards the nearest node with fewer than 2 children but, as thelocation of such a node is generally unknown, either direction will do. …sbst„and …splay„ use the simpler option.Option-q (quicker): Replace the (Key Val) pair of the node with the (Key Val)pair that sorts immediately after (or before) it. Then, remove this "successor"node, which must have at most 1 child. …avl„ and …redblack„ use the quicker option.93


T ’ K … © tree T without key K:· T ­ °: T © null T: key not in tree.· (Key Val)(Lft Rgt) „ T © naming parts of node.· K < Key: (Key Val)(Lft‘ Rgt) © lower: node with K ...· ; Lft‘ „ Lft ’ K © ... removed from left subtree.· K > Key: (Key Val)(Lft Rgt‘) © higher: node with K ...· ; Rgt‘ „ Rgt ’ K © ... removed from right subtree.· Rgt ­ °: Lft © match: null right: left· Lft ­ °: Rgt © match: null left: right.© then either the simpler but slower option-s:· (KeyValA (LftA ((Key Val)(RgtA Rgt))) ’ K © rgt-rotated Lft without K.· ; KeyValA (LftA RgtA) „ Lft © naming parts of K's Lft.© ÚÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎΩ Û [K] ~ K … A ~ K … A Û© Û / \ Û / \ Û / \ Û© Û A B Û p [K] Û p [K] ~ K … ...© Û / \ Û / \ Û / \ Û© Û p q Û q B Û q B Û© ÀÎÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎΩ or the quicker but more complex option-q:· (KeyS ValS) „ Left Rgt © successor key=value pair.· ; Left „ ’ KeyVal(Lft Rgt) … © leftmost key=value pair.· · · Lft ­ °: KeyVal © left child null: successor.· · · Lft » °: ’ Lft © otherwise: left of left subtree.· (KeyS ValS)(Lft Rgt‘) © successor key and value.· ; Rgt‘ „ Rgt ’ KeyS © right sub with successor removed.© ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌ© Û [K] ~ K Û [S] Û© Û / \ Û / \ Û© Û p A … p A ~ S Û© Û / \ Û / \ Û© Û ... t Û ... t Û© Û / Û / Û© Û q Û q Û© Û / \ Û / \ Û© Û [S] s Û [S] s Û© Û \ Û \ Û© Û r Û r Û© ÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙFor no particular reason, other than to explore both methods, operators …sbst„and …splay„ use option-s, whereas operators …avl„ and …redblack„ use option-q.Technical notes---------------Operators: …sbst„, …splay„, …avl„ and …redblack„ are used to derive access<strong>functions</strong> for their particular type of BST, depending on the operator's leftoperand:ž op © tree ¸ with key=val ¾.~ op © tree ¸ without key ¾.– op © value for key ¸ from tree ¾.• op © format of tree ¾.¹ op © enlist of tree ¾.? op © stats for tree ¾: ok size mean_depth height.­ op © depth of key ¾ in tree ¸ (only for …splay„).= op © balance of tree ¾ (only for …sbst„).94


Type----To help illuminate the code, closing braces of inner sub<strong>functions</strong> in each of theoperators show their "type", using the following notation::: "is of type"’ function place marker’’ operator place marker… returns- ~ # primitive types for char, numb, ref, à la …display„‚ ¸ ¾ type variables[‚] vector of type ‚[‚;] matrix of type ‚, etct treek keyv valuei subtree height increment: ¯1 0 1b node balance moment: ¯1 0 1r direction of rotation: ¯1 1e which edge (left right): ¯1 1d depth from root.h height of (sub)tree.s size of (sub)tree (number of nodes).a arbitrary accumulated value.y boolean value no/yes … 0/1.For example, the type of avl's inner function [search] shows:search :: t (t ’ k v … t i) ’’ k v … t imay be read as follows:search :: t (t ’ k v … t i) ’’ k v … t i © search is an operator¯¯¯¯¯¯¯¯search :: t (t ’ k v … t i) ’’ k v … t i © that takes an operand¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯search :: t (t ’ k v … t i) ’’ k v … t i © which is a function¯search :: t (t ’ k v … t i) ’’ k v … t i © that returns a tree-incr¯¯¯¯¯search :: t (t ’ k v … t i) ’’ k v … t i © from a tree and a key=val¯ ¯¯¯search :: t (t ’ k v … t i) ’’ k v … t i © and derives a function¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯search :: t (t ’ k v … t i) ’’ k v … t i © that returns a tree-incr¯¯¯¯¯search :: t (t ’ k v … t i) ’’ k v … t i © from a tree and a key=val.¯¯¯¯Using this notation, types of <strong>functions</strong> derivable from the operators are:put „ ž avl :: t ’ k v … t © tree ¸ with key=value pair ¾.get „ – avl :: k ’ t … v © value for key ¸ in tree ¾.rem „ ~ avl :: t ’ k … t © tree ¸ without key.fmt „ • avl :: ’ t … [-;] © char matrix format of tree ¾.chk „ ? avl :: ’ t … y s d h © statistics for tree ¾.vec „ ¹ avl :: ’ t … [k v] © key=value vector from tree ¾.95


Which is best?--------------·redblack ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌavl ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌ Ûsplay ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌ Û Ûsbst ÎÎÎÎÎÎÎÎÎÎÎÎÌ Û Û ÛÛ Û Û ÛBST SPL AVL R-BÚÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÌOrdered puts Û 1 Û 1 Û 4 Û 4 Û 0 N/AÃÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝ 1 PoorRandom puts Û 3 Û 3 Û 5 Û 5 Û 2 So-soÃÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝ 3 GoodAdaptive gets Û 0 Û 5 Û 0 Û 0 Û 4 Very GoodÃÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝ 5 ExcellentSimple code Û 4 Û 3 Û 2 Û 2 ÛÃÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝKey removal Û 1 Û 1 Û 4 Û 4 ÛÀÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÙva „ ¼1023vb „ “²³(10/2)‚¼1023© ascending sequence of keys (worst case).© binary-alternating order keys (best case).puts „ žavl foldl © insert keys ¾ into tree ¸.ta „ 0 puts vatb „ 0 puts vb© tree from ascending inserts.© tree from binary-alternating inserts.rems „ ~avl foldl © remove keys ¾ from tree ¸.96


ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÌÛ timeÛ Û Û Û ÛÛrotations Û sbstÛ splayÛ avlÛ redblackÛÃÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÝÛ 0 puts vaÛ 1970Û 2129Û 63Û 93ÛÛ Û Û Û1013 Û1005 ÛÃÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÝÛ 0 puts vbÛ 29Û 32Û 34Û 41ÛÛ Û Û Û0 Û0 ÛÃÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÝÛ ta rems vaÛ 3Û 3Û 31Û 47ÛÛ Û Û Û502 Û503 ÛÃÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÝÛ ta rems vbÛ 929Û 946Û 35Û 47ÛÛ Û Û Û0 Û8 ÛÃÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÝÛ ta rems²vaÛ 1947Û 1982Û 30Û 49ÛÛ Û Û Û502 Û494 ÛÃÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÝÛ tb rems vaÛ 18Û 17Û 31Û 37ÛÛ Û Û Û502 Û502 ÛÃÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÝÛ tb rems vbÛ 26Û 26Û 36Û 39ÛÛ Û Û Û0 Û0 ÛÃÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÝÛ tb rems²vaÛ 18Û 17Û 30Û 36ÛÛ Û Û Û502 Û502 ÛÃÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÝÛ 2‡chk vaÛ 511 1023Û 511 1023Û 8 10Û 9 18Û *ÃÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÝÛ 2‡chk vbÛ 8 10Û 8 10Û 8 10Û 9 10ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÙ* Worst-case red-black trees are deeper than worst-case AVLtrees but mean nodes depths, which indicate access times,are not too different.Key insertion and removal timings used operator …time„ with the following sequence.For example, the avl timing tests looked like this:ÚavlÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ puts „ ž avl foldl ÛÛ ta „ 0 puts time va ÛÛ00.63 ÛÛ tb „ 0 puts time vb ÛÛ00.34 ÛÛ rems „ ~ avl foldl ÛÛ ta rems time va ÛÛ00.31 ÛÛ ta rems time vb ÛÛ00.35 ÛÛ ta rems time ²va ÛÛ00.30 ÛÛ tb rems time va ÛÛ00.31 ÛÛ tb rems time vb ÛÛ00.36 ÛÛ tb rems time ²va ÛÛ00.30 ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙRotations were counted by injecting a line r+„1 at the start of each inner [rot]subfunction:97


ot„{ © single ¾-rotation of tree ¸.r+„1 © count rotations....and then, for example:502r„0 ª {}tb rems va ª r © number of removal rotations.References:[1] http://en.wikipedia.org/wiki/Binary_Search_Tree[2] Knuth: Computer Musings: The Associative Law, or The Anatomy of Rotations inBinary Trees (video). Stanford University Distinguished Lecture Series VII.University Video Communications (415) 813-0506.[3] P.J.Landin The Next 700 Programming Languages. CACM 9(3):157•65, March 1966.See also: sbst.105 splay.120 avl.96 redblack.110 alists.8 display.35 time.515ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎavlrslt „ {larg)(op ##.avl) rarg© Adelson-Velskii, Landis (AVL) trees.T‘ „ T ž avl (key val) © tree ¸ with key=val ¾.T‘ „ T ~ avl key © tree ¸ without key ¾.T‘ „ T – avl key © value for key ¾ in tree ¸.fmt „ • avl T © format of tree ¾.vec „ ¹ avl T © enlist of tree ¾.chk „ ? avl T © stats for tree ¾: ok size mean_depth height.See …BST„An AVL tree is a binary search tree in which subtree heights differ by no morethan 1.AVL trees do not guarantee minimal height. In the following diagram, the nodesare marked with their height (maximum distance to a leaf). For example, B‡2signifies a node with search key 'B' and height 2. Notice that sibling subtreesdiffer in height by at most 1:Height 4 AVL treeShallower reordering (also an AVL tree)E‡4 D‡3/ \ / \/ \ / \C‡3 F‡2 B‡2 F‡2/ \ \ / \ / \B‡2 D‡1 G‡1 A‡1 C‡1 E‡1 G‡1/A‡1If we remove node G‡1 from the diagram above left, the resulting tree is said to"overbalance" as F‡1 differs in height by 2 from its sibling C‡3:98E‡4/ \/ \C‡3 F‡1 overbalanced: C‡3 >> F‡1/ \B‡2 D‡1/A‡1


We can maintain the tree without keeping explicit track of the height of eachnode's subtrees. Instead, we record only the _difference_ in the heights of itssubtrees.By keeping only the difference in subtree heights, addition and removal of nodesrequires adjustment to only local regions of the tree.Further, in a correctly balanced AVL tree, this difference must be one of ¯1 0 1which means that only two bits per node are required to store balancing information.()We could reduce this to just one bit per node by devolving each node's balancebits to its left and right subtree. This works because leaf nodes, withonly null subtrees, are (clearly) balanced and so need no balance bits. Wecan see this scheme in operation by looking at the output from •avl, wherethe balance bits are represented by arrows supporting the subtrees.< left subtree higher · · ¯1subtrees of equal height· 0> right subtree higher · 1


Balancing---------During insertion or deletion, nodes may overbalance and need to be corrected byrotation. In the following examples node A overbalances to the left , the mirror-image transformations would be used.To avoid coding separate mirror-image rotation <strong>functions</strong>, the implementationparameterises the direction of rotation, see Technical notes below.Depending on case, rebalancing decreases or leaves the height of the node as awhole unaltered. A decrease in height may cause the node's parent to become unbalancedand so itself to require rebalancing, and so on.On deletion of a node, a worst-case of —2µ¾ rotations may be needed to preservethe tree's balance; on insertion of a new node, at most a single rotation is required.To simplify the following diagrams, a little additional notation is used:


For example, inserting a new leaf imparts a height increment of 1 to itssupporting edge. If this edge is a right edge (say), it imparts a balancingmoment of 1 to its parent node. If this node is already balanced (0), then itsbalance would be changed to 1 and it in turn would pass a height increment of 1to its supporting edge, and so on.Height Increments-----------------Case analysis yields a simple rule for determining the height increment of anode following insertion or deletion in one of its subtrees. In the followingdiagrams, without loss of generality, we can assume that the height increment(or decrement) is transmitted by the tree's right subtree:Insertion, 3 cases:ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ | |= Û | |+ Û | |= ÛÛ Û => A> Û A> => ÛÛ / + / \ Û + \ Û \ / \ ÛÛ Û Û b A ÛÛ Û INCR Û + ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙleading to the rule:ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ A height is transmitted iff the node was balanced. ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙDeletion, 9 cases:ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ | |- Û | |= Û | |- ÛÛ Û => A> Û A> => ÛÛ / / \ Û / \ / \ Û / \ / \ ÛÛ B A Û B> c B> c Û B> c B> c ÛÛ \ Û \ š \ Û \ \ \ \ ÛÛ c Û Û d d ÛÛ DECR Û Û š DECR ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙleading to the rule:ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ A height is transmitted iff the node is balanced. ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙ101


Operations on AVL trees-----------------------[avl] uses the standard …BST„ methods for search, insertion, and node removal.In the case of insertion a single rotation, and in the case of removal, severalrotations, may be necessary to maintain the tree's balance.Statistics----------An invocation of [avl] with a left operand of ? reports a 4-vector of statistics(ok size depth height) for its tree right argument, where:ok: boolean -> balance = difference in subtree heights, for all nodes.size: number of (non-null) nodes.depth: mean distance from the root of all nodes.height: maximum distance from root to each leaf; a null tree has height 0.Technical notes---------------These AVL <strong>functions</strong> are implemented using a recursive triple, with 0 standingfor the null tree:where:(key val) bal (lft rgt)key : numeric scalar or character vectorval : any array valuebal : balance ¯1 0 1lft : left subtree or 0rgt : right subtree or 0The AVL tree <strong>functions</strong>: insert/replace, delete, search, ... are derived from thesingle operator [avl] by binding an appropriate left operand. This is so thatcommon auxiliary <strong>functions</strong> such as balancing and rotation, which have little useoutside the context of AVL trees, may be hidden within the capsule (encapsulated).It is conceivable that an implementation of D: could retain a partial evaluationof such bindings to speed up subsequent application of the derived <strong>functions</strong>.Parameterising direction:In order to avoid having to code mirror-image sub<strong>functions</strong> for left/right traversaland left/right rotation, the direction is parameterised using subfunction:wise„{(¸=1)²¾}© subtrees ¾ in -¸, +¸ order.5 44 51 wise 4 5¯1 wise 4 5Similarly, a complete tree may be presented in either +1 or -1 orientation:proj„{(¸=0 0 ¯1)²¨¾} © ¸-projection of node ¾.1 proj 2 3(4 5)2 3 4 5¯1 proj 2 3(4 5)2 3 5 4102


(muse:In general, parameterisation saves duplication at the expense of abstraction.In other words, it produces more concentrated code, which is smallerbut harder to understand.)Formatting----------Derived function •avl transposes the tree and pushes the balance indicators outto either end of the subtree branches. Unlike the diagrams above, sibling subtreesof differing height are _each_ preceded by a '>' or '


© NB: In the following examples, the _values_ are numeric: 1 2 3 ...© but the _keys_ are alphabetic: 'one' 'two' 'three' ...© this means that 'one' precedes 'two' but that 'four' follows 'five'.tt „ tt žavl 'three' 3© insert third node.disp ttÚ…ÎÎÎÎÎÎÎÎÂÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛÛ ÛÚ…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛÛÛ ÛÛÚ…ÎÎÎÎÎÎÂÎÂÎÎÎÌÛÚ…ÎÎÎÎÎÎÂÎÂÎÎÎÌÛÛÛÚ…ÎÎÎÎÂÎÌÛ ÛÛÛÚ…ÎÎÂÎÌÛ Û ÛÛÛÚ…ÎÎÂÎÌÛ Û ÛÛÛÛÛthreeÛ3ÛÛ0ÛÛÛÛoneÛ1ÛÛ0Û0 0ÛÛÛÛtwoÛ2ÛÛ0Û0 0ÛÛÛÛÀÎÎÎÎ…ÁÎÙÛ ÛÛÛÀÎÎ…ÁÎÙÛ Û ÛÛÛÀÎÎ…ÁÎÙÛ Û ÛÛÛÛÛ ÛÛÀÎÎÎÎÎÎ…ÁÎÁ~Î…ÙÛÀÎÎÎÎÎÎ…ÁÎÁ~Î…ÙÛÛÛÛ ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÙÛÀÎÎÎÎÎÎÎÎ…ÁÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…Ù•avl ttÚÎone=1© format of tree.three=3ÝÀÎtwo=2tt „ tt žavl foldl ('four' 4) ('five' 5) ('six' 6) ('seven' 7)•avl ttÚ>five=5Úseven=7Ú>six=6ÙÀ>three=3ÝÀfive=5Úseven=7Ú>six=666ÙÀ>three=3ÝÀtwo=20tt ~avl foldl œ¨¹avl tt© tree with all keys removed.104


© Notice how insertion may require local rotation to maintain balance:display ® •avl°(0°(žavl foldl))¨,\6†ŒaÚ…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ̇ Ú…ÎÎÌ ÛÛ ‡A=AÛÛÛ ÀÎÎÎÙÛÛ Ú…ÎÎÎÎÎÎÎÌ ÛÛ ‡A=AÌ Û ÛÛ Û À>B=BÛ ÛÛ ÀÎÎÎÎÎÎÎÎÙ ÛÛ Ú…ÎÎÎÎÎÎÎÌ ÛÛ ‡ ÚÎA=AÛ ÛÛ ÛB=BÝ Û ÛÛ Û ÀÎC=CÛ ÛÛ ÀÎÎÎÎÎÎÎÎÙ ÛÛ Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÌ ÛÛ ‡ ÚC=CÌ Û ÛÛ Û À>D=DÛ ÛÛ ÀÎÎÎÎÎÎÎÎÎÎÎÎÎÙ ÛÛ Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÌ ÛÛ ‡ ÚD=DÝ Û ÛÛ Û ÀÎE=EÛ ÛÛ ÀÎÎÎÎÎÎÎÎÎÎÎÎÎÙ ÛÛ Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÌ ÛÛ ‡ ÚÎA=AÛ ÛÛ Û ÚÎB=BÝ Û ÛÛ Û Û ÀÎC=CÛ ÛÛ ÛD=DÝÛ ÛÛ Û ÀÎE=EÌ Û ÛÛ Û À>F=FÛ ÛÛ ÀÎÎÎÎÎÎÎÎÎÎÎÎÎÙ ÛÀ¹ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙ© insert A B .. F© Removal may also need rotation to maintain balance:A_F„0 žavl foldl 'ABCDEF'© tree A B .. F105


display ® •avl¨ A_F°(~avl foldl)¨,\' ABCDEF' © remove A B .. FÚ…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ̇ Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÌ ÛÛ ‡ ÚÎA=AÛ ÛÛ Û ÚÎB=BÝ Û ÛÛ Û Û ÀÎC=CÛ ÛÛ ÛD=DÝÛ ÛÛ Û ÀÎE=EÌ Û ÛÛ Û À>F=FÛ ÛÛ ÀÎÎÎÎÎÎÎÎÎÎÎÎÎÙ ÛÛ Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÌ ÛÛ ‡ ÚÎB=BÌ Û ÛÛ Û Û À>C=CÛ ÛÛ ÛD=DÝÛ ÛÛ Û ÀÎE=EÌ Û ÛÛ Û À>F=FÛ ÛÛ ÀÎÎÎÎÎÎÎÎÎÎÎÎÎÙ ÛÛ Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÌ ÛÛ ‡ ÚE=EÌ Û ÛÛ Û À>F=FÛ ÛÛ ÀÎÎÎÎÎÎÎÎÎÎÎÎÎÙ ÛÛ Ú…ÎÎÎÎÎÎÎÌ ÛÛ ‡ ÚÎD=DÛ ÛÛ ÛE=EÝ Û ÛÛ Û ÀÎF=FÛ ÛÛ ÀÎÎÎÎÎÎÎÎÙ ÛÛ Ú…ÎÎÎÎÎÎÎÌ ÛÛ ‡E=EÌ Û ÛÛ Û À>F=FÛ ÛÛ ÀÎÎÎÎÎÎÎÎÙ ÛÛ Ú…ÎÎÌÛÛ ‡F=FÛÛÛ ÀÎÎÎÙÛÛ Ú´ÌÛÛ ² ÛÛÛ ÀÎÙÛÀ¹ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙ106


© repeated removal of root node:display ® •avl¨ A_F°(~avl foldl)¨,\' DEBCFA'Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ̇ Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÌ ÛÛ ‡ ÚÎA=AÛ ÛÛ Û ÚÎB=BÝ Û ÛÛ Û Û ÀÎC=CÛ ÛÛ ÛD=DÝÛ ÛÛ Û ÀÎE=EÌ Û ÛÛ Û À>F=FÛ ÛÛ ÀÎÎÎÎÎÎÎÎÎÎÎÎÎÙ ÛÛ Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÌ ÛÛ ‡ ÚÎA=AÛ ÛÛ Û Ú>B=BÝ Û ÛÛ Û Û ÀÎC=CÛ ÛÛ ÛE=EÝÛ ÛÛ Û ÀF=FÙ Û ÛÛ ÀÎÎÎÎÎÎÎÎÎÎÎÎÎÙ ÛÛ Ú…ÎÎÎÎÎÎÎÌ ÛÛ ‡ ÚÎA=AÛ ÛÛ ÛC=CÝ Û ÛÛ Û ÀÎF=FÛ ÛÛ ÀÎÎÎÎÎÎÎÎÙ ÛÛ Ú…ÎÎÎÎÎÎÎÌ ÛÛ ‡ Ú>A=AÛ ÛÛ ÛF=FÙ Û ÛÛ ÀÎÎÎÎÎÎÎÎÙ ÛÛ Ú…ÎÎÌÛÛ ‡A=AÛÛÛ ÀÎÎÎÙÛÛ Ú´ÌÛÛ ² ÛÛÛ ÀÎÙÛÀ¹ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙSee also: BST.88 alists.8 sbst.105 splay.120 redblack.110 foldl.45 fibonacci.279ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎsbstrslt „ {larg} (op ##.sbst) rarg© Simple Binary Search Trees.T‘ „ T ž sbst (key val) © tree ¸ with key=val ¾.T‘ „ T ~ sbst key © tree ¸ without key ¾.T‘ „ T – sbst key © value for key ¾ in tree ¸.T‘ „ = sbst T © balanced tree.fmt „ • sbst T © format of tree ¾.vec „ ¹ sbst T © enlist of tree ¾.chk „ ? sbst T © stats for tree ¾: ok size mean_depth height.See …BST„[sbst] implements the simplest form of binary search tree (BST) with no attemptto keep the tree balanced. This means that it performs well only if the keys areinserted in random order or the tree is periodically rebalanced.107


Technical notes:In contrast with the other BST operators, [sbst] includes a balancing function=sbst, which uses the DSW algorithm [0] and works as follows.First, the tree is stripped into a degenerate left list, or "vine". A vine maybe pictured as a stem supporting (initially depth-0) leaves, each of which is acomplete tree. Starting at the (leftmost) leaf and working back up the vine,alternate sections are "compressed" by rotation, merging adjacent n-leaves into(n+1)-leaves. The process is repeated until, after —2µ¾ iterations the vine is abalanced tree.left vine of 0-leaves···/OšN/Mš „ alternate š edges are rotated.L/KšJ/ 1-leaves … 2-leaves … 3-leaves … ...I ··· ··· ···š / / /H N L H/ š \ š \ / \G L O š \ / \š / \ š \ / \F J M H N / \/ š \ / \ / \ / \E H K / \ M 0 / \š / \ / \ / \D F I D J D L/ š \ / \ / \ / \ / \C D G / \ I K / \ / \š / \ / \ / \ / \B B E B F B F J N/ / \ / \ / \ / \ / \ / \ / \A A C A C E G A C E G I K M OIf the vine starts with exactly ¯1+2*¾ nodes, for some ¾, the result is aperfectly balanced tree. Otherwise, a pre-pass is required to reduce the lengthby folding those adjacent 0-leaves over and above ¯1+2*¾ to form 1-leaves. Thisproduces a vine with exactly ¯1+2*¾ (0 or 1)-leaves, which becomes a tree thatis perfectly balanced except for extra nodes located at an incomplete deepestlevel. For example, a 10-node vine is reduced to a 7-node vine with 3 rotations:108


J „ vine with (3 + ¯1+2*3) 0-leaves.šI … I „ vine with ¯1+2*3 (0 1)-leaves./ š \H G J … G „ compression to (1 2)-leaves.š / \ / \G E H š \/ š \ / \F D F D I … D „ complete treeš / / \ / \ / \ with 3 extraE C B E H J / \ nodes F H J/ š / \ \ / \ at deepestD B A C F / \ level./ / / \C A / \/ / \B B G/ / \ / \A / \ / \/ \ / \A C E I\ / \F H JA left-hanging vine, which uses right rotation, is chosen because [sbst] has ahard-coded right rotation subfunction [rrot], used during node removal.B … Arrot„{ © right rotation. / \ / \B((A(p q))r)„¾ © unpack nodes. A r p BA(p(B(q r))) © repack nodes. / \ / \} © :: t „ ’ t p q q rClearly, right vines and left rotations would work just as well. Here is the DSWcode. Notice how the size of the tree is discovered by the enlisting function.bal„{© dsw-balancing.vine size„0 0 list ¾ © vine of 0-leaves and size.log„˜2µsize+1 © largest complete tree ˆ ¾.rem„1+size-2*log© no of surplus nodes.cmps„¯2+2*1+¼log© compression vector.†cmp/(1‡cmps,2×rem),›vine © compression reduction … balanced tree.} © :: t „ ’ tcmp„{© compress of alternate vine sections.¸=0:¾© far enough: terminal leaf.inf(lft rgt)„¾© parts of node.lev„(¸-1)’ lft© leftmost vine leaf.2|¸:inf(lev rgt)© copying of alternate vine sections.rrot inf(lev rgt)© rotation of alternate vine sections.} © :: t „ n ’ vlist„{ © list (0-vine) from tree ¾. /0­¾:¸ © null: accumulated vine. / Cinf(lft rgt)„¾ © node info & subtrees. B … /lev s„¸ ’ lft © left vine & size, / \ B(inf(lev 0))(s+1)’ rgt © ++ right vine. A C /} © :: v s „ v ’ t AAn alternative "brute force" method of rebalancing would be to take the vectorof key=value pairs returned by ¹sbst and re-insert them sequentially into a nulltree in an order that guarantees a good balance.109


al„{ © rebalance of tree ¾.pairs„¹sbst ¾© vector of key=value pairs.order„{“²³((—2µ¾)/2)‚¼¾}½pairs © binary insert order.œ{œ¾ žsbst ¸}/pairs[order],0 © new balanced tree.} © :: t „ ’ tHowever, this method performs poorly compared with DSW, as it uses O(2°µ) comparisonsfor each of ¾ insertions:tt „ 0 žsbst foldl 1000?1000© 1,000-node tree.cmpx'bal tt' 'bal2 tt'© compare with DSW.bal tt 2.2E¯1 0% ŒŒŒŒŒbal2 tt 1.8E0 +715% ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒReferences:[0] 'DSW' stands for Day-Stout-Warren:[1] Day A.C., Balancing a binary tree, Computer Journal 19.4, Nov 1976, 360-361.[2] Stout Q.F. Warren B.L., Tree Rebalancing in Optimal Time and Space,Comms ACM 29.9, Sept 1986, 902-908.Examples:•sbst 0 žsbst foldl¼7© no balancing if keys inserted in order.1=1ÌÀ2=2ÌÀ3=3ÌÀ4=4ÌÀ5=5ÌÀ6=6ÌÀ7=7•sbst =sbst 0 žsbst foldl¼7Ú1=1Ú2=2ÝÛ À3=34=4ÝÛ Ú5=5© explicit rebalancing.À6=6ÝÀ7=7© vector of key=value pairs:pairs „ ('one'1) ('two'2) ('three'3) ('four'4) ('five'5) ('six'6) ('seven'7)tt„0 žsbst foldl pairs•sbst ttÚfive=5Úfour=4Ù© pairs folded into tree.© format of tree.one=1ÝÛÚseven=7ÛÚsix=6ÙÛ Úthree=3ÙÀtwo=2Ùtt „ =sbst tt© balanced tree.110


•sbst ttÚfive=5Úfour=4ÝÛ Àone=1seven=7ÝÛÚsix=6Àthree=3ÝÀtwo=26'six'–sbst tttt „ tt ~sbst'four'© value for key 'six'© key 'four' removed.•sbst ttÚfive=5Úone=1Ùseven=7ÝÛÚsix=6Àthree=3ÝÀtwo=2disp ¹sbst tt© vector of key=value pairs.Ú…ÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÌÛÚ…ÎÎÎÂÎÌÛÚ…ÎÎÂÎÌÛÚ…ÎÎÎÎÂÎÌÛÚ…ÎÎÂÎÌÛÚ…ÎÎÎÎÂÎÌÛÚ…ÎÎÂÎÌÛÛÛfiveÛ5ÛÛÛoneÛ1ÛÛÛsevenÛ7ÛÛÛsixÛ6ÛÛÛthreeÛ3ÛÛÛtwoÛ2ÛÛÛÀÎÎÎ…ÁÎÙÛÀÎÎ…ÁÎÙÛÀÎÎÎÎ…ÁÎÙÛÀÎÎ…ÁÎÙÛÀÎÎÎÎ…ÁÎÙÛÀÎÎ…ÁÎÙÛÀÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎ…Ù?sbst tt1 6 2 3•sbst =sbst 0 žsbst foldl ŒaÚA=AÚB=BÝÛ ÀC=CÚD=DÝÛ Û ÚE=EÌÛ Û Û ÀF=FÛ ÀG=GÝÛ Û ÚH=HÛ ÀI=IÝÛÀJ=J© tree stats: ok size mean_depth height.© balance of (11+¯1+2*4)-node tree.K=KÝÛÚL=LÛ ÚM=MÝÛ Û ÀN=NÛ ÚO=OÝÛ Û Û ÚP=PÛ Û ÀQ=QÝÛ Û ÀR=RÀS=SÝÛ ÚT=TÛ ÚU=UÝÛ Û ÀV=VÀW=WÝÛ ÚX=XÀY=YÝÀZ=Z?sbst tt1 6 2 3© tree stats: ok size mean_depth height.See also: BST.88 alists.8 avl.96 splay.120 redblack.110111


ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎredblackrslt „ {larg) (op ##.redblack) rarg© Red-black trees.T‘ „ T ž avl (key val) © tree ¸ with key=val ¾.T‘ „ T ~ avl key © tree ¸ without key ¾.T‘ „ T – avl key © value for key ¾ in tree ¸.fmt „ • avl T © format of tree ¾.vec „ ¹ avl T © enlist of tree ¾.chk „ ? avl T © stats for tree ¾: ok size mean_depth height.See …BST„In contrast with the notes for …sbst„, …splay„ and …avl„, when discussing redblacktrees,it is convenient to show null subtrees (nulls) explicitly.AVL/Splay diagramEquivalent Red-black diagram----------------- ----------------------------EE/ \ / \/ \ / \/ \ / \B F B F/ \ / \ / \/ \ / \ ° °/ \ / \A C A C\ / \ / \D ° ° ° D/ \° °Defn: A red-black tree is a binary search tree (…BST„) with the properties (or"restrictions" or "rules"):[C] Every node is coloured either or [black],[I] Only internal nodes (other than the root or nulls) may be ,[R] Both children of a node are [black],[B] The path from a node to any leaf contains the same number of [black] nodes.Red nodes are annotated and black nodes [N]. The following tree satisfiesrules C-B:·[E]/ \/ \/ \ [F]/ \ / \/ \ [°] [°]/ \[A] [C]/ \ / \[°] [°] [°] / \[°] [°]112


Rules R and B keep the tree in reasonable balance; to construct a worst case(greatest height/size ratio), we could take an all-black (and therefore, by ruleB, perfectly balanced) tree and increase its height by injecting red nodes (onlyalternately by rule R) all down one side.·[b]/ \/ \ Height 4/ \ Size 6 (excluding nulls)./ \/ \/ \ In general, a red-black tree with ¾ non-/ \ null nodes has height at most 2×2µ¾+1.[b]/ \ / \/ \ / \/ \ / \[°] [°] [b] [b]/ \ / \[°] [°] [°] / \[°] [°]Red-black trees are implemented here using a recursive triple with 0 representingthe null tree:where:(key val) red (lft rgt)key : numeric scalar or character vectorval : any array valuered : colour of node 0=black, 1=red *lft : left subtree or 0 (null).rgt : right subtree or 0 (null)* The choice of 0 for black means that a structure assignment of a null nodeshows it as black:inf col(lft rgt)„¸© (possibly null) node colour and subs.Insertion---------Three generations of node are of interest:G grandparentP parentC childNew node C is inserted in the normal fashion (see …BST„) and coloured red .There are 4 cases: [ins#] [insB] [insRR] [insRB].Case [insRB] has 2 subcases: [insRBo] [insRBi].If is the root: recolour it [black].· … [C] … [C]/ \ / \[°] [°] [°] [°][ins#]113


Otherwise, has a parent:If 's parent [P] is black: no change.·[P] … [P] (no change)/ // \ / \[°] [°] [°] [°]Otherwise, 's parent is red.[insB][insR]This means that, from rule I, cannot be the root and so must itself have aparent G, which is 's grandparent.·G/// \[°] [°]Rule [R] ensures that [G] must be black as its child is red.·[G]/// \[°] [°]Call 's possibly null sibling U (C's Uncle).·[G]/ \ U// \[°] [°]¯If is red, change the colours of G, P and U.·[G] … [G] … / \ / \ … [P] [P] [U] … [U]/ \ / \ S S/ \ / \[°] [°] [°] [°][insRR]In this case, becomes the new node and ishandled recursively as if _it_ had been inserted.In other words, the algorithm next looks at 'sparent and grandparent to determine if furtherbalancing is necessary, and so on.Otherwise, [U] is black.[inaRB]114


If is 's outer child, swap colours and rotate G-P.¯¯¯¯¯[G] … [P] [G] … / \ / \ … [P] [U] ² G-P/ \ / \ [S][S] [U]Otherwise is inner child, rotate P-C and proceed as in [insRBo].¯¯¯¯¯[G] … [G] ² P-C/ \ / \ [insRBo] [U] [U]/ \ / \S q/ \ / \p q S p[insRBo][insRBi]All possibilities are covered:[ins]C is the root: [ins#] / \C's parent black: [insB] [insR] [insB]C's uncle red: [insRR] / \C is P's inner child: [insRBi] [insRR] [insRB]Otherwise: [insRBo] / \[insRBi] [insRBo]Removal-------To remove a node from a red-black tree, there are three phases:[loc] Locate X, the node to be deleted.[rep] Repaint the removed node's child.[bal] Rebalance the tree by absorbing any "double-black" nodes.[loc]----------------------------------------------------------------------[loc]Search the tree for the node to be deleted in the normal way (…BST„):··If the node is a leaf (only null subtrees),replace it with a null:X => [°]/ \[°] [°]Otherwise, if the node has only a single (non-null) child,replace the node with its child:X => C X => C/ \ / \[°] C C [°][loc0][loc1]Otherwise (the node has two non-null children),[loc2]exchange the node key=value with that of its right (say) successor node,which by definition does not have a left (say) child, then remove thesuccessor as in [loc0] or [loc1] above:115


target node X: X ~ X => X‘ ~ X => X‘/ \ / \ / \A B A B A B/ \ / /... ... .../ / /X's right successor: X‘ X X ~ X/ \ / \ / \[°] C [°] C [°] CAll possibilities are covered:Both subtrees null:One subtree null:Neither sutree null:[loc0][loc1][loc2]On deletion of X, it may be necessary to repaint X's child C:[rep]----------------------------------------------------------------------[rep]Repaint the removed node's child.If X was red, no more need be done:· => [C]\[C]Otherwise, if [X]'s child C is red, paint it black:·[X] => [C]\Otherwise, repaint [C] double-black.·[X] => [[C]]\[C][repR][repBR][repBB]In all cases, if we count double-black as 2, rule B continues to hold.All possibilities are covered:[rep]X red: [repR] / \C red: [repBR] [repR] [repB]C black: [repBB] / \[repBR] [repBB](·In some treatments, the double-black node is described as a separate "blacktoken", which is associated with the node. It amounts to the same thing:[X] => [[C]] [C] []


)In a particular implementation, the choice probably depends on how a null isrepresented. As we use a scalar 0 for null, there is no structure in whichto keep the double-blackness property, so a separate black token is preferable.However, the double brackets look more pleasing in diagrams, where wewill continue to use them ...[bal]----------------------------------------------------------------------[bal]Rebalance the tree by absorbing any double-black nodes [[N]].Notice how each of the transformations below preserves rules [C] [I] [R] & [B].In particular:The colour of the root of the subtree remains unchanged for rule R.Apart from the root case [bal#], the number of black nodes (square brackets)from the root of the subtree downwards remains unchanged for rule B.In the following diagrams, (N) means that the colour of N is immaterial to thetransformation.If [[N]] is the root, repaint it black:·[[N]] => [N]/ \ / \[bal#](this maintains rule B by decrementing the black count on every path).Otherwise, N has a parent and a (possibly null) sibling.If N's sibling S is red,Swap the colours of P and S and rotate P left.N's new sibling is black, so proceed from [balB].·[P] => [S] [P] … / \ / \ … [S]/ \ / \ ² P-S[[N]] [f] [balB]/ \ / \/ \ / \[n] [f] [[N]] [n][balR]Note that, after the transformation, [[N]]'s parent is red.This means that [balB] will, at worst, produce a singly-blackparent and so complete the rebalance. In particular, it is notnecessary to check for double-blackness on return of [balR]'scall to [balB].Otherwise N's sibling is black.If both nephews are black,paint sibling S red and blacken parent P.·(P) => [(P)] (P) … [(P)] */ \ / \ [[N]] … [N]/ \ / \ [S] … [[N]] [S] [N] / \ / \[n] [f] [n] [f][balB][balBbb]* (P) => [(P)] means "blacken",red goes to black … [P]black to double-black [P] … [[P]]117


Otherwise, if the far nephew f is red,Move N's extra brackets to the far nephew and rotate P-S.·(P) => (S) (S) … (P) */ \ / \ (P) … [P]/ \ / \ [[N]] … [N]/ \ / \ … [f][[N]] [S] [P] [f] ² P-S/ \ / \ / \(n) [N] (n) [a] [b]· · · / \[a] [b][balB_r]* (P) … (S) means that P's colour is transferred to S.Otherwise, the far nephew f is black (and the near one must be red),Swap the colours of S and l and rotate S right.Then proceed as in [balB_r].·(P) => (P) [S] … / \ / \ … [n]/ \ / \ ² S-n[[N]] [S] [[N]] [n] [balB_r]/ \ / \ [f][a] / \ / \[a] [b][b] [f][balBrb]All possibilities are covered:[bal]/ \[[N]] is the root: [bal#] [balR] [balB]N's sibling red: [balR] [1] / \Both nephews black: [balBbb] [2] [balB_r] [balB_b]Far nephew red: [balB_r] / \Otherwise [balBrb] [balBrb] [balBbb][1] If N has a parent, it must have a (possibly null) sibling.[2] As N is double-black, its parent must have had at least two blacknodes in each subtree (rule B). Therefore, N's sibling is not nulland so has two (possibly null) nephews.Technical notes:Insertion and removal require information about the node's parent, grandparent,uncle or nephews. In a language with pointers, we might arrange that each nodeinclude a pointer to its parent, although this would increase complexity.Similarly, we could use namespaces to implement nodes and include a ref to theparent space.We choose instead, to have the subject node's (grand) parent do the processingby returning a path (vector of directions) to the child in question. The (grand)parent can then check the length of this path to see if it must accommodate anychanges. Any node that decides that no further attention is required, returns apath that is long enough to be ignored by all ancestors. (0 0 0) will always dothe trick.References:[1] http://en.wikipedia.org/wiki/Red-black_tree[2] Internet: search for "red black tree"[3] "Paint It Black/Long Long While", Jagger/Richards, Decca F12395 (1966).118


Examples:© derive red-black tree <strong>functions</strong>:put „ ž redblack © tree ¸ with key=val ¾.rem „ ~ redblack © tree ¸ without key ¾.get „ – redblack © value for key ¸ from tree ¾.fmt „ • redblack © format of tree ¾.vec „ ~ redblack © enlist of tree ¾.chk „ ? redblack© stats for tree ¾: ok size mean_depth height.tt „ 0tt „ tt put 'one' 1fmt ttÚ[°]© null tree© single node tree: (key val) red (lft rgt)© root is [black][one=1]ÝÀ[°]tt „ tt put 'two' 2 © insert second nodefmt ttÚ[°]© new node is [one=1]ÝÛÚ[°]ÀÝÀ[°]tt „ tt put 'three' 3© insert third node.fmt ttÚ[°]ÚÝÛ À[°][three=3]ÝÛÚ[°]ÀÝÀ[°]tt „ tt put foldl ('four' 4) ('five' 5) ('six' 6) ('seven' 7)fmt ttÚ[°]Ú[five=5]ÝÛ À[°]ÚÝÛ Û Ú[°]Û Û ÚÝÛ Û Û À[°]Û À[seven=7]ÝÛ Û Ú[°]ÛÀÝÛÀ[°][three=3]ÝÛÚ[°]À[two=2]ÝÀ[°]chk tt1 7 2 4© tree stats.119


display ® fmt¨ 0 put foldl¨ 1‡¨,\0,¼6 © successive inserts 1 2 .. 6Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ̇ Ú…ÎÎÌ ÛÛ ‡[°]ÛÛÛ ÀÎÎÎÙÛÛ Ú…ÎÎÎÎÎÎÎÎÌÛÛ ‡ Ú[°]Û ÛÛ Û[1=1]Ý Û ÛÛ Û À[°]Û ÛÛ ÀÎÎÎÎÎÎÎÎÎÙÛÛ Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛÛ ‡ Ú[°] Û ÛÛ Û[1=1]Ý Û ÛÛ Û Û Ú[°]Û ÛÛ Û ÀÝ Û ÛÛ Û À[°]Û ÛÛ ÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙÛÛ Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛÛ ‡ Ú[°]Û ÛÛ Û ÚÝ Û ÛÛ Û Û À[°]Û ÛÛ Û[2=2]Ý Û ÛÛ Û Û Ú[°]Û ÛÛ Û ÀÝ Û ÛÛ Û À[°]Û ÛÛ ÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙÛÛ Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌ ÛÛ ‡ Ú[°] Û ÛÛ Û Ú[1=1]Ý Û ÛÛ Û Û À[°] Û ÛÛ Û[2=2]Ý Û ÛÛ Û Û Ú[°] Û ÛÛ Û À[3=3]Ý Û ÛÛ Û Û Ú[°]Û ÛÛ Û ÀÝ Û ÛÛ Û À[°]Û ÛÛ ÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙ ÛÛ Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌ ÛÛ ‡ Ú[°] Û ÛÛ Û Ú[1=1]Ý Û ÛÛ Û Û À[°] Û ÛÛ Û[2=2]Ý Û ÛÛ Û Û Ú[°]Û ÛÛ Û Û ÚÝ Û ÛÛ Û Û Û À[°]Û ÛÛ Û À[4=4]Ý Û ÛÛ Û Û Ú[°]Û ÛÛ Û ÀÝ Û ÛÛ Û À[°]Û ÛÛ ÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙ ÛÛ Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌ ÛÛ ‡ Ú[°] Û ÛÛ Û Ú[1=1]Ý Û ÛÛ Û Û À[°] Û ÛÛ Û[2=2]ÝÛ ÛÛ Û Û Ú[°] Û ÛÛ Û Û Ú[3=3]Ý Û ÛÛ Û Û Û À[°] Û ÛÛ Û ÀÝ Û ÛÛ Û Û Ú[°] Û ÛÛ Û À[5=5]Ý Û ÛÛ Û Û Ú[°]Û ÛÛ Û ÀÝ Û ÛÛ ÛÀ[°]Û ÛÛ ÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙ Û120


À¹ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙtt „ 0 put foldl ¼6© 6 nodes, ascending order.display ® fmt¨(›tt)rem foldl¨1‡¨,\0,¼6 © successive removals 1 2 .. 6Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ̇ Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌ ÛÛ ‡ Ú[°] Û ÛÛ Û Ú[1=1]Ý Û ÛÛ Û Û À[°] Û ÛÛ Û[2=2]ÝÛ ÛÛ Û Û Ú[°] Û ÛÛ Û Û Ú[3=3]Ý Û ÛÛ Û Û Û À[°] Û ÛÛ Û ÀÝ Û ÛÛ Û Û Ú[°] Û ÛÛ Û À[5=5]Ý Û ÛÛ Û Û Ú[°]Û ÛÛ Û ÀÝ Û ÛÛ ÛÀ[°]Û ÛÛ ÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙ ÛÛ Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌ ÛÛ ‡ Ú[°] Û ÛÛ Û Ú[2=2]Ý Û ÛÛ Û Û Û Ú[°]Û ÛÛ Û Û ÀÝ Û ÛÛ Û Û À[°]Û ÛÛ Û[4=4]Ý Û ÛÛ Û Û Ú[°] Û ÛÛ Û À[5=5]Ý Û ÛÛ Û Û Ú[°]Û ÛÛ Û ÀÝ Û ÛÛ Û À[°]Û ÛÛ ÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙ ÛÛ Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌ ÛÛ ‡ Ú[°] Û ÛÛ Û Ú[3=3]Ý Û ÛÛ Û Û À[°] Û ÛÛ Û[4=4]Ý Û ÛÛ Û Û Ú[°] Û ÛÛ Û À[5=5]Ý Û ÛÛ Û Û Ú[°]Û ÛÛ Û ÀÝ Û ÛÛ Û À[°]Û ÛÛ ÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙ ÛÛ Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛÛ ‡ Ú[°]Û ÛÛ Û Ú[4=4]Ý Û ÛÛ Û Û À[°]Û ÛÛ Û[5=5]Ý Û ÛÛ Û Û Ú[°]Û ÛÛ Û À[6=6]Ý Û ÛÛ Û À[°]Û ÛÛ ÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙÛÛ Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛÛ ‡ Ú[°] Û ÛÛ Û[5=5]Ý Û ÛÛ Û Û Ú[°]Û ÛÛ Û ÀÝ Û ÛÛ Û À[°]Û ÛÛ ÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙÛÛ Ú…ÎÎÎÎÎÎÎÎÌÛÛ ‡ Ú[°]Û ÛÛ Û[6=6]Ý Û ÛÛ Û À[°]Û Û121


Û ÀÎÎÎÎÎÎÎÎÎÙÛÛ Ú…ÎÎÌÛÛ ‡[°]ÛÛÛ ÀÎÎÎÙÛÀ¹ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙSee also: BST.88 sbst.105 avl.96 splay.120 foldl.45 alists.8ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎsplayrslt „ {larg} (op ##.splay) rarg© Splay trees.T‘ „ T ž splay (key val) © tree ¸ with key=val ¾.T‘ „ T ~ splay key © tree ¸ without key ¾.T‘ „ T – splay key © value for key ¾ in tree ¸.dep „ T ­ splay key © depth of key ¾ in tree ¸.fmt „ • splay T © format of tree ¾.vec „ ¹ splay T © enlist of tree ¾.chk „ ? splay T © stats for tree ¾: ok size mean_depth height.See …BST„A splay tree is a self-balancing binary search tree; each time a node is accessed,it is rotated nearer to the root. This mean that frequently accessed nodeswind up with shorter search paths.Unlike …avl„ and …redblack„ trees, splay trees are not maintained in a state ofreasonable balance. Instead, nodes with frequently accessed keys _tend_ tomigrate towards the root, which _tends_ to give them shorter access times.The performance of a splay tree may not be as optimal as one of its more complexrelatives, but its implementation is considerably simpler.Node Access-----------In the following, node [A] is accessed. There are three cases, × two left-rightmirrow-image orientations.[0] Node [A] is the root node: no change.[1] Node [A] is the left (right) child of the root.[2] Node [A] is the left (right) child of a left (right) child.¯¯¯¯¯¯¯¯[3] Node [A] is the right (left) child of a left (right) child.¯¯¯¯¯¯¯¯¯Cases [1 2 3] are summarised in the following diagram:122


ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌ[1] Û B [A] Û B [A] ÛÛ / \ … / \ Û / \ … / \ ÛÛ [A] r p B Û r [A] B p ÛÛ / \ / \ Û / \ / \ ÛÛ p q q r Û q p r q ÛÃÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÝ[2] Û C [A] Û C [A] ÛÛ / \ … / \ Û / \ … / \ ÛÛ B s p B Û s B B p ÛÛ / \ / \ Û / \ / \ ÛÛ [A] r q C Û r [A] C q ÛÛ / \ / \ Û / \ / \ ÛÛp q r s Û q p s r ÛÃÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÝ[3] Û C [A] Û C [A] ÛÛ / \ … / \ Û / \ … / \ ÛÛ B s / \ Û s B / \ ÛÛ / \ B C Û / \ C B ÛÛp [A] / \ / \ Û [A] p / \ / \ ÛÛ / \ p q r s Û / \ s r q pÛÛ q r Û r q ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙNode removal------------[splay] uses the "quicker" method of node removal. See …BST„.Technical notes---------------The tree is implemented as the pair-of-pairs: (key val) (lft rgt)key: node keyval: node valuelft: left subtree or 0rgt: right subtree or 0The two double rotations are coded by applying function [rot] twice. If speed iscritical, we could code them directly as follows:rotrr„{ © double ¾-¾-wise rotion of tree ¸.C(BAr s)„¾ wise\¸ © C AB(Apq r)„¾ wise\BAr © / \ … / \A(p q)„¾ wise\Apq © B s p B© / \ / \Crs„¾ wise\C(r s) © A r q CBqC„¾ wise\B(q Crs) © / \ / \¾ wise\A(p BqC) © p q r s}rotrl„{ © double ¾-¯¾-rotation of tree ¸.C(BpA s)„¾ wise\¸ © C AB(p Aqr)„¾ wise\BpA © / \ … / \A(q r)„¾ wise\Aqr © B s / \© / \ B CBpq„¾ wise\B(p q) © p A / \ / \Crs„¾ wise\C(r s) © / \ p q r s¾ wise\A(Bpq Crs) © q r}Notice that function ¾-wise is applied under scan (\), which means that it affectsonly the second item of the node pair (key val)(lft rgt).123


References----------http://en.wikipedia.org/wiki/Splay_treeExamples--------© key=value pairs:pairs „ ('one'1) ('two'2) ('three'3) ('four'4) ('five'5) ('six'6) ('seven'7)tt „ 0 žsplay foldl pairs© insert key=val pairs into a splay tree.display •splay tt© show resulting tree.Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ̇ Úfive=5 ÛÛ Úfour=4Ù ÛÛone=1ÝÛÛ Û Úseven=7ÛÛ Û Úsix=6Ù ÛÛ Û Úthree=3Ù ÛÛ Àtwo=2Ù ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙ5'seven' ­splay ttval tt „ 'seven' –splay tt© depth of key 'seven'.© first access of key 'seven',display •splay tt © moves it towards the root.Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ̇ Úfive=5 ÛÛ Úfour=4Ù ÛÛone=1ÝÛÛ Û Úseven=7Ì ÛÛ Û Û Àsix=6Ì ÛÛ Û Û Àthree=3ÛÛ Àtwo=2Ù ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙ3'seven' ­splay ttval tt „ 'seven' –splay tt© new depth of key 'seven'.© second access of key 'seven',display •splay tt © moves it to the root.Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ̇ Úfive=5ÛÛ Úfour=4Ù ÛÛ Úone=1Ù ÛÛseven=7ÝÛÛ Û Úsix=6Ì ÛÛ Û Û Àthree=3ÛÛ Àtwo=2Ù ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙ'seven' ­splay tt1?splay tt1 7 2 4tt „ tt ~splay 'seven'© depth of key 'seven'.© tree is: ok size=7, mean_depth=2, height=4.© tree with key 'seven' removed.124


display •splay ttÚ…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ̇ Úfive=5ÛÛ Úfour=4Ù ÛÛ Úone=1Ù ÛÛsix=6ÝÛÛ Û Úthree=3 ÛÛ Àtwo=2Ù ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙdisp ¹splay tt© enlist of tree key=val pairs.Ú…ÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÌÛÚ…ÎÎÎÂÎÌÛÚ…ÎÎÎÂÎÌÛÚ…ÎÎÂÎÌÛÚ…ÎÎÂÎÌÛÚ…ÎÎÎÎÂÎÌÛÚ…ÎÎÂÎÌÛÛÛfiveÛ5ÛÛÛfourÛ4ÛÛÛoneÛ1ÛÛÛsixÛ6ÛÛÛthreeÛ3ÛÛÛtwoÛ2ÛÛÛÀÎÎÎ…ÁÎÙÛÀÎÎÎ…ÁÎÙÛÀÎÎ…ÁÎÙÛÀÎÎ…ÁÎÙÛÀÎÎÎÎ…ÁÎÙÛÀÎÎ…ÁÎÙÛÀÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎ…ÁÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎ…Ù© Notice how repeated retrieval of a particular key© lifts its node towards the root:125


disp †•splay\¨†°(–splay/)traj 10,›0 žsplay foldl ¼10 © see …traj„Ú…ÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ̇ Û1=1Ì ÛÛ Û À2=2Ì ÛÛ Û À3=3Ì ÛÛ Û À4=4Ì ÛÛ10Û À5=5Ì ÛÛ Û À6=6Ì ÛÛ Û À7=7Ì ÛÛ Û À8=8Ì ÛÛ Û À9=9Ì ÛÛ ÛÀ10=10‡Ã~ÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÝÛ Û1=1ÌÛÛ Û À2=2Ì ÛÛ Û À3=3Ì ÛÛ Û À4=4Ì ÛÛ10Û À5=5Ì ÛÛ Û À6=6Ì ÛÛ Û À7=7Ì ÛÛ Û Û Ú8=8ÛÛ Û Û Ú9=9Ù ÛÛ Û À10=10Ù ‡Ã~ÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÝÛ Û 1=1ÌÛÛ Û À2=2Ì ÛÛ Û À3=3Ì ÛÛ Û À4=4Ì ÛÛ10Û À5=5Ì ÛÛ Û Û Ú6=6 ÛÛ Û Û Ú7=7Ý ÛÛ Û Û Û Û Ú8=8 ÛÛ Û Û Û À9=9Ù ÛÛ Û À10=10Ù ‡Ã~ÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÝÛ Û 1=1Ì ÛÛ Û À2=2Ì ÛÛ Û À3=3Ì ÛÛ Û Û Ú4=4 ÛÛ10Û Û Ú5=5Ý ÛÛ Û Û Û Û Ú6=6 ÛÛ Û Û Û À7=7Ý ÛÛ Û Û Û Û Ú8=8 ÛÛ Û Û Û À9=9Ù ÛÛ Û À10=10Ù ‡Ã~ÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÝÛ Û 1=1Ì ÛÛ Û Û Ú2=2 ÛÛ Û Û Ú3=3Ý ÛÛ Û Û Û Û Ú4=4 ÛÛ10Û Û Û À5=5Ý ÛÛ Û Û Û Û Ú6=6 ÛÛ Û Û Û À7=7Ý ÛÛ Û Û Û Û Ú8=8 ÛÛ Û Û Û À9=9Ù ÛÛ Û À10=10Ù ‡Ã~ÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÝÛ Û Ú1=1Ì ÛÛ Û Û Û Ú2=2 ÛÛ Û Û À3=3Ý ÛÛ Û Û Û Ú4=4 ÛÛ10Û Û À5=5Ý ÛÛ Û Û Û Ú6=6 ÛÛ Û Û À7=7Ý ÛÛ Û Û Û Ú8=8 Û126


Û Û Û À9=9Ù ÛÛ Û 10=10Ù ‡À~ÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÙSee also: BST.88 alists.8 sbst.105 avl.96 redblack.110 foldl.45 traj.220ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎdfttree „ {slant„1}(fn ##.dft) spread© Display of function tree.Operator [dft] returns a character matrix representation of its function operand[fn].Right argument [spread] determines the horizontal width of tree branches:'') dft¨ 1 3° °ÚÎÁÎÌ ÚÎÎÎÁÎÎÎÌ° ° ° °ÚÁÌ ÚÁÌ ÚÎÁÎÌ ÚÎÁÎÌ< , , > < , , >© narrow and wide tree display.Optional left argument {slant„1} determines whether a monadic operator shouldsuspend its left operand by a vertical (0) or slanted (1) line:1 0 +¨¨¨.× dft¨ 3 © compare slanted vs vertical left operand.. .ÚÎÁÎÌ ÚÎÁĮ̂ × ¨ ×ÚÎÙ Û¨ ¨ÚÎÙ Û¨¨ÚÎÙÛ+ +[dft] subsumes and replaces operator "ddft" and is extended to be function-trainready:(+/÷½) dft 1 © display of fork.ÚÎÏÎÌ/ ÷ ½ÚÙ+ulam dft 1© display of longer train:ÚÎÎÎÏÎÎÎÎÎÎÎÎÌÚÁÌ ° ÚÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÌ2 ½ ÚÁÎÌ þ † ÚÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎ̽ ÚÁÌ ÚÙ ÚÎÎÏÎÎÎÎÎÌ , ÚÎÎÎÏÎÎÎÎÎÎÌ” \ × ÚÁÌ + ÚÎÎÎÏÎÎÎÌ / ° ÚÎÎÏÎÎÎÌÚÙ 2 | ÚÁÌ ° ° ÚÁÌ ÚÁÌ ÚÁÌ ½ ÚÎÏÎÎÎÌ+ 1 + ÚÁÌ ÚÁÌ 2 ¼ / € 2 × 1 , ÚÎÏÎÎÌ× ˜ ÷ 2 - , ÚÁÎ̯1 ,Technical notes:For large trees, much space can be saved in the output by meshing subtrees tooverlap vertically.127


Without vertical overlap With vertical overlap------------------------ ---------------------° °ÚÎÎÁÎÎÎÎÎÎÎÎÎÎÌÚÎÎÎÁÎÎÎÌ° ° ° °ÚÎÎÁÎÌ ÚÎÎÁÎÌ ÚÎÁÎÌ ÚÎÁÎÌ° + ° + ° + ° +ÚÎÎÁÎÌ ÚÎÎÁÎÌ ÚÎÁÎÌ ÚÎÁÎÌ° + ° + ° + ° +ÚÎÁÎÌ ÚÎÁÎÌ ÚÎÁÎÌ ÚÎÁÎÌ° + ° + ° + ° +ÚÎÁÎÌ ÚÎÁÎÌ ÚÎÁÎÌ ÚÎÁÎÌ+ + + + + + + +This is achieved by inner function "mesh" using steps:1. Extend the shallower subtree so that both have the same number of rows.2. Determine the minimum horizontal gap between the subtrees.3. Distribute the number of characters to be dropped between the subtrees.4. Drop separating blanks; join corresponding rows; mix rows to a matrix.Examples:deco„ +.×þ°(÷°²°(+\)°²þ)þdisp Œcr'deco'Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÌÛÚ…ÎÎÎÎÎÎÂÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ ÛÛÛ Û ÛÚ…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÌÛÛ ÛÛÛ Û ÛÛÚ…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÂÎÌÛ ÛÛÛ ÛÛÛ Û ÛÛÛÚ…ÎÎÎÎÎÎÎÂÎÂÎÎÌÛ Û ÛÛ ÛÛÛ ÛÛÛÚ…ÎÎÂÎÌÛ ÛÛÛÛÚ…ÎÂÎÂÎÌÛ Û ÛÛ Û ÛÛ ÛÛÛ ÛÛÛÛ+.×ÛþÛÛ°ÛÛÛÛÛ÷þÛ°Û²ÛÛ°Û×\ÛÛ°Û²ÛÛþÛÛÛþÛÛÛÀÎÎ…ÁÎÙÛ ÛÛÛÛÀÎ…ÁÎÁÎÙÛ Û ÛÛ Û ÛÛ ÛÛÛ ÛÛÛ Û ÛÛÛÀÎÎÎÎÎÎÎ…ÁÎÁÎ…ÙÛ Û ÛÛ ÛÛÛ ÛÛÛ Û ÛÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÁÎÙÛ ÛÛÛ ÛÛÛ Û ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÙÛÛ ÛÛÀÎÎÎÎÎÎ…ÁÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÙÛ ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÙdeco dft 3þÚÎÙ°ÚÎÎÎÁÎÎÎÌþ þÚÎÙ ÚÎÙ. °ÚÎÁÎÌ ÚÎÁÎÌ+ × ° ²ÚÎÎÎÁÎÎÎÌ° \ÚÎÁÎÌ ÚÎÙ÷ ² ++{¸¸ ¾}{¸¸ ¾} dft 3{¸¸·¾}ÚÎÙ{¸¸·¾}ÚÎÙ+© derived function. See …derive„© nested canonical representation.© 3-spread tree.© non-primitive operator.128


^¨¨¨¨¨¨{¸¸°¸¸{¸¸°¸¸{¸¸°¸¸ dft ¾}¾}¾}3 © scary sea monster.°ÚÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÌ° °ÚÎÎÎÎÎÁÎÎÎÎÎÌÚÎÎÎÎÎÁÎÎÎÎÎÌ° ° ° °ÚÎÎÁÎÎÌ ÚÎÎÁÎÎÌ ÚÎÎÁÎÎÌ ÚÎÎÁÎĮ̂ ¨ ¨ ¨ ¨ ¨ ¨ ¨ÚÎÙ ÚÎÙ ÚÎÙ ÚÎÙ ÚÎÙ ÚÎÙ ÚÎÙ ÚÎÙ¨ ¨ ¨ ¨ ¨ ¨ ¨ ¨ÚÎÙ ÚÎÙ ÚÎÙ ÚÎÙ ÚÎÙ ÚÎÙ ÚÎÙ ÚÎÙ¨ ¨ ¨ ¨ ¨ ¨ ¨ ¨ÚÎÙ ÚÎÙ ÚÎÙ ÚÎÙ ÚÎÙ ÚÎÙ ÚÎÙ ÚÎÙ¨ ¨ ¨ ¨ ¨ ¨ ¨ ¨ÚÎÙ ÚÎÙ ÚÎÙ ÚÎÙ ÚÎÙ ÚÎÙ ÚÎÙ ÚÎÙ¨ ¨ ¨ ¨ ¨ ¨ ¨ ¨ÚÎÙ ÚÎÙ ÚÎÙ ÚÎÙ ÚÎÙ ÚÎÙ ÚÎÙ ÚÎÙ¨ ¨ ¨ ¨ ¨ ¨ ¨ ¨ÚÎÙ ÚÎÙ ÚÎÙ ÚÎÙ ÚÎÙ ÚÎÙ ÚÎÙ ÚÎÙ^ ^ ^ ^ ^ ^ ^ ^© In the absence of a more general mechansism in <strong>Dyalog</strong>, we need to augment our© operator set in order to be able to translate expressions of ¸ and ¾ into der-© ived <strong>functions</strong>. Combinators [in] and [on], together with primitive operators© compose ° and commute þ allow us to build long function-operator trains:© in„{œ¸¸/¾} © in (between): f in x y … x f yon„{¸¸ ¸ ¾}© and its counterpart: x f on y … f x y© J language's hook and fork constructs may be translated into such© trains using: ÚÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌ© Û J Syntax Û Equivalent D Û Equivalent Train Û© ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÝ© ÛMonadic Hook Û (g h) Û {¾ g h ¾} Û g°hþ Û© ÃÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÝ© ÛDyadic Hook Û (g h) Û {¸ g h ¾} Û g°h Û© ÃÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÝ© ÛMonadic Fork Û (f g h) Û {(f ¾)g h ¾} Û g°hþ°fþ Û© ÃÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÝ© ÛDyadic Fork Û (f g h) Û {(¸ f ¾)g ¸ h ¾} Û g°(h in)þ°(f in)þon Û© ÀÎÎÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙ© NB: <strong>Dyalog</strong> V14 introduces the fork as a primitive construct and so many of the© following examples may be simplified. © For example:avg „ ÷°½þ°(+/)þ © equivalent of monadic fork (+/ ÷ ½)avg 1 2 3 41 2 3 4avg dft 3þÚÎÙ°ÚÎÎÁÎÎÌþ /ÚÎÙ ÚÎÙ° +ÚÎÁÎÌ÷ ½© test function.© display of function tree.leq „ Ÿ°(=in)þ°(


0 0 1 1 leq 0 1 0 1 © test function.1 1 0 1leq dft 3on„{¸¸·¸·¾}ÚÎÙþÚÎÙ°ÚÎÎÁÎÎÌþ in„{œ¸¸/¾}ÚÎÙ ÚÎÙ°


dinv dft 3 © display of function tree.þÚÎÙon„{¸¸·¸·¾}ÚÎÙþÚÎÙ°ÚÎÎÎÁÎÎÎÌþ in„{œ¸¸/¾}ÚÎÙ ÚÎÙ° þÚÎÁÎÌ ÚÎÙþ œ on„{¸¸·¸·¾}ÚÎÙ ÚÎÙ° þÚÎÁÎÌ ÚÎÙþ - °ÚÎÙ ÚÎÎÎÁÎÎÎ̆ þ in„{œ¸¸/¾}ÚÎÙ ÚÎÙ° þÚÎÁÎÌ ÚÎÙþ œ °ÚÎÙ ÚÎÁÎÌ+ þ ×ÚÎÙ°ÚÎÁÎÌ× ½rinv „ —/¨°(-°›°¼°(œ°²)°½°œþ)°(¼¨in)°(‡¨)on© inverse for ²°¾.'Mississippi' rinv 'issippiMiss'4rinv dft 3on„{¸¸·¸·¾}ÚÎÙ°ÚÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÌ° ¨ÚÎÎÎÎÁÎÎÎÎÎÌÚÎÙ° in„{œ¸¸/¾} ‡ÚÎÎÁÎÎÌ ÚÎÙ¨ þ ¨ÚÎÙ ÚÎÙ ÚÎÙ/ ° ¼ÚÎÙ ÚÎÁÎÌ— ° œÚÎÁÎÌ° ½ÚÎÎÎÁÎÎÎÌ° °ÚÎÁÎÌ ÚÎÁÎÌ° ¼ œ ²ÚÎÁÎÌ- ›© display of function tree.© Functions for 1st and 2nd items of a pair, used in these examples, might also© be considered combinators. In the examples above, they have been implemented© (assuming Œml


See also: tfmt.130 fork.234 derive.535 parse.237ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎtfmtcmat „ ##.tfmt tree© Char matrix from tree(s).The character matrix result is an indented representation of the nested formattree argument.Examples, See: TreesSee also: tnest.130 tview.137ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎtnesttree „ ##.tnest (depth leaves)© Array from TreeView style tree.The TreeView style representation of a tree is rendered in nested array form.Technical note:An alternative coding of this function might be:tnest„{ŒML„0© Array from TreeView style tree.1{ © starting with split at 1s.1=½¾:œ²†¾© atom: leaf value.(›œ²œ¾),(¸+1)’¨(¸=œ¨¾)›¾ © tree: node followed by subarrays.}‡³†¾© vector of depth-node pairs.}Examples, See: TreesSee also: tfmt.130 tview.137ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎtravrslt „ ival (accm ##.trav subs) tree © Generic depth-first tree traversal.rslt „ ival (accm ##.ravt subs) tree © trav: parent-first, ravt: parent last.[trav] and [ravt] traverse a [tree], applying left operand accumulating function[accm] between the current value of the accumulator (initial value [ival]) andeach node. Right operand function [subs] is required to return a (possibly empty)vector of subtrees for each node.[trav] and [ravt] differ only in the order in which they visit the nodes of thesubject [tree].[trav] visits (applies [accm] to) the parent node before visiting any children.¯¯¯¯¯¯[ravt] visits the parent node after visiting any children.¯¯¯¯¯Mnemonic: given this tree:tÚÎÏÎÌr a vtrav visits: t r a vravt visits: r a v tBoth left and right operand <strong>functions</strong> are ambi-valent, with the current accumulatorvalue as left argument and current node as right argument. To borrow thetype notation developed in …foldl„:trav ravt :: ¸ (¸ ’ ¾ … ¸) ’’ (¸ ’ ¾ … [¾]) ¾ … ¸© type of trav & ravt132


Right operand function [subs] "projects" a tree structure onto its right argument.[tree] could be concrete, as with a collection of nested namespaces, butcould equally be a _notional_ tree, which is not instantiated in the workspace.In particular, successive arguments, produced during the evaluation of a purerecursive function, may be viewed as a tree. This means that, theoretically, anyrelationship that can be expressed as a pure recursive function, may be codedusing [trav] or [ravt]: the ¾th Fibonacci number; arithmetic <strong>functions</strong>, such asGCD and Ackermann; the solution(s) of a Sudoku puzzle; the best next move in agame of chess; and so on.An alternative interpretation is that right operand [subs] replaces the task athand with 0 (base-case) or more sub-tasks and left operand [accm] accumulatesthe results of these sub-tasks to produce the answer.For example, the ¾th Fibonacci number may be expressed recursively as:¾, if ¾ is 0 or 1the sum of the previous two Fibonacci numbers, otherwise.Leading to this [trav] coding:fib „ {¸+¾×¾¹0 1} trav {(¾-2 1)~-2 1}© ¾th fibonacci number0 fib¨ 0 to 10 © fibonacci sequence.0 1 1 2 3 5 8 13 21 34 55This trace operator shows what's happening by displaying accumulator ¸ and nodevalue ¾ as a node is visited:tc„{depth„¯2+½ŒSItab„¹depth½›'·Œ„tab,•¸ ¾¸ ¸¸ ¾}© Indented trace of node visit.© depth of recursion' © indentation vector© display of ¸ and ¾© node visit.0 {¸+¾×¾¹0 1}tc trav {(¾-2 1)~-2 1} 5 © fib 50 5· 0 3· · 0 1· · · 1 0· · 1 2· · · 1 0· · · 1 1· · · · 2 0· 2 4· · 2 2· · · 2 0· · · 2 1· · · · 3 0· · 3 3· · · 3 1· · · · 4 0· · · 4 2· · · · 4 0· · · · 4 1· · · · · 5 05133


(muse:·· The above naïve coding of the ¾th Fibonacci is very inefficient. Operator· …memo„ effectively transforms the above _tree_ into the much smaller _graph_· which, by removing duplication, leads to an evaulation with many fewer· steps:·· ÚÎ…ÎÌÎ…ÎÌÎ…ÎÌÎ…ÎÌÎ…ÎÌ· 5 4 3 2 1 0· ÀÎ…ÎÏÎ…ÎÝ Û Û Û· ÀÎ…ÎÏÎ…ÎÝ Û Û· ÀÎ…ÎÏÎ…ÎÝ Û· ÀÎ…ÎÏÎ…ÎÝ· ÀÎ…ÎÙ)Sometimes, there is only ever 1 (or 0 in the base case) sub-task. In such caseswe have a "unary" tree (AKA "List") as for Euclid's algorithm for Greatest CommonDivisor …gcd„:¾, if ¸ is 0gcd of ¾ and |¾-¸, otherwiseleading to this [trav] coding:gcd „ € trav {|¾-¸~0}© Euclid's GCD.35 gcd 55 © cf: 15Ÿ35535 €tc trav {|¾-¸~0} 55 © traced evaluation35 55· 55 20· · 20 35· · · 35 15· · · · 15 20· · · · · 20 5· · · · · · 5 15· · · · · · · 15 10· · · · · · · · 10 5· · · · · · · · · 5 5· · · · · · · · · · 5 0· · · · · · · · · · · 0 55.. and this more efficient version, which uses residue in place of repeated subtraction:35 |tc trav {¸~0} 55 © traced evaluation35 55· 20 35· · 15 20· · · 5 15· · · · 0 55(muse:·· Perhaps, in cases where there can be more than one sub-task at each node· (Fibonacci, chess problems, ...), an operator like [trav] could help with· organising their parallel evaluation, using multiple processors.)Technical notes:134


The coding of the body of trav is surprisingly simple:œ’þ/²(›¸ ¸¸ ¾),¸ ¾¾ ¾ÛÀÂÙ ÀÎÂÎÎÙ ÀÎÂÎÎÙÛ Û Û ÀÎÎÎÎ (possibly empty) vector of sub-trees.Û Û ÀÎÎÎÎÎÎÎÎÎÎÎÎ new value of accumulator.Û ÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ left-to-right reduction …foldl„ÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ recursive call on (¸¸ trav ¾¾).At first sight, the code appears to be missing a test to back out of the recursionafter a leaf-node has been visited. In fact, this occurs automatically: ifthe vector of sub-trees (¸ ¾¾ ¾) is empty, the sub-expression: (›¸ ¸¸ ¾),¸ ¾¾ ¾is a 1-item vector and so the reduction ’þ/ passes it along as result withoutapplying its operand function and thus avoiding the recursive call on trav.[ravt] is essentially the same but with the accumulation (... ¸¸ ¾) following,rather than preceding, the recursive call:(œ’þ/²(›¸),¸ ¾¾ ¾)¸¸ ¾© visit nodes _after_ subnodes.It is comforting to have the accumulator as left argument and the subject treeon the right. Swapping (commuting) these arguments would give a slightly simplercoding of the operator:vart„{œ’/(¾ ¾¾ ¸),›¸ ¸¸ ¾}© commuted version of trav,© ... produces simpler coding.at the expense of a correspondingly less intuitive coding for the [accm] operandfunction:accm „ {((0=­¸)/¸),¾}subs „ {(0¬­¾)/¾}list „ accm vart subs© accumulating simple scalars© non-atoms for processing© accumulation of atoms.'ab'('cd' 'e') list ''abcde135


(muse:·· Right operand [subs] determines how (for example) a nested array or a coll-· ection of namespaces, constitute a tree. Given such an association, left op-· erand [accm] defines a _property_ of the resulting tree, such as its size· (number of nodes or leaves) or the enlisted vector of its leaves.·· "Right Operand Currying", which appears in <strong>Dyalog</strong> V14, where an operator's· right operand may be bound independently of its left operand, is useful in· this situation. For example:·· atree „ trav {(0¬­¾)/¾} © vector as tree. Operand currying.· © ¯¯¯¯¯¯¯· acount „ {¸+1} atree © property: node count.· aleaves „ {¸,(0=­¾)/,¾} atree © property: leaf list.·· By analogy, "Left Argument Currying" would allow us to bind an initial acc-· umulator value to produce a monadic derived function:·· asize „ 0 acount © array-as-tree size. Argument currying.· alist „ « aleaves © enlist ¯¯¯¯¯¯¯¯·· Of course, left arguments may already be bound using the slightly less beau-· tiful composition: asize „ 0°acount ª alist „ «°aleaves·· Either way:·· asize (1 2)(3 4) © tree size (see examples below).· 7· alist 'ab'('cd' 'e') © enlist.· abcde)Non-termination:If the "tree" turns out to have cycles and is therefore a more general graphstructure,as may be the case with collections of namespace references, it isnecessary to detect this condition to prevent further node traversal. Otherwise,the traversal will fail to terminate. See example below.Breadth-first search--------------------The equivalent coding for a breadth-first search, which visits all nodes at eachlevel _before_ proceeding to any of their subnodes, is slightly more complex.See also …search„.bftrav„{ŒML„1© Generic breadth-first tree traversal.}¸ ¸¸{0=½¾:¸(¸ ¸¸œ¾)’(1‡¾),(¸ ¾¾œ¾)}¾¾,›¾subs „ {¾.(1‡–¨'0',‡Œnl 9)} © sub-namespaces for space ¾.'t.r.rr' 't.a.aa' 't.v.vv' Œns¨ ›''tree t#.t· a· · aa· r· · rr· v· · vv136© create tree.© depth-2 tree.


« ,bftrav subs t © nodes in breadth-first order.#.t #.t.a #.t.r #.t.v #.t.a.aa #.t.r.rr #.t.v.vvExamples:subs „ {¾.(1‡–¨'#',‡Œnl 9)} © sub-namespaces for space ¾.accm „ {¸+1}© counting nodes.0 accm trav subs # © count of spaces.3accm „ ,© accumulating into a vector.« accm trav subs # © vector of spaces. C.f. …refs„# #.notes #.scripts« accm ravt subs # © ravt visits node _after_ subnodes.#.notes #.scripts #usp „ {¾.(1‡–¨'#',‡Œnl 9)~¸}© unique sub-spaces, ignoring cycles.'xy'Œns¨›'' © spaces x and y.(x y).(x y)„›x y © create some cycles« ž trav usp x © vector of spaces in graph. C.f. …refs„#.x #.y© A (nested) array may be ÚÎÁÎÌ© considered as a tree with (1 2)(3 4) „… ÚÁÌ ÚÁÌ© depth-0 items as leaves: 1 2 3 4subs „ {(0¬­¾)/,¾} © sub-items of array ¾.accm „ {¸+1}© counting nodes.0 accm trav subs (1 2)(3 4) © node-count7accm „ {¸,(0=­¾)/,¾}© accumulating simple scalars« accm trav subs 'ab'('cd' 'e') © enlistabcde© N-queens problem:accm „ {¸,(¸¸=½¾)/›¾}© accumulated leaves.subs„{Œio„1 © possible placements \|/\ | \/| /dd„²¼½¾ © diagonal µ \ | /\|/ak„(¾-dd),¾,(¾+dd) © attacked cols in next row : \|/ µ¾°,¨(¼¸¸)~ak © subnodes µ}«(4 accm)trav(4 subs)« © 4-queens solutions vector.2 4 1 3 3 1 4 2© A similar expression for N-Queens using depth-first search is developed© in YouTube video: https://www.youtube.com/watch?v=DsZdfnlh_d0See also: refs.380 acc.10 foldl.45 osc.296 gcd.284 search.153 queens.481ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎtreecvec „ {maxcols„Œpw} ##.tree space© Display of namespace tree.The resulting character vector represents the structure of all objects in theargument space. The optional left argument (default ŒPW), determines the maximumnumber of columns for the result. Within sub-spaces, objects of each name-classare collected and prefixed with type code:137


~ variables’ <strong>functions</strong>° operatorsNamespaces of special type (Forms, Menus, etc.), are explicitly annotated.[tree] is a good candidate for invocation using a programmable function key, see…PF_keys„.Technical notes:In order to avoid name clashes with definitions local to tree itself, auxiliaryoperand function exec„{¸–¾} is installed _outside_ the main body of code. WhenŒNL and – are called via [exec], local names inside tree are invisible. This isone of the benefits of lexical as opposed to dynamic scope rules.Given that any space may contain a ref to any other space, the structure is moreproperly termed a _graph_ than a _tree_. Tree pursues only the immediate childrenof each space. Otherwise, _remote_ references appear as: ref … full_name.Notice that refs "hidden" within array variables are invisible to this versionof [tree].Examples:80 tree ##· ’ ambiv ascfile attrib cmat cmpx day det dice disp display dot factorial· ’ factors fibonacci find fndiff fnrefs gcd justify kt lcase life mean mtrim· ’ osc pack pmat queens refs root roots setwx sieve squeeze ss ssmat ssword· ’ stamps subs tfmt timestamp tnest to tokens tokens2 tree tview type ucase· ’ unwrap up vtrim words wrap wsdiff xtabs· ° bsearch else file limit perv pow saw traj until· notes· · ~ ambiv ascfile attrib bsearch cmat cmpx contents day det dice disp· · ~ display else factorial factors fibonacci file find fndiff fnrefs gcd· · ~ justify kt lcase life limit mean mtrim osc pack perv pmat pow queens· · ~ refs root roots saw setwx sieve squeeze ss ssmat ssword stamps subs· · ~ tfmt timestamp tnest to tokens tokens2 traj tree tview type ucase· · ~ until unwrap up vtrim words wrap wsdiff xtabs Line_vectors Namespaces· · ~ Trees Workspacestree ŒSE.cbbot.bandsb1ŒSE.cbbot.bandsb1 [CoolBand]· sb [StatusBar]· · caps [StatusField]· · hint [StatusField]· · ins [StatusField]· · · ’ KEY_TOGGLE· · mm [StatusField]· · mode [StatusField]· · · ’ KEY_TOGGLE· · num [StatusField]· · pause [StatusField]tree x#.x· ref … #.x· y· · ref … #.x.z· z· · ref … #.x.y© Sub-tree of session space.© Spaces containing 'remote' refs.See also: refs.380 Namespaces.377 PF_keys.606 cols.26138


ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎtview(depth leaves) „ ##.tview tree© TreeView style from nested array.Nested [tree] is returned as the TreeView style pair: depth-vector, leaf-vector.Examples, See: TreesSee also: tfmt.130 tnest.130ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎGraphsÎÎÎÎÎÎGraphsÎÎÎÎÎÎA graph is a set of nodes called _vertices_, connected by links called _edges_.The graph is said to be "weighted" if each edge has an associated weight. Otherwise,it is said to be "unweighted". Similarly, a graph is said to be "directed"if each edge has an associated direction, otherwise it is said to be "undirected".For a discussion of weighted graphs, see: …wGraphs„.The following diagram represents a simple unweighted, directed graph.Graph "a".ÚÎÎÎÎÎA„ÎÎÎÎÌÛ Û Û 5 vertices: A B C D E‡ ‡ ÛB„ÎÎÎ…CÎÎÎÎ…D 8 edges: A…B A…C B…C C…B† Û C…D D…A D…E E…CÛ ‡ÀÎÎÎÎÎENotice that there is an edge from C to B, as well as from B to C.A directed graph is a generalisation of a tree. A tree is a graph where everyvertex has at most one edge leading to it. All trees are graphs, but not allgraphs are trees. This means that the data structures and <strong>functions</strong> over graphsin the following, also apply to trees.Graphs can be used to model many structures found in everyday life.dw Example of Graph Vertex Edge Note-- ---------------- ------ ---- ----dw A transportation system such as a subway. station track [a]uu A fishing net. knot twinedu The World Wide Web (a large graph!). page linkdu A game of chess. position move [b]du This workspace's internal memory structure. memory block pointeruu The "Six Degrees of Kevin Bacon" game. actor starred with [c]uu A "Word Ladder" puzzle. word letter swap [d]du Finding which stamps to stick on a letter. total value stick stamp [e]uu Who dated whom at college. student dateduu The Maze at Hampton Court. intersection path [f]du The "See also" links used in these notes. note see also [g]uu Adjacency of regions in a planar map. region adjancent to [h]dw A job scheduling network. task dependencydu British TV TeleText coloured "hot buttons". teletext page hot linkÛÛÛÀÎ w:weighted, u:unweighted.ÀÎÎ d:directed, u:undirected.[a] Most stylised maps of subway systems treat the network as an _unweighted_graph: there is no attempt to indicate the relative journey times or costs betweenstations. Subways can generally be represented by _undirected_ graphs unlessthey contain any one-way sections, as is the case with London's Picadillyline.139


[b] A Pawn can't move backwards, so its moves must be represented by a directedgraph. Notice that despite the Queen's versatility, her _undirected_ graph isrelatively _sparse_; at best she can move to only 27 out of 64 board positions.[c] In the The Six Degrees of Kevin Bacon game, start with any movie actor andtry to establish a connection with Kevin Bacon in six or fewer moves. An examplemight be: "Sigourney Weaver":Sigourney Weaver was in Copycat withHolly Hunter, who was in The Firm withGene Hackman, who was in The Birdcage withDianne Weist, who was in Footloose withKevin Bacon.... 4 degrees (edges), 5 vertices.[d] A Word Ladder puzzle has two n-letter words, drawn at the top and bottom ofa picture of a ladder. The task is to write n-letter words on each of the interveningrungs, so that adjacent words differ by exactly one letter. Some examplesmight be:Puzzle Solution Puzzle Solution Puzzle SolutionÃbeardÝ ÃbeardÝ ÃtoothÝ ÃtoothÝ ÃwaterÝ ÃwaterÝÃÎÎÎÎÎÝ ÃbearsÝ ÃÎÎÎÎÎÝ ÃsoothÝ ÃÎÎÎÎÎÝ ÃwaderÝÃÎÎÎÎÎÝ ÃbeamsÝ ÃÎÎÎÎÎÝ ÃslothÝ ÃÎÎÎÎÎÝ ÃwadesÝÃÎÎÎÎÎÝ ÃseamsÝ ÃÎÎÎÎÎÝ ÃsloshÝ ÃÎÎÎÎÎÝ ÃwaresÝÃÎÎÎÎÎÝ ÃshamsÝ ÃÎÎÎÎÎÝ ÃslushÝ ÃÎÎÎÎÎÝ ÃwarnsÝÃÎÎÎÎÎÝ ÃshameÝ ÃÎÎÎÎÎÝ ÃblushÝ ÃÎÎÎÎÎÝ ÃwainsÝÃshaveÝ ÃshaveÝ ÃbrushÝ ÃbrushÝ ÃÎÎÎÎÎÝ ÃwhinsÝÃwhineÝ ÃwhineÝ[e] See …stamps„.[f] See …hampton„[g] See example at the end of these notes.[h] See …konigsberg„ and …uksfr„Two common ways to represent graphs, are as a boolean "adjacency matrix" or asan "adjacency vector" of vectors:Adjacency matrix M has a 1 at M[i;j] if there is an edge from i to j.A B C D EÚÎÎÎÎÎÎÎÎÎA Û0 1 1 0 0B Û0 0 1 0 0C Û0 1 0 1 0D Û1 0 0 0 1E Û0 0 1 0 0© Adjacency matrix for graph "a" above.© Third row shows two edges: C…B C…D.Adjacency vector V is an index vector of all edges from i to iœV.(2 3) (3) (2 4) (1 5) (3) © Adjacency structure for graph "a".A B C D EÀÎÎÎÎÎÎÎÎÎÎÎÎÎ © Third item shows two edges: 3…(2 4): C…B C…D.The matrix representation is better for dense graphs (who didn't date whom), andthe vector representation, better for sparse graphs such as links across theWorld Wide Web. Workspace tube.dws models the subway systems of various citiesusing vector representation. In the case of the London Underground, which hasover 1,200 vertices, the graph is smaller (uses less workspace) than the equivalentmatrix representation, by a factor of 6.140


At either end of the sparse-to-dense continuum are the "order-N null graph", andthe "order-N complete graph". An order-N _null_ graph contains N vertices and 0edges (who dated whom in the cricket team). The order-N _complete_ graph containsN vertices and n*2 edges (who attended college with whom at college).A _complete_, weighted, directed graph may conveniently be represented just by a_matrix_ of each vertex-to-vertex cost. Function …assign„ expects such a representation.Functions to convert between matrix and vector forms of unweighted graphs:{{¾/¼½¾}¨‡¾}{³(¼½¾)°.¹¾}© vector from matrix form.© matrix from vector form.The following boolean <strong>functions</strong> indicate whether their graph argument is directed:{¾»³¾}{~^/{Ÿ/¸¹¨¾[¸œ¾]}°¾¨¼½¾}© _matrix_ form is directed.© _vector_ form is directed.and the following graph-valued <strong>functions</strong> remove the asymmetry of direction fromtheir argument graphs:{¾Ÿ³¾}{{¾/¼½¾}¨‡¾}°{¾Ÿ³¾}°{³(¼½¾)°.¹¾}© remove direction from _matrix_ form.© remove direction from _vector_ form.The latter function removes direction by converting vector to matrix and backagain. The following alternative is slower but uses less workspace and preservesthe order of edges within each vertex:{{(¸œ¾)ž(¸{Ÿ/¸¹¾}¨¾)/¼½¾}°¾¨¼½¾}© remove direction from vector form.A vector of the edge-pairs for a (vector form) undirected graph is given by:{‡[ŒIO]{(0, we can shorten this to:tcv„{¾{(¼½¾)•¸,¹¸œ¨›¾}¨›¾}ÿ­© vector transitive closure (SL).The "complement" of a graph has the same number of vertices but edges only wherethere were none before. For graphs that represent relationships between thevertices (who dated whom), the complement graph represents the inverse relationship(who didn't date whom). The complement of an adjacency _matrix_ is given by{~¾}, and of an adjacency _vector_ by {(›¼½¾)~¨¾}.We investigate only the _vector_ representation from here onwards.141


The <strong>functions</strong> in this workspace deal only with graph structure. There is no provisionfor vertices or edges to carry data other than that required to maintainthe graph. In real applications, such "labelling" of vertices and edges isrequired. This can easily be achieved by keeping a separate vector of suchvalues (URLs, names, distances-between-stations, ···), parallel with the graph.An index origin of 1 is assumed in the examples that follow. An origin 1 graphmay be converted to origin 0, just by subtracting 1.There are many useful and interesting questions that we can ask of, and transformationsthat we can apply to, a graph. The <strong>functions</strong> in this workspace are:Transformation/QuestionFunction----------------------- --------Insert/remove a vertex.…insnode„ …remnode„Insert/remove an edge.Rotate a vertex to the front of the graph.What is the shortest path from vertex A to vertex B?Produce a "spanning tree" of the shortest path from thestarting vertex to every other vertex in the graph.The simple function …stpath„ can be used to recovershortest vertex-to-vertex paths directly from thespanning tree. Note that there may be any number ofshortest paths between any two vertices.The path and spanning <strong>functions</strong> are based on a breadthfirstsearch of the graph. A stripped-down versionof this procedure returns a vector of the verticesencountered by radiating outwards from a startingvertex. See …bfs„.…inslink„ …remlink„…popnode„…path„…span„…stpath„…search„Examples:disp a„(2 3)(3)(2 4)(1 5)(3)Ú…ÎÎÂÎÂÎÎÎÂÎÎÎÂÎÌÛ2 3Û3Û2 4Û1 5Û3ÛÀ~Î…ÁÎÁ~Î…Á~Î…ÁÎÙ© simple origin-1 graph "a" (above).disp a inslink 5 1 © ··· with new link 5…1Ú…ÎÎÂÎÂÎÎÎÂÎÎÎÂÎÎÎÌÛ2 3Û3Û2 4Û1 5Û3 1ÛÀ~Î…ÁÎÁ~Î…Á~Î…Á~Î…Ù© As many of the <strong>functions</strong> take a graph as _left_ argument and a "modifier" on© the _right_, the "fold left" operator …foldl„ is useful:disp a inslink foldl (5 1) (3 5) © graph "a" with new links: 5…1, 3…5.Ú…ÎÎÂÎÂÎÎÎÎÎÂÎÎÎÂÎÎÎÌÛ2 3Û3Û2 4 5Û1 5Û3 1ÛÀ~Î…ÁÎÁ~ÎÎÎ…Á~Î…Á~Î…Ùdisp a remlink foldl (1 3) (2 3) © graph "a" without links: 1…3, 2…3.Ú…ÂÎÂÎÎÎÂÎÎÎÂÎÌÛ2Û0Û2 4Û1 5Û3ÛÀ…Á´Á~Î…Á~Î…ÁÎÙdisp a popnode 2Ú…ÂÎÎÎÂÎÎÎÂÎÎÎÂÎÌÛ3Û1 3Û1 4Û2 5Û3ÛÀÎÁ~Î…Á~Î…Á~Î…ÁÎÙ© pop second node to front.142


disp a popnode 5 © pop fifth node to front.Ú…ÂÎÎÎÂÎÂÎÎÎÂÎÎÎÌÛ4Û3 4Û4Û3 5Û2 1ÛÀÎÁ~Î…ÁÎÁ~Î…Á~Î…Ùdisp a popnode foldl ¼½aÚ…ÂÎÎÎÂÎÎÎÂÎÂÎÎÎÌÛ3Û5 1Û4 2Û3Û4 3ÛÀÎÁ~Î…Á~Î…ÁÎÁ~Î…Ù© reverse graph using 5 pops.© We can borrow some lines from the …kt„ Knight's Tour function, to generate© a graph (k) of the knight's moves on an ¾-sized chessboard.kt_graph„{© Graph of knight's moves on ¾-board.kdef„,0 1°.²1 ¯1°.,2 ¯2 © vector of relative knight's moves.net„(›,¼¾)•¨‡(¼¾)°.+kdef © absolute moves from each square.ŒIO+,¾°ƒ¨¨net-ŒIO© adjacency vector.}disp k„kt_graph 8 8© graph of knight's moves on an 8×8 board.Ú…ÎÎÎÎÂÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÂÎÎÎÎÎÂÎÎÛ11 18Û12 17 19Û9 13 18 20Û10 14 19 21Û11 15 20 22Û12 16 21 23Û13 22 24Û14 23Û3À~ÎÎÎ…Á~ÎÎÎÎÎÎ…Á~ÎÎÎÎÎÎÎÎ…Á~ÎÎÎÎÎÎÎÎÎ…Á~ÎÎÎÎÎÎÎÎÎ…Á~ÎÎÎÎÎÎÎÎÎ…Á~ÎÎÎÎÎÎ…Á~ÎÎÎ…Á~ν¨k(†,/k)64 336© number of vertices and edges.k path 1 2 © Knight's path from square 1 to 2.1 11 17 2© We can keep a vector of data associated with each vertex separate from, but© parallel with, the graph. In this case we might like a vector of board posit-© ion notations: A1 A2 ··· B1 B2 ··· H8. This vector may exist independently as© a workspace variable, or could be bound with a "translation" function.show„(,³8 8†ŒA°.,1‡ŒD)°{¸[¾]} © show board positions.show k path 1 9 © a shortest path from A1 to A2.A1 C2 B4 A2show k path 1 64 © ·· ·· ·· ·· to opposite corner.A1 C2 E1 G2 F4 G6 H8show k path 1 10 © ·· ·· ·· ·· to adjacent diagonalA1 C2 E1 D3 B2a span 1 © spanning tree for graph "a" from vertex 1.¯1 1 1 3 41 2(a span 1)stpath 2 © shortest path from 1 to 2 using span tree.143


disp (a span 1)°stpath¨¼½a © shortest path from 1 to each vertex.Ú…ÂÎÎÎÂÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÎÎÌÛ1Û1 2Û1 3Û1 3 4Û1 3 4 5ÛÀ…Á~Î…Á~Î…Á~ÎÎÎ…Á~ÎÎÎÎÎ…Ù© shortest path betweendisp †{(a span ¾)°stpath¨¼½a}¨¼½a © each pair of vertices.Ú…ÎÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÎÎ̇ 1 Û 1 2 Û 1 3 Û1 3 4Û1 3 4 5ÛÃ~ÎÎÎÎÎ…Ï~ÎÎÎ…Ï~ÎÎÎ…Ï~ÎÎÎ…Ï~ÎÎÎÎÎ…ÝÛ2 3 4 1Û 2 Û 2 3 Û2 3 4Û2 3 4 5ÛÃ~ÎÎÎÎÎ…Ï~ÎÎÎ…Ï~ÎÎÎ…Ï~ÎÎÎ…Ï~ÎÎÎÎÎ…ÝÛ 3 4 1 Û 3 2 Û 3 Û 3 4 Û 3 4 5 ÛÃ~ÎÎÎÎÎ…Ï~ÎÎÎ…Ï~ÎÎÎ…Ï~ÎÎÎ…Ï~ÎÎÎÎÎ…ÝÛ 4 1 Û4 1 2Û4 1 3Û 4 Û 4 5 ÛÃ~ÎÎÎÎÎ…Ï~ÎÎÎ…Ï~ÎÎÎ…Ï~ÎÎÎ…Ï~ÎÎÎÎÎ…ÝÛ5 3 4 1Û5 3 2Û 5 3 Û5 3 4Û 5 ÛÀ~ÎÎÎÎÎ…Á~ÎÎÎ…Á~ÎÎÎ…Á~ÎÎÎ…Á~ÎÎÎÎÎ…Ùk span 1 © knight's spanning tree from vertex 1.¯1 17 18 21 11 21 22 14 26 20 1 18 28 20 5 22 11 1 2 5 11 5 6 30 35 11 17 11 12k span 10 © spanning tree from vertex 10.11 19 20 10 20 21 24 14 19 ¯1 21 27 19 4 21 31 27 3 4 10 4 5 8 14 10 20 10 13 14© We can write a format operator to display the spanning tree:mtree„{ŒML„0© Matrix format of spanning tree.vfmt„¸¸© vertex format function.tree„¾© spanning tree.†''{© mix to char matrix.this„›¸,œvfmt ¾ © indented, formatted vertex.next„(tree=¾)/¼½tree © child vertices of current vertex ¾.next­«:this© childless: finished.dent„¸,'· ' © increased indent.this,†,/dent°’¨next © formatted sub-trees.}tree¼¯1© ... from starting vertex.}© Using the small graph "a" and {¾œŒa} as a vertex formatting function:disp aÚ…ÎÎÂÎÂÎÎÎÂÎÎÎÂÎÌÛ2 3Û3Û2 4Û1 5Û3ÛÀ~Î…ÁÎÁ~Î…Á~Î…ÁÎÙ© graph "a".{¾œŒa}mtree a span 3 © spanning tree from vertex 3.C· B· D· · A· · E© The Word Ladder puzzle:wds„4œwords© vector of 4-letter words.wds[10?½wds]© random selection from 4-words.mack minx nest gits racy clue crib lean them browgph„{{¾/¼½¾}¨‡¾°.{1=+/¸¬¾}¾}wdswds[gph path wds¼'beer' 'wine']beer bear bead bend bind wind wine© graph of 1-letter changes.© beer … wine144


wds[gph path wds¼'wine' 'beer'] © wine … beerwine dine dint dent bent beet beerwds[gph path wds¼'lead' 'gold']lead load goad gold© lead … gold© The following expression returns a graph of the "See also:" links© in this workspace:notes.({¾°{¸{(1¹¨¸º¨›¾)/¼½¸}{(Ÿ/'See also:'º¾)š¾}ŒFMT–¾}¨¾}~°' '¨‡ŒNL 2)© Cubes in ¾-space© ----------------©© An ¾-cube is an undirected graph with 2*¾ vertices and ¾×2*¾-1 edges.©© We can make an ¾-cube by joining the corresponding© vertices of a pair of (¾-1)-cubes.© .----------.© /|\ /|\© / | \ / | \© .----------. .--•--.----.--•--.© /| /| |\ | /| |\ | /|© / | / | | \'š-•----•-'/ |© . .----------. .----------. | | /.-•----•-š.\ |© | | | | | | | |/ | \| |/ | \|© | | | | '-------|--' '--•--'----'--•--'© | | | | / | / \ | / \ | /© | | | |/ |/ \|/ \|/© ' ' '----------' '----------' '----------'© † † † † †© Û Û Û Û Û© Û Û Û Û ÀÎÎ 4-cube© Û Û Û Û (projected onto 2-space).© Û Û Û Û© Û Û Û ÀÎÎ 3-cube (projected onto 2-space).© Û Û Û© Û Û ÀÎÎ 2-cube (square)© Û Û© Û ÀÎ 1-cube (line)© Û© ÀÎ 0-cube (point)© This function returns an ¾-cube graph:cube„{© ¾-cube.‡{ © split simple matrix:0=¾:1 0½0© 0-cube: point.(2*¾-1){© number of vertices.(¾®¾+¸),¸²¼2׸ © ¾-cube from}’ ¾-1 © ¾-1-cube.}¾}Ú…ÌÛ0ÛÀ´Ùdisp cube 0© point.disp cube 1Ú…ÂÎÌÛ2Û1ÛÀ…Á…Ù© line.145


disp cube 2 © square.Ú…ÎÎÂÎÎÎÂÎÎÎÂÎÎÎÌÛ2 3Û1 4Û4 1Û3 2ÛÀ~Î…Á~Î…Á~Î…Á~Î…Ùdisp cube 3© regular 3-cube.Ú…ÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÌÛ2 3 5Û1 4 6Û4 1 7Û3 2 8Û6 7 1Û5 8 2Û8 5 3Û7 6 4ÛÀ~ÎÎÎ…Á~ÎÎÎ…Á~ÎÎÎ…Á~ÎÎÎ…Á~ÎÎÎ…Á~ÎÎÎ…Á~ÎÎÎ…Á~ÎÎÎ…Ùdisp cube 4© hypercube.Ú…ÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÛ2 3 5 9Û1 4 6 10Û4 1 7 11Û3 2 8 12Û6 7 1 13Û5 8 2 14Û8 5 3 15Û7 6 4 16Û10 11 13À~ÎÎÎÎÎ…Á~ÎÎÎÎÎÎ…Á~ÎÎÎÎÎÎ…Á~ÎÎÎÎÎÎ…Á~ÎÎÎÎÎÎ…Á~ÎÎÎÎÎÎ…Á~ÎÎÎÎÎÎ…Á~ÎÎÎÎÎÎ…Á~ÎÎÎÎÎÎÎ{(cube ¾)path 1,2*¾}10 © a path between opposite corners of a 10-cube.1 513 769 897 961 993 1009 1017 1021 1023 1024See also: wGraphs.163 bfs.531 scc.148See also: inslink.151 insnode.150 remlink.152 remnode.150 popnode.152See also: search.153 path.153 span.155 stpath.159 search.153See also: alists.8 foldl.45See also: stamps.314 hampton.545 konigsberg.548 uksfr.595See also: assign.144 kt.457 X.160ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎassignbmat „ ##.assign costs© Hungarian method cost assignment.[assign] is a classic algorithm implemented in the D style. H.W.Kuhn publisheda pencil and paper version in 1955, which was followed by J.R.Munkres' executableversion in 1957. The algorithm is sometimes referred to as the "Hungarianmethod".The method indicates an optimal assignment of a set of resources to a set ofrequirements, given a "cost" of each potential match. Examples might be theallocation of workers to tasks; the supply of goods by factories to warehouses;or the matching of brides with grooms. The function takes a cost matrix as argumentand returns a boolean assignment matrix result.The following table shows an optimal assignment of factories F, G, H to warehousesW, X, Y, given that the cost of transportation from F to W is 72 units, Fto X is 99 units, ···, G to W is 23 units, ··· and so on.W X YÚÎÎÎÎÂÎÎÎÎÂÎÎÎÎÌF Û[72]Û 99 Û 88 Û Minimum-cost assignment marked [.]:ÃÎÎÎÎÏÎÎÎÎÏÎÎÎÎÝG Û 23 Û 30 Û[35]Û Factory F supplies warehouse W,ÃÎÎÎÎÏÎÎÎÎÏÎÎÎÎÝ ·· G ·· ·· ·· ·· Y,H Û 51 Û[59]Û 84 Û ·· H ·· ·· ·· ·· X.ÀÎÎÎÎÁÎÎÎÎÁÎÎÎÎÙNotice that if the problem requires maximizing a benefit, rather than minimizinga cost, then a negative cost matrix is used. See below for an example.Technical notes:Munkres' algorith may be described in words as follows:Step 0:Ensure the costs matrix has at least as many rows as columns, by appending extra0-item rows if necessary. Go to Step 1.146


Step 1:Subtract the smallest item in each row from the row. Go to Step 2.Step 2:Select a set of "independent" zeros in the matrix and mark them with a star (*).To do this, star leading zeros in each row and column, ignoring rows and columnsalready containing stars; repeat this process until apart from ignored rows andcolumns, no more zeros remain. Go to Step 3.Step 3:Draw a line through (cover) each column containing a starred zero. If all columnsare covered, the starred zeros represent an optimal assignment. In thiscase, return a boolean matrix with the positions of the stars, as result. Otherwise,go to Step 4.Step 4:Find an uncovered zero. If there is none, go to Step 6 passing the smallest uncoveredvalue as a parameter. Otherwise, mark the zero with a prime (') and callit P0. If there is a starred zero (S1) in the row containing P0, cover this rowand uncover the column containing S1, then repeat Step 4. Otherwise, (if thereis no starred zero in P0's row) go to Step 5.Step 5:Find a path through alternating primes and stars. Starting with the uncoveredprime (P0) found in Step 4, find a star S1 (if any) in its column. Then find aprime P2 (there must be one) in S1's row, followed by a star S3 (if any) inP2's column, ··· and so on until a prime (Pn) is found that has no star in itscolumn. In the series P0, S1, P2, S3, ··· Pn, unstar each starred zero Si andstar each primed zero Pj. Finally, unprime all primed zeros in the matrix, uncoverall rows and columns. Go to Step 3.Step 6:Add the minimum cost value passed from Step 4 to each twice-covered (row andcolumn covered) item, and subtract it from each uncovered item. Preserving allstars, primes and covering lines, go to Step 4.The approach uses a rather convoluted "stepping algorithm", which can be representedas a flowchart:step0 after step:0, go to step:1.‡Ûstep1 after step:1, go to step:2.‡Ûstep2 after step:2, go to step:3.‡ÛÚ…step3ÎÎÎ… after step:3, go to step:4 or exit.Û ÛÚÎÛ΅·΄ÎÎÎÌÛ Û Û †Û Û step4Î…ÎÝ after step:4, go to step:4 or step:5 or step:6.† † Û ‡Û Û ‡Î„ÎÌ ÛÛ Û Û Û ÛÛ ÀÎstep5ÎÙ Û after step:5, go to step:5 or step:3.† Ú΄ÎÎÎÙÛ ‡Û step6 after step:6, go to step:4.Û ‡ÀÎ΄ÎÎÙ147


The algorithm is implemented by coding each step as a separate sub-function, andtail-calling from one step to the next. This is as close as we come to branchingin D!Notice that nearly all of the primitive and defined <strong>functions</strong> in [##.assign]deal in matrices - a tribute to <strong>APL</strong>'s native array-handling.The state is represented by 3 matrices at each step:costs: the current cost matrix.zeros: marked zeros: 0-not a zero, 1-unmarked zero, 2-starred, 3-primed.covers: 0-uncovered item, 1-item covered by horizontal (row covering) line,2-item covered by vertical (column covering) line, 3-item covered byboth horizontal and vertical lines.In addition, step 5 takes a boolean matrix left argument, indicating the positionof the first primed zero.Using the example cost matrix from above, the following trace shows the state ofplay between each step Î[n]Î.ÚÎÎÎÎÎÎÎÎÎÎÌ ÚÎÎÎÎÎÎÎÎÎÎÌ ÚÎÎÎÎÎÎÎÎÎÎÌ ÚÎÎÎÎÎÎÎÎÎÎÌ ÚÎÎÎÎÎÎÎÎÎÎÌÛ72 99 88Û Û 0 27 16Û Û*0 27 16Û Û*0Û 27 16Û Û*0Û 27 16ÛÛ23 30 35Ã[1]Ý 0 7 12Ã[2]Ý 0 7 12Ã[3]Ý 0Û 7 12Ã[4]Ý 0Û 7 12Ã[6]η·Û51 59 84Û Û 0 8 33Û Û 0 8 33Û Û 0Û 8 33Û Û 0Û 8 33Û(7)ÀÎÎÎÎÎÎÎÎÎÎÙ ÀÎÎÎÎÎÎÎÎÎÎÙ ÀÎÎÎÎÎÎÎÎÎÎÙ ÀÎÎÎÎÎÎÎÎÎÎÙ ÀÎÎÎÎÎÎÎÎÎÎÙÚÎÎÎÎÎÎÎÎÎÎÌ ÚÎÎÎÎÎÎÎÎÎÎÌ ÚÎÎÎÎÎÎÎÎÎÎÌ ÚÎÎÎÎÎÎÎÎÎÎÌ ÚÎÎÎÎÎÎÎÎÎÎÌÛ*0Û 20 9Û Û*0Û 20 9Û Û*0 20 9Û Û*0Û 20Û 9Û Û*0Û 20Û 9Û··Ý 0Û 0 5Ã[4]Ý 0Û['0] 5Ã[5]Ý 0 *0 5Ã[3]Ý 0Û *0Û 5Ã[4]Ý 0Û *0Û 5Ã[6]η·Û 0Û 1 26Û Û 0Û 1 26Û Û 0 1 26Û Û 0Û 1Û 26Û Û 0Û 1Û 26Û(5)ÀÎÎÎÎÎÎÎÎÎÎÙ ÀÎÎÎÎÎÎÎÎÎÎÙ ÀÎÎÎÎÎÎÎÎÎÎÙ ÀÎÎÎÎÎÎÎÎÎÎÙ ÀÎÎÎÎÎÎÎÎÎÎÙÚÎÎÎÎÎÎÎÎÎÎÌ ÚÎÎÎÎÎÎÎÎÎÎÌ ÚÎÎÎÎÎÎÎÎÎÎÌ ÚÎÎÎÎÎÎÎÎÎÎÌ ÚÎÎÎÎÎÎÎÎÎÎÌÛ*0Û 20Û 4Û Û*0Û 20 4Û Û*0Û 19 3Û Û*0Û 19 3Û Û*0 19 3Û··Ý 0Û *0Û 0Ã[4]Ý 0ÏÎ*0ÎÎ'0Ã[6]ÝÎ1ÏÎ*0ÎÎ'0Ã[4]ÝÎ1Ï[*0]['0Ã[5]Ý 1 0 *0Ã[3]η·Û 0Û 1Û 21Û Û 0Û 1 21Û(1)Û 0Û 0 20Û Û 0Û['0] 20Û Û 0 *0 20ÛÀÎÎÎÎÎÎÎÎÎÎÙ ÀÎÎÎÎÎÎÎÎÎÎÙ ÀÎÎÎÎÎÎÎÎÎÎÙ ÀÎÎÎÎÎÎÎÎÎÎÙ ÀÎÎÎÎÎÎÎÎÎÎÙÚÎÎÎÎÎÎÎÎÎÎÌÛ 1 0 0Û··Ý 0 0 1ÛÛ 0 1 0ÛÀÎÎÎÎÎÎÎÎÎÎÙReferences:H.W.Kuhn, The Hungarian method for the assignment problem, Naval ResearchLogistics Quarterly, 2 (1955), pp. 83-97.J.R.Munkres, Algorithms for the assignment and transportation problems,J. SIAM 5 (1957) 32-38.Examples:costs72 99 8823 30 3551 59 84© example cost matrix.1 0 00 0 10 1 0assign costs© minimum cost assignment.148


0 1 01 0 00 0 1assign -costs © maximum benefit assignment.166206{+/+/¾×assign ¾} costs{+/+/-¾×assign ¾} -costscosts„?6 10½50© total minimum cost.© total maximum benefit.© new 6×10 cost matrix.costs7 38 23 27 11 3 34 34 47 2026 42 2 3 27 34 1 20 4 2135 30 47 43 27 5 33 21 36 4639 14 3 37 17 32 38 50 19 1350 37 38 33 4 32 45 14 22 3924 12 14 18 9 25 45 46 4 46assign costs1 0 0 0 0 0 0 0 0 00 0 0 0 0 0 1 0 0 00 0 0 0 0 1 0 0 0 00 0 1 0 0 0 0 0 0 00 0 0 0 1 0 0 0 0 00 0 0 0 0 0 0 0 1 0{¾×assign ¾} costs7 0 0 0 0 0 0 0 0 00 0 0 0 0 0 1 0 0 00 0 0 0 0 5 0 0 0 00 0 3 0 0 0 0 0 0 00 0 0 0 4 0 0 0 0 00 0 0 0 0 0 0 0 4 0© minimum cost assignment.© cost per assignment.24{+/+/¾×assign ¾} costs© total minimum cost.assign -costs0 0 0 0 0 0 0 0 1 00 1 0 0 0 0 0 0 0 00 0 1 0 0 0 0 0 0 00 0 0 0 0 0 0 1 0 01 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 1{-¾×assign ¾} -costs0 0 0 0 0 0 0 0 47 00 42 0 0 0 0 0 0 0 00 0 47 0 0 0 0 0 0 00 0 0 0 0 0 0 50 0 050 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 46© maximum benefit assignment.© cost per assignment.282{+/+/-¾×assign ¾} -costscosts„?10 6½50© total maximum benefit.© new 10×6 cost matrix149


Technical notes:Tarjan's algorithm is often presented in a procedural language, using an innerand outer loop to mutate the state of a global vector (C), which accumulates thestrongly connected components. In addition, there is a global counter (N) of theorder in which the vertices are visited by the depth-first search; and a list orstack (P), the current path from the root.In contrast, as an exercise in pure functional programming, [scc] maintains nostate: arrays are named only once and are not mutated. The equivalent of the twoloops can be seen as two (/) reductions in the last two lines of the function.Values for: vertex number (N); component vector (C); and path-from-root (P); arearguments to the reductions, and their successor values: N‘, C‘ and P‘ are returnedas results.Notice that both of the lines of code that define a refined component vector C‘:andC‘„(c×n)+C×~nC‘„C+N‘×X=¸© reduced component set.© component numbers.are examples of merges: THIS array but with THOSE items at THESE positions. Theprovision of a primitive …merge„ operator might simplify these expressions.Condensation------------Contracting each strongly connected component into a single vertex yields adirected acyclic graph (DAG), the "condensation of G". The following functionreturns a 2-vector pair: the condensation graph, together with a correspondingvector of condensed vertices from the original graph. Notice the use of the keyoperator, which is introduced as primitive in <strong>Dyalog</strong> V14.con„{ © Condensation of graph ¾.c„scc ¾© strongly connected componentsv„{›¾}key c © component-grouped vertex indices e„c{›¾}key ¾ © .. .. edges x„ž¨(¹¨e)~¨v © out-of-component edgesm„‡Ÿ/¨x°.¹v © masks of remote verticesg„m/¨›¼½v © condensed DAGg v© ... and contracted vertices}Examples:© 1------>2------>34 © Wikipedia© ^ /| | ^© | / | | |© | / | | |© |À Ÿ Ÿ Ÿ© 5------>67


© 1


disp a remnode foldl 1 © remove first vertex from "a".Ú…ÂÎÎÎÂÎÂÎÌÛ2Û1 3Û4Û2ÛÀ…Á~Î…Á…Á…Ùdisp a remnode foldl 1 1Ú…ÂÎÂÎÌÛ2Û3Û1ÛÀ…Á…Á…Ùdisp a remnode foldl 5 4Ú…ÎÎÂÎÂÎÌÛ2 3Û3Û2ÛÀ~Î…Á…Á…Ùdrop„{¸ remnode foldl ¾/¼1}disp a drop 1Ú…ÂÎÎÎÂÎÂÎÌÛ2Û1 3Û4Û2ÛÀ…Á~Î…Á…Á…Ùdisp a drop 2Ú…ÂÎÂÎÌÛ2Û3Û1ÛÀ…Á…Á…Ù© remove first two vertices from "a".© remove last two vertices from "a".© vertex dropping function.© drop 1 vertex from "a".© drop 2 vertices from "a".Ú´ÌÛ0ÛÀ´Ùdisp a drop 5© drop 5 vertices from "a".See also: Graphs.137 insnode.150 popnode.152 remlink.152ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎinslinkgraph „ graph ##.inslink (from to) © Insert edge ¾ in graph ¸.[inslink] takes an unweighted graph as left argument and returns a new graphwith an extra edge defined by the right argument pair.Examples:disp aÚ…ÎÎÂÎÂÎÎÎÂÎÎÎÂÎÌÛ2 3Û3Û2 4Û1 5Û3ÛÀ~Î…ÁÎÁ~Î…Á~Î…ÁÎÙ© graph "a".disp a inslink 5 1 © ··· with new link 5…1Ú…ÎÎÂÎÂÎÎÎÂÎÎÎÂÎÎÎÌÛ2 3Û3Û2 4Û1 5Û3 1ÛÀ~Î…ÁÎÁ~Î…Á~Î…Á~Î…Ùdisp a inslink foldl (5 1) (3 5)Ú…ÎÎÂÎÂÎÎÎÎÎÂÎÎÎÂÎÎÎÌÛ2 3Û3Û2 4 5Û1 5Û3 1ÛÀ~Î…ÁÎÁ~ÎÎÎ…Á~Î…Á~Î…Ù© insert links: 5…1, 3…5.See also: Graphs.137 remlink.152 insnode.150153


ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎremlinkgraph „ graph ##.remlink (from to) © Remove edge ¾ from graph ¸.Returns a new graph with the target edge removed.Examples:disp aÚ…ÎÎÂÎÂÎÎÎÂÎÎÎÂÎÌÛ2 3Û3Û2 4Û1 5Û3ÛÀ~Î…ÁÎÁ~Î…Á~Î…ÁÎÙdisp a remlink 2 3Ú…ÎÎÂÎÂÎÎÎÂÎÎÎÂÎÌÛ2 3Û0Û2 4Û1 5Û3ÛÀ~Î…Á´Á~Î…Á~Î…ÁÎÙ© graph "a".© ... with link 2…3 removed.See also: Graphs.137 inslink.151 remnode.150ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎpopnodegraph „ graph ##.popnode vertex © Pop vertex ¾ to head of graph ¸.Returns a new graph with the indicated vertex moved to the front. The new graphis functionally identical (isomorphic) to the original. This simple operationcan be used to accomplish any ordering of the graph's vertices.Examples:disp aÚ…ÎÎÂÎÂÎÎÎÂÎÎÎÂÎÌÛ2 3Û3Û2 4Û1 5Û3ÛÀ~Î…ÁÎÁ~Î…Á~Î…ÁÎÙdisp a popnode 2Ú…ÂÎÎÎÂÎÎÎÂÎÎÎÂÎÌÛ3Û1 3Û1 4Û2 5Û3ÛÀÎÁ~Î…Á~Î…Á~Î…ÁÎÙdisp a popnode 5Ú…ÂÎÎÎÂÎÂÎÎÎÂÎÎÎÌÛ4Û3 4Û4Û3 5Û2 1ÛÀÎÁ~Î…ÁÎÁ~Î…Á~Î…Ùdisp popnode a foldl ¼½aÚ…ÂÎÎÎÂÎÎÎÂÎÂÎÎÎÌÛ3Û5 1Û4 2Û3Û4 3ÛÀÎÁ~Î…Á~Î…ÁÎÁ~Î…Ùgrot„{v„½¸rv„(v|-¾)½va popnode foldl rv}disp a grot 3Ú…ÎÎÂÎÂÎÎÎÂÎÂÎÎÎÌÛ3 2Û5Û4 5Û5Û4 1ÛÀ~Î…ÁÎÁ~Î…ÁÎÁ~Î…Ùdisp a grot ¯1Ú…ÂÎÎÎÂÎÂÎÎÎÂÎÎÎÌÛ4Û3 4Û4Û3 5Û2 1ÛÀÎÁ~Î…ÁÎÁ~Î…Á~Î…Ù© graph "a".© pop second node to front.© pop fifth node to front.© reverse graph using 5 pops.© graph "rotation".© number of vertices.© (v v v) pops© rv pops of last vertex.© 3-rotation of graph "a".© ¯1-rotation of graph "a".154


See also: Graphs.137 insnode.150 remnode.150ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎsearchvvec „ graph ##.search from © Breadth-first search of graph ¸.Returns a vector of vertices visited in a breadth-first search of graph ¸,starting from vertex ¾.Technical notes:Breadth-first search (BFS) radiates outwards from the starting vertex, visitingeach vertex that is accessible from it. This coding differs slightly from theclassic breadth-first search, see …bfs„.Examples:disp aÚ…ÎÎÂÎÂÎÎÎÂÎÎÎÂÎÌÛ2 3Û3Û2 4Û1 5Û3ÛÀ~Î…ÁÎÁ~Î…Á~Î…ÁÎÙ© graph "a".disp a search 3 © vertices in a breadth-first search from vertex 3.3 2 4 1 5k search 1© breadth-first search of knight's move graph. …kt„1 11 18 5 17 21 26 28 3 12 33 35 15 20 22 2 27 34 4 6 31 36 38 9 41 43 13 45 2950 25 52 30 32 10 14 37 7 16 39 19 42 44 49 51 23 46 48 53 55 58 60 62 2440 47 8 54 56 57 59 61 63 64See also: Graphs.137 bfs.531 path.153 span.155 dfspan.156 kt.457 trav.130ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎpathvvec „ graph ##.path (fm to) © Shortest path between ¾ in graph ¸.Returns a vector of vertices that represent a shortest path between the givenend points. Many paths may be of the _same_ length, but none is shorter. Noticethat the reverse path (to fm) may or may not be the reverse of the forward path.More generally, either or both of [fm] and [to] may be a _vector_ of vertices.In this case, [path] finds _a_ shortest path between the two sets, guaranteeingthat no shorter path exists from any vertex in [fm] to any vertex in [to].Technical notes:The function uses the same method as for a spanning tree, but stops as soon asit encounters a destination vertex. The path is then extracted from the treeusing the …stpath„ method.This coding differs slightly from classic breadth-first search, see …bfs„.Examples:disp aÚ…ÎÎÂÎÂÎÎÎÂÎÎÎÂÎÌÛ2 3Û3Û2 4Û1 5Û3ÛÀ~Î…ÁÎÁ~Î…Á~Î…ÁÎÙ© graph "a".4 1 33 4a path 4 3 © a shortest path from 4 to 3.a path 3 4 © a shortest path from 3 to 4.155


4 1 2a path 4, 2 3 © a shortest path from 4 to 2 or 3.disp k© graph of chess knight's moves. See …kt„Ú…ÎÎÎÎÂÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÂÎÎÎÎÎÂÎÎÛ11 18Û12 17 19Û9 13 18 20Û10 14 19 21Û11 15 20 22Û12 16 21 23Û13 22 24Û14 23Û3À~ÎÎÎ…Á~ÎÎÎÎÎÎ…Á~ÎÎÎÎÎÎÎÎ…Á~ÎÎÎÎÎÎÎÎÎ…Á~ÎÎÎÎÎÎÎÎÎ…Á~ÎÎÎÎÎÎÎÎÎ…Á~ÎÎÎÎÎÎ…Á~ÎÎÎ…Á~Îk path 1 641 11 5 15 30 47 64board„{(¼¸)¹Œio+‡³¸‚¾-Œio}© knight's shortest path to opposite corner.© crude display of path.8 8 board k path 1 64 © one shortest path.1 0 0 0 1 0 0 00 0 1 0 0 0 1 00 0 0 0 0 0 0 00 0 0 0 0 1 0 00 0 0 0 0 0 0 00 0 0 0 0 0 1 00 0 0 0 0 0 0 00 0 0 0 0 0 0 18 8 board (²¨k) path 1 64 © reverse edge order => distinct path.1 0 0 0 0 0 0 00 0 0 0 0 0 0 00 1 0 0 0 0 0 00 0 0 0 0 0 0 00 0 1 0 0 0 0 00 0 0 0 0 0 1 00 0 0 1 0 0 0 00 0 0 0 0 1 0 1rand„{¾[{¾?¾}½¾]}© randomize vector.8 8 board (rand¨k) path 1 64 © random edge order => distinct path.1 0 0 0 0 0 0 00 0 1 0 0 0 0 00 0 0 0 0 0 0 00 1 0 0 0 0 0 00 0 0 1 0 0 0 00 0 0 0 0 0 1 00 0 0 0 1 0 0 00 0 0 0 0 0 0 18 8 board (rand¨k) path 1 64 © ... and again.1 0 0 0 0 0 0 00 0 1 0 0 0 0 00 0 0 1 0 0 0 00 1 0 0 0 1 0 00 0 0 0 0 0 0 00 0 0 0 0 0 1 00 0 0 0 0 0 0 00 0 0 0 0 0 0 18 8 board (rand¨k) path 1 64 © ... and again.1 0 0 0 0 0 0 00 0 0 0 0 0 0 00 1 0 0 0 0 0 00 0 0 0 0 0 0 00 0 1 0 0 0 0 00 0 0 0 0 0 1 00 0 0 1 0 0 0 00 0 0 0 0 1 0 1156


See also: Graphs.137 bfs.531 stpath.159 span.155 search.153 kt.457ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎspantree „ graph ##.span fm © Breadth-first span tree for graph ¸ from vertex ¾.Returns a tree that, starting from the given vertex, spans all accessible verticesof the graph "breadth-first". The tree has the property that it has theleast depth possible: no spanning tree exists that has a shorter path from itsroot to any vertex.More generally, [fm] may be a _vector_ of vertices, in which case the breadthfirstsearch starts in parallel from each given vertex.The tree is returned in compact form: each item of the vector, with the exceptionof the root item, is the index of the tree node's parent node.The following operator may be used to display the tree in an indented format.The function operand takes a vertex number and returns a label:mtree„{ŒML„0© Matrix format of spanning tree.vfmt„¸¸© vertex format function.tree„¾© spanning tree.†''{© mix to char matrix.this„›¸,œvfmt ¾ © indented, formatted vertex.next„(tree=¾)/¼½tree © child vertices of current vertex ¾.next­«:this© childless: finished.dent„¸,'· ' © increased indent.this,†,/dent°’¨next © formatted sub-trees.}tree¼¯1© ... from starting vertex.}... and this function displays the tree in list format:ltree„{© List format of spanning tree.tree„¾© spanning tree.bkt„{'[',¾,']'}© bracket.sep„{†{¸,', ',¾}/¾} © comma-separate.{ © radiate outwards from root:next„(tree=¾)/¼½tree © nodes that point to this one.next­«:•¾© none: finished.bkt sep(›•¾),’¨next © node followed by sub-trees.}¾¼¯1© starting from root.}Technical notes:This coding differs slightly from classic breadth-first search, see …bfs„.Examples:© Graph "a".© ÚÎÎÎÎÎ1„ÎÎÎÎÌ 5 vertices: 1 2 3 4 5© Û Û Û© ‡ ‡ Û 8 edges: 1…2 1…3© 2„ÎÎÎ…3ÎÎÎÎ…4 2…3© † Û 3…2 3…4© Û ‡ 4…1 4…5© ÀÎÎÎÎÎ5 5…3a„(2 3)(3)(2 4)(1 5)(3)show„{†•¨(¼½¾),¨'…',¨¾}© simple origin-1 graph.© show graph.157


show a © graph "a".1 … 2 32 … 33 … 2 44 … 1 55 … 3a span 1 © spanning tree from vertex 1.¯1 1 1 3 4a span 3 © spanning tree from vertex 3.4 3 ¯1 3 4•mtree a span 3 © formatted spanning tree from vertex 3.3· 2· 4· · 1· · 5ltree a span 3 © list-format spanning tree from vertex 3.[3, 2, [4, 1, 5]]†{ltree a span ¾}¨¼½a[1, 2, [3, [4, 5]]][2, [3, [4, 1, 5]]][3, 2, [4, 1, 5]][4, [1, 2, 3], 5][5, [3, 2, [4, 1]]]© list format for all of a's span trees.gx„(2 5)(1 3 6)(2 4 7)(3 8)(1 6 9)(2 5)(3 8)(4 7 12)(5 10 13)(9 14)(12 15)(8© graph gx: breadth-first visiting sequence:©© 1ÎÎÎÎÎÎÎ2ÎÎÎÎÎÎÎ3ÎÎÎÎÎÎÎ4 [1]ÎÎÎÎÎ[2]ÎÎÎÎÎ[3]ÎÎÎÎÎ[4] c.f. …dfspan„© Û Û Û Û Û Û© Û Û Û Û Û Û© Û Û Û Û Û Û© 5ÎÎÎÎÎÎÎ6 7ÎÎÎÎÎÎÎ8 [2]ÎÎÎÎÎ[3] [4]ÎÎÎÎÎ[5]© Û Û Û Û© Û Û Û Û© Û Û Û Û© 9ÎÎÎÎÎÎ10 11ÎÎÎÎÎÎ12 [3]ÎÎÎÎÎ[4] [7] [6]© Û Û Û Û Û Û© Û Û Û Û Û Û© Û Û Û Û Û Û© 13ÎÎÎÎÎÎ14ÎÎÎÎÎÎ15ÎÎÎÎÎÎ16 [4]ÎÎÎÎÎ[5]ÎÎÎÎÎ[6]ÎÎÎÎÎ[7]gx span 1¯1 1 2 3 1 5 3 7 5 9 15 8 9 13 14 15See also: Graphs.137 bfs.531 stpath.159 path.153 search.153 dfspan.156ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎdfspantree „ graph ##.dfspan from © Depth-first spanning tree: graph ¸ from vertex ¾.Returns a tree that, starting from the given vertex, spans all accessible verticesof the graph. The vertices are visited in depth-first order, this means thatat each vertex, all vertices reachable from the first edge are visited beforethose reachable from any other edge. Compare with the breadth-first search in…span„ and …bfs„.…stpath„ may be used to extract paths from the resulting spanning tree.158


Examples:show„{††,¨/(¼½¾)'-'¾}g„{‡³†1 ¯1²¨›¾}¼10© show graph.© "polygon" graph.show g1 - 2 102 - 3 13 - 4 24 - 5 35 - 6 46 - 7 57 - 8 68 - 9 79 - 10 810 - 1 9show Œ„g dfspan 1¯1 1 2 3 4 5 6 7 8 91 - ¯12 - 13 - 24 - 35 - 46 - 57 - 68 - 79 - 810 - 9show Œ„g span 1¯1 1 2 3 4 7 8 9 10 11 - ¯12 - 13 - 24 - 35 - 46 - 77 - 88 - 99 - 1010 - 1g„{¾°~¨¾}¼8© depth-first search.© compare with breadth-first search.© order-8 complete graph.show g1 - 2 3 4 5 6 7 82 - 1 3 4 5 6 7 83 - 1 2 4 5 6 7 84 - 1 2 3 5 6 7 85 - 1 2 3 4 6 7 86 - 1 2 3 4 5 7 87 - 1 2 3 4 5 6 88 - 1 2 3 4 5 6 7g dfspan 1¯1 1 2 3 4 5 6 7g span 1¯1 1 1 1 1 1 1 1© depth-first search,© compare with breadth-first search.gx„(2 5)(1 3 6)(2 4 7)(3 8)(1 6 9)(2 5)(3 8)(4 7 12)(5 10 13)(9 14)(12 15)(8159


© graph gx, vertex numbers: depth-first visiting sequence:©© 1ÎÎÎÎÎÎÎ2ÎÎÎÎÎÎÎ3ÎÎÎÎÎÎÎ4 [1]ÎÎÎÎÎ[2]ÎÎÎÎÎ[3]ÎÎÎÎÎ[4] c.f. …span„© Û Û Û Û Û© Û Û Û Û Û© Û Û Û Û Û© 5ÎÎÎÎÎÎÎ6 7ÎÎÎÎÎÎÎ8 [13]ÎÎÎÎ[14] [6]ÎÎÎÎÎ[5]© Û Û Û Û© Û Û Û Û© Û Û Û Û© 9ÎÎÎÎÎÎ10 11ÎÎÎÎÎÎ12 [12]ÎÎÎÎ[11] [8]ÎÎÎÎÎ[7]© Û Û Û Û Û Û Û© Û Û Û Û Û Û Û© Û Û Û Û Û Û Û© 13ÎÎÎÎÎÎ14ÎÎÎÎÎÎ15ÎÎÎÎÎÎ16 [15] [10]ÎÎÎÎ[9]ÎÎÎÎÎ[16]show Œ„gx dfspan 1¯1 1 2 3 9 5 8 4 10 14 12 8 9 15 11 151 - ¯12 - 13 - 24 - 35 - 96 - 57 - 88 - 49 - 1010 - 1411 - 1212 - 813 - 914 - 1515 - 1116 - 15See also: Graphs.137 bfs.531 stpath.159 span.155ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎstdistsdvec „ ##.stdists tree© Spanning tree path lengths.Returns vector [dvec] of distances from the root to each vertex in the spanning[tree].Examples:©© Graph "a".© ÚÎÎÎÎÎ1„ÎÎÎÎÌ 5 vertices: 1 2 3 4 5© Û Û Û© ‡ ‡ Û 8 edges: 1…2 1…3© 2„ÎÎÎ…3ÎÎÎÎ…4 2…3© † Û 3…2 3…4© Û ‡ 4…1 4…5© ÀÎÎÎÎÎ5 5…3a„(2 3)(3)(2 4)(1 5)(3)© simple origin-1 graph.a span 1¯1 1 1 3 4stdists a span 1 © distances from vertex 1.0 1 1 2 3See also: span.155 stpath.159 stpaths.160 Graphs.137160


ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎstpathvvec „ tree ##.stpath to © Path through spanning tree ¸ to vertex ¾.Given a spanning tree from one vertex of a graph, returns a vector of verticesthat represent a path to the supplied vertex. If many paths from a common startingvertex are to be calculated, it is more efficient to produce and reuse thespanning tree, than to calculate the paths independently using the …path„ functioneach time.Examples:disp aÚ…ÎÎÂÎÂÎÎÎÂÎÎÎÂÎÌÛ2 3Û3Û2 4Û1 5Û3ÛÀ~Î…ÁÎÁ~Î…Á~Î…ÁÎÙŒ„ast3„a span 34 3 ¯1 3 4disp ast3°stpath¨¼5Ú…ÎÎÎÎÂÎÎÎÂÎÂÎÎÎÂÎÎÎÎÎÌÛ3 4 1Û3 2Û3Û3 4Û3 4 5ÛÀ~ÎÎÎ…Á~Î…Á…Á~Î…Á~ÎÎÎ…Ù© simple graph "a".© a's spanning tree from vertex 3, yields:© ... paths from 3 to all other vertices.disp vast„a°span¨¼½a© vector of a's spanning trees.Ú…ÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÌÛ¯1 1 1 3 4Û4 ¯1 2 3 4Û4 3 ¯1 3 4Û4 1 1 ¯1 4Û4 3 5 3 ¯1ÛÀ~ÎÎÎÎÎÎÎÎ…Á~ÎÎÎÎÎÎÎÎ…Á~ÎÎÎÎÎÎÎÎ…Á~ÎÎÎÎÎÎÎÎ…Á~ÎÎÎÎÎÎÎÎ…Ùdisp vast°.stpath¼½aÚ…ÎÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÎÎ̇ 1 Û 1 2 Û 1 3 Û1 3 4Û1 3 4 5ÛÃ~ÎÎÎÎÎ…Ï~ÎÎÎ…Ï~ÎÎÎ…Ï~ÎÎÎ…Ï~ÎÎÎÎÎ…ÝÛ2 3 4 1Û 2 Û 2 3 Û2 3 4Û2 3 4 5ÛÃ~ÎÎÎÎÎ…Ï~ÎÎÎ…Ï~ÎÎÎ…Ï~ÎÎÎ…Ï~ÎÎÎÎÎ…ÝÛ 3 4 1 Û 3 2 Û 3 Û 3 4 Û 3 4 5 ÛÃ~ÎÎÎÎÎ…Ï~ÎÎÎ…Ï~ÎÎÎ…Ï~ÎÎÎ…Ï~ÎÎÎÎÎ…ÝÛ 4 1 Û4 1 2Û4 1 3Û 4 Û 4 5 ÛÃ~ÎÎÎÎÎ…Ï~ÎÎÎ…Ï~ÎÎÎ…Ï~ÎÎÎ…Ï~ÎÎÎÎÎ…ÝÛ5 3 4 1Û5 3 2Û 5 3 Û5 3 4Û 5 ÛÀ~ÎÎÎÎÎ…Á~ÎÎÎ…Á~ÎÎÎ…Á~ÎÎÎ…Á~ÎÎÎÎÎ…Ùdisp a°path¨ °.,þ ¼½aÚ…ÎÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÎÎ̇ 1 Û 1 2 Û 1 3 Û1 3 4Û1 3 4 5ÛÃ~ÎÎÎÎÎ…Ï~ÎÎÎ…Ï~ÎÎÎ…Ï~ÎÎÎ…Ï~ÎÎÎÎÎ…ÝÛ2 3 4 1Û 2 Û 2 3 Û2 3 4Û2 3 4 5ÛÃ~ÎÎÎÎÎ…Ï~ÎÎÎ…Ï~ÎÎÎ…Ï~ÎÎÎ…Ï~ÎÎÎÎÎ…ÝÛ 3 4 1 Û 3 2 Û 3 Û 3 4 Û 3 4 5 ÛÃ~ÎÎÎÎÎ…Ï~ÎÎÎ…Ï~ÎÎÎ…Ï~ÎÎÎ…Ï~ÎÎÎÎÎ…ÝÛ 4 1 Û4 1 2Û4 1 3Û 4 Û 4 5 ÛÃ~ÎÎÎÎÎ…Ï~ÎÎÎ…Ï~ÎÎÎ…Ï~ÎÎÎ…Ï~ÎÎÎÎÎ…ÝÛ5 3 4 1Û5 3 2Û 5 3 Û5 3 4Û 5 ÛÀ~ÎÎÎÎÎ…Á~ÎÎÎ…Á~ÎÎÎ…Á~ÎÎÎ…Á~ÎÎÎÎÎ…Ù© extract paths between all vertices.© ... same as direct path extraction.See also: Graphs.137 span.155 path.153 search.153161


ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎstpathspvec „ ##.stpaths tree© Spanning tree paths.Returns vector [pvec] of the paths from the root to each vertex of the spanning[tree].It is quicker to extract single paths using …stpath„ but if all paths are required,[stpaths] is quicker than {¾°stpath¨¼½¾}.Examples:©© Graph "a".© ÚÎÎÎÎÎ1„ÎÎÎÎÌ 5 vertices: 1 2 3 4 5© Û Û Û© ‡ ‡ Û 8 edges: 1…2 1…3© 2„ÎÎÎ…3ÎÎÎÎ…4 2…3© † Û 3…2 3…4© Û ‡ 4…1 4…5© ÀÎÎÎÎÎ5 5…3a„(2 3)(3)(2 4)(1 5)(3)© simple origin-1 graph.a span 1¯1 1 1 3 4disp stpaths a span 1 © paths from vertex 1.Ú…ÂÎÎÎÂÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÎÎÌÛ1Û1 2Û1 3Û1 3 4Û1 3 4 5ÛÀ…Á~Î…Á~Î…Á~ÎÎÎ…Á~ÎÎÎÎÎ…ÙSee also: stpath.159 stdists.158 span.155 Graphs.137ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎXB „ {rcols„1..} ##.X M © Exact cover: Knuth's Algorithm X.Given a set of requirements and set of actions, each of which satisfies zero ormore of the requirements, choose a subset of the actions such that each requirementis satisfied exactly once.The problem can be represented as a boolean matrix, where each row is an actionwith 1s at the column positions of the requirements it satisfies.1 2 3 4ÚÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÌ Action A satisfies requirements 2 and 4A Û 0 Û 1 Û 0 Û 1 Û .. B .. .. .. 1 .. 2ÃÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝ .. C .. .. .. 1 .. 3B Û 1 Û 1 Û 0 Û 0 ÛÃÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝ In this case a solution is 1 0 1, as A and CC Û 1 Û 0 Û 1 Û 0 Û together satisfy all requirements exactly once.ÀÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÙBoolean result vector [B] identifies a subset of the rows of boolean argumentmatrix [M] with exactly one 1 in each column: 1^.=+šBšM. The selected rows aresaid to form an "exact cover" of the argument matrix.If no exact cover is possible, _scalar_ 0 is returned. This means that a testfor failure might be B­0 or 0=½½B.Many problems, including …sudoku„, …queens„ and pentomino-tiling can be reducedto the exact cover problem. See …sudokuX„, …queensX„ and ##.scripts.pentominos162


For some problems, such as …queensX„, some of the columns are "optional" and soneed not be covered. Optional boolean left argument vector [rcols], default all1s, specifies which columns are required to be covered.Knuth's algorithm is described as being "recursive with backtracking":[1] If ¾ has no columns (c=0) the algorithm succeeds with a result of r½0where r c„½¾.[2] Otherwise, choose any non-empty row r as a potential cover.[3] Identify a sub-matrix of ¾: columns not covered by r and rows not coveredby r-covered columns (because each column must be covered only once).[4] If the sub-matrix has an exact cover, merge this with r as result.[5] Otherwise, if there are un-tried rows besides r, try these.[6] Otherwise, return failure.Knuth suggests a heuristic: given that each column must be covered once and onlyonce, we can choose rows r by selecting a column with a minimum number of 1s andexamining only those rows selected by 1s in this column.As an example:1 2 3 4 5 6 7ÚÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÌA Û 1 Û 0 Û 0 Û 1 Û 0 Û 0 Û 1 ÛÃÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝB Û 1 Û 0 Û 0 Û 1 Û 0 Û 0 Û 0 ÛÃÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝC Û 0 Û 0 Û 0 Û 1 Û 1 Û 0 Û 1 ÛÃÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝD Û 0 Û 0 Û 1 Û 0 Û 1 Û 1 Û 0 ÛÃÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝE Û 0 Û 1 Û 1 Û 0 Û 0 Û 1 Û 1 ÛÃÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝF Û 0 Û 1 Û 0 Û 0 Û 0 Û 0 Û 1 ÛÀÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÙSelect any column; Knuth's heuristic recommends choosing one with a minimal numberof marked rows (1s). Let's select the leftmost column [1]:[1] 2 3 4 5 6 7ÚÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÌA Û 1 Û 0 Û 0 Û 1 Û 0 Û 0 Û 1 ÛÃÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝB Û 1 Û 0 Û 0 Û 1 Û 0 Û 0 Û 0 ÛÃÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝC Û 0 Û 0 Û 0 Û 1 Û 1 Û 0 Û 1 ÛÃÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝD Û 0 Û 0 Û 1 Û 0 Û 1 Û 1 Û 0 ÛÃÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝE Û 0 Û 1 Û 1 Û 0 Û 0 Û 1 Û 1 ÛÃÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝF Û 0 Û 1 Û 0 Û 0 Û 0 Û 0 Û 1 ÛÀÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÙSelecting any marked row in this column identifies an "uncovered" sub-matrix.First we mark columns selected by this row and then we mark rows selected by anyof the marked columns.163


Arbitrarily choosing the second row and marking the covered rows and columns:ÚÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ Columns marked by second row.ÛÛ[1] 2 3 4 5 6 7ÚÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÌA Û[1]Û 0 Û 0 Û[1]Û 0 Û 0 Û 1 ÛÎÂÎ Rows marked by marked columns.ÃÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝ Û[B]Û[1]Û 0 Û 0 Û[1]Û 0 Û 0 Û 0 ÛÎÝÃÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝ ÛC Û 0 Û 0 Û 0 Û[1]Û 1 Û 0 Û 1 ÛÎÙÃÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝD Û 0 Û 0 Û 1 Û 0 Û 1 Û 1 Û 0 ÛÎÂÎ Unmarked rowsÃÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝ ÛE Û 0 Û 1 Û 1 Û 0 Û 0 Û 1 Û 1 ÛÎÝÃÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝ ÛF Û 0 Û 1 Û 0 Û 0 Û 0 Û 0 Û 1 ÛÎÙÀÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÙÛ Û Û Û ÛÀÎÎÎÁÎÎÎÎÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÎÎ Unmarked columnsThe algorithm is applied recursively to the unmarked submatrix, in this case thematrix:2 3 5 6 7ÚÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÌD Û 0 Û 1 Û 1 Û 1 Û 0 ÛÃÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝE Û 1 Û 1 Û 0 Û 1 Û 1 ÛÃÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝF Û 1 Û 0 Û 0 Û 0 Û 1 ÛÀÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÙIf the recursive call fails to find an exact cover, it "backtracks" and a differentrow is examined. If there are no untried rows, the search fails.Otherwise, if the recursive call succeeds, the resulting covering vector, extendedwith the marked row, is returned as result.Technical note:In general, <strong>APL</strong> provides two ways to identify a subset of the rows and columnsof a matrix: the first is to use indices M[I;] or M[;I] and the second employs aboolean selection vector B/M or BšM. The coding of X arbitrarily chooses thesecond (boolean selection) method.Ref: http://en.wikipedia.org/wiki/Algorithm_XAlternative-----------Phil Last provides this alternative coding, which is good for small arrays:Example:X„{¾{³(¾½2)‚{¾/¼½¾}1^.=(³¸)+.^(¾½2)‚¼2*¾}«½½¾}M1 0 0 1 0 0 11 0 0 1 0 0 00 0 0 1 1 0 10 0 1 0 1 1 00 1 1 0 0 1 10 1 0 0 0 0 1© Constraint matrix.164


X M © Rows that form exact cover.0 1 0 1 0 1(X M)šM © selected covering rows.1 0 0 1 0 0 00 0 1 0 1 1 00 1 0 0 0 0 111^.=+š(X M)šM© condition for exact cover.© See also …sudokuX„ © Exact cover Sudoku solver.© See also …queensX„ © Exact cover N-Queens solver.© See also ##.scripts.pentominos © Exact cover Pentomino tiling.See also: Graphs.137 assign.144 sudoku.491 sudokuX.587 queensX.554ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎwGraphsÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎWeighted GraphsÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎA weighted graph has a traversal cost associated with each edge. An example ofan application might be in modelling a transportation system such as a road network.An edge of the graph would correspond to a stretch of road between twointersections, and its weight with the length of the section or expected timetaken to drive along it. Choosing an optimal path through such a network amountsto finding a set of graph edges connecting the start and end points, which has aminimal total cost.The following diagram represents a simple example, whose weights are shown tothe right of, or below, the direction arrow for each edge.Weighted Graph "aa".ÚÎÎÎÎÎA„ÎÎÎÎÌÛ Û1 Û 5 vertices: A B C D E‡1 ‡3 ÛB„ÎÎÎ…CÎÎÎÎ…D 8 edges: A…B A…C B…C C…B C…D D…A D…E E…C4 1†1 1Û weights: 1 3 1 4 1 1 1 1Û ‡1ÀÎÎÎÎÎE Notice that there is an edge C…B, as well as B…C.The graph is implemented as a 2-row matrix, whose first row is an unweightedgraph and whose second row is a vector of weights for each edge.Functions …wpath„ and …wspan„ do the same job as …path„ and …span„ respectively,and …wcost„ returns the cost for each edge of a path through the graph.Mike Day suggests a class of problem in which we navigate between adjacent cellsof a matrix and where there is a cost of visiting each cell. There may be restrictionson which directions we can take (for example: only rightwards anddownwards).Mike provides a function to convert from such a matrix to a weighted graph,suitable for wpath, wspan, etc:165


mattographa„{ŒML„0i„{¾½¼×/¾}½¾max„1+—/,i¸„1 1 1 1 © if up left right downaddlink„{1 1‡¯1 ¯1‡¸{¸=0:¾¸=1:¯1´¾¸=2:¯1²¾¸=3:1²¾¸=4:1´¾}¾}op„¸/¼4w„max,max,þmax®max®þilinks„,{¾/þ¾


show aa wpath 3 2 © lowest cost path C…B.C…D…A…BC…Bshow aa[1;] path 3 2© compare: best path C…B _ignoring_ weights.aa wspan 5 © spanning tree for aa from vertex 3.4 1 5 3 ¯1disp(aa wspan 5)°stpath¨¼5 © paths to each vertex from spanning tree 5.Ú…ÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÂÎÎÎÂÎÎÎÎÎÂÎÌÛ5 3 4 1Û5 3 4 1 2Û5 3Û5 3 4Û5ÛÀ~ÎÎÎÎÎ…Á~ÎÎÎÎÎÎÎ…Á~Î…Á~ÎÎÎ…Á…Ùaa wcost 1 3 4 5 3 2 3 23 1 1 1 4 1 4© cost of path through graph "aa".See also: Graphs.137 wpath.165 wspan.167 wcost.165 wmst.167 stpath.159See also: path.153 span.155ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎwcostcvec „ wgraph ##.wcost path © Cost vector for path ¾ through weighted graph ¸.The result, [cvec] is the cost-per-edge for the _path_ through the weightedgraph [wgraph]. Note that the resulting cost vector has one fewer items thanthe path.Examples:disp aaÚ…ÎÎÂÎÂÎÎÎÂÎÎÎÂÎ̇2 3Û3Û2 4Û1 5Û3ÛÃ~Î…ÏÎÏ~Î…Ï~Î…ÏÎÝÛ1 3Û1Û4 1Û1 1Û1ÛÀ~Î…ÁÎÁ~Î…Á~Î…ÁÎÙaa wcost 1 3 4 5 3 2 3 23 1 1 1 4 1 4© simple weighted graph.© cost of path through graph.See also: wGraphs.163 wspan.167 wpath.165ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎwpathpath „ wgraph ##.wpath (from to) © Quickest path from/to ¾ in weighted graph ¸.[wgraph] is a 2-row matrix representing a weighted graph. The result [path] is avector that represents a lowest-cost path between the given vertices. Noticethat the return path (to from) may not be the reverse of the forward path.NB: All of the weights in the 2nd row of [wgraph] must be non-negative, otherwisethe result is unpredictable.Technical notes:Shortest paths through _unweighted_ graphs, result immediately from a simplebreadth-first search: the target vertex is discovered in the fewest possiblesteps, as the search radiates outwards from the starting vertex.However, with a _weighted_ graph, the search can't stop on finding the target,as there may yet be lower-cost paths. The technique used here, is to maintain acost-to-reach value (which is initialised to: ˜/¼0), for each vertex. At eachpoint in the search, vertices are pursued only if the cost of reaching themwould be less than their current cost-to-reach value. In this case, the cost-toreachvalue for the vertices is adjusted accordingly and the search continued.167


As the "wave" front of visited vertices radiates from the starting vertex, thecode uses a destructive partial assignment to update tree and cost vectors:tree[wave]„ ...cost[wave]„ ...© link tree nodes to parent.© update cost vector.A problem arises if the wave converges on the same vertex from two or more directions.The following diagram shows the wave propogating left-to-right fromvertices A, B and C with cost-to-reach values of 8 9 and 7, respectively.A[8]ÎÎÎ4ÎÎ…ÎÌÛB[9]ÎÎÎ2ÎÎ…ÎD[?]ÛC[7]ÎÎÎ6ÎÎ…ÎÙThe edge costs A…D, B…D and C…D are 4 2 and 6, so the cost-to-reach D must beset to:˜8 9 7+4 2 611The partial assignment can be made "just to work" if we assign links and costsin _decreasing_ cost order:tree[··D··D··D··] „ ·· C A B ·· © link tree nodes to parent.cost[··D··D··D··] „ ·· 13 12 11 ·· © update cost vector.<strong>APL</strong>'s indexed assignment is defined to process its subscripts left-to-right, sothat the right-most assignment to D is the only effective one. Here is the code:()...cvec„†,/mask/¨totldecr„”cvecwave„decrœ¨›†,/nexttree[wave]„decrœ¨›backcost[wave]„decrœ¨›cvec...© cost vector.© decreasing cost order.© vertex wave front.© link tree nodes to parent.© update cost vector.¸œ¨›¾ is recognised as an idiom and is marginally quicker than the equivalent¾[¸].Thanks to Mike Day for suggesting a fix to the original coding.A small but important refinement, is to keep track of the cost-to-reach value ofthe _target_ node. Any path that would be more expensive than this is ignored:best„(vals¨adjv)˜toœcost© costs to beat.See also …bfs„ for notes on parallel breadth-first search.Examples:disp aaÚ…ÎÎÂÎÂÎÎÎÂÎÎÎÂÎ̇2 3Û3Û2 4Û1 5Û3ÛÃ~Î…ÏÎÏ~Î…Ï~Î…ÏÎÝÛ1 3Û1Û4 1Û1 1Û1ÛÀ~Î…ÁÎÁ~Î…Á~Î…ÁÎÙaa wpath 3 23 4 1 2© weighted graph "aa"© best path 3…2.3 2168aa[1;] path 3 2© compare: best path 3…2 _ignoring_ weights.


See also: wGraphs.163 Graphs.137 bfs.531 wspan.167 wcost.165 path.153ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎwspantree „ wgraph ##.wspan from © Spanning tree for weighted graph ¸ from ¾.[wspan] constructs a tree of the lowest-cost paths from the given root to allaccessible vertices of the weighted graph.Each item of the vector result, with the exception of the root item (¯1), is theindex of the corresponding tree node's parent node.Technical notes:This coding differs slightly from classic breadth-first search, see …bfs„.Examples:disp aaÚ…ÎÎÂÎÂÎÎÎÂÎÎÎÂÎ̇2 3Û3Û2 4Û1 5Û3ÛÃ~Î…ÏÎÏ~Î…Ï~Î…ÏÎÝÛ1 3Û1Û4 1Û1 1Û1ÛÀ~Î…ÁÎÁ~Î…Á~Î…ÁÎÙ© simple weighted graph.aa wspan 1 © spanning tree for aa from vertex 1.¯1 1 2 3 4See also: wGraphs.163 Graphs.137See also: bfs.531 wpath.165 wcost.165 stpath.159 span.155ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎwmsttree „ wug ##.wmst root © Minimum Spanning Tree for weighted graph ¸.[wmst] uses Prim's algorithm to find a Mimimum Spanning Tree (MST) for weighted,undirected graph [wug]. An MST is a set of minimum-total-cost edges that connectsall vertices. This set of edges must form a tree; otherwise, it would containat least one cycle, which means that an edge could be removed, reducing thetotal cost without isolating any vertices.Real-life examples of applications of MSTs include finding lowest-cost ways toconnect computers in a network or the least-expensive bridge-building project tojoin up a little cluster of islands.In the context of undirected graphs, a _tree_ has no concept of hierarchy. Thereis no parent-child relationship between the vertices and in particular, there isno "root" node. A tree is just a graph that contains no cycles.TreeÀÝ ÚÎÏÎÏÎÝÚÛÀÏÌÀÏÀÎÎÎÎNon-TreeÀÝ ÚÎÏÎÏÎÝÚÛÀÏÌÀÏÀÎÎÎÎÙHowever, the representation of a tree used by the graph <strong>functions</strong> in this workspace,imposes a hierarchy. A tree is represented by a vector of parent-vertexindices. Each vertex, apart from the root, which has a dummy index of ¯1, indicatesthe position in the vector of its parent. This representation is chosen becauseit is compact and makes it easy to extract paths from any vertex, back tothe root. Notice that we can produce a "directed" tree from an undirected one(pictured above left), by selecting _any_ vertex as root. Choosing a root inthis way, immediately imposes a unique hierarchy on the tree: every edge pointsfrom a child vertex back to its parent. Wmst takes this arbitrary root vertex asright argument.169


Technical notes:Prim's algorithm accumulates the MST as follows:Starting with the chosen root as a 1-vertex tree,while there are vertices not connected to the tree,identify edges connecting these vertices to those within the tree andincorporate the lowest-cost of these into the tree.endwhileNotice that for any graph and root vertex, the MST is _not_ the same as the treeproduced by …wspan„. [wmst] guarantees that the total edge cost is minimised,while …wspan„ produces the lowest cost path from the root to _each_ vertex. Thefollowing weighted, undirected 4-vertex graph illustrates the distinction.graph MST[A] wspan[A]AÎÎÎ1ÎÎÎB A΄Î1ÎÎÎB A΄Î1ÎÎÎBÛ Û † † †2 1 1 2 1Û Û Û Û ÛCÎÎÎ1ÎÎÎD CÎÎÎ1Î…ÎD C DThe difference is that the lowest-cost-path from C to A is C…A, but edge C-A istoo expensive to be included in the MST.An alternative to Prim's algorithm is Kruskal's algorithm, which builds the MSTby adding edges, rather than vertices. This is an equally good approach, thoughit requires a second pass to render the final tree in the format required by the<strong>functions</strong> in this workspace.References:Kruskal, J.B., On the shortest spanning tree of a graph and the traveling salesmanproblem. Proceedings of the American Mathematical Society, 7:48-50, 1956.Prim, R.C., Shortest connection networks and some generalizations. Bell SystemsTechnology Journal, 36:1389-1401, 1957.The graph used in the examples below, looks like this:ÚÎÎÎÎÎÎÎAÎÎÎÎÎÎÎÌ Edge WeightÛ Û Û ---- ------1 3 1 A-B 1Û Û Û A-C 3BÎÎÎ2ÎÎÎCÎÎÎ1ÎÎÎD A-D 1Û Û B-C 21 1 C-D 1Û Û C-E 1ÀÎÎÎÎÎÎÎE D-E 1Examples:disp aaÚ…ÎÎÎÎÂÎÎÎÂÎÎÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎ̇2 3 4Û1 3Û1 2 4 5Û1 3 5Û3 4ÛÃ~ÎÎÎ…Ï~Î…Ï~ÎÎÎÎÎ…Ï~ÎÎÎ…Ï~Î…ÝÛ1 3 1Û1 2Û3 2 1 1Û1 1 1Û1 1ÛÀ~ÎÎÎ…Á~Î…Á~ÎÎÎÎÎ…Á~ÎÎÎ…Á~Î…Ùaa wmst 22 ¯1 4 1 4aa wspan 22 ¯1 2 1 3© simple weighted, undirected graph shown above.© minimum spanning tree with root 2, c.f.:© spanning tree with lowest cost to each vertex.170


See also: wspan.167 span.155 Graphs.137 wGraphs.163ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎsswordcvec „ {prim supp} ##.ssword (srce from into)© Approx alternative to xutils ss.As ss, but only whole words, as defined by function 'words', are replaced. Theoptional left argument items [prim] and [supp] are the primary and supplementaryalphabets used for word splitting. See …words„ for more details.Example:ssword'Cant can an ant.' 'an' 'pickled'Cant can pickled ant.See also: words.169 ssmat.178 ss.177 subs.85ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎwordscvecs „ {prim supp} ##.words cvec© Source vector split into words.The character vector argument is split into words. A word is defined as a sequencestarting with a character from [prim], the primary alphabet and continuingwith characters from both this and the supplementary alphabet [supp]. If no leftargument is supplied, prim defaults to A-Z, a-z, •-õ and supp to 0-9. A simpleleft argument is interpreted as the primary alphabet, with a null supplementary.Examples:disp words 'It''s only words,'Ú…ÎÂÎÂÎÂÎÂÎÎÎÎÂÎÂÎÎÎÎÎÂÎÌÛItÛ'ÛsÛ ÛonlyÛ ÛwordsÛ,ÛÀÎ…Á…Á…Á…ÁÎÎÎ…Á…ÁÎÎÎÎ…Á…Ùdisp words'4x1+x2'Ú…ÂÎÎÂÎÂÎÎÌÛ4Ûx1Û+Ûx2ÛÀ…ÁÎ…Á…ÁÎ…Ùdisp (lcase Œa) words'mete and dole'Ú…ÎÎÎÂÎÂÎÎÎÂÎÂÎÎÎÎÌÛmeteÛ ÛandÛ ÛdoleÛÀÎÎÎ…Á…ÁÎÎ…Á…ÁÎÎÎ…Ùdisp (lcase Œa) words':If ŒIO=0'Ú…ÎÂÎÂÎÎÎÎÎÎÌÛ:IÛfÛ ŒIO=0ÛÀÎ…Á…ÁÎÎÎÎÎ…Ùdisp (ŒA,lcase Œa) words':If ŒIO=0'Ú…ÂÎÎÂÎÎÂÎÎÂÎÎÌÛ:ÛIfÛ ŒÛIOÛ=0ÛÀ…ÁÎ…ÁÎ…ÁÎ…ÁÎ…Ùdisp (':Œ',ŒA,lcase Œa) words':If ŒIO=0'Ú…ÎÎÂÎÂÎÎÎÂÎÎÌÛ:IfÛ ÛŒIOÛ=0ÛÀÎÎ…Á…ÁÎÎ…ÁÎ…Ùdisp (ŒD,':Œ',ŒA,lcase Œa) words':If ŒIO=0'Ú…ÎÎÂÎÂÎÎÎÂÎÂÎÌÛ:IfÛ ÛŒIOÛ=Û0ÛÀÎÎ…Á…ÁÎÎ…Á…Á…Ù© Word split at A-Z,a-z,•-õ.© Trailing 0-9 bind to left.© Simple alphabet split.© Split at a-z.© Split at A-Z,a-z.© Split at :,Œ,A-Z,a-z.© Split at 0-9,:,Œ,A-Z,a-z.171


disp ŒA (lcase Œa) words 'ThatsAllFolks!' © Split at A-Z; a-z trail.Ú…ÎÎÎÎÂÎÎÎÂÎÎÎÎÎÂÎÌÛThatsÛAllÛFolksÛ!ÛÀÎÎÎÎ…ÁÎÎ…ÁÎÎÎÎ…Á…Ùdisp (¼10) words 1 0 0 2 3 0 4 5 6Ú…ÂÎÎÎÂÎÎÎÂÎÂÎÎÎÎÎÌÛ1Û0 0Û2 3Û0Û4 5 6ÛÀ…Á~Î…Á~Î…Á…Á~ÎÎÎ…Ùdisp (¼10) 0 words 1 0 0 2 3 0 4 5 6Ú…ÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÌÛ1 0 0Û2 3 0Û4 5 6ÛÀ~ÎÎÎ…Á~ÎÎÎ…Á~ÎÎÎ…Ù© Numeric "alphabet".© Numeric; 0s trail.See also: tokens.170 segs.582ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎtokenscvecs „ {nv„0} ##.tokens cvec© Lex of <strong>APL</strong> src line.Splits an <strong>APL</strong> "source" line into its constituent tokens. Character literalstrings, comments and expanses of "white space" are deemed single tokens.Optional left argument [nv] deterimines whether numeric vectors (1 2 3) are tobe considered:0 multiple tokens (default)1 a single tokenAn alternative coding of the function might be:tokens2„{ŒML„0© Lex of <strong>APL</strong> source line.alph„(0ˆŒNC®ŒAV)/ŒAV© Alphabet for names.all„{+/^\¸¹¾}© ’ No of leading ¸¹¾acc„{n„¸¸ ¾ ª (¸,›n†¾)lex n‡¾}© ’’ Accumulated tokenslex„{© ’ Next lexical token0=½¾:¸ ª hd„œ¾© Next char else finishedhd=' ':¸{¾ all' '}acc ¾© White Spacehd¹alph:¸{¾ all alph,ŒD}acc ¾ © Namehd¹'Œ:':¸{1+(1‡¾)all alph,':'}acc ¾ © System Name / Keyword / guardhd='''':¸{+/^\{¾Ÿ¯1²¾}¬\¾=hd}acc ¾ © Char literalhd¹ŒD,'¯':¸{¾ all ŒD,'.¯E'}acc ¾ © Numeric scalar literalhd¹'¸¾’':¸{¾ all hd}acc ¾© Meta character.hd='©':¸½acc ¾© Comment¸{1}acc ¾© Single char token}(0½›'')lex,¾}172


Example:{Œ„disp tokens ¾}¨Œnr'tokens'Ú…ÎÎÎÎÎÂÎÂÎÂÎÎÎÂÎÂÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛtokensÛ„Û{ÛŒMLÛ„Û3ÛÛ© Lex of <strong>APL</strong> src line.ÛÀÎÎÎÎÎ…Á…Á…ÁÎÎ…Á…Á…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÙÚ´ÌÛ ÛÀ´ÙÚ…ÎÎÎÂÎÎÎÎÂÎÂÎÂÎÂÎÂÎÎÎÂÎÂÎÎÎÂÎÂÎÂÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ ÛalphÛ„Û(Û0ÛˆÛŒNCÛ®ÛŒAVÛ)Û/ÛŒAVÛ Û© Alphabet for names.ÛÀÎÎÎ…ÁÎÎÎ…Á…Á…Á…Á…ÁÎÎ…Á…ÁÎÎ…Á…Á…ÁÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÙÚ´ÌÛ ÛÀ´ÙÚ…ÎÎÎÂÎÎÎÂÎÂÎÂÎÂÎÂÎÂÎÂÎÂÎÂÎÂÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ ÛallÛ„Û{Û+Û/Û^Û\Û¸Û¹Û¾Û}Û Û© No. of leading ¸¹¾.ÛÀÎÎÎ…ÁÎÎ…Á…Á…Á…Á…Á…Á…Á…Á…Á…Á…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÙÚ´ÌÛ ÛÀ´ÙÚ…ÎÎÎÂÎÎÎÂÎÂÎÂÎÂÎÂÎÂÎÂÎÂÎÂÎÂÎÎÎÂÎÂÎÂÎÂÎÂÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ ÛaccÛ„Û{Û(Û¸Û,Û†Û/Û¾Û)ÛlexۜۇÛ/Û¾Û}Û Û© Accumulate tokens.ÛÀÎÎÎ…ÁÎÎ…Á…Á…Á…Á…Á…Á…Á…Á…Á…ÁÎÎ…Á…Á…Á…Á…Á…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÙÚ´ÌÛ ÛÀ´ÙÚ…ÎÎÎÂÎÎÎÂÎÂÎÌÛ ÛlexÛ„Û{ÛÀÎÎÎ…ÁÎÎ…Á…Á…ÙÚ´ÌÛ ÛÀ´ÙÚ…ÎÎÎÎÎÎÎÂÎÂÎÂÎÂÎÂÎÂÎÂÎÂÎÂÎÂÎÎÂÎÂÎÂÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÛ Û0Û=Û½Û¾Û:Û¸Û ÛªÛ ÛhdÛ„Û†Û¾Û Û© Next char else finisheÀÎÎÎÎÎÎÎ…Á…Á…Á…Á…Á…Á…Á…Á…Á…ÁÎ…Á…Á…Á…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÚ´ÌÛ ÛÀ´ÙÚ…ÎÎÎÎÎÎÎÂÎÎÂÎÂÎÎÎÂÎÂÎÂÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ ÛhdÛ=Û' 'Û:Û¸Û{Û Û© White Space.ÛÀÎÎÎÎÎÎÎ…ÁÎ…Á…ÁÎÎ…Á…Á…Á…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÙÚ…ÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÂÎÂÎÂÎÂÎÎÎÂÎÎÎÌÛÛsizeÛ„Û¾Û ÛallÛ' 'ÛÀÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎ…Á…Á…Á…ÁÎÎ…ÁÎÎ…ÙÚ…ÎÎÎÎÎÎÎÎÎÎÎÂÎÂÎÂÎÎÎÂÎÂÎÎÎÎÂÎÂÎÌÛÛ¸Û ÛaccÛ ÛsizeÛ Û¾ÛÀÎÎÎÎÎÎÎÎÎÎÎ…Á…Á…ÁÎÎ…Á…ÁÎÎÎ…Á…Á…ÙÚ…ÎÎÎÎÎÎÎÂÎÂÎÌÛ Û}Û¾ÛÀÎÎÎÎÎÎÎ…Á…Á…ÙÚ´ÌÛ ÛÀ´ÙÚ…ÎÎÎÎÎÎÎÂÎÎÂÎÂÎÎÎÎÂÎÂÎÂÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÌÛ ÛhdÛ¹ÛalphÛ:Û¸Û{Û Û© NameÛÀÎÎÎÎÎÎÎ…ÁÎ…Á…ÁÎÎÎ…Á…Á…Á…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎ…ÙÚ…ÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÂÎÂÎÂÎÂÎÎÎÂÎÂÎÎÎÎÂÎÂÎÎÌÛÛsizeÛ„Û¾Û ÛallÛ ÛalphÛ,ÛŒDÛÀÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎ…Á…Á…Á…ÁÎÎ…Á…ÁÎÎÎ…Á…ÁÎ…ÙÚ…ÎÎÎÎÎÎÎÎÎÎÎÂÎÂÎÂÎÎÎÂÎÂÎÎÎÎÂÎÂÎÌÛÛ¸Û ÛaccÛ ÛsizeÛ Û¾ÛÀÎÎÎÎÎÎÎÎÎÎÎ…Á…Á…ÁÎÎ…Á…ÁÎÎÎ…Á…Á…ÙÚ…ÎÎÎÎÎÎÎÂÎÂÎÌÛ Û}Û¾Û173


ÀÎÎÎÎÎÎÎ…Á…Á…ÙÚ´ÌÛ ÛÀ´ÙÚ…ÎÎÎÎÎÎÎÂÎÎÂÎÂÎÎÎÎÂÎÂÎÂÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ ÛhdÛ¹Û'Œ:'Û:Û¸Û{Û Û© System Name / KeywordÛÀÎÎÎÎÎÎÎ…ÁÎ…Á…ÁÎÎÎ…Á…Á…Á…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÙÚ…ÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÂÎÂÎÂÎÂÎÎÎÂÎÂÎÎÂÎÂÎÎÎÎÌÛÛsizeÛ„Û¾Û ÛallÛ ÛhdÛ,ÛalphÛÀÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎ…Á…Á…Á…ÁÎÎ…Á…ÁÎ…Á…ÁÎÎÎ…ÙÚ…ÎÎÎÎÎÎÎÎÎÎÎÂÎÂÎÂÎÎÎÂÎÂÎÎÎÎÂÎÂÎÌÛÛ¸Û ÛaccÛ ÛsizeÛ Û¾ÛÀÎÎÎÎÎÎÎÎÎÎÎ…Á…Á…ÁÎÎ…Á…ÁÎÎÎ…Á…Á…ÙÚ…ÎÎÎÎÎÎÎÂÎÂÎÌÛ Û}Û¾ÛÀÎÎÎÎÎÎÎ…Á…Á…ÙÚ´ÌÛ ÛÀ´ÙÚ…ÎÎÎÎÎÎÎÂÎÎÂÎÂÎÎÎÎÂÎÂÎÂÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ ÛhdÛ=Û''''Û:Û¸Û{Û Û© Char literalÛÀÎÎÎÎÎÎÎ…ÁÎ…Á…ÁÎÎÎ…Á…Á…Á…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÙÚ…ÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÂÎÂÎÂÎÂÎÂÎÂÎÂÎÂÎÂÎÎÂÎÂÎÂÎÂÎÂÎÂÎÎÂÎÂÎÌÛÛsizeÛ„Û+Û/Û^Û\Û{Û¾ÛŸÛ¯1Û²Û¾Û}Û¬Û\ÛhdÛ=Û¾ÛÀÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎ…Á…Á…Á…Á…Á…Á…Á…Á…ÁÎ…Á…Á…Á…Á…Á…ÁÎ…Á…Á…ÙÚ…ÎÎÎÎÎÎÎÎÎÎÎÂÎÂÎÂÎÎÎÂÎÂÎÎÎÎÂÎÂÎÌÛÛ¸Û ÛaccÛ ÛsizeÛ Û¾ÛÀÎÎÎÎÎÎÎÎÎÎÎ…Á…Á…ÁÎÎ…Á…ÁÎÎÎ…Á…Á…ÙÚ…ÎÎÎÎÎÎÎÂÎÂÎÌÛ Û}Û¾ÛÀÎÎÎÎÎÎÎ…Á…Á…ÙÚ´ÌÛ ÛÀ´ÙÚ…ÎÎÎÎÎÎÎÂÎÎÂÎÂÎÎÂÎÂÎÎÎÂÎÂÎÂÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ ÛhdÛ¹ÛŒDÛ,Û'¯'Û:Û¸Û{Û Û© Numeric literalÛÀÎÎÎÎÎÎÎ…ÁÎ…Á…ÁÎ…Á…ÁÎÎ…Á…Á…Á…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÙÚ…ÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÂÎÂÎÂÎÂÎÎÎÂÎÂÎÎÂÎÂÎÎÎÎÎÌÛÛsizeÛ„Û¾Û ÛallÛ ÛŒDÛ,Û'.¯E'ÛÀÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎ…Á…Á…Á…ÁÎÎ…Á…ÁÎ…Á…ÁÎÎÎÎ…ÙÚ…ÎÎÎÎÎÎÎÎÎÎÎÂÎÂÎÂÎÎÎÂÎÂÎÎÎÎÂÎÂÎÌÛÛ¸Û ÛaccÛ ÛsizeÛ Û¾ÛÀÎÎÎÎÎÎÎÎÎÎÎ…Á…Á…ÁÎÎ…Á…ÁÎÎÎ…Á…Á…ÙÚ…ÎÎÎÎÎÎÎÂÎÂÎÌÛ Û}Û¾ÛÀÎÎÎÎÎÎÎ…Á…Á…ÙÚ´ÌÛ ÛÀ´ÙÚ…ÎÎÎÎÎÎÎÂÎÎÂÎÂÎÎÎÎÎÂÎÂÎÂÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ ÛhdÛ¹Û'¸¾’'Û:Û¸Û{Û Û© ¸¸ or ¾¾ or ’’ÛÀÎÎÎÎÎÎÎ…ÁÎ…Á…ÁÎÎÎÎ…Á…Á…Á…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÙÚ…ÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÂÎÂÎÂÎÂÎÎÎÂÎÂÎÎÌÛÛsizeÛ„Û¾Û ÛallÛ ÛhdÛÀÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎ…Á…Á…Á…ÁÎÎ…Á…ÁÎ…ÙÚ…ÎÎÎÎÎÎÎÎÎÎÎÂÎÂÎÂÎÎÎÂÎÂÎÎÎÎÂÎÂÎÌÛÛ¸Û ÛaccÛ ÛsizeÛ Û¾ÛÀÎÎÎÎÎÎÎÎÎÎÎ…Á…Á…ÁÎÎ…Á…ÁÎÎÎ…Á…Á…ÙÚ…ÎÎÎÎÎÎÎÂÎÂÎÌÛ Û}Û¾ÛÀÎÎÎÎÎÎÎ…Á…Á…ÙÚ´ÌÛ ÛÀ´ÙÚ…ÎÎÎÎÎÎÎÂÎÎÂÎÂÎÎÎÂÎÂÎÂÎÂÎÎÎÂÎÂÎÂÎÂÎÂÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÌ174


Û ÛhdÛ=Û'©'Û:Û¸Û ÛaccÛ(Û½Û¾Û)Û¾Û Û© CommentÛÀÎÎÎÎÎÎÎ…ÁÎ…Á…ÁÎÎ…Á…Á…Á…ÁÎÎ…Á…Á…Á…Á…Á…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎ…ÙÚ´ÌÛ ÛÀ´ÙÚ…ÎÎÎÎÎÎÎÂÎÂÎÂÎÎÎÂÎÂÎÂÎÂÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ Û¸Û ÛaccÛ Û1Û Û¾Û Û© Single char token.ÛÀÎÎÎÎÎÎÎ…Á…Á…ÁÎÎ…Á…Á…Á…Á…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÙÚ…ÎÎÎÂÎÌÛ Û}ÛÀÎÎÎ…Á…ÙÚ´ÌÛ ÛÀ´ÙÚ…ÎÎÎÂÎÂÎÂÎÂÎÂÎÎÂÎÂÎÎÎÂÎÂÎÌÛ Û(Û0Û½Û›Û''Û)ÛlexÛ,Û¾ÛÀÎÎÎ…Á…Á…Á…Á…ÁÎ…Á…ÁÎÎ…Á…Á…ÙÚ…ÌÛ}ÛÀ…ÙSee also: words.169 unify.249 rmcm.247 segs.582ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎvoncaps „ {ack ign„'' ''} ##.von chars© Capitalise first letters of names.Suggested by Dick Bowman, this function by Veli-Matti Jantunen produces appropriatecapitalisation of a name. The function may be made to capitalise a "root"name following a prefix such as Mc or Mac, but leave separators such as le andvon in lower case.The optional left argument is a 2-item, depth-3 vector of prefixes to acknowledge(ack) and ignore (ign). The argument is permissive in accepting less deeplynested vectors:Depth-3 vector general case: · · · · (ack ack ...) (ign ign ...)Depth-2 vector 'one' 'two' ... is intepreted: (one two ...) ( )Depth-1 vector 'one' is interpreted: · · (one ) ( )Missing left argument: ( ) ( )Examples:titles„'margaretha von bahr' 'ahti von toilet' 'leonardo da vinci' 'willia†von¨titlesMargaretha von BahrAhti von ToiletLeonardo da VinciWilliam of OrangeLlywelyn ap GruffuddGuzman el BuenoWinnie the Poohvon'd''annunzio t''haarlem'd'Annunzio t'Haarlemvon'åkerlund æsop'Åkerlund Æsop'Mc'von'nasty norman mctavish o''reilly'Nasty Norman McTavish O'Reilly© default capitalisation.© caps after "'".© national language caps.© acknowledge "Mc" prefix.von 'Lorenzo de'' Medici Mohammed el-Gerousch c/o al-Ahram'Lorenzo de' Medici Mohammed el-Gerousch c/o al-Ahram175


names„'mcgryver macintosh macho dicaprio dickens'von namesMcgryver Macintosh Macho Dicaprio Dickens'mc' 'mac' 'di' von namesMcGryver MacIntosh MacHo DiCaprio DiCkens('Mc' 'Mac' 'Di')('Mach' 'Dick') von namesMcGryver MacIntosh Macho DiCaprio Dickens© default caps,© ... with Mc, Mac, Di,© ... except MacH, DiCk.See also: lcase.176 ucase.176 words.169ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎbase64coded „ ##.base64 plain© Base64 encoding and decoding as used in MIME.plain „ ##.base64 codedFrom Jay Foad, this function en/decodes between plain numbers and base64 encodingas used by MIME format.References:http://en.wikipedia.org/wiki/Base64http://tools.ietf.org/html/rfc2045Examples:base64 0 1 2 3 4 253 254 255AAECAwT9/v8=© encode some octetsbase64 'AAECAwT9/v8='0 1 2 3 4 253 254 255base64 Œucs 'If I were only dafter'SWYgSSB3ZXJlIG9ubHkgZGFmdGVy© encode some ASCII textŒucs base64 'SWYgSSB3ZXJlIG9ubHkgZGFmdGVy'If I were only dafterbase64 'UTF-8' Œucs '+/¾÷½¾'Ky/ijbXDt+KNtOKNtQ==© encode some UTF-8 text'UTF-8' Œucs base64 'Ky/ijbXDt+KNtOKNtQ=='+/¾÷½¾80 wrap Hobbes © Example from Wikipedia article.Man is distinguished, not only by his reason, but by this singular passion fromother animals, which is a lust of the mind, that by a perseverance of delight inthe continued and indefatigable generation of knowledge, exceeds the shortvehemence of any carnal pleasure.80 wrap base64 Œucs HobbesTWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=tails „ (0 to ¯4) ‡¨ ›¯20†Hobbes176


† tailsany carnal pleasure.any carnal pleasureany carnal pleasurany carnal pleasuany carnal pleas†base64°Œucs¨tailsYW55IGNhcm5hbCBwbGVhc3VyZS4=YW55IGNhcm5hbCBwbGVhc3VyZQ==YW55IGNhcm5hbCBwbGVhc3VyYW55IGNhcm5hbCBwbGVhc3U=YW55IGNhcm5hbCBwbGVhcw==See also: hex.286 Data_compression.190ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎjustrslt „ {dirn„¯1} ##.just chars© Justify text array.From Veli-Matti Jantunen, this function aligns text rows to the left, centre orright, according to the left argument:-1 left (default)0 centre1 rightExamples:display ¯1 just ' text 'Ú…ÎÎÎÎÎÎÎÌÛtext ÛÀÎÎÎÎÎÎÎÎÙdisplay 0 just ' text 'Ú…ÎÎÎÎÎÎÎÌÛ text ÛÀÎÎÎÎÎÎÎÎÙdisplay 1 just ' text 'Ú…ÎÎÎÎÎÎÎÌÛ textÛÀÎÎÎÎÎÎÎÎÙdisplay matÚ…ÎÎÎÎÎÎÎ̇do ÛÛ re ÛÛ mi ÛÛ fa ÛÛ sol ÛÛ la ÛÛ tiÛÀÎÎÎÎÎÎÎÎÙdisplay just matÚ…ÎÎÎÎÎÎÎ̇do ÛÛre ÛÛmi ÛÛfa ÛÛsol ÛÛla ÛÛti ÛÀÎÎÎÎÎÎÎÎÙ177


display ¯1 just matÚ…ÎÎÎÎÎÎÎ̇do ÛÛre ÛÛmi ÛÛfa ÛÛsol ÛÛla ÛÛti ÛÀÎÎÎÎÎÎÎÎÙdisplay 0 just matÚ…ÎÎÎÎÎÎÎ̇ do ÛÛ re ÛÛ mi ÛÛ fa ÛÛ sol ÛÛ la ÛÛ ti ÛÀÎÎÎÎÎÎÎÎÙdisplay 1 just matÚ…ÎÎÎÎÎÎÎ̇ doÛÛ reÛÛ miÛÛ faÛÛ solÛÛ laÛÛ tiÛÀÎÎÎÎÎÎÎÎÙÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎlcasechars „ ##.lcase chars© Lower-casification.chars „ ##.ucase chars© Upper-casification.Returns the lower- (resp. upper-) case equivalent of its simple character arrayargument. Note that these function take arguments of any rank. Note also, thatthey may easily be extended to work with "<strong>Dyalog</strong> ALT" or a font of our own.Examples:lcase 2 7½'PLEASE WHISPER'pleasewhisperucase 2 8½'please, speak up'PLEASE,SPEAK UP© upper- to lower-case.© lower- to upper-case.charmat „ 5 7½'Baker Fox able Dog charlie'178


{¾[“¾;]} charmat © case-sensitive sort.ablecharlieBakerDogFox{¾[“lcase ¾;]} charmat © case-INsensitive sort.ableBakercharlieDogFoxÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎmtrimcmat „ ##.mtrim cmat© Trim off trailing blank cols.Trims trailing blank columns from a character matrix.Example:txt„4 10½'It little profits that 'display txtÚ…ÎÎÎÎÎÎÎÎÎ̇It ÛÛlittle ÛÛprofits ÛÛthat ÛÀÎÎÎÎÎÎÎÎÎÎÙdisplay mtrim txtÚ…ÎÎÎÎÎÎ̇It ÛÛlittle ÛÛprofitsÛÛthat ÛÀÎÎÎÎÎÎÎÙSee also: vtrim.186 dtb.189ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎsscvec „ ##.ss (srce from into)© Approx alternative to xutils' ss.The right argument is a 3-item vector of simple vectors. The result is formedfrom the source [srce] with occurrences of string [from] replaced with string[into]. Notice that regular expressions are not used; there are no specialcharacters, so '*', '[]', etc. are taken literally. Notice also that in the caseof overlapping strings, both strings are identified and both are replaced.Examples:ss'Banana' 'an' 'AN'BANANass'Banana' 'ana' 'ANA'BANAANAss (¼10) (3 4 5) (88 99)1 2 88 99 6 7 8 9 10© non-overlapping strings.© overlapping strings.© numeric strings.b.zzss'b.bb' 'bb' 'zz'© "Ray's case".179


See also: subs.85 ssmat.178 ssword.169 subvec.83ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎssmatcmat „ ##.ssmat (cmat from into)© Matrix search/replace.As ss, but the result and first item in the argument are character matricesrather than vectors. When [from] and [into] are of differing lengths, shortervectors along the last axis are padded on the right with prototypical items.Examples:ssmat(2 12½'Is you is oris you aint?')'is' 'was'Is you was orwas you aint?ssmat (3 5½¼15) (7 8 9) (70 80 90)1 2 3 4 56 70 80 90 1011 12 13 14 15ssmat (3 5½¼15) (7 8 9) 'repl'1 2 3 4 5 06 r e p l 1011 12 13 14 15 0ssmat (3 5½¼15) (7 8 9) 'r'1 2 3 4 56 r 10 0 011 12 13 14 15© Numeric replacement.© Replace with longer string.© Replace with shorter string.See also: ss.177 ssword.169 subs.85ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎsqueezecvec „ ##.squeeze cvec© Compress multiple blanks.Multiple blank characters in [cvec] are replaced with a single blank.Examples see: …Line_vectors„squeeze ' oranges and lemons'oranges and lemonsSee also: justify.185 wrap.185 unwrap.185 dmb.190 Line_vectors.182ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎtimestampcvec „ {time„Œts} ##.timestamp cvec© Time-stamped message.Character vector [cvec] is prefixed with an ISO-standard(ish) date and time. Theoptional left argument (default ŒTS) allows an override of the current systemtime.Example:timestamp 'Starting ...'2000-11-06 13:15:02 Starting ...See also: Dates.353 date.358 days.356180


ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎxtabscvec „ {tabstops„8} ##.xtabs cvec© Expand/compress HT chars.The optional left argument (default 8) defines "tabstop" increments.For a positive left argument, horizontal tab characters in the right argumentare replaced with appropriate blanks and for a negative left argument, thereverse happens. Mnemonic:+ive -> expand-ive -> compress© replace tabs with blanks© replace blanks with tabs[xtabs] accommodates linefeed characters in its right argument, so a line-vectoror the content of a whole text file may be converted in one call.Technical note:In the coding of the compression case, two sub<strong>functions</strong> may be of general interest.The first, suggested by Morten Kromberg, identifies runs of adjacent 1s inits boolean vector argument:runs „ {s„+\¾ ª s-—\s×~¾} © runs of adjacent 1s.runs „ {¾{¾-—\¾×~¸}+\¾}© ditto, but with no local variable.runs 0 1 1 1 0 1 0 1 1 0 © runs of adjacent 1s.0 1 2 3 0 1 0 1 2 0and the second, by Nicolas Delcros, returns the effect of a state being set ONby 1s from its boolean left argument, and OFF by 1s from its right argument. Inelectronics, this function is known as the "SR (set-reset) flip flop".onoff „ {1‡œ,/Ÿ\¨(1,¾)›0,¸}ons ª offs ª ons onoff offs0 0 1 1 0 0 0 0 1 0 0 0 00 0 0 0 0 1 0 1 0 0 0 1 00 0 1 1 1 0 0 0 1 1 1 0 0© on where ¸=1, off where ¾=1.© show ons, offs and resulting state.Although this does not arise in the coding of xtabs, in general there is a problemin deciding what to do if ON and OFF bits coincide. Nicolas gives the followingalternatives:onoff „ {1‡œ,/Ÿ\¨(1,¾)›1,¸}onoff „ {1‡œ,/Ÿ\¨(1,¾)›0,¸}onoff „ {1‡œ,/^\¨(1,¸)›1,~¾}onoff „ {1‡œ,/^\¨(1,¸)›0,~¾}© priority given to ON, starting ON© priority given to ON, starting OFF© priority given to OFF, starting ON© priority given to OFF, starting OFFand this one, where coincident ON and OFF signals are ignored, may have pleasedGérard Langlet. The function starts in state OFF (to start in state ON, we couldjust invert the logic: on=0, off=1).onoff „ {n„¸¬¾ ª ¬\n\2¬/¯1,n/¸-¾}or, with an inner dfn instead of a local variable:onoff „ {(¸¬¾){¬\¸\2¬/¯1,¸/¾}¸-¾}181


(muse:·There is an intriguing story surrounding the coding of onoff:·Jim Weigang says: "In his <strong>APL</strong>85 paper (on pg. 82), Clark Wiedmann describesa programming problem posed to STSC employees. The task was to model astate-switching device that toggled state based on signals from two separate"on" and "off" wires. The device can be modeled trivially with a programthat loops. Clark wrote: "Over a period of 10 days, 12 programmers contributed14 distinct solutions. Nine of the first ten were incorrect. [Thecorrect one was the looping version.] The eleventh solution (by JeffChilton) was the first correct one that was non-iterative. It was:·1‡((1,OFF>ON)PORSCAN 0,ON>OFF)¬(1,OFF¬ON)PNESCAN 0,ON^OFFThe two subroutines [are partitioned or-scan and notequal-scan, from BobSmith's <strong>APL</strong>79 paper]." Clark estimated that the "quest for a non-loopingsolution cost about $13,000 in programming time and correspondence." A yearor two after this description was published, someone sent Clark a stunninglyshort solution that everyone had missed. One should not underestimate theamount of work it sometimes takes to find noniterative solutions in <strong>APL</strong>, orassume that finding such solutions is worth the amount of time spent onthem. ")Presumably, the "stunningly short solution" predated nested arrays and partitionedreduction.Example:textwhistles far and weeht „ (9+Œio)œŒavst „ ht'…'°subsst ¯8 xtabs textwhistles…far…and weest ¯4 xtabs textwhistles……far……and…wee© horizontal tab char.© show tabs as ….© compress using 8-tabs© compress using 4-tabs11text ­ 4 xtabs ¯4 xtabs text{¾­4 xtabs ¯4 xtabs ¾} #.notes.xtabs© full circle© text with embedded linefeeds.See also: Line_vectors.182 getfile.409ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎhtxsegs „ tag ##.htx html© Extract html segments.Extracts [tag]-tagged segments from character array [html].NB: This function may be coded more simply using system function ŒXML.Right argument [html] may be:- a character vector, possibly containing linefeed characters, or- a character matrix, or- a vector of character vectors (as delivered by …getfile„).182


If [tag] starts with a '' may also be included in [tag], but is ignored.Technical notes:The coding is an example of "programming with <strong>functions</strong>". Notice that nearly allof the local names refer to <strong>functions</strong>, rather than to data arrays.Examples:bold„'this and that'disp 'b' htx bold © extract text.Ú…ÎÎÎÂÎÎÎÎÌÛthisÛthatÛÀÎÎÎ…ÁÎÎÎ…Ùdisp '' htx boldÚ…ÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÌÛthisÛthatÛÀÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎ…Ù© .. including tags.htm© character vector (with linefeeds).%Eye PokeKumquatGuys6040Dolls2080disp 'table'htx htm© extract table.Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÛ %Eye PokeKumquat Guys60


ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎLine_vectorsÎÎÎÎÎÎÎÎÎÎÎÎLine-VectorsÎÎÎÎÎÎÎÎÎÎÎÎA "line-vector" or "line-list" is a character vector with embedded linefeed,ŒAV[3+Œio] characters. Line-vectors are an alternative to nested vectors-ofvectorsfor representing lines of text. Typically they trade off slower and morecomplex line access for reduced workspace usage. These notes are themselves anexample.Examples:show„{½Œ„' ·'subs ¾}© Show shape and '·'s for blanks.show text© Simple text vector."When·we·wish·to·start·on·a·subsidiary·operation·we·need·only·make·a·note·of·where·we·left·off·the·major·operation·and·then·apply·the·first·instruction·of·the·subsidiary.·When·the·subsidiary·is·over·we·look·up·the·note·and·continue·with·the·major·operation.·Each·subsidiary·operation·can·end·with·instructions·for·the·recovery·of·the·note.·How·is·the·burying·and·disinterring·of·the·note·to·be·done?·There·are·of·course·many·ways.·One·is·to·keep·a·list·of·these·notes·in·one·or·more·standard·size·delay·lines...·with·the·most·recent·last.·The·position·of·the·most·recent·of·these·will·be·kept·in·a·fixed·TS·[short·delay·line]·and·this·reference·will·be·modified·every·time·a·subsidiary·is·started·or·finished.·The·burying·and·disinterring·processes·are·fairly·elaborate,·but·there·is·fortunately·no·need·to·repeat·the·instructions·involved·each·time,·the·burying·being·done·through·a·standard·instruction·table·BURY,·and·the·disinterring·by·the·table·UNBURY."·-·A.M.Turing·1945.978show 60 wrap text© Text wrapped at 60 cols."When·we·wish·to·start·on·a·subsidiary·operation·we·needonly·make·a·note·of·where·we·left·off·the·major·operationand·then·apply·the·first·instruction·of·the·subsidiary.When·the·subsidiary·is·over·we·look·up·the·note·andcontinue·with·the·major·operation.·Each·subsidiaryoperation·can·end·with·instructions·for·the·recovery·of·thenote.·How·is·the·burying·and·disinterring·of·the·note·to·bedone?·There·are·of·course·many·ways.·One·is·to·keep·a·listof·these·notes·in·one·or·more·standard·size·delay·lines...with·the·most·recent·last.·The·position·of·the·most·recentof·these·will·be·kept·in·a·fixed·TS·[short·delay·line]·andthis·reference·will·be·modified·every·time·a·subsidiary·isstarted·or·finished.·The·burying·and·disinterring·processesare·fairly·elaborate,·but·there·is·fortunately·no·need·torepeat·the·instructions·involved·each·time,·the·buryingbeing·done·through·a·standard·instruction·table·BURY,·andthe·disinterring·by·the·table·UNBURY."·-·A.M.Turing·1945.978184


show justify 60 wrap text © Justified wrapped text."When··we··wish··to·start·on·a·subsidiary·operation·we·needonly··make··a·note·of·where·we·left·off·the·major·operationand··then··apply··the··first·instruction·of·the·subsidiary.When··the··subsidiary··is··over··we··look··up··the·note·andcontinue···with···the···major··operation.··Each··subsidiaryoperation·can·end·with·instructions·for·the·recovery·of·thenote.·How·is·the·burying·and·disinterring·of·the·note·to·bedone?··There·are·of·course·many·ways.·One·is·to·keep·a·listof··these·notes·in·one·or·more·standard·size·delay·lines...with··the·most·recent·last.·The·position·of·the·most·recentof··these·will·be·kept·in·a·fixed·TS·[short·delay·line]·andthis··reference·will·be·modified·every·time·a·subsidiary·isstarted·or·finished.·The·burying·and·disinterring·processesare··fairly··elaborate,·but·there·is·fortunately·no·need·torepeat··the··instructions··involved··each·time,·the·buryingbeing··done··through·a·standard·instruction·table·BURY,·andthe··disinterring··by·the·table·UNBURY."·-·A.M.Turing·1945.1019show unwrap justify 60 wrap text© Unwrapped again."When··we··wish··to·start·on·a·subsidiary·operation·we·need·only··make··a·note·of·where·we·left·off·the·major·operation·and··then··apply··the··first·instruction·of·the·subsidiary.·When··the··subsidiary··is··over··we··look··up··the·note·and·continue···with···the···major··operation.··Each··subsidiary·operation·can·end·with·instructions·for·the·recovery·of·the·note.·How·is·the·burying·and·disinterring·of·the·note·to·be·done?··There·are·of·course·many·ways.·One·is·to·keep·a·list·of··these·notes·in·one·or·more·standard·size·delay·lines...·with··the·most·recent·last.·The·position·of·the·most·recent·of··these·will·be·kept·in·a·fixed·TS·[short·delay·line]·and·this··reference·will·be·modified·every·time·a·subsidiary·is·started·or·finished.·The·burying·and·disinterring·processes·are··fairly··elaborate,·but·there·is·fortunately·no·need·to·repeat··the··instructions··involved··each·time,·the·burying·being··done··through·a·standard·instruction·table·BURY,·and·the··disinterring··by·the·table·UNBURY."·-·A.M.Turing·1945.1019show squeeze unwrap justify 60 wrap text © Re-squeezed."When·we·wish·to·start·on·a·subsidiary·operation·we·need·only·make·a·note·of·where·we·left·off·the·major·operation·and·then·apply·the·first·instruction·of·the·subsidiary.·When·the·subsidiary·is·over·we·look·up·the·note·and·continue·with·the·major·operation.·Each·subsidiary·operation·can·end·with·instructions·for·the·recovery·of·the·note.·How·is·the·burying·and·disinterring·of·the·note·to·be·done?·There·are·of·course·many·ways.·One·is·to·keep·a·list·of·these·notes·in·one·or·more·standard·size·delay·lines...·with·the·most·recent·last.·The·position·of·the·most·recent·of·these·will·be·kept·in·a·fixed·TS·[short·delay·line]·and·this·reference·will·be·modified·every·time·a·subsidiary·is·started·or·finished.·The·burying·and·disinterring·processes·are·fairly·elaborate,·but·there·is·fortunately·no·need·to·repeat·the·instructions·involved·each·time,·the·burying·being·done·through·a·standard·instruction·table·BURY,·and·the·disinterring·by·the·table·UNBURY."·-·A.M.Turing·1945.978text ­ squeeze unwrap justify wrap text © Full circle.1text ­ unwrap squeeze justify wrap text © Full circle.1See also: wrap.185 unwrap.185 squeeze.178 justify.185 wrapnote.186See also: ltov.184 vtol.184 htx.180See also: cols.26185


ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎltovnvec „ {sepr} ##.ltov lvec© Lines to nested vector.lvec „ {sepr} ##.vtol nvec© Nested vector to lines.Each function is an approximate equivalent of the xutils AP function of the samename. [ltov] and [vtol] convert between nested vectors and …Line_vectors„.Note that [vtol] appends a [sepr] character after each item of the argument, includingthe last. This means that, in general: lvec » vtol ltov lvec.More generally, [sepr] may be a vector of separators of any shape or depth, seeexamples below.Examples:nl„«½3‡Œav© newline.lvec„'fooling around', nl, 'with barrels', nl, 'in alleys'lvecfooling aroundwith barrelsin alleysdisp ltov lvecÚ…ÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÌÛfooling aroundÛwith barrelsÛin alleysÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎ…Ù© line vector.© nested vector.nl=lvec© note, no trailing nl:0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0nl=vtol ltov lvec© note extra nl:0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1disp (nl,' ')ltov lvecÚ…ÎÎÎÎÎÎÂÎÎÎÎÎÎÂÎÎÎÎÂÎÎÎÎÎÎÎÂÎÎÂÎÎÎÎÎÎÌÛfoolingÛaroundÛwithÛbarrelsÛinÛalleysÛÀÎÎÎÎÎÎ…ÁÎÎÎÎÎ…ÁÎÎÎ…ÁÎÎÎÎÎÎ…ÁÎ…ÁÎÎÎÎÎ…Ùdisp 0 ltov 1 2 3 0 4 5 6 0 7 8 9Ú…ÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÌÛ1 2 3Û4 5 6Û7 8 9ÛÀ~ÎÎÎ…Á~ÎÎÎ…Á~ÎÎÎ…Ù© split at newline or blank.© split numeric vector.© split nested vectordisp (›'and')ltov 'red' 'and' 'yellow' ',' 'pink' 'and' 'green'Ú…ÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÌÛÚ…ÎÎÌÛÚ…ÎÎÎÎÎÂÎÂÎÎÎÎÌÛÚ…ÎÎÎÎÌÛÛÛredÛÛÛyellowÛ,ÛpinkÛÛÛgreenÛÛÛÀÎÎ…ÙÛÀÎÎÎÎÎ…ÁÎÁÎÎÎ…ÙÛÀÎÎÎÎ…ÙÛÀÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎ…Ùdisp 'and' ',' ltov 'red' 'and' 'yellow' ',' 'pink' 'and' 'green'Ú…ÎÎÎÎÂÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÂÎÎÎÎÎÎÎÌÛÚ…ÎÎÌÛÚ…ÎÎÎÎÎÌÛÚ…ÎÎÎÌÛÚ…ÎÎÎÎÌÛÛÛredÛÛÛyellowÛÛÛpinkÛÛÛgreenÛÛÛÀÎÎ…ÙÛÀÎÎÎÎÎ…ÙÛÀÎÎÎ…ÙÛÀÎÎÎÎ…ÙÛÀÎÎÎÎ…ÁÎÎÎÎÎÎÎ…ÁÎÎÎÎÎ…ÁÎÎÎÎÎÎ…ÙSee also: Line_vectors.182186


ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎwraplvec„ {cols„Œpw} ##.wrap cvec© Wrap word vector at ¸ columns.The argument vector is split between words at [cols] (default ŒPW) columns andthe blank replaced with a [LF] character. The resulting line-vector will displayin the session in [cols] or fewer columns. Words longer than [cols] are brokenunceremoniously at [cols] columns.Technical notes:Compare Bob Smith's amazing non-looping solution:wrap„{¸„Œpwv„' ',¾,' 'j„(v=' ')/¼½vp„(j+¸+1)°.


justify txtWe're all going on asummer holiday;no more working for aweek or two.Examples, See: Line_vectorsSee also: squeeze.178 wrap.185 unwrap.185ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎvtrimcvec „ ##.vtrim cvec© Remove trailing blanks.Trailing blanks at the end of the character vector argument and any immediatelybefore a [LF] character, are removed. This function is useful after editing aline-vector such as these notes, where workspace-wasting trailing blanks mayhave been introduced unintentionally.Example:show„' ·'°subs½Œ„show textWhere·Alph,·the·sacred·river,·ran··Through·caverns·measureless·to·man······Down·to·a·sunless·sea.···········110½Œ„show vtrim textWhere·Alph,·the·sacred·river,·ranThrough·caverns·measureless·to·man··Down·to·a·sunless·sea.93© Show text with '·'s for blanks.© Text vector with trailing blanks.© Superfluous trailing blanks removed.See also: Line_vectors.182 subs.85 mtrim.177 dtb.189ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎwrapnotenote „ {new„Œpw {old„Œpw}} ##.wrapnote note © Wrap text paras in note vect.Paragraphs of text in notes such as these, may be wrapped to be more easilyreadable in an edit window of a particular size. Such wrapping might be advantageousfor example, on a "phablet", where edit windows are much narrower."Flowing" text paragraphs are identified as having lines that are left and rightjustified. That is, they extend from the _first_ to the _last_ column, possiblywith some extra padding between words. The value of _last_ is taken to be thewidth of the first non-blank line following the title sequence.To avoid mutilating pictures, rows containing box-drawing characters are exemptfrom wrapping:ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ This picture will not be wrapped, as each row contains at least one of the ÛÛ special box-drawing characters. ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙNotice in the example below, that [wrapnote] recombines words split by hyphenation.Example:30 wrapnote notes.wrapnotenote „ {new {old}} ##.wrapnote note188© Wrap text paragraphs in note vector.


Paragraphs of text in notessuch as these, may be wrappedto be more easily readable inan edit window of a particularsize. Such wrapping might beadvantageous for example, on a"phablet", where edit windowsare much narrower."Flowing" text paragraphs areidentified as having linesthat are left and rightjustified. That is, theyextend from the _first_ tothe _last_ column, possiblywith some extra paddingbetween words. The value of_last_ is taken to be thewidth of the first non-blankline following the titlesequence.To avoid mutilating pictures,rows containing box-drawingcharacters are exempt fromwrapping:ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ This picture will not be wrapped, as each row contains at least one of the ÛÛ special box-drawing characters. ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙNotice in the example below,that [wrapnote] recombineswords split by hyphenation.See also: Line_vectors.182 justify.185 wrap.185 squeeze.178See also: vtrim.186 refmt.401ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎBlank_removalÎÎÎÎÎÎÎÎÎÎÎÎÎBlank Removal rslt „ {blank} d?b argt © Remove blanks.ÎÎÎÎÎÎÎÎÎÎÎÎÎEach of these <strong>functions</strong>, provided by Veli-Matti Jantunen, removes "blanks" fromits argument "character" array. The <strong>functions</strong> are general in the sense that theyaccommodate arrays of any shape or depth. The optional left argument (default:' '), is a simple array of items to be removed from the argument array, accordingto the semantics of the particular removal function.dlb - drop leading blanks.dtb - drop trailing blanks.deb - drop ending blanks (both leading and trailing).dmb - drop multiple blanks (multiple blanks replaced by a single one).dxb - drop extraneous blanks (leading, trailing and multiple).dab - drop all blanks.Technical notes:All of these <strong>functions</strong> follow the same architecture:- Nested arrays are handled recursively.- Matrices are handled column-wise (eg. dlb drops leading blank columns).189


- Arrays of higher rank are treated the same way (they are temporarily reshapedas matrices)- Vectors are treated character-wise (sort of one-row matrices).- Default special character is blank, but the <strong>functions</strong> can be used for othercharacters or character sets, too - sometimes this can lead to unexpectedresults).- The core idiom(s) can easily be changed if more efficient ones are found.Examples:show„' ·'°subsshow cvec··twas··ever··thus··show dlb cvectwas··ever··thus··show dtb cvec··twas··ever··thusshow deb cvectwas··ever··thusshow dmb cvec·twas·ever·thus·show dxb cvectwas·ever·thusshow dab cvectwaseverthusshow cmat··twas··ever··thus····heart·with··clay··show dlb cmattwas··ever··thus··heart·with··clay··show deb cmattwas··ever··thusheart·with··clayshow dxb cmattwas··ever·thusheart·with·clayshow¨ dxb‡cmattwas·ever·thus heart·with·clayshow †dxb‡cmattwas·ever·thus·heart·with·clay's'dmb'Mississippi'Misisippi'sp'dmb'Mississippi'Misisipi© show '·'s for blanks.© character vector.© drop leading blanks.© drop trailing blanks.© drop ending blanks.© drop multiple blanks.© drop extraneous blanks.© drop all blanks.© character matrix.© drop leading blank columns.© drop ending blank columns.© drop extraneous blank columns.© drop extraneous blanks in depth 2 array.© drop extraneous blanks from each row.© drop multiple 's's.© ... and 'p's.190


Mipp'is'dxb'Mississippi' © drop extra 'i's and 's's.1 dmb 8 1 1 1 2 5 © drop multiple 1s.8 1 2 5See also: dab.190 deb.189 dlb.189 dmb.190 dtb.189 dxb.189ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎdlbrslt „ {blank} ##.dlb argt© Drop Leading Blanks.Leading blanks are dropped from the character vector argument. If the argumentis of higher rank, blank "columns" are dropped.Examples, See: Blank_removalSee also: dab.190 deb.189 dmb.190 dtb.189 dxb.189ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎdtbrslt „ {blank} ##.dtb argt© Drop Trailing Blanks.Trailing blanks are dropped from the character vector argument. If the argumentis of higher rank, blank "columns" are dropped.For interest, here are a couple of alternative codings. Both <strong>functions</strong> removetrailing blanks from a character vector.{(1-(¾=' ')ƒ1)‡¾}{(-{¾ƒ¾}¾=' ')‡¾}© (Maria Wells)© (Dan Baronet)Examples, See: Blank_removalSee also: dab.190 deb.189 dlb.189 dmb.190 dxb.189 mtrim.177 vtrim.186ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎdebrslt „ {blank} ##.deb argt© Drop Ending Blanks.Both leading and trailing blanks are dropped from the character vector argument.If the argument is of higher rank, blank "columns" are dropped.Notice that:deb ­­ dlb°²ÿ2© (John Daintree)where ÿ is the primitive power operator.Examples, See: Blank_removalSee also: dab.190 dlb.189 dmb.190 dtb.189 dxb.189ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎdxbrslt „ {blank} ##.dxb argt© Drop eXtraneous Blanks.Both leading and trailing blanks are dropped and multiple sequences of blanksare replaced by a single one. If the argument is of higher rank, blank "columns"are removed.Technical note: dxb ­ deb°dmbExamples, See: Blank_removal191


See also: dab.190 deb.189 dlb.189 dmb.190 dtb.189ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎdmbrslt „ {blank} ##.dmb argt© Drop Multiple Blanks.Multiple sequences of blanks in the character vector argument are replaced by asingle one. If the argument is of higher rank, adjacent blank "columns" are"squeezed".Examples, See: Blank_removalSee also: dab.190 deb.189 dlb.189 dtb.189 dxb.189 squeeze.178ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎdabrslt „ {blank} ##.dab argt© Drop All Blanks.All blanks are dropped from the character vector argument. If the argument is ofhigher rank, "short rows" are padded with blanks on the right.Examples, See: Blank_removalSee also: deb.189 dlb.189 dmb.190 dtb.189 dxb.189ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎData_compressionÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎpack-: Data CompressionÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎThese <strong>functions</strong>, mostly from Veli-Matti Jantunen, pack and unpack data. The leftargument of each function (default 1) determines whether the right argumentis to be 1:compressed or 0:expanded (mnemonic: 1-pack, 0-unpack).1text ­ 0 packT 1 packT textpacks are suitable for compressing:B H R S U Z 4D H S T ZN Zbitmaps and imagestext,sparse, simple numeric or character arrays.We can test the relative performance of the various approaches with a functionthat compresses and expands its argument. [pack_test] takes an array to pack asright argument and a 1-character algorithm code as left argument.pack_test„{pack„–'pack',¸ais„ŒAI ª cmp„ pack ¾aic„ŒAI ª exp„0 pack cmpaix„ŒAIexp»¾:'N / A'times„¯2-/2œ¨ais aic aixmill„,†6 0°•¨timesfmto„ŒSIZE†2 4½'exp cmp 'pcent„'%',þ4 0•100×÷/²-\fmtocsize„6 0•¯1†fmtocsize,pcent,mill}© Test pack/unpack.© compression function.© compressed data.© re-expanded data.© expansion time.© unpack & check.© processor times.© milliseconds processor time.© before and after sizes.© % reduction (bigger is better).© compressed size.© size compression milliseconds.192


Result fields are:csizeredn%cmillxmillsize of compressed data.percentage reduction (bigger is better).processor milliseconds for compression.processor milliseconds for expansion.The compression algorithms were tested against 3 arrays:A bitmap:'dapl'Œwc'BitMap' 'c:/dyalog90/dyalog.bmp'© <strong>Dyalog</strong> <strong>APL</strong> bitmapA text vector:notes.Data_compression.A sparse numeric matrix:nmat„{¾×0=10|¾}?100 100½1000... leading to:algs„'BDHNQRSTUX4Z' © algorithms: packB, ···data„notes.Data_compression dapl.CBits nmat © subject data.size„{stuff„¾ ª Œsize'stuff'}© size function.ttls„•¨'Text' 'BitMap' 'Sparse',¨size¨data © initial data sizes.0 disp (' ',algs),ttls®algs°.pack_test data © comparison table.ÚÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ Û Text 7632 Û BitMap 181940 Û Sparse 20020 ÛÃÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÝÛBÛ 7652 0% 0 16Û 6108 97% 0 16Û 3240 84% 0 0ÛÃÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÝÛDÛ 4612 40% 15 0Û N / A Û N / A ÛÃÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÝÛHÛ 4552 40% 16 78Û 5800 97% 15 531Û 2508 87% 15 110ÛÃÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÝÛNÛ 6768 11% 0 0Û187688 ¯3% 0 0Û 3384 83% 0 0ÛÃÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÝÛQÛ 4676 39% 0 16Û 13980 92% 15 32Û 3760 81% 0 0ÛÃÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÝÛRÛ 9728 ¯27% 16 0Û 15508 91% 0 0Û 5924 70% 0 0ÛÃÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÝÛSÛ 4764 38% 15 500Û 5800 97% 15 4649Û 2612 87% 15 390ÛÃÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÝÛTÛ 5612 26% 16 0Û N / A Û N / A ÛÃÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÝÛUÛ 7816 ¯2% 0 0Û 5776 97% 16 0Û 10284 49% 0 0ÛÃÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÝÛXÛ 6704 12% 46 16Û 5780 97% 47 15Û 6560 67% 16 15ÛÃÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÝÛ4Û 8612 ¯13% 125 172Û 12880 93% 265 296Û 6264 69% 109 125ÛÃÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÝÛZÛ 3816 50% 250 265Û 2536 99% 671 249Û 2556 87% 219 156ÛÀÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙFor comparison, the following examples show some different packings of the samearray 'Mississippi'.disp packB'Mississippi'© simple array packing.Ú…ÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ1 11 MispÛ1 1 1 0 1 1 0 1 1 0 1Û0 0 1 0 1 0 1 0 0 1 0 1 0 1 1 1ÛÀ+ÎÎÎÎÎÎÎ…Á~ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…Á~ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…Ù193


disp packD'Mississippi' © Pack char array to boolean vector.0 0 0 1 0 0 1 0 0 1 0 1 1 0 0 0 0 0 0 1 1 0 0 0 1 1 0 0 1 0 0 1 0 0 0 1 1 0 0 10 0 0 0 0 0 1 0 0 1 1 0 1 1 0 0 0 1 0 1 0 0 1 0 0 1 0 1 0 0 1 0 0 1 0 1 10 1 1 0 1 0disp packH'Mississippi'© Huffman packing.Ú…ÎÂÎÎÎÎÂÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ11ÛsMpiÛ1 3 3 2Û1 0 0 1 1 0 0 1 1 0 0 1 1 1 0 1 1 0 1 1 1ÛÀ~…ÁÎÎÎ…Á~ÎÎÎÎÎ…Á~ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…Ùdisp packQ'Mississippi'© Assorted uniQues packer.Ú…ÎÎÎÂÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛispMÛ1 11Û1 0 0 0 1 0 1 0 0 1 0 0 1 0 1 0 0 1 0 0 1 0 1 1 0 1 1 0 1 0ÛÀÎÎÎ…Á~ÎÎ…Á~ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…Ùdisp packR'Mississippi'Ú…ÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÌÛ11Û1 1 2 1 2 1 2 1ÛMisisipiÛÀ~…Á~ÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎ…Ù© RLE packing.disp packS'Mississippi'© Shannon-Fano packing.Ú…ÎÂÎÎÎÎÂÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ11ÛispMÛ1 2 3 3Û0 1 0 1 1 0 1 1 1 1 1 1 0 1 0 1 0 0 1 0 1 0 0 1 1 0 1 1 0 0ÛÀ~…ÁÎÎÎ…Á~ÎÎÎÎÎ…Á~ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…Ùdisp packU'Mississippi'Ú…ÎÂÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ11ÛMispÛ0 1 2 2 1 2 2 1 3 3 1ÛÀ~…ÁÎÎÎ…Á~ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…Ù© Unique packing.disp packX'Mississippi'© Text packing.Ú…ÎÎÎÂÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛMispÛ1 11Û0 1 0 0 1 0 1 0 0 1 1 0 0 0 0 1 0 1 0 0 1 0 0 0 1 1 0 0 0 0 0 1 1 1ÛÀÎÎÎ…Á~ÎÎ…Á~ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…Ùdisp pack4'Mississippi'© Quad-tree packing.Ú…ÎÎÎÂÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛMispÛ11Û¯3 0 1 ¯1 2 ¯1 2 1 ¯2 2 ¯1 2 1 ¯1 3 ¯1 3 1ÛÀÎÎÎ…Á~…Á~ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…Ùdisp packZ'Mississippi'Ú…ÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÌÛ Û0 0 0 0 1 1 0 0 0Û ÛÛ11Û0 0 1 1 0 1 1 1 0ÛMispÛÛ Û0 1 0 0 1 1 1 1 1‡ ÛÀ~…Á~ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎ…Ù© LZW packing.© Here are some more examples, using a larger text matrix:mm„Œfmt notes.Marilyn© mm is a simple char matrix. See: …Marilyn„chk„{© check of compress-decompress round-trip.size„{a„¾ ª «½Œsize'a'}¾­0 ¸¸ ¸¸ ¾:size ¸¸ ¾' Error: compression round-trip fails'}194


€ chk mm © Raw data size11300packB chk mm © Pack a simple array.11376pack4 chk mm © © Quad-tree packing.9176packR chk mm © Run Length Encoding (RLE packing).7808packT chk ,mm © Simple text vector packager.7136packQ chk mm © Assorted uniQues packer.5276packS chk mm © Shannon-Fano packing5084packU chk mm © Unique packer.5064packH chk mm © Huffman packing.5028packX chk mm © TeXt packer.3800packZ chk mm © Lempel-Ziv-Welch compression.3612See also: packB.195 packD.195 packH.197 packN.202 packQ.202 packR.203See also: packS.204 packT.204 packU.204 packX.205 packZ.205 pack4.193See also: pack.69 base64.174ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎpack4rslt „ {cmp„1} ##.pack4 image© Quad-tree packing.Quad-trees are normally used to compress 2-dimensional data such as bitmaps (ordigital television images?). However, the technique generalises nicely to arraysof any rank. For compression, the function takes, as right argument, an array tobe compressed and returns an encoded quad-tree as result.Left argument [cmp] specifies:¸=1: [default] Full-precision compression of array right argument "image".¸=0: Expansion of right argument to reconstitute the original image.¸>1: Part-precision compression, stops when array has only ¸ distinct items.The underlying idea is simple: the compression is:If all items of the array are identical, then that item.Otherwise, the recursive compression of 2*½½¾ subarray "quadrants".For roughly "square" arrays, such as TV screen images, this quartering workswell but in general, where axes may be of very different lengths, a better secondrule is:Otherwise, the recursive compression of each of the pair of subarrays thatresult from splitting the array along its longest axis.Quad-tree packing works best for arrays that contain significant regions of identicaladjacent values. For more irregular arrays, the technique is poor owingto the overhead of keeping track of small regions. A good bet for Rothko; a badbet for Pollock.Technical notes:195


The compressed form is the triple:uniq: A vector of the unique items of array ¾.shape: Shape of the subject array.subs: A sequence of "sub" records, where a sub is either:- an atom representing a subarray of identical items or- a pair of subs, introduced by a ¯1 marker: (¯1, sub, sub)The result is further compressed by replacing ¯1 ¯1 .. ¯1 with ¯¾.ÀÎÎÎξÎÎÎÎÙNotice that it is not necessary to encode the _shapes_ of compressed subarraysin the compression stream. This is because the array-splitting is completely determinedby the shape of the original subject array and so can be inferred ateach stage of decompression. The only additional packing overhead is a ¯1 marker,which distinguishes a "sub" from an "atom".Note the technique †{¸ ¾}/ of converting the stream vector to a push-down "list"for decompression. This makes reading the stream, one item at a time, quickerand more pleasant. See …list„ for more on this technique.Examples:Œ„vec„10 20/'ab'aaaaaaaaaabbbbbbbbbbbbbbbbbbbb© vector of a's and b's.0 pack4 pack4 10 20/'ab' © round-tripaaaaaaaaaabbbbbbbbbbbbbbbbbbbbdisp pack4 10 20/'ab'Ú…ÎÂÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛabÛ30Û¯2 0 ¯2 0 ¯1 0 1 1 1ÛÀÎ…Á~…Á~ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…Ùchk„{¾­0 pack4 pack4 ¾}chk 10 20/'ab'1Œ„image„˜0.5×°.˜þ0 to 70 0 0 0 0 0 0 00 0 0 0 0 0 0 00 0 1 1 1 1 1 10 0 1 1 1 1 1 10 0 1 1 2 2 2 20 0 1 1 2 2 2 20 0 1 1 2 2 3 30 0 1 1 2 2 3 3© packed structure.© check round-trip© 2D imagedisp pack4 imageÚ…ÎÎÎÎÎÎÂÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ0 1 2 3Û8 8Û¯3 0 ¯1 0 1 ¯1 0 1 ¯3 0 1 ¯1 0 1 ¯1 2 ¯1 2 3ÛÀ~ÎÎÎÎÎ…Á~Î…Á~ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…Ùmm„Œfmt ##.notes.Marilyn© larger 2D ASCII-image …Marilyn„1chk mm© check round-trip.size„{it„¾ ª Œsize'it'} © byte-size of ¾.size mm© size of unpacked array.11300size pack4 mm © size of full-precision packed array.9176size 2 pack4 mm © size of reduced-resolution packed array.3556196


© diminishing sizes of decreasing-resolution packings:{pk„¾ pack4 mm ª «½Œsize'pk'}¨ 1 to 169176 3556 2068 1252 844 624 432 324 260 216 188 140 128 124 108 100© This little function shows the effect of successively refined packing. After© popping up a blank-screen edit window, there is a delay of a couple of seconds© to give you time to maximise the window before the show starts:movie„{ © Increasingly refined image ¾.show„{screen°„(pk dl 1)¾} © show image.pk„{0 pack4 ¾ pack4 image} © ¾-resolution image.dl„{(ŒDL ¾¾)€¸¸ ¾}© apply ¸¸ ¾ then delay ¾¾.screen„{'·'}¨image„¾ © blank screen._„(ŒED dl 2)'screen' © window on image.1:_„(show¨dl 4)²¼½ž,¾ © show movie.}movie Œfmt notes.Marilyn© show movie.© It works best if you reduce the session font size so that the whole© image is visible in the edit window:pix„{© Apply ¸¸ ¾ with font-size ¾¾.save„ŒSE.FontObj © save current font settings.(2œŒSE.FontObj)„¾¾ © set font size.rslt„¸¸ ¾© apply function.ŒSE.FontObj„save © restore font settings.1:_„rslt © shy result of ¸¸ ¾.}movie pix 10 Œfmt notes.Marilyn© show movie in 10-pixel font.See also: Data_compression.190 list.54 Marilyn.604ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎpackBcmp „ {cmp„1} ##.packB exp© Pack a simple array.In some cases (esp. 16 bit bitmaps) this provides pretty good compression ratio!See also: Data_compression.190ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎpackDcmp „ {cmp„1} ##.packD data© Pack char array to boolean vector.Supplied by Veli-Matti Jantunen, this packer uses the same algorithm as packQ,but the result is a simple boolean vector.The algorithm is based on replacing the unique values with boolean sequencesthat start with ones and end with zeros:the most common element is replaced with 1 0the next two with 1 0 0 and 1 1 0the following with 1 0 0 0, 1 1 0 0 and 1 1 1 0and so on.The packing is efficient, if the data contains few unique elements and some ofthem are used widely; normal text documents and <strong>APL</strong> code seem to pack nicely.197


Because it is a boolean vector, we may decrypt the result in several ways:encrypt decrypt{~¾} {~¾}{²¾} {²¾}{¸²¾} {(-¸)²¾}{¾¬(½¾)½¸} {¾¬(½¾)½¸}For example, the following operator uses some of the methods:crypt„{©| ¸: character set (64 elements!)©| ¸¸: 0 = decrypt, 1 = crypt©| ¾¾: key (positive integer)©| ¾: text¸„ŒD,ŒA,'+-',lcase ŒAŒIO„0 ª set„¸key„{((˜2µ¾+1)½2)‚¾}¾¾cry„{b„{(6×—(½¾)÷6)†¾,6½1}packD ¾c„b¬(½b)½keyset[2ƒ(6,(½c)÷6)½c]}© default character set.© works nicer in zero origin.© binarise key.© encryption:© pack, pad with 1's if needed.© poor man's xor encryption.© result is gibberish.yrc„{© decryption:c„,(6½2)‚set¼¾© encode indices.0 packD{(-+/^\²¾)‡¾}c¬(½c)½key © de-xor, unpack (n.b. remove last}}0::¾ ª ¸¸=1:cry ¾ ª yrc ¾- This idea may be developed further, e.g. adding characters that are not used.- Decryption with a wrong key may crash crypt (because the result shape may beanything, say 723572108153 0 1783823 0 0 0 0 0).Examples:packD 'mississippi'0 0 0 1 0 0 1 0 0 1 0 1 1 0 0 0 0 0 0 1 1 0 0 0 1 1 0 0 1 0 0 1 0 0 0 1 1 0 0 10 0 0 0 0 0 0 0 1 1 1 0 1 1 0 0 0 1 0 1 0 0 1 0 0 1 0 1 0 0 1 0 0 1 0 1 1 01 1 0 1 01{¾­0 packD 1 packD ¾}'Full Circle'Œ„crypted„(1 crypt 313)'mississippi'5Na1n4ia1qmLJK1'mississippi'­(0 crypt 313)cryptedSee also: Data_compression.190198


ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎpackHcmp „ {cmp„1} ##.packH exp© Huffman packing.Huffman's algorithm builds a binary tree of unique items in the input string,using the items' frequency of occurrence as a weighting. Frequently occuringitems are placed near the root of the tree and those less frequent towards theleaves. For example, using the string 'Mississippi':Original string: M i s s i s s i p p iunique items: M i s pitem frequency: 1 4 4 2Huffman tree:ÚÎÎÁÎÎÌs ÚÎÁÎÎÌ4 ÚÎÁÎÌ iM p 41 2An item may then be picked from the tree using binary code: 0:left, 1:right. Forexample, in the above tree 'M' is at (1 0 0), 'i' is at (1 1) and 's' is at (0).The full coding for 'Mississippi' is the concatenation of codes:M i s s i s s i p p i(1 0 0) (1 1) (0) (0) (1 1) (0) (0) (1 1) (1 0 1) (1 0 1) (1 1)=> 1 0 0 1 1 0 0 1 1 0 0 1 1 1 0 1 1 0 1 1 1Choosing the shortest codes for the most frequently occurring items, guaranteesthat the total code length is optimally short.Notice that no separation marker is needed between successive code items in theoutput "bit string" as the length of each is determined by the path it describesfrom the root of the tree to its leaf. On expansion, bits are taken one-at-atimefrom the input bit stream, to navigate through the tree. Each time a leafis encountered, it is emitted to the output stream and the process resumed withthe following bit, starting from the tree's root.Output from the encoding is the bit string, together with its Huffman tree. Inaddition, in order to allow simple arrays of _any_ rank, the subject array isravelled, with its original shape prefixed to the output structure.Technical notes:The nested array form of the Huffman tree could be included directly in the outputstructure, but there are more space-efficient representations. An obviousone is to emit the vector of unique items and its corresponding frequency vector.This is appealing in that the sub-function that builds the tree from thefrequency vector may be used for both compression and expansion, and so may beincluded in the packH capsule as a common local function.Using this method, the output would look like this:disp packH'Mississippi'Ú…ÎÂÎÎÎÎÂÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ11ÛMispÛ1 4 4 2Û1 0 0 1 1 0 0 1 1 0 0 1 1 1 0 1 1 0 1 1 1ÛÀ~…ÁÎÎÎ…Á~ÎÎÎÎÎ…Á~ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÙHowever, for an array where any item occurs more than 127 times, elements of thefrequency vector will occupy 16 bits apiece (and 32 bits if any item occurs morethan 32,767 times). A more frugal method is to output the tree's [leaves] and[depths] vectors. For all pratical purposes, items of the depths vector willconsume only 8 bits each.199


disp packH'Mississippi'Ú…ÎÂÎÎÎÎÂÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ11ÛsMpiÛ1 3 3 2Û1 0 0 1 1 0 0 1 1 0 0 1 1 1 0 1 1 0 1 1 1ÛÀ~…ÁÎÎÎ…Á~ÎÎÎÎÎ…Á~ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÙA Huffman tree has the property that each node has either 0 or 2 sub-trees. Itis this property that allows us to reconstruct the tree unambiguously from thedepths of its leaves. For example, there are only four such distinct 4-leaftrees, and they have distinct leaf-depth vectors.4-leaf trees: ÚÎ°Ì ÚΰÎÎÌ ÚΰÎÌ ÚΰÎÌÚÎ°Ì D Ú°ÎÌ D A Ú°ÎÌ A ÚΰÌÚ°Ì C A Ú°Ì Ú°Ì D B Ú°ÌA B B C B C C Dleaf depths: 3 3 2 1 2 3 3 1 1 3 3 2 1 2 3 3In contrast, leaf-depth can not distinguish more general binary trees:2-leaf trees: Ú°Ì Ú°ÎÌÚ° B °Ì BAAleaf depths: 2 1 2 1As a larger example, look at the following (approximate (*)) Huffman tree forthese notes, with character '·' substituted for blanks and newlines. Notice howthe most frequently occurring character '·' is allocated code (0) and thatgroups of related characters such as '()', '{}', '[]', 'Ã Ï Ý', 'Ú Ì' and 'À Ù'tend to appear at the same depth in the tree. Notice also, how the very presenceof this tree diagram in the notes has forced the 'Î' character up to position(1 0 0) in itself.ÚÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎη ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÚÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÁÎÌÚÁÎÎÎÎÎÎÎÎÎÎÎÌ ÚÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌc ÚÎÁÎÌ h ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÚÎÎÎÎÎÁÌ ÚÁÎÎÎÌ ÚÁÎÎÎÎÎÌ ÚÎÁÎÎÎÎÎÎÎÎÚÎÁÎÎÎÌ y v ÚÎÁÌ b ÚÎÎÎÁÎÎÎÌ ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÁÌÚÁÌ ÚÎÁÌ ÚÁÌ 3 ÚÁÎÌ ÚÎÁÎÎÎÌ ÚÎÎÎÁÎÎÎÎÎÌ x Ú} † ÚÁÌ 4 ‡ ¯ A ÚÁÌ ÚÁÌ ÚÎÁÎÌ ÚÎÁÎÌ ÚÎÎÎÁÎÎÎÌ ÚÎÎÎÁB ­ F C D ² ÚÁÌ ÚÁÌ ÚÁÌ ÚÁÌ ÚÁÎÌ ÚÎÁÎÌ ÚÎÁÎÌN E * [ ] \ R 9 S ÚÁÌ ÚÁÌ ÚÁÌ ÚÁÌ ÚÁÌ# ! þ W “ ƒ ¼ ; 5 _(*) The tree is approximate, because inserting it into the notes, changes thenotes' Huffman tree slightly (as does adding this comment). Several iterationsof recalculating and replacing the tree resulted in a loop of several distincttrees, of which the above is one. Therefore, the above tree _does not_ representthese notes exactly unless adding this final remark happens to cause the iterationsto converge! The tree was formatted using:200hfmt„{join„{¾®³††{¸,' ',¾}/‡°³¨¸}arch„{¸¸ ¸[ŒIO+{¾+Ÿ\¾}¸¸'Á'=œ‡¾]}0=­¾:†,‡•,¾lft rgt„’¨¾case„×|­¨¾0 0­case:lft rgt join'ÚÁÌ' © leaf-leaf,0 1­case:lft rgt join'ÚÁ',' ÎÌ'²arch rgt © leaf-branch,}© Format Huffman tree.© join sub-trees.© make ÚÎÁÎÌ archway.© leaf: char mat.© sub-trees and their,© relative depths:1 0­case:lft rgt join'ÁÌ',þ' ÎÚ'+arch lft © branch-leaf,lft rgt join(' ÎÚ'+arch lft),'Á',' ÎÌ'²arch rgt © branch-branch.


-----------compression-----------The tree is built by taking the two most infrequently occurring items in theunique list and replacing them with a single item: their "pair" together withthe sum of their frequencies. This process is repeated until only a single itemremains:tree„{© Huffman tree.1=½¾:œ²œ¾© list exhausted: donenxt„¾[2†“œ¨¾]© next two lowest frequencies,freqs items„‡³†nxt© and corresponding items.’(¾~nxt),›(+/freqs),›items © collect 2 most infrequent items.}‡³†freq uniq© tree from frequency-item pairs.Ú…ÎÎÂÎÎÎÂÎÎÎÂÎÎÎÌ Ú…ÎÎÂÎÎÎÂÎÎÎÎÎÎÌ Ú…ÎÎÂÎÎÎÎÎÎÎÎÎÎÌ Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ1 MÛ4 iÛ4 sÛ2 pÛ => Û Û ÛÚ…ÂÎÎÌÛ => Û ÛÚ…ÂÎÎÎÎÎÎÌÛ => ÛÚ…ÎÂÎÎÎÎÎÎÎÎÎÎÌÛÀ+Î…Á+Î…Á+Î…Á+Î…Ù Û4 iÛ4 sÛÛ3ÛMpÛÛ Û ÛÛ ÛÚ…ÎÂÎÌÛÛ ÛÛ ÛÚ…ÂÎÎÎÎÎÎÌÛÛÛ Û ÛÀÎÁÎ…ÙÛ Û4 sÛÛ7ÛÛMpÛiÛÛÛ ÛÛ ÛÛ ÛÚ…ÎÂÎÌÛÛÛÀ+Î…Á+Î…ÁÎÎÎÎÎ…Ù Û ÛÛ ÛÀÎ…ÁÎÙÛÛ ÛÛ11ÛÛsÛÛMpÛiÛÛÛÛÛ ÛÀÎÁÎÎÎÎÎ…ÙÛ ÛÛ ÛÛ ÛÀÎ…ÁÎÙÛÛÛÚ…ÂÎÎÎÎÎÎÌ À+Î…ÁÎÎÎÎÎÎÎÎÎ…Ù ÛÛ ÛÀÎÁÎÎÎÎÎ…ÙÛÛyielding tree: Û ÛÚ…ÎÂÎÌÛÛÀ~ÎÁÎÎÎÎÎÎÎÎÎ…ÙÛÛsÛÛMpÛiÛÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÙÛ ÛÀÎ…ÁÎÙÛÀÎÁÎÎÎÎÎ…ÙThe leaves and depths vectors are extracted from the tree by a simple recursivetraversal.leaves depths„‡³†tree{ © tree leaves and depths.«­½¸:›¸ ¾© leaf: leaf and depth.†,/¸ ’¨1+¾© branch: traverse deeper sub-branches.}0 © starting at depth 0 for the root.---------expansion---------The tree is restored from its [depths] and [leaves] vectors with a single reductivepass across their transpose [depth-leaf] vector. During the reduction,the operand function examines adjacent nodes, replacing ones of identical depthwith a new pair of depth less by 1. The reduction is "seeded" with a dummy depthof ¯1 on the right. Using the 'Mississippi' example:disp depths leavesÚ…ÎÎÎÎÎÎÂÎÎÎÎÌÛ1 3 3 2ÛsMpiÛÀ~ÎÎÎÎÎ…ÁÎÎÎ…Ùdisp ‡³†depths leavesÚ…ÎÎÂÎÎÎÂÎÎÎÂÎÎÎÌÛ1 sÛ3 MÛ3 pÛ2 iÛÀ+Î…Á+Î…Á+Î…Á+Î…Ùtree„« 0 1œ{(œ¸)¬œœ¾:(›¸),¾(²{œ¾-1}\²‡³†¸(œ¾))’ 1‡¾}/(‡³†depths leaves),¯1© depths and leaves vectors.© depth-leaf vector.© reconstituted Huffman tree.© distinct adjacent depths: continue.© identical adjacent depths: coalesce.© depths/leaves ++ trailing dummy entry.The first line skips over (or accumulates into the result,) adjacent items iftheir depths differ:(œ¸)¬œœ¾:(›¸),¾© distinct adjacent depths: continue.201


The second line calls the operand function recursively for adjacent items ofidentical depth. We can break open the line to examine its constituent parts:(·················)’ 1‡¾ © repeat with adjacent nodes coalesced.·············¸(œ¾)······ © pair of adjacent same-depth tree nodes.··········‡³†··········· © => (depth depth) (node node)·²{····}\²·············· © apply to _first_ item of pair.···œ¾-1················· © reduced depth························ © => (depth-1)(node node)The 'Mississippi' example proceeds through the reduction as follows:ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ © adjacent depths:ÚÎÎÁÎÎÎÌÚÎÎÎÂÎÎÎÂÎÎηÎÌ Ú·ÎÌÛ 1 Û 3 Û 3 Û 2 Û Û¯1 Û© depths 2 ¯1 distinct: continue.Û s Û M Û p Û i Û Û ÛÀÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÙ ÀÎÎÎÙÚÎÎÎÂÎÎÎÂÎÎÎÌ ÚÎÎÎÂÎÎÎÌÛ 1 Û 3 Û 3 Û Û 2 Û¯1 ÛÛ s Û M Û p Û Û i Û ÛÀÎÎÎÁÎÎÎÁÎÎÎÙ ÀÎÎÎÁÎÎÎÙÚÎÎÎÂÎÎÎÌ ÚÎÎÎÂÎÎÎÂÎÎÎÌÛ 1 Û 3 Û Û 3 Û 2 Û¯1 ÛÛ s Û M Û Û p Û i Û ÛÀÎÎÎÁÎÎÎÙ ÀÎÎÎÁÎÎÎÁÎÎÎÙÚÎÎÎÂÎÎÎÌ ÚÎÎÎÂÎÎÎÌÛ 1 Û 2 Û Û 2 Û¯1 ÛÛ s ÛÚÁÌÛ Û i Û ÛÛ ÛM pÛ ÀÎÎÎÁÎÎÎÙÀÎÎÎÁÎÎÎÙ© depths 3 2 distinct: continue.© depths 3 3 same: pair 'M' 'p'© depths 2 2 same: pair 'Mp' 'i'ÚÎÎÎÂÎÎÎÎÎÌ ÚÎÎÎÌÛ 1 Û 1 Û Û¯1 Û © depths 1 ¯1 distinct: continue.Û s Û ÚÎÁÌÛ Û ÛÛ ÛÚÁÌ iÛ ÀÎÎÎÙÛ ÛM p ÛÀÎÎÎÁÎÎÎÎÎÙÚÎÎÎÌ ÚÎÎÎÎÎÂÎÎÎÌÛ 1 Û Û 1 Û¯1 Û © depths 1 1 same: pair 's'('Mp' 'i')Û s Û Û ÚÎÁÌÛ ÛÀÎÎÎÙ ÛÚÁÌ iÛ ÛÛM p Û ÛÀÎÎÎÎÎÁÎÎÎÙÚÎÎÎÎÎÎÎÌ ÚÎÎÎÌÛ 0 Û Û¯1 Û © depths 0 ¯1 distinct: continue,ÛÚÁÎÎÎÌ Û Û ÛÛs ÚÎÁÌÛ ÀÎÎÎÙÛ ÚÁÌ iÛÛ M p ÛÀÎÎÎÎÎÎÎÙÚÎÎÎÎÎÎÎÂÎÎÎÌÛ 0 Û¯1 Û © reduction complete.ÛÚÁÎÎÎÌ Û ÛÛs ÚÎÁÌÛ ÛÛ ÚÁÌ iÛ ÛÛ M p Û ÛÀÎÎÎÎÎÎÎÁÎÎÎÙ202


The tree is extracted from the final (scalar) result of the (vector) reductionusing (« 0 1œ)ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛÚ…ÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÌÛÛÛÚ…ÂÎÎÎÎÎÎÎÎÎÎÌÛ ÛÛÛÛÛ ÛÚ…ÂÎÎÎÎÎÎÌÛÛ ÛÛ Ú…ÂÎÎÎÎÎÎÌÛÛÛ ÛÛ ÛÚ…ÎÂÎÌÛÛÛ ÛÛ Û ÛÚ…ÎÂÎÌÛ{« 0 1œ¾} ÛÛÛ0ÛÛsÛÛMpÛiÛÛÛÛ¯1ÛÛ => ÛsÛÛMpÛiÛÛÛÛÛ ÛÛ ÛÀÎ…ÁÎÙÛÛÛ ÛÛ Û ÛÀÎ…ÁÎÙÛÛÛÛ ÛÀÎÁÎÎÎÎÎ…ÙÛÛ ÛÛ ÀÎÁÎÎÎÎÎ…ÙÛÛÀÎÁÎÎÎÎÎÎÎÎÎ…ÙÛ ÛÛÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎ…Á~ÎÙÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÙHaving reconstructed the Huffman tree, the bit-stream is traversed to retrievethe original items. A potential performance bottleneck for the unpacking function,is that the algorithm accesses one bit at a time, using consecutive bits totraverse the tree. An alternative approach is to construct a dictionary that canbe indexed by the (2°ƒ) of a number of consecutive bits at once. If the maximumdepth of the tree is [maxd], then a dictionary of (2*maxd) entries will have anentry for any possible value of [maxd] bits taken from the input string. For_short_ paths through the tree (for example, to the 's' of 'Mississippi'), dictionaryentries are duplicated. Each dictionary entry contains the value of itsleaf, and the number of bits required to reach it, and hence to skip in the inputstream. The input stream is padded with [maxd] dummy bits, to prevent thefinal indexing operation from failing.disp dictÚ…ÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÌÛ1 sÛ1 sÛ1 sÛ1 sÛ3 MÛ3 pÛ2 iÛ2 iÛÀ+Î…Á+Î…Á+Î…Á+Î…Á+Î…Á+Î…Á+Î…Á+Î…ÙPrefixing bit string values for each entry:0 disp ³†(,¼2 2 2)dictÚÎÎÎÎÎÂÎÎÎÌÛ0 0 0Û1 sÛÃÎÎÎÎÎÏÎÎÎÝÛ0 0 1Û1 sÛÃÎÎÎÎÎÏÎÎÎÝÛ0 1 0Û1 sÛÃÎÎÎÎÎÏÎÎÎÝÛ0 1 1Û1 sÛÃÎÎÎÎÎÏÎÎÎÝÛ1 0 0Û3 MÛÃÎÎÎÎÎÏÎÎÎÝÛ1 0 1Û3 pÛÃÎÎÎÎÎÏÎÎÎÝÛ1 1 0Û2 iÛÃÎÎÎÎÎÏÎÎÎÝÛ1 1 1Û2 iÛÀÎÎÎÎÎÁÎÎÎÙRef: David A. Huffmann, "A Method for the Construction of Minimum-RedundancyCodes," Proc. IRE, vol. 40, no. 9, pp. 1098-1101; September, 1952.See also: Data_compression.190 morse.479203


ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎpackNcmp „ {cmp„1} ##.packN exp© Null packing.Returns a 3-vector of: shape; boolean vector indicating non-null items; and theravel of the original array with nulls removed. This compression is very quickand is effective for simple arrays containing a large proportion of zeros orblanks.The saving comes from the fact that each item in the boolean vector requiresonly a single bit, instead of from 8- to 64-bits in the original. Of course,packN-ing a _boolean_ array is always counter-productive.Examples:string„'whistles far and wee' © text string.disp packN string© format of packN'd string.Ú…ÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÛ31Û1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 1 1 1 0 1 1 1ÛwhistlesfarandÀ~…Á~ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎ48104size„{stuff„¾ ª Œsize'stuff'}size stringsize packN stringsize 1000½string© show size.© size of char vector.© packed: nett loss.© larger string.1016size packN 1000½string © packed: nett gain.760mat0 0 0 2.48 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 3.66 0 0 7.57 09.92 0 0 0 0 0 0 0 0 0 0 6.33© numeric matrix.disp packN mat© format of packN'd matrix.Ú…ÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÛ4 12Û0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 1À~ÎÎ…Á~ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ404128size matsize packN mat© original size.© packed: nett gain.See also: Data_compression.190ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎpackQcmp „ {cmp„1} ##.packQ data© Assorted uniQues packer.The data must have no more than 256 unique elements.Veli-Matti Jantunen suggests the following technique for reducing the size of ashipped executable:© Using:(Œio Œml)„1 3© Remove comments and empty lines (enhanced hhh, see …rmcm„).204


{0¹½¾:z„''’ 1‡¾,(–†¾).{((¾,'.')°,¨~°' '¨‡Œnl 9){¸}{c„Œcr ¾ ª ~'©'¹c:0((,Ÿ\(c='©')^=\c¬'''')/,c)„' 'Œfx(Ÿ/c¬' ')šc}¨~°' '¨‡Œnl 3 4}†¾},'#'© Make the list for packing© Packlist„(~°' '¨‡Œnl 3 4)~'LX' 'packQ' 'Do'‘fns„packQ 1‡¹{Œtc[3],1‡¹Œtc[2],¨Œnr ¾}¨list© Make executable...© The LX function starts with the following:{Œfx(¾¬2œŒtc)›¾)¨{(¾¬3œŒtc)œ¾}0 packQ ‘fns ª Œex'‘fns'See also: Data_compression.190 rmcm.247ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎpackRcmp „ {cmp„1} ##.packR exp© Run-Length Encoding (RLE packing).Run-length encoding is suitable for heavily repeated data, otherwise it's prettyinefficient. Repeated items are represented by the item and its repeat count.Technical note:Repeated item runs are detected in the coding by pairwise reduction using notequal(¬):runs„1,2¬/vect© mask of start of runs.Changing the not-equal to a not-match (») would reduce performance a little, butallow packR to accommodate nested arguments.Examples:disp packR'Mississippi'Ú…ÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÌÛ11Û1 1 2 1 2 1 2 1ÛMisisipiÛÀ~…Á~ÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎ…Ùdisp packR 11 11 11 22 22 11 11Ú…ÂÎÎÎÎÎÂÎÎÎÎÎÎÎÎÌÛ7Û3 2 2Û11 22 11ÛÀ…Á~ÎÎÎ…Á~ÎÎÎÎÎÎ…Ù205


Œ„mat„{¾×[Œio]¾°.‰¾}¼9 © lower-diagonal matrix.1 0 0 0 0 0 0 0 02 2 0 0 0 0 0 0 03 3 3 0 0 0 0 0 04 4 4 4 0 0 0 0 05 5 5 5 5 0 0 0 06 6 6 6 6 6 0 0 07 7 7 7 7 7 7 0 08 8 8 8 8 8 8 8 09 9 9 9 9 9 9 9 9disp packR matÚ…ÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ9 9Û1 8 2 7 3 6 4 5 5 4 6 3 7 2 8 1 9Û1 0 2 0 3 0 4 0 5 0 6 0 7 0 8 0 9ÛÀ~Î…Á~ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…Á~ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÙSee also: Data_compression.190ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎpackScmp „ {cmp„1} ##.packS exp© Shannon-Fano packing.The Shannon-Fano algorithm is a variant of Huffman-coding, where the most frequentitem is replaced with the shortest key.Suitable for text packing, but alas, unpacking is s-l-o-w in <strong>APL</strong> (unless someoneinvents a really good way to do that).Because the indices are of variable length, expansion is pretty slow (and boring).See also: Data_compression.190ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎpackTcmp „ {cmp„1} ##.packT exp© Simple text vector packager.[packT] is a simple text vector packager, proposed by Stefano Lanzavecchia.The repeated items are replaced with [esc][asc][chr], where:esc = "escape" character (ŒAV[1 2 or 3], it shouldn't be in the data!)asc = ŒAV character indicates how many times the char must be repeatedchr = the characterBecause the RLE coding takes three characters, short repeated strings are notpacked (and thus ŒAV[1 2 3] are free for "esc"); if the repeated areas arelonger than 256 chars, there will be more esc sequences. If there are "esc"characters, they are doubled. This is a nice algorithm, but I (VMJ) have foundno real world data where it would be useful.See also: Data_compression.190ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎpackUcmp „ {cmp„1} ##.packU exp© Unique packing.Quick, suitable for cases where the data has only a few unique items, and thusthe index part consists of (small) integers, i.e. small bitmaps.206


Example:disp packU'Mississippi'Ú…ÎÂÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ11ÛMispÛ0 1 2 2 1 2 2 1 3 3 1ÛÀ~…ÁÎÎÎ…Á~ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÙSee also: Data_compression.190ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎpackXcmp „ {cmp„1} ##.packX txt© TeXt Packer.Supplied by Veli-Matti Jantunen, packX splits its text argument into two characterpairs, and saves the indices of the pairs that can be made from the uniquelist.The compression ratio is not quite as good as packH, but the uncompress speed ismuch better.VMJ says: I tested one 250 kB text file, which gave me the results:packer time to pack/pack+unpack ratio------ ------------------------ -----packH 0,4s 7,5s 51,6%packS 0,9s (>5min..) 51,1%packB 0,2s 0,4s 26,8%packX 1,4s 1,7s 30,8%See also: Data_compression.190ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎpackZcmp „ {cmp„12} ##.packZ exp© Abraham Lempel, Jacob Ziv, Terry Welch.The LZW algorithm relies on recurrence of sequences (strings) of items in itsinput vector. The items are typically characters, but may be drawn from any"alphabet" of distinct values, including for example the boolean alphabet: 0 1,or the unique items of a nested vector (see the example using …tokens„, below).The algorithm maintains a "dictionary", which maps strings in the input vectorto their associated output codes. The dictionary initially contains mappingsfor all possible strings of length one. Input is taken one item at a time tofind the longest initial string already present in the dictionary. The code forthat string is output and the string, extended with the following item (i) fromthe input vector, is added to the dictionary with the next unused code (obtainedby incrementing a counter). The process repeats, with the input string beginningwith (i).The number of bits in an output code, and hence the maximum number of entries inthe dictionary, is usually fixed and once this limit is reached, no more entriesare added. A code width of 12 bits has been recommended. The absolute value ofleft argument [cmp] specifies this limit. If [cmp] is negative, the dictionary,rather than the compression structure is returned. See example below.Technical notes:Output from the function is a 3-vector: (shape codes alphabet). [codes] is avector of non-negative indices into the dictionary, encoded as a w-row booleanmatrix, where w is the number of bits (default maximum 12) allocated for eachvalue. The integer vector for codes is easily reconstituted with 2ƒ¾. [alphabet]is the set of unique items in the input vector.207


Each new "string" inserted into the dictionary is identical to an existing one,but with one extra "character" appended. In light of this, the dictionary may berepresented as a tree. For an alphabet of ¸ unique items, each node in the treehas ¸ sub-nodes: an "¸-ary tree". For example, a boolean vector (with alphabet:0, 1) will produce a binary tree and a string that uses all values from ŒAV willgive rise to a 256-ary tree. Extracting the code associated with a string fromthe dictionary amounts to using a character at a time to navigate through eachof the tree's nodes. Encountering a null node signals that the string is notcurrently in the dictionary, which can be extended by adding a new node witha codeword representing the new string. This type of tree is known in the tradeas a "suffix trie" (Aho et al 1983).Historical note:The 20-year patent on this beautiful algorithm finally expired world-wide on 7thJuly, 2004. Prior to this date, incorporating any coding of LZW in commercialsoftware incurred a royalty.(muse:This raises the question of whether algorithms are invented or discovered.The following thought-experiment suggests they are _discovered_:If it turns out that life on Mars has advanced sufficiently to produce mathematicians,their set of prime numbers must coincide with ours (even iftheir anatomy has lead them to a counting base other than decimal).Neither civilisation invented the sequence of prime numbers; it was already"out there", when we became aware of, or discovered it.Same goes for algorithms. If the Martians are aware of prime numbers, in allprobability, they will also be aware of the sieving algorithm that extractsthem (perhaps they call it "The Sieve of Zork"). Similarly, it is unlikelythat they are unaware of the subtract-&-swap method for finding highestcommon factors, which was discovered on our planet by Euclid. And so on;Thus, algorithms exist independently of the cultures that discover them (anidea proposed by the Greek philosopher and mathematician Plato ¯427-¯347).Viewed in this light, useful algorithms could be seen as diamonds in theotherwise dark coal-face that is the set of all expression transformationsequences.()However, it's hard (for JMS) to see why the same argument doesn't applyto artefacts generally accepted to be inventions: the baby sling, thewheel/axle, the stirrup, the beer-can ring-pull, and so forth. Perhapsit's a question of the degree of complexity of the construction or perhapsit depends upon whether the components are discrete or continuous.)Of course, both inventions and discoveries may be patented.Examples:1packZ'mississippi'11 0 0 0 0 1 1 0 0 0 misp0 0 1 1 0 1 1 1 00 1 0 0 1 1 1 1 1{¾­0 packZ packZ ¾}'mississippi'© compress char vector.© expand recovers original.2ƒ2œpackZ'mississippi'0 1 2 2 5 7 3 3 1208© ... bool matrix decoded.


disp ¯8 packZ'mississippi' © final compression dictionary.Ú…ÂÎÂÎÂÎÂÎÎÂÎÎÂÎÎÂÎÎÂÎÎÎÂÎÎÎÂÎÎÂÎÎÌÛmÛiÛsÛpÛmiÛisÛssÛsiÛissÛsipÛppÛpiÛÀ…Á…Á…Á…ÁÎ…ÁÎ…ÁÎ…ÁÎ…ÁÎÎ…ÁÎÎ…ÁÎ…ÁÎ…Ùsegs„{(¯12 packZ ¾)[Œio+2ƒ2œpackZ ¾]} © dictionary entry per code word.disp segs'mississippi'Ú…ÂÎÂÎÂÎÂÎÎÂÎÎÂÎÂÎÂÎÌÛmÛiÛsÛsÛisÛsiÛpÛpÛiÛÀ…Á…Á…Á…ÁÎ…ÁÎ…Á…Á…Á…Ù© segments for string.{¾­†,/segs ¾}'mississippi'© enlist of segs recovers original.1disp segs 40½'a'© segs for highly repetitive string.Ú…ÂÎÎÂÎÎÎÂÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÎÂÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÂÎÎÎÎÌÛaÛaaÛaaaÛaaaaÛaaaaaÛaaaaaaÛaaaaaaaÛaaaaaaaaÛaaaaÛÀ…ÁÎ…ÁÎÎ…ÁÎÎÎ…ÁÎÎÎÎ…ÁÎÎÎÎÎ…ÁÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎ…ÁÎÎÎ…Ùdisp segs 40½'abcd'© segs for less repetitive string.Ú…ÂÎÂÎÂÎÂÎÎÂÎÎÂÎÎÎÂÎÎÂÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÂÎÎÎÌÛaÛbÛcÛdÛabÛcdÛabcÛdaÛbcÛdabÛcdaÛbcdÛabcdÛabcdaÛbcdaÛbcdÛÀ…Á…Á…Á…ÁÎ…ÁÎ…ÁÎÎ…ÁÎ…ÁÎ…ÁÎÎ…ÁÎÎ…ÁÎÎ…ÁÎÎÎ…ÁÎÎÎÎ…ÁÎÎÎ…ÁÎÎ…Ùdisp packZ'hello world'Ú…ÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÌÛ Û0 0 0 0 0 1 1 0 1 0 1Û ÛÛ11Û0 0 1 1 1 0 0 1 1 1 1Ûhelo wrdÛÛ Û0 1 0 0 1 0 1 1 0 0 1‡ ÛÀ~…Á~ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎ…Ù© compressed char vector.disp packZ 11 Œdr'hello world' © compressed bool vector.Ú…ÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÌÛ Û0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 1 0Û ÛÛ Û0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 0 1 0 1 1 0 1 1 0 0 1 0 0 1 1 1 0Û ÛÛ88Û0 0 0 0 0 1 0 1 1 1 0 0 1 1 1 1 1 0 0 0 1 0 0 0 1 0 1 0 0 1 1 0Û0 1ÛÛ Û0 0 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1 1 0 0 1 0 1 1 1 0 0 0 0 1 0 0Û ÛÛ Û0 1 1 0 0 0 0 0 1 0 1 0 1 0 0 0 1 1 1 1 1 0 1 0 1 0 0 1 0 0 0 0‡ ÛÀ~…Á~ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…Á~Î…ÙpackZ 83 ŒDR'hello world'© compressed integer vector.Ú…ÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ Û0 0 0 0 0 1 1 0 1 0 1ÛÛÛ11Û0 0 1 1 1 0 0 1 1 1 1Û104 101 108 111 32 119 114 100ÛÛ Û0 1 0 0 1 0 1 1 0 0 1‡ÛÀ~…Á~ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…Á~ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…Ùsize„{omega„¾ ª «½Œsize'omega'}size notes.packZ© function for size in bytes.© size of notes.7200size packZ notes.packZ © size of compressed notes.3948size 8 packZ notes.packZ © ... with 8-bit code words.5388size 100 100½¼7© size of numeric matrix.10020size packZ 100 100½¼7 © compressed size.512209


disp mat © nested matrix.Ú…ÎÎÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÎÎÎ̇ScissorsÛStoneÛ Paper ÛÃÎÎÎÎÎÎÎ…ÏÎÎÎÎ…ÏÎÎÎÎÎÎÎ…ÝÛ Stone ÛPaperÛScissorsÛÀÎÎÎÎÎÎÎ…ÁÎÎÎÎ…ÁÎÎÎÎÎÎÎ…Ùsize mat188size packZ ³mat172disp packZ matÚ…ÎÎÂÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ Û0 0 0 1 0ÛÚ…ÎÎÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÌÛÛ2 3Û0 0 1 0 0ÛÛScissorsÛStoneÛPaperÛÛÛ Û0 1 0 0 0‡ÀÎÎÎÎÎÎÎ…ÁÎÎÎÎ…ÁÎÎÎÎ…ÙÛÀ~Î…Á~ÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…Ù© matrix size.© compressed size.© compressed matrix.disp tokens œŒnr'packZ'© tokens in first line of packZ.Ú…ÎÎÎÎÂÎÂÎÂÎÎÎÂÎÂÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÛpackZÛ„Û{ÛŒIOÛ„Û0ÛÛ© Lempel-Ziv-Welch compressÀÎÎÎÎ…Á…Á…ÁÎÎ…Á…Á…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎtoks„†,/tokens¨Œnr'packZ'size toks© nested vector of packZ's tokens.© size of packZ's tokens.11508size packZ toks © size of compressed tokens.4672{¾­0 packZ packZ ¾}toks © nested pack: full circle.111{¾­0 packZ packZ ¾}'hello world'{¾­0 packZ packZ ¾}11 Œdr'hello world'© char pack: full circle.© bool pack: full circle.See also: Data_compression.190 tokens.170ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎcondrslt „ (if ##.cond then cond else) arg © proposition:consequence:alternativePhil Last says: this operator implements the triadic structure:[if] proposition [then] consequence [else] alternative.The correct way to call it is as above, monadically with two calls to the operatorseparating the three operands. The resulting derived conditional functionis similar to the D: guard construct ...proposition : consequence ª alternativeexcepting that it is a function, can be assigned a name, and within the D: contextits result is captured regardless of the truth of the proposition or not atall. Any of the three, proposition, consequence and alternative, can be eitherarrays or monadic (ambivalent) <strong>functions</strong> on arg. (proposition) or (propositionarg) must be a boolean singleton. Any of them can of course be further (parenthesised)or named conditionals on arg.210


The development started two decades ago in <strong>APL</strong>2 with defined operators such as:where:ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ ’ r„(f then g)w Û ’ r„a(f else g)w ÛÛ r„†g mon/(¼f w),›w Û r„†f mon/(¼a),g mon/(¼~a),›w ÛÛ ’ Û ’ ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ ’ r„a(f mon)w ÛÛ r„f w ÛÛ ’ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙrslt „ (proposition then consequence) argrslt „ test (consequence else alternative) argIn different versions of both operators the control, here effected by use ofreduction on a one or two item vector, could instead be by branching, using:If &c. control structures or latterly by use of a guard in a D:op. The idea wasto make all of these methods redundant. The operators, (then) and (else), couldnot be used together because the derived function (f then g else h) is dyadic,as it is derived from (else), and will run either (f then g) or (h) according toits boolean left argument where what is required is to run (f) unconditionallyfollowed by (g) or (h) according to its boolean result.A breakthrough was made on a napkin in Helsingør, a day or two earlier in truthand a notebook, by coding the two operators to work together to produce theMONADIC derived function (f then g else h) fulfilling these criteria. To do so,arguments were passed from (else) to (then) to control the calling of the propositionand consequence separately if at all. These worked exactly as expectedand were also upwardly compatible with the definitions above. Here are theirdefinitions ...ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ then„{¸„'M' Û else„{¸„'M' ÛÛ ¸='Q':(€°¸¸)¾ Û ¸=1:(€°¸¸)¾ ÛÛ ¸='Y':(€°¾¾)¾ Û ¸=0:(€°¾¾)¾ ÛÛ (€°¸¸)¾:(€°¾¾)¾ Û 'Q' ¸¸ ¾:'Y' ¸¸ ¾ ÛÛ ¾ Û (€°¾¾)¾ ÛÛ } Û } ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙNotice the (almost) identical lines in each.In (else) these operate the older standalone use where a boolean left argumentdetermines whether the consequence or the alternative should be run. In (then)these carry out the instruction passed in the left argument by the third line of(else) to run the proposition and possibly the consequence. The other lines of(then) operate the older standalone monadic use. However rigorously defined,having two disparate operators which can both be used independently but whichCAN work in concert and must agree on an arbitrary protocol to do so goesagainst the spirit if not the letter of good functional programming.Also, a conditional without an alternative, (proposition then consequence), canbe considered in the same dim light. Nevertheless they lasted a month before,walking around Københavns Søen, I realised this weakness could be overcome byproducing a single operator that implements the best of both without any dependencies.In fact the napkin coding of (else) as it stood was adequate for thetask after substituting 2, 1 and 0 for 'M', 'Q' and 'Y' but the clause ...rslt „ (proposition else consequence else alternative) arg211


has lost its meaning and confuses more by the fact that it SEEMS to mean somethingwhile not actually doing so.()This may be the prejudice of a native English speaker; I have heard, thoughI think it's probably a misunderstanding, that some eastern languages lackwords for the concepts carried by "therefore" and "because". I have alsoheard that programmers in eastern countries prefer the <strong>APL</strong> language becauseit is not encumbered with English (or western) language contructs.The final coding of the operator dispenses with the standalone use of both(then) and (else). Thus it is always coded twice separating the three operands.I decided that using the left argument as an "internal" flag really aught topreclude its use otherwise so although it's not impossible to call the derivedfunction dyadically its use is deprecated and its results are rather unpredictable.Including the different permutations of array and function operands therewere sixteen calling sequences for the (then) and (else) operators used individuallyand in combination. With the restrictions imposed by a single conditionalsymbol only usable in combination we are left with eight ...RSLT „ (proposition cond consequence cond alternative) ARGRSLT „ (proposition cond consequence cond OTHER) ARGRSLT „ (proposition cond VALUE cond alternative) ARGRSLT „ (proposition cond VALUE cond OTHER) ARGRSLT „ (TEST cond consequence cond alternative) ARGRSLT „ (TEST cond consequence cond OTHER) ARGRSLT „ (TEST cond VALUE cond alternative) ARGRSLT „ (TEST cond VALUE cond OTHER) ARGSome of the parentheses in the above are redundant. If you don't know which, youare best to leave them in. The last clause makes no use of ARG except to force<strong>APL</strong> to call the derived function rather than assigning it into RSLT!An alternative coding---------------------An alternative, if slightly more challenging, coding of cond might be:cond„{ © proposition : consequence : alternativem q y„147036925 258147036 369258147¸„m€°¸¸ÿ(¸=q)€€°¾¾ÿ(¸=y)€¸¸{(q ¸¸ ¾)¸¸{y°¸¸ÿ¸€€°¾¾ÿ(~¸)€¾}¾¾ ¾}¾¾ÿ(¸=m)€¾}Examples:eis„1°=°­cond›cond€© enclose if depth=1.disp 1 (,1) (›,1) © items have depth 0 1 2Ú…ÂÎÂÎÎÎÌÛ Û ÛÚÎÌÛÛ1Û1ÛÛ1ÛÛÛ Û ÛÀ…ÙÛÀÎÁ…ÁÎÎÎÙdisp eis¨ 1 (,1) (›,1)Ú…ÂÎÎÎÂÎÎÎÌÛ ÛÚÎÌÛÚÎÌÛÛ1ÛÛ1ÛÛÛ1ÛÛÛ ÛÀ…ÙÛÀ…ÙÛÀÎÁÎÎÎÁÎÎÎÙunless„{~°¾¾ cond ¸¸ cond€¾}© enclose depth-1 items.212log„µunless(ˆ°0)


log 31.0986122890log 0or„{(Ÿ/¸)cond((0ƒ¸)cond ¾¾ cond((2=½¸)cond ¸¸ cond((¯1‡¸)°¸¸)))cond€¾}0 0 0 0-or×or—or˜7.57.50 0 0 1-or×or—or˜7.570 0 1 0-or×or—or˜7.580 1 0 0-or×or—or˜7.511 0 0 0-or×or—or˜7.5¯7.5© Used as a dyadic, rather than "triadic" construct,© cond is equivalent to …else„:0 1 ÷cond-¨ 3¯3 0.33333333330 1 ÷else-¨ 3¯3 0.3333333333See also: while.221 until.222 else.212 and.233 or.233 co_ops.532ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎdorslt „ (dewy ##.do) rarg© Apply no-result function "en passant".A function [sic] that doesn't return its result is an embarrassment to the D-programmer. Operator [do] applies such a function to its argument and returnsthe argument as result.3{} do 3For example, suppose we want a D-fn "wset" which, given a ref to an object and aproperty-value pair, sets the new value and returns the previous one as result.We might be tempted to try something along the lines of:wset„{ © Set new prop-value ¾ on object ¸.rslt„¸ ŒWG ŒIOœ¾ © get old value.¸ ŒWS ¾ © set new value. !!!!!!! wrongrslt© return old value.}This won't work because the function terminates on the second line (ŒWS) beforereturning "rslt" on the third. We can't use a local assignment on the secondline to prolong execution:_„¸ ŒWS ¾ © set new value. !!!!!!! wrongbecause ŒWS does not (currently) return a result and so would produce a VALUEERROR. So we use [do] in the following way. Note that, as [do] derives a monadicfunction (takes no left argument), we are obliged to bind ŒWS's left argument ¸to form a monadic operand ¸°ŒWS:or_„¸°ŒWS do ¾0•¸°ŒWS do ¾:© set new value.© set new value.213


or we could combine the final two lines into:wset„{ © Set new prop-value ¾ on object ¸.rslt„¸ ŒWG ŒIOœ¾ © get old value.rslt•¸°ŒWS do ¾ © set new value and return old value.}(muse:To be of any value, <strong>functions</strong> that don't return results must have usefulside-effects. In other words, they _do_ things, rather than indicate whatthe value of the function at a particular argument _is_. For more on this,see: http://dfns.dyalog.com/downloads/howcomp.pdf}Technical notes:This coding of [do] depends on the behaviour of primitive execute (–): Executeof a diamond-separated string is defined to return the evaluation of the rightmostsegment as result.do„{–'¸¸ ¾ ª ¾' ª ¸¸}© Apply no-result function.Notice that we must include an unquoted (and unvisited) ¸¸ within the braces, inorder to denote [do] as an operator and so consume the function operand to itsleft.An alternative coding might trap the expected value error. This has the minordisadvantage that it disturbs any diagnostic message (ŒDM) and it appears to runa little slower:do„{6::¾ ª ¸¸ ¾}© Apply no-result function.Depressingly, [do] may be coded more simply and efficiently as a traditional operator:’ RARG „ (FUNC DO) RARG[1] FUNC RARG’but perhaps this is to be expected as tradfns are generally better for "do-y"programming, while D-<strong>functions</strong> excel at the "is-y" style (see the muse sectionabove).Examples:'F1'°ŒWS do 'Caption' 'Pugwash'Caption PugwashÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎelserslt „ cond (¸¸ ##.else ¾¾) argt © Condition f else g ...Conditional application of left or right operand. Returns: if cond is true,¸¸ argt, otherwise ¾¾ argt.NB: This operator is largely superseded by the more general …cond„. However, itis retained partly as an example of a simple operator and partly for reasons ofnostalgia, being the oldest piece of code in the dfns workspace:214'd t'attrib'else'1998-03-05 16:41:54© oldest op in WS.


[else] is more versatile than it might at first appear. In the following (¸) isa boolean singleton; (¾), (L) and (R) are arrays and (¸¸) and (¾¾) are monadic<strong>functions</strong>.case calling syntax if then else---- -------------- -- ---- ----[1] ¸ ¸¸ else ¾¾ ¾ ¸ ¸¸ ¾ ¾¾ ¾[2] ¸ ¸¸ else € ¾ ¸ ¸¸ ¾ ¾[3] ¸ ¸¸ else{R} ¾ ¸ ¸¸ ¾ R[4] ¸ € else ¾¾ ¾ ¸ ¾ ¾¾ ¾[5] ¸ € else{R} ¾ ¸ ¾ R[6] ¸ {L}else ¾¾ ¾ ¸ L ¾¾ ¾[7] ¸ {L}else € ¾ ¸ L ¾[8] ¸ {L}else{R} ¾ ¸ L RNotice that (L) and (R) may be arbitrarily complex _expressions_, which returnan array value but which are evaluated _only_ if (¸) selects that case.Phil Last suggests an _ambivalent_ variant of the operator:else„{ © {condition} f else g ...¸„€1­¸ 1:¸¸{ © valence test¸¸ ¾:¾ © monad: ¸¸ is test - nop if true¾¾ ¾ © else run ¾¾}¾¾ ¾¸:¸¸ ¾ © dyad: ¸ is test - run ¸¸ if true¾¾ ¾ © else run ¾¾}Notice Phil's technique used in the first two lines of the code. More often thannot, all that is needed for a missing left argument is to supply a defaultvalue. In this case however, the code needs to know _explicitly_ whether a leftargument is present. The first line ¸„€, makes ¸ the identity function if noleft argument has been passed. The guard on the second line 1­¸ 1, will "fire"only in this case, as _any_ array passed as left argument would strand with therightmost 1 to form a 2-vector, which cannot possibly match 1.The ambivalent version adds the following cases in which (T) is a booleansingleton and (tt) is a monadic function returning a boolean singleton:case calling syntax if then else---- -------------- -- ---- ----[9] tt else ¾¾ ¾ tt ¾ ¾ ¾¾ ¾[10] tt else{R} ¾ tt ¾ ¾ R[11] {T}else ¾¾ ¾ T ¾ ¾¾ ¾[12] {T}else{R} ¾ T ¾ RNotice in the examples below, that ¸„€ is used to _pass on_ a possibly nonexistentleft argument to a called function. In the following, if [main] iscalled without a left argument, then so is [sub].main„{¸„€¸ sub ¾}Examples:caseÎÎÎÎopen„{¸„0© File tie, optionally exclusive.¸ (¾°Œfstie) else (¾°Œftie) 0 © ¸=1: shared else exclusive. [1]}215


close„{¸„0 © File untie, optional resize.Œfuntie ¸ Œfresize else € ¾ © ¸=1: squeeze file else don't. [2]}openc„{¸„€© open as above - unless tie number(0¹¹¾) € else (¸°open) ¾ © tie„share openc file [4]}closec„{¸„€© close as above - if opened by openc(¸¸­¾) € else (¸°close) ¾ © squeeze(file closec)tie [4]}openc„{¸„€© open as above - unless tie number(0°¹°¹) else (¸°open) ¾ © tie„share openc file [9]}closec„{¸„€© close as above - if opened by openc(¸¸°­) else (¸°close) ¾ © squeeze(file closec)tie [9]}See also: cond.208 pow.218 and.233 or.233ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎforrslt „ i j k··· F ##.for G for H··· arg © Multiple selection of function list.This operator can be viewed as a function list version of (pow) or it could beseen as a multiple choice version of (case).Iffourfns„F for G for H for Kthen2 1 0 2 fourfns argisF F G K K argThe integer list left argument is anchored such that its right item controls thenumber of times the rightmost function is run and counts leftwards for the rest.The function operands are monadic and must be capable of acting on the result ofwhichever of the previous (to the right) <strong>functions</strong> happen to have run. Right toleft operation is the order of the day.Examples:embrace„{'(',¾,')'} for {'[',¾,']'} for {'{',¾,'}'} for {''}1 0 2 3 embrace 'this'({{}})See also: case.224 pow.218 co_ops.532ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎinvrrslt „ {guess„1+Œct} (fn ##.invr) argt © Inverse of real-valued function.Suggested by Mike Day, operator [invr] uses the Newton-Raphson method to find a[rslt], such that:argt ­ fn rsltwhere operand [fn] is a monadic continuous real-valued function and [argt] is anumeric array.216


The left argument (default 1+Œct), is a starting point for the iteration. Some<strong>functions</strong>, such as sin„1°±, are "many-to-one", which means that the inversecould be any of a number of values. In this case the left argument should bechosen to be close to the desired one. See the "ArcSin" example below.The choice of Œct as a default starting point is arbitrary. 0, 1 or ¾ would bejust as good. 1+Œct has the small advantage that it tends to avoid the discontinuityat 0, of primitive <strong>functions</strong> µ and ÷.Bugs:With an unfortunate choice of starting value, [invr] may generate a "no inverse"error or may even fail to terminate.Examples:1 2 34 5 61 2 347±invr ± 2 3½¼6{¾+¾}invr 2 4 6{2*¾}invr 16{¾*2}invr 49c2f„{32+¾×1.8}f2c„c2f invr© inverse of primitive function pi-times.© inverse of doubling function.© inverse of 2-exp is 2-log© inverse of square is sqrt.© define Celsius to Fahrenheit© derive Fahrenheit to Celsiusc2f (0 100) (¯40 ¯273)32 212 ¯40 ¯459.4f2c (32 212) (¯40 ¯459.4)0 100 ¯40 ¯273sin„1°±© convert nested array of temperatures.© convert using inverse function.© Sin(¾)sin 10¯0.5440268.54arcs„sin invrarcs sin 10© ArcSin(¾)© ArcSin(Sin(10)).109 arcs sin 10 © ArcSin(Sin(10)) near 9.See also: limit.215 pow.218ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎlimitrslt „ (fun ##.limit) arg© Function power limit (fixpoint).This operator applies its function operand repeatedly until the result has thesame value as the argument (a "fixpoint" of the function). Note that the operandfunction must be monadic and that a dyadic function may be rendered monadic bybeing bound to ("curried" with) either of its arguments:NB: <strong>Dyalog</strong> V11 implements [limit] directly using primitive operator ÿ.217


Technical notes:A straightforward coding of the operator might look like this:limit„{© Function power limit (fixpoint).rslt„¸¸ ¾ © Apply operand untilrslt­¾:rslt © ... it has no effect.’ rslt © Otherwise, repeat.}This variable-free version, due to Phil Last, which uses the left argument of aninner operator to carry the previous result, turns out to be quicker:limit„{© Function power limit (fixpoint).¾ ¸¸{© 'old' value:¸­¾:¾ © old matches new: finished.¾ ’ ¸¸ ¾ © otherwise: try new value.}¸¸ ¾© 'new' value.}For amusement, the operator can be made nearly _palindromic_ by substituting (’)with (¸¸ ’’):limit„{¾ ¸¸{¸­¾:¾¾ ¸¸ ’’ ¸¸ ¾}¸¸ ¾}... and fully palindromic by appending a dummy guard, which is never evaluated,after the recursive call. This is not without precedent; a significant proportionof our DNA _may_ turn out to be dummy code that is never evaluated!limit„{¾ ¸¸{¸­¾:¾¾ ¸¸ ’’ ¸¸ ¾¾:¾­¸}¸¸ ¾}© dummy line mirrors guard.Stringing this out on a single line shows the symmetry. The following expressioncalculates the "Golden Ratio" (a.k.a. "Phi") by finding a fixpoint of the function{1+÷¾} close to {¾÷+1}1. The 1 at the extreme left of the expression is includedsolely to mirror the 1 on the right and is ignored.1{1+÷¾}{¾ ¸¸{¸­¾:¾ ª ¾ ¸¸ ’’ ¸¸ ¾ ª ¾:¾­¸}¸¸ ¾}{¾÷+1}11.618033989For amusement, there is an animation of this expression on YouTube:See: http://www.youtube.com/watch?v=X3bv4Iu1aEg&fmt=18Examples:enlist„{1‡†,/'·',,,¨¾}limit © Expensive alternative to primitive: ¹.0¯1 10.5°× limit 2 © Fixpoint of halving function.© Note that a function can have more than one fixpoint:*°(÷3) limit¨¯2 2 © Two fixpoints of cube root function.© Operator: [nr] returns the next term in a Newton-Raphson approximation:218


nr„{¸„ŒCT © Newton-Raphson.y ‘y„¸¸¨(›¾)×1+0 ¸ © f(x), f(x+‘)¾+(¸×y)÷y-‘y© next estimate.}1°± nr limit 3 6 9 © Roots of Sin(x) near x=3, x=6, x=9.3.1416 6.2832 9.4248© Just for fun, the above code for the next item in the Newton-Raphson sequence© could be expressed as a single derived function:©© ÚÎÌ „ operand function 1°±© ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÝ ÃÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌ+°(÷°†°(-/)þ°(×°Œct)°œþþ)°(1°±¨)°((1+0 Œct)°×)°›þ limit 3 6 93.1416 6.2832 9.4248© See also …derive„© Gianluigi Quario suggests the following example for finding the Arithmetic-© Geometric Mean (AGM).©© The arithmetic-geometric mean of two numbers M and N is defined by starting© with a(0)„M and g(0)„N, then iterating:©© a(n+1) „ arithmetic mean of a(n) and g(n)© g(n+1) „ geometric mean of a(n) and g(n)© until© a(n)=g(n)AM„{(+/¾)×÷½,¾}© Arithmetic mean.GM„{(×/¾)*÷½,¾}© Geometric mean.AGM„{«½{(AM ¾),GM ¾}limit ¾} © Arithmetic-geometric mean.AM 1 2 3 4 53GM 1 2 3 4 52.6052AGM 1 2 3 4 52.7991÷AGM 1 2*÷2 © Gauss's constant.0.83463© Gianluigi's second example calculates ArcTan by similar means. (Acton, F.S.© "The Arctangent." In Numerical Methods that Work, upd. and rev. Washington,DC:© Math. Assoc. Amer., pp. 6-10, 1990.)ArcTan„{© Inverse trigonometric tangent - gqr 19-11-2002.© For scalar ¾: (ArcTan ¾)­¯3±¾©© Limit's operand function returns a 2-vector. Repeated application© of the function produces two sequences, both of which converge and© have the same limit:©© A­ {a(0),a(1), ... , a(n), ... }© G­ {g(0),g(1), ... , g(n), ... }©© Starting with arguments:© a(0)„(1+¾*2)*-÷2 and g(0)„1© the iteration produces:© a(n+1)„ arithmetic mean of a(n) and g(n)© g(n+1)„ geometric mean of a(n+1) and g(n)© until:© a(n+1)=a(n) and g(n+1)=g(n) and a(n+1)=g(n+1)219


}next„{ © next term in sequence.AM„{(+/¾)×÷½¾}© arithmetic mean.GM„{(×/¾)*÷½¾}© geometric mean.(AM ¾),GM(AM ¾),1‡¾}start„«½(1+¾*2)*-÷2finish„«½next limit start,1 © calculated limit«½¾×start÷finishArcTan 0.5 © method using limit ...0.46365¯3±0.50.46365© ... agrees with primitive function.© From Mayer Goldberg, the "Univac division algorithm" for ¸÷¾, where 0


pow„{ © Explicit function power.¸=0:¾© zero count: finished.(¸-1)’ ¸¸ ¾© tail call with reduced count.}Another, possibly due to Alan Graham, uses – and • to produce the expression: ¸¸¸¸ ¸¸ ... ¸¸ ¾. Note that an unquoted (but unreferenced) ¸¸ must be included tomake it an operator:pow„{–(•¸½›'¸¸'),'¾' ª ¸¸}The following coding was provided by Phil Last.pow„{†€°¸¸/(¼¸),›¾}© Explicit function power.Here's how it works: The composition: €°¸¸ is a _function_, which applies ¸¸ toits right argument and ignores its left one. For example:12 €°÷ 2 4 © reciprocal of 2 4 (the 12 is ignored).0.5 0.252 42 42 41 €°÷ 2 €°÷ 2 4 © reciprocal of reciprocal of 2 4 (1 2 ignored).† €°÷ / 1 2 (2 4) © recoding of the above using reduction /.† €°÷ / (¼2),›2 4 © same as above.Notice in the above, that only the _number_ of items in (¼2) is significant asitem values are ignored. The expression is therefore ŒIO independent. Choosingan index origin of 1, we can transform the body of the operator in the followingsteps:†€°¸¸/(¼¸),›¾© body of the operator.… †€°¸¸/1 2 ... ¸ ¾ © (¼¸) … 1 2 ... ¸… 1 €°¸¸ 2 €°¸¸ ... €°¸¸ ¸ €°¸¸ ¾ © expanding the reduction /.… €°¸¸ €°¸¸ ... €°¸¸ €°¸¸ ¾ © left arguments ignored.… ¸¸ ¸¸ ... ¸¸ ¸¸ ¾ © cumulative applications of ¸¸.The following related function uses monadic commute:acc„{†€°(,°›°¸¸°œ°²þ)/(¼¸),››¾}© ¸-accumulator.3 (1°+) acc 10 © 10 and 3 successors.10 11 12 13Examples:6 {''} pow 'wow'display 4 ›pow 'wow'ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌ ÛÛ Û ÚÎÎÎÎÎÎÎÎÎÎÎÌ Û ÛÛ Û Û ÚÎÎÎÎÎÎÎÌ Û Û ÛÛ Û Û Û Ú…ÎÎÌ Û Û Û ÛÛ Û Û Û ÛwowÛ Û Û Û ÛÛ Û Û Û ÀÎÎÎÙ Û Û Û ÛÛ Û Û À¹ÎÎÎÎÎÎÙ Û Û ÛÛ Û À¹ÎÎÎÎÎÎÎÎÎÎÙ Û ÛÛ À¹ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙ ÛÀ¹ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙ221


display 6 †°,°› pow 'hello' © 6-fold increase in rank.ÚÚÚÚÚÚ…ÎÎÎÎ̇‡‡‡‡‡helloÛÀÀÀÀÀÀÎÎÎÎÎÙ{«½ ¾ {1‡¾,+/¾} pow 0 1}¨ 0 to 100 1 1 2 3 5 8 13 21 34 55{«½² ¾ {1++\+\¾} pow 0 0}¨ 0 to 100 1 4 9 16 25 36 49 64 81 100© Fibonacci numbers.© squares.See also: for.214 to.316 limit.215 inverse traj.220 while.221 until.222ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎtrajvec „ (fun ##.traj) arg© Function limit 'trajectory'.Similar to …limit„, the operator applies its function operand cumulatively untilan argument that has been used before is detected. The vector of distinct argumentstogether with the final result is the trajectory of the function. As with…limit„, a dyadic function can be bound with one argument to provide the requiredmonadic operand function.Technical note:With the introduction of ÿ, the primitive power operator, this operator could becoded:traj„{¯1‡¸¸{¾,›¸¸œ²¾}ÿ{(›œ²¸)¹¾}›¾}Examples:{2|¾:1+3×¾ ª ¾÷2}traj 7© Trajectory of osc function.7 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1This operator gives the next approximation in a Newton-Raphson iteration:nr„{¸„ŒCTy ‘y„¸¸¨(›¾)×1+0 ¸¾+(¸×y)÷y-‘y}© Newton-Raphson.© f(x), f(x+‘)© next estimate.2°± nr traj 1.5 © Root of Cos(x) near 1.5.1.5 1.570990983 1.570796171 1.570796327 1.570796327 1.5707963271e¯3°(2°± nr)traj 1.5 © Same again but with an explicit increment.1.5 1.570912342 1.570796327 1.570796327© Nicolas Delcros reminds us of Gérard Langlet's algorithm for generating© a Sierpinski triangle by repeated applications of ¬\:222


' *'[Œio+†¬\traj 32½1] © Sierpinski triangle.********************************* * * * * * * * * * * * * * * *** ** ** ** ** ** ** *** * * * * * * ***** **** **** ***** * * * * * * *** ** ** *** * * ********* ********* * * * * * * *** ** ** *** * * ***** ***** * * *** *** ****************** * * * * * * *** ** ** *** * * ***** ***** * * *** *** ********** * * *** *** ****** ****See also: acc.10 limit.215 pow.218 while.221 until.222 osc.296 life.446ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎwhilerslt „ (func ##.while cond) argt© Conditional function power.Left operand [func] is applied cumulatively to argument [argt] while rightoperand [cond] returns "true". Notice that, in common with the :While ··· :Endcontrol structure, if (cond argt) is initially false, [func] is applied 0 times.Compare this with the …until„ operator.Examples:{¾,'.'} while {80>½¾} 'Note'© Extend while less than 80 wide.Note............................................................................disp ‡ while {1


ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎuntilrslt „ (func ##.until cond) argt© Conditional function power.NB: From <strong>Dyalog</strong> V11, this operator is implemented as primitive ÿ.Left operand [func] is applied cumulatively to argument [argt] until rightoperand [cond], applied to the result, returns 'true'. Notice that, in commonwith the :Repeat ··· :Until control structure, the test for termination isperformed _after_ an initial application of the left operand. This means thatthe operand is applied once even if the original argument satisfies thetermination conditions. Compare this with the …while„ operator.Examples:{¾,'.'} until {60=½¾} 'Note'© Extend until 60 wide.Note........................................................disp ‡ until {1=½½¾} 2 2 2 2½¼16 © Split until vector.Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛÚ…ÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÌÛÚ…ÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛÛÛÚ…ÎÎÂÎÎÎÌÛÚ…ÎÎÂÎÎÎÌÛÛÛÚ…ÎÎÎÂÎÎÎÎÎÌÛÚ…ÎÎÎÎÂÎÎÎÎÎÌÛÛÛÛÛ1 2Û3 4ÛÛÛ5 6Û7 8ÛÛÛÛÛ9 10Û11 12ÛÛÛ13 14Û15 16ÛÛÛÛÛÀ~Î…Á~Î…ÙÛÀ~Î…Á~Î…ÙÛÛÛÀ~ÎÎ…Á~ÎÎÎ…ÙÛÀ~ÎÎÎ…Á~ÎÎÎ…ÙÛÛÛÀÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎ…ÙÛÀÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎ…ÙÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…Ù1{¾+1} until {1} 0{1‡¾} while {' '¹¾} 'hello world'© {¾+1} applied once.© While & until _concur_ if initialworld{1‡¾} until {~' '¹¾} 'hello world'world{1‡¾} while {'Œ'¹¾} 'hello world'hello world{1‡¾} until {~'Œ'¹¾} 'hello world'ello world© ·· argument _escapes_ termination.© While & until _differ_ if initial© ·· argument _incurs_ termination.See also: cond.208 while.221 limit.215 pow.218 traj.220ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎFunction_arraysÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎFunction ArraysÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ<strong>Dyalog</strong> <strong>APL</strong> doesn't have arrays of <strong>functions</strong> but they can be simulated in variousways. Apart from …fnarray„, each of the operators here utilises a derived function"tree". The seemingly "linear" sequence ··· F op G op H ··· arg, can be representedgraphically in the following fashion:Úη·· argÚÎopÎÌÚÎopÎÌ HÚÎopÎÌ G··· FThe function array operators typically traverse the left "spine" of the tree byapplying ¸¸ to an argument until the required operand is reached.…fnarray„ uses an array of namespace references to contain each function.224


------------------Function selectors------------------Operators …case„ and …of„ apply the selected monadic function to the right argumentof the derived function. …case„ uses a boolean "mask" and …of„, a "pick"index. There is a subtle but significant difference in the usage of …case„ and…of„:660 1 0 - case ! case + 3 © [larg] fn case fn case fn rarg2 of - of ! of + 3 © [land] of fn of fn of fn rarg[larg] is the left _argument_ of the derived function: (fn case fn case fn),whereas [land] is the left _operand_ of the leftmost …of„ operator.In <strong>Dyalog</strong>, we can _name_ a derived function such as (fn case fn case fn) andwith this example, sometime later use the name in conjunction with a left argumentto "pick" a function to apply to a right argument. However, we can't namean incomplete operator expression (of fn of fn of fn) which has a missing leftoperand.Operationally, …case„ can "see" its left argument from the top (righmost) nodeof the derived function tree and pass an optionally modified copy of it leftwardsto each lower level. An …of„-tree on the other hand, has no left argumentand must traverse left until it happens upon an operand that isn't a function.Phil Last suggests a further operator [sel], which indexes _leftwards_ from therightmost operand function:sel„{¸ˆŒIO:¾¾ ¾(¸-1)¸¸ ¾}© select function from RHS of list.© apply ¾¾ at selected level.© traverse left.This combines …of„'s simplicity in that a pick index is used, with the advantageof …case„, that the derived function may be named. But here's the rub: the leftmostoperand function must accept but ignore, a left argument. This is becausethe operator doesn't know it _is_ the leftmost function and so passes the nextlowest index as left argument. This is not really a problem as an ambivalentfunction may easily be made strictly monadic by composing or enclosing it with amonadic identity function: €°fn or {fn ¾}.fnlist„{—¾} sel ˜ sel - sel ÷© 'vector' of <strong>functions</strong>,30.43Œnc'fnlist'© ... is a derived function.1 fnlist 2.5 © 1st from right function.4 fnlist 2.5 © 4th from right function.---------------------Function distributors---------------------Operators …lof„ (list-of-<strong>functions</strong>) and …vof„ (vector-of-<strong>functions</strong>) distributetheir <strong>functions</strong> over or between their array arguments. The distinction between…lof„ and …vof„ is that in the former, each function is applied to the wholeargument array, whereas in the latter, the items of the argument are distributedto each function.monadic:F lof G x y „… (F x y) (G x y)F vof G x y „… (F x ) (G y)225


dyadic:a b F lof G x y „… (a b F x y) (a b G x y)a b F vof G x y „… (a F x ) ( b G y)Examples:1 5 3 + lof — lof ˜ lof | 6 2 47 7 7 6 5 4 1 2 3 0 2 16 2 11 5 3 + vof — vof ˜ vof | 6 2 4- lof ÷ lof ! 4 5 6¯4 ¯5 ¯6 0.25 0.2 0.1666666667 24 120 720- vof ÷ vof ! 4 5 6¯4 0.2 720See also: case.224 of.225 lof.226 vof.229 for.214 fnarray.232ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎcaserslt „ i j k ··· F ##.case G case H ··· arg © Select statement.i j k ··· is a simple boolean vector whose length is the number of monadic<strong>functions</strong> (F G H ···) in the derived function. [case] applies the <strong>functions</strong>elected by the boolean left argument to the derived function's right argument.The statement is equivalent to::Select 1:Case i ª rslt„F arg:Case j ª rslt„G arg:Case k ª rslt„H arg:Case l ª rslt„I arg...:Else ª rslt„arg:EndThe simple alternating pattern of ... fn op fn op fn ... in the statement hidesthe fact that the <strong>functions</strong> are at different "depths" in the derived function.For illustration the derived fn (f05) below has two operands to the "topmost"compose operator; the right being (÷) and the left, all the rest (—°˜°-°×)f05„—°˜°-°×°÷ ª display Œcr'f05'Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌ ÛÛ Û Ú…ÎÎÎÎÎÎÎÎÎÎÌ Û ° ÷ ÛÛ Û Û Ú…ÎÎÌ Û ° × Û - - ÛÛ Û Û Û—°˜Û ° - Û - - Û ÛÛ Û Û ÀÎÎÎÙ - - Û Û ÛÛ Û À¹ÎÎÎÎÎÎÎÎÎÎÙ Û ÛÛ À¹ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙ ÛÀ¹ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙSimilarly in fns derived with (case), only (¾¾) is necessarily available forimmediate use so we run (¾¾) if the last of (¸) is set. If not, and if (¸) haslength 2 and the first is one we can run (¸¸) which must be at the "top" level.cf. (—°˜) in (f05) above. If there are more than two items in (¸), (¸¸) must bederived with another (case) call so we run it dyadically losing the last (¸).A no-guard one-liner using conditional monad-reduction (see …pow„) is possible.226


case„{œ¸¸{b ¸¸ ¾}/(i~Ÿ/b„¯1‡b),¸¸{¸¸ ¾}/(¼i„1 0­b),¾¾{¸¸ ¾}/(¼¯1†b„


Examples:10¯1010.1101 of + of - of × of ÷ 10 © +102 of + of - of × of ÷ 10 © -103 of + of - of × of ÷ 10 © ×104 of + of - of × of ÷ 10 © ÷105 of + of - of × of ÷ 10 © 10 (out of range index returns arg).See also: case.224 Function_arrays.222 pow.218 case.224 co_ops.532ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎlofrslt „ {larg} {''} ##.lof F lof G lof H ... rarg © List of <strong>functions</strong>.From Phil Last:[lof] simulates the distribution of the argument(s) to a "list of <strong>functions</strong>".F lof G lof H ··· rarg „… (F rarg)(G rarg)(H rarg) ···larg F lof G lof H ··· rarg „… (larg F rarg)(larg G rarg)(larg H rarg) ···Technical notes:lof„{© List of <strong>functions</strong>.¸„€© ambivalent.(¸ ¸¸ ¾),›¸ ¾¾ ¾ © one at a time.}One obstacle is that the result from the leftmost function application must be_enclosed_ prior to concatenation with the vector of results to its right. However,it is not easy for the operator to determine when its left operand is theleftmost. One way to overcome it takes several lines of additional code to beinterpreted at each iteration (level) and involves the analysis of the ŒCR ofthe derived function of itself by itself (not very nice really) so here we do itby an additional, apparently redundant call to the operator with a constant nullfunction {''}. Using the example above we write:{''} lof F lof G lof H lof J arrayAs we go down the tree, each function in turn (J H G & F) is run as ¾¾ andenclosed while ¸¸ gets progressively shallower until it is just {''} whoseresult is ineffectively catenated to the left of the combined result.The null call is only strictly necessary when the result of what would otherwisebe the leftmost function is other than a simple scalar, a real possibility! Thisis because the result of ¸¸ cannot be enclosed as it is the entire left spine ofthe tree.An alternative would be to provide a slightly different "special" coding for theleftmost operator:_lof„{© Close list of <strong>functions</strong>.¸„€© ambivalent.(¸ ¸¸ ¾)(¸ ¾¾ ¾) © one at a time.}228


Examples:2.5œ÷/ +/lof½ 1 2 3 4cvex„'will' 'you' 'nill'© arithmetic mean.© vector of vectors.disp {2†¾} lof {2†²¾} lof {²2†¾} cvexÚ…ÎÎÎÂÎÎÎÂÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÌÛ Û ÛÚ…ÎÎÎÂÎÎÎÌÛÚ…ÎÎÂÎÎÎÎÌÛÛwillÛyouÛÛnillÛyouÛÛÛyouÛwillÛÛÛ Û ÛÀÎÎÎ…ÁÎÎ…ÙÛÀÎÎ…ÁÎÎÎ…ÙÛÀÎÎÎ…ÁÎÎ…ÁÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎ…Ùdisp {''} lof {2†¾} lof {2†²¾} lof {²2†¾} cvexÚ…ÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÌÛÚ…ÎÎÎÂÎÎÎÌÛÚ…ÎÎÎÂÎÎÎÌÛÚ…ÎÎÂÎÎÎÎÌÛÛÛwillÛyouÛÛÛnillÛyouÛÛÛyouÛwillÛÛÛÀÎÎÎ…ÁÎÎ…ÙÛÀÎÎÎ…ÁÎÎ…ÙÛÀÎÎ…ÁÎÎÎ…ÙÛÀÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎ…Ùdisp {2†¾} _lof {2†²¾} lof {²2†¾} cvexÚ…ÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÌÛÚ…ÎÎÎÂÎÎÎÌÛÚ…ÎÎÎÂÎÎÎÌÛÚ…ÎÎÂÎÎÎÎÌÛÛÛwillÛyouÛÛÛnillÛyouÛÛÛyouÛwillÛÛÛÀÎÎÎ…ÁÎÎ…ÙÛÀÎÎÎ…ÁÎÎ…ÙÛÀÎÎ…ÁÎÎÎ…ÙÛÀÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎ…Ù© without left closure.© explicit closure.© closure using [_lof].See also: vof.229 Function_arrays.222 truth_tables.593 co_ops.532ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎlogicrslt „ larg (selector ##.logic) rarg © logical function array.Supplied by Phil Last, who says:Logical dyadic <strong>functions</strong> each take two boolean args and return one. The domainof scalar argument pairs is therefore (0 0)(0 1)(1 0)(1 1) and the codomain ofscalar results is 0 1. The results from one particular function for the 4 membersof the domain can be used to characterise the function. e.g.:=/¨(0 0)(0 1)(1 0)(1 1)1 0 0 1We can conveniently 2°ƒ this result to give us a single integer that completelyidentifies the function (in the above case, 9). There must therefore be (2*4)i.e. 16 possible logical dyadic <strong>functions</strong>. The mapping is shown in the table ...ÚÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÌÛ 0 Û 1 Û 2 Û 3 Û 4 Û 5 Û 6 Û 7 Û 8 Û 9 Û10 Û11 Û12 Û13 Û14 Û15 ÛÃÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝÛ 0 Û ^ Û > Û ¸ Û < Û ¾ Û ¬ Û Ÿ Û ‹ Û = Û~¾ Û ‰ Û~¸ Û ˆ Û Š Û 1 ÛÀÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÙFunctions 0, 3, 5, 10, 12 and 15 are the 6 that most <strong>APL</strong>s don't implement leavingthe 10 logical <strong>functions</strong> in the standard. Nowhere are any of them implementedas true scalar <strong>functions</strong> notwithstanding „ and … in Sharp <strong>APL</strong>, and • and €in D:(Perhaps a little tongue-in-cheek, Phil suggests that "notwithstanding" and"nevertheless" might be apt names for <strong>functions</strong> • and € respectively:"this notwithstanding that" implies "this","this nevertheless that" implies "that".229


Interestingly, both the Oxford and Collins dictionaries imply that the wordsare synonymous, whereas it is clear from the above that.notwithstanding „… nevertheless þnevertheless „… notwithstanding þ)As Phil says, this feels a little like saying that "because" and "therefore"mean the same thing.Here they are as D:fnsf0„{0^¸=¾}f3„{¸=¾=¾}f5„{¾=¸=¸}fa„{¾¬¸=¸}fc„{¸¬¾=¾}ff„{1Ÿ¸=¾}D:op (logic) supplies any or all of them according to its operand.¸ and ¾ are conformable logical arrays, any rank, any depth. ¸¸ is a functionthat returns a simple integer array conformable with ¸ and ¾.Thus:{1}logic is ^ and {7}logic is Ÿ,{6 11 13}logic is a 3 item function array of ¬ ‰ ˆ,{4 4½16?16}logic is a 4x4 array of all the logical <strong>functions</strong> in some order.Technical notes:logic„{œ(0 1 2 3=+/¸ ¸ ¾)Ÿ.^{›[1+¼½½¾]2 2 2 2‚¾}¸ ¸¸ ¾}© logical function arrayThe œ acts on a scalar, so is ŒML-proof.The 1+¼... is an axis spec, so is ŒIO-proof.The }¸ ¸¸ ¾ is in case the shapes of ¸ and ¾ are required to select or reshapethe integer array inside ¸¸. e.g.{(½¸=¾){¸½(0ƒ¸)½¾}integers}logic© a function for each column230


Examples:0 0 1 1 {0}logic 0 1 0 1 © 0 00 0 0 00 0 1 1 {1}logic 0 1 0 1 © 1 ^0 0 0 10 0 1 1 {2}logic 0 1 0 1 © 2 >0 0 1 00 0 1 1 {3}logic 0 1 0 1 © 3 ¸0 0 1 10 0 1 1 {4}logic 0 1 0 1 © 4


ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ A ÛÛÛÃÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÁÎÎÌÛ Û ÛÛ Û C ÛÛ B Û ÛÛ Û ÛÛÃÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙÛÛÀÎÎÎÎÎÎÎÎÎÎÎÎÙThe answer is:((1†½A) + (1†½B) — (1†½C)) , (¯1†½A) — (¯1†½B) + (¯1†½C)but it would be much nicer to be able to say:(½A) (+—) (½B) (—+) (½C)A diagram shows the distribution of <strong>functions</strong> with respect to argument items:ÚÎÎÎÎÎÂÎÎÎÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÎÎÎÌÛ Û Û Û Û(½A)[0 1] (+—) (½B)[0 1] (—+) (½C)[0 1]Û Û Û Û ÛÀÎÎÎÎÁÎÎÎÎÎÎÎÎÎÁÎÎÎÎÁÎÎÎÎÎÎÎÎÎÙwhere (+—) and (—+) are both 2-item "function vectors" to be distributed overtheir 2-item argument(s). Compare this with the way that a vector of namespacereferences in a function expression, distributes its function over its argumentswithout needing to specify each:(ref0 ref1 ref2 ref3).{···w} ¼4More generally:a b c···(f g h···) x y z··· „… (a f x)(b g y)(c h z)··· © vector vector(›a) (f g h···) x y z··· „… (a f x)(a g y)(a h z)··· © scalar vectora b c···(f g h···) ›x(›a) (f g h···) ›x„… (a f x)(b g x)(c h x)··· © vector scalar„… (a f x)(a g x)(a h x)··· © scalar scalar(f g h···) x y z··· „… (f x)(g y)(h z)··· © monadic vector(f g h···) ›x „… (f x)(g x)(h x)··· © monadic scalar[vof] implements the distributive function vector in the alternating mode wehave seen with …of„, …case„ and …lof„.{a b c ···} {''} vof f vof g vof h ··· x y zAs with …lof„ we need (except in special circumstances) the closing call withthe null function. An alternative would be to provide a slightly different"special" coding for the leftmost operator:232_vof„{© Close vector of <strong>functions</strong>.¸„›© ¸ elided: ›¾.(al ar)(wl wr)„¸ ¾© distrubute arg(s).1­¸ 1:(¸¸ wl)(¾¾ wr) © mondadic.(al ¸¸ wl)(ar ¾¾ wr) © dyadic.}


Although more expensive, the following coding works without a terminator to theleft. The control over the iteration is the length of the data so if the numberof <strong>functions</strong> is different it goes wrong as do the others.Uses the same method of self reference as the coding of fk in …fork„:vof„{(M D)„112358314594370 774156178538190}¸„M(m d)„M D¹›¸e„2¹½¾e


ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎfnarrayrefs „ (fn ##.fnarray) fns© Array of <strong>functions</strong>.Maria Wells suggests this operator to produce an array of <strong>functions</strong>. The operatoraccumulates a vector of namespace refs, each containing a single function f.The <strong>functions</strong> contained in each space can be applied to or between scalars orsimilarly shaped arrays by using the "reference array" syntax: refs.f.Note that the resulting function vector may be reshaped to form a function arrayof any rank and depth; see examples below.Examples:flist „ + fnarray - fnarray × fnarray '' © 3-vector of fns: + - ×.flist.f 1 2 31 ¯2 1© monadic application.1 2 3 flist.f 4 5 6 © dyadic application.5 ¯3 18fns„ —fnarray ˜fnarray « © 2-vector of fns — ˜.4 33 48 10fns.f 3.5© scalar ceiling and floor.fns.f 2.3 4.5© vector ceiling and floor.5 10 fns.f 8 12 © dyadic max and min.fmat„2 2½+fnarray -fnarray ×fnarray ÷fnarray« © 2×2 matrix of + - × ÷+ -× ÷fmat.Œcr'f'© show function matrix.12 820 510 fmat.f 2 © fn mat between scalars.disp fmat.f ¼2 2Ú…ÎÎÂÎÎÎÎÎÎÎ̇1 1Û ¯1 ¯2 ÛÃ~Î…Ï~ÎÎÎÎÎ…ÝÛ1 1Û0.5 0.5ÛÀ~Î…Á~ÎÎÎÎÎ…Ùfvex„‡fmatdisp fvex.Œcr'f'Ú…ÎÎÎÎÂÎÎÎÎÎÌÛÚ…ÂÎÌÛÚ…ÂÎÌÛÛÛ+Û-ÛÛÛ×Û÷ÛÛÛÀ…Á…ÙÛÀ…Á…ÙÛÀÎÎÎÎ…ÁÎÎÎÎ…Ùdisp 20 fvex.f ››4 5 10Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛÚ…ÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÌÛÚ…ÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÌÛÛÛ24 25 30Û16 15 10ÛÛÛ80 100 200Û5 4 2ÛÛÛÀ~ÎÎÎÎÎÎ…Á~ÎÎÎÎÎÎ…ÙÛÀ~ÎÎÎÎÎÎÎÎ…Á~ÎÎÎ…ÙÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…Ù© apply fmat to matrix arg.© nested array of <strong>functions</strong>.© display function array.© 3-way conformability.234fnest„,°›\,fmat© nastily nested array.


disp fnest.Œcr'f' © .. .. <strong>functions</strong>.Ú…ÂÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ Û Û ÛÚ…ÂÎÎÎÎÎÎÎÎÎÌÛÛ Û ÛÚ…ÂÎÎÎÎÎÌÛÛ ÛÚ…ÂÎÎÎÎÎÌÛÛÛ ÛÚ…ÂÎÌÛÛ ÛÚ…ÂÎÌÛÛÛ ÛÛ ÛÚ…ÂÎÌÛÛÛÛ+ÛÛ+Û-ÛÛÛ+ÛÛ-Û×ÛÛÛÛ+ÛÛ-ÛÛ×Û÷ÛÛÛÛÛ ÛÀ…Á…ÙÛÛ ÛÀ…Á…ÙÛÛÛ ÛÛ ÛÀ…Á…ÙÛÛÛÛ Û ÛÀ…ÁÎÎÎÎ…ÙÛÛ ÛÀ…ÁÎÎÎÎ…ÙÛÛÛ Û Û ÛÀ…ÁÎÎÎÎÎÎÎÎ…ÙÛÀ…ÁÎÎÎÎ…ÁÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎ…Ùdisp 12 fnest.f 3Ú…ÎÂÎÎÎÎÂÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ Û Û ÛÚ…ÎÂÎÎÎÎÎÎÎÎÌÛÛ Û ÛÚ…ÎÂÎÎÎÎÌÛÛ ÛÚ…ÂÎÎÎÎÌÛÛÛ15Û15 9ÛÛ15Û9 36ÛÛÛ15ÛÛ9Û36 4ÛÛÛÛ Û ÛÀ~ÎÁ~ÎÎ…ÙÛÛ ÛÀÎÁ~ÎÎ…ÙÛÛÛ Û Û ÛÀ~ÎÁÎÎÎÎÎÎÎ…ÙÛÀ~ÎÁ~ÎÎ…ÁÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎ…Ù© deep function application.© Function arrays need not be named:1 ¯2(+fnarray -fnarray «).f 1 2© raw monadic application.11 1810 20(+fnarray -fnarray «).f 1 2 © raw dyadic application.See also: Function_arrays.222ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎandrslt „ (f ##.and g) arg© Sequential test.rslt „ (f ##.or g) argSometimes, we must test conditions in sequence. For example, if we want to knowwhether ¾ is a scalar number, greater than zero, we need to check in order:that ¾ is a simple scalarand that ¾ is numericand that ¾ is greater than zero.In other words:0=­¾ © simple scalarand «­0/¾ © numericand 0


We have to resort to complex guards, along the lines of:gt0 „ {{}0¬­¾:0~«­0/¾:0¾>0 © > 0}¾:'YEP' ª 'NOPE'© not a simple scalar© not numericPhil Last's [and] and [or] operators encapsulate this sequential testing, allowingus to use the simpler:gt0 „ {{0=­¾} and {«­0/¾} and (0°


fk„{A B C„112358314594370 774156178538190 998752796516730}¸„A© ¸„A ª fg„f„¸¸ ª h„g„¾¾¸­A:B ¸¸ ¾(¾¾ ¾) © ¸­A:B fg ¾(h ¾)¸­B:œ¸¸{(¸¸ ¸)¾¾ ¾}¾¾/¾ © ¸­B:œ{(f ¸)g ¾}/¾¸­C:œ¸¸{(œ¸¸/¸)¾¾ ¾}¾¾/¾ © ¸­C:œ{(œf/¸)g ¾}/¾C ¸¸(¸ ¾)(¸ ¾¾ ¾) © C fg(¸ ¾)(¸ h ¾)It's slower than the _fk/fk_ pair obviously improving relatively as the overheadgets less significant ...(>fkŸfk=)cf(>_fkŸfk_=)°²þ¼1e12.292270531(>fkŸfk=)cf(>_fkŸfk_=)°²þ¼1e31.798882682(>fkŸfk=)cf(>_fkŸfk_=)°²þ¼1e60.9954407295at which point it's only twice as slow as the primitive ...(>fkŸfk=)cf‰°²þ¼1e62.006006006So it's only an exercise in coding but it's a better model if we ever decided toadd a primitive. It even extends correctly to odd trains (forks of forks) which_fk/fk_ doesn't ...The following is true for boolean arguments (‰ „… Ÿ°~ „… if) each time replacingthe leftmost function with an equivalent fork ...‰ „… >fkŸfk= „… =fk‹fk


See also: dft.125 cond.208 co_ops.532ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎlisprslt „ {eval„1} ##.lisp expr© Evaluator for a subset of Scheme.From Nick Nickolov, this function evaluates character vector [expr], which isan expression written in a subset of the Scheme language.Special forms:lambda (alias \)quotecond elseA small set of primitive <strong>functions</strong> is provided. This can be easily extended:+ sum- difference* product= equalwrite display using Œ„If optional left argument [eval] is set to 0, [lisp] returns the parse treeprior to evaluation.Technical note:Roughly, it follows the structure of the metacircular evaluator from SICP.See Gerald Jay Sussman's lecture: https://www.youtube.com/watch?v=0m6hoOelZH8Lisp structures are represented as follows:Lisp <strong>APL</strong>---- ---123 123atom 'atom'(x y) (x y)'x ('quote' x)Procedures are represented as 4-vectors of:'closure' environment parameters bodyEnvironments are two-column matrices of names and values.Examples:lisp '(+ 1 2 3)'© expression evaluation6lisp '((lambda(m n)(+ m n))3 4)' © lambda application7disp 0 lisp '((\(m n)(+ m n))3 4)' © parse tree (AST)Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÂÎÌÛÚ…ÂÎÎÎÎÎÂÎÎÎÎÎÎÎÌÛ Û ÛÛÛ ÛÚ…ÂÎÌÛÚ…ÂÎÂÎÌÛÛ Û ÛÛÛ\ÛÛmÛnÛÛÛ+ÛmÛnÛÛÛ3Û4ÛÛÛ ÛÀ…Á…ÙÛÀ…Á…Á…ÙÛÛ Û ÛÛÀ…ÁÎÎÎÎ…ÁÎÎÎÎÎÎ…ÙÛ Û ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÁÎÙlisp loop '…'© mini session using …loop„ operator.238


2412(* 2 3 4)((\(m n)(* m n))3 4)(quote (+ 1 2))© using "\" shorthand for "lambda"© quoted list+ 1 2'(* 4 5) © using "'" shorthand© Nick's example:s „ ' ((lambda (cons car cdr)'s,„ ' (car (cons 123 456))) 's,„ ''s,„ ' (lambda (x y) (lambda (i) (cond (i x) (else y)))) 's,„ ' (lambda (xy) (xy 0))'s,„ ' (lambda (xy) (xy 1)))'456lisp s© Applicative-order Y combinator:Y„'(\(f)((\(x)(x x))(\(x)(f(\(y)((x x)y))))))'fac„'(\(f)(\(n)(cond((= n 0)1)(else(* n(f(- n 1)))))))'© factorial24lisp '((',Y,fac,')4)' © !4© Fibonacci:fib „ '(\(f)(\(n)(cond((= n 0)0)((= n 1)1)(else(+(f(- n 1))(f(- n 2)))))))rec„Y{'((',¸¸,¸,')',¾,')'}© Y applicatorlisp¨ fib°rec¨ ŒD © fib¨ 0..90 1 1 2 3 5 8 13 21 34pchk„{0 ¯1‡1 0²' ',•†¾(+\1 ¯1 0['()'¼¾])}pchk Y© handy parenthesis depth checker( \ ( f ) ( ( \ ( x ) ( x x ) ) ( \ ( x ) ( f ( \ ( y ) ( ( x x ) y ) ) ) )1 1 2 2 1 2 3 3 4 4 3 4 4 4 4 3 2 3 3 4 4 3 4 4 5 5 6 6 5 6 7 7 7 7 6 6 5 4 3 2See also: loop.550 parse.237 bf.439 baby.427See https://github.com/ngn/only-tools-and-sources/tree/master/lib/lispÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎparsetree „ {trace„0} defn ##.parse expr © Bunda-Gerth parse of expression ¾.matr „ {format„1} defn ##.parse '' © Bunda-Gerth binding matrix.J.D.Bunda and J.A.Gerth describe an elegant parser for an infix notation, suchas <strong>APL</strong>:"<strong>APL</strong> Two by Two - Syntax Analysis by Pairwise Reduction"J.D.Bunda, J.A.Gerth,ACM Sigapl Apl Quote Quad, vol. 14, no. 4, pp. 85-94, 1984.Bunda-Gerth assigns binding-strength numbers between pairs of token categories.For example, an operator binds tighter to its operand, than does a function toits argument. Array-array binding (stranding) may bind tighter still, dependingon the dialect of <strong>APL</strong>.These relative bindings can be expressed in a table whose entries show thestrength and resulting category of each bond. Notice that some categories (forexample operator with operator) do not bind:239


ÚÎÎÎÂÎÎÎÎÂÎÎÂÎÎÎÂÎÌÛA ÛF ÛAFÛM ÛDÛ Categories:ÚÎÎÏÎÎÎÏÎÎÎÎÏÎÎÏÎÎÎÏÎÝ A: ArrayÛA Û4 AÛ2 AFÛ Û3 FÛ Û F: Ambi-valent functionÃÎÎÏÎÎÎÏÎÎÎÎÏÎÎÏÎÎÎÏÎÝ M: Monadic operatorÛF Û1 AÛ Û Û3 FÛ Û D: Dyadic operatorÃÎÎÏÎÎÎÏÎÎÎÎÏÎÎÏÎÎÎÏÎÝÛAFÛ1 AÛ Û Û Û Û For example, in the table to the left:ÃÎÎÏÎÎÎÏÎÎÎÎÏÎÎÏÎÎÎÏÎÝ 4 A: Array-Array binds with strength 4, to pro-ÛM Û Û Û Û Û Û duce an Array (strand).ÃÎÎÏÎÎÎÏÎÎÎÎÏÎÎÏÎÎÎÏÎÝ 3 F: Operand (array or function) binds withÛD Û3 MÛ3 M Û Û Û Û strength 3 to a monadic operator to produceÀÎÎÁÎÎÎÁÎÎÎÎÁÎÎÁÎÎÎÁÎÙa (derived) function.For the purposes of parsing, the table may need some categories that do not appearexplicitly in the language. In the above, AF represents the binding of adyadic function to its left argument array, to form a monadic function:2+3 … (2+)3 © A:F:A…AF:A "left-argument currying".Similarly, a dyadic operator binds with a right operand function or array toproduce a monadic operator:(muse:+.× … +(.×) © F:D:F…F:M right-operand currying.Whether such constructs appear explicitly is an aesthetic choice for thelanguage designer. The following would seem pretty handy:limit „ ÿ­ © D:F…M right-operand curryinginverse „ ÿ¯1 © D:F…M .. .. ..There is less pressure to provide explicit left-argument currying:next „ 1+© A:F…AF left-argument currying.as we can already do this with the primitive compose operator:)next „ 1°+© though not quite as prettily.Given a binding table and an expression to be parsed, Bunda-Gerth identifies thebinding strengths between each pair of tokens.For example, using the above table and the expression (+.×/2½›4 5½6), the columnsbelow represent the inter-token bindings. Notice that some categories donot bind (for example F:F) and so have a notional binding strength of 0:Œ ÌŒ Œ Œ Û token-to-token binding strengths.Œ Œ Œ Œ Œ ÛŒ Œ Œ Œ Œ Œ Œ ÙÚÁÂÁÂÁÂÁÂÁÂÁÂÁÂÁÂÁÂÁÌF D F M A F F A A F A © token categories+ . × / 2 ½ › 4 5 ½ 6 © subject expressionWorking right-to-left, the algorithm identifies the rightmost "peak" in theabove diagram. The tokens on either side of the peak are bound and the processrepeated until either: a single token remains, the result of a successful parse;or no adjacent tokens bind, which indicates a syntax error. For a plateau of adjacentcolumns of equal height, the leftmost column is chosen.Here is a worked example in which the rightmost (next to be bound) peak is identifiedby a column of 'Ž' characters.240


Ž „ rightmost peak (Ž)Œ ŒŽŒ Œ Œ Ž ŒŒ Œ Œ Œ Ž Œ ŒÚÁÂÁÂÁÂÁÂÁÂÁÂÁÂÁÂÁÂÁÌF D F M A F F A A F A „ categories+ . × / 2 ½ › 4 5 ½ 6 „ expression tokensÀÂÙ „ bindingA:A…A „ binding rule from table.Œ ŒŒ Œ Œ ŽŒ Œ Œ Œ Ž ŒÚÁÂÁÂÁÂÁÂÁÂÁÂÁÎÂÎÁÂÁÌF D F M A F F A F A+ . × / 2 ½ › ÚÁÌ ½ 6 „ bound tokens4 5 ÛÀÂÎÙ „ next bindingA:F…AFŒ ŒŒ Œ ŒŒ Œ Œ ŽÚÁÂÁÂÁÂÁÂÁÂÁÂÎÁÎÂÎÁÎÌF D F M A F F AF A+ . × / 2 ½ › ÚÁÎÌ 6ÚÁÌ ½ Û4 5 ÛÀÎÂÎÙAF:A…AŒ ŒŒ Œ ŒŒ Œ Œ ŽÚÁÂÁÂÁÂÁÂÁÂÁÂÎÎÁÎÎÌF D F M A F F A+ . × / 2 ½ › ÚÎÁÎÌÛ ÚÁÎÌ 6Û ÚÁÌ ½Û 4 5ÀÎÎÂÎÎÙF:A…AŒ ŒŒ Œ ŽŒ Œ Ž ŒÚÁÂÁÂÁÂÁÂÁÂÎÁÎÎÌF D F M A F A+ . × / 2 ½ ÚÎÎÁÎÎÌÀÂÙ › ÚÎÁÎÌA:F…AF ÚÁÎÌ 6ÚÁÌ ½4 5Œ ŒŒ ŒŒ Œ ŽÚÁÂÁÂÁÂÁÎÂÎÎÁÎÎÌF D F M AF A+ . × / ÚÁÌ ÚÎÎÁÎÎÌ2 ½ › ÚÎÁÎÌÛ ÚÁÎÌ 6ÛÛ 4 5ÀÎÎÂÎÎÙAF:A…AŽ ŒŽ ŒŽ ŒÚÁÂÁÂÁÂÎÎÁÎÎÌÚÁÌ ½241


F D F M A+ . × / ÚÎÎÁÎÎÌÀÂÙ ÚÁÌ ÚÎÎÁÎÎÌÛ 2 ½ › ÚÎÁÎÌD:F…M ÚÁÎÌ 6ÚÁÌ ½4 5ŽŽŽÚÁÎÂÁÎÂÎÎÁÎÎÌF M M A+ ÚÁÌ / ÚÎÎÁÎÎÌÛ . × ÚÁÌ ÚÎÎÁÎÎÌÀÂÎÙ 2 ½ › ÚÎÁÎÌF:M…F ÚÁÎÌ 6ÚÁÌ ½4 5ŽŽŽÚÎÎÁÎÂÎÎÁÎÎÌF M AÚÁÎÌ / ÚÎÎÁÎÎÌ+ ÚÁÌ Û ÚÁÌ ÚÎÎÁÎÎÌ. × Û 2 ½ › ÚÎÁÎÌÀÎÂÎÎÙ ÚÁÎÌ 6F:M…F ÚÁÌ ½4 5ŽÚÎÎÎÎÁÎÎÎÌF AÚÎÁÎÎÌ ÚÎÎÁÎÎÌÚÁÎÌ / ÚÁÌ ÚÎÎÁÎÎÌ+ ÚÁÌ 2 ½ › ÚÎÁÎÌ. - ÚÁÎÌ 6Û Û ÚÁÌ ½Û Û 4 5ÀÎÎÎÎÂÎÎÎÙF:A…AAÚÎÎÎÁÎÎÎÎÌÚÎÁÎÎÌ ÚÎÎÁÎÎÌÚÁÎÌ / ÚÁÌ ÚÎÎÁÎÎÌ+ ÚÁÌ 2 ½ › ÚÎÁÎÌ. × ÚÁÎÌ 6ÚÁÌ ½4 5[parse] implements a general Bunda-Gerth parser, which takes its language definitionas left argument and returns either a (formatted) binding matrix or aparse tree for right argument character vector [expr].Left argument [defn] defines the relative binding strengths of categories oftokens for an <strong>APL</strong>-like infix language. The definition may be a character matrix;vector (with embedded newlines); or a vector of character vectors.If right argument [expr] is null, [parse] returns the binding matrix.A two-item left argument [opt defn], where opt is 0 or 1, specifies whether:- The binding table should be formatted, in the case of a null [expr]- The parsing should be traced, in the case of a non-null [expr]242


Otherwise, if [expr] is non-null, it is assumed to be an expression of tokens,specified as representatives of each category, in the first section of the definition.Note that an unformatted binding table may be re-input as a left argument tosave the cost of compiling the definitions on subsequent calls. See the examplebelow.Binding Definition------------------The definition is split into blank-line-separated sections. The first section isspecial and defines token categories and representative tokens in each category.For example:A 1 2 3 4 © Category 'A' with representatives '1' '2' '3' and '4'.F + - × ÷ © Category 'F' .. .. .. '+' '-' '×' and '÷'.AF© Category 'AF' with no explicit representatives.In addition, the first section may contain a line that defines any bracket-pairsused in an expression, over and above primitive parentheses (). This line is identifiedby a starting pair () and followed by any number of pairs of charactersthat are to be interpreted as expression-enclosing brackets. For example:() [INDX] {DFN} © recognise square brackets and curly braces.Brackets are defined, rather than being hard-coded in the parser because:- In some infix notations, such as J, [, ], { and } do not constitute brackets.- It allows the introduction of additional bracket pairs such as: < > Ú Ì ...Each of the subsequent sections defines bonds between pairs of categories, togetherwith the category of the resulting bound pair:A:B…C © A binds with B to produce C.Within a section, the bonds all have the same binding-strength; bonds in earliersections are stronger than those in later sections. For example:A 1 2 3 4F + - × ÷AFA:F…AFAF:A…AF:A…A© 0th section: category 'A'; reps '1' '2' '3' '4'© 0th section: category 'F'; reps '+' '-' '×' '÷'© 0th section: category 'AF; no representatives.© 1st section: A binds (strength 2) to F to produce AF© 2nd section: AF binds (strength 1) to A to produce A© 2nd section: F binds (strength 1) to A to produce ADistributions-------------Rows and columns in the binding table often contain repeated items. For example,the left operand of an operator could be an array or a function, so the definitionmight contain the line:A:MOP…F F:MOP…FIn such cases, categories may be grouped with a '.' character. and the commoncategory "factored out":A:MOP…F F:MOP…F A.F:MOP…FIn general:A.B:Y…Z A:Y…Z B:Y…ZA:X.Y…Z A:Z…Z A:Y…Z243


On expansion, the outer product of the items on the left is matched against thelist of items on the right. A single result item on the right is extended toconform:A.B:C.D…Z A:C…Z A:D…ZB:C…Z B:D…ZA.B:C…X.Y A:C…X B:C…YA:B.C…X.Y A:B…X A.C…YMacros------Lines starting: word=... define a macro, whose body is substituted throughoutthe definition script. For example, using the previous example, we could code:rand=A.Frand:MOP…F© macro: operand can be function or array:© operand bound with monadic operator to derive function.which expands:rand:MOP…F=> A.F:MOP…F © (macro expansion of "rand")=> A:MOP…F F:MOP…F © (distribution of MOP)Bugs:[0] Tokens (category representatives) may be only single characters.[1] There is no way to identify a D-operator, as opposed to a D-function.[2] Bunda-Gerth unconditionally left-associates adjacent tokens of the same category.This is fine for classic <strong>APL</strong>, where only array-sequences (strands)occur but if we were to extend the language with, say, operator and function"trains" we might want operator trains to associate left and function trainsto associate right. A solution might be to add associativity indication tothe category definitions and to right-accumulate speculatively instead ofjust skipping left along the token stream. This speculative right-associatedtree would then be emitted if a weaker binding is encountered, or consumedpiecewise by a stronger binding.Requires: …segs„ …disp„ …subs„(muse:At first glance conventional "BIDMAS" (Brackets, Indexing (power), Division/Multiplication, Addition/Subtraction) arithmetic appears ideally suited to atwo-by-two treatment. But there's a problem. Monadic minus binds tightly tothe number on its right if there's a function to its left but less tightlyif there's a number to its left.2+-3×4 … 2+((-3)×4) © -:3 >> 3:×2 -3×4 … 2-(3×4) © -:3


lft„{ © move left one token in stream ¾.(‘_ L)A B C _‘ „ ¾‘_ L A B(C _‘)}rgt„{ © move right one token in stream ¾.‘_ A B C(R _‘) „ ¾(‘_ A)B C R _‘}rewind „ rgtÿ{eos­œ¸}© >>| rewind to right end of tape.Notice that the token reducer itself is quite simple; the bulk of [parse] beingconcerned with compiling and formatting the tables and trees:reduce„{© 2-by-2 parsing.(‘_ L)Aa Bb Cc(R _‘)„¾© 3-token window on stream.Aa Cc^.­eos:Bb© single node: done.Aa Bb^.­eos:¾© error: partial parse.(A a)(B b)(C c)„Aa Bb Cc © cats and toks.(›b c)¹1‡bkts:’ rgt(‘_ L)Aa(ebk b)R _‘ © empty brackets [].(›a c)¹bkts:’ rgt ‘_ L(a bkt Bb)R _‘ © bracketed single value Bb.(›a)¹rbs:’ lft lft ¾© right bracket: skip left.bonds„xmat[(A B)(B C)+1]© A:B B:C bonds.‰/bonds:’ lft ¾© A:B ‰ B:C … skip left.BbCc„zmat[B;C],›b c © B bound with C.’ show(‘_ L)Aa BbCc R _‘ © binds with token to the right?} © :: stream „ ’ streamExamples:© Simple definition with Arrays and (ambi-valent) Functions.© Parentheses () need not be defined explicitly:display af© Arrays, Functions.Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛA 1 2 3 4 © Arrays ÛÛF + - × ÷ © Functions ÛÛAF © bound left argument ÛÛÛÛA:F…AF © left argument to functionÛÛÛÛAF:A…A © dyadic function ÛÛ F:A…A © monadic function ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙaf parse''ÚÎÎÎÂÎÎÎÎÌÛA ÛF ÛÚÎÎÏÎÎÎÏÎÎÎÎÝÛA Û Û2 AFÛÃÎÎÏÎÎÎÏÎÎÎÎÝÛF Û1 AÛ ÛÃÎÎÏÎÎÎÏÎÎÎÎÝÛAFÛ1 AÛ ÛÀÎÎÁÎÎÎÁÎÎÎÎÙaf parse'2×3+4'AÚÎÁÎÎÌÚÁÌ ÚÁÎÌ2 × ÚÁÌ 43 +© Bunda-Gerth binding matrix.© parse of simple expression.245


af parse'(1+2)-3×÷4' © parentheses are retained in the parse-tree.AÚÎÎÎÁÎÎÎÌÚÎÎÁÎÎÌ ÚÎÁÎÌÚÎÁÎÌ - ÚÁÌ ÚÁÌ( ÚÁÎÌ 3 × ÷ 4ÚÁÌ 21 +af parse '(((2)))'AÚÁÎÌ( ÚÁÎÌ( ÚÁÌ( 2© redundant parentheses retained.© Definition extended with Array strands and operators.© Notice the use of macro "rand" for Array or Function operand:display afo© Arrays, Functions, Operators.Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ A 0 1 2 3 4 © Arrays ÛÛ F + - × ÷ © Functions ÛÛ AF © bound left argument ÛÛ MOP ¨ © Monadic operator ÛÛ DOP . ° ÿ © Dyadic operators ÛÛÛÛ rand=A.F © macro: operand is A or F ÛÛÛÛ A:A…A© strand binding, tightest of all ÛÛÛÛ DOP:rand…MOP © dyadic and ÛÛ rand:MOP…F © ... monadic operators ÛÛÛÛ A:F…AF © left argument to its function ÛÛÛÛ AF:A…A F:A…A © function to its right argument. ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙafo parse''ÚÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÌÛA ÛF ÛMOPÛÚÎÎÎÏÎÎÎÎÎÏÎÎÎÎÎÏÎÎÎÝÛA Û4 A Û2 AF Û3 FÛÃÎÎÎÏÎÎÎÎÎÏÎÎÎÎÎÏÎÎÎÝÛF Û1 A Û Û3 FÛÃÎÎÎÏÎÎÎÎÎÏÎÎÎÎÎÏÎÎÎÝÛAF Û1 A Û Û ÛÃÎÎÎÏÎÎÎÎÎÏÎÎÎÎÎÏÎÎÎÝÛDOPÛ3 MOPÛ3 MOPÛ ÛÀÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÙ© Bunda-Gerth binding matrix.afo parse '0 1+.ר3÷4' © parse tree for operator-function-array binding.AÚÎÎÎÎÁÎÎÎÎÌÚÎÎÁÎÎÌ ÚÁÎÌÚÁÌ ÚÎÁÎÎÌ ÚÁÌ 40 1 ÚÁÎÌ ¨ 3 ÷+ ÚÁÌ. ×246


afo parse '0+1-2×3÷4' © array-function sequences associate right.AÚÎÎÁÎÎÎÌÚÁÌ ÚÎÎÁÎÎÌ0 + ÚÁÌ ÚÎÁÎÎÌ1 - ÚÁÌ ÚÁÎÌ2 × ÚÁÌ 43 ÷afo parse '+°-°×°÷'FÚÎÎÁÎÎÎÌÚÎÎÁÎÎÌ ÚÁÌÚÁÎÌ ÚÁÌ ° ÷+ ÚÁÌ ° ×° -afo parse'+°2 3'FÚÁÎÌ+ ÚÁÎÌ° ÚÁÌ2 3© operator-operand sequences associate left.© strand binds tighter than operator.© Finally, the definition is extended with: Dfn braces {F} and "hybrid" tokens:© / š \ „, each of which can act as either function or operator, depending on© whether the token to its left is an array or function. Note the use of© distributions.display afho © afo extended with hybrids: H / š \ „Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛA 0 1 2 3 4 a ¸ ¾ © Arrays ÛÛF + - × ÷ © Functions ÛÛH / š \ „ © Hybrid function/operators ÛÛAF © bound left argument ÛÛMOP ¨ & © Monadic operators ÛÛDOP . ° ÿ © Dyadic operators ÛÛ() {F} © Dfn ÛÛÛÛrand=A.F.H © alias: operand ÛÛÛÛA:A…A© strand binding, tightest ÛÛÛÛDOP:rand…MOP © dyadic and ÛÛrand:MOP…F © ... monadic operators ÛÛF:H…F © hybrid as operator ÛÛÛÛA:F.H…AF© left arg to its function ÛÛÛÛAF.F:A…A© function to its right arg.ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙ247


afho parse'' © Bunda-Gerth binding table.ÚÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÌÛA ÛF ÛH ÛMOPÛÚÎÎÎÏÎÎÎÎÎÏÎÎÎÎÎÏÎÎÎÎÎÏÎÎÎÝÛA Û4 A Û2 AF Û2 AF Û3 FÛÃÎÎÎÏÎÎÎÎÎÏÎÎÎÎÎÏÎÎÎÎÎÏÎÎÎÝÛF Û1 A Û Û3 F Û3 FÛÃÎÎÎÏÎÎÎÎÎÏÎÎÎÎÎÏÎÎÎÎÎÏÎÎÎÝÛH Û Û Û Û3 FÛÃÎÎÎÏÎÎÎÎÎÏÎÎÎÎÎÏÎÎÎÎÎÏÎÎÎÝÛAF Û1 A Û Û Û ÛÃÎÎÎÏÎÎÎÎÎÏÎÎÎÎÎÏÎÎÎÎÎÏÎÎÎÝÛDOPÛ3 MOPÛ3 MOPÛ3 MOPÛ ÛÀÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÙafho°parse¨ '+/¨0' '1/¨0'A AÚÎÁÎÌ ÚÎÁÎÎÌÚÁÎÌ 0 ÚÁÎÌ 0ÚÁÌ ¨ 1 ÚÁÌ+ / / ¨afho°parse¨ 'a„0' 'a+„1'A AÚÁÎÌ ÚÎÁÎÎÌÚÁÌ 0 ÚÁÎÌ 1a „ a ÚÁÌ+ „afho parse'2{¸+¾}3'AÚÎÎÎÁÎÎÎÌÚÎÁÎÌ 32 ÚÎÁÎÌ{ ÚÁÎÌÚÁÌ ¾¸ +© hybrids: defining example.© regular vs. modified assignment.© Dfn248


1 afho parse'+.×/3/¾' © 1 defn ... => traced evaluation.ÚÎÂÎÎÎÂÎÂÎÂÎÂÎÂÎÌÛFÛDOTÛFÛHÛAÛHÛAÛÛ+Û. Û×Û/Û3Û/Û¾ÛÀÎÁÎÎÎÁÎÁÎÁÎÁÎÁÎÙÚÎÂÎÎÎÂÎÂÎÂÎÎÎÂÎÌÛFÛDOTÛFÛHÛ MFÛAÛÛ+Û. Û×Û/ÛÚÁÌÛ¾ÛÛ Û Û Û Û3 /Û ÛÀÎÁÎÎÎÁÎÁÎÁÎÎÎÁÎÙÚÎÂÎÎÎÂÎÂÎÂÎÎÎÎÎÌÛFÛDOTÛFÛHÛ A ÛÛ+Û. Û×Û/Û ÚÁÎÌÛÛ Û Û Û ÛÚÁÌ ¾ÛÛ Û Û Û Û3 / ÛÀÎÁÎÎÎÁÎÁÎÁÎÎÎÎÎÙÚÎÂÎÎÎÎÂÎÂÎÎÎÎÎÌÛFÛ MOPÛHÛ A ÛÛ+ÛÚÁÌ Û/Û ÚÁÎÌÛÛ Û. × Û ÛÚÁÌ ¾ÛÛ Û Û Û3 / ÛÀÎÁÎÎÎÎÁÎÁÎÎÎÎÎÙÚÎÎÎÎÎÂÎÂÎÎÎÎÎÌÛ F ÛHÛ A ÛÛÚÁÎÌ Û/Û ÚÁÎÌÛÛ+ ÚÁÌÛ ÛÚÁÌ ¾ÛÛ . ×Û Û3 / ÛÀÎÎÎÎÎÁÎÁÎÎÎÎÎÙÚÎÎÎÎÎÎÎÂÎÎÎÎÎÌÛ F Û A ÛÛ ÚÎÁÎÎÌÛ ÚÁÎÌÛÛÚÁÎÌ /ÛÚÁÌ ¾ÛÛ+ ÚÁÌ Û3 / ÛÛ . × Û ÛÀÎÎÎÎÎÎÎÁÎÎÎÎÎÙÚÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ A ÛÛ ÚÎÎÁÎÎÎÌ ÛÛ ÚÎÁÎÎÌ ÚÁÎÌÛÛÚÁÎÌ / ÚÁÌ ¾ÛÛ+ ÚÁÌ 3 / ÛÛ . × ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÙAÚÎÎÁÎÎÎÌÚÎÁÎÎÌ ÚÁÎÌÚÁÎÌ / ÚÁÌ ¾+ ÚÁÌ 3 /. ש For more examples, see ##.scripts.parse and ##.scripts.BindingSee also: dft.125 unify.249 tokens.170 bf.439 loop.550 lisp.236ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎrmcmline „ ##.rmcm line© <strong>APL</strong> source with comments removed.Removes comments from a vector or matrix of <strong>APL</strong>, by identifying the first unquoted"©" on each line character and stripping it and all characters to itsright.Note that the function doesn't remove any resulting trailing blank columns butif the result is to be passed to ŒFX, this will make no difference.249


VMJ supplies this alternative, named after a Finnish Prime Minister whose initialswere HHH, and whose most memorable quotation was "No comments, I'm drinkingcoffee now".hhh„{q„¾((Ÿ\(¾='©')^=\¾¬'''')/q)„' '(-+/^\' '=²q)‡q}Examples:a„brmcm 'a„b © copy'© comment removed.rmcm 'cm„''©'' © comment'cm„'©'clean_fn„{Œfx(rmcm¨Œnr ¾)~›''}display Œcr'dup'Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ̇dup„{ÛÛ© blah, blah,ÛÛÛÛ ¾ ¾ © blah, blah,ÛÛÛÛ© blah, blah.ÛÛÛÛ© (c) C-A.S. ÛÛ} ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙclean_fn'dup'display Œcr'dup'Ú…ÎÎÎÎÎÎ̇dup„{ ÛÛ ¾ ¾ÛÛ} ÛÀÎÎÎÎÎÎÎÙone_liner„{ŒML„0ŒFX†,‡{bd„'{ª' '{'db„'ª}' '}'bds„'{ ª' '{'dbs„'ª }' '}'†subs/bd db bds dbs ¾}†{¸,'ª',¾}/ŒNR ¾}Œcr one_liner'dup'dup„{¾ ¾}one_liner clean_fn'display'© '©' character preserved.© function with white space removed.© commented function.© remove comments and blank lines.© uncommented function.© Turn function into 1-liner.© fix:© brace-diamond … brace© diamond-brace … brace© brace diamond … brace© diamond brace … brace© substitution in© diamond-joined lines.© turn dup into 1-liner.© turn display fn into 1-liner.Œcr'display'display„{ŒIO ŒML„0 ª ¸„1 ª chars„¸œ'..''''|-' 'ÚÌÀÙÛÎ' ª tl tr bl br vt hz„chars250


display ¼2 2 © still works!Ú…ÎÎÎÎÎÎÎÎÎÎÎÎ̇ Ú…ÎÎÌ Ú…ÎÎÌ ÛÛ Û1 1Û Û1 2Û ÛÛ À~ÎÎÙ À~ÎÎÙ ÛÛ Ú…ÎÎÌ Ú…ÎÎÌ ÛÛ Û2 1Û Û2 2Û ÛÛ À~ÎÎÙ À~ÎÎÙ ÛÀ¹ÎÎÎÎÎÎÎÎÎÎÎÎÙŒcr one_liner clean_fn 'one_liner'one_liner„{ŒML„0 ª ŒFX†,‡{bd„'{' '{' ª db„'}' '}' ª bds„'{' '{' ª dbs„'}' '}' ª© This expression, with improvements from JoHo, removes comments from all© <strong>functions</strong> and operators in all namespaces:rmcm(refs Œthis).{¸¸{0=½¾: ª Œfx°¸¸°Œcr¨¾}Œnl-,¾°.+0.1 0.2}›3 4See also: tokens.170 refs.380ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎunifyexpr „ vars ##.unify expr expr ···© Unification of expressions.Returns the unification of a vector of expressions, with respect to variableslisted in its left argument.For example, if (1×2)+y and x+(3×4) represent the same expression, then it followsthat x = 1×2 and y = 3×4, and both expressions must be equal to (1×2)+(3×4).The new expression is said to be the "unification" of the previous ones with respectto variables x and y.Technical notes:Unify takes a _vector_ of expressions to be unified and uses primitive reductionto apply Robinson's algorithm cumulatively, two expressions at a time.The algorithm examines the two expressions in parallel, looking for the firstpair of terms that "disagree". For example, in expressions:(1+2) × y ÷ 3 - (z + 5)u × (6+7) ÷ 3 - (z + w)the disagreement pairs are:(1+2) uy (6+7)5 wIf just one of the items in the pair is a variable, it is substituted in both ofthe original expressions with the corresponding value of the pair, and the wholeprocess repeated until the expressions match. If neither of the items is a variable,then unification fails and a: "Can't unify" error is generated.A small complication arises with repeated variables. The expressions:z × z(1+y) × (x+2)251


yield two disagreement pairs:z (1+y)z (x+2)In this case, the _values_ of the two disagreement pairs (1+y) (x+2) are themselvesunified recursively to (1+2), before being substituted for z, yielding(1+2)×(1+2) as the unified expression.This coding includes an "occurs check" to guard against non-termination causedby an attempt to substitute for a variable with a value containing one or moreoccurrences of that variable. Using the notation: [¸/¾]¹ to mean "substitute ¸for occurrences of ¾ in expression ¹" or more succinctly "¸ for ¾ in ¹". An exampleof such non-termination might be:[(x+1)/x] 2+x=> [(x+1)/x] 2+(x+1)=> [(x+1)/x] 2+((x+1)+1)=> [(x+1)/x] 2+(((x+1)+1)+1)=> ...If the process that generates the expressions to be unified, can guarantee thatsuch cases do not occur, this check may be omitted.References:Robinson, J.A. "A machine-oriented logic based on the resolution principle",Journal of the ACM, 12:23-41, 1965.Brown, J.A. and Guerreiro, R. "<strong>APL</strong>2 Implementations of Unification", ConferenceProceedings <strong>APL</strong>87. <strong>APL</strong> Quote Quad, V17.4, 1987.A slightly different version of unify is used by max.dws for the unification oftype expressions during type inference. For a discussion of polymorphic typesand some more references, see max.dws/Implementation.Examples:© Here is a parser for simple parenthesised expressions.px„{© Single char token parser.1=½¾:œ¾© atom: return scalar.depth„ׯ1²-š+\'()'°.=¾ © within parens.lpars„0 1ºdepth© left parens.smask„lpars‰depth © segmentation mask.drops„1 ¯1×›smask/lpars © parens drop.’¨†‡¨/drops,›smask›¾ © process each segment.}© and a corresponding de-parser:fx„{© Format parse tree.0=­¾:•¾© atom: done.†,/{ © join branches.0=­¾:¾ © atom: done.'(',¾,')' © parenthesise.}°’¨¾© each branch.}© Expressions in x and y:lex rex„px¨ '(1×2)+y' 'x+(3×4)'252


disp¨ lex rexÚ…ÎÎÂÎÂÎÌ Ú…ÂÎÂÎÎÎÌÛ1×2Û+ÛyÛ ÛxÛ+Û3×4ÛÀÎÎ…ÁÎÁÎÙ ÀÎÁÎÁÎÎ…Ù© Unification of expressions:disp 'xy'unify lex rexÚ…ÎÎÂÎÂÎÎÎÌÛ1×2Û+Û3×4ÛÀÎÎ…ÁÎÁÎÎ…Ù© ... formatted.fx 'xy'unify lex rex(1×2)+(3×4)© More complex expressions:xa„' a + (b÷n) - (b × a) + a 'xb„'(1-c) + (c÷2) - d + e 'xc„' f + g - h + (i-3)'vars„lcase Œa© vars: a b ··· zfx vars unify px¨xa xb xc~¨' '(1-3)+(3÷2)-(3×(1-3))+(1-3)© Unify can be used to resolve "logical syllogisms", such as:©© Socrates is a man; all men are mortal; ergo, Socrates is mortal.s1„'Socrates' 'is' 'man's2„'Man' 'is' 'mortal''man' 'Man'unify s1 s2Socrates is mortal© If both items in the disagreement pair are variables, the (lexically)© higher is mapped to the lower. In this example, M…C, M…D, C…A, D…B…A:A+AŒa unify 'A+B' 'C+D' 'M+M'© matching variables.© Unify works on any conformable arrays, including those of higher rank.© In the following matrices, constant '*' propogates through all variables© A-Z:a„2 13½2/13†Œab„2 13½13‡Œa(œ²,b)„'*'disp a bÚ…ÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛAABBCCDDEEFFGÛNOPQRSTUVWXYZÛÛGHHIIJJKKLLMM‡NOPQRSTUVWXY*‡ÀÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎ…Ù© * matches M matches Y matches F matches X ...Œa unify a b**************************253


© Expression unification is used to infer type in some functional languages.© Here is the BNF for a tiny right-associative type expression:©© texp := func | atom© func := atom…texp | (texp)…texp© atom := tcon | tvar© tcon := #© tvar := ¸ | ‘ | ¹ | ¼ | ¾©© Type variables are ¸ ‘ ¹ ¼ ¾,© # is the only type constant and© … is the only type operator.© Examples of expressions:©© #, ¸, ¸…¾, (¸…‘)…¹…#© Parser for such expressions:pt„{ŒML„0© Parse type expression.œ«{© Parse tree and remainder.0=½¾:¸ ¾© done: parse tree and remainder.hd tl„(œ¾)(1‡¾)© head and tail of expr.'('=hd:†’/« ’ tl© parenthesised sub-expr:')'=hd:¸ tl© complete sub-expression:'…'=hd:²¸{¸¸ hd ¾}\²« ’ tl © function:hd ’ tl© atom:}¾~' '© ignoring blanks.}© and a corresponding de-parser:ft„{ŒML„10=­¾:•¾0=­œ¾:¹’¨¾'(',(’œ¾),')',¹’¨1‡¾}© Format parse tree.© atom: done.© atomic left branch: no parens.© parenthesised left branch.© Parse trees for type expressions:disp pt'¸…¹…¼…¾'Ú…ÂÎÂÎÎÎÎÎÎÎÎÎÌÛ Û ÛÚ…ÂÎÂÎÎÎÌÛÛ¸Û…ÛÛ¹Û…Û¼…¾ÛÛÛ Û ÛÀÎÁÎÁÎÎ…ÙÛÀÎÁÎÁÎÎÎÎÎÎÎÎ…Ùdisp pt'(¸…¹)…¼…¾'Ú…ÎÎÂÎÂÎÎÎÌÛ¸…¹Û…Û¼…¾ÛÀÎÎ…ÁÎÁÎÎ…Ù© Formatted parse tree. Note how redundant parentheses are ignored:ft pt'(¸…¹)…(¼…¾)'(¸…¹)…¼…¾© Vars: ¸ ‘ ¹ ¼ ¾vars„'¸‘¹¼¾'254


© Some type expressions:xa„'(¸…¸)…¹ 'xb„' ‘…‘ 'xc„' ¼…(¾…#)'© Unified type expressions:ft vars unify pt¨xa xb xc(#…#)…#…#© The following expressions can't be unified:clash„pt¨ '(¸…¸)…¾' '¸…(¾…¾)'ft vars unify clashCan't unifyft vars unify clash^© However, if the intention is that the variables© in the expressions are independent, they can be© distinguished by:dv„{ŒML„1 © Distinguish Variables ¸ in exprs ¾.vlft vrgt„¸°•°¹¨¾ © vars in left and right exprs(vlft•vrgt){© duplicate vars.(›¾)¹¸¸:(¸¸¼›¾)œ¾¾ © var in old: subs new.0=­¾:¾© atom: pass through.’¨¾© tree: traverse.}(¸~vlft)\¾© translated right expr.}© The left argument of dv is the "pool" of© variables, available for substitution.ft¨clash(¸…¸)…¾ ¸…¾…¾© Distinguish variables:ft¨vars dv clash(¸…¸)…¾ ‘…¹…¹© Unify succeeds:ft vars unify vars dv clash(¸…¸)…¹…¹See max.dws/Implementation.See also: tokens.170 parse.237ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎadicdigs „ alph ##.adic numb© Bijective base-¸ numeration.numb „ alph ##.adic digs© and its inverse.Bijective base-¸ numeration is a 1-1 mapping between strings in alphabet ¸ andthe natural numbers 0 1 2 ...The strings are mapped in "shortlex" order so that shorter strings map to smallernumbers and same-length strings map in lexicographical order. In particular,natural number 0 maps to the null string.255


Here are the mappings for the numbers 0..16 using alphabet 'AB':disp 'AB'°adic¨ 0 to 16Ú…ÂÎÂÎÂÎÎÂÎÎÂÎÎÂÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÎÂÎÎÎÎÌÛ ÛAÛBÛAAÛABÛBAÛBBÛAAAÛAABÛABAÛABBÛBAAÛBABÛBBAÛBBBÛAAAAÛAAABÛÀ´Á…Á…ÁÎ…ÁÎ…ÁÎ…ÁÎ…ÁÎÎ…ÁÎÎ…ÁÎÎ…ÁÎÎ…ÁÎÎ…ÁÎÎ…ÁÎÎ…ÁÎÎ…ÁÎÎÎ…ÁÎÎÎ…ÙNotice the difference between 2-adic enumeration (with alphabet 0 1):disp 0 1°adic¨ 1 to 10 © 2-adic 1..10Ú…ÂÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÌÛ0Û1Û0 0Û0 1Û1 0Û1 1Û0 0 0Û0 0 1Û0 1 0Û0 1 1ÛÀ…Á…Á~Î…Á~Î…Á~Î…Á~Î…Á~ÎÎÎ…Á~ÎÎÎ…Á~ÎÎÎ…Á~ÎÎÎ…Ùand regular binary:disp 2 ƒÿ¯1¨ 1 to 10 © binary 1..10Ú…ÂÎÎÎÂÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÌÛ1Û1 0Û1 1Û1 0 0Û1 0 1Û1 1 0Û1 1 1Û1 0 0 0Û1 0 0 1Û1 0 1 0ÛÀ…Á~Î…Á~Î…Á~ÎÎÎ…Á~ÎÎÎ…Á~ÎÎÎ…Á~ÎÎÎ…Á~ÎÎÎÎÎ…Á~ÎÎÎÎÎ…Á~ÎÎÎÎÎ…ÙRef: http://en.wikipedia.org/wiki/Bijective_numerationWith coding from Jay Foad, function [adic] converts between natural numbers and¸-adic digit strings. The function is a self-inverse: given a _scalar_ rightargument, it returns a vector of ¸-digits; and given a _vector_ right argument,it returns the corresponding natural number:ŒA adic 'DYALOG'58975989© 'A..Z'-adic … natural number.phrase „ ,¨ 'I' 'AM' 'OK' '' 'HOW' 'R' 'U'disp phraseÚ…ÂÎÎÂÎÎÂÎÂÎÎÎÂÎÂÎÌÛIÛAMÛOKÛ ÛHOWÛRÛUÛÀ…ÁÎ…ÁÎ…Á´ÁÎÎ…Á…Á…ÙŒA°adic¨ phrase9 39 401 0 5821 18 21'abc' adic 99cabc© vector of word vectors.© ŒA-adic number of each word.© 'abc'-adic representation of number,99'abc' adic 'abc' adic 99© and its inverse.ŒA (adicÿ2) 12341234© adicÿ2 is identity.ŒA (adicÿ2) 'DYALOG' © .. ..DYALOGApplications------------The function could be used for a systematic exploration of words that are writablein a given alphabet. For example, given some error-trapping, it could beused to test arbitrary expressions:256


try„{ © execute of ¾ expressions using tokens from ¸.join„{†¸{¸,¸¸,¾}/¾} © ¸-join of vector ¾.' 'join''join ¸°adic{ © ¸-adic translation from natural number.0::''© error: null.expr„¸¸ ¾© expression to try.rslt„–expr© attempted execution.›expr© success: good expression.}¨¼¾© ¾ is number of expressions to try.}'+/'try 500+ / +/ // +// /// +/// //// +//// ///// +///// ////// +////// /////// +///////'+/«'try 50+ / « +/ +« // «« ++« +// +/« +«« /// //« «+« «/« ««« +++« ++/« ++««try'#.[«]'try 1e3# « ## #« «# «« ### ##« #.# #«# #«« «## «#« «[] ««# ««« #### ###« ##.# ##«# ##««#.## #.#« #«## #«#« #«[] #««# #««« «### «##« «#.# «#[] «#«# «#«« «[«] «[]# «[]« ««## ««#« ««[] «««# «««« ##### ####« ###.# ###[] ###«# ###«« ##.####.#« ##«## ##«#« ##«[] ##««# ##««« #.### #.##« #.#.# #.#«# #.#««try'+/¨°«'try 1e3+ / « +/ +¨ +« // /¨ °¨ «¨ «« ++« +// +/¨ +/« +¨/ +¨¨ +¨« +°+ +°/ +°« +«« /// //¨ //« /¨/ /¨¨ /°+ /°/ /°« °¨/ °¨¨ °°+ °°/ °°« «+« «/« «¨/ «¨¨ «°+ «°/ «°«««¨ ««« +++« ++/« ++¨« ++«« +/+« +/// +//¨ +/¨/ +/¨¨ +/¨« +/°+ +/°/ +/°« +/«« +¨+« +¨// +¨/¨ +¨¨/ +¨¨¨ +¨¨« +¨°+ +¨°/ +¨°« +¨«« +°+/ +°+¨ +°+« +°//+°/¨ +°°¨ +°«/ +°«¨ +°«« +«+« +«/« +««« //+« //// ///¨ //¨/ //¨¨ //¨« //°+//°/ //°« //«« /¨// /¨/¨ /¨¨/ /¨¨¨ /¨°+ /¨°/ /¨°« /°+/ /°+¨ /°// /°/¨ /°°¨ /°«/ /°«¨ /°«« °¨// °¨/¨ °¨¨/ °¨¨¨ °¨°+ °¨°/ °¨°« °°+/ °°+¨ °°// °°/¨ °°°¨ °°«/ °°«¨ °°«« «++« «+¨« «/+« «/¨« «¨// «¨/¨ «¨¨/ «¨¨¨ «¨°+ «¨°/ «¨°« «°+/ «°+¨ «°+« «°// «°/¨ «°/« «°°¨ «°«/ «°«¨ «°«« ««¨/ ««¨¨ ««°+ ««°/ ««°««««¨ «««« ++++« +++/« +++¨« +++«« ++/+« ++/¨« ++/«« ++¨+« ++¨¨« ++¨«« ++°+« ++°/« ++«+« ++«/« ++««« +/++« +/+/« +/+¨« +/+«« +//// +///¨ +//¨/ +//¨¨+//¨« +//°+ +//°/ +//°« +/¨+« +/¨// +/¨/¨ +/¨¨/ +/¨¨¨ +/¨¨« +/¨°+ +/¨°/ +/¨°« +/¨«« +/°+/ +/°+¨ +/°+« +/°// +/°/¨ +/°°¨Notice that the last test found some errors in <strong>Dyalog</strong>'s parser. For example, °¨and °°+ should generate syntax errors but seem not to. In contrast, «¨ and «°«are syntactically correct derived <strong>functions</strong>, though they have yet to be assigneda meaning in <strong>Dyalog</strong>. See the "muse" in …ncpath„ for a suggestion for «¨.See also …parse„.[adic] could also be used to stress-test a symbol table:(Œns'') –¨ time ,°'„0'¨ Œa°adic¨ ¼1e536.58© create 100K symbols.(muse:Function ŒA°adic defines 1-1 mapping between the natural numbers and the setof single words that can be written using the upper-case alphabet. Here arethe "words" that correspond to: 1 10 100 1000 ...Œa°adic¨ 10* 0 to 10A J CV ALL NTP EQXD BDWGN UVXWJ HJUNYV CFDGSXL AFIPYQJPGiven enough time, this expression:{•„' ',Œa adic ¾ ª ’ ¾+1} 1 © display all words. [¾]will display all possible words that can be written using upper-case lettersA-Z.257


This includes all possible names and some of these names will refer to metaphysicaldeities.It is generally understood that uttering all of the names of the Almightybrings the universe to an abrupt end. The fate of the cosmos, therefore,hinges on whether displaying a name in the session constitutes an utterance.Computer-assisted devotion certainly has a precedent in the form of digitalprayer-wheels: http://en.wikipedia.org/wiki/Prayer_wheel.)More worrying, from a mathematical point of view, an expression is deemed tobe _equivalent_ to its evaluation. This means that the mere existence ofexpression [¾] above, should be enough to trigger the apocalypse. Though thefact that (you believe) you are reading this must raise some doubts.Examples:disp 1 2°adic¨ 0 to 15 © 2-adic numbersÚ…ÂÎÂÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÎÎÌÛ0Û1Û2Û1 1Û1 2Û2 1Û2 2Û1 1 1Û1 1 2Û1 2 1Û1 2 2Û2 1 1Û2 1 2Û2 2 1Û2 2 2Û1 1 1 1ÛÀ´Á…Á…Á~Î…Á~Î…Á~Î…Á~Î…Á~ÎÎÎ…Á~ÎÎÎ…Á~ÎÎÎ…Á~ÎÎÎ…Á~ÎÎÎ…Á~ÎÎÎ…Á~ÎÎÎ…Á~ÎÎÎ…Á~ÎÎÎÎÎ…Ùdisp 'abc'°adic¨0 to 23 © 3-adic numbersÚ…ÂÎÂÎÂÎÂÎÎÂÎÎÂÎÎÂÎÎÂÎÎÂÎÎÂÎÎÂÎÎÂÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÌÛ ÛaÛbÛcÛaaÛabÛacÛbaÛbbÛbcÛcaÛcbÛccÛaaaÛaabÛaacÛabaÛabbÛabcÛacaÛacbÛaccÛbaaÛbabÛÀ´Á…Á…Á…ÁÎ…ÁÎ…ÁÎ…ÁÎ…ÁÎ…ÁÎ…ÁÎ…ÁÎ…ÁÎ…ÁÎÎ…ÁÎÎ…ÁÎÎ…ÁÎÎ…ÁÎÎ…ÁÎÎ…ÁÎÎ…ÁÎÎ…ÁÎÎ…ÁÎÎ…ÁÎÎ…Ùdisp ŒA°adic¨¼35© bijective base-26 numbers.Ú…ÂÎÂÎÂÎÂÎÂÎÂÎÂÎÂÎÂÎÂÎÂÎÂÎÂÎÂÎÂÎÂÎÂÎÂÎÂÎÂÎÂÎÂÎÂÎÂÎÂÎÂÎÎÂÎÎÂÎÎÂÎÎÂÎÎÂÎÎÂÎÎÂÎÎÂÎÎÌÛAÛBÛCÛDÛEÛFÛGÛHÛIÛJÛKÛLÛMÛNÛOÛPÛQÛRÛSÛTÛUÛVÛWÛXÛYÛZÛAAÛABÛACÛADÛAEÛAFÛAGÛAHÛAIÛÀ…Á…Á…Á…Á…Á…Á…Á…Á…Á…Á…Á…Á…Á…Á…Á…Á…Á…Á…Á…Á…Á…Á…Á…Á…Á…ÁÎ…ÁÎ…ÁÎ…ÁÎ…ÁÎ…ÁÎ…ÁÎ…ÁÎ…ÁÎ…Ùdisp 1 adic¨ 0 to 8© 1-adic: unary numbersÚ…ÂÎÂÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ0Û1Û1 1Û1 1 1Û1 1 1 1Û1 1 1 1 1Û1 1 1 1 1 1Û1 1 1 1 1 1 1Û1 1 1 1 1 1 1 1ÛÀ´Á…Á~Î…Á~ÎÎÎ…Á~ÎÎÎÎÎ…Á~ÎÎÎÎÎÎÎ…Á~ÎÎÎÎÎÎÎÎÎ…Á~ÎÎÎÎÎÎÎÎÎÎÎ…Á~ÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÙSee also: nats.290 words.169ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎapportionalloc „ {seats„435} ##.apportion populations © Huntington-Hill apportionment.From Ray Polivka: This algorithm apportions a fixed number of assets "fairly"among competing beneficiaries. It has been in use since the 1920s to divide the435 seats in the US House of Representatives among the states in proportion tothe size of each state's population.The algorithm begins by assigning 1 seat per state and then repeatedly adds oneof the remaining seats to the most under-represented state at each iteration.For details see the Wikipedia article:http://en.wikipedia.org/wiki/Huntington-Hill_methodExamples:© Population per state following the 1790 census (Wikipedia):s1790 „'CT' 'DE' 'GA' 'KY' 'MD' 'MA' 'NH' 'NJ' 'NY' 'NC' 'Pp1790 „ 236841 55540 70835 68705 278514 475327 141822 179570 331589 353523 4105 apportion p1790 © 105 seats apportioned *fairly*7 2 2 2 8 14 4 5 10 10 12 2 6 3 18258


s1790 ,® 105 apportion p1790 © table of seats by (1790) state.CT 7DE 2GA 2KY 2MD 8MA 14NH 4NJ 5NY 10NC 10PA 12RI 2SC 6VT 3VA 18See also: assign.144 X.160ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎbigcvec „ {larg} (fn ##.big) rarg© Arithmetic on large integers.Big performs integer arithmetic using a primitive operand function chosen from:fn dyadic monadic-- ------ -------+ add identity- sub negate× mult signum÷ div| mod abs< ltˆ le= eq‰ ge> gt¬ neThe arguments may be either numeric or for larger numbers, the character vectorrepresentation of a number. In each case, the result is a character vector.The operator was developed by Maria Wells, with a multiply function from John R.Clark.Examples:66612 ×big 3 © numb × numb'2' ×big 3© char × numb'2' ×big '3'© char × char'6'=2 ×big 3© result is char.'¯7000000000000000000'+big 18¯6999999999999999982© addition to large number.'23000000000000000000'-big 1 © subtract .. ..22999999999999999999'199999999999999999999999' ×big 2 © multiply .. ..399999999999999999999998259


1¯1'19999999999'


Background----------Balanced Ternary (BT) is a number system in which each place represents a powerof 3: 1 9 27 81 243 ... It differs from "standard" ternary in that instead ofusing non-negative digits (0 1 2), BT uses (¯1 0 1), the first of which, pronounced"bar-one", is more properly written with the bar or "vinculum" directlyover the 1. Here are the first few non-negative numbers together with their decimalequivalents:BT Decimal0 01 11 ¯1 2 = 3 + ¯1 "one, bar-one"1 0 31 1 41 ¯1 ¯1 5 = 9 + ¯3 + ¯1 "one, bar-one, bar-one"1 ¯1 0 61 ¯1 1 7 = 9 + ¯3 + 11 0 ¯1 81 0 0 91 0 1 101 1 ¯1 111 1 0 121 1 1 131 ¯1 ¯1 ¯1 14 = 27 + ¯9 + ¯3 + ¯1Operation---------Operator [bt] applies its operand function to or between balanced ternary (BT)arguments. Each scalar argument is represented by a vector of the balanced ternarydigits ¹ ¯1 0 1. For example:1 ¯1 +bt 1 0 © 2+3 … 51 ¯1 ¯1Special monadic operands ‚ and ƒ encode and decode between regular integer scalarsand their BT equivalents.‚bt 100 © BT encoding of 1001 1 ¯1 0 12550ƒbt 1 0 ¯1 1 © decoding of BT 1 0 ¯1 1ƒbt (‚bt 20) +bt ‚bt 30 © 20+30 … 50A monadic operand may be one of:¯¯¯¯¯¯¯+ identity- negative× signum| absolute‚ encode BT from integerƒ decode integer from BT261


A dyadic operand may be one of:¯¯¯¯¯¯+ sum- difference× product÷ quotient| residue* exponent˜ min— maxŸ greatest common divisor^ least common multiple¬ relationalMany arithmetic operations on BT numbers are particularly elegant:Conversion between BT and integers----------------------------------BT_vector to integer is just 3°ƒ5¯113ƒ 1 ¯1 ¯13ƒ ¯1 ¯1 1© decode BT© decode BTInteger to BT_vector is also relatively simple:encode„{¯1 + norm 1 + 3 enco ¾}where:enco, coded {3..3‚¾}, encodes with an appropriate number of 3-digits,norm, coded {3..3‚3ƒ¾}, resolves (carries) overflows.For example:0 1 2 1 21 2 3 2 33 enco 50 © standard 3-encode.1 + 3 enco 50 © + 1 1 ... 1norm 1 + 3 enco 502 0 1 0 0¯1 + norm 1 + 3 enco 501 ¯1 0 ¯1 ¯1© normalised (3-overflows carried forward).© - 1 1 ... 1 … BT.Negation--------Balanced ternary numbers are symmetrical with respect to sign; the negative of aBT number is just the negative of each of its digits. Here are the first fewnegative BT numbers:262BT Decimal0 0¯1 ¯1¯1 1 ¯2 = ¯3+1¯1 0 ¯3¯1 ¯1 ¯4¯1 1 1 ¯5 = ¯9+3+1‚bt 100 © BT representation of +100 (+/ 81 27 ¯9 0 1)1 1 ¯1 0 1‚bt ¯100 © BT representation of ¯100 (+/ ¯81 ¯27 9 0 ¯1)¯1 ¯1 1 0 ¯1


ƒbt - ‚bt 100 © (negating its digits negates the number)¯100Notice that, unlike two's complement binary numbers, both positive and negativenumbers have notional leading zeros to the left of the most significant digit.A normal BT form would remove these leading zeros except for the anomalous case(shared with standard decimal notation) of the number zero itself.... 0 0 1 1 ¯1 0 1 … 1 1 ¯1 0 1 © 100... 0 0 ¯1 ¯1 1 0 ¯1 … ¯1 ¯1 1 0 ¯1 © ¯100... 0 0 0 0 0 0 0 … 0 © 0Signum------The signum (sign) of a BT number is just it's most significant digit.¯110×bt ¯1 1 1 0 © ׯ15 … ¯1×bt 1 ¯1 ¯1 0 © ×15 … 1×bt 0 © ×0 … 0Addition--------The addition table for BT digits is:+ ¯1 0 1ÚÎÎÎÂÎÎÎÂÎÎÎ̯1 Û 1-Û¯1 Û 0 Û where:ÃÎÎÎÏÎÎÎÏÎÎÎÝ0 Û¯1 Û 0 Û 1 Û 1- means 1 with a carry of ¯1 to the next column.ÃÎÎÎÏÎÎÎÏÎÎÎÝ1 Û 0 Û 1 Û¯1+Û ¯1+ means ¯1 with a carry of 1 to the next column.ÀÎÎÎÁÎÎÎÁÎÎÎÙFor example:1 0 ¯1 0 1 73 +¯1 ¯1 ¯1 1¯38-------------- ---0 1 1 0 ¯1 35-------------- ---¯1 ¯1 1 „ carry(subtraction is just addition of the negative of the subtrahend).Multiplication--------------We use high-school long-multiplication with the following table:× ¯1 0 1ÚÎÎÎÂÎÎÎÂÎÎÎ̯1 Û 1 Û 0 Û¯1 ÛÃÎÎÎÏÎÎÎÏÎÎÎÝ0 Û 0 Û 0 Û 0 ÛÃÎÎÎÏÎÎÎÏÎÎÎÝ1 Û¯1 Û 0 Û 1 ÛÀÎÎÎÁÎÎÎÁÎÎÎÙ263


For example:1 0 ¯1 1 25 ׯ1 1 1¯5----------- ----¯1 0 1 ¯1 0 0 + ¯225 +1 0 ¯1 1 0 751 0 ¯1 1 25----------------- ----¯1 1 1 1 0 1¯125----------------- ----¯1Division--------[bt] uses standard high-school long division. See: eval.dws/notes.Long_division.First the dividend is partitioned into two vectors p and s, where p has at mostthe same number of digits as the divisor (q) and s is a vector of the remainingdigits. For example, if divisor q is 1 ¯1 ¯1 and the dividend is 1 ¯1 1 1 ¯1,then p is 1 ¯1 1 and s is 1 ¯1.ÀÎÎpÎÙ ÀsÎÙMultiples (1 or ¯1) of q are repeatedly (actually, only once or twice) subtractedfrom p until p lies in the half-closed interval from (and including) 0 to(but excluding) q. Note that q might be negative, so this means:q>0: (0ˆp)^(p


p div q = 0 div' q part p © result 0, q-partitioned p¯¯¯ ¯¯¯ ¯¯¯¯· r div' p s = r div" p s, p in q © p in interval [0..q)· · ¯¯¯ ¯¯¯ ¯¯· · r div" p « 1 = r p © null s: quotient remainder· · ¯¯¯· · r div" p s 1 = (r,0) div' p xfer s © shift of dividend and rslt· · · ¯¯¯ ¯¯¯ ¯¯¯¯· · · p xfer s = (p,1†s) (1‡s) © transfer of next digit.· · · ¯¯¯¯· · r div" p s 0 = (r + m) div' (p-m×q) s © rslt +„ m, dividend -„ m×q· · · ¯¯¯ ¯ ¯¯¯ ¯ ¯· · · m = ×/×p q © multiple: ¯1 or 1.· · · ¯· · p in q = p in' q (q>0) © p in half-interval [0..q)· · · ¯¯ ¯¯ ¯· · · p in' q 1 = (0ˆp)^(p


Division by (powers of) 3-------------------------To divide a BT number by 3 (rounding down the result) we add ¯1; then all digitsbut the last constitute the integer quotient and the last digit + 1 is the remainder.Using the example 86÷3 … 28r2:1 0 1 ¯1 ¯1 + 86 +¯1 ¯1-------------1 0 0 1 1 + 85ÀÎÎÎÎÂÎÎÎÙ 1Û ----Û 1 ¯1Û ÀÎÂÙÛ ÀÎÎÎÎÎÎ remainder 2ÀÎÎÎÎÎÎÎÎÎÎÎÎ quotient 28More generally, to divide a BT number by 3*¾, we add ¾½¯1 digits, then the integerquotient is all but the rightmost ¾ digits, and rightmost ¾ digits + ¾½1 isthe remainder. For example, to divide 54321 by 81 (81=3*4):54321÷81 … 670r51:1 0 ¯1 1 0 ¯1 ¯1 ¯1 0 ¯1 0 + © 54321¯1 ¯1 ¯1 ¯1 © (3µ81)½¯1--------------------------------1 0 ¯1 1 ¯1 1 1 0 1 1 ¯1 +ÀÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÙ 1 1 1 1 © (3µ81)½1Û ----------Û 1 ¯1 0 ¯1 0Û ÀÎÎÎÎÎÂÎÎÎÎÎÙÛ ÀÎÎÎÎÎÎÎ remainder 51ÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ quotient 670[bt] uses fast division by 3 to implement power (¸ *bt ¾).Other fast divisors-------------------LeRoy Eide has an algorithm for fast division-by-2 of BT numbers. The method maybe generalised to division by numbers of the form ¯1 1+3*¾, which include suchuseful divisors as 2 4 8 and 10. See …JitSub„Note that the parity (2|) of a BT number is just the parity of the (absolutevalue of the) sum of its digits. For a proof, see: eval.dws/notes.proof.†+bt/ 1 ¯1 ¯1 ¯1 0© bt-sum of digits … ¯2 (even)¯1 1†+bt/ †+bt/ 1 ¯1 ¯1 ¯1 0 © bt-sum bt-sum of digits … 0 (even)0†°(+bt/)ÿ­ 1 ¯1 ¯1 ¯1 0© bt-sum …limit„ of digits … 0 (even)0†°(+bt/)ÿ­ 99½¯1© bt-sum limit of ¯1 ¯1 .. ¯1 … ¯1 (odd)¯1|†°(+bt/)ÿ­¨ ‚bt¨ ¯10 to 100 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0Power ¸*¾ (¾‰0)---------------For ¸*¾, we avoid calculating ¾ products ¸ × ¸ × ···, by using the recurrencerelation:ÀÎÎÎ ¾ ÎÎÎÙ266¸*0 = 1¸*1 = ¸¸*2 = ¸×¸¸*¾ = (¸*3|¾) × {¾×¾×¾} ¸*˜¾÷3


which needs only O(3×3µ¾) products. 3|¾ and ¾÷3 use the fast division methodoutlined above.Extension to fractional numbers-------------------------------Operator [bt] deals only in integers. Balanced ternary numbers extend nicely tofractional values using a "ternary point", as the following sequence shows:decimalbalanced ternary------- ----------------120 1 1 1 1 0120÷3 1 1 1 1120÷9 1 1 1 . 1120÷27 1 1 . 1 1120÷81 1 . 1 1 1120÷243 0 . 1 1 1 1... and so on.Fractional BT numbers have the pleasant property that truncating them on theright rounds to the nearest number; in other words truncation is the same asrounding.Notice that, in common with all number bases, a rational number, whose denominatorcontains prime factors other than those of the base, gives rise to an infinitelyrepeated fractional sequence. Specifically, with BT numbers, this occursif the divisor has prime factors other than 3. Here are some decimal rationalnumbers together with their BT equivalents:1÷3 0 . 12÷3 1 . ¯11÷9 0 . 0 12÷9 0 . 1 ¯11÷2 0 . 1 1 1 1 ...1÷4 0 . 1 ¯1 1 ¯1 ...1÷8 0 . 0 1 0 1 ...1÷10 0 . 0 1 0 ¯1 0 1 0 ¯1 ...Notice also that, in common with decimal notation, some BT numbers have alternativerepresentations. For example, in decimal, one half may be expressed eitheras 0.5 or as 0.4999... Similarly, in BT notation, one half may be written eitheras 0 . 1 1 1 ... or as 1 .¯1 ¯1 ¯1 ...For more on fractional BT numbers, see …ratsum„ and …ratrep„.Historical notes----------------In 1840, Thomas Fowler, a contemporary of Charles Babbage, designed and built abalanced ternary calculating machine. See:http://www.mortati.com/glusker/fowler/index.htmhttp://www.ThomasFowler.org.ukIn the early days of electronic computing, several attempts were made to employ3-state logic, in which case balanced ternary was a natural coding for numbers.Notable among these were the Russian Setun (1958) and Setun-70 (1970) machines.See:http://www.computer-museum.ru/english/setun.htmExamples:1 0 1 +bt 1 0 1 © 10+10 … 201 ¯1 1 ¯1267


1 0 1 -bt 1 ¯1 1 ¯1 © 10-20 … ¯10¯1 0 ¯11 0 1 ×bt 1 0 1 © 10×10 … 1001 1 ¯1 0 11 0 1 *bt 1 0 1 © 10*10 … 10,000,000,0001 0 0 ¯1 ¯1 1 1 0 ¯1 1 ¯1 1 0 ¯1 0 ¯1 0 1 0 1 0 1‚bt 1001 1 ¯1 0 1© integer to BT100ƒbt 1 1 ¯1 0 1© BT to integerSee also: abc.320 nats.290 rats.302 ratsum.308 to.316 limit.215 stamps.314See also: eval.dws/notes.btaSee also: JitSub.600 ratrep.556See also: ary.317 ratsum.308 phinary.341ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎcfractnvec „ {tolerance„Œct} ##.cfract numb © Continued fraction approx of real ¾.Result [nvec] is a simple numeric vector, whose continued fraction reduction iswithin comparison tolerance of scalar argument [numb].Any real number ¾ may be respresented by a continued fraction (CF) of the form:¾ = n + 1ÎÎÎÎÎi + 1ÎÎÎÎÎj + 1ÎÎÎÎÎwhere n is an integer andwhere i j k ... are positive integers.or:or:or:or:k + 1ÎÎÎÎÎ...¾ = n + 1 ÷ i + 1 ÷ j + 1 ÷ k + 1 ÷ ...¾ = n + ÷ i + ÷ j + ÷ k + ÷ ...¾ = n + ° ÷ i + ° ÷ j + ° ÷ k + ° ÷ ...¾ = +°÷/ n i j k ...Given a (possibly infinite) CF, we can reconstitute a rational number arbitrarilyclose to the real number it represents by reducing successively more terms.Rational numbers have finite CFs and irrational numbers have infinite though(after ignoring the first term) possibly regular ones. For example:cfract 123÷3450 2 1 4 8© rational number: finite CF.cfract *1© irrational number: infinite, regular CF.2 1 2 1 1 4 1 1 6 1 1 8 1 1 10 1 1 12 ...cfract ±1© irrational number: infinite, irregular CF.3 7 15 1 292 1 1 1 2 1 3 1 14 ...Reducing successively longer leading sequences of the CF, produces increasinglycloser approximations. Here are reductions of the first 10 terms of the CF fore = 2.718281828459...:268


+°÷/¨ ,\ 10†cfract *12 3 2.6666667 2.75 2.7142857 2.71875 2.7179487 2.7183099 2.7182796 2.7182836Here are the (base-10) log differences for successive terms of e, Pi sqrt(2) andPhi. The last rows in each column show that reducing all terms in the CFproduces a difference that is within comparison tolerance; in this case with adefault value of 10*¯14:seq „ {+°÷/¨,\cfract ¾}err „ {10µ|(¾-¸¸ ¾)÷¾}col „ {6 2•®¾}vals „ (*1) (±1) (2*÷2) (0.5×1+5*÷2)© successive reductions.© base 10 log error factor© formatted column.© exp, Pi, sqrt 2, phi.col°(seq err)¨ vals¯0.58 ¯1.35 ¯0.53 ¯0.42¯0.98 ¯3.40 ¯1.22 ¯0.63¯1.72 ¯4.58 ¯2.00 ¯1.14¯1.93 ¯7.07 ¯2.76 ¯1.52¯2.83 ¯9.74 ¯3.53 ¯1.95¯3.76 ¯9.98 ¯4.29 ¯2.37¯3.91 ¯10.41 ¯5.06 ¯2.79¯4.99 ¯11.03 ¯5.82 ¯3.20¯6.08 ¯11.56 ¯6.59 ¯3.62¯6.19 ¯12.29 ¯7.35 ¯4.04¯7.39 ¯14.15 ¯8.12 ¯4.46¯8.61 ¯8.89 ¯4.88¯8.69 ¯9.65 ¯5.29¯9.99 ¯10.42 ¯5.71¯11.30 ¯11.18 ¯6.13¯11.37 ¯11.95 ¯6.55¯12.75 ¯12.71 ¯6.97¯14.13 ¯13.48 ¯7.38¯14.24 ¯7.80¯8.22¯8.64¯9.05¯9.47¯9.89¯10.31¯10.73¯11.14¯11.56¯11.98¯12.40¯12.82¯13.24¯14.07© 10°µ errors in successive approximations.Technical notes:This recurrence relation defines the CF of a rational number P÷Q. The '.' introducesdefinitions, which are local to an exdented antecedent (see max.dws), and% is integer quotient {˜¸÷¾}.cf p÷1 = p© whole number.cf p÷q = n, cf q÷r © q>1. n = p%q © integer quotient,. r = q|p © and remainder.269


which translates directly into code:cfract„{ © Continued fraction approximation of real ¾.¸„ŒCT ª ŒCT„¸ © default comparison tolerance.,†{ © cf from rational ¸÷¾:¾=1:¸© whole number: finished.n r„0 ¾‚¸ © next term and remainder.n,¾ ’ r© next term and cf of remainder.}/˜¾ 1÷1Ÿ¾© whole number ratio. See …rational„}The first line:¸„ŒCT ª ŒCT„¸© default comparison tolerance.has a misleading symmetry. "¸„···" is a special syntax, which supplies a defaultvalue for a missing left argument. The line means: If no left argument is given,default it to the current value of ŒCT (comparison tolerance), and then make alocal system variable ŒCT with the explicit or assumed value. In other words:if a left argument is given, use its value for comparison tolerance; otherwise,use the current value of ŒCT.With finite-precision representation of real numbers, such as IEEE 64-bit floatingpoint, [cfract] necessarily returns a finite vector (though see the "muse"section below). Therefore, the result always represents a _rational_ number ¸-tolerably close to its "real" argument.The left and right arguments of the inner function, which is applied by reduction:,†{ © cf from rational ¸÷¾:...}/˜¾ 1÷1Ÿ¾© whole number ratio. See …rational„are integers whose quotient is a rational number ŒCT-tolerably close to ¾. Thisinner function could be made tail-recursive by passing the rational pair asright argument, thus freeing the left argument to be an accumulator:cfract„{ © Continued fraction approximation of real ¾.¸„ŒCT ª ŒCT„¸ © default comparison tolerance.«{ © sequence accumulator.p q„¾© rational argument pair.q=1:¸,p© whole number: finished.n r„0 q‚p © next term and remainder.(¸,n)’ q r © extended accumulator and new ratio.}˜¾ 1÷1Ÿ¾© whole number ratio. See …rational„}but in this case, as the number of recursive calls is relatively small, thesaving does not pay for the additional local name assignment and so the functionas a whole, runs marginally slower.Here is an alternative, slower coding, which generates the CF directly, comparingits value against the subject number at the generation of each term:270cfract„{ © Continued fraction approximation of real ¾.¸„ŒCT ª ŒCT„¸© default comparison tolerance.real„¾© "real" number.«{ © starting with null sequence.whole part„0 1‚¾ © whole and fractional part of number.seq„¸,whole© sequence extended with next term.real=+°÷/seq:seq © continued fraction approximates real: done.seq ’÷part© otherwise: continued accumulation of terms.}¾ © starting with real number.}


Ref: http://en.wikipedia.org/wiki/Continued_fraction(muse:Continued fractions have many properties that make them an attractive alternativeto regular decimals (3.1415...) and rationals (355÷113).Bill Gosper's treatment of continued fraction arithmetic suggests that valuesbe represented as objects, each of which, when referenced, returns thenext term in the CF sequence.Implementing "closures" in <strong>Dyalog</strong> would give us an elegant way to do this.For example, a CF representation of "e" (*1) is the infinite regular sequence:1 0 1 1 2 1 1 4 1 1 6 1 1 8 1 1 10 1 1 12 ...A closure-based approach to providing an object that returns the next ¾terms in this sequence might be:then:cfe‘„{ © continued fraction stream for *1.S„¾© initial stream.{ © closure:¾


2 20 © first 20 terms of CF for sqrt 2.1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2(1 seq‘ 1 2)20 © first 20 terms of CF for sqrt 19.1 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1Finally, we could generalise our sequence generator to return a closure for_any_ regular sequence. This operator takes, as right argument, the initialterms of the sequence and as left operand, a function that generates furtherterms on demand:Then:seq‘„{© generate regular sequence closure.S„,¾© initial sequence.s„½S© minimum size.¸¸{© closure:¾


Ref: http://mathworld.wolfram.com/ContinuedFraction.htmlhttp://www.tweedledum.com/rwg/cfup.htm)Details of an experimental version of <strong>Dyalog</strong>, which implements closures maybe found at: http://dfns.dyalog.com/downloads/fre.pdfExamples:cfract 5÷80 1 1 1 2cfract *12 1 2 1 1 4 1 1 6 1 1 8 1 1 10 1 1 12© rational numbers have a finite CF.© e has an infinite but regular CF.+°÷/ cfract *1 © reduction reconstitutes e.2.718281828+°÷/Œ„cfract ±13 7 15 1 292 1 1 1 2 1 43.141592654+°÷/Œ„cfract root 21 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 21.414213562© irregular infinite CF for pi.© CF for sqrt(2).+°÷/Œ„cfract 0.5×1+root 5 © CF for golden mean (phi ²)1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 21.618033989cfract 3±11 1 1 3 1 5 1 7 1 9 1 11 1 13 1 15© regular CF for tan(1){Œ„¾,':',cfract root ¾}¨¼20© (regular) CFs for first 20 sqrts.1 : 12 : 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 23 : 1 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 24 : 25 : 2 4 4 4 4 4 4 4 4 4 4 46 : 2 2 4 2 4 2 4 2 4 2 4 2 4 2 47 : 2 1 1 1 4 1 1 1 4 1 1 1 4 1 1 1 4 1 1 1 4 1 28 : 2 1 4 1 4 1 4 1 4 1 4 1 4 1 4 1 4 1 49 : 310 : 3 6 6 6 6 6 6 6 6 611 : 3 3 6 3 6 3 6 3 6 3 6 312 : 3 2 6 2 6 2 6 2 6 2 6 2 613 : 3 1 1 1 1 6 1 1 1 1 6 1 1 1 1 6 1 1 1 1 6 1 214 : 3 1 2 1 6 1 2 1 6 1 2 1 6 1 2 1 6 1 315 : 3 1 6 1 6 1 6 1 6 1 6 1 6 1 716 : 417 : 4 8 8 8 8 8 8 818 : 4 4 8 4 8 4 8 4 8 419 : 4 2 1 3 1 2 8 2 1 3 1 2 8 2 1 3 1 220 : 4 2 8 2 8 2 8 2 8 2 8 2273


{Œ„¾,':',cfract 3 root ¾}¨¼20 © irregular CFs for first 20 cube roots.1 : 12 : 1 3 1 5 1 1 4 1 1 8 1 14 1 10 2 1 43 : 1 2 3 1 4 1 5 1 1 6 2 5 8 3 34 : 1 1 1 2 2 1 3 2 3 1 3 1 30 1 4 1 2 95 : 1 1 2 2 4 3 3 1 5 1 1 4 10 186 : 1 1 4 2 7 3 508 1 5 67 : 1 1 10 2 16 2 1 4 2 1 21 1 3 58 : 29 : 2 12 2 18 1 1 1 1 4 1 1 24 1 910 : 2 6 2 9 1 1 2 4 1 12 1 1 1 1 5711 : 2 4 2 6 1 1 2 1 2 9 88 2 1 212 : 2 3 2 5 15 7 3 1 1 3 1 1 9613 : 2 2 1 5 1 1 43 3 2 1 1 3 10 714 : 2 2 2 3 1 1 5 5 9 6 21 215 : 2 2 6 1 8 1 10 8 12 1 72116 : 2 1 1 12 10 18 1 6 1 21 1 2 217 : 2 1 1 3 138 1 1 3 2 3 1 1 20718 : 2 1 1 1 1 1 3 22 1 2 2 2 24 6419 : 2 1 2 63 1 2 2 2 1 95 2 1 1 220 : 2 1 2 1 1 154 6 1 1 1 6 232rational +°÷/¨ ,\ cfract ±1 © successive rational approximations to Pi.3 22 333 355 103993 104348 208341 312689 833719 1146408 54193511 7 106 113 33102 33215 66317 99532 265381 364913 1725033See also: rational.298 factors.282 sieve.315 gcd.284 root.345 fibonacci.279ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎcolsumsumvec „ {base„10} ##.colsum cols© Sum of (default decimal) columns.Morten Kromberg's function adds columns of digits, resolving, in parallel, carriesfrom column-sum overflows.Left argument [base], default 10, determines in which number base the sum is tobe evaluated.For example:colsum †(0 0 1)(9 9 9) © decimal sum: 1 + 999 … 10001 0 0 02 colsum †(0 0 1)(1 1 1) © binary sum: 1 + 7 … 81 0 0 0Technical notes:colsum„{¸„10¸{{(0=«½¾)‡¾}+š1 0²0,0 ¸‚¾}ÿ­+š¾}© Sum of (default decimal) columns.© repeat while overflow.[colsum] uses power-limit (¸¸ÿ­) to ripple carry values along the sum until noneremain:274¸{{(0=«½¾)‡¾}+š1 0²0,0 ¸‚¾}ÿ­+š¾Û ÃÎÎÎÎÎÎÎÎÎÙÃÙÃÎÎÙÃÙÃÎÎÙ ÃÙÀÁÎ initial sum with overflow.Û Û Û Û Û Û ÀÎÎÎÎ while carries remain.Û Û Û Û Û ÀÎÎÎÎÎÎÎÎÎÎ carry and ¸-residue rows.Û Û Û Û ÀÎÎÎÎÎÎÎÎÎÎÎÎ extra 0-col to hold overflow.Û ÛÛ ÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ carries shifted to next highest column.Û ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ carries added into new sum vector.Û ÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ surplus 0-col removed.ÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ number base (default decimal).


We can watch the carry-ripple working by injecting Œ„ into the code:then:¸{{(0=«½¾)‡¾}Œ„+š1 0²0,0 ¸‚¾}ÿ­+š¾ © repeat while carries.ÀÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ display intermediate sum.colsum †(9 1/0 1)(10/9) © 1 + 9999999999 … 100000000000 9 9 9 9 9 9 9 9 10 00 9 9 9 9 9 9 9 10 0 00 9 9 9 9 9 9 10 0 0 00 9 9 9 9 9 10 0 0 0 00 9 9 9 9 10 0 0 0 0 00 9 9 9 10 0 0 0 0 0 00 9 9 10 0 0 0 0 0 0 00 9 10 0 0 0 0 0 0 0 00 10 0 0 0 0 0 0 0 0 01 0 0 0 0 0 0 0 0 0 00 1 0 0 0 0 0 0 0 0 0 01 0 0 0 0 0 0 0 0 0 0Notice that carries ripple along the resulting sum vector "in parallel". Thefollowing sum overflows initially in the 5th and 10th columns; then the 4th and9th and so on.colsum †(4 1 4 1/0 1 0 1)(10/9) © 100001 + 9999999999 … 100001000000 9 9 9 10 0 9 9 9 10 00 9 9 10 0 0 9 9 10 0 00 9 10 0 0 0 9 10 0 0 00 10 0 0 0 0 10 0 0 0 01 0 0 0 0 1 0 0 0 0 00 1 0 0 0 0 1 0 0 0 0 01 0 0 0 0 1 0 0 0 0 0Examples:colsum †(9 9 9 9)(0 0 0 1) © 9999 + 1 … 100001 0 0 0 04 5½¼9 © 5 columns of numbers.1 2 3 4 56 7 8 9 12 3 4 5 67 8 9 1 2colsum 4 5½¼91 8 2 6 0 4© 5-column sum. Compare with:+/12345 67891 23456 78912 © (for comparison with above).1826042 colsum †(1 1 1 1)(0 0 1 0) © binary: 15 + 2 … 171 0 0 0 116 colsum ®, 1000 © decimal 1000 in hexadecimal.3 14 8See also: nats.290275


ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎefractnvec „ P ##.efract Q© Egyptian fractions.Any rational number in the range 0


«{(p q)„¾÷(†¾){¾=0:|¸ ª ¾ ’ ¾|¸}†²¾p=1:{¾[“¾]}¸,q}r„(0=p|1+q×¼q-1)¼1s„(1+q×r)÷p(¸,s×q)’ r s}¸ ¾efract„{(ŒML ŒIO)„3 1© Egyptian fractions: Binary method‘G„{¾=0:|¸ ª ¾ ’ ¾|¸}(p q)„¸ ¾÷¸ ‘G ¾ ª p=1:qn„—2µq ª b„2*nr„˜(p×b)÷q ª s„(p×b)-r×q}(a c)„{2*((n½2)‚¾)/²¯1+¼n}¨r s(a,c){¾÷¸ ‘G¨¾}((½a),½c)/b×1 qExamples:3 efract 7 © Egyptian fraction rep of 3÷73 11 2313 7rational +/÷ 3 efract 7© round-trip to check.rational +/÷ Œ„ 355 efract 452 © (coarse approximation to ±÷4).2 4 29 1093 1790881 6.414507721E12355 452disp 2 3 5 7 °.efract 11 13 17 19Ú…ÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎ̇ 6 66 Û 7 91 Û 9 153 Û 10 190 ÛÃ~ÎÎÎÎ…Ï~ÎÎÎÎÎÎÎ…Ï~ÎÎÎÎÎÎÎ…Ï~ÎÎÎÎÎÎÎ…ÝÛ 4 44 Û5 33 2145Û 6 102 Û7 67 8911ÛÃ~ÎÎÎÎ…Ï~ÎÎÎÎÎÎÎ…Ï~ÎÎÎÎÎÎÎ…Ï~ÎÎÎÎÎÎÎ…ÝÛ3 9 99Û3 20 780 Û4 23 1564Û 4 76 ÛÃ~ÎÎÎÎ…Ï~ÎÎÎÎÎÎÎ…Ï~ÎÎÎÎÎÎÎ…Ï~ÎÎÎÎÎÎÎ…ÝÛ2 8 88Û 2 26 Û3 13 663 Û3 29 1653ÛÀ~ÎÎÎÎ…Á~ÎÎÎÎÎÎÎ…Á~ÎÎÎÎÎÎÎ…Á~ÎÎÎÎÎÎÎ…Ù© ... some more.See also: rational.298ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎesh##.esh digits© Shell for Eide-number sums.[esh] is an interactive shell for Eide-number sums (see …ratrep„). [esh] interpretseach line of •-input as a vector of numbers in the current base and displaysits sum by using …ratsum„ reduction. This input-eval-display loop continuesuntil a terminating ')' is input.The right argument provides the [digits] for the initial number base (radix).The digits, and therefore the base, may subsequently be changed by an input lineof the form {···0···}.277


To start in decimal, we could call [esh] so:esh ŒD© start in decimal.In addition to the formal syntax of numbers required by …ratsum„, [esh] acceptsand displays numbers in a more informal style, using these five substitutions:nnn.fff „… © plain num … enum.¯nnn.fff „… comp'' © negative num … complement...lrulrunnn.fff „… nnn.fffrrurru.. „… ..lrulrunnn.fffrrurru.. „… {lru|nnn.fff|rru}© .. precedes repeated lru.© .. follows repeated rru.© combination of the above.The "double-dot" digraph is a notational device, which captures its longest adjacenttwice-repeated string for the appropriate replication unit (RU).For example:123.45 „… © Simple number.¯123.45 „… © Explicit negative sign absorbed...12123.45 „… © Non-zero LRU.123.4545.. „… © Non-zero RRU...121234.5656.. „… © Both RUs non-zero.Notice that, with a number such as "0.233766233766..", it is the _whole_ of the"233766" that is repeated indefinitely (not just the "6" on the end). When readingsuch numbers, we must learn to spot the _longest_ twice-repeated sequence.Informally, .. means "the adjacent sequence repeated indefinitely". For example,one third may be represented in decimal thus:0.33.. © decimal one-third.NB: Double-dots do not confer any vagueness of value. Such numbers have perfectaccuracy (unlike the beguiling decimal "0.1" in your PC's spreadsheet).For example, the interaction:54.99.. © display number.does not constitute a rounding; "5" and "4.99.." are alternative representationsof the _same_ decimal number; it's just that esh's (actually …ratsum„'s) displaycode favours the shorter form.This may come as a bit of a surprise:¯1¯2..999..998although, after a moment's reflection, it seems reasonable that adding 1 to ..99would cause carried "1"s to ripple ever leftwards, leaving ..00. An alternativeway to come to terms with this might be to imagine a brand new odometer with anunspecified number of digit positions: [..00]. What would we expect to happen ifwe wound the odometer backwards by one click?278


Formal syntax:Examples¯¯¯¯¯¯¯¯num := seq © whole number 03102405| .. seqseq seq © non-zero LRU ..121234| seq . seq © fractional number 123.456| seq . seq seqseq .. © non-zero RRU 123.455..| .. seqseq seq . seq seqseq .. © non-zero RUs ..1123.4566..where:seq is a seqence of digits drawn from the current base {digs}. 012seqseq is a twice-repeated sequence. 012012Examples:esh Œd© start in decimal.©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©© Decimal1 2 3 4 © sum some nums.104.99.. © normalised display.50.142857142857.. 0.0909.. © 1/7 + 1/11 … 18/770.233766233766..5 ¯12 ¯4.5 © <strong>APL</strong> has a nice "neg" sign.¯11.5 © esh accepts formal input.2.2424..© Note the subtle differences in these four examples:2.33 5.667.992.33.. 5.667.9933..2.33 5.66..7.9966..8422.33.. 5.66....0042.00.. © double dots on left...11 © (see …ratrep„).¯0.11..0.1234.. © error (no repeated string to left of "..").bad number© Perhaps the following sequence will make you pause before© dismissing Euler's preposterous claim (see …ratrep„).279


¯11000000000..99 © (see note above)0.99.. © (see note above)..99 0.99.. © ¯1 + 1 … 0..99.99.. © .. ....33.33.. ..33.33.. ..33..33.. © 3 × ..33.33.. … ..99.99.. … 0..33.33.. © 0=3×¾ implies ¾=0..11.11.. ..11.11.. ..11.11.. © 3 × ..11.11.. … ..33.33.. … 0..11.11.. © 0=3×¾ implies ¾=0..0101.0101.. © the sum of 11 of these gives ..1111.1111....001001.001001.. © the sum of 111 of these gives ....123123.123123.. © 0=123×¾ implies ¾=0©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©© Balanced Ternary{-0+} © change base to balanced ternary. See also …bt„+--+ +-+- © balanced ternary: 16 + 20 … 36++00+--+ + + + + © balanced ternary 5.0.++.. +.--.. © two representations of one-half.+..-- © ... and a third, perhaps less obvious, one.0.++..©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©© Hexadecimal{0123456789abcdef}3e8 7d0 bb8 fa02710© change base to hexadecimal.© sum of four hex numbers.1e83e8 ¯200© sum with explicit negative sign.ffffffff 000003e81000003e7© ffffffff is ¯1+2*323e7..ffffff 000003e8© ..ffffff is ¯119d9c ¯deadbeef¯baad ¯3560¯f00d¯2..ffe©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©© Pos-skewed four280


{-0+#} © change base to pos-skewed four (# is double-plus).+--+# # # # # + © 11 (2+2+2+2+2+1) … (4ƒ1 ¯1 ¯1)0.# 0.# © one-half plus one-half©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©© Neg-skewed four{=-0+} © change base to neg-skewed four (= is double-minus).+==++ + + + + + © 6 (1+1+1+1+1+1) … (4ƒ1 ¯2 ¯2)+.= +.= © one-half plus one-half) © quit.See also: ratsum.308 ratrep.556 bt.258 loop.550ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎfactorialnum „ ##.factorial num© Tail recursive factorial.An illustration of tail recursion with a left argument accumulator. Note thatthis function is intended only as an illustration of a coding technique. The recommendedway of producing a factorial in <strong>APL</strong> is to use primitive function: _!_.Example:factorial¨¼101 2 6 24 120 720 5040 40320 362880 3628800See also: fibonacci.279ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎfibonaccinvec „ ##.fibonacci num© Tail-recursive Fibonacci.© Leonardo Fibonacci 1170-1250.An illustration of tail recursion with a left argument accumulator:fibonacci„{ © Tail-recursive Fibonacci.¸„0 1¾=0:«½¸(1‡¸,+/¸)’ ¾-1}Compare this coding with the naïve stack-recursive version:fib„{¾¹0 1:¾+/’¨¾-1 2}Some alternatives:Nick Nickolov and Jay Foad suggest:fib „ {œ(+/,œ)ÿ¾€1}and:fib „ {+/!°²þ¼¾}281


John R. Clark suggests these non-recursive <strong>functions</strong>:fib „ {+/{¾!²¾}(¼¾)-Œio}andfib „ {1‡–((3×¾)½'²+\'),'1 0'}© JRC[1]© JRC[2]JRC[1] may be cast as a derived function, using monadic commute:fib „ +/°(!°²þ)°(-°Œio)°¼© see …derive„and JRC[2] may be converted to use the primitive power operator:fib „ {«½²°(+\)ÿ¾,0 1}© ÿ is primitive power operator.or the equivalent derived function, using reduction for power (see …pow„):fib „ «°½°œ°(€°²°(+\)/)°(,°(›0 1))°¼In a similar way, power can be applied on the following matrix multiplication:|1 1| |A B| |A+C B+D||1 0| × |C D| = | A B |to obtain a terse but costly fib function:fib „ {œ(+.×ÿ¾)þ2 2½1 1 1 0}Another simple way is to perform a "hidden scan" with a reduction (see …scan„):fib „ {œ{¾,+/¯2†¾}/¾½1}The following function illustrates the relationship between the Fibonacci sequenceand rational approximations to the "golden mean" (Phi). See …phinary„.fib„{1^+°÷/0,¾/1}Û Û ÀÎÎÎÎÎ continued fraction: 0 1 1 1 ...Û ÀÎÎÎÎÎÎÎÎÎ approximation to Phi-1: 0 1 0.5 0.666 ...ÀÎÎÎÎÎÎÎÎÎÎÎ numerator of rational: 0 1 1 2 3 5 8 13 21 34 ...Dick Bowman reminds us of Binet's formula, which also uses Phi:fib „ {((phi*¾)-(1-phi„.5×1+5*.5)*¾)÷5*.5}Peter-Michael Hager suggests this pleasantly symmetrical coding of Binet's formula:fib„{p„0.5×1+5*0.5q„0.5×1-5*0.5((p*¾)-q*¾)÷p-q}In the above, constants p and q could be pre-evaluated and bound as the left andright operands of a dyadic operator:or:fib „ (0.5×1+5*0.5) {((¸¸*¾)-¾¾*¾)÷¸¸-¾¾} (0.5×1-5*0.5)fib „ (0.5×1+1 ¯1×5*0.5)°{(-š¸°.*¾)÷-/¸}As Binet's formula employs only scalar <strong>functions</strong>, it may be applied to an arrayargument. Using the above definition:282


fib (0 1 2)(2 2½2+¼4)0 1 1 2 35 8Jane Sullivan extends Binet's formula to the real and complex domains. A D-codindof Jane's real-valued function might look like this:fib„{z„0.5×1+s„5*0.5((z*¾)-(2±±¾)×z*-¾)÷s}© SullivanRef: Sullivan J. "Functional Extensions to the Fibonacci Sequence", Vector 15.4.Note that Jane's function is defined for negative arguments:Œpp„3 ª fib ¯5 ¯4.5 to 5 © fib ¯5 ¯4.5 .. 55 0.0513 ¯3 0.083 2 0.134 ¯1 0.217 1 0.352 0 0.569 1 0.92 1 1.49 2 2.41 3 3.9 5Veli-Matti Jantunen suggests this coding for large Fibonacci numbers, eg >10000.fib„{Œml„3¾ˆ2:1}{(+/^\¾='0')‡¾},'ZI9'Œfmt(¾-2){¸>0:(¸-1)’(†²¾)({^/¾


vec„{ © ¸ is accumulator.n(i j)„¾ © remaining number and current fib pair.i=0:¸,1© exhausted radix list: accumulator, sentinel.f„(j-i),i © next fib pair.t„n‰j© next term andr„n-t×j © remainder.(t,¸)’ r f © accumulated fib-coding.} © :: [b] „ [b] ’ n(i j)}« vec ¾,›¾ pair 0 1 © fi†•°fibcode¨0 to 10 © fibonacci coding of 0..1011 10 1 10 0 1 11 0 1 10 0 0 1 11 0 0 1 10 1 0 1 10 0 0 0 1 11 0 0 0 1 10 1 0 0 1 1See: http://en.wikipedia.org/wiki/Fibonacci_codingExample:fibonacci¨¼101 1 2 3 5 8 13 21 34 55fibonacci¨ 0 to 90 1 1 2 3 5 8 13 21 34© Œio=1: F1 .. F10© first 10 Fibonacci numbers: F0 ..F9.© compare monitor of tail-recursive version:fibonacci mdf 200 fibonacci„{ © Tail-recursive Fibonacci.21 ¸„0 121 ¾=0:«½¸20 (1‡¸,+/¸)’ ¾-10 }© ... with monitor of stack-recursive version:fib mdf 200 fib„{21891 ¾¹0 1:¾10945 +/’¨¾-1 20 }See also: factorial.279 mdf.501 pow.218 to.316 cfract.266 derive.535 nats.290See also: phinary.341 ratrep.556 ratsum.308ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎfactorsnvec „ ##.factors numb© Prime factors of ¾[factors] takes an integer scalar argument and returns a vector of ascendingprime numbers whose product is ¾.284


The stages in the process are:1. Sequence: (2 .. ¾*÷2),¾ must contain all but at most one factor.2. Extract those that divide ¾ exactly.3. Sieve out any multiples leaving only primes.4. For each prime factor, replicate those powers that divide ¾.5. Append single factor greater than ¾*÷2, if there is one.One weakness of this approach is that the vector generated in step 1 uses a lotof workspace, and will cause a WS FULL if ¾ is more than about (Œwa*2)÷2*8. Forexample, to extract the factors of a 10-digit phone number, we need around amegabyte and a half of available workspace.VMJ suggests that the initial sequence: (2 3 4 5 6 7 .. ¾*÷2) be replaced by thesparser: (2,3 5 7 .. ¾*÷2). This reduces both execution time and memory usage bya factor of around 2. In other words, the naïve coding:}(1‡¼˜¾*÷2),¾© 2 .. sqrt(¾),¾is replaced with:}2,(1+2×¼˜0.5×¾*÷2)© 2,3 5 .. sqrt(¾),¾The code could have been written as a series of assignments to local variables:seq0„2,(1+2×¼˜0.5×¾*÷2) © 2,3 5 .. sqrt(¾),¾seq1„(0=seq0|¾)/seq0 © divisors of ¾ in:···However, the large amount of workspace used for the first result would then haveendured for the rest of the process. The approach taken here of using a "pipeline"of <strong>functions</strong>:}{}{}{······... ensures that intermediate results are released as soon as possible.Examples:factors +4412568300302 3 3 5 71 73 945949factors +441256830031587 9007 83459© <strong>Dyalog</strong> phone number factors.© <strong>Dyalog</strong> fax number factors.factors 4294967297 © 5th Fermat number, factored by Euler 1732.641 6700417{¾­factors×/¾}sieve 2 to 30 © Factors of product of primes.12 3 5{¸­žfactors×/¸*¾}4 5 6 © Unique factors of product of prime powers.1factors Œrl © Initial Œrl is 7*5.7 7 7 7 7See also: pco.296 gcd.284 sieve.315 rational.298 cfract.266 nats.290 rats.302285


ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎgcdnum „ num ##.gcd num© Greatest Common Divisor.© Euclid ¯330-¯275.An illustration of tail recursion.gcd„{¾=0:|¸¾ ’ ¾|¸}© Greatest common divisor.NB: This function is for illustrative purposes only; GCD and LCM are primitive<strong>functions</strong> Ÿ and ^.Wikipedia says: "The original algorithm as described by Euclid treated it as ageometric problem, and hence used repeated subtraction of the smaller numberfrom the larger number rather than integer division ... which is considerablyless efficient than ... (using residue)."Ref: http://en.wikipedia.org/wiki/Euclidean_algorithmEuclid might have coded something like the following, which works for positivearguments:gcd„{¸¾: ¾ ’ ¸-¾¸=¾: ¸}© Euclid's algorithm.© ... using repeated© ... subtraction.Binary GCD----------This algorithm, which takes a pair of non-negative whole (unsigned integer)numbers as argument, is suitable for implementing GCD in a low-level compiled orassembly language. In such languages, 2|¾ and ¸÷2 are fast operations.bgcd„{© Binary gcd.0¹¾:+/¾ © either is 0: m ? m : n0 0­2|¾:2×’ ¾÷2 © even even: (’ (m >> 1) (n >> 1)) > 1) n1 0­2|¾:’ ¾÷1 2 © odd even: ’ m (n >> 1)ˆ/¾:’(-\¾)÷1 ¯2 © odd odd: mˆn: ’ m (n-m >> 1)’(²-\²¾)÷¯2 1 © odd odd: m>n: ’ (m-n >> 1) n}15bgcd 105 330© takes a pair of non-negative whole numbers.Ref: http://en.wikipedia.org/wiki/Binary_gcdArray GCD---------We can modify the coding slightly to find the GCDs of conformable (possiblynested) arrays in parallel:gcds„{¸­¸+¸:|¾(¸˜¾)’(¸˜¾)|¸—¾}© Array-GCD.© all 0s: done.© min ’ min | max.Œ„pvec„sieve 2 to 80 © primes 2..802 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79Œ„tvec„×/¨3,/pvec© products of consecutive triples.30 105 385 1001 2431 4199 7429 12673 20677 33263 47027 65231 82861 107113 146969286


Œ„ll rr„4 5°½¨0 ¯1²¨›tvec © matrices of adjacent triple products.30 105 385 1001 2431 409457 30 105 385 10014199 7429 12673 20677 33263 2431 4199 7429 12673 2067747027 65231 82861 107113 146969 33263 47027 65231 82861 107113190747 241133 290177 347261 409457 146969 190747 241133 290177 347261ll gcd¨rr1 15 35 77 143221 323 437 667 8991147 1517 1763 2021 24913127 3599 4087 4757 5183ll gcds rr1 15 35 77 143221 323 437 667 8991147 1517 1763 2021 24913127 3599 4087 4757 5183© GCDs using each.© parallel GCDs.cmpx'll gcd¨rr' 'll gcds rr' © timing comparison: parallel is faster.ll gcd¨rr 1.2E¯4 0% ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒll gcds rr 5.2E¯5 -56% ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒdisp (‡ll) gcds ‡rr© nested GCDs.Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÛ1 15 35 77 143Û221 323 437 667 899Û1147 1517 1763 2021 2491Û3127 3599 4087 4757À~ÎÎÎÎÎÎÎÎÎÎÎÎ…Á~ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…Á~ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…Á~ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎA better version for non-integral arguments-------------------------------------------Euclid's algorithm works well for whole-number arguments but gives poor resultsfor floating-point numbers. We can generalise Euclid to …rational„ arguments bynoting that:(A÷B) gcd (C÷D) ­­ (A gcd C) ÷ (B lcm D)where lcm is least-common-multiple. The following code does the trick:then:ggcd„{© General gcd.(a b)(c d)„rational¨¸ ¾ © rational approximations.lcm„{¸×¾÷¸ gcd ¾}© least common multiple.(a gcd c)÷b lcm d © (see notes.rats).}(1 to 11) ggcd¨ 0.111 © Gianluigi Quario's example.0.001 0.001 0.003 0.001 0.001 0.003 0.001 0.001 0.003 0.001 0.001Examples:155 7105 gcd 330factors (3×5×7) gcd 5×7×11lcm„{¸×¾÷¸ gcd ¾}© least common multiplefactors (3×5×7) lcm 5×7×113 5 7 11simple„{¾÷gcd/¾}© simplest fraction.2 3simple 24 36 © simplify: 24/36 … 2/3.See also: sieve.315 factors.282 nats.290 rats.302 rational.298287


ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎk6174seq „ ##.k6174 nnnn© Kaprekar's operation.Take any 4-digit number in which not all of the digits are the same. Re-arrangethe digits into descending and ascending order and subtract. Repeat.In 1949 D.R.Kaprekar pointed out that this sequence always results in an infiniterepetition of the number 6174.For example:1223 … 3221 - 1223… 1998 … 9981 - 1899… 8082 … 8820 - 0288… 8532 … 8532 - 2358… 6174 … 7641 - 1467… 6174 … ...Ref: http://en.wikipedia.org/wiki/KaprekarExamples:†{1‡•1e4+¾}¨°k6174¨ ¼20© First 20 Kaprekar sequences.0001 0999 8991 8082 8532 61740002 1998 8082 8532 61740003 2997 7173 6354 3087 8352 61740004 3996 6264 4176 61740005 4995 5355 1998 8082 8532 61740006 5994 5355 1998 8082 8532 61740007 6993 6264 4176 61740008 7992 7173 6354 3087 8352 61740009 8991 8082 8532 61740010 0999 8991 8082 8532 61740011 1089 9621 8352 61740012 2088 8532 61740013 3087 8352 61740014 4086 8172 7443 3996 6264 4176 61740015 5085 7992 7173 6354 3087 8352 61740016 6084 8172 7443 3996 6264 4176 61740017 7083 8352 61740018 8082 8532 61740019 9081 9621 8352 61740020 1998 8082 8532 6174© The following expression shows, of all 9990 possibilities, the number of© sequences of lengths 1 2 .. 8:{+š¾°.=¼—/¾} œ°½°k6174¨ (¼9999)~1111×¼91 383 576 2400 1272 1518 1656 2184© histogram.See also: osc.296ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎhexcvex „ {width} ##.hex nums © Hexadecimal from decimal.nums „ {signed„0} ##.dec cvex© Decimal from hexadecimal.[hex] and [dec] convert between arrays of decimal numbers and their hexadecimalequivalents.Hex's optional left argument {width} specifies the number of hexadecimal digitsrequired. Width defaults to 2, 4, 8 or 16 depending on the magnitude of the argument.288


Dec's optional left argument {signed} determines whether a hexadecimal numberwhose first digit is in the range 8..f is to be interpreted as a signed or unsigned(default) number.Restriction: [hex] will not accept numbers whose magnitude means that adding 1will make no difference. This means a maximum of around 2*53 for a number ofŒDR-type 645.Examples:disp hex 12 34 56Ú…ÎÂÎÎÂÎÎÌÛ0cÛ22Û38ÛÀÎ…ÁÎ…ÁÎ…Ùhex 100×¼60064 00c8 012c 0190 01f4 0258hex 100000×¼4000186a0 00030d40 000493e0 00061a80hex 4 5½¼2001 02 03 04 0506 07 08 09 0a0b 0c 0d 0e 0f10 11 12 13 14© (result is nested).© larger numbers.© even larger numbers.© array of numbers.4 hex 4 5½¼20 © specify width.0001 0002 0003 0004 00050006 0007 0008 0009 000a000b 000c 000d 000e 000f0010 0011 0012 0013 0014dec'3e8'© convert to decimal.1000dec'3E8' © upper case A-Z is OK, too.1000dec hex 2 4 5½¼40 © convert both ways.1 2 3 4 56 7 8 9 1011 12 13 14 1516 17 18 19 2021 22 23 24 2526 27 28 29 3031 32 33 34 3536 37 38 39 40disp hex saw(1 2 3)(100 200 300)Ú…ÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛÚ…ÎÂÎÎÂÎÎÌÛÚ…ÎÎÎÂÎÎÎÎÂÎÎÎÎÌÛÛÛ01Û02Û03ÛÛÛ0064Û00c8Û012cÛÛÛÀÎ…ÁÎ…ÁÎ…ÙÛÀÎÎÎ…ÁÎÎÎ…ÁÎÎÎ…ÙÛÀÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…Ùdec hex (1 2 3)(100 200 300)1 2 3 100 200 300© nested array.© full circle.© hex of negative integers returns 2's complement or "unsigned" hex number:hex ¯3 to 3fd fe ff 00 01 02 03© hex of negative numbers.1 dec hex ¯3 to 3 © round trip if signed.¯3 ¯2 ¯1 0 1 2 3289


0 dec hex ¯3 to 3 © non-round trip if unsigned.253 254 255 0 1 2 3hex 2*53© number too big.Too bighex 2*53^See also: int.289 saw.78 hexf.288See also: ary.317 phinary.341 bt.258ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎhexfhex „ ##.hexf num© IEEE 754/854 binary floating point.num „ ##.hexf hexConverts between numbers and character vectors of their IEEE 754-2008 and 854-2008 double-precision binary floating-point representation.The hexadecimal character vector is in big-endian format with the sign and exponentin the left-most 12 bits.hexf 3 © sign 0, exponent 400, (elided 1) mantissa binary 10000 ...40080000000000003hexf hexf 3© (round-trip).Hexf accomodates arrays of any rank and depth.NB: This coding of hexf subsumes function "decf", which has been withdrawn.NB: With code from Jay Foad, this version includes support for 128-bit DecimalFloating point.See: http://en.wikipedia.org/wiki/IEEE_754-2008 for details.Examples:nmat„÷2 3½¼6nmat1 0.5 0.33333333330.25 0.2 0.1666666667© simple numeric array.© display of array.hexf nmat© hex display of floating array.3FF0000000000000 3FE0000000000000 3FD55555555555553FD0000000000000 3FC999999999999A 3FC55555555555551nmat ­ hexf hexf nmat© check round-trip.© From <strong>Dyalog</strong> V13:ŒFR„1287 © Decimal Floating Point IEEE 854hexf ±1© Pi as 128-bit decimal floating-point.2DFFCC1AEB53B3FBB4E262D0DAB5E683See also: hex.286290


ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎinti „ bits ##.int u© Signed from unsigned integers.u „ bits ##.uns i© Unsigned from signed integers.These little <strong>functions</strong> "cast" between signed and unsigned integers. This issometimes useful when dealing with native files. Note that as all of the primitive<strong>functions</strong> used in the coding are pervasive, they-just-work on arrays ofhigher rank and depth.Technical notes:For 8-bit (type 83) integers, the <strong>functions</strong> may be simplified to:uns„{256|¾}int„{¯128+256|128+¾}© unsigned from signed byte.© signed from unsigned byte.and for 16-bit short (type 163) integers, to:uns„{65536|¾}int„{¯32768+65536|32768+¾}© unsigned from 16-bit signed.© signed from 16-bit unsigned.Thus, in general we have:uns„{(2*¸)|¾}int„{†¾{(¸|¾+¸¸)-¾}/2*¸-0 1}© unsigned from ¸-bit signed.© signed from ¸-bit unsigned.Examples:8 uns ¯3 to 3 © 8-bit unsigned.253 254 255 0 1 2 316 uns ¯3 to 3 © 16-bit unsigned.65533 65534 65535 0 1 2 312 uns ¯3 to 3 © 12-bit unsigned.4093 4094 4095 0 1 2 38 int 8 uns ¯3 to 3 © 8-bit round trip.¯3 ¯2 ¯1 0 1 2 316 int 16 uns ¯3 to 3 © 16-bit round trip.¯3 ¯2 ¯1 0 1 2 312 int 12 uns ¯3 to 3 © 12-bit round trip.¯3 ¯2 ¯1 0 1 2 34 hex 16 uns ¯3 to 3 © hex of uns ...fffd fffe ffff 0000 0001 0002 00034 hex ¯3 to 3 © ... same as hex of int.fffd fffe ffff 0000 0001 0002 0003disp 8 uns 8 int 2 3 4½256-¼24255 254 253 252251 250 249 248247 246 245 244© ok for higher rank arrays.243 242 241 240239 238 237 236235 234 233 232291


disp 8 int 8 uns †,°›/-¼5 © ok for nested arrays.Ú…ÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ ÛÚ…ÎÂÎÎÎÎÎÎÎÎÎÎÌÛÛ ÛÛ ÛÚ…ÎÂÎÎÎÎÎÌÛÛÛ¯1ÛÛ¯2ÛÛ¯3Û¯4 ¯5ÛÛÛÛ ÛÛ ÛÀ~ÎÁ~ÎÎÎ…ÙÛÛÛ ÛÀ~ÎÁÎÎÎÎÎÎÎÎÎ…ÙÛÀ~ÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÙSee also: hex.286ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎnatscvec „ larg (fn ##.nats) rarg© Natural number arithmetic.Nats applies its operand function between natural (non-negative, whole) numberarguments. The operand may be one of:+ sum- difference× product÷ quotient* exponent˜ min— max| residueŸ greatest common divisor^ least common multiple¬ relationalArguments [larg] and [rarg] are typically vectors of characters '0'-'9' but maybe numeric for (natural) numbers with no more than ŒPP digits.NB: [nats] deals only in single (scalar) numbers, rather than whole arrays.The result is a character vector of decimal digits.1234567890 ×nats '12345678901234567890'15241578751714678875019052100[nats] is similar to operator …big„ except that it:- deals only in non-negative numbers,- accepts only dyadic operand <strong>functions</strong>,- is quicker for large numbers.Operand (-) takes the "elementary school" approach of returning 0 if the minuendis smaller than the subtrahend (larg


Gianluigi Quario comments that it is difficult to enter large-magnitude numbers:456 +nats 123E20 © raw E-notation won't work.Bad number: 1.23E22456+nats 1.23E22^456 +nats '12300000000000000000000' © this works but is ungainly.12300000000000000000456456+nats 123×nats 10*nats 2012300000000000000000456© OK but inconvenient.Gianluigi suggests this function:pfmt„{ŒIO ŒML ŒPP„0 0 16© plain format of a numeric scalar.rep„•¾¾­rep:¾~'E'¹rep:repexp„–(1+rep¼'E')‡rep0>exp:'_ '~þ(ŒPP-exp)•¾sig„'¯'=œrepman„ŒPP†'.'~þ(sig‡(rep¼'E')†rep),ŒPP½'0' © mantissa(sig½'¯'),(1+exp)†man,exp½'0'}Then:456 +nats pfmt 123E2012300000000000000000456456 +nats pfmt 1.23E2212300000000000000000456Technical notes:Performance benefits from representing the numbers internally in a fairly largebase (radix). However, if too large a base is chosen, intermediate results runthe risk of exceeding the 53-bit precision of IEEE floating point arithmetic andso losing accuracy. A base of 10*6 seems optimal. A power of 10 base is chosento simplify conversion to and from internal format.Product-------Roger Hui points out that however small a base we choose, the product of sufficientlylong vectors of digits will cause 53-bit overflow. To avoid this loss ofprecision, inner function "mul" tests the lengths of its arguments and, if necessary,splits them into sub-products of shorter vectors. If ¸ and ¾ are vectorsof radix-rx digits, and + and × are vector sum and product respectively, then:¯ ¯¸ × ¾ „… ((¸ × s†¾),s‡¾½0) + ¸ × s‡¾¯ ¯ ¯ ¯For example, suppose a 7-digit product were enough to cause overflow. We couldavoid the overflow by splitting the product into the sum of a 3-digit and a 4-digit product, like so:1 2 × 3 4 5 6 7 8 9 „… ((1 2 × 3 4 5),0 0 0 0) + 1 2 × 6 7 8 9¯ ÀÎÎÎÎÎ7ÎÎÎÎÎÙ ¯ ÀÎ3ÎÙ ¯ ¯ ÀÎÎ4ÎÎÙAs a test case, Roger observes that the square of natural number ¾/'9' is(¾ 2 ¾ 2-1)/'9801':293


×natsþ'9'81×natsþ'99'9801×natsþ'999'998001×natsþ'99999999'9999999800000001With nat's radix of 10*6, the square of 999...9 is sufficent to require splitting:À60000Ù1(×natsþ6e4/'9')­(6e4 2 6e4 2-1)/'9801'© (takes around a minute).See …xtimes„ for a faster multi-digit product.Exponent--------For ¸*¾, we avoid calculating ¾ products ¸ × ¸ × ···, by using the recurrencerelation:ÀÎÎÎ ¾ ÎÎÎÙ¸*0 = 1¸*1 = ¸¸*¾ = (¸*2|¾) × {¾×¾} ¸*˜¾÷2which needs only O(2µ¾) products.(muse:Notice in the examples below that */5/2 is a number with 19,729 decimal digits.An amusing way to distinguish mathematicians from computer programmersat a social gathering (perhaps a cocktail party or wedding reception) is tosing this little song (to the tune of "The Grand old Duke of York"):Two,Two-to-the-two,Two-to-the-two-to-the-two,Two-to-the-two-to-the-two-to-the-two,Two-to-the-two-to-the-two-to-the-two-to-the-two,...You will find that after six or seven lines, the mathematicians begin tolook bored, while the computer programmers turn pale and start to faint.)See also: staplesQuotient--------We use the traditional "high-school" long division method (invented by CharlesBabbage, see: eval.dws/notes.Long_division). A minor refinement is that, as theradix is large, it pays to do a binary, rather than linear search for the next"digit" of the result. With a radix of 10*6 (around 2*20), we can find the digitin about 20 comparisons when using (0, radix-1) as the lower and upper searchbounds.But we can do a little better. We take the two most significant digits of thedividend and divisor ((p0 p1 ···)(q0 q1 ···)) and decode each pair using theradix. This gives a pair of numbers (pp qq), each in the range 0,radix*2, whichis still well within our required 53-bit precision limit.To find a lower bound, we assume that all digits following p0 and p1 are 0 andthat all those following q0 and q1 are (radix-1). This gives a lower bound of(˜pp÷qq+1).294


Likewise, an upper bound assumes all digits following p0 and p1 are (radix-1)and all those following q0 and q1 are 0, giving a upper bound of (—(pp+1)÷qq).It makes things a little easier if we soften this upper bound very slightly byobserving that:( —¾) = ˜1+¾ © for non-integer ¾(1+—¾) = ˜1+¾ © for integer ¾so we can reasonably take an upper bound of: (˜1+(pp+1)÷qq).In other words, the lower-upper bound pair is (˜pp÷qq+1) (˜1+(pp+1)÷qq).Then, using expression transformation to simplify:(˜pp÷qq+1) (˜1+(pp+1)÷qq) © (˜¸)(˜¾) = ˜¸ ¾_¯¯= ˜(pp÷qq+1) (1+(pp+1)÷qq) © (0+¸)(1+¾) = 0 1+¸ ¾____ ¯¯= ˜0 1+(pp÷qq+1) ((pp+1)÷qq) © (¸÷¾)(¹÷½) = (¸ ¹)÷(¾ ½)¯¯= ˜0 1+(pp(pp+1))÷(qq+1)qq © ¸(¸+1) = ¸+0 1, if ¸ scalar.¯¯¯¯¯¯¯¯ ¯¯¯¯¯¯¯¯= ˜0 1+(pp+0 1) ÷ qq+1 0 © ¸÷¾ = †÷/¸ ¾¯= ˜0 1+†÷/(pp+0 1) (qq+1 0) © (¸+¾)(¹+½) = ¸ ¾+¹ ½¯ ¯= ˜0 1+†÷/pp qq+(0 1)(1 0) © thus (pp qq) can use a single name ppqq.Examples:Œd ×nats Œd © 123456789 * 2152415787501905212*nats 1024 © 2*1024179769313486231590772930519078902473361797697894230657273430081157732675805500963132708477322407536021120113879871393357658789768814416622492847430639474124377767893424865485276302219601246094119453082952085005768838150682342462881473913110540827237163350510684586298239947245938479716304835356329624224137216½†*nats/5/219729© */5/2 has 19,729 decimal digits.Œd *nats 8 © 123456789 * 853965948844821664748141453212125737955899777414752273389058576481†÷nats/Œd Œd *nats¨ 101 100123456789© test accuracy0 1{¾=0:œ¸ ª (1‡¸,+nats/¸)’ ¾-1}1000 © 1,000th Fibonacci number (JRC).43466557686937456435688527675040625802564660517371780402481729089536555417949051890403879840079255169295922593080322634775209689623239873322471161642996440906533187938298969649928516003704476137795166849228875factorial „ †°(×nats/)°¼ © !¾295


factorial 1000 © !1000402387260077093773543702433923003985719374864210714632543799910429938512398629020592044208486969404800479988610197196058631666872994808558901323829669944590997424504087073759918823627727188732519779505950995276120874975462497043601418278094646496291056393887437886487337119181045825783647849977012476632889835955735432513185323958463075557409114262417474349347553428646576611667797396668820291207379143853719588249808126867838374559731746136085379534524221586593201928090878297308431392844403281231558611036976801357304216168747609675871348312025478589320767169132448426236131412508780208000261683151027341827977704784635868170164365024153691398281264810213092761244896359928705114964975419909342221566832572080821333186116811553615836546984046708975602900950537616475847728421889679646244945160765353408198901385442487984959953319101723355556602139450399736280750137837615307127761926849034352625200015888535147331611702103968175921510907788019393178114194545257223865541461062892187960223838971476088506276862967146674697562911234082439208160153780889893964518263243671616762179168909779911903754031274622289988005195444414282012187361745992642956581746628302955570299024324153181617210465832036786906117260158783520751516284225540265170483304226143974286933061690897968482590125458327168226458066526769958652682272807075781391858178889652208164348344825993266043367660176999612831860788386150279465955131156552036093988180612138558600301435694527224206344631797460594682573103790084024432438465657245014402821885252470935190620929023136493273497565513958720559654228749774011413346962715422845862377387538230483865688976461927383814900140767310446640259899490222221765904339901886018566526485061799702356193897017860040811889729918311021171229845901641921068884387121855646124960798722908519296819372388642614839657382291123125024186649353143970137428531926649875337218940694281434118520158014123344828015051399694290153483077644569099073152433278288269864602789864321139083506217095002597389863554277196742822248757586765752344220207573630569498825087968928162753848863396909959826280956121450994871701244516461260379029309120889086942028510640182154399457156805941872748998094254742173582401063677404595741785160829230135358081840096996372524230560855903700624271243416909004153690105933983835777939410970027753472000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000binomial „ {(factorial ¾)÷nats(factorial ¸)×nats factorial ¾-¸}© ¸!¾1000 binomial 20002048151626989489714335162502980825044396424887981397033820382637671748186202083755828932994182610206201464766319998023692415481798004524792018047549769261578563012896634320647148511523952516512277685886115395462561479073786684641544445336176137700738556738145896300713065104559595144798887462063687185145518285511731662762536637730846829322553890497438594814317550307837964443708100851637248274627914170166198837648408435414308177859470377465651884755146807496946749238030331018187232980096685674585602525499101181135253534658887941966653674904511306110096311906270342502293155911108976733963991149120© Handy prefixes for the first few 2*10×¾:©prefs „ 'kilo' 'mega' 'giga' 'tera' 'peta' 'exa' 'zetta' 'yotta' '...'296


³†prefs{¸ ¾}2*nats¨ 10 20 to 200kilo 1024mega 1048576giga 1073741824tera 1099511627776peta 1125899906842624exa 1152921504606846976zetta 1180591620717411303424yotta 1208925819614629174706176... 123794003928538027489912422412676506002282294014967032053761298074214633706907132624082305024132922799578491587290380706028034457613611294676837538538534984297270728458241393796574908163946345982392040522594123776142724769270595988105828596944949513638274662414615016373309029182036848327162830196559325429761496577676626844588240573268701473812127674924007424153249554086588885835834702715030918361873912218360217615692754338466701909589473558019166040255888611160086282241606938044258990275541962092341162602522202993782792835301376See also: xtimes.350 xpower.350 big.257 gcd.284 rats.302 bt.258 adic.253See also: numbers.551ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎnicedivnvec „ p ##.nicediv q © ¾ similar integers with sum ¸.From Nicolas Delcros, this function distributes integer [p] nicely into [q] similarly-sizedpartitions.For example, in a GUI application, we might want to draw a grid of 5 rows and 7columns, which fits exactly in a rectangle of 211 by 437 pixels:disp 211 437 nicediv¨ 5 8Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ42 42 43 42 42Û55 54 55 55 54 55 54 55ÛÀ~ÎÎÎÎÎÎÎÎÎÎÎÎ…Á~ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÙThen:'MyGrid' ŒWS 'CellHeights' 'CellWidths' {¸ ¾}¨ 211 437 nicediv¨ 5 8Technical note:Phil Last provides this alternative coding:nicecdiv„{¯2-/0,˜0.5++\¾½¸÷¾}and adds: "(¯2-/0,) is, I believe, the proper inverse of (+\) so we could do(+\ÿ¯1) instead!nicediv„{+\ÿ¯1˜0.5++\¾½¸÷¾}which is neater but slower by about 25%".Examples:100 nicediv 7 © 7 similar integers, which sum to 100.14 15 14 14 14 15 14297


† (0 to 10)nicediv¨5 © 5-item rows sum to 0 .. 100 0 0 0 00 0 1 0 00 1 0 1 01 0 1 0 11 1 0 1 11 1 1 1 11 1 2 1 11 2 1 2 12 1 2 1 22 2 1 2 22 2 2 2 2hist„{' Œ'¦þ›Œio+´³¾°.‰¼—/¾}stacked„{´Œfmt´°hist¨¸ nicediv¨¾}© simple histogram.© ¸ bricks stacked nicely into ¾ columns100 stacked 12 23 39 © 100 bricks in various column-widths.Œ Œ Œ ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ Œ Œ Œ Œ Œ Œ Œ ŒŒŒŒŒŒŒŒŒŒŒŒŒ ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ Œ Œ Œ ŒŒ Œ Œ Œ ŒŒ Œ Œ ŒŒ Œ Œ Œ ŒŒ Œ Œ ŒŒŒŒŒŒŒŒŒŒŒŒŒ ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ12 stacked 3 to 9 © various stackings of 12 bricks.ŒŒŒŒŒŒ ŒŒŒŒ Œ ŒŒŒŒ ŒŒŒŒ ŒŒŒŒŒ ŒŒŒŒŒŒ Œ ŒŒŒ Œ Œ Œ Œ Œ Œ Œ ŒŒŒŒ ŒŒŒŒ ŒŒŒŒŒ ŒŒŒŒŒŒ ŒŒŒŒŒŒŒ ŒŒŒŒŒŒŒŒ ŒŒŒŒŒŒŒŒŒÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎoscnum „ ##.osc num © Oscillate - probably returns 1.This function expounded by L.Collatz in 1937, illustrates the "cleanness" of theD-function style. B.Thwaites (1996) has offered a £1,100 reward for proving thatit terminates for all ¾>0 and Paul Erdös commented: "Mathematics is not yetready for such problems."In "Gödel, Escher, Bach:", Douglas Hofstadter defines a natural number (n) to be"Wondrous" if (osc n) terminates. He points out that no-one has yet discoveredan "un-wondrous" number.This sequence is also known as the "Hailstone" or "3N+1" sequence.Example:osc¨¼40© (engineer's proof)1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1See also: k6174.286298


ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎpcop „ ##.pco ¾ © ¾-th prime © Prime numbers.b „ 0 ##.pco ¾ © 1 iff ¾ is not primeb „ 1 ##.pco ¾ © 1 iff ¾ is primen „ ¯1 ##.pco ¾ © number of primes less than ¾v „ 2 ##.pco ¾ © prime factors and exponentsv „ 3 ##.pco ¾ © prime factorization of ¾p „ 4 ##.pco ¾ © next prime larger than ¾p „ ¯4 ##.pco ¾ © next prime smaller than ¾b „ 10 ##.pco ¾ © m+b/¼½b are all the primes between m and n, where ¾­m,nFrom Roger Hui, [pco] "p-colon" models most of the p: function in J.Technical note:[pco] uses two large literal values:pitab„2 1299721 2750161 4256249 5800139 7368791 8960467 10570849 ...p4792„2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 ...which means that the canonical representation of the function is quite wide:½Œcr'pco'102 27335which may prove challenging for some workspace administration tools.Examples:pco Œio2pco 2 5½¼102 3 5 7 1113 17 19 23 29pco 123456719394489© the first prime© the first 10 primes in a 2 by 5 table© the 1234567-th prime¯1 pco 19394509 © the number of primes < 193945091234567¯1 pco 97 © # primes < 9724¯1 pco 97.5 © # primes < 97.525pco 24© the 24-th prime89¯1 pco ¯1+2*31 © # primes < ¯1+2*31105097564pco 1050975642147483647© the 105097564-th prime1 pco 314159 © is 314159 a prime?1{¾/¼½¾} 1 pco ¼25 © all the primes less than 252 3 5 7 11 13 17 19 231 0 10 pco 144 17 49 © which numbers are not prime?3 pco 144 © prime factorization2 2 2 2 3 3299


2 pco 144 © primes and exponents2 34 2« ­ 3 pco 1 © the prime factorization of 1 is empty14 pco 10*1 2 3 4 © the next prime > 10 100 ...11 101 1009 10007¯4 pco 10*1 2 3 4 © the next prime < 10 100 ...7 97 997 9973Œ„b„10 pco 10 20 © primes between 10 and 20.0 1 0 1 0 0 0 1 0 1b/10 to 19 © prime between 10 and 20.11 13 17 19See also: factors.282 sieve.315 rats.302 rational.298ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎrangeindx „ brks ##.range nums© Numeric range classification.Each item of the result shows to which sub-range within the left argument, thecorresponding item of the right argument belongs. Values below the first breakreport 0, and those above the upper break report ½¾. A value is judged withina sub-range if it is greater-or-equal to the lower bound and strictly less thanthe upper bound: ¸[i] ˆ ¾ < ¸[i+1].Range was supplied by Veli-Matti Jantunen.Examples:0 5 10 15 range ¯1 to 16 © integer ranges.0 1 1 1 1 1 2 2 2 2 2 3 3 3 3 3 4 4¯1 0 1 range 1±¼40© real number ranges.2 2 2 1 1 1 2 2 2 1 1 1 2 2 2 1 1 1 2 2 2 1 1 1 1 2 2 2 1 1 1 2 2 2 1 1 1 2 2 2(5 7 to 20)range 2 3 4½¼24 © higher rank right arg.0 0 0 01 1 2 23 3 4 45 5 6 67 7 8 88 8 8 8See also: to.316ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎrationalrats „ {tolerance„Œct} ##.rational nums © Rational approximation to real ¾.Argument [nums] is a numeric, possibly nested, array of shape S. The result isan array of shape: (2,S) with pairs of whole numbers, along the first axis, witha quotient which is ¸-tolerably close to the corresponding argument item.[rational] guarantees to return the smallest pair of such numbers. For example,if we choose pi (an irrational number) as argument, then with the default ŒCT of1e¯14, we see:rational ±15419351 1725033© tolerable rational approximation to pi300


1(±1) = ÷/ rational ±1 © quotient of pair is ŒCT-equal to argument.Œct„1e¯10© coarser tolerance.rational ±1208341 66317© coarser tolerance yields smaller pair.disp numbs „ +/¨1› 2 2 2½ +\10*-¼8Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ0.1 0.111 Û0.11 0.1111 ÛÛ0.11111 0.1111111‡0.111111 0.11111111‡À~ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…Á~ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…Ùdisp rational numbsÚ…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ̇ 1 111 Û 11 1111 ÛÛ 11111 1111111 ‡ 111111 11111111 ‡Ã~ÎÎÎÎÎÎÎÎÎÎÎÎÎ…Ï~ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÝÛ 10 1000Û 100 10000ÛÛ100000 10000000‡1000000 100000000‡À~ÎÎÎÎÎÎÎÎÎÎÎÎÎ…Á~ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…Ù© nested numeric array.© rational pairs.1numbs ­ ÷š rational numbs© round-tripThe integer pair could be reconstituted directly from the continued fractionreturned by function …cfract„. The inner reduction in the coding that follows,represents the expression transformation:···+1 ···+1 ···+1 ···+1 Ì ···+ Ú yz+1Î Î Î Î Û Û ÎÎÎÎÎÎÎÎÎ => ···x+1 x+1 Ì Ú x+z Ì Ú x(yz+1)+z ÃÎÎÎ…ÎÎÝ x(yz+1)+zÎ Î ÃÎ…ÎÝ ÎÎÎÎ ÃÎ…ÎÝ ÎÎÎÎÎÎÎÎÎ Û ÀÚ y+1 Ì Ú yz+1 Û À yz+1 Ù À yz+1 ÙÛ Î ÃÎ…ÎÝ ÎÎÎÎ ÛÀ z Ù À z Ùrational„{© Rational approximation from continued fraction.²†{ © reversed accumulation of,top bot„¾ © tailmost,²top 0+¸ 1×bot © fractions.}/(cfract ¾),1 © continued fraction representation.}or the equivalent one-liner:rational„{²†{†¸{²¸ 0+¸¸ 1×¾}/¾}/(cfract ¾),›1 1}For amusement, [rational] could be recast as a derived function, although it'shard to see a practical benefit of doing so:rational „ †°(÷°›°(1°Ÿ)þ°(1°(,þ°›))þ)© derived fn (Œml=0)Historical note---------------Prior to the implementation of primitive function GCD (Ÿ) this more complex coding,which was slower by a factor of around 2, was used:301


ational„{ © Rational number near real ¾.¸„ŒCT ª ŒCT„¸© default comparison tolerance.real„¾© "real" number.real{© starting with real number.An„˜¸© nth term of continued fraction.Cn„1 An+.×¾© nth convergent pair.real=÷/Cn:Cn © tolerably close rational: done.(÷¸-An)’ 1 0‡¾®Cn © otherwise: next term.}2 2½0 1 1 0 © convergents: C¯2, C¯1.}A Perfectly Accurate (Œct-intolerant) Version---------------------------------------------If we ignore comparison tolerance, all IEEE floating point numbers are rational,with a denominator of a power of 2 (yeah?).Using …hexf„, this version decodes the bits from the internal IEEE double floating-pointrepresentation and uses …nats„ to provide a perfectly (ŒCT=0) accuraterational pair. The two-item result is a pair of character vectors of decimaldigits.ratf„{ŒIO ŒML ŒCT„0© Exact rational from IEEE double.digs„16†ŒD,ŒA© hex digits.bits„,³2 2 2 2‚digs¼hexf ¾ © binary floating number.split„(¼½bits)¹0 1 12© split fields: sign exponent mantissa.bsign bexp bmant„split›bits © bit-vector fields.sign„bsign/'¯'© negative sign.exp„¯1022+2ƒbexp© signed numeric binary exponent.deco„{†¸{¸+nats ¸¸×nats ¾}/²¾} © accurate ¸-decode.top„2 deco 1,bmant© numerator.bot„2*nats 53-exp© denominator.sign '',¨top{© rational pair, char vectors à la nats.1¹'13579'¹,†¯1†¨¸ ¾:¸ ¾ © either number is odd: done.(¸÷nats 2)’ ¾÷nats 2 © both even: cancel 2s.}bot}Notice that some friendly decimal numbers such as 0.1 are not representable withperfect accuracy in binary. This means that the closest number to 0.1 that maybe represented in 53 bits, is the rational number:0.13602879701896397 ÷ 36028797018963968disp ratf 1234Ú…ÎÎÎÂÎÌÛ1234Û1ÛÀÎÎÎ…Á…Ùdisp ratf 0.1Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ3602879701896397Û36028797018963968ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…Ùdisp ratf 2*¯16Ú…ÂÎÎÎÎÎÌÛ1Û65536ÛÀ…ÁÎÎÎÎ…Ùdisp ratf ¯0.75Ú…ÎÂÎÌÛ¯3Û4ÛÀÎ…Á…Ù© whole number.© ÷10 is not a finite binary number.© reciprocal of power of 2 is spot-on.© negative sign fixed to numerator.302


Notice that the denominator of the rational pair returned by ratf is always aninteger power of 2.Ref: http://en.wikipedia.org/wiki/Continued_fractionExamples:rational 0.75© three quarters.3 4rational ÷3 © one third.1 3rational ¯0.1234¯617 5000© negative real => negative numerator.0 1rational 0© 0 => 0÷1 (this is handy for …cfract„).1e¯10 rational 2*÷2114243 80782Œ„pi„rational ±15419351 1725033© coarse rational approximation to sqrt(2).© tolerable approxmiation to pi.(±1)=÷/pi© ... compares within Œct.1gcd/pi© pair is relatively prime.1gcd/Œ„rational 9÷16 © pair of relatively prime numbers:9 161rational 11÷29 © pair matches rational of quotient ...11 29© ... for all relatively prime pairs:{¾­rational÷/¾}¨ °.,þ sieve 2 to 1000 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 11 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 11 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 11 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 11 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 11 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 11 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 11 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 11 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 11 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 11 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 11 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 11 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 11 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 11 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 11 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 11 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 11 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 11 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 11 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 11 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 11 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 11 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 11 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 11 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0303


³ rational +°÷\ cfract ±1 © successive rational approximations to Pi.3 122 7333 106355 113103993 33102104348 33215208341 66317312689 99532833719 2653811146408 3649135419351 1725033© Looking at the third row above, we see that if we divide the number-of-the-© beast (666) by the NYC area code (212) we get a reasonable appoximation to Pi.See also: factors.282 sieve.315 gcd.284 cfract.266 efract.274 pco.296See also: hexf.288 nats.290See also: numbers.551ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎratsrslt „ {larg} (fn ##.rats) rarg© Rational arithmetic.rslt „ (land ##.rats) rarg © Rational number.[rats] provides accurate conversion and arithmetic for non-negative rationalnumbers.NB: [rats] deals only in single (scalar) numbers, rather than whole arrays.Called with a natural number left operand, rats converts [land] and [rarg] to aninternal form.r „ 16 rats 9 © internal form of rational number 16r9.s „ 1 rats 2 © .. .. .. .. 1r2.Otherwise, the operand is a function chosen from monadic • or –:rfmt „ •ratsreal „ –ratsrfmt¨ r s16r9 1r2real¨ r s1.7778 0.5© • r-format.© – approx real equivalent.© r-format of rational numbers.© approx real equivalent of rational numbers.or from one of the dyadic <strong>functions</strong> + - × ÷ * Ÿ ^:rfmt r +rats s41r18© + sum of rational numbers 16r9 + 1r2rfmt r -rats s © - difference · · · 16r9 - 1r223r188r9rfmt r ×rats s © × product · · · · 16r9 × 1r2rfmt r ÷rats s © ÷ quotient · · · 16r9 ÷ 1r232r94r3rfmt r *rats s © * power · · · 16r9 * 1r2304


fmt r Ÿrats s © Ÿ gcd · · · · · 16r9 Ÿ 1r21r18rfmt r ^rats s © ^ lcm · · · · · 16r9 ^ 1r216r1[rats] assumes the presence of function …factors„, which it calls when it needsto determine the prime factors of an argument. In practice, this happens relativelyinfrequently.Technical notes---------------A rational number ¸r¾ is conveniently represented as a pair [P Q] of vectors ofprime factors and corresponding powers. Within [rats] these vectors are storedas a 2-row simple integer matrix.For example: the rational number 28r75 has P­(2 7 3 5) and Q­(2 1 ¯1 ¯2):28 rats 75 © internal form of 28r75.2 7 3 52 1 ¯1 ¯2Positive powers contribute to the numerator and negative ones to the denominator.The approximate real equivalent of [P Q] is thus: P×.*Q.28÷75 © approx real 28r750.37333×/*š 28 rats 75 © .. ..0.37333This representation makes arithmetic particularly straightforward. Almost alloperations are expressed in terms of factor matrices and even sums and differencesare applied only to what remains after common factors have been removed.This means that the relatively expensive factoring of large numbers into primesis reduced to a minimum.Normal Form-----------Subfunction [norm] normalises its argument by collecting like factors and summingtheir powers. The sum of powers with differing signs is equivalent to thecancelling operation, when dealing with fractions.In addition, [norm] removes factors-of-power-0, and powers-of-factor-1. Thismeans that the structure for rational number 1r1 is a 0-column matrix:ڴ̇0ÛÛ0ÛÀ~Ùdisplay 1 rats 1© 1r1 - 0-column matrix.Finally, as 0r1, 0r2, ·· 0r are equivalent, [norm] chooses 0r1.NB: [norm] does not arrange factor-power columns in any particular order, so thefollowing are equivalent normal forms:disp r35 r53Ú…ÎÎÂÎÎÎÌÛ3 5Û5 3ÛÛ1 1‡1 1‡À~Î…Á~Î…Ù•rats¨ r35 r5315r1 15r1© equivalent expressions of 15r1© r-formats are identical.305


Product ×---------The product of two rational structures is just the normalisation of their catenation!mul „ {norm ¸,¾} © ¸×¾ (¸ and ¾ are rational numbers).¯Quotient ÷----------The integer power of a rational number [P Q]*¾ = [P Q×1 ¾].orSo:expn „ {†1 ¾×‡¸} © ¸*¾ (¸ is rational, ¾ is integer).expn „ {1 ¾×[Œio]¸}© ... according to taste.disp (28 rats 75)°expn¨1 2 3 © 28r75 * 1 2 3Ú…ÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÌÛ2 7 3 5Û2 7 3 5Û2 7 3 5ÛÛ2 1 ¯1 ¯2‡4 2 ¯2 ¯4‡6 3 ¯3 ¯6‡À~ÎÎÎÎÎÎÎ…Á~ÎÎÎÎÎÎÎ…Á~ÎÎÎÎÎÎÎ…ÙIn particular, expn°¯1 returns the _reciprocal_ of its rational argument:disp {¾°expn¨1 ¯1} 28 rats 75Ú…ÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÌÛ2 7 3 5Û 2 7 3 5ÛÛ2 1 ¯1 ¯2‡¯2 ¯1 1 2‡À~ÎÎÎÎÎÎÎ…Á~ÎÎÎÎÎÎÎ…Ù© 28r75 * 1 ¯1so we can use expn to implement division:div „ {norm ¸,¾ expn ¯1} © ¸÷¾ (¸ and ¾ rational).¯Next, notice that function 0°— returns the (un-normalised) numerator:0°— 28 rats 75 © 28r12 7 3 52 1 0 028real 0°— 28 rats 75© 28r1and applied to the reciprocal, reveals the denominator:disp {0—¾°expn¨1 ¯1} 28 rats 75 © 28r75 … 28 75Ú…ÎÎÎÎÎÎÂÎÎÎÎÎÎÎÌÛ2 7 3 5Û2 7 3 5ÛÛ2 1 0 0‡0 0 1 2‡À~ÎÎÎÎÎ…Á~ÎÎÎÎÎ…Ùsepr „ {0—¾°expn¨1 ¯1}© separate numerator/denominator.real¨ sepr 28 rats 75 © round trip: (28 75) … 28r75 … (28 75)28 75306


Power *-------The _rational_ power of a rational number:·[P Q]*[R S] = [P X],where X = Q×R×.*S,as long as X­˜X,otherwise, error "irrational".·4r9 * 3r2 … 8r27·2r1 * 1r2 … irrational (square root of 2).GCD Ÿ / LCM ^---------------We can extract greatest-common-divisor and least-common-multiple directly fromthe factors of a pair of normalised rational numbers.If two _whole_ numbers have normal rational forms [P Q] and [R S] (which meansthat vectors Q and S have no negative items) then:[P Q] Ÿ [R S] = [PiR QnS], © Ÿ ----------------------gcd[1]¯where:PiR is the intersection of factor vectors P and R and¯¯¯¯¯¯¯¯¯¯¯¯QnS is the minimum of power vectors Q and S within the intersection.¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯and[P Q] ^ [R S] = [PuR QxS],¯where:© ^ ----------------------lcm[1]PuR is the union of factor vectors P and R and¯¯¯¯¯QxS is the maximum of power vectors Q and S within the union.¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯For example:2 3 51 2 12 3 72 1 12 31 190 rats 1 © [(2 3 5)(1 2 1)]84 rats 1 © [(2 3 7)(2 1 1)](90 rats 1)Ÿrats 84 rats 1 © gcd Ÿ: intersection / minimum.(90 rats 1)^rats 84 rats 1 © lcm ^: union / maximum.2 3 5 72 2 1 1Secondly, if a, b, c and d are whole numbers, then in general:(a÷b) Ÿ (c÷d) = (aŸc) ÷ (b^c)(a÷b) ^ (c÷d) = (a^c) ÷ (bŸc)© Ÿ ----------------------gcd[2]© ^ ----------------------lcm[2]Let —P Q] and ˜P Q] be notation for the numerator and denominator of [P Q]307


—P Q] = num „ {norm 0—¾} © numerator.˜P Q] = den „ {norm 0—¾ expn ¯1}© denominator.For example:if[P Q] = [(2 3 5 7)(¯1 2 1 ¯3)]then—P Q] = [(3 5)(2 1)]˜P Q] = [(2 7)(1 3)]and[P Q] = —P Q] × ˜P Q] * ¯1¯therefore:© numerator.© denominator.© numerator × ÷ denominator.[P Q] Ÿ [R S]¯—P Q] —R S] © defn of —...] and ˜...]=> ----- Ÿ -----˜P Q] ¯ ˜R S]—P Q]Ÿ—R S] © from gcd[2] above.=> -----------˜P Q]^˜R S][PiR QnS]=> ---------[PuR QxS]© from gcd[1] above.=> [PiR QnS], [PuR QxS] * ¯1 © as in the quotient case.Similarly, for lcm (^):[P Q] ^ [R S]¯—P Q] —R S] © defn of —...] and ˜...]=> ----- ^ -----˜P Q] ¯ ˜R S]—P Q]^—R S] © from lcm[2] above.=> -----------˜P Q]Ÿ˜R S][PuR QxS]=> ---------[PiR QnS]© from lcm[1] above.=> [PuR QxS], [PiR QnS] * ¯1 © as in the quotient case.Sum / difference----------------In general, for numbers A and B and any N¬0:308


Ú A B ÌA + B = N × Û --- + --- Û¯À N ¯ N ÙIf we choose N = AŸB (greatest common divisor of A and B), then both (A÷N) and(B÷N) are whole numbers and may be added (resp. subtracted) directly. Further,(A÷N) and (B÷N) are the smallest whole numbers for which this holds, so theirsum (resp. difference) is as small as possible and so easiest to re-factorise.(muse:sum/difference deals separately with zero arguments. Zero seems (to JMS) tobe, let's say, an uneasy member of the set of rational numbers.)sum„{0¹¾:¸0¹¸:¾×nchk ¸¸ 1mul„¸ gcd ¾...© sum (difference).© ¸+0 … ¸, ¸-0 … ¸© 0+¾ … ¾, 0-¾ … error© gcd multiplierExamples:factors¨28 752 2 7 3 5 5© prime factors.28 rats 75 © rational representation.2 7 3 52 1 ¯1 ¯2•rats 28 rats 7528r75–rats 28 rats 750.3733333333© r-format.© approx real number equivalent.© We can make a translator for simple expressions of rational scalars:rexp„{¸„'r'© simple r-expression translator.rat„{')',¾,'rats('}© ¾ … )¾rats(svec„rat\¨2/¨'+-×÷*^•Ÿ–•' © subs pair for each op fn.src„†subs/(svec,›¸' rats '),›¾ © translated source. See …subs„.'(',src,')'© source for apl expression.}rexp'2r3 + 3r4'(2 rats 3 )+rats( 3 rats 4)eval „ •rats°–°rexpeval ' 36r140 '9r35© r-expression translation.© r-expression evaluation.© simplify.5r61r61r21r1eval '1r2 + 1r3'eval '1r2 - 1r3'eval '3r4 × 2r3'eval '2r3 ÷ 2r3'© sum.© difference.© product.© quotient.309


eval '4r9 * 3r2' © power8r271r56r51r2eval '2r5 Ÿ 3r5'eval '2r5 ^ 3r5'eval ' (1r2 × 3r4) + 1r8 '© gcd.© lcm.© more complex expression.See also: pco.296 factors.282 rational.298 subs.85 gcd.284 nats.290 bt.258 ary.3See also: numbers.551ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎratsumsum „ {larg} (digs ##.ratsum) rarg © ¸¸-rational sum of ¸ and ¾.cmp „ (digs ##.ratsum) rarg © ¸¸-complement (negative) of ¾.Operator [ratsum] returns the sum of arguments [larg] and [rarg], which are eachrational scalars in the number system defined by [digs].Called without a left argument, [ratsum] returns the complement (negative) of[rarg].This operator codes some of the ideas presented in LeRoy Eide's magnificentrepresentation scheme for rational numbers.See: …ratrep„.[digs] is a character vector of the digits used by the number system. The digitsmay be any characters, except that:- They must distinct from each other,- Exactly one of them must be '0',- They must not include any of the special characters ' {}[]()\|/,:.'The digits vector may, but need not, be embraced by braces.Arguments [larg] and [rarg] are character vectors of the form ,where lru, man and rru are vectors of [digs] and man may additionally contain anembedded '.' radix point.For example, if [digs] isthen0123456789 (decimal numbers) is 123 is 98.4 is 0 is 4.99.. is ..999LeRoy's paper …ratrep„ makes it all clear and function …esh„ provides an interactiveshell for exploring these numbers.Technical notes on the coding of [ratsum]-----------------------------------------Called dyadically, [ratsum] compiles its rational-number-expression (rexp) argumentsinto an "lmrs" triple of 2-row matrices, which represents the sum.(lrus mans rrus)© :: lmrs310


where:lrus: 2-row left replication units matrix.mans: 2-row mantissas matrix.rrus: 2-row right replication units matrix.for example:disp '' compile ''Ú…ÎÂÎÎÎÎÎÎÂÎÎÎÌÛ00Û123.45Û777ÛÛ14‡142.37‡897‡ÀÎ…ÁÎÎÎÎÎ…ÁÎÎ…ÙAddition Table--------------Inner function [atab] returns an addition table for a number system with digits¸¸. Each item in the table is the 2-vector: carry-out and sum.7 10†disp atab '012' © (partial) addition table for regular ternary.Ú…ÎÂÎÎÂη00Û01Û02ÛÃÎ…ÏÎ…ÏÎ…ÏÛ01Û02Û10ÛÃÎ…ÏÎ…ÏÎ…ÏÛ02Û10Û11ÛÃÎ…ÏÎ…ÏÎ…Ï7 10†disp atab '-0+' © (partial) addition table for balanced ternary.Ú…ÎÂÎÎÂη-+Û0-Û00ÛÃÎ…ÏÎ…ÏÎ…ÏÛ0-Û00Û0+ÛÃÎ…ÏÎ…ÏÎ…ÏÛ00Û0+Û+-ÛÃÎ…ÏÎ…ÏÎ…ÏIt is convenient for the addition table to accept numbers containing an embeddedradix point. This requires only one extra row and column for the dots:i j ... k .· · · · ÂÎÎÎÌi · · · · Ûi .Û In other words:· · · · ÏÎÎÎÝj · · · · Ûj .Û "Dot add dot is dot, carry 0".· · · · ÏÎÎÎÝ "Dot add thing is dot, carry thing"....· · · · Û Û· · · · ÏÎÎÎÝ 0 1 1 0 „ carriesk · · · · Ûk .Û 1 2 . 3 4ÃÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝ 4 5 . 7 5 +. Ûi .Ûj .Û Ûk .Û0 .Û ---------ÀÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÙ 5 8 . 0 9giving:disp atab '012'Ú…ÎÂÎÎÂÎÎÂÎÎ̇00Û01Û02Û0.ÛÃÎ…ÏÎ…ÏÎ…ÏÎ…ÝÛ01Û02Û10Û1.ÛÃÎ…ÏÎ…ÏÎ…ÏÎ…ÝÛ02Û10Û11Û2.ÛÃÎ…ÏÎ…ÏÎ…ÏÎ…ÝÛ0.Û1.Û2.Û0.ÛÀÎ…ÁÎ…ÁÎ…ÁÎ…Ù© full addition table for regular ternary.311


disp atab '-0+' © full addition table for balanced ternary.Ú…ÎÂÎÎÂÎÎÂÎÎ̇-+Û0-Û00Û-.ÛÃÎ…ÏÎ…ÏÎ…ÏÎ…ÝÛ0-Û00Û0+Û0.ÛÃÎ…ÏÎ…ÏÎ…ÏÎ…ÝÛ00Û0+Û+-Û+.ÛÃÎ…ÏÎ…ÏÎ…ÏÎ…ÝÛ-.Û0.Û+.Û0.ÛÀÎ…ÁÎ…ÁÎ…ÁÎ…ÙHere's the code:atab„{Œio Œml„0 © addition table for digits ¾.min„¾¼'0'© - minimum value.vals„-min-¼½¾© numeric values of digits.ntab„vals°.+vals© all sums larg vs. rarg.base„2/½¾© 2-digit encode/decode vector.vtab„-min-base‚baseƒmin+base‚ntab © base-¾: 2-digit addition values.ptab„‡(min+(¯1²¼3)³vtab)œ¨›¾ © array of (carry_out result) pairs,{(ptab,¾)®¾,›'0.'}¾,¨'.'© with additional rows/cols for '.'.} © :: [[carry sum];] „ ’ [digits]<strong>APL</strong> likes to do things in parallel: armed with our addition table, we can sum a2-row matrix of digits in one pop by indexing the table with a vector of pairsof digits to be summed. The result is a vector of carry-out, sum-digit pairs,which idiom ‡³† renders as a pair of carry-out, sum-digit vectors. Then, if thecarry-out vector is all-zeros, we're done; otherwise, we recursively [rsum] theleft-shifted carry-out vector with the total and try again:rsum„(atab digs){Œio Œml„0 © row sum of matrix ¾, carry_in ¸.cov itot„‡³†¸¸[‡³digs¼¾]© carry vector and initial total.'0'^.=cov,¸:'0'itot© all-zero carry: done.co tot„'0'’†(1‡cov,¸)itot© total with shifted carry vector.(œœ²'0'’†co,›1†cov)tot© aggregate carry and total.} © :: d [d] „ ’ [d;]Notice how we snuck the initial carry-in ¸ into the process on the right of thefirst left-shift of the carry vector.Here is a trace of rsum: 147258369.147258369 + 123456789.987654321 with initialcarry-in '1':+ 147258369.147258369 1 initial carry-in '1' (waiting in the wings).123456789.987654321------------------- digit-wise sum produces ...< 0010111110111011001 1 carry-out vector (initial carry-in still waiting).260604048.024802680 and total vector.shifting carry vector left and absorbing carry-in:+ 0101111101110110011 0 carry-out shifted left, initial carry-in absorbed.260604048.024802680------------------- digit-wise sum produces ...< 0000000001000000000 0 carry-out vector.270715158.134912691 and total vector.shifting carry vector left produces ...+ 0000000010000000000 0 carry-out shifted left (zero appended).270715158.134912691------------------- digit-wise sum produces ...0000000000000000000 all-zero carry-out vector270715159.134912691 and final total.Hence, using vector addition, in this case we were able to sum a pair of 18-digitnumbers in just three iterations. The very worst case would be to sum '0..01'with '9..99', which would require one iteration per digit.312


Notice how a carry is just passed along by the '.' column. The inclusion of arow and column for '.' in the addition table effectively renders the dot invisibleto the process, except as in the above case, where it occasions a singleextra iteration.Notice finally that [rsum] is a derived function, whose left operand (atab digs)is evaluated just once (per call on ratsum), when rsum is defined, rather thaneach time [rsum] is called.(muse:[ratsum] would be a good candidate for conversion to a function returning a"closure", should such a mechanism become available. In this case, insteadof:† Œd ratsum/ Œd © reduction using derived function.45if ratsum returned a closure, we would type:45† (ratsum Œd)/ Œd © reduction using closure.the advantage of using a closure is that we could arrange for the additiontable for a particular number system to be generated just once, at closureformationtime, rather than each time the derived function is applied. Inthe first example above, [atab] is called nine times, whereas in the secondexample, it is called just once.)For more on closures, see: http://dfns.dyalog.com/downloads/fre.pdfInner <strong>functions</strong> [clru] and [fmt] make use of auxiliary function [repl], whichtakes a left argument pair (to from) of strings to find and replace in its rightargument ¾:posh „ 'oun' 'in' ° repl© Talk like the Duke of Edinburgh.'' ª posh 'A bounder in the grounds? Release the hounds!'A binder in the grinds? Release the hinds!(muse:In some treatments of the lambda calculus, this (to from) order of items ispreferred to the more common (from to). Syntax "[to/fm]expr" means "expr"with each occurrence of "fm" replaced with "to". A pleasing mnemonic for thesyntax is to think of [to/fm] as a fraction applied to expr; it cancels "fm"and multiplies by "to". We could vocalise [to/fm]... as "to for fm in ...".)Replication Unit Alignment--------------------------Note that, when aligning LLUs and RRUs, as in: + the resulting RUs should each contain a number of digits equal to the lowestcommon-multiple(LCM) of those of its corresponding summands. In the above example,this is 6 in each case: © LRU and RRU misaligned :-( +313


ewrite: © LRU and RRU aligned :-) +Normal form of numbers----------------------[ratsum] attempts to normalise its result in a number of ways.Internal contraction of LRU and RRU: … ¯¯¯¯¯¯ ¯¯¯¯¯¯ ¯¯¯ ¯¯External absorption from the mantissa: … ¯¯¯ ¯¯ ¯ ¯¯¯Clearing the LRU to 0 or ~0: … ¯¯Replacing the RRU if it is ~0: … ¯ ¯ ¯Using an external '¯' where appropriate: … ¯273.15¯where ~0 is the complement of 0 (e.g., 9 in the decimal system). See …ratrep„for details.Examples--------©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©© Decimalsum „ neg „ Œd ratsum© standard decimal sum and negation fns.''sum'' © 92.3434... + 8.611... … 100.95454...''sum'' © ¯1 + 1 … 0 …ratrep„''sum neg'' © (1÷3) + - (2÷3) … -(1÷3) …ratrep„©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©© Balanced Ternarysum „ '-0+'ratsum© balanced ternary sum.''sum'' © balanced ternary 2 + 3 … 5''sum'' © balanced ternary 0.5 + 0.5 … 1©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©© Binarysum „ '01'ratsum© binary sum.''sum'' © binary 9 + 7 … 1610000©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©© Positively-skewed foure„{''}© Eidify simple number.disp '-0+#'ratsum\e¨'0++++++++' © ¼9 in positively-skewed four {-0+#}.Ú…ÎÎÎÎÎÎÂÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÌÛÛÛÛÛÛÛÛÛÛÀÎÎÎÎÎÎ…ÁÎÎÎÎÎÎ…ÁÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎ…Ù©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©© Negatively-skewed four314


disp '=-0+'ratsum\e¨'0+++++++' © ¼8 in negatively-skewed four {=-0+}.Ú…ÎÎÎÎÎÎÂÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÌÛÛÛÛÛÛÛÛÛÀÎÎÎÎÎÎ…ÁÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎ…Ù© Here's a handy little function to convert an array of regular integers into© ¸-numbers:encode„{ŒIO ŒML„0 © ¸-encode of int array ¾.u„(2ƒ'0'=2†¯1²¸)œ0 1 ¯1© extremal '0': unsigned.(|u)^u¹-×¾:((0>u××¾)/¨'¯'),¨¸ ’ u×|¾ © explicit '¯', where needed.min„¸¼'0'© - minimum value.width„1+—(½¸)µ—/1—,|¾© upper bound for no of digits.base„width/½¸© encode/decode vector.vals„-min-base‚baseƒmin+base‚³¾© base-¸ integers.nlz„{(-1—+/Ÿ\¾¬'0')†¾}© without surplus leading zeros.nlz¨‡¸[min+³vals]© array of ¸-numbers.}disp '-0+'encode ¯9 to 10© balanced ternary ¯9..10Ú…ÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÂÎÎÂÎÎÂÎÂÎÂÎÂÎÎÂÎÎÂÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÌÛ-00Û-0+Û-+-Û-+0Û-++Û--Û-0Û-+Û-Û0Û+Û+-Û+0Û++Û+--Û+-0Û+-+Û+0-Û+00Û+0+ÛÀÎÎ…ÁÎÎ…ÁÎÎ…ÁÎÎ…ÁÎÎ…ÁÎ…ÁÎ…ÁÎ…Á…Á…Á…ÁÎ…ÁÎ…ÁÎ…ÁÎÎ…ÁÎÎ…ÁÎÎ…ÁÎÎ…ÁÎÎ…ÁÎÎ…Ù© Various number systems:bases „ Œd '-0+' '01' '-0+#' '=-0+' '­=-0+#' '210' (16†Œd,Œa)disp basesÚ…ÎÎÎÎÎÎÎÎÎÂÎÎÎÂÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÎÎÂÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ0123456789Û-0+Û01Û-0+#Û=-0+Û­=-0+#Û210Û0123456789ABCDEFÛÀÎÎÎÎÎÎÎÎÎ…ÁÎÎ…ÁÎ…ÁÎÎÎ…ÁÎÎÎ…ÁÎÎÎÎÎ…ÁÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…Ùdisp †bases encode¨›¯5 to 12© ¯5..12 per number system.Ú…ÎÎÎÂÎÎÎÎÂÎÎÎÂÎÎÎÂÎÎÂÎÂÎÎÂÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎ̇ ¯5 Û ¯4 Û¯3 Û¯2 Û¯1Û0Û1 Û2 Û 3 Û 4 Û 5 Û 6 Û 7 Û 8 Û 9 Û 10 Û 11 Û 12 ÛÃÎÎÎ…ÏÎÎÎ…ÏÎÎ…ÏÎÎ…ÏÎ…Ï…ÏÎ…ÏÎ…ÏÎÎ…ÏÎÎ…ÏÎÎ…ÏÎÎ…ÏÎÎ…ÏÎÎÎ…ÏÎÎÎ…ÏÎÎÎ…ÏÎÎÎ…ÏÎÎÎ…ÝÛ-++ Û -- Û-0 Û-+ Û- Û0Û+ Û+-Û+0 Û++ Û+--Û+-0Û+-+Û+0- Û+00 Û+0+ Û++- Û++0 ÛÃÎÎÎ…ÏÎÎÎ…ÏÎÎ…ÏÎÎ…ÏÎ…Ï…ÏÎ…ÏÎ…ÏÎÎ…ÏÎÎ…ÏÎÎ…ÏÎÎ…ÏÎÎ…ÏÎÎÎ…ÏÎÎÎ…ÏÎÎÎ…ÏÎÎÎ…ÏÎÎÎ…ÝÛ¯101Û¯100Û¯11Û¯10Û¯1Û0Û1 Û10Û11 Û100Û101Û110Û111Û1000Û1001Û1010Û1011Û1100ÛÃÎÎÎ…ÏÎÎÎ…ÏÎÎ…ÏÎÎ…ÏÎ…Ï…ÏÎ…ÏÎ…ÏÎÎ…ÏÎÎ…ÏÎÎ…ÏÎÎ…ÏÎÎ…ÏÎÎÎ…ÏÎÎÎ…ÏÎÎÎ…ÏÎÎÎ…ÏÎÎÎ…ÝÛ -- Û -0 Û-+ Û-# Û- Û0Û+ Û# Û+- Û+0 Û++ Û+# Û#- Û #0 Û #+ Û ## Û+-- Û+-0 ÛÃÎÎÎ…ÏÎÎÎ…ÏÎÎ…ÏÎÎ…ÏÎ…Ï…ÏÎ…ÏÎ…ÏÎÎ…ÏÎÎ…ÏÎÎ…ÏÎÎ…ÏÎÎ…ÏÎÎÎ…ÏÎÎÎ…ÏÎÎÎ…ÏÎÎÎ…ÏÎÎÎ…ÝÛ -- Û -0 Û-+ Û = Û- Û0Û+ Û+=Û+- Û+0 Û++ Û+==Û+=-Û+=0 Û+=+ Û+-= Û+-- Û+-0 ÛÃÎÎÎ…ÏÎÎÎ…ÏÎÎ…ÏÎÎ…ÏÎ…Ï…ÏÎ…ÏÎ…ÏÎÎ…ÏÎÎ…ÏÎÎ…ÏÎÎ…ÏÎÎ…ÏÎÎÎ…ÏÎÎÎ…ÏÎÎÎ…ÏÎÎÎ…ÏÎÎÎ…ÝÛ -+ Û -# Û ­ Û = Û- Û0Û+ Û# Û+­ Û+= Û+- Û+0 Û++ Û +# Û #­ Û #= Û #- Û #0 ÛÃÎÎÎ…ÏÎÎÎ…ÏÎÎ…ÏÎÎ…ÏÎ…Ï…ÏÎ…ÏÎ…ÏÎÎ…ÏÎÎ…ÏÎÎ…ÏÎÎ…ÏÎÎ…ÏÎÎÎ…ÏÎÎÎ…ÏÎÎÎ…ÏÎÎÎ…ÏÎÎÎ…ÝÛ 12 Û 11 Û10 Û 2 Û1 Û0Û¯1Û¯2Û¯10Û¯11Û¯12Û¯20Û¯21Û¯22 Û¯100Û¯101Û¯102Û¯110ÛÃÎÎÎ…ÏÎÎÎ…ÏÎÎ…ÏÎÎ…ÏÎ…Ï…ÏÎ…ÏÎ…ÏÎÎ…ÏÎÎ…ÏÎÎ…ÏÎÎ…ÏÎÎ…ÏÎÎÎ…ÏÎÎÎ…ÏÎÎÎ…ÏÎÎÎ…ÏÎÎÎ…ÝÛ ¯5 Û ¯4 Û¯3 Û¯2 Û¯1Û0Û1 Û2 Û 3 Û 4 Û 5 Û 6 Û 7 Û 8 Û 9 Û A Û B Û C ÛÀÎÎÎ…ÁÎÎÎ…ÁÎÎ…ÁÎÎ…ÁÎ…Á…ÁÎ…ÁÎ…ÁÎÎ…ÁÎÎ…ÁÎÎ…ÁÎÎ…ÁÎÎ…ÁÎÎÎ…ÁÎÎÎ…ÁÎÎÎ…ÁÎÎÎ…ÁÎÎÎ…Ù© Various answers to the meaning of Life, the Universe, and Everything:†bases encode¨4242 +---0 101010 ### +--= ++0 ¯1120 2A© For more examples see test script: ##.scripts.ratsumSee also: ratrep.556 esh.275 JitSub.600See also: ary.317 rats.302 nats.290315


ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎstampsnvec „ {denoms„1 5 6 10 26 39 43} ##.stamps value © Postage stamps for ¾.Returns a vector of stamps whose total value is the right argument. The optionalleft argument is a vector of distinct stamp values and defaults to those denominationsprevalent in the UK circa 1998:¸„1 5 6 10 26 39 43 © Default UK stamp denominations.Technical note:Notice that the graph approach is, in general, better than a simple "greedy"algorithm, which repeatedly subtracts the largest possible remaining value:stomps„{© stamps - greedy algorithm.¸„1 5 6 10 26 39 43 © default UK stamp denominations.svec„¸© stamp vector.«{ © stamp accumulator.¾=0:¸© no remaining value: done.next„—/svec×svecˆ¾ © largest possible stamp.(¸,next)’ ¾-next © next stamp and remainder.}¾}{0 disp 2 0°•¨stomps ¾}¨50 51 52 53 © less-than-optimal postage.ÚÎÎÂÎÎÂÎÎÌ ÚÎÎÂÎÎÂÎÎÂÎÎÌ ÚÎÎÂÎÎÂÎÎÂÎÎÂÎÎÌ ÚÎÎÂÎÎÌÛ43Û 6Û 1Û Û43Û 6Û 1Û 1Û Û43Û 6Û 1Û 1Û 1Û Û43Û10ÛÀÎÎÁÎÎÁÎÎÙ ÀÎÎÁÎÎÁÎÎÁÎÎÙ ÀÎÎÁÎÎÁÎÎÁÎÎÁÎÎÙ ÀÎÎÁÎÎÙExamples:{0 disp 2 0°•¨stamps ¾}¨50 51 52 53 © default UK(1998) stamps.ÚÎÎÂÎÎÂÎÎÌ ÚÎÎÂÎÎÂÎÎÌ ÚÎÎÂÎÎÌ ÚÎÎÂÎÎÌÛ43Û 6Û 1Û Û39Û 6Û 6Û Û26Û26Û Û43Û10ÛÀÎÎÁÎÎÁÎÎÙ ÀÎÎÁÎÎÁÎÎÙ ÀÎÎÁÎÎÙ ÀÎÎÁÎÎÙbins„1 2 4 8 16 32© "binary" stamps:{0 disp 2 0°•¨bins stamps ¾}¨15 16 17 18ÚÎÎÂÎÎÂÎÎÂÎÎÌ ÚÎÎÌ ÚÎÎÂÎÎÌ ÚÎÎÂÎÎÌÛ 8Û 4Û 2Û 1Û Û16Û Û16Û 1Û Û16Û 2ÛÀÎÎÁÎÎÁÎÎÁÎÎÙ ÀÎÎÙ ÀÎÎÁÎÎÙ ÀÎÎÁÎÎÙ© Stamps with a negative face value would be quite handy:bts„1 ¯1 3 ¯3 9 ¯9 27 ¯27© "balanced ternary" stamps.{0 disp 2 0°•¨bts stamps ¾}¨12 13 14 15 © see …bt„ÚÎÎÂÎÎÌ ÚÎÎÂÎÎÂÎÎÌ ÚÎÎÂÎÎÂÎÎÂÎÎÌ ÚÎÎÂÎÎÂÎÎÌÛ 9Û 3Û Û 9Û 3Û 1Û Û27Û¯1Û¯3Û¯9Û Û27Û¯3Û¯9ÛÀÎÎÁÎÎÙ ÀÎÎÁÎÎÁÎÎÙ ÀÎÎÁÎÎÁÎÎÁÎÎÙ ÀÎÎÁÎÎÁÎÎÙ© ... although they are unlikely to catch on:©© "I'd like a 27p stamp please. Oh yeah, and two ¯9s and a ¯3."© "Thank you sir, that'll be 6p; will there be anything else?"See also: Graphs.137 bt.258See also: eval.dws/notes.bta316


ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎsievenvec „ ##.sieve nvec© Sieve of Eratosthenes© Eratosthenes of Cyrene (¯276-¯194)Removes multiples of numbers within the argument vector. Thus sieve 2..¾ returnsthose primes in the range 2..¾. An illustration of most of the D-function constructs:left argument defaulting; local definition; guards; tail recursion.(muse:Among other accomplishments, Eratosthenes estimated the circumference of theEarth to a surprising accuracy. This is even more impressive if you rememberthat, as late as Columbus's time, many people still believed the Earth to beflat.)http://en.wikipedia.org/wiki/Eratosthenes reports Eratasthenes' estimate tobe 16% too large, taking the value of the stadion to be 185m. However, if wetake a value of 157.2, which some people derive from Pliny, the estimatecomes in at only 3% too small.(muse:A succinct way to express the vector of prime numbers up to (say) 100 is:(~v¹v°.×v)/v„1‡¼100 © primes to 100.2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97This expression may be read left-to-right as: "Those items of v that are notin the product-table of v, where v is a vector of all but the first of thenumbers from 1 to 100."(~ v ¹ v °.× v) / v „ 1 ‡ ¼100Û Û ÀÎÎÂÎÎÙ ÀÂÙ Û ÀÂÙ ÀÂÎÙÛ Û Û ÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎThose items of v thatÛ Û Û Û Û ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎare notÛ Û Û Û ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎinÛ Û Û ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎthe product table of v,Û Û ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎwhere v is a vector ofÛ ÛÀÎÎÎÎÎÎÎÎÎÎall but the first ofÛÀÎÎÎÎÎÎthe numbers from 1 to 100.Note however, that this is an O(n*2) algorithm in both space and time and sois infeasible for large arguments.)A criticism that the <strong>APL</strong> language encourages "over computation", in that itleads us into calculating many more values than are required, is misdirected.The _language_ has no interest in which values are actually calculatedand a smart, lazy implementation might well avoid creating (parts of) intermediatearrays.Example:sieve 2 to 1002 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97See also: pco.296 to.316317


ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎtonvec „ num ##.to num© Sequence ¸ .. ¾Returns a vector of numbers ¸ to ¾ inclusive. ¸ is the _first_ value in the sequence,and ¾ the _last_. More generally, ¸ may be a 2-item vector, which determinesthe first two items of the sequence and hence the _step_ size.Notice that any of _first_, _step_ and _last_ may be positive, negative and/orfractional. If _last_ is not a whole number of _step_s from _first_, thesequence will stop short of _last_.Technical notes:The following simple function suffices for the ascending sequence ¸, ¸+1, ··· ¾.Notice how (·-Œio) makes it independent of index origin:to„{(¸-Œio)+¼1+¾-¸}Useful refinements to the function allow _descending_ sequences and optional_step_ sizes other than 1:to„{Œio„0© Sequence ¸ .. ¾from step„1 ¯1×-\2†¸,¸+×¾-¸ © step default is +/- 1.from+step×¼0—1+˜(¾-from)÷step+step=0 © ¸ thru ¾ inclusive.}Attempts to re-cast the function as a one-liner, include:to„{From+0,+\Step½þ0—˜Inc÷Step„--/2½¸,From+×Inc„¾-From„1½¸}to„{†+/¾{¾×{¾-ŒIO}¼1+0—˜(¸¸-¸)÷¾+¾=0}\1 ¯1×-\2†¸,¸+×¾-¸}to„{(«½¸)+(|-/²2†¸,¸+1){¸×(×¾)×(-ŒIO)+¼1+˜|¾÷¸}¾-«½¸}VMJ suggests the following extension, which accepts an optional explicit _step_size as a second item of its _right_ argument. _step_ defers to _next_ if bothare supplied.to„{ŒIO„0 ª ¸„1 ª z„0.0000000001(a n)„2†¸,¸ ª (b s)„2†¾,1d„|s{¾¬0:¾ ª ¸¬0:¸ ª 1}n-a{¾×z


disp (¯1 6)(0 4) to ›3 ¯2Ú…ÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÎ̇¯1 6Û¯1 4Û¯1 2Û¯1 0Û¯1 ¯2ÛÃ~ÎÎ…Ï~ÎÎ…Ï~ÎÎ…Ï~ÎÎ…Ï~ÎÎÎ…ÝÛ0 6 Û0 4 Û0 2 Û0 0 Û0 ¯2 ÛÃ~ÎÎ…Ï~ÎÎ…Ï~ÎÎ…Ï~ÎÎ…Ï~ÎÎÎ…ÝÛ1 6 Û1 4 Û1 2 Û1 0 Û1 ¯2 ÛÃ~ÎÎ…Ï~ÎÎ…Ï~ÎÎ…Ï~ÎÎ…Ï~ÎÎÎ…ÝÛ2 6 Û2 4 Û2 2 Û2 0 Û2 ¯2 ÛÃ~ÎÎ…Ï~ÎÎ…Ï~ÎÎ…Ï~ÎÎ…Ï~ÎÎÎ…ÝÛ3 6 Û3 4 Û3 2 Û3 0 Û3 ¯2 ÛÀ~ÎÎ…Á~ÎÎ…Á~ÎÎ…Á~ÎÎ…Á~ÎÎÎ…ÙExamples:3 to 10 © Inclusive ascending sequence.3 4 5 6 7 8 9 1010 to 3 © Descending sequence.10 9 8 7 6 5 4 377 to 7 © Single-item sequence.5 7 to 13 © 2-item start determines step.5 7 9 11 13¯10 ¯15 to ¯25¯10 ¯15 ¯20 ¯25© Negative start and step.1.5 1.7 to 2.5 © Fractional start and step.1.5 1.7 1.9 2.1 2.3 2.50 3 to 10 © Sequence stops short of _last_.0 3 6 9See also: sieve.315ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎaryenco „ base (##.ary) ratnum © ¸-ary representation of rational ¾.Returns a character vector representation of the ¸-based rational number that isŒCT-tolerably close to ¾.3 ary 66.6 © ternary representation of rational number.2110.12101210...If [base] is a positive number in the range 2..36, then the result is a charactervector, in one of three forms:nnn.fffnnn.fff...nnn.fff?© exact rational with finite representation.© exact non-terminating rational.© inexact irrational number.A rational number of the form P÷Q, expressed in base ¸, has a finite representationonly if all of the prime factors of Q are also prime factors of the base.Otherwise, the ¸-ary representation of P÷Q will have a repeating sequence oftrailing digits. Examples, base-10 are:10 ary 1÷ 2×3 © 3 is relatively prime to base (2×5).0.166...10 ary 4÷ 11 © 11 is relatively prime to base (2×5).0.3636...319


The ellipsis (...) identifies the _longest_ twice-repeated sequence to its leftas the repetition sequence. In the first example above, only the '6' is repeatedindefinitely, whereas in the second example, the whole of the longer string '36'is repeated. See also …esh„.10 ary 16*¯3 © exact, finite representation.0.00024414062510 ary ÷7 © exact, rational with repeating sequence.0.142857142857...10 ary ±1 © inexact, irrational with truncated digits.3.1415926535898?If left argument [base] is negative, character vector formatting is supressedand nested structure: (sig exp fix rep rat) is returned. Where:sig:exp:fix:rep:rat:scalar sign of [ratnum] (1, ¯1),scalar base-¸ exponent of [ratnum],vector leading, fixed part of mantissa,vector trailing, repeated part of mantissa,scalar boolean: 1 if the repesentation is exact.• 369+÷7369.14285714285717© primitive •-format of number (Œpp=17).10 ary 369+÷7 © [ary]-formatted number.369.142857142857...disp ¯10 ary 369+÷7Ú…ÂÎÂÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÂÎÌÛ1Û3Û3 6 9Û1 4 2 8 5 7Û1ÛÀÎÁÎÁ~ÎÎÎ…Á~ÎÎÎÎÎÎÎÎÎ…ÁÎÙ© [ary]-unformatted (sig exp fix rep rat)Technical notes:The inner conditional formatting function is derived from the power operator ÿ:ofmt„{© optional formatting....}ÿ(¸>0) © NB: ÿ(¸>0) © :: [char] „ ’ (sig exp fix rep rat)...q=1:ofmt sign(exp+1)(,1)« 1© base*n: special case.ofmt sign exp,« digs p×base© optional formatting of ¸-ary number.This is slightly neater than passing ¸ and testing it in the first line:ofmt„{© optional formatting.¸>0:¾© no formatting: done....} © :: [char] „ ’ (sig exp fix rep rat)...q=1:¸ ofmt sign(exp+1)(,1)« 1 © base*n: special case.¸ ofmt sign exp,« digs p×base © optional formatting of ¸-ary number.320


or, worse, using guards to determine whether to apply the function:ofmt„{© optional formatting....} © :: [char] „ ’ (sig exp fix rep rat)...z1„sign(exp+1)(,1)« 1© base*n: special case.zn„sign exp,« digs p×base© optional formatting of ¸-ary number.rslt„(q=1)œzn z1© special or regular result.(¸


disp ¯3 ary ¯12345 © negative whole ternary number (exact).Ú…ÎÂÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÂÎÌÛ¯1Û9Û1 2 1 2 2 1 0 2Û0Û1ÛÀ~ÎÁÎÁ~ÎÎÎÎÎÎÎÎÎÎÎÎÎ…Á´ÁÎÙdisp ¯16 ary *1© hexadecimal irrational (inexact).Ú…ÂÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÂÎÌÛ1Û1Û2 11 7 14 1 5 1 6 2 8 10 15Û0Û0ÛÀÎÁÎÁ~ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…Á´ÁÎÙSee also: adic.253 esh.275 ratrep.556 bt.258 phinary.341See also: numbers.551ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎabc-------------------------------------------------Arithmetic Boundary Checking - Stephen M. Mansour-------------------------------------------------A point partitions a line into three disjoint subsets: the set of points to itsleft, the point itself and the set of points to its right. Relational <strong>functions</strong>produce two results 0 and 1, effectively partitioning a line into only two subsets.A technique, known as arithmetic boundary checking, uses arithmetic <strong>functions</strong>instead of relational and Boolean <strong>functions</strong> to determine where a point liesin a line or a plane.Relational Functions--------------------Relational <strong>functions</strong> ask the question: is the statement true or false? If thestatement ¸


However, a performance test in <strong>Dyalog</strong> Version 10 shows that xd runs significantlyfaster than bd:U„1E¯4×500000-?100½1E6V„1E¯4×500000-?100½1E6cmpx 'U xd V' 'U bd V'U xd V 2.2E¯5 0% ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒU bd V 3.4E¯5 +52% ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒIntervals---------An interval is indicated by two distinct points on the real line. The intervalincludes the interior and may include one or both of the end-points. An intervalis open if it excludes the end-points; closed if it includes both of them, andhalf-open if it includes only one of them. A half-open interval can be open onthe left or on the right. The four types of intervals can be described by combiningrelational <strong>functions</strong> into the operator rg:rg„{(¸[0]¸¸ ¾)^¸[1]¾¾ ¾}© Range Operator1 3 ¼5 © Open Interval: ±-----------±0 0 1 0 01 3 ˆrg‰ ¼5 © Closed Interval: µ-----------µ0 1 1 1 01 3 ¼5 © Half-Open Right: µ-----------±0 1 1 0 0This operator is still limited in that it does not differentiate between aninterior point and a boundary (limit) point.Partitions----------A pair of distinct points on the real line can define two types of partitions:an interval partition and a range partition.An "interval partition" divides the real line into three disjoint subsets: theinterior (between the end-points), the boundary (the two end-points themselves),and the outside (everything else).Outside Bound Interior Bound Outside1 0 ¯1 0 1The product of the signum differences between a specified point and each of theboundary points will indicate whether the point falls in the interior, theboundary, or outside. If the point is outside the interval, the differences areboth positive, or both negative so their signum product is +1. If the point ison the boundary, one of the differences is zero, thus the product is zero. Andif the point is in the interior, the differences have opposite signs, so thesignum product is -1.A range partition divides the real line into five disjoint regions: below, lowerbound (L.B.), interior, upper bound (U.B.) and above:Below L.B. Interior U.B. Above¯2 ¯1 0 +1 +2323


ÚÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÌÛÛA„P xd LBÛB„P xd UBÛxp: A×BÛxs: A+BÛÃÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÝÛBelow Û ¯1 Û ¯1 Û 1 Û ¯2 ÛÃÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÝÛLower boundÛ 0 Û ¯1 Û 0 Û ¯1 ÛÃÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÝÛInterior Û 1 Û ¯1 Û ¯1 Û 0 ÛÃÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÝÛUpper boundÛ 1 Û 0 Û 0 Û 1 ÛÃÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÝÛAbove Û 1 Û 1 Û 1 Û 2 ÛÀÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÙTable 1: Signum Product and Signum SumThe sum of the signum differences will produce five distinct values ranging from-2 to +2 and corresponding to each of the 5 regions in a range partition.xp„{×/×¾°.-¸}© Signum product1 3 xp ¼5 © produces interval partition1 0 ¯1 0 1xs„{+/×¾°.-¸}© Signum sum1 3 xs ¼5 © produces range partition¯2 ¯1 0 1 2Two-Dimensional Region Checking-------------------------------In a GUI application, you may want to know whether the cursor is within a dialogbox. In particular you may want to know whether the cursor is in the interior ofthe box, on the boundary, or outside the box.ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ Interior(¯1) Û Outside (1)Boundary (0)--…ÛÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙFigure 1: Regions in the plane defined by a rectangleWe now extend the concept of arithmetic boundary checking to two dimensions.In the following example, we have six points in various positions relative to arectangular region in the plane. The coordinates of the upper left and lowerright corners of the rectangle are (3,2) and (5,6) respectively. The signumproducts of the x and y coordinates must be calculated separately.· °(2,3)··· Upper Left --… (3,2)°ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎΰ(3,5)ÎÎÌ· Û Û· Û Û· Û °(4,4) Û· Û Û· Û Û· (5,2)°ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎΰ(5,6) „-- Lower Right··· °(6,8)··°(7,6)324


Figure 2: Points in various positions relative to a rectangle in the plane.If we take the signum product of the x-coordinate with respect to the row coordinatesand the signum product of the y-coordinate with respect to the column coordinates,we obtain a ordered pair indicating the position in each direction.The following table shows this for the points in Figure 2.ÚÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÌÛPointÛDescriptionÛRow xpÛColumn xpÛRegion (—)ÛÃÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÝÛ(6,8)ÛOutside Û 1 Û 1 Û 1 ÛÃÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÝÛ(5,2)ÛCorner Û 0 Û 0 Û 0 ÛÃÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÝÛ(4,4)ÛInterior Û ¯1 Û ¯1 Û ¯1 ÛÃÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÝÛ(7,6)ÛBelow Û 1 Û 0 Û 1 ÛÃÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÝÛ(3,5)ÛEdge Û ¯1 Û 0 Û 0 ÛÃÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÝÛ(2,3)ÛAbove Û 1 Û ¯1 Û 1 ÛÀÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÙTable 2: Various points in the plane withrespect to a defined rectangular region.In order to be in the interior, both coordinates of the point must be in theinterior of their respective intervals in the x and y directions. If either coordinateis outside, then the point itself is outside. Otherwise, the point ison the boundary. In general, the region in which the point resides is the greaterof the partitions in each direction.xm„{-/œ×š×¸,.-³¾}b„œ(3 2)(5 6)© Max Signum© Upper Left and Lower Right Cornersb xmœ(6 8)(5 2)(4 4)(7 6)(3 5)(2 3)1 0 ¯1 1 0 1© Various PointsThe left argument of the dynamic function xm is a 2 x 2 matrix containing thecoordinates of the upper-left and lower-right corners of a rectangular region.The right argument is a 2-element vector or 2-column matrix containing the coordinatesof various points in the plane.Sometimes it is necessary to divide the borders of the dialog box into specificregions. For example when the cursor is over an edge, it will resize the windowin one direction. If it is over a corner, it will resize the window in two directions.The particular edge or corner selected also determines the position ofthe resized window.A rectangular region naturally subdivides the x-y plane into 25 regions, 5 inthe x direction by 5 in the y direction . The following regions are shown inFigure 3: 1 interior region, four corners, four edges, and 16 outside regions.325


ÚÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÌÛOutside (8)ÛOutside (8)ÛOutside (8)ÛOutside (8)ÛOutside (8)ÛÃÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÝÛOutside (8)ÛUpper Left ÛUpper Edge ÛUpper RightÛOutside (8)ÛÛ ÛCorner (¯4)Û (¯3) ÛCorner (¯2)Û ÛÃÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÝÛOutside (8)ÛLeft Edge ÛInterior ÛRight Edge ÛOutside (8)ÛÛ Û (¯1) Û (0) Û (1) Û ÛÃÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÝÛOutside (8)ÛLower Left ÛBottom EdgeÛLower RightÛOutside (8)ÛÛ ÛCorner (2) Û (3) ÛCorner (4) Û ÛÃÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÝÛOutside (8)ÛOutside (8)ÛOutside (8)ÛOutside (8)ÛOutside (8)ÛÀÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÙFigure 3: 25 Regions defined by a rectangleThe signum sum applied to each coordinate generates an ordered pair. If we wishto identify all 25 regions uniquely, we can use base value with a root of 5 togenerate the integers -12 to +12 with 0 representing the interior. More likely,we only wish to identify the 9 relevant regions, disregarding the 14 outsideregions. We can use base value with a root of 3. This will produce the values-4 to +4 with 0 representing the interior. We will assign the value 8 to theoutside regions. We can identify a point in the outside region if the orderedpair of its signum sums contains the value 2 or -2. The function xr generatesthe appropriate value.xr„{d„³œ+/×¾,.-³¸ ª ((2Ÿ.=|d)/d)„2 ª 3ƒd}b xr œ(2 3)(3 5)(4 4)(5 2)(6 8)(7 6)8 ¯3 0 2 8 8Theoretical Considerations and Conclusion-----------------------------------------Arithmetic boundary checking is based upon the topological properties of thereal line and the Euclidean 2-space [1]. The boundaries of an interval or arectangle correspond to limit points in topology. An open interval correspondsto the interior set, whereas a closed interval corresponds to the union of theboundary set and the interior set. A k-cell is defined as an closed intervalon the real line where k=1 or a closed rectangle in the plane, where k=2. [2]While Boolean <strong>functions</strong> are useful if binary results are adequate, they do notwork as well when more information is required. Location on the real line or inthe plane can be determined arithmetically without the use of Booleans. Theternary nature of signum is exploited to handle boundary conditions.References----------[1] Jerrold Marsden, "Elementary Classical Analysis" W.H.Freeman & Co. 1974,Chapter 2, Topology of, pp 32-44.[2] Walter Rudin, "Priciples of Mathematical Analysis, Third Edition", McGraw-Hill 1976, pp. 31-32 .See also: kcell.335 kball.336ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎbirthdayp „ s ##.birthday n© Probability of same birthday."In a group of 23 people there is a better than 50-50 chance that two of themshare a birthday".This function from Nicolas Delcros and Roger Hui generalises this assertion tofind the probability of a pair of coincident results occuring from n trials,each with probability ÷s.326


See: http://www.jsoftware.com/jwiki/Essays/Birthday_ProblemExamples:365 birthday 23 © probability that 2 people out of 23 share a birthday0.50729723436 birthday 2 © probability of a pair in dice-throwing.0.1666666667(2*32) birthday 1e4 © probability of BuildID collision for 10.000 builds0.01157288999ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎCholeskyy „ ##.Cholesky x © decomposition of Hermitian positive-definite matrix.From Roger Hui: see http://www.jsoftware.com/jwiki/Essays/Cholesky%20Decompositifor the derivation.Examples:x„t+.׳t„¯10+?5 5½20x153 ¯14 10 ¯117 ¯48¯14 286 ¯158 ¯203 7210 ¯158 178 112 ¯3¯117 ¯203 112 274 ¯16¯48 72 ¯3 ¯16 49y„Cholesky xy12.3693 0 0 0 0¯1.13183 16.8736 0 0 00.808452 ¯9.3095 9.52258 0 0¯9.45889 ¯12.6651 0.182868 4.90831 0¯3.88057 4.00672 3.93148 ¯0.545884 1.46044x ­ y +.× ³y1© The t+.׳t construct is a handy way to generate a Hermitian, positive definite© matrix. For real numbers, "Hermitian" is the same as symmetric (x­³x); for© complex matrices; Hermitian means z­+³z (conjugate transpose).z„t+.×+³t„(¯10+?5 5½20)+0j1ׯ10+?5 5½20z310 ¯51J¯092 93J0157 ¯31J145 244J¯024¯51J0092 357 ¯149J¯054 54J060 ¯192J020393J¯157 ¯149J0054 217 ¯16J115 113J¯203¯31J¯145 54J¯060 ¯16J¯115 397 10J¯048244J0024 ¯192J¯203 113J0203 10J048 384y„Cholesky z1z ­ y +.× +³y© So the Cholesky decomposition is a sort of "square root" y of a Hermitian© positive matrix z, such that y is lower-triangular and z­y+.×+³y.See also: det.326 gauss_jordan.327327


ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎdetnum „ ##.det nmat© Determinant of square matrix.From Roger Hui, [det] uses Gaussian elimination & Laplace expansion to find thedeterminant of square matrix [nmat].[det] finds the maximal entry in the entire matrix, not just the maximal entryin column 0 (i.e. it does "full pivoting".). It doesn't do row or column interchangesat all. Instead, after Gaussian elimination to zero out the i-th row(other than column j) or zero out the j-th column (other than row i), it does aLaplace expansion on the i-th row (or the j-th column). Post-Gaussian elimination,either expansion has just one non-zero co-factor, that is, just one minor’ ¾[k~i;k~j] with a non-zero coefficient ¾[i;j]ׯ1*i+j, and that coefficient ismultiplied by ¸ on the tail call.Alternative codings-------------------Also from Roger, an earlier draft of [det]:det_4a„{Œio Œml„0¸„1 © product of diagonal entries so far0=n„œ½¾:¸© answer for 0-by-0p„{¾¼—/¾}|¾[;0]© index of pivot rowp=n:0 © ¾ is singular if column is all 0k„¼n© row indicesk[²i]„k[i„(×p)/p,0] © interchange p and 0, if different(¸×dׯ1*×p)’ ¾[1‡k;1‡¼n]-(¾[1‡k;0]÷d„¾[œk;0])°.×¾[œk;1‡¼n]}The following rather unpleasant one-line alternative, is included just foramusement. It is interesting only in that it:- Is both ŒIO and ŒML independent.- Has no guards or local variables. It is a single pure <strong>APL</strong> expression that,without testing or looping, denotes the determinant of its argument matrix.- Codes the mathematical definition of determinant which is an O(!n) algorithmand so is viable for only the smallest of argument matrices.- Is the sort of thing that gets <strong>APL</strong> a bad name.detriment„{’{¾+(¯1*+/^\¸)×¾¾[Œio;¸¼0]׸¸ ¸/1 0‡¾¾}¾/(‡¬/¨¼½¾),0 0­½¾}VMJ suggests this version using the Gaussian method:and ...detG„{© Gaussian determinant.(Œio Œml)„1 3 ª r„½¾1‰×/r:†¾ ª 2¬½r:0 ª ¬/r:0© check for trivial cases1{ © inner loop2>†½¾:†¸×¾© end? -> result(m a c)„{ © calculate matrix, anchor & coeff0¬1½¾:¾(1½¾)1© default: original matrixz„¾ ª j„{¾¼—/¾}|z[;1] © look for 1st non-zeroz[1,j;]„z[j,1;]© reorder matrixz(1½z)¯1© NB. coeff=¯1}¾a=0:0© row of zeroes..(¸×a×c)’ 1 1‡m-m[;1]°.×m[1;]÷a © re-curses!}¾}328


det_mv„{ © Matrix determinant, based on Mahajan-Vinay algorithm:©| Meena Mahajan and V Vinay.©| Determinant: Combinatorics, Algorithms, and Complexity©| http://www.imsc.ernet.in/~meena/publ.html(Œio Œml)„0 3 ª mat„¾ ª n„†½matV„(2,3/n)½0 ª V[2|n;;;0]„1†{i„¾†{v„¾†{u„¾ª n=¾+1:0†{V[0;u;¾;i+1]+„V[0;u;v;i]×mat[v;¾]V[1;¾;¾;i+1]+„V[0;u;v;i]×mat[v;u]V[1;u;¾;i+1]+„V[1;u;v;i]×mat[v;¾]V[0;¾;¾;i+1]+„V[1;u;v;i]×mat[v;u]0}¨(¾+1)‡¼n}¨¼¾+1}¨¼n}¨¼n-1:}+/{-+/mat[¾;¼¾+1]×-šV[;¼¾+1;¾;n-1]}¨¼nExamples:¯2¯131det 2 2½2 3 4 5det 2 2½0 1 1 0det 1 1½3det 0 0½7hil„{÷1+°.+þ(¼¾)-Œio}© Order ¾ Hilbert matrix.det hil 102.1644805E¯53See also: gauss_jordan.327 Cholesky.325ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎgauss_jordaninv „ {vals} ##.gauss_jordan mat© Gauss-Jordan elimination.Gauss-Jordan elimination is a classic algorithm, implemented the D-style.NB: This function is included only for interest as <strong>APL</strong> provides both matrixinverse and matrix division as a primitive function: Ž.Further, the results of this D-function differ very slightly from those of <strong>APL</strong>'sprimitive function. This may be because <strong>APL</strong>'s C-code maintains 80-bit floatingpointaccuracy during (much, if not all of) its calculation, whereas the intermediatearrays of this function use only 64 bits. Of course, the function couldbe adapted to use, for example, rational …rats„ arithmetic for perfect precision(see test script: ##.scripts.gauss_jordan).Matrix right argument [mat] represents the coefficients of a system of linearequations and, if present, left argument [vals] represents the equations' valuevector (right-hand side).329


For example:x + y + 2z = ¯3¯1x + ¯2y + 3z = 143x + ¯7y + 4z = ¯3which may be written:A x = v¯ ¯ ¯where:Ú 1 1 2Ì v = [¯3 14 ¯3]A = Û¯1 ¯1 3Û ¯¯ Û 3 ¯7 4ÛÀ ÙThen the solution vector x is:¯x = v Ž A © using dyadic Ž.¯ ¯ ¯orx = (Ž A) × v © using monadic Ž (where × is matrix product +.×).¯ ¯ ¯ ¯ ¯Gauss-Jordan uses three simple transformations, none of which changes the solutionof the equations. For example, starting with:[0] Initial equations:x + y + 2z = ¯3¯1x + ¯2y + 3z = 143x + ¯7y + 4z = ¯3[1] Exchange rows:¯1x + ¯2y + 3z = 14x + y + 2z = ¯33x + ¯7y + 4z = ¯3© swap first and second rows.[2] Multiply each term in a row by the same factor:¯1x + ¯2y + 3z = 143x + 3y + 6z = ¯9 © multiply second row by 3.3x + ¯7y + 4z = ¯3[3] Subtract one row from another:¯1x + ¯2y + 3z = ¯23x + 3y + 6z = ¯90x + ¯10y + ¯2z = 6© subtract second row from third.The algorithm applies these three steps repeatedly, until the coefficient matrixis transformed into an identity matrix, giving:or:1x + 0y + 0z = ¯60x + 1y + 0z = ¯10x + 0y + 1z = 2x · · = ¯6· y · = ¯1· · z = 2330


Monadic case------------We find the explicit matrix inverse by starting with an identity matrix on theright:[0] © initial matrix:1x + 1y + 2z = 1 0 0¯1x + ¯2y + 3z = 0 1 03x + ¯7y + 4z = 0 0 1[1] © exchange first and third rows:3x + ¯7y + 4z = 0 0 1¯1x + ¯2y + 3z = 0 1 01x + 1y + 2z = 1 0 0[2]1x + ¯2.333y + 1.333z = 0 0 0.333 © multiply first row by ÷3:¯1x + ¯2y + 3z = 0 1 01x + 1y + 2z = 1 0 0[3] © subtract first row from others:1x + ¯2.333y + 1.333z = 0 0 0.3330x + ¯4.333y + 4.333z = 0 1 0.3330x + 3.333y + 0.667z = 1 0 ¯0.333... © and so on, until:1x + 0y + 0z = 0.25 ¯0.346 0.1350x + 1y + 0z = 0.25 ¯0.038 ¯0.0960x + 0y + 1z = 0.25 0.192 ¯0.019Choosing a pivot value----------------------In a finite-precision implementation, such as IEEE floating point, subtractingrelatively large but commensurate numbers introduces a significant error.Gauss-Jordan reduces this as much as possible by choosing the "pivot" value fortransformation [2] to be the item with the largest absolute magnitude within theremaining rows of the column under consideration.beforeafter1 0 · · · · 1 0 · · · ·0 1 · · · · In this example, working on the third 0 1 · · · ·0 0 3 · · · column, the pivot (max abs) value is 0 0 ¯4 · · ·0 0 ¯2 · · · ¯4, resulting in the exchange of the 0 0 ¯2 · · ·0 0 ¯4 · · · third and fifth rows. 0 0 3 · · ·0 0 1 · · · 0 0 1 · · ·Notice that values in the first two rows of the third column are ignored.Put simply, the pivot value for column ¸ is the item from rows ¸ downwards withthe largest absolute value: —/|¸‡¾[;¸].Illustration------------Here is an illustration of the steps in the Gauss-Jordan elimination of:ÚÎÎÎÎÎÎÎÎÌÛ4 8 4 0ÛÛ1 4 7 2ÛÛ1 5 4 ¯3ÛÛ1 3 0 ¯2ÛÀÎÎÎÎÎÎÎÎÙ331


Append an identity matrix:ÚÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÌÛ4 8 4 0Û1 0 0 0Û append identity matrix.Û1 4 7 2Û0 1 0 0ÛÛ1 5 4 ¯3Û0 0 1 0ÛÛ1 3 0 ¯2Û0 0 0 1ÛÀÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÙEliminate off-diagonal values from first column:ÚÂÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÌÛ4 8 4 0Û1 0 0 0Û first col; pivot value is 4. (4)· · ·Û1 4 7 2Û0 1 0 0Û 1 · · ·Û1 5 4 ¯3Û0 0 1 0Û 1 · · ·Û1 3 0 ¯2Û0 0 0 1Û 1 · · ·ÀÁÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÙÚÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÌÃ1Î2Î1ÎÎ0Ï0.25Î0Î0Î0Ý divide first row by pivot value.Û1 4 7 2Û0 1 0 0ÛÛ1 5 4 ¯3Û0 0 1 0ÛÛ1 3 0 ¯2Û0 0 0 1ÛÀÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÙÚÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÌÛ1 2 1 0Û 0.25 0 0 0Û subtract first row from remaining rows.Û0 2 6 2Û¯0.25 1 0 0Û to leave 0s in all off-diagonal rowsÛ0 3 3 ¯3Û¯0.25 0 1 0Û of first column.Û0 1 ¯1 ¯2Û¯0.25 0 0 1ÛÀÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÙEliminate off-diagonal values from second column:ÚÎÎÂÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÌÛ1 2 1 0Û 0.25 0 0 0Û · · · ·Û0 2 6 2Û¯0.25 1 0 0Û · 2 · ·Û0 3 3 ¯3Û¯0.25 0 1 0Û second col; pivot value is 3. ·(3)· ·Û0 1 ¯1 ¯2Û¯0.25 0 0 1Û · 1 · ·ÀÎÎÁÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÙÚÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÌÛ1 2 1 0Û 0.25 0 0 0Û · · · ·Ã0Î3ÎÎ3ί3ϯ0.25Î0Î1Î0Ý swap second row with ·(3)· ·Ã0Î2ÎÎ6ÎÎ2ϯ0.25Î1Î0Î0Ý pivot value row. · 2 · ·Û0 1 ¯1 ¯2Û¯0.25 0 0 1Û · 1 · ·ÀÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÙÚÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ1 2 1 0Û 0.25 0 0 0ÛÃ0Î1ÎÎ1ί1ϯ0.08333Î0Î0.3333Î0Ý divide second row by pivot value.Û0 2 6 2Û¯0.25 1 0 0ÛÛ0 1 ¯1 ¯2Û¯0.25 0 0 1ÛÀÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙÚÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ1 0 ¯1 2Û 0.4167 0 ¯0.6667 0Û subtract multiples of second row fromÛ0 1 1 ¯1Û¯0.08333 0 0.3333 0Û remaining rows to leave 0s in allÛ0 0 4 4Û¯0.08333 1 ¯0.6667 0Û off-diagonal rows of second column.Û0 0 ¯2 ¯1Û¯0.1667 0 ¯0.3333 1ÛÀÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙ332


Eliminate off-diagonal values from third column:ÚÎÎÎÎÎÂÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ1 0 ¯1 2Û 0.4167 0 ¯0.6667 0Û · · · ·Û0 1 1 ¯1Û¯0.08333 0 0.3333 0Û · · · ·Û0 0 4 4Û¯0.08333 1 ¯0.6667 0Û third col; pivot value is 4. · ·(4)·Û0 0 ¯2 ¯1Û¯0.1667 0 ¯0.3333 1Û · ·¯2 ·ÀÎÎÎÎÎÁÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙÚÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ1 0 ¯1 2Û 0.4167 0 ¯0.6667 0ÛÛ0 1 1 ¯1Û¯0.08333 0 0.3333 0ÛÃ0Î0ÎÎ1ÎÎ1ϯ0.02083Î0.25ί0.1667Î0Ý divide third row by pivot value.Û0 0 ¯2 ¯1Û¯0.1667 0 ¯0.3333 1ÛÀÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙÚÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ1 0 0 3Û 0.3958 0.25 ¯0.8333 0Û subtract multiples of third row fromÛ0 1 0 ¯2Û¯0.0625 ¯0.25 0.5 0Û remaining rows to leave 0s in allÛ0 0 1 1Û¯0.02083 0.25 ¯0.1667 0Û off-diagonal rows of third column.Û0 0 0 1Û¯0.2083 0.5 ¯0.6667 1ÛÀÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙEliminate off-diagonal values from fourth column:ÚÎÎÎÎÎÎÎÂÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ1 0 0 3Û 0.3958 0.25 ¯0.8333 0Û · · · ·Û0 1 0 ¯2Û¯0.0625 ¯0.25 0.5 0Û · · · ·Û0 0 1 1Û¯0.02083 0.25 ¯0.1667 0Û · · · ·Û0 0 0 1Û¯0.2083 0.5 ¯0.6667 1Û fourth col; pivot value is 1. · · ·(1)ÀÎÎÎÎÎÎÎÁÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙÚÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ1 0 0 0Û 1.021 ¯1.25 1.167 ¯3Û subtract multiples of fourth rowÛ0 1 0 0Û¯0.4792 0.75 ¯0.8333 2Û from remaining rows to leave 0s in allÛ0 0 1 0Û 0.1875 ¯0.25 0.5 ¯1Û off-diagonal rows of fourth column.Û0 0 0 1Û¯0.2083 0.5 ¯0.6667 1ÛÀÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙDrop leading identity matrix for inverse of original matrix:ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ 1.021 ¯1.25 1.167 ¯3ÛÛ¯0.4792 0.75 ¯0.8333 2ÛÛ 0.1875 ¯0.25 0.5 ¯1ÛÛ¯0.2083 0.5 ¯0.6667 1ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙ(muse:As supplied, the function is offensive to the functional programming puristbecause it uses destructive assignment:mat„¾© name matrix for updating.mat[¸ p;]„mat[p ¸;]© exchange ¸th and pth rows.mat[¸;]÷„mat[¸;¸] © reduce col diagonal to 1.For fun, we could recast it in a (non-destructive) purer form:gauss_jordan„{ŒML ŒIO„0© Gauss-Jordan elimination.elim„{ © elimination of row/col ¸.mask„¸=¼œ½¾© selection mask for ¸th row.pivt„{¾¼—/¾}|¾[;¸]ן\mask© position of pivot row.mat1„¸ pivt swap ¾© exchanged ¸th and pth rows.mat2„mat1÷[0]¾[pivt;¸]*mask © ¸th row divided by pivot.mat2-(mat2[;¸]×~mask)°.×mat2[¸;] © remaining rows reduced by pvt.}333


swap„{ © matrix ¾ with rows ¸ exchanged.i„¼œ½¾© index vector for rows.y n„1 0=›i¹¸© mask and not-mask for swap rows.¾[(n\n/i)+y\²y/i;]© merge with reversed rows.}}0::ŒSIGNAL ŒEN¸„=/†¼½¾(½¸)½(0 1×½¾)‡†elim/(²¼˜/½¾),›¾,¸© pass back error to caller.© id matrix for monadic case.© elimination/ ··· 2 1 0 (¾,¸)Further, we could remove square-bracket-indexing and represent our matricesas vectors-of-row-vectors:gauss_jordan„{ŒML ŒIO„0© Gauss-Jordan elimination.elim„{ © elimination of row/col ¸.mask„¸=¼½¾© selection mask for ¸th row/col.pivt„{¾¼—/¾}|(¸œ¨¾)ן\mask © position of pivot row.mat1„¸ pivt swap ¾© exchanged ¸th and pivot'th rows.mat2„mat1÷(pivt ¸œ¾)*mask © ¸th row divided by pivot.mat2-((¸œ¨mat2)×~mask)×›¸œmat2 © remaining rows reduced by pivot.}swap„{ © swap rows ¸ in matrix ¾.i„¼½¾© index vector for rows.y n„1 0=›i¹¸© mask and not-mask for swap rows.((n\n/i)+y\²y/i)œ¨›¾© merge with reversed rows.}0::ŒSIGNAL ŒEN¸„=/†¼½¾© pass back error to caller.© id matrix for monadic case.}(½¸)½(0 1×½¾)‡††elim/(²¼˜/½¾),›‡¾,¸ © elimination/ ··· 2 1 0 (¾,¸)The clinically obsessive would now be in a position to refine the <strong>functions</strong>till further by replacing local names with additional inner D-<strong>functions</strong> andoperators.Pursuing this approach to the edge of reason, we wind up with a functionthat is a single expression of <strong>functions</strong> and operators, with no assignmentsor guards. Here is the code for the monadic case (the dyadic equivalentreplaces (=/†¼½¾) with ¸ in the first line). The expression is strung outover a number of lines with some white space:334


{· (=/†¼½¾){· · (½¸)½(0 1×½¾)‡††{· · · ¸(· · · · (¸=¼½¾){· · · · · ¸(· · · · · · ¸¸{· · · · · · · ¾-(· · · · · · · · (¸œ¨¾)×~¸¸· · · · · · · )×›¸œ¾· · · · · · }· · · · · )¸(· · · · · · (· · · · · · · {¾¼—/¾}|(¸œ¨¾)ן\¸¸· · · · · · ){· · · · · · · (· · · · · · · · ¸ ¸¸{· · · · · · · · · ¸(· · · · · · · · · · (¼½¾){· · · · · · · · · · · †¾{· · · · · · · · · · · · (· · · · · · · · · · · · · (¾\¾/¾¾)+¸\²¸/¾¾· · · · · · · · · · · · )œ¨›¸¸· · · · · · · · · · · }¸¸/1 0=›¸¸¹¸· · · · · · · · · · }· · · · · · · · · )¾· · · · · · · · }¾· · · · · · · )÷(¸¸ ¸œ¾)*¾¾· · · · · · }¸¸· · · · · )¾· · · · }· · · )¾· · }/(²¼˜/½¾),›‡¾,¸· }¾}We can check that the coding is correct by pasting the lines into charactervariable gj_src, say, and then executing:)(Œio Œml) Œpp „ 0 4(–gj_src~Œtc,'·') 3 3½ 1 2 3, ¯3 1 5, 2 4 ¯10.4286 ¯0.2857 ¯0.1429¯0.1429 0.1429 0.28570.2857 0 ¯0.1429© condition environment.© apply function.Examples:Œ„mat„4 4½ 4 8 4 0, 1 4 7 2, 1 5 4 ¯3, 1 3 0 ¯24 8 4 01 4 7 21 5 4 ¯31 3 0 ¯2Œpp„4gauss_jordan mat1.021 ¯1.25 1.167 ¯3¯0.4792 0.75 ¯0.8333 20.1875 ¯0.25 0.5 ¯1¯0.2083 0.5 ¯0.6667 1© display numbers to 4 sig-figs.© matrix inverse.1 2 3 4 gauss_jordan mat © matrix divide.¯9.979 6.521 ¯2.813 2.792335


11(Žmat)­gauss_jordan mat © check against primitive matrix inverse.(1 2 3 4Žmat)­1 2 3 4 gauss_jordan mat © ditto matrix divide.© Using an order-¾ Hilbert matrix, we can see the slight variation between© primitive Ž and the D-function, as errors accumulate.hil„{÷1+°.+þ(¼¾)-ŒIO}© order-¾ Hilbert matrix.© The results are identical up to hil 5:0 1 0 disp †{(Ž¾)(gauss_jordan ¾)}°hil¨ 0 to 5ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ0 Û0 ÛÃÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÝÛ1 Û1 ÛÃÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÝÛ 4 ¯6 Û 4 ¯6 ÛÛ¯6 12 Û¯6 12 ÛÃÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÝÛ 9 ¯36 30 Û 9 ¯36 30 ÛÛ¯36 192 ¯180 Û¯36 192 ¯180 ÛÛ 30 ¯180 180 Û 30 ¯180 180 ÛÃÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÝÛ 16 ¯120 240 ¯140 Û 16 ¯120 240 ¯140 ÛÛ¯120 1200 ¯2700 1680 Û¯120 1200 ¯2700 1680 ÛÛ 240 ¯2700 6480 ¯4200 Û 240 ¯2700 6480 ¯4200 ÛÛ¯140 1680 ¯4200 2800 Û¯140 1680 ¯4200 2800 ÛÃÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÝÛ 25 ¯300 1050 ¯1400 630Û 25 ¯300 1050 ¯1400 630ÛÛ ¯300 4800 ¯18900 26880 ¯12600Û ¯300 4800 ¯18900 26880 ¯12600ÛÛ 1050 ¯18900 79380 ¯117600 56700Û 1050 ¯18900 79380 ¯117600 56700ÛÛ¯1400 26880 ¯117600 179200 ¯88200Û¯1400 26880 ¯117600 179200 ¯88200ÛÛ 630 ¯12600 56700 ¯88200 44100Û 630 ¯12600 56700 ¯88200 44100ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙ© However, at hil 6, owing to error accumulation,© small differences begin to appear:0 1 0 disp ® {(Ž¾)(gauss_jordan ¾)}hil 6ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÛ 36 ¯630.0000001 3360 ¯7560.000001 7560.000001Û ¯630.0000001 14700 ¯88200.00001 211680 ¯220500Û 3360 ¯88200.00001 564480.0001 ¯1411200 1512000 ¯Û¯7560.000001 211680 ¯1411200 3628800.001 ¯3969000.001 1Û 7560.000001 ¯220500 1512000 ¯3969000.001 4410000.001 ¯1Û¯2772.000001 83160.00002 ¯582120.0001 1552320 ¯1746360ÃÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÛ 36 ¯630 3360 ¯7560 7560.000001 ¯2772Û ¯630 14700 ¯88200.00001 211680 ¯220500 83160.000Û 3360 ¯88200.00001 564480 ¯1411200 1512000 ¯582120Û¯7560 211680 ¯1411200 3628800 ¯3969000 1552320Û 7560.000001 ¯220500 1512000 ¯3969000 4410000 ¯1746360Û¯2772 83160.00001 ¯582120 1552320 ¯1746360 698544.000ÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎSee also: rats.302 det.326 Cholesky.325336


ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎkcellrslt „ b (f ##.kcell) p© Relationship between point and k-cell.Supplied by Steve Mansour, this operator determines the relationship between apoint and a k-cell. For background, see Steve's paper Arithmetic Boundary Checking…abc„.For k=1, this is a line segment, (useful for input checking)k=2, this is a rectangle, (useful for checking cursor position in a window).k=3, this is a rectangular parallelepiped (brick) or cube,k=4, this is a hyperbrick or hypercube, etc.b: Left argument (bounds) is a numeric scalar, 2-vector or 2×k matrix; If b isa matrix, the rows represent the extreme points, (e.g. if k=2, the upperleft and lower right hand corners; the columns represent the lower / upperbounds in each dimension. Extreme points are indicated in the diagrams belowby 'µ'.p: Right argument (points) is any simple numeric array. If the left argument bis a scalar or 2-vector, each element of p is compared individually. If b isa matrix, the shape of the first axis of p must equal k--the number of columnsin b; each subvector in p represents the coordinates of a point in k-space.ÚÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛf: Operand Û × : signum product Û + : signum sum ÛÃÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÝÛResult: Û ¯1=Interior Û Unique -ive or +ive integer ÛÛ Û 0=Boundary Û representing a particular region ÛÛ Û 1=Outside Û in k-space. 0 always represents ÛÛ Û Û the interior. ÛÃÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÝÛb=scalar Û ¯1 0 1 Û ÛÛk=1 Û Û Same as (×) ÛÛRay Û Û ÛÃÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÝÛb=vector Û Û ÛÛk=1 Û 1 0 -1 0 1 Û ¯2 ¯1 0 1 2 ÛÛLine Û Û ÛÛSegment Û Û ÛÃÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÝÛ Û Û ¯12 ¯11 ¯10 ¯9 ¯8 ÛÛb=2×2 Û Û ÛÛmatrix Û 0…µ-----------. 1 Û ¯7 ¯6µ---¯5----¯4 ¯3 ÛÛk=2 Û | | Û | | ÛÛRectangle Û | -1 |„0 Û ¯2 ¯1 0 1 2 ÛÛ Û | | Û | | ÛÛ Û 1 '-----------µ Û 3 4----5----µ6 7 ÛÛ Û Û ÛÛ Û Û 8 9 10 11 12 ÛÃÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÝÛb=2×3 Û Û 62 ÛÛmatrix Û Û 6 ÛÛk=3 Û __0_________µ Û ¯19______‡___1____ µ31 ÛÛBrick Û /| ‡ /| Û /| ‡ /| ÛÛ(or cube) Û /_|__________/ | Û /_|______________/ | ÛÛ Û 1 | | -1 | | 1 Û ¯25…| 0 | | ÛÛ Û | |__________|_| Û | |______________|_|„29 ÛÛ Û 0…| / | / Û | / | / ÛÛ Û µ/___________|/ Û ¯31µ/___________†___|/ ÛÛ Û † Û † ¯1 ÛÛ Û1 0 Û ¯6 ÛÛ Û Û ¯62 ÛÀÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙ337


Examples:3 ×kcell 1 2 3 4 5 © Single Point Boundary (scalar).¯1 ¯1 0 1 12 4 ×kcell 1 2 3 4 5 © Upper and Lower Bounds (2-vector).1 0 ¯1 0 1© Differentiate between regions2 4 +kcell 1 2 3 4 5 © (signum sum).¯2 ¯1 0 1 2© Upper left and lower right handb„†(3 2)(5 6)© corners of a rectangle.© Various points in the plane© (2-space).© Positions: outside, boundary, int-© erior, outside, boundary, outside.© Positions: Below right, corner,© interior, below, edge, above.p„³†(6 8)(5 2)(4 4)(7 6)(3 5)(2 3)b ×kcell p1 0 ¯1 1 0 1b +kcell p12 4 0 11 ¯5 ¯10b3„2 3½0 0 0 10 10 10 © Coordinates of a cube.b3 ×kcell ³†(5 5 5)(11 15 20)(3 8 10)¯1 1 0© Inside, outside, boundary of cube.¯19¯61b3 +kcell 0 10 10b3 +kcell 5 0 0b3 +kcell 5 5 10© Top left rear corner of the cube.© Bottom Front Edge of the cube.© Top Face of the cube.b3 +kcell ³†(0 5 5)(2 3 4)¯25 0© Left Face, Interior of cube.See also: abc.320 kball.336ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎkballrslt „ {c„1} ##.kball p© Relationship between point and k-ball.Supplied by Steve Mansour, this function determines the relationship between apoint and a k-ball. For background, see Steve's paper Arithmetic Boundary Checking[abc].For k=1, this is a line segmentk=2, this is a circlek=3, this is a spherek=4, this is a hypersphere, etc.c: Left argument is a scalar or vectorFirst item of c is the radiusRemaining items are the coordinates of the center (default is origin)If left argument is not specified, it represents the unit ball centeredat the origin.p: Vector or matrixIf p is a k-vector it is the coordinates of a point in k-spaceIf p is a k×n matrix, each column represents the coordinates of a point338


slt: A scalar or vector of length n corresponding to the rows of pindicating the region to which it belongs as indicated in thediagram below:ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛÛÛ Outside (1) ÛÛ * * * ÛÛ Boundary (0) ÛÛ * * | ÛÛ Ÿ ÛÛ * * ÛÛÛÛÛÛ * * ÛÛÛÛ r ÛÛ ** * ÛÛ c ÛÛÛÛ * * ÛÛ Interior (-1) ÛÛÛÛ * * ÛÛÛÛ * * ÛÛÛÛ * * * ÛÛÛÛÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙExamples:5 kball 2 3 © Inside the circle.¯15 kball 3 4 © On the boundary.05 kball 5 6 © Outside the circle.15 1 2 kball 2 3, 4 6, ®9 9 © Radius 5; center at (1,2).¯1 0 1¯10113 kball 5 6 7 © Inside the sphere.13 kball 3 4 12 © On the surface.13 kball 6 8 12 © Outside the sphere.See also: abc.320 kcell.335 ksphere.337ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎkspherearea „ dim ##.ksphere radius© Hypersphere surface area.Inspired by Eugene McDonnell's paper [1], [ksphere] returns the surface area ofan ¸-sphere of radius ¾.NB: Wolfram [4] points out: "Unfortunately, geometers and topologists adopt incompatibleconventions for the meaning of "n-sphere," with geometers referringto the number of coordinates in the underlying space ("thus a two-dimensionalsphere is a circle," Coxeter 1973, p. 125) and topologists referring to thedimension of the surface itself". [ksphere] sides with the topologists so, here,we call a circle a 1-sphere or S1.339


Here are the surface areas of some unit hyperspheres. In particular, the "surfacearea" of a 1-sphere (circle) is its circumference.(1 to 10) ksphere 1 © surface of unit ¸-spheres.6.2832 12.566 19.739 26.319 31.006 33.073 32.47 29.687 25.502 20.725Notice that the area of a unit k-sphere achieves a maximum at around 6 dimensions.In his paper, Eugene poses the question: What dimension of space gives themaximum hypervolume to the unit radius hypersphere?As coded, [ksphere] is a continuous function over real ¸, so we can investigatenon-integral dimensions. Here is a crude Newton-Raphson technique for finding alocal maximum.max„{¸„ŒCT*÷2© Local maximum using Newton-Raphson.‘x„1+¯1 0 1׸© x deltas.¸¸{ ©‘‘x„¾×‘x© x-¹ x x+¹‘‘y„¸¸ ‘‘x© f(x-¹) f(x) f(x+¹)d1„÷š¯2-/†‘‘y ‘‘x © first difference.d2„÷/-/†d1(2†‘‘x) © second difference.‘„—/d1÷d2© increment f'(¾)÷f"(¾)‘=0:¾© approx convergence: done.’ ¾-‘ © ¾ … ¾ - f'(¾)÷f"(¾)}¾}Then:ksphere°1 max 66.256946087© approx maximum surface area of unit k-sphere.Seaching the Internet shows the maximum to be at dimension 6.2569464048605768 to17 sig figs. Wolfram Alpha [5] is particularly good for this sort of exercise.Notice that the volume of the (k+1)-ball inside the k-sphere is easily derivedfrom its surface area:kvol „ {¾×((¸-1) ksphere ¾)÷¸} © volume of ¸-ball of radius ¾.So to answer Eugene's question:kvol°1 max 55.256946138© approx maximum volume of unit k-sphere.(muse:Visualising Hyperspheres------------------------In general, we can construct n-sphere Sn by gluing together the surface(n-1)-spheres of two n-balls. Let's start with a familiar 2-sphere S2:Take a pair of 2-balls (flat circular discs) of thin rubber sheet and carefullyglue their outside (S1) edges together. Then inflate the enclosedspace to produce a regular 2-sphere. A Flatlander [7], living on the surfaceof S2, would perceive it as an unbounded, though finite, 2-universe.Ferdinand Magellan was in a similar position as he explored his finite butunbounded 2-sphere.Similarly, S1 may be constructed by gluing the endpoints of a pair of 1-balls (line segments) together and bowing the lines outwards to form acircle. A "Linelander", travelling around the circle, would not notice thetwo joining S0 points.340


We "3-landers" can build a 3-sphere by gluing the 2-sphere boundaries of apair of "adjacent" 3-balls (though we need to borrow a little 4-space inwhich to do the job). To make it easier, let's don scuba gear and swim insideone of a pair of massive 3-balls (reqular 3D balls) of sea-water, whichare suspended close to each other in 4-space. After our 4-lander friend hasglued together the outer 2-sphere-boundaries of our 3-balls (using specialtransparent sea-water adhesive) we can swim from our home hemiball, straightahead in any direction, into the other hemiball. If the sea-water gluereally is transparent, we should not notice as we swim through the 2-spherejoin. Again, we're in an unbounded manifold: even though we are within afinite volume of water, no matter how far we swim in any direction, we willnever encounter a boundary.NB: Before using a harpoon gun, please heed the warning, which is towardsthe end of the notes on …life„, about using artillery in a finite manifold.The Poincaré Conjecture-----------------------Imagine a 2-dimensional (Flatland) spider wandering around in the surface ofa large soap bubble. To amuse herself in this bleak landscape she plays alittle game: as she moves, she extrudes a single filament of web, which is,of course, also embedded in the surface of the S2 bubble. Her game is toroam around her 2-sphere looking for the starting end of the filament and,when she finds it, to reel it in. As she is holding both ends of the filament,topologically speaking, it forms a circle S1. Our spider finds thatshe can _always_ reel in her web-loop and so she convinces herself that shemust be in the surface of a sphere, rather than, for example, in the surfaceof a more exotic 2-manifold, such as a torus (S1×S1).We can play the same game in our sea-water 3-sphere: we swim forwards whileuncoiling our wreck-diving rope, leaving one end at a fixed position in the3-water. We find that, after swimming straight ahead in any direction for adistance of ±2×¾, the end of the rope hoves into view again. Now, if we grabboth ends of the rope and start to pull, we should be able to reel in thewhole of the loop without its becoming tight.By analogy with the flat-spider in the surface of torus S1×S1, we might notalways be able to reel in our rope had we found ourselves swimming, for exampleinside S1×S1×S1, which is made by gluing together opposite faces of a_cube_ of sea-water.It has long been assumed that a 3-sphere is the only 3-manifold in which onecan always reel in the rope-loop in this way. This assumption is known asthe "Poincaré Conjecture" and a proof of it, which carried a million-dollarreward, eluded mathematicians for the whole of the twentieth century. Theconjecture was proved in 2002 by Grigori Perelman, building on work by RichardHamilton. See ref[8] below.Explore 3-manifolds by downloading this magnificent hyper-flight-simulator:http://www.geometrygames.org/CurvedSpaces/index.html)(muse: At a picnic, never let a topologist slice the loaf.)Technical note:As [ksphere] utilises only scalar pervasive <strong>functions</strong>, it is itself scalar pervasive.This means that it may be applied directly between conformable argumentsof higher rank and depth.341


Refs:[1] http://www.jsoftware.com/papers/eem/storyofo.htm[2] http://en.wikipedia.org/wiki/Deriving_the_volume_of_an_n-ball[3] http://en.wikipedia.org/wiki/Hypersphere#cite_note-0[4] http://mathworld.wolfram.com/Hypersphere.html[5] http://www.wolframalpha.com[6] http://www.geometrygames.org/CurvedSpaces/index.html[7] http://en.wikipedia.org/wiki/Flatland[8] http://en.wikipedia.org/wiki/Poincare_conjectureExamples:Œpp„5© 1-sphere is a circle:1 ksphere 10 © circumference of circle, radius 10.62.8322×± 10 © compare with: 2×Pi×r.62.832© 2-sphere is a reqular sphere in 3-space:2 ksphere 10 © surface area of sphere, radius 10.1256.64×± 10*2 © compare with: 4×Pi×r-squared.1256.6(0 to 10) ksphere 1 © surface of unit ¸-spheres.2 6.2832 12.566 19.739 26.319 31.006 33.073 32.47 29.687 25.502 20.725kvol „ {¾×((¸-1) ksphere ¾)÷¸} © volume of ¸-ball of radius ¾.(0 to 10) kvol 1 © volumes of unit ¸-balls.2 3.1416 4.1888 4.9348 5.2638 5.1677 4.7248 4.0587 3.2985 2.5502 1.8841See also: kball.336 to.316 life.446ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎmeannum „ ##.mean nvec© Arithmetic mean.An illustration of local definitions.NB: From <strong>Dyalog</strong> V14, this function can be coded as the fork:mean „ +š ÷ »© mean along first axisExample:mean 1 2 3 42.5square „ *°2sqrt „ *°0.5stdev „ {sqrt(mean square ¾)-square mean ¾}© standard deviation.Œpp„5stdev 2 2 20stdev 1 2 30.8165342


© Also:stdev „ sqrt(mean°square - square°mean) © ditto using trainmean „ +.÷°½þmean „ {1÷.ƒ¾(¾=¾)}mean „ {¾Ž¾=¾}mean „ {Ž/¾°*¨1 0}mean „ Ž°(=þ)þmean „ € Ž =þ© (P.Last)© (G.Streeter <strong>Dyalog</strong>'14)© (T.Seppälä)© (R.Hui)© (R.Hui)© same idea using forkÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎNormRanddistribution „ average + standard_deviation × ##.NormRand (shape)From Nicolas Delcros, who says:Produces random numbers with a normal distribution, that is centered around zerowith a unitary standard deviation, so that, as the number of samples rises, thedistribution will tend towards a normal gaussian curve. Normal distributions arehelpful to model natural random variables.See: http://en.wikipedia.org/wiki/Box_mullerExamples:{+/¾÷½¾}¨NormRand¨10*¼5 © average tends towards 0¯0.46239003 0.2586531459 0.02013158866 0.003016077943 0.0009350952811{(+/¾*2)÷½¾}¨NormRand¨10*¼5 © standard deviation tends towards 10.431348813 0.8883835515 0.9924045046 0.9891854881 1.004654056ŒUSING„',sharpplot.dll'sp„ŒNEW Causeway.SharpPlotsp.HistogramStyle„Causeway.HistogramStyles.(NormalCurve+SDev1)sp.ClassInterval„0.1sp.DrawHistogram ›NormRand 1000(ŒNEW Causeway.SharpPlotViewer sp).Show «index: distribution, normal|randomindex; Box G.E.P|Muller M.E.|Delcros N.ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎphinarypnum „ {fmt„1} (##.phinary) nums © Phinary representation of numbers ¾.phinary 4101.01© A "phinary" number.Phi "The Golden Mean" has many interesting properties. A rectangle with sides ofratio Phi:1 is considered to have a particularly pleasing shape and appears inmany classical works of art. Appending a square to this rectangle produces alarger rectangle, whose sides are also in the ratio Phi:1.343


Therefore:ÚÎÎÎÎÎÎØÎÎÎÎÎÎÌÚÎÚÎÎÎÎÎÎÎÎÎÎÎÎÎÌÎÌÛ ÛÛ ÛÛ Û Û 1Ø ÛÛ Û+ ÃÎÎÎÎÎÎÎÎÎÎÎÎÎÝÎÝ1 Û Û Û Golden RectanglesÛ ÛÛ ÛÛ Û Û Ø Ø+1 ØÛ Û Û Û --- = ---Û Û Û Û Ø 1Û ÛÛ ÛÀÎÀÎÎÎÎÎÎÎÎÎÎÎÎÎÙÎÙÀÎÎÎÎÎÎØÎÎÎÎÎÎÙ(Ø*2) = Ø+1 © from above. [1]… 0 = (Ø*2) + (-Ø) + ¯1 © by rearranging terms.… 0 = ؃1 ¯1 ¯1 © from definition of ƒ.Solving this quadratic equation in Ø, with coefficients 1 ¯1 ¯1, yields a positiveroot (see …roots„) of (1+(1-¯4)*0.5)÷2 or (0.5×1+5*0.5), giving Phi a valueof:1.61803398874989484820458683436563811772030917980576286213544862270526046...See: http://en.wikipedia.org/wiki/Golden_ratioUsing Phi as a number base--------------------------We are accustomed to representing rational numbers using various integral basessuch as binary, octal, hexadecimal and, of course, regular decimal. See …ary„.(5/2) ‚ 19 © base-2 encode (binary).1 0 0 1 1(5/3) ‚ 19 © base-3 encode (ternary).0 0 2 0 1Bases could also be non-integral rational numbers:(5/7÷3) ‚ 19 © base-7÷3 encode.0 1 0.6666666667 1 0.3333333333or even irrational numbers:(5/±1) ‚ 19 © base-Pi encode.0 0 1 2.858407346 0.1504440785In particular Phi may be used as a number base:Ø „ 0.5×1+5*0.5© Phi is "root five plus one over two".(5/Ø) ‚ 19© base-Ø encode.1 1.381966011 1.145898034 1.291796068 1.201626124Positional number systems tend to have a "canonical" or "normal" form. For example,when using decimal notation, we prefer "forty-two" to "thirty-twelve",and 42.0 to 41.99...A normal form for phinary numbers suggests that:344[a] Only digits 1 and 0 be used.


[b] There be no adjacent 1 digits.Notice that, in phinary, 100 = 011: [2]100 © [base Ø]… Ø ƒ 1 0 0 © defn of base… (Ø*2) + 0 + 0 © defn of ‚… 0 + Ø + 1 © from [1] above.… Ø ƒ 0 1 1 © defn of ‚… 011 © [base Ø]Of course, we can multiply both sides of an equation by any constant, includinga power of Phi, so:100=011 => 1000=0110 => 1.00=0.11 => 0.1=0.011 => ...This gives us a rule for addition of phinary numbers in normal form:1 + 1… 1 + 1.00 © ¾ = ¾.00..… 1 + 0.11 © from [2] above… 1.11 © ..1.. + ..0.. … ..1..… 1.10 + 0.01 © ..1.. + ..0.. … ..1..… 10.00 + 0.01 © from [2]… 10.01 © ..1.. + ..0.. … ..1..Arranged in a traditional tableau:1.001.00 +-----10.01-----Notice how addition overflow causes a "carry" to propogate both one place to theleft AND two places to the right!From this, it is clear that successive natural numbers, generated by adding 1 tothe previous number, each has a finite number of phinary digits. In other words,natural phinary numbers all have a finite representation, despite being the sumsof powers of an irrational base.0 01 12 10.013 100.014 101.015 1000.10016 1010.0001See http://en.wikipedia.org/wiki/PhinaryFunction [phinary] takes a numeric right argument and returns its "phinary" representation,in normal form, as character vectors of '0' and '1' digits, togetherwith a phinary point where necessary. For example:phinary 4210100010.00100001© phinary from decimal.If optional left argument [fmt] is passed as 0, the formatting is suppressed anda vector of powers of Phi is returned:0 phinary 42 © raw powers of phi.7 5 1 ¯3 ¯8345


42Ø +.* 7 5 1 ¯3 ¯8 © reconstituted decimal number.[phinary] is a self-inverse (or "involution") in that:¾ ­ (phinaryÿ2) ¾ © self-inverse: phinaryÿ2 „… €42phinary'10100010.00100001'© decimal from phinary.The round-trip, applied to non-normal phinary numbers, returns the normal form:phinaryÿ2 ,'111.111' '222'1010.1 10101© normal form of phinary numbers.The phinary representation of numbers with components that are exclusively nonnegativepowers of Phi, have no '1's to the right of the phinary point:phinary Ø +.*¨ (2 4)(3 5)10100 101000© powers of Phi => clean phinary.whereas, apart from 0 and 1, regular counting numbers, expressed in phinary, includecomponents that are negative powers of Phi. This means that such numbersalways have '1's to the right of the phinary point:phinary 24 351001010.000101 10001010.00001001© counting numbers => scruffy phinary.(muse:This raises the question: what constitutes a "whole" or "natural" phinarynumber? Is it:[a] those numbers with only zeros to the right of the point, or is it[b] those that are conversions of decimal whole numbers into phinary?The answer is that the concept of "natural number" is deeper than its representationin any particular base. Such numbers have the property thatthey are closed under addition: adding any two produces a third as result.We can test which of the above sets of numbers is "natural", geometrically,using a rule and compass (if we accept compass steps as a model for addition).0 1 10 100 101 1000 1001 1010 10000Û Û Û Û Û Û Û Û ÛÃÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÁÎÎÎÂÎÎÎÎÎÁÎÎÎÂÎÎÎÎÎÁÎÎÎÂÎÁÎÎÎÎÎÎÎÂÎÁÎÎÎÎÎÁÎÂÎÎÎÎÎÎÎÁÎ...Û Û Û Û Û Û Û0 1 10.01 100.01 101.01 1000.1001 1010.0001... so the evenly spaced members of the second set (0 1 10.01 100.01 ...)are the natural numbers, despite their untidy appearance.)Perhaps, in this context, there is a distinction between whole- and naturalnumbers.Ref:http://www.maths.surrey.ac.uk/hosted-sites/R.Knott/Fibonacci/phigits.htmlhttp://www.goldennumber.netExamples:phinary 1 2 3 41 10.01 100.01 101.01346© some small phinary numbers.


align„{(-°(—/)þ¾¼¨'.')²†¾} © align '.'s in char matrix.,°align°phinaryþ ¯4 to 10¯4 ¯101.01¯3 ¯100.01¯2 ¯10.01¯1 ¯10 01 12 10.013 100.014 101.015 1000.10016 1010.00017 10000.00018 10001.00019 10010.010110 10100.0101© integers with their phinary equivalents.phinary 3÷17© rational number (non-terminating).0.000100010100001010100101000001001000000100010100001010100101000001001phinary 2*÷2© irrational number (non-terminating).1.010000010100101001000000010100000000010101010101010010000000101Ø „ +°÷/40/1phinary Ø*¯3 to 30.001 0.01 0.1 1 10 100 1000© Phi from continued fraction …cfract„.© powers of Phi have simple phinary reps.1Ø ­ +°(*°0.5)/0,40/1 © Phi ­ sqrt 1 + sqrt 1 + ... sqrt 1pcan „ phinaryÿ2© round-tripping produces canonical form.pcan '111.111'1010.1© canonical form.{†¾(pcan ¾)},\9/'1'© non- and canonical forms.1 11 111 1111 11111 111111 1111111 11111111 1111111111 100 1001 10100 101001 1010100 10101001 101010100 1010101001See also: ary.317 ratrep.556 ratsum.308 bt.258 mayan.465 hex.286See also: eval.dws/notes.bta eval.dws/notes.sbaSee also: nats.290 rats.302 fibonacci.279See also: numbers.551ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎrootnum „ {num„2} ##.root num© ¸'th root.An illustration of the default left argument construct.Examples:84root 64© square root.3 root 64 © cube root.347


ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎrootsnvec „ ##.roots triple© Real roots of quadratic.An illustration of a 'typical' D-function:roots„{a b c„¾d„(b*2)-4×a×c© Real roots of quadratic.© Coefficients.© Discriminant.}d0:(-b+¯1 1×d*0.5)÷2×a© No roots© One root© Two rootsNB: From <strong>Dyalog</strong> V13, this function can be recoded so that it always returns two,possibly complex, roots:thenroots„{a b c„¾d„(b*2)-4×a×c(-b+¯1 1×d*0.5)÷2×a}roots 1 2 3¯1J1.414213562 ¯1J¯1.414213562© Roots of quadratic.© coefficients.© discriminant.© both roots.Example:roots 2 1 ¯31 ¯1.5ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎcxdraw{mbrot„0}(cxfn ##.cxdraw) zoom© Complex function drawing.A tool for visual exploration of complex function [cxfn]. For example:*°0.5 cxdraw 2 © explore complex square root.NB: The operand function is called with a single complex point as argument andmust return a complex point as result; a multiple-valued function, suchas '¾+2 3', won't work.Right argument [zoom] determines the part of the complex plane that is visiblein the GUI window. For example, ...cxdraw 8 shows a square of "radius" 8, withcorners at ¯8j8 and 8j¯8. Real and imaginary axes and the unit circle are markedon the plane.Drawing:Mark: Double-click to draw domain (blue) and range (red) markers.Draw: Click and hold Left button to draw.Clear: Click Right button to clear.Quit: Press or close window to quit.As you hold down the left mouse button and draw, the function's domain path istracked in blue and its corresponding range path is calculated and drawn in red.It is informative to draw small circles crossing any branch cuts of the operandfunction.Notice that, while drawing, the GUI form's caption displays the complex coordinatesof current domain and range.348


Continuity----------Domain points that are close to, but which straddle a branch cut, map to (red)range points that are typically far apart. It is less distracting if the functionrefrains from connecting range points on either side of such a discontinuity.An example might be the square-root function ¾*÷2: as the domain crossesthe negative real axis, the range flips to its conjugate (mirror-image) point onthe other side of the real axis.We avoid this effect by looking at the _differential_ of the blue and red linesand by refusing to draw segments of the red line that correspond to a slope ofmore than an arbitrary limit (say 100). We sample the slope at a number (100) ofpoints along the blue and red lines.Ideally, we should compare the ratio of the _lengths_ of these "delta" sections:where:length„{+šunder(*°2)2-/zg ¾} © length of line segment at ¾.under„{¾¾ÿ¯1 ¸¸ ¾¾ ¾}© aka "dual" see …pow„.but for this exercise, the distance around two sides of the bounding rectangle+/|2-/[1]†rng domis considerably quicker to calculate and is accurate enough.ÚÎÎÎÎÎÎÎÎÎΰz+‘zÛ ./Û|Û ./ Û|Û ./ „ÎÎÛ|ÎÎÎ real length of line segment [z, z+‘z].Û ./ Û|Û./ Û|ÎÌz°ÎÎÎÎÎÎÎÎÎÎÙ/ Û¯¯¯¯¯¯¯¯¯¯¯ ÛÀÎÎÎÁÎ "good-enough" length of line segment [z, z+‘z].Mandelbrot mode---------------If optional left argument [mbrot], default 0, is set, only mouse movements aredetected and button clicks are ignored. In this mode, for each MouseMove event,we:Set the value of ¸ to the new position of the mouse cursor.Set temp variable z to 0.Apply expression (z„¸ cxfn z) a large (10) number of times. Then,If z is still within the square ¯2J2..2J¯2draw a dot at ¸; otherwise, don't.Using [cxfn] +°(×þ) reveals an approximation to the Mandelbrot set: by movingthe mouse, shade the region around the unit circle as if shading with a pencilon a piece of grease-spotted paper. In particular, by shading more thoroughly,discover the _boundary_ of the revealed figure.http://en.wikipedia.org/wiki/Mandelbrot_setTechnical note: the above iteration is coded using the power operator ÿ:to„,mapÿ10þzg†,‡y x© after 10 iterations.where:y and x are the GUI window coordinates,zg translates these coordinates to complex number (z) andmapÿ10 applies cxfn ten times.349


Notice that monadic commute þ starts the iteration with z„¸, rather than at z„0,but, in the case of the mandelbrot expression, this just saves one iteration.(Perhaps this technique might be extended to investigate the more general Juliaand Fatou sets http://en.wikipedia.org/wiki/Julia_set).Technical note:Notice, with the function that maps a GUI coordinate to a complex number, ratherthan using an easier-to-read dfn:zg„(¸÷100÷2 ¯2)°{†¸×‡´³¾-50}© scale: complex from gui coords.it is coded instead as a more obscure derived function:zg„†°((¸÷100÷2 ¯2)°×)°‡°(-°50)°´°³© scale: complex from gui coords.This is so that we can _generate_ zg's inverse directly (as zgÿ¯1), rather thanhaving to code a separate explicit inverse function. In fact, it is convenientto supply an "under" operator, which applies its left operand _under_ the effectof its right operand.under„{¾¾ÿ¯1 ¸¸ ¾¾ ¾}© aka "dual".Thanks to Giangluigi Quario for help with the GUI.Examples:+ cxdraw 2 © complex conjugate (horizontal mirror-image).*°0.5 cxdraw 2 © complex square root (investigate branch cut).8°± cxdraw 2 © Pythagorian function (investigate both branch cuts).* cxdraw 8 © complex exponential (find 4 "fixpoints", where z­*z).*°± cxdraw 2 © see that *±0j1 … ¯1 (Euler).{+/×þ1 2±¾}cxdraw 2 © sin-squared + cos-squared (watch form Caption).0j1°* cxdraw 2© see that 0j1*0j1 is a real(!) number.÷ cxdraw 2 © complex reciprocal (maps until circle inside out).+°(×þ)cxdraw 2© mandelbrot mode: try shading in the region 2>|¾.ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎpolarto „ {dirn„1} ##.polar fm© Polar from/to cartesian coordinates.[to] and [fm] are corresponding arrays of shape (2,S), where pairs along thefirst axis represent either cartesian and polar coordinates.Coordinate pairs are arranged along the _first_ axis.The optional left argument determines the direction of translation:1 polar ... © polar from cartesian coordinates.¯1 polar ... © cartesian from polar coordinates.NB: The phase angle for polar coordinates is in the range: ±0 2.NB: The polar equivalent of cartesian (0 0) is undefined. This implementationarbitrarily chooses to map it to (0, ±1).350


Technical notes:¯1°polar is straightforward but 1°polar has a couple of tricky areas.In general, the phase angle for cartesian (x y) is (¯3±y÷x). However, if x=0, adomain error is generated, so we must take steps to avoid such values:atan„¯3±y÷x+x=0© arctan y÷x (avoiding y÷0).and to return results ±1÷2 and ±3÷2 for +ive and -ive values of y, respectively.Secondly, ¯3± returns values in the range ±÷¯2 2 (+/- pi-by-two). Using the signof the cartesian coodinates, we map this value onto a range 0 ˆ< ±2.ÚÎÎÎÎÂÎÎÎÎÂÎÎÎÎÌy>0Ûa+±1Û±1÷2Û a Û where a„¯3±y÷xÃÎÎÎÎÏÎÎÎÎÏÎÎÎÎÝy=0Ûa+±1Û(±1)Û a ÛÃÎÎÎÎÏÎÎÎÎÏÎÎÎÎÝy


ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎxpowerdigits „ digits ##.xpower number© Fast multi-digit power using FFT.From Mike Day, [xpower] builds on Roger Hui's …xtimes„ to provide ¸*¾ for multidigitnumbers ¸.Left argument [digits] is a scalar or vector of decimal digits. Right argument[number] is a single whole number.Technical note:[xpower] uses "repeated squaring" to minimise the number of multiplications.See: http://www.jsoftware.com/jwiki/Essays/Repeated%20SquaringExamples:2 xpower 16 © 2*166 5 5 3 61 6 xpower 4 © 16*46 5 5 3 62 xpower 641 8 4 4 6 7 4 4 0 7 3 7 0 9 5 5 1 6 1 6†{ŒD[¾+ŒIO]}¨ 2 xpower¨2*0 to 8 © powers of powers of 2.241625665536429496729618446744073709551616340282366920938463463374607431768211456115792089237316195423570985008687907853269984665640564039457584007913129639936See also: xtimes.350 nats.290ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎxtimesz„x ##.xtimes y© Fast multi-digit product using FFT.0. IntroductionFFT is used to provide an O(n×µn) algorithm for the convolution of two vectors(polynomial multiplication), which is then used to implement a fast multiplicationfor integers with an arbitrary number of digits. The ideas and code werepresented by Henry Rich in the Jwiki essay FFT on 2010-12-27, here translatedfrom J to <strong>Dyalog</strong> <strong>APL</strong>. See: http://www.jsoftware.com/jwiki/Essays/FFTIn these notes, Œpp„6 and Œio„0 .1. ConvolutionConvolution (polynomial multiplication) can be coded succinctly:convolve„{+š(-¼½¸)²¸°.×¾,0×1‡¸}x„9 3 5 8 1 0 5y„6 2 3 7 4x convolve y54 36 63 130 94 73 109 49 19 35 20352


convolve works by summing the antidiagonals of x°.×y , that is, summing the elementsof x°.×y having like indices in (¼½x)°.+¼½y , resulting in a vector with¯1+(½x)+½y elements.(x°.×y) ' ' ((¼½x)°.+¼½y)54 18 27 63 36 0 1 2 3 418 6 9 21 12 1 2 3 4 530 10 15 35 20 2 3 4 5 648 16 24 56 32 3 4 5 6 76 2 3 7 4 4 5 6 7 80 0 0 0 0 5 6 7 8 930 10 15 35 20 6 7 8 9 10convolve takes time of order (½x)×(½y) , making it impractical on large arguments(longer than 1e5 , say).2. FFTA faster convolution obtains by use of FFT (fast Fourier transform). FFT convertsa polynomial represented by its coefficients into its value at n points,here the n roots of unity, and the inverse FFT converts from the n points backinto coefficients. The important properties are that¸ convolve ¾ „… iFFT (FFT ¸) × (FFT ¾)and that FFT and iFFT are computed in O(n×µn) time (justifying the moniker"fast").The key computation in FFT (and iFFT) is:floop„{(•/¸)’ÿ(×m)€(+š¾),[m-0.5]¸×[¼m„«½½½¸]-š¾}The right argument is a hypercube initially constructed from the argument ¾ toFFT as (r½2)½¾ where r„2µ«½½¾ . floop applies to the hypercube r times, to eachof the axes in order. Let p„¯1*2÷2*r be a primitive root of unity of order 2*r.The left argument is the hypercube p*(2*k)×s½¼×/s„2½þ(r-1)-k on the k-th applicationof floop . Equivalently, the initial left argument is p*s½¼×/s„(r-1)½2 andthe next left argument obtains from the current one by •/¸ .x9 3 5 8 1 0 5y6 2 3 7 4iFFT (FFT 16†x) × (FFT 16†y)54J¯9.32587E¯15 36J¯3.51108E¯15 63J¯6.38378E¯15 ...x rconvolve y54J¯9.32587E¯15 36J¯3.51108E¯15 63J¯6.38378E¯15 ...˜0.5+9± x rconvolve y54 36 63 130 94 73 109 49 19 35 20x convolve y54 36 63 130 94 73 109 49 19 35 20Because rconvolve is mathematically (if not numerically) equivalent to convolve,the application of 9± to its result is justified when the arguments are real andof ˜0.5+ when the they are integral.3. Integer Multiplication353


The convolution of x and y are the digits of their product when x and y are interpretedas vectors of digits. The convention here is that the digits are listedfrom most significant to least significant. For example, the number 3142 isrepresented by 3 1 4 2 . Base 10 is used here but other bases are possible.It remains to convert the result into standard form, with each element less thanthe base. If carry performs one step of propagating the carries, then the limitof its application is the desired computation.x9 3 5 8 1 0 5y6 2 3 7 4Œ„t„˜0.5+9± x rconvolve y54 36 63 130 94 73 109 49 19 35 20carry 0,t5 7 12 16 9 11 13 13 10 12 7 0carry carry 0,t5 8 3 6 10 2 4 4 1 2 7 0carry carry carry 0,t5 8 3 7 0 2 4 4 1 2 7 0carry carry carry carry 0,t5 8 3 7 0 2 4 4 1 2 7 0carryÿ­ 0,t5 8 3 7 0 2 4 4 1 2 7 0x xtimes y5 8 3 7 0 2 4 4 1 2 7 0' '~þ•x xtimes y583702441270{Œpp„18 ª •¾} 9358105 × 62374583702441270s t „ ‡ ? 2 1.5e4½10s xtimes time t00.296xtimes has the potential to multiply numbers with over a million digits in undera minute. The function as written is constrained by the fact that in <strong>Dyalog</strong> <strong>APL</strong>the maximum rank of an array is 15, so that the maximum product can have only2*15 or 32768 digits.4. Collected DefinitionsThe presentation here favors terseness and clarity over efficiency. Some possibleimprovements are described in the Jwiki essay. (For example, computing theroots of unity just once rather than four times.)convolve„{+š(-¼½¸)²¸°.×¾,0×1‡¸}354


xtimes„{roots „ {×\1,1‡(¾÷2)½¯1*2÷¾}cube „ {¾½þ2½þ2µ½¾}extend „ {(2*—2µ¯1+(½¸)+½¾)†¨¸ ¾}floop „ {(•/¸)’ÿ(×m)€(+š¾),[m-0.5]¸×[¼m„«½½½¸]-š¾} © FFT „ { ,(cube roots ½¾)floop cube ¾}iFFT „ {(½¾)÷þ,(cube +roots ½¾)floop cube ¾}rconvolve „ {(¯1+(½¸)+½¾)†iFFT œ×/FFT¨¸ extend ¾}carry „ {1‡+š1 0²0,0 10‚¾}(+/^\0=t)‡t„carryÿ­0,˜0.5+9± ¸ rconvolve ¾}Ref: http://www.jsoftware.com/jwiki/Essays/FFTSee also: nats.290 big.257 xpower.350ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎDatesÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎDate Conversion and FormattingÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎFunctions …days„ and …date„ convert between ŒTS format and the number of dayssince 1899-12-31 00:00:00 (sometimes called "International Day Number").…timestamp„ prefixes a character vector message with an ISO-standard(ish) dateand time. (ISO puts a 'T' between date and time).Œts2000 12 25 13 48 52 0© Time now.days Œts © IDN: Days since 1899-12-3136884.58333date 36884.617292000 12 25 14 48 53 856© Date from day number.1Œts­date days Œts© Full circle.2000 12 25 14 48 46 timestamp 'Now' © Formatted date.2000-12-25 14:48:46 NowA complication that arises with converting historical dates is the change fromthe Julian to the …Gregorian_calendar„.We can make a ŒTS formatter by composing function …timestamp„ with null:show„timestamp°''show Œts2000-12-25 14:15:44© Time now.Timestamps on file components are in 60th of a second since 1970-01-01. Thefollowing function converts Œfrdci time into day number. Notice that the constants(days 1970 1 1) and (÷×/1 3/24 60) are evaluated at definition time andbound as operands to the derived function.compidn„(days 1970 1 1){¸¸+¾¾×(Œio+2)œŒfrdci ¸ ¾}(÷×/1 3/24 60)show date 1 compidn 3 © Write-time: fnum 1, component 3.2000-12-25 14:09:16disp Œcr'compidn'© Canonical rep of derived function.Ú…ÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ25568Û{¸¸+¾¾×(ŒIO+2)œŒFRDCI ¸ ¾}‡1.929012346E¯7ÛÀ~ÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…Á~ÎÎÎÎÎÎÎÎÎÎÎÎÎÙ355


Here's a handy little function to return day-of-week from a ŒTS-type argument:dow„{(Œio+7|˜days ¾)œ'Sun' 'Mon' 'Tue' 'Wed' 'Thu' 'Fri' 'Sat'}Fridow Œts© TGI Friday!Note that 1899-12-31 00:00:00 is an _arbitrary_ choice of "epoch" selected fordate representation with the ŒSM/ŒSR character-based screen manager. We caneasily compose <strong>functions</strong> based on other starting points:The Julian epoch started at noon on Jan 1st, ¯4712:days_julian „ 2415019.5°+°(15821004°days)date_julian „ ¯115860°date°(-°2415019.5)© "Julian Days".days_mjd „ 15019°+°(15821004°days)date_mjd „ ¯115860°date°(-°15019)© "Modified Julian Days".unix_time „ 86400°×°(-°25568)°days © Secs since 1970-01-01 00:00:00.unix_date „ date°(+°25568)°(÷°86400)long_count „ mayan°(1830735°+°days)days_excel_1900 „ 1°+daysdate_excel_1900 „ date°(-°1)days_excel_1904 „ 1461°+daysdate_excel_1904 „ date°(-°1461)© Mayan Long Count (584,285 corr.).© Excel 1900 date system.© Excel 1904 date system.See also: days.356 date.358 cal.354 timestamp.178 mayan.465 easter.359 compidn.3See also: Gregorian_calendar.599 British_Calendar_Act_1751.598ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎcalcalendar „ ##.cal date© Calendar.[cal] is an emulation of Unix shell command cal(1). Right argument [date] may beone of:yyyy © year, eg: 1986yyyy mm © year and month, eg: 2009 12mm © relative month, 0 means current month, ¯1 means last month ...[cal] distinguishes the "yyyy" and "mm" cases on range. If the argument is asingle number in the range ¯12 to 12, it is interpreted as a relative month.Otherwise, it is taken as a year. This means that [cal] cannot return a calendarfor the years ¯0012 to 0012.Requires: …date„ …days„Examples:cal 0December 2009Su Mo Tu We Th Fr Sa1 2 3 4 56 7 8 9 10 11 1213 14 15 16 17 18 1920 21 22 23 24 25 2627 28 29 30 31© current month356


cal ¯1 © last monthNovember 2009Su Mo Tu We Th Fr Sa1 2 3 4 5 6 78 9 10 11 12 13 1415 16 17 18 19 20 2122 23 24 25 26 27 2829 30cal 2February 2010Su Mo Tu We Th Fr Sa1 2 3 4 5 67 8 9 10 11 12 1314 15 16 17 18 19 2021 22 23 24 25 26 2728cal 1985 2February 1985Su Mo Tu We Th Fr Sa1 23 4 5 6 7 8 910 11 12 13 14 15 1617 18 19 20 21 22 2324 25 26 27 28cal 1752 09September 1752Su Mo Tu We Th Fr Sa1 2 14 15 1617 18 19 20 21 22 2324 25 26 27 28 29 30© the month after next.© calendar for specific month.© Sept 1752 was a short month in Merrie England.cal 2010© calendar for a specific year.2010January February MarchSu Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa1 2 1 2 3 4 5 6 1 2 3 4 5 63 4 5 6 7 8 9 7 8 9 10 11 12 13 7 8 9 10 11 12 1310 11 12 13 14 15 16 14 15 16 17 18 19 20 14 15 16 17 18 19 2017 18 19 20 21 22 23 21 22 23 24 25 26 27 21 22 23 24 25 26 2724 25 26 27 28 29 30 28 28 29 30 3131April May JuneSu Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa1 2 3 1 1 2 3 4 54 5 6 7 8 9 10 2 3 4 5 6 7 8 6 7 8 9 10 11 1211 12 13 14 15 16 17 9 10 11 12 13 14 15 13 14 15 16 17 18 1918 19 20 21 22 23 24 16 17 18 19 20 21 22 20 21 22 23 24 25 2625 26 27 28 29 30 23 24 25 26 27 28 29 27 28 29 3030 31July August SeptemberSu Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa1 2 3 1 2 3 4 5 6 7 1 2 3 44 5 6 7 8 9 10 8 9 10 11 12 13 14 5 6 7 8 9 10 1111 12 13 14 15 16 17 15 16 17 18 19 20 21 12 13 14 15 16 17 1818 19 20 21 22 23 24 22 23 24 25 26 27 28 19 20 21 22 23 24 2525 26 27 28 29 30 31 29 30 31 26 27 28 29 30357


October November DecemberSu Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa1 2 1 2 3 4 5 6 1 2 3 43 4 5 6 7 8 9 7 8 9 10 11 12 13 5 6 7 8 9 10 1110 11 12 13 14 15 16 14 15 16 17 18 19 20 12 13 14 15 16 17 1817 18 19 20 21 22 23 21 22 23 24 25 26 27 19 20 21 22 23 24 2524 25 26 27 28 29 30 28 29 30 26 27 28 29 30 3131See also: Dates.353 date.358 days.356ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎcompidnTimeStamp „ TieNo ##.compidn CompNo© Component timestamp in IDN format.[TieNo] is a component tie number and [CompNo], the number of a component withinthe file. The result is a (fractional) day number since 1899-12-31 00:00:00 whenthe component was written.See …Dates„ for more.NB: compidn calls …days„Examples:Œts2012 3 30 14 48 12 300days Œts40997.61681© Today's date/time.© ... in IDN format.Œfnums© a tied component file9999 compidn¨ 1 2 © times of recently-written components.40997.54759 40997.5736date 88 compidn 22012 3 30 13 45 59 40© ... converted to ŒTS format.See also: Dates.353 days.356 date.358ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎdaysdaynos „ {g„17520902} ##.days dates © Day number from ŒTS format.Returns number of days since 1899-12-31 00:00:00 for each ŒTS-style vector alongthe last axis of its argument. Part of day appears as a fractional component ofthe result. For example, midnight on new year's eve 31 Dec 1899 yields 1 andnoon on the following day (1 Jan 1900) is 1.5.Optional left argument {g}, a scalar number of the form yyyymmdd, specifies thedate of the …Gregorian_calendar„ reform (default 17520902 ­­ 1752-09-02). Thisis of interest only when exploring historical dates, see the example below.(Bug: Although [days] accounts for the "removal" of 11 days in September 1752for the change to the Gregorian calendar, it does not accommodate the attendantchange to New Year's Day. Prior to the implementation of the…British_Calendar_Act_1751„ the year changed at midnight on the 24th March,making 25th March New Year's Day. The following pairs of dates should becontiguous in the British calendar:358


1750-03-24 1751-03-25 © Julian year change in March 1750.1751-12-31 1752-01-01 * © Calendar Act year change on Dec 31 in 1751.1752-03-24 1752-03-25 © no Julian year change March 1752.1752-09-02 1752-09-14 © change to Gregorian calendar.1752-12-31 1753-01-01 © normal Gregorian year change 1752-1753.)* "... according to which the Year of our Lord beginneth on the 25th Day ofMarch, shall not be made use of from and after the last Day of December1751; and that the first Day of January next following the said last Day ofDecember shall be reckoned, taken, deemed and accounted to be the first Dayof the Year of our Lord 1752; ..."Ref: Jean Meeus, "Astronomical Algorithms", p59. ISBN 0-943396-61-1, 1998.Sometimes called the "International Day Number" or IDN, [days] is an origin-1system, where 1900-01-01 00:00:00 ­­ 1.0. Compare this with the …mayan„ origin-0scheme, where a day started at noon.Peter-Michael Hager suggests this nifty one-liner, which is good for dates between1752-09-14 and 2400-02-28:n_days„{{¯693896+(¾>730500)+˜36524×¾÷36525}¯60++/¾[2]†(—365.25ƒ¾[1 3]),31,(2Examples:days Œts38455.58296days 1935 1 812791days 1935 1 8, 12 2012791.51389© Current date and time.© Whole number of days.© Part way through day.days 1879 3 14 11 30 © Negative for dates before 1899 12 31.¯7596.520833-/Œ„days 2 3½1533 8 26, 1536 5 19¯133795 ¯132798¯997Œts­date days Œts1days†1752 09°,¨02 14¯53799 ¯53798© Matrix of dates … vector of day nos.© Full circle.© Sept 1752: 2nd and 14th contiguous.1--/days †1700°,¨(2 29)(3 1)eudays„15821004°days© 1700 was still a leap year in GB.© European Gregorian calendar reform.eudays †1582 10°,¨04 15¯115860 ¯115859© Oct 1582: 4th and 15th contiguous.1--/eudays †1700°,¨(2 28)(3 1)© 1700 was not a leap year in Europe.See also: Dates.353 date.358 cal.354 timestamp.178 mayan.465 compidn.356See also: Gregorian_calendar.599 British_Calendar_Act_1751.598359


ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎdatedates „ {g„¯53799} ##.date daynos© ŒTS format from day number.The argument is an array of day numbers since 1899-12-31 00:00:00. The resultingarray has rank one greater than [daynos] where 7-vectors along the new last axisare ŒTS-style date and time: (‡date ¾)­date¨¾.Optional left argument {g} specifies the day number of the …Gregorian_calendar„reform (default ¯53799 ­­ 1752-09-02). This is of interest only when exploringhistorical dates.(Bug: Although [date] accounts for the "removal" of 11 days in September 1752for the change to the Gregorian calendar, it does not accommodate the attendantchange to New Year's Day. Prior to the implementation of the…British_Calendar_Act_1751„ the year changed at midnight on the 24th March,making 25th March New Year's Day. The following pairs of dates should becontiguous in the British calendar:1750-03-24 1751-03-25 © Julian year change in March 1750.1751-12-31 1752-01-01 * © Calendar Act year change on Dec 31 in 1751.1752-03-24 1752-03-25 © no Julian year change March 1752.1752-09-02 1752-09-14 © change to Gregorian calendar.1752-12-31 1753-01-01 © normal Gregorian year change 1752-1753.)* "... according to which the Year of our Lord beginneth on the 25th Day ofMarch, shall not be made use of from and after the last Day of December1751; and that the first Day of January next following the said last Day ofDecember shall be reckoned, taken, deemed and accounted to be the first Dayof the Year of our Lord 1752; ..."Ref: Jean Meeus, "Astronomical Algorithms", p59. ISBN 0-943396-61-1, 1998.Peter-Michael Hager suggests this nifty one-liner, which is good for dates between1752-09-14 and 2400-02-28:n_date„{y,m,1+d-(m„m+.ˆd)œm„+\0 31,(29-×4|1œy d„˜0 365.25‚694035+˜(36525×¾-6Examples:date 127911935 1 8 0 0 0 0date 12791.513888891935 1 8 12 20 0 0show„timestamp°''show date 1e5÷31991-04-06 08:00:00© Whole number of days.© Part way through day.© Format ŒTS vector.© Fractional number of days.show date ¯7596.520833 © Negative days before 1899 12 31.1879-03-14 11:30:00date 2 2½14892 15509 15761 147981940 10 9 0 0 0 01942 6 18 0 0 0 0© (½date ¾) ­ (½¾),7.1943 2 25 0 0 0 01940 7 7 0 0 0 0date ¯53799 + 0 11752 9 2 0 0 0 01752 9 14 0 0 0 0360© 1752 calendar reform


1Œts­date days Œts © Full circle.eudate„¯115860°date© European calendar reform:eudate ¯115860+0 11582 10 4 0 0 0 01582 10 15 0 0 0 0© 1582: Oct 4th and 15th contiguous.See also: Dates.353 days.356 cal.354 timestamp.178See also: Gregorian_calendar.599 British_Calendar_Act_1751.598ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎeasteryyyymmdd „ ##.easter year © Easter Sunday in year ¾.In 325 A.D. the Council of Nicaea decreed that Easter was to fall upon the firstSunday after the first full moon on or after the Vernal Equinox.Suggested by John R. Clark, this algorithm is taken from D.E.Knuth's "The Art ofComputer Programming - Fundamental Algorithms" Vol 1, Ch 1.3.2 Ex14.Knuth says: "The algorithm, due to the Neapolitan astronomer Aloysius Lilius andthe German Jesuit mathematician Christopher Clavius in the late 16th century isused by most Western churches to determine the date of Easter Sunday for anyyear after 1582. The first systematic algorithm for calculating the date ofEaster was the "canon paschalis" due to Victorius of Aquitania (457 A.D.). Thereare many indications that the sole important application of arithmetic in Europeduring the Middle Ages was the calculation of Easter date, and so such algorithmsare historically significant."Technical note:As all of the <strong>functions</strong> used in the coding of this function are "pervasive", itjust-workson arrays of higher rank and depth.Examples:easterœŒts20040411© This year's Easter.0 100 100‚easter 1984 © Œts-style Easter.1984 4 22easter ³4 10½2000 to 203920000423 20100404 20200412 2030042120010415 20110424 20210404 2031041320020331 20120408 20220417 2032032820030420 20130331 20230409 2033041720040411 20140420 20240331 2034040920050327 20150405 20250420 2035032520060416 20160327 20260405 2036041320070408 20170416 20270328 2037040520080323 20180401 20280416 2038042520090412 20190421 20290401 20390410disp easter(1800 1900)(2000 2100)Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ18000413 19000415Û20000423 21000328ÛÀ~ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…Á~ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…Ù© Easter tables for four decades.© nested array of years.© We can make an ISO-Date formatter for such (nested) arrays of dates:fmt„{†,°('-'°,)/¯4 ¯2 ¯2†¨'0',°•¨0 100 100‚¾}¨saw361


disp fmt easter ,°›/1900+¼4 © nested Easter Days.ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛÚ…ÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛÛÛÛÚ…ÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛÛÛÛÚÎÎÎÎÎÎÎÎÎÎÌÛÛÚÎÎÎÎÎÎÎÎÎÎÌÛÚ…ÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÌÛÛÛÛÛÛ1901-04-07ÛÛÛÛ1902-03-30ÛÛÛ1903-04-12Û1904-04-03ÛÛÛÛÛÛÀÎÎÎÎÎÎÎÎÎ…ÙÛÛÀÎÎÎÎÎÎÎÎÎ…ÙÛÀÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎ…ÙÛÛÛÛÛÛÀÎÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÙÛÛÛÀÎÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÙÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…Ùfmt easter ³6 10½2000 to 2059 © 60 Easters ...2000-04-23 2010-04-04 2020-04-12 2030-04-21 2040-04-01 2050-04-102001-04-15 2011-04-24 2021-04-04 2031-04-13 2041-04-21 2051-04-022002-03-31 2012-04-08 2022-04-17 2032-03-28 2042-04-06 2052-04-212003-04-20 2013-03-31 2023-04-09 2033-04-17 2043-03-29 2053-04-062004-04-11 2014-04-20 2024-03-31 2034-04-09 2044-04-17 2054-03-292005-03-27 2015-04-05 2025-04-20 2035-03-25 2045-04-09 2055-04-182006-04-16 2016-03-27 2026-04-05 2036-04-13 2046-03-25 2056-04-022007-04-08 2017-04-16 2027-03-28 2037-04-05 2047-04-14 2057-04-222008-03-23 2018-04-01 2028-04-16 2038-04-25 2048-04-05 2058-04-142009-04-12 2019-04-21 2029-04-01 2039-04-10 2049-04-18 2059-03-30© Here is a histogram of the frequency of one million Easter dates.© The numbers in the first column are dates, eg: 322 means March 22.hist„{ © Histogram of items of vector ¾.¸„60 © default no of cols.sort„{¾[“¾]}© vector sort.uniq„sortž¾© unique values.hits„+/uniq°.=¾© number of items per distinct value.bars„—¸×hits÷—/hits© bar lengths.uniq,' Œ'[Œio+bars°.‰¼¸] © histogram by unique item.}362


hist 1e4|easter 1582+¼1e6322 ŒŒŒŒŒŒŒŒ323 ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ324 ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ325 ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ326 ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ327 ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ328 ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ329 ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ330 ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ331 ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ401 ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ402 ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ403 ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ404 ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ405 ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ406 ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ407 ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ408 ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ409 ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ410 ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ411 ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ412 ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ413 ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ414 ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ415 ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ416 ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ417 ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ418 ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ419 ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ420 ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ421 ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ422 ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ423 ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ424 ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ425 ŒŒŒŒŒŒŒŒŒŒŒŒSee also: Dates.353 saw.78ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎWorkspacesÎÎÎÎÎÎÎÎÎÎWorkspacesÎÎÎÎÎÎÎÎÎÎFunctions that operate on saved workspaces typically copy them into a temporarynamespace for examination. Currently, ŒCY doesn't return a result; a behaviourwhich is problematic for D-function coding. One way around this is to embed thecopy in a "diamondised" execute string, the first segment of which does the copyand the second, a trivial expression that returns an ignored result._„–'tmp.Œcy wsid ª 0'See also: fndiff.363 wsdiff.371 refws.365 do.211ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎdfnscodecmats „ {mino minw„8 6} ##.dfnscode lpp © Formatted dfns code.[dfnscode] renders the source of the <strong>functions</strong> and operators in this workspaceas a vector of character matrices, suitable for printing in an appropriate font.Right argument [lpp] is the number of lines of text per page (the number ofcolumns is fixed at 80).363


In order to save paper, rather than start every code capsule on a separate page,each follows its predecessor after a short gap and a separating title line.Optional left argument pair (mino minw), default (8 6), deterimes the minimumnumber of "orphan" and "widow" lines to be allowed at the end and beginning ofeach page, respectively:{start of functionorphan lines---------------------- page breakwidow linesend of function}Pages are headed with dictionary-style "from-to" ranges of the <strong>functions</strong> andoperators that appear on each page and "footed" with page numbers. Headers andfooters are aligned alternately right and left, so that the pages are suitablefor double-sided printing.You can find an example of the formatted code in Portable Document Format at:http://dfns.dyalog.com/downloads/DfnsCode.pdfExamples:cmats „ dfnscode 66© format code, 66 lines per page.See also: dfnsnotes.362ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎdfnsnotescmats „ {gap„8} ##.dfnsnotes lpp© Formatted dfns notes.[dfnsnotes] renders the notes in this workspace as a vector of charactermatrices, suitable for printing in an appropriate font. Right argument [lpp] isthe number of lines of text per page (the number of columns is fixed at 80).Page numbers are aligned alternately right and left, so that the pages are suitablefor double-sided printing.The overall structure of the resulting vector of pages is:contents · from …contents„ in the notes namespace.notes · · the bulk of the notes, around 400 pages at 66 lines/page.ˆperson‰ index index of sources and contributors ···function index alphabetical list function and operator names.ˆtopic‰ index from the "Index:" lines at the end of each note.In order to save paper, rather than start every note on a separate page, eachfollows its predecessor after a short gap and a separating title line. Optionalleft argument [gap], default 8, determines the minimum number of "orphan" lines,at the end of a page, in which a new note may be started.Contents and index references have the form: note.pageno, as in:· Dates.256· · days.258 © Day number from ŒTS format.· · date.259 © ŒTS format from day number.· · easter.260 © Easter Day in year ¾.· · timestamp.148 © Time-stamped message.You can find an example of the formatted notes at:364http://dfns.dyalog.com/downloads/Dfns<strong>Notes</strong>.pdf


Example:cmats „ dfnsnotes 66© format notes, 66 lines/page.See also: index.364 dfnscode.361ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎexitcvec „ ##.exit code© Return to calling environment.Some "closed workspaces" like to call ŒOFF when their task is complete. This cancan be irritating during testing or if the workspace was executed as part of acontinuing interactive session. [exit] infers if this is the case by determiningwhether there is a six-space input prompt in the session log following the initial<strong>Dyalog</strong> <strong>APL</strong> banner.The result is the character vector format of [exit]'s argument, preceded by thevector 'ŒOFF ' only if it decides there is no session to which to return. [code]is typically a small integer "exit code" with 0 meaning success.[exit] _returns_ a character vector, rather than _executing_ it, to reduce theprobability of accidental termination of <strong>APL</strong> during testing.So, with a closed workspace, instead of:ŒLX„'main ª ŒOFF 0'we might prefer:ŒLX„'main ª – exit 0'With the latter coding, the ŒLX expression will exit to the session, rather thanterminating the process, if there has been any prior session interaction.Bugs:[exit] will incorrectly assume a non-interactive session to be interactive if:1. The session output contains a line with six or more explicit leading blanks.2. The session output has been sufficiently voluminous to cause the log to overflow,losing the line with the "<strong>Dyalog</strong> <strong>APL</strong>" banner.In both of these cases, [exit] fails safe by omitting the 'ŒOFF' vector from itsresult and thus prescribing a return to the session (rather than termination ofthe <strong>APL</strong> process).Examples:' 0' ­ exit 0'ŒOFF 0' ­ exit 0© in an interactive session.© in a runtime application.See also: refws.365ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎfndiffcmat „ {excl} ##.fndiff (fna fnb)© Defined function differences.Fndiff takes a pair of function names of the form 'fnid' or 'wsid fnid'. Where,[fnid] is a plain or space-referenced function or operator name and [wsid] is aworkspace id.If [wsid] is given and a directory path is not supplied, WSPATH (See Options->Configure->Workspace) is used to locate the saved workspace.365


Otherwise, the function is sought in the current active workspace. The result isa "split-screen" display of lines that are in one function but not the other.The optional left argument is a character vector exclusion list:' ' Exclude white space from the comparison.'©' Exclude comments from the comparison.In order to accommodate [wsids] containing embedded blanks, the _last_ word in afunction specification is taken as the [fnid] and everything to the left of it(omitting leading and trailing blanks) is taken as the [wsid]. Embedded multipleblanks are preserved:' My Documents\WS myfn ' => wsid ­ 'My Documents\WS'fnid ­ 'myfn'Examples:'©'fndiff'min trees' 'max trees'· 0=­¾:¾ · · · · · · · Û· 0=­¾:•¾ · · · · · · ·· ~(›œ¾)¹'@\=':¸°’¨¾ · · · · Û· (0­œ0½¾)Ÿ(0¬­œ¾)Ÿ(,3)»½¾:¸°’¨¾ ·'©'fndiff'display DISPLAY' 'display'DISPLAY„{ŒIO·ŒML„0 · · · · · Ûdisplay„{ŒIO·ŒML„0 · · · · ·· ¸„0 ª chars„¸œ'..''''|-'·'ÚÌÀÙÛÎ' Û· ¸„1 ª chars„¸œ'..''''|-'·'ÚÌÀÙÛÎ'See also: wsdiff.371 Workspaces.361ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎindexindx „ notespace ##.index class © ¾-index of notes in space ¸.[index] extracts lines starting 'Index',[class] from character arrays in space[notespace] and returns a vector of (entry refs) pairs:entry: index entry (character vector)refs: names of variables referencing entry (vector of character vectors).Multiple entries on the same line are separated by character '|'.The notes in this workspace use the convention ':' to add entries to a ˆtopic‰index, ';' to add entries to a ˆperson‰ index, and '­' to add entries to analias list.Index: topic_entry|topic_entry|...Index; person_entry|...Index­ alias, for example "network, see: graph", as follows:Aliases:Index­BFS…breadth-first search|network…graph|recursion…recursion|Phi…golden meanIndex­balanced tree…binary search tree|IDN…International Day NumberIndex­AGM…arithmetic-geometric mean|BST…binary search treeIndex­DFS…depth-first search|MST…minimum spanning tree|RLE…run-length encodingIndex­line list…line vector|FRE…Function Results Edition|LZW…Lempel-Ziv-WelchIndex­spaces…blanks|GCD…greatest common divisor|LCM…least common multipleIndex­JITS…Just-In-Time-Subtraction|HCF…greatest common divisorIndex­AST…abstract syntax tree|CPS…continuation-passing style|Ø…golden meanIndex­imaginary numbers…complex numbers|HHKB…Happy Hacking KeyboardIndex­line-drawing characters…box-drawing characters|FFT…Fast Fourier TransformIndex­data compression…compression|TAO…Total array orderingIndex­read-eval-print loop…REPL366


Example:† 5† notes index ':' © first 5 _topic_ index entries.¸th root root¸„ rootaccumulator factorial fibonacci listadjacent 1s xtabsAGMlimit† 5† notes index ';' © first 5 _person_ index entries.Adelson-Velskii G.M. avlBaas M.predBaronet D.dtbBeckham D.mayanBopp Y.enlist† 5† notes index ':;' © first 5 _combined_ index entries.¸th rootroot¸„ rootaccumulatorfactorial fibonacci listAdelson-Velskii G.M. avladjacent 1sxtabs{'see ',¾}\†{1‡¨('…'=¾)›¾}°{'…',œ¾}¨notes index'­'AGMsee arithmetic-geometric meanASTsee abstract syntax treebalanced tree see binary search treeBFSsee breadth-first searchBSTsee binary search treeDFSsee depth-first searchFREsee Function Results EditionGCDsee greatest common divisorHCFsee greatest common divisorIDNsee International Day NumberJITSsee Just-In-Time-SubtractionLCMsee least common multipleline list see line vectorLZWsee Lempel-Ziv-WelchMSTsee minimum spanning treenetwork see graphPhisee golden meanrecursion see recursionRLEsee run-length encodingspacessee blanks© alias entriesSee also: xhtml.374 dfnsnotes.362ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎrefwsref „ ##.refws wsid © Ref to saved ws ¾.Returns a ref to a namespace containing a copy of workspace [wsid]. This may beused to simulate remote expression execution. Refws is similar to Unix's _mount_command, where a device (workspace) is mounted at a particular node (ref) in thename tree. Note however, that changes made via the resulting ref are not savedin the target workspace. In this sense the mount is read-only (but gives nowarning that updates are ignored - see example below).As a convenience (in common with …wsdiff„) an argument wsid of '' is interpretedas ŒWSID, so that refws'' refers to the saved version of the active workspace.Examples:)clearclear ws© starting with a clear ws:367


)copy dfns refws··saved··dfns„refws'dfns.dws'dfns.disp¼2 2Ú…ÎÎÂÎÎÎ̇1 1Û1 2ÛÃ~Î…Ï~Î…ÝÛ2 1Û2 2ÛÀ~Î…Á~Î…Ù© ref to copy of dfns ws.© "remote" execute.© Temporary ws-refs need not be named:(refws'eval').Œed'tasman'(refws'tube').(Œed Œnl 3)(refws'').Œed'refws'© open remote edit window.© view all fns in saved workspace.© look at saved version of function.(refws'tube').(london trip 'Kings' 'Queens')compiling graph ...KingsburyKingsbury JubileeWembley Park JubileeWembley ParkWembley Park MetropolitanFinchley Road MetropolitanBaker Street MetropolitanBaker StreetBaker Street JubileeBond Street JubileeBond StreetBond Street CentralMarble Arch CentralLancaster Gate CentralQueensway CentralQueensway© remote execution.(refws'util').Œcr'DOIF'R„DOIF TEST © Return next line number,R„TEST‡1+1†1‡ŒLC © ... if TEST false© Note that changes made using refws are not saved in the reffed workspace:0(refws'display').aa„99(refws'display').Œnc'aa'© make var in copy of DISPLAY ws.© var was not saved in ws.© We can create and append to ŒPATH, a ref to a copy of a saved utility work© space. The advantage of this approach is that changes in the saved WS are© immediately available to the next <strong>APL</strong> session.)cs ŒseCreateRefs„{refws„{}sink„–'''refws''ŒCY''dfns'' ª 0'dfns°„refws'dfns' ª Œpath,„' dfns'util°„refws'util' ª Œpath,„' util'}© Œse.dfns.(...)© Œse.util.(...)onCreate„'CreateRefs'© ... now save the session [Session->Save]368


See also: xws.376 wsdiff.371 exit.363ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎtest{ok} „ {opts„'q'} ##.test script © Run test script: no news => good news.Namespace _scripts_ contains character-vector test scripts, which exercise the<strong>functions</strong> and operators in this workspace. In general, test's argument is a vectoror matrix of the names of scripts to be executed. For example:test'display'test'hex' 'dec'test Œnl 4© test display function.© test <strong>functions</strong>: hex and dec.© test scripts for all operators.As a convenience, right argument '' is interpreted as (scripts.Œnl 2), a matrixof all scripts, except for those starting with '_'. Such names may be used forauxiliary sub-scripts, which are not intended to be run in isolation.During test's evaluation of each script, differences between actual and expectedresults are displayed in the session; the shy result is a boolean vector indicatingwhich scripts succeeded without fault.If a difference is detected, the script name, and expected and actual resultsare shown in the form:name expected … actualBlanks in expected and actual results are replaced with '·' characters to showwhere differences may be attributed to spacing. A common example of this is withnested arrays, where the display form often contains trailing blanks.¼1 21 1 1 2' ·'subs •¼1 2·1·1··1·2·© nested array.© note trailing blank in output:In this case, expected trailing blanks must be present in the script, otherwisedifferences will be reported.Optional left argument [opts] determines:'q' quietly execute each script (default),'v' (verbosely) show the progress of each script.'e' edit script(s).'l' list script names, for example: cols'l'test''.'s' stop on difference and display the actual result in an edit window.Option 's' is useful when developing scripts. When a difference is detected, executionis paused and the actual result is presented in an edit window. If thisnew value is acceptable, just copy it into the clipboard; close the window andthen paste it into the script edit-window at the appropriate place. On closingscript-window, execution will proceed until the end of the script or anotherdifference is detected.The left argument value is set in variable "Alpha", which is visible from withinthe script. This is useful, for example, in passing the "show progress" value toa recursive call on test. For example, a script may contain the lines:1Alpha test '_sub'© pass verbose option to auxiliary script.Scripts may contain :If control structures for conditional inclusion of tests.369


:If 80=Œdr' '... unicode-specific tests:Elsẹ.. classic-specific tests:EndIfNote that variables and (even multi-line) <strong>functions</strong> defined in the script arelocal to that script. An example of a script might be the following newlinedelimitedcharacter vector:display scripts.sampleÚ…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ © Sample Script ÛÛÛÛ cvec „ 1‡' ÛÛmult-lineÛÛcharacterÛÛvector' © Temp variable. ÛÛÛÛ dup„{ © Temp function. ÛÛ ¾ ¾ ÛÛ } ÛÛÛÛ disp dup cvec © disp available to script.ÛÛÚ…ÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÌÛÛÛmult-lineÛmult-lineÛÛÛÛcharacterÛcharacterÛÛÛÛvector Ûvector Û ÛÛÀÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎ…ÙÛÛÛÛ:If 'v'¹Alpha © verbose mode: ÛÛ 'Sqrt ¯1:',¯1*÷2 ÛÛ Sqrt ¯1: 0J1 ÛÛ:ElseÛÛ ¯1*÷2 ÛÛ 0J1 ÛÛ:EndIfÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙIt is easy to add extra tests to a script: we just execute a test case in thesession, and if we're sure the result is correct, copy and paste the input lineand its result into the script. Note however, the following restrictions:Bugs:[1] Some of the scripts will report differences unless [AutoFormat <strong>functions</strong>] isswitched _off_, using the Session menu:ÚÎη··Options···ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÛ ÚÎη··Configure···ÎÎÎÎÎÎÎÎÎÎÎÎÎÛ Û ÚÎη··Trace/Edit···ÎÎÎÎÎÎÎÎÎÎÎÎÛ Û Û ···Û Û Û [ ] AutoFormat <strong>functions</strong>Û Û Û †Û Û Û ÀÎÎ Uncheck box.Or set environment variable AUTOFORMAT=0 in the calling line (or shell).370


[2] Test is currently confused by script lines that contain:Embedded assignments: · · · · · 2+a„3Diamonds: · · · · · · · · 2+3 ª 4+5Shy results:· · · · · · · · Œex'a'System commands · · · · · · · )erase aQuad output · · · · · · · · Œ„...Assigned result of raw dfn application: · a„{...}0Assigned <strong>functions</strong> derived from dfns: · f„{...}¨()The latter two problems occur because the lines are misinterpreted assimple dfn definitions. The test function could be more sophisticated indistinguishing such cases, but it is easy to avoid the error by codingit as: "a„ {...}0" or "f„ {...}¨" (with a blank after the „), which confoundsthe part of the code that is looking for dfns to fix.[3] It would be nice to have :ElseIf, :Select/:Case[List] and :Return keywords.Technical notes:[test] creates a temporary namespace in which to execute scripts, and into whichall root space <strong>functions</strong> and operators (#.Œnl 3 4) are copied. Within the temporaryspace, the script is processed as follows:Removing comments and ignoring blank lines:If the next line contains an unclosed quoted vectorform a multi-line character vector with the following line.Otherwise, if the next line starts with a ':'process the :If/:Else/:End[If] control structure.Otherwise, if the next line contains a dfn definition:identify and Œfx the single- or multiple-line dfn.Otherwise, if the next line is an assign ('„' at outer level):execute the assignment in the tmp space.Otherwise:execute the expression and compare the result with following lines.Examples:ok19.30test'hex'test'hex' 'dec'test scripts.Œnl 2(^/test'')/'ok'test time''© test hex function (no news is good news).© test two scripts.© test all scripts.© test all scripts.© time the test.'l' test 'a' Œnl 4accascanascana'q' test'gcd' 'osc''e' test'gcd' 'osc'© scripts for a-operators.© quiet: report only differences.© edit script(s).371


'v' test'gcd' 'osc' © verbose: show test running.©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©© scripts.gcd© Greatest Common Divisor:155 7105 gcd 330factors (3×5×7) gcd 5×7×11lcm„{¸×¾÷¸ gcd ¾}© lowest common multiplefactors (3×5×7) lcm 5×7×113 5 7 11©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©© scripts.osc© Oscillate - probably returns 1:osc¨1 to 401 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1{2|¾:1+3×¾ ª ¾÷2}traj 2727 82 41 124 62 31 94 47 142 71 214 107 322 161 484 242 121 364 182 91 274 137 412 206 103 310 155 466 233 700 350 175 526 263 790 395 1186 593 1780 890 445 1336 668 334 167 502 251 754 377 1132 566 283 850 425 1276 638 319 958479 1438 719 2158 1079 3238 1619 4858 2429 7288 3644 1822 911 2734 1367 4102 2051 6154 3077 9232 4616 2308 1154 577 1732 866 433 1300 650 325 976 488 244 122 61 184 92 46 23 70 35 106 53 160 80 40 20 10 5 16 8 4 2 1See also: time.515ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎutf8nums „ {utab} ##.utf8 chrs © ŒAV … UTF-8 translation. chrs „ {utab} ##.utf8 nums © UTF-8 … ŒAV translation. NB: This function is superseded by system function 'UTF-8'ŒUCS ...[chrs] is a simple character vector and [nums] is its UTF-8 encoding into avector of numbers in the range 0..255.To write the resulting UTF-8 numbers to native file using Œnappend, they shouldfirst be "cast" to 1-byte integers in the range ¯128..127 using …int„; <strong>functions</strong>…utf8put„ and …utf8get„ do this.Examples:4 0• utf8 'hello world'104 101 108 108 111 32 119 111 114 108 100© < > 4 0• utf8 'hello¼world'104 101 108 108 111 226 141 179 119 111 114 108 100© 4 0• utf8 'a¼½¨¯2',œŒav97 226 141 179 226 141 180 194 168 194 175 50 0© utf8 utf8 'a¼½¨¯2'a¼½¨¯2372© round-trip some <strong>APL</strong> chars.


1Œav ­ utf8 utf8 Œav © round-trip all <strong>APL</strong> chars.1{¾­utf8 utf8 ¾} notes.utf8© round-trip char vec with newlines.See also: utf8get.426 utf8put.426 int.289 xhtml.374ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎwsdiff{excl„'¾'} ##.wsdiff (wsa wsb)© Workspace differences.Saved workspaces [wsa] and [wsb] are located using WSPATH, and any differencesare displayed in the session (the function returns no explicit result). Linesthat are in one workspace, but not in the other are displayed "split-screen".Note that wsdiff does not detect differences that amount to a _re-ordering_ or_duplication_ of lines within a function or variable. [wsdiff] is a good candidatefor copying into a utility namespace in ŒSE for reference via ŒPATH orinvocation using a programmable function (PF) key: see …PF_keys„.By default, <strong>functions</strong> named [wsdiff] are excluded from the comparison. Thismeans that [wsdiff] may be copied into the active workspace and called withoutreporting its presence as a difference.A workspace name of: '' refers to the current active workspace.A simple vector right argument 'wsid' is short for: '' 'wsid'.A null right argument '', is short for: '' Œwsid.For example:wsdiff 'max' 'min' © compare two saved workspaces.wsdiff 'dfns.bak' © compare active workspace with saved workspace.wsdiff ''© compare active workspace with saved version.The optional left argument is a character vector exclusion list:'©' Exclude function/operator comments from comparison.' ' Exclude function/operator white space from comparison.'~' Ignore variables.'’' Ignore <strong>functions</strong> and operators.'¾' Ignore <strong>functions</strong> called 'wsdiff' (default).'Œ' Discard output of differences - show only object names.Variables, if included are compared "line by line".Technical notes:A complication arises in wsdiff, with trapping the DOMAIN ERROR resulting from amis-spelling of one of the workspace names. Wsdiff must copy ŒTRAP from eachsubject workspace in order to compare the values. As error-guards are implementedusing ŒTRAP, the incoming value _overwrites_ the error-guard. In itself,this doesn't cause a problem as by this time, the error-guard's job is done.However, when the error-guard goes out of scope, the incoming value of ŒTRAP islost. The solution is to pass back the _value_ of the incoming ŒTRAP along withany other workspace-wide variables, as part of the result of the copy function.A related problem occurs with using – to determine the values of variables inthe respective workspaces. An "external execute" operand function is used sothat subject names do not clash with local names in wsdiff. However, executingthe subject name should be protected with an error guard; an example might be aVALUE ERROR for an unitialised external variable. Again, ŒTRAP causes a problem,as its value will be changed by setting the error guard prior to the execute. Inthis case the code-around is to extract ŒTRAP's value explicitly; this is easyas ŒTRAP has the same value, workspace-wide.373


Bugs:[wsdiff] ignores differences in arrays that contain references to namespaces.Examples:' 'wsdiff'c:\dyalog82\ws\patch' 'c:\dyalog90\ws\patch' © ignoring blanks.Patch.Config.GET· · · · · · ÛPatch.Config.GET· · · · · ·· :If '8'=œ2œ'.'ŒWG'<strong>APL</strong>Version' · Û· :If '7'=œ2œ'.'ŒWG'<strong>APL</strong>Version' ·Patch.Config.PUT· · · · · · ÛPatch.Config.PUT· · · · · ·· :If '8'=œ2œ'.'ŒWG'<strong>APL</strong>Version' · Û· :If '7'=œ2œ'.'ŒWG'<strong>APL</strong>Version' ·Patch.P · · · · · · · · Û· · · · · · · · · ·· ·8.1.4 (DV)· 23·Dec·1999 1955328 Û· · · · · · · · · ·· ·8.1.4 (RT)· 23·Dec·1999 1955328 Û· · · · · · · · · ·Patch.PATCHABLES· · · · · · ÛPatch.PATCHABLES· · · · · ·· ·8.2.2 (DV)· 23·Dec·1999 2260992 Û· ·9.0.1 (DV)· 18·Aug·2000 2692608· ·8.2.2 (RT)· 23·Dec·1999 2260992 Û· ·9.0.1 (RT)· 18·Aug·2000 2692608· · · · · · · · · · Û· ·8.2.3 (DV)· 17·Aug·2000 2270720· · · · · · · · · · Û· ·8.2.3 (RT)· 17·Aug·2000 2270720· · · · · · · · · · Û· ·7.4.2 (DV)· 17·Aug·2000 2185036· · · · · · · · · · Û· ·7.4.2 (RT)· 17·Aug·2000 2184976Patch.SHOWMSG · · · · · · ÛPatch.SHOWMSG · · · · · ·· :If 0=ŒNC M · · · · · · Û· :If 9¬ŒNC M · · · · · ·· · · · · · · · · · Û· :OrIf 'Text'»M ŒWG'Type'· · ·Patch.UPDATE_PROGRESS · · · · ÛPatch.UPDATE_PROGRESS · · · ·· M ŒWC'Static'POS(18 200)('3D' 'ReceÛ· M ŒWC'Static'POS(18 200)('EdgeStyle'Œ'wsdiff'max' 'min' © Discarding output lines.ŒLX · · · · · · · · · ÛŒLX · · · · · · · · ·· · · · · · · · · · Ûcombo · · · · · · · ·compile · · · · · · · · Ûcompile · · · · · · · ·const · · · · · · · · Û· · · · · · · · · ·defn· · · · · · · · · Ûdefn· · · · · · · · ·equn· · · · · · · · · Û· · · · · · · · · ·extend · · · · · · · · Û· · · · · · · · · ·· · · · · · · · · · Ûformat · · · · · · · ·lambda · · · · · · · · Û· · · · · · · · · ·local · · · · · · · · Û· · · · · · · · · ·max · · · · · · · · · Û· · · · · · · · · ·· · · · · · · · · · Ûmin · · · · · · · · ·parse · · · · · · · · Ûparse · · · · · · · ·reduce · · · · · · · · Ûreduce · · · · · · · ·show· · · · · · · · · Û· · · · · · · · · ·· · · · · · · · · · Ûtrace · · · · · · · ·trees · · · · · · · · Ûtrees · · · · · · · ·type· · · · · · · · · Û· · · · · · · · · ·typex · · · · · · · · Û· · · · · · · · · ·unify · · · · · · · · Û· · · · · · · · · ·· · · · · · · · · · ÛBackground · · · · · · ·Example · · · · · · · · ÛExample · · · · · · · ·Implementation · · · · · · Û· · · · · · · · · ·Introduction· · · · · · · ÛIntroduction· · · · · · ·wsdiff'aaa' 'bbb' © system variable differences.ŒTRAP · · · · · · · · ÛŒTRAP · · · · · · · ·· · 11·C aaa · · · · · · Û· · 12·C bbb · · · · · ·ŒIO · · · · · · · · · ÛŒIO · · · · · · · · ·· 1 · · · · · · · · Û· 0 · · · · · · · ·374


wsdiff'' © changes since )load.notes.wsdiff· · · · · · · Ûnotes.wsdiff· · · · · · ·· A workspace name·of:·'' refers to tÛ· A workspace·name of: ''·refers to· A simple·vector right argument 'wsiÛ· argument·of is shorthand·for: ''·Œw· A null right·argument '', is·short Û· · wsdiff 'max'·'min' · © compa· For example:· · · · · · Û· · wsdiff '' 'dfns.bak'· © compa· · wsdiff 'max'·'min' © compare tÛ· · wsdiff '' · · · © compa· · wsdiff 'dfns.bak' © compare aÛ· · · · · · · · · ·· · wsdiff '' · · © compare aÛ· · · · · · · · · ·wsdiff · · · · · · · · Ûwsdiff · · · · · · · ·· · · wsv„,'ŒLX' 'ŒTRAP' · · Û· · · wsv„,'ŒLX' 'ŒTRAP' · © 'ŒS· · · ŒLX„'' · · · · · Û· · · ŒLX„'' ©ª ŒSM„0 3½0 · ·wsdiff'aaa' 'ccc'Can't copy: cccwsdiff'aaa' 'ccc'^© Error trapping for bad wsname.See also: fndiff.363 refws.365 Workspaces.361 PF_keys.606ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎwsmerge{protected„0} ##.wsmerge wsid© Merge saved ws into current active ws.[wsmerge] merges the saved workspace [wsid] into the current active workspace.The optional left argument (default 0) determines whether incoming objects areprevented from overwriting existing ones of the same name. [wsmerge] differsfrom )COPY and )PCOPY in that it merges, rather than replaces, namespaces withincoming ones of the same name.Technical note:To deliver a vector of namespace references, [wsmerge] incorporates rather thancalls, subfunction …refs„. This means that it can be copied as a stand-aloneutility, into an active workspace. See …refs„ for details.Examples:©ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ)load aaa··· saved ···tree ##· ~ aaa ccc· notes· · ~ aaacccaaa's ccc© load WS "aaa".© show aaa's content.© show aaa's variable "ccc".©ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ)load bbb··· saved ···tree ##· ~ bbb ccc· notes· · ~ bbb© load WS "bbb".© show bbb's content.375


ccc © show bbb's variable "ccc".bbb's ccc©ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ)load aaa··· saved ···)copy dfns wsmerge··· saved ···© load WS "aaa".© copy wsmerge into "aaa".1 wsmerge 'bbb' © PROTECTED merge "bbb".© Note how content of aaa's and bbb's namespace "notes" has been merged.tree ##· ~ aaa bbb ccc· ’ wsmerge· notes· · ~ aaa bbbcccaaa's ccc© show merged content.© aaa's variable was protected.©ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ)load aaa··· saved ···)copy dfns wsmerge··· saved ···© reload WS "aaa".© copy wsmerge into "aaa".0 wsmerge 'bbb' © UNPROTECTED merge "bbb".tree ##· ~ aaa bbb ccc· ’ wsmerge· notes· · ~ aaa bbbcccbbb's ccc© show merged content.© aaa's variable was overwritten.©ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎSee also: refs.380 xws.376 tree.135 wsdiff.371ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎxhtml{fids} „ ##.xhtml dir© Export this WS to ¾\*.htm.Extended by Stephen Taylor, [xhtml] writes UTF-8 encoded .htm files, correspondingto the structure of this workspace, into existing directory [dir]. Shy result[fids] is a vector of the names of the files, which have been created.Function [xhtml] is specific to this workspace in that it relies on variousidiosyncracies in the format of these notes. In general, it is unsuitable forproducing html for other workspaces.Font Issues-----------The style sheet (http://dfns.dyalog.com/xhtml.css) for these pages encouragesbrowsers to use the <strong>Dyalog</strong> "<strong>APL</strong>385 Unicode" font, supplied by Adrian Smith.376


Ideally, the font should be able to display all of the following characters:code_„†,/##.(,°Œcr¨‡Œnl 3 4)note_„†,/##.notes.(–¨‡Œnl 2)ws_chars„Œav•~°Œtc,code_,note_© chars used in code.© chars used in notes.© chars used in WS:ws_chars%'¸¾_abcdefghijklmnopqrstuvwxyz¯.«0123456789$£‘ABCDEFGHIJKLMNOPQRSTUVWXYZ·••õ{€In other words, the font should be able to draw the following little picture:0 disp 0 1 0°\¨16 16½(Œio+Œav¹ws_chars)select' 'Œav © chars used in WS:ÚÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÌÛ Û Û Û Û Û Û Û Û Û Û Û Û % Û ' Û ¸ Û ¾ ÛÃÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝÛ _ Û a Û b Û c Û d Û e Û f Û g Û h Û i Û j Û k Û l Û m Û n Û o ÛÃÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝÛ p Û q Û r Û s Û t Û u Û v Û w Û x Û y Û z Û Û Û ¯ Û . Û « ÛÃÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝÛ 0 Û 1 Û 2 Û 3 Û 4 Û 5 Û 6 Û 7 Û 8 Û 9 Û Û Û Û $ Û £ Û ÛÃÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝÛ ‘ Û A Û B Û C Û D Û E Û F Û G Û H Û I Û J Û K Û L Û M Û N Û O ÛÃÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝÛ P Û Q Û R Û S Û T Û U Û V Û W Û X Û Y Û Z Û Û Û Û · Û ÛÃÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝÛ • Û • Û Û Û Û Û Û Û Û Û Û Û Û Û Û ÛÃÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝÛ Û Û Û Û Û Û Û Û Û Û õ Û { Û € Û } Û • Û ÛÃÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝÛ ¨ Û • Û Ä Û Å Û Æ Û þ Û É Û Ñ Û Ö Û Ø Û Ü Û ß Û à Û Û Û ä ÛÃÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝÛ å Û æ Û Û è Û é Û Û Û Û Û ï Û ñ Û [ Û / Û š Û \ Û ÛÃÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝÛ < Û ˆ Û = Û ‰ Û > Û ¬ Û Ÿ Û ^ Û - Û + Û ÷ Û × Û ? Û ¹ Û ½ Û ~ ÛÃÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝÛ † Û ‡ Û ¼ Û ± Û * Û — Û ˜ Û ’ Û ° Û ( Û › Û œ Û • Û ž Û ƒ Û ‚ ÛÃÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝÛ | Û ; Û , Û ‹ Û Š Û ” Û “ Û ³ Û ² Û ´ Û µ Û Ž Û ! Û • Û – Û • ÛÃÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝÛ ® Û ­ Û » Û Û Û ö Û ø Û " Û # Û Û & Û Û Ù Û Ì Û Ú Û À ÛÃÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝÛ Ï Û Î Û Ã Û Ý Û Á Û Â Û Û Û @ Û Û Û Û • Û ü Û Û Û ÛÃÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝÛ : Û º Û ¿ Û Û ª Û „ Û … Û © Û ) Û ] Û Û Û Û Œ Û • Û ÛÀÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÙUnicode Characters------------------In addition to ŒAV, [xhtml] can render Unicode non-ŒAV characters, using atranslation mechanism defined in …unicode„.Code Format-----------The source code looks better in the html if you _UN_check [AutoFormat <strong>functions</strong>]in the Trace/Edit Tab from session menu: Options->Configure, while running the[xhtml] function.Requires: …subs„377


Example:disp xhtml'c:\tmp'Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÛc:\tmp\index.htmÛc:\tmp\n_ambiv.htmÛc:\tmp\n_ascan.htmÛ ...ÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎSee also: htx.180 index.364 subs.85 unicode.596ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎxwsrslt „ {expr„'–Œlx'} ##.xws wsid © Execute expr ¸ in saved ws ¾.NB: This function is now largely superseded by …refws„.[xws] evaluates expression [expr] (default '–ŒLX') as if from within the savedworkspace [wsid]. It does this by copying the saved workspace and its systemvariables into a temporary namespace, where the subject expression is executed.Technical note:The temporary namespace is created using _dyadic_ ŒNS with name: 'xws'. This isnot strictly necessary and _monadic_ ŒNS would certainly be simpler:(ŒNS'')–copy,lasv,copy,¸© execute expr in copied ws.However, monadic ŒNS returns a space whose display (and •) form is includes thestring: '[Namespace]'. Such a space precludes the use of many subject workspacesthat explictly or implicitly use space _names_, as in the example::With 'f1'ŒWC'Form'where the result of ŒWC is '#.[Namespace].f1', a character vector that isrejected by :With, whereas '#.xws.f1' would be OK.However, this leaves the problem of creating a temporary _named_ space. Localisationin D-<strong>functions</strong> is achieved _only_ through assignment, so we must assigna local name before creating the space. Unfortunately, the name must then be expungedprior to executing the dyadic ŒNS, which would otherwise do nothing.Further, the shy result of the ŒEX must be assigned a dummy 'sink' name in orderto prevent the function from terminating at this point. This all leads to therather grisly code:xws„ŒNS'' ª _„ŒEX'xws'('xws'ŒNS'')–copy,lasv,copy,¸© temp local space name.© execute expr in copied ws.A further problem may arise if the expression [expr], encounters code in thesubject workspace that refers to a namespace in absolute, rather than relativeterms. In particular, a reference such as (#.data) must fail where (##.##.data)would succeed.Examples:'Œnl 2 3 4'xws'display'DISPLAY© Objects in DISPLAY ws.'1 DISPLAY ŒA'xws'display' © Display ŒA in DISPLAY ws.Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛABCDEFGHIJKLMNOPQRSTUVWXYZÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙ'Œwsid'xws'display'u:\take90\dyalog\ws\display© DISPLAY's ŒWSID.378xws'display'© Execute DISPLAY's Œlx.


The argument is displayed with a series of boxes bordering each subarray.Characters embedded in the borders indicate array shape and type....wsvars„'Œnl 2'°xws© Vars in saved WS.wsvars¨'min' 'max'Background ExampleExample ImplementationIntroduction Introduction© Vars in min and max....'WDesign.RUN'xws'wdesign'© Run WDesign workspace.© The following function opens edit windows on both the current and backup© copy of a function, enabling cut 'n paste operations from old to new.© The left arg (default ŒWSID) is the workspace in which to find the backup© copy, which will appear in the top edit window with caption: 'xws.···'.edbak„{ © Edit current and backup versions of fn ¾.¸„ŒWSID© default: saved version of current ws._„ŒED ¾© open window on current fn.qt„''''°{¸,¾,¸} © enclose in quotes.('Œed ',qt ¾)xws ¸ © open window on backup fn.}See also: refws.365ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎNamespacesÎÎÎÎÎÎÎÎÎÎNamespacesÎÎÎÎÎÎÎÎÎÎWith the advent of namespace references (refs) in version 9.0, code whichtraverses a namespace structure, must make special arrangements to avoid the"infinite" recursion that may occur if a space contains a reference to one ofits ancestors. The way of avoiding this problem, used by the …refs„ function, isto maintain a list of spaces already visited, and so avoid visiting any spacemore than once. Alternatively, the …tree„ function just "gives up" when itencounters a ref which is not an immediate child of the current space.Example:#.x#.xrefrefref#.x)ns xx.ref„xx.refx.Œnl 9x.ref.Œnl 9x.ref.ref.Œnl 9x.ref.ref.ref.ref© cyclic reftree x#.x· ref … #.x© …tree„ function "gives up" on cyclic refs.#.xrefs x© …refs„ function visits each space exactly once.See also: refs.380 tree.135 xrefs.384379


ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎnspacksaved „ {seed} ##.nspack ref© Share arrays across space tree.Nspack takes a reference to a namespace to be packed by _array sharing_. Identicalarrays and subarrays are shared among all of the variables in the space andall of its children. In particular, if the argument is a reference to the rootspace (#), all variables in the workspace are shared. This may take a considerabletime but could result in a significant saving in a workspace containingcomplex nested arrays. The result is the number of workspace bytes saved.Nspack may be appropriate for reducing the size of a workspace, prior to deployment,when file storage is at a premium. For example, when saving to a PDA.Notice that the result of Œsize can be misleading as it ignores subarray sharingwhen counting the bytes consumed by a nested structure.The optional left argument is an array of values to be considered for sharing.<strong>Dyalog</strong> automatically shares literal constants from lines of code (or execute (–)expressions) across the whole workspace. Examples of literal constants are 9,'~’’' and 2 3 4 in:class„9,('~’’'¹incl)/2 3 4Given that these values are already present in the workspace, nspack may as wellshare them with any arrays that happen to contain an identical subarray. By default,"common" literals: 0, 1, ¯1, 2, «, '' and ' ' are used. If reducing thesize of the saved workspace is _very_ important, the following function may beused to harvest pointers to all literal values present in the workspace. Notehowever, that for a non-trivial workspace, it takes a depressingly long time torun (see example below).literals„{© Unique literal values.lines„ž1 enlist(refs ¾).(ŒNR¨‡ŒNL 3 4) © function source lines.tokns„ž1 enlist tokens¨lines© tokens within lines.ltoks„ž{((œ¨¾)¹'''¯',ŒD)/¾}tokns © literal tokens.1‡–¨'0',ltoks© literal values.}Technical note:Nspack includes _copies_ of <strong>functions</strong> …refs„ and …pack„. This is so that it maybe copied stand-alone into a subject workspace.Bugs:Nspack does not penetrate nested arrays looking for refs to (unnamed) spaces.This means that array values within such spaces are not shared.0refs„Œns¨'' ''© array of refs containing,refs.(a„¼3)© distinct values.nspack # © no sharing :-(Examples:nested„¼¨°¼¨°¼¨°¼¨¼3 3Œsize'nested'© complex nested array.© size in bytes.19484nspack # © nspack recovers most of the space.17996nspack # © subsequent pack saves no more space.019484Œsize'nested'© size "appears" not to have changed.© The following sequences show savings in various workspaces.380


©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©)xload tubeC:\<strong>Dyalog</strong>90\samples\dfns\tube saved Sun Jul 28 14:30:58 2002compile°–¨‡Œnl 9© compile graphs for all routes.)copy dfns nspackC:\<strong>Dyalog</strong>90\samples\dfns\dfns saved Sat Oct 12 00:18:00 2002nspack # © takes a while but saves 86k.88144)erase nspack'wsdiff'Œse.Œcy'dfns'Œse.wsdiff''© copy wsdiff to check that© changes are transparent.©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©)xload wdesignC:\<strong>Dyalog</strong>90\ws\wdesign saved Fri Mar 2 14:19:54 2001)copy dfns nspackC:\<strong>Dyalog</strong>90\samples\dfns\dfns saved Fri Oct 11 23:54:22 2002nspack # © saves 130k.133308)erase nspackŒse.wsdiff''© check changes are transparent.©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©© The following takes an inordinate time to run, but shares every last byte.)xload wdesignC:\<strong>Dyalog</strong>90\ws\wdesign saved Fri Mar 2 14:19:54 2001literals„{© unique literal values.lines„ž1 enlist(refs ¾).(ŒNR¨‡ŒNL 3 4) © function lines.tokns„ž1 enlist tokens¨lines© tokens.ltoks„ž{((œ¨¾)¹'''¯',ŒD)/¾}tokns © literal tokens.1‡–¨'0',ltoks© literal values.})copy dfns nspack refs enlist tokens timeC:\<strong>Dyalog</strong>90\samples\dfns\dfns saved Sun Oct 13 13:02:12 2002(literals time #)nspack #15:37.18144488© saves extra 14k (c.f. above).)erase literals nspack refs enlist tokens timeŒse.wsdiff''© check changes are transparent.©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©© The following example shows the difference between sharing© _within_ as opposed _among_ a number of namespaces.'x.a' 'x.b' 'x.c'Œns¨›''© make three spaces.x.(a b c).(var„¼¨°¼¨°¼¨°¼¨¼3 3)© populate separately.381


nspack¨x.(a b c) © packing _within_ spaces saves 17.5k each.17952 17952 179523064nspack x © packing _among_ spaces saves a further 3k.See also: pack.69 refs.380 Data_compression.190ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎrefsrvec „ {exclude„«} ##.refs ref© Vector of sub-space references.Produces a vector of namespace references to [ref] and each of its subspaces.The optional left argument is a list of sub-spaces to be excluded from the traversal.Technical notes:The coding is complicated by having to cater for "cyclic" namespace references.As a space may contain a reference to one if its ancestors, the code must notblindly follow all subspace references, otherwise unbounded recursion willresult in a WS FULL. The trick is to avoid re-visiting any space by maintaininga list of those already visited.refs„{ © Vector of sub-space references for ¾.¸„« ª (½,¸)‡¸{© default exclusion list.¸¹¾:¸© already been here: quit.¾.(†’°–þ/²(›¸,¾),‡ŒNL 9) © recursively traverse any sub-spaces.}¾ © for given starting ref.}The outer code defaults the exclusion list to null (no exclusions) and removesthe list from the final result:¸„« ª (½,¸)‡¸{© default exclusion list.···}¾ © for given starting ref.The first line of the inner function stops if the space is in the list:¸¹¾:¸© already been here: quit.The test could be omitted by set-subtracting the list of visited refs from thelist of subspace refs. However, the code would have to accomodate the execute ofeach of a null vector of sub-space names:(1‡–¨'0',‡ŒNL 9)~¸Perhaps a little daunting at first sight, the second line is interpreted thus:¾.(····················) © Within the subject space,·················‡ŒNL 9· © take a vector of sub-space names,··········(›¸,¾),······· © prefixed with extended visited-list.···†···þ/²·············· © left-to-right reduction with operand:····’··················· © recursive call between visited-list·····°·················· © and······–················· © ref from sub-space name.Notably absent from the code is any explicit test to quit when there are no moresub-spaces. In this case, ‡ŒNL 9 is a null vector, so ²(›¸,¾),‡ŒNL 9 is a 1-itemvector, which is just passed along as the result of the reduction without anapplication of its recursive operand function. The technique is abstracted inoperator …trav„.382


An alternative, suggested by Paul Mansour, which returns just GUI refs is:guirefs„{ © Vector of GUI references for ¾.«{ © starting with null result accumulator.¾.(†’°–þ/²(›¸,¾),ŒWN'') © recursively traverse any sub-spaces.}¾ © for given starting ref.}or the equivalent:guirefs„{ © Vector of GUI references for ¾.¸„«© starting with null result accumulator.¾.(†’°–þ/²(›¸,¾),ŒWN'') © recursively traverse any sub-spaces.}This code needs no check for circularity as ŒWN acknowledges only the strict GUIparent-child hierarchy. Again, what is perhaps remarkable, is the lack of anyexplicit test for termination: guirefs can safely navigate an arbitrarily complexGUI-tree even though it has "no moving parts".Phil Last observes that a ref from a space inside the subject space to one outsideit, will include _all_ subspaces of the outer space. For example:'x'Œns''x.cuckoo„#refs x#.x # #.notes #.scriptsTo report only those refs _within_ the subject space (x), Phil suggests replacingthe recursive line:¾.(†’°–þ/²(›¸,¾),‡ŒNL 9) © recursively traverse any sub-spaces.with:¾.(†’þ/²(›¸,¾),¾{(0 0,1‡¸=¾.##)/0,¾}–'¾',,' ',ŒNL 9)¯¯¯¯¯¯The crucial part of the above is ¸=¾.##, which produces a mask to extract thosesubspaces whose parent is the current space. This removes outward pointing refs(such as "cuckoo" above) from the result as its parent is not the current space.The elegance of the expression is marred a little by having to avoid errors ifthere are no true subspaces.Firstly, if ŒNL 9 were to return an empty matrix, then –,' ',ŒNL 9 would generatea VALUE ERROR. To avoid this, we preface the possibly empty list of refswith known ref '¾' (which will be removed later).–'¾',,' ',ŒNL 9Secondly, because the interpreter does not currently provide a prototypical ref,we must avoid the NONCE ERROR that would occur if (···¸=¾.##)/¾ resulted in anull (if ¸=¾.## produced all zeros). This is achieved by prefixing 0 to the vectorof refs: 0,¾ and removing it with a corresponding 0 as the first item of thereplicate:¾.(†’þ/²(›¸,¾),¾{(0 0,1‡¸=¾.##)/0,¾}–'¾',,' ',ŒNL 9)¯¯¯Finally, the extra prefixed '¾' from the first step is removed by substitutinga 0 for the second item in the replication mask:¾.(†’þ/²(›¸,¾),¾{(0 0,1‡¸=¾.##)/0,¾}–'¾',,' ',ŒNL 9)¯¯¯¯¯¯¯¯Examples:383


efs Œse © Vector of space refs for ŒSE.(refs #).(ŒWX„1)© Set value of ŒWX in all spaces in ws.—/(refs #).Œml© Max ŒML in workspace.—/{+/'.'=•¾}¨refs #© Max namespace depth.œ+š†½¨(refs #).Œnl 2© Total number of global variables.†®/{¾ find'½½'}¨refs #© Search for rank.^/0=(refs #).Œnc›'foo'© Is this a foo-free workspace?(refs #).Œex›'foo'© Defoobarise the workspace.(refs #)fnrepl¨›'foo' 'bar' © In all the fns in all the spaces ...Œse.(cbtop cbbot) refs Œse © ŒSE refs, excluding CoolBands.See also: trav.130 tree.135 up.383 Namespaces.377 xrefs.384 pow.218ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎrefmatchmatch „ this ##.refmatch that© Space reference match.The arguments are references to namespaces to be compared. [refmatch] deems therefs matching iff:[1.0] They are refs to the same space, or[2.1] The namelists for all classes are identical, and[2.2] Variables in both spaces match, and[2.3] Those System variables with namespace extent in both spaces match.[2.4] Function and operator source (ŒCR) in both spaces match, and[2.5] Any sub-spaces match, using the same criteria.Note that in comparing namespaces, this function ignores:- GUI properties, such as Posn, Size, Handle, ···- Timestamps and User IDs in <strong>functions</strong>.- Œstop, Œtrace, Œmonitor settings on <strong>functions</strong>.Example:110notes refmatch notes © match on criterion [1]notes refmatch Œns notes © clone matches on criteria [2].notes refmatch {¾.Œio„0 ª ¾} Œns notes© disturbed clone: mismatch.'x.z' 'y.z'Œns¨›''© create spaces.(x y).hello„›'hello' © identical vars in x & y.(x y).z.world„›'world' © .. .. in x.z & y.z.(x y).z.(dup„{¾ ¾}) © .. fns .. ..disp tree¨x yÚ…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ#.x Û#.y ÛÛ· ~ hello Û· ~ hello ÛÛ· z Û· z ÛÛ· · ~ worldÛ· · ~ worldÛÛ· · ’ dup Û· · ’ dup ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…Ù10x refmatch yx.z.world„''x refmatch y© spaces match.© zap x.z's world.© spaces no longer match.See also: le.49 tree.135384


ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎupsref „ {from„Œthis} ##.up gens© Reference to ancestor space.Returns a space reference to the [gens]-parent of the space reference [from](default current space). Gens is the number of generations to go "up" the namespace tree:0 - Self,1 - Parent,2 - Grandparent,3 - ...Examples:Œse.mb.options.tt.show up 3ŒSE.mbhere„up 0© Great grandparent of ref.© Ref to current space.See also: refs.380 Namespaces.377 refpath.582ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎvwiserslt „ (fn ##.vwise) ref © Variable-wise: apply ¸¸ to each var in space ¾.Suggested by Paul Mansour, [vwise] applies its operand function to each variablein the namespace referenced by right argument ¾.Note that any non-primitive <strong>functions</strong> in vwise's operand will execute in the_calling_, rather than the _target_ space.Paul suggests some related operators: "Furthermore, we need a way to operate oneach sub namespace in a namespace, which suggests swise, or "space wise":swise„{¸¸¨refs ¾}© Space wise© Apply to each spaceIt is convenient to have variations of these operators that do replacement:vwiser„{n„‡¾.ŒNL 2v„¸¸¨¾°–¨n¾•n ¾.{–¸,'„¾'}¨v}© Var wise, with Replacement© Var Names© Apply to each© Reset varsandswiser„{†¸¸¨refs ¾}© Space wise with replacement© Apply to each spaceNote that we could have one version of each operator and control their behaviorwith a left argument, but this increases the complexity of the syntax when callingthem.With operator "saw" (simple-array-wise) and these new operators, we can get towork on an arbitrary namespace structure. Here is an example that finds and replaces"words" in each simple text vector of a namespace ns:f„ft rt°sswordg„f sawh„g vwiserh swiser ns© Find and replace© ... in each simple array© ... in every variable© ... in every space385


where ft is the find text, rt is the replace text, and ssword is a slightly reworkedversion of its DFNS namesake.Or simply rotate every variable in and under namespace A:² vwiser swiser Aor display the contents all variables in and under A:€ vwise swise AIt appears vwise and swise are used in together a lot, so it might be useful tocombine them in a single operator:andvswise„{© Var and Space Wise¸¸ vwise swise ¾ © ...}vswiser„{© Var and Space Wise¸¸ vwiser swiser ¾ © ...}Count the number of simple matrices in every item of every variable in and underA:+/¹{2=½½¾}saw vswise ARotate every matrix, simple or nested, in and under A:{2=½½¾:²¾ ª ¾} vswiser AExamples:15011#+/{82=Œdr ¾}vwise notes © number of simple char vars in #.^/{¾­vtrim ¾}vwise notes © check that all notes have been trimmed.~1¹(' ',Œtc)¹{œ²¾}vwise notes © check no trailing white space in notes.ž{€Œcs''}vwise notes© operand function runs in calling space.See also: refs.380 xrefs.384 saw.78ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎxrefsrefs „ ##.xrefs array © Extract refs vector from array ¾.Returns a vector of unique namespace references extracted from the array argument.Examples:)ns x)ns ydisp aa„y((1 2)x)yÚ…ÎÎÂÎÎÎÎÎÎÎÎÎÂÎÎÎÌÛ ÛÚ…ÎÎÂÎÎÎÌÛ ÛÛ#.yÛÛ1 2Û#.xÛÛ#.yÛÛ ÛÀ~Î…Á#ÎÎÙÛ ÛÀ#ÎÎÁÎÎÎÎÎÎÎÎ…Á#ÎÎÙ© nested array containing refs.386


xrefs aa © unique refs.#.y #.x© The following expression returns a vector of references to all of the name-© spaces in the workspace. It includes those enclosed in any variables and any© bound by a derived function, such as: kwd„notes°find.©© ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ Unique values of ...© Û ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ all refs together with© Û Û ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ extracted refs from© Û Û Û ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ values of© Û Û Û Û ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ all variables and© Û Û Û Û Û ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ all <strong>functions</strong> in© Û Û Û Û Û Û ÚÎÎÎÎÎÎ all spaces.© Û Û Û Û Û Û Ûnub{¾,xrefs ¾.((–¨'0',‡ŒNL 2))(Œcr¨‡Œnl 3)}refs ## #.notesSee also: refs.380 vwise.383ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎambiv{name} „ {ref} ##.ambiv namelist© Ambivalize traditional function.Changes the header in [namelist] traditional defined <strong>functions</strong> by enclosing theleft argument in each header line in braces. Useful when importing dyadic <strong>APL</strong>2<strong>functions</strong> that may be called with no left argument. The shy result is a vectorof the names of those <strong>functions</strong> that have been changed with nulls for those thathaven't. The optional left argument specifies the namespace in which the operationis to take place, default: current space. Notice that [ambiv] may be used inconjunction with …refs„ to ambivalize all <strong>functions</strong> and operators in a namespacetree.Examples:ambiv Œnl 3 4ambiv'foo' 'goo' 'hoo'Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ Ú…ÎÎÌ Ú´Ì Ú…ÎÎÌ ÛÛ ÛfooÛ Û Û ÛhooÛ ÛÛ ÀÎÎÎÙ ÀÎÙ ÀÎÎÎÙ ÛÀ¹ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙŒse.NumEd ambiv'numed'© ambivalize all fns and ops in this space.© worked for foo and hoo, but not goo.© ambivalize Œse.NumEd.numed.{¾ ambiv ¾.Œnl 3 4}¨refs # © ambivalize all fns and ops in workspace.See also: refs.380ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎattribcmat „ {attributes} ##.attrib namelist © Function/operator attributes.The right argument is a namelist of <strong>functions</strong> or operators and the optional leftargument, a character vector of the attributes to be displayed. By default,date, name and first comment are shown in date-time order. The attributes thatcan be displayed are:387


n name of function or operator,d date of fix yyyy-mm-dd,t time of fix hh:mm:ss,i id of fixer,r number of rows,c number of cols,s size or "workspace footprint" in bytes.’ function or operator syntax which is depicted:½„ explicit result.{½„} shy result.¸ required left argument.{¸} optional left argument.¸¸ left operand.¾ right argument.¾¾ right operand.’ function.’’ operator.© first line comment,In addition, sort characters '“' and '^' are acknowledged:“ use following row as a _visible_ sort field.^ use following row as an _invisible_ sort field.· any other character is passed literally to the result column.[attrib] is a good candidate for invocation using a programmable function (PF)key, see …PF_keys„.Technical notes:<strong>APL</strong>'s traditional "name clash" problem is avoided by executing the name referencingsystem <strong>functions</strong>: ŒAT, ŒNR, ŒSIZE, chronologically _before_ the creationof any of attrib's local names. This means that at system function time, none ofthe subject names are obscured by local definitions.···names lines sntx time ids sizes„†{ © names local to attrib.(›‡¾){¸,¾ © names,}(›ŒNR¨‡¾){¸,¾ © ŒNR,}(1 1 0 1/‡³†,‡ŒAT ¾){¸,¾ © ŒAT,}›ŒSIZE ¾ © ŒSIZE.}ŒFMT†¾© executed _before_ local name creation.···Notice that a more readable and seemingly equivalent version of the inner fourlines above:names„›‡¾lines„›ŒNR¨‡¾attrs„1 1 0 1/‡³†,‡ŒAT ¾sizes„›ŒSIZE ¾names,lines,attrs,sizes© fn/op names.© ŒNR,© ŒAT,© ŒSIZE,© accumulated attributes.... would defeat the object by creating "early" local names. For example, localnames: [names], [lines] and [attrs], would obscure a workspace function or operatorof the same name from the following system <strong>functions</strong>. An alternative butungainly coding would be to string the whole thing across a single source line:(›‡¾),(›ŒNR¨‡¾),(1 1 0 1/‡³†,‡ŒAT ¾),›ŒSIZE ¾... but this is over-long and hard to comment or amend. The compromise is tospread it over several lines using the linking function: {¸,¾}388


(···){¸,¾}(···){¸,¾}(···)Incidentally, "workspace footprint" is perhaps a less misleading term for theresult of ŒSIZE. If we imagine the footprints from a number of people on a dustyfloor, some of the prints will probably overlap and in extremis, the total areaof individual footprints might exceed that of the floor. Similarly, the ŒSIZEreported for each function or operator includes that of the symbols and literalconstants it references. As symbols and constants with identical values areshared (or overlap) between <strong>functions</strong> and operators, (+/ŒSIZE ŒNL 3 4) could exceedthe value of ŒWA in an empty workspace!Examples:attrib 'a'Œnl 3© a-<strong>functions</strong> in date-time order.2000-10-01 ascfile © Ascii file as nested vector.2000-11-09 ambiv © Ambivalize traditional <strong>functions</strong>.2001-11-02 assign © Hungarian method cost assignment.2002-10-31 attrib © Function/operator attributes.names„'attrib' 'wsdiff' 'pow' 'else' © selection of fns/ops.attrib names© default fields in fixtime order.1998-03-05 else © Condition f else g ...2000-10-11 pow © Explicit function power.2002-10-31 wsdiff © Workspace differences.2002-10-31 attrib © Function/operator attributes.'n ©'attrib namesattrib © Function/operator attributes.wsdiff © Workspace differences.pow © Explicit function power.else © Condition f else g ...'“n ©'attrib namesattrib © Function/operator attributes.else © Condition f else g ...pow © Explicit function power.wsdiff © Workspace differences.© names and comments.© names and comments in name order.'n i r×c ’ ©'attrib names© name id rows cols syntax comment.attrib Dyadic 56×82 ½„{¸}’¾ © Function/operator attributes.wsdiff Dyadic 102×82 ½„{¸}’¾ © Workspace differences.pow Dyadic 3×50 ½„{¸}(¸¸’’)¾ © Explicit function power.else Dyadic 4×45 ½„{¸}(¸¸’’¾¾)¾ © Condition f else g ...'dTt s'attrib names2002-10-31T14:19:22 53402002-10-31T10:42:03 85282000-10-11T12:14:54 3601998-03-05T16:41:54 436'n “s'attrib namespow 360else 436attrib 5340wsdiff 8528'n “rדc'attrib namespow 3×50else 4×45attrib 56×82wsdiff 102×82© ISO timestamp and size.© names in order of WS footprint.© names in row, then col order.389


© The final examples show the difference in sorting on date or date-time.'“d “t n'attrib 2†names2002-10-31 10:42:03 wsdiff2002-10-31 14:19:22 attrib'“d n'attrib 2†names2002-10-31 attrib2002-10-31 wsdiff'“d^t n'attrib 2†names2002-10-31 wsdiff2002-10-31 attrib© date-time order© date order.© date-(time) order.See also: PF_keys.606ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎdinrslt „ ##.din ''© Evaluation of multi-line D-expression.{name} „ ##.din name© Definition of multi-line Dfn,NB: From <strong>Dyalog</strong> V14, this function is available as User-Command: ]dinput.[din] inputs a multi-line expression or definition, directly from the session,using •-prompting.[din] anticipates the input of closing braces and infers appropriate indentationfor each prompt. "White dots" are included at each tab point in the prompt as areminder that we're in an input loop and to assist in keeping track of nestinglevels.Entering a single '…' character, at any time, will abort the input loop.In the following illustration, only the underlined characters are typed. Notice,in particular, that no closing braces need be entered:din'dup'¯¯¯¯¯¯¯¯· dup„{· · {¯· · · ¾ ¾¯¯¯· · }¾¯· }Technical note:After swapping leading '·' characters in prompted input for blanks, [din] accumulatesin ¸ and ¾:¸ defn: Vector of input line vectors, including comments.¾ expr: ª-separated concatenation of uncommented input lines.At exit, [din] tries to ŒFX accumulated [defn] lines. If this succeeds, the nameof the newly-fixed function is returned as a shy result.Otherwise, if the fix fails, the accumulated [expr] is executed and, if successful,its result is returned.390


This means that a dfn definition will be fixed as entered, with comments intact.In addition, though a multi-line _derived_ function will fail to ŒFX, it will beestablished at second attempt by the executed assignment. See examples below.Examples:din''· †{· · size„Œsize ¾· · ¾,size· }¨‡Œnl ¼10dddd 1044din 6760dup 324gcd 480notes 4652display Œcr din'gcd'· gcd„{ © (c) Euclid· · ¸=0:|¾· · ¾ ’ |¸-¾· }Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ̇gcd„{ © (c) EuclidÛÛ ¸=0:|¾ ÛÛ ¾ ’|¸-¾ ÛÛ} ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙdisp Œcr din'dddd'· dddd„{· · ¾ ¾ © comments· }°{ © disappear· · ¾ ¾· }{· · ¸¸ ¸¸ ¾· }Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÌÛÚ…ÎÎÎÎÂÎÂÎÎÎÎÎÌÛÛÛÛ{¾ ¾}‡°Û{¾ ¾}‡Û{¸¸ ¸¸ ¾}ÛÛÀÎÎÎÎ…ÁÎÁÎÎÎÎ…ÙÛ ‡ÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎ…Ù© multi-line expression evaluation.© multi-line dfn definition.© multi-line derived function definition:See also: dots.389ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎdotscrep „ {dot„'·'} ##.dots crep© Show dfn with "white dots".Returns canonical representation of function [crep] with (by default) "whitedots" issuing vertically from the closing brace of each multi-line D function orfrom the ':' of each closing control structure keyword. This format makes thecode of complex and deeply nested <strong>functions</strong> (arguably) more pleasant to read onthe printed page.The left argument, which defaults to '·', may be any single character.Examples:391


© Using default "white dots":dots Œcr'dots'dots„{© Show dfn with "white dots".· ¸„'·' © white dot.· cmat„ŒCR ¾ © char rep of function.· kwds„':E' ':C' ':U'º¨›cmat © end of ctrl paragraph keywords.· ends„†Ÿ/kwds,›cmat='}' © end of cstructs and dfns.· spcs„^\' '=cmat © leading spaces.· xdents„ends^1,0 ¯1‡spcs © leading exdents.· flood„(®1 2){ © flood upwards into blanks.· · hits„¸º¾ © 1s above 2s· · ~1¹hits:¾ © none: done.· · ¸ ’ hits+¾ © try again with 1 2 … 2 2.· }spcs+2×xdents © spaces 'n braces.· dmask„,2=flood-xdents © mask vector for white dots.· cmat[dmask/,¼½cmat]„¸ © place dots in char matrix,· cmat © and return.}© A more deeply nested function:dots Œcr'fnrepl'fnrepl„{© Function string replacement.· ¸„Œthis © default current space.· 1:shy„{¾~›''}¸.{ŒML„3 © shy rslt: changed function list.· · (‡ŒNL 3 4){ © target space, names of fns (and ops).· · · (ŒNR ¸){ © function source lines.· · · · ¸­¾:'' © no change: ignore.· · · · €ŒFX ¾ © name of changed fn.· · · }(ŒNR ¸){ © function lines.· · · · fm to„¾ © target and replacement strings.· · · · cvex„{(+\fmº¾)›¾}fm,¸ © partitioned at find points.· · · · (½to)‡¹{to,(½fm)‡¾}¨cvex © collected with replacements.· · · }¨›¾ © each line of,· · }¨›¾ © each function.· },¨¾ © find and replace vectors.}© Using heavier dots:'.'dots Œcr'fnrepl'fnrepl„{© Function string replacement.. ¸„Œthis © default current space.. 1:shy„{¾~›''}¸.{ŒML„3 © shy rslt: changed function list.. . (‡ŒNL 3 4){ © target space, names of fns (and ops).. . . (ŒNR ¸){ © function source lines.. . . . ¸­¾:'' © no change: ignore.. . . . €ŒFX ¾ © name of changed fn.. . . }(ŒNR ¸){ © function lines.. . . . fm to„¾ © target and replacement strings.. . . . cvex„{(+\fmº¾)›¾}fm,¸ © partitioned at find points.. . . . (½to)‡¹{to,(½fm)‡¾}¨cvex © collected with replacements.. . . }¨›¾ © each line of,. . }¨›¾ © each function.. },¨¾ © find and replace vectors.}392


© Using solid lines:'Û'dots Œcr'fnrepl'fnrepl„{© Function string replacement.Û ¸„Œthis © default current space.Û 1:shy„{¾~›''}¸.{ŒML„3 © shy rslt: changed function list.Û Û (‡ŒNL 3 4){ © target space, names of fns (and ops).Û Û Û (ŒNR ¸){ © function source lines.Û Û Û Û ¸­¾:'' © no change: ignore.Û Û Û Û €ŒFX ¾ © name of changed fn.Û Û Û }(ŒNR ¸){ © function lines.Û Û Û Û fm to„¾ © target and replacement strings.Û Û Û Û cvex„{(+\fmº¾)›¾}fm,¸ © partitioned at find points.Û Û Û Û (½to)‡¹{to,(½fm)‡¾}¨cvex © collected with replacements.Û Û Û }¨›¾ © each line of,Û Û }¨›¾ © each function.Û },¨¾ © find and replace vectors.}© Traditional function with control structures:)copy util FIND393


dots Œcr'FIND'{RSLT}„{DIRS}FIND NAMES;ŒIO;ŒML© NAMES in workspaces in DIRS.ŒIO ŒML„0© {DIRS} defaults to WSPATH.·:With ŒNS''© Temp space avoids ŒCY clash.·· names„(‡ŒFMT†(ŒEX'NAMES')/NAMES)~¨' ' © Copy names to avoid ŒCY clash.·· findstr„'{I4 {I4 I4} {I4 I4} {I4 I4} {I4 I4} {I4 I4} T[260] T[14]}'· 'first'ŒNA'I4 kernel32|FindFirstFileA ',findstr· 'fnext'ŒNA'U4 kernel32|FindNextFileA I4 >',findstr· 'close'ŒNA'kernel32|FindClose I4'· sepr patn„{ © WSPATH separator and file patt· · wind„';' '\*.dws' © windows style.· · unix„':' '/*' © unix style· · ¾œwind unix © select appropriate style.· }'M'=2œ'.'ŒWG'<strong>APL</strong>Version' © Windows / Unix.·· found„0½›'' © Accumulator for found list.·· :Trap 1000 © Interrupt: result so far.· ·· · :For dir :In (ŒEX'DIRS')/{ © For each directory in list.· · · 2=ŒNC ¾:(‡ŒFMT†–¾)~¨' ' © use supplied directory list.· · · sepr{ŒML„3 © partition WSPATH,· · · · (((1+¾=¸)›¾)~¨¸)~›'' © at ';'.· · · }2 ŒNQ'.' 'GetEnvironment' 'WSPATH' © directory list from WSPATH.· · }'DIRS'· · ·· · · :For wsid :In { © For each ws in directory.· · · · handle stuff„first(¾,patn)0 © first '.dws' file.· · · · handleˆ0:0½›'' © bad handle: quit.· · · · trim„{(^\¾¬œŒAV)/¾} © Trim name at null byte.· · · · handle{ © Subsequent workspaces.· · · · · ok stuff„fnext ¸ 0 © Next file.· · · · · ok¬1:¾•close ¸ © Bad status, quit.· · · · · name„trim 6œstuff © File name.· · · · · '.dse'­¯4†name:¾•close ¸ © .dse files cause a Œcy prob.· · · · · ¸ ’ ¾,›name © OK: next wsid.· · · · }›trim 6œstuff © first wsid.· · · }dir © current directory.· · · ·· · · · slash„œ(dir,'\')•'\/' © user's / or \ preference.· · · · path„dir,slash,wsid © full directory name.· · · ·· · · · 'tmp'ŒNS'' © temp ns for copy.· · · · :Trap 11 © trap ws version probs.· · · · · tmp.ŒCY path © copy ws.· · · · · drop„1+½tmp.ŒCS'' © size of temp ns name.· · · · · tmp°{ © traverse sub spaces.· · · · · · found,„¸{ © found list extended by:· · · · · · · 0‰¸.ŒNC ¾:« © object not found: null.· · · · · · · name„drop‡(•¸),'.',¾ © found object name.· · · · · · · Œ„path,' ',name © display find.· · · · · · · ›path name © new found list item.· · · · · · }¾ © for this namespace.· · · · · · 0=œ½¸.ŒNL 9: © no subspaces: done.· · · · · · ¸.(–¨‡ŒNL 9)’¨›¾ © traverse each subspace.· · · · · }¨names © for each name.· · · · :EndTrap· · · · ŒEX'tmp' © discard copied ws.· · · :EndFor· · :EndFor· :Else· · Œ„'...' © Acknowledge interruption.394


· :EndTrap· © 'RSLT' may be ŒCY'd fn:· RSLT„(ŒEX'RSLT')/found © install result variable.:EndWithSee also: refmt.401ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎfix{name} „ ##.fix rep© Fix function/operator rep.Fixes the function or operator from its [rep]resentation. The name of the fixedfunction is returned as a shy result.Technical note:[fix] uses a technique suggested by Maurice Jordan for re-establishing the Œorof a function. It works as follows:Taking the Œor of a function is fast because it doesn't do anything! A _pointer_to the function is marked as _value_, rather than _function_ in the parser'sinternal state. This causes a name assigned to the value to have a class of 2,rather than 3. Conversely, the Œfx of a Œor is fast because the parser merelymarks the pointer as _function_.A D- (or traditionally defined) _operator_ may be given either an array or afunction as operand. On receipt of an operand, the operator looks at the internalstructure of the value passed and allocates a name class accordingly. Ifthe operator receives the Œor of a function as operand, it deduces that it hasbeen passed a function and sets the class (of ¸¸, in the case of a d:op) to 3.Maurice's traditionally defined operator looked like this:’ Z„(QOR APPLY)A © Apply ŒOR of function to A[1] Z„QOR A’In the case of a derived function, [fix] passes the Œor as _operand_ and the[name] as _argument_, to an inner operator. Notice that as ¸¸ is quoted in theargument to – that is used to effect the assignment, a dummy, unvisited ¸¸ isplaced on the following line. This is in order to force the enclosing {}s to bean operator and so receive the Œor as left operand, rather than left argument.Example:fix„{© Fix function/operator rep.···¸{ © Œor (operand to inner operator).–¾,'„¸¸ ···' © name derived/primitive/system function.¸¸© (dummy ¸¸ forces class).}¾ © name for assignment.···}disp vecÚ…ÎÎÎÎÎÂÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÌÛ Û ÛÚ…ÎÎÂÎÎÎÎÌÛÛ ’tfn Û ’dfn ÛÛafnÛ ×/ ÛÛÛ Û ÛÀÎÎ…Á’ÎÎÎÙÛÀ’ÎÎÎÎÎÁ’ÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎ…Ùfix¨vec© vector of function reps.© fix <strong>functions</strong>.395


disp Œcr¨'afn' 'dfn' 'tfn' © function 'source'.Ú…ÎÂÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÌÛ×/Ûdfn„{3†¾}Ûz„tfnÛÛ Û‡z„ŒTS‡ÀÎ…ÁÎÎÎÎÎÎÎÎ…ÁÎÎÎÎ…Ùafn dfn tfn600300© test <strong>functions</strong>.See also: rep.402ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎfnrefscvecs „ ##.fnrefs func © External refs from function ¾.Returns a vector of names referenced by function: func. This list is approximateand should be used only as a guide. It does not, for example, 'see' names referencedby the execute function: –, nor does it compute correctly in all cases thescope of names within a D function.Fnrefs attemps to bind namespace references, so that "aa.bb.cc" and "##.dd" willeach contribute a single item to the result. However, "(refs #).ee" will generatethree items: 'ref' '#' 'ee'.Example:fnrefs'ssword'wordsSee also: tokens.170 words.169ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎfnrepl{fns} „ {space„Œthis} ##.fnrepl (from to) © Function string replacement.[fnrepl] replaces occurrences of string [from] with string [to] in all defined<strong>functions</strong> and operators in [space] (default current space). The shy result is alist of the names of <strong>functions</strong> that have been changed.Example:fnrepl 'ŒTCNL' '•TCNL'(refs #)fnrepl¨›'foo' 'bar'find'¸°,¨'#.packH[16] †,/(¸°,¨0 1)’¨¾#.packH[39] †,/(¸°,¨0 1)’¨¾#.queens[6] next„¸°,¨hddisp fnrepl'¸°,¨' '(›¸),¨'Ú…ÎÎÎÎÂÎÎÎÎÎÎÌÛpackHÛqueensÛÀÎÎÎÎ…ÁÎÎÎÎÎ…Ù© change all ŒTCNL … •TCNL in current space.© change 'foo' to 'bar' everwhere.© find fns containing '¸°,¨'.© extended codes for sub-trees.© visit each branch,© possible next steps.© show changed <strong>functions</strong>.find'(›¸),¨'© find fns containing '(›¸),¨'.#.packH[16] †,/((›¸),¨0 1)’¨¾© extended codes for sub-trees.#.packH[39] †,/((›¸),¨0 1)’¨¾© visit each branch,#.packS[6] 1=½,¾:2,¸ ª a„(›¸),¨0 1#.queens[6] next„(›¸),¨hd© possible next steps.See also: refs.380396


ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎisdfnbool „ ##.isdfn name© Test for D function.[isdfn] takes a character vector argument [name] and returns 1 if it refers to aD function or operator.NB: With <strong>Dyalog</strong> V11, this function became trivial. ŒNC with a nested argumentnow returns sub-classes, which distinguish various types of <strong>functions</strong>, includingD-fns. Prior to V11, the task was more challenging ...Technical notes:The many ways to write this function seem to split into two broad categories:"honest" and "sneaky". The "honest" solutions attempt to analyse the source codeof the function, whereas the "sneaky" ones try to detect differences in theeffect of various system operations. This is not to say that an honest solutionis any "better" than a sneaky one.Honest------The main difficulty with looking at the source code, is that the header line ofan _ambivalent_ traditional function in <strong>Dyalog</strong> contains braces:rslt„{larg} func rarg... which rules out testing for the string '„{' in the header. Checking that the_last_ character in the function is a '}' also comes unstuck, because a trad-fncould finish by defining a D-fn:rslt„{larg} func rarg...dup„{¾ ¾}The water is further muddied because <strong>Dyalog</strong> header lines may contain comments,which could make a trad-fn resemble a D-fn.rslt„{larg} func rarg © {}and the first line in a D-fn might contain character literals, which could makeit look a little like an ambivalent trad-fn.dfn„{larg'}' func rarg...The "honest" approach seems to boil down to:It's a D-fn iff:the ŒCR is a matrix,whose first line,(ignoring comments and character literals)contains a '{' andnothing follows any matching '}'.Examples of this approach include:Phil Last's:isdfn„{© is fn/op named in (¾) a dfn/dop?{1=½½¾:0© vector ŒCR - derived function{('}'=œ²¾)Ÿ¬/+š¾°.='{}' © where do braces balance?}{¾/þ^\¾¬'©'© remove remarks}{¾/þ~¬\¾='''' © remove literals}¾[?1;]~' ' © first line}ŒCR ¾© foreign needs qualified name}397


Reima Naumanen's "one-liner" (broken up a bit to show what's happening):isdfn„{{('}'=ŒIOœ¾)Ÿ¬/('{}'°.=¾)+.×~2|+\''''=¾}(²{¾/þ^\~¾='©'}}ŒIOœŒNR ¾)~' 'Veli-Matti Jantunen produced a whole suite of <strong>functions</strong>!isdfn_W0„{©| Add comment column to the function body,©| fix the fn in an unnamed namespace and check for the©| last non-blank - dfn doesn't have the last lamp!}c„ŒCR ¾ ª '}'¬¯1†(,c)~' ':0n„ŒNS'' ª '}'=«½¯1†n.(,ŒCR ŒFX ##.c,'©')~' 'isdfn_W1„{©| Add blank column to the function body,©| fix the fn in an unnamed namespace and check for the©| header - dfn starts with "dfn„{"}f„¾~' ' ª c„ŒCR f ª (f,'„{')»(2+½f)½c:0n„ŒNS'' ª (f,'„{')­(2+½f)½n.(ŒCR ŒFX' ',##.c)isdfn_W2„{©| Count the brace balance in the function body.©| If the balance is fulfilled only with the last©| right brace which ends the function body -> dfn!}f„¾~' ' ª c„ŒCR f ª (f,'„{')»(2+½f)½c:0ŒML„3 ª g„{(~¬\¾='''')/¾}¨‡cr„¹{(^\¾¬'©')/¾}¨gs„{(+\¾='{')-+\¾='}'}(1+½f)‡r~' '(1=+/s=0)>0¹¯1‡sisdfn_W3„{©| A variant of brace balance algorithm.©| This time only the header is checked.}f„¾~' ' ª c„ŒCR f ª (f,'„{')»(2+½f)½c:0h„{(~¬\¾='''')/¾}{(¾¼'©')†¾}c[ŒIO;]1‰+/0={(+\¾='{')-+\¾='}'}(1+½f)‡h~' 'isdfn_W4„{©| If a) the body starts with fun„{, and©| b) the following part between braces is a valid name©| => the header is that of a trad fn/operator.©| Alas, we have to check for the D function df„{variable}, too :(}f„¾~' ' ª v„¯7‡6‡ŒVR f(f,'„{')»(2+½f)½v:0¯1=ŒNC(2+½f)‡(¯1+v¼'}')†v:1(ŒIO+(Ÿ/ŒTC¹v)


isdfn_W5„{©| This time we'll just check the header:©| If the brace balance is met, the fn is traditional...©| but we must take care for the one-line dfns, too (with drop).}n„ŒNR f ª 0¹½n:02|+/'{}'¹þ{(~¬\¾='''')/¾}{(¾¼'©')†¾}(-1=½n)‡(ŒIOœn)~' 'isdfn_W6„{©| A slightly different variant from isdfn_W4v„¯7‡6‡ŒVR ¾ ª '}'¬¯1†v:0 © dfn _must_ end with }f„¾~' ' ª (f,'„{')»(2+½f)½v:0 © ..and start with dfn„{© now we have a dfn OR trad fn with a header like© fun„{left} fun right..© mop„{left}( mop R) right..© dop„{left}(L dop R) right..}¯1=ŒNC(2+½f)‡(¯1+v¼'}')†v:1 © not {left} ?~Ÿ/ŒTC¹v© dfn„{variable} caseSneaky------The alternative is to discover a "dark little corner" in the interpreter thatbehaves in a different way for D- and trad- <strong>functions</strong>. For example:- If auto-format is on, the ŒCR of a trad-fn starts with a blank.- ŒREFS of a D-fn bombs with a DOMAIN ERROR.- Dyadic ŒSTOP on a D-fn has no effect.These all seem to work; are in general simpler and quicker than the honest waybut are dangerous in that the behaviour on which they rely is susceptible to being"fixed". Some (slightly amended to make them Œml- and Œio- proof) examplesare:Jim Ryan's:isdfn„{' '¬«½ŒCR ¾}Ray Cannon's:VMJ's:isdfn„{11::10•ŒREFS ¾}isdfn_W7„{0¹½ŒVR ¾:0 ª ~0¹½ŒMONITOR ¾:0~0¹½0 ŒMONITOR ¾:0•« ŒMONITOR ¾1 2­2½1 ŒAT ¾}and this from someone who, understandably, prefers to remain anonymous:isdfn„{ŒSTOP°¾{(¸¸ ¾)€«­¸¸ 0}ŒSTOP·¾}399


John Daintree notes that Œfx is intolerant of unbalanced braces when fixing adfn. He exploits this by appending an extra brace and attempting a re-fix, whichfails for a dfn and succeeds for a trad-fn. In order to avoid damaging an existingtraditional function, the Œfx is applied in a temporary namespace. Note thatthis version classifies a named derived function (sum„+/), or even a variable(pi„3.142), as a dfn. It is safe therefore, only in a context where the subjectis known to be either a trad-fn or a d-fn.isdfn„{«­0½(Œns'').Œfx'}',þŒnr ¾}Paul Mansour's solution seems to be "sneaky but safe" as it relies on a behaviouraldifference that is there by design, rather than accident:If a D-fn is assigned a name, the ŒCR/ŒNR/ŒVR of the function reflects thatname. In particular, if a second name is assigned, the ŒCR/.. using the new namereflects that new name. This is not the case with a trad-fn where the ŒCR remembersits "original" name:d1„{¾ ¾} ª d2„d1 ª Œcr'd2' ª ­/Œcr¨'d1' 'd2' © D-fn.d2„{¾ ¾}0Œfx,›'zz„t1 zz' ª t2„t1 ª Œcr't2' ª ­/Œcr¨'t1' 't2'rg„t1 rg1© Trad-fn.Paul's solution exploits this distinction in the following way:isdfn„{© Test for D function.1 ¯2 0»ŒIOœŒAT ¾:0 © No exp result, Not ambivalent, can't be D•„–¾© Give it a new name»/ŒVR¨'•'¾© Compare}There is one small problem with the approach. What if the subject functionhappens to be called '•'? In this case, whatever the function type of the argument,the ŒVR's will match and [isdfn] will return 0. We need to find a new namethat is guaranteed to be distinct from ¾. One solution is to use a temporaryname whose pedigree is known. "isdfn" fits the bill!isdfn„{© Test for D function.1 ¯2 0»ŒIOœŒAT ¾:0 © No exp result, Not ambivalent, can't be D.'isdfn'­¾~' ':1 © I'm a D-fn!isdfn„–¾© Give it a new name.»/ŒVR¨'isdfn'¾ © Compare.}This solution works in all cases but is slightly precarious. If we wanted to renamethe function: IsDfn„isdfn, we would have to remember to make correspondingchanges to both occurrences of the string 'isdfn' in the code body. A morerobust but more complex solution would be to have an alternative temporary namein reserve in case there's a clash. VMJ suggests:isdfn„{© Test for D function.0¹½ŒVR ¾:0© Irrepresentable: not a dfn.1 ¯2 0»ŒIOœŒAT ¾:0 © No exp rslt, not ambiv, can't be D.f0„f1„–¾© Choose new names and(ŒVR ¾)»ŒVR'f',•'f1'»¾~' ' © compare.}Choosing names 'f0' and 'f1' ensures that a name clash is impossible. If thesubject function is one of these, it can't be the other one.Notice that these latter solutions, correctly or incorrectly, fail to classify aD _operator_ as a 'dfn'. This version of ##.isdfn includes operators:400


isdfn„{ © Test for Dfns/Dops.0.2=1|ŒNC›¾}ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎncnvec „ ##.nc names © Extended ŒNC for objects named in ¾. Supplied by David Crossley, nc takes a list of names (character scalar, vector,matrix) and returns a numeric vector of extended name classifications:NB: In <strong>Dyalog</strong> V11.0 and above, extended ŒNC gives similar information directly.Special:¯1: invalid name0: unused1: labelVariable:20: normal21: ŒorFunction:30: traditional "header-style" function.31: locked .. .. ..32: assigned33: dynamic34: externalOperator:40: traditional "header-style" operator.41: locked .. .. ..43: dynamicNamespace:90: Non-GUI namespace91: GUI object92: Ref to non-GUI namespace93: Ref to GUI objectFor the purposes of this function, a "Ref" in the last category is deemed to bea space whose name is distinct from its display form.Examples:© Extended class of:3330nc'nc'nc Œfx'trad' 'fn'nc†'notes' 'scripts'© Dfn© TradFn© Space90 90xx yy„notes scripts © synonymsnc†'xx' 'yy'© "Refs".92 92nc'fooey' © unused.0See also: ncpath.400401


ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎncpathcvec „ {path„Œpath} ##.ncpath names© Œpath-aware Œnc.Suggested by Mark Johns, this function searches namespaces in its left argument(default ŒPATH) for <strong>functions</strong> and operators named in its right argument.Right argument [names] is a simple character matrix, vector or scalar, suitableas a right argument for ŒNC.For each name found along the [path], [ncpath] reports:3 for a function,4 for an operator and0 otherwise.Note that this function ignores names with a class other than 3 or 4.Bugs:This rather simple coding of the function does not cope with the special Œpathentry: '†'. We could arrange to have it substitute occurrences of '†' in Œpathwith an appropriate sequence '## ##.## ##.##.## ···'. The following expressionreturns such a sequence:{¸,'.',¾}\{'##'}¨(Œcs'')•'.'(muse:Remember that operators may take arrays, as well as <strong>functions</strong>, as operands.We could choose to extend primitive operator each (¨) to "apply" an arrayoperand to each item of its argument. Then sub-expression {'##'}¨ abovecould be replaced with just '##'¨.disp '##'¨ '...'Ú…ÎÂÎÎÂÎÎÌÛ##Û##Û##ÛÀÎ…ÁÎ…ÁÎ…Ù)0¨¼2 30 0 00 0 0Examples:3203 4ncpath'display'notes.Œnc'display'notes ncpath'display'ncpath†'display' 'rows'Œpath„'Œse'Œse.dup„{¾ ¾}© display is a function.© display is a variable in notes.© no display function in notes.© rows is an operator.© set Œpath for utility fns.© make a duplicator fn in Œse.dup 3333 33© function reference using Œpath.03Œnc'dup'ncpath'dup'© no dup in current space.© dup is a fn somewhere on Œpath.See also: nc.399 refs.380402


ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎrefmtcrep „ {tabs csep„4} ##.refmt crep© Reformat dfn/op representation.Reformats the (possibly nested) canonical representation of D-function or operator[crep]. The optional left argument (default 4) specifies:[tabs] the indentation width for nested inner <strong>functions</strong> and[csep] the number of blank columns to separate code from comment lines.A previous version of this function, which took and returned the name of a functionto be reformatted, can be composed:old_refmt „ Œfx°refmt°ŒcrNB: If [AutoFormat <strong>functions</strong>] is checked in the session's Options…Configure…Trace/Edit tab, the system will reimpose its own canonical formatting style when<strong>functions</strong> are fixed. To preserve "non-standard" formatting, uncheck the box andtry again.Examples:display Œcr'refmt'© unformatted dfn.Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ̇refmt„{ŒIO ŒML„0 © Reformat dfn/op. ÛÛ ¸„4 ª dent csep„¸ © default indents and ©-separation.ÛÛ ŒFX{ © refix function. ÛÛ unqt„{~¬\¾=''''} © mask of unquoted tokens. ÛÛ code coms„‡³†{ © code and comment vectors. ÛÛ umsk„unqt ¾ © unquoted chars. ÛÛ cmsk„Ÿ\umsk^¾='©' © comment mask. ÛÛ code coms„(0 1=›cmsk)/¨›¾ © code / comments. ÛÛ rlb„{(Ÿ\¾¬' ')/¾} © remove leading blanks. ÛÛ clean„²rlb²rlb code © cleaned code. ÛÛ clean coms © clean code / comment. ÛÛ }¨¾ © for each line. ÛÛ dents„{ © indentation for each line ÛÛ toks„(unqt ¾){¸\¸/¾}¾ © unquoted code characters. ÛÛ dvec„-š0 1²+\'{}'°.=toks © brace-depth of each token. ÛÛ lmask„toks='·' © start of each line. ÛÛ (dent×lmask/dvec)/¨' ' © indentation for each line. ÛÛ }†,/'·',¨code © collected code vector. ÛÛ scoms„(›csep½' '),¨coms © separated comments. ÛÛ icode„‡†dents,¨code © indented code lines. ÛÛ icode,¨scoms © reunited code and comments. ÛÛ }ŒNR ¾ © lines of function. ÛÛ} ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙ403


display 4 refmt Œcr'refmt' © generous formatting.Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ̇refmt„{ŒIO ŒML„0 © Reformat dfn/op. ÛÛ ¸„4 ª dent csep„¸ © default indents and ©-separation.ÛÛ ŒFX{ © refix function. ÛÛ unqt„{~¬\¾=''''} © mask of unquoted tokens. ÛÛ code coms„‡³†{ © code and comment vectors. ÛÛ umsk„unqt ¾ © unquoted chars. ÛÛ cmsk„Ÿ\umsk^¾='©' © comment mask. ÛÛ code coms„(0 1=›cmsk)/¨›¾ © code / comments. ÛÛ rlb„{(Ÿ\¾¬' ')/¾} © remove leading blanks. ÛÛ clean„²rlb²rlb code © cleaned code. ÛÛ clean coms © clean code / comment. ÛÛ }¨¾ © for each line. ÛÛ dents„{ © indentation for each line ÛÛ toks„(unqt ¾){¸\¸/¾}¾ © unquoted code characters. ÛÛ dvec„-š0 1²+\'{}'°.=toks © brace-depth of each token. ÛÛ lmask„toks='·' © start of each line. ÛÛ (dent×lmask/dvec)/¨' ' © indentation for each line. ÛÛ }†,/'·',¨code © collected code vector. ÛÛ scoms„(›csep½' '),¨coms © separated comments. ÛÛ icode„‡†dents,¨code © indented code lines. ÛÛ icode,¨scoms © reunited code and comments. ÛÛ }ŒNR ¾ © lines of function. ÛÛ} ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙdisplay 2 1 refmt Œcr'refmt' © frugal formatting.Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ̇refmt„{ŒIO ŒML„0 © Reformat dfn/op. ÛÛ ¸„4 ª dent csep„¸© default indents and ©-separation.ÛÛ ŒFX{ © refix function. ÛÛ unqt„{~¬\¾=''''} © mask of unquoted tokens. ÛÛ code coms„‡³†{ © code and comment vectors. ÛÛ umsk„unqt ¾ © unquoted chars. ÛÛ cmsk„Ÿ\umsk^¾='©' © comment mask. ÛÛ code coms„(0 1=›cmsk)/¨›¾ © code / comments. ÛÛ rlb„{(Ÿ\¾¬' ')/¾} © remove leading blanks. ÛÛ clean„²rlb²rlb code © cleaned code. ÛÛ clean coms © clean code / comment. ÛÛ }¨¾ © for each line. ÛÛ dents„{ © indentation for each line ÛÛ toks„(unqt ¾){¸\¸/¾}¾ © unquoted code characters. ÛÛ dvec„-š0 1²+\'{}'°.=toks © brace-depth of each token. ÛÛ lmask„toks='·' © start of each line. ÛÛ (dent×lmask/dvec)/¨' ' © indentation for each line. ÛÛ }†,/'·',¨code © collected code vector. ÛÛ scoms„(›csep½' '),¨coms © separated comments. ÛÛ icode„‡†dents,¨code © indented code lines. ÛÛ icode,¨scoms © reunited code and comments. ÛÛ }ŒNR ¾ © lines of function. ÛÛ} ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙSee also: wrapnote.186 dots.389ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎrepenc „ ##.rep name© Encapsulate function/operator.Returns an encapsulation of the function or operator [name] suitable for storingin an array or on file. Notably, the representation accommodates named, derived(or "assigned") <strong>functions</strong>, such as: sum„+/.404


Technical note:For traditional and D- <strong>functions</strong>/operators, Œor could be used directly, but theŒor of a derived function does not include its name for re-fixing. In this case,the capsule is a (name Œor) pair. Note that the rank of Œcr is used to distinguish:0=½½Œcr ¾: primitive / system function.1=½½Œcr ¾: derived function.2=½½Œcr ¾: defined / D-function.Example:Œfx'z„tfn' 'z„Œts'dfn„{3†¾}afn„×/© trad fn.© D fn.© assigned fn.disp rep¨'tfn' 'dfn' 'afn'Ú…ÎÎÎÎÎÂÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÌÛ Û ÛÚ…ÎÎÂÎÎÎÎÌÛÛ ’tfn Û ’dfn ÛÛafnÛ ×/ ÛÛÛ Û ÛÀÎÎ…Á’ÎÎÎÙÛÀ’ÎÎÎÎÎÁ’ÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎ…ÙSee also: fix.393 mns.66ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎtracerslt „ {larg} (func ##.trace) rarg© Trace function application.Trace applies its function operand to (or between) its argument(s). As a sideeffectthe argument(s), function and result are displayed in the session.Trace can be used as a debugging aid and to observe the behaviour of primitive(and D- or defined) operators.In the case of a _primitive_ operator, trace shows its _formal_ reduction sequence.When unobserved by trace, the interpreter is free to "cheat" in a numberof ways. For example, +/ of a boolean array is actually performed 8-items-at-atime,and for associative <strong>functions</strong> such as + and ×, scan (\) operates cumulativelyin one pass from left to right.Technical note:trace„{¸„€func„¸¸{aa„¸¸ ª ŒOR'aa'}¾rslt„¸ ¸¸ ¾Œ„¸ func ¾'=>'rsltrslt}© Trace function application.© function representation.© result.© display.© return result.As '¸¸' is outside the domain of ŒOR, the function representation is produced bynaming the operand function within an inner operator.func„¸¸{aa„¸¸ ª ŒOR'aa'}¾© function representation.With a change to the interpreter to bring '¸¸' into the domain of ŒOR, this linecould be replaced with the simpler:func„Œor'¸¸'© function representation.405


This in turn, leads to successive simplifications (sic):trace„{¸„€© Trace function application.rslt„¸ ¸¸ ¾© result.Ú… Œ„¸(Œor'¸¸')¾'=>'rslt © display.ÀÎ rslt© return result.}trace„{¸„€rslt„¸ ¸¸ ¾ ÎÎÎÎÎÎÎÎÎ̆«½²Œ„¸(Œor'¸¸')¾'=>'rslt}© Trace function application.© result.© display and return result.trace„{¸„€†«½²Œ„¸(Œor'¸¸')¾'=>'(¸ ¸¸ ¾)}© Trace function application.© display and return result.Examples:1 2 3 +trace 4 5 6 © vector addition.1 2 3 + 4 5 6 => 5 7 95 7 91 2 3 +trace¨ 4 5 6 © item-wise addition.1 + 4 => 52 + 5 => 73 + 6 => 95 7 9¼trace¨2 3¼ 2 => 1 2¼ 3 => 1 2 31 2 1 2 3×trace/¼54 × 5 => 203 × 20 => 602 × 60 => 1201 × 120 => 120120×trace\¼51 × 2 => 22 × 3 => 61 × 6 => 63 × 4 => 122 × 12 => 241 × 24 => 244 × 5 => 203 × 20 => 602 × 60 => 1201 × 120 => 1201 2 6 24 120© monadic function application.© reduce© scan2 3 4 5 +trace.(×trace) 6 7 8 9 © inner product.5 × 9 => 454 × 8 => 3232 + 45 => 773 × 7 => 2121 + 77 => 982 × 6 => 1212 + 98 => 110110redl„{†¸¸þ/²¾}© operator: reduce from left.406


+trace redl ¼5 © trace operand application.1 + 2 => 33 + 3 => 66 + 4 => 1010 + 5 => 1515+trace/¼54 + 5 => 93 + 9 => 122 + 12 => 141 + 14 => 1515© compare with reduce (fold from right).See also: foldl.45 scan.79ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎUndoRedocommit „ (Œns'') ##.UndoRedo© Derive undo/redo function.commit var ... © commit application state.'!' commit _© initialize undo/redo stacks.'†' commit size © truncate undo stack.sizes „ '?' commit _ © query undo/redo stack lengths.var ... „ '' commit var ... © redo (wind) application state.UndoRedo is an operator, used to derive a function for saving and restoring thestate of an application. We can use it to implement "Undo" and "Redo" commands.One way to provide undo/redo is for each command that changes the state of theapplication, to stack an equal and opposite inverse command. Each _Insert_ wouldstore a _Delete_ and each _Delete_ would store the corresponding _Insert_. Thisis the technique used by the <strong>Dyalog</strong> editor.A simpler way is to stack the complete state of the application at each "commit"point. Because of the way <strong>Dyalog</strong> shares arrays, this method does not use as muchworkspace as one might expect. All unchanged parts of the state, are _shared_ at_every_ level in the undo stack. A commit called after only a small modificationof the state uses little workspace - see the example below.The state of a typical application might be represented by the values of a (potentiallylarge) number of variables: V1, V2, ..., which need to be restored inorder to roll back to a prior state. In this case, the derived "commit" functionwould be called as follows:'!' commit 0© initialize undo/redo stacks.commit V1 V2 ... © commit application state.... © application changes its state.commit V1 V2 ... © commit application state.(V1 V2 ...) „ '' commit V1 V2 ... © redo .. ..(When the number of values defining the application state is large, it may betidier to define a pair of "getstate" and "setstate" <strong>functions</strong>.407


setstate„{getstate„{props V1 V2 ...„¾props„... Œwg... _„... Œws do ... © see …do„V1„a b ca b c°„V1V2„i j ki j k°„V2... ...Vn„x y zx y z°„Vnprops V1 V2 ... }}Then:commit getstate 0setstate '


'!'­¸:¸¸.(redo undo max„« « ¾) © initialize history vectors.}Then:'?'­¸:,†½¨¸¸.(redo undo)''­¸:¸¸{0=½¸.redo:¾¸.undo„¾ psh ¸.undoœnext ¸.redo„pop ¸.redo}¾'†'­¸:¸¸{¸.max„¾¸.(undo„(¾˜½undo)†undo)¸.redo„«}¾commitV „ (Œns'') UndoRedoV© query history vectors.© undo:© no more undo: state unchanged.© push current state on redo vector.© pop last state.© redo:© no more redo: state unchanged.© push current state on undo vector.© pop last state.© resize undo vector.© set new undo vector size limit.© truncate undo vector.© remove redo records.© derive commitV function.'!'commitV 10© initialise, setting history size.commitV ... © commit transactions ...'†'commitV 4© change history vector size.Example:0 0commit„(Œns'')UndoRedo'!'commit 0'?'commit 0A B C D„'now' 'is' 'the' 'time'commit A B C DA B „ 'then' 'was'commit A B C DA C „ 'that' 'a'commit A B C DB D „ 'took' 'while'© derive a commit function.© initialise history stack.© both stacks empty.© initial application state.© commit application state.© change state,© commit changes.© change state,© commit changes.© change state,Œ„A B C Dthat took a while'?'commit 00 3Œ„A B C D„'


'?'commit 0 © redo stack has 1 item.1 2Œ„A B C D„''„commit A B C Dthat was a timeŒ„A B C D„'>'commit A B C Dthat took a while'?'commit 00 3Œ„A B C D„'


Local variables are avoided by duplicating a value to produce a pair and operatingon each item of the pair in turn. The sequence of events could be representedgraphically by the following "railway diagram":œ €°Œnuntie\² €°¸¸\2½¾ Œntie 0expression‡ ‡ ‡ ‡ ‡ ‡ÎÎÌÃÎ[Œnuntie]ÎÌÎ[¸¸]ÎÂÎ[Œntie]ÎÎ railway diagramÀÎÎÎÎÎÎÎÎÎÎÎÙÀÎÎÎÎÎÎÙ† † † † † †Û Û Û Û Û ÀÎÎξ Œntie 0ÎÎ opens file and returns tie number.Û Û Û Û ÀÎÎÎÎ2½ÎÎÎÎÎÎÎÎÎÎÎ duplicates tie number into a pair.Û Û Û ÀÎÎ΀°¸¸\ÎÎÎÎÎÎÎÎÎÎÎÎÎ applies ¸¸ to second item of pair.Û Û ÀÎÎβÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ swaps the items of the pair.Û ÀÎÎ΀°Œnuntie\ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ unties pair's new second item.ÀÎÎÎœÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ extracts pair's new first item.Example:Œnsize file Œwsid,'.dws'217608© size of saved version of this workspace.See also: getfile.409 xtabs.179ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎgetfilelines „ {tabs„0 {ctype„80}} ##.getfile filename © Text file ¾ as nested vector.Returns text file as a vector of character vectors using default ASCII to ŒAV(or current Œnxlate 0 mapping if this has been changed), translation. The filecontent is split at [LF] chars, and [CR] chars are removed.Optional left argument {tabs} specifies tabstop positions for tab expansion. Avalue greater than 0 (the default) causes horizontal tab characters in the fileto be replaced with an appropriate number of blanks in the result.Optional left argument {ctype} specifies the type of characters to be read fromthe file. In pre-unicode versions of the interpreter, this would always be leftto default or set to 82. In unicode interpreters, the default is 80 but it couldbe set to 160 or 320.Note that tabs can be expanded after reading the file, using …xtabs„¨, but thisis not quite as fast.Example:{Œ„¾}¨12†8 getfile'c:/dyalog90/aplfmt/default.dft'+-----------------------------------------------++ D a t e F o r m a t s ++-----------------------------------------------+D:SundayD:Monday Tuesday Wednesday Thursday FridayD:SaturdayM:January February MarchM:April May JuneM:July August SeptemberM:October November DecemberSee also: putfile.425 xtabs.179411


ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎhexdump{cmds„''} ##.hexdump file© Hex dump of native file.Native [file] is opened and the first few words displayed in hexadecimal. Type to show successive words of the binary file, and ")" to quit.Each output line starts with the file position, followed by the file content (ifany) at this position, displayed as hexadecimal 32-bit words:hexdump'myfile'00000000:·020801aa 00000000 00000001 00000001·00000010:·00000001 00000000 00000034 00000001·00000020:·00000054 00000054 00000000 00000000·00000030:·fffffffc 00000014 36a33e18 00000000·00000040:·00000006 0000222f 00000001 00000003·00000050:·ff00ff00 ffffffab 00000000 00000002·00000060:·00000000 00000002 00000000·00000070:·00000080:·00000090:·000000a0:·) © quitThe file position may be changed using expressions, which are evaluated left-toright.The current value is an implicit left argument to otherwise niladic ormonadic <strong>functions</strong>. For example:+3 © increment.%4 © 4-residue.ƒ © set base.Numeric input is interpreted as hexadecimal.Input sequences, including partial expressions and commands, may be named usinga simple macro definition scheme.Hexdump's optional left argument, character vector [cmds] is a sequence of commandsto be processed prior to interactive input.Hexdump has a somewhat arcane user interface, reminiscent of software tools datingfrom the 1970s. The function could be viewed as a simple hexadecimal calculator,which just happens to display the content (if any) of its file at the positionof the current value.Note that the current value is a 32-bit unsigned quantity, which means that onlythe first 4GB of the subject file is accessible.Expressions:hexset value (file position).+ hex increment.- hex decrement.× hex multiply.÷ hex integer divide.% hex integer remainder (residue commute).ƒ set address base.! absolute position (subtract base).* get 32-bit word from file„ hex put 32-bit word to file.: case case selection (see below).412


Commands:( call, saving current state.) return / quit.© ··· comment.'···' message.? help.‚ trace on/off.< var include sub-script.name = ···· niladic macro.name ¾ = ·· monadic macro.System variables:Œdw = · display width (words).Œbe = · big-endian 0/1.Some examples-------------42 © set file position to hex 42 (decimal 66) bytes.10*×4-(c*)ƒ© set base to 4 × value at 0x10, minus value at 0x0c.÷100×100 © value with least significant byte cleared.(%2:'even':'odd') © display parity.clsb = ÷100×100 © define macro.Relative Addresses------------------Many binary files have an internal structure, where values in the file representpositions relative to a "base". A <strong>Dyalog</strong> workspace, for example, contains memorypointers that were in effect when the workspace was saved. In the .dws filethese can be viewed as offsets from a notional base.Command "ƒ" is used to set the base, which is then added to:- directly entered hexadecimal values _excluding_ those immediately to theright of a monadic function:00000000:·2ÀÎÎÎÎÎÎÎÎÎÎ base added to this value.00000002:·+ 3 + 4ÀÎÎÎÁÎÎ base _not_ added to this value- values retrieved from the file content using monadic *:00000099:·*ÀÎÎÎÎÎÎÎÎÎÎ base added to value of file word at 0x99.Apart from indirection (*), the content of the file has no bearing on addresscalculation. Only the current base and position play a part. To illustrate this,the following examples use the special file "nul", which is of zero length:hexdump'nul'00000000:·ƒ Sets the base to the current file position. This base is then added to allsubsequent input values to calculate the absolute file position.········:·1000 © set file position to 0x1000.00001000:·ƒ © set base to 0x1000.00001000:·ab © go to _relative_ file position 0xab,000010ab:·© which is _absolute_ file position 0x10ab.413


! Foils relative addressing by subtracting the current base:········:·cd000010cd:·!000000cd:·ef!000000ef:·© relative 0xcd© absolute 0xcd© absolute 0xefTo remove relative addressing, reset the base to 0:········:·0!ƒ© reset base.Call / Return-------------When investigating a tree structure, for example, it is often convenient to beable to return to a parent node after examining subnodes. Command "(" saves thecurrent state (file position, base, macro table, trace state) and it is restoredby a matching ")".Note that saving the base allows a temporary base to be installed for the durationof a local operation.The current calling level is indicated by the number of white dots (·) followingthe input prompt. Entering ")" at level one terminates hexdump.A nuance: there is a subtle difference between parentheses used in the above wayand those used to bind the right argument of a monadic function: 1+(2×3). In thelatter case, the current value (6) is _returned_ as the result of the subexpression,whereas in the former (call/return) case, the pre-call value is_restored_. Notice this distinction in the following:hexdump'nul'00000000:·2+3 © set file position to 5.00000005:·0''© note file position is _5_.00000000:·(2+3) © call; set file position to 5; return.00000000:·0''© note file position is _0_.00000000:·1+(2+3) © set file position to 1+5.00000006:·0''© note file position is _6_.00000000:·(2+3)+1 © call; set file position to 5; return; advance 1.00000001:·0''© note file position is _1_.This rarely causes a problem in practice, as parentheses are never needed to theleft of a function, just as in <strong>APL</strong> they are never needed to the right.Message Output--------------Consecutive messages are concatenated and may contain embedded newlines:display exampleÚ…ÎÎÎÎÎÎÎÌÛ'join ' ÛÛ'these 'ÛÛ'up' ÛÛ ÛÛ' ÛÛoutput ÛÛseparateÛÛlines ÛÛ ÛÛ' ÛÀÎÎÎÎÎÎÎÎÙ© sample script vector.414


example hexdump'nul'join these upoutputseparatelines00000000:·)Case Selection--------------A case is selected using the construct (value :case0 :case1 ··· :default).To allow the selected case to modify the environment _outside_ the construct(for example, to set the file position) it is copied to the input stream _after_processing the construct's closing parenthesis.On encountering a colon:if the current value is zero orif this is the final (default) case:the first case is moved to immediately after the closing ")" andany other cases are discarded:ÚÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌ ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ0Û:first case:next case:··· ) more Û…Û) first case more ÛÀÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙ ÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙÚÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌ ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛnÛ:final case ) more Û…Û) final case more ÛÀÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙ ÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙotherwise:the first case is discarded andthe current value is decremented by 1:For example:ÚÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌ ÚÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛnÛ:first case:next case: ···) more Û…Ûn-1Û:next case: ···) more ÛÀÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙ ÀÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙ00000000:·('The value at 0x0c is ' c*%2 :'even':'odd')'.'The value at 0x0c is even.00000000:·123 © set value to 123.00000123:·$ © display current value, see $ macro below.12300000123:·(99:$) © selects default case $, which is12300000123:·(99)$ © evaluated like this,12300000123:·(99$) © not like this.9900000123:·Tip: a case may not contain an unbalanced ")", as this would terminate the construct.However, the ")" may be _named_ outside the case selection and the nameused within:] = ) © ] means )pop = (depth::]) © pop if depth¬0.415


Macros------File exploration is made a little easier by being able to define simple macros.Macro names may include any character and those composed exclusively from A-Z,a-z, 0-9, _ and Œ may be of any length (otherwise, they are of length 1 and lexicallyequivalent to primitive commands). This means, for example, that a macrowith a name such as µ, need not be blank-separated from a literal number: µ99.string interpretation------ --------------aabb name "aabb"aa bb two names: "aa" and "bb"µ name "µ"¸¸two names: "¸" and "¸"__one name "__"‘_•three names "‘", "_" and "•"{oct} three names "{", "oct" and "}"Œthis single name.When a macro name is encountered in the input stream, it is immediately replacedwith the corresponding value and processing resumed. In particular, this meansthat the macro value is re-scanned, so that any sub-macros are also evaluated.Unbounded recursion will "hang" hexdump:hexdump'nul'00000000:·hang = hang00000000:·hang© don't try this at home:© unboundedly recursive macro,© ... hangs until interrupted.Macros may redefine (cover) even primitive constructs. For example "!" (nonrelativevalue) could be coded as:!=-(0) © subtract base value.š and -------Keystrokes and are converted to tokens š and respectively.By default these system commands advance and reverse the file position by 4׌dw,where Œdw is the current display width (number of word-columns). We can changethe effect of entering these keystrokes by redefining them. Notice in thefollowing example, how backing up over the prompt, generates commands.'100'hexdump'nul'00000100:·š=''+1 Û advance one byte per .00000100:·=''-1 Û back up one byte per .00000100:· Û Û00000101:· Û Û00000102: Û Û000001 Û Û000000fd:·)Û might be coded to return from a call:416hexdump''00000000:·=)Û = return from call00000000:·(((((( Û call to depth 700000000:······· Û at depth 700000010:··· Û over 4 dots to return 4 levels00000000:··· Û enter at depth 300000010:· Û return 2 further levels00000000: Û return right out of hexdump.


NB: generation depends _only_ on detecting that the input is shorter than theprompt. If so, a corresponding number of '' chars are injected into the inputstream. In particular, no account is taken of the _content_ of the shorterinput. This means that chars following backspaces, up to the initial size of theprompt, are ignored:hexdump''00000000:·(((( Û increase depth to 5.00000000:····· Û advances file posn 0…10.00000010:···1234 Û 1234: only 34 recognised :-(00000034:····· Û advances 34…44.00000044:··· Û reverses 44…24.00000024:·····1234 Û 1234 sets file posn.00001234:·····))))) Û quit.to avoid confusion, always enter chars on a separate line. See note on"Prior line editing", below.Providing code for š can be used to great effect in annotating a structure thatextends over a number of lines of output.NB: be wary of the effects of redefining primitive commands:hexdump'nul' © don't try this at home:00000000:·)= © ) expands to the null string, so00000000:·) © there is no way out!00000000:·)...Even hexadecimal numbers may be used as macro names! When processing a tokenfrom the input stream, hexdump looks first in the macro table _before_ wonderingwhether it's a number. A hex value, occluded by a macro name, may be accessed byprefixing an extra 0:hexdump'nul'00000000:·face© go to 0xface.0000face: 0 © go to 0.00000000:·face='happy' © macro definition.00000000:·face© macro reference.happy00000000:·0face© go to 0xface0000face:·hexdump'nul'00000000:·3='three'00000000:·100000001:·200000002:·0300000003:·400000004:·)The body of a macro extends as far as the next newline together, if input isfrom a script, with any following lines that are indented further than thedefining "=". This "offside rule" allows definitions to extend over a number oflines and enables macros to define macros:aa = ...© definition of aa, which when calledbb = ... © aa defines bb, which when calledcc = ... © bb defines ccdd = ... © aa defines dd.ee = ... © ee is _not_ part of aa (not right of aa's =).Note that the above macro-defined macros are global; the only way to localise adefinition is with () call/return.417


Some examples of macro definitions might be:right = (+4*© call right pointer in binary tree.retn = )© return from callline = '---------------------------------'help = 'm: more rows © multi-line help output.· · n: next sibling· · q: quit'symb = '········ ········ ········ ········ lft····· rgt····· val····· spc· · lft = (+0c*· · rgt = (+10*· · val = (+14*· · spc = (+18*+c* nsrhow_many = (::'one':'two':'plenty')© primitive counting.quit = ) quit© exit from any level of ")"s.aa = bb = cc = 'hello' © aa defines bb, which defines cc.Notice that indented macro definitions may be rendered more legible by the presenceof "white dots" (·), which are interpreted as white space and ignored.Macros are stored in a table, which is local to the current calling level. Thismeans that macros defined after a "(", disappear with the corresponding ")".Part of the charm, power and danger of any macro system is that incomplete expressionsmay be named; it is inherently type-unsafe. This means that erroneousdefinitions may be hard to track down.Prior line editing------------------It is often convenient to modify and resubmit lines previously entered into thehexdump session:'Œdw=2'hexdump Œwsid,'.dws' Û Examine WS with display width = 2.00000000:·050903aa 80050009·1234 Û set file posn to 1234 · · · · [A]00001234:·00000005 00003401· Û advances 1234+8…123c0000123c:·037e4fb8 037e50bc·Û advances 123c+8…124400000000:·050903aa 80050009·1234+4321 Û edit & reinput line [A].00005555:·e4000008 e8037f1c· Û file posn is now 1234+4321.Beware however, that all (and only) those characters in the modified input lineto the right of the original prompt are entered into the input stream. This canbe confusing if the display width differs between the prior and current lines:'Œdw=2'hexdump Œwsid,'.dws' Û Examine WS with display width = 2.00000000:·050903aa 80050009·'hello' Û file posn 0; output string · · · [A]helloÛ00000000:·050903aa 80050009·Œdw=1 Û reduce display width to 1.00000000:·050903aa·Û advances 4 bytes.00000004:·80050009· Û edit and resubmit line [A]00000000:·050903aa 80050009·'world' Û the prompt has been overwrittenworldÛ note that the last word of the80050009:·) Û prompt 80050009 has been input!This is also the cause of the problem, mentioned above, when following a sequenceof backspaces with some characters intended for input:418'(((('hexdump'' Û start hexdump at depth 5.00000000:····· Û advances to posn 10.00000010:···1234 Û 1234, only '34' extends beyond prompt00000034:····· Û so only 34 input.


to avoid confusion, always enter chars on a separate line.Writing to file---------------Command "„" overwrites the word at the current position with its hex-valuedright argument. As a safeguard, writing is enabled only if the first characterin hexdump's left argument is a '„'.'„'hexdump'myfile'© enable write.00000000:·03020100 07060504 0b0a0908 0f0e0d0c·„ace00000000:·00000ace 07060504 0b0a0908 0f0e0d0c·(4„dead)00000000:·00000ace 0000dead 0b0a0908 0f0e0d0c·(8„(beef×10000))00000000:·00000ace 0000dead beef0000 0f0e0d0c·To overwrite a single byte, we might use a macro to merge the new value with theexisting word:00000000:·00000ace 0000dead beef0000 0f0e0d0c·setb = *÷100×100+00000000:·00000ace 0000dead beef0000 0f0e0d0c·(f„(f setb aa))00000000:·00000ace 0000dead beef0000 aa0e0d0c·Tracing-------Setting trace mode using "‚" shows the current input line as each token is processed.Addresses generated during the trace are distinguished by a "‚" char inplace of the ":", following the file position.hexdump'nul'00000000:·2+3×4 '' © untraced expression.00000014:·‚2+3×4‚ '' © traced expression.00000014‚ 2+3×4‚ '' © traced expression.00000002‚ +3×4‚ '' © traced expression.00000002‚ 3×4‚ '' © traced expression.00000005‚ ×4‚ '' © traced expression.00000005‚ 4‚ '' © traced expression.00000014‚ ‚ '' © traced expression.00000014:·2+‚3×4‚ '' © traced subexpression.00000002‚ 3×4‚ '' © traced subexpression.00000005‚ ×4‚ '' © traced subexpression.00000005‚ 4‚ '' © traced subexpression.00000014‚ ‚ '' © traced subexpression.00000014:·Including sub-scripts---------------------Command "


display xd © script for hex and decimal conversion macros.Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ© display decimal equivalent of hex value: ÛÛÛÛ dec = (:'0':'1':'2':'3':'4':'5':'6':'7':'8':'9':(÷a dec)(%a dec))ÛÛÛÛ© set hex equivalent of decimal value: ÛÛÛÛ hex = ÛÛ . = ÷10 sub × a + ÛÛ sub = (::(%10:.0:.1:.2:.3:.4:.5:.6:.7:.8:.9)) ÛÛ sub ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙxd hexdump'nul'00000000:·(42 dec) © show decimal equivalent of 0x42.6600000000:·66 hex © set hex equivalent of decimal 66.00000042:·)Decode the "magic" word at the start of a <strong>Dyalog</strong> binary file:display file© script for file identification macro:Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛfile = (0!ƒÛÛ· · ; = ' © newline ÛÛ· · ' ÛÛ· · dec = (_d:(÷a dec)(%a dec)) ÛÛ· · hex = (_d:'a':'b':'c':'d':'e':'f':(÷10hex)(%10hex))ÛÛ· · ·_d = :'0':'1':'2':'3':'4':'5':'6':'7':'8':'9' ÛÛ· · dd = (%100 dec) ÷100 © show dec 'n skip. ÛÛ· · xx = (%100 hex) ÷100 © .. hex .. ÛÛ· · ÛÛ· · wsfile = ÛÛ· · · · 'Version: ' 2* dd '.' dd ; ÛÛ· · · · 'Saved by: ' 4* dd '.' dd '.' dd ; ÛÛ· · · · 'Type: ' ÛÛ· · · · · (÷80%2:'big':'little')'-endian' ÛÛ· · · · · (÷40%2::' ,dextend') ÛÛ· · · · · (÷20%2::' ,64-bit' ) ÛÛ· · · · · (÷10%2::' ,dalign' ) ÛÛ· · · · · (÷08%2::' ,unicode') ÛÛ· · ÛÛ· · (0*%100-aa ÛÛ· · ·:'<strong>Dyalog</strong> ' ÛÛ· · · default = 1* 'file 0x' xx ÛÛ· · · (1*%100 ÛÛ· · · : default ÛÛ· · · :'32-bit component file: ' 2* dd '.' dd ÛÛ· · · :'External Variable: ' 2* dd '.' dd ÛÛ· · · :'Workspace'; wsfile ÛÛ· · · : default ÛÛ· · · : default ÛÛ· · · : default ÛÛ· · · :'Session'; wsfile ÛÛ· · · : default ÛÛ· · · :'64-bit component file: ' 2* dd '.' dd ÛÛ· · · : default ÛÛ· · · ) ÛÛ· · ·:'File ' 0* xx' 'xx' 'xx' 'xx' ...' ÛÛ· · ) ÛÛ· ) ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙ420


Here is the osc function (see …osc„ and the example in …traj„):hexdump'nul'00000000:·osc = dec ' '(:'?'::(%2:÷2:×3+1) osc)00000000:·dec = (:'0':'1':'2':'3':'4':'5':'6':'7':'8':'9':(÷a dec)(%a dec))00000000:·3 osc3 10 5 16 8 4 2 100000001:·7 osc7 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 100000001:·)This repeater macro calls its operand sequence a specified number of times.00000000:·reps=(::oseq -1 reps)© repeater macro.00000000:·oseq='ding '© operand sequence.00000000:·3 reps © 3 repetitions.ding ding ding00000000:·oseq=dec ' '© new operand sequence.00000000:·5 reps © 5 repetitions.5 4 3 2 100000000:·Monadic macros--------------As the above examples show, a surprising amount may be achieved using niladicmacros, which operate on the current value. Sometimes however, it is convenientto "parameterise" a macro with a right argument. Monadic macros are distinguishedwith a "¾" between the name and the "=". Compare the niladic macro:© Display current value "¸" in decimal:da= (:'0':'1':'2':'3':'4':'5':'6':'7':'8':'9':(÷a da)(%a da))with its monadic counterpart:© Display ¾ in decimal:dw ¾ = (¾:'0':'1':'2':'3':'4':'5':'6':'7':'8':'9':(dw(¾÷a))(dw(¾%a)))then:...00000000:·(3e8 da)100000000000:·dw 3e8100000000000:·...© display "¸"© display ¾we can recode the osc function from above to take an explicit (right) argument:osc ¾ = dw ¾ © osc: probably returns 1.· · (¾ © arg is :· · :'?' © 0: huh?· · :1 © 1: done.· · :' ' © display inter-number gap.· · (¾%2 © parity:· · : osc(¾÷2) © even: ’¾÷2· · : osc(¾×3+1) © odd: ’1+3×¾· · )· · )...00000000:·osc 33 10 5 16 8 4 2 100000001:·osc 77 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 100000001:·)421


and even access both implicit (left) and explicit (right) arguments to emulate adyadic function. Here is Ackermann's function - but with the usual order of argumentsreversed, as this is easier to code. In other words: ack_ ­­ ackþ.ack_ ¾ = © da'-'dw ¾© (commuted) Ackermann's function.· · (¾ © ack_„{· · :+1 © ' ' © ¾=0:¸+1· · : © ' ' ©· · ·( ©· · ·: 1 ack_ (¾-1) © ¸=0:1 ’ ¾-1· · ·:-1 ack_ ¾ ack_ (¾-1) © ((¸-1)’ ¾)’ ¾-1· · ·) © }· · )...00000000:·dw(0 ack_ 0) © 0 ackþ 0100000000:·dw(1 ack_ 1) © 1 ackþ 1300000000:·dw(1 ack_ 2) © 1 ackþ 2500000000:·dw(2 ack_ 3) © 2 ackþ 32900000000:·dw(3 ack_ 3) © 3 ackþ 3 (takes a minute or so).6100000000:·)(remove the © from within the first, third and forth lines to watch it working).Finally, this macro displays the sequence of prime numbers, until it is interrupted:primes = all=(prime 2::da' ')+1 all© display primes.· · da = (:'0':'1':'2':'3':'4':'5':'6':'7':'8':'9':(÷a da)(%a da))· · prime ¾=(-¾:1:(%¾:0:prime(¾+1))) © ¸ is prime?· · 2 all © starting from 2 ......00000000:·primes© display the primes.2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 101Technical notes---------------[hexdump] maintains state variables, relatively global to the main command loop.It commits the sin of destructive assignment, which is generally a bad thing asthis introduces "state". The presence of state makes reasoning about a programdifficult and hinders code transformation. However, in this case, the alternativewould be to pass the variables among all participating <strong>functions</strong>, whichwould make the code considerably more unwieldy.In <strong>Dyalog</strong> V10 and above, we can have hexdump use _mapped_, rather than _native_files by substituting the following four lines:fndiff'dfnsV10 hexdump' 'hexdump'· read„{323 ŒDR map[{(¾


For example, if we want to implement a _stack_ in which to pass values as parameters,we need only add two more command lines to the loop function:'‡'­cmd:rem ’ vpush ¾ ©© ‡ push value.'†'­cmd:rem ’ vpop ¾ ©© † pop value.together with their support <strong>functions</strong> and an initialisation line:vpush„{stack,þ„¾}vpop„{(stack‡þ„1)€œstack,¾}stack„«© push value onto stack.© pop value from stack.© global stack variable.Then:hexdump_pro''© extended hexdump.00000000:·50 © go 5000000050:·‡ © push value00000050:·80 © go 8000000080:·‡999 © push and go 99900000999:·† © pop last value (80)00000080:·† © pop previous value (50)00000050:·† © empty stack: pop does nothing00000050:·) © quit.and we could commute the (implicit) left argument with the right argument of amonadic function mfn:00000000:·larg ‡ rarg mfn †© mfnþSome handy scripts------------------Open an edit window on a new character vector using, for example:)ed …script_namethen cut & paste lines from the following:©ÎsnipÎhereÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎapls=(*!%100::(*!%100 apl) +1 apls)apl=(© <strong>APL</strong> string from file.© <strong>APL</strong> char translation.:'¦':'¦':'' :'¦':' ':'•':'•':'•':'•':'•':'•':'•':'%':'''':'¸':'¾':'_':'a':'b':'c':'d':'e':'f':'g':'h':'i':'j':'k':'l':'m':'n':'o':'p':'q':'r':'s':'t':'u':'v':'w':'x':'y':'z':'•':'•':'¯':'.':'«':'0':'1':'2':'3':'4':'5':'6':'7':'8':'9':'•':'€':'¥':'$':'£':'¢':'‘':'A':'B':'C':'D':'E':'F':'G':'H':'I':'J':'K':'L':'M':'N':'O':'P':'Q':'R':'S':'T':'U':'V':'W':'X':'Y':'Z':'•':'•':'ý':'·':'•':'•':'•':'•':'•':'Ç':'È':'Ê':'Ë':'•':'Í':'•':'•':'•':'Ò':'Ó':'Ô':'Õ':'•':'•':'•':'•':'Þ':'ã':'ì':'ð':'ò':'õ':'{':'€':'}':'•':'¦':'¨':'•':'Ä':'Å':'Æ':'þ':'É':'Ñ':'Ö':'Ø':'Ü':'ß':'à':'á':'â':'ä':'å':'æ':'ç':'è':'é':'ê':'ë':'í':'î':'ï':'ñ':'[':'/':'š':'\':'':'':'¬':'Ÿ':'^':'-':'+':'÷':'×':'?':'¹':'½':'~':'†':'‡':'¼':'±':'*':'—':'˜':'’':'°':'(':'›':'œ':'•':'ž':'ƒ':'‚':'|':';':',':'‹':'Š':'”':'“':'³':'²':'´':'µ':'Ž':'!':'•':'–':'•':'®':'­':'»':'ó':'ô':'ö':'ø':'"':'#':'•':'&':'•':'Ù':'Ì':'Ú':'À':'Ï':'Î':'Ã':'Ý':'Á':'Â':'Û':'@':'ù':'ú':'û':'•':'ü':'•':'•':'':':':'º':'¿':'¡':'ª':'„':'…':'©':')':']':'•':' ':'§':'Œ':'•':'ÿ')©ÎsnipÎhereÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎascs=(*!%100::(*!%100 asc) +1 ascs)© ASCII string from file.423


asc=(© ASCII char translation.:'¦':'•':'•':'•':'•':'•':'•':'•':'·':'•':'' :'•':'•':'·':'•':'•':'Ø':'É':'Ü':'•':'Ö':'Ñ':'Æ':'ø':'Ä':'Å':'í':'•':'•':'•':'•':'•':' ':'!':'"':'#':'$':'%':'&':'''':'(':')':'*':'+':',':'-':'.':'/':'0':'1':'2':'3':'4':'5':'6':'7':'8':'9':':':';':'':'?':'@':'A':'B':'C':'D':'E':'F':'G':'H':'I':'J':'K':'L':'M':'N':'O':'P':'Q':'R':'S':'T':'U':'V':'W':'X':'Y':'Z':'[':'\':']':'^':'_':'•':'a':'b':'c':'d':'e':'f':'g':'h':'i':'j':'k':'l':'m':'n':'o':'p':'q':'r':'s':'t':'u':'v':'w':'x':'y':'z':'{':'|':'}':'~':'•':'€':'•':'‚':'ƒ':'„':'…':'†':'‡':'ˆ':'‰':'Š':'‹':'Œ':'•':'Ž':'•':'•':'‘':'’':'“':'”':'•':'–':'—':'˜':'':'š':'›':'œ':'•':'ž':'Ÿ':' ':'¡':'¢':'£':'€':'¥':'¦':'§':'¨':'©':'ª':'«':'¬':'­':'®':'¯':'°':'±':'²':'³':'´':'µ':'':'·':'¸':'¹':'º':'»':'¼':'½':'¾':'¿':'À':'•':'•':'•':'Á':'Â':'Ã':'Ç':'È':'Ì':'Ê':'Ë':'•':'Í':'•':'•':'•':'Î':'Ò':'Ó':'Ô':'Õ':'Ï':'×':'Ù':'•':'•':'•':'Ú':'•':'Þ':'ß':'à':'á':'â':'ã':'ä':'å':'æ':'ç':'è':'é':'ê':'ë':'ì':'Û':'î':'ï':'ð':'ñ':'ò':'ó':'ô':'õ':'ö':'÷':'Ý':'ù':'ú':'û':'ü':'ý':'þ':'ÿ')©ÎsnipÎhereÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎΩ display ASCII chars:ch4 = Œdw=4© display 4 words ASCII·


Examples:Û<strong>Notes</strong>hexdump Œwsid,'.dws'© dump this WS Û00000000:·050903aa 80050009 02310050 fffc3c45·Û00000010:·00000060 000019c0 00000000 02432f9b·'message' Ûdisplay msg.messageÛ00000010:·00000060 000019c0 00000000 02432f9b· Û00000020:·00000000 00000000 00000000 00000000· Û00000030:·00000000 02432cdd 00000000 00000000·0 '' Ûgo 0.Û00000000:·050903aa 80050009 02310050 fffc3c45·18c-(8*)ƒÛset base.0000018c:·fffffff9 00000003 00003121 023141f8·Œdw=2Ûreduce width.0000018c:·fffffff9 00000003·lft = +0c* © follow left subtree Ûdefine,0000018c:·fffffff9 00000003·rgt = +10* © follow right subtree Û macros.0000018c:·fffffff9 00000003·Œdw=5Ûincrease width.0000018c:·fffffff9 00000003 00003121 023141f8 00000000·lft Ûfollow left.00004334:·fffffff9 00000004 00004001 023123e8 02314d38·lft Û00002524:·fffffff8 00000003 00000001 02315218 023152d0·rgt Ûfollow right.0000540c:·fffffff9 00000003 00000001 02317210 02313a0c·rgt Û00003b48:·fffffff9 00000003 00000001 0231546c 02315b80·? Ûshow help.hex relative file posn. Û+ hex add. Û- hex subtract. Û× hex multiply. Û÷ hex integer divide. Û% hex integer remainder. Û* get word from file. Û„ hex put word to file. Û! absolute position. Û: case select case. Û( call. Û) return. Ûƒ set base. Û'···' display message. Û© comment. Û? help. Û‚ trace on/off. Û< var include subscript. Ûname=·· define macro.Û00003b48:·fffffff9 00000003 00000001 0231546c 02315b80·0!ƒ'' Ûreset base = 0.Û00000000:·050903aa 80050009 02310050 fffc3c45 00000060·1234 Ûabsolute addr.00001234:·0000c801 0231c8e8 02311894 02311108 fffffffb·Û00001248:·00000001 0000001f 00000003 00604010 fffffff8·) Ûquit.425


© Macro definitions may be included in the left argument command stream:'tlx=14*' hexdump 'comp.dcf'© component file dump.00000000:·000901aa 00000002 00000001 00000001·00000010:·0000001b 00000234 00000000 00000000·tlx 'top level index'top level index00000234:·0000004c 000001f4 00000000 00000000·00000244:·00000000 00000000 00000000 00000000·00000254:·00000000 00000000 00000000 00000000·00000264:·00000000 00000000 00000000 00000000·tlx* 'second level index'second level index0000004c:·00000000 00000034 0000008c 000000a4·0000005c:·000000bc 000000d4 000000ec 00000104·0000006c:·0000011c 00000134 0000014c 00000164·0000007c:·0000017c 00000194 000001ac 000001c4·tlx*+4* 'first component'first component00000034:·0000000c 41166bcd 00000000 00000004·0000007c:·0000017c 00000194 000001ac 000001c4·tlx*+8* 'second component'second component0000008c:·0000000c 41166bcd 00000000 00000004·0000007c:·0000017c 00000194 000001ac 000001c4·tlx*+c* 'third component'third component000000a4:·0000000c 41166bcd 00000000 00000004·000000b4:·0000000f 00000043 0000000c 41166bcd·)© The following vector might be used by <strong>Dyalog</strong> developers© to analyse the state indicator in an aplcore file:display stackÚ…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÛ© Examine aplcore stackÛÛ 10*×4+c-(8*)ƒ © Set WS biasÛÛ© StackÛÛ n = +c* © next frameÛ shad = ( _shad +14 © call shadow blockÛ sname = ( _sym +0* © call shadow nameÛ svalue = ( _gen +4* © call shadow valueÛÛ© SymbolÛÛ lft = ( _sym +c* © call left subtreeÛ rgt = ( _sym +10* © call right subtreeÛ val = ( _gen +14* © call valueÛÛ© Cols and annotation by type:ÛÛ _sym = Œdw=8 'symbol: left right vaÛ _shad = Œdw=3 'shadow: sname svalue class'Û _gen = Œdw=8ÛÛ Œdw=3 94!+c*© top of stack.ÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ426


stack hexdump 'aplcore' © examine stack:000e55d8:·ffffffec 00000001 00003085·n000e5570:·ffffffe6 00000001 00004005·n000e554c:·fffffff7 00000001 00005385·n000e5520:·fffffff5 00000001 00005475·n000e54a4:·fffffff9 00000001 00006005·n000e543c:·ffffffec 00000001 00003095·n000e53d4:·ffffffe6 00000001 00004005·shadshadow: sname svalue class000e53e8:·02323270 00000000 00000000··000e53f4:·02323250 00000000 00000000··000e5400:·02311cc4 00000000 00000000··000e540c:·02311ce4 00000000 00000000··000e5418:·02311d44 00000000 00000000··000e5424:·02311d24 0237c8d4 00000002··svalue0006ca10:·fffffff8 00000005 00000627 00000001 00000003 02312084 0237c89c 0237c79000e5424:·02311d24 0237c8d4 00000002··snamesymbol: left right value00001e60:·fffffff8 00000009 00002001 02323270 02311d44 0237c89c 22202815 1d221f00006c9d8:·fffffff2 00000004 00000627 00000001 00000009 023121e4 0237c7b0 0237c7d00002320:·fffffffc 00000003 0000000f 000000a6 fffffffa 00000003 0000c001 023242b000e5424:·02311d24 0237c8d4 00000002··000e5430:·02311d04 0236f1b0 00000002··svalue0005f2ec:·ffffd973 00000004 00000627 000009a2 00000004 0235a440 0235a334 0235a4b000e5430:·02311d04 0236f1b0 00000002··000e543c:·ffffffec 00000001 00003095··)000e53d4:·ffffffe6 00000001 00004005·n0006cd0c:·fffffff7 00000001 00002015·n0006ccbc:·ffffffec 00000001 00003095·n0006cc84:·fffffff2 00000001 00004005·n0006cc64:·fffffff8 00000001 00005455·n0006cc4c:·fffffffa 00000001 000058a5·)See also: hex.286 osc.296 traj.220ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎputfile{size} „ {term„2} ##.putfile (fid rows) © Put rows to text-file.Writes [rows] to text file [fid]. Optional left argument (default 2) determineshow many terminator characters are to be appended to each line:2: cr lf (Windows)1: lf (Unix)0: (no line terminators)If the file already exists, its contents are _replaced_.The shy result is the [size] of the file in bytes.Technical note:In preparation for the Unicode version of <strong>Dyalog</strong>, the file is assumed to containany and only characters from ŒAV. This means that pre-Unicode versions shoulduse conversion code 82 and post-Unicode should use 160. This is achieved withversion-independent code:size„cvec ŒNAPPEND ntie,ŒDR ŒAV¯¯¯¯¯¯¯Examples:© write lines to file.lines„'first line' 'second' 'third'putfile 'tmp.txt' lines© create (Windows) text file.427


See also: getfile.409 xtabs.179ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎutf8getcvec „ ##.utf8get fid © Char vector from UTF-8 file ¾.The entire content of UTF-8 file [fid] is returned as a character vector.Requires: …utf8„Examples:18Œ„'Hello ¼½ World' utf8put 'tmp.txt'© put 18-byte UTF-8 file.utf8get 'tmp.txt'Hello ¼½ World© get file.notes.utf8get utf8put 'tmp.txt' © put these notes.1notes.utf8get ­ utf8get 'tmp.txt'© get these notes.See also: utf8put.426 utf8.370 int.289 getfile.409ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎutf8put{size „} cvec ##.utf8put fid © Char vector ¸ to UTF-8 file ¾.Character vector [cvec] is written to file [fid] in UTF-8 format and the filesize in bytes returned as a shy result.Requires: …utf8„Examples:18Œ„'Hello ¼½ World' utf8put 'tmp.txt'© put 18-byte UTF-8 file.utf8get 'tmp.txt'Hello ¼½ World© get file.notes.utf8put utf8put 'tmp.txt' © put these notes.1notes.utf8put ­ utf8get 'tmp.txt'© get these notes.See also: utf8get.426 utf8.370 int.289 putfile.425ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎfilefindcnos „ file ##.filefind string © Find 'string' ¾ in component file ¸.Returns a vector of the indices of components in [file] that contain [string].[string] may be an array of any shape or depth. [file] may be a character stringfile name or the tie number of an already tied file.If a file _name_ is presented as left argument, the file is tied, then searched,then untied.If a file _tie number_ is presented as left argument, the file remains tiedafter the search has completed.428


Examples:tie„'temp'Œfcreate 0app„Œfappend°tie© Create temp file.© Append to file.app'hello' © component 1.app'world' © component 2.app'hello' 'world' © component 3.app'bonjour' 'monde' © component 4.app('hello' 'world')('bonjour' 'monde') © component 5.tie filefind'hello'© components with 'hello'1 3 5tie filefind'bonjour' © etc.4 5tie filefind'hello' 'world'3 5tie filefind'o'1 2 3 4 5tie filefind'e'1 3 4 54 5Œfuntie tie'temp'filefind'monde'Œfnums'temp'Œferase'temp'Œftie 0© release file tie.© after using file [name],© no residual file tie.© remove temp file.See also: find.40ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎbabybmat „ {A CI} ##.baby bmat © Manchester Small Scale Experimental Machine.The Manchester Small Scale Experimental Machine (Baby) was the first operationalelectronic stored-program computer. The first program, which ran on 21 June 1948searched for the highest factor of a given number. See the example below.This function, which emulates the SSEM machine, takes a 32×32 boolean matrixargument that defines the initial state of the machine's memory and, on encounteringa Halt instruction, returns the final state as result.Technical notes for SSEM------------------------NB: Binary values in the SSEM are written with the least significant bits on theleft, for example:0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 © 01 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 © 10 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 © 21 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 © 31 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 © ¯30 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 © -2*181 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 © ¯1+2*18The machine's memory is a 32×32 matrix of bits, stored in a Cathode Ray Tube.The memory is addressed as 32 words or "lines", each 32 bits wide. Each linerepresents either a (2's complement) signed integer or an instruction in thefollowing format:429


0 5 13 16ÚÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ0 0 0 0 0Û0 0 0 0 0 0 0 0Û0 0 0Û0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0ÛÀÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙÛ Û Û ÀÎÎÎ unusedÛ Û ÀÎÎÎÎÎÎÎÎÎ function number (operation code)ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ (spare: storage unit number)ÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ operand address.In addition to the main store, there are three visible "registers":A 32-bit Accumulator.CI 32-bit Control Instruction (program counter) only first 5 bits are used.PI 32-bit Present Instruction (op-code buffer) only first 3 bits are used.andS is a 5-bit internal register used to hold the current operand address.The seven machine instructions are:0 0 0 jmp CI „STORE[S;] © Jump1 0 0 jrp CI+„STORE[S;] © Jump relative0 1 0 ldn A „-STORE[S;] © Load negative1 1 0 sto STORE[S;]„A © Store0 0 1 sub A-„STORE[S;] © Subtract1 0 1 (same as 0 0 1) ©0 1 1 cmp CI+„A


display sumÚ…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ01 ldn 10 © negate first number into accumulator.ÛÛ02 sub 11 © subtract second number. ÛÛ03 sto 12 © store negative of result. ÛÛ04 ldn 12 © negate negative ... ÛÛ05 sto 12 © ... result. ÛÛ06 hlt © stop ÛÛÛÛ10 1234 © input ÛÛ11 5678 © input ÛÛ12 © result ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙHere is an assember for baby code:asm„{ŒML ŒIO„0© Assembler for Baby.¸„32 32 ª lines bits„¸ © memory size.ops„‡8 3½'jmpjrpldnstosub cmphlt' © opcode mnemonics.wds„{¾~›''}°{¾~¨' '}°{(1,1‡¾=' ')›¾} © blank-separated words.raw„{(^\¾¬'©')/¾}© without comments.bin„{²(¸/2)‚¾}© ssem-binary from decimal.†{ © bool store matrix.†(¸¼,¨¼lines)œ¨›lines†¾© lines in line-number order.}/‡³†{ © line_numbers, lines.0::11 ŒSIGNALþ'bad line: ',¾ © something wrong with line.nn instr„{(œ¾)(1‡¾)}wds raw ¾ © line number and content.line„(–nn,',«')°{¸ ¾}© line_number, bool_vector pair.0=½instr:line bits bin 0© null instruction: 0 line.~(1†instr)¹ops:line bits bin–•instr © 1st wd not opcode: raw value.oper rand„2†instr,›'0'© opcode and operand address.addr„5 bin–rand© operand address.unit„8 bin 0© (storage unit number).opco„3 bin ops¼›oper© operator code.line bits†addr,unit,opco© line number and bool vector.}¨‡ŒFMT†¾© char vecs from any format.}.. and a corresponding disassembler:dis„{ŒIO ŒML„0© Disassembler for Baby.lines bits„½¾© no of lines and word size.max„2*bits© miximum unsigned value.ops„‡8 3½'jmpjrpldnstosubsubcmphlt' © opcode mnemonics.arity„–' 1 1 1 1 1 1 0 0 ' © instruction arity.decode„(0 5 13 16¹þ¼bits)°›© instruction decode.lfmt„{¯2†'0',•¾}© line number format.dec„(-max÷2){¸¸+¾¾|¾-¸¸}max°{2ƒ²¾} © signed decimal from ²binary.{ © assembled lines:nn num instr„¾© line, decimal value, instr.(†nn),' ',(•®num),†instr© assembled to char matrix.}‡³†(lfmt¨¼lines){© label for each line.addr _ opco _„dec¨decode ¾© instruction decode.oper„opcoœops© instruction mnemonic.rand„(opcoœarity)/' ',lfmt addr © operand address.¸(dec ¾)(' © ',oper,rand)© instruction © number.}¨‡¾© ... for each line.}The disassembler shows both an integer and instruction decoding of each line. Inparticular, the instruction decoding for a line with a value of 0 is jmp 00.Here is the result of our sum program from above. Notice that the result (1234 +5678 … 6912) is in line[12]:431


display dis baby asm sum © assemble-run-disassemble sum program.Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ̇00 0 © jmp 00ÛÛ01 16394 © ldn 10ÛÛ02 32779 © sub 11ÛÛ03 24588 © sto 12ÛÛ04 16396 © ldn 12ÛÛ05 24588 © sto 12ÛÛ06 57344 © hlt ÛÛ07 0 © jmp 00ÛÛ08 0 © jmp 00ÛÛ09 0 © jmp 00ÛÛ10 1234 © jmp 18ÛÛ11 5678 © jmp 14ÛÛ12 6912 © jmp 00ÛÛ13 0 © jmp 00ÛÛ14 0 © jmp 00ÛÛ15 0 © jmp 00ÛÛ16 0 © jmp 00ÛÛ17 0 © jmp 00ÛÛ18 0 © jmp 00ÛÛ19 0 © jmp 00ÛÛ20 0 © jmp 00ÛÛ21 0 © jmp 00ÛÛ22 0 © jmp 00ÛÛ23 0 © jmp 00ÛÛ24 0 © jmp 00ÛÛ25 0 © jmp 00ÛÛ26 0 © jmp 00ÛÛ27 0 © jmp 00ÛÛ28 0 © jmp 00ÛÛ29 0 © jmp 00ÛÛ30 0 © jmp 00ÛÛ31 0 © jmp 00ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙWatching Baby working---------------------To watch the machine working, we can display its "cathode-ray tube" in an editwindow in the following way:1. Fix function by Cutting & Pasting from the notes above.2. Edit [baby] to inject a new line, which formats the machine state into aglobal character matrix CRT, at the start of the inner state transitionfunction:...0{ © CI increment.CRT°„0 disp{†,/2†¨¾œ¨›'·µ'}¨®¾ © NEW LINE: update CRT display.A CI_ M„¾© Acc Ctrl-Instr Store-Matrix....3. Cut & Paste prog0 (say) assembly source, from the examples below, into a variable:)ed …prog04. Open an edit window on global character matrix CRT:)ed -CRT5. Now run the program:432baby asm prog0 © watch that Baby go ...


History-------The precise wording of "first operational electronic stored-program computer" issignificant.Wikipedia provides an excellent chronology:http://en.wikipedia.org/wiki/Timeline_of_computing_2400_BC-1949http://en.wikipedia.org/wiki/Computing_timeline_1950-1979http://en.wikipedia.org/wiki/Computing_timeline_1980-1989http://en.wikipedia.org/wiki/Computing_timeline_1990-forward433


Here is an extract from this history, with relevance to the SSEM:Provided a computing service to end users ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌMultiple instances built ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌ ÛNumber base ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌ Û ÛPractical ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌ Û Û ÛTuring-complete ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌ Û Û Û ÛElectronic ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌ Û Û Û Û ÛStored program ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌ Û Û Û Û Û ÛGeneral purpose ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌ Û Û Û Û Û Û ÛConceived ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌ Û Û Û Û Û Û Û ÛOperational ÎÎÎÎÎÌ Û Û Û Û Û Û Û Û ÛO C G S E T P N M UÚÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÌTally sticks Û¯35000 Û Û Y Û - Û - Û - Û Y Û 1Û Y Û Y ÛÃÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝBead Abacus Û¯2400 Û Û Y Û - Û - Û - Û Y Û2×5Û Y Û Y ÛÃÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝda Vinci's calculator Û Û1492 Û Y Û - Û - Û - Û Y Û 10Û - Û - ÛÃÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝNapier's Bones Û1617 Û1614 Û Y Û - Û - Û - Û Y Û 10Û Y Û Y ÛÃÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝSlide Rule Û1622 Û Û Y Û - Û - Û - Û Y Û 10Û Y Û Y ÛÃÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝSchickard's calculator Û1623 Û Û Y Û - Û - Û - Û Y Û 10Û - Û Y ÛÃÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝPascal's adding m/c Û1642 Û Û Y Û - Û - Û - Û Y Û 10Û Y Û Y ÛÃÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝBabbage's Anal.Engine Û Û1834 Û Y Û - Û - Û Y Û Y Û 10Û - Û - ÛÃÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝTuring's paper Û Û1936 Û Y Û Y Û - Û Y Û - Û - Û - Û - ÛÃÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝZuse's Z3 Û1941-05-12Û1936 Û Y Û - Û - Û Y Û - Û 2Û Û ÛÃÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝAtanasoff/Berry's ABC Û1942 Û1937 Û - Û - Û Y Û - Û - Û 2Û Û ÛÃÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝColossus Û1943-04 Û Û - Û Y Û Y Û - Û Y Û 2Û Û Y ÛÃÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝHarvard Mk1 Û1944-08-07Û Û - Û - Û - Û - Û Y Û 10Û Û ÛÃÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝENIAC Û1946-02 Û Û Y Û - Û Y Û Y Û Y Û 10Û Û Y ÛÚÎÎÎÎÌÃÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝÛBabyÃÎÎÎÎÎÎÎÎ SSEM Û1948-06-21Û Û Y Û Y Û Y Û Y Û - Û 2Û - Û ÛÀÎÎÎÎÙÃÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝEDSAC Û1949-05-06ÛÛ Y Û Y Û Y Û Y Û Y Û 2Û - Û Y ÛÃÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝACE (Pilot) Û1950-05-10Û1946-02-19Û Y Û Y Û Y Û Y Û Y Û 2Û - Û ÛÃÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝMESM Û1951-01-04Û Û Y Û Y Û Y Û Y Û Y Û 2Û Û Y ÛÃÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝEDVAC Û1951 Û1945-06-30Û Y Û Y Û Y Û Y Û Y Û 2Û - Û Y ÛÃÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝUNIVAC Û1951-03-30ÛÛ Y Û Y Û Y Û Y Û Y Û 2Û Y Û Y ÛÀÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÙO C G S E T P N M USSEM References:http://www.computer50.org/kgill/mark1/ssem.htmlhttp://en.wikipedia.org/wiki/Manchester_Small-Scale_Experimental_Machinehttp://www.computer50.orghttp://www.cs.man.ac.uk/CCS/ssem/progref1.html434


Technical notes:[baby] is written in a pure functional style, without variables or side-effects.Therefore, it would be possible to transform the code step-by-step into a single(albeit long) expression, which contains no name-assignments or guards; onlyprimitive <strong>functions</strong>, operators and parentheses. See …cmat„ for an example ofthis process.(muse:We can view this expression as a mapping from a vector of machine states toa vector of machine states. The vector has one item for each of the2*32×32+2 possible initial machine configurations (if we include initialstates of CI and A). The considerably shorter vector has an item foreach state in which CI addresses a line containing a instruction, togetherwith a single additional special state "ƒ" ("bottom"), which representsnon-termination. See …declarative„.)In the interests of authenticity (but at considerable expense to performance),subsystems of the machine are written to use SSEM-binary values directly, ratherthan to cheat by using regular <strong>APL</strong> numbers. In particular, no use is made of <strong>APL</strong>primitive <strong>functions</strong> ‚ or ƒ. For example, the instruction is implemented asa binary subtractor, which deals directly with its boolean-vector arguments.In fact, the machine has both an adder and a subtractor. As these differ only intheir bit-manipulation <strong>functions</strong> ...add„{© parallel binary adder.c„¸^¾ © note ^ © carry bits.~1¹c:¸Ÿ¾ © note Ÿ © no carry bits: done.(¸¬¾)’ 0,¯1‡c© shift & add/sub carry bits.}sub„{© parallel binary subtractor.c„¸¾ © note > © no carry bits: done.(¸¬¾)’ 0,¯1‡c© shift & add/sub carry bits.}... we can abstract them into a single operator and pass the bit-manipulation<strong>functions</strong> as operands:addsub„{c„¸ ¸¸ ¾~1¹c:¸ ¾¾ ¾(¸¬¾)’ 0,¯1‡c}© parallel binary adder/subtractor.© carry bits.© no carry bits: done.© shift & add/sub carry bits.then:add„^addsubŸsub„© parallel binary adder.© parallel binary subtractor.For example:1 0 1 0 0 add 0 1 1 0 0 © 5 + 6 … 111 1 0 1 01 0 1 0 0 sub 0 1 1 0 0 © 5 - 6 … ¯11 1 1 1 1435


We also need binary successor, predecessor and negation <strong>functions</strong>:inc„{(¾>^\¾)Ÿ


The coding of the function uses an unusual scan {0}\:0 1 1­PI:({0}\²A)’ A CI M © cmp: CI+„A


in0 © ssem-binary is the 32×32 store matrix.0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 1 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 1 0 1 1 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 1 0 1 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 01 1 0 1 1 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 01 1 1 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 01 1 0 1 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 1 0 1 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 01 0 0 1 1 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 01 0 0 1 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 1 0 1 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 01 0 1 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 01 1 0 1 1 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 01 1 0 1 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 1 0 1 1 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 01 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 11 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 11 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0rslt0 „ baby bin0 © Takes many minutes ...438


slt0 © store dump.0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 1 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 1 0 1 1 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 1 0 1 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 01 1 0 1 1 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 01 1 1 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 01 1 0 1 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 1 0 1 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 01 0 0 1 1 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 01 0 0 1 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 1 0 1 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 01 0 1 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 01 1 0 1 1 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 01 1 0 1 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 1 0 1 1 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 01 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 11 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 11 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0439


dis rslt0 © disassembled result of prog000 0 © jmp 0001 16408 © ldn 2402 24602 © sto 2603 16410 © ldn 2604 24603 © sto 2705 16407 © ldn 2306 32795 © sub 2707 49152 © cmp08 8212 © jrp 2009 32794 © sub 2610 24601 © sto 2511 16409 © ldn 2512 49152 © cmp13 57344 © hlt14 16410 © ldn 2615 32789 © sub 2116 24603 © sto 2717 16411 © ldn 2718 24602 © sto 2619 22 © jmp 2220 ¯3 © hlt21 1 © jmp 0122 4 © jmp 0423 ¯262144 © jmp 0024 262143 © hlt25 0 © jmp 0026 ¯131072 © jmp 0027 131072 © jmp 0028 0 © jmp 0029 0 © jmp 0030 0 © jmp 0031 0 © jmp 00hcf© code:01 ldn 30 © Highest common factor (Tootill 1948).02 sto 29 © http://www.computer50.org/mark1/prog98/intro.html03 ldn 3104 sto 3105 ldn 3106 sto 3007 ldn 2908 sub 3009 cmp10 jrp 2711 sub 3112 sto 3113 sub 2814 cmp15 jmp 0016 hlt© data:27 -328 229 030 3141593 © input … rslt31 5214 © input440


dis baby asm hcf00 0 © jmp 0001 16414 © ldn 3002 24605 © sto 2903 16415 © ldn 3104 24607 © sto 3105 16415 © ldn 3106 24606 © sto 3007 16413 © ldn 2908 32798 © sub 3009 49152 © cmp10 8219 © jrp 2711 32799 © sub 3112 24607 © sto 3113 32796 © sub 2814 49152 © cmp15 0 © jmp 0016 57344 © hlt17 0 © jmp 0018 0 © jmp 0019 0 © jmp 0020 0 © jmp 0021 0 © jmp 0022 0 © jmp 0023 0 © jmp 0024 0 © jmp 0025 0 © jmp 0026 0 © jmp 0027 ¯3 © hlt28 2 © jmp 0229 ¯237 © hlt30 79 © jmp 1531 0 © jmp 00© For more sample Baby programs, see:© test script ##.scripts.baby and© http://www.computer50.org/mark1/prog98/prizewinners.htmlSee also: merge.61 truth_tables.593 bf.439 lisp.236ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎbf{tape} „ {tape} ##.bf toks© Brainfuck.The startling term "Brainfuck", henceforth "BF" in the interests of brevity (anddelicacy), denotes both a theoretical machine and its order-code or programminglanguage. The machine is an exercise in minimalism in that it has only eightinstructions, none of which takes an explicit operand.Despite its simplicity, BF is "Turing-complete", which means that, given enoughtime and memory, it may be programmed to solve any problem that a regular computercan tackle. See: http://www.iwriteiam.nl/Ha_bf_Turing.htmlFor a full description of the language, together with some programming examples,after noting the warning about character mapping below, see:http://en.wikipedia.org/wiki/BrainfuckMachine architecture--------------------The machine has just two "moving parts":- An instruction token stream, the character vector argument to the function.441


ÚÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÛ > Û [ Û - Û < Û + Û > Û ] Û < Û °°°ÀÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÎ- An infinite "tape" of cells, each of which holds a single numeric value.ÚÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÛ 1 Û 3 Û 4 Û 48Û 49Û 0 Û 1 Û 2 Û 5 Û 0 °°°ÀÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎThe tape and token stream are manipulated using the eight machine instructions:> Move tape pointer one cell position to right.< Move tape pointer one cell position to left.+ Increment value in current tape cell.- Decrement value in current tape cell.. Output character corresponding to value in current tape cell., Set value in current tape cell to ŒAV-index of an input char.[ If current cell value = 0, jump to right of matching ] in token stream.] If current cell value ¬ 0, jump to right of matching [ in token stream.The final two instructions, [ and ], provide a "while loop".Any characters other than the above eight "+-.,[]" are ignored and may be usedas program commentary (see example below).Programming-----------The following vector (with embedded newlines) is an example of a BF program,which outputs the string 'Hello World':display helloÚ…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛaddr:val shows current cell address and value ÛÛÛÛ+++++ +++++ [ 0:10 × loop: ÛÛ > +++++ ++ 1:10×7 for H W ÛÛ > ++ 2:10×2 for e l l o r l dÛÛ ++ . 1:72 … H ÛÛ>+. 2:21 … e ÛÛ+++++ ++ .. 2:28 … l l ÛÛ+++ . 2:31 … o ÛÛ . 2:31 … o ÛÛ+++ . 2:34 … r ÛÛ--- --- . 2:28 … l ÛÛ--- --- --. 2:20 … d ÛÛ


inp„{(ŒUCS «½•)put ¾} © input single character.Using the tape--------------The final state of the tape is returned as a shy result of the function and maybe re-loaded as optional left argument to a subsequent BF session. This meansthat we can use the state of the tape for simple calculations without having toconvert between characters '1' '2' '3' ... and numbers 1 2 3 .. for input andoutput.Œ„123 45 bf '[->+++[-] ÛŒŒŒ°°°··· +±±ÀÎÎÎÛ < Û < Û by []+-., Û > Û > ÛÎÎÎÙÀÎÎÎÎÎÛ Û instructions Û ÛÎÎÎÎÎÙÀÎÎÎÎÎÎÎÛÛÎÎÎÎÎÎÎÙÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙ443


This infinite tape mechanism is borrowed from Alan Turing's theoretical machine.See: http://en.wikipedia.org/wiki/Turing_machineTechnical notes:Both tape and token stream are pleasingly implemented in <strong>Dyalog</strong> as a recursivedata structure, which is a pair of "snoc" and "cons" …list„s, separated by thecurrent cell. The tape is accessed using structure assignment:get„{_ m _„¾ ª m}put„{l _ r„¾ ª l ¸ r}lft„{(ll l)m r„¾ ª ll l(m r)}rgt„{l m(r rr)„¾ ª (l m)r rr}© current item.© ¸ replaces current item.© tape pointer left.© tape pointer right.Note how <strong>Dyalog</strong>'s "scalar extension" mechanism automatically extends the tape ineither direction, as required:tape„0 99 0tape „ lft lft tape ª disp tapeÚ…ÂÎÂÎÎÎÎÎÎÎÎÌÛ Û ÛÚ…ÂÎÎÎÎÌÛÛ0Û0ÛÛ0Û99 0ÛÛÛ Û ÛÀÎÁ~ÎÎ…ÙÛÀÎÁÎÁÎÎÎÎÎÎÎ…Ùtape „ rgt rgt tape ª disp tapeÚ…ÎÎÎÎÎÎÂÎÎÂÎÌÛÚ…ÎÎÂÎÌÛ Û ÛÛÛ0 0Û0ÛÛ99Û0ÛÛÀ~Î…ÁÎÙÛ Û ÛÀÎÎÎÎÎÎ…Á~ÎÁÎÙtape „ rgt rgt tape ª disp tapeÚ…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÂÎÌÛÚ…ÎÎÎÎÎÎÎÎÎÎÎÂÎÌÛ Û ÛÛÛÚ…ÎÎÎÎÎÎÂÎÎÌÛ ÛÛ Û ÛÛÛÛÚ…ÎÎÂÎÌÛ ÛÛ ÛÛ Û ÛÛÛÛÛ0 0Û0ÛÛ99ÛÛ0ÛÛ0Û0ÛÛÛÛÀ~Î…ÁÎÙÛ ÛÛ ÛÛ Û ÛÛÛÀÎÎÎÎÎÎ…Á~ÎÙÛ ÛÛ Û ÛÛÀÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÙÛ Û ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÁÎÙtape„lft lft tape ª disp tapeÚ…ÎÎÎÎÎÎÂÎÎÂÎÎÎÎÎÎÎÌÛÚ…ÎÎÂÎÌÛ ÛÚ…ÂÎÎÎÌÛÛÛ0 0Û0ÛÛ99ÛÛ0Û0 0ÛÛÛÀ~Î…ÁÎÙÛ ÛÀÎÁ~Î…ÙÛÀÎÎÎÎÎÎ…Á~ÎÁÎÎÎÎÎÎ…Ù© initial 3-cell tape.© move two cells left, extending tape.© move two cells right again.© move two cells right, extending tape.© move two cells left again to home.Further, to increment (decrement) the current cell, we need only add (subtract)the triple 0 1 0.inc„+°0 1 0dec„-°0 1 0© + increment current tape cell.© - decrement current tape cell.However, this operation takes significantly more time as the memory tape becomesextended. This is because the interpreter must add 0 to both (nested) ends ofthe memory tape. It could be argued that the interpreter should special-case 0+¾as a no-op but it would probably still need to traverse a nested array so that,for example, 0+((((5)4)3)2)1(2(3(4(5'?')))) would continue to generate a DOMAINERROR.444


A less elegant but O(1) increment would be:inc„{l m r„¾ ª l(m+1)r}© increment of current tape cell.The only challenging part of the code is in inner operator [skip], which searchesthe token stream, left or right, to find a matching bracket for [ or ]. Thecode is complicated by having to navigate nested pairs of brackets, which meansthat inner matching [...] pairs must be skipped over during the search. [skip]achieves this with a signature double recursion, characteristic of bracket processingin list implementations. See the line with the exdented comment:(muse:skip„{ © search ¸¸-wise for [] match in ¾.fm to„{¾,'[]'~¾}get ¾© current and target brackets.¸¸{© ¸¸ is lft or rgt.tok„get ¾© current token.tok­to:¾© found match: done.tok­fm:’ ¸¸ ’ ¸¸ ¾© inner loop: skip over it.tok­'°':¾© run off end: quit.’ ¸¸ ¾ © skip lft or rgt to next token.}¸¸ ¾© skipping over starting bracket.}In this code, [skip], bound to its operand function [rgt] or [lft], is alwaysapplied by the conditional application operator if„{(¸¸ÿ¾)¸}.... ¾ rgt skip if 0=get... ¾ lft skip if 0¬getIf <strong>Dyalog</strong> were to implement …hyperators„, then (skip if) could be bound atdefinition time:)skip_if„{ © search ¸¸-wise for [] match in ¾.fm to„{¾,'[]'~¾}get ¾ © current and target brackets.¸¸{© ¸¸ is lft or rgt.tok„get ¾© current token.tok­to:¾© found match: done.tok­fm:’ ¸¸ ’ ¸¸ ¾ © inner loop: skip over it.tok­'°':¾© run off end: quit.’ ¸¸ ¾ © skip lft or rgt to next token.}¸¸ ¾© skipping over starting bracket.}{(¸¸ ¸¸¸ÿ¾)¸}© conditional …hyperator„.Refs:[1] http://en.wikipedia.org/wiki/Brainfuck Brainfuck full description.[2] http://en.wikipedia.org/wiki/Turing_machine Turing machine.[3] http://esolangs.org/wiki/Brainfuck More on brainfuck.[4] http://www.iwriteiam.nl/Ha_bf_Turing.html Bf is turing-complete.[5] http://esolangs.org More esoteric languages.[6] min.dws max.dws Home-brewed minimal languages.Note, when searching the Internet that, owing to its second syllable's being ataboo word in English, "brainfuck" is often written as brainf***, brainf*ck,brainfsck, BF or even b****fuck!The language was designed to be extremely simple to implement. For example, itmay be expressed in only:- 21 lines of the minuscule functional language: max.dws/lib.bf- 18 reduction rules in term-rewrite system: eval.dws/bfckThanks to Nicolas Delcros and Jason Rivers for sowing the seed.445


Examples:bf'++++++++++[>+++++++>+++.+++++++..+++..+Hello World© The following program inputs two single-digit numbers and ouputs their sum:display add© sum of two single digit numbers.Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ output sum of two ASCII digitsÛÛ "¸" plus "¾" … "¸" Ï "¾" Î "0" where "0" = 48 ÛÛÛÛ , 0: 1st digit '0' plus ¸ ÛÛ > +++++ + [ 1:6 × loop: ÛÛ < ----- --- 0: sub 6×8: '0' plus ¸ … ¸ ÛÛ >- 1: decr loop counter ÛÛ ] 1:0 ÛÛ , 1: 2nd digit '0' plus ¾ ÛÛ + 1: incr ¾ ÛÛ .0: output ¸ plus '0' plus ¾ ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙbf add © input 3, 4; output 7.347+5 8 bf '[>+++++++++[-]++++++++[-]]'© fast-forward over non-zero cells.adr „ '[->+[-]+>+',adr,'>',dot© output sum of two input digits.© using "sum" from above.© double of input digit.© This program, transliterated from Böhm's P" language, a precursor to BF,© returns the predecessor of a number represented in 2…adic„ number system:© « 1 2 11 12 21 22 111 112 121 ...+1 1 2 bf'>[>]


See also: mac.464 bfack.527 balm.519See also: baby.427 list.54 time.515 adic.253 lisp.236See also: min.dws max.dws eval.dwsSee also: max.dws/lib.bf eval.dws/bfckÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎdicecvec„ ##.dice ?6 6© Interpret a throw of dice.An illustration of the versatility of the guard construct.Example:Sevendice?6 6ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎdrawcmat „ {marker„'*'} ##.draw cmat© Draw over '*'s.Supplied by Veli-Matti Jantunen, draw replaces adjacent markers in the charactermatrix argument with appropriate box-drawing characters. Optional left argument('*' by default) specifies the marker; all other characters are passed throughto the result character matrix.Examples:© Show arg and result, starting with blank canvas.canvas„4 4½' ' ª display¨ canvas (draw canvas)Ú…ÎÎÎÌ Ú…ÎÎÎ̇ Û ‡ ÛÛ Û Û ÛÛ Û Û ÛÛ Û Û ÛÀÎÎÎÎÙ ÀÎÎÎÎÙcanvas[4;2 3]„'*' ª display¨ canvas (draw canvas)Ú…ÎÎÎÌ Ú…ÎÎÎ̇ Û ‡ ÛÛ Û Û ÛÛ Û Û ÛÛ ** Û Û ÎÎ ÛÀÎÎÎÎÙ ÀÎÎÎÎÙcanvas[2 3;4]„'*' ª display¨ canvas (draw canvas)Ú…ÎÎÎÌ Ú…ÎÎÎ̇ Û ‡ ÛÛ *Û Û ÛÛÛ *Û Û ÛÛÛ ** Û Û ÎÎ ÛÀÎÎÎÎÙ ÀÎÎÎÎÙcanvas[4;4]„'*' ª display¨ canvas (draw canvas)Ú…ÎÎÎÌ Ú…ÎÎÎ̇ Û ‡ ÛÛ *Û Û ÛÛÛ *Û Û ÛÛÛ ***Û Û ÎÎÙÛÀÎÎÎÎÙ ÀÎÎÎÎÙ447


canvas[2;¼4]„'*' ª display¨ canvas (draw canvas)Ú…ÎÎÎÌ Ú…ÎÎÎ̇ Û ‡ ÛÛ****Û ÛÎÎÎÌÛÛ *Û Û ÛÛÛ ***Û Û ÎÎÙÛÀÎÎÎÎÙ ÀÎÎÎÎÙcanvas[¼4;2]„'*' ª display¨ canvas (draw canvas)Ú…ÎÎÎÌ Ú…ÎÎÎ̇ * Û ‡ Û ÛÛ****Û ÛÎÏÎÌÛÛ * *Û Û Û ÛÛÛ ***Û Û ÀÎÙÛÀÎÎÎÎÙ ÀÎÎÎÎÙcanvas[1;1]„'*' ª display¨ canvas (draw canvas)Ú…ÎÎÎÌ Ú…ÎÎÎ̇** Û ‡ÚÌ ÛÛ****Û ÛÀÏÎÌÛÛ * *Û Û Û ÛÛÛ ***Û Û ÀÎÙÛÀÎÎÎÎÙ ÀÎÎÎÎÙ'?'draw ' ?'[?10 50½2]© random scribbles with ? marker.? ? ÚÂÎ ÚÌ ÎÎ ÎÎÂÂÎ ? ÚÂÎ Û ÚÂÌ ÎÎÂÌ ÎÌ ÛÀÝ ÚÏÝ Û Û ? ÀÙ Û ÎÁÝ ÚÁÎÁÁÏÌ ÀÏÎ Û ÛÚÎ Û ÀÁÁÎÁÌ Û ÎÙ ÀÎ Û ÀÏÎÂÌ Û ÛÛ Û ÚÁÎ Û Û Û ? ÚÁÎ ÎÎ Û ÀÁÂÙ ÚÙ ÚÎÀÂÂÎ ÚÝ ÚÌ ÎÂÏÎÎÙ ÚÝ Û ÚÌ ÎÎÎÙ Û ÀÌ Û Û ÚÝÃÝ ÀÙ ÎÏÝ ÀÝ ÃÝ Û ÀÝ ? Û ? Û Û ÚÁÁÌÚÁÝ ? Û ÃÁÎÌ Û ÚÏÁÌ Û ÀÌ ÃÂÁÎÂÌ Û ÛÛ ÃÌ Û ÃÎÙ ÃÎÙ ? ÀÙ Û ÀÎ ÃÂÂÎ Û ÎÏÝ ÀÙ ÛÀÂÏÙ Û Û ÎÝ ? ? ÚÁÏÙ ÀÎ Û ÀÏÂÌ ? ÚÌÀÙ ÎÙ ÎÎ ÀÎ ? ? ? Û Û ? ÎÙ ? ÀÁÁÎ ÎÁÙSee also ##.scripts.pentominosSee also: box.14ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎlifebmat „ ##.life bmat© John Conway's "Game of Life".This version of John Conway's cellular automaton takes a boolean matrix argumentrepresenting a population of "creatures" and returns a boolean matrix of thesucceeding generation. Each cell in the matrix may be occupied by a creature(1) or be empty (0).The two rules of life are:[1] An empty cell that has exactly 3 neighbouring occupied cells is "born" intoin the next generation.[2] An occupied cell that has exactly 2 or 3 neighbouring occupied cells, survivesto the next generation. Otherwise, its occupant dies (of loneliness orovercrowding).ÏÎÎÎÏÎÎÎÏÎÎÎÏÛ · Û · Û · ÛÏÎÎÎÏÎÎÎÏÎÎÎÏÛ µ Û µ Û µ ÛÏÎÎÎÏÎÎÎÏÎÎÎÏÛ · Û · Û · ÛÏÎÎÎÏÎÎÎÏÎÎÎÏ448


In the above example, only the creature in the centre survives but new ones areborn above and below it. The next generation thus has three creatures in a verticalline; the generation after that reverts to the horizontal; and so on.For more complex configurations, the sequence may develop for many generationsbefore repeating. An instance of an interesting initial configuration is the R-Pentomino:ÏÎÎÎÏÎÎÎÏÎÎÎÏÛ · Û µ Û µ ÛÏÎÎÎÏÎÎÎÏÎÎÎÏÛ µ Û µ Û · ÛÏÎÎÎÏÎÎÎÏÎÎÎÏÛ · Û µ Û · ÛÏÎÎÎÏÎÎÎÏÎÎÎÏIn the coding in this workspace, the use of ´ and ² render opposite edges of thecreatures' rectangular universe, adjacent. In effect, the creatures live on thesurface of a torus (doughnut, innertube, ..). We illustrate this arrangementusing a little square diagram, which shows the orientations of the connectionsof corresponding edges:torusÚÎ…ÎÌ upper edge joined to lower,“ “ left edge joined to right.ÀÎ…ÎÙWe can visualise the square, made from a very flexible material, being distortedso that the left and right sides are joined with their “ arrows aligned to forma tube. We then stretch the tube and bend it to join its two circular ends withthe … arrows aligned, to form a torus.We can investigate edge connections (universes, manifolds) other than the torus;it is most convenient to explore these using auxiliary operators, leaving thecoding of the life function itself unchanged.For example, we might want the edges not to be joined at all; creatures crossingthe boundaries would just disappear.ÚÎÎÎÌÛ Û plane: no edge connections.ÀÎÎÎÙEasy-peasy! We just prefix a 0 row and column to the argument matrix and removea row and column from the result:plane„{© ÚÎÎÎÌ1 0‡0 1‡¸¸ 0,0®¾ © Û Û} © ÀÎÎÎÙTo see the effect, let's make an initial configuration:glider „ 3 3½0 0 1 1 0 1 0 1 1and a function to display each generation:show„{'·µ'[Œio+¾]}··µµ·µ·µµshow glider449


We can see the glider's first few generations, using the power operator …pow„:0 disp show¨(0 to 6) life pow¨ ›5 5†gliderÚÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÌÛ··µ··Û·µ···Û··µ··Û·····Û·····Û·····Û·····ÛÛµ·µ··Û··µµ·Û···µ·Û·µ·µ·Û···µ·Û··µ··Û···µ·ÛÛ·µµ··Û·µµ··Û·µµµ·Û··µµ·Û·µ·µ·Û···µµÛ····µÛÛ·····Û·····Û·····Û··µ··Û··µµ·Û··µµ·Û··µµµÛÛ·····Û·····Û·····Û·····Û·····Û·····Û·····ÛÀÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÙAlternatively, operator …traj„ applies its operand function repeatedly until acycle is detected:0 disp show¨ life traj 5 5†gliderÚÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÛ··µ··Û·µ···Û··µ··Û·····Û·····Û·····Û·····Û·····Û·····Û·····Û·····Û····µÛµ···µÛµÛµ·µ··Û··µµ·Û···µ·Û·µ·µ·Û···µ·Û··µ··Û···µ·Û·····Û·····Û·····Û·····Û·····Û·····Û·Û·µµ··Û·µµ··Û·µµµ·Û··µµ·Û·µ·µ·Û···µµÛ····µÛ··µ·µÛ····µÛ···µ·Û····µÛ·····Û·····Û·Û·····Û·····Û·····Û··µ··Û··µµ·Û··µµ·Û··µµµÛ···µµÛ··µ·µÛµ···µÛµ····Ûµ··µ·Ûµ····Û·Û·····Û·····Û·····Û·····Û·····Û·····Û·····Û···µ·Û···µµÛ···µµÛµ··µµÛµ···µÛµ··µ·ÛµÀÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎTo save typing, we can distil the above expression into a "try" operator:try„{0 disp show¨ ¸¸ traj ¾}© repeat until cycle detected.life try 5 5†glider© life on a torus.ÚÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÛ··µ··Û·µ···Û··µ··Û·····Û·····Û·····Û·····Û·····Û·····Û·····Û·····Û····µÛµ···µÛµÛµ·µ··Û··µµ·Û···µ·Û·µ·µ·Û···µ·Û··µ··Û···µ·Û·····Û·····Û·····Û·····Û·····Û·····Û·Û·µµ··Û·µµ··Û·µµµ·Û··µµ·Û·µ·µ·Û···µµÛ····µÛ··µ·µÛ····µÛ···µ·Û····µÛ·····Û·····Û·Û·····Û·····Û·····Û··µ··Û··µµ·Û··µµ·Û··µµµÛ···µµÛ··µ·µÛµ···µÛµ····Ûµ··µ·Ûµ····Û·Û·····Û·····Û·····Û·····Û·····Û·····Û·····Û···µ·Û···µµÛ···µµÛµ··µµÛµ···µÛµ··µ·ÛµÀÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎNow, spot the difference if we apply life under our plane operator. As soon asthe glider hits the edge, parts of it disappear and so it no longer flies:life plane try 5 5†glider© life on a plane.ÚÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÌÛ··µ··Û·µ···Û··µ··Û·····Û·····Û·····Û·····Û·····Û·····Û·····Û·····Û·····ÛÛµ·µ··Û··µµ·Û···µ·Û·µ·µ·Û···µ·Û··µ··Û···µ·Û·····Û·····Û·····Û·····Û·····ÛÛ·µµ··Û·µµ··Û·µµµ·Û··µµ·Û·µ·µ·Û···µµÛ····µÛ··µ·µÛ····µÛ···µ·Û·····Û·····ÛÛ·····Û·····Û·····Û··µ··Û··µµ·Û··µµ·Û··µµµÛ···µµÛ··µ·µÛ····µÛ····µÛ···µµÛÛ·····Û·····Û·····Û·····Û·····Û·····Û·····Û···µ·Û···µµÛ···µµÛ···µµÛ···µµÛÀÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÙNote that the final µµ is a stable configuration, as each cell has exactly 3neighbours. µµOther possibilities-------------------We could connect just two of the edges to see life on a cylinder:cylinder„{© ÚÎÎÎÌ1 0‡¸¸ 0®¾ © “ “} © ÀÎÎÎÙ450


life cylinder try 5 5†glider © life on a cylinder.ÚÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÛ··µ··Û·µ···Û··µ··Û·····Û·····Û·····Û·····Û·····Û·····Û·····Û·····Û·····Û·····Û·Ûµ·µ··Û··µµ·Û···µ·Û·µ·µ·Û···µ·Û··µ··Û···µ·Û·····Û·····Û·····Û·····Û·····Û·····Û·Û·µµ··Û·µµ··Û·µµµ·Û··µµ·Û·µ·µ·Û···µµÛ····µÛ··µ·µÛ····µÛ···µ·Û····µÛ·····Û·····Û·Û·····Û·····Û·····Û··µ··Û··µµ·Û··µµ·Û··µµµÛ···µµÛ··µ·µÛµ···µÛµ····Ûµ··µ·Ûµ····ÛµÛ·····Û·····Û·····Û·····Û·····Û·····Û·····Û···µ·Û···µµÛ···µµÛµ··µµÛµ···µÛµ···µÛµÀÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎFor completeness, we should have a null operator for life on a torus:torus„{© ÚÎ…Î̸¸ ¾ © “ “} © ÀÎ…ÎÙlife torus try 5 5†glider© life on a torus.ÚÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÛ··µ··Û·µ···Û··µ··Û·····Û·····Û·····Û·····Û·····Û·····Û·····Û·····Û····µÛµ···µÛµÛµ·µ··Û··µµ·Û···µ·Û·µ·µ·Û···µ·Û··µ··Û···µ·Û·····Û·····Û·····Û·····Û·····Û·····Û·Û·µµ··Û·µµ··Û·µµµ·Û··µµ·Û·µ·µ·Û···µµÛ····µÛ··µ·µÛ····µÛ···µ·Û····µÛ·····Û·····Û·Û·····Û·····Û·····Û··µ··Û··µµ·Û··µµ·Û··µµµÛ···µµÛ··µ·µÛµ···µÛµ····Ûµ··µ·Ûµ····Û·Û·····Û·····Û·····Û·····Û·····Û·····Û·····Û···µ·Û···µµÛ···µµÛµ··µµÛµ···µÛµ··µ·ÛµÀÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎFinally, we could connect opposite edges with a twist to give two further universes:möbius and klein. To produce the effect of a twist prior to connectingopposite edges, we append the reverse of each of the outside columns to theiropposing side. After applying the operand function, we must remember to removethese extra columns.© append reversed columns.twist„{ © ÚÎÎÎÌ Ú ÚÎÎÎÌ Ì¯1²¾,²´2†[1+Œio]¯1²¾ © “ † … ‡,“ †,”} © ÀÎÎÎÙ À ÀÎÎÎÙ ÙThen:plane„{© ÚÎÎÎÌ1 0‡0 1‡¸¸ 0,0®¾ © Û Û} © ÀÎÎÎÙcylinder„{© ÚÎÎÎÌ1 0‡¸¸ 0®¾ © “ “} © ÀÎÎÎÙtorus„{© ÚÎ…Î̸¸ ¾ © “ “} © ÀÎ…ÎÙmöbius„{© ÚÎÎÎÌ möbius strip1 0‡0 2‡¯1²¸¸ 0®twist ¾ © “ ”} © ÀÎÎÎÙklein„{Œml„0© ÚÎ…ÎÌ klein bottle0 2‡¯1²¸¸ twist ¾ © “ ”} © ÀÎ…ÎÙlife möbius try 5 5†glider© life on a möbius strip.ÚÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÛ··µ··Û·µ···Û··µ··Û·····Û·····Û·····Û·····Û·····Û·····Û·····Ûµ····Ûµ····Ûµ····ÛµÛµ·µ··Û··µµ·Û···µ·Û·µ·µ·Û···µ·Û··µ··Û···µ·Û·····Û·····Ûµ····Ûµ····Ûµ····Ûµ····ÛµÛ·µµ··Û·µµ··Û·µµµ·Û··µµ·Û·µ·µ·Û···µµÛ····µÛ··µ·µÛ····µÛ···µ·Û····µÛ·····Û·····Û·Û·····Û·····Û·····Û··µ··Û··µµ·Û··µµ·Û··µµµÛ···µµÛ··µ·µÛ····µÛ·····Û···µ·Û·····Û·Û·····Û·····Û·····Û·····Û·····Û·····Û·····Û···µ·Û···µµÛ···µµÛ···µµÛ····µÛ····µÛ·ÀÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎ451


life klein try 5 5†glider © life on a klein bottle.ÚÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÂÎÛ··µ··Û·µ···Û··µ··Û·····Û·····Û·····Û·····Û·····Û·····Û·····Ûµ····Ûµ···µÛµ···µÛµÛµ·µ··Û··µµ·Û···µ·Û·µ·µ·Û···µ·Û··µ··Û···µ·Û·····Û·····Ûµ····Ûµ····Ûµ····Ûµ····Û·Û·µµ··Û·µµ··Û·µµµ·Û··µµ·Û·µ·µ·Û···µµÛ····µÛ··µ·µÛ····µÛ···µ·Û····µÛ·····Û·····Û·Û·····Û·····Û·····Û··µ··Û··µµ·Û··µµ·Û··µµµÛ···µµÛ··µ·µÛ····µÛ·····Û···µ·Û·····Û·Û·····Û·····Û·····Û·····Û·····Û·····Û·····Û···µ·Û···µµÛ···µµÛ···µµÛ····µÛµ··µ·ÛµÀÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÁÎLibrary-------If you are viewing this page from an <strong>APL</strong> session, you can generate a booleanmatrix argument for life from any of the following patterns using these steps:1. While pressing the _right_ mouse button, select the area within a box.2. From this edit window menu, select Edit->Copy.3. Open a new edit window to receive the character matrix: )ed -pattern4. Select Edit->Paste in the new window, then close it.5. Test using, for example: {Œ„'Î'®'·µ'[Œio+¾] ª ’ life ¾} 20 50†pattern='µ'R-Pentomino Glider Glider Gun (Gosper)ÚÎÎÎÌ ÚÎÎÎÌ ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ·µµÛ Û··µÛ Û························µ···········ÛÛµµ·Û Ûµ·µÛ Û······················µ·µ···········ÛÛ·µ·Û Û·µµÛ Û············µµ······µµ············µµÛÀÎÎÎÙ ÀÎÎÎÙ Û···········µ···µ····µµ············µµÛÛµµ········µ·····µ···µµ··············ÛBistable statesÛµµ········µ···µ·µµ····µ·µ···········ÛÚÎÎÎÌ ÚÎÎÎÎÌÛ··········µ·····µ·······µ···········ÛÛµµµÛ Û·µµµÛÛ···········µ···µ····················ÛÀÎÎÎÙ Ûµµµ·ÛÛ············µµ······················ÛÀÎÎÎÎÙÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙStable statesThe glider gun generates a stream ofÚÎÎÌ ÚÎÎÎÎÌgliders.ÛµµÛ Û·µµ·ÛÛµµÛ Ûµ··µÛÀÎÎÙ Û·µµ·ÛÀÎÎÎÎÙTechnical note--------------The expression for the next generation in the life game:†1 ¾Ÿ.^3 4=+/,¯1 0 1°.´¯1 0 1°.²›¾ © Expression for next generation.is developed in real time in YouTube video:http://www.youtube.com/watch?gl=GB&hl=en-GB&v=a9xAKttWgP4&fmt=18(Actually, the expression on YouTube differs very slightly in that the rightmostouter product, above, is replaced with an , but is otherwise identical).Shorter Expression------------------We can transform the expression into a marginally shorter, if somewhat more complex,one by observing that:ergo:¸ ´ ¾ „… ³ ¸ ²³ ¾¸ ² ¸ ´ ¾ „… ¸ ² ³ ¸ ²³ ¾ „… ¸ ²°³ÿ2 ¾452


esulting in:†1 ¾Ÿ.^3 4=+/,¯1 0 1°.(²°³)ÿ2›¾ © Expression for next generation.Examples:0 disp{'·µ'[Œio+¾]}¨life traj 5 8†3 3½0 0 1 1 0 1 0 1 1 © Glider.ÚÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÛ··µ·····Û·µ······Û··µ·····Û········Û········Û········Û········Û········Û·······Ûµ·µ·····Û··µµ····Û···µ····Û·µ·µ····Û···µ····Û··µ·····Û···µ····Û········Û·······Û·µµ·····Û·µµ·····Û·µµµ····Û··µµ····Û·µ·µ····Û···µµ···Û····µ···Û··µ·µ···Û····µ··Û········Û········Û········Û··µ·····Û··µµ····Û··µµ····Û··µµµ···Û···µµ···Û··µ·µ··Û········Û········Û········Û········Û········Û········Û········Û···µ····Û···µµ··ÀÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎΩ Conway's automaton is best viewed as an animation.© Here is a (pretty rough) gui front end:gui„{Œio„0© Life animation.show„{'·µ'[¾]}© formatting function.f„Œns''© localise class 9 name._„'f'Œwc'form' ''(2 48)('OnTop' 1) © make a form._„'f.t'Œwc'Text'(show ¾)(0 0)© make a text box.f.t.(FontObj BCol)„'<strong>Dyalog</strong> Std'(3/255) © font and white background.¸„500 © default 500ms delay.¸ ¸¸{ ©_„Œdl ¸÷1000© delay ¸ ms.next„¸¸ ¾© next generation.f.t.Text„show next© display new generation.¸ ’ next© ... and so on.}¾}© Fix this function and the glider_gun as described in "Library" above© and then try:100 life gui 30 80†glider_gun='µ' © glider gun on torus.© But beware: a glider gun in a torus is doomed because it inevitably shoots© itself in the back. Artillery in a finite manifold is a dangerous business.©© Aficionados of the 1979 arcade game "Asteroids", which took place on a© torus, will recall that the manufacturers thoughtfully gave their canon© a range just short of the screen's circumferences.© See: http://en.wikipedia.org/wiki/Asteroids_(video_game)See also: traj.220See also: http://www.youtube.com/watch?gl=GB&hl=en-GB&v=a9xAKttWgP4&fmt=18ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎkeyboards<strong>Dyalog</strong> <strong>APL</strong> keyboard layouts¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯In addition to regular (national language) characters, <strong>APL</strong> keyboards need to beable to produce all of the special <strong>APL</strong> characters: ¸ ¾ ¼ ½ ³ º ... They achievethis by having an extra "<strong>APL</strong>" shift state. This means that, in combination withthe normal Shift, there are four permutations and so each keycap can host up tofour characters:453


<strong>APL</strong>/Shift code:ÚÎÎÎÎÎÂÎÎÎÎÎÌÛ Û<strong>APL</strong>+ Û On Windows systems, the <strong>APL</strong> key is Ctrl so, for example,ÛShiftÛShiftÛ to key "½", we press Ctrl+r and for "“", Ctrl+Shift+4.ÃÎÎÎÎÎÏÎÎÎÎÎÝÛ Û<strong>APL</strong> Û On platforms other than Windows the <strong>APL</strong> key may be else-Û Û Û where; please consult the product release notes.ÀÎÎÎÎÎÁÎÎÎÎÎÙ<strong>Dyalog</strong> <strong>APL</strong>/US keyboard¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ÚÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÎÎÎÎÎÌÛ~ Û! • Û@ • Û# ” Û$ “ Û% ² Û^ ³ Û& ´ Û* µ Û( ‹ Û) Š Û_ ! Û+ Ž ÛBackspaceÛÛ• ª Û1 ¨ Û2 ¯ Û3 < Û4 ˆ Û5 = Û6 ‰ Û7 > Û8 ¬ Û9 Ÿ Û0 ^ Û- × Û= ÷ ÛÛÃÎÎÎÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÎÎÎÎÎÝÛTab ÛQ ÛW ÛE º ÛR ÛT þ ÛY ÛU ÛI ¼_ÛO ±¨ÛP ÿ Û{ • Û} « Û| • ÛÛ Ûq ? Ûw ¾ Ûe ¹ Ûr ½ Ût ~ Ûy † Ûu ‡ Ûi ¼ Ûo ± Ûp * Û[ „ Û] … Û\ € ÛÃÎÎÎÎÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÎÎÎÎÎÎÝÛCaps ÛA ÛS ÛD ÛF ÛG ÛH ÛJ °¨ÛK Œ=ÛL ¦ Û: ­ Û" » ÛEnter ÛÛLock Ûa ¸ Ûs — Ûd ˜ Ûf _ Ûg ’ Ûh ‘ Ûj ° Ûk ' Ûl Œ Û; – Û' • Û ÛÃÎÎÎÎÎÎÎÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÎÎÎÎÎÎÎÎÝÛShift ÛZ ÛX ÛC ÛV ÛB ÛN ÛM Û< ® Û> • Û? Œ:ÛShift ÛÛ Ûz › Ûx œ Ûc • Ûv ž Ûb ƒ Ûn ‚ Ûm | Û, © Û. Û/ š Û ÛÃÎÎÎÎÎÎÎÂÎÎÎÁÎÂÎÎÁÎÎÎÂÁÎÎÎÎÁÎÎÎÎÁÎÎÎÎÁÎÎÎÎÁÎÎÎÎÁÂÎÎÎÁÎÎÂÎÁÎÎÎÎÏÎÎÎÎÎÂÎÎÎÎÎÎÝÛCtrl ÛWin ÛAlt Û ÛAlt GrÛWin ÛMenu ÛCtrl ÛÛ Û Û Û Û Û Û Û ÛÀÎÎÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÁÎÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÎÙ<strong>Dyalog</strong> <strong>APL</strong>/UK keyboard¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ÚÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÎÎÎÎÎÌÛÎÌ Û! • Û" • Û£ ” Û$ “ Û% ² Û^ ³ Û& ´ Û* µ Û( ‹ Û) Š Û_ ! Û+ Ž ÛBackspaceÛÛ• ª Û1 ¨ Û2 ¯ Û3 < Û4 ˆ Û5 = Û6 ‰ Û7 > Û8 ¬ Û9 Ÿ Û0 ^ Û- × Û= ÷ ÛÛÃÎÎÎÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÎÎÎÎÎÝÛTab ÛQ ÛW ÛE º ÛR ÛT þ ÛY ÛU ÛI ¼_ÛO ±¨ÛP ÿ Û{ • Û} « ÛEnter ÛÛ Ûq ? Ûw ¾ Ûe ¹ Ûr ½ Ût ~ Ûy † Ûu ‡ Ûi ¼ Ûo ± Ûp * Û[ „ Û] … Û ÛÃÎÎÎÎÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÌ ÛÛCaps ÛA ÛS ÛD ÛF ÛG ÛH ÛJ °¨ÛK Œ=ÛL ¦ Û: ­ Û@ » Û~ Û ÛÛLock Ûa ¸ Ûs — Ûd ˜ Ûf _ Ûg ’ Ûh ‘ Ûj ° Ûk ' Ûl Œ Û; – Û' • Û# Û ÛÃÎÎÎÎÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÎÎÁÎÎÎÎÎÝÛShift Û| • ÛZ ÛX ÛC ÛV ÛB ÛN ÛM Û< ® Û> • Û? Œ:ÛShift ÛÛ Û\ € Ûz › Ûx œ Ûc • Ûv ž Ûb ƒ Ûn ‚ Ûm | Û, © Û. Û/ š Û ÛÃÎÎÎÎÎÎÁÂÎÎÎÁÎÂÎÎÁÎÎÎÂÁÎÎÎÎÁÎÎÎÎÁÎÎÎÎÁÎÎÎÎÁÎÎÎÎÁÂÎÎÎÁÎÎÂÎÁÎÎÎÎÏÎÎÎÎÎÂÎÎÎÎÎÎÝÛCtrl ÛWin ÛAlt Û ÛAlt GrÛWin ÛMenu ÛCtrl ÛÛ Û Û Û Û Û Û Û ÛÀÎÎÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÁÎÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÎÙ454


<strong>Dyalog</strong> <strong>APL</strong>/DK Danish keyboard¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ÚÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÎÎÎÎÎÌÛ§ Û! • Û" • Û# ” Û°* “Û% ² Û& ³ Û/ ´ Û( µ Û) ‹ Û= Š Û? ! Û• Ž ÛBackspaceÛÛ1/2ªÛ1 ¨ Û2 ¯ Û3 < Û4 ˆ Û5 = Û6 ‰ Û7 > Û8 ¬ Û9 Ÿ Û0 ^ Û+ × Û//÷ ÛÛÃÎÎÎÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÎÎÎÎÎÝÛTab ÛQ ÛW ÛE º ÛR ÛT þ ÛY ÛU ÛI ¼_ÛO ±¨ÛP ÿ ÛÅ • Û• « ÛEnter ÛÛ Ûq ? Ûw ¾ Ûe ¹ Ûr ½ Ût ~ Ûy † Ûu ‡ Ûi ¼ Ûo ± Ûp * Ûå „ Û¨ … Û ÛÃÎÎÎÎÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÌ ÛÛCaps ÛA ÛS ÛD ÛF ÛG ÛH ÛJ °¨ÛK Œ=ÛL ¦ ÛÆ ­ ÛØ » Û* Û ÛÛLock Ûa ¸ Ûs — Ûd ˜ Ûf _ Ûg ’ Ûh ‘ Ûj ° Ûk ' Ûl Œ Ûæ – Ûø • Û' Û ÛÃÎÎÎÎÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÎÎÁÎÎÎÎÎÝÛShift Û> • ÛZ ÛX ÛC ÛV ÛB ÛN ÛM Û; ® Û: • Û_ Œ:ÛShift ÛÛ Û< € Ûz › Ûx œ Ûc • Ûv ž Ûb ƒ Ûn ‚ Ûm | Û, © Û. Û- š Û ÛÃÎÎÎÎÎÎÁÂÎÎÎÁÎÂÎÎÁÎÎÎÂÁÎÎÎÎÁÎÎÎÎÁÎÎÎÎÁÎÎÎÎÁÎÎÎÎÁÂÎÎÎÁÎÎÂÎÁÎÎÎÎÏÎÎÎÎÎÂÎÎÎÎÎÎÝÛCtrl ÛWin ÛAlt Û ÛAlt GrÛWin ÛMenu ÛCtrl ÛÛ Û Û Û Û Û Û Û ÛÀÎÎÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÁÎÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÎÙAdditional characters on the front of keycaps are accessed using Alt Gr:ÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÛ" • ÛÛ# ” ÛÛ€ “ ÛÛ% ² ÛÛ/ ´ ÛÛ( µ ÛÛ) ‹ ÛÛ= Š ÛÛ• Ž ÛÛE º ÛÛ> • ÛÛ• « ÛÛM « ÛÛ2 ¯ ÛÛ3 < ÛÛ4 ˆ ÛÛ5 = ÛÛ7 > ÛÛ8 ¬ ÛÛ9 Ÿ ÛÛ0 ^ ÛÛ' ÷ ÛÛe ¹ ÛÛ< € ÛÛ¨ … ÛÛm | ÛÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÛ@ ÛÛ£ ÛÛ$ ÛÛ• ÛÛ{ ÛÛ[ ÛÛ] ÛÛ} ÛÛ| ÛÛ• ÛÛ\ ÛÛ~ ÛÛmu ÛÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙ<strong>Dyalog</strong> <strong>APL</strong>/DE German keyboard (AWS)¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯This version is based on the layout of the <strong>Dyalog</strong> hardware keyboardsÚÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÎÎÎÎÎÌÛ°° Û! • Û" • Û§ ” Û$ “ Û% ² Û& ³ Û/ ´ Û( µ Û) ‹ Û= Š Û? ! Û• Ž ÛBackspaceÛÛ• ªÛ1 ¨ Û2 ¯ Û3 < Û4 ˆ Û5 = Û6 ‰ Û7 > Û8 ¬ Û9 Ÿ Û0 ^ Ûß × Û//÷ ÛÛÃÎÎÎÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÎÎÎÎÎÝÛTab ÛQ ÛW ÛE º ÛR ÛT þ ÛZ ÛU ÛI ¼_ÛO ±¨ÛP ÿ ÛÜ • Û* « ÛEnter ÛÛ Ûq ? Ûw ¾ Ûe ¹ Ûr ½ Ût ~ Ûz † Ûu ‡ Ûi ¼ Ûo ± Ûp * Ûü „ Û+ … Û ÛÃÎÎÎÎÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÌ ÛÛCaps ÛA ÛS ÛD ÛF ÛG ÛH ÛJ °¨ÛK Œ=ÛL ¦ ÛÖ ­ ÛÄ » Û' Û ÛÛLock Ûa ¸ Ûs — Ûd ˜ Ûf _ Ûg ’ Ûh ‘ Ûj ° Ûk ' Ûl Œ Ûö – Ûä • Û# # Û ÛÃÎÎÎÎÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÎÎÁÎÎÎÎÎÝÛShift Û> • ÛY ÛX ÛC ÛV ÛB ÛN ÛM Û; ® Û: • Û_ Œ:ÛShift ÛÛ Û< € Ûy › Ûx œ Ûc • Ûv ž Ûb ƒ Ûn ‚ Ûm | Û, © Û. Û- š Û ÛÃÎÎÎÎÎÎÁÂÎÎÎÁÎÂÎÎÁÎÎÎÂÁÎÎÎÎÁÎÎÎÎÁÎÎÎÎÁÎÎÎÎÁÎÎÎÎÁÂÎÎÎÁÎÎÂÎÁÎÎÎÎÏÎÎÎÎÎÂÎÎÎÎÎÎÝÛCtrl ÛWin ÛAlt Û ÛAlt GrÛWin ÛMenu ÛCtrl ÛÛ Û Û Û Û Û Û Û ÛÀÎÎÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÁÎÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÎÙAdditional characters on the front of keycaps are accessed using Alt Gr:ÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÛ" • ÛÛ§ ” ÛÛ/ ´ ÛÛ( µ ÛÛ) ‹ ÛÛ= Š ÛÛ? ! ÛÛQ ÛÛE º ÛÛ* « ÛÛ> • ÛÛM ÛÛ2 ¯ ÛÛ3 < ÛÛ7 > ÛÛ8 ¬ ÛÛ9 Ÿ ÛÛ0 ^ ÛÛß × ÛÛq ? ÛÛe ¹ ÛÛ+ … ÛÛ< € ÛÛm | ÛÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÛ2_ ÛÛ3_ ÛÛ{ ÛÛ[ ÛÛ] ÛÛ} ÛÛ\ ÛÛ@ ÛÛ• ÛÛ~ ÛÛ| ÛÛmu ÛÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙ455


<strong>Dyalog</strong> <strong>APL</strong>/ES Spanish keyboard (AWS)¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ÚÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÎÎÎÎÎÌÛ†a Û! • Û" • Û· ” Û$ “ Û% ² Û& ³ Û/ ´ Û( µ Û) ‹ Û= Š Û? ! Û¿ Ž ÛBackspaceÛÛ†o ªÛ1 ¨ Û2 ¯ Û3 < Û4 ˆ Û5 = Û6 ‰ Û7 > Û8 ¬ Û9 Ÿ Û0 ^ Û' × Û¡ ÷ ÛÛÃÎÎÎÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÎÎÎÎÎÝÛTab ÛQ ÛW ÛE º ÛR ÛT þ ÛY ÛU ÛI ¼_ÛO ±¨ÛP ÿ Û• • Û* « ÛEnter ÛÛ Ûq ? Ûw ¾ Ûe ¹ Ûr ½ Ût ~ Ûy † Ûu ‡ Ûi ¼ Ûo ± Ûp * Û• „ Û+ … Û ÛÃÎÎÎÎÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÌ ÛÛCaps ÛA ÛS ÛD ÛF ÛG ÛH ÛJ °¨ÛK Œ=ÛL ¦ ÛÑ ­ Û¨ » ÛÇ Û ÛÛLock Ûa ¸ Ûs — Ûd ˜ Ûf _ Ûg ’ Ûh ‘ Ûj ° Ûk ' Ûl Œ Ûñ – Û//• Ûç # Û ÛÃÎÎÎÎÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÎÎÁÎÎÎÎÎÝÛShift Û> • ÛZ ÛX ÛC ÛV ÛB ÛN ÛM Û; ® Û: • Û_ Œ:ÛShift ÛÛ Û< € Ûz › Ûx œ Ûc • Ûv ž Ûb ƒ Ûn ‚ Ûm | Û, © Û. Û- š Û ÛÃÎÎÎÎÎÎÁÂÎÎÎÁÎÂÎÎÁÎÎÎÂÁÎÎÎÎÁÎÎÎÎÁÎÎÎÎÁÎÎÎÎÁÎÎÎÎÁÂÎÎÎÁÎÎÂÎÁÎÎÎÎÏÎÎÎÎÎÂÎÎÎÎÎÎÝÛCtrl ÛWin ÛAlt Û ÛAlt GrÛWin ÛMenu ÛCtrl ÛÛ Û Û Û Û Û Û Û ÛÀÎÎÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÁÎÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÎÙAdditional characters on the front of keycaps are accessed using Alt Gr:ÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÛ†a ÛÛ! • ÛÛ" • ÛÛ· ” ÛÛ$ “ ÛÛ& ³ ÛÛ• • ÛÛ* « ÛÛ¨ » ÛÛÇ ÛÛ†o ªÛÛ1 ¨ ÛÛ2 ¯ ÛÛ3 < ÛÛ4 ˆ ÛÛ6 ‰ ÛÛ• „ ÛÛ+ … ÛÛ//• ÛÛç # ÛÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÛ\ ÛÛ| ÛÛ@ ÛÛ# ÛÛ~ ÛÛÎÌ ÛÛ[ ÛÛ] ÛÛ{ ÛÛ} ÛÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙThe keyboard layouts above represent a standard in the sense that:1. Any physical "hardware" keyboards supplied by <strong>Dyalog</strong> Ltd would conform tothis style of layout. In particular, the <strong>APL</strong> symbols are on the same physicalkeys in each layout. See …kbolay„2. Over several release cycles, these layouts will become the installation"factory settings" default, although other alternatives, such as those thatfollow, will continue to be available as a configuration option.<strong>Dyalog</strong> <strong>APL</strong>/BE Belgian keyboard¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ÚÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÎÎÎÎÎÌÛ3_ Û1 • Û2 • Û3 ” Û4 “ Û5 ² Û6 ³ Û7 ´ Û8 µ Û9 ‹ Û0 Š Û° « Û_ Ž ÛBackspaceÛÛ2_ª Û& ¨ Ûé ¯ Û" < Û' ˆ Û( = Û§ ‰ Ûè > Û! ¬ Ûç Ÿ Ûà ^ Û) ÷ Û- × ÛÛÃÎÎÎÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÎÎÎÎÎÝÛTab ÛA ÛZ ÛE º ÛR ÛT þ ÛY ÛU ÛI ¼_ÛO ±¨ÛP ÿ Û¨ • Û* • ÛEnter ÛÛ Ûa ¸ Ûz ¾ Ûe ¹ Ûr ½ Ût ~ Ûy † Ûu ‡ Ûi ¼ Ûo ± Ûp * Û^ „ Û$ … Û ÛÃÎÎÎÎÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÌ ÛÛCaps ÛQ ÛS ÛD ÛF ÛG ÛH ÛJ °¨ÛK Œ=ÛL ¦ ÛM Û% – Û£ • Û ÛÛLock Ûq ? Ûs — Ûd ˜ Ûf _ Ûg ’ Ûh ‘ Ûj ° Ûk ' Ûl Œ Ûm | Ûù [ Ûmu ]Û ÛÃÎÎÎÎÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÎÎÁÎÎÎÎÎÝÛShift Û> • ÛW ÛX ÛC ÛV ÛB ÛN Û? ® Û. © Û/ š Û+ Œ:ÛShift ÛÛ Û< € Ûw › Ûx œ Ûc • Ûv ž Ûb ƒ Ûn ‚ Û, ­ Û; » Û: Û= Û ÛÃÎÎÎÎÎÎÁÂÎÎÎÁÎÂÎÎÁÎÎÎÂÁÎÎÎÎÁÎÎÎÎÁÎÎÎÎÁÎÎÎÎÁÎÎÎÎÁÂÎÎÎÁÎÎÂÎÁÎÎÎÎÏÎÎÎÎÎÂÎÎÎÎÎÎÝÛCtrl ÛWin ÛAlt Û ÛAlt GrÛWin ÛMenu ÛCtrl ÛÛ Û Û Û Û Û Û Û ÛÀÎÎÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÁÎÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÎÙAdditional characters on the front of keycaps are accessed using Alt Gr:ÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÛ1 • ÛÛ2 • ÛÛ3 ” ÛÛ6 ³ ÛÛ9 ‹ ÛÛ0 Š ÛÛE º ÛÛ¨ • ÛÛ* • ÛÛ> • ÛÛ% – ÛÛ£ • ÛÛ+ Œ:ÛÛ& ¨ ÛÛé ¯ ÛÛ" < ÛÛ§ ‰ ÛÛç Ÿ ÛÛà ^ ÛÛe ¹ ÛÛ^ „ ÛÛ$ … ÛÛ< € ÛÛù [ ÛÛmu ]ÛÛ= ÛÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÛ || ÛÛ @ ÛÛ # ÛÛ ^ ÛÛ { ÛÛ } ÛÛ E= ÛÛ [ ÛÛ ] ÛÛ \ ÛÛacutÛÛgravÛÛtildÛÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙ456


<strong>Dyalog</strong> <strong>APL</strong>/FR French keyboard (BL)¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ÚÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÎÎÎÎÎÌÛ Û1 • Û2 • Û3 ” Û4 “ Û5 ² Û6 ³ Û7 ´ Û8 µ Û9 ‹ Û0 Š Û° « Û+ Ž ÛBackspaceÛÛ2_ª Û& ¨ Ûé ¯ Û" < Û' ˆ Û( = Û- ‰ Ûè > Û_ ¬ Ûç Ÿ Ûà ^ Û) ÷ Û= × ÛÛÃÎÎÎÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÎÎÎÎÎÝÛTab ÛA ÛZ ÛE º ÛR ÛT þ ÛY ÛU ÛI ¼_ÛO ±¨ÛP ÿ Û¨ • Û£ • ÛEnter ÛÛ Ûa ¸ Ûz ¾ Ûe ¹ Ûr ½ Ût ~ Ûy † Ûu ‡ Ûi ¼ Ûo ± Ûp * Û^ „ Û$ … Û ÛÃÎÎÎÎÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÌ ÛÛCaps ÛQ ÛS ÛD ÛF ÛG ÛH ÛJ °¨ÛK Œ=ÛL ¦ ÛM Û% – Ûmu •Û ÛÛLock Ûq ? Ûs — Ûd ˜ Ûf _ Ûg ’ Ûh ‘ Ûj ° Ûk ' Ûl Œ Ûm | Ûù [ Û* ] Û ÛÃÎÎÎÎÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÎÎÁÎÎÎÎÎÝÛShift Û> • ÛW ÛX ÛC ÛV ÛB ÛN Û? ® Û. © Û/ š Û§ Œ:ÛShift ÛÛ Û< € Ûw › Ûx œ Ûc • Ûv ž Ûb ƒ Ûn ‚ Û, ­ Û; » Û: Û! Û ÛÃÎÎÎÎÎÎÁÂÎÎÎÁÎÂÎÎÁÎÎÎÂÁÎÎÎÎÁÎÎÎÎÁÎÎÎÎÁÎÎÎÎÁÎÎÎÎÁÂÎÎÎÁÎÎÂÎÁÎÎÎÎÏÎÎÎÎÎÂÎÎÎÎÎÎÝÛCtrl ÛWin ÛAlt Û ÛAlt GrÛWin ÛMenu ÛCtrl ÛÛ Û Û Û Û Û Û Û ÛÀÎÎÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÁÎÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÎÙAdditional characters on the front of keycaps are accessed using Alt Gr:ÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÛ2 • ÛÛ3 ” ÛÛ4 “ ÛÛ5 ² ÛÛ6 ³ ÛÛ7 ´ ÛÛ8 µ ÛÛ9 ‹ ÛÛ0 Š ÛÛ° « ÛÛ+ Ž ÛÛE º ÛÛ£ • ÛÛé ¯ ÛÛ" < ÛÛ' ˆ ÛÛ( = ÛÛ- ‰ ÛÛè > ÛÛ_ ¬ ÛÛç Ÿ ÛÛà ^ ÛÛ) ÷ ÛÛ= × ÛÛe ¹ ÛÛ$ … ÛÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÛ ~ ÛÛ # ÛÛ { ÛÛ [ ÛÛ || ÛÛ '' ÛÛ \ ÛÛ • ÛÛ @ ÛÛ ] ÛÛ } ÛÛ E= ÛÛ °× ÛÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙ<strong>Dyalog</strong> <strong>APL</strong>/DE German keyboard (PMH)¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ÚÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÎÎÎÎÎÌ ÚÎÎÛ° « Û! • Û" • Û§ ” Û$ “ Û% ² Û& ³ Û/ ´ Û( µ Û) ‹ Û= Š Û? ! Û• Ž ÛBackspaceÛ ÛEiÛ• ª Û1 ¨ Û2 ¯ Û3 < Û4 ˆ Û5 = Û6 ‰ Û7 > Û8 ¬ Û9 Ÿ Û0 ^ Ûß × Û//÷ ÛÛ ÛÃÎÎÎÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÎÎÎÎÎÝ ÃÎÎÛTab ÛQ ÛW ÛE º ÛR ÛT þ ÛZ ÛU ÛI ¼_ÛO ±¨ÛP ÿ ÛÜ ­ Û* » ÛEnter Û ÛEnÛ Ûq ? Ûw ¾ Ûe ¹ Ûr ½ Ût ~ Ûz † Ûu ‡ Ûi ¼ Ûo ± Ûp * Ûü „ Û+ … Û Û ÛÃÎÎÎÎÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÌ Û ÀÎÎÛCaps ÛA ÛS ÛD ÛF ÛG • ÛH • ÛJ °¨ÛK • ÛL Œ:ÛÖ [ ÛÄ ] Û' Û ÛÛLock Ûa ¸ Ûs — Ûd ˜ Ûf _ Ûg ’ Ûh ‘ Ûj ° Ûk ' Ûl Œ Ûö ( Ûä ) Û# ¦ Û ÛÃÎÎÎÎÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÎÎÁÎÎÎÎÎÝÛShift Û> • ÛY ÛX ÛC ÛV ÛB – ÛN • ÛM Û; ® Û: Û_ š ÛShift ÛÛ Û< € Ûy › Ûx œ Ûc • Ûv ž Ûb ƒ Ûn ‚ Ûm | Û, © Û. \ Û- / Û ÛÃÎÎÎÎÎÎÁÂÎÎÎÁÎÂÎÎÁÎÎÎÂÁÎÎÎÎÁÎÎÎÎÁÎÎÎÎÁÎÎÎÎÁÎÎÎÎÁÂÎÎÎÁÎÎÂÎÁÎÎÎÎÏÎÎÎÎÎÂÎÎÎÎÎÎÝ ÚÎÎÛStrg ÛWin ÛAlt Û ÛAlt GrÛWin ÛMenü ÛStrg Û Û „Û Û Û Û Û Û Û Û Û ÛÀÎÎÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÁÎÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÎÙ ÀÎÎAdditional characters on the front of keycaps are accessed using Alt Gr:ÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÛ" • ÛÛ§ ” ÛÛ/ ´ ÛÛ( µ ÛÛ) ‹ ÛÛ= Š ÛÛ? ! ÛÛQ ÛÛE º ÛÛ* » ÛÛF ÛÛ> • ÛÛL Œ:ÛÛNÛ2 ¯ ÛÛ3 < ÛÛ7 > ÛÛ8 ¬ ÛÛ9 Ÿ ÛÛ0 ^ ÛÛß × ÛÛq ? ÛÛe ¹ ÛÛ+ … ÛÛf _ ÛÛ< € ÛÛl Œ ÛÛnÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÛ2_ ÛÛ3_ ÛÛ{ ÛÛ[ ÛÛ] ÛÛ} ÛÛ\ ÛÛ@ ÛÛ• ÛÛ~ ÛÛfmt.ÛÛ| ÛÛloc.ÛÛnÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎ457


<strong>Dyalog</strong> <strong>APL</strong>/FI Finnish keyboard (VMJ)¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ÚÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÎÎÎÎÎÌÛ« ® Û! ­ Û" • Û# ” Û€ “ Û% ² Û& ³ Û/ ´ Û( µ Û) ‹ Û= Š Û? ! Û• Ž ÛBackspaceÛÛ§ ª Û1 ¨ Û2 ¯ Û3 < Û4 ˆ Û5 = Û6 ‰ Û7 > Û8 ¬ Û9 Ÿ Û0 ^ Û+ × Û' ÷ Û ÛÃÎÎÎÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÎÎÎÎÎÝÛTab ÛQ ÛW ÛE º ÛR ÛT þ ÛY ÛU ÛI ÛO ÛP ÿ ÛÅ • Û^ « ÛEnter ÛÛ Ûq ? Ûw ¾ Ûe ¹ Ûr ½ Ût ~ Ûy † Ûu ‡ Ûi ¼ Ûo ± Ûp * Ûå „ Û¨ … Û ÛÃÎÎÎÎÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÌ ÛÛCaps ÛA ÛS ÛD ÛF ÛG ÛH ÛJ ÛK Œ=ÛL ¦ ÛÖ [ ÛÄ ] Û* º Û ÛÛLock Ûa ¸ Ûs — Ûd ˜ Ûf _ Ûg ’ Ûh ‘ Ûj ° Ûk ' Ûl Œ Ûö – Ûä • Û' ­ Û ÛÃÎÎÎÎÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÎÎÁÎÎÎÎÎÝÛShift Û> ¦ ÛZ ÛX ÛC ÛV ÛB ÛN ÛM Û; ¢ Û: Û_ þ ÛShift ÛÛ Û< • Ûz › Ûx œ Ûc • Ûv ž Ûb ƒ Ûn ‚ Ûm | Û, © Û. Û- š Û ÛÃÎÎÎÎÎÎÁÂÎÎÎÁÎÂÎÎÁÎÎÎÂÁÎÎÎÎÁÎÎÎÎÁÎÎÎÎÁÎÎÎÎÁÎÎÎÎÁÂÎÎÎÁÎÎÂÎÁÎÎÎÎÏÎÎÎÎÎÂÎÎÎÎÎÎÝÛCtrl ÛWin ÛAlt Û ÛAlt GrÛWin ÛMenu ÛCtrl ÛÛ Û Û Û Û Û Û Û ÛÀÎÎÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÁÎÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÎÙAdditional characters are accessed using Alt Gr:ÚÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÎÎÎÎÎÌÛ Û! ¡ Û" Û# ¥ Û€ ¢ Û% Û& Û/ Û( Û) Û= Û? ¿ Û É ÛBackspaceÛÛ§ • Û1 » Û2 @ Û3 £ Û4 $ Û5 • Û6 Û7 { Û8 [ Û9 ] Û0 } Û+ \ Û' //Û ÛÃÎÎÎÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÎÎÎÎÎÝÛTab ÛQ ÛW ÛE ë ÛR ÛT ÛY ÛU Ü ÛI í ÛO ó ÛP ÛÅ • Û• þ ÛEnter ÛÛ Ûq Ûw Ûe • Ûr ê Ût Ûy Ûu ü Ûi î Ûo ô Ûp ÿ Ûå à Û¨ ~ Û ÛÃÎÎÎÎÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÌ ÛÛCaps ÛA á ÛS ÛD ÛF è ÛG ÛH ÛJ í ÛK Œ=ÛL Ž ÛÖ Ø ÛÄ Æ Û* » Û ÛÛLock Ûa â Ûs â Ûd Ûf é Ûg Ûh • Ûj ï Ûk Ûl Ûö ø Ûä æ Û' ÿ Û ÛÃÎÎÎÎÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÎÎÁÎÎÎÎÎÝÛShift Û> ÛZ ÛX ÛC ÛV ú ÛB ÛN Ñ ÛM Û; Û: Û_ ÛShift ÛÛ Û< ||Ûz Ûx • Ûc ç Ûv û Ûb ß Ûn ñ Ûm Û, ® Û. \ Û- / Û ÛÃÎÎÎÎÎÎÁÂÎÎÎÁÎÂÎÎÁÎÎÎÂÁÎÎÎÎÁÎÎÎÎÁÎÎÎÎÁÎÎÎÎÁÎÎÎÎÁÂÎÎÎÁÎÎÂÎÁÎÎÎÎÏÎÎÎÎÎÂÎÎÎÎÎÎÝÛCtrl ÛWin ÛAlt Û ÛAlt GrÛWin ÛMenu ÛCtrl ÛÛ Û Û Û Û Û Û Û ÛÀÎÎÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÁÎÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÎÙ<strong>Dyalog</strong> <strong>APL</strong>/IT Italian keyboard (RR)¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ÚÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÎÎÎÎÎÌÛ| ® Û! þ Û" • Û£ ” Û$ “ Û% ² Û& ³ Û/ ´ Û( µ Û) ‹ Û= Š Û? ! Û• Ž ÛBackspaceÛÛ\ ª Û1 ¨ Û2 ¯ Û3 < Û4 ˆ Û5 = Û6 ‰ Û7 > Û8 ¬ Û9 Ÿ Û0 ^ Û' × Ûì ÷ Û ÛÃÎÎÎÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÎÎÎÎÎÝÛTab ÛQ ÛW ÛE º ÛR ÛT ÛY ¼_ÛU ÛI • ÛO ±¨ÛP ÿ Ûé • Û* « ÛEnter ÛÛ Ûq ? Ûw ¾ Ûe ¹ Ûr ½ Ût ~ Ûy † Ûu ‡ Ûi ¼ Ûo ± Ûp * Ûè „ Û+ … Û ÛÃÎÎÎÎÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÌ ÛÛCaps ÛA ÛS ÛD ÛF ÛG ÛH • ÛJ °¨ÛK Œ=ÛL ¦ Ûç ( Û° ) Û§ • Û ÛÛLock Ûa ¸ Ûs — Ûd ˜ Ûf _ Ûg ’ Ûh ‘ Ûj ° Ûk ' Ûl Œ Ûò – Ûà • Ûù € Û ÛÃÎÎÎÎÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÎÎÁÎÎÎÎÎÝÛShift Û> » ÛZ › ÛX œ ÛC • ÛV ž ÛB ÛN ÛM Û; Û: Œ:Û_ \ ÛShift ÛÛ Û< ­ Ûz Ûx Ûc Ûv Ûb ƒ Ûn ‚ Ûm ||Û, © Û. Û- / Û ÛÃÎÎÎÎÎÎÁÂÎÎÎÁÎÂÎÎÁÎÎÎÂÁÎÎÎÎÁÎÎÎÎÁÎÎÎÎÁÎÎÎÎÁÎÎÎÎÁÂÎÎÎÁÎÎÂÎÁÎÎÎÎÏÎÎÎÎÎÂÎÎÎÎÎÎÝÛCtrl ÛWin ÛAlt Û ÛAlt GrÛWin ÛMenu ÛCtrl ÛÛ Û Û Û Û Û Û Û ÛÀÎÎÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÁÎÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÎÙAdditional characters on the front of keycaps are accessed using Alt Gr and AltÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌÚÎÎÎÎÌ ÚÎÎÎÎÌÛ| ® ÛÛ/ ´ ÛÛ( µ ÛÛ) ‹ ÛÛ= Š ÛÛQ ÛÛE º ÛÛé • ÛÛ* « ÛÛç ( ÛÛ° ) ÛÛ§ • Û Û_ \ ÛÛ\ ª ÛÛ7 > ÛÛ8 ¬ ÛÛ9 Ÿ ÛÛ0 ^ ÛÛq ?ÛÛe ¹ ÛÛè „ ÛÛ+ … ÛÛò – ÛÛà • ÛÛù € Û Û- / ÛÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝÃÎÎÎÎÝ ÃÎÎÎÎÝÛº ÛÛ{ ÛÛ{ ÛÛ} ÛÛ} ÛÛ@ ÛÛ• ÛÛ[ { ÛÛ] } ÛÛ@ [ ÛÛ# ] ÛÛ• Û Ûš ÛÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙÀÎÎÎÎÙ ÀÎÎÎÎÙ458


The diagrams illustrate a _mapping_ from key-presses to characters. A _physical_keyboard designed along these lines would probably omit the engraving of lowercase letters, so as to reduce clutter:ÚÎÎÎÎÌÚÎÎÎÎÌMapping: ÛE º Û Engraving: ÛE º ÛÛe ¹ ÛÛ ¹ ÛÀÎÎÎÎÙÀÎÎÎÎÙNB: On Windows systems for UK, US and DK layouts, despite the above diagrams,glyphs œ • ž are, by default, keyed using Ctrl+Shift. This is so that un-shiftedCtrl+X, Ctrl+C, Ctrl+V can retain their "standard" <strong>functions</strong> as Cut, Copy andPaste. This preference may be configured from the session:Options->Configure->Keyboard Shortcuts->Use Ctrl-X,C,V for clipboardWindows Keyboards - Numeric keypad¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯It may be attractive to place box-drawing characters on the numeric keypad, so:ÚÎÎÎÎÂÎÎÎÎÂÎÎÎÎÌ ÚÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÌÛ Û Û Û ÛNum Û Û Û ÛÛIns ÛHomeÛPgUpÛ ÛLockÛ/ Û* Û- ÛÃÎÎÎÎÏÎÎÎÎÏÎÎÎÎÝ ÃÎÎÎÎÏÎÎÎÎÏÎÎÎÎÏÎÎÎÎÝÛ Û Û Û Û Û Û Û ÛÛDel ÛEnd ÛPgDnÛ Û7 Ú Û8  Û9 Ì Û ÛÀÎÎÎÎÁÎÎÎÎÁÎÎÎÎÙ ÃÎÎÎÎÏÎÎÎÎÏÎÎÎÎÝ ÛÛ Û Û Û ÛÛ4 à Û5 Ï Û6 Ý Û+ ÛÚÎÎÎÎÌ ÃÎÎÎÎÏÎÎÎÎÏÎÎÎÎÏÎÎÎÎÝÛ Û Û Û Û Û ÛÛ† Û Û1 À Û2 Á Û3 Ù ÛEn- ÛÚÎÎÎÎÏÎÎÎÎÏÎÎÎÎÌ ÃÎÎÎÎÁÎÎÎÎÏÎÎÎÎÝter ÛÛ Û Û Û Û Û Û ÛÛ„ Û‡ Û… Û Û0 Î Û. Û Û ÛÀÎÎÎÎÁÎÎÎÎÁÎÎÎÎÙ ÀÎÎÎÎÎÎÎÎÎÁÎÎÎÎÁÎÎÎÎÙPhysical US, UK, DK and BE keyboards are now available from <strong>Dyalog</strong> Ltd.Please contact sales@dyalog.com for details.See also: http://en.wikipedia.org/wiki/Keyboard_layoutSee also: unicode.596 dvorak.539 kbolay.547 kbmac.546ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎktnmats „ {sreq„1} ##.kt (rows cols)© Knight's Tour Chess Problem.The challenge is to move a knight around the chessboard visiting each squareexactly once. The 2-vector right argument is the board size (rows and cols) andthe optional left argument is the number of solutions required (default 1).Technical notes:This is an example of a problem that is amenable to tree-searching. The knightstarts from each board square in turn, where he will have between 2 and 8possibilities for his next "step" to a previously unvisited, let's call it"k-adjacent", square. At each subsequent step he will have a choice of up to8 moves until he has either visited all squares and so found a solution to theproblem, or all of his ways forward are blocked by already visited squares andhe has "painted himself into a corner". The choice of initial starting square,together with the decisions facing him at each step on the way, can be visualisedas the forks of a dense branching tree.459


The algorithm proceeds by trying at each step, EACH possible branch of the tree,accumulating solutions when all squares have been visited and "backtracking"when there is no way forward. This could be coded by applying the searchrecursively at each step to each possible way forward using the primitive"each" (¨) operator.However, a small complication, which arises with this particular problem, is thesize of the tree. The number of knight's moves from each square on a standardsized board is:2 3 4 4 4 4 3 23 4 6 6 6 6 4 34 6 8 8 8 8 6 44 6 8 8 8 8 6 44 6 8 8 8 8 6 44 6 8 8 8 8 6 43 4 6 6 6 6 4 32 3 4 4 4 4 3 2which means that to explore the complete tree would involve a number of stepsin the order of the product of these numbers: 9E43. See the examples below forthe number of solutions for some small-sized boards.One possible way forward is to _display_ each solution as it is discovered usingŒ„···, and have the punter interrupt the process when s/he gets bored. An alternativeapproach, adopted here, is to specify how many solutions are required(¸„1) and exit from the process as soon as this many have been found. However,this presents a further problem in that, at this point <strong>APL</strong>'s state indicatorwill contain ×/¾ pendent each (¨) operations which must be interrupted. A ratherclumsy way of achieving this would be to Œsignal the vector of results back toa receiving error-guard at the top level, thus bypassing the pending eaches.The solution adopted here is to use primitive reduction (/) instead of each (¨).Reduction allows us to pass the vector of solutions-so-far as right argument andeach next step position in turn as left argument to the reduction's operandfunction:{operand-function} / step0, step1, ··· stepn, solutions-so-farThe difference is that with _reduction_, successive applications of the operandfunction can be aware of the number of solutions accumulated by items to itsright in the reduction's argument, whereas with _each_, the items are processedin isolation. In some sense, _each_ is parallel, while _reduce_ is sequential.The reduction's operand function is coded to terminate as soon as it finds thatits right argument contains the required number of solutions. The reductioncontinues to apply its operand with each remaining item as left argument but thefunction now returns immediately without searching its tree-branch. By observation,this involves just 168 tests after the first solution for an 8×8 board.A heuristic (sneaky trick) employed in the code is to find easy solutions first.At each step, the following step that itself has the fewest available choices,is examined first. This has the effect of making the knight "cling to the walls"and eke out dark corners, leaving richer pickings in the centre of the board forwhen things get tight later. Note that he will still find all solutions thisway, but they will become harder to find as the search progresses, rather thanbeing more evenly distributed throughout. The technique, suggested by H. C.Warnsdorff in 1823, is known as "Warnsdorff's rule".460


Coding details are as follows:kt„{ŒML„0© Knight's Tour Chess Problem.¸„1 ª sreq„¸ ª nsqs„×/¾ © no. of solutions required, default: 1.kdef„,0 1°.²1 ¯1°.,2 ¯2 © vector of relative knight's moves.net„(›,¼¾)•¨‡(¼¾)°.+kdef © absolute moves from each square.¼°(¼¾)¨†«{© initially empty placement vector.sreq=½¾:¾© found required no. of solutions: stop.path„¸¸,›¸© extended placement vector.nsqs=½path:¾,›path © solution: accumulate.nxt„(›¸)œ¾¾© moves from current square.0=½nxt:¾© stitched: back out.net„¾¾~¨››¸© compressed net.ord„nxt[”†½¨net[nxt]] © tightest-rightmost order.†path ’’ net/ord,›¾ © pursue remaining possibilities.}net/(²,¼¾),›0½›«© from each starting position.}Taking a line at a time:The code executes in migration-level 0, so that † means mix.As the number (¸„1) of distinct solutions required and the total number ofsquares are invariant for the whole of the search, it is convenient to assignthem names [sreq] and [nsqs] for reference from within the operand function.[kdef] is a nested 8-vector of relative Knight's moves. The trivially easyRook's, King's, Queen's and the clearly impossible Bishop's and Pawn's, Tourproblems could be coded merely by changing [kdef] to reflect these pieces' rulesof play.disp kdefÚ…ÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÎÂÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÎÌÛ1 2Û1 ¯2Û¯1 2Û¯1 ¯2Û2 1Û¯2 1Û2 ¯1Û¯2 ¯1ÛÀ~Î…Á~ÎÎ…Á~ÎÎ…Á~ÎÎÎ…Á~Î…Á~ÎÎ…Á~ÎÎ…Á~ÎÎÎ…Ù[net] is an ¾-matrix representing the network of possible next positions fromeach square on the board. Each cell contains a vector of the coordinates of itsk-adjacent squares. [net] is passed as an operand at each step in the search. Asthe knight chooses his next step, the net is compressed to reflect squares thatare still available. The top left corner of the initial [net] for a standardsized chessboard looks like this:disp 3 3†netÚ…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎη Ú…ÎÎÂÎÎÎÌ Û Ú…ÎÎÂÎÎÎÂÎÎÎÌ Û Ú…ÎÎÂÎÎÎÂÎÎÎÂÎÎÎÌÛ Û2 3Û3 2Û Û Û2 4Û3 1Û3 3Û Û Û2 1Û2 5Û3 2Û3 4ÛÛ À~Î…Á~Î…Ù Û À~Î…Á~Î…Á~Î…Ù Û À~Î…Á~Î…Á~Î…Á~Î…ÙÃÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÛ Ú…ÎÎÂÎÎÎÂÎÎÎÌ Û Ú…ÎÎÂÎÎÎÂÎÎÎÂÎÎÎÌ Û Ú…ÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÌÛ Û1 3Û3 3Û4 2Û Û Û1 4Û3 4Û4 1Û4 3Û Û Û1 1Û1 5Û3 1Û3 5Û4 2Û4 4ÛÛ À~Î…Á~Î…Á~Î…Ù Û À~Î…Á~Î…Á~Î…Á~Î…Ù Û À~Î…Á~Î…Á~Î…Á~Î…Á~Î…Á~Î…ÙÃÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÛÚ…ÎÎÂÎÎÎÂÎÎÎÂÎÎÎÌÛÚ…ÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÌÛÚ…ÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÛÛ1 2Û2 3Û4 3Û5 2ÛÛÛ1 1Û1 3Û2 4Û4 4Û5 1Û5 3ÛÛÛ1 2Û1 4Û2 1Û2 5Û4 1Û4 5Û5 2Û5ÛÀ~Î…Á~Î…Á~Î…Á~Î…ÙÛÀ~Î…Á~Î…Á~Î…Á~Î…Á~Î…Á~Î…ÙÛÀ~Î…Á~Î…Á~Î…Á~Î…Á~Î…Á~Î…Á~Î…Á~ÎÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎThe unnamed body of code at the core of the search is a dyadic operator, whosederived function is operand to the reduction.†«{ © initially empty placement vector.···}net/(²,¼¾),›0½›« © from each starting position.461


It is convenient to use an operator, as the values of both the current placementvector and [net] are invariant for the duration of the reduction and so may bebound per-reduction as operands and referenced as ¸¸ and ¾¾ respectively. In thelower line above, the argument to the reduction is a vector (²,¼¾) of all possiblestarting positions followed by an initially empty result vector: 0½›«.Within the body of the derived function:sreq=½¾:¾© found enough solutions: stop.returns the result vector if enough solutions have been found. The next lineappends the next step to the current placement vector:path„¸¸,›¸© extended placement vector.If the path length is now equal to the number of squares on the board, theknight has visited all squares and thus found a solution. The extended solutionsvector is returned as result:(½path)=×/½net:¾,›path© solution: accumulate.The vector of next possible steps is extracted from the current net:nxt„(›¸)œ¾¾© moves from current square.If there are no moves open to the knight, the current solutions vector is passedalong to the next item in the reduction to see if it has more luck:0=½nxt:¾© stitched: back out.Otherwise, if progress is still possible, a new [net] is calculated by removingpaths to the current square from each k-adjacent square.net„¾¾~¨››¸© compressed net.The heuristic described above is applied by sorting remaining k-adjacent squarecoordinates so that the one with the fewest exits is on the right and thusvisited first by the reduction.ord„nxt[”†½¨net[nxt]]© tightest-rightmost order.The final line calls the operator recursively with newly-bound operands [path]and [net] as operand to the reduction of the sorted next-step vector [ord].Notice that because the operands are supplied explicitly, the recursive call ison the operator _’’_, rather than it's derived function _’_.†path ’’ net/ord,›¾© pursue remaining possibilities.When the required number of results have been found, the ¸-vector of (×/¾)-pathsis converted into an ¸-vector of index-origin-sensitive ¾-matrices by thefunction: ¼°(¼¾)¨.Examples:kt 8 81 26 15 24 29 50 13 3216 23 28 51 14 31 64 4927 2 25 30 63 60 33 1222 17 52 59 44 57 48 613 42 21 56 53 62 11 3418 39 54 43 58 45 8 4741 4 37 20 55 6 35 1038 19 40 5 36 9 46 7© 1 tour around a standard 8×8 board.462


disp 3 kt 5 5 © 3 tours around a smaller board.Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ 1 12 25 18 7Û 1 12 23 18 7Û 1 12 23 18 7ÛÛ22 17 8 13 24Û22 17 8 13 24Û24 17 8 13 22ÛÛ11 2 23 6 19Û11 2 25 6 19Û11 2 21 6 19ÛÛ16 21 4 9 14Û16 21 4 9 14Û16 25 4 9 14ÛÛ 3 10 15 20 5‡ 3 10 15 20 5‡ 3 10 15 20 5‡À~ÎÎÎÎÎÎÎÎÎÎÎÎ…Á~ÎÎÎÎÎÎÎÎÎÎÎÎ…Á~ÎÎÎÎÎÎÎÎÎÎÎÎ…Ùkt 3 41 4 7 108 11 2 53 6 9 12© Tour around a non-square board.disp ¯1 kt 4 3© All solutions for a 4×3 board.Ú…ÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÛ 1 12 3Û 1 8 3Û12 1 10Û 8 1 10Û10 1 12Û10 1 8Û 3 12 1Û 3 8 1Û10 5 1Û 4 9 6Û 4 11 6Û 9 4 7Û11 4 7Û 7 4 9Û 7 4 11Û 6 9 4Û 6 11 4Û 7 2Û 7 2 11Û 7 2 9Û 6 11 2Û 6 9 2Û 2 11 6Û 2 9 6Û11 2 7Û 9 2 7Û 4 11Û10 5 8‡10 5 12‡ 3 8 5‡ 3 12 5‡ 5 8 3‡ 5 12 3‡ 8 5 10‡12 5 10‡ 1 8À~ÎÎÎÎÎÎ…Á~ÎÎÎÎÎÎ…Á~ÎÎÎÎÎÎ…Á~ÎÎÎÎÎÎ…Á~ÎÎÎÎÎÎ…Á~ÎÎÎÎÎÎ…Á~ÎÎÎÎÎÎ…Á~ÎÎÎÎÎÎ…Á~ÎÎÎÎÎÎ1(¼1000)­{¾¼¾}1000 kt 8 8 © First 1000 solutions are all distinct.{œ½¯1 kt ¾}¨(¼7 7)-Œio0 0 0 0 0 0 00 1 0 0 0 0 00 0 0 0 0 0 00 0 0 0 16 0 00 0 0 16 0 164 14880 0 0 0 164 1728 375680 0 0 0 1488 37568 6637920© Number of solutions for some small boards.© Here is an alternative coding for a square board from Arthur Whitney:kt_aw„{Œio Œml„0n„¾m„,0 1°.²1 ¯1°.,2 ¯2m„{nƒ¨(¾­¨n|¾)/¾}¨‡(,¼n n)°.+mk„{0


ktourw 80 49 14 31 60 27 12 2915 32 63 54 13 30 59 2650 1 48 43 56 61 28 1133 16 55 62 53 46 25 582 51 44 47 42 57 10 3917 34 19 52 45 40 7 2420 3 36 41 22 5 38 935 18 21 4 37 8 23 6© See: http://www.jsoftware.com/jwiki/Essays/Knight's%20Tour---------------------------------The General Knight's Tour Problem---------------------------------It is characteristic of <strong>APL</strong>'s generality with respect to array rank, that thefunction can be extended to higher-rank chessboards, merely by defining therelative moves for a "hyper-knight". For example, a "normal" (1 2)-knight moves1 square in any of 4 directions, followed by 2 squares in either of 2 directionsperpendicular to the first move. By analogy, a (1 2 3)-knight on a rank-3 board,moves 1 square in any of 6 directions, followed by 2 squares in any of 4 directionsperpendicular to the first move, followed by 3 squares in either of 2directions perpendicular to the first two moves.In the generalised version [gkt], the right argument extends to a matrix, whosefirst row is the board size and second row (default: 1 2) is the definition ofthe hyper-knight's moves. Notice the use of function [pmat] to generate a permutationmatrix.gkt„{ŒML„0© General Knight's Tour Chess Problem.¸„1 ª sreq„¸ © no. of solutions required, default: 1.bsize kdefn„{© board size and moves definition.1+(-½¸)†¾-1© extend to left with 1's.}\2†(‡¾),›1 2© default (1 2)-knight.nsqs„×/bsize ª grid„,¨¼bsize © number of squares and grid coords.net„(›,grid)•¨‡grid°.+ž,‡†{ © absolute moves from each square.¾[pmat½¾]© all permutations of moves,}°,¨†°.,/1 ¯1°×¨kdefn© in each possible direction.¼°grid¨†«{© initially empty placement vector.sreq=½¾:¾© found required no. of solutions: stop.path„¸¸,›¸© extended placement vector.nsqs=½path:¾,›path© solution: accumulate.nxt„(›¸)œ¾¾© moves from current square.0=½nxt:¾© stitched: back out.net„¾¾~¨››¸© compressed net.ord„nxt[”†½¨net[nxt]] © tightest-rightmost order.†path ’’ net/ord,›¾© pursue remaining possibilities.}net/(²,grid),›0½›«© from each starting position.}Examples:gkt 8 81 26 15 24 29 50 13 3216 23 28 51 14 31 64 4927 2 25 30 63 60 33 1222 17 52 59 44 57 48 613 42 21 56 53 62 11 3418 39 54 43 58 45 8 4741 4 37 20 55 6 35 1038 19 40 5 36 9 46 7© Tour of standard board by normal (1 2)-knight.464


gkt †(4 5 6)(1 2 2) © Tour of a 4×5×6 board by a (1 2 2)-knight.1 96 57 72 7 9488 59 106 21 90 3915 112 51 84 19 10870 55 110 17 74 533 98 41 86 5 9250 83 28 103 44 81119 10 67 34 117 1232 65 30 99 36 61105 26 63 38 101 2448 77 14 115 46 79113 22 89 60 107 2056 71 8 95 52 7397 2 69 58 93 642 87 4 91 40 85111 16 75 54 109 1866 33 118 11 68 3527 104 43 82 29 10276 49 114 23 80 459 120 47 78 13 11664 31 100 25 62 37gkt 3 3 4 51 144 43 96 5186 155 90 129 22123 14 121 76 107170 71 180 33 164© Tour of a 3×3×4×5 board by a (1 1 1 2)-knight.136 79 150 25 132153 38 147 48 9962 173 64 159 2811 116 57 102 733 142 35 94 4582 139 88 127 20119 8 113 60 105168 69 178 31 162138 81 140 19 126151 6 135 46 9354 167 74 161 309 114 61 104 5915 118 83 108 7736 179 52 177 34175 4 165 42 91112 89 124 17 110148 85 154 23 130145 40 133 50 9756 171 72 157 2613 122 67 100 6539 146 41 98 4984 149 78 131 24117 12 111 66 101172 63 176 27 158465


134 87 156 21 128141 2 143 44 9568 169 70 163 327 120 55 106 755 152 37 92 4780 137 16 125 18115 10 109 58 103166 53 174 29 160disp ¯1 gkt 2 1½3 1Ú…ÎÎÎÎÂÎÎÎÎÎÌÛ1 2 3Û3 2 1ÛÀ~ÎÎÎ…Á~ÎÎÎ…Ù© All tours of a 3 board by a 1-knight.See also: queens.481 pmat.71ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎmacbfobj „ (##.mac) src© Simple macro processor for bf.[mac] is a simple macro processor intended for use with …bf„.Only single characters may be used as names for definitions. For example, wecould define ';' to generate the BF code to input a single character '0'-'9' andto subtract '0', leaving a number 0-9 in the current cell. This version uses itsright neighbour as a temporary loop counter.;=,>------[+]6‘[-]< .)Technical note:Mac's principal function [mexp]'s use of sub-<strong>functions</strong> [defn] and [dref] illustratea technique called "continuation-passing style" or CPS.[mexp] uses [defn] and [dref] respectively, to define and dereference names.Conceptually, the sub<strong>functions</strong> each _return_ two lists of already- and yet-tobe-processed tokens, with which [mexp] dyadically, and tail-recursively, callsitself.466


We can arrange that the calls on [defn] and [dref] are themselves tail-calls, ifwe have them _call_ [mexp] rather than _return_ to it. In other words, [mexp]'stail-recursive call, following evaluation of its sub<strong>functions</strong> is devolved to thesub<strong>functions</strong>. We do this by passing [mexp] as operand (’) to the sub<strong>functions</strong>,which then become suboperators:b­'=':¸ ’ defn ¾© = defn: accumulate.¯a¹œ¸:¸ ’ dref ¾© ¸ name: expand.¯Now [defn] and [dref] can tail-call [mexp], as ¸¸, rather than to return to it:(¸,þ°›¨name val)¸¸ dd uuu © extended association vectors.¯¯¸ ¸¸ ddd(val(n copy)uu) © expanded macro insert.¯¯Though used explicitly in this example, CPS is more frequently employed behindthe scenes by compiler-optimisers to transform stack-calls into tail-calls.See: http://en.wikipedia.org/wiki/Continuation-passing_styleExamples:movl„'l=[-/] 'mac movl, '2l 1l 0l'[-] [-] [-+]© move left ¸ cell positions ("/" replicates.).© move left 2 1 0 (the last of which will hang BF).OKOKOKOKOKOKmac'a=KO a=OK a'mac'a=K (a=O a)a'mac'a=OK b=a a=KO b'mac'a=KO b=\a a=OK b'mac'O=? b=\\\OK b'mac'a=K b=(a=O a) ba'© subsequent defns replace previous ones.© inner block defns shadow outer ones.© a expanded at b defn time.© a expanded at b dref time.© O not expanded.© inner defn is local to block.© See …bfack„ and …balm„ for some more substantial examples.See also: bfack.527 balm.519 bf.439ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎmayancols „ {base„1} ##.mayan numb© Mayan numbers.As the Pre-Columbian people of Central America used their toes as well as theirfingers for counting, they wound up with a base 20 (vigesimal) number system.In earlier writings, distinct symbols were used to represent different powers of20:1 - dot20 - hatchet or flag400 - feather8000 - purse or incense pouchFor example, if µ, •, †, $ represent pictograms of dot, hatchet, feather andpurse respectively, then$ $ † • • • µ µ µ µ … 20ƒ2 1 3 4 … 16464467


An <strong>APL</strong> function to decode such strings might be:deco„{20ƒ+/'$†•µ'°.=¾~' '}16464deco'$ $ † • • • µ µ µ µ'By the 10th century AD, this had evolved into a positional system in which digits1-19 were expressed as dots 'µ' arranged in 4 rows (hands/feet) of 5 (fingers/toes).For legibility, completed rows of 5 were drawn as a solid line'ŽŽŽŽŽ' and multi-digit numbers were written in columns with more significantdigit-blocks (higher powers of 20) uppermost.For example, the number 258 (20ƒ12 18) would be written:ÚÎÎÎÎÎÎÎÌÛ µ µ ÛÛ ŽŽŽŽŽ Û (2+5+5)×20Û ŽŽŽŽŽ ÛÛ Û +Û µµµ ÛÛ ŽŽŽŽŽ Û (3+5+5+5)×1Û ŽŽŽŽŽ ÛÛ ŽŽŽŽŽ ÛÀÎÎÎÎÎÎÎÙThe system boasted a Zero (represented by a snail or sea shell pictogram) andwhen used for date calculations, had a curious irregularity in the third place(and only the third place) in that items in this position represented 18×20,rather than 20×20. In <strong>APL</strong> terms, this means we use ··· 20 20 18 20 to encodeinto Mayan calendrical numbers.Function mayan's optional left argument selects0: regular ··· 20 20 20 base,1: calendar ··· 20 18 20 base (default).As the principal use of arithmetic was astronomical and calendrical, it is probablethat the 18×20 (=360) irregularity was introduced as a simplification. TheMayan calendar year had 360 regular days together with 5 extra "null" days inthe short month of Wayeb (see below).We should not infer any vagueness about the length of a Mayan year: The Priest-Astronomers managed to calculate Sun, Moon and planet cycles to an astonishingaccuracy; for example, the length of a year was calculated to a precision betterthan we manage with our Gregorian leap year system, even with its no-it-isn't,yes-it-is adjustment at 100 and 400 years:Modern "accurate" solar year · 365.242198 daysMayan calculation of solar year · 365.242 days (-0.000054% error)Gregorian leap year system · · 365.2425 days (+0.000083% error)(The Mayan calendar uses the following units of time:468


)(days ×\Kin 1 1 (day)Uinal 20 20 (month)Tun 360 18 (year)Katun 7,200 20 (a "score" of years)Baktun 144,000 20Piktun 2,880,000 20Kalabtun 57,600,000 20Kinchiltun 1,152,000,000 20Alautun 23,040,000,000 20Hablatun 460,800,000,000 20The names of cardinal numbers reveal a vestigial decimal system:0 xix im 10 lahun 20 hun kal1 hun 11 buluc 40 ca kal2 caa 12 lahca 60 ox kal3 ox 13 oxlahun 80 can kal4 can 14 canlahun 100 hoo kal5 hoo 15 hoolahun 120 uac kal6 uac 16 uaclahun 140 uuc kal7 uuc 17 uuclahun 200 ka hoo kal8 uaxac 18 uaxaclahun 400 hun bak9 bolon 19 bolonlahun 800 ca bak1,200 ox bak1,600 can bak2,000 hoo bak8,000 hun pic160,000 hun calab3,200,000 hun kinchil64,000,000 hun alau(The name for 10 "lahun" appears to include the word for 1 "hun", whichmeans it might translate into English as something like "one-ty". Thiswould imply that the Maya had distinct words for the numbers 0-9, whereasEnglish has distinct words for 1-10 (with Zero following later).Mayan months and weeks both start with day 0.All of this suggests that the Maya were ŒIO„0 people.))Yay Maya!()Positional number systems lend themselves to calculation using various typesof abacus. An example "Nepohualtzitzin" dates from 900-1000 AD.See: eval.dws/notes.sorobanTo convert decimal number 86,672 to (calendrical) Mayan, we would use:20 20 18 20‚8662712 0 11 7Which, using Mayan-style digits, becomes:µ µ 12 × 7200ŽŽŽŽŽŽŽŽŽŽ +469


_@/ 0 × 360 (_@/ is a picture of a snail)+µ 11 × 20ŽŽŽŽŽŽŽŽŽŽ +µ µ 7 × 1ŽŽŽŽŽExamples:µ µŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽµµµŽŽŽŽŽŽŽŽŽŽµŽŽŽŽŽµ µŽŽŽŽŽŽŽŽŽŽ_@/µmayan 6386 © (20 18 20‚6386 … 17 13 6)mayan 4321 © (20 18 20‚4321 … 12 0 1)mayan 70© "Three score years and ten".µµµŽŽŽŽŽŽŽŽŽŽ0 disp°mayan¨ Œ © various numbers:Œ:1234 2345 3456 4567 5678 360 7200ÚÎÎÎÎÎÌ ÚÎÎÎÎÎÌ ÚÎÎÎÎÎÌ ÚÎÎÎÎÎÌ ÚÎÎÎÎÎÌ ÚÎÎÎÎÎÌ ÚÎÎÎÎÎÌÛ Û Û Û Û Û Û Û Û Û Û Û Û ÛÛ µµµ Û Û µ Û Ûµµµµ Û Û µ µ Û ÛŽŽŽŽŽÛ Û µ Û Û µ ÛÃÎÎÎÎÎÝ ÛŽŽŽŽŽÛ ÛŽŽŽŽŽÛ ÛŽŽŽŽŽÛ ÛŽŽŽŽŽÛ ÃÎÎÎÎÎÝ ÃÎÎÎÎÎÝÛ Û ÃÎÎÎÎÎÝ ÃÎÎÎÎÎÝ ÛŽŽŽŽŽÛ ÛŽŽŽŽŽÛ Û Û Û ÛÛ µ µ Û Û Û Û Û ÃÎÎÎÎÎÝ ÃÎÎÎÎÎÝ Û _@/ Û Û _@/ ÛÛŽŽŽŽŽÛ Ûµµµµ Û ÛŽŽŽŽŽÛ Û Û Û Û ÃÎÎÎÎÎÝ ÃÎÎÎÎÎÝÃÎÎÎÎÎÝ ÛŽŽŽŽŽÛ ÛŽŽŽŽŽÛ Û µ µ Û Û µµµ Û Û Û Û ÛÛ Û ÃÎÎÎÎÎÝ ÃÎÎÎÎÎÝ ÛŽŽŽŽŽÛ ÛŽŽŽŽŽÛ Û _@/ Û Û _@/ ÛÛµµµµ Û Û Û Û Û ÛŽŽŽŽŽÛ ÛŽŽŽŽŽÛ ÀÎÎÎÎÎÙ ÃÎÎÎÎÎÝÛŽŽŽŽŽÛ ÛŽŽŽŽŽÛ Û µ Û ÃÎÎÎÎÎÝ ÃÎÎÎÎÎÝ Û ÛÛŽŽŽŽŽÛ ÀÎÎÎÎÎÙ ÛŽŽŽŽŽÛ Û Û Û Û Û _@/ ÛÀÎÎÎÎÎÙ ÛŽŽŽŽŽÛ Û µ µ Û Û µµµ Û ÀÎÎÎÎÎÙÛŽŽŽŽŽÛ ÛŽŽŽŽŽÛ ÛŽŽŽŽŽÛÀÎÎÎÎÎÙ ÀÎÎÎÎÎÙ ÛŽŽŽŽŽÛÛŽŽŽŽŽÛÀÎÎÎÎÎÙ470


© The following function converts ŒTS-style dates into Mayan "Long Count" form,© assuming that the Long Count epoch started August 11th, 3114 BCE.µ µŽŽŽŽŽŽŽŽŽŽµµµµŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽµŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽlong_count„{ © Mayan Long Count from Gregorian (ŒTS) date.¸„584283 © default GMT correlation: 0.0.0.0.0 ­ JD:584283.G„˜days ¾ © Gregorian day.J„2415020+G © Julian day.mayan J-¸ © Mayan from Julian.}long_count 2003 12 25 © 2003-12-25 ­ 12.19.10.15.16long_count 2012 12 21© First day of 14th Baktun.µµµŽŽŽŽŽŽŽŽŽŽ_@/_@/_@/_@/© This stand-alone version converts a YYYY MM DD vector into the equivalent© n.n.n.n.n vector:long_vec„{© Raw long-count vector.¸„584283 © default GMT correlation: 0.0.0.0.0 ­ JD:584283.G„˜days ¾ © Gregorian day.J„2415020+G © Julian day.M„J-¸© Mayan from Julian.}n„1+—18µ1—M © generous number of digits.b„20-2²n†2 © encoding base.v„b‚M© long-count vector.(Ÿ\v¬0)/v © without leading 0s.long_vec 2012 12 2113 0 0 0 0© first day of 14th Backtun471


Correlation with Modern Dates-----------------------------There is overwhelming evidence that the Maya maintained a rigorous calendar.However, as this ceased with the decline of the civilisation, it has been difficultto determine how Mayan dates correspond to the Julian or Gregorian calendars.Two correlations seem to be favoured:The first, known as "GMT" (Goodman, Martinez, Thompson), suggests that Mayandate 0.0.0.0.0 corresponds to Julian date 584,283. This is based on studies ofsome contemporary Central American communities, whose calendar seems to be inheritedfrom the Maya. The argument is that (unless the population of suchpeoples dwindled to a critical number at some point in the past before recovering)it is inconceivable that their calendar should have missed or gained days;it would be as unthinkable as western civilisation's missing or duplicating acouple of Wednesdays.The second "GMT+2", which uses relatively recent evidence, is based upon Mayanrecorded observations of eclipses. We can date such events with extremeaccuracy, and they suggest a correlation with Julian date 584,285.If the astronomical recording was accurate, an explanation of the discrepencymight be that the 584,285 calendar was subsequently adjusted to realign with theseasons in the same way the Gregorian calendar skipped 3-13 September in 1752.The <strong>functions</strong> shown here use the 584,283 (GMT) correlation, which now appears tobe the more generally accepted one.Cycles------Today almost all of the civilised world enjoys a 7-day week. This cycle, whichis independent of month and year, is so universal that we forget why we decidedupon seven.(muse:There are many suggestions as to the origin of the 7-day week, and no singletheory is widely accepted as the definitive answer.One example is that the concept of the week arose in primitive agriculturalsocieties, where seven days was about the right interval for a farmer toprepare and bring his goods to market. A shorter interval would waste toomuch time away from production, and a longer one might risk goods perishingbetween market days.Note firstly, that there are strong reasons for market days to occur at exactlyregular intervals: every so-many days, rather than being constantlyre-negotiated. With a regular "week", there is much more chance of everyoneshowing up on the same day; a prerequisite for successful trading.It is tempting to speculate whether widespread acceptance of an interval ofseven days might have come about by a form of natural selection, rather thanas a collective or bureaucratic conscious decision: A farmer returning fromhis local market might have found on occasion, that his figs, chickens andso-forth were ready again after six days. If his local market did not fallon the following day, he might have felt inclined to take his goods to aneighbouring village's market even though it was slightly farther to travel.Villages whose market days just happened to accommodate natural agriculturalcycles would tend to retain regular trade as well as to attract occasionaladditional visitors, whereas those with slightly more inconvenient cycleswould tend to decline. In this way, farmer-friendly market cycles would tendautomatically to become the norm.472


(Having established same-length cycles in adjacent villages, there mayhave been a second mechanism that selected for staggered market days,while reinforcing their regularity.Service providers such as pot-menders and tooth-pullers, who needed notime to prepare between market days, would probably have toured marketson different days in nearby locations. In the case of a collision, thetrader would probably have chosen the better-attended market, and hispresence there would in turn have made that market marginally more attractiveto shoppers, tending to increase its size, ... and so on.Looking at the larger picture, these rotating service providers (axegrinders,sooth-sayers, hair-cutters, entertainers, ...) could be seenas the teeth on the interlocking cogs of an expanding economic machine,which absorbed adjacent communities, synchronising them into the 7-daycycle.)()If this were the case, we might expect the names of the days of theweek (in a particular locale) to indicate the locations of the moreimportant markets in that area: "Oxford-day", "Banbury-day", and soforth, rather than being named after deities.That the Mayan civilization chose a week with thirteen days (see below), asopposed to one with seven, does not, of itself, detract from this theory, asthe Mayan agricultural profile was quite different from that of Eurasia's"Fertile Crescent". See "Guns, Germs, and Steel: The Fates of Human Societies",Jared Diamond.)But all of this is merely conjecture ...The Mayan calendar included several cycles, two of which often accompany a LongCount date. Combinations such as these are similar to our compound date format:Wednesday, November 5, 2003.ÛÛÛÀÎÎÎÎ Month 12-cycle.ÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ Weekday 7-cycle."Haab" is a cycle of 18 × 20-day months."Tzolkin" is a cycle of 20 × 13-day weeks.Haab has 18 × 20-day months together with one 5-day month making a total of 365days in the year:Pop Wo Sip Sotz' TzekXul Yaxk'in Mol Ch'en YaxSak Keh Mak K'ank'in MuwanPax K'ayab Kumk'u Wayeb (5)Months„'Pop' 'Wo' 'Sip' 'Sotz''' 'Tzek' 'Xul' 'Yaxk''in' 'Mol' 'Ch''en' 'YaxThe short month of Wayeb is inauspicious; one should refrain from washing, haircombing and nit-picking during Wayeb.473


Day-within-month and Month name can be extracted by:haab„{ŒIO„0© Mayan day within month.¸„245 © align Gregorian and Maya cycles.mon day„0 20‚365|¸+˜days ¾ © month index and day number.name„monœMonths© name of month.day name© origin-0 day within month.}haab 2003 12 254 K'ank'inhaab 2003 12 265 K'ank'inhaab 2003 12 276 K'ank'in© Christmas day 2003 fell on the fourth day of K'ank'in.© Boxing day fell on the fifth day of K'ank'in.© ... etc.The names of the 20 Tzolkin days are as follows:Imix Ik' Ak'bal K'an ChikchanKimi Manik' Lamat Muluk OkChuwen Eb Ben Ix MenKib Kaban Etz'nab Kawak AhawDays„'Imix' 'Ik''' 'Ak''bal' 'K''an' 'Chikchan' 'Kimi' 'Manik''' 'Lamat' 'MuThe 20 Tzolkin days are reused cyclically for successive 13-day weeks. Thismeans that a particular day number (0-12) coincides with a particular day name(Imix-Ahaw) only every 20×13 = 260 days.The Tzolkin date can be extracted using:tzolkin„{ŒIO„0© Mayan Tzolkin number and day.¸„2 16 © align Gregorian and Maya cycles.num day„13 20|¸+˜days ¾ © day number and name index.name„dayœDays© day name.(num+1)name© origin-1 day within cycle.}tzolkin 2003 12 259 Kibtzolkin 2003 12 2610 Kabantzolkin 2003 12 2711 Etz'nab© Christmas day 2003 fell on day 9, a Kib-day.© Boxing day fell on day 10, a Kaban-day.© ... etc.An Attractive Gift------------------Print the result of the following function on a stone tablet or gold pendant tomake an attractive "Stela" of a loved one's date of birth. The final (lower) twodigits show Tzolkin and Haab dates, the Mayan cultural equivalent of an astrologicalstar sign.time_units„'Kin' 'Uinal' 'Tun' 'Katun' 'Baktun' 'Piktun' 'Kalabtun' 'Kinch474


stela„{ © Stela for date ¾ (yyyy mm dd).long„long_count ¾© Long Count days.hnum hname„haab ¾© month and day.tnum tname„tzolkin ¾© week and day.digits„long®†,°mayan¨tnum hnum © maya-style digits.lft„1 0°‡¨digits© left-side column: numbers.rgt„²7†hname tname,time_units © right-side column: names.0 disp lft,rgt © collected stela.}Here are Stelae for Victoria and David Beckham, together with little Brooklyn,Romeo, Cruz and Harper. Notice how Brooklyn and Cruz share the same star signs.david„1974 04 17victoria„1975 05 02brooklyn„1999 03 04romeo„2002 09 01cruz„2005 02 20harper7„2011 07 10stela¨¨(david victoria)(brooklyn romeo cruz harper7)ÚÎÎÎÎÎÂÎÎÎÎÎÎÌ ÚÎÎÎÎÎÂÎÎÎÎÎÎÌ ÚÎÎÎÎÎÂÎÎÎÎÎÎÌ ÚÎÎÎÎÎÂÎÎÎÎÎÎÌ ÚÎÎÎÎÎÂÎÎÎÎÎÛ µ µ Û Û Û µ µ Û Û Û µ µ Û Û Û µ µ Û Û Û µ µ ÛÛŽŽŽŽŽÛBaktunÛ ÛŽŽŽŽŽÛBaktunÛ ÛŽŽŽŽŽÛBaktunÛ ÛŽŽŽŽŽÛBaktunÛ ÛŽŽŽŽŽÛBaktuÛŽŽŽŽŽÛ Û ÛŽŽŽŽŽÛ Û ÛŽŽŽŽŽÛ Û ÛŽŽŽŽŽÛ Û ÛŽŽŽŽŽÛÃÎÎÎÎÎÏÎÎÎÎÎÎÝ ÃÎÎÎÎÎÏÎÎÎÎÎÎÝ ÃÎÎÎÎÎÏÎÎÎÎÎÎÝ ÃÎÎÎÎÎÏÎÎÎÎÎÎÝ ÃÎÎÎÎÎÏÎÎÎÎÎÛ µµµ Û Û Û µµµ Û Û Ûµµµµ Û Û Ûµµµµ Û Û Ûµµµµ ÛÛŽŽŽŽŽÛKatun Û ÛŽŽŽŽŽÛKatun Û ÛŽŽŽŽŽÛKatun Û ÛŽŽŽŽŽÛKatun Û ÛŽŽŽŽŽÛKatunÛŽŽŽŽŽÛ Û ÛŽŽŽŽŽÛ Û ÛŽŽŽŽŽÛ Û ÛŽŽŽŽŽÛ Û ÛŽŽŽŽŽÛÛŽŽŽŽŽÛ Û ÛŽŽŽŽŽÛ Û ÛŽŽŽŽŽÛ Û ÛŽŽŽŽŽÛ Û ÛŽŽŽŽŽÛÃÎÎÎÎÎÏÎÎÎÎÎÎÝ ÃÎÎÎÎÎÏÎÎÎÎÎÎÝ ÃÎÎÎÎÎÏÎÎÎÎÎÎÝ ÃÎÎÎÎÎÏÎÎÎÎÎÎÝ ÃÎÎÎÎÎÏÎÎÎÎÎÛ _@/ Û Tun Û Û µ Û Tun Û ÛŽŽŽŽŽÛ Tun Û Ûµµµµ Û Tun Û Û µ µ ÛÃÎÎÎÎÎÏÎÎÎÎÎÎÝ ÃÎÎÎÎÎÏÎÎÎÎÎÎÝ ÃÎÎÎÎÎÏÎÎÎÎÎÎÝ ÛŽŽŽŽŽÛ Û ÛŽŽŽŽŽÛ TunÛ µµµ Û Û Ûµµµµ Û Û Û µ µ Û Û ÃÎÎÎÎÎÏÎÎÎÎÎÎÝ ÛŽŽŽŽŽÛÛŽŽŽŽŽÛUinal Û ÛŽŽŽŽŽÛUinal Û ÛŽŽŽŽŽÛUinal Û Ûµµµµ ÛUinal Û ÃÎÎÎÎÎÏÎÎÎÎÎÛŽŽŽŽŽÛ Û ÛŽŽŽŽŽÛ Û ÛŽŽŽŽŽÛ Û ÛŽŽŽŽŽÛ Û Û _@/ ÛUinalÃÎÎÎÎÎÏÎÎÎÎÎÎÝ ÃÎÎÎÎÎÏÎÎÎÎÎÎÝ ÛŽŽŽŽŽÛ Û ÃÎÎÎÎÎÏÎÎÎÎÎÎÝ ÃÎÎÎÎÎÏÎÎÎÎÎÛ µ µ Û Û Û µ µ Û Û ÃÎÎÎÎÎÏÎÎÎÎÎÎÝ Û µ Û Û Ûµµµµ ÛÛŽŽŽŽŽÛ Kin Û ÛŽŽŽŽŽÛ Kin Û Ûµµµµ Û Û ÛŽŽŽŽŽÛ Kin Û ÛŽŽŽŽŽÛ KinÛŽŽŽŽŽÛ Û ÛŽŽŽŽŽÛ Û ÛŽŽŽŽŽÛ Kin Û ÛŽŽŽŽŽÛ Û ÛŽŽŽŽŽÛÃÎÎÎÎÎÏÎÎÎÎÎÎÝ ÃÎÎÎÎÎÏÎÎÎÎÎÎÝ ÛŽŽŽŽŽÛ Û ÛŽŽŽŽŽÛ Û ÛŽŽŽŽŽÛÛ µ µ Û Eb Û ÛŽŽŽŽŽÛ Eb Û ÛŽŽŽŽŽÛ Û ÃÎÎÎÎÎÏÎÎÎÎÎÎÝ ÃÎÎÎÎÎÏÎÎÎÎÎÛŽŽŽŽŽÛ Û ÛŽŽŽŽŽÛ Û ÃÎÎÎÎÎÏÎÎÎÎÎÎÝ ÛŽŽŽŽŽÛ Kib Û Û µµµ ÛKawakÃÎÎÎÎÎÏÎÎÎÎÎÎÝ ÃÎÎÎÎÎÏÎÎÎÎÎÎÝ Û µ µ ÛKawak Û ÛŽŽŽŽŽÛ Û ÃÎÎÎÎÎÏÎÎÎÎÎÛŽŽŽŽŽÛ Pop Û Û _@/ Û Wo Û ÛŽŽŽŽŽÛ Û ÃÎÎÎÎÎÏÎÎÎÎÎÎÝ Û µ µ ÛK'ayaÀÎÎÎÎÎÁÎÎÎÎÎÎÙ ÀÎÎÎÎÎÁÎÎÎÎÎÎÙ ÃÎÎÎÎÎÏÎÎÎÎÎÎÝ Ûµµµµ Û Mol Û ÀÎÎÎÎÎÁÎÎÎÎÎÛ µ µ Û Û ÛŽŽŽŽŽÛ ÛÛŽŽŽŽŽÛK'ayabÛ ÀÎÎÎÎÎÁÎÎÎÎÎÎÙÛŽŽŽŽŽÛ ÛÀÎÎÎÎÎÁÎÎÎÎÎÎÙReferences:http://en.wikipedia.org/wiki/Maya_numeralshttp://en.wikipedia.org/wiki/Mesoamerican_Long_Count_calendarIfrah, G. "The Universal History of Numbers".Diamond, J. "Guns, Germs, and Steel: The Fates of Human Societies".http://mayan-calendar.com/calc.htmlSee also: eval.dws/notes.soroban.See also: roman.490 days.356 Dates.353 ary.317475


ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎmazecmat„ {smooth„1} ##.maze shape© Kidz maze.Returns a random maze of specified shape. Note that the rank of the maze may begreater than 2. The optional left argument determines whether the output willuse "smooth" box-drawing characters (default) or "clunky" characters, which arepresent in all fonts.Entry to, and exit from the maze is through a portal, top left and bottom right,marked "‡".In a high-rank maze, we can move within a plane in the normal way, or warp betweenplanes, up-down/left-right (but not diagonally), providing our way is notblocked by a closed cell containing a °. See examples below.Technical notes:Maze construction is in two stages:[path] Starting at the entrance and exit, a pair of random paths are extendedalternately into the maze, until they meet. This is the solution path.[fill] Starting from each randomly chosen unvisited cell, a random path is extendeduntil it collides with an existing path. This is a "tributary" ofthe solution path.As an exercise in functional programming, the coding of the maze function is"stateless". This means that there are no variables (only definitions, thatdon't vary) and no partial assignments, such as ]„ and )„. In particular, subfunction…select„ has been used in places where indexed assignment would be considerablyfaster on the grounds that, for a folly such as this, the speed ofexecution may take second place to exploration of programming techniques.As a coding aid, the closing } of some of the inner <strong>functions</strong> have been labelledusing an ad hoc notation, with the "type" of the function. For example initialisationfunction [init] is labelled: (c d)(fm to)„:: size. This is to be interpretedas "function takes a right argument of size and returns a nested 2-vectorof control and display arrays, and from and to node indices". Similarly, function[extend] is of type: (c d)(fm to)„(c d)tag :: path, which means it takes apath vector on the right and a "structure" on the left, and returns a pair ofpairs.476


Examples:maze 10 20 © 2-maze.Ú‡ÎÎÎÎÂÎÎÎÎÎÎÎÂÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÂÎÎÎÌÛ Û Û Û Û Û ÛÛ ÚÎÂÎÁÎÂÎÌ Û ÀÎÌ ÀÎÎ Û ÎÎÎÎÂÎÎ Û Û ÀÎÎ ÛÛ Û Û Û Û Û Û Û Û Û ÛÛ Û Û Û Û Û ÀÎÎÎÙ ÎÎÂÎÏÎÎ ÎÎÏÎÎÎÂÎÏÎÎÎÎ ÛÛ Û Û Û Û Û Û Û Û ÛÛ ÀÎÎ Û ÎÎÙ ÚÎÎÎÌ ÎÎÙ Û ÎÎÌ ÃÎÌ Û ÀÎÂÎÎ ÛÛ Û Û Û Û Û Û Û Û ÛÛ ÎÎÌ ÃÎÂÎÎÎÝ Û Û ÎÎÌ ÃÎÂÎÝ Û ÃÎÎÎÎ ÀÎÌ ÛÛ Û Û Û Û Û Û Û Û Û Û Û ÛÃÎÎ Û Û Û Û Û Û Û Û ÀÎÙ Û ÀÎÎ Û ÚÎÎÎÎÎÝ ÛÛ Û Û Û Û Û Û Û Û Û Û ÛÃÎÌ ÃÎÎÎÙ ÃÎÂÎÁÎÏÎÁÎÎÎÎÎÏÎÎÎÂÎÙ Û ÚÎÎ Û ÛÛ Û Û Û Û Û Û Û Û Û ÛÛ Û ÃÎÎ ÎÎÝ Û Û Û ÎÎÂÎÎÎÙ Û Û ÚÎÎÎÝ ÎÎÝ ÛÛ Û Û Û Û Û Û Û Û Û Û ÛÛ ÎÎÏÎÌ Û ÀÎÂÎÙ ÀÎÎ Û Û Û Û Û Û Û ÀÎÌ Û ÛÛ Û Û Û Û Û Û Û Û Û Û Û ÛÛ ÎÎÙ Û Û Û Û ÎÎÂÎÎ ÀÎÁÎÁÎÙ ÃÎÎ ÀÎÌ ÀÎÎÎÝÛ Û Û Û Û Û Û ÛÀÎÎÎÎÎÁÎÁÎÁÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÁÎÎηÙ0 maze 10 20 © same maze with clunky output.+‡+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+| | | | | | |+ +-+-+-+-+ + +-+ +-+ + +-+-+-+ + + +-+ +| | | | | | | | | | |+ + + + + + +-+-+ +-+-+-+ +-+-+-+-+-+-+ +| | | | | | | | | |+ +-+ + +-+ +-+-+ +-+ + +-+ +-+ + +-+-+ +| | | | | | | | | |+ +-+ +-+-+-+ + + +-+ +-+-+ + +-+-+ +-+ +| | | | | | | | | | | | |+-+ + + + + + + + + +-+ + +-+ + +-+-+-+ +| | | | | | | | | | | |+-+ +-+-+ +-+-+-+-+-+-+-+-+-+-+ + +-+ + +| | | | | | | | | | |+ + +-+ +-+ + + + +-+-+-+ + + +-+-+ +-+ +| | | | | | | | | | | |+ +-+-+ + +-+-+ +-+ + + + + + + + +-+ + +| | | | | | | | | | | | |+ +-+ + + + + +-+-+ +-+-+-+ +-+ +-+ +-+-+| | | | | | | |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+‡+maze 3 3 4 © 3-mazeÚÎÂÎÂÎÂÎÌ ÚÎÂÎÂÎÎÎÌ ÚÎÂÎÂÎÂÎÌ ÚÎÎÎÂÎÂÎÌ ÚÎÂÎÂÎÂÎÌ ÚÎÎÎÎÎÎÎÌ ÚÎÂÎÂÎÂÎÌÛ‡Û°Û°Û°Û Û Û Û Û Û Û°Û Û°Û Û Û Û Û Û°Û°Û°Û Û Û Û Û°Û°Û°Û°ÛÃÎÏÎÏÎÏÎÝ ÃÎÙ ÃÎÎ Û ÃÎÏÎÏÎÏÎÝ Û Û ÃÎÁÎÝ ÃÎÏÎÏÎÏÎÝ ÃÎÎÎÎ Û Û ÃÎÏÎÏÎÏÎÝÛ°Û°Û°Û°Û Û Û Û Û°Û Û°Û Û Û Û Û Û Û Û°Û Û°Û Û Û Û Û°Û°Û°Û°ÛÃÎÏÎÏÎÏÎÝ ÃÎÎÎÏÎÎ Û ÃÎÏÎÏÎÏÎÝ Û ÃÎÁÎÎÎÝ ÃÎÏÎÏÎÏÎÝ ÃÎÎÎÌ ÀÎÝ ÃÎÏÎÏÎÏÎÝÛ°Û°Û°Û°Û Û Û Û Û Û Û°Û°Û Û Û Û Û°Û Û°Û°Û Û Û Û Û°Û°Û°Û‡ÛÀÎÁÎÁÎÁÎÙ ÀÎÎÎÁÎÎÎÙ ÀÎÁÎÁÎÁÎÙ ÀÎÁÎÎÎÎÎÙ ÀÎÁÎÁÎÁÎÙ ÀÎÎÎÁÎÎÎÙ ÀÎÁÎÁÎÁÎÙ477


The route through this maze is as follows:‡ entranceÚÎÂÎÂÎÂÎÌ ÚÎÂÎÂÎÎÎÌ ÚÎÂÎÂÎÂÎÌ ÚÎÎÎÂÎÂÎÌ ÚÎÂÎÂÎÂÎÌ ÚÎÎÎÎÎÎÎÌ ÚÎÂÎÂÎÂÎÌÛ1Û°Û°Û°Û Û2Û Û Û Û3Û°Û Û°Û Û4 Û Û Û Û°Û°Û°Û Û Û Û Û°Û°Û°Û°ÛÃÎÏÎÏÎÏÎÝ ÃÎÙ ÃÎÎ Û ÃÎÏÎÏÎÏÎÝ Û Û ÃÎÁÎÝ ÃÎÏÎÏÎÏÎÝ ÃÎÎÎÎ Û Û ÃÎÏÎÏÎÏÎÝÛ°Û°Û°Û°Û Û Û Û Û°Û Û°Û Û Û5Û Û Û Û6Û°Û Û°Û Û7 Û Û Û°Û°Û°Û°ÛÃÎÏÎÏÎÏÎÝ ÃÎÎÎÏÎÎ Û ÃÎÏÎÏÎÏÎÝ Û ÃÎÁÎÎÎÝ ÃÎÏÎÏÎÏÎÝ ÃÎÎÎÌ ÀÎÝ ÃÎÏÎÏÎÏÎÝÛ°Û°Û°Û°Û Û Û Û Û Û Û°Û°Û Û Û Û Û°Û Û°Û°Û Û Û 8Û Û°Û°Û°Û9ÛÀÎÁÎÁÎÁÎÙ ÀÎÎÎÁÎÎÎÙ ÀÎÁÎÁÎÁÎÙ ÀÎÁÎÎÎÎÎÙ ÀÎÁÎÁÎÁÎÙ ÀÎÎÎÁÎÎÎÙ ÀÎÁÎÁÎÁÎÙexit ‡Similarly:maze 2 3 2 3 © 4-maze.ÚÎÂÎÂÎÌ ÚÎÂÎÂÎÌ ÚÎÂÎÂÎÌ ÚÎÂÎÂÎÌ ÚÎÂÎÂÎÌ ÚÎÂÎÂÎÌ ÚÎÂÎÂÎÌÛ°Û°Û°Û Û‡Û°Û°Û Û°Û°Û°Û Û°Û°Û°Û Û°Û°Û°Û Û°Û°Û°Û Û°Û°Û°ÛÃÎÏÎÏÎÝ ÃÎÏÎÏÎÝ ÃÎÏÎÏÎÝ ÃÎÏÎÏÎÝ ÃÎÏÎÏÎÝ ÃÎÏÎÏÎÝ ÃÎÏÎÏÎÝÛ°Û°Û°Û Û°Û°Û°Û Û°Û°Û°Û Û°Û°Û°Û Û°Û°Û°Û Û°Û°Û°Û Û°Û°Û°ÛÀÎÁÎÁÎÙ ÀÎÁÎÁÎÙ ÀÎÁÎÁÎÙ ÀÎÁÎÁÎÙ ÀÎÁÎÁÎÙ ÀÎÁÎÁÎÙ ÀÎÁÎÁÎÙÚÎÂÎÂÎÌ ÚÎÂÎÂÎÌ ÚÎÂÎÂÎÌ ÚÎÂÎÎÎÌ ÚÎÂÎÂÎÌ ÚÎÂÎÎÎÌ ÚÎÂÎÂÎÌÛ°Û°Û°Û Û Û Û Û Û Û Û Û Û Û Û Û°Û°Û Û Û Û Û Û°Û°Û°ÛÃÎÏÎÏÎÝ ÃÎÁÎÁÎÝ ÃÎÏÎÏÎÝ ÃÎÏÎÂÎÝ ÃÎÏÎÏÎÝ ÃÎÁÎÎÎÝ ÃÎÏÎÏÎÝÛ°Û°Û°Û Û Û Û°Û°Û Û Û Û Û Û Û Û°Û°Û Û Û Û°Û°Û°ÛÀÎÁÎÁÎÙ ÀÎÎÎÎÎÙ ÀÎÁÎÁÎÙ ÀÎÁÎÁÎÙ ÀÎÁÎÁÎÙ ÀÎÎÎÎÎÙ ÀÎÁÎÁÎÙÚÎÂÎÂÎÌ ÚÎÂÎÂÎÌ ÚÎÂÎÂÎÌ ÚÎÂÎÂÎÌ ÚÎÂÎÂÎÌ ÚÎÂÎÂÎÌ ÚÎÂÎÂÎÌÛ°Û°Û°Û Û Û Û°Û Û°Û°Û°Û Û°Û Û°Û Û°Û°Û°Û Û Û Û°Û Û°Û°Û°ÛÃÎÏÎÏÎÝ ÃÎÏÎÏÎÝ ÃÎÏÎÏÎÝ ÃÎÏÎÏÎÝ ÃÎÏÎÏÎÝ ÃÎÏÎÏÎÝ ÃÎÏÎÏÎÝÛ°Û°Û°Û Û Û°Û°Û Û°Û°Û°Û Û Û Û Û Û°Û°Û°Û Û°Û°Û°Û Û°Û°Û°ÛÀÎÁÎÁÎÙ ÀÎÁÎÁÎÙ ÀÎÁÎÁÎÙ ÀÎÁÎÁÎÙ ÀÎÁÎÁÎÙ ÀÎÁÎÁÎÙ ÀÎÁÎÁÎÙÚÎÂÎÂÎÌ ÚÎÂÎÎÎÌ ÚÎÂÎÂÎÌ ÚÎÂÎÎÎÌ ÚÎÂÎÂÎÌ ÚÎÎÎÎÎÌ ÚÎÂÎÂÎÌÛ°Û°Û°Û Û Û Û Û Û°Û°Û Û Û Û Û°Û°Û°Û Û Û Û°Û°Û°ÛÃÎÏÎÏÎÝ Û ÃÎÂÎÝ ÃÎÏÎÏÎÝ ÃÎÙ Û Û ÃÎÏÎÏÎÝ Û Û ÎÎÝ ÃÎÏÎÏÎÝÛ°Û°Û°Û Û Û Û Û Û°Û Û Û Û Û Û Û°Û°Û°Û Û Û Û Û°Û°Û°ÛÀÎÁÎÁÎÙ ÀÎÁÎÁÎÙ ÀÎÁÎÁÎÙ ÀÎÎÎÁÎÙ ÀÎÁÎÁÎÙ ÀÎÁÎÎÎÙ ÀÎÁÎÁÎÙÚÎÂÎÂÎÌ ÚÎÂÎÂÎÌ ÚÎÂÎÂÎÌ ÚÎÂÎÂÎÌ ÚÎÂÎÂÎÌ ÚÎÂÎÂÎÌ ÚÎÂÎÂÎÌÛ°Û°Û°Û Û°Û°Û°Û Û°Û°Û°Û Û°Û°Û°Û Û°Û°Û°Û Û°Û°Û°Û Û°Û°Û°ÛÃÎÏÎÏÎÝ ÃÎÏÎÏÎÝ ÃÎÏÎÏÎÝ ÃÎÏÎÏÎÝ ÃÎÏÎÏÎÝ ÃÎÏÎÏÎÝ ÃÎÏÎÏÎÝÛ°Û°Û°Û Û°Û°Û°Û Û°Û°Û°Û Û°Û°Û°Û Û°Û°Û°Û Û°Û°Û‡Û Û°Û°Û°ÛÀÎÁÎÁÎÙ ÀÎÁÎÁÎÙ ÀÎÁÎÁÎÙ ÀÎÁÎÁÎÙ ÀÎÁÎÁÎÙ ÀÎÁÎÁÎÙ ÀÎÁÎÁÎÙWith solution:478‡ entranceÚÎÂÎÂÎÌ ÚÎÂÎÂÎÌ ÚÎÂÎÂÎÌ ÚÎÂÎÂÎÌ ÚÎÂÎÂÎÌ ÚÎÂÎÂÎÌ ÚÎÂÎÂÎÌÛ°Û°Û°Û ÛaÛ°Û°Û Û°Û°Û°Û Û°Û°Û°Û Û°Û°Û°Û Û°Û°Û°Û Û°Û°Û°ÛÃÎÏÎÏÎÝ ÃÎÏÎÏÎÝ ÃÎÏÎÏÎÝ ÃÎÏÎÏÎÝ ÃÎÏÎÏÎÝ ÃÎÏÎÏÎÝ ÃÎÏÎÏÎÝÛ°Û°Û°Û Û°Û°Û°Û Û°Û°Û°Û Û°Û°Û°Û Û°Û°Û°Û Û°Û°Û°Û Û°Û°Û°ÛÀÎÁÎÁÎÙ ÀÎÁÎÁÎÙ ÀÎÁÎÁÎÙ ÀÎÁÎÁÎÙ ÀÎÁÎÁÎÙ ÀÎÁÎÁÎÙ ÀÎÁÎÁÎÙÚÎÂÎÂÎÌ ÚÎÂÎÂÎÌ ÚÎÂÎÂÎÌ ÚÎÂÎÎÎÌ ÚÎÂÎÂÎÌ ÚÎÂÎÎÎÌ ÚÎÂÎÂÎÌÛ°Û°Û°Û ÛbÛ Û Û Û Û Û Û Û Ûo pÛ Û°Û°ÛqÛ Û Ûs rÛ Û°Û°Û°ÛÃÎÏÎÏÎÝ ÃÎÁÎÁÎÝ ÃÎÏÎÏÎÝ ÃÎÏÎÂÎÝ ÃÎÏÎÏÎÝ ÃÎÁÎÎÎÝ ÃÎÏÎÏÎÝÛ°Û°Û°Û Ûg hÛ Û°Û°ÛiÛ Û Û ÛjÛ Û Û°Û°Û Û Û Û°Û°Û°ÛÀÎÁÎÁÎÙ ÀÎÎÎÎÎÙ ÀÎÁÎÁÎÙ ÀÎÁÎÁÎÙ ÀÎÁÎÁÎÙ ÀÎÎÎÎÎÙ ÀÎÁÎÁÎÙÚÎÂÎÂÎÌ ÚÎÂÎÂÎÌ ÚÎÂÎÂÎÌ ÚÎÂÎÂÎÌ ÚÎÂÎÂÎÌ ÚÎÂÎÂÎÌ ÚÎÂÎÂÎÌÛ°Û°Û°Û ÛcÛ Û°Û Û°Û°Û°Û Û°ÛnÛ°Û Û°Û°Û°Û Û ÛtÛ°Û Û°Û°Û°ÛÃÎÏÎÏÎÝ ÃÎÏÎÏÎÝ ÃÎÏÎÏÎÝ ÃÎÏÎÏÎÝ ÃÎÏÎÏÎÝ ÃÎÏÎÏÎÝ ÃÎÏÎÏÎÝÛ°Û°Û°Û ÛfÛ°Û°Û Û°Û°Û°Û Û Û ÛkÛ Û°Û°Û°Û Û°Û°Û°Û Û°Û°Û°ÛÀÎÁÎÁÎÙ ÀÎÁÎÁÎÙ ÀÎÁÎÁÎÙ ÀÎÁÎÁÎÙ ÀÎÁÎÁÎÙ ÀÎÁÎÁÎÙ ÀÎÁÎÁÎÙ


ÚÎÂÎÂÎÌ ÚÎÂÎÎÎÌ ÚÎÂÎÂÎÌ ÚÎÂÎÎÎÌ ÚÎÂÎÂÎÌ ÚÎÎÎÎÎÌ ÚÎÂÎÂÎÌÛ°Û°Û°Û ÛdÛ Û Û Û°Û°Û Û Ûm Û Û°Û°Û°Û Û u Û Û°Û°Û°ÛÃÎÏÎÏÎÝ Û ÃÎÂÎÝ ÃÎÏÎÏÎÝ ÃÎÙ Û Û ÃÎÏÎÏÎÝ Û Û ÎÎÝ ÃÎÏÎÏÎÝÛ°Û°Û°Û ÛeÛ Û Û Û°Û Û Û Û ÛlÛ Û°Û°Û°Û Û Û vÛ Û°Û°Û°ÛÀÎÁÎÁÎÙ ÀÎÁÎÁÎÙ ÀÎÁÎÁÎÙ ÀÎÎÎÁÎÙ ÀÎÁÎÁÎÙ ÀÎÁÎÎÎÙ ÀÎÁÎÁÎÙÚÎÂÎÂÎÌ ÚÎÂÎÂÎÌ ÚÎÂÎÂÎÌ ÚÎÂÎÂÎÌ ÚÎÂÎÂÎÌ ÚÎÂÎÂÎÌ ÚÎÂÎÂÎÌÛ°Û°Û°Û Û°Û°Û°Û Û°Û°Û°Û Û°Û°Û°Û Û°Û°Û°Û Û°Û°Û°Û Û°Û°Û°ÛÃÎÏÎÏÎÝ ÃÎÏÎÏÎÝ ÃÎÏÎÏÎÝ ÃÎÏÎÏÎÝ ÃÎÏÎÏÎÝ ÃÎÏÎÏÎÝ ÃÎÏÎÏÎÝÛ°Û°Û°Û Û°Û°Û°Û Û°Û°Û°Û Û°Û°Û°Û Û°Û°Û°Û Û°Û°ÛwÛ Û°Û°Û°ÛÀÎÁÎÁÎÙ ÀÎÁÎÁÎÙ ÀÎÁÎÁÎÙ ÀÎÁÎÁÎÙ ÀÎÁÎÁÎÙ ÀÎÁÎÁÎÙ ÀÎÁÎÁÎÙexit ‡See also: select.81 hampton.545ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎmmind##.mmind ŒA[?4½6]© Mastermind or "cows and bulls".Reima Naumanen provides this one-liner to play Mastermind (or "cows and bulls").The rules of the game are:- The machine chooses a 4-letter code at random from characters A B C D E F.Letters in the code may be repeated, so examples might be: ABDF, FFAB, BBBB,··- You try to guess the combination by suggesting a 4-letter code.- The machine responds to your guess by reporting a "hint" of how many "cows"and "bulls" you scored:A bull (*) is a correct letter in its correct position.A cow (+) is a correct letter in the wrong position.Note that the order and position of the *s and +s in the hint has no significance;for example, **+ means that two of the letters (not necessarily thefirst two) are in the correct position and that a further one is present butin the wrong position.For example, if the code is ABBA, then the following guesses would elicithints:code: ABBA ABBA ABBA ABBA ABBA ABBA ABBA ABBAguess: EACD CDEF BACD AAAD BAAB BABA AAAA ABBAhint: + ++ *+ ++++ **++ ** ****- Based on the hints, you try repeated guesses until you score 4 bulls (****)and the game finishes.- The aim of the game is to guess the hidden code in as few moves as possible.For example, if the code were ADEA, a game might look like this:ADEA(hidden code)479


mmind ŒA[?4½6]FECF1st guess+ 0 bulls 1 cowBABC2nd guess+ 1 cowEBDB3rd guess++ 2 cowsDDFB4th guess* 1 bullADEA5th guess**** 4 bulls! (osuu oikein)Note that while "official" Mastermind uses 4 letters chosen from 6, Reima'sversion works with any number chosen from any number. Try: mmind Œa[5?9], etc.Technical notes:Remarkably, the game can be both programmed and invoked by entering just 77 keystrokes(including the terminating _Return_) into a clear session!{'*'Ÿ.¬(½¾)†Œ„'*+'/þ¾{(¸+.=¾),¸{+/œ˜/+/¨(›ž¸)°.=¨(¸¬¾)°/¨¸ ¾}¾}•:’¾}ŒA[?4½6]If we eschew codes with repeated letters, this number drops to 55!{'*'Ÿ.¬(½¾)†Œ„'*+'/þ¾{(¸+.=¾),+/(¸¹¾)>¸=¾}•:’¾}ŒA[5?6]Veli-Matti Jantunen suggests this version, which copes with wrong-length answers:{¾{Œ„(+/¨


ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎmorsecode „ ##.morse text© Conversion to/from Morse code.text „ ##.morse code © Samuel Morse 1791-1872.Given a text vector of characters from: "A-Z", "0-9", ".,:?'-/()"@= ", [morse]returns a nested vector of the equivalent Morse codes.Conversely, given a nested vector of Morse codes, the function returns the equivalentplain text.Unrecognised characters and codes are ignored. In particular, [morse] ignoreslower-case letters "a-z".Morse alphabet tree-------------------Morse chooses shorter codes for more frequently occurring letters (in English).The designers of old-style linotype type-setting machines judged the order ofthis frequency to be: ETAOIN SHRDLU CMFWYP VBGKQJ XZ.. Û _ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌ. E _ . T _ÚÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÌÚÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÌ. I _ . A _ . N _ . M _ÚÎÎÎÁÎÎÎÌ ÚÎÎÎÁÎÎÎÌ ÚÎÎÎÁÎÎÎÌ ÚÎÎÎÁÎÎÎÌ. S _ . U . R . W _ . D _ . K _ . G _ OÚÎÁÎÌ ÚÎÙ ÚÎÙ ÚÎÁÎÌ ÚÎÁÎÌ ÚÎÁÎÌ ÚÎÁÎÌH V F L P J B X C Y Z QRef: http://en.wikipedia.org/wiki/Morse_code(muse:)It is said that experienced telegraph operators, who used morse code totransmit messages, could recognise each others tapping style; the equivalentof being able to distinguish someone's handwriting (or coding style).Examples:disp morse 'HELLO WORLD'Ú…ÎÎÎÂÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÂÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÎÂÎÎÎÌÛ....Û.Û.-..Û.-..Û---Û/Û.--Û---Û.-.Û.-..Û-..ÛÀÎÎÎ…Á…ÁÎÎÎ…ÁÎÎÎ…ÁÎÎ…Á…ÁÎÎ…ÁÎÎ…ÁÎÎ…ÁÎÎÎ…ÁÎÎ…Ùmorse morse'ROUND TRIP'ROUND TRIPdisp morse 'Samuel Finley Breese'Ú…ÎÎÂÎÂÎÎÎÎÂÎÂÎÎÎÎÌÛ...Û/Û..-.Û/Û-...ÛÀÎÎ…Á…ÁÎÎÎ…Á…ÁÎÎÎ…Ù© Morse code from plain text.© ... and back again.© lower-case letters ignored,disp morse ucase 'Samuel Finley Breese' © ... so convert to upper-case.Ú…ÎÎÂÎÎÂÎÎÂÎÎÎÂÎÂÎÎÎÎÂÎÂÎÎÎÎÂÎÎÂÎÎÂÎÎÎÎÂÎÂÎÎÎÎÂÎÂÎÎÎÎÂÎÎÎÂÎÂÎÂÎÎÎÂÎÌÛ...Û.-Û--Û..-Û.Û.-..Û/Û..-.Û..Û-.Û.-..Û.Û-.--Û/Û-...Û.-.Û.Û.Û...Û.ÛÀÎÎ…ÁÎ…ÁÎ…ÁÎÎ…Á…ÁÎÎÎ…Á…ÁÎÎÎ…ÁÎ…ÁÎ…ÁÎÎÎ…Á…ÁÎÎÎ…Á…ÁÎÎÎ…ÁÎÎ…Á…Á…ÁÎÎ…Á…ÙSee also: ucase.176 packH.197481


ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎmp3{files} „ {type„''} ##.mp3 dirs © Create playlist(s) for music directories.Supplied by Veli-Matti Jantunen, who says:Creates simple playlists in each directory (and each sub-directory thereof)specified by the right argument. Currently, five playlist file formats aresupported and it should be pretty simple to add new formats if needed (or finetunethe specific formatter for the user's own needs).The left argument specifies:lower case letters 'abmpw' for different playlist file types,upper case letters 'MOW4' for different music file types andupper case letters 'DFPS' for extra switches.The following file types may be created:a … .asx file (Media Player should detect this),b … .b4s file (WinAmp's XML format, not supported by the version 5.*),m … .m3u file (the old WinAmp playlist, this is the default),p … .pls file (WinAmp),w … .wpl file (Media Player).Several files may be created in one run. The playlist file is created only ifcorresponding music files are present in the directory. By default, the filelist doesn't contain the path (i.e. the file "d:\mp3\Album\song.mp3" will beshown in the list only as "song.mp3").The switches are:D … Delete the playlists (from directories specified in the right argument),F … make the Folder name as the playlist name (instead of the default playlist.extension)P … use the full file Path name in the list,S … do not visit the Sub-directories.The shy result has all the created playlist names.For example,To create new m3u and wpl playlists for all the mp3 albums found in d:\mp3,C:\My Music and their sub-directories:'mw' mp3 'd:\mp3' 'C:\My Music'To delete all asx and b4s playlists found in d:\mp3 and its children:'abD' mp3 'd:\mp3'The function uses ŒNA for directory reading.N.B. I cannot guarantee that the playlist files will work in every machine configuration- I have just sort of reverse engineered the minimum file formatsthat seem to work adequately in my machines.Examples:mp3 'd:\mp3' © create m3u playlist files (if there are any mp3 files)© in the directory d:\mp3 and its sub-directories.mp3 'd:' 'c:' © create m3u files in every C: and D: directory where© there are mp3 files..'apw' mp3 'd:\mp3' © create the asx, pls and wpl playlist files.482


'apwO' mp3 'd:\mp3' © as the previous example, but create only for .ogg files.'apwOP' mp3 'd:\mp3' © ditto, now the file lists contain paths.'apwD' mp3 'd:\mp3' © delete all asx, pls and wpl playlists.'apwDS' mp3 'd:\mp3' © ditto, but only from the d:\mp3 directory.ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎqueenscmats „ ##.queens N© The N-Queens ProblemPlace N Queens on an N×N chessboard such that no queen is attacking any other.This coding returns all unique solutions for the given board as a vector ofcharacter matrices with 'µ' representing a queen. Trivially equivalent solutionsthat represent rotations and reflections are omitted.Technical notes:There are many ways to approach this problem. A simple but rather expensivemethod is to generate all permutations (see …pmat„) of ¼¾ and then filter outthose that represent a solution. The approach used here is a tree search: First,place a queen anywhere in the first row (or "rank" in chess-speak). Next, placea second queen in the second rank on any square not attacked by the first one.Continue placing queens on "safe" squares in successive ranks until either allranks have been covered (a configuration that constitutes a solution) or until arank is reached where all squares are attacked by previously placed queens. Inthe latter case, "back track" to the last rank where all squares have not yetbeen tried and after moving that queen to a different square, try again.For a standard 8×8 chessboard, there are 96 solutions but these include 2 reflectionsand 4 rotations of each "distinct" solution, so in fact there are only12 interesting solutions. Part of the challenge is to avoid generating or to removethese duplicates.During the search, the current state of play is represented by two vectors, eachitem of which corresponds to a rank. The first is a simple vector of placementsalready made and the second, a vector of vectors of remaining free squares perrank. For example, after placing the first 4 queens, the state of play mightlook like this:file: 0 1 2 3 4 5 6 7ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌrank: 0 Û· µ · · · · · ·Û1 Û· · · µ · · · ·Û2 Û· · · · · · µ ·Û3 Ûµ · · · · · · ·Û4 Û· · ± · · · · ±Û5 Û· · · · ± ± · ·Û6 Û· · · · ± ± · ·Û7 Û· · ± · · ± · ±ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙµ placed queen.± free square.The vector of placements is 1 3 6 0, and the vector of free squares is (2 7),(4 5)(4 5)(2 5 7). Placing the next queen in column 2, would render the state ofplay:483


file: 0 1 2 3 4 5 6 7ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌrank: 0 Û· µ · · · · · ·Û1 Û· · · µ · · · ·Û2 Û· · · · · · µ ·Û3 Ûµ · · · · · · ·Û4 Û· · µ · · · · ·Û5 Û· · · · ± ± · ·Û6 Û· · · · · ± · ·Û7 Û· · · · · · · ±ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙµ placed queen.± free square.with placement vector: 1 3 6 0 2, and free-square vector: (4 5)(5)(7).The search is implemented by passing the placement vector as left argument andfree-square vector as right argument to inner function [search]: The tree searchconsists of appending in turn, each free square from the next rank, to theplacement vector and recursively calling search with a reduced vector of freesquares. Search returns if either any of the ranks contain no free squares:(›«)¹¾, or no ranks remain: 0=½¾, which constitutes a solution. Notice a smalldetail: the result when there are no free squares must be suitably enclosed:0½›«, so that in the three cases where there are no solutions queens¨0 2 3, theoverall result is a vector of _matrices_ in common with all other cases.search„{(›«)¹¾:0½›«0=½¾:rmdups ¸hd tl„(œ¾)(1‡¾)next„¸°,¨hdrems„hd free¨›tl†,/next ’¨rems}© Search for all solutions.© stitched: abandon this branch.© all done: solution!© head 'n tail of remaining ranks.© possible next steps.© unchecked squares.© ... in following ranks.[Free] returns a new vector of free-squares after those in check from the nextplacement have been removed:free„{¾~¨¸+(½¾)†cvex}© Unchecked squares.As [cvex], is invariant during the search, it is computed initially as an optimisation.cvex„(1+¼¾)×›¯1 0 1© Checking vectors.Given that the final solution vector must contain no duplicates, a further optimisationis to start the tree search from only half of the squares in the firstrank. Any solution resulting from a search starting from the remaining squaresmust constitute a "reflected" solution. So instead of:we have:squares„¾½›¼¾ © (0 1 2 3 4 5 6 7) (0 1 2 3 4 5 6 7) ···squares„(›¼—¾÷2),1‡¾½›¼¾ © (0 1 2 3) (0 1 2 3 4 5 6 7) ···which _halves_ the total search time.[rmdups] discards "boring" equivalent solutions by generating all 4 rotationsand 2 reflections and then rejecting the putative solution if it isn't themost attractive member of this set:484


mdups„{ © Ignore duplicate solution.rots„{{”¾}\4/›¾}© 4 rotations.refs„{{“¾}\2/›¾}© 2 reflections.best„{(œ“†¾)œ¾}© best (=lowest) solution.all8„,†refs¨rots ¾© all 8 orientations.(¾­best all8)œ«(,›¾) © ignore if not best.}Finally, [fmt] renders each solution as a character matrix with '·' for an emptysquare and 'µ' for an occupied one. Each matrix is spread horizontally to makeit appear more square-shaped on the screen.fmt„{chars„'·µ'[(†¾)°.=¼¸]expd„1‡,†¸½›0 1†¨‡‡expd\chars}© Format solution.© char array of placed queens.© expansion mask.© vector of char matrices.Alternative Codings-------------------The following, perhaps rather opaque coding, is remarkable in that it is a_single expression_ for the vector of unique solutions to the problem in thesame way that {+/¾÷½¾} is a single expression for the mean value of a numericvector. It contains no guards; just applications of operators to operands and<strong>functions</strong> to arguments. The code assumes an index-origin and migration-level of0.{¾{†¨‡‡(2|1‡¼2׸)\((†¾)°.=¼¸)œ¨›'·µ'}ž{{(œ“†¾)œ¾},†¾}¨{{“¾}\2/›¾}¨°{{”¾}\4We can prove that it works by pasting it into the session and appending an argument(such as 8) after remembering to set Œio Œml„0. To examine it further, wemight find it helpful to assign a name and use the editor to split it up alittle:qn„{¾{†¨‡‡(2|1‡¼2׸)\((†¾)°.=¼¸)œ¨›'·µ'}ž{{(œ“†¾)œ¾},†¾}¨{{“¾}\2/›¾}¨°{{”¾}\4/›¾}¨¾{(¸=,†½¨¾)/¾}},¨†«{†(¸¸,¸)’’(1‡¾¾~¨¸+(1+¼½¾¾)×›¯1 0 1)/((œ¾¾)~¸+¯1 0 1),›¾,›¸¸,¸}(1‡¾½›²¼¾)/(²¼—¾÷2),›0½›«The left side (top in the wrapped version) of the expression is much the same as[queens], except that the slightly shorter and quicker: '·µ'[(†¾)°.=¼¸] has beenreplaced by the slightly purer ((†¾)°.=¼¸)œ¨›'·µ', in order to avoid <strong>APL</strong>'s arguablyanomalous square-bracket syntax.The main difference is in the search sub-expression, which uses _reduce /_rather than _each ¨_ to recur along ranks.†«{†(¸¸,¸)’’(1‡¾¾~¨¸+(1+¼½¾¾)×›¯1 0 1)/((œ¾¾)~¸+¯1 0 1),›¾,›¸¸,¸}(1‡¾½›²¼¾)/(²¼—¾÷2),›0½›«The operand of the outer reduction is a function derived from the inner dyadicoperator whose left and right array operands are the placement and free-squarevectors respectively:485


†··· © disclose result of reduction.·«{ © left operand: placement vector.··· © inner dyadic operator.}(1‡¾½›²¼¾)··· © right operand: free-square vector.···········/··· © reduction with above derived function.The argument to the reduction is the vector of squares in the first rank andemulates queens in representing only half of the files as an optimisation. Thefinal item is the vector of solutions so-far and is enclosed to ensure thecorrect rank for the three cases where there are no solutions.············(²¼—¾÷2),›0½›«The inner dyadic operator then, has operands/arguments:Left argument: next square in current rank.Left operand: current placement vector.Right operand: free-square vector.Right argument: vector of solutions-so-far.This leaves just the code _inside_ the operator, which is another reductionusing a recursive call with new values for the left and right operands:†(¸¸,¸)’’(1‡¾¾~¨¸+(1+¼½¾¾)×›¯1 0 1)/((œ¾¾)~¸+¯1 0 1),›¾,›¸¸,¸This breaks down as a reduction:†··································· © disclose result of reduction.·······’’··························· © recursive call on operator with·(¸¸,¸)····························· © operands: extended placement vector·········(1‡¾¾~¨¸+(1+¼½¾¾)×›¯1 0 1)· © and reduced free-square vector.···································/ © ... reduction.The argument to the reduction is the vector of solutions-so-far extended withthe new path and prefixed with the vector of remaining squares in the next rank:····································((œ¾¾)~¸+¯1 0 1),›¾,›¸¸,¸The new path: _¸¸,¸_ does not constitute a solution if it's shorter than ¾items. These 'short' solutions are removed later when full-length vectors arefiltered out by the next function:¾{ © board size.(¸=,†½¨¾)/¾ © filter out full-length solutions.}Roger Hui suggests this coding. Transliterated from J, it finds all solutionsincluding reflections and rotations:queens„{¾{((+/b)š¾),¸|(,b)/¼×/½b„~†(›¼¸)¹¨(‡¾)+[0]¨›(c-¼c„1‡½¾)°.ׯ1 0 1}ÿ¾¼See: http://jsoftware.com/jwiki/Essays/N_Queens_ProblemThis coding, which includes reflections and rotations, uses depth-first traversaloperator …trav„:486qtrav„{© N-queens using trav DFS.subs„{(›¾),¨(¼½œ¸)~atk ¾} © sub-trees of tree-node ¾.accm„{¸,((½¾)=½œ¸)/›¾}© accumlation of N-placement.atk„{†(›¾)+¯1 0 1×›²¼½¾} © columns under attack in row 1+¾.fmt„{¾°.=¼½¾}© formatted as bool matrix.fmt¨(‡0 ¾½0)accm trav subs « © formatted solutions.}


Examples:disp°queens¨0 1 2 3 4 5 6 © solutions for small boards.Ú´Ì Ú…Ì Ú´ÎÎÌ Ú´ÎÎÎÎÌ Ú…ÎÎÎÎÎÎÌ Ú…ÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÌ Ú…ÎÎÎÎÎÎÎÎÎÎÌÛ ² Ûµ‡ Û ² Û ² Û· µ · ·Û Ûµ · · · ·Û· µ · · ·Û Û· µ · · · ·ÛÀ´Ù À…Ù ÀÎÎ…Ù ÀÎÎÎÎ…Ù Û· · · µÛ Û· · µ · ·Û· · · · µÛ Û· · · µ · ·ÛÛµ · · ·Û Û· · · · µÛ· · µ · ·Û Û· · · · · µÛÛ· · µ ·‡ Û· µ · · ·Ûµ · · · ·Û Ûµ · · · · ·ÛÀÎÎÎÎÎÎ…Ù Û· · · µ ·‡· · · µ ·‡ Û· · µ · · ·ÛÀÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎ…Ù Û· · · · µ ·‡ÀÎÎÎÎÎÎÎÎÎÎ…Ùdisp queens 7Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÛµ · · · · · ·Ûµ · · · · · ·Û· µ · · · · ·Û· µ · · · · ·Û· µ · · · · ·Û· µ · · ·Û· · µ · · · ·Û· · · µ · · ·Û· · · µ · · ·Û· · · · µ · ·Û· · · · µ · ·Û· · · · ·Û· · · · µ · ·Û· · · · · · µÛµ · · · · · ·Ûµ · · · · · ·Û· · · · · · µÛ· · µ · ·Û· · · · · · µÛ· · µ · · · ·Û· · · · · · µÛ· · · µ · · ·Û· · · µ · · ·Û· · · · ·Û· µ · · · · ·Û· · · · · µ ·Û· · · · µ · ·Û· · · · · · µÛµ · · · · · ·Û· · · µ ·Û· · · µ · · ·Û· µ · · · · ·Û· · µ · · · ·Û· · µ · · · ·Û· · µ · · · ·Ûµ · · · ·Û· · · · · µ ·‡· · · · µ · ·‡· · · · · µ ·‡· · · · · µ ·‡· · · · · µ ·‡· · · · µÀÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎdisp 3 4½queens 8Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ̇µ · · · · · · ·Ûµ · · · · · · ·Û· µ · · · · · ·Û· µ · · · · · ·ÛÛ· · · · µ · · ·Û· · · · · µ · ·Û· · · µ · · · ·Û· · · · µ · · ·ÛÛ· · · · · · · µÛ· · · · · · · µÛ· · · · · µ · ·Û· · · · · · µ ·ÛÛ· · · · · µ · ·Û· · µ · · · · ·Û· · · · · · · µÛµ · · · · · · ·ÛÛ· · µ · · · · ·Û· · · · · · µ ·Û· · µ · · · · ·Û· · µ · · · · ·ÛÛ· · · · · · µ ·Û· · · µ · · · ·Ûµ · · · · · · ·Û· · · · · · · µÛÛ· µ · · · · · ·Û· µ · · · · · ·Û· · · · · · µ ·Û· · · · · µ · ·ÛÛ· · · µ · · · ·‡· · · · µ · · ·‡· · · · µ · · ·‡· · · µ · · · ·‡ÃÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÝÛ· µ · · · · · ·Û· µ · · · · · ·Û· µ · · · · · ·Û· µ · · · · · ·ÛÛ· · · · µ · · ·Û· · · · · µ · ·Û· · · · · µ · ·Û· · · · · · µ ·ÛÛ· · · · · · µ ·Ûµ · · · · · · ·Û· · · · · · · µÛ· · µ · · · · ·ÛÛ· · · µ · · · ·Û· · · · · · µ ·Û· · µ · · · · ·Û· · · · · µ · ·ÛÛµ · · · · · · ·Û· · · µ · · · ·Ûµ · · · · · · ·Û· · · · · · · µÛÛ· · · · · · · µÛ· · · · · · · µÛ· · · µ · · · ·Û· · · · µ · · ·ÛÛ· · · · · µ · ·Û· · µ · · · · ·Û· · · · · · µ ·Ûµ · · · · · · ·ÛÛ· · µ · · · · ·‡· · · · µ · · ·‡· · · · µ · · ·‡· · · µ · · · ·‡ÃÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÝÛ· µ · · · · · ·Û· · µ · · · · ·Û· · µ · · · · ·Û· · µ · · · · ·ÛÛ· · · · · · µ ·Û· · · · µ · · ·Û· · · · µ · · ·Û· · · · · µ · ·ÛÛ· · · · µ · · ·Û· µ · · · · · ·Û· · · · · · · µÛ· µ · · · · · ·ÛÛ· · · · · · · µÛ· · · · · · · µÛ· · · µ · · · ·Û· · · · µ · · ·ÛÛµ · · · · · · ·Ûµ · · · · · · ·Ûµ · · · · · · ·Û· · · · · · · µÛÛ· · · µ · · · ·Û· · · · · · µ ·Û· · · · · · µ ·Ûµ · · · · · · ·ÛÛ· · · · · µ · ·Û· · · µ · · · ·Û· µ · · · · · ·Û· · · · · · µ ·ÛÛ· · µ · · · · ·‡· · · · · µ · ·‡· · · · · µ · ·‡· · · µ · · · ·‡ÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…Ù{œ½queens ¾}¨0 to 16© Number of solutions for various boards.0 1 0 0 1 2 1 6 12 46 92 341 1787 9233 45752 285053 1846955See also: kt.457 sudoku.491 pmat.71 queensX.554 trav.130 X.160487


ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎquzzlesoln „ ##.quzzle grid© A hard, simple problem.Supplied by David Crossley, who says: I spotted this puzzle in the Economist,Dec 4-10,2004, "A hard, simple problem", p82.A grid of squares of unit size is represented by a text matrix. The grid containsan initial setup of non-overlapping, rectangular tiles whose sides are 1 ormore units. Each tile is identified by a unique character (except '•' or '_').Thus, the tile marked 1 below is a 2×2 tile; 3 is a 2×1 tile. Blank squares canbe moved into.Here is an example setup in a 5×4 grid: 1122 top left tile is 111134 11The task is to move the 2×2 tile (1) in 34the top-left corner to any other corner 5667 top right tile is 22by sliding tiles up, down, left or right. 5889There are just 2 initial moves: 1-down or 5-up. It•s not as simple as it looks!Function [quzzle] works out the shortest possible solutions for puzzles of thisclass, though it may take some time for larger grids.Example:Œ„grid„5 4½'11221134 3456675889'112211343456675889quzzle gridBottom-right Bottom-leftin 37 moves in 56 moves488


1‡ 1‡2„ 2„2„ 2„3† 3†4† 4†7† 7†7„ 7„4‡ 4‡4‡ 4‡3… 3…7† 7†7† 7†1… 1…5† 5†5† 5†6„ 6„8„ 8„9„ 9„9† 9†8… 8…8… 8…6‡ 6‡9„ 9„9„ 9„1‡ 1‡7‡ 7‡7„ 7„3„ 3„4† 4†4† 4†1… 1…9… 9…9† 5‡6† 7„8„ 9†8„ 9†1‡ 1„4‡4‡3…2…9…7…5†5†1„4„3‡2…7†9„4†8†6…6…1‡489


ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎripplenvec „ ##.ripple nvec© Perfect Ripple Shuffle.Items from the second and first halves of the argument vector are interleaved inthe result.Technical note:The code shows an innovative use of the grade-up and grade-down primitive <strong>functions</strong>:ripple„{¾[“”(½¾)½0 1]}© Perfect Ripple Shuffle.(muse:Cumulatively re-applying ripple eventually yields the original argument.In the case of a 52-vector, ripple must be re-applied 52 times to completethe cycle but for other length vectors, the cycle is shorter. Here are therepeat counts for vectors of length 0-99.10 10½ {1¼þ(¼¾){(¼¾)­¸ ripple pow ¼¾}¨¾}¨0 to 991 1 2 2 4 4 3 3 6 610 10 12 12 4 4 8 8 18 186 6 11 11 20 20 18 18 28 285 5 10 10 12 12 36 36 12 1220 20 14 14 12 12 23 23 21 218 8 52 52 20 20 18 18 58 5860 60 6 6 12 12 66 66 22 2235 35 9 9 20 20 30 30 39 3954 54 82 82 8 8 28 28 11 1112 12 10 10 36 36 48 48 30 30There may be a simple expression for these numbers.See: Vector 21.3 "Jottings 43: A Rippling Good Yarn!" Norman Thomson.http://www.vector.org.uk/archive/v213/jot213.htm)See also: http://www.mathscarves.orgExamples:ripple ¼16 © 9-16 meshed with 1-8.9 1 10 2 11 3 12 4 13 5 14 6 15 7 16 8show„œ¨°›°(,'HCDS'°.,'A23456789XJQK') © show card(s) no. ¾.© Hearts, Clubs, Diamonds, Spades.© ¯ ¯ ¯ ¯© Ace 2-9 X(10) Jack Queen King.© ¯ ¯ ¯ ¯ ¯show 4 13½¼52HA H2 H3 H4 H5 H6 H7 H8 H9 HX HJ HQ HKCA C2 C3 C4 C5 C6 C7 C8 C9 CX CJ CQ CKDA D2 D3 D4 D5 D6 D7 D8 D9 DX DJ DQ DKSA S2 S3 S4 S5 S6 S7 S8 S9 SX SJ SQ SKshow 4 13½ ripple ¼52DA HA D2 H2 D3 H3 D4 H4 D5 H5 D6 H6 D7H7 D8 H8 D9 H9 DX HX DJ HJ DQ HQ DK HKSA CA S2 C2 S3 C3 S4 C4 S5 C5 S6 C6 S7C7 S8 C8 S9 C9 SX CX SJ CJ SQ CQ SK CK490© show deck in order.© shuffled deck.


ipple ripple ¼16 © double ripple.13 9 5 1 14 10 6 2 15 11 7 3 16 12 8 43 ripple pow ¼16 © triple ripple.15 13 11 9 7 5 3 1 16 14 12 10 8 6 4 24 ripple pow ¼16 © quadruple ripple reverses.16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 18 ripple pow ¼16 © octuple ripple restores.1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16See also: pow.218 to.316ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎrrrounds „ ##.rr players© Round-robin tournament.From Jay Foad:Given an even number of participants, how do we arrange that each plays against(or dances with) everyone else, exactly once?See: http://en.wikipedia.org/wiki/Round-robin_tournamentFor example, with contestants, Maggie, Milly, Molly and May, there will be threerounds. The columns of matrices along the first axis show the bouts: in thefirst round, Maggie plays May, while Milly plays Molly, and so on ...'Maggie' 'Milly' 'Molly' 'May'[rr 4]Maggie MillyMay MollyMaggie MollyMilly MayMaggie MayMolly MillyTechnical note:Note the use of embedded assignments of local names m, v and n:IO+(¾÷2)†[2]m,[0.5]²m„0,v²1+n n½v„¼n„0—¾-1¯¯¯¯ ¯¯While embedded assignment has its detractors, there are some advantages. Takinga trivial (and contrived) example:2{1+x„1+¾}0 © successor of successor of ...Firstly, the code reads nicely from left to right: "One more than x where x isone more than omega".¯¯¯¯¯¯¯¯¯¯¯¯Secondly, local assignment is _currently_ marginally faster than, for example,employing an inner Dfn. Here is a timing comparison of some alternative codings:cmpx'{1+x„¾+1}0' '{{1+¾}1+¾}0' '(1°+)°(1°+)0' '{1+¾}°(1°+)0' '{1+¾}°{1+¾}0'{1+x„¾+1}0 … 2.1E¯6 | 0% ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ{{1+¾}1+¾}0 … 2.6E¯6 | +22% ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ(1°+)°(1°+)0 … 2.9E¯6 | +36% ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ{1+¾}°(1°+)0 … 4.1E¯6 | +91% ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ{1+¾}°{1+¾}0 … 4.6E¯6 | +116% ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ491


(muse:)The code-snippet: 0—... is present to allow the degenerate case of a 0-playertournament, which returns an array of shape 0 2 0, indicating 0 roundsof 0 plays each. In general, an ¾-player tournament requires ¯1+¾÷2 rounds,so it could be argued that the length of the first axis in this case shouldbe ¯1, which is impossible. The maths says that if no-one shows up to TheBall, the band should play ¯1 tunes before packing up and going home.Examples:display rr¨ 0 2 to 8Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ ÚÚ´Ì ÚÚ…Ì ÚÚ…ÎÎÌ ÚÚ…ÎÎÎÎÌ ÚÚ…ÎÎÎÎÎÎÌ ÛÛ ²‡0Û ‡‡1Û ‡‡1 2Û ‡‡1 2 3Û ‡‡1 2 3 4Û ÛÛ ÛÛ0Û ÛÛ2Û ÛÛ4 3Û ÛÛ6 5 4Û ÛÛ8 7 6 5Û ÛÛ ÀÀ~Ù ÀÀ~Ù ÛÛ Û ÛÛ Û ÛÛ Û ÛÛÛÛ1 3Û ÛÛ1 3 4Û ÛÛ1 3 4 5Û ÛÛÛÛ2 4Û ÛÛ2 6 5Û ÛÛ2 8 7 6Û ÛÛ ÛÛ Û ÛÛ Û ÛÛ Û ÛÛÛÛ1 4Û ÛÛ1 4 5Û ÛÛ1 4 5 6Û ÛÛÛÛ3 2Û ÛÛ3 2 6Û ÛÛ3 2 8 7Û ÛÛ ÀÀ~ÎÎÙ ÛÛ Û ÛÛ Û ÛÛÛÛ1 5 6Û ÛÛ1 5 6 7Û ÛÛÛÛ4 3 2Û ÛÛ4 3 2 8Û ÛÛ ÛÛ Û ÛÛ Û ÛÛÛÛ1 6 2Û ÛÛ1 6 7 8Û ÛÛÛÛ5 4 3Û ÛÛ5 4 3 2Û ÛÛ ÀÀ~ÎÎÎÎÙ ÛÛ Û ÛÛÛÛ1 7 8 2Û ÛÛÛÛ6 5 4 3Û ÛÛ ÛÛ Û ÛÛÛÛ1 8 2 3Û ÛÛÛÛ7 6 5 4Û ÛÛÀÀ~ÎÎÎÎÎÎÙ ÛÀ¹ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙ© Tournaments for 0 2 .. 8 players.See also: cmat.19 cmpx.500ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎromanres „ {sin} (fvn ##.roman) dex© Roman numeral arithmetic.Nobis Reima Naumanen hic opvm dat, qvi envmerare facit per nvmeri Romani.Exempli gratia:XVIIILXXXI'IX' +roman 'IX' © 9 + 9 … 18'IX' ×roman 'IX' © 9 × 9 … 81{¼¾}roman 'X' © 1 .. 10I II III IV V VI VII VIII IX X'I' 'III' to roman 'XIX' © 1 3 .. 19I III V VII IX XI XIII XV XVII XIX'II' 'III' 'IV' {¸½¼¾}roman 'XXIV'I II III IVV VI VII VIIIIX X XI XII© Cvbvs nvmerorvm.492


XIII XIV XV XVIXVII XVIII XIX XXXXI XXII XXIII XXIV'I'('II' 'III') +roman ('IV' 'V')'VI'V VI VIII IX© Congeries nidificatvr.XIV€roman 'IIIIIIIIIIIIII'© Per norma.€roman'IVXCM'DCCCLXXXIV© (dicere denvo)°.×þ°{¼¾}roman 'X'© Mensa mvltiplicandorvm.I II III IV V VI VII VIII IX XII IV VI VIII X XII XIV XVI XVIII XXIII VI IX XII XV XVIII XXI XXIV XXVII XXXIV VIII XII XVI XX XXIV XXVIII XXXII XXXVI XLV X XV XX XXV XXX XXXV XL XLV LVI XII XVIII XXIV XXX XXXVI XLII XLVIII LIV LXVII XIV XXI XXVIII XXXV XLII XLIX LVI LXIII LXXVIII XVI XXIV XXXII XL XLVIII LVI LXIV LXXII LXXXIX XVIII XXVII XXXVI XLV LIV LXIII LXXII LXXXI XCX XX XXX XL L LX LXX LXXX XC C{1999 2000 2001}roman'' © Anni certi.MCMXCIX MM MMIQuod vide: mayanhttp://pascal.sources.ru/string/romarab.htm (Dmitriy Krylov).eval.dws/notes.romanÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎsudokusvec „ {shape„«½(½¾)*÷2} ##.sudoku prob © Solution vector for Sudoku problem ¾.The Sudoku puzzle consists of a 3×3 grid of 3×3 boxes, each cell of which iseither empty or contains a number in the range 1 to 9. A typical problem mightlook like this:ÚÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÌÛ· · 1Û6 9 ·Û5 · ·ÛÛ4 · ·Û2 7 ·Û· · 1ÛÛ· 7 ·Û· · ·Û· 9 ·ÛÃÎÎÎÎÎÏÎÎÎÎÎÏÎÎÎÎÎÝÛ· · ·Û· · ·Û· 3 ·ÛÛ· · ·Û4 3 ·Û· · 7ÛÛ· · ·Û7 8 ·Û6 · ·ÛÃÎÎÎÎÎÏÎÎÎÎÎÏÎÎÎÎÎÝÛ· · 6Û· · ·Û8 · ·ÛÛ· 2 ·Û1 4 ·Û· 6 ·ÛÛ· 1 ·Û3 5 ·Û· 4 ·ÛÀÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÙThe challenge is to supply the missing numbers in such a way that:each 3×3 box andeach 9-item row andeach 9-item columncontains each of the 9 numbers with no repeats.493


A solution to the above problem might be:ÚÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÌÛ3 8 1Û6 9 4Û5 7 2ÛÛ4 6 9Û2 7 5Û3 8 1ÛÛ2 7 5Û8 1 3Û4 9 6ÛÃÎÎÎÎÎÏÎÎÎÎÎÏÎÎÎÎÎÝÛ7 9 4Û5 6 2Û1 3 8ÛÛ6 5 8Û4 3 1Û9 2 7ÛÛ1 3 2Û7 8 9Û6 5 4ÛÃÎÎÎÎÎÏÎÎÎÎÎÏÎÎÎÎÎÝÛ5 4 6Û9 2 7Û8 1 3ÛÛ9 2 3Û1 4 8Û7 6 5ÛÛ8 1 7Û3 5 6Û2 4 9ÛÀÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÙThe puzzle may be generalised to accept problems of shape other than 3×3×3×3,see examples below.Argument matrix [prob] contains numbers 1-9 in occupied cells and 0s otherwise.Optional left argument [shape] specifies the box shape for non-square problems.The result is a vector of all solution matrices.Technical notes:This solution was supplied by Veli-Matti Jantunen, who says:¸ may be used to denote the sudoku rectangle, the default is 2/(†½¾)*0.5 (eg. if"mat" is a 6x6 matrix and the sub area is 2 3, the call must be 2 3 sudoku mat).The result is a vector of all the solutions found, or « (no solutions) or ''(error - should not happen, but if there are zillions of results)The algorithm is simple:handle the matrix as a vectorthe rows, columns and sudoku areas are denoted by index vectorsdo the basic checking for the puzzle (i.e. polish) and with the main functioncheck one alternative from the list at time:filter all the possible elements for all the cellsif at least one cell is empty = no solution -> take the next from the listif one cell contains more than one number -> select the cell from thetightest group and add every combination (from this cell) to the listif all cells contain one number = solution -> take the next from the list.Veli-Matti also provides this new-from-old problem shuffler:Shuffle„{©| Shuffle the original sudoku table to another one ;)©| ¸: sudoku box (use for e.g. 6x6 tables, like 2 3 Shuffle table).}¸„(½¾)*0.5 ª (ŒIO ŒML ŒRL)„1 3(ŒTS+.*2)(¯1+?3½2){(²ÿ(†¸))(³ÿ(†1²¸))(´ÿ(†²¸))¾}¾{(0,(†½¸)?†½¸)[¾¦¸+1]}(†½¾){¹{¾[494


David Crossley supplies an alternative coding:·sudoku„{ŒIO ŒML„0 1© Sudoku - ¾: N×N setup where box size N*÷2 is integral© The setup is a valid arrangement in some cells of numbers from 1-N; th© Each row, column and the N boxes of each result must contain all numbevalid„{© Validate. ¾ be...(2¬½½¾)Ÿ(¬/2†½¾)Ÿ0¬1|(œ½¾)*÷2:1 © a square matrix with an integr((½¾)½0)»œ1†0½›¾:1© numeric N×N matrix1¹~¾¹¼1+œ½¾:1© numbers 0-N only0=+/,¾© at least one number}box„{¾š(¾×¼¾)°.+¾/¼¾}© Box template ¾:sq root of sizechk„{1¹1œ¸:¾© no cellp„¾ ª p[;œ¸]„¸[1]=¼œ½¾ ª p© item ¸ in to 1, rest of cell t}next„{© Cell-value pairs for possible¾{¾,¨iv ¸[;¾]© in the cell with the minimum n}{1¼þ¸\{¾=˜/¾}¸/¾}/{(¾>1)¾}+š¾ © possibilities (2 or more)}rules„{© Apply logic tests to resolve c~0¹œz„sole ¾:z© detect single-value possibilit~0¹œz„†singles/(¼œ½RCB),›z:z © single-valued cells in row/col~0¹œz„†uniques/(¼(½œz)*÷2),›z:z © values unique to one row/col o~0¹œz„†NinN/4 3 2,›z:z© detect N vals in N cells~0¹œz„†matches/4 3 2,›z:z© matches of N vals in N cells oz­¾:¾© finish if no state change’ z © otherwise repeat rules}sole„{© Resolve sole value cells. ¸:so~0¹œr p„¾:¾© pass through0¹n„+šp:« «© no go(½r)=i„1¼þn×r=0:¾© no remaining single value cellr[i]„1+p[;i]¼1© set result valuep[¯1+iœr;i~þiv iœMasks]„0© remove as possible value in re’ r p © check for further single-value}singles„{© Fix box cells that resolve to~0¹œr p„¾:¾© pass throughi„RCB[¸;]© cells in row, col or boxb„i/p© possibles for cells~1¹l„(1=+/b)^~(1+¼œ½p)¹i/r:¾ © values that occur just once exc„(iv i)[(‡lšb)¼¨1]© cells where they occurp[;c]„(¼œ½p)°.=iv l© modify to just the single valusole r p© resolve the sole values}uniques„{© Unique to one row/col of the ¸~0¹œr p„¾:¾© pass throughb„p[;¸œBox]© box cell valuesi„(½i)‚iv,(i>1)^i=³(²½i)½+/i„+/b © 2 or more unique to a rowj„(½j)‚iv,(j>1)^j=³(²½j)½+/j„+/[1]b © 2 or more unique to a column(0¹½i)^0¹½j:¾© none found495


··s„œ²½b © box sizep[(s(¸ rinds)‡i),s(¸ cinds)‡j]„0 © remove vals from cols of othersole r p© resolve sole values}rinds„{© uniques: row pick inds to upda0=½œ¾:0½›0 0†,/(0œ¾),¨¨((¸*2)×(1œ¾)+¨¸×˜¸¸÷¸)+›(¼¸*2)~(¸×¸|¸¸)+¼¸}cinds„{© uniques: column pick inds to u0=½œ¾:0½›0 0†,/(0œ¾),¨¨((1œ¾)+¨¸×¸|¸¸)+›(¸*2)×(¼¸*2)~(¸×˜¸¸÷¸)+¼¸}matches„{© Resolve exact matches on ¸ pos~0¹œr p„¾:¾© pass through0¹n„+šp:« «© no go if no possibilities fori„(n=¸){iv ¸\un 2ƒ¸/¾}p© cells with ¸ possible valuessole†(¸ match)/i,›¾© resolve each ¸-set then sole v}match„{© Resolve exact matches in row/c~0¹œr p„¾:¾© pass through¸¸¬+/p[;¸]:¾© cell no longer has ¸¸ values¸¸>+/l„p[;¸]^.=p:¾© occurrences of matches with th1¹¸¸¸¸ matches in any ro~1¹n=¸¸:¾© no r/c/b•s with exactly ¸¸ matp„†(l do_matches)/(iv n=¸¸),›p © remove matched vals from relatsole r p© resolve singles then sole valu}do_matches„{© Remove vals from other row/colp„¾© ¸¸ marks all occurrences of map[iv p[;¸¸¼1];iv RCB[¸;]^~¸¸]„0 © filter occurrences in the ¸•thp}NinN„{© Reduce ¸-sets in exactly ¸ cel~0¹œr p„¾:¾© pass throughs„¸ sets(½r)*÷2© all combns of sets of ¸ valuesl„r=0© non-singular cellsn„(¸=(sŸ.^p)+.^³RCB)^¸=(sŸ.^l\l/p)+.^³RCB © set-RCB combinations witi„‡[0](½n)‚iv,n© indices of set-RCB combnssole†(s do_NinN)/i,›¾© reduce non-set values from cel}do_NinN„{© Remove values not in set œ¸ fri„¸¸[0œ¸;] ª j„RCB[1œ¸;]© set values / row-col-box maskr p„¾ ª p[iv~i;iv j^iŸ.^p]„0 ª r p © [vals not in set;cells in set}setup„{© Setup LM possibilities per celp„(›1+¼œ½¾)~¨Masks/¨›,¾© possibles per cell, except...((0¬,¾)/p)„0~þ,¾© adjust given cells to single v(1+¼œ½¾)°.¹p© convert to LM vals×cells}res„(½¾)°{¸°½¨((½¾)½(×/¸)†1)›¾}© Shape result(s)valid ¾:'Invalid setup'© ValidateRCB„{,¨(¾/¼¾)(¾ ¾½¼¾)(box ¾*÷2)}œ½¾ © Rows-Columns-BoxesMasks„‡†Ÿ/{¾°.=¾}¨RCB© Sets per cell of related row/cRCB„†®/(›¼œ½¾)°.=¨RCB© Selection vectors for rows,colBox„((½¾)*÷2)°½¨(‡RCB[(2ל½¾)+¼œ½¾;])/¨›¼×/½¾ © Box indices1¹chk¨Masks/¨›,¾:'Invalid setup' © Duplicates in row/column/boxres¹¯1 0 search(,¾)(setup ¾)©: ADC 5Jun2005}Finally, here is Arthur Whitney's amazing solution in K 5:496x(,/{@[x;y;]'(!10)•x*|/p[;y]=p,:,3/:-3!p:!9 9}')/&~*x


Translated by Phil Last into a D-function:sudoku„{Œio„0 © Whitney/Lastp„{(†¾)°{(¸Ÿ.=¾)/¼n×n}¨,¾},(n*÷2){¾,¸ƒ˜¾÷¸}¨¼n n„½¾m„{(›¾)—(›¸=¼½¾)×(1+¼n)~¾[¸œp]}(½¾)°½¨œ{œ,/¸ m¨¾}/{((¾=0)/¼½¾),››¾},¾}Morten Kromberg's recasting defines some of K's constructs explicitly and so iscloser to the original. Note that, like the K version, it takes and returns 81-vectors, rather than matrices.sudoku„{© Define one k fn and one op missing from <strong>APL</strong>wh„{(¾¬0)/¼½¾}© k '&' functionmg„{a„¸ ª a[¸¸]„¾ ª a} © merge operator: r„old (indexes mg) new}rcq„(†,¼9 9),3/,3š3 3½¼9 © Row, Column, Quadrantp„{wh rcqŸ.=¾}¨‡rcq © Cells in same row, col or quadrantnzd„1+¼9© Non-zero digits for a little more speedœ{œ,/¸{¾°(¸ mg)¨nzd~¾[¸œp]}¨¾}/(wh ¾=0),››¾ © kapow!Roger Hui presents this in the following more beautiful form, generalised fornon-square puzzles:Sudoku„{¸„(½¾)*÷2 © Solutions of shape-¸ Sudoku puzzle ¾.svec „ {œpvex/(emt ¾),››¾} © solution vectorpvex „ {œ,/¸°pvec¨¾}© vector of placementspvec „ {(¸ avl ¾)(¸ at)¨›¾} © placementsavl „ {(¼œ½¾)~¾×œ¸¦CMAP} © list of available numbersat „ {¾+¸×(¼½¾)¹›¸¸} © ¸ at cell ¸¸ in ¾emt „ {(,¾=0)/,¼½¾}© row & column indices of empty cellsrcb „ {(¼½¾),¨¸ box(½¾)÷¸} © row/column/box numbersbox „ {(œ¸)š(œ²¸)/¾½¼×/¾} © box numbers for a puzzle of size ¾*2cmap „ {›[¼2]1¹¨¾°.=¾}© contention map for puzzle ¾CMAP „ cmap ¸ rcb ¾© contention map for puzzle}svec ¾© vector of solutions.See …sudoku_bfs„ for an illustration of this algorithm.See "Learn" in: http://www.Try<strong>APL</strong>.org for step-by-step demonstration.Watch: http://www.youtube.com/watch?v=DmT80OseAGs to see it in action.Thanks also to Maurice Jordan and John R. Clark for suggestions.Examples:s330 0 1 6 9 0 5 0 04 0 0 2 7 0 0 0 10 7 0 0 0 0 0 9 00 0 0 0 0 0 0 3 00 0 0 4 3 0 0 0 70 0 0 7 8 0 6 0 00 0 6 0 0 0 8 0 00 2 0 1 4 0 0 6 00 1 0 3 5 0 0 4 0© sample 3×3 problem.497


disp sudoku s33 © ... has 3 solutions.Ú…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ3 8 1 6 9 4 5 7 2Û2 8 1 6 9 3 5 7 4Û2 8 1 6 9 3 5 7 4ÛÛ4 6 9 2 7 5 3 8 1Û4 6 9 2 7 5 3 8 1Û4 6 9 2 7 5 3 8 1ÛÛ2 7 5 8 1 3 4 9 6Û3 7 5 8 1 4 2 9 6Û5 7 3 8 1 4 2 9 6ÛÛ7 9 4 5 6 2 1 3 8Û7 9 2 5 6 1 4 3 8Û7 9 2 5 6 1 4 3 8ÛÛ6 5 8 4 3 1 9 2 7Û6 5 8 4 3 9 1 2 7Û6 5 8 4 3 9 1 2 7ÛÛ1 3 2 7 8 9 6 5 4Û1 3 4 7 8 2 6 5 9Û1 3 4 7 8 2 6 5 9ÛÛ5 4 6 9 2 7 8 1 3Û5 4 6 9 2 7 8 1 3Û3 4 6 9 2 7 8 1 5ÛÛ9 2 3 1 4 8 7 6 5Û9 2 3 1 4 8 7 6 5Û9 2 5 1 4 8 7 6 3ÛÛ8 1 7 3 5 6 2 4 9‡8 1 7 3 5 6 9 4 2‡8 1 7 3 5 6 9 4 2‡À~ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…Á~ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…Á~ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…Ù© This function separates inner boxes for easier reading:sbox„{ŒIO ŒML„0 1© Box sudoku grids.¸„(½¾)*÷2© default square cells.vp hp„0=¸|¼¨½¾© vert and horiz partition vectors.numbs„³†vp°(›[0])¨hp›¾© numeric sub-areas.width„2+˜10µ—/1,,¾© digits per number.fmt„width°{¾=0:²¸†'·' ª ¸ 0•¾} © dots for zeros.cells„0 1°‡¨†°(,/)¨fmt¨¨numbs © char matrix sub-areas.hv„¸½¨›¨²(½œcells)/¨'ÛÎ'© vert and horiz boundaries.in„{†¸{¸,¸¸,¾}/¾} © ¸ separates ¾.(t m b)lr„'ÂÏÁ' 'ÃÝ'in¨°›¨hv © bordering lines.body„m in³¨›[1 2]'Û'in cells © collected cells.(³body in t b)in lr in¨'ÚÀ' 'ÌÙ' © boxed grid.}sbox¨ sudoku s33© formatted solutionsÚÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÌ ÚÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÌ ÚÎÎÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÌÛ3 8 1Û6 9 4Û5 7 2Û Û2 8 1Û6 9 3Û5 7 4Û Û2 8 1Û6 9 3Û5 7 4ÛÛ4 6 9Û2 7 5Û3 8 1Û Û4 6 9Û2 7 5Û3 8 1Û Û4 6 9Û2 7 5Û3 8 1ÛÛ2 7 5Û8 1 3Û4 9 6Û Û3 7 5Û8 1 4Û2 9 6Û Û5 7 3Û8 1 4Û2 9 6ÛÃÎÎÎÎÎÏÎÎÎÎÎÏÎÎÎÎÎÝ ÃÎÎÎÎÎÏÎÎÎÎÎÏÎÎÎÎÎÝ ÃÎÎÎÎÎÏÎÎÎÎÎÏÎÎÎÎÎÝÛ7 9 4Û5 6 2Û1 3 8Û Û7 9 2Û5 6 1Û4 3 8Û Û7 9 2Û5 6 1Û4 3 8ÛÛ6 5 8Û4 3 1Û9 2 7Û Û6 5 8Û4 3 9Û1 2 7Û Û6 5 8Û4 3 9Û1 2 7ÛÛ1 3 2Û7 8 9Û6 5 4Û Û1 3 4Û7 8 2Û6 5 9Û Û1 3 4Û7 8 2Û6 5 9ÛÃÎÎÎÎÎÏÎÎÎÎÎÏÎÎÎÎÎÝ ÃÎÎÎÎÎÏÎÎÎÎÎÏÎÎÎÎÎÝ ÃÎÎÎÎÎÏÎÎÎÎÎÏÎÎÎÎÎÝÛ5 4 6Û9 2 7Û8 1 3Û Û5 4 6Û9 2 7Û8 1 3Û Û3 4 6Û9 2 7Û8 1 5ÛÛ9 2 3Û1 4 8Û7 6 5Û Û9 2 3Û1 4 8Û7 6 5Û Û9 2 5Û1 4 8Û7 6 3ÛÛ8 1 7Û3 5 6Û2 4 9Û Û8 1 7Û3 5 6Û9 4 2Û Û8 1 7Û3 5 6Û9 4 2ÛÀÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÙ ÀÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÙ ÀÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÙs220 2 3 43 0 0 02 0 0 04 0 0 0sbox¨ sudoku s22ÚÎÎÎÂÎÎÎÌ ÚÎÎÎÂÎÎÎÌ ÚÎÎÎÂÎÎÎÌÛ1 2Û3 4Û Û1 2Û3 4Û Û1 2Û3 4ÛÛ3 4Û2 1Û Û3 4Û1 2Û Û3 4Û1 2ÛÃÎÎÎÏÎÎÎÝ ÃÎÎÎÏÎÎÎÝ ÃÎÎÎÏÎÎÎÝÛ2 1Û4 3Û Û2 1Û4 3Û Û2 3Û4 1ÛÛ4 3Û1 2Û Û4 3Û2 1Û Û4 1Û2 3ÛÀÎÎÎÁÎÎÎÙ ÀÎÎÎÁÎÎÎÙ ÀÎÎÎÁÎÎÎÙ© sample 2×2 problem.© ... has 3 solutions.498


3 4 sbox s34 © sample 3×4 problem.ÚÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÌÛ 9 6 · ·Û10 · · 8Û 2 · · 4ÛÛ · 1 · 11Û · 12 · ·Û · · 3 5ÛÛ · · · ·Û 6 · 7 11Û12 · · ·ÛÃÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÝÛ · · 10 7Û · · · ·Û 4 · 9 ·ÛÛ 1 · 6 ·Û12 11 · 4Û · 3 · ·ÛÛ · · 9 ·Û · 10 8 1Û · · 6 ·ÛÃÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÝÛ · 7 · ·Û11 2 1 ·Û · 12 · ·ÛÛ 2 · 12 ·Û 4 · 6 5Û · 1 · 11ÛÛ · 10 · 5Û · · · ·Û 3 4 · ·ÛÃÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÝÛ · · · 10Û 5 8 · 7Û · · · ·ÛÛ 5 3 · ·Û · · 11 ·Û 9 · · ·ÛÛ 7 · · ·Û 3 · · 6Û · · 4 2ÛÀÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÙ3 4°sbox¨ 3 4 sudoku s34 © ... has 2 solutions.ÚÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÌ ÚÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÌÛ 9 6 5 12Û10 1 3 8Û 2 7 11 4Û Û 9 6 5 12Û10 1 3 8Û 2 7 11 4ÛÛ 8 1 7 11Û 9 12 4 2Û 6 10 3 5Û Û 8 1 7 11Û 9 12 4 2Û 6 10 3 5ÛÛ10 4 2 3Û 6 5 7 11Û12 9 1 8Û Û10 4 2 3Û 6 5 7 11Û12 9 1 8ÛÃÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÝ ÃÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÝÛ12 11 10 7Û 2 6 5 3Û 4 8 9 1Û Û12 11 10 7Û 2 6 5 3Û 4 8 9 1ÛÛ 1 2 6 8Û12 11 9 4Û 7 3 5 10Û Û 1 2 6 8Û12 11 9 4Û10 3 5 7ÛÛ 3 5 9 4Û 7 10 8 1Û11 2 6 12Û Û 3 5 9 4Û 7 10 8 1Û11 2 6 12ÛÃÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÝ ÃÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÝÛ 4 7 3 6Û11 2 1 10Û 5 12 8 9Û Û 4 7 3 6Û11 2 1 10Û 5 12 8 9ÛÛ 2 8 12 9Û 4 3 6 5Û10 1 7 11Û Û 2 8 12 9Û 4 3 6 5Û 7 1 10 11ÛÛ11 10 1 5Û 8 7 12 9Û 3 4 2 6Û Û11 10 1 5Û 8 7 12 9Û 3 4 2 6ÛÃÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÝ ÃÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÝÛ 6 9 4 10Û 5 8 2 7Û 1 11 12 3Û Û 6 9 4 10Û 5 8 2 7Û 1 11 12 3ÛÛ 5 3 8 2Û 1 4 11 12Û 9 6 10 7Û Û 5 3 8 2Û 1 4 11 12Û 9 6 7 10ÛÛ 7 12 11 1Û 3 9 10 6Û 8 5 4 2Û Û 7 12 11 1Û 3 9 10 6Û 8 5 4 2ÛÀÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÙ ÀÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÙSee also: queens.481 sudoku_bfs.584 X.160 sudokuX.587See also: http://www.ams.org/notices/200904/rtx090400460p.pdfSee also: http://www.Try<strong>APL</strong>.orgSee also: http://www.youtube.com/watch?v=DmT80OseAGsÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎcfrslt „ {larg} (land ##.cf rand) rarg © Ratio of operand timings.(cf. compare, abbrv. confer(arch.) [Lat: conferre:com-:together + ferre:bring])Phil Last supplies this operator, which reports the ratio of the times taken toapply its left and right operand <strong>functions</strong> to (or between) its argument(s).¸ f ’’ g ¾ „… (¸ f time ¾) ÷ ¸ g time ¾f ’’ g ¾ „… ( f time ¾) ÷ g time ¾Technical notes:Phil points out that we could do some interesting code transformations:cf„{¸„€© Compare operand timings.a„¸ ª f„¸¸ ª g„¾¾ ª w„¾ ª t„{«½2‡ŒAI-(¸¸/¼1+¾)€ŒAI}÷/1{œ’/¸{(1000


Spreading the code over a number of lines, we see:cf„{¸„€© Compare operand timings.a„¸© naming of ¸f„¸¸ © ¸¸g„¾¾ © ¾¾w„¾ © ¾t„{© ¸¸-timing operator«½2‡ŒAI-(¸¸/¼1+¾)€ŒAI © time ¸¸ ¸¸ .. ¸¸ applications. [1]} © ÀÎÎÎξÎÎÎÎÙ÷/1{ © ratio of (initially 1) applications.œ’/¸{© repetition while 2-item vector from:(1000


12'do' gg 'zen')This is explored further in the experimental "Function Results Edition" of<strong>Dyalog</strong>, See: http://dfns.dyalog.com/downloads/fre.pdfIncorporating this technique into our cf operator yields:cf„{¸„€© Compare operand timings.ff„€°(¸°¸¸)°¾ © naming of {¸ ¸¸ ¾}gg„€°(¸°¾¾)°¾ © {¸ ¾¾ ¾}t„{© ¸¸-timing operator«½2‡ŒAI-(€°¸¸/¼1+¾)€ŒAI © time ¸¸ ¸¸ .. ¸¸ applications. [1]} © ÀÎÎÎξÎÎÎÎÙ÷/1{ © ratio of (initially 1) applications.œ’/¸{© repetition while 2-item vector from:(1000


ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎcmpxtable „ {opts„«} ##.cmpx exprs© Approx expression timings.Exprs is a vector of character vectors, each representing a result-returning <strong>APL</strong>expression. Each expression is compiled into a loop, and its evaluation timedfor 1, 2, 4, 8, 16, ··· iterations. The iteration count is doubled until themean time to execute is more than [secs]. Finally, an empty loop is compiled andits execution time for the final number of iterations subtracted to give nettexecution time in seconds for each expression.Optional left argument [opts] specifies a vector of 0-4 items. Defaults are assumedif fewer than 4 items are supplied. The options are:raw: 0:graphical display as below; 1:raw numeric vector of times in seconds.cpu: 0:elapsed ŒAI[3] time; 1:cpu ŒAI[2] time.cols: Maximum column-width for histogram. 0 implies the default width of 40.secs: Test period in seconds; default 1.By default, [cmpx] returns a character matrix representing a 5-column table:cmpx'ŒioœŒa' 'Œa[Œio]' '«½Œa' '1†Œa'© CoMPare eXpressions.ŒioœŒa … 1.1E¯6 | 0% ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒa[Œio] … 1.7E¯6 | +51% ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ«½Œa … 1.0E¯6 | -8% ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ* 1†Œa … 1.3E¯6 | +16% ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒÛ Û Û Û ÛÛ Û Û Û ÀÎ Histogram for at-a-glance comparison.Û Û Û ÀÎÎÎÎÎ Percentage difference relative to first expression.Û ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ Approx time in seconds for a single iteration.Û ÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ Subject expression.ÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ Warning for results not identical to the first one.(The first three expressions return a scalar resultand the fourth, a 1-item vector).Given a _single_ expression, [cmpx] returns only the number of seconds taken toexecute it:cmpx'ŒioœŒa'1.3E¯6© Time single expression.Technical notes:Notice in the coding of this function, that name conflicts are avoided by havingthe subject expression timings execute lexically _outside_ the main operator.Further, the small amount of code visible at execution (–) time has been carefullychosen to be both ŒIO and ŒML independent:cmpx„{···1{(–¾)-ŒAI}{ŒIO ŒML„0times„¸ ¸¸{© Execute expression outside© main operator so that no system variable© or name conflicts occur.Differences in the expression results are detected by a final re-execution ofeach expression in the _right_ operand of the main operator, which is again outsidethe main operator body and so ŒIO and ŒML independent.···diff„{¾œ' *'}¨×{¾¼¾},¾¾¨¾ © result differences.···}{ © right operand:–¾ © execute expr in its native envt.}¾ © vector of subject expressions.502


Examples:cmpx'100½2' '100/2'© / is slower (though easier to spell.100½2 … 9.5E¯7 | 0% ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ100/2 … 2.6E¯6 | +175% ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒcmpx'œ ›«' '† ›«'© first quicker than mix for disclose.œ ›« … 4.2E¯7 | 0% ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ† ›« … 1.1E¯6 | +153% ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ© Stranding (« « ... «) appears to be an O(n*2) operation:cmpx 11/'«' © 10 strandings.6.4E¯6cmpx 101/'«' © 100 strandings.1.9E¯4cmpx 1001/'«'1.5E¯2cmpx 10001/'«'1.5E0© 1000 strandings.© 10000 strandings1 cmpx'ŒioœŒa' 'Œa[Œio]' '«½Œa' '1†Œa' © option: raw exprssion times.4.472732544E¯7 5.502700806E¯7 4.024505615E¯7 5.06401062E¯7(1 0)(1 1) cmpx¨ ›'osc¨¼1e3' © elapsed vs cpu ŒAI times.0.0673125 0.06725See also: time.515 mdf.501 ticks.509 cf.497ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎmdfreport „ {larg} (dfn ##.mdf) rarg© Monitor D function.Mdf applies its operand D function to (or between) its argument(s) then displaysthe function with a count of the number of times each line was executed. Thisoutput is a useful indication of the "hot spots" in the subject function whereit might pay to review the code in order to improve overall performance.NB: From dyalog V13, ŒPROFILE will supply this information directly.Technical notes:The coding of this operator is "nasty" in the sense that there is extensive interferencebetween the operator and its subject D function. In particular, thereis scope for name clashes, which with luck, have been avoided by choosing unlikelynames, and refraining from naming transient values where possible.The operator initialises a count vector "_mdf_c" with zeros corresponding toeach line of the subject function. It then makes a temporary copy "_mdf_f" ofthe subject function, prefacing each line with a segment of code that incrementsthe count for this line:_mdf_c[Œio+«½Œlc]+„1 ªFurther nastiness occurs in order to determine the name of the subject function.The approach taken is to compare all but the header source line of the temporaryfunction with those of all <strong>functions</strong> in the current namespace.From <strong>Dyalog</strong> V13, this operator can be coded in a more pleasant way:503


Bugs:mdf„{ © Line hits for function ¸¸.name„¸¸¨{ff„¸¸ ª (•ŒOR'ff')~'’ ¨'}« © deduce name of operand fn._„ŒPROFILE¨'reset' 'on'© initialise profilng.¸„€ ª _„¸ ¸¸ ¾© apply function.data _„ŒPROFILE¨('data'name)'reset' © profiling data for ¸¸.lines count„1‡¨1‡3†‡³data© lines visited and hit-count.code„ŒCR name© source code for ¸¸.v„0•¨‡code© initial hits vector.v[lines+ŒIO]„count© insert hits.v,code© hits followed by source.}[1] An inner D-fn that has executable code on its first (or only) line:inner„{¸„0or:free„{¾~¨¸+(½¾)†cvex}reports a count corresponding to the definition rather than the execution ofthe first line. In order to examine such cases in more detail, split themover several lines. For example in queens below, splitting the definition ofinner function "free" over two lines, shows it defined once but called 862times:1 free„{862 ¾~¨¸+(½¾)†cvex} © Unchecked squares.[2] A subject operand function that happened to contain either of the names"_mdf_c" or "_mdf_f" would produce unpredictable results.[3] The subject operand function may not be more exotic than a named simple D-fn. In particular, it may not be:Examples:a derived function as in:foo¨mdf 0foo°goo mdf 0foo mdf mdf 0an unnamed function such as:{¾ ¾}mdf 0© Monitored application of various <strong>functions</strong>:osc mdf 270 osc„{ © Oscillate - probably returns 1.112 1=¾:1111 2|¾:’ 1+3×¾70 ’ ¾÷20 }105 gcd mdf 3300 gcd„{ © Greatest common divisor.4 ¾=0:¸3 ¾ ’ ¾|¸0 }504


sieve mdf 2 to 1000 sieve„{ © Sieve of Eratosthenes.5 ¸„« © Default no primes yet.5 nxt„1†¾ © Next prime, and5 msk„×nxt|¾ © ... mask of non-multiples.5 ^/1‡msk:¸,¾ © All non multiples - finished.4 (¸,nxt)’ msk/¾ © Sieve remainder.0 }queens mdf 80 queens„{ŒML ŒIO„0 © The N-queens problem.11 search„{ © Search for all solutions.863 (›«)¹¾:0½›« © stitched: abandon this branch.583 0=½¾:rmdups ¸ © all done: solution!537 hd tl„(œ¾)(1‡¾) © head 'n tail of remaining ranks.537 next„¸°,¨hd © possible next steps.537 rems„hd free¨›tl © unchecked squares.537 †,/next ’¨rems © ... in following ranks.0 }11 cvex„(1+¼¾)×›¯1 0 1 © Checking vectors.11 free„{¾~¨¸+(½¾)†cvex} © Unchecked squares.11 rmdups„{ © Ignore duplicate solution.46 rots„{{”¾}\4/›¾} © 4 rotations.46 refs„{{“¾}\2/›¾} © 2 reflections.46 best„{(œ“†¾)œ¾} © best (=lowest) solution.46 all8„,†refs¨rots ¾ © all 8 orientations.46 (¾­best all8)œ«(,›¾) © ignore if not best.0 }11 fmt„{ © Format solution.1 chars„'·µ'[(†¾)°.=¼¸] © char array of placed queens.1 expd„1‡,†¸½›0 1 © expansion mask.1 †¨‡‡expd\chars © vector of char matrices.0 }11 squares„(›¼—¾÷2),1‡¾½›¼¾ © initial squares11 ¾ fmt « search squares © all distinct solutions.0 }3 ack mdf 3 © Ackermann's function.0 ack„{2432 ¸=0:¾+11244 ¾=0:(¸-1)’ 11187 (¸-1)’ ¸ ’ ¾-10 }See also: ticks.509 cmpx.500 time.515ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎmemorslt „ {larg} (¸¸ ##.memo cache) rarg © Function memoization.sref „ ##.cache ivec© Ref to space with initial cache.[memo] binds an ambi-valent function left operand with a cache right operand toproduce a derived function. On application to arguments, the derived functionretrieves previously-calculated values from the cache, which it extends whennecessary with newly-calculated ones.fast_fn „ slow_fn memo cache© bind slow_fn with cache to produce fast_fn.505


[cache] is a reference to a namespace containing two vectors [keys] and [vals],whose items are previously encountered arguments together with their correspondingresults. The cache is initialised using the auxiliary function [cache]which pre-populates it with any number of expected result-argument pairs.The technique, proposed by Donald Michie in 1968 ["Memo" <strong>functions</strong> and machinelearning, Nature, 218, 19-22], was published as an <strong>APL</strong>2 operator by AndréasGeyer-Schultz. This more self-contained version was suggested by Stefano Lanzavecchiaand Phil Last.As with any caching system, care must be taken to remove from the cache, itemsthat become "stale" when the cached result no longer reflects external reality.An example might be a cached file read when the "real" file component is subsequentlyupdated.Access to the cache for maintenance purposes (a kind of inspection hatch), canbe achieved by retaining an explicit reference to its namespace.‘foo „ cache''qfoo „ foo memo ‘foorslt „ qfoo args ···‘foo.(···)© initialise cache for slow function foo.© derive "quick" version of foo.© using qfoo extends its cache.© maintain cache using space-reference.Expunging the explicit reference leaves the cache intact within the derivedfunction but effectively seals off external access to it. Access can be recoveredby stopping inside memo, tabbing to the session and assigning a newexternal reference.Œex'‘foo'rslt „ qfoo args ···qfoo arg [Ctrl-Enter][Ctrl-Tab]‘foo„¾¾© expunge handle to foo's cache.© qfoo continues to function normally.© trace into derived function,© ... tab to session and© ... take new external ref.Related ancillary <strong>functions</strong> [show] and [zap], included in the examples below,may be of some use but are considered "hors d'oeuvre" and so not fixed in theworkspace.Technical notes:When called, the derived function: (slow_fn memo cache) examines its cache forthe supplied argument(s) and if found, returns the corresponding result. Otherwise,it returns a freshly-calculated result, updating the cache en passant.memo„{© Function memoization.¸„€© ambi-valent.(›¸ ¾ ¾)¹¾¾.keys:¾¾.((keys¼›¸ ¾ ¾)œvals) © arg(s) known: fetch result.ŒIOœ¾¾.(vals keys),°›„(¸ ¸¸ ¾)(¸ ¾ ¾) © else: calc & extend cache.}Notice that the "look-up key" is (¸ ¾ ¾). This is so that a monadic call withsay, a 2-item right argument is distinct from a dyadic call with 1-item left andright argument:call key---- ---monadic: ’ 3 4 (3 4)(3 4)’ 2 2 2dyadic: 3 ’ 4 3 4 42 ’ 2 2 2 2506


Auxiliary function [cache] returns a reference to an unnamed space containingtwo vectors "vals" and "keys". The cache is populated by calling the functionwith a vector of 2 or 3 item "tuples" denoting monadic: (rslt rarg) pairs, ordyadic: (rslt larg rarg) triples.cache„{ŒML„0vals keys„‡³†{(œ¾)(1‡¾,¯1†¾)}¨1‡(›0 0),¾ŒNS'vals' 'keys'}© Ref to space containing initialised cache.© result values and keys.© rslt - {larg} rarg rarg.© initial values of cache.© unnamed ref containing cache variables.In the penultimate line above, the phrase 1‡(›0 0),¾ ensures that cache's argumentvector has a viable prototypical item. This means that to create an emptycache we may merely: (cache''), rather than (cache 0½›0 0).To initialise the cache with values for:÷ 1 2 © monadic ÷1 0.51 ÷ 2 © dyadic ÷0.5We would call cache thus:cache ((1 0.5)(1 2)) (0.5 1 2)ÛÛÛÀÎÎÎÎÎÎ triple => rslt larg rarg (dyadic case)ÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ pair => rslt rarg (monadic case)Persistent Local Variables--------------------------The technique of binding a space reference to a function may be used in generalto implement persistent local variables. That is, variables that are local to afunction but whose values are retained between calls. The following functioncan be used to generate a stream of integers on successive calls:123 451 2 3next„(Œns'')°{0=¾:¸.n„0(¼¸.n+„¾)+¸.n}next 0next 1next 1next 2next 1next 0next 3© space bound as left arg.© next 0: reset number stream.© next ¾: return next ¾ numbers.© reset count.© next number.© next number.© next two numbers.© next number.© reset count.© next three numbers,As Ray Cannon observes, the technique may even be used to _share_ persistentdata among several <strong>functions</strong> with no additional workspace footprint; participating<strong>functions</strong> enjoy a strictly private communication. In the following example,[brak], [join], [bkts] and [sepr] share the same space to access communal localvariables: [lft], [rgt] and [sep].507


Ú’brakÎÌ Ú’bktsÎÌÛ Û ÚÎÎÎÎÎÎÎÎÎÌ Û ÛÛ Ã΄ÎÏÎÌ ÚÎÏ΄ÎÝ ÛÀÎÎÎÎÎÎÙ Û ÃÎlftÎÝ Û ÀÎÎÎÎÎÎÙÛ ÀÎrgtÎÙ ÛÚ’joinÎÌ Û ÚÎsepÎÌ Û Ú’seprÎÌÛ Ã΄ÎÏÎÙ ÀÎÏ΄ÎÝ ÛÛ Û ÀÎÎÎÎÎÎÎÎÎÙ Û ÛÀÎÎÎÎÎÎÙÀÎÎÎÎÎÎÙ'tmp'Œns''brak„tmp{¸¸.(lft,¾,rgt)}join„tmp{†,°(¸¸.sep°,)/¾}bkts„tmp{¸¸.(lft rgt)„¾}sepr„tmp{¸¸.sep„¾}Œex'tmp'bkts'[]' ª sepr'-'join brak¨'tic' 'tac' 'toe'[tic]-[tac]-[toe]sepr''join brak¨'tic' 'tac' 'toe'[tic][tac][toe]bkts'''' ª sepr', 'join brak¨'tic' 'tac' 'toe''tic', 'tac', 'toe'brak join'tic' 'tac' 'toe''tic, tac, toe'© temporary external reference to space.© function to "bracket" its argument.© function to join items with separators.© function to set bracket characters.© function to set separator string.© remove external reference to space.© set bracket and separator strings.© join bracketed char vectors.© change separator string.© join bracketed char vectors.© change bracket and separator strings.© join bracketed char vectors.© bracket joined char vectors.Caveat: Techniques such as these, should be used with caution, if at all. Theyare included here in the spirit of exploration, rather than as a suggestion thatthey form the basis for any operational software. While interesting in their ownright, they may prove difficult to maintain as the structures will almost certainlybe unfamiliar to the maintenance programmer and impenetrable to workspaceadministration tools such as those for name cross-referencing and documentation.This operator could be coded in a more elegant way if <strong>APL</strong> provided "closures".Closures are explored further in an experimental "Function Results Edition" of<strong>Dyalog</strong>. See: http://dfns.dyalog.com/downloads/fre.pdfExamples:fread„Œfread memo(cache «)fread 1 19···fread 1 19afib„{ŒIO„0¾¹¼¸:¾+/¸ afib¨¾-1+¼¸}© Cached file read.© Read 'n cache file component.© Subsequent reads satisfied from cache.© Naïve coding of ¸-fibonacci number.© small number: done,© otherwise: sum of preceding ¸ fib numbers.2 afib¨¼20 © Fibonacci sequence.1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765508


time„{ © Coarse function timer.¸„€© accept monadic operand.ai„ŒAI© start the clock.rslt„¸ ¸¸ ¾© apply function.secs„•0.001×1†2‡ŒAI-ai © seconds elapsed.†,/•¨rslt': 'secs' Secs' © timed result.}2 afib¨time¼20 © *slow* ¸-fibonacci sequence.1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765: 1.262 Secsafib„afib memo(cache «)© Memoize afib.2 afib¨time¼20 © *fast* ¸-fibonacci sequence.1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765: 0.1 Secs© Notice that afib is coded to use its own name explicitly, rather than '’'© for the recursion. This is so that the recursive call references the newly-© assigned derived function, whereas '’' would have referenced the original© function and circumvented the memoization.© Perhaps surprisingly, the cache can be relied upon to supply the "base values"© of the recursion, thus simplifying the initial function coding.fib„{+/fib¨¾-1 2}fib„fib memo(cache 2/¨0 1)© Naïve coding of regular fibonacci number.© sum of preceding 2 fib numbers.© Cache pre-populated with base values.fib¨time¼20© Fast fibonacci sequence.1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765: 0.1 Secsdiv„÷ memo (cache «)© Ambivalent operand function2 div 7 © Dyadic use distinct from ...0.2857142857div 2 70.5 0.1428571429© ... monadic use.osc„{ © Oscillate - probably returns 1.2|¾:osc 1+3×¾© odd: triple 'n add-one,osc ¾÷2© even: halve.}keysvals1 „ 1‘osc„cache›1 1osc„osc memo ‘osc‘osc.Œnl 2show„{ŒML„0†¾.(vals{¸'„',›¯1‡¾}¨keys)}show ‘osc© Initialise cache for osc.© derive "fast" osc function.© cache-space contents.© Show cache [rslts „ args]© (dropping extra rarg).© Show initial cache.509


11 „ 11 „ 2osc 2 © Apply derived function, extending cache.show ‘osc© Show extended cache.1osc 3© Apply function again.show ‘osc1 „ 11 „ 21 „ 41 „ 81 „ 161 „ 51 „ 101 „ 3© Show extended cache.zap„{ŒML„0 © Remove value ¾ from cache ¸.¸.{© within cache:mask„¾°­¨‡³†vals keys © mask of matches.vals keys/þ„›~mask © retain non-matches.}(œ¾)(1‡¾,¯1†¾)© target value and key.}1 „ 11 „ 21 „ 41 „ 81 „ 51‘osc°zap¨(1 16)(1 10)(1 3)show ‘oscosc 3© Zap selected cache entries.© Show compacted cache.© Re-run function.show ‘osc1 „ 11 „ 21 „ 41 „ 81 „ 51 „ 101 „ 3Œex'‘osc'osc¨¼101 1 1 1 1 1 1 1 1 1© Partially restored cache.© Seal access to osc's cache.© Derived function still operates normally.© And finally ...delay„Œdl memo (cache «)delay time 1010.024: 10.034 Secs© Cached delay.© Delay 10 seconds.delay time 10 © Side-effect-free delay :-)10.024: 0 SecsSee also: UndoRedo.405 fibonacci.279 osc.296510


ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎticks{rslt} „ {larg} (fun ##.ticks) rarg© Sample Dfn execution clock ticks.During code execution, ŒAI's "compute time" clock ticks every so-many milliseconds.Operator [ticks] records which line in its operand [fun]ction is executingas each tick occurs and reports the percentage of ticks that fall on each line.In order to obtain a significant tick-sample, the function is applied repeatedlyto (or between) its argument(s) until the clock has ticked 1,000 times. Repeatedapplication means that any side effects (Œnappend, etc) will also be perpetratedrepeatedly, which may be undesirable.At the end of the time period, the function source is displayed in the sessiontogether with, for each line:- The number of times the line was "visited".- The percentage of clock ticks recorded for the line.Where:ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎ visitsÛ ÚÎÎÎÎÎÎÎÎÎÎÎ percentÛ Û ÚÎÎÎÎÎÎÎÎ sourceÛ Û Û5 14 sieve„{ © Sieve of Eratosthenes.5 15 ¸„« © Default no primes yet.5 14 nxt„1†¾ © Next prime, and5 14 msk„×nxt|¾ © ... mask of non-multiples.5 17 ^/1‡msk:¸,¾ © All non multiples - finished.4 26 (¸,nxt)’ msk/¾ © Sieve remainder.0 0 }- Visits: This is (intended to be) an accurate account of the number visits toeach line. A line containing a local function is deemed to be visited both atdefinition and application time. This behaviour differs from that of operator…mdf„, which reports only the definition count in such cases. See Bugs[6]below.- Percent: Approximate indication of the proportion of clock ticks occuring ineach line. Owing to timing granularity, the column total may not be 100; seebelow.- Source: As much of the subject function's source code as will fit across thescreen.Unlike ŒMONITOR used with traditional <strong>functions</strong>, the time attributed to a line_excludes_ that spent in called sub<strong>functions</strong>. This is a _good_thing_.ŒAI's clock resolution varies: on some systems, the clock ticks every 10 millisecondsand on others, every 16 (or so). In any case, many lines of code may beexecuted between ticks. The best we can do is to run the function for a periodof time and notice on which lines the ticks occur.The following diagram illustrates the problem: each ÏÎÎÎÎÏ represents the realand varying execution time of successive lines of code, and †tick shows the regularclock ticks occuring.ÎÏÎÎÎÏÎÎÏÎÏÎÎÎÎÏÎÎÎÎÏÎÎÎÏÎÏÎÎÏÎÏÎÏÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÏÎÎÎÎÎÏÎÏÎÎÎφ † † †tick tick tick tickTo interpret the result as an indication of relative processing time for eachline, we must suppose that, in general, lines that take longer to execute willsustain proportionally more ticks.511


Bugs:[1] The time taken to execute the monitoring code often vastly exceeds the timetaken to execute the code it is monitoring. This would be OK if the monitortook _exactly_ the same time to execute on each occasion, in which case, wecould calculate and subtract the overhead. However, in <strong>Dyalog</strong> <strong>APL</strong>, the heapmanager may take a different number of cycles to satisfy a request dependingon the state of fragmentation of the heap. This means that attempts toaccount for the execution time overhead of the monitoring code can be onlyapproximate.[2] If the (copy of the) subject function, with its embedded monitoring code,happens to run in a time that is an exact multiple of the system clock'sresolution, all bets are off as ticks would tend to accumulate in the samefew lines.[3] The generated monitoring function (•_f) will fail with a SYNTAX ERROR if anylocal function call does not produce a result. For example:loop„{0


1 ·· dup3„{2 ·· dup„{¾ ¾} ÎÎÎÎ 2 visits: 1 definition +1 ·· dup dup ¾ ÎÎÎÎ 1 (double) call.0 ·· }1 ·· dup4„{1 ·· {¾ ¾}{¾ ¾}¾ ÎÎÎÎ 1 visit to line.0 ·· }1 ·· dup5„{2 ·· { ÎÎÎÎ 2 visits: 1 definition +1 ·· ¾ ¾ ÎÎÎÎ 1 call.1 ·· }{1 ·· ¾ ¾0 ·· }¾0 ·· }1 ·· dup6„{1 ·· {¾ ¾}¨¾ ¾ ÎÎÎÎ 1 visit to line.0 ·· }[7] When the execution path through the subject function is determined by factorsother than its arguments, the first (visits) column of the result maycontain non-integers. This might be the case, for example, if ŒTS or ŒRLwere used within the function, as with:maze ticks 10 20© reports non-integral line visits count.Such a result might be interpreted as an _average_ number of line visits.Technical notes:The coding of [ticks] is fairly ghastly for the same reason as …mdf„. See thetechnical notes in …mdf„ for details.Monitoring is achieved in several stages:- A copy of the subject function is injected with entry (…¾) and exit (¸„) markersat the start of each line and at the entry and exit points of each subfunction.These markers are subsequently replaced with calls to the entry andexit monitoring sequences:•_ ¾: ª ··· © entry sequence.¸ _• ··· © exit sequence,where ¸ and ¾ are replaced with the number of the function line in which thesequence appears. Monitoring function •_ returns 0 (so that its guard is ignored)and _• returns its right argument as the result of the (sub-) function.- A small loop is executed to determine ŒAI's clock resolution and therefore thetime needed to endure 1,000 clock ticks.- The doctored function is executed repeatedly for this time period, duringwhich sampling information is accumulated in the operator's local variables:•_t time accumulated per line.•_n number of times line is visited (first column of resulting display).•_e number of times entry monitor is called.•_x .. .. exit .. ..513


The copy (•_f) of the subject function is applied under – in order to defyDfns' "strictly local to the capsule" rule that would otherwise put the accumulatingvariables beyond its scope.- An attempt is made to calculate the time overhead spent within the monitoringcode itself. This is effected by timing loops with embedded entry and exitsequences. Note that these loops are "compiled" by using –, so that they benefitfrom the same interpreter performance improvements, if any (such as idiomrecognition), as the monitored subject function.- Finally, this approximate monitoring overhead is subtracted from the monitoredtimes and the result displayed using Œ„. The result of the subject functionapplication is returned as a shy result, so that [ticks] may easily be embeddedwithin any expression; see the tube.dws example below.Examples:© Ackermann's function is a challenging case, as the processing time is© _negligible_ compared with the monitoring overhead. Repeated monitoring© of this function often shows quite disparate timing.3 ack ticks 32432 23 ack„{2432 22 ¸=0:¾+11244 14 ¾=0:(¸-1)’ 11187 41 (¸-1)’ ¸ ’ ¾-10 0 }3 ack ticks 32432 22 ack„{2432 24 ¸=0:¾+11244 16 ¾=0:(¸-1)’ 11187 38 (¸-1)’ ¸ ’ ¾-10 0 }© However, for more substatial <strong>functions</strong>, the display can be illuminating. Here© is the output from a graph searching function in tube.dws. Inserting a call on© ticks into the trip function, shows that around 80% of its time is spent in© determining which vertices are free.©© trip[19] find„¸.graph{¸¸ path ticks ¸ ¾} © find one leg of the route.© ¯¯¯¯¯514


london trip 'Hammersmith' 'Mornington'1 0 path„{ © Shortest path from/to ¾ in graph ¸.1 0 graph„¸ © ¸ is graph vector.1 0 fm to„¾ © starting and target vertex(ices).1 1 tree„¯2+(¼½¸)¹fm © initial spanning tree.573 80 free„{(¯2=tree[¾])/¾} © free vertices in ¾.20 1 «{ © path accumulator.19 1 ¾


assign ticks ?100 100½10001 0 assign„{ŒML„0 © Hungarian method cost assi1 02 0 step0„{step1(²—\²½¾)†¾} © 0: at least as many rows a1 02 0 step1„{step2†(‡¾)-˜/¾} © 1: reduce rows by minimum1 02 0 step2„{ © 2: mark independent zeros.4 0 stars„{ © independent zeros.3 0 ~1¹¾:¸ © no more zeros: done.2 0 next„zero, 2=>independent ze1 0 step3 ¾ zeros © next step: 3.0 0 }1 041 0 step3„{costs zeros„¾ © 3: cover cols with starred40 0 stars„zeros=2 © starred zeros.40 0 covers„2×cols stars © covered cols.40 0 ~0¹covers:stars © all cols covered: solution39 0 step4 costs zeros covers © next step: 4.0 0 }1 0828 1 step4„{costs zeros covers„¾ © 4: adjust covering lines.827 3 mask„covers=0 © mask of uncovered elements827 5 open„1=mask×zeros © uncovered zeros.827 5 ~1¹open:(˜/(,mask)/,costs)step6 ¾ © no uncovered zeros, next s767 1 prime„first open © choose first uncovered zer767 1 prow„rows prime © row containing prime.767 6 star„2=zeros×prow © star in row containing pri806 6 ~1¹star:prime step5{ © no star in row, next step39 0 costs ¾ prime © adjusted zeros matrix,0 0 }zeros+2×prime © new primed zero (3).728 1 cnext„covers+prow-2×cols star © adjusted covers.728 6 znext„zeros—3×prime © primed zero.728 4 ’ costs znext cnext © adjusted zeros and covers0 0 }1 0109 0 step5„{costs zeros prime„¾ © 5: exchange starred zeros.108 1 star„(cols prime)^zeros=2 © next star.147 0 ~1¹star:step3 ¸{ © no stars: next step :3.117 1 {costs ¾}{¾-2×¾=3}¾-¸^¾>1 © unstarred stars; starred p0 0 }zeros © adjusted zero markers.69 0 pnext„(rows star)^zeros=3 © next prime.69 0 (¸ŸpnextŸstar)’ costs zeros pnext © ¸-accumulated prime-star-·0 0 }1 061 0 step6„{costs zeros covers„¾ © 6: adjust cost matrix.60 20 cnext„costs+¸×¯1 1+.×0 3°.=covers © add and subtract minimum v60 1 znext„zeros+(×costs)-×cnext © amended zeros marker.60 0 step4 cnext znext covers © next step: 4.0 0 }1 0839 15 rows„{(½¾)½(œ²½¾)/Ÿ/¾} © row propagation.879 12 cols„{(½¾)½Ÿš¾} © column propagation.768 12 first„{(½¾)½


ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎtime{rslt} „ {larg} (fun ##.time) rarg© Time function application.[time] displays the elapsed time taken, to the nearest centi-second, when function[fun] is applied to or between its argument(s). The result of the applicationis returned as a shy result.Examples:00.12queens time 8© 8-queens problem takes just over a tenth of a second.queens time 1303:32.27© 13-queens problem takes three and a half minutes.00.07'myfile'findfile time'string'© timing of dyadic function.22305.57223{+/,¾×assign ¾} costs © complex expression.{+/,¾×assign time ¾} costs© time displayed as side-effect.See also: cmpx.500 mdf.501 ticks.509ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎwsreqbytes „ {reserve„Œwa} ##.wsreq expr © WS required to execute expression ¾.[wsreq] reports how many bytes of workspace are required to execute its charactervector argument [expr]ession. It relies on trapping WS FULL errors and doinga "binary chop" to find the minimum amount of free workspace needed to evaluatethe expression without error.Optional left argument [reserve] specifies the amount of workspace to allow forevaluation of [expr]. Setting this value close to, but greater than, the actualrequirement will reduce the number of iterations [wsreq] must perform, making itquicker. If [reserve] is not specified [wsreq] uses all of the remaining spacein the heap.NB: Some primitive <strong>functions</strong> use a different algorithm, depending on the amountof workspace available. In this case, [wsreq] forces the choice of the morefrugal and thus slower method.Technical notes:Left argument [reserve] defaults to leaving the whole of the workspace availablefor the evaluation:wsreq„{ © WS required to execute expression ¾.¸„ŒWA© no explicit reserve: use all WS.Prior to the main iteration, the expression is evaluated once using the reservedspace to check that it is sufficient:1::'Needs more space'ŒSIGNAL 1 © not enough space reserved.((–¾)€(0—ŒWA-¸)½' ')°€°{ © initial padding.¯¯¯¯ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯The padding vector is bound as (an ignored) left operand of composition °€° inorder to retain it and so to reduce the amount of available workspace for theduration of the evaluation. The simpler technique of creating a named variable:padding„(0—ŒWA-¸)½' '© name "padding" might clash!517


would introduce a potential name-clash with the subject expression.The remainder of the code employs the same binary search technique as operator…bsearch„. The workspace is packed with varying numbers of blanks in order todetermine the minimum amount of available workspace in which the expression maybe executed:{}¸„¯700+0 ’'«'© ¸ is calibration constant.{1::0 ª ¾½' '}ŒWA: © force initial WS FULL to set ŒDM.ŒWA-¸+¾{© WS required.1::1 1 0/¾ © WS FULL:: explore lower range (lo mid).(0 1 1/¾)•¸¸{–¸}¸½' ' © execute subject expr with restricted WA.}{ © binary search for WS FULL failure point:mid„˜+/¾÷2© mid point of range.mid¹¾:«½¾© convergence: maximum packing value.lo hi„¾© lower and upper bounds.’ mid ¸¸ lo mid hi © explore lower or upper range.}0 ŒWA © starting with maximum range.Notice that the expression is executed (–) within an operand function outsidethe binary search operator. This is to avoid the possibility of a name clashbetween names used in the subject expression and those (mid lo hi) used in thesearch. Within the operand function, no local names are in scope.Details:[1] ¸„¯700+0 ’'«' © ¸ is calibration constant.This line calibrates the particular version of the interpreter that is runningthe test. Different interpreter versions have differing memory requirements forstructures such as stack frames and code and symbol representations. The linecalls [wsreq] recursively with a calibration constant (¸) of 0 and subject expression'«', which is known not to consume additional workspace in its evaluation.The calibration is to some extent arbitrary, as we need to decide how much ofthe space taken by ancilliary structures, such as tokens and symbol references,to include. The additional fixed calibration constant ¯700 (termed a "fudgefactor" in some circles) is chosen simply so as to report a value of 2016 forexpression '¼1000'.[2] {1::0 ª ¾½' '}ŒWA: © force initial WS FULL to set ŒDM.This forced WS FULL is used to set ŒDM to a predetermined value. Otherwise, thefirst WS FULL sustained in the body of the test can spoil the results by retainingpointers to error structures.[3] ŒWA-¸+¾{ © WS required.[4] 1::1 1 0/¾ © WS FULL:: explore lower range (lo mid).[5] (0 1 1/¾)•¸¸{–¸}¸½' ' © execute subject expr with restricted WA.[6] }{ © initial range; calibrated result.The operand function traps (1::) WS FULL on line[4] before attempting to executethe subject expression (¸¸) on line[5], after packing (¸½' ') the workspace with¸ blanks. The function is passed the three items of the range (lo mid hi) as aright argument, and returns which range to examine next (1 1 0/¾) or (0 1 1/¾),depending on whether the execution sustains a WS FULL error or not.Temporary results-----------------Remember that an <strong>APL</strong> function requires enough workspace for its argument(s) aswell as for its result. Temporary results are released only when they are nolonger referenced. For example, if [vec] is a 1,000-item character vector:518


vec„1000½'abc' © 1,016-byte vector.then successive catenations:vec„vec,vec,vecrequire an additional 2,016 bytes for the first (rightmost) catenation to storea temporary 2,000-item vector. This temporary vector must remain in the workspacefor the duration of the second (leftmost) catenation, which requires afurther 3,016 bytes for its 3,000-item result. During the second catenation, thetotal workspace required is:named vector [vec]: 1,016result of rightmost cat: 2,016result of leftmost cat: 3,016-----6,048 bytes-----as the second catenation completes, its temporary right argument is releasedleaving:named vector [vec]: 1,016result of leftmost cat: 3,016-----4,032 bytes-----and the final assignment releases the original array leaving:named vector [vec]: 3,016-----3,016 bytes-----Given the presence of a 1,000-item character vector [vec], the additional spaceneeded to do the above catenations is 2016 + 3016:vec„1000½'abc'wsreq'vec,vec,vec'5032NB: wsreq may report a little more WS usage than above, as it includes spacetaken for symbols and code tokens, etc.NB: In 32-bit versions of the interpreter, each floating-point (645=Œdr ¾) arrayis padded with either 0 or 4 bytes in order to align its IEEE floating-pointnumbers. This _may_ affect the result of wsreq by 4 bytes for each simple floatingpoint array generated by the subject expression.Examples:)resetwsreq'¼1000'2016© reset ŒDM, etc:© workspace used to generate index sequence.3000 wsreq'¼1000' © ... with explicit reservation (quicker).2016680wsreq'Œa[¼½Œa]'© workspace used for indexing.519


wsreq'(1000½7)+1000½8' © workspace for more complex expression.10068wsreq'2+2+2+2+2+1000½2'8056© multiple temporary space allocations.See also: pack.69 nspack.378 Data_compression.190 bsearch.258ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎavl_worstWorst-case AVL trees--------------------Function for a depth-¾ worst-case AVL tree.fib„{© Depth-¾ worst-case fibonacci tree.œ«½ŒIO{© first item is tree.¾=0:0 ¸ © f 0 … []¾=1:(¸ 0(0 0))(¸+1) © f 1 … ¸ [] []l m„¸ ’ ¾-2© left subtree and next value.r n„(m+1)’ ¾-1 © right .. .. .. .. ..(m 1(l r))n © f ¾+1 … ¸ [f ¾-2] [f ¾-1]}¾ © :: tree next „ next ’ depth}•avl fib 7Ú1=1Ú2=2ÝÛ À>3=3ÌÛ À>4=4Ú5=5ÝÛ Û Ú6=6ÌÛ Û Û À>7=7Û À>8=8ÝÛ Û Ú9=9Û À>10=10ÝÛÀ>11=11ÌÛÀ>12=12© Depth-7 worst case.13=13ÝÛ Ú14=14ÌÛ Û À>15=15Û Ú16=16ÝÛ Û Û Ú17=17Û Û À>18=18ÝÛ Û À>19=19ÌÛ Û À>20=20À>21=21ÝÛ Ú22=22Û Ú23=23ÝÛ Û À>24=24ÌÛ Û À>25=25À>26=26ÝÛ Ú27=27ÌÛ Û À>28=28À>29=29ÝÛ Ú30=30À>31=31ÝÀ>32=32ÌÀ>33=33520


•avl (fib 7) ~avl 1 © removing node 1:Ú2=2Ú3=3ÝÛ À4=4Ú5=5ÝÛ À6=6ÌÛ À>7=7Ú8=8ÝÛ Û Ú9=9Û À10=10ÝÛÀ>11=11ÌÛÀ>12=12Ú13=13ÝÛ Û Ú14=14ÌÛ Û Û À>15=15Û À16=16ÝÛ Û Ú17=17ÛÀ>18=18ÝÛÀ>19=19ÌÛÀ>20=2021=21ÝÛ Ú22=22Û Ú23=23ÝÛ Û À>24=24ÌÛ Û À>25=25À26=26ÝÛ Ú27=27ÌÛ Û À>28=28À>29=29ÝÛ Ú30=30À>31=31ÝÀ>32=32ÌÀ>33=33See also: avl.96ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎbalmBrainbalm: An easier-to-program interface to Brainfuck------------------------------------------------------Here are some …mac„ros for a simple interface to Brainfuck. The macros expand toregular "pure" BF code, which uses only tokens: [ ] + - < > , .The Balm machine extends BF with:* If-else-fi constructions, which may be nested.* A push-down stack (for non-negative values).* Directly addressable (random-access) memory.* Instructions ; and : for input/output of numeric digits.This little function "‘" will help us to collect sample source lines into a newline-separatedline-vector in buffer •:‘„{{}•,„¾,¯1†4†Œav}•„''© accumulate into • buffer.© null accumulation buffer.First, we implement directly-addressable (random-access) memory in BF, with thehome (current) cell used as an accumulator "A". In addition, internal, invisible"registers" b and c will be used for some copy operations and will be assumed tobe zero between instructions.ÚÎÂÎÂÎÎÎÎÎÎÎÎÎÎÎ Accumulator A and registers b and c.ÂÎÂÎÏAÂÎÂÎÂÎÂÎÂÎÂÎÛc bÛ Û Û Û Û Û Û °°°ÁÎÁÎÏ0Á1Á2Á3Á4Á5ÁÎÀÎÁÎÁÎÁÎÁÎÁÎÎ "memory addresses" 0 1 2 3 4 5 ...521


Macros ­, „ and … implement directly-addressable or random-access BF memory:‘'­=( ' © ­ copy to A. eg: n­‘' /> ' © go to ‘' [-/] ' © move to A and b.‘' /< ' © go to A.‘' < ' © go to b.‘' [->/>+/ ' © go to A.‘')'‘'…=( ' © … move to A. eg: n…‘' /> ' © go to ‘' [-/] ' © move to A.‘' /< ' © go to A.‘')'‘'„=( ' © „ move A to eg: n„‘' />[-]/< ' © clear ‘' [-/>+/>] ' © skip back to (S-1).v (aka b)‘' > ' © go to A‘')'‘'†=( ' © pop: A+„†S ª S„1‡A‘' …=[-/>+/ >>] ' © move value down stack to (S-1).t (aka c)‘' < ' © go to c‘' 2… ' © move c to A‘' >> ' © go to A‘' - ' © decrement popped value.‘')'


‘'!=>>/>/>>> ' © reserve space for ¸-stack and regs b and c. Eg: 1000!stk •„• '' © stack macros ‡ † and !.Macros ; and : code the standard BF sequences that convert between characterdigits '0'-'9' and their numeric equivalents, by adding or subtracting '0':‘';=( ' © ; input digit A„Œ‘' , ' © input char '0'-'9'.‘' ‘=/- ' © minus.‘' 8‘ ' © subtract '0'=48.‘')'‘':=( ' © : output digit Œ„A‘' ‘=/+ ' © plus.‘' 8‘ ' © add '0'=48.‘' . ' © output char '0'-'9'.‘')'io •„• '' © numeric I/O macros ; and :.and finally, here are {, ª and }, which give us an if-else-fi control struct:‘' {=[ ' © { if A¬0‘' ª=


ack m n· push ¯1 © end of stacked-items marker.· repeat © loop· · if m=0 © ack(0, n)· · · push n+1 © = n+1· · else if n=0 © ack(m, 0)· · · push m-1 © = ack(m-1, ÎÎÎÎÎÎÎÎÎÌ· · · push 1 © 1) Û "recursive"· · else © ack(m, n) Û calls.· · · push m-1 © = ack(m-1, ÎÎÎÎÎÎÎÎÎÝ· · · push m © ack(m, ÎÎÎÎÎÎÎÙ· · · push n-1 © n-1))· · fi ©· · n „ pop © ÎÎÌ "recursive"· · m „ pop © ÎÎÙ return.· while m¬¯1 © while items on stack.· return nIt will simplify our task if we replace the "else if" construct in favour of asimpler, though more deeply-nested, "if else fi".ack m n· push ¯1· repeat· · if m=0· · · push n+1· · else © "else if" … "else" with an· · · if n=0 © indented "if"· · · · push m-1 ©· · · · push 1 ©· · · else ©· · · · push m-1 ©· · · · push m ©· · · · push n-1 ©· · · fi © together with an additional "fi".· · fi· · n „ pop· · m „ pop· while m¬¯1· return nNow we can factor the "push m-1" from both clauses of the "if n=0" case:ack m n· push ¯1· repeat· · if m=0· · · push n+1· · else· · · · push m-1 © factored-out push.· · · if n=0· · · · push 1· · · else· · · · push m· · · · push n-1· · · fi· · fi· · n „ pop· · m „ pop· while m¬¯1· return nand reverse the sense of the tests from =0 to ¬0 by exchanging the correspondingclauses.524


ack m n· push ¯1· repeat· · if m¬0 © test for non-0· · · · push m-1· · · if n¬0 © test for non-0· · · · push m· · · · push n-1· · · else· · · · push 1· · · fi· · else· · · push n+1· · fi· · n „ pop· · m „ pop· while m¬¯1· return nFinally, as copying negative values would add significant complexity to the BFcoding, we add 1 to m and n throughout and subtract one from the final result.This allows our end-of-stacked-items marker to be 0, rather than ¯1.Here is the version of Ackermann's fuction that we will code in Brainfuck:ÚÎIterative AckermannÎÎÎÎÎÎÎÎÎÎÎÌÛÛÛ ack m n ÛÛ · m n +„ 1 ÛÛ · push 0 ÛÛ · repeat ÛÛ · · if 0¬m-1 ÛÛ · · · push m-1 ÛÛ · · · if 0¬n-1 ÛÛ · · · · push m ÛÛ · · · · push n-1 ÛÛ · · · else ÛÛ · · · · push 1+1 ÛÛ · · · fi ÛÛ · · else ÛÛ · · · push n+1 ÛÛ · · fi ÛÛ · · n „ pop ÛÛ · · m „ pop ÛÛ · while m¬0 ÛÛ · return n-1 ÛÛÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙ525


©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©© ©© © Ackermann's function. ©‘' m=1 n=2 ' © declare local vars. ©‘' ;+m„ ;+n„ ' © input and incr m and n ©‘' ‡ ' © push 0 ©‘' m­[ ' © repeat ©‘' · -{ ' © · if 0¬m-1 ©‘' · · ‡ ' © · · push m-1 ©‘' · · n­-{[-] ' © · · if 0¬n-1 ©‘' · · · m… ‡ ' © · · · push m ©‘' · · · n…-‡ ' © · · · push n-1 ©‘' · · ª ' © · · else ©‘' · · · ++‡ ' © · · · push 1+1 ©‘' · · } ' © · · fi ©‘' · ª ' © · else ©‘' · · n…+‡ ' © · · push n+1 ©‘' · } ' © · fi ©‘' · †n„ ' © · pop n ©‘' · †m„ ' © · pop m ©‘' m­] ' © while stacked items ©‘' n…-: ' © output n-1 ©ack •„• '' ©© ©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©239601bf opt dark mac if,io,ram,stk, '10!',ack © ack 2 3 … 9½opt dark mac if,io,ram,stk,ack© Size of BF code for Ackermann.© Using this coding, ack(3,3) takes around half an hour on a 2GHz machine.© Compare this with around 15 seconds for the coding in …bfack„.This function wraps and indents BF loops for easier reading:pretty„{ŒML„1nl„œ²ŒTCdents„{¹¨(0—¾+1 ¯1)½¨››4†'·'}0{nice(next nasty)„¾'°'=next:¹nicemore less„dents ¸'['=next:(¸+1)’(nice,next,nl,more)nasty']'=next:(¸-1)’(nice,nl,less,next)nasty¸ ’(nice next)nasty}†{¸ ¾}/¾,'°'}526


pretty opt dark mac if,io,ram,stk,ack © Ackermann's function from Balm.,--------+>[· -]+>[· -]+


· · · · ]>· · · ]· · ]+++[· · · · -· · · ][· · -· ]+[· · -· ]+


· ]>]>>[· -]


This simplification entails one additional final reduction, so instead of:we have:ack « 0 n … n+1ack ¯1 0 n … ack ¯1 (n+1) … n+1Coded in D and using ¸ as the accumulator:ack„{¸„¯1a„¯2‡¸,¾m n„¯2†¸,¾m=¯1:nm=0:a ’ n+1n=0:a ’(m-1)1a ’(m-1)m(n-1)}61ack 3 3 © ack 3 3 … 61We can now code this tail-recursive version of Ackermann's function in BF using…mac„ our simple macro processor.The following small function collects character vectors into a newline-separatedline-vector in buffer •:‘„{{}•,„¾,¯1†4†Œav}•„''© accumulate into • buffer.© null accumulation buffer.530


So:©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©© ©© Macros: © Ackermann's function. ©© © ©‘' ;=(, ‘=/- >6‘[+]< )· · ' © input digit ©‘' :=( ‘=/+ >6‘[-]< .)· · ' © output digit ©‘' ' © ©‘' {=/>+/-/< · · · · · · · ' © if ©‘' ª=/>]/>[-/< · · · · · · · · ' © else ©‘' }=/>/>]/+>+ ' © m .. 0 … 0 .. m m ©‘' [-]+/; ' © ¯1(m) ©‘' >;< ' © ¯1(m)n ©‘' +[- ' © a(m)n ©‘' 2{ ' © if m¬0: ©‘' >1{ ' © if n¬0: ©‘' 1… ' © a m(0)n m ©‘' >>2„ ' © a m m n(0) ©‘' 1„: ' © output n ©ack •„• '' ©© ©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©The program inputs two single digits and outputs a single digit result. Unlesswe use the memory dump, this restricts the possible arguments to:m n…0 1 2 3 4 5 6 7 8‡ ÚÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÌ0 Û 1 Û 2 Û 3 Û 4 Û 5 Û 6 Û 7 Û 8 Û 9 ÛÃÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÙ1 Û 2 Û 3 Û 4 Û 5 Û 6 Û 7 Û 8 Û 9 ÛÃÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÙ2 Û 3 Û 5 Û 7 Û 9 ÛÃÎÎÎÏÎÎÎÁÎÎÎÁÎÎÎÙ3 Û 5 ÛÀÎÎÎÙ239bf mac ack © ack 2 3 … 9531


The following function removes all non-BF "white space", which was preserved bythe macro processor:dark „ •°'[]+-,.'© without white space.and this optimiser removes cancelling and >< sequences.opt „ {†{({¾‹¯1²¾}¸º¾)/¾}ÿ­/'>


ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎbfsClassic Breadth-First Search----------------------------Dijkstra's classic breadth-first search algorithm maintains a _queue_ of yet-to-be-visited vertices. Items are taken one at a time from the front of the queue,and unvisited vertices reachable from the head item are added to the back. Thealgorithm terminates when the queue is empty.An <strong>APL</strong> coding of the classic algorithm might look like this:search„{© Classical breadth-first search.graph„¸© ¸ is graph vector.«{ © no vertices visited.¾­«:¸© no vertices left: done.head„1†¾ ª tail„1‡¾ © next and remaining vertices in queue.next„headœgraph© vertices adjacent to head.(¸,head)’(tailžnext)~¸ © accumulate visited vertices.}¾ © from starting vertex.}The inner tail-recursive function uses ¸ as an accumulator for vertices alreadyvisited, and ¾ as a queue for those still to be visited. By appending new verticesto the back of the queue and removing them from the front, we are assuredof visiting nearer vertices before more remote ones.Using the following graph as an example:graph„(2 5)(1 3 6)(2 4 7)(3 8)(1 6 9)(2 5)(3 8)(4 7 12)(5 10 13)(9 14)(12 151ÎÎÎÎÎÎÎ2ÎÎÎÎÎÎÎ3ÎÎÎÎÎÎÎ4Û Û Û ÛÛ Û Û ÛÛ Û Û Û5ÎÎÎÎÎÎÎ6 7ÎÎÎÎÎÎÎ8ÛÛÛÛÛÛ9ÎÎÎÎÎÎ10 11ÎÎÎÎÎÎ12Û Û Û ÛÛ Û Û ÛÛ Û Û Û13ÎÎÎÎÎÎ14ÎÎÎÎÎÎ15ÎÎÎÎÎÎ16Graph Vertex numbers:Breadth-first search from vertex 1 visits vertices in the following order:[1]ÎÎÎÎÎ[2]ÎÎÎÎÎ[4]ÎÎÎÎÎ[7]Û Û Û ÛÛ Û Û ÛÛ Û Û Û[3]ÎÎÎÎÎ[5] [8]ÎÎÎÎÎ[11]ÛÛÛÛÛÛ[6]ÎÎÎÎÎ[9] [15]ÎÎÎÎ[13]Û Û Û ÛÛ Û Û ÛÛ Û Û Û[10]ÎÎÎÎ[12]ÎÎÎÎ[14]ÎÎÎÎ[16]BREADTH-first order of visits:The function may be changed to produce a depth-first search, by _prefixing_ newvertices to the queue, which then operates as a stack. See …dfspan„.533


[1]ÎÎÎÎÎ[2]ÎÎÎÎÎ[3]ÎÎÎÎÎ[4] DEPTH-first order of visits:Û Û Û ÛÛ Û Û ÛÛ Û Û Û[13]ÎÎÎÎ[14] [6]ÎÎÎÎÎ[5]ÛÛÛÛÛÛ[12]ÎÎÎÎ[11] [8]ÎÎÎÎÎ[7]Û Û Û ÛÛ Û Û ÛÛ Û Û Û[15]ÎÎÎÎ[10]ÎÎÎÎ[9]ÎÎÎÎÎ[16]Ref: Dijkstra, E.W. (1959), "A note on two problems in connection with graphs."Numerische Mathematik, (1), pp. 269-271.Parallel Breath-First Search----------------------------In <strong>APL</strong> we can process ALL vertices at the same distance from the starting vertexin parallel. For non-trivial graphs, this leads to a significant performance improvement.Conceptually, starting from the originating vertext ¾, the algorithmgenerates a "fringe" or "wave", which ripples outwards in all possible directionsthrough the graph. At each pass of the algorithm, the wave front is advancedone step further from the starting vertex.search„{© Parallel breadth-first search.graph„¸© ¸ is graph vector.¾{ © from starting vertex.¾­«:¸© no unvisited vertices: done.adjv„graph[¾] © nested vector of ALL adjacent vertices.next„ž(†,/adjv)~¸ © simple vector of next unvisited vertices.(¸,next)’ next © advance wave of visited vertices.}¾ © from starting vertex.}Using graph as above:[1]ÎÎÎÎÎ[2]ÎÎÎÎÎ[3]ÎÎÎÎÎ[4]Û Û Û ÛÛ Û Û ÛÛ Û Û Û[2]ÎÎÎÎÎ[3] [4]ÎÎÎÎÎ[5]ÛÛÛÛÛÛ[3]ÎÎÎÎÎ[4] [7]ÎÎÎÎÎ[6]Û Û Û ÛÛ Û Û ÛÛ Û Û Û[4]ÎÎÎÎÎ[5]ÎÎÎÎÎ[6]ÎÎÎÎÎ[7]PARALLEL BREADTH-first order of visits:See also: dfspan.156 Graphs.137 wGraphs.163ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎco_opsCo-operators¯¯¯¯¯¯¯¯¯¯¯¯A number of the operators in this workspace are designed to co-operate in multipleinstances within a derived function:f co_op g co_op h co_op k ... argument© typical co-operator expression.534


with expression tree:ÚÎÎÁÎÎÌ... argumentÛÚco_opÌÛ ÛÚco_opÌ kÛ ÛÚco_opÌ hÛ Ûf gNotice that co-operators are always dyadic but may produce a monadic or ambivalentderived function.A typical use of a co-operator is for the left argument to select which monadicoperand function should be applied to the right argument.... to be continuedExamples are:…case„ Select statement.…cond„ Conditional function application.…for„ Multiple selection of function list.…fork„ Function fork.…lof„ List of <strong>functions</strong>.…of„ Pick'th fn applied to arg.…vof„ Vector of <strong>functions</strong>.ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎcolour_change------------------------------------Changing the colour of notes windows------------------------------------You can make these notes easier on the eye by changing their colour:Right-click in the body of this window and select [Colours...]Click on the [Variables] tab.From the [Color Element] drop-down, select [Character Vector] or clickin the [CharVector - ...] window.Choose Foreground and Background colours to taste.Click on [OK].ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎdecayDecay¯¯¯¯¯Cans of soup at the back of the cupboard decay into cans of tomato soup.Non-soup cans decay into cans of either chickpeas or red kidney beans.Pencils of grade HB or better decay into 2H or worse.High-value coins decay into low-value coins and bank notes into pocket fluff.And so things go.·535


ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎdeclarativeDeclarative Programming-----------------------The essence of the declarative programming paradigm is that we tell the computerwhat we want, not how to go about doing it. For example, the <strong>APL</strong> function forthe mean item of a vector: {(+/¾)÷½¾} declares that the mean is the quotient ofthe sum and number of items. Contrast this with the coding in a typical procedurallanguage, where we are obliged to determine the sequence of operations:rslt = mean(vec length):sum = 0index = 0while index < lengthsum = sum + vec[index]rslt = sum ÷ lengthThe penultimate line: sum = sum + ... is particularly thought-provoking:There is a story that Ken Iverson, the inventor of <strong>APL</strong>, was passing a terminalat which a Fortran programmer had just typed:I = I+1Ken paused for a moment, muttered "no it doesn't", and passed on.A similar yarn relates to a computer scientist who, many years ago, before theconcept of declarative programming was generally understood, was teaching programmingto a group of geography students. The students were having a hard timeunderstanding what I=I+1 means. To his immense credit, on reflection, the teacherrealised that he didn't understand either. Thus came a significant advance incomputer science.Note however, that in a lazy functional language such as Haskell or min.dws ormax.dws, such statements have meaning. For example, in max, we can say:#max''i = +ii::© start max session./ declare i to be its own successor./ the type of i is "num"./ However, a problem occurs if we try to display the value of i/ by reducing it to a number: the reduction fails to terminate/ as max tries to display a number which is its own successor.i / this will not terminate !!!... INTERRUPTFP theorists assign a special symbol "ƒ", pronounced "bottom" to non-terminationin order that they can reason about expressions containing such values.(muse:Stupid questions ...During the time we were implementing the very first version of <strong>Dyalog</strong>, afriend, who was not a programmer, asked me how much of it was coded in <strong>APL</strong>.I thought he was bonkers.We now have exactly this internal "magic function" prototyping facility.536


When "Visual Display Units" first appeared alongside scrolling paper terminals,a participant on a course I was giving asked me where the writing wentwhen it disappeared off the top of the screen. I explained it was just,well, gone; same place the ticking goes when the clock stops.We now have scrolling sessions.On another course, someone asked me what (A B) means, when A and B are variables.I explained that it didn't mean anything as there wasn't a functionbetween the A and the B.We now have vector notation.)Sound bite: A stupid question is a portal into an alternative mindset.Landin prefers the term "denotative":"The word "denotative" seems more appropriate than nonprocedural, declarative orfunctional. The antithesis of denotative is "imperative".""The Next 700 Programming Languages", Landin,P.J., Comms ACM 9.3, March 1966.See also: pearly.553ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎderiveMechanical Transformation of Simple D-<strong>functions</strong> into Derived Functions ----------------------------------------------------------------------The following <strong>functions</strong> are said to be "extensionally equal" as, given any arrayargument, each returns the same result.{«½½¾}«°½°½© D-function for first-of-shape.© Derived function for first-of-shape.For very small <strong>functions</strong>, either coding may be appropriate, though for more complexones, the first style is probably preferable.Having said this, it is possible to prescribe a set of rules for transforming(a subset of) simple monadic D-<strong>functions</strong> into derived <strong>functions</strong>.NB: There seems to be little practical value in performing this transformation,other than as an entertainment. One possible exception is that primitive poweroperator ÿ may derive the inverse of a derived function, whereas D-<strong>functions</strong> arenot currently admitted.The following rules may be applied repeatedly to transform a simple monadic D-function into a derived function:where:[0] { f ¾} … f[1] a f ¾} … a°f ¾}[2] ¾ f a} … (f°a) ¾}[3] ¾ f ¾} … fþ ¾}[4] f f ¾} … f°f ¾}[5] f f a} … f (f a)[6] (X) f ¾} … ¾ fþ X}[7] (X) f a} … (f°a) X}a is an arrayf is a (possibly derived) functionX is an array-returning expression537


In the following examples "n…" means "transforms using rule[n] to:" and thepattern of the underlined tokens selects which rule to apply next.¯¯¯¯¯¯¯¯¯¯{(›“¾)¦¾}© sort (Phil Last)¯¯¯¯¯¯¯¯6… {¾¦þ›“¾}¯¯¯¯4… {¾¦þ›°“¾}¯¯¯¯¯¯¯4… {¾¦þ°›°“¾}¯¯¯¯¯¯¯¯¯3… {¦þ°›°“þ¾}¯¯¯¯¯¯¯¯¯¯0… ¦þ°›°“þ{(+/¾)÷½¾}¯¯¯¯4… {(+/¾)÷°½¾}¯¯¯¯¯¯¯¯¯¯6… {¾ ÷°½þ +/ ¾}¯¯¯¯¯¯¯¯¯¯4… {¾ ÷°½þ°(+/) ¾}¯¯¯¯¯¯¯¯¯¯¯¯¯¯3… {÷°½þ°(+/)þ¾}¯¯¯¯¯¯¯¯¯¯¯¯¯0… ÷°½þ°(+/)þ© mean item of vector ¾Regarding rule [6]: if expression X in (X) does not include an occurrence of ¾,an optimisation is to apply rule [1] instead. This generally leads to a simplerderived function (although see the section on optimisation in "Extensions andRestrictions" below):{(›«),¾} © (›«) does not contain ¾, so apply rule [1].¯¯¯¯¯¯¯1… {(›«)°,¾}¯¯¯¯¯¯¯¯0… (›«)°,as opposed to:{(›«),¾} © ignore optimisation: apply rule [6].¯¯¯¯¯¯¯6… {¾,þ›«}¯¯¯¯¯5… {¾,þ(›«)}¯¯¯¯¯¯¯¯2… {(,þ°(›«))¾}¯¯¯¯¯¯¯¯¯¯¯¯0… ,þ°(›«)Prior to the transformations, the D-function must be pre-processed to remove:[1] array strands that include an ¾:... A ¾ B ... … ... (›A),(›¾),(›B) ...538


For example:{¾ ¾} © dup[licate]¯¯¯… {(›¾),›¾}¯¯¯¯4… {(›¾),°›¾}¯¯¯¯¯¯¯¯¯6… {¾,°›þ›¾}¯¯¯¯¯¯¯4… {¾,°›þ°›¾}¯¯¯¯¯¯¯¯¯3… {,°›þ°›þ¾}¯¯¯¯¯¯¯¯¯¯0… ,°›þ°›þ[2] square-brackets:A[B;C] … B C ¦ A© index brackets‡[1] ... … ‡³ ... © axis bracketsThere is a larger example towards the end of ##.scripts.dftRestrictions and Extensions---------------------------[1] This process doesn't cope with an expression that contains ¾ as the operandof an operator:{(›ÿ¾)'Doh'}[2] Nor will it transform a recursive call ’. Although it seems likely (to JMS)that rules might be discovered for replacing some cases of recursion withthe power operator ÿ.[3] For multi-line dfns, Phil Last has shown us how to transform a guard into asimple expression using /. See, for example …pow„ and …cond„.[8] C:TªF} … œ{F}/(¼~C),{T}/(¼C),›¾}where C, T and F are expressions. Unfortunately, guard expression C is evaluatedtwice.(muse:There was overwhelming cultural pressure, in the specification of primitivepower operator ÿ, for the "repeat count" to be the right _operand_.Had the repeat count been assigned to the left _argument_ of a monadicoperator, as in …pow„, rule [8] could have been the simplified slightly:[8] C:TªF} … (~C){F}ÿ C{T}ÿ ¾}Oh, and the _monadic_ derived function could have been "fixpoint":)1°+°÷ ÿ 1 © 1+÷ 1+÷ ... 11.618033989539


Dyadic Functions----------------In the absence of Hooks and Forks, the best plan appears to be to convert dyadic<strong>functions</strong> into monadic equivalents by passing left and right arguments as a pairand referencing them from within the function as (œ¾) and (œ²¾). If the subjectfunction is applied under an operator, the argument-pair array must be preparedaccordingly:X {...¸...¾...} Y … {...(œ¾)...(œ²¾)...} X Y © simply applied fn.X {...¸...¾...}¨ Y … {...(œ¾)...(œ²¾)...}¨ (›¨X) ,¨ ›¨Y © applied with each.X °.{...¸...¾...} Y … {...(œ¾)...(œ²¾)...}¨ (›¨X) °., ›¨Y © outer product....etc.Optimisation------------It might be interesting to provide a second set of post-transformation optimisationrules such as:[o1] fþþ … f[o2] fþ°a … a°f[o3] a°(fþ) … f°a...Rule [o2] would render choosing between rules [1] and [6], in the case (a) f ¾},unnecessary as either would (eventually) produce the same result:{(›«),¾} © (›«) does not contain ¾, so apply rule [1].¯¯¯¯¯¯¯1… {(›«)°,¾}¯¯¯¯¯¯¯¯0… (›«)°,as opposed to:{(›«),¾} © ignore optimisation: apply rule [6].¯¯¯¯¯¯¯6… {¾,þ›«}¯¯¯¯¯5… {¾,þ(›«)}¯¯¯¯¯¯¯¯2… {(,þ°(›«))¾}¯¯¯¯¯¯¯¯¯¯¯¯0… ,þ°(›«)¯¯¯¯¯¯¯o2… (›«)°,© (same derived function as above)See also: dft.125 trainsÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎdfns_style_guideWhen changing this workspace ...--------------------------------For new Dfn (or Dop): , don't forget:- That the web pages are (mostly) designed to fit in an 80-char-wide window.- To switch off .- To provide a notes vector: )ed …notes.newfn- To provide (and test!) a …test„ script: 'e'test'newfn'- To add a line to …contents„.540


When writing or amending a note, don't forget to:- Ensure notes have no trailing blanks (otherwise, test'vtrim' will fail).- Right-align text to 80 columns.- Add Index: and Index; entries for Dfns<strong>Notes</strong>.pdf. See …index„.- Add …...„ and See also: links, where helpful.- Ensure notes have no trailing empty rows.- Make the content attractive to casual internet browsers.- Enjoy yourself.Before saving the workspace:- test'' Otherwise, test failures will stop the overnight build.- wsdiff'' To check that all changes are as expected.- )reset To reset ŒDM.- )save Using <strong>Dyalog</strong> V13.1. Remember:- Google is watching us. These pages attract a reasonable number of browsers tothe <strong>Dyalog</strong> web site.ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎdvorak(muse:Programmer Dvorak http://www.kaufmann.no/roland/dvorak¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ÚÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÎÎÎÎÎÌÛ~ Û% Û7 Û5 Û3 Û1 Û9 Û0 Û2 Û4 Û6 Û8 Û• ÛBackspaceÛÛ$ Û& Û[ Û{ Û} Û( Û= Û* Û) Û+ Û] Û! Û# Û ÛÃÎÎÎÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÎÎÎÎÎÝÛTab Û: Û< Û> ÛP ÛY ÛF ÛG ÛC ÛR ÛL Û? Û^ ÛEnter ÛÛ Û; Û, Û. Ûp Ûy Ûf Ûg Ûc Ûr Ûl Û/ Û@ Û ÛÃÎÎÎÎÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÌ ÛÛCaps ÛA ÛO ÛE ÛU ÛI ÛD ÛH ÛT ÛN ÛS Û_ Û| Û ÛÛLock Ûa Ûo Ûe Ûu Ûi Ûd Ûh Ût Ûn Ûs Û- Û\ Û ÛÃÎÎÎÎÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÎÎÁÎÎÎÎÎÝÛShift Û Û" ÛQ ÛJ ÛK ÛX ÛB ÛM ÛW ÛV ÛZ ÛShift ÛÛ Û Û' Ûq Ûj Ûk Ûx Ûb Ûm Ûw Ûv Ûz Û ÛÃÎÎÎÎÎÎÁÂÎÎÎÁÎÂÎÎÁÎÎÎÂÁÎÎÎÎÁÎÎÎÎÁÎÎÎÎÁÎÎÎÎÁÎÎÎÎÁÂÎÎÎÁÎÎÂÎÁÎÎÎÎÏÎÎÎÎÎÂÎÎÎÎÎÎÝÛctrl ÛWin ÛAlt Û ÛAlt GrÛWin ÛMenu ÛCtrl ÛÛ Û Û Û Û Û Û Û ÛÀÎÎÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÁÎÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÎÙWhere should we allocate <strong>APL</strong> symbols on a Dvorak keyboard? The spirit of thelayout is to ignore mnemonic association in favour of arranging keys withrespect to the frequency of occurrence of key-sequences. Among other considerations,the keys are placed so as to minimise the total distance that ourfingers travel from their home positions in the centre of the keyboard.The guiding assumption is that, while mnemonic associations (½ on R, ¼ on I,and so forth) are handy while we're learning the keyboard, with a littlepractice, our _fingers_ soon remember where the characters are located withoutresort to the mnemonic. This "muscle memory" phenomenon can be seen inaction when we drive a stick-shift or dance the quickstep; we delegate thechanges to our hands and feet without having to think consciously aboutthem.If we accept this, then mnemonic placement of keys soon becomes counterproductivecompared with schemes that try to minimise hand movements. The(arguably) most mnemonic keyboard of all: ABCDEF..., doesn't seem to havegiven QWERTY much of a run for its money even though such keyboards are,these days, no more expensive to produce.541


(muse:)For what it's worth, this typist finds it significantly easier spellBRAM(ley) on those ticket machines in Reading Railway Station that sportQWERTY touch-screens, than on the few that offer ABCDEF.http://mkweb.bcgsc.ca/carpalx/?home is an excellent website, which addressesmany of the issues of efficient keyboard layout. In particular, see thesection on "typing effort".Frequency of Characters in this Workspace¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯Here is a frequency sample (as of 2009-03-22) of _single_ <strong>APL</strong> characters insource code in this workspace. It excludes workspace notes and test-scriptsbut includes <strong>APL</strong> characters in function comments:apl„'•”“²³´µ‹ŠŽª¨¯ˆ‰¬Ÿ×÷ÿ•«•¾¹½†‡¼±„…€­®¸—˜’‘°Œ–•º•þ›œ•žƒ‚©š¦'code„†,/,°Œcr¨‡Œnl 3 4© source code chars.freq „ {(ž¾){¸{(‡³†¸¾)[”¾]}+/¸°.=¾}¾}4 40 cols freq code•apl © apl char-frequency.© 4468 ’ 426 … 111 ‰ 44 • 14¾ 4011 ° 402 — 99 “ 42 ” 13„ 3159 ¯ 336 ³ 99 ž 42 • 7¸ 2705 ¹ 323 ˜ 97 ® 41 Ž 5½ 811 × 318 • 81 ƒ 40 ‹ 4Œ 799 ² 297 ‘ 81 ´ 38 ¦ 3¨ 717 ¼ 279 š 70 ‚ 36 Š 3† 623 ª 268 • 68 µ 32 € 1› 563 « 150 – 64 ˆ 25 ÿ 1‡ 532 ÷ 140 º 60 • 25œ 523 ¬ 128 þ 57 • 16­ 444 Ÿ 127 ± 54 15It _could_ be argued that we should also reassign non-<strong>APL</strong>, non-alphamericchars:other„'~%•$&[{}(=*)+]!#:?^;,./@_|-\"'''4 40 cols freq code•aplžother © non-alphameric frequency.© 4468 = 618 \ 259 # 71 • 25¾ 4011 + 592 < 233 š 70 ! 22. 3936 › 563 > 227 ? 69 • 16' 3411 ‡ 532 | 206 • 68 15„ 3159 œ 523 ^ 193 – 64 • 14¸ 2705 ­ 444 « 150 º 60 ” 13) 1988 ’ 426 " 142 þ 57 • 7: 1985 ° 402 ÷ 140 ± 54 % 6( 1981 ¯ 336 ¬ 128 ‰ 44 Ž 5, 1859 [ 324 Ÿ 127 “ 42 ‹ 4{ 1779 ] 324 * 116 ž 42 ¦ 3} 1771 ¹ 323 … 111 ® 41 Š 3- 1178 × 318 — 99 ƒ 40 @ 3/ 954 _ 307 ³ 99 ´ 38 $ 1½ 811 ~ 298 ˜ 97 ‚ 36 € 1Œ 799 ² 297 • 81 µ 32 • 1¨ 717 ¼ 279 ‘ 81 & 30 ÿ 1† 623 ª 268 ; 75 ˆ 25but doing so would win us few friends among (any) existing Programmer Dvorakusers.542


Character sequences¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯The incidence of character _sequences_ is as important as that of individualcharacters. For example, it is beneficial to allocate frequently occurringsequences so that, where possible, the characters are typed with alternatinghands or, failing that, single-hand "finger runs" from the outer (pinky) tothe inner (index) side with the same hand. Regarding this last point,http://en.wikipedia.org/wiki/Dvorak_Simplified_Keyboard notes that we generallydrum our fingers on the table in this direction.(muse:)In the same Wikipedia article, Dvorak also recommends: "Digraphs shouldnot be typed with adjacent fingers.". This seems a bit rich, given thathe allocates one of the most frequent digraphs in English: "th" to thesecond and index finger of the right hand. Presumably this was as theresult of a compromise, which avoided an even worse combination.The following function returns a list, for each <strong>APL</strong> character, of the mostfrequent non-alphameric characters that (a) precede and (b) follow it. Thelist is returned in order of individual <strong>APL</strong> character frequency, as above.cseqs„{© ¾-char-sequence table.code„{(¾¬1²¾)/¾}†,/,°ŒCR¨‡ŒNL 3 4 © source code chars.atab„{+/¾ºcode}¨°.,þ¸,¾© adjacency count table.pops„{{¾¼—/¾}¨‡¾³atab}© indices of popular pairs.pqx„pops¨(2 1)(1 2)© popular ¸¾ and ¾¸ indices.chars„¸,¾© apl and other chars.achar„{¸œ¨¨(›chars){¸ ¾}¨‡¾³atab} © popular adjacent char and count.pqvex„pqx achar¨(2 1)(1 2)© preceding and following counts.fmt„{© format:(pc pn)(qc qn)„¾© preceding count and char,pn pc(,¸)qc(•qn) © - char -} © following char and count.list„¸ fmt¨(½¸)†‡³†pqvex© list of char adjacencies.sort„{¸{¸[”¾]}+/¸°.=¾}© sorted in order of frequency.freq„{(ž¾)sort ¾}code•¸© char frequency.‡•†list[¸¼freq]© list by frequency.}For example, in the output below (arranged in four columns, so as to be easyon the eye), the _third_ item in the first column: "129 ¸ „ { 1015" indicatesthat '„', the _third_ most popular <strong>APL</strong> character, is preceded most often(128) by an '¸' and followed most often (1015) by a '{'.ÚÎÎÎÎÎÎÎÎÎ „, the third-most frequently occurring <strong>APL</strong> character,129 ¸ „ { 1015ÀÎÎÎÝ ÀÎÎÎÎÁÎÎ is followed most (1015) frequently by {.ÀÎÎÎÎÎÎÎÎÎÎÎ and preceded most (129) frequently by ¸.This suggests that it might be (1015)-attractive to site the '„' key so thatProgrammer-Dvorak '{' may easily follow it.Of course, an analysis of a more traditional workspace, where D-function usagewas less prevalent, might yield quite different results! ;-)NB: Take care not to infer from the above item, anything about the frequencyof occurrence of the sequence '¸„{'. In fact, it occurs only 21 times, while'¸„' occurs 129 times and '„{' occurs 1015 times.Note also that, in the first line of cseqs, function {(¾¬1²¾)/¾} deliberatelyremoves adjacent identical characters from the analysis. A frequent occurrenceof, say, double-each ¨¨ wouldn't help us to locate the ¨ symbol onthe keyboard.543


Here are the results for the code in this workspace (as of 2009-03-22):4 60 cols apl cseqs other © adjacent char frequencies.28 ' © ' 34 51 ¾ ¹ ' 47 19 + š ¾ 18 5 ¸ • „ 4302 ½ ¾ } 619 22 . × ¾ 43 9 ' • _ 61 8 } • „ 10129 ¸ „ { 1015 42 œ ² ¾ 53 14 ( – ¾ 17 3 ' . 4193 „ ¸ ) 243 34 ( ¼ ½ 82 17 ' º ¾ 30 7 [ ” ¾ 5112 { Œ „ 14 5 ' ª ' 9 5 ¹ þ ° 8 6 ¾ • ' 4111 ( ½ ¾ 302 22 „ « ½ 22 2 × ± ¾ 36 3 ¸ • ¾ 3137 } ¨ ¾ 111 27 ) ÷ ¾ 10 6 ¸ ‰ ½ 13 2 ' Ž ' 271 ) † ¾ 101 24 ¾ ¬ ' 21 13 „ ž , 10 2 ) ‹ ² 2165 , › ' 145 21 ( Ÿ \ 34 8 ) ® ( 9 2 ) ¦ ¨ 170 ) ‡ ¾ 129 12 ' … ' 11 2 ' ƒ ³ 5 1 ‹ Š ” 162 ) œ ¾ 112 45 ‡ ³ † 46 10 [ “ † 16 1 { € } 1137 ' ­ ¸ 85 10 „ — / 25 8 { ´ ¾ 9 1 • ÿ • 085 ) ’ ¨ 60 21 „ ˜ / 19 13 ) ‚ ¾ 1578 } ° { 75 14 ( • ¨ 15 3 × µ ¾ 637 ( ¯ ' 14 15 ' ‘ „ 5 4 < ˆ = 4Happily, many of the above rankings confirm our expectations:„ is often followed by {, for function definition,¨ is most often preceded by }, as in "dfn-each",¾ is often followed by },¾ often follows a primitive function,) often precedes a primitive function,“ and ” are often preceded by [,³ is often preceded by ‡ and often followed by † (as in ‡³†),ƒ is often followed by ³,... and so on.NB: Before attempting to use the above results to design an <strong>APL</strong>/Dvorak keyboard,it might be better to adjust function cseqs to report not just thesingle highest-frequency predecessor and successor character. Perhaps weshould consider a "top ten" popular neighbour chart for each character. Thiswould permit us a little "wiggle room" when trying to optimise the allocationof <strong>APL</strong> symbols to keys.With the advent of Input Method Editors (IMEs), it is relatively easy to experimentwith alternative keyboard layouts. Here is one that has attracted amodest following:"Colemak" http://colemak.comÚÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÎÎÎÎÌÛ • Û 1 Û 2 Û 3 Û 4 Û 5 Û 6 Û 7 Û 8 Û 9 Û 0 Û - Û = ÛBackspcÛÃÎÎÎÁÎÂÎÁÎÂÎÁÎÂÎÁÎÂÎÁÎÂÎÁÎÂÎÁÎÂÎÁÎÂÎÁÎÂÎÁÎÂÎÁÎÂÎÁÎÂÎÁÎÂÎÎÎÎÎÝÛTab Û Q Û W Û F Û P Û G Û J Û L Û U Û Y Û ; Û [ Û ] Û \ ÛÃÎÎÎÎÎÁÂÎÎÁÂÎÎÁÂÎÎÁÂÎÎÁÂÎÎÁÂÎÎÁÂÎÎÁÂÎÎÁÂÎÎÁÂÎÎÁÂÎÎÁÂÎÎÁÎÎÎÎÎÝÛCaps Û A Û R Û S Û T Û D Û H Û N Û E Û I Û O Û ' Û Enter ÛÃÎÎÎÎÎÎÁÎÂÎÁÎÂÎÁÎÂÎÁÎÂÎÁÎÂÎÁÎÂÎÁÎÂÎÁÎÂÎÁÎÂÎÁÎÂÎÁÎÂÎÁÎÎÎÎÎÎÎÎÝÛShift Û Z Û X Û C Û V Û B Û K Û M Û , Û . Û / Û Shift ÛÃÎÎÎÎÂÎÎÎÁÂÎÎÁÎÎÂÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÂÎÎÁÎÂÎÁÎÎÎÏÎÎÎÎÂÎÎÎÎÎÝÛCtrlÛWin ÛAlt ÛÛAltGÛWin ÛMenuÛCtrl ÛÀÎÎÎÎÁÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÁÎÎÎÎÎÙFinally, here is the physical layout of a pretty little keyboard: the HappyHacking Professional JP, from PFU-Fujitsu. Notice that the narrow space barleaves room for some additional mode keys, which is just the ticket for <strong>APL</strong>.For example, the keys adjacent to the space bar, which are pressed with thethumbs, could be used for <strong>APL</strong> and <strong>APL</strong>+Shift.544


)Happy Hacking Professional2 JP (PD-KB420B)ÚÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÌÛescÛ Û Û Û Û Û Û Û Û Û Û Û Û Ûbs ÛÃÎÎÎÁÎÂÎÁÎÂÎÁÎÂÎÁÎÂÎÁÎÂÎÁÎÂÎÁÎÂÎÁÎÂÎÁÎÂÎÁÎÂÎÁÎÂÎÁÎÂÎÁÎÂÎÁÎÎÎÝÛtab Û Û Û Û Û Û Û Û Û Û Û Û ÛenterÛÃÎÎÎÎÎÁÂÎÎÁÂÎÎÁÂÎÎÁÂÎÎÁÂÎÎÁÂÎÎÁÂÎÎÁÂÎÎÁÂÎÎÁÂÎÎÁÂÎÎÁÂÎÎÁÌ ÛÛctrl Û Û Û Û Û Û Û Û Û Û Û Û Û ÛÃÎÎÎÎÎÎÁÂÎÎÁÂÎÎÁÂÎÎÁÂÎÎÁÂÎÎÁÂÎÎÁÂÎÎÁÂÎÎÁÂÎÎÁÂÎÎÁÂÎÎÁÂÎÎÁÂÎÎÎÝÛshift Û Û Û Û Û Û Û Û Û Û Û Û † ÛsftÛÃÎÎÎÂÂÎÎÁÂÎÎÁÂÎÎÁÂÎÎÁÂÎÎÁÎÎÎÁÎÎÂÁÎÎÂÁÎÎÂÁÎÎÂÁÎÎÂÏÎÎÎÏÎÎÎÏÎÎÎÝÛfn ÛÛ Û ÛaltÛ Û space Û Û ÛaltÛfn ÛÛ „ Û ‡ Û … ÛÀÎÎÎÁÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÎÎÎÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÁÎÎÎÁÎÎÎÁÎÎÎÙhttp://www.pfu.fujitsu.com/hhkeyboardhttp://www.youtube.com/watch?v=kWGsxxV1k0ASee also: http://en.wikipedia.org/wiki/Keyboard_layoutSee also: cols.26ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎeachrslt „ (¸¸ ##.each) array© Fast each for pure operand function.Mike Day's each operator indentifies unique items in its argument [array] andapplies monadic operand function ¸¸ only once to each in turn. It then distributesthe resulting items among any duplicates.IfThe operand function takes a significant time to evaluate,But has no side-effects,And the argument array has a significant number of duplicate items,Then[each] may produce a significant time saving.Examples:© This rather contrived example takes only 3 seconds to run:Œ „ Œdl each time ?10 10½203.001 2 1 2 1 1 2 2 2 12 2 1 1 2 2 1 1 1 12 2 2 2 2 1 2 1 2 22 1 1 2 1 2 2 2 1 12 2 2 2 1 2 2 1 1 21 1 1 1 1 1 2 2 1 22 2 1 2 1 1 1 2 1 21 1 2 2 1 2 1 2 2 21 1 2 2 2 2 2 2 2 11 1 2 2 2 1 2 1 1 2count„0{count+„1 ª ¾+1}¨ 5 5½1 2 32 3 4 2 34 2 3 4 23 4 2 3 42 3 4 2 34 2 3 4 2© count of operand function calls.© primitive each:25Œ count „ count 0© operand function called 25 times.545


{count+„1 ª ¾+1}each 5 5½1 2 3 © [each]: same result:2 3 4 2 34 2 3 4 23 4 2 3 42 3 4 2 34 2 3 4 23count© operand functin called only 3 times.See also: sam.75 enss.39 time.515ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎgcrGregorian Calendar Reform-------------------------Countries adopted the Gregorian calendar at different times. When using …days„or …date„ for historical dates in other than the UK or Eastern Seaboard USA,use a left argument from the following table:¸°days ¸°date------ ------Albania · · · · 19121201 4731Austria (Salzburg) · 15831005 ¯115494Bulgaria · · · 19160331 5947Czech (Bohemia Moravia) 15840106 ¯115401Denmark · · · · 17000218 ¯72989Egypt · · · · 18750101 ¯9118Finland · · · · 17530217 ¯53631France · · · · 15821209 ¯115794 PGreece · · · · 19240309 8847Italy · · · · 15821004 ¯115860 RIreland · · · · 17520902 ¯53799 LJapan · · · · 18730101 ¯9848 JRussia · · · · 19180131 6618Poland · · · · 15821004 ¯115860 RPortugal · · · 15821004 ¯115860 RSpain · · · · 15821004 ¯115860 RSweden · · · · 17530217 ¯53631Turkey · · · · 19270101 9875UK · · · · · 17520902 ¯53799 LUSA, Eastern Seaboard 17520902 ¯53799 LUSA, Mississippi valley 15821209 ¯115794 PUSA, TX FL CA NV AZ NM 15821004 ¯115860 RUSA, WA OR · · · 17520902 ¯53799 LUSA, AK · · · 18671001 ¯11767R: Same as Rome.L: Same as London.P: Same as Paris.J: The Gregorian calendar replaced the traditional Japanese calendar 1873-01-01.Example:tx_days„15821004°daystx_date„¯115860°dateva_days„17520902°daysva_date„¯53799°date© Texas conversions.© Virginia conversions.© John Rolfe married Pocahontas on 1614-04-05(VA). If guests were expected© from Texas or Florida, the wedding planning must have been a nightmare:3†tx_date va_days 1614 4 5 © Apr 1614: 5 (VA) -> 15 (TX)1614 4 15546


See also: Dates.353 days.356 date.358ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎgrayFull many a gem of purest ray sereneThe dark unfathom'd caves of ocean bear;Full many a flower is born to blush unseen,And waste its sweetness on the desert air.Thomas Gray (1716-1771)ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎhamptonHampton Court Maze------------------The maze at Hampton Court was created for William of Orange, by George Londonand Henry Wise sometime between 1689-95. The actual maze is trapezoidal in shapebut the following s t r e t c h e d version is equivalent. Interestingly, themaze at Castle Bromwich Hall Gardens is a rectangularized version of a mirrorimage of the Hampton Court maze:ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ Û 4 Û Û ÛÛ ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ Û ÚÎÎÎÎÎÎÎÙ 7 ÎÎÎÎÌ Û ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌ ÛÛ Û Û Û Û Û Û ÛÛ Û ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙ Û ÎÎÎÎÂÎÎÎÎ Û ÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌ Û ÛÛ Û Û Û Û Û 9 Û Û ÛÛ Û Û ÚÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎ Û ÎÎÎÎÁÎÎÎÌ ÚÎÎÎÎÎÎÎÌ Û Û ÛÛ Û 3 Û Û Û Û Û Û 10 Û ÛÛ ÀÎÎÎÌ Û Û Û ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÌ Û Û Û Û ÚÎÎÎÙ ÛÛ Û Û Û Û Û Û Û Û Û Û Û ÛÃÎÎÎÎ Û Û Û Û Û 13 Û Û Û Û Û Û 11ÎÎÎÎÝÛ Û Û Û Û Û Û Û Û Û Û Û ÛÛ ÚÎÎÎÙ Û Û Û ÀÎÎÎÌ ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙ Û Û Û Û Û Û ÛÛ Û 5 Û Û Û Û Û Û Û Û Û Û ÛÛ Û Û Û Û ÀÎÎÎÌ Û Û ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙ Û ÃÎÎÎÎÎÎÎÙ Û ÛÛ Û Û Û 6 Û Û Û 8 Û12 Û ÛÛ Û ÀÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÙ Û ÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÙ ÛÛ Û Û ÛÛ ÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÁ---ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÝÛ2 ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ 1 ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙIf we mark intersections and cul-de-sacs as above, we wind up with the followingrather simple undirected graph:Graph:1ÎÎÎ3ÎÎÎ4 13Û Û Û2 5ÎÎÎ7ÎÎÎ9ÎÎ10ÎÎ11Û Û Û Û Û6 ÀÎÎÎ8ÎÎÎÙ 12See also: Graphs.137547


ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎhumour(muse:Humour is but the rehearsal of abstraction.)ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎhyperatorsHyperators¯¯¯¯¯¯¯¯¯¯Functions take arrays as arguments;¯¯¯¯¯¯¯¯¯ ¯¯¯¯¯¯ ¯¯¯¯¯¯¯¯¯Operators take <strong>functions</strong> (and arrays) as operands;¯¯¯¯¯¯¯¯¯ ¯¯¯¯¯¯¯¯¯ ¯¯¯¯¯¯¯¯Q: What takes operators?Hyperators take operators (and <strong>functions</strong> (and arrays)) as hyperands.¯¯¯¯¯¯¯¯¯¯ ¯¯¯¯¯¯¯¯¯ ¯¯¯¯¯¯¯¯¯Clearly, this is a never-ending sequence.A proof of the (need for the) existence of hyperators:0. We like to write tools that deal with <strong>APL</strong> entities (arrays, <strong>functions</strong>, operators)as subjects. For example, we like to:- Format them by drawing boxes around subarrays and by aligning the commentswithin the source code of <strong>functions</strong> and operators.- Search for text within the character representations of these entities.- Determine the amount of worspace they occupy.- ... and so on.1. <strong>APL</strong> entities may be named: "vec", "sum", "twice" or not: 'ab', +/, {¸¸ ¸¸ ¾}.2. For named entities, we have the rather ugly option of passing the name to thetool: ŒSIZE'vec', ŒAT'sum', ŒCR'twice', ...3. For unnamed entities, we do not have this option.- To examine an unnamed array, we must pass it as argument to the analysisfunction. ¯¯¯¯¯ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯- To examine an unnamed function, we must pass it as operand to an operator.¯¯¯¯¯¯¯¯ ¯¯¯¯¯¯¯ ¯¯¯¯¯¯¯¯- To examine an unnamed operator, we must pass it as hyperand to a hyperator.¯¯¯¯¯¯¯¯ ¯¯¯¯¯¯¯¯ ¯¯¯¯¯¯¯¯¯- ... and so on.Q.E.D.ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎkbmacKeyboard for Mac Laptop-----------------------NB: <strong>Dyalog</strong> Mac keyboards use Alt as the <strong>APL</strong> key, so for "½" we press Alt+r andfor "“", Alt+Shift+4.This is a standard OS X keyboard layout but with <strong>APL</strong> characters overwriting muchof the Alt+ set. This means that all other keystroke combinations should behaveas expected.548


<strong>Dyalog</strong> Mac <strong>APL</strong>/UK keyboard--------------------------ÚÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÎÎÎÎÎÌÛ+- Û! • Û@ • Û£ ” Û$ “ Û% ² Û^ ³ Û& ´ Û* µ Û( ‹ Û) Š Û_ ! Û+ Ž ÛBackspaceÛÛ§ ª Û1 ¨ Û2 ¯ Û3 < Û4 ˆ Û5 = Û6 ‰ Û7 > Û8 ¬ Û9 Ÿ Û0 ^ Û- × Û= ÷ Û ÛÃÎÎÎÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÎÎÎÎÎÝÛTab ÛQ ÛW ÛE º ÛR ÛT þ ÛY ÛU ÛI ¼_ÛO ±¨ÛP ÿ Û{ • Û} « ÛEnter ÛÛ Ûq ? Ûw ¾ Ûe ¹ Ûr ½ Ût ~ Ûy † Ûu ‡ Ûi ¼ Ûo ± Ûp * Û[ „ Û] … Û ÛÃÎÎÎÎÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÌ ÛÛCaps ÛA ÛS ÛD ÛF ÛG ÛH ÛJ °¨ÛK Œ=ÛL ¦ Û: ­ Û" » Û| Û ÛÛLock Ûa ¸ Ûs — Ûd ˜ Ûf _ Ûg ’ Ûh ‘ Ûj ° Ûk ' Ûl Œ Û; – Û' • Û\ # Û ÛÃÎÎÎÎÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÎÎÁÎÎÎÎÎÝÛShift Û~ • ÛZ ÛX ÛC ÛV ÛB ÛN ÛM Û< ® Û> • Û? Œ:ÛShift ÛÛ Û• € Ûz › Ûx œ Ûc • Ûv ž Ûb ƒ Ûn ‚ Ûm | Û, © Û. Û/ š Û ÛÃÎÎÎÎÎÎÁÂÎÎÎÁÎÂÎÎÁÎÎÎÂÁÎÎÎÎÁÎÎÎÎÁÎÎÎÎÁÎÎÎÎÁÎÎÎÎÁÂÎÎÎÁÎÎÂÎÁÎÎÎÎÏÎÎÎÎÎÂÎÎÎÎÎÎÝÛCtrl ÛWin ÛAlt Û ÛAlt GrÛWin ÛMenu ÛCtrl ÛÛ Û Û Û Û Û Û Û ÛÀÎÎÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÁÎÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÎÙNote the following differences from the standard <strong>Dyalog</strong> <strong>APL</strong>/UK keyboard:# uses Alt+\@ and " change places• and ~ are lower left\ and | are next to the Enter keySee [OS X] tab in: http://www.dyalog.com/apl-font-keyboard.htm for download.See also: keyboards.451 kbolay.547ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎkbolayUS <strong>APL</strong> Keyboard Overlay¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ÚÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÎÎÎÎÎÌÛ Û • Û • Û ” Û “ Û ² Û ³ Û ´ Û µ Û ‹ Û Š Û ! Û Ž ÛBackspaceÛÛ ª Û ¨ Û ¯ Û < Û ˆ Û = Û ‰ Û > Û ¬ Û Ÿ Û ^ Û × Û ÷ ÛÛÃÎÎÎÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÎÎÎÎÎÝÛTab Û Û Û º Û Û þ Û Û Û ¼_Û ±¨Û ÿ Û • Û « Û • ÛÛ Û ? Û ¾ Û ¹ Û ½ Û ~ Û † Û ‡ Û ¼ Û ± Û * Û „ Û … Û € ÛÃÎÎÎÎÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÎÎÎÎÎÎÝÛCaps Û Û Û Û Û Û Û °¨Û Œ=Û ¦ Û ­ Û » ÛEnter ÛÛLock Û ¸ Û — Û ˜ Û _ Û ’ Û ‘ Û ° Û ' Û Œ Û – Û • Û ÛÃÎÎÎÎÎÎÎÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÎÎÎÎÎÎÎÎÝÛShift Û Û Û Û Û Û Û Û ® Û • Û Œ:ÛShift ÛÛ Û › Û œ Û • Û ž Û ƒ Û ‚ Û | Û © Û Û š Û ÛÃÎÎÎÎÎÎÎÂÎÎÎÁÎÂÎÎÁÎÎÎÂÁÎÎÎÎÁÎÎÎÎÁÎÎÎÎÁÎÎÎÎÁÎÎÎÎÁÂÎÎÎÁÎÎÂÎÁÎÎÎÎÏÎÎÎÎÎÂÎÎÎÎÎÎÝÛCtrl ÛWin ÛAlt Û ÛAlt GrÛWin ÛMenu ÛCtrl ÛÛ Û Û Û Û Û Û Û ÛÀÎÎÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÁÎÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÎÙ549


Generic European <strong>APL</strong> Keyboard Overlay¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ÚÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÎÎÎÎÎÌÛ Û • Û • Û ” Û “ Û ² Û ³ Û ´ Û µ Û ‹ Û Š Û ! Û Ž ÛBackspaceÛÛ ª Û ¨ Û ¯ Û < Û ˆ Û = Û ‰ Û > Û ¬ Û Ÿ Û ^ Û × Û ÷ ÛÛÃÎÎÎÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÎÎÎÎÎÝÛTab Û Û Û º Û Û þ Û Û Û ¼_Û ±¨Û ÿ Û • Û « ÛEnter ÛÛ Û ? Û ¾ Û ¹ Û ½ Û ~ Û † Û ‡ Û ¼ Û ± Û * Û „ Û … Û ÛÃÎÎÎÎÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÂÎÎÎÁÌ ÛÛCaps Û Û Û Û Û Û Û °¨Û Œ=Û ¦ Û ­ Û » Û Û ÛÛLock Û ¸ Û — Û ˜ Û _ Û ’ Û ‘ Û ° Û ' Û Œ Û – Û • Û Û ÛÃÎÎÎÎÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÂÎÁÎÎÎÎÁÎÎÎÎÎÝÛShift Û • Û Û Û Û Û Û Û Û ® Û • Û Œ:ÛShift ÛÛ Û € Û › Û œ Û • Û ž Û ƒ Û ‚ Û | Û © Û Û š Û ÛÃÎÎÎÎÎÎÁÂÎÎÎÁÎÂÎÎÁÎÎÎÂÁÎÎÎÎÁÎÎÎÎÁÎÎÎÎÁÎÎÎÎÁÎÎÎÎÁÂÎÎÎÁÎÎÂÎÁÎÎÎÎÏÎÎÎÎÎÂÎÎÎÎÎÎÝÛCtrl ÛWin ÛAlt Û ÛAlt GrÛWin ÛMenu ÛCtrl ÛÛ Û Û Û Û Û Û Û ÛÀÎÎÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÁÎÎÎÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÎÙWindows Keyboards - Numeric keypad¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ÚÎÎÎÎÂÎÎÎÎÂÎÎÎÎÌ ÚÎÎÎÎÂÎÎÎÎÂÎÎÎÎÂÎÎÎÎÌÛ Û Û Û ÛNum Û Û Û ÛÛIns ÛHomeÛPgUpÛ ÛLockÛ/ Û* Û- ÛÃÎÎÎÎÏÎÎÎÎÏÎÎÎÎÝ ÃÎÎÎÎÏÎÎÎÎÏÎÎÎÎÏÎÎÎÎÝÛ Û Û Û Û Û Û Û ÛÛDel ÛEnd ÛPgDnÛ Û7 Ú Û8  Û9 Ì Û ÛÀÎÎÎÎÁÎÎÎÎÁÎÎÎÎÙ ÃÎÎÎÎÏÎÎÎÎÏÎÎÎÎÝ ÛÛ Û Û Û ÛÛ4 à Û5 Ï Û6 Ý Û+ ÛÚÎÎÎÎÌ ÃÎÎÎÎÏÎÎÎÎÏÎÎÎÎÏÎÎÎÎÝÛ Û Û Û Û Û ÛÛ† Û Û1 À Û2 Á Û3 Ù ÛEn- ÛÚÎÎÎÎÏÎÎÎÎÏÎÎÎÎÌ ÃÎÎÎÎÁÎÎÎÎÏÎÎÎÎÝter ÛÛ Û Û Û Û Û Û ÛÛ„ Û‡ Û… Û Û0 Î Û. Û Û ÛÀÎÎÎÎÁÎÎÎÎÁÎÎÎÎÙ ÀÎÎÎÎÎÎÎÎÎÁÎÎÎÎÁÎÎÎÎÙSee also: keyboards.451 kbmac.546550


ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎkonigsbergA "planar" graph is one that may be drawn on the 2-D plane with its edges intersectingonly at its vertices.·Examples include:·- A map of a country's adjacent states or territories.- The layout of a maze or a city street plan.·An example of the latter is the arrangement of seven bridges over a fork in theriver at Königsberg (now Kaliningrad in Western Russia). One of the earliestachievements in graph theory was a proof in 1735 by Swiss mathematician LeonhardEuler, that is it impossible to walk over each bridge exactly once.·Here is a map of the area, together with a picture of the correspondinggraph (*) and its coding; the four areas of land adjacent to the river are consideredvertices, and the bridges, edges:·Map Ì Ú Ì Ú [1] Ì Ú--- ÚÎÎÎÎÎÎÛ ÛÎÎÎÎÎÛ ÛÎÎÎÎÎÎÎÎÎÎÎÛ ÛÎÎÎÎÎÎÛ~~~~~~Û Û~~~~~Û Û~~~~~~~~~~~Û Û~~~~~~~Û~~~ÚÎÎÛ ÛÎÎÎÎÎÛ ÛÎÎÎÌ~~~ÚÎÎÎÛ ÛÎÎÎÎÎÎÎÎÛ~~~Û Ù À Ù À Û~~~Û Ù ÀÛ~~~Û [2] ÀÎÎÎÎÎÙÛ~~~Û Ì Ú Ì Ú ÚÎÎÎÎÎÌÎÎÎÎÎÙ~~~ÀÎÎÛ ÛÎÎÎÎÎÛ ÛÎÎÎÙ~~~Û [3]~~~~~~~~~~~Û Û~~~~~Û Û~~~~~~~ÛÎÎÎÎÎÎÎÎÎÎÎÛ ÛÎÎÎÎÎÛ ÛÎÎÎÌ~~~ÛÙ À Ù À Û~~~Û Ì Ú[4] Û~~~ÀÎÎÎÛ ÛÎÎÎÎÎÎÎÛ~~~~~~~Û Û~~~~~~~~ÀÎÎÎÎÎÎÎÛ ÛÎÎÎÎÎÎÎÎÎGraphÙ À----- ÚÎÎÎ1ÎÎÎÌÛ Û Û Coding: (2 2 3)(1 1 3 4 4)(1 2 4)(2 2 3)Û Û ÛÃÎÎÎ2ÎÎÎ3Û Û ÛÛ Û ÛÀÎÎÎ4ÎÎÎÙ·Euler's masterstroke was in considering _vertices_, rather than _edges_ whenthinking about the problem. His proof went something along the lines of:·The number of edges issuing from a vertex is called its "degree". To succeed allbut the starting and finishing vertices must have an even degree (correspondingwith an entry to, and exit from the vertex). This cannot be the case in Königsberg,as more than two vertices have an odd degree.·(*) Note that the graph above is strictly a "pseudo-" or "multi-" graph as somevertices are connected by more than one edge. This is apparent from duplicateitems in the graph coding: {~¾­ž¨¾}.·An example of a non-planar graph is any complete graph of size>4:·comp„{¾°{¸~¾}¨¾}°¼ © order ¾ complete graph.·disp comp 5Ú…ÎÎÎÎÎÎÂÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÌÛ2 3 4 5Û1 3 4 5Û1 2 4 5Û1 2 3 5Û1 2 3 4ÛÀ~ÎÎÎÎÎ…Á~ÎÎÎÎÎ…Á~ÎÎÎÎÎ…Á~ÎÎÎÎÎ…Á~ÎÎÎÎÎ…Ù551


ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎloop(eval ##.loop)stop© input-eval-display loop.[loop] uses quote-quad (•) to prompt for, and input, a character vector argumentfor evaluation by operand function [eval]. Output from the evaluation is displayedin the session and the loop repeated until character vector [stop] is input.In particular, if [stop] is the null vector '', then loop continues untilan empty line is entered.This operator is sometimes referred to as "REPL", a read-eval-print loop:http://en.wikipedia.org/wiki/Read-eval-print_loopTechnical note:In order to make its error-guard visible from the operand function, [loop] callsthe function from an –. This bypasses the operator's local-hiding mechanism andleaves the error-guard in-scope.Examples:² loop'…' © reverse of input.helloollehworlddlrow…Œsize loop ')'display© size of object3588loop684notes1363400)– loop '' © mini-session until null input.2+35¼31 2 3disp°– loop')'© boxed output1 2 + 3 44 61 2 + ›3 4Ú…ÎÎÂÎÎÎÌÛ4 5Û5 6ÛÀ~Î…Á~Î…Ù}}} © errorEh?)scripts._defs°parse loop'…'© bind left arg for dyadic fuction: …parse„2+3AÚÁÎÌÚÁÌ 32 +552


°.+/m nAÚÎÎÁÎÎÌÚÎÁÎÎÌ ÚÁÌÚÁÎÌ / m n° ÚÁÌ. +…See also: parse.237 esh.275 lisp.236ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎmusonA number of the notes in this workspace contain sections that are merely themusings of the author. They may not be entirely factual and you should check thecontent with say, Wikipedia, before repeating them to a discerning audience. Forexample:(muse:·A muse is a compound of "musons"; the elementary particles of consciousness;the atoms of our mental world. More complex patterns, such as our views onpolitics, religion, country music, and so forth, are constructed from clustersof these units.·An example of a muson might be the fleeting intention to buy more trash-canliners. In isolation, the muson is typically temporary and inconsequential;anything smaller does not register on EEG.·The human mind is characterized by its ability to build large and enduringstructures from such particles, while other animals get by with much simplercombinations. For a dog, memory-of-rabbit is about as fancy as it gets.·Some meditation regimes may be seen as the attempt to dwell for extendedperiods within a single muson. The most successful exponent of this turnsout to be the common oyster (Ostrea edulis), which spends its entire mentallife within the sole muson of which it is capable.·Although there is no direct human equivalent of the oyster's muson, anapproximation might be something midway between an appreciation of sea waterand a vague yearning for locomotion.)But see: seme (semantics), meme (memetics) and morpheme (linguistics).ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎnumbers(muse:<strong>APL</strong> Numbers¯¯¯¯¯¯¯¯¯¯¯Classic <strong>APL</strong> recognises only "numbers"; it has no interest in their internalrepresentation in binary integer or floating point form.Sometimes confused with this internal data type, is the fact that some primitive<strong>functions</strong> have restricted argument domains. For example, the "Boolean"<strong>functions</strong> ^ Ÿ Š ‹ take only arrays of numbers in the set 0 1; the items ofthe left argument of reshape (½) must be "natural" (non-negative, whole)numbers 0 1 2 ...; and the relational <strong>functions</strong> < ˆ ‰ > take only thosenumbers whose imaginary part is 0. We can see this distinction with expressionssuch as:553


1 ^ 2.5-3÷2 © right argument of ^ is 0 or 11(-¯3) ½ 3 © left argument of ½ is non-negative whole number3 3 3As a thought experiment, we could propose an <strong>APL</strong> that supported only rational,or even only whole, numbers. In the latter case, 21÷3 would return 7 but21÷2 would generate a domain error. This is analogous to an <strong>APL</strong> that doesn'tprovide complex numbers, where ¯1*÷3 returns ¯1 but where ¯1*÷2 is a domainerror.This brings to mind the sequence of generalisation:N › Z › Q › R › C › H › O.Prefacing this list with B, the boolean numbers 0 and 1, gives:B Booleans: 0 1 © Boole G. 1815-1864› N Natural numbers: 0 1 2 ...› Z Integers: ... ¯2 ¯1 0 1 2 ...› Q Rationals: (4÷3) (¯7÷13) ...› R Reals: (*1) (±1) (2*÷2) ...› C Complex: 3j4 (¯1*÷2) ...› H Quaternions © Hamilton W.R. 1805-1865› O Octonions © Graves J.T. 1806-1870At each step, we gain generality in exchange for some loss of structure. Forexample, going from R to C to H to O, we lose respectively: ordering, commutativityand associativity.This table illustrates the capabilities of an <strong>APL</strong> system for each of the increasinglygeneral number systems:ÚÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÌÛ B Û N Û Z Û Q Û R Û C ÛÚÎÎÎÎÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝÛ 0Ÿ1 Û Y Û Y Û Y Û Y Û * Û * ÛÃÎÎÎÎÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝÛ 2+3 Û - Û Y Û Y Û Y Û Y Û Y ÛÃÎÎÎÎÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝÛ 2-3 Û - Û - Û Y Û Y Û Y Û Y ÛÃÎÎÎÎÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝÛ 2÷3 Û - Û - Û - Û Y Û Y Û Y ÛÃÎÎÎÎÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝÛ 2*÷2 Û - Û - Û - Û - Û Y Û Y ÛÃÎÎÎÎÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝÛ ¯1*÷2 Û - Û - Û - Û - Û - Û Y ÛÀÎÎÎÎÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÙ* GCD (…gcd„) is not meaningful for irrational numbers. In order to provideGCD/LCM for its internal floating-point numbers, <strong>Dyalog</strong> uses as many termsof their continued fraction (…cfract„) expansion as necessary to produce atolerably close rational approximation.)N http://en.wikipedia.org/wiki/Natural_numberZ http://en.wikipedia.org/wiki/IntegerQ http://en.wikipedia.org/wiki/Rational_numberR http://en.wikipedia.org/wiki/Real_numberC http://en.wikipedia.org/wiki/Complex_numberH http://en.wikipedia.org/wiki/QuaternionO http://en.wikipedia.org/wiki/Octonianhttp://en.wikipedia.org/wiki/Sedenion…nats„…rats„…cxdraw„554


ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎpearlyOn Arriving at the Pearly Gates-------------------------------On arriving at the Pearly Gates, if you have been thinking and coding in a declarativestyle, be sure to mention this to an official, who will fast-track youthrough.In days-gone-by, this would have made little difference. The old wrought-ironGates were at the end of a winding path; atop a grassy hill; betwixt high, whitewalls; 'neath a clear, blue sky. You would just chip up; press the bell; andwait for Saint Peter to show you in.However, with the steady year-on-year increase in traffic, the Gate Area now resemblesthe immigration hall at JFK; the lines zig-zag out of sight and youcan't quite hear the announcements. You'll be glad of any little advantage.(One test They use is to see whether your end-of-line comments are predominantlynoun-phrases, rather than imperatives.²¸ © reverse ¸ (imperative indicates procedural thinking)²¾ © the reverse of ¾ (noun phrase suggests declarative thinking)¯¯¯¯¯n„+/v © add up v and assign it to n (procedural)n„+/v © n is the sum of the items of v (declarative)¯¯ ¯¯¯Of course, you could rip through and edit your comments but They have otherways ...They might ask you to read "m„0" aloud:"m gets zero" (procedural)"m becomes zero" (procedural)"zero m"(procedural)"m is zero" (declarative)"m names zero" (declarative)"m indicates zero" (declarative)"m is specified as zero" (declarative - KEI)"m denotes zero" (declarative - SJT)They might ask what happens when the interpreter evaluates m„0:"It assigns the value zero to m""It assigns the name m to zero"(procedural)(declarative)For a declarative view of the world, it may be helpful to visualise "„" as aright-pointing finger, rather than as a left-pointing arrow (in the same waythat € is a right-pointing tack).Regarding assignment: at a baby-naming ceremony we (with the possible exceptionof some folk in the pop music industry) usually think of assigningthe name to the baby, rather than the baby to the name.And finally:"<strong>APL</strong> evaluates right-to-left""<strong>APL</strong> <strong>functions</strong> apply to everything to their right"(procedural)(declarative)12÷1+2 © two added to one then divided into twelve (procedural)12÷1+2 © twelve divided by: one plus two (declarative)and for a pop at a place at Top Table, you might suggest that J„2+I be verbalised:555


J„2+I © J denotes the second successor of the referent of I)See: http://dfns.dyalog.com/downloads/howcomp.pdfSee also: declarative.534 muson.551ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎpigeonsFolklore has it that: "Nobody ever saw a baby pigeon."It turns out that adult pigeons come into existence spontaneously, often in midair,sometimes at high altitude, with a flurry of feathers and a loud THWOPPsound, reminiscent of one of those cardboard and brown paper kite-shaped thwoppers,occasionally free with the Beano.Some commentators think that the pigeon is surprised by the event but philosophersargue that this is not so: surprise is the experience of the sudden changefrom one subjective state to another and in this case there is no prior state.See also: muson.551ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎqueensXExact cover N-Queens--------------------The N-Queens puzzle may be expressed and solved as an exact cover problem:queensX„{© Exact cover N-Queens.m„¼3/¾© cell coordinate properties.r„=/¨1 0 1°/¨m © each rank must contain one queen.f„=/¨0 1 1°/¨m © .. file .. .. ..}dm„-/¨¼2/¾du„{¾[“¾]}ž,dmy„´x„dm°.=dum„,[¼2]x,y,r,fd„~(¼1‡½m)¹¼2×½du¾ ¾½d X m© diagonal labels.© unique labels.© x and y diagonals.© constraints matrix.© mask of required cols.© exact cover - matrix of queens.© A solution for each of first 9 N-Queens problems:0 1 0 disp queensX¨ 0 to 8ÚÂÎÂÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛÛ1Û0 0Û0 0 0Û0 1 0 0Û0 0 0 0 1Û0 0 0 0 1 0Û0 0 0 0 0 0 1Û0 0 0 0 0 0 0 1ÛÛÛ Û0 0Û0 0 0Û0 0 0 1Û0 1 0 0 0Û0 0 1 0 0 0Û0 0 0 0 1 0 0Û0 0 0 1 0 0 0 0ÛÛÛ Û Û0 0 0Û1 0 0 0Û0 0 0 1 0Û1 0 0 0 0 0Û0 0 1 0 0 0 0Û1 0 0 0 0 0 0 0ÛÛÛ Û Û Û0 0 1 0Û1 0 0 0 0Û0 0 0 0 0 1Û1 0 0 0 0 0 0Û0 0 1 0 0 0 0 0ÛÛÛ Û Û Û Û0 0 1 0 0Û0 0 0 1 0 0Û0 0 0 0 0 1 0Û0 0 0 0 0 1 0 0ÛÛÛ Û Û Û Û Û0 1 0 0 0 0Û0 0 0 1 0 0 0Û0 1 0 0 0 0 0 0ÛÛÛ Û Û Û Û Û Û0 1 0 0 0 0 0Û0 0 0 0 0 0 1 0ÛÛÛ Û Û Û Û Û Û Û0 0 0 0 1 0 0 0ÛÀÁÎÁÎÎÎÁÎÎÎÎÎÁÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙTechnical notes:Function [queensX] constructs a boolean constraint matrix m, in which the colmumsrepresenting diagonals are optional. As an example, the final constraintsmatrix for the inner function for a 4-Queens problem has these regions:556


ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ x-diagonal requirementsÛ ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ y-diagonal .. ..Û Û ÚÎÎÎÎÎÎÎÎÎÎÎÎ rank (row) .. ..Û Û Û ÚÎÎÎÎ file (col) .. ..Û Û Û ÛÚÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÌÛ0 0 0 1 0 0 0Û0 0 0 0 0 0 1Û1 0 0 0Û1 0 0 0ÛÛ0 0 1 0 0 0 0Û0 0 0 0 0 1 0Û1 0 0 0Û0 1 0 0ÛÛ0 1 0 0 0 0 0Û0 0 0 0 1 0 0Û1 0 0 0Û0 0 1 0ÛÛ1 0 0 0 0 0 0Û0 0 0 1 0 0 0Û1 0 0 0Û0 0 0 1ÛÛ0 0 0 0 1 0 0Û0 0 0 0 0 1 0Û0 1 0 0Û1 0 0 0ÛÛ0 0 0 1 0 0 0Û0 0 0 0 1 0 0Û0 1 0 0Û0 1 0 0ÛÛ0 0 1 0 0 0 0Û0 0 0 1 0 0 0Û0 1 0 0Û0 0 1 0ÛÛ0 1 0 0 0 0 0Û0 0 1 0 0 0 0Û0 1 0 0Û0 0 0 1ÛÛ0 0 0 0 0 1 0Û0 0 0 0 1 0 0Û0 0 1 0Û1 0 0 0ÛÛ0 0 0 0 1 0 0Û0 0 0 1 0 0 0Û0 0 1 0Û0 1 0 0ÛÛ0 0 0 1 0 0 0Û0 0 1 0 0 0 0Û0 0 1 0Û0 0 1 0ÛÛ0 0 1 0 0 0 0Û0 1 0 0 0 0 0Û0 0 1 0Û0 0 0 1ÛÛ0 0 0 0 0 0 1Û0 0 0 1 0 0 0Û0 0 0 1Û1 0 0 0ÛÛ0 0 0 0 0 1 0Û0 0 1 0 0 0 0Û0 0 0 1Û0 1 0 0ÛÛ0 0 0 0 1 0 0Û0 1 0 0 0 0 0Û0 0 0 1Û0 0 1 0ÛÛ0 0 0 1 0 0 0Û1 0 0 0 0 0 0Û0 0 0 1Û0 0 0 1ÛÃÎÎÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÝÛ1 0 0 0 0 0 0 0 0 0 0 0 0 0Û0 0 0 0 0 0 0 0ÛÛ0 1 0 0 0 0 0 0 0 0 0 0 0 0Û0 0 0 0 0 0 0 0ÛÛ0 0 1 0 0 0 0 0 0 0 0 0 0 0Û0 0 0 0 0 0 0 0ÛÛ0 0 0 1 0 0 0 0 0 0 0 0 0 0Û0 0 0 0 0 0 0 0ÛÛ0 0 0 0 1 0 0 0 0 0 0 0 0 0Û0 0 0 0 0 0 0 0ÛÛ0 0 0 0 0 1 0 0 0 0 0 0 0 0Û0 0 0 0 0 0 0 0ÛÛ0 0 0 0 0 0 1 0 0 0 0 0 0 0Û0 0 0 0 0 0 0 0ÛÛ0 0 0 0 0 0 0 1 0 0 0 0 0 0Û0 0 0 0 0 0 0 0ÛÛ0 0 0 0 0 0 0 0 1 0 0 0 0 0Û0 0 0 0 0 0 0 0ÛÛ0 0 0 0 0 0 0 0 0 1 0 0 0 0Û0 0 0 0 0 0 0 0ÛÛ0 0 0 0 0 0 0 0 0 0 1 0 0 0Û0 0 0 0 0 0 0 0ÛÛ0 0 0 0 0 0 0 0 0 0 0 1 0 0Û0 0 0 0 0 0 0 0ÛÛ0 0 0 0 0 0 0 0 0 0 0 0 1 0Û0 0 0 0 0 0 0 0ÛÛ0 0 0 0 0 0 0 0 0 0 0 0 0 1Û0 0 0 0 0 0 0 0ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙÛÛÛÀÎÎÎÎÎÎÎÎ padding for required reqts.ÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ dummy rows for optional reqts.See also: X.160 queens.481ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎquotesKDF9 Manual, 1961-----------------KDF9 is the acme of advanced thought and design in electronic computers; nowhereis this more true than in the design of the nesting store which combines maximumecomony in programming with maximum operating speed.A nesting store is, in effect, a series of sixteen registers holding a column ofitems of data, with the rule that an incoming item joins the column at the topand causes all the items alreadv present to move down one place. Similarly, anitem can be transferred out of the column only from the top, and when this happensall the remaining items move up one place.557


ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎratrepAuthor:LeRoy N. EideCreated: 03-Apr-2008Modified: 12-Jul-2008Charset: US-ASCII; Displays best with a mono-spaced font; Lines no longer than 79 charactersThe following is a somewhat brief description of a representation schemefor rational numbers -- including some discussion about addition andsubtraction of numbers so represented. Most of this is derived frompersonal thoughts and notes developed over the past few years.===============================================================================Consider the bi-directionally infinite polynomial in b... + d[2]*b^(2) + d[1]*b^(1) + d[0]*b^(0) + d[-1]*b^(-1) + ...where: + * ^ mean respectively addition, multiplication, and exponentiation;- is used conventionally as a negation sign (and also subtraction);... (ellipsis) is used conventionally for (possibly) omitted materialand where "x...y" means that "y differs from x";.. (short ellipsis) is used for possibly omitted materialand where "x..y" means that "y may be identical to x";d[i] means "d sub i for some integer i", i.e. the coefficient of b^(i),and each d[i] is a member of an ordered set of "digits" ofcardinality b, one of which is chosen to represent the valuezero, e.g. {..,0,..}, implying that b > 0 (a non-empty set)but in practice it is assumed that b > 1.The polynomial above is generally given as the interpretation of a"number" as typically written, e.g.123.95where b is assumed to be ten and d's are chosen from the ordered set{0,1,2,3,4,5,6,7,8,9}, i.e. d[2]=1, d[1]=2, d[0]=3, d[-1]=9, d[-2]=5.The zero digit is conventionally represented by the character '0'; otherdigits in this ordered set are also assumed to represent integer valuesdescending (to the left) or ascending (to the right) in steps of one.Also, the (radix) point is conventionally placed between the d[0] and d[-1]digits (although it should arguably be placed beneath the d[0] digit). Andzeros are conventionally thought of (but generally unwritten) as extendinginfinitely on both sides of the written number.So much for convention.===============================================================================Euler's Claim:-------------S(x) = ... + x^(3) + x^(2) + x^(1) + x^(0) + x^(-1) + x^(-2) + x^(-3) + ...orSUM(x^i) over all integers iis identically zero for all x.At first blush this seems preposterous, but there are some plausiblereasons to suspect the (computational) truth to this claim. Withoutexpounding much, simply consider the implications of:x*S(x) - S(x) = 0The Author accepts Leonhard Euler's claim in the discussion that follows.558


===============================================================================The Notation used herein is described below. Be patient -- it starts outlooking rather ugly but becomes increasingly beautiful (and useful) aftera little development ...-------------------------------------------------------------------------------The Digits:----------An ordered set of digits (symbols) are separated by commas and enclosed incurly braces, e.g.or{0,1,2,3,4,5,6,7,8,9} also {0,...,9}{-,0,+}but if all of the digits are single characters, the commas may be omitted,e.g.or{0123456789} also {0...9}{-0+}An ellipsis is never used if the omitted content is not obvious fromcontext.If it is unclear which digit represents zero, that digit is enclosedin parentheses (which may also act as digit separators if commas wouldotherwise be needed), e.g.{M(Z)P} or {M,(Z),P}but the use of commas is encouraged if there are any multi-character digitssince{MINUS,(ZERO),PLUS}would be ambiguous without the commas.The primary consequence of designating some digit to be the zero is thatthe location of the zero digit entirely determines the characteristics ofthe addition and subtraction (and multiplication) tables.The set of digits, if specified, is always mentioned external to (andusually following) the number being represented, e.g.123.95 {0123456789}If the set of digits is conventional or obvious from context, the set ofdigits won't be mentioned at all.Note that digits may be represented by "non-digit" symbols but the use ofany of the following characters as digits should (and will) be avoided:{ } [ ] ( ) < > \ | / : , .All of these characters except ':' are used in the rational numberrepresentation described herein; ':' is used notationally in thecomputation apparatus (described below). The characters+ - 0 = #559


are also used in the computation apparatus but in a manner that causesno conflict with their simultaneous use as digits. Additionally, thecharacter '~' is used to indicate a complement but, again, this usagecauses no conflict with its use as a digit.The characters '+', '-', and '0' are used for additive and subtractivecarries regardless of base; think of these as "positive one", "negativeone", and "zero" respectively.Of special note is the use of '=' for double-minus and '#' for double-plusdigits (except where pressed into service for "equality" and "inequality").The digits '0' through '9', the point '.', and also the characters[ ] ( ) < > \ | / * ^ + - =are used mathematically in conventional ways; these uses will be clear fromcontext (or with an explanatory note if needed).An attempt is made to distinguish symbols from values by enclosing symbolsin single quotes (e.g. '0') and spelling out values (e.g. zero). But sinceeverything is symbolic at some level, the reader will need to resolve manysymbol vs. value conflicts from context.-------------------------------------------------------------------------------The Base:--------If needed, the base b may be noted in square brackets where the baseitself (possibly signed) is written in conventional base ten, for example[10] or [3]. Otherwise, the base may be inferred from the cardinality ofthe specified set of digits (if present) or from context.The base, if specified, is always mentioned external to (and usuallyfollowing) the number being represented, e.g.123.95 [10]-------------------------------------------------------------------------------The Number and Its Infinite Extensions:--------------------------------------Two bars delimit what is generally considered the number proper.If powers of the base increase to the left, \'s are used: \123.95\If powers of the base increase to the right, /'s are used: /59.321/The intended mnemonics are: \ rises to the left, / rises to the right.In either case, the infinite sequence of zeros to both the left and rightare also always indicated with angle brackets as or where the point appears between the digits that are the coefficients of theb^(0) and b^(-1) terms of the representative polynomial in b.If the digits of the number are multi-character, commas are used to separatethe digits one from another (the point, if present, as well as \ or / mayalso act as digit separators), e.g. [10] {(_),I,II,III,IV,V,VI,VII,VIII,IX}-------------------------------------------------------------------------------560


The Point and Scale Factor:--------------------------Note that the (radix) point cannot appear outside of the enclosing bars!If the point is omitted, it is assumed to be nestled in the (inside) acutecorner of one of the bars, e.g. means and means both of which represent the answer to life, the universe, and everything!As previously mentioned, it would be preferable to designate the locationof the point by, well, just "pointing" at the digit that is thecoefficient of b^(0) -- something like^possibly with an integer "scale factor" (in conventional base ten) placedbelow, e.g.^-2All of which gets rather notationally messy.As a compromise (and to avoid multi-line notation), the point may bereplaced by a (possibly signed) scale factor wrapped in round brackets(i.e. parentheses), e.g. or Note that '.' is simply shorthand for '(0)'. Think of '()' as a "reallybig dot" with a (base ten) integer written inside of it. This "dot" maybe moved either right or left as needed, its contained integer increasingif moving "upward" (toward higher powers of the base) or decreasing ifmoving "downward" (toward lower powers of the base) -- just think of"upward" as "left" for \\ or "right" for //, else "downward". All of thisis, of course, nothing more than a sort of embedded scientific notation.In any case, the point (or the really big dot with enclosed scale factor)must always remain between the bars.-------------------------------------------------------------------------------The Bars:--------The \\ and // bar notations are themselves without much grace.If one conventionally (and always) writes numbers only in one direction orthe other, then it's cleaner (and clearer) to use vertical bars instead.This usage will be adopted from here on, using || for \\ throughout unlesssome non-obvious distinction needs to be drawn. means unless otherwise noted.561


Note that Arabic actually writes its numbers low-order digit first -- butsince those numbers are written right-to-left, they appear to be the"same" as ours. Historically, when the West adopted the Arabic way ofwriting numbers, it didn't correct for the direction in which they werewritten ... it seems to have been a sufficient accomplishment that theconcept of zero was finally accepted (perhaps for no other purpose than asa placeholder for a "missing digit"). We have by now generally acceptedzero as an actual digit, but a lot more acceptance is going to be neededin much of what follows!-------------------------------------------------------------------------------The Replication Units:---------------------The Right Replication (or Repetition) Unit (hereinafter the RRU) indicatesthe repeating sequence of digits that go ever onward for decreasing powersof the base. Examples: means 0.0000... or more simply |0> means 0000... means 0.3333... |3> means 3333... means 0.1414... |14> means 1414...The following are allowed for an RRU:a) Internal replication -- |14> may be rewritten as |1414> or |141414> or ...b) Internal contraction -- |829829> may be rewritten as |829>c) External emission -- |567> may be rewritten as 5|675> or 56|756> or ...d) External absorption -- 12|312> may be rewritten as 1|231> or |123>In (c) and (d) above, care must be taken to explicitly fix the pointpreceding the bar before un-rolling and/or re-rolling the infinite spoolof repeating digits across the bar; the point cannot simply be assumed toimmediately precede the bar nor can the point be absorbed into the spoolof digits. If necessary, the point can always be converted into a scalefactor and then moved as needed (while appropriately adjusting the scalefactor, of course).In (d) above, a digit can be absorbed only if it could have beenpreviously emitted. Also note that both emission and absorptionappropriately rotate the RRU contents (but do not otherwise permute it).All of this is, of course, obvious after some brief thought.The Left Replication (or Repetition) Unit (hereinafter the LRU) indicatesthe repeating sequence of digits that go ever onward for increasing powersof the base; items (a) through (d) apply to an LRU as well and withsimilar comments and caveats.But, you say, "Isn't just '


Examples: Base ten {0123456789}complements {9876543210} -- the so-called 9's complementBase two {01}complements {10} -- the so-called 1's complementBalanced ternary {-0+}complements {+0-}Skewed four {=-0+}complements {+0-=}The symbol '~' is often used as a prefix (operator) to indicate acomplement and may be so used here:~ [10] just means [10]The astute reader will notice that the complementation of a numberinvolves all of its digits -- not merely the digits between the bars!Note that for any base the sum of a digit and its complement is a constantwhose value can be represented by some single digit (i.e. this sum willnever produce a non-zero carry). It is this characteristic thatultimately permits us to identify the complement of a number with thenegative of that number.Complements provide intrinsically-signed numbers. Consider a number N ofthe formwhere l is the LRU contents,n is the so-called integer part of the number,p is the point (or scale factor),m is the so-called fractional part (mantissa) of the number,and r is the RRU contents.If n is absorbed by l and m by r, then may be written as provided that the scale factor is zero, e.g. is simply a convenient shorthand for In this compact notation a single bar separates the digits of the numberinto those that are coefficients of the negative powers of the base andthose that are coefficients of the non-negative powers (which includes theso-called "units" digit).The determination as to whether N < 0 or N = 0 or N > 0 can be madewithout resorting to any extrinsic sign convention; signs are intrinsicfor any base -- stay tuned!If N and its complement were added, the result would befor some constant k (where each k here may actually be a sequence of k's).We will see that numbers of this form are (computationally) merelyvariants of zero -- but first we must learn how to add and subtract!-------------------------------------------------------------------------------Negative Numbers:----------------563


Most people are unaccustomed to dealing with numbers in a base other thanten and with negative numbers in general. Negative numbers are for most aconcept without substance since nowhere in elementary or secondary schoolsare negative numbers written with intrinsic sign -- all numeric signs arepresented as extrinsic and not as part of a number itself. This requiresa separate computational process to manipulate these extrinsic signs,leading to the notion that negative numbers are somehow less "real" thanpositive (or unsigned) numbers. This is indeed unfortunate.For those who dabble with balanced ternary (or other balanced or skewedsystems), the notion of an intrinsic sign is far more concrete and clear.But even many computer programmers cannot see the typical computerrepresentation of integers as binary with intrinsic sign for what it is,preferring instead to think of a "sign bit" followed by an unsigned basetwo integer that is complemented for some magical and obscure reason.The computation apparatus described and used herein handles numbers withintrinsic sign for all bases. Extrinsic signs are avoided whereverpossible.===============================================================================A variety of operations are possible involving rational numbersrepresented as described above. These operations can be performed almostentirely symbolically, requiring no more actual numerical computation thanthe ability to add or subtract (or multiply) single digits (with apossible single digit carried in and/or out). Even these single-digitoperations can be accomplished symbolically by the arithmetically impaired(or by a computer program) through the use of addition or subtraction (ormultiplication) tables.It is interesting to note that during the European Middle Ages theexpected mental computation abilities of the average householder ormerchant was the addition or subtraction of single digits no greater thanfive with a possible single "memory location" (a free hand) to "hold" asingle-digit intermediate result -- everything else was done symbolicallyby moving counters (often pebbles or small shells -- the "calculi") arounda counting board (hence "calculation"). In most cases, the "calculator"had no sense (nor needed any) of the actual numbers being operated on norof the final numerical result. Counters were "added to" or "taken from"the board, the final collection of counters was normalized to a standardrepresentation (again using simple but possibly opaque rules), and theresult was the "answer". Multiplication was essentially highermathematics requiring two counting boards; division required an advancedmathematical education. [Citation needed here]Similarly, in what follows, no more mental computation is required thanthe ability to add or subtract (or multiply) single digits in whatevernumber base is being considered (with a possible single digit carried inand/or out). The computation apparatus is designed to keep track ofcarries (no free hand required!). And referring to some prepared tablesfor sums or differences (or products) is not considered cheating.-------------------------------------------------------------------------------Addition:--------As we all learned in elementary school, adding two unsigned (decimal)numbers requires that564a) the (decimal) points "line up"b) zeros are assumed to the right (but no further than needed)c) zeros are assumed to the left (but no further than needed)


and then addition proceeds, starting at the rightmost column of digits,by adding each column and propagating any carry (either zero or one) tothe column immediately to the left; continue until done. But we all hadrather simplistic views of what "rightmost" and "done" actually meant.And subtraction had its own set of arcane rules and restrictions ...The more general procedure requires thata) the points "line up" (meaning that the scale factors are equaland are positioned one above the other) -- move the "dot"s asneeded to adjust the scale factors;b) the bars "line up" -- emit from each RU as needed;c) the angle brackets of the RUs "line up" (meaning that the LRUsare of equal length and the RRUs are of equal length) --replicate RUs to achieve least-common-multiple lengthsand then addition proceeds, starting at the rightmost column of digits,by adding each column and propagating any carry (negative one, zero, orpositive one) to the column immediately to the left; continue until done-- but with the caveat that what is carried into an RU must also becarried out (like the Wilderness Rule "Carry out what you carried in!").That the magnitude of each carry is either zero or one, regardless of base(balanced, skewed, or otherwise), is left as an exercise for the reader --but the proof is not difficult.Here's an example of a base ten addition problem: rewrite + + by emission------------=0 + =0 -- carriesNote that '+' and '-' are used to indicate non-zero carries and that allzero carries are omitted here except for the carry-in for each RU sum.Additionally, if the carry-out for an RU differs from its carry-in, then a'#' is used to mark this difference (here meaning inequality); otherwise an'=' is used (both '#' and '=' here are notational devices and are onlyplaced above non-digits).If the carry-out for the RRU sum is non-zero, then the initially assumedcarry-in of zero was incorrect; in this case, the addition is aborted andthen restarted assuming the correct initial carry-in for the RRU sum (orone might cheat and simply add the carry-out back into the RRU, therebycorrecting the initial incorrect assumption -- but only if the initiallyassumed carry-in was zero!).But what if the carry-out of the LRU of the sum differs from its carry-in?We can't just "correct" the carry-in (that carry was computationallygenerated!) but we can extend the LRUs and have another go at it. Here'san example: rewrite by emission+ + by emission and replication-----------=0#+ + = 0 -- carries rewrite Here a broken bar ':' is used as a tentative bar for the LRU of the sumuntil the LRU carry-out equals its carry-in. The leftmost broken bar isthen retained as a full bar, the other broken bars being removed.565


The broken bar ':' may need to be used up to three times (that no more thanthree are ever required is left as an exercise for the reader -- ponder thepossible carries).All summed LRUs should be computed in this manner.The requirement that the bars and angle brackets of the addend and augmentall line up before the addition can proceed insures that the RUs of thesum are computed correctly and be the same length as the RUs above them.After the sum is computed, it might be possible to simplify its RUs bycontraction. Similar comments apply to the subtrahend, minuend, and thedifference of subtraction.-------------------------------------------------------------------------------Subtraction:-----------Subtraction is similar to addition but with digit differences rather thansums and negative carries (or so-called borrows). Recall that carries arealways additive for both addition and subtraction. Here's a base tenexample: rewrite by emission- - by emission and replication-----------=0 -- = 0 -- carries rewrite It is tempting to think of subtraction as merely the addition of acomplement: rewrite by emission+~ + by emission and replication-----------+#+0 -- carries|31> -- abort (wrong carry-out)!=+ +=++ -- carries rewrite Although the addition of a complement will always produce the correctsubtractive result, the form of that result may be different from thatwhich straight subtraction would yield. Here is a standard base threeexample to illustrate this point: rewrite - - by emission--------=0 - =0 -- carries rewrite by absorptionBut adding the complement of yields: rewrite + ~ + by emission--------=1 =0 -- carries rewrite by absorptionBoth results are correct but differ in form, namely both are equivalenteventual representations of two.===============================================================================566


Equivalent Eventual Representations:-----------------------------------Some numbers have more than one conventional form but they arecomputationally (and mathematically) equivalent. For example:1.000... or [10]0.999... or [10]Such forms are characterized by the fact that their RRUs will accept morethan one assumed initial carry-in which they will then generate as thecarry-out. This is equivalent to adding zero () to a number butassuming either '+' or '-' as the initial carry-in instead of '0'. will accept either '0' or '-' (the latter generating ) will accept either '0' or '+' (the latter generating )The term "eventual" is usually applied only to a number represented witha non-zero RRU (and an LRU of either . Conventionally, an RRU of |0> is thought of as simplyterminating the representation rather than repeating and leading to some"eventuality"; unconventionally, |0> is no less an RRU than, say, |9> andboth are treated similarly herein. In any case, there are equivalent (andeventual) representations having nothing to do with zero.Such equivalent eventual forms are not problematic.===============================================================================A Plethora of Zeros:--------------------It is obvious that is computationally zero; it yields itself whenadded to itself. But so does [10] -- a simple exercise. In factany number consisting of a single digit throughout is computationallyzero.Recall Euler's claim mentioned at the beginning -- this simply states that is zero for any base whatsoever!This is one of the consequences of the statement (also aforementioned) ofb*S(b) - S(b) = 0 for any base b.Since all numbers consisting solely of a single digit are merely somemultiple of then all of these must be computationally zero aswell. And so are numbers that consist solely of some repeating sequenceof digits, such as since(b^3)*S(b) - S(b) = 0for any base band similarly for(b^n)*S(b) - S(b) = 0 for any n.As a notational convenience, a number likewhich can be written as by absorptionmay also be written as by convention (as aforementioned)or even more compactly as just by convention (established here).567


The same may be done for any zero, e.g. written compactly aswhich may also be written asor evenDue care must be taken when expanding a compact zero (such as ) intoa full form with double bars which ultimately needs to represent abi-directionally infinite repeating sequence of digits (such as ...824...).Note that "bi-directionally infinite" means that the number extendsinfinitely to both the left and right, not that the number is infinite!The following are possible and correct expansions of :The novice might wish to always expand a compact zero into a full formwhere each RU contains the compact zero and the digit sequence between thebars is some number of replications (possibly none) of the compact zero.The resulting representation can then be modified by various absorptionsinto or emissions out of the RUs as well as replication within either RU.Facility in writing appropriate zeros in full form comes with practice anda little bit of attention. Consider the balanced ternary representation {-0+} or seven and three eighths.Here are three full form zeros that match one of the components of thisbalanced ternary number (this skill will be useful in much of whatfollows):Since all of these representations are computationally zero, the point (orscale factor) may be placed arbitrarily anywhere between the bars.But how can there be so many zeros? Isn't there really just one zero?This is something like the particle zoo of 20th-century physics whichsettled down only after the appropriate viewpoint was finally achieved.-------------------------------------------------------------------------------A Plethora of Numbers:---------------------Given any "simple" number like (namely one), we can create a vastquantity of computationally equivalent forms by adding appropriate zerosto it, yielding things like or or by absorption.Now wait a minute! What's really going on here?===============================================================================The Background (or Philosophy):------------------------------568


First, think of what we really do when we write a (conventional) number.We assume a bi-directionally infinite blank slate (really filled with '0's)and a "point" (to indicate a known "units" position) upon which we will laysome "digits" in appropriate positions, making these digits differ from theblank background. We compute the value of our work (our number) bymeasuring the difference each digit has from the original blank (or '0')background. We are constrained in the amount of variation we can make atany position by the base of our number system -- the value at each positionmust be representable by one (and only one) of the digits from our orderedset of digits (this insures that the number that we want to write on ourslate has a unique representation -- except for the possible eventual butequivalent representations described above). This is what the Authorbelieves was the true insight of those who long ago discovered that zerowas as much a digit as any other -- perhaps a "place holder" but a digitnonetheless.But suppose that the background on our slate consists of '1's rather than'0's -- it's still flat but everything is elevated a bit. In order tomake a difference of one we need to write a '2', for a difference of twowe write a '3', ..., for eight a '9' -- but (assuming base ten) how do wemake a difference of nine? We must write a '2' in the next digitposition on the slate (making a difference of one there, that is to say adifference of ten here) and then write a '0' in the current position(making its value be one less that the background of '1'); combined, theresulting difference from the background is nine.All of this remains true for background terrain that is hilly rather thanflat -- it's the variance from the expected background, not the actualelevation, that determines the value of the number represented. The onlyreal constraint is that the elevation (i.e. the value) at each location berepresentable (and represented) by one of the digits from our ordered setof digits.There are an infinite number of backgrounds -- that's why there are aninfinite number of zeros (they each just follow and do not deviate fromtheir respective backgrounds). That's the view from the outside; from theinside, there is just one zero -- the current background.So what determines the background? Well, it's just the contents of theLRU. The LRU specifies the expected terrain (the local zero); the rest ofthe number specifies the deviations from the expectations.And it's the first deviation (going from left to right in our conventionalrepresentation) that determines the sign of the entire number -- if theelevation is higher than expected, the number is positive; if lower thanexpected, the number is negative. This is the intrinsic sign.That's why [10] represents negative two -- the expected digitis not '6' but '8'.If the function of being zero is assigned to the first digit in theordered set of digits, it is not possible to represent a negative numberwith a background (LRU) entirely of zero digits since a descent from thebackground is necessary in order to form a negative number. Similarly, ifthe function of being zero is assigned to the last digit in the orderedset of digits, it is not possible to represent a positive number with abackground entirely of zero digits since an ascent from the background isnecessary in order to form a positive number. Such numbers can berepresented, however, by choosing another background -- and there is aninfinite collection of backgrounds to choose from.Assigning the function of being zero to an intermediate digit in theordered set of digits permits the representation of both positive andnegative numbers all with a background consisting entirely of zero digits(although another background could be chosen if desired).569


One way of thinking about a background in a number representation is byanalogy to a carrier wave with amplitude modulation -- but with therestriction that the amplitude is constrained by both upper and lowerbounds.===============================================================================Real Subtraction vs. the Addition of a Complement:-------------------------------------------------To say that subtraction is merely the addition of a complement is notstrictly true.Complementing a number complements its background along with everythingelse; adding this number to another produces a sum with a "mixed"background which then conveniently more-or-less goes away in balancedsystems as well as in systems where zero is an extremal (the first orlast) digit in the ordered set of digits. In balanced systems theaddition of a complemented zero background by itself produces no carriesduring the addition of the two backgrounds (producing an unchangedbackground); in the others a carry is (or can) be produced which ripplesfrom the far right of the RRU and carries all the way to the far left ofthe LRU (flipping the background back to zero).It is seductive to think of subtraction as being the same as the additionof a complement -- but it's not, as is well illustrated by consideringskewed systems. Subtraction differs from the addition of a complement inthat the resulting backgrounds differ by - ~.Consider four and two thirds less two thirds in the skewed system {-0+#}:Doing "real" subtraction yields the following: rewrite - - by convention and emission--------=0 =0 -- carries rewrite or four.Adding the complement of two thirds: rewrite + ~ + by convention and emission--------=0 =0 -- carries rewrite which is still fourbut with a background biased by .===============================================================================Adjusting the LRU (or the Background):-------------------------------------Subtracting the background (the LRU) will clear the background if at allpossible. Here are two base ten examples: [10] or positive five- [10]----------= 0 - = 0 or by contraction and absorption.570


[10] or negative forty-two- [10]----------=-- - = 0 or by contractionor ~or ~ (see "Adjusting the RRU" below).If the background cannot be cleared by this process, the LRU will become asingle digit (the complement of '0') if '0' is either the first digit (andthe number is negative) or the last digit (and the number is positive) inthe ordered set of digits of the system being considered, e.g. {012} or{=-0} respectively. This won't happen in a system where the '0' digit isnot extremal, e.g. {-0+} -- in these systems the background can always beleveled to zero.That is, background clearing always works if the system's '0' digit is notextremal since in such a system it is always possible to represent bothpositive and negative numbers against a background (LRU) of zero.In balanced or skewed systems, background clearing by subtraction isalways possible because there is wiggle room both up from zero (forpositive numbers) and down from zero (for negative numbers). But forextremal systems where zero is at one end of the ordered set of digits,there is wiggle room in only one direction. If the the background cannotbe cleared by subtracting it from the number, then the background willsimply end up as a single digit, namely the complement of the zero digit.If the '0' digit is extremal there are two cases:a) Negative numbers cannot be represented against a background of zero(as for {012} and the like);b) Positive numbers cannot be represented against a background of zero(as for {=-0} and the like).In either of these cases, though, subtracting the background will cause itto become a single extremal digit.Here are two more examples using the system {=-0}:Can the background be removed from or (both are one)? {=-0} rewrite - - -------=+ =0 -- carries or equivalently {=-0} rewrite - - -------=+ =0 -- carries or equivalently Since our number is positive but there's no wiggle room above zero,any attempt to clear the background simply yields the single-digitbackground or ~.The LRUs of numbers do not need to be adjusted before either adding orsubtracting them; sums and differences of backgrounds simply result inother backgrounds that properly support the sum or difference.Here's an extended example of the addition of two numbers with different(and patently obscure) backgrounds.571


First, a bit of review of balanced ternary's, well, "bits":-1/2: or -3/8: -1/4: -1/8: 0: or or +1/8: +1/4: +3/8: +1/2: or Now, consider the addition problem2.6251.25-----3.875but do it in balanced ternary {-0+} with weird backgrounds. Here goes: [10] or {-0+} three less three eighths(or two and five eighths)rewrite by emission+ add a background of ----------= 0 = 0 -- carries rewrite or by contractionor by equivalenceor by absorptionor just two and five eighths. [10] or {-0+} one and a fourthFinally, the balanced ternary addition problem:rewrite by emission and replication+ add a background of ----------+#+0 -- carries|0+> -- abort (wrong carry-out)! {-0+} two and five eighths+ {-0+} one and a fourth--------+#0 -- carries|-> -- abort (wrong carry-out)!= 0 += + -- carries rewrite or by absorptionor by contractionor by equivalenceor just one and a fourth.= -# 0#++ +=+ -- carries rewrite {-0+}or by absorptionor three and seven eighths -- oh, really?572


Let's clear this new background: rewrite by replication- - by emission-----------= 0 --- = 0 -- carries rewrite or by contractionor by absorptionor four less an eighthwhich is just three and seven eighths!-------------------------------------------------------------------------------Adjusting the RRU:-----------------For any given system, one (and only one) of the following applies(where 0 means the digit assigned the function of being zeroand ~0 means the complement of that digit):a) 0 < ~0 as in {012} where '0' precedes '2' or {-0+#} where '0' precedes '+'b) 0 = ~0 as in {-0+} where '0' equals '0' or {=-0+#} where '0' equals '0'c) 0 > ~0 as in {=-0} where '0' follows '=' or {=-0+} where '0' follows '-'In case (a) if the RRU consists of a single digit that is the complementof '0' and that digit is extremal, then the RRU can be reduced to zero byadding with an initial carry of '+'; this can occur for {012} butnever for {-0+#}.In case (b) no single digit can be both the complement of '0' and extremal(well, maybe base one {0} but that's not very interesting!).In case (c) if the RRU consists of a single digit that is the complementof '0' and that digit is extremal, then the RRU can be reduced to zero byadding with an initial carry of '-'; this can occur for {=-0} butnever for {=-0+}.In order for a non-zero RRU to be part of an equivalent eventualrepresentation, it must consist of a single extremal digit; in order forit to be convertible to an RRU of zero, then '0' must be the otherextremal digit.There are, of course, other pairs of equivalent eventual representationsthat do not involve the '0' digit; they always do, however, involve theextremal digits of the system being considered: {-0+} or one half, {-0+} also one half.Converting a representation to an equivalent eventual representation mightnot set the RRU to zero but it does not affect the LRU; arbitrarilysetting the RRU to zero, however, by subtracting the RRU from the numbergenerally does alter the LRU. Requiring that both the LRU and RRU besimultaneously zero is to live in a world of integers only; requiring thatthe LRU and RRU be the same is simply living in a different world ofintegers.===============================================================================[Material needed here]-------------------------------------------------------------------------------573


Base Zero:---------Here the ordered set of digits is empty, namely {} -- there's nothing todesignate as the zero digit. Forget I even mentioned it ...-------------------------------------------------------------------------------Base One:---------Again, uninteresting. At least there is a digit in {0} to designate asthe zero digit, namely '0' -- but there are no numbers that we canrepresent other than zero itself, namely (i.e., there is no way tomake a difference from the one-and-only background).-------------------------------------------------------------------------------Negative Bases:--------------If the base b is negative, then all even powers of the base are positiveso we can consider this as a "normal" number in base b^(2).Consider base negative two [-2] {01} as an example. In this so-callednega-binary system, each even power of the base makes a positive (or zero)contribution to the value of the number while each odd power of the basemakes a negative (or zero) contribution. A brief examination will showthat nega-binary numbers have unique (but allowing for eventual)representations. The digits here can be considered in pairs as the skewedbase four system [+4] {=-0+}:[-2] [+4]----- ----0: 00000 00001: 00001 000+2: 00110 00+=3: 00111 00+-4: 00100 00+05: 00101 00++6: 11010 0+==7: 11011 0+=-8: 11000 0+=09: 11001 0+=+10: 11110 0+-=11: 11111 0+--12: 11100 0+-013: 11101 0+-+14: 10010 0+0=15: 10011 0+0-16: 10000 0+00... ... and so on.Since a negative base b can be "normally" represented as base b^(2), it isonly required that |b| > 1. Consequently, negative bases may be disposedof as a mere curiosity.-------------------------------------------------------------------------------Reciprocal Bases:----------------574


A number represented in a base that is a reciprocal of an integer b > 1seems only to be the base b number in the opposite direction (with dueattention being paid to negating the scale factor and adding one since thedirections of increasing/decreasing powers of the base are now swapped andthe point needs to be moved to the other side of the digit to which it isadjacent). Lacking this interpretation, it is difficult to make sense ofthe cardinality of any ordered set of digits as relating to the base. [1/3] {-0+} or [1/3] {-0+}should likely be interpreted as [3] {-0+} or [3] {-0+}or, reversing the directionality of the representation, asor just [3] {-0+} or [3] {-0+} [3] {-0+}in the more conventional "upright bar" notation.If one could make some other coherent sense of reciprocal bases, it mightthen be possible to make coherent sense of fractional bases in general.Short of that, the Author is inclined to disregard all non-integral basesas lacking even a modicum of curiosity.On the other hand, just thinking about reciprocal bases makes clearer somethings that might otherwise remain rather opaque. In particular, ponderthe power series generator:1/(1-x) = P(x) = 1 + x^(1) + x^(2) + x^(3) + x^(4) + ...This is generally considered only when 0 < x < 1 for which P(x) converges,e.g.P(1/3) = 1.5but, when squinted at in just the right way, one notices thatP(1/3) = [1/3] {012} or [1/3] by assumed point [1/3] by definition of "dot" [3] by interpretation above [3] by moving the "dot" [3] by definition of "dot" [3] by assuming the pointor [3] {012} in conventional "upright bar" notationwhich is one and a half.If x > 1 then P(x) diverges, say for x = 3 -- or does it?Clearly the generator has a well-defined (negative) value for P(3), sosquinting again in just the right way, one can see thatP(3) = [3] {012} or [3] by reversal of the barsor [3] {012} in conventional "upright bar" notationwhich is negative one half (as we have seen before) --exactly what the generator evaluates to.It's an easy exercise to show thatP(b) + P(1/b) = [b]for any base b > 0.575


===============================================================================There's Only One Base b (for any b):-----------------------------------For b zero, one, negative, or a unit fraction, these are all described(and dismissed) above. For any integral base b > 1 there are b differentsystems (one for each choice of the digit to function as the zero), eachwith its own addition table. Or are there?Consider the three possible base three systems:{012} -- standard ternary (sometimes {0+#} if using plus and double-plus);{-0+} -- balanced ternary; and{=-0} -- inverted ternary (using double-minus and minus)and also a generic base three system:{xyz} -- this could be any of the three systems above ...What can one say about a number represented in this generic {xyz} system?Consider: {xyz}First, the number is positive since the first digit to deviate from thebackground is y, which is ordered after x in {xyz} and thus x < y, sowe have intrinsic (positive) sign.Second, the value of the number is determined solely by the deviations ofthe digits from the expected background; let us compute:up one in the 3^(2) position -- counts for +9;up two in the 3^(1) position -- counts for +6;up two in the 3^(0) position -- counts for +2;then up one all the way out from the implied point -- counts for +0.5;for a total of +17.5 -- seventeen and a half.For reference, here are the addition tables for the three possible {xyz}systems (where the left-most character in each sum pair is the carry --always represented as one of '0', '+', or '-'):{012} {-0+} {=-0}0 1 2 - 0 + = - 0------------ ------------ ------------0 | 00 01 02 - | -+ 0- 00 = | -- -0 0=1 | 01 02 +0 0 | 0- 00 0+ - | -0 0= 0-2 | 02 +0 +1 + | 00 0+ +- 0 | 0= 0- 00and the corresponding subtraction tables (where the left-most character ineach difference pair is the carry):0 1 2 - 0 + = - 0------------ ------------ ------------0 | 00 -1 -2 - | 00 0- -+ = | 00 0- 0=1 | 01 00 -1 0 | 0+ 00 0- - | += 00 0-2 | 02 01 00 + | +- 0+ 00 0 | +- += 00If {xyz} is really {(x)yz}, meaning {012}, this is normally just written as: or {0+#} if using plus and double-pluswhich is seventeen and a half in {012}.576


Now suppose that {xyz} is really {x(y)z}, meaning {-0+}. Then we have:- adjust the background by subtracting -----------=0#+ ++ =0 -- carries rewrite {-0+}which is recognizably seventeen and a half in {-0+}. Or with a different initial carry (+ rather than 0) ...- -----------=0#+ +++=+ -- carries rewrite {-0+}But suppose that {xyz} is really {xy(z)}, meaning {=-0}. Then we have:- adjust background by subtracting ---------+#0 -- carries|0> -- abort (wrong carry-out)!=+ +++=+ -- carries rewrite ... no change -- but not surprisingsince subtracting is similarto adding ~ which is just .Perhaps one could try subtracting instead ...- -----------=0#+ ++ =0 -- carries rewrite {=-0}Compare this pattern with {-0+} from above. Or with a different initial carry (+ rather than 0) ...- -----------=0#+ +++=+ -- carries rewrite {=-0}Compare this pattern with {-0+} from above.And certainly subtracting won't help either ...- ---------=0 =0 -- carries rewrite ... no change (not surprising).We can't make the background since in this system'0' is the topmost digit and there is no "up" from '0'to represent a positive number.Nonetheless, {=-0} is seventeen and a half.This behavior is not restricted to representations having a single-digitbackground. Being somewhat more adventurous, consider the following: {xyz}577


If {xyz} is really {(x)yz}, meaning {012}, then: by replication- adjust background by subtracting ----------= 0 = 0 -- carries rewrite or by contractionwhich is recognizably seven and three eighths in {012}.If {xyz} is really {x(y)z}, meaning {-0+}, then: by replication- adjust background by subtracting -------------= 0# + = 0 -- carries rewrite or by contractionor by absorptionwhich is recognizably seven and three eighths in {-0+}.If {xyz} is really {xy(z)}, meaning {=-0}, then: by replication- adjust background by subtracting ----------+# 0 -- carries|=0> -- abort (wrong carry-out)!=++ ++=++ -- carries rewrite or by contractionwhich is still seven and three eighths in {=-0} eventhough the best that can be accomplished, again, isto reduce the background to (i.e. ~).The Author suspects, however, that "" would not be a properresponse to the haberdasher's question, "Sir, what is your hat size?".[Suggested pronunciation: "LES-iz bar-NUL-neg bar-NEG-iz MOR"]A consequence of all this is that whether a base b number is representedin the system {0,...,b-1} or {-1,0,..,b-2} or ... or {2-b,..,0,1} or{1-b,...,0} is completely irrelevant; the representation encodes the valueof the number regardless of which digit is assigned the function of beingzero. But it's not necessary to actually change the symbols for thedigits in the representation when moving from one base b system toanother. All that is needed is to designate (perhaps arbitrarily) somedigit to be the zero digit which then entirely determines the propertiesof the addition and subtraction tables.How can this be? Remember that the background (the LRU) permeates theentire number representation and the value of that number is determinedsolely by the variances from that background. Adding two numbers simplysums the variances as well as the backgrounds themselves, producing summedvariances against a summed background. And one may (arbitrarily)interpret that sum in a base b system other than the system that was usedto produce that sum.The choice of a base b system applies to both the addend and augment (orsubtrahend and minuend) and determines the addition (or subtraction) tableto be used. Choosing different base b systems to sum two base b numberswill produce different backgrounds, but these "different" sums will alwaysrepresent the same base b number.578


Here again are the addition tables for the three possible {xyz} systemsbut in a more abstract form (where the left-most character in each sumpair is the carry):{(x)yz} {x(y)z} {xy(z)}x y z x y z x y z------------ ------------ ------------x | 0x 0y 0z x | -z 0x 0y x | -y -z 0xy | 0y 0z +x y | 0x 0y 0z y | -z 0x 0yz | 0z +x +y z | 0y 0z +x z | 0x 0y 0zand the corresponding subtraction tables (where the left-most character ineach difference pair is the carry):x y z x y z x y z------------ ------------ ------------x | 0x -z -y x | 0y 0x -z x | 0z 0y 0xy | 0y 0x -z y | 0z 0y 0x y | +x 0z 0yz | 0z 0y 0x z | +x 0z 0y z | +y +x 0z===============================================================================Symbols vs. Values:------------------[forthcoming commentary]===============================================================================Normalization:-------------Some representations of a number are more easily comprehended than otherseven though all of them are equally valid for purposes of computation.The normalization of a representation simply produces a form that is asconventional and compact as possible.Converting from one form of base b to another form of base b is simply amatter of reassigning the function of being zero to a different digit inthe ordered set of digits (and using different addition and subtractiontables, of course); consequently, without loss of generality, the firstdigit from the ordered set of digits may always be assigned the functionof being zero -- later converting to another form of base b if required.Note that these so-called conversions do not require any modification of anumber's representation (it remains unchanged); relabeling the digits ispermitted, of course, but this does not change the relationship of onedigit to another in the representation. Conversion is simply a matter ofarbitrarily declaring one of the digits in the system to be the zerodigit.In much of what now follows, it is convenient (and clearer) to make thesimplifying assumption that a base b system is just {0,1,..,b-1}.Once a digit has been chosen to function as the zero in the system, theLRU (i.e. the background) can be adjusted and contracted to a single zerodigit (or its complement). The RRU can then be contracted and possiblyadjusted (if it's an eventual form) to match the LRU.Finally, each RU should absorb as much as possible (this may require theintroduction and adjustment of a scale factor between the bars). If nodigits remain between the bars and the scale factor is zero (or just thepoint), the bars (and point) may be replaced by a single bar.579


If the LRU is the complement of the zero digit, one may complement theentire representation and prefix a '~' character for display purposes.[Examples needed here]===============================================================================Reciprocals:-----------[forthcoming -- soon]===============================================================================Multiplication:--------------While addition is the sum of two bi-directionally infinite numbers,multiplication is essentially the infinite summation of such numbers, eachbeing a single-digit multiple of the multiplicand with an appropriatescale factor. With a little work, multiplication can be reduced to thesum of just four bi-directionally infinite numbers, each being formed fromproducts of finite extent.[forthcoming -- soon]===============================================================================Division:--------[forthcoming -- eventually]===============================================================================Just-In-Time-Subtraction (JITS) Revisited:-----------------------------------------Halving a (balanced) ternary integer N by doing a single subtraction --conceptually this is computing M = 3*M - 2*M where 2*M = NIf N is actually divisible by two (i.e. even), the procedure yields thecorrect result. Does it also yield the correct result if N is odd?Let N = 7, i.e. {-0+};the JITS procedure yields which can be rewritten as .By subtracting a convenient zero, say , one can readjust the backgroundof this result:- --------=0 =0 -- carries which is recognizable as three and a half.So, yes, the JITS procedure also produces the correct result if N is odd-- one merely needs to adjust the background of the result to get it tozero elevation in order to more clearly see the result.===============================================================================What's the REAL Difference Between 1's- and 2's-Complement Arithmetic:---------------------------------------------------------------------580


Modern computing hardware generally represents integers as binary withintrinsic sign, abandoning attempts to represent integers as (extrinsic)sign and magnitude.So positive integers are represented as [2] where the LRU isexplicitly represented as a high-order bit, the RRU is implicitly assumed,and n (the number) is represented by a fixed-length string of binarydigits (bits) typically of length word-size less one.Negative integers are simply the complements of corresponding positiveintegers which complements the LRU background (the so-called "sign" bit)without altering the bit-length of n. But what is done with the RRU?For 1's-complement hardware, the RRU is simply left unchanged (i.e. thebackground is assumed to extend both left and right).But 2's-complement hardware always assumes that the RRU is |0> independentof the background; consequently, an RRU carry-in of '+' is arbitrarilyassumed for any complement and will convert the |1> (the complemented |0>)back to |0> carrying out a '+' across the bar. Unfortunately, if all thebits between the bars are also one, the carry continues across the otherbar and finally carries out of the LRU as well. No carry-in/carry-outrules are violated, but will always get converted to (thisis either good or bad, depending on one's computational point of view).Such hardware usually implements a "logical" complement in addition to an"arithmetic" complement, as well as a number of other "logical" operationsthat function rather like their 1's-complement "arithmetic" counterparts.The Author remains computationally agnostic on this point.===============================================================================Credits:-------The Author's co-worker and office mate, John Halleck, deserves much creditfor being a sounding board for bizarre ideas over many of these past years.He has also been a persistent prod to the Author to document some of theseideas in order to Make the Intuitively Obvious Understandable.The "Just-in-Time Subtraction" procedure divides a base-b number by b-1.The name was coined by Dylan Pocock, another of the Author's co-workers.To John Scholes I owe thanks for taking an interest in the JITS procedureand doggedly searching out its source -- and then taking an interest in theideas (with clarifications) that led to such a scheme in the first place.-------------------------------------------------------------------------------Comments:--------The JITS procedure actually generates a complete and accurate division byb-1 without remainder -- provided that one properly handles bi-directionallyinfinite strings of digits (in some base b) as representations of rationalnumbers. In such a world there are multiple but equivalent representationsof every rational number (both positive and negative), all of which areamenable to even simple pencil-and-paper calculation. The JITS procedurealways generates a rational result without remainder but possibly in one ofthose equivalent representations.581


Concerning balanced ternary, one will undoubtedly notice that a simple testfor evenness (and therefore integral divisibility by two) is just to sum thenon-zero digits of the number (assuming RUs of zero), iteratively as needed("casting out signs" is like "casting out nines" in base ten).Pre-rounding/truncating the number to induce evenness would eliminate theneed for a post-adjustment of any non-integral division by two.It has been pointed out that the phrase "Replication (or Repetition) Unit"is somewhat ponderous; the terminology "Repetition Sequence" has beensuggested as a possibly more appropriate replacement. The two terms"Replication" and "Unit" got into this fine mess during some of the Author'soriginal doodling regarding representations of rational numbers; these termshave simply survived, but are mostly replaced by the somewhat semanticallyempty moniker "RU". The Author remains open to further suggestions.I originally thought of a continual carry to the left as somehowdisappearing over the horizon ("To Infinity and Beyond!") so as to beout-of-sight and out-of-mind. And I always wanted to avoid invoking anynotion of "end-around" carries in all contexts -- a notion that seemed to beexpedient in many cases but which I felt obscured a more fundamentalunderstanding of what was going on. All of this eventually got reduced tothe "carry out what you carry in" maxim. An end-around carry, in any case,is merely a convenient fiction -- RU carries always originate at thelow-order end, propagate through the RU, and then carry out of thehigh-order end (there's no "around" around here). If the carry-out differsfrom the carry-in, then the initially assumed carry-in is incorrect and thecomputation must be redone using the correct initial carry (which one can'tactually know until the carry-out is known).I toyed with the idea of placing the initial (low-order) carry over thefinal delimiter of an RU but decided in the end (pun intended) that itreally belongs in line with the (low-order) digit to which it applies.Similarly, the carry-out skips the leading non-digit punctuation and linesup with the digit to which it applies (the '=' or '#' being placed over theleading punctuation to indicate whether the carry-out equaled the carry-inor not).Additionally, I have come to think of the background and its reduction to asea of '0's as being akin to the particle physicist's trick ofrenormalization to get rid of those "damned infinities" (as Richard Feynmanreferred to them). And if we cannot computationally reduce the backgroundto zero but only to the complement of zero, then we are no worse off thancomputer scientists who do this all the time with their "high-order signbit(s)".-------------------------------------------------------------------------------Connections:-----------I originally came to the problem of the continual carries (actually borrows)while working on the JITS procedure. But this ultimately seemed no morebizarre than the continual carries (of zero) that fundamentally happen forevery addition/subtraction operation -- carries that as school children wewere taught to ignore (if they were ever mentioned at all), but they arethere nonetheless. The JITS procedure was trying to tell me something -- itcertainly wasn't just random noise heading over the far horizon! And if itmeant anything at all, it had to be a representation of the remainder, orsomething like that ...582


And the JITS procedure itself was only a consequence of considering what isoften called the "Hailstone Problem": pick n > 0 and odd, multiply by three,add one, cast out all factors of two, cook 'til (d)one. It seemed obviousthat patterns of numbers might be usefully investigated in base three inorder to gain some insights -- but that division by two was just plainnasty! Hence JITS.The idea for JITS initially sprang from remembering an old (base ten)addition puzzle:SEND+ MORE-----MONEYThe idea for the RU notation was unashamedly swiped from quantum mechanics(the "bra" and "ket" notation) where it is used for an entirely differentpurpose.The Middle Ages counting board (essentially a marked table top or "board")was a common piece of household furniture. Even after losing its markings,it is still commonly known as a "counter". A portable set of markings on a"checkered" cloth was popular with tax collectors who worked for the"exchequer".The word "xyzzy" comes from an early interactive fantasy role playing gamecalled Adventure (written in Fortran as I recall); the word was (and Isuppose still is) carved in stone and effected magical transport whenuttered, er, typed. The fact that is also my hat size I chalk upto the general perversity of Life, the Universe, and Everything -- but forthat we really need .===============================================================================Back to: …ratsum„See also: JitSub.600 bt.258 esh.275 ary.317 ratsum.308 phinary.341 fibonacci.279See also: eval.dws/notes.btaÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎrefcardHere is a handy aide-mémoire for the D-programmer.583


Print it on a piece of green card, folding as indicated:ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ Û {¸ Function ¾} Û {¸¸ Operator ¾¾} Û : Guard ÛÛÃÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÝÛ D-programming Û ¸ Left argument Û ¸¸ Left operand Û :: Error-guard ÛÛ reference ÃÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÝÛ card Û ¾ Right argument Û ¾¾ Right operand Û ¸„ Default larg ÛÛÃÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÝÛÛ ’ Self reference Û ’’ Self referenceÛ 1:s„ Shy result ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙ† † †Û Û ÛÀÎÎfoldÎÎhereÎÎandÎÁÎhereÎÎandÎÎhereÎÎÙ. . .|\ /|\ /|| \ //| \ //|


These effects are illustrated by the following example:wds „ ' '°segs© blank-separated words.disp wds 'ready steady go' © three words.Ú…ÎÎÎÎÂÎÎÎÎÎÎÂÎÎÌÛreadyÛsteadyÛgoÛÀÎÎÎÎ…ÁÎÎÎÎÎ…ÁÎ…ÙExamples:song „ 'Any old Iron, any old iron? Any old, any old, iron?'disp '?'segs songÚ…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛAny old Iron, any old ironÛ Any old, any old, ironÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…Ùdisp ','segs¨ '?'segs songÚ…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛÚ…ÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛÚ…ÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÂÎÎÎÎÎÌÛÛÛAny old IronÛ any old ironÛÛÛ Any oldÛ any oldÛ ironÛÛÛÀÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎ…ÙÛÀÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎ…ÁÎÎÎÎ…ÙÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…Ùdisp ' 'segs¨¨ ','segs¨ '?'segs songÚ…ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛÚ…ÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛÚ…ÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÌÛÛÛÚ…ÎÎÂÎÎÎÂÎÎÎÎÌÛÚ…ÎÎÂÎÎÎÂÎÎÎÎÌÛÛÛÚ…ÎÎÂÎÎÎÌÛÚ…ÎÎÂÎÎÎÌÛÚ…ÎÎÎÌÛÛÛÛÛAnyÛoldÛIronÛÛÛanyÛoldÛironÛÛÛÛÛAnyÛoldÛÛÛanyÛoldÛÛÛironÛÛÛÛÛÀÎÎ…ÁÎÎ…ÁÎÎÎ…ÙÛÀÎÎ…ÁÎÎ…ÁÎÎÎ…ÙÛÛÛÀÎÎ…ÁÎÎ…ÙÛÀÎÎ…ÁÎÎ…ÙÛÀÎÎÎ…ÙÛÛÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÙÛÀÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎ…ÙÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ…ÙSee also: words.169 tokens.170ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎsoupÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ SoupÛÛ ----ÛÛ Vegetable soup · · $1 ÛÛ Chicken soup · · · $2 ÛÛ Vegan soup · · · · $3 ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙSee also: decay.533 muson.551ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎstaples"A computer programmeris someone who staplesa single sheet of paper."The state of refinement of the human intellect can be judged by the use it makesof the humble paper stapler:Regular People often staple together multi-sheet printed documents.¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯For consistency, Computer Programmers also staple single-sheet documents.¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯In addition, Systems Programmers staple zero-sheet documents.¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ ¯¯¯¯¯¯¯¯¯¯Finally, Mathematicians staple documents containing a negative number of sheets.¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯585


The above musings were prompted by the following C code extract:if (so_and_so_is_true){do_stuff();then_do_this_stuff();}else{do_this_other_stuff();}as the clause is a single statement the braces are not necessary but onecan see why a consistency junkie might put them there.And a few more ...The Salesman claims that this particular paper is self-stapling.The Accountant restricts use of the stapler to reduce stapling costs.The Politician denies the existence of the document.The Luddite denies the existence of the stapler.The Razor manufacturer gives you a free stapler and hits you for the staples.The Anagram enthusiast Meets up the Scotlands.The Haiku poet / staples document pages / as necessary.The Fading <strong>APL</strong> Implementor can't remember where he left the stapler or document.... and so on.See also: muson.551ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎsudoku_bfsBreadth-First Search Sudoku Solver----------------------------------The Sudoku solver shown in YouTube: http://www.youtube.com/watch?v=DmT80OseAGsuses a breadth-first tree search technique.Taking a 4×4 puzzle as an example:ÚÎÎÎÂÎÎÎÌÛ· ·Û· ·ÛÛ· ·Û2 1ÛÃÎÎÎÏÎÎÎÝÛ3 ·Û· 4ÛÛ· ·Û· ·ÛÀÎÎÎÁÎÎÎÙStep[1] Choose any blank cell and make a vector of possible placements at thatposition. Let's start with cell [1 1] at the top left corner. In this case, asthe possible placements are 1, 2 or 4, we wind up with a 3-vector of matrices:ÚÎÎÎÂÎÎÎÌÚÎÎÎÂÎÎÎÌÚÎÎÎÂÎÎÎÌÛ1 ·Û· ·ÛÛ2 ·Û· ·ÛÛ4 ·Û· ·ÛÛ· ·Û2 1ÛÛ· ·Û2 1ÛÛ· ·Û2 1ÛÃÎÎÎÏÎÎÎÝÃÎÎÎÏÎÎÎÝÃÎÎÎÏÎÎÎÝÛ3 ·Û· 4ÛÛ3 ·Û· 4ÛÛ3 ·Û· 4ÛÛ· ·Û· ·ÛÛ· ·Û· ·ÛÛ· ·Û· ·ÛÀÎÎÎÁÎÎÎÙÀÎÎÎÁÎÎÎÙÀÎÎÎÁÎÎÎÙStep[2] Choose a second position, say [2 2] and, for _each_ of the above, make a_vector_ of possible placements, giving us a vector-of-vectors-of-matrices:586


ÚÎÎÎÂÎÎÎÌÚÎÎÎÂÎÎÎÌ ÚÎÎÎÂÎÎÎÌÚÎÎÎÂÎÎÎÌ ÚÎÎÎÂÎÎÎÌÛ1 ·Û· ·ÛÛ1 ·Û· ·Û Û2 ·Û· ·ÛÛ2 ·Û· ·Û Û4 ·Û· ·ÛÛ· 3Û2 1ÛÛ· 4Û2 1Û Û· 3Û2 1ÛÛ· 4Û2 1Û Û· 3Û2 1ÛÃÎÎÎÏÎÎÎÝÃÎÎÎÏÎÎÎÝ ÃÎÎÎÏÎÎÎÝÃÎÎÎÏÎÎÎÝ ÃÎÎÎÏÎÎÎÝÛ3 ·Û· 4ÛÛ3 ·Û· 4Û Û3 ·Û· 4ÛÛ3 ·Û· 4Û Û3 ·Û· 4ÛÛ· ·Û· ·ÛÛ· ·Û· ·Û Û· ·Û· ·ÛÛ· ·Û· ·Û Û· ·Û· ·ÛÀÎÎÎÁÎÎÎÙÀÎÎÎÁÎÎÎÙ ÀÎÎÎÁÎÎÎÙÀÎÎÎÁÎÎÎÙ ÀÎÎÎÁÎÎÎÙNext, concatenate the items of this 3-vector-of-vectors-of-matrices into a single5-vector-of-matrices:ÚÎÎÎÂÎÎÎÌÚÎÎÎÂÎÎÎÌÚÎÎÎÂÎÎÎÌÚÎÎÎÂÎÎÎÌÚÎÎÎÂÎÎÎÌÛ1 ·Û· ·ÛÛ1 ·Û· ·ÛÛ2 ·Û· ·ÛÛ2 ·Û· ·ÛÛ4 ·Û· ·ÛÛ· 3Û2 1ÛÛ· 4Û2 1ÛÛ· 3Û2 1ÛÛ· 4Û2 1ÛÛ· 3Û2 1ÛÃÎÎÎÏÎÎÎÝÃÎÎÎÏÎÎÎÝÃÎÎÎÏÎÎÎÝÃÎÎÎÏÎÎÎÝÃÎÎÎÏÎÎÎÝÛ3 ·Û· 4ÛÛ3 ·Û· 4ÛÛ3 ·Û· 4ÛÛ3 ·Û· 4ÛÛ3 ·Û· 4ÛÛ· ·Û· ·ÛÛ· ·Û· ·ÛÛ· ·Û· ·ÛÛ· ·Û· ·ÛÛ· ·Û· ·ÛÀÎÎÎÁÎÎÎÙÀÎÎÎÁÎÎÎÙÀÎÎÎÁÎÎÎÙÀÎÎÎÁÎÎÎÙÀÎÎÎÁÎÎÎÙ... and contine from Step[1] above.Choosing position [2 1] for our next move:ÚÎÎÎÂÎÎÎÌ ÚÌ ÚÎÎÎÂÎÎÎÌ ÚÌ ÚÌÛ1 ·Û· ·Û ÛÛ Û2 ·Û· ·Û ÛÛ ÛÛÛ4 3Û2 1Û ÛÛ Û4 3Û2 1Û ÛÛ ÛÛÃÎÎÎÏÎÎÎÝ ÃÝ ÃÎÎÎÏÎÎÎÝ ÃÝ ÃÝÛ3 ·Û· 4Û ÛÛ Û3 ·Û· 4Û ÛÛ ÛÛÛ· ·Û· ·Û ÛÛ Û· ·Û· ·Û ÛÛ ÛÛÀÎÎÎÁÎÎÎÙ ÀÙ ÀÎÎÎÁÎÎÎÙ ÀÙ ÀÙIn this case, only one placement is possible at each of the 1st and 3rd items,and _none_ are possible at the 2nd, 4th and 5th. This means that the lengths ofthe resulting vectors of matrices are 1, 0, 1, 0 and 0 respectively.Concatenating these vectors-of-vectors before returning to Step[1] produces the2-vector of matrices:ÚÎÎÎÂÎÎÎÌÚÎÎÎÂÎÎÎÌÛ1 ·Û· ·ÛÛ2 ·Û· ·ÛÛ4 3Û2 1ÛÛ4 3Û2 1ÛÃÎÎÎÏÎÎÎÝÃÎÎÎÏÎÎÎÝÛ3 ·Û· 4ÛÛ3 ·Û· 4ÛÛ· ·Û· ·ÛÛ· ·Û· ·ÛÀÎÎÎÁÎÎÎÙÀÎÎÎÁÎÎÎÙNotice how "dead-ends" in the tree search produce 0-length vectors are just absorbedby the concatenation step.Choosing [3 2] next:ÚÎÎÎÂÎÎÎÌÚÎÎÎÂÎÎÎÌ ÚÎÎÎÂÎÎÎÌÚÎÎÎÂÎÎÎÌÛ1 ·Û· ·ÛÛ1 ·Û· ·Û Û2 ·Û· ·ÛÛ2 ·Û· ·ÛÛ4 3Û2 1ÛÛ4 3Û2 1Û Û4 3Û2 1ÛÛ4 3Û2 1ÛÃÎÎÎÏÎÎÎÝÃÎÎÎÏÎÎÎÝ ÃÎÎÎÏÎÎÎÝÃÎÎÎÏÎÎÎÝÛ3 1Û· 4ÛÛ3 2Û· 4Û Û3 1Û· 4ÛÛ3 2Û· 4ÛÛ· ·Û· ·ÛÛ· ·Û· ·Û Û· ·Û· ·ÛÛ· ·Û· ·ÛÀÎÎÎÁÎÎÎÙÀÎÎÎÁÎÎÎÙ ÀÎÎÎÁÎÎÎÙÀÎÎÎÁÎÎÎÙ587


Concatenating the 2 2-vectors to form a 4-vector:ÚÎÎÎÂÎÎÎÌÚÎÎÎÂÎÎÎÌÚÎÎÎÂÎÎÎÌÚÎÎÎÂÎÎÎÌÛ1 ·Û· ·ÛÛ1 ·Û· ·ÛÛ2 ·Û· ·ÛÛ2 ·Û· ·ÛÛ4 3Û2 1ÛÛ4 3Û2 1ÛÛ4 3Û2 1ÛÛ4 3Û2 1ÛÃÎÎÎÏÎÎÎÝÃÎÎÎÏÎÎÎÝÃÎÎÎÏÎÎÎÝÃÎÎÎÏÎÎÎÝÛ3 1Û· 4ÛÛ3 2Û· 4ÛÛ3 1Û· 4ÛÛ3 2Û· 4ÛÛ· ·Û· ·ÛÛ· ·Û· ·ÛÛ· ·Û· ·ÛÛ· ·Û· ·ÛÀÎÎÎÁÎÎÎÙÀÎÎÎÁÎÎÎÙÀÎÎÎÁÎÎÎÙÀÎÎÎÁÎÎÎÙ... and so on.Repeating these steps for all blank cells results in a vector of possible solutionswith numbers in all positions.Published Sudoku puzzles typically claim to have a solution vector of length 1.Improvements------------Using more suggestive names for the <strong>functions</strong>:Sudoku„{BoxNos „ {¾š¾/¾ ¾½¼¾*2}RowColBoxNos „ {(¼¾),¨BoxNosœ¾*0.5}ContentionMap „ {›[¼2] 1¹¨¾°.=¾}CMAP „ ContentionMap RowColBoxNos ½¾© Solution vector for square Sud© box numbers for a puzzle of si© row/column/box numbers© contention map for puzzle ¾© fixed contention map for curreat „ {¾+¸×(¼½¾)¹›¸¸} © puzzle ¾ with ¸ at position ¸¸Available „ {(¼œ½¾)~¾×œ¸¦CMAP}© list of available numbers at pEmptyCells „ {(,¾=0)/,¼½¾}© row & column indices of emptyPlacements „ {(¸ Available ¾) (¸ at)¨ ›¾} © puzzle ¾ with all available nuAllPlacements „ {œ,/¸°Placements¨¾}© all possible Placements at ¸ bSolutions „ {œAllPlacements/(EmptyCells ¾),››¾} © solution vector}Solutions ¾The choice of "next node" is subject to optimisation using "Warndorff's rule",which prescribes selecting tree nodes in order of increasing degree. This means:for the next node, choose the one with the fewest available placements.An approximation to the rule can be arranged by sorting the result of function above:Sorted „ {¾[“†½¨¾ avl¨›¸]}© sorted into ½ Available order.then:Solutions „ {œAllPlacements/(²¾ Sorted EmptyCells ¾),››¾} © solution vector¯¯¯¯¯¯¯¯¯Extension to higher rank puzzles--------------------------------Various extensions to higher-dimensional (3D 4D ...) puzzles have been proposed.The rules for one of these variations is simply that no number should be repeatedin any of the rank (¯1+½½¾) sub-planes. In the case of a 3×3×3 puzzle, suchas:5880 0 08 1 00 0 20 6 00 7 09 0 4


5 0 00 0 30 0 0this means there should be no repeats in any of the 9: x, y or z planes. Noticethat for this puzzle there are no "boxes", so we won't need inner function; instead, we need only the primitive indices function: ¼. Here arethe modifications:ContentionMap „ {›[¼½½¾] 1¹¨¾°.=¾} © contention map for puzzle ¾¯¯¯CMAP „ ContentionMap ¼ ½¾© fixed contention map for current puzzl¯Available „ {(¼×/1‡½¾)~¾×œ¸¦CMAP} © list of available numbers at position¯¯¯¯leading to solution:3 4 98 1 67 5 21 6 82 7 59 3 45 2 74 9 36 8 1See also: sudoku.491 X.160ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎsudokuXExact cover Sudoku solver-------------------------A Sudoku puzzle may be expressed and solved as an exact cover problem:sudokuX„{ŒML ŒIO„1n n„½¾¸„smat nr„¹(¾¬0)>(›¼n)¹¨¾m„(~r)š¸f„X mz„(~r)\fn n½z/(½z)½¼n}© Exact cover Sudoku solver.© n×n puzzle.© generic ¾×¾ constraint matrix.© already placed rows.© reduced matrix.© exact cover.© merge of placements.© solution matrix.smat„{© Matrix for ¾ ¾-Sudoku puzzle.z„,[¼6],[6+¼4]¼10½¾*÷2© cell coordinate properties.row„‡1 1 0 0 1 1 1 1 1 1/†z © each row must contain each number.col„‡0 0 1 1 1 1 1 1 1 1/†z © .. col .. .. .. .. .. ..box„‡1 0 1 0 1 1 1 1 1 1/†z © .. box .. .. .. .. .. ..all„‡1 1 1 1 0 0 1 1 1 1/†z © each cell must contain a number.same„­/°(1 0 0 0 1 0 0 0°›) © matching pairs.same¨row,col,box,all© constraints matrix for ¾ ¾-puzzle.}589


s99 © puzzle0 0 1 6 9 0 5 0 04 0 0 2 7 0 0 0 10 7 0 0 0 0 0 9 00 0 0 0 0 0 0 3 00 0 0 4 3 0 0 0 70 0 0 7 8 0 6 0 00 0 6 0 0 0 8 0 50 2 0 1 4 0 0 6 00 1 0 3 5 0 0 4 0sudokuX s992 8 1 6 9 3 5 7 44 6 9 2 7 5 3 8 15 7 3 8 1 4 2 9 67 9 2 5 6 1 4 3 86 5 8 4 3 9 1 2 71 3 4 7 8 2 6 5 93 4 6 9 2 7 8 1 59 2 5 1 4 8 7 6 38 1 7 3 5 6 9 4 2© solution.Technical notes:Each row in the constraints matrix (smat ¾) represents the placement of a number1..9 in one of the 9×9 cells:9×9×9 … 729 rows.There are four column groups to code for the requirement that each number 1..9be represented in each of 9 rows (ColsR), 9 columns (ColsC) and 9 boxes (ColsB),together with the rule that every cell be occupied (ColsA).4×9×9 … 324 columns.This (¾ 4×¾*2) boolean constraint matrix is invariant for a square sudoku puzzleof size ¾ ¾ and may be pre-fabricated and used for any number of specific instancesof puzzles of this size.Labelling the Rows, Cols and Boxes of a shape ¾ ¾ Sudoku puzzle: R1..R¾, C2..C¾,B1..B¾, and calling the four column groups ColsR, ColsC, ColsB and ColsA:Rows: ¾×¾×¾ possible actions:Place; 1 in R1C1; place 2 in R1C1; ... place ¾ in R1C1;Place; 1 in R1C2; place 2 in R1C2; ... place ¾ in R1C2;...Place; 1 in R¾C¾; place 2 in R¾C¾; ... place ¾ in R¾C¾.ColsR ¾×¾ requirements (all numbers appear in each puzzle Row):R1 contains 1; R1 contains 2; ... R1 contains ¾;R2 contains 1; R2 contains 2; ... R2 contains ¾;...R¾ contains 1; R¾ contains 2; ... R¾ contains ¾.ColsC ¾×¾ requirements (all numbers appear in each puzzle Col):C1 contains 1; C1 contains 2; ... C1 contains ¾;C2 contains 1; C2 contains 2; ... C2 contains ¾;...C¾ contains 1; C¾ contains 2; ... C¾ contains ¾.ColsB ¾×¾ requirements (all numbers appear in each puzzle Box):B1 contains 1; B1 contains 2; ... B1 contains ¾;B2 contains 1; B2 contains 2; ... B2 contains ¾;...B¾ contains 1; B¾ contains 2; ... B¾ contains ¾.590


ColsA ¾×¾ requirements (each cell is occupied at most once):R1C1 occupied; R1C2 occupied; ... R1C¾ occupied;R2C1 occupied; R2C2 occupied; ... R2C¾ occupied;...R¾C1 occupied; R¾C2 occupied; ... R¾C¾ occupied;Given a specific puzzle to be solved, rows are removed from a copy of this genericmatrix to represent numbers that may not be placed in pre-populated cells.For example, given the 4×4 puzzle:0 0 0 00 0 2 13 0 0 40 0 0 0we would remove 12 rows corresponding to placements of:m[2;3]„2 … remove 3 rows m[2;3] ¹ 1 3 4m[2;4]„1 … remove 3 rows m[2;4] ¹ 2 3 4m[3;1]„3 … remove 3 rows m[3;1] ¹ 1 2 4m[3;4]„4 … remove 3 rows m[3;4] ¹ 1 2 3Coding details--------------For the solver:sudokuX„{ŒML ŒIO„1n n„½¾¸„smat nr„¹(¾¬0)>(›¼n)¹¨¾m„(~r)š¸f„X mz„(~r)\fn n½z/(½z)½¼n}© Exact cover Sudoku solver.© n×n puzzle.© generic ¾×¾ constraint matrix.© already placed rows.© reduced matrix.© exact cover.© merge of placements.© solution matrix.Taking the lines one at a time:[0] sudokuX„{ŒML ŒIO„1 © Exact cover Sudoku solver.Index-origin is set to 1 so that ¼9 produces numbers 1..9, leaving 0 free forunoccupied cells.Migration level is set to 1 for the enlist (¹) function on line[3].[1] n n„½¾ © n×n puzzle.Sets n to the scalar value of the number of rows (and columns) of the squarepuzzle. The squareness =/½¾ is not enforced by this statement and in fact nwinds up as the number of columns, irrespective of the number of rows. But thecode at least hints that the number of rows and columns is assumed to be thesame.[2] ¸„smat n © generic ¾ ¾-matrix.A pre-computed generic contraints matrix may be passed as left argument but, ifnot, this statement computes it. Doing so takes a second or so, so it is worthwhilestoring the value if many puzzles of a particular size are to be solved.The boolean matrix could be bound (composed) with the solver to derive a newmonadic function, thus:sx99 „ (smat 9 9)°sudokuX© 9 9-sudoku solver.591


[3] r„¹(¾¬0)>(›¼n)¹¨¾ © already placed rows.Give the above 4×4 puzzle,0 0 0 00 0 2 13 0 0 40 0 0 0the rightmost segment of this line:r„¹(¾¬0)>(›¼n)¹¨¾ © already placed rows.¯¯¯¯¯¯¯¯produces a matrix of masks for the already placed numbers.Ú…ÎÎÎÎÎÎÂÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎ̇0 0 0 0Û0 0 0 0Û0 0 0 0Û0 0 0 0ÛÃ~ÎÎÎÎÎ…Ï~ÎÎÎÎÎ…Ï~ÎÎÎÎÎ…Ï~ÎÎÎÎÎ…ÝÛ0 0 0 0Û0 0 0 0Û0 1 0 0Û1 0 0 0ÛÃ~ÎÎÎÎÎ…Ï~ÎÎÎÎÎ…Ï~ÎÎÎÎÎ…Ï~ÎÎÎÎÎ…ÝÛ0 0 1 0Û0 0 0 0Û0 0 0 0Û0 0 0 1ÛÃ~ÎÎÎÎÎ…Ï~ÎÎÎÎÎ…Ï~ÎÎÎÎÎ…Ï~ÎÎÎÎÎ…ÝÛ0 0 0 0Û0 0 0 0Û0 0 0 0Û0 0 0 0ÛÀ~ÎÎÎÎÎ…Á~ÎÎÎÎÎ…Á~ÎÎÎÎÎ…Á~ÎÎÎÎÎ…Ùthe second part:r„¹(¾¬0)>(›¼n)¹¨¾ © already placed rows.¯¯¯¯¯¯delivers a matrix of masks of disallowed numbers per cell:Ú…ÎÎÎÎÎÎÂÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎ̇0 0 0 0Û0 0 0 0Û0 0 0 0Û0 0 0 0ÛÃ~ÎÎÎÎÎ…Ï~ÎÎÎÎÎ…Ï~ÎÎÎÎÎ…Ï~ÎÎÎÎÎ…ÝÛ0 0 0 0Û0 0 0 0Û1 0 1 1Û0 1 1 1ÛÃ~ÎÎÎÎÎ…Ï~ÎÎÎÎÎ…Ï~ÎÎÎÎÎ…Ï~ÎÎÎÎÎ…ÝÛ1 1 0 1Û0 0 0 0Û0 0 0 0Û1 1 1 0ÛÃ~ÎÎÎÎÎ…Ï~ÎÎÎÎÎ…Ï~ÎÎÎÎÎ…Ï~ÎÎÎÎÎ…ÝÛ0 0 0 0Û0 0 0 0Û0 0 0 0Û0 0 0 0ÛÀ~ÎÎÎÎÎ…Á~ÎÎÎÎÎ…Á~ÎÎÎÎÎ…Á~ÎÎÎÎÎ…Ù... the enlist (¹) of which is a boolean mask vector of which rows are to be removedfrom the constraint matrix for this puzzle instance, as in the followingline:[4] m„(~r)š¸ © reduced matrix.m is a reduced-rows matrix for this puzzle instance.[5] f„X m © exact cover.Line[5] finds the exact cover for the reduced matrix and line[6]:[6] z„(~r)\f © merge of placements.... expands this to a row selection for the presented puzzle, including its preplacednumbers. Finally, line[7]:[7] n n½z/(½z)½¼n © solution matrix.592


presents this allocation of numbers to cells as a solution in the standard form:2 1 4 34 3 2 13 2 1 41 4 3 2For the function that generates the generic constraints matrix:smat„{© Matrix for ¾ ¾-Sudoku puzzle.z„,[¼6],[6+¼4]¼10½¾*÷2© cell coordinate properties.row„‡1 1 0 0 1 1 1 1 1 1/†z © each row must contain each number.col„‡0 0 1 1 1 1 1 1 1 1/†z © .. col .. .. .. .. .. ..box„‡1 0 1 0 1 1 1 1 1 1/†z © .. box .. .. .. .. .. ..all„‡1 1 1 1 0 0 1 1 1 1/†z © each cell must contain a number.same„­/°(1 0 0 0 1 0 0 0°›) © matching pairs.same¨row,col,box,all© constraints matrix for ¾ ¾-puzzle.}Taking the lines one at a time:[1] z„,[¼6],[6+¼4]¼10½¾*÷2 © cell coordinate properties.It is easier to address the cells at square-within-box resolution. For the above4×4 puzzle:ÚÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÌÛ 0 Û 0 Û 0 Û 0 ÛÃÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝÛ 0 Û 0 Û 2 Û 1 ÛÃÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝÛ 3 Û 0 Û 0 Û 4 ÛÃÎÎÎÏÎÎÎÏÎÎÎÏÎÎÎÝÛ 0 Û 0 Û 0 Û 0 ÛÀÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÙThe cell coordinates would be:ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛÚÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÌÛÚÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÌÛÛÛÚÎÎÎÂÎÎÎÌÛÚÎÎÎÂÎÎÎÌÛÛÛÚÎÎÎÂÎÎÎÌÛÚÎÎÎÂÎÎÎÌÛÛÛÛÛ1 1Û1 1ÛÛÛ1 1Û1 2ÛÛÛÛÛ1 2Û1 1ÛÛÛ1 2Û1 2ÛÛÛÛÛÀÎÎÎÁÎÎÎÙÛÀÎÎÎÁÎÎÎÙÛÛÛÀÎÎÎÁÎÎÎÙÛÀÎÎÎÁÎÎÎÙÛÛÛÃÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÝÛÃÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÝÛÛÛÚÎÎÎÂÎÎÎÌÛÚÎÎÎÂÎÎÎÌÛÛÛÚÎÎÎÂÎÎÎÌÛÚÎÎÎÂÎÎÎÌÛÛÛÛÛ1 1Û2 1ÛÛÛ1 1Û2 2ÛÛÛÛÛ1 2Û2 1ÛÛÛ1 2Û2 2ÛÛÛÛÛÀÎÎÎÁÎÎÎÙÛÀÎÎÎÁÎÎÎÙÛÛÛÀÎÎÎÁÎÎÎÙÛÀÎÎÎÁÎÎÎÙÛÛÛÀÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÙÛÀÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÙÛÃÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÝÛÚÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÌÛÚÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÌÛÛÛÚÎÎÎÂÎÎÎÌÛÚÎÎÎÂÎÎÎÌÛÛÛÚÎÎÎÂÎÎÎÌÛÚÎÎÎÂÎÎÎÌÛÛÛÛÛ2 1Û1 1ÛÛÛ2 1Û1 2ÛÛÛÛÛ2 2Û1 1ÛÛÛ2 2Û1 2ÛÛÛÛÛÀÎÎÎÁÎÎÎÙÛÀÎÎÎÁÎÎÎÙÛÛÛÀÎÎÎÁÎÎÎÙÛÀÎÎÎÁÎÎÎÙÛÛÛÃÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÝÛÃÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÎÎÝÛÛÛÚÎÎÎÂÎÎÎÌÛÚÎÎÎÂÎÎÎÌÛÛÛÚÎÎÎÂÎÎÎÌÛÚÎÎÎÂÎÎÎÌÛÛÛÛÛ2 1Û2 1ÛÛÛ2 1Û2 2ÛÛÛÛÛ2 2Û2 1ÛÛÛ2 2Û2 2ÛÛÛÛÛÀÎÎÎÁÎÎÎÙÛÀÎÎÎÁÎÎÎÙÛÛÛÀÎÎÎÁÎÎÎÙÛÀÎÎÎÁÎÎÎÙÛÛÛÀÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÙÛÀÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÙÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙFor example, the coordinates of the 4 in the third row, fourth column, are:ÚÎÎÎÂÎÎÎÌÛ2 2Û1 2Û box:2 2 ; cell:1 2ÀÎÎÎÁÎÎÎÙ593


It is convenient also to represent the numbers to be placed as a base ¾*÷2 pair.For a 9×9 puzzle, numbers 1..9 are represented:ÚÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÂÎÎÎÌÛ1 1Û1 2Û1 3Û2 1Û2 2Û2 3Û3 1Û3 2Û3 3ÛÀÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÁÎÎÎÙso, for example, the number 4 is represented as 2 1.This means that the rank-10 array:z„,[¼6],[6+¼4]¼10½¾*÷2© cell coordinate properties.¯¯¯¯¯¯¯¯encodes sufficient information to generate the constraint matrix. Ravelling thefirst six and last four axes:z„,[¼6],[6+¼4]¼10½¾*÷2© cell coordinate properties.¯¯¯¯¯¯¯¯¯¯¯¯produces a rank-2 (¾ 4×¾*2)-matrix, each of whose items is a 10-vector of theproperties of that particular constraint:br bc cr cc hi lo xr xc hi loÀÎÂÎÙ ÀÎÂÎÙ ÀÎÂÎÙ ÀÎÂÎÙ ÀÎÂÎÙÛ Û Û Û ÀÎÎÎ number: high/low digit.Û Û Û ÀÎÎÎÎÎÎÎÎÎÎ row/col coordinate.Û Û ÛÛ Û ÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ number: high/low digit.Û ÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ cell-within-box row/col coords.ÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ box row/col coords.Lines[2-5] can then select four coord/number pairs for comparison:[2] row„‡1 1 0 0 1 1 1 1 1 1/†z © each row must contain each number.[3] col„‡0 0 1 1 1 1 1 1 1 1/†z © .. col .. .. .. .. .. ..[4] box„‡1 0 1 0 1 1 1 1 1 1/†z © .. box .. .. .. .. .. ..[5] all„‡1 1 1 1 0 0 1 1 1 1/†z © each cell must contain a number.Line[6] defines a function for separation and comparison of the items of eachpair:[6] same„­/°(1 0 0 0 1 0 0 0°›) © matching pairs.and finally, line[7] applies this function to the catenation of the four columngroups:[7] same¨row,col,box,all © constraints matrix for ¾ ¾-puzzle.Back to …X„See also: sudoku.491 X.160ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎsufficient"It [Colossus II, commissioned 1944-06-01] contained 2400 valves and worked at aprocessing speed of 25,000 alphabetical characters per second. This was 125times the speed of mechanical processors, and sufficiently fast for the task inhand." - T.H.Flowers.594


ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎtruth_tablesBoolean <strong>functions</strong> and truth tables----------------------------------NB: There is substantial overlap between this article and Phil Last's …logic„.Boolean <strong>functions</strong> may be represented as "truth tables". Here are truth tablesfor ^ (and), Ÿ (or) and ¬ (not-equal):^ 0 1 Ÿ 0 1 ¬ 0 1ÚÎÎÎÂÎÎÎÌ ÚÎÎÎÂÎÎÎÌ ÚÎÎÎÂÎÎÎÌ0 Û 0 Û 0 Û 0 Û 0 Û 1 Û 0 Û 0 Û 1 ÛÃÎÎÎÏÎÎÎÝ ÃÎÎÎÏÎÎÎÝ ÃÎÎÎÏÎÎÎÝ1 Û 0 Û 1 Û 1 Û 1 Û 1 Û 1 Û 1 Û 0 ÛÀÎÎÎÁÎÎÎÙ ÀÎÎÎÁÎÎÎÙ ÀÎÎÎÁÎÎÎÙWe can represent these results in a more compact form by raveling the matrix:^ 0 0 0 1 Ÿ 0 1 1 1 ¬ 0 1 1 0Notice that each of the above vectors is the result of applying its dyadic functionbetween arguments 0 0 1 1 and 0 1 0 1.Here is the complete list of boolean <strong>functions</strong>:{¸^0^¾} 0 0 0 0^ 0 0 0 1> 0 0 1 0{¸Ÿ0^¾} 0 0 1 1< 0 1 0 0{¾Ÿ0^¸} 0 1 0 1¬ 0 1 1 0Ÿ 0 1 1 1‹ 1 0 0 0= 1 0 0 1{¾Š1Ÿ¸} 1 0 1 0‰ 1 0 1 1{¸Š1Ÿ¾} 1 1 0 0ˆ 1 1 0 1Š 1 1 1 0{¸Ÿ1Ÿ¾} 1 1 1 1© boolean <strong>functions</strong> (pervasive).We can check this by accumulating a list-of-<strong>functions</strong>, using operator …lof„, toapply each function in turn:bfns„{''} © initial boolean <strong>functions</strong> vector ...bfns „ bfns lof {¸^0^¾}bfns „ bfns lof ^bfns „ bfns lof >bfns „ bfns lof {¸Ÿ0^¾}bfns „ bfns lof


† 0 0 1 1 bfns 0 1 0 1 © check (pervasive) boolean <strong>functions</strong>.0 0 0 00 0 0 10 0 1 00 0 1 10 1 0 00 1 0 10 1 1 00 1 1 11 0 0 01 0 0 11 0 1 01 0 1 11 1 0 01 1 0 11 1 1 01 1 1 1For depth=0 arguments, the non-scalar (D) <strong>functions</strong> may be greatly simplified,as they are then not required to pervade their arguments:{0} 0 0 0 0 © boolean <strong>functions</strong> (non-pervasive).^ 0 0 0 1> 0 0 1 0• 0 0 1 1< 0 1 0 0€ 0 1 0 1¬ 0 1 1 0Ÿ 0 1 1 1‹ 1 0 0 0= 1 0 0 1{~¾} 1 0 1 0‰ 1 0 1 1{~¸} 1 1 0 0ˆ 1 1 0 1Š 1 1 1 0{1} 1 1 1 1(Of course, each of the above D-<strong>functions</strong> may be made pervasive by bindingit with the …perv„ operator:0 1 €perv ›0 10 1 0 10 1 •perv ›0 10 0 1 1).. etc.Boolean scans-------------Many of the <strong>functions</strong> derive interesting <strong>functions</strong> with scan (\). For example:^\ © leading 1s


ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎuksfrÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÂÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ····················Û////////////ÚÙ····································ÛÛ····················ÀÂÎÎÎÎÎÎÎÎÎÎÂÙ·····································ÛÛ·····················ÀÌ·········ÀÎÌ···U.K.·Shipping·Forecast·Regions···ÛÛ······················ÃÎÌ·S.E.····ÀÎÌ··································ÛÛ·····················ÚÙ·ÀÌ·Iceland··ÀÎÌ································ÛÛ·······^············ÚÙ···ÀÌ·······ÚÎÎÎÁÎÌ······························ÛÛ·······Û············Û·····ÀÎÌ31ÚÎÎÙ·····ÀÎÌ····························ÛÛ·····ÎÎNÎη········ÚÙ·······ÀÂÎÙ··········ÀÌ························ÚÎÎÛÛ·······Û···········Û·········ÀÎÌ··Faeroes··ÀÎÌ···················ÚÎÎÙ//ÛÛ·······Û··········ÚÙ···········ÀÌ············ÃÎÌ················ÚÙ/////ÛÛ·················ÚÙ··Bailey·····ÃÌ········ÚÎÎÙ·ÀÎÌ············ÚÎÙ//////ÛÛ·················Û·············ÚÙÀÌ30···ÚÎÙ······ÀÎÌ··········Û////////ÛÛ················ÚÙ·············Û··ÀÂÎÎÎÎÙ··········ÃÎÎÎÎÎÎÂÎÎÎÝ////////ÛÛ···············ÚÙ·············ÚÙ···ÀÎÌ··Fair·Isle··Û······ÛN.Utsire////ÛÛ···············ÃÎÌ28··········Û······ÀÌ············ÛVikingÛ2···ÚÎÙ/////ÛÛ··············ÚÙ·ÀÎÎÎÎÌ······ÚÙ·······ÀÎÌ29········Û······ÃÎÎÎÂÙ///////ÛÛ·············ÚÙ·······ÀÎÎÎÎÎÎÝ·Hebrides·ÀÂÎÎÌ······Û1·····ÛS.Utsire////ÛÛ·············Û···············Û··········ÚÙ//ÀÂÎÎÂÎÎÁÎÎÎÎÎÎÝ···ÚÙ///////ÛÛ············ÚÙ··············ÚÁÎÌ27·····ÚÙCromarty·········Û3··ÀÎÌ//////ÛÛ···········ÚÙ···············Û··ÀÎÎÎÎÎÌÚÙ/////ÀÌ5Û·········ÀÂÎÎÎÎÁÎÎÂÎÎÎÝÛ···········Û····Rockall····ÚÙ········ÃÙ//////ÚÁÎÝ·Forties··ÛFisher·ÀÌ··ÛÛ··········ÚÙ···············Û··Malin··ÀÎÌ//ÚForthÛ4·········Û9·······ÛÚÎÝÛ·········ÚÙ25·············ÚÙ··········ÚÙ//ÀÌ6·ÚÎÏÎÎÎÎÎÎÎÎÎÎÏÎÎÎÎÎÎÎÂÁÙ/ÛÛ········ÚÁÎÎÎÌ············Û26··ÚÎÎÎÎÌ·ÀÌ///ÀÎÂÙ7ÀÌ·········Û·······Û///ÛÛ········Û····ÀÎÎÎÎÌ······ÚÙÚÎÎÎÙ////Û·ÚÙ/////ÀÌT·ÀÌ········Û·······Û///ÛÛ·······ÚÙ·········ÀÎÎÎÌ··ÛÚÙ////////ÃÎÁÎÎÌ////Û·y·Û·Dogger·ÛGerman·ÀÌ//ÛÛ·······Û··············ÀÎÎÁÁÌ//////ÚÎÙ····Û////ÀÌ·nÀÌ·······Û·Bight··Û//ÛÛ······ÚÙ··················ÚÙ//////ÛIrish·Û/////ÀÌ·eÛ8······Û········ÀÌ/ÛÛ·····ÚÙ·····Shannon·····ÚÎÙ//////ÚÙSeaÚÎÎÙ//////ÃÎÎÁÎÎÎÎÎÎÎÁÎÎÌ10····Û/ÛÛ····ÚÙ·················ÚÝ////////Û····Û/////////Û11··Humber··ÚÁÌ·ÚÎÎÎÙ/ÛÛ····ÃÎÎÌ24·············ÛÀÎÎÎÎÎÎÎÎÏÌ23ÚÙ/////////ÀÎÎÂÎÎÎÎÎÎÎÎÎÝ/Û·Û/////ÛÛ···ÚÙ··ÀÎÎÎÎÎÌ·········Û········ÚÙÀÂÎÙ/////////////ÛThames·ÚÎÙ/ÀÎÙ/////ÛÛ··ÚÙ·········ÀÎÎÎÎÎÎÌ··Û·FastnetÛ21ÀÎÎÌ///////////ÚÙ12···ÚÎÙ///////////ÛÛ··Û·················ÀÎÎÁÎÌ22···ÚÙLundyÙ/////////ÚÎÙ·ÚÎÎÎÎÝ/////////////ÛÛ·ÚÙ20·········Sole·······ÀÎÎÎÌ·Û·ÚÎÎÙ///////////ÀÂÎÎÙDover/////////////ÛÛ·ÃÎÎÎÎÎÌ·····················ÀÎÏÎÁÎÎÎÂÎÎÎÎÎÂÎÎÎÎÎÝ13ÎÎÎÎÙ//////////////ÛÛÚÙ·····ÀÎÎÎÎÎÌ················ÚÙPly-·ÛPort-ÛWightÛÚÙ///////////////////ÛÃÙ············ÀÎÎÎÎÌ···········Û·mouthÛlandÎÝ14·ÚÎÁÙ////////////////////ÛÛ··················ÀÎÎÎÎÎÌ····ÚÙ16····Û15·Û/ÀÎÎÎÙ///////////////////////ÛÛ························ÀÎÎÎÎÏÎÎÌ·ÚÎÎÁÎÎÎÙ/////////////////////////////ÛÛ·····························Û··ÀÎÁÌ///////////////////////////////////ÛÛ····························ÚÙ·····ÀÎÎÌ////////////////////////////////ÛÛ····························Û·········ÀÌ///////////////////////////////ÛÛ···························ÚÙ··········Û///////////////////////////////ÛÛ······Fitzroy··············Û···········ÀÌ//////////////////////////////ÛÛ··························ÚÙ············ÀÌ/////////////////////////////ÛÛ··························Û···Biscay·····Û/////////////////////////////ÛÛ·························ÚÙ·············ÚÙ/////////////////////////////ÛÛ····················ÚÎÎÌ·Û17············Û//////////////////////////////ÛÛ·················ÚÎÎÙ//ÀÎÁÎÎÌ··········ÚÙ//////////////////////////////ÛÛ·················Û//////////ÀÎÎÎÎÌ·····Û///////////////////////////ÚÎÎÎÝÃÌ19··············Û///////////////ÀÎÎÎÎÎÙ////////////////////////ÚÎÎÙ···ÛÛÀÎÎÎÎÎÎÎÌ········Û///////////////////////////////////ÚÎÎÎÎÌ///ÚÎÙ······ÛÛ········ÀÎÎÎÎÌ···Û/////////////////////////////////ÚÎÙ····ÀÎÎÎÙ········ÛÛ·············ÀÎÎÂÙ/////////////////////////////////Û···················ÛÛ···············ÚÙ//////////////////////////////////Û···················ÛÛ··Trafalgar····Û////////////////////////////////ÚÎÎÙ···················ÛÛ·············ÚÎÙ////////////////////////////ÚÎÎÎÙ······················ÛÛ·············Û////////////////////////////ÚÎÙ··························ÛÛ18···········Û///////////////////////////ÚÙ····························ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÁÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙ597


Adjacency graph:ÚÎÎÎÎÎÎ31Û ÛÛ ÛÛ Û28ÎÎÎÎÎÎ30ÎÎÎÎÎÎÎÌ ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ2ÛÀÎÌ Û Û Û ÛÛ ÀÎÌ Û Û Û ÛÛ ÀÎÌÛ Û Û ÛÚÎÎÎÎÎÎ25ÎÎÎÎÎÎ27ÎÎÎÎÎÎ29ÎÎÎÎÎÎÎ1ÎÎÎÎÎÎÎÌ ÛÛ Û Û ÛÀÎÌ Û Û ÛÛ Û Û Û ÀÎÌ Û Û ÛÛ Û Û Û ÀÎÌÛ Û ÛÚÎÎÎÎÎÎ24ÎÎÎÎÎÎ26ÎÎÎÎÎÎÎÙ 5ÎÎÎÎÎÎÎ4ÎÎÎÎÎÎÎ3ÎÎÎÎÎÎÎÙÛ Û Û Û ÚÎÙÛÀÎÌ ÛÛ Û Û Û ÚÎÙ Û ÀÎÌ ÛÛ Û Û ÛÚÎÙ Û ÀÎÌÛÚÎÎÎÎÎÎ20ÎÎÎÎÎÎ22 Û 6Ù Û À9Û Û Û Û Û Û ÛÛ Û Û Û Û Û ÛÛ Û Û Û Û Û ÛÛ Û 21ÎÎÎÎÎÎ23 7ÎÎÎÎÎÎÎ8ÎÎÎÎÎÎ10Û Û Û Û Û ÛÛ Û Û Û Û ÛÛ Û Û Û Û ÛÛ ÀÎÎÎÎÎÎ16ÎÎÎÎÎÎÎÌ ÀÎÎÎÎÎÎ11ÎÎÎÎÎÎÎÙÛ Û Û ÛÛ Û Û ÛÛ Û Û Û19ÎÎÎÎÎÎÎÎÎÎÎÎÎÎ17 15ÎÎÎÎÎÎ14ÎÎÎÎÎÎ13ÎÎÎÎÎÎ12ÛÛÛ18Graph specification:names „ 'Viking' 'North Utsire' 'South Utsire' 'Forties' 'Cromarty'graph „ (2 3 4 29) (1 3) (1 2 4 9) (1 3 5 6 8 9 29) (4 6 29)ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎunicodeUnicode characters¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯This workspace is maintained using <strong>Dyalog</strong> V12 in order that all supported versionsof the interpreter will be able to load it. However, function …xhtml„ wouldlike to display some Unicode characters, which are not available in classic V12,in its web-pages.The following table provides translation from special ŒAV sequences into Unicodecharacters. This is used extensively in the notes on the layout of …keyboards„.This mechanism must be retained for as long as a classic (non-unicode) versionof the workspace is required.598


ÚfromÌ ÚtoÎÎÌÛÎÌ Û … Û¬ ÛÛ• ª Û … Û` ª ÛÛ• Ž Û … Û` Ž ÛÛ• „ Û … Û` „ ÛÛ†a Û … Ûª Û © Spanish Feminine Ordinal IndicatorÛ†o ªÛ … Ûº ª Û © Spanish Masculine Ordinal IndicatorÛ//÷ Û … Û´ ÷ ÛÛ//• Û … Û´ • ÛÛ// Û … Û´ ÛÛ' //Û … Û' ´ ÛÛ ¼_Û … Û ? ÛÛI ¼_Û … ÛI ? ÛÛY ¼_Û … ÛY ? ÛÛO ±¨Û … ÛO ? ÛÛ ±¨Û … Û ? ÛÛ °¨Û … Û ? ÛÛJ °¨Û … ÛJ ? ÛÛ°* “Û … Û¤ “ Û © Unicode Currency SignÛ Œ:Û … Û ? ÛÛ? Œ:Û … Û? ? ÛÛ_ Œ:Û … Û_ ? ÛÛL Œ:Û … ÛL ? ÛÛK Œ=Û … ÛK ? ÛÛ Œ=Û … Û ? ÛÛ: Œ:Û … Û: ? ÛÛ+ Œ:Û … Û+ ? ÛÛ§ Œ:Û … Û§ ? ÛÛ1/2ªÛ … Û½ ª ÛÛ• Û … Û€ ÛÛ5 • Û … Û5 € ÛÛe • Û … Ûe € ÛÛmu Û … Ûm ÛÛmu •Û … Ûm • ÛÛmu ]Û … Ûm ] ÛÛ2_ Û … Û² ÛÛ3_ Û … Û³ ÛÛ°° Û … Û° ÛÛ° « Û … Û° « ÛÛ2_ª Û … Û² ª ÛÛ || Û … Û ¦ Û © French broken barÛ '' Û … Û ` Û © French gràveÛ E= Û … Û € ÛÛacutÛ … Û ´ ÛÛgravÛ … Û ` ÛÛtildÛ … Û ? ÛÛ °× Û … Û ¤ ÛÛ° ) Û … Û° ) ÛÛ< ||Û … Û< ? Û © Finnish Alt-GrÛm ||Û … Ûm ? ÛÛ+- Û … Û± ÛErdös … Erd?s © Paul Erdös in notes.oscŒ= … &#9016 © key operator°¨ … &#9060 © rank operatorÀfromÙ ÀÎÎtoÙNB: This page is specifically excluded from translation to show what's going on.See also: xhtml.374 keyboards.451599


ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎBritish_Calendar_Act_1751British Calendar Act of 1751For The Year 1752·C A P. XXIII.A.D. 1751. Anno vicesimo quarto GEORGII II.An Act for Regulating the Commencement of the Year;and for Correcting the Calendar now in Use.·Amended by 25 Geo. 2. c. 30.'·WHEREAS the legal Supputation of the Year of our Lord in that Part of GreatBritain called England, according to which the Year beginneth on the 25th Day ofMarch, hath been found by Experience to be attended with divers Inconveniencies,not only as it differs from the Usage of neighbouring Nations, but also from thelegal Method of Computation in that Part of Great Britain called Scotlond, andfrom the common Usage throughout the whole Kingdom, and thereby frequentMistakes are occasioned in the Dates of Deeds, and other Writings, and Disputesarise therefrom: •And whereas the Calendar now in Use throughout all hisMajesty's British Dominions, commonly called The Julian Calendar, hath beendiscovered to be erroneous, by means whereof the Vernal or Spring Equinox, whichat the Time of the General Council of Nice in the Year of our Lord 325, happenedon or about the 21st Day of March, now happens on the 9th or 10th Day of thesame Month; and the said Error is still increasing, and if not remedied, would,in Process of Time, occasion the several Equinoxes and Solstices to fall at verydifferent Times in the Civil Year from what they formerly did, which might tendto mislead Persons ignorant of the said Alteration: •And whereas a Method ofcorrecting the Calendar in such manner, as that the Equinoxes and Solstices mayfor the future fall nearly on the same nominal Days, on which the same happenedat the Time of the said General Council, hath been received and established, andis now generally practiced by almost all other Nations of Europe: •And whereasit will be of general Convenience to Merchants, and other Persons correspondingwith other Nations and Countries, and tend to prevent Mistakes and Disputes inor concerning the Dates of Letters, and Accounts, if the like Correction bereceived and established in his Majesty's Dominions: 'May it therefore pleaseyour Majesty, that it may be enacted, and be it enacted by the King's mostExcellent Majesty, by and with the Advice and Consent of the Lords Spiritual andTemporal, and Commons, in this present Parliament assembled, and by theAuthority of the same,·The old Supputation of the Year not to be made use of after Dec. 1751. Year tocommence, for the future, on 1 Jan.·That in and throughout all his Majesty's Dominions and Countries in Europe,Asia, Africa, and America, belonging or subject to the Crown of Great Britain,the said Supputation, according to which the Year of our Lord beginneth on the25th Day of March, shall not be made use of from and after the last Day ofDecember 1751; and that the first Day of January next following the said lastDay of December shall be reckoned, taken, deemed and accounted to be the firstDay of the Year of our Lord 1752; and the first Day of January, which shallhappen next after the said first Day of January 1752, shall be reckoned, taken,deemed and accounted to be the first Day of the Year of our Lord 1753; and soon, from Time to Time, the first Day of January in every Year, which shallhappen in Time to come, shall be reckoned, taken, deemed and accounted to be thefirst Day of the Year; and that each new Year shall accordingly commence, andbegin to be reckoned, from the first Day of every such Month of January nextpreceding the 25th Day of March, on which such Year would, according to thepresent Supputation, have begun or commenced:·The Days to be numbered as now until 2 Sept. 1752; and the Day following to beaccounted 14 Sept. omitting 11 Days.600


And that from and after the said first Day of January 1752, the several Days ofeach Month shall go on, and be reckoned and numbered in the same Order; and theFeast of Easter, and other moveable Feasts thereon depending, shall beascertained according to the same Method, as they now are, until the 2nd Day ofSeptember in the said Year 1752 inclusive; and that the natural Day nextimmediately following the said 2nd Day of September, shall be called, reckonedand accounted to be the 14th Day of September, omitting for that Time only the11 intermediate nominal Days of the common Calendar; and that the severalnatural Days, which shall follow and succeed next after the said 14th Day ofSeptember, shall be respectively called, reckoned and numbered forwards innumerical Order from the said 14th Day of September, according to the Order andSuccession of Days now used in the present Calendar; and that all Acts, Deeds,Writings, <strong>Notes</strong> and other Instruments of what Nature or Kind soever, whetherEcclesiastical or Civil, Publick or Private, which shall be made, executed orsigned, upon or after the said first Day of January 1752, shall bear Dateaccording to the said new Method of Supputation,·Ref: http://webexhibits.org/calendars/year-text-British.htmlÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎEulere raised to the pi times i,And plus 1 leaves you nought but a sigh,This fact amazed Euler,That genius toiler,And still gives us pause, bye the bye.ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎGregorian_calendarGregorian and Julian Calendars------------------------------The time taken for the Earth to orbit the sun is approximately 365.242198 days.This means that in order to avoid drifting from the solar year, a calendar mustcorrect for the extra 0.242198 day (05:48:45.9072) each year.The Romans attempted to accommodate this extra time with the Julian calendar,established by Julius Caesar in 45 BCE. The Julian calendar added an extra dayto each fourth (leap) year, producing an approximation of 365.25 days.By the sixteenth century, it became apparent that the Julian calendar was out ofsynch with the solar year by well over a week.The Gregorian calendar, proposed by Neapolitan physician Aloysius Lilius, wasintroduced to correct for this error. In accordance with recommendations fromthe Council of Trent (1545-1563), it was decreed by Pope Gregory XIII in papalbull "Inter Gravissimas" on Feb 24, 1582.In most of continental Europe, the new calendar came into effect on October 4th,1582, with the removal of the following 10 days. This meant that, in Rome forexample, the day following October 4th was October 15th. France followed shortlyafter, on December 9th of the same year.In Great Britain (UK) however, the new calendar was not adopted until the…British_Calendar_Act_1751„, which removed 11 days September 3-13 in 1752. Differentstates in the US adopted the changes at different times, depending upontheir allegiance to Rome, Paris or London. See …gcr„.All of this means that when converting historical dates in the Julian, as opposedto the modern Gregorian calendar, we must be careful to specify when thechange took place. For example, specific dates in the seventeenth century do notrefer to the same day when quoted in French or British sources. The problem evenoccurs in adjacent states in the US! See …gcr„.Both …days„ and …date„ take the date of the Julian to Gregorian change as anoptional left argument. …gcr„ lists arguments for various locations.601


The Gregorian calendar approximates the solar year as 365+97÷400 = 365.2425 dayswhich means that it takes approximately 3,300 years to shift one day relative tothe true solar year.The approximation 356+97÷400 is achieved by an injecting an extra 97 "leap" daysevery 400 years, using the rule:Extra days / 400 yearsEach year in 400 has 365 days, · · · · · · 0· except that every 4 years is a leap year, · · +100· · except that every 100 years isn't, · · · -4· · · except that every 400 years is. · · · +1----97¯¯¯¯The rule could be extended to give ever-closer approximations to the true (correctto 9 sig. figs) solar year of 365.242198 days. Astronomer John Herschel(1792-1871), and others, proposed a closer approximation of:365 + 969 ÷ 4000 … 365.24225 days.This correction would require that every 4,000 year period include only 969 extradays, compared with the Gregorian calendar's 970, suggesting the additionalrule:· · · · except that every 4,000 years isn't.To date, no-one has implemented Herschel's suggestion.See also: mayan.465 date.358 days.356 gcr.544See also: British_Calendar_Act_1751.598ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎJitSubFast BT division-by-2 using "Just-in-Time Subtraction" (LeRoy Eide)-------------------------------------------------------------------John Halleck provides this description of LeRoy Eide's very nifty algorithm forbalanced ternary division-by-2. Notice that the algorithm is unusual in that itgenerates digits of the result from least- to most-significant (right-to-left).This is based on work originally presented at the Utah Logic Group.See: http://web.utah.edu/utahlogicThe method is best illustrated using the more familar base-10 and division by 9.LeRoy points out that q = (10×q)-9×q, so we could get q by subtracting our known9×q from 10×q. Ah... I hear you think... we don't happen to know 10×q either.True, but we know something about it, namely that it ends in a zero ...For example, suppose we want to divide 1332 by 9 to find quotient q, so that1332 = 9×q. OK, let's set this up:10q = . . . 0-9q = 1 3 3 2=================q = . . . .We actually have enough information to compute the last column:¯110q = . . . 0-9q = 1 3 3 2=================q = . . . 8„ borrow602


But if the last digit of q is 8, then the next to last digit of 10×q must alsobe 8.¯110q = . . 8 0-9q = 1 3 3 2=================q = . . . 8And we have enough information to compute the next digit of q (and therefore thenext digit of 10×q)10q = . 4 8 0-9q = 1 3 3 2=================q = . . 4 8And now we have enough to compute the next digit of q and 10×q:10q = 1 4 8 0-9q = 1 3 3 2=================q = . 1 4 8And we're done!10q = 1 4 8 0-9q = 1 3 3 2=================q = 0 1 4 8Observations------------The method clearly extends to:1. Division by 99, 999, ... ¯1+10*¾.2. Division by base+1 (rather than base-1)3. Number bases other than 10 (including balanced ternary).In the case of balanced ternary numbers, this gives us fast division by 2, 4, 8and 10 (among others).Balanced Ternary Division by 2------------------------------Here is John's worked example for balanced ternary numbers:Suppose we want BT: 1 1 0 (decimal 12) divided by 2.To subtract a balanced ternary number, we just add it's negation:We have 2q = 1 1 0so -2q = ¯1 ¯1 0Then the steps are similar to the decimal example above:3q = . . . . 0+ -2q = 0 0 ¯1 ¯1 0===================q = . . . . .We can fill in the rightmost digit of q, since this is an addition problem, andwe have both low order digits:603


3q = . . . . 0+ -2q = 0 0 ¯1 ¯1 0===================q = . . . . 0But now we know the low order digit of q, we therefore know the next to the loworder digit of 3q, since it is identical. (since 3q is q shifted left by one).3q = . . . 0 0+ -2q = 0 0 ¯1 ¯1 0===================q = . . . . 0Now the second column is a straightforward addition problem (0 plus ¯1) and wecan compute the second digit (¯1) and fill that digit in for q, and the sameknowledge in 3q:3q = . . ¯1 0 0+ -2q = 0 0 ¯1 ¯1 0===================q = . . . ¯1 0And, lo, we can now do the arithmetic to compute the next digit (with a carrythis time).¯13q = . 1 ¯1 0 0+ -2q = 0 0 ¯1 ¯1 0===================q = . . 1 ¯1 0„ carryAnd the next ...¯13q = . 1 ¯1 0 0+ -2q = 0 0 ¯1 ¯1 0===================q = . 0 1 ¯1 0And so on.3q = 0 1 ¯1 0 0+ -2q = 0 0 ¯1 ¯1 0===================q = 0 0 1 ¯1 0And we have our answer.But what if there's a remainder?--------------------------------On the face of it, the method seems to run into a problem if the dividend is notan exact multiple of the divisor. But we can fix it.The effect is that the difference between (base-1) and the remainder is subtractedfrom _each_ digit position, so we can recover this as it falls off theleft side of the result and add it back, vector-wise, to each column. Then, allthat remains to do is to normalise any columns that have overflowed (‰base).LeRoy points out that an alternative approach for balanced ternary division by 2is to start by subtracting its parity (2|) from the dividend, rendering it evenand thus divisible by 2 without remainder.604


The of a BT number is:if the number has only a single digit (¯1 0 1), then its absolute value;otherwise, the of the (BT) sum of its digits.See …bt„ for more on this.Coding in D-----------Here is a D-coding for decimal (base-10) fast division by 9 with remainder. Themethod suggests a right-to-left reduction, which deduces a digit at a time intoan accumulating argument: †scan/... If no remainder pops out of the left side ofthe reduction, we're done: rem=0: ... Otherwise, we add the remainder to eachcolumn (rem+rslt) and normalise (carry overflows forward) the result in a secondreduction: †norm/...Remember that LeRoy's just-in-time subtraction method (conveniently) operatesright-to-left, in contrast with traditional left-to-right division.decimal_div_9„{scan„{(enc-¸-+/2†¾),1‡¾}nlz„{(-1—+/Ÿ\0¬¾)†¾}enc„0 10°‚rslt„1‡†scan/0,¾,0rem„9|9-1†rsltrem=0:(nlz rslt)rem© Fast decimal division-by-9 - LeRoy Eide.© pair-wise deduction of digits.© without superfluous leading zeros.© 2-digit decimal encode.© remainder, quotient.© remainder.© exact divide: quotient and 0-remainder.}norm„{(¸ 0+enc «½¾),1‡¾}rslt„1‡†norm/0,rem+rslt(nlz rslt)rem© pair-wise overflow resolution.© vector-sum of rem with each digit.© integer quotient and remainder.disp div9 1 2 3 4 5Ú…ÎÎÎÎÎÎÂÎÌÛ1 3 7 1Û6ÛÀ~ÎÎÎÎÎ…Á…Ù© 12345÷9 … 1371r6(While in keeping with its surroundings, the normalisation code is less thanoptimal. Rather than digit-by-digit reduction, it would be faster to use aparallel shift-carry function:norm„{© decimal digit overflow normalisation.10^.>¾:¾ © all digits in range 0..9: done.’ +š1 0²0 10‚¾ © otherwise: shift-carry-add and try again.}Note that from <strong>Dyalog</strong> V11, this could be coded using a fixpoint functionderived from the power operator ÿ:norm „ {+š1 0²0 10‚¾}ÿ­© decimal digit vector normalisation.or:norm „ +š°(1 0°²)°(0 10°)ÿ­ © decimal digit vector normalisation.) © see …derive„Balanced Ternary----------------To change our decimal division-by-9 function to balanced ternary division-by-2,we need change only the encode function (enc) and divisor (9). This suggestsabstracting an operator, which takes these as left and right operands ¸¸ and ¾¾:fast_div„{© Fast division by ¾¾ - LeRoy Eide.605


scan„{(enc-¸-+/2†¾),1‡¾} © pair-wise deduction of digits.nlz„{(-1—+/Ÿ\0¬¾)†¾} © without superfluous leading zeros.enc„¸¸© 2-digit encode.}rslt„1‡†scan/0,¾,0rem„¾¾|¾¾-1†rsltrem=0:(nlz rslt)remnorm„{(¸ 0+enc «½¾),1‡¾}rslt„1‡†norm/0,rem+rslt(nlz rslt)rem© remainder, quotient.© remainder.© exact divide: quotient and 0-remainder.© pair-wise overflow resolution.© vector-sum of rem with each digit.© integer quotient and remainder.We are now in a position to derive <strong>functions</strong> for decimal_division_by_9 and balanced_ternary_division_by2:enc_dec „ 0 10°‚© 2-digit decimal encode.dec_div_9 „ enc_dec fast_div 9 © decimal divide-by-9.©disp dec_div_9 1 2 3 4 5 © decimal 12345÷9 … 1371r6Ú…ÎÎÎÎÎÎÂÎÌÛ1 3 7 1Û6ÛÀ~ÎÎÎÎÎ…Á…Ùenc_bt „ {¯1+0 3‚3ƒ1+0 3‚¾}bt_div_2 „ enc_bt fast_div 2disp bt_div_2 1 0 ¯1 ¯1Ú…ÎÎÎÎÎÂÎÌÛ1 1 ¯1Û1ÛÀ~ÎÎÎÎ…Á…Ù© 2-digit balanced ternary encode.© bt divide-by-2.© __ _ _© balanced ternary 1011÷11 … 111r1See also: ratrep.556 ratsum.308 bt.258 derive.535Back to Balanced Ternary Arithmetic: …bt„606


ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎMarilyn777777777777$7777$$$$$$$$$$$$$$$$$$$$$$$$7$77$77I?+==========+?II7$$$$$$$$$$$$$$77777777777777777777$$$$$$$7$$$$$$$$$$$7777III======~~~~~===~~~~~=?I777$$$$$$$$$77777777777777777777777777$$$$$$$$$$$7II??++====++===~~~~~~===~~==~~=~~+?$$$$$$$77777777777777777777777777777$7777I?+=~~:~~~~======~~~~========~=~======~II777$$777777777777777777777$777$7777777?==~~~~::::~====~~~:=+++???=++=~~~~~++=====7$77777777777777777777777777777777I?+~~~=========~~~~~~~==+?????+?I??=~~========+?I77777777777777777777777777777I?+=======++?7I???=======+???III????I?=======~=+=+I777777777777777777777777777I??++++~~=+???7777$77??+=+????+?I77I????++=+=====+=~=?77777777777777777777777777I+?+===++=?II77$$$$Z$$77I??II?I??I$7?II??I++===+=+~~~+7777777777777777777777777I??+=~=====?II7$$$$$$Z$$7II?I??I???$I?II++?++=~~+===~~=77777777777777777777I77I??+===++?$$$Z$$$$$$$Z$ZZ$$77?7?+++++I+=I?==++=+~~++=~~~=7777777777777777777I??+==++=++?777$$$$$$$$$$$$ZZ$7II??++====+=+I=~~===+=~?+===~~77II7777777777777III=====++==+II?II7$$$$$$77$$$7III??=======+=+?==:~~=+++++=~~~=III7777777777II77$$7?+=~~~++=+?++7ZOZ$Z$$77$$ZIIII?=====+===+=+I+=~~~+I?+======+III7777777777?I777$$I+====?+==++=ZZOZZZZ$$$7777III+~=~~====~==+?+====+?+=~==+===III7777777777I?I$$7?++?II?+++====$$ZZZZZ77777$I7??======+++=+++=+++?I+?+==++++==IIIIII777777III?I7$$$$7777???+==+$$ZZ$$ZI77III7I???+?+++???++??++=III???????+++=IIIII7IIIIIII?+I77$$7777II$I???++77ZZO$7II?????I?I???IIII77??IIIII?II???IOOZ$7?=IIIIIIII777II++I77$777777I?II?+++I7ZZO$7??????+?+??????I?II??7I???????II$OOOO$I+IIIIII7IIIII?++II7777II?????I???+?I7$$7I+++==========++++?????++?????????IIII?+=IIIIIIIIIIII?=+II77$7?=~~=+I77II??I7777?+++==+=========++++++++++++?++???III???+IIIIIIIIIII?+=+I$Z$$7I?+++777II77+??III?++===+=========+++===++===++++++??III???IIIIIIIIIII?+++?777$7777II++??I7$7III77I+=====~===================++++++???IIIIIIIIIIIIIIII?+=+?I777777III?II777$$$$$$77+=====~~~~~================+++++????IIIIIIIIIIIIIII?+++??III7777I7$$77777$$$$$$77+==~~~~~~~~~~=============++++++???IIIIIIIIIIIIIII??I?IIIII777??7$7$$$77$$77$$$I=~~~~~~~~~~~~~~~=~==~=====++++++????II7IIIIIIIIII?II777III?II77?++?I??????IIII+~~~~~~~~~~~~~~~~~~~~~~~~===++++++???IIIIIIIIIIII????I7III??I7IIII?+???????+??+=~~~~~~~~~~~~~~~~~~~~~~~~~====++++???IIIIIIIIIII???++?II??I?II77I??I+???+??+??+===~~~~~~~~~~~~~~~~~~~~~~~~~===+++++???IIII??IIII????I??II????IIII?+?77I??I7I?+===~=~~~~~~:~::::~~~~~~~~~~~~~===+++????IIII???II??????III++???I?II77?77777II+++====++++===~~::::~~~~~~~~~~~~===+++??I77$777II?I??++????I?+?I??I+?I7$7777I????++=+I$$Z$$$$$$777I?=~~~~~~~=====+I7$ZZZOOOOOZOI?????=++???I?+?III?==+?II$III????++?7Z$I7I7$$$$$$777+=~~~~~~=====?7$$ZZZZZZ$77$??????==++?I7???II?+~~+?III7IIIII??7$$I++====+??I7777+==~~~~==+++?7$$ZZZ$I???III??????===+?II??II?+==+??I7$$77IIII$ZI+?+==++++??II???++==~~~=++?II$$$$$77IIIIII7???????+++??I??+??+I??I777$$7IIII$7I?????++==~==++++??+===~~=+?I77Z$7?=~~=++I777???????77I??7++????I?III77$7II7777I7IIII++=~~~==+====??+==~~==?I$ZI?==~~~=+?I7$$??????+I77II$++??I7I?III7$$77I777777III?++=~~=++=+=++??++==~~=?7$O+==~~+????II7$?????????I77$=+II777777$$$$77III777777II7$Z888D8O8OZ$=++++===+?7ZZIZOOODNDDDD8OZ???????II?I7$??$$$7IIII77$$$7777I7777OOODDDDD8O7III+===+++==~=?7$$II??+$Z8888DDD?????????I7$$7I$OOZZ$77II7$$7IIIII???I7ZZII+++?++=~~====+++===?I7$???+++??II777$???????????I7$7$ZZ$7?I7III7$7III?+++++=========~~~~====+++++++???III??++=====+++????????????I$$$Z$$$?+?III777II??+++====~===~~~~~~~~===+++++++????II?+++======++????????????I$$$$$ZZZ$?+?I777II??+=====~~~~~~~~~~~~~===++??+===+?I7I?++++=+=++++??????????III7$7$$$$$$$I??IIIII??+++====~~~~~~=~~=~~=++????+~~==?IIZI++++=+=++++????????II??I$$777$Z77???I77IIIII+++====~~~~~~~~~~~==+??II77I?I7$ZI7$?+++==+++++????????I???I$$7I77$7I?++?77II7II?++=====~~~~:~~~~~==???II7777$$ZOZ$Z7+++===++++???????II??I7Z77$$$7II+==+$777777???++++==~~~~~~~~===II7$8D8ZOZO8DOOOO7+=====++????????I7III777$$7?++?+++?7II7777III???++==~~~~~=====?I777?+$ZZOO8OO8O$?+====++?????????I$$$Z7777I?++++?I?+?I777$7IIII??+++=================++++?II77II??====+???????????7Z$77$777I?=++?I?~??I$$$7777III??++++=======+====++++===+???IIII??+Z$III????????7$$77$7IIII+???II~?+?7$$$777III??++++===+===+==++==+==+++IIIII77???77III??????????7$I77I?++??IIII=~+?I7$$$77III???++++++====+I77?+?ZZ$$$$ZOOZ$77I???II7?????????????7$ZO$77IIII77??+??I77$7777I????+++++?++7ZZZOZOZ$ZZ$ZOOOOOO8O7II??I7I????????????II7ZZZ$Z$$$$7II$D$7I$77777II???+++???7ZZZZ$?=~::=::==7$ZOOOO7I?III7I?????????????I7$ZZZZZZZZZ?7N8ZD$$7777II?????++???$OO888$$$III?+IZZ$OO8DO?????I7?????????????7$ZZZOZZZZZZZ$7DDNDO$$7777I????+++?++IO8DZ$III7ZZOZZOO8DD8O$????II7I????????????ZZZOZOO$ZZZZOO8DD788$77777II???++++++=?77?++++=~=~=+I$$Z$ZZ7???III7I????????????$$$77$ZZ$$$ZOD8ZDDNDOOZ$7III???++++====+$777I+=I7II7$$$$Z$7IIIIIII7II???????????ZZZ$$77ZOO88D8ODOODDDOZ$$77II????++++===+IZZZZZ777$ZZZZ$77IIIII7777II??????????IZZ$77$$7$O8888DDZD$OD88Z$$7IIII??+++++==++++?II77$$77II7IIIIII7777$I????????????ZZZ7I77??Z8888DD8DDDD88OZZ$IIII??+++======++++???II??IIIIIIIII777$$II???????????I7$ZZ$7$77I$Z88DOO8DD88Z7$Z$7III??++++==============+??????II77$$$$II???????????I7$Z$$$7$$$$$OZ$$O88888O77ZO$77II???++++====~~~~~==++??????I77$$$$$607


III??????????I$$$$$7$77$$$$I7ZOO8888O7I7OOZ$77?????++===~~~~~~===+?????II7$$$ZZZIII??????????I7$$$$77$$$$$7IZOOOO888Z7II$O8O$77II???+====~~~======+???I77$ZZ$ZZOII????????????I$Z$$$7I7$$$7ZOZ$7$OO8O$III7Z888$$77II?++=====++?+++??I7$$ZZZZOOOOIII????????????7OOOZZ$$$$7$$$II$7ZO88Z7I?II$ZOD8OZZ$$IIII???II7II7$ZZZZZZOOOOOOOIII????????????I$ZZZZZZ$$$7I??I+=?I7$Z$I???II7O88888OOOOZZZOOOOOOOOOOOOOOOO88OOOIII????????????I77$Z$$$77$7I?+~~~::::~=???????$ZOO88888888OOOOOOOOOOOOOOOO888OOOIIII???????????I77$Z77777777?=~::,,,,,~???????I7$Z8888888888OO88OOOO8OOOOO88OOOOIIIII????????????7$$$77777I~,::~:...,..~I???????II7ZZ8888888888OOOOOOOO8OO8888OOIIII???????????????IIII?II,.....,....,,,I?????++???I7ZOO8888888OOOOOOOOOOO888OOOIIIII????????????????????~............::+I??????++??I$$ZOOO88OOOOOOOOOOOOO8888OOIIIII??????????????????=,..............::I???????++??II7$ZOO8OOOOOOOOOOOOO888OOOIIIII?????????????????+:...............::II?????++????II7$ZZOOOOOOOOOOOOOOO88OOOIIII??????????????????+,................~~?I????????????II7$ZZZOOOOOOOOO8OOOOOOOIIIIII?????????????????~,.,.............::=II?????????????II7$ZZZZOOOOOOOOOO8OOOIIIIII??????????????????=,:,.............:=77I????????????III7$$$$ZZOOOOOOOO8OOO7IIIII??????????????????+:~:,......... ...~7$7???????????IIIII77$$ZZZZZOOOOOOOOOII7IIII???????????????????~=~:,............:I7III?????I???IIIIII77$$$ZZZZZZZOZZZ777IIIII??????????????????=~~~:,............,+77IIII???????IIIIII77$$$$$$$$$$$$77I7IIIII??????????????????~,:~::,............,Z77IIII????????IIIIII777777777777I777IIIIII???????????????I?:,:::,,.............IZ7IIII???????????I?IIIII777IIIIII777IIIIII??I????????????I?:,:::,,.............~77I????????????????IIIIIIIIIIII??7777IIIIIIIII?????????I???~:::,,,..............,?I+++++++++++??+????I????????+++7777IIIIIIIIIIII?IIIIIIIII~::,,,,................+?==========+++++++++++++++++++7777IIIIIIIIIIII?IIII????+::,,,,..................I?==============++++++++++++++7777IIIIIIIIIIII????++++=~,,,,,.............,,,,.,$D?~=~~~~=~~======+==++==+====7777IIIIIIIIIIII???++=+=:,,,,,...............,,..7NNO=~~~~~=~~==================77777IIIIIIIII??+++===~,,,..,.................,,?NDDD===========================777777IIIIIII+++=====:,,,......................,ZNDDD??++++=====================777777IIIIII?=======,......,... . .............:8NDDDZI??+++++===========~======777777IIIIII?===~==~........... . .............~DNDDDO7I???+++++======~~========ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎPF_keysÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎUtility <strong>functions</strong> on Programmable Function (PF) KeysÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎA number of the <strong>functions</strong> in this workspace lend themselves to being attached tofunction keys F1, F2, ··· etc.Among the candidates are:wsdiff'' © What changes have I made so far this session?attrib Œnl 3 4 © Which fns and ops have I changed recently?tree Œcs'' © What does this namespace look like?One of many ways to achieve this, is to copy and execute the function dynamicallyfrom the saved workspace into ŒSE (for example). This has the advantage that,in exchange for a small hit in execution time, which for these types of utilitiesis probably acceptable, we get the following benefits:* Less permanent space is consumed in the ŒSE namespace.* No additional copy of the utility need be maintained.Œshadow may be used to create a temporary local name to receive the copied function.However, in this case, it must be called from a traditional function asD-<strong>functions</strong> don't support it.Many utilities are "namespace sensitive". This means they must execute inside(attrib) or outside (wsdiff) the current space or take it as an argument (tree).The following (ŒSE) function uses variable: 'home' to distinguish such cases.608


’ pfkey key;cmd;home © Respond to PFKEY ¾.[1] cmd„{ © execute string to:[2] shad„'Œshadow''',¸,'''' © shadow utility name,[3] copy„'''',¸,'''Œcy''dfns''' © copy utility,[4] shad,'ª',copy,'ª',¾ © call utility.[5] } ©[6] home„œ«½ŒNSI © calling space.[7] :Select key © Key:[8] :Case 1 ª –'wsdiff'cmd'wsdiff''''' © F1: wsdiff''[9] :Case 2 ª –'tree 'cmd'tree home' © F2: treeœ«½Œnsi[10] :Case 3 ª home–'attrib'cmd'attrib Œnl 3 4' © F3: attrib Œnl 3 4[11] :EndSelect’Calling this function:Œse.pfkey 1 © executes: wsdiff'' from within ŒSE.Œse.pfkey 2 © executes: tree home from within ŒSE.Œse.pfkey 3 © executes: attrib Œnl 3 4 from within 'home'.Note that there is a little name pollution: the …attrib„ function always appearsin its own output. To avoid this, we could modify attrib to take a target spaceas an extra parameter, while it executes from within ŒSE.Next, to arrange that pressing a function key generates the required call, weattach the session 'Create' event to a callback function that loads the functionkeys:'Œse'Œws'Event' 'Create' 'Œse.pfk_init'© Attach Session Create to:’ pfk_init © Initialise PF keys.[1] {[2] ('Œse.pfkey ',(•¾),›'ER')Œpfkey ¾ © load key ¾,[3] }¨1 2 3 © for each key.’As dfns can't currently be used for callbacks, pfk_init is coded as a traditionalfunctionWarning: If you have modified <strong>APL</strong>'s command line to include a starting workspacesuch as "C:\dyalog90\dyalog.exe C:\MYWS.DWS", the Session Create event will belost during workspace load and PF keys will not be set. You can monitor thisprocess by having pfk_init output a message to the session as it runs:pfk_init[4] Œ„'PF keys loaded'After defining these <strong>functions</strong> and setting the callback, don't forget to savethe session by clicking on Session->Save in the session menu.See also: attrib.385 keyboards.451609


610


ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ P e r s o n I n d e x ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙ611


Person Index------------Abelson H.· · · · · · · lisp.236Ackermann W.· · · · · · balm.519 bfack.527 hexdump.410 mdf.501 ticks.509Adelson-Velskii G.M.· · avl.96Aquitania, Victorius of easter.359Baas M. · · · · · · · · pred.72Babbage C.· · · · · · · baby.427 bt.258 nats.290Bacon K.· · · · · · · · Graphs.137Baronet D.· · · · · · · dtb.189Beckham D.· · · · · · · mayan.465Bernecky R. · · · · · · select.81Binet J.· · · · · · · · fibonacci.279Boole G.· · · · · · · · numbers.551Bopp Y. · · · · · · · · enlist.37Bowman D. · · · · · · · display.35 fibonacci.279 von.173Brown J.A.· · · · · · · unify.249Bunda J.D.· · · · · · · parse.237Böhm C. · · · · · · · · bf.439Cannon R. · · · · · · · isdfn.395 memo.503 UndoRedo.405Chilton J.· · · · · · · xtabs.179Cholesky A-L. · · · · · Cholesky.325Clark J.R.· · · · · · · big.257 easter.359 fibonacci.279 sudoku.491Clavius C.· · · · · · · easter.359Coleridge S.T.· · · · · vtrim.186Collatz L.· · · · · · · osc.296Conway J.H. · · · · · · life.446Crossley A.D. · · · · · nc.399 quzzle.486 sudoku.491cummings e.e. · · · · · alists.8Daintree J. · · · · · · isdfn.395 wrap.185Day A.C.· · · · · · · · sbst.105Day M.· · · · · · · · · each.543 invr.214 wGraphs.163 wpath.165 xpower.350Delcros N.· · · · · · · bf.439 birthday.324 nicediv.295 scan.79 traj.220· · · · · · · · · · · · xtabs.179Diamond J.· · · · · · · mayan.465Dijkstra E.W. · · · · · bfs.531Dittmer D.· · · · · · · subvec.83Dvorak A. · · · · · · · dvorak.539Edinburgh, Duke of· · · ratsum.308Eide L.N. · · · · · · · bt.258 esh.275 JitSub.600 phinary.341 ratrep.556· · · · · · · · · · · · ratsum.308Eratosthenes· · · · · · sieve.315Erdös P.· · · · · · · · osc.296Euclid· · · · · · · · · cfract.266 gcd.284 packZ.205Euler L.· · · · · · · · cxdraw.346 esh.275 Euler.599 factors.282· · · · · · · · · · · · konigsberg.548 ratrep.556Eusebi E. · · · · · · · saw.78Fermat P. de· · · · · · factors.282Fibonacci L.· · · · · · fibonacci.279 nats.290 pow.218Flowers T.H.· · · · · · sufficient.592Foad J. · · · · · · · · adic.253 base64.174 BST.88 dist.36 fibonacci.279· · · · · · · · · · · · hexf.288 nlines.67Fowler T. · · · · · · · bt.258Gauss C.F.· · · · · · · det.326 gauss_jordan.327 limit.215Gerth J.A.· · · · · · · parse.237Geyer-Schultz A.· · · · memo.503Goldberg M. · · · · · · limit.215Gosper W. · · · · · · · cfract.266 life.446Gradney K.· · · · · · · cmat.19Graham A. · · · · · · · pow.218Graves J.T. · · · · · · numbers.551Gray T. · · · · · · · · gray.545Hager P-M.· · · · · · · date.358 days.356 fibonacci.279 keyboards.451Halleck J.B.· · · · · · JitSub.600Hamilton R. · · · · · · ksphere.337612


Hamilton W.R. · · · · · numbers.551Hansen J.N. · · · · · · cmat.19Herschel J. · · · · · · Gregorian_calendar.599Hill J.A. · · · · · · · apportion.256Hoffmann J. · · · · · · rmcm.247Hofstadter D. · · · · · osc.296Holkeri H.H.· · · · · · rmcm.247Huffman D.· · · · · · · packH.197Hui R.· · · · · · · · · birthday.324 Cholesky.325 cmat.19 det.326 key.48· · · · · · · · · · · · kt.457 le.49 mean.340 nats.290 pco.296 pmat.71· · · · · · · · · · · · xpower.350 xtimes.350Huntington E.V. · · · · apportion.256Ifra G. · · · · · · · · mayan.465Iverson K.E.· · · · · · declarative.534 pearly.553 rank.73 select.81Ivie F. · · · · · · · · merge.61Izzy· · · · · · · · · · do.211Jaeger K. · · · · · · · UndoRedo.405Jantunen V-M. · · · · · Blank_removal.187 box.14 cmat.19· · · · · · · · · · · · Data_compression.190 det.326 draw.445 efract.274· · · · · · · · · · · · enss.39 factors.282 fibonacci.279 isdfn.395· · · · · · · · · · · · just.175 keyboards.451 mmind.477 mp3.480 packB.195· · · · · · · · · · · · packD.195 packQ.202 packS.204 packT.204 packU.204· · · · · · · · · · · · packX.205 range.298 rmcm.247 sudoku.491 to.316· · · · · · · · · · · · von.173Johns M.· · · · · · · · ncpath.400Jordan M. · · · · · · · fix.393 sudoku.491Jordan W. · · · · · · · gauss_jordan.327Kaprekar.D.R· · · · · · k6174.286Kassler M.· · · · · · · subvec.83Kilburn T.· · · · · · · baby.427Knuth D.E.· · · · · · · avl.96 BST.88 bt.258 easter.359 X.160Kromberg M. · · · · · · colsum.272 sudoku.491 xtabs.179Kronecker L.· · · · · · phinary.341Kuhn H.W. · · · · · · · assign.144Landin P.J. · · · · · · declarative.534Landis E.M. · · · · · · avl.96Langlet G.· · · · · · · traj.220 xtabs.179Lanzavecchia S. · · · · file.408 memo.503 packT.204Last P. · · · · · · · · acc.10 and.233 cf.497 cond.208 derive.535 else.212· · · · · · · · · · · · foldl.45 fork.234 Function_arrays.222 isdfn.395· · · · · · · · · · · · limit.215 lof.226 logic.227 mean.340 memo.503· · · · · · · · · · · · nicediv.295 pow.218 rank.73 refs.380 saw.78· · · · · · · · · · · · scan.79 vof.229 X.160Lempel A. · · · · · · · packZ.205Levenshtein V.· · · · · dist.36Lilius A. · · · · · · · easter.359 Gregorian_calendar.599London G. · · · · · · · hampton.545Lucas F.· · · · · · · · fibonacci.279Magellan F. · · · · · · ksphere.337Mandelbrot B. · · · · · cxdraw.346Mansour P.· · · · · · · fibonacci.279 isdfn.395 mns.66 refs.380 sam.75· · · · · · · · · · · · saw.78 vwise.383Mansour S.M.· · · · · · abc.320 iotag.47 kball.336 kcell.335 squad.84Marsden J.· · · · · · · abc.320McDonnell E.E.· · · · · ksphere.337Meeus J.· · · · · · · · date.358 days.356Michie D. · · · · · · · memo.503Monroe M. · · · · · · · Data_compression.190 pack4.193Morse S.F.B.· · · · · · morse.479Munkres J.R.· · · · · · assign.144Naumanen R. · · · · · · isdfn.395 mmind.477 roman.490Nickolov N. · · · · · · fibonacci.279 lisp.236Orange, William of· · · hampton.545Pakarinen P.· · · · · · pmat.71Parks P.· · · · · · · · bags.12613


Perelman G. · · · · · · ksphere.337Poincaré H. · · · · · · ksphere.337Polivka R.· · · · · · · apportion.256Pollock J.· · · · · · · pack4.193Quario G. · · · · · · · acc.10 cxdraw.346 from.42 gcd.284 limit.215· · · · · · · · · · · · nats.290Rabenhorst D.A. · · · · display.35Rich H. · · · · · · · · xtimes.350Riediger R. · · · · · · keyboards.451Rivers J. · · · · · · · bf.439Robinson J.A. · · · · · unify.249Rothko M. · · · · · · · pack4.193Rudin W.· · · · · · · · abc.320Ryan J. · · · · · · · · isdfn.395Schickard.W.· · · · · · baby.427Segner J.A. · · · · · · BST.88Seppälä T.· · · · · · · mean.340Sierpinski W. · · · · · traj.220Smith A.· · · · · · · · xhtml.374Smith R.A.· · · · · · · bags.12 to.316 wrap.185 xtabs.179Stout Q.F.· · · · · · · sbst.105Streeter G. · · · · · · mean.340Sullivan J. · · · · · · fibonacci.279Sussman G.J.· · · · · · lisp.236Tarjan R. · · · · · · · scc.148Taylor S.J. · · · · · · pearly.553 xhtml.374Thomson N.· · · · · · · ripple.488Thwaites B. · · · · · · osc.296Tootill G.C.· · · · · · baby.427Turing A.M. · · · · · · baby.427 bf.439 Line_vectors.182Vera· · · · · · · · · · beyond.527Warndorff H.C.· · · · · kt.457Warren B.L. · · · · · · sbst.105Weigang J.· · · · · · · xtabs.179Welch T.· · · · · · · · packZ.205Wells M.· · · · · · · · big.257 dtb.189 fnarray.232Whitney A.· · · · · · · kt.457 sudoku.491Wiedmann C. · · · · · · xtabs.179Williams F.C. · · · · · baby.427Wise H. · · · · · · · · hampton.545York, Grand old Duke of nats.290Ziv J.· · · · · · · · · packZ.205614


ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ F u n c t i o n / O p e r a t o r I n d e x ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙ615


Function/Operator Index-----------------------A acc.10 adic.253 alext.8 alrem.8alrems.8 alval.8 alvals.8 ambiv.385and.233 apportion.256 ary.317 ascan.79ascana.79 assign.144 attrib.385 avl.96B baby.427 bags.12 base64.174 bf.439big.257 birthday.324 box.14 bsearch.258bt.258C cache.503 cal.354 case.224 cf.497cfract.266 chksum.18 cmat.19 cmpx.500cols.26 colsum.272 compidn.356 cond.208cxdraw.346 Cholesky.325D dab.190 date.358 days.356 deb.189dec.286 det.326 dfnscode.361 dfnsnotes.362dfspan.156 dft.125 dice.445 din.388disp.31 display.35 displayr.35 displays.35dist.36 dlb.189 dmb.190 do.211dots.389 draw.445 dscan.79 dtb.189dxb.189E each.543 easter.359 efract.274 else.212enlist.37 enss.39 esh.275 exit.363F factorial.279 factors.282 fibonacci.279 file.408filefind.426 find.40 fix.393 fk.234fk_ fnarray.232 fndiff.363 fnrefs.394fnrepl.394 foldl.45 for.214 from.42G gauss_jordan.327 gcd.284getfile.409H hex.286 hexdump.410 hexf.288 htx.180I index.364 inslink.151 insnode.150 int.289invr.214 iotag.47 isdfn.395J just.175justify.185K kball.336 kcell.335 key.48 ksphere.337kt.457 k6174.286L lcase.176 le.49 lex.53 life.446limit.215 lisp.236 list.54 lof.226logic.227 loop.550 ltov.184 ltrav.54M mac.464 match.58 mayan.465 maze.474mdf.501 mean.340 memo.503 merge.61merge2.61 mmind.477 mns.66 morse.479mp3.480 mscan.79 mtrim.177N nats.290 nc.399 ncpath.400 nicediv.295nlines.67 nspack.378 NormRand.341O of.225 or.233 osc.296P pack.69 pack4.193 packB.195 packD.195packH.197 packN.202 packQ.202 packR.203packS.204 packT.204 packU.204 packX.205packZ.205 parse.237 path.153 pco.296perv.70 phinary.341 pmat.71 polar.348popnode.152 pow.218 pred.72 putfile.425616


Q queens.481quzzle.486R range.298 rank.73 rational.298 rats.302ratsum.308 ravt.130 redblack.110 refmatch.382refmt.401 refpath.582 refs.380 refws.365remlink.152 remnode.150 rep.402 ripple.488rmcm.247 roman.490 root.345 roots.346rows.74rr.489S sam.75 saw.78 sbst.105 scc.148search.153 segs.582 select.81 sieve.315span.155 splay.120 squad.84 squeeze.178ss.177 ssmat.178 ssword.169 stamps.314stdists.158 stpath.159 stpaths.160 subs.85subvec.83sudoku.491T test.367 tfmt.130 ticks.509 time.515timestamp.178 tnest.130 to.316 tokens.170trace.403 traj.220 trav.130 tree.135tview.137type.86U ucase.176 unify.249 uns.289 until.222unwrap.185 up.383 utf8.370 utf8get.426utf8put.426 UndoRedo.405V vof.229 von.173 vtol.184 vtrim.186vwise.383W wcost.165 while.221 wmst.167 words.169wpath.165 wrap.185 wrapnote.186 wsdiff.371wsmerge.373 wspan.167 wsreq.515X xhtml.374 xpower.350 xrefs.384 xtabs.179xtimes.350 xws.376 X.160_ _fk.234617


618


ÚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÌÛ T o p i c I n d e x ÛÀÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÙ619


Topic Index-----------¸th root· · · · · · · · · · · root.345abacus· · · · · · · · · · · · mayan.465ABC · · · · · · · · · · · · · baby.427accumulator · · · · · · · · · factorial.279 fibonacci.279 list.54ACE · · · · · · · · · · · · · baby.427Ackermann's function· · · · · balm.519 bfack.527 hexdump.410 mdf.501· · · · · · · · · · · · · · · ticks.509addition· · · · · · · · · · · colsum.272adjacency matrix· · · · · · · Graphs.137adjacent 1s · · · · · · · · · xtabs.179AGM · · · · · · · · · · · · · see arithmetic-geometric meanaide-mémoire· · · · · · · · · refcard.581Algorithm X · · · · · · · · · X.160align text· · · · · · · · · · just.175 justify.185ambivalent· · · · · · · · · · ambiv.385ancestor space· · · · · · · · refpath.582 up.383<strong>APL</strong>'88· · · · · · · · · · · · mean.340<strong>APL</strong>385 Unicode· · · · · · · · xhtml.374apportionment · · · · · · · · apportion.256Arithmetic Boundary Checking· abc.320arithmetic-geometric mean · · limit.215assembler · · · · · · · · · · baby.427assignment· · · · · · · · · · apportion.256 assign.144 X.160assignment, destructive · · · alists.8 hexdump.410 merge.61 sam.75· · · · · · · · · · · · · · · select.81 wpath.165assignment, indexed · · · · · maze.474 merge.61 select.81 wpath.165assignment, selective · · · · merge.61association list· · · · · · · alists.8 mns.66AST · · · · · · · · · · · · · see abstract syntax treeAsteroids · · · · · · · · · · life.446astronomy · · · · · · · · · · mayan.465attributes· · · · · · · · · · attrib.385autoformat· · · · · · · · · · test.367Baby· · · · · · · · · · · · · baby.427bags· · · · · · · · · · · · · bags.12balanced ternary· · · · · · · bt.258 esh.275 JitSub.600 ratrep.556· · · · · · · · · · · · · · · ratsum.308 stamps.314balanced tree · · · · · · · · see binary search treeBase64 encoding · · · · · · · base64.174Beano · · · · · · · · · · · · pigeons.554Beast, number of the· · · · · rational.298BFS · · · · · · · · · · · · · see breadth-first searchBIDMAS· · · · · · · · · · · · parse.237bijective numeration· · · · · adic.253binary· · · · · · · · · · · · ary.317binary search · · · · · · · · bsearch.258binary search tree· · · · · · avl.96 BST.88 redblack.110 sbst.105 splay.120binding strength· · · · · · · parse.237 rank.73binomial· · · · · · · · · · · nats.290birthday· · · · · · · · · · · birthday.324biscuit, ginger · · · · · · · beyond.527blanks· · · · · · · · · · · · Blank_removal.187 dab.190 deb.189 dlb.189· · · · · · · · · · · · · · · dmb.190 dtb.189 dxb.189 mtrim.177 vtrim.186boolean <strong>functions</strong> · · · · · · logic.227 truth_tables.593border· · · · · · · · · · · · box.14bottom ƒ· · · · · · · · · · · baby.427 declarative.534boundary· · · · · · · · · · · abc.320 kcell.335 ksphere.337box · · · · · · · · · · · · · box.14 disp.31 display.35 draw.445box-drawing characters· · · · box.14 dft.125 disp.31 display.35 draw.445· · · · · · · · · · · · · · · keyboards.451 maze.474 select.81 wrapnote.186Brainfuck · · · · · · · · · · bf.439 bfack.527 mac.464breadth-first search· · · · · bfs.531 path.153 search.153 span.155 trav.130BST · · · · · · · · · · · · · see binary search tree620


Bunda-Gerth parser· · · · · · parse.237cache · · · · · · · · · · · · memo.503calendar· · · · · · · · · · · British_Calendar_Act_1751.598 cal.354 date.358· · · · · · · · · · · · · · · Dates.353 Gregorian_calendar.599 mayan.465calibration · · · · · · · · · wsreq.515canon paschalis · · · · · · · easter.359cans· · · · · · · · · · · · · decay.533capitalisation· · · · · · · · von.173card deck · · · · · · · · · · ripple.488cartesian coordinates · · · · polar.348case, lower · · · · · · · · · lcase.176case, upper · · · · · · · · · lcase.176cash prize· · · · · · · · · · osc.296cast· · · · · · · · · · · · · int.289Catalan number· · · · · · · · BST.88cellular automaton· · · · · · life.446checksum· · · · · · · · · · · chksum.18chess puzzle· · · · · · · · · kt.457 queens.481 queensX.554Cholesky decomposition· · · · Cholesky.325classification, name· · · · · nc.399 ncpath.400closure · · · · · · · · · · · cf.497 cfract.266 memo.503 ratsum.308closures· · · · · · · · · · · lisp.236coding, fibonacci · · · · · · fibonacci.279coins · · · · · · · · · · · · decay.533Colemak · · · · · · · · · · · dvorak.539Colossus· · · · · · · · · · · baby.427colour, changing· · · · · · · colour_change.533column sum· · · · · · · · · · colsum.272combination · · · · · · · · · cmat.19 rr.489combinator· · · · · · · · · · dft.125comment removal · · · · · · · rmcm.247compare arrays· · · · · · · · le.49compare <strong>functions</strong> · · · · · · fndiff.363compare namespaces· · · · · · refmatch.382compare workspaces· · · · · · wsdiff.371complex numbers · · · · · · · cxdraw.346 polar.348 roots.346component file· · · · · · · · filefind.426compression · · · · · · · · · dab.190 Data_compression.190 deb.189 dlb.189· · · · · · · · · · · · · · · dmb.190 dtb.189 dxb.189 nspack.378 pack.69· · · · · · · · · · · · · · · packB.195 packD.195 packH.197 packN.202· · · · · · · · · · · · · · · packQ.202 packR.203 packS.204 packT.204· · · · · · · · · · · · · · · packU.204 packX.205 packZ.205 pack4.193· · · · · · · · · · · · · · · squeeze.178 vtrim.186computer programmers· · · · · nats.290 staples.583computer, first · · · · · · · baby.427conditional operator· · · · · case.224 cond.208 else.212 for.214 lof.226· · · · · · · · · · · · · · · logic.227 of.225 until.222 while.221cons· · · · · · · · · · · · · list.54consciousness · · · · · · · · muson.551continuation-passing style· · mac.464continued fraction· · · · · · cfract.266 fibonacci.279convolution · · · · · · · · · xtimes.350coordinates · · · · · · · · · polar.348cost vector · · · · · · · · · wcost.165cover, exact· · · · · · · · · X.160cows and bulls, game of · · · mmind.477co-operator · · · · · · · · · case.224 co_ops.532 cond.208 for.214 fork.234· · · · · · · · · · · · · · · lof.226 of.225 vof.229CPS · · · · · · · · · · · · · see continuation-passing stylecross-reference · · · · · · · fnrefs.394currying· · · · · · · · · · · parse.237 trav.130cylinder· · · · · · · · · · · life.446data compression· · · · · · · see compressiondata conversion · · · · · · · type.86date· · · · · · · · · · · · · Dates.353 days.356 easter.359621


· · · · · · · · · · · · · · · Gregorian_calendar.599 mayan.465 timestamp.178debugging · · · · · · · · · · trace.403 traj.220decay · · · · · · · · · · · · decay.533Decimal Floating Point· · · · hexf.288decimal normalisation · · · · JitSub.600decimal (from hex)· · · · · · hex.286declarative programming · · · bfack.527 bt.258 declarative.534 merge.61· · · · · · · · · · · · · · · pearly.553default display · · · · · · · nlines.67default left argument · · · · root.345define function · · · · · · · din.388denotative· · · · · · · · · · declarative.534depth-first search· · · · · · dfspan.156 scc.148 trav.130derived function· · · · · · · derive.535 dft.125determinant · · · · · · · · · det.326DFS · · · · · · · · · · · · · see depth-first searchdictionary· · · · · · · · · · alists.8difference, <strong>functions</strong> · · · · fndiff.363disassembler· · · · · · · · · baby.427display (of arrays) · · · · · disp.31 display.35diversions· · · · · · · · · · baby.427 dice.445 draw.445 kt.457 life.446· · · · · · · · · · · · · · · mayan.465 maze.474 mmind.477 mp3.480· · · · · · · · · · · · · · · queens.481 quzzle.486 ripple.488 roman.490· · · · · · · · · · · · · · · sudoku.491 sudokuX.587 von.173division by ¯1 1+base*¾ · · · JitSub.600division, fast· · · · · · · · JitSub.600division, long· · · · · · · · bt.258 nats.290do-y function · · · · · · · · do.211drawing · · · · · · · · · · · cxdraw.346dual· · · · · · · · · · · · · cxdraw.346Dvorak· · · · · · · · · · · · dvorak.539D-function, test for· · · · · isdfn.395each· · · · · · · · · · · · · each.543Easter· · · · · · · · · · · · easter.359EDSAC · · · · · · · · · · · · baby.427EDVAC · · · · · · · · · · · · baby.427Egyptian fraction · · · · · · efract.274Eide numbers· · · · · · · · · esh.275 ratrep.556 ratsum.308encapsulate function· · · · · rep.402encoding· · · · · · · · · · · utf8.370 utf8get.426 utf8put.426encryption· · · · · · · · · · packD.195endian· · · · · · · · · · · · hexdump.410 hexf.288engineers · · · · · · · · · · osc.296ENIAC · · · · · · · · · · · · baby.427enlist· · · · · · · · · · · · avl.96 BST.88 enlist.37 enss.39 enss.39· · · · · · · · · · · · · · · Graphs.137 limit.215 nspack.378 redblack.110· · · · · · · · · · · · · · · sbst.105 splay.120Erasomatic (tm) · · · · · · · beyond.527error-guard, dynamic· · · · · loop.550evaluator · · · · · · · · · · lisp.236exact cover · · · · · · · · · X.160exa-· · · · · · · · · · · · · nats.290experience, near-death· · · · beyond.527expression· · · · · · · · · · parse.237expression comparison · · · · cf.497 cmpx.500expression transformation · · avl.96 cmat.19 derive.535 nats.290external workspace· · · · · · refws.365factorial · · · · · · · · · · big.257 factorial.279 lisp.236 nats.290Fast Fourier Transform· · · · xpower.350 xtimes.350FFT · · · · · · · · · · · · · see Fast Fourier Transformfibonacci coding· · · · · · · fibonacci.279fibonacci number· · · · · · · avl.96 cfract.266 cmat.19 dft.125· · · · · · · · · · · · · · · fibonacci.279 lisp.236 memo.503 nats.290· · · · · · · · · · · · · · · pow.218 trav.130find· · · · · · · · · · · · · filefind.426622


Finn<strong>APL</strong> Idiom List· · · · · · bags.12fixpoint· · · · · · · · · · · cxdraw.346 derive.535 JitSub.600 limit.215flip flop (RS)· · · · · · · · xtabs.179fold· · · · · · · · · · · · · foldl.45font· · · · · · · · · · · · · xhtml.374fork· · · · · · · · · · · · · derive.535 dft.125 fork.234 vof.229formatting, <strong>functions</strong> · · · · dots.389 refmt.401 rmcm.247formatting, trees · · · · · · tfmt.130 tnest.130FRE · · · · · · · · · · · · · see Function Results Editionfudge factor· · · · · · · · · wsreq.515function array· · · · · · · · fnarray.232 fnarray.232 for.214· · · · · · · · · · · · · · · Function_arrays.222 of.225 rep.402 vof.229function inverse· · · · · · · invr.214function power· · · · · · · · limit.215 pow.218Function Results Edition· · · cf.497 cfract.266 memo.503 ratsum.308function selection· · · · · · for.214function trains · · · · · · · dft.125<strong>functions</strong>, list of· · · · · · lof.226function, fix · · · · · · · · fix.393fuzzy · · · · · · · · · · · · dist.36Gates, Pearly · · · · · · · · pearly.553Gaussian method · · · · · · · det.326Gauss-Jordan· · · · · · · · · gauss_jordan.327GCD · · · · · · · · · · · · · see greatest common divisorgiga- · · · · · · · · · · · · nats.290glider· · · · · · · · · · · · life.446golden mean · · · · · · · · · cfract.266 fibonacci.279 limit.215 phinary.341grade · · · · · · · · · · · · le.49 ripple.488graph · · · · · · · · · · · · alists.8 assign.144 bfs.531 dfspan.156· · · · · · · · · · · · · · · Graphs.137 inslink.151 insnode.150 kt.457· · · · · · · · · · · · · · · scc.148 stamps.314 stdists.158 stpath.159· · · · · · · · · · · · · · · stpaths.160graph, planar · · · · · · · · konigsberg.548graph, unweighted · · · · · · Graphs.137 path.153 popnode.152 remlink.152· · · · · · · · · · · · · · · remnode.150 search.153 span.155graph, weighted · · · · · · · Graphs.137 wcost.165 wGraphs.163 wmst.167· · · · · · · · · · · · · · · wpath.165 wspan.167greatest common divisor · · · cfract.266 gcd.284 nats.290 rats.302Gregorian calendar· · · · · · date.358 gcr.544 Gregorian_calendar.599guard · · · · · · · · · · · · dice.445Gödel, Escher, Bach · · · · · osc.296Haiku · · · · · · · · · · · · staples.583Hailstone sequence· · · · · · osc.296Happy Hacking Keyboard· · · · dvorak.539Harvard Mk1 · · · · · · · · · baby.427hashing · · · · · · · · · · · chksum.18HCF · · · · · · · · · · · · · see greatest common divisorHeaven· · · · · · · · · · · · beyond.527 pearly.553Helsingør · · · · · · · · · · cond.208hexadecimal · · · · · · · · · esh.275 hex.286 hexdump.410 hexf.288HHKB· · · · · · · · · · · · · see Happy Hacking KeyboardHilbert matrix· · · · · · · · det.326 gauss_jordan.327histogram · · · · · · · · · · cmpx.500 easter.359 nicediv.295hook· · · · · · · · · · · · · derive.535 dft.125 fork.234horizontal tabs · · · · · · · xtabs.179humour· · · · · · · · · · · · humour.546Hungarian method· · · · · · · assign.144hyperator · · · · · · · · · · bf.439 cf.497 cond.208 hyperators.546hypercube · · · · · · · · · · Graphs.137 kcell.335hypersphere · · · · · · · · · kball.336 ksphere.337IDN · · · · · · · · · · · · · see International Day NumberIEEE FP precision · · · · · · ary.317 gauss_jordan.327 nats.290IEEE 754· · · · · · · · · · · hexf.288IEEE 854· · · · · · · · · · · hexf.288imaginary numbers · · · · · · see complex numbers623


independent zeros · · · · · · assign.144indexing, array · · · · · · · from.42infinite precision· · · · · · big.257 colsum.272 nats.290insensitive, case · · · · · · lcase.176integer · · · · · · · · · · · int.289intellect, human· · · · · · · staples.583International Day Number· · · days.356interval· · · · · · · · · · · abc.320inverse · · · · · · · · · · · invr.214iota, generialised· · · · · · iotag.47is-y function · · · · · · · · do.211J · · · · · · · · · · · · · · key.48 pco.296JFK Airport · · · · · · · · · pearly.553JITS· · · · · · · · · · · · · see Just-In-Time-SubtractionJulian calendar · · · · · · · Gregorian_calendar.599justify text· · · · · · · · · just.175 justify.185 Line_vectors.182Just-In-Time-Subtraction· · · JitSub.600 ratrep.556K · · · · · · · · · · · · · · sudoku.491Kaliningrad · · · · · · · · · konigsberg.548key adverb· · · · · · · · · · key.48keyboard layout · · · · · · · dvorak.539 kbmac.546 kbolay.547 keyboards.451kilo- · · · · · · · · · · · · nats.290klein bottle· · · · · · · · · life.446knight's tour · · · · · · · · Graphs.137 kt.457Kumquat · · · · · · · · · · · disp.31 htx.180k-adic numbers· · · · · · · · adic.253K-ball· · · · · · · · · · · · kball.336K-cell· · · · · · · · · · · · kcell.335K-sphere· · · · · · · · · · · ksphere.337Königsberg· · · · · · · · · · konigsberg.548lambda· · · · · · · · · · · · lisp.236lambda expression · · · · · · list.54lazy evaluation · · · · · · · and.233LCM · · · · · · · · · · · · · see least common multipleleast common multiple · · · · gcd.284 nats.290 rats.302Lempel-Ziv-Welch· · · · · · · packZ.205lexical scan· · · · · · · · · tokens.170lexicographical comparison· · lex.53life, game of · · · · · · · · life.446line list · · · · · · · · · · see line vectorline vector · · · · · · · · · justify.185 Line_vectors.182 ltov.184· · · · · · · · · · · · · · · squeeze.178 unwrap.185 wrap.185 wrapnote.186lines of output · · · · · · · nlines.67line-drawing characters · · · see box-drawing charactersLisp· · · · · · · · · · · · · lisp.236lists · · · · · · · · · · · · alists.8 bf.439 list.54local names · · · · · · · · · mean.340look-up table · · · · · · · · alists.8loop· · · · · · · · · · · · · loop.550lower case· · · · · · · · · · lcase.176Lucas numbers · · · · · · · · fibonacci.279LZW · · · · · · · · · · · · · see Lempel-Ziv-WelchMac · · · · · · · · · · · · · kbmac.546macro · · · · · · · · · · · · balm.519 hexdump.410 mac.464magic function· · · · · · · · declarative.534Manchester computer · · · · · baby.427Mandelbrot set· · · · · · · · cxdraw.346manifolds · · · · · · · · · · ksphere.337 life.446Mastermind· · · · · · · · · · mmind.477mathematicians· · · · · · · · nats.290 packZ.205 staples.583maximise· · · · · · · · · · · assign.144maximum, local· · · · · · · · ksphere.337maze· · · · · · · · · · · · · hampton.545 maze.474media player (MP3)· · · · · · mp3.480mega- · · · · · · · · · · · · nats.290624


memoization · · · · · · · · · memo.503merge · · · · · · · · · · · · baby.427 merge.61 scc.148 select.81 sudoku.491merge, workspace· · · · · · · wsmerge.373MESM· · · · · · · · · · · · · baby.427Metacircular· · · · · · · · · lisp.236MIME· · · · · · · · · · · · · base64.174min (workspace) · · · · · · · list.54mininum spanning tree · · · · wmst.167monitor · · · · · · · · · · · mdf.501 ticks.509 time.515 trace.403 wsreq.515Morse code· · · · · · · · · · morse.479MP3 (media player)· · · · · · mp3.480MST · · · · · · · · · · · · · see minimum spanning treemultiset· · · · · · · · · · · bags.12multi-graph · · · · · · · · · konigsberg.548muscle memory · · · · · · · · dvorak.539muse· · · · · · · · · · · · · muson.551music · · · · · · · · · · · · mp3.480möbius strip· · · · · · · · · life.446name classification · · · · · nc.399 ncpath.400namespace · · · · · · · · · · mns.66 Namespaces.377namespace comparison· · · · · refmatch.382namespace references· · · · · refpath.582 refs.380 up.383 xrefs.384name-clash problem· · · · · · attrib.385 dots.389 find.40 isdfn.395 mdf.501· · · · · · · · · · · · · · · ticks.509 tree.135 wsdiff.371native file · · · · · · · · · file.408 getfile.409 hexdump.410 int.289· · · · · · · · · · · · · · · putfile.425natural number· · · · · · · · nats.290network · · · · · · · · · · · see graphNewton-Raphson· · · · · · · · invr.214 ksphere.337 limit.215 traj.220Nicaea, Council of· · · · · · easter.359non-termination · · · · · · · baby.427 declarative.534no-result · · · · · · · · · · do.211number system · · · · · · · · mayan.465 roman.490N-Queens· · · · · · · · · · · queens.481 queensX.554 trav.130 X.160offside rule· · · · · · · · · hexdump.410one-liner · · · · · · · · · · rmcm.247optimise· · · · · · · · · · · assign.144order (of arrays) · · · · · · le.49orphans · · · · · · · · · · · dfnscode.361OS X· · · · · · · · · · · · · kbmac.546Oscillate · · · · · · · · · · osc.296oyster· · · · · · · · · · · · muson.551packing · · · · · · · · · · · nspack.378 packB.195 packD.195 packH.197· · · · · · · · · · · · · · · packN.202 packQ.202 packR.203 packS.204· · · · · · · · · · · · · · · packT.204 packU.204 packX.205 packZ.205· · · · · · · · · · · · · · · pack4.193palindrome· · · · · · · · · · limit.215parent space· · · · · · · · · refpath.582 up.383parsing · · · · · · · · · · · list.54 parse.237 tokens.170 unify.249partioned reduction · · · · · pred.72Pascal's triangle · · · · · · cmat.19passant, en · · · · · · · · · do.211path· · · · · · · · · · · · · stdists.158 stpath.159 stpaths.160 wpath.165pattern-matching· · · · · · · bfack.527 bt.258pencils · · · · · · · · · · · beyond.527 decay.533pentomino · · · · · · · · · · life.446 X.160performance · · · · · · · · · cf.497 cmpx.500 mdf.501 ticks.509 time.515· · · · · · · · · · · · · · · wsreq.515permutation matrix· · · · · · pmat.71persistent local variable · · memo.503pervasive function· · · · · · easter.359 int.289 perv.70 truth_tables.593peta- · · · · · · · · · · · · nats.290Phi · · · · · · · · · · · · · see golden meanphinary number· · · · · · · · phinary.341Pi· · · · · · · · · · · · · · cfract.266 rational.298625


pigeons · · · · · · · · · · · pigeons.554playlist· · · · · · · · · · · mp3.480Poincaré Conjecture · · · · · ksphere.337polar coordinates · · · · · · polar.348polynomial· · · · · · · · · · ratrep.556 xtimes.350posh· · · · · · · · · · · · · ratsum.308postage stamps· · · · · · · · stamps.314power operator· · · · · · · · pow.218prime number· · · · · · · · · factors.282 hexdump.410 pco.296 rats.302· · · · · · · · · · · · · · · sieve.315printing· · · · · · · · · · · dfnscode.361 dfnsnotes.362probability · · · · · · · · · birthday.324programmable function keys· · PF_keys.606proof, engineer's · · · · · · osc.296pseudo-graph· · · · · · · · · konigsberg.548pure function · · · · · · · · baby.427 each.543 gauss_jordan.327 queens.481· · · · · · · · · · · · · · · sam.75 select.81puzzle· · · · · · · · · · · · quzzle.486quadratic, real roots of· · · roots.346quad-tree · · · · · · · · · · pack4.193quality assurance · · · · · · test.367queue · · · · · · · · · · · · bfs.531quicksort · · · · · · · · · · le.49quickstep · · · · · · · · · · dvorak.539QWERTY· · · · · · · · · · · · dvorak.539 keyboards.451railway diagram · · · · · · · file.408rank operator · · · · · · · · rank.73rational number · · · · · · · ary.317 cfract.266 esh.275 rational.298· · · · · · · · · · · · · · · ratrep.556 rats.302 ratsum.308read-eval-print loop· · · · · see REPLrectangle, golden · · · · · · phinary.341recursion · · · · · · · · · · see recursionredo· · · · · · · · · · · · · UndoRedo.405reduction · · · · · · · · · · acc.10 foldl.45red-black trees · · · · · · · redblack.110reference card· · · · · · · · refcard.581references, function· · · · · fnrefs.394references, workspace · · · · refws.365refs· · · · · · · · · · · · · refs.380remote execution· · · · · · · refws.365 xws.376REPL· · · · · · · · · · · · · din.388 esh.275 hexdump.410 loop.550 mmind.477Representatives, House of, US apportion.256RLE · · · · · · · · · · · · · see run-length encodingroman numerals· · · · · · · · roman.490Round-robin tournament· · · · rr.489run-length encoding · · · · · packR.203r-pentomino · · · · · · · · · life.446scalar-wise · · · · · · · · · perv.70scan operators· · · · · · · · scan.79Scheme· · · · · · · · · · · · lisp.236sea monster, scary· · · · · · dft.125seawater· · · · · · · · · · · ksphere.337 muson.551select and modify · · · · · · sam.75select operator · · · · · · · case.224selective specification · · · enss.39sequence· · · · · · · · · · · cfract.266 k6174.286 osc.296 to.316 traj.220sequential test · · · · · · · and.233session input · · · · · · · · din.388Setun computer· · · · · · · · bt.258Shannon-Fano· · · · · · · · · packS.204sharing, array· · · · · · · · pack.69shell · · · · · · · · · · · · esh.275 loop.550shipping regions, UK· · · · · uksfr.595shortlex· · · · · · · · · · · adic.253shuffle · · · · · · · · · · · ripple.488626


SICP· · · · · · · · · · · · · lisp.236Signum difference · · · · · · abc.320simple-array-wise · · · · · · saw.78skewed four · · · · · · · · · ratrep.556 ratsum.308sort· · · · · · · · · · · · · le.49sound bite· · · · · · · · · · declarative.534 humour.546 merge.61soup· · · · · · · · · · · · · decay.533 soup.583source code · · · · · · · · · dfnscode.361spaces· · · · · · · · · · · · see blanksspanning tree · · · · · · · · dfspan.156 span.155 stdists.158 stpath.159· · · · · · · · · · · · · · · stpaths.160 wmst.167 wspan.167sphere· · · · · · · · · · · · kball.336 ksphere.337split · · · · · · · · · · · · segs.582squab · · · · · · · · · · · · pigeons.554squad indexing· · · · · · · · squad.84SSEM· · · · · · · · · · · · · baby.427standard deviation· · · · · · mean.340staples · · · · · · · · · · · staples.583stela · · · · · · · · · · · · mayan.465stepping· · · · · · · · · · · to.316string comparison · · · · · · dist.36string replacement· · · · · · fnrepl.394 ss.177 ssmat.178 ssword.169 subs.85string search · · · · · · · · find.40Strongly connected components scc.148stuff · · · · · · · · · · · · alists.8 Data_compression.190 dots.389 le.49· · · · · · · · · · · · · · · packN.202 staples.583stupid questions· · · · · · · declarative.534subset· · · · · · · · · · · · subvec.83substitution· · · · · · · · · ss.177 ssmat.178 ssword.169 subs.85subtraction, just-in-time · · JitSub.600 ratrep.556subvector · · · · · · · · · · subvec.83sudoku, game of · · · · · · · sudoku.491 sudoku_bfs.584 sudokuX.587 X.160suffix trie · · · · · · · · · packZ.205sum · · · · · · · · · · · · · colsum.272symbol table· · · · · · · · · alists.8syntax· · · · · · · · · · · · attrib.385tab expansion · · · · · · · · xtabs.179tag, XML· · · · · · · · · · · htx.180tail recursion· · · · · · · · bfack.527 factorial.279 fibonacci.279 gcd.284TAO · · · · · · · · · · · · · see Total array orderingtera- · · · · · · · · · · · · nats.290ternary · · · · · · · · · · · ary.317 bt.258text· · · · · · · · · · · · · Blank_removal.187 Data_compression.190· · · · · · · · · · · · · · · Line_vectors.182 segs.582 unwrap.185 words.169· · · · · · · · · · · · · · · wrap.185 wrapnote.186text file · · · · · · · · · · getfile.409 putfile.425time· · · · · · · · · · · · · timestamp.178timing· · · · · · · · · · · · cf.497 cmpx.500 mdf.501 ticks.509 time.515topology· · · · · · · · · · · abc.320 ksphere.337torus · · · · · · · · · · · · ksphere.337 life.446Total array ordering· · · · · le.49tradfn· · · · · · · · · · · · ambiv.385trailing blanks · · · · · · · mtrim.177trains· · · · · · · · · · · · dft.125trajectory· · · · · · · · · · traj.220transformation, expression· · derive.535transitive closure· · · · · · Graphs.137translation · · · · · · · · · unicode.596tree· · · · · · · · · · · · · avl.96 dft.125 redblack.110 sbst.105· · · · · · · · · · · · · · · splay.120 tfmt.130 tnest.130 trav.130· · · · · · · · · · · · · · · Trees.87 tview.137tree searching· · · · · · · · kt.457 queens.481truth tables· · · · · · · · · logic.227 truth_tables.593turing complete · · · · · · · baby.427 bf.439Turing tape · · · · · · · · · balm.519 bf.439 parse.237627


type· · · · · · · · · · · · · type.86type conversion · · · · · · · int.289type notation · · · · · · · · avl.96 BST.88 foldl.45 sbst.105 trav.130unary · · · · · · · · · · · · adic.253 trav.130under · · · · · · · · · · · · cxdraw.346undo· · · · · · · · · · · · · UndoRedo.405Unicode · · · · · · · · · · · getfile.409 iotag.47 putfile.425 unicode.596· · · · · · · · · · · · · · · utf8.370 utf8get.426 utf8put.426 xhtml.374unification · · · · · · · · · unify.249unit circle · · · · · · · · · cxdraw.346unit sphere · · · · · · · · · ksphere.337unit testing· · · · · · · · · test.367Univac· · · · · · · · · · · · baby.427 limit.215UNIVAC· · · · · · · · · · · · baby.427unsigned· · · · · · · · · · · int.289upper case· · · · · · · · · · lcase.176UTF-8 · · · · · · · · · · · · utf8.370 utf8get.426 utf8put.426 xhtml.374variable-wise · · · · · · · · vwise.383vector of <strong>functions</strong> · · · · · vof.229vector-wise · · · · · · · · · rows.74vegan · · · · · · · · · · · · soup.583vigesimal number system · · · mayan.465Warndorff's rule· · · · · · · kt.457 sudoku_bfs.584white dots· · · · · · · · · · dots.389 hexdump.410widows· · · · · · · · · · · · dfnscode.361wondrous number · · · · · · · osc.296word ladder · · · · · · · · · Graphs.137words · · · · · · · · · · · · segs.582 wrap.185 wrapnote.186workspace · · · · · · · · · · refws.365 tree.135 Workspaces.361 wsdiff.371· · · · · · · · · · · · · · · wsmerge.373 xws.376wrapping, words · · · · · · · Line_vectors.182 unwrap.185www.dyalog.com· · · · · · · · xhtml.374XML · · · · · · · · · · · · · htx.180xutils, ss· · · · · · · · · · ss.177 ssmat.178 ssword.169Y combinator· · · · · · · · · lisp.236yotta-· · · · · · · · · · · · nats.290YouTube · · · · · · · · · · · dvorak.539 life.446 limit.215 sudoku.491· · · · · · · · · · · · · · · sudoku_bfs.584 trav.130zetta-· · · · · · · · · · · · nats.290Zuse Z3 · · · · · · · · · · · baby.427128-bit Floating Point· · · · hexf.2881752· · · · · · · · · · · · · British_Calendar_Act_1751.598 date.358 days.356· · · · · · · · · · · · · · · gcr.5442-adic numbers· · · · · · · · bf.4393N+1 sequence · · · · · · · · osc.296¼, generalised· · · · · · · · iotag.47Ø · · · · · · · · · · · · · · see golden meanŒAT · · · · · · · · · · · · · attrib.385ŒDR · · · · · · · · · · · · · type.86ŒML · · · · · · · · · · · · · cmat.19 cmpx.500 enss.39 limit.215 logic.227· · · · · · · · · · · · · · · mns.66ŒNC, extended · · · · · · · · nc.399 ncpath.400ŒSE · · · · · · · · · · · · · din.388ŒSIZE · · · · · · · · · · · · attrib.385ŒWX · · · · · · · · · · · · · refs.380628

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!