From: Mark Thom Date: Sat, 5 May 2018 19:20:06 +0000 (-0600) Subject: simplify detection of cycles in printer X-Git-Tag: v0.8.110~468 X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=885d7c04e32b451884f0eb8cf07c9f3484828953;p=scryer-prolog.git simplify detection of cycles in printer --- diff --git a/src/prolog/copier.rs b/src/prolog/copier.rs index 7a083656..3099cb8c 100644 --- a/src/prolog/copier.rs +++ b/src/prolog/copier.rs @@ -4,30 +4,13 @@ use prolog::ast::*; use std::collections::HashMap; use std::ops::IndexMut; -pub type Trail = Vec<(Ref, HeapCellValue)>; +type Trail = Vec<(Ref, HeapCellValue)>; -pub struct RedirectInfo { - trail: Trail, - list_redirect: HashMap, - offset: usize +pub(crate) struct RedirectInfo { + trail: Trail } -// allows us to reconstruct a HeapVarDict by relating variables -// in an existing HeapVarDict to the ones created in fn duplicate_term. -// It is used to create meaningful error reports at the toplevel. -pub struct CellRedirect(pub HashMap); - -impl CellRedirect { - pub fn new() -> Self { - CellRedirect(HashMap::new()) - } - - pub fn clear(&mut self) { - self.0.clear(); - } -} - -pub trait CopierTarget +pub(crate) trait CopierTarget { fn source(&self) -> usize; fn threshold(&self) -> usize; @@ -36,34 +19,6 @@ pub trait CopierTarget fn deref(&self, Addr) -> Addr; fn stack(&mut self) -> &mut AndStack; - // unwind the trail *and* compute a cell redirection table. - fn unwind_and_redirect(&mut self, redirect: RedirectInfo) -> CellRedirect - where Self: IndexMut - { - let mut cell_redirect: HashMap = HashMap::new(); - - for (r, hcv) in redirect.trail { - let addr = Addr::from(r); - - match r { - Ref::HeapCell(h) => { - cell_redirect.insert(addr, self[h].as_addr(h) - redirect.offset); - self[h] = hcv; - }, - Ref::StackCell(fr, sc) => { - cell_redirect.insert(addr, self.stack()[fr][sc].clone() - redirect.offset); - self.stack()[fr][sc] = hcv.as_addr(0); - } - }; - } - - for (l, h) in redirect.list_redirect { - cell_redirect.insert(Addr::Lis(l), Addr::Lis(h - redirect.offset)); - } - - CellRedirect(cell_redirect) - } - fn unwind_trail(&mut self, redirect: RedirectInfo) where Self: IndexMut { @@ -173,14 +128,7 @@ pub trait CopierTarget } } - RedirectInfo { trail, list_redirect, offset: old_h } - } - - fn duplicate_term_and_redirect(&mut self, addr: Addr) -> CellRedirect - where Self: IndexMut - { - let redirect = self.duplicate_term_impl(addr); - self.unwind_and_redirect(redirect) + RedirectInfo { trail } } fn duplicate_term(&mut self, addr: Addr) diff --git a/src/prolog/heap_print.rs b/src/prolog/heap_print.rs index 11a23ae1..e7f5ea48 100644 --- a/src/prolog/heap_print.rs +++ b/src/prolog/heap_print.rs @@ -190,7 +190,7 @@ impl<'a, Formatter: HCValueFormatter, Outputter: HCValueOutputter> fn print_offset(&mut self, addr: Addr) { match addr { - Addr::HeapCell(h) | Addr::Lis(h) => + Addr::HeapCell(h) | Addr::Lis(h) | Addr::Str(h) => self.outputter.append(format!("_{}", h).as_str()), Addr::StackCell(fr, sc) => self.outputter.append(format!("s_{}_{}", fr, sc).as_str()), diff --git a/src/prolog/machine/machine_state.rs b/src/prolog/machine/machine_state.rs index 51804f55..c5f10f98 100644 --- a/src/prolog/machine/machine_state.rs +++ b/src/prolog/machine/machine_state.rs @@ -221,7 +221,6 @@ pub struct MachineState { pub(super) hb: usize, pub(super) block: usize, // an offset into the OR stack. pub(super) ball: Ball, - pub(super) redirect: CellRedirect, pub(super) interms: Vec, // intermediate numbers. } diff --git a/src/prolog/machine/machine_state_impl.rs b/src/prolog/machine/machine_state_impl.rs index 8f1fd505..2392741d 100644 --- a/src/prolog/machine/machine_state_impl.rs +++ b/src/prolog/machine/machine_state_impl.rs @@ -50,7 +50,6 @@ impl MachineState { hb: 0, block: 0, ball: Ball::new(), - redirect: CellRedirect::new(), interms: vec![Number::default(); 256] } } @@ -1618,9 +1617,9 @@ impl MachineState { let addr = self[temp_v!(1)].clone(); self.ball.boundary = self.heap.h; - self.redirect = { + { let mut duplicator = DuplicateBallTerm::new(self); - duplicator.duplicate_term_and_redirect(addr) + duplicator.duplicate_term(addr); }; self.p += 1; @@ -2333,6 +2332,5 @@ impl MachineState { self.block = 0; self.ball.reset(); - self.redirect.clear(); } } diff --git a/src/tests.rs b/src/tests.rs index 9477caf2..df7cbae2 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -1313,6 +1313,13 @@ fn test_queries_on_builtins() assert_prolog_success!(&mut wam, "?- duplicate_term(f(X), f(X)).", [["X = _1"]]); + // test duplicate_term on cyclic terms. + assert_prolog_failure!(&mut wam, "?- X = g(X, Y), Y = f(X), duplicate_term(Y, g(Z))."); + assert_prolog_success!(&mut wam, "?- X = g(X, Y), Y = f(X), duplicate_term(Y, f(Z)).", + [["Y = f(g(X, Y))", "X = g(X, f(X))", "Z = g(Z, f(Z))"]]); + assert_prolog_success!(&mut wam, "?- X = g(X, Y), Y = f(X), duplicate_term(Y, V).", + [["Y = f(g(X, Y))", "X = g(X, f(X))", "V = f(g(_9, V))"]]); + assert_prolog_success!(&mut wam, "?- float(3.14159269)."); assert_prolog_failure!(&mut wam, "?- float(3)."); assert_prolog_failure!(&mut wam, "?- float(\"sdfsa\").");