5 | module Search.Tychonoff.PartI
9 | import Data.Nat.Order
12 | import Decidable.Equality
13 | import Decidable.Decidable
24 | 0 Decidable : Pred a -> Type
25 | Decidable p = (x : a) -> Dec (p x)
32 | 0 HilbertEpsilon : Pred x -> Type
33 | HilbertEpsilon p = (v : x ** (v0 : x) -> p v0 -> p v)
39 | 0 IsSearchable : Type -> Type
40 | IsSearchable x = (0 p : Pred x) -> Decidable p -> HilbertEpsilon p
43 | record (<->) (a, b : Type) where
47 | inverseL : (x : a) -> backwards (forwards x) === x
48 | inverseR : (y : b) -> forwards (backwards y) === y
51 | map : (a <-> b) -> IsSearchable a -> IsSearchable b
52 | map (MkIso f g _ inv) search p pdec =
53 | let (
xa ** prfa)
= search (p . f) (\ x => pdec (f x)) in
54 | (
f xa ** \ xb, pxb => prfa (g xb) $
replace {p} (sym $
inv xb) pxb)
56 | interface Searchable (0 a : Type) where
57 | constructor MkSearchable
58 | search : IsSearchable a
60 | Inhabited : Type -> Type
63 | searchableIsInhabited : IsSearchable a -> Inhabited a
64 | searchableIsInhabited search = fst (search (\ _ => ()) (\ _ => Yes ()))
70 | search p pdef = (
() ** \ (), prf => prf)
73 | Searchable Bool where
74 | search p pdec = case pdec True of
76 | Yes prf => MkDPair True $
\ _, _ => prf
78 | No contra => MkDPair False $
\case
80 | True => absurd . contra
85 | (Searchable a, Searchable b) => Searchable (Either a b) where
87 | let (
xa ** prfa)
= search (p . Left) (\ xa => pdec (Left xa)) in
88 | let (
xb ** prfb)
= search (p . Right) (\ xb => pdec (Right xb)) in
89 | case pdec (Left xa) of
90 | Yes pxa => (
Left xa ** \ _, _ => pxa)
91 | No npxa => case pdec (Right xb) of
92 | Yes pxb => (
Right xb ** \ _, _ => pxb)
93 | No npxb => MkDPair (Left xa) $
\case
94 | Left xa' => \ pxa' => absurd (npxa (prfa xa' pxa'))
95 | Right xb' => \ pxb' => absurd (npxb (prfb xb' pxb'))
98 | (Searchable a, Searchable b) => Searchable (a, b) where
101 | let (
fb ** prfb)
= Pair.choice $
\ a => search (p . (a,)) (\ b => pdec (a, b)) in
102 | let (
xa ** prfa)
= search (\ a => p (a, fb a)) (\ xa => pdec (xa, fb xa)) in
103 | MkDPair (xa, fb xa) $
\ (xa', xb'), pxab' => prfa xa' (prfb xa' xb' pxab')
107 | searchVect : Searchable a => (n : Nat) -> Searchable (Vect n a)
108 | searchVect 0 = MkSearchable $
\ p, pdec => (
[] ** \case [] => id)
109 | searchVect (S n) = MkSearchable $
\ p, pdec =>
110 | let %hint ih : Searchable (Vect n a)
112 | 0 P : Pred (a, Vect n a)
113 | P = p . Prelude.uncurry (::)
115 | Pdec = \ (x, xs) => pdec (x :: xs)
116 | in bimap (uncurry (::)) (\ prf => \case (v0 :: vs0) => prf (v0, vs0))
120 | 0 LPO : Type -> Type
121 | LPO a = (f : a -> Bool) ->
122 | Either (x : a ** f x === True) ((x : a) -> f x === False)
124 | 0 LPO' : Type -> Type
125 | LPO' a = (0 p : Pred a) -> Decidable p ->
126 | Either (x : a ** p x) ((x : a) -> Not (p x))
128 | SearchableIsLPO : IsSearchable a -> LPO' a
129 | SearchableIsLPO search p pdec =
130 | let (
x ** prf)
= search p pdec in
132 | Yes px => Left (
x ** px)
133 | No npx => Right (\ x', px' => absurd (npx (prf x' px')))
135 | LPOIsSearchable : LPO' a -> Inhabited a -> IsSearchable a
136 | LPOIsSearchable lpo inh p pdec = case lpo p pdec of
137 | Left (
x ** px)
=> (
x ** \ _, _ => px)
138 | Right contra => (
inh ** \ x, px => absurd (contra x px))
140 | EqUntil : (m : Nat) -> (a, b : Nat -> x) -> Type
141 | EqUntil m a b = (k : Nat) -> k `LTE` m -> a k === b k
148 | Decreasing : (Nat -> Bool) -> Type
149 | Decreasing f = (n : Nat) -> So (f (S n)) -> So (f n)
152 | record NatInf where
153 | constructor MkNatInf
154 | sequence : Nat -> Bool
155 | isDecreasing : Decreasing sequence
157 | repeat : x -> (Nat -> x)
161 | Zero = MkNatInf (repeat False) (\ n, prf => prf)
164 | Omega = MkNatInf (repeat True) (\ n, prf => prf)
166 | (::) : x -> (Nat -> x) -> (Nat -> x)
168 | (v :: f) (S n) = f n
170 | Succ : NatInf -> NatInf
171 | Succ f = MkNatInf (True :: f .sequence) decr where
173 | decr : Decreasing (True :: f .sequence)
175 | decr (S n) = f .isDecreasing n
177 | fromNat : Nat -> NatInf
179 | fromNat (S k) = Succ (fromNat k)
181 | soFromNat : k `LT` n -> So ((fromNat n) .sequence k)
182 | soFromNat p = case view p of
184 | LTSucc p => soFromNat p
186 | fromNatSo : {k, n : Nat} -> So ((fromNat n) .sequence k) -> k `LT` n
187 | fromNatSo {n = 0} hyp = absurd hyp
188 | fromNatSo {k = 0} {n = S n} hyp = LTESucc LTEZero
189 | fromNatSo {k = S k} {n = S n} hyp = LTESucc (fromNatSo hyp)
191 | LTE : (f, g : NatInf) -> Type
192 | f `LTE` g = (n : Nat) -> So (f .sequence n) -> So (g .sequence n)
194 | minimalZ : (f : NatInf) -> fromNat 0 `LTE` f
195 | minimalZ f n prf = absurd prf
197 | maximalInf : (f : NatInf) -> f `LTE` Omega
198 | maximalInf f n prf = Oh
200 | min : (f, g : NatInf) -> NatInf
201 | min (MkNatInf f prf) (MkNatInf g prg)
202 | = MkNatInf (\ n => f n && g n) $
\ n, prfg =>
203 | let (l, r) = soAnd prfg in
204 | andSo (prf n l, prg n r)
206 | minLTE : (f, g : NatInf) -> min f g `LTE` f
207 | minLTE (MkNatInf f prf) (MkNatInf g prg) n pr = fst (soAnd pr)
209 | max : (f, g : NatInf) -> NatInf
210 | max (MkNatInf f prf) (MkNatInf g prg)
211 | = MkNatInf (\ n => f n || g n) $
\ n, prfg =>
212 | orSo $
case soOr prfg of
213 | Left pr => Left (prf n pr)
214 | Right pr => Right (prg n pr)
216 | maxLTE : (f, g : NatInf) -> f `LTE` max f g
217 | maxLTE (MkNatInf f prf) (MkNatInf g prg) n pr = orSo (Left pr)
219 | record ClosenessFunction (0 x : Type) (c : (v, w : x) -> NatInf) where
220 | constructor MkClosenessFunction
221 | selfClose : (v : x) -> c v v === Omega
222 | closeSelf : (v, w : x) -> c v w === Omega -> v === w
223 | symmetric : (v, w : x) -> c v w === c w v
224 | ultrametic : (u, v, w : x) -> min (c u v) (c v w) `LTE` c u w
230 | Discrete : Type -> Type
233 | dc : Discrete x => (v, w : x) -> NatInf
234 | dc v w = ifThenElse (isYes $
decEq v w) Omega Zero
236 | dcIsClosenessFunction : Discrete x => ClosenessFunction x PartI.dc
237 | dcIsClosenessFunction
238 | = MkClosenessFunction selfClose closeSelf symmetric ultrametric
242 | selfClose : (v : x) -> dc v v === Omega
243 | selfClose v with (decEq v v)
245 | _ | No npr = absurd (npr Refl)
247 | closeSelf : (v, w : x) -> dc v w === Omega -> v === w
248 | closeSelf v w eq with (decEq v w)
250 | _ | No npr = absurd (cong (($
0) . sequence) eq)
252 | symmetric : (v, w : x) -> dc v w === dc w v
253 | symmetric v w with (decEq v w)
254 | symmetric v v | Yes Refl = rewrite decEqSelfIsYes {x = v} in Refl
255 | _ | No nprf with (decEq w v)
256 | _ | Yes prf = absurd (nprf (sym prf))
259 | ultrametric : (u, v, w : x) -> min (dc u v) (dc v w) `LTE` dc u w
260 | ultrametric u v w n with (decEq u w)
261 | _ | Yes r = const Oh
262 | _ | No nr with (decEq u v)
263 | _ | Yes p with (decEq v w)
264 | _ | Yes q = absurd (nr (trans p q))
266 | _ | No np with (decEq v w)
274 | decEqUntil : Discrete x => (n : Nat) -> (f, g : Nat -> x) -> Dec (EqUntil n f g)
275 | decEqUntil n f g = decideLTEBounded (\ n => decEq (f n) (g n)) n
277 | fromYes : (d : Dec p) -> isYes d === True -> p
278 | fromYes (Yes prf) _ = prf
281 | Discrete x => (n : Nat) -> (f, g : Nat -> x) ->
282 | isYes (decEqUntil (S n) f g) === True ->
283 | isYes (decEqUntil n f g) === True
284 | decEqUntilPred n f g eq with (decEqUntil n f g)
286 | _ | No nprf = let prf = fromYes (decEqUntil (S n) f g) eq in
287 | absurd (nprf $
\ l, bnd => prf l (lteSuccRight bnd))
290 | dsc : Discrete x => (f, g : Nat -> x) -> NatInf
291 | dsc f g = (MkNatInf Meas decr) where
294 | Meas = \ n => (ifThenElse (isYes $
decEqUntil n f g) Omega Zero) .sequence n
296 | decr : Decreasing Meas
297 | decr n with (decEqUntil (S n) f g) proof eq
298 | _ | Yes eqSn = rewrite decEqUntilPred n f g (cong isYes eq) in id
299 | _ | No neqSn = \case prf impossible
301 | interface IsSubSingleton x where
302 | isSubSingleton : (v, w : x) -> v === w
304 | IsSubSingleton Void where
305 | isSubSingleton p q = absurd p
307 | IsSubSingleton () where
308 | isSubSingleton () () = Refl
310 | (IsSubSingleton a, IsSubSingleton b) => IsSubSingleton (a, b) where
311 | isSubSingleton (p,q) (u,v) = cong2 (,) (isSubSingleton p u) (isSubSingleton q v)
313 | IsSubSingleton (So b) where
314 | isSubSingleton Oh Oh = Refl
317 | IsSubSingleton (v === w) where
318 | isSubSingleton Refl Refl = Refl
320 | 0 (~~~) : {0 b : a -> Type} -> (f, g : (x : a) -> b x) -> Type
321 | f ~~~ g = (x : a) -> f x === g x
323 | 0 ExtensionalEquality : Type
324 | ExtensionalEquality
325 | = {0 a : Type} -> {0 b : a -> Type} ->
326 | {f, g : (x : a) -> b x} ->
329 | interface Extensionality where
330 | functionalExt : ExtensionalEquality
332 | {0 p : a -> Type} ->
334 | ((x : a) -> IsSubSingleton (p x)) =>
335 | IsSubSingleton ((x : a) -> p x) where
336 | isSubSingleton v w = functionalExt (\ x => isSubSingleton (v x) (w x))
339 | Extensionality => IsSubSingleton p => IsSubSingleton (Dec p) where
340 | isSubSingleton (Yes p) (Yes q) = cong Yes (isSubSingleton p q)
341 | isSubSingleton (Yes p) (No nq) = absurd (nq p)
342 | isSubSingleton (No np) (Yes q) = absurd (np q)
343 | isSubSingleton (No np) (No nq) = cong No (isSubSingleton np nq)
345 | parameters {auto _ : Extensionality}
347 | seqEquals : {f, g : Nat -> x} -> f ~~~ g -> f === g
348 | seqEquals = functionalExt
350 | decEqUntilSelfIsYes : Discrete x => (n : Nat) -> (f : Nat -> x) ->
351 | decEqUntil n f f === Yes (\ k, bnd => Refl)
352 | decEqUntilSelfIsYes n f = isSubSingleton ? ?
354 | NatInfEquals : {f, g : Nat -> Bool} ->
355 | {fdecr : Decreasing f} ->
356 | {gdecr : Decreasing g} ->
357 | f ~~~ g -> MkNatInf f fdecr === MkNatInf g gdecr
358 | NatInfEquals {f} eq with (seqEquals eq)
359 | _ | Refl = cong (MkNatInf f) (isSubSingleton ? ?
)
361 | dscIsClosenessFunction : Discrete x => ClosenessFunction (Nat -> x) PartI.dsc
362 | dscIsClosenessFunction {x}
363 | = MkClosenessFunction
365 | (\ v, w, eq => seqEquals (closeSelf v w eq))
366 | (\ v, w => NatInfEquals (symmetric v w))
371 | selfClose : (v : Nat -> x) -> dsc v v === Omega
372 | selfClose v = NatInfEquals $
\ n => rewrite decEqUntilSelfIsYes n v in Refl
374 | closeSelf : (v, w : Nat -> x) -> dsc v w === Omega -> v ~~~ w
375 | closeSelf v w eq n with (cong (\ f => f .sequence n) eq)
376 | _ | prf with (decEqUntil n v w)
377 | _ | Yes eqn = eqn n reflexive
378 | _ | No neqn = absurd prf
380 | symmetric : (v, w : Nat -> x) -> (dsc v w) .sequence ~~~ (dsc w v) .sequence
381 | symmetric v w n with (decEqUntil n v w)
382 | _ | Yes p with (decEqUntil n w v)
384 | _ | No nq = absurd (nq $
\ k, bnd => sym (p k bnd))
385 | _ | No np with (decEqUntil n w v)
386 | _ | Yes q = absurd (np $
\ k, bnd => sym (q k bnd))
389 | ultrametric : (u, v, w : Nat -> x) -> min (dsc u v) (dsc v w) `LTE` dsc u w
390 | ultrametric u v w n with (decEqUntil n u w)
391 | _ | Yes r = const Oh
392 | _ | No nr with (decEqUntil n u v)
393 | _ | Yes p with (decEqUntil n v w)
394 | _ | Yes q = absurd (nr (\ k, bnd => trans (p k bnd) (q k bnd)))
396 | _ | No np with (decEqUntil n v w)
400 | closeImpliesEqUntil : Discrete x =>
401 | (n : Nat) -> (f, g : Nat -> x) ->
402 | fromNat (S n) `LTE` dsc f g ->
404 | closeImpliesEqUntil n f g prf with (prf n)
405 | _ | prfn with (decEqUntil n f g)
407 | _ | No neqn = absurd (prfn (soFromNat reflexive))
409 | eqUntilImpliesClose : Discrete x =>
410 | (n : Nat) -> (f, g : Nat -> x) ->
412 | fromNat (S n) `LTE` dsc f g
413 | eqUntilImpliesClose n f g prf k hyp with (decEqUntil k f g)
415 | _ | No np = let klten = fromLteSucc $
fromNatSo {k} {n = S n} hyp in
416 | absurd (np $
\ k', bnd => prf k' (transitive bnd klten))
418 | buildUp : Discrete x => (n : Nat) -> (f, g : Nat -> x) ->
419 | fromNat n `LTE` dsc f g ->
421 | fromNat (S n) `LTE` dsc (v :: f) (v :: g)
422 | buildUp n f g hyp v
423 | = eqUntilImpliesClose n (v :: f) (v :: g)
424 | $
\ k, bnd => case bnd of
426 | LTESucc bnd => closeImpliesEqUntil ?
f g hyp ?
bnd
428 | head : (Nat -> x) -> x
431 | tail : (Nat -> x) -> (Nat -> x)
434 | parameters {auto _ : Extensionality}
436 | eta : (f : Nat -> x) -> f === head f :: tail f
437 | eta f = functionalExt $
\case
449 | 0 IsUModFor : (c : (v, w : x) -> NatInf) -> (p : Pred x) -> (mod : Nat) -> Type
450 | IsUModFor c p mod = (v, w : x) -> fromNat mod `LTE` c v w -> p v -> p w
455 | record UContinuous {0 x : Type} (c : (v, w : x) -> NatInf) (p : Pred x) where
458 | isUModFor : IsUModFor c p uModulus
466 | 0 IsCSearchable : (x : Type) -> ((v, w : x) -> NatInf) -> Type
468 | = (0 p : Pred x) -> UContinuous c p -> Decidable p ->
471 | interface CSearchable x (0 c : (v, w : x) -> NatInf) where
472 | csearch : IsCSearchable x c
474 | [DEMOTE] Searchable x => CSearchable x c where
475 | csearch p uc pdec = search p pdec
477 | CSearchable Bool (PartI.dc {x = Bool}) where
478 | csearch = csearch @{DEMOTE}
480 | discreteIsUContinuous :
481 | {0 p : Pred x} -> Discrete x =>
482 | Decidable p -> UContinuous PartI.dc p
483 | discreteIsUContinuous pdec = MkUC 1 isUContinuous where
485 | isUContinuous : IsUModFor PartI.dc p 1
486 | isUContinuous v w hyp pv with (decEq v w)
487 | _ | Yes eq = replace {p} eq pv
488 | _ | No neq = absurd (hyp 0 Oh)
490 | [PROMOTE] Discrete x => CSearchable x PartI.dc => Searchable x where
491 | search p pdec = csearch p (discreteIsUContinuous pdec) pdec
501 | Decidable p -> IsUModFor c p 0 ->
502 | (v : x ** p v) -> (v : x) -> p v
503 | nullModHilbert pdec pmod0 (
v0 ** pv0)
v = pmod0 v0 v (\ n => absurd) pv0
505 | trivial : UContinuous c (const ())
506 | trivial = MkUC 0 (\ _, _, _, _ => ())
511 | 0 tailPredicate : Pred (Nat -> x) -> x -> Pred (Nat -> x)
512 | tailPredicate p v = p . (v ::)
515 | {0 p : Pred (Nat -> x)}
516 | {auto _ : Discrete x}
517 | (pdec : Decidable p)
519 | decTail : (v : x) -> Decidable (tailPredicate p v)
520 | decTail v vs = pdec (v :: vs)
523 | (mod : Nat) -> IsUModFor PartI.dsc p (S mod) ->
524 | (v : x) -> IsUModFor PartI.dsc (tailPredicate p v) mod
525 | predModTail mod hyp v f g prf pvf
526 | = hyp (v :: f) (v :: g) (buildUp mod f g prf v) pvf
528 | [BYUCONTINUITY] Extensionality =>
530 | CSearchable x PartI.dc =>
531 | CSearchable (Nat -> x) (PartI.dsc {x}) where
532 | csearch q quni qdec
533 | = go (search @{PROMOTE})
540 | go : IsSearchable x ->
541 | {0 p : Pred (Nat -> x)} -> Decidable p ->
542 | (n : Nat) -> IsUModFor PartI.dsc p n ->
545 | = let f = const (searchableIsInhabited s) in
546 | MkDPair f (\ v0, pv0 => nullModHilbert {c = dsc} pdec hyp (
v0 ** pv0)
f)
547 | go s pdec (S mod) hyp
549 | stepping : x -> (Nat -> x)
550 | stepping i = fst (go s (decTail pdec i) mod (predModTail pdec mod hyp i))
553 | PH = \ v => p (v :: stepping v)
554 | pHdec : Decidable PH
555 | pHdec = \ v => pdec (v :: stepping v)
556 | sH : HilbertEpsilon PH
559 | 0 PT : x -> Pred (Nat -> x)
560 | PT i = tailPredicate p i
561 | pTdec : (v : x) -> Decidable (PT v)
562 | pTdec i = decTail pdec i
563 | sT : (v : x) -> HilbertEpsilon (PT v)
564 | sT i = go s (pTdec i) mod (predModTail pdec mod hyp i)
567 | vs : Nat -> x;
vs = (sT v) .fst
568 | in MkDPair (v :: vs) $
\ vv0s, pvv0s =>
569 | let v0 : x;
v0 = head vv0s
570 | v0s : Nat -> x;
v0s = tail vv0s
573 | $
replace {p} (eta vv0s) pvv0s
575 | cantorIsCSearchable : Extensionality => IsCSearchable (Nat -> Bool) PartI.dsc
576 | cantorIsCSearchable = csearch @{BYUCONTINUITY}