Hai perfettamente ragione sul fatto che l'arresto del problema sia un esempio del secondo tipo di "prova per contraddizione" - è in realtà solo un'affermazione negativa.
Supponiamo che decides_halt(M)
sia un predicato che dice che la macchina M
decide se il suo input è una macchina che si ferma (cioè M
è un programma che per qualche macchina m
e input i
, decide se si m
ferma sull'input i
).
Dimenticando per un momento come dimostrarlo, il problema dell'arresto è l'affermazione che non esiste una macchina che decida il problema dell'arresto. Potremmo affermarlo in Coq come (exists M, decides_halt M) -> False
, o forse preferiamo dire che una determinata macchina non risolve il problema di arresto forall M, decides_halt M -> False
. Si scopre che senza assiomi queste due formalizzazioni sono equivalenti in Coq. (Ho scritto la prova in modo che tu possa vedere come funziona, ma firstorder
farà tutto!)
Parameter machine:Type.
Parameter decides_halt : machine -> Prop.
(* Here are two ways to phrase the halting problem: *)
Definition halting_problem : Prop :=
(exists M, decides_halt M) -> False.
Definition halting_problem' : Prop :=
forall M, decides_halt M -> False.
Theorem statements_equivalent :
halting_problem <-> halting_problem'.
Proof.
unfold halting_problem, halting_problem'; split; intros.
- exact (H (ex_intro decides_halt M H0)).
- destruct H0.
exact (H x H0).
Qed.
Penso che entrambe le affermazioni non siano troppo difficili da dimostrare come argomento di diagonalizzazione, sebbene formalizzare macchine, calcolabilità e fermarsi sia probabilmente ragionevolmente impegnativo. Per un esempio più semplice, non è troppo difficile provare il teorema della diagonalizzazione di Cantor (vedi https://github.com/bmsherman/finite/blob/master/Iso.v#L277-L291 per una prova che nat -> nat
enat
non sono isomorfi).
La diagonalizzazione di cui sopra fornisce un esempio di come si potrebbe fare derivando una contraddizione da un isomorfismo tra nat -> nat
enat
. Ecco l'essenza di quella dimostrazione sottolineata come esempio autonomo:
Record bijection A B :=
{ to : A -> B
; from : B -> A
; to_from : forall b, to (from b) = b
; from_to : forall a, from (to a) = a
}.
Theorem cantor :
bijection nat (nat -> nat) ->
False.
Proof.
destruct 1 as [seq index ? ?].
(* define a function which differs from the nth sequence at the nth index *)
pose (f := fun n => S (seq n n)).
(* prove f differs from every sequence *)
assert (forall n, f <> seq n). {
unfold not; intros.
assert (f n = seq n n) by congruence.
subst f; cbn in H0.
eapply n_Sn; eauto.
}
rewrite <- (to_from0 f) in H.
apply (H (index f)).
reflexivity.
Qed.
Anche senza guardare i dettagli, dall'affermazione possiamo vedere che questa prova prende la mera esistenza di una biiezione e dimostra che è impossibile. Diamo prima i due lati della biiezione i nomi seq
e index
. La chiave è che il comportamento della biiezione nella sequenza speciale f := fun n => S (seq n n)
e nel suo indice index f
è contraddittorio. La dimostrazione del problema di arresto provocherebbe una contraddizione in un modo simile, istanziando la sua ipotesi su una macchina che risolve il problema di arresto con una macchina scelta con cura (e in particolare una che dipende effettivamente dalla macchina assunta).