Scrivi un programma il cui non termine sia indipendente dall'aritmetica di Peano


29

Sfida

Scrivi un programma P, senza prendere input, in modo tale che la proposizione "l'esecuzione di P alla fine termina" è indipendente dall'aritmetica di Peano .

Regole formali

(Nel caso in cui tu sia un logico matematico che pensa che la descrizione sopra sia troppo informale.)

In linea di principio, è possibile convertire alcune macchine Universal Turing U (ad es. Il tuo linguaggio di programmazione preferito) in una formula aritmetica Peano HALT sulla variabile p , dove HALT ( p ) codifica la proposizione " U termina sul programma ( codificato da Gödel ) p ". La sfida è trovare p tale che né HALT ( p ) né ¬HALT ( p ) possano essere dimostrati nell'aritmetica di Peano.

Puoi presumere che il tuo programma funzioni su una macchina ideale con memoria illimitata e numeri interi / puntatori abbastanza grandi da accedervi.

Esempio

Per vedere che esistono tali programmi, un esempio è un programma che cerca esaustivamente una prova aritmetica di Peano di 0 = 1. L'aritmetica di Peano dimostra che questo programma si interrompe se e solo se l'aritmetica di Peano è incoerente. Poiché l'aritmetica di Peano è coerente ma non può dimostrare la propria coerenza , non può decidere se questo programma si interrompe.

Tuttavia, ci sono molte altre proposte indipendenti dall'aritmetica di Peano su cui puoi basare il tuo programma.

Motivazione

Questa sfida è stata ispirata da un nuovo articolo di Yedidia e Aaronson (2016) che espone una macchina Turing a 7.918 stati il ​​cui non-termine è indipendente dallo ZFC , un sistema molto più forte dell'aritmetica di Peano. Potresti essere interessato alla sua citazione [22]. Per questa sfida, ovviamente, puoi usare il tuo linguaggio di programmazione preferito al posto delle macchine Turing attuali.


6
Quali sistemi di assiomi possono essere usati per dimostrare che (a) il programma non si ferma e (b) la non fermata del programma non è dimostrabile in PA?
— feersum

5
Non credo sia ragionevole richiedere che questa domanda contenga tutto lo sfondo necessario nella logica matematica. Ce n'è un bel po 'e ci sono collegamenti alle informazioni rilevanti. Non è offuscato, è solo un argomento tecnico. Penso che sarebbe utile per l'accessibilità dichiarare il requisito del codice separato dalla motivazione che coinvolge le macchine di Turing e collegarsi ad alcuni esempi di dichiarazioni indipendenti da Peano da considerare, in particolare il Teorema di Goodstein ( golf correlato )
— xnor

Perché ciò abbia senso, dovremmo supporre che il codice venga eseguito su una macchina idealizzata con memoria illimitata. Possiamo anche supporre che la macchina abbia una precisione reale arbitraria?
— xnor

1
@feersum Non mi aspetto una prova assiomatica di (a) e (b). Basta scrivere un programma e fornire una descrizione / argomenti / citazioni sufficienti per convincere ragionevolmente che le affermazioni sono vere, come faresti con qualsiasi altra sfida. Puoi fare affidamento su qualsiasi assioma e teorema di norma accettato di cui hai bisogno.
— Anders Kaseorg,

2
@xnor Puoi assumere memoria illimitata e puntatori illimitati con cui accedervi. Ma non credo sia ragionevole assumere una precisione reale arbitraria a meno che la tua lingua non la fornisca effettivamente; nella maggior parte delle lingue, un programma simile x = 1.0; while (x) { x = x / 2.0; }si arresterà molto rapidamente.
— Anders Kaseorg,

Risposte:


27

Haskell, 838 byte

"Se vuoi fare qualcosa, ..."

