2013-05-18 46 views
1

我有一個字符串排序函數定義如下,並想在下面證明一個引理 sort_str_list_same。我不是Coq專家,我試圖用歸納解決它,但無法解決它。請幫我解決它。謝謝,Coq字符串排序引理

Require Import Ascii. 
Require Import String. 

Notation "x :: l" := (cons x l) (at level 60, right associativity). 
Notation "[ ]" := nil. 
Notation "[ x , .. , y ]" := (cons x .. (cons y nil) ..). 

Fixpoint ble_nat (n m : nat) : bool := 
    match n with 
    | O => true 
    | S n' => 
     match m with 
     | O => false 
     | S m' => ble_nat n' m' 
     end 
    end. 

Definition ascii_eqb (a a': ascii) : bool := 
if ascii_dec a a' then true else false. 

(** true if s1 <= s2; s1 is before/same as s2 in alphabetical order *) 
Fixpoint str_le_gt_dec (s1 s2 : String.string) 
: bool := 
match s1, s2 with 
| EmptyString, EmptyString => true 
| String a b, String a' b' => 
     if ascii_eqb a a' then str_le_gt_dec b b' 
     else if ble_nat (nat_of_ascii a) (nat_of_ascii a') 
     then true else false 
| String a b, _ => false 
| _, String a' b' => true 
end. 

Fixpoint aux (s: String.string) (ls: list String.string) 
: list String.string := 
match ls with 
| nil => s :: nil 
| a :: l' => if str_le_gt_dec s a 
       then s :: a :: l' 
       else a :: (aux s l') 
end. 

Fixpoint sort (ls: list String.string) : list String.string := 
match ls with 
| nil => nil 
| a :: tl => aux a (sort tl) 
end. 

Notation "s1 +s+ s2" := (String.append s1 s2) (at level 60, right associativity) : string_scope. 

Lemma sort_str_list_same: forall z1 z2 zm, 
sort (z1 :: z2 :: zm) = 
sort (z2 :: z1 :: zm). 
Proof with o. 
Admitted. 

回答

3

您的引理相當於forall z1 z2 zm, aux z1 (aux z2 zm) = aux z2 (aux z1 zm)。對於具有順序關係的任意類型,以下說明如何證明類似的定理。要在你的情況下使用它,你只需要證明給定的假設。請注意,Coq標準庫defines有一些排序功能並證明了它們的引用,所以你可以在不需要證明太多東西的情況下解決你的問題。

Require Import Coq.Lists.List. 

Section sort. 

Variable A : Type. 

Variable comp : A -> A -> bool. 

Hypothesis comp_trans : 
    forall a b c, comp a b = true -> 
       comp b c = true -> 
       comp a c = true. 

Hypothesis comp_antisym : 
    forall a b, comp a b = true -> 
       comp b a = true -> 
       a = b. 

Hypothesis comp_total : 
    forall a b, comp a b = true \/ comp b a = true. 

Fixpoint insert (a : A) (l : list A) : list A := 
    match l with 
    | nil => a :: nil 
    | a' :: l' => if comp a a' then a :: a' :: l' 
        else a' :: insert a l' 
    end. 

Lemma l1 : forall a1 a2 l, insert a1 (insert a2 l) = insert a2 (insert a1 l). 
Proof. 
    intros a1 a2 l. 
    induction l as [|a l IH]; simpl. 
    - destruct (comp a1 a2) eqn:E1. 
    + destruct (comp a2 a1) eqn:E2; trivial. 
     rewrite (comp_antisym _ _ E1 E2). trivial. 
    + destruct (comp a2 a1) eqn:E2; trivial. 
     destruct (comp_total a1 a2); congruence. 
    - destruct (comp a2 a) eqn:E1; simpl; 
    destruct (comp a1 a) eqn:E2; simpl; 
    destruct (comp a1 a2) eqn:E3; simpl; 
    destruct (comp a2 a1) eqn:E4; simpl; 
    try rewrite E1; trivial; 
    try solve [rewrite (comp_antisym _ _ E3 E4) in *; congruence]; 
    try solve [destruct (comp_total a1 a2); congruence]. 
    + assert (H := comp_trans _ _ _ E3 E1). congruence. 
    + assert (H := comp_trans _ _ _ E4 E2). congruence. 
Qed. 

Section sort.