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