What is the difference between these shape graphs which use sh:or? - sparql

I have the following Data Graph.
#prefix hr: <http://learningsparql.com/ns/humanResources#> .
#prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
#prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
#prefix sch: <http://schema.org/> .
#prefix xml: <http://www.w3.org/XML/1998/namespace> .
#prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
hr:Another a rdfs:Class .
hr:Employee a rdfs:Class ;
rdfs:label "model" ;
rdfs:comment "a good employee" .
hr:Longer a hr:Employee ;
rdfs:label "model" ;
rdfs:comment "a good employee" .
hr:freestanding a rdf:Property ;
sch:rangeIncludes sch:Text .
hr:missing rdfs:comment "some comment about missing" .
hr:name a rdf:Property ;
sch:domainIncludes hr:Employee .
hr:nosuper a rdf:Property ;
sch:domainIncludes hr:Uncreated ;
sch:rangeIncludes sch:Text .
hr:randomtype a hr:invalidtype ;
rdfs:label "some label about randomtype" ;
rdfs:comment "some comment about randomtype" .
hr:typo a rdfs:Classs ;
rdfs:label "some label about typo" ;
rdfs:comment "some comment about typo" .
I am trying to understand the difference between these two Shape Graphs, which I think (wrongly!) should return the same result...validation errors for hr:typo, hr:randomtype, and hr:missing because there is no rdf:type property path to either rdfs:Class or rdf:Property.
The following Shape Graph produces the expected validation errors.
(A) -- good results
#prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
#prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
#prefix sch: <http://schema.org/> .
#prefix sh: <http://www.w3.org/ns/shacl#> .
#prefix ex: <http://example.org/> .
ex:ClassShape
a sh:NodeShape ;
sh:property [
sh:path [ sh:zeroOrMorePath rdf:type ];
sh:nodeKind sh:IRI ;
sh:hasValue rdfs:Class;
sh:message "class" ;
] .
ex:PropertyShape
a sh:NodeShape ;
sh:property [
sh:path [ sh:zeroOrMorePath rdf:type ];
sh:nodeKind sh:IRI ;
sh:hasValue rdf:Property;
sh:message "property" ;
] .
ex:ClassOrProperty
a sh:NodeShape ;
sh:target [
a sh:SPARQLTarget ;
sh:select """
SELECT ?this
WHERE {
?this ?p ?o .
}
""" ;
] ;
sh:or (
ex:ClassShape
ex:PropertyShape
);
.
The good and expected validation errors produced by (A) are:
Validation Report
Conforms: False
Results (3):
Constraint Violation in OrConstraintComponent (http://www.w3.org/ns/shacl#OrConstraintComponent):
Severity: sh:Violation
Source Shape: ex:ClassOrProperty
Focus Node: hr:randomtype
Value Node: hr:randomtype
Constraint Violation in OrConstraintComponent (http://www.w3.org/ns/shacl#OrConstraintComponent):
Severity: sh:Violation
Source Shape: ex:ClassOrProperty
Focus Node: hr:typo
Value Node: hr:typo
Constraint Violation in OrConstraintComponent (http://www.w3.org/ns/shacl#OrConstraintComponent):
Severity: sh:Violation
Source Shape: ex:ClassOrProperty
Focus Node: hr:missing
Value Node: hr:missing
However, this Shape Graph:
(B) -- bad results
#prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
#prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
#prefix sch: <http://schema.org/> .
#prefix sh: <http://www.w3.org/ns/shacl#> .
#prefix ex: <http://example.org/> .
ex:ClassOrProperty
a sh:NodeShape ;
sh:target [
a sh:SPARQLTarget ;
sh:select """
SELECT ?this
WHERE {
?this ?p ?o .
}
""" ;
] ;
sh:property [
sh:path [sh:zeroOrMorePath rdf:type] ;
sh:nodeKind sh:IRI ;
sh:or (
[ sh:hasValue rdfs:Class; ]
[ sh:hasValue rdf:Property; ]
)
];
.
does not produce only the expected validation errors. I get:
Validation Report
Conforms: False
Results (12):
Constraint Violation in OrConstraintComponent (http://www.w3.org/ns/shacl#OrConstraintComponent):
Severity: sh:Violation
Source Shape: [ sh:nodeKind sh:IRI ; sh:or ( [ sh:hasValue rdfs:Class ] [ sh:hasValue rdf:Property ] ) ; sh:path [ sh:zeroOrMorePath rdf:type ] ]
Focus Node: hr:freestanding
Value Node: hr:freestanding
Result Path: [ sh:zeroOrMorePath rdf:type ]
Constraint Violation in OrConstraintComponent (http://www.w3.org/ns/shacl#OrConstraintComponent):
Severity: sh:Violation
Source Shape: [ sh:nodeKind sh:IRI ; sh:or ( [ sh:hasValue rdfs:Class ] [ sh:hasValue rdf:Property ] ) ; sh:path [ sh:zeroOrMorePath rdf:type ] ]
Focus Node: hr:name
Value Node: hr:name
Result Path: [ sh:zeroOrMorePath rdf:type ]
Constraint Violation in OrConstraintComponent (http://www.w3.org/ns/shacl#OrConstraintComponent):
Severity: sh:Violation
Source Shape: [ sh:nodeKind sh:IRI ; sh:or ( [ sh:hasValue rdfs:Class ] [ sh:hasValue rdf:Property ] ) ; sh:path [ sh:zeroOrMorePath rdf:type ] ]
Focus Node: hr:Another
Value Node: hr:Another
Result Path: [ sh:zeroOrMorePath rdf:type ]
Constraint Violation in OrConstraintComponent (http://www.w3.org/ns/shacl#OrConstraintComponent):
Severity: sh:Violation
Source Shape: [ sh:nodeKind sh:IRI ; sh:or ( [ sh:hasValue rdfs:Class ] [ sh:hasValue rdf:Property ] ) ; sh:path [ sh:zeroOrMorePath rdf:type ] ]
Focus Node: hr:nosuper
Value Node: hr:nosuper
Result Path: [ sh:zeroOrMorePath rdf:type ]
Constraint Violation in OrConstraintComponent (http://www.w3.org/ns/shacl#OrConstraintComponent):
Severity: sh:Violation
Source Shape: [ sh:nodeKind sh:IRI ; sh:or ( [ sh:hasValue rdfs:Class ] [ sh:hasValue rdf:Property ] ) ; sh:path [ sh:zeroOrMorePath rdf:type ] ]
Focus Node: hr:Employee
Value Node: hr:Employee
Result Path: [ sh:zeroOrMorePath rdf:type ]
Constraint Violation in OrConstraintComponent (http://www.w3.org/ns/shacl#OrConstraintComponent):
Severity: sh:Violation
Source Shape: [ sh:nodeKind sh:IRI ; sh:or ( [ sh:hasValue rdfs:Class ] [ sh:hasValue rdf:Property ] ) ; sh:path [ sh:zeroOrMorePath rdf:type ] ]
Focus Node: hr:randomtype
Value Node: hr:randomtype
Result Path: [ sh:zeroOrMorePath rdf:type ]
Constraint Violation in OrConstraintComponent (http://www.w3.org/ns/shacl#OrConstraintComponent):
Severity: sh:Violation
Source Shape: [ sh:nodeKind sh:IRI ; sh:or ( [ sh:hasValue rdfs:Class ] [ sh:hasValue rdf:Property ] ) ; sh:path [ sh:zeroOrMorePath rdf:type ] ]
Focus Node: hr:randomtype
Value Node: hr:invalidtype
Result Path: [ sh:zeroOrMorePath rdf:type ]
Constraint Violation in OrConstraintComponent (http://www.w3.org/ns/shacl#OrConstraintComponent):
Severity: sh:Violation
Source Shape: [ sh:nodeKind sh:IRI ; sh:or ( [ sh:hasValue rdfs:Class ] [ sh:hasValue rdf:Property ] ) ; sh:path [ sh:zeroOrMorePath rdf:type ] ]
Focus Node: hr:typo
Value Node: hr:typo
Result Path: [ sh:zeroOrMorePath rdf:type ]
Constraint Violation in OrConstraintComponent (http://www.w3.org/ns/shacl#OrConstraintComponent):
Severity: sh:Violation
Source Shape: [ sh:nodeKind sh:IRI ; sh:or ( [ sh:hasValue rdfs:Class ] [ sh:hasValue rdf:Property ] ) ; sh:path [ sh:zeroOrMorePath rdf:type ] ]
Focus Node: hr:typo
Value Node: rdfs:Classs
Result Path: [ sh:zeroOrMorePath rdf:type ]
Constraint Violation in OrConstraintComponent (http://www.w3.org/ns/shacl#OrConstraintComponent):
Severity: sh:Violation
Source Shape: [ sh:nodeKind sh:IRI ; sh:or ( [ sh:hasValue rdfs:Class ] [ sh:hasValue rdf:Property ] ) ; sh:path [ sh:zeroOrMorePath rdf:type ] ]
Focus Node: hr:missing
Value Node: hr:missing
Result Path: [ sh:zeroOrMorePath rdf:type ]
Constraint Violation in OrConstraintComponent (http://www.w3.org/ns/shacl#OrConstraintComponent):
Severity: sh:Violation
Source Shape: [ sh:nodeKind sh:IRI ; sh:or ( [ sh:hasValue rdfs:Class ] [ sh:hasValue rdf:Property ] ) ; sh:path [ sh:zeroOrMorePath rdf:type ] ]
Focus Node: hr:Longer
Value Node: hr:Employee
Result Path: [ sh:zeroOrMorePath rdf:type ]
Constraint Violation in OrConstraintComponent (http://www.w3.org/ns/shacl#OrConstraintComponent):
Severity: sh:Violation
Source Shape: [ sh:nodeKind sh:IRI ; sh:or ( [ sh:hasValue rdfs:Class ] [ sh:hasValue rdf:Property ] ) ; sh:path [ sh:zeroOrMorePath rdf:type ] ]
Focus Node: hr:Longer
Value Node: hr:Longer
Result Path: [ sh:zeroOrMorePath rdf:type ]
Why are the results different?
The reason why I liked (B) over (A) is because it would have been more concise, if it had worked.
Both pySHACL and TopBraid SHACL API shaclvalidate.sh agree on the results.

It is important to understand how property paths work. A path is used to reach values. When using sh:path [sh:zeroOrMorePath rdf:path] and considering the node hr:Longer, it will reach three values -- (0) hr:Longer, (1) hr:Employee, and (2) rdfs:Class.
With this concept firmly in mind, what is going on in (B) and why it does not work can be fully explained.
Both (A) and (B) have the same target definition and will return the same focus nodes. These are:
hr:Another
hr:Employee
hr:Longer
hr:freestanding
hr:missing
hr:name
hr:nosuper
hr:randomtype
hr:typo
Additionally, common to both (A) and (B) is sh:path [sh:zeroOrMorePath rdf:type] ;. When considering the node hr:Longer, for example, it will emit three values, each of which may need to be checked. These three values are (0) hr:Longer, (1) hr:Employee, and (2) rdfs:Class.
For (B), when it considers hr:Longer and passes emitted value hr:Longer to sh:or, it see that it is not either a rdfs:Class or rdf:Property. A validation error is emitted because neither clause of sh:or was satisfied.
To make (B) work, the two clauses in the sh:or need to be changed to [ sh:path [sh:zeroOrMorePath rdf:type] ; sh:hasValue rdfs:Class; ] and [ sh:path [sh:zeroOrMorePath rdf:type] ; sh:hasValue rdf:Property; ]. In this case, when hr:Longer is passed into the sh:or, each clause checks the entire path and sh:hasValue only requires that one of the three values emitted by the path matches.
(B) - Working
#prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
#prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
#prefix sch: <http://schema.org/> .
#prefix sh: <http://www.w3.org/ns/shacl#> .
#prefix ex: <http://example.org/> .
ex:ClassOrProperty
a sh:NodeShape ;
sh:target [
a sh:SPARQLTarget ;
sh:select """
SELECT ?this
WHERE {
?this ?p ?o .
}
""" ;
] ;
sh:property [
sh:path [sh:zeroOrMorePath rdf:type] ;
sh:nodeKind sh:IRI ;
sh:or (
[ sh:path [sh:zeroOrMorePath rdf:type] ; sh:hasValue rdfs:Class; ]
[ sh:path [sh:zeroOrMorePath rdf:type] ; sh:hasValue rdf:Property; ]
)
];
.
Now considering (A), each focus node is passed to ex:PropertyShape and ex:ClassShape. If it validates against one of the shapes, it will validate. Both shapes are similar in that they each use the path sh:path [ sh:zeroOrMorePath rdf:type ];. Because they use sh:hasValue, only one of the emitted values for the path needs to match. Considering hr:Longer again, because the path will emit the value rdfs:Class, it validates against ex:ClassShape and no validation error is generated.

Related

SPARQL: Variable must be included in group by clause

For every sosa:FeatureOfInterest (room), get the lowest temperature per day from the associated sensors for that room. There are 100 rooms. Each room has 3 sensors. The timeframe is one year.
Goal: Query to select lowest temperature per day per room from group of sensors plus time of day when the temperature occurred.
Example data (N3):
prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
prefix sosa: <http://www.w3.org/ns/sosa/>
prefix xsd: <http://www.w3.org/2001/XMLSchema#>
prefix ex: <http://www.example.com/>
# Room FOIs
ex:room1Foi a sosa:FeatureOfInterest .
# ...
ex:room100Foi a sosa:FeatureOfInterest .
# Room 1 sensor observations 1/1/2021
ex:obs1Room1 a sosa:Observation .
sosa:hasFeatureOfInterest ex:room1Foi ;
sosa:resultTime "2021-01-01T00:00:00"^^xsd:dateTime ;
sosa:observedProperty "TEMP"^^xsd:string ;
sosa:hasSimpleResult "51.4"^^xsd:decimal .
ex:obs2Room1 a sosa:Observation .
sosa:hasFeatureOfInterest ex:room1Foi .
sosa:resultTime "2021-01-01T08:00:00"^^xsd:dateTime ;
sosa:observedProperty "TEMP"^^xsd:string ;
sosa:hasSimpleResult "50.2"^^xsd:decimal .
ex:obs3Room1 a sosa:Observation .
sosa:hasFeatureOfInterest ex:room1Foi .
sosa:resultTime "2021-01-01T:16:00"^^xsd:dateTime ;
sosa:observedProperty "TEMP"^^xsd:string ;
sosa:hasSimpleResult "49.8"^^xsd:decimal .
# Room 1 sensor observations 1/2/2021
ex:obs4Room1 a sosa:Observation .
sosa:hasFeatureOfInterest ex:room1Foi ;
sosa:resultTime "2021-01-02T00:00:00"^^xsd:dateTime ;
sosa:observedProperty "TEMP"^^xsd:string ;
sosa:hasSimpleResult "61.4"^^xsd:decimal .
ex:obs5Room1 a sosa:Observation .
sosa:hasFeatureOfInterest ex:room1Foi .
sosa:resultTime "2021-01-02T08:00:00"^^xsd:dateTime ;
sosa:observedProperty "TEMP"^^xsd:string ;
sosa:hasSimpleResult "60.2"^^xsd:decimal .
ex:obs6Room1 a sosa:Observation .
sosa:hasFeatureOfInterest ex:room1Foi .
sosa:resultTime "2021-01-02T:16:00"^^xsd:dateTime ;
sosa:observedProperty "TEMP"^^xsd:string ;
sosa:hasSimpleResult "59.8"^^xsd:decimal .
# ...
# Room 100 sensor observations 1/1/2021
ex:obs1Room100 a sosa:Observation .
sosa:hasFeatureOfInterest ex:room100Foi ;
sosa:resultTime "2021-01-01T00:00:00"^^xsd:dateTime ;
sosa:observedProperty "TEMP"^^xsd:string ;
sosa:hasSimpleResult "50.7"^^xsd:decimal .
ex:obs2Room100 a sosa:Observation .
sosa:hasFeatureOfInterest ex:room100Foi .
sosa:resultTime "2021-01-01T08:00:00"^^xsd:dateTime ;
sosa:observedProperty "TEMP"^^xsd:string ;
sosa:hasSimpleResult "51.6"^^xsd:decimal .
ex:obs3Room100 a sosa:Observation .
sosa:hasFeatureOfInterest ex:room100Foi .
sosa:resultTime "2021-01-01T:16:00"^^xsd:dateTime ;
sosa:observedProperty "TEMP"^^xsd:string ;
sosa:hasSimpleResult "48.0"^^xsd:decimal .
# Room 1 sensor observations 1/2/2021
# ...
One attempt:
prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
prefix sosa: <http://www.w3.org/ns/sosa/>
prefix xsd: <http://www.w3.org/2001/XMLSchema#>
prefix ex: <http://www.example1.com/>
select ?oFoi ?day min(?val) as ?minTemp ?time where {
{select ?f where {
?f a sosa:FeatureOfInterest .
}}
?o a sosa:Observation ;
sosa:hasFeatureOfInterest ?oFoi ;
sosa:resultTime ?time ;
sosa:observedProperty ?p ;
sosa:hasSimpleResult ?val .
filter(?oFoi = ?f) .
bind(day(?t) as ?day) .
} group by ?oFoi ?day ?time
order by desc(?oFoi) asc(?day)
Result:
oFoi
day
minTemp
time
http://www.example.com/room1Foi
1
51.4
2021-01-01 0:00:00
http://www.example.com/room1Foi
1
50.2
2021-01-01 8:00:00
http://www.example.com/room1Foi
1
49.8
2021-01-01 16:00:00
http://www.example.com/room1Foi
2
59.8
2021-01-02 16:00:00
http://www.example.com/room1Foi
2
60.2
2021-01-02 8:00:00
http://www.example.com/room1Foi
2
61.4
2021-01-02 0:00:00
...
...
...
...
This doesn't work because ?time must be included in the group by clause. Removing ?time from group by clause will return the correct rows. However, ?time is necessary to be included.
Ideal result:
oFoi
day
minTemp
time
http://www.example.com/room1Foi
1
49.8
2021-01-01 16:00:00
http://www.example.com/room1Foi
2
59.8
2021-01-02 16:00:00
...
...
...
...
Update:
This gets closer but still is including multiple results when two times in the same day have the same temperature (both results included):
select ?o2 ?oFoi2 ?day2 ?val2 sample(?t2) as ?tx2 ?p2 where {
?o2 a sosa:Observation ;
sosa:hasFeatureOfInterest ?oFoi2 ;
sosa:resultTime ?t2 ;
sosa:observedProperty ?p2 ;
sosa:hasSimpleResult ?val2 .
bind(day(?t2) as ?day2) .
filter(?oFoi2 = ?oFoi) .
filter(?day2 = ?day) .
filter(?val2 = ?vx) .
{select ?oFoi ?day min(?val) as ?vx where {
{select ?f where {
?f a sosa:FeatureOfInterest .
}}
?o a sosa:Observation ;
sosa:hasFeatureOfInterest ?oFoi ;
sosa:resultTime ?t ;
sosa:observedProperty ?p ;
sosa:hasSimpleResult ?val .
filter(?oFoi = ?f) .
bind(day(?t) as ?day) .
} group by ?oFoi ?day
order by desc(?oFoi) asc(?day)
}
} group by ?o2 ?oFoi2 ?day2 ?p2 ?val2
Result:
o2
oFoi2
day2
val2
tx2
p2
http://www.example3.com/obs3Room100
http://www.example3.com/room100Foi
1
48
2021-01-01 16:00:00
"TEMP"^^http://www.w3.org/2001/XMLSchema#string
http://www.example3.com/obs6Room1
http://www.example3.com/room1Foi
2
59.8
2021-01-02 16:00:00
"TEMP"^^http://www.w3.org/2001/XMLSchema#string
http://www.example3.com/obs333Room1
http://www.example3.com/room1Foi
1
-9.8
2021-01-01 16:00:00
"aTEMP"^^http://www.w3.org/2001/XMLSchema#string
http://www.example3.com/obs33Room1
http://www.example3.com/room1Foi
1
-9.8
2021-01-01 7:59:00
"aTEMP"^^http://www.w3.org/2001/XMLSchema#string
...
...
...
...
...
...
Oops: ?o2 is unnecessary and removing it from the above query results in the correct solution.
Adding an outer select appears to solve this. Using an aggregate for the time such as min(), max(), avg(), sample(), etc. are all valid approaches for aggregating the time variable. (Adding an extra property aTEMP to help in understanding.)
Query:
select ?oFoi2 ?day2 ?val2 sample(?t2) as ?tx2 ?p2 where {
?o2 a sosa:Observation ;
sosa:hasFeatureOfInterest ?oFoi2 ;
sosa:resultTime ?t2 ;
sosa:observedProperty ?p2 ;
sosa:hasSimpleResult ?val2 .
bind(day(?t2) as ?day2) .
filter(?oFoi2 = ?oFoi) .
filter(?day2 = ?day) .
filter(?val2 = ?vx) .
{select ?oFoi ?day min(?val) as ?vx where {
{select ?f where {
?f a sosa:FeatureOfInterest .
}}
?o a sosa:Observation ;
sosa:hasFeatureOfInterest ?oFoi ;
sosa:resultTime ?t ;
sosa:observedProperty ?p ;
sosa:hasSimpleResult ?val .
filter(?oFoi = ?f) .
bind(day(?t) as ?day) .
} group by ?oFoi ?day
order by desc(?oFoi) asc(?day)
}
} group by ?oFoi2 ?day2 ?p2 ?val2
Result:
oFoi2
day2
val2
tx2
p2
http://www.example3.com/room100Foi
1
48
2021-01-01 16:00:00
"TEMP"^^http://www.w3.org/2001/XMLSchema#string
http://www.example3.com/room1Foi
2
59.8
2021-01-02 16:00:00
"TEMP"^^http://www.w3.org/2001/XMLSchema#string
http://www.example3.com/room1Foi
1
-9.8
2021-01-01 7:59:00
"aTEMP"^^http://www.w3.org/2001/XMLSchema#string
...
...
...
...
...

using conditional CONSTRUCT queries in SPARQL

I am in need of some help regarding SPARQL construct queries. How is it possible to make a CONSTRUCT query with an IF condition to get triples that enable rules representation?
Like a CONSTRUCT query that enables us to express the following rules:
If X is an instance of a C1 class, and C1 is a subclass of a C2 class, then X is an instance of C2.
and
If X has in P1 property the value V, and P1 is a subproperty of P2, then X has in property P2 the value V.
For this Data File (Beatles.ttl)
#prefix c: <http://beatlesExample/ns/class/> .
#prefix t: <http://beatlesExample/ns/title/> .
#prefix pi: <http://beatlesExample/ns/playsInstrument/> .
#prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
#prefix m: <http://beatlesExample/ns/musician/> .
t:MagicalMysteryTour a c:Song ;
rdfs:label "Magical Mystery Tour" ;
pi:acousticrhythmguitar m:JohnLennon ;
pi:bass m:PaulMcCartney ;
pi:drums m:RingoStarr ;
pi:leadguitar m:GeorgeHarrison ;
pi:percussion m:RingoStarr , m:NeilAspinall , m:MalEvans , m:GeorgeHarrison , m:JohnLennon ;
pi:piano m:PaulMcCartney ;
pi:trumpet m:ElgarHowarth , m:JohnWilbraham , m:DavidMason , m:RoyCopestake ;
pi:vocals m:JohnLennon , m:PaulMcCartney , m:GeorgeHarrison .
t:PennyLane a c:Song ;
rdfs:label "Penny Lane" ;
pi:acousticguitar m:JohnLennon ;
pi:backingvocals m:JohnLennon , m:GeorgeHarrison ;
pi:bassguitar m:PaulMcCartney ;
pi:doublebass m:FrankClarke ;
pi:drums m:RingoStarr ;
pi:electricguitar m:JohnLennon ;
pi:flutesorpiccolos m:PGoody , m:RaySwinfield , m:MannyWinters , m:DennisWalton ;
pi:guitar m:GeorgeHarrison ;
pi:handclaps m:GeorgeHarrison , m:JohnLennon , m:PaulMcCartney ;
pi:harmonium m:PaulMcCartney ;
pi:oboesorcoranglais m:DickMorgan , m:MikeWinfield ;
pi:piano m:JohnLennon , m:PaulMcCartney ;
pi:tambourine m:RingoStarr ;
pi:trumpetsorflugelhorn m:FreddyClayton , m:LeonCalvert , m:BertCourtley , m:DuncanCampbell , m:DavidMason ;
pi:tubularbells m:RingoStarr ;
pi:vocals m:PaulMcCartney .
t:NotASecondTime a c:Song ;
rdfs:label "Not A Second Time" ;
pi:acousticrhythmguitar m:JohnLennon ;
pi:bass m:PaulMcCartney ;
pi:drums m:RingoStarr ;
pi:piano m:GeorgeMartin ;
pi:vocals m:JohnLennon .
t:Yesterday a c:Song ;
rdfs:label "Yesterday" ;
pi:cello m:FranciscoGabarro ;
pi:guitar m:PaulMcCartney ;
pi:viola m:KennethEssex ;
pi:violin m:TonyGilbert , m:SidneySax ;
pi:vocals m:PaulMcCartney .
t:LosParanoias a c:Song ;
rdfs:label "Los Paranoias" ;
pi:acousticguitar m:PaulMcCartney ;
pi:percussion m:JohnLennon ;
pi:shaker m:RingoStarr ;
pi:vocals m:PaulMcCartney .
t:LikeDreamersDo a c:Song ;
rdfs:label "Like Dreamers Do" ;
pi:bass m:PaulMcCartney ;
pi:drums m:PeteBest ;
pi:leadguitar m:GeorgeHarrison ;
pi:rhythmguitar m:JohnLennon ;
pi:vocals m:PaulMcCartney .
t:IGotToFindMyBaby a c:Song ;
rdfs:label "I Got To Find My Baby" ;
pi:bass m:PaulMcCartney ;
pi:drums m:RingoStarr ;
pi:harmonica m:JohnLennon ;
pi:leadguitar m:GeorgeHarrison ;
pi:rhythmguitar m:JohnLennon ;
pi:vocals m:JohnLennon .
t:Revolution1 a c:Song ;
rdfs:label "Revolution 1" ;
pi:Hammondorgan m:PaulMcCartney ;
pi:acousticguitar m:JohnLennon ;
pi:backingvocals m:FrancieSchwartz , m:GeorgeHarrison , m:PaulMcCartney ;
pi:bass m:PaulMcCartney ;
pi:drums m:RingoStarr ;
pi:leadguitar m:GeorgeHarrison , m:JohnLennon ;
pi:piano m:PaulMcCartney ;
pi:trombone m:JPower , m:DonLang , m:BillPovey , m:RexMorris ;
pi:trumpet m:FreddyClayton , m:DerekWatkins ;
pi:vocals m:JohnLennon .
t:DizzyMissLizzy a c:Song ;
rdfs:label "Dizzy Miss Lizzy" ;
pi:Hammondorgan m:JohnLennon ;
pi:HohnerPianetelectricpiano m:PaulMcCartney ;
pi:bass m:PaulMcCartney ;
pi:cowbell m:RingoStarr ;
pi:double-trackedleadguitar m:GeorgeHarrison ;
pi:drums m:RingoStarr ;
pi:rhythmguitar m:JohnLennon ;
pi:vocals m:JohnLennon .
t:YesItIs a c:Song ;
rdfs:label "Yes It Is" ;
pi:acousticrhythmguitar m:JohnLennon ;
pi:bass m:PaulMcCartney ;
pi:drums m:RingoStarr ;
pi:harmonyvocals m:GeorgeHarrison , m:PaulMcCartney ;
pi:leadguitar m:GeorgeHarrison ;
pi:tambourine m:RingoStarr ;
pi:vocals m:JohnLennon .
t:IWannaBeYourMan a c:Song ;
rdfs:label "I Wanna Be Your Man" ;
pi:Hammondorgan m:GeorgeMartin ;
pi:backingvocals m:PaulMcCartney , m:JohnLennon ;
pi:bass m:PaulMcCartney ;
pi:drums m:RingoStarr ;
pi:leadguitar m:GeorgeHarrison ;
pi:maracas m:RingoStarr ;
pi:rhythmguitar m:JohnLennon ;
pi:vocals m:RingoStarr .
t:ThingsWeSaidToday a c:Song ;
rdfs:label "Things We Said Today" ;
pi:acousticrhythmguitar m:JohnLennon ;
pi:bass m:PaulMcCartney ;
pi:drums m:RingoStarr ;
pi:leadguitar m:GeorgeHarrison ;
pi:piano m:JohnLennon ;
pi:tambourine m:RingoStarr ;
pi:vocals m:PaulMcCartney .
t:HallelujahILoveHerSo
a c:Song ;
rdfs:label "Hallelujah, I Love Her So" ;
pi:bass m:StuartSutcliffe ;
pi:guitar m:GeorgeHarrison , m:PaulMcCartney , m:JohnLennon ;
pi:vocals m:PaulMcCartney .
t:OldBrownShoe a c:Song ;
rdfs:label "Old Brown Shoe" ;
pi:backingvocals m:JohnLennon , m:PaulMcCartney ;
pi:bass m:GeorgeHarrison ;
pi:drums m:RingoStarr ;
pi:guitar m:GeorgeHarrison , m:PaulMcCartney ;
pi:organ m:GeorgeHarrison ;
pi:piano m:PaulMcCartney ;
pi:vocals m:GeorgeHarrison .
t:GoodNight a c:Song ;
rdfs:label "Good Night" ;
pi:12violins m:Uncredited ;
pi:backingvocals m:MikeRedway , m:PatWhitmore , m:FredLucas , m:ValStockwell , m:IreneKing , m:IngridThomas , m:KenBarrie , m:RossGilmour ;
pi:celesta m:GeorgeMartin ;
pi:clarinet m:Uncredited ;
pi:doublebass m:Uncredited ;
pi:harp m:Uncredited ;
pi:horn m:Uncredited ;
pi:threecellos m:Uncredited ;
pi:threeflutes m:Uncredited ;
pi:threeviolas m:Uncredited ;
pi:vibraphone m:Uncredited ;
pi:vocals m:RingoStarr .
t:MemphisTennessee a c:Song ;
rdfs:label "Memphis, Tennessee" ;
pi:bass m:PaulMcCartney ;
pi:drums m:RingoStarr ;
pi:leadguitar m:GeorgeHarrison ;
pi:rhythmguitar m:JohnLennon ;
pi:vocals m:JohnLennon .
t:TicketToRide a c:Song ;
rdfs:label "Ticket To Ride" ;
pi:bass m:PaulMcCartney ;
pi:double-trackedleadvocals m:JohnLennon ;
pi:drums m:RingoStarr ;
pi:handclaps m:RingoStarr ;
pi:harmonyvocals m:PaulMcCartney ;
pi:leadguitar m:PaulMcCartney ;
pi:rhythmguitar m:GeorgeHarrison , m:JohnLennon ;
pi:tambourine m:RingoStarr .
t:Ob-La-DiOb-La-Da a c:Song ;
rdfs:label "Ob-La-Di, Ob-La-Da" ;
pi:acousticguitar m:GeorgeHarrison ;
pi:backingvocals m:JohnLennon , m:GeorgeHarrison ;
pi:bass m:PaulMcCartney ;
pi:bongo m:RingoStarr ;
pi:drums m:RingoStarr ;
pi:handclaps m:JohnLennon , m:PaulMcCartney , m:GeorgeHarrison , m:RingoStarr ;
pi:percussion m:RingoStarr ;
pi:piano m:JohnLennon ;
pi:threesaxophones m:Uncredited ;
pi:vocals m:PaulMcCartney .
t:LetItBe a c:Song ;
rdfs:label "Let It Be" ;
pi:backingvocals m:JohnLennon , m:LindaMcCartney , m:PaulMcCartney , m:GeorgeHarrison ;
pi:bassguitar m:PaulMcCartney ;
pi:cello m:Uncredited ;
pi:drums m:RingoStarr ;
pi:electricpiano m:BillyPreston ;
pi:leadguitar m:GeorgeHarrison ;
pi:maracas m:PaulMcCartney ;
pi:organ m:BillyPreston ;
pi:piano m:PaulMcCartney ;
pi:tenorsaxophone m:Uncredited ;
pi:twotrombones m:Uncredited ;
pi:twotrumpets m:Uncredited ;
pi:vocals m:PaulMcCartney .
t:IGotAWoman a c:Song ;
rdfs:label "I Got A Woman" ;
pi:bass m:PaulMcCartney ;
pi:drums m:RingoStarr ;
pi:leadguitar m:GeorgeHarrison ;
pi:rhythmguitar m:JohnLennon ;
pi:vocals m:JohnLennon .
t:TheSaints a c:Song ;
rdfs:label "The Saints" ;
pi:bass m:PaulMcCartney ;
pi:drums m:PeteBest ;
pi:leadguitar m:TonySheridan , m:GeorgeHarrison ;
pi:rhythmguitar m:JohnLennon ;
pi:vocals m:TonySheridan .
t:LendMeYourComb a c:Song ;
rdfs:label "Lend Me Your Comb" ;
pi:bass m:PaulMcCartney ;
pi:drums m:RingoStarr ;
pi:leadguitar m:GeorgeHarrison ;
pi:rhythmguitar m:JohnLennon ;
pi:vocals m:GeorgeHarrison , m:PaulMcCartney , m:JohnLennon .
t:BesameMucho a c:Song ;
rdfs:label "Besame Mucho" ;
pi:bass m:PaulMcCartney ;
pi:drums m:PeteBest ;
pi:leadguitar m:GeorgeHarrison ;
pi:rhythmguitar m:JohnLennon ;
pi:vocals m:PaulMcCartney .
As suggested in the comments: you don't actually need a conditional to express this. All you're doing in the left-hand side of the rule is matching a combination of triple patterns. This is exactly what the WHERE clause in a SPARQL query does. Similarly, the right-hand side of the rule simply recombines matched resources into new triple patterns - this is exactly what the CONSTRUCT clause does. For example:
If X is an instance of a C1 class, and C1 is a subclass of a C2 class, then X is an instance of C2.
That could be expressed as:
CONSTRUCT { ?X a ?C2 }
WHERE { ?X a ?C1. ?C1 rdfs:subClassOf+ ?C2 }
Similarly:
If X has in P1 property the value V, and P1 is a subproperty of P2, then X has in property P2 the value V.
could be expressed as:
CONSTRUCT { ?X ?P2 ?V }
WHERE { ?X ?P1 ?V . ?P1 rdfs:subPropertyOf+ ?P2 }
That's all you need.

How to Access Colspan table in SPARQL?

[EDIT]
I have this RDF :
#prefix : <http://www.x.com/ontology#> .
#prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
#prefix owl: <http://www.w3.org/2002/07/owl#> .
#prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
#prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
#prefix ontology: <http://www.x.com/ontology/> .
<http://www.x.com/ontology>
a owl:Ontology .
ontology:melalui_jalur
a owl:ObjectProperty .
ontology:memiliki_peminat
a owl:ObjectProperty .
ontology:alias a owl:DatatypeProperty .
ontology:jumlah a owl:DatatypeProperty .
ontology:nama a owl:DatatypeProperty .
ontology:tahun a owl:DatatypeProperty .
ontology:Jalur_Terima
a owl:Class ;
rdfs:subClassOf [ a owl:Restriction ;
owl:allValuesFrom xsd:string ;
owl:onProperty ontology:alias
] ;
rdfs:subClassOf [ a owl:Restriction ;
owl:allValuesFrom xsd:string ;
owl:onProperty ontology:nama
] ;
rdfs:subClassOf [ a owl:Restriction ;
owl:allValuesFrom xsd:string ;
owl:onProperty ontology:alias
] ;
rdfs:subClassOf [ a owl:Restriction ;
owl:allValuesFrom xsd:string ;
owl:onProperty ontology:nama
] .
ontology:Peminat a owl:Class ;
rdfs:subClassOf ontology:Penerimaan ;
rdfs:subClassOf [ a owl:Restriction ;
owl:allValuesFrom xsd:int ;
owl:onProperty ontology:jumlah
] ;
rdfs:subClassOf [ a owl:Restriction ;
owl:allValuesFrom xsd:int ;
owl:onProperty ontology:tahun
] ;
rdfs:subClassOf [ a owl:Restriction ;
owl:allValuesFrom xsd:int ;
owl:onProperty ontology:jumlah
] ;
rdfs:subClassOf [ a owl:Restriction ;
owl:allValuesFrom xsd:int ;
owl:onProperty ontology:tahun
] .
ontology:Penerimaan a owl:Class ;
rdfs:subClassOf [ a owl:Restriction ;
owl:onProperty ontology:melalui_jalur ;
owl:someValuesFrom ontology:Jalur_Terima
] ;
rdfs:subClassOf [ a owl:Restriction ;
owl:onProperty ontology:melalui_jalur ;
owl:someValuesFrom ontology:Jalur_Terima
] .
ontology:Prodi a owl:Class ;
rdfs:subClassOf [ a owl:Restriction ;
owl:onProperty ontology:memiliki_peminat ;
owl:someValuesFrom ontology:Peminat
] ;
rdfs:subClassOf [ a owl:Restriction ;
owl:allValuesFrom xsd:string ;
owl:onProperty ontology:alias
] ;
rdfs:subClassOf [ a owl:Restriction ;
owl:allValuesFrom xsd:string ;
owl:onProperty ontology:nama
] ;
rdfs:subClassOf [ a owl:Restriction ;
owl:onProperty ontology:memiliki_peminat ;
owl:someValuesFrom ontology:Peminat
] ;
rdfs:subClassOf [ a owl:Restriction ;
owl:allValuesFrom xsd:string ;
owl:onProperty ontology:alias
] ;
rdfs:subClassOf [ a owl:Restriction ;
owl:allValuesFrom xsd:string ;
owl:onProperty ontology:nama
] .
ontology:Non_Reguler a ontology:Jalur_Terima , owl:NamedIndividual .
ontology:Pem_Non_2017
a ontology:Peminat , owl:NamedIndividual ;
ontology:jumlah 0 ;
ontology:melalui_jalur ontology:Non_Reguler ;
ontology:tahun 2017 .
ontology:Pem_Non_2018
a ontology:Peminat , owl:NamedIndividual ;
ontology:jumlah 0 ;
ontology:melalui_jalur ontology:Non_Reguler ;
ontology:tahun 2018 .
ontology:Pem_SAP_2017
a ontology:Peminat , owl:NamedIndividual ;
ontology:jumlah 8 ;
ontology:melalui_jalur ontology:SAP ;
ontology:tahun 2017 .
ontology:SAP a ontology:Jalur_Terima , owl:NamedIndividual .
ontology:Pem_SAP_2018
a ontology:Peminat , owl:NamedIndividual ;
ontology:jumlah 7 ;
ontology:melalui_jalur ontology:SAP ;
ontology:tahun 2018 .
ontology:Pem_SBM_2017
a ontology:Peminat , owl:NamedIndividual ;
ontology:jumlah 6 ;
ontology:melalui_jalur ontology:SBMPTN ;
ontology:tahun 2017 .
ontology:SBMPTN a ontology:Jalur_Terima , owl:NamedIndividual .
ontology:Pem_SBM_2018
a ontology:Peminat , owl:NamedIndividual ;
ontology:jumlah 5 ;
ontology:melalui_jalur ontology:SBMPTN ;
ontology:tahun 2018 .
ontology:Pem_SNM_2017
a ontology:Peminat , owl:NamedIndividual ;
ontology:jumlah 4 ;
ontology:melalui_jalur ontology:SNMPTN ;
ontology:tahun 2017 .
ontology:SNMPTN a ontology:Jalur_Terima , owl:NamedIndividual .
ontology:Pem_SNM_2018
a ontology:Peminat , owl:NamedIndividual ;
ontology:jumlah 3 ;
ontology:melalui_jalur ontology:SNMPTN ;
ontology:tahun 2018 .
ontology:Pem_SPMK_2017
a ontology:Peminat , owl:NamedIndividual ;
ontology:jumlah 2 ;
ontology:melalui_jalur ontology:SPMK ;
ontology:tahun 2017 .
ontology:SPMK a ontology:Jalur_Terima , owl:NamedIndividual .
ontology:Pem_SPMK_2018
a ontology:Peminat , owl:NamedIndividual ;
ontology:jumlah 1 ;
ontology:melalui_jalur ontology:SPMK ;
ontology:tahun 2018 .
ontology:TIF a ontology:Prodi , owl:NamedIndividual ;
ontology:memiliki_peminat ontology:Pem_Non_2017 , ontology:Pem_Non_2018 , ontology:Pem_SAP_2017 , ontology:Pem_SAP_2018 , ontology:Pem_SBM_2017 , ontology:Pem_SBM_2018 , ontology:Pem_SNM_2017 , ontology:Pem_SNM_2018 , ontology:Pem_SPMK_2017 , ontology:Pem_SPMK_2018 .
Expected Result :
i want to access (tahun and jumlah)-data property in Peminat based on Jalur_Terima so the data can showed into this
table
right now i can access my table using this query
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX x: <http://www.x.com/ontology/>
SELECT ?tahun ?snm_pem ?sbm_pem ?spmk_pem ?sap_pem ?non_pem
WHERE {
Bind(x:TIF as ?tif)
?tif x:memiliki_peminat ?pem1.
?pem1 x:tahun ?tahun;
x:melalui_jalur x:SNMPTN;
x:jumlah ?snm_pem.
x:TIF x:memiliki_peminat ?pem2.
?pem2 x:tahun ?tahun;
x:melalui_jalur x:SBMPTN;
x:jumlah ?sbm_pem.
x:TIF x:memiliki_peminat ?pem3.
?pem3 x:tahun ?tahun;
x:melalui_jalur x:SPMK;
x:jumlah ?spmk_pem.
x:TIF x:memiliki_peminat ?pem4.
?pem4 x:tahun ?tahun;
x:melalui_jalur x:SAP;
x:jumlah ?sap_pem.
x:TIF x:memiliki_peminat ?pem5.
?pem5 x:tahun ?tahun;
x:melalui_jalur x:Non_Reguler;
x:jumlah ?non_pem.
}
ORDER BY DESC(?tahun)
i'd like to ask,
how to simplify this Query? or is there any other method to access it?
thank you

Perform a coordinate transformation of a 4th-order tensor with np.einsum and np.tensordot

The equation is
$C'_{ijkl} = Q_{im} Q_{jn} C_{mnop} (Q^{-1})_{ok} (Q^{-1})_{pl}$
I was able to use
np.einsum('im,jn,mnop,ok,pl', Q, Q, C, Q_inv, Q_inv)
to do the job, and also expect
np.tensordot(np.tensordot(np.tensordot(Q, np.tensordot(Q, C, axes=[1,1]), axes=[1,0]), Q_inv, axes=[2,0]), Q_inv, axes=[3,0])
to work, but it doesn't.
Specifics:
C is a 4th-order elastic tensor:
array([[[[ 552.62389047, -0.28689554, -0.32194701],
[ -0.28689554, 118.89168597, -0.65559912],
[ -0.32194701, -0.65559912, 130.21758722]],
[[ -0.28689554, 166.02923119, -0.00000123],
[ 166.02923119, 0.49494431, -0.00000127],
[ -0.00000123, -0.00000127, -0.57156702]],
[[ -0.32194701, -0.00000123, 165.99413061],
[ -0.00000123, -0.64666809, -0.0000013 ],
[ 165.99413061, -0.0000013 , 0.42997465]]],
[[[ -0.28689554, 166.02923119, -0.00000123],
[ 166.02923119, 0.49494431, -0.00000127],
[ -0.00000123, -0.00000127, -0.57156702]],
[[ 118.89168597, 0.49494431, -0.64666809],
[ 0.49494431, 516.15898907, -0.33132485],
[ -0.64666809, -0.33132485, 140.09010389]],
[[ -0.65559912, -0.00000127, -0.0000013 ],
[ -0.00000127, -0.33132485, 165.98553869],
[ -0.0000013 , 165.98553869, 0.41913346]]],
[[[ -0.32194701, -0.00000123, 165.99413061],
[ -0.00000123, -0.64666809, -0.0000013 ],
[ 165.99413061, -0.0000013 , 0.42997465]],
[[ -0.65559912, -0.00000127, -0.0000013 ],
[ -0.00000127, -0.33132485, 165.98553869],
[ -0.0000013 , 165.98553869, 0.41913346]],
[[ 130.21758722, -0.57156702, 0.42997465],
[ -0.57156702, 140.09010389, 0.41913346],
[ 0.42997465, 0.41913346, 486.62412063]]]])
Q is a rotation matrix changing x and y coords.
array([[ 0, 1, 0],
[-1, 0, 0],
[ 0, 0, 1]])
Q_inv is
array([[-0., -1., -0.],
[ 1., 0., 0.],
[ 0., 0., 1.]])
np.einsum leads to
array([[[[ 516.15898907, -0.49494431, -0.33132485],
[ -0.49494431, 118.89168597, 0.64666809],
[ -0.33132485, 0.64666809, 140.09010389]],
[[ -0.49494431, 166.02923119, 0.00000127],
[ 166.02923119, 0.28689554, -0.00000123],
[ 0.00000127, -0.00000123, 0.57156702]],
[[ -0.33132485, 0.00000127, 165.98553869],
[ 0.00000127, -0.65559912, 0.0000013 ],
[ 165.98553869, 0.0000013 , 0.41913346]]],
[[[ -0.49494431, 166.02923119, 0.00000127],
[ 166.02923119, 0.28689554, -0.00000123],
[ 0.00000127, -0.00000123, 0.57156702]],
[[ 118.89168597, 0.28689554, -0.65559912],
[ 0.28689554, 552.62389047, 0.32194701],
[ -0.65559912, 0.32194701, 130.21758722]],
[[ 0.64666809, -0.00000123, 0.0000013 ],
[ -0.00000123, 0.32194701, 165.99413061],
[ 0.0000013 , 165.99413061, -0.42997465]]],
[[[ -0.33132485, 0.00000127, 165.98553869],
[ 0.00000127, -0.65559912, 0.0000013 ],
[ 165.98553869, 0.0000013 , 0.41913346]],
[[ 0.64666809, -0.00000123, 0.0000013 ],
[ -0.00000123, 0.32194701, 165.99413061],
[ 0.0000013 , 165.99413061, -0.42997465]],
[[ 140.09010389, 0.57156702, 0.41913346],
[ 0.57156702, 130.21758722, -0.42997465],
[ 0.41913346, -0.42997465, 486.62412063]]]])
which I believe is correct, while four np.tensordot leads to
array([[[[ 552.62389047, -0.28689554, 0.32194701],
[ -0.28689554, 118.89168597, 0.65559912],
[ -0.32194701, -0.65559912, -130.21758722]],
[[ -0.28689554, 166.02923119, 0.00000123],
[ 166.02923119, 0.49494431, 0.00000127],
[ -0.00000123, -0.00000127, 0.57156702]],
[[ -0.32194701, -0.00000123, -165.99413061],
[ -0.00000123, -0.64666809, 0.0000013 ],
[ 165.99413061, -0.0000013 , -0.42997465]]],
[[[ -0.28689554, 166.02923119, 0.00000123],
[ 166.02923119, 0.49494431, 0.00000127],
[ -0.00000123, -0.00000127, 0.57156702]],
[[ 118.89168597, 0.49494431, 0.64666809],
[ 0.49494431, 516.15898907, 0.33132485],
[ -0.64666809, -0.33132485, -140.09010389]],
[[ -0.65559912, -0.00000127, 0.0000013 ],
[ -0.00000127, -0.33132485, -165.98553869],
[ -0.0000013 , 165.98553869, -0.41913346]]],
[[[ 0.32194701, 0.00000123, 165.99413061],
[ 0.00000123, 0.64666809, -0.0000013 ],
[-165.99413061, 0.0000013 , 0.42997465]],
[[ 0.65559912, 0.00000127, -0.0000013 ],
[ 0.00000127, 0.33132485, 165.98553869],
[ 0.0000013 , -165.98553869, 0.41913346]],
[[-130.21758722, 0.57156702, 0.42997465],
[ 0.57156702, -140.09010389, 0.41913346],
[ -0.42997465, -0.41913346, 486.62412063]]]])
Notice the negative big numbers.
Approach #1
One way would be to use np.tensordot to get the same result as with np.einsum though not in a single step and with some help from the trusty broadcasting -
# Get broadcasted elementwise multiplication between two versions of Q.
# This corresponds to "np.einsum('im,jn,..', Q, Q)" producing "'ijmn""
# broadcasted version of elementwise multiplications between Q's.
Q_ext = Q[:,None,:,None]*Q[:,None,:]
# Similarly for Q_inv : For "np.einsum('..ok,pl', Q_inv, Q_inv)" get "'opkl'"
# broadcasted version of elementwise multiplications between Q_inv's.
Q_inv_ext = Q_inv[:,None,:,None]*Q_inv[:,None,:]
# Perform "np.einsum('im,jn,mnop,ok,pl', Q, Q, C)" with "np.tensordot".
# Notice that we are using the last two axes from 'Q_ext', so "axes=[2,3]"
# and first two from 'C', so "axes=[0,1]" for it.
# These axes would be reduced by the dot-product, leaving us with 'ijop'.
parte1 = np.tensordot(Q_ext,C,axes=([2,3],[0,1]))
# Do it one more time to perform "np.einsum('ijop,ok,pl', parte1,Q_inv,Q_inv)"
# to reduce dimensions represented by 'o,p', leaving us with 'ijkl'.
# To confirm, compare the following against original einsum approach :
# "np.einsum('im,jn,mnop,ok,pl->ijkl', Q, Q, C, Q_inv, Q_inv)"
out = np.tensordot(parte1,Q_inv_ext,axes=([2,3],[0,1]))
Approach #2
If you wish to avoid broadcasting in favour of using two more instances of np.tensordot, you could do -
# Perform "np.einsum('jn,mnop', Q, C). Notice how, Q is represented by 'jn'
# and C by 'mnop'. We need to reduce the 'm' dimension, i.e. reduce 'axes=1'
# from Q and `axes=1` from C corresponding to `n' in each of the inputs.
# Thus, 'jn' + 'mnop' => 'jmop' after 'n' is reduced and order is maintained.
Q_C1 = np.tensordot(Q,C,axes=([1],[1]))
# Perform "np.einsum('im,jn,mnop', Q, Q, C). We need to use Q and Q_C1.
# Q is 'im' and Q_C1 is 'jmop'. Thus, again we need to reduce 'axes=1'
# from Q and `axes=1` from Q_C1 corresponding to `m' in each of the inputs.
# Thus, 'im' + 'jmop' => 'ijop' after 'm' is reduced and order is maintained.
parte1 = np.tensordot(Q,Q_C1,axes=([1],[1]))
# Use the same philosophy to get the rest of the einsum equivalent,
# but use parte1 and go right and use Q_inv
out = np.tensordot(np.tensordot(parte1,Q_inv,axes=([2],[0])),Q_inv,axes=([2],[0]))
The trick with np.tensordot is to keep track of the dimensions that are reduced by the axes parameter and how the collapsed dimensions align against the remaining inputs' dimensions.

Retrieve the collection of unionOf and intersectionOf for each OWL

I'm trying to extract intersectionOf and unionOf in an OWL file, where interesctionOf and unionOf consist of collection of classes, someValuesFrom or/and onProperty. I have created a SPARQL query which extracts the "collection" for the intersectionOf, but the problem is that some of the retrieved data are not related to the class.
For example, I have class called man. This class has an equivalent class which is intersectionOf of three classes, namely, adult,person, and male .My SPARQL query returns some incorrect result: it returns that the classes adult, person, and male are equivalent to class man (i.e., this part is correct), but they are also equivalent classes to all other classes in my OWL file such as haulage_worker, which is incorrect. Here is my SPARQL query:
PREFIX abc: <http://owl.cs.manchester.ac.uk/2009/07/sssw/people#>
PREFIX ghi: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX mno: <http://www.w3.org/2001/XMLSchema#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX list: <http://jena.hpl.hp.com/ARQ/list#>
SELECT Distinct ?class ?equivalentClass
WHERE{ ?class a owl:Class .
FILTER( STRSTARTS(STR(?class),"http://www.w3.org/2002/07/owl#") || STRSTARTS(STR(?class),"http://owl.cs.manchester.ac.uk/2009/07/sssw/people#")
)
?x a owl:Class ; owl:intersectionOf ?list .
?list rdf:rest*/rdf:first ?equivalentClass .
} GROUP BY ?class ?equivalentClass ORDER BY ?no
and this is my OWL file:
<?xml version="1.0"?>
<rdf:RDF
xmlns="http://owl.cs.manchester.ac.uk/2009/07/sssw/people#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xmlns:owl="http://www.w3.org/2002/07/owl#"
xmlns:ns0="http://owl.cs.manchester.ac.uk/2009/07/sssw/people#"
xml:base="http://owl.cs.manchester.ac.uk/2009/07/sssw/people">
<owl:Ontology rdf:about="http://owl.cs.manchester.ac.uk/2009/07/sssw/people"/>
<owl:Class rdf:about="http://www.w3.org/2002/07/owl#Thing"/>
<owl:Class rdf:about="http://owl.cs.manchester.ac.uk/2009/07/sssw/people#haulage_worker">
<rdfs:comment rdf:datatype="http://www.w3.org/2001/XMLSchema#string"
></rdfs:comment>
<owl:equivalentClass>
<owl:Restriction>
<owl:onProperty>
<owl:ObjectProperty rdf:about="http://owl.cs.manchester.ac.uk/2009/07/sssw/people#works_for"/>
</owl:onProperty>
<owl:someValuesFrom>
<owl:Class>
<owl:unionOf rdf:parseType="Collection">
<owl:Restriction>
<owl:onProperty>
<owl:ObjectProperty rdf:about="http://owl.cs.manchester.ac.uk/2009/07/sssw/people#part_of"/>
</owl:onProperty>
<owl:someValuesFrom>
<owl:Class rdf:about="http://owl.cs.manchester.ac.uk/2009/07/sssw/people#haulage_company"/>
</owl:someValuesFrom>
</owl:Restriction>
<owl:Class rdf:about="http://owl.cs.manchester.ac.uk/2009/07/sssw/people#haulage_company"/>
</owl:unionOf>
</owl:Class>
</owl:someValuesFrom>
</owl:Restriction>
</owl:equivalentClass>
<rdfs:label rdf:datatype="http://www.w3.org/2001/XMLSchema#string"
>haulage worker</rdfs:label>
</owl:Class>
<owl:Class rdf:about="http://owl.cs.manchester.ac.uk/2009/07/sssw/people#man">
<owl:equivalentClass>
<owl:Class>
<owl:intersectionOf rdf:parseType="Collection">
<owl:Class rdf:about="http://owl.cs.manchester.ac.uk/2009/07/sssw/people#adult"/>
<owl:Class rdf:about="http://owl.cs.manchester.ac.uk/2009/07/sssw/people#person"/>
<owl:Class rdf:about="http://owl.cs.manchester.ac.uk/2009/07/sssw/people#male"/>
</owl:intersectionOf>
</owl:Class>
</owl:equivalentClass>
</owl:Class>
</rdf:RDF>
This is the output which I got (they are not correct output):
-----------------------------------------
| class | equivalentClass |
=========================================
| abc:adult | abc:adult |
| abc:adult | abc:male |
| abc:adult | abc:person |
| abc:haulage_company | abc:adult |
| abc:haulage_company | abc:male |
| abc:haulage_company | abc:person |
| abc:haulage_worker | abc:adult |
| abc:haulage_worker | abc:male |
| abc:haulage_worker | abc:person |
| abc:male | abc:adult |
| abc:male | abc:male |
| abc:male | abc:person |
| abc:man | abc:adult |
| abc:man | abc:male |
| abc:man | abc:person |
| abc:person | abc:adult |
| abc:person | abc:male |
| abc:person | abc:person |
| owl:Thing | abc:adult |
| owl:Thing | abc:male |
| owl:Thing | abc:person |
-----------------------------------------
The expected output would be like this:
-----------------------------------------
| class | equivalentClass |
=========================================
| abc:adult | abc:adult |
| abc:adult | abc:male |
| abc:adult | abc:person |
| abc:haulage_company | |
| abc:haulage_company | |
| abc:haulage_company | |
| abc:haulage_worker | |
| abc:haulage_worker | |
| abc:haulage_worker | |
| abc:male | abc:adult |
| abc:male | abc:male |
| abc:male | abc:person |
| abc:man | abc:adult |
| abc:man | abc:male |
| abc:man | abc:person |
| abc:person | abc:adult |
| abc:person | abc:male |
| abc:person | abc:person |
| owl:Thing | |
| owl:Thing | |
| owl:Thing | |
-----------------------------------------
What should I change in my SPARQL query in order to make my output like the previous table?
Cleaning up your query a bit, we have:
prefix abc: <http://owl.cs.manchester.ac.uk/2009/07/sssw/people#>
prefix ghi: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
prefix mno: <http://www.w3.org/2001/XMLSchema#>
prefix owl: <http://www.w3.org/2002/07/owl#>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
prefix list: <http://jena.hpl.hp.com/ARQ/list#>
select distinct ?class ?equivalentClass where {
?class a owl:Class .
filter( strstarts(str(?class),str(owl:)) || # since "owl:" is an IRI, you can
strstarts(str(?class),str(abc:)) ) # use str(owl:) and str(:abc)
?x a owl:Class ;
owl:intersectionOf ?list .
?list rdf:rest*/rdf:first ?equivalentClass .
}
group by ?class ?equivalentClass
order by ?class # ?class, not ?no
Your problem lies in that you're selecting ?class, which can be every owl:Class in the ontology (as long as it starts with an appropriate prefix), and then selecting ?equivalentClass from the list of intersection classes of ?x, and ?x has no connection whatsoever to ?class. (You were also sorting by?no, but I think you meant to sort by?class`.)
Figuring out the right query to write will be easier if we take a look at the data in a more human readable format, e.g., Turtle. In Turtle, the man class is:
ns0:man a owl:Class ;
owl:equivalentClass [ a owl:Class ;
owl:intersectionOf ( ns0:adult ns0:person ns0:male )
] .
You're looking for things which are owl:Classes, are related by owl:equivalentClass to something else that's an owl:Class, and which has a list value for owl:intersectionOf. This isn't too hard in SPARQL, and the query actually has the same kind of structure as this Turtle text:
prefix abc: <http://owl.cs.manchester.ac.uk/2009/07/sssw/people#>
prefix ghi: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
prefix mno: <http://www.w3.org/2001/XMLSchema#>
prefix owl: <http://www.w3.org/2002/07/owl#>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
prefix list: <http://jena.hpl.hp.com/ARQ/list#>
select distinct ?class ?otherClass where {
?class a owl:Class ;
owl:equivalentClass [ a owl:Class ;
owl:intersectionOf [ rdf:rest*/rdf:first ?otherClass ] ] .
filter( strstarts(str(?class),str(owl:)) ||
strstarts(str(?class),str(abc:)) )
}
group by ?class ?otherClass
order by ?class
I changed the variable name from equivalentClass to otherClass, because adult, male, and person aren't equivalent to man. Their intersection is. Using Jena's command line sparql tool, you'll get results like this:
$ sparql --data data.rdf --query query.rq
------------------------
| class | otherClass |
========================
| abc:man | abc:adult |
| abc:man | abc:male |
| abc:man | abc:person |
------------------------
This query only retrieves classes that are equivalent to some intersection. Your expected results showed all the classes whose IRIs started with abc: or owl:, which means that the extra structure is actually optional, so we adjust the query accordingly by wrapping the optional parts in optional { … }, and we get the kind of results we're looking for:
prefix abc: <http://owl.cs.manchester.ac.uk/2009/07/sssw/people#>
prefix ghi: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
prefix mno: <http://www.w3.org/2001/XMLSchema#>
prefix owl: <http://www.w3.org/2002/07/owl#>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
prefix list: <http://jena.hpl.hp.com/ARQ/list#>
select distinct ?class ?otherClass where {
  ?class a owl:Class .
  optional { 
    ?class owl:equivalentClass [ a owl:Class ;
                                 owl:intersectionOf [ rdf:rest*/rdf:first ?otherClass ] ] .
  }
  filter( strstarts(str(?class),str(owl:)) ||
          strstarts(str(?class),str(abc:))    )
}
group by ?class ?otherClass
order by ?class
$ sparql --data data.rdf --query query.rq
------------------------------------
| class | otherClass |
====================================
| abc:adult | |
| abc:haulage_company | |
| abc:haulage_worker | |
| abc:male | |
| abc:man | abc:adult |
| abc:man | abc:male |
| abc:man | abc:person |
| abc:person | |
| owl:Thing | |
------------------------------------