1

Languages like Agda, and Charity are not turing complete. However, they are still useful languages because they are able to simulate any provably terminating Turing machine. Is there a term for this kind of sub-Turing-completeness? I suppose this class of programming languages would correspond to the family of recursive languages, but is there a term specifically for programming languages/computational frameworks (like Agda, the simply typed lambda calculus, etc...) where the set of formal languages it can accept is exactly the recursive languages?

  • 1
    Can programs in these languages really simulate any provably terminating Turing machine? I'm not familiar with them, so maybe I've misunderstood. Apparently, programs in them provably terminate. So why can't you diagonalize? Write a Turing machine which checks that its input is, say, an Agda program (if not, it just halts), runs the Agda program using the Agda program itself as input, and then appends an extra character to the output (so its output is different from what the Agda program outputs).This is a Turing machine which provably halts but which cannot be simulated by an Agda program. – Mitchell Spector Nov 24 '16 at 06:47
  • @MitchellSpector Hmm... I suppose the question is, what is "provably halting"? Agda is basically a typed lambda calculus, so every program is strongly normalizing, and I would consider the derivation of a program in a type system to be a proof of termination, but I suppose there could be other proofs of termination not expressible in terms of a derivation in type theory. I suppose what I'm asking is: "Are there any lambda terms that (provably) have a normal form, and yet cannot be expressed in terms of the simply typed lambda calculus?" – Nathan BeDell Nov 26 '16 at 16:42
  • I don't know Agda or Charity, but the key is whether they satisfy the following three properties: (1) A program is a string of characters in some alphabet $\Sigma,$ with input and output in $\Sigma^;$ (2) Every program halts on every input string in $\Sigma^;$ (3) If we define the function $f$ with domain $\Sigma^\times\Sigma^$ by setting $f(P,s)$ equal to \begin{cases}\text{output of program }P\text{ on input }s,&\text{ if }P\text{ is a syntactically valid program with one argument,}\\text{the empty string,}&\text{ otherwise},\end{cases} then $f$ is recursive. (continued...) – Mitchell Spector Nov 27 '16 at 01:19
  • (... continued from above) If the three properties above are satisfied, then the function $g$ which maps $s$ to the concatenation of $f(s,s)$ with $"!0!"$ (or any non-empty string) is a function which always halts and which is computable by a Turing machine, but $g$ is not computable by any program in the language. – Mitchell Spector Nov 27 '16 at 01:19

2 Answers2

1

Take any Turing-complete programming language and any useful consistent formal system $S$ ("useful" meaning that it has a proof verifier and interprets arithmetic). Then (as described in the linked post), given any program $P$ and input $X$, if $P$ halts on $X$ then $S$ can prove the output. In fact (omitting the coding and interpretation function for convenience) there is a $3$-parameter $Σ_1$-sentence $run$ over PA such that:

  1. For any program $P$ that halts on an input $X$:

    • $S \vdash run(P,X,P(X))$.

    • $S \vdash \neg run(P,X,Y)$ for every string $Y \ne X$.

  2. For any program $P$ that does not halt on input $X$:

    • $\mathbb{N} \vDash \neg run(P,X,Y)$ for every string $Y$.
  3. For any explicitly primitive recursive program $P$ (using only for-loops):

    • $S \vdash \forall x\ \exists y\ ( run(P,x,y) )$.
  4. For any program $P$ on input $X$ that reaches a simple infinite-loop code:

    • $S \vdash \neg \exists y\ ( run(P,X,y) )$.
  5. For any programs $P,Q,R$:

    • $S \vdash \forall x,y\ \Big( run(( t \mapsto \text{if $P(t)$ then $Q(t)$ else $R(t)$} ),x,y)$

      $\quad \quad \quad \quad \leftrightarrow \exists z\ ( run(P,x,z) \land z \ne 0 \land run(Q,x,y) ) \lor ( run(P,x,0) \land run(R,x,y) ) \Big)$.

  6. For any program $P$ that halts on input $X$:

    • $S \vdash \forall w\ ( run((t \mapsto P(X)),w,P(X)) )$.

Also, for any program $P$, define $total(P)$ to be the sentence $\forall x\ \exists y\ ( run(P,x,y) )$.

