feat: LambdaCalculus.LocallyNameless.Coc#392
feat: LambdaCalculus.LocallyNameless.Coc#392matthunz wants to merge 17 commits intoleanprover:mainfrom
LambdaCalculus.LocallyNameless.Coc#392Conversation
|
Hi, thanks for your interest in contributing! Can I ask why the jump to CoC for this named representation of binding? It is a little uncommon to do this style at all, so there's not much else to build off yet. I was hoping that STLC and System F would get filled out first to work out any kinks before more complex type systems. We are planning to add well scoped indices as an alternative in the next few months or so, but if your interest is formalizing CoC right now would you be interested in doing so in the locally nameless style? This would be much easier to review in comparison to what we already have and prior work in Rocq. |
LambdaCalculus.Named.CocLambdaCalculus.LocallyNameless.Coc
|
Hey 👋 thanks so much for the feedback! I wanted to go the named representation route at first because it felt more natural to me coming from functional programming but I'm definitely unsure of how to prove things like well-formedness with that approach. I'd be thrilled if we can fit this in here somehow given the current plans, here's what I did for now:
I think the biggest remaining features would now be reduction and the related proofs to tie everything together, which might be a somewhat significant undertaking 😅 happy to defer to your judgement on what the scope of this PR should be |
chenson2018
left a comment
There was a problem hiding this comment.
Some of this looks good, in particular thank you for mostly following conventions from the System F formalization. There are a few important places however where I'm not sure about the definitions. Because these are tricky to get right I suggest closely following prior work like the formalization from Charguéraud I link below.
| /-- Pi type. -/ | ||
| | pi : Term Var → Term Var → Term Var | ||
| /-- Type universe. -/ | ||
| | type : Term Var |
There was a problem hiding this comment.
We probably want this to be ℕ → Term Var as well.
| abbrev Env (Var : Type u) := Finset (Var × Term Var) | ||
|
|
||
| def Env.dom [DecidableEq Var] : Env Var → Finset Var := Finset.image Prod.fst |
There was a problem hiding this comment.
I would expect we reuse LocallyNameless.Context instead of this abbrev.
|
|
||
| /-- Variable opening of the ith bound variable. -/ | ||
| @[scoped grind =] | ||
| def openingRec (i : ℕ) (s : Term Var) : Term Var → Term Var |
There was a problem hiding this comment.
We should name this consistently as openRec and open' with the other typesystems.
| | abs (L : Finset Var) : σ.LC → (∀ x ∉ L, LC (t₁ ^ᵗ fvar x)) → LC (abs σ t₁) | ||
| | pi (L : Finset Var) : σ.LC → (∀ x ∉ L, LC (t₁ ^ᵗ fvar x)) → LC (pi σ t₁) |
There was a problem hiding this comment.
For CoC, the variable σ is a term, as opposed to System F where it was a type. I'd update the variable names accordingly to use t₁ and t₂.
|
|
||
| /-- A locally closed term is unchanged by opening. -/ | ||
| lemma openingRec_lc [HasFresh Var] {σ τ : Term Var} (lc : σ.LC) : σ = σ⟦X ↝ τ⟧ := by | ||
| classical |
There was a problem hiding this comment.
This is for decidable equality? I'd rather make this explicit as a typeclass parameter.
| open Term | ||
|
|
||
| /-- β-equivalence. -/ | ||
| inductive BetaEquiv : Term Var → Term Var → Prop |
There was a problem hiding this comment.
This definition looks very different from what I expected. See for instance the definition in the Rocq formalization I closely followed for other type systems.
| BetaEquiv := BetaEquiv | ||
|
|
||
| /-- Typing judgement -/ | ||
| inductive Typing [DecidableEq Var] : Env Var → Term Var → Term Var → Prop |
There was a problem hiding this comment.
I was expecting to see a mutual block also defining well-formed contexts.
| /-- An environment is well-formed if it binds each variable exactly once to a well-formed type. -/ | ||
| inductive Env.Wf : Env Var → Prop | ||
| | nil : Wf {} | ||
| | cons : Wf Γ → Term.Wf Γ τ → x ∉ Γ.dom → Wf ({⟨x, τ⟩} ∪ Γ) |
There was a problem hiding this comment.
I don't think this is right. Because of the dependent types aspect, we need a typing derivation before adding to the context, right?
…fit current conventions
| open Term | ||
|
|
||
| /-- β-reduction. -/ | ||
| inductive BetaEquiv : Term Var → Term Var → Prop |
There was a problem hiding this comment.
I should have mentioned previously. This should use the reduction_sys attribute to get notation, because this is still reduction and not the equivalence (reflexive symmetric transitive closure), right? I would remove the HasBetaEquiv class and use this.
Summary
Adds basic syntax and typing judgments for the Calculus of Constructions following Coquand's algorithm. I tried to keep everything as close to other lambda calculi in this project as well as general code style. Some of the lemmas from that paper are noticeably missing but I'm hoping this can be an OK first cut 😃
LambdaCalculus.LocallyNameless.CocCslib.Foundations.Syntax.HasBetaEquivHasBetaEquiv(similar toHasAlphaEquiv) for the notationA =β B