lean4-htt/src/Lean/Meta/Tactic
Joachim Breitner f45c19b428
feat: identify more fixed parameters (#7166)
This PR extends the notion of “fixed parameter” of a recursive function
also to parameters that come after varying function. The main benefit is
that we get nicer induction principles.


Before the definition

```lean
def app (as : List α) (bs : List α) : List α :=
  match as with
  | [] => bs
  | a::as => a :: app as bs
```

produced

```lean
app.induct.{u_1} {α : Type u_1} (motive : List α → List α → Prop) (case1 : ∀ (bs : List α), motive [] bs)
  (case2 : ∀ (bs : List α) (a : α) (as : List α), motive as bs → motive (a :: as) bs) (as bs : List α) : motive as bs
```
and now you get
```lean
app.induct.{u_1} {α : Type u_1} (motive : List α → Prop) (case1 : motive [])
  (case2 : ∀ (a : α) (as : List α), motive as → motive (a :: as)) (as : List α) : motive as
```
because `bs` is fixed throughout the recursion (and can completely be
dropped from the principle).

This is a breaking change when such an induction principle is used
explicitly. Using `fun_induction` makes proof tactics robust against
this change.

The rules for when a parameter is fixed are now:

1. A parameter is fixed if it is reducibly defq to the the corresponding
argument in each recursive call, so we have to look at each such call.
2. With mutual recursion, it is not clear a-priori which arguments of
another function correspond to the parameter. This requires an analysis
with some graph algorithms to determine.
3. A parameter can only be fixed if all parameters occurring in its type
are fixed as well.
This dependency graph on parameters can be different for the different
functions in a recursive group, even leading to cycles.
4. For structural recursion, we kinda want to know the fixed parameters
before investigating which argument to actually recurs on. But once we
have that we may find that we fixed an index of the recursive
parameter’s type, and these cannot be fixed. So we have to un-fix them
5. … and all other fixed parameters that have dependencies on them.

Lean tries to identify the largest set of parameters that satisfies
these criteria.

Note that in a definition like
```lean
def app : List α → List α → List α
  | [], bs => bs
  | a::as, bs => a :: app as bs
```
the `bs` is not considered fixes, as it goes through the matcher
machinery.


Fixes #7027
Fixes #2113
2025-03-04 22:26:20 +00:00
..
AC refactor: mark the Simp.Context constructor as private 2024-11-13 14:12:55 +11:00
Grind feat: cooper conflict resolution in cutsat (#7315) 2025-03-04 03:23:14 +00:00
Simp feat: IntX simprocs (#7228) 2025-03-03 13:37:57 +00:00
Try feat: try? to use fun_induction (#7082) 2025-02-18 16:06:58 +00:00
AC.lean perf: add prelude to all Lean modules 2024-02-18 14:55:17 -08:00
Acyclic.lean refactor: mark the Simp.Context constructor as private 2024-11-13 14:12:55 +11:00
Apply.lean feat: Nat.(fold|foldRev|any|all)M? take a function which sees the upper bound (#6139) 2024-11-22 03:05:51 +00:00
Assert.lean feat: allow MVarId.assertHypotheses to set BinderInfo/Kind (#5587) 2024-10-02 05:09:49 +00:00
Assumption.lean chore: delete deprecations from 2022 (#4618) 2024-07-02 03:47:33 +00:00
AuxLemma.lean feat: propagate maxHeartbeats to kernel (#4113) 2024-05-09 17:44:19 +00:00
Backtrack.lean chore: rename List.join to List.flatten 2024-10-14 22:28:12 +11:00
Cases.lean feat: split on match-expressions in the grind tactic (#6569) 2025-01-08 03:10:11 +00:00
Cleanup.lean chore: delete deprecations from 2022 (#4618) 2024-07-02 03:47:33 +00:00
Clear.lean feat: Array.insertIdx/eraseIdx take a tactic-provided proof (#6133) 2024-11-20 09:52:38 +00:00
Congr.lean perf: add prelude to all Lean modules 2024-02-18 14:55:17 -08:00
Constructor.lean fix: bring elaborator in line with kernel for primitive projections (#5822) 2024-10-31 03:16:52 +00:00
Contradiction.lean feat: close goals using match-expression conditions in grind (#6783) 2025-01-26 17:13:11 +00:00
Delta.lean chore: delete deprecations from 2022 (#4618) 2024-07-02 03:47:33 +00:00
ElimInfo.lean feat: induction tactic to err on extra targets (#7224) 2025-02-25 20:53:16 +00:00
ExposeNames.lean fix: prevent exact? and apply? from suggesting invalid tactics (#7192) 2025-02-25 15:24:09 +00:00
Ext.lean refactor: move ext environment extension to Lean.Meta.Tactic 2025-01-17 12:31:14 -08:00
FunInd.lean feat: identify more fixed parameters (#7166) 2025-03-04 22:26:20 +00:00
FunIndCollect.lean feat: try? to use fun_induction (#7082) 2025-02-18 16:06:58 +00:00
FunIndInfo.lean feat: identify more fixed parameters (#7166) 2025-03-04 22:26:20 +00:00
FVarSubst.lean feat: offset constraints support for the grind tactic (#6603) 2025-01-12 20:38:39 +00:00
Generalize.lean chore: update copyrights (#5449) 2024-09-24 05:27:53 +00:00
Grind.lean feat: add Grind.mkDiseqProof? (#7231) 2025-02-25 23:40:07 +00:00
IndependentOf.lean chore: upstream solve_by_elim (#3408) 2024-02-21 01:16:04 +00:00
Induction.lean feat: cleanup of get and back functions on List/Array (#7059) 2025-02-17 01:43:45 +00:00
Injection.lean fix: nontermination while generating equation lemmas for match-expressions (#6180) 2024-11-23 00:06:34 +00:00
Intro.lean chore: mark Meta.Context.config as private (#6051) 2024-11-13 13:30:06 +11:00
LibrarySearch.lean feat: try? tactic (#6905) 2025-02-02 06:37:49 +00:00
NormCast.lean feat: use attribute command to add and erase simprocs (#3511) 2024-02-26 23:41:49 +00:00
Refl.lean feat: apply_rfl tactic: handle Eq, HEq, better error messages (#3714) 2024-09-20 08:25:10 +00:00
Rename.lean chore: delete deprecations from 2022 (#4618) 2024-07-02 03:47:33 +00:00
Repeat.lean chore: update copyrights (#5449) 2024-09-24 05:27:53 +00:00
Replace.lean fix: use Expr.equal instead of == in MVarId.replaceTargetDefEq and MVarId.replaceLocalDeclDefEq (#6098) 2024-11-16 02:03:16 +00:00
Revert.lean fix: revert creates natural metavariable goal (#6145) 2024-11-21 23:00:57 +00:00
Rewrite.lean feat: binderNameHint (#6947) 2025-02-06 11:03:27 +00:00
Rewrites.lean chore: mark Meta.Context.config as private (#6051) 2024-11-13 13:30:06 +11:00
Rfl.lean fix: isDefEq, whnf, simp caching and configuration (#6053) 2024-11-18 01:17:26 +00:00
Simp.lean feat: cutsat preparations (#7097) 2025-02-16 02:52:14 +00:00
SolveByElim.lean chore: update copyrights (#5449) 2024-09-24 05:27:53 +00:00
Split.lean refactor: simpMatch to not etaStruct (#6901) 2025-02-01 19:04:05 +00:00
SplitIf.lean feat: partial_fixpoint: partial functions with equations (#6355) 2025-01-21 09:54:30 +00:00
Subst.lean feat: Nat.(fold|foldRev|any|all)M? take a function which sees the upper bound (#6139) 2024-11-22 03:05:51 +00:00
Symm.lean fix: isDefEq, whnf, simp caching and configuration (#6053) 2024-11-18 01:17:26 +00:00
Try.lean feat: improve try? suggestion (#6991) 2025-02-07 16:33:25 +00:00
TryThis.lean fix: missing indents in Try this message (#7191) 2025-02-25 16:55:50 +00:00
Unfold.lean refactor: mark the Simp.Context constructor as private 2024-11-13 14:12:55 +11:00
UnifyEq.lean chore: move MessageData.ofConstName earlier (#5877) 2024-10-29 21:23:51 +00:00
Util.lean feat: labeled and unique sorries (#5757) 2024-12-11 23:53:02 +00:00