]> Repositorios git - scryer-prolog.git/commitdiff
simplify detection of cycles in printer
authorMark Thom <[email protected]>
Sat, 5 May 2018 19:20:06 +0000 (13:20 -0600)
committerMark Thom <[email protected]>
Sat, 5 May 2018 19:20:06 +0000 (13:20 -0600)
src/prolog/copier.rs
src/prolog/heap_print.rs
src/prolog/machine/machine_state.rs
src/prolog/machine/machine_state_impl.rs
src/tests.rs

index 7a08365652d1deb7755fee49494a9d5dd6f769cd..3099cb8c6f28a2b6f1d2a145832d8321b2ee6845 100644 (file)
@@ -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<usize, usize>,
-    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<Addr, Addr>);
-
-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<usize, Output=HeapCellValue>
-    {
-        let mut cell_redirect: HashMap<Addr, Addr> = 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<usize, Output=HeapCellValue>
     {
@@ -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<usize, Output=HeapCellValue>
-    {
-        let redirect = self.duplicate_term_impl(addr);
-        self.unwind_and_redirect(redirect)
+        RedirectInfo { trail }
     }
 
     fn duplicate_term(&mut self, addr: Addr)
index 11a23ae1f3e926836c41fab5107a0c6c8a5680f2..e7f5ea48442d789864dee112c8a8d7cdfbc2dfd9 100644 (file)
@@ -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()),
index 51804f55a59c5edc2ff93c979bebe71e187db643..c5f10f984196f1fd59c33a538a02e0087b98b0ce 100644 (file)
@@ -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<Number>, // intermediate numbers.
 }
 
index 8f1fd505e40c0989023f4359162f94415c98a143..2392741d47ec19f68641643fb89ca9c9af74fbef 100644 (file)
@@ -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();
     }
 }
index 9477caf23e5619bef402591e1dbe8f6df55cead7..df7cbae2a3cbc3520ea474a02470d5382f900c2e 100644 (file)
@@ -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\").");