Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Appendix: Datalog EBNF

The following is the EBNF definition of the Datalog native text representation. Note that this is simplified somewhat from the actual parser specification ASDI uses although in practice the differences are irrelevant.

program ::= pragma* ( fact | rule | query )* ;

/* ************************************************************************* */

fact    ::= predicate ( "(" constant ( "," constant )* ")" )? "." ;

predicate
        ::= LC_ALPHA ( ALPHA | DIGIT | "_" )* ;

/* ************************************************************************* */

constant
        ::= string | number | boolean ;

string  ::= predicate ( ":" ALPHA ( ALPHA | DIGIT | "_" * )? )
            | DQUOTE [^#x22]* DQUOTE ;

number  ::= float | decimal | integer ;

integer ::= ( "+" | "-" )? DIGIT+ ;

decimal ::= integer "." DIGIT+ ;

float   ::= decimal ( "e" | "E" ) integer ;

boolean ::= ( "true" | "⊤" ) | ( "false" | "⊥" ) ;

/* ************************************************************************* */

rule    ::= ( head | "⊥" )? ( ":-" | "<-" | "⟵" ) body "." ;

head    ::= ( atom ( ( ";" | "|" | "OR" | "∨" ) atom )* ) ;

body    ::= literal ( ( "," | "&" | "AND" | "∧" ) literal )* ;


/* ************************************************************************* */

atom    ::= predicate "(" term ( "," term )* ")" ;

term    ::= variable | constant ;

variable
        ::= named-variable | anon-variable ;

named-variable
        ::= UC_ALPHA ( ALPHA | DIGIT | "_" )* ;

anon-variable
        ::= "_" ;

/* ************************************************************************* */

literal ::= ( "!" | "NOT" | "¬" )? ( atom | comparison ) ;

/* ************************************************************************* */

comparison
        ::= operand operator operand ;

operand ::= ( named-variable | constant ) ;

operator
        ::= "="
            | ("!=" | "/=" | "≠")
            | "<"
            | ("<=" | "≤")
            | ">"
            | (">=" | "≥")
            | ("*=" | "≛" | "MATCHES") ;

/* ************************************************************************* */

query   ::= ( "?-" atom "." ) | ( atom "?" ) ;

/* ************************************************************************* */

pragma  ::= "." ( feature | assert | infer | fd | input | output ) "." ;

feature ::= "feature" "(" feature-id ( "," feature-id )* ")" ;

feature-id
        ::= "comparisons"
        | "constraints"
        | "disjunction"
        | "negation"
        | "functional_dependencies" ;

assert  ::= "assert" predicate "(" attribute-decl ( "," attribute-decl )* ")" ;

attribute-decl
        ::= ( predicate ":" )? ( "boolean" | "integer" | "string" ) ;

infer   ::= "infer"
            ( predicate "(" attribute-decl ( "," attribute-decl )* ")"
            | "from" predicate ) "." ;

fd      ::= ( "fd" | "functional_dependency" )
            predicate ":"
            attribute-index-list ( "-->" | "⟶" ) attribute-index-list ;

attribute-index-list
        ::= attribute-index ( "," attribute-index )* ;

attribute-index
        ::= integer | predicate ;

input   ::= "input" io-details ;

io-details
        ::= "(" predicate "," quoted-string ( "," quoted-string )? ")" ;

output  ::= "output" io-details ;

/* ************************************************************************* */

comment ::= "%" [^\r\n]* EOL
            | '/*' ( [^*] | '*'+ [^*/] )* '*'* '*/' ;

/* ************************************************************************* */

EOL     ::= "\n" | "\\r\\n" | "\r" ;

WHITESPACE
        ::= " " | "\t" | EOL ;

DQUOTE  ::= #x22 ;

LC_ALPHA
        ::= ? corresponds to the Unicode category 'Ll' ? ;

UC_ALPHA
        ::= ? corresponds to the Unicode category 'Lu' ? ;

ALPHA   ::= LC_ALPHA | UC_ALPHA ;

DIGIT   ::= ? corresponds to the Unicode category 'Nd' (decimal number) ? ;

This file is accessible directly here.