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 asmk (↑(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
modNat
in favor of just havingUintX
modUIntX
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
withmod
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 preferringmod
overmodn
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