Zulip Chat Archive
Stream: new members
Topic: Recovering information about one term by induction on o...
Dan Plyukhin (Feb 04 2025 at 23:38):
I have an inductive datatype for expressions,
inductive Exp : Type where
| app (M₁ : Exp) (M₂ : Exp)
| ...
and one for type derivations:
inductive Typed : Context → Exp → Ty → Type where
| app:
Typed Γ M₁ (funTy T1 T2) →
Typed Γ M₂ T1→
--------------------------------
Typed Γ (app M₁ M₂) T2
I'm trying to prove a proposition by induction on type derivations of expressions. I'll elide the details and show the important bit:
example (M_typed : Typed Γ M T) : False := by
induction M_typed with
| app h1 h2 ih1 ih2 =>
admit
Since the app
typing rule only holds when M
is app
, I would expect to find an equation in my context telling me that M = app ?M1 ?M2
. But I don't! Instead my context shows no relationship between M
and the type derivation:
Γ : Context
M : Exp
T : Ty
Γ✝ : Context
M₁✝ : Exp
T₁✝ T₂✝ : Ty
M₂✝ : Exp
h1 : Typed Γ✝ M₁✝ (T₁✝.funType T₂✝)
h2 : Typed Γ✝ M₂✝ T₁✝
ih1 ih2 : False
⊢ False
How do I recover the fact that M = app M₁✝ M₂✝
?
Aaron Liu (Feb 04 2025 at 23:59):
Why do you need this? If induction
has worked correctly, there should be no mention of M
in your environment anymore, so even if you knew this, you would not be able to do anything with it.
Aaron Liu (Feb 05 2025 at 00:02):
You can do generalize hM : M = M' at M_typed; induction M_typed generalizing M with ...
(not tested, because you didn't post a #mwe)
Dan Plyukhin (Feb 05 2025 at 00:09):
Hmm good point! I want it because the app typing rule has a ton of implicit arguments (Gamma, T1, T2, M1, M2, and other rules have even more implicit arguments). I need to give names to M1 and M2, and I don't want to give names to the other arguments. I could just use underscores:
induction M_typed with
| @app _ _ M₁ M₂ _ _ h1 h2 ih1 ih2 =>
but that doesn't look very nice. I like your idea of using generalize
! I'll try that.
Notification Bot (Feb 05 2025 at 15:27):
Dan Plyukhin has marked this topic as resolved.
Notification Bot (Feb 06 2025 at 21:44):
Dan Plyukhin has marked this topic as unresolved.
Dan Plyukhin (Feb 06 2025 at 21:50):
I went down the generalize
rabbit hole, and I didn't like what I saw :) I've constructed an MWE in case anybody has other ideas.
The code below shows a simply typed lambda calculus, and an attempt to prove a proposition by induction on the type derivation. In that proof, I know M
must have the form app M1 M2
, and I want to give names to that M1
and M2
. So my question is, what's the cleanest way to do that?
import Mathlib.Data.Finmap
def Var := String
deriving DecidableEq
inductive Exp where
| app (M₁ : Exp) (M₂ : Exp)
| var (x : Var)
inductive Ty : Type where
| funType (T₁ T₂ : Ty)
| basicType
open Exp Ty
abbrev Typing.Context := Finmap (λ _ : Var ↦ Ty)
inductive Typed : Typing.Context → Exp → Ty → Type where
| app {Γ M₁ M₂ T₁ T₂} :
Typed Γ M₁ (funType T₁ T₂) →
Typed Γ M₂ T₁ →
--------------------------------
Typed Γ (app M₁ M₂) T₂
| var {Γ x T} :
Γ.lookup x = some T →
----------------------
Typed Γ (var x) T
example {M_typed : Typed Γ M T} : M = M := by
induction M_typed with
| app M₁_ty M₂_ty ih₁ ih₂ =>
let (app M₁ M₂) := M -- PROBLEM: The typechecker doesn't accept this!
admit
| var h =>
admit
Aaron Liu (Feb 06 2025 at 22:04):
Come up with a better mwe?
example {M_typed : Typed Γ M T} : M = M := by
induction M_typed with
| app M₁_ty M₂_ty ih₁ ih₂ =>
clear M -- `clear`ly, you don't need `M`
rename_i M₁ M₂ _ _
sorry
| var h =>
sorry
Dan Plyukhin (Feb 06 2025 at 23:37):
:skull: We can forget about M since I can just define let M:= app M1 M2. I don’t like rename_i because it’s not robust to change. If I mess around with other parts of the proof or add parameters to Typed.app, then rename_i breaks.
Aaron Liu (Feb 06 2025 at 23:40):
This is the case for other tactics too, right? If I add a constructor or reorder the arguments to Typed.app, the induction
breaks too.
Dan Plyukhin (Feb 06 2025 at 23:48):
If I add a constructor I expect things to break. Ideally I want my automation to be robust enough that I can reorder arguments and most proofs wouldn’t break.
Last updated: May 02 2025 at 03:31 UTC