• Stars
    star
    379
  • Rank 113,004 (Top 3 %)
  • Language
    Clojure
  • License
    Eclipse Public Li...
  • Created over 8 years ago
  • Updated over 2 years ago

Reviews

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

Repository Details

Datalog based rules engine

This repository is no longer being maintained. For ongoing development, please see https://github.com/quoll/naga/.

Naga Build Status Contributor Covenant

Datalog based rules engine.

Clojars Project

Naga allows users to load data, and define rules to entailed new data. Once rules have been executed, the database will be populated with new inferences which can be queried.

Naga can use the Asami database, or wrap an external graph database. A command line utility to demonstrate Naga will load rules, into memory, run them, and print all the inferred results.

Usage

Naga is a library for executing rules on a graph database.

There is also an included project called Naga-CLI (in the cli directory). This was written as an example of how to use the Datomic API, but it can also be run on a Datalog script as a utility.

The script can be provided via stdin or in a filename argument.

The easiest way to run this tool is with Leiningen.

  cd cli
  lein run example_data/family.lg

This runs the program found in the example_data/family.lg file. It loads the data specified in the file, executes the rules, and finally prints the final results database, without the input data.

Options

  • --init Initialization data for the configured storage.
  • --json Input path/url for JSON to be loaded and processed.
  • --out Output file when processing JSON data (ignored when JSON not used).
  • --uri URI describing a database to connect to. (default: mem. Datomic supported).

Programs

The language being implemented is called "Pabu" and it strongly resembles Prolog. It is simply a series of statements, which are of two types: assertions and rules.

Assertions

To declare facts, specify a unary or binary predicate.

  man(fred).
  friend(fred,barney).

The first statement declares that fred is of type man. The second declares that fred has a friend who is barney.

Nothing needs to be declared about man or friend. The system doesn't actually care what they mean, just that they can be used in this way. The use of these predicates is all the declaration that they need.

Rules

Rules are declared in 2 parts.

head :- body .

The body of the rule, defines the data that causes the rule to be executed. This is a comma separated series of predicates, each typically containing one or more variables. The predicate itself can also be variable (this is very unusual in logic systems).

The head of the rule uses some of the variables in the body to declare new information that the rule will create. It is comprised of a single predicate.

Variables are words that begin with a capital letter (yes, Prolog really does look like this).

Here is a rule that will infer an uncle relationship from existing data:

  uncle(Nibling,Uncle) :- parent(Nibling,Parent), brother(Parent,Uncle).

In the above statement, Nibling, Parent, and Uncle are all variables. Once variables have been found to match the predicates after the :- symbol, then they can be substituted into the uncle predicate in the head of the rule.

Other Syntax

Both assertions and rules end with a period.

Pabu (and Prolog) uses "C" style comments:

  /* This is a comment */

Any element can be given a namespace by using a colon separator. Only 1 colon may appear in an identifier.

  owl:SymmetricProperty(sibling).

To see this in use, look in pabu/family-2nd-ord.lg, and try running it:

  lein run example_data/family-2nd-ord.lg

APIs

Naga defines a data access API to talk to storage. This is a Clojure protocol or Java interface called Storage, found in naga.store. It should be possible to wrap most graph database APIs in the Storage API.

For the moment, the only configured implementations are Asami and Datomic. Recently, the focus has been on Asami.

Asami

The following can be used to access an in-memory database on Asami:

