(* ========================================================================= *)
(*  Permuted lists.                                                          *)
(*                                                                           *)
(*  Author: Marco Maggesi                                                    *)
(*          University of Florence, Italy                                    *)
(*          http://www.math.unifi.it/~maggesi/                               *)
(*                                                                           *)
(*          (c) Copyright, Marco Maggesi, 2005-2007                          *)
(* ========================================================================= *)
needs "Permutation/morelist.ml";;
parse_as_infix("PERMUTED",(12,"right"));;
(* ------------------------------------------------------------------------- *)
(*  Permuted lists.                                                          *)
(* ------------------------------------------------------------------------- *)
let PERMUTED_RULES, PERMUTED_INDUCT, PERMUTED_CASES =
  new_inductive_definition
  `[] PERMUTED [] /\
   (!h t1 t2. t1 PERMUTED t2 ==> h :: t1 PERMUTED h :: t2) /\
   (!l1 l2 l3. l1 PERMUTED l2 /\ l2 PERMUTED l3 ==> l1 PERMUTED l3) /\
   (!x y t. x :: y :: t PERMUTED y :: x :: t)`;;
let PERMUTED_INDUCT_STRONG =
  derive_strong_induction(PERMUTED_RULES,PERMUTED_INDUCT);;
let PERMUTED_SYM = prove
  (`!(xs:A list) l2. xs PERMUTED l2 <=> l2 PERMUTED xs`,
   SUFFICE_TAC []
     `!(xs:A list) l2. xs PERMUTED l2 ==> l2 PERMUTED xs` THEN
   MATCH_MP_TAC PERMUTED_INDUCT THEN ASM_MESON_TAC [PERMUTED_RULES]);;
 
let PERMUTED_TRS = prove
  (`!xs l2 l3. xs PERMUTED l2 /\ l2 PERMUTED l3 ==> xs PERMUTED l3`,
   MESON_TAC [PERMUTED_RULES]);;
 
let PERMUTED_MAP = prove
  (`!f l1 l2. l1 PERMUTED l2 ==>  
MAP f l1 PERMUTED 
MAP f l2`,
   GEN_TAC THEN MATCH_MP_TAC PERMUTED_INDUCT THEN
   REWRITE_TAC [
MAP; PERMUTED_RULES]);;
 
let PERMUTED_MEM = prove
  (`!(a:A) l1 l2. l1 PERMUTED l2 ==> (
MEM a l1 <=> 
MEM a l2)`,
   GEN_TAC THEN MATCH_MP_TAC PERMUTED_INDUCT THEN
   REWRITE_TAC [
MEM] THEN REPEAT STRIP_TAC THEN
   ASM_REWRITE_TAC[] THEN MESON_TAC[]);;
 
let PERMUTED_ALL = prove
  (`!P xs ys. xs PERMUTED ys ==> (
ALL P xs <=> 
ALL P ys)`,
   GEN_TAC THEN MATCH_MP_TAC PERMUTED_INDUCT THEN
   REWRITE_TAC [
ALL] THEN REPEAT STRIP_TAC THEN
   ASM_SIMP_TAC[] THEN MESON_TAC[]);;