From: Mark Thom Date: Sun, 28 Apr 2019 05:39:19 +0000 (-0600) Subject: speed up unification X-Git-Tag: v0.8.110~79 X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=e1350633251305e57fa12d07ce3b67102e8d9f85;p=scryer-prolog.git speed up unification --- diff --git a/Cargo.toml b/Cargo.toml index ec8c4405..222973ab 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "scryer-prolog" -version = "0.8.69" +version = "0.8.70" authors = ["Mark Thom "] repository = "https://github.com/mthom/scryer-prolog" description = "A modern Prolog implementation written mostly in Rust." diff --git a/src/prolog/heap_print.rs b/src/prolog/heap_print.rs index 9af3542a..4ec6ef16 100644 --- a/src/prolog/heap_print.rs +++ b/src/prolog/heap_print.rs @@ -487,7 +487,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> for _ in 0 .. arity { self.state_stack.push(TokenOrRedirect::FunctorRedirect); self.state_stack.push(TokenOrRedirect::Comma); - } + } self.state_stack.pop(); self.state_stack.push(TokenOrRedirect::Open); @@ -778,7 +778,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> fn print_string(&mut self, s: StringList) { match self.machine_st.machine_flags().double_quotes { - DoubleQuotes::Chars | DoubleQuotes::Codes => { + DoubleQuotes::Chars | DoubleQuotes::Codes => if !s.is_empty() { if self.ignore_ops { self.format_struct(2, clause_name!(".")); @@ -791,8 +791,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> } } else if !self.at_cdr("") { self.append_str("[]"); - } - }, + }, DoubleQuotes::Atom => { let borrowed_str = s.borrow(); @@ -802,7 +801,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> } } } - + fn push_list(&mut self) { let cell = Rc::new(Cell::new(true)); diff --git a/src/prolog/machine/machine_state_impl.rs b/src/prolog/machine/machine_state_impl.rs index 70427a65..f022f0d9 100644 --- a/src/prolog/machine/machine_state_impl.rs +++ b/src/prolog/machine/machine_state_impl.rs @@ -342,7 +342,8 @@ impl MachineState { pub(super) fn unify(&mut self, a1: Addr, a2: Addr) { let mut pdl = vec![a1, a2]; - + let mut tabu_list: HashSet<(Addr, Addr)> = HashSet::new(); + self.fail = false; while !(pdl.is_empty() || self.fail) { @@ -350,7 +351,16 @@ impl MachineState { let d2 = self.deref(pdl.pop().unwrap()); if d1 != d2 { - match (self.store(d1.clone()), self.store(d2.clone())) { + let d1 = self.store(d1); + let d2 = self.store(d2); + + if tabu_list.contains(&(d1.clone(), d2.clone())) { + continue; + } else { + tabu_list.insert((d1.clone(), d2.clone())); + } + + match (d1.clone(), d2.clone()) { (Addr::AttrVar(h), addr) | (addr, Addr::AttrVar(h)) => self.bind(Ref::AttrVar(h), addr), (Addr::HeapCell(h), _) =>