2013-05-18 2 views
1

아래에 정의 된 문자열 정렬 함수가 있으며 아래 보조제 sort_str_list_same을 증명하려고합니다. 나는 전문가가 아니기 때문에 유도를 사용하여 그것을 풀려고했지만 그것을 풀 수는 없었다. 제발 도와주세요. 감사합니다.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.