src/HOL/Library/Permutations.thy
changeset 39198 f967a16dfcdd
parent 36361 1debc8e29f6a
child 39302 d7728f65b353
equal deleted inserted replaced
39166:19efc2af3e6c 39198:f967a16dfcdd
    14 (* ------------------------------------------------------------------------- *)
    14 (* ------------------------------------------------------------------------- *)
    15 (* Transpositions.                                                           *)
    15 (* Transpositions.                                                           *)
    16 (* ------------------------------------------------------------------------- *)
    16 (* ------------------------------------------------------------------------- *)
    17 
    17 
    18 lemma swapid_sym: "Fun.swap a b id = Fun.swap b a id"
    18 lemma swapid_sym: "Fun.swap a b id = Fun.swap b a id"
    19   by (auto simp add: expand_fun_eq swap_def fun_upd_def)
    19   by (auto simp add: ext_iff swap_def fun_upd_def)
    20 lemma swap_id_refl: "Fun.swap a a id = id" by simp
    20 lemma swap_id_refl: "Fun.swap a a id = id" by simp
    21 lemma swap_id_sym: "Fun.swap a b id = Fun.swap b a id"
    21 lemma swap_id_sym: "Fun.swap a b id = Fun.swap b a id"
    22   by (rule ext, simp add: swap_def)
    22   by (rule ext, simp add: swap_def)
    23 lemma swap_id_idempotent[simp]: "Fun.swap a b id o Fun.swap a b id = id"
    23 lemma swap_id_idempotent[simp]: "Fun.swap a b id o Fun.swap a b id = id"
    24   by (rule ext, auto simp add: swap_def)
    24   by (rule ext, auto simp add: swap_def)
    25 
    25 
    26 lemma inv_unique_comp: assumes fg: "f o g = id" and gf: "g o f = id"
    26 lemma inv_unique_comp: assumes fg: "f o g = id" and gf: "g o f = id"
    27   shows "inv f = g"
    27   shows "inv f = g"
    28   using fg gf inv_equality[of g f] by (auto simp add: expand_fun_eq)
    28   using fg gf inv_equality[of g f] by (auto simp add: ext_iff)
    29 
    29 
    30 lemma inverse_swap_id: "inv (Fun.swap a b id) = Fun.swap a b id"
    30 lemma inverse_swap_id: "inv (Fun.swap a b id) = Fun.swap a b id"
    31   by (rule inv_unique_comp, simp_all)
    31   by (rule inv_unique_comp, simp_all)
    32 
    32 
    33 lemma swap_id_eq: "Fun.swap a b id x = (if x = a then b else if x = b then a else x)"
    33 lemma swap_id_eq: "Fun.swap a b id x = (if x = a then b else if x = b then a else x)"
    65 lemma permutes_inverses:
    65 lemma permutes_inverses:
    66   fixes p :: "'a \<Rightarrow> 'a"
    66   fixes p :: "'a \<Rightarrow> 'a"
    67   assumes pS: "p permutes S"
    67   assumes pS: "p permutes S"
    68   shows "p (inv p x) = x"
    68   shows "p (inv p x) = x"
    69   and "inv p (p x) = x"
    69   and "inv p (p x) = x"
    70   using permutes_inv_o[OF pS, unfolded expand_fun_eq o_def] by auto
    70   using permutes_inv_o[OF pS, unfolded ext_iff o_def] by auto
    71 
    71 
    72 lemma permutes_subset: "p permutes S \<Longrightarrow> S \<subseteq> T ==> p permutes T"
    72 lemma permutes_subset: "p permutes S \<Longrightarrow> S \<subseteq> T ==> p permutes T"
    73   unfolding permutes_def by blast
    73   unfolding permutes_def by blast
    74 
    74 
    75 lemma permutes_empty[simp]: "p permutes {} \<longleftrightarrow> p = id"
    75 lemma permutes_empty[simp]: "p permutes {} \<longleftrightarrow> p = id"
    76   unfolding expand_fun_eq permutes_def apply simp by metis
    76   unfolding ext_iff permutes_def apply simp by metis
    77 
    77 
    78 lemma permutes_sing[simp]: "p permutes {a} \<longleftrightarrow> p = id"
    78 lemma permutes_sing[simp]: "p permutes {a} \<longleftrightarrow> p = id"
    79   unfolding expand_fun_eq permutes_def apply simp by metis
    79   unfolding ext_iff permutes_def apply simp by metis
    80 
    80 
    81 lemma permutes_univ: "p permutes UNIV \<longleftrightarrow> (\<forall>y. \<exists>!x. p x = y)"
    81 lemma permutes_univ: "p permutes UNIV \<longleftrightarrow> (\<forall>y. \<exists>!x. p x = y)"
    82   unfolding permutes_def by simp
    82   unfolding permutes_def by simp
    83 
    83 
    84 lemma permutes_inv_eq: "p permutes S ==> inv p y = x \<longleftrightarrow> p x = y"
    84 lemma permutes_inv_eq: "p permutes S ==> inv p y = x \<longleftrightarrow> p x = y"
   109 
   109 
   110 lemma permutes_inv: assumes pS: "p permutes S" shows "inv p permutes S"
   110 lemma permutes_inv: assumes pS: "p permutes S" shows "inv p permutes S"
   111   using pS unfolding permutes_def permutes_inv_eq[OF pS] by metis
   111   using pS unfolding permutes_def permutes_inv_eq[OF pS] by metis
   112 
   112 
   113 lemma permutes_inv_inv: assumes pS: "p permutes S" shows "inv (inv p) = p"
   113 lemma permutes_inv_inv: assumes pS: "p permutes S" shows "inv (inv p) = p"
   114   unfolding expand_fun_eq permutes_inv_eq[OF pS] permutes_inv_eq[OF permutes_inv[OF pS]]
   114   unfolding ext_iff permutes_inv_eq[OF pS] permutes_inv_eq[OF permutes_inv[OF pS]]
   115   by blast
   115   by blast
   116 
   116 
   117 (* ------------------------------------------------------------------------- *)
   117 (* ------------------------------------------------------------------------- *)
   118 (* The number of permutations on a finite set.                               *)
   118 (* The number of permutations on a finite set.                               *)
   119 (* ------------------------------------------------------------------------- *)
   119 (* ------------------------------------------------------------------------- *)
   134 
   134 
   135   {fix p
   135   {fix p
   136     {assume pS: "p permutes insert a S"
   136     {assume pS: "p permutes insert a S"
   137       let ?b = "p a"
   137       let ?b = "p a"
   138       let ?q = "Fun.swap a (p a) id o p"
   138       let ?q = "Fun.swap a (p a) id o p"
   139       have th0: "p = Fun.swap a ?b id o ?q" unfolding expand_fun_eq o_assoc by simp
   139       have th0: "p = Fun.swap a ?b id o ?q" unfolding ext_iff o_assoc by simp
   140       have th1: "?b \<in> insert a S " unfolding permutes_in_image[OF pS] by simp
   140       have th1: "?b \<in> insert a S " unfolding permutes_in_image[OF pS] by simp
   141       from permutes_insert_lemma[OF pS] th0 th1
   141       from permutes_insert_lemma[OF pS] th0 th1
   142       have "\<exists> b q. p = Fun.swap a b id o q \<and> b \<in> insert a S \<and> q permutes S" by blast}
   142       have "\<exists> b q. p = Fun.swap a b id o q \<and> b \<in> insert a S \<and> q permutes S" by blast}
   143     moreover
   143     moreover
   144     {fix b q assume bq: "p = Fun.swap a b id o q" "b \<in> insert a S" "q permutes S"
   144     {fix b q assume bq: "p = Fun.swap a b id o q" "b \<in> insert a S" "q permutes S"
   178       {
   178       {
   179         fix b p c q assume bp: "(b,p) \<in> ?pF'" and cq: "(c,q) \<in> ?pF'"
   179         fix b p c q assume bp: "(b,p) \<in> ?pF'" and cq: "(c,q) \<in> ?pF'"
   180           and eq: "?g (b,p) = ?g (c,q)"
   180           and eq: "?g (b,p) = ?g (c,q)"
   181         from bp cq have ths: "b \<in> insert x F" "c \<in> insert x F" "x \<in> insert x F" "p permutes F" "q permutes F" by auto
   181         from bp cq have ths: "b \<in> insert x F" "c \<in> insert x F" "x \<in> insert x F" "p permutes F" "q permutes F" by auto
   182         from ths(4) `x \<notin> F` eq have "b = ?g (b,p) x" unfolding permutes_def
   182         from ths(4) `x \<notin> F` eq have "b = ?g (b,p) x" unfolding permutes_def
   183           by (auto simp add: swap_def fun_upd_def expand_fun_eq)
   183           by (auto simp add: swap_def fun_upd_def ext_iff)
   184         also have "\<dots> = ?g (c,q) x" using ths(5) `x \<notin> F` eq
   184         also have "\<dots> = ?g (c,q) x" using ths(5) `x \<notin> F` eq
   185           by (auto simp add: swap_def fun_upd_def expand_fun_eq)
   185           by (auto simp add: swap_def fun_upd_def ext_iff)
   186         also have "\<dots> = c"using ths(5) `x \<notin> F` unfolding permutes_def
   186         also have "\<dots> = c"using ths(5) `x \<notin> F` unfolding permutes_def
   187           by (auto simp add: swap_def fun_upd_def expand_fun_eq)
   187           by (auto simp add: swap_def fun_upd_def ext_iff)
   188         finally have bc: "b = c" .
   188         finally have bc: "b = c" .
   189         hence "Fun.swap x b id = Fun.swap x c id" by simp
   189         hence "Fun.swap x b id = Fun.swap x c id" by simp
   190         with eq have "Fun.swap x b id o p = Fun.swap x b id o q" by simp
   190         with eq have "Fun.swap x b id o p = Fun.swap x b id o q" by simp
   191         hence "Fun.swap x b id o (Fun.swap x b id o p) = Fun.swap x b id o (Fun.swap x b id o q)" by simp
   191         hence "Fun.swap x b id o (Fun.swap x b id o p) = Fun.swap x b id o (Fun.swap x b id o q)" by simp
   192         hence "p = q" by (simp add: o_assoc)
   192         hence "p = q" by (simp add: o_assoc)
   249 
   249 
   250 (* ------------------------------------------------------------------------- *)
   250 (* ------------------------------------------------------------------------- *)
   251 (* Various combinations of transpositions with 2, 1 and 0 common elements.   *)
   251 (* Various combinations of transpositions with 2, 1 and 0 common elements.   *)
   252 (* ------------------------------------------------------------------------- *)
   252 (* ------------------------------------------------------------------------- *)
   253 
   253 
   254 lemma swap_id_common:" a \<noteq> c \<Longrightarrow> b \<noteq> c \<Longrightarrow>  Fun.swap a b id o Fun.swap a c id = Fun.swap b c id o Fun.swap a b id" by (simp add: expand_fun_eq swap_def)
   254 lemma swap_id_common:" a \<noteq> c \<Longrightarrow> b \<noteq> c \<Longrightarrow>  Fun.swap a b id o Fun.swap a c id = Fun.swap b c id o Fun.swap a b id" by (simp add: ext_iff swap_def)
   255 
   255 
   256 lemma swap_id_common': "~(a = b) \<Longrightarrow> ~(a = c) \<Longrightarrow> Fun.swap a c id o Fun.swap b c id = Fun.swap b c id o Fun.swap a b id" by (simp add: expand_fun_eq swap_def)
   256 lemma swap_id_common': "~(a = b) \<Longrightarrow> ~(a = c) \<Longrightarrow> Fun.swap a c id o Fun.swap b c id = Fun.swap b c id o Fun.swap a b id" by (simp add: ext_iff swap_def)
   257 
   257 
   258 lemma swap_id_independent: "~(a = c) \<Longrightarrow> ~(a = d) \<Longrightarrow> ~(b = c) \<Longrightarrow> ~(b = d) ==> Fun.swap a b id o Fun.swap c d id = Fun.swap c d id o Fun.swap a b id"
   258 lemma swap_id_independent: "~(a = c) \<Longrightarrow> ~(a = d) \<Longrightarrow> ~(b = c) \<Longrightarrow> ~(b = d) ==> Fun.swap a b id o Fun.swap c d id = Fun.swap c d id o Fun.swap a b id"
   259   by (simp add: swap_def expand_fun_eq)
   259   by (simp add: swap_def ext_iff)
   260 
   260 
   261 (* ------------------------------------------------------------------------- *)
   261 (* ------------------------------------------------------------------------- *)
   262 (* Permutations as transposition sequences.                                  *)
   262 (* Permutations as transposition sequences.                                  *)
   263 (* ------------------------------------------------------------------------- *)
   263 (* ------------------------------------------------------------------------- *)
   264 
   264 
   350   apply (case_tac "a = c \<and> b \<noteq> d")
   350   apply (case_tac "a = c \<and> b \<noteq> d")
   351   apply (rule disjI2)
   351   apply (rule disjI2)
   352   apply (rule_tac x="b" in exI)
   352   apply (rule_tac x="b" in exI)
   353   apply (rule_tac x="d" in exI)
   353   apply (rule_tac x="d" in exI)
   354   apply (rule_tac x="b" in exI)
   354   apply (rule_tac x="b" in exI)
   355   apply (clarsimp simp add: expand_fun_eq swap_def)
   355   apply (clarsimp simp add: ext_iff swap_def)
   356   apply (case_tac "a \<noteq> c \<and> b = d")
   356   apply (case_tac "a \<noteq> c \<and> b = d")
   357   apply (rule disjI2)
   357   apply (rule disjI2)
   358   apply (rule_tac x="c" in exI)
   358   apply (rule_tac x="c" in exI)
   359   apply (rule_tac x="d" in exI)
   359   apply (rule_tac x="d" in exI)
   360   apply (rule_tac x="c" in exI)
   360   apply (rule_tac x="c" in exI)
   361   apply (clarsimp simp add: expand_fun_eq swap_def)
   361   apply (clarsimp simp add: ext_iff swap_def)
   362   apply (rule disjI2)
   362   apply (rule disjI2)
   363   apply (rule_tac x="c" in exI)
   363   apply (rule_tac x="c" in exI)
   364   apply (rule_tac x="d" in exI)
   364   apply (rule_tac x="d" in exI)
   365   apply (rule_tac x="b" in exI)
   365   apply (rule_tac x="b" in exI)
   366   apply (clarsimp simp add: expand_fun_eq swap_def)
   366   apply (clarsimp simp add: ext_iff swap_def)
   367   done
   367   done
   368 with H show ?thesis by metis
   368 with H show ?thesis by metis
   369 qed
   369 qed
   370 
   370 
   371 lemma swapidseq_id_iff[simp]: "swapidseq 0 p \<longleftrightarrow> p = id"
   371 lemma swapidseq_id_iff[simp]: "swapidseq 0 p \<longleftrightarrow> p = id"
   516   shows "bij p"
   516   shows "bij p"
   517 proof-
   517 proof-
   518   from p obtain n where n: "swapidseq n p" unfolding permutation_def by blast
   518   from p obtain n where n: "swapidseq n p" unfolding permutation_def by blast
   519   from swapidseq_inverse_exists[OF n] obtain q where
   519   from swapidseq_inverse_exists[OF n] obtain q where
   520     q: "swapidseq n q" "p \<circ> q = id" "q \<circ> p = id" by blast
   520     q: "swapidseq n q" "p \<circ> q = id" "q \<circ> p = id" by blast
   521   thus ?thesis unfolding bij_iff  apply (auto simp add: expand_fun_eq) apply metis done
   521   thus ?thesis unfolding bij_iff  apply (auto simp add: ext_iff) apply metis done
   522 qed
   522 qed
   523 
   523 
   524 lemma permutation_finite_support: assumes p: "permutation p"
   524 lemma permutation_finite_support: assumes p: "permutation p"
   525   shows "finite {x. p x \<noteq> x}"
   525   shows "finite {x. p x \<noteq> x}"
   526 proof-
   526 proof-
   542   using surj_f_inv_f[of p] inv_f_f[of f] by (auto simp add: bij_def)
   542   using surj_f_inv_f[of p] inv_f_f[of f] by (auto simp add: bij_def)
   543 
   543 
   544 lemma bij_swap_comp:
   544 lemma bij_swap_comp:
   545   assumes bp: "bij p" shows "Fun.swap a b id o p = Fun.swap (inv p a) (inv p b) p"
   545   assumes bp: "bij p" shows "Fun.swap a b id o p = Fun.swap (inv p a) (inv p b) p"
   546   using surj_f_inv_f[OF bij_is_surj[OF bp]]
   546   using surj_f_inv_f[OF bij_is_surj[OF bp]]
   547   by (simp add: expand_fun_eq swap_def bij_inv_eq_iff[OF bp])
   547   by (simp add: ext_iff swap_def bij_inv_eq_iff[OF bp])
   548 
   548 
   549 lemma bij_swap_ompose_bij: "bij p \<Longrightarrow> bij (Fun.swap a b id o p)"
   549 lemma bij_swap_ompose_bij: "bij p \<Longrightarrow> bij (Fun.swap a b id o p)"
   550 proof-
   550 proof-
   551   assume H: "bij p"
   551   assume H: "bij p"
   552   show ?thesis
   552   show ?thesis
   686           with permutes_inj[OF H(2)] have "p n = n" unfolding inj_on_def by blast
   686           with permutes_inj[OF H(2)] have "p n = n" unfolding inj_on_def by blast
   687           with h have False by simp}
   687           with h have False by simp}
   688         ultimately have "p n = n" by blast }
   688         ultimately have "p n = n" by blast }
   689       ultimately show "p n = n"  by blast
   689       ultimately show "p n = n"  by blast
   690     qed}
   690     qed}
   691   thus ?thesis by (auto simp add: expand_fun_eq)
   691   thus ?thesis by (auto simp add: ext_iff)
   692 qed
   692 qed
   693 
   693 
   694 lemma permutes_natset_ge:
   694 lemma permutes_natset_ge:
   695   assumes p: "p permutes (S::'a::wellorder set)" and le: "\<forall>i \<in> S.  p i \<ge> i" shows "p = id"
   695   assumes p: "p permutes (S::'a::wellorder set)" and le: "\<forall>i \<in> S.  p i \<ge> i" shows "p = id"
   696 proof-
   696 proof-
   809 lemma setsum_over_permutations_insert:
   809 lemma setsum_over_permutations_insert:
   810   assumes fS: "finite S" and aS: "a \<notin> S"
   810   assumes fS: "finite S" and aS: "a \<notin> S"
   811   shows "setsum f {p. p permutes (insert a S)} = setsum (\<lambda>b. setsum (\<lambda>q. f (Fun.swap a b id o q)) {p. p permutes S}) (insert a S)"
   811   shows "setsum f {p. p permutes (insert a S)} = setsum (\<lambda>b. setsum (\<lambda>q. f (Fun.swap a b id o q)) {p. p permutes S}) (insert a S)"
   812 proof-
   812 proof-
   813   have th0: "\<And>f a b. (\<lambda>(b,p). f (Fun.swap a b id o p)) = f o (\<lambda>(b,p). Fun.swap a b id o p)"
   813   have th0: "\<And>f a b. (\<lambda>(b,p). f (Fun.swap a b id o p)) = f o (\<lambda>(b,p). Fun.swap a b id o p)"
   814     by (simp add: expand_fun_eq)
   814     by (simp add: ext_iff)
   815   have th1: "\<And>P Q. P \<times> Q = {(a,b). a \<in> P \<and> b \<in> Q}" by blast
   815   have th1: "\<And>P Q. P \<times> Q = {(a,b). a \<in> P \<and> b \<in> Q}" by blast
   816   have th2: "\<And>P Q. P \<Longrightarrow> (P \<Longrightarrow> Q) \<Longrightarrow> P \<and> Q" by blast
   816   have th2: "\<And>P Q. P \<Longrightarrow> (P \<Longrightarrow> Q) \<Longrightarrow> P \<and> Q" by blast
   817   show ?thesis
   817   show ?thesis
   818     unfolding permutes_insert
   818     unfolding permutes_insert
   819     unfolding setsum_cartesian_product
   819     unfolding setsum_cartesian_product