From 8402f7a608156cc3dd24ed8bcbc8d17884e02df1 Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Fri, 26 May 2017 12:59:03 -0600 Subject: [PATCH] evacuate arg at shallow level when necessary --- src/prolog/ast.rs | 9 +++++++++ src/prolog/debray_allocator.rs | 24 ++++++++++++++++++++---- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/src/prolog/ast.rs b/src/prolog/ast.rs index f49a7baa..f8005d2f 100644 --- a/src/prolog/ast.rs +++ b/src/prolog/ast.rs @@ -13,6 +13,15 @@ pub enum GenContext { Head, Mid(usize), Last(usize) // Mid & Last: chunk_num } +impl GenContext { + pub fn chunk_num(self) -> usize { + match self { + GenContext::Head => 0, + GenContext::Mid(cn) | GenContext::Last(cn) => cn + } + } +} + pub enum PredicateClause { Fact(Term), Rule(Rule) diff --git a/src/prolog/debray_allocator.rs b/src/prolog/debray_allocator.rs index 29c5f1c7..6c7a0d08 100644 --- a/src/prolog/debray_allocator.rs +++ b/src/prolog/debray_allocator.rs @@ -14,7 +14,14 @@ pub struct DebrayAllocator<'a> { in_use: BTreeSet, } -impl<'a> DebrayAllocator<'a> { +impl<'a> DebrayAllocator<'a> { + fn is_curr_arg_distinct_from(&self, var: &'a Var) -> bool { + match self.contents.get(&self.arg_c) { + Some(t_var) if **t_var != *var => true, + _ => false + } + } + fn occurs_shallowly_in_head(&self, var: &'a Var, r: usize) -> bool { match self.bindings.get(var).unwrap() { @@ -142,6 +149,7 @@ impl<'a> DebrayAllocator<'a> { match term_loc { GenContext::Head => if let Level::Shallow = lvl { + self.evacuate_arg(0, target); self.alloc_with_cr(var) } else { self.alloc_with_ca(var) @@ -262,14 +270,22 @@ impl<'a> Allocator<'a> for DebrayAllocator<'a> RegType::Perm(0) => { let pr = cell.get().norm(); self.record_register(var, pr); + (pr, true) }, - r => (r, false) + r => (r, false) }; match lvl { Level::Shallow => { let k = self.arg_c; + + if !r.is_perm() { + if self.is_curr_arg_distinct_from(var) { + self.evacuate_arg(term_loc.chunk_num(), target); + } + } + self.arg_c += 1; cell.set(VarReg::ArgAndNorm(r, k)); @@ -295,14 +311,14 @@ impl<'a> Allocator<'a> for DebrayAllocator<'a> Level::Deep => target.push(Target::subterm_to_value(r)) }; - + if !r.is_perm() { let o = r.reg_num(); self.contents.insert(o, var); self.record_register(var, r); self.in_use.insert(o); - } + } } fn reset(&mut self) { -- 2.54.0