src/HOL/Imperative_HOL/Legacy_Mrec.thy
author wenzelm
Thu, 06 Mar 2014 22:15:01 +0100
changeset 55965 0c2c61a87a7d
parent 53374 a14d2a854c02
permissions -rw-r--r--
merged
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
53109
186535065f5c renamed theory Mrec to Legacy_Mrec, no longer included by default
krauss
parents: 44890
diff changeset
     1
theory Legacy_Mrec
37772
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
     2
imports Heap_Monad
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
     3
begin
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
     4
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
     5
subsubsection {* A monadic combinator for simple recursive functions *}
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
     6
53109
186535065f5c renamed theory Mrec to Legacy_Mrec, no longer included by default
krauss
parents: 44890
diff changeset
     7
text {*
186535065f5c renamed theory Mrec to Legacy_Mrec, no longer included by default
krauss
parents: 44890
diff changeset
     8
  NOTE: The use of this obsolete combinator is discouraged. Instead, use the
186535065f5c renamed theory Mrec to Legacy_Mrec, no longer included by default
krauss
parents: 44890
diff changeset
     9
  @{text "partal_function (heap)"} command.
186535065f5c renamed theory Mrec to Legacy_Mrec, no longer included by default
krauss
parents: 44890
diff changeset
    10
*}
186535065f5c renamed theory Mrec to Legacy_Mrec, no longer included by default
krauss
parents: 44890
diff changeset
    11
