Introduction
This document defines some basic relations and types, to be used in ddot.it. Ddot.it itself is relation agnostic and can be used with any relations, including those defined in RDF.
There are only two built-in relations, representing syntax shortcuts from the parsing layer: Relation text (for text annotating a triple, after the ,, marker) and Relation links to / is linked from (the default relation for the untyped link shortcut ....).
Monotonicity
Ddot.it is a monotonic modelling language, and the relations defined here preserve that.
Monotonic means: adding a statement can never invalidate a conclusion already drawn. Whatever a reasoner infers from a set of triples it still infers after more triples arrive; inference only ever adds, it never retracts. The formal statement is that if a knowledge base entails some fact, then every superset of that knowledge base entails it too.
This follows from the language being positive: there is no way to write a negation, so no statement can contradict another. A monotonic language cannot produce contradictions — the worst that can happen is that it infers something you consider wrong, which is a modelling error, not a logical one.
The practical payoff: triples from different files, authors and tools can simply be merged. No statement can invalidate another, so there is no ordering, no precedence and no conflict resolution to define. Every relation in this document is designed to keep that guarantee — see for instance how cycles in has subtype collapse into same as instead of being an error.
RDFS, OWL and CDS are monotonic in the same way. Languages with negation, defaults or a closed-world assumption are not: there, a later statement can withdraw an earlier conclusion.
Syntax
-
In this document,
foo,barandbazare variables. -
We use this syntax to present some triples above the line as Given from which we deduce the Inferred triple below the line.
Given / Inferred... given triples here ... ___________________________________ ... inferred triples here -
Self-Referential: To make ddot.it self-sufficient, the relations in this document are defined using the relations in this document. This is common practice.
Declaration Conventions
Every built-in in this document is declared with the same shape, so that a tool can load the vocabulary without special-casing:
-
Canonical names are spelled out. A built-in block always uses the canonical relation name (
has alias, notalias;same as, notis same as). Alternative spellings appear only as..has alias..values. -
Both sides of a pair are declared. A relation and its inverse each get their own block with their own
has type,has supertype,has inverseanduri. -
Hierarchies point upwards only. A built-in block states
has supertype, neverhas subtype; each entry names its parent, so the full tree is the union of those edges. Only the three roots —entityfor types,relatedandhas propertyfor relations — state nohas supertypeat all. -
Symmetric relations are their own inverse. For a relation of type
symmetric relationthehas inversetriple is implied and therefore not stated. -
Every built-in has a
uriin the ddot.it namespace (see Relationprefix). -
This document is authoritative; the
.ddotfile is derived.ddot-it-vocabulary.ddotnext to this file is the machine-readable twin of the built-in blocks below. It is generated from this document, never edited by hand, and CI asserts the two agree:./check-vocabulary.sh # verify; non-zero exit on mismatch ./check-vocabulary.sh --update # accept the current output as the new baselineSo a built-in is changed here, and the
.ddotfile is regenerated. If the two ever disagree, this document wins and the.ddotfile is stale. -
Only built-ins are machine-readable. The document turns ddot.it parsing off immediately below the title block with an
https://ddot.it/offcommand, and each built-in block switches it back on withhttps://ddot.it/onand off again straight after. Everything else — prose,link:macros, theGiven / Inferredrules, theExampleblocks and the CDS migration table — is therefore never parsed. Indexing this file with a ddot.it tool yields exactly the built-in triples and nothing else:ddot index -f vocabulary.ddot --ext adoc site/spec/The commands are written inside AsciiDoc comments (
// https://ddot.it/off), so they steer the parser without showing up in the rendered document. This relies on two properties, both now guaranteed by the Parse Specification: pre-parse commands are recognised anywhere on a line, so the leading//does not hide them; and the reader is a plain ddot.it parser working on the raw file, which is what theddot indexinvocation above uses. A host-aware AsciiDoc parser that discarded comment lines would lose this steering, which is why such parsers SHOULD preserve pre-parse commands found in host comments.
Top-Level Types
We can use Relation has type / has instance to assign subjects a type. Additionally, we can use Relation has subtype / has supertype to define type hierarchies. So what are the root / top-most elements in the ddot.it type hierarchy?
has type Type entity
The absolute root type. Everything in ddot.it is an Relation has instance or Relation has subtype / has supertype of this type.
entity ..has type.. entity
..has type.. type
..uri.. https://ddot.it/vocabulary/2026-07-20#entityentity has no supertype — it is the root. Its subtypes thing and value state the edge from their side, see below.
It carries two types, and both are wanted. entity ..has type.. type says the same thing thing, value and type say about themselves: it is a type, usable as the object of a Relation has type / has instance. entity ..has type.. entity says it is also an instance of itself, which follows from being the root — everything, types included, is an entity. Neither triple contradicts the other; in a monotonic language they simply both hold.
Types thing and value
Ddot.it has only one datatype: string. So it cannot distinguish between, let’s say 42 being the age of someone or it being the identifier for a chemical compound. Everything is just an Type entity.
thingWe define thing to be all entities that are object-like, physical or imaginary concepts that can be named. In RDF, these are URIs or Blank Nodes.
thing ..has type.. type
..has supertype.. entity
..uri.. https://ddot.it/vocabulary/2026-07-20#thingvalueWe define value to be all entities that have no identity on their own. These are merely used to describe other entities. In RDF, these are the Literals.
value ..has type.. type
..has supertype.. entity
..uri.. https://ddot.it/vocabulary/2026-07-20#value Types type and relation
typeThe "mother of all types" is the type type — the super-type of all types. It is its own type.
type ..has type.. type
..has supertype.. thing
..uri.. https://ddot.it/vocabulary/2026-07-20#typerelationAll relations have the type relation.
relation ..has type.. type
..has supertype.. type
..uri.. https://ddot.it/vocabulary/2026-07-20#relationLinking with Mathematical Relations
Some relations have mathematical properties that let a reasoner infer further triples. Ddot.it models these properties as types of relations, so they are stated with the ordinary has type relation.
Type symmetric relation
The type symmetric relation is the type of all mathematically symmetric relations.
aaa ..fooRel.. bbb
fooRel ..has type.. symmetric relation
___________________________________
bbb ..fooRel.. aaasymmetric relation ..has type.. type
..has supertype.. relation
..uri.. https://ddot.it/vocabulary/2026-07-20#symmetric-relation Type transitive relation
The type transitive relation is the type of all mathematically transitive relations.
aaa ..fooRel.. bbb
bbb ..fooRel.. ccc
fooRel ..has type.. transitive relation
___________________________________
aaa ..fooRel.. ccctransitive relation ..has type.. type
..has supertype.. relation
..uri.. https://ddot.it/vocabulary/2026-07-20#transitive-relationUsage in Formal Systems and Inference
For formal systems, such as rule and inference engines, a crucial question is: Are these two entities the same or different logical entities? To make using ddot.it easier, many relations define aliases that are alternative names denoting the same concept.
Relation has inverse
Often relations form natural pairs, depending on their direction. A Person works for a Company. In the other direction, a Company employs a Person. So works for and employs express the same fact, but stated from a different perspective. For many use cases, the distinction should be ignored. Like in OWL, ddot.it allows to explicitly state the inverse relation of a relation.
a ..ppp.. b
ppp ..has inverse.. qqq
_____________________________________
b ..qqq.. a
ppp ..has type.. relation
qqq ..has type.. relationhas inverse ..has type.. relation
..has type.. symmetric relation
..has supertype.. related
..uri.. https://ddot.it/vocabulary/2026-07-20#has-inverseSyntax for Inverse Relations On The Fly
Given any relation foo, you can use ^foo to state a triple like "the other way round". Formally, the ^ syntax only works as the first character in a relation name. It’s the same character used by the SPARQL query language for the same effect.
a ..^foo.. b
_____________________________________
b ..foo.. a
foo ..has type.. relation
^foo ..has type.. relation
foo ..has inverse.. ^foo
^foo ..has inverse.. fooAnd you can always give ^foo a better Relation label.
Relation has type / has instance
has typeaaa ..has type.. Car — aaa is an instance of the type Car. The inverse is has instance; the supertype is has tag, because typing is a refinement of tagging.
has type ..has type.. relation
..has supertype.. has tag
..has inverse.. has instance
..uri.. https://ddot.it/vocabulary/2026-07-20#has-type
..has alias.. hasTypea shortcutIn N3 (and other RDF syntaxes), the built-in a expresses typing, e.g. (ex:Berlin, a, ex:City). To keep ddot.it self-documenting, the canonical name is has type, so we write Berlin ..has type.. City. But typing with just a is convenient, so a is declared to be replaced by has type: an editor may substitute the one for the other, and a reasoner treats both as the same relation.
a ..is replaced by.. has typehas instanceThe inverse of has type: Car ..has instance.. aaa whenever aaa ..has type.. Car.
Typing is a refinement of tagging: has instance is a subtype of is tag of. So aaa ..has type.. Car implies aaa ..has tag.. Car, which lets type-browsing and tag-browsing share one user interface.
has instance ..has type.. relation
..has supertype.. is tag of
..has inverse.. has type
..uri.. https://ddot.it/vocabulary/2026-07-20#has-instance
..has alias.. hasInstance Relation has subtype / has supertype
has subtypeTypes assigned with has type are inherited along this relation. The inverse is has supertype.
The type Vehicle has the more specialised type Car: Vehicle ..has subtype.. Car.
aaa ..has type.. Car Vehicle ..has subtype.. Car
infers
aaa ..has type.. Vehicle
So if we know something is a Car, then it also must be a Vehicle. It does not work the other way round.
has subtype ..has type.. relation
..has type.. transitive relation
..has supertype.. has detail
..has inverse.. has supertype
..uri.. https://ddot.it/vocabulary/2026-07-20#has-subtype
..has alias.. subtypehas supertypehas supertype ..has type.. relation
..has type.. transitive relation
..has supertype.. has context
..has inverse.. has subtype
..uri.. https://ddot.it/vocabulary/2026-07-20#has-supertype
..has alias.. supertypehas type and has subtype are deliberately not the same relation, and the difference is member-versus-set:
| Write | When | Example |
|---|---|---|
| the subject is one thing that belongs to a category |
|
| the subject is a category of things |
|
It is tempting to merge them, since one transitive relation would give inheritance for free — myCar isa Car, Car isa Vehicle, done. Three things are lost by doing so, and they are why ddot.it keeps both:
-
Member and set stay distinguishable. Merged,
SportscarandmyCarwould sit underCaridentically, and "how many cars are there" would stop having an answer. -
RDF round-trips.
has typemaps tordf:typeandhas subtypetordfs:subClassOf; these are distinct in RDF, and the CDS & Standards Alignment maps to RDFS, OWL, SKOS and WordNet throughout. -
Membership stays non-transitive. A member of a set is not a member of that set’s members.
has subtypeis transitive;has typeis not.
What ddot.it does not require is a strict separation of class and instance: an entity may carry both, and several built-ins do (see entity, which is both a type and an instance of itself). Punning is allowed; merging the two relations is not.
If has subtype forms a cycle, all participants of the cycle are considered to be the same entity (same as). This is exactly what the RDFS specification also states. This is the logicians' solution to "nothing is forbidden".
A linter should show such cycles, as they are rarely intentional.
Top-Level Relations
The relation hierarchy has two roots, because ddot.it relations do two different jobs:
related-
connects a thing to a thing. Both ends have an identity of their own, so the link is worth following in either direction.
has property-
attaches a value to a thing. The value end has no identity of its own; it merely describes the thing.
Every other relation in this document is a subtype of one of these two.
Each root is paired with a type that marks which family a relation belongs to — relation and property respectively (see A type and a relation, in parallel with relation / related). The root is the relation you inherit from; the type is what you are.
-
Each box holds a relation and its inverse as
forward / inverse. The upper name is ahas subtypeof its parent’s upper name; the lower name likewise on the inverse side. So one arrowA <|-- Bstates both B.forwardhas supertypeA.forward and B.inversehas supertypeA.inverse. -
The symmetric relations (
related,has similar,same as) are their own inverse, so they carry a single name. -
has propertyis the second root and carries a single name for the opposite reason: its inverse exists but is not worth naming — see A type and a relation, in parallel withrelation/related. -
An arrow
A <|-- Bmeans: a statement using B also holds for A (via relation inheritance). -
«symmetric»and«transitive»mark relations of that type; on a pair, the marker applies to both directions. -
Typing (
has instance/has type) is deliberately a refinement of tagging, which is itself a refinement of annotation. This mirrors Fig. 4.5 of the source thesis (see Relationhas instance). -
has subtype/has supertyperefinehas detail/has context: a subtype is a special kind of detail. The type hierarchy they build is shown in Top-Level Types.
Relation related
An undirected link connecting foo and bar, with no further claim about how they are related. The weakest link ddot.it offers. The root of all relations between things.
related ..has type.. relation
..has type.. symmetric relation
..uri.. https://ddot.it/vocabulary/2026-07-20#related
..has alias.. is related to
..has alias.. hasRelated Relation property
foo ..property.. bar — bar is a value that describes foo. The weakest such statement ddot.it offers, and the root of all value-carrying relations.
Because the object is a value, stating a property also tells us what kind of entity sits on each end — this is how ddot.it recovers the thing / value distinction that its single string datatype cannot express:
aaa ..ppp.. vvv
ppp ..has type.. property
___________________________________
aaa ..has type.. thing
vvv ..has type.. valueproperty and its subtypes deliberately have no has inverse. The inverse direction is well defined — "which entities carry this value?" — but the value end is not an entity you navigate from, so naming a relation for it would only invite people to model values as things.
Where the inverse is genuinely needed, the ^ syntax supplies it without a name: ^property, ^label, ^grade always exist and can be given a Relation label locally.
relation / relatedThe value-carrying family is described by two built-ins, exactly mirroring how the thing-to-thing family works:
| Family | Top-level relation | Type |
|---|---|---|
between things | ||
value-carrying |
|
property is a type: it marks a relation as one that attaches a value. has property is the relation at the root of that family, the one every value-carrying relation has as its supertype. Writing label ..has type.. property says what kind of relation label is; writing label ..has supertype.. has property places it in the relation hierarchy. Both are declared, just as has subtype declares both ..has type.. transitive relation and ..has supertype.. has detail.
propertyproperty ..has type.. type
..has supertype.. relation
..uri.. https://ddot.it/vocabulary/2026-07-20#propertyhas propertyhas property ..has type.. relation
..has type.. property
..uri.. https://ddot.it/vocabulary/2026-07-20#has-property
..has alias.. hasProperty A identifying relation is always a subtype of property: it carries a value that happens to pin down its subject. This is declared, as identifying relation ..has supertype.. property in its built-in block — and both ends are now types, so the edge sits wholly inside the type hierarchy. |
label and text are defined under Content Management Relations, uri and prefix under Linking with the Semantic Web, the remaining six under Provenance.
Identity: Same or Different?
Some core relations.
Relation has similar
foo and bar are similar, without any claim that they are the same. Weaker than same as, stronger than related.
has similar ..has type.. relation
..has type.. symmetric relation
..has supertype.. related
..uri.. https://ddot.it/vocabulary/2026-07-20#has-similar
..has alias.. is similar to
..has alias.. hasSimilarhas similar is symmetric but not transitive. From a ..has similar.. b and b ..has similar.. c nothing follows about a and c. That is what makes it the safe target for importing fuzzy links such as skos:closeMatch or WordNet’s similar to — see the alignment tables.
Relation same as
foo and bar refer to the same concept. Neither one is the main name — compare is alias of, which does distinguish.
same as ..has type.. relation
..has type.. symmetric relation
..has type.. transitive relation
..has supertype.. has similar
..uri.. https://ddot.it/vocabulary/2026-07-20#same-as
..has alias.. is same as Relation has alias / is alias of
has aliasbar ..has alias.. foo — foo is an alternative name for bar, which stays the main one.
has alias ..has type.. relation
..has supertype.. has similar
..has inverse.. is alias of
..uri.. https://ddot.it/vocabulary/2026-07-20#has-alias
..has alias.. aliasis alias ofLike same as, but with a clear main concept: foo is the alternative name, bar is the one to keep. This is like a sym-link.
The inverse is has alias.
is alias of ..has type.. relation
..has supertype.. has similar
..has inverse.. has alias
..uri.. https://ddot.it/vocabulary/2026-07-20#is-alias-of Relations is replaced by / replaces
foo ..replaces.. bar — foo supersedes bar. Both remain distinct entities; use same as if they are in fact the same thing.
In an editor, when a user types a string aaa marked as aaa ..is replaced by.. bbb, the editor should replace aaa directly with bbb. This is how the a shortcut for has type is defined.
is replaced by ..has type.. relation
..has supertype.. has similar
..has inverse.. replaces
..uri.. https://ddot.it/vocabulary/2026-07-20#is-replaced-by
..has alias.. replacedBy
..has type.. transitive relation
replaces ..has type.. relation
..has supertype.. has similar
..has inverse.. is replaced by
..uri.. https://ddot.it/vocabulary/2026-07-20#replaces
..has type.. transitive relation Type identifier and Relation identifying relation
identifierWe define identifier to be a subtype of Type value, used in a relation of type Type identifying relation.
identifier ..has type.. type
..has supertype.. value
..uri.. https://ddot.it/vocabulary/2026-07-20#identifieridentifying relationAn identifying relation carries a value, which uniquely identifies subjects.
a ..rel.. q
b ..rel.. q
rel ..has type.. identifying relation
_____________________________________
a ..same as.. b
q ..has type.. identifier
a ..has type.. thing
b ..has type.. thingSee Relation same as.
identifying relation ..has type.. type
..has supertype.. relation
..has supertype.. property
..uri.. https://ddot.it/vocabulary/2026-07-20#identifying-relationOrder
Relations has next / has previous
has nextA sequence. foo ..has next.. bar places foo earlier than bar. Both directions are transitive, so a chain of steps yields the full ordering.
has next ..has type.. relation
..has type.. transitive relation
..has supertype.. links to
..has inverse.. has previous
..uri.. https://ddot.it/vocabulary/2026-07-20#has-next
..has alias.. has after
..has alias.. hasAfterhas previoushas previous ..has type.. relation
..has type.. transitive relation
..has supertype.. is linked from
..has inverse.. has next
..uri.. https://ddot.it/vocabulary/2026-07-20#has-previous
..has alias.. has prev
..has alias.. has before
..has alias.. hasBeforeLinking
Linking, like in hyper-text, is the most basic way of a directed relation in ddot.it.
Relation links to / is linked from
This relation is also one of the relations built into ddot.it parsing. It is used as the implicit relation of an untyped link, written …. or .. ...
If the empty relation shortcut is used as in
-
s....o(no space) or its variant -
s.. ..o(with spaces),then there is no relation name given. Emitters omit the relation (the event’s
typefield) for such untyped links; consumers default a missing relation tolinks to(see Triple Events).
links to ..has type.. relation
..has supertype.. related
..has inverse.. is linked from
..uri.. https://ddot.it/vocabulary/2026-07-20#links-to
..has alias.. has target
..has alias.. hasTarget
..has alias.. ^is linked fromis linked fromThe inverse of links to. Its alias has source is the name used in CDS.
is linked from ..has type.. relation
..has supertype.. related
..has inverse.. links to
..uri.. https://ddot.it/vocabulary/2026-07-20#is-linked-from
..has alias.. has source
..has alias.. hasSource
..has alias.. ^links toSee also parsing.
Hierarchies
Relations has detail and has context
foo ..has detail.. bar — bar elaborates or refines foo. Read the other way, foo is the context in which bar makes sense.
has detail ..has type.. relation
..has supertype.. links to
..has inverse.. has context
..uri.. https://ddot.it/vocabulary/2026-07-20#has-detail
..has alias.. hasDetail
has context ..has type.. relation
..has supertype.. is linked from
..has inverse.. has detail
..uri.. https://ddot.it/vocabulary/2026-07-20#has-context
..has alias.. hasContextThe relations has detail/has context are not transitive, unlike has part below, which is a more specific relation. A detail of a detail is not automatically a detail of the whole.
Relations has part and is part of
foo ..has part.. bar — bar is a component of foo. Both directions are transitive: a part of a part is a part of the whole.
has part ..has type.. relation
..has type.. transitive relation
..has supertype.. has detail
..has inverse.. is part of
..uri.. https://ddot.it/vocabulary/2026-07-20#has-part
..has alias.. hasPart
is part of ..has type.. relation
..has type.. transitive relation
..has supertype.. has context
..has inverse.. has part
..uri.. https://ddot.it/vocabulary/2026-07-20#is-part-of
..has alias.. isPartOfA tag on a whole applies to each of its parts:
aaaPart ..is part of.. bbbWhole
bbbWhole ..has tag.. cccTag
___________________________________
aaaPart ..has tag.. cccTagEngine ..is part of.. Car Car ..has tag.. mechanical __________________________ Engine ..has tag.. mechanical
Going Meta
Relations has annotation / annotates
bar ..annotates.. foo — bar is a remark, comment or note about foo. The annotation is a first-class entity, so it can itself be annotated, tagged or typed.
annotates ..has type.. relation
..has supertype.. links to
..has inverse.. has annotation
..uri.. https://ddot.it/vocabulary/2026-07-20#annotates
..has alias.. has annotation member
..has alias.. hasAnnotationMember
has annotation ..has type.. relation
..has supertype.. is linked from
..has inverse.. annotates
..uri.. https://ddot.it/vocabulary/2026-07-20#has-annotation
..has alias.. hasAnnotation Annotating a triple rather than an entity is what the ,, meta part is for. See parsing. |
Relation has tag / is tag of
has tagfoo has the tag bar. A tag is usually a single term. Sometimes multiple words are also used.
has tag ..has type.. relation
..has supertype.. has annotation
..has inverse.. is tag of
..uri.. https://ddot.it/vocabulary/2026-07-20#has-tag
..has alias.. tagTags are not transitive. A tag on a tag says nothing about the tagged entity.
is tag ofThe inverse of has tag: bar ..is tag of.. foo whenever foo ..has tag.. bar. Declared separately so that the tag side of the pair has a name and a URI of its own.
is tag of ..has type.. relation
..has supertype.. annotates
..has inverse.. has tag
..uri.. https://ddot.it/vocabulary/2026-07-20#is-tag-of
..has alias.. has tag member
..has alias.. hasTagMemberContent Management Relations
Relation label
foo ..label.. bar sets the visible label of foo to bar. The semantic layer therefore gives every node an id and a label, the latter defaulting to the id string. Tools that display the knowledge graph show the label and hide the relabelled id. Only the use as a triple relation is defined here. What a tool then does with a label — showing it in place of the id, using it for search, exporting it — belongs to higher layers, and this document says nothing about it.
label ..has type.. relation
..has type.. property
..has supertype.. has property
..uri.. https://ddot.it/vocabulary/2026-07-20#label
..has alias.. has labelSplitting the two makes a graph written in one file easier to change. These two graphs have the same structure and the same displayed names:
Alice ..knows.. Bob
Bob ..knows.. Carola ..knows.. b
b ..knows.. c
a ..label.. Alice
b ..label.. Bob
c ..label.. CarolThe first is more ddot.it-ish and is the right default. The second is easier to maintain while the naming is still in flux: a name is corrected in one place instead of at every occurrence, and the ids stay stable, so nothing else in the graph has to be touched.
The distinction matters only in downstream tools that support labels. At graphinout.com, incoming graph data — ddot.it syntax included — is first converted to Connected JSON (CJ), which has label support, and then to the requested target format.
In previous versions of ddot.it, this was modelled as a command (!!label), documented on its own page at https://ddot.it/label. It is now an ordinary relation and is defined here; the command and its page are gone. !!label in a relation slot is still lexed as a command (command syntax is registry-free) and carries no command semantics — see corpus case 15-label. |
Relation text
This relation is one of the relations built into ddot.it parsing. It carries the free text of a ,, meta that holds no triple (MetaTextInline / MetaTextBlock). Used as an ordinary relation (foo ..text.. some content) it assigns free-form content to a subject — the same relation, written explicitly rather than produced by the ,, shorthand.
When parsing meta-text, as in s..p..o,, meta-text, this is reported as the triple event meta: [{"type":"text","to":"meta-text"}]. A meta pair uses the same type/to keys as the triple event itself, and the collector keeps those keys — one key vocabulary across both layers.
text ..has type.. relation
..has type.. property
..has supertype.. has property
..uri.. https://ddot.it/vocabulary/2026-07-20#text
..has alias.. has text
..has alias.. has contentLinking with the Semantic Web
Ddot.it should be compatible with semantic web / linked open data standards. The triple structure fits exactly, and even the triple-meta parts map to upcoming RDF 1.2 specs (see Primer or Spec). The "base layer" of these standards, The Resource Description Framework (RDF), mandates that resource identifiers are URIs. For that reason, we give every ddot.it relation a URI via ddot.it uri.
Relation uri
uri ..has type.. relation
..has type.. property
..has supertype.. has property
..uri.. https://ddot.it/vocabulary/2026-07-20#uriIf an entity has several URIs, all of them denote the same entity.
Relation prefix
prefix ..has type.. relation
..has type.. property
..has supertype.. has property
..uri.. https://ddot.it/vocabulary/2026-07-20#prefixAdditionally, because URIs are visually quite ugly and have a repetitive part, it’s common practice in most syntaxes to abbreviate the reoccurring URI prefix. Ddot.it does the same.
-
For any string starting with a sequence
foo:barin-
subject (
foo:bar ..y.. z) -
relation (
x ..foo:bar.. z), or -
object (
x ..y.. foo:bar),
-
-
where we also have the triple
foo .. prefix .. baz, -
we infer a similar string with the prefix resolved into its namespace
-
subject (
bazbar ..y.. z) -
relation (
x ..bazbar.. z), or -
object (
x ..y.. bazbar).
-
In practice, baz is usually something like https://example.com/ns/v3/.
We also state as a built-in:
ddot ..prefix.. https://ddot.it/vocabulary/2026-07-20#Provenance
In this section we define some common relations to be used in the meta part of a triple (after the ,, marker). All of them take a value as object; all dates and times are ISO 8601 strings.
Relation source uri
The file or web resource a triple was collected from — maybe only for debugging, maybe always. The URI should name the source file and should locate the source lines in the # fragment, e.g. file:///home/me/notes.adoc#L12-L14.
source uri ..has type.. relation
..has type.. property
..has supertype.. has property
..uri.. https://ddot.it/vocabulary/2026-07-20#source-uri
..has alias.. sourceUri Relation collected
When the triple was collected, as an ISO 8601 date-time.
collected ..has type.. relation
..has type.. property
..has supertype.. has property
..uri.. https://ddot.it/vocabulary/2026-07-20#collected
..has alias.. collected at Relations valid since / valid until
valid since is the date from which the triple holds — a kind of "first collected". valid until is the date after which it no longer holds; if it is missing, the triple is still valid.
valid since ..has type.. relation
..has type.. property
..has supertype.. has property
..uri.. https://ddot.it/vocabulary/2026-07-20#valid-since
..has alias.. validSince
valid until ..has type.. relation
..has type.. property
..has supertype.. has property
..uri.. https://ddot.it/vocabulary/2026-07-20#valid-until
..has alias.. validUntil Relation last modified
When the source document was last changed. Used on the source, not on the triple:
notes.adoc ..has type.. source
..last modified.. 2026-10-09T09:13:59last modified ..has type.. relation
..has type.. property
..has supertype.. has property
..uri.. https://ddot.it/vocabulary/2026-07-20#last-modified
..has alias.. lastModified
source ..has type.. type
..has supertype.. thing
..uri.. https://ddot.it/vocabulary/2026-07-20#source Relation grade
How much a triple can be trusted. The object is one of unreviewed, reviewed or manual.
An unreviewed triple is a tool’s guess and should be treated as disposable. A tool that re-runs its matcher is expected to drop the ..grade.. unreviewed triples it previously emitted. Never store an author’s intent as an auto-link.
| Dropping those triples does not violate monotonicity. Monotonicity is a property of inference over one knowledge base state: no statement present can invalidate a conclusion drawn from the others. Regenerating a derived file is a lifecycle operation on the inputs — the tool is not retracting a conclusion, it is producing a new set of triples to reason over. The same distinction applies to editing any source file: deleting a line changes the input, not the logic. |
grade ..has type.. relation
..has type.. property
..has supertype.. has property
..uri.. https://ddot.it/vocabulary/2026-07-20#grade
unreviewed ..has type.. grade value
..uri.. https://ddot.it/vocabulary/2026-07-20#unreviewed
reviewed ..has type.. grade value
..uri.. https://ddot.it/vocabulary/2026-07-20#reviewed
manual ..has type.. grade value
..uri.. https://ddot.it/vocabulary/2026-07-20#manual
grade value ..has type.. type
..has supertype.. value
..uri.. https://ddot.it/vocabulary/2026-07-20#grade-value In CDS some triple provenance was modelled by using relations. This is now superseded by using grade. The migration is as follows: |
| CDS | ddot.it |
|---|---|
a ..hasManualLinkTarget.. b | a....b ,, ..grade.. manual |
b ..hasManualLinkSource.. a | a....b ,, ..grade.. manual |
a ..hasAutoLinkTarget.. b | a....b ,, ..grade.. unreviewed |
b ..hasAutoLinkSource.. a | a....b ,, ..grade.. unreviewed |
Cardinality
How many values a relation may carry. Ddot.it borrows the model from ECore, which expresses cardinality as bounds rather than as a separate construct.
Bounds are written as two separate properties[1] , each taking a plain integer:
Person ..has address.. Address ,, ..min cardinality.. 1 ;; ..max cardinality.. 3An omitted max cardinality means unbounded. There is no * or -1 sentinel: saying nothing is how "no upper limit" is said.
Relation cardinality
For the common case where a relation carries exactly n values, cardinality sets both bounds at once.
rel ..cardinality.. nnn
___________________________________
rel ..min cardinality.. nnn
rel ..max cardinality.. nnnmin cardinality ..has type.. relation
..has type.. property
..has supertype.. has property
..uri.. https://ddot.it/vocabulary/2026-07-20#min-cardinality
..has alias.. lowerBoundmax cardinality ..has type.. relation
..has type.. property
..has supertype.. has property
..uri.. https://ddot.it/vocabulary/2026-07-20#max-cardinality
..has alias.. upperBoundcardinality ..has type.. relation
..has type.. property
..has supertype.. has property
..uri.. https://ddot.it/vocabulary/2026-07-20#cardinality Types required, single valued and multi valued
Three named shorthands cover almost every practical case. They are relation types, declared the same way as symmetric relation and transitive relation, and they describe the relation itself rather than one triple that uses it.
rel ..has type.. required
___________________________________
rel ..min cardinality.. 1rel ..has type.. single valued
___________________________________
rel ..max cardinality.. 1required ..has type.. type
..has supertype.. relation
..uri.. https://ddot.it/vocabulary/2026-07-20#requiredsingle valued ..has type.. type
..has supertype.. relation
..uri.. https://ddot.it/vocabulary/2026-07-20#single-valuedmulti valued ..has type.. type
..has supertype.. relation
..uri.. https://ddot.it/vocabulary/2026-07-20#multi-valued multi valued infers nothing, and that is deliberate. Being unbounded is the default — it is what an absent max cardinality already means — and ddot.it is monotonic, with no way to state "there is no maximum" as a constraint that would forbid one being added later. multi valued is therefore documentation: it says the author considered the bound and meant it to be open. Its counterpart single valued does infer, because max cardinality 1 is a positive statement. |
| UML | ddot.it | Shorthand | Meaning |
|---|---|---|---|
|
|
| Optional single value |
|
|
| Exactly one |
| (nothing) |
| Any number, including none |
|
|
| At least one |
Summary
Type Hierarchy
The has subtype tree, rooted at entity. Each entry links to its definition.
Relation Hierarchy
The has supertype forest, mirroring the overview diagram in Top-Level Relations and Fig. 4.5 of the source thesis. There are two trees: related for relations between things, and has property for relations carrying a value. Each entry links to its definition; the inverse relation is shown in parentheses. s marks symmetric and t transitive relations.
-
related
s-
-
annotates (has annotation)
-
has next (has previous)
t -
has detail (has context)
-
has subtype (has supertype)
t -
has part (is part of)
t
-
-
None of these has a named inverse; use ^ if you need one (see A type and a relation, in parallel with relation / related). Each also carries ..has type.. property.
Versioning
This vocabulary is versioned independently of the ddot.it syntax specification.
The title carries a semantic version (currently 1.1.0):
-
Major — a built-in was removed or its meaning narrowed, so previously valid data may now be wrong.
-
Minor — built-ins were added, or aliases and supertypes were added without invalidating existing data.
-
Patch — wording, examples and typo fixes only; no triple changed.
Every built-in URI lives in a dated namespace, currently https://ddot.it/vocabulary/2026-07-20# (see prefix). The date changes only on a major version, so minor and patch releases keep every existing URI resolvable. Consumers should therefore pin the namespace, not the version number.
Because a minor release only ever adds built-ins, a consumer that ignores relations it does not know stays correct across minor upgrades. The per-release list of changes is kept in the Ddot.it changelog.
| This is a property of the release policy, not the same thing as the monotonicity of the language itself. Both point the same way — nothing is ever taken back — but a major release may remove a built-in, whereas monotonicity holds for every version of ddot.it. |
1..3 as a single value. It parses where it stands, because a meta object may contain .. — but the same string used as a subject silently misparses: 1..3 ..has type.. cardinality reads as subject 1, relation 3. Two bounds avoid the trap entirely.