src/HOL/Relation_Power.thy
author haftmann
Fri Feb 15 16:09:12 2008 +0100 (2008-02-15)
changeset 26072 f65a7fa2da6c
parent 25861 494d9301cc75
child 26799 5bd38256ce5b
permissions -rw-r--r--
<= and < on nat no longer depend on wellfounded relations
nipkow@10213
     1
(*  Title:      HOL/Relation_Power.thy
nipkow@10213
     2
    ID:         $Id$
nipkow@10213
     3
    Author:     Tobias Nipkow
nipkow@10213
     4
    Copyright   1996  TU Muenchen
paulson@15410
     5
*)
nipkow@11306
     6
paulson@15410
     7
header{*Powers of Relations and Functions*}
nipkow@10213
     8
nipkow@15131
     9
theory Relation_Power
haftmann@26072
    10
imports Power Transitive_Closure
nipkow@15131
    11
begin
nipkow@10213
    12
nipkow@10213
    13
instance
wenzelm@18398
    14
  set :: (type) power ..
paulson@15410
    15
      --{* only type @{typ "('a * 'a) set"} should be in class @{text power}!*}
nipkow@10213
    16
haftmann@25861
    17
overloading
haftmann@25861
    18
  relpow \<equiv> "power \<Colon> ('a \<times> 'a) set \<Rightarrow> nat \<Rightarrow> ('a \<times> 'a) set"  (unchecked)
haftmann@25861
    19
begin
haftmann@25861
    20
haftmann@25861
    21
text {* @{text "R ^ n = R O ... O R"}, the n-fold composition of @{text R} *}
nipkow@10213
    22
haftmann@25861
    23
primrec relpow where
haftmann@25861
    24
  "(R \<Colon> ('a \<times> 'a) set)  ^ 0 = Id"
haftmann@25861
    25
  | "(R \<Colon> ('a \<times> 'a) set) ^ Suc n = R O (R ^ n)"
haftmann@25861
    26
haftmann@25861
    27
end
nipkow@11305
    28
nipkow@11306
    29
instance
haftmann@21414
    30
  "fun" :: (type, type) power ..
paulson@15410
    31
      --{* only type @{typ "'a => 'a"} should be in class @{text power}!*}
nipkow@11305
    32
haftmann@25861
    33
overloading
haftmann@25861
    34
  funpow \<equiv> "power \<Colon>  ('a \<Rightarrow> 'a) \<Rightarrow> nat \<Rightarrow> 'a \<Rightarrow> 'a" (unchecked)
haftmann@25861
    35
begin
haftmann@25861
    36
haftmann@25861
    37
text {* @{text "f ^ n = f o ... o f"}, the n-fold composition of @{text f} *}
haftmann@25861
    38
haftmann@25861
    39
primrec funpow where
haftmann@25861
    40
  "(f \<Colon> 'a \<Rightarrow> 'a) ^ 0 = id"
haftmann@25861
    41
  | "(f \<Colon> 'a \<Rightarrow> 'a) ^ Suc n = f o (f ^ n)"
haftmann@25861
    42
haftmann@25861
    43
end
nipkow@11305
    44
paulson@15410
    45
text{*WARNING: due to the limits of Isabelle's type classes, exponentiation on
paulson@15410
    46
functions and relations has too general a domain, namely @{typ "('a * 'b)set"}
paulson@15410
    47
and @{typ "'a => 'b"}.  Explicit type constraints may therefore be necessary.
paulson@15410
    48
For example, @{term "range(f^n) = A"} and @{term "Range(R^n) = B"} need
paulson@15410
    49
constraints.*}
paulson@15410
    50
haftmann@21414
    51
text {*
haftmann@21414
    52
  Circumvent this problem for code generation:
haftmann@21414
    53
*}
haftmann@21414
    54
haftmann@25861
    55
primrec
haftmann@25861
    56
  fun_pow :: "nat \<Rightarrow> ('a \<Rightarrow> 'a) \<Rightarrow> 'a \<Rightarrow> 'a"
haftmann@22737
    57
where
haftmann@25861
    58
  "fun_pow 0 f = id"
haftmann@25861
    59
  | "fun_pow (Suc n) f = f o fun_pow n f"
haftmann@21414
    60
haftmann@25861
    61
lemma funpow_fun_pow [code inline]: "f ^ n = fun_pow n f"
haftmann@25861
    62
  unfolding funpow_def fun_pow_def ..
