• Stars
    star
    247
  • Rank 163,039 (Top 4 %)
  • Language
    Prolog
  • License
    BSD 2-Clause "Sim...
  • Created over 11 years ago
  • Updated about 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

An in-memory datalog implementation for OCaml.

Datalog

build status

An in-memory datalog implementation for OCaml.

It features two main algorithm:

  • bottom-up focuses on big sets of rules with small relations, with frequent updates of the relations. Therefore, it tries to achieve good behavior in presence of incremental modifications of the relations.

  • top-down resembles prolog (and allows nested subterms). It handles stratified negation and only explores the part of the search space that is relevant to a given query.

Bottom-Up

This version, backward, features a backward-chaining operation. It resembles top-down algorithms because goals (possibly non-ground literals) can be added to the db; it means that if G is a goal and A :- B1,B2,...,Bn is a clause, if A and B1 are unifiable with subst, then subst(B1) is also a goal. Handlers (semantic attachments) can be provided by the user, to be called on every goal. The point is that the handlers can add facts that solve the goal by adding facts that match it.

For instance, a handler may solve goals of the form lt_than(i,j) (where i and j are integers) by adding the fact lt(i,j) if i < j is really true. Another example: if symbols are strings, then the goal concat("foo", "bar", X) may be solved by adding the fact concat("foo", "bar", "foobar"). The tool datalog_cli has build-in definitions of lt, le (lower or equal) and equal; see the last example. Thus, goals are a way to call semantic attachments in a goal-oriented way.

A relational query mode is available (its signature is in Datalog.BottomUp.S.Query, see the module's documentation. It allows to make one-shot queries on a db (the result won't update if facts or clauses are added later), with a simple relational model with negation.

Top-Down

There is also a top-down, prolog-like algorithm that should be very efficient for querying only a subpart of the intensional database (the set of all facts that can be deduced from rules). The main module is Datalog_top_down, and it has its own parser and lexer. An executable (not installed but compiled) is topDownCli.exe. A very important distinction is that terms can be nested (hence the distinct AST and parsers).

The format of semantic attachments for symbols is simpler: a handler, when queried with a given goal, can return a set of clauses whose heads will then be unified with the goal.

CamlInterface

The module Datalog_caml_interface in the library datalog.caml_interface contains a universal embedding of OCaml's types, with helpers to build unary, binary, and ternary atoms that directly relate OCaml values.

Small example:

# #require "datalog";;
# #require "datalog.caml_interface";;
# module CI = Datalog_caml_interface;;
module CI = Datalog_caml_interface
# let edge = CI.Rel2.create ~k1:CI.Univ.int ~k2:CI.Univ.int "edge";;
val edge : (int, int) CI.Rel2.t = <abstr>
# let db = CI.Logic.DB.create();;
val db : CI.Logic.DB.t = <abstr>
# CI.Rel2.symmetry db edge;;
- : unit = ()
# CI.Rel2.add_list db edge [1,2; 2,3; 3,4];;
- : unit = ()
# CI.Rel2.find db edge;;
- : (int * int) list = [(4, 3); (3, 2); (2, 1); (3, 4); (2, 3); (1, 2)]

The relation edge is really intensional: if we add axioms to it, CI.Rel2.find will return an updated view.

# CI.Rel2.transitive db edge;;
- : unit = ()
# CI.Rel2.find db edge;;
- : (int * int) list =
[(1, 3); (2, 4); (1, 4); (4, 1); (3, 1); (4, 2); (4, 3); (3, 2); (2, 1);
 (1, 1); (3, 3); (4, 4); (2, 2); (3, 4); (2, 3); (1, 2)]

One can also directly load a Datalog file (atoms: ints and strings) and access it using (properly typed) relations:

