← Back to AILP Home

Ternary — trit and tryte

Overview

Nitpick supports balanced ternary (base 3) as a fundamental primitive for cognitive modeling, three-state logic, and quantum-like states (Q3). Unlike standard binary where digits are {0, 1}, balanced ternary digits are {-1, 0, +1}. This provides inherent symmetry, trivial negation, and native three-state logic.

There are two ternary types: - trit: A single balanced ternary digit. - tryte: A 6-trit word (ternary byte), offering $3^6 = 729$ possible states.

Specifications

Property trit tryte
Total size 8 bits (C int8_t) 16 bits (C uint16_t)
Valid range [-1, +1] [-364, +364]
Valid states 3 $729$ ($3^6$)
Storage Signed integer Split-byte (two 5-trit trybbles)
ERR Sentinel -128 0xFFFF
Logic type Kleene (min/max) Bitwise-equivalent over trits

Internal Representation

To efficiently emulate ternary on binary hardware, Nitpick uses specific storage layouts: - trit: Stored as a native 8-bit signed integer. Values are directly -1, 0, and 1. - tryte: Stored as a 16-bit unsigned integer using a "split-byte" strategy. The first 5 trits (low trybble) are packed into the lower 8 bits, and the next 5 trits (high trybble) into the upper 8 bits. Note that while a tryte is logically 6 trits, the storage format can hold up to 10 trits.

Declaration

You can declare ternary variables using the 0t literal syntax, where T represents -1.

// trit literals: 0t[01T]+
trit:positive = 0t1;
trit:zero = 0t0;
trit:negative = 0tT;

// tryte literals (evaluated positionally base-3)
tryte:val1 = 0t10T;     // 1*9 + 0*3 + (-1)*1 = 8
tryte:val2 = 0t001T00;  // Leading zeros optional
tryte:max  = 0t111111;  // +364
tryte:min  = 0tTTTTTT;  // -364

Arithmetic Operations

Balanced ternary arithmetic is naturally symmetric. Standard arithmetic operators are supported.

// trit arithmetic
trit:a = 0t1;
trit:b = 0tT;
trit:sum = a + b;  // 0t0
trit:prod = a * b; // 0tT
trit:neg = -a;     // 0tT (flip digits)

// tryte arithmetic (supports division/modulo)
tryte:x = 0t100;   // 9
tryte:y = 0t010;   // 3
tryte:q = x / y;   // 0t010 (3)
tryte:rem = x % y; // 0t000 (0)

[!NOTE] trit addition overflows to ERR if the sum exceeds [-1, 1]. For multi-digit addition, use tryte.

Three-State Logic (Kleene Logic)

Because a trit inherently holds three states, it natively implements Kleene logic (True = 1, Unknown = 0, False = -1).

trit:t_true = 0t1;
trit:t_false = 0tT;
trit:t_unknown = 0t0;

// AND is minimum
trit:and_result = t_true & t_unknown;   // 0t0
trit:and_result2 = t_false & t_unknown; // 0tT

// OR is maximum
trit:or_result = t_true | t_unknown;    // 0t1
trit:or_result2 = t_false | t_unknown;  // 0t0

// NOT is negation (flip)
trit:not_result = ~t_unknown;           // 0t0

Error Handling & The ERR Sentinel

Both trit and tryte utilize sticky ERR sentinels to indicate invalid states (e.g., overflow, division by zero) without causing undefined behavior.

Triggers for ERR: - Division by zero (tryte:x / 0t0ERR) - trit addition overflow (0t1 + 0t1ERR) - Operation on an existing ERR value (sticky propagation)

To check for ERR states, use the ok() function:

tryte:result = risky_operation();
if (ok(result) == 0) {
    // result is ERR
    !!! ERR_INVALID_STATE;
}

Type Conversions

You can convert between ternary and binary integer types using standard casts. Conversions will preserve the mathematical value, raising ERR or standard error states if out of range.

// tryte to int32
int32:val = @cast<int32>(tryte_val);

// int32 to tryte
tryte:ternary_val = @cast<tryte>(42);

Performance Implications

All ternary arithmetic is software-emulated via C runtime calls. It is not natively supported by standard binary CPUs.

[!TIP] Use trit and tryte for their expressiveness, symmetry, and native three-state logic representation (like Q3 cognitive states). Do not use them in performance-critical hot loops where standard int16 or int32 would suffice.

Related