Frame agreement: Difference between revisions

Jump to navigation Jump to search
1,764 bytes added ,  14:23, 26 August 2023
m
m (Introduction rewording, and formatting fixes)
 
(14 intermediate revisions by the same user not shown)
Line 1: Line 1:
'''Frame agreement''' is a [[conformability]] rule designed for [[leading axis theory]] and used by [[J]]. It states that a [[dyadic]] [[function]] can be applied between two [[array]]s only if one of their [[frame]]s, with frame length based on the function's dyadic [[function rank]], is a [[prefix]] of the other. The leading shape of the result is that of the [[argument]] with longer frame.
'''Frame agreement''' is a [[conformability]] rule which describes the conditions that must be satisfied by the [[frame]]s of [[arguments]] to [[dyadic]] [[function]]s with rank (either [[Rank operator|derived]] and/or, when supported, [[function rank|native]]). The [[frame]]s must either be identical, or one must be [[empty]], or, more generally, when supported, one frame must be a [[prefix]] of the other.


== Description ==
== Empty frame agreement ==
A dyadic function <syntaxhighlight lang=j inline>f</syntaxhighlight> with left and right ranks <syntaxhighlight lang=j inline>lr</syntaxhighlight> and <syntaxhighlight lang=j inline>rr</syntaxhighlight>, respectively, splits its left argument <syntaxhighlight lang=j inline>x</syntaxhighlight> into <syntaxhighlight lang=j inline>lf</syntaxhighlight>-[[cell]]s, and splits its right argument <syntaxhighlight lang=j inline>y</syntaxhighlight> into <syntaxhighlight lang=j inline>rf</syntaxhighlight>-cells. Each argument's shape is thus split into a frame and a cell shape. Given that one frame must be a prefix of the other, the prefix (i.e. shorter) frame is called the common frame (denoted here as <syntaxhighlight lang=j inline>cf</syntaxhighlight>), and the suffix of the longer frame relative to the common frame is called the surplus frame (denoted here as <syntaxhighlight lang=j inline>sf</syntaxhighlight>. "Cells" will be used here to denote the <syntaxhighlight lang=j inline>lr</syntaxhighlight>-cells (for the left argument <syntaxhighlight lang=j inline>a</syntaxhighlight>) or the <syntaxhighlight lang=j inline>rr</syntaxhighlight>-cells (for the right argument <syntaxhighlight lang=j inline>b</syntaxhighlight>). If the frames are identical, each cell of <syntaxhighlight lang=j inline>x</syntaxhighlight> is paired with the corresponding cell of <syntaxhighlight lang=j inline>y</syntaxhighlight> in a 1-to-1 pairing. For the case in which the frame lengths differ, we'll denote the shorter-framed argument as <syntaxhighlight lang=j inline>sa</syntaxhighlight> and the longer-framed argument as <syntaxhighlight lang=j inline>la</syntaxhighlight>. Each cell of <syntaxhighlight lang=j inline>sa</syntaxhighlight> is paired with each among the corresponding group of <syntaxhighlight lang=j inline>*/sf</syntaxhighlight> cells of <syntaxhighlight lang=j inline>la</syntaxhighlight>. The collective results among all applications of <syntaxhighlight lang=j inline>f</syntaxhighlight> are framed by the longer frame <syntaxhighlight lang=j inline>lf</syntaxhighlight>.
In [[SHARP APL]] and [[Dyalog]], frames agree only if they [[match]], or if one frame is empty. The latter case corresponds to pairing one argument in its entirety with each of the [[cells]] of the other argument.
=== Examples ===
<syntaxhighlight lang=apl>
      x←⍳2
      y←2 3 2⍴⍳12
      x{⍺⍵}⍤99 2⊢y      ⍝ 1-to-n pairing; ⍤99 corresponds to empty frame
┌───┬─────┐
│1 2│1 2  │
│  │3 4  │
│  │5 6  │
├───┼─────┤
│1 2│ 7  8│
│  │ 9 10│
│  │11 12│
└───┴─────┘
      x{⍺⍵}⍤0 2⊢y      ⍝ 1-to-1 pairing; frames match; (,2) ≡ (,2)
┌─┬─────┐
│1│1 2  │
│ │3 4  │
│ │5 6  │
├─┼─────┤
│2│ 7  8│
│ │ 9 10│
│ │11 12│
└─┴─────┘
</syntaxhighlight>
{{Works in|[[Dyalog APL]]}}
 
== Frame prefix agreement ==
In [[A+]], [[BQN]], and [[J]], frames agree if one is a prefix of the other. In J, because every function has associated [[function rank|ranks]], frame agreement generalizes [[leading axis agreement]].
 
