Zulip Chat Archive
Stream: new members
Topic: Induction, "index in target's type is not a variable..."
Chris Henson (Jun 25 2024 at 17:18):
I am working with the simply typed lambda calculus (with pairs), following the style in PLFA of terms parameterized by contexts. I tried to prove a simplified version of the permutation lemma, but don't understand this error message. Here is an mwe:
inductive Ty (K : Type)
| Basic : K → Ty K
| Arr : Ty K → Ty K → Ty K
| Prod : Ty K → Ty K → Ty K
infixr:60 " × " => Ty.Prod
infixr:70 " ⇒ " => Ty.Arr
prefix:90 "` " => Ty.Basic
abbrev Context (K : Type) : Type := List (Ty K)
inductive Lookup {K : Type} : Context K → Ty K → Type
| z : Lookup (T :: Γ) T
| s : Lookup Γ T → Lookup (T' :: Γ) T
infix:40 " ∋ " => Lookup
inductive Term {K : Type} : Context K → Ty K → Type
| var : Γ ∋ a → Term Γ a
| lam : Term (a :: Γ) b → Term Γ (a ⇒ b)
| ap : Term Γ (a ⇒ b) → Term Γ a → Term Γ b
| cop : Term Γ a → Term Γ b → Term Γ (a × b)
| fst : Term Γ (a × b) → Term Γ a
| snd : Term Γ (a × b) → Term Γ b
namespace Term
infix:40 " ⊢ " => Term
prefix:50 "ƛ " => lam
infixl:70 " □ " => ap
prefix:70 "fst" => fst
prefix:70 "snd" => snd
prefix:90 "` " => var
end Term
theorem permute : (τ :: σ :: Γ) ⊢ T → (σ :: τ :: Γ) ⊢ T := by
intros tm
induction tm
/-
error message: index in target's type is not a variable (consider using the `cases` tactic instead) τ :: σ :: Γ
-/
I searched here on Zulip and saw some suggestions about using the generalize
tactic, but I wasn't sure if/how that might work here. I'd also like to understand what the message means past just immediately getting past this theorem, if there's some suggested reading/docs.
Chris Henson (Jun 25 2024 at 17:42):
I think the way that I've stated permute
is not quite right either, I'd just like to understand how I can do induction over a term with something cons'd into the context (or understand if/why another approach would be better).
Kyle Miller (Jun 25 2024 at 18:10):
The induction tactic requires that indices be variables, so that it can substitute in values according to each of the cases. Here's how you use generalize
for that:
theorem permute : (τ :: σ :: Γ) ⊢ T → (σ :: τ :: Γ) ⊢ T := by
intros tm
generalize htm : τ :: σ :: Γ = ctx at tm
induction tm
Kyle Miller (Jun 25 2024 at 18:13):
It's a little silly here because each of the Term
constructors have the context as a variable, so this is an unnecessary requirement.
Because of that, you can undo the generalizing at the same time using
induction tm <;> cases htm
(Or <;> subst htm
if you wish, it does the same thing)
Chris Henson (Jun 25 2024 at 21:09):
Thanks! Would you mind explaining roughly what "index" means here? Is it the same meaning as in Coq?
Henrik Böving (Jun 25 2024 at 21:35):
Index of an inductive type means the same in Coq and Lean yes, in general a lot of the type theory related jargon is interchangeable
Last updated: May 02 2025 at 03:31 UTC