Coq战术来排序列表?

时间:2018-11-14 23:08:01

标签: coq coq-tactic

为证明起见,我想使用以下事实:对于任何整数列表,都存在该列表的排序版本。这对我来说似乎很明显,但是我找不到一种能做类似事情的战术。我试图创建自己的(下),但是我陷入了困境,所以也许这个事实并不像我想象的那么明显(或者甚至不是真的?)

Definition sorted := (StronglySorted (λ x y, x ≤ y)).
Lemma exists_sorted:  ∀ (L : list Z) (a : Z), ∃ L0 : list Z, sorted L0 ∧ (List.In a L ⇔ List.In a L0).
Proof.
  induction L.
  - intros.
    exists nil.
    split.
    + apply SSorted_nil.
    + tauto.
  - intros.
    pose proof (IHL a).
    destruct H as [L0 [H H0]].

从那里开始,我的想法似乎有点循环。有什么建议吗?

2 个答案:

答案 0 :(得分:3)

摘要:

Require Import Orders Sorting ZArith.

Module ZOrder <: TotalLeBool.
Definition t := Z.
Definition leb := Z.leb.
Lemma leb_total : forall x y : t, leb x y = true \/ leb y x = true.
Proof.
intros x y; case (Zle_bool_total x y); auto.
Qed.

End ZOrder.

Module ZSort := Sort ZOrder.

Lemma Transitive_Zle_bool : Transitive (fun x y => is_true (x <=? y)%Z).
Proof.
intros x y z; unfold is_true; rewrite <- 3!Zle_is_le_bool; apply Z.le_trans.
Qed.

Lemma exists_sorted:  forall (L : list Z), exists L0 : list Z, 
 StronglySorted (fun x y => is_true (x <=? y)%Z) L0 /\ 
 (forall a: Z, List.In a L <-> List.In a L0).
Proof.
intros l; exists (ZSort.sort l).
split;[apply ZSort.StronglySorted_sort; apply Transitive_Zle_bool | ].
intros a; split; apply Permutation.Permutation_in.
  apply ZSort.Permuted_sort.
apply Permutation.Permutation_sym; apply ZSort.Permuted_sort.
Qed.

这是浏览Coq库的问题。我不知道您是怎么想到StronglySorted这个概念的,但是确实存在于Coq系统随附的库中。

如果仅输入以下内容

Require Import Sorted ZArith.

然后,您仅获得定义要对列表进行排序的含义的定义,而不是排序功能的定义。您看到这是因为命令

Search StronglySorted.

仅返回六个定理,这些定理主要与StronglySortedSorted之间的关系以及StronglySorted的归纳原理相关。

通过在Coq分布的来源上使用git grep,我发现在两个库中使用了概念StronglySorted,第二个库被命名为Mergesort。啊哈! merge sort 是算法的名称,因此它可能会构建一个排序列表 为我们。现在两个Mergesort Sorted都包含在Sorting中,这就是我们 将使用。

Require Import Sorting ZArith.

现在,如果我输入Search StronglySorted.,我会看到结果中添加了一个新定理,名称为NatSort.StronglySorted_sort。情节变厚。这个定理的陈述很长,但它基本上表示如果由函数Nat.leb计算的关系是可传递的,则函数NatSort.sort确实返回一个排序列表。

好吧,我们不希望对自然数进行排序,而希望对Z类型的整数进行排序。但是,如果您研究文件Mergesort.v,则会发现NatSort是在描述自然数比较函数的结构上 functor 的实例化,并且证明了这种比较是 total 在某种意义上。因此,我们只需要为整数创建相同类型的结构即可。

请注意,我为引理exists_sorted证明的陈述与您所使用的陈述不同。重要的修改是,存在性陈述和通用量化的顺序不同。使用您的陈述,可以通过仅提供包含a的列表来证明该陈述,具体取决于a是否在L中。

现在,这只是部分令人满意的答案,因为StronglySorted (fun x y => (x <=? y)%Z)与您的sorted不同。这向我们表明,当StronglySorted R1 <-> StronglySorted R2R1相等时,表示R2的库中缺少引理。

补码:要使语句在StronglySorted中具有正确的关系,您将需要接近以下证明的内容。我认为模块StronglySorted_impl中也应提供引理Sorted

Lemma StronglySorted_impl {A : Type} (R1 R2 : A -> A -> Prop) (l : list A) :
  (forall x y, List.In x l -> List.In y l -> R1 x y -> R2 x y) ->
  StronglySorted R1 l -> StronglySorted R2 l.
Proof.
intros imp sl; revert imp; induction sl as [ | a l sl IHsl Fl];
  intros imp; constructor.
  now apply IHsl; intros x y xin yin; apply imp; simpl; right.
clear IHsl sl; revert imp; induction Fl; auto.
constructor;[now apply imp; simpl; auto | ].
apply IHFl.
intros y z yin zin; apply imp; simpl in yin, zin.
  now destruct yin as [ ya | yin]; simpl; auto.
now destruct zin as [za | zin]; simpl; auto.
Qed.

Lemma exists_sorted':  forall (L : list Z), exists L0 : list Z, 
 StronglySorted (fun x y => (x <= y)%Z) L0 /\ 
 (forall a: Z, List.In a L <-> List.In a L0).
Proof.
intros L; destruct (exists_sorted L) as [L' [sl permP]].
exists L'; split; [ | exact permP].
apply (StronglySorted_impl (fun x y => is_true (x <=? y)%Z)); auto.
now intros x y _ _; apply Zle_bool_imp_le.
Qed.

答案 1 :(得分:2)

实际上,如果您允许Z为任意类型,那么在构造类型理论中选择顺序并不是那么简单。我建议您看一下西里尔·科恩(及其他)finmap library,尤其是给定类型为T且具有选择原则和可判定相等性的类型时,它确实可以满足您的要求,也就是说得出T的任何列表的规范排序。

特别是,请参阅排序功能here

Definition f (s : seq K) := choose (perm_eq (undup s)) (undup s).

其中

choose : forall T : choiceType, pred T -> T -> T

是选择原则,undup删除重复项,perm_eq相等直到排列。

编辑对于类型已经具有相等关系的情况,只要您具有排序功能及其理论,证明就应该是微不足道的。示例:

From mathcomp Require Import all_ssreflect all_algebra.

Open Scope ring_scope.
Import Num.Theory.

Lemma exists_sorted (N : realDomainType) (l : seq N) :
  exists l_sorted, sorted <=%R l_sorted /\ perm_eq l_sorted l.
Proof.
exists (sort <=%R l).
by split; [apply: (sort_sorted (@ler_total _))|apply/perm_eqlP/perm_sort].
Qed.

Definition exists_sorted_int := exists_sorted [realDomainType of int].

实际上,整个定理是多余的,因为您对原始理论有更好的了解。