vocabulary

package
v1.0.0-alpha.13 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 8, 2026 License: MIT Imports: 5 Imported by: 0

README

Vocabulary Package

Purpose: Semantic vocabulary management with dotted notation predicates and optional IRI mappings for standards compliance.

Design Philosophy: Pragmatic Semantic Web

The vocabulary package follows a pragmatic semantic web approach that balances clean internal architecture with customer requirements for standards compliance.

Core Principles

Internal: Always use dotted notation (domain.category.property)

  • Clean, human-readable predicates
  • NATS wildcard query support
  • No URI/IRI complexity in internal code

External: Optional IRI mappings at API boundaries

  • RDF/Turtle export with standard vocabularies
  • OGC compliance (GeoSPARQL, SSN/SOSA)
  • Integration with existing semantic systems

No Leakage: Standards complexity does NOT leak inward

  • Internal code never sees IRIs
  • Triples always use dotted predicates
  • NATS subjects use dotted notation

Predicate Structure

All predicates follow three-level dotted notation:

domain.category.property

Examples:

  • sensor.temperature.celsius - Sensor domain, temperature category
  • geo.location.latitude - Geospatial domain, location category
  • time.lifecycle.created - Temporal domain, lifecycle category
  • robotics.battery.level - Robotics domain, battery category

Naming Conventions:

  • domain: lowercase, business domain (sensors, geo, time, robotics)
  • category: lowercase, groups related properties (temperature, location, lifecycle)
  • property: lowercase, specific property name (celsius, latitude, created)
  • No underscores or special characters (dots only for level separation)

Why This Works:

  • ✅ NATS wildcards: robotics.battery.* finds all battery predicates
  • ✅ Human-readable: Clear semantic meaning without URIs
  • ✅ Consistent: Matches EntityID.Key() and Type.Key() patterns
  • ✅ Simple: No namespace prefixes or IRI complexity

Quick Start

1. Define Domain Predicates
package robotics

const (
    BatteryLevel   = "robotics.battery.level"
    BatteryVoltage = "robotics.battery.voltage"
    FlightModeArmed = "robotics.flight.armed"
)
2. Register with Metadata
func init() {
    vocabulary.Register(BatteryLevel,
        vocabulary.WithDescription("Battery charge level percentage"),
        vocabulary.WithDataType("float64"),
        vocabulary.WithUnits("percent"),
        vocabulary.WithRange("0-100"),
        vocabulary.WithIRI("http://schema.org/batteryLevel"))

    vocabulary.Register(BatteryVoltage,
        vocabulary.WithDescription("Battery voltage"),
        vocabulary.WithDataType("float64"),
        vocabulary.WithUnits("volts"))

    vocabulary.Register(FlightModeArmed,
        vocabulary.WithDescription("Flight mode armed status"),
        vocabulary.WithDataType("bool"))
}
3. Use in Messages
// Create triples - always dotted notation
triple := message.Triple{
    Subject:   entityID,
    Predicate: robotics.BatteryLevel,  // "robotics.battery.level"
    Object:    85.5,
}

// NATS queries work naturally
nc.Subscribe("robotics.battery.*", handler)  // All battery predicates
4. Export to RDF (Optional)
import "github.com/c360studio/semstreams/vocabulary/export"

// Serialize triples to Turtle
err := export.Serialize(os.Stdout, triples, export.Turtle)

// Or get as string in any format
s, err := export.SerializeToString(triples, export.NTriples)
s, err := export.SerializeToString(triples, export.JSONLD)

Functional Options API

The Register() function uses functional options for clean, composable configuration:

Available Options
WithDescription(desc string)

Human-readable description of the predicate.

vocabulary.Register("sensor.temperature.celsius",
    vocabulary.WithDescription("Temperature in degrees Celsius"))
WithDataType(dataType string)

Expected Go type for the object value.

Common types: "string", "float64", "int", "bool", "time.Time"

vocabulary.Register("sensor.temperature.celsius",
    vocabulary.WithDataType("float64"))
WithUnits(units string)

Measurement units (if applicable).

vocabulary.Register("sensor.temperature.celsius",
    vocabulary.WithUnits("celsius"))
WithRange(valueRange string)

Valid value ranges (if applicable).

vocabulary.Register("robotics.battery.level",
    vocabulary.WithRange("0-100"))
WithIRI(iri string)

W3C/RDF equivalent IRI for standards compliance.

Use constants from standards.go for common vocabularies.

vocabulary.Register("entity.label.preferred",
    vocabulary.WithIRI(vocabulary.SkosPrefLabel))
WithAlias(aliasType, priority int)

Mark as entity alias for resolution.

vocabulary.Register("robotics.communication.callsign",
    vocabulary.WithAlias(vocabulary.AliasTypeCommunication, 0))  // Priority 0 = highest
Complete Example
vocabulary.Register("robotics.battery.level",
    vocabulary.WithDescription("Battery charge level percentage"),
    vocabulary.WithDataType("float64"),
    vocabulary.WithUnits("percent"),
    vocabulary.WithRange("0-100"),
    vocabulary.WithIRI("http://schema.org/batteryLevel"))

Alias Predicates for Entity Resolution

Some predicates represent entity aliases (identifiers, labels, call signs). The registry tracks these for entity resolution and correlation.

Alias Types

AliasTypeIdentity - Entity equivalence

  • Go constants: vocabulary.OwlSameAs, vocabulary.SchemaSameAs
  • RDF equivalents: owl:sameAs, schema:sameAs
  • Use for: Federated entity IDs, external system UUIDs
  • Resolution: ✅ Can resolve to entity IDs

AliasTypeAlternate - Secondary unique identifiers

  • Go constants: vocabulary.SchemaAlternateName, vocabulary.DcAlternative
  • RDF equivalents: schema:alternateName, dc:alternative
  • Use for: Model numbers, registration IDs
  • Resolution: ✅ Can resolve to entity IDs

AliasTypeExternal - External system identifiers

  • Go constants: vocabulary.DcIdentifier, vocabulary.SchemaIdentifier
  • RDF equivalents: dc:identifier, schema:identifier
  • Use for: Manufacturer serial numbers, legacy system IDs
  • Resolution: ✅ Can resolve to entity IDs

AliasTypeCommunication - Communication identifiers

  • Go constants: vocabulary.FoafAccountName
  • RDF equivalent: foaf:accountName
  • Use for: Radio call signs, network hostnames, MQTT client IDs
  • Resolution: ✅ Can resolve to entity IDs

AliasTypeLabel - Display names

  • Go constants: vocabulary.RdfsLabel, vocabulary.SkosPrefLabel, vocabulary.SchemaName
  • RDF equivalents: rdfs:label, skos:prefLabel, schema:name
  • Use for: Human-readable display names
  • Resolution: ❌ NOT for resolution (ambiguous - many entities share labels)

Note: The RDF notation shown (e.g., owl:sameAs) is shorthand for full IRIs. In Go code, always use the provided constants from standards.go (e.g., vocabulary.OwlSameAs).

Example: Registering Aliases
// Communication identifier - highest priority
vocabulary.Register("robotics.communication.callsign",
    vocabulary.WithDescription("Radio call sign for ATC"),
    vocabulary.WithDataType("string"),
    vocabulary.WithAlias(vocabulary.AliasTypeCommunication, 0),
    vocabulary.WithIRI(vocabulary.FoafAccountName))

// External identifier
vocabulary.Register("robotics.identifier.serial",
    vocabulary.WithDescription("Manufacturer serial number"),
    vocabulary.WithDataType("string"),
    vocabulary.WithAlias(vocabulary.AliasTypeExternal, 1),
    vocabulary.WithIRI(vocabulary.DcIdentifier))

// Display label - NOT used for resolution
vocabulary.Register("entity.label.display",
    vocabulary.WithDescription("Human-readable display name"),
    vocabulary.WithDataType("string"),
    vocabulary.WithAlias(vocabulary.AliasTypeLabel, 10),  // Low priority
    vocabulary.WithIRI(vocabulary.RdfsLabel))
Discovering Aliases
// Get all alias predicates with priorities
aliases := vocabulary.DiscoverAliasPredicates()
// Returns: map["robotics.communication.callsign"]int(0), etc.

Standards Mappings

Common standard vocabulary IRIs are provided in standards.go:

