Frame agreement: Difference between revisions
Jump to navigation
Jump to search
m (→Examples) |
(Reorganize page to cover general frame conformance; add model for prefix agreement.) |
||
Line 1: | Line 1: | ||
'''Frame agreement''' is a [[conformability]] rule | '''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. | ||
== | == Empty frame agreement == | ||
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]]}} | |||
== Examples == | == 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 === | |||
<syntaxhighlight lang=j> | <syntaxhighlight lang=j> | ||
Line 20: | Line 52: | ||
{{Works in|[[J]]}} | {{Works in|[[J]]}} | ||
The table below shows the pairing of cells from the above example. Here the notation <syntaxhighlight lang=apl inline>[shape]</syntaxhighlight> denotes the cell shape, and <syntaxhighlight lang=apl inline>|</syntaxhighlight> denotes the division between the common frame and the remaining trailing axes. | 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. | ||
{|class=wikitable | {|class=wikitable | ||
Line 39: | Line 71: | ||
|} | |} | ||
Based on the ranks <syntaxhighlight lang=apl inline> | 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. | |||
The expanded example below uses APL to model frame agreement. | |||
<syntaxhighlight lang=apl> | <syntaxhighlight lang=apl> | ||
⎕IO←0 ⍝ for comparison with J example | |||
x←⍳2 | x←⍳2 | ||
y←2 3 2⍴⍳12 | y←2 3 2⍴⍳12 | ||
Line 52: | Line 84: | ||
│2│2 3│ | │2│2 3│ | ||
└─┴───┘ | └─┴───┘ | ||
⊢cf←lf{⍺<⍥≢⍵:⍺ ⋄ ⍵}rf ⍝ common (shorter) frame | ⊢cf←lf{⍺<⍥≢⍵:⍺ ⋄ ⍵}rf ⍝ common (i.e. shorter) frame | ||
2 | 2 | ||
x{⍺⍵}⍤(-≢cf)⊢y ⍝ 1st step: the (-≢cf)-cells are paired 1-to-1 between x and y | x{⍺⍵}⍤(-≢cf)⊢y ⍝ 1st step: the (-≢cf)-cells are paired 1-to-1 between x and y | ||
Line 82: | Line 114: | ||
RANK ERROR | RANK ERROR | ||
x+⍤l r⍤(-≢cf)⊢y ⍝ matches the result of J's frame agreement | x+⍤l r⍤(-≢cf)⊢y ⍝ matches the result of J's frame agreement | ||
0 1 | |||
2 3 | |||
4 5 | |||
7 8 | |||
9 10 | |||
11 12 | |||
</syntaxhighlight> | |||
{{Works in|[[Dyalog APL]]}} | |||
=== Model === | |||
In dialects that do not feature frame prefix agreement, it can nevertheless be utilised by the introduction of an explicit operator: | |||
<syntaxhighlight lang=apl> | |||
_FA_←{ | |||
assert←{0≡⍵:'RANK ERROR: one frame must be a prefix of the other' ⎕SIGNAL 4 ⋄ ⍵} | |||
r←(1↓⌽3⍴⌽⍵⍵)⌊≢∘⍴¨⍺⍵ ⍝ dyadic ranks | |||
lf rf←(-r)↓∘⍴¨⍺⍵ ⍝ frames | |||
cf←lf{⍺<⍥≢⍵:⍺ ⋄ ⍵}rf ⍝ common frame, assuming frames agree | |||
k←{⍬≡⍵:99 ⋄ -≢⍵}cf ⍝ relative rank | |||
assert ⍺∧⍥(cf≡(≢cf)↑⍴)⍵: ⍝ verify that frames agree | |||
⍺ ⍺⍺⍤⍵⍵⍤k⊢⍵ | |||
} | |||
x+_FA_ 0 1⊢y | |||
0 1 | 0 1 | ||
2 3 | 2 3 |