NB. aatrace

cocurrent 'jtrace'

Notes=: 0 : 0

Developmental version as of: 3 November 2010

Invitation for:

Study:

Intended work:

Hopes:

)

help=: Note 0 Programmers new to J soon find that liberal use of parentheses is good insurance against misunderstandings of the order of execution, but then find that managing large numbers of parentheses is also challenging. Programmers exploring advanced features of J can also experience unexpected results or error messages from symbol sequences which seem plausibly appropriate.

The trace workspace offers tools to assist with understanding, at three different levels of complexity, the behavior of a puzzling expression in J:

-> pyr y elevates parenthesized sub-expressions in a pyramidal format,

Examples:

fn _

(3 4$i.12)

(a+b)

*Unbalanced

-> paren y fully parenthesizes an expression to show clearly which

Examples:

((+/)(i.4))

((3 4$(i.12))((+/) .*)(*:(i.4)))

-> parenpyr y fully parenthesizes an expression and elevates inner

Examples:

1 (+ /) (i. 4) 0 ( _ )

2 (i. 12) (+ /) (i. 4) 1 (3 4 $ _ ) ( _ . *) (*: ) 0 ( _ _ )

-> flowtree y produces a diagram showing the relationships among each

Example:

│ │ └──┬F─┬─F─┬─F─┬─F──┬─F─┬─F─┬F─┬┘

-> x trace y lists the arguments and result of each operation as it is

Example:


1 Monad


  1. 4 0 1 2 3

2 Dyad


3 4 5 6

Remember to double any apostrophes within the phrase. As with many aspects of program development and testing, it is usually wise to avoid using these tools on voluminous amounts of data or numbers of repetitions until simpler cases have been proved.


* Options being considered:

)

flownote=: 0 : 0 Comments on flowtree

The flowtree presentation differs in orientation and operation placement from the syntactic diagrams of system function 5!:4 . Unlike them, it will show the steps of an evaluation even when all operands are provided.

The resulting diagram will be most readable when using box-drawing characters (set by Toggle ASCII Box Drawing in the Tools menu, or 9!:7). The choice among fixed-width fonts can also affect readability.

The most relevant diagram will be produced only when any names in the analyzed expression have current globally defined meanings suitable to its execution in, or accessible from, locale jtrace.

The tree depicts a generally downward flow of information (data). An arithmetic formula may be read from left to right, interpreted in J from right to left, and listed from innermost to outermost in the tree form. Where sub-expressions evaluate independently, they appear in their original relative left-right relationship, but perhaps at different levels.

People familiar with machine-register loading or "reverse-Polish" notations may not find this view too unsettling. It is also used in "data-pipeline" programming, where processing of a succession of records (or atoms or rows or layers) is described as a funneling of the data to workstations or agents which perform their individual tasks and pass the results down the pipe. A flow can be split by copying the data to an alternate stream, as performed by Hook or Fork in J. Separate streams may join, as with dyadic verbs in J. A holding tank or buffer, collecting a whole stream before releasing any results, is effected in J by infinite-rank operations such as Sort, At, and the &.: version of Under. Some selections, like Infix, and finite-rank applications perform partial bufferings at the relevant levels of data aggregation.

In attempting to depict operand flow, a verb is enclosed within connecting input and output bars to any adverb, rank specifier, or other conjunction which has full control over both. A Hook or Fork train is capped with a common bus for distributing external arguments to the internal verbs. A verb formed with Bond (&) is marked with an R as a reminder that a "third argument" is possible, serving as a Repetition factor (or "power"), able to cause mysterious errors. A verb formed with Compose (also &) is marked with a C to call attention to the second-argument juggling which is shown there.

These syntactic diagrams give no depiction of the type, amount, or structure of the data which may be processed. They do not obviate the need to understand the meanings of each symbol or named object, especially the argument-delivery actions of adverbs and conjunctions. What it can help with is understanding whether a verb's monadic or dyadic meaning is being called for, and where its argument(s) is(are) coming from. Once a likely flow structure has been designed, then a trace report can show what results are actually created at each "station" in the pipe network.


