@@ -28,6 +28,7 @@ open Int
2828namespace Rat
2929
3030variable {α : Type *} [Field α] [LinearOrder α] [IsStrictOrderedRing α] [FloorRing α]
31+ variable {R : Type *} [Ring R] [LinearOrder R] [IsStrictOrderedRing R] [FloorRing R]
3132
3233@[deprecated Rat.le_floor_iff (since := "2025-09-02")]
3334protected theorem le_floor {z : ℤ} : ∀ {r : ℚ}, z ≤ Rat.floor r ↔ (z : ℚ) ≤ r
@@ -228,6 +229,60 @@ def evalIntCeil : NormNumExt where eval {u αZ} e := do
228229 return .isNegNat q(inferInstance) z q(isInt_intCeil_ofIsRat_neg $x $n $d $h)
229230 | _, _, _ => failure
230231
232+ theorem isNat_intFract_of_isNat (r : R) (m : ℕ) : IsNat r m → IsNat (Int.fract r) 0 := by
233+ rintro ⟨⟨⟩⟩; exact ⟨by simp⟩
234+
235+ theorem isNat_intFract_of_isInt (r : R) (m : ℤ) : IsInt r m → IsNat (Int.fract r) 0 := by
236+ rintro ⟨⟨⟩⟩; exact ⟨by simp⟩
237+
238+ theorem isNNRat_intFract_of_isNNRat (r : α) (n d : ℕ) :
239+ IsNNRat r n d → IsNNRat (Int.fract r) (n % d) d := by
240+ rintro ⟨inv, rfl⟩
241+ refine ⟨inv, ?_⟩
242+ simp only [invOf_eq_inv, ← div_eq_mul_inv, fract_div_natCast_eq_div_natCast_mod]
243+
244+ theorem isRat_intFract_of_isRat_negOfNat (r : α) (n d : ℕ) :
245+ IsRat r (negOfNat n) d → IsRat (Int.fract r) (-n % d) d := by
246+ rintro ⟨inv, rfl⟩
247+ refine ⟨inv, ?_⟩
248+ simp only [invOf_eq_inv, ← div_eq_mul_inv, fract_div_intCast_eq_div_intCast_mod,
249+ negOfNat_eq, ofNat_eq_coe]
250+
251+ /-- `norm_num` extension for `Int.fract` -/
252+ @[norm_num (Int.fract _)]
253+ def evalIntFract : NormNumExt where eval {u α} e := do
254+ match e with
255+ | ~q(@Int.fract _ $instR $instO $instF $x) =>
256+ match ← derive x with
257+ | .isBool .. => failure
258+ | .isNat _ _ pb => do
259+ let _i ← synthInstanceQ q(IsStrictOrderedRing $α)
260+ assertInstancesCommute
261+ have z : Q(ℕ) := Lean.mkRawNatLit 0
262+ letI : $z =Q 0 := ⟨⟩
263+ return .isNat _ z q(isNat_intFract_of_isNat $x _ $pb)
264+ | .isNegNat _ _ pb => do
265+ let _i ← synthInstanceQ q(IsStrictOrderedRing $α)
266+ assertInstancesCommute
267+ have z : Q(ℕ) := Lean.mkRawNatLit 0
268+ letI : $z =Q 0 := ⟨⟩
269+ return .isNat _ z q(isNat_intFract_of_isInt _ _ $pb)
270+ | .isNNRat _ q n d h => do
271+ let _i ← synthInstanceQ q(Field $α)
272+ let _i ← synthInstanceQ q(IsStrictOrderedRing $α)
273+ assertInstancesCommute
274+ have n' : Q(ℕ) := Lean.mkRawNatLit (q.num.natAbs % q.den)
275+ letI : $n' =Q $n % $d := ⟨⟩
276+ return .isNNRat _ (Int.fract q) n' d q(isNNRat_intFract_of_isNNRat _ $n $d $h)
277+ | .isNegNNRat _ q n d h => do
278+ let _i ← synthInstanceQ q(Field $α)
279+ let _i ← synthInstanceQ q(IsStrictOrderedRing $α)
280+ assertInstancesCommute
281+ have n' : Q(ℤ) := mkRawIntLit (q.num % q.den)
282+ letI : $n' =Q -$n % $d := ⟨⟩
283+ return .isRat _ (Int.fract q) n' d q(isRat_intFract_of_isRat_negOfNat _ $n $d $h)
284+ | _, _, _ => failure
285+
231286end NormNum
232287
233288end Rat
0 commit comments