From: Lady <redacted>
Date: Mon, 24 Feb 2025 02:10:58 +0000 (-0500)
Subject: Add Olo
X-Git-Url: https://git.ladys.computer/Vocab/commitdiff_plain/834c9ede26e8a90900ea07e73b79161adb1e4b8b?ds=inline

Add Olo

This defines Ordered Lists as effectively a more ergonomic kind of
Aggregation, which helps with bridging them and Ore‐ or P·C·D·M‐based
models. One caveat is that this requires Slots to have exactly one
item, and their item to be an object (i·e not a literal). In an
alternate universe, Slots could instead have had _either_ an item _or_
a value, but it’s simple enough to just make their item be an object
with that value instead.
---

diff --git "a/data/classes/olo\302\246OrderedList" "b/data/classes/olo\302\246OrderedList"
new file mode 100644
index 0000000..95bd3e6
--- /dev/null
+++ "b/data/classes/olo\302\246OrderedList"
@@ -0,0 +1,31 @@
+<?xml version="1.0"?>
+<!--
+SPDX-FileCopyrightText: 2025 Lady <https://www.ladys.computer/about/#lady>
+SPDX-License-Identifier: CC0-1.0
+-->
+<!DOCTYPE Class SYSTEM "../../DTD">
+<Class>
+	<label xml:lang="en">Ordered List</label>
+	<comment xml:lang="en">
+		<p>
+			An <ref target="ore:Aggregation">Aggregation</ref> which provides an ordered listing of <ref target="olo:Slot">Slots</ref>.
+		</p>
+		<p>
+			Ordered Lists are required to have a <ref target="olo:length">length</ref>.
+		</p>
+	</comment>
+	<isDefinedBy>
+		<SpecificResource source="(OLO)" fragment="OrderedList"/>
+	</isDefinedBy>
+	<subClassOf>
+		<resource name="ore:Aggregation"/>
+	</subClassOf>
+	<subClassOf>
+		<Restriction>
+			<onProperty>
+				<resource name="olo:length"/>
+			</onProperty>
+			<cardinality>1</cardinality>
+		</Restriction>
+	</subClassOf>
+</Class>
diff --git "a/data/classes/olo\302\246Slot" "b/data/classes/olo\302\246Slot"
new file mode 100644
index 0000000..6d0b2ba
--- /dev/null
+++ "b/data/classes/olo\302\246Slot"
@@ -0,0 +1,55 @@
+<?xml version="1.0"?>
+<!--
+SPDX-FileCopyrightText: 2025 Lady <https://www.ladys.computer/about/#lady>
+SPDX-License-Identifier: CC0-1.0
+-->
+<!DOCTYPE Class SYSTEM "../../DTD">
+<Class>
+	<label xml:lang="en">Slot</label>
+	<comment xml:lang="en">
+		<p>
+			A <ref target="ore:Proxy">Proxy</ref> representing a single item in an <ptr target="olo:OrderedList">Ordered List</ptr>.
+		</p>
+		<p>
+			Slots are required to have an <ref target="olo:index">index</ref>, which should be less than or equal to its <ref target="olo:ordered_list">ordered list</ref>¦s <ref target="olo:length">length</ref>, and an <ref target="olo:item">item</ref>, providing the thing being proxied by the slot.
+		</p>
+		<p>
+			A Slot is not actually required to have an ordered list by <ptr target="(OLO)"/>, and this caveat may prove useful for ordered slots in <ref target="ore:Aggregation">Aggregations</ref> of indeterminate length, or Aggregations which allow multiple slots with identical indices.
+			In these cases, Slots will still never·the·less <ref target="ore:proxyIn">be a proxy in</ref> some Aggregation, which provides the context for interpreting their index.
+		</p>
+	</comment>
+	<isDefinedBy>
+		<SpecificResource source="(OLO)" fragment="Slot"/>
+	</isDefinedBy>
+	<subClassOf>
+		<resource name="ore:Proxy"/>
+	</subClassOf>
+	<subClassOf>
+		<Restriction>
+			<onProperty>
+				<resource name="olo:index"/>
+			</onProperty>
+			<cardinality>1</cardinality>
+		</Restriction>
+	</subClassOf>
+	<subClassOf>
+		<Restriction>
+			<onProperty>
+				<resource name="olo:item"/>
+			</onProperty>
+			<cardinality>1</cardinality>
+		</Restriction>
+	</subClassOf>
+	<subClassOf>
+		<Restriction>
+			<onProperty>
+				<resource name="olo:ordered_list"/>
+			</onProperty>
+			<maxCardinality>1</maxCardinality>
+		</Restriction>
+	</subClassOf>
+	<hasKey>
+		<resource name="olo:ordered_list"/>
+		<resource name="olo:index"/>
+	</hasKey>
+</Class>
diff --git "a/data/datatype_properties/olo\302\246index" "b/data/datatype_properties/olo\302\246index"
new file mode 100644
index 0000000..0930507
--- /dev/null
+++ "b/data/datatype_properties/olo\302\246index"
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+<!--
+SPDX-FileCopyrightText: 2025 Lady <https://www.ladys.computer/about/#lady>
+SPDX-License-Identifier: CC0-1.0
+-->
+<!DOCTYPE DatatypeProperty SYSTEM "../../DTD">
+<DatatypeProperty functional="yes">
+	<label xml:lang="en">index</label>
+	<comment xml:lang="en">
+		<p>
+			The index of this <ref target="olo:Slot">Slot</ref>.
+		</p>
+		<p>
+			Indices start from 1.
+		</p>
+	</comment>
+	<isDefinedBy>
+		<SpecificResource source="(OLO)" fragment="index"/>
+	</isDefinedBy>
+	<domain>
+		<resource name="olo:Slot"/>
+	</domain>
+	<range>
+		<resource name="xsd:positiveInteger"/>
+	</range>
+</DatatypeProperty>
diff --git "a/data/datatype_properties/olo\302\246length" "b/data/datatype_properties/olo\302\246length"
new file mode 100644
index 0000000..468e4fc
--- /dev/null
+++ "b/data/datatype_properties/olo\302\246length"
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+<!--
+SPDX-FileCopyrightText: 2025 Lady <https://www.ladys.computer/about/#lady>
+SPDX-License-Identifier: CC0-1.0
+-->
+<!DOCTYPE DatatypeProperty SYSTEM "../../DTD">
+<DatatypeProperty functional="yes">
+	<label xml:lang="en">length</label>
+	<comment xml:lang="en">
+		<p>
+			The length of this <ref target="olo:OrderedList">Ordered List</ref>.
+		</p>
+	</comment>
+	<isDefinedBy>
+		<SpecificResource source="(OLO)" fragment="length"/>
+	</isDefinedBy>
+	<domain>
+		<resource name="olo:OrderedList"/>
+	</domain>
+	<range>
+		<resource name="xsd:nonNegativeInteger"/>
+	</range>
+</DatatypeProperty>
diff --git a/data/named_individuals/_OLO_ b/data/named_individuals/_OLO_
new file mode 100644
index 0000000..9dde828
--- /dev/null
+++ b/data/named_individuals/_OLO_
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<!--
+SPDX-FileCopyrightText: 2025 Lady <https://www.ladys.computer/about/#lady>
+SPDX-License-Identifier: CC0-1.0
+-->
+<!DOCTYPE NamedIndividual SYSTEM "../../DTD">
+<NamedIndividual name="http://purl.org/ontology/olo/core">
+	<label xml:lang="en">Olo</label>
+	<comment xml:lang="en">
+		<p>
+			The Ordered List Ontology (Olo) provides, as its name implies, a small number of terms for use describing ordered lists.
+			This help to rectify the faults of other list‐specification mechanisms in consort with Owl; <ref target="rdf:List">Lists</ref> are hard to reason about and <ref target="rdfs:Container">Containers</ref> require an implicit understanding of <resource name="rdfs:ContainerMembershipProperty"/> which Owl does not provide.
+		</p>
+		<p>
+			This ontology interprets <ref target="olo:OrderedList">Ordered Lists</ref> as <ref target="ore:Aggregation">Aggregations</ref>, and their <ref target="olo:Slot">Slots</ref> as a kind of <ref target="ore:Proxy">Proxy</ref>.
+			This makes them an ergonomic extension to the mechanisms specified in <ptr target="(OAI-ORE)"/>.
+		</p>
+	</comment>
+	<type>
+		<resource name="dcterms:BibliographicResource"/>
+	</type>
+	<type>
+		<resource name="doap:Specification"/>
+	</type>
+</NamedIndividual>
diff --git "a/data/object_properties/olo\302\246item" "b/data/object_properties/olo\302\246item"
new file mode 100644
index 0000000..ab3c4d7
--- /dev/null
+++ "b/data/object_properties/olo\302\246item"
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+<!--
+SPDX-FileCopyrightText: 2025 Lady <https://www.ladys.computer/about/#lady>
+SPDX-License-Identifier: CC0-1.0
+-->
+<!DOCTYPE ObjectProperty SYSTEM "../../DTD">
+<ObjectProperty functional="yes" irreflexive="yes">
+	<label xml:lang="en">has item</label>
+	<comment xml:lang="en">
+		<p>
+			The thing being proxied by this <ref target="olo:Slot">Slot</ref>.
+		</p>
+	</comment>
+	<isDefinedBy>
+		<SpecificResource source="(OLO)" fragment="item"/>
+	</isDefinedBy>
+	<subPropertyOf>
+		<resource name="ore:proxyFor"/>
+	</subPropertyOf>
+	<domain>
+		<resource name="olo:Slot"/>
+	</domain>
+</ObjectProperty>
diff --git "a/data/object_properties/olo\302\246next" "b/data/object_properties/olo\302\246next"
new file mode 100644
index 0000000..56a08b1
--- /dev/null
+++ "b/data/object_properties/olo\302\246next"
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+<!--
+SPDX-FileCopyrightText: 2025 Lady <https://www.ladys.computer/about/#lady>
+SPDX-License-Identifier: CC0-1.0
+-->
+<!DOCTYPE ObjectProperty SYSTEM "../../DTD">
+<ObjectProperty functional="yes" inverseFunctional="yes">
+	<label xml:lang="en">has next</label>
+	<comment xml:lang="en">
+		<p>
+			The <ref target="olo:Slot">Slot</ref> which immediately follows this Slot (by index) in its <ref target="olo:OrderedList">Ordered List</ref>.
+		</p>
+	</comment>
+	<isDefinedBy>
+		<SpecificResource source="(OLO)" fragment="next"/>
+	</isDefinedBy>
+	<subPropertyOf>
+		<resource name="rel:next"/>
+	</subPropertyOf>
+	<domain>
+		<resource name="olo:Slot"/>
+	</domain>
+	<range>
+		<resource name="olo:Slot"/>
+	</range>
+</ObjectProperty>
diff --git "a/data/object_properties/olo\302\246ordered_list" "b/data/object_properties/olo\302\246ordered_list"
new file mode 100644
index 0000000..ad0cad5
--- /dev/null
+++ "b/data/object_properties/olo\302\246ordered_list"
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+<!--
+SPDX-FileCopyrightText: 2025 Lady <https://www.ladys.computer/about/#lady>
+SPDX-License-Identifier: CC0-1.0
+-->
+<!DOCTYPE ObjectProperty SYSTEM "../../DTD">
+<ObjectProperty functional="yes">
+	<label xml:lang="en">has ordered list</label>
+	<comment xml:lang="en">
+		<p>
+			The <ref target="olo:OrderedList">Ordered List</ref> of this <ref target="olo:Slot">Slot</ref>.
+		</p>
+	</comment>
+	<isDefinedBy>
+		<SpecificResource source="(OLO)" fragment="ordered_list"/>
+	</isDefinedBy>
+	<subPropertyOf>
+		<resource name="ore:proxyIn"/>
+	</subPropertyOf>
+	<inverseOf>
+		<resource name="olo:slot"/>
+	</inverseOf>
+	<domain>
+		<resource name="olo:Slot"/>
+	</domain>
+</ObjectProperty>
diff --git "a/data/object_properties/olo\302\246previous" "b/data/object_properties/olo\302\246previous"
new file mode 100644
index 0000000..4d9b389
--- /dev/null
+++ "b/data/object_properties/olo\302\246previous"
@@ -0,0 +1,29 @@
+<?xml version="1.0"?>
+<!--
+SPDX-FileCopyrightText: 2025 Lady <https://www.ladys.computer/about/#lady>
+SPDX-License-Identifier: CC0-1.0
+-->
+<!DOCTYPE ObjectProperty SYSTEM "../../DTD">
+<ObjectProperty functional="yes" inverseFunctional="yes">
+	<label xml:lang="en">has previous</label>
+	<comment xml:lang="en">
+		<p>
+			The <ref target="olo:Slot">Slot</ref> which immediately precedes this Slot (by index) in its <ref target="olo:OrderedList">Ordered List</ref>.
+		</p>
+	</comment>
+	<isDefinedBy>
+		<SpecificResource source="(OLO)" fragment="previous"/>
+	</isDefinedBy>
+	<subPropertyOf>
+		<resource name="rel:previous"/>
+	</subPropertyOf>
+	<inverseOf>
+		<resource name="olo:next"/>
+	</inverseOf>
+	<domain>
+		<resource name="olo:Slot"/>
+	</domain>
+	<range>
+		<resource name="olo:Slot"/>
+	</range>
+</ObjectProperty>
diff --git "a/data/object_properties/olo\302\246slot" "b/data/object_properties/olo\302\246slot"
new file mode 100644
index 0000000..6beb79b
--- /dev/null
+++ "b/data/object_properties/olo\302\246slot"
@@ -0,0 +1,27 @@
+<?xml version="1.0"?>
+<!--
+SPDX-FileCopyrightText: 2025 Lady <https://www.ladys.computer/about/#lady>
+SPDX-License-Identifier: CC0-1.0
+-->
+<!DOCTYPE ObjectProperty SYSTEM "../../DTD">
+<ObjectProperty inverseFunctional="yes">
+	<label xml:lang="en">has slot</label>
+	<comment xml:lang="en">
+		<p>
+			A <ref target="olo:Slot">Slot</ref> in this <ref target="olo:OrderedList">Ordered List</ref>.
+		</p>
+	</comment>
+	<isDefinedBy>
+		<SpecificResource source="(OLO)" fragment="slot"/>
+	</isDefinedBy>
+	<subPropertyOf>
+		<ObjectProperty>
+			<inverseOf>
+				<resource name="ore:proxyIn"/>
+			</inverseOf>
+		</ObjectProperty>
+	</subPropertyOf>
+	<domain>
+		<resource name="olo:Slot"/>
+	</domain>
+</ObjectProperty>
diff --git "a/data/object_properties/ore\302\246proxyFor" "b/data/object_properties/ore\302\246proxyFor"
index c2bd8ed..2ed3a4d 100644
--- "a/data/object_properties/ore\302\246proxyFor"
+++ "b/data/object_properties/ore\302\246proxyFor"
@@ -4,7 +4,7 @@ SPDX-FileCopyrightText: 2025 Lady <https://www.ladys.computer/about/#lady>
 SPDX-License-Identifier: CC0-1.0
 -->
 <!DOCTYPE ObjectProperty SYSTEM "../../DTD">
