get logical with datalog - goto conference · 2012-05-24 · get logical with datalog stuart...

89
Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

Upload: others

Post on 06-Aug-2020

7 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

Get Logical with DatalogStuart Halloway

Datomic Team, Clojure/core, Relevance

1

Page 3: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

Roadmap

• How

• Why

• Bonus Round

• problem / solution form

3

Page 4: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

Query Anatomy

q([:find ... :in ... :where ...], input1, ... inputN);

4

Page 5: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

Query Anatomy

q([:find ... :in ... :where ...], input1, ... inputN);

constraints

5

Page 6: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

Query Anatomy

q([:find ... :in ... :where ...], input1, ... inputN);

inputs

6

Page 7: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

Query Anatomy

q([:find ... :in ... :where ...], input1, ... inputN);

names forinputs

7

Page 8: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

Query Anatomy

q([:find ... :in ... :where ...], input1, ... inputN);

variables toreturn

8

Page 9: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

Variables

?customer

?orderId

?product

?email

9

Page 10: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

Constants

42

“john”

:email

#inst "2012-02-29"

:order/id

10

Page 11: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

Keywords

42

“john”

:email

#inst "2012-02-29"

:order/id

11

Page 12: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

Namespaces

42

“john”

:email

#inst "2012-02-29"

:order/id

12

Page 13: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

Extensible Reader

42

“john”

:email

#inst "2012-02-29"

:order/id

13

Page 14: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

Example Database

entity attribute value

42 :email [email protected]

43 :email [email protected]

42 :orders 107

42 :orders 141

14

Page 15: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

[?customer :email ?email]

Constrains the results returned,binds variables

Data Pattern

15

Page 16: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

[?customer :email ?email]

Constrains the results returned,binds variables

Data Pattern

entity attribute value

16

Page 17: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

[?customer :email ?email]

Constrains the results returned,binds variables

Data Pattern

constant

17

Page 18: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

[?customer :email ?email]

Constrains the results returned,binds variables

Data Pattern

variable variable

18

Page 19: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

entity attribute value

42 :email [email protected]

43 :email [email protected]

42 :orders 107

42 :orders 141

[?customer :email ?email]

19

Page 20: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

[42 :email ?email]

“Find a particular customer’s email”

Constants Anywhere

20

Page 21: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

entity attribute value

42 :email [email protected]

43 :email [email protected]

42 :orders 107

42 :orders 141

[42 :email ?email]

21

Page 22: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

[42 ?attribute]

“What attributes does customer 42 have?

Variables Anywhere

22

Page 23: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

entity attribute value

42 :email [email protected]

43 :email [email protected]

42 :orders 107

42 :orders 141

[42 ?attribute]

23

Page 24: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

[42 ?attribute ?value]

“What attributes and values does customer 42 have?

Variables Anywhere

24

Page 25: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

entity attribute value

42 :email [email protected]

43 :email [email protected]

42 :orders 107

42 :orders 141

[42 ?attribute ?value]

25

Page 26: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

[:find ?customer :where [?customer :email]]

Where Clause

datapattern

26

Page 27: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

[:find ?customer :where [?customer :email]]

Find Clause

variable to return

27

Page 28: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

[:find ?customer :where [?customer :email] [?customer :orders]]

“Find all the customers who have placed orders.”

Implicit Join

28

Page 29: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

import static datomic.Peer.q;

q("[:find ?customer :where [?customer :id] [?customer :orders]]", db);

API

29

Page 30: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

import static datomic.Peer.q;

q("[:find ?customer :where [?customer :id] [?customer :orders]]", db);

q

30

Page 31: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

import static datomic.Peer.q;

q("[:find ?customer :where [?customer :id] [?customer :orders]]", db);

Query

31

Page 32: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

import static datomic.Peer.q;

q("[:find ?customer :where [?customer :id] [?customer :orders]]", db);

Input(s)

32

Page 33: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

:in $database ?email

In Clause

Names inputs so you can refer to themelsewhere in the query

