lean4-htt/library/init/wf.lean
2016-09-23 17:36:32 -07:00

194 lines
6.8 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/-
Copyright (c) 2014 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Author: Leonardo de Moura
-/
prelude
import init.relation init.nat init.prod
universe variables u v
inductive acc {A : Type u} (r : A → A → Prop) : A → Prop
| intro : ∀ x, (∀ y, r y x → acc y) → acc x
namespace acc
variables {A : Type u} {r : A → A → Prop}
definition inv {x y : A} (h₁ : acc r x) (h₂ : r y x) : acc r y :=
acc.rec_on h₁ (λ x₁ ac₁ ih h₂, ac₁ y h₂) h₂
-- dependent elimination for acc
attribute [recursor]
protected definition drec
{C : Π (a : A), acc r a → Type v}
(h₁ : Π (x : A) (acx : Π (y : A), r y x → acc r y), (Π (y : A) (ryx : r y x), C y (acx y ryx)) → C x (acc.intro x acx))
{a : A} (h₂ : acc r a) : C a h₂ :=
acc.rec (λ x acx ih h₂, h₁ x acx (λ y ryx, ih y ryx (acx y ryx))) h₂ h₂
end acc
inductive well_founded {A : Type u} (r : A → A → Prop) : Prop
| intro : (∀ a, acc r a) → well_founded
namespace well_founded
definition apply {A : Type u} {r : A → A → Prop} (wf : well_founded r) : ∀ a, acc r a :=
take a, well_founded.rec_on wf (λ p, p) a
section
parameters {A : Type u} {r : A → A → Prop}
local infix `≺`:50 := r
hypothesis hwf : well_founded r
theorem recursion {C : A → Type v} (a : A) (h : Π x, (Π y, y ≺ x → C y) → C x) : C a :=
acc.rec_on (apply hwf a) (λ x₁ ac₁ ih, h x₁ ih)
theorem induction {C : A → Prop} (a : A) (h : ∀ x, (∀ y, y ≺ x → C y) → C x) : C a :=
recursion a h
variable {C : A → Type v}
variable F : Π x, (Π y, y ≺ x → C y) → C x
definition fix_F (x : A) (a : acc r x) : C x :=
acc.rec_on a (λ x₁ ac₁ ih, F x₁ ih)
theorem fix_F_eq (x : A) (r : acc r x) :
fix_F F x r = F x (λ (y : A) (p : y ≺ x), fix_F F y (acc.inv r p)) :=
acc.drec (λ x r ih, rfl) r
end
variables {A : Type u} {C : A → Type v} {r : A → A → Prop}
-- Well-founded fixpoint
definition fix (hwf : well_founded r) (F : Π x, (Π y, r y x → C y) → C x) (x : A) : C x :=
fix_F F x (apply hwf x)
-- Well-founded fixpoint satisfies fixpoint equation
theorem fix_eq (hwf : well_founded r) (F : Π x, (Π y, r y x → C y) → C x) (x : A) :
fix hwf F x = F x (λ y h, fix hwf F y) :=
fix_F_eq F x (apply hwf x)
end well_founded
open well_founded
-- Empty relation is well-founded
definition empty_wf {A : Type u} : well_founded empty_relation :=
well_founded.intro (λ (a : A),
acc.intro a (λ (b : A) (lt : false), false.rec _ lt))
-- Subrelation of a well-founded relation is well-founded
namespace subrelation
section
parameters {A : Type u} {r Q : A → A → Prop}
parameters (h₁ : subrelation Q r)
parameters (h₂ : well_founded r)
definition accessible {a : A} (ac : acc r a) : acc Q a :=
acc.rec_on ac (λ x ax ih,
acc.intro x (λ (y : A) (lt : Q y x), ih y (h₁ lt)))
definition wf : well_founded Q :=
⟨λ a, accessible (apply h₂ a)⟩
end
end subrelation
-- The inverse image of a well-founded relation is well-founded
namespace inv_image
section
parameters {A : Type u} {B : Type v} {r : B → B → Prop}
parameters (f : A → B)
parameters (h : well_founded r)
private definition acc_aux {b : B} (ac : acc r b) : ∀ (x : A), f x = b → acc (inv_image r f) x :=
acc.rec_on ac (λ x acx ih z e,
acc.intro z (λ y lt, eq.rec_on e (λ acx ih, ih (f y) lt y rfl) acx ih))
definition accessible {a : A} (ac : acc r (f a)) : acc (inv_image r f) a :=
acc_aux ac a rfl
definition wf : well_founded (inv_image r f) :=
⟨λ a, accessible (apply h (f a))⟩
end
end inv_image
-- The transitive closure of a well-founded relation is well-founded
namespace tc
section
parameters {A : Type u} {r : A → A → Prop}
local notation `r⁺` := tc r
definition accessible {z : A} (ac : acc r z) : acc (tc r) z :=
acc.rec_on ac (λ x acx ih,
acc.intro x (λ y rel,
tc.rec_on rel
(λ a b rab acx ih, ih a rab)
(λ a b c rab rbc ih₁ ih₂ acx ih, acc.inv (ih₂ acx ih) rab)
acx ih))
definition wf (h : well_founded r) : well_founded r⁺ :=
⟨λ a, accessible (apply h a)⟩
end
end tc
-- less-than is well-founded
definition nat.lt_wf : well_founded nat.lt :=
⟨nat.rec
(acc.intro 0 (λ n h, absurd h (nat.not_lt_zero n)))
(λ n ih, acc.intro (nat.succ n) (λ m h,
or.elim (nat.eq_or_lt_of_le (nat.le_of_succ_le_succ h))
(λ e, eq.substr e ih) (acc.inv ih)))⟩
definition measure {A : Type u} : (A → ) → A → A → Prop :=
inv_image lt
definition measure_wf {A : Type u} (f : A → ) : well_founded (measure f) :=
inv_image.wf f nat.lt_wf
namespace prod
open well_founded
section
variables {A : Type u} {B : Type v}
variable (ra : A → A → Prop)
variable (rb : B → B → Prop)
-- Lexicographical order based on ra and rb
inductive lex : A × B → A × B → Prop
| left : ∀ {a₁ b₁} a₂ b₂, ra a₁ a₂ → lex (a₁, b₁) (a₂, b₂)
| right : ∀ a {b₁ b₂}, rb b₁ b₂ → lex (a, b₁) (a, b₂)
-- relational product based on ra and rb
inductive rprod : A × B → A × B → Prop
| intro : ∀ {a₁ b₁ a₂ b₂}, ra a₁ a₂ → rb b₁ b₂ → rprod (a₁, b₁) (a₂, b₂)
end
section
parameters {A : Type u} {B : Type v}
parameters {ra : A → A → Prop} {rb : B → B → Prop}
local infix `≺`:50 := lex ra rb
definition lex_accessible {a} (aca : acc ra a) (acb : ∀ b, acc rb b): ∀ b, acc (lex ra rb) (a, b) :=
acc.rec_on aca (λ xa aca iha b,
acc.rec_on (acb b) (λ xb acb ihb,
acc.intro (xa, xb) (λ p lt,
have aux : xa = xa → xb = xb → acc (lex ra rb) p, from
@prod.lex.rec_on A B ra rb (λ p₁ p₂, fst p₂ = xa → snd p₂ = xb → acc (lex ra rb) p₁)
p (xa, xb) lt
(λ a₁ b₁ a₂ b₂ h (eq₂ : a₂ = xa) (eq₃ : b₂ = xb), iha a₁ (eq.rec_on eq₂ h) b₁)
(λ a b₁ b₂ h (eq₂ : a = xa) (eq₃ : b₂ = xb), eq.rec_on eq₂~>symm (ihb b₁ (eq.rec_on eq₃ h))),
aux rfl rfl)))
-- The lexicographical order of well founded relations is well-founded
definition lex_wf (ha : well_founded ra) (hb : well_founded rb) : well_founded (lex ra rb) :=
⟨λ p, destruct p (λ a b, lex_accessible (apply ha a) (well_founded.apply hb) b)⟩
-- relational product is a subrelation of the lex
definition rprod_sub_lex : ∀ a b, rprod ra rb a b → lex ra rb a b :=
λ a b h, prod.rprod.rec_on h (λ a₁ b₁ a₂ b₂ h₁ h₂, lex.left rb a₂ b₂ h₁)
-- The relational product of well founded relations is well-founded
definition rprod_wf (ha : well_founded ra) (hb : well_founded rb) : well_founded (rprod ra rb) :=
subrelation.wf (rprod_sub_lex) (lex_wf ha hb)
end
end prod