Hypergraphs and SHACL Rules
More explorations on how to implement hypergraphs in RDF 1.2
Hypergraphs sound sexy. The term first surfaced for me a few years ago in the context of some discussions I was having with a client concerning various graph representations, and it has been thrown about with abandon (and more than a little bit of inaccuracy) by people since then, because if graphs are cool, then hypergraphs must be way cooler, right?
Mathematically, a hypergraph can be thought of using sets of IRIs or literals rather than a single IRI or literal as one or more items of a triple (as a subject, predicate or object). In practice, a hypergraph can be represented with linked literals in all three “slots” of a triple. A very simple example of such a triple might be something like:
( :lion :tiger :panther :cheetah :leopard ) ( rdf:type) (class:BigCats) .In practice, the expected behaviour of such a triple is to decompose into five triples:
:lion rdf:type class:BigCats .
:tiger rdf:type class:BigCats .
:panther rdf:type class:BigCats .
:cheetah rdf:type class:BigCats .
:leopard rdf:type class:BigCats .This is considered a triple cross product, with 5 subjects, 1 predicate, and 1 object (5 x 1 x 1). If you expanded this just a little bit:
( :lion :tiger :panther :cheetah :leopard ) ( rdf:type) (class:BigCats class:Carnivores) .Then you get a triple cross product with 5 subjects, one predicate and two objects (5 x 1 x 2) = 10 triples total:
:lion rdf:type class:BigCats .
:tiger rdf:type class:BigCats .
:panther rdf:type class:BigCats .
:cheetah rdf:type class:BigCats .
:leopard rdf:type class:BigCats
:lion rdf:type class:Carnivores .
:tiger rdf:type class:Carnivores .
:panther rdf:type class:Carnivores .
:cheetah rdf:type class:Carnivores .
:leopard rdf:type class:Carnivores .In general, if you have a hypergraph composed of linked lists, then the cross product will be S x P x O triples:
( :s1 :s2 :s3 … :sI) ( :p1 :p2 … :pJ) ( :o1 :o2 … :oK).becomes
:s1 :p1 :o1 .
:s1 :p1 :o2 .
...
:s1 :p1 :oK .
:s1 :p2 :o1 .
:s1 :p2 :o2 .
...
:s2 :p1 :o1 .
...
:sI :pJ :oK .There is only one problem with this: while the above form is (mostly) valid RDF (there are some minor quibbles about the predicate), the condensed (hypergraph) form doesn’t automatically turn into the other form.
Hypergraphs and SHACL Rules
Suppose, however, that you had a SHACL Rule that said, “Anytime you have three linked lists together, treat them them as a cross product of three linear lists.”
Ordinarily, the pattern
( … ) ( … ) ( … ) .where (… ) indicates a linked list, which doesn’t typically occur in RDF. However, it indicates that a hypergraph is being described, and a SHACL rule could then be used to derive the hypergraph into an output graph.
@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix ex: <http://example.org/> .
@prefix hg: <http://example.org/hg#> .
# ============================================
# CORE CROSS-PRODUCT RULE
# ============================================
ex:SetPointerExpansionRule
a sh:NodeShape ;
sh:target [
a sh:SPARQLTarget ;
sh:select """
SELECT ?this
WHERE {
?this ex:listA ?listA ;
ex:listB ?listB ;
ex:listC ?listC .
}
"""
] ;
sh:rule [
a sh:SPARQLRule ;
sh:construct """
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX hg: <http://example.org/hg#>
CONSTRUCT {
?a ?b ?c .
}
WHERE {
# Expand linear lists
$this ex:listA ?listA ;
ex:listB ?listB ;
ex:listC ?listC .
# Dereference listA - if it's a set pointer, get the actual list
OPTIONAL { ?actualListAList hg:inSet ?listA . }
BIND(COALESCE(?actualListAList, ?listA) AS ?finalListA)
# Dereference listB
OPTIONAL { ?actualListBList hg:inSet ?listB . }
BIND(COALESCE(?actualListBList, ?listB) AS ?finalListB)
# Dereference listC
OPTIONAL { ?actualListCList hg:inSet ?listC . }
BIND(COALESCE(?actualListCList, ?listC) AS ?finalListC)
# Expand each list
?finalListA rdf:rest*/rdf:first ?a .
?finalListB rdf:rest*/rdf:first ?bRaw .
?finalListC rdf:rest*/rdf:first ?c .
# Map 'a' to rdf:type if needed
BIND(IF(?bRaw = <http://example.org/a>, rdf:type, ?bRaw) AS ?b)
}
""" ;
] .This SHACL rule does several things.
Triple Linear List
If the triple consists of three linear lists, then expand these into a hypergraph as indicated above.
Naming a Linear List
You can name a linear list through the hg:inSet predicate, where hg: expands to the namespace <http://example.org/hg#> .
( :lion :tiger :panther :cheetah :leopard ) hg:inSet :BigCats .
( Class:BigCats Class:Carnivores ) hg:inSet :CatClasses .
:BigCats ( rdf:type ) :CatClasses .This expands to the 5 x 1 x 2 list above:
:lion rdf:type class:BigCats .
:tiger rdf:type class:BigCats .
:panther rdf:type class:BigCats .
:cheetah rdf:type class:BigCats .
:leopard rdf:type class:BigCats
:lion rdf:type class:Carnivores .
:tiger rdf:type class:Carnivores .
:panther rdf:type class:Carnivores .
:cheetah rdf:type class:Carnivores .
:leopard rdf:type class:Carnivores .The “a” rule
In Turtle, the “a” term is often used as a shortcut for rdf:type. This is difficult to handle ordinarily, but “a” is assumed to indicate <http://example.org/a> , which is the default namespace if none is otherwise provided. This means that:
:BigCats ( a ) :CatClasses .is treated as
:BigCats ( rdf:type ) :CatClasses .Hypergraph Set Operations
Once you have this core primitive rule in place for hypergraphs, you can also set up hypergraph set operations:
@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix ex: <http://example.org/> .
@prefix hg: <http://example.org/hg#> .
# ============================================
# CORE CROSS-PRODUCT RULE
# ============================================
ex:SetPointerExpansionRule
a sh:NodeShape ;
sh:target [
a sh:SPARQLTarget ;
sh:select """
SELECT ?this
WHERE {
?this ex:listA ?listA ;
ex:listB ?listB ;
ex:listC ?listC .
}
"""
] ;
sh:rule [
a sh:SPARQLRule ;
sh:construct """
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX hg: <http://example.org/hg#>
CONSTRUCT {
?a ?b ?c .
}
WHERE {
$this ex:listA ?listA ;
ex:listB ?listB ;
ex:listC ?listC .
# Dereference listA - if it's a set pointer, get the actual list
OPTIONAL { ?actualListAList hg:inSet ?listA . }
BIND(COALESCE(?actualListAList, ?listA) AS ?finalListA)
# Dereference listB
OPTIONAL { ?actualListBList hg:inSet ?listB . }
BIND(COALESCE(?actualListBList, ?listB) AS ?finalListB)
# Dereference listC
OPTIONAL { ?actualListCList hg:inSet ?listC . }
BIND(COALESCE(?actualListCList, ?listC) AS ?finalListC)
# Expand each list
?finalListA rdf:rest*/rdf:first ?a .
?finalListB rdf:rest*/rdf:first ?bRaw .
?finalListC rdf:rest*/rdf:first ?c .
# Map 'a' to rdf:type if needed
BIND(IF(?bRaw = <http://example.org/a>, rdf:type, ?bRaw) AS ?b)
}
""" ;
] .
# ============================================
# SET UNION RULE
# ============================================
ex:SetUnionRule
a sh:NodeShape ;
sh:name "Set Union Rule" ;
sh:description "Creates the union of two or more sets, containing all unique elements from all input sets" ;
sh:target [
a sh:SPARQLTarget ;
sh:select """
PREFIX hg: <http://example.org/hg#>
SELECT ?this
WHERE {
?this hg:setUnion ?unionDef .
}
"""
] ;
sh:rule [
a sh:SPARQLRule ;
sh:construct """
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX hg: <http://example.org/hg#>
CONSTRUCT {
?element hg:inSet $this .
}
WHERE {
$this hg:setUnion ?unionDef .
# unionDef is a list of sets to union
?unionDef rdf:rest*/rdf:first ?inputSet .
# Get all elements from each input set
?sourceList hg:inSet ?inputSet .
?sourceList rdf:rest*/rdf:first ?element .
}
""" ;
] .
# ============================================
# SET INTERSECTION RULE
# ============================================
ex:SetIntersectionRule
a sh:NodeShape ;
sh:name "Set Intersection Rule" ;
sh:description "Creates the intersection of two or more sets, containing only elements present in all input sets" ;
sh:target [
a sh:SPARQLTarget ;
sh:select """
PREFIX hg: <http://example.org/hg#>
SELECT ?this
WHERE {
?this hg:setIntersection ?intersectionDef .
}
"""
] ;
sh:rule [
a sh:SPARQLRule ;
sh:construct """
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX hg: <http://example.org/hg#>
CONSTRUCT {
?element hg:inSet $this .
}
WHERE {
$this hg:setIntersection ?intersectionDef .
# Get the first set as the base
?intersectionDef rdf:first ?firstSet .
?firstList hg:inSet ?firstSet .
?firstList rdf:rest*/rdf:first ?element .
# Ensure element exists in ALL other sets
FILTER NOT EXISTS {
?intersectionDef rdf:rest+ ?restNode .
?restNode rdf:rest*/rdf:first ?otherSet .
# This other set doesn't contain the element
FILTER NOT EXISTS {
?otherList hg:inSet ?otherSet .
?otherList rdf:rest*/rdf:first ?element .
}
}
}
""" ;
] .
# ============================================
# SET DIFFERENCE RULE
# ============================================
ex:SetDifferenceRule
a sh:NodeShape ;
sh:name "Set Difference Rule" ;
sh:description "Creates A - B: elements in the first set but not in the second set" ;
sh:target [
a sh:SPARQLTarget ;
sh:select """
PREFIX hg: <http://example.org/hg#>
SELECT ?this
WHERE {
?this hg:setDifference ?differenceDef .
}
"""
] ;
sh:rule [
a sh:SPARQLRule ;
sh:construct """
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX hg: <http://example.org/hg#>
CONSTRUCT {
?element hg:inSet $this .
}
WHERE {
$this hg:setDifference ?differenceDef .
# differenceDef is (SetA SetB) - elements in A but not in B
?differenceDef rdf:first ?setA .
?differenceDef rdf:rest/rdf:first ?setB .
# Get elements from set A
?listA hg:inSet ?setA .
?listA rdf:rest*/rdf:first ?element .
# Ensure element is NOT in set B
FILTER NOT EXISTS {
?listB hg:inSet ?setB .
?listB rdf:rest*/rdf:first ?element .
}
}
""" ;
] .
# ============================================
# SET SYMMETRIC DIFFERENCE (EXCLUSION) RULE
# ============================================
ex:SetExclusionRule
a sh:NodeShape ;
sh:name "Set Symmetric Difference (Exclusion) Rule" ;
sh:description "Creates the symmetric difference: elements in either set but not in both (XOR)" ;
sh:target [
a sh:SPARQLTarget ;
sh:select """
PREFIX hg: <http://example.org/hg#>
SELECT ?this
WHERE {
?this hg:setExclusion ?exclusionDef .
}
"""
] ;
sh:rule [
a sh:SPARQLRule ;
sh:construct """
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX hg: <http://example.org/hg#>
CONSTRUCT {
?element hg:inSet $this .
}
WHERE {
$this hg:setExclusion ?exclusionDef .
# exclusionDef is (SetA SetB)
?exclusionDef rdf:first ?setA .
?exclusionDef rdf:rest/rdf:first ?setB .
# Elements in A but not in B
{
?listA hg:inSet ?setA .
?listA rdf:rest*/rdf:first ?element .
FILTER NOT EXISTS {
?listB hg:inSet ?setB .
?listB rdf:rest*/rdf:first ?element .
}
}
UNION
# Elements in B but not in A
{
?listB hg:inSet ?setB .
?listB rdf:rest*/rdf:first ?element .
FILTER NOT EXISTS {
?listA hg:inSet ?setA .
?listA rdf:rest*/rdf:first ?element .
}
}
}
""" ;
] .
# ============================================
# SET COUNT RULE
# ============================================
ex:SetCountRule
a sh:NodeShape ;
sh:name "Set Count Rule" ;
sh:description "Computes the cardinality (number of elements) in a set" ;
sh:target [
a sh:SPARQLTarget ;
sh:select """
PREFIX hg: <http://example.org/hg#>
SELECT ?this
WHERE {
?this hg:count ?targetSet .
}
"""
] ;
sh:rule [
a sh:SPARQLRule ;
sh:construct """
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX hg: <http://example.org/hg#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
CONSTRUCT {
$this hg:hasCardinality ?count .
}
WHERE {
$this hg:count ?targetSet .
{
SELECT ?targetSet (COUNT(DISTINCT ?element) AS ?count)
WHERE {
?list hg:inSet ?targetSet .
?list rdf:rest*/rdf:first ?element .
}
GROUP BY ?targetSet
}
}
""" ;
] .These functions can then be used to create “magic” predicates for performing various set operations:
@prefix hg: <http://example.org/hg#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix ex: <http://example.org/> .
@prefix : <http://example.org/> .
@prefix auto: <http://example.org/automotive#> .
# ============================================
# HYPERGRAPH SET OPERATIONS - USAGE EXAMPLES
# ============================================
# ============================================
# 1. SET UNION EXAMPLES
# ============================================
# Example 1.1: Color Union
(:red :green :blue) hg:inSet :PrimaryColors .
(:yellow :green :orange) hg:inSet :SecondaryColors .
(:blue :purple :pink) hg:inSet :TertiaryColors .
:AllColors hg:setUnion (:PrimaryColors :SecondaryColors :TertiaryColors) .
# Generated Result:
# :red hg:inSet :AllColors .
# :green hg:inSet :AllColors .
# :blue hg:inSet :AllColors .
# :yellow hg:inSet :AllColors .
# :orange hg:inSet :AllColors .
# :purple hg:inSet :AllColors .
# :pink hg:inSet :AllColors .
# Example 1.2: Vehicle Models Union
(:Apex_S :Apex_SE :Apex_Limited) hg:inSet :ApexModels .
(:Prestige_Base :Prestige_Sport :Prestige_Luxury) hg:inSet :PrestigeModels .
:AllSedanModels hg:setUnion (:ApexModels :PrestigeModels) .
# Generated Result:
# :Apex_S hg:inSet :AllSedanModels .
# :Apex_SE hg:inSet :AllSedanModels .
# :Apex_Limited hg:inSet :AllSedanModels .
# :Prestige_Base hg:inSet :AllSedanModels .
# :Prestige_Sport hg:inSet :AllSedanModels .
# :Prestige_Luxury hg:inSet :AllSedanModels .
# Example 1.3: Transmission Types Union
(:Manual_6Speed :Manual_7Speed) hg:inSet :ManualTransmissions .
(:Auto_6Speed :Auto_8Speed :Auto_10Speed) hg:inSet :AutomaticTransmissions .
(:CVT) hg:inSet :CVTTransmissions .
:AllTransmissions hg:setUnion (:ManualTransmissions :AutomaticTransmissions :CVTTransmissions) .
# Generated Result:
# :Manual_6Speed hg:inSet :AllTransmissions .
# :Manual_7Speed hg:inSet :AllTransmissions .
# :Auto_6Speed hg:inSet :AllTransmissions .
# :Auto_8Speed hg:inSet :AllTransmissions .
# :Auto_10Speed hg:inSet :AllTransmissions .
# :CVT hg:inSet :AllTransmissions .
# Example 1.4: Access Control - Staff Union
(:alice :bob :charlie) hg:inSet :Managers .
(:diana :eve :frank) hg:inSet :Developers .
(:grace :henry) hg:inSet :Designers .
:TechStaff hg:setUnion (:Managers :Developers :Designers) .
# Generated Result: All 8 people have hg:inSet :TechStaff
# ============================================
# 2. SET INTERSECTION EXAMPLES
# ============================================
# Example 2.1: Team Membership Intersection
(:alice :bob :charlie :diana) hg:inSet :SalesTeam .
(:bob :charlie :eve :frank) hg:inSet :EngineeringTeam .
(:charlie :diana :eve :grace) hg:inSet :ProjectAlpha .
:CoreTeam hg:setIntersection (:SalesTeam :EngineeringTeam :ProjectAlpha) .
# Generated Result:
# :charlie hg:inSet :CoreTeam .
# (Only charlie appears in all three teams)
# Example 2.2: Compatible Features Intersection
(:AWD :Turbo :Premium_Sound :Sunroof) hg:inSet :LuxuryFeatures .
(:AWD :Turbo :Sport_Suspension :Racing_Seats) hg:inSet :PerformanceFeatures .
(:AWD :Eco_Mode :Regenerative_Braking) hg:inSet :EcoFeatures .
:UniversalFeatures hg:setIntersection (:LuxuryFeatures :PerformanceFeatures :EcoFeatures) .
# Generated Result:
# :AWD hg:inSet :UniversalFeatures .
# (Only AWD appears in all three feature sets)
# Example 2.3: Available Paint Colors Across Models
(:Pearl_White :Jet_Black :Racing_Red :Metallic_Silver) hg:inSet :SedanColors .
(:Pearl_White :Jet_Black :Forest_Green :Desert_Tan) hg:inSet :SUVColors .
(:Pearl_White :Jet_Black :Racing_Red :Carbon_Gray) hg:inSet :SportsColors .
:StandardColors hg:setIntersection (:SedanColors :SUVColors :SportsColors) .
# Generated Result:
# :Pearl_White hg:inSet :StandardColors .
# :Jet_Black hg:inSet :StandardColors .
# (Only these two colors available across all vehicle types)
# Example 2.4: Multi-Platform Software Compatibility
(:Windows :macOS :Linux :iOS) hg:inSet :Platform_A_Support .
(:Windows :macOS :Android :iOS) hg:inSet :Platform_B_Support .
(:Windows :macOS :Linux) hg:inSet :Platform_C_Support .
:UniversalPlatforms hg:setIntersection (:Platform_A_Support :Platform_B_Support :Platform_C_Support) .
# Generated Result:
# :Windows hg:inSet :UniversalPlatforms .
# :macOS hg:inSet :UniversalPlatforms .
# ============================================
# 3. SET DIFFERENCE EXAMPLES
# ============================================
# Example 3.1: Engine Types Difference
(:V6_Standard :V6_Twin_Turbo :V8_Performance :I4_Turbo :Hybrid_Mild) hg:inSet :AllEngines .
(:V6_Twin_Turbo :V8_Performance) hg:inSet :PerformanceEngines .
:StandardEngines hg:setDifference (:AllEngines :PerformanceEngines) .
# Generated Result:
# :V6_Standard hg:inSet :StandardEngines .
# :I4_Turbo hg:inSet :StandardEngines .
# :Hybrid_Mild hg:inSet :StandardEngines .
# Example 3.2: Available vs Premium Features
(:Sunroof :Leather_Seats :Navigation :Premium_Sound :HUD :Massage_Seats) hg:inSet :AllFeatures .
(:Premium_Sound :HUD :Massage_Seats) hg:inSet :PremiumOnlyFeatures .
:StandardAvailableFeatures hg:setDifference (:AllFeatures :PremiumOnlyFeatures) .
# Generated Result:
# :Sunroof hg:inSet :StandardAvailableFeatures .
# :Leather_Seats hg:inSet :StandardAvailableFeatures .
# :Navigation hg:inSet :StandardAvailableFeatures .
# Example 3.3: Access Control - Unrestricted Documents
(:Doc1 :Doc2 :Doc3 :Doc4 :Doc5 :Doc6) hg:inSet :AllDocuments .
(:Doc2 :Doc4 :Doc6) hg:inSet :ConfidentialDocuments .
:PublicDocuments hg:setDifference (:AllDocuments :ConfidentialDocuments) .
# Generated Result:
# :Doc1 hg:inSet :PublicDocuments .
# :Doc3 hg:inSet :PublicDocuments .
# :Doc5 hg:inSet :PublicDocuments .
# Example 3.4: Product Catalog - Non-Discontinued Items
(:Product_A :Product_B :Product_C :Product_D :Product_E) hg:inSet :HistoricalCatalog .
(:Product_B :Product_D) hg:inSet :DiscontinuedProducts .
:CurrentCatalog hg:setDifference (:HistoricalCatalog :DiscontinuedProducts) .
# Generated Result:
# :Product_A hg:inSet :CurrentCatalog .
# :Product_C hg:inSet :CurrentCatalog .
# :Product_E hg:inSet :CurrentCatalog .
# ============================================
# 4. SET SYMMETRIC DIFFERENCE (EXCLUSION) EXAMPLES
# ============================================
# Example 4.1: Transmission Categories Exclusion
(:Manual_6Speed :Manual_7Speed :Auto_8Speed :Auto_10Speed) hg:inSet :SportsTransmissions .
(:Auto_6Speed :Auto_8Speed :Auto_10Speed :CVT) hg:inSet :ComfortTransmissions .
:ExclusiveTransmissions hg:setExclusion (:SportsTransmissions :ComfortTransmissions) .
# Generated Result:
# :Manual_6Speed hg:inSet :ExclusiveTransmissions .
# :Manual_7Speed hg:inSet :ExclusiveTransmissions .
# :Auto_6Speed hg:inSet :ExclusiveTransmissions .
# :CVT hg:inSet :ExclusiveTransmissions .
# (Excludes :Auto_8Speed and :Auto_10Speed which appear in both)
# Example 4.2: Feature Sets Comparison
(:CarPlay :Android_Auto :Wireless_Charging :Premium_Sound) hg:inSet :TechPackage .
(:Premium_Sound :HUD :360_Camera :Adaptive_Cruise) hg:inSet :SafetyPackage .
:UniqueFeatures hg:setExclusion (:TechPackage :SafetyPackage) .
# Generated Result:
# :CarPlay hg:inSet :UniqueFeatures .
# :Android_Auto hg:inSet :UniqueFeatures .
# :Wireless_Charging hg:inSet :UniqueFeatures .
# :HUD hg:inSet :UniqueFeatures .
# :360_Camera hg:inSet :UniqueFeatures .
# :Adaptive_Cruise hg:inSet :UniqueFeatures .
# (Excludes :Premium_Sound which appears in both)
# Example 4.3: Market Availability Comparison
(:USA :Canada :Mexico :UK :Germany) hg:inSet :NorthAmericaEuropeMarkets .
(:UK :Germany :France :Italy :Spain) hg:inSet :EuropeOnlyExpanded .
:RegionalExclusives hg:setExclusion (:NorthAmericaEuropeMarkets :EuropeOnlyExpanded) .
# Generated Result:
# :USA hg:inSet :RegionalExclusives .
# :Canada hg:inSet :RegionalExclusives .
# :Mexico hg:inSet :RegionalExclusives .
# :France hg:inSet :RegionalExclusives .
# :Italy hg:inSet :RegionalExclusives .
# :Spain hg:inSet :RegionalExclusives .
# (Excludes :UK and :Germany which appear in both)
# Example 4.4: User Permissions Asymmetry
(:read :write :delete :admin) hg:inSet :PowerUserPermissions .
(:read :write :share :export) hg:inSet :RegularUserPermissions .
:DistinctivePermissions hg:setExclusion (:PowerUserPermissions :RegularUserPermissions) .
# Generated Result:
# :delete hg:inSet :DistinctivePermissions .
# :admin hg:inSet :DistinctivePermissions .
# :share hg:inSet :DistinctivePermissions .
# :export hg:inSet :DistinctivePermissions .
# (Excludes :read and :write which both user types have)
# ============================================
# 5. SET COUNT EXAMPLES
# ============================================
# Example 5.1: Inventory Count
(:item1 :item2 :item3 :item4 :item5) hg:inSet :InventoryItems .
:InventoryCount hg:count :InventoryItems .
# Generated Result:
# :InventoryCount hg:hasCardinality "5"^^xsd:integer .
# Example 5.2: Color Options Count
(:Pearl_White :Jet_Black :Metallic_Silver :Deep_Blue :Racing_Red) hg:inSet :StandardColors .
(:Satin_Gray :Matte_Black :Custom_Orange :Championship_White) hg:inSet :PremiumColors .
:StandardColorCount hg:count :StandardColors .
:PremiumColorCount hg:count :PremiumColors .
# Generated Result:
# :StandardColorCount hg:hasCardinality "5"^^xsd:integer .
# :PremiumColorCount hg:hasCardinality "4"^^xsd:integer .
# Example 5.3: Team Size Metrics
(:alice :bob :charlie :diana :eve) hg:inSet :EngineeringTeam .
(:frank :grace :henry) hg:inSet :DesignTeam .
(:iris :judy :kevin :laura :mike :nancy) hg:inSet :SalesTeam .
:EngineeringTeamSize hg:count :EngineeringTeam .
:DesignTeamSize hg:count :DesignTeam .
:SalesTeamSize hg:count :SalesTeam .
# Generated Result:
# :EngineeringTeamSize hg:hasCardinality "5"^^xsd:integer .
# :DesignTeamSize hg:hasCardinality "3"^^xsd:integer .
# :SalesTeamSize hg:hasCardinality "6"^^xsd:integer .
# Example 5.4: Feature Availability Count
(:Sunroof :Navigation :Premium_Sound :Leather :HUD) hg:inSet :LuxuryFeatures .
:LuxuryFeatureCount hg:count :LuxuryFeatures .
# Generated Result:
# :LuxuryFeatureCount hg:hasCardinality "5"^^xsd:integer .
# Example 5.5: Product SKU Count
(:SKU_001 :SKU_002 :SKU_003) hg:inSet :RedProducts .
(:SKU_004 :SKU_005 :SKU_006 :SKU_007 :SKU_008) hg:inSet :BlueProducts .
:RedProductCount hg:count :RedProducts .
:BlueProductCount hg:count :BlueProducts .
# Generated Result:
# :RedProductCount hg:hasCardinality "3"^^xsd:integer .
# :BlueProductCount hg:hasCardinality "5"^^xsd:integer .
# ============================================
# 6. COMPLEX COMBINED EXAMPLES
# ============================================
# Example 6.1: Automotive Material Analysis
(:Leather_Premium :Leather_Nappa :Cloth_Standard) hg:inSet :AllSeatMaterials .
(:Leather_Premium :Leather_Nappa) hg:inSet :PremiumMaterials .
(:Cloth_Standard :Leather_Synthetic) hg:inSet :BudgetMaterials .
# Union of premium and budget
:AvailableMaterials hg:setUnion (:PremiumMaterials :BudgetMaterials) .
# Intersection (materials that are both premium and budget - should be empty)
:ConflictMaterials hg:setIntersection (:PremiumMaterials :BudgetMaterials) .
# Difference (premium materials not available in budget)
:ExclusivePremium hg:setDifference (:PremiumMaterials :BudgetMaterials) .
# Count premium materials
:PremiumCount hg:count :PremiumMaterials .
:BudgetCount hg:count :BudgetMaterials .
# Generated Results:
# :Leather_Premium hg:inSet :AvailableMaterials .
# :Leather_Nappa hg:inSet :AvailableMaterials .
# :Cloth_Standard hg:inSet :AvailableMaterials .
# :Leather_Synthetic hg:inSet :AvailableMaterials .
#
# :ConflictMaterials has no members (empty set)
#
# :Leather_Premium hg:inSet :ExclusivePremium .
# :Leather_Nappa hg:inSet :ExclusivePremium .
#
# :PremiumCount hg:hasCardinality "2"^^xsd:integer .
# :BudgetCount hg:hasCardinality "2"^^xsd:integer .
# Example 6.2: Access Control Matrix
(:alice :bob :charlie) hg:inSet :Admins .
(:bob :charlie :diana :eve) hg:inSet :Editors .
(:eve :frank :grace) hg:inSet :Viewers .
# All users with any access
:AllUsers hg:setUnion (:Admins :Editors :Viewers) .
# Users with both admin and editor privileges
:SuperUsers hg:setIntersection (:Admins :Editors) .
# Admin-only users (not editors)
:AdminOnlyUsers hg:setDifference (:Admins :Editors) .
# Users who are either admins or viewers but not both
:NonOverlapping hg:setExclusion (:Admins :Viewers) .
# Count each category
:AdminCount hg:count :Admins .
:EditorCount hg:count :Editors .
:ViewerCount hg:count :Viewers .
:TotalUserCount hg:count :AllUsers .
# Generated Results:
# :AllUsers contains: alice, bob, charlie, diana, eve, frank, grace (7 users)
# :SuperUsers contains: bob, charlie (2 users)
# :AdminOnlyUsers contains: alice (1 user)
# :NonOverlapping contains: alice, bob, charlie, frank, grace (5 users)
# :AdminCount hg:hasCardinality "3"^^xsd:integer .
# :EditorCount hg:hasCardinality "4"^^xsd:integer .
# :ViewerCount hg:hasCardinality "3"^^xsd:integer .
# :TotalUserCount hg:hasCardinality "7"^^xsd:integer .
# Example 6.3: Product Feature Compatibility
(:WiFi :Bluetooth :USB_C :Wireless_Charging) hg:inSet :Model2024Features .
(:WiFi :Bluetooth :5G :USB_C :Wireless_Charging :AI_Assistant) hg:inSet :Model2025Features .
(:Bluetooth :USB_C :HDMI :Ethernet) hg:inSet :Model2023Features .
# Features carried over from 2024 to 2025
:RetainedFeatures hg:setIntersection (:Model2024Features :Model2025Features) .
# New features in 2025
:NewIn2025 hg:setDifference (:Model2025Features :Model2024Features) .
# Features unique to 2023 or 2025
:EvolutionaryFeatures hg:setExclusion (:Model2023Features :Model2025Features) .
# All features across all models
:AllModelFeatures hg:setUnion (:Model2023Features :Model2024Features :Model2025Features) .
# Count features by year
:Features2023Count hg:count :Model2023Features .
:Features2024Count hg:count :Model2024Features .
:Features2025Count hg:count :Model2025Features .
:TotalFeaturesCount hg:count :AllModelFeatures .
# Generated Results:
# :RetainedFeatures: WiFi, Bluetooth, USB_C, Wireless_Charging (4 features)
# :NewIn2025: 5G, AI_Assistant (2 features)
# :EvolutionaryFeatures: HDMI, Ethernet, WiFi, 5G, AI_Assistant, Wireless_Charging (6 features)
# :AllModelFeatures: WiFi, Bluetooth, USB_C, Wireless_Charging, 5G, AI_Assistant, HDMI, Ethernet (8 features)
# :Features2023Count hg:hasCardinality "4"^^xsd:integer .
# :Features2024Count hg:hasCardinality "4"^^xsd:integer .
# :Features2025Count hg:hasCardinality "6"^^xsd:integer .
# :TotalFeaturesCount hg:hasCardinality "8"^^xsd:integer .
# ============================================
# 7. QUERY EXAMPLES
# ============================================
# Query 7.1: Find all elements in a union set
# SELECT ?element WHERE { ?element hg:inSet :AllColors . }
# Query 7.2: Find all sets containing a specific element
# SELECT ?set WHERE { :red hg:inSet ?set . }
# Query 7.3: Get cardinality of a set
# SELECT ?count WHERE { :InventoryCount hg:hasCardinality ?count . }
# Query 7.4: Find sets with more than 5 elements
# SELECT ?set ?count WHERE {
# ?countNode hg:count ?set ;
# hg:hasCardinality ?count .
# FILTER(?count > 5)
# }
# Query 7.5: Compare sizes of two sets
# SELECT ?set1Count ?set2Count WHERE {
# :Count1 hg:count :Set1 ; hg:hasCardinality ?set1Count .
# :Count2 hg:count :Set2 ; hg:hasCardinality ?set2Count .
# }
# ============================================
# END OF USAGE EXAMPLES
# ============================================Evaluating SHACL Rules
There are currently no “native” SHACL rules engines that have complete support for SHACL 1.2, as the spec is still evolving. However, I’ve found that Anthropic Claude (specifically Sonnet 4.5) can function as an “ersatz” SHACL Rules Engine. Typically I do this by specifying as part of a prompt:
Use SHACL 1.2 Core (at https://www.w3.org/TR/shacl12-core/)for evaluating SHACL Rules, with the following rulesets.Paste in the rulesets given above. This gives you a hypergraph-aware SHACL rules processor. Then simply indicate the hypergraph rules:
Evaluate:
```
(:red :green :blue) hg:inSet :PrimaryColors .
(:yellow :green :orange) hg:inSet :SecondaryColors .
(:blue :purple :pink) hg:inSet :TertiaryColors .
:AllColors hg:setUnion (:PrimaryColors :SecondaryColors :TertiaryColors) .
```Claude thinks for a bit, then generates the output:
:red hg:inSet :AllColors .
:green hg:inSet :AllColors .
:blue hg:inSet :AllColors .
:yellow hg:inSet :AllColors .
:orange hg:inSet :AllColors .
:purple hg:inSet :AllColors .
:pink hg:inSet :AllColors .Note that at this point, SHACL does not have a list-building operation (it’s still in discussion), so the output will be a set of normal triples. This will likely change.
Analysis: Hypergraphs and SHACL
SHACL hypergraph functions transform RDF modelling by replacing manual triple enumeration with declarative set operations and cross-products. This approach achieves 20-50x compression in specification size, eliminates consistency errors, and enables compositional reasoning impossible in traditional RDF.
Part 1: Triple Generation Benefits
1. Massive Compression
Example: Product Catalog
# Traditional: 39 manual triples
:item1 :hasColor :red .
:item1 :hasColor :yellow .
# ... 37 more
# Hypergraph: 4 definitions generate 39 triples
(:item1 :item2 :item3) hg:inSet :Items .
(:red :yellow :green :blue :white :black) hg:inSet :Colors .
ex:Config ex:listA :Items ; ex:listB (:hasColor) ; ex:listC :Colors .
Compression Ratios:
Simple catalog: 5:1
Automotive (18 models): 37:1 (3,000 triples from 80 lines)
Enterprise access control: 50:1+
2. Automatic Consistency
Problem: Manual triples are error-prone
# Easy to create inconsistencies
:Apex_S :hasEngine :V6_Standard .
:Apex_SE :hasEngine :V6_Standard .
:Apex_Limited :hasEngine :I4_Turbo . # Inconsistent!
# :Apex_S missing :hasTransmission entirely
Solution: Cross-products guarantee uniformity
(:Apex_S :Apex_SE :Apex_Limited) hg:inSet :ApexModels .
(:I4_Turbo :V6_Standard :V6_Twin_Turbo) hg:inSet :Engines .
ex:ApexEngines ex:listA :ApexModels ; ex:listB (:hasEngine) ; ex:listC :Engines .
# All 3 models get all 3 engines - impossible to be inconsistent
3. Compositional Maintenance
Adding new item: O(1) instead of O(n)
# Add to set once
(:item1 :item2 :item3 :item4) hg:inSet :Items .
# 13 triples generated automatically (item4 × 13 attributes)
Adding new attribute: O(1) instead of O(m)
# Add to set once
(:red :yellow :green :blue :white :black :neon_green) hg:inSet :Colors .
# 3 triples generated automatically (neon_green × 3 items)
4. Integrated Constraints
ex:NoManualWithHybridConstraint
sh:sparql [
sh:message "Manual transmissions cannot be combined with hybrid engines" ;
sh:select """
SELECT $this WHERE {
$this :hasTransmission ?trans ; :hasEngine ?engine .
FILTER(?trans IN (:Manual_6Speed, :Manual_7Speed))
FILTER(?engine IN (:Hybrid_Mild, :Hybrid_Plugin))
}
"""
] .
Benefits: Validation, documentation, and enforcement in one place.
5. Scalability
Scaling: O(n³) manual vs O(n) declarative
6. Clear Intent
Traditional: Intent implicit in patterns
:ProductA :hasColor :red .
:ProductA :hasColor :blue .
# Why these specific triples?
Hypergraph: Intent explicit
# Clear: all standard products get all standard colors
(:ProductA :ProductB) hg:inSet :StandardProducts .
(:red :blue) hg:inSet :StandardColors .
:Config ex:listA :StandardProducts ; ex:listB (:hasColor) ; ex:listC :StandardColors .
Part 2: Set Operation Benefits
1. Declarative Set Algebra
# Define once, updates automatically
(:red :green :blue) hg:inSet :PrimaryColors .
(:orange :purple :green) hg:inSet :SecondaryColors .
:AllColors hg:setUnion (:PrimaryColors :SecondaryColors) .
# Result: {red, green, blue, orange, purple}
vs Traditional:
# Must write and re-run manually
CONSTRUCT { ?color a :AllColors . }
WHERE {
{ ?color hg:inSet :PrimaryColors }
UNION
{ ?color hg:inSet :SecondaryColors }
}
2. Access Control Matrices
(:alice :bob :charlie) hg:inSet :Managers .
(:read :write :delete) hg:inSet :AllPermissions .
(:Doc1 :Doc2 :Doc3) hg:inSet :ConfidentialDocs .
# Managers get full access: 3×3×3 = 27 ACL entries from 3 lines
ex:ManagerAccess ex:listA :Managers ;
ex:listB :AllPermissions ;
ex:listC :ConfidentialDocs .
Benefits:
Policy as code
Automatic onboarding (add to set, inherit permissions)
Audit trail
Compliance validation
3. Lifecycle Management
(:ProductA :ProductB :ProductC :ProductD) hg:inSet :AllProducts .
(:ProductB :ProductD) hg:inSet :DiscontinuedProducts .
# Active = All - Discontinued
:ActiveProducts hg:setDifference (:AllProducts :DiscontinuedProducts) .
# Result: {ProductA, ProductC}
4. Version Comparison
(:FeatureX :FeatureY :FeatureZ) hg:inSet :Version1 .
(:FeatureY :FeatureZ :FeatureW) hg:inSet :Version2 .
:NewFeatures hg:setDifference (:Version2 :Version1) . # {FeatureW}
:RemovedFeatures hg:setDifference (:Version1 :Version2) . # {FeatureX}
:ChangedFeatures hg:setExclusion (:Version1 :Version2) . # {FeatureX, FeatureW}
5. Multi-Criteria Selection
(:Windows :macOS :Linux) hg:inSet :DesktopPlatforms .
(:iOS :Android) hg:inSet :MobilePlatforms .
(:Windows :iOS) hg:inSet :MicrosoftEcosystem .
# Intersection: only Windows appears in all three
:UniversalFeatures hg:setIntersection (:DesktopPlatforms :MobilePlatforms :MicrosoftEcosystem) .
6. Real-Time Metrics
:ActiveProducts hg:setDifference (:AllProducts :DiscontinuedProducts) .
:ActiveCount hg:count :ActiveProducts .
# Automatically tracks active catalog size as products change
Part 3: Comparative Impact
Development Velocity
Scenario: Add product line with 5 models, 4 subsystems, 20 options each
Improvement: 4-16x faster
Error Reduction
Estimated: 70-90% error reduction
Cognitive Load
Maintenance Impact
Example: Adding safety feature to all 18 vehicle models
Version control: Smaller diffs, clearer intent, easier review
Part 4: Advanced Capabilities
1. Compositional Transformations
# ETL pipeline as set operations
:ValidData hg:setDifference (:RawData :InvalidRecords) .
:TransformedData ex:listA :ValidData ;
ex:listB (:transformedTo) ;
ex:listC :OutputFormat .
:ProcessedCount hg:count :TransformedData .
2. Temporal Reasoning
:Catalog2025 hg:setUnion (:Catalog2024 :NewProducts2025) .
:NewProducts2025 hg:setDifference (:Catalog2025 :Catalog2024) .
:Discontinued2025 hg:setDifference (:Catalog2024 :Catalog2025) .
3. Multi-Tenancy
ex:TenantA_Config ex:listA :TenantA_Users ;
ex:listB (:hasFeature) ;
ex:listC :PremiumFeatures .
ex:TenantB_Config ex:listA :TenantB_Users ;
ex:listB (:hasFeature) ;
ex:listC :BasicFeatures .
4. Graph Algorithms
# Breadth-first search as set operations
:Level1 ex:listA :Level0 ; ex:listB (:connectedTo) ; ex:listC :AllNodes .
:Visited1 hg:setUnion (:Level0 :Level1) .
:Level2 hg:setDifference (:Level1Neighbors :Visited1) .
Part 5: Limitations & Mitigations
Part 6: When to Use
✅ Ideal Use Cases
Product catalogs with multi-dimensional options
Access control matrices (users × permissions × resources)
Configuration management (vehicles, devices, services)
Regulatory compliance (all X must have Y)
ETL pipelines and data transformations
Version comparison and lifecycle management
Multi-tenant systems
❌ Not Recommended For
Small, static datasets (< 100 triples)
Highly irregular relationship patterns
Performance-critical real-time systems
When triple-level provenance is essential
Implementation Roadmap
Phase 1: Pilot (2-4 weeks)
Choose bounded domain (e.g., product colors)
Implement basic cross-product rules
Validate against manual triples
Measure compression ratio
Phase 2: Expansion (1-3 months)
Add set operations
Implement constraints
Build external list materializer
Develop debugging tools
Phase 3: Production (3-6 months)
Migrate major ontology sections
Integrate with CI/CD
Train team
Document patterns
Key Metrics Summary
Business Use Cases for Hypergraph Generation and Set Operations
1. E-Commerce & Retail
Product Catalog Management
Generate all SKU variants (color × size × material × style)
Manage seasonal collections (union of base + seasonal items)
Track discontinued vs. active products (set difference)
Calculate available inventory combinations
Impact: 50-100x reduction in catalog maintenance
Personalized Recommendations
Customer segments × product categories × promotion types
Similar customers intersection for collaborative filtering
Exclude previously purchased items (set difference)
2. Automotive & Manufacturing
Vehicle Configuration
All valid combinations of models × engines × transmissions × features
Regulatory compliance (all models must have safety features)
Market-specific offerings (US configurations vs. EU configurations)
Impact: 3,000+ configurations from 80 lines of rules
Supply Chain Optimization
Suppliers × components × manufacturers (valid supply paths)
Alternative suppliers (set union for redundancy)
Single-source components (set difference for risk analysis)
3. Healthcare & Pharmaceuticals
Clinical Trial Design
Patients × treatments × dosages × schedules
Inclusion/exclusion criteria (set intersection/difference)
Drug interaction matrices (contraindicated combinations)
Treatment Protocols
Conditions × symptoms × medications × contraindications
Eligible treatments per patient profile (intersection of compatible options)
4. Financial Services
Investment Portfolio Management
Assets × strategies × risk levels × time horizons
Regulatory constraints (permissible combinations)
Tax-optimized portfolios (exclude tax-inefficient combinations)
Risk & Compliance
Jurisdictions × regulations × product types × customer segments
FATCA/CRS reporting combinations
AML rule matrices (customer types × transaction types × risk levels)
5. Enterprise Software & SaaS
Access Control (IAM)
Users × roles × permissions × resources
Organizational hierarchy (union of department permissions)
Separation of duties (intersection violations)
Impact: 27 ACL entries from 3 lines for managers
Feature Flags & Configuration
Tenants × features × plans × regions
A/B test variant assignments
Gradual rollout (progressive set unions)
6. Telecommunications
Service Bundles
Plans × devices × add-ons × regions
Compatible device-plan combinations
Network coverage (intersection of service areas)
Network Planning
Cell towers × frequency bands × coverage areas
Interference analysis (overlapping coverage sets)
7. Insurance
Policy & Premium Calculation
Customer segments × coverage types × deductibles × regions
Excluded conditions (set difference from coverage)
Risk pools (intersection of demographic factors)
Claims Processing
Claim types × coverage levels × approval workflows
Valid adjuster assignments (intersection of expertise and availability)
8. Real Estate
Property Matching
Properties × buyer criteria × financing options × locations
Available properties (all properties - sold/pending)
Price range intersections with buyer budgets
Zoning & Compliance
Parcels × zoning codes × permitted uses × restrictions
Variances and exceptions (set differences)
9. Education & Training
Course Scheduling
Courses × instructors × rooms × time slots
Prerequisite validation (intersection of completed courses)
Degree requirements (union of required course sets)
Skill Development
Employees × skills × certifications × training programs
Skill gaps (required skills - current skills)
10. Hospitality & Travel
Booking Systems
Hotels × room types × dates × rates × policies
Available inventory (all rooms - booked rooms)
Package deals (accommodation + transportation + activities)
Loyalty Programs
Members × tiers × benefits × partners
Redeemable rewards (intersection of member tier and partner offerings)
11. Media & Entertainment
Content Rights Management
Content × territories × platforms × time periods
Available content per region (intersection of rights and platform)
Expiring licenses (set difference by date)
Streaming Recommendations
Users × genres × viewing history × availability
Similar viewer intersections (collaborative filtering)
12. Government & Public Sector
Regulatory Compliance
Entities × regulations × jurisdictions × requirements
Compliance gaps (required - implemented)
Multi-jurisdiction obligations (intersection of requirements)
Procurement
Vendors × products × contracts × agencies
Eligible bidders (intersection of qualifications and certifications)
13. Energy & Utilities
Grid Management
Substations × transmission lines × capacity × regions
Redundant paths (union of backup routes)
Critical infrastructure (intersection of high-priority nodes)
Pricing Models
Customer segments × usage tiers × time-of-day × seasons
Rate combinations for different customer profiles
14. Logistics & Transportation
Route Optimization
Origins × destinations × carriers × service levels
Available routes (all routes - restricted routes)
Multi-modal options (union of transport modes)
Fleet Management
Vehicles × drivers × routes × cargo types
Certified driver-cargo combinations (intersection of licenses)
15. Human Resources
Workforce Planning
Employees × skills × projects × locations
Available resources (all employees - assigned employees)
Succession planning (intersection of qualified candidates)
Compensation & Benefits
Roles × levels × locations × benefit packages
Benefit eligibility (intersection of tenure and status)
Key Benefits Across All Use Cases
Selection Criteria
Use hypergraphs when you have:
✅ Multi-dimensional configuration spaces (3+ dimensions)
✅ Combinatorial relationship patterns (products of sets)
✅ Strict consistency requirements across combinations
✅ Frequent schema or rule changes
✅ Regulatory compliance needs
✅ 1,000+ generated relationships from source definitions
Avoid hypergraphs when:
❌ Relationships are highly irregular or one-off
❌ Small, static datasets (< 100 relationships)
❌ Real-time generation is required (millisecond latency)
❌ Team lacks RDF/SHACL expertise and can’t invest in training
Analysis Overview
Hypergraphs, as described here, become a generative strategy. They can be used in areas where you have a fairly strong degree of consistency in your content, including product catalogues, customisation packages, regulatory requirements, supply chain management, access control, and so forth, in essence, allowing you to customise a number of relationships through simple set manipulation.
SHACL hypergraph functions provide 10-100x improvement in modelling efficiency through:
Declarative specification: Replace manual triples with set operations
Automatic consistency: Cross-products guarantee completeness
Compositional design: Changes propagate automatically
Set-theoretic operations: Union, intersection, difference built-in
Integrated validation: Constraints enforced at generation time
Best suited for: Domains with multi-dimensional configuration spaces, combinatorial relationships, and strong consistency requirements.
Overall ROI: Most significant for systems with >1,000 generated triples, where compression ratios of 20-100:1 and error reductions of 70-90% justify the learning curve and tooling investment.
One final point - this also illustrates the power of SHACL rulesets in general. In effect, you can make “magical predicates” that allow for very complex operations, such as set manipulation or cross product generation. It’s one of many reasons I’m so jazzed about SHACL 1.2.
Note: Some of this analysis was generated by Sonnet 4.5.
In Media Res,
Check out my LinkedIn newsletter, The Cagle Report.
I am also currently seeking new projects or work opportunities. If anyone is looking for a CTO or Director-level AI/Ontologist, please get in touch with me through my Calendly:
If you want to shoot the breeze or have a cup of virtual coffee, I have a Calendly account at https://calendly.com/theCagleReport. I am available for consulting and full-time work as an ontologist, AI/Knowledge Graph guru, and coffee maker. Also, for those of you whom I have promised follow-up material, it’s coming; I’ve been dealing with health issues of late.
I’ve created a Ko-fi account for voluntary contributions, either one-time or ongoing, or you can subscribe directly to The Ontologist. If you value my articles, technical pieces, or general reflections on work in the 21st century, please consider contributing to support my work and allow me to continue writing.












Respectfully, "Mathematically, a hypergraph can be thought of using sets of IRIs or literals rather than a single IRI or literal as one or more items of a triple (as a subject, predicate or object)." is not a mathematical definition.
Mathematically, a hypergraph is defined by sets of vertices (V) and hyperedges (E), independent of data types like IRIs or literals.