Zulip Chat Archive
Stream: maths
Topic: Induction principle for well-founded recursion definition
Heather Macbeth (Mar 05 2023 at 21:39):
When you make a definition by well-founded recursion, is there a way to auto-generate an induction principle for it?
For example, the following definition is made by well-founded recursion (it moves strictly forward according to the default SizeOf
instance on Nat × Nat
, namely SizeOf.sizeOf (a, b) = 1 + a + b
):
def Pascal : Nat × Nat → Nat
| (0, _) => 1
| (_, 0) => 1
| (a + 1, b + 1) => Pascal (a + 1, b) + Pascal (a, b + 1)
Is there a way to generate the following induction principle for free: if P : Nat × Nat → Nat → Prop
is some family of predicates, true in the right base cases, and also if we have we have the right inductive hypothesis (it's complicated but approximately
if we have assigned Nat values to everything less than
(a.succ, b.succ)
as specified by a functionA : ∀ y : Nat × Nat, sizeOf y < sizeOf (a.succ, b.succ) → Nat
, and they all satisfyP
for the right inputs, then the assignation of a Nat value according to the induction rule for(a.succ, b.succ)
will also satisfyP
for the right inputs
) then the statement is true for P (a, b) (Pascal (a, b))
for all (a, b)
?
open SizeOf
theorem lt_left {a b : Nat} : sizeOf (a, b) < sizeOf (a.succ, b) :=
Nat.add_lt_add_right (Nat.add_lt_add_left a.lt_succ_self _) _
theorem lt_right {a b : Nat} : sizeOf (a, b) < sizeOf (a, b.succ) :=
Nat.add_lt_add_left b.lt_succ_self _
theorem Pascal.rec {P : Nat × Nat → Nat → Prop} (hP1 : ∀ j, P (0, j) 1) (hP2 : ∀ i, P (i, 0) 1)
(hP : ∀ a b,
∀ (A : ∀ y : Nat × Nat, sizeOf y < sizeOf (a.succ, b.succ) → Nat),
(∀ (y : Nat × Nat) (hy : sizeOf y < sizeOf (a.succ, b.succ)), P y (A y hy))
→ P (a.succ, b.succ) ((A (a.succ, b) lt_right) + (A (a, b.succ) lt_left)))
(x : Nat × Nat) :
P x (Pascal x) :=
sorry
Anne Baanen (Mar 06 2023 at 09:56):
My first idea is to turn the inductive definition of Pascal
into an inductive relation:
inductive PascalRel : Nat → Nat → Nat → Prop
| zero_left {b} : PascalRel 0 b 1
| zero_right {a} : PascalRel a 0 1
| succ_succ {a b m n} : PascalRel (a + 1) b m → PascalRel a (b + 1) n → PascalRel (a + 1) (b + 1) (m + n)
Wouldn't the induction principle for PascalRel
be exactly what you are looking for?
Anne Baanen (Mar 06 2023 at 10:01):
Looking at #print PascalRel.rec
we'd need to do some rewriting (namely by using PascalRel a b n ↔ n = Pascal a b
), but I think it's close to what you're looking for.
recursor PascalRel.rec : ∀ {motive : (a a_1 a_2 : Nat) → PascalRel a a_1 a_2 → Prop},
(∀ {b : Nat}, motive 0 b 1 (_ : PascalRel 0 b 1)) →
(∀ {a : Nat}, motive a 0 1 (_ : PascalRel a 0 1)) →
(∀ {a b m n : Nat} (a_1 : PascalRel (a + 1) b m) (a_2 : PascalRel a (b + 1) n),
motive (a + 1) b m a_1 →
motive a (b + 1) n a_2 → motive (a + 1) (b + 1) (m + n) (_ : PascalRel (a + 1) (b + 1) (m + n))) →
∀ {a a_1 a_2 : Nat} (t : PascalRel a a_1 a_2), motive a a_1 a_2 t
Last updated: Dec 20 2023 at 11:08 UTC