]> Repositorios git - scryer-prolog.git/commitdiff
use acyclic iteration when projecting onto query vars
authorMark Thom <[email protected]>
Sat, 23 Feb 2019 00:48:49 +0000 (17:48 -0700)
committerMark Thom <[email protected]>
Sat, 23 Feb 2019 00:48:49 +0000 (17:48 -0700)
src/prolog/instructions.rs
src/prolog/lib/builtins.pl
src/prolog/machine/attributed_variables.rs
src/prolog/machine/system_calls.rs
src/prolog/write.rs
src/tests.rs

index 875921bc8486d26644e28abfd725b55b4ddf3620..779a51d52cba167b0cc5b76c79409b2e393b15a5 100644 (file)
@@ -249,7 +249,7 @@ pub enum SystemClauseType {
     TruncateIfNoLiftedHeapGrowth,
     GetAttributedVariableList,
     GetAttrVarQueueDelimiter,
-    GetAttrVarQueueBeyond,    
+    GetAttrVarQueueBeyond,
     GetBValue,
     GetLiftedHeapFromOffset,
     GetSCCCleaner,
@@ -280,13 +280,14 @@ pub enum SystemClauseType {
     SkipMaxList,
     Succeed,
     TermVariables,
+    TruncateLiftedHeapTo,
     UnwindStack,
     WriteTerm
 }
 
 impl SystemClauseType {
     pub fn name(&self) -> ClauseName {
-        match self {            
+        match self {
             &SystemClauseType::CheckCutPoint => clause_name!("$check_cp"),
             &SystemClauseType::CopyToLiftedHeap => clause_name!("$copy_to_lh"),
             &SystemClauseType::DeleteAttribute => clause_name!("$del_attr_non_head"),
@@ -330,17 +331,18 @@ impl SystemClauseType {
             &SystemClauseType::SkipMaxList => clause_name!("$skip_max_list"),
             &SystemClauseType::Succeed => clause_name!("$succeed"),
             &SystemClauseType::TermVariables => clause_name!("$term_variables"),
+            &SystemClauseType::TruncateLiftedHeapTo => clause_name!("$truncate_lh_to"),
             &SystemClauseType::UnwindStack => clause_name!("$unwind_stack"),
             &SystemClauseType::WriteTerm => clause_name!("$write_term"),
         }
     }
 
     pub fn from(name: &str, arity: usize) -> Option<SystemClauseType> {
-        match (name, arity) {            
+        match (name, arity) {
             ("$check_cp", 1) => Some(SystemClauseType::CheckCutPoint),
             ("$copy_to_lh", 2) => Some(SystemClauseType::CopyToLiftedHeap),
             ("$del_attr_non_head", 1) => Some(SystemClauseType::DeleteAttribute),
-            ("$del_attr_head", 1) => Some(SystemClauseType::DeleteHeadAttribute),            
+            ("$del_attr_head", 1) => Some(SystemClauseType::DeleteHeadAttribute),
             ("$module_call", 2) => Some(SystemClauseType::DynamicModuleResolution),
             ("$enqueue_attribute_goal", 1) => Some(SystemClauseType::EnqueueAttributeGoal),
             ("$enqueue_attr_var", 1) => Some(SystemClauseType::EnqueueAttributedVar),
@@ -379,6 +381,7 @@ impl SystemClauseType {
             ("$set_double_quotes", 1) => Some(SystemClauseType::SetDoubleQuotes),
             ("$skip_max_list", 4) => Some(SystemClauseType::SkipMaxList),
             ("$term_variables", 2) => Some(SystemClauseType::TermVariables),
+            ("$truncate_lh_to", 1) => Some(SystemClauseType::TruncateLiftedHeapTo),
             ("$unwind_stack", 0) => Some(SystemClauseType::UnwindStack),
             ("$write_term", 4) => Some(SystemClauseType::WriteTerm),
             _ => None
index 7fae977fbc31bbda5190ba8195e71addc4852d77..437ee42f19a4be1f799c21d3d187016484aac123 100644 (file)
@@ -361,10 +361,14 @@ throw(Ball) :- '$set_ball'(Ball), '$unwind_stack'.
     '$truncate_if_no_lh_growth'(LhOffset),
     '$get_lh_from_offset'(LhOffset, Solutions).
 
+truncate_lh_to(LhLength) :- '$truncate_lh_to'(LhLength).
+
 findall(Template, Goal, Solutions) :-
     '$skip_max_list'(_, -1, Solutions, R),
     (  nonvar(R), R \== [], throw(error(type_error(list, Solutions), findall/3))
     ;  true
     ),
     '$lh_length'(LhLength),
-    '$call_with_default_policy'('$iterate_find_all'(Template, Goal, Solutions, LhLength)).
+    '$call_with_default_policy'(catch('$iterate_find_all'(Template, Goal, Solutions, LhLength),
+                                     Error,
+                                     ( truncate_lh_to(LhLength), throw(Error) ))).
index 189704c2f2afe044ab3f2b50f700af6729d7be3f..174f89f4a2a3031be01bdfec0642048757f36f2a 100644 (file)
@@ -1,4 +1,3 @@
-use prolog::heap_iter::*;
 use prolog::machine::*;
 
 use std::collections::HashSet;
@@ -107,7 +106,7 @@ impl MachineState {
         let attr_vars = self.gather_attr_vars_created_since(0);
 
         for (_, addr) in var_dict {
-            let iter = HCPreOrderIterator::new(&self, addr.clone());
+            let iter = self.acyclic_pre_order_iter(addr.clone());
 
             for value in iter {
                 match value {
@@ -156,12 +155,12 @@ impl MachineState {
         self.p = CodePtr::Local(LocalCodePtr::DirEntry(p));
     }
 
-    fn print_attribute_goals(&mut self, var_dict: &HeapVarDict)
+    fn print_attribute_goals_string(&mut self, var_dict: &HeapVarDict) -> String
     {
         let mut attr_goals = mem::replace(&mut self.attr_var_init.attribute_goals, vec![]);
 
         if attr_goals.is_empty() {
-            return;
+            return String::from("");
         }
 
         attr_goals.sort_unstable_by(|a1, a2| self.compare_term_test(a1, a2));
@@ -184,13 +183,13 @@ impl MachineState {
         let output_len = output.len();
         output.truncate(output_len - 2);
 
-        println!("\r\n{}\r", output.result());
+        output.result()
     }
 }
 
 impl Machine {
     pub
-    fn attribute_goals(&mut self, var_dict: &HeapVarDict)
+    fn attribute_goals(&mut self, var_dict: &HeapVarDict) -> String
     {
         let p = self.machine_st.attr_var_init.project_attrs_loc;
         let (query_vars, attr_vars) = self.machine_st.populate_project_attr_lists(var_dict);
@@ -203,6 +202,6 @@ impl Machine {
         self.machine_st.p = CodePtr::Local(LocalCodePtr::DirEntry(p));
         self.machine_st.query_stepper(&mut self.indices, &mut self.policies, &mut self.code_repo);
 
-        self.machine_st.print_attribute_goals(var_dict);
+        self.machine_st.print_attribute_goals_string(var_dict)
     }
 }
index ed0208e3f2d839f684f8a9f0282d8fd097c6f4ef..a19227cd9db3152aac8f5bfa785564a455f9dc42 100644 (file)
@@ -743,6 +743,12 @@ impl MachineState {
                 let a2 = self[temp_v!(2)].clone();
                 self.unify(a2, outcome);
             },
+            &SystemClauseType::TruncateLiftedHeapTo =>
+                match self.store(self.deref(self[temp_v!(1)].clone())) {
+                    Addr::Con(Constant::Usize(lh_offset)) =>
+                        self.lifted_heap.truncate(lh_offset),
+                    _ => self.fail = true
+                },
             &SystemClauseType::UnwindStack => self.unwind_stack(),
             &SystemClauseType::WriteTerm => {
                 let addr = self[temp_v!(1)].clone();
index badc96df8208a8011932912912b37340da3dae8d..96224d5f8778ad14f3b6b20cdf5195b4950d9ec3 100644 (file)
@@ -383,7 +383,11 @@ pub fn print(wam: &mut Machine, result: EvalSession) {
                 write!(raw_stdout, "{}", bindings).unwrap();
                 raw_stdout.flush().unwrap();
 
-                wam.attribute_goals(&heap_locs);
+                let attr_goals = wam.attribute_goals(&heap_locs);
+
+                if !attr_goals.is_empty() {
+                    write!(raw_stdout, "\r\n{}\r", attr_goals).unwrap();
+                }
 
                 if !wam.or_stack_is_empty() {
                     raw_stdout.flush().unwrap();
index b0669b901a11826374989566ca4e0bb49b93f4cd..0288eb53dd4c824b6d735772fd3acd06282c5124 100644 (file)
@@ -1715,7 +1715,7 @@ fn test_queries_on_builtins()
     assert_prolog_success!(&mut wam, "?- findall(X, (X = 1 ; X = 2), S).",
                            [["S = [1, 2]", "X = _0"]]);
     assert_prolog_success!(&mut wam, "?- findall(X+Y, (X = 1), S).",
-                           [["S = [1+_18]", "X = _1", "Y = _2"]]);
+                           [["S = [1+_31]", "X = _1", "Y = _2"]]);
     assert_prolog_success!(&mut wam, "?- findall(X, false, S).",
                            [["S = []", "X = _0"]]);
     assert_prolog_success!(&mut wam, "?- findall(X, (X = 1 ; X = 1), S).",