pub fn build_rule_tree_rec(
    ctx: &mut AssumptionContext<'_>,
    rule: &Rule,
    termenv: &TermEnv,
    typeenv: &TypeEnv,
    depth: usize,
    max_depth: usize,
) -> RuleTree {
    // Basic sanity check to avoid infinite cycles, might want to add actual
    // cycle checking later.
    assert!(depth <= max_depth, "Exceeded maximum rule tree depth!");

    // Get the semantics for this specific rule
    let rule_sem = ctx.interp_rule(rule);

    // If we are at the root of the tree, we should not have any undefined
    // terms on the left hand side
    if depth == 0 {
        assert!(
            rule_sem.lhs_undefined_terms.is_empty(),
            "Cannot have undefined terms in the LHS of the initial root rule, found: {:?}",
            rule_sem.lhs_undefined_terms
        );
    }

    // Recur: if any RHS term is undefined, add a child for each possible next
    // rule. Also track the height of the tree.
    let mut children: HashMap<BoundVar, Vec<RuleTree>> = HashMap::new();
    let mut max_height = 0;

    // TODO: need more complicated logic for multiple undefined terms
    assert!(
        rule_sem.rhs_undefined_terms.len() <= 1,
        "too many undefined terms: {}",
        rule_sem
            .rhs_undefined_terms
            .iter()
            .map(|t| t.name.clone())
            .collect::<Vec<String>>()
            .join(", ")
    );

    for t in rule_sem
        .rhs_undefined_terms
        .clone()
        .into_iter()
        .unique_by(|x| x.name.clone())
    {
        let next_rules = rules_with_lhs_root(&t.name, termenv, typeenv);

        // Since we are not at a leaf node (because there are undefined terms
        // on the RHS), we need next rules for any of the terms currently
        // undefined (which by definition lack annotations).
        assert!(
            !next_rules.is_empty(),
            "Missing annotation or next rules for unknown term  {:?}",
            t.name
        );
        let mut subtrees = vec![];
        for next_rule in rules_with_lhs_root(dbg!(&t.name), termenv, typeenv) {
            let child =
                build_rule_tree_rec(ctx, &next_rule, termenv, typeenv, depth + 1, max_depth);
            if child.height > max_height {
                max_height = child.height;
            }
            subtrees.push(child);
        }
        children.insert(t.ret.clone(), subtrees);
    }

    RuleTree {
        value: rule_sem,
        children,
        height: max_height + 1,
    }
}
/// Recursively build a rule tree of possible rewrites, connected by undefined
/// terms on the left hand sides (LHS) and right hand sides (RHS).
Recursively build a rule tree of possible rewrites, connected by undefined
terms on the left hand sides (LHS) and right hand sides (RHS).
Recursively build a rule tree of possible rewrites connected by undefined terms on the left hand sides ( LHS ) and right hand sides ( RHS ) .
pub fn build_rule_tree_rec(
    ctx: &mut AssumptionContext<'_>,
    rule: &Rule,
    termenv: &TermEnv,
    typeenv: &TypeEnv,
    depth: usize,
    max_depth: usize,
) -> RuleTree {
    // Basic sanity check to avoid infinite cycles, might want to add actual
    // cycle checking later.
    assert!(depth <= max_depth, "Exceeded maximum rule tree depth!");
    // Get the semantics for this specific rule
    let rule_sem = ctx.interp_rule(rule);
    // If we are at the root of the tree, we should not have any undefined
    // terms on the left hand side
    if depth == 0 {
        assert!(
            rule_sem.lhs_undefined_terms.is_empty(),
            "Cannot have undefined terms in the LHS of the initial root rule, found: {:?}",
            rule_sem.lhs_undefined_terms
        );
    }
    // Recur: if any RHS term is undefined, add a child for each possible next
    // rule. Also track the height of the tree.
    let mut children: HashMap<BoundVar, Vec<RuleTree>> = HashMap::new();
    let mut max_height = 0;
    // TODO: need more complicated logic for multiple undefined terms
    assert!(
        rule_sem.rhs_undefined_terms.len() <= 1,
        "too many undefined terms: {}",
        rule_sem
            .rhs_undefined_terms
            .iter()
            .map(|t| t.name.clone())
            .collect::<Vec<String>>()
            .join(", ")
    );
    for t in rule_sem
        .rhs_undefined_terms
        .clone()
        .into_iter()
        .unique_by(|x| x.name.clone())
    {
        let next_rules = rules_with_lhs_root(&t.name, termenv, typeenv);
        // Since we are not at a leaf node (because there are undefined terms
        // on the RHS), we need next rules for any of the terms currently
        // undefined (which by definition lack annotations).
        assert!(
            !next_rules.is_empty(),
            "Missing annotation or next rules for unknown term  {:?}",
            t.name
        );
        let mut subtrees = vec![];
        for next_rule in rules_with_lhs_root(dbg!(&t.name), termenv, typeenv) {
            let child =
                build_rule_tree_rec(ctx, &next_rule, termenv, typeenv, depth + 1, max_depth);
            if child.height > max_height {
                max_height = child.height;
            }
            subtrees.push(child);
        }
        children.insert(t.ret.clone(), subtrees);
    }
    RuleTree {
        value: rule_sem,
        children,
        height: max_height + 1,
    }
}
pub fn build_rule_tree_rec ( ctx : & mut AssumptionContext < ' _ > , rule : & Rule , termenv : & TermEnv , typeenv : & TypeEnv , depth : usize , max_depth : usize , ) -> RuleTree { // Basic sanity check to avoid infinite cycles, might want to add actual // cycle checking later. assert ! ( depth max_depth " " ) ; // Get the semantics for this specific rule let rule_sem = ctx . interp_rule ( rule ) ; // If we are at the root of the tree, we should not have any undefined // terms on the left hand side if depth == 0 { assert ! ( rule_sem lhs_undefined_terms is_empty ( ) " " rule_sem lhs_undefined_terms ) ; } // Recur: if any RHS term is undefined, add a child for each possible next // rule. Also track the height of the tree. let mut children : HashMap < BoundVar , Vec < RuleTree > > = HashMap :: new ( ) ; let mut max_height = 0 ; // TODO: need more complicated logic for multiple undefined terms assert ! ( rule_sem rhs_undefined_terms len ( ) 1 " " rule_sem rhs_undefined_terms iter ( ) map ( t t name clone ( ) ) collect Vec String ( ) join ( " " ) ) ; for t in rule_sem . rhs_undefined_terms . clone ( ) . into_iter ( ) . unique_by ( | x | x . name . clone ( ) ) { let next_rules = rules_with_lhs_root ( & t . name , termenv , typeenv ) ; // Since we are not at a leaf node (because there are undefined terms // on the RHS), we need next rules for any of the terms currently // undefined (which by definition lack annotations). assert ! ( next_rules is_empty ( ) " " t name ) ; let mut subtrees = vec ! [ ] ; for next_rule in rules_with_lhs_root ( dbg ! ( t name ) , termenv , typeenv ) { let child = build_rule_tree_rec ( ctx , & next_rule , termenv , typeenv , depth + 1 , max_depth ) ; if child . height > max_height { max_height = child . height ; } subtrees . push ( child ) ; } children . insert ( t . ret . clone ( ) , subtrees ) ; } RuleTree { value : rule_sem , children , height : max_height + 1 , } }
Recursively build a rule tree of possible rewrites, connected by undefined
terms on the left hand sides (LHS) and right hand sides (RHS).
Recursively build a rule tree of possible rewrites connected by undefined terms on the left hand sides ( LHS ) and right hand sides ( RHS ) .
ctx
&mut AssumptionContext<'_>
rule
&Rule
termenv
&TermEnv
typeenv
&TypeEnv
depth
usize
max_depth
usize
ctx
&mut AssumptionContext<'_>
rule
&Rule
termenv
&TermEnv
typeenv
&TypeEnv
depth
usize
max_depth
usize