leanprover / leanprover/lean4

fun_cases does not unfold dependent function

Open
#10,775 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug P-medium
Dominant language
Lean
Stars
9.2k
Forks
990
Avg merge
1d 17h
Merged PRs (30d)
175

Description

Consider


opaque R : (n m : Int) → Type

axiom mkR : Nat → R n m

def d : ∀ (n m : Int), R n m
  | .ofNat n, .ofNat m => mkR 0
  | .negSucc n, .negSucc m => mkR 0
  | .negSucc 0, .ofNat 0 => mkR 0
  | .ofNat _, .negSucc _ => mkR 0
  | .negSucc _, .ofNat _ => mkR 0

/--
error: unsolved goals
case refine_1
⊢ ∀ (n m : Nat), ¬↑n + 1 = ↑m → mkR 0 = mkR 0

case refine_2
⊢ ∀ (n m : Nat), ¬Int.negSucc n + 1 = Int.negSucc m → mkR 0 = mkR 0

case refine_3
⊢ ¬0 = 0 → mkR 0 = mkR 0

case refine_4
⊢ ∀ (a a_1 : Nat), ¬↑a + 1 = Int.negSucc a_1 → mkR 0 = mkR 0

case refine_5
⊢ ∀ (a a_1 : Nat), (a = 0 → a_1 = 0 → False) → ¬Int.negSucc a + 1 = ↑a_1 → mkR 0 = mkR 0
-/
#guard_msgs in
example : (n m : Int) → (hnm : n + 1 ≠ m) → d n m = mkR 0 := by
  refine d.fun_cases_unfolding (motive := fun n m r => (n + 1 ≠ m) → r = mkR 0)
    ?_ ?_ ?_ ?_ ?_ <;> dsimp

/--
error: unsolved goals
case case1
n✝ m✝ : Nat
hnm : Int.ofNat n✝ + 1 ≠ Int.ofNat m✝
⊢ d (Int.ofNat n✝) (Int.ofNat m✝) = mkR 0

case case2
n✝ m✝ : Nat
hnm : Int.negSucc n✝ + 1 ≠ Int.negSucc m✝
⊢ d (Int.negSucc n✝) (Int.negSucc m✝) = mkR 0

case case3
hnm : Int.negSucc 0 + 1 ≠ Int.ofNat 0
⊢ d (Int.negSucc 0) (Int.ofNat 0) = mkR 0

case case4
a✝¹ a✝ : Nat
hnm : Int.ofNat a✝¹ + 1 ≠ Int.negSucc a✝
⊢ d (Int.ofNat a✝¹) (Int.negSucc a✝) = mkR 0

case case5
a✝¹ a✝ : Nat
x✝ : a✝¹ = 0 → a✝ = 0 → False
hnm : Int.negSucc a✝¹ + 1 ≠ Int.ofNat a✝
⊢ d (Int.negSucc a✝¹) (Int.ofNat a✝) = mkR 0
-/
#guard_msgs in
example : (n m : Int) → (hnm : n + 1 ≠ m) → d n m = mkR 0 := by
  intros n m hnm
  fun_cases d

/--
error: unsolved goals
case case1
n✝ m✝ : Nat
hnm : Int.ofNat n✝ + 1 ≠ Int.ofNat m✝
⊢ d (Int.ofNat n✝) (Int.ofNat m✝) = mkR 0

case case2
n✝ m✝ : Nat
hnm : Int.negSucc n✝ + 1 ≠ Int.negSucc m✝
⊢ d (Int.negSucc n✝) (Int.negSucc m✝) = mkR 0

case case3
hnm : Int.negSucc 0 + 1 ≠ Int.ofNat 0
⊢ d (Int.negSucc 0) (Int.ofNat 0) = mkR 0

case case4
a✝¹ a✝ : Nat
hnm : Int.ofNat a✝¹ + 1 ≠ Int.negSucc a✝
⊢ d (Int.ofNat a✝¹) (Int.negSucc a✝) = mkR 0

case case5
a✝¹ a✝ : Nat
x✝ : a✝¹ = 0 → a✝ = 0 → False
hnm : Int.negSucc a✝¹ + 1 ≠ Int.ofNat a✝
⊢ d (Int.negSucc a✝¹) (Int.ofNat a✝) = mkR 0
-/
#guard_msgs in
example : (n m : Int) → (hnm : n + 1 ≠ m) → d n m = mkR 0 := by
  intros n m hnm
  cases n, m using d.fun_cases_unfolding

I’d expect the second and third example to produce the same goals as the first example.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the three examples around the fun_cases_unfolding and fun_cases entry points shown in the issue, then compare the generated goals. Done means the second and third examples produce the same goals as the first while preserving the dependent-function behavior.

Written by the indexing model from the issue text.

Assessment

Domain
tooling
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.