Skip to content

Commit c8193e0

Browse files
Garmelongithub-actions[bot]david-christiansendatokratsgraf812
authored
chore: bump toolchain to v4.33.0-rc1 (#897)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: David Thrane Christiansen <david@lean-fro.org> Co-authored-by: David Thrane Christiansen <david@davidchristiansen.dk> Co-authored-by: Paul Reichert <6992158+datokrat@users.noreply.github.com> Co-authored-by: Sebastian Graf <sgraf1337@gmail.com> Co-authored-by: Robert J. Simmons <442315+robsimmons@users.noreply.github.com> Co-authored-by: Kim Morrison <477956+kim-em@users.noreply.github.com> Co-authored-by: Pim Otte <otte.pim@gmail.com> Co-authored-by: Phil Nguyen <pcn@cs.umd.edu> Co-authored-by: Violetta Sim <38787503+eyihluyc@users.noreply.github.com> Co-authored-by: Markus Himmel <markus@himmel-villmar.de> Co-authored-by: Anne Baanen <Vierkantor@users.noreply.github.com> Co-authored-by: euprunin <178733547+euprunin@users.noreply.github.com> Co-authored-by: u <u@h> Co-authored-by: Pablo Graubner <2234137+pgraubner@users.noreply.github.com> Co-authored-by: Anne C.A. Baanen <vierkantor@vierkantor.com> Co-authored-by: Marc Huisinga <mhuisi@protonmail.com> Co-authored-by: Joachim Breitner <mail@joachim-breitner.de> Co-authored-by: jrr6 <7482866+jrr6@users.noreply.github.com> Co-authored-by: Leonardo de Moura <leomoura@amazon.com> Co-authored-by: Johan Commelin <johan@commelin.net> Co-authored-by: Sebastian Ullrich <sebasti@nullri.ch> Co-authored-by: jcreedcmu <jcreed@gmail.com> Co-authored-by: Violetta Sim <38787503+viol37@users.noreply.github.com> Co-authored-by: Rob Simmons <rob@lean-fro.org> Co-authored-by: leanprover-bot <leanprover-bot@lean-fro.org> Co-authored-by: Kim Morrison <kim@tqft.net> Co-authored-by: github-actions <github-actions@github.com> Co-authored-by: Wojciech Różowski <wojciech@lean-fro.org> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: Richard Davison <richard.neil.davison@gmail.com> Co-authored-by: Chris Su <102528557+chrissuu@users.noreply.github.com> Co-authored-by: ericrbg-harmonic <eric@harmonic.fun> Co-authored-by: Mac Malone <tydeu@hatpress.net> Co-authored-by: Orfeas Stefanos Thyfronitis Litos <18602747+OrfeasLitos@users.noreply.github.com> Co-authored-by: Juan José Madrigal <juanjomadrigal326@gmail.com> Co-authored-by: Julien Cretin <github@ia0.eu>
1 parent 986f6e9 commit c8193e0

16 files changed

Lines changed: 833 additions & 119 deletions

Manual/BasicTypes/Char.lean

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,5 +180,3 @@ tag := "char-api-classes"
180180
## Unicode
181181

182182
{docstring Char.utf8Size}
183-
184-
{docstring Char.utf16Size}

Manual/BasicTypes/Float.lean

Lines changed: 138 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -25,74 +25,176 @@ tag := "Float"
2525

2626
Floating-point numbers are a an approximation of the real numbers that are efficiently implemented in computer hardware.
2727
Computations that use floating-point numbers are very efficient; however, the nature of the way that they approximate the real numbers is complex, with many corner cases.
28-
The IEEE 754 standard, which defines the floating-point format that is used on modern computers, allows hardware designers to make certain choices, and real systems differ in these small details.
28+
The IEEE 754 standard, which defines the floating-point format that is used on modern computers, allows hardware designers and programming language implementations to make certain choices, and real systems differ in these small details.
29+
Any given combination of hardware, operating system, C compiler, library versions, and even compilation flags can result in different behavior.
2930
For example, there are many distinct bit representations of `NaN`, the indicator that a result is undefined, and some platforms differ with respect to _which_ `NaN` is returned from adding two `NaN`s.
3031

31-
Lean exposes the underlying platform's floating-point values for use in programming, but they are not encoded in Lean's logic.
32-
They are represented by an opaque type.
33-
This means that the {tech}[kernel] is not capable of computing with or reasoning about floating-point values without additional {ref "axioms"}[axioms].
34-
A consequence of this is that equality of floating-point numbers is not decidable.
35-
Furthermore, comparisons between floating-point values are decidable, but the code that does so is opaque; in practice, the decision procedure can only be used in compiled code.
32+
To enable reasoning about floating-point numbers, Lean exposes a logical model of {name}`Float` that is used in proofs.
33+
In particular, {name}`Float` and {name}`Float32` are implemented as wrappers around the logical model.
34+
In compiled code, this logical model is replaced by efficient native code.
35+
Differences between platforms are resolved by choosing specific representations (for example, all `NaN` values are replaced by a single canonical `NaN` when any operation requests a bit representation) and by modeling only the subset of floating-point operations that are implemented identically on all supported platforms.
36+
Other operations, such as trigonometric functions, are represented as opaque functions in Lean's logic.
3637

37-
Lean provides two floating-point types: {name}`Float` represents 64-bit floating point values, while {name}`Float32` represents 32-bit floating point values.
38+
The logical model is extensively empirically tested against the floating-point operations on all supported platforms.
39+
As long as FFI code does not modify the floating-point environment, Lean's runtime floating-point primitives match the model's specification.
40+
41+
{docstring Float}
42+
43+
{docstring Float32}
44+
45+
# Logical Model
46+
47+
Lean provides two floating-point types: {name}`Float` represents 64-bit floating-point values, while {name}`Float32` represents 32-bit floating-point values.
3848
The precision of {name}`Float` does not vary based on the platform that Lean is running on.
3949

50+
## Model Details
51+
52+
The logical models of {lean}`Float` and {lean}`Float32` consist of unsigned integers with validity predicates.
53+
Each defined operation first interprets the integer into a {lean}`Float.Model.UnpackedFloat`, which is a higher-level model that is not specific to a bit width.
54+
Then, the defined operation is implemented in terms of {name Float.Model.UnpackedFloat}`UnpackedFloat`, and the result is re-packed.
55+
These definitions constitute a _logical specification_ designed for reasoning.
56+
Although they can be executed, they will run significantly slower than native code.
57+
Not all operations are defined; some are instead opaque functions whose behavior cannot be reasoned about in Lean's logic.
58+
59+
This model is not intended to serve as the basis for a more extensive floating-point library.
60+
It exists only to support the reasoning tools available in Lean and is not suitable for larger-scale development.
61+
Do not use this model as the basis of a more extensive floating-point library.
62+
Instead, implement a suitable model, prove the equivalence of the its operations to this model, and then transfer lemmas using the equivalence.
63+
64+
{docstring Float.Model}
65+
66+
{docstring Float32.Model}
67+
68+
{docstring Float.Model.pack}
69+
70+
{docstring Float32.Model.pack}
71+
72+
{docstring Float.Model.unpack}
73+
74+
{docstring Float32.Model.unpack}
75+
76+
{docstring Float.Model.UnpackedFloat}
77+
78+
## Model Operations
79+
80+
The following operations are specified for floating-point values.
81+
Other operators are represented by opaque functions and do not reduce in the kernel.
82+
83+
{docstring Float.Model.UnpackedFloat.add}
84+
85+
{docstring Float.Model.UnpackedFloat.sub}
86+
87+
{docstring Float.Model.UnpackedFloat.mul}
88+
89+
{docstring Float.Model.UnpackedFloat.div}
90+
91+
{docstring Float.Model.UnpackedFloat.sqrt}
92+
93+
{docstring Float.Model.UnpackedFloat.neg}
94+
95+
{docstring Float.Model.UnpackedFloat.abs}
96+
97+
{docstring Float.Model.UnpackedFloat.isNaN}
98+
99+
{docstring Float.Model.UnpackedFloat.isInf}
100+
101+
{docstring Float.Model.UnpackedFloat.isFinite}
102+
103+
{docstring Float.Model.UnpackedFloat.compare}
104+
105+
{docstring Float.Model.UnpackedFloat.beq}
106+
107+
{docstring Float.Model.UnpackedFloat.lt}
108+
109+
{docstring Float.Model.UnpackedFloat.le}
110+
111+
{docstring Float.Model.UnpackedFloat.ofNat}
112+
113+
{docstring Float.Model.UnpackedFloat.ofInt}
114+
115+
{docstring Float.Model.UnpackedFloat.ofScientific}
40116

41-
{docstring Float (label := "type") +hideStructureConstructor +hideFields}
117+
{docstring Float.Model.UnpackedFloat.toInt8}
42118

43-
{docstring Float32 (label := "type") +hideStructureConstructor +hideFields}
119+
{docstring Float.Model.UnpackedFloat.ofInt8}
44120

121+
{docstring Float.Model.UnpackedFloat.toInt16}
45122

46-
:::example "No Kernel Reasoning About Floating-Point Numbers"
123+
{docstring Float.Model.UnpackedFloat.ofInt16}
124+
125+
{docstring Float.Model.UnpackedFloat.toInt32}
126+
127+
{docstring Float.Model.UnpackedFloat.ofInt32}
128+
129+
{docstring Float.Model.UnpackedFloat.toInt64}
130+
131+
{docstring Float.Model.UnpackedFloat.ofInt64}
132+
133+
{docstring Float.Model.UnpackedFloat.toISize}
134+
135+
{docstring Float.Model.UnpackedFloat.ofISize}
136+
137+
{docstring Float.Model.UnpackedFloat.toUInt8}
138+
139+
{docstring Float.Model.UnpackedFloat.ofUInt8}
140+
141+
{docstring Float.Model.UnpackedFloat.toUInt16}
142+
143+
{docstring Float.Model.UnpackedFloat.ofUInt16}
144+
145+
{docstring Float.Model.UnpackedFloat.toUInt32}
146+
147+
{docstring Float.Model.UnpackedFloat.ofUInt32}
148+
149+
{docstring Float.Model.UnpackedFloat.toUInt64}
150+
151+
{docstring Float.Model.UnpackedFloat.ofUInt64}
152+
153+
{docstring Float.Model.UnpackedFloat.toUSize}
154+
155+
{docstring Float.Model.UnpackedFloat.ofUSize}
156+
157+
:::example "Kernel Reasoning"
47158
The Lean kernel can compare expressions of type {lean}`Float` for syntactic equality, so {lean (type := "Float")}`0.0` is definitionally equal to itself.
48159
```lean
49160
example : (0.0 : Float) = (0.0 : Float) := by rfl
50161
```
51162

52-
Terms that require reduction to become syntactically equal cannot be checked by the kernel:
53-
```lean +error (name := zeroPlusZero)
163+
Additionally, terms that require reduction to become syntactically equal can be checked by the kernel when they use only operations that are modeled in Lean's logic:
164+
```lean
54165
example : (0.0 : Float) = (0.0 + 0.0 : Float) := by rfl
55166
```
56-
```leanOutput zeroPlusZero
57-
Tactic `rfl` failed: The left-hand side
58-
0.0
59-
is not definitionally equal to the right-hand side
60-
0.0 + 0.0
61-
62-
0.0 = 0.0 + 0.0
63-
```
64-
65-
Similarly, the kernel cannot evaluate {lean}`Bool`-valued comparisons of floating-point numbers while checking definitional equality:
66-
```lean +error (name := zeroPlusZero') -keep
67-
theorem Float.zero_eq_zero_plus_zero :
68-
((0.0 : Float) == (0.0 + 0.0 : Float)) = true :=
69-
by rfl
167+
The kernel cannot reduce terms that use operations that are not directly modeled, such as trigonometric functions:
168+
```lean (name := sin0) +error
169+
example : (0.0 : Float).sin = (0.0 : Float) := by rfl
70170
```
71-
```leanOutput zeroPlusZero'
171+
```leanOutput sin0
72172
Tactic `rfl` failed: The left-hand side
73-
0.0 == 0.0 + 0.0
173+
Float.sin 0.0
74174
is not definitionally equal to the right-hand side
75-
true
175+
0.0
76176

77-
(0.0 == 0.0 + 0.0) = true
177+
Float.sin 0.0 = 0.0
78178
```
79179

80180

81181
However, the {tactic}`native_decide` tactic can invoke the underlying platform's floating-point primitives that are used by Lean for run-time programs:
82182
```lean
83-
theorem Float.zero_eq_zero_plus_zero :
84-
((0.0 : Float) == (0.0 + 0.0 : Float)) = true := by
183+
theorem Float.sin_zero_eq_zero :
184+
((0.0 : Float).sin == (0.0 : Float)) = true := by
85185
native_decide
86186
```
87187
This tactic executes a decision procedure as compiled native code.
88188
This requires trusting the Lean compiler, interpreter and the low-level implementations of built-in operators in addition to the kernel.
89-
To make this dependency precisely clear, the tactic creates the axiom {name}`Float.zero_eq_zero_plus_zero._native.native_decide.ax_1`:
189+
To make this dependency precisely clear, the tactic creates the axiom {name}`Float.sin_zero_eq_zero._native.native_decide.ax_1`:
90190
```lean (name := ofRed)
91-
#print axioms Float.zero_eq_zero_plus_zero
191+
#print axioms Float.sin_zero_eq_zero
92192
```
93193
```leanOutput ofRed
94-
'Float.zero_eq_zero_plus_zero' depends on axioms: [Classical.choice,
95-
Float.zero_eq_zero_plus_zero._native.native_decide.ax_1]
194+
'Float.sin_zero_eq_zero' depends on axioms: [propext,
195+
Classical.choice,
196+
Quot.sound,
197+
Float.sin_zero_eq_zero._native.native_decide.ax_1]
96198
```
97199
:::
98200

@@ -178,15 +280,6 @@ Floating-point numbers fall into one of three categories:
178280
{docstring Float32.isFinite}
179281

180282

181-
## Syntax
182-
183-
These operations exist to support the {inst}`OfScientific Float` and {inst}`OfScientific Float32` instances and are normally invoked indirectly as a result of a literal value.
184-
185-
{docstring Float.ofScientific}
186-
187-
{docstring Float32.ofScientific}
188-
189-
190283
## Conversions
191284

192285
{docstring Float.toBits}
@@ -253,10 +346,6 @@ These operations exist to support the {inst}`OfScientific Float` and {inst}`OfSc
253346

254347
{docstring Float32.ofNat}
255348

256-
{docstring Float.ofBinaryScientific}
257-
258-
{docstring Float32.ofBinaryScientific}
259-
260349
{docstring Float.frExp}
261350

262351
{docstring Float32.frExp}

0 commit comments

Comments
 (0)