2016-04-01 23:53:46 +00:00
|
|
|
#lang syndicate
|
2015-04-24 20:16:19 +00:00
|
|
|
|
|
|
|
(require racket/set)
|
2016-03-12 16:54:31 +00:00
|
|
|
(require "../trie.rkt")
|
2015-04-24 20:16:19 +00:00
|
|
|
(require "../demand-matcher.rkt")
|
2016-07-12 19:05:56 +00:00
|
|
|
(require/activate "../drivers/timer.rkt")
|
2015-04-24 20:16:19 +00:00
|
|
|
|
2015-04-25 15:51:55 +00:00
|
|
|
(spawn (lambda (e old-count)
|
|
|
|
(match e
|
|
|
|
[(? patch?)
|
2016-03-12 16:54:31 +00:00
|
|
|
(define-values (in out) (patch-project/set #:take 2 e `(parent ,(?!) ,(?!))))
|
2015-04-25 15:51:55 +00:00
|
|
|
(define new-count (+ old-count (set-count in) (- (set-count out))))
|
|
|
|
(printf "New parent-record count: ~v\n" new-count)
|
|
|
|
(transition new-count
|
|
|
|
(list (retract `(parent-count ,?))
|
|
|
|
(assert `(parent-count ,new-count))))]
|
|
|
|
[_ #f]))
|
|
|
|
0
|
2015-12-03 20:53:07 +00:00
|
|
|
(patch-seq (sub `(parent ,? ,?))
|
|
|
|
(assert `(parent-count 0))))
|
2015-04-25 15:51:55 +00:00
|
|
|
|
2015-04-24 20:16:19 +00:00
|
|
|
(define (insert-record record . monitors)
|
|
|
|
(printf "Record ~v inserted, depending on ~v\n" record monitors)
|
|
|
|
(spawn (lambda (e s)
|
|
|
|
(match e
|
|
|
|
[(? patch/removed?)
|
|
|
|
(printf "Retracting ~v because dependencies ~v vanished\n"
|
|
|
|
record
|
2016-03-12 16:54:31 +00:00
|
|
|
(set->list (trie-project/set/single (patch-removed e) (?!))))
|
2015-04-24 20:16:19 +00:00
|
|
|
(quit)]
|
|
|
|
[(message `(retract ,(== record)))
|
|
|
|
(printf "Retracting ~v because we were told to explicitly\n" record)
|
|
|
|
(quit)]
|
|
|
|
[_ #f]))
|
|
|
|
(void)
|
2015-12-03 20:53:07 +00:00
|
|
|
(patch-seq (assert record)
|
|
|
|
(sub `(retract ,record))
|
|
|
|
(patch-seq* (map sub monitors)))))
|
2015-04-24 20:16:19 +00:00
|
|
|
|
|
|
|
(insert-record `(parent john douglas))
|
|
|
|
(insert-record `(parent bob john))
|
|
|
|
(insert-record `(parent ebbon bob))
|
|
|
|
|
|
|
|
(spawn (lambda (e s)
|
|
|
|
(match e
|
|
|
|
[(? patch?)
|
|
|
|
(transition s
|
2016-03-12 16:54:31 +00:00
|
|
|
(for/list [(AB (trie-project/set #:take 2
|
|
|
|
(patch-added e)
|
|
|
|
`(parent ,(?!) ,(?!))))]
|
2015-04-24 20:16:19 +00:00
|
|
|
(match-define (list A B) AB)
|
|
|
|
(insert-record `(ancestor ,A ,B)
|
|
|
|
`(parent ,A ,B))))]
|
|
|
|
[_ #f]))
|
|
|
|
(void)
|
|
|
|
(sub `(parent ,? ,?)))
|
|
|
|
|
|
|
|
(spawn (lambda (e s)
|
|
|
|
(match e
|
|
|
|
[(? patch?)
|
|
|
|
(transition s
|
2016-03-12 16:54:31 +00:00
|
|
|
(for/list [(AC (trie-project/set #:take 2
|
|
|
|
(patch-added e)
|
|
|
|
`(parent ,(?!) ,(?!))))]
|
2015-04-24 20:16:19 +00:00
|
|
|
(match-define (list A C) AC)
|
|
|
|
(printf "Inductive step for ~v asserted\n" `(parent ,A ,C))
|
|
|
|
(spawn (lambda (e s)
|
|
|
|
(define removed-parents
|
|
|
|
(and (patch? e)
|
2016-03-12 16:54:31 +00:00
|
|
|
(trie-project (patch-removed e) `(parent ,(?!) ,(?!)))))
|
2016-01-22 02:55:41 +00:00
|
|
|
(if (trie-non-empty? removed-parents)
|
2015-04-24 20:16:19 +00:00
|
|
|
(begin
|
|
|
|
(printf
|
|
|
|
"Inductive step for ~v retracted because of removal ~v\n"
|
|
|
|
`(parent ,A ,C)
|
2016-03-12 16:54:31 +00:00
|
|
|
(trie-key-set #:take 2 removed-parents))
|
2015-04-24 20:16:19 +00:00
|
|
|
(quit))
|
|
|
|
(and (patch? e)
|
|
|
|
(transition s
|
2016-01-22 02:55:41 +00:00
|
|
|
(for/list [(CB (trie-project/set
|
2016-03-12 16:54:31 +00:00
|
|
|
#:take 2
|
2015-04-24 20:16:19 +00:00
|
|
|
(patch-added e)
|
2016-03-12 16:54:31 +00:00
|
|
|
`(ancestor ,(?!) ,(?!))))]
|
2015-04-24 20:16:19 +00:00
|
|
|
(match-define (list _ B) CB)
|
|
|
|
(insert-record `(ancestor ,A ,B)
|
|
|
|
`(parent ,A ,C)
|
|
|
|
`(ancestor ,C ,B)))))))
|
|
|
|
(void)
|
2015-12-03 20:53:07 +00:00
|
|
|
(patch-seq (sub `(parent ,A ,C))
|
|
|
|
(sub `(ancestor ,C ,?))))))]
|
2015-04-24 20:16:19 +00:00
|
|
|
[_ #f]))
|
|
|
|
(void)
|
|
|
|
(sub `(parent ,? ,?)))
|
|
|
|
|
2015-04-25 18:51:12 +00:00
|
|
|
;;;; Backward-chaining, below, doesn't quite work as formulated with
|
|
|
|
;;;; this code snippet: the demand-matcher gets confused by wildcard
|
|
|
|
;;;; demand from the recursive step. One way out of this might be to
|
|
|
|
;;;; avoid patterns quantifying over more than one place at once: to
|
|
|
|
;;;; have a process for *all* potential ancestor-queries for a given
|
|
|
|
;;;; person, rather than one for each *specific* ancestor-query.
|
|
|
|
;;
|
|
|
|
;; (spawn-demand-matcher (observe `(ancestor ,(?!) ,(?!)))
|
|
|
|
;; (advertise `(ancestor ,(?!) ,(?!)))
|
|
|
|
;; (lambda (A B)
|
|
|
|
;; (spawn (lambda (e old-facts)
|
|
|
|
;; (match e
|
|
|
|
;; [(? patch/removed?) (quit)]
|
|
|
|
;; [(? patch?)
|
2016-01-22 02:55:41 +00:00
|
|
|
;; (define new-facts (trie-union old-facts (patch-added e)))
|
2016-03-12 16:54:31 +00:00
|
|
|
;; (define triples (trie-project/set #:take 3 new-facts
|
|
|
|
;; `(,(?!) ,(?!) ,(?!))))
|
2015-04-25 18:51:12 +00:00
|
|
|
;; (printf "Learned new facts: ~v\n" triples)
|
|
|
|
;; (transition new-facts
|
|
|
|
;; (when (or (set-member? triples `(parent ,A ,B))
|
|
|
|
;; (for/or ((triple triples))
|
|
|
|
;; (match triple
|
|
|
|
;; [`(ancestor ,C ,(== B))
|
|
|
|
;; (set-member? triples `(parent ,A ,C))]
|
|
|
|
;; [_ #f])))
|
|
|
|
;; (printf "... and as a result, asserting ~v\n"
|
|
|
|
;; `(ancestor ,A ,B))
|
|
|
|
;; (assert `(ancestor ,A ,B))))]
|
|
|
|
;; [_ #f]))
|
2016-03-12 16:54:31 +00:00
|
|
|
;; trie-empty
|
2015-12-03 20:53:07 +00:00
|
|
|
;; (patch-seq
|
|
|
|
;; (sub `(parent ,A ,B))
|
|
|
|
;; (sub `(parent ,A ,?))
|
|
|
|
;; (sub `(ancestor ,? ,B))
|
|
|
|
;; (pub `(ancestor ,A ,B))))))
|
2015-04-25 18:51:12 +00:00
|
|
|
|
|
|
|
(spawn (lambda (e s)
|
|
|
|
(when (patch? e) (pretty-print-patch e))
|
|
|
|
#f)
|
|
|
|
(void)
|
|
|
|
(sub `(ancestor ebbon douglas)))
|
|
|
|
|
2015-04-24 20:16:19 +00:00
|
|
|
(define (after msec thunk)
|
|
|
|
(define id (gensym 'after))
|
2015-04-24 21:30:51 +00:00
|
|
|
(if (zero? msec)
|
|
|
|
(thunk)
|
2015-12-03 20:53:07 +00:00
|
|
|
(spawn (lambda (e s) (and (message? e) (quit (thunk))))
|
|
|
|
(void)
|
|
|
|
(list (message (set-timer id msec 'relative))
|
|
|
|
(sub (timer-expired id ?))))))
|
2015-04-24 20:16:19 +00:00
|
|
|
|
2015-04-24 21:30:51 +00:00
|
|
|
(define use-delays? #t)
|
|
|
|
|
|
|
|
(after (if use-delays? 1000 0) (lambda ()
|
|
|
|
(printf "----- Retracting\n")
|
|
|
|
(message `(retract (parent bob john)))))
|
|
|
|
(after (if use-delays? 2000 0) (lambda ()
|
|
|
|
(printf "----- Asserting\n")
|
|
|
|
(list (insert-record `(parent bob mary))
|
|
|
|
(insert-record `(parent mary sue))
|
|
|
|
(insert-record `(parent sue john)))))
|