Zulip Chat Archive

Stream: general

Topic: Finmap within mutual definition


Zach (Sep 18 2025 at 13:54):

Hello! I'm relatively inexperienced with Lean: I think I have a basic understanding of the dependent type theory involved, but I'm struggling with an error from the kernel that I think might be due to how an induction principle is being derived. Here's a MWE of my situation:

import Mathlib.Data.Finmap

mutual
  inductive Foo : Type where
    | Mk : Bar  Foo

  inductive Bar : Type where
    | Mk : Finmap (fun (_ : Nat) => Foo)  Bar
end

And here's the resulting error message I'm seeing, focused on the inductive Foo line:

(kernel) application type mismatch
  entries.NodupKeys
argument has type
  Multiset _nested.Sigma_2
but function has type
  Multiset ((_ : ) × Foo)  Prop

Examining the message, it seems clear that the Mk constructor of Bar is being invoked by some spooky code I haven't written. The invocation of the Mk constructor appears to be receiving a thing of type Multiset _nested.Sigma_2, a type with which I'm unfamiliar and, if the leading underscore is any indication, I perhaps shouldn't even know about.

My overall goal is to prove an alignment between two proof systems, so I'm intentionally defining everything using structures like Finmap rather than e.g. TreeMap. I suspect that there's some set_option that I could perform to see the code generated for the induction principle (to test my hypothesis), but if that turned out to be true, I'm not sure what I could do about it.

Any suggestions? Thanks for reading!

Robin Arnez (Sep 18 2025 at 13:56):

There are multiple problems here: Finmap is a subtype and nested subtypes aren't supported and Multiset is a quotient a nested quotients aren't supported.

Zach (Sep 18 2025 at 13:57):

Thanks for the reply! When you say "aren't supported", do you mean with respect to mutually-defined inductive types?

Robin Arnez (Sep 18 2025 at 13:59):

Well, nested quotients aren't supported in the sense that you can't do something like

inductive Fails where
  | mk (x : Quot (fun a b : List Fails => a.Perm b))

i.e. you can't have a recursive reference of any inductive type in the mutual block nested inside of a quotient

Kenny Lau (Sep 18 2025 at 14:02):

why is it not supported?

Robin Arnez (Sep 18 2025 at 14:02):

And nested subtypes aren't supported because of how the kernel de-nests types:

mutual
  inductive Foo : Type where
    | Mk : Bar  Foo

  inductive Bar : Type where
    | Mk : Finmap (fun (_ : Nat) => Foo)  Bar
end

turns into

mutual
  inductive Foo : Type where
    | Mk : Bar  Foo

  inductive Bar : Type where
    | Mk : _nested.Finmap_1  Bar

  -- Finmap (fun (_ : Nat) => Foo)
  structure _nested.Finmap_1 where
    entries : Multiset _nested.Sigma_2
    nodupKeys : entries.NodupKeys -- error

  -- Sigma (fun (_ : Nat) => Foo)
  structure _nested.Sigma_2 where
    fst : Nat
    snd : Foo
end

Zach (Sep 18 2025 at 14:03):

I think I'm following. (Still a novice!) It seems almost as if I'll need to have some representation of the finite maps that appear in my proof systems that doesn't rely on the Finset part of Mathlib. Thank you for the explanation!

Kenny Lau (Sep 18 2025 at 14:04):

@Zach you'll need to use List and then later quotient on the big type

Kenny Lau (Sep 18 2025 at 14:05):

see how docs#ZFSet works

Zach (Sep 18 2025 at 14:06):

@Kenny Lau Thanks! I was suspecting this. I'm using finite maps in a few different places, so I was looking for what would essentially be a dictionary structure at the proposition level. I'm tempted to define my own: even if it goes poorly, I'm sure I'll learn something from the process. :)


Last updated: Dec 20 2025 at 21:32 UTC