chase-rs/README.md
Hassan Abedi 8f9806c515 WIP
2026-03-09 11:09:12 +01:00

96 lines
2.7 KiB
Markdown

## Chase-rs
An implementation of the chase algorithm in Rust for advanced reasoning engines.
### Overview
The chase algorithm is a fundamental technique in context of database theory and knowledge representation used for:
- Query answering under tuple-generating dependencies (TGDs)
- Computing universal models
- Ontology-based data access (OBDA)
- Datalog with existential rules
This implementation provides a **restricted chase** that guarantees termination even with existential rules by tracking applied triggers.
### Features
- **Core Data Types**: Terms, Atoms, Rules, and Instances
- **Existential Quantification**: Automatic generation of labeled nulls
- **Restricted Chase**: Termination guarantees via trigger tracking
- **Fluent API**: `RuleBuilder` for readable rule construction
- **Zero Dependencies**: Pure Rust with no external runtime dependencies
See [ROADMAP.md](ROADMAP.md) for the list of implemented and planned features.
> [!IMPORTANT]
> This project is still in early development, so bugs and breaking changes are expected.
> Please use the [issues page](https://code.obsidian.systems/habedi-work/chase-rs/issues) to report bugs or request features.
---
### Quickstart
```rust
use chase_rs::{chase, Atom, Instance, Term};
use chase_rs::chase::rule::RuleBuilder;
// Create initial facts
let instance: Instance = vec![
Atom::new("Parent", vec![Term::constant("alice"), Term::constant("bob")]),
Atom::new("Parent", vec![Term::constant("bob"), Term::constant("carol")]),
].into_iter().collect();
// Define rules
// Parent(X, Y) -> Ancestor(X, Y)
let rule1 = RuleBuilder::new()
.when("Parent", vec![Term::var("X"), Term::var("Y")])
.then("Ancestor", vec![Term::var("X"), Term::var("Y")])
.build();
// Ancestor(X, Y), Parent(Y, Z) -> Ancestor(X, Z)
let rule2 = RuleBuilder::new()
.when("Ancestor", vec![Term::var("X"), Term::var("Y")])
.when("Parent", vec![Term::var("Y"), Term::var("Z")])
.then("Ancestor", vec![Term::var("X"), Term::var("Z")])
.build();
// Run the chase
let result = chase(instance, &[rule1, rule2]);
assert!(result.terminated);
println!("Derived {} facts", result.instance.len());
```
### Existential Rules
Rules with head-only variables (existential quantification) automatically generate fresh labeled nulls:
```rust
// Every person has an SSN: Person(X) -> HasSSN(X, Y)
let rule = RuleBuilder::new()
.when("Person", vec![Term::var("X")])
.then("HasSSN", vec![Term::var("X"), Term::var("Y")]) // Y is existential
.build();
```
### Usful Commands
```bash
# Run all tests
make test
# Run linter checks
make lint
# Run with optimizations
make build
# Run CLI
make run
```
### License
This project is licensed under [BSD-3](LICENSE).