Zulip Chat Archive
Stream: lean4
Topic: Parametrized modules in Lean?
Andrey Yao (Oct 24 2024 at 04:48):
I am relatively new to Lean, but I have some prior experience using the Coq proof assistant. I am trying to work with variables (both implicit and explicit) in Lean in the following code snippet:
import Mathlib.Data.Finite.Basic
import Mathlib.Data.List.Basic
import Mathlib.Logic.Function.Defs
import Mathlib.Data.Set.Finite
/-- A vector is a list with extra length information enforced -/
structure Vect {n : Nat} (A : Type) where
lst : List A
len : lst.length = n
def Vect.map {A B : Type} (f : A -> B) (V : @Vect n A) : @Vect n B :=
{ lst := List.map f V.lst,
len := Eq.subst V.len (List.length_map V.lst f) }
def Vect.mem {A : Type} (V : @Vect n A) (a : A) : Prop := List.Mem a V.lst
structure Schema where
relSym : Type
arities : relSym -> Nat
variable (S : Schema)
variable {outs : Nat}
variable {V V1 V2 : Type}
variable (vars : Set V) (vars1 : Set V1) (vars2 : Set V2)
structure Atom where
R : S.relSym
var_vec : @Vect (S.arities R) vars
structure CQ where
head : @Vect outs vars
body : List (Atom S vars)
def Atom.map (f : vars1 -> vars2) (A : Atom S vars1) : Atom S vars2 :=
{ R := A.R, var_vec := Vect.map f A.var_vec }
class homomorphism (q1 : @CQ S outs V1 vars1) (q2 : @CQ S outs V2 vars2) where
f : vars1 -> vars2
body_cond : List.Forall (fun (A : Atom S vars1) => q2.body.Mem (Atom.map S vars1 vars2 f A)) q1.body
head_cond : q2.head = Vect.map f q1.head
As you can see, since I am using many variables, I have to manually put in a LOT of explicit variable instantiation to the types, for example at @CQ S outs V1 vars1. This can't be the expected way to structure my code, right? I know that in Coq you can use a "parametrized module" where the module takes these variables as arguments, and you can just use them freely in the module body. Is there a way to achieve something similar in Lean?
Joël Riou (Oct 24 2024 at 05:26):
Could you edit your code so as to add a list of imports which makes the code work?
Otherwise, the only simplification that I personaly see is that in the definition of CQ, vars refers to V, so that in the subsequent uses, you should not have to specify V1 and vars1, but only vars1. I would also make outs an explicit variable. Then the syntax CQ S outs vars1 could be used.
Andrey Yao (Oct 24 2024 at 05:50):
Sorry, hopefully it compiles now
Those are good suggestions. I was just wondering how people handle the number of variables in more complex codebases? It seems like there is extensive use of typeclasses, so I am assuming a lot of these variables are encapsulated in typeclass instances?
Johan Commelin (Oct 24 2024 at 05:53):
Yep, or custom structures that bundle a set of variables together
Andrey Yao (Oct 24 2024 at 05:58):
Thanks to you both!
Last updated: May 02 2025 at 03:31 UTC