← USINFERENCE.COM   POWERED_BY_FORTH

Forth words

Generated from the vocabulary (npm run forth -- --words > forth/WORDS.md). In the REPL: ? lists words, help <word> shows one. Numbers are float32; true is -1, false is 0; a 4-D vector is four floats on the stack (x y z w).

WordStackDoes
+( a b -- a+b )add
-( a b -- a-b )subtract
*( a b -- a*b )multiply
/( a b -- a/b )divide (float)
mod( a b -- a%b )remainder
min( a b -- m )smaller of two
max( a b -- m )larger of two
atan2( y x -- rad )angle of the point (x, y)
negate( a -- -a )change sign
abs( a -- |a| )absolute value
sqrt( a -- r )square root
sin( rad -- s )sine
cos( rad -- c )cosine
floor( a -- n )round down
1+( a -- a+1 )increment
1-( a -- a-1 )decrement
2*( a -- 2a )double
2/( a -- a/2 )halve
pi( -- 3.14159 )the constant pi
dup( a -- a a )duplicate the top
drop( a -- )discard the top
swap( a b -- b a )exchange the top two
over( a b -- a b a )copy the second item
rot( a b c -- b c a )rotate the third item to the top
-rot( a b c -- c a b )rotate the top item to third
nip( a b -- b )drop the second item
2dup( a b -- a b a b )duplicate the top pair
2drop( a b -- )discard the top pair
2swap( a b c d -- c d a b )exchange the top two pairs
depth( -- n )number of items on the stack
=( a b -- f )equal (true = -1, false = 0)
<>( a b -- f )not equal
<( a b -- f )less than
>( a b -- f )greater than
<=( a b -- f )less or equal
>=( a b -- f )greater or equal
0=( a -- f )is zero
0<( a -- f )is negative
and( a b -- a&b )bitwise and (int32)
or( a b -- a|b )bitwise or (int32)
xor( a b -- a^b )bitwise xor (int32)
invert( a -- ~a )bitwise not (int32)
true( -- -1 )the true flag
false( -- 0 )the false flag
assert( f -- )error "assertion failed" when f is 0 (used by ci/smoke.fs)
near( a b eps -- f )true when |a-b| <= eps
if( f -- )run the next part when f is not 0 (inside : definitions)
else( -- )alternative branch of if
then( -- )end of if
begin( -- )start of a begin..until/again/while loop
until( f -- )loop back to begin until f is not 0
again( -- )loop back to begin forever (the watchdog ends it)
while( f -- )leave the begin..repeat loop when f is 0
repeat( -- )end of begin..while..repeat
do( limit start -- )counted loop (runs at least once)
loop( -- )end of do, step 1
+loop( n -- )end of do, step n
i( -- n )index of the innermost do loop
j( -- n )index of the next outer do loop
;( -- )end a : definition; redefining an existing word replaces its body in place, so callers see the change
:( -- ) namestart a definition: : square dup * ;
[( -- )switch to interpreting inside a definition
]( -- )back to compiling
literal( x -- )compile x as a literal: [ 2 3 + ] literal
immediate( -- )make the last definition run at compile time
'( -- xt ) namepush the execution token of a word
[']( -- ) namecompile the execution token of a word as a literal
execute( xt -- )run the word with this token
see( -- ) namedecompile a word from its threaded code: see sq
variable( -- ) namedefine a variable; the name pushes its address
create( -- ) namedefine a name that pushes the next free cell address; fill with ,
,( x -- )store x in the next free cell
constant( x -- ) namedefine a constant
v4( x y z w -- ) namedefine a named 4-D vector; the name pushes its 4 floats
@( addr -- x )fetch a variable
!( x addr -- )store into a variable
+!( x addr -- )add into a variable
.( a -- )print and drop
.s( -- )print the stack, bottom first
cr( -- )newline
space( -- )print a space
."( -- ) text"print text up to the closing quote: ." hello"
words ?( -- )list every word
help( -- ) nameone-line help: help rotxw
time( -- s )seconds since the scene started (frozen in reduced-motion)
time!( s -- )set the clock (CLI, tests, brand marks)
mouse( -- mx my )pointer relative to the hero, -0.5 .. 0.5 (0 0 when absent)
view( -- left top right bottom )the visible area in scene units, origin at the hero centre
reduced( -- f )true under prefers-reduced-motion
nodes( -- n )topology: number of nodes (boards, head, mini, switch) from scene/topology.json
links( -- n )topology: number of links
link@( j -- a b )topology: node indices joined by link j
role@( i -- r )topology: role of node i: 0 board, 1 head, 2 mini, 3 switch
boards( -- n )topology: number of boards (nodes whose role is board)
zoom( eye -- )move the camera to this distance over 0.4 s, easing out (1500 at rest; 380 flies into the inner cell)
eye( -- d )current camera distance
zoomed( -- f )true when the camera is flying to, or sits at, a close distance (eye target below 1000)
pointer( -- x y )the pointer (mouse, or the last tap) in scene units around the hero centre; 100000 100000 when there is none
label( x y i -- )write the 2-letter role glyph of topology node i at (x, y): B1 .. B7, HD head, MN mini, SW switch
gpu@( i -- gb )topology: memory class in GB of node i (0 for non-boards)
rgb( r g b -- )set the stroke colour, 0..255
alpha( a -- )set the stroke opacity, 0..1
width( w -- )set the line width
offset( dx dy -- )translate everything drawn next (the chromatic split uses it)
line( x1 y1 x2 y2 -- )draw a segment
moveto( x y -- )set the pen
lineto( x y -- )draw from the pen to (x, y) and move the pen there
disc( x y r -- )draw a filled dot of radius r
tag( x y -- ) textwrite a small label at (x, y): 12 40 tag U_VEC
cls( -- )clear what the REPL drew
gfx-reset( -- )reset colour, alpha, width, offset and the draw statistics
nlines( -- n )segments drawn since gfx-reset
ndots( -- n )dots drawn since gfx-reset
gbounds( -- x0 y0 x1 y1 )bounding box of everything drawn since gfx-reset
gsum( -- s )sum of all drawn coordinates (a checksum for ci/smoke.fs)
rotxy( angle -- )set the xy-plane angle of the 4-D rotor, radians (absolute, not cumulative)
rotxz( angle -- )set the xz-plane angle of the 4-D rotor, radians (absolute, not cumulative)
rotxw( angle -- )set the xw-plane angle of the 4-D rotor, radians (absolute, not cumulative)
rotyz( angle -- )set the yz-plane angle of the 4-D rotor, radians (absolute, not cumulative)
rotyw( angle -- )set the yw-plane angle of the 4-D rotor, radians (absolute, not cumulative)
rotzw( angle -- )set the zw-plane angle of the 4-D rotor, radians (absolute, not cumulative)
rot0( -- )reset the rotor to identity
rotate( x y z w -- x y z w )apply the rotor to a 4-D vector
mat( -- m00 .. m33 )push the 16 entries of the rotor, row-major
v*( x y z w k -- x y z w )scale a 4-D vector
proj( x y z w -- x y z )perspective 4-D to 3-D along w, distance 1500
proj3( x y z -- sx sy )3-D to 2-D with the scene rotateX(-25) rotateY(45), perspective 1500
tess( -- v0 .. v15 )the 16 vertices (x y z w) of a unit tesseract, +-1/2, turned by the rotor
tessn( n -- v0 .. v15 )the same, with edge length n
edges( -- a0 b0 .. a31 b31 )the 32 edges as vertex index pairs
draw( v0 .. v15 n -- )scale 16 vertices by n, project 4-D to 3-D to 2-D and draw the 32 edges
cube( -- v0 .. v7 )the 8 vertices (x y z) of a unit cube (the tesseract's w = 0 section), turned by the rotor
draw3( v0 .. v7 n -- )scale 8 cube vertices by n, project 3-D to 2-D and draw the 12 edges (the brand mark)
dot( a0 a1 a2 a3 b0 b1 b2 b3 -- d )4-D dot product
norm( x y z w -- n )length of a 4-D vector
inference ƒ( a b -- y )a tiny fixed 2-16-1 ReLU perceptron, weights baked in: y ~ hypot(a, b) within 1 %

The math behind the geometry words

Rotor (rotxy rotxz rotxw rotyz rotyw rotzw, rot0, rotate, mat). R^4 has six rotation planes. A rotation by theta in the (a, b) plane is the identity except on those two axes, where it is the Givens matrix [[cos t, -sin t], [sin t, cos t]]. The rotor is the product G_zw G_yw G_yz G_xw G_xz G_xy (xy applied first); each word sets one plane's angle absolutely, so time rotxw is a clean animation. The 4x4 product is rebuilt on every set.

Perspective (proj). The eye sits at w = D, D = 1500 (the page's CSS perspective). A 4-D point maps to 3-D by f = D / (D - w), (x, y, z) <- f (x, y, z). Points with w = 0 are unchanged.

Scene projection (proj3). The 3-D point is turned by the scene rotation M = Rx(-25 deg) Ry(45 deg) (the order and signs of RetroHypercube's rotateX(-25deg) rotateY(45deg); y points down) and projected by f = D / (D - z'), giving screen (x' f, y' f). brand/src/mkmark.py used exactly this; the tests hold the new code to its numbers within 1e-3.

Tesseract (tess tessn edges draw). Schlaefli {4,3,3}: the 16 vertices are all sign choices (+-1/2)^4, vertex i taking its x, y, z, w sign from bits 0..3 of i. Two vertices share an edge when they differ in exactly one bit (Hamming distance 1): 16 * 4 / 2 = 32 edges, listed in the order i < j. It has 8 cubic cells: fixing one coordinate to +-1/2 gives a cube. Its dual is the 16-cell (8 vertices +-e_i, 24 edges). cube / draw3 use the w = 0 section (a cube of the same size, the brand mark's nested cells); draw runs 4-D, then proj, then proj3.

Nested cells (scene/cells.fs). Sizes 160, 110, 70, 35 and turn periods 10, 15, 20, 25 s; cell i turns by 2 pi t / period_i.

inference. A 2-16-1 ReLU perceptron: hidden unit k computes max(0, a cos t_k + b sin t_k), t_k = k * 22.5 deg, and the output is 0.197 times their sum. The sum equals r * S(phi) with S within +-1 % of a constant, so the net approximates hypot(a, b). The weights were set analytically, not trained.

Topology (scene/hero.fs). node i of n sits on a Fibonacci sphere: z = 1 - (2i+1)/n, r = sqrt(1 - z^2), phi = i * 2.39996 (the golden angle); the vertex (r cos phi, r sin phi, z, 0) is scaled, rotated by the inner cell's rotor and projected like any other 4-vector. Memory class sets the dot radius.

The compiler