RDF Surfaces Primer

Living Document,

Issue Tracking:
Inline In Spec
Editors:
(KNoWS)
(KNoWS)

Abstract

This document specifies a Notation3 sublanguage to express RDF Surfaces: RDF with first-order logic semantics.

1. Introduction

Logo

This document presents a Notation3 sublanguage to express a revised RDF logic as envisioned by Pat Hayes in his 2009 ISWC Invited Talk: BLOGIC. RDF Surfaces logic can be thought as an implementation of Charles Sanders Peirce's Existential Graphs in RDF.

An RDF surface is a kind of sheet of paper on which RDF graphs can be written. All triples that are part of an RDF graph are then on this sheet of paper, including all [URI]s, literals, and Blank nodes. A sheet of paper can contain more than one RDF graph. An RDF graph can’t be split over multiple sheets of paper. However, one can copy an RDF graph from one sheet of paper to another sheet of paper.

Blank nodes are special. They can’t be copied to a new piece of paper. They can be thought of as scratches on a piece of paper. These scratches, or graffiti, are engraved into the piece of paper and can’t be transferred. When copying data with blank nodes onto a new sheet of paper, new scratches need to be made.

An empty positive surface is a tautology.

blank surface

A positive surface with one triple :Gent a :City, which means "Ghent is a city".

blank surface

A positive surface with one triple containing a blank node [] a :City, which means "There is something that is a city".

blank surface

Two positive surfaces, one with the triple [] a :City (which means "There is something that is a city"), and another one with the triple [] a :Cat (which means "There is something that is a cat").

blank surface

One can copy these two RDF graphs to a new surface. This will contain two graphs with two blank nodes:

@prefix : <http://example.org/ns#> .

[] a :City .
[] a :Cat .

This means, "There is something that is a city AND There is something that is a cat."

blank surface

Positive surface

The default surface on which RDF graphs are written is a positive surface. For instance, the sheet of paper in Example 1 is an example of a positive surface. (In this document, we use a paper with a black border as a positive surface.) Any RDF triple written on this surface is interpreted as logical assertion (true). An empty sheet of positive paper is an empty claim and is treated as a logical tautology (true).

When there is more than one RDF triple on the surface, it is a logical conjunction (AND). If we interpret the sheets of paper with black borders in the examples above as positive surfaces, then they express:

The blank nodes need to be interpreted as existential quantified variables on logical paper.

Negative surface

In the same way that a positive surface asserts a logical truth, a negative surface asserts a logical negation. The examples below will use a sheet of paper with a red border as a negative surface.

An empty negative surface on the default positive surface expresses a logical contradiction. When one or more RDF graphs are written on a negative surface, they mean the negation of those RDF graphs.

A blank node on a negative surface is interpreted as a universal quantified variable. The reason is as follows:

NOT(∃ x : P(x)) ⇔ ∀ x : NOT(P(x))
An empty negative surface (on a default positive surface) is a contradiction.

blank surface

A negative surface with one triple :Ghent a :Cat means "It is not the case that Ghent is a cat".

blank surface

A negative surface with one triple [] a :City means "It is not the case that something is a city" , or "Nothing is a city".

blank surface

Propositional logic

With combinations of conjunction, by putting triples on a positive surface, and negation, by putting triples on a negative surface, any compound truth-functional statement can be symbolized with positive and negative sheets of paper:

Propositional logic using positive and negative surfaces.

blank surface

First-order logic

First-order logic can be added to the RDF surfaces by interpreting a blank node as an existential quantified variable, and using the rule that a universal quantified variable can be made from an existential quantified variable by placing it in an enclosing negative surface:

First-order logic using positive and negative surfaces.

blank surface

First-order logic in Notation3

RDF Surfaces provide a way to express the notion of positive and negative surfaces in Notation3 with help of the built-in log:onNegativeSurface. A log:onNegativeSurface is true when at least one of the nested triples in the object is false. A negative surface can be constructed from a single log:onNegativeSurface built-in. A positive surface can be constructed from double-nested log:onNegativeSurface built-ins.

