Scripts/TacitToExplicit

From J Wiki
Jump to navigation Jump to search

In this message, Harvey Hahn asks whether it's possible to convert tacit verbs to explicit. Here's an attempt.

NB. Rewrite trains and other tacit verbs to explicit definition.
0 :0
ttem is an adverb that converts a monadic verb to explicit.
tted is the same for diadic verbs.

It's not perfect, so some strange verbs might not work.
The output is somewhat simplified in structure,
but we don't care about unnecessary parenthesis or whitespace.
It may also have more serious bugs, tell me if you find any.

Implementation note: we prefix local variables so they don't clash with
globals occurring in the verb, because if they clash they can mess up
4!:0 queries.

NB. Zsban Ambrus
)


ttesymcnt =: _1x
ttegensym =: 3 :0
({&'tsrqpz'@:],":@:[)/@:(0 6&#:) ttesymcnt=:>:ttesymcnt
)

tte =: 1 :'u ttem'
ttem =: 1 :0
(ttemmain ttederef 5!:1<'u') ttemwrap
)
tted =: 1 :0
(ttedmain ttederef 5!:1<'u') ttedwrap
)
ttemwrap =: 3 :
ttedwrap =: 4 :
ttederef =: 3 :0
if. 1<L.y do. y elseif. 3~:4!:0 y do. y elseif.do. 5!:1 y end.
)
ttemmain =: (,<'y')&ttemain
ttedmain =: ('x';'y')&ttemain
ttexy =: 3 :'>{.y'
ttexn =: 3 :'>_2{a:,y'
ttey =: 3 :'>{:y'
ttesimplep =: 1=L.
ttetrivialp =: 0:`((,.'[]')e.~,@:>)@.ttesimplep
ttenamep =: _1<:4!:0

ttemain =: 4 :0
if. ttesimplep y do. x ttesimple y
elseif. L.tte_h=.,>{.>y do. x ttedefault y
elseif. tte_h-:,'3' do. x ttefork >{:>y
elseif. tte_h-:,'2' do. x ttedefault y NB. hooks are homework for the reader
elseif. tte_h-:'@:' do. x ttecompose >{:>y
elseif. tte_h-:,'&' do. x ttebond >{:>y
elseif. tte_h-:,'"' do. x tterank >{:>y
elseif. tte_h-:,'~' do. x ttetilde {.>{:>y
elseif.do. x ttedefault y
end.
)

ttedefault =: 4 :0
tte_z=.y 5!:0
<(ttexn x),'(',(5!:5<'tte_z'),')',ttey x
)
ttetrivial =: 4 :0
if. (tte_h=.,>y)-:,'[' do. <ttexy x elseif. tte_h-:,']' do. <ttey x
elseif.do. [:0 end.
)
ttesimple =: 4 :0
if. ttetrivialp y do. x ttetrivial y
else. <(ttexn x),' ',(>y),' ',ttey x end.
)
ttetoname =: 3 :0
if. ttenamep{:y do.
(>{:y) ,&:< }:y
else.
tte_t=. ttegensym 0
tte_b=:(}:y),(<tte_t,'=. ',>{:y)
tte_t ,&:< tte_b
end.
)
ttecompose =: 4 :0
tte_b=. x ttemain {:y
if. ttesimplep {.y do.
(}:tte_b),<(>{.y),' ',>{:tte_b
else.
'tte_t tte_bb'=. ttetoname tte_b
tte_a=. (<tte_t)ttemain{.y
tte_bb,tte_a
end.
)
ttefork =: 4 :0
if. '[:'-:,>0{y do. x ttecompose }.y
else.
tte_l=.(0{y)5!:0
if. 0=4!:0<'tte_l'
do.
tte_a=.$0
tte_s=.'(',(5!:5<'tte_l'),')'
else.
'tte_s tte_a'=. ttetoname x ttemain 0{y
end.
'tte_t tte_c'=. ttetoname x ttemain 2{y
tte_b=. (tte_s,&:<tte_t)ttemain 1{y
tte_c,tte_a,tte_b
end.
)
tterank =: 4 :0
tte_l=.({.y)5!:0
if. 0~:4!:0<'tte_l'
do. x ttedefault <'"';<y
elseif. tte_r=.({:y)5!:0
0~:4!:0<'tte_r'
do. x ttedefault <'"';<y
elseif. +./_~:tte_r
do. x ttedefault <'"';<y
elseif.do. <5!:5<'tte_l'
end.
)
ttebond =: 4 :0
if. 2=#x do. x ttedefault <'&';<y
elseif. tte_l=.({.y)5!:0
0=4!:0<'tte_l'
do.
if. 5<#tte_ll=:5!:5<'tte_l' do.
'tte_s tte_a'=. ttetoname<tte_ll
tte_b=. (x,~<tte_s) ttemain {:y
tte_a,tte_b
else.
(x,~<'(',tte_ll,')') ttemain {:y
end.
elseif. tte_r=.({:y)5!:0
0=4!:0<'tte_r'
do.
if. 5<#tte_rr=:5!:5<'tte_r' do.
'tte_t tte_b'=. ttetoname<tte_rr
tte_a=. (x,<tte_t) ttemain {.y
tte_b,tte_a
else.
(x,<'(',tte_rr,')') ttemain {.y
end.
elseif.do.
x ttedefault <'&';<y
end.
)
ttetilde =: 4 :0
if. tte_l=.y 5!:0
0=4!:0<'tte_l'
do.
1!:2&2 'D10';<<'~';<,y
x ttedefault <'~';<,y
elseif. 2=#x do.
(|.x) ttemain y
elseif.do.
(x,x) ttemain y
end.
)


NB. end of code

TODO:

  • Handling of hooks should be implemented.
  • The handling of constant nouns should be factored out from tterank and applied uniformly to ttebond as well.
  • Handling of number constant shorthand verbs _9: to 9: and _: should be implemented.
  • Apply recursively to the verb or gerund parameter of the most common operators, e.g. rank, reduce. This may encounter a difficulty with how 5!:5 handles explicit definitions though.

And an example, let's take this verb that forms a spiral from this mailing list message I wrote.

   spiral1 =: - ]\ >:@:i.@:*: [`]`[} [: /: [: ,/ [: (>.&| , (12&o.)@:(1j_1&*)@:j.)"0/~ i. - -:@:<:

Suppose we have all the above code saved to tte.ijs. Let's do the following to translate this verb to explicit.

0!:0<'tte.ijs'
spiral1 =: - ]\ >:@:i.@:*: [`]`[} [: /: [: ,/ [: (>.&| , (12&o.)@:(1j_1&*)@:j.)
NB. we decompose this to two verbs
sh =: >.&| , (12&o.)@:(1j_1&*)@:j.
sp =: - ]\ >:@:i.@:*: [`]`[} [: /: [: ,/ [: sh"0/~ i. - -:@:<:
sp 5
NB. now convert it to explicit automatically
she =: sh tted
she
spx =: - ]\ >:@:i.@:*: [`]`[} [: /: [: ,/ [: she"0/~ i. - -:@:<:
spx 5
spe =: spx ttem
spe
spe 5
spe 4

And the output is:

   NB. we decompose this to two verbs
   sh =: >.&| , (12&o.)@:(1j_1&*)@:j.
   sp =: - ]\ >:@:i.@:*: [`]`[} [: /: [: ,/ [: sh"0/~ i. - -:@:<:
   sp 5
25 24 23 22 21
10  9  8  7 20
11  2  1  6 19
12  3  4  5 18
13 14 15 16 17
   NB. now convert it to explicit automatically
   she =: sh tte
   she
sh tte
   0!:0<'tte.ijs'
   spiral1 =: - ]\ >:@:i.@:*: [`]`[} [: /: [: ,/ [: (>.&| , (12&o.)@:(1j_1&*)@:j.)
   NB. we decompose this to two verbs
   sh =: >.&| , (12&o.)@:(1j_1&*)@:j.
   sp =: - ]\ >:@:i.@:*: [`]`[} [: /: [: ,/ [: sh"0/~ i. - -:@:<:
   sp 5
25 24 23 22 21
10  9  8  7 20
11  2  1  6 19
12  3  4  5 18
13 14 15 16 17
   NB. now convert it to explicit automatically
   she =: sh tted
   she
4 : 0
s0=. x j. y
r0=. (1j_1) * s0
q0=. (12) o. r0
t0=. x(>.&|)y
t0 , q0
)
   spx =: - ]\ >:@:i.@:*: [`]`[} [: /: [: ,/ [: she"0/~ i. - -:@:<:
   spx 5
25 24 23 22 21
10  9  8  7 20
11  2  1  6 19
12  3  4  5 18
13 14 15 16 17
   spe =: spx ttem
   spe
3 : 0
r1=. -:  <: y
s1=.  i. y
q1=. s1 - r1
p1=. q1(she"0/)q1
z1=. /: (,/)p1
z0=.  *: y
t1=. >:  i. z0
t2=. t1([`]`[})z1
p0=.  - y
p0(]\)t2
)
   spe 5
25 24 23 22 21
10  9  8  7 20
11  2  1  6 19
12  3  4  5 18
13 14 15 16 17
   spe 4
16 15 14 13
 5  4  3 12
 6  1  2 11
 7  8  9 10

The diad [`]`[} isn't translated automatically, I think the translation would be 4 :'x y} x'.

-- B Jonas <<DateTime(2008-05-03T17:31:38Z)>>