Project

sdu_smart

0.0
The project is in a healthy, maintained state
Ruby gem providing the SmartSDU Core Ontology information model. Includes Entity, Provision, TermEntry, PublicationDocument, SKOS taxonomy instances, and RDF namespace modules. Built on lutaml-model with Turtle and JSON-LD serialization support.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Runtime

~> 0.8.11
 Project Readme

SDU SMART Core Ontology (sdu_smart)

Table of Contents
  • Purpose
  • Installation
  • Quick start
    • Create entities
    • Create term entries
    • Create annotations
    • Track provenance
    • Serialize to Turtle
    • Round-trip serialization
    • Use taxonomies
  • Architecture
    • Class hierarchy
    • Entity base class
    • Provision subtypes
    • TermEntry
    • Annotation model
    • Provenance model
    • Taxonomy classes
    • RDF namespaces
    • Extension pattern for domain gems
  • Development
  • Contributing
  • Copyright and license

Purpose

sdu_smart provides the SmartSDU Core Ontology information model as a Ruby gem. It models the entities found in standards documents — provisions, terms, clauses, publications, agents — and serializes them to RDF formats (Turtle, JSON-LD).

Domain gems (e.g. isq for ISO/IEC 80000) extend the base classes with domain-specific subclasses.

Key features:

  • Entity model: Provision, Clause, TermEntry, PublicationDocument, Agent, Activity

  • Annotation model: Annotation, SpecificResource, Selector (W3C Web Annotation)

  • Provenance model: Derivation (prov:Derivation)

  • SKOS taxonomies: Controlled vocabularies for bindingness, provision types, term forms

  • RDF serialization: Turtle output and round-trip parsing via rdf do mapping blocks

  • Extensible: Domain gems subclass TermEntry and Provision for domain-specific types

Built on the lutaml-model framework.

Installation

Add to your Gemfile:

gem "sdu_smart", "~> 0.1.0"

Then execute:

$ bundle install

Or install directly:

$ gem install sdu_smart

Quick start

Create entities

require "sdu_smart"

doc = SduSmart::PublicationDocument.new(
  id: "iso-80000-1",
  publication_type: "internationalStandard",
  issued: "2022",
)

clause = SduSmart::Clause.new(
  id: "clause-4",
  title: "Quantities",
  section_number: "4",
  bindingness_type: "normative",
)

term = SduSmart::Term.new(
  id: "term-length",
  pronunciation: "lengθ",
  term_form_type: "fullForm",
)

Create term entries

entry = SduSmart::TermEntry.new(
  id: "te-length",
  definition: "extent of something from end to end",
  identifier: "3-1",
  pref_label: ["term-length"],
  alt_label: ["term-len"],
  scope_note: "Applies to vector quantities",
  bindingness_type: "normative",
  is_part_of: "clause-3-1",
)

Create annotations

Annotations link provisions to specific locations in documents:

selector = SduSmart::Selector.new(
  id: "sel-4-1",
  value: "xpath:///p[1]",
)

resource = SduSmart::SpecificResource.new(
  id: "sr-4-1",
  has_source: "iso-80000-1",
  has_selector: "sel-4-1",
)

annotation = SduSmart::Annotation.new(
  id: "ann-4-1",
  has_target: "sr-4-1",
  has_body: "prov-4-1",
)

Track provenance

derivation = SduSmart::Derivation.new(
  id: "deriv-length",
  entity: "iso-80000-3-2006",
  change_note: "Updated definition from 2006 edition",
)

Serialize to Turtle

puts doc.to_turtle
# <https://w3id.org/standards/smart/ontologies/core/iso-80000-1>
#   a smart:PublicationDocument ;
#   smart:hasPublicationType "internationalStandard" ;
#   dcterms:issued "2022" .

puts clause.to_turtle
# <https://w3id.org/standards/smart/ontologies/core/clause-4>
#   a smart:Clause ;
#   smart:hasBindingnessType "normative" ;
#   smart:hasSectionNumber "4" ;
#   dcterms:title "Quantities" .

