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.

instance, if we want to compute the last element of the list [3,4,5] based on append, we could try<br />

to solve the search goal<br />

\e -> append l [e] =:= [3,4,5]<br />

However, the evaluation of this goal suspends due to the necessary binding of the free variable l.<br />

This can be avoided by declaring the variable l as local to the constraint by the use of let (see<br />

Section 2.5), like in the following expression:<br />

first \e -> let l free in append l [e] =:= [3,4,5]<br />

Due to the local declaration of the variable l (which corresponds logically to an existential quantification),<br />

the variable l is only visible inside the constraint and, therefore, it can be bound to<br />

different values in different branches. Hence this expression evaluates to the result 5.<br />

In order to ensure that an encapsulated search will not be suspended due to necessary bindings<br />

of free variables, the search goal should be a closed expression when a search operator is applied<br />

to it, i.e., the search variable is bound by the lambda abstraction and all other free variables are<br />

existentially quantified by local declarations.<br />

8.3 Predefined Search Operators<br />

There are a number of search operators which are predefined in the prelude. All these operators are<br />

based on the primitive try as described above. It is also possible to define other search strategies<br />

in a similar way. Thus, the try operator is a a powerful primitive to define appropriate search<br />

strategies. In the following, we list the predefined search operators.<br />

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

Compute all solutions for a search goal via a depth-first search strategy. If there is no solution<br />

and the search space is finite, the result is the empty list, otherwise the list contains solved<br />

search goals (i.e., without defined operations).<br />

once :: (a->Success) -> (a->Success)<br />

Compute the first solution for a search goal via a depth-first search strategy. Note that once<br />

is partially defined, i.e., if there is no solution and the search space is finite, the result is<br />

undefined.<br />

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

Compute all solutions for a search goal via a depth-first search strategy and unpack the<br />

solution’s values for the search variable into a list.<br />

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

Compute the best solution via a depth-first search strategy, according to a specified relation<br />

(the second argument) that can always take a decision which of two solutions is better<br />

(the relation should deliver True if the first argument is a better solution than the second<br />

argument).<br />

As a trivial example, consider the relation shorter defined by<br />

shorter l1 l2 = length l1

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

Saved successfully!

Ooh no, something went wrong!