OWL (Web Ontology Language)
const (
    OwlSameAs            = "http://www.w3.org/2002/07/owl#sameAs"
    OwlEquivalentClass   = "http://www.w3.org/2002/07/owl#equivalentClass"
    OwlInverseOf         = "http://www.w3.org/2002/07/owl#inverseOf"
)
SKOS (Simple Knowledge Organization System)
const (
    SkosPrefLabel = "http://www.w3.org/2004/02/skos/core#prefLabel"
    SkosAltLabel  = "http://www.w3.org/2004/02/skos/core#altLabel"
    SkosBroader   = "http://www.w3.org/2004/02/skos/core#broader"
    SkosNarrower  = "http://www.w3.org/2004/02/skos/core#narrower"
)
Dublin Core
const (
    DcIdentifier  = "http://purl.org/dc/terms/identifier"
    DcTitle       = "http://purl.org/dc/terms/title"
    DcAlternative = "http://purl.org/dc/terms/alternative"
    DcReferences  = "http://purl.org/dc/terms/references"
    DcRequires    = "http://purl.org/dc/terms/requires"
)
Schema.org
const (
    SchemaName          = "https://schema.org/name"
    SchemaAlternateName = "https://schema.org/alternateName"
    SchemaIdentifier    = "https://schema.org/identifier"
    SchemaSameAs        = "https://schema.org/sameAs"
)
PROV-O (Provenance Ontology)
const (
    ProvEntity            = "http://www.w3.org/ns/prov#Entity"
    ProvActivity          = "http://www.w3.org/ns/prov#Activity"
    ProvAgent             = "http://www.w3.org/ns/prov#Agent"
    ProvWasDerivedFrom    = "http://www.w3.org/ns/prov#wasDerivedFrom"
    ProvWasGeneratedBy    = "http://www.w3.org/ns/prov#wasGeneratedBy"
    ProvWasAssociatedWith = "http://www.w3.org/ns/prov#wasAssociatedWith"
    ProvActedOnBehalfOf   = "http://www.w3.org/ns/prov#actedOnBehalfOf"
)
SSN/SOSA (Semantic Sensor Network)
const (
    SsnHasDeployment    = "http://www.w3.org/ns/ssn/hasDeployment"
    SosaObserves        = "http://www.w3.org/ns/sosa/observes"
    SosaHasSimpleResult = "http://www.w3.org/ns/sosa/hasSimpleResult"
)
FOAF (Friend of a Friend)
const (
    FoafName        = "http://xmlns.com/foaf/0.1/name"
    FoafAccountName = "http://xmlns.com/foaf/0.1/accountName"
)

See standards.go for the complete list of standard vocabulary IRIs.

Ontology Subpackages

The vocabulary package includes ontology subpackages that provide IRI constants layered from foundational to domain-specific:

bfo/ - Basic Formal Ontology (BFO 2.0)

Upper-level ontology (ISO 21838-2) providing domain-neutral categories for all entities.

import "github.com/c360studio/semstreams/vocabulary/bfo"

// Classify a physical asset
triple := message.Triple{
    Subject:   entityID,
    Predicate: "rdf.type",
    Object:    bfo.Object, // http://purl.obolibrary.org/obo/BFO_0000030
}

Key concepts: Entity, Continuant, Occurrent, Object, Process, Role, Quality

cco/ - Common Core Ontologies

Mid-level ontology built on BFO for modeling agents, actions, information entities, and artifacts.

import "github.com/c360studio/semstreams/vocabulary/cco"

// Classify a software agent
triple := message.Triple{
    Subject:   agentID,
    Predicate: "rdf.type",
    Object:    cco.IntelligentSoftwareAgent,
}

Key concepts: InformationContentEntity, Agent, IntentionalAct, PlanSpecification, Capability

agentic/ - W3C S-Agent-Comm

AI agent interoperability predicates aligned with the W3C Semantic Agent Communication ontology.

import "github.com/c360studio/semstreams/vocabulary/agentic"

// Express an agent's intent
triple := message.Triple{
    Subject:   agentID,
    Predicate: agentic.IntentGoal,
    Object:    "analyze customer feedback",
}

// Register all agentic predicates with IRI mappings
agentic.Register()

Key concepts: IntentGoal, CapabilityName, DelegationFrom, AccountabilityActor, ExecutionEnvironment

export/ - RDF Serialization

Serializes []message.Triple to standard RDF formats (Turtle, N-Triples, JSON-LD) using the vocabulary registry for IRI resolution.

import "github.com/c360studio/semstreams/vocabulary/export"

output, err := export.SerializeToString(triples, export.Turtle)

Supported formats: export.Turtle, export.NTriples, export.JSONLD

See Vocabulary Documentation for architecture guides and detailed usage.

Registry API

Registration
// Register with functional options
vocabulary.Register(name string, opts ...Option)

// Register using struct directly (backward compatibility)
vocabulary.RegisterPredicate(meta PredicateMetadata)
Retrieval
// Get metadata for a predicate
meta := vocabulary.GetPredicateMetadata("robotics.battery.level")
if meta != nil {
    fmt.Println(meta.Description)
    fmt.Println(meta.StandardIRI)
}

// List all registered predicates
predicates := vocabulary.ListRegisteredPredicates()

// Discover alias predicates
aliases := vocabulary.DiscoverAliasPredicates()
Testing
// Clear registry (testing only)
vocabulary.ClearRegistry()

Internal vs External Usage

Internal: Always Dotted Notation
// Creating triples
triple := message.Triple{
    Subject:   "c360.platform1.robotics.drone.001",
    Predicate: "robotics.battery.level",  // Dotted, not IRI
    Object:    85.5,
}

// NATS subscriptions
nc.Subscribe("robotics.battery.*", handler)

// Entity properties
entityState.SetProperty("geo.location.latitude", 37.7749)

// NO IRIs in internal code!
External: IRI Mappings at Boundaries

The export package handles dotted-to-IRI translation automatically:

import "github.com/c360studio/semstreams/vocabulary/export"

// Serialize to Turtle — registered predicates map to standard IRIs,
// unregistered predicates generate SemStreams predicate IRIs.
err := export.Serialize(w, triples, export.Turtle)

// Custom base IRI for subject generation
err = export.Serialize(w, triples, export.NTriples,
    export.WithBaseIRI("https://example.org"))

// Custom subject IRI function for full control
err = export.Serialize(w, triples, export.JSONLD,
    export.WithSubjectIRIFunc(func(subject string) string {
        return "https://example.org/entities/" + subject
    }))

Best Practices

Predicate Definition
  1. Use Package Constants

    • Define predicates as package constants
    • Don't inline predicate strings
    • Group by domain and category
  2. Register in init()

    • Register all domain predicates during package initialization
    • Use functional options for clarity
    • Include IRI mappings for customer-facing predicates
  3. Consistent Naming

    • Follow domain.category.property strictly
    • Use lowercase throughout
    • Choose semantic, descriptive names
IRI Mappings
  1. Only When Needed

    • Map to standard IRIs for customer integrations
    • Skip IRI for internal-only predicates
    • Use well-known standards (Schema.org, OWL, SKOS)
  2. At API Boundaries

    • Translate dotted → IRI in RDF export
    • Translate IRI → dotted in RDF import
    • Keep internal code IRI-free
  3. Document Mappings

    • Explain why specific IRI chosen
    • Reference standard vocabulary documentation
    • Note any semantic differences
Entity Resolution
  1. Mark Alias Predicates

    • Use WithAlias() for identity-related predicates
    • Set appropriate priority for conflict resolution
    • Choose correct AliasType for semantics
  2. Avoid Label Confusion

    • Don't use AliasTypeLabel for resolution
    • Labels are for display only (ambiguous)
    • Use identity/alternate/external for unique IDs

Graph Domain Predicates

The vocabulary package provides standard relationship predicates for linking entities in the semantic graph. These graph.rel.* predicates enable rich semantic relationships with mappings to standard vocabularies.

Relationship Types

All relationship predicates follow the pattern graph.rel.* and are registered with Dublin Core, Schema.org, and PROV-O mappings where applicable.

Hierarchical Relationships
vocabulary.GraphRelContains     // Parent contains child
vocabulary.GraphRelDependsOn    // Subject depends on object
  • graph.rel.containsprov:hadMember - Hierarchical containment (platform contains sensors)
  • graph.rel.depends_ondcterms:requires - Dependency relationship (spec depends on spec)
Reference Relationships
vocabulary.GraphRelReferences   // Directional reference
vocabulary.GraphRelRelatedTo    // General association
vocabulary.GraphRelDiscusses    // Discussion/commentary
  • graph.rel.referencesdcterms:references - Documentation references specifications
  • graph.rel.related_todcterms:relation - Generic relationship
  • graph.rel.discussesschema:about - Discussion about a topic
Causal Relationships
vocabulary.GraphRelInfluences   // Causal/impact relationship
vocabulary.GraphRelTriggeredBy  // Event causation
  • graph.rel.influences - Decision influences implementation
  • graph.rel.triggered_by - Alert triggered by threshold
Implementation Relationships
vocabulary.GraphRelImplements   // Implementation relationship
vocabulary.GraphRelSupersedes   // Replacement/versioning
vocabulary.GraphRelBlockedBy    // Blocking relationship
  • graph.rel.implements - Code implements specification
  • graph.rel.supersedesdcterms:replaces - v2 supersedes v1
  • graph.rel.blocked_by - Issue blocked by another issue
Spatial/Communication Relationships
vocabulary.GraphRelNear         // Spatial proximity
vocabulary.GraphRelCommunicates // Communication/interaction
  • graph.rel.near - Sensors near a location
  • graph.rel.communicates - Services communicate with each other
Usage Example
import "github.com/c360studio/semstreams/vocabulary"

// Create relationship between specification and implementation
triple := message.Triple{
    Subject:   "spec-001",
    Predicate: vocabulary.GraphRelImplements,  // "graph.rel.implements"
    Object:    "pr-123",
}

