Zulip Chat Archive

Stream: lean4 dev

Topic: Type mismatch after moving instNatCast to Lean


Tobias Grosser (Oct 13 2024 at 05:32):

I am currently flashing out some of the BitVec <-> Fin interfaces in Lean working on this patch: https://github.com/leanprover/lean4/pull/5680/files.

Tobias Grosser (Oct 13 2024 at 05:33):

Unfortunately, I get the seemingly unrelated error in FloatArray:

  type mismatch
    fun xs i h => xs.uget i h
  has type
    (xs : FloatArray)  (i : USize)  i.val < xs.size  Float : Type
  but is expected to have type
    (xs : FloatArray)  (i : USize)  i.val < xs.size  Float : Type

This code worked before , but fails after adding:

  instance instNatCast [NeZero n] : NatCast (Fin n) where
  natCast n := Fin.ofNat'' n

Tobias Grosser (Oct 13 2024 at 05:33):

This error arises in these lines (where I added explicit type annotations to simplify debugging)

instance : GetElem FloatArray USize Float fun xs i => i.val < xs.size where
  getElem xs i (h : @LT.lt Nat instLTNat (i.val) xs.size) := xs.uget i h

François G. Dorais (Oct 13 2024 at 12:29):

The instance at https://github.com/leanprover/lean4/blob/1d8555fe0bdd02c82664446309b2e167ac89c9e9/src/Init/Data/FloatArray/Basic.lean#L65C1-L67C1 should be:

instance : GetElem FloatArray USize Float fun xs i => i.toNat < xs.size where
  getElem xs i h := xs.uget i h

The issue is that i.val is actually Fin USize.size instead of Nat, which picks out the wrong coercion.

Tobias Grosser (Oct 13 2024 at 12:32):

This seems to work. Thank you, @François G. Dorais.

Notification Bot (Oct 13 2024 at 12:32):

Tobias Grosser has marked this topic as resolved.

Tobias Grosser (Oct 13 2024 at 12:36):

Actually, now I am in an entire new mess.

Tobias Grosser (Oct 13 2024 at 12:37):

It seems this cast lemmas has broken many things in Fin/Lemmas.lean.

Tobias Grosser (Oct 13 2024 at 12:38):

/-
application type mismatch
  Nat.le_of_lt_succ (is_lt i)
argument
  is_lt i
has type
  ↑i < n + 1 : Prop
but is expected to have type
  ↑i < (↑↑n).succ : Prop
-/
theorem is_le (i : Fin (n + 1)) : i  n := Nat.le_of_lt_succ i.is_lt

Notification Bot (Oct 13 2024 at 12:39):

Tobias Grosser has marked this topic as unresolved.

François G. Dorais (Oct 13 2024 at 12:40):

It's probably not ideal to have casts both ways between Nat and Fin. It's a coin toss which applies in each case.

Tobias Grosser (Oct 13 2024 at 12:40):

Right.

Tobias Grosser (Oct 13 2024 at 12:41):

