Hash :
3fbd5a78
Author :
Thomas de Grivel
Date :
2023-07-11T14:01:32
1.1 The world is the totality of facts, not of things.
– Ludwig Wittgenstein, Tractatus Logico Philosophicus
cl-facts is a small in-memory graph database for Common Lisp. It features :
You will need :
Adds facts (triples) to the database. Triples can be grouped by subject.
(facts:add ("Blade Runner" :is-a :movie
:director "Ridley Scott"
:actor "Harison Ford"
:actor "Rutger Hauer")
("Snow White" :is-a :movie
:director "William Cottrell"
:director "David Hand"))
or either
(facts:add (?movie :is-a :movie
:title "Blade Runner"
:director "Ridley Scott"
:actor "Harrison Ford"
:actor "Rutger Hauer"))
(facts:add (?movie :is-a :movie
:title "Snow White and the Seven Dwarfs"
:director "William Cottrell"
:director "David Hand"))
(with ((?s ?p ?o))
(format t "~&~S ~S ~S~&" ?s ?p ?o))
=> NIL
FACTS.ANON::MOVIE-0000 :ACTOR "Harison Ford"
FACTS.ANON::MOVIE-0000 :ACTOR "Rutger Hauer"
FACTS.ANON::MOVIE-0000 :DIRECTOR "Ridley Scott"
FACTS.ANON::MOVIE-0000 :IS-A :MOVIE
FACTS.ANON::MOVIE-0000 :TITLE "Blade Runner"
FACTS.ANON::MOVIE-0001 :DIRECTOR "David Hand"
FACTS.ANON::MOVIE-0001 :DIRECTOR "William Cottrell"
FACTS.ANON::MOVIE-0001 :IS-A :MOVIE
FACTS.ANON::MOVIE-0001 :TITLE "Snow White"
The second version with ?movie
will generate an anonymous symbol prefixed with movie-
.
It is considered a more clean and efficient way to abstract identifiers.
(facts:rm (?movie :actor "Harison Ford"))
To follow Wittgenstein’s view of the world, all queries get turned into testing the presence or absence of triples (facts).
Variables are prefixed with a question mark symbol “?” and are wildcards, matching everything. Nested queries get their variables expanded, giving pattern matching abilities. For instance :
(with ((?s ?p ?o)
(format t "~&~S ~S ~S~&" ?s ?p ?o))
=>
"Blade Runner" :ACTOR "Harison Ford"
"Blade Runner" :ACTOR "Rutger Hauer"
"Blade Runner" :DIRECTOR "Ridley Scott"
"Blade Runner" :IS-A :MOVIE
"Snow White" :DIRECTOR "David Hand"
"Snow White" :DIRECTOR "William Cottrell"
"Snow White" :IS-A :MOVIE
Multiple queries on the same subject can be grouped together easily :
(facts:with ((?movie :is-a :movie
:title ?title
:director ?director))
(format t "~A directed ~A~%" ?director ?title))
=>
Ridley Scott directed Blade Runner
David Hand directed Snow White and the Seven Dwarfs
William Cottrell directed Snow White and the Seven Dwarfs
Negative facts specifications will remove matching facts from the results.
(with ((?s ?p ?o)
(:not ?s :actor "Harison Ford"))
(format t "~&~S ~S ~S~&" ?s ?p ?o))
=>
"Snow White" :DIRECTOR "David Hand"
"Snow White" :DIRECTOR "William Cottrell"
"Snow White" :IS-A :MOVIE
The current facts database.
Clears the database from every facts.
Dump the database facts into filespec INTO.
Load the facts from SRC into *db*.
Enclose BODY database operations into a transaction.
A transaction ensures that all database operations will succeed or be reverted using their respective rollback functions.
Transactions can be nested safely.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
facts-db/cl-facts
=================
> 1.1 The world is the totality of facts, not of things.
>
> -- Ludwig Wittgenstein, Tractatus Logico Philosophicus
cl-facts is a small in-memory graph database for Common Lisp.
It features :
* a triple store based on unlabelled skip lists
* a very simple query language (facts:with)
* transactions using rollback functions
* logging and replay of transactions to/from disk
* dumping and loading the database to/from disk
---
Requirements
------------
You will need :
* https://git.kmx.io/facts-db/cl-compare
* https://git.kmx.io/facts-db/cl-rollback
---
Usage
-----
### FACTS:ADD &rest SPECS
Adds facts (triples) to the database. Triples can be grouped by subject.
```common-lisp
(facts:add ("Blade Runner" :is-a :movie
:director "Ridley Scott"
:actor "Harison Ford"
:actor "Rutger Hauer")
("Snow White" :is-a :movie
:director "William Cottrell"
:director "David Hand"))
```
or either
```common-lisp
(facts:add (?movie :is-a :movie
:title "Blade Runner"
:director "Ridley Scott"
:actor "Harrison Ford"
:actor "Rutger Hauer"))
(facts:add (?movie :is-a :movie
:title "Snow White and the Seven Dwarfs"
:director "William Cottrell"
:director "David Hand"))
(with ((?s ?p ?o))
(format t "~&~S ~S ~S~&" ?s ?p ?o))
=> NIL
FACTS.ANON::MOVIE-0000 :ACTOR "Harison Ford"
FACTS.ANON::MOVIE-0000 :ACTOR "Rutger Hauer"
FACTS.ANON::MOVIE-0000 :DIRECTOR "Ridley Scott"
FACTS.ANON::MOVIE-0000 :IS-A :MOVIE
FACTS.ANON::MOVIE-0000 :TITLE "Blade Runner"
FACTS.ANON::MOVIE-0001 :DIRECTOR "David Hand"
FACTS.ANON::MOVIE-0001 :DIRECTOR "William Cottrell"
FACTS.ANON::MOVIE-0001 :IS-A :MOVIE
FACTS.ANON::MOVIE-0001 :TITLE "Snow White"
```
The second version with `?movie` will generate an anonymous symbol prefixed with `movie-`.
It is considered a more clean and efficient way to abstract identifiers.
---
### FACTS:RM &rest SPECS
```common-lisp
(facts:rm (?movie :actor "Harison Ford"))
```
---
### FACTS:WITH SPECS &body BODY
To follow Wittgenstein's view of the world, all queries get turned into
testing the presence or absence of triples (facts).
Variables are prefixed with a question mark symbol "?" and are
wildcards, matching everything. Nested queries get their variables
expanded, giving pattern matching abilities. For instance :
```common-lisp
(with ((?s ?p ?o)
(format t "~&~S ~S ~S~&" ?s ?p ?o))
=>
"Blade Runner" :ACTOR "Harison Ford"
"Blade Runner" :ACTOR "Rutger Hauer"
"Blade Runner" :DIRECTOR "Ridley Scott"
"Blade Runner" :IS-A :MOVIE
"Snow White" :DIRECTOR "David Hand"
"Snow White" :DIRECTOR "William Cottrell"
"Snow White" :IS-A :MOVIE
```
Multiple queries on the same subject can be grouped together easily :
```common-lisp
(facts:with ((?movie :is-a :movie
:title ?title
:director ?director))
(format t "~A directed ~A~%" ?director ?title))
=>
Ridley Scott directed Blade Runner
David Hand directed Snow White and the Seven Dwarfs
William Cottrell directed Snow White and the Seven Dwarfs
```
Negative facts specifications will remove matching facts from the
results.
```common-lisp
(with ((?s ?p ?o)
(:not ?s :actor "Harison Ford"))
(format t "~&~S ~S ~S~&" ?s ?p ?o))
=>
"Snow White" :DIRECTOR "David Hand"
"Snow White" :DIRECTOR "William Cottrell"
"Snow White" :IS-A :MOVIE
```
---
### FACTS:\*DB\*
The current facts database.
---
### FACTS:CLEAR-DB
Clears the database from every facts.
---
### FACTS:SAVE-DB &key INTO (READABLY T)
Dump the database facts into filespec INTO.
---
### FACTS:LOAD-DB SRC
Load the facts from SRC into \*db\*.
---
### FACTS:WITH-TRANSACTION &body BODY
Enclose BODY database operations into a transaction.
A transaction ensures that all database operations will succeed or be
reverted using their respective rollback functions.
Transactions can be nested safely.
---
TODO
----
- binding of negation : :not resulting from another binding
- barriers / hooks : functions that will be called when a spec is added
or removed.