我是coq的初学者,所以这可能是一个微不足道的问题。在编写定理时,有时我无法弄清楚我需要调用哪些术语。一个简单的例子,
Theorem silly1 : forall (n m o p : nat),
n = m ->
[n;o] = [n;p] ->
[n;o] = [m;p].
Proof.
intros n m o p eq1 eq2.
rewrite <- eq1.
apply eq2. Qed.
我知道基于目标,我可能需要在(n m o p)上调用intros,但为什么我需要在eq1和eq2上使用它。
此外,在其他一些定理中,您可能需要在类型参数,假设或归纳假设上使用介绍。实施例
Theorem trans_eq : forall (X:Type) (n m o : X),
n = m -> m = o -> n = o.
Proof.
intros X n m o eq1 eq2. rewrite -> eq1. rewrite -> eq2.
reflexivity. Qed.
Theorem silly3' : forall (n : nat),
(beq_nat n 5 = true -> beq_nat (S (S n)) 7 = true) ->
true = beq_nat n 5 ->
true = beq_nat (S (S n)) 7.
Proof.
intros n eq H.
symmetry in H. apply eq in H. symmetry in H.
apply H. Qed.
所以我想我要问的是......当我开始证明一个定理时,我应该如何推理目标,确定我需要调用哪些术语?
答案 0 :(得分:2)
加莱所指的是一个例子。
Theorem example_1 : forall A B, (A -> B) -> A -> B.
Proof. intros ? ? H1. apply H1. Qed.
Theorem example_2 : forall A B, (A -> B) -> A -> B.
Proof. intros ? ? H1 H2. apply H1. apply H2. Qed.
Print example_1.
Print example_2.
可能出现问题的另一个例子是在使用归纳之前使用介绍。这使得归纳假设不同。
Fixpoint reverse_helper {A : Type} (l1 l2 : list A) : list A :=
match l1 with
| nil => l2
| cons x l1 => reverse_helper l1 (cons x l2)
end.
Theorem example_3 : forall A (l1 l2 : list A), reverse_helper l1 l2 = app (reverse_helper l1 nil) l2.
Proof. intros. induction l1. simpl. reflexivity. simpl. try rewrite IHl1. Abort.
Theorem example_4 : forall A (l1 l2 : list A), reverse_helper l1 l2 = app (reverse_helper l1 nil) l2.
Proof. induction l1. intros. simpl. reflexivity. intros. simpl. rewrite (IHl1 (cons a l2)). rewrite (IHl1 (cons a nil)). Admitted.
否则,您应该尽可能使用介绍。在你做之前,你无法使用任何被量化的东西或暗示的前因。
顺便说一下
H1 : A1
...
Hn : An
___
B
相当于
H1: A1, ..., Hn: An ⊢ B.
当你以交互方式证明某事时,你会从结论开始使用后续的微积分,然后再回到假设。