SHACL validation: Ignore edge direction

Hello,

consider I have the following graph:

CREATE (n:A)-[:develops]->(m:B)

I'd like to enforce that A has at least one edge "develops" and that B has at least one edge "develops".
For A, this is easy enough:

@prefix neo4j: <neo4j://graph.schema#> .
@prefix sh: <http://www.w3.org/ns/shacl#> .

neo4j:AShape a sh:NodeShape ;
  sh:targetClass neo4j:A ;
  sh:property [
    sh:minCount 1 ;
    sh:path neo4j:develops;
    sh:class neo4j:B;
    sh:nodekind sh:IRI;
  ]
.

The graph is validated without error.
Now, for validating the constraint on B, I tried (in the same manner):

.
neo4j:BShape a sh:NodeShape ;
  sh:targetClass neo4j:B ;
  sh:property [
    sh:minCount 1 ;
    sh:path neo4j:develops;
    sh:class neo4j:A;
    sh:nodekind sh:IRI;
  ]
.

But that fails when validating:

╒═══════════╤══════════╤════════════════════════════╤════════════════════════════════════════════════════════╤════════════════╤════════════╤══════════════════════════════════════╤══════════════════════════════╕
│"focusNode"│"nodeType"│"shapeId"                   │"propertyShape"                                         │"offendingValue"│"resultPath"│"severity"                            │"resultMessage"               │
╞═══════════╪══════════╪════════════════════════════╪════════════════════════════════════════════════════════╪════════════════╪════════════╪══════════════════════════════════════╪══════════════════════════════╡
│109        │"B"       │"bnode://id/node1fj1fn0bkx1"│"http://www.w3.org/ns/shacl#MinCountConstraintComponent"│null            │"develops"  │"http://www.w3.org/ns/shacl#Violation"│"unnacceptable cardinality: 0"│
└───────────┴──────────┴────────────────────────────┴────────────────────────────────────────────────────────┴────────────────┴────────────┴──────────────────────────────────────┴──────────────────────────────┘

It looks to me as if the first node in a relationship owns the edge. That would be bad for my use case, where I cannot really reverse the direction of the edge. I also tried

call n10s.validation.shacl.import.inline('
@prefix neo4j: <neo4j://graph.schema#> .
@prefix sh: <http://www.w3.org/ns/shacl#> .

neo4j:BShape a sh:NodeShape ;
  sh:targetClass neo4j:B ;
  sh:property [
    sh:minCount 1 ;
    sh:path [sh:inversePath neo4j:develops];
    sh:class neo4j:A;
    sh:nodekind sh:IRI;
  ]
.
', "Turtle")

but that would give me the following error:

Failed to invoke procedure `n10s.validation.shacl.validate`: Caused by: java.lang.ClassCastException: class org.neo4j.cypher.internal.expressions.HasDegreeLessThan cannot be cast to class org.neo4j.cypher.internal.expressions.InequalityExpression (org.neo4j.cypher.internal.expressions.HasDegreeLessThan and org.neo4j.cypher.internal.expressions.InequalityExpression are in unnamed module of loader 'app')

So, I guess my question is: How can I ensure that a node has at least one incoming edge of a certain type?

I politely want to push this issue, as I am totally clueless here.

May be the cast is not fixed and its dynamic so difficult for program to gauge.So the program is assuming a wrong caste when in reality it is of other caste.That is what is causing chaos in
the local program.

Thanking you
Sameer SG

Hi @max_beikirch at the moment the SHACL validator does not support sh:inversePath, which means that you can unfortunately only define constraints on outgoing relationships.

I agree that the error message is not particularly useful :crazy_face:

We are planning to extend the coverage of the SHACL primitives so hopefully the wait will not be very long. Watch out for the new releases of neosemantics for updates on this.

Thanks!

JB.

Those are great news :) I guess I'll hack something together in python for now and replace that with a proper sh:inversePath-solution when it's there. Thanks for your work!! Do you already have an estimate on when an implementation might be there?