Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/Nathan-Fenner/sat_toasty_helper
A Rust utility for defining SAT problems
https://github.com/Nathan-Fenner/sat_toasty_helper
Last synced: 1 day ago
JSON representation
A Rust utility for defining SAT problems
- Host: GitHub
- URL: https://github.com/Nathan-Fenner/sat_toasty_helper
- Owner: Nathan-Fenner
- Created: 2023-04-27T21:10:30.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2024-04-06T20:44:09.000Z (7 months ago)
- Last Synced: 2024-08-03T07:03:03.965Z (4 months ago)
- Language: Rust
- Size: 9.77 KB
- Stars: 2
- Watchers: 3
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
- awesome-rust-formalized-reasoning - sat_toasty_helper - convenient way to write and solve SAT constraints. (Projects / Libraries)
README
# `sat_toasty_helper` is a convenient way to write and solve SAT constraints in Rust
Currently, `sat_toasty_helper` relies on [`splr`](https://crates.io/crates/splr), a modern SAT solver written in Rust.
In the future, I hope to make this part more configurable - but for the initial release, it's provided to give the best "batteries-included" experience for initial setup.
This is a very WIP project; I'm gradually cleaning up and publishing pieces of the utilities I've built for setting and solving pen-and-paper puzzles.
## Sudoku
Here's an example of setting up Sudoku constraints (TODO: show usage as import of crate):
```rs
use sat::{Lit, Prop, Solver};
mod sat;use sat::ClauseBuilderHelper;
use Lit::*;// Define a type representing a position in the Sudoku grid.
// 0 <= r, c < 9.
#[derive(Copy, Clone, Eq, PartialEq, Hash, PartialOrd, Ord, Debug)]
struct GridCell {
r: i32,
c: i32,
}/// We can define custom "propositions" (without interpretation) by addding an `impl Prop` for them.
/// The `Num(p, v)` proposition says that grid cell `p` contains the digit `v`.
#[derive(Copy, Clone, Eq, PartialEq, Debug, PartialOrd, Ord)]
struct Num(GridCell, i32);
impl Prop for Num {}fn main() {
// Create a new solver. All of the constraints will be added to this object.
let mut s = Solver::new();// Set up the rules for Sudoku:
let cells: Vec = (0..9)
.flat_map(|r| (0..9).map(move |c| GridCell { r, c }))
.collect();// Each cell has a value.
for &p in &cells {
// This means that exactly one of Num(p, 1); Num(p, 2); ...; Num(p, 9) is true.
s.exactly_one((1..=9).map(|v| Pos(Num(p, v))));
}// If two different cells share a row, column, or 3x3 box, they cannot have the same value.
for &p1 in &cells {
for &p2 in &cells {
if p1 == p2 {
continue;
}
if p1.r == p2.r || p1.c == p2.c || (p1.r / 3, p1.c / 3) == (p2.r / 3, p2.c / 3) {
for v in 1..=9 {
// They cannot both be 'v':
s.at_most_one([Pos(Num(p1, v)), Pos(Num(p2, v))]);
}
}
}
}// Get the solution.
// In production code, you should check here for errors (timeouts or unsatisfiability).
let ans = s.solve_splr().expect("solvable").unwrap();// Print the resulting grid:
for r in 0..9 {
for c in 0..9 {
let p = GridCell { r, c };
for v in 1..=9 {
// We can look up the `Var` for each proposition by calling `.resolve_prop`.
if ans[&s.resolve_prop(Num(p, v))] {
print!("{v}");
}
}
}
println!();
}
}
```