Crate serde_datalog

Crate serde_datalog 

Source
Expand description

Serde Datalog provides functionality to generate a database of facts from any data structure whose type implements serde::Serialize. In Datalog parlance, this crate serializes data structures to EDBs.

There are two main components. DatalogExtractor is an implementation of serde::Serializer that generates facts from data structures mapped onto Serde’s data model. The extractor does not explicitly represent these facts; instead, it calls out into implementations of the DatalogExtractorBackend trait, which materializes these facts into some explicit representation. You can swap out backends to change the representation of facts.

§Example

Consider the following enum type:

#[derive(Serialize)]
enum Foo {
    A(Box<Foo>),
    B(i64)
}

Note that Foo implements the serde::Serialize trait. This is necessary because Serde Datalog assumes that inputs can be lowered into Serde’s data model. (It’s in the name!)

Consider the enum instance Foo::A(Box::new(Foo::B(10))). The extractor generates the following facts to represent this data structure:

  • Element 1 is a newtype variant
  • Element 1 has type Foo and variant name A
  • The first field of Element 1 references Element 2
  • Element 2 is a newtype variant
  • Element 2 has type Foo and variant name B
  • The first field of Element 2 references Element 3
  • Element 3 is an i64
  • Element 3 has value 10

The extractor generates facts from a data structure through flattening: it generates unique identifiers for each element within the data structure, and references between elements are “unswizzled” into identifiers.

For each fact, the extractor will make calls to an implementation of DatalogExtractorBackend to materialize the fact. For example, we can use the vector backend to materialize these extracted facts as vectors of tuples. You can then use these vectors as inputs to queries for Datalog engines embedded in Rust, such as Ascent or Crepe.

let input = Foo::A(Box::new(Foo::B(10)));
let mut extractor = DatalogExtractor::new(backend::vector::Backend::default());
input.serialize(&mut extractor);

// Now we can inspect the tables in the backend to see what facts got
// extracted from the input.

let data: backend::vector::BackendData<ElemId> = extractor.get_backend().get_data();

// there are 3 total elements
assert!(data.type_table.len() == 3);

// there are 2 enum variant elements
assert!(data.variant_type_table.len() == 2);

// there is 1 number element
assert!(data.number_table.len() == 1);

Alternatively, you can store the generated facts in a SQLite file with the Souffle SQLite backend. You can then use this file as an input EDB for Datalog queries executed by Souffle.

let input = Foo::A(Box::new(Foo::B(10)));
let mut backend = backend::souffle_sqlite::Backend::default();
let mut extractor = DatalogExtractor::new(&mut backend);
input.serialize(&mut extractor);
backend.dump_to_db("input.db");

Modules§

backend
Implementations of DatalogExtractorBackend.

Structs§

DatalogExtractor
Implementation of serde::Serializer that extracts facts from a data structure. Note that the extractor does not contain an explicit representation of the facts that it generates from a data structure. Instead, it calls out to a DatalogExtractorBackend to materialize facts.
ElemId
A unique identifier for data elements. Identifiers are automatically generated by the extractor.

Enums§

DatalogExtractionError
Error encountered during extraction.
ElemType
Enumeration of possible element types within a data structure. These correspond directly to the types in Serde’s data model. The main exception is that this enum does not contain a variant for option types; instead of treating it as a special case, DatalogExtractor instead treats option values as regular enum values. That is, None values are treated as unit variants with type name Option and variant name None, while Some values are treated as newtype variants with type name Option and variant name Some.

Traits§

DatalogExtractorBackend
An implementation of DatalogExtractorBackend materializes facts generated by DatalogExtractor. These facts can be represented in whatever format the backend chooses, e.g. a SQLite database, a set of vectors, etc.

Type Aliases§

Result