lean4-htt/tests/lean/run/congrTactic.lean
Kyle Miller ac600853c0
fix: let the congr tactic handle "under-applied" applications (#9225)
This PR improves the `congr` tactic so that it can handle function
applications with fewer arguments than the arity of the head function.
This also fixes a bug where `congr` could not make progress with
`Set`-valued functions in Mathlib, since `Set` was being unfolded and
making such functions have an apparently higher arity.

This addresses issue #2128 for the `congr` tactic, but not `simp` and
others.
2025-07-08 11:48:08 +00:00

73 lines
2 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/-!
# Tests of the `congr` tactic
-/
example (h : a = b) : Nat.succ (a + 1) = Nat.succ (b + 1) := by
congr
example (h : a = b) : Nat.succ (a + 1) = Nat.succ (b + 1) := by
congr 1
show a + 1 = b + 1
rw [h]
def f (p : Prop) (a : Nat) (h : a > 0) [Decidable p] : Nat :=
if p then
a - 1
else
a + 1
example (h : a = b) : f True (a + 1) (by simp +arith) = f (0 = 0) (b + 1) (by simp +arith) := by
congr
decide
example (h : a = b) : f True (a + 1) (by simp +arith) = f (0 = 0) (b + 1) (by simp +arith) := by
congr 1
· decide
· show a + 1 = b + 1
rw [h]
example (h₁ : α = β) (h₂ : α = γ) (a : α) : cast h₁ a ≍ cast h₂ a := by
congr
· subst h₁ h₂; rfl
· subst h₁ h₂; apply heq_of_eq; rfl
example (f : Nat → Nat) (g : Nat → Nat) : f (g (x + y)) = f (g (y + x)) := by
congr 2
rw [Nat.add_comm]
example (p q r : Prop) (h : q = r) : (p → q) = (p → r) := by
congr
example (p q r s : Prop) (h₁ : q = r) (h₂ : r = s) : (p → q) = (p → s) := by
congr
rw [h₁, h₂]
namespace Tao1
/-!
Reported on Zulip: https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/congr.20unexpectedly.20fails.20with.20Set.2Eimage/near/527382064
The `congr` tactic used to make no progress here because `congr` was computing the arity from the head function
(`Set.image`) rather than from the actual number of supplied arguments.
-/
def Set (α : Type _) := α → Prop
def Set.image {α β : Type _} (f : α → β) (s : Set α) : Set β :=
fun y => ∃ x, s x ∧ f x = y
infixl:80 " '' " => Set.image
example {X Y : Type} (f : X → Y) (E F : Set X) (h : E = F) : f '' E = f '' F := by
congr
/-!
This also didn't work, for the same reason.
-/
example {X Y : Type} (f g : X → Y) (h : f = g) : Set.image f = Set.image g := by
congr
/-!
The `HEq` version also did not work.
-/
example {X Y Y' : Type} (h : Y = Y') (f : X → Y) (f' : X → Y') (hf : f ≍ f') (E : Set X) : f '' E ≍ f' '' E := by
congr
end Tao1