puts annotation.to_turtle
# <https://w3id.org/standards/smart/ontologies/core/ann-4-1>
#   a oa:Annotation ;
#   oa:hasTarget "sr-4-1" ;
#   oa:hasBody "prov-4-1" .

Round-trip serialization

turtle = doc.to_turtle
restored = SduSmart::PublicationDocument.from_turtle(turtle)
restored.publication_type  # => "internationalStandard"
restored.issued            # => "2022"

turtle = entry.to_turtle
restored = SduSmart::TermEntry.from_turtle(turtle)
restored.definition        # => "extent of something from end to end"
restored.identifier        # => "3-1"

Use taxonomies

# Create via constructor
bt = SduSmart::Taxonomy::BindingnessType.new(label: "normative")
puts bt.to_turtle
# <https://w3id.org/standards/smart/taxonomies/bindingness-type/normative>
#   a smart:BindingnessType ;
#   skos:prefLabel "normative" .

# Create via validated factory
bt = SduSmart::Taxonomy::BindingnessType.fetch("normative")
bt.label  # => "normative"

SduSmart::Taxonomy::BindingnessType.fetch("invalid")
# => ArgumentError: invalid value 'invalid'. Valid: normative, informative

# Valid values are defined as constants
SduSmart::Taxonomy::BindingnessType::VALUES
# => ["normative", "informative"]

Architecture

Class hierarchy

All model classes inherit from Lutaml::Model::Serializable. Entity subclasses go through SduSmart::Entity; non-Entity classes (annotation, provenance) and taxonomy concepts inherit directly from Serializable:

Lutaml::Model::Serializable
├── SduSmart::Entity
│   ├── Provision (abstract)
│   │   ├── Statement
│   │   ├── Instruction
│   │   ├── Requirement
│   │   ├── Recommendation
│   │   ├── Permission
│   │   ├── Capability
│   │   ├── Possibility
│   │   └── ExternalConstraint
│   ├── ProvisionSet
│   │   └── Clause
│   ├── ProvisionSupplement
│   ├── TermEntry          ← extended by domain gems (e.g. isq)
│   ├── Term
│   ├── PublicationDocument
│   ├── Agent
│   │   └── Organization
│   └── Activity
├── SduSmart::Annotation       (oa:Annotation)
├── SduSmart::SpecificResource  (oa:SpecificResource)
├── SduSmart::Selector          (oa:Selector)
├── SduSmart::Derivation        (prov:Derivation)
└── SduSmart::Taxonomy::Concept
    ├── BindingnessType
    ├── ProvisionType
    ├── PublicationComponentType
    ├── PublicationDocumentType
    ├── ProvisionSupplementType
    ├── PartOfSpeechType
    └── TermFormType

Entity base class

SduSmart::Entity (lib/sdu_smart/entity.rb) is the root of the entity hierarchy. It declares attribute :id and sets the RDF subject pattern:

https://w3id.org/standards/smart/ontologies/core/{id}

Every subclass inherits this subject pattern and adds its own rdf:type and predicates via rdf do blocks.

Provision subtypes

The 8 concrete provision subtypes (Statement, Requirement, etc.) share the same attributes (bindingness_type, provision_type, is_part_of, distribution, etc.) but each declares a distinct rdf:type (e.g. smart:Statement, smart:Requirement).

TermEntry

TermEntry models a terminological entry — the root element of a concept definition. It carries a rich set of predicates from the SHACL shapes:

  • skos:definition — concept definition

  • dcterms:identifier — entry identifier (e.g. clause number)

  • skos:scopeNote — scope clarification

  • skosxl:prefLabel / skosxl:altLabel — preferred and alternative terms (IRI references to Term)

  • smart:deprecatedLabel — deprecated term labels (IRI references to Term)

  • prov:qualifiedDerivation — provenance chain (IRI references to Derivation)

  • smart:hasBindingnessType — bindingness classification

  • dcterms:isPartOf — parent clause or document