Firstly, if $S$ is $Σ_1$-sound, then given any program $P$, if $S \vdash total(P)$ then $P$ is total, because for every (standard) string $x$ we have $S \vdash \exists y\ ( run(P,x,y) )$ and hence $\mathbb{N} \vDash \exists y\ ( run(P,x,y) )$, which implies by (2) that $P$ halts on $x$. Similarly, if $S \vdash \neg total(P)$ then $P$ is really not total, because by (2) we have $\mathbb{N} \vDash \forall y\ ( \neg run(P,x,y) )$.

But (assuming just consistency of $S$) there is a total program $Q$ such that $S \nvdash total(Q)$. Let $φ$ be a $1$-parameter $Δ_0$-sentence over PA such that $\mathbb{N} \vDash \forall x\ ( φ(x) )$ but $S \nvdash \forall x\ ( φ(x) )$, which exists by the incompleteness theorem (as shown in the linked post). Then let $Q$ be a program that uses primitive recursion to evaluate $φ$ on the input string and then halts if it is true but loops forever otherwise. $Q$ is total, but $S \nvdash total(Q)$, because $S \vdash \forall x\ ( φ(x) \lor \neg \exists y\ ( run(Q,x,y) )$ by construction of $Q$ and (1),(3),(4),(5).

And there is also a non-total program $R$ such that $S \nvdash \neg total(R)$. This is because we can construct a program $H$ that, given as inputs a program $R$ and string $X$, simultaneously does the following:

  (a) Simulate $R$ on $X$ and output $1$ if $R$ halts on $X$.

  (b) Search for a proof of $\neg total((t \mapsto R(X)))$ over $S$ and output $0$ if such a proof is found.

If $S \vdash \neg total(R)$ for every non-total program $R$, then $H$ always halts on every valid input pair. If $R$ does not halt on $X$, then (a) never terminates. If $R$ halts on $X$, then by (6) $S \vdash total(t \mapsto R(X))$ and hence (b) never terminates by consistency of $S$. Thus $H$ always outputs the correct answer, contradicting the undecidability of the halting problem.


The above shows in particular that no useful consistent formal system can prove totality of every total program. One might think that perhaps we could find a slightly less useful consistent formal system that does not interpret Robinson's arithmetic and hence escape the incompleteness theorem. But if you look at the proof of the incompleteness theorem again you see that all $S$ needs to be able to do is to correctly prove output of a program that halts on an input, as stated in (1). So at its core it is not even about arithmetic but whether or not you can verify a finite computation! Also, (3),(4),(5),(6) are other basic properties that we ourselves are capable of identifying about a program, so it would be ridiculous if our formal system is unable to. Note that (2) is not used to show that there is a total program that $S$ cannot prove is total.

user21820
  • 57,693
  • 9
  • 98
  • 256
  • It is hard to follow what we want to do. Agda needs a proof of termination for each of its program, and does some automated theorem proving from this ? – reuns Jan 03 '17 at 14:08
  • @user1952009: I have no idea what you're trying to say. My post applies to any formal system whatsoever. Making a formal system in which you can only construct total programs is trivial. The question is itself not very clear but asks for a formal system that allows you to construct all and only total programs, which I've explained is impossible. – user21820 Jan 03 '17 at 14:41
  • come on... what is the key idea of agda, based on what you wrote ? – reuns Jan 03 '17 at 15:23
  • @user1952009: What key idea are you talking about? As I said it's trivial; you just choose some decidable class of total functions and only permit you to construct those.. You'll never get all the total programs that way. – user21820 Jan 03 '17 at 15:44
0

user21820 has answered my question as stated (i.e. is there a programming language which corresponds to the class of recursive programs), but I'd like to add the following to answer a more general question:

If there is no "universal total programming language", how might we measure the strength of different total programming languages?

To which, I think the natural answer is to use Curry-Howard, and measure the strength of a total programming language by its proof theoretic ordinal. For example, according to ncat lab Agda has a proof theoretic ordinal of $\psi_\Omega(\Omega_{M+\omega})$.

Actually, Michael Rathjen discusses in his paper "Theories and Ordinals in Proof Theory" explicitly how proof theoretic ordinals can be used to measure "computational content".

However, to see another useful way we might look at things, consider that although Agda is a total language, we can still model a turing-complete language inside Agda by using corecursion. I think this is possibly related to the answer to my question here.