pub struct ProofLog { /* private fields */ }Expand description
A proof log which logs the proof steps necessary to prove unsatisfiability or optimality. We allow the following types of proofs:
- A CP proof log - This can be created using
ProofLog::cp. - A DIMACS proof log - This can be created using
ProofLog::dimacs.
When a proof log should not be generated, use the implementation of Default.
Implementations§
Source§impl ProofLog
impl ProofLog
Sourcepub fn cp(
file_path: &Path,
format: Format,
log_inferences: bool,
log_hints: bool,
) -> Result<ProofLog>
pub fn cp( file_path: &Path, format: Format, log_inferences: bool, log_hints: bool, ) -> Result<ProofLog>
Create a CP proof logger.
Examples found in repository?
examples/nqueens.rs (line 40)
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
fn main() {
let Cli {
n,
proof: proof_path,
} = Cli::parse();
if n < 2 {
println!("Please provide an 'n > 1'");
return;
}
let Ok(proof_log) = proof_path
.as_ref()
.map(|path| ProofLog::cp(path, Format::Text, true, true))
.transpose()
.map(|proof| proof.unwrap_or_default())
else {
eprintln!(
"Failed to create proof file at {}",
proof_path.unwrap().display()
);
return;
};
let mut solver = Solver::with_options(
LearningOptions::default(),
pumpkin_solver::options::SolverOptions {
proof_log,
..Default::default()
},
);
let variables = (0..n)
.map(|i| solver.new_named_bounded_integer(0, n as i32 - 1, format!("q{i}")))
.collect::<Vec<_>>();
let _ = solver
.add_constraint(constraints::all_different(variables.clone()))
.with_tag(NonZero::new(1).unwrap())
.post();
let diag1 = variables
.iter()
.cloned()
.enumerate()
.map(|(i, var)| var.offset(i as i32))
.collect::<Vec<_>>();
let diag2 = variables
.iter()
.cloned()
.enumerate()
.map(|(i, var)| var.offset(-(i as i32)))
.collect::<Vec<_>>();
let _ = solver
.add_constraint(constraints::all_different(diag1))
.with_tag(NonZero::new(2).unwrap())
.post();
let _ = solver
.add_constraint(constraints::all_different(diag2))
.with_tag(NonZero::new(3).unwrap())
.post();
let mut brancher = solver.default_brancher_over_all_propositional_variables();
match solver.satisfy(&mut brancher, &mut Indefinite) {
SatisfactionResult::Satisfiable(solution) => {
let row_separator = format!("{}+", "+---".repeat(n as usize));
for row in 0..n {
println!("{row_separator}");
let queen_col = solution.get_integer_value(variables[row as usize]) as u32;
for col in 0..n {
let string = if queen_col == col { "| * " } else { "| " };
print!("{string}");
}
println!("|");
}
println!("{row_separator}");
}
SatisfactionResult::Unsatisfiable => {
println!("{n}-queens is unsatisfiable.");
}
SatisfactionResult::Unknown => {
println!("Timeout.");
}
}
}Trait Implementations§
Auto Trait Implementations§
impl Freeze for ProofLog
impl RefUnwindSafe for ProofLog
impl Send for ProofLog
impl Sync for ProofLog
impl Unpin for ProofLog
impl UnwindSafe for ProofLog
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
Converts
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
Converts
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more