=== Description ===
A dyadic function with left and right ranks l and r splits its left argument into l-cells, and splits its right argument into r-cells. Each argument's [[shape]] is thus split into a frame and a cell shape. Given that one frame must be a prefix of the other, the shorter frame is called the common frame, which may be empty. Here, the generic term "cells" will denote the l-cells (for the left argument) or r-cells (for the right argument). If the frames are identical, the cells are paired 1-to-1 between the arguments. If the frame lengths differ, each cell of the shorter-framed argument is paired with each among the corresponding group of cells of the longer-framed argument. This 1-to-n pairing can be viewed as extending the shorter frame to match the longer frame. The collective results of the individual applications of the function are framed by the longer frame.
 
=== Examples ===


== Examples ==
<syntaxhighlight lang=j>
<syntaxhighlight lang=j>
   a=: 3 4
   x=: i.2
   b=: i.2 3 2
   y=: i.2 3 2
   'lr rr'=: }.+"0 1 b.0          NB. let lv and rv denote the left and right ranks of the verb +"0 1
   x+"0 1 y
  lr;rr
0 1
┌─┬─┐
2 3
│0│1│
  4  5
└─┴─┘
 
  ]af=: (-lr)}.$a                NB. a's frame
2
  ]bf=: (-rr)}.$b                NB. b's frame
2 3
  af =/@(<.&# {.&> ;) bf          NB. one frame prefixes the other
1
  ]cf=: af {.@(<.&#{.&>;~) bf    NB. the common frame (always the shorter of the two frames)
2
  ]lf=: af >@(-.@>&# { ;) bf      NB. the longer of the two frames
2 3
  ]sf=: lf }.~ #cf                NB. the surplus frame results from removing the common frame from the left side of longer frame
3
  a +"0 1]b
3 4
  5 6
  7  8
  7  8
9 10
11 12
</syntaxhighlight>
{{Works in|[[J]]}}


10 11
The table below shows the pairing of cells from the above example. Here, the notation <syntaxhighlight lang=apl inline>[cell shape]</syntaxhighlight> denotes the cell shape, and <syntaxhighlight lang=apl inline>|</syntaxhighlight> denotes the division between the common frame and the remaining trailing axes.
12 13
 
14 15
{|class=wikitable
  'A B'=: (<"lr]a),&<(<"rr]b)    NB. frame each argument in terms of lr- or rr-cells
! Argument          !!        Step 1: Frames / Cells          !! Step 2: Common frame—cells paired
  A                              NB. a framed as lr-cells
|-
┌─┬─┐
| <syntaxhighlight lang=apl inline>x</syntaxhighlight>    || <syntaxhighlight lang=apl inline>2 []</syntaxhighlight>                    || <syntaxhighlight lang=apl inline>2|[]</syntaxhighlight>
│3│4│
|-
└─┴─┘
| <syntaxhighlight lang=apl inline>y</syntaxhighlight>    || <syntaxhighlight lang=apl inline>2 3 [2]</syntaxhighlight>                  || <syntaxhighlight lang=apl inline>2|3 [2]</syntaxhighlight>
  $A
|}
 
The same example, but without considering cell shape:
{|class=wikitable
! Argument          !!        Step 1: Frame / Cells          !! Step 2: Common frame
|-
| <syntaxhighlight lang=apl inline>x</syntaxhighlight>    || <syntaxhighlight lang=apl inline>2 C</syntaxhighlight>                    || <syntaxhighlight lang=apl inline>2|C</syntaxhighlight>
|-
| <syntaxhighlight lang=apl inline>y</syntaxhighlight>    || <syntaxhighlight lang=apl inline>2 3 C</syntaxhighlight>                  || <syntaxhighlight lang=apl inline>2|3 C</syntaxhighlight>
|}
 
Based on the ranks <syntaxhighlight lang=apl inline>0 1</syntaxhighlight> of the given function, <syntaxhighlight lang=apl inline>x</syntaxhighlight>'s frame is <syntaxhighlight lang=apl inline>,2</syntaxhighlight> and its cell shape is empty; y's frame is <syntaxhighlight lang=apl inline>2 3</syntaxhighlight> and its cell shape is <syntaxhighlight lang=apl inline>,2</syntaxhighlight>. The shorter of the frames, and thus the common frame, is <syntaxhighlight lang=apl inline>,2</syntaxhighlight>. Relative to the common frame, each atom of <syntaxhighlight lang=apl inline>x</syntaxhighlight> is paired with the corresponding 3 vectors of <syntaxhighlight lang=apl inline>y</syntaxhighlight>.
 
The expanded example below uses APL to model frame prefix agreement.
 
<syntaxhighlight lang=apl>
      ⎕IO←0                      ⍝ for comparison with J example
      x←⍳2
      y←2 3 2⍴⍳12
      l r←0 1                    ⍝ the left and right ranks of the function +⍤0 1
      ⊢lf rf←(-l r)↓¨x,⍥(⊂∘⍴)y  ⍝ frames
┌─┬───┐
│2│2 3│
└─┴───┘
      ⊢cf←lf{⍺<⍥≢⍵:⍺ ⋄ ⍵}rf      ⍝ common (i.e. shorter) frame
2
2
  B                              NB. b framed as rr-cells
      x{⍺⍵}⍤(-≢cf)⊢y            ⍝ 1st step: the (-≢cf)-cells are paired 1-to-1 between x and y
