use symbolica::{ atom::{Atom, AtomView}, coefficient::CoefficientView, domains::finite_field, id::{Condition, Match, MatchSettings, WildcardRestriction}, state::State, }; fn main() { let expr = Atom::parse("f(1,2,3,4,5,6,7)").unwrap(); let pat_expr = Atom::parse("f(x__,y__,z__,w__)").unwrap(); let pattern = pat_expr.as_view().into_pattern(); let x = State::get_symbol("x__"); let y = State::get_symbol("y__"); let z = State::get_symbol("z__"); let w = State::get_symbol("w__"); let conditions = Condition::from((x, WildcardRestriction::Length(0, Some(2)))) & (y, WildcardRestriction::Length(0, Some(4))) & ( y, WildcardRestriction::Cmp( x, Box::new(|y, x| { let len_x = match x { Match::Multiple(_, s) => s.len(), _ => 1, }; let len_y = match y { Match::Multiple(_, s) => s.len(), _ => 1, }; len_x >= len_y }), ), ) & ( z, WildcardRestriction::Filter(Box::new(|x: &Match| { if let Match::Single(AtomView::Num(num)) = x { if let CoefficientView::Natural(x, y) = num.get_coeff_view() { y == 1 && x > 0 && finite_field::is_prime_u64(x as u64) } else { false } } else { false } })), ) & (w, WildcardRestriction::Length(0, None)); let settings = MatchSettings::default(); println!( "> Matching pattern {} : 0 <= len(x) <= 2, 0 <= len(y) <= 4, len(x) >= len(y) & is_prime(z) to {}:", pat_expr, expr ); let mut it = pattern.pattern_match(expr.as_view(), &conditions, &settings); while let Some(m) = it.next() { println!("\tMatch at location {:?} - {:?}:", m.position, m.used_flags); for (id, v) in m.match_stack { print!("\t\t{} = ", State::get_name(*id)); match v { Match::Single(s) => { print!("{}", s) } Match::Multiple(slice_type, mm) => { print!("{:?} ", slice_type); for vv in mm { print!("{}", vv); print!(", ") } } Match::FunctionName(f) => { print!("Fn {}", State::get_name(*f)) } } println!(); } } }