Consider the following example:
:rangeA :lowerLimit :LeftMarginA ;
:upperLimit :RightMarginA .
:rangeB :lowerLimit :LeftMarginB ;
:upperLimit :RightMarginB .
:LeftMarginA :hasValue 20 ;
:RightMarginA :hasValue 80 .
:LeftMarginB :hasValue 30 ;
:RightMarginB :hasValue 60 .
How to get inference results using SPARQL or SWRL
:rangeA :Contains :rangeB
My idea is:
if (:LeftMarginB >= :LeftMarginA)
&& (:RightMarginB <= :RightMarginA)
then :rangeA :contains :rangeB
But how do I write this SPARQL or SWRL statement?
Thanks for help.
If you can write a SELECT query that selects one range that contains another, it's just one more step to convert it into a CONSTRUCT WHERE query that generates the triple that captures your inference. For instance:
Some Data
#prefix : <urn:ex:>
:x :lower 30 ; :upper 60 .
:y :lower 20 ; :upper 80 .
A query
prefix : <urn:ex:>
construct {
?a :contains ?b
} where {
?a :lower ?la ; :upper ?ua .
?b :lower ?lb ; :upper ?ub .
filter ( ?lb < ?la && ?ua < ?ub )
}
The result
#prefix : <urn:ex:> .
:x :contains :y .
I've tested and this does work:
prefix : <#>
CONSTRUCT { ?rangeA :contains ?rangeB . }
WHERE {
{
SELECT ?rangeA ?rangeB
WHERE {
?rangeA :lowerLimit ?LeftMarginA ;
:upperLimit ?RightMarginA .
?rangeB :lowerLimit ?LeftMarginB ;
:upperLimit ?RightMarginB .
?LeftMarginA :hasValue ?valueLA.
?RightMarginA :hasValue ?valueRA.
?LeftMarginB :hasValue ?valueLB.
?RightMarginB :hasValue ?valueRB.
Filter ((?valueLB >= ?valueLA) && (?valueRB <= ?valueRA)
&& (?rangeA !=?rangeB))
}
}
}
But that doesn't take into account the inclusion of the boundary.
If consider boundary inclusion like :
:LeftMarginA :hasValue 20 ;
:inclusive True.
:RightMarginA :hasValue 80 ;
:inclusive False.
How can SPARQL statements be modified to work properly?
Thank you all, the final solution is as follows:
#-----rdf data
#prefix : <#> .
:rangeA :lowerLimit 20 ;
:lowerLimitInclusiveA false ;
:upperLimit 80 ;
:upperLimitInclusiveA false .
:rangeB :lowerLimit 20.5 ;
:lowerLimitInclusiveB false ;
:upperLimit 60 ;
:upperLimitInclusiveB false .
#---sparql query ========================
prefix : <#>
CONSTRUCT { ?rangeA :contains ?rangeB . }
WHERE {
{
SELECT ?rangeA ?rangeB
WHERE {
?rangeA :lowerLimit ?LeftMarginA ;
:lowerLimitInclusiveA ?lowerA ;
:upperLimit ?RightMarginA ;
:upperLimitInclusiveA ?upperA .
?rangeB :lowerLimit ?LeftMarginB ;
:lowerLimitInclusiveB ?lowerB ;
:upperLimit ?RightMarginB ;
:upperLimitInclusiveB ?upperB .
Filter (if(?lowerA,?LeftMarginB>=?LeftMarginA, ?LeftMarginB>?LeftMarginA)
&& if(?upperA, ?RightMarginB<=?RightMarginA, ?RightMarginB<?RightMarginA)
&& (?rangeA!= ?rangeB))
}
}
}
Related
The example ontology has two classes (:MyClass and :Value) and two properties (:MyObjProp and :MyDataProp).
:MyClass
a owl:Class ;
a sh:NodeShape ;
rdfs:subClassOf owl:Thing ;
.
:MyDataProp
a owl:DatatypeProperty ;
rdfs:domain :MyClass ;
rdfs:range xsd:string ;
.
:MyObjProp
a owl:ObjectProperty ;
rdfs:domain :MyClass ;
rdfs:range :Value ;
.
:Value
a owl:Class ;
rdfs:subClassOf owl:Thing ;
.
Some instances were added.
:MyClass_1
a :MyClass ;
:MyDataProp :Value_1 ;
:MyObjProp :Value_1 ;
.
:MyClass_2
a :MyClass ;
:MyObjProp :Value_2 ;
.
:Value_1
a :Value ;
.
:Value_2
a :Value ;
.
A NodeShape :NodeShapeRule with a sh:rule (:SPARQLRule_1) was created. This rule creates new triples. With the sh:condition the rule should be restricted to a subset of targets.
:NodeShapeRule
a sh:NodeShape ;
sh:rule :SPARQLRule_1 ;
sh:targetClass :MyClass ;
.
:SPARQLRule_1
a sh:SPARQLRule ;
sh:condition :NodeShapeConditionSPARQL ;
sh:construct """
PREFIX : <http://example.org/ex#>
CONSTRUCT
{
$this :MyDataProp \"New input\" .
}
WHERE
{
$this :MyObjProp ?p .
}
""" ;
.
For the restriction two equivalent NodeShapes were defined. The first constraint works with sh:property, the other uses sh:sparql.
:NodeShapeConditionProperty
a sh:NodeShape ;
sh:property [
sh:path :MyObjProp ;
sh:description "NodeShapeConditionProperty" ;
sh:hasValue :Value_1 ;
] ;
sh:targetClass :MyClass ;
.
:NodeShapeConditionSPARQL
a sh:NodeShape ;
sh:sparql [
sh:message "NodeShapeConditionSPARQL" ;
sh:prefixes <http://example.org/ex> ;
sh:select """
PREFIX : <http://example.org/ex#>
SELECT $this
WHERE
{
$this :MyObjProp ?prop .
}
""" ;
] ;
sh:targetClass :MyClass ;
.
While doing inferencing with Topbraid Composer I received different results for both solutions. Only the solution with sh:property provides the expected response. Please, can someone explain me this behavior?
:MyClass_1 :MyDataProp "New input"
The right explanation is that the SPAQRL query produces a constraint violation for each result (row) in SELECT query. So if the SPARQL query returns no result (rows) then all is fine and the rule will fire. The reason for this design is that this enables SPARQL queries to return more information about the violation, e.g. the focus node ($this) and the value node (?value).
Changing the :NodeShapeConditionSPARQL it produces violation for not existing results and then both solutions behave in the same manner.
:NodeShapeConditionSPARQL
a sh:NodeShape ;
sh:sparql [
sh:message "NodeShapeConditionSPARQL" ;
sh:prefixes <http://example.org/ex> ;
sh:select """
PREFIX : <http://example.org/ex#>
SELECT $this
WHERE
{
FILTER NOT EXISTS { $this :MyObjProp ?anyProp } .
}
""" ;
] ;
sh:targetClass :MyClass ;
.
Please have a look at the following example:
#prefix : <#> .
#prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
:Bob :score 78 .
:John :score 50 .
:rule1 :condition [
rdf:subject :score ;
rdf:predicate :notLessThan ;
rdf:object 60
];
:condition [
rdf:subject :score ;
rdf:predicate :notGreaterThan ;
rdf:object 80
];
:rating :passed .
:rule2 :condition [
rdf:subject :score ;
rdf:predicate :lessThan ;
rdf:object 60
];
:rating :failed .
I want to get the following output by spqrql query:
:Bob :rating :passed.
:John :rating :failed.
here rdf:predicate is changeable by the user, and its value may be:
lessThan, notLessThan, greaterThan, notGreaterThan
So how do I write this SPARQL statement based on dynamic predicate?
I don't have any ideas. Thank you for helping me.
This does work perfectly :
PREFIX : <#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
CONSTRUCT {
?student :rating ?rating .
} WHERE {
?student :score ?score .
?rule :rating ?rating .
OPTIONAL {
?rule :condition ?condition .
?condition rdf:subject :score .
?condition rdf:predicate ?predicate .
?condition rdf:object ?object .
# fails condition
FILTER (
! ( (?predicate = :lessThan && ?score < ?object ) ||
(?predicate = :notLessThan && ?score >= ?object ) ||
(?predicate = :greaterThan && ?score > ?object ) ||
(?predicate = :notGreaterThan && ?score <= ?object )
)
)
}
FILTER(!bound(?condition))
}
and we get the results:
:Bob :rating :passed .
:John :rating :failed .
I have multiple trees where nodes are linked with hasParent and each node has some particular color. I need to filter a tree by a color and extract the topmost elements (exclude nested elements after filtering).
Here is an example of my data:
The result I need is: [A, B, I].
I know how to implement basic tree filter that returns [A, B, I, J, L, O]:
SELECT DISTINCT ?s WHERE {
?s <http://looneytunes-graph.com/color> "yellow"^^xsd:string
}
Is there a way to implement such additional filtering? or do I need to rethink my solution and use something else instead of graph db (AWS Neptune)?
I'm testing it with https://sparql-playground.sib.swiss/data and the following data:
#prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
<http://looneytunes-graph.com/A> <http://looneytunes-graph.com/color> "yellow"^^xsd:string .
<http://looneytunes-graph.com/B> <http://looneytunes-graph.com/color> "yellow"^^xsd:string .
<http://looneytunes-graph.com/C> <http://looneytunes-graph.com/color> "green"^^xsd:string .
<http://looneytunes-graph.com/D> <http://looneytunes-graph.com/color> "red"^^xsd:string ;
<http://looneytunes-graph.com/hasParent> <http://looneytunes-graph.com/A> .
<http://looneytunes-graph.com/E> <http://looneytunes-graph.com/color> "blue"^^xsd:string ;
<http://looneytunes-graph.com/hasParent> <http://looneytunes-graph.com/A> .
<http://looneytunes-graph.com/F> <http://looneytunes-graph.com/color> "blue"^^xsd:string ;
<http://looneytunes-graph.com/hasParent> <http://looneytunes-graph.com/B> .
<http://looneytunes-graph.com/G> <http://looneytunes-graph.com/color> "green"^^xsd:string ;
<http://looneytunes-graph.com/hasParent> <http://looneytunes-graph.com/B> .
<http://looneytunes-graph.com/H> <http://looneytunes-graph.com/color> "red"^^xsd:string ;
<http://looneytunes-graph.com/hasParent> <http://looneytunes-graph.com/C> .
<http://looneytunes-graph.com/I> <http://looneytunes-graph.com/color> "yellow"^^xsd:string ;
<http://looneytunes-graph.com/hasParent> <http://looneytunes-graph.com/C> .
<http://looneytunes-graph.com/J> <http://looneytunes-graph.com/color> "yellow"^^xsd:string ;
<http://looneytunes-graph.com/hasParent> <http://looneytunes-graph.com/D> .
<http://looneytunes-graph.com/K> <http://looneytunes-graph.com/color> "green"^^xsd:string ;
<http://looneytunes-graph.com/hasParent> <http://looneytunes-graph.com/D> .
<http://looneytunes-graph.com/L> <http://looneytunes-graph.com/color> "yellow"^^xsd:string ;
<http://looneytunes-graph.com/hasParent> <http://looneytunes-graph.com/F> .
<http://looneytunes-graph.com/M> <http://looneytunes-graph.com/color> "red"^^xsd:string ;
<http://looneytunes-graph.com/hasParent> <http://looneytunes-graph.com/G> .
<http://looneytunes-graph.com/N> <http://looneytunes-graph.com/color> "blue"^^xsd:string ;
<http://looneytunes-graph.com/hasParent> <http://looneytunes-graph.com/G> .
<http://looneytunes-graph.com/O> <http://looneytunes-graph.com/color> "yellow"^^xsd:string ;
<http://looneytunes-graph.com/hasParent> <http://looneytunes-graph.com/I> .
SELECT DISTINCT ?s WHERE {
?s <http://looneytunes-graph.com/color> "yellow"^^xsd:string .
FILTER NOT EXISTS {
?s hasParent+ [<http://looneytunes-graph.com/color> "yellow"^^xsd:string] .
}
}
With this query you are filtering out the nodes having (a parent node having a parent node having...) a yellow parent node.
I did not get the right sentence to ask the question.
I would like to explain my problem using a sample data.
let's say the triples are as below.
#prefix skos: <http://www.w3.org/2004/02/skos/core#> .
#prefix xs: <http://www.w3.org/2001/XMLSchema#> .
#prefix p0: <http://www.mlacustom.com#> .
#prefix p2: <http://www.mla.com/term/> .
_:bnode7021016689601753065 p0:lastModifiedDateTime "2018-09-14T12:55:38"^^<xsd:dateTime> ;
p0:lastModifiedUser "admin"^^xs:string .
<http://www.mla.com/name/4204078359> p0:hasClassingFacet "http://www.mla.com/facet/RA"^^xs:string ;
p0:type "Normal"^^xs:string ;
p0:classification _:bnode3452184423513029143 ,
_:bnode6827572371999795686 ;
p0:recordType "Name"^^xs:string ;
p0:recordNumber "4204078359"^^xs:string ;
p0:stdDescriptor "classification111111"^^xs:string ;
p0:establishedBy "admin"^^xs:string ;
skos:prefLabel "classification111111"^^xs:string ;
p0:createdBy "admin"^^xs:string ;
a skos:Concept ;
p0:createdDate "2018-09-14T12:55:38"^^<xsd:dateTime> ;
p0:establishedDate "2018-09-14T12:55:38"^^<xsd:dateTime> ;
p0:hasRAsubFacet "http://www.mla.com/subfacet/classing-subject-authors"^^xs:string ;
p0:lastModifiedDate "2018-09-14T12:55:38"^^<xsd:dateTime> ;
p0:lastModifiedDetails _:bnode7021016689601753065 ;
p0:isProblematic "N,N"^^xs:string ;
p0:lastModifiedBy "admin"^^xs:string ;
p0:status "established"^^xs:string .
_:bnode3452184423513029143 p0:literature p2:1513 ;
p0:timePeriod p2:1005 ;
p0:language p2:3199 .
_:bnode6827572371999795686 p0:literature p2:11307 ;
p0:timePeriod p2:1009 ;
p0:language p2:31 .
please have a look at the p0:classification it has two blank nodes and both the blank nodes has triples with p0:literature, p0:timePeriod, p0:language
Now I want to write a SPARQL query where
(
(p0:literature is p2:1513 AND p0:timePeriod is p2:1005) AND
(p0:literature is p2:11307 AND p0:timePeriod is p2:1009)
)
As per the above scenario it should return me the http://www.mla.com/name/4204078359 subject
Classification can have any number of blank nodes.
Here is one of the solutions. It is possible to find many different queries. This one is explicit.
SELECT ?s WHERE {
?s p0:classification ?o1 .
?s p0:classification ?o2 .
?o1 p0:literature p2:1513 ;
p0:timePeriod p2:1005 .
?o2 p0:literature p2:11307 ;
p0:timePeriod p2:1009 .
}
I have exactly these triples in GraphDB:
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
<http://example.com/greeting>
a <http://example.com/word> ;
rdfs:label "hello" .
I want to know if there is a thing in my triplestore with the label "hello" and another with the label "goodbye"
PREFIX : <http://example.com/>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
ASK
WHERE
{ VALUES ?l { "goodbye" "hello" }
?s a :thing ;
rdfs:label ?l
}
I am being told that yes, this is true, as if it is saying at least one of those are true. But I want to know if all of those patterns are true.
Can I do that in a SPARQL ASK?
I also tried the following but got the same (unwanted) result:
PREFIX : <http://example.com/>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
ASK
WHERE
{ VALUES (?l) { ("goodbye") ("hello") }
?s a :thing ;
rdfs:label ?l
}
Sanity check: the answer to this ASK is false
PREFIX : <http://example.com/>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
ASK
WHERE
{ VALUES (?l) { ("goodbye") }
?s a :thing ;
rdfs:label ?l
}
Rather than asking "are all of these present", ask "is any of these not present" (and then negate the result either I've your application or with another "filter not exists":
ask {
values ?label { "hello" "goodbye" }
filter not exists {
?s a :thing ; rdfs:label ?word
}
}
My group is developing tools to convert tabular data about hospital records into RDF triples and then perform various cleanups and aggregations.
I have started this "answer" by writing out an illustration of this workflow with sample data.
Working implementations of the suggestions from #Joshua Taylor and #AKSW's are at the bottom.
The tabular data is first converted into "shortcut triples", which instantiate a minimal number of classes and link all literal values to those classes, even if the literal values are really "more about" something else.
So tabular data like this:
+-------+------------+----------+----------+
| EncID | EncDate | DiagCode | CodeType |
+-------+------------+----------+----------+
| 102 | 12/05/2015 | J44.9 | ICD-10 |
| 103 | 11/25/2015 | 602.9 | ICD-9 |
| 102 | 12/05/2015 | I50.9 | ICD-10 |
+-------+------------+----------+----------+
First becomes triples like this (ignoring the EncDates and CodeTypes.)
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX obo: <http://purl.obolibrary.org/obo/>
PREFIX turbo: <http://example.org/ontologies/>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
INSERT DATA {
GRAPH turbo:encounters_from_karma {
turbo:5f62d61cee174283a4f875ccb8bb91a1 rdf:type obo:OGMS_0000097 .
turbo:5f62d61cee174283a4f875ccb8bb91a1 turbo:ScEnc2DiagCode "J44.9" .
turbo:5f62d61cee174283a4f875ccb8bb91a1 turbo:ScEnc2DiagCodeRegText "ICD-10" .
turbo:5f62d61cee174283a4f875ccb8bb91a1 turbo:ScEnc2EncID "102" .
turbo:81fcbb5c5bd141c9bde7f23321648ff7 rdf:type obo:OGMS_0000097 .
turbo:81fcbb5c5bd141c9bde7f23321648ff7 turbo:ScEnc2DiagCode "I50.9" .
turbo:81fcbb5c5bd141c9bde7f23321648ff7 turbo:ScEnc2DiagCodeRegText "ICD-10" .
turbo:81fcbb5c5bd141c9bde7f23321648ff7 turbo:ScEnc2EncID "102" .
turbo:820dd597229244ab853ed845dd740f1f rdf:type obo:OGMS_0000097 .
turbo:820dd597229244ab853ed845dd740f1f turbo:ScEnc2DiagCode "602.9" .
turbo:820dd597229244ab853ed845dd740f1f turbo:ScEnc2DiagCodeRegText "ICD-9" .
turbo:820dd597229244ab853ed845dd740f1f turbo:ScEnc2EncID "103" . }
}
And is then expanded like this
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX obo: <http://purl.obolibrary.org/obo/>
PREFIX turbo: <http://example.org/ontologies/>
INSERT {
GRAPH turbo:expanded_encounters {
?NewEnc rdf:type obo:OGMS_0000097 .
?NewEnc turbo:previousUriText ?previousUriText .
?NewEnc obo:OBI_0000299 ?DiagCrid .
?DiagCrid rdf:type turbo:DiagCrid .
?DiagCrid obo:BFO_0000051 ?DiagSymb .
?DiagSymb rdf:type turbo:EncounterDiagCodeSymbol .
?DiagSymb turbo:thingLiteralValue ?DiagSymbVal .
}
}
WHERE
{ GRAPH turbo:encounters_from_karma
{ ?EncFromKarma
rdf:type obo:OGMS_0000097 ;
turbo:ScEnc2DiagCode ?DiagSymbVal
BIND(str(?EncFromKarma) AS ?previousUriText)
BIND(uri(concat("http://transformunify.org/ontologies/", struuid())) AS ?NewEnc)
BIND(uri(concat("http://transformunify.org/ontologies/", struuid())) AS ?DiagCrid)
BIND(uri(concat("http://transformunify.org/ontologies/", struuid())) AS ?DiagSymb)
}
}
And therefore looks like this:
#prefix turbo: <http://purl.obolibrary.org/obo/> .
#prefix obo: <http://example.org/ontologies/> .
<http://example.org/ontologies/b9dc5b08-cf1b-465e-8773-4b19bfbcf803>
a <http://purl.obolibrary.org/obo/OGMS_0000097> ;
turbo:OBI_0000299 <http://example.org/ontologies/8a04f52f-22d2-4aab-bacf-d96e1c7fe900> ;
obo:previousUriText "http://example.org/ontologies/5f62d61cee174283a4f875ccb8bb91a1" .
obo:8a04f52f-22d2-4aab-bacf-d96e1c7fe900
a obo:DiagCrid ;
turbo:BFO_0000051 obo:6738d8c0-8bb8-4078-8430-5e9294e5af15 .
obo:6738d8c0-8bb8-4078-8430-5e9294e5af15
a obo:EncounterDiagCodeSymbol ;
obo:thingLiteralValue "J44.9" .
obo:d3a8a700-2eb9-420d-a863-d47462fa393c
a turbo:OGMS_0000097 ;
turbo:OBI_0000299 obo:c12acc26-6dbe-486d-9ae9-9f34c9561aea ;
obo:previousUriText "http://example.org/ontologies/81fcbb5c5bd141c9bde7f23321648ff7" .
obo:c12acc26-6dbe-486d-9ae9-9f34c9561aea
a obo:DiagCrid ;
turbo:BFO_0000051 obo:3b784151-b369-4594-9ce3-285f5fe60850 .
obo:3b784151-b369-4594-9ce3-285f5fe60850
a obo:EncounterDiagCodeSymbol ;
obo:thingLiteralValue "I50.9" .
obo:af0e949a-99e4-48cd-885b-7cb1aa3dd265
a turbo:OGMS_0000097 ;
turbo:OBI_0000299 obo:c2da52ec-7331-4011-b8f8-6fbf8b419708 ;
obo:previousUriText "http://example.org/ontologies/820dd597229244ab853ed845dd740f1f" .
obo:c2da52ec-7331-4011-b8f8-6fbf8b419708
a obo:DiagCrid ;
turbo:BFO_0000051 obo:7f8399ef-5fcd-447c-80a4-18dfb160e99c .
obo:7f8399ef-5fcd-447c-80a4-18dfb160e99c
a obo:EncounterDiagCodeSymbol ;
obo:thingLiteralValue "602.9" .
Finally, I can check for the correct transformation with the suggestions from #Joshua Taylor or #AKSW:
#Joshua Taylor
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX obo: <http://purl.obolibrary.org/obo/>
PREFIX turbo: <http://example.org/ontologies/>
ASK
WHERE
{ { GRAPH turbo:expanded_encounters
{ VALUES ( ?previousUriTextVal ?DiagSymbVal ) {
( "http://example.org/ontologies/5f62d61cee174283a4f875ccb8bb91a1" "J44.9" )
( "http://example.org/ontologies/820dd597229244ab853ed845dd740f1f" "602.9" )
( "http://example.org/ontologies/81fcbb5c5bd141c9bde7f23321648ff7" "I50.9" )
}
FILTER NOT EXISTS { ?NewEnc rdf:type obo:OGMS_0000097 ;
turbo:previousUriText ?previousUriTextVal ;
obo:OBI_0000299 ?DiagCrid .
?DiagCrid rdf:type turbo:DiagCrid ;
obo:BFO_0000051 ?DiagSymb .
?DiagSymb rdf:type turbo:EncounterDiagCodeSymbol ;
turbo:thingLiteralValue ?DiagSymbVal
}
}
}
}
#AKSW
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX obo: <http://purl.obolibrary.org/obo/>
PREFIX turbo: <http://example.org/ontologies/>
ASK
WHERE
{ GRAPH turbo:expanded_encounters
{ FILTER ( ?count = 3 )
{ SELECT (COUNT(DISTINCT ?NewEnc) AS ?count)
WHERE
{ VALUES ( ?previousUriTextVal ?DiagSymbVal ) {
( "http://example.org/ontologies/5f62d61cee174283a4f875ccb8bb91a1" "J44.9" )
( "http://example.org/ontologies/820dd597229244ab853ed845dd740f1f" "602.9" )
( "http://example.org/ontologies/81fcbb5c5bd141c9bde7f23321648ff7" "I50.9" )
}
?NewEnc rdf:type obo:OGMS_0000097 ;
turbo:previousUriText ?previousUriTextVal ;
obo:OBI_0000299 ?DiagCrid .
?DiagCrid rdf:type turbo:DiagCrid ;
obo:BFO_0000051 ?DiagSymb .
?DiagSymb rdf:type turbo:EncounterDiagCodeSymbol ;
turbo:thingLiteralValue ?DiagSymbVal
}
}
}
}