Turing-Completeness of Polymorphic Stream Equation Systems Christian Sattler Joint Work with Florent Balestrieri University of Nottingham
May 30, 2012
Semantic Setting
I
Partial streams StrD := N → D⊥ over datatype D
Semantic Setting
I
Partial streams StrD := N → D⊥ over datatype D
I
Polymorphic stream functions: families fD : Strm D → StrD polymorphic (or natural, parametric, . . . ) in D
Semantic Setting
I
Partial streams StrD := N → D⊥ over datatype D
I
Polymorphic stream functions: families fD : Strm D → StrD polymorphic (or natural, parametric, . . . ) in D: StrD1 × . . . × StrD1
fD1
/ StrD 1 map(g )
[map(g ),...,map(g )]
StrD2 × . . . × StrD2
fD2
/ StrD 2
for all g : D1 → (D2 )⊥ (where map(g )(s)(i) := g (s(i))).
Polymorphic stream functions are effectively crippled: They may only discard, duplicate, and reorder stream elements. Example: f (s, t) = s(0) :: t(0) :: t(1) :: s(1) :: s(2) :: t(2) :: . . .
Polymorphic stream functions are effectively crippled: They may only discard, duplicate, and reorder stream elements. Example: f (s, t) = s(0) :: t(0) :: t(1) :: s(1) :: s(2) :: t(2) :: . . . Polymorphic fD : Strm D → StrD can equivalently be represented by an indexing function f : N → ({0, . . . , m − 1} × N)⊥ : For k ∈ N and (j, i) := f (k), the k-th output element of fD is given by the i-th stream element of the j-th input argument of fD . For the above example: f starts with (0, 0), (1, 0), (1, 1), (0, 1), (0, 2), (1, 2), . . .
Polymorphic stream functions are effectively crippled: They may only discard, duplicate, and reorder stream elements. Example: f (s, t) = s(0) :: t(0) :: t(1) :: s(1) :: s(2) :: t(2) :: . . . Polymorphic fD : Strm D → StrD can equivalently be represented by an indexing function f : N → ({0, . . . , m − 1} × N)⊥ : For k ∈ N and (j, i) := f (k), the k-th output element of fD is given by the i-th stream element of the j-th input argument of fD . For the above example: f starts with (0, 0), (1, 0), (1, 1), (0, 1), (0, 2), (1, 2), . . . In case of f unary we can write f : N → N⊥ . This gives a direct notion of computability for polymorphic stream functions.
Syntactic Setting A (stream equation) system is a set of equations f0 (s0 , . . . , sm0 −1 ) = ρ1 , ... fn−1 (s0 , . . . , smn−1 −1 ) = ρn where ρ, σ ::= si | tail(σ) | head(σ) :: σ 0 | fj (σ0 , . . . , σmj −1 ).
Syntactic Setting A (stream equation) system is a set of equations f0 (s0 , . . . , sm0 −1 ) = ρ1 , ... fn−1 (s0 , . . . , smn−1 −1 ) = ρn where ρ, σ ::= si | tail(σ) | head(σ) :: σ 0 | fj (σ0 , . . . , σmj −1 ).
I
Interpret head(·) :: · (head-cons) and tail canonically
I
Kleene’s theorem guarantees unique (partial) least fixpoint m solutions (fj )D : StrD j → StrD .
Examples
Interleaving: zipn (s0 , . . . , sn−1 ) = head(s0 ) :: zipn (s1 , . . . , sn−1 , tail(s0 )) " # = head(s0 ) . . . head(sn−1 ) :: zipn (tail(s0 ), . . . , tail(sn−1 ))
Examples
Interleaving: zipn (s0 , . . . , sn−1 ) = head(s0 ) :: zipn (s1 , . . . , sn−1 , tail(s0 )) " # = head(s0 ) . . . head(sn−1 ) :: zipn (tail(s0 ), . . . , tail(sn−1 ))
Projection: projn (s) = head(s) :: projn (tailn (s))
Operational Semantics: Small-Step Introduce functional relation σ ! k for computing stream position k ∈ N in σ: tail(σ) ! k → σ ! k + 1, ( σ ! 0 if k = 0, 0 head(σ) :: σ ! k → 0 σ ! k − 1 else, fj (σ0 , . . . , σnj −1 ) ! k → ρj [σi /si ]i∈{0,...,nj −1} ! k
Operational Semantics: Small-Step Introduce functional relation σ ! k for computing stream position k ∈ N in σ: tail(σ) ! k → σ ! k + 1, ( σ ! 0 if k = 0, 0 head(σ) :: σ ! k → 0 σ ! k − 1 else, fj (σ0 , . . . , σnj −1 ) ! k → ρj [σi /si ]i∈{0,...,nj −1} ! k We are now able to explicitly define ( sw (i) if fj (s0 , . . . , smj −1 ) ! k →∗ sw ! i, fj,D (s0 , . . . , smj −1 ) = ⊥ else.
Operational Semantics: Term Rewriting
Equivalent view: rewriting system on terms head(tailk (σ)) based on head(head(σ) :: σ 0 ) → head(σ), tail(head(σ) :: σ 0 ) → σ 0 , fj (σ0 , . . . , σnj −1 ) → ρj [σi /si ]i∈{0,...,nj −1} with deterministic outermost rewriting strategy. Or simply: an infinitary rewriting system.
Examples: Indexing Functions
Interleaving: zipn (s0 , . . . , sn−1 ) = head(s0 ) :: zipn (s1 , . . . , sn−1 , tail(s0 )) zipn (k) = (k mod n, bn/kc)
Examples: Indexing Functions
Interleaving: zipn (s0 , . . . , sn−1 ) = head(s0 ) :: zipn (s1 , . . . , sn−1 , tail(s0 )) zipn (k) = (k mod n, bn/kc) Projection: projn (s) = head(s) :: projn (tailn (s)) projn (k) = nk
A Warning
Important Polymorphism is a debilitating restriction!
A Warning
Important Polymorphism is a debilitating restriction! Even with only two distinguishable elements 0, 1 ∈ D, we can directly represent Turing machines on alphabet {0, 1} [Roşu, 2006; Simonsen, 2009]: I
One stream for the tape left of the head
I
One stream for the tape right of the head
I
State transition rules based on case distinction (matching) of head value and current state (fixed number of bits)
A Warning
Important Polymorphism is a debilitating restriction! Even with only two distinguishable elements 0, 1 ∈ D, we can directly represent Turing machines on alphabet {0, 1} [Roşu, 2006; Simonsen, 2009]: I
One stream for the tape left of the head
I
One stream for the tape right of the head
I
State transition rules based on case distinction (matching) of head value and current state (fixed number of bits)
With only polymorphic stream functions, it is not clear at all how to encode machines, not being able to match on data.
Big Questions
Can we decide productivity (equivalently, semantic totality, convergence, . . . )?
Big Questions
Can we decide productivity (equivalently, semantic totality, convergence, . . . )? I
No, it is Π02 -complete [Endrullis, Grabmayer, Hendriks, 2009] proof by reduction from Fractran.
Big Questions
Can we decide productivity (equivalently, semantic totality, convergence, . . . )? I
No, it is Π02 -complete [Endrullis, Grabmayer, Hendriks, 2009] proof by reduction from Fractran.
What does the class of definable stream functions look like?
Big Questions
Can we decide productivity (equivalently, semantic totality, convergence, . . . )? I
No, it is Π02 -complete [Endrullis, Grabmayer, Hendriks, 2009] proof by reduction from Fractran.
What does the class of definable stream functions look like? I
All computable polymorphic stream functions are definable proof idea similar to the above, but with reduction from counter machines.
I
A polymorphic stream function is computable iff its indexing function of type N → ({0, . . . , n − 1} × N)⊥ is computable.
Definability: Basic Idea
I
Encode register state R0 , R1 , R2 , . . . ∈ N as finstruction ! 2R0 3R1 5R2 . . . .
I
projpi increments register i.
I
zippi decrements register i.
Definability: Basic Idea
I
Encode register state R0 , R1 , R2 , . . . ∈ N as finstruction ! 2R0 3R1 5R2 . . . .
I
projpi increments register i.
I
zippi decrements register i. Most importantly: zippi also acts as a dispatching device, sending states to different paths depending on the residue of the index modulo pi , i.e. whether Ri is zero or not.
I
I
We have branching!
Definability: Basic Idea
The central point of the previous construction, as well the construction of Endrullis et al., is the use of interleaving as the only available device for control flow handling.
Definability: Basic Idea
The central point of the previous construction, as well the construction of Endrullis et al., is the use of interleaving as the only available device for control flow handling. What if we removed interleaving from the language, i.e. restricted systems to only unary function definitions?
Definability: Basic Idea
The central point of the previous construction, as well the construction of Endrullis et al., is the use of interleaving as the only available device for control flow handling. What if we removed interleaving from the language, i.e. restricted systems to only unary function definitions? How do you encode machines without the possibility of branching?
Main Result: Unary Definability
What does the class of polymorphic stream functions definable by a unary system look like?
Main Result: Unary Definability
What does the class of polymorphic stream functions definable by a unary system look like? I
It is still equal to the class of computable unary polymorphic stream functions!
Main Result: Unary Definability
What does the class of polymorphic stream functions definable by a unary system look like? I
It is still equal to the class of computable unary polymorphic stream functions!
I
Proof highly technical: multiple layers of emulation with crazy encodings
Main Result: Unary Definability
What does the class of polymorphic stream functions definable by a unary system look like? I
It is still equal to the class of computable unary polymorphic stream functions!
I
Proof highly technical: multiple layers of emulation with crazy encodings
Corollary: Productivity is undecidable even for only unary stream equations.
Main Result: Sketch of a Sketch
1. Encode generalized Collatz functions.
Main Result: Sketch of a Sketch
1. Encode generalized Collatz functions. 2. Use these to simulate a single loop iteration of a While-program with a single top-level loop.
Main Result: Sketch of a Sketch
1. Encode generalized Collatz functions. 2. Use these to simulate a single loop iteration of a While-program with a single top-level loop. 3. Modify such While-programs to encode their result in the number of loop iterations until termination.
Main Result: Sketch of a Sketch
1. Encode generalized Collatz functions. 2. Use these to simulate a single loop iteration of a While-program with a single top-level loop. 3. Modify such While-programs to encode their result in the number of loop iterations until termination. 4. Loop the program and decode the result from the run time.
Main Result: Generalized Collatz Functions
Encoding of g (n · q + i) = ai · q + bi (for i = 0, . . . , n − 1): add(s) = head(tailn·a0 +0 (s)) :: . . . :: head(tailn·an−1 +(n−1) (s)) :: add(tailn (s)), u(s) = head(tailn·b0 +0 (s)) :: . . . :: head(tailn·bn−1 +(n−1) (s)) :: u(add(s)), div(s) = head(s) :: . . . :: head(s) :: div(tail(s)), | {z } n times
v (s) = u(div(s)) v =g
Unary Definability: Minimum System Size
In total, we need to define eleven non-mutual unary equations, of which nine are essential. It is natural to ask: what is the minimal number of equations required for unary definability?
Unary Definability: Minimum System Size
In total, we need to define eleven non-mutual unary equations, of which nine are essential. It is natural to ask: what is the minimal number of equations required for unary definability? We managed to find a construction using only four non-mutual unary equations (very ugly, even more technical).
Unary Definability: Three Equations Are Not Enough
Define a0,1 := 0, an := blog2 (log2 (n))c + 1 for n ≥ 2. Let b : N → N be the infinite concatenation, for n = 0, 1, 2, . . ., of an , an + 1, . . . , n. There is no unary system of size 3 with b as indexing function.
Unary Definability: Summary
I
Four equations can define any computable stream function.
I
Three equations do not suffice.
Unary Definability: Summary
I
Four equations can define any computable stream function.
I
Three equations do not suffice.
I
Productivity is still undecidable (Π02 -complete) for only two equations.
Unary Definability: Summary
I
Four equations can define any computable stream function.
I
Three equations do not suffice.
I
Productivity is still undecidable (Π02 -complete) for only two equations.
I
Surprisingly, productivity for a single equation is decidable!
Unary Definability: Summary
I
Four equations can define any computable stream function.
I
Three equations do not suffice.
I
Productivity is still undecidable (Π02 -complete) for only two equations.
I
Surprisingly, productivity for a single equation is decidable!
[Proofs mostly rather lengthy and technical]
Conclusions
I
Delineated exact boundaries of decidability and productivity for (unary) polymorphic stream equations
I
Found an elegant model of Turing-completeness in a severely restricted environment