Suppose I have the following proof:

```
open import Agda.Builtin.Equality
open import Data.Nat.Base

data ⊥ : Set where

data  : Set where
  I : 
  O : 

inv :  → 
inv I = O
inv O = I

invNeq : ∀ d → d ≡ inv d → ⊥
invNeq I ()
invNeq O ()

data Idx : Set where
  at : ℕ → Idx

ℝ : Set
ℝ = Idx → 

_≈_ : {a b : Set} → (f₁ f₂ : a → b) → Set
_≈_ f₁ f₂ = ∀ x → f₁ x ≡ f₂ x

diagEx : (f : ℕ → ℝ) → ℝ
diagEx f (at n) = inv (f n (at n))

doesn'tBelong : (f : ℕ → ℝ) → (n : ℕ) → (f n ≈ diagEx f) → ⊥
doesn'tBelong f n funEq = invNeq (f n (at n)) (funEq (at n))

```

We encode real numbers as functions from natural numbers to binary digits, then (in `diagEx`), given some mapping `f` from natural numbers to reals (or, rather, some subset of those), we build a function that doesn't belong to said mapping, and then prove (in `doesn'tBelong`) that, for any mapping `f`, there exists a function (built by `diagEx f`) that isn't equal to any real number enumerated by the `f`. This, of course, includes `f`'s claiming to be surjective, so that's largely the diagonal argument for proving uncountability of reals. Yay!

Or at least that's the intent of the proof. But what have we really proven? Could it be that we've only proven that there doesn't exist a *terminating* numbering of reals? Or a *computable* one?

My concern is that we're working in some language, and said language only allows terminating functions (modulo some irrelevant details, but even with them it's about computable functions). On the other hand, we don't rely on the computational behaviour of `f` at all, so, in theory, this `f` could be `postulate`d (or, stretching it a little, it could even go ahead and consult some external oracle about each next digit without making the system inconsistent, I guess).

So what's the power of this proof? What's the right tool to reason about this kind of questions? It feels related to model theory, but I have very passing familiarity with that subject.