(* ========================================================================= *)
(* Quick sort algorithm. *)
(* *)
(* Author: Marco Maggesi *)
(* University of Florence, Italy *)
(* http://www.math.unifi.it/~maggesi/ *)
(* *)
(* (c) Copyright, Marco Maggesi, 2005-2007 *)
(* ========================================================================= *)
needs "Permutation/permuted.ml";;
(* ------------------------------------------------------------------------- *)
(* Ordered lists. *)
(* ------------------------------------------------------------------------- *)
let ORDERED_RULES, ORDERED_INDUCT, ORDERED_CASES = new_inductive_definition
`(!le. ORDERED le []) /\
(!le h t. ORDERED le t /\ ALL (le h) t ==> ORDERED le (CONS h t))`;;
let ORDERED_CONS = prove
(`!le (h:A) t. ORDERED le (h :: t) <=> (ORDERED le t /\
ALL (le h) t)`,
SUBGOAL_THEN
`!le (h:A) t. ORDERED le (h :: t) ==> (ORDERED le t /\
ALL (le h) t)`
(fun th -> MESON_TAC [th; ORDERED_RULES]) THEN
REPEAT GEN_TAC THEN
DISCH_THEN (MP_TAC o ONCE_REWRITE_RULE [ORDERED_CASES]) THEN
REWRITE_TAC [
NOT_CONS_NIL;
CONS_11] THEN MESON_TAC []);;
let ORDERED_APPEND = prove
(`!l1 l2:A list.
ORDERED le (
APPEND l1 l2) <=>
ORDERED le l1 /\ ORDERED le l2 /\
ALL (\x.
ALL (le x) l2) l1`,
SUBGOAL_THEN
`(!l1 l2:A list.
ORDERED le (
APPEND l1 l2)
==> ORDERED le l1 /\ ORDERED le l2 /\
ALL (\x.
ALL (le x) l2) l1) /\
(!l1 l2. ORDERED le l1 /\ ORDERED le l2 /\
ALL (\x.
ALL (le x) l2) l1
==> ORDERED le (
APPEND l1 l2))`
(fun th -> MESON_TAC [th]) THEN
CONJ_TAC THEN LIST_INDUCT_TAC THEN
REWRITE_TAC [
APPEND;
ALL; ORDERED_RULES;
ORDERED_CONS] THEN
ASM_SIMP_TAC [
ORDERED_CONS;
ALL_APPEND] THEN ASM_MESON_TAC [
ALL_APPEND]);;
(* ------------------------------------------------------------------------- *)
(* Quick Sort. *)
(* ------------------------------------------------------------------------- *)
let QSORT =
let PROVE_RECURSIVE_FUNCTION_EXISTS_TAC : tactic = fun g ->
let th = pure_prove_recursive_function_exists (snd g) in
MATCH_MP_TAC (DISCH_ALL th) g in
new_specification ["QSORT"] (prove
(`?f. (!le. f le [] = [] : A list) /\
(!le h t. f le (CONS h t) =
APPEND (f le (FILTER (\x. ~le h x) t))
(CONS h (f le (FILTER (\x. le h x) t))))`,
REWRITE_TAC [GSYM SKOLEM_THM; AND_FORALL_THM] THEN GEN_TAC THEN
PROVE_RECURSIVE_FUNCTION_EXISTS_TAC THEN
EXISTS_TAC `MEASURE (LENGTH:A list -> num)` THEN
REWRITE_TAC [WF_MEASURE; MEASURE; LENGTH; FILTER] THEN
REWRITE_TAC [LT_SUC_LE; LENGTH_FILTER_LE]));;
let ORDERED_QSORT = prove
(`!le (l:A list).
(!x y. le x y \/ le y x) /\ (!x y z. le x y \/ le y z ==> le x z)
==> ORDERED le (QSORT le l)`,
(* Example:
REWRITE_CONV [QSORT; ARITH_LE; ARITH_LT; FILTER; APPEND]
`QSORT (<=) [12;3;5;1;23;2;1]`;;
*)