Author(s): Amadeo Casas Cuadrado, Daniel Cabeza, Manuel Hermenegildo.
Version: 1.10#6 (2004/8/7, 21:46:39 CEST)
Version of last change: 1.9#291 (2004/2/13, 20:46:8 CET)
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
~ is a function application, as in
write(~arg(1,T)), which is equivalent to the sequence
arg(1,T,A), write(A). Functors can be declared as evaluable by using the declaration
function/1, and thus avoiding the need to use the operator
~, as in
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:
is/2. This feature can be disabled by a declaration
:- function(arith(false))(and reverted by using
(?)/2. A disjunctive expression has the form
(V1|V2), and its value when first evaluated is
V1, and on re-execution
V2. A conditional expression has the form
(Cond ? V1), or more commonly
(Cond ? V1 | V2), and its value, if the execution of
Condas a goal succeeds, is
V1, otherwise in the first form it causes backtracking, and on the second form its value is
V2. Note that due to the operator precedences, these expressions need normally to be surrounded by parenthesis.
A functional clause is written using the binary operator
:=, as in
opposite(red) := green.
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:
fact(0) := 1. fact(N) := N * ~fact(--N) :- N > 0.
Note that often a guard can be better defined using a conditional expression:
fact(N) := N = 0 ? 1 | N > 0 ? N * ~fact(--N).
In clause heads (either defined as predicates or functions) functors can be prevented from being evaluated by using the
(^)/1 prefix operator, as in
pair(A,B) := ^(A-B).
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
(^^)/1 prefix operator, as in
findall(X, (d(Y), ^^(X = Y+1)), L) (which could also be written as
findall(X, ^^ (d(Y), X = Y+1), L)).
Go to the first, previous, next, last section, table of contents.