Beginner's J question, vol. 5 (ranks continued)
Author Message
Beginner's J question, vol. 5 (ranks continued)

My gratitude to respondents is unbounded.  Again:

The function q operates on 3x3 arrays to produce a boolean result.
Given an Nx3x3 array, I want to construe it as N 3x3 arrays and
apply q pairwise between the cells, to produce an NxN table.

This seemed like a job for the / (table) adverb, but what is required
is:

tbl =. q"_ _1"_1 _ /~

If either or both rank conjunctions are omitted, the function fails.

It appears that the second rank is used by / to establish the shape of
the left argument, and the first rank is then used during applications
of q to the resulting pairs of cells.  If this is so, why?

I tried to follow the parse table, but my first production started
with    n a a n   which I couldn't find in the table.

Henry Rich

Mon, 24 Mar 1997 05:22:53 GMT
Beginner's J question, vol. 5 (ranks continued)
Henry Rich:
. The function q operates on 3x3 arrays to produce a boolean result.
. Given an Nx3x3 array, I want to construe it as N 3x3 arrays and
. apply q pairwise between the cells, to produce an NxN table.
.
. This seemed like a job for the / (table) adverb, but what is
. required is:
.
. tbl =. q"_ _1"_1 _ /~

Here's some simplified versions:
tbl =. q"_1 _1/~
tbl =. q"_1/~
tbl =. q"2/~

. It appears that the second rank is used by / to establish the shape
. of the left argument, and the first rank is then used during
. applications of q to the resulting pairs of cells.  If this is so,
. why?

You're using q dyadically.  You want to apply q to rank 2 subarrays
for both the left and right arguments.  [Or maybe I am missing
something...]

. I tried to follow the parse table, but my first production started
. with    n a a n   which I couldn't find in the table.

Using \$ to indicate end of sentence, and assuming that the adverbs
produce verbs:

