# BQN runtime part 1. Requires: # Type Fill Log GroupLen GroupOrd _fillBy_ # +-×÷⋆⌊⌈|<>=≠≤≥≢⊢⊣⥊∾⋈↑↓↕⊏⊑!⌜˙˜¨´`∘○⊸⟜◶⊘⍟ # Filled in by runtime: glyphs and default PrimInd # Provides: all BQN primitives Ind1 ← { 0 Fill +`(0⌈≠-1˙)⊸↑GroupLen+`𝕩 } / ← Ind1 ⊘ (Ind1⊸⊏) # LIMITED to natural number list 𝕩/𝕨 Decompose ← {0‿𝕩} PrimInd ← {𝕩} SetPrims ← {Decompose‿PrimInd ↩ 𝕩} SetInv ← {{swapInverse 𝕏↩}𝕨 ⋄ inverse 𝕏↩} IsArray ← 0=Type IsAtom ← 1≤Type Int ← (1=Type)◶⟨0,⌊⊸=⟩ Nat ← (1=Type)◶⟨0,|∘⌊⊸=⟩ ToArray ← <⍟IsAtom IsSimple ← 1×´IsAtom⌜ Deshape ← IsArray◶{𝕩Fill⟨𝕩⟩}‿⥊ Cell ← ↓⟜≢ MatchS ← 1×´=¨ PermInv ← 1⌜⊸GroupOrd _qSearch ← {+´·×`𝕗(1-=)⌜<} _glyphLookup_ ← { {PrimInd𝕩} ⊑ ((𝕘⊑˜𝕗_qSearch)⌜glyphs)˙ } _isGlyph ← { (glyphs _qSearch 𝕗) = {PrimInd𝕩} } IsJoin ← '∾'_isGlyph IsTable ← '⌜'_isGlyph DIsConst ← (4=0⊸⊑)◶0‿('˙'_isGlyph 2⊸⊑) Split2 ← { s←2⊸×⌜↕(≠𝕩)÷2 ⋄ ⟨s⊏𝕩,(1⊸+⌜s)⊏𝕩⟩ } _lookup_ ← { k‿v←Split2 𝕘 ⋄ k _glyphLookup_ (v∾⟨𝕗⟩) } ScalId ← @ _lookup_ ⟨ '+',0 , '-',0 '×',1 , '÷',1 '⋆',1 , '¬',1 '⌊',∞ , '⌈',¯∞ '∨',0 , '∧',1 '≠',0 , '=',1 '>',0 , '≥',1 ⟩ TabId ← { id ← (4=0⊸⊑)◶⟨0,(IsTable 2⊸⊑)⟩◶⟨@,ScalId 1⊸⊑⟩ Decompose 𝕩 "´: Identity not found" ! @>id ⋄ 0 } =○=◶⟨>○=◶⟨𝔽_e⋄𝔽˜_e˜⟩⋄𝔽_d⟩ } _perv←{ # Pervasion R←+○IsArray◶⟨ 𝔽 {R⌜𝕩}⊘(>○IsArray◶{𝕨˙⊸R⌜𝕩}‿{R⟜(𝕩˙)⌜𝕨}) _fillBy_ {𝕨R𝕩} {𝕨R _eachd𝕩} _fillBy_ {𝕨R𝕩} ⟩ } # Sorting CLE ← (≤⟜∞≤·=˜⊢)≤≤ # Place NaNs after other numbers Cmp0 ← CLE˜-CLE Cmp1 ← (0<1×´≢∘⊢)◶⟨1, IsArray∘⊢◶(1-2×≤)‿{𝕨Cmp1𝕩}⟜(0⊑⥊)⟩ CmpLen ← { e←𝕨-○(1×´0⊸<⌜)𝕩 𝕨(e=0)◶⟨e,0⟩‿{ SM←Cmp0 ⋈ ≥⊑⋈ c‿r←𝕨SM○≠𝕩 l←𝕨{ i←0+´×`𝕨=¨𝕩 m←1×´i↕⊸⊏𝕨 {k‿l←SM´𝕩⋄c↩k⋄m×↩l}∘(<⊑⌜𝕨‿𝕩˙)⍟(r⊸>)i m }○{𝕩⊏˜(¯1+≠𝕩)⊸-⌜↕r}𝕩 ⟨c,l⟩ }𝕩 } _getCellCmp ← { Ci←𝔽⋄c←𝕨⊣0⋄l←𝕩 Cc←{ a←𝕨⋄b←𝕩 S←(l⊸=)◶{S∘(1+𝕩)⍟(0⊸=)a Ci○(𝕩⊸+)b}‿c S 0 } (𝕨 ⊢⊘{𝕨⍟(0⊸=)𝕏} ci˙)⍟(1=l) cc } Cmp ← +○IsArray◶⟨ Cmp0 IsArray∘⊣◶⟨Cmp1,-Cmp1˜⟩ { lc←𝕨CmpLen○≢𝕩 cc ← (⊑⟜(⥊𝕨))⊸Cmp⟜(⊑⟜(⥊𝕩)) _getCellCmp´ lc Cc˜0 } ⟩ _grade ← { gt ← 𝕗 cmps ← {𝕏˜}⌜⍟𝕗⟨Cmp,Cmp0,Cmp≤0˙,CLE⟩ _getC_ ← { 𝕨 𝕘{(𝕨 𝕏 _getCellCmp 𝕗)≤0˙}⍟(𝕩≤1) 𝔽 𝕩⊑cmps } 0 Fill { "⍋𝕩: 𝕩 must have rank at least 1" ! 1≤=𝕩 l←≠𝕩 (2≤l)◶⟨↕∘l,{ m1←1=m←1×´1 Cell 𝕩 𝕩↩⥊𝕩 a0←1⋄ts←0⋄{a0×↩1≤𝕩⋄ts+↩𝕩}∘Type⌜𝕩 cs←a0+2×m1 Merge ← { # Merge sort le ← 𝕩{𝕏○(⊑⟜𝕗)} _getC_ m cs B←l⊸≤◶⊢‿l (↕l){ i←-d←𝕨 ⋄ j←ei←ej←0 e←3 ⋄ G←LE○(⊑⟜(m⊸×⌜⍟(1-m1)𝕩)) ⋄ c←⟨1-G,0,1,2⟩ s←(8≤d)⊑⟨+,{(𝕩-1){e↩2⋄j↩i⋄i↩𝕩}⍟G⍟(1-e)𝕩}⟩ N←{i↩d+𝕨⋄ej↩B d+ei↩B j↩d+𝕩⋄e↩l≤j⋄S ei⋄i R j} R←{𝕨e◶c𝕩}◶{e+↩2×ei=i↩1+𝕨⋄𝕨}‿{e+↩ej=j↩1+𝕩⋄𝕩}‿N {(i R j)⊑𝕩}⟜𝕩⌜𝕩 }´(2⋆ni-1+⊢)⌜↕ni←⌈2 Log l+l=0 } # Counting sort for small-range ints bl←bu←0 ⋄ Count←{GroupLen⊸GroupOrd (gt⊑⟨-⟜bl,bu⊸-⟩)⌜𝕩} sr←((3=cs)×ts=l)◶⟨0,(1×´⌊⊸=⌜)◶0‿{((bu↩⌈´𝕩)-bl↩⌊´𝕩)≤2×l}⟩𝕩 sr◶Merge‿Count 𝕩 }⟩𝕩 }⊘{ cx←(=𝕩)-c←1-˜=𝕨 "⍋ or ⍒: Rank of 𝕨 must be at least 1" ! 0≤c "⍋ or ⍒: Rank of 𝕩 must be at least cell rank of 𝕨" ! 0≤cx sw←1 Cell 𝕨 ⋄ nw←≠𝕨 𝕩↩ToArray𝕩 ⋄ sx←cx Cell 𝕩 ⋄ lz←1×´sz←cx↑≢𝕩 sz ⥊ 𝕨 (0⟜1) 1 + (nw+1) R ¯1 } (BinSearch (1×´sx)⊸×)⌜ ↕lz }○⥊ 𝕩 } } ⍋ ← 0 _grade ⍒ ← 1 _grade # Searching _search←{ # 0 for ∊˜, 1 for ⊐ ind ← 𝕗 red ← 𝕗⊑⟨1-×´,+´×`⟩ 0 Fill { c←1-˜=𝕨 "p⊐𝕩 or 𝕨∊p: p must have rank at least 1" ! 0≤c "p⊐n or n∊p: Rank of n must be at least cell rank of p" ! c≤=𝕩 n←≠𝕨 ⋄ k←1×´s←1 Cell 𝕨 ⋄ cx←c-˜=𝕩 lx←1×´sh←cx↑≢𝕩 sh ⥊ 𝕨 (e←0,⊢⟩ n×e)⌜↕lx}‿{ cc ← (⊑⟜(⥊𝕨))⊸(1-Match)⟜(⊑⟜(⥊𝕩)) _getCellCmp k 𝕨 ×○(8<≠∘⥊)◶{𝕩 i‿j←(k⊸×⌜↕)⌜n‿lx ⋄ {Red CC⟜𝕩⌜i}⌜j }‿{ g←Reverse⍒𝕨 i←g⊏˜(0⌈-⟜1)⌜⥊(g⊏𝕨)⍋𝕩 adj←ind⊑⟨1⊸-,⊣--⟜n⊸×⟩ i(⊣ Adj CC○(k⊸×))¨↕lx } 𝕩 } 𝕩 }⟜ToArray } _self←{ "∊𝕩 or ⊐𝕩: 𝕩 must have rank at least 1" ! 1≤=𝕩 g←⍋𝕩 k←1×´1 Cell 𝕩 cc ← (1-Match)○(⊑⟜(⥊𝕩)) _getCellCmp k 0 Fill (PermInv g) ⊏ g 𝔽 0⊸<◶⟨1, -⟜1 CC○(⊑⟜(k⊸×⌜g)) ⊢⟩⌜↕≠𝕩 } Find←{ r←=𝕨 ⋄ d←(=𝕩)-r "𝕨⍷𝕩: Rank of 𝕨 cannot exceed rank of 𝕩" ! 0≤d i←<0 ⋄ j←⥊⟜(↕1×´⊢)d↑s←≢𝕩 (≢𝕨) { A←×⟜𝕩⌜⊸(+⌜)⟜↕ ⋄ i A↩𝕨 ⋄ j A↩0⌈1+𝕩-𝕨 }¨ d↓s 0 Fill (𝕨 Match (⥊𝕩)⊏˜i+⌜<)⌜ j }○ToArray Indices←{ "/𝕩: 𝕩 must have rank 1" ! 1==𝕩 "/𝕩: 𝕩 must consist of natural numbers" ! 1×´Nat⌜𝕩 / 𝕩 } IndicesInv←{ IA 1==𝕩 IA 1×´Nat⌜𝕩 GroupLen 𝕩 } SelfClas ← (PermInv∘⍋∘/˜⊏˜¯1+`⊢) _self OccurrenceCount ← ↕∘≠⊸(⊣-¨·⌈`ר) _self Transpose←(1<=)◶⟨ToArray,{ l←≠𝕩 ⋄ m←1×´c←1 Cell 𝕩 (⥊𝕩)⊏˜(c⥊↕m)+⟜(m⊸×)⌜↕l }_fillBy_⊢⟩ TransposeInv←{ r←1-˜=𝕩 ⋄ s←≢𝕩 ⋄ l←r⊑s ⋄ c←r↑s (⥊𝕩)⊏˜(↕l)+⟜(l⊸×)⌜c⥊↕1×´c }_fillBy_⊢⍟{IX IsArray𝕩⋄1<=𝕩} _reorderAxesSub_←{ "𝕨⍉𝕩: 𝕨 must have rank at most 1" ! 1≥=𝕨 𝕨↩Deshape𝕨 ⋄ 𝕩↩ToArray𝕩 "𝕨⍉𝕩: Length of 𝕨 must not exceed rank of 𝕩" ! (≠𝕨)≤r←=𝕩 "𝕨⍉𝕩: 𝕨 must consist of valid axis indices" ! 1∧´(Nat∧<⟜r)⌜𝕨 r𝔽↩n←GroupLen𝕨 k←≠a←𝔾 𝕨∾/0⊸=⌜n c‿d←k(↑⋈↓)≢𝕩 l‿s←a⊸Group1⌜⋈⟜Stride c (⌊´⌜l) (0<≠∘⊢)◶⟨∾⟜d⊸⥊,((<0)+⌜´s(<+´)⊸(×⌜)⟜↕¨⊣)⊏(⟨1×´c⟩∾d)⥊⊢⟩ ⥊𝕩 } HandleDupAxes←{ r←𝕨-0+´(0⌈-⟜1)⌜𝕩 "𝕨⍉𝕩: Skipped result axis" ! (≠𝕩)≤r r } ReorderAxes ← HandleDupAxes _reorderAxesSub_ ⊢ ReorderAxesInv ← {IA 1≥0⌈´𝕩⋄𝕨} _reorderAxesSub_ PermInv Prefixes←{ "↑𝕩: 𝕩 must have rank at least 1" ! 1≤=𝕩 0⊸⊑⊸Fill ↕⊸⊏⟜𝕩⌜ ↕1+≠𝕩 } Suffixes←{ "↓𝕩: 𝕩 must have rank at least 1" ! 1≤=𝕩 l←≠𝕩 l⊸⊑⊸Fill {𝕩⊸+⌜↕l-𝕩}⊸⊏⟜𝕩⌜ ↕1+l } NormIndP‿NormIndS←{ EI‿er←𝕩 ⋄ _cr←{⊢⊣er!𝔽} 0⊸≤◶⟨0⊸≤_cr+, >_cr⟩ ⊣ EI∘⊢ }⌜⟨ ⟨"𝕨⊑𝕩: Indices in 𝕨 must consist of integers"!Int,"𝕨⊑𝕩: Index out of range"⟩ ⟨"𝕨⊏𝕩: Indices in 𝕨 must be integers"!⌊⊸=,"𝕨⊏𝕩: Indices out of range"⟩ ⟩ Pick0←{ "𝕨⊑𝕩: 𝕩 must be a list when 𝕨 is a number" ! 1==𝕩 𝕩⊑˜(≠𝕩)NormIndP𝕨 } Pick1←{ "𝕨⊑𝕩: Indices in compound 𝕨 must be lists" ! 1==𝕨 "𝕨⊑𝕩: Index length in 𝕨 must match rank of 𝕩" ! 𝕨=○≠s←≢𝕩 i←0⋄𝕨{i↩(𝕩NormIndP𝕨)+𝕩×i}¨s i⊑⥊𝕩 }⟜ToArray Pickd←IsArray◶⟨1,IsSimple⥊⟩∘⊣◶{Pickd⟜𝕩⌜𝕨}‿Pick1 Pick←IsArray∘⊣◶Pick0‿Pickd _multiAxis←{ gl‿Test‿d1‿aa‿Single‿Ind ← 𝕗 pre ← "𝕨"∾gl∾"𝕩: " es ← pre∾"𝕩 must have rank at least 1 for simple 𝕨" er ← pre∾"Compound 𝕨 must have rank at most 1" el ← pre∾"Length of compound 𝕨 must be at most rank of 𝕩" et ← pre∾"𝕨 must be an array of numbers or list of such arrays" tt ← d1 ⊑ ⟨⊢ , et ! 1×´·⥊IsArray◶⟨aa,1×´·⥊(1=Type)⌜⟩⌜ ⟩ Test∘⊣◶{ # Multiple axes er ! 1≥=𝕨 ⋄ TT 𝕨 l←≠𝕨↩⥊𝕨 ⋄ el ! l≤=𝕩 i←𝕨Ind¨p←l↑s←≢𝕩 j←i (0<1×´≠∘⥊⌜i)◶⟨{⟨⟩⥊˜Join1≢⌜𝕨}, {j←<0⋄𝕨{j↩(j×⌜<𝕩)+⌜𝕨}¨𝕩⋄j}⟩ p j ⊏ (⟨1×´p⟩∾l↓s)⥊𝕩 }‿{ es ! 1≤=𝕩 𝕨 Single 𝕩 } } FirstCell←{ "⊏𝕩: 𝕩 must have rank at least 1" ! 1≤=𝕩 "⊏𝕩: 𝕩 cannot have length 0" ! 0<≠𝕩 (<0) ⊏ 𝕩 } Select ← ⟨"⊏" 1×´·(1=Type)⌜⥊ ⋄ 1,0 {(≠𝕩)⊸NormIndS⌜𝕨} ⊏ ⊢ {𝕩⊸NormIndS⌜𝕨} ⟩_multiAxis○ToArray First ← IsArray◶⟨⊢, (0<≠)◶⟨!∘"⊑𝕩: 𝕩 can't be empty",0⊸⊑⟩⥊⟩ Reverse←{ "⌽𝕩: 𝕩 must have rank at least 1" ! 1≤=𝕩 l←≠𝕩 ((l-1)⊸-⌜↕l) ⊏ 𝕩 } RotReduce ← { "𝕨⌽𝕩: 𝕨 must consist of integers" ! Int𝕨 𝕩+↩0=𝕩 ⋄ r←𝕨-𝕩×⌊𝕨÷𝕩 "𝕨⌽𝕩: 𝕨 too large" ! r<𝕩 r } RotL ← ↓∾↑ Rot ← (1==∘⊢)◶⟨RotL⟜(↕≠)⊏⊢,RotL⟩ Rotate ← ⟨"⌽" IsAtom, 0,0 (RotReduce⟜≠ Rot ⊢)⍟(0<≠∘⊢) (RotReduce RotL ·↕⊢) ⟩_multiAxis⟜ToArray _fillBy_ ⊢ RepInd←(2⌊=∘⊣)◶{ 𝕨↩(0⊑⥊)⍟IsArray𝕨 "𝕨/𝕩: 𝕨 must consist of natural numbers" ! Nat 𝕨 e←r←𝕨 {e+↩r⋄1+𝕩}⍟{e=𝕨}˜`↕r×𝕩 }‿{ "𝕨/𝕩: Lengths of components of 𝕨 must match 𝕩" ! 𝕩=≠𝕨 "𝕨/𝕩: 𝕨 must consist of natural numbers" ! 1×´|∘⌊⊸=⌜𝕨 / 𝕨 }‿{ "𝕨/𝕩: Components of 𝕨 must have rank 0 or 1" ! 0˙ } Replicate←⟨"/" ((0<≠)×´(1=Type)⌜)∘⥊, 1,1 RepInd⟜≠ ⊏ ⊢ RepInd ⟩_multiAxis○ToArray _fillBy_ ⊢ IsPure ← {d←Decompose𝕩 ⋄ 2⊸≤◶⟨≤⟜0, 1×´·𝕊⌜1↓d˙⟩0⊑d} hfils ← {𝕏´{0 Fill 𝕏}‿⊢}⌜(⊢∾{𝕏˜}⌜)⊢‿{𝕎{𝕎⊘𝕏}𝕏} HomFil ← "=≠≡≢"_glyphLookup_(1‿1‿2‿3‿0⊏hfils)⊸{𝕎𝕩} _fillByPure_←{ 𝕘 (3≤Type∘⊣)◶⟨{𝕨Fill𝕏},{(𝕨HomFil𝕩)_fillBy_𝕨}⍟(IsPure⊣)⟩ 𝕗 } _each ← {𝕨𝔽⌜⊘(𝔽_eachd)_fillByPure_𝔽○ToArray𝕩} _table ← {𝕨𝔽⌜_fillByPure_𝔽○ToArray𝕩} match←{(0⊑𝕨)◶(1⊑𝕨)‿𝕩}´⟨ ⟨=○IsArray, 0⟩ ⟨IsArray∘⊢, =⟩ ⟨=○= , 0⟩ ⟨MatchS○≢ , 0⟩ {1×´⥊𝕨Match¨𝕩} ⟩ Depth←IsArray◶0‿{1+0⌈´Depth⌜⥊𝕩} Join1←{ # List of lists "∾𝕩: 𝕩 must have an element with rank at least =𝕩" ! 0<0+´=⌜𝕩 i←j←¯1 ⋄ e←⟨⟩ ⋄ a←𝕩 {{e↩Deshape a⊑˜i↩𝕩⋄j↩¯1}⍟(1-i⊸=)𝕩⋄(j↩j+1)⊑e}⌜/≠⌜𝕩 } under←{ Err←{𝕩} IsErr ← (3=Type)◶⟨0,Err˙⊸=⟩ E ← Err˙ _errIf ← {⊢⊘×○(1-𝔽)◶⟨Err˙,𝕏⟩} SE ← IsErr _errIf⍟(3≥Type) Expand ← { f‿a‿i‿q←𝕩 ⋄ e←i⊑⥊a ⟨IsArray◶⟨⟨⟩,∾⟜⟨i⟩⟩f,e,IsArray◶⟨0,@Fill⥊⟜(↕1×´⊢)∘≢⟩e,q⟩ }⍟(>⟜(IsArray 2⊑⊢)) Expand2 ← { xf‿xa‿xi‿xq ← 𝕩 E ← { f‿a‿i‿q←𝕩 ⋄ {f‿a‿𝕩‿q _s}⍟(1-IsStruct)⌜⍟(0<≠f) i } i ← (E 1 Expand IsStruct◶{xf‿xa‿𝕩‿xq}‿(1⊑Decompose))⌜ xi ⟨⟩‿@‿i‿⟨1,1⟩ } _s ← { ⟨st,d‿o⟩←𝕩 # Function, input depth, output is structural f‿a‿i‿⟨q,r⟩←Expand2⍟(2=d) (0)⌜n _tf←{𝕗⌜_withNest} ⋄ _ef←{𝕗_eachd _withNest} a ← {(𝕨 B 𝕗)_tf𝕩}‿{𝔽⟜(𝕩˙)_tf𝕨}‿_ef _d←{ t←2⊸×⊸+´0⊸>⌜𝕗 ⋄ 𝕗{𝕩⋄m←(t-1)⊑a⋄(+⟜1⌜𝕗)_d _m}⍟(0", 2‿1 _mon "∾", 2‿1 {+○IsStruct◶⟨𝕏, 𝕩‿𝕗{𝕏𝕗}⊘E, 𝕏_nested⟩} "¨⌜", {m←𝕩⋄{𝔽 _m _withNest}} "˘", {𝕩⋄{𝔽 _rankStruct_ ¯1}} "⎉", rankStruct˙ "⚇", depthStruct˙ ⟩ NSPrim ← (Type-3˙)◶⟨NS, {m←𝕩⋄{NS(𝕗_m)˙0}}, {m←𝕩⋄{NS(𝕗_m_𝕘)˙0}}⟩ SP ← (Join1 k)_glyphLookup_((k≠⌜⊸/v)∾⟨NSPrim⟩) Recompose ← ⊣◶⟨ ⊢ # 0 primitive ⊢ # 1 block {𝕎𝕏}´⊢ # 2-train {F‿G‿H←𝕩⋄F G H} # 3-train {F‿m←𝕩⋄F _m} # 4 1-modifier {F‿m‿G←𝕩⋄F _m_ G} # 5 2-modifier ⟩ Recomp ← (E˙=≥⟜3⊸⊑)◶⟨Recompose,E˙⟩ SFN ← 0⊸≤◶⟨3,2⊸≤◶⊢‿2⟩∘(0⊑⊢)◶⟨ SE · {p←SP𝕩⋄P𝕩} 1⊑⊢ # 0 primitive E˙ # 1 block DIsConst◶⟨SE 0⊸⊑ Recomp {SFN⌜1↓𝕩}, {(1⊑𝕩)˙}⟩ # other operation SE 1⊑⊢ # ¯1 constant ⟩⟜{Decompose𝕩} # Traverse indices 𝕩 and values 𝕨. # Return flat lists ⟨indices,values⟩, or err if 𝕨 doesn't capture 𝕩. conform ← {𝕎◶0‿𝕏}´⟨IsArray⊢, =○=, MatchS○≢⟩ GetInserts ← { v‿d←𝕨 count←1⋄DC←IsArray◶⟨0,d◶⟨1,1+0⌈´{count+↩¯1+≠d←⥊𝕩⋄DC⌜d}⟩⟩⋄depth←DC𝕩 𝕩 (2⌊depth)◶(⋈○⋈)‿(Conform◶⟨Err˙,⋈○⥊⟩)‿{ Fail←{𝕊‿0} # 𝕎 is parent traversal; 𝕩 is current components of ind and val Trav←(IsArray 0⊑⊢)◶⟨⋈, Conform´∘⊢◶Fail‿{ Parent←𝕎 ⋄ n←≠0⊑a←⥊⌜𝕩 ⋄ j←¯1 Child←Trav⟜{𝕩⊸⊑⌜a} { j+↩1 ⋄ f←n⊸≤◶⟨𝕊˙⊸Child,Parent˙⟩j ⋄ F 0 } }⟩ next ← 0 Trav 𝕨‿𝕩 res ← {n‿o←Next𝕩⋄next↩n⋄o}⌜ ↕count (next=fail)◶⟨0⊸⊑⌜ ⋈ 1⊸⊑⌜, Err˙⟩ res } v }⍟(1-IsErr∘⊢) _insert_ ← { i‿v←𝕗_indRec⍟𝕘 𝕩 root‿x←𝕗 Set1←{ 𝕩↩ToArray𝕩 s←≢𝕩⋄l←≠d←⥊𝕩 "Cannot modify fill with Structural Under"!1∧´@⊸>⌜i gl←l GroupLen i ⋄ v⊏˜↩gl GroupOrd i j←0⋄Adv←{(j+↩𝕩)-1}⊑v˙ CM←"⌾: Incompatible result elements in structural Under"!Match s⥊(↕l)2⊸⌊◶⟨⊑⟜d,Adv,Adv{(𝕨CM(j-𝕩)⊸+⊑v˙)⌜↕𝕩-1⋄𝕨}⊢⟩¨gl } _at_ ← {(↕≠𝕩)𝔽⍟((𝔾𝕩)=⊣)¨𝕩} Set ← 0⊸{ (𝕨≥≠root)◶⟨≢⥊(1+𝕨)⊸𝕊_at_(𝕨⊑root˙)∘⥊, Set1⟩ _fillBy_ ⊢ 𝕩 } IsArray∘root◶⟨0⊑v˙, Set⟩ x } _indRec ← { root‿x←𝕗 ⋄ iv←𝕩 l ← GroupLen i ← (1=Type)◶⟨0⊑0⊑1⊑Decompose,¯1⟩⌜ 0⊑iv ind‿val ← (l GroupOrd i)⊸⊏⌜ iv ⋄ rec←0 ic ← (1<·≠0⊑⊢)◶⟨2⊑⊢,{rec↩1⋄𝕩_s}(⋈1↓0⊑⊢)∾1↓⊢⟩∘(1⊑Decompose)⌜ ind j←0 ⋄ IJ←{(j+↩𝕩) ⊢ val ⋈⟜1⊸GetInserts○((j⊸+⌜↕𝕩)⊸⊏) ic} m ← (⊢ ⋈ ⊑⟜(⥊x) {⟨⟩‿𝕨 _insert_ rec⍟(1-IsErr) 𝕩} ·IJ⊑⟜l)⌜ /0⊸<⌜l t ← (/ ¯1⊸=⌜i)⊸⊏⌜ iv {(𝕩⊸⊑⌜m)∾𝕩⊑t}⌜ ↕2 } { val←𝕨𝔽○𝔾𝕩 s←𝕘 SFN⊸{𝕎𝕩} InitS 𝕩 root‿ind‿⟨d,rec⟩ ← IsStruct◶⟨0‿Err‿⟨0,0⟩,0‿2‿3⊏1⊑Decompose⟩ s IsErr◶⟨root‿𝕩 _insert_ rec, {𝕏val}·Inverse𝔾˙⟩ val‿d GetInserts ind } } ≡ ← Depth ⊘ Match ≢ ↩ IsArray◶(↕0)‿≢ ⊘ (1-Match) IF ← ⊢⊣!∘≡ # Intersect fill IEF← (0<≠)◶⟨⊢_fillBy_ Fill, ⊢_fillBy_ IF´⟩∘⥊ HasFill ← 0=·Fill⊢_fillBy_(@⍟(3≤Type∘⊣))⟜(↕0) _fillMerge_ ← {(0<≠∘⥊)◶⟨(𝔾○≢⥊⟨⟩˙)_fillBy_⊢⟜Fill⍟HasFill, 𝔽 ⊣_fillBy_⊢ IEF⟩} Merge←{ c←≢0⊑⥊𝕩 (">𝕩: Elements of 𝕩 must have matching shapes" ! c =○≠◶0‿MatchS ≢)⌜⥊𝕩 (Deshape⌜𝕩)⊑˜⌜c⥊↕1×´c }_fillMerge_∾⍟IsArray JoinTo←(1<⌈○=)◶(∾○⥊)‿{ a←1-˜𝕨⌈○=𝕩 s←𝕨⋈○≢𝕩 "𝕨∾𝕩: Rank of 𝕨 and 𝕩 must differ by at most 1" ! 1×´(a≤≠)⌜s c←(≠-a˙)⊸↓⌜s "𝕨∾𝕩: Cell shapes of 𝕨 and 𝕩 must match" ! MatchS´c l←0+´(a<≠)◶1‿(0⊑⊢)⌜s (⟨l⟩∾0⊑c)⥊𝕨∾○⥊𝕩 }○ToArray _fillBy_ IF _s0←{s←𝕨⋄F←𝔽⋄{o←s⋄s F↩𝕩⋄o}⌜𝕩} Stride←Reverse 1 ×_s0 Reverse JoinM←{ # Multidimensional n←≠z←⥊𝕩 ⋄ s←≢⌜z ⋄ r←=𝕩 sh←≢𝕩 ⋄ p←1 ⋄ i←j←he←<0 (Stride sh){ q←𝕨 a←𝕩⊑sh h←-⟜(1-˜0⌈´rr)⌜rr←=⌜z⊏˜q⊸×⌜↕a "∾𝕩: Incompatible element ranks" ! 1×´0⊸≤⌜h hl←≠ih←q⊸×⌜/h sf←s⊏˜⥊((a×q)⊸×⌜↕p)+⌜ih+⌜↕q si←⥊he⊣⌜↕hl×q "∾𝕩: Incompatible element ranks" ! 1×´si<⟜≠¨sf m←si⊑¨sf lf←m⊏˜q⊸×⌜↕hl "∾𝕩: 𝕩 element shapes must be compatible" ! m MatchS ⥊(↕p)⊢⌜lf⊣⌜↕q k ← / l←{i←¯1⋄⊢◶1‿{(i+↩𝕩)⊑lf}⌜h} c ← (↕≠k)-¨k ⊏ 0+_s0 l he↩ he +⌜ h i ↩ (i ×⌜ k⊏l) +¨ i⊢⌜c j ↩ j ×⟜a⊸+⌜ k p×↩a }¨↕r d←(=0⊑z)-0⊑he↩⥊he "∾𝕩: 𝕩 element trailing shapes must match" ! he MatchS (=-d˙)⌜z G←(Deshape⌜z){𝕨⊑𝕩⊑𝕗}¨ i (0⟜0)⊢)⍟take (l×k) (take=p)◶↓‿↑ ⥊𝕩 }‿{ ernk ! 1≥=𝕨 𝕨 ↩ ⥊𝕨 eint ! 1×´Int⌜𝕨 r ← ≠𝕨 s ← r {(1⌜∘↕𝕨-≠𝕩)∾𝕩}⍟(>⟜≠) ≢𝕩 _c ← { (×⟜𝕗⌜𝕨) +⌜ 𝕩 } i←<0 ⋄ k←1 ⋄ UIk←{ i (k×𝕨)_c↩ k ↕⊸(𝕨_c)⍟(1-=⟜1) 𝕩 ⋄ k↩1 ⋄ ≠𝕩 } doFil←0 sh ← (r↑s) Noop◶{k×↩𝕨⋄𝕨}‿(⊣ UIk {𝕩⋄doFil↩1}_inds)¨ 𝕨 (0<=i)◶(s⊸⥊)‿{ sh ∾↩ t ← r↓s {i 𝕩_c↩ ↕𝕩}⍟(1-1⊸=) k×´t Sel ← ⊑⟜(⥊𝕩) 𝕩{Sel↩0⊸≤◶⟨(Fill𝕨)˙,Sel⟩}⍟⊢doFil Sel⌜ sh ⥊ i } 𝕩 }_fillBy_⊢ ⟜ ToArray } Take ← 0 _takeDrop Drop ← 1 _takeDrop ShiftCheck←{ "« or »: 𝕩 must have rank at least 1" ! 1≤=𝕩 s←1 Cell 𝕩 𝕨 { # Only if called with two arguments "« or »: 𝕨 must not have higher rank than 𝕩" ! 0≤𝕩 "« or »: Rank of 𝕨 must be at least rank of 𝕩 minus 1" ! 1≥𝕩 "« or »: 𝕨 must share 𝕩's major cell shape" ! s MatchS (1-𝕩)↓≢𝕨 } 𝕩-○=𝕨 (𝕨1⊘{(𝕩≤○=⊢)◶1‿≠𝕨}𝕩) ×´ s } ShiftBefore←{ n←𝕨 ShiftCheck 𝕩 m←n⌊l←≠d←⥊𝕩 (≢𝕩) ⥊ (𝕨{(Fill𝕩)⌜↕𝕨}⍟(0⟜0×1+≥⟜=)◶⟨<⊢,EncCell,<⌜_fillBy_<⊢⟩ _cells ← { F←𝔽 ⋄ _m←{𝔽⌜⊘(𝔽¨)_fillByPure_𝔽○(1⊸EncCell)} D←{ "˘: Argument lengths don't agree" ! 𝕩=○≠𝕨 ⋄ 𝕨 F _m 𝕩 } Merge 𝕨 2⊸×⊸+○(0<=)◶⟨⟜≠◶⟨↑, ⊣(⊢∾-⟜≠↑⊢)÷⟜2⊸{𝕨𝕊⟜(∾˜)⍟(>⟜≠)𝕩}⟩ 𝕩 }_fillBy_⊢⍟(1-l=n) d } _group←{ "⊔: Grouping argument must consist of integers" ! 1×´Int⌜𝕩 "⊔: Grouping argument values cannot be less than ¯1" ! 1×´¯1⊸≤⌜𝕩 GL←GroupLen⋄𝕩↩𝕨(-˜⟜≠{GL↩(0⌈𝕨⊑𝕩)GL⊢⋄𝕨↑𝕩}⊢)⍟(0⊘⊣)𝕩 d←(l←GL𝕩)GroupOrd𝕩 i←0⋄(𝔽d⊏˜{(i+↩𝕩)⊢i⊸+⌜↕𝕩})⌜l } GroupInds←{ "⊔𝕩: 𝕩 must be a list" ! 1==𝕩 G←⊢_group (1<≡)◶⟨ ↕∘0 Fill G ((⊢Fill⥊⟜⟨⟩)0⌜) Fill (<<⟨⟩) ∾⌜⌜´ {⊏⟜(⥊Range≢𝕩)⌜ G⥊𝕩}∘ToArray⌜ ⟩ 𝕩 } Group1←{ n←=𝕨 "𝕨⊔𝕩: Rank of simple 𝕨 must be at most rank of 𝕩" ! n≤=𝕩 ld←(≢𝕨)-¨n↑s←≢𝕩 dr←(1=n)◶⟨0,1=0⊸⊑⟩ld "𝕨⊔𝕩: Lengths of 𝕨 must equal to 𝕩, or one more only in a rank-1 component" ! dr◶⟨1×´0⊸=⌜,1⟩ld SX←((n==𝕩)◶{c←1×´t←n↓s⋄𝕩⊏˜(c⊸×⊸+)⌜⟜(t⥊↕c)}‿{⊏⟜𝕩} ⥊𝕩)∘⊣ _fillBy_ ⊢⟜𝕩 (SX⟨⟩) Fill dr SX _group ⥊𝕨 }○ToArray GroupM←{ "𝕨⊔𝕩: Compound 𝕨 must be a list" ! 1==𝕨 n←0+´r←=⌜𝕨 "𝕨⊔𝕩: Total rank of 𝕨 must be at most rank of 𝕩" ! n≤=𝕩 ld←(Join1≢⌜𝕨)-¨n↑≢𝕩 "𝕨⊔𝕩: Lengths of 𝕨 must equal to 𝕩, or one more only in a rank-1 component" ! 1×´ld((0≤⊣)×≤)¨r/1⊸=⌜r dr←r⌊¨(0+_s0 r)⊏ld∾⟨0⟩ l←dr-˜⟜≠¨𝕨↩Deshape⌜𝕨 ⋄ LS←∾⟜(n Cell 𝕩) Reshape 𝕩˙ S←⊏⟜(LS⟨1×´l⟩) (LS 0⌜𝕨) Fill dr (1≠≠∘⊢)◶⟨ S _group○(0⊸⊑) S⌜ ·+⌜⌜´ (Stride l) {𝕨⊸×⌜⌜𝕩}¨ ⊢_group¨ ⟩ 𝕨 } GroupGen←{ "𝕨⊔𝕩: 𝕩 must be an array" ! IsArray 𝕩 𝕨(2≤≡𝕨)◶Group1‿GroupM𝕩 } GroupIndsInv ← { IA 1==𝕩 IX 1×´(1==)⌜𝕩 j←Join1 𝕩 IA 1×´(1≠=)⌜j IX 1×´Nat⌜j {IX𝕨<𝕩⋄𝕨}´⍟(0<≠)⌜𝕩 g←GroupLen j IX 1×´≤⟜1⌜g o←/1⊸-⌜g (PermInv j∾o)⊏(/≠⌜𝕩)∾¯1⌜o } GroupInv ← { IA 1==𝕨 IA 1×´Nat⌜𝕨 l←GroupLen𝕨 IX l=○≠𝕩 IX l MatchS ≠⌜𝕩 (PermInv l GroupOrd 𝕨) ⊏ Join 𝕩 } ValidateRanks←{ "⎉ or ⚇: 𝔾 result must have rank at most 1" ! 1≥=𝕩 𝕩↩Deshape𝕩 "⎉ or ⚇: 𝔾 result must have 1 to 3 elements" ! (1⊸≤×≤⟜3)≠𝕩 "⎉ or ⚇: 𝔾 result must consist of integers" ! 1×´Int⌜𝕩 𝕩 ⊏˜ (≠𝕩)⊸(-+1-˜⌊∘÷˜×⊣)⌜ 𝕨 } _ranks ← {⟨2⟩⊘⟨1,0⟩ ValidateRanks 𝔽} _depthOp_←{ neg←0⊸>⌜n←𝕨𝔾_ranks𝕩 ⋄ F←𝔽 ⋄ B←{𝕏}⊘{𝕨˙⊸𝕏} fb←((3≤Type)◶1‿IsPure𝕗)⊑{𝕘⋄𝔽}‿{𝔽_fillBy_𝔾} _tf←{𝕗⌜_fb_𝕗} ⋄ _ef←{𝕗_eachd _fb_ 𝕗} _d←{ r←0 ⋄ GR←𝕗{𝕩⋄gr↩0⋄R↩(𝕗+¨neg)_d} Tw‿Tx←⟨0⟩⊸∾⍟(2>≠)neg{(𝕨×0≤𝕩)⊑⟨(0⌈𝕩)<≡,0⟩}¨𝕗 (2×Tw)⊸+⟜Tx◶⟨ F, {GR 0⋄(𝕨 B r)_tf𝕩}, {GR 0⋄R⟜(𝕩˙)_tf𝕨}, {GR 0⋄𝕨R _ef𝕩} ⟩ } 𝕨 n _d 𝕩 } _rankOp_←{ Min←<◶⊢‿⊣ k←𝕨(⋈○= (0≤⊢)◶⟨Min⟜-,⊣-Min⟩¨ 𝔾_ranks)𝕩 Merge ((0⊑k)EncRank𝕨) 𝔽_each ((1-˜≠)⊸⊑k)EncRank𝕩 } _repeat_←{ F←𝔽 ⋄ b←𝕨{𝕏⊣}˙⊘{𝕨˙{𝔽𝕏⊣}}0 n←𝕨𝔾𝕩 Multi←{ l←u←0 {"⍟: 𝕨𝔾𝕩 must consist of integers"!Int𝕩⋄l⌊↩𝕩⋄u⌈↩𝕩}_perv n i←⟨𝕩⟩⋄P←B⊸{𝕎`i∾↕𝕩} pos←f P u neg←f 0⊸<◶⟨i,Inverse⊸P⟩ -l (|⊑<⟜0⊑pos‿neg˙)_perv n } (Nat n)◶Multi‿{𝕩(B f)∘⊢´↕n} 𝕩 } ÷ ↩ ÷ _perv ⋆ ↩ ⋆ _perv √ ← ⋆⟜(÷2) ⊘ (⋆⟜÷˜) | ← (| ⊘ (>○|◶{𝕩-𝕨×⌊𝕩÷𝕨}‿(+⍟(<⟜0◶⟨0⊸>,0⊸<⟩))) ) _perv ⌊ ↩ (⌊ ⊘ (⊣⍟<)) _perv ⌈ ↩ (-∘⌊∘- ⊘ (⊣⍟>)) _perv ∧ ← ⍋⊸⊏ ⊘ (× _perv) ∨ ← ⍒⊸⊏ ⊘ ((+-×) _perv) × ↩ (0⊸(<->) ⊘ ×) _perv < ↩ < ⊘ ((1-≥) _perv) > ↩ Merge ⊘ ((1-≤) _perv) ≠ ↩ ≠ ⊘ ((1-=) _perv) = ↩ = ⊘ (= _perv) ≥ ← !∘"≥: Needs two arguments" ⊘ (≥ _perv) ≤ ↩ !∘"≤: Needs two arguments" ⊘ (≤ _perv) + ↩ + _perv - ↩ - _perv ¬ ← 1+- ⊐ ← SelfClas ⊘ (1 _search) ProgressiveIndexOf ← 0 Fill { c←1-˜=𝕨 "⊒: Rank of 𝕨 must be at least 1" ! 0≤c "⊒: Rank of 𝕩 must be at least cell rank of 𝕨" ! c≤=𝕩 𝕨⊐○(⋈¨⟜(≢⥊OccurrenceCount∘⥊) 𝕨⊸⊐)𝕩 } ⁼ ← {Inverse 𝕗} IsConstant ← (3≤Type)◶⟨1 ⋄ DIsConst∘{Decompose𝕩}⊢⟩ AtopInverse ← {(𝕏𝕎)⊘(𝕏⟜𝕎)}○{Inverse𝕩} TrainInverse ← { t‿f‿g‿h←𝕩 K←¬IsConstant f K∘⊣◶⟨{𝕏⁼{𝕨𝔽𝔾𝕩}(𝕨G⁼⊢)},K∘⊢◶⟨{𝕎⁼𝕩G{SwapInverse𝕗}⊢},INF˙⟩⟩ h } FuncInverse ← (0⊸⊑ ⊣◶⟨ {PrimInverse𝕩} 1⊸⊑ # 0 primitive (!∘"Can't invert blocks (add an undo header?)")˙ # 1 block 1⊸⊑ AtopInverse 2⊸⊑ # 2-train TrainInverse # 3-train 1⊸⊑ {𝕏𝕨}⟜{Mod1Inverse𝕩} 2⊸⊑ # 4 1-modifier 1‿3⊸⊏ {𝕏´𝕨}⟜{Mod2Inverse𝕩} 2⊸⊑ # 5 2-modifier ⟩ ⊢) {Decompose𝕩} Inverse ← Type◶(3‿1‿2/{⊢⊣𝕩IX∘≡⊢}‿FuncInverse‿(!∘"Cannot invert modifier")) IA ← "⁼: Inverse failed"⊸! IX ← "⁼: Inverse does not exist"⊸! INF← "⁼: Inverse not found"!0˙ _invChk_ ← {i←𝕨𝔽𝕩⋄IX 𝕩≡𝕨𝔾i⋄i} ↕ ↩ Range ⊘ Windows ⊏ ↩ FirstCell ⊘ Select _fillBy_ ⊢ ⌽ ← Reverse ⊘ Rotate ↑ ↩ Prefixes ⊘ Take ↓ ↩ Suffixes ⊘ Drop PrimInverse ← INF _lookup_ ⟨ '+', +⊘(-˜) '-', - '×', ⊢_invChk_×⊘(÷˜) '÷', ÷ '⋆', Log _perv '√', ט⊘(⋆˜) '∧', ⊢_invChk_∧⊘(÷˜) '∨', ⊢_invChk_∨⊘(-˜÷1-⊣) '¬', ¬ '≠', {B←0⊸=∨1⊸=⋄IX B𝕩⋄IA B𝕨⋄𝕩≠𝕨} _perv '<', {IX IsArray𝕩⋄IX 0==𝕩⋄0⊑⥊𝕩}⊘(IA∘0) '⊢', ⊢ '⊣', ⊢⊘(⊢⊣IX∘≡) '∾', IA∘0 ⊘ {d←𝕩-○=𝕨⋄IX(0⊸≤∧≤⟜1)d⋄l←d◶≠‿1𝕨⋄IX l≤≠𝕩⋄IX (ToArray𝕨)≡d◶⟨l⊸↑,⊏⟩𝕩⋄l↓𝕩} '≍', {IX 1 =≠𝕩⋄ ⊏𝕩} ⊘ {IX 2 =≠𝕩⋄IX 𝕨≡ ⊏𝕩⋄1⊏𝕩} '⋈', {IX ⟨1⟩≡≢𝕩⋄0⊑𝕩} ⊘ {IX ⟨2⟩≡≢𝕩⋄IX 𝕨≡0⊑𝕩⋄1⊑𝕩} '↑', ¯1⊸⊑_invChk_↑ ⊘ (IA∘0) '↓', 0⊸⊑_invChk_↓ ⊘ (IA∘0) '↕', ≢_invChk_↕ ⊘ (IA∘0) # Should trace edge and invChk '⌽', ⌽ ⊘ (-⊸⌽ ⊣ IX∘IsArray∘⊢) '⍉', TransposeInv ⊘ ReorderAxesInv '/', IndicesInv ⊘ (IA∘0) '⊔', GroupIndsInv ⊘ GroupInv ⟩ SwapInverse ← INF _lookup_ ⟨ '+', ÷⟜2⊘(-˜) '-', IA∘0⊘+ '×', √⊘(÷˜) '÷', IA∘0⊘× '⋆', IA∘0⊘√ '√', IA∘0⊘(÷Log) '∧', √⊘(÷˜) '∨', (¬√∘¬)⊘(-˜÷1-⊣) '¬', IA∘0⊘(+-1˙) ⟩ ⌜ ↩ _table ¨ ↩ _each ∾ ↩ Join ⊘ JoinTo » ← ShiftBefore « ← ShiftAfter Mod1Inverse ← INF˙ _lookup_ ⟨ '⁼', ⊢ '˜', {SwapInverse𝕩} '¨', {𝕏⁼¨ ⊣·IX 0<≡∘⊢} '⌜', {𝕏⁼⌜⊘(IA∘0) ⊣·IX 0<≡∘⊢} '˘', {(IX∘IsArray⊸⊢𝕏⁼)˘ ⊣·IX 0<=∘⊢} '`', {(⊏∾¯1⊸↓𝕏1⊸↓)⍟(1<≠)⊘(»𝕏⊢)⊣·IX 0<=∘⊢}∘{𝕏⁼¨} ⟩ ⍟ ↩ _repeat_ ⌾ ← _under_ Mod2Inverse ← INF˙ _lookup_ ⟨ '∘', AtopInverse '○', {Fi←𝕎⁼⋄𝕏⁼ Fi⊘(𝕏⊸Fi)} '⌾', {𝕎⁼⌾𝕏} # Need to verify for computational Under '⍟', Int∘⊢◶⟨IA∘0˙,{𝕎⍟(-𝕩)}⟩ '⊘', {(𝕎⁼)⊘(𝕏⁼)} '⊸', IsConstant∘⊣ ⊣◶{INF⊘𝕏}‿⊢ {𝕎⊸(𝕏⁼)} '⟜', {(𝕨IsConstant∘⊢◶⟨IA∘0˙,{𝕩𝕎{SwapInverse𝕗}⊢}⟩𝕩)⊘(𝕏⁼𝕎⁼)} ⟩ ´ ↩ _fold ˝ ← _insert ⁼ ↩ {i←Inverse𝕗⋄𝕨I𝕩} ˘ ← _cells ⊑ ↩ First ⊘ Pick ◶ ↩ {𝕨((𝕨𝔽𝕩)⊑𝕘){𝔽}𝕩} # Same definition, new Pick ⚇ ← _depthOp_ ⎉ ← _rankOp_ ⥊ ↩ Deshape ⊘ Reshape ≍ ← >∘⋈ _fillBy_ (⊢⊘IF) ⋈ ↩ {𝕩Fill⟨𝕩⟩} ⊘ (⋈○⊑ _fillBy_ IF○<) ⊔ ← GroupInds ⊘ GroupGen ⍉ ← Transpose ⊘ ReorderAxes ∊ ← ⊢_self ⊘ (0 _search˜) ⍷ ← ∊⊸/ ⊘ Find ⊒ ← OccurrenceCount⊘ ProgressiveIndexOf / ↩ Indices ⊘ Replicate