blob: 924036e16e3e7e4f31018cdbcaa5e3053ee4e5d2 [file] [edit]
/-
Copyright (c) 2023 Miyahara Kō. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Miyahara Kō
-/
module
prelude
public import Init.WF
import Init.NotationExtra
import Init.WFTactics
/-!
# Computable Acc.rec and WellFounded.fix
This file adds csimp theorems so that the compiler will be able to compile
`Acc.rec`, `WellFounded.fix` and related operations.
Without this change, the following code will fail to compile as
`WellFounded.fix` is noncomputable.
```
def log2p1 : Nat → Nat :=
WellFounded.fix Nat.lt_wfRel.2 fun n IH =>
let m := n / 2
if h : m < n then
IH m h + 1
else
0
```
-/
namespace Acc
public instance wfRel {r : α → α → Prop} : WellFoundedRelation { val // Acc r val } where
rel := InvImage r (·.1)
wf := ⟨fun ac => InvImage.accessible _ ac.2⟩
/-- A computable version of `Acc.rec`. -/
@[specialize, elab_as_elim] public def recC {motive : (a : α) → Acc r a → Sort v}
(intro : (x : α) → (h : ∀ (y : α), r y x → Acc r y) →
((y : α) → (hr : r y x) → motive y (h y hr)) → motive x (intro x h))
{a : α} (t : Acc r a) : motive a t :=
intro a (fun _ h => t.inv h) (fun _ hr => recC intro (t.inv hr))
termination_by Subtype.mk a t
@[csimp] public theorem rec_eq_recC : @Acc.rec = @Acc.recC := by
funext α r motive intro a t
induction t with
| intro x h ih =>
rw [recC]
dsimp only
congr; funext y hr; exact ih _ hr
/-- A computable version of `Acc.ndrec`. -/
@[inline] public abbrev ndrecC {C : α → Sort v}
(m : (x : α) → ((y : α) → r y x → Acc r y) → ((y : α) → (a : r y x) → C y) → C x)
{a : α} (n : Acc r a) : C a :=
n.recC m
@[csimp] public theorem ndrec_eq_ndrecC : @Acc.ndrec = @Acc.ndrecC := by
funext α r motive intro a t
rw [Acc.ndrec, rec_eq_recC, Acc.ndrecC]
/-- A computable version of `Acc.ndrecOn`. -/
@[inline] public abbrev ndrecOnC {C : α → Sort v} {a : α} (n : Acc r a)
(m : (x : α) → ((y : α) → r y x → Acc r y) → ((y : α) → r y x → C y) → C x) : C a :=
n.recC m
@[csimp] public theorem ndrecOn_eq_ndrecOnC : @Acc.ndrecOn = @Acc.ndrecOnC := by
funext α r motive intro a t
rw [Acc.ndrecOn, rec_eq_recC, Acc.ndrecOnC]
end Acc
namespace WellFounded
/-- A computable version of `WellFounded.fixF`. -/
@[inline] public def fixFC {α : Sort u} {r : α → α → Prop}
{C : α → Sort v} (F : ∀ x, (∀ y, r y x → C y) → C x) (x : α) (a : Acc r x) : C x := by
induction a using Acc.recC with
| intro x₁ _ ih => exact F x₁ ih
@[csimp] public theorem fixF_eq_fixFC : @fixF = @fixFC := by
funext α r C F x a
rw [fixF, Acc.rec_eq_recC, fixFC]
/-- A computable version of `fix`. -/
@[specialize] public def fixC {α : Sort u} {C : α → Sort v} {r : α → α → Prop}
(hwf : WellFounded r) (F : ∀ x, (∀ y, r y x → C y) → C x) (x : α) : C x :=
F x (fun y _ => fixC hwf F y)
termination_by hwf.wrap x
unseal fixC
@[csimp] public theorem fix_eq_fixC : @fix = @fixC := by
rfl
end WellFounded