Giter Club home page Giter Club logo

mathlib4's Introduction

mathlib4

GitHub CI Bors enabled project chat

Mathlib is a user maintained library for the Lean theorem prover. It contains both programming infrastructure and mathematics, as well as tactics that use the former and allow to develop the latter.

Installation

You can find detailed instructions to install Lean, mathlib, and supporting tools on our website.

Using mathlib4 as a dependency

Please refer to https://github.com/leanprover-community/mathlib4/wiki/Using-mathlib4-as-a-dependency

Experimenting

Got everything installed? Why not start with the tutorial project?

For more pointers, see Learning Lean.

Documentation

Besides the installation guides above and Lean's general documentation, the documentation of mathlib consists of:

Much of the discussion surrounding mathlib occurs in a Zulip chat room, and you are welcome to join, or read along without signing up. Questions from users at all levels of expertise are welcome! We also provide an archive of the public discussions, which is useful for quick reference.

Contributing

The complete documentation for contributing to mathlib is located on the community guide contribute to mathlib

The process is different from other projects where one should not fork the repository. Instead write permission for non-master branches should be requested on Zulip by introducing yourself, providing your GitHub handle and what contribution you are planning on doing. You may want to subscribe to the mathlib4 stream

  • To obtain precompiled olean files, run lake exe cache get. (Skipping this step means the next step will be very slow.)

  • To build mathlib4 run lake build.

  • To build and run all tests, run lake test.

  • You can use lake build Mathlib.Import.Path to build a particular file, e.g. lake build Mathlib.Algebra.Group.Defs.

  • If you added a new file, run the following command to update Mathlib.lean

    lake exe mk_all

Guidelines

Mathlib has the following guidelines and conventions that must be followed

Downloading cached build files

You can run lake exe cache get to download cached build files that are computed by mathlib4's automated workflow.

If something goes mysteriously wrong, you can try one of lake clean or rm -rf .lake before trying lake exe cache get again. In some circumstances you might try lake exe cache get! which re-downloads cached build files even if they are available locally.

Call lake exe cache to see its help menu.

Building HTML documentation

Building HTML documentation locally is straightforward, but it may take a while:

lake -Kdoc=on build Mathlib:docs

The HTML files can then be found in build/doc.

Transitioning from Lean 3

For users familiar with Lean 3 who want to get up to speed in Lean 4 and migrate their existing Lean 3 code we have:

Dependencies

If you are a mathlib contributor and want to update dependencies, use lake update, or lake update batteries aesop (or similar) to update a subset of the dependencies. This will update the lake-manifest.json file correctly. You will need to make a PR after committing the changes to this file.

Please do not run lake update -Kdoc=on as previously advised, as the documentation related dependencies should only be included when CI is building documentation.

Maintainers:

