src/HOL/Library/While_Combinator.thy
changeset 67091 1393c2340eec
parent 63561 fba08009ff3e
child 67613 ce654b0e6d69
equal deleted inserted replaced
67090:0ec94bb9cec4 67091:1393c2340eec
    10 begin
    10 begin
    11 
    11 
    12 subsection \<open>Partial version\<close>
    12 subsection \<open>Partial version\<close>
    13 
    13 
    14 definition while_option :: "('a \<Rightarrow> bool) \<Rightarrow> ('a \<Rightarrow> 'a) \<Rightarrow> 'a \<Rightarrow> 'a option" where
    14 definition while_option :: "('a \<Rightarrow> bool) \<Rightarrow> ('a \<Rightarrow> 'a) \<Rightarrow> 'a \<Rightarrow> 'a option" where
    15 "while_option b c s = (if (\<exists>k. ~ b ((c ^^ k) s))
    15 "while_option b c s = (if (\<exists>k. \<not> b ((c ^^ k) s))
    16    then Some ((c ^^ (LEAST k. ~ b ((c ^^ k) s))) s)
    16    then Some ((c ^^ (LEAST k. \<not> b ((c ^^ k) s))) s)
    17    else None)"
    17    else None)"
    18 
    18 
    19 theorem while_option_unfold[code]:
    19 theorem while_option_unfold[code]:
    20 "while_option b c s = (if b s then while_option b c (c s) else Some s)"
    20 "while_option b c s = (if b s then while_option b c (c s) else Some s)"
    21 proof cases
    21 proof cases
    22   assume "b s"
    22   assume "b s"
    23   show ?thesis
    23   show ?thesis
    24   proof (cases "\<exists>k. ~ b ((c ^^ k) s)")
    24   proof (cases "\<exists>k. \<not> b ((c ^^ k) s)")
    25     case True
    25     case True
    26     then obtain k where 1: "~ b ((c ^^ k) s)" ..
    26     then obtain k where 1: "\<not> b ((c ^^ k) s)" ..
    27     with \<open>b s\<close> obtain l where "k = Suc l" by (cases k) auto
    27     with \<open>b s\<close> obtain l where "k = Suc l" by (cases k) auto
    28     with 1 have "~ b ((c ^^ l) (c s))" by (auto simp: funpow_swap1)
    28     with 1 have "\<not> b ((c ^^ l) (c s))" by (auto simp: funpow_swap1)
    29     then have 2: "\<exists>l. ~ b ((c ^^ l) (c s))" ..
    29     then have 2: "\<exists>l. \<not> b ((c ^^ l) (c s))" ..
    30     from 1
    30     from 1
    31     have "(LEAST k. ~ b ((c ^^ k) s)) = Suc (LEAST l. ~ b ((c ^^ Suc l) s))"
    31     have "(LEAST k. \<not> b ((c ^^ k) s)) = Suc (LEAST l. \<not> b ((c ^^ Suc l) s))"
    32       by (rule Least_Suc) (simp add: \<open>b s\<close>)
    32       by (rule Least_Suc) (simp add: \<open>b s\<close>)
    33     also have "... = Suc (LEAST l. ~ b ((c ^^ l) (c s)))"
    33     also have "... = Suc (LEAST l. \<not> b ((c ^^ l) (c s)))"
    34       by (simp add: funpow_swap1)
    34       by (simp add: funpow_swap1)
    35     finally
    35     finally
    36     show ?thesis 
    36     show ?thesis 
    37       using True 2 \<open>b s\<close> by (simp add: funpow_swap1 while_option_def)
    37       using True 2 \<open>b s\<close> by (simp add: funpow_swap1 while_option_def)
    38   next
    38   next
    39     case False
    39     case False
    40     then have "~ (\<exists>l. ~ b ((c ^^ Suc l) s))" by blast
    40     then have "\<not> (\<exists>l. \<not> b ((c ^^ Suc l) s))" by blast
    41     then have "~ (\<exists>l. ~ b ((c ^^ l) (c s)))"
    41     then have "\<not> (\<exists>l. \<not> b ((c ^^ l) (c s)))"
    42       by (simp add: funpow_swap1)
    42       by (simp add: funpow_swap1)
    43     with False  \<open>b s\<close> show ?thesis by (simp add: while_option_def)
    43     with False  \<open>b s\<close> show ?thesis by (simp add: while_option_def)
    44   qed
    44   qed
    45 next
    45 next
    46   assume [simp]: "~ b s"
    46   assume [simp]: "\<not> b s"
    47   have least: "(LEAST k. ~ b ((c ^^ k) s)) = 0"
    47   have least: "(LEAST k. \<not> b ((c ^^ k) s)) = 0"
    48     by (rule Least_equality) auto
    48     by (rule Least_equality) auto
    49   moreover 
    49   moreover 
    50   have "\<exists>k. ~ b ((c ^^ k) s)" by (rule exI[of _ "0::nat"]) auto
    50   have "\<exists>k. \<not> b ((c ^^ k) s)" by (rule exI[of _ "0::nat"]) auto
    51   ultimately show ?thesis unfolding while_option_def by auto 
    51   ultimately show ?thesis unfolding while_option_def by auto 
    52 qed
    52 qed
    53 
    53 
    54 lemma while_option_stop2:
    54 lemma while_option_stop2:
    55  "while_option b c s = Some t \<Longrightarrow> EX k. t = (c^^k) s \<and> \<not> b t"
    55  "while_option b c s = Some t \<Longrightarrow> \<exists>k. t = (c^^k) s \<and> \<not> b t"
    56 apply(simp add: while_option_def split: if_splits)
    56 apply(simp add: while_option_def split: if_splits)
    57 by (metis (lifting) LeastI_ex)
    57 by (metis (lifting) LeastI_ex)
    58 
    58 
    59 lemma while_option_stop: "while_option b c s = Some t \<Longrightarrow> ~ b t"
    59 lemma while_option_stop: "while_option b c s = Some t \<Longrightarrow> \<not> b t"
    60 by(metis while_option_stop2)
    60 by(metis while_option_stop2)
    61 
    61 
    62 theorem while_option_rule:
    62 theorem while_option_rule:
    63   assumes step: "!!s. P s ==> b s ==> P (c s)"
    63   assumes step: "!!s. P s ==> b s ==> P (c s)"
    64     and result: "while_option b c s = Some t"
    64     and result: "while_option b c s = Some t"
    65     and init: "P s"
    65     and init: "P s"
    66   shows "P t"
    66   shows "P t"
    67 proof -
    67 proof -
    68   define k where "k = (LEAST k. ~ b ((c ^^ k) s))"
    68   define k where "k = (LEAST k. \<not> b ((c ^^ k) s))"
    69   from assms have t: "t = (c ^^ k) s"
    69   from assms have t: "t = (c ^^ k) s"
    70     by (simp add: while_option_def k_def split: if_splits)    
    70     by (simp add: while_option_def k_def split: if_splits)    
    71   have 1: "ALL i<k. b ((c ^^ i) s)"
    71   have 1: "ALL i<k. b ((c ^^ i) s)"
    72     by (auto simp: k_def dest: not_less_Least)
    72     by (auto simp: k_def dest: not_less_Least)
    73 
    73 
    74   { fix i assume "i <= k" then have "P ((c ^^ i) s)"
    74   { fix i assume "i \<le> k" then have "P ((c ^^ i) s)"
    75       by (induct i) (auto simp: init step 1) }
    75       by (induct i) (auto simp: init step 1) }
    76   thus "P t" by (auto simp: t)
    76   thus "P t" by (auto simp: t)
    77 qed
    77 qed
    78 
    78 
    79 lemma funpow_commute: 
    79 lemma funpow_commute: 
   241 
   241 
   242 text\<open>Proving termination:\<close>
   242 text\<open>Proving termination:\<close>
   243 
   243 
   244 theorem wf_while_option_Some:
   244 theorem wf_while_option_Some:
   245   assumes "wf {(t, s). (P s \<and> b s) \<and> t = c s}"
   245   assumes "wf {(t, s). (P s \<and> b s) \<and> t = c s}"
   246   and "!!s. P s \<Longrightarrow> b s \<Longrightarrow> P(c s)" and "P s"
   246   and "\<And>s. P s \<Longrightarrow> b s \<Longrightarrow> P(c s)" and "P s"
   247   shows "EX t. while_option b c s = Some t"
   247   shows "\<exists>t. while_option b c s = Some t"
   248 using assms(1,3)
   248 using assms(1,3)
   249 proof (induction s)
   249 proof (induction s)
   250   case less thus ?case using assms(2)
   250   case less thus ?case using assms(2)
   251     by (subst while_option_unfold) simp
   251     by (subst while_option_unfold) simp
   252 qed
   252 qed
   262  with wf have "wf {(t,s). P s \<and> b s \<and> t = c s}" by (auto simp: wf_subset)
   262  with wf have "wf {(t,s). P s \<and> b s \<and> t = c s}" by (auto simp: wf_subset)
   263  with inv init show ?thesis by (auto simp: wf_while_option_Some)
   263  with inv init show ?thesis by (auto simp: wf_while_option_Some)
   264 qed
   264 qed
   265 
   265 
   266 theorem measure_while_option_Some: fixes f :: "'s \<Rightarrow> nat"
   266 theorem measure_while_option_Some: fixes f :: "'s \<Rightarrow> nat"
   267 shows "(!!s. P s \<Longrightarrow> b s \<Longrightarrow> P(c s) \<and> f(c s) < f s)
   267 shows "(\<And>s. P s \<Longrightarrow> b s \<Longrightarrow> P(c s) \<and> f(c s) < f s)
   268   \<Longrightarrow> P s \<Longrightarrow> EX t. while_option b c s = Some t"
   268   \<Longrightarrow> P s \<Longrightarrow> \<exists>t. while_option b c s = Some t"
   269 by(blast intro: wf_while_option_Some[OF wf_if_measure, of P b f])
   269 by(blast intro: wf_while_option_Some[OF wf_if_measure, of P b f])
   270 
   270 
   271 text\<open>Kleene iteration starting from the empty set and assuming some finite
   271 text\<open>Kleene iteration starting from the empty set and assuming some finite
   272 bounding set:\<close>
   272 bounding set:\<close>
   273 
   273