Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/night-crawler/nnf
Negation Normal Form manipulation library
https://github.com/night-crawler/nnf
cnf nnf tseitin-transformation
Last synced: 8 days ago
JSON representation
Negation Normal Form manipulation library
- Host: GitHub
- URL: https://github.com/night-crawler/nnf
- Owner: night-crawler
- License: mit
- Created: 2022-12-26T20:40:56.000Z (almost 2 years ago)
- Default Branch: main
- Last Pushed: 2023-04-19T11:50:05.000Z (over 1 year ago)
- Last Synced: 2024-05-22T21:34:42.836Z (6 months ago)
- Topics: cnf, nnf, tseitin-transformation
- Language: Rust
- Homepage:
- Size: 30.3 KB
- Stars: 1
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- awesome-rust-formalized-reasoning - nnf - Negation Normal Form manipulation library. (Projects / Libraries)
README
# nnf
[![crates.io](https://img.shields.io/crates/v/nnf.svg)](https://crates.io/crates/nnf)
[![Rust](https://github.com/night-crawler/nnf/actions/workflows/rust.yml/badge.svg?branch=main)](https://github.com/night-crawler/nnf/actions/workflows/rust.yml)
[![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE)Negation Normal Form manipulation library
### Macro & bit operations
```rust
fn sample() {
let a = Nnf::Var("a", true);
let b = var!("b", false);
let or = or!(a.clone(), b.clone());
}```
### Simple operations optimization
```rust
assert_eq!(and!("a") & and!("b"), and!("a", "b"));
assert_eq!(and!("a") | and!("b"), or!("a", "b"));
```### Tseitin Transform (NNF -> CNF)
```rust
fn transform(sentence: Nnf<&'static str>) -> Nnf<&'static str> {
let mut counter = 0;
let transformer = TseitinTransform::new(|_| {
let name: &'static str = Box::leak(Box::new(format!("aux_{}", counter)));
counter += 1;
var!(name)
});transformer.transform(sentence)
}fn test() {
let sentence = or!(
and!(
var!("a"),
and!("b", "c")
),
and!(
or!("!d", "e"),
and!("f", "!g")
)
);
assert!(!sentence.is_cnf(), "Expression is not a cnf yet");let sentence = transform(sentence);
assert!(sentence.is_cnf(), "Expression must be in the cnf form after transformation");assert_eq!(
sentence,
and!(
or!("a", "!aux_1"),
or!("aux_0", "!aux_1"),
or!("aux_1", "aux_4"),
or!("aux_2", "!aux_4"),
or!("aux_3", "!aux_4"),
or!("!aux_0", "b"),
or!("!aux_0", "c"),
or!("aux_3", "d"),
or!("aux_3", "!e"),
or!("!aux_2", "f"),
or!("!aux_2", "!g"),
or!("!a", "!aux_0", "aux_1"),
or!("!aux_2", "!aux_3", "aux_4"),
or!("aux_0", "!b", "!c"),
or!("!aux_3", "!d", "e"),
or!("aux_2", "!f", "g")
)
);
}
```## Parse Tree
### Macro support
```rust
fn test() {
let root = ExpressionNode::Not(
ExpressionNode::And(
ExpressionNode::Or(
ExpressionNode::Leaf(1).into(),
ExpressionNode::Leaf(2).into(),
).into(),
ExpressionNode::And(
ExpressionNode::Leaf(3).into(),
ExpressionNode::Leaf(4).into(),
).into(),
).into());let root = e_not!(
e_and!(
e_or!(
e_leaf!(1),
e_leaf!(2)
),
e_and!(
e_leaf!(3),
e_leaf!(4)
)
)
);
}
```### Expression Tree to NNF conversion (De Morgan's Law, double negation, etc.)
```rust
assert_eq!(
e_not!(e_leaf!(true) & e_leaf!(true)).to_nnf(),
e_or!(e_leaf!(false), e_leaf!(false))
);assert_eq!(
e_not!(e_leaf!(true) | e_leaf!(true)).to_nnf(),
e_and!(e_leaf!(false), e_leaf!(false))
);assert_eq!(
!ExpressionNode::Not(e_or!(e_leaf!(true), e_leaf!(true)).into()),
e_or!(e_leaf!(true), e_leaf!(true))
);
```## (Optional) Render / Graphviz
```rust
fn test() {
let sentence = or!(
and!(
var!("a"),
and!("b", "c")
),
and!(
or!("!d", "e"),
and!("f", "!g")
)
);
assert!(!sentence.render().is_empty());
}
```