fn explore_state(&self, state: &State<S>) -> HashSet<State<S>> {
        // Computation exceeded time limit,
        // skip this state because its result won't be used anyway.
        if self.time_limit.is_some() && Instant::now() > self.time_limit.unwrap() {
            return HashSet::new();
        }

        let anchor = state
            .g
            .atoms()
            .iter()
            .enumerate()
            .filter(|(i, a)| {
                state
                    .g
                    .neighbors(*i)
                    .map(|j| state.g.bonds().get(*i, j))
                    .sum::<u8>()
                    < crate::Atoms::max_bonds(**a)
            })
            .map(|(i, _)| i)
            .next();

        if anchor.is_none() {
            return HashSet::new();
        }

        let anchor = anchor.unwrap();

        // Iterate over all the subgraphs that are still available.
        self.subgraphs
            .attachable_subgraphs()
            .enumerate()
            .filter_map(|(_idx, sg)| {
                // Skip this subgraph if we already used all of those.
                if state.used.amount_of(sg) >= self.subgraphs.amount_of(sg) {
                    return None;
                }

                // Iterate over the different options to attach this subgraph.
                Some(
                    crate::attach(&state.g, sg)
                        .into_iter()
                        .filter_map(move |attachment| {
                            let new_node = attachment.new_node;

                            // Find the node(s) in sg that the new_node is attached to.
                            let attached_node: Option<Vec<usize>> = attachment
                                .new_node
                                .map(|new_node| sg.neighbors(new_node).collect());

                            let mapping: BTreeMap<_, _> = attachment.into();

                            // check if the attached_node already contained a similar new_node.
                            // this means checking if the combination of atom label and number of bonds is already present in the bitset.
                            if let Some(attached_node) = attached_node {
                                // Only the anchor can gain neighbors.
                                if attached_node
                                    .iter()
                                    .map(|sgi| mapping[sgi])
                                    .all(|gi| anchor != gi)
                                {
                                    return None;
                                }

                                for sgi in attached_node {
                                    let gi = mapping[&sgi];

                                    // If this atom cannot have another neighbor, skip this.
                                    if state
                                        .g
                                        .neighbors(gi)
                                        .map(|j| state.g.bonds().get(gi, j))
                                        .sum::<u8>()
                                        >= crate::Atoms::max_bonds(state.g.atoms()[gi])
                                    {
                                        return None;
                                    }
                                }
                            }

                            // Actually perform the attachment and create a graph.
                            let g = crate::attachment::perform(&state.g, &sg, mapping, new_node)?;

                            // Rule out graphs with too many atom bonds.
                            for i in 0..g.size() {
                                let s: u8 = (0..g.size()).map(|j| g.bonds().get(i, j)).sum();
                                let e = g.atoms()[i];

                                if s > crate::Atoms::max_bonds(e) {
                                    return None;
                                }
                            }

                            // Calculate newly used subgraphs.
                            let used_subgraphs = S::new(&g);

                            // Check, if by attaching this subgraph in this way,
                            // we used more subgraphs than we're allowed to.
                            if used_subgraphs.is_subset_of(&self.subgraphs) {
                                Some(State::new(g, used_subgraphs))
                            } else {
                                // if self.current_iter == 6 {
                                //     use std::hash::Hasher;
                                //     use std::io::Write;
                                //     let mut hasher =
                                //         std::collections::hash_map::DefaultHasher::default();
                                //     sg.hash(&mut hasher);
                                //     let hash = hasher.finish();

                                //     if crate::statistics::trace_enabled() {
                                //         let filename = format!("trace/sgs_{}_invalid.dot", hash);
                                //         let mut f = std::fs::File::create(filename).unwrap();
                                //         writeln!(&mut f, "graph invalid {{").unwrap();
                                //         sg.dump(&mut f, 0, false).unwrap();
                                //         g.dump(&mut f, sg.size(), true).unwrap();
                                //         writeln!(&mut f, "}}").unwrap();
                                //     }

                                //     if crate::statistics::trace_enabled() {
                                //         let filename = format!("trace/sgs_{}_used.dot", hash);
                                //         let f = std::fs::File::create(filename).unwrap();
                                //         crate::prelude::dump_map(f, used_subgraphs.with_counts())
                                //             .unwrap();
                                //     }

                                //     if crate::statistics::trace_enabled() {
                                //         let filename = format!("trace/sgs_{}_avail.dot", hash);
                                //         let f = std::fs::File::create(filename).unwrap();
                                //         crate::prelude::dump_map(f, self.subgraphs.with_counts())
                                //             .unwrap();
                                //     }
                                // }

                                // println!("the subgraphs just dont add up.");
                                None
                            }
                        }),
                )
            })
            .flatten()
            .collect::<HashSet<_>>()
    }
