fn try_group_by_cond(&mut self, cond: Condition<'cd, A>, not_cond: Condition<'cd, A>) -> bool {
        let cctx = self.cctx;

        if cond.is_true() {
            return false;
        }

        // find all nodes that have a reaching condition that is an `AND` of
        // either `cond` or `not_cond`
        let mut then_cands = HashMap::new();
        let mut else_cands = HashMap::new();
        let mut rest = Vec::with_capacity(self.graph.node_count());
        for node in self.graph.node_indices() {
            let orig_cond = self.graph[node].0;
            if let Some(new_cond) = cctx.remove_and(cond, orig_cond) {
                then_cands.insert(node, new_cond);
            } else if let Some(new_cond) = cctx.remove_and(not_cond, orig_cond) {
                else_cands.insert(node, new_cond);
            } else {
                rest.push(node);
            }
        }

        let then_len = then_cands
            .keys()
            .filter(|&&n| self.graph[n].1.is_some())
            .count();
        let else_len = else_cands
            .keys()
            .filter(|&&n| self.graph[n].1.is_some())
            .count();

        if then_len + else_len < 2 {
            // can't make if-else with only one node
            return false;
        }

        if then_len == 0 {
            // only else-branch
            graph_utils::contract_nodes_and_map(
                &mut self.graph,
                &else_cands.keys().collect(),
                |node, (_, ast)| (else_cands[&node], ast),
                |_, _| (),
                |else_graph| {
                    (
                        not_cond,
                        Some(
                            Refiner::<A> {
                                cctx,
                                graph: else_graph,
                            }
                            .refine(),
                        ),
                    )
                },
            );
        } else {
            // make then-branch
            let then_node = graph_utils::contract_nodes_and_map(
                &mut self.graph,
                &then_cands.keys().collect(),
                |node, (_, ast)| (then_cands[&node], ast),
                |_, _| (),
                |then_graph| {
                    (
                        cond,
                        Some(
                            Refiner::<A> {
                                cctx,
                                graph: then_graph,
                            }
                            .refine(),
                        ),
                    )
                },
            );
            if else_len != 0 {
                // make else-branch
                let else_node = graph_utils::contract_nodes_and_map(
                    &mut self.graph,
                    &else_cands.keys().collect(),
                    |node, (_, ast)| (else_cands[&node], ast),
                    |_, _| (),
                    |else_graph| {
                        (
                            not_cond,
                            Some(
                                Refiner::<A> {
                                    cctx,
                                    graph: else_graph,
                                }
                                .refine(),
                            ),
                        )
                    },
                );

                // can't use `contract_nodes_and_map` b/c we need to know
                // which node is `then` and which is `else`
                debug_assert!(
                    self.graph
                        .find_edge_undirected(then_node, else_node)
                        .is_none()
                );
                let preds: NodeSet = self
                    .graph
                    .neighbors_directed(then_node, Incoming)
                    .chain(self.graph.neighbors_directed(else_node, Incoming))
                    .collect();
                let succs: NodeSet = self
                    .graph
                    .neighbors_directed(then_node, Outgoing)
                    .chain(self.graph.neighbors_directed(else_node, Outgoing))
                    .collect();

                let (_, then_ast) = self.graph.remove_node(then_node).unwrap();
                let (_, else_ast) = self.graph.remove_node(else_node).unwrap();
                let if_node = self.graph.add_node((
                    cctx.mk_true(),
                    Some(AstNodeC::Cond(
                        cond,
                        Box::new(then_ast.unwrap_or_default()),
                        Some(Box::new(else_ast.unwrap_or_default())),
                    )),
                ));

                for p in &preds {
                    self.graph.add_edge(p, if_node, ());
                }
                for s in &succs {
                    self.graph.add_edge(if_node, s, ());
                }
            }
        }
        debug_assert!(!algo::is_cyclic_directed(&self.graph));

        true
    }
