program ::= clause EOCL
| clause EOCL program
clause ::= head
| head rulech goals
| rulech goals
head ::= term_h
goals ::= term_g
| goals , goals
| goals ; goals
| goals -> goals
| goals -> goals ; goals
term_h ::= term_h(0)
| term(1200)
term_g ::= term_g(0)
| term(1200)
term(0) ::= VAR /* not a term_h */
| attr_var /* not a term_h */
| ATOM
| structure
| structure_with_fields
| subscript
| list
| STRING /* not a term_h nor a term_g */
| number /* not a term_h nor a term_g */
| bterm
term(N) ::= term(0)
| prefix_expression(N)
| infix_expression(N)
| postfix_expression(N)
prefix_expression(N) ::= fx(N) term(N-1)
| fy(N) term(N)
| fxx(N) term(N-1) term(N-1)
| fxy(N) term(N-1) term(N)
infix_expression(N) ::= term(N-1) xfx(N) term(N-1)
| term(N) yfx(N) term(N-1)
| term(N-1) xfy(N) term(N)
postfix_expression(N) ::= term(N-1) xf(N)
| term(N) yf(N)
attr_var ::= VAR { attributes }
/* Note: no space before { */
attributes ::= attribute
| attribute , attributes
attribute ::= qualified_attribute
| nonqualified_attribute
qualified_attribute ::= ATOM : nonqualified_attribute
nonqualified_attribute ::= term_a
structure ::= functor ( termlist )
/* Note: no space before ( */
structure_with_fields ::= functor { termlist }
| functor { }
/* Note: no space before { */
subscript ::= structure list
| VAR list
/* Note: no space before list */
termlist ::= term_a
| term_a , termlist
list ::= [ listexpr ]
| .(term_a, term_a)
listexpr ::= term_a
| term_a | term_a
| term_a , listexpr
term_a ::= term(1200)
/* Note: it depends on syntax_options */
number ::= INT
| INTBAS
| INTCHAR
| RAT
| FLOAT
| BREAL
bterm ::= ( clause )
| { clause }
functor ::= ATOM /* arity > 0 */
rulech ::= :-
| ?-
f is declared prefix unary (fx or fy),
then the term f(X) can alternatively be written as f X.
f is declared prefix binary (fxx or fxy),
then the term f(X,Y) can alternatively be written as f X Y.
f is declared postfix (xf or yf),
then the term f(X) can alternatively be written as X f.
f is declared infix (xfx, xfy or yfx),
then the term f(X,Y) can alternatively be written as X f Y.
Operator declarations are usually local to a module, but they can be exported and imported. The operator visible in a module is either the local one (if any), an imported one, or a predefined one. Some operators are pre-defined (see Appendix B on page ??). They may be locally redefined if desired.Example declaration will allow to stand for --------------------------------------------------------------- :- op(500,xfx,in). A in B in(A,B) :- op(500,xfy,in). A in B in C in(A,in(B,C)) :- op(500,yfx,in). A in B in C in(in(A,B),C) :- op(500,fx ,pre). pre A pre(A) :- op(500,fy ,pre). pre pre A pre(pre(A)) :- op(500, xf,post). A post post(A) :- op(500, yf,post). A post post post(post(A)) :- op(500,fxx,bin). bin A B bin(A,B) :- op(500,fxy,bin). bin A bin B C bin(A,bin(B,C))