add call_residue_vars/2
This commit is contained in:
@@ -11,6 +11,7 @@ pub(super) type Bindings = Vec<(usize, Addr)>;
|
||||
|
||||
pub(super) struct AttrVarInitializer {
|
||||
pub(super) attribute_goals: Vec<Addr>,
|
||||
pub(super) attr_var_queue: Vec<usize>,
|
||||
pub(super) bindings: Bindings,
|
||||
pub(super) cp: LocalCodePtr,
|
||||
pub(super) verify_attrs_loc: usize,
|
||||
@@ -21,6 +22,7 @@ impl AttrVarInitializer {
|
||||
pub(super) fn new(verify_attrs_loc: usize, project_attrs_loc: usize) -> Self {
|
||||
AttrVarInitializer {
|
||||
attribute_goals: vec![],
|
||||
attr_var_queue: vec![],
|
||||
bindings: vec![],
|
||||
cp: LocalCodePtr::default(),
|
||||
verify_attrs_loc,
|
||||
@@ -30,6 +32,7 @@ impl AttrVarInitializer {
|
||||
|
||||
#[inline]
|
||||
pub(super) fn reset(&mut self) {
|
||||
self.attr_var_queue.clear();
|
||||
self.bindings.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -341,6 +341,9 @@ pub(crate) trait CallPolicy: Any {
|
||||
|
||||
machine_st.heap.truncate(machine_st.or_stack[b].h);
|
||||
|
||||
let attr_var_init_b = machine_st.or_stack[b].attr_var_init_b;
|
||||
machine_st.attr_var_init.attr_var_queue.truncate(attr_var_init_b);
|
||||
|
||||
machine_st.hb = machine_st.heap.h;
|
||||
machine_st.p += 1;
|
||||
|
||||
@@ -379,6 +382,9 @@ pub(crate) trait CallPolicy: Any {
|
||||
|
||||
machine_st.heap.truncate(machine_st.or_stack[b].h);
|
||||
|
||||
let attr_var_init_b = machine_st.or_stack[b].attr_var_init_b;
|
||||
machine_st.attr_var_init.attr_var_queue.truncate(attr_var_init_b);
|
||||
|
||||
machine_st.hb = machine_st.heap.h;
|
||||
machine_st.p += offset;
|
||||
|
||||
@@ -414,8 +420,11 @@ pub(crate) trait CallPolicy: Any {
|
||||
machine_st.pstr_trail.truncate(machine_st.pstr_tr);
|
||||
|
||||
machine_st.heap.truncate(machine_st.or_stack[b].h);
|
||||
machine_st.b = machine_st.or_stack[b].b;
|
||||
|
||||
let attr_var_init_b = machine_st.or_stack[b].attr_var_init_b;
|
||||
machine_st.attr_var_init.attr_var_queue.truncate(attr_var_init_b);
|
||||
|
||||
machine_st.b = machine_st.or_stack[b].b;
|
||||
machine_st.or_stack.truncate(machine_st.b);
|
||||
|
||||
machine_st.hb = machine_st.heap.h;
|
||||
@@ -454,8 +463,10 @@ pub(crate) trait CallPolicy: Any {
|
||||
|
||||
machine_st.heap.truncate(machine_st.or_stack[b].h);
|
||||
|
||||
machine_st.b = machine_st.or_stack[b].b;
|
||||
let attr_var_init_b = machine_st.or_stack[b].attr_var_init_b;
|
||||
machine_st.attr_var_init.attr_var_queue.truncate(attr_var_init_b);
|
||||
|
||||
machine_st.b = machine_st.or_stack[b].b;
|
||||
machine_st.or_stack.truncate(machine_st.b);
|
||||
|
||||
machine_st.hb = machine_st.heap.h;
|
||||
|
||||
@@ -2256,6 +2256,7 @@ impl MachineState {
|
||||
self.or_stack.push(gi,
|
||||
self.e,
|
||||
self.cp.clone(),
|
||||
self.attr_var_init.attr_var_queue.len(),
|
||||
self.b,
|
||||
self.p.clone() + 1,
|
||||
self.tr,
|
||||
@@ -2288,10 +2289,11 @@ impl MachineState {
|
||||
&ChoiceInstruction::TryMeElse(offset) => {
|
||||
let n = self.num_of_args;
|
||||
let gi = self.next_global_index();
|
||||
|
||||
|
||||
self.or_stack.push(gi,
|
||||
self.e,
|
||||
self.cp.clone(),
|
||||
self.attr_var_init.attr_var_queue.len(),
|
||||
self.b,
|
||||
self.p.clone() + offset,
|
||||
self.tr,
|
||||
|
||||
@@ -31,7 +31,7 @@ impl MachineState {
|
||||
// a step in Brent's algorithm.
|
||||
fn brents_alg_step(&self, brent_st: &mut BrentAlgState) -> Option<CycleSearchResult>
|
||||
{
|
||||
match self.heap[brent_st.hare].clone() {
|
||||
match self.heap[brent_st.hare].clone() {
|
||||
HeapCellValue::NamedStr(..) =>
|
||||
Some(CycleSearchResult::NotList),
|
||||
HeapCellValue::Addr(addr) =>
|
||||
@@ -43,14 +43,14 @@ impl MachineState {
|
||||
Addr::Lis(l) => {
|
||||
brent_st.hare = l + 1;
|
||||
brent_st.steps += 1;
|
||||
|
||||
|
||||
if brent_st.tortoise == brent_st.hare {
|
||||
return Some(CycleSearchResult::NotList);
|
||||
} else if brent_st.steps == brent_st.power {
|
||||
brent_st.tortoise = brent_st.hare;
|
||||
brent_st.power <<= 1;
|
||||
}
|
||||
|
||||
|
||||
None
|
||||
},
|
||||
_ =>
|
||||
@@ -204,7 +204,7 @@ impl MachineState {
|
||||
Addr::Con(Constant::Usize(old_b)) if self.b <= old_b + 2 => {},
|
||||
_ => self.fail = true
|
||||
};
|
||||
},
|
||||
},
|
||||
&SystemClauseType::DeleteAttribute => {
|
||||
let ls0 = self.store(self.deref(self[temp_v!(1)].clone()));
|
||||
|
||||
@@ -265,6 +265,15 @@ impl MachineState {
|
||||
let addr = self[temp_v!(1)].clone();
|
||||
self.attr_var_init.attribute_goals.push(addr);
|
||||
},
|
||||
&SystemClauseType::EnqueueAttributedVar => {
|
||||
let addr = self[temp_v!(1)].clone();
|
||||
|
||||
match self.store(self.deref(addr)) {
|
||||
Addr::AttrVar(h) =>
|
||||
self.attr_var_init.attr_var_queue.push(h),
|
||||
_ => {}
|
||||
}
|
||||
},
|
||||
&SystemClauseType::ExpandGoal => {
|
||||
self.p = CodePtr::Local(LocalCodePtr::UserGoalExpansion(0));
|
||||
return Ok(());
|
||||
@@ -296,6 +305,35 @@ impl MachineState {
|
||||
let list_addr = self[temp_v!(2)].clone();
|
||||
self.unify(Addr::HeapCell(attr_var_list), list_addr);
|
||||
},
|
||||
&SystemClauseType::GetAttrVarQueueDelimiter => {
|
||||
let addr = self[temp_v!(1)].clone();
|
||||
let value = Addr::Con(Constant::Usize(self.attr_var_init.attr_var_queue.len()));
|
||||
|
||||
self.unify(addr, value);
|
||||
},
|
||||
&SystemClauseType::GetAttrVarQueueBeyond => {
|
||||
let addr = self[temp_v!(1)].clone();
|
||||
|
||||
match self.store(self.deref(addr)) {
|
||||
Addr::Con(Constant::Usize(b)) => {
|
||||
let mut attr_vars: Vec<_> = self.attr_var_init.attr_var_queue[b ..]
|
||||
.iter().filter_map(|h|
|
||||
match self.store(self.deref(Addr::HeapCell(*h))) {
|
||||
Addr::AttrVar(h) => Some(Addr::AttrVar(h)),
|
||||
_ => None
|
||||
}).collect();
|
||||
|
||||
attr_vars.sort_unstable_by(|a1, a2| self.compare_term_test(a1, a2));
|
||||
|
||||
self.term_dedup(&mut attr_vars);
|
||||
let var_list_addr = Addr::HeapCell(self.heap.to_list(attr_vars.into_iter()));
|
||||
|
||||
let list_addr = self[temp_v!(2)].clone();
|
||||
self.unify(var_list_addr, list_addr);
|
||||
},
|
||||
_ => self.fail = true
|
||||
}
|
||||
},
|
||||
&SystemClauseType::GetDoubleQuotes => {
|
||||
let a1 = self[temp_v!(1)].clone();
|
||||
|
||||
@@ -410,7 +448,7 @@ impl MachineState {
|
||||
for (h, addr) in bindings {
|
||||
self.heap[h] = HeapCellValue::Addr(addr);
|
||||
}
|
||||
},
|
||||
},
|
||||
&SystemClauseType::RemoveCallPolicyCheck => {
|
||||
let restore_default =
|
||||
match call_policy.downcast_mut::<CWILCallPolicy>().ok() {
|
||||
|
||||
Reference in New Issue
Block a user