Coq 是否有从假设中提取含义的策略(反转除外)?
假设我有以下目标: 在人眼看来,很明显,H最终为真的唯一方法是n为7或21。我想用“既然H需要n是7或21,那么目标必须是真的”来证明这一点Coq 是否有从假设中提取含义的策略(反转除外)?,coq,Coq,假设我有以下目标: 在人眼看来,很明显,H最终为真的唯一方法是n为7或21。我想用“既然H需要n是7或21,那么目标必须是真的”来证明这一点 我的第一个猜测是使用“反转H”,但这只增加了另一个相同形式的假设。考虑到假设H的形状,我担心这里最好的策略是使用暴力:即使匹配以简洁的形状打印,它的计算就像是由22个嵌套模式匹配组成,如 H : match n with | 0 => false | S n1 => match n1 with | 0
我的第一个猜测是使用“反转H”,但这只增加了另一个相同形式的假设。考虑到假设H的形状,我担心这里最好的策略是使用暴力:即使匹配以简洁的形状打印,它的计算就像是由22个嵌套模式匹配组成,如
H : match n with
| 0 => false
| S n1 =>
match n1 with
| 0 => false
| S n2 => ... (* The case for 7 is somewhere there *)
match n21 with
| 0 => true
| S _ => false
end
...
end
end
因此,您可以重复对n
进行案例分析,放弃所有获得假设true=false
的琐碎情况。
以下是一种方法:
Goal forall (n:nat), match n with | 7 | 21 => true | _ => false end = true -> n = 7 \/ n = 21.
Proof.
intros n.
repeat (destruct n as [|n] ; try discriminate). (* applies 22 times and then stops progressing *)
all: auto. (* solves the last two goals by reflexivity *)
Qed.
如果您不喜欢repeat子句,也可以尝试使用依赖模式匹配来解决此问题:
Proof.
intros n.
refine (match n as k return match k with | 7 | 21 => true | _ => false end = true -> k = 7 \/ k = 21 with
| 7 => _
| 21 => _
| _ => _ end).
(* 22 goals left *)
all: try discriminate. (* solves the 20 absurd goals *)
all: auto. (* solves the last two goals by reflexivity *)
Qed.
然而,我不能建议遵循这条路径:即使证明脚本是“小”的,它们实际上扩展到与最大整数的大小相同的模式匹配(因此证明的大小至少与所匹配的最大常量的大小成线性关系,这在第二个证明脚本中可以清楚地看到)
解决这个问题的一个更好的方法是用
H:Nat.eqb n 7 | | Nat.eqb n 21=true修改给你这个假设H的源定义,并使用关于等式的引理(可能还有反射,请参阅以获取关于该主题的参考)。考虑到假设H的形状,恐怕这里最好的策略是使用暴力:即使匹配以简洁的形状打印出来,它的计算也好像是由22个嵌套模式匹配组成,如
H : match n with
| 0 => false
| S n1 =>
match n1 with
| 0 => false
| S n2 => ... (* The case for 7 is somewhere there *)
match n21 with
| 0 => true
| S _ => false
end
...
end
end
因此,您可以重复对n
进行案例分析,放弃所有获得假设true=false
的琐碎情况。
以下是一种方法:
Goal forall (n:nat), match n with | 7 | 21 => true | _ => false end = true -> n = 7 \/ n = 21.
Proof.
intros n.
repeat (destruct n as [|n] ; try discriminate). (* applies 22 times and then stops progressing *)
all: auto. (* solves the last two goals by reflexivity *)
Qed.
如果您不喜欢repeat子句,也可以尝试使用依赖模式匹配来解决此问题:
Proof.
intros n.
refine (match n as k return match k with | 7 | 21 => true | _ => false end = true -> k = 7 \/ k = 21 with
| 7 => _
| 21 => _
| _ => _ end).
(* 22 goals left *)
all: try discriminate. (* solves the 20 absurd goals *)
all: auto. (* solves the last two goals by reflexivity *)
Qed.
然而,我不能建议遵循这条路径:即使证明脚本是“小”的,它们实际上扩展到与最大整数的大小相同的模式匹配(因此证明的大小至少与所匹配的最大常量的大小成线性关系,这在第二个证明脚本中可以清楚地看到)
解决这个问题的一个更好的方法是,用H:Nat.eqb n 7 | | | Nat.eqb n 21=true修改给出这个假设H的源定义,并使用关于等式的引理(可能还有反射,请参阅以获取该主题的参考)。这非常有用。非常感谢你!这非常有帮助。非常感谢你!