// Query all relationships using NATS wildcards
nc.Subscribe("graph.rel.*", handler)  // All relationship types
nc.Subscribe("graph.rel.contains", handler)  // Only containment
Standards Compliance

Relationship predicates map to established semantic web vocabularies:

  • Dublin Core Terms - References, dependencies, replacements, relations
  • PROV-O - Provenance and membership relationships
  • Schema.org - Discussion and content relationships

See relationships.go for the complete registration and standards.go for IRI constants.

Framework Predicates

The vocabulary package provides example framework predicates in predicates.go. These demonstrate the pattern but are NOT required.

Applications should define their own domain-specific vocabularies. See examples/robotics.go and examples/semantic.go for reference implementations.

  • doc.go - Comprehensive package documentation
  • standards.go - Standard vocabulary IRI constants (OWL, SKOS, Dublin Core, PROV-O, SSN/SOSA)
  • bfo/ - BFO 2.0 upper-level ontology classes and relations
  • cco/ - Common Core Ontology classes for agents, actions, information
  • agentic/ - W3C S-Agent-Comm predicates for AI agent interoperability
  • export/ - RDF serialization to Turtle, N-Triples, JSON-LD
  • examples/ - Reference domain vocabulary implementations
  • message/triple.go - Triple structure for semantic facts
  • message/types.go - EntityID, EntityType, Type patterns
  • Vocabulary Documentation - Architecture guides and usage patterns

The vocabulary package focuses on predicate management, not IRI generation. For entity-level IRI needs, use the entity's own methods.

Documentation

Overview

Package vocabulary provides semantic vocabulary management for the SemStreams platform. It defines predicates using dotted notation and provides optional IRI mappings for standards compliance at API boundaries.

Architecture Philosophy: Pragmatic Semantic Web

The vocabulary package follows a "pragmatic semantic web" approach:

**Internal**: Clean dotted notation everywhere (domain.category.property)

**External**: Optional IRI/URI mappings at API boundaries for standards compliance

**No Leakage**: Standards complexity does NOT leak into internal architecture

Core Design Principles

1. **Dotted Notation Internally**

  • Predicates: "robotics.battery.level" (not URIs)
  • Enables NATS wildcard queries: "robotics.battery.*"
  • Human-readable and semantic
  • Consistent with message.Type and EntityID patterns

2. **IRI Mappings at Boundaries**

  • Optional StandardIRI field for RDF/OGC export
  • Bidirectional translation (dotted ↔ IRI)
  • Used only for customer integrations
  • Internal code never sees IRIs

3. **Customer Standards Support**

  • RDF/Turtle export with standard vocabularies
  • OGC compliance (GeoSPARQL, SSN/SOSA ontologies)
  • Integration with existing semantic systems
  • Support for domain-specific ontologies

Predicate Structure

Predicates follow three-level dotted notation:

domain.category.property

Examples:

  • sensor.temperature.celsius
  • geo.location.latitude
  • time.lifecycle.created
  • robotics.battery.level

Naming conventions:

  • domain: lowercase, business domain (sensors, geo, time, robotics)
  • category: lowercase, groups related properties (temperature, location, lifecycle)
  • property: lowercase, specific property name (celsius, latitude, created)
  • No underscores or special characters (dots only for level separation)

Predicate Registration

Register domain-specific predicates using functional options:

vocabulary.Register("robotics.battery.level",
    vocabulary.WithDescription("Battery charge level percentage"),
    vocabulary.WithDataType("float64"),
    vocabulary.WithUnits("percent"),
    vocabulary.WithRange("0-100"),
    vocabulary.WithIRI("http://schema.org/batteryLevel"))

The registry provides:

  • Metadata about each predicate (type, description, units)
  • Optional IRI mappings for RDF export
  • Alias semantics for entity resolution
  • Runtime predicate discovery

Internal Usage (Always Dotted)

// Creating triples - always use dotted notation
triple := message.Triple{
    Subject:   entityID,
    Predicate: "robotics.battery.level",  // Clean, dotted
    Object:    85.5,
}

// Querying via NATS - wildcards work naturally
nc.Subscribe("robotics.battery.*", handler)  // All battery predicates

// No IRI usage in internal code!

External Usage (IRI Mappings at API Boundaries)

// RDF export - translate dotted to IRI
if meta := vocabulary.GetPredicateMetadata(triple.Predicate); meta != nil {
    if meta.StandardIRI != "" {
        rdfTriple.Predicate = meta.StandardIRI  // "http://schema.org/batteryLevel"
    }
}

// Import from RDF - translate IRI to dotted
if dotted := vocabulary.LookupByIRI(rdfTriple.Predicate); dotted != "" {
    triple.Predicate = dotted  // "robotics.battery.level"
}

Alias Predicates for Entity Resolution

Some predicates represent entity aliases (identifiers, labels, call signs). The registry tracks these for entity resolution:

vocabulary.Register("robotics.communication.callsign",
    vocabulary.WithDescription("Radio call sign for ATC"),
    vocabulary.WithAlias(vocabulary.AliasTypeCommunication, 0))  // Priority 0 = highest

Alias types:

  • AliasTypeIdentity: Entity equivalence (owl:sameAs, schema:sameAs)
  • AliasTypeAlternate: Secondary unique identifiers (model numbers, registration IDs)
  • AliasTypeExternal: External system identifiers (serial numbers, legacy IDs)
  • AliasTypeCommunication: Communication identifiers (call signs, hostnames)
  • AliasTypeLabel: Display names (NOT used for resolution - ambiguous)

Domain Vocabulary Examples

Applications define domain-specific vocabularies:

package robotics

const (
    BatteryLevel = "robotics.battery.level"
    BatteryVoltage = "robotics.battery.voltage"
    FlightModeArmed = "robotics.flight.armed"
)

func init() {
    vocabulary.Register(BatteryLevel,
        vocabulary.WithDescription("Battery charge percentage"),
        vocabulary.WithDataType("float64"),
        vocabulary.WithUnits("percent"),
        vocabulary.WithRange("0-100"),
        vocabulary.WithIRI("http://schema.org/batteryLevel"))
    // ... register other predicates
}

Standards Mappings

Common standard vocabulary IRIs are provided in standards.go:

const (
    OWL_SAME_AS = "http://www.w3.org/2002/07/owl#sameAs"
    SKOS_PREF_LABEL = "http://www.w3.org/2004/02/skos/core#prefLabel"
    SCHEMA_NAME = "http://schema.org/name"
    // ... many more
)

Use these constants when registering predicates with standard mappings:

vocabulary.Register("entity.label.preferred",
    vocabulary.WithIRI(vocabulary.SKOS_PREF_LABEL))

Best Practices

## Predicate Definition

1. **Use Package Constants**

  • Define predicates as package constants
  • Don't inline predicate strings at call sites
  • Group by domain and category

2. **Register in init()**

  • Register all domain predicates during package initialization
  • Use functional options for clarity
  • Include IRI mappings for customer-facing predicates

3. **Consistent Naming**

  • Follow domain.category.property pattern strictly
  • Use lowercase throughout
  • Choose semantic, descriptive names

## IRI Mappings

1. **Only When Needed**

  • Map to standard IRIs for customer integrations
  • Skip IRI for internal-only predicates
  • Use well-known standards (Schema.org, OWL, SKOS, etc.)

2. **At API Boundaries**

  • Translate dotted → IRI in RDF export
  • Translate IRI → dotted in RDF import
  • Keep internal code IRI-free

3. **Document Mappings**

  • Explain why specific IRI chosen
  • Reference standard vocabulary documentation
  • Note any semantic differences

## Entity Resolution

1. **Mark Alias Predicates**

  • Use WithAlias() for identity-related predicates
  • Set appropriate priority for conflict resolution
  • Choose correct AliasType for semantics

2. **Avoid Label Confusion**

  • Don't use AliasTypeLabel for resolution
  • Labels are for display only (ambiguous)
  • Use identity/alternate/external for unique IDs

Registry API

The global predicate registry provides:

// Register a predicate
Register(name string, opts ...Option)

// Retrieve metadata
GetPredicateMetadata(name string) *PredicateMetadata

// List all registered
ListRegisteredPredicates() []string

// Discover aliases
DiscoverAliasPredicates() map[string]int

// Clear (testing only)
ClearRegistry()

Migration from Colon Notation

If you have legacy code using colon notation ("robotics:Drone"):

**Before:**

iri := vocabulary.EntityTypeIRI("robotics:Drone")

**After:**

// Use dotted notation everywhere
entityType := message.EntityType{Domain: "robotics", Type: "drone"}
typeStr := entityType.Key()  // "robotics.drone"

// IRI functions now accept dotted notation
iri := vocabulary.EntityTypeIRI(typeStr)

Design Philosophy Summary

The vocabulary package embodies these principles:

1. **Simplicity**: Dotted notation is clean and human-readable 2. **NATS-friendly**: Wildcards work naturally with dotted predicates 3. **Standards-compliant**: Optional IRI mappings at boundaries 4. **No Leakage**: External complexity stays external 5. **Customer Value**: Support RDF/OGC without internal cost

This "pragmatic semantic web" approach gives you:

  • Clean internal architecture
  • Standards compliance where needed
  • Customer integration support
  • NATS query power
  • Human-readable code