# let db = CI.Logic.DB.create ();;
val db : CI.Logic.DB.t = <abstr>
# CI.Parse.load_file db "tests/clique10.pl";;
- : bool = true
# let edge = CI.Rel2.create ~k1:CI.Univ.int ~k2:CI.Univ.int "edge";;
val edge : (int, int) CI.Rel2.t = <abstr>
# let reachable = CI.Rel2.create ~k1:CI.Univ.int ~k2:CI.Univ.int "reachable";;
val reachable : (int, int) CI.Rel2.t = <abstr>
# CI.Rel2.find db reachable;;
- : (int * int) list =
[(5, 0); (5, 1); (4, 0); (5, 2); (4, 1); (3, 0); (10, 7); (5, 3); (10, 8);
 (9, 7); (4, 2); (3, 1); (2, 0); (5, 4); (10, 9); (9, 8); (8, 7); (4, 3);
 (3, 2); (2, 1); (1, 0); (5, 5); (10, 10); (9, 9); (8, 8); (7, 7); (4, 4);
 (3, 3); (2, 2); (1, 1); (0, 0); (0, 1); (1, 2); (2, 3); (3, 4); (4, 5);
 (5, 6); (6, 7); (7, 8); (8, 9); (9, 10); (8, 10); (7, 9); (6, 8); (5, 7);
 (4, 6); (3, 5); (2, 4); (1, 3); (0, 2); (7, 10); (6, 9); (5, 8); (4, 7);
 (3, 6); (2, 5); (1, 4); (0, 3); (6, 10); (5, 9); (4, 8); (3, 7); (2, 6);
 (1, 5); (0, 4); (5, 10); (4, 9); (3, 8); (2, 7); (1, 6); (0, 5); (4, 10);
 (3, 9); (2, 8); (1, 7); (0, 6); (3, 10); (2, 9); (1, 8); (0, 7); (2, 10);
 (1, 9); (0, 8); (1, 10); (0, 9); (0, 10)]

Documentation

You can consult the online documentation

License

The code is distributed under the bsd_license See the LICENSE file.

Build

It is recommended to use opam: opam install datalog.

Manual build:

You need OCaml >= 4.02 with dune. Just type in the root directory:

$ make

How to use it

There are two ways to use datalog:

  • With the command line tool, datalog_cli.exe, or datalog_cli if you installed it on your system; just type in
$ datalog_cli <problem_file>
  • The libraries datalog, datalog.top_down, datalog.unix, datalog.caml_interface. See the .mli files for documentation, or the online documentation. For both Datalog_top_down and Datalog.BottomUp, functors are provided to use your own datatype for symbols (constants); however, a default implementation with strings as symbols is available as Datalog.Default (which is used by the parser Datalog.Parser) for bottom-up and in Datalog_top_down.Default for top-down.

A few example files, suffixed with .pl, can be found in tests/. For instance, you can try:

$ cat tests/clique10.pl
% generate problem of size 10
reachable(X,Y) :- edge(X,Y).
reachable(X,Y) :- edge(X,Z), reachable(Z,Y).
same_clique(X,Y) :- reachable(X,Y), reachable(Y,X).
edge(0, 1).
edge(1, 2).
edge(2, 3).
edge(3, 4).
edge(4, 5).
edge(5, 0).
edge(5, 6).
edge(6, 7).
edge(7, 8).
edge(8, 9).
edge(9, 10).
edge(10, 7).
$ datalog_cli tests/clique10.pl --pattern 'same_clique(1,X)'
% start datalog
% parse file tests/clique10.pl
% process 15 clauses
% computing fixpoint...
% done.
% facts matching pattern same_clique(1, X0):
  same_clique(1, 4).
  same_clique(1, 5).
  same_clique(1, 3).
  same_clique(1, 2).
  same_clique(1, 1).
  same_clique(1, 0).
...

Or

$ datalog_cli tests/graph200.pl --size --sum reachable
% start datalog
% parse file tests/graph200.pl
% process 205 clauses
% computing fixpoint...
% done.
% size of saturated set: 41209
% number of fact with head reachable: 40401
...

Or

$ datalog_cli tests/graph10.pl --goal 'increasing(3,7)' --pattern 'increasing(3,X)'
% start datalog
% parse file tests/graph10.pl
% process 15 clauses
% computing fixpoint...
% done.
% facts matching pattern increasing(3, X0):
  increasing(3, 10).
  increasing(3, 7).
  increasing(3, 6).
  increasing(3, 4).
  increasing(3, 5).
  increasing(3, 8).
  increasing(3, 9).
...

Or

$ datalog_cli tests/small.pl --query '(X,Y) :- ancestor(X,john), father(X,Y), not mother(Y,Z)'
% start datalog
% parse file tests/small.pl
% process 12 clauses
% computing fixpoint...
% done.
% query plan: (match[0] ancestor(X0, john) |><| match[1,0] father(X0, X1)) |> match[2,1] mother(X1, X2)
% query answer:
    'jean-jacques', alphonse
    brad, john
...

Aggregates in top-down:

$ cat test.pl
foo(a, 1).
foo(a, 2).
foo(b, 10).
foo(b, 11).
foo(c, 0).

bar(A, S) :- S := sum B : foo(A, B).

$ topDownCli -load foo.pl -builtin '(X,Y) :- bar(X,Y)'
  (a, 3).
  (b, 21).
  (c, 0).