The subjects of both built-ins are the blank nodes that need to be put on the surfaces (so that they become existential or universal quantified variables, depending on the nesting level of the surface).

"Something is a city" in Notation3.
@prefix : <http://example.org/ns#> .
@prefix log: <http://www.w3.org/2000/10/swap/log#> .

() log:onNegativeSurface {
  (_:X) log:onNegativeSurface {
    _:X a :City .
  }
} .
"Something is a city" in Notation3, version 2: because the default surface is defined as a positive surface.
@prefix : <http://example.org/ns#> .
@prefix log: <http://www.w3.org/2000/10/swap/log#> .

_:X a :City .
"Everything is a city" in Notation3. Note that we can make universal or existential quantified variables by placing blank nodes on an oddly- or evenly-nested surface.
@prefix : <http://example.org/ns#> .
@prefix log: <http://www.w3.org/2000/10/swap/log#> .

( _:X ) log:onNegativeSurface {
  () log:onNegativeSurface {
    _:X a :City .
  }
} .
"Nothing is a problem" in Notation3.
@prefix : <http://example.org/ns#> .
@prefix log: <http://www.w3.org/2000/10/swap/log#> .

( _:X ) log:onNegativeSurface {
    _:X a :Problem .
} .
"All cats are alive OR dead" in Notation3. These are Schrödinger cats: logical OR can mean alive, or dead, or both alive and dead.
@prefix : <http://example.org/ns#> .
@prefix log: <http://www.w3.org/2000/10/swap/log#> .

( _:X ) log:onNegativeSurface {
    _:X a :Cat .

    () log:onNegativeSurface {
        _:X :is :Alive .
    } .

    () log:onNegativeSurface {
        _:X :is :Dead .
    } .
} .
"If any cat X is alive, then X says meow" in Notation3.
@prefix : <http://example.org/ns#> .
@prefix log: <http://www.w3.org/2000/10/swap/log#> .

( _:X ) log:onNegativeSurface {
    _:X a :Cat ;
        :is :Alive .
    () log:onNegativeSurface {
        _:X :says :Meow .
    } .
} .

A surface can be queried by providing a query surface with the log:onNegativeAnswerSurface built-in. The results of this query will be the final results of the reasoning engine interpreting the surfaces.

:Ghent a :City is a triple on the implicit positive surface. The two nested negative surfaces express that for any subject _:S on the positive surface that is a :City, it is implied that _:S if also a :HumanCommunity.

@prefix ex: <http://example.org/ns#> .
@prefix log: <http://www.w3.org/2000/10/swap/log#> .

ex:Ghent a ex:City.

# Every city is a human community
( _:S ) log:onNegativeSurface {
    _:S a ex:City .
    () log:onNegativeSurface {
        _:S a ex:HumanCommunity .
    }.
}.

# Query
( _:S _:C ) log:onNegativeSurface {
    _:S a _:C .
    () log:onNegativeAnswerSurface {
      _:S a _:C .
    } .
} .

When this surface is executed by a reasoner, the result would be:

@prefix ex: <http://example.org/ns#> .

ex:Ghent a ex:City .
ex:Ghent a ex:HumanCommunity .

More test cases can be found at https://github.com/eyereasoner/rdfsurfaces-tests.

2. Document Conventions

Within this document, the following namespace prefix bindings to [URI]s are used:

Prefix Namespace
ex http://example.org/ns#
rdf http://www.w3.org/1999/02/22-rdf-syntax-ns#
log http://www.w3.org/2000/10/swap/log#
list http://www.w3.org/2000/10/swap/list#
string http://www.w3.org/2000/10/swap/string#

3. Surface

Surfaces are written as triples where the subject is a list of zero or more blank nodes. The object is a graph term or a boolean literal. The blank nodes in the subject list are treated as marks on the object RDF graph. The predicate specifies the kind of surface. Any kind of surface may be used, but the following built-ins have special semantics:

built-in semantics
log:onNegativeSurface Negative surface claim that any RDF graph in the object position is false.

