Skip to content

Commit

Permalink
feat: batsat solver interface
Browse files Browse the repository at this point in the history
interface to the [BatSat](https://github.com/c-cube/batsat) solver

closes #84

Squashed commit of the following:

commit 25bea4d
Author: Noah Bruns <51422579+nfbruns@users.noreply.github.com>
Date:   Thu Jul 4 16:01:43 2024 +0200

    refactor: reorder clippy valid idents list

    Co-authored-by: Christoph Jabs <98587286+chrjabs@users.noreply.github.com>

commit adbe43e
Author: Noah Bruns <nbruns@efs.at>
Date:   Thu Jul 4 12:03:33 2024 +0200

    lint: Batsat added as valid ident

commit 80db5aa
Author: Noah Bruns <nbruns@efs.at>
Date:   Thu Jul 4 09:42:01 2024 +0200

    ci: run cargo rdme

commit 3a3bd46
Author: Noah Bruns <51422579+nfbruns@users.noreply.github.com>
Date:   Thu Jul 4 09:41:02 2024 +0200

    docu: remove code blocks for names

    Co-authored-by: Christoph Jabs <98587286+chrjabs@users.noreply.github.com>

commit e0a9cd2
Author: Noah Bruns <nbruns@efs.at>
Date:   Wed Jul 3 11:03:56 2024 +0200

    ci: run cargo rdme after comments changed

commit 0aeac45
Author: Noah Bruns <nbruns@efs.at>
Date:   Mon Jul 1 18:09:57 2024 +0200

    docu: more comments and restructuring

commit a549dda
Author: Noah Bruns <nbruns@efs.at>
Date:   Mon Jul 1 17:51:42 2024 +0200

    docu: cargo rdme run

commit a1e4498
Author: Noah Bruns <nbruns@efs.at>
Date:   Mon Jul 1 17:48:15 2024 +0200

    lint: clippy fixes and docu

commit fcfa9df
Author: Noah Bruns <nbruns@efs.at>
Date:   Mon Jul 1 17:32:42 2024 +0200

    PR: implemented suggestions and applied reviews

commit 1544980
Author: Noah Bruns <nbruns@efs.at>
Date:   Wed Jun 26 11:17:22 2024 +0200

    fix: clippy linting issues addressed

commit 727e42c
Author: Noah Bruns <51422579+nfbruns@users.noreply.github.com>
Date:   Fri Jun 21 19:19:21 2024 +0200

    fix: use workspace dependencies

commit 707e207
Merge: 4649148 1e6aa6b
Author: Noah Bruns <nbruns@efs.at>
Date:   Wed Jun 26 11:08:55 2024 +0200

    Merge branch 'feat-batsat-solver' of github.com:nfbruns/rustsat into feat-batsat-solver

commit 4649148
Author: Noah Bruns <nbruns@efs.at>
Date:   Wed Jun 26 11:08:40 2024 +0200

    compatability to 0.5.1 and solvertests implemented

commit ed21c4f
Author: Noah Bruns <nbruns@efs.at>
Date:   Wed Jun 26 11:08:40 2024 +0200

    test: cleanup and renaming

commit 8ecd6ad
Author: Noah Bruns <51422579+nfbruns@users.noreply.github.com>
Date:   Wed Jun 26 11:08:40 2024 +0200

    fix: return of ok if clause not added

commit a0e84a1
Author: Noah Bruns <51422579+nfbruns@users.noreply.github.com>
Date:   Wed Jun 26 11:08:40 2024 +0200

    docs: fixed comments

commit 4acddcd
Author: Noah Bruns <nbruns@efs.at>
Date:   Wed Jun 26 11:08:40 2024 +0200

    ci: running github workflows

commit 2ccc905
Author: Noah Bruns <nbruns@efs.at>
Date:   Wed Jun 26 11:08:40 2024 +0200

    docs: changelog and readme added

commit 9f59fdd
Author: Noah Bruns <nbruns@efs.at>
Date:   Wed Jun 26 11:08:40 2024 +0200

    feat:implemented batsat api

commit 1e6aa6b
Author: Noah Bruns <nbruns@efs.at>
Date:   Fri Jun 14 17:21:51 2024 +0200

    compatability to 0.5.1 and solvertests implemented

commit cf6dd71
Merge: 31d7e1c ff1a3d6
Author: Noah Bruns <51422579+nfbruns@users.noreply.github.com>
Date:   Fri Jun 14 16:48:35 2024 +0200

    Merge branch 'main' into feat-batsat-solver

commit 31d7e1c
Author: Noah Bruns <nbruns@efs.at>
Date:   Wed Apr 10 16:25:51 2024 +0200

    test: cleanup and renaming

commit 46b2c27
Author: Noah Bruns <51422579+nfbruns@users.noreply.github.com>
Date:   Wed Apr 10 17:10:03 2024 +0200

    fix: return of ok if clause not added

commit 4b58cc8
Author: Noah Bruns <51422579+nfbruns@users.noreply.github.com>
Date:   Wed Apr 10 17:08:58 2024 +0200

    docs: fixed comments

commit ae01e17
Author: Noah Bruns <nbruns@efs.at>
Date:   Wed Apr 10 15:56:36 2024 +0200

    ci: running github workflows

commit b8326be
Author: Noah Bruns <nbruns@efs.at>
Date:   Wed Apr 10 15:55:25 2024 +0200

    docs: changelog and readme added

commit 5b78bd2
Author: Noah Bruns <nbruns@efs.at>
Date:   Wed Apr 10 15:17:41 2024 +0200

    feat:implemented batsat api
  • Loading branch information
nfbruns authored and chrjabs committed Jul 8, 2024
1 parent 0692ba7 commit 4d15c0f
Show file tree
Hide file tree
Showing 14 changed files with 222 additions and 2 deletions.
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 <nbruns@efs.at>"]
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

0 comments on commit 4d15c0f

Please sign in to comment.