Predicates
Derived predicates from the base relation: accepts, conforms_to, is_comparable, is_equivalent
Foundation
All predicates are derived from the base relation $\preceq$ defined in URN Syntax:
This document defines four predicates that provide different views of this relation.
The Four Predicates
accepts(a, b)
Definition:
Meaning: a subsumes b. The URN a (as a pattern) accepts b (as an instance).
“Is a at least as general as b?”
accepts(media:bytes, media:pdf;bytes) = true # bytes accepts pdf;bytes
accepts(media:pdf;bytes, media:bytes) = false # pdf;bytes does not accept bytes
accepts(media:pdf, media:pdf) = true # identical
conforms_to(a, b)
Definition:
Meaning: a satisfies or refines b. The URN a (as an instance) conforms to b (as a pattern).
Equivalent to accepts(b, a).
“Is a at least as specific as b?”
conforms_to(media:pdf;bytes, media:bytes) = true # pdf;bytes conforms to bytes
conforms_to(media:bytes, media:pdf;bytes) = false # bytes does not conform to pdf;bytes
conforms_to(media:pdf, media:pdf) = true # identical
is_comparable(a, b)
Definition:
Meaning: a and b are on the same specialization chain. One subsumes the other.
“Are these related by specialization in either direction?”
is_comparable(media:bytes, media:pdf;bytes) = true # same chain
is_comparable(media:pdf, media:image) = false # different branches
is_comparable(media:pdf, media:pdf) = true # identical
Comparability is necessary but NOT sufficient for dispatch. Two URNs can be comparable but not dispatchable.
is_equivalent(a, b)
Definition:
Meaning: a and b are at the same position in the partial order. They are semantically identical.
“Are these semantically identical?”
is_equivalent(media:pdf, media:pdf) = true
is_equivalent(media:bytes;pdf, media:pdf;bytes) = true # same tags, different order
is_equivalent(media:pdf, media:pdf;bytes) = false # different specificity
Relationship Summary
| Predicate | Definition | Symmetric? | Use Case |
|---|---|---|---|
accepts(a,b) |
$b \preceq a$ | No | Pattern matching |
conforms_to(a,b) |
$a \preceq b$ | No | Instance checking |
is_comparable(a,b) |
$a \preceq b \lor b \preceq a$ | Yes | Discovery, grouping |
is_equivalent(a,b) |
$a \preceq b \land b \preceq a$ | Yes | Exact identity |
Implications
But NOT:
Usage Guidelines
Use accepts when:
Checking if a pattern matches an instance. The first argument is the pattern/template.
if pattern.accepts(&instance) {
// instance satisfies pattern
}
Use conforms_to when:
Checking if an instance satisfies a requirement. The first argument is the instance/value.
if instance.conforms_to(&requirement) {
// instance meets requirement
}
Use is_comparable when:
Exploring related capabilities, building discovery/search features, grouping URNs by family, or diagnostics.
if urn_a.is_comparable(&urn_b) {
// they're on the same specialization chain
}
Use is_equivalent when:
Exact lookup in a registry, deduplication, or verifying identity.
if urn_a.is_equivalent(&urn_b) {
// they are semantically identical
}
Common Mistakes
Using accepts for dispatch
// WRONG:
if registered.accepts(&request) { /* route here */ }
A generic provider accepts a specific request, but may not meet the request’s output requirements. Dispatch requires the 3-axis check (see Dispatch).
Using conforms_to for dispatch
// WRONG:
if registered.conforms_to(&request) { /* route here */ }
A specific provider conforms to a generic request, but the request may not provide what the provider needs as input.
Using is_comparable for dispatch
// WRONG:
if registered.is_comparable(&request) { /* route here */ }
Being on the same chain doesn’t mean the provider can handle the request. They might be comparable but in the wrong direction.
Confusing direction
// WRONG — trying to check if instance satisfies pattern:
if pattern.conforms_to(&instance) { ... } // BACKWARDS!
// CORRECT:
if instance.conforms_to(&pattern) { ... }
// OR equivalently:
if pattern.accepts(&instance) { ... }
Algebraic Properties
accepts
- Not symmetric:
accepts(a,b)does not implyaccepts(b,a) - Reflexive:
accepts(a,a)always holds - Transitive:
accepts(a,b)$\land$accepts(b,c)$\implies$accepts(a,c)
conforms_to
- Not symmetric:
conforms_to(a,b)does not implyconforms_to(b,a) - Reflexive:
conforms_to(a,a)always holds - Transitive:
conforms_to(a,b)$\land$conforms_to(b,c)$\implies$conforms_to(a,c)
is_comparable
- Symmetric:
is_comparable(a,b)$\iff$is_comparable(b,a) - Reflexive:
is_comparable(a,a)always holds - Not transitive:
is_comparable(a,b)$\land$is_comparable(b,c)does NOT implyis_comparable(a,c)
is_equivalent
- Symmetric:
is_equivalent(a,b)$\iff$is_equivalent(b,a) - Reflexive:
is_equivalent(a,a)always holds - Transitive:
is_equivalent(a,b)$\land$is_equivalent(b,c)$\implies$is_equivalent(a,c)
This makes is_equivalent an equivalence relation.
Summary
| Question | Predicate |
|---|---|
| “Does pattern accept instance?” | accepts(pattern, instance) |
| “Does instance satisfy pattern?” | conforms_to(instance, pattern) |
| “Are these related?” | is_comparable(a, b) |
| “Are these identical?” | is_equivalent(a, b) |
For Cap URN dispatch, none of these alone is sufficient. See Dispatch for the correct routing predicate.