14.11.2012 Views

Curry: An Integrated Functional Logic Language

Curry: An Integrated Functional Logic Language

Curry: An Integrated Functional Logic Language

SHOW MORE
SHOW LESS

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

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!