TRANSFINITE CORECURSION

0 downloads 0 Views 181KB Size Report
The notion of ordinal is obtained as a generalization of the notion of natural ... There is a natural order ⩽ on ordinals: o ⩽ π iff, for any well-ordered sets A and.
Nordic Journal of Computing 12(2005), 1–24.

TRANSFINITE CORECURSION HÄRMEL NESTRA Institute of Computer Science, University of Tartu J. Liivi 2, 50409 Tartu, Estonia [email protected]

Abstract. This paper presents theorems which enable to define transfinite semantics for programming languages easily. We call these theorems “corecursion theorems” because they state the existence of a function satisfying certain conditions analogous to the usual corecurrent equations for defining stream-valued functions. Transfinite semantics have been proposed for overcoming the “semantic anomaly” of program slicing. In this paper, we define two example semantics which justify this approach, relying on our corecursion theorems. ACM CCS Categories and Subject Descriptors: D.3.1 [Programming Languages]: Formal Definitions and Theory – semantics; F.3.2 [Logics and Meanings of Programs]: Semantics of Programming Languages – operational semantics; F.4.1 [Mathematical Logic and Formal Languages]: Mathematical Logic – set theory; I.2.2 [Artificial Intelligence]: Automatic Programming – program transformation Key words: corecursion, transfinite semantics, program slicing

1. Introduction Standard semantics consider computations doing at most ω steps (i.e. computations whose any proper initial part is finite). This choice has been artless since no real computation process can ever do more. By transfinite semantics, one means a semantics according to which computation may continue after an infinite number of steps from some limit state determined somehow by the infinite computation performed. Transfinite semantics have turned out to be useful for constructing an adequate theoretical setting for some applications. For example, the first study of transfinite semantics has been done for functional programming, see [6]. The necessity arises from the fact that there are (finite) expressions whose value is an infinite data structure which can not be reached using any standard reduction strategy with the first ω reductions. Recently, Giacobazzi and Mastroeni [4] have investigated transfinite semantics for a simple imperative language with structured control flow with the aim to overcome the so-called semantic anomaly of program slicing [2] which arises when infinite loops are sliced away. The idea was proposed already in [3]. We give a brief overview on this matter now; further discussion is carried out in Sect. 6. Informally, the aim of program slicing is to find an executable part (a slice) of a program which can compute certain interesting values equally well to the original Received February 2005; accepted September 2005.

2

HÄRMEL NESTRA

program. A standard example of program slicing is the following: 0 sum

:= 0; := 1; 2 i := 0; while 3 i < n do ( 4 i := i + 1; 5 sum := sum + i; 6 prod := prod * i );

0 sum

:= 0;

1 prod

2i

:= 0; while 3 i < n do ( 4 i := i + 1; 5 sum := sum + i;

−→

); 7

7

(The small numbers denote program points.) The first program computes both the sum and the product of the first n positive integers (where n is the initial value of n). The second program computes the sum; all statements concerning the product only are sliced away. If the sum is the only interesting value, the two programs are equally good. A slicing criterion of a program P is any subset of V(cfg P) × X where V(cfg P) is the set of all program points of P and X is the set of variables occurring in P. The criterion specifies which variables at which program points contain values important to the user. Hence  the second program above is a slice of the first program w.r.t. criterion (7, sum) . The essential property of slice — being equally good to the original program in computing the values of user’s interest — is more precisely formulated as follows: for arbitrary initial values of variables, the slice and the original program compute the same sequence of values for every program point and variable related by the criterion. For the example program and its slice above, control reaches program point 7 just once (at the end of execution) and, when this happened, the value of sum computed by both programs is the same. Consider now the following example. while 0 true do ; 1 x := 0 ; 2

−→

1x

:= 0 ;

2

The program  on the right is obtained by slicing the program on the left w.r.t. criterion (2, x) . But the desired property of slice discussed above is not met because program point 2 is reached no times by the original program while being reached once by the slice. This phenomenon is called semantic anomaly [9, 4]. The desired property would hold if we had some terminating statement instead of while true do . Semantic anomaly is therefore a fundamental issue since no slicing algorithm can decide for all cases whether a loop terminates. So to properly specify program slicing, a semantics is needed which abstracts from termination. In our work in progress, we look for mathematically rigorous specification of slicing using transfinite trace semantics, trying to go beyond the results of [4]. Transfinite trace semantics of a program is basically a set of transfinite lists of

TRANSFINITE CORECURSION

3

