-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Expand file tree
/
Copy pathGroup.lean
More file actions
103 lines (80 loc) · 3.57 KB
/
Group.lean
File metadata and controls
103 lines (80 loc) · 3.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/-
Copyright (c) 2020 Patrick Massot. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Thomas Browning, Patrick Massot
-/
module
public import Mathlib.Algebra.Group.Commutator -- shake: keep (tactic dependency)
public import Mathlib.Algebra.Order.Sub.Basic -- shake: keep (tactic dependency)
public meta import Mathlib.Tactic.FailIfNoProgress
public import Mathlib.Tactic.Ring
/-!
# `group` tactic
Normalizes expressions in the language of groups. The basic idea is to use the simplifier
to put everything into a product of group powers (`zpow` which takes a group element and an
integer), then simplify the exponents using the `ring` tactic. The process needs to be repeated
since `ring` can normalize an exponent to zero, leading to a factor that can be removed
before collecting exponents again. The simplifier step also uses some extra lemmas to avoid
some `ring` invocations.
## Tags
group theory
-/
public meta section
namespace Mathlib.Tactic.Group
open Lean
open Lean.Meta
open Lean.Parser.Tactic
open Lean.Elab.Tactic
-- The next three lemmas are not general purpose lemmas, they are intended for use only by
-- the `group` tactic.
@[to_additive]
theorem zpow_trick {G : Type*} [Group G] (a b : G) (n m : ℤ) :
a * b ^ n * b ^ m = a * b ^ (n + m) := by rw [mul_assoc, ← zpow_add]
@[to_additive]
theorem zpow_trick_one {G : Type*} [Group G] (a b : G) (m : ℤ) :
a * b * b ^ m = a * b ^ (m + 1) := by rw [mul_assoc, mul_self_zpow]
@[to_additive]
theorem zpow_trick_one' {G : Type*} [Group G] (a b : G) (n : ℤ) :
a * b ^ n * b = a * b ^ (n + 1) := by rw [mul_assoc, mul_zpow_self]
/-- Auxiliary tactic for the `group` tactic. Calls the simplifier only. -/
syntax (name := aux_group₁) "aux_group₁" (location)? : tactic
macro_rules
| `(tactic| aux_group₁ $[at $location]?) =>
`(tactic| simp -decide -failIfUnchanged only
[commutatorElement_def, mul_one, one_mul,
← zpow_neg_one, ← zpow_natCast, ← zpow_mul,
Int.natCast_add, Int.natCast_mul,
Int.mul_neg, Int.neg_mul, neg_neg,
one_zpow, zpow_zero, zpow_one, mul_zpow_neg_one,
← mul_assoc,
← zpow_add, ← zpow_add_one, ← zpow_one_add, zpow_trick, zpow_trick_one, zpow_trick_one',
tsub_self, sub_self, add_neg_cancel, neg_add_cancel]
$[at $location]?)
/-- Auxiliary tactic for the `group` tactic. Calls `ring_nf` to normalize exponents. -/
syntax (name := aux_group₂) "aux_group₂" (location)? : tactic
macro_rules
| `(tactic| aux_group₂ $[at $location]?) =>
`(tactic| ring_nf (ifUnchanged := .silent) $[at $location]?)
/-- `group` normalizes expressions in multiplicative groups that occur in the goal. `group` does not
assume commutativity, instead using only the group axioms without any information about which group
is manipulated. If the goal is an equality, and after normalization the two sides are equal, `group`
closes the goal.
For additive commutative groups, use the `abel` tactic instead.
* `group at l1 l2 ...` normalizes at the given locations.
Example:
```lean
example {G : Type} [Group G] (a b c d : G) (h : c = (a*b^2)*((b*b)⁻¹*a⁻¹)*d) : a*c*d⁻¹ = a := by
group at h -- normalizes `h` which becomes `h : c = d`
rw [h] -- the goal is now `a*d*d⁻¹ = a`
group -- which then normalized and closed
```
-/
syntax (name := group) "group" (location)? : tactic
macro_rules
| `(tactic| group $[$loc]?) =>
`(tactic| repeat (fail_if_no_progress (aux_group₁ $[$loc]? <;> aux_group₂ $[$loc]?)))
end Mathlib.Tactic.Group
/-!
We register `group` with the `hint` tactic.
-/
register_hint 900 group