Skip to main content

pattern_core/pattern/
core.rs

1//! Pattern type definition
2//!
3//! This module provides the core `Pattern<V>` type, a recursive, nested structure
4//! (s-expression-like) that is generic over value type `V`.
5//!
6//! # Construction Functions
7//!
8//! - [`Pattern::point`] - Creates an atomic pattern from a value (special case, matches gram-hs API)
9//! - [`Pattern::pattern`] - Creates a pattern with elements (primary constructor, matches gram-hs API)
10//! - [`Pattern::from_list`] - Creates a pattern from a list of values
11//!
12//! # Accessor Methods
13//!
14//! - [`Pattern::value`] - Returns a reference to the pattern's value
15//! - [`Pattern::elements`] - Returns a slice of the pattern's elements
16//!
17//! # Inspection Utilities
18//!
19//! - [`Pattern::length`] - Returns the number of direct elements
20//! - [`Pattern::size`] - Returns the total number of nodes
21//! - [`Pattern::depth`] - Returns the maximum nesting depth
22//! - [`Pattern::is_atomic`] - Checks if a pattern is atomic
23//! - [`Pattern::values`] - Extracts all values as a flat list (pre-order)
24//!
25//! # Query Functions
26//!
27//! - [`Pattern::any_value`] - Checks if at least one value satisfies a predicate (short-circuits)
28//! - [`Pattern::all_values`] - Checks if all values satisfy a predicate (short-circuits)
29//! - [`Pattern::filter`] - Extracts subpatterns that satisfy a pattern predicate
30//! - [`Pattern::find_first`] - Finds the first subpattern that satisfies a pattern predicate (short-circuits)
31//! - [`Pattern::matches`] - Checks if two patterns have identical structure
32//! - [`Pattern::contains`] - Checks if a pattern contains another as a subpattern
33//!
34//! # Combination Operations
35//!
36//! - [`Pattern::combine`] - Combines two patterns associatively (value combination + element concatenation)
37
38use std::cmp::Ordering;
39use std::fmt;
40use std::hash::{Hash, Hasher};
41
42/// A recursive, nested structure (s-expression-like) that is generic over value type `V`.
43///
44/// The value provides "information about the elements" - they form an intimate pairing.
45/// Elements are themselves patterns, creating the recursive structure.
46///
47/// Patterns are s-expression-like structures, not trees, though they may appear tree-like
48/// and accept tree-like operations.
49///
50/// # Examples
51///
52/// ## Creating a simple pattern
53///
54/// ```rust
55/// use pattern_core::Pattern;
56///
57/// let pattern = Pattern {
58///     value: "hello".to_string(),
59///     elements: vec![],
60/// };
61/// ```
62///
63/// ## Creating a nested pattern
64///
65/// ```rust
66/// use pattern_core::Pattern;
67///
68/// let nested = Pattern {
69///     value: "parent".to_string(),
70///     elements: vec![
71///         Pattern {
72///             value: "child1".to_string(),
73///             elements: vec![],
74///         },
75///         Pattern {
76///             value: "child2".to_string(),
77///             elements: vec![],
78///         },
79///     ],
80/// };
81/// ```
82///
83/// ## Using with Subject type
84///
85/// ```rust
86/// use pattern_core::{Pattern, Subject, Symbol};
87/// use std::collections::HashSet;
88///
89/// let subject = Subject {
90///     identity: Symbol("n".to_string()),
91///     labels: HashSet::new(),
92///     properties: std::collections::HashMap::new(),
93/// };
94///
95/// let pattern: Pattern<Subject> = Pattern {
96///     value: subject,
97///     elements: vec![],
98/// };
99/// ```
100///
101/// # Trait Implementations
102///
103/// - `Clone`: Patterns can be cloned when `V: Clone`
104/// - `PartialEq`, `Eq`: Patterns can be compared for equality when `V: PartialEq` (or `Eq`)
105/// - `PartialOrd`, `Ord`: Patterns can be ordered when `V: PartialOrd` (or `Ord`)
106///   - Uses value-first lexicographic ordering: compares values, then elements
107///   - Enables sorting, min/max operations, and use in ordered collections (BTreeSet, BTreeMap)
108/// - `Hash`: Patterns can be hashed when `V: Hash` for use in HashMap/HashSet
109///   - Enables pattern deduplication and caching
110///   - Structure-preserving: different structures produce different hashes
111///   - Note: `Pattern<Subject>` is NOT hashable (Subject contains f64)
112/// - `Debug`: Structured representation for debugging (with truncation for deep nesting)
113/// - `Display`: Human-readable representation
114///
115/// # Performance
116///
117/// Patterns support:
118/// - At least 100 nesting levels without stack overflow
119/// - At least 10,000 elements efficiently
120/// - WASM compilation for web applications
121#[derive(Clone, PartialEq, Eq)]
122pub struct Pattern<V> {
123    /// The value component, which provides information about the elements.
124    ///
125    /// The value and elements form an intimate pairing where the value provides
126    /// "information about the elements".
127    pub value: V,
128
129    /// The nested collection of patterns that form the recursive structure.
130    ///
131    /// Elements are themselves `Pattern<V>`, creating the recursive nested structure.
132    /// An empty vector represents an atomic pattern (a pattern with no nested elements).
133    pub elements: Vec<Pattern<V>>,
134}
135
136/// Configurable validation rules for pattern structure.
137///
138/// Rules can specify limits on nesting depth, element counts, or other structural properties.
139/// Rules are optional (None means no limit).
140///
141/// # Examples
142///
143/// ```
144/// use pattern_core::ValidationRules;
145///
146/// // No constraints (all patterns valid)
147/// let rules = ValidationRules::default();
148///
149/// // Maximum depth constraint
150/// let rules = ValidationRules {
151///     max_depth: Some(10),
152///     ..Default::default()
153/// };
154/// ```
155#[derive(Debug, Clone, Default)]
156pub struct ValidationRules {
157    /// Maximum nesting depth allowed (None = no limit)
158    pub max_depth: Option<usize>,
159    /// Maximum element count allowed (None = no limit)
160    pub max_elements: Option<usize>,
161    /// Required fields (reserved for future value-specific validation)
162    pub required_fields: Vec<String>,
163}
164
165/// Error type for pattern validation failures.
166///
167/// Provides detailed information about what rule was violated and where
168/// in the pattern structure the violation occurred.
169///
170/// # Examples
171///
172/// ```
173/// use pattern_core::ValidationError;
174///
175/// let error = ValidationError {
176///     message: "Pattern depth exceeds maximum".to_string(),
177///     rule_violated: "max_depth".to_string(),
178///     location: vec!["elements".to_string(), "0".to_string()],
179/// };
180/// ```
181#[derive(Debug, Clone, PartialEq, Eq)]
182pub struct ValidationError {
183    /// Human-readable error message
184    pub message: String,
185    /// Name of violated rule (e.g., "max_depth", "max_elements")
186    pub rule_violated: String,
187    /// Path to violating node in pattern structure
188    pub location: Vec<String>,
189}
190
191/// Results from structure analysis utilities.
192///
193/// Provides detailed information about pattern structural characteristics
194/// including depth distribution, element counts, nesting patterns, and summaries.
195///
196/// # Examples
197///
198/// ```
199/// use pattern_core::{Pattern, StructureAnalysis};
200///
201/// let pattern = Pattern::pattern("root".to_string(), vec![/* ... */]);
202/// let analysis = pattern.analyze_structure();
203///
204/// println!("Depth distribution: {:?}", analysis.depth_distribution);
205/// println!("Summary: {}", analysis.summary);
206/// ```
207#[derive(Debug, Clone)]
208pub struct StructureAnalysis {
209    /// Count of nodes at each depth level (index = depth, value = count)
210    pub depth_distribution: Vec<usize>,
211    /// Element counts at each level (index = level, value = count)
212    pub element_counts: Vec<usize>,
213    /// Identified structural patterns (e.g., "linear", "tree", "balanced")
214    pub nesting_patterns: Vec<String>,
215    /// Human-readable summary of structure
216    pub summary: String,
217}
218
219impl<V: fmt::Debug> Pattern<V> {
220    fn fmt_debug_with_depth(
221        &self,
222        f: &mut fmt::Formatter<'_>,
223        depth: usize,
224        max_depth: usize,
225    ) -> fmt::Result {
226        if depth > max_depth {
227            return write!(f, "...");
228        }
229
230        f.debug_struct("Pattern")
231            .field("value", &self.value)
232            .field(
233                "elements",
234                &DebugElements {
235                    elements: &self.elements,
236                    depth,
237                    max_depth,
238                },
239            )
240            .finish()
241    }
242}
243
244impl<V: fmt::Debug> fmt::Debug for Pattern<V> {
245    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
246        self.fmt_debug_with_depth(f, 0, 10) // Max depth of 10 for truncation
247    }
248}
249
250struct DebugElements<'a, V> {
251    elements: &'a Vec<Pattern<V>>,
252    depth: usize,
253    max_depth: usize,
254}
255
256impl<'a, V: fmt::Debug> fmt::Debug for DebugElements<'a, V> {
257    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
258        if self.depth > self.max_depth {
259            return write!(f, "[...]");
260        }
261
262        let mut list = f.debug_list();
263        for (i, elem) in self.elements.iter().enumerate() {
264            if i >= 5 && self.elements.len() > 10 {
265                // Truncate if more than 10 elements
266                list.entry(&format_args!("... ({} more)", self.elements.len() - 5));
267                break;
268            }
269            list.entry(&DebugPattern {
270                pattern: elem,
271                depth: self.depth + 1,
272                max_depth: self.max_depth,
273            });
274        }
275        list.finish()
276    }
277}
278
279struct DebugPattern<'a, V> {
280    pattern: &'a Pattern<V>,
281    depth: usize,
282    max_depth: usize,
283}
284
285impl<'a, V: fmt::Debug> fmt::Debug for DebugPattern<'a, V> {
286    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
287        self.pattern
288            .fmt_debug_with_depth(f, self.depth, self.max_depth)
289    }
290}
291
292impl<V: fmt::Display> Pattern<V> {
293    fn fmt_display_with_depth(
294        &self,
295        f: &mut fmt::Formatter<'_>,
296        depth: usize,
297        max_depth: usize,
298    ) -> fmt::Result {
299        if depth > max_depth {
300            return write!(f, "...");
301        }
302
303        write!(f, "(")?;
304        write!(f, "{}", self.value)?;
305
306        if !self.elements.is_empty() {
307            write!(f, " ")?;
308            for (i, elem) in self.elements.iter().enumerate() {
309                if i > 0 {
310                    write!(f, " ")?;
311                }
312                if i >= 5 && self.elements.len() > 10 {
313                    write!(f, "... ({} more)", self.elements.len() - 5)?;
314                    break;
315                }
316                elem.fmt_display_with_depth(f, depth + 1, max_depth)?;
317            }
318        }
319
320        write!(f, ")")
321    }
322}
323
324impl<V: fmt::Display> fmt::Display for Pattern<V> {
325    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
326        self.fmt_display_with_depth(f, 0, 10) // Max depth of 10 for truncation
327    }
328}
329
330// Construction Functions
331
332impl<V> Pattern<V> {
333    /// Creates an atomic pattern (a pattern with no elements) from a value.
334    ///
335    /// This is the special case constructor for atomic patterns.
336    /// Equivalent to gram-hs `point :: v -> Pattern v`.
337    ///
338    /// # Arguments
339    ///
340    /// * `value` - The value component of the pattern
341    ///
342    /// # Returns
343    ///
344    /// A new atomic `Pattern<V>` instance with the specified value and empty elements.
345    ///
346    /// # Examples
347    ///
348    /// ```
349    /// use pattern_core::Pattern;
350    ///
351    /// let atomic = Pattern::point("atom".to_string());
352    /// assert_eq!(atomic.value, "atom");
353    /// assert_eq!(atomic.elements.len(), 0);
354    /// ```
355    pub fn point(value: V) -> Self {
356        Pattern {
357            value,
358            elements: vec![],
359        }
360    }
361
362    /// Creates a pattern with a value and elements.
363    ///
364    /// This is the primary constructor for creating patterns. Takes a decoration value
365    /// and a list of pattern elements. The elements form the pattern itself; the value
366    /// provides decoration about that pattern.
367    ///
368    /// Equivalent to gram-hs `pattern :: v -> [Pattern v] -> Pattern v`.
369    ///
370    /// # Arguments
371    ///
372    /// * `value` - The value component of the pattern
373    /// * `elements` - The nested collection of patterns
374    ///
375    /// # Returns
376    ///
377    /// A new `Pattern<V>` instance with the specified value and elements.
378    ///
379    /// # Examples
380    ///
381    /// ```
382    /// use pattern_core::Pattern;
383    ///
384    /// let pattern = Pattern::pattern("root".to_string(), vec![
385    ///     Pattern::point("child".to_string()),
386    /// ]);
387    /// assert_eq!(pattern.value, "root");
388    /// assert_eq!(pattern.elements.len(), 1);
389    /// ```
390    #[allow(clippy::self_named_constructors)]
391    pub fn pattern(value: V, elements: Vec<Pattern<V>>) -> Self {
392        Pattern { value, elements }
393    }
394
395    /// Creates a pattern from a list of values.
396    ///
397    /// Creates a pattern where the first argument is the decoration value,
398    /// and the list of values are converted to atomic patterns and used as elements.
399    /// Equivalent to gram-hs `fromList :: v -> [v] -> Pattern v`.
400    ///
401    /// # Arguments
402    ///
403    /// * `value` - The decoration value for the pattern
404    /// * `values` - List of values to convert to atomic patterns as elements
405    ///
406    /// # Returns
407    ///
408    /// A new `Pattern<V>` instance with value as decoration and values converted to atomic patterns as elements.
409    ///
410    /// # Examples
411    ///
412    /// ```
413    /// use pattern_core::Pattern;
414    ///
415    /// let pattern = Pattern::from_list("root".to_string(), vec![
416    ///     "a".to_string(),
417    ///     "b".to_string(),
418    ///     "c".to_string(),
419    /// ]);
420    /// assert_eq!(pattern.value, "root");
421    /// assert_eq!(pattern.elements.len(), 3);
422    /// ```
423    pub fn from_list(value: V, values: Vec<V>) -> Self {
424        Pattern {
425            value,
426            elements: values.into_iter().map(Pattern::point).collect(),
427        }
428    }
429
430    /// Returns a reference to the pattern's value component.
431    ///
432    /// Equivalent to gram-hs `value :: Pattern v -> v` (record field accessor).
433    ///
434    /// # Returns
435    ///
436    /// An immutable reference to the pattern's value.
437    ///
438    /// # Examples
439    ///
440    /// ```
441    /// use pattern_core::Pattern;
442    ///
443    /// let pattern = Pattern::point("hello".to_string());
444    /// let value = pattern.value(); // &String
445    /// assert_eq!(value, "hello");
446    /// ```
447    pub fn value(&self) -> &V {
448        &self.value
449    }
450
451    /// Returns a slice of the pattern's elements.
452    ///
453    /// Equivalent to gram-hs `elements :: Pattern v -> [Pattern v]` (record field accessor).
454    ///
455    /// # Returns
456    ///
457    /// An immutable slice of the pattern's nested elements.
458    ///
459    /// # Examples
460    ///
461    /// ```
462    /// use pattern_core::Pattern;
463    ///
464    /// let pattern = Pattern::pattern("parent".to_string(), vec![
465    ///     Pattern::point("child1".to_string()),
466    ///     Pattern::point("child2".to_string()),
467    /// ]);
468    /// let elements = pattern.elements();
469    /// assert_eq!(elements.len(), 2);
470    /// ```
471    pub fn elements(&self) -> &[Pattern<V>] {
472        &self.elements
473    }
474
475    /// Returns the number of direct elements in a pattern's sequence.
476    ///
477    /// Equivalent to gram-hs `length :: Pattern v -> Int`.
478    ///
479    /// # Returns
480    ///
481    /// The number of direct elements (not nested).
482    ///
483    /// # Examples
484    ///
485    /// ```
486    /// use pattern_core::Pattern;
487    ///
488    /// let pattern = Pattern::pattern("parent".to_string(), vec![
489    ///     Pattern::point("child1".to_string()),
490    ///     Pattern::point("child2".to_string()),
491    /// ]);
492    /// assert_eq!(pattern.length(), 2);
493    /// ```
494    pub fn length(&self) -> usize {
495        self.elements.len()
496    }
497
498    /// Returns the total number of nodes in a pattern structure, including all nested patterns.
499    ///
500    /// Equivalent to gram-hs `size :: Pattern v -> Int`.
501    ///
502    /// # Returns
503    ///
504    /// The total number of nodes (root + all nested nodes).
505    ///
506    /// # Examples
507    ///
508    /// ```
509    /// use pattern_core::Pattern;
510    ///
511    /// let atomic = Pattern::point("atom".to_string());
512    /// assert_eq!(atomic.size(), 1);
513    ///
514    /// let pattern = Pattern::pattern("root".to_string(), vec![
515    ///     Pattern::point("child1".to_string()),
516    ///     Pattern::point("child2".to_string()),
517    /// ]);
518    /// assert_eq!(pattern.size(), 3); // root + 2 children
519    /// ```
520    pub fn size(&self) -> usize {
521        1 + self.elements.iter().map(|e| e.size()).sum::<usize>()
522    }
523
524    /// Returns the maximum nesting depth of a pattern structure.
525    ///
526    /// Equivalent to gram-hs `depth :: Pattern v -> Int`.
527    ///
528    /// # Returns
529    ///
530    /// The maximum nesting depth. Atomic patterns (patterns with no elements) have depth 0.
531    ///
532    /// # Examples
533    ///
534    /// ```
535    /// use pattern_core::Pattern;
536    ///
537    /// let atomic = Pattern::point("hello".to_string());
538    /// assert_eq!(atomic.depth(), 0); // Atomic patterns have depth 0
539    ///
540    /// let nested = Pattern::pattern("parent".to_string(), vec![
541    ///     Pattern::pattern("child".to_string(), vec![
542    ///         Pattern::point("grandchild".to_string()),
543    ///     ]),
544    /// ]);
545    /// assert_eq!(nested.depth(), 2);
546    /// ```
547    pub fn depth(&self) -> usize {
548        if self.elements.is_empty() {
549            0
550        } else {
551            1 + self.elements.iter().map(|e| e.depth()).max().unwrap_or(0)
552        }
553    }
554
555    /// Checks if a pattern is atomic (has no elements).
556    ///
557    /// This is a convenience helper for pattern classification.
558    ///
559    /// # Returns
560    ///
561    /// `true` if the pattern has no elements, `false` otherwise.
562    ///
563    /// # Examples
564    ///
565    /// ```
566    /// use pattern_core::Pattern;
567    ///
568    /// let atomic = Pattern::point("hello".to_string());
569    /// assert!(atomic.is_atomic());
570    ///
571    /// let nested = Pattern::pattern("parent".to_string(), vec![
572    ///     Pattern::point("child".to_string()),
573    /// ]);
574    /// assert!(!nested.is_atomic());
575    /// ```
576    pub fn is_atomic(&self) -> bool {
577        self.elements.is_empty()
578    }
579
580    /// Checks if at least one value in the pattern satisfies the given predicate.
581    ///
582    /// This operation traverses the pattern structure in pre-order (root first, then elements)
583    /// and applies the predicate to each value. Returns `true` as soon as a value satisfies
584    /// the predicate (short-circuit evaluation - both predicate evaluation AND traversal stop),
585    /// or `false` if no values match.
586    ///
587    /// Equivalent to Haskell's `anyValue :: (v -> Bool) -> Pattern v -> Bool`.
588    ///
589    /// # Type Parameters
590    ///
591    /// * `F` - A function that takes a reference to a value and returns a boolean
592    ///
593    /// # Arguments
594    ///
595    /// * `predicate` - A function to test each value
596    ///
597    /// # Returns
598    ///
599    /// * `true` if at least one value satisfies the predicate
600    /// * `false` if no values satisfy the predicate (including empty patterns)
601    ///
602    /// # Complexity
603    ///
604    /// * Time: O(n) worst case, O(1) to O(n) average (short-circuits on first match)
605    /// * Space: O(1) heap, O(d) stack where d = maximum depth
606    ///
607    /// # Examples
608    ///
609    /// ```
610    /// use pattern_core::Pattern;
611    ///
612    /// let pattern = Pattern::pattern(5, vec![
613    ///     Pattern::point(10),
614    ///     Pattern::point(3),
615    /// ]);
616    ///
617    /// // Check if any value is greater than 8
618    /// assert!(pattern.any_value(|v| *v > 8));  // true (10 > 8)
619    ///
620    /// // Check if any value is negative
621    /// assert!(!pattern.any_value(|v| *v < 0)); // false (all positive)
622    /// ```
623    ///
624    /// # Short-Circuit Behavior
625    ///
626    /// The operation stops traversal as soon as a matching value is found:
627    ///
628    /// ```
629    /// use pattern_core::Pattern;
630    ///
631    /// let pattern = Pattern::pattern(1, vec![
632    ///     Pattern::point(2),
633    ///     Pattern::point(5), // Matches here - stops traversal
634    ///     Pattern::point(3), // Not visited
635    /// ]);
636    ///
637    /// assert!(pattern.any_value(|v| *v == 5));
638    /// ```
639    pub fn any_value<F>(&self, predicate: F) -> bool
640    where
641        F: Fn(&V) -> bool,
642    {
643        self.any_value_recursive(&predicate)
644    }
645
646    /// Helper function for any_value with early termination.
647    fn any_value_recursive<F>(&self, predicate: &F) -> bool
648    where
649        F: Fn(&V) -> bool,
650    {
651        // Check current value (pre-order)
652        if predicate(&self.value) {
653            return true;
654        }
655
656        // Check elements recursively, stop on first match
657        for element in &self.elements {
658            if element.any_value_recursive(predicate) {
659                return true;
660            }
661        }
662
663        false
664    }
665
666    /// Checks if all values in the pattern satisfy the given predicate.
667    ///
668    /// This operation traverses the pattern structure in pre-order (root first, then elements)
669    /// and applies the predicate to each value. Returns `false` as soon as a value is found
670    /// that does not satisfy the predicate (short-circuit evaluation - both predicate evaluation
671    /// AND traversal stop), or `true` if all values satisfy the predicate.
672    ///
673    /// Equivalent to Haskell's `allValues :: (v -> Bool) -> Pattern v -> Bool`.
674    ///
675    /// # Type Parameters
676    ///
677    /// * `F` - A function that takes a reference to a value and returns a boolean
678    ///
679    /// # Arguments
680    ///
681    /// * `predicate` - A function to test each value
682    ///
683    /// # Returns
684    ///
685    /// * `true` if all values satisfy the predicate (vacuous truth for patterns with no values)
686    /// * `false` if at least one value does not satisfy the predicate
687    ///
688    /// # Complexity
689    ///
690    /// * Time: O(n) worst case, O(1) to O(n) average (short-circuits on first failure)
691    /// * Space: O(1) heap, O(d) stack where d = maximum depth
692    ///
693    /// # Examples
694    ///
695    /// ```
696    /// use pattern_core::Pattern;
697    ///
698    /// let pattern = Pattern::pattern(5, vec![
699    ///     Pattern::point(10),
700    ///     Pattern::point(3),
701    /// ]);
702    ///
703    /// // Check if all values are positive
704    /// assert!(pattern.all_values(|v| *v > 0));  // true (all > 0)
705    ///
706    /// // Check if all values are greater than 8
707    /// assert!(!pattern.all_values(|v| *v > 8)); // false (5 and 3 fail)
708    /// ```
709    ///
710    /// # Short-Circuit Behavior
711    ///
712    /// The operation stops traversal as soon as a non-matching value is found:
713    ///
714    /// ```
715    /// use pattern_core::Pattern;
716    ///
717    /// let pattern = Pattern::pattern(1, vec![
718    ///     Pattern::point(2),
719    ///     Pattern::point(-5), // Fails here - stops traversal
720    ///     Pattern::point(3),  // Not visited
721    /// ]);
722    ///
723    /// assert!(!pattern.all_values(|v| *v > 0));
724    /// ```
725    ///
726    /// # Relationship to any_value
727    ///
728    /// The following equivalence holds: `all_values(p) ≡ !any_value(!p)`
729    ///
730    /// ```
731    /// use pattern_core::Pattern;
732    ///
733    /// let pattern = Pattern::pattern(5, vec![Pattern::point(10)]);
734    /// let predicate = |v: &i32| *v > 0;
735    ///
736    /// assert_eq!(
737    ///     pattern.all_values(predicate),
738    ///     !pattern.any_value(|v| !predicate(v))
739    /// );
740    /// ```
741    pub fn all_values<F>(&self, predicate: F) -> bool
742    where
743        F: Fn(&V) -> bool,
744    {
745        self.all_values_recursive(&predicate)
746    }
747
748    /// Helper function for all_values with early termination.
749    fn all_values_recursive<F>(&self, predicate: &F) -> bool
750    where
751        F: Fn(&V) -> bool,
752    {
753        // Check current value (pre-order)
754        if !predicate(&self.value) {
755            return false;
756        }
757
758        // Check elements recursively, stop on first failure
759        for element in &self.elements {
760            if !element.all_values_recursive(predicate) {
761                return false;
762            }
763        }
764
765        true
766    }
767
768    /// Filters subpatterns that satisfy the given pattern predicate.
769    ///
770    /// This operation traverses the pattern structure in pre-order (root first, then elements)
771    /// and collects references to all patterns that satisfy the predicate. Unlike `any_value`
772    /// and `all_values` which operate on values, this method operates on entire patterns,
773    /// allowing predicates to test structural properties (length, depth, etc.) as well as values.
774    ///
775    /// Equivalent to Haskell's `filterPatterns :: (Pattern v -> Bool) -> Pattern v -> [Pattern v]`.
776    ///
777    /// # Type Parameters
778    ///
779    /// * `F` - A function that takes a reference to a pattern and returns a boolean
780    ///
781    /// # Arguments
782    ///
783    /// * `predicate` - A function to test each pattern (including the root)
784    ///
785    /// # Returns
786    ///
787    /// A vector of immutable references to patterns that satisfy the predicate, in pre-order
788    /// traversal order. Returns an empty vector if no patterns match.
789    ///
790    /// # Complexity
791    ///
792    /// * Time: O(n) where n is the number of nodes (must visit all patterns)
793    /// * Space: O(m) heap where m is the number of matches, O(d) stack where d = maximum depth
794    ///
795    /// # Examples
796    ///
797    /// ```
798    /// use pattern_core::Pattern;
799    ///
800    /// let pattern = Pattern::pattern(
801    ///     "root",
802    ///     vec![
803    ///         Pattern::point("leaf1"),
804    ///         Pattern::pattern("branch", vec![
805    ///             Pattern::point("leaf2"),
806    ///         ]),
807    ///     ],
808    /// );
809    ///
810    /// // Find all atomic (leaf) patterns
811    /// let leaves = pattern.filter(|p| p.is_atomic());
812    /// assert_eq!(leaves.len(), 2);  // leaf1, leaf2
813    ///
814    /// // Find all patterns with specific value
815    /// let roots = pattern.filter(|p| p.value == "root");
816    /// assert_eq!(roots.len(), 1);
817    ///
818    /// // Find patterns with elements (non-atomic)
819    /// let branches = pattern.filter(|p| p.length() > 0);
820    /// assert_eq!(branches.len(), 2);  // root, branch
821    /// ```
822    ///
823    /// # Pre-Order Traversal
824    ///
825    /// Results are returned in pre-order traversal order (root first, then elements in order):
826    ///
827    /// ```
828    /// use pattern_core::Pattern;
829    ///
830    /// let pattern = Pattern::pattern(1, vec![
831    ///     Pattern::point(2),
832    ///     Pattern::pattern(3, vec![Pattern::point(4)]),
833    ///     Pattern::point(5),
834    /// ]);
835    ///
836    /// let all = pattern.filter(|_| true);
837    /// assert_eq!(all.len(), 5);
838    /// assert_eq!(all[0].value, 1); // root
839    /// assert_eq!(all[1].value, 2); // first element
840    /// assert_eq!(all[2].value, 3); // second element
841    /// assert_eq!(all[3].value, 4); // nested in second element
842    /// assert_eq!(all[4].value, 5); // third element
843    /// ```
844    ///
845    /// # Combining with Other Operations
846    ///
847    /// Filter can be combined with value predicates:
848    ///
849    /// ```
850    /// use pattern_core::Pattern;
851    ///
852    /// let pattern = Pattern::pattern(5, vec![
853    ///     Pattern::point(10),
854    ///     Pattern::pattern(3, vec![]),
855    /// ]);
856    ///
857    /// // Find patterns with large values
858    /// let large = pattern.filter(|p| p.value > 8);
859    /// assert_eq!(large.len(), 1); // Only point(10)
860    ///
861    /// // Find non-empty patterns with all values positive
862    /// let branches = pattern.filter(|p| {
863    ///     p.length() > 0 && p.all_values(|v| *v > 0)
864    /// });
865    /// ```
866    ///
867    /// # Lifetime and References
868    ///
869    /// The returned references borrow from the source pattern and have the same lifetime:
870    ///
871    /// ```
872    /// use pattern_core::Pattern;
873    ///
874    /// let pattern = Pattern::pattern("a", vec![Pattern::point("b")]);
875    /// let matches = pattern.filter(|_| true);
876    /// // matches[0] and matches[1] borrow from pattern
877    /// // Cannot move or drop pattern while matches exist
878    /// ```
879    pub fn filter<F>(&self, predicate: F) -> Vec<&Pattern<V>>
880    where
881        F: Fn(&Pattern<V>) -> bool,
882    {
883        let mut result = Vec::new();
884        self.filter_recursive(&predicate, &mut result);
885        result
886    }
887
888    /// Helper function for recursive filter implementation.
889    ///
890    /// This performs a pre-order traversal, checking the current pattern first,
891    /// then recursively filtering elements.
892    fn filter_recursive<'a, F>(&'a self, predicate: &F, result: &mut Vec<&'a Pattern<V>>)
893    where
894        F: Fn(&Pattern<V>) -> bool,
895    {
896        // Check current pattern (pre-order: root first)
897        if predicate(self) {
898            result.push(self);
899        }
900
901        // Recursively filter elements
902        for element in &self.elements {
903            element.filter_recursive(predicate, result);
904        }
905    }
906
907    /// Finds the first subpattern (including self) that satisfies a predicate.
908    ///
909    /// This method performs a depth-first pre-order traversal of the pattern structure
910    /// (checking the root first, then elements recursively from left to right) and
911    /// returns the first pattern that satisfies the predicate.
912    ///
913    /// # Arguments
914    ///
915    /// * `predicate` - A function that takes a pattern reference and returns `true`
916    ///   if it matches the search criteria. The predicate can examine both the
917    ///   pattern's value and its structure (element count, depth, etc.).
918    ///
919    /// # Returns
920    ///
921    /// * `Some(&Pattern<V>)` - A reference to the first matching pattern
922    /// * `None` - If no pattern in the structure satisfies the predicate
923    ///
924    /// # Traversal Order
925    ///
926    /// The method uses depth-first pre-order traversal:
927    /// 1. Check the root pattern first
928    /// 2. Then check elements from left to right
929    /// 3. For each element, recursively apply the same order
930    ///
931    /// This ensures consistent, predictable ordering and matches the behavior
932    /// of other pattern traversal methods (`filter`, `fold`, `map`).
933    ///
934    /// # Short-Circuit Evaluation
935    ///
936    /// Unlike `filter`, which collects all matches, `find_first` stops immediately
937    /// upon finding the first match. This makes it more efficient when you only
938    /// need to know if a match exists or when you want the first occurrence.
939    ///
940    /// # Time Complexity
941    ///
942    /// * Best case: O(1) - if root matches
943    /// * Average case: O(k) - where k is position of first match
944    /// * Worst case: O(n) - if no match exists or match is last
945    ///
946    /// # Space Complexity
947    ///
948    /// O(d) where d is the maximum nesting depth (recursion stack)
949    ///
950    /// # Examples
951    ///
952    /// ## Finding by value
953    ///
954    /// ```
955    /// use pattern_core::Pattern;
956    ///
957    /// let pattern = Pattern::pattern("root", vec![
958    ///     Pattern::point("child1"),
959    ///     Pattern::point("target"),
960    /// ]);
961    ///
962    /// let result = pattern.find_first(|p| p.value == "target");
963    /// assert!(result.is_some());
964    /// assert_eq!(result.unwrap().value, "target");
965    /// ```
966    ///
967    /// ## Finding by structure
968    ///
969    /// ```
970    /// use pattern_core::Pattern;
971    ///
972    /// let pattern = Pattern::pattern("root", vec![
973    ///     Pattern::pattern("branch", vec![
974    ///         Pattern::point("leaf"),
975    ///     ]),
976    ///     Pattern::point("leaf2"),
977    /// ]);
978    ///
979    /// // Find first atomic pattern (no elements)
980    /// let leaf = pattern.find_first(|p| p.is_atomic());
981    /// assert!(leaf.is_some());
982    /// assert_eq!(leaf.unwrap().value, "leaf");  // First in pre-order
983    /// ```
984    ///
985    /// ## No match returns None
986    ///
987    /// ```
988    /// use pattern_core::Pattern;
989    ///
990    /// let pattern = Pattern::point("single");
991    /// let result = pattern.find_first(|p| p.value == "other");
992    /// assert!(result.is_none());
993    /// ```
994    ///
995    /// ## Combining value and structural predicates
996    ///
997    /// ```
998    /// use pattern_core::Pattern;
999    ///
1000    /// let pattern = Pattern::pattern(5, vec![
1001    ///     Pattern::pattern(10, vec![
1002    ///         Pattern::point(3),
1003    ///         Pattern::point(7),
1004    ///     ]),
1005    ///     Pattern::point(15),
1006    /// ]);
1007    ///
1008    /// // Find first pattern with value > 8 AND has elements
1009    /// let result = pattern.find_first(|p| p.value > 8 && p.length() > 0);
1010    /// assert!(result.is_some());
1011    /// assert_eq!(result.unwrap().value, 10);
1012    /// ```
1013    ///
1014    /// ## Pre-order traversal demonstration
1015    ///
1016    /// ```
1017    /// use pattern_core::Pattern;
1018    ///
1019    /// let pattern = Pattern::pattern(1, vec![
1020    ///     Pattern::pattern(2, vec![
1021    ///         Pattern::point(3),
1022    ///     ]),
1023    ///     Pattern::point(4),
1024    /// ]);
1025    ///
1026    /// // Traversal order: 1 (root), 2, 3, 4
1027    /// // First pattern with value > 1 is 2 (not 3)
1028    /// let result = pattern.find_first(|p| p.value > 1);
1029    /// assert_eq!(result.unwrap().value, 2);
1030    /// ```
1031    ///
1032    /// ## Integration with other methods
1033    ///
1034    /// ```
1035    /// use pattern_core::Pattern;
1036    ///
1037    /// let pattern = Pattern::pattern(5, vec![
1038    ///     Pattern::pattern(10, vec![
1039    ///         Pattern::point(-3),
1040    ///         Pattern::point(7),
1041    ///     ]),
1042    ///     Pattern::pattern(2, vec![
1043    ///         Pattern::point(1),
1044    ///         Pattern::point(4),
1045    ///     ]),
1046    /// ]);
1047    ///
1048    /// // Find first pattern where all values are positive
1049    /// let result = pattern.find_first(|p| p.all_values(|v| *v > 0));
1050    /// assert!(result.is_some());
1051    /// assert_eq!(result.unwrap().value, 7);  // First point with all positive values
1052    /// ```
1053    ///
1054    /// # Panics
1055    ///
1056    /// This method does not panic. All inputs are valid:
1057    /// - Works with atomic patterns (no elements)
1058    /// - Works with patterns with empty elements
1059    /// - Works with deeply nested structures (limited only by stack size)
1060    /// - Handles all predicate results gracefully
1061    ///
1062    /// # Relationship to Other Methods
1063    ///
1064    /// * `filter` - Returns all matches, `find_first` returns only the first
1065    /// * `any_value` - Operates on values only, `find_first` operates on whole patterns
1066    /// * Consistency: `find_first(p).is_some()` implies `filter(p).len() > 0`
1067    /// * Consistency: If `find_first(p) == Some(x)`, then `filter(p)[0] == x`
1068    pub fn find_first<F>(&self, predicate: F) -> Option<&Pattern<V>>
1069    where
1070        F: Fn(&Pattern<V>) -> bool,
1071    {
1072        self.find_first_recursive(&predicate)
1073    }
1074
1075    /// Helper function for recursive find_first implementation.
1076    ///
1077    /// This performs a pre-order traversal with early termination.
1078    /// Checks the current pattern first, then recursively searches elements.
1079    ///
1080    /// Returns `Some(&Pattern<V>)` on first match, `None` if no match found.
1081    fn find_first_recursive<'a, F>(&'a self, predicate: &F) -> Option<&'a Pattern<V>>
1082    where
1083        F: Fn(&Pattern<V>) -> bool,
1084    {
1085        // Check current pattern first (pre-order: root first)
1086        if predicate(self) {
1087            return Some(self);
1088        }
1089
1090        // Recursively search elements (with early termination)
1091        for element in &self.elements {
1092            if let Some(found) = element.find_first_recursive(predicate) {
1093                return Some(found);
1094            }
1095        }
1096
1097        // No match found
1098        None
1099    }
1100
1101    /// Checks if two patterns have identical structure.
1102    ///
1103    /// This method performs structural equality checking, comparing both values and
1104    /// element arrangement recursively. Two patterns match if and only if:
1105    /// - Their values are equal (using `PartialEq`)
1106    /// - They have the same number of elements
1107    /// - All corresponding elements match recursively
1108    ///
1109    /// This is distinct from the `Eq` trait implementation and is intended for
1110    /// structural pattern matching operations. While currently equivalent to `==`
1111    /// for patterns where `V: Eq`, this method may diverge in the future to support
1112    /// wildcards, partial matching, or other pattern matching semantics.
1113    ///
1114    /// # Type Constraints
1115    ///
1116    /// Requires `V: PartialEq` so that values can be compared for equality.
1117    ///
1118    /// # Mathematical Properties
1119    ///
1120    /// * **Reflexive**: `p.matches(&p)` is always `true`
1121    /// * **Symmetric**: `p.matches(&q) == q.matches(&p)`
1122    /// * **Structural**: Distinguishes patterns with same values but different structures
1123    ///
1124    /// # Time Complexity
1125    ///
1126    /// * Best case: O(1) - if root values differ
1127    /// * Average case: O(min(n, m) / 2) - short-circuits on first mismatch
1128    /// * Worst case: O(min(n, m)) - if patterns are identical or differ only at end
1129    ///
1130    /// Where n and m are the number of nodes in each pattern.
1131    ///
1132    /// # Space Complexity
1133    ///
1134    /// O(min(d1, d2)) where d1 and d2 are the maximum nesting depths
1135    /// (recursion stack usage).
1136    ///
1137    /// # Examples
1138    ///
1139    /// ## Identical patterns match
1140    ///
1141    /// ```
1142    /// use pattern_core::Pattern;
1143    ///
1144    /// let p1 = Pattern::pattern("root", vec![
1145    ///     Pattern::point("a"),
1146    ///     Pattern::point("b"),
1147    /// ]);
1148    /// let p2 = Pattern::pattern("root", vec![
1149    ///     Pattern::point("a"),
1150    ///     Pattern::point("b"),
1151    /// ]);
1152    ///
1153    /// assert!(p1.matches(&p2));
1154    /// ```
1155    ///
1156    /// ## Self-matching (reflexive)
1157    ///
1158    /// ```
1159    /// use pattern_core::Pattern;
1160    ///
1161    /// let pattern = Pattern::point("a");
1162    /// assert!(pattern.matches(&pattern));
1163    /// ```
1164    ///
1165    /// ## Different values don't match
1166    ///
1167    /// ```
1168    /// use pattern_core::Pattern;
1169    ///
1170    /// let p1 = Pattern::point("a");
1171    /// let p2 = Pattern::point("b");
1172    /// assert!(!p1.matches(&p2));
1173    /// ```
1174    ///
1175    /// ## Different structures don't match
1176    ///
1177    /// ```
1178    /// use pattern_core::Pattern;
1179    ///
1180    /// let p1 = Pattern::pattern("a", vec![
1181    ///     Pattern::point("b"),
1182    ///     Pattern::point("c"),
1183    /// ]);
1184    /// let p2 = Pattern::pattern("a", vec![
1185    ///     Pattern::pattern("b", vec![
1186    ///         Pattern::point("c"),
1187    ///     ]),
1188    /// ]);
1189    ///
1190    /// // Same flattened values ["a", "b", "c"] but different structure
1191    /// assert!(!p1.matches(&p2));
1192    /// ```
1193    ///
1194    /// ## Symmetry property
1195    ///
1196    /// ```
1197    /// use pattern_core::Pattern;
1198    ///
1199    /// let p1 = Pattern::point(42);
1200    /// let p2 = Pattern::point(99);
1201    ///
1202    /// // p1.matches(&p2) == p2.matches(&p1)
1203    /// assert_eq!(p1.matches(&p2), p2.matches(&p1));
1204    /// ```
1205    ///
1206    /// # Panics
1207    ///
1208    /// This method does not panic. All inputs are valid:
1209    /// - Works with atomic patterns
1210    /// - Works with patterns with empty elements
1211    /// - Works with deeply nested structures (limited only by stack size)
1212    ///
1213    /// # Relationship to Other Methods
1214    ///
1215    /// * **Eq trait**: Currently equivalent for `V: Eq`, may diverge in future
1216    /// * **contains**: `p.matches(&q)` implies `p.contains(&q)` (equality implies containment)
1217    pub fn matches(&self, other: &Pattern<V>) -> bool
1218    where
1219        V: PartialEq,
1220    {
1221        // Values must match
1222        if self.value != other.value {
1223            return false;
1224        }
1225
1226        // Element counts must match
1227        if self.elements.len() != other.elements.len() {
1228            return false;
1229        }
1230
1231        // All corresponding elements must match recursively
1232        self.elements
1233            .iter()
1234            .zip(other.elements.iter())
1235            .all(|(e1, e2)| e1.matches(e2))
1236    }
1237
1238    /// Checks if this pattern contains another pattern as a subpattern.
1239    ///
1240    /// This method searches the entire pattern structure to determine if the given
1241    /// subpattern appears anywhere within it. A pattern contains a subpattern if:
1242    /// - The pattern matches the subpattern (using `matches`), OR
1243    /// - Any of its elements contains the subpattern (recursive search)
1244    ///
1245    /// This provides a structural containment check that goes beyond simple equality,
1246    /// allowing you to test whether a pattern appears as part of a larger structure.
1247    ///
1248    /// # Type Constraints
1249    ///
1250    /// Requires `V: PartialEq` because it uses `matches` internally for comparison.
1251    ///
1252    /// # Mathematical Properties
1253    ///
1254    /// * **Reflexive**: `p.contains(&p)` is always `true` (self-containment)
1255    /// * **Transitive**: If `a.contains(&b)` and `b.contains(&c)`, then `a.contains(&c)`
1256    /// * **Weaker than matches**: `p.matches(&q)` implies `p.contains(&q)`, but not vice versa
1257    /// * **Not symmetric**: `p.contains(&q)` does NOT imply `q.contains(&p)`
1258    ///
1259    /// # Time Complexity
1260    ///
1261    /// * Best case: O(1) - if root matches subpattern
1262    /// * Average case: O(n * m / 2) - where n = container size, m = subpattern size
1263    /// * Worst case: O(n * m) - if subpattern not found or found at end
1264    ///
1265    /// # Space Complexity
1266    ///
1267    /// O(d) where d is the maximum nesting depth (recursion stack usage).
1268    ///
1269    /// # Examples
1270    ///
1271    /// ## Self-containment
1272    ///
1273    /// ```
1274    /// use pattern_core::Pattern;
1275    ///
1276    /// let pattern = Pattern::pattern("root", vec![
1277    ///     Pattern::point("child"),
1278    /// ]);
1279    ///
1280    /// // Every pattern contains itself
1281    /// assert!(pattern.contains(&pattern));
1282    /// ```
1283    ///
1284    /// ## Direct element containment
1285    ///
1286    /// ```
1287    /// use pattern_core::Pattern;
1288    ///
1289    /// let pattern = Pattern::pattern("root", vec![
1290    ///     Pattern::point("a"),
1291    ///     Pattern::point("b"),
1292    /// ]);
1293    ///
1294    /// let subpattern = Pattern::point("a");
1295    /// assert!(pattern.contains(&subpattern));
1296    /// ```
1297    ///
1298    /// ## Nested descendant containment
1299    ///
1300    /// ```
1301    /// use pattern_core::Pattern;
1302    ///
1303    /// let pattern = Pattern::pattern("root", vec![
1304    ///     Pattern::pattern("branch", vec![
1305    ///         Pattern::point("leaf"),
1306    ///     ]),
1307    /// ]);
1308    ///
1309    /// let subpattern = Pattern::point("leaf");
1310    /// assert!(pattern.contains(&subpattern));
1311    /// ```
1312    ///
1313    /// ## Non-existent subpattern
1314    ///
1315    /// ```
1316    /// use pattern_core::Pattern;
1317    ///
1318    /// let pattern = Pattern::pattern("root", vec![
1319    ///     Pattern::point("a"),
1320    /// ]);
1321    ///
1322    /// let subpattern = Pattern::point("b");
1323    /// assert!(!pattern.contains(&subpattern));
1324    /// ```
1325    ///
1326    /// ## Transitivity
1327    ///
1328    /// ```
1329    /// use pattern_core::Pattern;
1330    ///
1331    /// let a = Pattern::pattern("a", vec![
1332    ///     Pattern::pattern("b", vec![
1333    ///         Pattern::point("c"),
1334    ///     ]),
1335    /// ]);
1336    /// let b = Pattern::pattern("b", vec![
1337    ///     Pattern::point("c"),
1338    /// ]);
1339    /// let c = Pattern::point("c");
1340    ///
1341    /// // If a contains b and b contains c, then a contains c
1342    /// assert!(a.contains(&b));
1343    /// assert!(b.contains(&c));
1344    /// assert!(a.contains(&c));  // Transitive
1345    /// ```
1346    ///
1347    /// ## Contains is weaker than matches
1348    ///
1349    /// ```
1350    /// use pattern_core::Pattern;
1351    ///
1352    /// let pattern = Pattern::pattern("root", vec![
1353    ///     Pattern::pattern("branch", vec![
1354    ///         Pattern::point("leaf"),
1355    ///     ]),
1356    /// ]);
1357    /// let subpattern = Pattern::point("leaf");
1358    ///
1359    /// // pattern contains subpattern, but they don't match
1360    /// assert!(pattern.contains(&subpattern));
1361    /// assert!(!pattern.matches(&subpattern));
1362    /// ```
1363    ///
1364    /// # Panics
1365    ///
1366    /// This method does not panic. All inputs are valid:
1367    /// - Works with atomic patterns
1368    /// - Works with patterns with empty elements
1369    /// - Works with deeply nested structures (limited only by stack size)
1370    /// - Handles multiple occurrences correctly
1371    ///
1372    /// # Relationship to Other Methods
1373    ///
1374    /// * **matches**: `p.matches(&q)` implies `p.contains(&q)`, but not vice versa
1375    /// * **Short-circuit**: Returns `true` as soon as a match is found
1376    pub fn contains(&self, subpattern: &Pattern<V>) -> bool
1377    where
1378        V: PartialEq,
1379    {
1380        // Check if this pattern matches the subpattern
1381        if self.matches(subpattern) {
1382            return true;
1383        }
1384
1385        // Recursively check if any element contains the subpattern
1386        self.elements
1387            .iter()
1388            .any(|element| element.contains(subpattern))
1389    }
1390
1391    /// Maps a function over all values in the pattern, preserving structure.
1392    ///
1393    /// This is equivalent to Haskell's `fmap` for the Functor typeclass,
1394    /// but follows Rust naming conventions. The transformation applies to
1395    /// all values recursively while preserving the pattern structure
1396    /// (number of elements, nesting depth, element order).
1397    ///
1398    /// # Functor Laws
1399    ///
1400    /// This implementation satisfies the functor laws:
1401    /// - **Identity**: `pattern.map(|x| x.clone()) == pattern`
1402    /// - **Composition**: `pattern.map(|x| g(&f(x))) == pattern.map(f).map(g)`
1403    ///
1404    /// # Type Parameters
1405    ///
1406    /// * `W` - The output value type (can be different from `V`)
1407    /// * `F` - The transformation function type
1408    ///
1409    /// # Arguments
1410    ///
1411    /// * `f` - Transformation function that takes a reference to a value (`&V`)
1412    ///   and returns a new value (`W`)
1413    ///
1414    /// # Returns
1415    ///
1416    /// A new `Pattern<W>` with the same structure but transformed values
1417    ///
1418    /// # Examples
1419    ///
1420    /// ## String transformation
1421    ///
1422    /// ```
1423    /// use pattern_core::Pattern;
1424    ///
1425    /// let pattern = Pattern::point("hello");
1426    /// let upper = pattern.map(|s| s.to_uppercase());
1427    /// assert_eq!(upper.value, "HELLO");
1428    /// ```
1429    ///
1430    /// ## Type conversion
1431    ///
1432    /// ```
1433    /// use pattern_core::Pattern;
1434    ///
1435    /// let numbers = Pattern::point(42);
1436    /// let strings = numbers.map(|n| n.to_string());
1437    /// assert_eq!(strings.value, "42");
1438    /// ```
1439    ///
1440    /// ## Nested patterns
1441    ///
1442    /// ```
1443    /// use pattern_core::Pattern;
1444    ///
1445    /// let pattern = Pattern::pattern("root", vec![
1446    ///     Pattern::point("child1"),
1447    ///     Pattern::point("child2"),
1448    /// ]);
1449    /// let upper = pattern.map(|s| s.to_uppercase());
1450    /// assert_eq!(upper.value, "ROOT");
1451    /// assert_eq!(upper.elements[0].value, "CHILD1");
1452    /// assert_eq!(upper.elements[1].value, "CHILD2");
1453    /// ```
1454    ///
1455    /// ## Composition
1456    ///
1457    /// ```
1458    /// use pattern_core::Pattern;
1459    ///
1460    /// let result = Pattern::point(5)
1461    ///     .map(|n| n * 2)
1462    ///     .map(|n| n + 1);
1463    /// assert_eq!(result.value, 11);
1464    /// ```
1465    ///
1466    /// # Performance
1467    ///
1468    /// - Time complexity: O(n) where n is the total number of nodes
1469    /// - Space complexity: O(n) for the new pattern + O(d) for recursion stack
1470    ///   where d is the maximum nesting depth
1471    /// - Handles patterns with 100+ nesting levels without stack overflow
1472    /// - Handles patterns with 10,000+ nodes efficiently
1473    pub fn map<W, F>(self, f: F) -> Pattern<W>
1474    where
1475        F: Fn(&V) -> W,
1476    {
1477        self.map_with(&f)
1478    }
1479
1480    /// Internal helper for map that takes function by reference.
1481    /// This enables efficient recursion without cloning the closure.
1482    fn map_with<W, F>(self, f: &F) -> Pattern<W>
1483    where
1484        F: Fn(&V) -> W,
1485    {
1486        Pattern {
1487            value: f(&self.value),
1488            elements: self
1489                .elements
1490                .into_iter()
1491                .map(|elem| elem.map_with(f))
1492                .collect(),
1493        }
1494    }
1495
1496    /// Folds the pattern into a single value by applying a function to each value with an accumulator.
1497    ///
1498    /// Processes values in depth-first, root-first order (pre-order traversal).
1499    /// The root value is processed first, then elements are processed left to right, recursively.
1500    /// Each value in the pattern is processed exactly once, and the accumulator is threaded through
1501    /// all processing steps.
1502    ///
1503    /// # Type Parameters
1504    ///
1505    /// * `B` - The accumulator type (can be different from `V`)
1506    /// * `F` - The folding function type
1507    ///
1508    /// # Arguments
1509    ///
1510    /// * `init` - Initial accumulator value
1511    /// * `f` - Folding function with signature `Fn(B, &V) -> B`
1512    ///   - First parameter: Accumulator (passed by value)
1513    ///   - Second parameter: Value reference (borrowed from pattern)
1514    ///   - Returns: New accumulator value
1515    ///
1516    /// # Returns
1517    ///
1518    /// The final accumulated value of type `B`
1519    ///
1520    /// # Examples
1521    ///
1522    /// ## Sum all integers
1523    ///
1524    /// ```
1525    /// use pattern_core::Pattern;
1526    ///
1527    /// let pattern = Pattern::pattern(10, vec![
1528    ///     Pattern::point(20),
1529    ///     Pattern::point(30),
1530    /// ]);
1531    /// let sum = pattern.fold(0, |acc, v| acc + v);
1532    /// assert_eq!(sum, 60);  // 10 + 20 + 30
1533    /// ```
1534    ///
1535    /// ## Count values
1536    ///
1537    /// ```
1538    /// use pattern_core::Pattern;
1539    ///
1540    /// let pattern = Pattern::pattern("root", vec![
1541    ///     Pattern::point("child1"),
1542    ///     Pattern::point("child2"),
1543    /// ]);
1544    /// let count = pattern.fold(0, |acc, _| acc + 1);
1545    /// assert_eq!(count, 3);  // root + 2 children
1546    /// assert_eq!(count, pattern.size());
1547    /// ```
1548    ///
1549    /// ## Concatenate strings
1550    ///
1551    /// ```
1552    /// use pattern_core::Pattern;
1553    ///
1554    /// let pattern = Pattern::pattern("Hello", vec![
1555    ///     Pattern::point(" "),
1556    ///     Pattern::point("World"),
1557    /// ]);
1558    /// let result = pattern.fold(String::new(), |acc, s| acc + s);
1559    /// assert_eq!(result, "Hello World");
1560    /// ```
1561    ///
1562    /// ## Type transformation (string lengths to sum)
1563    ///
1564    /// ```
1565    /// use pattern_core::Pattern;
1566    ///
1567    /// let pattern = Pattern::pattern("hello", vec![
1568    ///     Pattern::point("world"),
1569    ///     Pattern::point("!"),
1570    /// ]);
1571    /// let total_length: usize = pattern.fold(0, |acc, s| acc + s.len());
1572    /// assert_eq!(total_length, 11);  // 5 + 5 + 1
1573    /// ```
1574    ///
1575    /// ## Build a vector
1576    ///
1577    /// ```
1578    /// use pattern_core::Pattern;
1579    ///
1580    /// let pattern = Pattern::pattern(1, vec![
1581    ///     Pattern::point(2),
1582    ///     Pattern::point(3),
1583    /// ]);
1584    /// let values: Vec<i32> = pattern.fold(Vec::new(), |mut acc, v| {
1585    ///     acc.push(*v);
1586    ///     acc
1587    /// });
1588    /// assert_eq!(values, vec![1, 2, 3]);
1589    /// ```
1590    ///
1591    /// ## Verify traversal order
1592    ///
1593    /// ```
1594    /// use pattern_core::Pattern;
1595    ///
1596    /// let pattern = Pattern::pattern("A", vec![
1597    ///     Pattern::point("B"),
1598    ///     Pattern::pattern("C", vec![
1599    ///         Pattern::point("D"),
1600    ///     ]),
1601    /// ]);
1602    /// // Root first, then elements in order, depth-first
1603    /// let result = pattern.fold(String::new(), |acc, s| acc + s);
1604    /// assert_eq!(result, "ABCD");
1605    /// ```
1606    ///
1607    /// # Performance
1608    ///
1609    /// - Time complexity: O(n) where n is the total number of values
1610    /// - Space complexity: O(d) for recursion stack where d is the maximum nesting depth
1611    /// - Handles patterns with 100+ nesting levels without stack overflow
1612    /// - Handles patterns with 10,000+ nodes efficiently
1613    ///
1614    /// # Behavioral Guarantees
1615    ///
1616    /// 1. **Completeness**: Every value in the pattern is processed exactly once
1617    /// 2. **Order**: Values processed in depth-first, root-first order
1618    /// 3. **Non-destructive**: Pattern structure is not modified (borrows only)
1619    /// 4. **Reusability**: Pattern can be folded multiple times
1620    pub fn fold<B, F>(&self, init: B, f: F) -> B
1621    where
1622        F: Fn(B, &V) -> B,
1623    {
1624        self.fold_with(init, &f)
1625    }
1626
1627    /// Internal helper for fold that takes function by reference.
1628    ///
1629    /// This enables efficient recursion without cloning the closure.
1630    /// Public `fold` passes closure by value for ergonomics,
1631    /// internal `fold_with` passes closure by reference for efficiency.
1632    fn fold_with<B, F>(&self, acc: B, f: &F) -> B
1633    where
1634        F: Fn(B, &V) -> B,
1635    {
1636        // Process root value first
1637        let acc = f(acc, &self.value);
1638
1639        // Process elements recursively (left to right)
1640        self.elements
1641            .iter()
1642            .fold(acc, |acc, elem| elem.fold_with(acc, f))
1643    }
1644
1645    /// Collects all values from the pattern into a vector in traversal order.
1646    ///
1647    /// Returns references to all values in the pattern, maintaining depth-first,
1648    /// root-first order (same as `fold`). The root value appears first in the vector,
1649    /// followed by element values in traversal order.
1650    ///
1651    /// This method uses `fold` internally and is a convenience for the common case
1652    /// of collecting all pattern values into a standard collection.
1653    ///
1654    /// # Returns
1655    ///
1656    /// A `Vec<&V>` containing references to all values in traversal order
1657    ///
1658    /// # Examples
1659    ///
1660    /// ## Get all values
1661    ///
1662    /// ```
1663    /// use pattern_core::Pattern;
1664    ///
1665    /// let pattern = Pattern::pattern(1, vec![
1666    ///     Pattern::point(2),
1667    ///     Pattern::point(3),
1668    /// ]);
1669    /// let values: Vec<&i32> = pattern.values();
1670    /// assert_eq!(values, vec![&1, &2, &3]);
1671    /// assert_eq!(values.len(), pattern.size());
1672    /// ```
1673    ///
1674    /// ## Verify order
1675    ///
1676    /// ```
1677    /// use pattern_core::Pattern;
1678    ///
1679    /// let pattern = Pattern::pattern(1, vec![
1680    ///     Pattern::point(2),
1681    ///     Pattern::pattern(3, vec![
1682    ///         Pattern::point(4),
1683    ///     ]),
1684    /// ]);
1685    /// let values = pattern.values();
1686    /// assert_eq!(values, vec![&1, &2, &3, &4]);
1687    /// ```
1688    ///
1689    /// ## Use with Iterator methods
1690    ///
1691    /// ```
1692    /// use pattern_core::Pattern;
1693    ///
1694    /// let pattern = Pattern::pattern(1, vec![
1695    ///     Pattern::point(2),
1696    ///     Pattern::point(3),
1697    ///     Pattern::point(4),
1698    /// ]);
1699    /// let sum: i32 = pattern.values().iter().map(|&&v| v).sum();
1700    /// assert_eq!(sum, 10);
1701    ///
1702    /// let all_positive = pattern.values().iter().all(|&&v| v > 0);
1703    /// assert!(all_positive);
1704    /// ```
1705    ///
1706    /// ## Nested patterns
1707    ///
1708    /// ```
1709    /// use pattern_core::Pattern;
1710    ///
1711    /// let pattern = Pattern::pattern(1, vec![
1712    ///     Pattern::pattern(2, vec![
1713    ///         Pattern::point(3),
1714    ///     ]),
1715    /// ]);
1716    /// let values: Vec<&i32> = pattern.values();
1717    /// assert_eq!(values, vec![&1, &2, &3]);
1718    /// ```
1719    ///
1720    /// # Performance
1721    ///
1722    /// - Time complexity: O(n) where n is the total number of values
1723    /// - Space complexity: O(n) for the result vector
1724    /// - Efficient single-pass collection using fold
1725    pub fn values(&self) -> Vec<&V> {
1726        // Collect all values into a vector using fold
1727        let mut result = Vec::with_capacity(self.size());
1728        self.collect_values(&mut result);
1729        result
1730    }
1731
1732    /// Internal helper to recursively collect values into a vector.
1733    fn collect_values<'a>(&'a self, result: &mut Vec<&'a V>) {
1734        result.push(&self.value);
1735        for elem in &self.elements {
1736            elem.collect_values(result);
1737        }
1738    }
1739
1740    /// Paramorphism: structure-aware folding over patterns.
1741    ///
1742    /// Folds the pattern into a single value using a structure-aware folding function.
1743    /// Unlike `fold` (which only provides values), paramorphism gives the folding function
1744    /// access to the full pattern structure at each position, enabling sophisticated
1745    /// aggregations that consider depth, element count, and nesting level.
1746    ///
1747    /// # Type Parameters
1748    ///
1749    /// * `R` - Result type produced by the folding function (can differ from `V`)
1750    /// * `F` - Folding function type `Fn(&Pattern<V>, &[R]) -> R`
1751    ///
1752    /// # Parameters
1753    ///
1754    /// * `f` - Folding function with signature `Fn(&Pattern<V>, &[R]) -> R`
1755    ///   - First parameter: Reference to the current pattern subtree
1756    ///   - Second parameter: Slice of results from the pattern's elements (left-to-right order)
1757    ///   - Returns: Result for this node (type `R`)
1758    ///
1759    /// # Returns
1760    ///
1761    /// The result produced by applying the folding function at the root after all elements
1762    /// have been processed recursively.
1763    ///
1764    /// # Semantics
1765    ///
1766    /// - **Evaluation order**: Bottom-up. For each node, para is first applied to all
1767    ///   elements (left to right); then the folding function is called with the current
1768    ///   pattern and the slice of those results.
1769    /// - **Atomic patterns**: If the pattern has no elements, the folding function receives
1770    ///   an empty slice `&[]` for the second argument.
1771    /// - **Element order**: The slice of results is in the same order as `self.elements()`.
1772    /// - **Non-destructive**: The pattern is not modified. The pattern can be reused after the call.
1773    /// - **Single traversal**: Each node is visited exactly once.
1774    ///
1775    /// # Complexity
1776    ///
1777    /// - **Time**: O(n) where n = total number of nodes in the pattern
1778    /// - **Space**: O(n) for collecting element results (plus O(d) stack where d = max depth)
1779    ///
1780    /// # Relationship to Other Operations
1781    ///
1782    /// | Operation | Access | Use when |
1783    /// |-----------|--------|----------|
1784    /// | `fold` | Values only | Reducing to a single value without structure (e.g. sum, count) |
1785    /// | `para` | Pattern + element results | Structure-aware aggregation (e.g. depth-weighted sum) |
1786    /// | `extend` | Pattern for transformation | Structure-aware transformation returning new Pattern |
1787    ///
1788    /// # Examples
1789    ///
1790    /// ## Sum all values (equivalent to fold)
1791    ///
1792    /// ```
1793    /// use pattern_core::Pattern;
1794    ///
1795    /// let p = Pattern::pattern(10, vec![Pattern::point(5), Pattern::point(3)]);
1796    /// let sum: i32 = p.para(|pat, rs| *pat.value() + rs.iter().sum::<i32>());
1797    /// assert_eq!(sum, 18);  // 10 + 5 + 3
1798    /// ```
1799    ///
1800    /// ## Depth-weighted sum
1801    ///
1802    /// ```
1803    /// use pattern_core::Pattern;
1804    ///
1805    /// let p = Pattern::pattern(10, vec![Pattern::point(5), Pattern::point(3)]);
1806    /// let depth_weighted: i32 = p.para(|pat, rs| {
1807    ///     *pat.value() * pat.depth() as i32 + rs.iter().sum::<i32>()
1808    /// });
1809    /// // Root: 10*1 + (0+0) = 10
1810    /// // Elements are atomic (depth 0): 5*0=0, 3*0=0
1811    /// assert_eq!(depth_weighted, 10);
1812    /// ```
1813    ///
1814    /// ## Atomic pattern receives empty slice
1815    ///
1816    /// ```
1817    /// use pattern_core::Pattern;
1818    ///
1819    /// let atom = Pattern::point(42);
1820    /// let result = atom.para(|pat, rs| {
1821    ///     assert!(rs.is_empty());  // Atomic pattern has no elements
1822    ///     *pat.value()
1823    /// });
1824    /// assert_eq!(result, 42);
1825    /// ```
1826    ///
1827    /// ## Nesting statistics (sum, count, max_depth)
1828    ///
1829    /// ```
1830    /// use pattern_core::Pattern;
1831    ///
1832    /// let p = Pattern::pattern(1, vec![
1833    ///     Pattern::pattern(2, vec![Pattern::point(3)]),
1834    /// ]);
1835    ///
1836    /// let (sum, count, max_depth): (i32, usize, usize) = p.para(|pat, rs| {
1837    ///     let (child_sum, child_count, child_depth) = rs.iter()
1838    ///         .fold((0_i32, 0_usize, 0_usize), |(s, c, d), (s2, c2, d2)| {
1839    ///             (s + s2, c + c2, d.max(*d2))
1840    ///         });
1841    ///     (*pat.value() + child_sum, 1 + child_count, pat.depth().max(child_depth))
1842    /// });
1843    ///
1844    /// assert_eq!(sum, 6);        // 1 + 2 + 3
1845    /// assert_eq!(count, 3);      // 3 nodes total
1846    /// assert_eq!(max_depth, 2);  // Maximum nesting depth (root -> pattern(2) -> point(3))
1847    /// ```
1848    ///
1849    /// # Reference
1850    ///
1851    /// Ported from gram-hs: `../pattern-hs/libs/pattern/src/Pattern/Core.hs` (lines 1188-1190)
1852    pub fn para<R, F>(&self, f: F) -> R
1853    where
1854        F: Fn(&Pattern<V>, &[R]) -> R,
1855    {
1856        self.para_with(&f)
1857    }
1858
1859    /// Internal helper for paramorphism that takes the folding function by reference.
1860    ///
1861    /// This avoids moving the closure on each recursive call, which would require
1862    /// the closure to be `Clone`. By taking `&F` instead of `F`, we can recursively
1863    /// call `para_with` without ownership issues.
1864    fn para_with<R, F>(&self, f: &F) -> R
1865    where
1866        F: Fn(&Pattern<V>, &[R]) -> R,
1867    {
1868        // Recursively compute results for all elements (left to right)
1869        let child_results: Vec<R> = self
1870            .elements
1871            .iter()
1872            .map(|child| child.para_with(f))
1873            .collect();
1874
1875        // Apply folding function to current pattern and element results
1876        f(self, &child_results)
1877    }
1878
1879    /// Validates pattern structure against configurable rules and constraints.
1880    ///
1881    /// Returns `Ok(())` if the pattern is valid according to the rules,
1882    /// or `Err(ValidationError)` if validation fails.
1883    ///
1884    /// # Arguments
1885    ///
1886    /// * `rules` - Validation rules to apply
1887    ///
1888    /// # Returns
1889    ///
1890    /// * `Ok(())` if pattern is valid
1891    /// * `Err(ValidationError)` if validation fails, containing detailed error information
1892    ///
1893    /// # Examples
1894    ///
1895    /// ```
1896    /// use pattern_core::{Pattern, ValidationRules};
1897    ///
1898    /// let pattern = Pattern::pattern("root".to_string(), vec![/* ... */]);
1899    ///
1900    /// let rules = ValidationRules {
1901    ///     max_depth: Some(10),
1902    ///     ..Default::default()
1903    /// };
1904    ///
1905    /// match pattern.validate(&rules) {
1906    ///     Ok(()) => println!("Pattern is valid"),
1907    ///     Err(e) => println!("Validation failed: {} at {:?}", e.message, e.location),
1908    /// }
1909    /// ```
1910    ///
1911    /// # Performance
1912    ///
1913    /// This operation is O(n) where n is the number of nodes in the pattern.
1914    /// Must handle at least 100 nesting levels without stack overflow.
1915    pub fn validate(&self, rules: &ValidationRules) -> Result<(), ValidationError> {
1916        self.validate_recursive(rules, 0, &mut Vec::new())
1917    }
1918
1919    /// Internal recursive validation helper
1920    fn validate_recursive(
1921        &self,
1922        rules: &ValidationRules,
1923        current_depth: usize,
1924        location: &mut Vec<String>,
1925    ) -> Result<(), ValidationError> {
1926        // Check max_depth constraint
1927        if let Some(max_depth) = rules.max_depth {
1928            if current_depth > max_depth {
1929                return Err(ValidationError {
1930                    message: format!(
1931                        "Pattern depth {} exceeds maximum allowed depth {}",
1932                        current_depth, max_depth
1933                    ),
1934                    rule_violated: "max_depth".to_string(),
1935                    location: location.clone(),
1936                });
1937            }
1938        }
1939
1940        // Check max_elements constraint at current level
1941        if let Some(max_elements) = rules.max_elements {
1942            if self.elements.len() > max_elements {
1943                return Err(ValidationError {
1944                    message: format!(
1945                        "Pattern has {} elements, exceeding maximum allowed {}",
1946                        self.elements.len(),
1947                        max_elements
1948                    ),
1949                    rule_violated: "max_elements".to_string(),
1950                    location: location.clone(),
1951                });
1952            }
1953        }
1954
1955        // Recursively validate all elements
1956        for (index, element) in self.elements.iter().enumerate() {
1957            location.push("elements".to_string());
1958            location.push(index.to_string());
1959
1960            element.validate_recursive(rules, current_depth + 1, location)?;
1961
1962            location.pop(); // Remove index
1963            location.pop(); // Remove "elements"
1964        }
1965
1966        Ok(())
1967    }
1968
1969    /// Analyzes pattern structure and returns detailed information about structural characteristics.
1970    ///
1971    /// Provides comprehensive structural analysis including depth distribution, element counts,
1972    /// nesting patterns, and a human-readable summary.
1973    ///
1974    /// # Returns
1975    ///
1976    /// `StructureAnalysis` containing:
1977    /// - Depth distribution: Count of nodes at each depth level
1978    /// - Element counts: Maximum element count at each level (for pattern identification)
1979    /// - Nesting patterns: Identified structural patterns
1980    /// - Summary: Human-readable text summary
1981    ///
1982    /// # Examples
1983    ///
1984    /// ```
1985    /// use pattern_core::Pattern;
1986    ///
1987    /// let pattern = Pattern::pattern("root".to_string(), vec![/* ... */]);
1988    /// let analysis = pattern.analyze_structure();
1989    ///
1990    /// println!("Depth distribution: {:?}", analysis.depth_distribution);
1991    /// println!("Element counts: {:?}", analysis.element_counts);
1992    /// println!("Nesting patterns: {:?}", analysis.nesting_patterns);
1993    /// println!("Summary: {}", analysis.summary);
1994    /// ```
1995    ///
1996    /// # Performance
1997    ///
1998    /// This operation is O(n) where n is the number of nodes in the pattern.
1999    /// Must handle at least 100 nesting levels without stack overflow.
2000    /// Must handle at least 10,000 elements efficiently.
2001    pub fn analyze_structure(&self) -> StructureAnalysis {
2002        let mut depth_distribution = Vec::new();
2003        let mut element_counts = Vec::new();
2004
2005        self.analyze_recursive(0, &mut depth_distribution, &mut element_counts);
2006
2007        // Trim trailing zeros from element_counts (leaf levels with 0 elements)
2008        // According to spec: atomic pattern should have [], 2-level tree should have [count], not [count, 0]
2009        while let Some(&0) = element_counts.last() {
2010            element_counts.pop();
2011        }
2012
2013        // Identify nesting patterns
2014        let nesting_patterns = self.identify_nesting_patterns(&depth_distribution, &element_counts);
2015
2016        // Generate summary
2017        let summary =
2018            self.generate_summary(&depth_distribution, &element_counts, &nesting_patterns);
2019
2020        StructureAnalysis {
2021            depth_distribution,
2022            element_counts,
2023            nesting_patterns,
2024            summary,
2025        }
2026    }
2027
2028    /// Internal recursive analysis helper
2029    /// Tracks maximum element count at each level for pattern identification
2030    fn analyze_recursive(
2031        &self,
2032        current_depth: usize,
2033        depth_distribution: &mut Vec<usize>,
2034        element_counts: &mut Vec<usize>,
2035    ) {
2036        // Ensure vectors are large enough
2037        while depth_distribution.len() <= current_depth {
2038            depth_distribution.push(0);
2039        }
2040        while element_counts.len() <= current_depth {
2041            element_counts.push(0);
2042        }
2043
2044        // Count this node at current depth
2045        depth_distribution[current_depth] += 1;
2046
2047        // Track maximum element count at current level
2048        // Maximum is used for linear/tree pattern detection (all nodes <= 1 vs any node > 1)
2049        // For balanced patterns, we compare maximums across levels, which works correctly
2050        // with the fixed balanced pattern logic (ratio between 0.5 and 2.0)
2051        let current_count = self.elements.len();
2052        if current_count > element_counts[current_depth] {
2053            element_counts[current_depth] = current_count;
2054        }
2055
2056        // Recursively analyze elements
2057        for element in &self.elements {
2058            element.analyze_recursive(current_depth + 1, depth_distribution, element_counts);
2059        }
2060    }
2061
2062    /// Identify structural patterns from depth distribution and element counts
2063    fn identify_nesting_patterns(
2064        &self,
2065        depth_distribution: &[usize],
2066        element_counts: &[usize],
2067    ) -> Vec<String> {
2068        let mut patterns = Vec::new();
2069
2070        if depth_distribution.len() <= 1 {
2071            patterns.push("atomic".to_string());
2072            return patterns;
2073        }
2074
2075        // Check for linear pattern (one element per level)
2076        let is_linear = element_counts.iter().all(|&count| count <= 1);
2077        if is_linear {
2078            patterns.push("linear".to_string());
2079        }
2080
2081        // Check for tree-like pattern (multiple elements, decreasing with depth)
2082        let has_branching = element_counts.iter().any(|&count| count > 1);
2083        if has_branching {
2084            patterns.push("tree".to_string());
2085        }
2086
2087        // Check for balanced pattern (similar element counts across levels)
2088        // Balanced means counts are within 50% of each other (ratio between 0.5 and 2.0)
2089        // Note: element_counts already has trailing zeros trimmed, so all entries are non-zero
2090        if element_counts.len() >= 2 {
2091            let first_count = element_counts[0];
2092            if first_count > 0 {
2093                // Check all levels (trailing zeros already trimmed)
2094                let similar_counts = element_counts.iter().skip(1).all(|&count| {
2095                    let ratio = count as f64 / first_count as f64;
2096                    // Balanced if ratio is between 0.5 and 2.0 (within 50% of first_count)
2097                    (0.5..=2.0).contains(&ratio)
2098                });
2099                if similar_counts && first_count > 1 {
2100                    patterns.push("balanced".to_string());
2101                }
2102            }
2103        }
2104
2105        if patterns.is_empty() {
2106            patterns.push("irregular".to_string());
2107        }
2108
2109        patterns
2110    }
2111
2112    /// Generate human-readable summary of structure
2113    fn generate_summary(
2114        &self,
2115        depth_distribution: &[usize],
2116        _element_counts: &[usize], // Reserved for future use in summary generation
2117        nesting_patterns: &[String],
2118    ) -> String {
2119        let total_nodes: usize = depth_distribution.iter().sum();
2120        let max_depth = depth_distribution.len().saturating_sub(1);
2121        let pattern_desc = if nesting_patterns.is_empty() {
2122            "unknown"
2123        } else {
2124            &nesting_patterns[0]
2125        };
2126
2127        format!(
2128            "Pattern with {} level{}, {} node{}, {}-like structure",
2129            max_depth + 1,
2130            if max_depth == 0 { "" } else { "s" },
2131            total_nodes,
2132            if total_nodes == 1 { "" } else { "s" },
2133            pattern_desc
2134        )
2135    }
2136
2137    // ====================================================================================
2138    // Traversable Operations
2139    // ====================================================================================
2140
2141    /// Applies an effectful function returning `Option` to all values in the pattern.
2142    ///
2143    /// Traverses the pattern in depth-first, root-first order (pre-order traversal).
2144    /// If any transformation returns `None`, the entire operation returns `None`.
2145    /// If all transformations return `Some`, returns `Some(Pattern<W>)` with transformed values.
2146    ///
2147    /// This implements the Traversable pattern for Option, providing:
2148    /// - Structure preservation: Output pattern has same shape as input
2149    /// - Effect sequencing: Short-circuits on first None
2150    /// - All-or-nothing semantics: All values must be Some for success
2151    ///
2152    /// # Type Parameters
2153    ///
2154    /// * `W` - The type of transformed values
2155    /// * `F` - The transformation function type
2156    ///
2157    /// # Arguments
2158    ///
2159    /// * `f` - A function that transforms values of type `&V` to `Option<W>`
2160    ///
2161    /// # Returns
2162    ///
2163    /// * `Some(Pattern<W>)` if all transformations succeed
2164    /// * `None` if any transformation returns None (short-circuit)
2165    ///
2166    /// # Examples
2167    ///
2168    /// ```
2169    /// use pattern_core::Pattern;
2170    ///
2171    /// // Successful traversal - all values parse
2172    /// let pattern = Pattern::pattern("1", vec![Pattern::point("2")]);
2173    /// let result = pattern.traverse_option(|s| s.parse::<i32>().ok());
2174    /// assert!(result.is_some());
2175    /// assert_eq!(result.unwrap().value, 1);
2176    ///
2177    /// // Failed traversal - one value doesn't parse
2178    /// let pattern = Pattern::pattern("1", vec![Pattern::point("invalid")]);
2179    /// let result = pattern.traverse_option(|s| s.parse::<i32>().ok());
2180    /// assert!(result.is_none());
2181    /// ```
2182    ///
2183    /// # Traversable Laws
2184    ///
2185    /// This implementation satisfies the traversable laws:
2186    /// - Identity: `pattern.traverse_option(|v| Some(*v)) == Some(pattern.clone())`
2187    /// - Structure preservation: If successful, output has same size, depth, and length
2188    ///
2189    /// # Performance
2190    ///
2191    /// - Time: O(n) where n is the number of nodes
2192    /// - Space: O(n) for the new pattern + O(d) stack for recursion depth d
2193    /// - Short-circuits on first None without processing remaining values
2194    pub fn traverse_option<W, F>(&self, f: F) -> Option<Pattern<W>>
2195    where
2196        F: Fn(&V) -> Option<W>,
2197    {
2198        self.traverse_option_with(&f)
2199    }
2200
2201    /// Internal helper for `traverse_option` that takes function by reference.
2202    ///
2203    /// This enables efficient recursion without cloning the closure.
2204    /// Public `traverse_option` passes closure by value for ergonomics,
2205    /// internal `traverse_option_with` passes closure by reference for efficiency.
2206    fn traverse_option_with<W, F>(&self, f: &F) -> Option<Pattern<W>>
2207    where
2208        F: Fn(&V) -> Option<W>,
2209    {
2210        // Transform root value first (short-circuits on None via ?)
2211        let new_value = f(&self.value)?;
2212
2213        // Transform elements recursively (left to right)
2214        // Iterator::collect() handles Option sequencing - stops on first None
2215        let new_elements: Option<Vec<Pattern<W>>> = self
2216            .elements
2217            .iter()
2218            .map(|elem| elem.traverse_option_with(f))
2219            .collect();
2220
2221        // Construct new pattern with transformed value and elements
2222        Some(Pattern {
2223            value: new_value,
2224            elements: new_elements?,
2225        })
2226    }
2227
2228    /// Applies an effectful function returning `Result` to all values in the pattern.
2229    ///
2230    /// Traverses the pattern in depth-first, root-first order (pre-order traversal).
2231    /// If any transformation returns `Err`, the entire operation returns `Err` (short-circuits).
2232    /// If all transformations return `Ok`, returns `Ok(Pattern<W>)` with transformed values.
2233    ///
2234    /// This implements the Traversable pattern for Result, providing:
2235    /// - Structure preservation: Output pattern has same shape as input
2236    /// - Effect sequencing: Short-circuits on first Err
2237    /// - All-or-nothing semantics: All values must be Ok for success
2238    /// - Error propagation: First error encountered is returned
2239    ///
2240    /// # Type Parameters
2241    ///
2242    /// * `W` - The type of transformed values
2243    /// * `E` - The error type
2244    /// * `F` - The transformation function type
2245    ///
2246    /// # Arguments
2247    ///
2248    /// * `f` - A function that transforms values of type `&V` to `Result<W, E>`
2249    ///
2250    /// # Returns
2251    ///
2252    /// * `Ok(Pattern<W>)` if all transformations succeed
2253    /// * `Err(E)` with the first error encountered (short-circuit)
2254    ///
2255    /// # Examples
2256    ///
2257    /// ```
2258    /// use pattern_core::Pattern;
2259    ///
2260    /// // Successful traversal - all values parse
2261    /// let pattern = Pattern::pattern("1", vec![Pattern::point("2")]);
2262    /// let result: Result<Pattern<i32>, String> = pattern.traverse_result(|s| {
2263    ///     s.parse::<i32>().map_err(|e| format!("parse error: {}", e))
2264    /// });
2265    /// assert!(result.is_ok());
2266    /// assert_eq!(result.unwrap().value, 1);
2267    ///
2268    /// // Failed traversal - one value doesn't parse
2269    /// let pattern = Pattern::pattern("1", vec![Pattern::point("invalid")]);
2270    /// let result: Result<Pattern<i32>, String> = pattern.traverse_result(|s| {
2271    ///     s.parse::<i32>().map_err(|e| format!("parse error: {}", e))
2272    /// });
2273    /// assert!(result.is_err());
2274    /// ```
2275    ///
2276    /// # Traversable Laws
2277    ///
2278    /// This implementation satisfies the traversable laws:
2279    /// - Identity: `pattern.traverse_result(|v| Ok(*v)) == Ok(pattern.clone())`
2280    /// - Structure preservation: If successful, output has same size, depth, and length
2281    ///
2282    /// # Short-Circuiting
2283    ///
2284    /// The traversal stops immediately when the first error is encountered:
2285    /// - Root value is checked first
2286    /// - Elements are processed left-to-right
2287    /// - Nested patterns are traversed depth-first
2288    /// - No further values are processed after an error
2289    ///
2290    /// # Performance
2291    ///
2292    /// - Time: O(n) where n is the number of nodes (best case: O(1) if root errors)
2293    /// - Space: O(n) for the new pattern + O(d) stack for recursion depth d
2294    /// - Short-circuits on first Err without processing remaining values
2295    pub fn traverse_result<W, E, F>(&self, f: F) -> Result<Pattern<W>, E>
2296    where
2297        F: Fn(&V) -> Result<W, E>,
2298    {
2299        self.traverse_result_with(&f)
2300    }
2301
2302    /// Internal helper for `traverse_result` that takes function by reference.
2303    ///
2304    /// This enables efficient recursion without cloning the closure.
2305    /// Public `traverse_result` passes closure by value for ergonomics,
2306    /// internal `traverse_result_with` passes closure by reference for efficiency.
2307    fn traverse_result_with<W, E, F>(&self, f: &F) -> Result<Pattern<W>, E>
2308    where
2309        F: Fn(&V) -> Result<W, E>,
2310    {
2311        // Transform root value first (short-circuits on Err via ?)
2312        let new_value = f(&self.value)?;
2313
2314        // Transform elements recursively (left to right)
2315        // Iterator::collect() handles Result sequencing - stops on first Err
2316        let new_elements: Result<Vec<Pattern<W>>, E> = self
2317            .elements
2318            .iter()
2319            .map(|elem| elem.traverse_result_with(f))
2320            .collect();
2321
2322        // Construct new pattern with transformed value and elements
2323        Ok(Pattern {
2324            value: new_value,
2325            elements: new_elements?,
2326        })
2327    }
2328}
2329
2330impl<V: Clone> Pattern<Option<V>> {
2331    /// Flips the layers of structure from `Pattern<Option<V>>` to `Option<Pattern<V>>`.
2332    ///
2333    /// This is the `sequence` operation for Option, which "sequences" or "flips" the
2334    /// nested structure layers. If all values in the pattern are `Some`, returns
2335    /// `Some(Pattern<V>)` with the unwrapped values. If any value is `None`, returns `None`.
2336    ///
2337    /// This operation is equivalent to `traverse_option` with the identity function,
2338    /// and demonstrates the relationship: `sequence = traverse(id)`.
2339    ///
2340    /// # Type Parameters
2341    ///
2342    /// * `V` - The type inside the Option values (must implement Clone)
2343    ///
2344    /// # Returns
2345    ///
2346    /// * `Some(Pattern<V>)` if all values are Some (unwrapped)
2347    /// * `None` if any value in the pattern is None
2348    ///
2349    /// # Examples
2350    ///
2351    /// ```
2352    /// use pattern_core::Pattern;
2353    ///
2354    /// // All Some values → Some(Pattern)
2355    /// let pattern = Pattern::pattern(Some(1), vec![Pattern::point(Some(2))]);
2356    /// let result = pattern.sequence_option();
2357    /// assert!(result.is_some());
2358    /// assert_eq!(result.unwrap().value, 1);
2359    ///
2360    /// // Any None → None
2361    /// let pattern = Pattern::pattern(Some(1), vec![Pattern::point(None)]);
2362    /// let result = pattern.sequence_option();
2363    /// assert!(result.is_none());
2364    /// ```
2365    ///
2366    /// # All-or-Nothing Semantics
2367    ///
2368    /// - If all values are `Some`, returns `Some` with unwrapped pattern
2369    /// - If any value is `None`, returns `None` (short-circuits)
2370    /// - Preserves pattern structure when successful
2371    ///
2372    /// # Use Cases
2373    ///
2374    /// - Converting `Pattern<Option<V>>` from multiple optional lookups into `Option<Pattern<V>>`
2375    /// - Validating that all values in a pattern are present
2376    /// - Implementing all-or-nothing processing for optional data
2377    ///
2378    /// # Performance
2379    ///
2380    /// - Time: O(n) where n is the number of nodes (best case: O(1) if root is None)
2381    /// - Space: O(n) for the new pattern + O(d) stack for recursion depth d
2382    /// - Short-circuits on first None without processing remaining values
2383    pub fn sequence_option(self) -> Option<Pattern<V>> {
2384        self.traverse_option(|opt| opt.as_ref().cloned())
2385    }
2386}
2387
2388impl<V, E> Pattern<Result<V, E>> {
2389    /// Flips the layers of structure from `Pattern<Result<V, E>>` to `Result<Pattern<V>, E>`.
2390    ///
2391    /// This is the `sequence` operation for Result, which "sequences" or "flips" the
2392    /// nested structure layers. If all values in the pattern are `Ok`, returns
2393    /// `Ok(Pattern<V>)` with the unwrapped values. If any value is `Err`, returns that `Err`.
2394    ///
2395    /// This operation is equivalent to `traverse_result` with the identity function,
2396    /// and demonstrates the relationship: `sequence = traverse(id)`.
2397    ///
2398    /// # Type Parameters
2399    ///
2400    /// * `V` - The success type inside the Result values
2401    /// * `E` - The error type
2402    ///
2403    /// # Returns
2404    ///
2405    /// * `Ok(Pattern<V>)` if all values are Ok (unwrapped)
2406    /// * `Err(E)` with the first error encountered
2407    ///
2408    /// # Examples
2409    ///
2410    /// ```
2411    /// use pattern_core::Pattern;
2412    ///
2413    /// // All Ok values → Ok(Pattern)
2414    /// let pattern: Pattern<Result<i32, String>> = Pattern::pattern(
2415    ///     Ok(1),
2416    ///     vec![Pattern::point(Ok(2))]
2417    /// );
2418    /// let result = pattern.sequence_result();
2419    /// assert!(result.is_ok());
2420    /// assert_eq!(result.unwrap().value, 1);
2421    ///
2422    /// // Any Err → Err
2423    /// let pattern: Pattern<Result<i32, String>> = Pattern::pattern(
2424    ///     Ok(1),
2425    ///     vec![Pattern::point(Err("error".to_string()))]
2426    /// );
2427    /// let result = pattern.sequence_result();
2428    /// assert!(result.is_err());
2429    /// ```
2430    ///
2431    /// # All-or-Nothing Semantics
2432    ///
2433    /// - If all values are `Ok`, returns `Ok` with unwrapped pattern
2434    /// - If any value is `Err`, returns first `Err` encountered (short-circuits)
2435    /// - Preserves pattern structure when successful
2436    ///
2437    /// # Use Cases
2438    ///
2439    /// - Converting `Pattern<Result<V, E>>` from multiple fallible operations into `Result<Pattern<V>, E>`
2440    /// - Validating that all operations in a pattern succeeded
2441    /// - Implementing all-or-nothing processing for fallible operations
2442    ///
2443    /// # Performance
2444    ///
2445    /// - Time: O(n) where n is the number of nodes (best case: O(1) if root is Err)
2446    /// - Space: O(n) for the new pattern + O(d) stack for recursion depth d
2447    /// - Short-circuits on first Err without processing remaining values
2448    pub fn sequence_result(self) -> Result<Pattern<V>, E>
2449    where
2450        V: Clone,
2451        E: Clone,
2452    {
2453        self.traverse_result(|res| res.clone())
2454    }
2455}
2456
2457impl<V> Pattern<V> {
2458    /// Applies a validation function to all values and collects ALL errors.
2459    ///
2460    /// Unlike `traverse_result` which short-circuits on the first error, `validate_all`
2461    /// processes the entire pattern and collects all errors encountered. This is useful
2462    /// for comprehensive validation where you want to report all issues at once.
2463    ///
2464    /// Traverses in depth-first, root-first order (pre-order). If all validations succeed,
2465    /// returns `Ok(Pattern<W>)` with transformed values. If any validation fails, returns
2466    /// `Err(Vec<E>)` with ALL errors collected in traversal order.
2467    ///
2468    /// # Type Parameters
2469    ///
2470    /// * `W` - The type of transformed values
2471    /// * `E` - The error type
2472    /// * `F` - The validation function type
2473    ///
2474    /// # Arguments
2475    ///
2476    /// * `f` - A function that validates and transforms values of type `&V` to `Result<W, E>`
2477    ///
2478    /// # Returns
2479    ///
2480    /// * `Ok(Pattern<W>)` if all validations succeed
2481    /// * `Err(Vec<E>)` with ALL errors collected in traversal order
2482    ///
2483    /// # Examples
2484    ///
2485    /// ```
2486    /// use pattern_core::Pattern;
2487    ///
2488    /// // All validations succeed
2489    /// let pattern = Pattern::pattern(1, vec![Pattern::point(2), Pattern::point(3)]);
2490    /// let result: Result<Pattern<i32>, Vec<String>> = pattern.validate_all(|v| {
2491    ///     if *v > 0 { Ok(*v * 10) } else { Err(format!("negative: {}", v)) }
2492    /// });
2493    /// assert!(result.is_ok());
2494    ///
2495    /// // Multiple validations fail - ALL errors collected
2496    /// let pattern = Pattern::pattern(-1, vec![Pattern::point(2), Pattern::point(-3)]);
2497    /// let result: Result<Pattern<i32>, Vec<String>> = pattern.validate_all(|v| {
2498    ///     if *v > 0 { Ok(*v * 10) } else { Err(format!("negative: {}", v)) }
2499    /// });
2500    /// assert!(result.is_err());
2501    /// let errors = result.unwrap_err();
2502    /// assert_eq!(errors.len(), 2); // Both -1 and -3 reported
2503    /// ```
2504    ///
2505    /// # Comparison with traverse_result
2506    ///
2507    /// **traverse_result**: Returns first error (short-circuits)
2508    /// - Use when: You want to fail fast and stop processing
2509    /// - Performance: O(1) to O(n) depending on error location
2510    /// - Behavior: Stops at first error
2511    ///
2512    /// **validate_all**: Returns ALL errors (no short-circuit)
2513    /// - Use when: You want comprehensive error reporting
2514    /// - Performance: Always O(n) - processes entire pattern
2515    /// - Behavior: Collects all errors, then returns
2516    ///
2517    /// # Error Ordering
2518    ///
2519    /// Errors are collected in traversal order (root first, then elements left to right).
2520    /// This provides predictable and consistent error reporting.
2521    ///
2522    /// # Performance
2523    ///
2524    /// - Time: Always O(n) where n is the number of nodes (no short-circuiting)
2525    /// - Space: O(n) for the new pattern + O(e) for error collection + O(d) stack depth
2526    /// - Processes every value regardless of errors
2527    pub fn validate_all<W, E, F>(&self, f: F) -> Result<Pattern<W>, Vec<E>>
2528    where
2529        F: Fn(&V) -> Result<W, E>,
2530    {
2531        self.validate_all_with(&f)
2532    }
2533
2534    /// Internal helper for `validate_all` that takes function by reference.
2535    ///
2536    /// This enables efficient recursion without cloning the closure.
2537    /// Collects errors during traversal and returns them all at the end.
2538    ///
2539    /// Uses a single-pass approach:
2540    /// 1. Apply function to all values once, collecting both successes and errors
2541    /// 2. If no errors: Build the transformed pattern from collected successes
2542    /// 3. If errors: Return all collected errors
2543    fn validate_all_with<W, E, F>(&self, f: &F) -> Result<Pattern<W>, Vec<E>>
2544    where
2545        F: Fn(&V) -> Result<W, E>,
2546    {
2547        // Helper to recursively collect all results in pre-order (root first, then elements)
2548        fn collect_results<V, W, E, F>(
2549            pattern: &Pattern<V>,
2550            f: &F,
2551            successes: &mut Vec<W>,
2552            errors: &mut Vec<E>,
2553        ) where
2554            F: Fn(&V) -> Result<W, E>,
2555        {
2556            // Process root value first
2557            match f(&pattern.value) {
2558                Ok(w) => successes.push(w),
2559                Err(e) => errors.push(e),
2560            }
2561
2562            // Process elements recursively (left to right)
2563            for elem in &pattern.elements {
2564                collect_results(elem, f, successes, errors);
2565            }
2566        }
2567
2568        // Single pass: apply function to all values, collecting results
2569        let mut successes = Vec::new();
2570        let mut errors = Vec::new();
2571        collect_results(self, f, &mut successes, &mut errors);
2572
2573        // If any errors occurred, return them all
2574        if !errors.is_empty() {
2575            return Err(errors);
2576        }
2577
2578        // All validations succeeded - rebuild pattern from collected values
2579        // Values are in pre-order, so we consume them in the same order
2580        fn rebuild<V, W>(pattern: &Pattern<V>, values: &mut impl Iterator<Item = W>) -> Pattern<W> {
2581            // Get root value (next in pre-order sequence)
2582            let value = values
2583                .next()
2584                .expect("validate_all: insufficient transformed values");
2585
2586            // Rebuild elements recursively
2587            let elements = pattern
2588                .elements
2589                .iter()
2590                .map(|elem| rebuild(elem, values))
2591                .collect();
2592
2593            Pattern { value, elements }
2594        }
2595
2596        Ok(rebuild(self, &mut successes.into_iter()))
2597    }
2598}
2599
2600// ============================================================================
2601// Ordering Trait Implementations
2602// ============================================================================
2603
2604/// `PartialOrd` implementation for `Pattern`.
2605///
2606/// Provides lexicographic ordering for patterns based on their structure.
2607/// Patterns are compared by their value first, then by their elements recursively.
2608///
2609/// This implementation follows the same semantics as the Haskell reference implementation
2610/// in `gram-hs/libs/pattern/src/Pattern/Core.hs`.
2611///
2612/// # Ordering Rules
2613///
2614/// 1. **Value-first comparison**: Compare pattern values first using the value type's `PartialOrd` instance
2615/// 2. **Element comparison**: If values are equal, compare element vectors lexicographically
2616/// 3. **Lexicographic elements**: Elements are compared left-to-right, stopping at first difference
2617/// 4. **Length comparison**: If all compared elements are equal, shorter < longer
2618///
2619/// # Examples
2620///
2621/// ```
2622/// use pattern_core::Pattern;
2623///
2624/// // Comparing atomic patterns
2625/// let p1 = Pattern::point(1);
2626/// let p2 = Pattern::point(2);
2627/// assert!(p1 < p2);
2628///
2629/// // Comparing patterns with same value but different elements
2630/// let p3 = Pattern::pattern(5, vec![Pattern::point(1)]);
2631/// let p4 = Pattern::pattern(5, vec![Pattern::point(2)]);
2632/// assert!(p3 < p4); // Values equal, first element 1 < 2
2633///
2634/// // Value takes precedence over elements
2635/// let p5 = Pattern::pattern(3, vec![Pattern::point(100)]);
2636/// let p6 = Pattern::pattern(4, vec![Pattern::point(1)]);
2637/// assert!(p5 < p6); // 3 < 4, elements not compared
2638/// ```
2639///
2640/// # Comparison with Haskell
2641///
2642/// This implementation is behaviorally equivalent to the Haskell `Ord` instance:
2643///
2644/// ```haskell
2645/// instance Ord v => Ord (Pattern v) where
2646///   compare (Pattern v1 es1) (Pattern v2 es2) =
2647///     case compare v1 v2 of
2648///       EQ -> compare es1 es2
2649///       other -> other
2650/// ```
2651impl<V: PartialOrd> PartialOrd for Pattern<V> {
2652    /// Compares two patterns, returning `Some(ordering)` if comparable, `None` otherwise.
2653    ///
2654    /// Uses value-first lexicographic comparison:
2655    /// 1. Compare pattern values using `V::partial_cmp`
2656    /// 2. If equal (or both None), compare element vectors lexicographically
2657    /// 3. If values differ, return that ordering
2658    ///
2659    /// # Returns
2660    ///
2661    /// - `Some(Ordering::Less)` if `self < other`
2662    /// - `Some(Ordering::Equal)` if `self == other`
2663    /// - `Some(Ordering::Greater)` if `self > other`
2664    /// - `None` if values cannot be compared (e.g., NaN in floats)
2665    ///
2666    /// # Performance
2667    ///
2668    /// - **Best case**: O(1) - Values differ, immediate return
2669    /// - **Average case**: O(log n) - Finds difference early in elements
2670    /// - **Worst case**: O(n) - Must compare all nodes where n = total nodes
2671    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
2672        match self.value.partial_cmp(&other.value) {
2673            Some(Ordering::Equal) => self.elements.partial_cmp(&other.elements),
2674            other => other,
2675        }
2676    }
2677}
2678
2679/// `Ord` implementation for `Pattern`.
2680///
2681/// Provides total ordering for patterns where the value type implements `Ord`.
2682/// This enables patterns to be used as keys in ordered data structures like
2683/// `BTreeMap`, `BTreeSet`, and `BinaryHeap`.
2684///
2685/// # Ordering Rules
2686///
2687/// Same as `PartialOrd`:
2688/// 1. Compare values first
2689/// 2. If equal, compare elements lexicographically
2690///
2691/// # Properties
2692///
2693/// This implementation satisfies all `Ord` trait requirements:
2694///
2695/// - **Reflexivity**: `x.cmp(&x) == Ordering::Equal` for all x
2696/// - **Antisymmetry**: if `x.cmp(&y) == Less` then `y.cmp(&x) == Greater`
2697/// - **Transitivity**: if `x < y` and `y < z` then `x < z`
2698/// - **Totality**: For all x, y, exactly one of `x < y`, `x == y`, `x > y` holds
2699/// - **Consistency with Eq**: `x == y` implies `x.cmp(&y) == Equal`
2700///
2701/// These properties are verified through property-based tests.
2702///
2703/// # Examples
2704///
2705/// ```
2706/// use pattern_core::Pattern;
2707/// use std::cmp::Ordering;
2708///
2709/// let p1 = Pattern::point(1);
2710/// let p2 = Pattern::point(2);
2711///
2712/// // Using cmp directly
2713/// assert_eq!(p1.cmp(&p2), Ordering::Less);
2714///
2715/// // Using comparison operators
2716/// assert!(p1 < p2);
2717/// assert!(p1 <= p2);
2718/// assert!(p2 > p1);
2719/// assert!(p2 >= p1);
2720///
2721/// // Sorting collections
2722/// let mut patterns = vec![p2.clone(), p1.clone()];
2723/// patterns.sort();
2724/// assert_eq!(patterns, vec![p1, p2]);
2725/// ```
2726///
2727/// # Usage in Data Structures
2728///
2729/// ```
2730/// use pattern_core::Pattern;
2731/// use std::collections::{BTreeMap, BTreeSet};
2732///
2733/// // As BTreeSet elements
2734/// let mut set = BTreeSet::new();
2735/// set.insert(Pattern::point(3));
2736/// set.insert(Pattern::point(1));
2737/// set.insert(Pattern::point(2));
2738/// // Iteration in sorted order: 1, 2, 3
2739///
2740/// // As BTreeMap keys
2741/// let mut map = BTreeMap::new();
2742/// map.insert(Pattern::point(1), "first");
2743/// map.insert(Pattern::point(2), "second");
2744/// ```
2745impl<V: Ord> Ord for Pattern<V> {
2746    /// Compares two patterns, returning their ordering.
2747    ///
2748    /// Uses value-first lexicographic comparison:
2749    /// 1. Compare pattern values using `V::cmp`
2750    /// 2. If equal, compare element vectors lexicographically
2751    /// 3. If values differ, return that ordering
2752    ///
2753    /// This method always returns a definitive ordering (never None).
2754    ///
2755    /// # Performance
2756    ///
2757    /// - **Best case**: O(1) - Values differ, immediate return
2758    /// - **Average case**: O(log n) - Finds difference early in elements
2759    /// - **Worst case**: O(n) - Must compare all nodes where n = total nodes
2760    ///
2761    /// # Short-Circuit Optimization
2762    ///
2763    /// Comparison stops as soon as a difference is found:
2764    /// - If values differ, elements are never compared
2765    /// - If elements differ, remaining elements are not compared
2766    ///
2767    /// This provides efficient comparison even for large patterns.
2768    fn cmp(&self, other: &Self) -> Ordering {
2769        match self.value.cmp(&other.value) {
2770            Ordering::Equal => self.elements.cmp(&other.elements),
2771            non_equal => non_equal,
2772        }
2773    }
2774}
2775
2776// ============================================================================
2777// Pattern Combination
2778// ============================================================================
2779
2780impl<V: crate::Combinable> Pattern<V> {
2781    /// Combines two patterns associatively.
2782    ///
2783    /// Creates a new pattern by:
2784    /// 1. Combining the values using `V::combine`
2785    /// 2. Concatenating the element vectors (left first, then right)
2786    ///
2787    /// The operation is associative: `(a.combine(b)).combine(c)` equals `a.combine(b.combine(c))`.
2788    ///
2789    /// # Parameters
2790    ///
2791    /// * `self` - The first pattern (consumed)
2792    /// * `other` - The second pattern to combine with (consumed)
2793    ///
2794    /// # Returns
2795    ///
2796    /// A new `Pattern<V>` with:
2797    /// * `value`: Result of `self.value.combine(other.value)`
2798    /// * `elements`: Concatenation of `self.elements` and `other.elements`
2799    ///
2800    /// # Examples
2801    ///
2802    /// ## Atomic Patterns
2803    ///
2804    /// ```rust
2805    /// use pattern_core::Pattern;
2806    ///
2807    /// let p1 = Pattern::point("hello".to_string());
2808    /// let p2 = Pattern::point(" world".to_string());
2809    /// let result = p1.combine(p2);
2810    ///
2811    /// assert_eq!(result.value(), "hello world");
2812    /// assert_eq!(result.length(), 0);  // No elements
2813    /// ```
2814    ///
2815    /// ## Patterns with Elements
2816    ///
2817    /// ```rust
2818    /// use pattern_core::Pattern;
2819    ///
2820    /// let p1 = Pattern::pattern("a".to_string(), vec![
2821    ///     Pattern::point("b".to_string()),
2822    ///     Pattern::point("c".to_string()),
2823    /// ]);
2824    ///
2825    /// let p2 = Pattern::pattern("d".to_string(), vec![
2826    ///     Pattern::point("e".to_string()),
2827    /// ]);
2828    ///
2829    /// let result = p1.combine(p2);
2830    ///
2831    /// assert_eq!(result.value(), "ad");
2832    /// assert_eq!(result.length(), 3);  // [b, c, e]
2833    /// ```
2834    ///
2835    /// ## Associativity
2836    ///
2837    /// ```rust
2838    /// use pattern_core::Pattern;
2839    ///
2840    /// let a = Pattern::point("a".to_string());
2841    /// let b = Pattern::point("b".to_string());
2842    /// let c = Pattern::point("c".to_string());
2843    ///
2844    /// let left = a.clone().combine(b.clone()).combine(c.clone());
2845    /// let right = a.combine(b.combine(c));
2846    ///
2847    /// assert_eq!(left, right);  // Associativity holds
2848    /// ```
2849    ///
2850    /// # Performance
2851    ///
2852    /// * **Time Complexity**: O(|elements1| + |elements2| + value_combine_cost)
2853    /// * **Space Complexity**: O(|elements1| + |elements2|)
2854    ///
2855    /// Element concatenation uses `Vec::extend` for efficiency.
2856    ///
2857    /// **Benchmark Results** (on typical hardware):
2858    /// * Atomic patterns: ~100 ns
2859    /// * 100 elements: ~11 µs
2860    /// * 1000 elements: ~119 µs
2861    /// * 100-pattern fold: ~17 µs
2862    ///
2863    /// All operations complete in microseconds, making combination suitable
2864    /// for performance-critical applications.
2865    pub fn combine(self, other: Self) -> Self {
2866        // Step 1: Combine values using V's Combinable implementation
2867        let combined_value = self.value.combine(other.value);
2868
2869        // Step 2: Concatenate elements (left first, then right)
2870        let mut combined_elements = self.elements;
2871        combined_elements.extend(other.elements);
2872
2873        // Step 3: Return new pattern
2874        Pattern {
2875            value: combined_value,
2876            elements: combined_elements,
2877        }
2878    }
2879
2880    /// Creates patterns by combining three lists pointwise (zipWith3).
2881    ///
2882    /// Takes three lists of equal length and combines them element-wise to create
2883    /// new patterns. Each resulting pattern has:
2884    /// - **value**: From the `values` list
2885    /// - **elements**: A pair `[left, right]` from the corresponding positions
2886    ///
2887    /// This is useful for creating relationship patterns from separate lists of
2888    /// source nodes, target nodes, and relationship values.
2889    ///
2890    /// # Arguments
2891    ///
2892    /// * `left` - First list of patterns (e.g., source nodes)
2893    /// * `right` - Second list of patterns (e.g., target nodes)
2894    /// * `values` - List of values for the new patterns (e.g., relationship types)
2895    ///
2896    /// # Returns
2897    ///
2898    /// A vector of patterns where each pattern has value from `values` and
2899    /// elements `[left[i], right[i]]`.
2900    ///
2901    /// # Behavior
2902    ///
2903    /// - Stops at the length of the shortest input list
2904    /// - Consumes all three input vectors
2905    ///
2906    /// # Examples
2907    ///
2908    /// ```
2909    /// use pattern_core::Pattern;
2910    ///
2911    /// // Create relationship patterns
2912    /// let sources = vec![
2913    ///     Pattern::point("Alice".to_string()),
2914    ///     Pattern::point("Bob".to_string()),
2915    /// ];
2916    /// let targets = vec![
2917    ///     Pattern::point("Company".to_string()),
2918    ///     Pattern::point("Project".to_string()),
2919    /// ];
2920    /// let rel_types = vec!["WORKS_FOR".to_string(), "MANAGES".to_string()];
2921    ///
2922    /// let relationships = Pattern::zip3(sources, targets, rel_types);
2923    ///
2924    /// assert_eq!(relationships.len(), 2);
2925    /// assert_eq!(relationships[0].value, "WORKS_FOR");
2926    /// assert_eq!(relationships[0].elements.len(), 2);
2927    /// ```
2928    pub fn zip3(left: Vec<Pattern<V>>, right: Vec<Pattern<V>>, values: Vec<V>) -> Vec<Pattern<V>> {
2929        left.into_iter()
2930            .zip(right)
2931            .zip(values)
2932            .map(|((l, r), v)| Pattern::pattern(v, vec![l, r]))
2933            .collect()
2934    }
2935
2936    /// Creates patterns by applying a function to pairs from two lists (zipWith2).
2937    ///
2938    /// Takes two lists of patterns and applies a function to each pair to compute
2939    /// the value for the resulting pattern. Each resulting pattern has:
2940    /// - **value**: Computed by applying `value_fn` to the pair
2941    /// - **elements**: A pair `[left, right]` from the corresponding positions
2942    ///
2943    /// This is useful when relationship values are derived from the patterns being
2944    /// connected, rather than from a pre-computed list.
2945    ///
2946    /// # Arguments
2947    ///
2948    /// * `left` - First list of patterns (e.g., source nodes)
2949    /// * `right` - Second list of patterns (e.g., target nodes)
2950    /// * `value_fn` - Function that computes the value from each pair
2951    ///
2952    /// # Returns
2953    ///
2954    /// A vector of patterns where each pattern has value computed by `value_fn`
2955    /// and elements `[left[i], right[i]]`.
2956    ///
2957    /// # Behavior
2958    ///
2959    /// - Stops at the length of the shortest input list
2960    /// - Borrows patterns (uses references) to allow inspection without consuming
2961    ///
2962    /// # Examples
2963    ///
2964    /// ```
2965    /// use pattern_core::Pattern;
2966    ///
2967    /// let people = vec![
2968    ///     Pattern::point("Alice".to_string()),
2969    ///     Pattern::point("Bob".to_string()),
2970    /// ];
2971    /// let companies = vec![
2972    ///     Pattern::point("TechCorp".to_string()),
2973    ///     Pattern::point("StartupInc".to_string()),
2974    /// ];
2975    ///
2976    /// // Derive relationship type from patterns
2977    /// let relationships = Pattern::zip_with(people, companies, |person, company| {
2978    ///     format!("{}_WORKS_AT_{}", person.value, company.value)
2979    /// });
2980    ///
2981    /// assert_eq!(relationships[0].value, "Alice_WORKS_AT_TechCorp");
2982    /// ```
2983    pub fn zip_with<F>(
2984        left: Vec<Pattern<V>>,
2985        right: Vec<Pattern<V>>,
2986        value_fn: F,
2987    ) -> Vec<Pattern<V>>
2988    where
2989        F: Fn(&Pattern<V>, &Pattern<V>) -> V,
2990    {
2991        left.into_iter()
2992            .zip(right)
2993            .map(|(l, r)| {
2994                let value = value_fn(&l, &r);
2995                Pattern::pattern(value, vec![l, r])
2996            })
2997            .collect()
2998    }
2999}
3000
3001// ============================================================================
3002// Default Trait Implementation - Identity Element for Monoid
3003// ============================================================================
3004
3005/// Provides a default (identity) pattern for value types that implement `Default`.
3006///
3007/// The default pattern serves as the identity element for pattern combination,
3008/// completing the monoid algebraic structure (associative operation + identity).
3009/// The default pattern has the default value for type `V` and an empty elements list.
3010///
3011/// # Monoid Laws
3012///
3013/// When combined with the [`Combinable`] trait, patterns form a complete monoid
3014/// satisfying these identity laws:
3015///
3016/// - **Left Identity**: `Pattern::default().combine(p) == p` for all patterns `p`
3017/// - **Right Identity**: `p.combine(Pattern::default()) == p` for all patterns `p`
3018///
3019/// These laws ensure that the default pattern acts as a neutral element: combining
3020/// any pattern with the default pattern (on either side) yields the original pattern
3021/// unchanged.
3022///
3023/// # Implementation
3024///
3025/// The default pattern is created using [`Pattern::point`] with the default value
3026/// for type `V`. This results in:
3027/// ```text
3028/// Pattern {
3029///     value: V::default(),
3030///     elements: vec![]
3031/// }
3032/// ```
3033///
3034/// # Examples
3035///
3036/// ## Basic Usage
3037///
3038/// ```rust
3039/// use pattern_core::Pattern;
3040///
3041/// // Create default pattern for String
3042/// let empty: Pattern<String> = Pattern::default();
3043/// assert_eq!(empty.value(), "");
3044/// assert_eq!(empty.length(), 0);
3045///
3046/// // Create default pattern for Vec<i32>
3047/// let empty: Pattern<Vec<i32>> = Pattern::default();
3048/// let expected: Vec<i32> = vec![];
3049/// assert_eq!(empty.value(), &expected);
3050/// assert_eq!(empty.length(), 0);
3051///
3052/// // Create default pattern for unit type
3053/// let empty: Pattern<()> = Pattern::default();
3054/// assert_eq!(empty.value(), &());
3055/// assert_eq!(empty.length(), 0);
3056/// ```
3057///
3058/// ## Identity Laws
3059///
3060/// ```rust
3061/// use pattern_core::{Pattern, Combinable};
3062///
3063/// let p = Pattern::point("hello".to_string());
3064/// let empty = Pattern::<String>::default();
3065///
3066/// // Left identity: empty.combine(p) == p
3067/// assert_eq!(empty.clone().combine(p.clone()), p);
3068///
3069/// // Right identity: p.combine(empty) == p
3070/// assert_eq!(p.clone().combine(empty.clone()), p);
3071/// ```
3072///
3073/// ## Usage with Iterators
3074///
3075/// ```rust
3076/// use pattern_core::{Pattern, Combinable};
3077///
3078/// let patterns = vec![
3079///     Pattern::point("hello".to_string()),
3080///     Pattern::point(" ".to_string()),
3081///     Pattern::point("world".to_string()),
3082/// ];
3083///
3084/// // Fold with default as initial value
3085/// let result = patterns.into_iter()
3086///     .fold(Pattern::default(), |acc, p| acc.combine(p));
3087///
3088/// assert_eq!(result.value(), "hello world");
3089/// ```
3090///
3091/// ## Handling Empty Collections
3092///
3093/// ```rust
3094/// use pattern_core::{Pattern, Combinable};
3095///
3096/// let empty_vec: Vec<Pattern<String>> = vec![];
3097///
3098/// // Folding empty collection returns default
3099/// let result = empty_vec.into_iter()
3100///     .fold(Pattern::default(), |acc, p| acc.combine(p));
3101///
3102/// assert_eq!(result, Pattern::default());
3103/// ```
3104///
3105/// # See Also
3106///
3107/// - [`Pattern::point`] - Used internally to create the default pattern
3108/// - [`Pattern::combine`] - The associative combination operation
3109/// - [`Combinable`] - Trait for types supporting associative combination
3110///
3111/// [`Combinable`]: crate::Combinable
3112impl<V> Default for Pattern<V>
3113where
3114    V: Default,
3115{
3116    /// Creates a default pattern with the default value and empty elements.
3117    ///
3118    /// This is the identity element for pattern combination operations.
3119    ///
3120    /// # Returns
3121    ///
3122    /// A pattern with `V::default()` as the value and an empty elements vector.
3123    ///
3124    /// # Examples
3125    ///
3126    /// ```rust
3127    /// use pattern_core::Pattern;
3128    ///
3129    /// let empty: Pattern<String> = Pattern::default();
3130    /// assert_eq!(empty.value(), "");
3131    /// assert_eq!(empty.length(), 0);
3132    /// assert!(empty.is_atomic());
3133    /// ```
3134    fn default() -> Self {
3135        Pattern::point(V::default())
3136    }
3137}
3138
3139// ============================================================================
3140// Hash Trait Implementation
3141// ============================================================================
3142
3143/// Provides hashing support for patterns where the value type implements `Hash`.
3144///
3145/// This enables patterns to be used as keys in `HashMap` and elements in `HashSet`,
3146/// enabling efficient pattern deduplication, caching, and set-based operations.
3147///
3148/// # Hash/Eq Consistency
3149///
3150/// This implementation guarantees that equal patterns produce equal hashes:
3151/// - If `p1 == p2`, then `hash(p1) == hash(p2)`
3152/// - This consistency is required for correct HashMap/HashSet behavior
3153///
3154/// # Structure-Preserving Hashing
3155///
3156/// The hash incorporates both the value and the element structure recursively:
3157/// - Different patterns with the same values produce different hashes
3158/// - The nesting structure and element order affect the hash
3159/// - Atomic patterns hash differently from compound patterns
3160///
3161/// # Implementation
3162///
3163/// The implementation hashes both components of a pattern:
3164/// 1. Hash the value using `V::hash`
3165/// 2. Hash the elements vector (which recursively hashes nested patterns)
3166///
3167/// This approach leverages `Vec<T>`'s built-in `Hash` implementation, which
3168/// automatically handles recursive hashing of nested patterns correctly.
3169///
3170/// # Type Constraints
3171///
3172/// Only patterns where `V: Hash` can be hashed. This means:
3173/// - ✅ `Pattern<String>` is hashable (String implements Hash)
3174/// - ✅ `Pattern<Symbol>` is hashable (Symbol implements Hash)
3175/// - ✅ `Pattern<i32>` is hashable (integers implement Hash)
3176/// - ❌ `Pattern<Subject>` is NOT hashable (Subject contains f64)
3177/// - ❌ `Pattern<f64>` is NOT hashable (floats don't implement Hash)
3178///
3179/// This is correct behavior - the type system prevents hashing types that
3180/// shouldn't be hashed due to problematic equality semantics (e.g., NaN != NaN for floats).
3181///
3182/// # Examples
3183///
3184/// ## Using Patterns in HashSet (Deduplication)
3185///
3186/// ```rust
3187/// use pattern_core::Pattern;
3188/// use std::collections::HashSet;
3189///
3190/// let p1 = Pattern::point("hello".to_string());
3191/// let p2 = Pattern::point("world".to_string());
3192/// let p3 = Pattern::point("hello".to_string());  // Duplicate of p1
3193///
3194/// let mut set = HashSet::new();
3195/// set.insert(p1);
3196/// set.insert(p2);
3197/// set.insert(p3);  // Automatically deduplicated
3198///
3199/// assert_eq!(set.len(), 2);  // Only unique patterns
3200/// ```
3201///
3202/// ## Using Patterns as HashMap Keys (Caching)
3203///
3204/// ```rust
3205/// use pattern_core::Pattern;
3206/// use std::collections::HashMap;
3207///
3208/// let mut cache: HashMap<Pattern<String>, i32> = HashMap::new();
3209///
3210/// let p1 = Pattern::point("key1".to_string());
3211/// let p2 = Pattern::point("key2".to_string());
3212///
3213/// cache.insert(p1.clone(), 42);
3214/// cache.insert(p2.clone(), 100);
3215///
3216/// assert_eq!(cache.get(&p1), Some(&42));
3217/// assert_eq!(cache.get(&p2), Some(&100));
3218/// ```
3219///
3220/// ## Hash Consistency with Equality
3221///
3222/// ```rust
3223/// use pattern_core::Pattern;
3224/// use std::collections::hash_map::DefaultHasher;
3225/// use std::hash::{Hash, Hasher};
3226///
3227/// fn hash_pattern<V: Hash>(p: &Pattern<V>) -> u64 {
3228///     let mut hasher = DefaultHasher::new();
3229///     p.hash(&mut hasher);
3230///     hasher.finish()
3231/// }
3232///
3233/// let p1 = Pattern::point("test".to_string());
3234/// let p2 = Pattern::point("test".to_string());
3235///
3236/// // Equal patterns have equal hashes
3237/// assert_eq!(p1, p2);
3238/// assert_eq!(hash_pattern(&p1), hash_pattern(&p2));
3239/// ```
3240///
3241/// ## Structure Distinguishes Hashes
3242///
3243/// ```rust
3244/// use pattern_core::Pattern;
3245/// use std::collections::hash_map::DefaultHasher;
3246/// use std::hash::{Hash, Hasher};
3247///
3248/// fn hash_pattern<V: Hash>(p: &Pattern<V>) -> u64 {
3249///     let mut hasher = DefaultHasher::new();
3250///     p.hash(&mut hasher);
3251///     hasher.finish()
3252/// }
3253///
3254/// // Same values, different structures
3255/// let atomic = Pattern::point("value".to_string());
3256/// let compound = Pattern::pattern(
3257///     "value".to_string(),
3258///     vec![Pattern::point("child".to_string())]
3259/// );
3260///
3261/// // Different structures produce different hashes
3262/// assert_ne!(atomic, compound);
3263/// // Note: Hash inequality is not guaranteed but expected
3264/// // (hash collisions are possible but rare)
3265/// ```
3266///
3267/// # Performance
3268///
3269/// - **Time Complexity**: O(n) where n is the total number of nodes in the pattern
3270/// - **Space Complexity**: O(1) (hash computation uses constant space)
3271/// - Hashing is typically very fast (microseconds even for large patterns)
3272/// - Results are cached in HashMap/HashSet (computed once per pattern)
3273///
3274/// # Comparison with Haskell
3275///
3276/// This implementation is behaviorally equivalent to the Haskell `Hashable` instance:
3277///
3278/// ```haskell
3279/// instance Hashable v => Hashable (Pattern v) where
3280///   hashWithSalt salt (Pattern v es) =
3281///     salt `hashWithSalt` v `hashWithSalt` es
3282/// ```
3283///
3284/// Both implementations hash the value and elements in the same order, ensuring
3285/// equivalent hash values for equivalent patterns.
3286///
3287/// # See Also
3288///
3289/// - `HashMap` - For using patterns as keys in hash-based maps
3290/// - `HashSet` - For pattern deduplication and set operations
3291/// - [`Pattern::combine`] - Pattern combination (works well with cached patterns)
3292/// - [`Eq`] - Equality trait that Hash must be consistent with
3293impl<V: Hash> Hash for Pattern<V> {
3294    /// Hashes this pattern into the provided hasher.
3295    ///
3296    /// Computes the hash by:
3297    /// 1. Hashing the value component
3298    /// 2. Hashing the elements vector (recursively hashes nested patterns)
3299    ///
3300    /// This ensures that equal patterns produce equal hashes while different
3301    /// structures produce different hashes.
3302    ///
3303    /// # Parameters
3304    ///
3305    /// * `state` - The hasher to write the hash into
3306    ///
3307    /// # Examples
3308    ///
3309    /// ```rust
3310    /// use pattern_core::Pattern;
3311    /// use std::collections::hash_map::DefaultHasher;
3312    /// use std::hash::{Hash, Hasher};
3313    ///
3314    /// let pattern = Pattern::point("test".to_string());
3315    ///
3316    /// let mut hasher = DefaultHasher::new();
3317    /// pattern.hash(&mut hasher);
3318    /// let hash_value = hasher.finish();
3319    /// ```
3320    fn hash<H: Hasher>(&self, state: &mut H) {
3321        self.value.hash(state);
3322        self.elements.hash(state);
3323    }
3324}
3325
3326// ============================================================================
3327// Paramorphism Tests
3328// ============================================================================
3329
3330#[cfg(test)]
3331mod para_tests {
3332    use super::*;
3333
3334    // ========================================================================
3335    // Phase 3: User Story 1 – Pattern-of-Elements Analysis
3336    // ========================================================================
3337
3338    /// T007: Atomic pattern receives empty slice
3339    #[test]
3340    fn para_atomic_pattern_receives_empty_slice() {
3341        let atom = Pattern::point(42);
3342        let result = atom.para(|p, rs| {
3343            // Verify atomic pattern has no elements
3344            assert!(rs.is_empty(), "Atomic pattern should receive empty slice");
3345            assert_eq!(
3346                p.elements().len(),
3347                0,
3348                "Atomic pattern should have no elements"
3349            );
3350            *p.value()
3351        });
3352        assert_eq!(result, 42);
3353    }
3354
3355    /// T008: Pattern with elements receives results in element order
3356    #[test]
3357    fn para_preserves_element_order() {
3358        // Build pattern: root(10) with elements [point(5), point(3), point(7)]
3359        let p = Pattern::pattern(
3360            10,
3361            vec![Pattern::point(5), Pattern::point(3), Pattern::point(7)],
3362        );
3363
3364        // Use para to collect values in pre-order (root first, then elements left-to-right)
3365        let values: Vec<i32> = p.para(|pat, child_results| {
3366            let mut result = vec![*pat.value()];
3367            for child_vec in child_results {
3368                result.extend(child_vec);
3369            }
3370            result
3371        });
3372
3373        // Should be: [10, 5, 3, 7] (root, then elements in order)
3374        assert_eq!(values, vec![10, 5, 3, 7]);
3375    }
3376
3377    /// T008 (additional): Nested pattern preserves element order
3378    #[test]
3379    fn para_preserves_element_order_nested() {
3380        // Build nested pattern:
3381        // root(1) with elements [
3382        //   pattern(2) with [point(3), point(4)],
3383        //   point(5)
3384        // ]
3385        let p = Pattern::pattern(
3386            1,
3387            vec![
3388                Pattern::pattern(2, vec![Pattern::point(3), Pattern::point(4)]),
3389                Pattern::point(5),
3390            ],
3391        );
3392
3393        // Collect values in pre-order
3394        let values: Vec<i32> = p.para(|pat, child_results| {
3395            let mut result = vec![*pat.value()];
3396            for child_vec in child_results {
3397                result.extend(child_vec);
3398            }
3399            result
3400        });
3401
3402        // Should be: [1, 2, 3, 4, 5] (pre-order traversal)
3403        assert_eq!(values, vec![1, 2, 3, 4, 5]);
3404    }
3405
3406    /// T009: Structure access – para can access pattern structure
3407    #[test]
3408    fn para_provides_structure_access() {
3409        // Build pattern with known structure
3410        // Root(10) with [Pattern(20, [Point(30)]), Point(40)]
3411        // Depth: 2 (root -> pattern(20) -> point(30))
3412        let p = Pattern::pattern(
3413            10,
3414            vec![
3415                Pattern::pattern(20, vec![Pattern::point(30)]),
3416                Pattern::point(40),
3417            ],
3418        );
3419
3420        // Test 1: Access depth at each position
3421        let depth_at_root = p.para(|pat, _| pat.depth());
3422        assert_eq!(depth_at_root, 2, "Root should have depth 2 (max nesting)");
3423
3424        // Test 2: Access element count at each position
3425        let element_count_at_root = p.para(|pat, _| pat.elements().len());
3426        assert_eq!(element_count_at_root, 2, "Root should have 2 elements");
3427
3428        // Test 3: Verify structure access matches direct calls
3429        assert_eq!(p.depth(), depth_at_root);
3430        assert_eq!(p.elements().len(), element_count_at_root);
3431    }
3432
3433    /// T009 (additional): Structure access for nested patterns
3434    #[test]
3435    fn para_structure_access_nested() {
3436        // Pattern structure:
3437        // Root(1) with [Pattern(2, [Point(3), Point(4)]), Point(5)]
3438        // Depth: 2 (root -> pattern(2) -> point(3/4))
3439        let p = Pattern::pattern(
3440            1,
3441            vec![
3442                Pattern::pattern(2, vec![Pattern::point(3), Pattern::point(4)]),
3443                Pattern::point(5),
3444            ],
3445        );
3446
3447        // Collect (value, depth, element_count) at each position
3448        type Info = (i32, usize, usize);
3449        let info: Info = p.para(|pat, child_infos: &[Info]| {
3450            let value = *pat.value();
3451            let depth = pat.depth();
3452            let elem_count = pat.elements().len();
3453
3454            // Verify child infos match expected structure
3455            if value == 1 {
3456                // Root: should have 2 children
3457                assert_eq!(child_infos.len(), 2);
3458                assert_eq!(child_infos[0].0, 2); // First child value
3459                assert_eq!(child_infos[1].0, 5); // Second child value
3460            } else if value == 2 {
3461                // Middle node: should have 2 children
3462                assert_eq!(child_infos.len(), 2);
3463                assert_eq!(child_infos[0].0, 3);
3464                assert_eq!(child_infos[1].0, 4);
3465            } else {
3466                // Leaf nodes: no children
3467                assert_eq!(child_infos.len(), 0);
3468            }
3469
3470            (value, depth, elem_count)
3471        });
3472
3473        assert_eq!(info.0, 1); // Root value
3474        assert_eq!(info.1, 2); // Root depth (max nesting: root -> pattern(2) -> point)
3475        assert_eq!(info.2, 2); // Root has 2 elements
3476    }
3477
3478    // ========================================================================
3479    // Phase 4: User Story 2 – Element-Count-Aware Computation
3480    // ========================================================================
3481
3482    /// T010: Element-count-weighted computation
3483    #[test]
3484    fn para_element_count_weighted_computation() {
3485        // Pattern: root(10) with [point(5), point(3)]
3486        // Formula: value * element_count + sum(element_results)
3487        // Expected: 10*2 + (5*0 + 3*0) = 20 + 0 = 20
3488        let p = Pattern::pattern(10, vec![Pattern::point(5), Pattern::point(3)]);
3489
3490        let result: i32 = p.para(|pat, rs| {
3491            let value = *pat.value();
3492            let elem_count = pat.elements().len() as i32;
3493            let element_sum: i32 = rs.iter().sum();
3494            value * elem_count + element_sum
3495        });
3496
3497        assert_eq!(result, 20, "Root: 10*2 + (0+0) = 20");
3498    }
3499
3500    /// T010 (additional): Element-count-weighted with nested pattern
3501    #[test]
3502    fn para_element_count_weighted_nested() {
3503        // Pattern: root(10) with [pattern(5, [point(2)]), point(3)]
3504        // Root: 10*2 + (middle_result + 0) = 20 + middle_result
3505        // Middle: 5*1 + (0) = 5
3506        // Expected: 20 + 5 = 25
3507        let p = Pattern::pattern(
3508            10,
3509            vec![
3510                Pattern::pattern(5, vec![Pattern::point(2)]),
3511                Pattern::point(3),
3512            ],
3513        );
3514
3515        let result: i32 = p.para(|pat, rs| {
3516            let value = *pat.value();
3517            let elem_count = pat.elements().len() as i32;
3518            let element_sum: i32 = rs.iter().sum();
3519            value * elem_count + element_sum
3520        });
3521
3522        // Root: 10*2 + (5 + 0) = 25
3523        // Middle pattern(5): 5*1 + 0 = 5
3524        // Leaves: 2*0=0, 3*0=0
3525        assert_eq!(result, 25);
3526    }
3527
3528    /// T011: Nested patterns with varying element counts
3529    #[test]
3530    fn para_varying_element_counts() {
3531        // Build pattern with varying element counts at each level:
3532        // root(1) with [
3533        //   pattern(2, [point(3), point(4)]),  // 2 elements
3534        //   pattern(5, [point(6)]),             // 1 element
3535        //   point(7)                            // 0 elements
3536        // ]
3537        let p = Pattern::pattern(
3538            1,
3539            vec![
3540                Pattern::pattern(2, vec![Pattern::point(3), Pattern::point(4)]),
3541                Pattern::pattern(5, vec![Pattern::point(6)]),
3542                Pattern::point(7),
3543            ],
3544        );
3545
3546        // Aggregate element counts at each level
3547        type CountInfo = (i32, usize); // (value, total_element_count_in_subtree)
3548        let result: CountInfo = p.para(|pat, rs: &[CountInfo]| {
3549            let value = *pat.value();
3550            let elem_count = pat.elements().len();
3551            let subtree_count: usize = rs.iter().map(|(_, count)| count).sum();
3552            (value, elem_count + subtree_count)
3553        });
3554
3555        // Root has 3 direct elements
3556        // First element has 2 elements
3557        // Second element has 1 element
3558        // Third element has 0 elements
3559        // Total: 3 + 2 + 1 + 0 = 6
3560        assert_eq!(result.0, 1, "Root value should be 1");
3561        assert_eq!(
3562            result.1, 6,
3563            "Total element count across all levels should be 6"
3564        );
3565    }
3566
3567    /// T011 (additional): Element count aggregation with depth
3568    #[test]
3569    fn para_element_count_by_depth() {
3570        // Pattern: root(1) with [pattern(2, [point(3), point(4)]), point(5)]
3571        let p = Pattern::pattern(
3572            1,
3573            vec![
3574                Pattern::pattern(2, vec![Pattern::point(3), Pattern::point(4)]),
3575                Pattern::point(5),
3576            ],
3577        );
3578
3579        // Count elements at each depth level
3580        type DepthCounts = Vec<usize>; // counts[depth] = number of elements at that depth
3581        let result: DepthCounts = p.para(|pat, rs: &[DepthCounts]| {
3582            let elem_count = pat.elements().len();
3583            let max_depth = rs.iter().map(|v| v.len()).max().unwrap_or(0);
3584
3585            let mut counts = vec![0; max_depth + 1];
3586            counts[0] = elem_count; // Current level
3587
3588            // Aggregate from elements
3589            for child_counts in rs {
3590                for (depth, &count) in child_counts.iter().enumerate() {
3591                    counts[depth + 1] += count;
3592                }
3593            }
3594
3595            counts
3596        });
3597
3598        // Depth 0 (root level): 2 elements [pattern(2), point(5)]
3599        // Depth 1 (pattern(2) level): 2 elements [point(3), point(4)]
3600        // Depth 2: 0 elements (all leaves)
3601        assert_eq!(result[0], 2, "Root has 2 elements");
3602        assert_eq!(result[1], 2, "Second level has 2 elements");
3603    }
3604
3605    // ========================================================================
3606    // Phase 5: User Story 3 – Nesting Statistics
3607    // ========================================================================
3608
3609    /// T012: Atomic pattern nesting statistics
3610    #[test]
3611    fn para_atomic_nesting_statistics() {
3612        let atom = Pattern::point(42);
3613
3614        // Compute (sum, count, max_depth) for atomic pattern
3615        type Stats = (i32, usize, usize);
3616        let stats: Stats = atom.para(|pat, rs: &[Stats]| {
3617            let value = *pat.value();
3618            let (child_sum, child_count, child_max_depth) = rs
3619                .iter()
3620                .fold((0_i32, 0_usize, 0_usize), |(s, c, d), (s2, c2, d2)| {
3621                    (s + s2, c + c2, d.max(*d2))
3622                });
3623
3624            (
3625                value + child_sum,
3626                1 + child_count,
3627                pat.depth().max(child_max_depth),
3628            )
3629        });
3630
3631        assert_eq!(stats.0, 42, "Sum should be the value itself");
3632        assert_eq!(stats.1, 1, "Count should be 1 (single node)");
3633        assert_eq!(stats.2, 0, "Max depth should be 0 (atomic pattern)");
3634    }
3635
3636    /// T013: Nested pattern computing (sum, count, max_depth) in single traversal
3637    #[test]
3638    fn para_nested_nesting_statistics() {
3639        // Pattern: root(1) with [pattern(2, [point(3)]), point(4)]
3640        // Structure:
3641        //   1
3642        //   ├─ 2
3643        //   │  └─ 3
3644        //   └─ 4
3645        let p = Pattern::pattern(
3646            1,
3647            vec![
3648                Pattern::pattern(2, vec![Pattern::point(3)]),
3649                Pattern::point(4),
3650            ],
3651        );
3652
3653        // Compute (sum, count, max_depth) in a single traversal
3654        type Stats = (i32, usize, usize);
3655        let stats: Stats = p.para(|pat, rs: &[Stats]| {
3656            let value = *pat.value();
3657            let (child_sum, child_count, child_max_depth) = rs
3658                .iter()
3659                .fold((0_i32, 0_usize, 0_usize), |(s, c, d), (s2, c2, d2)| {
3660                    (s + s2, c + c2, d.max(*d2))
3661                });
3662
3663            (
3664                value + child_sum,
3665                1 + child_count,
3666                pat.depth().max(child_max_depth),
3667            )
3668        });
3669
3670        assert_eq!(stats.0, 10, "Sum: 1 + 2 + 3 + 4 = 10");
3671        assert_eq!(stats.1, 4, "Count: 4 nodes total");
3672        assert_eq!(stats.2, 2, "Max depth: 2 (root -> pattern(2) -> point(3))");
3673    }
3674
3675    /// T013 (additional): Complex nested pattern statistics
3676    #[test]
3677    fn para_complex_nesting_statistics() {
3678        // More complex pattern:
3679        // root(1) with [
3680        //   pattern(2, [point(3), point(4)]),
3681        //   pattern(5, [pattern(6, [point(7)])]),
3682        //   point(8)
3683        // ]
3684        let p = Pattern::pattern(
3685            1,
3686            vec![
3687                Pattern::pattern(2, vec![Pattern::point(3), Pattern::point(4)]),
3688                Pattern::pattern(5, vec![Pattern::pattern(6, vec![Pattern::point(7)])]),
3689                Pattern::point(8),
3690            ],
3691        );
3692
3693        type Stats = (i32, usize, usize);
3694        let stats: Stats = p.para(|pat, rs: &[Stats]| {
3695            let value = *pat.value();
3696            let (child_sum, child_count, child_max_depth) = rs
3697                .iter()
3698                .fold((0_i32, 0_usize, 0_usize), |(s, c, d), (s2, c2, d2)| {
3699                    (s + s2, c + c2, d.max(*d2))
3700                });
3701
3702            (
3703                value + child_sum,
3704                1 + child_count,
3705                pat.depth().max(child_max_depth),
3706            )
3707        });
3708
3709        // Sum: 1+2+3+4+5+6+7+8 = 36
3710        assert_eq!(stats.0, 36, "Sum of all values");
3711        // Count: 8 nodes
3712        assert_eq!(stats.1, 8, "Total node count");
3713        // Max depth: 3 (root -> pattern(5) -> pattern(6) -> point(7))
3714        assert_eq!(stats.2, 3, "Maximum nesting depth");
3715    }
3716
3717    /// T013 (additional): Verify single traversal efficiency
3718    #[test]
3719    fn para_single_traversal_statistics() {
3720        let p = Pattern::pattern(
3721            10,
3722            vec![
3723                Pattern::pattern(20, vec![Pattern::point(30), Pattern::point(40)]),
3724                Pattern::point(50),
3725            ],
3726        );
3727
3728        // Use a counter to verify single traversal
3729        use std::cell::RefCell;
3730        let visit_count = RefCell::new(0);
3731
3732        type Stats = (i32, usize, usize);
3733        let stats: Stats = p.para(|pat, rs: &[Stats]| {
3734            *visit_count.borrow_mut() += 1;
3735
3736            let value = *pat.value();
3737            let (child_sum, child_count, child_max_depth) = rs
3738                .iter()
3739                .fold((0_i32, 0_usize, 0_usize), |(s, c, d), (s2, c2, d2)| {
3740                    (s + s2, c + c2, d.max(*d2))
3741                });
3742
3743            (
3744                value + child_sum,
3745                1 + child_count,
3746                pat.depth().max(child_max_depth),
3747            )
3748        });
3749
3750        // Verify statistics
3751        assert_eq!(stats.0, 150, "Sum: 10+20+30+40+50");
3752        assert_eq!(stats.1, 5, "Count: 5 nodes");
3753        assert_eq!(stats.2, 2, "Max depth: 2");
3754
3755        // Verify single traversal: each node visited exactly once
3756        assert_eq!(
3757            *visit_count.borrow(),
3758            5,
3759            "Should visit each node exactly once"
3760        );
3761    }
3762
3763    // ========================================================================
3764    // Phase 6: User Story 4 – Custom Structure-Aware Folding
3765    // ========================================================================
3766
3767    /// T014: Para simulates fold – equivalence test
3768    #[test]
3769    fn para_simulates_fold() {
3770        let p = Pattern::pattern(
3771            10,
3772            vec![
3773                Pattern::pattern(20, vec![Pattern::point(30), Pattern::point(40)]),
3774                Pattern::point(50),
3775            ],
3776        );
3777
3778        // Para version: sum all values
3779        let para_sum: i32 = p.para(|pat, rs| *pat.value() + rs.iter().sum::<i32>());
3780
3781        // Fold version: sum all values
3782        let fold_sum: i32 = p.fold(0, |acc, v| acc + v);
3783
3784        assert_eq!(para_sum, fold_sum, "Para should produce same sum as fold");
3785        assert_eq!(para_sum, 150, "Sum: 10+20+30+40+50 = 150");
3786    }
3787
3788    /// T014 (additional): Para simulates fold for different operations
3789    #[test]
3790    fn para_simulates_fold_product() {
3791        let p = Pattern::pattern(
3792            2,
3793            vec![
3794                Pattern::pattern(3, vec![Pattern::point(4)]),
3795                Pattern::point(5),
3796            ],
3797        );
3798
3799        // Para version: product of all values
3800        let para_product: i32 = p.para(|pat, rs| {
3801            let element_product: i32 = rs.iter().product();
3802            if element_product == 0 {
3803                *pat.value() // No elements, just the value
3804            } else {
3805                *pat.value() * element_product
3806            }
3807        });
3808
3809        // Fold version: product of all values
3810        let fold_product: i32 = p.fold(1, |acc, v| acc * v);
3811
3812        assert_eq!(
3813            para_product, fold_product,
3814            "Para should produce same product as fold"
3815        );
3816        assert_eq!(para_product, 120, "Product: 2*3*4*5 = 120");
3817    }
3818
3819    /// T015: Para preserves element order (toList property)
3820    #[test]
3821    fn para_preserves_order_tolist() {
3822        let p = Pattern::pattern(
3823            1,
3824            vec![
3825                Pattern::pattern(2, vec![Pattern::point(3), Pattern::point(4)]),
3826                Pattern::point(5),
3827            ],
3828        );
3829
3830        // Use para to build value list (pre-order: root first, then elements)
3831        let para_values: Vec<i32> = p.para(|pat, rs: &[Vec<i32>]| {
3832            let mut result = vec![*pat.value()];
3833            for child_vec in rs {
3834                result.extend(child_vec);
3835            }
3836            result
3837        });
3838
3839        // Expected pre-order: 1, 2, 3, 4, 5
3840        assert_eq!(
3841            para_values,
3842            vec![1, 2, 3, 4, 5],
3843            "Para should preserve pre-order"
3844        );
3845
3846        // Verify it matches values() method
3847        let values_method: Vec<i32> = p.values().into_iter().copied().collect();
3848        assert_eq!(
3849            para_values, values_method,
3850            "Para toList should match values()"
3851        );
3852    }
3853
3854    /// T015 (additional): Para order preservation with different structures
3855    #[test]
3856    fn para_order_preservation_wide() {
3857        // Wide pattern: many siblings
3858        let p = Pattern::pattern(
3859            0,
3860            vec![
3861                Pattern::point(1),
3862                Pattern::point(2),
3863                Pattern::point(3),
3864                Pattern::point(4),
3865            ],
3866        );
3867
3868        let para_values: Vec<i32> = p.para(|pat, rs: &[Vec<i32>]| {
3869            let mut result = vec![*pat.value()];
3870            for child_vec in rs {
3871                result.extend(child_vec);
3872            }
3873            result
3874        });
3875
3876        assert_eq!(
3877            para_values,
3878            vec![0, 1, 2, 3, 4],
3879            "Should preserve left-to-right order"
3880        );
3881    }
3882
3883    /// T016: Custom folding function with structure access
3884    #[test]
3885    fn para_custom_structure_aware_folding() {
3886        let p = Pattern::pattern(
3887            "root",
3888            vec![
3889                Pattern::pattern(
3890                    "branch",
3891                    vec![Pattern::point("leaf1"), Pattern::point("leaf2")],
3892                ),
3893                Pattern::point("leaf3"),
3894            ],
3895        );
3896
3897        // Custom folding: build a description of the structure
3898        type Description = String;
3899        let description: Description = p.para(|pat, rs: &[Description]| {
3900            let value = *pat.value();
3901            let elem_count = pat.elements().len();
3902            let depth = pat.depth();
3903
3904            if elem_count == 0 {
3905                // Atomic pattern
3906                format!("Leaf({})", value)
3907            } else {
3908                // Pattern with elements
3909                let children_desc = rs.join(", ");
3910                format!(
3911                    "Node({}, depth={}, elements=[{}])",
3912                    value, depth, children_desc
3913                )
3914            }
3915        });
3916
3917        // Verify structure description
3918        assert!(description.contains("root"), "Should mention root");
3919        assert!(description.contains("branch"), "Should mention branch");
3920        assert!(description.contains("leaf1"), "Should mention leaf1");
3921        assert!(description.contains("depth="), "Should include depth info");
3922    }
3923
3924    /// T016 (additional): Structure-aware transformation returning Pattern
3925    #[test]
3926    fn para_structure_preserving_transformation() {
3927        let p = Pattern::pattern(
3928            1,
3929            vec![
3930                Pattern::pattern(2, vec![Pattern::point(3)]),
3931                Pattern::point(4),
3932            ],
3933        );
3934
3935        // Use para to transform: multiply each value by its depth + 1
3936        let transformed: Pattern<i32> = p.para(|pat, rs: &[Pattern<i32>]| {
3937            let value = *pat.value();
3938            let depth = pat.depth();
3939            let new_value = value * (depth as i32 + 1);
3940
3941            Pattern::pattern(new_value, rs.to_vec())
3942        });
3943
3944        // Verify structure is preserved
3945        assert_eq!(transformed.size(), p.size(), "Size should be preserved");
3946        assert_eq!(transformed.depth(), p.depth(), "Depth should be preserved");
3947        assert_eq!(
3948            transformed.elements().len(),
3949            p.elements().len(),
3950            "Element count should be preserved"
3951        );
3952
3953        // Verify values are transformed correctly
3954        // Root (depth=2): 1 * 3 = 3
3955        assert_eq!(*transformed.value(), 3);
3956    }
3957
3958    /// T016 (additional): Para with complex custom logic
3959    #[test]
3960    fn para_complex_custom_logic() {
3961        let p = Pattern::pattern(
3962            10,
3963            vec![
3964                Pattern::pattern(20, vec![Pattern::point(30)]),
3965                Pattern::point(40),
3966            ],
3967        );
3968
3969        // Custom logic: compute weighted sum where each value is weighted by
3970        // (1 + number of descendants)
3971        type WeightedSum = (i32, usize); // (weighted_sum, descendant_count)
3972        let result: WeightedSum = p.para(|pat, rs: &[WeightedSum]| {
3973            let value = *pat.value();
3974            let (child_sum, child_descendants): (i32, usize) =
3975                rs.iter().fold((0, 0), |(s, d), (s2, d2)| (s + s2, d + d2));
3976
3977            let my_descendants = child_descendants + pat.elements().len();
3978            let my_weighted_value = value * (1 + my_descendants) as i32;
3979
3980            (my_weighted_value + child_sum, my_descendants)
3981        });
3982
3983        // Verify the computation
3984        // Leaf 30: 30 * 1 = 30, descendants=0
3985        // Leaf 40: 40 * 1 = 40, descendants=0
3986        // Branch 20: 20 * 2 = 40, descendants=1 (point 30)
3987        // Root 10: 10 * 4 = 40, descendants=3 (branch 20, point 30, point 40)
3988        // Total: 30 + 40 + 40 + 40 = 150
3989        assert_eq!(result.0, 150, "Weighted sum should be 150");
3990        assert_eq!(result.1, 3, "Root should have 3 descendants");
3991    }
3992}
3993
3994// ============================================================================
3995// Comonad Operations
3996// ============================================================================