Search code examples
isabelle

Using `defines` with induction


Consider following lemma which should be easily provable:

lemma
  fixes n m::nat
  defines "m ≡ n - 1"
  shows "m ≤ n"
proof(induction n)
  case 0
  then show ?case unfolding m_def 
      (* Why does «n» appear here? *)
next
  case (Suc n)
  then show ?case sorry
qed

However after unfolding m, the goal becomes n - 1 ≤ 0 instead of 0 - 1 ≤ 0 rendering the goal unprovable since n = 2 is a counterexample.

Is this a bug in Isabelle? How can I unfold the definition correctly?


Solution

  • As Javier pointed out, the n defined in the lemma head is different from the n created by induction. In other words, any facts from "outside" that reference n are not directly usable within the proof (induction n) environment.

    However, Isabelle does offer a way to "inject" such facts, by piping them into induction:

    lemma
      fixes n m::nat
      defines "m ≡ n - 1"
      shows "m ≤ n"
      using m_def (* this allows induction to use this fact *)
    proof(induction n)
      case 0
      then show ?case by simp
    next
      case (Suc n)
      then show ?case by simp
    qed
    

    using assms will work just as well in this case.

    Note that direcly referring to m_def is no longer necessary, since a version of it is included for each case (in 0.hyps and Suc.hyps; use print_cases inside the proof for more information).