Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented an interface to BatSat #84

Closed
wants to merge 27 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
5b78bd2
feat:implemented batsat api
nfbruns Apr 10, 2024
b8326be
docs: changelog and readme added
nfbruns Apr 10, 2024
ae01e17
ci: running github workflows
nfbruns Apr 10, 2024
4b58cc8
docs: fixed comments
nfbruns Apr 10, 2024
46b2c27
fix: return of ok if clause not added
nfbruns Apr 10, 2024
31d7e1c
test: cleanup and renaming
nfbruns Apr 10, 2024
cf6dd71
Merge branch 'main' into feat-batsat-solver
nfbruns Jun 14, 2024
1e6aa6b
compatability to 0.5.1 and solvertests implemented
nfbruns Jun 14, 2024
9f59fdd
feat:implemented batsat api
nfbruns Jun 26, 2024
2ccc905
docs: changelog and readme added
nfbruns Jun 26, 2024
4acddcd
ci: running github workflows
nfbruns Jun 26, 2024
a0e84a1
docs: fixed comments
nfbruns Jun 26, 2024
8ecd6ad
fix: return of ok if clause not added
nfbruns Jun 26, 2024
ed21c4f
test: cleanup and renaming
nfbruns Jun 26, 2024
4649148
compatability to 0.5.1 and solvertests implemented
nfbruns Jun 26, 2024
707e207
Merge branch 'feat-batsat-solver' of github.com:nfbruns/rustsat into …
nfbruns Jun 26, 2024
727e42c
fix: use workspace dependencies
nfbruns Jun 21, 2024
1544980
fix: clippy linting issues addressed
nfbruns Jun 26, 2024
fcfa9df
PR: implemented suggestions and applied reviews
nfbruns Jul 1, 2024
a1e4498
lint: clippy fixes and docu
nfbruns Jul 1, 2024
a549dda
docu: cargo rdme run
nfbruns Jul 1, 2024
0aeac45
docu: more comments and restructuring
nfbruns Jul 1, 2024
e0a9cd2
ci: run cargo rdme after comments changed
nfbruns Jul 3, 2024
3a3bd46
docu: remove code blocks for names
nfbruns Jul 4, 2024
80db5aa
ci: run cargo rdme
nfbruns Jul 4, 2024
adbe43e
lint: Batsat added as valid ident
nfbruns Jul 4, 2024
25bea4d
refactor: reorder clippy valid idents list
nfbruns Jul 4, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions .github/workflows/batsat.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: BatSat

on:
push:
branches: [ "main", "next-major" ]
pull_request:
branches: [ "main", "next-major" ]

env:
CARGO_TERM_COLOR: always

jobs:
build-test:
name: Build and test
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- name: Checkout sources
uses: actions/checkout@v4
- name: Install stable toolchain
uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
with:
shared-key: "build-test"
- name: Cargo build
run: cargo build -p rustsat-batsat --verbose
- name: Cargo test
run: cargo test -p rustsat-batsat --verbose
2 changes: 1 addition & 1 deletion .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
echo "failed for main crate"
return=false
fi
for dir in tools cadical kissat minisat glucose ipasir capi pyapi; do
for dir in tools cadical kissat minisat glucose batsat ipasir capi pyapi; do
cd ${dir}
if ! cargo rdme --check; then
echo "failed for ${dir}"
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/semver-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,7 @@ jobs:
uses: obi1kenobi/cargo-semver-checks-action@v2
with:
package: rustsat-ipasir
- name: BatSat
uses: obi1kenobi/cargo-semver-checks-action@v2
with:
package: rustsat-batsat
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ members = [
"solvertests",
"capi",
"pyapi",
"batsat",
]
resolver = "2"

Expand Down
2 changes: 2 additions & 0 deletions batsat/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/target
/Cargo.lock
9 changes: 9 additions & 0 deletions batsat/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Changelog

All notable changes to this project will be documented in this file.

## [0.1.0] - <Set Date When Releasing>

Initial Release

<!-- generated by git-cliff -->
21 changes: 21 additions & 0 deletions batsat/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[package]
name = "rustsat-batsat"
version = "0.1.0"
edition = "2021"
authors = ["Noah Bruns <[email protected]>"]
license = "MIT"
description = "Interface to the SAT solver BatSat for the RustSAT library. BatSat is fully implemented in Rust"
keywords = ["sat-solver", "rustsat", "batsat"]
repository = "https://github.com/chrjabs/rustsat"
readme = "README.md"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
batsat = "0.5.0" # when changing this version, do not forget to update signature
anyhow.workspace = true
thiserror.workspace = true
rustsat.workspace = true

