Question
I was experimenting with generating truth tables in J:
nand =: *:
nand /~ 0 1
1 1
1 0
bxor =: 22 b. NB. Built-in bitwise XOR
bxor /~ 0 1
0 1
1 0
Now I want to define my own logical xor, which I did like so:
xor =: 3 : 0
]y NB. monadic case is just the identity
:
(x*.-.y)+.(y*.-.x) NB. dyadic case is (x AND NOT y) OR (y AND NOT x)
)
This works as I expect when I call it directly.
0 xor 0 1
0 1
1 xor 0 1
1 0
But it doesn't generate a truth table:
xor /~ 0 1
0 0
Why not?
I thought maybe the problem was that ]/~ 0 1
itself produced a 1 x 2 array, so I changed the monadic part to use nand (*:y
) because it produces the 2x2 array:
*:/~ 0 1
1 1
1 0
xor =: 3 : 0
*:y NB. certainly wrong, but at least has 2x2 shape.
:
(x*.-.y)+.(y*.-.x)
)
But I still get the same behavior:
xor /~ 0 1
0 0
Can someone help me understand the flaw in my thinking?
Solution
Your xor
has infinite rank, while *:
,~:
have rank 0. You can verify that by using b.: v b. 0
like so:
~: b. 0
_ 0 0
*: b. 0
0 0 0
xor b. 0
_ _ _
What this means is that xor
operates on the list 0 1
rather than on each individual atom 0
, 1
.
You will get the result you expect if you use xor
with rank 0:
xor"0 /~ 0 1
0 1
1 0
Or if you define xor
to be of rank 0.