doc-src/TutorialI/Overview/LNCS/FP1.thy
author chaieb
Wed, 19 May 2004 11:23:59 +0200
changeset 14758 af3b71a46a1c
parent 14138 ca5029d391d1
child 17656 a8b83a82c4c6
permissions -rw-r--r--
A new implementation for presburger arithmetic following the one suggested in technical report Chaieb Amine and Tobias Nipkow. It is generic an smaller. the tactic has also changed and allows the abstaction over fuction occurences whose type is nat or int.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
13262
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
     1
(*<*)theory FP1 = Main:(*>*)
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
     2
14138
ca5029d391d1 *** empty log message ***
nipkow
parents: 13489
diff changeset
     3
subsection{*Quickcheck*}
ca5029d391d1 *** empty log message ***
nipkow
parents: 13489
diff changeset
     4
ca5029d391d1 *** empty log message ***
nipkow
parents: 13489
diff changeset
     5
lemma "rev(xs @ ys) = rev xs @ rev ys"
ca5029d391d1 *** empty log message ***
nipkow
parents: 13489
diff changeset
     6
quickcheck
ca5029d391d1 *** empty log message ***
nipkow
parents: 13489
diff changeset
     7
oops
ca5029d391d1 *** empty log message ***
nipkow
parents: 13489
diff changeset
     8
ca5029d391d1 *** empty log message ***
nipkow
parents: 13489
diff changeset
     9
subsection{*More Syntax*}
ca5029d391d1 *** empty log message ***
nipkow
parents: 13489
diff changeset
    10
13262
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    11
lemma "if xs = ys
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    12
       then rev xs = rev ys
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    13
       else rev xs \<noteq> rev ys"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    14
by auto
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    15
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    16
lemma "case xs of
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    17
         []   \<Rightarrow> tl xs = xs
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    18
       | y#ys \<Rightarrow> tl xs \<noteq> xs"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    19
apply(case_tac xs)
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    20
by auto
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    21
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    22
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    23
subsection{*More Types*}
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    24
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    25
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    26
subsubsection{*Natural Numbers*}
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    27
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    28
consts sum :: "nat \<Rightarrow> nat"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    29
primrec "sum 0 = 0"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    30
        "sum (Suc n) = Suc n + sum n"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    31
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    32
lemma "sum n + sum n = n*(Suc n)"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    33
apply(induct_tac n)
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    34
apply(auto)
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    35
done
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    36
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    37
text{*Some examples of linear arithmetic:*}
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    38
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    39
lemma "\<lbrakk> \<not> m < n; m < n+(1::int) \<rbrakk> \<Longrightarrow> m = n"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    40
by(auto)
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    41
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    42
lemma "min i (max j k) = max (min k i) (min i (j::nat))"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    43
by(arith)
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    44
14138
ca5029d391d1 *** empty log message ***
nipkow
parents: 13489
diff changeset
    45
text{*Full Presburger arithmetic:*}
ca5029d391d1 *** empty log message ***
nipkow
parents: 13489
diff changeset
    46
lemma "8 \<le> (n::int) \<Longrightarrow> \<exists>i j. 0\<le>i \<and> 0\<le>j \<and> n = 3*i + 5*j"
ca5029d391d1 *** empty log message ***
nipkow
parents: 13489
diff changeset
    47
by(arith)
ca5029d391d1 *** empty log message ***
nipkow
parents: 13489
diff changeset
    48