33

Page 34: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

“Find a customer by email.”

Parameterized Query

q([:find ?customer :in $database ?email :where [$database ?customer :email ?email]], db, "[email protected]");

34

Page 35: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

“Find a customer by email.”

First Input

q([:find ?customer :in $database ?email :where [$database ?customer :email ?email]], db, "[email protected]");

35

Page 36: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

“Find a customer by email.”

Second Input

q([:find ?customer :in $database ?email :where [$database ?customer :email ?email]], db, "[email protected]");

36

Page 37: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

“Find a customer by email.”

Verbose?

q([:find ?customer :in $database ?email :where [$database ?customer :email ?email]], db, "[email protected]");

37

Page 38: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

“Find a customer by email.”

Shortest Name Possible

q([:find ?customer :in $ ?email :where [$ ?customer :email ?email]], db, "[email protected]");

38

Page 39: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

“Find a customer by email.”

Elide $ in Where

q([:find ?customer :in $ ?email :where [ ?customer :email ?email]], db, "[email protected]");

no need to specify $

39

Page 40: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

[(< 50 ?price)]

Predicates

Functional constraints that can appear in a :where clause

40

Page 41: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

[:find ?item :where [?item :item/price ?price] [(< 50 ?price)]]

“Find the expensive items”

Adding a Predicate

41

Page 42: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

[(shipping ?zip ?weight) ?cost]

Take bound variables as inputs and bind variables with output

Functions

42

Page 43: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

[(shipping ?zip ?weight) ?cost]

Function Args

bound inputs

43

Page 44: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

[(shipping ?zip ?weight) ?cost]

Function Returns

bind returnvalues

44

Page 45: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

[:find ?customer ?product :where [?customer :shipAddress ?addr] [?addr :zip ?zip] [?product :product/weight ?weight] [?product :product/price ?price] [(Shipping/estimate ?zip ?weight) ?shipCost] [(<= ?price ?shipCost)]]

“Find me the customer/product combinations where the shipping cost

dominates the product cost.”

Calling a Function

45

Page 46: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

[:find ?customer ?product :where [?customer :shipAddress ?addr] [?addr :zip ?zip] [?product :product/weight ?weight] [?product :product/price ?price] [(Shipping/estimate ?zip ?weight) ?shipCost] [(<= ?price ?shipCost)]]

“Find me the customer/product combinations where the shipping cost

dominates the product cost.”

Calling a Function

navigate fromcustomer to zip

46

Page 47: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

[:find ?customer ?product :where [?customer :shipAddress ?addr] [?addr :zip ?zip] [?product :product/weight ?weight] [?product :product/price ?price] [(Shipping/estimate ?zip ?weight) ?shipCost] [(<= ?price ?shipCost)]]

“Find me the customer/product combinations where the shipping cost

dominates the product cost.”

Calling a Function

get product factsneeded during query

47

Page 48: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

[:find ?customer ?product :where [?customer :shipAddress ?addr] [?addr :zip ?zip] [?product :product/weight ?weight] [?product :product/price ?price] [(Shipping/estimate ?zip ?weight) ?shipCost] [(<= ?price ?shipCost)]]

“Find me the customer/product combinations where the shipping cost

dominates the product cost.”

Calling a Function

call web serviceto bind shipCost

48

Page 49: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

public class Shipping { public static BigDecimal estimate(String zip1, int pounds);}

Functions can be plain JVM code.

BYO Functions

49

Page 50: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

[:find ?customer ?product :where [?customer :shipAddress ?addr] [?addr :zip ?zip] [?product :product/weight ?weight] [?product :product/price ?price] [(Shipping/estimate ?zip ?weight) ?shipCost] [(<= ?price ?shipCost)]]

“Find me the customer/product combinations where the shipping cost

dominates the product cost.”

Calling a Function

constrain price

50

Page 51: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

[:find ?customer ?product :where [?customer :shipAddress ?addr] [?addr :zip ?zip] [?product :product/weight ?weight] [?product :product/price ?price] [(Shipping/estimate ?zip ?weight) ?shipCost] [(<= ?price ?shipCost)]]