A surface can contain zero or more other surfaces. These contained surfaces are "nested". Nested surfaces can share the same [URIs] and literals (by copying the data), but can’t share blank nodes. Any blank nodes that are written inside a surface (not as subject of an RDF Surface) are to be interpreted as coreferences to the blank node graffiti defined on a parent RDF Surface. If no such parent RDF Surface exists, then it is assumed that the blank node is a coreference to an implicitly declared blank node graffiti on the default positive surface.

An ex:myFirstSurface is created which contains two triples and a nested surface. The blank node in _:X a ex:OtherStatement is a co-reference to the _:X graffiti on ex:myFirstSurface.

In the nested surface ex:mySecondSurface, the blank node in _:X ex:is true is also a reference to the _:X blank node graffiti on ex:myFirstSurface.

The blank node _:Y co-reference in ex:mySecondSurface doesn’t refer to a parent blank node graffiti. It is assumed that the default positive surface contains that graffiti.

In the nested surface ex:myThirdSurface, the blank node in _:X ex:is false is a co-reference to the _:X blank node graffiti on ex:myThirdSurface. The new graffiti shields the _:X that was defined on ex:myFirstSurface: the scope of _:X co-references is now limited to ex:myThirdSurface.

@prefix ex: <http://example.org/ns#> .

( _:X ) ex:myFirstSurface {

    ex:Statement1 a ex:NiceStatement .
    _:X a ex:OtherStatement .
     
    () ex:mySecondSurface {
        _:X ex:is true . 
        _:Y a ex:AnotherStatement .

        ( _:X ) ex:myThirdSurface {
            _:X ex:is false .
        } .
    }.
} .

3.1. Default Positive Surface

The default positive surface claims that any RDF Graph that is placed on it is true. This is the current interpretation of RDF Semantics. When no surfaces are provided in an RDF document, the implicit default positive surface is assumed.

The two surfaces below are equal (because a double negation of a statement is the same as claiming the statement is true, i.e., positive):
@prefix : <http://example.org/ns#> .
@prefix log: <http://www.w3.org/2000/10/swap/log#> .

:Alice a :Person .

and

@prefix : <http://example.org/ns#> .
@prefix log: <http://www.w3.org/2000/10/swap/log#> .

() log:onNegativeSurface {
  () log:onNegativeSurface {
    :Alice a :Person .
  } .
}

The semantics of the default positive surface are interpreted as a logical truth:

The surface below should be interpreted as: "Alice is a person and knows Bob, and Bob is a person and knows Alice".

As a logical statement:

:Alice a :Person AND 
:Alice :knows :Bob AND (
  :Bob a :Person AND 
  :Bob :knows :Alice
)

As RDF Surface:

@prefix : <http://example.org/ns#> .
@prefix log: <http://www.w3.org/2000/10/swap/log#> .

:Alice a :Person .
:Alice :knows :Bob .

() log:onNegativeSurface {
  () log:onNegativeSurface {
    :Bob a :Person .
    :Bob :knows :Alice .
  } .
} .

When a blank node is marked on an evenly-nested negative surface, it is interpreted as an existential quantified variable in the scope of the nested surface.

The surface below should be interpreted as: "There is a person that knows Alice".

As a logical statement:

∃ _:X : _:X a :Person AND _:X :knows :Alice

Or, rewritten using NOT:

NOT ( NOT ( ∃ _:X : _:X a :Person AND _:X :knows :Alice ) )

We make use of the logical rule that a negation of a negation cancels, and creates a positive statement.

As RDF Surface:

@prefix : <http://example.org/ns#> .
@prefix log: <http://www.w3.org/2000/10/swap/log#> .

() log:onNegativeSurface {
  ( _:X ) log:onNegativeSurface {
    _:X a :Person .
    _:X :knows :Alice .
  } .
} .

In RDF Surfaces, a default positive surface is implicitly assumed for each RDF document. On this default positive surface, all existential variables are implicitly quantified. Example 20 can be rewritten as:

