]> Repositorios git - scryer-prolog.git/commitdiff
incomplete cut corrections.
authorMark Thom <[email protected]>
Sat, 7 Apr 2018 06:15:34 +0000 (00:15 -0600)
committerMark Thom <[email protected]>
Sat, 7 Apr 2018 06:15:34 +0000 (00:15 -0600)
src/prolog/allocator.rs
src/prolog/ast.rs
src/prolog/codegen.rs
src/prolog/debray_allocator.rs
src/prolog/io.rs
src/prolog/iterators.rs
src/prolog/machine/mod.rs
src/prolog/parser

index 5fbe9fac0ca456aa062d857c087acc10cc12b8cf..b075b5c1fcf04d6f8bff75f1a19014106e56270a 100644 (file)
@@ -8,19 +8,22 @@ use std::rc::Rc;
 pub trait Allocator<'a>
 {
     fn new() -> Self;
-    
+
     fn mark_anon_var<Target>(&mut self, Level, &mut Vec<Target>)
         where Target: CompilationTarget<'a>;
     fn mark_non_var<Target>(&mut self, Level, GenContext, &'a Cell<RegType>, &mut Vec<Target>)
         where Target: CompilationTarget<'a>;
+    fn mark_reserved_var<Target>(&mut self, Rc<Var>, Level, &'a Cell<VarReg>, GenContext,
+                                 &mut Vec<Target>, RegType, bool)
+        where Target: CompilationTarget<'a>;
     fn mark_var<Target>(&mut self, Rc<Var>, Level, &'a Cell<VarReg>, GenContext, &mut Vec<Target>)
-        where Target: CompilationTarget<'a>;    
-    
+        where Target: CompilationTarget<'a>;
+
     fn reset(&mut self);
     fn reset_contents(&mut self) {}
     fn reset_arg(&mut self, usize);
     fn reset_at_head(&mut self, &Vec<Box<Term>>);
-    
+
     fn advance_arg(&mut self);
 
     fn bindings(&self) -> &AllocVarDict;
@@ -46,15 +49,15 @@ pub trait Allocator<'a>
 
         perm_vs
     }
-    
+
     fn get(&self, var: Rc<Var>) -> RegType {
         self.bindings().get(&var).map_or(temp_v!(0), |v| v.as_reg_type())
     }
 
     fn is_unbound(&self, var: Rc<Var>) -> bool {
-        self.get(var) == temp_v!(0)
+        self.get(var).reg_num() == 0
     }
-    
+
     fn record_register(&mut self, var: Rc<Var>, r: RegType) {
         match self.bindings_mut().get_mut(&var).unwrap() {
             &mut VarData::Temp(_, ref mut s, _) => *s = r.reg_num(),
index d2c8d4d6aeca50629a759a622ee6bcc18587b2a9..f30644653580e8ab210713b24f56e05cf255dda3 100644 (file)
@@ -668,7 +668,8 @@ pub type JumpStub = Vec<Term>;
 
 pub enum QueryTerm {
     Clause(Cell<RegType>, ClauseType, Vec<Box<Term>>),
-    Cut,
+    BlockedCut, // a cut which is 'blocked by letters', like the P term in P -> Q.
+    UnblockedCut,
     Jump(JumpStub)
 }
 
@@ -676,7 +677,7 @@ impl QueryTerm {
     pub fn arity(&self) -> usize {
         match self {
             &QueryTerm::Clause(_, _, ref subterms) => subterms.len(),
-            &QueryTerm::Cut => 0,
+            &QueryTerm::BlockedCut | &QueryTerm::UnblockedCut => 0,
             &QueryTerm::Jump(ref vars) => vars.len()
         }
     }
index e10d9fd9f08ad76946f680b267cbbf9469e422bd..05b9bf2aafa6e6ab17fd69ad2527a732bc467774 100644 (file)
@@ -161,6 +161,17 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
                     } else {
                         self.marker.mark_anon_var(lvl, &mut target);
                     },
+                TermRef::Var(lvl @ Level::Shallow, cell, ref var) if var.as_str() == "!" => {
+                    if self.marker.is_unbound(var.clone()) {
+                        if term_loc != GenContext::Head {
+                            self.marker.mark_reserved_var(var.clone(), lvl, cell, term_loc,
+                                                          &mut target, perm_v!(1), false);
+                            continue;
+                        }
+                    }
+
+                    self.marker.mark_var(var.clone(), lvl, cell, term_loc, &mut target);
+                },
                 TermRef::Var(lvl @ Level::Shallow, cell, var) =>
                     self.marker.mark_var(var.clone(), lvl, cell, term_loc, &mut target),
                 _ => {}
@@ -397,7 +408,9 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
                 };
 
                 match *term {
-                    &QueryTerm::Cut =>
+                    &QueryTerm::UnblockedCut =>
+                        code.push(set_cp!(self.marker.get(rc_atom!("!")))),                    
+                    &QueryTerm::BlockedCut =>
                         code.push(if chunk_num == 0 {
                             Line::Cut(CutInstruction::NeckCut)
                         } else {
@@ -469,7 +482,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
     {
         // add a proceed to bookend any trailing cuts.
         match toc {
-            &QueryTerm::Cut => code.push(proceed!()),
+            &QueryTerm::BlockedCut | &QueryTerm::UnblockedCut => code.push(proceed!()),
             _ => {}
         };
 
index 00aa1ed2554841dccd2a548b4389bde232ecb304..2ded88f8bc299a340305b12a6183de1cdd6db70a 100644 (file)
@@ -249,7 +249,7 @@ impl<'a> Allocator<'a> for DebrayAllocator
         }
     }
 
-    fn mark_var<Target>(&mut self, var: Rc<Var>, lvl: Level, cell: &Cell<VarReg>,
+    fn mark_var<Target>(&mut self, var: Rc<Var>, lvl: Level, cell: &'a Cell<VarReg>,
                         term_loc: GenContext, target: &mut Vec<Target>)
         where Target: CompilationTarget<'a>
     {
@@ -271,6 +271,14 @@ impl<'a> Allocator<'a> for DebrayAllocator
             r => (r, false)
         };
 
+        self.mark_reserved_var(var, lvl, cell, term_loc, target, r, is_new_var);
+    }
+
+    fn mark_reserved_var<Target>(&mut self, var: Rc<Var>, lvl: Level, cell: &'a Cell<VarReg>,
+                                 term_loc: GenContext, target: &mut Vec<Target>, r: RegType,
+                                 is_new_var: bool)
+      where Target: CompilationTarget<'a>
+    {
         match lvl {
             Level::Root | Level::Shallow => {
                 let k = self.arg_c;
index 293d5484b41a065416c19e97c4595170372bf7fd..89440174e383801321460be9115d853554a94f58 100644 (file)
@@ -540,6 +540,8 @@ fn compile_query(terms: Vec<QueryTerm>, queue: Vec<TopLevel>, code_size: usize,
     let query_info = QueryInfo {};
     query_info.label_clauses(code_size, code_dir, &mut code);
 
+    print_code(&code);
+    
     Ok((code, cg.take_vars()))
 }
 
@@ -571,6 +573,8 @@ fn compile_decl(wam: &mut Machine, tl: TopLevel, queue: Vec<TopLevel>) -> EvalSe
 
             decl_info.label_clauses(wam.code_size(), &mut wam.code_dir, &mut code);
 
+            print_code(&code);
+            
             if !code.is_empty() {
                 wam.add_user_code(name, tl.arity(), code, tl.as_predicate().unwrap())
             } else {
index e8bee4296db0fd38766192ad028afc9e77b012c5..8ed518e61054ec5ff2c8ef9cb5aee30662278d25 100644 (file)
@@ -50,7 +50,8 @@ impl<'a> QueryIterator<'a> {
                 let state = TermIterState::Clause(Level::Root, 0, cell, ct.clone(), terms);
                 QueryIterator { state_stack: vec![state] }
             },
-            &QueryTerm::Cut => QueryIterator { state_stack: vec![] },
+            &QueryTerm::BlockedCut | &QueryTerm::UnblockedCut =>
+                QueryIterator { state_stack: vec![] },
             &QueryTerm::Jump(ref vars) => {
                 let state_stack = vars.iter().rev().map(|t| {
                     TermIterState::subterm_to_state(Level::Shallow, t)
@@ -213,11 +214,24 @@ impl<'a> ChunkedTerm<'a> {
     }
 }
 
+fn contains_cut_var<'a, Iter: Iterator<Item=&'a Term>>(terms: Iter) -> bool {
+    for term in terms {
+        if let &Term::Var(_, ref var) = term {
+            if var.as_str() == "!" {
+                return true;
+            }
+        }
+    }
+
+    false
+}
+
 pub struct ChunkedIterator<'a>
 {
     pub chunk_num: usize,
     iter: Box<Iterator<Item=ChunkedTerm<'a>> + 'a>,
-    deep_cut_encountered: bool
+    deep_cut_encountered: bool,
+    cut_var_in_head: bool
 }
 
 type ChunkedIteratorItem<'a>  = (usize, usize, Vec<ChunkedTerm<'a>>);
@@ -248,7 +262,8 @@ impl<'a> ChunkedIterator<'a>
         ChunkedIterator {
             chunk_num: 0,
             iter: Box::new(terms.iter().map(|t| ChunkedTerm::BodyTerm(t))),
-            deep_cut_encountered: false
+            deep_cut_encountered: false,
+            cut_var_in_head: false
         }
     }
 
@@ -260,7 +275,8 @@ impl<'a> ChunkedIterator<'a>
         ChunkedIterator {
             chunk_num: 0,
             iter: Box::new(iter),
-            deep_cut_encountered: false
+            deep_cut_encountered: false,
+            cut_var_in_head: false
         }
     }
 
@@ -276,6 +292,7 @@ impl<'a> ChunkedIterator<'a>
             chunk_num: 0,
             iter: Box::new(iter),
             deep_cut_encountered: false,
+            cut_var_in_head: false
         }
     }
 
@@ -291,20 +308,32 @@ impl<'a> ChunkedIterator<'a>
 
         while let Some(term) = item {
             match term {
-                ChunkedTerm::HeadClause(..) =>
-                    result.push(term),
+                ChunkedTerm::HeadClause(_, terms) => {
+                    if contains_cut_var(terms.iter().map(|t| t.as_ref())) {
+                        self.cut_var_in_head = true;
+                    }
+
+                    result.push(term);
+                },
                 ChunkedTerm::BodyTerm(&QueryTerm::Jump(ref vars)) => {
                     result.push(term);
                     arity = vars.len();
+
+                    if contains_cut_var(vars.iter()) && !self.cut_var_in_head {
+                        self.deep_cut_encountered = true;
+                    }
+                    
                     break;
                 },
-                ChunkedTerm::BodyTerm(&QueryTerm::Cut) => {
+                ChunkedTerm::BodyTerm(&QueryTerm::BlockedCut) => {
                     result.push(term);
 
                     if self.chunk_num > 0 {
                         self.deep_cut_encountered = true;
                     }
                 },
+                ChunkedTerm::BodyTerm(&QueryTerm::UnblockedCut) =>
+                    result.push(term),                
                 ChunkedTerm::BodyTerm(&QueryTerm::Clause(_, ClauseType::Inlined(_), _)) =>
                     result.push(term),
                 ChunkedTerm::BodyTerm(&QueryTerm::Clause(_, ClauseType::CallN, ref subterms)) => {
index b1d35baa813eaa3678a101356f2f0d800bb15678..c06ecc3a88c660adc0bd64cdb5d4d1c7f84676d3 100644 (file)
@@ -306,13 +306,12 @@ impl Machine {
     {
         for (var, var_data) in alloc_locs {
             match var_data {
-                &VarData::Perm(_) => {
+                &VarData::Perm(p) if p > 0 => {
                     let e = self.ms.e;
-
                     let r = var_data.as_reg_type().reg_num();
                     let addr = self.ms.and_stack[e][r].clone();
-
-                    heap_locs.insert(var.clone(), addr);
+                    
+                    heap_locs.insert(var.clone(), addr);                    
                 },
                 &VarData::Temp(cn, _, _) if cn == chunk_num => {
                     let r = var_data.as_reg_type();
index ad4f9e573069ab5932c060d0ed093432f3d31c58..737d6ba091bb5909b0af31c221f290debc95bf2d 160000 (submodule)
@@ -1 +1 @@
-Subproject commit ad4f9e573069ab5932c060d0ed093432f3d31c58
+Subproject commit 737d6ba091bb5909b0af31c221f290debc95bf2d