//! Scheduling of processing and solving steps. //! //! The current implementation is temporary and will be replaced with something more flexible. use log::info; use partial_ref::{partial, PartialRef}; use crate::{ cdcl::conflict_step, clause::{ collect_garbage, reduce::{reduce_locals, reduce_mids}, Tier, }, context::{parts::*, Context}, prop::restart, state::SatState, }; mod luby; use luby::LubySequence; /// Scheduling of processing and solving steps. #[derive(Default)] pub struct Schedule { conflicts: u64, next_restart: u64, restarts: u64, luby: LubySequence, } /// Perform one step of the schedule. pub fn schedule_step<'a>( mut ctx: partial!( Context<'a>, mut AnalyzeConflictP, mut AssignmentP, mut AssumptionsP, mut BinaryClausesP, mut ClauseActivityP, mut ClauseAllocP, mut ClauseDbP, mut ImplGraphP, mut ModelP, mut ProofP<'a>, mut ScheduleP, mut SolverStateP, mut TmpDataP, mut TmpFlagsP, mut TrailP, mut VariablesP, mut VsidsP, mut WatchlistsP, SolverConfigP, ), ) -> bool { let (schedule, mut ctx) = ctx.split_part_mut(ScheduleP); let (config, mut ctx) = ctx.split_part(SolverConfigP); if ctx.part(SolverStateP).sat_state != SatState::Unknown || ctx.part(SolverStateP).solver_error.is_some() { false } else { if schedule.conflicts > 0 && schedule.conflicts % 5000 == 0 { let db = ctx.part(ClauseDbP); let units = ctx.part(TrailP).top_level_assignment_count(); info!( "confl: {}k rest: {} vars: {} bin: {} irred: {} core: {} mid: {} local: {}", schedule.conflicts / 1000, schedule.restarts, ctx.part(AssignmentP).assignment().len() - units, ctx.part(BinaryClausesP).count(), db.count_by_tier(Tier::Irred), db.count_by_tier(Tier::Core), db.count_by_tier(Tier::Mid), db.count_by_tier(Tier::Local) ); } if schedule.next_restart == schedule.conflicts { restart(ctx.borrow()); schedule.restarts += 1; schedule.next_restart += config.luby_restart_interval_scale * schedule.luby.advance(); } if schedule.conflicts % config.reduce_locals_interval == 0 { reduce_locals(ctx.borrow()); } if schedule.conflicts % config.reduce_mids_interval == 0 { reduce_mids(ctx.borrow()); } collect_garbage(ctx.borrow()); conflict_step(ctx.borrow()); schedule.conflicts += 1; true } }