Package vocabulary provides semantic vocabulary definitions and mappings.

Index

Constants

View Source
const (
	SemStreamsBase  = "https://semstreams.semanticstream.ing"
	GraphNamespace  = SemStreamsBase + "/graph"
	SystemNamespace = SemStreamsBase + "/system"
)

Base IRI constants for the SemStreams vocabulary

View Source
const (
	// SensorTemperatureCelsius is float64, degrees Celsius
	SensorTemperatureCelsius = "sensor.temperature.celsius"
	// SensorTemperatureFahrenheit is float64, degrees Fahrenheit
	SensorTemperatureFahrenheit = "sensor.temperature.fahrenheit"
	// SensorTemperatureKelvin is float64, degrees Kelvin
	SensorTemperatureKelvin = "sensor.temperature.kelvin"

	// SensorPressurePascals is float64, pascals
	SensorPressurePascals = "sensor.pressure.pascals"
	// SensorPressureBar is float64, bar
	SensorPressureBar = "sensor.pressure.bar"
	// SensorPressurePsi is float64, pounds per square inch
	SensorPressurePsi = "sensor.pressure.psi"

	// SensorHumidityPercent is float64, 0-100 percentage
	SensorHumidityPercent = "sensor.humidity.percent"
	// SensorHumidityAbsolute is float64, g/m³
	SensorHumidityAbsolute = "sensor.humidity.absolute"

	// SensorAccelX is float64, m/s²
	SensorAccelX = "sensor.accel.x"
	// SensorAccelY is float64, m/s²
	SensorAccelY = "sensor.accel.y"
	// SensorAccelZ is float64, m/s²
	SensorAccelZ = "sensor.accel.z"

	// SensorGyroX is float64, rad/s
	SensorGyroX = "sensor.gyro.x"
	// SensorGyroY is float64, rad/s
	SensorGyroY = "sensor.gyro.y"
	// SensorGyroZ is float64, rad/s
	SensorGyroZ = "sensor.gyro.z"

	// SensorMagX is float64, gauss
	SensorMagX = "sensor.mag.x"
	// SensorMagY is float64, gauss
	SensorMagY = "sensor.mag.y"
	// SensorMagZ is float64, gauss
	SensorMagZ = "sensor.mag.z"
)
View Source
const (
	// GeoLocationLatitude is float64, degrees (-90 to 90)
	GeoLocationLatitude = "geo.location.latitude"
	// GeoLocationLongitude is float64, degrees (-180 to 180)
	GeoLocationLongitude = "geo.location.longitude"
	// GeoLocationAltitude is float64, meters above sea level
	GeoLocationAltitude = "geo.location.altitude"
	// GeoLocationElevation is float64, meters above ground
	GeoLocationElevation = "geo.location.elevation"

	// GeoVelocityGround is float64, m/s ground speed
	GeoVelocityGround = "geo.velocity.ground"
	// GeoVelocityVertical is float64, m/s climb/descent rate
	GeoVelocityVertical = "geo.velocity.vertical"
	// GeoVelocityHeading is float64, degrees (0-360)
	GeoVelocityHeading = "geo.velocity.heading"

	// GeoAccuracyHorizontal is float64, meters CEP
	GeoAccuracyHorizontal = "geo.accuracy.horizontal"
	// GeoAccuracyVertical is float64, meters vertical accuracy
	GeoAccuracyVertical = "geo.accuracy.vertical"
	// GeoAccuracyDilution is float64, dilution of precision
	GeoAccuracyDilution = "geo.accuracy.dilution"

	// GeoZoneUtm is string, UTM zone
	GeoZoneUtm = "geo.zone.utm"
	// GeoZoneMgrs is string, MGRS grid
	GeoZoneMgrs = "geo.zone.mgrs"
	// GeoZoneRegion is string, geographic region name
	GeoZoneRegion = "geo.zone.region"
)
View Source
const (
	// TimeLifecycleCreated is time.Time, when entity was created
	TimeLifecycleCreated = "time.lifecycle.created"
	// TimeLifecycleUpdated is time.Time, when entity was last updated
	TimeLifecycleUpdated = "time.lifecycle.updated"
	// TimeLifecycleSeen is time.Time, when entity was last observed
	TimeLifecycleSeen = "time.lifecycle.seen"
	// TimeLifecycleExpired is time.Time, when entity expired/deleted
	TimeLifecycleExpired = "time.lifecycle.expired"

	// TimeDurationActive is float64, seconds active
	TimeDurationActive = "time.duration.active"
	// TimeDurationIdle is float64, seconds idle
	TimeDurationIdle = "time.duration.idle"
	// TimeDurationTotal is float64, total seconds
	TimeDurationTotal = "time.duration.total"

	// TimeScheduleStart is time.Time, scheduled start
	TimeScheduleStart = "time.schedule.start"
	// TimeScheduleEnd is time.Time, scheduled end
	TimeScheduleEnd = "time.schedule.end"
	// TimeScheduleNext is time.Time, next scheduled event
	TimeScheduleNext = "time.schedule.next"
)
View Source
const (
	// NetworkConnectionStatus is string, connection status
	NetworkConnectionStatus = "network.connection.status"
	// NetworkConnectionStrength is float64, signal strength
	NetworkConnectionStrength = "network.connection.strength"
	// NetworkConnectionLatency is float64, milliseconds
	NetworkConnectionLatency = "network.connection.latency"

	// NetworkProtocolType is string, protocol name
	NetworkProtocolType = "network.protocol.type"
	// NetworkProtocolVersion is string, protocol version
	NetworkProtocolVersion = "network.protocol.version"
	// NetworkProtocolPort is int, port number
	NetworkProtocolPort = "network.protocol.port"

	// NetworkTrafficBytesIn is int64, bytes received
	NetworkTrafficBytesIn = "network.traffic.bytes.in"
	// NetworkTrafficBytesOut is int64, bytes sent
	NetworkTrafficBytesOut = "network.traffic.bytes.out"
	// NetworkTrafficPacketsIn is int64, packets received
	NetworkTrafficPacketsIn = "network.traffic.packets.in"
	// NetworkTrafficPacketsOut is int64, packets sent
	NetworkTrafficPacketsOut = "network.traffic.packets.out"
)
View Source
const (
	// QualityConfidenceScore is float64, 0-1 confidence level
	QualityConfidenceScore = "quality.confidence.score"
	// QualityConfidenceSource is string, source of confidence assessment
	QualityConfidenceSource = "quality.confidence.source"
	// QualityConfidenceMethod is string, confidence calculation method
	QualityConfidenceMethod = "quality.confidence.method"

	// QualityValidationStatus is string, validation status
	QualityValidationStatus = "quality.validation.status"
	// QualityValidationErrors is int, number of validation errors
	QualityValidationErrors = "quality.validation.errors"
	// QualityValidationWarnings is int, number of warnings
	QualityValidationWarnings = "quality.validation.warnings"

	// QualityAccuracyAbsolute is float64, absolute accuracy
	QualityAccuracyAbsolute = "quality.accuracy.absolute"
	// QualityAccuracyRelative is float64, relative accuracy percentage
	QualityAccuracyRelative = "quality.accuracy.relative"
	// QualityAccuracyPrecision is float64, measurement precision
	QualityAccuracyPrecision = "quality.accuracy.precision"
)
View Source
const (
	// GraphRelContains represents hierarchical containment (parent contains child)
	// Example: A platform contains sensors, a system contains components
	GraphRelContains = "graph.rel.contains"

	// GraphRelReferences represents directional reference (subject references object)
	// Example: Documentation references specifications, code references APIs
	GraphRelReferences = "graph.rel.references"

	// GraphRelInfluences represents causal or impact relationships
	// Example: A decision influences implementation, configuration influences behavior
	GraphRelInfluences = "graph.rel.influences"

	// GraphRelCommunicates represents communication or interaction relationships
	// Example: Services communicate, components interact
	GraphRelCommunicates = "graph.rel.communicates"

	// GraphRelNear represents spatial proximity relationships
	// Example: Sensors near a location, entities in the same area
	GraphRelNear = "graph.rel.near"

	// GraphRelTriggeredBy represents event causation
	// Example: An alert triggered by a threshold, action triggered by event
	GraphRelTriggeredBy = "graph.rel.triggered_by"

	// GraphRelDependsOn represents dependency relationships
	// Example: Specifications depend on other specs, modules depend on libraries
	GraphRelDependsOn = "graph.rel.depends_on"

	// GraphRelImplements represents implementation relationships
	// Example: Code implements specifications, components implement interfaces
	GraphRelImplements = "graph.rel.implements"

	// GraphRelDiscusses represents discussion or commentary relationships
	// Example: GitHub discussions discuss issues, comments discuss topics
	GraphRelDiscusses = "graph.rel.discusses"

	// GraphRelSupersedes represents replacement or versioning relationships
	// Example: New decisions supersede old ones, v2 supersedes v1
	GraphRelSupersedes = "graph.rel.supersedes"

	// GraphRelBlockedBy represents blocking relationships
	// Example: An issue blocked by another issue, work blocked by dependencies
	GraphRelBlockedBy = "graph.rel.blocked_by"

	// GraphRelRelatedTo represents general association relationships
	// Example: Related documents, related entities without specific semantics
	GraphRelRelatedTo = "graph.rel.related_to"
)
View Source
const (
	// HierarchyDomainMember indicates entity belongs to a domain (3-part prefix match).
	// Subject is the entity, object is the domain prefix (e.g., "c360.logistics.sensor").
	// StandardIRI: skos:broader (entity is narrower than domain)
	// InverseOf: HierarchyDomainContains
	// Example: sensor-temp-001 hierarchy.domain.member c360.logistics.sensor
	HierarchyDomainMember = "hierarchy.domain.member"

	// HierarchyDomainContains indicates domain contains an entity (inverse of HierarchyDomainMember).
	// Subject is the domain, object is the entity.
	// StandardIRI: skos:narrower (domain contains narrower entities)
	// InverseOf: HierarchyDomainMember
	// Example: c360.logistics.sensor hierarchy.domain.contains sensor-temp-001
	HierarchyDomainContains = "hierarchy.domain.contains"

	// HierarchySystemMember indicates entity belongs to a system (4-part prefix match).
	// Subject is the entity, object is the system prefix (e.g., "c360.logistics.sensor.document").
	// StandardIRI: skos:broader (entity is narrower than system)
	// InverseOf: HierarchySystemContains
	// Example: sensor-temp-001 hierarchy.system.member c360.logistics.sensor.document
	HierarchySystemMember = "hierarchy.system.member"

	// HierarchySystemContains indicates system contains an entity (inverse of HierarchySystemMember).
	// Subject is the system, object is the entity.
	// StandardIRI: skos:narrower (system contains narrower entities)
	// InverseOf: HierarchySystemMember
	// Example: c360.logistics.sensor.document hierarchy.system.contains sensor-temp-001
	HierarchySystemContains = "hierarchy.system.contains"

	// HierarchyTypeSibling indicates entities share the same type (5-part prefix match).
	// Bidirectional relationship between entities with same type prefix.
	// StandardIRI: skos:related (symmetric relationship)
	// IsSymmetric: true (if A is sibling of B, B is sibling of A)
	// Example: sensor-temp-001 hierarchy.type.sibling sensor-temp-002
	HierarchyTypeSibling = "hierarchy.type.sibling"

	// HierarchyTypeMember indicates entity belongs to a type container (5-part prefix + .group).
	// Subject is the entity, object is the type container entity ID.
	// StandardIRI: skos:broader (entity is narrower than type container)
	// InverseOf: HierarchyTypeContains
	// Example: acme.iot.sensors.hvac.temperature.001 hierarchy.type.member acme.iot.sensors.hvac.temperature.group
	HierarchyTypeMember = "hierarchy.type.member"

	// HierarchyTypeContains indicates type container contains an entity (inverse of HierarchyTypeMember).
	// Subject is the type container, object is the entity.
	// StandardIRI: skos:narrower (container contains narrower entities)
	// InverseOf: HierarchyTypeMember
	// Example: acme.iot.sensors.hvac.temperature.group hierarchy.type.contains acme.iot.sensors.hvac.temperature.001
	HierarchyTypeContains = "hierarchy.type.contains"
)
View Source
const (
	// OwlSameAs indicates that two URI references refer to the same entity.
	// Used for: AliasTypeIdentity
	// Example: "drone-001" owl:sameAs "c360.platform.test.drone.001"
	OwlSameAs = "http://www.w3.org/2002/07/owl#sameAs"

	// OwlEquivalentClass indicates equivalent classes
	OwlEquivalentClass = "http://www.w3.org/2002/07/owl#equivalentClass"

	// OwlEquivalentProperty indicates equivalent properties
	OwlEquivalentProperty = "http://www.w3.org/2002/07/owl#equivalentProperty"

	// OwlInverseOf indicates that two properties are inverse of each other.
	// Used to link predicates that represent opposite directions of a relationship.
	// Example: skos:broader owl:inverseOf skos:narrower
	OwlInverseOf = "http://www.w3.org/2002/07/owl#inverseOf"

	// OwlSymmetricProperty indicates a property where if A relates to B,
	// then B also relates to A with the same property.
	// Example: skos:related is symmetric (if A is related to B, B is related to A)
	OwlSymmetricProperty = "http://www.w3.org/2002/07/owl#SymmetricProperty"

	// OwlTransitiveProperty indicates a property where if A→B and B→C, then A→C.
	// Example: skos:broaderTransitive
	OwlTransitiveProperty = "http://www.w3.org/2002/07/owl#TransitiveProperty"

	// OwlReflexiveProperty indicates a property that always applies to itself.
	// Example: owl:sameAs is reflexive (everything is sameAs itself)
	OwlReflexiveProperty = "http://www.w3.org/2002/07/owl#ReflexiveProperty"
)