A default positive surface with an implicit _:X existential variable.
@prefix : <http://example.org/ns#> .
@prefix log: <http://www.w3.org/2000/10/swap/log#> .

_:X a :Person .
_:X :knows :Alice .

When a blank node is marked on an oddly-nested negative surface, it is interpreted as a universal quantified variable in the scope of the nested surface.

The surface below should be interpreted as: "Everything is a person and knows Alice".

As a logical statement:

∀ _:X : _:X a :Person AND _:X :knows :Alice

Or, rewritten using NOT:

NOT( ∃ _:X : NOT ( _:X a :Person AND _:X :knows :Alice ) )

We make here use of the logical rule that NOT ( ∃ _:X ... ) is equal to ∀ _:X NOT ( ... ).

As RDF Surface:

@prefix : <http://example.org/ns#> .
@prefix log: <http://www.w3.org/2000/10/swap/log#> .

(_:X) log:onNegativeSurface {
  () log:onNegativeSurface {
    _:X a :Person .
    _:X :knows :Alice .
  } .
} .

3.2. Negative Surface

A negative surface claims that any RDF Graph that is placed on it is false. The interpretation of the negative surface is the negation of the RDF Graph that is placed on it.

The semantics of a negative surface are interpreted as a logical falsehood:

The surface below should be interpreted as: "Alice is a person and knows Bob, and Bob is not a person and does not know Alice".

As a logical statement:

:Alice a :Person AND 
:Alice :knows :Bob AND NOT (
  :Bob a :Person AND 
  :Bob :knows :Alice
)

As RDF Surface:

@prefix : <http://example.org/ns#> .
@prefix log: <http://www.w3.org/2000/10/swap/log#> .

:Alice a :Person .
:Alice :knows :Bob .

() log:onNegativeSurface {
    :Bob a :Person .
    :Bob :knows :Alice .
} .

When a blank node is marked on a negative surface, it should be interpreted as an existential quantified variable in the scope of the negative surface.

The surface below should be interpreted as "Alice is a Person and knows Bob, and there isn’t a person that knows Alice".

As a logical statement:

:Alice a :Person AND 
:Alice :knows :Bob AND NOT (
  ∃ _:X :
     _:X a :Person AND 
     _:X :knows :Alice
)

which is the same as:

:Alice a :Person AND 
:Alice :knows :Bob AND 
  ( ∀ _:X :
     NOT (
      _:X a :Person AND 
      _:X :knows :Alice
    )
  ) 
)

As RDF Surface:

@prefix : <http://example.org/ns#> .
@prefix log: <http://www.w3.org/2000/10/swap/log#> .

:Alice a :Person .
:Alice :knows :Bob .

( _:X ) log:onNegativeSurface {
    _:X a :Person .
    _:X :knows :Alice .
} .

When two or more negative surfaces are nested in a parent negative surface, it should be interpreted as a logical disjunction.

The surface below should be interpreted as "Alice is a Person OR Bob is a Person OR Charly is a person".

As a logical statement:

:Alice a :Person OR
:Bob a :Person OR
:Charly a :Person 

which is the same as:

NOT (
  NOT ( :Alice a :Person ) AND
  NOT ( :Bob a :Person ) AND
  NOT ( :Charly a :Person )
)

As RDF Surface:

@prefix : <http://example.org/ns#> .
@prefix log: <http://www.w3.org/2000/10/swap/log#> .

:Alice a :Person .
:Alice :knows :Bob .

() log:onNegativeSurface {
    () log:onNegativeSurface {
      :Alice a :Person .
    } .

    () log:onNegativeSurface {
      :Bob a :Person .
    } .

    () log:onNegativeSurface {
      :Charly a :Person .
    } .
}.

Other logical truth functions can be built with combinations of AND and NOT, such as the following:

Negative surfaces should also follow the law of double negation elimination: P = NOT ( NOT ( P ) ).

3.3. Answer Surface

TODO

4. Examples

