Commit graph

444 commits

Author SHA1 Message Date
Henrik Böving
406bda8807
feat: implement a Selector for async TCP (#8078)
This PR is a follow up to #8055 and implements a `Selector` for async
TCP in order to allow IO multiplexing using TCP sockets.

As we must not commit to actually fetching data from the socket buffer
this cannot be implemented by just racing on `recv?`. Instead we perform
a call to `uv_read_start` and pass an `alloc_cb` that allocates no
memory at all. According to the docs of
[`uv_alloc_cb`](https://docs.libuv.org/en/v1.x/handle.html#c.uv_alloc_cb)
this is guaranteed to give us a `UV_ENOBUFS` in the relevant callback.
Thus we can first run this "zero read" and then go into one of three
cases:
1. We get cancelled before the zero read completes, in this case just
cancel the zero read and give up.
2. The zero read completes and we loose the race for completing the
`select`, in this case just don't do anything anymore
3. The zero read completes and we win the race for completing the
`select`, in this case we perform the actual read on the socket. As we
know that data is available already (since the read callback of the zero
read is only triggered if data actually is available) we know that the
subsequent actual read should complete right away.

In this way we avoid any data loss if we loose the race.
2025-04-24 16:05:35 +00:00
Luisa Cicolini
bc032eec8d
feat: add BitVec.sdivOverflow definition and lemmas for overflow in signed and unsigned division (#7671)
This PR contains the theorem proving that signed division x.toInt /
y.toInt only overflows when `x = intMin w` and `y = allOnes w` (for `0 <
w`).
To show that this is the *only* case in which overflow happens, we refer
to overflow for negation
(`BitVec.sdivOverflow_eq_negOverflow_of_neg_one`): in fact,
`x.toInt/(allOnes w).toInt = - x.toInt`, i.e., the overflow conditions
are the same as `negOverflow` for `x`, and then reason about the signs
of the operands with the respective theorems.
These BitVec theorems themselves rely on numerous `Int.ediv_*` theorems,
that carefully set the bounds of signed division for integers.

co-authored by @bollu, @tobiasgrosser
2025-04-24 15:27:18 +00:00
Markus Himmel
68d9d14d44
chore: do not use the coercion α → Option α in Init and Std (#8085)
This PR moves the coercion `α → Option α` to the new file
`Init.Data.Option.Coe`. This file may not be imported anywhere in `Init`
or `Std`.
2025-04-24 13:35:01 +00:00
Markus Himmel
781c94f2cf
chore: test that there are no orphaned modules (#8082)
This PR adds a test that makes sure that there are no orphaned modules.
2025-04-24 11:55:07 +00:00
Paul Reichert
be66157583
fix: import all raw tree map modules into Std.Data (#8044)
This PR introduces the modules `Std.Data.DTreeMap.Raw`,
`Std.Data.TreeMap.Raw` and `Std.Data.TreeSet.Raw` and imports them into
`Std.Data`. All modules related to the raw tree maps are imported into
these new modules so that they are now a transitive dependency of `Std`.
2025-04-24 10:06:32 +00:00
Henrik Böving
58c7e5da94
feat: async IO multiplexing framework + implementation for timers (#8055)
This PR adds an implementation of an async IO multiplexing framework as
well as an implementation of it for the `Timer` API in order to
demonstrate it.

The main motivation is to have fair and data loss free multiplexing of
event sources.
To illustrate two situations where just naively racing two tasks that
read from an event source might be the wrong thing:
1. Suppose we are waiting on two channel reads that are continuously
being filled up. As the first channel will always be ready when we start
its receive function it will instantly resolve the race before the
second one can even try. Thus the path where we receive data from the
second channel gets starved. For this reason we want to try in random
order (for fairness) if the event sources already have data available
for us.
2. Suppose we are waiting on two socket reads and both happen to finish
at the same time. As we are now only going to select one of them to
execute further, we are going to loose data on the second one (unless
there is a user written buffering mechanism involved) as we are going to
disregard the buffer it received and do a new receive next time. For
this reason it is important to wait for an event source to be available
without committing to actually fetching some data until we know that
this particular event source is going to win the select race.

The implementation is inspired by the Oslo framework written by
@haesbaert as well as Go's
[`select`](https://go.dev/src/runtime/select.go) implementation. Given a
list of event sources to select one from it is going to:
1. Randomly shuffle them
2. Attempt to fetch data from them (in their new random order) without
blocking (for fairness). If any of them succeeds return right away.
3. If none has data available right away set all of them up to resolve a
promise. They will then race to win the right to resolve that promise.
Only the data source that wins the race is allowed to then actually
fetch data, ensuring that no other event source actually fetches data
and then fails to deliver it to the consumer.


Follow up PRs are going to add implementations of `Selector` for
`Std.Channel` as well as TCP and UDP sockets.

---------

Co-authored-by: Markus Himmel <markus@lean-fro.org>
2025-04-24 07:55:39 +00:00
Henrik Böving
8e1b9abb7a
fix: missing wakeup in bounded channel try receive (#8052)
This PR fixes a small oversight in the wakeup mechanism of blocked
bounded channel senders that occurs when calling `tryRecv`.

Marked as `changelog-no` as this isn't released yet.
2025-04-22 14:32:59 +00:00
Henrik Böving
39f7380663
perf: fix linearity issue in bv_decide (#8036)
This PR fixes a linearity issue in `bv_decide`'s bitblaster, caused by
the fact that the higher order combinators `AIG.RefVec.zip` and
`AIG.RefVec.fold` were not being properly specialised.

Example benchmark `QF_BV/sage/app1/bench_1967.smt2`:
- before: https://share.firefox.dev/4cE86It
- after: https://share.firefox.dev/42L9chd
2025-04-21 13:51:21 +00:00
Sebastian Ullrich
11f6326102
chore: un-orphan file (#8031)
This file is used in a test, which thus fails using `-DUSE_LAKE=ON`
2025-04-20 18:16:51 +00:00
Rob23oba
acfc9c50d5
feat: hash map lemmas for filter, map and filterMap (#7400)
This PR adds lemmas for the `filter`, `map` and `filterMap` functions of
the hash map.

---------

Co-authored-by: jt0202 <johannes.tantow@gmail.com>
Co-authored-by: Johannes Tantow <44068763+jt0202@users.noreply.github.com>
Co-authored-by: Markus Himmel <markus@himmel-villmar.de>
2025-04-17 10:15:52 +00:00
Markus Himmel
9d57ed83a9
chore: upstream Int lemmas from mathlib (#7983)
This PR upstreams many of the results from `Mathlib/Data/Int/Init.lean`.

Notably, we upstream the `simp` tag on `Int.natCast_pow`. While this is
desirable as a `simp` lemma, it is non-confluent with other good `simp`
lemmas like `Int.emod_bmod_congr`, and this will need to be addressed in
the future.
2025-04-16 17:45:08 +00:00
Rob23oba
7cca594a4a
chore: adjust BEq classes (#7855)
This PR moves `ReflBEq` to `Init.Core` and changes `LawfulBEq` to extend
`ReflBEq`.

**BREAKING CHANGES:**
- The `refl` field of `ReflBEq` has been renamed to `rfl` to match
`LawfulBEq`
- `LawfulBEq` extends `ReflBEq`, so in particular `LawfulBEq.rfl` is no
longer valid
2025-04-16 13:24:23 +00:00
Markus Himmel
5a34ffb9b0
chore: upstream Nat material from mathlib (#7971)
This PR upstreams much of the material from `Mathlib/Data/Nat/Init.lean`
and `Mathlib/Data/Nat/Basic.lean`.
2025-04-16 06:55:32 +00:00
Henrik Böving
712bb070f9
feat: make bv_decide work on simp normal forms of shifts (#7976)
This PR ensure that `bv_decide` can handle the simp normal form of a
shift.

Consider:
```lean
theorem test1 (b s : BitVec 5) (hb : b = 0) (hs : s ≠ 0)
  : b <<< s = 0 := by
  bv_decide
```
This works out, however:
```lean
theorem test2 (b s : BitVec 5) (hb : b = 0) (hs : s ≠ 0)
  : b <<< s = 0 := by
  simp
  bv_decide
```
this fails because the `simp` normal form adds `toNat` to the right hand
argument of the `<<<` and `bv_decide` cannot deal with shifts by
non-constant `Nat`.

Discovered by @spdskatr
2025-04-15 17:26:19 +00:00
Henrik Böving
dd7ca772d8
refactor: more complete channel implementation for Std.Channel (#7819)
This PR extends `Std.Channel` to provide a full sync and async API, as
well as unbounded, zero sized and bounded channels.

A few notes on the implementation:
- the bounded channel is inspired by [Go channels on
steroids](https://docs.google.com/document/d/1yIAYmbvL3JxOKOjuCyon7JhW4cSv1wy5hC0ApeGMV9s/pub)
though currently doesn't do any of the lock-free optimizations
- @mhuisi convinced me that having a non-closable channel may be a good
idea as this alleviates the need for error handling which is very
annoying when working with `Task`. This does complicate the API a little
bit and I'm not quite sure whether this is a choice we want users to
give. An alternative to this would be to just write `send!` that panics
on sending to a closed channel (receiving from a closed channel is not
an error), this is for example the behavior that golang goes with.
2025-04-12 21:02:24 +00:00
Henrik Böving
e9cc776f22
perf: bv_decide DecidableEq fast path using hash comparison (#7920)
This PR introduces a fast path based on comparing the (cached) hash
value to the `DecidableEq` instance of the core expression data type in
`bv_decide`'s bitblaster.

As we use a good hash function ™️ this should allow us to short
circuit to "not equal" quicker (if appropriate) than currently as we
will often not have to traverse all the way down to the actual conflict.
This in turn should speed up traversing of bucket chains during hash
collisions.
2025-04-11 15:00:41 +00:00
Markus Himmel
cf3b257ccd
chore: Option cleanup (#7897)
This PR cleans up the `Option` development, upstreaming some results
from mathlib in the process.

Notable changes:
- the name `<op>_eq_some_iff` is preferred over `<op>_eq_some`
- the `simp` normal form for `<$>` is `Option.map`, for `>>=` is
`Option.bind` and for `<|>` is `Option.orElse` (for the former two, this
was already true before this PR). All further lemmas about these
operations are now stated only in terms of
`Option.map`/`Option.bind`/`Option.orElse`. Previously, in some cases
both versions were available, with a prime used to disambiguate (the
primed version was usually the "non-ascii-art" version). Now, there are
no lemmas about the ascii-art versions besides the ones turning them
into the non-ascii-art operations, and there is only one version of
every lemma, about the non-ascii-art operation, and named without a
prime.
2025-04-10 18:53:30 +00:00
Markus Himmel
106b772659
chore: remove membership instance on Option from most theorem statements (#7856)
This PR changes definitions and theorems not to use the membership
instance on `Option` unless the theorem is specifically about the
membership instance.

The reasoning for this change is that the lemma `a ∈ o ↔ o = some a` is
a `simp` lemma, and we generally want theorem statements to use `simp`
normal forms.

One notable exception is the `ForIn'` instance, which must use
`Membership` because unlike `GetElem`, `ForIn'` requires the validity
predicate to be expressed via `Membership`.
2025-04-08 08:06:50 +00:00
JovanGerb
bfed223306
perf: use Array.emptyWithCapacity in toArray for HashMap and TreeMap (#7863)
This PR improves the `toArray` functions of `HashMap` and `TreeMap` to
use the known size for the initial capacity of the `Array`.
2025-04-08 05:59:53 +00:00
Kim Morrison
f8691bcb62
chore: remove @[simp] from @[deprecated] theorems (#7847)
This PR removes `@[simp]` from all deprecated theorems. `simp` will
still use such lemmas, without any warning message.
2025-04-07 05:49:11 +00:00
euprunin
2ea675369f
chore: fix spelling mistakes (#7328)
Co-authored-by: euprunin <euprunin@users.noreply.github.com>
2025-04-07 01:15:48 +00:00
JovanGerb
ca839f6d6c
chore: generalize some type classes (#7611)
This PR generalizes some typeclasses. They were found using a linter.

[#mathlib4 > Linter for generalizing type class
hypotheses](https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/Linter.20for.20generalizing.20type.20class.20hypotheses)
2025-04-07 01:10:19 +00:00
Rob23oba
575e0307bf
chore: fix naming of several theorems (#7499)
This PR fixes the spelling of several theorems to adhere to the naming
convention.

Note: The changes here were found using [a
tool](https://leanprover.zulipchat.com/#narrow/channel/270676-lean4/topic/automatic.20spelling.20generation.20.26.20comparison/with/505770987).
2025-04-04 10:52:52 +00:00
Luisa Cicolini
e59d070af1
feat: add BitVec.umulOverflow and BitVec.smulOverflow definitions and additional theorems (#7659)
This PR adds SMT-LIB operators to detect overflow
`BitVec.(umul_overflow, smul_overflow)`, according to the definitions
[here](https://github.com/SMT-LIB/SMT-LIB-2/blob/2.7/Theories/FixedSizeBitVectors.smt2),
and the theorems proving equivalence of such definitions with the
`BitVec` library functions (`umulOverflow_eq`, `smulOverflow_eq`).
Support theorems for these proofs are `BitVec.toInt_one_of_lt,
BitVec.toInt_mul_toInt_lt, BitVec.le_toInt_mul_toInt,
BitVec.toNat_mul_toNat_lt, BitVec.two_pow_le_toInt_mul_toInt_iff,
BitVec.toInt_mul_toInt_lt_neg_two_pow_iff` and `Int.neg_mul_le_mul,
Int.bmod_eq_self_of_le_mul_two, Int.mul_le_mul_of_natAbs_le,
Int.mul_le_mul_of_le_of_le_of_nonneg_of_nonpos, Int.pow_lt_pow`. The PR
also includes a set of tests.

Co-authored by @tobiasgrosser.

---------

Co-authored-by: Tobias Grosser <tobias@grosser.es>
Co-authored-by: Tobias Grosser <github@grosser.es>
Co-authored-by: Siddharth <siddu.druid@gmail.com>
2025-04-03 08:42:52 +00:00
Henrik Böving
626075ca34
feat: add Std.SharedMutex (#7770)
This PR adds a shared mutex (or read-write lock) as `Std.SharedMutex`.

In order to easily migrate a `Std.Mutex` to `Std.SharedMutex` if
necessary, the functions for obtaining exclusive access are named the
same, allowing a correct drop in to be done by just swapping types.
2025-04-03 08:30:54 +00:00
Henrik Böving
6a45bd5f77
feat: add Std.Barrier (#7771)
This PR adds a barrier primitive as `Std.Barrier`.

The implementation is mirrored after [the Rust
one](https://github.com/rust-lang/rust/blob/b8ae372/library/std/src/sync/barrier.rs)
as C++14 does not have barriers yet.
2025-04-01 15:48:13 +00:00
Henrik Böving
32cd701994
feat: add Std.RecursiveMutex (#7755)
This PR adds `Std.RecursiveMutex` as a recursive/reentrant equivalent to
`Std.Mutex`.
2025-04-01 07:35:36 +00:00
Henrik Böving
6faab78384
chore: delete unused invariant (#7759)
This PR deletes an unused invariant from the AIG to CNF conversion.
Interestingly despite being listed in the AIGNET paper it is actually
not used in the proof so we can just remove it.
2025-03-31 17:35:46 +00:00
Henrik Böving
1b5a52a5e9
feat: Std.BaseMutex.tryLock and Mutex.tryAtomically (#7751)
This PR adds `Std.BaseMutex.tryLock` and `Std.Mutex.tryAtomically` as
well as unit tests for our locking and condition variable primitives.

---------

Co-authored-by: Markus Himmel <markus@lean-fro.org>
2025-03-31 12:19:09 +00:00
David Thrane Christiansen
35894b119c
doc: docstring review for bitvectors (#7713)
This PR makes the BitVec docstrings match each other and the rest of the
API in style.

---------

Co-authored-by: Markus Himmel <markus@himmel-villmar.de>
Co-authored-by: Siddharth <siddu.druid@gmail.com>
2025-03-31 08:04:33 +00:00
Henrik Böving
176e8bc077
perf: in the AIG always store the constant node at the same spot (#7733)
This PR ensures that in the AIG the constant circuit node is always
stored at the first spot. This allows us to skip performing a cache
lookup when we require a constant node.
2025-03-30 10:07:31 +00:00
Henrik Böving
e37bbdbf23
perf: slightly better CNF -> dimacs conversion (#7727)
This PR avoids some unnecessary allocations in the CNF to dimacs
conversion
2025-03-29 23:32:57 +00:00
Henrik Böving
2fc77e3242
perf: compress the AIG representation (#7720)
This PR compresses the AIG representation by storing the inverter bit in
the lowest bit of the gate descriptor instead of as a separate `Bool`.

Note that this is only the first step, we also need to compress the
representation in `Ref` though this is a potentially more difficult
refactor as `Ref`'s constructor is being referred to all over the place.
2025-03-29 22:16:44 +00:00
Paul Reichert
a558a5a1eb
feat: Ord-related instances for IntX, Ordering, BitVec, Array, List and Vector (#7700)
This PR provides `Ord`-related instances such as `TransOrd` for `IntX`,
`Ordering`, `BitVec`, `Array`, `List` and `Vector`.
2025-03-29 15:55:13 +00:00
Henrik Böving
bb23713542
perf: skip computing hash of bv_decide BVExpr.Cache.Key (#7709)
This PR skips computation of the hash of `BVExpr.Cache.Key` as the
expression's hash is a computed field and the width is already mixed in
by its hash function. This will probably only have a very minor effect
but is visible in large SMTLIB benchmarks.
2025-03-28 17:21:10 +00:00
Alex Meiburg
5fb990fcbd
doc: Rat.lean docstring: "Mathlib" -> "Batteries" (#7708)
This PR fixes an inaccuracy in a module doc for an internal file.

The "Mathib rational numbers" are actually defined in Batteries now -
someone using Batteries but not Mathlib could potentialy be misled by
this. I think this is an improvement on the docstring.
2025-03-28 14:56:44 +00:00
Paul Reichert
d7f5d9a67a
feat: Ord-related instances for various types (#7687)
This PR provides `Inhabited`, `Ord` (if missing), `TransOrd`,
`LawfulEqOrd` and `LawfulBEqOrd` instances for various types, namely
`Bool`, `String`, `Nat`, `Int`, `UIntX`, `Option`, `Prod` and date/time
types. It also adds a few related theorems, especially about how the
`Ord` instance for `Int` relates to `LE` and `LT`.

---------

Co-authored-by: Paul Reichert <datokrat@users.noreply.github.com>
2025-03-28 13:31:09 +00:00
Paul Reichert
e4968ae854
feat: add simp-friendly, Ord-based tree map lemmas (#7697)
This PR is a follow-up to #7695, which removed `simp` attributes from
tree map lemmas with bad discrimination patterns. In this PR, we
introduce some `Ord`-based lemmas that are more simp-friendly.

---------

Co-authored-by: Paul Reichert <datokrat@users.noreply.github.com>
2025-03-28 08:29:16 +00:00
Paul Reichert
7bd9375804
chore: write tests for the non-verified tree map functions (#7680)
This PR provides tests for those tree map functions that are not
verified yet.

---------

Co-authored-by: Paul Reichert <datokrat@users.noreply.github.com>
2025-03-27 13:52:34 +00:00
Paul Reichert
e46cc64d1e
feat: tree map lemmas for maxKeyD (#7675)
This PR provides lemmas about the tree map function `maxKeyD` and its
interactions with other functions for which lemmas already exist.

---------

Co-authored-by: Paul Reichert <datokrat@users.noreply.github.com>
2025-03-27 13:49:21 +00:00
Sofia Rodrigues
d95a2ee35e
feat: add FormatConfig for GenericFormat with leap second validation (#7584)
This PR introduces a structure called `FormatConfig`, which provides
additional configuration options for `GenericFormat`, such as whether
leap seconds should be allowed during parsing. By default, this option
is set to `false`.

This PR also fixes certain flaws to make the implementation less
permissive by:

- Disallowing the final leap second, such as `2016-12-31T23:59:60Z`,
when `allowLeapSeconds = false`.
- Disallowing invalid leap seconds, such as `2017-06-30T23:59:60Z`, when
`allowLeapSeconds = false`.
- Disallowing leap-minute time zones, such as
`2016-12-31T00:00:00+2360`, and out-of-range time zones, such as
`2016-12-31T00:00:00+2490`.

These changes ensure that Lean aligns with TypeScript's behavior, as
outlined in this table:
https://github.com/cedar-policy/cedar-spec/pull/519#issuecomment-2613547897.
2025-03-27 13:25:23 +00:00
Paul Reichert
725979a91a
fix: remove bad simp lemmas about the tree maps (#7695)
This PR removes simp lemmas about the tree map with a metavariable in
the head of the discrimination pattern.

Co-authored-by: Paul Reichert <datokrat@users.noreply.github.com>
2025-03-27 13:14:43 +00:00
Markus Himmel
3e3ff31864
feat: support material for finite type theory (#7694)
This PR contains additional material on `BitVec`, `Int` and `Nat`, split
off from #7592.
2025-03-27 12:32:27 +00:00
Markus Himmel
7d9d622057
feat: BitVec and Int results for finite types (#7685)
This PR contains additional material about `BitVec` and `Int` spun off
from #7592.
2025-03-27 06:53:20 +00:00
Paul Reichert
e9fda1a3e4
feat: tree map lemmas for maxKey! (#7686)
This PR provides lemmas for the tree map function `maxKey!` and its
interactions with other functions for which lemmas already exist.

---------

Co-authored-by: Paul Reichert <datokrat@users.noreply.github.com>
2025-03-26 16:13:15 +00:00
Sofia Rodrigues
5ad6edc8d0
fix: corrects the handling of datetime size for certain specifiers during parsing (#7571)
This PR fixes #7478 by modifying `number` specifiers from `atLeast size`
to `flexible size` for parsing. This change allows:
- 1 repetition to accept 1 or more characters
- More than 1 repetition to require exactly that many characters

For `year` specifiers, the number of repetitions is always strictly
enforced, requiring exactly the specified amount.

---------

Co-authored-by: Markus Himmel <markus@himmel-villmar.de>
2025-03-26 16:11:13 +00:00
Sofia Rodrigues
74b1c29a48
feat: UDP socket support using LibUV (#7574)
This PR introduces UDP socket support using the LibUV library, enabling
asynchronous I/O operations with it.
2025-03-26 15:04:25 +00:00
Paul Reichert
b2da85971d
fix: fix maxKey/maxEntry tree map functions and add lemmas for maxKey (#7664)
This PR fixes a bug in the definition of the tree map functions `maxKey`
and `maxEntry`. Moreover, it provides lemmas for this function and its
interactions with other function for which lemmas already exist.

---------

Co-authored-by: Paul Reichert <datokrat@users.noreply.github.com>
2025-03-26 12:49:33 +00:00
Kim Morrison
daa4fd9955
feat: review of implicitness of arguments in List/Array (#7672)
This PR reviews the implicitness of arguments across List/Array/Vector,
generally trying to make arguments implicit where possible, although
sometimes correcting propositional arguments which were incorrectly
implicit to explicit.
2025-03-26 04:40:06 +00:00
Paul Reichert
7f4e4557a7
feat: tree map lemmas for maxKey? (#7657)
This PR provides lemmas for the tree map function `maxKey?` and its
interations with other functions for which lemmas already exist.

---------

Co-authored-by: Paul Reichert <datokrat@users.noreply.github.com>
2025-03-25 12:41:46 +00:00