OWL (Web Ontology Language) Standard IRIs

View Source
const (
	// SkosPrefLabel provides the preferred lexical label for a resource.
	// Used for: AliasTypeLabel
	// Example: "Alpha Drone" is the preferred display name
	SkosPrefLabel = "http://www.w3.org/2004/02/skos/core#prefLabel"

	// SkosAltLabel provides an alternative lexical label for a resource.
	// Used for: AliasTypeLabel
	// Example: "Drone A", "Alpha", "UAV-001" are alternate labels
	SkosAltLabel = "http://www.w3.org/2004/02/skos/core#altLabel"

	// SkosHiddenLabel provides a label not intended for display but useful for search.
	// Example: Common misspellings, abbreviations
	SkosHiddenLabel = "http://www.w3.org/2004/02/skos/core#hiddenLabel"

	// SkosNotation provides a notation (code or identifier) within a concept scheme.
	// Used for: AliasTypeAlternate
	SkosNotation = "http://www.w3.org/2004/02/skos/core#notation"

	// SkosBroader indicates a hierarchical link to a more general concept.
	// Used for: hierarchy.*.member predicates (entity → container membership)
	// Example: sensor-001 skos:broader temperature-group (sensor is narrower than group)
	SkosBroader = "http://www.w3.org/2004/02/skos/core#broader"

	// SkosNarrower indicates a hierarchical link to a more specific concept.
	// Inverse of SkosBroader.
	// Example: temperature-group skos:narrower sensor-001 (group contains sensor)
	SkosNarrower = "http://www.w3.org/2004/02/skos/core#narrower"

	// SkosRelated indicates an associative (non-hierarchical) link between concepts.
	// Used for: hierarchy.type.sibling predicates (symmetric relationship)
	// Example: sensor-001 skos:related sensor-002 (siblings in same type group)
	SkosRelated = "http://www.w3.org/2004/02/skos/core#related"
)

SKOS (Simple Knowledge Organization System) Standard IRIs

View Source
const (
	// RdfsLabel provides a human-readable name for a resource.
	// Used for: AliasTypeLabel
	RdfsLabel = "http://www.w3.org/2000/01/rdf-schema#label"

	// RdfsComment provides a human-readable description
	RdfsComment = "http://www.w3.org/2000/01/rdf-schema#comment"

	// RdfsSeeAlso indicates a resource that provides additional information
	RdfsSeeAlso = "http://www.w3.org/2000/01/rdf-schema#seeAlso"
)

RDF Schema Standard IRIs

View Source
const (
	// DcIdentifier provides an unambiguous reference to the resource.
	// Used for: AliasTypeExternal
	// Example: ISBN, DOI, serial number
	DcIdentifier = "http://purl.org/dc/terms/identifier"

	// DcTitle provides the name given to the resource.
	// Used for: AliasTypeLabel
	DcTitle = "http://purl.org/dc/terms/title"

	// DcAlternative provides an alternative name for the resource.
	// Used for: AliasTypeAlternate
	DcAlternative = "http://purl.org/dc/terms/alternative"

	// DcSource indicates a related resource from which the described resource is derived.
	DcSource = "http://purl.org/dc/terms/source"
)

Dublin Core Metadata Terms Standard IRIs

View Source
const (
	// DCTermsTitle is the dotted notation predicate for resource title.
	// Maps to: DcTitle (http://purl.org/dc/terms/title)
	DCTermsTitle = "dc.terms.title"

	// DCTermsCreator is the dotted notation predicate for resource creator.
	// Maps to: http://purl.org/dc/terms/creator
	DCTermsCreator = "dc.terms.creator"

	// DCTermsIdentifier is the dotted notation predicate for resource identifier.
	// Maps to: DcIdentifier (http://purl.org/dc/terms/identifier)
	DCTermsIdentifier = "dc.terms.identifier"
)

Dublin Core Dotted Notation Predicates These constants provide dotted notation predicates for use in Triples. They map semantically to the Dublin Core IRIs above.

View Source
const (
	// SchemaName provides the name of the item.
	// Used for: AliasTypeLabel
	SchemaName = "https://schema.org/name"

	// SchemaAlternateName provides an alias for the item.
	// Used for: AliasTypeAlternate
	SchemaAlternateName = "https://schema.org/alternateName"

	// SchemaIdentifier provides a unique identifier for the item.
	// Used for: AliasTypeExternal
	SchemaIdentifier = "https://schema.org/identifier"

	// SchemaSameAs indicates a URL that unambiguously indicates the item's identity.
	// Used for: AliasTypeIdentity
	SchemaSameAs = "https://schema.org/sameAs"
)

