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):
- 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;xpromette la presenza e nessun valore. - Sovrapposizione, la possibilità (
meets). Le due ammettono uno stato in comune.xincontrax=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:
araffinabbaccettaaasta più in basso dibnell’ordine parziale
Definizione operativa
a ⪯ b vale se e solo se per ogni chiave K:
- ogni stato che
aammette per K è ammesso dabper K (inclusione; vedi Che cosa significa una forma, e le tabelle) apuò vincolare chiavi chebnon menziona
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:
- Rappresentazione normalizzata: forma di stringa canonica tramite le regole su maiuscole/minuscole e ordinamento
- Alfabeto di vincoli a sei forme:
?x,x?=v,x(=x=*),x!=v,x=v,!x, più il “mancante” implicito - Ordine parziale ⪯: relazione riflessiva, transitiva, antisimmetrica
- Struttura di reticolo: identità in cima, specificità crescente verso il basso
- 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.