最小的非空有限集

时间:2018-05-21 09:42:17

标签: coq minimum

通过以下定义,我想证明引理without_P

Variable n : nat.
Definition mnnat := {m : nat | m < n}.
Variable f : mnnat -> nat.

Lemma without_P : (exists x : mnnat, True) -> (exists x, forall y, f x <= f y).

引理without_P表示:如果你知道(有限的)集合mnnat不是空的,那么mnnat中必须存在一个元素,它是所有元素中最小的元素。将f映射到mnnat 我们知道mnnat是有限的,因为其中有n-1个数字,并且在without_P的证明的上下文中,我们也知道mnnat不是空的,因为前提是(exists x : mnnat, True)
现在mnnat非空,有限的“自然/直觉”具有一些最小元素(在对其所有元素应用f之后)。

目前我被困在下面这一点,我想在n上进行归纳,这是不允许的。

1 subgoal  
n : nat  
f : mnnat -> nat  
x : nat  
H' : x < n  
______________________________________(1/1)  

exists (y : nat) (H0 : y < n),
  forall (y0 : nat) (H1 : y0 < n),
  f (exist (fun m : nat => m < n) y H0) <= f (exist (fun m : nat => m < n) y0 H1)

我唯一的想法是断言这样的函数f' : nat -> nat的存在:exists (f' : nat -> nat), forall (x : nat) (H0: x < n), f' (exist (fun m : nat => m < n) x H0) = f x,在解决了这个断言之后,我通过n的归纳证明了这个引理。 如何证明这一断言?

有没有办法证明“非空的,有限的集合(在对每个元素应用f之后”有一个最小的“更直接?我的当前路径对我来说似乎太难了COQ技能。

3 个答案:

答案 0 :(得分:3)

Require Import Psatz Arith.  (* use lia to solve the linear integer arithmetic. *)

Variable f : nat -> nat.

这下面基本上是你的目标,将语句模块打包成某种依赖类型。 (它并不是说mi&lt; n,但你可以扩展证明声明也包含它。)

Goal forall n, exists mi, forall i, i < n -> f mi <= f i.

  induction n; intros.
  - now exists 0; inversion 1. (* n cant be zero *)
  - destruct IHn as [mi IHn].  (* get the smallest pos mi, which is < n *)
    (* Is f mi still smallest, or is f n the smallest? *)    
    (* If f mi < f n then mi is the position of the 
       smallest value, otherwise n is that position,
       so consider those two cases. *)
    destruct (lt_dec (f mi) (f n));
      [ exists mi |  exists n];
      intros.

    + destruct (eq_nat_dec i n).
      subst; lia.
      apply IHn; lia.

    + destruct (eq_nat_dec i n).
      subst; lia.
      apply le_trans with(f mi).
      lia.
      apply IHn.
      lia.
Qed.

答案 1 :(得分:3)

您的问题是更一般结果的特定实例,例如在math-comp中已经证实。在那里,你甚至有一个表示“最小x使它符合P”的符号,其中P必须是一个可判定的谓词。

如果没有过多地调整你的陈述,我们会得到:

From mathcomp Require Import all_ssreflect.

Variable n : nat.
Variable f : 'I_n.+1 -> nat.

Lemma without_P : exists x, forall y, f x <= f y.
Proof.
have/(_ ord0)[] := arg_minP (P:=xpredT) f erefl => i _ P.
by exists i => ?; apply/P.
Qed.

答案 2 :(得分:0)

我通过使用引理(exists (f' : nat -> nat), forall (x : nat) (H0: x < n), f (exist (fun m : nat => m < n) x H0) = f' x).证明类似的断言(exists (f' : nat -> nat), forall x : mnnat, f x = f' (proj1_sig x)).,找到了我的断言f'exists的证明。然后,第一个断言几乎是微不足道的 在我证明了这个断言后,我可以对用户larsr做类似的证明,以证明Lemma without_P

除了mod的基本情况之外,我使用nat - 函数将任何nat转换为n小于n = 0

Lemma mod_mnnat : forall m,
  n > 0 -> m mod n < n.
Proof.
  intros.
  apply PeanoNat.Nat.mod_upper_bound.
  intuition.
Qed.

Lemma mod_mnnat' : forall m,
  m < n -> m mod n = m.
Proof.
  intros.
  apply PeanoNat.Nat.mod_small.
  auto.
Qed.

Lemma f_proj1_sig : forall x y,
  proj1_sig x = proj1_sig y -> f x = f y.
Proof.
  intros.
  rewrite (sig_eta x).
  rewrite (sig_eta y).
  destruct x. destruct y as [y H0].
  simpl in *.
  subst.
  assert (l = H0).
  apply proof_irrelevance. (* This was tricky to find. 
    It means two proofs of the same thing are equal themselves. 
    This makes (exist a b c) (exist a b d) equal, 
    if c and d prove the same thing. *)
  subst.
  intuition.
Qed.


(* Main Lemma *)
Lemma f'exists :
  exists (ff : nat -> nat), forall x : mnnat, f x = ff (proj1_sig x).
Proof.
  assert (n = 0 \/ n > 0).
  induction n.
  auto.
  intuition.
  destruct H.
  exists (fun m : nat => m).
  intuition. destruct x. assert (l' := l). rewrite H in l'. inversion l'.
  unfold mnnat in *.

  (* I am using the mod-function to map (m : nat) -> {m | m < n} *)
  exists (fun m : nat => f (exist (ltn n) (m mod n) (mod_mnnat m H))).
  intros.
  destruct x.
  simpl.
  unfold ltn.
  assert (l' := l).
  apply mod_mnnat' in l'.

  assert (proj1_sig (exist (fun m : nat => m < n) x l) = proj1_sig (exist (fun m : nat => m < n) (x mod n) (mod_mnnat x H))).
  simpl. rewrite l'.
  auto.
  apply f_proj1_sig in H0.
  auto.
Qed.