| //! Decision heuristics. |
| |
| use partial_ref::{partial, PartialRef}; |
| |
| use varisat_formula::Var; |
| |
| use crate::{ |
| context::{parts::*, Context}, |
| prop::{enqueue_assignment, Reason}, |
| }; |
| |
| pub mod vsids; |
| |
| /// Make a decision and enqueue it. |
| /// |
| /// Returns `false` if no decision was made because all variables are assigned. |
| pub fn make_decision( |
| mut ctx: partial!( |
| Context, |
| mut AssignmentP, |
| mut ImplGraphP, |
| mut TrailP, |
| mut VsidsP |
| ), |
| ) -> bool { |
| let (vsids, mut ctx) = ctx.split_part_mut(VsidsP); |
| |
| if let Some(decision_var) = vsids.find(|&var| ctx.part(AssignmentP).var_value(var).is_none()) { |
| let decision = decision_var.lit(ctx.part(AssignmentP).last_var_value(decision_var)); |
| |
| ctx.part_mut(TrailP).new_decision_level(); |
| |
| enqueue_assignment(ctx.borrow(), decision, Reason::Unit); |
| |
| true |
| } else { |
| false |
| } |
| } |
| |
| /// Make a variable available for decisions. |
| pub fn make_available(mut ctx: partial!(Context, mut VsidsP), var: Var) { |
| ctx.part_mut(VsidsP).make_available(var); |
| } |
| |
| /// Initialize decision heuristics for a new variable. |
| pub fn initialize_var(mut ctx: partial!(Context, mut VsidsP), var: Var, available: bool) { |
| ctx.part_mut(VsidsP).reset(var); |
| |
| if available { |
| make_available(ctx.borrow(), var); |
| } |
| } |
| |
| /// Remove a variable from the decision heuristics. |
| pub fn remove_var(mut ctx: partial!(Context, mut VsidsP), var: Var) { |
| ctx.part_mut(VsidsP).make_unavailable(var); |
| } |