Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to calculate f1(f2(...fn(x)...)) given a gerund?

Tags:

j

One can calculate f1(f2(f3(x))) as

*: +: >: 4                 NB. 100

Given a gerund of "unknown" length (eg. m1 =: *:`+:`>:, or m2 =: +:`>:) how can one calculate f1(f2(...(fn(x)) ...))?

So far I have only been able to evoke the gerund using m `: 0.

(*:`+:`>: `: 0) 4         NB. 16 8 5
like image 711
Micha Wiedenmann Avatar asked Dec 13 '19 09:12

Micha Wiedenmann


2 Answers

Let:

   NB. an example gerund
   ] g=: *:`<:`+:`>:
┌──┬──┬──┬──┐
│*:│<:│+:│>:│
└──┴──┴──┴──┘
   NB. a sentence to evoke
   *: <: +: >: 4
81

1st approach (via dynamic programming)

1A. Compose the whole sentence then evoke it

Convert all elements in gerund to linear representation (LR), compose the sentence, then evoke it:

   NB. utility to find out a LR from an atomic
   NB. representation (AR) and parenthesize it
   NB. pLR=. plr AR
   plr=: 3 : 0
v=. y 5!:0
'(' , (5!:5 < 'v') , ') '
)
   NB. result=. gerund v1 input
   v1=: 4 : '". (; <@plr"0 x) , ": y'
   NB. evoke v1 with a gerund and input applied
   g v1 4
81

Pros: no

Cons:

  1. input data type should be exact (neither float nor complex) since Format (":) may truncate
  2. a verb applied to input can be a monad only

1B. Evoke component verbs sequentially

Take the current element from gerund, transform it to verb, apply that verb to accumulator, repeat for the next element from gerund:

   NB. result=. gerund v2 input
   v2=: >@(4 : '(x 5!:0)&.> y'/)@(, <)
   NB. evoke v2 with a gerund and input applied
   g v2 4
81

Pros:

  1. any data types for input are allowed

Cons:

  1. a verb applied to input can be a monad only

2nd approach (functional)

2A. Transform gerund to fork

   NB. a fork we are going to compose, in action
   ([: *: [: <: [: +: >:) 4
81
   NB. its structure
   ([: *: [: <: [: +: >:)
┌──┬──┬──────────────────┐
│[:│*:│┌──┬──┬──────────┐│
│  │  ││[:│<:│┌──┬──┬──┐││
│  │  ││  │  ││[:│+:│>:│││
│  │  ││  │  │└──┴──┴──┘││
│  │  │└──┴──┴──────────┘│
└──┴──┴──────────────────┘
   NB. how to compose it
   ('[:' ; g)@.0 1 0 2 0 3 4
┌──┬──┬──────────────────┐
│[:│*:│┌──┬──┬──────────┐│
│  │  ││[:│<:│┌──┬──┬──┐││
│  │  ││  │  ││[:│+:│>:│││
│  │  ││  │  │└──┴──┴──┘││
│  │  │└──┴──┴──────────┘│
└──┴──┴──────────────────┘
   NB. selector (ISO generator)
   NB. iso=. sel gerund
   sel=: (< < < _2) { (0 ,@,. #\)
   NB. let's test it
   sel g
0 1 0 2 0 3 4
   NB. sentence to assemble a fork
   ('[:' ; g)@.(sel g)
┌──┬──┬──────────────────┐
│[:│*:│┌──┬──┬──────────┐│
│  │  ││[:│<:│┌──┬──┬──┐││
│  │  ││  │  ││[:│+:│>:│││
│  │  ││  │  │└──┴──┴──┘││
│  │  │└──┴──┴──────────┘│
└──┴──┴──────────────────┘
   NB. an adverb executing that sentence
   NB. fork=. gerund a2a
   a2a=: 1 : '(''[:'' ; m)@.(sel m)'
   NB. evoke that adverb to transform a gerund to a fork
   g a2a
┌──┬──┬──────────────────┐
│[:│*:│┌──┬──┬──────────┐│
│  │  ││[:│<:│┌──┬──┬──┐││
│  │  ││  │  ││[:│+:│>:│││
│  │  ││  │  │└──┴──┴──┘││
│  │  │└──┴──┴──────────┘│
└──┴──┴──────────────────┘
   NB. apply a fork produced to input
   g a2a 4
81

Pros:

  1. any data types for input are allowed
  2. a verb applied to input can be of any valence (either monad, dyad or ambivalent)

Cons: no

2B. Transform gerund to conveyor

Join component verbs by At (@:) somehow. A resulting verb will be an At-chained sequence of component verbs.

2B1. Via arconj utility

Join component verbs to compose AR, then convert AR to verb by Define (5!:0).

   NB. a chain we are going to compose, in action
   *:@:<:@:+:@:>: 4
81
   NB. its structure
   *:@:<:@:+:@:>:
┌──────────────────┬──┬──┐
│┌──────────┬──┬──┐│@:│>:│
││┌──┬──┬──┐│@:│+:││  │  │
│││*:│@:│<:││  │  ││  │  │
││└──┴──┴──┘│  │  ││  │  │
│└──────────┴──┴──┘│  │  │
└──────────────────┴──┴──┘
   NB. its AR
   chain=. *:@:<:@:+:@:>:
   5!:1 < 'chain'
┌────────────────────────────────┐
│┌──┬───────────────────────────┐│
││@:│┌──────────────────────┬──┐││
││  ││┌──┬─────────────────┐│>:│││
││  │││@:│┌────────────┬──┐││  │││
││  │││  ││┌──┬───────┐│+:│││  │││
││  │││  │││@:│┌──┬──┐││  │││  │││
││  │││  │││  ││*:│<:│││  │││  │││
││  │││  │││  │└──┴──┘││  │││  │││
││  │││  ││└──┴───────┘│  │││  │││
││  │││  │└────────────┴──┘││  │││
││  ││└──┴─────────────────┘│  │││
││  │└──────────────────────┴──┘││
│└──┴───────────────────────────┘│
└────────────────────────────────┘
   NB. we'll compose it with AR utility (arconj) from addon
   load 'misc/miscutils/langexten'
   NB. an adverb assembling a chain
   NB. chain=. gerund a2b1a
   a2b1a=: 1 : '(''@:'' arconj~/ |. m) 5!:0'
   NB. evoke that adverb to transform a gerund to chain
   g a2b1a
┌──────────────────┬──┬──┐
│┌──────────┬──┬──┐│@:│>:│
││┌──┬──┬──┐│@:│+:││  │  │
│││*:│@:│<:││  │  ││  │  │
││└──┴──┴──┘│  │  ││  │  │
│└──────────┴──┴──┘│  │  │
└──────────────────┴──┴──┘
   NB. apply a chain produced to input
   g a2b1a 4
81

Pros:

  1. any data types for input are allowed
  2. a verb applied to input can be of any valence (either monad, dyad or ambivalent)

Cons: no

Notes:

  1. a2b1a can be simplified to produce a chain with a slightly different structure but the same functionality:

    a2b1b=: 1 : '(''@:'' arconj/ m) 5!:0'
    
  2. arconj utility may be re-implemented manually as [1]:

    arconj2=: (<'@:') ,@<@, <@,
    a2b1c=: 1 : '({. arconj2/ m) 5!:0'
    

    or as [1]:

    arconj3=: 4 : '(x`:6)@(y`:6)`'''''
    a2b1d=: 1 : '({. arconj3/ m) 5!:0'
    

2B2. Via Train (`:6)

Join component verbs, then apply Train (`:6) [2].

   NB. a chain we are going to compose, in action
   *:@:<:@:+:@:>: 4
81
   NB. its structure
   *:@:<:@:+:@:>:
┌──────────────────┬──┬──┐
│┌──────────┬──┬──┐│@:│>:│
││┌──┬──┬──┐│@:│+:││  │  │
│││*:│@:│<:││  │  ││  │  │
││└──┴──┴──┘│  │  ││  │  │
│└──────────┴──┴──┘│  │  │
└──────────────────┴──┴──┘
   NB. an adverb assembling a chain
   NB. chain=. gerund a2b2
   a2b2=: 1 : '(}: , m ,. <''@:'')`:6'
   NB. evoke that adverb to transform a gerund to chain
   g a2b2
┌──────────────────┬──┬──┐
│┌──────────┬──┬──┐│@:│>:│
││┌──┬──┬──┐│@:│+:││  │  │
│││*:│@:│<:││  │  ││  │  │
││└──┴──┴──┘│  │  ││  │  │
│└──────────┴──┴──┘│  │  │
└──────────────────┴──┴──┘
   NB. apply a chain produced to input
   g a2b2 4
81

Pros:

  1. any data types for input are allowed
  2. a verb applied to input can be of any valence (either monad, dyad or ambivalent)
  3. the simplest version

Cons: no

Notes

J Forums are the best place to ask if you prefer to get answer quicker.

References

[1]: [Jprogramming] Gerund composed application by Raul Miller, 2017-09-25

[2]: System/Interpreter/Requests#verb pipelines by Dan Bron, 2007-12-21

like image 184
Igor Zhuravlov Avatar answered Oct 19 '22 21:10

Igor Zhuravlov


This solution is not elegant, but it works.

Start by converting the gerund into a string form using Foreign Conjunctions Define (5!:0) adverb and Atomic Representation (5!:1) then unbox using Raze (;).

Then convert the y argument to a string using Default Format (":) and prepending a blank to give space to the gerund string.

Use Append (,) to create one string and apply Do (".) to that string for the result.

g=: 4 : 0
s=: ; (5!:1 <'t'[t=.x) 5!:0  NB. changes gerunds to string
a=:' ' , ": y                NB. makes argument into a string prefixed by blank
". s,a
)

or on one line

g1=: 4 : ' ". (; (5!:1 <''t''[t=.x) 5!:0 ), '' '' , ": y'

   *:` +:` >: g 4
100
   *:` +:` >: g1 4
100
like image 2
bob Avatar answered Oct 19 '22 21:10

bob