"Illegal schematic variable(s)" 在证明生成的代码中(案例规则:...)`
"Illegal schematic variable(s)" in code generated by proof (cases rule: ...)`
我为 case_option
定义了一个案例规则,希望能使一些证明更具可读性。
但是,当将它与 proof (cases rule: ...)
一起应用并使用 proof
语句建议的代码片段时,
Isar case
语法告诉我 Illegal schematic variable(s) in case ...
,即使该规则在其他情况下也有效。
lemma case_option_cases[case_names None Some]: (* removing the "case_names" tag does not solve the issue *)
assumes "x = None ==> P a"
and "!!y. x = Some y ==> P (b y)"
shows "P (case x of None => a | Some y => b y)"
using assms unfolding option.split_sel by blast
notepad
begin
fix P :: "'y => bool" and x :: "'x option" and a :: "'y" and b :: "'x => 'y"
(* sanity check *)
assume "x = None ==> P a" and "!!y. x = Some y ==> P (b y)"
then have "P (case x of None => a | Some y => b y)"
by (cases rule: case_option_cases) (* also works just "by (rule ...)" *)
have "P (case x of None => a | Some y => b y)"
proof (cases rule: case_option_cases) (* this line generates and suggests the following structure *)
case None (* Illegal schematic variable(s) in case "None" *)
then show ?thesis sorry
next
case (Some y) (* same here *)
then show ?thesis sorry
qed
end
有办法解决这个问题吗?
正如 Javier 指出的那样,解决方案是 实例化变量 (似乎只需要 x
)。
但是,cases
已经内置了这个:
proof (cases x rule: case_option_cases)
(* generates the following template *)
case None
then show ?thesis (* replace by "P a" *) sorry
next
case (Some y)
then show ?thesis (* replace by "P (b y)" *) sorry
qed
请注意,生成的代码仍然失败,因为 ?thesis
与应用 cases
后的新目标不匹配。相反,必须明确说明目标。
更好(虽然不太直观),使用 induction
代替 cases
自动实例化相关变量,额外的好处是提供正确的目标为 ?case
:
proof (induction rule: case_option_cases)
(* generates the following template *)
case None
then show ?case sorry
next
case (Some y)
then show ?case sorry
qed
我为 case_option
定义了一个案例规则,希望能使一些证明更具可读性。
但是,当将它与 proof (cases rule: ...)
一起应用并使用 proof
语句建议的代码片段时,
Isar case
语法告诉我 Illegal schematic variable(s) in case ...
,即使该规则在其他情况下也有效。
lemma case_option_cases[case_names None Some]: (* removing the "case_names" tag does not solve the issue *)
assumes "x = None ==> P a"
and "!!y. x = Some y ==> P (b y)"
shows "P (case x of None => a | Some y => b y)"
using assms unfolding option.split_sel by blast
notepad
begin
fix P :: "'y => bool" and x :: "'x option" and a :: "'y" and b :: "'x => 'y"
(* sanity check *)
assume "x = None ==> P a" and "!!y. x = Some y ==> P (b y)"
then have "P (case x of None => a | Some y => b y)"
by (cases rule: case_option_cases) (* also works just "by (rule ...)" *)
have "P (case x of None => a | Some y => b y)"
proof (cases rule: case_option_cases) (* this line generates and suggests the following structure *)
case None (* Illegal schematic variable(s) in case "None" *)
then show ?thesis sorry
next
case (Some y) (* same here *)
then show ?thesis sorry
qed
end
有办法解决这个问题吗?
正如 Javier 指出的那样,解决方案是 实例化变量 (似乎只需要 x
)。
但是,cases
已经内置了这个:
proof (cases x rule: case_option_cases)
(* generates the following template *)
case None
then show ?thesis (* replace by "P a" *) sorry
next
case (Some y)
then show ?thesis (* replace by "P (b y)" *) sorry
qed
请注意,生成的代码仍然失败,因为 ?thesis
与应用 cases
后的新目标不匹配。相反,必须明确说明目标。
更好(虽然不太直观),使用 induction
代替 cases
自动实例化相关变量,额外的好处是提供正确的目标为 ?case
:
proof (induction rule: case_option_cases)
(* generates the following template *)
case None
then show ?case sorry
next
case (Some y)
then show ?case sorry
qed