The purpose of this memo is to take generative code, transliterate, and run it from first principles in mathematica. This is all done in good fun, so we will also throw in extra symmetry analysis for free.
At least one of the NFT projects on opensea, namely Larva Lab's Autoglyphys, shows exemplary rigor with asset data on chain. The Autoglyphs are valuable works of art comparable with hand-drawn designs from geometric tattoo artists, and the original authors are also doing interesting things with robotic printing. Thus we have a motive to recreate the autoglyphs locally, and to study their properties. Examining the contract closely enough, we find a few simple functions that do most of the work, and one confusing but critical line:
uint a = uint(uint160(keccak256(abi.encodePacked(idToSeed[id]))));
Don't ask me for all the details. I calculated (with an old compiler), for special example AG#308, the hidden value:
a308 = 804491777491045640850919148972519969740151830770;
Mod[a308, 83]
Out[]=14
Since $14<20$, indeed we are working in scheme $1$ with lexicon $\{X,/,\backslash \}$. We need a little bit of code, which essentially computes a multiplication table with variable symmetry and bad truncation of 256-bit integers (which seems to add entropy and structure):
ONE = 4294967296;
SIZE = 64; HALFSIZE = 32;
y[ind_, aVal_] := With[{y0 = 2*(ind - HALFSIZE) + 1},
Switch[Mod[aVal, 3], 0, y0, 1, -y0, 2, Abs[y0]]*aVal]
x[ind_, aVal_] := With[{x0 = 2*(ind - HALFSIZE) + 1},
Switch[Mod[aVal, 2], 0, x0*aVal, 1, Abs[x0]*aVal]]
v[x_, y_, mod_] := With[{v0 = Mod[Floor[
If[# > 2^255 - 1, Mod[(# - 2^256)/ONE + 1, 2^256],
#/ONE] &@Mod[x*y, 2^256]], mod]}, If[v0 < 5, v0, 0]]
AutoGlyphM[aVal_] := With[{mod = Mod[aVal, 11] + 5},
Outer[v[x[#2, a308], y[#1, a308], mod] &,
Range[0, SIZE - 1], Range[0, SIZE - 1], 1]]
TakeAutoGlyphType1[ind_] := ReplaceAll[Characters[StringSplit[Import[
"https://www.larvalabs.com/autoglyphs/rawglyph?index="
<> ToString[ind]], " "]], {"." -> 0, "X" -> 1, "/" -> 2, "\\" -> 3}]
This code seems to work for example $308$ because the difference between data and compute is an null array interspersed with $4$ values, but in this spec. $4$ is an extra null symbol.
dat1 = AutoGlyphM[a308];
dat2 = TakeAutoGlyphType1[308];
ArrayPlot /@ {dat1, dat2}
ArrayPlot[dat1 - dat2]
So instead of wasting the $4$ data, we will map it to an extra $O$ symbol. Then we can affix a seal for the new moon of December, when a cubist $\emptyset$ and a mutation of the OX glyph could both be taken from the proofs of $\large{+}$ my?T¿Ry $\large{+}\large{+} 4\rightarrow O$.
Also, I made two different view functions, one vector, one array.
t0 = 1/8;
HashFill[or_] := Polygon[or + # & /@ Tuples[{1/2, -1/2}, 2][[{1, 2, 4, 3}]]];
EmptyFill[or_] := {};
DashLine[or_] := Polygon[{or - {1/2, t0}, or - {1/2, -t0}, or + {1/2, t0},
or + {1/2, -t0}}];
PipeLine[or_] := Polygon[{or - {t0, 1/2}, or - {-t0, 1/2}, or + {t0, 1/2},
or + {-t0, 1/2}}];
BSlash[or_] := Polygon[{or + {-1/2, 1/2} + {0, -t0 Sqrt[2]}, or + {-1/2, 1/2},
or + {-1/2, 1/2} + {t0 Sqrt[2], 0},
or + {1/2, -1/2} + {0, t0 Sqrt[2]},
or + {1/2, -1/2}, or + {1/2, -1/2} + {-t0 Sqrt[2], 0}}];
FSlash[or_] := Polygon[{or + {-1/2, -1/2} + {0, t0 Sqrt[2]}, or + {-1/2, -1/2},
or + {-1/2, -1/2} + {t0 Sqrt[2], 0},
or + {1/2, 1/2} + {0, -t0 Sqrt[2]},
or + {1/2, 1/2}, or + {1/2, 1/2} + {-t0 Sqrt[2], 0}}];
CrossLines[or_] := {FSlash[or], BSlash[or]};
PlusLines[or_] := {DashLine[or], PipeLine[or]};
Circ[or_] := {Black, Disk[or, 1/2], White, Disk[or, 1/2 - 2 t0]};
MHashFill = Table[1, {i, 1, 3}, {j, 1, 3}];
MEmptyFill = Mod[MHashFill + 1, 2];
MDashLine = Table[#, {i, 1, 3}] & /@ {0, 1, 0};
MPipeLine = Transpose[MDashLine];
MBSlash = IdentityMatrix[3];
MFSlash = Reverse[MBSlash];
MCirc = MapThread[Mod[#1 + #2, 2] &, {MDashLine, MPipeLine}, 2];
MPlus = ReplacePart[MCirc, {2, 2} -> 1];
MCross = ReplacePart[
MapThread[Mod[#1 + #2, 2] &, {MFSlash, MBSlash}, 2], {2, 2} -> 1];
Hexagram[or_, code_] := Map[or + # &, Position[ReplacePart[Table[If[OddQ[i],
If[MemberQ[Complement[Range[15], {2, 14}], j], 1, 0],
If[MemberQ[{1, 15}, j], 1, 0]], {i, 15}, {j, 15}],
Join[{{1, 2} -> 1, {1, 14} -> 1, {15, 2} -> 1, {15, 14} -> 1},
Flatten[
Outer[{1 + 2 #1, #2} -> 0 &,
Position[code, 0][[All, 1]], {7, 8, 9}]]
]], 1]]
Once again, the view code is messy, and takes more space than compute, but recall that view code doesn't need to be on chain. Nevertheless, such code is valuable since it makes data easier to understand and appreciate
Show[Graphics[ MapIndexed[
Apply[#1 /. {0 -> EmptyFill, 1 -> CrossLines, 2 -> FSlash,
3 -> BSlash, 4 -> Circ },
{Reverse[#2] {1, -1}}] &, dat1, {2}], ImageSize -> 64*8],
Graphics[{Darker@Red, EdgeForm[Darker@Red],
HashFill[Reverse@# {1, -1}] & /@
Hexagram[{3, 3}, {0, 0, 1, 0, 1, 0}]}], ImageSize -> 192*4]
Image[ReplacePart[ Mod[Plus[ ArrayFlatten[
dat1 /. {0 -> MEmptyFill, 1 -> MCross, 2 -> MFSlash,
3 -> MBSlash, 4 -> MCirc }], 1], 2], # -> 2 & /@
Hexagram[{20, 21}, {0, 0, 1, 0, 1, 0}]] /. {0 -> {0, 0, 0},
1 -> {1, 1, 1}, 2 -> {0.8, 0, 0}}, ImageSize -> 192*4]
Now we can see quite obviously transpose symmetry, and note that it probably follows from the truth value
And[Mod[a308, 3] == 0, Mod[a308, 2] == 0]
Out[]=True
We are not too enthusiastic about proving this conjecture, but would rather strengthen it through more data analysis. What are the secret code values for the other $511$ glyphs? Do modulus values of these codes predict symmetry type? We will return shortly with more answers.