TODOs/ideas

  • Goal subsumption
  • Clause subsumption (when selected lit is ground)
  • Clause retraction
  • Library of standard interpreted predicates

More Repositories

1

ocaml-containers

A lightweight, modular standard library extension, string library, and interfaces to various libraries (unix, threads, etc.) BSD license.
OCaml
485
star
2

qcheck

QuickCheck inspired property-based testing for OCaml.
OCaml
343
star
3

iter

Simple iterator abstract datatype, intended to iterate efficiently on collections while performing some transformations.
OCaml
104
star
4

tiny_httpd

Minimal HTTP server using good old threads + blocking IO, with a small request router.
OCaml
75
star
5

printbox

print nested boxes, lists, arrays, tables in several formats
OCaml
75
star
6

stimsym

[toy] A rewriting language similar to the core of Mathematica
OCaml
55
star
7

moonpool

Commodity thread pools and concurrency primitives for OCaml 5
OCaml
54
star
8

gen

Simple, efficient iterators for OCaml
OCaml
53
star
9

mc2

[research] A modular SMT solver in OCaml, based on mcSAT
SMT
39
star
10

oseq

Purely functional iterators compatible with standard `seq`.
OCaml
32
star
11

batsat

A (parametrized) Rust SAT solver originally based on MiniSat
Rust
31
star
12

lwt-pipe

[beta] A multi-consumer, multi-producers blocking queue and stream for Lwt
OCaml
31
star
13

calculon

Library for writing IRC bots in OCaml, a collection of plugins, and a dramatic robotic actor.
OCaml
28
star
14

ocaml-iostream

generic I/O streams of bytes
OCaml
28
star
15

cconv

[dead] combinators for type conversion (serialization/deserialization) to/from several formats. See this blog post (outdated): http://cedeela.fr/universal-serialization-and-deserialization.html
OCaml
27
star
16

linol

Wrapper around the OCaml `lsp` library to make it easier to write LSP servers
OCaml
26
star
17

ezcurl

A simple wrapper around OCurl.
OCaml
26
star
18

bare-ocaml

