我正在学习命题逻辑和推理规则。 “析取三段论”规则指出,如果我们在我们的前提中有(P或Q),也有(不是P);然后我们可以到达Q。
我无法为自己的一生弄清楚如何在Coq中做到这一点。假设我有:
// XML document that we want to modify
let xml = "<foo><button/></foo>"
// Parse XML document
guard let document = try? XMLDocument(xmlString: xml, options: .documentValidate) else {
return
}
// Find all the buttons
let buttons = try? document.nodes(forXPath: "//button")
// Modify the buttons by adding custom attributes
buttons?.compactMap({ $0 as? XMLElement }).forEach {
$0.setAttributesWith([
"customClass": "AmazingButton",
"customModule": "IBComponents",
"customModuleProvider": "target"
])
}
// Print modified XML document
print(document.xmlString)
我应该使用哪种策略
<?xml version="1.0" encoding="UTF-8"?><foo><button customModuleProvider="target" customModule="IBComponents" customClass="AmazingButton"></button></foo>
另外,如果有人可以与我分享Coq战术上的基本推理规则(例如惯用语收费或析取性介绍等),我会很高兴。也许我可以使用一个插件吗?
答案 0 :(得分:3)
Coq没有内置此策略,但是幸运的是您可以定义自己的策略。注意
destruct H as [H1 | H1]; [contradiction |].
按照您的要求在上下文中放入H1 : B
。因此,您可以为此组合策略创建别名:
Ltac disj_syllogism AorB notA B :=
destruct AorB as [? | B]; [contradiction |].
现在,我们可以像这样轻松地模仿析取三段论规则:
Section Foo.
Context (A B : Prop) (H : A \/ B) (H0 : ~ A).
Goal True.
disj_syllogism H H0 H1.
End Foo.
让我展示一些自动化程度较低的方法:
Ltac disj_syllogism AorB notA B :=
let A := fresh "A" in
destruct AorB as [A | B]; [contradiction (notA A) |].
这种方法不要求Coq找到矛盾,而是直接将其提供给contradiction
策略(notA A
术语)。或者我们可以在pose proof
策略中使用明确的术语:
Ltac disj_syllogism AorB notA B :=
pose proof (match AorB with
| or_introl a => False_ind _ (notA a)
| or_intror b => b
end) as B.
我希望这会有所帮助。我不确定是否需要其他解释-请随时进行澄清,我将更新答案。
答案 1 :(得分:0)
基于安东·特鲁诺夫(Anton Trunov)的答案,“分离三段论”的简单版本如下:
(* Helper tactics. *)
Ltac oe1 P_or_Q not_P :=
destruct P_or_Q ; [ contradiction | ].
Ltac oe2 P_or_Q not_Q :=
destruct P_or_Q ; [ | contradiction ].
(* Main tactic *)
Ltac oE AorB H :=
oe1 AorB H || oe2 AorB H.
助手策略将根据False析取是在右边还是左边来处理一个案例,主要策略会同时尝试并返回成功者。
答案 2 :(得分:-1)
我认为您对Coq的工作方式可能抱有错误的期望?证明这一点的一般方法实质上是针对各种可能性的真值表:
Lemma it: forall a b, (a \/ b) /\ ~a -> b.
Proof.
intuition.
Show Proof.
Qed.
(fun (a b : Prop) (H : (a \/ b) /\ ~ a) =>
and_ind
(fun (H0 : a \/ b) (H1 : ~ a) =>
or_ind (fun H2 : a => let H3 : False := H1 H2 in False_ind b H3)
(fun H2 : b => H2) H0) H)
如果查看结果证明项,您会发现Coq本质上正在分解布尔型构造函数。我们可以手动执行此操作并获得相同的证明条件:
Lemma it: forall a b, (a \/ b) /\ ~a -> b.
Proof.
intros a b H.
induction H.
induction H.
contradict H. exact H0.
exact H.
Qed.
例如惯用语对应于Coq中的apply
,我认为这不是直接内置的。
然后,您可以使用此引理(并且我确定标准库中的某个位置有相应的版本)可以通过apply
得出其他假设。