asdi 0.2.1

Another Simplistic Datalog Implementation (in Rust)
Documentation

Crate asdi

Another Simplistic Datalog Implementation (in Rust).

MIT License Minimum Rust Version crates.io docs.rs Build Audit GitHub stars

This package provides a data model to represent Datalog programs in memory, a parser for the textual representation, and some evaluation implementations.

The text representation parser is a separate feature, so if you only need to construct and evaluate programs using the API you may opt out of the Pest parser and support.

Status

  1. Library API mostly stable, but minimal, will try and make the construction API more ergonomic.
  2. Library Documentation good top-level documentation but very little else right now.
  3. Library validation checking basic checking, but some is done in the parser and needs to be in the library.
  4. Parser full support for the core language as well as pragmas, require more unit tests.
  5. I/O relations are now connected to the file input/output pragmas, the io module includes traits for reading/writing relations as well as basic JSON and CSV support.
  6. Evaluation current evaluator is basically top-down brute force and does not support any additional language features.

Example

parent(xerces, brooke).
parent(brooke, damocles).

ancestor(X, Y) ⟵ parent(X, Y).
ancestor(X, Y) ⟵ parent(X, Z) ⋀ parent(Z, Y).

?- ancestor(xerces, X).
use asdi::edb::{Attribute, Predicate};
use asdi::idb::{Atom, Query, Term, Variable};
use asdi::Program;
use std::str::FromStr;

fn ancestor_example() {
    // See https://en.wikipedia.org/wiki/Datalog

    let mut ancestors = Program::default();

    let parent_predicate = Predicate::from_str("parent").unwrap();
    {
        let parent = ancestors
            .add_new_relation(
                parent_predicate.clone(),
                vec![Attribute::string(), Attribute::string()],
            )
            .unwrap();
        parent
            .add_as_fact(["xerces".into(), "brooke".into()])
            .unwrap();
        parent
            .add_as_fact(["brooke".into(), "damocles".into()])
            .unwrap();
    };

    let ancestor_predicate = Predicate::from_str("ancestor").unwrap();

    let var_x: Term = Variable::from_str("X").unwrap().into();
    let var_y: Term = Variable::from_str("Y").unwrap().into();
    let var_z: Term = Variable::from_str("Z").unwrap().into();

    ancestors
        .add_new_rule(
            ancestor_predicate.clone(),
            [var_x.clone(), var_y.clone()],
            [Atom::new(parent_predicate.clone(), [var_x.clone(), var_y.clone()]).into()],
        )
        .unwrap();
    ancestors
        .add_new_rule(
            ancestor_predicate.clone(),
            [var_x.clone(), var_y.clone()],
            [
                Atom::new(parent_predicate, [var_x.clone(), var_z.clone()]).into(),
                Atom::new(ancestor_predicate.clone(), [var_z, var_y]).into(),
            ],
        )
        .unwrap();

    ancestors
        .add_new_query(ancestor_predicate, ["xerces".into(), var_x])
        .unwrap();

    println!(">{}<", ancestors);
}

Changes

Version 0.2.1

  • Added traits for consistency across types.
  • Added a predicate cache to reduce duplication.
  • Finished the file input and output for relations.
  • Cleaned up the error module and added functions for error construction.

Version 0.2.0

  • New internal structures and library layout.
  • Less cloning, but still too much.
  • Finished top-level documentation, more to come.

Version 0.1.0

  • Not published, used for own verification only.

Version 0.1.0-dev

  • Initial release, mostly to verify CI infrastructure through to crates.io