/// Tries to group nodes into an `if-else` statement with the given
/// condition.
Tries to group nodes into an `if-else` statement with the given
condition.
Tries to group nodes into an ` if - else ` statement with the given condition .
fn try_group_by_cond(&mut self, cond: Condition<'cd, A>, not_cond: Condition<'cd, A>) -> bool {
        let cctx = self.cctx;
        if cond.is_true() {
            return false;
        }
        // find all nodes that have a reaching condition that is an `AND` of
        // either `cond` or `not_cond`
        let mut then_cands = HashMap::new();
        let mut else_cands = HashMap::new();
        let mut rest = Vec::with_capacity(self.graph.node_count());
        for node in self.graph.node_indices() {
            let orig_cond = self.graph[node].0;
            if let Some(new_cond) = cctx.remove_and(cond, orig_cond) {
                then_cands.insert(node, new_cond);
            } else if let Some(new_cond) = cctx.remove_and(not_cond, orig_cond) {
                else_cands.insert(node, new_cond);
            } else {
                rest.push(node);
            }
        }
        let then_len = then_cands
            .keys()
            .filter(|&&n| self.graph[n].1.is_some())
            .count();
        let else_len = else_cands
            .keys()
            .filter(|&&n| self.graph[n].1.is_some())
            .count();
        if then_len + else_len < 2 {
            // can't make if-else with only one node
            return false;
        }
        if then_len == 0 {
            // only else-branch
            graph_utils::contract_nodes_and_map(
                &mut self.graph,
                &else_cands.keys().collect(),
                |node, (_, ast)| (else_cands[&node], ast),
                |_, _| (),
                |else_graph| {
                    (
                        not_cond,
                        Some(
                            Refiner::<A> {
                                cctx,
                                graph: else_graph,
                            }
                            .refine(),
                        ),
                    )
                },
            );
        } else {
            // make then-branch
            let then_node = graph_utils::contract_nodes_and_map(
                &mut self.graph,
                &then_cands.keys().collect(),
                |node, (_, ast)| (then_cands[&node], ast),
                |_, _| (),
                |then_graph| {
                    (
                        cond,
                        Some(
                            Refiner::<A> {
                                cctx,
                                graph: then_graph,
                            }
                            .refine(),
                        ),
                    )
                },
            );
            if else_len != 0 {
                // make else-branch
                let else_node = graph_utils::contract_nodes_and_map(
                    &mut self.graph,
                    &else_cands.keys().collect(),
                    |node, (_, ast)| (else_cands[&node], ast),
                    |_, _| (),
                    |else_graph| {
                        (
                            not_cond,
                            Some(
                                Refiner::<A> {
                                    cctx,
                                    graph: else_graph,
                                }
                                .refine(),
                            ),
                        )
                    },
                );
                // can't use `contract_nodes_and_map` b/c we need to know
                // which node is `then` and which is `else`
                debug_assert!(
                    self.graph
                        .find_edge_undirected(then_node, else_node)
                        .is_none()
                );
                let preds: NodeSet = self
                    .graph
                    .neighbors_directed(then_node, Incoming)
                    .chain(self.graph.neighbors_directed(else_node, Incoming))
                    .collect();
                let succs: NodeSet = self
                    .graph
                    .neighbors_directed(then_node, Outgoing)
                    .chain(self.graph.neighbors_directed(else_node, Outgoing))
                    .collect();
                let (_, then_ast) = self.graph.remove_node(then_node).unwrap();
                let (_, else_ast) = self.graph.remove_node(else_node).unwrap();
                let if_node = self.graph.add_node((
                    cctx.mk_true(),
                    Some(AstNodeC::Cond(
                        cond,
                        Box::new(then_ast.unwrap_or_default()),
                        Some(Box::new(else_ast.unwrap_or_default())),
                    )),
                ));
                for p in &preds {
                    self.graph.add_edge(p, if_node, ());
                }
                for s in &succs {
                    self.graph.add_edge(if_node, s, ());
                }
            }
        }
        debug_assert!(!algo::is_cyclic_directed(&self.graph));
        true
    }