-<ObjectProperty functional="yes">
+<ObjectProperty functional="yes" irreflexive="yes">
 	<label xml:lang="en">proxy for</label>
 	<comment xml:lang="en">
 		<p>
diff --git "a/data/ontologies/\302\246" "b/data/ontologies/\302\246"
index cdc6aa1..680b0e9 100644
--- "a/data/ontologies/\302\246"
+++ "b/data/ontologies/\302\246"
@@ -77,6 +77,10 @@ SPDX-License-Identifier: CC0-1.0
 		<prefix>ladys</prefix>
 		<namespace>https://vocab.ladys.computer/terms/</namespace>
 	</declare>
+	<declare>
+		<prefix>olo</prefix>
+		<namespace>http://purl.org/ontology/olo/core#</namespace>
+	</declare>
 	<declare>
 		<prefix>ore</prefix>
 		<namespace>http://www.openarchives.org/ore/terms/</namespace>
diff --git a/transforms/infer.xslt b/transforms/infer.xslt
index 056e57a..c37f339 100644
--- a/transforms/infer.xslt
+++ b/transforms/infer.xslt
@@ -92,7 +92,7 @@ If a copy of the M·P·L was not distributed with this file, You can obtain one
 									<with-param name="source" select="$source"/>
 								</apply-templates>
 							</for-each>
-							<for-each select="key($relationship-key, $source)">
+							<for-each select="key($relationship-key, $source)[@rdf:about]">
 								<apply-templates select="." mode="Vocab:format-get">
 									<with-param name="source" select="string(@rdf:about)"/>
 								</apply-templates>
@@ -175,7 +175,7 @@ If a copy of the M·P·L was not distributed with this file, You can obtain one
 								<with-param name="source" select="$source"/>
 							</apply-templates>
 						</for-each>
-						<for-each select="key(concat('Vocab:equivalent-', $kind), $source)">
+						<for-each select="key(concat('Vocab:equivalent-', $kind), $source)[@rdf:about]">
 							<apply-templates select="." mode="Vocab:format-get">
 								<with-param name="source" select="string(@rdf:about)"/>
 							</apply-templates>
@@ -276,6 +276,7 @@ If a copy of the M·P·L was not distributed with this file, You can obtain one
 				</element>
 			</when>
 			<otherwise>
+				<!-- assume this is a property (like `owl:inverseOf´), not an instance (like `owl:ObjectProperty´); in this case, the members are what is desired -->
 				<for-each select="*">
 					<copy>
 						<copy-of select="@*|node()"/>