我有一个函数count
,它可以计算给定谓词在应用于列表元素时可证明的次数。它的定义如下:
Parameter T : Type.
Parameter dec: forall (p: T -> Prop) (w: T), {p w} + {~ (p w)}.
Fixpoint count (p: T -> Prop) (l: list T) := match l with
| nil => 0
| (cons head tail) => if (dec p head) then (1 + (count p tail)) else (count p tail)
end.
然后,我使用此函数来声明如下所示的引理:
Parameter a b c: T.
Parameter q: T -> Prop.
Axiom Aa: (q a).
Axiom Ab: (q b).
Axiom Ac: ~ (q c).
Lemma example: (count q (cons a (cons b (cons c nil)))) = 2.
我对这些引理的证据往往很乏味:
Lemma example: (count q (cons a (cons b (cons c nil)))) = 2.
Proof.
unfold count.
assert (q a); [apply Aa| auto].
assert (q b); [apply Ab| auto].
assert (~ (q c)); [apply Ac| auto].
destruct (dec q a); [auto | contradiction].
destruct (dec q b); [auto | contradiction].
destruct (dec q c); [contradiction | auto].
Qed.
我可以做些什么来自动化涉及使用count
函数进行计算的繁琐证据?
答案 0 :(得分:2)
这通常是指您最好通过反思来证明事物的情况。看看情况如何顺利(当然我修改了一些你的例子以避免所有这些公理):
count
我意识到你对count
的定义是在类型T上采用命题谓词(但假设所有关于类型T的谓词都是可判定的)而我建议定义Parameter T : Type.
Parameter dec: forall (p: T -> Prop) (w: T), {p w} + {~ (p w)}.
Definition prop_to_bool_predicate (p : T -> Prop) (x : T) : bool :=
if dec p x then true else false.
来取一个布尔谓词。但是你可能会意识到具有可判定的命题谓词或具有布尔谓词实际上是等价的。
E.g。从你的公理,我可以定义一个函数,将任何命题谓词转换为布尔谓词:
p
当然,因为你的例子中涉及公理,所以实际上不可能用布尔谓词来计算。但是我假设你把所有这些公理用于示例的目的,并且你的实际应用程序没有它们。
正如我告诉过你的,一旦你用公理(或Parameter
定义了一些函数,因为这是相同的事情),你再也无法用它来计算。 / p>
然而,这是一个解决方案,其中命题谓词count
的可判定性是一个引理。我用Defined
而不是Qed
结束了引理的证明,以允许用它进行计算(否则,它不会比公理更好)。正如您所看到的,我还重新定义了bool
函数以获取谓词并证明其可判定性。在这种情况下,反射证明仍然有效。没有Require Import List.
Import ListNotations.
Fixpoint count {T : Type}
(p : T -> Prop) (dec : forall (w: T), {p w} + {~ (p w)}) (l : list T) :=
match l with
| [] => 0
| h :: t => if dec h then S (count p dec t) else (count p dec t)
end.
Inductive T := a | b | c.
Definition p x := match x with | a => True | b => True | c => False end.
Lemma dec_p: forall (w: T), {p w} + {~ (p w)}.
Proof.
intros []; simpl; auto.
Defined.
Lemma example2: (count p dec_p [a; b; c]) = 2. Proof. reflexivity. Qed.
但它完全等同。
| BeKwX8iN3wzHDvCaxBD1 |
| 3rPB9t6EF3RGla28YbLE |
| OAYRwbrkctcVbrXaaTef |
| N8lxYdvx47FI7eYt5FUX |
| zwtRdHr3aYYnX9avcMjX |
.....
答案 1 :(得分:1)
让我们创建自定义提示数据库并在那里添加公理:
Hint Resolve Aa : axiom_db.
Hint Resolve Ab : axiom_db.
Hint Resolve Ac : axiom_db.
现在,firstorder
策略可以使用提示数据库:
Lemma example: count q (cons a (cons b (cons c nil))) = 2.
Proof.
unfold count.
destruct (dec q a), (dec q b), (dec q c); firstorder with axiom_db.
Qed.
我们可以使用以下Ltac自动化我们的解决方案:
Ltac solve_the_probem :=
match goal with
|- context [if dec ?q ?x then _ else _] =>
destruct (dec q x);
firstorder with axioms_db;
solve_the_probem
end.
然后,unfold count; solve_the_probem.
将能够证明这个引理。