changed 5 years ago
Linked with GitHub

Discriminators

Example:

<#Thing> { }

<#CreativeWork> EXTENDS @<#Thing> DISCRIMINATOR {
    a [schema:CreativeWork] ;
} {
    schema:aggregateRating @<#AggregateRating> *;
    schema:author (@<#Person> OR @<#Organization>) *;
    schema:datePublished (@<#Date> OR @<#DateTime>) *;
    schema:publisher (@<#Person> OR @<#Organization>) *;
}

<#Foo> EXTENDS @<#Thing> DISCRIMINATOR {
    a [schema:Foo] ;
} {
   ...
*;
}

If you want to validate a node n with shape <#Thing>, it shows error messages only when a node conforms to the discriminator (a schema:CrativeWork).

<#CreativeWork_OR_Foo>
DISCRIMINATOR {
    a [schema:CreativeWork] ;
} CLOSED {
    schema:aggregateRating @<#AggregateRating> *;
    schema:author (@<#Person> OR @<#Organization>) *;
    schema:datePublished (@<#Date> OR @<#DateTime>) *;
    schema:publisher (@<#Person> OR @<#Organization>) *;
}
OR
DISCRIMINATOR {
    a [schema:Foo] ;
} {
   ...
*;
}

<n1>@<#CreativeWork_OR_Foo>

Syntax:

ShapeExpr ::= ... 
   NodeConstraint
   NOT ShapeExpr
   ShapeExpr AND ShapeExpr
   ShapeExpr OR ShapeExpr
   Closed? EXTRA p1...pN (DISCRIMINATOR {TriplExpr})? { TripleExpr }
   EXTENDS ShapeExpr Shape
   
TripleExpr ::= pred ShapeExpr
   TripleExpr ; TripleExpr
   TripleExpr | TripleExpr
   
ShapeExpr ::= ... 
   NodeConstraint
   NOT ShapeExpr
   ShapeExpr AND ShapeExpr
   ShapeExpr OR ShapeExpr
   Shape 
   EXTENDS ShapeExpr Shape
   
Shape ::= 
   EXTENDS Closed Extra p1...pN ShapeExpr | Triple Expr
   
TripleExpr ::= pred ShapeExpr
   TripleExpr ; TripleExpr
   TripleExpr | TripleExpr
   
   
public class  Shape extends ShapeExpr implements AnnotedObject {
	private boolean closed;
	private Set<TCProperty> extra;
	private TripleExpr tripleExpr;
	private List<Annotation> annotations;
	private List<ShapeExprRef> extended;
   

Basic semantics: Discriminator te1 te2 could be compiled to te1 ; te2

Alternative syntax:

...Closed? EXTRA p1...pN (DISCRIMINATOR ShapeExpr)? { TripleExpr }

Examples

<S1> DISC { :p1 [1 2] } { :p1 [2 3] }
<n1> :p1 1 . # satisfied disc, failed
<n2> :p1 2 . # "
<n3> :p1 3 . # fails disc
<n4> :p1 1, 2 # passed
<n5> :p1 2, 3 # passes
<S1> DISC { :p1 [1 2] ; :p1 [2 3]? } { :p1 [2 3] }
<n4> :p1 1, 2 . # passes
<n5> :p1 1, 4 . # fails
<S1> DISC { :p1 [1 2] ; :p1 [2 3]? } { :p1 [2 3]; :q [ 1 ] }
<n4> :p1 1, 2; :q 1 . # passes
<n5> :p1 1, 2 . # disc. fails or all error messages?
<n5> :p1 1, 3 . # disc. fails or evaluate all?

Algorithm (notes)

When testing N@S, recurse through S's
For any Shape, if there's a discriminator and it fails, fail with a DiscriminatorFailure

<S> (@<S1> OR @<S2>) AND @<S3>
<S1> DISCRIMINATOR { :p0 [0] } { :p1 [1] }
<S2> { :p2 [2] }
<S3> DISCRIMINATOR { :p3 [3] } { :p4 . }
<F1> @<F2>

start of DNF

@@ something like this?:

<S> DISCRIMINATOR { :p0 [0]; :p3 [3] } { :p1 [1] } AND { :p4 . }

Errors vs warnings

Select a repo