COQ-证明非空序列中存在最大元素
作为一种练习,我想证明,在非空序列中始终存在最大元素。
Theorem largest_el_in_list (s: seq rat) x : x \in s -> exists y, y \in s /\ forall z, z \in s -> y >= z.
我的想法是通过归纳对S进行归纳,然后破坏X。在第一种情况下,最大的元素是列表中唯一的元素。但是,在第二种情况下,我感到非常困惑。我应该使用归纳假设吗?我的想法是,我们可以通过存在Max A A1
来摆脱存在性,其中A是我们在上一步中发现的最大元素,而A1是正在添加到序列中的新元素。但是,如果我这样做,那么我将无法使用归纳假设,并且完全卡住了。
我已经呆了几个小时,很想知道我有正确的主意。
编辑: 这是到目前为止的证明,下面有当前的证明状态:
Theorem largest_el_in_list (s: seq rat) x : x \in s -> exists y, y \in s /\ forall z, z \in s -> y >= z.
Proof.
elim/last_ind : s => //= s x0 IH x_in_rcons.
case : s IH x_in_rcons.
move => _ x_in_sx0.
exists x0. split.
rewrite in_cons. apply/orP. left. by apply/eqP.
rewrite in_cons in x_in_sx0. case/orP : x_in_sx0 => //= xeqx0 z z_in_sx0.
rewrite in_cons in z_in_sx0. case/orP : z_in_sx0 => //= zeqx0. case/eqP : zeqx0 => zeqx0.
by rewrite zeqx0.
move => a l IH x_in_rcons.
exists (maxr x0 a). split.
have [agex0 | x0gta] := (lerP x0 a).
by rewrite mem_head.
rewrite rcons_cons in_cons. apply/orP. right. by rewrite in_rcons.
move => z z_in_rcons.
Admitted.
证明状态:
x: rat_eqType
x0, a: rat
l: seq rat
IH: x \in a :: l ->
exists y : rat, y \in a :: l /\ (forall z : rat, z \in a :: l -> z <= y)
x_in_rcons: x \in rcons (a :: l) x0
z: rat
z_in_rcons: z \in rcons (a :: l) x0
-------------------------------
(1/1)
z <= maxr x0 a
另一个编辑:
导入:
From finprob Require Import prob.
From mathcomp Require Import all_ssreflect all_algebra seq.
From extructures Require Import ord fset fmap ffun.
Import Num.Theory.
Import GRing.
Import Bool.
Import Num.Def.
您可以在此处找到挤压 https://github.com/arthuraa/extructures and Finprob在这里 https://github.com/arthuraa/finprob
:
尽管更改定义可以清除路径,但仍然存在问题。这是更新的证明和证明状态:
Theorem largest_el_in_list (s: seq rat) : s != [::] -> exists y, y \in s /\ forall z, z \in s -> y >= z.
Proof.
elim/last_ind : s => //= s x0 IH x_in_rcons.
case : s IH x_in_rcons.
move => _ x_in_sx0.
exists x0. split.
rewrite in_cons. apply/orP. left. by apply/eqP.
move => z z_in_cons.
rewrite in_cons in z_in_cons.
case/orP : z_in_cons => //= zeqx0.
case/eqP : zeqx0 => zeqx0. by rewrite zeqx0.
move => a l IH cons_nempty.
case IH => //= x [x_in_cons IH'].
exists x.
split.
rewrite in_cons in x_in_cons.
rewrite in_cons.
case/orP : x_in_cons => [xeqa | x_in_l].
by rewrite xeqa orTb. apply/orP. right. rewrite in_rcons. apply/orP. by right.
move => z z_in_cons.
apply IH'.
rewrite in_cons. rewrite in_cons in z_in_cons.
case/orP : z_in_cons => [zeqa | z_in_cons].
by rewrite zeqa orTb.
Admitted.
x0, a: rat
l: seq rat
IH: a :: l != [::] ->
exists y : rat, y \in a :: l /\ (forall z : rat, z \in a :: l -> z <= y)
cons_nempty: rcons (a :: l) x0 != [::]
x: rat
x_in_cons: x \in a :: l
IH': forall z : rat, z \in a :: l -> z <= x
z: rat
z_in_cons: z \in rcons l x0
-------------------------
(1/1)
(z == a) || (z \in l)
我看不出这是如何真实的,因为我们从z_in_cons知道z要么等于x0,要么在l中。因此,如果我们通过案例,第一种情况是不可能的,因为我们缺少有关X0的一些信息。
As an exercise I want to prove that there is always exists a maximum element in a non-empty sequence.
Theorem largest_el_in_list (s: seq rat) x : x \in s -> exists y, y \in s /\ forall z, z \in s -> y >= z.
My idea was to go by induction on s, and then to destruct x. The largest element in this first case is the only element in the list. However, in the second case I'm getting quite confused. Am I supposed to use the inductive hypothesis? My idea was that we can get rid of the existential by exists max a a1
, where a is the maximal element we found in the previous step, and a1 is the new element being added to the sequence. But if I do this, then I can't use the inductive hypothesis and I get completely stuck.
I've been stuck for hours and would love to know if I have the right idea.
Edit:
Here is the proof so far, with the current proof state below:
Theorem largest_el_in_list (s: seq rat) x : x \in s -> exists y, y \in s /\ forall z, z \in s -> y >= z.
Proof.
elim/last_ind : s => //= s x0 IH x_in_rcons.
case : s IH x_in_rcons.
move => _ x_in_sx0.
exists x0. split.
rewrite in_cons. apply/orP. left. by apply/eqP.
rewrite in_cons in x_in_sx0. case/orP : x_in_sx0 => //= xeqx0 z z_in_sx0.
rewrite in_cons in z_in_sx0. case/orP : z_in_sx0 => //= zeqx0. case/eqP : zeqx0 => zeqx0.
by rewrite zeqx0.
move => a l IH x_in_rcons.
exists (maxr x0 a). split.
have [agex0 | x0gta] := (lerP x0 a).
by rewrite mem_head.
rewrite rcons_cons in_cons. apply/orP. right. by rewrite in_rcons.
move => z z_in_rcons.
Admitted.
Proof state:
x: rat_eqType
x0, a: rat
l: seq rat
IH: x \in a :: l ->
exists y : rat, y \in a :: l /\ (forall z : rat, z \in a :: l -> z <= y)
x_in_rcons: x \in rcons (a :: l) x0
z: rat
z_in_rcons: z \in rcons (a :: l) x0
-------------------------------
(1/1)
z <= maxr x0 a
ANOTHER EDIT:
Imports:
From finprob Require Import prob.
From mathcomp Require Import all_ssreflect all_algebra seq.
From extructures Require Import ord fset fmap ffun.
Import Num.Theory.
Import GRing.
Import Bool.
Import Num.Def.
You can find extructures here https://github.com/arthuraa/extructures
And finprob here https://github.com/arthuraa/finprob
UPDATE:
Although changing the definition clears the path, there is still an issue. Here is the updated proof and proof state:
Theorem largest_el_in_list (s: seq rat) : s != [::] -> exists y, y \in s /\ forall z, z \in s -> y >= z.
Proof.
elim/last_ind : s => //= s x0 IH x_in_rcons.
case : s IH x_in_rcons.
move => _ x_in_sx0.
exists x0. split.
rewrite in_cons. apply/orP. left. by apply/eqP.
move => z z_in_cons.
rewrite in_cons in z_in_cons.
case/orP : z_in_cons => //= zeqx0.
case/eqP : zeqx0 => zeqx0. by rewrite zeqx0.
move => a l IH cons_nempty.
case IH => //= x [x_in_cons IH'].
exists x.
split.
rewrite in_cons in x_in_cons.
rewrite in_cons.
case/orP : x_in_cons => [xeqa | x_in_l].
by rewrite xeqa orTb. apply/orP. right. rewrite in_rcons. apply/orP. by right.
move => z z_in_cons.
apply IH'.
rewrite in_cons. rewrite in_cons in z_in_cons.
case/orP : z_in_cons => [zeqa | z_in_cons].
by rewrite zeqa orTb.
Admitted.
x0, a: rat
l: seq rat
IH: a :: l != [::] ->
exists y : rat, y \in a :: l /\ (forall z : rat, z \in a :: l -> z <= y)
cons_nempty: rcons (a :: l) x0 != [::]
x: rat
x_in_cons: x \in a :: l
IH': forall z : rat, z \in a :: l -> z <= x
z: rat
z_in_cons: z \in rcons l x0
-------------------------
(1/1)
(z == a) || (z \in l)
I don't see how this can be true, because we know from z_in_cons that z is either equal to x0, or it is in l. Thus, if we go by cases, the first case is impossible because we are lacking some information about x0.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
另一种方法是从一开始就明确提供
y
的值,即您正在寻找的值。这应该是列表的最大值,您可以通过fixpoint
定义来指定自己,或者是COQ中定义的最大值。但是,如果您想在评论中提出的那样,如果您想通过归纳来保留证明,这是一种方法(我想可以更简洁的方式编写它)。我在这里使用
nat
而不是rat
,为方便起见:Another approach would be to explicitly provide, right from the start, a value for
y
, the existence of which you are looking for. This should be the maximum of the list, which you could either specify yourself, via aFixpoint
definition, or be the maximum as defined in Coq.But if you want to keep the proof by induction, as you suggest in your comment, here is one way (I suppose one can write it in a more concise manner). I'm using here
nat
instead ofrat
, for convenience:问题可能来自变量
x
。一个可能的解决方法是拥有
X
普遍量化的,例如,使用移动:X
(在s
上进行启动之前)。另一个解决方案是删除
x
,它在您的语句中仅出现一次,并使子目标难以读取并证明:May be the issue comes from the variable
x
.A possible fix is to have
x
universally quantified, e.g. by starting the proof with amove: x
(before the induction ons
).Another solution would be to remove
x
, which occurs only once in your statement and makes the subgoals hard to read, and prove instead: