owned this note
owned this note
Published
Linked with GitHub
---
tags: ShEx, EXTENDS
---
# EXTENDS
## [EXTENDS Issue Example](https://tinyurl.com/yxlmx3et)
``` xml
<IssueShape> CLOSED {
ex:reproducedBy @<EmployeeShape>?
}
ABSTRACT <PersonShape> IRI CLOSED {
foaf:name xsd:string ;
foaf:mbox IRI
}
<UserShape> /^https?:\/\//
AND
EXTENDS @<PersonShape> CLOSED {
ex:representative @<EmployeeShape>
}
ABSTRACT <RepShape> CLOSED {
foaf:phone IRI+
}
<EmployeeShape>
EXTENDS @<PersonShape> EXTENDS @<RepShape> CLOSED {
}
```
## [RESTRICTS Issue Example](https://tinyurl.com/y2lvc8fw)
``` xml
<IssueShape> {
ex:reproducedBy @<EmployeeShape>?
}
ABSTRACT <PersonShape> IRI {
foaf:name xsd:string ;
foaf:mbox IRI
}
<UserShape> /^https?:\/\// AND @<PersonShape> AND {
ex:representative @<EmployeeShape> # not captured
}
<RepShape> {
foaf:phone IRI+
}
<EmployeeShape> @<PersonShape> AND @<RepShape>
```
- only works with open shapes
- "ABSTRACT" is meaningless - no way to say "must conform to some derived shape expr"
- would require compilation from some expression of EXTENDS
## [INCLUDES Issue Example](https://tinyurl.com/y2ewpylq)
``` xml
<IssueShape> {
$<IssueShapeTE> ex:reproducedBy @<EmployeeShape>?
}
<PersonShape> IRI {
$<PersonShapeTE> ( foaf:name xsd:string ;
foaf:mbox IRI )
}
<UserShape> /^https?:\/\// AND {
&<PersonShapeTE> ;
ex:representative @<EmployeeShape>
}
<RepShape> {
$<RepShapeTE> foaf:phone IRI+
}
<EmployeeShape> {
&<PersonShapeTE> ;
&<RepShapeTE>
}
```
- open shapes
- no derived shapes (again requires compilation)
## EXTENDS Semantics
+ inclusion of ShapeExpression `A (EXTENDS B)+ { C }`
+ B': list[ShapeExpression], C: TripleExpression
+ TEs: list[TripleConstraints] from C
+ Ps: map[shapeLabel -> list[TripleConstraints]]
+ substitution FOCUS@B
+ candidates = closure of A over `A EXTENDS B`
+ "ABSTRACT" eliminates substitution candidates
+ for B EXTENDS A (with some closed semantics):
+ b does not satify A as b has more information
+ some partition of b satisfies A ([substitutibility](https://en.wikipedia.org/wiki/Liskov_substitution_principle))
## Class Substitution
``` java
class UKAddress extends Address {
...
}
```
- a serialized `UKAddress` can't be de-serialized as an `Address`
- round-tripping through XML would have the same issue.
## XML Schena Analog
``` XML
<xs:complexType name="AddressType">
<xs:sequence>
<xs:element name="Line1" type="xs:string" />
<xs:element name="Line2" type="xs:string" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="UKAddressType">
<xs:complexContent>
<xs:extension base="AddressType">
<xs:sequence>
<xs:element name="County" type="xs:string" />
<xs:element name="Postcode" type="xs:string" />
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="USAddressType">
<xs:complexContent>
<xs:extension base="AddressType">
<xs:sequence>
<xs:element name="State" type="xs:string" />
<xs:element name="Zipcode" type="xs:string" />
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
```
## Proposal
- shape deriviation
- substitution
- add API parameters to control substitution
- FOCUS shape substitution
- referenced shape substitution
## Resources
- Wikidata file formats: [software emulator](https://www.wikidata.org/wiki/EntitySchema:E91) extended by [FOSS software emulator](https://www.wikidata.org/wiki/EntitySchema:E93)
- [FHIR example](https://rawgit.com/shexSpec/primer/extends/vitals.html)
- [Primer draft](https://rawgit.com/shexSpec/primer/extends/#extension)
https://tinyurl.com/y4gs6uen
## Decisions of July 18 meeting
### AND and & to be preferred on EXTENDS
We encourage the use of AND and include (&) which semantics is definable in ShEx 2.0. EXTENDS can lead to unexpected behaviour and should be used only when AND and & do not allow to model what we want.
### Implicit triple expression names with &
The difficulty with using & (include) is that we can only include a TripleExpr that has been named.
In order to allow for more frequent usage of &, we assume a default name for some TripleExpr. Namely: if a ShapeExpr has a unique non negated Shape (no AND,OR,NOT), then & can be used with the name of that ShapeExpr and refers to the top-level TripleExpr of its Shape. Example:
```
<S> { :p IRI; :q Literal }
<U> &<S> # here &<S> refers to the TripleExpr { :p IRI ; :q Literal }
```
### Semantics of EXTENDS
We decided to give the following semantics of EXTENDS:
- A syntactic restriction applies: a ShapeExpr A cannot be extended if it uses negation (NOT)
- If *B* extends *A*, then a node *n* satisfies *B* if the neighbourhood of *n* can be split into 2 disjoint sets, *S1* and *S2*. The first one, *S1*, must satisfy the definition of *A* except that unmatchables and matchables in *S1* should be empty (for the meaning of matchables and unmatchables see ShEx spec section 5.2). The second one *S2*, must satisfy the definition of *B*. This intuitively means that we combine the defintions of *A* and *B* while ignoring all EXTRA modifiers and considering all shapes as CLOSED in *A*. An illustration
```
<A> EXTRA :p { :p xsd:int }
<B> EXTENDS <A> {:p xsd:string}
# <n1> satisfies <B> with S1 containing the triple (<n1> :p 1) and S2 the remaining triples
<n1> :p 1 ;
:p "abc" ;
:q "x" .
# <n2> does not satisfy <B>.
# In particular, the partitioning in which S1 contains the triples (<n2> :p 1) and (<n2> :p <http://some.iri>) and S2 contains the remaining triple is not good even though <n2> restricted to its <S1> neighbours satisfies <A> because the triple (<n2> :p <http://some.iri>) is in matchables
<n2> :p 1 ;
:p <http://some.iri/> ;
:p "abc" .
```
### Semantics of RESTRICTS
We didn't have time ot clear it.
# Notes of July 18 meeting
closed is false or unmatchables is empty.
http://shex.io/shex-semantics/index.html#triple-expressions-semantics
```
PREFIX : <asdf#>
<S1> ({
:p .
} AND {
:q .
}) OR {
:r .
} OR NOT (CLOSED {
:r .
})
<T> CLOSED EXTRA :r {}
<t1> :r 1. # Fails according to Eric, passes according to Harold and Jérémie
<F> @<S1> AND @<S2>
<S> @<F>
<F2> {&<F>}
# S3 matches exactly one :p or at least one predicate
<S3> EXTRA :r {:p .}
<S2> EXTENDS @<S3> CLOSED {
:r xsd:int
}
<n1> :r 1 ;
:r "a" ;
:p 2 .
<n2> :r 1 ;
:q 3 ;
:p 2 .
```
```
<X> {
:r . {0} ;
:r .
}
```
```
<S5> {
:p @<S6>
}
<S7> EXTENDS <S5> {
:p @<S8>
}
<S6> {
:q Literal
}
<S8> {
:q xsd:int
}
<n1> :p [:q 1] .
<n1> :p [:q 2] .
```
https://rawgit.com/shexSpec/shex.js/extends/packages/shex-webapp/doc/shex-simple.html?schema=PREFIX%20%3A%20%3Casdf%23%3E%0A%0A%3CS1%3E%20%7B%0A%20%20%3Ap%20%5B1%5D%0A%7D%0A%0A%3CS2%3E%20EXTENDS%20%40%3CS1%3E%20CLOSED%20%7B%0A%20%20%3Ar%20.%0A%7D%0A&data=PREFIX%20%3A%20%3Casdf%23%3E%0A%0A%3An1%20%3Ap%2011%20%3B%20%3Ar%203%20.%0A&manifestURL=..%2Fexamples%2Fmanifest.json&shape-map=%3Casdf%23n1%3E%40%3CS2%3E&interface=appinfo®expEngine=threaded-val-nerr
```
<#Observation> {
fhir:code .? ;
fhir:component {
fhir:code . ;
fhir:value .
}*
}
# -- super-classes --
ABSTRACT <#Vital>
EXTENDS @<#Observation> {fhir:code .}
```
```
<#Observation> {
fhir:code . ;
fhir:component {
fhir:code . ;
fhir:value .
}*
}
<S1> {:p .}
<S2> EXTENDS @<S1> { }
<n1> :p 1 ;
# :p 2 ;
:p 3 .
# "Inheritence tree"
<s3> @<s4> or @<s5> ... OR {(s3 definition)}
<s3> {:p xsd:int} OR {:p xsd:string}
<s4> RESTRICTS @<s3> {:p xsd:positiveint}
# <s3> is equivalent to <s31>
<s31> {:p xsd:int OR xsd:string}
# but <s41> is not equivalent to <s4>
<s41> RESTRICTS @<s31> {:p xsd:positiveint}
<s411> {:p (xsd:int OR xsd:string) AND xsd:positiveint}
# does not match <s4> because it doesn't match <s3>
<n1> :p "a" ;
:p 1 .
<n11> :p -1 ;
:q "a" .
# matches <s4>
<n2> :p 2 .
# <s33> must consist of exactly one :p int or exactly one :p string and any other non-p
<s33> {:p xsd:int} OR {:p xsd:string}
<s91> CLOSED EXTRA :p @<s33>
# <s34> exactly anything that matches <s33>
<s34> EXTENDS @<s33> {:p . {0}}
# <s36> matches exactly one :p that is int or string and any other predicate, including another :p
<s36> EXTENDS @<s33> {}
# <s35> matches exactly one p IRI, exactly one r IRI and either one p: int or one :p string and any other non-p (non-r?)
<s35> EXTENDS @<s33> {:p IRI; :r .}
<s44> EXTENDS @<s33> CLOSED {:p xsd:positiveint}
<n1> :p 0; :p 1 ; :r 3 ;
# -- super-classes --
ABSTRACT <#Vital>
EXTENDS @<#Observation> {fhir:code xsd:int}
ABSTRACT <#Vital>
EXTENDS @<#Observation> {} AND {fhir:code xsd:positiveint; fhir:foo .}
RESTRICTS @<#Observation> {fhir:code xsd:positiveint; fhir:foo .}
EXTENDS (@<bla>) { fhir:foo .}
<bla> RESTRICTS @<#Observation> {fhir:code xsd:positiveint;}
```
```
<#Observation> {
}
# -- super-classes --
ABSTRACT <#Vital> {
fhir:code . ;
fhir:code . ;
fhir:component {
fhir:code . ;
fhir:value .
}*
}
```
# Further notes
Example of undesired behaviour of EXTENDS
```
<A> EXTRA :p {
:p [1]
} AND EXTRA :p {
:p [2]
}
<B> EXTENDS <A> {
:p [3]
}
# <n> does not satisfy <B> because its neighbourhood restricted to (<n> :p 1) and (<n> :p 2) does not satisfy <A> when the EXTRA are ignored
<n> :p 1 , 2 , 3.
```
```
# <A2> is equivalent to <A>
<A2> EXTRA :p {
:p [1] ;
:p [2]
}
# but <B2> is not equivalent to <B>
<B2> EXTENDS <A2> {
:p [3]
}
# I would argue that only the shapeDefinition construct is subject to the
# rules involving EXTRA and CLOSED. Anything else (NOT, AND, OR) should be
# viewed as "sealed". I realize, however, this this is a pretty subtle
# complexity -- I always look at things like this from the perspective of
# trying to teach someone about them -- so I wonder whether there wouldn't be
# some way of accomplishing what we need *without* undoing EXTRA or CLOSED?
```
# HERE
Shape :- list of ShapeRef | BasicShape
``` java
public class Shape extends ShapeExpr implements AnnotedObject {
private boolean closed;
private Set<TCProperty> extra;
private TripleExpr tripleExpr;
private List<Annotation> annotations;
private List<ShapeExpr> _extends;
```
https://rawgit.com/shexSpec/shex.js/extends/packages/shex-webapp/doc/shex-simple.html?manifestURL=../examples/inheritance/manifest.json
https://github.com/janeirodigital/shex-java/blob/dev-extends-ericprud/shex/src/main/java/fr/inria/lille/shexjava/schema/parsing/ShExCParser.java#L353
https://github.com/janeirodigital/shex-java/blob/dev-extends-ericprud/shex/src/main/antlr4/fr/inria/lille/shexjava/schema/parsing/ShExC/ShExDoc.g4#L56
https://github.com/shexSpec/shexTest/compare/extends
src/main/java/fr/inria/lille/shexjava/schema/parsing/
ShExDoc.g4
ShExCParser.java