Zulip Chat Archive
Stream: general
Topic: Defining general recursive functions on their domains
Trebor Huang (May 28 2023 at 14:48):
Given an arbitrary general recursive function, how can we (1) define the domain on which it is total, and (2) define the function as a PFun
? Here's my method which is in theory generally workable:
/-
To define a function
f(0) = f(1) = 0
f(n) = f(n/2) + 1 for n even
f(n) = f(3*n+1) + 1 for n odd
But we don't know whether it is total yet. Can we
define f as a `PFun`? To do that, we need a
predicate for its domain.
-/
inductive Domain : Nat → Prop
| zero : Domain 0
| one : Domain 1
-- We can have cycles here, eg.
-- even : Domain n → Domain (2*n)
-- But this is slightly cleaner.
| even : Domain (n+1) → Domain (2*n+2)
| odd : Domain (6*n+10) → Domain (2*n+3)
/-
If we define `Domain` as a Type, then it is
known as the Bove–Capretta predicate, and we can
happily recurse along that, giving
f (n : Nat) : Domain n → Nat
And if one day we manage to prove ∀ n, Domain n
then we can get the total function.
-/
inductive Prec : Nat → Nat → Prop
| even : Prec (n+1) (2*n+2)
| odd : Prec (6*n+10) (2*n+3)
| trans : Prec m n → Prec n p → Prec m p
def Prec' (u v : Subtype Domain) : Prop := Prec u.val v.val
/- Mostly just do the obvious thing, induction
on `Prec` is now available because we are proving
a `Prop` too. -/
theorem WfPrec' : WellFounded Prec' := sorry
Now we just do well-founded recursion, giving Subtype Domain -> Nat
, which can then be converted to a PFun
. Is there a neater way to do this? And can this be fully automated?
Eric Wieser (May 28 2023 at 19:32):
Can you write a sorry
for your PFun
question?
Eric Wieser (May 28 2023 at 19:33):
It's not clear to me what you're asking for
Trebor Huang (May 29 2023 at 01:22):
Trebor Huang (May 29 2023 at 01:24):
After looking at the library I think the current fastest way is to write it as a fixpoint, then using PFun.fix
Last updated: Dec 20 2023 at 11:08 UTC