/// Explores one of the current states by trying to attach unused subgraphs.
Explores one of the current states by trying to attach unused subgraphs.
Explores one of the current states by trying to attach unused subgraphs .
fn explore_state(&self, state: &State<S>) -> HashSet<State<S>> {
        // Computation exceeded time limit,
        // skip this state because its result won't be used anyway.
        if self.time_limit.is_some() && Instant::now() > self.time_limit.unwrap() {
            return HashSet::new();
        }
        let anchor = state
            .g
            .atoms()
            .iter()
            .enumerate()
            .filter(|(i, a)| {
                state
                    .g
                    .neighbors(*i)
                    .map(|j| state.g.bonds().get(*i, j))
                    .sum::<u8>()
                    < crate::Atoms::max_bonds(**a)
            })
            .map(|(i, _)| i)
            .next();
        if anchor.is_none() {
            return HashSet::new();
        }
        let anchor = anchor.unwrap();
        // Iterate over all the subgraphs that are still available.
        self.subgraphs
            .attachable_subgraphs()
            .enumerate()
            .filter_map(|(_idx, sg)| {
                // Skip this subgraph if we already used all of those.
                if state.used.amount_of(sg) >= self.subgraphs.amount_of(sg) {
                    return None;
                }
                // Iterate over the different options to attach this subgraph.
                Some(
                    crate::attach(&state.g, sg)
                        .into_iter()
                        .filter_map(move |attachment| {
                            let new_node = attachment.new_node;
                            // Find the node(s) in sg that the new_node is attached to.
                            let attached_node: Option<Vec<usize>> = attachment
                                .new_node
                                .map(|new_node| sg.neighbors(new_node).collect());
                            let mapping: BTreeMap<_, _> = attachment.into();
                            // check if the attached_node already contained a similar new_node.
                            // this means checking if the combination of atom label and number of bonds is already present in the bitset.
                            if let Some(attached_node) = attached_node {
                                // Only the anchor can gain neighbors.
                                if attached_node
                                    .iter()
                                    .map(|sgi| mapping[sgi])
                                    .all(|gi| anchor != gi)
                                {
                                    return None;
                                }
                                for sgi in attached_node {
                                    let gi = mapping[&sgi];
                                    // If this atom cannot have another neighbor, skip this.
                                    if state
                                        .g
                                        .neighbors(gi)
                                        .map(|j| state.g.bonds().get(gi, j))
                                        .sum::<u8>()
                                        >= crate::Atoms::max_bonds(state.g.atoms()[gi])
                                    {
                                        return None;
                                    }
                                }
                            }
                            // Actually perform the attachment and create a graph.
                            let g = crate::attachment::perform(&state.g, &sg, mapping, new_node)?;
                            // Rule out graphs with too many atom bonds.
                            for i in 0..g.size() {
                                let s: u8 = (0..g.size()).map(|j| g.bonds().get(i, j)).sum();
                                let e = g.atoms()[i];
                                if s > crate::Atoms::max_bonds(e) {
                                    return None;
                                }
                            }
                            // Calculate newly used subgraphs.
                            let used_subgraphs = S::new(&g);
                            // Check, if by attaching this subgraph in this way,
                            // we used more subgraphs than we're allowed to.
                            if used_subgraphs.is_subset_of(&self.subgraphs) {
                                Some(State::new(g, used_subgraphs))
                            } else {
                                // if self.current_iter == 6 {
                                //     use std::hash::Hasher;
                                //     use std::io::Write;
                                //     let mut hasher =
                                //         std::collections::hash_map::DefaultHasher::default();
                                //     sg.hash(&mut hasher);
                                //     let hash = hasher.finish();
                                //     if crate::statistics::trace_enabled() {
                                //         let filename = format!("trace/sgs_{}_invalid.dot", hash);
                                //         let mut f = std::fs::File::create(filename).unwrap();
                                //         writeln!(&mut f, "graph invalid {{").unwrap();
                                //         sg.dump(&mut f, 0, false).unwrap();
                                //         g.dump(&mut f, sg.size(), true).unwrap();
                                //         writeln!(&mut f, "}}").unwrap();
                                //     }
                                //     if crate::statistics::trace_enabled() {
                                //         let filename = format!("trace/sgs_{}_used.dot", hash);
                                //         let f = std::fs::File::create(filename).unwrap();
                                //         crate::prelude::dump_map(f, used_subgraphs.with_counts())
                                //             .unwrap();
                                //     }
                                //     if crate::statistics::trace_enabled() {
                                //         let filename = format!("trace/sgs_{}_avail.dot", hash);
                                //         let f = std::fs::File::create(filename).unwrap();
                                //         crate::prelude::dump_map(f, self.subgraphs.with_counts())
                                //             .unwrap();
                                //     }
                                // }
                                // println!("the subgraphs just dont add up.");
                                None
                            }
                        }),
                )
            })
            .flatten()
            .collect::<HashSet<_>>()
    }
