:- use_package(assertions).
:- comment(nodoc,assertions).

:- comment(title,"Functional notation").

:- comment(author,"Daniel Cabeza").

:- comment(module, "This library package allows the use of functional
   notation in a Ciao module/program.

   It should be made clear that this package just provides a kind of
   syntactic sugar for defining and using predicates as if they were
   functions, and thus any function definition is in fact defining a
   predicate, and any predicate can be used as a function.  The
   predicate associated to a function has the same name and one more
   argument, added to the right, to hold the result of the function.

   Any term preceded by the operator @tt{~} is a function application,
   as in @tt{write(~arg(1,T))}, which is equivalent to the sequence
   @tt{arg(1,T,A), write(A)}.  Functors can be declared as evaluable by
   using the declaration @pred{function/1}, and thus avoiding the need
   to use the operator @tt{~}, as in
@begin{verbatim}
:- function(arg/2).
@end{verbatim}
   Note that this declaration, as is customary in Ciao Prolog, is local
   to the source code where it is included.  In addition, the package
   defines several functors as evaluable by default, those being:
@begin{itemize}
@item All the functors understood by @pred{is/2}.  This feature can be
      disabled by a declaration @tt{:- function(arith(false))} (and
      reverted by using @tt{true} instead of @tt{false}).
@item The functors used for disjunctive and conditional expressions,
      @tt{(|)/2} and @tt{(?)/2}.  A disjunctive expression has the form
      @tt{(V1|V2)}, and its value when first evaluated is @tt{V1}, and
      on re-execution @tt{V2}.  A conditional expression has the form
      @tt{(Cond ? V1)}, or more commonly @tt{(Cond ? V1 | V2)},
      and its value, if the execution of @tt{Cond} as a goal succeeds,
      is @tt{V1}, otherwise in the first form it causes backtracking,
      and on the second form its value is @tt{V2}. Note that due to the
      operator precedences, these expressions need normally to be surrounded
      by parenthesis.
@end{itemize}

   A functional clause is written using the binary operator @tt{:=},
   as in
@begin{verbatim}
opposite(red) := green.
@end{verbatim}
   Functional clauses can also have a body, which is executed before the
   result value is computed.  It can serve as a guard for the clause or to
   provide the equivalent of a where-clause in a functional language:
@begin{verbatim}
fact(0) := 1.
fact(N) := N * ~fact(--N) :- N > 0.
@end{verbatim}
   Note that often a guard can be better defined using a conditional
   expression:
@begin{verbatim}
fact(N) := N = 0 ? 1
         | N > 0 ? N * ~fact(--N).
@end{verbatim}

   In clause heads (either defined as predicates or functions)
   functors can be prevented from being evaluated by using the
   @tt{(^)/1} prefix operator, as in
@begin{verbatim}
pair(A,B) := ^(A-B).
@end{verbatim}
   Note that this just prevents the evaluation of the principal functor
   of the enclosed term, not the possible occurrences of other evaluable
   functors inside.  The operator is by now ignored outside clause
   heads, due to the recurrent nature of the goal translations used.

   When using function applications inside the goal arguments of
   meta-predicates, there is an ambiguity as they could be evaluated
   either in the scope of the outer execution or the in the scope of
   the inner execution.  The chosen behavior is by default to evaluate
   function applications in the scope of the outer execution, and if
   they should be evaluated in the inner scope, the goal containing the
   function application needs to be escaped with the @tt{(^^)/1} prefix
   operator, as in @tt{findall(X, (d(Y), ^^(X = Y+1)), L)} (which could
   also be written as @tt{findall(X, ^^ (d(Y), X = Y+1), L)}).
  ").

:- comment(bug, "The @tt{(^)/1} operator only works in clause heads.").
:- comment(bug, "Assumes that @pred{is/2} is imported.").

:- comment(version_maintenance,dir('../../version')).

:- comment(version(1*9+291,2004/02/13,20:46*08+'CET'), "Added support
   for conditional and disjunctive expressions.  Fixed bug which disallowed
   the use of functions inside @pred{is/2}. (Daniel Cabeza Gras)").

:- comment(version(1*9+242,2003/12/22,19:22*40+'CET'), "Added comment
   author. (Edison Mera)").

:- comment(version(1*7+186,2002/02/04,19:11*45+'CET'), "Added ^^
   operator to avoid expanding a goal inside another goal.  (Daniel
   Cabeza Gras)").

:- comment(version(1*7+183,2002/01/31,19:15*16+'CET'), "Fixed a bug
   related expansion of module-qualified predicate/function calls.
   (Daniel Cabeza Gras)").

:- comment(version(1*7+103,2001/05/21,19:22*58+'CEST'), "Fixed a bug
   related to disabling arithmetic functions and defining new predefined
   function names.  (Daniel Cabeza Gras)").

