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

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

which takes a search goal and produces a list of search goals. The search operator try attempts to<br />

evaluate the search goal until the computation finishes or performs a non-deterministic splitting.<br />

In the latter case, the computation is stopped and the different search goals caused by this splitting<br />

are returned as the result list. Thus, an expression of the form try \x->c can have three possible<br />

results:<br />

1. <strong>An</strong> empty list. This indicates that the search goal \x->c has no solution. For instance, the<br />

expression<br />

try \x -> 1=:=2<br />

reduces to [].<br />

2. A list containing a single element. In this case, the search goal \x->c has a single solution<br />

represented by the element of this list. For instance, the expression<br />

try \x->[x]=:=[0]<br />

reduces to [\x->x=:=0]. Note that a solution, i.e., a binding for the search variable like the<br />

substitution {x ↦→ 0}, can always be presented by an equational constraint like x=:=0.<br />

Generally, a one-element list as a result of try has always the form [\x->x=:=e] (plus some<br />

local variables, see next subsection) where e is fully evaluated, i.e., e does not contain defined<br />

functions. Otherwise, this goal might not be solvable due to the definition of equational<br />

constraints.<br />

3. A list containing more than one element. In this case, the evaluation of the search goal<br />

\x->c requires a non-deterministic computation step. The different alternatives immediately<br />

after this non-deterministic step are represented as elements of this list. For instance, if the<br />

function f is defined by<br />

f a = c<br />

f b = d<br />

then the expression<br />

try \x -> f x =:= d<br />

reduces to the list [\x->x=:=a & f a =:= d, \x->x=:=b & f b =:= d]. This example also<br />

shows why the search variable must be abstracted: the alternative bindings cannot be actually<br />

performed (since a free variable is only bound to at most one value in each computation<br />

thread) but are represented as equational constraints in the search goal.<br />

Note that the search goals of the list in the last example are not further evaluated. This provides<br />

the possibility to determine the behavior for non-deterministic computations. For instance, the<br />

following function defines a depth-first search operator which collects all solutions of a search goal<br />

in a list:<br />

solveAll :: (a->Success) -> [a->Success]<br />

solveAll g = collect (try g)<br />

where collect [] = []<br />

30

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

Saved successfully!

Ooh no, something went wrong!