(* ========================================================================= *)
(* 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_TRS_TAC tm : tactic =
MATCH_MP_TAC PERMUTED_TRS THEN EXISTS_TAC tm THEN CONJ_TAC ;;
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[]);;