From: Mark Thom Date: Sat, 7 Dec 2019 00:52:40 +0000 (-0400) Subject: add backtracking of attributed variable data X-Git-Tag: v0.8.118~37 X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=3d2c4f0801c3aae61f79babba4ef647fc882958c;p=scryer-prolog.git add backtracking of attributed variable data --- diff --git a/src/prolog/machine/attributed_variables.rs b/src/prolog/machine/attributed_variables.rs index 0a119539..1edc240d 100644 --- a/src/prolog/machine/attributed_variables.rs +++ b/src/prolog/machine/attributed_variables.rs @@ -36,19 +36,25 @@ impl AttrVarInitializer { 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); } @@ -61,6 +67,7 @@ impl MachineState { .bindings .iter() .map(|(ref h, _)| Addr::AttrVar(*h)); + let var_list_addr = Addr::HeapCell(self.heap.to_list(iter)); let iter = self @@ -68,6 +75,7 @@ impl MachineState { .bindings .iter() .map(|(_, ref addr)| addr.clone()); + let value_list_addr = Addr::HeapCell(self.heap.to_list(iter)); (var_list_addr, value_list_addr) diff --git a/src/prolog/machine/machine_state.rs b/src/prolog/machine/machine_state.rs index 5b26e0bb..64c761cd 100644 --- a/src/prolog/machine/machine_state.rs +++ b/src/prolog/machine/machine_state.rs @@ -441,11 +441,10 @@ pub(crate) trait CallPolicy: Any { machine_st.heap.truncate(machine_st.stack.index_or_frame(b).prelude.h); - let attr_var_init_b = machine_st.stack.index_or_frame(b).prelude.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.stack.index_or_frame(b).prelude.attr_var_init_queue_b; + let attr_var_init_bindings_b = machine_st.stack.index_or_frame(b).prelude.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; @@ -485,11 +484,10 @@ pub(crate) trait CallPolicy: Any { machine_st.heap.truncate(machine_st.stack.index_or_frame(b).prelude.h); - let attr_var_init_b = machine_st.stack.index_or_frame(b).prelude.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.stack.index_or_frame(b).prelude.attr_var_init_queue_b; + let attr_var_init_bindings_b = machine_st.stack.index_or_frame(b).prelude.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; @@ -527,11 +525,10 @@ pub(crate) trait CallPolicy: Any { machine_st.heap.truncate(machine_st.stack.index_or_frame(b).prelude.h); - let attr_var_init_b = machine_st.stack.index_or_frame(b).prelude.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.stack.index_or_frame(b).prelude.attr_var_init_queue_b; + let attr_var_init_bindings_b = machine_st.stack.index_or_frame(b).prelude.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.stack.index_or_frame(b).prelude.b; machine_st.truncate_stack(); @@ -572,11 +569,10 @@ pub(crate) trait CallPolicy: Any { machine_st.heap.truncate(machine_st.stack.index_or_frame(b).prelude.h); - let attr_var_init_b = machine_st.stack.index_or_frame(b).prelude.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.stack.index_or_frame(b).prelude.attr_var_init_queue_b; + let attr_var_init_bindings_b = machine_st.stack.index_or_frame(b).prelude.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.stack.index_or_frame(b).prelude.b; machine_st.truncate_stack(); diff --git a/src/prolog/machine/machine_state_impl.rs b/src/prolog/machine/machine_state_impl.rs index dea7b468..a56da366 100644 --- a/src/prolog/machine/machine_state_impl.rs +++ b/src/prolog/machine/machine_state_impl.rs @@ -3241,8 +3241,10 @@ impl MachineState { or_frame.prelude.pstr_tr = self.pstr_tr; or_frame.prelude.h = self.heap.h; or_frame.prelude.b0 = self.b0; - or_frame.prelude.attr_var_init_b = + or_frame.prelude.attr_var_init_queue_b = self.attr_var_init.attr_var_queue.len(); + or_frame.prelude.attr_var_init_bindings_b = + self.attr_var_init.bindings.len(); self.b = b; @@ -3278,7 +3280,9 @@ impl MachineState { or_frame.prelude.pstr_tr = self.pstr_tr; or_frame.prelude.h = self.heap.h; or_frame.prelude.b0 = self.b0; - or_frame.prelude.attr_var_init_b = + or_frame.prelude.attr_var_init_queue_b = + self.attr_var_init.attr_var_queue.len(); + or_frame.prelude.attr_var_init_bindings_b = self.attr_var_init.attr_var_queue.len(); self.b = b;