Last active 1735235784

capitalex's Avatar capitalex revised this gist 1735235783. Go to revision

2 files changed, 752 insertions

fruitcake.chr(file created)

@@ -0,0 +1,16 @@
1 + kitchen("flour"), kitchen("sugar"), kitchen("sugar"), kitchen("apples")
2 + <=> kitchen("apple cake")
3 +
4 + kitchen("apples"), kitchen("oranges"), kitchen("cherries")
5 + <=> kitchen("fruit salad")
6 +
7 + kitchen("fruit salad"), kitchen("apple cake")
8 + <=> kitchen("fruit cake")
9 +
10 + start <=>
11 + kitchen("sugar"),
12 + kitchen("oranges"),
13 + kitchen("apples"),
14 + kitchen("cherries"),
15 + kitchen("flour"),
16 + kitchen("apples")

fruitcake.js(file created)

@@ -0,0 +1,736 @@
1 + /**
2 + *
3 + * Automatically generated
4 + * Do not edit
5 + *
6 + * Created using CHR.js AOT compiler
7 + * (CHR.js version v3.3.21)
8 + * http://github.com/fnogatz/CHR.js
9 + *
10 + */
11 +
12 + module.exports = (function () {
13 +
14 + /* eslint no-labels: ["error", { "allowLoop": true }] */
15 +
16 + // Constraint
17 + function Constraint (name, arity, args) {
18 + this.name = name
19 + this.arity = arity
20 + this.functor = name + '/' + arity
21 + this.args = args
22 + this.id = null
23 + this.alive = true
24 + this.activated = false
25 + this.stored = false
26 + this.hist = null
27 + this.cont = null
28 + }
29 +
30 + Constraint.prototype.continue = function () {
31 + this.cont[0].call(this, this, this.cont[1])
32 + }
33 +
34 + Constraint.prototype.toString = function () {
35 + let s = this.name
36 + if (this.arity >= 1) {
37 + s += '(' + this.args.join(',') + ')'
38 + }
39 + return s
40 + }
41 +
42 + // Store
43 + function Store () {
44 + this._index = {}
45 + this._size = 0
46 + this._nextId = 0
47 + }
48 +
49 + Store.prototype.add = function (constraint) {
50 + if (typeof this._index[constraint.functor] === 'undefined') {
51 + this._index[constraint.functor] = []
52 + }
53 + constraint.id = this._nextId
54 + this._index[constraint.functor].push(constraint)
55 + this._size += 1
56 + this._nextId += 1
57 + }
58 +
59 + Store.prototype.remove = function (constraint) {
60 + constraint.alive = false
61 + const ix = this._index[constraint.functor].indexOf(constraint)
62 + this._index[constraint.functor].splice(ix, 1)
63 +
64 + this._size -= 1
65 + }
66 +
67 + Store.prototype.lookup = function (rule, patterns, constraint) {
68 + const ret = this.lookupResume(rule, patterns, constraint, 0)
69 + if (!ret || !ret.res) {
70 + return false
71 + }
72 + return ret.res
73 + }
74 +
75 + Store.prototype.lookupResume = function (rule, patterns, constraint, startFrom) {
76 + startFrom = startFrom || 0
77 +
78 + const lastPattern = patterns.length - 1
79 + const lengths = []
80 + const divs = []
81 + let div = 1
82 + let i
83 +
84 + // build array of arrays
85 + const arr = []
86 + for (i = 0; i <= lastPattern; i++) {
87 + if (patterns[i] === '_') {
88 + // "_" is a placeholder for the given `constraint`
89 + arr[i] = [constraint]
90 + } else if (typeof this._index[patterns[i]] !== 'undefined') {
91 + arr[i] = this._index[patterns[i]]
92 + } else {
93 + // not a single element for this functor
94 + return false
95 + }
96 + }
97 +
98 + for (i = lastPattern; i >= 0; i--) {
99 + lengths[i] = arr[i].length
100 + divs[i] = div
101 + div *= arr[i].length
102 + }
103 + const max = divs[0] * arr[0].length
104 +
105 + let res
106 + let resIds
107 + let curr
108 + loopng: for (let n = startFrom; n < max; n++) {
109 + res = []
110 + resIds = []
111 + curr = n
112 + for (i = 0; i <= lastPattern; i++) {
113 + res[i] = arr[i][curr / divs[i] >> 0]
114 + resIds[i] = res[i].id
115 +
116 + // avoid multiple occurences of the same constraint
117 + if (res.slice(0, i).indexOf(res[i]) !== -1) {
118 + continue loopng
119 + }
120 +
121 + curr = curr % divs[i]
122 + }
123 +
124 + // check if already in history
125 + /*
126 + if (history.lookup(rule, resIds)) {
127 + continue loopng
128 + }
129 + */
130 + return {
131 + n: n,
132 + res: res
133 + }
134 + }
135 +
136 + return false
137 + }
138 +
139 + Store.prototype.size = function () {
140 + return this._size
141 + }
142 +
143 + Store.prototype.valueOf = function () {
144 + return this.size()
145 + }
146 +
147 + Store.prototype.toString = function () {
148 + if (this.size() === 0) {
149 + return '(empty)'
150 + }
151 +
152 + let maxLengthC = 'constraint'.length
153 + let maxLengthI = 'id'.length
154 + const rows = []
155 + let functor
156 + for (functor in this._index) {
157 + this._index[functor].forEach(function (c) {
158 + const s = c.toString()
159 + maxLengthC = Math.max(s.length, maxLengthC)
160 + maxLengthI = Math.max(c.id.toString().length + 1, maxLengthI)
161 + })
162 + }
163 + for (functor in this._index) {
164 + this._index[functor].forEach(function (c) {
165 + rows.push(c.id.toString().padStart(maxLengthI) + ' | ' + c.toString().padEnd(maxLengthC))
166 + })
167 + }
168 +
169 + return [
170 + 'id'.padStart(maxLengthI) + ' | ' + 'constraint'.padEnd(maxLengthC),
171 + ''.padStart(maxLengthI, '-') + '-+-' + ''.padEnd(maxLengthC, '-')
172 + ].concat(rows).join('\n')
173 + }
174 +
175 + // History
176 + /*
177 + function History () {
178 + this._index = {}
179 + this._size = 0
180 + }
181 +
182 + History.prototype.size = function () {
183 + return this._size
184 + }
185 +
186 + History.prototype.valueOf = function () {
187 + return this.size()
188 + }
189 +
190 + History.prototype.toString = function () {
191 + if (this.size() === 0) {
192 + return "(empty)"
193 + }
194 +
195 + var maxLength_r = "rule".length
196 + var maxLength_f = "fired with".length
197 + var rows = []
198 + var curr
199 + for (var rule in this._index) {
200 + maxLength_r = Math.max(rule.toString().length, maxLength_r)
201 + }
202 +
203 + // TODO
204 + }
205 +
206 + History.prototype.add = function (rule, ids) {
207 + if (!this._index.hasOwnProperty(rule)) {
208 + this._index[rule] = {}
209 + }
210 +
211 + var curr = this._index[rule]
212 + for (var i = 0; i < ids.length-1; i++) {
213 + if (!curr.hasOwnProperty(ids[i])) {
214 + curr[ids[i]] = {}
215 + }
216 + curr = curr[ids[i]]
217 + }
218 + curr[ids[i]] = true
219 +
220 + this._size += 1
221 + }
222 +
223 + History.prototype.lookup = function (rule, ids) {
224 + if (!this._index.hasOwnProperty(rule)) {
225 + return false
226 + }
227 +
228 + var curr = this._index[rule]
229 + for (var i = 0; i < ids.length; i++) {
230 + if (!curr[ids[i]]) {
231 + return false
232 + }
233 + curr = curr[ids[i]]
234 + }
235 +
236 + if (curr !== true) {
237 + return false
238 + }
239 +
240 + return true
241 + }
242 + */
243 + // trampoline
244 + function trampoline () { // eslint-disable-line
245 + let constraint
246 + while (constraint = stack.pop()) { // eslint-disable-line
247 + constraint.continue()
248 + }
249 + }
250 +
251 + var chr = { // eslint-disable-line
252 + Store: new Store()
253 + }
254 +
255 + var stack = [] // eslint-disable-line
256 + // var history = new History()
257 +
258 + function __kitchen_1_0 (constraint, __n) {
259 + __n = __n || 0
260 +
261 + if (constraint.args[0] !== "apples") {
262 + constraint.cont = [__kitchen_1_1, 0]
263 + stack.push(constraint)
264 + return
265 + }
266 +
267 + var constraintPattern = [ "kitchen/1", "kitchen/1", "kitchen/1", "_" ]
268 + var lookupResult = chr.Store.lookupResume(0, constraintPattern, constraint, __n)
269 + if (lookupResult === false) {
270 + constraint.cont = [__kitchen_1_1, 0]
271 + stack.push(constraint)
272 + return
273 + }
274 + var constraints = lookupResult.res
275 +
276 + if (constraints[0].args[0] !== "flour") {
277 + constraint.cont = [__kitchen_1_0, __n + 1]
278 + stack.push(constraint)
279 + return
280 + }
281 +
282 + if (constraints[1].args[0] !== "sugar") {
283 + constraint.cont = [__kitchen_1_0, __n + 1]
284 + stack.push(constraint)
285 + return
286 + }
287 +
288 + if (constraints[2].args[0] !== "sugar") {
289 + constraint.cont = [__kitchen_1_0, __n + 1]
290 + stack.push(constraint)
291 + return
292 + }
293 +
294 + chr.Store.remove(constraints[0])
295 + chr.Store.remove(constraints[1])
296 + chr.Store.remove(constraints[2])
297 +
298 + ;(function () {
299 + var _c = new Constraint("kitchen", 1, [ "apple cake" ])
300 + _c.cont = [__kitchen_1_0, 0]
301 + stack.push(_c)
302 + })()
303 +
304 + // active constraint gets removed
305 + }
306 +
307 + function __kitchen_1_1 (constraint, __n) {
308 + __n = __n || 0
309 +
310 + if (constraint.args[0] !== "sugar") {
311 + constraint.cont = [__kitchen_1_2, 0]
312 + stack.push(constraint)
313 + return
314 + }
315 +
316 + var constraintPattern = [ "kitchen/1", "kitchen/1", "_", "kitchen/1" ]
317 + var lookupResult = chr.Store.lookupResume(0, constraintPattern, constraint, __n)
318 + if (lookupResult === false) {
319 + constraint.cont = [__kitchen_1_2, 0]
320 + stack.push(constraint)
321 + return
322 + }
323 + var constraints = lookupResult.res
324 +
325 + if (constraints[0].args[0] !== "flour") {
326 + constraint.cont = [__kitchen_1_1, __n + 1]
327 + stack.push(constraint)
328 + return
329 + }
330 +
331 + if (constraints[1].args[0] !== "sugar") {
332 + constraint.cont = [__kitchen_1_1, __n + 1]
333 + stack.push(constraint)
334 + return
335 + }
336 +
337 + if (constraints[3].args[0] !== "apples") {
338 + constraint.cont = [__kitchen_1_1, __n + 1]
339 + stack.push(constraint)
340 + return
341 + }
342 +
343 + chr.Store.remove(constraints[0])
344 + chr.Store.remove(constraints[1])
345 + chr.Store.remove(constraints[3])
346 +
347 + ;(function () {
348 + var _c = new Constraint("kitchen", 1, [ "apple cake" ])
349 + _c.cont = [__kitchen_1_0, 0]
350 + stack.push(_c)
351 + })()
352 +
353 + // active constraint gets removed
354 + }
355 +
356 + function __kitchen_1_2 (constraint, __n) {
357 + __n = __n || 0
358 +
359 + if (constraint.args[0] !== "sugar") {
360 + constraint.cont = [__kitchen_1_3, 0]
361 + stack.push(constraint)
362 + return
363 + }
364 +
365 + var constraintPattern = [ "kitchen/1", "_", "kitchen/1", "kitchen/1" ]
366 + var lookupResult = chr.Store.lookupResume(0, constraintPattern, constraint, __n)
367 + if (lookupResult === false) {
368 + constraint.cont = [__kitchen_1_3, 0]
369 + stack.push(constraint)
370 + return
371 + }
372 + var constraints = lookupResult.res
373 +
374 + if (constraints[0].args[0] !== "flour") {
375 + constraint.cont = [__kitchen_1_2, __n + 1]
376 + stack.push(constraint)
377 + return
378 + }
379 +
380 + if (constraints[2].args[0] !== "sugar") {
381 + constraint.cont = [__kitchen_1_2, __n + 1]
382 + stack.push(constraint)
383 + return
384 + }
385 +
386 + if (constraints[3].args[0] !== "apples") {
387 + constraint.cont = [__kitchen_1_2, __n + 1]
388 + stack.push(constraint)
389 + return
390 + }
391 +
392 + chr.Store.remove(constraints[0])
393 + chr.Store.remove(constraints[2])
394 + chr.Store.remove(constraints[3])
395 +
396 + ;(function () {
397 + var _c = new Constraint("kitchen", 1, [ "apple cake" ])
398 + _c.cont = [__kitchen_1_0, 0]
399 + stack.push(_c)
400 + })()
401 +
402 + // active constraint gets removed
403 + }
404 +
405 + function __kitchen_1_3 (constraint, __n) {
406 + __n = __n || 0
407 +
408 + if (constraint.args[0] !== "flour") {
409 + constraint.cont = [__kitchen_1_4, 0]
410 + stack.push(constraint)
411 + return
412 + }
413 +
414 + var constraintPattern = [ "_", "kitchen/1", "kitchen/1", "kitchen/1" ]
415 + var lookupResult = chr.Store.lookupResume(0, constraintPattern, constraint, __n)
416 + if (lookupResult === false) {
417 + constraint.cont = [__kitchen_1_4, 0]
418 + stack.push(constraint)
419 + return
420 + }
421 + var constraints = lookupResult.res
422 +
423 + if (constraints[1].args[0] !== "sugar") {
424 + constraint.cont = [__kitchen_1_3, __n + 1]
425 + stack.push(constraint)
426 + return
427 + }
428 +
429 + if (constraints[2].args[0] !== "sugar") {
430 + constraint.cont = [__kitchen_1_3, __n + 1]
431 + stack.push(constraint)
432 + return
433 + }
434 +
435 + if (constraints[3].args[0] !== "apples") {
436 + constraint.cont = [__kitchen_1_3, __n + 1]
437 + stack.push(constraint)
438 + return
439 + }
440 +
441 + chr.Store.remove(constraints[1])
442 + chr.Store.remove(constraints[2])
443 + chr.Store.remove(constraints[3])
444 +
445 + ;(function () {
446 + var _c = new Constraint("kitchen", 1, [ "apple cake" ])
447 + _c.cont = [__kitchen_1_0, 0]
448 + stack.push(_c)
449 + })()
450 +
451 + // active constraint gets removed
452 + }
453 +
454 + function __kitchen_1_4 (constraint, __n) {
455 + __n = __n || 0
456 +
457 + if (constraint.args[0] !== "cherries") {
458 + constraint.cont = [__kitchen_1_5, 0]
459 + stack.push(constraint)
460 + return
461 + }
462 +
463 + var constraintPattern = [ "kitchen/1", "kitchen/1", "_" ]
464 + var lookupResult = chr.Store.lookupResume(1, constraintPattern, constraint, __n)
465 + if (lookupResult === false) {
466 + constraint.cont = [__kitchen_1_5, 0]
467 + stack.push(constraint)
468 + return
469 + }
470 + var constraints = lookupResult.res
471 +
472 + if (constraints[0].args[0] !== "apples") {
473 + constraint.cont = [__kitchen_1_4, __n + 1]
474 + stack.push(constraint)
475 + return
476 + }
477 +
478 + if (constraints[1].args[0] !== "oranges") {
479 + constraint.cont = [__kitchen_1_4, __n + 1]
480 + stack.push(constraint)
481 + return
482 + }
483 +
484 + chr.Store.remove(constraints[0])
485 + chr.Store.remove(constraints[1])
486 +
487 + ;(function () {
488 + var _c = new Constraint("kitchen", 1, [ "fruit salad" ])
489 + _c.cont = [__kitchen_1_0, 0]
490 + stack.push(_c)
491 + })()
492 +
493 + // active constraint gets removed
494 + }
495 +
496 + function __kitchen_1_5 (constraint, __n) {
497 + __n = __n || 0
498 +
499 + if (constraint.args[0] !== "oranges") {
500 + constraint.cont = [__kitchen_1_6, 0]
501 + stack.push(constraint)
502 + return
503 + }
504 +
505 + var constraintPattern = [ "kitchen/1", "_", "kitchen/1" ]
506 + var lookupResult = chr.Store.lookupResume(1, constraintPattern, constraint, __n)
507 + if (lookupResult === false) {
508 + constraint.cont = [__kitchen_1_6, 0]
509 + stack.push(constraint)
510 + return
511 + }
512 + var constraints = lookupResult.res
513 +
514 + if (constraints[0].args[0] !== "apples") {
515 + constraint.cont = [__kitchen_1_5, __n + 1]
516 + stack.push(constraint)
517 + return
518 + }
519 +
520 + if (constraints[2].args[0] !== "cherries") {
521 + constraint.cont = [__kitchen_1_5, __n + 1]
522 + stack.push(constraint)
523 + return
524 + }
525 +
526 + chr.Store.remove(constraints[0])
527 + chr.Store.remove(constraints[2])
528 +
529 + ;(function () {
530 + var _c = new Constraint("kitchen", 1, [ "fruit salad" ])
531 + _c.cont = [__kitchen_1_0, 0]
532 + stack.push(_c)
533 + })()
534 +
535 + // active constraint gets removed
536 + }
537 +
538 + function __kitchen_1_6 (constraint, __n) {
539 + __n = __n || 0
540 +
541 + if (constraint.args[0] !== "apples") {
542 + constraint.cont = [__kitchen_1_7, 0]
543 + stack.push(constraint)
544 + return
545 + }
546 +
547 + var constraintPattern = [ "_", "kitchen/1", "kitchen/1" ]
548 + var lookupResult = chr.Store.lookupResume(1, constraintPattern, constraint, __n)
549 + if (lookupResult === false) {
550 + constraint.cont = [__kitchen_1_7, 0]
551 + stack.push(constraint)
552 + return
553 + }
554 + var constraints = lookupResult.res
555 +
556 + if (constraints[1].args[0] !== "oranges") {
557 + constraint.cont = [__kitchen_1_6, __n + 1]
558 + stack.push(constraint)
559 + return
560 + }
561 +
562 + if (constraints[2].args[0] !== "cherries") {
563 + constraint.cont = [__kitchen_1_6, __n + 1]
564 + stack.push(constraint)
565 + return
566 + }
567 +
568 + chr.Store.remove(constraints[1])
569 + chr.Store.remove(constraints[2])
570 +
571 + ;(function () {
572 + var _c = new Constraint("kitchen", 1, [ "fruit salad" ])
573 + _c.cont = [__kitchen_1_0, 0]
574 + stack.push(_c)
575 + })()
576 +
577 + // active constraint gets removed
578 + }
579 +
580 + function __kitchen_1_7 (constraint, __n) {
581 + __n = __n || 0
582 +
583 + if (constraint.args[0] !== "apple cake") {
584 + constraint.cont = [__kitchen_1_8, 0]
585 + stack.push(constraint)
586 + return
587 + }
588 +
589 + var constraintPattern = [ "kitchen/1", "_" ]
590 + var lookupResult = chr.Store.lookupResume(2, constraintPattern, constraint, __n)
591 + if (lookupResult === false) {
592 + constraint.cont = [__kitchen_1_8, 0]
593 + stack.push(constraint)
594 + return
595 + }
596 + var constraints = lookupResult.res
597 +
598 + if (constraints[0].args[0] !== "fruit salad") {
599 + constraint.cont = [__kitchen_1_7, __n + 1]
600 + stack.push(constraint)
601 + return
602 + }
603 +
604 + chr.Store.remove(constraints[0])
605 +
606 + ;(function () {
607 + var _c = new Constraint("kitchen", 1, [ "fruit cake" ])
608 + _c.cont = [__kitchen_1_0, 0]
609 + stack.push(_c)
610 + })()
611 +
612 + // active constraint gets removed
613 + }
614 +
615 + function __kitchen_1_8 (constraint, __n) {
616 + __n = __n || 0
617 +
618 + if (constraint.args[0] !== "fruit salad") {
619 + constraint.cont = [__kitchen_1_9, 0]
620 + stack.push(constraint)
621 + return
622 + }
623 +
624 + var constraintPattern = [ "_", "kitchen/1" ]
625 + var lookupResult = chr.Store.lookupResume(2, constraintPattern, constraint, __n)
626 + if (lookupResult === false) {
627 + constraint.cont = [__kitchen_1_9, 0]
628 + stack.push(constraint)
629 + return
630 + }
631 + var constraints = lookupResult.res
632 +
633 + if (constraints[1].args[0] !== "apple cake") {
634 + constraint.cont = [__kitchen_1_8, __n + 1]
635 + stack.push(constraint)
636 + return
637 + }
638 +
639 + chr.Store.remove(constraints[1])
640 +
641 + ;(function () {
642 + var _c = new Constraint("kitchen", 1, [ "fruit cake" ])
643 + _c.cont = [__kitchen_1_0, 0]
644 + stack.push(_c)
645 + })()
646 +
647 + // active constraint gets removed
648 + }
649 +
650 + function __start_0_0 (constraint, __n) {
651 + __n = __n || 0
652 +
653 + ;(function () {
654 + var _c = new Constraint("kitchen", 1, [ "sugar" ])
655 + _c.cont = [__kitchen_1_0, 0]
656 + stack.push(_c)
657 + })()
658 +
659 + ;(function () {
660 + var _c = new Constraint("kitchen", 1, [ "oranges" ])
661 + _c.cont = [__kitchen_1_0, 0]
662 + stack.push(_c)
663 + })()
664 +
665 + ;(function () {
666 + var _c = new Constraint("kitchen", 1, [ "apples" ])
667 + _c.cont = [__kitchen_1_0, 0]
668 + stack.push(_c)
669 + })()
670 +
671 + ;(function () {
672 + var _c = new Constraint("kitchen", 1, [ "cherries" ])
673 + _c.cont = [__kitchen_1_0, 0]
674 + stack.push(_c)
675 + })()
676 +
677 + ;(function () {
678 + var _c = new Constraint("kitchen", 1, [ "flour" ])
679 + _c.cont = [__kitchen_1_0, 0]
680 + stack.push(_c)
681 + })()
682 +
683 + ;(function () {
684 + var _c = new Constraint("kitchen", 1, [ "apples" ])
685 + _c.cont = [__kitchen_1_0, 0]
686 + stack.push(_c)
687 + })()
688 +
689 + // active constraint gets removed
690 + }
691 +
692 + function __kitchen_1_9 (constraint) {
693 + constraint.cont = null
694 + chr.Store.add(constraint)
695 + }
696 +
697 + function __start_0_1 (constraint) {
698 + constraint.cont = null
699 + chr.Store.add(constraint)
700 + }
701 +
702 + function kitchen () {
703 + var args = Array.prototype.slice.call(arguments)
704 + var arity = arguments.length
705 + var functor = "kitchen/" + arity
706 + var constraint = new Constraint("kitchen", arity, args)
707 + if (arity === 1) {
708 + constraint.cont = [__kitchen_1_0, ]
709 + } else {
710 + throw new Error("Undefined constraint: " + functor)
711 + }
712 + stack.push(constraint)
713 +
714 + trampoline()
715 + }
716 +
717 + function start () {
718 + var args = Array.prototype.slice.call(arguments)
719 + var arity = arguments.length
720 + var functor = "start/" + arity
721 + var constraint = new Constraint("start", arity, args)
722 + if (arity === 0) {
723 + constraint.cont = [__start_0_0, ]
724 + } else {
725 + throw new Error("Undefined constraint: " + functor)
726 + }
727 + stack.push(constraint)
728 +
729 + trampoline()
730 + }
731 +
732 + chr.kitchen = kitchen
733 + chr.start = start
734 +
735 + return chr
736 + })()
Newer Older