src/HOL/Extraction/Higman.thy
author berghofe
Wed, 13 Nov 2002 15:34:01 +0100
changeset 13711 5ace1cccb612
parent 13470 d2cbbad84ad3
child 13930 562fd03b266d
permissions -rw-r--r--
Removed (now unneeded) declarations of realizers for bar induction.
berghofe@13405
     1
(*  Title:      HOL/Extraction/Higman.thy
berghofe@13405
     2
    ID:         $Id$
berghofe@13405
     3
    Author:     Stefan Berghofer, TU Muenchen
berghofe@13405
     4
                Monika Seisenberger, LMU Muenchen
berghofe@13405
     5
*)
berghofe@13405
     6
berghofe@13405
     7
header {* Higman's lemma *}
berghofe@13405
     8
berghofe@13405
     9
theory Higman = Main:
berghofe@13405
    10
berghofe@13405
    11
text {*
berghofe@13405
    12
  Formalization by Stefan Berghofer and Monika Seisenberger,
berghofe@13405
    13
  based on Coquand and Fridlender \cite{Coquand93}.
berghofe@13405
    14
*}
berghofe@13405
    15
berghofe@13405
    16
datatype letter = A | B
berghofe@13405
    17
berghofe@13405
    18
consts
berghofe@13405
    19
  emb :: "(letter list \<times> letter list) set"
berghofe@13405
    20
berghofe@13405
    21
inductive emb
berghofe@13405
    22
intros
berghofe@13405
    23
  emb0 [CPure.intro]: "([], bs) \<in> emb"
berghofe@13405
    24
  emb1 [CPure.intro]: "(as, bs) \<in> emb \<Longrightarrow> (as, b # bs) \<in> emb"
berghofe@13405
    25
  emb2 [CPure.intro]: "(as, bs) \<in> emb \<Longrightarrow> (a # as, a # bs) \<in> emb"
berghofe@13405
    26
berghofe@13405
    27
consts
berghofe@13405
    28
  L :: "letter list \<Rightarrow> letter list list set"
berghofe@13405
    29
berghofe@13405
    30
inductive "L y"
berghofe@13405
    31
intros
berghofe@13405
    32
  L0 [CPure.intro]: "(w, y) \<in> emb \<Longrightarrow> w # ws \<in> L y"
berghofe@13405
    33
  L1 [CPure.intro]: "ws \<in> L y \<Longrightarrow> w # ws \<in> L y"
berghofe@13405
    34
berghofe@13405
    35
consts
berghofe@13405
    36
  good :: "letter list list set"
berghofe@13405
    37
berghofe@13405
    38
inductive good
berghofe@13405
    39
intros
berghofe@13405
    40
  good0 [CPure.intro]: "ws \<in> L w \<Longrightarrow> w # ws \<in> good"
berghofe@13405
    41
  good1 [CPure.intro]: "ws \<in> good \<Longrightarrow> w # ws \<in> good"
berghofe@13405
    42
berghofe@13405
    43
consts
berghofe@13405
    44
  R :: "letter \<Rightarrow> (letter list list \<times> letter list list) set"
berghofe@13405
    45
berghofe@13405
    46
inductive "R a"
berghofe@13405
    47
intros
berghofe@13405
    48
  R0 [CPure.intro]: "([], []) \<in> R a"
berghofe@13405
    49
  R1 [CPure.intro]: "(vs, ws) \<in> R a \<Longrightarrow> (w # vs, (a # w) # ws) \<in> R a"
berghofe@13405
    50
berghofe@13405
    51
consts
berghofe@13405
    52
  T :: "letter \<Rightarrow> (letter list list \<times> letter list list) set"
berghofe@13405
    53
berghofe@13405
    54
inductive "T a"
berghofe@13405
    55
intros
berghofe@13405
    56
  T0 [CPure.intro]: "a \<noteq> b \<Longrightarrow> (ws, zs) \<in> R b \<Longrightarrow> (w # zs, (a # w) # zs) \<in> T a"
berghofe@13405
    57
  T1 [CPure.intro]: "(ws, zs) \<in> T a \<Longrightarrow> (w # ws, (a # w) # zs) \<in> T a"
berghofe@13405
    58
  T2 [CPure.intro]: "a \<noteq> b \<Longrightarrow> (ws, zs) \<in> T a \<Longrightarrow> (ws, (b # w) # zs) \<in> T a"
berghofe@13405
    59
berghofe@13405
    60
consts
berghofe@13405
    61
  bar :: "letter list list set"
berghofe@13405
    62
berghofe@13405
    63
inductive bar
berghofe@13405
    64
intros
berghofe@13405
    65
  bar1 [CPure.intro]: "ws \<in> good \<Longrightarrow> ws \<in> bar"
berghofe@13405
    66
  bar2 [CPure.intro]: "(\<forall>w. w # ws \<in> bar) \<Longrightarrow> ws \<in> bar"
berghofe@13405
    67
berghofe@13405
    68
theorem prop1: "([] # ws) \<in> bar" by rules
berghofe@13405
    69
berghofe@13405
    70
theorem lemma1: "ws \<in> L as \<Longrightarrow> ws \<in> L (a # as)"
berghofe@13405
    71
  by (erule L.induct, rules+)
berghofe@13405
    72
berghofe@13405
    73
theorem lemma2' [rule_format]: "(vs, ws) \<in> R a \<Longrightarrow> vs \<in> L as \<longrightarrow> ws \<in> L (a # as)"
berghofe@13405
    74
  apply (erule R.induct)
berghofe@13405
    75
  apply (rule impI)
berghofe@13405
    76
  apply (erule L.elims)
berghofe@13405
    77
  apply simp+
berghofe@13405
    78
  apply (rule impI)
berghofe@13405
    79
  apply (erule L.elims)
berghofe@13405
    80
  apply simp_all
berghofe@13405
    81
  apply (rule L0)
berghofe@13405
    82
  apply (erule emb2)
berghofe@13405
    83
  apply (erule L1)
berghofe@13405
    84
  done
berghofe@13405
    85
 
berghofe@13405
    86
theorem lemma2 [rule_format]: "(vs, ws) \<in> R a \<Longrightarrow> vs \<in> good \<longrightarrow> ws \<in> good"
berghofe@13405
    87
  apply (erule R.induct)
berghofe@13405
    88
  apply rules
berghofe@13405
    89
  apply (rule impI)
berghofe@13405
    90
  apply (erule good.elims)
berghofe@13405
    91
  apply simp_all
berghofe@13405
    92
  apply (rule good0)
berghofe@13405
    93
  apply (erule lemma2')
berghofe@13405
    94
  apply assumption
berghofe@13405
    95
  apply (erule good1)
berghofe@13405
    96
  done
berghofe@13405
    97
berghofe@13405
    98
theorem lemma3' [rule_format]:
berghofe@13405
    99
    "(vs, ws) \<in> T a \<Longrightarrow> vs \<in> L as \<longrightarrow> ws \<in> L (a # as)"
berghofe@13405
   100
  apply (erule T.induct)
berghofe@13405
   101
  apply (rule impI)
berghofe@13405
   102
  apply (erule L.elims)
berghofe@13405
   103
  apply simp_all
berghofe@13405
   104
  apply (rule L0)
berghofe@13405
   105
  apply (erule emb2)
berghofe@13405
   106
  apply (rule L1)
berghofe@13405
   107
  apply (erule lemma1)
berghofe@13405
   108
  apply (rule impI)
berghofe@13405
   109
  apply (erule L.elims)
berghofe@13405
   110
  apply simp_all
berghofe@13405
   111
  apply rules+
berghofe@13405
   112
  done
berghofe@13405
   113
berghofe@13405
   114
theorem lemma3 [rule_format]: "(ws, zs) \<in> T a \<Longrightarrow> ws \<in> good \<longrightarrow> zs \<in> good"
berghofe@13405
   115
  apply (erule T.induct)
berghofe@13405
   116
  apply (rule impI)
berghofe@13405
   117
  apply (erule good.elims)
berghofe@13405
   118
  apply simp_all
berghofe@13405
   119
  apply (rule good0)
berghofe@13405
   120
  apply (erule lemma1)
berghofe@13405
   121
  apply (erule good1)
berghofe@13405
   122
  apply (rule impI)
berghofe@13405
   123
  apply (erule good.elims)
berghofe@13405
   124
  apply simp_all
berghofe@13405
   125
  apply (rule good0)
berghofe@13405
   126
  apply (erule lemma3')
berghofe@13405
   127
  apply rules+
berghofe@13405
   128
  done
berghofe@13405
   129
berghofe@13405
   130
theorem letter_cases:
berghofe@13405
   131
  "(a::letter) \<noteq> b \<Longrightarrow> (x = a \<Longrightarrow> P) \<Longrightarrow> (x = b \<Longrightarrow> P) \<Longrightarrow> P"
berghofe@13405
   132
  apply (case_tac a)
berghofe@13405
   133
  apply (case_tac b)
berghofe@13405
   134
  apply (case_tac x, simp, simp)
berghofe@13405
   135
  apply (case_tac x, simp, simp)
berghofe@13405
   136
  apply (case_tac b)
berghofe@13405
   137
  apply (case_tac x, simp, simp)
berghofe@13405
   138
  apply (case_tac x, simp, simp)
berghofe@13405
   139
  done
berghofe@13405
   140
  
berghofe@13405
   141
theorem prop2:
berghofe@13405
   142
  "xs \<in> bar \<Longrightarrow> \<forall>ys. ys \<in> bar \<longrightarrow>
berghofe@13405
   143
     (\<forall>a b zs. a \<noteq> b \<longrightarrow> (xs, zs) \<in> T a \<longrightarrow> (ys, zs) \<in> T b \<longrightarrow> zs \<in> bar)"
berghofe@13405
   144
  apply (erule bar.induct)
berghofe@13405
   145
  apply (rule allI impI)+
berghofe@13405
   146
  apply (rule bar1)
berghofe@13405
   147
  apply (rule lemma3)
berghofe@13405
   148
  apply assumption+
berghofe@13405
   149
  apply (rule allI, rule impI)
berghofe@13405
   150
  apply (erule bar.induct)
berghofe@13405
   151
  apply (rule allI impI)+
berghofe@13405
   152
  apply (rule bar1)
berghofe@13405
   153
  apply (rule lemma3, assumption, assumption)
berghofe@13405
   154
  apply (rule allI impI)+
berghofe@13405
   155
  apply (rule bar2)
berghofe@13405
   156
  apply (rule allI)
berghofe@13405
   157
  apply (induct_tac w)
berghofe@13405
   158
  apply (rule prop1)
berghofe@13405
   159
  apply (rule_tac x=aa in letter_cases, assumption)
berghofe@13405
   160
  apply hypsubst
berghofe@13405
   161
  apply (erule_tac x=list in allE)
berghofe@13405
   162
  apply (erule conjE)
berghofe@13405
   163
  apply (erule_tac x=wsa in allE, erule impE)
berghofe@13405
   164
  apply (rule bar2)
berghofe@13405
   165
  apply rules
berghofe@13405
   166
  apply (erule allE, erule allE, erule_tac x="(a # list) # zs" in allE,
berghofe@13405
   167
    erule impE, assumption)
berghofe@13405
   168
  apply (erule impE)
berghofe@13405
   169
  apply (rule T1)
berghofe@13405
   170
  apply assumption
berghofe@13405
   171
  apply (erule mp)
berghofe@13405
   172
  apply (rule T2)
berghofe@13405
   173
  apply (erule not_sym)
berghofe@13405
   174
  apply assumption
berghofe@13405
   175
  apply hypsubst
berghofe@13405
   176
  apply (rotate_tac 1)
berghofe@13405
   177
  apply (erule_tac x=list in allE)
berghofe@13405
   178
  apply (erule conjE)
berghofe@13405
   179
  apply (erule allE, erule allE, erule_tac x="(b # list) # zs" in allE,
berghofe@13405
   180
    erule impE)
berghofe@13405
   181
  apply assumption
berghofe@13405
   182
  apply (erule impE)
berghofe@13405
   183
  apply (rule T2)
berghofe@13405
   184
  apply assumption
berghofe@13405
   185
  apply assumption
berghofe@13405
   186
  apply (erule mp)
berghofe@13405
   187
  apply (rule T1)
berghofe@13405
   188
  apply assumption
berghofe@13405
   189
  done
berghofe@13405
   190
berghofe@13405
   191
theorem lemma4 [rule_format]: "(ws, zs) \<in> R a \<Longrightarrow> ws \<noteq> [] \<longrightarrow> (ws, zs) \<in> T a"
berghofe@13405
   192
  apply (erule R.induct)
berghofe@13405
   193
  apply rules
berghofe@13405
   194
  apply (rule impI)
berghofe@13405
   195
  apply (case_tac vs)
berghofe@13405
   196
  apply (erule R.elims)
berghofe@13405
   197
  apply simp
berghofe@13405
   198
  apply (case_tac a)
berghofe@13405
   199
  apply (rule_tac b=B in T0)
berghofe@13405
   200
  apply simp
berghofe@13405
   201
  apply (rule R0)
berghofe@13405
   202
  apply (rule_tac b=A in T0)
berghofe@13405
   203
  apply simp
berghofe@13405
   204
  apply (rule R0)
berghofe@13405
   205
  apply simp
berghofe@13405
   206
  apply (rule T1)
berghofe@13405
   207
  apply (erule mp)
berghofe@13405
   208
  apply simp
berghofe@13405
   209
  done
berghofe@13405
   210
berghofe@13405
   211
theorem R_nil: "([], zs) \<in> R a \<Longrightarrow> zs = []"
berghofe@13405
   212
  by (erule R.elims, simp+)
berghofe@13405
   213
berghofe@13405
   214
theorem letter_eq_dec: "(a::letter) = b \<or> a \<noteq> b"
berghofe@13405
   215
  apply (case_tac a)
berghofe@13405
   216
  apply (case_tac b)
berghofe@13405
   217
  apply simp
berghofe@13405
   218
  apply simp
berghofe@13405
   219
  apply (case_tac b)
berghofe@13405
   220
  apply simp
berghofe@13405
   221
  apply simp
berghofe@13405
   222
  done
berghofe@13405
   223
berghofe@13405
   224
theorem prop3: "xs \<in> bar \<Longrightarrow> \<forall>zs. (xs, zs) \<in> R a \<longrightarrow> zs \<in> bar"
berghofe@13405
   225
  apply (erule bar.induct)
berghofe@13405
   226
  apply (rule allI impI)+
berghofe@13405
   227
  apply (rule bar1)
berghofe@13405
   228
  apply (rule lemma2)
berghofe@13405
   229
  apply assumption+
berghofe@13405
   230
  apply (rule allI impI)+
berghofe@13405
   231
  apply (case_tac ws)
berghofe@13405
   232
  apply simp
berghofe@13405
   233
  apply (drule R_nil)
berghofe@13405
   234
  apply simp_all
berghofe@13405
   235
  apply rules
berghofe@13405
   236
  apply (rule bar2)
berghofe@13405
   237
  apply (rule allI)
berghofe@13405
   238
  apply (induct_tac w)
berghofe@13405
   239
  apply (rule prop1)
berghofe@13405
   240
  apply (rule_tac a1=aaa and b1=a in disjE [OF letter_eq_dec])
berghofe@13405
   241
  apply rules
berghofe@13405
   242
  apply (rule_tac xs="aa # list" and ys="lista # zs" and zs="(aaa # lista) # zs"
berghofe@13405
   243
    and b=aaa in prop2 [rule_format])
berghofe@13405
   244
  apply (rule bar2)
berghofe@13405
   245
  apply rules
berghofe@13405
   246
  apply assumption
berghofe@13405
   247
  apply (erule not_sym)
berghofe@13405
   248
  apply (rule T2)
berghofe@13405
   249
  apply (erule not_sym)
berghofe@13405
   250
  apply (erule lemma4)
berghofe@13405
   251
  apply simp
berghofe@13405
   252
  apply (rule T0)
berghofe@13405
   253
  apply assumption+
berghofe@13405
   254
  done
berghofe@13405
   255
berghofe@13405
   256
theorem prop5: "[w] \<in> bar"
berghofe@13405
   257
  apply (induct_tac w)
berghofe@13405
   258
  apply (rule prop1)
berghofe@13405
   259
  apply (rule prop3 [rule_format])
berghofe@13405
   260
  apply rules+
berghofe@13405
   261
  done
berghofe@13405
   262
berghofe@13405
   263
theorem higman: "[] \<in> bar"
berghofe@13405
   264
  apply (rule bar2)
berghofe@13405
   265
  apply (rule allI)
berghofe@13405
   266
  apply (rule prop5)
berghofe@13405
   267
  done
berghofe@13405
   268
berghofe@13405
   269
consts
berghofe@13405
   270
  is_prefix :: "'a list \<Rightarrow> (nat \<Rightarrow> 'a) \<Rightarrow> bool"
berghofe@13405
   271
berghofe@13405
   272
primrec
berghofe@13405
   273
  "is_prefix [] f = True"
berghofe@13405
   274
  "is_prefix (x # xs) f = (x = f (length xs) \<and> is_prefix xs f)"
berghofe@13405
   275
berghofe@13405
   276
theorem good_prefix_lemma:
berghofe@13405
   277
  "ws \<in> bar \<Longrightarrow> is_prefix ws f \<longrightarrow> (\<exists>vs. is_prefix vs f \<and> vs \<in> good)"
berghofe@13405
   278
  apply (erule bar.induct)
berghofe@13405
   279
  apply rules
berghofe@13405
   280
  apply (rule impI)
berghofe@13405
   281
  apply (erule_tac x="f (length ws)" in allE)
berghofe@13405
   282
  apply (erule conjE)
berghofe@13405
   283
  apply (erule impE)
berghofe@13405
   284
  apply simp
berghofe@13405
   285
  apply assumption
berghofe@13405
   286
  done
berghofe@13405
   287
berghofe@13405
   288
theorem good_prefix: "\<exists>vs. is_prefix vs f \<and> vs \<in> good"
berghofe@13405
   289
  apply (insert higman)
berghofe@13405
   290
  apply (drule good_prefix_lemma)
berghofe@13405
   291
  apply simp
berghofe@13405
   292
  done
berghofe@13405
   293
berghofe@13711
   294
subsection {* Extracting the program *}
berghofe@13405
   295
berghofe@13711
   296
declare bar.induct [ind_realizer]
berghofe@13405
   297
berghofe@13405
   298
extract good_prefix
berghofe@13405
   299
berghofe@13405
   300
text {*
berghofe@13405
   301
  Program extracted from the proof of @{text good_prefix}:
berghofe@13405
   302
  @{thm [display] good_prefix_def [no_vars]}
berghofe@13405
   303
  Corresponding correctness theorem:
berghofe@13405
   304
  @{thm [display] good_prefix_correctness [no_vars]}
berghofe@13405
   305
  Program extracted from the proof of @{text good_prefix_lemma}:
berghofe@13405
   306
  @{thm [display] good_prefix_lemma_def [no_vars]}
berghofe@13405
   307
  Program extracted from the proof of @{text higman}:
berghofe@13405
   308
  @{thm [display] higman_def [no_vars]}
berghofe@13405
   309
  Program extracted from the proof of @{text prop5}:
berghofe@13405
   310
  @{thm [display] prop5_def [no_vars]}
berghofe@13405
   311
  Program extracted from the proof of @{text prop1}:
berghofe@13405
   312
  @{thm [display] prop1_def [no_vars]}
berghofe@13405
   313
  Program extracted from the proof of @{text prop2}:
berghofe@13405
   314
  @{thm [display] prop2_def [no_vars]}
berghofe@13405
   315
  Program extracted from the proof of @{text prop3}:
berghofe@13405
   316
  @{thm [display] prop3_def [no_vars]}
berghofe@13405
   317
*}
berghofe@13405
   318
berghofe@13405
   319
generate_code
berghofe@13405
   320
  test = good_prefix
berghofe@13405
   321
berghofe@13405
   322
ML {*
berghofe@13405
   323
val a = 16807.0;
berghofe@13405
   324
val m = 2147483647.0;
berghofe@13405
   325
berghofe@13405
   326
fun nextRand seed =
berghofe@13405
   327
  let val t = a*seed
berghofe@13405
   328
  in  t - m * real (Real.floor(t/m)) end;
berghofe@13405
   329
berghofe@13405
   330
fun mk_word seed l =
berghofe@13405
   331
  let
berghofe@13405
   332
    val r = nextRand seed;
berghofe@13405
   333
    val i = Real.round (r / m * 10.0);
berghofe@13405
   334
  in if i > 7 andalso l > 2 then (r, []) else
berghofe@13405
   335
    apsnd (cons (if i mod 2 = 0 then A else B)) (mk_word r (l+1))
berghofe@13405
   336
  end;
berghofe@13405
   337
berghofe@13405
   338
fun f s id0 = mk_word s 0
berghofe@13405
   339
  | f s (Suc n) = f (fst (mk_word s 0)) n;
berghofe@13405
   340
berghofe@13405
   341
val g1 = snd o (f 20000.0);
berghofe@13405
   342
berghofe@13405
   343
val g2 = snd o (f 50000.0);
berghofe@13405
   344
berghofe@13405
   345
fun f1 id0 = [A,A]
berghofe@13405
   346
  | f1 (Suc id0) = [B]
berghofe@13405
   347
  | f1 (Suc (Suc id0)) = [A,B]
berghofe@13405
   348
  | f1 _ = [];
berghofe@13405
   349
berghofe@13405
   350
fun f2 id0 = [A,A]
berghofe@13405
   351
  | f2 (Suc id0) = [B]
berghofe@13405
   352
  | f2 (Suc (Suc id0)) = [B,A]
berghofe@13405
   353
  | f2 _ = [];
berghofe@13405
   354
berghofe@13405
   355
val xs1 = test g1;
berghofe@13405
   356
val xs2 = test g2;
berghofe@13405
   357
val xs3 = test f1;
berghofe@13405
   358
val xs4 = test f2;
berghofe@13405
   359
*}
berghofe@13405
   360
berghofe@13405
   361
end