aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/primitive.md2
-rw-r--r--doc/rank.md53
-rw-r--r--docs/doc/primitive.html2
-rw-r--r--docs/doc/rank.html81
-rw-r--r--docs/help/cells.html1
-rw-r--r--docs/help/rank.html1
-rw-r--r--help/cells.md1
-rw-r--r--help/rank.md1
8 files changed, 134 insertions, 8 deletions
diff --git a/doc/primitive.md b/doc/primitive.md
index 2cc034de..afa5a7f7 100644
--- a/doc/primitive.md
+++ b/doc/primitive.md
@@ -83,7 +83,7 @@ Other modifiers control array traversal and iteration. In three cases a simpler
| 1-Modifier | Name | 2-Modifier | Name
|------------|---------------------------------------|------------|--------
-| `˘` | [Cells](rank.md) | `⎉` | [Rank](https://aplwiki.com/wiki/Rank_(operator))
+| `˘` | [Cells](rank.md) | `⎉` | [Rank](rank.md#rank)
| `¨` | [Each](map.md) | `⚇` | [Depth](depth.md#the-depth-modifier)
| `⌜` | [Table](map.md) |
| `⁼` | [Undo](undo.md) | `⍟` | [Repeat](repeat.md)
diff --git a/doc/rank.md b/doc/rank.md
index 0aa78bfa..fdf46637 100644
--- a/doc/rank.md
+++ b/doc/rank.md
@@ -16,9 +16,9 @@ The function `𝔽˘` applies `𝔽` to the major cells of `𝕩`. So, for examp
⟨ a , »a , »˘a ⟩
-What's it mean for Nudge to shift the "entire table"? The block above shows that is shifts downward, but what's really happening is that Nudge treats `𝕩` as a collection of major cells—its rows—and shifts these. So it adds an entire row and moves the rest of the rows downwards. Nudge Cells appears similar, but it's acting independently on each row, and the values that it moves around are major cells of the row, that is, rank-0 units.
+What's it mean for Nudge to shift the "entire table"? The block above shows that it shifts downward, but what's really happening is that Nudge treats `𝕩` as a collection of major cells—its rows—and shifts these. So it adds an entire row and moves the rest of the rows downwards. Nudge Cells appears similar, but it's acting independently on each row, and the values that it moves around are major cells of the row, that is, rank-0 units.
-Here's an example showing how Cells can be used to shift each row independently, even though it's not possible to shift columns like this (in fact the best way to would be to [transpose](transpose.md) in order to work on rows). It uses the not-yet-introduced dyadic form of Cells, so you might want to come back to it after reading the next section.
+Here's an example showing how Cells can be used to shift each row independently, even though it's not possible to shift columns like this (in fact the best way to do that would be to [transpose](transpose.md) in order to work on rows). It uses the not-yet-introduced dyadic form of Cells, so you might want to come back to it after reading the next section.
(↑"∘∘") ⊑⊸»˘ a
@@ -38,7 +38,7 @@ This approach can apply to more complicated functions as well. And because the r
### Two arguments
-When given two arguments, Cells tries to pair their cells together. Starting simple, a unit array on either side will be paired with every cell of the other argument (and an atom is converted to an array).
+When given two arguments, Cells tries to pair their cells together. Starting simple, a unit (whether array or atom) on either side will be paired with every cell of the other argument.
'∘' »˘ a
@@ -55,3 +55,50 @@ This is because the general case of Cells does one-to-one matching, pairing the
The arguments might have different ranks: for example, `"012"` has rank 1 and `a` has rank 2 above. That's fine: it just means Cells will pass arguments of rank 0 and 1 to its operand. You can see these arguments using [Pair](pair.md) Cells, `⋈˘`, so that each cell of the result is just a list of the two arguments used for that call.
"012" ⋈˘ a
+
+## Rank
+
+Rank (`⎉`) is a generalization of Cells (`𝔽˘` is defined to be `𝔽⎉¯1`) that can apply to arbitrary—not just major—cells and combine different levels of mapping for two arguments.
+
+Rank comes in handy when there are high-rank arrays with lots of exciting axes, which is a great use case for BQN but honestly isn't all that common. And to continue this trend of honesty, using Rank just never *feels* good—it's some heavy machinery that I drag out when nothing else works, only to make use of a small part of the functionality. If Cells covers your use cases, that's probably for the best!
+
+### Negative and positive ranks
+
+I've said that `𝔽⎉¯1` is `𝔽˘`. And it's also the case that `𝔽⎉¯2` is `𝔽˘˘`. And `𝔽⎉¯3` is `𝔽˘˘˘`. And so on.
+
+ (↕4) (⋈˘˘˘ ≡ ⋈⎉¯3) ↕4‿2‿2‿5
+
+So `𝔽⎉(-k)`, at least for `k≥1`, is how you map over the first `k` axes of an array or two. We'll get more into why this is in the next section. What about some positivity for a change?
+
+ <⎉0 "abc"≍"def"
+
+ <⎉1 "abc"≍"def"
+
+The function `𝔽⎉k`, for `k≥0`, operates on the `k`-cells of its arguments—that is, it maps over all *but* the last `k` axes. For any given argument `a`, ranks `k` and `k-=a` are the same, as long as `k≥0` and `(k-=a)≤¯1`. So rank 2 is rank ¯3 for a rank-5 array. The reason this option is useful is that the same rank might be applied to multiple arguments, either with multiple function calls or one call on two arguments. Let's revisit an example with Cells from before, shifting the same string into each row of a table. The function `»` should be called on rank-1 strings, but because the argument ranks are different, a negative rank can't get down to rank 1 on both sides. Positive rank 1 does the job, allowing us to unbundle the string `"∘∘"` so that `»⎉1` is a standalone function.
+
+ "∘∘"⊸»˘ a
+
+ "∘∘" »⎉1 a
+
+The rank for a given argument is clamped, so that on a rank 3 argument for example, a rank of ¯5 counts as ¯3 and a rank of 6 counts as 3 (same for any other value less than ¯3 or greater than 3, although it does have to be a whole number). You may have noticed there's [no](../commentary/problems.md#rankdepth-negative-zero) option for ¯0, "don't map over anything", but ∞ serves that purpose as it indicates the highest possible rank and thus the entire array. More on why that's useful later.
+
+### Frame and Cells
+
+### Multiple and computed ranks
+
+The Rank modifier also accepts a list of one to three numbers for `𝕘`, as well as a function `𝔾` returning such a list. Practically speaking, here's what you need to know:
+
+- A single number or one-element list indicates the ranks for all arguments.
+- Two numbers indicate the ranks for `𝕨` and `𝕩`.
+
+ ⊢ m ← >⟨0‿1‿0,¯1‿0‿0,0‿0‿1⟩
+
+ m +˝∘×⎉1‿∞ 1‿2‿3
+
+ m +˝∘×⎉1‿∞ 1‿2‿3×⌜1‿10
+
+ ("abc"≍"def") ∾⎉1⎉1‿∞ >"QR"‿"ST"‿"UV"
+
+Here's the full, boring description of how `𝔾` is handled. The operand `𝔾` is called on the arguments `𝕨𝔾𝕩` before doing anything else (if it's not a function, this just returns `𝕘`). Then it's converted to a list. It's required to have rank 0 or 1, but numbers and enclosed numbers are fine. This list can have one to three elements; three elements is the general case, as the elements give the ranks for monadic `𝕩`, dyadic `𝕨`, and dyadic `𝕩` in order. If there are less than three elements, the list `r` is expanded backwards-cyclically to `3⊸⥊⌾⌽r`, turning `⟨a⟩` into `a‿a‿a` and `a‿b` into `b‿a‿b`. So `3⊸⥊⌾⌽⥊𝕨𝔾𝕩` is the final formula.
+
+### Leading axis agreement
diff --git a/docs/doc/primitive.html b/docs/doc/primitive.html
index 157c05bc..7e32c91e 100644
--- a/docs/doc/primitive.html
+++ b/docs/doc/primitive.html
@@ -495,7 +495,7 @@
<td><code><span class='Modifier'>˘</span></code></td>
<td><a href="rank.html">Cells</a></td>
<td><code><span class='Modifier2'>⎉</span></code></td>
-<td><a href="https://aplwiki.com/wiki/Rank_(operator)">Rank</a></td>
+<td><a href="rank.html#rank">Rank</a></td>
</tr>
<tr>
<td><code><span class='Modifier'>¨</span></code></td>
diff --git a/docs/doc/rank.html b/docs/doc/rank.html
index fd618d93..aef2edcd 100644
--- a/docs/doc/rank.html
+++ b/docs/doc/rank.html
@@ -21,8 +21,8 @@
┘ ┘ ┘
</pre>
-<p>What's it mean for Nudge to shift the &quot;entire table&quot;? The block above shows that is shifts downward, but what's really happening is that Nudge treats <code><span class='Value'>𝕩</span></code> as a collection of major cells—its rows—and shifts these. So it adds an entire row and moves the rest of the rows downwards. Nudge Cells appears similar, but it's acting independently on each row, and the values that it moves around are major cells of the row, that is, rank-0 units.</p>
-<p>Here's an example showing how Cells can be used to shift each row independently, even though it's not possible to shift columns like this (in fact the best way to would be to <a href="transpose.html">transpose</a> in order to work on rows). It uses the not-yet-introduced dyadic form of Cells, so you might want to come back to it after reading the next section.</p>
+<p>What's it mean for Nudge to shift the &quot;entire table&quot;? The block above shows that it shifts downward, but what's really happening is that Nudge treats <code><span class='Value'>𝕩</span></code> as a collection of major cells—its rows—and shifts these. So it adds an entire row and moves the rest of the rows downwards. Nudge Cells appears similar, but it's acting independently on each row, and the values that it moves around are major cells of the row, that is, rank-0 units.</p>
+<p>Here's an example showing how Cells can be used to shift each row independently, even though it's not possible to shift columns like this (in fact the best way to do that would be to <a href="transpose.html">transpose</a> in order to work on rows). It uses the not-yet-introduced dyadic form of Cells, so you might want to come back to it after reading the next section.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=KOKGkSLiiJjiiJgiKSDiipHiirjCu8uYIGE=">↗️</a><pre> <span class='Paren'>(</span><span class='Function'>↑</span><span class='String'>&quot;∘∘&quot;</span><span class='Paren'>)</span> <span class='Function'>⊑</span><span class='Modifier2'>⊸</span><span class='Function'>»</span><span class='Modifier'>˘</span> <span class='Value'>a</span>
┌─
╵"abcdefgh
@@ -49,7 +49,7 @@
</pre>
<p>This approach can apply to more complicated functions as well. And because the result of <code><span class='Function'>&lt;</span></code> always has the same shape, <code><span class='Bracket'>⟨⟩</span></code>, the function <code><span class='Function'>&lt;</span><span class='Modifier2'>∘</span><span class='Function'>𝔽</span><span class='Modifier'>˘</span></code> can never have a shape agreement error. So if <code><span class='Function'>𝔽</span><span class='Modifier'>˘</span></code> fails, it can't hurt to check <code><span class='Function'>&lt;</span><span class='Modifier2'>∘</span><span class='Function'>𝔽</span><span class='Modifier'>˘</span></code> and see what results <code><span class='Function'>𝔽</span></code> is returning.</p>
<h3 id="two-arguments"><a class="header" href="#two-arguments">Two arguments</a></h3>
-<p>When given two arguments, Cells tries to pair their cells together. Starting simple, a unit array on either side will be paired with every cell of the other argument (and an atom is converted to an array).</p>
+<p>When given two arguments, Cells tries to pair their cells together. Starting simple, a unit (whether array or atom) on either side will be paired with every cell of the other argument.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=J+KImCcgwrvLmCBh">↗️</a><pre> <span class='String'>'∘'</span> <span class='Function'>»</span><span class='Modifier'>˘</span> <span class='Value'>a</span>
┌─
╵"∘abcdefg
@@ -92,3 +92,78 @@
</pre>
+<h2 id="rank"><a class="header" href="#rank">Rank</a></h2>
+<p>Rank (<code><span class='Modifier2'>⎉</span></code>) is a generalization of Cells (<code><span class='Function'>𝔽</span><span class='Modifier'>˘</span></code> is defined to be <code><span class='Function'>𝔽</span><span class='Modifier2'>⎉</span><span class='Number'>¯1</span></code>) that can apply to arbitrary—not just major—cells and combine different levels of mapping for two arguments.</p>
+<p>Rank comes in handy when there are high-rank arrays with lots of exciting axes, which is a great use case for BQN but honestly isn't all that common. And to continue this trend of honesty, using Rank just never <em>feels</em> good—it's some heavy machinery that I drag out when nothing else works, only to make use of a small part of the functionality. If Cells covers your use cases, that's probably for the best!</p>
+<h3 id="negative-and-positive-ranks"><a class="header" href="#negative-and-positive-ranks">Negative and positive ranks</a></h3>
+<p>I've said that <code><span class='Function'>𝔽</span><span class='Modifier2'>⎉</span><span class='Number'>¯1</span></code> is <code><span class='Function'>𝔽</span><span class='Modifier'>˘</span></code>. And it's also the case that <code><span class='Function'>𝔽</span><span class='Modifier2'>⎉</span><span class='Number'>¯2</span></code> is <code><span class='Function'>𝔽</span><span class='Modifier'>˘˘</span></code>. And <code><span class='Function'>𝔽</span><span class='Modifier2'>⎉</span><span class='Number'>¯3</span></code> is <code><span class='Function'>𝔽</span><span class='Modifier'>˘˘˘</span></code>. And so on.</p>
+<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=KOKGlTQpICjii4jLmMuYy5gg4omhIOKLiOKOicKvMykg4oaVNOKAvzLigL8y4oC/NQ==">↗️</a><pre> <span class='Paren'>(</span><span class='Function'>↕</span><span class='Number'>4</span><span class='Paren'>)</span> <span class='Paren'>(</span><span class='Function'>⋈</span><span class='Modifier'>˘˘˘</span> <span class='Function'>≡</span> <span class='Function'>⋈</span><span class='Modifier2'>⎉</span><span class='Number'>¯3</span><span class='Paren'>)</span> <span class='Function'>↕</span><span class='Number'>4</span><span class='Ligature'>‿</span><span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>5</span>
+1
+</pre>
+<p>So <code><span class='Function'>𝔽</span><span class='Modifier2'>⎉</span><span class='Paren'>(</span><span class='Function'>-</span><span class='Value'>k</span><span class='Paren'>)</span></code>, at least for <code><span class='Value'>k</span><span class='Function'>≥</span><span class='Number'>1</span></code>, is how you map over the first <code><span class='Value'>k</span></code> axes of an array or two. We'll get more into why this is in the next section. What about some positivity for a change?</p>
+<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=POKOiTAgImFiYyLiiY0iZGVmIgoKPOKOiTEgImFiYyLiiY0iZGVmIg==">↗️</a><pre> <span class='Function'>&lt;</span><span class='Modifier2'>⎉</span><span class='Number'>0</span> <span class='String'>&quot;abc&quot;</span><span class='Function'>≍</span><span class='String'>&quot;def&quot;</span>
+┌─
+╵ ┌· ┌· ┌·
+ ·'a' ·'b' ·'c'
+ ┘ ┘ ┘
+ ┌· ┌· ┌·
+ ·'d' ·'e' ·'f'
+ ┘ ┘ ┘
+ ┘
+
+ <span class='Function'>&lt;</span><span class='Modifier2'>⎉</span><span class='Number'>1</span> <span class='String'>&quot;abc&quot;</span><span class='Function'>≍</span><span class='String'>&quot;def&quot;</span>
+⟨ "abc" "def" ⟩
+</pre>
+<p>The function <code><span class='Function'>𝔽</span><span class='Modifier2'>⎉</span><span class='Value'>k</span></code>, for <code><span class='Value'>k</span><span class='Function'>≥</span><span class='Number'>0</span></code>, operates on the <code><span class='Value'>k</span></code>-cells of its arguments—that is, it maps over all <em>but</em> the last <code><span class='Value'>k</span></code> axes. For any given argument <code><span class='Value'>a</span></code>, ranks <code><span class='Value'>k</span></code> and <code><span class='Value'>k</span><span class='Function'>-=</span><span class='Value'>a</span></code> are the same, as long as <code><span class='Value'>k</span><span class='Function'>≥</span><span class='Number'>0</span></code> and <code><span class='Paren'>(</span><span class='Value'>k</span><span class='Function'>-=</span><span class='Value'>a</span><span class='Paren'>)</span><span class='Function'>≤</span><span class='Number'>¯1</span></code>. So rank 2 is rank ¯3 for a rank-5 array. The reason this option is useful is that the same rank might be applied to multiple arguments, either with multiple function calls or one call on two arguments. Let's revisit an example with Cells from before, shifting the same string into each row of a table. The function <code><span class='Function'>»</span></code> should be called on rank-1 strings, but because the argument ranks are different, a negative rank can't get down to rank 1 on both sides. Positive rank 1 does the job, allowing us to unbundle the string <code><span class='String'>&quot;∘∘&quot;</span></code> so that <code><span class='Function'>»</span><span class='Modifier2'>⎉</span><span class='Number'>1</span></code> is a standalone function.</p>
+<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=IuKImOKImCLiirjCu8uYIGEKCiLiiJjiiJgiIMK74o6JMSBh">↗️</a><pre> <span class='String'>&quot;∘∘&quot;</span><span class='Modifier2'>⊸</span><span class='Function'>»</span><span class='Modifier'>˘</span> <span class='Value'>a</span>
+┌─
+╵"∘∘abcdef
+ ∘∘ijklmn
+ ∘∘qrstuv"
+ ┘
+
+ <span class='String'>&quot;∘∘&quot;</span> <span class='Function'>»</span><span class='Modifier2'>⎉</span><span class='Number'>1</span> <span class='Value'>a</span>
+┌─
+╵"∘∘abcdef
+ ∘∘ijklmn
+ ∘∘qrstuv"
+ ┘
+</pre>
+<p>The rank for a given argument is clamped, so that on a rank 3 argument for example, a rank of ¯5 counts as ¯3 and a rank of 6 counts as 3 (same for any other value less than ¯3 or greater than 3, although it does have to be a whole number). You may have noticed there's <a href="../commentary/problems.html#rankdepth-negative-zero">no</a> option for ¯0, &quot;don't map over anything&quot;, but ∞ serves that purpose as it indicates the highest possible rank and thus the entire array. More on why that's useful later.</p>
+<h3 id="frame-and-cells"><a class="header" href="#frame-and-cells">Frame and Cells</a></h3>
+<h3 id="multiple-and-computed-ranks"><a class="header" href="#multiple-and-computed-ranks">Multiple and computed ranks</a></h3>
+<p>The Rank modifier also accepts a list of one to three numbers for <code><span class='Value'>𝕘</span></code>, as well as a function <code><span class='Function'>𝔾</span></code> returning such a list. Practically speaking, here's what you need to know:</p>
+<ul>
+<li>A single number or one-element list indicates the ranks for all arguments.</li>
+<li>Two numbers indicate the ranks for <code><span class='Value'>𝕨</span></code> and <code><span class='Value'>𝕩</span></code>.</li>
+</ul>
+<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oqiIG0g4oaQID7in6gw4oC/MeKAvzAswq8x4oC/MOKAvzAsMOKAvzDigL8x4p+pCgptICvLneKImMOX4o6JMeKAv+KIniAx4oC/MuKAvzMKCm0gK8ud4oiYw5fijokx4oC/4oieIDHigL8y4oC/M8OX4oycMeKAvzEwCgooImFiYyLiiY0iZGVmIikg4oi+4o6JMeKOiTHigL/iiJ4gPiJRUiLigL8iU1Qi4oC/IlVWIg==">↗️</a><pre> <span class='Function'>⊢</span> <span class='Value'>m</span> <span class='Gets'>←</span> <span class='Function'>&gt;</span><span class='Bracket'>⟨</span><span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>0</span><span class='Separator'>,</span><span class='Number'>¯1</span><span class='Ligature'>‿</span><span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>0</span><span class='Separator'>,</span><span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>1</span><span class='Bracket'>⟩</span>
+┌─
+╵ 0 1 0
+ ¯1 0 0
+ 0 0 1
+ ┘
+
+ <span class='Value'>m</span> <span class='Function'>+</span><span class='Modifier'>˝</span><span class='Modifier2'>∘</span><span class='Function'>×</span><span class='Modifier2'>⎉</span><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>∞</span> <span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>3</span>
+⟨ 2 ¯1 3 ⟩
+
+ <span class='Value'>m</span> <span class='Function'>+</span><span class='Modifier'>˝</span><span class='Modifier2'>∘</span><span class='Function'>×</span><span class='Modifier2'>⎉</span><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>∞</span> <span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>3</span><span class='Function'>×</span><span class='Modifier'>⌜</span><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>10</span>
+┌─
+╵ 2 20
+ ¯1 ¯10
+ 3 30
+ ┘
+
+ <span class='Paren'>(</span><span class='String'>&quot;abc&quot;</span><span class='Function'>≍</span><span class='String'>&quot;def&quot;</span><span class='Paren'>)</span> <span class='Function'>∾</span><span class='Modifier2'>⎉</span><span class='Number'>1</span><span class='Modifier2'>⎉</span><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>∞</span> <span class='Function'>&gt;</span><span class='String'>&quot;QR&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;ST&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;UV&quot;</span>
+┌─
+╎"abcQR
+ abcST
+ abcUV
+
+ ·defQR
+ defST
+ defUV"
+ ┘
+</pre>
+<p>Here's the full, boring description of how <code><span class='Function'>𝔾</span></code> is handled. The operand <code><span class='Function'>𝔾</span></code> is called on the arguments <code><span class='Value'>𝕨</span><span class='Function'>𝔾</span><span class='Value'>𝕩</span></code> before doing anything else (if it's not a function, this just returns <code><span class='Value'>𝕘</span></code>). Then it's converted to a list. It's required to have rank 0 or 1, but numbers and enclosed numbers are fine. This list can have one to three elements; three elements is the general case, as the elements give the ranks for monadic <code><span class='Value'>𝕩</span></code>, dyadic <code><span class='Value'>𝕨</span></code>, and dyadic <code><span class='Value'>𝕩</span></code> in order. If there are less than three elements, the list <code><span class='Value'>r</span></code> is expanded backwards-cyclically to <code><span class='Number'>3</span><span class='Modifier2'>⊸</span><span class='Function'>⥊</span><span class='Modifier2'>⌾</span><span class='Function'>⌽</span><span class='Value'>r</span></code>, turning <code><span class='Bracket'>⟨</span><span class='Value'>a</span><span class='Bracket'>⟩</span></code> into <code><span class='Value'>a</span><span class='Ligature'>‿</span><span class='Value'>a</span><span class='Ligature'>‿</span><span class='Value'>a</span></code> and <code><span class='Value'>a</span><span class='Ligature'>‿</span><span class='Value'>b</span></code> into <code><span class='Value'>b</span><span class='Ligature'>‿</span><span class='Value'>a</span><span class='Ligature'>‿</span><span class='Value'>b</span></code>. So <code><span class='Number'>3</span><span class='Modifier2'>⊸</span><span class='Function'>⥊</span><span class='Modifier2'>⌾</span><span class='Function'>⌽⥊</span><span class='Value'>𝕨</span><span class='Function'>𝔾</span><span class='Value'>𝕩</span></code> is the final formula.</p>
+<h3 id="leading-axis-agreement"><a class="header" href="#leading-axis-agreement">Leading axis agreement</a></h3>
diff --git a/docs/help/cells.html b/docs/help/cells.html
index 4d123802..6aaec9c1 100644
--- a/docs/help/cells.html
+++ b/docs/help/cells.html
@@ -6,6 +6,7 @@
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">help</a></div>
<h1 id="breve-"><a class="header" href="#breve-">Breve (<code><span class='Modifier'>˘</span></code>)</a></h1>
<h2 id="𝔽-𝕩-𝕨-𝔽-𝕩-cells"><a class="header" href="#𝔽-𝕩-𝕨-𝔽-𝕩-cells"><code><span class='Function'>𝔽</span><span class='Modifier'>˘</span> <span class='Value'>𝕩</span></code>, <code><span class='Value'>𝕨</span> <span class='Function'>𝔽</span><span class='Modifier'>˘</span> <span class='Value'>𝕩</span></code>: Cells</a></h2>
+<p><a class="fulldoc" href="../doc/rank.html#cells">→full documentation</a></p>
<p>Apply <code><span class='Function'>𝔽</span></code> to/between the major cells of the arguments. (<code><span class='Function'>𝔽</span><span class='Modifier2'>⎉</span><span class='Number'>¯1</span></code>)</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=YSDihpAgM+KAvzMg4qWKIOKGlTkKCgo8y5ggYQoKYSDiiY3LmCBh">↗️</a><pre> <span class='Value'>a</span> <span class='Gets'>←</span> <span class='Number'>3</span><span class='Ligature'>‿</span><span class='Number'>3</span> <span class='Function'>⥊</span> <span class='Function'>↕</span><span class='Number'>9</span>
diff --git a/docs/help/rank.html b/docs/help/rank.html
index ff2d224a..ff427cea 100644
--- a/docs/help/rank.html
+++ b/docs/help/rank.html
@@ -6,6 +6,7 @@
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">help</a></div>
<h1 id="circled-horizontal-bar-with-notch-"><a class="header" href="#circled-horizontal-bar-with-notch-">Circled Horizontal Bar With Notch (<code><span class='Modifier2'>⎉</span></code>)</a></h1>
<h2 id="𝔽𝕘-𝕩-𝕨-𝔽𝕘-𝕩-rank"><a class="header" href="#𝔽𝕘-𝕩-𝕨-𝔽𝕘-𝕩-rank"><code><span class='Function'>𝔽</span><span class='Modifier2'>⎉</span><span class='Value'>𝕘</span> <span class='Value'>𝕩</span></code>, <code><span class='Value'>𝕨</span> <span class='Function'>𝔽</span><span class='Modifier2'>⎉</span><span class='Value'>𝕘</span> <span class='Value'>𝕩</span></code>: Rank</a></h2>
+<p><a class="fulldoc" href="../doc/rank.html#rank">→full documentation</a></p>
<p>Apply <code><span class='Function'>𝔽</span></code> to cells at ranks given in <code><span class='Value'>𝕘</span></code>. Non-negative numbers indicate the rank of the cell and negative ones indicate the difference from full rank.</p>
<p>The ranks applied are given by the following:</p>
<ul>
diff --git a/help/cells.md b/help/cells.md
index f043bc67..a9e62921 100644
--- a/help/cells.md
+++ b/help/cells.md
@@ -3,6 +3,7 @@
# Breve (`˘`)
## `𝔽˘ 𝕩`, `𝕨 𝔽˘ 𝕩`: Cells
+[→full documentation](../doc/rank.md#cells)
Apply `𝔽` to/between the major cells of the arguments. (`𝔽⎉¯1`)
diff --git a/help/rank.md b/help/rank.md
index 7ef5a3ac..f647a93a 100644
--- a/help/rank.md
+++ b/help/rank.md
@@ -3,6 +3,7 @@
# Circled Horizontal Bar With Notch (`⎉`)
## `𝔽⎉𝕘 𝕩`, `𝕨 𝔽⎉𝕘 𝕩`: Rank
+[→full documentation](../doc/rank.md#rank)
Apply `𝔽` to cells at ranks given in `𝕘`. Non-negative numbers indicate the rank of the cell and negative ones indicate the difference from full rank.