import Control.Monad.State
data T=V Int|T:$T|A(T->T)
g=guard
r=runStateT
s!a@(V i)=maybe a id$lookup i s
s!(a:$b)=(s!a):$(s!b)
s@((i,_):_)!A f=A(\a->((i+1,a):s)!f(V$i+1))
c l=do(m,k)<-(`divMod`sum(1<$l)).pred<$>get;g$m>=0;put m;l!!fromEnum k
i&a=V i:$a
i%t=(:$).(i&)<$>t<*>t
x i=c$[4%x i,5%x i,(6&)<$>x i]++map(pure.V)[7..i-1]
y i=c[A<$>z i,1%y i,(2&)<$>y i,3%x i]
z i=(\a e->[(i,e)]!a)<$>y(i+1)
(i?h)p=c[g$any(p#i)h,do q<-y i;i?h$q;i?h$1&q:$p,do f<-z i;a<-x i;g$p#i$f a;c[i?h$A f,do b<-x i;i?h$3&b:$a;i?h$f b],case p of A f->c[(i+1)?h$f$V i,do i?h$f$V 7;(i+1)?(f(V i):h)$f$6&V i];V 1:$q:$r->c[i?(q:h)$r,i?(2&r:h)$V 2:$q];_->mzero]
(V a#i)(V b)=a==b
((a:$b)#i)(c:$d)=(a#i)c&&(b#i)d
(A f#i)(A g)=f(V i)#(i+1)$g$V i
(_#_)_=0<0
main=print$(r(8?map fst(r(y 8)=<<[497,8269,56106533,12033,123263749,10049,661072709])$3&V 7:$(6&V 7))=<<[0..])!!0

Spiegazione

Questo programma cerca direttamente una prova aritmetica di Peano di 0 = 1. Poiché PA è coerente, questo programma non termina mai; ma poiché l'AP non può dimostrare la propria coerenza, il non termine di questo programma è indipendente dall'AP.

T è il tipo di espressioni e proposizioni:

  • A Prappresenta la proposizione ∀ x [ P ( x )].
  • (V 1 :$ P) :$ Qrappresenta la proposizione P → Q .
  • V 2 :$ Prappresenta la proposizione ¬ P .
  • (V 3 :$ x) :$ yrappresenta la proposizione x = y .
  • (V 4 :$ x) :$ yrappresenta il naturale x + y .
  • (V 5 :$ x) :$ yrappresenta la naturale x ⋅ y .
  • V 6 :$ xrappresenta la S naturale ( x ) = x + 1.
  • V 7 reinventa lo 0 naturale.

In un ambiente con i variabili libere, codifichiamo espressioni, proposizioni e prove come matrici intere 2 × 2 [1, 0; a , b ], come segue:

  • M ( i , ∀ x [ P ( x )]) = [1, 0; 1, 4] ⋅ M ( i , λ x [P (x)])
  • M ( i , λ x [ F ( x )]) = M ( i + 1, F ( x )) dove M ( j , x ) = [1, 0; 5 + i , 4 + j ] per tutto j > i
  • M ( i , P → Q ) = [1, 0; 2, 4] ⋅ M ( i , P ) ⋅ M ( i , Q )
  • M ( i , ¬ P ) = [1, 0; 3, 4] ⋅ M ( i , P )
  • M ( i , x = y ) = [1, 0; 4, 4] ⋅ M ( i , x ) ⋅ M ( i , y )
  • M ( i , x + y ) = [1, 0; 1, 4 + i ] ⋅ M ( i , x ) ⋅ M ( i , y )
  • M ( i , x ⋅ y ) = [1, 0; 2, 4 + i ] ⋅ M ( i , x ) ⋅ M ( i , y )
  • M ( i , S x ) = [1, 0; 3, 4 + i ] ⋅ M ( i , x )
  • M ( i , 0) = [1, 0; 4, 4 + i ]
  • M ( i , ( Γ , P ) ⊢ P ) = [1, 0; 1, 4]
  • M ( i , Γ ⊢ P ) = [1, 0; 2, 4] ⋅ M ( i , Q ) ⋅ M ( i , Γ ⊢ Q ) ⋅ M ( i , Γ ⊢ Q → P )
  • M ( i , Γ ⊢ P ( x )) = [1, 0; 3, 4] ⋅ M ( i , λ x [P (x)]) ⋅ M ( i , x ) ⋅ [1, 0; 1, 2] ⋅ M ( i , Γ ⊢ ∀ x P (x))
  • M ( i , Γ ⊢ P ( x )) = [1, 0; 3, 4] ⋅ M ( i , λ x [P (x)]) ⋅ M ( i , x ) ⋅ [1, 0; 2, 2] ⋅ M ( i , y ) ⋅ M ( i , Γ ⊢ y = x ) ⋅ M ( i , Γ ⊢ P ( y ))
  • M ( i , Γ ⊢ ∀ x , P ( x )) = [1, 0; 8, 8] ⋅ M ( i , λ x [ Γ ⊢ P ( x )])
  • M ( i , Γ ⊢ ∀ x , P ( x )) = [1, 0; 12, 8] ⋅ M ( i , Γ ⊢ P (0)) ⋅ M ( i , λ x [( Γ , P ( x )) ⊢ P (S ( x ))])
  • M ( i , Γ ⊢ P → Q ) = [1, 0; 8, 8] ⋅ M ( i , ( Γ , P ) ⊢ Q )
  • M ( i , Γ ⊢ P → Q ) = [1, 0; 12, 8] ⋅ M ( i , ( Γ , ¬ Q ) ⊢ ¬ P )

Gli assiomi rimanenti sono codificati numericamente e inclusi nell'ambiente iniziale Γ :

  • M (0, ∀ x [ x = x ]) = [1, 0; 497, 400]
  • M (0, ∀ x [¬ (S ( x ) = 0)]) = [1, 0; 8269, 8000]
  • M (0, ∀ x ∀ y [S ( x ) = S ( y ) → x = y ]) = [1, 0; 56106533, 47775744]
  • M (0, ∀ x [ x + 0 = x ]) = [1, 0; 12033, 10000]
  • M (0, ∀ y [ x + S ( y ) = S ( x + y )]) = [1, 0; 123263749, 107495424]
  • M (0, ∀ x [ x ⋅ 0 = 0]) = [1, 0; 10049, 10000]
  • M (0, ∀ x ∀ y [ x ⋅ S ( y ) = x ⋅ y + x ]) = [1, 0; 661072709, 644972544]

Una prova con matrice [1, 0; a , b ] può essere verificato dato solo l'angolo inferiore sinistro a (o qualsiasi altro valore congruente a un modulo b ); gli altri valori sono lì per consentire la composizione delle prove.

Ad esempio, ecco una prova che l'aggiunta è commutativa.

  • M (0, Γ ⊢ ∀ x ∀ y [ x + y = y + x]) = [1, 0; 6651439985424903472274778830412211286042729801174124932726010503641310445578492460637276210966154277204244776748283051731165114392766752978964153601068040044362776324924904132311711526476930755026298356469866717434090029353415862307981531900946916847172554628759434336793920402956876846292776619877110678804972343426850350512203833644, 14010499234317302152403198529613715336094817740448888109376168978138227692104106788277363562889534501599380268163213618740021570705080096139804941973102814335632180523847407060058534443254569282138051511292576687428837652027900127452656255880653718107444964680660904752950049505280000000000000000000000000000000000000000000000000000000]

Puoi verificarlo con il programma come segue:

*Main> let p = A $ \x -> A $ \y -> V 3 :$ (V 4 :$ x :$ y) :$ (V 4 :$ y :$ x)
*Main> let a = 6651439985424903472274778830412211286042729801174124932726010503641310445578492460637276210966154277204244776748283051731165114392766752978964153601068040044362776324924904132311711526476930755026298356469866717434090029353415862307981531900946916847172554628759434336793920402956876846292776619877110678804972343426850350512203833644
*Main> r(8?map fst(r(y 8)=<<[497,8269,56106533,12033,123263749,10049,661072709])$p)a :: [((),Integer)]
[((),0)]

Se la prova non fosse valida, otterresti invece l'elenco vuoto.


1
Per favore, spiega l'idea dietro le matrici.
— orgoglioso haskeller

2
@proudhaskeller Sono solo un modo conveniente e relativamente compatto di numerare Gödel per tutti gli alberi di prova possibili. Puoi anche pensarli come numeri a radice mista che vengono decodificati dal lato meno significativo usando div e mod dal numero di scelte possibili ad ogni passo.
— Anders Kaseorg,

Come hai codificato gli assiomi di induzione?
— PyRulez,

@PyRulez M (i, Γ ⊢ ∀x, P (x)) = [1, 0; 12, 8] ⋅ M (i, Γ ⊢ P (0)) ⋅ M (i, λx [(Γ, P (x)) ⊢ P (S (x))]) è l'assioma di induzione.
— Anders Kaseorg,

Penso che potresti ridurlo se usi invece Calculus of Constructions (dal momento che Calculus of Constructions ha una logica del primo ordine integrata ed è molto piccola). Il calcolo delle costruzioni è forte quanto lo ZFC, quindi la sua consistenza è sicuramente indipendente dall'AP. Per verificare se è coerente, è sufficiente cercare un termine di tipo vuoto.
— PyRulez,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.