Schema.org Standard IRIs

View Source
const (
	// ProvEntity is a physical, digital, conceptual, or other kind of thing
	// with some fixed aspects. Entities can be real or imaginary.
	// Examples: a document, a dataset, a concept, a physical object
	ProvEntity = ProvNamespace + "Entity"

	// ProvActivity is something that occurs over a period of time and acts upon
	// or with entities. It may include consuming, processing, transforming,
	// modifying, relocating, using, or generating entities.
	// Examples: a workflow execution, a file edit, a data transformation
	ProvActivity = ProvNamespace + "Activity"

	// ProvAgent is something that bears some form of responsibility for an
	// activity taking place, for the existence of an entity, or for another
	// agent's activity.
	// Examples: a person, an organization, a software agent
	ProvAgent = ProvNamespace + "Agent"
)

PROV-O Core Classes The three fundamental types in PROV-O provenance model.

View Source
const (
	// ProvPlan is a set of actions or steps intended by one or more agents
	// to achieve some goals.
	// Examples: a mission plan, a workflow definition
	ProvPlan = ProvNamespace + "Plan"

	// ProvCollection is an entity that provides a structure to group other entities.
	// Examples: a dataset, a folder, a fleet
	ProvCollection = ProvNamespace + "Collection"

	// ProvBundle is a named set of provenance descriptions. It is itself an entity
	// so that its provenance can be described.
	// Examples: a provenance graph, a set of related provenance statements
	ProvBundle = ProvNamespace + "Bundle"

	// ProvEmptyCollection is a collection without any members.
	ProvEmptyCollection = ProvNamespace + "EmptyCollection"

	// ProvLocation is a location that is relevant to an entity.
	// Examples: a geographic location, a URL, a file path
	ProvLocation = ProvNamespace + "Location"

	// ProvSoftwareAgent is a running software agent.
	// Examples: a microservice, a daemon process
	ProvSoftwareAgent = ProvNamespace + "SoftwareAgent"

	// ProvPerson is a person agent.
	ProvPerson = ProvNamespace + "Person"

	// ProvOrganization is an organization agent.
	ProvOrganization = ProvNamespace + "Organization"
)

PROV-O Extended Classes Additional entity and activity subtypes.

View Source
const (
	// ProvWasAttributedTo indicates who an entity was attributed to.
	// Domain: Entity, Range: Agent
	ProvWasAttributedTo = ProvNamespace + "wasAttributedTo"

	// ProvWasDerivedFrom indicates a derivation relationship.
	// Domain: Entity, Range: Entity
	// Example: processedData wasDerivedFrom rawData
	ProvWasDerivedFrom = ProvNamespace + "wasDerivedFrom"

	// ProvHadPrimarySource indicates a primary source.
	// A primary source is a specialized derivation for sources.
	// Domain: Entity, Range: Entity
	ProvHadPrimarySource = ProvNamespace + "hadPrimarySource"

	// ProvWasQuotedFrom indicates the entity was quoted from another entity.
	// Domain: Entity, Range: Entity
	ProvWasQuotedFrom = ProvNamespace + "wasQuotedFrom"

	// ProvWasRevisionOf indicates the entity is a revised version of another.
	// Domain: Entity, Range: Entity
	ProvWasRevisionOf = ProvNamespace + "wasRevisionOf"
)

PROV-O Derivation Relations Relations expressing how entities derive from other entities.

View Source
const (
	// ProvWasGeneratedBy indicates an entity was generated by an activity.
	// Domain: Entity, Range: Activity
	// Example: report wasGeneratedBy analysisActivity
	ProvWasGeneratedBy = ProvNamespace + "wasGeneratedBy"

	// ProvGenerated indicates an activity generated an entity (inverse of wasGeneratedBy).
	// Domain: Activity, Range: Entity
	ProvGenerated = ProvNamespace + "generated"

	// ProvUsed indicates an activity used an entity.
	// Domain: Activity, Range: Entity
	// Example: transformActivity used inputData
	ProvUsed = ProvNamespace + "used"

	// ProvWasInvalidatedBy indicates an entity was invalidated by an activity.
	// Domain: Entity, Range: Activity
	ProvWasInvalidatedBy = ProvNamespace + "wasInvalidatedBy"

	// ProvInvalidated indicates an activity invalidated an entity.
	// Domain: Activity, Range: Entity
	ProvInvalidated = ProvNamespace + "invalidated"
)

PROV-O Generation and Usage Relations Relations expressing how entities are generated and used by activities.

View Source
const (
	// ProvWasAssociatedWith indicates an activity was associated with an agent.
	// Domain: Activity, Range: Agent
	// Example: missionActivity wasAssociatedWith pilotAgent
	ProvWasAssociatedWith = ProvNamespace + "wasAssociatedWith"

	// ProvActedOnBehalfOf indicates an agent acted on behalf of another agent.
	// Domain: Agent, Range: Agent
	// Example: droneAgent actedOnBehalfOf operatorAgent
	ProvActedOnBehalfOf = ProvNamespace + "actedOnBehalfOf"

	// ProvHadMember indicates membership in a collection.
	// Domain: Collection, Range: Entity
	// Used for: GraphRelContains
	ProvHadMember = ProvNamespace + "hadMember"
)

PROV-O Association Relations Relations expressing how agents are associated with activities.

View Source
const (
	// ProvWasInfluencedBy indicates one element was influenced by another.
	// Most other PROV-O relations are specializations of this.
	// Domain: Entity|Activity|Agent, Range: Entity|Activity|Agent
	ProvWasInfluencedBy = ProvNamespace + "wasInfluencedBy"

	// ProvInfluenced indicates one element influenced another (inverse).
	// Domain: Entity|Activity|Agent, Range: Entity|Activity|Agent
	ProvInfluenced = ProvNamespace + "influenced"

	// ProvWasInformedBy indicates an activity was informed by another activity.
	// The first activity used an entity generated by the second.
	// Domain: Activity, Range: Activity
	ProvWasInformedBy = ProvNamespace + "wasInformedBy"

	// ProvWasStartedBy indicates an activity was started by an entity.
	// Domain: Activity, Range: Entity
	ProvWasStartedBy = ProvNamespace + "wasStartedBy"

	// ProvWasEndedBy indicates an activity was ended by an entity.
	// Domain: Activity, Range: Entity
	ProvWasEndedBy = ProvNamespace + "wasEndedBy"

	// ProvHadActivity indicates a qualified relation had an activity.
	// Used in qualified influence patterns.
	ProvHadActivity = ProvNamespace + "hadActivity"
)

PROV-O Influence Relations General influence relations between provenance elements.

View Source
const (
	// ProvQualifiedGeneration links an entity to its qualified generation.
	// Domain: Entity, Range: Generation
	ProvQualifiedGeneration = ProvNamespace + "qualifiedGeneration"

	// ProvQualifiedUsage links an activity to its qualified usage.
	// Domain: Activity, Range: Usage
	ProvQualifiedUsage = ProvNamespace + "qualifiedUsage"

	// ProvQualifiedAssociation links an activity to its qualified association.
	// Domain: Activity, Range: Association
	ProvQualifiedAssociation = ProvNamespace + "qualifiedAssociation"

	// ProvQualifiedDerivation links an entity to its qualified derivation.
	// Domain: Entity, Range: Derivation
	ProvQualifiedDerivation = ProvNamespace + "qualifiedDerivation"

	// ProvQualifiedAttribution links an entity to its qualified attribution.
	// Domain: Entity, Range: Attribution
	ProvQualifiedAttribution = ProvNamespace + "qualifiedAttribution"

	// ProvQualifiedDelegation links an agent to its qualified delegation.
	// Domain: Agent, Range: Delegation
	ProvQualifiedDelegation = ProvNamespace + "qualifiedDelegation"

	// ProvQualifiedInfluence links to a qualified influence.
	ProvQualifiedInfluence = ProvNamespace + "qualifiedInfluence"

	// ProvHadPlan links an association to the plan that was followed.
	// Domain: Association, Range: Plan
	ProvHadPlan = ProvNamespace + "hadPlan"

	// ProvHadRole links a qualified relation to the role played.
	// Domain: Influence, Range: Role
	ProvHadRole = ProvNamespace + "hadRole"
)

PROV-O Qualified Relations Properties used in qualified influence patterns for detailed provenance.

View Source
const (
	// ProvStartedAtTime indicates when an activity started.
	// Domain: Activity, Range: xsd:dateTime
	ProvStartedAtTime = ProvNamespace + "startedAtTime"

	// ProvEndedAtTime indicates when an activity ended.
	// Domain: Activity, Range: xsd:dateTime
	ProvEndedAtTime = ProvNamespace + "endedAtTime"

	// ProvGeneratedAtTime indicates when an entity was generated.
	// Domain: Entity, Range: xsd:dateTime
	ProvGeneratedAtTime = ProvNamespace + "generatedAtTime"

	// ProvInvalidatedAtTime indicates when an entity was invalidated.
	// Domain: Entity, Range: xsd:dateTime
	ProvInvalidatedAtTime = ProvNamespace + "invalidatedAtTime"

	// ProvAtTime indicates when an instantaneous event occurred.
	// Domain: InstantaneousEvent, Range: xsd:dateTime
	ProvAtTime = ProvNamespace + "atTime"
)

