Qcert.Basic.Util.RSort



Section RSort.


  Section Strongly.

    Context {A:Type}.
    Context {R:AAProp}.
    Context (R_dec : a a', {R a a'} + {¬R a a'}).

    Fixpoint insertion_sort_insert a l
      := match l with
           | nila :: nil
           | b::xsif (R_dec a b)
                      then a::b::xs
                      else if (R_dec b a) then
                             b::insertion_sort_insert a xs
                           else b::xs
         end.

    Fixpoint insertion_sort (l:list A)
      := match l with
           | nilnil
           | a::xsinsertion_sort_insert a (insertion_sort xs)
         end.

    Lemma insertion_sort_insert_Sorted a (l:list A) :
      Sorted R l Sorted R (insertion_sort_insert a l).

    Lemma insertion_sort_Sorted (l:list A) : Sorted R (insertion_sort l).


    Fixpoint is_list_sorted (l:list A) :=
      match l with
        | niltrue
        | x::xsmatch xs with
                     | niltrue
                     | y::lsif R_dec x y then is_list_sorted xs else false
                   end
      end.

    Lemma is_list_sorted_Sorted_iff l:
      is_list_sorted l = true Sorted R l.


    Lemma is_list_sorted_ext : l (p1 p2:is_list_sorted l = true), p1 = p2.

    Lemma sorted_StronglySorted `{Transitive A R}: l, is_list_sorted l = true StronglySorted R l.

    Lemma Forall_nin_irr `{Irreflexive A R}: a l, Forall (R a) l ¬ In a l.

    Lemma StronglySorted_NoDup `{Irreflexive A R}:
       l, StronglySorted R l NoDup l.

    Lemma Sorted_NoDup `{StrictOrder A R}:
       l, Sorted R l NoDup l.

    Lemma is_list_sorted_NoDup `{StrictOrder A R} :
       l, is_list_sorted l = true NoDup l.

    Lemma is_list_sorted_cons a r :
      is_list_sorted (a::r) = true
      
      (is_list_sorted r = true
        match r with
            | nilTrue
            | y::_R a y
          end).

    Lemma is_list_sorted_cons_inv {a r} :
      is_list_sorted (a::r) = true
      is_list_sorted r = true.

    Lemma StronglySorted_cons_in {x a l} :
      StronglySorted R (a::l)
      In x l
      R a x.

  Lemma insertion_sort_sorted_is_id l :
    is_list_sorted l = true
    insertion_sort l = l.

  Lemma insertion_sort_idempotent l :
    insertion_sort (insertion_sort l) =
    insertion_sort l.

  Lemma insertion_sort_insert_not_nil a l :
    insertion_sort_insert a l nil.

  Lemma insertion_sort_nil l :
    insertion_sort l = nil l = nil.

 Lemma insertion_sort_insert_swap a a0 l `{StrictOrder A R}:
   R a a0
   insertion_sort_insert a (insertion_sort_insert a0 l) =
   insertion_sort_insert a0 (insertion_sort_insert a l).

  End Strongly.

  Section In.
    Lemma StronglySorted_filter {A} {R} f {l} :
      @StronglySorted A R l StronglySorted R (filter f l).

    Lemma in_insertion_sort_insert {A R R_dec} {x l a} :
      In x (@insertion_sort_insert A R R_dec a l) a = x In x l.

    Lemma in_insertion_sort {A R R_dec} {x l} :
      In x (@insertion_sort A R R_dec l) In x l.

    Lemma insertion_sort_insert_in_strong {A R R_dec} {x l a}
          (contr:asymmetric_over R (a::l)) :
      a = x In x l In x (@insertion_sort_insert A R R_dec a l).

    Lemma insertion_sort_insert_in {A R R_dec} {x l a}
          (contr: x y, ¬R x y ¬R y x x = y) :
      a = x In x l In x (@insertion_sort_insert A R R_dec a l).

    Lemma insertion_sort_in_strong {A R R_dec} {x l}
          (contr:asymmetric_over R l) :
      In x l In x (@insertion_sort A R R_dec l).


    Lemma insertion_sort_in {A R R_dec} {x l}
          (contr: x y, ¬R x y ¬R y x x = y) :
      In x l In x (@insertion_sort A R R_dec l).

    Lemma equivlist_insertion_sort_strong {A R} R_dec {l l'}
          (contr:asymmetric_over R l) :
      equivlist l l'
      equivlist (@insertion_sort A R R_dec l) (@insertion_sort A R R_dec l').

    Lemma equivlist_insertion_sort {A R} R_dec {l l'}
          (contr: x y, ¬R x y ¬R y x x = y) :
      equivlist l l'
      equivlist (@insertion_sort A R R_dec l) (@insertion_sort A R R_dec l').

      Lemma insertion_sort_insert_insertion_nin {A:Type} lt dec
        `{StrictOrder A lt}
        (trich: a b, {lt a b} + {eq a b} + {lt b a})
        (a:A) a0 l :
   ¬ lt a0 a
   ¬ lt a a0
   insertion_sort_insert dec a0
     (insertion_sort_insert dec a l)
   = @insertion_sort_insert A lt dec a l.

 Lemma insertion_sort_insert_cons_app {A:Type} lt dec
        `{StrictOrder A lt}
        (trich: a b, {lt a b} + {eq a b} + {lt b a}) a l l2 :
    insertion_sort dec (insertion_sort_insert dec a l ++ l2) = @insertion_sort A lt dec (a::l ++ l2).

 Lemma insertion_sort_insertion_sort_app1 {A} lt dec `{StrictOrder A lt}
        (trich: a b, {lt a b} + {eq a b} + {lt b a}) l1 l2 :
    insertion_sort dec (insertion_sort dec l1 ++ l2) =
    @insertion_sort A lt dec (l1 ++ l2).


    Lemma insertion_sort_trich_equiv {A:Type} lt dec
        (trich: a b, {lt a b} + {eq a b} + {lt b a}) (l:list A)
  : equivlist (@insertion_sort A lt dec l) l.

   Lemma insertion_sort_insert_forall_lt
   {A:Type} lt dec (a:A) (l:list A) :
     Forall (lt a) l
     @insertion_sort_insert A lt dec a l = a :: l.

   Lemma sort_insert_filter_true {A:Type} f lt dec `{StrictOrder A lt}
         (trich: a b, {lt a b} + {eq a b} + {lt b a})
         (a:A) (l:list A) :
     StronglySorted lt l
     f a = true
         filter f (@insertion_sort_insert A lt dec a l)
     = insertion_sort_insert dec a (filter f l).

   Lemma sort_insert_filter_false {A:Type} f lt dec (a:A) (l:list A) :
     f a = false
     filter f (@insertion_sort_insert A lt dec a l) =
     filter f l.

   Lemma sort_filter_commute {A:Type} f lt dec
         `{StrictOrder A lt}
         (trich: a b, {lt a b} + {eq a b} + {lt b a})
         (l:list A) :
     filter f (@insertion_sort A lt dec l)
     = insertion_sort dec (filter f l).

   Lemma Forall_insertion_sort {A R R_dec} {P} l :
     Forall P l Forall P (@insertion_sort A R R_dec l).

  End In.

  Section map.

  Lemma map_insertion_sort_insert {A B}
        {R1 R2}
        (R1_dec : a a' : A, {R1 a a'} + {¬ R1 a a'})
        (R2_dec : b b' : B, {R2 b b'} + {¬ R2 b b'})
        (f:AB)
    (consistent: x y, R1 x y
                                R2 (f x) (f y)) a l :
    map f (insertion_sort_insert R1_dec a l) =
    insertion_sort_insert R2_dec (f a) (map f l).

  Lemma map_insertion_sort {A B}
        {R1 R2}
        (R1_dec : a a' : A, {R1 a a'} + {¬ R1 a a'})
        (R2_dec : b b' : B, {R2 b b'} + {¬ R2 b b'})
        (f:AB)
    (consistent: x y, R1 x y
                                R2 (f x) (f y)) l :
    map f (insertion_sort R1_dec l) =
    insertion_sort R2_dec (map f l).

  End map.

End RSort.