For a list containing more detailed information, see https://leanprover-community.github.io/teams/maintainers.html

  • Anne Baanen (@Vierkantor): algebra, number theory, tactics
  • Matthew Robert Ballard (@mattrobball): algebra, algebraic geometry, category theory, performance
  • Reid Barton (@rwbarton): category theory, topology
  • Riccardo Brasca (@riccardobrasca): algebra, number theory, algebraic geometry, category theory
  • Kevin Buzzard (@kbuzzard): algebra, number theory, algebraic geometry, category theory
  • Mario Carneiro (@digama0): lean formalization, tactics, type theory, proof engineering
  • Bryan Gin-ge Chen (@bryangingechen): documentation, infrastructure
  • Johan Commelin (@jcommelin): algebra, number theory, category theory, algebraic geometry
  • Anatole Dedecker (@ADedecker): topology, functional analysis, calculus
  • Rémy Degenne (@RemyDegenne): probability, measure theory, analysis
  • Floris van Doorn (@fpvandoorn): measure theory, model theory, tactics
  • Frédéric Dupuis (@dupuisf): linear algebra, functional analysis
  • Gabriel Ebner (@gebner): tactics, infrastructure, core, formal languages
  • Sébastien Gouëzel (@sgouezel): topology, calculus, geometry, analysis, measure theory
  • Markus Himmel (@TwoFX): category theory
  • Chris Hughes (@ChrisHughes24): algebra
  • Yury G. Kudryashov (@urkud): analysis, topology, measure theory
  • Robert Y. Lewis (@robertylewis): tactics, documentation
  • Jireh Loreaux (@j-loreaux): analysis, topology, operator algebras
  • Heather Macbeth (@hrmacbeth): geometry, analysis
  • Patrick Massot (@patrickmassot): documentation, topology, geometry
  • Bhavik Mehta (@b-mehta): category theory, combinatorics
  • Kyle Miller (@kmill): combinatorics, tactics, metaprogramming
  • Kim Morrison (@semorrison): category theory, tactics
  • Oliver Nash (@ocfnash): algebra, geometry, topology
  • Joël Riou (@joelriou): category theory, homology, algebraic geometry
  • Adam Topaz (@adamtopaz): algebra, category theory, algebraic geometry
  • Eric Wieser (@eric-wieser): algebra, infrastructure

Emeritus maintainers:

  • Jeremy Avigad (@avigad): analysis
  • Johannes Hölzl (@johoelzl): measure theory, topology
  • Simon Hudon (@cipher1024): tactics

mathlib4's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mathlib4's Issues

Unexpanders broken by #617

Consider this example:

example : ∃ (x : Nat), x = 0 := by

If you don't import Mathlib, the goal is listed as ∃ x, x = 0. If you import Mathlib, the goal is listed as Exists fun x ↦ x = 0. It appears that it is the introduction of that is causing the problem. The unexpander for Exists isn't expecting that symbol, so it's not working.

There are other unexpanders that also expect => rather than , so I suspect that they also have the same problem, although I haven't tested them. The ones I found are unexpandSigma, unexpandPSigma, and unexpandSubtype.

split_ifs doesn't completely split hypotheses

In Lean 3, we had:

import tactic.split_ifs
import tactic.localized

open_locale classical

example (P Q : Prop) (w : if P then (if Q then true else true) else true = true) : true :=
begin
  split_ifs at w,
  -- 3 goals, no `if`s in `w`
  all_goals { trivial, }
end

while currently in mathlib4 we have:

import Mathlib.Tactic.SplitIfs

open Classical

example (P Q : Prop) (w : if P then (if Q then true else true) else true = true) : true := by
  split_ifs at w
  -- two goals here, and in the first `w : if Q then true else true`

This first came up in porting Logic.Embedding.Basic.

needs a LICENSE

If you are accepting external contributions, it will save you headaches later if you nail down the license ASAP.
Otherwise, you could get into an awkward situation where you need to chase down all contributors
to ask their permission about various ways you might want to use the code.

Simplest would be to copy the Apache license from mathlib.

`to_additive` doesn't interact with several other attributes.

Right now, to_additive is generating additive declarations which do not inherit other attributes attached to the multiplicative declaration. This is an issue because not all mathlib4 porters are aware of this, so right now some stuff is being incorrectly ported.

Here are examples:

  1. simp
import Mathlib.Tactic.ToAdditive
import Mathlib.Init.ZeroOne

-- to_additive doesn't attach `simp`
@[simp, to_additive]
theorem One.foo [One α] [Mul α] (a : α) : (1 : α) * a = 1 := sorry

example [One α] [Mul α] (a : α) : (1 : α) * a = 1 := by simp

#check @Zero.foo -- exists

