diff options
author | Mark Thom <markjordanthom@gmail.com> | 2019-10-19 00:29:50 -0600 |
---|---|---|
committer | Mark Thom <markjordanthom@gmail.com> | 2019-10-19 00:29:50 -0600 |
commit | 24e5e39c28ce16b48a14f11f16ffcaf3138d6094 (patch) | |
tree | 61fec45aaba760fcb6c73d93270d99b183979ea8 | |
parent | ab9a14cc6a9c726ac6d248a26e9af67bcd178255 (diff) |
add order preserving tidy_trail, fix random_labeling/2v0.8.114
-rw-r--r-- | Cargo.toml | 2 | ||||
-rw-r--r-- | src/prolog/lib/atts.pl | 2 | ||||
-rw-r--r-- | src/prolog/lib/non_iso.pl | 9 | ||||
-rw-r--r-- | src/prolog/machine/attributed_variables.pl | 1 | ||||
-rw-r--r-- | src/prolog/machine/attributed_variables.rs | 8 | ||||
-rw-r--r-- | src/prolog/machine/machine_indices.rs | 6 | ||||
-rw-r--r-- | src/prolog/machine/machine_state_impl.rs | 99 | ||||
-rw-r--r-- | src/prolog/machine/mod.rs | 96 | ||||
-rw-r--r-- | src/prolog/machine/system_calls.rs | 2 |
9 files changed, 124 insertions, 101 deletions
@@ -1,6 +1,6 @@ [package] name = "scryer-prolog" -version = "0.8.113" +version = "0.8.114" authors = ["Mark Thom <markjordanthom@gmail.com>"] build = "build.rs" repository = "https://github.com/mthom/scryer-prolog" diff --git a/src/prolog/lib/atts.pl b/src/prolog/lib/atts.pl index 25a84fc5..5de6d32c 100644 --- a/src/prolog/lib/atts.pl +++ b/src/prolog/lib/atts.pl @@ -20,7 +20,7 @@ '$default_attr_list'([PG | PGs], Module, AttrVar) --> ( { '$module_of'(Module, PG) } -> [Module:put_atts(AttrVar, PG)] - ; true + ; { true } ), '$default_attr_list'(PGs, Module, AttrVar). '$default_attr_list'([], _, _) --> []. diff --git a/src/prolog/lib/non_iso.pl b/src/prolog/lib/non_iso.pl index e4a45c95..84595e83 100644 --- a/src/prolog/lib/non_iso.pl +++ b/src/prolog/lib/non_iso.pl @@ -130,11 +130,12 @@ variant(X, Y) :- '$variant'(X, Y). maybe :- '$maybe'. set_random(Seed) :- - ( nonvar(Seed) -> + ( nonvar(Seed) -> ( Seed = seed(S) -> - ( integer(S) -> '$set_seed'(S) + ( var(S) -> throw(error(instantiation_error, set_random/1)) + ; integer(S) -> '$set_seed'(S) ; throw(error(type_error(integer(S), set_random/1))) - ) + ) ) ; throw(error(instantiation_error, set_random/1)) - ). + ). diff --git a/src/prolog/machine/attributed_variables.pl b/src/prolog/machine/attributed_variables.pl index f7b5493c..1323d2f5 100644 --- a/src/prolog/machine/attributed_variables.pl +++ b/src/prolog/machine/attributed_variables.pl @@ -25,6 +25,7 @@ verify_attrs([], _, _, []). call_verify_attributes(Attrs, _, _, []) :- var(Attrs), !. +call_verify_attributes([], _, _, []). call_verify_attributes([Attr|Attrs], Var, Value, ListOfGoalLists) :- gather_modules([Attr|Attrs], Modules0), sort(Modules0, Modules), diff --git a/src/prolog/machine/attributed_variables.rs b/src/prolog/machine/attributed_variables.rs index c1af6aab..638c403b 100644 --- a/src/prolog/machine/attributed_variables.rs +++ b/src/prolog/machine/attributed_variables.rs @@ -14,6 +14,7 @@ pub(super) struct AttrVarInitializer { pub(super) attr_var_queue: Vec<usize>, pub(super) bindings: Bindings, pub(super) cp: LocalCodePtr, + pub(super) instigating_p: LocalCodePtr, pub(super) verify_attrs_loc: usize, pub(super) project_attrs_loc: usize, } @@ -24,6 +25,7 @@ impl AttrVarInitializer { attribute_goals: vec![], attr_var_queue: vec![], bindings: vec![], + instigating_p: LocalCodePtr::default(), cp: LocalCodePtr::default(), verify_attrs_loc, project_attrs_loc, @@ -41,10 +43,12 @@ impl AttrVarInitializer { 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(); + self.attr_var_init.cp = self.p.local() + 1; } self.p = CodePtr::VerifyAttrInterrupt(self.attr_var_init.verify_attrs_loc); @@ -201,7 +205,7 @@ impl Machine { &mut self.code_repo, &mut readline::input_stream(), ); - + self.machine_st .print_attribute_goals_string(&self.indices.op_dir) } diff --git a/src/prolog/machine/machine_indices.rs b/src/prolog/machine/machine_indices.rs index db642a55..40fda8a7 100644 --- a/src/prolog/machine/machine_indices.rs +++ b/src/prolog/machine/machine_indices.rs @@ -469,6 +469,12 @@ pub struct IndexStore { } impl IndexStore { + pub fn reset_global_variable_offsets(&mut self) { + for (_, ref mut offset) in self.global_variables.values_mut() { + *offset = None; + } + } + pub fn predicate_exists( &self, name: ClauseName, diff --git a/src/prolog/machine/machine_state_impl.rs b/src/prolog/machine/machine_state_impl.rs index 81884fff..32a06774 100644 --- a/src/prolog/machine/machine_state_impl.rs +++ b/src/prolog/machine/machine_state_impl.rs @@ -741,29 +741,21 @@ impl MachineState { } let b = self.b - 1; - let mut i = self.or_stack[b].tr; + let hb = self.hb; + let mut offset = 0; - while i < self.tr { - let tr_i = self.trail[i]; - let hb = self.hb; - - match tr_i { + for i in self.or_stack[b].tr .. self.tr { + match self.trail[i] { TrailRef::Ref(Ref::AttrVar(tr_i)) | TrailRef::Ref(Ref::HeapCell(tr_i)) | TrailRef::AttrVarHeapLink(tr_i) - | TrailRef::AttrVarListLink(tr_i, _) => { - if tr_i < hb { - i += 1; - } else { - let tr = self.tr; - let val = self.trail[tr - 1].clone(); - self.trail[i] = val; - self.trail.pop(); - self.tr -= 1; - } - } + | TrailRef::AttrVarListLink(tr_i, _) => + if tr_i >= hb { + offset += 1; + } else { + self.trail[i - offset] = self.trail[i]; + }, TrailRef::Ref(Ref::StackCell(fr, _)) => { - let b = self.b - 1; let fr_gi = self.and_stack[fr].global_index; let b_gi = if !self.or_stack.is_empty() { self.or_stack[b].global_index @@ -771,20 +763,19 @@ impl MachineState { 0 }; - if fr_gi < b_gi { - i += 1; + if fr_gi >= b_gi { + offset += 1; } else { - let tr = self.tr; - let val = self.trail[tr - 1]; - self.trail[i] = val; - self.trail.pop(); - self.tr -= 1; + self.trail[i - offset] = self.trail[i]; } } - }; + } } - } + self.tr -= offset; + self.trail.truncate(self.tr); + } + #[inline] fn write_char_to_string(&mut self, s: &mut StringList, c: char) -> bool { self.pstr_trail(s.clone()); @@ -1675,7 +1666,7 @@ impl MachineState { } else if s.is_expandable() { self.heap .push(HeapCellValue::Addr(Addr::Con(Constant::String(s.clone())))); - + self.s = h; self.mode = MachineMode::Read; } else { @@ -3434,56 +3425,4 @@ impl MachineState { self.heap_locs.clear(); self.lifted_heap.clear(); } - - pub(super) fn sink_to_snapshot(&mut self) -> MachineState { - let mut snapshot = MachineState::with_capacity(0); - - snapshot.hb = self.hb; - snapshot.e = self.e; - snapshot.b = self.b; - snapshot.b0 = self.b0; - snapshot.s = self.s; - snapshot.tr = self.tr; - snapshot.pstr_tr = self.pstr_tr; - snapshot.num_of_args = self.num_of_args; - - snapshot.fail = self.fail; - snapshot.trail = mem::replace(&mut self.trail, vec![]); - snapshot.pstr_trail = mem::replace(&mut self.pstr_trail, vec![]); - snapshot.heap = self.heap.take(); - snapshot.mode = self.mode; - snapshot.and_stack = self.and_stack.take(); - snapshot.or_stack = self.or_stack.take(); - snapshot.registers = mem::replace(&mut self.registers, vec![]); - snapshot.block = self.block; - - snapshot.ball = self.ball.take(); - snapshot.lifted_heap = mem::replace(&mut self.lifted_heap, vec![]); - - snapshot - } - - pub(super) fn absorb_snapshot(&mut self, mut snapshot: MachineState) { - self.hb = snapshot.hb; - self.e = snapshot.e; - self.b = snapshot.b; - self.b0 = snapshot.b0; - self.s = snapshot.s; - self.tr = snapshot.tr; - self.pstr_tr = snapshot.pstr_tr; - self.num_of_args = snapshot.num_of_args; - - self.fail = snapshot.fail; - self.trail = mem::replace(&mut snapshot.trail, vec![]); - self.pstr_trail = mem::replace(&mut snapshot.pstr_trail, vec![]); - self.heap = snapshot.heap.take(); - self.mode = snapshot.mode; - self.and_stack = snapshot.and_stack.take(); - self.or_stack = snapshot.or_stack.take(); - self.registers = mem::replace(&mut snapshot.registers, vec![]); - self.block = snapshot.block; - - self.ball = snapshot.ball.take(); - self.lifted_heap = mem::replace(&mut snapshot.lifted_heap, vec![]); - } } diff --git a/src/prolog/machine/mod.rs b/src/prolog/machine/mod.rs index 1c6b4505..21ed9670 100644 --- a/src/prolog/machine/mod.rs +++ b/src/prolog/machine/mod.rs @@ -6,6 +6,7 @@ use crate::prolog::fixtures::*; use crate::prolog::forms::*; use crate::prolog::heap_print::*; use crate::prolog::instructions::*; +use crate::prolog::machine::heap::Heap; use crate::prolog::read::*; use crate::prolog::write::{next_keypress, ContinueResult}; @@ -71,6 +72,7 @@ impl MachinePolicies { pub struct Machine { pub(super) machine_st: MachineState, + pub(super) inner_heap: Heap, pub(super) policies: MachinePolicies, pub(super) indices: IndexStore, pub(super) code_repo: CodeRepo, @@ -227,13 +229,13 @@ impl Machine { } pub fn run_init_code(&mut self, code: Code) { - let old_machine_st = self.machine_st.sink_to_snapshot(); + let old_machine_st = self.sink_to_snapshot(); self.machine_st.reset(); self.code_repo.cached_query = code; self.run_query(&AllocVarDict::new()); - self.machine_st.absorb_snapshot(old_machine_st); + self.absorb_snapshot(old_machine_st); } pub fn run_top_level(&mut self) { @@ -260,6 +262,7 @@ impl Machine { pub fn new(prolog_stream: PrologStream) -> Self { let mut wam = Machine { machine_st: MachineState::new(), + inner_heap: Heap::with_capacity(256 * 256), policies: MachinePolicies::new(), indices: IndexStore::new(), code_repo: CodeRepo::new(), @@ -570,9 +573,14 @@ impl Machine { }; let stream = parsing_stream(s.as_bytes()); + let snapshot = self.sink_to_snapshot(); + let policies = mem::replace(&mut self.policies, MachinePolicies::new()); - let snapshot = self.machine_st.sink_to_snapshot(); self.machine_st.reset(); + self.machine_st.heap = mem::replace( + &mut self.inner_heap, + Heap::with_capacity(0), + ); let result = match stream_to_toplevel(stream, self) { Ok(packet) => compile_term(self, packet), @@ -580,6 +588,8 @@ impl Machine { }; self.handle_eval_session(result, snapshot); + self.indices.reset_global_variable_offsets(); + self.policies = policies; } REPLCodePtr::UseModule => self.use_module(ModuleSource::Library), @@ -594,10 +604,66 @@ impl Machine { self.machine_st.p = CodePtr::Local(p); } + fn sink_to_snapshot(&mut self) -> MachineState { + let mut snapshot = MachineState::with_capacity(0); + + snapshot.hb = self.machine_st.hb; + snapshot.e = self.machine_st.e; + snapshot.b = self.machine_st.b; + snapshot.b0 = self.machine_st.b0; + snapshot.s = self.machine_st.s; + snapshot.tr = self.machine_st.tr; + snapshot.pstr_tr = self.machine_st.pstr_tr; + snapshot.num_of_args = self.machine_st.num_of_args; + + snapshot.fail = self.machine_st.fail; + snapshot.trail = mem::replace(&mut self.machine_st.trail, vec![]); + snapshot.pstr_trail = mem::replace(&mut self.machine_st.pstr_trail, vec![]); + snapshot.heap = self.machine_st.heap.take(); + snapshot.mode = self.machine_st.mode; + snapshot.and_stack = self.machine_st.and_stack.take(); + snapshot.or_stack = self.machine_st.or_stack.take(); + snapshot.registers = mem::replace(&mut self.machine_st.registers, vec![]); + snapshot.block = self.machine_st.block; + + snapshot.ball = self.machine_st.ball.take(); + snapshot.lifted_heap = mem::replace(&mut self.machine_st.lifted_heap, vec![]); + + snapshot + } + + fn absorb_snapshot(&mut self, mut snapshot: MachineState) { + self.machine_st.hb = snapshot.hb; + self.machine_st.e = snapshot.e; + self.machine_st.b = snapshot.b; + self.machine_st.b0 = snapshot.b0; + self.machine_st.s = snapshot.s; + self.machine_st.tr = snapshot.tr; + self.machine_st.pstr_tr = snapshot.pstr_tr; + self.machine_st.num_of_args = snapshot.num_of_args; + + self.machine_st.fail = snapshot.fail; + self.machine_st.trail = mem::replace(&mut snapshot.trail, vec![]); + self.machine_st.pstr_trail = mem::replace(&mut snapshot.pstr_trail, vec![]); + + self.inner_heap = self.machine_st.heap.take(); + self.inner_heap.truncate(0); + + self.machine_st.heap = snapshot.heap.take(); + self.machine_st.mode = snapshot.mode; + self.machine_st.and_stack = snapshot.and_stack.take(); + self.machine_st.or_stack = snapshot.or_stack.take(); + self.machine_st.registers = mem::replace(&mut snapshot.registers, vec![]); + self.machine_st.block = snapshot.block; + + self.machine_st.ball = snapshot.ball.take(); + self.machine_st.lifted_heap = mem::replace(&mut snapshot.lifted_heap, vec![]); + } + fn propagate_exception_to_toplevel(&mut self, snapshot: MachineState) { let ball = self.machine_st.ball.take(); - self.machine_st.absorb_snapshot(snapshot); + self.absorb_snapshot(snapshot); self.machine_st.ball = ball; let h = self.machine_st.heap.h; @@ -617,7 +683,7 @@ impl Machine { }; let attr_goals = self.attribute_goals(); - + if !(self.machine_st.b > 0) { if bindings.is_empty() { let space = if requires_space(&attr_goals, ".") { @@ -632,7 +698,7 @@ impl Machine { println!("true."); } - self.machine_st.absorb_snapshot(snapshot); + self.absorb_snapshot(snapshot); return; } } else if bindings.is_empty() && attr_goals.is_empty() { @@ -664,7 +730,7 @@ impl Machine { } ContinueResult::Conclude => { print!(" ...\r\n"); - self.machine_st.absorb_snapshot(snapshot); + self.absorb_snapshot(snapshot); return; } }; @@ -676,12 +742,12 @@ impl Machine { return; } else { print!("false.\r\n"); - self.machine_st.absorb_snapshot(snapshot); + self.absorb_snapshot(snapshot); return; } } EvalSession::Error(err) => { - self.machine_st.absorb_snapshot(snapshot); + self.absorb_snapshot(snapshot); self.throw_session_error(err, (clause_name!("repl"), 0)); return; } @@ -712,7 +778,7 @@ impl Machine { } }, EvalSession::Error(err) => { - self.machine_st.absorb_snapshot(snapshot); + self.absorb_snapshot(snapshot); self.throw_session_error(err, (clause_name!("repl"), 0)); return; } @@ -725,7 +791,7 @@ impl Machine { _ => println!("true.") } - self.machine_st.absorb_snapshot(snapshot); + self.absorb_snapshot(snapshot); } pub(super) fn run_query(&mut self, alloc_locs: &AllocVarDict) { @@ -1048,7 +1114,13 @@ impl MachineState { CodePtr::VerifyAttrInterrupt(_) => { self.p = CodePtr::Local(self.attr_var_init.cp); - if !self.verify_attr_stepper(indices, policies, code_repo, prolog_stream) { + let instigating_p = CodePtr::Local(self.attr_var_init.instigating_p); + let instigating_instr = code_repo.lookup_instr(false, &instigating_p).unwrap(); + + if instigating_instr.as_ref().is_head_instr() { + let cp = self.p.local(); + self.run_verify_attr_interrupt(cp); + } else if !self.verify_attr_stepper(indices, policies, code_repo, prolog_stream) { if self.fail { break; } diff --git a/src/prolog/machine/system_calls.rs b/src/prolog/machine/system_calls.rs index 5673b149..483ceeeb 100644 --- a/src/prolog/machine/system_calls.rs +++ b/src/prolog/machine/system_calls.rs @@ -1686,7 +1686,7 @@ impl MachineState { return Ok(()); } &SystemClauseType::ReturnFromAttributeGoals => { - self.deallocate(); + self.deallocate(); self.p = CodePtr::Local(LocalCodePtr::TopLevel(0, 0)); return Ok(()); } |