use acyclic iteration when projecting onto query vars
This commit is contained in:
@@ -280,6 +280,7 @@ pub enum SystemClauseType {
|
|||||||
SkipMaxList,
|
SkipMaxList,
|
||||||
Succeed,
|
Succeed,
|
||||||
TermVariables,
|
TermVariables,
|
||||||
|
TruncateLiftedHeapTo,
|
||||||
UnwindStack,
|
UnwindStack,
|
||||||
WriteTerm
|
WriteTerm
|
||||||
}
|
}
|
||||||
@@ -330,6 +331,7 @@ 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"),
|
||||||
}
|
}
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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) ))).
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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).",
|
||||||
|
|||||||
Reference in New Issue
Block a user