This is the second of three sets of fixed point exercises. The first post in this sequence is here, giving context.
Recall Cantor’s diagonal argument for the uncountability of the real numbers. Apply the same technique to convince yourself than for any set S, the cardinality of S is less than the cardinality of the power set \mathcal{P}(S) (i.e. there is no surjection from S to \mathcal{P}(S)).
Suppose that a nonempty set T has a function f from T to T which lacks fixed points (i.e.f(x) \neq x for all x \in T). Convince yourself that there is no surjection from S to S \rightarrow T, for any nonempty S. (We will write the set of functions from A to B either as A \rightarrow B or B^A; these are the same.)
For nonempty S and T, suppose you are given g:S \rightarrow T^S a surjective function from the set S to the set of functions from S to T, and let f be a function from T to itself. The previous result implies that there exists an x in T such that f(x)=x. Can you use your proof to describe x in terms of f and g?
Given sets A and B, let \mathrm{Comp}(A, B) denote the space of total computable functions from A to B. We say that a function from C to \mathrm{Comp}(A, B) is computable if and only if the corresponding function f':C \times A \rightarrow B (given by f'(c,a)=f(c)(a)) is computable. Show that there is no surjective computable function from the set S of all strings to \mathrm{Comp}(S, {T,F}).
Show that the previous result implies that there is no computable function \mathtt{halt}(x,y) from S \times S \rightarrow {T,F} which outputs T if and only if the first input is a code for a Turing machine that halts when given the second input.
Given topological spaces A and B, let \mathrm{Cont}(A, B) be the space with the set of continuous functions from A to B as its underlying set, and with topology such that f : C \rightarrow \mathrm{Cont}(A, B) is continuous if and only if the corresponding function f': C \times A \rightarrow B (given by f'(c,a)=f(c)(a)) is continuous, assuming such a space exists. Convince yourself that there is no space X which continuously surjects onto \mathrm{Cont}(X, S), where S is the circle.
In your preferred programming language, write a quine, that is, a program whose output is a string equal to its own source code.
Write a program that defines a function \mathtt{f} taking a string as input, and produces its output by applying \mathtt{f} to its source code. For example, if \mathtt{f} reverses the given string, then the program should outputs its source code backwards.
Given two sets A and B of sentences, let \mathrm{Syn}(A, B) be the set of all functions from A to B defined by substituting the Gödel number of a sentence in A into a fixed formula. Let S_0 be the set of all sentences in the language of arithmetic with one unbounded universal quantifier and arbitrarily many bounded quantifiers, and let S_1 be the set of all formulas with one free variables of that same quantifier complexity. By representing syntax using arithmetic, it is possible to give a function f \in \mathrm{Syn}(S_1 \times S_1, S_0) that substitutes its second argument into its first argument. Pick some coding of formulas as natural numbers, where we denote the number coding for a formula \varphi as \ulcorner \varphi \urcorner. Using this, show that for any formula \phi \in S_1, there is a formula \psi \in S_0 such that \phi(\ulcorner \psi \urcorner) \leftrightarrow \psi.
(Gödel’s second incompleteness theorem) In the set S_1, there is a formula \neg\mathrm{Bew} such that \neg\mathrm{Bew}(\ulcorner \psi \urcorner) holds iff the sentence \psi is not provable in Peano arithmetic. Using this, show that Peano arithmetic cannot prove its own consistency.
(Löb’s theorem) More generally, the diagonal lemma states that for any formula \phi with a single free variable, there is a formula \psi such that, provably, \phi(\ulcorner \psi \urcorner) \leftrightarrow \psi. Now, suppose that Peano arithmetic proves that \mathrm{Bew}(\psi) \rightarrow \psi for some formula \psi. Show that Peano arithmetic also proves \psi itself. Some facts that you may need are that (a) when a sentence \psi is provable, the sentence \mathrm{Bew}(\psi) is itself provable, (b) Peano arithmetic proves this fact, that is, Peano arithmetic proves \mathrm{Bew}(\psi) \rightarrow \mathrm{Bew}(\mathrm{Bew}(\psi)), for any sentence \psi and (c) Peano arithmetic proves the fact that if \chi and \chi \rightarrow \zeta are provable, then \zeta is provable.
(Tarski’s theorem) Show that there does not exist a formula \phi with one free variable such that for each sentence \psi, the statement \phi(\ulcorner \psi \urcorner) \leftrightarrow \psi holds.
Looking back at all these exercises, think about the relationship between them.
Please use the spoilers feature—the symbol ‘>’ followed by ‘!’ followed by space -in your comments to hide all solutions, partial solutions, and other discussions of the math. The comments will be moderated strictly to hide spoilers!
I recommend putting all the object level points in spoilers and including metadata outside of the spoilers, like so: "I think I’ve solved problem #5, here’s my solution
Ex 8: (in Python, using a reversal function) def f(s): return s[::-1]dlmt = ’"""‘code = """def f(s): return s[::-1]dlmt = ’{}’code = {}{}{}code = code.format(dlmt, dlmt, code, dlmt)print(f(code))"″"code = code.format(dlmt, dlmt, code, dlmt)print(f(code))
Ex 4 Given a computable function \phi : S \mapsto \text{Comp}(S, {T,F}), define a function f : S \mapsto {T,F} by the rule f(s) = \begin{cases} T & \phi(s)(s) = F \ F & \phi(s)(s) = T\end{cases}. Then f is computable, however, f \notin \phi(S) because for s \in S, we have that \phi(s)(s) = F \implies f(s) = T \implies \phi(s) \neq f and \phi(s)(s) = T \implies f(s) = F \implies \phi(s) \neq f.
Ex 5: We show the contrapositive: given a function halt, we construct a surjective function f from S to \text{Comp}(S, {T,F}) as follows: enumerate all turing machines, such that each corresponds to a string. Given a t \in S, if t does not decode to a turing machine, set f(t) \equiv F. If it does, let [t] denote that turning machine. Let f(t) with input s \in S first run halt(t,s); if halt returns F, put out F, otherwise [t] will halt on input s; run [t] on s and put out the result. Given a computable function g : S \mapsto {T,F}, there is a string t^* \in S such that [t^] implements g (if the turing thesis is true). Then g = f(t^), so that f is surjective. Ex 6: Let h : \mathbb{R} \mapsto S be a parametrization of the circle given by h(r) \mapsto (\cos(r), \sin(r)). Given p \in S and r \in \mathbb{R}, write p + r to denote the point h(p' + r), where p' \in h^{-1}({p}). First, note that, regardless of the topology on X, it holds true that if f : X \mapsto S is continuous, then so is f_r : x \mapsto f(x) + r for any r \in \mathbb{R}, because given a basis element (h(a), h(b)) of the circle, we have f_r^{-1}(B) = f^{-1}(h(a)-r, h(b)-r) which is open because f is continuous. Let \phi be a continuous function from X to \text{Cont}(X,S). Then \phi' : X \times X \mapsto S is continuous, and so is the diagonal function h : x \mapsto \phi(x,x). Fix any r \in (0, 2\pi), then f : X \mapsto S given by f : x \mapsto (\phi'(x,x) + r)) is also continuous, but given any x \in X, one has \phi(x)(x) = \phi'(x,x) \neq \phi'(x,x) + r = f(x) and thus \phi(x) \neq f. It follows that \phi is not surjective. Ex 7: I did it in java. There’s probably easier ways to do this, especially in other languages, but it still works. It was incredibly fun to do. My basic idea was to have a loop iterate 2 times, the first time printing the program, the second time printing the printing command. Escaping the " characters is the biggest problem, the main idea here was to have a string q that equals " in the first iteration and " + q + " in the second. That second string (as part of the code in an expression where a string is printed) will print itself in the console output. Code: package maths;public class Quine{public static void main(String[]args){for(int i=0;i<2;i++){String o=i==1?""+(char)34:"";String q=""+(char)34;q=i==1?q+"+q+"+q:q;String e=i==1?o+"+e);}}}":"System.out.print(o+";System.out.print(o+"package maths;public class Quine{public static void main(String[]args){for(int i=0;i<2;i++){String o=i==1?"+q+""+q+"+(char)34:"+q+""+q+";String q="+q+""+q+"+(char)34;q=i==1?q+"+q+"+q+"+q+"+q:q;String e=i==1?o+"+q+"+e);}}}"+q+":"+q+"System.out.print(o+"+q+";"+e);}}}
For #6, I have what looks to me like a counterexample. Possibly I am using the wrong definition of continuous function? I am taking this one as my source. Take as the topological space X the real line under the Euclidean topology. Let f'(x,y) be the point in S_1 at (x+y) radians rotation. This is surjective; all points in S_1 are mapped to infinitely many times. It is also continuous; For every (x,y)\in X,X and neighborhood N(f'(x,y)) there is a neighborhood M(x,y) such that \forall p \in M, f(p)\in N The partial functions f(x) from X \to S_1 are also continuous by the same argument.
Comment
Currying doesn’t preserve surjectivity. As a simple example, you can easily find a surjective function 2 \times 2 \rightarrow 2, but there are no surjective functions 2 \rightarrow 2^2.
Comment
Ah, yes, that makes sense. I got distracted by the definition of Cont(A,B)’s topology and applied it to surjectivity as well as continuity.
Thoughts on #10:
I am confused about this exercise. The standard/modern proof of Gödel’s second incompleteness theorem uses the Hilbert–Bernays–Löb derivability conditions, which are stated as (a), (b), (c) in exercise #11. If the exercises are meant to be solved in sequence, this seems to imply that #10 is solvable without using the derivability conditions. I tried doing this for a while without getting anywhere.
Maybe another way to state my confusion is that I’m pretty sure that up to exercise #10, nothing that distinguishes Peano arithmetic from Robinson arithmetic has been introduced (it is only with the introduction of the derivability conditions in #11 that this difference becomes apparent). It looks like there is a version of the second incompleteness theorem for Robinson arithmetic, but the paper says "The proof is by the construction of a nonstandard model in which this formula [i.e. formula expressing consistency] is false", so I’m guessing this proof won’t work for Peano arithmetic.
My solution for #12:
Suppose for the sake of contradiction that such a formula \phi exists. By the diagonal lemma applied to \neg \phi, there is some sentence \psi such that, provably, \neg\phi(\ulcorner \psi\urcorner) \leftrightarrow \psi. By the soundness of our theory, in fact \neg\phi(\ulcorner \psi\urcorner) \leftrightarrow \psi. But by the property for \phi we also have \phi(\ulcorner \psi\urcorner) \leftrightarrow \psi, which means \neg\phi(\ulcorner \psi\urcorner) \leftrightarrow \phi(\ulcorner \psi\urcorner), a contradiction.
This seems to be the "semantic" version of the theorem, where the property for \phi is stated outside the system. There is also a "syntactic" version where the property for \phi is stated within the system.
#1 Let f be such a surjection. Construct a member of P(S) outside f’s image by differing from each f(x) in whether it contains x. #2 A nonempty set has functions without a fixed point iff it has at least two elements. It suffices to show that there is no surjection from S to S → 2, which is analogous to #1. #3 T has only one element. Use that one. #7 Haskell source = "main = putStrLn ("source = " ++ show source ++ "\n" ++ source)"main = putStrLn ("source = " ++ show source ++ "\n" ++ source) Is #8 supposed to read "Write a program that takes a function f taking a string as input as input, and produces its output by applying f to its source code. For example, if f reverses the given string, then the program should outputs its source code backwards."? If so, here. source = "onme = putStrLn $ f $ "source = " ++ show source ++ "\n" ++ source"onme f = putStrLn $ f $ "source = " ++ show source ++ "\n" ++ source
Ex 1 Exercise 1: Let f : S \mapsto \mathcal{P}(S) and let A = {x \in S | x \notin f(x)}. Suppose that A \in f(S), then let x \in S be an element such that f(x) = A. Then x \notin f(x) = A \implies x \in A by definition, and x \in A = f(x) \implies x \notin A. So x \notin A \iff x \in A, a contradiction. Hence A \notin f(S), so that f is not surjective. Ex 2 Exercise 2: Since T is nonempty, it contains at least one element t_0. Let h : T \mapsto T be a function without a fixed point, then t_0 \neq h(t_0) =: t_1, so that t_0 and t_1 are two different elements in T (this is the only thing we shall use the function h for). Let \Psi : S \mapsto T^S for S nonempty. Suppose by contradiction that \Psi is surjective. Define a map f : S \mapsto \mathcal{P}(S) by the rule f(x) = {s \in S | \Psi(x)(s) = t_0 }. Given any subset U \subset S, let g : S \mapsto T be given by g : x \mapsto \begin{cases} t_0 & x \in U \ t_1 & x \notin U \end{cases} Since \Psi is surjective, we find a s^* \in S such that \Psi(s^) = g. Then f(s^) = U. This proves that f is surjective, which contradicts the result from (a). Ex 3 Exercise 3: By (2) we know that T = {x}, and so f = {(x,x)} and g = {(s,h) | s \in S} where h = {(s,x) | s \in S}. That means x = g(s)(s') = f^n(g(s)(s')) for any s,s' \in S. and n \in \mathbb{N}.
Attempted solution and some thoughts on #9:
Define a formula \xi(v) taking one free variable to be f(\ulcorner\phi\urcorner, \ulcorner f(v,v)\urcorner).
Now define \psi to be f(\ulcorner\xi\urcorner,\ulcorner\xi\urcorner). By the definition of f we have \psi \leftrightarrow \xi(\ulcorner\xi\urcorner).
We have \phi(\ulcorner\psi\urcorner) \leftrightarrow f(\ulcorner\phi\urcorner,\ulcorner\psi\urcorner) \leftrightarrow f(\ulcorner\phi\urcorner, \ulcorner f(\ulcorner\xi\urcorner,\ulcorner\xi\urcorner)\urcorner) \leftrightarrow \xi(\ulcorner \xi\urcorner) \leftrightarrow \psi
The first step follows by the definition of f, the second by the definition of \psi, the third by the definition of \xi, and the fourth by the property of \psi mentioned above. Since \psi \in S_0 by the type signature of f, this completes the proof.
Things I’m not sure about:
It’s a little unclear to me what the \mathrm{Syn}(A,B) notation means. In particular, I’ve assumed that f takes as inputs Gödel numbers of formulas rather than the formulas themselves. If f takes as inputs the formulas themselves, then I don’t think we can assume that the formula \xi exists without doing more arithmetization work (i.e. the equivalent of \xi would need to know how to convert from the Gödel number of a formula to the formula itself).
If the biconditional "\leftrightarrow" is a connective in the logic itself, then I think the same proof works but we would need to assume more about f than is given in the problem statement, namely that the theory we have can prove the substitution property of f.
The assumption about the quantifier complexity of S_0 and S_1 was barely used. It was just given to us in the type signature for f, and the same proof would have worked without this assumption, so I am confused about why the problem includes this assumption.
Comment
Here’s the proof from the paper again:
=s2A < px0,0..p9x0> xx0x0x0x0x0e0..6y0e0x0e0x0e0x0e0e0e0x0e0e0x0e0e0x0.x0e0x0e0e0x0e0e0e0x0e0.x0e0bx<x0e0e0x0e0e0e0e0x0e0.x0e0e0.e0e0.x0e0e0e0e0..2e0e0.x0e0e0e0e0).
So, a proof can’t be "s2A" or "s2B" or "s2A" or "s2B" or "s2B" or "s2C" or "worlds" or "possible worlds" or "no known world". But it might well be that the proof is correct enough given the premises.
So we assume the proof is correct!
Q7 (Python): Y = lambda s: eval(s)(s)Y(‘lambda s: print("Y = lambda s: eval(s)(s)\nY({s!r})")’) Q8 (Python): Not sure about the interpretation of this one. Here’s a way to have it work for any fixed (python function) f: f = ‘lambda s: "\n".join(s.splitlines()[::-1])’ go = ‘lambda s: print(eval(f)(eval(s)(s)))’ eval(go)(‘lambda src: f"f = {f!r}\ngo = {go!r}\neval(go)({src!r})"’)
I am confused by the introductory statement for #9. Is this an accurate rephrasing? By representing syntax using arithmetic, it is possible to define a function f as follows: Define f(s\in S_1,t\in S_1) with image in S_0, such that: f substitutes the Goedel-number of t into s (creating s') and then substitutes the Goedel-number of s' into some fixed formula to get a result in S_0.
I’m confused about Q9.
Given the way Syn(A, B) is defined, it’s unclear to me how we ensure type correctness of Syn(S_1 \times S_1, S_0). In what sense is S_1 \times S_1 a set of sentences (rather than a set of pairs of sentences)? What does an element of that set look like?
Comment
Yeah, it is just functions that take in two sentences and put both their Godel numbers into a fixed formula (with 2 inputs).
Ex 1. Suppose there is a surjection f : S → P(S). Consider the set X = {x \in S | x \notin f(x)} . Since f is a surjection, X = f(y) for some y in S. Does y lie in X? If y \in X , then y \in f(y) , so by definition of X, y \notin X . If y \notin X , then y \notin f(y), so y must belong to X. Contradiction. Ex 2. Since there is a function f: T \to T without fixed points, T must have at least two elements. Hence, there is a surjection s: T \to {0,1} , which induces a surjection T^S \to 2^S (a function g: S \to T goes to s \circ g ). So, if there were a surjection S \to T^S , there would also be a surjection S \to 2^S , which cannot be by previous exercise. Ex 4. Suppose f: S \to \text{Comp}(S, {T, F}) is a computable surjective function. Consider the function g: S \to {T, S}defined by g(s) = \neg f(s)(s). The function g is computable, therefore there should exist an s^* \in S: f(s^) = g . Then f(s^)(s^) = g(s^) = \neg f(s^)(s^) . Contradiction. Ex 5. Suppose halt(x,y) is a computable function. Consider the function f: S \to {T, F}: f(s) = \neg s(s) \text{ if halt(s,s)} ; T if \neg \text{halt}(s,s) Suppose s' is a Turing code of f. Since f halts everywhere, halt(s’, s’) = T. But then s'(s') = f(s') = \neg s'(s') . Contradiction. Ex 6. Suppose that f: X \to \text{Cont}(X, S) is a continuous surjection. Consider the function g \in \text{Cont}(X, S) g(x) = - f(x, x) (here—f(x, x) is a point diametrically opposed to f(x, x)). f is surjective, hence g = f(y), but then g(y) = f(y,y) = - f(y,y). Contradiction. Ex 7. A quine in python3: code = """code = {}{}{}{}{}{}{} print(code.format(‘"’,‘"’,‘"’,code,‘"’,‘"’,‘"’))"""print(code.format(‘"’,‘"’,‘"’,code,‘"’,‘"’,‘"’)) Ex 8. In python: import inspectdef f(string): return string[::-1]def applytoself(f): source = inspect.getsource(f) return f(source)applytoself(f) ‘\n]1-::[gnirts nruter \n:)gnirts(f fed’ Ex 9. The formula for \psi is \forall x((x = \ulcorner\psi\urcorner)\to \phi(x)) Ex 11. Suppose \phi is the formula Bew(x) \to \psi . By the diagonal lemma, there exists a formula A such that \vdash A \leftrightarrow(Bew(A) \to \psi) . Therefore, \vdash Bew(A \to (Bew(A) \to \psi)) By property c, \vdash Bew(A) \to Bew(Bew(A) \to \psi) Again by property c, \vdash Bew(Bew(A) \to \psi) \to (Bew(Bew(A)) \to Bew(\psi)) Combining previous two implications, \vdash Bew(A) \to (Bew(Bew(A)) \to Bew(\psi)) Since \vdash Bew(A) \to Bew(Bew(A)) , we have \vdash Bew(A) \to Bew(\psi) Combining this with \vdash Bew(\psi) \to \psi , we get \vdash Bew(A) \to \psi From this we get \vdash A , therefore, \vdash Bew(A) and \vdash \psi . QED.
Comment
Don’t know if this is still relevant, but on Ex9
you definitely can’t define \psi this way. Your definition includes the godel numeral for \psi, which makes the definition depend on itself.
Comment
Self-referential definitions can be constructed with the diagonal lemma. Given that the point of the exercise is to show something similar, you’re right that this solution is probably a bit suspect.
Comment
I might be wrong, but I believe this is not correct. The diagonal lemma lets you construct a sentence that is logically equivalent to something including its own godel numeral. This is different from having its own godel numeral be part of the syntactic definition.
In particular, the former isn’t recursive. It defines one sentence and then, once that sentence is defined, proves something about a second sentence which includes the godel numeral of the first. But what seed attempted (unless I misunderstood it) was to use the godel numeral \ulcorner \psi \urcorner in the syntactic definition for \psi, which doesn’t make sense because \ulcorner \psi \urcorner is not defined until \psi is.
Minor correction for #7: You probably want to say "nonempty quine" or "nontrivial quine". The trivial quine works in many languages.
Comment
My nontrivial answer for Q7, in Python: with open("foo.py", "r") as foo: print foo.read() And for Q8: def f(string): return ″.join([chr(ord(c)+1) for c in string])with open("foo.py", "r") as foo: print f(foo.read())
Ex8
This was reasonably straight-forward given the quine.
def apply(f): l = chr(123) # opening curly bracket r = chr(125) # closing curly bracket q = chr(39) # single quotation mark n = chr(10) # linebreak z = [n+" ", l+f"z[i]"+r+q+n+" + f"+q] x = [n+" ", l+f"x[i]"+r] e = [q, l+"e[i]"+r+q+")"+n+" print(f(sourcecode))"] sourcecode = "" for i in range(0,2): sourcecode += (f'def apply(f):{z[i]}' + f'l = chr(123) # opening curly bracket{z[i]}' + f'r = chr(125) # closing curly bracket{z[i]}' + f'q = chr(39) # single quotation mark{z[i]}' + f'n = chr(10) # linebreak{z[i]}' + f'z = [n+" ", l+f"z[i]"+r+q+n+" + f"+q]{z[i]}' + f'x = [n+" ", l+f"x[i]"+r]{z[i]}' + f'e = [q, l+"e[i]"+r+q+")"+n+" print(f(sourcecode))"]{z[i]}' + f'sourcecode = ""{z[i]}' + f'for i in range(0,2):{x[i]}sourcecode += (f{e[i]}') print(f(sourcecode))
Last time, I got to Ex7. This time, I decided to do them all again before continuing.
Comment on Ex1-6
It gets easy if you just write down what property you want to have in first-order logic.
For example, for Ex1 you want a set A that does the following:
\forall x f(x) \neq A
now if we consider a set as a function that takes an element and returns true or false, this becomes
\forall x \exists y f(x)(y) \neq A(y)
How do you get such a y? You can just choose y := x, then
\forall x f(x)(x) \neq A(x)
and this is done by defining A(x) := \neg f(x)(x), i.e., A := {x : x \notin f(x)} which is precisely the solution. This almost immediately answers Ex 1,2,4 and it mostly answers Ex6.
Another quine for Ex7, this time in python:
l = chr(123) # opening curly bracket r = chr(125) # closing curly bracket q = chr(39) # single quotation mark t = chr(9) # tab n = chr(10) # linebreak z = [n, l+f"z[i]"+r+q+n+t+"+ f"+q] x = [n+t, l+f"x[i]"+r] e = [q, l+"e[i]"+r+q+", end="+q+q+")"] for i in range(0,2): print(f'l = chr(123) # opening curly bracket{z[i]}' + f'r = chr(125) # closing curly bracket{z[i]}' + f'q = chr(39) # single quotation mark{z[i]}' + f't = chr(9) # tab{z[i]}' + f'n = chr(10) # linebreak{z[i]}' + f'z = [n, l+f"z[i]"+r+q+n+t+"+ f"+q]{z[i]}' + f'x = [n+t, l+f"x[i]"+r]{z[i]}' + f'e = [q, l+"e[i]"+r+q+", end="+q+q+")"]{z[i]}' + f'for i in range(0,2):{x[i]}print(f{e[i]}', end='')