// ---
// tags: trop, trident
// crystal-type: circuit
// crystal-domain: comp
// ---
// Tropical semiring element over U32.
//
// The tropical semiring (min, +):
// - Tropical addition: a + b = min(a, b)
// - Tropical multiplication: a * b = a + b (ordinary, saturating)
// - Additive identity (ZERO): +inf (U32 max = 4294967295)
// - Multiplicative identity (ONE): 0
module trop.element
/// Sentinel for +infinity (tropical zero, additive identity).
pub const INF: U32 = 4294967295
/// A tropical semiring element wrapping a U32.
/// val == INF represents +infinity.
/// val == 0 represents tropical one (multiplicative identity).
pub struct Tropical {
val: U32
}
/// Construct a Tropical element from a raw U32.
pub fn from_u32(v: U32) -> Tropical {
Tropical { val: v }
}
/// Extract the inner U32 value.
pub fn as_u32(t: Tropical) -> U32 {
t.val
}
/// Check whether this element is +inf (tropical zero).
pub fn is_inf(t: Tropical) -> bool {
t.val == INF
}
/// Check whether this element is finite.
pub fn is_finite(t: Tropical) -> bool {
t.val != INF
}
/// Tropical addition: min(a, b).
/// If either operand is INF, returns the other.
pub fn add(a: Tropical, b: Tropical) -> Tropical {
if a.val < b.val {
a
} else {
b
}
}
/// Tropical multiplication: a + b (saturating).
/// If either operand is INF, or if the sum overflows U32, returns INF.
pub fn mul(a: Tropical, b: Tropical) -> Tropical {
if a.val == INF {
Tropical { val: INF }
} else if b.val == INF {
Tropical { val: INF }
} else {
let sum: U32 = a.val + b.val
// Overflow check: if sum wrapped around, it will be less than either operand.
// Also guard against hitting the INF sentinel exactly.
if sum < a.val {
Tropical { val: INF }
} else if sum == INF {
Tropical { val: INF }
} else {
Tropical { val: sum }
}
}
}
/// Tropical zero: +inf (identity for min).
pub fn zero() -> Tropical {
Tropical { val: INF }
}
/// Tropical one: 0 (identity for ordinary addition).
pub fn one() -> Tropical {
Tropical { val: 0 }
}
trop/tri/element.tri
ฯ 0.0%