Thank you both for your swift replies!
In reply to zachary.whitley, the rules are all variations of this rule, defining different "contains" and "containedBy" relationships:
Collection(?c), CredentialAccess(?ca), Discovery(?d), Exfiltration(?e), LateralMovement(?lm), Effects(?es), NetworkEffects(?nes), RemoteServiceEffects(?rses), Consequence(?ctf) -> contains(?ctf, ?c), contains(?ctf, ?ca), contains(?ctf, ?d), contains(?ctf, ?e), contains(?ctf, ?lm), contains(?ctf, ?es), contains(?ctf, ?nes), contains(?ctf, ?rses), containedBy(?c, ?ctf), containedBy(?ca, ?ctf), containedBy(?d, ?ctf), containedBy(?e, ?ctf), containedBy(?lm, ?ctf), containedBy(?es, ?ctf), containedBy(?nes, ?ctf), containedBy(?rses, ?ctf)
The query just queries over everything in the graph:
construct {
?s ?p ?o
} where {
graph ?g {
?s ?p ?o
}
}
The data being reasoned over is just a set of 33 JSON objects, here is a sample of a few:
[
{
"@type": ["tag:darklight:attack#AdversaryOpsec"],
"@id": "tag:darklight:attack#AdversaryOpsec"
},
{
"@type": ["tag:darklight:attack#BuildCapabilities"],
"@id": "tag:darklight:attack#BuildCapabilities"
},
{
"@type": ["tag:darklight:attack#Collection"],
"@id": "tag:darklight:attack#Collection"
}]
In reply to safrant, I will try this filter out! Thanks for the idea!