|
| 1 | +set_option grind.warning false |
| 2 | + |
| 3 | +axiom R : Type |
| 4 | +instance : Lean.Grind.CommRing R := sorry |
| 5 | + |
| 6 | +axiom cos : R → R |
| 7 | +axiom sin : R → R |
| 8 | +axiom trig_identity : ∀ x, (cos x)^2 + (sin x)^2 = 1 |
| 9 | + |
| 10 | +grind_pattern trig_identity => cos x |
| 11 | +grind_pattern trig_identity => sin x |
| 12 | + |
| 13 | +-- Whenever `grind` sees `cos` or `sin`, it adds `(cos x)^2 + (sin x)^2 = 1` to the blackboard. |
| 14 | +-- That's a polynomial, so it is sent to the Grobner basis module. |
| 15 | +-- And we can prove equalities modulo that relation! |
| 16 | +example : (cos x + sin x)^2 = 2 * cos x * sin x + 1 := by |
| 17 | + grind +ring |
| 18 | + |
| 19 | +-- `grind` notices that the two arguments of `f` are equal, |
| 20 | +-- and hence the function applications are too. |
| 21 | +example (f : R → Nat) : f ((cos x + sin x)^2) = f (2 * cos x * sin x + 1) := by |
| 22 | + grind +ring |
| 23 | + |
| 24 | +-- After that, we can use basic modularity conditions: |
| 25 | +-- this reduces to `4 * x ≠ 2 + x` for some `x : ℕ` |
| 26 | +example (f : R → Nat) : 4 * f ((cos x + sin x)^2) ≠ 2 + f (2 * cos x * sin x + 1) := by |
| 27 | + grind +ring |
| 28 | + |
| 29 | +-- A bit of case splitting is also fine. |
| 30 | +-- If `max = 3`, then `f _ = 0`, and we're done. |
| 31 | +-- Otherwise, the previous argument applies. |
| 32 | +example (f : R → Nat) : max 3 (4 * f ((cos x + sin x)^2)) ≠ 2 + f (2 * cos x * sin x + 1) := by |
| 33 | + grind +ring |
| 34 | + |
| 35 | +-- See https://github.com/leanprover-community/mathlib4/blob/nightly-testing/MathlibTest/grind/trig.lean |
| 36 | +-- for the Mathlib version of this test, using the real `ℝ`, `cos`, `sin`, and `cos_sq_and_sin_sq` declarations. |
0 commit comments