fn explore_state ( & self , state : & State < S > ) -> HashSet < State < S > > { // Computation exceeded time limit, // skip this state because its result won't be used anyway. if self . time_limit . is_some ( ) && Instant :: now ( ) > self . time_limit . unwrap ( ) { return HashSet :: new ( ) ; } let anchor = state . g . atoms ( ) . iter ( ) . enumerate ( ) . filter ( | ( i , a ) | { state . g . neighbors ( * i ) . map ( | j | state . g . bonds ( ) . get ( * i , j ) ) . sum :: < u8 > ( ) < crate :: Atoms :: max_bonds ( * * a ) } ) . map ( | ( i , _ ) | i ) . next ( ) ; if anchor . is_none ( ) { return HashSet :: new ( ) ; } let anchor = anchor . unwrap ( ) ; // Iterate over all the subgraphs that are still available. self . subgraphs . attachable_subgraphs ( ) . enumerate ( ) . filter_map ( | ( _idx , sg ) | { // Skip this subgraph if we already used all of those. if state . used . amount_of ( sg ) >= self . subgraphs . amount_of ( sg ) { return None ; } // Iterate over the different options to attach this subgraph. Some ( crate :: attach ( & state . g , sg ) . into_iter ( ) . filter_map ( move | attachment | { let new_node = attachment . new_node ; // Find the node(s) in sg that the new_node is attached to. let attached_node : Option < Vec < usize > > = attachment . new_node . map ( | new_node | sg . neighbors ( new_node ) . collect ( ) ) ; let mapping : BTreeMap < _ , _ > = attachment . into ( ) ; // check if the attached_node already contained a similar new_node. // this means checking if the combination of atom label and number of bonds is already present in the bitset. if let Some ( attached_node ) = attached_node { // Only the anchor can gain neighbors. if attached_node . iter ( ) . map ( | sgi | mapping [ sgi ] ) . all ( | gi | anchor != gi ) { return None ; } for sgi in attached_node { let gi = mapping [ & sgi ] ; // If this atom cannot have another neighbor, skip this. if state . g . neighbors ( gi ) . map ( | j | state . g . bonds ( ) . get ( gi , j ) ) . sum :: < u8 > ( ) >= crate :: Atoms :: max_bonds ( state . g . atoms ( ) [ gi ] ) { return None ; } } } // Actually perform the attachment and create a graph. let g = crate :: attachment :: perform ( & state . g , & sg , mapping , new_node ) ? ; // Rule out graphs with too many atom bonds. for i in 0 .. g . size ( ) { let s : u8 = ( 0 .. g . size ( ) ) . map ( | j | g . bonds ( ) . get ( i , j ) ) . sum ( ) ; let e = g . atoms ( ) [ i ] ; if s > crate :: Atoms :: max_bonds ( e ) { return None ; } } // Calculate newly used subgraphs. let used_subgraphs = S :: new ( & g ) ; // Check, if by attaching this subgraph in this way, // we used more subgraphs than we're allowed to. if used_subgraphs . is_subset_of ( & self . subgraphs ) { Some ( State :: new ( g , used_subgraphs ) ) } else { // if self.current_iter == 6 { //     use std::hash::Hasher; //     use std::io::Write; //     let mut hasher = //         std::collections::hash_map::DefaultHasher::default(); //     sg.hash(&mut hasher); //     let hash = hasher.finish(); //     if crate::statistics::trace_enabled() { //         let filename = format!("trace/sgs_{}_invalid.dot", hash); //         let mut f = std::fs::File::create(filename).unwrap(); //         writeln!(&mut f, "graph invalid {{").unwrap(); //         sg.dump(&mut f, 0, false).unwrap(); //         g.dump(&mut f, sg.size(), true).unwrap(); //         writeln!(&mut f, "}}").unwrap(); //     } //     if crate::statistics::trace_enabled() { //         let filename = format!("trace/sgs_{}_used.dot", hash); //         let f = std::fs::File::create(filename).unwrap(); //         crate::prelude::dump_map(f, used_subgraphs.with_counts()) //             .unwrap(); //     } //     if crate::statistics::trace_enabled() { //         let filename = format!("trace/sgs_{}_avail.dot", hash); //         let f = std::fs::File::create(filename).unwrap(); //         crate::prelude::dump_map(f, self.subgraphs.with_counts()) //             .unwrap(); //     } // } // println!("the subgraphs just dont add up."); None } } ) , ) } ) . flatten ( ) . collect :: < HashSet < _ > > ( ) }
Explores one of the current states by trying to attach unused subgraphs.
Explores one of the current states by trying to attach unused subgraphs .
&self
state
&State<S>