use crate::resonance::{ResonanceFilter, ResonanceLaw, SemanticUnit};
use crate::traits::{Fractal, FractalCollection};
use std::any::Any;
pub struct LawFilter {
pub allowed: Vec<ResonanceLaw>,
}
impl ResonanceFilter for LawFilter {
fn as_any(&self) -> &dyn Any { self }
fn passes(&self, fractal: &dyn Fractal) -> bool {
self.allowed.contains(&fractal.resonance_law())
}
fn apply(&self, units: &[SemanticUnit]) -> Vec<SemanticUnit> {
units
.iter()
.filter(|u| self.allowed.iter().any(|law| u.label == law.to_string()))
.cloned()
.collect()
}
}
pub struct ScoreFilter {
pub min_score: f64,
}
impl ResonanceFilter for ScoreFilter {
fn as_any(&self) -> &dyn Any { self }
fn passes(&self, fractal: &dyn Fractal) -> bool {
fractal.resonance_score() >= self.min_score
}
fn apply(&self, units: &[SemanticUnit]) -> Vec<SemanticUnit> {
units.iter().filter(|u| u.phase >= self.min_score).cloned().collect()
}
}
pub struct PredicateFilter {
pub predicate: Box<dyn Fn(&SemanticUnit) -> bool + Send + Sync>,
}
impl ResonanceFilter for PredicateFilter {
fn as_any(&self) -> &dyn Any { self }
fn passes(&self, _fractal: &dyn Fractal) -> bool {
true
}
fn apply(&self, units: &[SemanticUnit]) -> Vec<SemanticUnit> {
units.iter().filter(|&u| (self.predicate)(u)).cloned().collect()
}
}
pub struct TagMatchFilter {
pub required_tags: Vec<String>,
}
impl ResonanceFilter for TagMatchFilter {
fn as_any(&self) -> &dyn Any { self }
fn passes(&self, fractal: &dyn Fractal) -> bool {
self.required_tags.iter().all(|tag| fractal.tags().contains(tag))
}
fn apply(&self, units: &[SemanticUnit]) -> Vec<SemanticUnit> {
units.iter().filter(|unit| self.passes(&*unit.fractal)).cloned().collect()
}
}
pub struct DomainFilter {
pub domain: String,
}
impl ResonanceFilter for DomainFilter {
fn as_any(&self) -> &dyn Any { self }
fn passes(&self, fractal: &dyn Fractal) -> bool {
fractal.metadata().domain == self.domain
}
fn apply(&self, units: &[SemanticUnit]) -> Vec<SemanticUnit> {
units.iter().filter(|unit| self.passes(&*unit.fractal)).cloned().collect()
}
}
#[derive(Debug, Clone)]
pub enum FilterLogic {
And,
Or,
Not,
}
pub struct ComposedFilter {
pub filters: Vec<Box<dyn ResonanceFilter>>,
pub logic: FilterLogic,
}
impl ResonanceFilter for ComposedFilter {
fn as_any(&self) -> &dyn Any { self }
fn passes(&self, fractal: &dyn Fractal) -> bool {
match self.logic {
FilterLogic::And => self.filters.iter().all(|f| f.passes(fractal)),
FilterLogic::Or => self.filters.iter().any(|f| f.passes(fractal)),
FilterLogic::Not => !self.filters[0].passes(fractal),
}
}
fn apply(&self, units: &[SemanticUnit]) -> Vec<SemanticUnit> {
match self.logic {
FilterLogic::And => self.filters.iter().fold(units.to_vec(), |acc, f| f.apply(&acc)),
FilterLogic::Or => {
let mut result = Vec::new();
for f in &self.filters {
for unit in f.apply(units) {
if !result.contains(&unit) { result.push(unit);
}
}
}
result
}
FilterLogic::Not => {
let filtered_out = self.filters[0].apply(units);
units
.iter()
.filter(|u| !filtered_out.contains(u))
.cloned()
.collect()
}
}
}
}
pub enum CompositeFilter {
All(Vec<Box<dyn ResonanceFilter>>),
Any(Vec<Box<dyn ResonanceFilter>>),
Not(Box<dyn ResonanceFilter>),
}
impl ResonanceFilter for CompositeFilter {
fn as_any(&self) -> &dyn Any { self }
fn passes(&self, fractal: &dyn Fractal) -> bool {
match self {
CompositeFilter::All(filters) => filters.iter().all(|f| f.passes(fractal)),
CompositeFilter::Any(filters) => filters.iter().any(|f| f.passes(fractal)),
CompositeFilter::Not(filter) => !filter.passes(fractal),
}
}
fn apply(&self, units: &[SemanticUnit]) -> Vec<SemanticUnit> {
units
.iter()
.filter(|unit| self.passes(&*unit.fractal))
.cloned()
.collect()
}
}
#[derive(Debug, Clone)]
pub struct FilterTrace {
pub filter_name: String,
pub passed: Vec<usize>, pub failed: Vec<usize>, }
#[derive(Debug, Clone)]
pub struct ResonantFractalCollection {
pub collection: FractalCollection,
pub resonance_scores: Vec<f64>,
pub resonance_laws: Vec<ResonanceLaw>,
pub average_resonance: f64,
}
impl ResonantFractalCollection {
pub fn new(collection: FractalCollection) -> Self {
let resonance_scores: Vec<f64> = collection
.members
.iter()
.map(|m| m.fractal.resonance_score())
.collect();
let resonance_laws: Vec<ResonanceLaw> = collection
.members
.iter()
.map(|m| m.fractal.resonance_law())
.collect();
let average_resonance = if resonance_scores.is_empty() {
0.0
} else {
resonance_scores.iter().copied().sum::<f64>() / resonance_scores.len() as f64
};
Self {
collection,
resonance_scores,
resonance_laws,
average_resonance,
}
}
pub fn reevaluate(&mut self) {
*self = Self::new(self.collection.clone());
}
}
impl ResonantFractalCollection {
pub fn filter(&self, filter: &dyn ResonanceFilter) -> FractalCollection {
let filtered_members = self
.collection
.members
.iter()
.filter(|m| filter.passes(&m.fractal)) .cloned()
.collect();
FractalCollection { members: filtered_members }
}
pub fn trace_filter(&self, filter: &dyn ResonanceFilter, name: &str) -> FilterTrace {
let mut passed = Vec::new();
let mut failed = Vec::new();
for (i, member) in self.collection.members.iter().enumerate() {
if filter.passes(&member.fractal) {
passed.push(i);
} else {
failed.push(i);
}
}
FilterTrace {
filter_name: name.to_string(),
passed,
failed,
}
}
}