3

I would like to define a rule for proof by cases, to be used with proof (cases rule: <rule-name>). I managed to use the case_names and consumes parameters, but I did not manage to bind the schematic variable ?case, so that, inside a case of a proof using my rule, one can write show ?case .... How do I bind it?

Concretely: I have the Mizar-inspired notion of a trivial set, i.e. empty or singleton set. I would like to prove properties of trivial sets by empty vs. singleton case analysis. So far I have:

definition trivial where "trivial x = (x ⊆ {the_elem x})"

lemma trivial_cases [case_names empty singleton, consumes 1]:
  assumes "trivial X"
  assumes empty: "P {}"
      and singleton: "⋀ x . X = {x} ⟹ P {x}"
  shows "P X"
using assms unfolding trivial_def by (metis subset_singletonD)

and I can make use of this as follows:

notepad
begin
  fix Q
  fix X::"'a set"
  have "trivial X" sorry
  then have "Q X"
  proof (cases rule: trivial_cases)
    case empty
    show "Q {}" sorry
  next
    case (singleton x)
    show "Q {x}" sorry
  qed
end

But I cannot use show ?case. If I try, it gives me the error message "Unbound schematic variable: ?case". print_cases inside the proof outputs the following:

cases:
  empty:
    let "?case" = "?P {}"
  singleton:
    fix x_
    let "?case" = "?P {x_}"
    assume "X = {x_}"

Which suggests that it doesn't work because ?P is not bound to trivial.

BTW: The full context in which I am using this can be seen at https://github.com/formare/auctions/blob/master/isabelle/Auction/SetUtils.thy.

chris
  • 4,988
  • 20
  • 36
Christoph Lange
  • 595
  • 2
  • 13
  • 2
    `cases` AFAIK never binds `?case`. Maybe you want to use the `induct` method, which does? – Joachim Breitner Sep 08 '13 at 19:44
  • Thanks, that works. I just hadn't thought of trying it, as using “induction” to prove a finite statement seemed strange to me. And indeed a different pattern has been suggested here. – Christoph Lange Sep 09 '13 at 05:43

1 Answers1

3

As Joachim already mentioned, unlike induct, the cases method does not bind the schematic variable ?case. I would say the "canonical" way of conducting case analysis (as a proof method) conforms to this setup, since typically only different assumptions -- which taken together are exhaustive -- are considered, whereas the conclusion stays the same (abbreviated by ?thesis in Isabelle) throughout the different cases. I would set up your trivial_cases as follows:

lemma trivial_cases [consumes 1, case_names empty singleton]:
  assumes "trivial X" and "X = {} ⟹ P" and "⋀x . X = {x} ⟹ P"
  shows "P"
  using assms by (auto simp: trivial_def)

Then you can use it like

notepad
begin
  fix P and X :: "'a set"
  have "trivial X" sorry
  then have "P X"
  proof (cases rule: trivial_cases)
    case empty
    then show ?thesis sorry
  next
    case (singleton x)
    then show ?thesis sorry
  qed
end

where the simplifier or explicit unfolding takes care of specializing X to {} and {x}, respectively.

Side Note: You can further tune trivial_cases by adding the attribtue cases pred: trivial. Then, whenever trivial ?X is the major assumption fed to cases, the rule trivial_cases is used implicitly, i.e., you can do the following

have "trivial X" sorry
then have "P X"
proof (cases)

in the above proof.

chris
  • 4,988
  • 20
  • 36
  • Thanks, that works very well. I have now modified my sources accordingly. `cases pred` actually also allows me to get rid of `consumes 1`, as the latter is the default for `cases pred` (`isabelle doc isar-ref` section 6.6.3). – Christoph Lange Sep 09 '13 at 05:55
  • 1
    Although the feature to enable `proof induct` and `proof cases` without a rule is very slick I have later regretted using it, when I was reading my theories a few months later. Explicit rules are more stable! – Joachim Breitner Sep 09 '13 at 07:21
  • Good point. However if Isabelle supported (I think it doesn't) displaying what implicit rule it applied whenever you write `proof` or `proof (cases)` or `proof (induct)` without explicitly referencing a rule, this would be easier to manage. – Christoph Lange Sep 09 '13 at 08:00
  • @JoachimBreitner: I kind of disagree ;). If I have an explicit rule, the only additional information (at least at this point in the sources) I get is the name of the rule, which might be completely useless. A combination of implicit rules and explicitly stating assumptions (instead of using `case (...)`) is the most *readable* variant I think. The cost is that you have to type more and maybe duplicate some formulas. (But of course I see the value of being able to click on a rule name and get to the corresponding proof.) – chris Sep 09 '13 at 08:09
  • I agree with @ChristophLange: It would be all fine if `proof`, `proof cases` et. al. would tell me what they are doing. – Joachim Breitner Sep 09 '13 at 08:37
  • @JoachimBreitner I think you can declare [[rule_trace]] to get more information from rule et al. – Lars Noschinski Sep 09 '13 at 10:17