@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>.
@prefix owl: <http://www.w3.org/2002/07/owl#>.
@prefix list: <http://www.w3.org/2000/10/swap/list#>.
@prefix log: <http://www.w3.org/2000/10/swap/log#>.
@prefix : <http://example.org/#>.

:HasCardinalityCheck owl:onProperty :name.
:HasCardinalityCheck owl:cardinality 3.

:P1 :name "Patrick".
:P1 :name "Christian".
:P1 :name "Herman".

:P2 :name "Stefanie".
:P2 :name "Elizabeth".

# declare components
:cardinalCount a log:Component.

# Check for a cardinality
(_:a _:b _:c _:x _:y _:Counter _:o) log:onNegativeSurface [ log:graph (
    [ log:triple (_:a owl:onProperty _:b)]
    [ log:triple (_:a owl:cardinality _:c)]

    [ log:triple (_:x _:b _:y)]

    # Search for a cardinality Counter
    # ...actually this means for any log:GraphCounter you
    # can find this must be true.
    [ log:triple (_:Counter rdf:type log:GraphCounter)]

    [ log:triple ([ log:graph (
        [ log:triple (_:x _:b _:o)]
    )] _:Counter _:c)]

    [ log:triple (() log:onNegativeSurface [ log:graph (
       [ log:triple (_:x rdf:type _:a)]
    )])]
)].

# This is a local implementation of a log:GraphCounter
:cardinalCount a log:GraphCounter.
(_:Graph _:Count _:List _:Scope) log:onNegativeSurface [ log:graph (
    [ log:triple (() log:onNegativeSurface [ log:graph (
        [ log:triple (_:Graph :cardinalCount _:Count)]
    )])]
    [ log:triple ((() _:Graph _:List) log:collectAllIn _:Scope)]
    [ log:triple (_:List list:length _:Count)]
)].

# Test
(_:P) log:onNegativeSurface [ log:graph (
    [ log:triple (_:P rdf:type :HasCardinalityCheck)]
    [ log:triple (() log:onNegativeAnswerSurface [ log:graph (
        [ log:triple (_:P rdf:type :HasCardinalityCheck)]
    )])]
)].
