SNAPKITTYWEST's picture
push from SNAPKITTYWEST/hyperkitty-constraint-dsl
224e773 verified
Raw History Blame Contribute Delete
1.68 kB
//! QLG Sphere: Canonical six-point integer geometry
//!
//! S_can = {x ∈ Z³ : x₀² + x₁² + x₂² = 1}
//! Solutions: {(±1,0,0), (0,±1,0), (0,0,±1)}
use crate::Point;
/// Verify membership in canonical sphere.
pub fn is_on_sphere(p: &Point) -> bool {
p.0 * p.0 + p.1 * p.1 + p.2 * p.2 == 1
}
/// All six canonical points
pub fn canonical_points() -> [Point; 6] {
[
Point(1, 0, 0),
Point(-1, 0, 0),
Point(0, 1, 0),
Point(0, -1, 0),
Point(0, 0, 1),
Point(0, 0, -1),
]
}
/// Encode point to 3-byte array (little-endian signed integers)
pub fn encode(p: &Point) -> [u8; 3] {
[
(p.0 as i8) as u8,
(p.1 as i8) as u8,
(p.2 as i8) as u8,
]
}
/// Decode point from 3-byte array
pub fn decode(bytes: &[u8; 3]) -> Point {
Point(
bytes[0] as i8 as i32,
bytes[1] as i8 as i32,
bytes[2] as i8 as i32,
)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn canonical_on_sphere() {
for p in canonical_points() {
assert!(is_on_sphere(&p));
}
}
#[test]
fn six_solutions() {
assert_eq!(canonical_points().len(), 6);
}
#[test]
fn round_trip() {
for p in canonical_points() {
let encoded = encode(&p);
let decoded = decode(&encoded);
assert_eq!(p, decoded);
}
}
#[test]
fn invalid_rejected() {
assert!(!is_on_sphere(&Point(1, 1, 0)));
assert!(!is_on_sphere(&Point(2, 0, 0)));
assert!(!is_on_sphere(&Point(0, 0, 0)));
}
}