nipkow@10213: (* Title: HOL/Relation_Power.thy nipkow@10213: Author: Tobias Nipkow nipkow@10213: Copyright 1996 TU Muenchen paulson@15410: *) nipkow@11306: paulson@15410: header{*Powers of Relations and Functions*} nipkow@10213: nipkow@15131: theory Relation_Power haftmann@29654: imports Power Transitive_Closure Plain nipkow@15131: begin nipkow@10213: haftmann@30949: consts funpower :: "('a \ 'b) \ nat \ 'a \ 'b" (infixr "^^" 80) nipkow@10213: haftmann@25861: overloading haftmann@30949: relpow \ "funpower \ ('a \ 'a) set \ nat \ ('a \ 'a) set" haftmann@25861: begin haftmann@25861: haftmann@30949: text {* @{text "R ^^ n = R O ... O R"}, the n-fold composition of @{text R} *} nipkow@10213: haftmann@25861: primrec relpow where haftmann@30949: "(R \ ('a \ 'a) set) ^^ 0 = Id" haftmann@30949: | "(R \ ('a \ 'a) set) ^^ Suc n = R O (R ^^ n)" haftmann@25861: haftmann@25861: end nipkow@11305: haftmann@25861: overloading haftmann@30949: funpow \ "funpower \ ('a \ 'a) \ nat \ 'a \ 'a" haftmann@25861: begin haftmann@25861: haftmann@30949: text {* @{text "f ^^ n = f o ... o f"}, the n-fold composition of @{text f} *} haftmann@25861: haftmann@25861: primrec funpow where haftmann@30949: "(f \ 'a \ 'a) ^^ 0 = id" haftmann@30949: | "(f \ 'a \ 'a) ^^ Suc n = f o (f ^^ n)" haftmann@25861: haftmann@25861: end nipkow@11305: haftmann@30949: primrec fun_pow :: "nat \ ('a \ 'a) \ 'a \ 'a" where haftmann@30949: "fun_pow 0 f = id" haftmann@25861: | "fun_pow (Suc n) f = f o fun_pow n f" haftmann@21414: haftmann@30949: lemma funpow_fun_pow [code unfold]: haftmann@30949: "f ^^ n = fun_pow n f" haftmann@25861: unfolding funpow_def fun_pow_def .. haftmann@21414: haftmann@30949: lemma funpow_add: haftmann@30949: "f ^^ (m + n) = f ^^ m o f ^^ n" wenzelm@18398: by (induct m) simp_all nipkow@15112: haftmann@30949: lemma funpow_swap1: haftmann@30949: "f ((f ^^ n) x) = (f ^^ n) (f x)" nipkow@18049: proof - haftmann@30949: have "f ((f ^^ n) x) = (f ^^ (n+1)) x" unfolding One_nat_def by simp haftmann@30949: also have "\ = (f ^^ n o f ^^ 1) x" by (simp only: funpow_add) haftmann@30949: also have "\ = (f ^^ n) (f x)" unfolding One_nat_def by simp nipkow@18049: finally show ?thesis . nipkow@18049: qed nipkow@18049: wenzelm@18398: lemma rel_pow_1 [simp]: haftmann@30949: fixes R :: "('a * 'a) set" haftmann@30949: shows "R ^^ 1 = R" wenzelm@18398: by simp paulson@15410: haftmann@30949: lemma rel_pow_0_I: haftmann@30949: "(x, x) \ R ^^ 0" haftmann@30949: by simp haftmann@30949: haftmann@30949: lemma rel_pow_Suc_I: haftmann@30949: "(x, y) \ R ^^ n \ (y, z) \ R \ (x, z) \ R ^^ Suc n" wenzelm@18398: by auto paulson@15410: wenzelm@18398: lemma rel_pow_Suc_I2: haftmann@30949: "(x, y) \ R \ (y, z) \ R ^^ n \ (x, z) \ R ^^ Suc n" haftmann@30949: by (induct n arbitrary: z) (simp, fastsimp) paulson@15410: haftmann@30949: lemma rel_pow_0_E: haftmann@30949: "(x, y) \ R ^^ 0 \ (x = y \ P) \ P" wenzelm@18398: by simp paulson@15410: wenzelm@18398: lemma rel_pow_Suc_E: haftmann@30949: "(x, z) \ R ^^ Suc n \ (\y. (x, y) \ R ^^ n \ (y, z) \ R \ P) \ P" wenzelm@18398: by auto paulson@15410: wenzelm@18398: lemma rel_pow_E: haftmann@30949: "(x, z) \ R ^^ n \ (n = 0 \ x = z \ P) haftmann@30949: \ (\y m. n = Suc m \ (x, y) \ R ^^ m \ (y, z) \ R \ P) haftmann@30949: \ P" wenzelm@18398: by (cases n) auto paulson@15410: wenzelm@18398: lemma rel_pow_Suc_D2: haftmann@30949: "(x, z) \ R ^^ Suc n \ (\y. (x, y) \ R \ (y, z) \ R ^^ n)" wenzelm@20503: apply (induct n arbitrary: x z) wenzelm@18398: apply (blast intro: rel_pow_0_I elim: rel_pow_0_E rel_pow_Suc_E) wenzelm@18398: apply (blast intro: rel_pow_Suc_I elim: rel_pow_0_E rel_pow_Suc_E) wenzelm@18398: done paulson@15410: paulson@15410: lemma rel_pow_Suc_D2': haftmann@30949: "\x y z. (x, y) \ R ^^ n \ (y, z) \ R \ (\w. (x, w) \ R \ (w, z) \ R ^^ n)" wenzelm@18398: by (induct n) (simp_all, blast) paulson@15410: wenzelm@18398: lemma rel_pow_E2: haftmann@30949: "(x, z) \ R ^^ n \ (n = 0 \ x = z \ P) haftmann@30949: \ (\y m. n = Suc m \ (x, y) \ R \ (y, z) \ R ^^ m \ P) haftmann@30949: \ P" haftmann@30949: apply (cases n, simp) wenzelm@18398: apply (cut_tac n=nat and R=R in rel_pow_Suc_D2', simp, blast) wenzelm@18398: done paulson@15410: haftmann@30949: lemma rtrancl_imp_UN_rel_pow: haftmann@30949: "p \ R^* \ p \ (\n. R ^^ n)" haftmann@30949: apply (cases p) apply (simp only:) wenzelm@18398: apply (erule rtrancl_induct) wenzelm@18398: apply (blast intro: rel_pow_0_I rel_pow_Suc_I)+ wenzelm@18398: done paulson@15410: haftmann@30949: lemma rel_pow_imp_rtrancl: haftmann@30949: "p \ R ^^ n \ p \ R^*" haftmann@30949: apply (induct n arbitrary: p) haftmann@30949: apply (simp_all only: split_tupled_all) wenzelm@18398: apply (blast intro: rtrancl_refl elim: rel_pow_0_E) wenzelm@18398: apply (blast elim: rel_pow_Suc_E intro: rtrancl_into_rtrancl) wenzelm@18398: done paulson@15410: haftmann@30949: lemma rtrancl_is_UN_rel_pow: haftmann@30949: "R^* = (UN n. R ^^ n)" wenzelm@18398: by (blast intro: rtrancl_imp_UN_rel_pow rel_pow_imp_rtrancl) paulson@15410: kleing@25295: lemma trancl_power: haftmann@30949: "x \ r^+ = (\n > 0. x \ r ^^ n)" kleing@25295: apply (cases x) kleing@25295: apply simp kleing@25295: apply (rule iffI) kleing@25295: apply (drule tranclD2) kleing@25295: apply (clarsimp simp: rtrancl_is_UN_rel_pow) kleing@25295: apply (rule_tac x="Suc x" in exI) kleing@25295: apply (clarsimp simp: rel_comp_def) kleing@25295: apply fastsimp kleing@25295: apply clarsimp kleing@25295: apply (case_tac n, simp) kleing@25295: apply clarsimp kleing@25295: apply (drule rel_pow_imp_rtrancl) kleing@25295: apply fastsimp kleing@25295: done paulson@15410: wenzelm@18398: lemma single_valued_rel_pow: haftmann@30949: fixes R :: "('a * 'a) set" haftmann@30949: shows "single_valued R \ single_valued (R ^^ n)" haftmann@30949: apply (induct n arbitrary: R) haftmann@30949: apply simp_all wenzelm@18398: apply (rule single_valuedI) wenzelm@18398: apply (fast dest: single_valuedD elim: rel_pow_Suc_E) wenzelm@18398: done paulson@15410: nipkow@10213: end