asdi 0.2.5

Another Simplistic Datalog Implementation (in Rust)
Documentation
program ::= pragma* ( fact | rule | query )*

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

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

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

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

constant
        ::= string | number | boolean

string  ::= predicate ( ":" ALPHA ( ALPHA | DIGIT | "_" * )? )
            | DQUOTE [^\"]* 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
        ::= ( named-variable | constant ) operator ( 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
        ::= '"'

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) ?
*/