In any programming language, the interpretation and execution of any statement or program is dependent on the context in which it is defined and executed. It can give useful results only for particular ranges and combinations of the data with which it works, whether built in as literal values, stored as external variables, or supplied as arguments. The actions of called subroutines will vary with the nature of the libraries from which they are pulled.

The fully dynamic interpretive nature of J provides nearly unlimited opportunities for misinterpretation leading to error conditions, lack of results, or--in the worst case--plausible but incorrect results. To analyze a J statement or program accurately, it must be performed in a context as close as possible to that in which is to be used, dependent on:

--loaded scripts --current locale --current search path --libraries available for searching --system parameters modifiable via '!:' --global names defined or redefined by prior execution --local names defined in active functions

All(!) of these conditions are dynamically modifiable in J. Most strikingly, the syntactic structure of a statement can vary as the names appearing in it are redefined as nouns, verbs, adverbs, or conjunctions. An appropriate parse diagram may be obtainable only by inserting a parsing call for a statement in its context, just ahead of, or in place of, the statement itself. The diagram may be written to the screen, to a noun, or to a file, replacing or appending to previous values.

This wide variability makes it more important than in some other languages to include tests for the suitability of arguments and other values, especially since J's built-in operations will return some conceivably useful result whenever the combination of arguments permits.

Execution

Because the syntactic nature of a name can change during a computation, a statement being parsed has to be executed as the report is being generated. To minimize side effects, it is performed in locale jtrace. Because a subexpression may be executed repeatedly within each containing expression, one which contains an assignment may store varying values on successive rounds, leading to results different from what would have been a single execution, and possibly a different parsing structure. (Flowtree executes each verb only once, but beware of successive invocations.) Any global assignment will leave a lasting record in locale jtrace or some explicitly assigned locale. Analyzing a statement which should take forever can still produce some useful result, by activating the output statement at the end of 'connect', to report on intermediate sub-expressions in the statement. )

NB.


NB. Table of J-parsing rules NB. Boxed columns to ue in processing four top values on stack: NB. class pattern, selected positions, rule identifier

(x)=: 2^i.#x=. ;:'noun verb adv conj lpar rpar asgn name mark' any=: _1 avn=: adv + verb + noun cavn=: conj + adv + verb + noun edge=: mark + asgn + lpar

x=. ,: (edge, verb, noun, any ); 0 1 1 0; '0 Monad' x=. x, ((edge+avn), verb, verb, noun ); 0 0 1 1; '1 Monad' x=. x, ((edge+avn), noun, verb, noun ); 0 1 1 1; '2 Dyad' x=. x, ((edge+avn), (verb+noun),adv, any ); 0 1 1 0; '3 Adverb' x=. x, ((edge+avn), (verb+noun),conj, verb+noun); 0 1 1 1; '4 Conj' x=. x, ((edge+avn), (verb+noun),verb, verb ); 0 1 1 1; '5 Trident' x=. x, (edge, cavn, cavn, any ); 0 1 1 0; '6 Bident' x=. x, ((name+noun),asgn, cavn, any ); 1 1 1 0; '7 Is' x=. x, (lpar, cavn, rpar, any ); 1 1 1 0; '8 Paren'

PTpatterns=: > 0{"1 x NB. parse table - patterns PTsubj=: > 1{"1 x NB. "subject to" masks PTactions=: 2{"1 x NB. actions

bwand=: 17 b. NB. bitwise and

prespace=: , ~ e.&'.:'@ {. $ ' '"_ NB. preface a space to a word beginning with . or :

isname=: ({: e. '.:'"_) < {. e. (a.{~ , (i. 26)+/ 65 97)"_ NB. 1 iff a string y from the result of ;: is a name

class=: 3 : 0 NB. the class of the word represented by string y

)

show=: 3 : 0

)

encall1=: '('"_ , ] , ' call"'"_ , ] , ')'"_ encall=: encall1&.>^:(isname&> *. 3: = 4!:0)"0 NB. replace function names f in words y by (f call"f)

call=: 1 : 0 NB. for tracing function calls

)

call1=: 4 : 0 NB. call function x on argument(s) y

)

