fn enumerate_paths_to_leaves_rec(
    tree: &RuleTree,
    prior_term: Option<UndefinedTerm>,
) -> Vec<RulePath> {
    // Leaf base case
    if tree.children.is_empty() {
        assert!(
            tree.value.lhs_undefined_terms.len() <= 1,
            "Unexpected LHS undefined terms: {:?}",
            tree.value.lhs_undefined_terms
        );
        let undefined_term_pairs = match prior_term {
            Some(rhs_term) => vec![(rhs_term, tree.value.lhs_undefined_terms[0].clone())],
            None => vec![],
        };
        return vec![RulePath {
            rules: vec![tree.value.clone()],
            undefined_term_pairs,
        }];
    }
    let mut all_paths = vec![];
    // For now, assume there is at most one undefined term per RHS
    assert!(tree.children.len() <= 1);
    for (term, children) in &tree.children {
        for child in children {
            let rhs_undefined_term = tree
                .value
                .rhs_undefined_terms
                .iter()
                .find(|x| x.ret == *term);
            assert!(rhs_undefined_term.is_some());
            let paths = enumerate_paths_to_leaves_rec(child, rhs_undefined_term.cloned());
            for path in paths {
                let mut rules = path.rules.clone();
                rules.insert(0, tree.value.clone());
                let mut undefined_term_pairs = path.undefined_term_pairs.clone();
                match prior_term {
                    Some(ref rhs_term) => {
                        let lhs_undefined_term = child
                            .value
                            .lhs_undefined_terms
                            .iter()
                            .find(|x| x.ret == *term);
                        let new_pair = (rhs_term.clone(), lhs_undefined_term.unwrap().clone());
                        undefined_term_pairs.insert(0, new_pair);
                    }
                    None => (),
                };
                all_paths.push(RulePath {
                    rules,
                    undefined_term_pairs,
                })
            }
        }
    }
    all_paths
}
/// Enumerate all paths from root to leaves. Note: this is not optimized for
/// efficiency, values are cloned for each path.
Enumerate all paths from root to leaves. Note: this is not optimized for
efficiency, values are cloned for each path.
Enumerate all paths from root to leaves . Note : this is not optimized for efficiency values are cloned for each path .
fn enumerate_paths_to_leaves_rec(
    tree: &RuleTree,
    prior_term: Option<UndefinedTerm>,
) -> Vec<RulePath> {
    // Leaf base case
    if tree.children.is_empty() {
        assert!(
            tree.value.lhs_undefined_terms.len() <= 1,
            "Unexpected LHS undefined terms: {:?}",
            tree.value.lhs_undefined_terms
        );
        let undefined_term_pairs = match prior_term {
            Some(rhs_term) => vec![(rhs_term, tree.value.lhs_undefined_terms[0].clone())],
            None => vec![],
        };
        return vec![RulePath {
            rules: vec![tree.value.clone()],
            undefined_term_pairs,
        }];
    }
    let mut all_paths = vec![];
    // For now, assume there is at most one undefined term per RHS
    assert!(tree.children.len() <= 1);
    for (term, children) in &tree.children {
        for child in children {
            let rhs_undefined_term = tree
                .value
                .rhs_undefined_terms
                .iter()
                .find(|x| x.ret == *term);
            assert!(rhs_undefined_term.is_some());
            let paths = enumerate_paths_to_leaves_rec(child, rhs_undefined_term.cloned());
            for path in paths {
                let mut rules = path.rules.clone();
                rules.insert(0, tree.value.clone());
                let mut undefined_term_pairs = path.undefined_term_pairs.clone();
                match prior_term {
                    Some(ref rhs_term) => {
                        let lhs_undefined_term = child
                            .value
                            .lhs_undefined_terms
                            .iter()
                            .find(|x| x.ret == *term);
                        let new_pair = (rhs_term.clone(), lhs_undefined_term.unwrap().clone());
                        undefined_term_pairs.insert(0, new_pair);
                    }
                    None => (),
                };
                all_paths.push(RulePath {
                    rules,
                    undefined_term_pairs,
                })
            }
        }
    }
    all_paths
}
fn enumerate_paths_to_leaves_rec ( tree : & RuleTree , prior_term : Option < UndefinedTerm > , ) -> Vec < RulePath > { // Leaf base case if tree . children . is_empty ( ) { assert ! ( tree value lhs_undefined_terms len ( ) 1 " " tree value lhs_undefined_terms ) ; let undefined_term_pairs = match prior_term { Some ( rhs_term ) => vec ! [ ( rhs_term tree value lhs_undefined_terms [ 0 ] clone ( ) ) ] , None => vec ! [ ] , } ; return vec ! [ RulePath { rules vec [ tree value clone ( ) ] undefined_term_pairs } ] ; } let mut all_paths = vec ! [ ] ; // For now, assume there is at most one undefined term per RHS assert ! ( tree children len ( ) 1 ) ; for ( term , children ) in & tree . children { for child in children { let rhs_undefined_term = tree . value . rhs_undefined_terms . iter ( ) . find ( | x | x . ret == * term ) ; assert ! ( rhs_undefined_term is_some ( ) ) ; let paths = enumerate_paths_to_leaves_rec ( child , rhs_undefined_term . cloned ( ) ) ; for path in paths { let mut rules = path . rules . clone ( ) ; rules . insert ( 0 , tree . value . clone ( ) ) ; let mut undefined_term_pairs = path . undefined_term_pairs . clone ( ) ; match prior_term { Some ( ref rhs_term ) => { let lhs_undefined_term = child . value . lhs_undefined_terms . iter ( ) . find ( | x | x . ret == * term ) ; let new_pair = ( rhs_term . clone ( ) , lhs_undefined_term . unwrap ( ) . clone ( ) ) ; undefined_term_pairs . insert ( 0 , new_pair ) ; } None => ( ) , } ; all_paths . push ( RulePath { rules , undefined_term_pairs , } ) } } } all_paths }
Enumerate all paths from root to leaves.
Enumerate all paths from root to leaves .
tree
&RuleTree
prior_term
Option<UndefinedTerm>
tree
&RuleTree
prior_term
Option<UndefinedTerm>