cap: Documentation
Browse Sign In

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:

$$ a \preceq b \;\text{iff}\; a \text{ is at least as specific as } b $$

This document defines four predicates that provide different views of this relation.

The Four Predicates

accepts(a, b)

Definition:

$$ \text{accepts}(a, b) \iff b \preceq a $$

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:

$$ \text{conforms_to}(a, b) \iff a \preceq b $$

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:

$$ \text{is_comparable}(a, b) \iff a \preceq b \lor b \preceq a $$

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:

$$ \text{is_equivalent}(a, b) \iff a \preceq b \land b \preceq a $$

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

$$ \text{is_equivalent}(a,b) \implies \text{is_comparable}(a,b) $$
$$ \text{is_equivalent}(a,b) \implies \text{accepts}(a,b) \land \text{accepts}(b,a) $$
$$ \text{is_equivalent}(a,b) \implies \text{conforms_to}(a,b) \land \text{conforms_to}(b,a) $$

But NOT:

$$ \text{is_comparable}(a,b) \;\not\!\!\implies \text{is_equivalent}(a,b) $$
$$ \text{accepts}(a,b) \;\not\!\!\implies \text{conforms_to}(a,b) $$

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 imply accepts(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 imply conforms_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 imply is_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.