Coq/SSreflect 中的有序序列
Ordered seq in Coq/SSreflect
我目前正在 Coq 中研究红黑树,想为 nat
的列表配备一个顺序,以便它们可以使用 [=16] 存储在红黑树中=]模块。
因此,我定义了 seq_lt
,如下所示:
Fixpoint seq_lt (p q : seq nat) := match p, q with
| _, [::] => false
| [::], _ => true
| h :: p', h' :: q' =>
if h == h' then seq_lt p' q'
else (h < h')
end.
到目前为止,我已经展示了:
Lemma lt_not_refl p : seq_lt p p = false.
Proof.
elim: p => //= ? ?; by rewrite eq_refl.
Qed.
以及
Lemma lt_not_eqseq : forall p q, seq_lt p q -> ~(eqseq p q).
Proof.
rewrite /not. move => p q.
case: p; case: q => //= a A a' A'.
case: (boolP (a' == a)); last first.
- move => ? ?; by rewrite andFb.
- move => a'_eq_a A'_lt_A; rewrite andTb eqseqE; move/eqP => Heq.
move: A'_lt_A; by rewrite Heq lt_not_refl.
Qed.
但是,我正在努力证明以下内容:
Lemma seq_lt_not_gt p q : ~~(seq_lt q p) -> (seq_lt p q) || (eqseq p q).
Proof.
case: p; case: q => // a A a' A'.
case: (boolP (a' < a)) => Haa'.
- rewrite {1}/seq_lt.
suff -> : (a' == a) = false by move/negP => ?.
by apply: ltn_eqF.
- rewrite -leqNgt leq_eqVlt in Haa'.
move/orP: Haa'; case; last first.
+ move => a_lt_a' _; apply/orP; left; rewrite /seq_lt.
have -> : (a == a') = false by apply: ltn_eqF. done.
+ (* What now? *)
Admitted.
我什至不确定最后一个引理是否可以使用归纳法来实现,但我已经研究了几个小时并且不知道从哪里开始。 seq_lt
的定义有问题吗?
我不确定你的归纳问题是什么,但证明似乎很简单:
Local Notation "x < y" := (seq_lt x y).
Lemma seq_lt_not_gt p q : ~~ (q < p) = (p < q) || (p == q).
Proof.
elim: p q => [|x p ihp] [|y q] //=; rewrite [y == x]eq_sym eqseq_cons.
by case: ifP => h_eq; [exact: ihp | rewrite orbF ltnNge leq_eqVlt h_eq negbK].
Qed.
如果你要使用命令,我建议你使用一些扩展 ssreflect 的库来达到这个目的;我似乎记得 Cyril Cohen 在 github 上有过开发。请注意,订单上的引理在 mathcomp 中的形式略有不同(示例 ltn_neqAle
),因此您也可以这样做:
Lemma lts_neqAltN p q : (q < p) = (q != p) && ~~ (p < q).
Proof.
elim: p q => [|x p ihp] [|y q] //=; rewrite eqseq_cons [y == x]eq_sym.
by case: ifP => h_eq; [apply: ihp | rewrite ltnNge leq_eqVlt h_eq].
Qed.
这对于重写可能会更好一些。
p.s:我建议你用这个证明来证明你的第二个引理:
Lemma lt_not_eqseq p q : seq_lt p q -> p != q.
Proof. by apply: contraTneq => heq; rewrite heq lt_not_refl. Qed.
我目前正在 Coq 中研究红黑树,想为 nat
的列表配备一个顺序,以便它们可以使用 [=16] 存储在红黑树中=]模块。
因此,我定义了 seq_lt
,如下所示:
Fixpoint seq_lt (p q : seq nat) := match p, q with
| _, [::] => false
| [::], _ => true
| h :: p', h' :: q' =>
if h == h' then seq_lt p' q'
else (h < h')
end.
到目前为止,我已经展示了:
Lemma lt_not_refl p : seq_lt p p = false.
Proof.
elim: p => //= ? ?; by rewrite eq_refl.
Qed.
以及
Lemma lt_not_eqseq : forall p q, seq_lt p q -> ~(eqseq p q).
Proof.
rewrite /not. move => p q.
case: p; case: q => //= a A a' A'.
case: (boolP (a' == a)); last first.
- move => ? ?; by rewrite andFb.
- move => a'_eq_a A'_lt_A; rewrite andTb eqseqE; move/eqP => Heq.
move: A'_lt_A; by rewrite Heq lt_not_refl.
Qed.
但是,我正在努力证明以下内容:
Lemma seq_lt_not_gt p q : ~~(seq_lt q p) -> (seq_lt p q) || (eqseq p q).
Proof.
case: p; case: q => // a A a' A'.
case: (boolP (a' < a)) => Haa'.
- rewrite {1}/seq_lt.
suff -> : (a' == a) = false by move/negP => ?.
by apply: ltn_eqF.
- rewrite -leqNgt leq_eqVlt in Haa'.
move/orP: Haa'; case; last first.
+ move => a_lt_a' _; apply/orP; left; rewrite /seq_lt.
have -> : (a == a') = false by apply: ltn_eqF. done.
+ (* What now? *)
Admitted.
我什至不确定最后一个引理是否可以使用归纳法来实现,但我已经研究了几个小时并且不知道从哪里开始。 seq_lt
的定义有问题吗?
我不确定你的归纳问题是什么,但证明似乎很简单:
Local Notation "x < y" := (seq_lt x y).
Lemma seq_lt_not_gt p q : ~~ (q < p) = (p < q) || (p == q).
Proof.
elim: p q => [|x p ihp] [|y q] //=; rewrite [y == x]eq_sym eqseq_cons.
by case: ifP => h_eq; [exact: ihp | rewrite orbF ltnNge leq_eqVlt h_eq negbK].
Qed.
如果你要使用命令,我建议你使用一些扩展 ssreflect 的库来达到这个目的;我似乎记得 Cyril Cohen 在 github 上有过开发。请注意,订单上的引理在 mathcomp 中的形式略有不同(示例 ltn_neqAle
),因此您也可以这样做:
Lemma lts_neqAltN p q : (q < p) = (q != p) && ~~ (p < q).
Proof.
elim: p q => [|x p ihp] [|y q] //=; rewrite eqseq_cons [y == x]eq_sym.
by case: ifP => h_eq; [apply: ihp | rewrite ltnNge leq_eqVlt h_eq].
Qed.
这对于重写可能会更好一些。
p.s:我建议你用这个证明来证明你的第二个引理:
Lemma lt_not_eqseq p q : seq_lt p q -> p != q.
Proof. by apply: contraTneq => heq; rewrite heq lt_not_refl. Qed.