haftmann@21414
    63
nipkow@15112
    64
lemma funpow_add: "f ^ (m+n) = f^m o f^n"
wenzelm@18398
    65
  by (induct m) simp_all
nipkow@15112
    66
nipkow@18049
    67
lemma funpow_swap1: "f((f^n) x) = (f^n)(f x)"
nipkow@18049
    68
proof -
nipkow@18049
    69
  have "f((f^n) x) = (f^(n+1)) x" by simp
wenzelm@18398
    70
  also have "\<dots>  = (f^n o f^1) x" by (simp only: funpow_add)
nipkow@18049
    71
  also have "\<dots> = (f^n)(f x)" by simp
nipkow@18049
    72
  finally show ?thesis .
nipkow@18049
    73
qed
nipkow@18049
    74
wenzelm@18398
    75
lemma rel_pow_1 [simp]:
wenzelm@18398
    76
  fixes R :: "('a*'a)set"
wenzelm@18398
    77
  shows "R^1 = R"
wenzelm@18398
    78
  by simp
paulson@15410
    79
paulson@15410
    80
lemma rel_pow_0_I: "(x,x) : R^0"
wenzelm@18398
    81
  by simp
paulson@15410
    82
paulson@15410
    83
lemma rel_pow_Suc_I: "[| (x,y) : R^n; (y,z):R |] ==> (x,z):R^(Suc n)"
wenzelm@18398
    84
  by auto
paulson@15410
    85
wenzelm@18398
    86
lemma rel_pow_Suc_I2:
wenzelm@18398
    87
    "(x, y) : R \<Longrightarrow> (y, z) : R^n \<Longrightarrow> (x,z) : R^(Suc n)"
wenzelm@20503
    88
  apply (induct n arbitrary: z)
wenzelm@18398
    89
   apply simp
wenzelm@18398
    90
  apply fastsimp
wenzelm@18398
    91
  done
paulson@15410
    92
paulson@15410
    93
lemma rel_pow_0_E: "[| (x,y) : R^0; x=y ==> P |] ==> P"
wenzelm@18398
    94
  by simp
paulson@15410
    95
wenzelm@18398
    96
lemma rel_pow_Suc_E:
wenzelm@18398
    97
    "[| (x,z) : R^(Suc n);  !!y. [| (x,y) : R^n; (y,z) : R |] ==> P |] ==> P"
wenzelm@18398
    98
  by auto
paulson@15410
    99
wenzelm@18398
   100
lemma rel_pow_E:
wenzelm@18398
   101
    "[| (x,z) : R^n;  [| n=0; x = z |] ==> P;
wenzelm@18398
   102
        !!y m. [| n = Suc m; (x,y) : R^m; (y,z) : R |] ==> P
paulson@15410
   103
     |] ==> P"
wenzelm@18398
   104
  by (cases n) auto
paulson@15410
   105
wenzelm@18398
   106
lemma rel_pow_Suc_D2:
wenzelm@18398
   107
    "(x, z) : R^(Suc n) \<Longrightarrow> (\<exists>y. (x,y) : R & (y,z) : R^n)"
wenzelm@20503
   108
  apply (induct n arbitrary: x z)
wenzelm@18398
   109
   apply (blast intro: rel_pow_0_I elim: rel_pow_0_E rel_pow_Suc_E)
wenzelm@18398
   110
  apply (blast intro: rel_pow_Suc_I elim: rel_pow_0_E rel_pow_Suc_E)
wenzelm@18398
   111
  done
paulson@15410
   112
paulson@15410
   113
lemma rel_pow_Suc_D2':
wenzelm@18398
   114
    "\<forall>x y z. (x,y) : R^n & (y,z) : R --> (\<exists>w. (x,w) : R & (w,z) : R^n)"
wenzelm@18398
   115
  by (induct n) (simp_all, blast)
paulson@15410
   116
wenzelm@18398
   117
lemma rel_pow_E2:
wenzelm@18398
   118
    "[| (x,z) : R^n;  [| n=0; x = z |] ==> P;
wenzelm@18398
   119
        !!y m. [| n = Suc m; (x,y) : R; (y,z) : R^m |] ==> P
paulson@15410
   120
     |] ==> P"
wenzelm@18398
   121
  apply (case_tac n, simp)
