matcher->finite-set -> matcher-key-set
This commit is contained in:
parent
cad1dbbbca
commit
2ccd066012
|
@ -23,7 +23,7 @@
|
||||||
matcher-relabel
|
matcher-relabel
|
||||||
compile-projection
|
compile-projection
|
||||||
matcher-project
|
matcher-project
|
||||||
matcher->finite-set
|
matcher-key-set
|
||||||
pretty-print-matcher)
|
pretty-print-matcher)
|
||||||
|
|
||||||
(define-syntax-rule (define-singleton-struct singleton-name struct-name print-representation)
|
(define-syntax-rule (define-singleton-struct singleton-name struct-name print-representation)
|
||||||
|
@ -236,9 +236,13 @@
|
||||||
[(r #f) #f]
|
[(r #f) #f]
|
||||||
[(r1 r2) (walk r1 r2)])))
|
[(r1 r2) (walk r1 r2)])))
|
||||||
|
|
||||||
|
(define (set-subtract/false s1 s2)
|
||||||
|
(define r (set-subtract s1 s2))
|
||||||
|
(if (set-empty? r) #f r))
|
||||||
|
|
||||||
;; Removes re2's mappings from re1. Assumes re2 has previously been union'd into re1.
|
;; Removes re2's mappings from re1. Assumes re2 has previously been union'd into re1.
|
||||||
;; The combine-successes function should return #f to signal "no remaining success values".
|
;; The combine-successes function should return #f to signal "no remaining success values".
|
||||||
(define (matcher-erase-path re1 re2 [combine-successes set-subtract])
|
(define (matcher-erase-path re1 re2 [combine-successes set-subtract/false])
|
||||||
(define (cofinite-pattern)
|
(define (cofinite-pattern)
|
||||||
(error 'matcher-erase-path "Cofinite pattern required"))
|
(error 'matcher-erase-path "Cofinite pattern required"))
|
||||||
(define (walk path aggregate)
|
(define (walk path aggregate)
|
||||||
|
@ -246,7 +250,9 @@
|
||||||
[((wildcard-sequence r1) (wildcard-sequence r2)) (rwildseq (walk r1 r2))]
|
[((wildcard-sequence r1) (wildcard-sequence r2)) (rwildseq (walk r1 r2))]
|
||||||
[((wildcard-sequence r1) r2) (cofinite-pattern)]
|
[((wildcard-sequence r1) r2) (cofinite-pattern)]
|
||||||
[(r1 (wildcard-sequence r2)) (walk r1 (expand-wildseq r2))]
|
[(r1 (wildcard-sequence r2)) (walk r1 (expand-wildseq r2))]
|
||||||
[((success v1) (success v2)) (success (combine-successes v1 v2))]
|
[((success v1) (success v2))
|
||||||
|
(define new-v (combine-successes v1 v2))
|
||||||
|
(and new-v (success new-v))]
|
||||||
[((? hash? h1) (? hash? h2))
|
[((? hash? h1) (? hash? h2))
|
||||||
(define w1 (rlookup h1 ?))
|
(define w1 (rlookup h1 ?))
|
||||||
(define w2 (rlookup h2 ?))
|
(define w2 (rlookup h2 ?))
|
||||||
|
@ -416,8 +422,9 @@
|
||||||
[(? hash?) (error 'pattern->matcher "Cannot match on hash tables at present")]
|
[(? hash?) (error 'pattern->matcher "Cannot match on hash tables at present")]
|
||||||
[other (cons other acc)])))
|
[other (cons other acc)])))
|
||||||
|
|
||||||
;; Matcher × CompiledProjection → Matcher
|
;; Matcher × CompiledProjection [× (Value -> (Option Value))] → Matcher
|
||||||
;; The result matches a vector of length equal to the number of captures.
|
;; The result matches a vector of length equal to the number of captures.
|
||||||
|
;; The project-success function should return #f to signal "no success values".
|
||||||
(define matcher-project
|
(define matcher-project
|
||||||
;; TODO: skip-nested, capture-nested, and the ? and ?! cases in
|
;; TODO: skip-nested, capture-nested, and the ? and ?! cases in
|
||||||
;; walk-out all share a suspicious amount of code. Refactor it away.
|
;; walk-out all share a suspicious amount of code. Refactor it away.
|
||||||
|
@ -449,58 +456,60 @@
|
||||||
[else (rupdate acc key (capture-nested mk k))])))]
|
[else (rupdate acc key (capture-nested mk k))])))]
|
||||||
[_ (matcher-empty)]))
|
[_ (matcher-empty)]))
|
||||||
|
|
||||||
(define (walk-out m spec)
|
(lambda (m spec [project-success values])
|
||||||
(match spec
|
(define (walk-out m spec)
|
||||||
['()
|
(match spec
|
||||||
(match m
|
['()
|
||||||
[(success v) (rseq EOS (rseq EOS (success #t)))]
|
(match m
|
||||||
;; ^ the #t yields a matcher that does not preserve map values.
|
[(success v)
|
||||||
[_ (matcher-empty)])]
|
(define new-v (project-success v))
|
||||||
|
(if new-v
|
||||||
|
(rseq EOS (rseq EOS (success new-v)))
|
||||||
|
(matcher-empty))]
|
||||||
|
[_ (matcher-empty)])]
|
||||||
|
|
||||||
[(cons (== ?) k)
|
[(cons (== ?) k)
|
||||||
(match m
|
(match m
|
||||||
[(wildcard-sequence _) (walk-out m k)]
|
[(wildcard-sequence _) (walk-out m k)]
|
||||||
[(? hash?)
|
[(? hash?)
|
||||||
(for/fold [(acc (walk-out (rlookup m ?) k))] [((key mk) (in-hash m))]
|
(for/fold [(acc (walk-out (rlookup m ?) k))] [((key mk) (in-hash m))]
|
||||||
(if (eq? key ?)
|
(if (eq? key ?)
|
||||||
acc
|
acc
|
||||||
(matcher-union acc (cond
|
(matcher-union acc (cond
|
||||||
[(key-open? key) (skip-nested mk (lambda (mk) (walk-out mk k)))]
|
[(key-open? key) (skip-nested mk (lambda (mk) (walk-out mk k)))]
|
||||||
[(key-close? key) #f]
|
[(key-close? key) #f]
|
||||||
[else (walk-out mk k)]))))]
|
[else (walk-out mk k)]))))]
|
||||||
[_ (matcher-empty)])]
|
[_ (matcher-empty)])]
|
||||||
|
|
||||||
[(cons (== ?!) k)
|
[(cons (== ?!) k)
|
||||||
(match m
|
(match m
|
||||||
[(wildcard-sequence _) (rwild (walk-out m k))]
|
[(wildcard-sequence _) (rwild (walk-out m k))]
|
||||||
[(? hash?)
|
[(? hash?)
|
||||||
(for/fold [(acc (rwild (walk-out (rlookup m ?) k)))] [((key mk) (in-hash m))]
|
(for/fold [(acc (rwild (walk-out (rlookup m ?) k)))] [((key mk) (in-hash m))]
|
||||||
(if (eq? key ?)
|
(if (eq? key ?)
|
||||||
acc
|
acc
|
||||||
(cond
|
(cond
|
||||||
[(key-open? key)
|
[(key-open? key)
|
||||||
(rupdate acc key (capture-nested mk (lambda (mk) (walk-out mk k))))]
|
(rupdate acc key (capture-nested mk (lambda (mk) (walk-out mk k))))]
|
||||||
[(key-close? key) acc]
|
[(key-close? key) acc]
|
||||||
[else (rupdate acc key (walk-out mk k))])))]
|
[else (rupdate acc key (walk-out mk k))])))]
|
||||||
[_ (matcher-empty)])]
|
[_ (matcher-empty)])]
|
||||||
|
|
||||||
[(cons sigma k)
|
[(cons sigma k)
|
||||||
(match m
|
(match m
|
||||||
[(wildcard-sequence mk)
|
[(wildcard-sequence mk)
|
||||||
(if (key-close? sigma)
|
(if (key-close? sigma)
|
||||||
(walk-out mk k)
|
(walk-out mk k)
|
||||||
(walk-out m k))]
|
(walk-out m k))]
|
||||||
[(? hash?)
|
[(? hash?)
|
||||||
(matcher-union (walk-out (rlookup m sigma) k)
|
(matcher-union (walk-out (rlookup m sigma) k)
|
||||||
(walk-out (rlookup m ?) k))]
|
(walk-out (rlookup m ?) k))]
|
||||||
[_ (matcher-empty)])]))
|
[_ (matcher-empty)])]))
|
||||||
|
|
||||||
(lambda (m spec)
|
|
||||||
(rseq SOV (walk-out m spec)))))
|
(rseq SOV (walk-out m spec)))))
|
||||||
|
|
||||||
;; Matcher → (Option (Setof Value))
|
;; Matcher → (Option (Setof Value))
|
||||||
;; Multiplies out unions. Returns #f if any dimension of m is infinite.
|
;; Multiplies out unions. Returns #f if any dimension of m is infinite.
|
||||||
(define matcher->finite-set
|
(define matcher-key-set
|
||||||
(let ()
|
(let ()
|
||||||
;; Matcher (Value Matcher -> (Setof Value)) -> (Option (Setof Value))
|
;; Matcher (Value Matcher -> (Setof Value)) -> (Option (Setof Value))
|
||||||
;; Calls k with each possible atomic value at this matcher
|
;; Calls k with each possible atomic value at this matcher
|
||||||
|
@ -520,7 +529,7 @@
|
||||||
(maybe-union acc
|
(maybe-union acc
|
||||||
(k (transform-seqs vs key) vsk)))))]
|
(k (transform-seqs vs key) vsk)))))]
|
||||||
[(key-close? key)
|
[(key-close? key)
|
||||||
(error 'matcher->finite-set "Internal error: unexpected key-close")]
|
(error 'matcher-key-set "Internal error: unexpected key-close")]
|
||||||
[else
|
[else
|
||||||
(k key mk)]))))]
|
(k key mk)]))))]
|
||||||
[_ (set)]))
|
[_ (set)]))
|
||||||
|
@ -936,49 +945,57 @@
|
||||||
|
|
||||||
(check-equal? (matcher-project (matcher-union (pattern->matcher SA (list 'a 'a))
|
(check-equal? (matcher-project (matcher-union (pattern->matcher SA (list 'a 'a))
|
||||||
(pattern->matcher SB (list 'a 'b)))
|
(pattern->matcher SB (list 'a 'b)))
|
||||||
(compile-projection (list 'a ?!)))
|
(compile-projection (list 'a ?!))
|
||||||
|
(lambda (v) #t))
|
||||||
(matcher-union (pattern->matcher #t (vector 'a))
|
(matcher-union (pattern->matcher #t (vector 'a))
|
||||||
(pattern->matcher #t (vector 'b))))
|
(pattern->matcher #t (vector 'b))))
|
||||||
|
|
||||||
(check-equal? (matcher-project (matcher-union (pattern->matcher SA (list 'a 'a))
|
(check-equal? (matcher-project (matcher-union (pattern->matcher SA (list 'a 'a))
|
||||||
(pattern->matcher SB (list 'a (vector 'b 'c 'd))))
|
(pattern->matcher SB (list 'a (vector 'b 'c 'd))))
|
||||||
(compile-projection (list 'a ?!)))
|
(compile-projection (list 'a ?!))
|
||||||
|
(lambda (v) #t))
|
||||||
(matcher-union (pattern->matcher #t (vector 'a))
|
(matcher-union (pattern->matcher #t (vector 'a))
|
||||||
(pattern->matcher #t (vector (vector 'b 'c 'd)))))
|
(pattern->matcher #t (vector (vector 'b 'c 'd)))))
|
||||||
|
|
||||||
(check-equal? (matcher-project (matcher-union (pattern->matcher SA (list 'a 'a))
|
(check-equal? (matcher-project (matcher-union (pattern->matcher SA (list 'a 'a))
|
||||||
(pattern->matcher SB (list 'a (vector 'b ? 'd))))
|
(pattern->matcher SB (list 'a (vector 'b ? 'd))))
|
||||||
(compile-projection (list 'a ?!)))
|
(compile-projection (list 'a ?!))
|
||||||
|
(lambda (v) #t))
|
||||||
(matcher-union (pattern->matcher #t (vector 'a))
|
(matcher-union (pattern->matcher #t (vector 'a))
|
||||||
(pattern->matcher #t (vector (vector 'b ? 'd)))))
|
(pattern->matcher #t (vector (vector 'b ? 'd)))))
|
||||||
|
|
||||||
(check-equal? (matcher->finite-set
|
(check-equal? (matcher-key-set
|
||||||
(matcher-project (matcher-union (pattern->matcher SA (list 'a 'a))
|
(matcher-project (matcher-union (pattern->matcher SA (list 'a 'a))
|
||||||
(pattern->matcher SB (list 'a 'b)))
|
(pattern->matcher SB (list 'a 'b)))
|
||||||
(compile-projection (list 'a ?!))))
|
(compile-projection (list 'a ?!))
|
||||||
|
(lambda (v) #t)))
|
||||||
(set '#(a) '#(b)))
|
(set '#(a) '#(b)))
|
||||||
|
|
||||||
(check-equal? (matcher->finite-set
|
(check-equal? (matcher-key-set
|
||||||
(matcher-project (matcher-union (pattern->matcher SA (list 'a 'a))
|
(matcher-project (matcher-union (pattern->matcher SA (list 'a 'a))
|
||||||
(pattern->matcher SB (list 'a (vector 'b 'c 'd))))
|
(pattern->matcher SB (list 'a (vector 'b 'c 'd))))
|
||||||
(compile-projection (list 'a ?!))))
|
(compile-projection (list 'a ?!))
|
||||||
|
(lambda (v) #t)))
|
||||||
(set '#(a) '#(#(b c d))))
|
(set '#(a) '#(#(b c d))))
|
||||||
|
|
||||||
(check-equal? (matcher->finite-set
|
(check-equal? (matcher-key-set
|
||||||
(matcher-project (matcher-union (pattern->matcher SA (list 'a 'a))
|
(matcher-project (matcher-union (pattern->matcher SA (list 'a 'a))
|
||||||
(pattern->matcher SB (list 'a (vector 'b ? 'd))))
|
(pattern->matcher SB (list 'a (vector 'b ? 'd))))
|
||||||
(compile-projection (list 'a ?!))))
|
(compile-projection (list 'a ?!))
|
||||||
|
(lambda (v) #t)))
|
||||||
#f)
|
#f)
|
||||||
|
|
||||||
(check-equal? (matcher-project (matcher-union (pattern->matcher SA (cons 1 2))
|
(check-equal? (matcher-project (matcher-union (pattern->matcher SA (cons 1 2))
|
||||||
(pattern->matcher SB (cons 3 4)))
|
(pattern->matcher SB (cons 3 4)))
|
||||||
(compile-projection (cons ?! ?!)))
|
(compile-projection (cons ?! ?!))
|
||||||
|
(lambda (v) #t))
|
||||||
(matcher-union (pattern->matcher #t (vector 1 2))
|
(matcher-union (pattern->matcher #t (vector 1 2))
|
||||||
(pattern->matcher #t (vector 3 4))))
|
(pattern->matcher #t (vector 3 4))))
|
||||||
|
|
||||||
(check-equal? (matcher->finite-set
|
(check-equal? (matcher-key-set
|
||||||
(matcher-project (matcher-union (pattern->matcher SA (cons 1 2))
|
(matcher-project (matcher-union (pattern->matcher SA (cons 1 2))
|
||||||
(pattern->matcher SB (cons 3 4)))
|
(pattern->matcher SB (cons 3 4)))
|
||||||
(compile-projection (cons ?! ?!))))
|
(compile-projection (cons ?! ?!))
|
||||||
|
(lambda (v) #t)))
|
||||||
(set '#(1 2) '#(3 4)))
|
(set '#(1 2) '#(3 4)))
|
||||||
)
|
)
|
Loading…
Reference in New Issue