PROV-O Time Properties Properties for expressing when activities occurred and entities existed.

View Source
const (
	// DcReferences indicates a related resource that is referenced by the described resource
	// Used for: GraphRelReferences
	DcReferences = "http://purl.org/dc/terms/references"

	// DcIsReferencedBy indicates a related resource that references the described resource
	// Inverse of DcReferences
	DcIsReferencedBy = "http://purl.org/dc/terms/isReferencedBy"

	// DcRequires indicates a related resource that is required by the described resource
	// Used for: GraphRelDependsOn
	DcRequires = "http://purl.org/dc/terms/requires"

	// DcIsRequiredBy indicates a related resource that requires the described resource
	// Inverse of DcRequires
	DcIsRequiredBy = "http://purl.org/dc/terms/isRequiredBy"

	// DcReplaces indicates a related resource that is supplanted by the described resource
	// Used for: GraphRelSupersedes
	DcReplaces = "http://purl.org/dc/terms/replaces"

	// DcIsReplacedBy indicates a related resource that supplants the described resource
	// Inverse of DcReplaces
	DcIsReplacedBy = "http://purl.org/dc/terms/isReplacedBy"

	// DcRelation indicates a related resource (generic relationship)
	// Used for: GraphRelRelatedTo
	DcRelation = "http://purl.org/dc/terms/relation"
)

Dublin Core Relations Standard IRIs

View Source
const (
	// SchemaAbout indicates the subject matter of the content
	// Used for: GraphRelDiscusses
	SchemaAbout = "http://schema.org/about"

	// SchemaIsPartOf indicates that this item is part of something else
	SchemaIsPartOf = "http://schema.org/isPartOf"

	// SchemaHasPart indicates that something is part of this item
	// Used for: GraphRelContains
	SchemaHasPart = "http://schema.org/hasPart"
)

Schema.org Relationship IRIs

View Source
const (
	// FoafName provides a person's or thing's name
	// Used for: AliasTypeLabel
	FoafName = "http://xmlns.com/foaf/0.1/name"

	// FoafNick provides a short informal nickname
	// Used for: AliasTypeAlternate
	FoafNick = "http://xmlns.com/foaf/0.1/nick"

	// FoafAccountName provides an account name
	// Used for: AliasTypeCommunication
	FoafAccountName = "http://xmlns.com/foaf/0.1/accountName"
)

FOAF (Friend of a Friend) Standard IRIs

View Source
const (
	// SsnHasDeployment indicates where/when a system is deployed
	SsnHasDeployment = "http://www.w3.org/ns/ssn/hasDeployment"

	// SosaObserves indicates what property a sensor observes
	SosaObserves = "http://www.w3.org/ns/sosa/observes"

	// SosaHasSimpleResult provides the simple result value
	SosaHasSimpleResult = "http://www.w3.org/ns/sosa/hasSimpleResult"
)

SSN (Semantic Sensor Network Ontology) Standard IRIs Useful for IoT and robotics applications

View Source
const (
	// ProvAtLocation indicates where an instantaneous event occurred.
	// Domain: Entity|Activity, Range: Location
	ProvAtLocation = ProvNamespace + "atLocation"
)

PROV-O Location Properties Properties for expressing where activities occurred.

View Source
const (
	// ProvNamespace is the base IRI prefix for all PROV-O terms.
	ProvNamespace = "http://www.w3.org/ns/prov#"
)

PROV-O Namespace

View Source
const (
	// ProvValue provides a direct representation of an entity's value.
	// Domain: Entity, Range: any
	ProvValue = ProvNamespace + "value"
)

PROV-O Value Properties Properties for expressing values.

Variables

This section is empty.

Functions

func ClearRegistry

func ClearRegistry()

ClearRegistry clears all registered predicates. This is primarily useful for testing.

func DiscoverAliasPredicates

func DiscoverAliasPredicates() map[string]int

DiscoverAliasPredicates discovers all predicates marked as aliases in the registry. Returns a map of predicate name to priority (lower number = higher priority). Used by AliasIndex to determine which predicates to index.

If no alias predicates are registered, returns an empty map. Applications must register their domain-specific alias predicates using RegisterPredicate().

func DiscoverInversePredicates

func DiscoverInversePredicates() map[string]string

DiscoverInversePredicates returns all predicates that have inverses defined. Returns a map where keys are predicate names and values are their inverse predicate names. For symmetric predicates, the value equals the key.

This function is useful for:

  • Debugging and introspection
  • Generating documentation about predicate relationships
  • Reasoning systems that need to traverse relationships bidirectionally

Example output:

{
    "hierarchy.type.member": "hierarchy.type.contains",
    "hierarchy.type.contains": "hierarchy.type.member",
    "hierarchy.type.sibling": "hierarchy.type.sibling",  // symmetric
}

func EntityIRI

func EntityIRI(dottedType string, platform config.PlatformConfig, localID string) string

EntityIRI generates an IRI for a specific entity instance for RDF export. This creates a unique identifier for entities in federated scenarios.

Input format: "domain.type" using EntityType.Key() (e.g., "robotics.drone") Output format: "https://semstreams.semanticstream.ing/entities/{platform_id}[/{region}]/{domain}/{type}/{local_id}"

This function is intended for RDF/Turtle export at API boundaries only. Internal code should always use EntityID.Key() for dotted notation.

Examples:

Returns empty string if platform.ID, localID is empty, or dottedType is invalid.

Example:

entityType := message.EntityType{Domain: "robotics", Type: "drone"}
iri := EntityIRI(entityType.Key(), platform, "drone_001")

func EntityTypeIRI

func EntityTypeIRI(dottedType string) string

EntityTypeIRI converts a dotted entity type to an IRI format for RDF export.

Input format: "domain.type" using EntityType.Key() (e.g., "robotics.drone") Output format: "https://semstreams.semanticstream.ing#type"

This function is intended for RDF/Turtle export at API boundaries only. Internal code should always use dotted notation.

Returns empty string for invalid input formats.

Example:

entityType := message.EntityType{Domain: "robotics", Type: "drone"}
iri := EntityTypeIRI(entityType.Key())  // "https://semstreams.semanticstream.ing/robotics#drone"

func GetInversePredicate

func GetInversePredicate(predicate string) string

GetInversePredicate returns the inverse predicate name, if defined. Returns an empty string if no inverse is defined for the given predicate.

For symmetric predicates (IsSymmetric=true), returns the predicate itself since symmetric predicates are their own inverse.

Example:

GetInversePredicate("hierarchy.type.member")   // Returns "hierarchy.type.contains"
GetInversePredicate("hierarchy.type.sibling")  // Returns "hierarchy.type.sibling" (symmetric)
GetInversePredicate("sensor.temperature.celsius")  // Returns "" (no inverse)

func HasInverse

func HasInverse(predicate string) bool

HasInverse checks if a predicate has an inverse defined (either explicit or symmetric). Returns true if the predicate is symmetric or has an InverseOf set.

func IsSymmetricPredicate

func IsSymmetricPredicate(predicate string) bool

IsSymmetricPredicate checks if a predicate is symmetric. Symmetric predicates represent bidirectional relationships where if A relates to B, then B also relates to A with the same predicate.

Returns false if the predicate is not registered or is not symmetric.

func IsValidPredicate

func IsValidPredicate(predicate string) bool

IsValidPredicate checks if a predicate follows the three-level dotted notation and matches the expected format: domain.category.property

func ListRegisteredPredicates

func ListRegisteredPredicates() []string

ListRegisteredPredicates returns a list of all registered predicate names. Useful for debugging and introspection.

func Register

func Register(name string, opts ...Option)

Register registers a predicate with its metadata in the global registry. This should be called during package initialization (init functions) by domain vocabularies.

The predicate name must follow three-level dotted notation: domain.category.property

If a predicate is already registered, it will be overwritten (enables domain-specific overrides).

Example:

Register("robotics.battery.level",
    WithDescription("Battery charge level percentage"),
    WithDataType("float64"),
    WithUnits("percent"),
    WithRange("0-100"),
    WithIRI("http://schema.org/batteryLevel"))

func RegisterPredicate

func RegisterPredicate(meta PredicateMetadata)

RegisterPredicate registers a predicate using the PredicateMetadata struct directly. This function is provided for backward compatibility and testing. New code should use Register() with functional options. Allows overriding framework defaults.

func RelationshipIRI

func RelationshipIRI(relType string) string

RelationshipIRI converts relationship types to IRI format. Handles various naming conventions and converts them to kebab-case.

Examples:

Returns empty string for empty input.

func SubjectIRI

func SubjectIRI(subject string) string

SubjectIRI converts NATS subject strings to IRI format. Converts dot-separated subjects to path-separated IRIs.

Examples:

Returns empty string for empty input or malformed subjects (leading/trailing dots).

Types

type AliasType

type AliasType string

