orx_v/cardinality/
d3_variable.rs1use super::{
2 card::{child_fun_unchecked, Card},
3 panic_d1, panic_d2,
4};
5use crate::{
6 cardinality::d2_variable::VariableCardD2, CardD1, Dim, FunVec, IdxLeqD2, NVec, D3, V2,
7};
8
9#[derive(Clone, Copy)]
12pub struct VariableCardD3<V: V2<usize>>(pub(super) V);
13
14impl<V: V2<usize>> From<V> for VariableCardD3<V> {
15 fn from(value: V) -> Self {
16 Self(value)
17 }
18}
19
20impl<V: V2<usize>> Card<D3> for VariableCardD3<V> {
21 fn is_rectangular(&self) -> bool {
22 let n = self.0.card([]);
23 let m = match n {
24 0 => 0,
25 _ => self.0.card([0]),
26 };
27 let p = match m {
28 0 => 0,
29 _ => self.0.at([0, 0]),
30 };
31
32 for i in 0..n {
33 if self.0.card([i]) != m {
34 return false;
35 }
36
37 for j in 0..m {
38 if self.0.at([i, j]) != p {
39 return false;
40 }
41 }
42 }
43
44 true
45 }
46
47 fn cardinality_of(&self, idx: impl Into<<D3 as Dim>::CardIdx>) -> usize {
48 match idx.into() {
49 IdxLeqD2::IdxD0([]) => self.0.card([]),
50 IdxLeqD2::IdxD1([i]) => match i < self.0.card([]) {
51 true => self.0.card([i]),
52 false => panic_d1(i, self.0.card([])),
53 },
54 IdxLeqD2::IdxD2([i, j]) => match i < self.0.card([]) {
55 true => match j < self.0.card([i]) {
56 true => self.0.at([i, j]),
57 false => panic_d2(i, j, self.0.card([i])),
58 },
59 false => panic_d1(i, self.0.card([])),
60 },
61 }
62 }
63
64 fn child_card(&self, i: usize) -> impl Card<<D3 as Dim>::PrevDim> {
65 match i < self.0.card([]) {
66 true => {
67 let card_idx0 = self.0.card([i]);
68 let card_idx1 = FunVec::new(move |[j]| self.0.at([i, j]), CardD1::from(card_idx0));
69 VariableCardD2(card_idx1)
70 }
71 false => panic_d1(i, self.0.card([])),
72 }
73 }
74
75 fn child_fun<T, F>(&self, i: usize, fun: F) -> impl Fn(<<D3 as Dim>::PrevDim as Dim>::Idx) -> T
76 where
77 F: Fn(<D3 as Dim>::Idx) -> T,
78 {
79 match i < self.0.card([]) {
80 true => child_fun_unchecked::<D3, _, _>(i, fun),
81 false => panic_d1(i, self.0.card([])),
82 }
83 }
84
85 fn vec_all<'a, T, N>(&'a self, vec: &'a N) -> impl Iterator<Item = T>
86 where
87 N: NVec<D3, T> + 'a,
88 {
89 (0..self.cardinality_of([])).flat_map(move |i| {
90 (0..self.cardinality_of([i]))
91 .flat_map(move |j| (0..self.cardinality_of([i, j])).map(move |k| vec.at([i, j, k])))
92 })
93 }
94
95 fn vec_enumerate_all<'a, T, N>(
96 &'a self,
97 vec: &'a N,
98 ) -> impl Iterator<Item = (<D3 as Dim>::Idx, T)>
99 where
100 N: NVec<D3, T> + 'a,
101 {
102 (0..self.cardinality_of([])).flat_map(move |i| {
103 (0..self.cardinality_of([i])).flat_map(move |j| {
104 (0..self.cardinality_of([i, j])).map(move |k| ([i, j, k], vec.at([i, j, k])))
105 })
106 })
107 }
108}