]> Repositorios git - scryer-prolog.git/commitdiff
evacuate arg at shallow level when necessary phase_1_milestone origin/phase_1_milestone
authorMark Thom <[email protected]>
Fri, 26 May 2017 18:59:03 +0000 (12:59 -0600)
committerMark Thom <[email protected]>
Fri, 26 May 2017 18:59:03 +0000 (12:59 -0600)
src/prolog/ast.rs
src/prolog/debray_allocator.rs

index f49a7baa2f56f74e8c9617e6e0de4d21d4e11ba3..f8005d2f07e80c22dbbec0b5e2eaedb4810e5ea0 100644 (file)
@@ -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)
index 29c5f1c7fcd5fe835a439740bcf1c79956d4e225..6c7a0d081ceec722b523749372ef17ea3bc27f95 100644 (file)
@@ -14,7 +14,14 @@ pub struct DebrayAllocator<'a> {
     in_use:   BTreeSet<usize>,
 }
 
-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) {