Escardó’s Exhaustive Search: Part 2

July 26, 2025 • #math #pltheory


pulling the rabbit out of the hat??

At the end of the previous blog, I mentioned that the topological properties of the Cantor space make it searchable via a constructive algorithm. Surprisingly, its not too much of a lift but still feels kinda magical. Not only are we deciding a total predicate without any a priori information other than continuity and compactness. Nothing else is known ahead of time: which bit indices will be queried, the number of bits that are required, or any details about the frontier itself. All of this information is extracted at execution time.

Cylinder Set

In a world of AI generated images, enjoy my hand-drawn rendition of a rabbit in a hat1. I know it is shit. Sorry.

haskell wizardry

sme :: Pred -> IO [Prefix]
sme p = go IM.empty where
  go asg = case evalP p asg of
    Right True -> pure [asg]
    Right False -> pure []
    Left i -> do
      f0 <- go (IM.insert i False asg)
      f1 <- go (IM.insert i True asg)
      pure (f0 ++ f1)

This performs a determinsitic DFS of the decision tree induced by the predicate p:(BNB)Bp: (\mathbb{B}^\mathbb{N} \rightarrow \mathbb{B}) \rightarrow \mathbb{B} via a partial oracle that answers onl ythe bits present int eh current prefix σ\sigma and raises a Need exception when pp demands an unknown bit index ii (this is all covered in the previous blog, nothing new here).

In this case, at node σ\sigma we now have three cases:

  1. evalP returns True = pp is already a constant 11 on [σ][\sigma] cylinder set so we can record σ\sigma and return
  2. evalP returns False, so [σ]Uc[\sigma] \subseteq U^c so the entire branch can be pruned
  3. It raises Need i so we branch to σ{i0}\sigma \cup \{i \mapsto 0 \} and σ{i1}\sigma \cup \{i \mapsto 1 \}.

The result of this procedure is F=SME(p)\cal{F} = \text{SME}(p), which represents the set of minimal true prefixes (an antichain2 fo finite σ\sigma with p1p \equiv 1 on [σ][\sigma]). Topologically, the preimage U=p1(1)U = p^{-1}(1) (which represents the set of satsifying assignments) can be expressed as the following disjoint union of cylinders

U=σF[σ] U = \bigcup_{\sigma \in \cal{F}} [\sigma]
Geometric Intuition

Imagine each prefix σ\sigma as carving out a subcube (cylinder set) of all points that agree with σ\sigma. Then taking the union fills up the region where U=p1(1)U = p^{-1} (1). By compactness, there is always a finite subcover but our algorithm refines this so that they are also disjoint.

examples

-- fib-eventually (7 cylinders)

\x -> any (\f -> f < 30 && x f) (takeWhile (< 30) fibonacci)

This checks: “Does the infinite binary sequence x have True at any Fibonacci position < 30?”

The 7 cylinders represent the minimal decision tree:

-- prime-eventually (8 cylinders)

\x -> any (\p -> p < 20 && x p) (takeWhile (< 20) primes)

This computes primes on-demand from primes = filter isPrime [2..] (infinite list), then checks if x is True at any prime position < 20. The 8 cylinders correspond to checking positions 2, 3, 5, 7, 11, 13, 17, 19 in sequence.

-- collatz-reaches-1 (942 cylinders!)

\x -> let collatz n = if even n then n `div` 2 else 3*n+1
        orbit n = takeWhile (/= 1) (iterate collatz n)
    in length (orbit (sum [i | i <- [0..9], x i] + 1)) < 50

Again expanding this gives us:

  1. Takes first 10 bits of x, sums the indices where x[i] = True, adds 1
  2. Computes the Collatz orbit of that number (3n+13n+1 conjecture)
  3. Checks if the orbit reaches 1 in < 50 steps

Certain predicates over infinite sequences can be decided by examining only finite prefixes, and algorithms like sme can discover these finite characterizations. I wonder if there is something interesting in representing this as finite automata. In the next blog, we’ll go into some implications of introducing Randomness.

Footnotes

  1. I came across this blog on Schrodinger’s equation when trying to come up with the intro, it seems pretty interesting.

  2. Each finite prefix σ:FB\sigma: F \rightarrow \mathbb{B} (where FF is the local modulus of continuity3) defines a cylinder set [σ]={xBNxF=σ}[\sigma] = \{x \in \mathbb{B}^\mathbb{N} | x|_F = \sigma\}. If a new finite prefix τ\tau extends σ\sigma, then [τ][σ][\tau] \subseteq [\sigma]. A small exercise is to prove that there si no way for two distinct prefixes two be returned. Consequently, {σ}\{ \sigma \} defiens an antichain under this extension order. Algorithmically, this is enforced by minimality and early stopping.

  3. Recursive footnoting is surely a crime somewhere. Anyways, for every infintie stream xBNx \in \mathbb{B}^\mathbb{N}, there exists some finite set of indices such that for FxNF_x \subseteq \mathbb{N} if yy is another sream and y(i)=x(i)y(i) = x(i) for all iFxi \in F_x, then p(y)=p(x)p(y) = p(x). It is essentially the collection of coordinates of xx that pp actualy looks at when deciding its value at xx.


← Back to posts