states or configurations satisfying certain conditions. Transfinite list is a function whose domain is a downward closed set of ordinals (i.e. a set O containing all elements less than any element belonging to O). This paper makes a step toward this aim by providing corecursion theorems for justifying definitions of transfinite trace semantics analogous to the widely used corecurrent definitions of streams. Traditional stream corecursion is not satisfactory for defining transfinite lists because it is able to determine only up to ω first elements of the list, telling nothing about the following part. So the key problem lies in allowing the “infinite steps” which involves defining the limit states into which computation falls after an infinite number of steps. Section 2 gives a closer (but rather informal) explanation of the kind of corecursion we are desiring, contrasting it with the usual stream corecursion. Section 3 contains an introduction to ordinals, listing some basic notions and many basic facts. All this is well-known to people familiar with ordinals. However, we in a few cases prefer to use our own non-standard terms. In Sect. 4, we prove two transfinite corecursion theorems: one is designed for applying to deterministic semantics, the other for non-deterministic case. The theorems are formulated at a quite abstract level without even mentioning semantics to enable them to be used in possible other areas. Section 5 gives a further discussion about the matter. Section 6 provides examples of defining transfinite semantics of While (a simple imperative programming language). The advantage of transfinite semantics over standard ones is explained from the aspect of solving the semantic anomaly problem of program slicing. Section 7 describes briefly some problems to be investigated in the future and refers to related work. 2. Corecursion Like recursion, corecursion is a special way to define functions. The name is due to the fact that recursion and corecursion are dual notions [5]. To get a very informal insight on this, note that functions defined on finite lists are often defined recursively on the structure of argument; functions giving finite or infinite lists (streams) as values can often be defined corecursively on the structure of result. When one has to define functions whose values are streams, corecursion is often the neatest choice. Consider an example from number theory of defining continued fractions. The function c which takes real numbers to their representations as continued fractions satisfies the corecurrent equation ) (   1 if x < Z c hxi c(x) = ⌊x⌋ : nil otherwise where : and nil are the cons and empty-list constructor, respectively, and ⌊x⌋, hxi denote the integral and fractional part of x, respectively. Obviously, this equation determines the function c uniquely despite containing c in the right-hand side. In number theory books, continued fractions are usually defined recursively rather than corecursively, resulting in a more complicated formulation because the length of the result is not known a priori, it clears up as the computation reaches the end.

4

HÄRMEL NESTRA

The soundness of both recursive and corecursive definitions in the case of their simplest forms is obvious; however, proving it is surprisingly hard. There are works trying to give proofs to corecursion theorems at a very general level; the reader being interested in is recommended to study [1]. When defining a standard trace semantics of a programming language, one usually gives a plenty of elementary transition rules to be used for different syntactic constructions. In other words, one has a transition function or, if a nondeterministic semantics is desired, a transition relation. It is trivial to argue by stream coinduction that a transition function gives rise to a unique deterministic semantics, i.e. it determines the unique function from initial states to streams of states such that the first state of the result is the initial state and any following state is obtained from its predecessor by applying the transition function. In the case of non-determinism, the things are similar. The corecursion theorems being proved in this paper are good for defining and checking the soundness of transfinite trace semantics. In this case, one has to define transfinite lists rather than usual streams. While the corecurrent equations of usual kind relate a list with its tail, tail of tail etc. only, the new form of corecurrent equations must enable to relate transfinite lists with their arbitrarily (transfinitely) deep substructures. 3. Ordinals In this section, we give a short introduction to ordinals. The definitions and facts listed here are generally those we need when proving the corecursion theorems. There are plenty of books giving more profound overviews of ordinal theory; two different approaches can be found in [7, 11]. The notion of ordinal is obtained as a generalization of the notion of natural number by adding infinite elements. So we have all the natural numbers 0, 1, 2, . . ., as well as ω and a lot of greater elements, among ordinals. This notion differs from the notion of cardinal in that ordinals can be distinguished by the order of elements in set while cardinals express only the size. Being precise, an ordinal is an isomorphism class of well-ordered sets. (A wellordered set is an ordered set whose every non-empty subset has a least element.) As all the well-orders of a fixed finite set are isomorphic, there exists just one ordinal for any size of a finite set. For countable sets, for instance, there are many (actually uncountably many) in principle different well-orders. The standard order of natural numbers (representing ω) is among them; one of the others is the order of N ∪ {∞} where ∞ is greater than any natural number. There is a natural order 6 on ordinals: o 6 π iff, for any well-ordered sets A and B corresponding to o and π, respectively, A is isomorphic to a cut of B. (A cut of a well-ordered set C is a subset D of it containing all elements of C being less than any given element of D. Cuts are also called downward closed subsets.) Every set of ordinals is well-ordered w.r.t. 6. Clearly 0 is less than any other ordinal. The set of all ordinals less than o is denoted by Oo ; it turns out that (Oo ; 6) is a representative of o.

TRANSFINITE CORECURSION

5

Any ordinal o has a unique immediate successor w.r.t. 6; we denote it o′ . If A is a well-ordered set representing o, a set representing o′ is obtained by adding a new greatest element to A. If an ordinal has an immediate predecessor, i.e. if it is a successor of some ordinal, it is called successor ordinal. Otherwise it is called limit ordinal. However, 0 is often considered as a neither successor nor limit ordinal. For example, all naturals but 0 are successor ordinals while ω — the least infinite ordinal — is a limit ordinal (the least greater than 0). Then there are countably many successor ordinals ω′ , ω′′ etc., followed by the next limit ordinal which of course is followed by countably many successor ordinals. Let o, π be ordinals. Let A, B be some well-ordered sets representing o and π, respectively. An ordinal ̺ is called sum of o and π iff it corresponds to the wellordered set obtained from A and B by finding their disjoint union and considering every element of A less than every element of B. The sum of o and π is denoted by o + π. Obviously o′ = o + 1 for any ordinal o. The operation + is associative and, for any o, o + 0 = 0 + o = o. For ordinals o and π, o 6 π iff o + ̺ = π for some ordinal ̺. If o 6 o′ and π 6 π′ then always o + π 6 o′ + π′ (addition is monotone w.r.t. both its arguments). For example, ω + 1 corresponds to the well-order of N ∪ {∞} introduced before. The ordinal ω + ω corresponds to the limit of the sequence ω, ω′ , ω′′ , . . ., being the least limit ordinal greater than ω. We can construct the infinite sequence ω, ω + ω, ω + ω + ω, . . . of limit ordinals. There exists a limit of this sequence, followed by its successor etc. Ordinals form a “very infinite” biome in the sense that no set of ordinals can ever be complete. If o + π = o + ̺ then always π = ̺. This allows to define subtraction of ordinals. If o 6 π then π − o is the ordinal ̺ such that o + ̺ = π. The following term of selfish ordinal is ours. In [11], these ordinals are called additive principal numbers; we like our shorter term more. D 1. We call an ordinal γ > 0 selfish if γ − o = γ for every o < γ. In other words, γ is selfish iff the well-order of the part remaining when cutting out any initial segment from the well-order Γ representing γ is isomorphic to Γ itself. (A segment is a proper cut.) One more characterization is as follows: an ordinal γ > 0 is selfish iff it cannot be expressed as the sum of two ordinals less than γ (i.e. Oγ is closed under finite sums). For example, ω is selfish. If one cuts out any proper initial part of the well-order representing ω (see next figure), the remaining part represents ω itself. • — • — • — • — • — • — • — • —... The ordinals ω + ω, ω + ω + ω etc. are not selfish because removing the initial ω decreases the number. However, the limit ω2 of this sequence is selfish. Similarly, the limit ω3 of the sequence ω2 , ω2 + ω2 , ω2 + ω2 + ω2 , . . . is selfish. This observation can be continued infinitely. We obtain an infinite sequence ω, ω2 , ω3 , . . . of selfish ordinals. The limit of this sequence is ωω which is also selfish. Now we

6

HÄRMEL NESTRA

can construct the sequence ωω , ωω + ωω , ωω + ωω + ωω , . . . whose limit is ωω+1 , again selfish. Note that 1 is selfish — the least, the only finite and the only successor ordinal among them. It turns out that the notion of selfishness plays a key role in generalizing stream corecursion to transfinite case. The reason is that, for relating a list to its some substructure at depth o, special rules must be added if and only if o is selfish (the steps of other depth can be expressed in terms of steps of selfish depth). P 1. (i) Every ordinal o > 0 is uniquely representable in the form o = α + γ where γ is selfish and α is the least ordinal for which o − α is selfish. (ii) Every ordinal o > 0 is uniquely representable in the form o = λ + β where λ is selfish and β < o. P. (i) If o is selfish, the representation o = 0 + o obviously meets the requirements. Suppose o not being selfish. Then o can be represented as the sum of two ordinals both less than o. For any such representation, both ordinals are non-zero because otherwise the other would equal to o. Let γ be the least non-zero ordinal for which o = α + γ is possible. If γ = π + ̺ for some π and ̺ both less than γ then o = α + (π + ̺) = (α + π) + ̺ contradicts the choice of γ. Thus γ is selfish. Minimize α for this γ. We state that this results in the desired representation. For that, it suffices to prove that o − α, even for varying α, can evaluate to at most one selfish ordinal. Assume o = α1 + γ1 = α2 + γ2 with selfish γ1 , γ2 . W.l.o.g., γ1 6 γ2 . Suppose γ1 < γ2 . It is easy to see that α1 > α2 (supposing α1 6 α2 would give o = α1 + γ1 6 α2 + γ1 < α2 + γ2 = o, a contradiction). So α1 = α2 + ε for some ε. Now α2 + ε + γ1 = o = α2 + γ2 implying ε + γ1 = γ2 , a contradiction with selfishness of γ1 and γ2 . Hence γ1 = γ2 and the result follows. (ii) Let λ be the least ordinal for which o = λ + β for some β < o; then λ > 0. If λ = π + ̺ for some π and ̺ both less than λ then o = (π + ̺) + β = π + (̺ + β). Then ̺ + β = o by the choice of λ which gives a contradiction with the choice of λ. Hence λ is selfish. Now assume o = λ1 + β1 = λ2 + β2 with selfish λ1 , λ2 and β1 < o, β2 < o. W.l.o.g., λ1 6 λ2 . Suppose λ1 < λ2 . Then λ2 = λ1 +δ for some δ; actually, δ = λ2 since λ2 is selfish. Now λ1 + β1 = o = λ1 + λ2 + β2 giving β1 = λ2 + β2 = o which contradicts β1 < o. So λ1 = λ2 implying also β1 = β2 .  Proposition 1 implies that every ordinal can be uniquely expressed as the sum of the elements of a finite non-increasing list of selfish ordinals. This fact can also be deduced from the classic theorem of ordinal theory about representations on base since it can be proven that an ordinal is selfish if and only if it is a power of ω; the representation on base ω is also called Cantor normal form [8, 11].

7

TRANSFINITE CORECURSION

In the rest, the representation o = α + γ where γ being selfish and α minimized (the representation of Prop. 1(i)) is called the canonical representation of o and the expression α + γ is sometimes called canonical sum. The following lemma is used many times in our proofs of the next section. L 1. Let o be an ordinal with canonical representation o = α + γ. Let λ be any selfish ordinal. If α > 0 or λ > γ, the canonical representation of λ + o is (λ + α) + γ; otherwise, the canonical representation is 0 + γ. P. For the “if” part of the lemma, assume α > 0 or λ > γ holding. Take an arbitrary β such that λ + o = β + γ. Show β > λ by contradiction. If β < λ then λ = β + λ leading to β + λ + α + γ = β + γ, thus also λ + α + γ = γ and λ + α < γ. In the case α > 0, we have α > γ (otherwise α + γ = γ = 0 + γ contradicting the minimality of α), a contradiction with λ + α < γ. The case λ > γ contradicts the same inequality. Let β = λ + ε. Then λ + α + γ = λ + ε + γ and thus α + γ = ε + γ. As the lhs is canonical, this implies α 6 ε. So λ + α 6 λ + ε = β. Consequently, (λ + α) + γ is the canonical representation of λ + o. For the “otherwise” case, assume α = 0 and λ < γ. Then λ + α + γ = λ + γ = γ = 0 + γ where the last sum is canonical.  4. Transfinite corecursion theorems In Subsect. 4.1, transfinite lists and some basic operations related to them are defined and their properties are discussed. Subsection 4.2 proves a corecursion theorem applicable to deterministic semantics, Subsect. 4.3 proves its counterpart for nondeterministic semantics. Subsection 4.4 shows some connections between the two variants of transfinite corecursion. 4.1 Transfinite lists Transfinite lists over A are functions which take ordinals into A and whose domain is downward closed (i.e. the domain is a cut). So a transfinite list over A is a function l : Oo → A for some o; in this case, o is called length of l and denoted by |l|. Denote the empty list — the list of length 0 — by nil. For a transfinite list l and α < |l|, l(α) (or lα ) is the αth component of l. For simplicity, we allow writing l(α) also for α > |l| and count l(α) = ⊥ in this case where ⊥ is a special value standing for any type of undefinedness and belonging to no set dealt with here unless mentioned explicitly. We also denote head l = l(0). Let ∝ be a fixed selfish ordinal and let TList A denote the set of all transfinite lists over A of length not exceeding ∝. Let STList A denote the subset of TList A consisting of lists by which next elements are defined, i.e. lists of length being both selfish and less than ∝ (lists of length ∝ do not have next elements). So [ [ (Oo → A) , STList A = (Oγ → A) . TList A = o6∝

γ |l| or l is not a list (because of its domain not being a cut) then take o l = ⊥ = drop o l. All operations considered in this paper are strict, i.e. a subexpression with value ⊥ turns the value of the whole expression to ⊥. Hence the implication ∀o < ∝ (l(o) = k(o)) ⇒ l = k fails if l, k are nil, ⊥ in some order (for l, k ∈ TList A, this implication holds since ⊥ < TList A). L 2. Let l be any transfinite list. (i) For ordinals o and π, l(o + π) = (drop o l)(π). (ii) For ordinal o, l(o) = head(drop o l). (iii) For ordinals o and π, drop(o + π) l = drop π(drop o l). (iv) For ordinals o and π, take π(drop o l) = drop o(take(o + π) l). (v) For ordinals o and π, if π 6 o 6 |l| then take π l = take π(take o l). P. (i) Trivial because if o + π > |l| then l(o + π) = ⊥ = (drop o l)(π). (ii) We have head(drop o l) = (drop o l)(0) = l(o + 0) = l(o). (iii) For any ordinal α, (drop π(drop o l))(α) = (drop o l)(π + α) = l(o + π + α) = (drop(o + π) l)(α) . (iv) If o + π > |l|, both sides of the desired equality are ⊥. Otherwise, both are defined giving, for any ordinal α, (drop o(take(o + π) l))(α) = (take(o + π) l)(o + α)   = l(o + α) if o + α < o + π otherwise  ⊥ (drop o l)(α) if α < π = ⊥ otherwise = (take π(drop o l))(α) .

TRANSFINITE CORECURSION

9

(v) For any ordinal α,   (take π(take o l))(α) = (take o l)(α) if α < π otherwise  ⊥ l(α) if α < π and α o then l(α) = (drop o l)(α − o) = (drop o k)(α − o) = k(α) . Hence l = k. (ii) Let α be any ordinal. If α < |l| then (take |l|(l + + k))(α) = (l + + k)(α) = l(α) , otherwise both sides of the desired equality are ⊥. If α < |k| then (drop |l|(l + + k))(α) = (l + + k)(|l| + α) = k(|l| + α − |l|) = k(α) , otherwise both sides of the desired equality are ⊥.  4.2 Functions with transfinite lists as values D 2. Let X, A be sets. Assume ϕ : X → 1 + A and ψ : STList A → X. We say that a function f : X → TList A is corecursive on ϕ and ψ iff the following two corecursion conditions hold: (1) if ϕ(x) = a ∈ A then head( f (x)) = a, and if ϕ(x) ∈ 1 then f (x) = nil; (2) if | f (x)| > λ and λ < ∝ is selfish then drop λ( f (x)) = f (ψ(take λ( f (x)))) .

10

HÄRMEL NESTRA

Here, ψ plays the role of “limit operator” taking transfinite lists of selfish length to elements of X. As 1 is one particular selfish ordinal, the corecursion handles finite and infinite steps uniformly. Taking λ = 1, one gets conditions similar to stream corecursion in the sense that the result list is defined in two parts: one determines its head and the other, corecursively, its tail. T 1. Let X, A be sets. Let ϕ : X → 1 + A and ψ : STList A → X. Assume ψ(l) = ψ(drop λ l) for all selfish ordinals λ, γ with λ < γ < ∝ and transfinite lists l ∈ (Oγ → A). Then there is a unique function f : X → TList A being corecursive on ϕ and ψ. P. Existence. To simplify things a bit, assume w.l.o.g. that 1 + A = A ∪ {⊥}. For each x ∈ X, define h(x) : O∝ → A ∪ {⊥} with the equations h(x)(0) = ϕ(x), h(x)(o) = ϕ(ψ(take γ(drop α(h(x))))) where 0 < o < ∝ and o = α + γ is canonical. This is a correct definition by transfinite recursion as the rhs uses the values of function h(x) on arguments less than α + γ = o only. We show that h is corecursive on ϕ and ψ. First, make clear that h(x) ∈ TList A for every x. Let h(x)(π) = ⊥ and π < o. Since o > 0, there is a canonical representation o = α + γ. As take γ(drop α(h(x))) = drop α(take o(h(x))) = ⊥ , also h(x)(o) = ⊥ by the definition of h. Thus the domain of h(x) is a cut. Next, we have head(h(x)) = h(x)(0) = ϕ(x); thereby, if ϕ(x) < A then h(x)(0) = ⊥ implying h(x) = nil. Thus corecursion condition 1 holds. It remains to prove corecursion condition 2. Take x and λ < ∝ selfish such that |h(x)| > λ. We are going to show by transfinite induction that h(x)(λ + o) = h(ψ(take λ(h(x))))(o) for every ordinal o. Assume the equality being valid for all ordinals π < o, so take o(drop λ(h(x))) = take o(h(ψ(take λ(h(x))))). If o = 0, we get h(x)(λ + 0) = h(x)(0 + λ) = ϕ(ψ(take λ(drop 0(h(x))))) = ϕ(ψ(take λ(h(x)))) = h(ψ(take λ(h(x))))(0) . If o > 0, let o = α + γ be the canonical representation and consider two cases. 1. α > 0 or λ > γ. Using the induction hypothesis, we get take γ(drop(λ + α)(h(x))) = = = =

take γ(drop α(drop λ(h(x)))) drop α(take o(drop λ(h(x)))) drop α(take o(h(ψ(take λ(h(x)))))) take γ(drop α(h(ψ(take λ(h(x)))))) .

TRANSFINITE CORECURSION

11

By Lemma 1, (λ + α) + γ is the canonical representation of λ + o. Thus h(x)(λ + o) = ϕ(ψ(take γ(drop(λ + α)(h(x))))) = ϕ(ψ(take γ(drop α(h(ψ(take λ(h(x)))))))) = h(ψ(take λ(h(x))))(o) . 2. α = 0 and λ < γ. Using the special restriction on ψ and the induction hypothesis, we get ψ(take γ(drop 0(h(x)))) = = = = = =

ψ(take γ(h(x))) ψ(drop λ(take γ(h(x)))) ψ(drop λ(take(λ + γ)(h(x)))) ψ(take γ(drop λ(h(x)))) ψ(take γ(h(ψ(take λ(h(x)))))) ψ(take γ(drop 0(h(ψ(take λ(h(x))))))) .

Note that 0 + γ is the canonical representation of both o and λ + o. Thus h(x)(λ + o) = ϕ(ψ(take γ(drop 0(h(x))))) = ϕ(ψ(take γ(drop 0(h(ψ(take λ(h(x)))))))) = h(ψ(take λ(h(x))))(o) . This completes the proof of existence. Uniqueness. Suppose both f , g being corecursive on ϕ and ψ. We are going to prove that ∀x ∈ X ( f (x)(o) = g(x)(o)) (1) for every o < ∝. Argue by transfinite induction. For o = 0, one obtains f (x)(0) = head( f (x)) = ϕ(x) = head(g(x)) = g(x)(0) . Consider now any non-zero o < ∝ and assume Eq. (1) for all π < o. Take o = λ + β with λ selfish and β < o. The induction hypothesis implies | f (x)| > λ ⇐⇒ |g(x)| > λ, as well as take λ( f (x)) = take λ(g(x)), as well as f (y)(β) = g(y)(β) for every y ∈ X. Using these, we get f (x)(o) = f (x)(λ + β) = (drop λ( f (x)))(β) = ( f (ψ(take λ( f (x)))))(β) = ( f (ψ(take λ(g(x)))))(β) = (g(ψ(take λ(g(x)))))(β) = (drop λ(g(x)))(β) = g(x)(λ + β) = g(x)(o) .  The condition ψ(l) = ψ(drop λ l) is used in the proof at one place in the existence part only. We finish this subsection with showing that, without this restriction on ψ, the theorem would break. O 1. Let X, A be sets. Let ϕ : X → 1 + A and ψ : STList A → X. Assume that f : X → TList A is corecursive on ϕ and ψ. Let λ, γ be selfish ordinals less than ∝ and take x ∈ X.

12

HÄRMEL NESTRA

(i) Then drop γ(drop λ( f (x))) = f (ψ(take γ(drop λ( f (x))))) . (ii) Moreover, if λ < γ then f (ψ(take γ( f (x)))) = f (ψ(drop λ(take γ( f (x))))) . P. (i) If | f (x)| > λ + γ then drop γ(drop λ( f (x))) = drop γ( f (ψ(take λ( f (x))))) = f (ψ(take γ( f (ψ(take λ( f (x))))))) = f (ψ(take γ(drop λ( f (x))))) . If | f (x)| < λ + γ then both sides of the equality are ⊥. (ii) Note that λ + γ = γ since γ is selfish. If | f (x)| > γ then f (ψ(take γ( f (x)))) = = = = =

drop γ( f (x)) = drop(λ + γ)( f (x)) drop γ(drop λ( f (x))) f (ψ(take γ(drop λ( f (x))))) f (ψ(drop λ(take(λ + γ)( f (x))))) f (ψ(drop λ(take γ( f (x))))) .

If | f (x)| < γ then both sides of the equality are ⊥.  Take X = A = {0, 1}, ϕ(x) = x for both x ∈ X, and   ψ(l) = 1 if |l| = 1 or ∀o < |l| (l(o) = 1) . 0 otherwise Suppose that f is corecursive on ϕ and ψ. It is easy to see that take ω( f (0)) = 0 : 1 : 1 : 1 : . . . . Thus the equality stated by Observation 1(ii) is broken: head( f (ψ(0 : 1 : 1 : 1 : . . .))) = , = =

head( f (0)) = ϕ(0) = 0 1 = ϕ(1) = head( f (1)) head( f (ψ(1 : 1 : 1 : . . .))) head( f (ψ(drop 1(0 : 1 : 1 : 1 : . . .)))) .

13

TRANSFINITE CORECURSION

4.3 Functions with sets of transfinite lists as values We start with providing a new definition of corecursion which is the counterpart of Definition 2 in the case where functions with sets of transfinite lists as values are considered. By ℘S , denote the set of all subsets of S . Moreover, we use the set comprehension syntax of the well-known Z notation [12]. D 3. Let X, A be sets. Take ϕ : X → 1 + A and Ψ : STList A → ℘X. We say that a function F : X → ℘(TList A) is corecursive on ϕ and Ψ iff the following two corecursion conditions hold: (1) if ϕ(x) = a ∈ A then, for every l ∈ F(x), head l = a, and if ϕ(x) ∈ 1 then F(x) = {nil}; (2) for any selfish λ < ∝ and transfinite list l ∈ (Oλ → A) such that there exists an m ∈ F(x) for which take λ m = l, [  m ∈ F(x) | take λ m = l • drop λ m = F(z) . z∈Ψ (l)

L 4. Let X, A be sets. Let ϕ : X → 1 + A and Ψ : STList A → ℘X. Assume that F : X → ℘(TList A) is corecursive on ϕ and Ψ . Suppose o being an ordinal with canonical representation α + γ. Let x ∈ X and l ∈ TList A, |l| = o such that there exists an m ∈ F(x) such that take o m = l. Then [  m ∈ F(x) | take o m = l • drop o m ⊆ F(z) . z∈Ψ (drop α l)

P. If α = 0, the claim follows directly from the premises. So suppose α > 0. Proceed by induction on o. As γ > 0, we have α < o, so the induction hypothesis holds for α. Let β + δ be the canonical representation of α. Then, for arbitrary k ∈ TList A,  k ∈ m ∈ F(x) | take o m = l • drop o m ⇐⇒ ∃m ∈ F(x) (take o m = l ∧ drop o m = k) ⇐⇒ ∃m ∈ F(x) ( take α(take o m) = take α l ∧ drop α(take o m) = drop α l ∧ drop γ(drop α m) = k ) ⇐⇒ ∃m ∈ F(x) ( take α m = take α l ∧ take γ(drop α m) = drop α l ∧ drop γ(drop α m) = k )  ⇐⇒ ∃d ∈ m ∈ F(x) | take α m = take α l • drop α m

14

HÄRMEL NESTRA

(take γ d = drop α l ∧ drop γ d = k) [ =⇒ ∃d ∈ F(z) z∈Ψ (drop β(take α l))

(take γ d = drop α l ∧ drop γ d = k) ⇐⇒ ∃z ∈ Ψ (drop β(take α l)) ∃d ∈ F(z) (take γ d = drop α l ∧ drop γ d = k) ⇐⇒ ∃z ∈ Ψ (drop β(take α l))  (k ∈ d ∈ F(z) | take γ d = drop α l • drop γ d ) [ F(w)) =⇒ ∃z ∈ Ψ (drop β(take α l)) (k ∈ w∈Ψ (drop α l)

⇐⇒ k ∈

[

F(w) .

w∈Ψ (drop α l)

This completes the proof.  Theorem 2 claims the existence of a largest function meeting certain conditions rather than a unique function like it was in Theorem 1. The order on functions is defined componentwise basing on the order of set inclusion. T 2. Let X, A be sets. Let ϕ : X → 1 + A and Ψ : STList A → ℘X. Assume Ψ (l) = Ψ (drop λ l) for all selfish ordinals λ, γ with λ < γ < ∝ and transfinite lists l ∈ (Oγ → A). Then there is a largest function F : X → ℘(TList A) being corecursive on ϕ and Ψ . P. Let function H : X → ℘(TList A) be defined with ( ) {nil} if ϕ(x) < A H(x) =  l ∈ TList A | head l = a ∧ H(l) • l if ϕ(x) = a ∈ A

where H(l) means that

for all o < |l| with canonical representation o = α + γ, ∃z ∈ Ψ (drop α(take o l)) (ϕ(z) = l(o)) and, with canonical representation |l| = α + γ, ∃z ∈ Ψ (drop α l) (ϕ(z) < A) . We are going to show that H is the largest function being corecursive on ϕ and Ψ . The proof is divided into many cases and subcases. 1. Show that H is corecursive on ϕ and Ψ . 1.1. Corecursion condition 1. If ϕ(x) = a ∈ A and l ∈ H(x) then head l = a by definition of H. If ϕ(x) < A then H(x) = {nil} by definition of H. 1.2. Corecursion condition 2.

TRANSFINITE CORECURSION

15

Let x ∈ X. Fix a selfish ordinal λ < ∝ and a transfinite list l ∈ (Oλ → A) such that take λ m = l for some m ∈ H(x). Then H(x) , ∅, hence ϕ(x) = a ∈ A. Take an arbitrary k ∈ TList A. We are going to show that  k ∈ m ∈ H(x) | take λ m = l • drop λ m ⇐⇒ ∃z ∈ Ψ (l) (k ∈ H(z)) .

1.2.a. The case |k| = 0, i.e. k = nil. 1.2.a.(⊆). Assume nil = drop λ m for m ∈ H(x) with take λ m = l. Then l = m ∈ H(x). By H(l), we get ϕ(z) < A for some z ∈ Ψ (drop 0 l) = Ψ (l). Then H(z) = {nil} ∋ k for the same z. 1.2.a.(⊇). Assume nil ∈ H(z) for some z ∈ Ψ (l). Then ϕ(z) < A. Choose m ∈ H(x) such that take λ m = l. Then head l = head m = a by definition of H. Take an arbitrary ordinal o < |l| with canonical representation α + γ. As m ∈ H(x) and o < |m|, there exists a w ∈ Ψ (drop α(take o m)) such that ϕ(w) = m(o). As m(o) = l(o) and take o m = take o l, we have shown the first part of H(l). The other part follows from ϕ(z) < A and z ∈ Ψ (l). 1.2.b. The case |k| > 0. 1.2.b.(⊆). Fix m ∈ H(x) such that l = take λ m and k = drop λ m. Then λ < |m| with canonical representation λ = 0 + λ, so we have ϕ(z) = m(λ) for some z ∈ Ψ (take λ m) = Ψ (l). It suffices to show k ∈ H(z). As ϕ(z) = m(λ) ∈ A, we must show head k = m(λ) and H(k). The former comes from head k = (drop λ m)(0) = m(λ + 0). We now prove H(k). 1.2.b.(⊆).1. Take o < |k| with o = α + γ canonical. Then Ψ (drop α(take o k)) = = = =

Ψ (take γ(drop α k)) Ψ (take γ(drop α(drop λ m))) Ψ (take γ(drop(λ + α) m)) Ψ (drop(λ + α)(take(λ + o) m)) .

Note that λ + o < λ + |k| = |m|. If α > 0 or λ > γ then, using H(m), we get k(o) = m(λ + o) = ϕ(w) for some w ∈ Ψ (drop(λ + α)(take(λ + o) m)) = Ψ (drop α(take o k)). If α = 0 and λ < γ then, using H(m) together with the restriction imposed on Ψ , we get k(o) = k(γ) = m(γ) = ϕ(w) for some w ∈ Ψ (take γ m) = Ψ (take γ k). The first clause of H(k) follows. 1.2.b.(⊆).2. Take |k| = α + γ canonical. Then Ψ (drop α k) = Ψ (drop α(drop λ m)) = Ψ (drop(λ + α)m) . Note that λ + |k| = |m|. If α > 0 or λ > γ then, using H(m), we get ϕ(w) < A for some w ∈ Ψ (drop(λ + α) m) = Ψ (drop α k). If α = 0 and λ < γ then, using H(m) together with the restriction imposed on Ψ , we get ϕ(w) < A for some w ∈ Ψ (m) = Ψ (k). The second clause of H(k) follows. 1.2.b.(⊇). Assume k ∈ H(z) for some z ∈ Ψ (l). Fix m ∈ H(x) such that take λ m = l. It suffices to show l + + k ∈ H(x). As ϕ(x) = a ∈ A, we have to check head(l + + k) = a and H(l + + k). The former comes from head(l + + k) = head l = head m = a. We now prove H(l + + k).

16

HÄRMEL NESTRA

1.2.b.(⊇).1. Let o < |l + + k| = |l| + |k| with canonical representation o = β + δ. If o < λ then, as m ∈ H(x), we have ϕ(w) = m(o) = l(o) = (l + + k)(o) for w ∈ Ψ (drop β(take o m)) = Ψ (drop β(take o l)) = Ψ (drop β(take o(l + + k))). Assume o > λ now; let o = λ + π. If π = 0 then, as k ∈ H(z), we have ϕ(z) = k(0) = (l + + k)(o). In this case, β = 0 and o = λ, so Ψ (drop β(take o(l + + k))) = Ψ (l) ∋ z . It remains to consider the case π > 0. Let π = α + γ be canonical. If α > 0 or λ > γ then β = λ + α and δ = γ. Note that Ψ (drop α(take π k)) = = = =

Ψ (drop α(take π(drop λ(l + + k)))) Ψ (drop α(drop λ(take o(l + + k)))) Ψ (drop(λ + α)(take o(l + + k))) Ψ (drop β(take o(l + + k))) .

Thus we have ϕ(w) = k(π) = (l + + k)(o) for w ∈ Ψ (drop β(take o(l + + k))). If α = 0 and λ < γ then β = 0 and δ = γ. Note that Ψ (take γ k) = Ψ (take γ(drop λ(l + + k))) = Ψ (drop λ(take γ(l + + k))) = Ψ (take γ(l + + k)) = Ψ (take o(l + + k)) . Thus we have ϕ(w) = k(π) = k(γ) = (l + + k)(γ) = (l + + k)(o) for some w ∈ Ψ (take o(l + + k)). In all cases, we have proven the first condition of H(l + + k). 1.2.b.(⊇).2. Let |k| = α + γ be canonical. If α > 0 or λ > γ then, since k ∈ H(z), we have ϕ(w) < A for some w ∈ Ψ (drop α k) = Ψ (drop(λ + α)(l + + k)). If α = 0 and λ < γ then analogously we have ϕ(w) < A for some w ∈ Ψ (k) = Ψ (drop λ(l + + k)) = Ψ (l + + k). In both cases, the second clause of H(l + + k) follows. 2. Show that if some F is corecursive on ϕ and Ψ then F ⊑ H (i.e. F(x) ⊆ H(x) for every x ∈ X ). If ϕ(x) < A then F(x) = {nil} = H(x). Let now ϕ(x) = a ∈ A and take l ∈ F(x). Then head l = a by corecursion condition 1. Take o 6 |l| with canonical representation α + γ. By Lemma 4, [  m ∈ F(x) | take o m = take o l • drop o m ⊆ F(z) . z∈Ψ (drop α(take o l))

Thus drop o l ∈ F(z) for some z ∈ Ψ (drop α(take o l)). If o < |l| then obviously drop o l , nil. Thus F(z) , {nil} implying ϕ(z) = b ∈ A. Now head(drop o l) = b, i.e. ϕ(z) = l(o). If o = |l|, we get z ∈ Ψ (drop α l) and nil ∈ F(z). Then ϕ(z) ∈ A would contradict F satisfying corecursion condition 1, hence ϕ(z) < A. Altogether, this gives H(l). Consequently, l ∈ H(x).  To finish this subsection, we show that the function H constructed in the proof of Theorem 2 is not the only one being corecursive on ϕ and Ψ .

17

TRANSFINITE CORECURSION

Note that the corecursion conditions hold trivially whenever F(x) =



{nil} ∅

 if ϕ(x) < A otherwise

for every x ∈ X. Let X = {0, 1}, A = {0} and ϕ(0) = 0, ϕ(1) < A. Let Ψ (l) = X for every l. Then F(0) = ∅ while H(0) ∋ 0 : nil. 4.4 Connections between the two corecursions The corecursion theorems (Theorems 1 and 2) were proven independently on each other. Nevertheless, the two corecursions are analogous. This subsection points out the relation between them. The following result states that using our corecursion of the second type for defining one-element sets is equivalent to the corecursion of the first type. T 3. Let X, A be sets. Take ϕ : X → 1 + A, as well as ψ : STList A → X and Ψ : STList A → ℘X such that Ψ (l) = ψ(l) for every l ∈ STList A. Assume that f : X → TList A is corecursive on ϕ and ψ. Then F(x) = f (x) is the largest function corecursive on ϕ and Ψ . P. We show first that F is corecursive on ϕ and Ψ . Take an arbitrary x ∈ X. If ϕ(x) ∈ A then, for every  l ∈ F(x), obviously head l = head( f (x)) = ϕ(x). If ϕ(x) < A then F(x) = f (x) = {nil}. Take now a selfish λ and a transfinite list l ∈ (Oλ → A) such that take λ m = l for some m ∈ F(x). This obviously implies take λ( f (x)) = l and 

 m ∈ F(x) | take λ m = l • drop λ m = drop λ( f (x))   = f (ψ(take λ( f (x)))) = f (ψ(l)) [ = F(ψ(l)) = F(z) . z∈Ψ (l)

So F is indeed corecursive on ϕ and Ψ . Let now G : X → ℘(TList A) be any function corecursive on ϕ and Ψ . We show by transfinite induction on o that ∀x ∈ X ∀l ∈ G(x) ( f (x)(o) = l(o))

(2)

for every ordinal o < ∝. Firstly, we obtain 

f (x)(0) = head( f (x)) = ϕ(x) ⊥

 if ϕ(x) ∈ A = head l = l(0) otherwise

for every x ∈ X and l ∈ G(x). Consider now any non-zero o < ∝ and assume Eq. (2) holding for all π < o. Take o = γ + β with γ selfish and β < o. Fix x ∈ X and l ∈ G(x) arbitrarily. The induction hypothesis implies |l| > γ ⇐⇒ | f (x)| > γ,

18

HÄRMEL NESTRA

as well as take γ( f (x)) = take γ l, as well as f (z)(β) = k(β) for every z ∈ X and k ∈ G(z). By corecursiveness of G,  m ∈ G(x) | take γ m = take γ l • drop γ m =

[

G(z)

z∈Ψ (take γ l)

= G(ψ(take γ l)) . So drop γ l ∈ G(ψ(take γ l)). Hence f (x)(o) = f (x)(γ + β) = (drop γ( f (x)))(β) = ( f (ψ(take γ( f (x)))))(β) = ( f (ψ(take γ l)))(β) = (drop γ l)(β) = l(γ + β) = l(o) .  This shows that F(x) = f (x) ⊇ G(x) for every x ∈ X, i.e. G ⊑ F. 

There is also a result of more general kind relating the two corecursions.

L 5. Let X, A be sets. Take ϕ : X → 1 + A, as well as Ψ1 , Ψ2 : STList A → X such that Ψ1 ⊑ Ψ2 (i.e. Ψ1 (l) ⊆ Ψ2 (l) for every l ∈ STList A). Assume both Ψ1 (l) = Ψ1 (drop λ l) and Ψ2 (l) = Ψ2 (drop λ l) for all selfish ordinals λ, γ with λ < γ < ∝ and transfinite lists l ∈ (Oγ → A). Let F1 : X → ℘(TList A) be the largest function corecursive on ϕ and Ψ1 , and F2 : X → ℘(TList A) be the largest function corecursive on ϕ and Ψ2 . Then F1 ⊑ F2 . P. Let H1 and H2 denote the condition H from the proof of Theorem 2 defined for Ψ1 and Ψ2 , respectively. Let H1 and H2 be the corresponding functions H defined in the same proof. The proof shows that F1 = H1 and F2 = H2 . So it suffices to check H1 (x) ⊆ H2 (x) for all x ∈ X which is an easy case study by the definition of H using the assumption Ψ1 ⊑ Ψ2 .  T 4. Let X, A be sets. Take ϕ : X → 1 + A, as well as ψ : STList A → X and Ψ : STList A → ℘X such that ψ(l) ∈ Ψ (l) for every l ∈ STList A. Assume both ψ(l) = ψ(drop λ l) and Ψ (l) = Ψ (drop λ l) for all selfish ordinals λ, γ with λ < γ < ∝ and transfinite lists l ∈ (Oγ → A). Let f : X → TList A be the function corecursive on ϕ and ψ and F : X → ℘(TList A) be the largest function corecursive on ϕ and Ψ . Then f (x) ∈ F(x) for every x ∈ X.  ′ P. 3, F ′ (x) =  Define Ψ (l) = ψ(l) for all l ∈ STList A.′ By Theorem ′ function corecursive on ϕ and Ψ . Since Ψ (l) = ψ(l) =  f (x) is the largest ψ(drop λ l) = Ψ ′ (drop λ l) for all selfish ordinals λ, γ with λ < γ < ∝ and lists l ∈ (Oλ → A), Lemma 5 applies and gives the desired result.  Theorem 4 made all the assumptions which are needed to prove any of the two corecursion theorems. Contrasting to it, Theorem 3 assumes only the corecursivness of f on ϕ and ψ, no further assumptions except the special shape of Ψ are needed.

TRANSFINITE CORECURSION

19

5. Discussion We would like to discuss a few questions and concerns about our transfinite corecursion which can easily arise. 1. Is it corecursion? Usual corecursion is called corecursion because it is dual to recursion. We have not found such kind of connection between transfinite recursion and transfinite corecursion. The name “transfinite corecursion” has been chosen solely by the analogy with usual corecursion where one writes equations relating a (possibly infinite) structure with its substructures which are all expressed as values of the same function. 2. Why corecursion? Are semantics really defined by corecursion? One can notice that the idea behind the proofs of both transfinite corecursion theorems is to construct the specified function in another way, namely recursively. And, of course, when one is going to define real transfinite semantics, one does not write down the corecursive equation again and again. One of the consequences of the theorems is that it always suffices to provide just ϕ and ψ satisfying the conditions. Also finitary semantics are normally defined by transition function without giving any equations. As there is no need to write equations, one could prove the sufficiency of providing of such ϕ and ψ in some other way being simpler than proving these corecursion theorems. However, knowing the semantics satisfying the corecurrent equations is useful as the corecurrent equations relate the whole transfinite list to its substructures, so stating the important property that the possible results of the computation starting from a given state are independent on the computation performed before reaching this state. Recursive equations express one single state in terms of its predecessors, not implying this invariant explicitly. 3. Isn’t it too restrictive? At first sight, our corecursion theorems seem relatively straitening in the sense that ϕ and ψ (or Ψ ) together contain all the information needed for finding all possible continuations of any transfinite list starting from its any single component. This means that any single component of a transfinite list constructed by some fixed ϕ and ψ determines all the following components uniquely. It is not so in the case of usual corecursive definitions of streams: for example, the tail of a continued fraction is not determined by the head of it. We think that this restriction is natural and even desirable in the case of semantics (see previous item of this discussion list). Moreover, it is easy to see that this restriction is not fundamental as, if a “more general” kind of transfinite list is needed, one can tie the “additional information” together with “real elements” into pairs and define transfinite lists of these pairs. 6. An application 6.1 The language While with a standard semantics Consider the following simple imperative programming language While. Denote by Num, TVal and Var the sets of all numerals, boolean constants (true and

20

HÄRMEL NESTRA

false) and variables of the language, respectively. The abstract syntax of While is described as follows: AExp → | BExp → Stmt → | | | |

Num | Var - AExp | AExp + AExp | AExp * AExp TVal | AExp = AExp | AExp < AExp Var := AExp if BExp then Stmt else Stmt while BExp do Stmt Stmt ; Stmt

The language has arithmetic expressions (AExp), boolean expressions (BExp) and statements (Stmt) which are also called programs. For simplicity, we do not allow procedures. The “followed by” operator ; is assumed to be associative: for instance, the programs z := x ; (x := y ; y := z) and

(z := x ; x := y) ; y := z

are syntactically equal. Furthermore, the empty statement is assumed to be the unit of ; at syntactic level (so x := 0 ; is the same program as x := 0). We first consider a standard trace semantics of While also called structural operational semantics. The meaning of each program is a function whose values are sequences (streams or finite lists) of configurations. A configuration is a pair of a program and a state. The former expresses the rest of the computation and it is also called program point; a state is an evaluation of variables. So we have the semantic categories State = Var → Z and Conf = Stmt × State. Let T = {tt, ff}; suppose N : Num → N and T : TVal → T mapping the numerals and the boolean constants, respectively, to their values. Define the expression evaluation functions A : AExp → State → Z and B : BExp → State → T as follows:   N(a)      s(a)    −A(c) A(a)(s) =      A(c1 ) + A(c2 )     A(c ) · A(c ) 1 2   T (b)    A(c B(b)(s) =  1 ) = A(c2 )    A(c ) < A(c ) 1

2

if a ∈ Num if a ∈ Var if a = - c if a = c1 + if a = c1 * if b ∈ TVal if b = c1 = if b = c1
o . t(x) = ⊤ if there is no such o and a The limit program lim S is going to be used as the program yet to be executed when the body of the loop has been processed ω times. Definition 4(i) ensures that, after executing the body of a loop for ω times, we reach a configuration where we have “overcome” the loop. (Under the conditions of Definition 4(i), while b do T is the outermost loop whose body is executed an infinite number of times during the γ steps; if the number were larger than ω, the loop would have been abandoned already before with achieving a shorter program.) A loop while b do T in this semantics means “while b keeps holding, do T , but never more than ω times”. In the limit state lim s, a variable x has value a if the transfinite list of the values of x during the transfinite computation represented by s stabilizes to a; if the list does not stabilize then the value of x is ambiguous (⊤). Denote by Conf − the set of all final configurations, i.e. configurations where no computation step is possible (in While with the currently observed transition rules, Conf − consists of precisely the configurations with empty program component), and define Conf + = Conf \ Conf − . For every c ∈ Conf + , let next c denote the configuration obtained from c by applying the suitable transition rule (the transition rules are deterministic). Assume 1 + Conf = Conf ∪ {⊥}. Now define ψ1 : STList Conf → 1 + Conf as follows: ψ1 (hS o | so i : o < γ)  ⊥    =   nexthS 0 | s0 i hlim S | lim si

if hS 0 | s0 i ∈ Conf − if hS 0 | s0 i ∈ Conf +



   if γ = 1  .    otherwise

By Theorem 1, there exists a function f : 1 + Conf → TList Conf being corecursive on id : 1+Conf → 1+Conf and ψ1 . The desired transfinite semantics is obtained by currying f , i.e. S(P)(s) = f (hP | si) for every program P and initial state s. Being strict, applying the theorem needs fixing an ordinal ∝ which is the upper bound of lengths of all transfinite lists obtained as values of the corecursive functions. We can choose ∝ arbitrarily; [4] proves that taking ∝ = ωω+1 ensures any program being executed to the end of its code and it is easy to find analogous proof also for ωω . In this semantics, of the program in the last example of Section 1 n the execution o with initial state x → 1 goes as follows: n o n o n o h0 | x → 1 i → h0 | x → 1 i → h0 | x → 1 i → .|{z} ..... ω steps

23

TRANSFINITE CORECURSION

→ h1 |

n

o n o x → 1 i → h2 | x → 0 i .

So it reaches program point 2 once just like the execution of the slice on the same initial state and computes the same value (0) for x. The way in which we defined the limit state into which the computation falls after an infinite number of steps coincides with the one in [4]. It turns out that this is not a completely satisfactory approach if the aim is to describe slicing. Consider one more example. while 0 0 < i do ( 1 i := 1 ; 2 i := 2 ); 3

while 2i

−→

00

< i do (

:= 2

); 3

 The second program is a slice of the first w.r.t. criterion (3, i) . However in the transfinite semantics defined above, the value of i at 3 is ⊤ in the first program but 2 in the second. Hence the concept of slicing is still not met. Another way to compute limit states helps. The idea is in noting that the intuitive way of understanding slicing, followed also by the standard slicing algorithms, assumes the statements of the program being passed through in one particular order, namely in the order which is used when the program terminates. In the last example, this means the loop being abandoned only at program point 0, but not, for example, at 2 where i has a different value. This principle must be met also by transfinite semantics. Define ψ2 (hS o | so i : o < γ)   ⊥ if hS 0 | s0 i ∈ Conf −    = nexthS 0 | s0 i if hS 0 | s0 i ∈ Conf +   hlim S | lim(coll(so : o < γ ∧ S o = A))i

   if γ = 1     otherwise

where A denotes the shortest program occurring infinitely many times in S and coll collapses an ordinal-indexed family to a transfinite list, keeping the order of components unchanged (it is necessary since, in (so : o < γ ∧ S o = A), there are intermediate ordinals o which are not used, so it is not a transfinite list formally). Using the transfinite semantics relying on ψ2 instead of ψ1 , both programs in the last example compute 2 as the value of i at program point 3. 7. Conclusion, further and related work Our paper introduces a generalization of corecurrent ways to define stream-valued functions to ways to define functions whose values are transfinite lists. It also studies analogous ways to define functions whose values are sets of transfinite lists. The results can be used in defining transfinite trace semantics of programming languages. The motivation came from [4] where transfinite semantics are studied, claiming they are forming a proper framework for describing program slicing. Our last

24

HÄRMEL NESTRA

observation in Subsect. 6.2 indicates that their transfinite semantics also give rise to problems. One of our aims is to prove correctness of standard slicing algorithms w.r.t. some transfinite trace semantics generalizing the standard semantics. It seems credible that it is possible to do this at least for simple languages having neither procedures nor unstructured control flow like While. The next interesting problem would be to find ways to do the same for more complex programming languages having unstructured control flow or recursive procedures. The first difficult thing one faces with is the choice of transfinite semantics. With recursive procedures, one can obtain a new kind of loops due to infinitely deep recursion. There is no obvious way to define limits of such infinite computations. Besides transfinite semantics, there are some more approaches to handle semantic anomaly, see [9]. A fundamental theoretical study of program slicing in context of standard semantics can be found in [10]. References [1] B, J.  M, L. 1996. Vicious Circles. CSLI Lecture Notes No 60. CSLI Publications. [2] B, D. W.  G, K. B. 1996. Program Slicing. Advances in Computers 43, 1–50. [3] C, P. 1997. Constructive Design of a Hierarchy of Semantics of a Transition System by Abstract Interpretation. Electronic Notes in Theoretical Computer Science 6, 25 pp. [4] G, R.  M, I. 2003. Non-Standard Semantics for Program Slicing. HigherOrder Symbolic Computation 16, 297–339. [5] J, B.  R, J. 1997. A Tutorial on (Co)Algebras and (Co)Induction. EATCS Bulletin 62, 222–259. [6] K, R., K, J. W., S, R.,  V, F.-J. . 1995. Transfinite Reductions in Orthogonal Term Rewriting Systems. Information and Computation 119, 1, 18–38. [7] M, Y. N. 1994. Notes on Set Theory. Undergraduate Texts in Mathematics. SpringerVerlag. [8] P, B. 2000. A Course in Model Theory: an Introduction to Contemporary Mathematical Logic. Springer-Verlag New York. [9] R, T.  T, T. 1996. Program Specialization via Program Slicing. In Proceedings of the Dagstuhl Seminar of Partial Evaluation, Volume 1110 of Lecture Notes in Computer Science. Springer, 409–429. [10] R, T.  Y, W. 1989. The Semantics of Program Slicing and Program Integration. In Proceedings of the International Joint Conference on Theory and Practice of Software Development, Volume 352 of Lecture Notes in Computer Science. Springer, 360–374. [11] S¨, K. 1977. Proof Theory. Grundlehren der matematischen Wissenschaften. SpringerVerlag. [12] S, M. 1992. The Z notation: A Reference Manual. 2nd edition, Prentice Hall International Series in Computer Science.