I took this code from mathlib (https://github.com/leanprover-community/mathlib4/blob/81d66bb893988a10f0e7f3b5baa2f8bc0f35993f/Mathlib/Data/Fin/Basic.lean#L432), where this setup seems to work.

Mario Carneiro (Oct 13 2024 at 12:55):

Well not really, Kyle has frequently complained about essentially this issue. You should avoid binary operators between a Nat and a Fin unless you have a on one side because it's ambiguous.

Tobias Grosser (Oct 13 2024 at 13:10):

Interesting.

Tobias Grosser (Oct 13 2024 at 13:12):

I guess this means moving NatCast to Lean proper is a bad idea.

Tobias Grosser (Oct 13 2024 at 13:12):

Thank you for the insight.

Mario Carneiro (Oct 13 2024 at 13:25):

I think NatCast is already in lean proper?

Mario Carneiro (Oct 13 2024 at 13:25):

it just doesn't have an instance for Fin until it gets one indirectly in mathlib because it's a ring

Tobias Grosser (Oct 13 2024 at 13:25):

NatCast ist, but the following instance is not:
https://github.com/leanprover-community/mathlib4/blob/81d66bb893988a10f0e7f3b5baa2f8bc0f35993f/Mathlib/Data/Fin/Basic.lean#L432C1-L433C29

instance instNatCast [NeZero n] : NatCast (Fin n) where
  natCast n := Fin.ofNat'' n

Tobias Grosser (Oct 13 2024 at 13:26):

(Also, it seems to get this instance directly, AFAIU the code above)

Mario Carneiro (Oct 13 2024 at 13:26):

ah, that may be true but I think that's just to avoid diamond issues

Tobias Grosser (Oct 13 2024 at 13:26):

Right.

Tobias Grosser (Oct 13 2024 at 13:28):

I am working towards upstreaming: https://github.com/opencompl/lean-mlir/blob/main/SSA/Projects/InstCombine/ForMathlib.lean and am trying to see where each theorem fits best (Lean vs. Mathlib)

Tobias Grosser (Oct 13 2024 at 13:28):

The objective is to define:

instance : CommRing (BitVec w) :=
  toFin_injective.commRing _
    toFin_zero toFin_one toFin_add toFin_mul toFin_neg toFin_sub
    toFin_nsmul toFin_zsmul toFin_pow toFin_natCast toFin_intCast

Tobias Grosser (Oct 13 2024 at 13:29):

To unbreak https://github.com/leanprover/lean4/pull/5323.

Mario Carneiro (Oct 13 2024 at 13:29):

well, I see a ring-shaped issue with upstreaming that

Tobias Grosser (Oct 13 2024 at 13:29):

Can you expand on this.

Mario Carneiro (Oct 13 2024 at 13:30):

CommRing is largely agreed to be the domain of mathlib

Mario Carneiro (Oct 13 2024 at 13:30):

so if you need that specifically then I don't think it can be upstreamed

Tobias Grosser (Oct 13 2024 at 13:31):

Ah, I want to upstream the CommRing instance into Mathlib.

Mario Carneiro (Oct 13 2024 at 13:32):

oh, well then there are no problems, and also this thread is in the wrong stream?

Tobias Grosser (Oct 13 2024 at 13:32):

Henrik's patch to Lean4 which transitions uint to bitvec breaks the mathlib build, due to a missing CommRing instance for BitVec.

Tobias Grosser (Oct 13 2024 at 13:32):

So this thread covers both Lean4 and Mathlib.

Tobias Grosser (Oct 13 2024 at 13:33):

So I am trying to break apart the changes that must be made to keep things in the right domains.

Tobias Grosser (Oct 13 2024 at 13:33):

AFAIU BitVec lemmas should go into lean, but CommRing into mathlib.

Mario Carneiro (Oct 13 2024 at 13:33):

I'm confused, can you explain the context and situation here?

Tobias Grosser (Oct 13 2024 at 13:34):

Right, some context might be useful. :smile:

Tobias Grosser (Oct 13 2024 at 13:34):

There is this Lean4 patch currently proposed to Lean: https://github.com/leanprover/lean4/pull/5323

Mario Carneiro (Oct 13 2024 at 13:35):

hm, I'm already mild negative on this, I thought we didn't want to involve BitVecs in math

Tobias Grosser (Oct 13 2024 at 13:36):

I see.

Tobias Grosser (Oct 13 2024 at 13:36):

So you feel uint counts as 'math'?

Mario Carneiro (Oct 13 2024 at 13:37):

yes

Mario Carneiro (Oct 13 2024 at 13:37):

at least, it's going to make it a lot harder to avoid bitvecs in unrelated code going forward

Mario Carneiro (Oct 13 2024 at 13:39):

but anyway, I guess this is an independent discussion. How does this result in needing a CommRing instance on BitVec?

Mario Carneiro (Oct 13 2024 at 13:40):

(which by the way clearly looks like "involving bitvecs in math" so my worries are not unfounded)

Tobias Grosser (Oct 13 2024 at 13:41):

The CommRing instance of UInt requires updating: https://github.com/leanprover-community/mathlib4/blob/lean-pr-testing-5323/Mathlib/Data/UInt.lean#L77

Mario Carneiro (Oct 13 2024 at 13:42):

Some time ago there was a push to get mathlib to avoid even mentioning the type BitVec, so this is a bit of reversal

Tobias Grosser (Oct 13 2024 at 13:42):

So it seemed natural to me to first define CommRing for BitVec and then using this definition.

Mario Carneiro (Oct 13 2024 at 13:42):

but that said I think we should have the instance

Mario Carneiro (Oct 13 2024 at 13:43):

but shouldn't the proof basically look just like those UInt proofs? Transfer an injective function and then all the proofs are rfl

Mario Carneiro (Oct 13 2024 at 13:47):

also, what is up with this deprecation?

warning: ././././Mathlib/Data/UInt.lean:26:0: `UInt8.eq_of_val_eq` has been deprecated, use `UInt8.eq_of_toBitVec_eq` instead

The API should let me step over the bitvec step if I want to

Tobias Grosser (Oct 13 2024 at 13:48):

I guess there are several parts of this conversation. I am mostly interested in defining CommRing (BigVec w).

Mario Carneiro (Oct 13 2024 at 13:50):

I think the answer to that is to just upstream everything to mathlib

Tobias Grosser (Oct 13 2024 at 13:50):

To keep the conversation focused (and complexity at a level that is suitable for my mathlib skills), maybe its best if I create a simple PR for the CommRing instance.

Tobias Grosser (Oct 13 2024 at 13:51):

I will propose a patch for https://github.com/leanprover-community/mathlib4/blob/master/Mathlib/Data/BitVec.lean.

Tobias Grosser (Oct 13 2024 at 13:51):

Thank you.

Henrik Böving (Oct 13 2024 at 13:58):

Mario Carneiro said:

but shouldn't the proof basically look just like those UInt proofs? Transfer an injective function and then all the proofs are rfl

There is a single proof that is not refl as explained in the PR

Henrik Böving (Oct 13 2024 at 13:59):

Mario Carneiro said:

but anyway, I guess this is an independent discussion. How does this result in needing a CommRing instance on BitVec?

Using the BitVec instance to define the UInt one should be the right way to go because we want to have BitVec in between UInt and Fin now no?

Henrik Böving (Oct 13 2024 at 14:00):

Mario Carneiro said:

also, what is up with this deprecation?

warning: ././././Mathlib/Data/UInt.lean:26:0: `UInt8.eq_of_val_eq` has been deprecated, use `UInt8.eq_of_toBitVec_eq` instead

The API should let me step over the bitvec step if I want to

You can do that by using the proper lemma in BitVec, I don't think we shoudl expose the transitive closure of our abstraction level shfit lemmas as explicit lemmas

Tobias Grosser (Oct 13 2024 at 14:00):

OK, the CommRing instance seems to work: https://github.com/leanprover-community/mathlib4/pull/17700

Tobias Grosser (Oct 13 2024 at 14:01):

I am currently cleaning this up.

Mario Carneiro (Oct 13 2024 at 14:08):

Henrik Böving said:

Mario Carneiro said:

also, what is up with this deprecation?

warning: ././././Mathlib/Data/UInt.lean:26:0: `UInt8.eq_of_val_eq` has been deprecated, use `UInt8.eq_of_toBitVec_eq` instead

The API should let me step over the bitvec step if I want to

You can do that by using the proper lemma in BitVec, I don't think we shoudl expose the transitive closure of our abstraction level shfit lemmas as explicit lemmas

We should if that's the API people were using before

Mario Carneiro (Oct 13 2024 at 14:08):

just because core wants to define things this way doesn't mean downstream users want to deal with this too

Mario Carneiro (Oct 13 2024 at 14:09):

There are now 3 steps from UInt8 to Nat, I don't want to have to apply 3 lemmas instead of 1

Henrik Böving (Oct 13 2024 at 14:11):

Well there should just, not be a need to do this in almost all situations after the API is finished.

Mario Carneiro (Oct 13 2024 at 14:12):

Henrik Böving said:

Mario Carneiro said:

but shouldn't the proof basically look just like those UInt proofs? Transfer an injective function and then all the proofs are rfl

There is a single proof that is not refl as explained in the PR

Not explained as far as I can tell, but mentioned once. What's the issue exactly?

Henrik Böving (Oct 13 2024 at 14:13):

https://github.com/leanprover/lean4/pull/5323#issuecomment-2407062190

I addressed all comments and everything in batteries and mathlib apart from a singular sorry here: https://github.com/leanprover-community/mathlib4/blob/lean-pr-testing-5323/Mathlib/Data/UInt.lean#L77 is fixed. This was previously rfl but is now not rfl anymore. It also appears there is very little API around this thing so I don't quite see how to do a nice proof here without definition bashing.

Mario Carneiro (Oct 13 2024 at 14:13):

Henrik Böving said:

Well there should just, not be a need to do this in almost all situations after the API is finished.

There should not be a need to relate unsigned integers to natural numbers?

Mario Carneiro (Oct 13 2024 at 14:13):

@Henrik Böving yes I see that, that's what I call a mention

Mario Carneiro (Oct 13 2024 at 14:13):

it's just restating what you said

Mario Carneiro (Oct 13 2024 at 14:13):

what is not refl and why?

Henrik Böving (Oct 13 2024 at 14:14):

The proof that is linked?

Mario Carneiro (Oct 13 2024 at 14:14):

I see a sorry, do you want me to compile it to find out the goal?

Mario Carneiro (Oct 13 2024 at 14:15):

it also doesn't answer the why

Mario Carneiro (Oct 13 2024 at 14:15):

which change broke it?

Henrik Böving (Oct 13 2024 at 14:16):

Having the redefinition of UInt in terms of BitVec and then fixing the file you are looking at in a way that Kim deemed reasonable broke it.

Mario Carneiro (Oct 13 2024 at 14:17):

this is completely not answering the question

Mario Carneiro (Oct 13 2024 at 14:17):

you are saying all of the things I knew before looking at the PR

Mario Carneiro (Oct 13 2024 at 14:17):

what specifically did you change and why is it causing this breakage

Tobias Grosser (Oct 13 2024 at 14:18):

I guess I can compile it and see what's going on. Might be a learning experience for me as well.

Henrik Böving (Oct 13 2024 at 14:20):

The proof state is

x : 
 (x).val = x

where the lhs casts Int to UInt8 and the rhs casts int to Fin. I presume that the fact that .val is now not the only projection of the structure anymore broke the rfl thing, I do not know why it broke precisely.

Tobias Grosser (Oct 13 2024 at 14:32):

I can reproduce this proof state in my build:

x : 
 (x).val = x

Tobias Grosser (Oct 13 2024 at 14:36):

Francois advised me to use .toNat instead of .val at some point.

Tobias Grosser (Oct 13 2024 at 14:37):

Maybe the same ambiguity is biting us here.

Mario Carneiro (Oct 13 2024 at 14:37):

I don't think ambiguity can explain a non-refl proof, this is a change of definitions

Tobias Grosser (Oct 13 2024 at 14:38):

How do I track this down?

Tobias Grosser (Oct 13 2024 at 14:41):

https://github.com/leanprover-community/mathlib4/commit/0aa61183b0ba32a07b90fc6fb5fea72f876fde17 seems harmless.

Mario Carneiro (Oct 13 2024 at 14:41):

So if we work out the definitions:

  • ↑(x : Int) : UInt8 is defined as mk (↑(x : Int) : BitVec 8) (note that it's BitVec and not Fin now)
  • which resolves via the IntCast (BitVec 8) instance, which comes from... nowhere?

Mario Carneiro (Oct 13 2024 at 14:41):

master has a CommSemiring instance but not a CommRing instance for BitVec

Mario Carneiro (Oct 13 2024 at 14:41):

so I'm not sure who is providing this intcast instance

Mario Carneiro (Oct 13 2024 at 14:43):

basically the problem in 0aa6118 is that line 70 (which was not touched) uses the mk function which has silently changed type

Tobias Grosser (Oct 13 2024 at 14:43):

Right.

Tobias Grosser (Oct 13 2024 at 14:44):

But should this line not break, if there is no IntCast instance for UInt via BitVec?

Mario Carneiro (Oct 13 2024 at 14:44):

but I'm not sure how this typechecks in the first place

Mario Carneiro (Oct 13 2024 at 14:44):

that line should be a type error if there is no IntCast instance for BitVec

Mario Carneiro (Oct 13 2024 at 14:44):

so such an instance must exist somehow

Henrik Böving (Oct 13 2024 at 14:45):

Yeah it sits in core

Mario Carneiro (Oct 13 2024 at 14:45):

and its definition is apparently not defeq to the original definition which used mod on Fin n

Henrik Böving (Oct 13 2024 at 14:45):

https://loogle.lean-lang.org/?q=IntCast+%28BitVec+%3Fw%29

Tobias Grosser (Oct 13 2024 at 14:49):

Interesting.

Tobias Grosser (Oct 13 2024 at 14:49):

Thank you for understanding this.

Mario Carneiro (Oct 13 2024 at 14:49):

So what is the IntCast (Fin n) definition defeq to?

Mario Carneiro (Oct 13 2024 at 14:50):

that is the RHS of the goal

Mario Carneiro (Oct 13 2024 at 14:51):

it seems like the LHS should be defeq to x % Int.ofNat 256 which looks okay

Tobias Grosser (Oct 13 2024 at 14:53):

I am afraid I don't fully follow.

Tobias Grosser (Oct 13 2024 at 14:53):

How did you derive this?

Mario Carneiro (Oct 13 2024 at 14:55):

Because of structure eta, we only really care about the nat part of the expression, the rest is just proofs. So all the mk wrappers do nothing, and val just cancels those wrappers out anyway. The only part that matters is the nat part of src#BitVec.ofInt , which is (i % (Int.ofNat (2^n))).toNat

Mario Carneiro (Oct 13 2024 at 14:56):

actually I guess the .toNat part could also be troublesome

Mario Carneiro (Oct 13 2024 at 14:56):

there was something in the PR description about removing some variant of mod, maybe this is the issue?

Tobias Grosser (Oct 13 2024 at 14:57):

I feel the mod issue is unrelated.

Henrik Böving (Oct 13 2024 at 14:57):

That variant of mod was removing UIntx mod Nat in favor of just having UintX mod UIntX

Tobias Grosser (Oct 13 2024 at 14:57):

The definition of BitVec.ofInt is historically grown.

Tobias Grosser (Oct 13 2024 at 14:58):

Where do I find the intCast instance of Fin, which was used before?

Tobias Grosser (Oct 13 2024 at 14:58):

Loogle does not help: https://loogle.lean-lang.org/?q=IntCast+%28Fin+%3Fw%29

Mario Carneiro (Oct 13 2024 at 14:58):

Henrik Böving said:

That variant of mod was removing UIntx mod Nat in favor of just having UintX mod UIntX

That's not a valid replacement?

Mario Carneiro (Oct 13 2024 at 14:59):

if you mod by something larger than 256 it's not equivalent to reducing the denominator first

Mario Carneiro (Oct 13 2024 at 15:00):

but I don't think it's implicated here, at least I haven't found any calls to modn appearing in these functions

Mario Carneiro (Oct 13 2024 at 15:00):

what does #synth IntCast (Fin 256) give you @Tobias Grosser ?

Tobias Grosser (Oct 13 2024 at 15:01):

Ring.toIntCast

Henrik Böving (Oct 13 2024 at 15:01):

modn was only used to define left and right shift such that it doesn't cause UB in core and that def can be easily done with just UInt

Mario Carneiro (Oct 13 2024 at 15:02):

you should be able to hover the expression until you find something that's actually about Fin

Mario Carneiro (Oct 13 2024 at 15:03):

I don't think it's about UB, the function has different semantics

Henrik Böving (Oct 13 2024 at 15:03):

It is about UB in core

Mario Carneiro (Oct 13 2024 at 15:03):

I agree that in the case of modding by a constant like 8 it makes no difference

Henrik Böving (Oct 13 2024 at 15:04):

Shifting to the left on a UIntX by more than X is UB. So the shifter is changed. This was previously modn and is now just mod

Tobias Grosser (Oct 13 2024 at 15:04):

@Ring.toIntCast (Fin 256) CommRing.toRing : IntCast (Fin 256)

Mario Carneiro (Oct 13 2024 at 15:04):

that's C semantics, not lean

Tobias Grosser (Oct 13 2024 at 15:04):

@CommRing.toRing (Fin 256) (Fin.instCommRing 256)

Mario Carneiro (Oct 13 2024 at 15:04):

in lean shifting to the left should just result in multiplication by 2^n and then modding by the byte size

Henrik Böving (Oct 13 2024 at 15:05):

Yes, but the Lean function has to reflect what we implemented in the C runtime. And this is what is implemented in the C rutnime.

Henrik Böving (Oct 13 2024 at 15:05):

I've been over this discussion already internally and it was decided to keep it the way it is at least for now.

Mario Carneiro (Oct 13 2024 at 15:06):

suggesting that users replace uses of modn with mod is dangerous because it's not semantics preserving

Tobias Grosser (Oct 13 2024 at 15:07):

Mario Carneiro said:

suggesting that users replace uses of modn with mod is dangerous because it's not semantics preserving

Interesting observation.

Mario Carneiro (Oct 13 2024 at 15:07):

if you want to remove native support for modn it can still be simulated with a branch on the value

Mario Carneiro (Oct 13 2024 at 15:08):

if h : b < UIntN.size then a % <<b, h>> else a

Henrik Böving (Oct 13 2024 at 15:11):

You can discuss that one out with reviewers on the PR if you like.

Mario Carneiro (Oct 13 2024 at 15:12):

Tobias Grosser said:

@CommRing.toRing (Fin 256) (Fin.instCommRing 256)

I don't see anything in src#Fin.instCommRing which would give the value of intCast, so it's probably getting the default implementation, which is not a mod expression

Tobias Grosser (Oct 13 2024 at 15:12):

Where do I find the default implementation?

Henrik Böving (Oct 13 2024 at 15:12):

Besides, it's not like modn is deleted, it's just that there is this signular change of not havign modn coming up in shfits anymore and generally preferring mod over modn in API lemmas when applicable.

Tobias Grosser (Oct 13 2024 at 15:14):

/-- Default value for `IntCast.intCast` in an `AddGroupWithOne`. -/
protected def Int.castDef {R : Type u} [NatCast R] [Neg R] :   R
  | (n : ) => n
  | Int.negSucc n => -(n + 1 : )

Mario Carneiro (Oct 13 2024 at 15:15):

Henrik Böving said:

Besides, it's not like modn is deleted, it's just that there is this signular change of not havign modn coming up in shfits anymore and generally preferring mod over modn in API lemmas when applicable.

In this case, modn should either not be deprecated or should have a deprecation which does not just point at UintN.mod but uses text to explain what the options are

Mario Carneiro (Oct 13 2024 at 15:16):

Replacing modn with mod in shifts is perfectly fine, the part I find questionable is the removal of the functions (which may have been in use downstream)

Mario Carneiro (Oct 13 2024 at 15:17):

and I have confirmed that Fin.instCommRing uses src#Int.castDef

Henrik Böving (Oct 13 2024 at 15:17):

Henrik Böving said:

You can discuss that one out with reviewers on the PR if you like.

^

Henrik Böving (Oct 13 2024 at 15:18):

There is two people on the PR that think this change is fine, you don't think it's fine, I don't care what happens as long as it gets merged.

Tobias Grosser (Oct 13 2024 at 15:20):

Mario Carneiro said:

and I have confirmed that Fin.instCommRing uses src#Int.castDef

Right.

Tobias Grosser (Oct 13 2024 at 15:21):

I guess now we now why the casts have changed semantics.

Tobias Grosser (Oct 13 2024 at 15:21):

I feel the new definition is a bit more correct than the old one.

Tobias Grosser (Oct 13 2024 at 15:21):

Meaning, it implements two's complement conversion or sth similar.

Tobias Grosser (Oct 13 2024 at 15:22):

I guess it is obvious to you why the refl proof breaks and how to fix it?

Mario Carneiro (Oct 13 2024 at 15:23):

The implementation of intCast for Fin should also use mod

Mario Carneiro (Oct 13 2024 at 15:24):

I think you just need to add a line to src#Fin.instCommRing for this

Mario Carneiro (Oct 13 2024 at 15:24):

although maybe it is better to separately define IntCast (Fin n) and then add it to the structure before the where

Tobias Grosser (Oct 13 2024 at 15:25):

And I guess I would define Fin.ofInt as well?

Mario Carneiro (Oct 13 2024 at 15:26):

surely this already exists?

Tobias Grosser (Oct 13 2024 at 15:26):

https://loogle.lean-lang.org/?q=Fin.ofInt

Tobias Grosser (Oct 13 2024 at 15:26):

unknown identifier 'Fin.ofInt'

Mario Carneiro (Oct 13 2024 at 15:26):

@loogle Int -> Fin ?n

loogle (Oct 13 2024 at 15:26):

:shrug: nothing found

Mario Carneiro (Oct 13 2024 at 15:27):

src#BitVec.ofInt seems to be reinventing such a function

Mario Carneiro (Oct 13 2024 at 15:28):

in fact I think you could just copy and paste that function with n instead of 2^n

Tobias Grosser (Oct 13 2024 at 15:36):

Like this:

protected def ofInt (n : Nat) (i : Int) : Fin n := (Int.toNat (i % (Int.ofNat n))), by sorry

Mario Carneiro (Oct 13 2024 at 15:38):

yes, and then instance intCast : IntCast (Fin n) := \<Fin.ofInt\> and instance : CommRing (Fin n) := { ..., Fin.intCast n with ... }

Tobias Grosser (Oct 13 2024 at 15:38):

OK.

Mario Carneiro (Oct 13 2024 at 15:39):

hopefully you should be able to confirm that adding those lines makes the sorry in question rfl again

Mario Carneiro (Oct 13 2024 at 15:41):

Although, if the goal is to make this file only go via toBitVec instead of val, then probably the CommRing UIntN proof should be lifting from toBitVec (which would make this proof rfl anyway since now both sides will be using the bitvec ofInt implementation), but you will also need that CommRing (BitVec n) instance in that case

Henrik Böving (Oct 13 2024 at 15:45):

That was the original goal of this thread as explained above yes.

Tobias Grosser (Oct 13 2024 at 15:47):

OK, this gives a clear path forward.

Tobias Grosser (Oct 13 2024 at 15:47):

Thanks a lot.

Henrik Böving (Oct 13 2024 at 15:48):

But thanks for figuring out the defeq issue for us :thumbs_up:

Eric Wieser (Oct 17 2024 at 20:26):

Should the definition use docs#Int.natMod ?

Mario Carneiro (Oct 18 2024 at 20:38):

it's defeq to it either way


Last updated: May 02 2025 at 03:31 UTC