We want to capture more abstractly what is needed for the coding
theorem to hold. Originally we used divisibility for numbers, but we
can more generally assume that there is some binary predicate satisfying
the following two axioms.
Variable In : nat -> nat -> Prop.
Notation "u ∈ c" := (In u c) (at level 45).
Hypothesis H_empty : exists e, forall x, ~ x ∈ e.
Hypothesis H_extend : forall n c, exists c', forall x, x ∈ c' <-> x = n \/ x ∈ c.
Notation "u ∈ c" := (In u c) (at level 45).
Hypothesis H_empty : exists e, forall x, ~ x ∈ e.
Hypothesis H_extend : forall n c, exists c', forall x, x ∈ c' <-> x = n \/ x ∈ c.
We can now prove that this binary relation can be used for encoding predicates.
Lemma bounded_coding p n :
(forall x, x < n -> p x \/ ~ p x) ->
exists c, forall u, (u < n -> (p u <-> u ∈ c)) /\ (u ∈ c -> u < n).
Proof.
assert (forall u n, u < S n -> u < n \/ u = n) as E by lia.
induction n.
{ intros. destruct H_empty as [e He].
exists e. intros u. split; [lia|]. intros []%He. }
intros Dec_p.
destruct IHn as [c Hc], (Dec_p n ltac:(lia)) as [pn|pn'].
1, 2: intros; apply Dec_p; lia.
- destruct (H_extend n c) as [c' Hc']. exists c'.
intros u. split.
+ intros [| ->]%E. split.
* intros p_u%Hc; auto. apply Hc'; auto.
* intros [->|]%Hc'; auto. now apply Hc.
* split; eauto. intros _. apply Hc'; auto.
+ intros [->|H%Hc]%Hc'; auto.
- exists c.
intros u; split.
+ intros [| ->]%E; [now apply Hc|].
split; [now intros ?%pn'|].
intros H%Hc. lia.
+ intros H%Hc. lia.
Qed.
Lemma DN_bounded_lem p n :
~ ~ (forall x, x < n -> p x \/ ~ p x).
Proof.
induction n as [|n IH].
{ DN.ret. lia. }
DN.lem (p n). intros Hn.
DN.bind IH. DN.ret. intros x Hx.
assert (x < n \/ x = n) as [| ->] by lia.
all: auto.
Qed.
Corollary DN_coding p n :
~~ exists c, forall u, (u < n -> (p u <-> u ∈ c)) /\ (u ∈ c -> u < n).
Proof.
eapply DN.bind_.
- apply DN_bounded_lem.
- intro. apply DN.ret_, (bounded_coding p n); eauto.
Qed.
End Coding.
(forall x, x < n -> p x \/ ~ p x) ->
exists c, forall u, (u < n -> (p u <-> u ∈ c)) /\ (u ∈ c -> u < n).
Proof.
assert (forall u n, u < S n -> u < n \/ u = n) as E by lia.
induction n.
{ intros. destruct H_empty as [e He].
exists e. intros u. split; [lia|]. intros []%He. }
intros Dec_p.
destruct IHn as [c Hc], (Dec_p n ltac:(lia)) as [pn|pn'].
1, 2: intros; apply Dec_p; lia.
- destruct (H_extend n c) as [c' Hc']. exists c'.
intros u. split.
+ intros [| ->]%E. split.
* intros p_u%Hc; auto. apply Hc'; auto.
* intros [->|]%Hc'; auto. now apply Hc.
* split; eauto. intros _. apply Hc'; auto.
+ intros [->|H%Hc]%Hc'; auto.
- exists c.
intros u; split.
+ intros [| ->]%E; [now apply Hc|].
split; [now intros ?%pn'|].
intros H%Hc. lia.
+ intros H%Hc. lia.
Qed.
Lemma DN_bounded_lem p n :
~ ~ (forall x, x < n -> p x \/ ~ p x).
Proof.
induction n as [|n IH].
{ DN.ret. lia. }
DN.lem (p n). intros Hn.
DN.bind IH. DN.ret. intros x Hx.
assert (x < n \/ x = n) as [| ->] by lia.
all: auto.
Qed.
Corollary DN_coding p n :
~~ exists c, forall u, (u < n -> (p u <-> u ∈ c)) /\ (u ∈ c -> u < n).
Proof.
eapply DN.bind_.
- apply DN_bounded_lem.
- intro. apply DN.ret_, (bounded_coding p n); eauto.
Qed.
End Coding.