SSReflect の case タクティックは,否定 (not, ~ A) に関しても場合分けしてくれる.
だが,その前に,普通のを見てみる.
============================ forall b : bool, b -> G
という状況で,case.
とすると,
2 subgoals, subgoal 1 (ID 10) G : Prop ============================ true -> G subgoal 2 (ID 11) is: false -> G
となる.そりゃそうだ.
inductive type を値の型とする関数も case ができるようだ.
実験してみるとなかなか不思議な仕様であるように思われる:
1 subgoals, subgoal 1 (ID 3) f : nat -> bool ============================ f 3 && f 2 == f 1
この状況で, case f.
とすると,
2 subgoals, subgoal 1 (ID 4) f : nat -> bool ============================ true && f 2 == f 1 subgoal 2 (ID 5) is: false && f 2 == f 1
となる.うーむ.ま,それはそれとして,適用するものがないと,作れと要求される.
1 subgoals, subgoal 1 (ID 2) f : bool -> bool ============================ nat
この状況で,case f.
とすると,
3 subgoals, subgoal 1 (ID 3) f : bool -> bool ============================ bool subgoal 2 (ID 4) is: nat subgoal 3 (ID 5) is: nat
となる.順に,場合分けに使うfの定義域の値の要求,値が true の場合と false の場合の
nat値の要求,となっている.実際,case f.
の代わりに
case f; [exact true | exact 10 | exact 20].
とすると
定義ができて,Print してみると,
fun f : bool -> bool => if f true then 10 else 20 : (bool -> bool) -> nat
となる.
やっと本題.こういうわけなので,
============================ ~ A -> G
という状況で,case.
すると,
~A
は,関数 A -> False
のことなので,
A のどの値で見るか,というのを尋ねる1個と,False の constructor の数 ( = 0 個) の
和の分だけの subgoal ができるわけで,
============================ A
となる.