src/HOL/Imperative_HOL/Mrec.thy
author krauss
Tue, 28 Sep 2010 09:54:07 +0200
changeset 39754 150f831ce4a3
parent 37792 ba0bc31b90d7
child 40671 5e46057ba8e0
permissions -rw-r--r--
no longer declare .psimps rules as [simp]. This regularly caused confusion (e.g., they show up in simp traces when the regular simp rules are disabled). In the few places where the rules are used, explicitly mentioning them actually clarifies the proof text.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
37772
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
     1
theory Mrec
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
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
     7
text {* Using a locale to fix arguments f and g of MREC *}
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
     8
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
     9
locale mrec =
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    10
  fixes f :: "'a \<Rightarrow> ('b + 'a) Heap"
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    11
  and g :: "'a \<Rightarrow> 'a \<Rightarrow> 'b \<Rightarrow> 'b Heap"
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    12
begin
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    13
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    14
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
    15
  "mrec x h = (case execute (f x) h of
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    16
     Some (Inl r, h') \<Rightarrow> Some (r, h')
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    17
   | Some (Inr s, h') \<Rightarrow> (case mrec s h' of
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    18
             Some (z, h'') \<Rightarrow> execute (g x s z) h''
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    19
           | None \<Rightarrow> None)
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    20
   | None \<Rightarrow> None)"
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    21
by auto
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    22
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    23
lemma graph_implies_dom:
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    24
  "mrec_graph x y \<Longrightarrow> mrec_dom x"
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    25
apply (induct rule:mrec_graph.induct) 
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    26
apply (rule accpI)
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    27
apply (erule mrec_rel.cases)
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    28
by simp
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    29
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    30
lemma mrec_default: "\<not> mrec_dom (x, h) \<Longrightarrow> mrec x h = None"
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    31
  unfolding mrec_def 
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    32
  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
    33
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    34
lemma mrec_di_reverse: 
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    35
  assumes "\<not> mrec_dom (x, h)"
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    36
  shows "
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    37
   (case execute (f x) h of
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    38
     Some (Inl r, h') \<Rightarrow> False
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    39
   | Some (Inr s, h') \<Rightarrow> \<not> mrec_dom (s, h')
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    40
   | None \<Rightarrow> False
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    41
   )" 
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    42
using assms apply (auto split: option.split sum.split)
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    43
apply (rule ccontr)
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    44
apply (erule notE, rule accpI, elim mrec_rel.cases, auto)+
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    45
done
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    46
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    47
lemma mrec_rule:
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    48
  "mrec x h = 
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    49
   (case execute (f x) h of
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    50
     Some (Inl r, h') \<Rightarrow> Some (r, h')
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    51
   | Some (Inr s, h') \<Rightarrow> 
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    52
          (case mrec s h' of
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    53
             Some (z, h'') \<Rightarrow> execute (g x s z) h''
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    54
           | None \<Rightarrow> None)
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    55
   | None \<Rightarrow> None
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    56
   )"
39754
150f831ce4a3 no longer declare .psimps rules as [simp].
krauss
parents: 37792
diff changeset
    57
apply (cases "mrec_dom (x,h)", simp add: mrec.psimps)
37772
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    58
apply (frule mrec_default)
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    59
apply (frule mrec_di_reverse, simp)
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    60
by (auto split: sum.split option.split simp: mrec_default)
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    61
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    62
definition
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    63
  "MREC x = Heap_Monad.Heap (mrec x)"
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    64
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    65
lemma MREC_rule:
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    66
  "MREC x = 
37792
ba0bc31b90d7 Heap_Monad uses Monad_Syntax
krauss
parents: 37787
diff changeset
    67
  do { y \<leftarrow> f x;
37772
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    68
                (case y of 
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    69
                Inl r \<Rightarrow> return r
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    70
              | Inr s \<Rightarrow> 
37792
ba0bc31b90d7 Heap_Monad uses Monad_Syntax
krauss
parents: 37787
diff changeset
    71
                do { z \<leftarrow> MREC s ;
ba0bc31b90d7 Heap_Monad uses Monad_Syntax
krauss
parents: 37787
diff changeset
    72
                     g x s z })}"
37772
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    73
  unfolding MREC_def
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    74
  unfolding bind_def return_def
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    75
  apply simp
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    76
  apply (rule ext)
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    77
  apply (unfold mrec_rule[of x])
37787
30dc3abf4a58 theorem collections do not contain default rules any longer
haftmann
parents: 37772
diff changeset
    78
  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
    79
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    80
lemma MREC_pinduct:
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    81
  assumes "execute (MREC x) h = Some (r, h')"
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    82
  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
    83
  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
    84
    \<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
    85
  shows "P x h h' r"
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    86
proof -
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    87
  from assms(1) have mrec: "mrec x h = Some (r, h')"
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    88
    unfolding MREC_def execute.simps .
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    89
  from mrec have dom: "mrec_dom (x, h)"
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    90
    apply -
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    91
    apply (rule ccontr)
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    92
    apply (drule mrec_default) by auto
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    93
  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
    94
    by auto
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    95
  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
    96
  proof (induct arbitrary: r h' rule: mrec.pinduct[OF dom])
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    97
    case (1 x h)
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    98
    obtain rr h' where "the (mrec x h) = (rr, h')" by fastsimp
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
    99
    show ?case
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   100
    proof (cases "execute (f x) h")
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   101
      case (Some result)
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   102
      then obtain a h1 where exec_f: "execute (f x) h = Some (a, h1)" by fastsimp
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   103
      note Inl' = this
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   104
      show ?thesis
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   105
      proof (cases a)
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   106
        case (Inl aa)
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   107
        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
   108
          by (auto simp: mrec.psimps)
37772
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   109
      next
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   110
        case (Inr b)
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   111
        note Inr' = this
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   112
        show ?thesis
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   113
        proof (cases "mrec b h1")
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   114
          case (Some result)
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   115
          then obtain aaa h2 where mrec_rec: "mrec b h1 = Some (aaa, h2)" by fastsimp
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   116
          moreover from this have "P b h1 (snd (the (mrec b h1))) (fst (the (mrec b h1)))"
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   117
            apply (intro 1(2))
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   118
            apply (auto simp add: Inr Inl')
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   119
            done
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   120
          moreover note mrec mrec_rec exec_f Inl' Inr' 1(1) 1(3)
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   121
          ultimately show ?thesis
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   122
            apply auto
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   123
            apply (rule rec_case)
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   124
            apply auto
39754
150f831ce4a3 no longer declare .psimps rules as [simp].
krauss
parents: 37792
diff changeset
   125
            unfolding MREC_def by (auto simp: mrec.psimps)
37772
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   126
        next
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   127
          case None
39754
150f831ce4a3 no longer declare .psimps rules as [simp].
krauss
parents: 37792
diff changeset
   128
          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
   129
        qed
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   130
      qed
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) mrec 1(3) show ?thesis by (simp add: 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
  from this h'_r show ?thesis by simp
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   137
qed
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   138
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   139
end
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   140
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   141
text {* Providing global versions of the constant and the theorems *}
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   142
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   143
abbreviation "MREC == mrec.MREC"
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   144
lemmas MREC_rule = mrec.MREC_rule
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   145
lemmas MREC_pinduct = mrec.MREC_pinduct
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   146
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   147
lemma MREC_induct:
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   148
  assumes "crel (MREC f g x) h h' r"
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   149
  assumes "\<And> x h h' r. crel (f x) h h' (Inl r) \<Longrightarrow> P x h h' r"
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   150
  assumes "\<And> x h h1 h2 h' s z r. crel (f x) h h1 (Inr s) \<Longrightarrow> crel (MREC f g s) h1 h2 z \<Longrightarrow> P s h1 h2 z
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   151
    \<Longrightarrow> crel (g x s z) h2 h' r \<Longrightarrow> P x h h' r"
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   152
  shows "P x h h' r"
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   153
proof (rule MREC_pinduct[OF assms(1) [unfolded crel_def]])
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   154
  fix x h h1 h2 h' s z r
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   155
  assume "Heap_Monad.execute (f x) h = Some (Inr s, h1)"
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   156
    "Heap_Monad.execute (MREC f g s) h1 = Some (z, h2)"
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   157
    "P s h1 h2 z"
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   158
    "Heap_Monad.execute (g x s z) h2 = Some (r, h')"
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   159
  from assms(3) [unfolded crel_def, OF this(1) this(2) this(3) this(4)]
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   160
  show "P x h h' r" .
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   161
next
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   162
qed (auto simp add: assms(2)[unfolded crel_def])
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   163
026ed2fc15d4 split off mrec into separate theory
haftmann
parents:
diff changeset
   164
end