From: Mark Date: Mon, 20 Nov 2023 23:24:31 +0000 (-0700) Subject: add global_count inference counter that is always incremented (#2009) X-Git-Tag: v0.9.4~110 X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=54166b91eb6e86c506bc716cab8336a7c3252c18;p=scryer-prolog.git add global_count inference counter that is always incremented (#2009) --- diff --git a/Cargo.lock b/Cargo.lock index bcb67381..4e90682e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1599,9 +1599,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" dependencies = [ "autocfg", ] diff --git a/build/instructions_template.rs b/build/instructions_template.rs index 69cf2d12..773b6746 100644 --- a/build/instructions_template.rs +++ b/build/instructions_template.rs @@ -329,6 +329,8 @@ enum SystemClauseType { InstallSCCCleaner, #[strum_discriminants(strum(props(Arity = "3", Name = "$install_inference_counter")))] InstallInferenceCounter, + #[strum_discriminants(strum(props(Arity = "1", Name = "$inference_count")))] + InferenceCount, #[strum_discriminants(strum(props(Arity = "1", Name = "$lh_length")))] LiftedHeapLength, #[strum_discriminants(strum(props(Arity = "3", Name = "$load_library_as_stream")))] @@ -1720,6 +1722,7 @@ fn generate_instruction_preface() -> TokenStream { &Instruction::CallHeadIsDynamic | &Instruction::CallInstallSCCCleaner | &Instruction::CallInstallInferenceCounter | + &Instruction::CallInferenceCount | &Instruction::CallLiftedHeapLength | &Instruction::CallLoadLibraryAsStream | &Instruction::CallModuleExists | @@ -1954,6 +1957,7 @@ fn generate_instruction_preface() -> TokenStream { &Instruction::ExecuteHeadIsDynamic | &Instruction::ExecuteInstallSCCCleaner | &Instruction::ExecuteInstallInferenceCounter | + &Instruction::ExecuteInferenceCount | &Instruction::ExecuteLiftedHeapLength | &Instruction::ExecuteLoadLibraryAsStream | &Instruction::ExecuteModuleExists | diff --git a/src/machine/dispatch.rs b/src/machine/dispatch.rs index 6afce926..a8957528 100644 --- a/src/machine/dispatch.rs +++ b/src/machine/dispatch.rs @@ -36,7 +36,7 @@ macro_rules! try_or_throw { macro_rules! increment_call_count { ($s:expr) => {{ - if !($s.increment_call_count_fn)(&mut $s) { + if !$s.increment_call_count() { $s.backtrack(); continue; } @@ -3675,6 +3675,16 @@ impl Machine { try_or_throw!(self.machine_st, self.install_inference_counter()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } + &Instruction::CallInferenceCount => { + let global_count = self.machine_st.cwil.global_count.clone(); + self.inference_count(self.machine_st.registers[1], global_count); + step_or_fail!(self, self.machine_st.p += 1); + } + &Instruction::ExecuteInferenceCount => { + let global_count = self.machine_st.cwil.global_count.clone(); + self.inference_count(self.machine_st.registers[1], global_count); + step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + } &Instruction::CallLiftedHeapLength => { self.lifted_heap_length(); step_or_fail!(self, self.machine_st.p += 1); diff --git a/src/machine/machine_state.rs b/src/machine/machine_state.rs index 7f682e0a..596eefbd 100644 --- a/src/machine/machine_state.rs +++ b/src/machine/machine_state.rs @@ -96,7 +96,6 @@ pub struct MachineState { pub(crate) unify_fn: fn(&mut MachineState), pub(crate) bind_fn: fn(&mut MachineState, Ref, HeapCellValue), pub(crate) run_cleaners_fn: fn(&mut Machine) -> bool, - pub(crate) increment_call_count_fn: fn(&mut MachineState) -> bool, } impl fmt::Debug for MachineState { @@ -417,15 +416,17 @@ impl MachineState { return true; } + self.cwil.global_count += 1; + if let Some(&(ref limit, block)) = self.cwil.limits.last() { - if self.cwil.count == *limit { + if self.cwil.local_count == *limit { self.cwil.inference_limit_exceeded = true; self.block = block; self.unwind_stack(); return false; } else { - self.cwil.count += 1; + self.cwil.local_count += 1; } } @@ -967,7 +968,8 @@ impl MachineState { #[allow(clippy::upper_case_acronyms)] #[derive(Debug)] pub(crate) struct CWIL { - count: Integer, + local_count: Integer, + pub(crate) global_count: Integer, limits: Vec<(Integer, usize)>, pub(crate) inference_limit_exceeded: bool, } @@ -975,22 +977,22 @@ pub(crate) struct CWIL { impl CWIL { pub(crate) fn new() -> Self { CWIL { - count: Integer::from(0), + local_count: Integer::from(0), + global_count: Integer::from(0), limits: vec![], inference_limit_exceeded: false, } } - pub(crate) fn add_limit(&mut self, limit: usize, block: usize) -> &Integer { - let mut limit = Integer::from(limit); - limit += &self.count; + pub(crate) fn add_limit(&mut self, mut limit: Integer, block: usize) -> &Integer { + limit += &self.local_count; match self.limits.last() { Some((ref inner_limit, _)) if *inner_limit <= limit => {} _ => self.limits.push((limit, block)), - }; + } - &self.count + &self.local_count } #[inline(always)] @@ -1001,12 +1003,12 @@ impl CWIL { } } - &self.count + &self.local_count } #[inline(always)] pub(crate) fn reset(&mut self) { - self.count = Integer::from(0); + self.local_count = Integer::from(0); self.limits.clear(); self.inference_limit_exceeded = false; } diff --git a/src/machine/machine_state_impl.rs b/src/machine/machine_state_impl.rs index 772a9642..82a64bf4 100644 --- a/src/machine/machine_state_impl.rs +++ b/src/machine/machine_state_impl.rs @@ -60,7 +60,6 @@ impl MachineState { unify_fn: MachineState::unify, bind_fn: MachineState::bind, run_cleaners_fn: |_| false, - increment_call_count_fn: |_| true, } } diff --git a/src/machine/system_calls.rs b/src/machine/system_calls.rs index aa78f1a1..0c425b96 100644 --- a/src/machine/system_calls.rs +++ b/src/machine/system_calls.rs @@ -1,8 +1,7 @@ use crate::parser::ast::*; use crate::parser::parser::*; -use dashu::integer::Sign; -use dashu::integer::UBig; +use dashu::integer::{Sign, UBig}; use lazy_static::lazy_static; use num_order::NumOrd; @@ -5516,11 +5515,8 @@ impl Machine { let a2 = self.deref_register(2); let n = match Number::try_from(a2) { - Ok(Number::Fixnum(bp)) => bp.get_num() as usize, - Ok(Number::Integer(n)) => { - let value: usize = (&*n).try_into().unwrap(); - value - } + Ok(Number::Fixnum(bp)) => Integer::from(bp.get_num() as usize), + Ok(Number::Integer(n)) => (*n).clone(), _ => { let stub = functor_stub(atom!("call_with_inference_limit"), 3); @@ -5531,21 +5527,24 @@ impl Machine { let bp = cell_as_fixnum!(a1).get_num() as usize; let a3 = self.deref_register(3); - let count = self.machine_st.cwil.add_limit(n, bp); - let result = count.try_into(); - if let Ok(value) = result { - self.machine_st.unify_fixnum(Fixnum::build_with(value), a3); - } else { - let count = arena_alloc!(count.clone(), &mut self.machine_st.arena); - self.machine_st.unify_big_int(count, a3); - } - - self.machine_st.increment_call_count_fn = MachineState::increment_call_count; + let count = self.machine_st.cwil.add_limit(n, bp).clone(); + self.inference_count(a3, count); Ok(()) } + #[inline(always)] + pub(crate) fn inference_count(&mut self, count_var: HeapCellValue, count: Integer) { + if let Some(value) = <&Integer as TryInto>::try_into(&count).ok() { + self.machine_st + .unify_fixnum(Fixnum::build_with(value), count_var); + } else { + let count = arena_alloc!(count, &mut self.machine_st.arena); + self.machine_st.unify_big_int(count, count_var); + } + } + #[inline(always)] pub(crate) fn module_exists(&mut self) { let module = self.deref_register(1); @@ -5671,7 +5670,6 @@ impl Machine { if bp == self.machine_st.b && self.machine_st.cwil.is_empty() { self.machine_st.cwil.reset(); - self.machine_st.increment_call_count_fn = |_| true; } }