Skip to content

Commit

Permalink
Merge pull request trueagi-io#557 from vsbogd/fix-crash-on-full-retain
Browse files Browse the repository at this point in the history
Fix crash on retain all variables from single binding
  • Loading branch information
vsbogd authored Jan 31, 2024
2 parents 55f6ff8 + 3f1e4cf commit 2b45c30
Showing 1 changed file with 34 additions and 4 deletions.
38 changes: 34 additions & 4 deletions lib/src/atom/matcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ impl Bindings {
self.bindings.remove(binding_id).atom
} else {
if binding.var == *var {
self.rename_binding(binding_id, var);
let _ = self.rename_binding(binding_id);
}
None
}
Expand All @@ -190,14 +190,15 @@ impl Bindings {
}
}

fn rename_binding(&mut self, binding_id: usize, old_var: &VariableAtom) {
fn rename_binding(&mut self, binding_id: usize) -> Result<(), ()> {
let binding = &mut self.bindings[binding_id];
let var = self.binding_by_var.iter()
.filter(|(v, i)| **i == binding.id && *v != old_var)
.filter(|(v, i)| **i == binding.id && **v != binding.var)
.map(|(v, _i)| v)
.next()
.expect("Unexpected state");
.ok_or(())?;
binding.var = var.clone();
Ok(())
}

fn move_binding_to_binding(&mut self, from_binding_id: usize, to_binding_id: usize) {
Expand Down Expand Up @@ -1712,6 +1713,35 @@ mod test {
Ok(())
}

#[test]
fn bindings_retain_all() -> Result<(), &'static str> {
let mut bindings = Bindings::new()
.add_var_equality(&VariableAtom::new("a"), &VariableAtom::new("b"))?;
bindings.retain(|_| false);
assert!(bindings.is_empty());
Ok(())
}

#[test]
fn bindings_rename_binding() -> Result<(), &'static str> {
let a = &VariableAtom::new("a");
let b = &VariableAtom::new("b");
let mut bindings = Bindings::new().add_var_equality(a, b)?;
let binding_id = bindings.get_binding(a).unwrap().id;
assert_eq!(bindings.resolve(a), Some(Atom::Variable(a.clone())));
assert_eq!(bindings.resolve(b), Some(Atom::Variable(a.clone())));

assert_eq!(bindings.rename_binding(binding_id), Ok(()));
assert_eq!(bindings.resolve(a), Some(Atom::Variable(b.clone())));
assert_eq!(bindings.resolve(b), Some(Atom::Variable(b.clone())));

let mut bindings = Bindings::new().with_var_no_value(a);
let binding_id = bindings.get_binding(a).unwrap().id;
assert_eq!(bindings.rename_binding(binding_id), Err(()));
assert_eq!(bindings.resolve(a), Some(Atom::Variable(a.clone())));
Ok(())
}

#[ignore = "Unstable because HashMap doesn't guarantee the order of entries"]
#[test]
fn bindings_into_entries() -> Result<(), &'static str> {
Expand Down

0 comments on commit 2b45c30

Please sign in to comment.