Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: abstract tactic #22296

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Mathlib.lean
Original file line number Diff line number Diff line change
Expand Up @@ -5117,6 +5117,7 @@ import Mathlib.SetTheory.ZFC.Rank
import Mathlib.Std.Data.HashMap
import Mathlib.Tactic
import Mathlib.Tactic.Abel
import Mathlib.Tactic.Abstract
import Mathlib.Tactic.AdaptationNote
import Mathlib.Tactic.Algebraize
import Mathlib.Tactic.ApplyAt
Expand Down
1 change: 1 addition & 0 deletions Mathlib/Tactic.lean
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import Mathlib.Tactic.Abel
import Mathlib.Tactic.Abstract
import Mathlib.Tactic.AdaptationNote
import Mathlib.Tactic.Algebraize
import Mathlib.Tactic.ApplyAt
Expand Down
32 changes: 32 additions & 0 deletions Mathlib/Tactic/Abstract.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/-
Copyright (c) 2025 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn, Sven Manthe
-/
import Mathlib.Init
import Lean.Elab.Tactic.Simp

Check warning on line 7 in Mathlib/Tactic/Abstract.lean

View workflow job for this annotation

GitHub Actions / Build

unused import (use `lake exe shake --fix` to fix this, or `lake exe shake --update` to ignore)

Check warning on line 7 in Mathlib/Tactic/Abstract.lean

View workflow job for this annotation

GitHub Actions / Build

import #[Lean.Meta.Closure] instead

/-! # The `abstract` tactic -/

open Lean Meta Elab Tactic Term

/--
Usage: `abstract <tacticSeq>`.

The abstract tactic executes the provided tactic sequence, and "hides" its proof behind a new
auxiliary lemma. This is mostly useful to hide long proofs in the statement of a theorem, since
certain tactics can be slow if the goal contains a large proof as subterm.
-/
elab "abstract" tacs:ppDedent(tacticSeq) : tactic => do
if (← getGoals).length ≠ 1 then
throwError "Abstract failed. There are {(← getGoals).length} goals. Expected exactly 1 goal."
let target ← getMainTarget
if !(← isProp target) then
throwError "Abstract failed. The current goal is not propositional."
let goal ← getMainGoal
let newGoal ← mkFreshExprMVar target
setGoals [newGoal.mvarId!]
evalTactic tacs
setGoals [goal]
let auxName := (← getDeclName?).get! ++ `abstract ++ (← mkFreshId)
goal.assign <| ← mkAuxTheorem auxName target newGoal
23 changes: 23 additions & 0 deletions MathlibTest/Abstract.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import Mathlib.Tactic.Abstract
import Mathlib.Tactic.Core
import Mathlib.Lean.Name

open Lean

theorem foo (x : Fin 1) : x = ⟨0, by abstract omega⟩ := Subsingleton.elim ..

-- We don't test the precise type of `foo`, since I don't know how robust
-- the generated unique number is (currently 87)
run_cmd do
let some t := (← getEnv).find? `foo | unreachable!
if !t.type.foldConsts false (fun n b ↦ b || n matches .num _ _) then
throwError "no aux-lemma in the type of foo"

/-- error: Abstract failed. The current goal is not propositional. -/
#guard_msgs in
example (n : Nat) : n = by abstract exact 0 := sorry

/-- error: Abstract failed. There are 2 goals. Expected exactly 1 goal. -/
#guard_msgs in
example (f : True ∧ True → Nat) (n : Nat) :
n = f (by constructor; abstract trivial; trivial) := sorry
Loading