Zulip Chat Archive

Stream: lean4

Topic: Inter-project name collision


Jun Yoshida (Jul 30 2023 at 09:18):

I ran into a problem about collision of theorem names in different projects.
I have two personal projects, say A and B, using Lean4; A doesn't depend on Mathlib while B does.
The problem is that I cannot use codes from the project A in B because some auxiliary lemmas in A have the same names as ones in Mathlib.
My questions are:

  • is there any "standard" solution in such a situation?
  • lake build stops at each collision pair with the error message like
B.lean:1:0: error: import A.Data.List.Basic failed, environment already contains 'List.dropLast_eq_take' from Mathlib.Data.List.Basic

It is good if I can detect all collision pair at onece. Any idea?

Jun Yoshida (Jul 30 2023 at 09:18):

Another concern is that, as Mathlib is growing, I am not sure my auxiliary theorems in the project A have "safe" names even in near future.

Mac Malone (Jul 30 2023 at 09:38):

@Jun Yoshida The usual way to solve this is for packages to not define all their definitions within a namespace that matches the package / root module name (i.e., A and B and your example). Only very standard libraries like Mathlib and Std should stick stuff in the root namespace or augment existing namespaces like List.

Jun Yoshida (Jul 30 2023 at 09:49):

If List.dropLast_eq_take, for example, is defined inbetween namespace A-end A, then I cannot write l.dropLast_eq_take for l : List Nat.
This seems a drawback.

Alex J. Best (Jul 30 2023 at 09:50):

(deleted)

Kyle Miller (Jul 30 2023 at 10:11):

The "standard" solution for having names in library namespaces might be to try to contribute such lemmas to mathlib or std.

Another solution would be to add a prefix to names you insert into library namespaces, like List.my_dropLast_eq_take or List.jun_dropLast_eq_take.

Kyle Miller (Jul 30 2023 at 10:14):

The safest solution is to do what Mac suggested, put your own things into your own namespace. It's true that it's unfortunate that you can't use l.dropLast_eq_take notation, but that's the tradeoff you have to take if you want to be safe against name collisions.

Eric Wieser (Jul 30 2023 at 13:19):

The "standard" solution for having names in library namespaces might be to try to contribute such lemmas to mathlib or std.

In this particular case it sounds like the lemma is already in mathlib; the problem is that project A decided to reimplement this lemma rather than depending on mathlib

Jun Yoshida (Aug 10 2023 at 18:52):

Thank you for a lot of advice. I do not use mathlib in the project A because it is a library for data structures/algorithms to be used in constructive context. Some name collision are actually due to Classical-free re-proof of theorems in std for which I just stupidly add primes in the last of the original name. I understand that the library name space is the safest solution, but it requires a huge refactor in the project A, which I want to avoid as much as possible.

I also consider the use of private declarations. If I keep track with such declarations in the project, I can export them locally in the same way as export private does.
Here is my attempt to this approach:

Definition of pkg_local attribute and pkg_include command

Expected workflow is

  1. Define a private def/theorem with pkg_local attribute:
-- A.Data.List.Basic

@[pkg_local]
private theorem List.foo {α : Type u} (x : List α) : x.length = x.length := sorry
  1. In other modules in the same project, import the declaration using pkg_include command:
-- A.Data.MyData.Lemma

-- #print List.foo -- error before `pkg_include`

pkg_include List.foo

#print List.foo
/-
private theorem List.foo.{u} : {α : Type u} → (x : List α) → x.length = x.length := List.foo
-/

Last updated: Dec 20 2023 at 11:08 UTC