As an illustration of RDF Surface, we offer a graph traversal example. Example 26 provides information about French roads where some roads are blocked due to road works. In this example, we use the predicate :oneway to indicate that a connection is possible from one city to another. To deny this connection, we use a negative surface.

Possible connections between the French cities including a blocked connection between Chartes and Lemans.
@prefix : <urn:example:> .

:Paris :oneway :Orleans .
:Paris :oneway :Chartres .
:Paris :oneway :Amiens .
:Orleans :oneway :Blois .
:Orleans :oneway :Bourges .
:Blois :oneway :Tours .
:Lemans :oneway :Angers .
:Lemans :oneway :Tours .
:Angers :oneway :Nantes .

# blocking some roads
() log:onNegativeSurface {
    :Chartres :oneway :Lemans .
}.

Next, we would like to provide the logic of a "path" through the French road system. We would like to share an RDF document that states: "When there is a :oneway from one city to another city, then there is a :path from the first to the second". Or, expressed in a symbolic form:

∀ _:A, _:B : ( _:A :oneway _:B ) IMPLIES ( _:A :path _:B )

These paths are transitive. When there is a path from A to B and a path from B to C, there is a path from A to C. Or, expressed in a symbolic form:

∀ _:A, _:B, _:C : ( ( _:A :path _:B ) AND ( _:B :path _:C ) ) IMPLIES ( _:A :path _:C )

Using the patterns for IMPLIES from the previous sections these logical formulas can be written as RDF Surfaces in Example 27.

The RDF Surfaces of a path algorithm.
@prefix log: <http://www.w3.org/2000/10/swap/log#> .
@prefix : <urn:example:> .

# oneway subproperty of path
( _:A _:B ) log:onNegativeSurface {
    _:A :oneway _:B .
    () log:onNegativeSurface {
        _:A :path _:B .
    } .
} .

# path transitive property
( _:A _:B _:C ) log:onNegativeSurface {
    _:A :path _:B .
    _:B :path _:C .
    () log:onNegativeSurface {
        _:A :path _:C .
    } .
} .

Based on the RDF documents in Example 26 and 27, we can construct a query to find out which paths are possible that end in Nantes. For this, we use a specialized answer surface that expresses: "If there is some path from A to Nantes, then this is an answer". This is expressed as RDF Surfaces in Example 28.

Query for a possible path from A to Nantes.
@prefix log: <http://www.w3.org/2000/10/swap/log#> .
@prefix : <urn:example:> .

(_:A) log:onNegativeSurface {
    _:A :path :nantes .
    () log:onNegativeAnswerSurface {
        _:A :path :nantes .
        :test :is :true .
    } .
} .

Combining the RDF documents from Examples 26, 27, and 28, an RDF Surfaces reasoner should give as answers:

:Angers :path :Nantes .
:Lemans :path :Nantes .

If we remove the negative surface around :Chartes :oneway :Lemans, an RDF Surfaces reasoner should provide more answers:

:Angers :path :Nantes .
:Lemans :path :Nantes .
:Chartres :path :Nantes .
:Paris :path :Nantes .

For more RDF Surfaces examples, see:

Conformance

Conformance requirements are expressed with a combination of descriptive assertions and RFC 2119 terminology. The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in the normative parts of this document are to be interpreted as described in RFC 2119. However, for readability, these words do not appear in all uppercase letters in this specification.

All of the text of this specification is normative except sections explicitly marked as non-normative, examples, and notes. [RFC2119]

Examples in this specification are introduced with the words “for example” or are set apart from the normative text with class="example", like this:

This is an example of an informative example.

Informative notes begin with the word “Note” and are set apart from the normative text with class="note", like this:

Note, this is an informative note.

References

Normative References

[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. March 1997. Best Current Practice. URL: https://datatracker.ietf.org/doc/html/rfc2119

Informative References

[URI]
T. Berners-Lee; R. Fielding; L. Masinter. Uniform Resource Identifier (URI): Generic Syntax. January 2005. Internet Standard. URL: https://www.rfc-editor.org/rfc/rfc3986

Issues Index

TODO