Curry: An Integrated Functional Logic Language
Curry: An Integrated Functional Logic Language
Curry: An Integrated Functional Logic Language
You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
collect [g] = [g]<br />
collect (g1:g2:gs) = concat (map solveAll (g1:g2:gs))<br />
(concat concatenates a list of lists to a single list). For instance, if append is the list concatenation,<br />
then the expression<br />
solveAll \l -> append l [1] =:= [0,1]<br />
reduces to [\l->l=:=[0]].<br />
The value computed for the search variable in a search goal can be easily accessed by applying<br />
it to a free variable. For instance, the evaluation of the applicative expression<br />
(solveAll \l->append l [1] =:= [0,1]) =:= [g] & g x<br />
binds the variable g to the search goal [\l->l=:=[0]] and the variable x to the value [0] (due to<br />
solving the constraint x=:=[0]). Based on this idea, there is a predefined function<br />
findall :: (a->Success) -> [a]<br />
which takes a search goal and collects all solutions (computed by a depth-first search like solveAll)<br />
for the search variable into a list.<br />
Due to the laziness of the language, search goals with infinitely many solutions cause no problems<br />
if one is interested only in finitely many solutions. For instance, a function which computes only<br />
the first solution w.r.t. a depth-first search strategy can be defined by<br />
first g = head (findall g)<br />
Note that first is a partial function, i.e., it is undefined if g has no solution.<br />
8.2 Local Variables<br />
Some care is necessary if free variables occur in the search goal, like in the goal<br />
\l2 -> append l1 l2 =:= [0,1]<br />
Here, only the variable l2 is abstracted in the search goal but l1 is free. Since non-deterministic<br />
bindings cannot be performed during encapsulated search, free variables are never bound inside encapsulated<br />
search. Thus, if it is necessary to bind a free variable in order to proceed an encapsulated<br />
search operation, the computation suspends. For instance, the expression<br />
first \l2 -> append l1 l2 =:= [0,1]<br />
cannot be evaluated and will be suspended until the variable l1 is bound by another part of the<br />
computation. Thus, the constraint<br />
s =:= (first \l2->append l1 l2 =:= [0,1]) & l1 =:= [0]<br />
can be evaluated since the free variable l1 in the search goal is bound to [0], i.e., this constraint<br />
reduces to the answer<br />
{l1=[0], s=[1]}<br />
In some cases it is reasonable to have unbound variables in search goals, but these variables should<br />
be treated as local, i.e., they might have different bindings in different branches of the search. For<br />
31