use acyclic iteration when projecting onto query vars

This commit is contained in:
Mark Thom
2019-02-22 17:48:49 -07:00
parent f41b5f465e
commit 6ba47b6b08
6 changed files with 30 additions and 14 deletions

View File

@@ -249,7 +249,7 @@ pub enum SystemClauseType {
TruncateIfNoLiftedHeapGrowth, TruncateIfNoLiftedHeapGrowth,
GetAttributedVariableList, GetAttributedVariableList,
GetAttrVarQueueDelimiter, GetAttrVarQueueDelimiter,
GetAttrVarQueueBeyond, GetAttrVarQueueBeyond,
GetBValue, GetBValue,
GetLiftedHeapFromOffset, GetLiftedHeapFromOffset,
GetSCCCleaner, GetSCCCleaner,
@@ -280,13 +280,14 @@ pub enum SystemClauseType {
SkipMaxList, SkipMaxList,
Succeed, Succeed,
TermVariables, TermVariables,
TruncateLiftedHeapTo,
UnwindStack, UnwindStack,
WriteTerm WriteTerm
} }
impl SystemClauseType { impl SystemClauseType {
pub fn name(&self) -> ClauseName { pub fn name(&self) -> ClauseName {
match self { match self {
&SystemClauseType::CheckCutPoint => clause_name!("$check_cp"), &SystemClauseType::CheckCutPoint => clause_name!("$check_cp"),
&SystemClauseType::CopyToLiftedHeap => clause_name!("$copy_to_lh"), &SystemClauseType::CopyToLiftedHeap => clause_name!("$copy_to_lh"),
&SystemClauseType::DeleteAttribute => clause_name!("$del_attr_non_head"), &SystemClauseType::DeleteAttribute => clause_name!("$del_attr_non_head"),
@@ -330,17 +331,18 @@ impl SystemClauseType {
&SystemClauseType::SkipMaxList => clause_name!("$skip_max_list"), &SystemClauseType::SkipMaxList => clause_name!("$skip_max_list"),
&SystemClauseType::Succeed => clause_name!("$succeed"), &SystemClauseType::Succeed => clause_name!("$succeed"),
&SystemClauseType::TermVariables => clause_name!("$term_variables"), &SystemClauseType::TermVariables => clause_name!("$term_variables"),
&SystemClauseType::TruncateLiftedHeapTo => clause_name!("$truncate_lh_to"),
&SystemClauseType::UnwindStack => clause_name!("$unwind_stack"), &SystemClauseType::UnwindStack => clause_name!("$unwind_stack"),
&SystemClauseType::WriteTerm => clause_name!("$write_term"), &SystemClauseType::WriteTerm => clause_name!("$write_term"),
} }
} }
pub fn from(name: &str, arity: usize) -> Option<SystemClauseType> { pub fn from(name: &str, arity: usize) -> Option<SystemClauseType> {
match (name, arity) { match (name, arity) {
("$check_cp", 1) => Some(SystemClauseType::CheckCutPoint), ("$check_cp", 1) => Some(SystemClauseType::CheckCutPoint),
("$copy_to_lh", 2) => Some(SystemClauseType::CopyToLiftedHeap), ("$copy_to_lh", 2) => Some(SystemClauseType::CopyToLiftedHeap),
("$del_attr_non_head", 1) => Some(SystemClauseType::DeleteAttribute), ("$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), ("$module_call", 2) => Some(SystemClauseType::DynamicModuleResolution),
("$enqueue_attribute_goal", 1) => Some(SystemClauseType::EnqueueAttributeGoal), ("$enqueue_attribute_goal", 1) => Some(SystemClauseType::EnqueueAttributeGoal),
("$enqueue_attr_var", 1) => Some(SystemClauseType::EnqueueAttributedVar), ("$enqueue_attr_var", 1) => Some(SystemClauseType::EnqueueAttributedVar),
@@ -379,6 +381,7 @@ impl SystemClauseType {
("$set_double_quotes", 1) => Some(SystemClauseType::SetDoubleQuotes), ("$set_double_quotes", 1) => Some(SystemClauseType::SetDoubleQuotes),
("$skip_max_list", 4) => Some(SystemClauseType::SkipMaxList), ("$skip_max_list", 4) => Some(SystemClauseType::SkipMaxList),
("$term_variables", 2) => Some(SystemClauseType::TermVariables), ("$term_variables", 2) => Some(SystemClauseType::TermVariables),
("$truncate_lh_to", 1) => Some(SystemClauseType::TruncateLiftedHeapTo),
("$unwind_stack", 0) => Some(SystemClauseType::UnwindStack), ("$unwind_stack", 0) => Some(SystemClauseType::UnwindStack),
("$write_term", 4) => Some(SystemClauseType::WriteTerm), ("$write_term", 4) => Some(SystemClauseType::WriteTerm),
_ => None _ => None

View File

@@ -361,10 +361,14 @@ throw(Ball) :- '$set_ball'(Ball), '$unwind_stack'.
'$truncate_if_no_lh_growth'(LhOffset), '$truncate_if_no_lh_growth'(LhOffset),
'$get_lh_from_offset'(LhOffset, Solutions). '$get_lh_from_offset'(LhOffset, Solutions).
truncate_lh_to(LhLength) :- '$truncate_lh_to'(LhLength).
findall(Template, Goal, Solutions) :- findall(Template, Goal, Solutions) :-
'$skip_max_list'(_, -1, Solutions, R), '$skip_max_list'(_, -1, Solutions, R),
( nonvar(R), R \== [], throw(error(type_error(list, Solutions), findall/3)) ( nonvar(R), R \== [], throw(error(type_error(list, Solutions), findall/3))
; true ; true
), ),
'$lh_length'(LhLength), '$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) ))).

View File

@@ -1,4 +1,3 @@
use prolog::heap_iter::*;
use prolog::machine::*; use prolog::machine::*;
use std::collections::HashSet; use std::collections::HashSet;
@@ -107,7 +106,7 @@ impl MachineState {
let attr_vars = self.gather_attr_vars_created_since(0); let attr_vars = self.gather_attr_vars_created_since(0);
for (_, addr) in var_dict { 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 { for value in iter {
match value { match value {
@@ -156,12 +155,12 @@ impl MachineState {
self.p = CodePtr::Local(LocalCodePtr::DirEntry(p)); 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![]); let mut attr_goals = mem::replace(&mut self.attr_var_init.attribute_goals, vec![]);
if attr_goals.is_empty() { if attr_goals.is_empty() {
return; return String::from("");
} }
attr_goals.sort_unstable_by(|a1, a2| self.compare_term_test(a1, a2)); attr_goals.sort_unstable_by(|a1, a2| self.compare_term_test(a1, a2));
@@ -184,13 +183,13 @@ impl MachineState {
let output_len = output.len(); let output_len = output.len();
output.truncate(output_len - 2); output.truncate(output_len - 2);
println!("\r\n{}\r", output.result()); output.result()
} }
} }
impl Machine { impl Machine {
pub 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 p = self.machine_st.attr_var_init.project_attrs_loc;
let (query_vars, attr_vars) = self.machine_st.populate_project_attr_lists(var_dict); 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.p = CodePtr::Local(LocalCodePtr::DirEntry(p));
self.machine_st.query_stepper(&mut self.indices, &mut self.policies, &mut self.code_repo); 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)
} }
} }

View File

@@ -743,6 +743,12 @@ impl MachineState {
let a2 = self[temp_v!(2)].clone(); let a2 = self[temp_v!(2)].clone();
self.unify(a2, outcome); 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::UnwindStack => self.unwind_stack(),
&SystemClauseType::WriteTerm => { &SystemClauseType::WriteTerm => {
let addr = self[temp_v!(1)].clone(); let addr = self[temp_v!(1)].clone();

View File

@@ -383,7 +383,11 @@ pub fn print(wam: &mut Machine, result: EvalSession) {
write!(raw_stdout, "{}", bindings).unwrap(); write!(raw_stdout, "{}", bindings).unwrap();
raw_stdout.flush().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() { if !wam.or_stack_is_empty() {
raw_stdout.flush().unwrap(); raw_stdout.flush().unwrap();

View File

@@ -1715,7 +1715,7 @@ fn test_queries_on_builtins()
assert_prolog_success!(&mut wam, "?- findall(X, (X = 1 ; X = 2), S).", assert_prolog_success!(&mut wam, "?- findall(X, (X = 1 ; X = 2), S).",
[["S = [1, 2]", "X = _0"]]); [["S = [1, 2]", "X = _0"]]);
assert_prolog_success!(&mut wam, "?- findall(X+Y, (X = 1), S).", 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).", assert_prolog_success!(&mut wam, "?- findall(X, false, S).",
[["S = []", "X = _0"]]); [["S = []", "X = _0"]]);
assert_prolog_success!(&mut wam, "?- findall(X, (X = 1 ; X = 1), S).", assert_prolog_success!(&mut wam, "?- findall(X, (X = 1 ; X = 1), S).",