AliasType defines the semantic meaning of an alias predicate.

Each type corresponds to standard W3C/RDF vocabularies for semantic web interoperability. See vocabulary/standards.go for IRI constants to use in PredicateMetadata.StandardIRI.

const (
	// AliasTypeIdentity represents entity equivalence.
	//
	// Standard Mappings:
	//   - owl:sameAs (OWL_SAME_AS)
	//   - schema:sameAs (SCHEMA_SAME_AS)
	//
	// Used for: Federated entity IDs, external system UUIDs, cross-system identity
	// Resolution: ✅ Can resolve to entity IDs
	// Example: "uuid:abc-123" identifies the same entity as "c360.platform.test.drone.001"
	AliasTypeIdentity AliasType = "identity"

	// AliasTypeLabel represents human-readable display names.
	//
	// Standard Mappings:
	//   - skos:prefLabel (SKOS_PREF_LABEL) - preferred label
	//   - skos:altLabel (SKOS_ALT_LABEL) - alternative label
	//   - rdfs:label (RDFS_LABEL) - generic label
	//   - dc:title (DC_TITLE) - title
	//   - schema:name (SCHEMA_NAME) - name
	//   - foaf:name (FOAF_NAME) - name
	//
	// Used for: Display names, titles, human-readable descriptions
	// Resolution: ❌ NOT used for entity resolution (ambiguous - many entities can share labels)
	// Example: "Alpha Drone", "Battery 1" - for display only
	AliasTypeLabel AliasType = "label"

	// AliasTypeAlternate represents secondary unique identifiers.
	//
	// Standard Mappings:
	//   - schema:alternateName (SCHEMA_ALTERNATE_NAME)
	//   - dc:alternative (DC_ALTERNATIVE)
	//   - skos:notation (SKOS_NOTATION)
	//   - foaf:nick (FOAF_NICK)
	//
	// Used for: Model numbers, registration IDs, alternative unique identifiers
	// Resolution: ✅ Can resolve to entity IDs
	// Example: "MODEL-X1000", "REG-12345"
	AliasTypeAlternate AliasType = "alternate"

	// AliasTypeExternal represents external system identifiers.
	//
	// Standard Mappings:
	//   - dc:identifier (DC_IDENTIFIER)
	//   - schema:identifier (SCHEMA_IDENTIFIER)
	//   - dc:source (DC_SOURCE)
	//
	// Used for: Manufacturer serial numbers, legacy system IDs, third-party references
	// Resolution: ✅ Can resolve to entity IDs
	// Example: "SN-12345", "LEGACY-DB-ID-789", "VENDOR-REF-456"
	AliasTypeExternal AliasType = "external"

	// AliasTypeCommunication represents communication system identifiers.
	//
	// Standard Mappings:
	//   - foaf:accountName (FOAF_ACCOUNT_NAME)
	//
	// Used for: Radio call signs, network hostnames, MQTT client IDs, communication endpoints
	// Resolution: ✅ Can resolve to entity IDs
	// Example: "ALPHA-1" (call sign), "drone.local" (hostname), "mqtt-client-001"
	AliasTypeCommunication AliasType = "communication"
)

func (AliasType) CanResolveToEntityID

func (at AliasType) CanResolveToEntityID() bool

CanResolveToEntityID returns true if this alias type can be used for entity resolution

func (AliasType) String

func (at AliasType) String() string

String returns the string representation of the alias type

type Option

type Option func(*PredicateMetadata)

Option is a functional option for configuring predicate registration.

func WithAlias

func WithAlias(aliasType AliasType, priority int) Option

WithAlias marks this predicate as representing an entity alias. Aliases are used for entity resolution and identity correlation.

Parameters:

  • aliasType: The semantic meaning (identity, alternate, external, communication, label)
  • priority: Conflict resolution order (lower number = higher priority)

Example:

Register("robotics.communication.callsign",
    WithAlias(AliasTypeCommunication, 0))  // Highest priority

func WithDataType

func WithDataType(dataType string) Option

WithDataType sets the expected Go type for the object value. Examples: "string", "float64", "int", "bool", "time.Time"

func WithDescription

func WithDescription(desc string) Option

WithDescription sets the human-readable description of the predicate.

func WithIRI

func WithIRI(iri string) Option

WithIRI sets the W3C/RDF equivalent IRI for standards compliance. This enables RDF/JSON-LD export and semantic web interoperability. Use constants from standards.go for common vocabularies.

Examples:

func WithInverseOf

func WithInverseOf(inversePredicate string) Option

WithInverseOf declares the inverse predicate name. The inverse predicate should also be registered with its own metadata, pointing back to this predicate as its inverse.

Example:

Register("hierarchy.type.member",
    WithIRI(SkosBroader),
    WithInverseOf("hierarchy.type.contains"))

Register("hierarchy.type.contains",
    WithIRI(SkosNarrower),
    WithInverseOf("hierarchy.type.member"))

Note: The registry stores the inverse relationship but does not auto-generate inverse triples at runtime. Applications can use GetInversePredicate() to look up the inverse name for display or reasoning purposes.

func WithRange

func WithRange(valueRange string) Option

WithRange describes valid value ranges (if applicable). Examples: "0-100", "-90 to 90", "positive"

func WithSymmetric

func WithSymmetric(symmetric bool) Option

WithSymmetric marks the predicate as symmetric (its own inverse). Symmetric predicates imply bidirectional relationships: if A relates to B, then B relates to A with the same predicate.

Example:

Register("hierarchy.type.sibling",
    WithIRI(SkosRelated),
    WithSymmetric(true))

When IsSymmetric is true, GetInversePredicate() returns the predicate itself. Do not set both WithSymmetric(true) and WithInverseOf() on the same predicate.

func WithUnits

func WithUnits(units string) Option

WithUnits specifies the measurement units (if applicable). Examples: "percent", "meters", "celsius", "pascals"

type PredicateMetadata

type PredicateMetadata struct {
	// Name is the predicate constant (e.g., "sensor.temperature.celsius")
	// Uses dotted notation for NATS stream query compatibility
	Name string

	// Description provides human-readable documentation
	Description string

	// DataType indicates the expected Go type for the object value
	DataType string

	// Units specifies the measurement units (if applicable)
	Units string

	// Range describes valid value ranges (if applicable)
	Range string

	// Domain identifies which domain owns this predicate
	Domain string

	// Category identifies the predicate category within the domain
	Category string

	// StandardIRI provides the W3C/RDF equivalent IRI for standards compliance (optional)
	// Examples: "http://www.w3.org/2002/07/owl#sameAs", "http://www.w3.org/2004/02/skos/core#prefLabel"
	// This enables RDF/JSON-LD export and semantic web interoperability while maintaining
	// dotted notation for NATS compatibility internally.
	// See vocabulary/standards.go for common constants.
	StandardIRI string

	// Alias semantics (for entity resolution and alias indexing)
	// IsAlias marks predicates that represent entity aliases
	IsAlias bool

	// AliasType defines the semantic meaning (identity, label, external, etc.)
	// Only meaningful when IsAlias is true. See AliasType documentation for
	// standard vocabulary mappings (OWL, SKOS, Schema.org).
	AliasType AliasType

	// AliasPriority defines conflict resolution order (lower number = higher priority)
	// Only meaningful when IsAlias is true
	AliasPriority int

	// InverseOf names the predicate that represents the inverse relationship.
	// Example: "hierarchy.type.member" has InverseOf = "hierarchy.type.contains"
	// When entity A → hierarchy.type.member → B, the inverse relationship is
	// B → hierarchy.type.contains → A.
	//
	// Important: Both predicates in an inverse pair should be registered with
	// their InverseOf pointing to each other. The registry stores relationships;
	// it does not auto-generate inverse triples at runtime.
	//
	// StandardIRI equivalent: owl:inverseOf
	InverseOf string

	// IsSymmetric indicates the predicate is its own inverse.
	// Example: "hierarchy.type.sibling" - if A is sibling of B, then B is sibling of A.
	// Symmetric predicates don't need InverseOf set; GetInversePredicate() returns
	// the predicate itself for symmetric cases.
	//
	// StandardIRI equivalent: owl:SymmetricProperty
	IsSymmetric bool
}

PredicateMetadata provides semantic information about each predicate This enables validation, type checking, and documentation generation

func GetPredicateMetadata

func GetPredicateMetadata(predicate string) *PredicateMetadata

GetPredicateMetadata retrieves metadata for a predicate from the registry. Returns nil if the predicate is not registered. This function is thread-safe and can be called concurrently.

Directories

Path Synopsis
Package agentic provides vocabulary constants for AI agent interoperability.
Package agentic provides vocabulary constants for AI agent interoperability.
Package bfo provides IRI constants for the Basic Formal Ontology (BFO) 2.0.
Package bfo provides IRI constants for the Basic Formal Ontology (BFO) 2.0.
Package cco provides IRI constants for the Common Core Ontologies (CCO).
Package cco provides IRI constants for the Common Core Ontologies (CCO).
Package examples provides reference vocabulary implementations.
Package examples provides reference vocabulary implementations.
Package export serializes []message.Triple to standard RDF formats.
Package export serializes []message.Triple to standard RDF formats.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL