In questa sezione

Definizione

Sia U l’insieme di tutti i tagged URN normalizzati.

Un tagged URN ha la struttura:

prefix:key1=value1;key2=value2;...

Ogni elemento u ∈ U ha:

  • Un prefisso (per esempio media, cap)
  • Zero o più tag come coppie chiave-valore
  • Una rappresentazione canonica ben definita

Sintassi

Grammatica

tagged-urn  ::= prefix ":" tags?
prefix      ::= identifier
tags        ::= tag (";" tag)*
tag         ::= key ("=" value)?
key         ::= identifier
value       ::= unquoted-value | quoted-value
identifier  ::= [a-z][a-z0-9-]*

Esempi

media:                           # Identità (nessun tag)
media:bytes;pdf                  # Due tag con valori * impliciti
cap:in=media:pdf;extract;out=media:record
cap:in="media:bytes;pdf";extract;out="media:record"

Normalizzazione

Tutti i tagged URN vengono normalizzati durante il parsing secondo queste regole:

Normalizzazione di maiuscole e minuscole

Componente Regola
Prefisso Minuscolo
Chiavi Minuscolo
Valori senza virgolette Minuscolo
Valori fra virgolette Maiuscole e minuscole preservate

Tag senza valore

Un tag senza = viene trattato come se avesse valore *:

Input:  media:bytes;pdf
Parsed: media:pdf=*;bytes=*

Nella serializzazione, i valori * tornano alla forma senza valore:

Internal: {pdf: "*", bytes: "*"}
Output:   media:bytes;pdf

Ordinamento dei tag

I tag sono memorizzati in una mappa ordinata (BTreeMap) e serializzati in ordine alfabetico delle chiavi:

Input:  media:bytes;pdf
Output: media:bytes;pdf      # 'bytes' precede 'pdf' in ordine alfabetico

Regole per le virgolette

Un valore deve essere racchiuso fra virgolette se contiene: ;, =, ", \, uno spazio o caratteri maiuscoli.

Fra virgolette:

  • " si scrive come \"
  • \ si scrive come \\
  • Tutti gli altri caratteri sono letterali

Le sei forme canoniche

I tagged URN codificano i vincoli su ciascuna chiave usando una di sei forme canoniche. Diversi alias scritti dall’autore confluiscono nella stessa forma canonica durante il parsing; la serializzazione emette sempre il rappresentante canonico in modo deterministico.

Alias scritti Canonica Valore memorizzato Lettura
?x ≡ x? ≡ x=? ?x "?" nessun vincolo
?x=v ≡ x?=v ≡ x=?v x?=v "?=v" assente OPPURE (presente e diverso da v)
x ≡ x=* x "*" presente con qualsiasi valore (deve esserci)
!x=v ≡ x!=v ≡ x=!v x!=v "!=v" presente e diverso da v
x=v x=v "v" presente ed esattamente v
!x ≡ x! ≡ x=! !x "!" assente (non deve esserci)

Posizione del qualificatore

Il qualificatore ? o ! può comparire O come prefisso della chiave (?x, !x, ?x=v, !x=v) O come infisso subito prima di = (x?, x!, x?=v, x!=v). Le due notazioni sono alias esatti.

Combinazioni non ammesse

Errori di parsing bloccanti:

  • Prefisso e infisso insieme: ?x?, ?x?=v, !x!=v, !x?. Il qualificatore compare due volte sulla stessa chiave.
  • ? e ! insieme: ?!x, !?x. Sono contraddittori.
  • Qualificatore con un valore sigillo: ?x=*, !x=*, ?x=?, ?x=!. Un qualificatore e un valore composto solo da un sigillo confonderebbero le due semantiche.
  • Valore vuoto: x= — un valore esatto non può essere vuoto.
  • ? o ! isolato senza nulla dopo: prefix:?, prefix:!. Un qualificatore richiede una chiave.

Perché sei forme

Le sei forme si ripartiscono in due catene semantiche più i loro estremi:

  • Catena positiva (affermazioni di presenza): ?x (nessun vincolo) → x (deve esserci, con qualsiasi valore) → x=v (deve esserci, esattamente v).
  • Catena negativa (affermazioni di assenza/esclusione): ?x (nessun vincolo) → x?=v (assente o diverso da v) → x!=v (presente e diverso da v) → !x (assente).

Entrambe le catene partono dalla stessa origine comune (?x, nessun vincolo). Le catene divergono per il tipo di affermazione che fanno: le catene positive richiedono la presenza e fissano progressivamente il valore; le catene negative vietano valori e restringono progressivamente il tipo di divieto.

Forma canonica di x=*

x da solo e x=* sono la stessa forma. Il parser memorizza entrambi con valore "*"; il serializzatore emette come canonica la forma breve x (senza il suffisso =*). In questo modo la scrittura in stile marcatore (extract, bytes, numeric) resta coerente con la scrittura a valore esplicito.


Che cosa significa una forma, e le tabelle

Ogni forma significa l’insieme degli stati in cui può trovarsi la sua chiave (non impostata, o impostata a un valore), e lo significa su entrambi i lati di un confronto:

