lean4-htt/tests/lean/run/mutual_coinduction.lean
Wojciech Różowski 5c03ab9630
fix: unfolding order on predicates (#10245)
This PR changes the implementation of a function `unfoldPredRel` used in
(co)inductive predicate machinery, that unfolds pointwise order on
predicates to quantifications and implications. Previous implementation
relied on `withDeclsDND` that could not deal with types which depend on
each other. This caused the following example to fail:

```lean4
inductive infSeq_functor1.{u} {α : Type u} (r : α → α → Prop) (call : {α : Type u} → (r : α → α → Prop) → α → Prop) : α → Prop where
  | step : r a b → infSeq_functor1 r call b → infSeq_functor1 r call a

def infSeq1 (r : α → α → Prop) : α → Prop := infSeq_functor1 r (infSeq1)
  coinductive_fixpoint monotonicity by sorry

#check infSeq1.coinduct
```
Closes #10234.
2025-09-08 10:07:15 +00:00

122 lines
3.6 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.

namespace MutualCoinduction
mutual
def f : Prop :=
g
coinductive_fixpoint
def g : Prop :=
f
coinductive_fixpoint
end
/--
info: MutualCoinduction.f.coinduct (pred_1 pred_2 : Prop) (hyp_1 : pred_1 → pred_2) (hyp_2 : pred_2 → pred_1) : pred_1 → f
-/
#guard_msgs in
#check MutualCoinduction.f.coinduct
/--
info: MutualCoinduction.f.mutual_induct (pred_1 pred_2 : Prop) (hyp_1 : pred_1 → pred_2) (hyp_2 : pred_2 → pred_1) :
(pred_1 → f) ∧ (pred_2 → g)
-/
#guard_msgs in
#check MutualCoinduction.f.mutual_induct
/--
info: MutualCoinduction.g.coinduct (pred_1 pred_2 : Prop) (hyp_1 : pred_1 → pred_2) (hyp_2 : pred_2 → pred_1) : pred_2 → g
-/
#guard_msgs in
#check MutualCoinduction.g.coinduct
end MutualCoinduction
namespace MutualInduction
mutual
def f : Prop :=
g
inductive_fixpoint
def g : Prop :=
f
inductive_fixpoint
end
/--
info: MutualInduction.f.induct (pred_1 pred_2 : Prop) (hyp_1 : pred_2 → pred_1) (hyp_2 : pred_1 → pred_2) : f → pred_1
-/
#guard_msgs in
#check MutualInduction.f.induct
/--
info: MutualInduction.f.mutual_induct (pred_1 pred_2 : Prop) (hyp_1 : pred_2 → pred_1) (hyp_2 : pred_1 → pred_2) :
(f → pred_1) ∧ (g → pred_2)
-/
#guard_msgs in
#check MutualInduction.f.mutual_induct
/--
info: MutualInduction.g.induct (pred_1 pred_2 : Prop) (hyp_1 : pred_2 → pred_1) (hyp_2 : pred_1 → pred_2) : g → pred_2
-/
#guard_msgs in
#check MutualInduction.g.induct
end MutualInduction
namespace MixedInductionCoinduction
mutual
def f : Prop :=
g → f
inductive_fixpoint
def g : Prop :=
f → g
coinductive_fixpoint
end
/--
info: MixedInductionCoinduction.f.induct (pred_1 pred_2 : Prop) (hyp_1 : (pred_2 → pred_1) → pred_1)
(hyp_2 : pred_2 → pred_1 → pred_2) : f → pred_1
-/
#guard_msgs in
#check f.induct
/--
info: MixedInductionCoinduction.f.mutual_induct (pred_1 pred_2 : Prop) (hyp_1 : (pred_2 → pred_1) → pred_1)
(hyp_2 : pred_2 → pred_1 → pred_2) : (f → pred_1) ∧ (pred_2 → g)
-/
#guard_msgs in
#check f.mutual_induct
/--
info: MixedInductionCoinduction.g.coinduct (pred_1 pred_2 : Prop) (hyp_1 : (pred_2 → pred_1) → pred_1)
(hyp_2 : pred_2 → pred_1 → pred_2) : pred_2 → g
-/
#guard_msgs in
#check g.coinduct
end MixedInductionCoinduction
namespace DifferentPredicateTypes
mutual
def f (n : Nat) : Prop :=
g (n+1) (n+2)
coinductive_fixpoint
def g (n m : Nat): Prop :=
f (n + 2) g (m + 1) m
coinductive_fixpoint
end
/--
info: DifferentPredicateTypes.f.coinduct (pred_1 : Nat → Prop) (pred_2 : Nat → Nat → Prop)
(hyp_1 : ∀ (n : Nat), pred_1 n → pred_2 (n + 1) (n + 2))
(hyp_2 : ∀ (n m : Nat), pred_2 n m → pred_1 (n + 2) pred_2 (m + 1) m) (n : Nat) : pred_1 n → f n
-/
#guard_msgs in
#check f.coinduct
/--
info: DifferentPredicateTypes.f.mutual_induct (pred_1 : Nat → Prop) (pred_2 : Nat → Nat → Prop)
(hyp_1 : ∀ (n : Nat), pred_1 n → pred_2 (n + 1) (n + 2))
(hyp_2 : ∀ (n m : Nat), pred_2 n m → pred_1 (n + 2) pred_2 (m + 1) m) :
(∀ (n : Nat), pred_1 n → f n) ∧ ∀ (n m : Nat), pred_2 n m → g n m
-/
#guard_msgs in
#check f.mutual_induct
/--
info: DifferentPredicateTypes.g.coinduct (pred_1 : Nat → Prop) (pred_2 : Nat → Nat → Prop)
(hyp_1 : ∀ (n : Nat), pred_1 n → pred_2 (n + 1) (n + 2))
(hyp_2 : ∀ (n m : Nat), pred_2 n m → pred_1 (n + 2) pred_2 (m + 1) m) (n m : Nat) : pred_2 n m → g n m
-/
#guard_msgs in
#check g.coinduct
end DifferentPredicateTypes