call_verify_attributes([], _, _, []).
call_verify_attributes([Attr|Attrs], Var, Value, ListOfGoalLists) :-
gather_modules([Attr|Attrs], Modules0),
- sort(Modules0, Modules),
+ sort(Modules0, Modules),
verify_attrs(Modules, Var, Value, ListOfGoalLists).
call_goals([ListOfGoalLists | ListsCubed]) :-
self.attr_var_queue.clear();
self.bindings.clear();
}
+
+ #[inline]
+ pub(super) fn backtrack(&mut self, queue_b: usize, bindings_b: usize) {
+ self.attr_var_queue.truncate(queue_b);
+ self.bindings.truncate(bindings_b);
+ }
}
impl MachineState {
pub(super) fn push_attr_var_binding(&mut self, h: usize, addr: Addr) {
if self.attr_var_init.bindings.is_empty() {
self.attr_var_init.instigating_p = self.p.local();
-
+
if self.last_call {
self.attr_var_init.cp = self.cp;
} else {
self.attr_var_init.cp = self.p.local() + 1;
}
-
+
self.p = CodePtr::VerifyAttrInterrupt(self.attr_var_init.verify_attrs_loc);
}
.bindings
.iter()
.map(|(ref h, _)| Addr::AttrVar(*h));
+
let var_list_addr = Addr::HeapCell(self.heap.to_list(iter));
let iter = self
.bindings
.iter()
.map(|(_, ref addr)| addr.clone());
+
let value_list_addr = Addr::HeapCell(self.heap.to_list(iter));
(var_list_addr, value_list_addr)
}
}
- fn reinstantiate_var(&mut self, addr: Addr, threshold: usize) {
- match addr {
- Addr::HeapCell(h) => {
- self.target[threshold] = HeapCellValue::Addr(Addr::HeapCell(threshold));
- self.target[h] = HeapCellValue::Addr(Addr::HeapCell(threshold));
- self.trail
- .push((Ref::HeapCell(h), HeapCellValue::Addr(Addr::HeapCell(h))));
- }
- Addr::StackCell(fr, sc) => {
- self.target[threshold] = HeapCellValue::Addr(Addr::HeapCell(threshold));
- self.target.stack()[fr][sc] = Addr::HeapCell(threshold);
- self.trail.push((
- Ref::StackCell(fr, sc),
- HeapCellValue::Addr(Addr::StackCell(fr, sc)),
- ));
- }
- Addr::AttrVar(h) => {
- let redirect_tag = self.attr_var_redirect_tag();
-
- self.target[threshold] = HeapCellValue::Addr(redirect_tag(threshold));
- self.target[h] = HeapCellValue::Addr(redirect_tag(threshold));
- self.trail
- .push((Ref::AttrVar(h), HeapCellValue::Addr(Addr::AttrVar(h))));
- }
- _ => {}
- }
- }
-
fn copied_list(&mut self, addr: usize) -> bool {
if let HeapCellValue::Addr(Addr::Lis(addr)) = self.target[addr].clone() {
if addr >= self.old_h {
let rd = self.target.store(self.target.deref(ra));
match rd.clone() {
- Addr::AttrVar(h) if h >= self.old_h => {
- let redirect_tag = self.attr_var_redirect_tag();
- self.target[threshold] = HeapCellValue::Addr(redirect_tag(h));
- }
- Addr::HeapCell(h) if h >= self.old_h => {
+ Addr::AttrVar(h) | Addr::HeapCell(h) if h >= self.old_h => {
self.target[threshold] = HeapCellValue::Addr(rd)
}
- Addr::AttrVar(h) => {
- if Addr::AttrVar(h) == rd {
- self.reinstantiate_var(Addr::AttrVar(h), threshold);
- } else {
- let redirect_tag = self.attr_var_redirect_tag();
- self.target[threshold] = HeapCellValue::Addr(redirect_tag(h));
- }
- }
- ra @ Addr::HeapCell(..) | ra @ Addr::StackCell(..) => {
+ ra @ Addr::AttrVar(..) | ra @ Addr::HeapCell(_) | ra @ Addr::StackCell(..) => {
if ra == rd {
self.reinstantiate_var(ra, threshold);
} else {
self.scan += 1;
}
+ fn reinstantiate_var(&mut self, addr: Addr, threshold: usize) {
+ match addr {
+ Addr::HeapCell(h) => {
+ self.target[threshold] = HeapCellValue::Addr(Addr::HeapCell(threshold));
+ self.target[h] = HeapCellValue::Addr(Addr::HeapCell(threshold));
+ self.trail.push((
+ Ref::HeapCell(h),
+ HeapCellValue::Addr(Addr::HeapCell(h)),
+ ));
+ }
+ Addr::StackCell(fr, sc) => {
+ self.target[threshold] = HeapCellValue::Addr(Addr::HeapCell(threshold));
+ self.target.stack()[fr][sc] = Addr::HeapCell(threshold);
+ self.trail.push((
+ Ref::StackCell(fr, sc),
+ HeapCellValue::Addr(Addr::StackCell(fr, sc)),
+ ));
+ }
+ Addr::AttrVar(h) => {
+ let redirect_tag = self.attr_var_redirect_tag();
+
+ self.target[threshold] = HeapCellValue::Addr(redirect_tag(threshold));
+ self.target[h] = HeapCellValue::Addr(redirect_tag(threshold));
+ self.trail.push((
+ Ref::AttrVar(h),
+ HeapCellValue::Addr(Addr::AttrVar(h)),
+ ));
+ }
+ _ => unreachable!()
+ }
+ }
+
fn copy_var(&mut self, addr: Addr) {
let rd = self.target.store(self.target.deref(addr.clone()));
self.target
.push(HeapCellValue::Addr(redirect_tag(threshold)));
- if let Addr::AttrVar(_) = redirect_tag(threshold) {
+ if let AttrVarPolicy::DeepCopy = self.attr_var_policy {
let list_val = self.target[h + 1].clone();
self.target.push(list_val);
}
self.reinstantiate_var(addr, scan);
self.scan += 1;
}
- _ => *self.value_at_scan() = HeapCellValue::Addr(rd),
+ _ => {
+ *self.value_at_scan() = HeapCellValue::Addr(rd);
+ }
}
}
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);
+ let attr_var_init_queue_b = machine_st.or_stack[b].attr_var_init_queue_b;
+ let attr_var_init_bindings_b = machine_st.or_stack[b].attr_var_init_bindings_b;
+
+ machine_st.attr_var_init.backtrack(
+ attr_var_init_queue_b,
+ attr_var_init_bindings_b,
+ );
machine_st.hb = machine_st.heap.h;
machine_st.p += 1;
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);
+ let attr_var_init_queue_b = machine_st.or_stack[b].attr_var_init_queue_b;
+ let attr_var_init_bindings_b = machine_st.or_stack[b].attr_var_init_bindings_b;
+
+ machine_st.attr_var_init.backtrack(
+ attr_var_init_queue_b,
+ attr_var_init_bindings_b,
+ );
machine_st.hb = machine_st.heap.h;
machine_st.p += offset;
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);
+ let attr_var_init_queue_b = machine_st.or_stack[b].attr_var_init_queue_b;
+ let attr_var_init_bindings_b = machine_st.or_stack[b].attr_var_init_bindings_b;
+
+ machine_st.attr_var_init.backtrack(
+ attr_var_init_queue_b,
+ attr_var_init_bindings_b,
+ );
machine_st.b = machine_st.or_stack[b].b;
machine_st.or_stack.truncate(machine_st.b);
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);
+ let attr_var_init_queue_b = machine_st.or_stack[b].attr_var_init_queue_b;
+ let attr_var_init_bindings_b = machine_st.or_stack[b].attr_var_init_bindings_b;
+ machine_st.attr_var_init.backtrack(
+ attr_var_init_queue_b,
+ attr_var_init_bindings_b,
+ );
+
machine_st.b = machine_st.or_stack[b].b;
machine_st.or_stack.truncate(machine_st.b);
self.e,
self.cp.clone(),
self.attr_var_init.attr_var_queue.len(),
+ self.attr_var_init.bindings.len(),
self.b,
self.p.clone() + 1,
self.tr,
self.e,
self.cp.clone(),
self.attr_var_init.attr_var_queue.len(),
+ self.attr_var_init.bindings.len(),
self.b,
self.p.clone() + offset,
self.tr,
pub global_index: usize,
pub e: usize,
pub cp: LocalCodePtr,
- pub attr_var_init_b: usize,
+ pub attr_var_init_queue_b: usize,
+ pub attr_var_init_bindings_b: usize,
pub b: usize,
pub bp: CodePtr,
pub tr: usize,
global_index: usize,
e: usize,
cp: LocalCodePtr,
- attr_var_init_b: usize,
+ attr_var_init_queue_b: usize,
+ attr_var_init_bindings_b: usize,
b: usize,
bp: CodePtr,
tr: usize,
global_index,
e,
cp,
- attr_var_init_b,
+ attr_var_init_queue_b,
+ attr_var_init_bindings_b,
b,
bp,
tr,
global_index: usize,
e: usize,
cp: LocalCodePtr,
- attr_var_init_b: usize,
+ attr_var_init_queue_b: usize,
+ attr_var_init_bindings_b: usize,
b: usize,
bp: CodePtr,
tr: usize,
global_index,
e,
cp,
- attr_var_init_b,
+ attr_var_init_queue_b,
+ attr_var_init_bindings_b,
b,
bp,
tr,
),
( '$get_b_value'(B), call(Term), '$write_eqs_and_read_input'(B, VarList), !
; write('false.'), nl
- ),
- '$reset_attr_var_state'.
+ ).
'$needs_bracketing'(Value, Op) :-
catch((functor(Value, F, _),