Abstract. Functional logic languages extend purely functional languages with two features: operations defined by overlapping rules and logic variables in both defining rules and expressions to evaluate. In this paper, we show that only one of these features is sufficient in a core language. On the one hand, overlapping rules can be eliminated by introducing logic variables in rules. On the other hand, logic variables can be eliminated by introducing operations defined by overlapping rules. The proposed transformations between different classes of programs not only give a better understanding of the features of functional logic programs but also may simplify implementations of functional logic languages.
MotivationFunctional logic languages [20] integrate the best features of functional and logic languages in order to provide a variety of programming concepts. For instance, the concepts of demand-driven evaluation and higher-order functions from functional programming can be combined with logic programming features like computing with partial information (logic variables), constraint solving, and nondeterministic search for solutions. In contrast to purely functional languages, functional logic languages allow computations with overlapping rules (i.e., more than one rule can be applied to evaluate a function call) and logic variables (i.e., unbound variables occurring in the initial expression and/or rules, also called extra variables). Operationally, these features are supported by nondeterministic computation steps.Functional logic languages are modeled by constructor-based term rewriting systems (TRS) with narrowing as the evaluation mechanism. A crucial choice in the design of a language, both at the source level and the implementation level, is the class of rewrite systems used to model the programs. Early languages (e.g., ) were modeled by weakly orthogonal, constructor-based TRSs. Larger classes are more expressive, i.e., programs in