fix: regression reported at issue #1113

see issue #1113
This commit is contained in:
Leonardo de Moura 2022-04-23 14:42:00 -07:00
parent 4ab57475a0
commit 13bcbe91cd
3 changed files with 32 additions and 4 deletions

View file

@ -469,7 +469,7 @@ where
withParent e <| e.withApp fun f args => do
congrArgs (← simp f) args
/- Return true iff processing the given congruence theorem hypothesis produced a non-refl proof. -/
/-- Process the given congruence theorem hypothesis. Return true if it made "progress". -/
processCongrHypothesis (h : Expr) : M Bool := do
forallTelescopeReducing (← inferType h) fun xs hType => withNewLemmas xs do
let lhs ← instantiateMVars hType.appFn!.appArg!
@ -481,9 +481,25 @@ where
throwCongrHypothesisFailed
unless (← isDefEq h (← mkLambdaFVars xs (← r.getProof))) do
throwCongrHypothesisFailed
return r.proof?.isSome
/- We used to return `false` if `r.proof? = none` (i.e., an implicit `rfl` proof) because we
assumed `dsimp` would also be able to simplify the term, but this is not true
for non-trivial user-provided theorems.
Example:
```
@[congr] theorem image_congr {f g : α → β} {s : Set α} (h : ∀ a, mem a s → f a = g a) : image f s = image g s :=
...
/- Try to rewrite `e` children using the given congruence theorem -/
example {Γ: Set Nat}: (image (Nat.succ ∘ Nat.succ) Γ) = (image (fun a => a.succ.succ) Γ) := by
simp only [Function.comp_apply]
```
`Function.comp_apply` is a `rfl` theorem, but `dsimp` will not apply it because the composition
is not fully applied. See comment at issue #1113
Thus, we have an extra check now if `xs.size > 0`. TODO: refine this test.
-/
return r.proof?.isSome || (xs.size > 0 && lhs != r.expr)
/-- Try to rewrite `e` children using the given congruence theorem -/
trySimpCongrTheorem? (c : SimpCongrTheorem) (e : Expr) : M (Option Result) := withNewMCtxDepth do
trace[Debug.Meta.Tactic.simp.congr] "{c.theoremName}, {e}"
let thm ← mkConstWithFreshMVarLevels c.theoremName

View file

@ -7,4 +7,7 @@ h_size : size ≤ cap
h_full : ∀ (i : Nat), i < size → Option.isSome (backing { val := i, isLt := (_ : i < cap) }) = true
i : Nat
h : i < size
⊢ Option.isSome (if h : i < cap then backing { val := i, isLt := h } else none) = true
⊢ Option.isSome
(if h_1 : i < cap then backing { val := i, isLt := (_ : { val := i, isLt := (_ : i < cap + cap) }.val < cap) }
else none) =
true

View file

@ -0,0 +1,9 @@
def Set (α : Type u) := α → Prop
def mem (a : α) (s : Set α) := s a
def image (f : α → β) (s : Set α) : Set β := fun b => ∃ a, mem a s ∧ f a = b
@[congr] theorem image_congr {f g : α → β} {s : Set α} (h : ∀ a, mem a s → f a = g a) : image f s = image g s :=
sorry
example {Γ: Set Nat}: (image (Nat.succ ∘ Nat.succ) Γ) = (image (fun a => a.succ.succ) Γ) := by
simp only [Function.comp_apply]