Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/robbepop/cnf-parser

Efficient and customizable CNF parser for SAT solving.
https://github.com/robbepop/cnf-parser

cnf-clauses parser sat-solver

Last synced: 3 months ago
JSON representation

Efficient and customizable CNF parser for SAT solving.

Awesome Lists containing this project

README

        

# CNF Parser

| Continuous Integration | Documentation | Crates.io |
|:----------------------:|:----------------:|:--------------------:|
| [![CI][1]][2] | [![docs][3]][4] | [![crates][5]][6] |

An efficient and customizable parser for the [`.cnf` (Conjunctive Normal Form)][cnf-format]
file format used by [SAT solvers][sat-solving].

- No `unsafe` Rust!
- No dependencies!
- No heap allocations while parsing!
- `no_std` compatible!

## Usage

For parsing use the `parse_cnf` function.
It requires some input source that is expected to be `.cnf` encoded as well
as a `&mut` to a customizable output.
This output needs to implement the `Output` trait and is most probably your solver
or something that initializes your solver from the given `.cnf` input.

### Example

In order to use `parse_cnf` you first have to define your own `Output` type:

```rust
#[derive(Default)]
pub struct MyOutput {
head_clause: Vec,
clauses: Vec>,
}

impl Output for MyOutput {
type Error = &'static str;

fn problem(
&mut self, num_variables: u32, num_clauses: u32
) -> Result<(), Self::Error> {
Ok(())
}

fn literal(&mut self, literal: Literal) -> Result<(), Self::Error> {
self.head_clause.push(literal); Ok(())
}

fn finalize_clause(&mut self) -> Result<(), Self::Error> {
if self.head_clause.is_empty() {
return Err("encountered empty clause")
}
self.clauses.push(
core::mem::replace(&mut self.head_clause, Vec::new())
);
Ok(())
}

fn finish(&mut self) -> Result<(), Self::Error> {
if !self.head_clause.is_empty() {
self.finalize_clause()?
}
Ok(())
}
}
```

Then use `parse_cnf` as follows:

```rust
let my_input: &[u8] = br"
c This is my input .cnf file with 3 variables and 2 clauses.
p cnf 3 2
1 -2 3 0
1 -3 0
";
let mut my_output = MyOutput::default();
cnf_parser::parse_cnf(&mut my_input.as_ref(), &mut my_output)
.expect("encountered invalid .cnf input");
```

## License

Licensed under either of

* Apache license, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
* MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)

at your option.

### Dual licence: [![badge][license-mit-badge]](LICENSE-MIT) [![badge][license-apache-badge]](LICENSE-APACHE)

### Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any
additional terms or conditions.

[1]: https://github.com/Robbepop/cnf-parser/workflows/Rust%20-%20Continuous%20Integration/badge.svg?branch=master
[2]: https://github.com/Robbepop/cnf-parser/actions?query=workflow%3A%22Rust+-+Continuous+Integration%22+branch%3Amaster
[3]: https://docs.rs/cnf-parser/badge.svg
[4]: https://docs.rs/cnf-parser
[5]: https://img.shields.io/crates/v/cnf-parser.svg
[6]: https://crates.io/crates/cnf-parser

[sat-solving]: https://en.wikipedia.org/wiki/Boolean_satisfiability_problem
[cnf-format]: https://www.cs.utexas.edu/users/moore/acl2/manuals/current/manual/index-seo.php/SATLINK____DIMACS

[license-mit-badge]: https://img.shields.io/badge/license-MIT-blue.svg
[license-apache-badge]: https://img.shields.io/badge/license-APACHE-orange.svg