In order to represent lists as Lisp-like dotted pairs (head . tail) or Prolog-like lists [head | tail], a refinement of
Const '(' TERM* ')'
from Positive Conditions, namely the specialized syntax
'List' '(' TERM TERM ')'
is used by employing a distinguished binary function symbol, List, and a distinguished constant symbol, Nil. Besides dealing with these two distinguished symbols, nothing else changes (especially, in the semantics).
Abstract Syntax
The abstract syntax of lists extends the class TERM in Positive Conditions by a class LIST as follows:
class TERM subclass Var property name: xsd:string subclass Const property name: xsd:string subclass Uniterm property op: Const property arg: list of TERM subclass LIST subclass Nil subclass PAIR property arg1: TERM property arg2: TERM
Here, Nil is a special singleton class. The properties ("role stripes") arg1 and arg2 at the same time suggest minimal use of positional information in concrete syntaxes: the natural order of the two elements of a LIST that is a PAIR. This will considerably support readability of the concrete syntaxes (see below). There is an obvious 1-to-1 mapping between the above LIST class and the following earlier-considered LIST class:
subclass LIST subclass Nil subclass PAIR property first: TERM property rest: TERM
The abstract syntax is visualized by a UML diagram. (***TBD***)
Upload new attachment "ListConditionModel.png"
Concrete Syntax
The abstract syntax of Section Abstract Syntax can again be instantiated to a concrete EBNF syntax.
For this, TERMs, in Positive Conditions defined as
TERM ::= Const | Var | Uniterm
are extended to
TERM ::= Const | Var | Uniterm | LIST
with
LIST ::= 'Nil' | 'List' '(' TERM TERM ')'
For example, the Prolog list [a,Y,c] or [a | [Y | [ c | []]]] becomes the List nesting
List( a List( ?Y List( c Nil ) ) )
The following is a possible XML-serializing mapping of the abstract syntax in Section Abstract Syntax (and of the above EBNF syntax):
<List> <Const>a</Const> <List> <Var>Y</Var> <List> <Const>c</Const> <Nil/> </List> </List> </List>
This shortens an equivalent earlier-considered version using explicit arg stripes:
<List> <arg index="1"><Const>a</Const></arg> <arg index="2"> <List> <arg index="1"><Var>Y</Var></arg> <arg index="2"> <List> <arg index="1"><Const>c</Const></arg> <arg index="2"><Nil/></arg> </List> </arg> </List> </arg> </List>
Lists can be decomposed using syntactic equality (unification). For example, [?head | ?tail] = [a ?Y c]:
<List> <Var>head</Var> <Var>tail</Var> </List>
unifies with
<List> <Const>a</Const> <List> <Var>Y</Var> <List> <Const>c</Const> <Nil/> </List> </List> </List>
by binding
<Var>head</Var> to
<Const>a</Const>
and
<Var>tail</Var>
to
<List> <Var>Y</Var> <List> <Const>c</Const> <Nil/> </List> </List>
Nested Prolog Lists such as [a,[X,b],c] or [a | [[X | [b | []]] | [ c | []]]] are of course allowed:
<List> <Const>a</Const> <List> <List> <Var>X</Var> <List> <Const>b</Const> <Nil/> </List> </List> <List> <Const>c</Const> <Nil/> </List> </List> </List>
The mapping to RDF lists is even more direct than in OWL 1.1, since its source are binary List constructor applications rather than n-ary SEQ constructor applications.