Forma Gli stati che ammette
mancante, ?x ogni stato
x?=v non impostata, o impostata a qualsiasi valore tranne v
x impostata, a qualsiasi valore
x!=v impostata, a qualsiasi valore tranne v
x=v impostata esattamente a v
!x non impostata

Due forme si confrontano attraverso i loro insiemi, e i confronti sono due (Predicati contiene entrambe le tabelle):

  1. Inclusione, la garanzia (⪯). L’istanza soddisfa il pattern quando ogni stato che l’istanza ammette è ammesso anche dal pattern. Un’istanza che omette una chiave, o dice ?x, non promette nulla; x promette la presenza e nessun valore.
  2. Sovrapposizione, la possibilità (meets). Le due ammettono uno stato in comune. x incontra x=pdf: “un qualche x” potrebbe essere un pdf.

Una cosa completa (il media di un valore, i tag propri di una cap) si confronta per inclusione dopo che le sue omissioni sono state lette come assenze (satisfies).

Esempi

# Tipo: media:bytes;pdf        Pattern: media:pdf
# 'pdf': presente ⊆ presente ✓      'bytes': presente ⊆ (qualsiasi cosa) ✓
# conforms_to: SÌ

# Tipo: media:pdf;audio=mp3    Pattern: media:pdf;!audio
# 'audio': {mp3} ⊄ {non impostata}
# conforms_to: NO, meets: NO

# Tipo: media:pdf;v=final      Pattern: media:pdf;v!=draft
# 'v': {final} ⊆ {impostata, diversa da draft} ✓
# conforms_to: SÌ

# Tipo: media:pdf              Pattern: media:pdf;v?=draft
# 'v': (qualsiasi cosa) ⊄ {non impostata o diversa da draft} — un TIPO pdf può essere una draft
# conforms_to: NO, meets: SÌ
# Un VALORE pdf senza il tag v: satisfies: SÌ

# Tipo: media:ext              Pattern: media:document;ext=pdf
# 'ext': {qualsiasi valore} ⊄ {pdf}, ma si sovrappongono
# conforms_to: NO, meets: SÌ

La relazione di base ⪯

Si definisce una relazione binaria sui tagged URN:

a ⪯ b   sse   a è almeno tanto specifico quanto b

In modo equivalente:

  • a raffina b
  • b accetta a
  • a sta più in basso di b nell’ordine parziale

Definizione operativa

a ⪯ b vale se e solo se per ogni chiave K:

Proprietà

La relazione ⪯ è:

  • Riflessiva: ∀u ∈ U, u ⪯ u
  • Transitiva: (a ⪯ b ∧ b ⪯ c) ⟹ a ⪯ c
  • Antisimmetrica (a meno della normalizzazione): (a ⪯ b ∧ b ⪯ a) ⟹ a ≡ b

Ciò rende ⪯ un ordine parziale sugli URN normalizzati.


Elementi identità

Identità dei media

L’identità dei media URN è:

media:

Questo URN:

  • Non ha tag
  • Accetta qualsiasi media URN (è il massimo dell’ordine parziale)
  • Ha specificità 0

Riflessività: media: ⪯ media: vale (l’identità accetta se stessa).

Identità dei tagged URN

Per qualsiasi prefisso P, l’identità è:

P:

Un URN senza tag accetta qualsiasi URN con lo stesso prefisso.


Struttura di ordine parziale

I tagged URN con lo stesso prefisso formano un ordine parziale (ordine di specializzazione):

                    media:                    (top: il più generico)
                      |
              media:bytes
                /         \
       media:pdf          media:image
           |                   |
   media:pdf;v=2.0      media:png;image
           |
media:pdf;v=2.0;compressed              (più specifico)
  • Massimo (⊤): l’identità prefix: senza tag
  • Ordinamento: più tag = più specifico = più in basso nell’ordine

Nota: benché questa struttura abbia proprietà simili a quelle di un reticolo (è limitata superiormente dall’identità), non definiamo formalmente le operazioni di join (⊔) o meet (⊓). Il sistema usa solo la relazione d’ordine parziale ⪯.


Errori di parsing

Le condizioni seguenti producono errori di parsing:

Condizione Errore
Prefisso mancante MissingPrefix
Prefisso vuoto EmptyPrefix
Chiave duplicata DuplicateKey
Chiave numerica NumericKey
Valore vuoto dopo = EmptyValue
Virgolette non chiuse UnclosedQuote
Sequenza di escape non valida InvalidEscape

Riepilogo

Il dominio dei tagged URN U fornisce:

  1. Rappresentazione normalizzata: forma di stringa canonica tramite le regole su maiuscole/minuscole e ordinamento
  2. Alfabeto di vincoli a sei forme: ?x, x?=v, x (=x=*), x!=v, x=v, !x, più il “mancante” implicito
  3. Ordine parziale ⪯: relazione riflessiva, transitiva, antisimmetrica
  4. Struttura di reticolo: identità in cima, specificità crescente verso il basso
  5. Corrispondenza composizionale: chiave per chiave, in base a ciò che ogni forma significa: inclusione per la garanzia, sovrapposizione per la possibilità

Tutti i costrutti di livello superiore (predicati, cap URN, dispatch) si basano su questo fondamento.