“Find me the customer/product combinations where the shipping cost

dominates the product cost.”

Calling a Function

return customer,product pairs

51

Page 52: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

Why

52

Page 53: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

Why Clojure?

• Data

• good literals

• immutable data

• extensible reader

• Platform

• extensibility

• performance

• Lisp

53

Page 54: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

Why Datalog?

• Equivalent to Relational Model + Recursion

• Better fit than Prolog for query

• No clause order dependency

• Guaranteed termination

• Pattern-matching style easy to learn

54

Page 55: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

Problem: Rectangles

• join table

• person table

• club table

• id key in person table

• person key in join table

• club key in join table

• id key in club table

“People can belong tomultiple clubs”

55

Page 56: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

Structural Navigation

Structural Rigidity

56

Page 57: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

CoC Taxonomy

purpose assessment

make an arbitrary choice often helpful

default the common choice often helpful

automate boilerplate dangerous

57

Page 58: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

Solution: Universal Relation

“People can belong to multiple clubs”

[?person :club ?club]

58

Page 59: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

Did You Ever Want To...

• Make a column name variable?

• Make a table name variable?

• Treat metadata as first-class data?

59

Page 60: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

[?person ?attr ?value]

First-Class Attributes

attribute slot isn’t special

60

Page 61: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

[?e :db/valueType]

Schema Made of Ordinary Data

find allattributes

61

Page 62: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

SELECT ID FROM CUSTOMERS;

Problem: Ambient DB

in what db?

62

Page 63: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

q("[:find ?customer :where [?customer :id] [?customer :orders]]", db);

Solution: Explicit DB

in this db!

63

Page 64: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

q([:find ?customer :in $database ?email :where [$database ?customer :email ?email]], db, "[email protected]");

Benefit: Query Params

parameterized queryis not a separate feature

64

Page 65: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