NB.


executep=: 4 : 0 NB. execute rule x for stack y for "paren"

)

executet=: 4 : 0 NB. execute rule x for stack y for "trace"

)

NB. ========================================================= aid=: 0 : 0

┌┌─┌┐─┌┌─┌┐─┌┴─┴┐ │ + │─│ / │─│ \ │ └─└─┘ └─└─┘ └─┬─┘

┌┌─┌┐ ┌┴─┴┐ │+ *│─│ 1│ │└`┘│─│@.┘│ └─└─┘ └─┬─┘

)

NB. ========================================================= x=. ,: (edge, verb, noun, any ); 0 1 1 0; '0 Monad' x=. x, ((edge+avn), verb, verb, noun ); 0 0 1 1; '1 Monad' x=. x, ((edge+avn), noun, verb, noun ); 0 1 1 1; '2 Dyad' x=. x, ((edge+avn), (verb+noun),adv, any ); 0 1 1 0; '3 Adverb' x=. x, ((edge+avn), verb, conj, verb ); 0 1 1 1; '4 ConjVV' x=. x, ((edge+avn), verb, conj, noun ); 0 1 1 1; '5 ConjVN' x=. x, ((edge+avn), noun, conj, verb ); 0 1 1 1; '6 ConjNV' x=. x, ((edge+avn), noun, conj, noun ); 0 1 1 1; '7 ConjNN' x=. x, ((edge+avn), verb, verb, verb ); 0 1 1 1; '8 Fork' x=. x, ((edge+avn), noun, verb, verb ); 0 1 1 1; '9 Trident' x=. x, (edge, cavn, cavn, any ); 0 1 1 0; '10 Bident' x=. x, ((name+noun),asgn, cavn, any ); 1 1 1 0; '11 Is' x=. x, (lpar, cavn, rpar, any ); 1 1 1 0; '12 Paren'

PTApatterns=: > 0{"1 x NB. *augmented* parse table - patterns PTAsubj=: > 1{"1 x NB. "subject to" masks PTAactions=: 2{"1 x NB. actions

NB. Diagrammatic symbols BC=: ' ', 9 6 1 8 10{ 9!:6 HBC=: 0 1 2 3 4 5 6 7 8 10{ 9!:6 VBC=: 0 1 2 3 4 5 6 7 8 9{ 9!:6 BCM=: (5 5$ 1 0 2 0 3 0 0 10 0 0 4 11 5 11 6 0 0 10 0 0 7 0 8 0 9){ ' ', 9!:6 lkix=: ((1 2; 1 0; 1 2), (4 0; 0 2; 4 4),: 1 0; 1 2; 1 0) Argsplit=: (4 0; 0 2; 4 4){ BCM

wid=: _1&{@ (1&,@ $) tomat=: (((_2&{.@ ((2&#@ (*@ (*/@ ]))) , ]) ($@ ]))) $ ,@ ]) botrow=: ({:@ tomat) toprow=: ({.@ tomat) vbarpos=: (I.@ ((_1{ VBC)&=@ ]))"1 catenaries=: ;: ', ,. ,: ; Catenate Stitch Laminate Link'

midpos=: 3 : 0

)

trimval=: 4 : 0

)

nobar=: (((1&|.@ (_1 0&,@ (((9{ 9!:6 )&=@ ({."1))# i.@ #))) {"2 ])@ ":)

propup=: 4 : 0

)

topconn=: 3 : 0

)

botconn=: 3 : 0

)

NB. Index of component containing right- or left-most entry (vertical bar) lastvp=: _1&{@ (I.@ (*@ (>@ (#each@ ])))) firstvp=: 0&{@ (I.@ (*@ (>@ (#each@ ])))) endvp=: [ { (I.@ (*@ (>@ (#each@ ])))) NB. 0 or _1 and position list

NB. Table of joints and extensions: left, right, up, down (size 3 9) bjoint=: <"0 , 0 2 4{ 0 2 4{"1 BCM tr=. |.each t [ t=. (] , |.@])(< 1 1), (< 2 1), (< 2 1) bjoint=: bjoint,: , |: (,each/)"1 (<"1 (3 2$ t)) ,"0/ <"1 (3 2$ tr) bjoint=: bjoint, , 0 2 4 (<@,"0/) 0 2 4

corner=: 4 : 0

)

widentop=: 4 : 0

)

NB.


wrapmod=: 4 : 0

NB. 'Stop' 13!:8 ] 91

NB. 'Stop' 13!:8 ] 92

)

wrapio=: 4 : 0

NB. 'Stop' 13!:8 ] 103

NB. 'Stop' 13!:8 ] 104

NB. 'Stop' 13!:8 ] 105

)

spread=: 4 : 0

NB. 'Stop' 13!:8 ] 101

)

NB.


connect=: 4 : 0

NB. if. 18< # rulhist do. NB. aashstk=: 1 NB. smoutput rultyp; wt; < top NB. 'Stop' 13!:8 ] 1 NB. end.


NB. 'Stop' 13!:8 ] 11


NB. 'Stop' 13!:8 ] 33


NB. top=. (< (> 0{ top),"1 ((# > 0{ top), 0>. tbdiff)$ ' ') 0} top NB. wt=. wt+ (0>. tbdiff), 0 0 NB. vtall=. > ; vt+each 0, (0{ wt), +/ 0 1{ wt [ vt=. (< 0) 0} vt NB. tbdiff=. 0

'Stop' 13!:8 ] 100

NB. 'Stop' 13!:8 ] 109


NB. if. rultyp= 2 do. 'Stop' 13!:8 ] 82 end.

NB. 'Stop' 13!:8 ] 22

NB. 'Stop' 13!:8 ] 23

NB. smoutput rultyp; wt; tbdiff; < top NB. 'Stop' 13!:8 ] 83

NB. if. rultyp= 8 do. 'Stop' 13!:8 ] 83 end.

NB. if. rultyp= 2 do. 'Stop' 13!:8 ] 24 end.

NB. 'Stop' 13!:8 ] 88

NB. 'Stop' 13!:8 ] 77


NB. 1 0 _1 VV 4: " ` ^: & &. &.: &: . .. .: : :.
@ @:

