get logical with datalog
play

Get Logical with Datalog Stuart Halloway Datomic Team, - PowerPoint PPT Presentation

Get Logical with Datalog Stuart Halloway Datomic Team, Clojure/core, Relevance 1 https://github.com/clojure/core.logic https://github.com/nathanmarz/cascalog http://datomic.com/ 2 Roadmap How Why Bonus Round problem /


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

  2. https://github.com/clojure/core.logic https://github.com/nathanmarz/cascalog http://datomic.com/ 2

  3. Roadmap • How • Why • Bonus Round • problem / solution form 3

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

  5. Query Anatomy constraints q([:find ... :in ... :where ...], input1, ... inputN); 5

  6. Query Anatomy q([:find ... :in ... :where ...], input1, ... inputs inputN); 6

  7. Query Anatomy q([:find ... names for :in ... inputs :where ...], input1, ... inputN); 7

  8. Query Anatomy q([:find ... :in ... variables to return :where ...], input1, ... inputN); 8

  9. Variables ?customer ?product ?orderId ?email 9

  10. Constants :email 42 “john” :order/id #inst "2012-02-29" 10

  11. Keywords :email 42 “john” :order/id #inst "2012-02-29" 11

  12. Namespaces :email 42 “john” :order/id #inst "2012-02-29" 12

  13. Extensible Reader :email 42 “john” :order/id #inst "2012-02-29" 13

  14. Example Database entity attribute value 42 :email jdoe@example.com 43 :email jane@example.com 42 :orders 107 42 :orders 141 14

  15. Data Pattern Constrains the results returned, binds variables [?customer :email ?email] 15

  16. Data Pattern Constrains the results returned, binds variables [?customer :email ?email] value entity attribute 16

  17. Data Pattern Constrains the results returned, binds variables constant [?customer :email ?email] 17

  18. Data Pattern Constrains the results returned, binds variables variable variable [?customer :email ?email] 18

  19. entity attribute value 42 :email jdoe@example.com 43 :email jane@example.com 42 :orders 107 42 :orders 141 [?customer :email ?email] 19

  20. Constants Anywhere “Find a particular customer’s email” [ 42 :email ?email] 20

  21. entity attribute value 42 :email jdoe@example.com 43 :email jane@example.com 42 :orders 107 42 :orders 141 [ 42 :email ?email] 21

  22. Variables Anywhere “What attributes does customer 42 have? [42 ?attribute ] 22

  23. entity attribute value 42 :email jdoe@example.com 43 :email jane@example.com 42 :orders 107 42 :orders 141 [42 ?attribute ] 23

  24. Variables Anywhere “What attributes and values does customer 42 have? [42 ?attribute ?value ] 24

  25. entity attribute value 42 :email jdoe@example.com 43 :email jane@example.com 42 :orders 107 42 :orders 141 [42 ?attribute ?value] 25

  26. Where Clause data pattern [:find ?customer :where [?customer :email] ] 26

  27. Find Clause variable to return [:find ?customer :where [?customer :email]] 27

  28. Implicit Join “Find all the customers who have placed orders.” [:find ?customer :where [ ?customer :email] [ ?customer :orders]] 28

  29. API import static datomic.Peer.q; q("[:find ?customer :where [?customer :id] [?customer :orders]]", db); 29

  30. q import static datomic.Peer.q ; q ("[:find ?customer :where [?customer :id] [?customer :orders]]", db); 30

  31. Query import static datomic.Peer.q; q(" [:find ?customer :where [?customer :id] [?customer :orders]] ", db); 31

  32. Input(s) import static datomic.Peer.q; q("[:find ?customer :where [?customer :id] [?customer :orders]]", db ); 32

  33. In Clause Names inputs so you can refer to them elsewhere in the query :in $database ?email 33

  34. Parameterized Query “Find a customer by email.” q([:find ?customer :in $database ?email :where [$database ?customer :email ?email]], db, "jdoe@example.com"); 34

  35. First Input “Find a customer by email.” q([:find ?customer :in $database ?email :where [ $database ?customer :email ?email]], db , "jdoe@example.com"); 35

  36. Second Input “Find a customer by email.” q([:find ?customer :in $database ?email :where [$database ?customer :email ?email ]], db, "jdoe@example.com" ); 36

  37. Verbose? “Find a customer by email.” q([:find ?customer :in $database ?email :where [ $database ?customer :email ?email]], db , "jdoe@example.com"); 37

  38. Shortest Name Possible “Find a customer by email.” q([:find ?customer :in $ ?email :where [ $ ?customer :email ?email]], db , "jdoe@example.com"); 38

  39. Elide $ in Where “Find a customer by email.” q([:find ?customer :in $ ?email :where [ ?customer :email ?email]], db, "jdoe@example.com"); no need to specify $ 39

  40. Predicates Functional constraints that can appear in a :where clause [(< 50 ?price)] 40

  41. Adding a Predicate “Find the expensive items” [:find ?item :where [?item :item/price ?price] [ (< 50 ?price) ]] 41

  42. Functions Take bound variables as inputs and bind variables with output [(shipping ?zip ?weight) ?cost] 42

  43. Function Args [(shipping ?zip ?weight ) ?cost] bound inputs 43

  44. Function Returns [(shipping ?zip ?weight) ?cost ] bind return values 44

  45. Calling a Function “Find me the customer/product combinations where the shipping cost dominates the product cost.” [: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)]] 45

  46. Calling a Function “Find me the customer/product combinations where the shipping cost dominates the product cost.” navigate from customer to zip [: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)]] 46

  47. Calling a Function “Find me the customer/product combinations where the shipping cost dominates the product cost.” get product facts [:find ?customer ?product needed during query :where [?customer :shipAddress ?addr] [?addr :zip ?zip] [?product :product/weight ?weight] [?product :product/price ?price] [(Shipping/estimate ?zip ?weight) ?shipCost] [(<= ?price ?shipCost)]] 47

  48. Calling a Function “Find me the customer/product combinations where the shipping cost dominates the product cost.” call web service [:find ?customer ?product to bind shipCost :where [?customer :shipAddress ?addr] [?addr :zip ?zip] [?product :product/weight ?weight] [?product :product/price ?price] [(Shipping/estimate ?zip ?weight) ?shipCost] [(<= ?price ?shipCost)]] 48

  49. BYO Functions Functions can be plain JVM code. public class Shipping { public static BigDecimal estimate(String zip1, int pounds); } 49

  50. Calling a Function “Find me the customer/product combinations where the shipping cost dominates the product cost.” [: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) ]] constrain price 50

  51. Calling a Function “Find me the customer/product combinations where the shipping cost dominates the product cost.” return customer, product pairs [: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)]] 51

  52. Why 52

  53. Why Clojure? • Data • good literals • immutable data • extensible reader • Platform • extensibility • performance • Lisp 53

  54. 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

  55. Problem: Rectangles • join table • person table • club table “People can belong to • id key in person table multiple clubs” • person key in join table • club key in join table • id key in club table 55

  56. Structural Navigation Structural Rigidity 56

  57. CoC Taxonomy purpose assessment make an arbitrary choice often helpful default the common choice often helpful automate boilerplate dangerous 57

  58. Solution: Universal Relation “People can belong [?person :club ?club] to multiple clubs” 58

  59. Did You Ever Want To... • Make a column name variable? • Make a table name variable? • Treat metadata as first-class data? 59

  60. First-Class Attributes [?person ?attr ?value] attribute slot isn’t special 60

  61. Schema Made of Ordinary Data [?e :db/valueType ] find all attributes 61

  62. Problem: Ambient DB SELECT ID FROM CUSTOMERS; in what db? 62

  63. Solution: Explicit DB q("[:find ?customer :where [?customer :id] [?customer :orders]]", db); in this db! 63

  64. Benefit: Query Params q([:find ?customer :in $database ?email :where [$database ?customer :email ?email]], db, "jdoe@example.com"); parameterized query is not a separate feature 64

Recommend


More recommend