Ltac 模式匹配:为什么 `forall x, ?P x` 不匹配 `forall x, x`?
Ltac pattern matching: why does `forall x, ?P x` not match `forall x, x`?
Ltac checkForall H :=
let T := type of H in
match T with
| forall x, ?P x =>
idtac
| _ =>
fail 1 "not a forall"
end.
Example test : (forall x, x) -> True.
Proof.
intros H.
Fail checkForall H. (* not a forall *)
Abort.
我天真地期望 checkForall H
会成功,但事实并非如此。
在 Adam Chlipala Certified Programming with Dependent Types 一书中,discusses 模式匹配对依赖类型的限制:
The problem is that unification variables may not contain locally bound variables.
这是我在这里看到的行为的原因吗?
H的类型是forall x, x
,不是forall x, P x
。
Ltac checkForall H :=
let T := type of H in
match T with
| forall x, ?P x =>
idtac
| forall x, x =>
idtac "this matches"
| _ =>
fail 1 "not a forall"
end.
Example test : (forall x, x) -> True.
Proof.
intros H.
checkForall H. (* not a forall *)
Abort.
或匹配您的 checkForall
Example test {T} (f:T->Prop) : (forall x, f x) -> True.
Proof.
intros H.
checkForall H.
正如 larsr 所解释的,模式 ?P x
只能匹配在句法上属于应用程序的术语,它不涵盖您正在考虑的情况。但是,Ltac 确实提供了您正在寻找的匹配项的功能。正如 user manual 所说:
There is also a special notation for second-order pattern-matching problems: in an applicative pattern of the form @?id id1 …idn
, the variable id matches any complex expression with (possible) dependencies in the variables id1 …idn
and returns a functional term of the form fun id1 …idn => term
.
因此,我们可以编写如下证明脚本:
Goal (forall x : Prop, x) -> False.
intros H.
match goal with
| H : forall x : Prop, @?P x |- _ => idtac P
end.
打印 (fun x : Prop => x)
.
Ltac checkForall H :=
let T := type of H in
match T with
| forall x, ?P x =>
idtac
| _ =>
fail 1 "not a forall"
end.
Example test : (forall x, x) -> True.
Proof.
intros H.
Fail checkForall H. (* not a forall *)
Abort.
我天真地期望 checkForall H
会成功,但事实并非如此。
在 Adam Chlipala Certified Programming with Dependent Types 一书中,discusses 模式匹配对依赖类型的限制:
The problem is that unification variables may not contain locally bound variables.
这是我在这里看到的行为的原因吗?
H的类型是forall x, x
,不是forall x, P x
。
Ltac checkForall H :=
let T := type of H in
match T with
| forall x, ?P x =>
idtac
| forall x, x =>
idtac "this matches"
| _ =>
fail 1 "not a forall"
end.
Example test : (forall x, x) -> True.
Proof.
intros H.
checkForall H. (* not a forall *)
Abort.
或匹配您的 checkForall
Example test {T} (f:T->Prop) : (forall x, f x) -> True.
Proof.
intros H.
checkForall H.
正如 larsr 所解释的,模式 ?P x
只能匹配在句法上属于应用程序的术语,它不涵盖您正在考虑的情况。但是,Ltac 确实提供了您正在寻找的匹配项的功能。正如 user manual 所说:
There is also a special notation for second-order pattern-matching problems: in an applicative pattern of the form
@?id id1 …idn
, the variable id matches any complex expression with (possible) dependencies in the variablesid1 …idn
and returns a functional term of the formfun id1 …idn => term
.
因此,我们可以编写如下证明脚本:
Goal (forall x : Prop, x) -> False.
intros H.
match goal with
| H : forall x : Prop, @?P x |- _ => idtac P
end.
打印 (fun x : Prop => x)
.