wenzelm@18398
   122
  apply (cut_tac n=nat and R=R in rel_pow_Suc_D2', simp, blast)
wenzelm@18398
   123
  done
paulson@15410
   124
paulson@15410
   125
lemma rtrancl_imp_UN_rel_pow: "!!p. p:R^* ==> p : (UN n. R^n)"
wenzelm@18398
   126
  apply (simp only: split_tupled_all)
wenzelm@18398
   127
  apply (erule rtrancl_induct)
wenzelm@18398
   128
   apply (blast intro: rel_pow_0_I rel_pow_Suc_I)+
wenzelm@18398
   129
  done
paulson@15410
   130
paulson@15410
   131
lemma rel_pow_imp_rtrancl: "!!p. p:R^n ==> p:R^*"
wenzelm@18398
   132
  apply (simp only: split_tupled_all)
wenzelm@18398
   133
  apply (induct n)
wenzelm@18398
   134
   apply (blast intro: rtrancl_refl elim: rel_pow_0_E)
wenzelm@18398
   135
  apply (blast elim: rel_pow_Suc_E intro: rtrancl_into_rtrancl)
wenzelm@18398
   136
  done
paulson@15410
   137
paulson@15410
   138
lemma rtrancl_is_UN_rel_pow: "R^* = (UN n. R^n)"
wenzelm@18398
   139
  by (blast intro: rtrancl_imp_UN_rel_pow rel_pow_imp_rtrancl)
paulson@15410
   140
kleing@25295
   141
lemma trancl_power:
kleing@25295
   142
  "x \<in> r^+ = (\<exists>n > 0. x \<in> r^n)"
kleing@25295
   143
  apply (cases x)
kleing@25295
   144
  apply simp
kleing@25295
   145
  apply (rule iffI)
kleing@25295
   146
   apply (drule tranclD2)
kleing@25295
   147
   apply (clarsimp simp: rtrancl_is_UN_rel_pow)
kleing@25295
   148
   apply (rule_tac x="Suc x" in exI)
kleing@25295
   149
   apply (clarsimp simp: rel_comp_def)
kleing@25295
   150
   apply fastsimp
kleing@25295
   151
  apply clarsimp
kleing@25295
   152
  apply (case_tac n, simp)
kleing@25295
   153
  apply clarsimp
kleing@25295
   154
  apply (drule rel_pow_imp_rtrancl)
kleing@25295
   155
  apply fastsimp
kleing@25295
   156
  done
paulson@15410
   157
wenzelm@18398
   158
lemma single_valued_rel_pow:
wenzelm@18398
   159
    "!!r::('a * 'a)set. single_valued r ==> single_valued (r^n)"
wenzelm@18398
   160
  apply (rule single_valuedI)
wenzelm@18398
   161
  apply (induct n)
wenzelm@18398
   162
   apply simp
wenzelm@18398
   163
  apply (fast dest: single_valuedD elim: rel_pow_Suc_E)
wenzelm@18398
   164
  done
paulson@15410
   165
paulson@15410
   166
ML
paulson@15410
   167
{*
paulson@15410
   168
val funpow_add = thm "funpow_add";
paulson@15410
   169
val rel_pow_1 = thm "rel_pow_1";
paulson@15410
   170
val rel_pow_0_I = thm "rel_pow_0_I";
paulson@15410
   171
val rel_pow_Suc_I = thm "rel_pow_Suc_I";
paulson@15410
   172
val rel_pow_Suc_I2 = thm "rel_pow_Suc_I2";
paulson@15410
   173
val rel_pow_0_E = thm "rel_pow_0_E";
paulson@15410
   174
val rel_pow_Suc_E = thm "rel_pow_Suc_E";
paulson@15410
   175
val rel_pow_E = thm "rel_pow_E";
paulson@15410
   176
val rel_pow_Suc_D2 = thm "rel_pow_Suc_D2";
paulson@15410
   177
val rel_pow_Suc_D2 = thm "rel_pow_Suc_D2";
paulson@15410
   178
val rel_pow_E2 = thm "rel_pow_E2";
paulson@15410
   179
val rtrancl_imp_UN_rel_pow = thm "rtrancl_imp_UN_rel_pow";
paulson@15410
   180
val rel_pow_imp_rtrancl = thm "rel_pow_imp_rtrancl";
paulson@15410
   181
val rtrancl_is_UN_rel_pow = thm "rtrancl_is_UN_rel_pow";
paulson@15410
   182
val single_valued_rel_pow = thm "single_valued_rel_pow";
paulson@15410
   183
*}
paulson@15410
   184
nipkow@10213
   185
end