13262
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    49
text{*Not proved automatically because it involves multiplication:*}
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    50
lemma "n*n = n \<Longrightarrow> n=0 \<or> n=(1::int)"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    51
(*<*)oops(*>*)
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    52
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    53
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    54
subsubsection{*Pairs*}
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    55
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    56
lemma "fst(x,y) = snd(z,x)"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    57
by auto
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    58
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    59
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    60
subsection{*Definitions*}
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    61
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    62
consts xor :: "bool \<Rightarrow> bool \<Rightarrow> bool"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    63
defs xor_def: "xor x y \<equiv> x \<and> \<not>y \<or> \<not>x \<and> y"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    64
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    65
constdefs nand :: "bool \<Rightarrow> bool \<Rightarrow> bool"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    66
         "nand x y \<equiv> \<not>(x \<and> y)"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    67
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    68
lemma "\<not> xor x x"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    69
apply(unfold xor_def)
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    70
by auto
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    71
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    72
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    73
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    74
subsection{*Simplification*}
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    75
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    76
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    77
subsubsection{*Simplification Rules*}
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    78
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    79
lemma fst_conv[simp]: "fst(x,y) = x"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    80
by auto
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    81
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    82
text{*Setting and resetting the @{text simp} attribute:*}
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    83
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    84
declare fst_conv[simp]
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    85
declare fst_conv[simp del]
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    86
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    87
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    88
subsubsection{*The Simplification Method*}
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    89
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    90
lemma "x*(y+1) = y*(x+1::nat)"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    91
apply simp
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    92
(*<*)oops(*>*)
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    93
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    94
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    95
subsubsection{*Adding and Deleting Simplification Rules*}
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    96
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    97
lemma "\<forall>x::nat. x*(y+z) = r"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    98
apply (simp add: add_mult_distrib2)
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
    99
(*<*)oops(*>*)text_raw{* \isanewline\isanewline *}
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   100
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   101
lemma "rev(rev(xs @ [])) = xs"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   102
apply (simp del: rev_rev_ident)
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   103
(*<*)oops(*>*)
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   104
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   105
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   106
subsubsection{*Rewriting with Definitions*}
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   107
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   108
lemma "xor A (\<not>A)"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   109
apply(simp only: xor_def)
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   110
apply simp
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   111
done
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   112
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   113
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   114
subsubsection{*Conditional Equations*}
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   115
13489
79d117a158bd *** empty log message ***
nipkow
parents: 13262
diff changeset
   116
(*<*)thm hd_Cons_tl(*>*)
79d117a158bd *** empty log message ***
nipkow
parents: 13262
diff changeset
   117
text{*A pre-proved simplification rule: @{thm hd_Cons_tl[no_vars]}*}
79d117a158bd *** empty log message ***
nipkow
parents: 13262
diff changeset
   118
lemma "hd(xs @ [x]) # tl(xs @ [x]) = xs @ [x]"
13262
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   119
by simp
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   120
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   121
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   122
subsubsection{*Automatic Case Splits*}
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   123
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   124
lemma "\<forall>xs. if xs = [] then A else B"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   125
apply simp
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   126
(*<*)oops(*>*)
13489
79d117a158bd *** empty log message ***
nipkow
parents: 13262
diff changeset
   127
text{*Case-expressions are only split on demand.*}
13262
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   128
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   129
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   130
subsubsection{*Arithmetic*}
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   131
13489
79d117a158bd *** empty log message ***
nipkow
parents: 13262
diff changeset
   132
text{*Only simple arithmetic:*}
13262
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   133
lemma "\<lbrakk> \<not> m < n; m < n+(1::nat) \<rbrakk> \<Longrightarrow> m = n"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   134
by simp
13489
79d117a158bd *** empty log message ***
nipkow
parents: 13262
diff changeset
   135