37772
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    12
text {* Using a locale to fix arguments f and g of MREC *}
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    13
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    14
locale mrec =
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    15
  fixes f :: "'a \<Rightarrow> ('b + 'a) Heap"
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    16
  and g :: "'a \<Rightarrow> 'a \<Rightarrow> 'b \<Rightarrow> 'b Heap"
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    17
begin
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    18
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    19
function (default "\<lambda>(x, h). None") mrec :: "'a \<Rightarrow> heap \<Rightarrow> ('b \<times> heap) option" where
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    20
  "mrec x h = (case execute (f x) h of
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    21
     Some (Inl r, h') \<Rightarrow> Some (r, h')
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    22
   | Some (Inr s, h') \<Rightarrow> (case mrec s h' of
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    23
             Some (z, h'') \<Rightarrow> execute (g x s z) h''
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    24
           | None \<Rightarrow> None)
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    25
   | None \<Rightarrow> None)"
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    26
by auto
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    27
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    28
lemma graph_implies_dom:
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    29
  "mrec_graph x y \<Longrightarrow> mrec_dom x"
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    30
apply (induct rule:mrec_graph.induct) 
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    31
apply (rule accpI)
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    32
apply (erule mrec_rel.cases)
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    33
by simp
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    34
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    35
lemma mrec_default: "\<not> mrec_dom (x, h) \<Longrightarrow> mrec x h = None"
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    36
  unfolding mrec_def 
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    37
  by (rule fundef_default_value[OF mrec_sumC_def graph_implies_dom, of _ _ "(x, h)", simplified])
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    38
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    39
lemma mrec_di_reverse: 
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    40
  assumes "\<not> mrec_dom (x, h)"
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    41
  shows "
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    42
   (case execute (f x) h of
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    43
     Some (Inl r, h') \<Rightarrow> False
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    44
   | Some (Inr s, h') \<Rightarrow> \<not> mrec_dom (s, h')
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    45
   | None \<Rightarrow> False
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    46
   )" 
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    47
using assms apply (auto split: option.split sum.split)
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    48
apply (rule ccontr)
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    49
apply (erule notE, rule accpI, elim mrec_rel.cases, auto)+
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    50
done
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    51
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    52
lemma mrec_rule:
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    53
  "mrec x h = 
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    54
   (case execute (f x) h of
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    55
     Some (Inl r, h') \<Rightarrow> Some (r, h')
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    56
   | Some (Inr s, h') \<Rightarrow> 
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    57
          (case mrec s h' of
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    58
             Some (z, h'') \<Rightarrow> execute (g x s z) h''
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    59
           | None \<Rightarrow> None)
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    60
   | None \<Rightarrow> None
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    61
   )"
39754
150f831ce4a3 no longer declare .psimps rules as [simp].
krauss
parents: 37792
diff changeset
    62
apply (cases "mrec_dom (x,h)", simp add: mrec.psimps)
37772
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    63
apply (frule mrec_default)
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    64
apply (frule mrec_di_reverse, simp)
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    65
by (auto split: sum.split option.split simp: mrec_default)
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    66
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    67
definition
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    68
  "MREC x = Heap_Monad.Heap (mrec x)"
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    69
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    70
lemma MREC_rule:
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    71
  "MREC x = 
37792
ba0bc31b90d7 Heap_Monad uses Monad_Syntax
krauss
parents: 37787
diff changeset
    72
  do { y \<leftarrow> f x;
37772
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    73
                (case y of 
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    74
                Inl r \<Rightarrow> return r
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    75
              | Inr s \<Rightarrow> 
37792
ba0bc31b90d7 Heap_Monad uses Monad_Syntax
krauss
parents: 37787
diff changeset
    76
                do { z \<leftarrow> MREC s ;
ba0bc31b90d7 Heap_Monad uses Monad_Syntax
krauss
parents: 37787
diff changeset
    77
                     g x s z })}"
37772
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    78
  unfolding MREC_def
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    79
  unfolding bind_def return_def
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    80
  apply simp
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    81
  apply (rule ext)
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    82
  apply (unfold mrec_rule[of x])
37787
30dc3abf4a58 theorem collections do not contain default rules any longer
haftmann
parents: 37772
diff changeset
    83
  by (auto simp add: execute_simps split: option.splits prod.splits sum.splits)
37772
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    84
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    85
lemma MREC_pinduct:
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    86
  assumes "execute (MREC x) h = Some (r, h')"
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    87
  assumes non_rec_case: "\<And> x h h' r. execute (f x) h = Some (Inl r, h') \<Longrightarrow> P x h h' r"
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    88
  assumes rec_case: "\<And> x h h1 h2 h' s z r. execute (f x) h = Some (Inr s, h1) \<Longrightarrow> execute (MREC s) h1 = Some (z, h2) \<Longrightarrow> P s h1 h2 z
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    89
    \<Longrightarrow> execute (g x s z) h2 = Some (r, h') \<Longrightarrow> P x h h' r"
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    90
  shows "P x h h' r"
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    91
proof -
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    92
  from assms(1) have mrec: "mrec x h = Some (r, h')"
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    93
    unfolding MREC_def execute.simps .
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    94
  from mrec have dom: "mrec_dom (x, h)"
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    95
    apply -
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    96
    apply (rule ccontr)
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    97
    apply (drule mrec_default) by auto
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    98
  from mrec have h'_r: "h' = snd (the (mrec x h))" "r = fst (the (mrec x h))"
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    99
    by auto
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   100
  from mrec have "P x h (snd (the (mrec x h))) (fst (the (mrec x h)))"
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   101
  proof (induct arbitrary: r h' rule: mrec.pinduct[OF dom])
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   102
    case (1 x h)
44890
22f665a2e91c new fastforce replacing fastsimp - less confusing name
nipkow
parents: 40671
diff changeset
   103
    obtain rr h' where "the (mrec x h) = (rr, h')" by fastforce
37772
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   104
    show ?case
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   105
    proof (cases "execute (f x) h")
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   106
      case (Some result)
44890
22f665a2e91c new fastforce replacing fastsimp - less confusing name
nipkow
parents: 40671
diff changeset
   107
      then obtain a h1 where exec_f: "execute (f x) h = Some (a, h1)" by fastforce
37772
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   108
      note Inl' = this
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   109
      show ?thesis
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   110
      proof (cases a)
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   111
        case (Inl aa)
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   112
        from this Inl' 1(1) exec_f mrec non_rec_case show ?thesis
39754
150f831ce4a3 no longer declare .psimps rules as [simp].
krauss
parents: 37792
diff changeset
   113
          by (auto simp: mrec.psimps)
37772
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   114
      next
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   115
        case (Inr b)
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   116
        note Inr' = this
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   117
        show ?thesis
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   118
        proof (cases "mrec b h1")
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   119
          case (Some result)
44890
22f665a2e91c new fastforce replacing fastsimp - less confusing name
nipkow
parents: 40671
diff changeset
   120
          then obtain aaa h2 where mrec_rec: "mrec b h1 = Some (aaa, h2)" by fastforce
53374
a14d2a854c02 tuned proofs -- clarified flow of facts wrt. calculation;
wenzelm
parents: 53109
diff changeset
   121
          moreover from mrec_rec have "P b h1 (snd (the (mrec b h1))) (fst (the (mrec b h1)))"
37772
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   122
            apply (intro 1(2))
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   123
            apply (auto simp add: Inr Inl')
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   124
            done
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   125
          moreover note mrec mrec_rec exec_f Inl' Inr' 1(1) 1(3)
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   126
          ultimately show ?thesis
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   127
            apply auto
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   128
            apply (rule rec_case)
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   129
            apply auto
39754
150f831ce4a3 no longer declare .psimps rules as [simp].
krauss
parents: 37792
diff changeset
   130
            unfolding MREC_def by (auto simp: mrec.psimps)
37772
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   131
        next
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   132
          case None
39754
150f831ce4a3 no longer declare .psimps rules as [simp].
krauss
parents: 37792
diff changeset
   133
          from this 1(1) exec_f mrec Inr' 1(3) show ?thesis by (auto simp: mrec.psimps)
37772
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   134
        qed
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   135
      qed
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   136
    next
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   137
      case None
39754
150f831ce4a3 no longer declare .psimps rules as [simp].
krauss
parents: 37792
diff changeset
   138
      from this 1(1) mrec 1(3) show ?thesis by (simp add: mrec.psimps)
37772
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   139
    qed
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   140
  qed
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   141
  from this h'_r show ?thesis by simp
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   142
qed
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   143
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   144
end
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   145
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   146
text {* Providing global versions of the constant and the theorems *}
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   147
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   148
abbreviation "MREC == mrec.MREC"
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   149
lemmas MREC_rule = mrec.MREC_rule
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   150
lemmas MREC_pinduct = mrec.MREC_pinduct
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   151
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   152
lemma MREC_induct:
40671
5e46057ba8e0 renamed slightly ambivalent crel to effect
haftmann
parents: 39754
diff changeset
   153
  assumes "effect (MREC f g x) h h' r"
5e46057ba8e0 renamed slightly ambivalent crel to effect
haftmann
parents: 39754
diff changeset
   154
  assumes "\<And> x h h' r. effect (f x) h h' (Inl r) \<Longrightarrow> P x h h' r"
5e46057ba8e0 renamed slightly ambivalent crel to effect
haftmann
parents: 39754
diff changeset
   155
  assumes "\<And> x h h1 h2 h' s z r. effect (f x) h h1 (Inr s) \<Longrightarrow> effect (MREC f g s) h1 h2 z \<Longrightarrow> P s h1 h2 z
5e46057ba8e0 renamed slightly ambivalent crel to effect
haftmann
parents: 39754
diff changeset
   156
    \<Longrightarrow> effect (g x s z) h2 h' r \<Longrightarrow> P x h h' r"
37772
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   157
  shows "P x h h' r"
40671
5e46057ba8e0 renamed slightly ambivalent crel to effect
haftmann
parents: 39754
diff changeset
   158
proof (rule MREC_pinduct[OF assms(1) [unfolded effect_def]])
37772
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   159
  fix x h h1 h2 h' s z r
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   160
  assume "Heap_Monad.execute (f x) h = Some (Inr s, h1)"
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   161
    "Heap_Monad.execute (MREC f g s) h1 = Some (z, h2)"
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   162
    "P s h1 h2 z"
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   163
    "Heap_Monad.execute (g x s z) h2 = Some (r, h')"
40671
5e46057ba8e0 renamed slightly ambivalent crel to effect
haftmann
parents: 39754
diff changeset
   164
  from assms(3) [unfolded effect_def, OF this(1) this(2) this(3) this(4)]
37772
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   165
  show "P x h h' r" .
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   166
next
40671
5e46057ba8e0 renamed slightly ambivalent crel to effect
haftmann
parents: 39754
diff changeset
   167
qed (auto simp add: assms(2)[unfolded effect_def])
37772
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   168
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   169
end