//! Fold protocol โ responsive conformations.
//!
//! Per prysm/layout.md ยง4.3, every molecule defines `F` = ordered set of
//! conformations:
//!
//! `F = {l_1, l_2, ..., l_k}` where `w_min(l_1) > w_min(l_2) > ... > w_min(l_k)`
//!
//! Selection at runtime:
//!
//! `l* = l_i where i = min{j : w_min(l_j) โค c_w}`
//!
//! Theorem 6 (derived in spec ยง4.3a): for a stack with `m` organelles each
//! with importance `ฯ*_i` and width `w_i`, the optimal fold set is computed
//! in `O(m log m)` by greedily removing the least important remaining
//! organelle.
/// One layout conformation in a fold set. Includes a subset of children
/// (by their indices in the parent's `Element.children` Vec) and the
/// minimum constraint width at which this conformation fits.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Conformation {
/// Indices into the parent `Element::children` Vec for the children
/// included in this conformation. Indices preserve original order.
pub child_indices: Vec<usize>,
/// Minimum main-axis constraint at which this conformation fits, in quanta.
pub w_min: u32,
}
/// Ordered fold set โ conformations from widest to narrowest by `w_min`.
#[derive(Debug, Clone, Default)]
pub struct FoldSet {
/// Conformations ordered by decreasing `w_min`. Index 0 is the widest
/// (full set); the last index is the narrowest (smallest subset).
pub conformations: Vec<Conformation>,
}
impl FoldSet {
/// Select the active conformation for a constraint of width `c_w`.
///
/// Returns the index of the conformation whose `w_min โค c_w` and is
/// the widest among those that fit. Per spec ยง4.3: `i = min{j : w_min(l_j) โค c_w}`
/// when conformations are ordered widest-first (decreasing w_min).
///
/// If no conformation fits, returns the narrowest available
/// (caller's choice: clip, scroll, or render best-effort).
pub fn select(&self, c_w: u32) -> usize {
for (i, conf) in self.conformations.iter().enumerate() {
if conf.w_min <= c_w {
return i;
}
}
self.conformations.len().saturating_sub(1)
}
/// Return the active conformation by reference, if any exist.
pub fn active(&self, c_w: u32) -> Option<&Conformation> {
if self.conformations.is_empty() {
None
} else {
Some(&self.conformations[self.select(c_w)])
}
}
/// Derive an optimal fold set per spec Theorem 6.
///
/// `widths[i]` is the main-axis width of organelle i in quanta.
/// `importances[i]` is the scalar importance `ฯ*_i` (e.g. cyberank,
/// focus, or manual priority). `gap` is the inter-organelle gap.
///
/// Returns m conformations: l_1 includes all; l_{j+1} = l_j minus the
/// least important remaining organelle; l_m has just the single most
/// important organelle.
///
/// Panics if `widths.len() != importances.len()`.
pub fn derive_optimal(widths: &[u32], importances: &[f32], gap: u32) -> Self {
assert_eq!(
widths.len(),
importances.len(),
"widths and importances must have the same length"
);
let m = widths.len();
if m == 0 {
return Self::default();
}
// Sort original indices by importance ascending (least important first).
let mut indices_by_imp: Vec<usize> = (0..m).collect();
indices_by_imp.sort_by(|&a, &b| {
importances[a]
.partial_cmp(&importances[b])
.unwrap_or(std::cmp::Ordering::Equal)
});
// l_1 = full set, w_min = ฮฃ widths + (m-1)*gap.
let mut current: Vec<usize> = (0..m).collect();
let mut current_w_min: u32 = widths
.iter()
.sum::<u32>()
.saturating_add(gap.saturating_mul((m as u32).saturating_sub(1)));
let mut conformations: Vec<Conformation> = Vec::with_capacity(m);
conformations.push(Conformation {
child_indices: current.clone(),
w_min: current_w_min,
});
// Greedy: remove least important remaining organelle.
for j in 0..m.saturating_sub(1) {
let to_remove = indices_by_imp[j];
current.retain(|&i| i != to_remove);
current_w_min = current_w_min
.saturating_sub(widths[to_remove])
.saturating_sub(gap);
conformations.push(Conformation {
child_indices: current.clone(),
w_min: current_w_min,
});
}
Self { conformations }
}
/// Build a fold set manually from explicit conformations. The caller
/// must ensure they are ordered by decreasing `w_min`.
pub fn from_conformations(conformations: Vec<Conformation>) -> Self {
Self { conformations }
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn derive_optimal_with_three_organelles() {
// 3 organelles with widths [10, 20, 30] and importances [1, 2, 3].
// Sorted by importance ascending: indices [0, 1, 2].
// Conformations:
// l_1: {0,1,2}, w_min = 10+20+30 + 2*gap
// l_2: {1,2}, w_min = 20+30 + 1*gap (removed 0)
// l_3: {2}, w_min = 30 + 0*gap (removed 1)
let fs = FoldSet::derive_optimal(&[10, 20, 30], &[1.0, 2.0, 3.0], 2);
assert_eq!(fs.conformations.len(), 3);
assert_eq!(fs.conformations[0].child_indices, vec![0, 1, 2]);
assert_eq!(fs.conformations[0].w_min, 10 + 20 + 30 + 2 * 2);
assert_eq!(fs.conformations[1].child_indices, vec![1, 2]);
assert_eq!(fs.conformations[1].w_min, 20 + 30 + 2);
assert_eq!(fs.conformations[2].child_indices, vec![2]);
assert_eq!(fs.conformations[2].w_min, 30);
}
#[test]
fn select_picks_widest_that_fits() {
let fs = FoldSet::derive_optimal(&[10, 20, 30], &[1.0, 2.0, 3.0], 2);
// c_w = 100: l_1 (w_min=64) fits.
assert_eq!(fs.select(100), 0);
// c_w = 50: l_2 (w_min=52) does not fit, l_3 (w_min=30) fits.
assert_eq!(fs.select(50), 2);
// c_w = 52: l_2 just fits.
assert_eq!(fs.select(52), 1);
// c_w = 30: only l_3 fits.
assert_eq!(fs.select(30), 2);
// c_w = 10: nothing fits; returns narrowest.
assert_eq!(fs.select(10), 2);
}
#[test]
fn derive_optimal_handles_equal_importance() {
// When importances tie, sort is stable in std (for the tie-break we
// rely on stable sort of (importance, index) โ but partial_cmp may
// not be strictly stable). Just verify the algorithm doesn't crash
// and produces a valid fold set.
let fs = FoldSet::derive_optimal(&[10, 10, 10], &[1.0, 1.0, 1.0], 1);
assert_eq!(fs.conformations.len(), 3);
assert_eq!(fs.conformations[0].child_indices.len(), 3);
assert_eq!(fs.conformations[2].child_indices.len(), 1);
}
#[test]
fn empty_input_yields_empty_fold_set() {
let fs = FoldSet::derive_optimal(&[], &[], 0);
assert!(fs.conformations.is_empty());
assert!(fs.active(100).is_none());
}
#[test]
fn single_organelle_yields_one_conformation() {
let fs = FoldSet::derive_optimal(&[10], &[1.0], 0);
assert_eq!(fs.conformations.len(), 1);
assert_eq!(fs.conformations[0].child_indices, vec![0]);
assert_eq!(fs.conformations[0].w_min, 10);
}
#[test]
fn theorem6_invariant_widths_decrease() {
// Spec invariant: conformations ordered by decreasing w_min.
let fs = FoldSet::derive_optimal(&[5, 10, 15, 20], &[4.0, 3.0, 2.0, 1.0], 1);
for i in 1..fs.conformations.len() {
assert!(
fs.conformations[i - 1].w_min > fs.conformations[i].w_min,
"conformations must have strictly decreasing w_min"
);
}
}
}
//! Fold protocol โ responsive conformations.
//!
//! Per prysm/layout.md ยง4.3, every molecule defines `F` = ordered set of
//! conformations:
//!
//! `F = {l_1, l_2, ..., l_k}` where `w_min(l_1) > w_min(l_2) > ... > w_min(l_k)`
//!
//! Selection at runtime:
//!
//! `l* = l_i where i = min{j : w_min(l_j) โค c_w}`
//!
//! Theorem 6 (derived in spec ยง4.3a): for a stack with `m` organelles each
//! with importance `ฯ*_i` and width `w_i`, the optimal fold set is computed
//! in `O(m log m)` by greedily removing the least important remaining
//! organelle.
/// One layout conformation in a fold set. Includes a subset of children
/// (by their indices in the parent's `Element.children` Vec) and the
/// minimum constraint width at which this conformation fits.
/// Ordered fold set โ conformations from widest to narrowest by `w_min`.