(require '[asami.core :as asami])    ;; loads Asami
(require '[naga.storage.asami.core]) ;; load the Asami adapter for Naga
(require '[naga.lang.pabu :refer [read-str]]) ;; namespace for reading rule strings
(require '[naga.rules :as rules])    ;; namespace for rule definitions and compiling
(require '[naga.engine :as engine])  ;; the rules engine

  ;; create a database and connect to it
(def uri "asami:mem://my-db")
(asami/create-database uri)
(let [connection (asami/connect uri)]

  ;; add some data
  ;; deref to wait until the transaction has completed
  (deref
    (asami/transact connection
                    {:tx-data [[:db/add :xerces :parent :brooke]
                               [:db/add :brooke :parent :damocles]]}))

  ;; load some rules and compile into a program
  (let [rules (:rules (read-str "ancestor(X, Y) :- parent(X, Y).
                                 ancestor(X, Y) :- parent(X, Z), ancestor(Z, Y)."))
        program (rules/create-program rules)]
    (engine/run connection program)

    ;; look at the data to see who Xerces' ancestors are
    (println (asami/q '[:find [?ancestor ...] :where [:xerces :ancestor ?ancestor]] (asami/db connection)))))

This prints:

(:brooke :damocles)

This starts and ends with standard Asami access. Naga is used to parse the rule program, and execute the rules.

In Memory Database

Naga is designed to operate against any graph database. The interface for this is the Storage protocol described above, and is defined in the project naga-store. Implementations of this protocol exist for Datomic, and a local in-memory graph database called Asami. Asami is used by default. Asami has a relatively capable query planner, and internal operations for inner joins and projection. More operations are in the works.

Queries may be executed directly against the database, but for the moment they require API access.

We also have some partial implementations for on-disk storage, which we hope to use. These are based on the same architecture as the indexes in the Mulgara Database.

License

Copyright © 2016-2021 Cisco Systems

Copyright © 2011-2016 Paula Gearon

Distributed under the Eclipse Public License either version 1.0 or (at your option) any later version.

More Repositories

1

asami

A graph store for Clojure and ClojureScript
Clojure
637
star
2

kiries

A turn-key deployment of Kibana, Riemann and ElasticSearch
Shell
126
star
3

pldb

(DEPRECATED) persistent logic database for clojure core.logic
Clojure
73
star
4

ctia

Cisco Threat Intelligence API
Clojure
67
star
5

ctim

Cisco Threat Intellligence Model
Clojure
66
star
6

jq-go

A Go language binding for the JQ JSON filter library
Go
21
star
7

ring-jwt-middleware

JWT auth checks for Ring
Clojure
16
star
8

declarative.bash

A simple framework for writing declarative shell scripts
Shell
14
star
9

ductile

A Clojure Elasticsearch library
Clojure
12
star
10

jqpipe-go

A Go Wrapper for JQ
Go
12
star
11

ring-graphql-ui

GraphQL UI
Clojure
11
star
12

asynp

A Clojure core.async library for efficiently managing subprocesses I/O
Clojure
10
star
13

scopula

Clojure
8
star
14

redismq

A Redis-based queue system for Clojure
Clojure
8
star
15

asami-loom

Loom extensions for Asami
Clojure
7
star
16

naga-http

Logic server for the Naga rule engine
Clojure
7
star
17

naga-store

Storage API for Naga
Clojure
7
star
18

clj-momo

Shared code use in multiple swagger-api backed Clojure web apps
Clojure
6
star
19

zuko

Clojure
5
star
20

ctia-ui

A web-based interface to a Cisco Threat Intel API instance
CSS
5
star
21

nix-hive

Nix Hive is a tool for building and deploying Nix systems to multiple hosts in an efficient way.
Go
4
star
22

appa

JSON processing library for Asami
Clojure
3
star
23

clj-experiments

Clojure
3
star
24

formatting-stack.alias-rewriter

2
star
25

osquery

This fork contains changes to OSQuery made by Orbital.
C++
2
star
26

ring-graphiql

GraphiQL packaged for Ring Apps
Clojure
1
star
27

securex-news

SecureX news aggregation service
JavaScript
1
star
28

flanders

Define data types for CTIM
Clojure
1
star
29

ring-graphql-voyager

GraphQL Voyager packaged for Ring Apps
HTML
1
star
30

ring-api-key-middleware

Clojure
1
star