fn try_group_by_cond ( & mut self , cond : Condition < ' cd , A > , not_cond : Condition < ' cd , A > ) -> bool { let cctx = self . cctx ; if cond . is_true ( ) { return false ; } // find all nodes that have a reaching condition that is an `AND` of // either `cond` or `not_cond` let mut then_cands = HashMap :: new ( ) ; let mut else_cands = HashMap :: new ( ) ; let mut rest = Vec :: with_capacity ( self . graph . node_count ( ) ) ; for node in self . graph . node_indices ( ) { let orig_cond = self . graph [ node ] . 0 ; if let Some ( new_cond ) = cctx . remove_and ( cond , orig_cond ) { then_cands . insert ( node , new_cond ) ; } else if let Some ( new_cond ) = cctx . remove_and ( not_cond , orig_cond ) { else_cands . insert ( node , new_cond ) ; } else { rest . push ( node ) ; } } let then_len = then_cands . keys ( ) . filter ( | & & n | self . graph [ n ] . 1 . is_some ( ) ) . count ( ) ; let else_len = else_cands . keys ( ) . filter ( | & & n | self . graph [ n ] . 1 . is_some ( ) ) . count ( ) ; if then_len + else_len < 2 { // can't make if-else with only one node return false ; } if then_len == 0 { // only else-branch graph_utils :: contract_nodes_and_map ( & mut self . graph , & else_cands . keys ( ) . collect ( ) , | node , ( _ , ast ) | ( else_cands [ & node ] , ast ) , | _ , _ | ( ) , | else_graph | { ( not_cond , Some ( Refiner :: < A > { cctx , graph : else_graph , } . refine ( ) , ) , ) } , ) ; } else { // make then-branch let then_node = graph_utils :: contract_nodes_and_map ( & mut self . graph , & then_cands . keys ( ) . collect ( ) , | node , ( _ , ast ) | ( then_cands [ & node ] , ast ) , | _ , _ | ( ) , | then_graph | { ( cond , Some ( Refiner :: < A > { cctx , graph : then_graph , } . refine ( ) , ) , ) } , ) ; if else_len != 0 { // make else-branch let else_node = graph_utils :: contract_nodes_and_map ( & mut self . graph , & else_cands . keys ( ) . collect ( ) , | node , ( _ , ast ) | ( else_cands [ & node ] , ast ) , | _ , _ | ( ) , | else_graph | { ( not_cond , Some ( Refiner :: < A > { cctx , graph : else_graph , } . refine ( ) , ) , ) } , ) ; // can't use `contract_nodes_and_map` b/c we need to know // which node is `then` and which is `else` debug_assert ! ( self graph find_edge_undirected ( then_node else_node ) is_none ( ) ) ; let preds : NodeSet = self . graph . neighbors_directed ( then_node , Incoming ) . chain ( self . graph . neighbors_directed ( else_node , Incoming ) ) . collect ( ) ; let succs : NodeSet = self . graph . neighbors_directed ( then_node , Outgoing ) . chain ( self . graph . neighbors_directed ( else_node , Outgoing ) ) . collect ( ) ; let ( _ , then_ast ) = self . graph . remove_node ( then_node ) . unwrap ( ) ; let ( _ , else_ast ) = self . graph . remove_node ( else_node ) . unwrap ( ) ; let if_node = self . graph . add_node ( ( cctx . mk_true ( ) , Some ( AstNodeC :: Cond ( cond , Box :: new ( then_ast . unwrap_or_default ( ) ) , Some ( Box :: new ( else_ast . unwrap_or_default ( ) ) ) , ) ) , ) ) ; for p in & preds { self . graph . add_edge ( p , if_node , ( ) ) ; } for s in & succs { self . graph . add_edge ( if_node , s , ( ) ) ; } } } debug_assert ! ( algo is_cyclic_directed ( self graph ) ) ; true }
Tries to group nodes into an `if-else` statement with the given
condition.
Tries to group nodes into an ` if - else ` statement with the given condition .
&mut self
cond
Condition<'cd, A>
not_cond
Condition<'cd, A>
&mut self
cond
Condition<'cd, A>
not_cond
Condition<'cd, A>