┌───┬───┬─────┐
┌─┬─────┐
│0 1│2 3│4 5  │
│0│0 1  │
├───┼───┼─────┤
│ │2 3  │
│6 7│8 9│10 11│
│ │4 5  │
└───┴───┴─────┘
├─┼─────┤
  $B
│1│ 6  7│
2 3
│ │ 8  9│
  ]pairs=: A([;'+';])&>_1]B      NB. each cell of sa is paired with each cell among the corresponding group of (*/sf) cells of la
│ │10 11│
┌─┬─┬─────┐
└─┴─────┘
│3│+│0 1  │
      x{⍺⍵}⍤l r⍤(-≢cf)⊢y        ⍝ 2nd step: the (-≢cf)-cells in each pairing are split into l- and r-cells, and these are paired 1-to-n (or 1-to-1 if the frames are identical)
├─┼─┼─────┤
┌─┬─────┐
│3│+│2 3  │
│0│0 1  │
├─┼─┼─────┤
├─┼─────┤
│3│+│4 5  │
│0│2 3  │
└─┴─┴─────┘
├─┼─────┤
│0│4 5  │
└─┴─────┘
┌─┬─────┐
│1│6 7  │
├─┼─────┤
│1│8 9  │
├─┼─────┤
│1│10 11│
└─┴─────┘
      x+⍤0 1⊢y                  ⍝ n-to-m pairing; invalid in APL
RANK ERROR
      x+⍤l r⍤(-≢cf)⊢y            ⍝ matches the result of J's frame agreement
0  1
2  3
4  5


┌─┬─┬─────┐
│4│+│6 7  │
├─┼─┼─────┤
│4│+│8 9  │
├─┼─┼─────┤
│4│+│10 11│
└─┴─┴─────┘
  A+&>"_1]B                      NB. the results of all applications of + are framed by lf
3  4
5  6
  7  8
  7  8
9 10
11 12
</syntaxhighlight>
{{Works in|[[Dyalog APL]]}}


10 11
=== Model ===
12 13
In dialects that do not feature frame prefix agreement, it can nevertheless be utilised by the introduction of an explicit operator:
14 15
  pairs -: a ([;'+';])"_1"(-#cf)]b
1
</syntaxhighlight>
{{Works in|[[J]]}}


In the example above, based on the ranks <syntaxhighlight lang=j inline>0 1</syntaxhighlight> of the verb <syntaxhighlight lang=j inline>+"0 1</syntaxhighlight>, <syntaxhighlight lang=j inline>a</syntaxhighlight>'s frame is <syntaxhighlight lang=j inline>,2</syntaxhighlight> and its cell shape is [[empty array|empty]] (<syntaxhighlight lang=j inline>0$0</syntaxhighlight>); b's frame is <syntaxhighlight lang=j inline>2 3</syntaxhighlight> and its cell shape is <syntaxhighlight lang=j inline>,2</syntaxhighlight>. The shorter of these, and thus the common frame, is <syntaxhighlight lang=j inline>,2</syntaxhighlight>, so each of the two <syntaxhighlight lang=j inline>0$0</syntaxhighlight>-shaped cells (atoms) of <syntaxhighlight lang=j inline>a</syntaxhighlight> is paired with each of the corresponding <syntaxhighlight lang=j inline>6</syntaxhighlight> (i.e. <syntaxhighlight lang=j inline>*/sf</syntaxhighlight>) corresponding <syntaxhighlight lang=j inline>b</syntaxhighlight> cells.
<syntaxhighlight lang=apl>
      _FA_←{
          assert←{0≡⍵:'error: no common frame prefix' ⎕SIGNAL 4 ⋄ ⍵}
          r←1↓⌽3⍴⌽⍵⍵ ⋄ ar←≢¨p←⍴¨⍺⍵      ⍝ dyadic ranks, array ranks, shapes
          c←r{⍺>0:⍺⌊⍵ ⋄ 0⌈⍺+⍵}¨ar      ⍝ cell ranks
          fl fr←(-c)↓¨p                ⍝ left and right frames                     
          s←fl{⍺<⍥≢⍵:⍺ ⋄ ⍵}fr          ⍝ shorter frame
          k←{⍬≡⍵:99 ⋄ -≢⍵}s            ⍝ relative rank
          assert ⍺∧⍥(s≡(≢s)↑⍴)⍵:        ⍝ do frames agree?
          ⍺ ⍺⍺⍤c⍤k⊢⍵
      }
      x+_FA_ 0 1⊢y
0  1
2  3
4  5


7  8
9 10
11 12
</syntaxhighlight>
{{Works in|[[Dyalog APL]]}}
[[Category:Leading axis theory]][[Category:Function characteristics]][[Category:Conformability]]{{APL features}}
[[Category:Leading axis theory]][[Category:Function characteristics]][[Category:Conformability]]{{APL features}}
trusted
83

edits

Navigation menu