NB. 1 0 _1 VN 5: " ` ^: & ;. !. d. D. D: L: S: T. NB. _1 0 1 NV 6: " ` @. & NB. _1 0 _1 NN 7: "  @. : ;. !: : D. H. NB. Selecting from up/dn joint (col.) for center/left/right (row)

jntclr=. ((] * 1&>:@ (|@ ])) 1 0 2{ updn){"0 1 ] ((< 0 2), 2 3$ _2<\ 0 2 0 0 4 0 0 2 0 4 4 4){ BCM NB. Widths l/c/r, for middle/bottom/top in each vmdu=. > 0 1 2{each ((] * 1&>:@ (|@ ])) 0 1 2{ updn){ (< 3# < i. 0), (< vb), < vt wdu=. (< 0 1)|: > (0 1 2{ updn){ (< i. 0), (< wb), < wt cdir=. - _1{ updn NB. Verb-last/first indicator (_1 1) uplt=. _1= {. updn [ uprt=. _1= {: updn 'ml mc mr'=. mid

if. -. ((< 0 0){ BCM)e. mc do.

conjs=. '" @. ` !: : ;. :.

.. .: & ' flags=. 'ran age tie fgn mdy cut obv adv eve odd bon ' conjs=. conjs, '^: !. &. &.: &: `: L: S: d. D. D: H: T: ' flags=. flags, 'pow fit und una app evo lva spr dv0 drv sec hyp tay ' conjs=. conjs, 'Rank Agenda Tie Foreign Dyad Cut Obverse Adverse ' flags=. flags, 'Ran Age Tie Fgn Mdy Cut Obv Adv ' conjs=. conjs, 'Even Odd Bond Power Fit Under Appose' flags=. flags, 'Eve Odd Bon Pow Fit Und App ' (flags)=. (< , {. mc)(<@ =) ;: conjs ran=. ran+. Ran [ age=. age+. Age [ cut=. cut+. Cut

NB. >>> More needed here!

NB. 'Stop' 13!:8 ] 47

NB. 'Stop' 13!:8 ] 40

NB. 'Stop' 13!:8 ] 42

NB. 'Stop' 13!:8 ] 42

NB. 'Stop' 13!:8 ] 64

NB. 'Stop' 13!:8 ] 65

NB. 'Stop' 13!:8 ] 66

NB. 'Stop' 13!:8 ] 67

NB. 'Stop' 13!:8 ] 68

NB. 'Stop' 13!:8 ] 43

NB. 'Stop' 13!:8 ] 43

NB. top=. (< (((# > 1{ top), dr- dl)$ ' '),"1 > 1{ top) 1} top NB. wt=. (wid@ >) top NB. vtall=. > ; vt+each 0, (0{ wt), +/ 0 1{ wt

NB. 'Stop' 13!:8 ] 44

NB. 'Stop' 13!:8 ] 97

NB. smoutput rultyp, fgn, hyp, mdy

NB. 'Stop' 13!:8 ] 98

NB. 'Stop' 13!:8 ] 97

)

executef=: 4 : 0

)

NB. ========================================================= NB. Each row of queue or stack shows: NB. a value classification NB. a value expression (evaluation result, when in flowtree mode) NB. a formatted tree (when in flowtree mode) NB. "parse" initializes queue, then processes to stack, compacting both

movep=: 3 : 0 NB. move from queue to stack for "paren"

)

movef=: 3 : 0 NB. move from queue to stack for "flowtree"

)

movet=: 3 : 0 NB. move from queue to stack for "trace"

)

NB.


NB. stack=: parse mode; depth, or size, limit; sentence NB. mode: 'trace' or 'paren' or 'flowtree' NB. depth: depth limit for function calls to trace NB. sentence: character string to be parsed NB. stack: stack at the end of the parse

parse=: 3 : 0 NB. for paren, trace

try.

catchd.

end.

)

parsef=: 3 : 0 NB. for flowtree

NB. elseif. 'parenpyr' -: t_mode do. NB. execute=. executepp NB. move=. movep

)

flowstat=: 3 : 0

)

NB.


pdepthn=: (+/\@ (1 _1 0&({~)@ ('()'&i.@ ((2&|@ (+/\@ ('&=))){"0 0 1 ('&(,.~)))))) CP=: {@(,&<)

pyr=: 3 : 0 NB. pyramid of parenthetical levels

)

paren=: 3 : 0 NB. full parenthesization of sentence y

)

parenpyr=: 3 : 0 NB. pyramidal parenthesization of sentence y

)

flowtree=: 3 : 0 NB. syntactic diagram of sentence y

)

trace=: 3 : 0 NB. execution trace to depth x (_ default) of sentence y

)

paren_z_=: paren_jtrace_ pyr_z_=: pyr_jtrace_ parenpyr_z_=: parenpyr_jtrace_ flowtree_z_=: flowtree_jtrace_ trace_z_=: trace_jtrace_

ArtAnger/aatrace.ijs (last edited 2010-11-04 02:55:33 by ArtAnger)