@@ -49,7 +49,7 @@ instance : FloorRing ℚ :=
49
49
50
50
protected theorem floor_def {q : ℚ} : ⌊q⌋ = q.num / q.den := Rat.floor_def' q
51
51
52
- theorem floor_int_div_nat_eq_div { n : ℤ} { d : ℕ} : ⌊(↑n : ℚ) / (↑d : ℚ)⌋ = n / (↑d : ℤ) := by
52
+ theorem floor_int_div_nat_eq_div ( n : ℤ) ( d : ℕ) : ⌊(↑n : ℚ) / (↑d : ℚ)⌋ = n / (↑d : ℤ) := by
53
53
rw [Rat.floor_def]
54
54
obtain rfl | hd := @eq_zero_or_pos _ _ d
55
55
· simp
@@ -78,6 +78,48 @@ theorem round_cast (x : ℚ) : round (x : α) = round x := by
78
78
theorem cast_fract (x : ℚ) : (↑(fract x) : α) = fract (x : α) := by
79
79
simp only [fract, cast_sub, cast_intCast, floor_cast]
80
80
81
+ section NormNum
82
+
83
+ open Mathlib.Meta.NormNum Qq
84
+
85
+ theorem isNat_intFloor {R} [LinearOrderedRing R] [FloorRing R] (r : R) (m : ℕ) :
86
+ IsNat r m → IsNat ⌊r⌋ m := by rintro ⟨⟨⟩⟩; exact ⟨by simp⟩
87
+
88
+ theorem isInt_intFloor {R} [LinearOrderedRing R] [FloorRing R] (r : R) (m : ℤ) :
89
+ IsInt r m → IsInt ⌊r⌋ m := by rintro ⟨⟨⟩⟩; exact ⟨by simp⟩
90
+
91
+ theorem isInt_intFloor_ofIsRat (r : α) (n : ℤ) (d : ℕ) :
92
+ IsRat r n d → IsInt ⌊r⌋ (n / d) := by
93
+ rintro ⟨inv, rfl⟩
94
+ constructor
95
+ simp only [invOf_eq_inv, ← div_eq_mul_inv, Int.cast_id]
96
+ rw [← floor_int_div_nat_eq_div n d, ← floor_cast (α := α), Rat.cast_div,
97
+ cast_intCast, cast_natCast]
98
+
99
+ /-- `norm_num` extension for `Int.floor` -/
100
+ @[norm_num ⌊_⌋]
101
+ def evalIntFloor : NormNumExt where eval {u αZ} e := do
102
+ match u, αZ, e with
103
+ | 0 , ~q(ℤ), ~q(@Int.floor $α $instR $instF $x) =>
104
+ match ← derive x with
105
+ | .isBool .. => failure
106
+ | .isNat sα nb pb => do
107
+ assertInstancesCommute
108
+ return .isNat q(inferInstance) _ q(isNat_intFloor $x _ $pb)
109
+ | .isNegNat sα nb pb => do
110
+ assertInstancesCommute
111
+ -- floor always keeps naturals negative, so we can shortcut `.isInt`
112
+ return .isNegNat q(inferInstance) _ q(isInt_intFloor _ _ $pb)
113
+ | .isRat dα q n d h => do
114
+ let _i ← synthInstanceQ q(LinearOrderedField $α)
115
+ assertInstancesCommute
116
+ have z : Q(ℤ) := mkRawIntLit ⌊q⌋
117
+ letI : $z =Q ⌊$n / $d⌋ := ⟨⟩
118
+ return .isInt q(inferInstance) z ⌊q⌋ q(isInt_intFloor_ofIsRat _ $n $d $h)
119
+ | _, _, _ => failure
120
+
121
+ end NormNum
122
+
81
123
end Rat
82
124
83
125
theorem Int.mod_nat_eq_sub_mul_floor_rat_div {n : ℤ} {d : ℕ} : n % d = n - d * ⌊(n : ℚ) / d⌋ := by
0 commit comments