Domain gems subclass TermEntry to add domain-specific attributes and RDF types.

Annotation model

The W3C Web Annotation model links provisions to specific locations in publication documents. These classes inherit from Lutaml::Model::Serializable directly (not Entity) since their RDF types use the oa: namespace:

  • Annotation (oa:Annotation) — links a target (SpecificResource) to a body (Provision)

  • SpecificResource (oa:SpecificResource) — references a source document (PublicationDocument) via a Selector, with optional successor chain (smart:isSuccessorOf), text value (rdf:value), and format (dcterms:format)

  • Selector (oa:Selector) — holds an rdf:value fragment identifier (e.g. XPath, CSS selector)

Provenance model

  • Derivation (prov:Derivation) — tracks term provenance with prov:entity (source IRI) and skos:changeNote

Linked from TermEntry via prov:qualifiedDerivation.

Taxonomy classes

SduSmart::Taxonomy contains SKOS concept classes. All inherit from SduSmart::Taxonomy::Concept (not Entity), which provides a taxonomy macro and a validated .fetch factory:

Taxonomy types and their values:

Class VALUES

BindingnessType

normative, informative

ProvisionType

governingProvision, assertionalProvision

PublicationComponentType

code, figure, mathematicalFormula, table, textual

PublicationDocumentType

guide, publiclyAvailableSpecification, technicalReport, technicalSpecification, normativeDocument, standard, internationalStandard

ProvisionSupplementType

example, footnote, note

PartOfSpeechType

adjective, adverb, noun, verb

TermFormType

abbreviation, acronym, equation, formula, fullForm, symbol, variant

RDF namespaces

Defined in lib/sdu_smart/rdf/namespaces/ as Lutaml::Rdf::Namespace subclasses:

Class Prefix → IRI

SmartNamespace

smart:https://w3id.org/standards/smart/ontologies/core/

IsoIec80000Namespace

isoiec80000:https://w3id.org/standards/isoiec80000/ontologies/core/

OaNamespace

oa:http://www.w3.org/ns/oa#

DcatNamespace

dcat:http://www.w3.org/ns/dcat#

ProvNamespace

prov:http://www.w3.org/ns/prov#

SkosXlNamespace

skosxl:http://www.w3.org/2008/05/skos-xl#

Entity rdf do blocks also reference built-in lutaml namespaces (dcterms:, skos:, rdf:) for predicates like dcterms:issued, skos:definition, and rdf:value.

Extension pattern for domain gems

TermEntry is the primary extension point. Domain gems subclass it and add domain-specific attributes and RDF types:

# In a domain gem (e.g. isq)
class Isq::Quantity < SduSmart::TermEntry
  attribute :has_unit, :string

  rdf do
    type "isoiec80000:Quantity"
    # TermEntry predicates are NOT inherited (lutaml-model replaces rdf blocks)
    # Re-declare needed predicates or use the TermEntry base class for serialization
  end
end
Note

Subclass rdf do blocks replace (not merge with) parent rdf do blocks. This means provision subtypes (Statement, Requirement, etc.) only output their rdf:type in Turtle — they don’t serialize inherited predicates like hasBindingnessType. To serialize/deserialize provision predicates, use the Provision base class directly.

Development

After checking out the repo, install dependencies and run the test suite:

$ bundle install
$ bundle exec rspec

Run a single spec file or example:

$ bundle exec rspec spec/sdu_smart/entity_spec.rb
$ bundle exec rspec spec/sdu_smart/entity_spec.rb:54

reference-docs/ contains the authoritative SmartSDU information model (OWL ontology, SHACL shapes, SKOS taxonomies in Turtle format). Use it to verify that RDF predicates and class design match the specification.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/metanorma/sdu-smart.

Copyright Ribose. BSD-2-Clause License.