From 1c7e9f16d13e69ce3f989ec0777ab731bda841f0 Mon Sep 17 00:00:00 2001 From: Sean Olson Date: Fri, 22 Nov 2024 12:16:14 -0800 Subject: [PATCH] [wip] Introduce layout and shape traits for adjuncts. --- eudoxus/src/adjunct.rs | 119 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 118 insertions(+), 1 deletion(-) diff --git a/eudoxus/src/adjunct.rs b/eudoxus/src/adjunct.rs index 0f5f5cd..18d446a 100644 --- a/eudoxus/src/adjunct.rs +++ b/eudoxus/src/adjunct.rs @@ -19,9 +19,126 @@ use num_traits::{One, Zero}; use std::ops::{Add, Mul}; +use typenum::{Max, Min, U1, U2}; use crate::space::{FiniteDimensional, ProjectiveDimensions}; -use crate::Increment; +use crate::{Increment, Natural}; + +pub trait Layout { + type Bounds: Adjunct + AsRef<[usize]> + Copy + Map; + + const N: usize; + const BOUNDS: Self::Bounds; + + fn is_zero() -> bool { + Self::BOUNDS.as_ref().iter().any(|&bound| bound == 0) + } +} + +pub trait ShapeEq: Layout +where + T: Layout, +{ +} + +impl ShapeEq<(N,)> for (R, C) +where + N: Natural, + R: Max + Min + Natural, + C: Natural, +{ +} + +impl ShapeEq<(R, C)> for (N,) +where + N: Natural, + R: Max + Min + Natural, + C: Natural, +{ +} + +impl ShapeEq<(R1, C1)> for (R2, C2) +where + R1: Max + Min + Natural, + C1: Natural, + R2: Max>::Output> + + Min>::Output> + + Natural, + C2: Natural, +{ +} + +pub trait ShapeSpan: Layout { + type Output: Natural; +} + +impl ShapeSpan for (N,) +where + N: Natural, +{ + type Output = U1; +} + +impl ShapeSpan for (R, C) +where + R: Min + Natural, + C: Natural, + U2: Min<>::Output>, + >::Output>>::Output: Natural, +{ + type Output = >::Output>>::Output; +} + +impl Layout for (N,) +where + N: Natural, +{ + type Bounds = [usize; 1]; + + const N: usize = 1; + const BOUNDS: Self::Bounds = [N::USIZE]; +} + +impl Layout for (R, C) +where + R: Natural, + C: Natural, +{ + type Bounds = [usize; 2]; + + const N: usize = 2; + const BOUNDS: Self::Bounds = [R::USIZE, C::USIZE]; +} + +pub trait Shaped: Adjunct { + type Layout: Layout; + + const ORDERING: ::Bounds; + + fn get(&self, index: ::Bounds) -> Option<&Self::Item>; +} + +// TODO: This work was done a long time ago, so this comment _could_ be wrong, but it really +// appears that this trait is meant to replace the `Linear` trait below. The "2" is probably +// an artifact of experimentation with shape and layout ahead of replacing `Linear`. +pub trait Linear2: Shaped +where + Self::Layout: ShapeSpan, +{ + fn get(&self, index: usize) -> Option<&Self::Item> { + ::get( + self, + ::BOUNDS.clone().map(|bound| { + if bound == 1 { + 0 + } + else { + index + } + }), + ) + } +} pub trait Adjunct: Sized { type Item;