queue               stack       pattern                 subsequent action
\$ n a a n                       ?      ?  ? ?           Get Next
\$ n a a                 n       ?      ?  ? ?           Get Next
\$ n a                 a n       ?      ?  ? ?           Get Next
\$ n                 a a n       ?      ?  ? ?           Get Next
\$                 n a a n       ?      ?  ? ?           Get Next
\$ n a a n       \$=(avn nv a ?           Adverb
\$ v a n       \$=(avn nv a ?           Adverb
\$ v n       \$=(    v  n ?           Monad
\$ n                               ACCEPT

Note that pattern matching occurs against the stack, from left to
right.  If the stack is deeper than four elements the rightmost
elements are ignored.

--
Raul D. Miller           n =: p*q             NB. 9<##:##:n [.large prime p, q

NB.  public e, n, y
x -: n&|&(*&y)^:d 1  NB. 1=(d*e)+.p*&<:q

Mon, 24 Mar 1997 09:30:31 GMT
Beginner's J question, vol. 5 (ranks continued)

Quote:
>Henry Rich:
>. The function q operates on 3x3 arrays to produce a boolean result.
>. Given an Nx3x3 array, I want to construe it as N 3x3 arrays and
>. apply q pairwise between the cells, to produce an NxN table.
>.
>. This seemed like a job for the / (table) adverb, but what is
>. required is:
>.
>. tbl =. q"_ _1"_1 _ /~

>Here's some simplified versions:
>tbl =. q"_1 _1/~
>tbl =. q"_1/~
>tbl =. q"2/~

In my version (J 6.2), these do not produce the same results.

tbl =. q"2/~

produces the desired result, but the others generate a 1xN vector.

Quote:

>. It appears that the second rank is used by / to establish the shape
>. of the left argument, and the first rank is then used during
>. applications of q to the resulting pairs of cells.  If this is so,
>. why?

>You're using q dyadically.  You want to apply q to rank 2 subarrays
>for both the left and right arguments.  [Or maybe I am missing
>something...]

I guess I chose an unlucky time to experiment with negative ranks,
but at least I'm learning something.

The main point is this: I thought I had learned that the key point
is to determine the rank of the verb.  But, for some reason,

tbl =. q"_ _1"_1 _ /~      (correct result)
tbl =. q"_1 _ /~           (length error)
tbl =. q"_ _1 /~           (length error)

are all different.  In particular, the behavior of the first
line suggests that the rank of this verb is from a two-dimensional
space (i. e. the rank used for developing the left argument seems
to be different frm the one used for developing the right argument).

will just ask: how can the first line not be the same as
one of the other two? (I can enclose the verb in parentheses with
no effect)

Quote:
>Note that pattern matching occurs against the stack, from left to
>right.

Ah, I was matching right-to-left.

Henry Rich

Mon, 24 Mar 1997 20:46:08 GMT
Beginner's J question, vol. 5 (ranks continued)
Henry Rich:
>Here's some simplified versions:
>tbl =. q"_1 _1/~
>tbl =. q"_1/~
>tbl =. q"2/~

In my version (J 6.2), these do not produce the same results.
tbl =. q"2/~
produces the desired result, but the others generate a 1xN vector.

Hmmm.. I hadn't tested the variants with "_1 or "_1 _1, but I get an N
element result under J7.  I expect that this is an implementation bug.

--
Raul D. Miller           n =: p*q             NB. 9<##:##:n [.large prime p, q

NB.  public e, n, y
x -: n&|&(*&y)^:d 1  NB. 1=(d*e)+.p*&<:q

Tue, 25 Mar 1997 01:32:17 GMT
Beginner's J question, vol. 5 (ranks continued)
I've been asked in email about the existence of a routine to show
parsing overviews.  My prior post had been produced by hand, but it's
not hard to make an automatic parser.  I've appended the code of such
to the end of this post.  Here's a couple examples of how it looks:

parse 'n a a n'
queue                             stack      pattern             action
\$ n a a n                                    ?      ?    ?    ?  GetNext
\$ n a a                               n      ?      ?    ?    ?  GetNext
\$ n a                               a n      ?      ?    ?    ?  GetNext
\$ n                               a a n      ?      ?    ?    ?  GetNext
\$                               n a a n      ?      ?    ?    ?  GetNext
\$ n a a n      \$=(avn nv   a    ?  Adverb
\$ v a n      \$=(avn nv   a    ?  Adverb
\$ v n      \$=(    v    n    ?  Monad1
\$ n                          Accept

parse 'n (c c c) n n'
queue                             stack      pattern             action
\$ n ( c c c ) n n                            ?      ?    ?    ?  GetNext
\$ n ( c c c ) n                       n      ?      ?    ?    ?  GetNext
\$ n ( c c c )                       n n      ?      ?    ?    ?  GetNext
\$ n ( c c c                       ) n n      ?      ?    ?    ?  GetNext
\$ n ( c c                       c ) n n      ?      ?    ?    ?  GetNext
\$ n ( c                       c c ) n n      ?      ?    ?    ?  GetNext
\$ n (                       c c c ) n n      ?      ?    ?    ?  GetNext
\$ n                       ( c c c ) n n      \$=(    ac   ac   ac Forkc
\$ n                           ( c ) n n      (      cavn )    ?  Punct
\$ n                               c n n      ?      ?    ?    ?  GetNext
\$                               n c n n      ?      ?    ?    ?  GetNext
\$ n c n n      \$=(avn nv   c    nv Conj
\$ v n      \$=(    v    n    ?  Monad1
\$ n                          Accept

I dunno -- maybe someone will find this educational.

Raul D. Miller           n =: p*q             NB. 9<##:##:n [.large prime p, q

NB.  public e, n, y
x -: n&|&(*&y)^:d 1  NB. 1=(d*e)+.p*&<:q

attachment: parse.js

NB. adverb which derives a verb which interprets the trailing
NB. character of a string as a delimiter.
split=: ;._2

NB. porting notes: In J7 (0 :4) gathers the following lines as a newline
NB. terminated string (up to a terminating line which is a right parenthesis
NB. alone on a line.  Also note that each of the following lines should
NB. contain five tab characters (and no space characters, the last
NB. character of each line should be a tab).
NB.
NB. parsetable is a 15 by 5 array where the first column is actions
NB. and the remaining four columns represent the pattern which
NB. triggers the action.

parsetable=:  <split split (0 :4)
Conj    \$=(avn  nv      c       nv
Forkv   \$=(avn  v       v       v
Hookv   \$=(     v       v       ?
Forkc   \$=(     ac      ac      ac
Hookc   \$=(     ac      ac      ?
Curry   \$=(     c       nv      ?
Curry   \$=(     nv      c       ?
Is      np      =       cavn    ?
Punct   (       cavn    )       ?
Deref   p       ?       ?       ?
GetNext ?       ?       ?       ?
)

NB. verb derived by syntax takes a single argument which is a triple:
NB. left side is region to be substituted, middle is substitution (or
NB. empty), right side is stack before substitution.  Verb is derived
NB. from a specification of allowable object types (if multipe types
NB. are possible, the first listed is the default).
syntax=: 0 :0 &
:
('region';'sub';'stack')=: x.
('offset';'len')=: region
sub=: sub [^:(*#sub) {.y.
". (-. ({.sub) e. y.) # 'error=:''domain error'''
(offset{.stack), (<sub), (offset+len)}.stack
)

NB. verb derived by subst generates argument for verb derived by
NB. syntax.  Verb is derived from a specification of pre-set
NB. substitutions (arranged as a table where first column is "before"
NB. and second column is "after") and the substitution region.
subst=: 0 :0 &
:
('table';'region')=: y.
('keys';'members')=:|:table
pat=: x. {~ (+ i.)/region
new=:(keys i.<pat){members,<''
". (new-:<0) #'error=:''domain error'''
(<region),new,<x.
)

NB. handlers for actions

NB. verb to convert a name to its gerund

conjs=:  0 2\$''

forkvs=: 0 2\$''

hookvs=: 0 2\$''

currys=: 0 2\$''

Is =:    2&}.

Punct =: 1&{ , 3&}.

GetNext =: 0 :0 , ]
". (0 = # queue)#'error=:''syntax error'''
t=:     {: queue
queue=: }: queue
t
)

NB. take a list of boxes which represents a flat list and return that list

print =: 1!:2&2
widths=: 20 _20 5 20 10

NB. top level function.  Right arg is text to be executed.
parse=: 0 :0
queue=: ;:'\$ ',y.
error=:''

stack=: ''
patterns=: }."1 parsetable
t=: ":patterns,&.>' '
patdisplay=: ((t{~<1 0)={."1 t)#((t{~<0 1)={.t)#"1 t
actions=: {."1 parsetable
handlers=: verb actions
print widths format 'queue';'stack';'';'pattern';'action'

loop) ind=: patterns match 4{.stack
print widths format (form queue); (}:form stack); ''; (ind{patdisplay); >ind{actions
stack=: (ind{handlers)\ stack

NB. status check
done=: (0=#queue)*('\$'={.>{.stack)*2=#stack
\$.=. >(0=#error){abort; done{loop; finish

finish)
print widths format (form queue); (}:form stack); ''; ''; 'Accept'
\$.=.''

abort)
print widths format (form queue); error; ''; ''; 'error'
''
)

Sat, 29 Mar 1997 08:15:31 GMT
Beginner's J question, vol. 5 (ranks continued)
My routine 'parse' has a rather unpleasant behavior when the string
being parsed is too long -- it just truncates the queue and stack.

For example,

parse 'noun verb conjunction verb noun'
queue                             stack      pattern             action
\$ noun verb conjunct                         ?      ?    ?    ?  GetNext
\$ noun verb conjunct               noun      ?      ?    ?    ?  GetNext
\$ noun verb conjunct          verb noun      ?      ?    ?    ?  GetNext
\$ noun verb         njunction verb noun      ?      ?    ?    ?  GetNext
\$ noun              njunction verb noun      ?      ?    ?    ?  GetNext
\$                   njunction verb noun      \$=(avn nv   c    nv Conj
\$                           noun v noun      ?      ?    ?    ?  GetNext
\$ noun v noun      \$=(avn n    v    n  Dyad
\$ n                          Accept

This can be corrected, by changing the formatting used by parse.
For example:

alph=:  ~.' ',a.

width=: 40

parse=: 0 :0
queue=: ;:'\$ ',y.
error=:''

stack=: ''
patterns=: }."1 parsetable
t=: ":(1 |."1 parsetable,<'  '),&.>' '
patdisplay=: '   ',"1((t{~<1 0)={."1 t)#((t{~<0 1)={.t)#"1 t
actions=: {."1 parsetable
handlers=: verb actions
width=. width >. 5+# reform queue
patwidth=: {:\$patdisplay
print (width merge 'queue';'stack '), patwidth merge '   pattern';'action  '

loop) ind=: patterns match 4{.stack
print (width merge queue;&form stack), ind{patdisplay
stack=: (ind{handlers)\ stack

NB. status check
done=: (0=#queue)*('\$'={.>{.stack)*2=#stack
\$.=. >(0=#error){abort; done{loop; finish

finish)
print (width merge queue;&form stack), patwidth merge ''; 'Accept  '
\$.=.''

abort)
print (width merge (form queue); error), patwidth merge ''; 'error   '
''
)

If you append this code to the bottom of the previous parse.js file,
things work somewhat more smoothly:

parse 'noun verb conjunction verb noun'
queue                             stack   pattern                action
\$ noun verb conjunction verb noun          ?      ?    ?    ?  GetNext
\$ noun verb conjunction verb       noun    ?      ?    ?    ?  GetNext
\$ noun verb conjunction       verb noun    ?      ?    ?    ?  GetNext
\$ noun verb       conjunction verb noun    ?      ?    ?    ?  GetNext
\$ noun       verb conjunction verb noun    ?      ?    ?    ?  GetNext
\$       noun verb conjunction verb noun    \$=(avn nv   c    nv Conj
\$                           noun v noun    ?      ?    ?    ?  GetNext
\$ noun v noun    \$=(avn n    v    n  Dyad
\$ n                        Accept

Also, in the course of testing, I noticed that GetNext doesn't quite
do what I'd wanted it to do.  Here's a fixed version:

GetNext =: 0 :0 , ]
". (0 = # queue)#'\$.=.i.0 [ error=:''syntax error'''
t=:     {: queue
queue=: }: queue
t
)

--
Raul D. Miller           n =: p*q             NB. 9<##:##:n [.large prime p, q

NB.  public e, n, y
x -: n&|&(*&y)^:d 1  NB. 1=(d*e)+.p*&<:q

Mon, 31 Mar 1997 07:49:29 GMT
Beginner's J question, vol. 5 (ranks continued)
I found another problem with parse -- this time it's a definition I
left out.

Deref=: (<'v')"_,}.

By the way, if anyone wants to add a "symbol table" to the routine,
all you have to do is change the definitions of Is and Deref.  Names
begining with 'p' are valid candidates to appear in such a symbol
table.

I'd do it myself, but I don't know if anyone besides myself is
interested in this sort of thing -- so perhaps it's better to leave
this sort of thing "as an exercise for the reader".

Another possible enhancement are to give enhance Adverb and Conj so
that specific functions can yield results with types other than
'v'erb.

--
Raul D. Miller           n =: p*q             NB. 9<##:##:n [.large prime p, q

NB.  public e, n, y
x -: n&|&(*&y)^:d 1  NB. 1=(d*e)+.p*&<:q

Mon, 31 Mar 1997 11:01:20 GMT

 Page 1 of 1 [ 7 post ]

Relevant Pages