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
Fooand variant nameA - The first field of Element 1 references Element 2
- Element 2 is a newtype variant
- Element 2 has type
Fooand variant nameB - 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§
- Datalog
Extractor - 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§
- Datalog
Extraction Error - Error encountered during extraction.
- Elem
Type - 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,
Nonevalues are treated as unit variants with type nameOptionand variant nameNone, whileSomevalues are treated as newtype variants with type nameOptionand variant nameSome.
Traits§
- Datalog
Extractor Backend - An implementation of
DatalogExtractorBackendmaterializes 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.