Primordial LX

Introduction

The primordial serialization is a simple format for subject-predicate-object (or thing-property-value) triples. These triples can function as a foundation for other languages and are useful in their own right as seen in the history of frame systems, semantic networks, and recent work on in RDF. This syntax is equivalent to RDF without literals.

This flavor of LX, like the primordial soup, is more a conceptual point-of-origin than something to actually produce or consume in quantity.

Names

Each of the three terms in each triple is a kind of name or identifier for something in the domain of discourse. Names are either internal, being local to the scope of the document, or external, being universally shared.

Internal names are roughly equivalent to existentially quantified variables whose scope is that of the document and to RDF bNodes. There are also very similar to programming language identifiers which are local to a compilation unit.

External names follow the URI-Reference syntax and semantics [RFC 2396]. They to denote the same thing in all expressions in all documents where they occur as names. In their external form, they look like: http://www.example.com/animals#Dog or sometimes just http://www.example.com/animals

Individual reasoners (human and machine) may have various addition knowledge about particular external names (URI-References) and the things they denote. This is what allows Primordial LX be a useful language; without such knowledge, only the most trivial information can be conveyed. The descriptions of URI-Refs comprising the vanilla and chunky LX vocabularies allows vanilla and chunky expressions to be conveyed in primordial LX documents.

Syntax for Names

To reduce human error and improve readability, internal names must be explicitely introduced. This can be done with either a @internal directive, or with an exists quantifier.

External names can be given in either a full form, which is a URI-Ref surrounded by angle-brackets and single quotes:

'<http://www.example.com/animals#Dog>'
or in an abbreviate form, which looks like an internal name but is mapped to a URI-Ref. In this case, we might use animals_Dog, with the prefix "animals_" declared to correspond to http://www.example.com/animals#"

@external(abbreviated-name, external-name) can be used for a particular name, while @external(abbreviation-prefix*, external-name-prefix) can be used for a group.

This is not perfect. It would be nice to reduce the error potential in mistyping and misusing external names. It would be nice to specify directionality (import vs export). It might be nice to have external names, even in abbreviated form, look different from internal names. Perhaps lx:Conjunction, lx::Conjunction, or lx.Conjuction would be better than lx_Conjunction. This will do for now.

The @ directives are not strictly necessary in LX, but they do significantly improve readability and maintainability. While that is not important for primordial LX, it will be useful for languages which use primordial as their starting point.

Examples

A simple triple, saying the rdf:type of rdf:type is rdf:Property:

triple('<http://www.w3.org/1999/02/22-rdf-syntax-ns#type>',
       '<http://www.w3.org/1999/02/22-rdf-syntax-ns#type>', 
       '<http://www.w3.org/1999/02/22-rdf-syntax-ns#Property>').

The same triple, using the "@external" name mapping directive:

@external(rdf_*, "http://www.w3.org/1999/02/22-rdf-syntax-ns#").
triple(rdf_type, rdf_type, rdf_Property).

A pair of triples using two local names:

@external(rdf_*, "http://www.w3.org/1999/02/22-rdf-syntax-ns#").
exists t s (
  triple(t, rdf_type, rdf_Statement) &
  triple(t, rdf_subject s)
)

The same pair of triples using the "@local" directive:

@local(t)
@local(s)
triple(t, rdf_type, rdf_Statement).
triple(t, rdf_subject s).

Grammar

This grammar is written in blindfold's EBNF.

token(ws, comment, string, tripleKeyword, plainName, URIRef)
document ::= ( item "." )*
item ::= directive | formula
directive ::= "@local(" name ")"
            | "@external(" name "," string ")"
            | "@external(" name "*" "," string ")"
ws ::= [\n\r\t ]* @ignored
comment ::= "#[^\n]*" @ignored
formula ::= tightFormula | looseFormula
tightFormula ::= atomicFormula 
               | "(" formula ")"
looseFormula ::= formula "&" formula
               | "exists" namelist tightFormula
atomicFormula ::= tripleKeyword "(" name "," name "," name ")"
tripleKeyword ::= "triple"
name ::= ( plainName | URIRef )     # disjoint from tripleKeyword
plainName ::= [_a-zA-Z][_a-zA-Z0-9]*
URIRef ::= "'<" [^ ()[]<>{}] ">'"          # should be more detailed
namelist ::= plainName ( "," plainName )*

Restrictions not shown in this grammar:

  1. All plainNames must be introduced before being used. They can be introduced for the rest of the document by a directive, or for one formula scope by an "exists". "exists" may not re-introduce an already introduced name; it increases the potential for confusion (especially with external names) for no demonstrated benefit.
  2. The predicate (middle) name in an atomicFormula must be external. This is an unpleasant bit of RDF we need to put here for full compatibility.

Semantics

The semantics of Primordial are exactly those of this syntactic subset of Vanilla. Existentials quantification and conjunction have their usual classical meaning. Multiple formulas in a document are considered to be conjoined.

Issues

@include

It's tempting to add @import(f, uri) which makes f be the logical formula available at the given URI, or some other inclusion mechanism, but maybe this is better done with log:semantics, where uri can be a variable.

Maybe we can at least have @include so we don't need huge lists of @externals in every file?

Triple as Binary Atomic Sentence

It's very tempting to use p(s,o) instead of triple(s, p, o). We would get rid of the ugly "triple" keyword. And it would make the RDF restriction of having no bNode predicates seem right.

But it would mean we couldn't even axiomatize RDFS. We could use a fake higher-order syntax, and "lower" everything with a "holds" predicate before doing FOL reasoning, but then it would hardly be Vanilla.

Declaring Universal Variables

In Vanilla, we often want document-scope universally-quantified variables. Can we do that like @internal? Maybe @variable? Or just use all-caps like Prolog?

A Better Syntax for Full Externals

Maybe uriref('<.....>') would allow better evolution and not use up single-quotes? It's still OTTER compatible, although it might slow things down a little. But it would not be usable for naming functions and predicates in Vanilla. Or we could just do <...> and have the directive preprocessor handle it. Is that disjoint enough from greater-than and less-than? One can also put in a space to make it distinct, I guess.

Internal Names for Prediciates

Is this okay? Not in RDF. At what level...?

Blindfold Grammar

What should the bf grammar translate to? Maybe primordial without directives or internal names, ie Pure Otter? Handling the directives itself is probably beyond blindfold. Hrm.

Other Grammar

How about pointing us at SOME kind of parser for this, which turns it into a suitable OTTER formula list? It can have a flag on whether to expand or ignore @external declarations.


LX development work is being done as part of the MIT/LCS DAML Project under the MIT/AFRL cooperative agreement number F30602- 00-2-0593. This work is not on the W3C recommendation track and is not the product of a W3C working group or interest group.

Sandro Hawke
First: 2002/11/04; This: $Date: 2002/11/08 23:52:03 $