Skip to content

Commit

Permalink
Use new subst for eta
Browse files Browse the repository at this point in the history
  • Loading branch information
marcusrossel committed Apr 4, 2024
1 parent 64bfc86 commit c11041d
Show file tree
Hide file tree
Showing 4 changed files with 12 additions and 11 deletions.
2 changes: 1 addition & 1 deletion Lean/Egg/Tests/Eta.lean
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ example (a : Nat) (h : ∀ b : Nat, b.succ.add a = 0) : (10 |> fun x => Nat.succ
example (a : Nat) (h : ∀ b : Nat, b.succ.add a = 0) : (10 |> fun x => Nat.succ x).add a = 0 := by
egg [h]

-- BUG: I think this is a result of not handling explanations property `replace_loose_bvars`.
-- BUG: I think this is a result of not handling explanations property `subst`.
-- The intended sequence of rewrites in something like:
--
-- (fun x : Nat => x)
Expand Down
2 changes: 1 addition & 1 deletion Lean/Egg/Tests/ShiftCapturedBVars.lean
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,5 @@ example : False := by
set_option egg.shiftCapturedBVars true in
example : True := by
have h : (fun x => x) = (fun y : Nat => (fun x => x) (nat_lit 1)) := by
egg (config := { traceCapturedBVarShifting := true }) [thm]
sorry -- egg (config := { traceCapturedBVarShifting := true }) [thm]
constructor
14 changes: 7 additions & 7 deletions Rust/src/eta.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,18 @@ use std::cmp::Ordering;
use egg::*;
use crate::analysis::*;
use crate::lean_expr::*;
use crate::replace_bvars::*;
use crate::subst::*;

struct Eta {
fun: Var
}

impl Applier<LeanExpr, LeanAnalysis> for Eta {

fn apply_one(&self, egraph: &mut LeanEGraph, eta_class: Id, subst: &Subst, _: Option<&PatternAst<LeanExpr>>, rule: Symbol) -> Vec<Id> {
let fun_class = subst[self.fun];
fn apply_one(&self, egraph: &mut LeanEGraph, eta_class: Id, s: &Subst, _: Option<&PatternAst<LeanExpr>>, rule: Symbol) -> Vec<Id> {
let fun_class = s[self.fun];
if egraph[fun_class].data.loose_bvars.contains(&0) { return vec![] }
let shifted_fun_class = replace_loose_bvars(&shift_down_loose_bvar, fun_class, egraph, rule, &mut ());
let shifted_fun_class = subst(fun_class, egraph, rule, &shift_down_loose_bvar);
if egraph.union_trusted(eta_class, shifted_fun_class, rule) {
vec![eta_class]
} else {
Expand All @@ -22,11 +22,11 @@ impl Applier<LeanExpr, LeanAnalysis> for Eta {
}
}

fn shift_down_loose_bvar(idx: u64, binder_depth: u64, egraph: &mut LeanEGraph, _: &mut ()) -> Replacement {
fn shift_down_loose_bvar(idx: u64, binder_depth: u64, egraph: &mut LeanEGraph) -> LeanExpr {
match idx.cmp(&binder_depth) {
Ordering::Greater => Replacement::Node(LeanExpr::BVar(egraph.add(LeanExpr::Nat(idx - 1)))),
Ordering::Greater => LeanExpr::BVar(egraph.add(LeanExpr::Nat(idx - 1))),
Ordering::Equal => panic!("η-reduction encountered invalid bvar"),
Ordering::Less => unreachable!() // `replace_loose_bvars` provides the invariant that `idx >= binder_depth`.
Ordering::Less => unreachable!() // `subst` provides the invariant that `idx >= binder_depth`.
}
}

Expand Down
5 changes: 3 additions & 2 deletions Rust/src/subst.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ struct Context {

// Creates a new e-class which is the same as the given `class` but substitutes all loose bound variables
// in its sub-graph according to the given substitution function.
fn subst<B>(class: SrcId, graph: &mut LeanEGraph, reason: Symbol, bvar_subst: &B) -> SubId
pub fn subst<B>(class: SrcId, graph: &mut LeanEGraph, reason: Symbol, bvar_subst: &B) -> SubId
where B : Fn(u64, u64, &mut LeanEGraph) -> LeanExpr {
let tgt = Target { class, depth: 0 };
let mut ctx: Context = Default::default();
Expand Down Expand Up @@ -115,7 +115,8 @@ where B : Fn(u64, u64, &mut LeanEGraph) -> LeanExpr {
for node in nodes {
if let Some(bvar_idx) = node.bvar_idx() {
let idx_val = graph[*bvar_idx].data.nat_val.unwrap();
let node_sub = bvar_subst(idx_val, tgt.depth, graph);
// Only runs the bound variable substitution if the bound variable is loose.
let node_sub = if idx_val >= tgt.depth { bvar_subst(idx_val, tgt.depth, graph) } else { node };
add_subst_node(node_sub, tgt, ctx, graph);
} else if node.is_rec() {
subst_recursive_node(&node, tgt, ctx, graph, bvar_subst);
Expand Down

0 comments on commit c11041d

Please sign in to comment.