example [Zero α] [Add α] : (0 : α) + a = 0 := by simp -- fails (note: zero_add doesn't fire because it's not imported)
  1. simps (note that the docs currently claim that this works, but it doesn't seem to?)
import Mathlib.Algebra.Hom.Group

-- `simps` doesn't run on additivised declaration
@[to_additive, simps]
def OneHom.id' (M : Type _) [One M] : OneHom M M where
  toFun x := x
  map_one' := rfl

#check OneHom.id'_apply -- exists
#check ZeroHom.id' -- exists
#check ZeroHom.id'_apply -- doesn't exist
  1. ext
import Mathlib.Algebra.Group.Units

@[ext, to_additive]
theorem Units.ext' [Monoid α] : Function.Injective (fun (u : αˣ) => (u : α))
  | ⟨v, i₁, vi₁, iv₁⟩, ⟨v', i₂, vi₂, iv₂⟩, e => by
    simp only at e; subst v'; congr;
    simpa only [iv₂, vi₁, one_mul, mul_one] using mul_assoc i₂ v i₁

example [Monoid α] (a b : αˣ) : a = b := by
  ext -- does something
  sorry

example [AddMonoid α] (a b : AddUnits α) : a = b := by
  ext -- fails

Other attributes currently used with to_additive in Mathlib are norm_cast, coe, symm and trans. I'm not sure which ones currently interact in the optimal way.

performance regression in ring

I don't have time to debug now but I just bisected what looks like a pretty bad performance regression in ring, coming from 085e7ab it seems.

According to the following

import Mathlib.Tactic.Ring

set_option profiler true
set_option maxHeartbeats 700000 in
lemma a [CommRing R] (a1 a2 a3 a4 a6 : R) (P : R × R) :
  -(a1 ^ 4 * a2 * a3 ^ 2 - a1 ^ 5 * a3 * a4 + a1 ^ 6 * a6 + 8 * a1 ^ 2 * a2 ^ 2 * a3 ^ 2
  - a1 ^ 3 * a3 ^ 3 - 8 * a1 ^ 3 * a2 * a3 * a4 - a1 ^ 4 * a4 ^ 2 + 12 * a1 ^ 4 * a2 * a6
  + 16 * a2 ^ 3 * a3 ^ 2 - 36 * a1 * a2 * a3 ^ 3 - 16 * a1 * a2 ^ 2 * a3 * a4
  + 30 * a1 ^ 2 * a3 ^ 2 * a4 - 8 * a1 ^ 2 * a2 * a4 ^ 2 + 48 * a1 ^ 2 * a2 ^ 2 * a6
  - 36 * a1 ^ 3 * a3 * a6 + 27 * a3 ^ 4 - 72 * a2 * a3 ^ 2 * a4 - 16 * a2 ^ 2 * a4 ^ 2
  + 96 * a1 * a3 * a4 ^ 2 + 64 * a2 ^ 3 * a6 - 144 * a1 * a2 * a3 * a6 - 72 * a1 ^ 2 * a4 * a6
  + 64 * a4 ^ 3 + 216 * a3 ^ 2 * a6 - 288 * a2 * a4 * a6 + 432 * a6 ^ 2) =
  -((48 * P.fst * P.snd * a2 ^ 2 + 24 * a1 * a2 * a6 + 216 * P.snd * a6 + P.snd * a1 ^ 6 +
  11 * P.snd * a1 ^ 4 * a2 + P.fst * a1 ^ 4 * a3 + 38 * P.fst * a1 ^ 2 * a2 * a3
  + 8 * a1 ^ 2 * a2 ^ 2 * a3 + a1 ^ 4 * a2 * a3 + 40 * P.snd * a1 ^ 2 * a2 ^ 2
  + 32 * P.snd * a2 ^ 3 + 24 * P.fst * P.snd * a1 * a3 + 30 * P.fst ^ 2 * a2 * a3
  + 3 * P.fst * a1 ^ 3 * a4 + 60 * P.fst ^ 2 * a1 * a4 + 30 * P.fst ^ 2 * a1 ^ 2 * a3
  + 31 * a1 ^ 2 * a3 * a4 + 144 * P.snd ^ 2 * a3 + 198 * P.snd * a3 ^ 2 + 27 * a3 ^ 3
  + 60 * a1 * a4 ^ 2 + 36 * P.fst * a1 * a6 + 76 * P.fst * a2 ^ 2 * a3
  + 16 * a2 ^ 3 * a3 + 84 * P.fst * a1 * a2 * a4 - (36 * a3 * a6 + P.fst ^ 2 * a1 ^ 5
  + P.fst * a1 ^ 5 * a2 + P.fst * P.snd * a1 ^ 4
  + 9 * P.fst ^ 2 * a1 ^ 3 * a2 + 10 * P.fst * a1 ^ 3 * a2 ^ 2 + a1 ^ 5 * a4
  + 6 * P.snd ^ 2 * a1 ^ 3 + 8 * P.fst * P.snd * a1 ^ 2 * a2 + 24 * P.fst ^ 2 * a1 * a2 ^ 2
  + 32 * P.fst * a1 * a2 ^ 3 + 35 * P.snd * a1 ^ 3 * a3 + a1 ^ 3 * a3 ^ 2 + 9 * a1 ^ 3 * a2 * a4
  + 48 * P.snd ^ 2 * a1 * a2 + 134 * P.snd * a1 * a2 * a3 + 27 * P.fst * a1 * a3 ^ 2
  + 36 * a1 * a2 * a3 ^ 2 + 58 * P.snd * a1 ^ 2 * a4 + 24 * a1 * a2 ^ 2 * a4
  + 144 * P.fst * P.snd * a4 + 120 * P.snd * a2 * a4 + 168 * P.fst * a3 * a4
  + 34 * a2 * a3 * a4)) * (2 * P.snd + a1 * P.fst + a3) + (a1 ^ 2 * a3 ^ 2 + 12 * a1 ^ 2 * a6
  + 16 * a2 ^ 2 * a4 + 32 * P.fst * a2 ^ 3 + a1 ^ 4 * a4 + 144 * P.fst * a6 + 48 * a2 * a6
  + P.fst * a1 ^ 4 * a2 + 84 * P.fst * a3 ^ 2 + 56 * P.snd * a1 * a4 + 8 * a1 ^ 2 * a2 * a4
  + 28 * P.snd * a1 ^ 2 * a3 + 52 * P.snd * a2 * a3 + 96 * P.fst * P.snd * a3
  + 8 * P.fst * a1 ^ 2 * a2 ^ 2 + 38 * a2 * a3 ^ 2 + 32 * P.fst ^ 2 * a2 ^ 2
  - (2 * P.fst * a1 ^ 3 * a3 + 112 * P.fst * a2 * a4 + a1 ^ 3 * a2 * a3 + 36 * a1 * a3 * a4
  + 96 * P.fst ^ 2 * a4 + 32 * P.fst * P.snd * a1 * a2 + 32 * P.snd * a1 * a2 ^ 2 + 64 * a4 ^ 2
  + 4 * P.fst * P.snd * a1 ^ 3 + 10 * P.snd * a1 ^ 3 * a2 + P.snd * a1 ^ 5 + 8 * a1 * a2 ^ 2 * a3
  + 46 * P.fst * a1 * a2 * a3)) * (a1 * P.snd - (3 * P.fst ^ 2 + 2 * a2 * P.fst + a4))
  + (60 * a1 ^ 2 * a4 + 288 * P.fst * a4 + 240 * a2 * a4 + 12 * P.snd * a1 ^ 3
  + 36 * a1 ^ 3 * a3 + 96 * P.snd * a1 * a2 + 168 * a1 * a2 * a3 - (432 * a6 + a1 ^ 6
  + 288 * P.snd * a3 + 252 * a3 ^ 2 + 12 * a1 ^ 4 * a2 + 48 * a1 ^ 2 * a2 ^ 2 + 96 * P.fst * a2 ^ 2
  + 64 * a2 ^ 3)) * (P.snd ^ 2 + a1 * P.fst * P.snd + a3 * P.snd - (P.fst ^ 3 + a2 * P.fst ^ 2
  + a4 * P.fst + a6)))
:= by ring

the runtime of ring jumps from 2-3s to 18-40s on my machine, from d419b09 to 085e7ab.

@digama0 any ideas, both the ring and norm_num internals were affected by this commit, but I can't see a smoking gun.

LibrarySearch finds proof with sorryAx

Example:

def Bool_eq_iff
  {A B: Bool}
  : (A = B) = (A ↔ B)
  := by (cases A <;> cases B <;> simp)

def Bool_eq_iff2
  {A B: Bool}
  : (A = B) = (A ↔ B)
  := by library_search -- 𝔗𝔯𝔶 𝔱𝔥𝔦𝔰: exact sorryAx ((A = B) = (A = true ↔ B = true)) 

I would expect it to find the theorem Bool_eq_iff that solves the goal without sorry.

A simple fix is to add the following line to isBlackListed:

  if declName matches Name.str _ "sorryAx" _ then return true

set as a TermElab

E.g. in this slightly silly example, rather than writing

def a (t : Nat) (h : t < 7) : Nat :=
  if t = 0 then 0 else
  let b : Nat := t - 1
  (a b (by rw [(show b = t - 1 by rfl)]; sorry)) + 1

I'd like to be able to write

def a (t : Nat) (h : t < 7) : Nat :=
  if t = 0 then 0 else
  set b : Nat := t - 1 with h
  (a b (by rw [h]; sorry)) + 1

`ring` tactic bug

MWE:

import Mathlib.Tactic.Ring

def sum : Nat → Nat
  | 0     => 0
  | n + 1 => n + 1 + sum n

theorem mulDist {a b c : Nat} : a * (b + c) = a * b + a * c := by ring

theorem twoTimesSumEqTimesSucc {n : Nat} : 2 * sum n = n * (n + 1) := by
  induction n with
    | zero => rfl
    | succ n hi =>
      simp only [sum]
      iterate rw [mulDist]
      rw [hi]
      ring -- unknown free variable '_uniq.1942'

After some quick debugging, I noticed that the problem happens on this call.

tactic porting tracking issue

This issue parallels the content of Mathlib/Mathport/Syntax.lean, tracking the remaining work to port mathlib3 tactics to mathlib4, but also contains "ephemeral" information that does not belong in that file.

Primarily, this issue contains a list of tactics (or groups of tactics), along with any relevant information about work-in-progress (e.g. people who've "claimed" a tactic, PRs, abandoned work, etc). Some "claims" are probably out-of-date. Feel free to remove yourself from anything here without explanation!

We hope that everyone will edit this freely to try to keep it up to date.

Currently this is in the same order as Syntax.lean (although with tactics we might skip or only "stub" deferred to the end), but it may be worthwhile to turn this into a prioritised list.

🔹 – unclaimed
◼️ – claimed
☑️ – PR'd, unneeded, or otherwise done

E: Easy. It's a simple macro in terms of existing things,
or an elab tactic for which we have many similar examples. Example: left
M: Medium. An elab tactic, not too hard, perhaps a 100-200 lines file. Example: have
N: Possibly requires new mechanisms in lean 4, some investigation required
B: Hard, because it is a big and complicated tactic
S: Possibly easy, because we can just stub it out or replace with something else
?: uncategorized


We then have a number of tactics and commands for which mere stubs will suffice for the port. Sometimes this is because the tactic is only used during development (but not in PRs to mathlib), other times because it is not used at all anymore in mathlib.

Mem instance for lists

Right now we have infix:50 " ∈ " => mem in Data.List.Basic, and also a notation class Mem used for sets. I tried to replace the list notation with an instance of Mem and it broke all the proofs :-( What am I doing wrong? Obviously I could just fix all the proofs one by one and make them all longer, but I was not sure this would be welcome as a PR and I suspect I'm missing a trick.

Natural abs syntax clashes with pattern matching

The notation for abs clashes with some variants of the match notation:

import Mathbin.Algebra.Abs -- works if this is not imported

def test : Nat → Nat
| 0 => 0  -- expected '|'
| n + 1 => 0

should `clear_` tactic also clear inaccessible hypotheses?

In mathlib3, pairwise_and_iff has a usage of clear_ with this context:

α : Type u_1,
R S : α → α → Prop,
l : list α,
_x : pairwise R l ∧ pairwise S l,
_fun_match : pairwise R l ∧ pairwise S l → pairwise (λ (a b : α), R a b ∧ S a b) l,
hR : pairwise R l,
hS : pairwise S l
⊢ pairwise (λ (a b : α), R a b ∧ S a b) l

(see https://github.com/leanprover-community/mathlib/blob/aff61c0f687c5d366edb248791f26fa69a4adfe2/src/data/list/pairwise.lean#L67)

A direct translation into Lean 4 leads to this context in the same place:

α : Type u_1
R : α → α → Prop
a : α
l : List α
S : α → α → Prop
: Pairwise R l ∧ Pairwise S l
hR : Pairwise R l
hS : Pairwise S l
⊢ Pairwise (fun a b => R a b ∧ S a b) l

In this case, the current version of mathlib4's clear_ won't drop the Pairwise R l ∧ Pairwise S l hypothesis, because it is anonymous inaccessible. We need to drop that hypothesis to get the later induction to work. It's easy enough to work around this problem by adapting the proof a bit, but it would be nice if we could have a direct translation. What would make most sense to me is for mathlib4's clear_ to also drop unnamed hypotheses (in addition to hypotheses whose names start with _). We could even make the behavior configurable.

Make `invFun` an exception in `to_additive`

Currently, to_additive overeagerly translates invFun to negFun, when it means the inverse function. Consider adding invFun as an exception to the inv -> neg rule. Example: MulEquiv.invFun_eq_symm

add protected after the fact?

We need a mechanism to add protected, or otherwise to tell alias to create protected declarations.

There is an example in Mathlib/Algebra/GroupWithZero/Units/Basic.lean.

Definition of subset

The definition of subset in Mathlib.Init.Set.lean is ∀ {a}, a ∈ s₁ → a ∈ s₂. But the corresponding definition in mathlib3 was ∀ {{a}}, a ∈ s₁ → a ∈ s₂. Floris van Doorn suggested to me that the definition should be changed to use {{a}} as it did before.

Here is an example of a problem caused by the new definition. The following proof doesn't work:

example (A B : Set Nat) (h1 : A ⊆ C) (h2 : A = B) : B ⊆ C := by
  have h3 : B ⊆ C := h2 ▸ h1
  exact h3

The exact h3 line generates the error

type mismatch
  h3
has type
  ?m.645 ∈ B → ?m.645 ∈ C : Prop
but is expected to have type
  B ⊆ C : Prop

The cause of the problem is the implicit argument {a} in the definition of subset.

`to_additive` fails to translate `iff` with Exists

import Mathlib.Tactic.ToAdditive

@[to_additive]
def IsUnit [Mul M] (a : M) : Prop := a ≠ a

-- this works fine
@[to_additive]
theorem isUnit_iff_inv [Mul M] {a : M} : IsUnit a ↔ a ≠ a :=
  ⟨fun h => absurd rfl h, fun h => h⟩
#print isAddUnit_iff_neg

/-
The declaration isUnit_iff_exists_inv depends on the declaration isUnit_iff_exists_inv.match_1 which
is in the namespace isUnit_iff_exists_inv, but does not have the `@[to_additive]` attribute.
This is not supported.  Workaround: move isUnit_iff_exists_inv.match_1 to a different namespace.
-/
@[to_additive]
theorem isUnit_iff_exists_inv [Mul M] {a : M} : IsUnit a ↔ ∃ b : α, a ≠ a :=
  ⟨fun h => absurd rfl h, fun ⟨b, hab⟩ => hab⟩

-- attribute [to_additive isAddUnit_iff_exists_neg.match_1] isUnit_iff_exists_inv.match_1
-- attribute [to_additive] isUnit_iff_exists_inv

The first example works fine. Including the Exists makes to_additive fails. I've had to do the "tag match_1" workaround repeatedly in #549.

`max`/`min`

From #348: Lean 4 defines max and min in the prelude, while Lean 3 (as of leanprover-community/lean#609) defines them differently as part of linear_order. We will need to figure out how to resolve this conflict.

Probably the easiest thing would be to get notation typeclasses Max and Min into core.

Set theory notation

I'd like to suggest adding the following to Mathlib.Init.Set.lean:

macro (priority := low-1) "{ " pat:term " : " t:term " | " p:term " }" : term =>
  `({x : $t | match x with | $pat => $p})

macro (priority := low-1) "{ " pat:term " | " p:term " }" : term =>
  `({x | match x with | $pat => $p})

@[app_unexpander setOf]
def setOf.unexpander : Lean.PrettyPrinter.Unexpander
  | `($_ fun $_:ident =>
        match $_:ident with
        | $pat => $p) => `({ $pat:term | $p:term })
  | _ => throw ()

This allows set theory notation like {(a, b) : Nat × Nat | a < b}.
I have set the priority lower than all other set theory notation defined in Mathlib.Init.Set.lean, so this shouldn't interfere with any existing notation.

Typo in definition of empty set?

In Mathlib/Init/Set, the definition of the empty set is:

instance : EmptyCollection (Set α) :=
⟨λ _ => false⟩

Is this a typo? Should it be λ _ => False?

`to_additive` unable to translate `toOneHomClass`

See PR #659, in Algebra.Hom.Group, around theorem MonoidHom.coe_coe. If the quickfix

attribute [to_additive AddMonoidHomClass.toZeroHomClass] MonoidHomClass.toOneHomClass

is removed, the to_additive tactic seems to be looking for AddMonoidHomClass.toOneHomClass, when it should look for AddMonoidHomClass.toZeroHomClass. It has no trouble translating OneHomClass to ZeroHomClass, but has trouble with toOneHomClass.

zify incorrectly uses decide

Becauses simp by default uses decide in Lean 4, zify has become too powerful.

In Lean 4:

import Mathlib.Tactic.Zify

example (h : 0 = 7) : False := by
  zify at h

but in Lean 3:

import tactic.zify

example (h : 0 = 7) : false :=
begin
  zify at h,
  fail_if_success { assumption, },
  revert h, dec_trivial,
end

symm attribute error

The following code produces an error on the symm attribute:

import Mathlib.Algebra.Hom.Group
import Mathlib.Logic.Equiv.Basic

def MulHom.inverse [Mul M] [Mul N] (f : M →ₙ* N) (g : N → M) (h₁ : Function.LeftInverse g f)
    (h₂ : Function.RightInverse g f) : N →ₙ* M where
  toFun := g
  map_mul' x y :=
    calc
      g (x * y) = g (f (g x) * f (g y)) := by rw [h₂ x, h₂ y]
      _ = g (f (g x * g y)) := by rw [f.map_mul]
      _ = g x * g y := h₁ _

structure MulEquiv (M N : Type _) [Mul M] [Mul N] extends M ≃ N, M →ₙ* N

infixl:25 " ≃* " => MulEquiv

@[symm]
-- @[symm] attribute only applies to lemmas proving x ∼ y → y ∼ x, got {M : Type u_1} →
--  {N : Type u_2} → [inst : Mul M] → [inst_1 : Mul N] → M ≃* N → N ≃* M
def foo_symm {M N : Type _} [Mul M] [Mul N] (h : M ≃* N) : N ≃* M :=
  { h.toEquiv.symm with map_mul' := (h.toMulHom.inverse h.toEquiv.symm h.left_inv h.right_inv).map_mul }

It appears that trans is similarly having trouble recognising the structure of trans lemmas.

`ring` doesn't support negation

Currently the implementation of ring is incomplete and has no understanding of subtraction or negation:

import Mathlib.Tactic.Ring

example (a b : ℤ) : a - b = a + -b := by ring
-- ring failed, ring expressions not equal: 
-- (1) * (a - b)^1 + 0
--   !=
-- (1) * (a)^1 + (1) * (-b)^1 + 0

.\lean_packages\std\.\.\Std\Data\Nat\Lemmas.lean:152:42: error: no goals to be solved?

I'm trying to update lean4-samples to latest mathlib4 so I can pick up the new symm tactic, but the Std library build fails with:

error: > LEAN_PATH=.\build\lib;.\lean_packages\mathlib\build\lib;.\lean_packages\std\build\lib;.\lean_packages\Qq\build\lib c:\Users\clovett\.elan\toolchains\leanprover--lean4---nightly\bin\lean.exe -DwarningAsError=true -Dlinter.missingDocs=true .\lean_packages\std\.\.\Std\Data\Nat\Lemmas.lean -R .\lean_packages\std\.\. -o .\lean_packages\std\build\lib\Std\Data\Nat\Lemmas.olean -i .\lean_packages\std\build\lib\Std\Data\Nat\Lemmas.ilean -c .\lean_packages\std\build\ir\Std\Data\Nat\Lemmas.c
error: stdout:
.\lean_packages\std\.\.\Std\Data\Nat\Lemmas.lean:152:42: error: no goals to be solved
.\lean_packages\std\.\.\Std\Data\Nat\Lemmas.lean:157:26: error: application type mismatch

`zify` incorrectly uses `eq.refl`

In Lean 3 we had:

import tactic.zify

example (h : 0 = 0) : true :=
begin
  zify at h,     -- `h` is `(0 : ℤ) = 0`, not `true`.
  fail_if_success { assumption, },
  trivial,
end

but in Lean 4 we now have:

import Mathlib.Tactic.Zify

example (h : 0 = 0) : True := by
  zify at h   -- `h` has become `True`
  assumption

Goal state updates need debouncing

bounce.mp4

See the video above and note how after I finish typing, the infoview has to churn through 18s (!!) of intermediate states before showing the current goal state. I haven't yet investigated why this happens, but I am assuming it is a consequence of the fact that we eagerly fetch and display new goal states without waiting for the user to finish typing (doing this is known as debouncing). We should add debouncing, probably with a user-configurable debounce period (the tradeoff is that waiting can also delay the display of up-to-date info). I will give implementing this a go, but if it's not done in two-ish weeks feel free to poke me.

Note also that the issue is more observable on debug builds, and even more on debug builds over remote SSH setups (which is what I used to record this).

delta-derive handler

https://leanprover-community.github.io/mathlib_docs/tactic/delta_instance.html#tactic.delta_instance_handler
In lean3 there was a default derive handler which would run delta on the goal. That is, it would pull the instance through the type synonym. We don't have this at present in lean4, so it is necessary to construct the instance by hand.

Examples:

deriving instance LargeCategory, ConcreteCategory for HeytAlgCat

turns into

deriving instance LargeCategory for HeytAlgCat

instance : ConcreteCategory HeytAlgCat := by
  dsimp [HeytAlgCat]
  infer_instance

convert regression

import Mathlib.Tactic.Convert

example [Subsingleton α] (a b c : α) (w : a = c) : a = b := by
  convert w -- fails with unsolved goal `b = c`

while in Lean 3

import tactic.congr

example {α} [subsingleton α] (a b c : α) (w : a = c) : a = b :=
by convert w

succeeds.

I'm not sure yet whether this needs a change in convert or in congr in core.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.