# Decode in depth ⊥

# Decode in depth `⊥`

#

Let’s begin with a basic understand of what a number system really means. When we write `123`

, what we really mean is

```
+/1 2 3×100 10 1
```

123

But why `100 10 1`

? You might say that’s `10*2 1 0`

, but another way to look at it is `⌽×\1,2⍴10`

. The `1`

here is the “seed” or initial value for our running product. Now we can see a way to generalise this. Instead of `2⍴10`

we could choose two different numbers, say 60 and 24. This gives us `⌽×\1 60 24`

or `1440 60 1`

. This would be a days-hours-minutes system, 1 day being 1440 minutes. So, if we have 1 day, 2 hours, 3 minutes, how many minutes do we have?

```
+/1 2 3×1440 60 1
```

1563

This brings us to what `⊥`

does. It takes a mixed-radix spec as left argument, and evaluates how many of the smallest unit a given “number” (expressed as a vector of “digits”) corresponds to.

```
0 24 60⊥1 2 3
```

1563

Note the difference in the spec between the `+/×`

method and the `⊥`

method. We don’t have to specify the unit (which’ll always be 1 anyway) on the little end, but instead, we pad with a 0 on the big end. The 0 is ignored, and could actually be any value. The only reason it’s needed at all is to match the length of the right argument.

Now, APL, of course, allows using a scalar and will distribute it to all positions. This allows things like:

```
10⊥1 2 3 ⍝ base ten
2⊥1 0 1 ⍝ binary
```

123

5

So `⊥`

is really a kind of fanciful cover for `+/×`

or actually `+.×`

, the latter explaining why `⊥`

takes a transposed argument.

```
10 10 10 ⊥ ⍉2 3⍴1 2 3 3 2 1
100 10 1+.×⍉2 3⍴1 2 3 3 2 1
```

123 321

123 321

We can model `⊥`

as:

```
10 10 1 {(⌽×\⌽⍺)+.×⍵} ⍉2 3⍴1 2 3 3 2 1
24 60 1 {(⌽×\⌽⍺)+.×⍵} 1 2 3
```

123 321

1563

Because `⊥`

has a specific definition rather than being some specialised type-dependent utility, it can be used for some unusual tricks that have little apparent connection to base-conversion. One that has achieved some fame is `⊥⍨`

on a Boolean vector. Let’s analyse what it does.

Let’s say we have the vector `1 0 1 1 1`

. `⍨`

will cause the vector to be used both a base specification and as the count for each “type” place (“hundreds”, “tens”, ones). So we have `1 0 1 1 1⊥1 0 1 1 1`

. Remember, this really means:

```
+/(⌽×\⌽1,⍨1↓1 0 1 1 1)×1 0 1 1 1
⊥⍨1 0 1 1 1
```

3

3

That’s why `⊥⍨`

is “count trailing 1s”. Conceptually, we add 1s from the right (though each is multiplied by increasing powers of 1 — all `1*n`

being always 1 of course), until a 0 causes everything after that to become 0 (`n×0`

being always 0 of course). Finally, we sum.

Another trick, often used in tacit APL, is `1⊥something`

. Let’s analyse that one. The first thing we can recognise here is that the 1 will be expanded to match the length of the right argument, so say `1⊥3 1 4`

really means `1 1 1⊥3 1 4`

. This is simply:

```
+/(⌽×\⌽1,⍨1↓1 1 1)×3 1 4
1⊥3 1 4
```

8

8

`×\`

applied to a vector of 1s, is still “1”. That’s the multiplicative identity, which means that `1⊥`

is equivalent to `+/`

. But remember the transposing when dealing with multi-dimensional arguments, and you’ll soon realise that it is actually `+⌿`

. Let’s look at that. Notice that the two numbers 271 and 314 are represented in base 10 as:

```
⍉2 3⍴2 7 1 3 1 4
```

2 3 7 1 1 4

Why? Because then we can do:

```
100 10 1+.×⍉2 3⍴2 7 1 3 1 4
```

271 314

which is the same thing as:

```
+⌿100 10 1×⍤0 1⍉2 3⍴2 7 1 3 1 4
```

271 314

Or, in other words, we multiply each row by its place weight (big endian) and then sum vertically. Then, if the weight is a constant 1, we have a simple vertical summation, or `+⌿`

.

Another trick, also sometimes used in tacit APL is `0⊥something`

. Let’s analyse that one. First, the left argument is extended to match the shape of the right argument: `0⊥314`

is the same as `0 0 0⊥3 1 4`

. Again, recall that this is the same as

```
(⌽×\⌽1,⍨1↓0 0 0)×3 1 4
```

0 0 4

Summing that gives us 4; the last element of the vector:

```
+/(⌽×\⌽1,⍨1↓0 0 0)×3 1 4
0⊥3 1 4
```

4

4

What happens if we apply this to a higher-rank array? If we examine the rank, we can see it returns the last major cell of its argument:

```
⊢m←3 3⍴9?9
⊢c←0⊥m
⊃⍴c
```

4 1 6 5 2 9 7 8 3

7 8 3

3

Since we’re returning the last major cell unmodified, it is the same as `⊢⌿`

.