Hassan Abedi aac85af9a1 WIP
2026-03-09 10:49:50 +01:00
WIP
2026-03-09 10:42:36 +01:00
WIP
2026-03-09 10:42:36 +01:00
WIP
2026-03-09 10:42:36 +01:00
2026-03-09 10:42:31 +01:00
WIP
2026-03-09 10:42:36 +01:00
WIP
2026-03-09 10:42:36 +01:00
WIP
2026-03-09 10:44:30 +01:00
WIP
2026-03-09 10:42:36 +01:00
2026-03-09 10:42:31 +01:00
WIP
2026-03-09 10:42:36 +01:00
2026-03-09 10:42:31 +01:00
WIP
2026-03-09 10:49:50 +01:00
2026-03-09 10:42:31 +01:00

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

Quick Start

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:

// 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();

Building and Testing

## Run all tests
cargo test

## Run with optimizations
cargo build --release

## Check for lint warnings
cargo clippy

License

This project is licensed under BSD-3.

Description
A chase algorithm implementation in Rust 🦀
Readme BSD-3-Clause 127 KiB
Languages
Rust 89.3%
Makefile 7.3%
Nix 3.4%