text{*\noindent Complex goals need @{text arith}-method.*}
13262
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   136
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   137
(*<*)
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   138
subsubsection{*Tracing*}
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   139
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   140
lemma "rev [a] = []"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   141
apply(simp)
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   142
oops
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   143
(*>*)
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   144
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   145
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   146
subsection{*Case Study: Compiling Expressions*}
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   147
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   148
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   149
subsubsection{*Expressions*}
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   150
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   151
types 'v binop = "'v \<Rightarrow> 'v \<Rightarrow> 'v"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   152
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   153
datatype ('a,'v)expr = Cex 'v
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   154
                     | Vex 'a
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   155
                     | Bex "'v binop"  "('a,'v)expr"  "('a,'v)expr"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   156
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   157
consts value :: "('a,'v)expr \<Rightarrow> ('a \<Rightarrow> 'v) \<Rightarrow> 'v"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   158
primrec
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   159
"value (Cex v) env = v"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   160
"value (Vex a) env = env a"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   161
"value (Bex f e1 e2) env = f (value e1 env) (value e2 env)"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   162
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   163
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   164
subsubsection{*The Stack Machine*}
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   165
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   166
datatype ('a,'v) instr = Const 'v
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   167
                       | Load 'a
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   168
                       | Apply "'v binop"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   169
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   170
consts exec :: "('a,'v)instr list \<Rightarrow> ('a\<Rightarrow>'v) \<Rightarrow> 'v list \<Rightarrow> 'v list"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   171
primrec
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   172
"exec [] s vs = vs"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   173
"exec (i#is) s vs = (case i of
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   174
    Const v  \<Rightarrow> exec is s (v#vs)
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   175
  | Load a   \<Rightarrow> exec is s ((s a)#vs)
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   176
  | Apply f  \<Rightarrow> exec is s ((f (hd vs) (hd(tl vs)))#(tl(tl vs))))"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   177
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   178
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   179
subsubsection{*The Compiler*}
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   180
14138
ca5029d391d1 *** empty log message ***
nipkow
parents: 13489
diff changeset
   181
consts compile :: "('a,'v)expr \<Rightarrow> ('a,'v)instr list"
13262
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   182
primrec
14138
ca5029d391d1 *** empty log message ***
nipkow
parents: 13489
diff changeset
   183
"compile (Cex v)       = [Const v]"
ca5029d391d1 *** empty log message ***
nipkow
parents: 13489
diff changeset
   184
"compile (Vex a)       = [Load a]"
ca5029d391d1 *** empty log message ***
nipkow
parents: 13489
diff changeset
   185
"compile (Bex f e1 e2) = (compile e2) @ (compile e1) @ [Apply f]"
13262
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   186
14138
ca5029d391d1 *** empty log message ***
nipkow
parents: 13489
diff changeset
   187
theorem "exec (compile e) s [] = [value e s]"
13262
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   188
(*<*)oops(*>*)
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   189
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   190
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   191
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   192
subsection{*Advanced Datatypes*}
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   193
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   194
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   195
subsubsection{*Mutual Recursion*}
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   196
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   197
datatype 'a aexp = IF   "'a bexp" "'a aexp" "'a aexp"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   198
                 | Sum  "'a aexp" "'a aexp"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   199
                 | Var 'a
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   200
                 | Num nat
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   201
and      'a bexp = Less "'a aexp" "'a aexp"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   202
                 | And  "'a bexp" "'a bexp"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   203
                 | Neg  "'a bexp"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   204
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   205
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   206
consts  evala :: "'a aexp \<Rightarrow> ('a \<Rightarrow> nat) \<Rightarrow> nat"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   207
        evalb :: "'a bexp \<Rightarrow> ('a \<Rightarrow> nat) \<Rightarrow> bool"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   208
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   209
primrec
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   210
  "evala (IF b a1 a2) env =
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   211
     (if evalb b env then evala a1 env else evala a2 env)"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   212
  "evala (Sum a1 a2) env = evala a1 env + evala a2 env"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   213
  "evala (Var v) env = env v"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   214
  "evala (Num n) env = n"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   215
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   216
  "evalb (Less a1 a2) env = (evala a1 env < evala a2 env)"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   217
  "evalb (And b1 b2) env = (evalb b1 env \<and> evalb b2 env)"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   218
  "evalb (Neg b) env = (\<not> evalb b env)"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   219
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   220
consts substa :: "('a \<Rightarrow> 'b aexp) \<Rightarrow> 'a aexp \<Rightarrow> 'b aexp"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   221
       substb :: "('a \<Rightarrow> 'b aexp) \<Rightarrow> 'a bexp \<Rightarrow> 'b bexp"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   222
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   223
primrec
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   224
  "substa s (IF b a1 a2) =
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   225
     IF (substb s b) (substa s a1) (substa s a2)"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   226
  "substa s (Sum a1 a2) = Sum (substa s a1) (substa s a2)"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   227
  "substa s (Var v) = s v"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   228
  "substa s (Num n) = Num n"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   229
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   230
  "substb s (Less a1 a2) = Less (substa s a1) (substa s a2)"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   231
  "substb s (And b1 b2) = And (substb s b1) (substb s b2)"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   232
  "substb s (Neg b) = Neg (substb s b)"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   233
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   234
lemma substitution_lemma:
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   235
 "evala (substa s a) env = evala a (\<lambda>x. evala (s x) env) \<and>
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   236
  evalb (substb s b) env = evalb b (\<lambda>x. evala (s x) env)"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   237
apply(induct_tac a and b)
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   238
by simp_all
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   239
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   240
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   241
subsubsection{*Nested Recursion*}
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   242
14138
ca5029d391d1 *** empty log message ***
nipkow
parents: 13489
diff changeset
   243
datatype tree = Tree "tree list"
13262
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   244
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   245
text{*Some trees:*}
14138
ca5029d391d1 *** empty log message ***
nipkow
parents: 13489
diff changeset
   246
term "Tree []"
ca5029d391d1 *** empty log message ***
nipkow
parents: 13489
diff changeset
   247
term "Tree [Tree [Tree []], Tree []]"
13262
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   248
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   249
consts
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   250
mirror :: "tree \<Rightarrow> tree"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   251
mirrors:: "tree list \<Rightarrow> tree list"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   252
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   253
primrec
14138
ca5029d391d1 *** empty log message ***
nipkow
parents: 13489
diff changeset
   254
  "mirror(Tree ts) = Tree(mirrors ts)"
13262
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   255
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   256
  "mirrors [] = []"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   257
  "mirrors (t # ts) = mirrors ts @ [mirror t]"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   258
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   259
lemma "mirror(mirror t) = t \<and> mirrors(mirrors ts) = ts"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   260
apply(induct_tac t and ts)
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   261
apply simp_all
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   262
(*<*)oops(*>*)
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   263
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   264
text{*
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   265
\begin{exercise}
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   266
Complete the above proof.
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   267
\end{exercise}
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   268
*}
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   269
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   270
subsubsection{*Datatypes Involving Functions*}
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   271
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   272
datatype ('a,'i)bigtree = Tip | Br 'a "'i \<Rightarrow> ('a,'i)bigtree"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   273
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   274
text{*A big tree:*}
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   275
term "Br 0 (\<lambda>i. Br i (\<lambda>n. Tip))"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   276
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   277
consts map_bt :: "('a \<Rightarrow> 'b) \<Rightarrow> ('a,'i)bigtree \<Rightarrow> ('b,'i)bigtree"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   278
primrec
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   279
"map_bt f Tip      = Tip"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   280
"map_bt f (Br a F) = Br (f a) (\<lambda>i. map_bt f (F i))"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   281
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   282
lemma "map_bt (g o f) T = map_bt g (map_bt f T)"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   283
apply(induct_tac T, rename_tac[2] F)
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   284
apply simp_all
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   285
done
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   286
14138
ca5029d391d1 *** empty log message ***
nipkow
parents: 13489
diff changeset
   287
text{*The ordinals:*}
ca5029d391d1 *** empty log message ***
nipkow
parents: 13489
diff changeset
   288
datatype ord = Zero | Succ ord | Lim "nat \<Rightarrow> ord"
ca5029d391d1 *** empty log message ***
nipkow
parents: 13489
diff changeset
   289
ca5029d391d1 *** empty log message ***
nipkow
parents: 13489
diff changeset
   290
thm ord.induct[no_vars]
ca5029d391d1 *** empty log message ***
nipkow
parents: 13489
diff changeset
   291
ca5029d391d1 *** empty log message ***
nipkow
parents: 13489
diff changeset
   292
instance ord :: plus ..
ca5029d391d1 *** empty log message ***
nipkow
parents: 13489
diff changeset
   293
instance ord :: times ..
ca5029d391d1 *** empty log message ***
nipkow
parents: 13489
diff changeset
   294
ca5029d391d1 *** empty log message ***
nipkow
parents: 13489
diff changeset
   295
primrec
ca5029d391d1 *** empty log message ***
nipkow
parents: 13489
diff changeset
   296
"a + Zero   = a"
ca5029d391d1 *** empty log message ***
nipkow
parents: 13489
diff changeset
   297
"a + Succ b = Succ(a+b)"
ca5029d391d1 *** empty log message ***
nipkow
parents: 13489
diff changeset
   298
"a + Lim F  = Lim(\<lambda>n. a + F n)"
ca5029d391d1 *** empty log message ***
nipkow
parents: 13489
diff changeset
   299
ca5029d391d1 *** empty log message ***
nipkow
parents: 13489
diff changeset
   300
primrec
ca5029d391d1 *** empty log message ***
nipkow
parents: 13489
diff changeset
   301
"a * Zero   = Zero"
ca5029d391d1 *** empty log message ***
nipkow
parents: 13489
diff changeset
   302
"a * Succ b = a*b + a"
ca5029d391d1 *** empty log message ***
nipkow
parents: 13489
diff changeset
   303
"a * Lim F  = Lim(\<lambda>n. a * F n)"
ca5029d391d1 *** empty log message ***
nipkow
parents: 13489
diff changeset
   304
ca5029d391d1 *** empty log message ***
nipkow
parents: 13489
diff changeset
   305
text{*An example provided by Stan Wainer:*}
ca5029d391d1 *** empty log message ***
nipkow
parents: 13489
diff changeset
   306
consts H :: "ord \<Rightarrow> (nat \<Rightarrow> nat) \<Rightarrow> (nat \<Rightarrow> nat)"
ca5029d391d1 *** empty log message ***
nipkow
parents: 13489
diff changeset
   307
primrec
ca5029d391d1 *** empty log message ***
nipkow
parents: 13489
diff changeset
   308
"H Zero     f n = n"
ca5029d391d1 *** empty log message ***
nipkow
parents: 13489
diff changeset
   309
"H (Succ b) f n = H b f (f n)"
ca5029d391d1 *** empty log message ***
nipkow
parents: 13489
diff changeset
   310
"H (Lim F)  f n = H (F n) f n"
ca5029d391d1 *** empty log message ***
nipkow
parents: 13489
diff changeset
   311
ca5029d391d1 *** empty log message ***
nipkow
parents: 13489
diff changeset
   312
lemma [simp]: "H (a+b) f = H a f \<circ> H b f"
ca5029d391d1 *** empty log message ***
nipkow
parents: 13489
diff changeset
   313
apply(induct b)
ca5029d391d1 *** empty log message ***
nipkow
parents: 13489
diff changeset
   314
apply auto
ca5029d391d1 *** empty log message ***
nipkow
parents: 13489
diff changeset
   315
done
ca5029d391d1 *** empty log message ***
nipkow
parents: 13489
diff changeset
   316
ca5029d391d1 *** empty log message ***
nipkow
parents: 13489
diff changeset
   317
lemma [simp]: "H (a*b) = H b \<circ> H a"
ca5029d391d1 *** empty log message ***
nipkow
parents: 13489
diff changeset
   318
apply(induct b)
ca5029d391d1 *** empty log message ***
nipkow
parents: 13489
diff changeset
   319
apply auto
ca5029d391d1 *** empty log message ***
nipkow
parents: 13489
diff changeset
   320
done
ca5029d391d1 *** empty log message ***
nipkow
parents: 13489
diff changeset
   321
13262
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   322
text{* This is \emph{not} allowed:
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   323
\begin{verbatim}
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   324
datatype lambda = C "lambda => lambda"
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   325
\end{verbatim}
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   326
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   327
\begin{exercise}
14138
ca5029d391d1 *** empty log message ***
nipkow
parents: 13489
diff changeset
   328
Define the ordinal $\Gamma_0$.
13262
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   329
\end{exercise}
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   330
*}
bbfc360db011 *** empty log message ***
nipkow
parents:
diff changeset
   331
(*<*)end(*>*)