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.

to an expression):<br />

Eval [ϕ(e1, . . . , em)@e] ⇒ ϕ(e1, . . . , em, e) if ϕ has arity n and m < n<br />

Thus, we evaluate an application by simply adding the argument to a partial application. If<br />

a function has the right number of arguments, it is evaluated by the rules in Figure 2. Note<br />

that the function application is “rigid” in its first argument since the application suspends if the<br />

applied function is unknown (instead of a possible but expensive non-deterministic search for the<br />

appropriate function).<br />

λ-abstractions occurring in expressions are anonymous functions and can be implemented by<br />

assigning a new name to each λ-abstraction, where the free variables become parameters of the<br />

function. For instance, the λ-abstraction (f is a free variable)<br />

\x y -> f x y + 2<br />

can be replaced by the (partial) application (lambda f), where lambda is a new name, and adding<br />

the rule<br />

lambda f x y = f x y + 2<br />

Note that this transformation (as well as the extension of Eval [·] above) is only used to explain the<br />

operational meaning of <strong>Curry</strong>’s higher-order features. A concrete <strong>Curry</strong> system is free to choose<br />

other implementation techniques.<br />

D.6 Generating Definitional Trees<br />

<strong>Curry</strong>’s computation model is based on the specification of a definitional tree for each operation.<br />

Although definitional trees are a high-level formalism to specify evaluation strategies, it is tedious<br />

to annotate each operation which its definitional tree. Therefore, the user need not write them<br />

explicitly in the program since they are automatically inserted by the <strong>Curry</strong> system. In the following,<br />

we present <strong>Curry</strong>’s algorithm to generate definitional trees from the left-hand sides of the<br />

functions’ rules.<br />

The generation of definitional trees for each function is not straightforward, since there may<br />

exist many non-isomorphic definitional trees for a single function representing different evaluation<br />

strategies. This demands for a default strategy to generate definitional trees. <strong>Curry</strong> uses the<br />

following default strategy:<br />

1. The leftmost argument, where a constructor occurs at the corresponding position in all lefthand<br />

sides defining this function, is evaluated to head normal form.<br />

2. or nodes (i.e., disjunctions) are generated in case of a conflict between constructors and<br />

variables in the left-hand sides, i.e., if two rules have a variable and a constructor at the same<br />

position on the left-hand side.<br />

In the following, we assume that all rules are unconditional (it is obvious how to extend it to<br />

conditional rules since only the left-hand sides of the rules are relevant for the definitional trees).<br />

To specify the construction algorithm, we define by<br />

DP (π, R) = {o position of a variable in π | root(l|o) ∈ C for some l = r ∈ R}<br />

70

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

Saved successfully!

Ooh no, something went wrong!