(q '[:find ?k :in [[?k]]] (System/getProperties))

What system properties are available?

Benefit: BYO Data

65

Page 66: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

(q '[:find ?k :in [[?k]]] (System/getProperties))

What system properties are available?

Benefit: BYO Data

bind first element ofeach tuple in a relation

66

Page 67: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

Binding Patterns

Pattern Binds Example Input

Binds ?a To

?a scalar 42 42

[?a ?b] tuple [1 2] 1

[?a ...] collection [1 2] 1, 2

[[?a ?b ?c]] relation john likes pizzajane likes pasta john, jane

67

Page 68: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

(q '[:find ?v :in [[?k ?v]] :where [(.endsWith ?k "path")]] (System/getProperties))

Which system properties are path-related?

BYO Data

68

Page 69: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

(q '[:find ?pathElem :in [[?k ?v]] :where [(.endsWith ?k "path")] [(.split ?v ":") [?pathElem ...]]] (System/getProperties))

What path elements are mentioned insystem properties?

BYO Data

69

Page 70: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

(q '[:find ?pathElem :in [[?k ?v]] :where [(.endsWith ?k "path")] [(.split ?v ":") [?pathElem ...]] [(.endsWith ?pathElem ".jar")]] (System/getProperties))

What JAR files are in my systemproperty paths?

BYO Data

70

Page 71: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

q("[:find ?customer :where [?customer :id] [?customer :orders]]", db.asOf(lastMonth));

Benefit: Time Travel

71

Page 72: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

[:find ?customer ?email :in $cust $emp :where [$cust ?customer :email ?email] [$emp _ :email ?email]]

“Find me the customers who are also employees.”

Benefit: Join Across DBs

q(query, custDb, empDb);

implicit join

72

Page 73: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

[:find ?customer ?email :in $cust $emp :where [$cust ?customer :email ?email] [$emp _ :email ?email]]

“Find me the customers who are also employees.”

Benefit: Join Across DBs

q(query, custDb, empDb);

data patterns can be led by database names

73

Page 74: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

Problem: Better Views

• Good

• abstraction

• relational

• Bad

• over there

• rectangular

• tool/language choices

74

Page 75: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

[(relatedProduct ?p1 ?p2) [?p1 :category ?c] [?p2 :category ?c] [(!= ?p1 ?p2)]]

“Products are related if theyhave a common category.”

Solution: Rules

75

Page 76: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

[(relatedProduct ?p1 ?p2) [?p1 :category ?c] [?p2 :category ?c] [(!= ?p1 ?p2)]]

“Products are related if theyhave a common category.”

Rule Head

this is true...

76

Page 77: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

[(relatedProduct ?p1 ?p2) [?p1 :category ?c] [?p2 :category ?c] [(!= ?p1 ?p2)]]

“Products are related if theyhave a common category.”

Rule Body

...if all these are true

77

Page 78: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

q("[:find ?p2 :in $ % :where (expensiveChocolate p1) (relatedProduct p1 p2)", db, rules)

“Find all products related toexpensive chocolate.”

Using Rules

rules are a kind of input

78

Page 79: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

q("[:find ?p2 :in $ % :where (expensiveChocolate p1) (relatedProduct p1 p2)", db, rules)

“Find all products related toexpensive chocolate.”

Using Rules

rule names beginwith %

79

Page 80: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

q("[:find ?p2 :in $ % :where (expensiveChocolate p1) (relatedProduct p1 p2)", db, rules)

“Find all products related toexpensive chocolate.”

Using Rules

rule patterns can appear in :where clause

80

Page 81: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

[[(relatedProduct ?p1 ?p2) [?p1 :category ?c] [?p2 :category ?c] [(!= ?p1 ?p2)]] [(relatedProduct ?p1 ?p2) [?o :order/item ?item1] [?item1 :order/product ?p1] [?o :order/item ?item2] [?item2 :order/product ?p2] [(!= ?p1 ?p2)]]]

“Products are related if they have the same category, or they have appeared in the same order.”

Implicit Or

81

Page 82: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

Problem: Extent

Line Item 1

Order

Line Item 2

Product A

Product B

Customer

Get “the whole order”.

82

Page 83: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

Problem: Extent

Get “the whole order”.

Line Item 1

Order

Line Item 2

Product A

Product B

Customer

83

Page 84: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

[(extent ?x ?e ?a ?v) (?e ?a ?v) (?x ?a ?v) [(= ?e ?x)]]

Find Values :x References

Line Item 1

Order

Line Item 2

Product A

Product B

Customer

84

Page 85: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

[(extent ?x ?e ?a ?v) (?e ?a ?v) (?e ?a ?x) [(= ?v ?x)]]

Finds Entities Referencing :x

Line Item 1

Order

Line Item 2

Product A

Product B

Customer

matches ref from customer, not customer itself

85

Page 86: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

[(extent ?x ?e ?a ?v) (components ?x ?y) (extent ?y ?e ?a ?v)][(components ?p ?c) (?a :db/isComponent) (?p ?a ?c)]

Recurse Component Attributes

Line Item 1

Order

Line Item 2

Product A

Product B

Customer

86

Page 87: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

[(extent ?x ?e ?a ?v) (components ?x ?y) (extent ?y ?e ?a ?v)][(components ?p ?c) (?a :db/isComponent) (?p ?a ?c)]

Recurse Component Attributes

Line Item 1

Order

Line Item 2

Product A

Product B

Customer

recursive definition

87

Page 88: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

[(extent ?x ?e ?a ?v) (components ?x ?y) (extent ?y ?e ?a ?v)][(components ?p ?c) (?a :db/isComponent) (?p ?a ?c)]

Recurse Component Attributes

Line Item 1

Order

Line Item 2

Product A

Product B

Customer

only recurse attributesmarked :db/isComponent

88

Page 89: Get Logical with Datalog - GOTO Conference · 2012-05-24 · Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1

Stuart Halloway

datomic.com@datomic_team@stuarthalloway

89