From 6ba47b6b08d51a13312df17e029484078780a56e Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Fri, 22 Feb 2019 17:48:49 -0700 Subject: [PATCH] use acyclic iteration when projecting onto query vars --- src/prolog/instructions.rs | 11 +++++++---- src/prolog/lib/builtins.pl | 6 +++++- src/prolog/machine/attributed_variables.rs | 13 ++++++------- src/prolog/machine/system_calls.rs | 6 ++++++ src/prolog/write.rs | 6 +++++- src/tests.rs | 2 +- 6 files changed, 30 insertions(+), 14 deletions(-) diff --git a/src/prolog/instructions.rs b/src/prolog/instructions.rs index 875921bc..779a51d5 100644 --- a/src/prolog/instructions.rs +++ b/src/prolog/instructions.rs @@ -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 { - 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 diff --git a/src/prolog/lib/builtins.pl b/src/prolog/lib/builtins.pl index 7fae977f..437ee42f 100644 --- a/src/prolog/lib/builtins.pl +++ b/src/prolog/lib/builtins.pl @@ -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) ))). diff --git a/src/prolog/machine/attributed_variables.rs b/src/prolog/machine/attributed_variables.rs index 189704c2..174f89f4 100644 --- a/src/prolog/machine/attributed_variables.rs +++ b/src/prolog/machine/attributed_variables.rs @@ -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) } } diff --git a/src/prolog/machine/system_calls.rs b/src/prolog/machine/system_calls.rs index ed0208e3..a19227cd 100644 --- a/src/prolog/machine/system_calls.rs +++ b/src/prolog/machine/system_calls.rs @@ -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(); diff --git a/src/prolog/write.rs b/src/prolog/write.rs index badc96df..96224d5f 100644 --- a/src/prolog/write.rs +++ b/src/prolog/write.rs @@ -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(); diff --git a/src/tests.rs b/src/tests.rs index b0669b90..0288eb53 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -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).", -- 2.54.0