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))