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.

Eval [e; rule(l | c = r)] ⇒ {id σ(c|r)}<br />

if σ is a substitution with σ(l) = e<br />

Eval [c] ⇒ D<br />

Eval [c|e] ⇒ replace(c|e, 1, D) Eval [success|e] ⇒ {id e}<br />

Figure 3: Evaluation of conditional rules<br />

always shared, i.e., if an argument of a function is instantiated during a call to this function to<br />

an expression and this expression is evaluated to some value (head normal form), then all other<br />

expressions resulting from instantiating occurrences of the same argument are replaced by the<br />

same value (head normal form). 21 This is necessary not only for efficiency reasons but also for the<br />

soundness of the operational semantics in the presence of non-deterministic functions, as discussed<br />

in Section 2.3.1. The sharing of variables can be described with the more complicated framework<br />

of graph rewriting. Formal descriptions of graph rewriting and narrowing can be found in [15, 18].<br />

D.3 Committed Choice<br />

To define the semantics of calls to functions with the evaluation annotation choice, we assume<br />

that all such calls are enclosed by choice(. . .). Now we extend the rules in Figures 2 and 3 for<br />

covering such choices. <strong>An</strong> expression choice(f(e1, . . . , en)) is reduced as follows. If<br />

Eval [f(e1, . . . , en)] ⇒ ∗ {. . . , σ success|ϕ(r), . . .}<br />

according to the operational semantics described in Figures 2 and 3, where l | c = r is a rule for<br />

f, 22 σ does not bind any free variable occurring in f(e1, . . . , en), and this is the first step in the<br />

derivation with this property, then Eval [choice(f(e1, . . . , en))] ⇒ {id ϕ(r)}.<br />

Thus, if disjunctions occur due to the evaluation of a call to a choice function, these disjunctions<br />

are not distributed to the top-level but are kept inside the choice expression. If one rule for<br />

the choice function becomes applicable (without binding of free variables in this call), all other<br />

alternatives in the disjunction are discarded. Hence, a call to a choice function corresponds to the<br />

committed choice (with deep guards) of concurrent logic languages. This can be implemented by<br />

evaluating this call (with a fair strategy for alternatives) as usual but with the restriction that only<br />

local variables can be bound.<br />

D.4 Equational Constraints<br />

<strong>An</strong> equational constraint e1=:=e2 is solvable if both sides are reducible to a unifiable data term<br />

(strict equality). <strong>An</strong> equational constraint can be solved in an incremental way by an interleaved<br />

21 It should be noted that values are constructor terms like 23, True, or [2,4,5]. This means that the evaluation<br />

of constraints and I/O actions are not shared since they are not replaced by a value after evaluation but<br />

constraints are solved in order to apply a conditional rule (in case of constraints) and I/O actions are applied<br />

to the outside world when they appear at the top-level in a program. This is the intended behavior since the<br />

expressions “putChar ’a’ >> putChar ’a’” and “let ca = putChar ’a’ in ca >> ca” should have an identical<br />

behvarior, namely printing the character ’a’ twice.<br />

22 <strong>An</strong> unconditional rule l = r is considered here as an abbreviation for l | success = r.<br />

68

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

Saved successfully!

Ooh no, something went wrong!