]> Repositorios git - scryer-prolog.git/commitdiff
preserve heap contents in between goal expansions (#240, #241)
authorMark Thom <[email protected]>
Thu, 28 Nov 2019 07:45:13 +0000 (00:45 -0700)
committerMark Thom <[email protected]>
Thu, 28 Nov 2019 07:45:13 +0000 (00:45 -0700)
Cargo.lock
Cargo.toml
src/prolog/machine/term_expansion.rs
src/prolog/machine/toplevel.rs

index 48178a56054f831bdb473d53588ec07a9485e39b..dd192cb7d2a93bb8f6e9b2e230ddd46ebd394165 100644 (file)
@@ -311,7 +311,7 @@ dependencies = [
 
 [[package]]
 name = "prolog_parser"
-version = "0.8.35"
+version = "0.8.36"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "lexical 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -447,7 +447,7 @@ dependencies = [
  "nix 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-rug-adapter 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "ordered-float 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "prolog_parser 0.8.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "prolog_parser 0.8.36 (registry+https://github.com/rust-lang/crates.io-index)",
  "ref_thread_local 0.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rug 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustyline 5.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -590,7 +590,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum num-traits 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "443c53b3c3531dfcbfa499d8893944db78474ad7a1d87fa2d94d1a2231693ac6"
 "checksum ordered-float 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7eb5259643245d3f292c7a146b2df53bba24d7eab159410e648eb73dc164669d"
 "checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
-"checksum prolog_parser 0.8.35 (registry+https://github.com/rust-lang/crates.io-index)" = "1bc16334ea998d54f73cda14254fe546c57ae0c6c990263d50f7efd6ae10ea9d"
+"checksum prolog_parser 0.8.36 (registry+https://github.com/rust-lang/crates.io-index)" = "fea0ae985b51f28cb3582469fbe9318e238d504a7358d90eb671f0d772fb5061"
 "checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
 "checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
 "checksum rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
index 676e1707f76031991c2c70c8b66c3ce515d381ec..30099863b6b44e6547521b8e8b67058f7d26d008 100644 (file)
@@ -24,7 +24,7 @@ libc = "0.2.62"
 nix = "0.15.0"
 num-rug-adapter = { optional = true, version = "0.1.1" }
 ordered-float = "0.5.0"
-prolog_parser = { version = "0.8.35", default-features = false }
+prolog_parser = { version = "0.8.36", default-features = false }
 ref_thread_local = "0.0.0"
 rug = { version = "1.4.0", optional = true }
 rustyline = "5.0.3"
index f8ef4ed370b65403ecae17d3bb4ed71539b1d01f..f322f712aa0965e48aa8d85a1db579fc99dffe5f 100644 (file)
@@ -257,7 +257,6 @@ impl<'a, R: Read> TermStream<'a, R> {
                         self.enqueue_term(term)?
                     }
                     None => {
-                        let term = self.run_goal_expanders(&mut machine_st, op_dir, term)?;
                         return Ok(term);
                     }
                 };
@@ -281,40 +280,6 @@ impl<'a, R: Read> TermStream<'a, R> {
         }
     }
 
-    pub(crate) fn run_goal_expanders(
-        &mut self,
-        machine_st: &mut MachineState,
-        op_dir: &OpDir,
-        term: Term,
-    ) -> Result<Term, ParserError> {
-        match term {
-            Term::Clause(cell, name, mut terms, arity) => {
-                let mut new_terms = {
-                    let old_terms = match (name.as_str(), terms.len()) {
-                        (":-", 2) => {
-                            let comma_term = *terms.pop().unwrap();
-                            unfold_by_str(comma_term, ",")
-                        }
-                        ("?-", 1) => unfold_by_str(*terms.pop().unwrap(), ","),
-                        _ => return Ok(Term::Clause(cell, name, terms, arity)),
-                    };
-
-                    self.expand_goals(machine_st, op_dir, VecDeque::from(old_terms))?
-                };
-
-                let initial_term = new_terms.pop().unwrap();
-                terms.push(Box::new(fold_by_str(
-                    new_terms.into_iter(),
-                    initial_term,
-                    clause_name!(","),
-                )));
-
-                Ok(Term::Clause(cell, name, terms, arity))
-            }
-            _ => Ok(term),
-        }
-    }
-
     pub(super)
     fn expand_goals(
         &mut self,
@@ -374,6 +339,15 @@ impl MachineState {
         output
     }
 
+    // reset the machine, but keep the heap contents as they were.
+    // this prevents clashes between underscored variable names
+    // in the same query.
+    fn reset_with_heap_preservation(&mut self) {
+        let heap = self.heap.take();            
+        self.reset();
+        self.heap = heap;
+    }
+
     fn try_expand_term(
         &mut self,
         wam: &mut Machine,
@@ -398,7 +372,7 @@ impl MachineState {
         );
 
         if self.fail {
-            self.reset();
+            self.reset_with_heap_preservation();            
             None
         } else {
             let TermWriteResult { var_dict, .. } = term_write_result;
@@ -406,7 +380,7 @@ impl MachineState {
             self.heap_locs = var_dict;
             let output = self.print_with_locs(Addr::HeapCell(h), &wam.indices.op_dir);
 
-            self.reset();
+            self.reset_with_heap_preservation();            
             Some(output.result())
         }
     }
index a01d3dd852918704333ca32fddce8f58455492ba..ea91d1e62e6211d731965ea8c166073137b71418 100644 (file)
@@ -60,8 +60,8 @@ impl<'a, 'b, 'c, R: Read> CompositeIndices<'a, 'b, 'c, R> {
             IndexSource::TermStream => &mut self.term_stream.wam.indices.code_dir,
             IndexSource::Local(ref mut indices) => &mut indices.code_dir,
         }
-    }    
-    
+    }
+
     fn static_code_dir(&self) -> Option<&CodeDir> {
         match self.static_code_dir {
             Some(IndexSource::TermStream) => Some(&self.term_stream.wam.indices.code_dir),
@@ -84,7 +84,7 @@ impl<'a, 'b, 'c, R: Read> CompositeIndices<'a, 'b, 'c, R> {
             self.local_code_dir().insert((name.clone(), arity), idx.clone());
             idx
         } else {
-            let idx = CodeIndex::default();            
+            let idx = CodeIndex::default();
             self.local_code_dir().insert((name.clone(), arity), idx.clone());
             idx
         }
@@ -240,7 +240,7 @@ fn setup_module_export(
             } else {
                 Err(ParserError::InvalidModuleDecl)
             }
-        })    
+        })
 }
 
 fn setup_module_decl(
@@ -259,7 +259,7 @@ fn setup_module_decl(
 
     while let Term::Cons(_, t1, t2) = export_list {
         let module_export = setup_module_export(*t1, atom_tbl.clone())?;
-    
+
         exports.push(module_export);
         export_list = *t2;
     }
@@ -327,9 +327,14 @@ fn setup_qualified_import(
     }
 }
 
-fn is_consistent(tl: &TopLevel, clauses: &Vec<PredicateClause>) -> bool {
+fn is_consistent(
+    name: Option<ClauseName>,
+    arity: usize,
+    clauses: &Vec<PredicateClause>,
+) -> bool
+{
     match clauses.first() {
-        Some(ref cl) => tl.name() == cl.name() && tl.arity() == cl.arity(),
+        Some(ref cl) => name == cl.name() && arity == cl.arity(),
         None => true,
     }
 }
@@ -342,18 +347,18 @@ fn merge_clauses(tls: &mut VecDeque<TopLevel>) -> Result<TopLevel, ParserError>
             TopLevel::Query(_) if clauses.is_empty() && tls.is_empty() => return Ok(tl),
             TopLevel::Declaration(_) if clauses.is_empty() => return Ok(tl),
             TopLevel::Query(_) => return Err(ParserError::InconsistentEntry),
-            TopLevel::Fact(..) if is_consistent(&tl, &clauses) =>
+            TopLevel::Fact(..) if is_consistent(tl.name(), tl.arity(), &clauses) =>
                 if let TopLevel::Fact(fact, line_num, col_num) = tl {
                     let clause = PredicateClause::Fact(fact, line_num, col_num);
                     clauses.push(clause);
                 },
-            TopLevel::Rule(..) if is_consistent(&tl, &clauses) => {
+            TopLevel::Rule(..) if is_consistent(tl.name(), tl.arity(), &clauses) => {
                 if let TopLevel::Rule(rule, line_num, col_num) = tl {
                     let clause = PredicateClause::Rule(rule, line_num, col_num);
                     clauses.push(clause);
                 }
             }
-            TopLevel::Predicate(_) if is_consistent(&tl, &clauses) => {
+            TopLevel::Predicate(_) if is_consistent(tl.name(), tl.arity(), &clauses) => {
                 if let TopLevel::Predicate(pred) = tl {
                     clauses.extend(pred.clauses().into_iter())
                 }
@@ -751,11 +756,11 @@ impl RelationWorker {
                     if name.as_str() == "," {
                         let term = Term::Clause(cell, name, terms, op_spec);
                         let mut subterms = unfold_by_str(term, ",");
-                        
+
                         while let Some(subterm) = subterms.pop() {
                             work_queue.push_front(Box::new(subterm));
                         }
-                        
+
                         continue;
                     } else {
                         term = Term::Clause(cell, name, terms, op_spec);
@@ -769,7 +774,7 @@ impl RelationWorker {
                 query_terms.push(self.pre_query_term(indices, term)?);
             }
         }
-        
+
         Ok(query_terms)
     }
 
@@ -974,7 +979,7 @@ impl<'a, R: Read> TopLevelBatchWorker<'a, R> {
         &mut self,
         indices: &mut IndexStore,
         preds: &mut Vec<PredicateClause>,
-    ) -> Result<(), SessionError> {
+    ) -> Result<(), SessionError> {       
         let mut indices = CompositeIndices::new(
             &mut self.term_stream,
             IndexSource::Local(indices),
@@ -1020,17 +1025,18 @@ impl<'a, R: Read> TopLevelBatchWorker<'a, R> {
 
         while !self.term_stream.eof()? {
             let term = self.term_stream.read_term(&indices.op_dir)?;
-            let (mut tl, new_rel_worker) = self.try_term_to_tl(indices, term)?;
-
-            if tl.is_end_of_file_atom() {
-                tl = TopLevel::Declaration(Declaration::EndOfFile);
-            }
-
+            
             // if is_consistent is false, preds is non-empty.
-            if !is_consistent(&tl, &preds) {
+            if !is_consistent(term.predicate_name(), term.predicate_arity(), &preds) {
                 self.process_result(indices, &mut preds)?;
                 self.take_dynamic_clauses();
             }
+            
+            let (mut tl, new_rel_worker) = self.try_term_to_tl(indices, term)?;
+
+            if tl.is_end_of_file_atom() {
+                tl = TopLevel::Declaration(Declaration::EndOfFile);
+            }            
 
             self.rel_worker.absorb(new_rel_worker);