Zulip Chat Archive

Stream: mathlib4

Topic: AtomM cache?


Thomas Murrills (Jul 15 2024 at 22:11):

Should AtomM have a cache for the atoms? Currently addAtom gets the atom of an expression e by looking at an array atoms : Array Expr, then checks each element of this array in turn against e by isDefEq.

Is the current AtomM behavior less expensive than it sounds? Would there be any benefit in doing a cheaper check in a HashMap Expr Nat, then falling back on iterating through the array if that fails? I imagine this might have been considered already, but thought I'd check.

Henrik Böving (Jul 15 2024 at 22:24):

The HashMap behavior is what both LeanSAT and omega are doing for performance reasons + actually no fallback to isDefEq at all.

Eric Wieser (Jul 15 2024 at 23:08):

Doesn't that mean that a + b can end up not matching a + b if the HAdd instance is different-but-defeq?

Eric Wieser (Jul 15 2024 at 23:12):

This test-case passes, so it seems omega is doing something with defeq:

import Mathlib

def my_add {α} [AddSemigroup α] (a b : α) := a + b

example : (1 + 2 : ) - (my_add 1 2 : ) = 0 := by
  rw [my_add]
  omega

Kim Morrison (Jul 16 2024 at 00:59):

omega uses Lean.Meta.Canonicalizer. This is much more efficient than AtomM.

Thomas Murrills (Jul 16 2024 at 01:01):

Is Canonicalizer strictly better than AtomM all around, or do they have different use cases?

Eric Wieser (Jul 16 2024 at 01:02):

(https://leanprover-community.github.io/mathlib4_docs/Lean/Meta/Canonicalizer.html)

Eric Wieser (Jul 16 2024 at 01:02):

I think there's quite a difference in philosophy between the two, and so picking between them is more than just a performance choice

Eric Wieser (Jul 16 2024 at 01:16):

I think the two things going for AtomM are:

  • It "sees through" abbrev, which depending on your model of what abbrev is supposed to mean, could be a feature
  • It can be used to unify metavariables; though perhaps CanonM could special case expressions with metavariables, assigning them all the same hash, for parity here.

Thomas Murrills (Jul 16 2024 at 01:22):

Hmm, it also seems that there are some expression reductions omega/CanonM doesn’t do, which AtomM would in the course of isDefEq, e.g.

import Mathlib

example : (fun x => x) (1 + 2 : ) - (1 + 2 : ) = 0 := by
  omega --error

Thomas Murrills (Jul 16 2024 at 01:25):

Though I wonder how “CanonM plus expression reductions” would compare to AtomM.

Mario Carneiro (Jul 16 2024 at 03:47):

AtomM is a linear scan exactly because it can't use the discrimination tree because it works up to unfolding semireducibles

Mario Carneiro (Jul 16 2024 at 03:47):

I've thought about having a hybrid version where if the reducibility setting is reducible then it uses a discrimination tree instead

Mario Carneiro (Jul 16 2024 at 03:48):

in practice I don't think it's a major issue, but it is quadratic in the size of the statement

Mario Carneiro (Jul 16 2024 at 03:49):

Note that ring/linarith actually used to be using something closer to the discrimination tree approach, this is the result of a feature request


Last updated: May 02 2025 at 03:31 UTC