Guest User

Untitled

a guest
Jan 24th, 2018
59
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.63 KB | None | 0 0
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <title>Database.js</title>
  6. </head>
  7. <body>
  8. <script>
  9. 'use strict';
  10.  
  11. function isVar(x) {
  12. return typeof x === 'string' && x[0] === '$';
  13. }
  14.  
  15. const EMPTY_BINDING = {facts: []};
  16.  
  17. class Database {
  18. constructor(...facts) {
  19. this.facts = new Set(facts);
  20. }
  21.  
  22. assert(fact) {
  23. this.facts.add(fact);
  24. }
  25.  
  26. refute(fact) {
  27. this.facts.delete(fact);
  28. }
  29.  
  30. query(qs, callback, bindings = [EMPTY_BINDING]) {
  31. if (qs.length === 0) {
  32. bindings.forEach(b => {
  33. const assert = (fact) => {
  34. fact.provenance = b.facts;
  35. this.assert(fact);
  36. }
  37.  
  38. const refute = (fact) => this.refute(fact);
  39.  
  40. callback(b, assert, refute)
  41. });
  42. return;
  43. }
  44.  
  45. const newBindings = this.match(qs[0], this.facts, bindings);
  46. return this.query(qs.slice(1), callback, newBindings);
  47. }
  48.  
  49. match(q, facts, bindings) {
  50. let filtered = [];
  51.  
  52. for (let b of bindings) {
  53. for (let f of facts) {
  54. const newB = this.matchOne(q, f, b);
  55. if (newB) {
  56. filtered.push(newB);
  57. }
  58. }
  59. }
  60.  
  61. return filtered;
  62. }
  63.  
  64. matchOne(q, fact, binding) {
  65. if (q.length !== fact.length) {
  66. return null;
  67. }
  68.  
  69. let newB = {...binding, facts: [...binding.facts, fact]};
  70.  
  71. for (let i in q) {
  72. const qpart = q[i];
  73.  
  74. if (isVar(qpart) && newB.hasOwnProperty(qpart) && newB[qpart] !== fact[i]) {
  75. return null;
  76. } else if (isVar(qpart)) {
  77. newB[qpart] = fact[i];
  78. } else if (qpart !== fact[i]) {
  79. return null;
  80. }
  81. }
  82.  
  83. return newB;
  84. }
  85. }
  86.  
  87. let db = new Database(
  88. ['C1', 'is a', 'circle', 'at', '(', 300, ',', 300, ')'],
  89. ['C1', '\'s', 'color', 'is', 'blue'],
  90. ['C1', '\'s', 'radius', 'is', 50],
  91.  
  92. ['C2', 'is a', 'circle', 'at', '(', 200, ',', 500, ')'],
  93. ['C2', '\'s', 'color', 'is', 'red'],
  94. ['C2', '\'s', 'radius', 'is', 120],
  95. )
  96.  
  97. db.query([
  98. ['$name', 'is a', 'circle', 'at', '(', '$x', ',', '$y', ')'],
  99. ['$name', '\'s', 'radius', 'is', '$r'],
  100. ['$name', '\'s', 'color', 'is', 'red'],
  101. ], m => console.log(m));
  102.  
  103. db.query([
  104. ['$name', 'is a', 'circle', 'at', '(', '$x', ',', '$y', ')'],
  105. ['$name', '\'s', 'radius', 'is', '$r'],
  106. ], ({$name, $r}, assert, refute) => {
  107. console.log($name, $r);
  108. if ($r > 100) {
  109. assert([$name, 'is', 'large']);
  110. }
  111. })
  112. </script>
  113. </body>
  114. </html>
Add Comment
Please, Sign In to add comment