runtime library and code-generator for BARE (https://baremessages.org/)
OCaml
24
star
19

sidekick

A modular library for CDCL(T) SMT solvers, with [wip] proof generation.
SMT
24
star
20

smbc

Experimental model finder/SMT solver for functional programming.
OCaml
23
star
21

choice

Choice operator in OCaml, providing a backtracking monad
OCaml
22
star
22

spelll

fuzzy string searching, using Levenshtein automaton. Can be used for spell-checking.
OCaml
22
star
23

ocaml-avro

Runtime library and schema compiler for the Avro serialization format
OCaml
21
star
24

ocaml-trace

Common interface for tracing/instrumentation libraries in OCaml
OCaml
21
star
25

sqlite3_utils

[beta] High-level wrapper around ocaml-sqlite3
OCaml
18
star
26

olinq

LINQ-like combinators for manipulating collections of in-memory data
OCaml
17
star
27

maki

[beta] persistent memoization of computations, e.g. for repeatable tests and benchmarks
OCaml
17
star
28

ocaml-bigstring

Overlay over bigarrays of chars
OCaml
15
star
29

thread-local-storage

thread-local storage for OCaml
OCaml
15
star
30

fuseau

[alpha] lightweight fiber library for OCaml 5
OCaml
13
star
31

ocaml-minisat

OCaml bindings to Minisat
C++
13
star
32

ocaml-gnuplot

bindings to gnuplot (fork of https://bitbucket.org/ogu/gnuplot-ocaml/)
OCaml
13
star
33

seq

compatibility package for the standard OCaml iterator type
OCaml
12
star
34

quip

[wip] Proof format and checker for first-order and higher-order theorem provers
OCaml
12
star
35

batsat-ocaml

OCaml bindings for batsat (https://github.com/c-cube/batsat)
OCaml
11
star
36

trustee

[wip] A LCF-style kernel of trust intended for certified ATP and proof checking for FOL/HOL.
OCaml
11
star
37

ocabot

IRC bot for #ocaml@freenode
OCaml
10
star
38

ocaml-qbf

OCaml bindings to QBF solver(s)
C
10
star
39

jsonrpc2

[unfinished] Jsonrpc2 for OCaml, parametrized by the underlying IO.
OCaml
10
star
40

IKSML

[toy] industrial-strength implementation of the SKI calculus, using XML
8
star
41

thrifty

[wip] Reimplementation of thrift in OCaml
Thrift
8
star
42

hashset_benchs

Reproducing https://www.reddit.com/r/rust/comments/4dd5yl/rust_vs_f_hashset_benchmark/
Clojure
8
star
43

funarith

[wip] functorial library with classic algorithms for arithmetic
OCaml
8
star
44

ocaml-atomic

Compatibility package for the Atomic module
OCaml
8
star
45

indexed-set

OCaml implementation of indexed sets (inspired from Haskell's ixSet library)
OCaml
8
star
46

ty

[draft] dynamic representation of types
OCaml
7
star
47

zulip-log-viewer

Small website to serve zulip logs obtained from [zulip archive](https://github.com/zulip/zulip-archive)
OCaml
6
star
48

ocaml-twirp

OCaml implementation of Twirp using ocaml-protoc
OCaml
6
star
49

poc-modular-io

proof of concept for https://github.com/ocaml/RFCs/pull/19
OCaml
6
star
50

frog-utils

[frozen] Scheduling and running jobs on a shared computer, then analyse their output
OCaml
5
star
51

oasis-parser

Simple parser for _oasis files
OCaml
5
star
52

ocaml-chord

[unfinished] Chord DHT implementation in OCaml (not production-ready)
OCaml
5
star
53

rcontext

Per-request context, inspired from Go's
OCaml
5
star
54

space_camels

[toy] Tiny game built to try notty
OCaml
5
star
55

smtlib-utils

A parser and some utils for SMTLIB. For a fully compliant parser, see https://github.com/Gbury/dolmen/.
SMT
5
star
56

gemini-client

[toy] ocaml client for gemini
OCaml
4
star
57

containers-lwt

Utilities for Lwt
OCaml
4
star
58

bender

[toy] IRC bot in rust, for my private use
Rust
4
star
59

iterators_bench

[bench] benchmark of various iterator implementations
OCaml
4
star
60

playground

various little experiments
OCaml
4
star
61

ccbor

[WIP] CBOR codec for OCaml
OCaml
4
star
62

ocaml-ty

[clone] Fork of ocaml-ty by GrΓ©goire Henry (original url https://gitorious.org/ocaml-ty/)
OCaml
4
star
63

containers-misc

[toy] Random stuff from containers, low quality, experimental
OCaml
4
star
64

neperien

[unfinished] structured, hierarchical log system for OCaml
OCaml
4
star
65

andes

[toy, wip] A chain with lots of lemmas. More specifically, a logic programming engine.
OCaml
4
star
66

logtk

[migrated to https://github.com/c-cube/zipperposition] Logic toolkit, designed primarily for first-order automated reasoning. It aims at providing basic types and algorithms (terms, unification, orderings, indexing, etc.) that can be factored out of several applications.
OCaml
4
star
67

vim-tptp

Vim syntax file for the TPTP logic format (http://www.cs.miami.edu/~tptp/)
Vim Script
4
star
68

paradox

[clone] model finder for first-order logic, from http://vlsicad.eecs.umich.edu/BK/Slots/cache/www.cs.chalmers.se/~koen/paradox/
Haskell
4
star
69

bencode_rpc

[toy] Remote Procedure Call with B-encode serialization and Lwt concurrency (probably not production ready).
OCaml
3
star
70

ldl

[TOY] loop-dee-loop, an event loop
OCaml
3
star
71

bender-ocaml

[dead] Write OCaml plugins for bender
OCaml
3
star
72

quip-book

Book for Quip, a proof format for first-order and higher-order theorem provers
SMT
3
star
73

ocaml-aig

[toy] And-Inverter Graph in OCaml
OCaml
2
star
74

tiny-httpd-moonpool-bench

experiment with tiny_httpd using moonpool as a scheduler
Makefile
2
star
75

tomato-chan

[wip] IRC bot.
OCaml
2
star
76

unif-visitor

Playground for visitors on terms
OCaml
2
star
77

ocaml-polynomials

[toy] Toy implementation of multi-variable polynomials over Z
OCaml
1
star
78

microsat

experiments around microsat
Rust
1
star
79

ppx_deriving_cconv

[deprecated] ppx_deriving instance for CConv encoders/decoders
OCaml
1
star
80

tip-parser

[obsolete] parser for https://github.com/tip-org/
OCaml
1
star
81

irky

[wip] IRC client for OCaml
OCaml
1
star
82

ocaml-irclog

parsing IRC logs as produced by irssi
OCaml
1
star
83

strictly_tally

Implementation of relative placement tabulation for dance competitions
Rust
1
star