@@ -3,13 +3,13 @@ Copyright (c) 2022 Jon Eugster. All rights reserved.
33Released under Apache 2.0 license as described in the file LICENSE.
44Authors: Jon Eugster, David Renshaw, Heather Macbeth, Michael Rothgang
55-/
6- import Mathlib.Tactic.FieldSimp
6+ import Mathlib.Tactic.Field
77import Mathlib.Tactic.Positivity
88import Mathlib.Tactic.Ring
99import Mathlib.Data.Real.Basic
1010
1111/-!
12- # Tests for the `field_simp` tactic
12+ # Tests for the `field_simp` and `field` tactics
1313-/
1414
1515private axiom test_sorry : ∀ {α}, α
@@ -370,16 +370,17 @@ end
370370
371371/-! ## Cancel denominators from equalities -/
372372
373- /-! ### Most common use case: Cancel denominators to something solvable by `ring`
373+ /-! ### Finishing tactic
374374
375- When (eventually) this is robust enough, there should be a `field` tactic
375+ The `field` tactic is a finishing tactic for equalities in fields.
376+ Effectively it runs `field_simp` to clear denominators, then hands the result to `ring1`.
376377-/
377378
378- macro "field" : tactic => `(tactic | (try field_simp) <;> ring1)
379-
380379example : (1 :ℚ) / 3 + 1 / 6 = 1 / 2 := by field
381380example {x : ℚ} (hx : x ≠ 0 ) : x * x⁻¹ = 1 := by field
382381example {a b : ℚ} (h : b ≠ 0 ) : a / b + 2 * a / b + (-a) / b + (- (2 * a)) / b = 0 := by field
382+
383+ -- example from the `field` docstring
383384example {x y : ℚ} (hx : x + y ≠ 0 ) : x / (x + y) + y / (x + y) = 1 := by field
384385
385386example {x : ℚ} : x ^ 2 / (x ^ 2 + 1 ) + 1 / (x ^ 2 + 1 ) = 1 := by field
@@ -392,14 +393,67 @@ example {K : Type*} [Field K] (a b c d x y : K) (hx : x ≠ 0) (hy : y ≠ 0) :
392393 a + b / x + c / x ^ 2 + d / x ^ 3 = a + x⁻¹ * (y * b / y + (d / x + c) / x) := by
393394 field
394395
396+ -- example from the `field` docstring
395397example {a b : ℚ} (ha : a ≠ 0 ) : a / (a * b) - 1 / b = 0 := by field
398+
396399example {x : ℚ} : x ^ 2 * x⁻¹ = x := by field
397400
401+ -- example from `field` docstring
402+ example {K : Type *} [Field K] (hK : ∀ x : K, x ^ 2 + 1 ≠ 0 ) (x : K) :
403+ 1 / (x ^ 2 + 1 ) + x ^ 2 / (x ^ 2 + 1 ) = 1 := by
404+ field [hK]
405+
398406-- testing that mdata is cleared before parsing goal
399407example {x : ℚ} (hx : x ≠ 0 ) : x * x⁻¹ = 1 := by
400408 have : 1 = 1 := rfl
401409 field
402410
411+ -- `field` will suggest `field_simp` on failure, if `field_simp` does anything.
412+
413+ /--
414+ info: Try this:
415+ field_simp
416+ ---
417+ error: unsolved goals
418+ x y z : ℚ
419+ hx : x + y ≠ 0
420+ ⊢ 1 = z
421+ -/
422+ #guard_msgs in
423+ example {x y z : ℚ} (hx : x + y ≠ 0 ) : x / (x + y) + y / (x + y) = z := by field
424+
425+ -- If `field` fails but `field_simp` also fails, we just throw an error.
426+ /--
427+ error: ring failed, ring expressions not equal
428+ x y z : ℚ
429+ ⊢ x + y = z
430+ -/
431+ #guard_msgs in
432+ example {x y z : ℚ} : x + y = z := by field
433+
434+ /-
435+ The `field` tactic differs slightly from `field_simp; ring1` in that it clears denominators only at
436+ the top level, not recursively in subexpressions.
437+
438+ (`ring1` acts only at the top level, so for consistency we also clear denominators only at the top
439+ level.) -/
440+ /--
441+ info: Try this:
442+ field_simp
443+ ---
444+ error: unsolved goals
445+ a b : ℚ
446+ f : ℚ → ℚ
447+ ⊢ f (a * b) * (1 - 1) = 0
448+ -/
449+ #guard_msgs in
450+ example (a b : ℚ) (f : ℚ → ℚ) : f (a ^ 2 * b / a) - f (b ^ 2 * a / b) = 0 := by field
451+
452+ -- (Compare with the example above: this is out of scope for `field`.)
453+ example (a b : ℚ) (f : ℚ → ℚ) : f (a ^ 2 * b / a) - f (b ^ 2 * a / b) = 0 := by
454+ field_simp
455+ ring1
456+
403457/-! ### Mid-proof use -/
404458
405459example {K : Type *} [Semifield K] (x y : K) (hy : y + 1 ≠ 0 ) : 2 * x / (y + 1 ) = x := by
@@ -535,9 +589,10 @@ normalize properly.
535589It is not clear whether or not this iterated alternation always achieves the "obvious" normalization
536590eventually. Nor is it clear whether, if so, there are any bounds on how many iterations are needed.
537591-/
538- section
539592
540593-- modified from 2021 American Mathematics Competition 12B, problem 9
594+ section
595+
541596example (P : ℝ → Prop ) {x y : ℝ} (hx : 0 < x) (hy : 0 < y) :
542597 P ((4 * x + y) / x / (x / (3 * x + y)) - (5 * x + y) / x / (x / (2 * x + y))) := by
543598 ring_nf
@@ -562,6 +617,77 @@ example (P : ℝ → Prop) {x y : ℝ} (hx : 0 < x) (hy : 0 < y) :
562617
563618end
564619
620+ section
621+
622+ -- This example is used in the `field` docstring.
623+ example {a b : ℚ} (H : b + a ≠ 0 ) : a / (a + b) + b / (b + a) = 1 := by
624+ ring_nf at *
625+ field
626+
627+ /--
628+ info: Try this:
629+ field_simp
630+ ---
631+ error: unsolved goals
632+ a b : ℚ
633+ H : b + a ≠ 0
634+ ⊢ (a + b) / (a + b) = 1
635+ -/
636+ #guard_msgs in
637+ example {a b : ℚ} (H : b + a ≠ 0 ) : a / (a + b) + b / (b + a) = 1 := by
638+ ring_nf
639+ field
640+
641+ /--
642+ info: Try this:
643+ field_simp
644+ ---
645+ error: unsolved goals
646+ a b : ℚ
647+ H : b + a ≠ 0
648+ ⊢ a * (b + a) / (a + b) + b = b + a
649+ -/
650+ #guard_msgs in
651+ example {a b : ℚ} (H : b + a ≠ 0 ) : a / (a + b) + b / (b + a) = 1 := by
652+ field
653+
654+ example {a b : ℚ} (H : a + b + 1 ≠ 0 ) :
655+ a / (a + (b + 1 ) ^ 2 / (b + 1 )) + (b + 1 ) / (b + a + 1 ) = 1 := by
656+ field_simp
657+ ring_nf at *
658+ field
659+
660+ /--
661+ info: Try this:
662+ field_simp
663+ ---
664+ error: unsolved goals
665+ a b : ℚ
666+ H : 1 + a + b ≠ 0
667+ ⊢ a * (1 + a + b) / (a + b * 2 / (1 + b) + b ^ 2 / (1 + b) + 1 / (1 + b)) + b + 1 = 1 + a + b
668+ -/
669+ #guard_msgs in
670+ example {a b : ℚ} (H : a + b + 1 ≠ 0 ) :
671+ a / (a + (b + 1 ) ^ 2 / (b + 1 )) + (b + 1 ) / (b + a + 1 ) = 1 := by
672+ ring_nf at *
673+ field
674+
675+ /--
676+ info: Try this:
677+ field_simp
678+ ---
679+ error: unsolved goals
680+ a b : ℚ
681+ H : a + b + 1 ≠ 0
682+ ⊢ a / (a + (b + 1)) + (b + 1) / (b + a + 1) = 1
683+ -/
684+ #guard_msgs in
685+ example {a b : ℚ} (H : a + b + 1 ≠ 0 ) :
686+ a / (a + (b + 1 ) ^ 2 / (b + 1 )) + (b + 1 ) / (b + a + 1 ) = 1 := by
687+ field
688+
689+ end
690+
565691/-! From PluenneckeRuzsa: new `field_simp` doesn't handle variable exponents -/
566692
567693example (x y : ℚ≥0 ) (n : ℕ) (hx : x ≠ 0 ) : y * ((y / x) ^ n * x) = (y / x) ^ (n + 1 ) * x * x := by
0 commit comments