Skip to main content

macroonz_compiler/relation/
types.rs

1//! The relation home's rows, postures, standings, and refusals.
2//!
3//! Declarations only.
4//! Every road that reaches a private field lives in `type_guard.rs` or `questions.rs`, this file's own children.
5
6use crate::bounded::{Bounded, DuplicateKey, ForeignRosterReference, KeyedRoster, NonEmpty};
7
8#[path = "type_guard.rs"]
9mod guard;
10
11#[path = "questions.rs"]
12mod questions;
13
14/// Foreign-free rows referencing one left and one right caller-keyed roster.
15///
16/// Rows retain authored order and may be empty or repeated until a caller-selected posture informs those questions.
17#[derive(Debug, Clone, PartialEq, Eq, Hash)]
18pub struct KeyedRosterRows<
19    'rosters,
20    Left,
21    LeftKey,
22    Right,
23    RightKey,
24    Payload,
25    const LEFT: usize,
26    const RIGHT: usize,
27    const ROWS: usize,
28> {
29    left: &'rosters KeyedRoster<Left, LeftKey, LEFT>,
30    right: &'rosters KeyedRoster<Right, RightKey, RIGHT>,
31    rows: Bounded<ReferencedRosterRow<'rosters, Left, LeftKey, Right, RightKey, Payload>, ROWS>,
32    canonical_indices: Bounded<usize, ROWS>,
33}
34
35/// One duplicate-free relation promoted from foreign-free keyed-roster rows.
36#[derive(Debug, Clone, PartialEq, Eq, Hash)]
37pub struct KeyedRosterRelation<
38    'rosters,
39    Left,
40    LeftKey,
41    Right,
42    RightKey,
43    Payload,
44    const LEFT: usize,
45    const RIGHT: usize,
46    const ROWS: usize,
47> {
48    rows: KeyedRosterRows<'rosters, Left, LeftKey, Right, RightKey, Payload, LEFT, RIGHT, ROWS>,
49}
50
51crate::roster! {
52    /// Which stable relation-row reading a caller selects.
53    pub enum RowOrder {
54        /// The order in which the caller declared the rows.
55        Authored = "authored",
56        /// Left-roster position, then right-roster position, with authored order breaking equal-pair ties.
57        Canonical = "canonical",
58    }
59}
60
61crate::roster! {
62    /// Which structural question one recipe relation may answer.
63    pub(crate) enum RelationQuestion {
64        /// Whether the relation has any row.
65        Empty = "empty",
66        /// Whether an endpoint pair occurs more than once.
67        Repetition = "repetition",
68        /// Whether each endpoint roster is open or closed.
69        Membership = "membership",
70        /// Whether each endpoint roster is completely covered.
71        Completeness = "completeness",
72        /// Whether every possible endpoint pair occurs.
73        Density = "density",
74        /// What a generated operation does when no row applies.
75        Absence = "absence",
76        /// Whether a same-roster row may relate one member to itself.
77        SelfRelation = "self_relation",
78        /// Whether a same-roster directed cycle remains lawful.
79        Cycle = "cycle",
80    }
81}
82
83crate::roster! {
84    /// Whether repeated endpoint pairs remain lawful.
85    pub enum RepetitionPosture {
86        /// Repeated pairs are retained as caller-owned rows.
87        Allowed = "allowed",
88        /// Every endpoint pair must occur once.
89        Refusal = "refused",
90    }
91}
92
93crate::roster! {
94    /// Whether a relation with no row remains lawful.
95    pub enum EmptyPosture {
96        /// An empty relation remains lawful.
97        Allowed = "allowed",
98        /// At least one relation row is required.
99        Refusal = "refused",
100    }
101}
102
103crate::roster! {
104    /// Whether a declared roster is the complete membership vocabulary.
105    pub enum MembershipPosture {
106        /// Values outside the declared roster may exist, while every enumerated operation remains bounded by the stated roster.
107        Open = "open",
108        /// The declared roster is the complete membership vocabulary.
109        Closed = "closed",
110    }
111}
112
113crate::roster! {
114    /// Whether incomplete structural coverage remains lawful.
115    pub enum CompletenessPosture {
116        /// Partial coverage remains lawful.
117        Partial = "partial",
118        /// Every member under the selected question must be covered.
119        Total = "total",
120    }
121}
122
123crate::roster! {
124    /// Whether a relation may omit endpoint pairs from the full cross product.
125    pub enum DensityPosture {
126        /// Omitted endpoint pairs remain lawful.
127        Sparse = "sparse",
128        /// Every left and right endpoint pair must occur.
129        Dense = "dense",
130    }
131}
132
133crate::roster! {
134    /// What a generated operation does where no relation row applies.
135    pub enum AbsencePosture {
136        /// The caller supplies or accepts an ordinary absent case.
137        Allowed = "allowed",
138        /// An absent case is a typed refusal.
139        Refusal = "refused",
140    }
141}
142
143crate::roster! {
144    /// Whether a member may relate to itself in a same-roster relation.
145    pub enum SelfRelationPosture {
146        /// Self relations remain lawful.
147        Allowed = "allowed",
148        /// Every self relation is refused.
149        Refusal = "refused",
150    }
151}
152
153crate::roster! {
154    /// Whether a same-roster directed cycle remains lawful.
155    pub enum CyclePosture {
156        /// Directed cycles remain lawful.
157        Allowed = "allowed",
158        /// The relation must be acyclic.
159        Refusal = "refused",
160    }
161}
162
163crate::roster! {
164    /// Whether the relation holds no row or at least one.
165    pub enum OccupancyStanding {
166        /// The relation holds no row.
167        Empty = "empty",
168        /// The relation holds at least one row.
169        Populated = "populated",
170    }
171}
172
173crate::roster! {
174    /// Whether every endpoint pair occurs once or at least one pair repeats.
175    pub enum RepetitionStanding {
176        /// Every endpoint pair occurs once.
177        Distinct = "distinct",
178        /// At least one endpoint pair occurs more than once.
179        Repeated = "repeated",
180    }
181}
182
183crate::roster! {
184    /// Whether every member under one structural question is covered.
185    pub enum CompletenessStanding {
186        /// At least one member is not covered.
187        Partial = "partial",
188        /// Every member is covered.
189        Complete = "complete",
190    }
191}
192
193crate::roster! {
194    /// Whether every left and right endpoint pair occurs.
195    pub enum DensityStanding {
196        /// At least one endpoint pair is absent.
197        Sparse = "sparse",
198        /// Every endpoint pair occurs.
199        Dense = "dense",
200    }
201}
202
203crate::roster! {
204    /// Whether two relation sides borrow the same roster instance.
205    pub enum RosterRelationStanding {
206        /// Both sides borrow the same roster instance.
207        Same = "same",
208        /// The sides borrow different roster instances.
209        Cross = "cross",
210    }
211}
212
213crate::roster! {
214    /// Whether at least one same-roster row relates a member to itself.
215    pub enum SelfRelationStanding {
216        /// No row relates a member to itself.
217        Absent = "absent",
218        /// At least one row relates a member to itself.
219        Present = "present",
220    }
221}
222
223crate::roster! {
224    /// Whether one same-roster directed relation contains a cycle.
225    pub enum CycleStanding {
226        /// No directed cycle exists.
227        Acyclic = "acyclic",
228        /// At least one directed cycle exists.
229        Cyclic = "cyclic",
230    }
231}
232
233/// One caller-declared answer required of one independently computed structural answer.
234#[must_use = "a structural requirement has not been settled against an observed answer"]
235#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
236pub struct StructuralRequirement<Answer> {
237    required: Answer,
238}
239
240/// One disagreement between a caller-required answer and the answer a structural question computed.
241#[must_use = "a structural mismatch names the required and observed answers"]
242#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
243pub struct StructuralMismatch<Answer> {
244    required: Answer,
245    observed: Answer,
246}
247
248/// Which members one same-roster root can and cannot reach.
249#[must_use = "a reachability reading retains the complete reachable and unreachable position partition"]
250#[derive(Debug, Clone, PartialEq, Eq, Hash)]
251pub struct Reachability<const N: usize> {
252    reachable: NonEmpty<usize, N>,
253    unreachable: Bounded<usize, N>,
254}
255
256/// A same-roster structural question was asked of two distinct roster instances.
257#[must_use = "a same-roster refusal means the question has no lawful subject"]
258#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
259pub struct SameRosterRequired;
260
261/// How a same-roster reachability question refuses before traversal.
262#[must_use = "a reachability refusal names whether its roster or root was unavailable"]
263#[derive(Debug, Clone, PartialEq, Eq, Hash)]
264pub enum ReachabilityError<Key> {
265    /// The two relation sides borrow different roster instances.
266    DifferentRosters(SameRosterRequired),
267    /// The declared root key is outside the shared roster.
268    RootOutsideRoster {
269        /// The caller-declared root key.
270        root: Key,
271    },
272}
273
274/// One internally resolved relation row.
275#[derive(Debug, Clone, PartialEq, Eq, Hash)]
276struct ReferencedRosterRow<'rosters, Left, LeftKey, Right, RightKey, Payload> {
277    left_position: usize,
278    left_key: &'rosters LeftKey,
279    left_member: &'rosters Left,
280    right_position: usize,
281    right_key: &'rosters RightKey,
282    right_member: &'rosters Right,
283    payload: Payload,
284}
285
286/// One repeated relation pair and every authored position at which it occurred.
287#[derive(Clone, PartialEq, Eq, Hash)]
288pub struct RepeatedRelationPair<const N: usize> {
289    duplicate: DuplicateKey<RelationPair, N>,
290}
291
292/// Every distinct relation pair that occurred more than once.
293#[must_use = "a repeated-pair refusal carries every duplicated relation coordinate"]
294#[derive(Debug, Clone, PartialEq, Eq, Hash)]
295pub struct RepeatedRelationPairs<const N: usize> {
296    pairs: NonEmpty<RepeatedRelationPair<N>, N>,
297}
298
299/// How offered rows refuse reference-safe admission over two keyed rosters.
300#[derive(Debug, Clone, PartialEq, Eq, Hash)]
301pub enum KeyedRosterRowsError<LeftKey, RightKey, const N: usize> {
302    /// More rows were offered than the declared row ceiling admits.
303    Overflow(crate::bounded::Overflow),
304    /// One or more rows name a key outside the left roster.
305    ForeignLeft(NonEmpty<ForeignRosterReference<LeftKey>, N>),
306    /// One or more rows name a key outside the right roster.
307    ForeignRight(NonEmpty<ForeignRosterReference<RightKey>, N>),
308}
309
310struct ResolvedRosterMember<'roster, Member, Key> {
311    position: usize,
312    key: &'roster Key,
313    member: &'roster Member,
314}
315
316struct CanonicalRelationPosition {
317    authored: usize,
318    left: usize,
319    right: usize,
320}
321
322#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
323struct RelationPair {
324    left: usize,
325    right: usize,
326}
327
328enum RowResolutionError<Key, const N: usize> {
329    Overflow(crate::bounded::Overflow),
330    Foreign(NonEmpty<ForeignRosterReference<Key>, N>),
331}