mirror of
https://github.com/leanprover/lean4.git
synced 2026-03-17 18:34:06 +00:00
This PR sets up the new integrated test/bench suite. It then migrates all benchmarks and some related tests to the new suite. There's also some documentation and some linting. For now, a lot of the old tests are left alone so this PR doesn't become even larger than it already is. Eventually, all tests should be migrated to the new suite though so there isn't a confusing mix of two systems.
230 lines
6.0 KiB
Lean4
230 lines
6.0 KiB
Lean4
-- Coinductive predicate definition
|
||
def infseq {α} (R : α → α → Prop) : α → Prop :=
|
||
λ x : α => ∃ y, R x y ∧ infseq R y
|
||
coinductive_fixpoint
|
||
|
||
-- Application of the rewrite rule
|
||
def infseq_fixpoint {α} (R : α → α → Prop) (x : α) :
|
||
infseq R x = ∃ y, R x y ∧ infseq R y := by
|
||
rw [infseq]
|
||
|
||
-- The associated coinduction principle
|
||
|
||
/--
|
||
info: infseq.coinduct.{u_1} {α : Sort u_1} (R : α → α → Prop) (pred : α → Prop)
|
||
(hyp : ∀ (a : α), pred a → ∃ y, R a y ∧ pred y) (a✝ : α) : pred a✝ → infseq R a✝
|
||
-/
|
||
#guard_msgs in #check infseq.coinduct
|
||
|
||
/--
|
||
error: Unknown constant `infseq.mutual_induct`
|
||
-/
|
||
#guard_msgs in
|
||
#check infseq.mutual_induct
|
||
|
||
-- Simple proof by coinduction
|
||
theorem cycle_infseq {R : α → α → Prop} (x : α) : R x x → infseq R x := by
|
||
apply @infseq.coinduct α R (λ m => R m m)
|
||
intro x _
|
||
apply Exists.intro x
|
||
trivial
|
||
|
||
-- Inductive predicate, as a inductive definition
|
||
inductive star (R : α → α → Prop) : α → α → Prop where
|
||
| star_refl : ∀ x : α, star R x x
|
||
| star_step : ∀ x y z, R x y → star R y z → star R x z
|
||
|
||
-- Inductive predicate, as a least fixpoint
|
||
def star_ind (tr : α → α → Prop) (q₁ q₂ : α) : Prop :=
|
||
∃ (z : α), q₁ = q₂ ∨ (tr q₁ z ∧ star_ind tr z q₂)
|
||
inductive_fixpoint
|
||
|
||
/--
|
||
info: star_ind.induct.{u_1} {α : Sort u_1} (tr : α → α → Prop) (q₂ : α) (pred : α → Prop)
|
||
(hyp : ∀ (q₁ : α), (∃ z, q₁ = q₂ ∨ tr q₁ z ∧ pred z) → pred q₁) (q₁ : α) : (fun q₁ => star_ind tr q₁ q₂) q₁ → pred q₁
|
||
-/
|
||
#guard_msgs in #check star_ind.induct
|
||
|
||
-- From one you can prove the other
|
||
theorem star_implies_star' (R : α → α → Prop) : ∀ a b : α, star R a b → star_ind R a b := by
|
||
intro a b s
|
||
induction s
|
||
case star_refl x =>
|
||
unfold star_ind
|
||
apply Exists.intro x
|
||
left
|
||
trivial
|
||
case star_step x y z rel s2 ih =>
|
||
unfold star_ind
|
||
apply Exists.intro y
|
||
right
|
||
trivial
|
||
|
||
-- More elaborate example from Xavier Leroy's compiler verification course
|
||
theorem star_one (R : α → α → Prop) : ∀ a b : α, R a b → star R a b := by
|
||
intro a b Rab
|
||
apply star.star_step
|
||
exact Rab
|
||
apply star.star_refl
|
||
|
||
theorem star_trans {α} (R : α → α → Prop) : ∀ (a b : α), star R a b → ∀ c : α, star R b c → star R a c := by
|
||
intro a b sab
|
||
intro c
|
||
intro sbc
|
||
induction sab
|
||
case star_refl => exact sbc
|
||
case star_step rel m ih =>
|
||
apply star.star_step
|
||
exact rel
|
||
apply ih
|
||
trivial
|
||
|
||
inductive plus (R : α → α → Prop) : α → α → Prop where
|
||
| plus_left : ∀ a b c, R a b → star R b c → plus R a c
|
||
|
||
theorem plus_one : ∀ a b, R a b → plus R a b := by
|
||
intro a b Rab
|
||
apply plus.plus_left
|
||
exact Rab
|
||
apply star.star_refl
|
||
|
||
theorem plus_star : ∀ a b, plus R a b → star R a b := by
|
||
intro a b h
|
||
cases h
|
||
case plus_left h₁ h₂ h₃ =>
|
||
apply star.star_step
|
||
exact h₂
|
||
exact h₃
|
||
|
||
theorem plus_star_trans (R : α → α → Prop) : ∀ (a b c : α), star R a b → plus R b c → plus R a c := by
|
||
intro a b c s p
|
||
induction s
|
||
case star_refl d =>
|
||
exact p
|
||
case star_step d e f rel s2 ih =>
|
||
apply plus.plus_left
|
||
exact rel
|
||
apply plus_star
|
||
apply ih
|
||
exact p
|
||
|
||
def all_seq_inf (R : α → α → Prop) (x : α) : Prop :=
|
||
∀ y : α, star R x y → ∃ z, R y z
|
||
|
||
def infseq_if_all_seq_inf (R : α → α → Prop) : ∀ x, all_seq_inf R x → infseq R x := by
|
||
apply infseq.coinduct
|
||
intro x H
|
||
unfold all_seq_inf at H
|
||
have H' := H x (by simp [star.star_refl])
|
||
apply Exists.elim H'
|
||
intro y Rxy
|
||
apply Exists.intro y
|
||
apply And.intro
|
||
exact Rxy
|
||
unfold all_seq_inf
|
||
intro y'
|
||
intro Ryy'
|
||
apply H y'
|
||
apply star.star_step
|
||
exact Rxy
|
||
trivial
|
||
|
||
theorem infseq_coinduction_principle_2:
|
||
∀ (x : α → Prop),
|
||
(∀ (a : α), x a → ∃ b, plus R a b ∧ x b) →
|
||
∀ (a : α), x a → infseq R a := by
|
||
intro X
|
||
intro h₁ a rel
|
||
apply @infseq.coinduct _ _ (fun a => ∃ b, star R a b ∧ X b)
|
||
case x =>
|
||
apply Exists.elim (h₁ a rel)
|
||
intro a' ⟨h₁, h₂⟩
|
||
apply Exists.intro a'
|
||
apply And.intro
|
||
apply plus_star
|
||
exact h₁
|
||
exact h₂
|
||
case hyp =>
|
||
intro a0 h₂
|
||
apply Exists.elim h₂
|
||
intro a1 ⟨ h₃ , h₄ ⟩
|
||
have h₁' := h₁ a1 h₄
|
||
apply Exists.elim h₁'
|
||
intro mid ⟨ h₅, h₆⟩
|
||
have t := plus_star_trans R a0 a1 mid h₃ h₅
|
||
cases t
|
||
case plus_left mid2 rel2 s =>
|
||
apply Exists.intro mid2
|
||
apply And.intro
|
||
exact rel2
|
||
apply Exists.intro mid
|
||
exact ⟨ s, h₆ ⟩
|
||
|
||
-- Automata theory example that involves forall quantifier
|
||
def DFA (Q : Type) (A : Type) : Type := Q → (Bool × (A → Q))
|
||
|
||
def language_equivalent (automaton : DFA Q A) (q₁ q₂ : Q) : Prop :=
|
||
let ⟨o₁, t₁⟩ := automaton q₁
|
||
let ⟨o₂, t₂⟩ := automaton q₂
|
||
o₁ = o₂ ∧ (∀ a : A, language_equivalent automaton (t₁ a) (t₂ a))
|
||
coinductive_fixpoint
|
||
|
||
/--
|
||
info: language_equivalent.coinduct {Q A : Type} (automaton : DFA Q A) (pred : Q → Q → Prop)
|
||
(hyp :
|
||
∀ (q₁ q₂ : Q),
|
||
pred q₁ q₂ →
|
||
(automaton q₁).fst = (automaton q₂).fst ∧ ∀ (a : A), pred ((automaton q₁).snd a) ((automaton q₂).snd a))
|
||
(q₁ q₂ : Q) : pred q₁ q₂ → language_equivalent automaton q₁ q₂
|
||
-/
|
||
#guard_msgs in
|
||
#check language_equivalent.coinduct
|
||
|
||
namespace mixed1
|
||
mutual
|
||
def tick : Prop :=
|
||
¬tock
|
||
coinductive_fixpoint
|
||
|
||
def tock : Prop :=
|
||
¬tick
|
||
inductive_fixpoint
|
||
end
|
||
end mixed1
|
||
|
||
namespace mixed2
|
||
mutual
|
||
def tick : Prop :=
|
||
¬tock
|
||
inductive_fixpoint
|
||
|
||
def tock : Prop :=
|
||
¬tick
|
||
coinductive_fixpoint
|
||
end
|
||
end mixed2
|
||
|
||
namespace mixed3
|
||
mutual
|
||
def tick : Prop :=
|
||
tock → tick
|
||
coinductive_fixpoint
|
||
|
||
def tock : Prop :=
|
||
tick → tock
|
||
inductive_fixpoint
|
||
end
|
||
end mixed3
|
||
|
||
namespace mixed4
|
||
mutual
|
||
def tick : Prop :=
|
||
tock → tick
|
||
inductive_fixpoint
|
||
|
||
def tock : Prop :=
|
||
tick → tock
|
||
coinductive_fixpoint
|
||
end
|
||
end mixed4
|