Checking the semantic equivalence of operations is an important task in software development. For instance, regression testing is a routine task performed when software systems are developed and improved, and software package managers require the equivalence of operations in different versions of a package within the same major number version. A solid foundation is required to support a good automation of this process. It has been shown that the notion of equivalence is not obvious when non-deterministic features are present. In this paper, we discuss a general notion of equivalence in functional logic programs and develop a practical method to check it. Our method is integrated in a property-based testing tool which is used in a software package manager to check the semantic versioning of software packages.
MotivationFunctional logic languages combine the most important features of functional and logic programming in a single language (see [4,20] for recent surveys). In this paper we consider Curry [24], a contemporary functional logic language that conceptually extends Haskell with common features of logic programming. Hence, a Curry function is evaluated lazily and may be non-deterministic when defined by overlapping rules. As discussed in [7], the combination of these features raises new issues for defining the equivalence of expressions. Actually, three different notions of equivalence can be distinguished:1. Ground equivalence: Two expressions are equivalent if they produce the same results when their variables are replaced by ground terms. 2. Computed-result equivalence: Two expressions are equivalent if they produce the same outcomes, i.e., variables in expressions are considered as free variables which might be instantiated during the evaluation process. 3. Contextual equivalence: Two expressions are equivalent if they produce the same outcomes in all possible contexts.⋆ This is an extended version of a paper appeared in → denotes the reflexive and transitive closure of this reduction relation. The equivalence of this rewrite relation and CRWL is shown in [28].
Equivalent OperationsAs discussed above, equivalence of operations can be defined in different ways. Ground equivalence and computed result equivalence only compare the values of applications. This is too weak since some operations have no finite values.Example 3. Consider the following operations that generate infinite lists of numbers: ints1 n = n : ints1 (n+1) ints2 n = n : ints2 (n+2)Lemma 2. Let x be an integer and rs and xs lists of integers such that x ≤ z for all z ∈ rs. Then, for some list of integers r, minRest x rs xs * → (m, r) with m ≤ z for all z ∈ (x : rs++xs) and perm (x : rs++xs) * → m : r (where rs++xs denotes the concatenation of the lists rs and xs).Proof. We assume that x ≤ z for all z ∈ rs. We prove the lemma by induction on the length of the list xs.Base case: xs = []:Since minRest x rs [] *