diff --git a/minimart/demand-matcher.rkt b/minimart/demand-matcher.rkt index c6542e4..5dbd542 100644 --- a/minimart/demand-matcher.rkt +++ b/minimart/demand-matcher.rkt @@ -55,8 +55,8 @@ (define new-d (struct-copy demand-matcher d [current-demand new-demand] [current-supply new-supply])) - (let* ((s (for/fold [(s s)] [(k (in-set demand+))] (apply inc-h s (vector->list k)))) - (s (for/fold [(s s)] [(k (in-set supply-))] (apply dec-h s (vector->list k))))) + (let* ((s (for/fold [(s s)] [(captures (in-set demand+))] (apply inc-h s captures))) + (s (for/fold [(s s)] [(captures (in-set supply-))] (apply dec-h s captures)))) (values new-d s))) (define (demand-matcher-handle-event e d) diff --git a/minimart/gestalt.rkt b/minimart/gestalt.rkt index 2269a8b..ff5d736 100644 --- a/minimart/gestalt.rkt +++ b/minimart/gestalt.rkt @@ -9,6 +9,7 @@ (provide (struct-out gestalt) gestalt-match-value compile-gestalt-projection + compile-gestalt-projection* gestalt-project drop-gestalt lift-gestalt @@ -85,8 +86,11 @@ (define matcher ((if is-feedback? cdr car) level)) ;; feedback targets advertisers/publishers (set-union (matcher-match-value matcher body) acc))) -(define (compile-gestalt-projection spec) - (compile-projection spec)) +(define (compile-gestalt-projection* specs) + (compile-projection* specs)) + +(define (compile-gestalt-projection . specs) + (compile-gestalt-projection* specs)) ;; Gestalt × Natural × Natural × Boolean × CompiledSpec → Matcher (define (gestalt-project g metalevel level get-advertisements? capture-spec) diff --git a/minimart/ground.rkt b/minimart/ground.rkt index 12d9b74..cae2055 100644 --- a/minimart/ground.rkt +++ b/minimart/ground.rkt @@ -24,7 +24,7 @@ ;; process be identified and terminated? (when (not es) (error 'extract-active-events "User program subscribed to wildcard event")) (for/list [(ev (in-set es))] - (match-define (vector e) ev) + (match-define (list e) ev) (event-handler e))) (define idle-handler diff --git a/minimart/route.rkt b/minimart/route.rkt index e533b3e..117ec44 100644 --- a/minimart/route.rkt +++ b/minimart/route.rkt @@ -12,6 +12,7 @@ ?! (struct-out capture) pattern->matcher + pattern->matcher* matcher? ;; expensive; see implementation matcher-empty matcher-empty? @@ -23,6 +24,7 @@ matcher-append matcher-relabel compile-projection + compile-projection* projection->pattern matcher-project matcher-key-set @@ -131,15 +133,17 @@ (for/fold [(acc knil)] [(elem (in-vector v (- (vector-length v) 1) -1 -1))] (kons elem acc))) -(define (pattern->matcher v p) - (let walk ((p p) (acc (rseq EOS (rsuccess v)))) +(define (pattern->matcher* v ps) + (define (walk-list ps acc) + (match ps + ['() (rseq EOS acc)] + [(cons p ps) (walk p (walk-list ps acc))] + [other (rseq ILM (walk other (rseq EOS acc)))])) + + (define (walk p acc) (match p [(== ?) (rwild acc)] - [(cons p1 p2) (rseq SOL (walk p1 (let walk-list ((p p2)) - (match p - ['() (rseq EOS acc)] - [(cons p1 p2) (walk p1 (walk-list p2))] - [other (rseq ILM (walk other (rseq EOS acc)))]))))] + [(cons p1 p2) (rseq SOL (walk p1 (walk-list p2 acc)))] [(? vector? v) (rseq SOV (vector-foldr walk (rseq EOS acc) v))] [(embedded-matcher m) (matcher-append m (lambda (mv) acc))] [(? non-object-struct?) @@ -149,7 +153,12 @@ (rseq t (foldr walk (rseq EOS acc) fs))] ;; TODO: consider options for treating hash tables as compounds rather than (useless) atoms [(? hash?) (error 'pattern->matcher "Cannot match on hash tables at present")] - [other (rseq other acc)]))) + [other (rseq other acc)])) + + (walk-list ps (rsuccess v))) + +(define (pattern->matcher v . ps) + (pattern->matcher* v ps)) (define (rlookup r key) (hash-ref r key (lambda () #f))) @@ -473,19 +482,18 @@ [(wildcard-sequence m1) (rwildseq (walk m1))] [(? hash?) (for/fold [(acc #f)] [((k v) (in-hash m))] (rupdate acc k (walk v)))]))) -(define (compile-projection p) - ;; Extremely similar to pattern->matcher. Besides use of conses - ;; rather than chained hashtables, the only interesting difference - ;; is how ?! is treated. - (let walk ((p p) (acc (cons EOS '()))) +(define (compile-projection* ps) + (define (walk-list ps acc) + (match ps + ['() (cons EOS acc)] + [(cons p ps) (walk p (walk-list ps acc))] + [other (cons ILM (walk other (cons EOS acc)))])) + + (define (walk p acc) (match p [(capture sub) (cons SOC (walk sub (cons EOC acc)))] ;; TODO: enforce non-nesting here [(== ?) (cons ? acc)] - [(cons p1 p2) (cons SOL (walk p1 (let walk-list ((p p2)) - (match p - ['() (cons EOS acc)] - [(cons p1 p2) (walk p1 (walk-list p2))] - [other (cons ILM (walk other (cons EOS acc)))]))))] + [(cons p1 p2) (cons SOL (walk p1 (walk-list p2 acc)))] [(? vector? v) (cons SOV (vector-foldr walk (cons EOS acc) v))] [(embedded-matcher m) (error 'compile-projection "Cannot embed matcher in projection")] [(? non-object-struct?) @@ -495,7 +503,12 @@ (cons t (foldr walk (cons EOS acc) fs))] ;; TODO: consider options for treating hash tables as compounds rather than (useless) atoms [(? hash?) (error 'compile-projection "Cannot match on hash tables at present")] - [other (cons other acc)]))) + [other (cons other acc)])) + + (walk-list ps '())) + +(define (compile-projection . ps) + (compile-projection* ps)) (define (projection->pattern p) (let walk ((p p)) @@ -553,7 +566,7 @@ ['() (when capturing? (error 'matcher-project "Bad specification: unclosed capture")) (match m - [(success v) (rseq EOS (rseq EOS (rsuccess ((matcher-project-success) v))))] + [(success v) (rseq EOS (rsuccess ((matcher-project-success) v)))] [_ (matcher-empty)])] [(cons (== EOC) k) @@ -609,7 +622,7 @@ [_ (matcher-empty)]))])) (lambda (m spec) - (rseq SOV (walk #f m spec))))) + (walk #f m spec)))) (define (untransform-list-value vs) (match vs @@ -618,7 +631,7 @@ [(cons (== ILM) _) (error 'untransform-list-value "Illegal use of ILM" vs)] [(cons v vs) (cons v (untransform-list-value vs))])) -;; Matcher → (Option (Setof Value)) +;; Matcher → (Option (Setof (Listof Value))) ;; Multiplies out unions. Returns #f if any dimension of m is infinite. (define matcher-key-set (let () @@ -662,7 +675,7 @@ (k (for/set [(vs (in-set vss))] (cons v vs)) vsk)))))]))))] - [_ (k (set) #f)])) ;; TODO: ?? + [_ (k (set) #f)])) ;; (Listof Value) Sigma -> Value (define (transform-seqs vs opener) @@ -675,7 +688,7 @@ (define (maybe-union s1 s2) (and s1 s2 (set-union s1 s2))) (lambda (m) - (walk m (lambda (v k) (set v)))))) + (walk-seq m (lambda (vss vsk) vss))))) (define (struct-type-name st) (define-values (name x2 x3 x4 x5 x6 x7 x8) (struct-type-info st)) @@ -1153,32 +1166,32 @@ (check-equal? (matcher-project (matcher-union (pattern->matcher SA (list 'a 'a)) (pattern->matcher SB (list 'a 'b))) (compile-projection (list 'a (?!)))) - (matcher-union (pattern->matcher #t (vector 'a)) - (pattern->matcher #t (vector 'b)))) + (matcher-union (pattern->matcher #t 'a) + (pattern->matcher #t 'b))) (check-equal? (matcher-project (matcher-union (pattern->matcher SA (list 'a 'a)) (pattern->matcher SB (list 'a (vector 'b 'c 'd)))) (compile-projection (list 'a (?!)))) - (matcher-union (pattern->matcher #t (vector 'a)) - (pattern->matcher #t (vector (vector 'b 'c 'd))))) + (matcher-union (pattern->matcher #t 'a) + (pattern->matcher #t (vector 'b 'c 'd)))) (check-equal? (matcher-project (matcher-union (pattern->matcher SA (list 'a 'a)) (pattern->matcher SB (list 'a (vector 'b ? 'd)))) (compile-projection (list 'a (?!)))) - (matcher-union (pattern->matcher #t (vector 'a)) - (pattern->matcher #t (vector (vector 'b ? 'd))))) + (matcher-union (pattern->matcher #t 'a) + (pattern->matcher #t (vector 'b ? 'd)))) (check-equal? (matcher-key-set (matcher-project (matcher-union (pattern->matcher SA (list 'a 'a)) (pattern->matcher SB (list 'a 'b))) (compile-projection (list 'a (?!))))) - (set '#(a) '#(b))) + (set '(a) '(b))) (check-equal? (matcher-key-set (matcher-project (matcher-union (pattern->matcher SA (list 'a 'a)) (pattern->matcher SB (list 'a (vector 'b 'c 'd)))) (compile-projection (list 'a (?!))))) - (set '#(a) '#(#(b c d)))) + (set '(a) '(#(b c d)))) (check-equal? (matcher-key-set (matcher-project (matcher-union (pattern->matcher SA (list 'a 'a)) @@ -1190,13 +1203,13 @@ (matcher-project (matcher-union (pattern->matcher SA (list 'a 'a)) (pattern->matcher SB (list 'a (vector 'b ? 'd)))) (compile-projection (list 'a (?! 'a))))) - (set '#(a))) + (set '(a))) (check-equal? (matcher-project (matcher-union (pattern->matcher SA (cons 1 2)) (pattern->matcher SB (cons 3 4))) (compile-projection (cons (?!) (?!)))) - (matcher-union (pattern->matcher #t (vector 1 2)) - (pattern->matcher #t (vector 3 4)))) + (matcher-union (pattern->matcher #t 1 2) + (pattern->matcher #t 3 4))) (check-equal? (matcher-project (foldr matcher-union (matcher-empty) (list (pattern->matcher SA (cons 1 2)) @@ -1204,9 +1217,9 @@ (pattern->matcher SC (cons 3 4)))) (compile-projection (cons (?!) (?!)))) (foldr matcher-union (matcher-empty) - (list (pattern->matcher #t (vector 1 2)) - (pattern->matcher #t (vector 1 4)) - (pattern->matcher #t (vector 3 4))))) + (list (pattern->matcher #t 1 2) + (pattern->matcher #t 1 4) + (pattern->matcher #t 3 4)))) (check-equal? (matcher-project (foldr matcher-union (matcher-empty) (list (pattern->matcher SA (cons 1 2)) @@ -1214,9 +1227,9 @@ (pattern->matcher SC (cons 3 4)))) (compile-projection (?! (cons ? ?)))) (foldr matcher-union (matcher-empty) - (list (pattern->matcher #t (vector (cons 1 2))) - (pattern->matcher #t (vector (cons 1 4))) - (pattern->matcher #t (vector (cons 3 4)))))) + (list (pattern->matcher #t (cons 1 2)) + (pattern->matcher #t (cons 1 4)) + (pattern->matcher #t (cons 3 4))))) (check-equal? (matcher-project (foldr matcher-union (matcher-empty) (list (pattern->matcher SA (cons 1 2)) @@ -1224,8 +1237,8 @@ (pattern->matcher SC (cons 3 4)))) (compile-projection (?! (cons 1 ?)))) (foldr matcher-union (matcher-empty) - (list (pattern->matcher #t (vector (cons 1 2))) - (pattern->matcher #t (vector (cons 1 4)))))) + (list (pattern->matcher #t (cons 1 2)) + (pattern->matcher #t (cons 1 4))))) (check-equal? (matcher-project (foldr matcher-union (matcher-empty) (list (pattern->matcher SA (cons 1 2)) @@ -1233,8 +1246,8 @@ (pattern->matcher SC (cons 3 4)))) (compile-projection (cons (?! 1) (?!)))) (foldr matcher-union (matcher-empty) - (list (pattern->matcher #t (vector 1 2)) - (pattern->matcher #t (vector 1 4))))) + (list (pattern->matcher #t 1 2) + (pattern->matcher #t 1 4)))) (check-equal? (matcher-project (foldr matcher-union (matcher-empty) (list (pattern->matcher SA (cons 1 2)) @@ -1242,8 +1255,8 @@ (pattern->matcher SC (cons 3 4)))) (compile-projection (cons (?!) (?! 4)))) (foldr matcher-union (matcher-empty) - (list (pattern->matcher #t (vector 1 4)) - (pattern->matcher #t (vector 3 4))))) + (list (pattern->matcher #t 1 4) + (pattern->matcher #t 3 4)))) (check-equal? (matcher-key-set (matcher-project (foldr matcher-union (matcher-empty) @@ -1259,18 +1272,18 @@ (pattern->matcher SC (cons 1 3)) (pattern->matcher SB (cons 3 4)))) (compile-projection (cons ? (?!))))) - (set '#(2) '#(3) '#(4))) + (set '(2) '(3) '(4))) (check-equal? (matcher-key-set (matcher-project (matcher-union (pattern->matcher SA (cons 1 2)) (pattern->matcher SB (cons 3 4))) (compile-projection (cons (?!) (?!))))) - (set '#(1 2) '#(3 4)))) + (set '(1 2) '(3 4)))) (check-equal? (matcher-project (matcher-union (pattern->matcher SA ?) (pattern->matcher SB (list 'a))) (compile-projection (?! (list (list ?))))) - (pattern->matcher SA (vector (list (list ?))))) + (pattern->matcher SA (list (list ?)))) (check-equal? (projection->pattern (list 'a 'b)) (list 'a 'b)) (check-equal? (projection->pattern (list 'a ?)) (list 'a ?))