(declare (usual-integrations))
\f
-(define (make-compound-tag predicate operator operands)
- (make-tag predicate
- (cons operator (map tag-name operands))
+(define (make-compound-tag datum-test operator operands)
+ (make-tag (cons operator (map tag-name operands))
+ datum-test
+ predicate-tagging-strategy:optional
+ operator
(make-compound-tag-extra operator operands)))
(define (compound-tag? object)
(declare (usual-integrations))
\f
-(define (make-parametric-tag predicate name template bindings)
- (make-tag predicate
- name
+(define (parametric-predicate? object)
+ (and (predicate? object)
+ (tag-is-parametric? (predicate->tag object))))
+
+(define (parametric-predicate-template predicate)
+ (parametric-tag-template (predicate->tag predicate)))
+
+(define (parametric-predicate-bindings predicate)
+ (parametric-tag-bindings (predicate->tag predicate)))
+
+(define (make-parametric-tag name datum-test tagging-strategy template bindings)
+ (make-tag name
+ datum-test
+ tagging-strategy
+ 'make-predicate-template
(make-parametric-tag-extra template bindings)))
(define (tag-is-parametric? tag)
(template parametric-tag-extra-template)
(bindings parametric-tag-extra-bindings))
\f
-(define (parametric-predicate? object)
- (and (predicate? object)
- (tag-is-parametric? (predicate->tag object))))
-
-(define (parametric-predicate-template predicate)
- (parametric-tag-template (predicate->tag predicate)))
+;;;; Templates
-(define (parametric-predicate-bindings predicate)
- (parametric-tag-bindings (predicate->tag predicate)))
+(define (make-predicate-template name pattern tagging-strategy make-data-test)
+ (guarantee template-pattern? pattern 'make-predicate-template)
+ (letrec*
+ ((instantiator
+ (make-instantiator name pattern make-data-test tagging-strategy
+ (lambda () template)))
+ (template
+ (%make-predicate-template name
+ pattern
+ (all-args-memoizer equal?
+ (lambda patterned-tags
+ patterned-tags)
+ instantiator)
+ (lambda (object)
+ (and (parametric-predicate? object)
+ (eqv? template
+ (parametric-predicate-template
+ object)))))))
+ (register-predicate! (predicate-template-predicate template)
+ (symbol name '-predicate)
+ '<= parametric-predicate?)
+ template))
(define-record-type <predicate-template>
(%make-predicate-template name pattern instantiator predicate)
predicate-template?
(name predicate-template-name)
(pattern predicate-template-pattern)
- (instantiator predicate-template-instantiator)
+ (instantiator template-instantiator)
(predicate predicate-template-predicate))
-(define (make-predicate-template name pattern)
- (guarantee template-pattern? pattern 'make-predicate-template)
- (letrec*
- ((instantiator
- (make-predicate-template-instantiator
- (lambda () template)))
- (predicate
- (lambda (object)
- (and (parametric-predicate? object)
- (eqv? (parametric-predicate-template object)
- template))))
- (template
- (%make-predicate-template
- name
- pattern
- (all-args-memoizer equal?
- (lambda parameters parameters)
- instantiator)
- predicate)))
- (register-predicate! predicate (symbol name '-predicate)
- '<= parametric-predicate?)
- template))
+(define (make-instantiator name pattern make-data-test tagging-strategy
+ get-template)
+ (lambda (patterned-tags caller)
+ (letrec ((tag
+ (make-parametric-tag
+ (cons name
+ (map-template-pattern pattern
+ patterned-tags
+ tag-name
+ caller))
+ (make-data-test (lambda () tag))
+ tagging-strategy
+ (get-template)
+ (match-template-pattern pattern
+ patterned-tags
+ tag?
+ caller))))
+ tag)))
\f
-(define (make-predicate-template-instantiator get-template)
- (lambda parameters
- (let ((template (get-template)))
- (let ((name (predicate-template-name template))
- (pattern (predicate-template-pattern template)))
- (let ((parameters
- (map-template-pattern pattern
- parameters
- predicate->tag)))
- (letrec* ((predicate
- (lambda (object)
- (and (predicate? object)
- (tag<= (predicate->tag object) tag))))
- (tag
- (make-parametric-tag
- predicate
- (cons name
- (map-template-pattern pattern
- parameters
- tag-name))
- template
- (match-template-pattern pattern
- parameters
- tag?))))
- predicate))))))
+(define (predicate-template-constructor template #!optional caller)
+ (let ((instantiator (template-instantiator template))
+ (pattern (predicate-template-pattern template)))
+ (lambda patterned-predicates
+ (tag->predicate
+ (instantiator (map-template-pattern pattern
+ patterned-predicates
+ predicate->tag
+ caller)
+ caller)))))
(define (predicate-template-parameter-names template)
(template-pattern->names (predicate-template-pattern template)))
-(define (predicate-template-accessor name template)
+(define (predicate-template-accessor name template #!optional caller)
(let ((elt
(find (lambda (elt)
- (eq? (template-pattern-element-name elt) name))
+ (eq? name (template-pattern-element-name elt)))
(predicate-template-pattern template))))
(if (not elt)
- (error "Unknown parameter name:" name template))
+ (error:bad-range-argument name 'predicate-template-accessor))
(let ((valid? (predicate-template-predicate template))
(convert
(if (template-pattern-element-single-valued? elt)
tag->predicate
- tags->predicates)))
+ (lambda (tags) (map tag->predicate tags)))))
(lambda (predicate)
- (if (not (valid? predicate))
- (error "Not a valid predicate:" predicate))
+ (guarantee valid? predicate caller)
(convert
(parameter-binding-value
(find (lambda (binding)
(eqv? name (parameter-binding-name binding)))
- (parametric-tag-bindings
- (predicate->tag predicate)))))))))
-
-(define (tags->predicates tags)
- (map tag->predicate tags))
+ (parametric-tag-bindings (predicate->tag predicate)))))))))
\f
;;;; Template patterns
(define (template-pattern->names pattern)
(map template-pattern-element-name pattern))
-\f
-(define (match-template-pattern pattern values value-predicate)
- (guarantee list? values 'match-template-pattern)
+
+(define (match-template-pattern pattern values value-predicate caller)
+ (guarantee list? values caller)
(if (not (= (length values) (length pattern)))
- (error "Wrong number of values:" values pattern))
+ (error:bad-range-argument values caller))
(map (lambda (element value)
(case (template-pattern-element-operator element)
((?)
(list? (cdr value))
(every value-predicate value)))
(error "Mismatch:" element value)))
- (else
- (error:not-a template-pattern? pattern 'match-template-pattern)))
+ (else (error:not-a template-pattern? pattern caller)))
(make-parameter-binding element value))
pattern
values))
+(define (map-template-pattern pattern object value-procedure caller)
+ (map (lambda (element o)
+ (case (template-pattern-element-operator element)
+ ((?) (value-procedure o))
+ ((?* ?+) (map value-procedure o))
+ (else (error:not-a template-pattern? pattern caller))))
+ pattern
+ object))
+\f
(define-record-type <parameter-binding>
(make-parameter-binding element value)
parameter-binding?
(list (parameter-binding-value binding))
(parameter-binding-value binding)))
-(define (map-template-pattern pattern object value-procedure)
- (map (lambda (element o)
- (case (template-pattern-element-operator element)
- ((?) (value-procedure o))
- ((?* ?+) (map value-procedure o))
- (else
- (error:not-a template-pattern? pattern 'map-template-pattern))))
- pattern
- object))
-
(add-boot-init!
(lambda ()
(register-predicate! parametric-predicate? 'parametric-predicate
(define (register-predicate! predicate name . keylist)
(guarantee keyword-list? keylist 'register-predicate!)
(let ((tag
- (make-tag predicate
- name
+ (make-tag name
+ predicate
+ predicate-tagging-strategy:never
(get-keyword-value keylist 'extra)
(get-keyword-value keylist 'description))))
(for-each (lambda (superset)
(and tag
(not (tag-extra tag)))))
\f
-(define (make-tag predicate name #!optional extra description)
- (guarantee unary-procedure? predicate 'make-tag)
- (guarantee tag-name? name 'make-tag)
- (if (predicate? predicate)
- (error "Predicate is already registered:" predicate))
- (let ((tag
- (%make-tag predicate
- name
- (if (default-object? description)
- #f
- (guarantee string? description 'make-tag))
- (if (default-object? extra) #f extra)
- (make-strong-eq-hash-table)
- (make-strong-eq-hash-table))))
- (set-predicate-tag! predicate tag)
- tag))
+(define (make-tag name datum-test tagging-strategy caller
+ #!optional extra description)
+ (guarantee tag-name? name caller)
+ (guarantee unary-procedure? datum-test caller)
+ (if (not (default-object? description))
+ (guarantee string? description caller))
+ (tagging-strategy name datum-test
+ (lambda (predicate constructor accessor)
+ (let ((tag
+ (%make-tag name
+ predicate
+ constructor
+ accessor
+ (if (default-object? extra) #f extra)
+ (if (default-object? description) #f description)
+ (make-strong-eq-hash-table)
+ (make-strong-eq-hash-table))))
+ (set-predicate-tag! predicate tag)
+ tag))))
(define (tag-name? object)
(or (symbol? object)
(every tag-name? object))))
(define-record-type <tag>
- (%make-tag predicate name description extra subsets supersets)
+ (%make-tag name predicate constructor accessor extra description
+ subsets supersets)
tag?
- (predicate tag->predicate)
(name tag-name)
- (description %tag-description)
+ (predicate tag->predicate)
+ (constructor tag-constructor)
+ (accessor tag-accessor)
(extra tag-extra)
+ (description %tag-description)
(subsets tag-subsets)
(supersets tag-supersets))
parametric-predicate-template
parametric-predicate?
predicate-template-accessor
- predicate-template-instantiator
+ predicate-template-constructor
predicate-template-name
predicate-template-parameter-names
predicate-template-pattern
(files "predicate-tagging")
(parent (runtime))
(export ()
- object->datum
- object->predicate
- object-tagger
predicate-tagging-strategy:always
predicate-tagging-strategy:never
predicate-tagging-strategy:optional
+ object->datum
+ object->predicate
+ object-tagger
set-tagged-object-unparser-method!
tag-object
tagged-object-datum
"runtime/test-arith"
"runtime/test-bytevector"
("runtime/test-char-set" (runtime character-set))
- ("runtime/test-compound-predicate" (runtime compound-predicate))
+ ("runtime/test-compound-predicate" (runtime))
"runtime/test-dragon4"
"runtime/test-dynamic-env"
"runtime/test-division"
"runtime/test-integer-bits"
"runtime/test-mime-codec"
("runtime/test-parametric-predicate" (runtime parametric-predicate))
- ("runtime/test-predicate-lattice" (runtime predicate-lattice))
- ("runtime/test-predicate-metadata" (runtime predicate-metadata))
+ ("runtime/test-predicate-lattice" (runtime))
+ ("runtime/test-predicate-metadata" (runtime))
"runtime/test-thread-queue"
"runtime/test-process"
"runtime/test-readwrite"
(declare (usual-integrations))
\f
+(define (make-template name pattern)
+ (make-predicate-template name pattern
+ predicate-tagging-strategy:always
+ (lambda (tag) tag any-object?)))
+
(define-test 'parametric-predicate-one-parameter
(lambda ()
(let ((pattern '((? base))))
- (let* ((template (make-predicate-template 'template pattern))
- (instantiator (predicate-template-instantiator template)))
+ (let* ((template (make-template 'template pattern))
+ (constructor (predicate-template-constructor template)))
(test-template-operations template 'template pattern)
(let ((params1 (list number?))
(params2 (list boolean?)))
- (let ((tn (apply instantiator params1))
- (tb (apply instantiator params2)))
+ (let ((tn (apply constructor params1))
+ (tb (apply constructor params2)))
(test-predicate-operations tn '(template number))
(test-predicate-operations tb '(template boolean))
(test-parametric-predicate-operations tn template params1)
(define-test 'parametric-predicate-two-parameters
(lambda ()
(let ((pattern '((?* domains -) (? base))))
- (let* ((template (make-predicate-template 'template pattern))
- (instantiator (predicate-template-instantiator template)))
+ (let* ((template (make-template 'template pattern))
+ (constructor (predicate-template-constructor template)))
(test-template-operations template 'template pattern)
(let ((params1 (list (list number? number?) number?))
(params2 (list (list boolean? boolean?) boolean?)))
- (let ((tn (apply instantiator params1))
- (tb (apply instantiator params2)))
+ (let ((tn (apply constructor params1))
+ (tb (apply constructor params2)))
(test-predicate-operations tn '(template (number number) number))
(test-predicate-operations tb '(template (boolean boolean) boolean))
(test-parametric-predicate-operations tn template params1)
(define-test 'covariant-ordering
(lambda ()
- (let* ((template (make-predicate-template 'foo '((? a))))
- (instantiator (predicate-template-instantiator template)))
- (let ((p1 (instantiator (disjoin string? symbol?)))
- (p2 (instantiator string?))
- (p3 (instantiator symbol?)))
+ (let* ((template (make-template 'foo '((? a))))
+ (constructor (predicate-template-constructor template)))
+ (let ((p1 (constructor (disjoin string? symbol?)))
+ (p2 (constructor string?))
+ (p3 (constructor symbol?)))
(assert-true (predicate<= p1 p1))
(assert-false (predicate<= p1 p2))
\f
(define-test 'contravariant-ordering
(lambda ()
- (let* ((template (make-predicate-template 'foo '((? a -))))
- (instantiator (predicate-template-instantiator template)))
- (let ((p1 (instantiator (disjoin string? symbol?)))
- (p2 (instantiator string?))
- (p3 (instantiator symbol?)))
+ (let* ((template (make-template 'foo '((? a -))))
+ (constructor (predicate-template-constructor template)))
+ (let ((p1 (constructor (disjoin string? symbol?)))
+ (p2 (constructor string?))
+ (p3 (constructor symbol?)))
(assert-true (predicate<= p1 p1))
(assert-true (predicate<= p1 p2))
(define-test 'mixed-ordering
(lambda ()
- (let* ((template (make-predicate-template 'foo '((? a -) (? b))))
- (instantiator (predicate-template-instantiator template)))
- (let ((p1 (instantiator (disjoin string? symbol?)
- (disjoin string? symbol?)))
- (p2 (instantiator string? string?))
- (p3 (instantiator string? (disjoin string? symbol?)))
- (p4 (instantiator (disjoin string? symbol?) string?)))
+ (let* ((template (make-template 'foo '((? a -) (? b))))
+ (constructor (predicate-template-constructor template)))
+ (let ((p1 (constructor (disjoin string? symbol?)
+ (disjoin string? symbol?)))
+ (p2 (constructor string? string?))
+ (p3 (constructor string? (disjoin string? symbol?)))
+ (p4 (constructor (disjoin string? symbol?) string?)))
(for-each (lambda (predicate)
(assert-true (predicate<= predicate predicate)))
(parametric-predicate-template predicate)))
(define (match-numbers pattern values)
- (parameter-bindings->alist (match-template-pattern pattern values number?)))
+ (parameter-bindings->alist
+ (match-template-pattern pattern values number? 'match-numbers)))
(define (parameter-bindings->alist bindings)
(map (lambda (binding)