Coq/SSReflect: 反映&&和/\时如何进行案例分析
Coq/SSReflect: How to do case analysis when reflecting && and /\
我有以下反映谓词:
Require Import mathcomp.ssreflect.all_ssreflect.
Inductive reflect (P : Prop) (b : bool) : Prop :=
| ReflectT (p : P) (e : b = true)
| ReflectF (np : ~ P) (e : b = false).
我正在尝试将布尔合取与逻辑合取联系起来,并通过以下单行证明:
Lemma andP (b1 b2 : bool) : reflect (b1 /\ b2) (b1 && b2).
Proof.
case b1; case b2; constructor =>//; by case.
Qed.
不过,我不明白最后的; by case.
是怎么应用的。当我们检查没有最后一个 ; by case.
:
的证明时
Lemma andP (b1 b2 : bool) : reflect (b1 /\ b2) (b1 && b2).
Proof.
case b1; case b2; constructor =>//.
我们得到 6 个子目标(其中 2 个基本正确):
6 subgoals (ID 45)
b1, b2 : bool
============================
true /\ false
subgoal 2 (ID 46) is:
true && false = true
subgoal 3 (ID 116) is:
false /\ true
subgoal 4 (ID 117) is:
false && true = true
subgoal 5 (ID 187) is:
false /\ false
subgoal 6 (ID 188) is:
false && false = true
我不确定如何从这里开始,因为它们都是 false
- 我们如何证明这一点?我尝试单独执行 . case.
但这不起作用。 ; by case
如何一次承认这些子目标?
谢谢。
我不确定你为什么得到 6 个子目标:case b1; case b2; constructor
产生 4 个子目标,对应于布尔值组合的四种可能情况:
true /\ true
subgoal 2 (ID 13) is:
~ (true /\ false)
subgoal 3 (ID 15) is:
~ (false /\ true)
subgoal 4 (ID 17) is:
~ (false /\ false)
第一个被 //
认为微不足道。
Set Printing Coercions
会告诉你你的子目标或实际如下:
is_true true /\ is_true true
subgoal 2 (ID 13) is:
~ (is_true true /\ is_true false)
subgoal 3 (ID 15) is:
~ (is_true false /\ is_true true)
subgoal 4 (ID 17) is:
~ (is_true false /\ is_true false)
展开 is_true
可能有帮助:case b1; case b2; constructor; rewrite /is_true.
:
true = true /\ true = true
subgoal 2 (ID 19) is:
~ (true = true /\ false = true)
subgoal 3 (ID 20) is:
~ (false = true /\ true = true)
subgoal 4 (ID 21) is:
~ (false = true /\ false = true)
最后 3 个子目标的形式为 (_ /\ _) -> False
(因为 ~ P
代表 not P
,展开为 P -> False
。
因此在 constructor
之后添加的 case
策略破坏了顶级假设,将最后三个目标变成了以下内容:
true = true -> false = true -> False
subgoal 2 (ID 145) is:
false = true -> true = true -> False
subgoal 3 (ID 155) is:
false = true -> false = true -> False
在这里,我们将 false = true
作为每个子目标的假设之一,这意味着我们得到了一个矛盾,SSReflect 可以立即识别并使用 principle of explosion.
完成证明
战术的顺序组合行为在最近几年发生了一些变化。如今,像 constructor
这样的策略可以在执行它们的延续时回溯。因为您对 reflect
的定义与标准定义有点不同,如果您只是调用 constructor
,Coq 将立即应用 ReflectT
,导致在以下三种情况下卡住目标:
Lemma andP (b1 b2 : bool) : reflect (b1 /\ b2) (b1 && b2).
Proof.
case b1; case b2=> /=.
- constructor=> //.
- (* constructor. *) (* Stuck *)
当您使用顺序组合时,constructor
策略回溯,正确找到 ReflectF
构造函数。
constructor; by try case.
- constructor; by try case.
- constructor; by try case.
Qed.
我有以下反映谓词:
Require Import mathcomp.ssreflect.all_ssreflect.
Inductive reflect (P : Prop) (b : bool) : Prop :=
| ReflectT (p : P) (e : b = true)
| ReflectF (np : ~ P) (e : b = false).
我正在尝试将布尔合取与逻辑合取联系起来,并通过以下单行证明:
Lemma andP (b1 b2 : bool) : reflect (b1 /\ b2) (b1 && b2).
Proof.
case b1; case b2; constructor =>//; by case.
Qed.
不过,我不明白最后的; by case.
是怎么应用的。当我们检查没有最后一个 ; by case.
:
Lemma andP (b1 b2 : bool) : reflect (b1 /\ b2) (b1 && b2).
Proof.
case b1; case b2; constructor =>//.
我们得到 6 个子目标(其中 2 个基本正确):
6 subgoals (ID 45)
b1, b2 : bool
============================
true /\ false
subgoal 2 (ID 46) is:
true && false = true
subgoal 3 (ID 116) is:
false /\ true
subgoal 4 (ID 117) is:
false && true = true
subgoal 5 (ID 187) is:
false /\ false
subgoal 6 (ID 188) is:
false && false = true
我不确定如何从这里开始,因为它们都是 false
- 我们如何证明这一点?我尝试单独执行 . case.
但这不起作用。 ; by case
如何一次承认这些子目标?
谢谢。
我不确定你为什么得到 6 个子目标:case b1; case b2; constructor
产生 4 个子目标,对应于布尔值组合的四种可能情况:
true /\ true
subgoal 2 (ID 13) is:
~ (true /\ false)
subgoal 3 (ID 15) is:
~ (false /\ true)
subgoal 4 (ID 17) is:
~ (false /\ false)
第一个被 //
认为微不足道。
Set Printing Coercions
会告诉你你的子目标或实际如下:
is_true true /\ is_true true
subgoal 2 (ID 13) is:
~ (is_true true /\ is_true false)
subgoal 3 (ID 15) is:
~ (is_true false /\ is_true true)
subgoal 4 (ID 17) is:
~ (is_true false /\ is_true false)
展开 is_true
可能有帮助:case b1; case b2; constructor; rewrite /is_true.
:
true = true /\ true = true
subgoal 2 (ID 19) is:
~ (true = true /\ false = true)
subgoal 3 (ID 20) is:
~ (false = true /\ true = true)
subgoal 4 (ID 21) is:
~ (false = true /\ false = true)
最后 3 个子目标的形式为 (_ /\ _) -> False
(因为 ~ P
代表 not P
,展开为 P -> False
。
因此在 constructor
之后添加的 case
策略破坏了顶级假设,将最后三个目标变成了以下内容:
true = true -> false = true -> False
subgoal 2 (ID 145) is:
false = true -> true = true -> False
subgoal 3 (ID 155) is:
false = true -> false = true -> False
在这里,我们将 false = true
作为每个子目标的假设之一,这意味着我们得到了一个矛盾,SSReflect 可以立即识别并使用 principle of explosion.
战术的顺序组合行为在最近几年发生了一些变化。如今,像 constructor
这样的策略可以在执行它们的延续时回溯。因为您对 reflect
的定义与标准定义有点不同,如果您只是调用 constructor
,Coq 将立即应用 ReflectT
,导致在以下三种情况下卡住目标:
Lemma andP (b1 b2 : bool) : reflect (b1 /\ b2) (b1 && b2).
Proof.
case b1; case b2=> /=.
- constructor=> //.
- (* constructor. *) (* Stuck *)
当您使用顺序组合时,constructor
策略回溯,正确找到 ReflectF
构造函数。
constructor; by try case.
- constructor; by try case.
- constructor; by try case.
Qed.