[dev-dependencies]
rustsat-solvertests = { path = "../solvertests" }
18 changes: 18 additions & 0 deletions batsat/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[![Check & Test](https://github.com/chrjabs/rustsat/actions/workflows/batsat.yml/badge.svg)](https://github.com/chrjabs/rustsat/actions/workflows/batsat.yml)
[![crates.io](https://img.shields.io/crates/v/rustsat-batsat)](https://crates.io/crates/rustsat-batsat)
[![docs.rs](https://img.shields.io/docsrs/rustsat-batsat)](https://docs.rs/rustsat-batsat)
[![License](https://img.shields.io/crates/l/rustsat-batsat)](../LICENSE)

<!-- cargo-rdme start -->

# rustsat-batsat - Interface to the BatSat SAT Solver for RustSAT

Interface to the [BatSat](https://github.com/c-cube/batsat) incremental SAT-Solver to be used with the [RustSAT](https://github.com/chrjabs/rustsat) library.

BatSat is fully implemented in Rust which has advantages in restricted compilation scenarios like WebAssembly.

# BatSat Version

The version of BatSat in this crate is Version 0.5.0.

<!-- cargo-rdme end -->
1 change: 1 addition & 0 deletions batsat/data
125 changes: 125 additions & 0 deletions batsat/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
//! # rustsat-batsat - Interface to the BatSat SAT Solver for RustSAT
//!
//! Interface to the [BatSat](https://github.com/c-cube/batsat) incremental SAT-Solver to be used with the [RustSAT](https://github.com/chrjabs/rustsat) library.
//!
//! BatSat is fully implemented in Rust which has advantages in restricted compilation scenarios like WebAssembly.
//!
//! # BatSat Version
//!
//! The version of BatSat in this crate is Version 0.5.0.

#![warn(clippy::pedantic)]
#![warn(missing_docs)]

use batsat::{intmap::AsIndex, lbool, BasicSolver, SolverInterface};
use rustsat::{
solvers::{Solve, SolveIncremental, SolverResult},
types::{Clause, Lit, TernaryVal},
};
use thiserror::Error;

/// API Error from the BatSat library (for example if the solver is in an UNSAT state)
#[derive(Error, Clone, Copy, PartialEq, Eq, Debug)]
#[error("BatSat returned an invalid value: {error}")]
pub struct InvalidApiReturn {
error: &'static str,
}

/// RustSAT wrapper for the [`BasicSolver`] Solver from BatSat
#[derive(Default)]
pub struct BatsatBasicSolver(BasicSolver);

impl Extend<Clause> for BatsatBasicSolver {
fn extend<T: IntoIterator<Item = Clause>>(&mut self, iter: T) {
iter.into_iter()
.for_each(|cl| self.add_clause(cl).expect("Error adding clause in extend"));
}
}

impl<'a> Extend<&'a Clause> for BatsatBasicSolver {
fn extend<T: IntoIterator<Item = &'a Clause>>(&mut self, iter: T) {
iter.into_iter().for_each(|cl| {
self.add_clause_ref(cl)
.expect("Error adding clause in extend");
});
}
}

impl Solve for BatsatBasicSolver {
fn signature(&self) -> &'static str {
"BatSat 0.5.0"
}

fn solve(&mut self) -> anyhow::Result<SolverResult> {
match self.0.solve_limited(&[]) {
x if x == lbool::TRUE => Ok(SolverResult::Sat),
x if x == lbool::FALSE => Ok(SolverResult::Unsat),
x if x == lbool::UNDEF => Err(InvalidApiReturn {
error: "BatSat Solver is in an UNSAT state",
}
.into()),
_ => unreachable!(),
}
}

fn lit_val(&self, lit: Lit) -> anyhow::Result<TernaryVal> {
let l = batsat::Lit::new(batsat::Var::from_index(lit.vidx() + 1), lit.is_pos());

match self.0.value_lit(l) {
x if x == lbool::TRUE => Ok(TernaryVal::True),
x if x == lbool::FALSE => Ok(TernaryVal::False),
x if x == lbool::UNDEF => Ok(TernaryVal::DontCare),
_ => unreachable!(),
}
}

fn add_clause(&mut self, clause: Clause) -> anyhow::Result<()> {
let mut c: Vec<batsat::Lit> = clause
.iter()
.map(|l| batsat::Lit::new(self.0.var_of_int(l.vidx32() + 1), l.is_pos()))
.collect::<Vec<batsat::Lit>>();

self.0.add_clause_reuse(&mut c);

Ok(())
}

fn add_clause_ref(&mut self, clause: &Clause) -> anyhow::Result<()> {
let mut c: Vec<batsat::Lit> = clause
.iter()
.map(|l| batsat::Lit::new(self.0.var_of_int(l.vidx32() + 1), l.is_pos()))
.collect::<Vec<batsat::Lit>>();

self.0.add_clause_reuse(&mut c);

Ok(())
}
}

impl SolveIncremental for BatsatBasicSolver {
fn solve_assumps(&mut self, assumps: &[Lit]) -> anyhow::Result<SolverResult> {
let a = assumps
.iter()
.map(|l| batsat::Lit::new(self.0.var_of_int(l.vidx32() + 1), l.is_pos()))
.collect::<Vec<_>>();

match self.0.solve_limited(&a) {
x if x == lbool::TRUE => Ok(SolverResult::Sat),
x if x == lbool::FALSE => Ok(SolverResult::Unsat),
x if x == lbool::UNDEF => Err(InvalidApiReturn {
error: "BatSat Solver is in an UNSAT state",
}
.into()),
_ => unreachable!(),
}
}

fn core(&mut self) -> anyhow::Result<Vec<Lit>> {
Ok(self
.0
.unsat_core()
.iter()
.map(|l| Lit::new(l.var().idx() - 1, !l.sign()))
.collect::<Vec<_>>())
}
}
1 change: 1 addition & 0 deletions batsat/tests/incremental.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
rustsat_solvertests::incremental_tests!(rustsat_batsat::BatsatBasicSolver);
3 changes: 3 additions & 0 deletions batsat/tests/small.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
mod base {
rustsat_solvertests::base_tests!(rustsat_batsat::BatsatBasicSolver, false, true);
}
2 changes: 1 addition & 1 deletion clippy.toml
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
doc-valid-idents = ["RustSAT", "CaDiCaL", "MaxSAT", ".."]
doc-valid-idents = ["RustSAT", "CaDiCaL", "MaxSAT", "BatSat", ".."]
avoid-breaking-exported-api = false
5 changes: 5 additions & 0 deletions release-plz.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,8 @@ git_release_enable = false
name = "rustsat-pyapi"
release = false
git_release_enable = false

[[package]]
name = "rustsat-batsat"
release = false
git_release_enable = false
Loading