portmatching/matcher/many_patterns/
naive.rs

1use std::hash::Hash;
2
3use portgraph::{LinkView, NodeIndex};
4
5use crate::{
6    matcher::{Match, PatternMatch, PortMatcher, SinglePatternMatcher},
7    patterns::UnweightedEdge,
8    EdgeProperty, NodeProperty, Pattern, PatternID, Universe,
9};
10
11/// A simple matcher for matching multiple patterns.
12///
13/// This matcher uses [`SinglePatternMatcher`]s to match each pattern separately.
14/// Useful as a baseline in benchmarking.
15pub struct NaiveManyMatcher<U: Universe, PNode, PEdge: Eq + Hash> {
16    matchers: Vec<SinglePatternMatcher<U, PNode, PEdge>>,
17}
18
19impl<U: Universe, PNode: NodeProperty, PEdge: EdgeProperty> NaiveManyMatcher<U, PNode, PEdge> {
20    pub fn from_patterns(patterns: Vec<Pattern<U, PNode, PEdge>>) -> Self {
21        Self {
22            matchers: patterns
23                .into_iter()
24                .map(SinglePatternMatcher::new)
25                .collect(),
26        }
27    }
28}
29
30impl<U: Universe, PNode, PEdge: Eq + Hash> Default for NaiveManyMatcher<U, PNode, PEdge> {
31    fn default() -> Self {
32        Self {
33            matchers: Default::default(),
34        }
35    }
36}
37
38impl<U, G> PortMatcher<G, NodeIndex, U> for NaiveManyMatcher<U, (), UnweightedEdge>
39where
40    U: Universe,
41    G: LinkView + Copy,
42{
43    type PNode = ();
44    type PEdge = UnweightedEdge;
45
46    fn find_rooted_matches(&self, graph: G, root: NodeIndex) -> Vec<Match> {
47        self.matchers
48            .iter()
49            .enumerate()
50            .flat_map(|(i, m)| {
51                m.find_rooted_matches(graph, root).into_iter().map(
52                    move |PatternMatch { root, .. }| PatternMatch {
53                        pattern: i.into(),
54                        root,
55                    },
56                )
57            })
58            .collect()
59    }
60
61    fn get_pattern(&self, id: PatternID) -> Option<&Pattern<U, (), UnweightedEdge>> {
62        let m = self.matchers.get(id.0)?;
63        <SinglePatternMatcher<_, _, _> as PortMatcher<G, NodeIndex, U>>::get_pattern(m, 0.into())
64    }
65}
66
67impl<U: Universe, PNode, PEdge: Eq + Hash> FromIterator<SinglePatternMatcher<U, PNode, PEdge>>
68    for NaiveManyMatcher<U, PNode, PEdge>
69{
70    fn from_iter<T: IntoIterator<Item = SinglePatternMatcher<U, PNode, PEdge>>>(iter: T) -> Self {
71        Self {
72            matchers: iter.into_iter().collect(),
73        }
74    }
75}
76
77#[cfg(test)]
78mod naive_tests {}