This PR changes where errors are displayed when trying to use `coinductive` keyword when targeting things that do not live in `Prop`. Instead of displaying the error above the first element of the mutual block, it is displayed above the erroneous definition. --------- Co-authored-by: Rob23oba <152706811+Rob23oba@users.noreply.github.com>
265 lines
7.9 KiB
Text
265 lines
7.9 KiB
Text
-- set_option trace.Elab.coinductive true
|
||
set_option pp.proofs true
|
||
section
|
||
variable (α : Type)
|
||
|
||
/--
|
||
docstring
|
||
-/
|
||
coinductive infSeq (r : α → α → Prop) : α → Prop where
|
||
| step : r a b → infSeq r b → infSeq r a
|
||
|
||
/--
|
||
info: infSeq.step (α : Type) (r : α → α → Prop) {a b : α} : r a b → infSeq α r b → infSeq α r a
|
||
-/
|
||
#guard_msgs in
|
||
#check infSeq.step
|
||
|
||
theorem casesOnTest (r : α → α → Prop) (a : α) : infSeq α r a → ∃ b, r a b := by
|
||
intro h
|
||
cases h
|
||
case step b _ hr => exists b
|
||
|
||
-- `match` support does not work yet
|
||
/--
|
||
error: Invalid pattern: Expected a constructor or constant marked with `[match_pattern]`
|
||
|
||
Hint: These are similar:
|
||
'Lean.Order.iterates.below.step',
|
||
'Lean.Order.iterates.step',
|
||
'Nat.le.below.step',
|
||
'Nat.le.step',
|
||
'infSeq._functor.step'
|
||
---
|
||
error: Case tag `rhs` not found.
|
||
|
||
Note: There are no cases to select.
|
||
-/
|
||
#guard_msgs in
|
||
theorem casesOnTest' (r : α → α → Prop) (a : α) : infSeq α r a → ∃ b, r a b := by
|
||
intro h
|
||
match h with
|
||
| step b _ hr => exists b
|
||
|
||
/--
|
||
info: infSeq.casesOn (α : Type) (r : α → α → Prop) {motive : (a : α) → infSeq α r a → Prop} {a✝ : α} (t : infSeq α r a✝)
|
||
(step : ∀ {a b : α} (a_1 : r a b) (a_2 : infSeq α r b), motive a (infSeq.step α r a_1 a_2)) : motive a✝ t
|
||
-/
|
||
#guard_msgs in
|
||
#check infSeq.casesOn
|
||
|
||
/--
|
||
info: infSeq.functor_unfold (α : Type) (r : α → α → Prop) (a✝ : α) : infSeq α r a✝ = infSeq._functor α r (infSeq α r) a✝
|
||
-/
|
||
#guard_msgs in
|
||
#check infSeq.functor_unfold
|
||
|
||
/-- info: infSeq (α : Type) (r : α → α → Prop) : α → Prop -/
|
||
#guard_msgs in
|
||
#check infSeq
|
||
|
||
/--
|
||
info: inductive infSeq._functor : (α : Type) → (α → α → Prop) → (α → Prop) → α → Prop
|
||
number of parameters: 3
|
||
constructors:
|
||
infSeq._functor.step : ∀ (α : Type) (r : α → α → Prop) (infSeq._functor.call : α → Prop) {a b : α},
|
||
r a b → infSeq._functor.call b → infSeq._functor α r infSeq._functor.call a
|
||
-/
|
||
#guard_msgs in
|
||
#print infSeq._functor
|
||
|
||
/--
|
||
info: def infSeq._functor.existential : (α : Type) → (α → α → Prop) → (α → Prop) → α → Prop :=
|
||
fun α r infSeq._functor.call a => ∃ b, r a b ∧ infSeq._functor.call b
|
||
-/
|
||
#guard_msgs in
|
||
#print infSeq._functor.existential
|
||
|
||
/--
|
||
info: infSeq._functor.existential_equiv (α : Type) (r : α → α → Prop) (infSeq._functor.call : α → Prop) (a✝ : α) :
|
||
infSeq._functor α r infSeq._functor.call a✝ ↔ ∃ b, r a✝ b ∧ infSeq._functor.call b
|
||
-/
|
||
#guard_msgs in
|
||
#check infSeq._functor.existential_equiv
|
||
|
||
/--
|
||
info: infSeq.coinduct (α : Type) (r : α → α → Prop) (pred : α → Prop) (hyp : ∀ (a : α), pred a → ∃ b, r a b ∧ pred b)
|
||
(a✝ : α) : pred a✝ → infSeq α r a✝
|
||
-/
|
||
#guard_msgs in
|
||
#check infSeq.coinduct
|
||
|
||
/--
|
||
info: infSeq.step (α : Type) (r : α → α → Prop) {a b : α} : r a b → infSeq α r b → infSeq α r a
|
||
-/
|
||
#guard_msgs in
|
||
#check infSeq.step
|
||
end
|
||
|
||
section
|
||
mutual
|
||
coinductive tick : Prop where
|
||
| mk : ¬tock → tick
|
||
|
||
inductive tock : Prop where
|
||
| mk : ¬tick → tock
|
||
end
|
||
|
||
/--
|
||
info: tick._functor.casesOn {tick._functor.call tock._functor.call : Prop}
|
||
{motive_1 : tick._functor tick._functor.call tock._functor.call → Prop}
|
||
(t : tick._functor tick._functor.call tock._functor.call)
|
||
(mk : ∀ (a : ¬tock._functor.call), motive_1 (tick._functor.mk tick._functor.call tock._functor.call a)) : motive_1 t
|
||
-/
|
||
#guard_msgs in
|
||
#check tick._functor.casesOn
|
||
|
||
/-- info: tick.mk : ¬tock → tick -/
|
||
#guard_msgs in
|
||
#check tick.mk
|
||
|
||
/-- info: tock.mk : ¬tick → tock -/
|
||
#guard_msgs in
|
||
#check tock.mk
|
||
|
||
/-- info: tock._functor (tick._functor.call tock._functor.call : Prop) : Prop -/
|
||
#guard_msgs in
|
||
#check tock._functor
|
||
|
||
/-- info: tock._functor.existential (tick._functor.call tock._functor.call : Prop) : Prop -/
|
||
#guard_msgs in
|
||
#check tock._functor.existential
|
||
|
||
/--
|
||
info: tick.coinduct (pred_1 pred_2 : Prop) (hyp_1 : pred_1 → pred_2 → False) (hyp_2 : (pred_1 → False) → pred_2) :
|
||
pred_1 → tick
|
||
-/
|
||
#guard_msgs in
|
||
#check tick.coinduct
|
||
|
||
/--
|
||
info: tock._functor.existential_equiv (tick._functor.call tock._functor.call : Prop) :
|
||
tock._functor tick._functor.call tock._functor.call ↔ ¬tick._functor.call
|
||
-/
|
||
#guard_msgs in
|
||
#check tock._functor.existential_equiv
|
||
|
||
/--
|
||
info: tock.induct (pred_1 pred_2 : Prop) (hyp_1 : pred_1 → pred_2 → False) (hyp_2 : (pred_1 → False) → pred_2) : tock → pred_2
|
||
-/
|
||
#guard_msgs in
|
||
#check tock.induct
|
||
|
||
/--
|
||
info: tick.mutual_induct (pred_1 pred_2 : Prop) (hyp_1 : pred_1 → pred_2 → False) (hyp_2 : (pred_1 → False) → pred_2) :
|
||
(pred_1 → tick) ∧ (tock → pred_2)
|
||
-/
|
||
#guard_msgs in
|
||
#check tick.mutual_induct
|
||
end
|
||
|
||
/-- error: `coinductive` keyword can only be used to define predicates -/
|
||
#guard_msgs in
|
||
coinductive my_nat where
|
||
| zero : my_nat
|
||
| succ : my_nat → my_nat
|
||
|
||
def Set := Nat → Prop
|
||
|
||
coinductive Foo : Set where
|
||
|
||
/--
|
||
info: Foo.coinduct (pred : Set) (hyp : ∀ (a : Nat), pred a → False) (a✝ : Nat) : pred a✝ → Foo a✝
|
||
-/
|
||
#guard_msgs in
|
||
#check Foo.coinduct
|
||
|
||
coinductive Bar : Set where
|
||
| make : Bar 42
|
||
|
||
/--
|
||
info: Bar.coinduct (pred : Set) (hyp : ∀ (a : Nat), pred a → a = 42) (a✝ : Nat) : pred a✝ → Bar a✝
|
||
-/
|
||
#guard_msgs in
|
||
#check Bar.coinduct
|
||
|
||
|
||
coinductive dependentTest : (n : Nat) → (Vector α n) → Prop where
|
||
| mk (x : α) : dependentTest m v → dependentTest (m+1) (v.push x)
|
||
|
||
/--
|
||
info: dependentTest.coinduct.{u_1} {α : Type u_1} (pred : (n : Nat) → Vector α n → Prop)
|
||
(hyp : ∀ (n : Nat) (a : Vector α n), pred n a → ∃ m v x, pred m v ∧ n = m + 1 ∧ a ≍ v.push x) (n : Nat)
|
||
(a✝ : Vector α n) : pred n a✝ → dependentTest n a✝
|
||
-/
|
||
#guard_msgs in
|
||
#check dependentTest.coinduct
|
||
|
||
/-
|
||
Duplicated parameters and dependent types
|
||
-/
|
||
coinductive dependentTest2 : (n : Nat) → (m : Nat) → (Vector α (m + n)) → (Vector α (m + n)) → Prop where
|
||
| mk (x : α) : dependentTest2 0 n v v → dependentTest2 0 (n + 1) (v.push x) (v.push x)
|
||
|
||
coinductive dependentTest3 : (α : Type) → (ls : List α) → (vec : Vector α ls.length) → (Vector α vec.size) → Prop where
|
||
| mk : dependentTest3 Nat [a] (Vector.singleton a) (Vector.singleton a)
|
||
| mk2 : dependentTest3 String ["hi"] (Vector.singleton b) (Vector.singleton c)
|
||
|
||
/--
|
||
info: dependentTest3.casesOn
|
||
{motive :
|
||
(α : Type) →
|
||
(ls : List α) → (vec : Vector α ls.length) → (a : Vector α vec.size) → dependentTest3 α ls vec a → Prop}
|
||
{α : Type} {ls : List α} {vec : Vector α ls.length} {a✝ : Vector α vec.size} (t : dependentTest3 α ls vec a✝)
|
||
(mk : ∀ {a : Nat}, motive Nat [a] (Vector.singleton a) (Vector.singleton a) dependentTest3.mk)
|
||
(mk2 : ∀ {b c : String}, motive String ["hi"] (Vector.singleton b) (Vector.singleton c) dependentTest3.mk2) :
|
||
motive α ls vec a✝ t
|
||
-/
|
||
#guard_msgs in
|
||
#check dependentTest3.casesOn
|
||
|
||
coinductive test1 (r: α → α → Prop) : α → α → Prop where
|
||
| mk : r a b → test1 r a b → test1 r a a
|
||
| mk2 : test1 r a a
|
||
|
||
coinductive test2 (r: α → α → Prop) : α → α → Prop where
|
||
| mk : r a b → test2 r b b → test2 r a a
|
||
|
||
/--
|
||
error: Cannot define an coinductive predicate and a constructor with the same name `A.mk`
|
||
---
|
||
error: Cannot define an coinductive predicate and a constructor with the same name `A.mk`
|
||
-/
|
||
#guard_msgs in
|
||
mutual
|
||
coinductive A : Prop where
|
||
| mk : A.mk → A
|
||
coinductive A.mk : Prop where
|
||
| mk : A → A.mk
|
||
end
|
||
|
||
macro "test%" : command => `(command|
|
||
coinductive MacroTest : Prop where | mk : MacroTest
|
||
)
|
||
|
||
/-- error: Coinductive predicates are not allowed inside of macro scopes -/
|
||
#guard_msgs in
|
||
test%
|
||
|
||
namespace unsafe_test
|
||
unsafe coinductive infSeq2 (r : α → α → Prop) : α → Prop where
|
||
| step : r a b → infSeq2 r b → infSeq2 r a
|
||
end unsafe_test
|
||
|
||
/--
|
||
@ +4:14...20
|
||
error: `coinductive` keyword can only be used to define predicates
|
||
-/
|
||
#guard_msgs (positions := true) in
|
||
mutual
|
||
coinductive wrong1 : Prop where
|
||
|
||
coinductive wrong2 where
|
||
| zero : wrong2
|
||
| succ : wrong1 → wrong2
|
||
end
|