src/HOL/Library/Nested_Environment.thy
author haftmann
Fri, 10 Oct 2008 06:45:53 +0200
changeset 28562 4e74209f113e
parent 28228 7ebe8dc06cbb
child 30663 0b6aff7451b2
permissions -rw-r--r--
`code func` now just `code`
wenzelm@10943
     1
(*  Title:      HOL/Library/Nested_Environment.thy
wenzelm@10943
     2
    ID:         $Id$
wenzelm@10943
     3
    Author:     Markus Wenzel, TU Muenchen
wenzelm@10943
     4
*)
wenzelm@10943
     5
wenzelm@14706
     6
header {* Nested environments *}
wenzelm@10943
     7
nipkow@15131
     8
theory Nested_Environment
haftmann@28228
     9
imports Plain "~~/src/HOL/List" "~~/src/HOL/Code_Eval"
nipkow@15131
    10
begin
wenzelm@10943
    11
wenzelm@10943
    12
text {*
wenzelm@10943
    13
  Consider a partial function @{term [source] "e :: 'a => 'b option"};
wenzelm@10943
    14
  this may be understood as an \emph{environment} mapping indexes
wenzelm@10943
    15
  @{typ 'a} to optional entry values @{typ 'b} (cf.\ the basic theory
wenzelm@10948
    16
  @{text Map} of Isabelle/HOL).  This basic idea is easily generalized
wenzelm@10948
    17
  to that of a \emph{nested environment}, where entries may be either
wenzelm@10948
    18
  basic values or again proper environments.  Then each entry is
wenzelm@10948
    19
  accessed by a \emph{path}, i.e.\ a list of indexes leading to its
wenzelm@10948
    20
  position within the structure.
wenzelm@10943
    21
*}
wenzelm@10943
    22
wenzelm@10943
    23
datatype ('a, 'b, 'c) env =
wenzelm@10943
    24
    Val 'a
wenzelm@10943
    25
  | Env 'b  "'c => ('a, 'b, 'c) env option"
wenzelm@10943
    26
wenzelm@10943
    27
text {*
wenzelm@10943
    28
  \medskip In the type @{typ "('a, 'b, 'c) env"} the parameter @{typ
wenzelm@10943
    29
  'a} refers to basic values (occurring in terminal positions), type
wenzelm@10943
    30
  @{typ 'b} to values associated with proper (inner) environments, and
wenzelm@10943
    31
  type @{typ 'c} with the index type for branching.  Note that there
wenzelm@10943
    32
  is no restriction on any of these types.  In particular, arbitrary
wenzelm@10943
    33
  branching may yield rather large (transfinite) tree structures.
wenzelm@10943
    34
*}
wenzelm@10943
    35
wenzelm@10943
    36
wenzelm@10943
    37
subsection {* The lookup operation *}
wenzelm@10943
    38
wenzelm@10943
    39
text {*
wenzelm@10943
    40
  Lookup in nested environments works by following a given path of
wenzelm@10943
    41
  index elements, leading to an optional result (a terminal value or
wenzelm@10943
    42
  nested environment).  A \emph{defined position} within a nested
wenzelm@10943
    43
  environment is one where @{term lookup} at its path does not yield
wenzelm@10943
    44
  @{term None}.
wenzelm@10943
    45
*}
wenzelm@10943
    46
wenzelm@10943
    47
consts
wenzelm@10943
    48
  lookup :: "('a, 'b, 'c) env => 'c list => ('a, 'b, 'c) env option"
wenzelm@10943
    49
  lookup_option :: "('a, 'b, 'c) env option => 'c list => ('a, 'b, 'c) env option"
wenzelm@10943
    50
wenzelm@10943
    51
primrec (lookup)
wenzelm@10943
    52
  "lookup (Val a) xs = (if xs = [] then Some (Val a) else None)"
wenzelm@10943
    53
  "lookup (Env b es) xs =
wenzelm@10943
    54
    (case xs of
wenzelm@10943
    55
      [] => Some (Env b es)
wenzelm@10943
    56
    | y # ys => lookup_option (es y) ys)"
wenzelm@10943
    57
  "lookup_option None xs = None"
wenzelm@10943
    58
  "lookup_option (Some e) xs = lookup e xs"
wenzelm@10943
    59
wenzelm@10943
    60
hide const lookup_option
wenzelm@10943
    61
wenzelm@10943
    62
text {*
wenzelm@10943
    63
  \medskip The characteristic cases of @{term lookup} are expressed by
wenzelm@10943
    64
  the following equalities.
wenzelm@10943
    65
*}
wenzelm@10943
    66
wenzelm@10943
    67
theorem lookup_nil: "lookup e [] = Some e"
wenzelm@10943
    68
  by (cases e) simp_all
wenzelm@10943
    69
wenzelm@10943
    70
theorem lookup_val_cons: "lookup (Val a) (x # xs) = None"
wenzelm@10943
    71
  by simp
wenzelm@10943
    72
wenzelm@10943
    73
theorem lookup_env_cons:
wenzelm@10943
    74
  "lookup (Env b es) (x # xs) =
wenzelm@10943
    75
    (case es x of
wenzelm@10943
    76
      None => None
wenzelm@10943
    77
    | Some e => lookup e xs)"
wenzelm@10943
    78
  by (cases "es x") simp_all
wenzelm@10943
    79
wenzelm@10943
    80
lemmas lookup.simps [simp del]
wenzelm@10943
    81
  and lookup_simps [simp] = lookup_nil lookup_val_cons lookup_env_cons
wenzelm@10943
    82
wenzelm@10943
    83
theorem lookup_eq:
wenzelm@10943
    84
  "lookup env xs =
wenzelm@10943
    85
    (case xs of
wenzelm@10943
    86
      [] => Some env
wenzelm@10943
    87
    | x # xs =>
wenzelm@10943
    88
      (case env of
wenzelm@10943
    89
        Val a => None
wenzelm@10943
    90
      | Env b es =>
wenzelm@10943
    91
          (case es x of
wenzelm@10943
    92
            None => None
wenzelm@10943
    93
          | Some e => lookup e xs)))"
wenzelm@10943
    94
  by (simp split: list.split env.split)
wenzelm@10943
    95
wenzelm@10943
    96
text {*
wenzelm@10943
    97
  \medskip Displaced @{term lookup} operations, relative to a certain
wenzelm@10943
    98
  base path prefix, may be reduced as follows.  There are two cases,
wenzelm@10943
    99
  depending whether the environment actually extends far enough to
wenzelm@10943
   100
  follow the base path.
wenzelm@10943
   101
*}
wenzelm@10943
   102
wenzelm@10943
   103
theorem lookup_append_none:
wenzelm@18153
   104
  assumes "lookup env xs = None"
wenzelm@18153
   105
  shows "lookup env (xs @ ys) = None"
wenzelm@23394
   106
  using assms
wenzelm@20503
   107
proof (induct xs arbitrary: env)
wenzelm@18153
   108
  case Nil
wenzelm@18153
   109
  then have False by simp
wenzelm@18153
   110
  then show ?case ..
wenzelm@18153
   111
next
wenzelm@18153
   112
  case (Cons x xs)
wenzelm@18153
   113
  show ?case
wenzelm@18153
   114
  proof (cases env)
wenzelm@18153
   115
    case Val
wenzelm@18153
   116
    then show ?thesis by simp
wenzelm@10943
   117
  next
wenzelm@18153
   118
    case (Env b es)
wenzelm@18153
   119
    show ?thesis
wenzelm@18153
   120
    proof (cases "es x")
wenzelm@18153
   121
      case None
wenzelm@18153
   122
      with Env show ?thesis by simp
wenzelm@10943
   123
    next
wenzelm@18153
   124
      case (Some e)
wenzelm@18153
   125
      note es = `es x = Some e`
wenzelm@10943
   126
      show ?thesis
wenzelm@18153
   127
      proof (cases "lookup e xs")
wenzelm@18153
   128
        case None
wenzelm@18153
   129
        then have "lookup e (xs @ ys) = None" by (rule Cons.hyps)
wenzelm@18153
   130
        with Env Some show ?thesis by simp
wenzelm@10943
   131
      next
wenzelm@18153
   132
        case Some
wenzelm@18153
   133
        with Env es have False using Cons.prems by simp
wenzelm@18153
   134
        then show ?thesis ..
wenzelm@10943
   135
      qed
wenzelm@10943
   136
    qed
wenzelm@18153
   137
  qed
wenzelm@10943
   138
qed
wenzelm@10943
   139
wenzelm@10943
   140
theorem lookup_append_some:
wenzelm@18153
   141
  assumes "lookup env xs = Some e"
wenzelm@18153
   142
  shows "lookup env (xs @ ys) = lookup e ys"
wenzelm@23394
   143
  using assms
wenzelm@20503
   144
proof (induct xs arbitrary: env e)
wenzelm@18153
   145
  case Nil
wenzelm@18153
   146
  then have "env = e" by simp
wenzelm@18153
   147
  then show "lookup env ([] @ ys) = lookup e ys" by simp
wenzelm@18153
   148
next
wenzelm@18153
   149
  case (Cons x xs)
wenzelm@18153
   150
  note asm = `lookup env (x # xs) = Some e`
wenzelm@18153
   151
  show "lookup env ((x # xs) @ ys) = lookup e ys"
wenzelm@18153
   152
  proof (cases env)
wenzelm@18153
   153
    case (Val a)
wenzelm@18153
   154
    with asm have False by simp
wenzelm@18153
   155
    then show ?thesis ..
wenzelm@10943
   156
  next
wenzelm@18153
   157
    case (Env b es)
wenzelm@18153
   158
    show ?thesis
wenzelm@18153
   159
    proof (cases "es x")
wenzelm@18153
   160
      case None
wenzelm@18153
   161
      with asm Env have False by simp
wenzelm@18153
   162
      then show ?thesis ..
wenzelm@10943
   163
    next
wenzelm@18153
   164
      case (Some e')
wenzelm@18153
   165
      note es = `es x = Some e'`
wenzelm@10943
   166
      show ?thesis
wenzelm@18153
   167
      proof (cases "lookup e' xs")
wenzelm@18153
   168
        case None
wenzelm@18153
   169
        with asm Env es have False by simp
wenzelm@18153
   170
        then show ?thesis ..
wenzelm@10943
   171
      next
wenzelm@18153
   172
        case Some
wenzelm@18153
   173
        with asm Env es have "lookup e' xs = Some e"
wenzelm@18153
   174
          by simp
wenzelm@18153
   175
        then have "lookup e' (xs @ ys) = lookup e ys" by (rule Cons.hyps)
wenzelm@18153
   176
        with Env es show ?thesis by simp
wenzelm@10943
   177
      qed
wenzelm@10943
   178
    qed
wenzelm@18153
   179
  qed
wenzelm@10943
   180
qed
wenzelm@10943
   181
wenzelm@10943
   182
text {*
wenzelm@10943
   183
  \medskip Successful @{term lookup} deeper down an environment
wenzelm@10943
   184
  structure means we are able to peek further up as well.  Note that
wenzelm@10943
   185
  this is basically just the contrapositive statement of @{thm
wenzelm@10943
   186
  [source] lookup_append_none} above.
wenzelm@10943
   187
*}
wenzelm@10943
   188
wenzelm@10943
   189
theorem lookup_some_append:
wenzelm@18153
   190
  assumes "lookup env (xs @ ys) = Some e"
wenzelm@18153
   191
  shows "\<exists>e. lookup env xs = Some e"
wenzelm@10943
   192
proof -
wenzelm@23394
   193
  from assms have "lookup env (xs @ ys) \<noteq> None" by simp
wenzelm@18153
   194
  then have "lookup env xs \<noteq> None"
wenzelm@10943
   195
    by (rule contrapos_nn) (simp only: lookup_append_none)
nipkow@18576
   196
  then show ?thesis by (simp)
wenzelm@10943
   197
qed
wenzelm@10943
   198
wenzelm@10943
   199
text {*
wenzelm@10943
   200
  The subsequent statement describes in more detail how a successful
wenzelm@10943
   201
  @{term lookup} with a non-empty path results in a certain situation
wenzelm@10943
   202
  at any upper position.
wenzelm@10943
   203
*}
wenzelm@10943
   204
wenzelm@18153
   205
theorem lookup_some_upper:
wenzelm@18153
   206
  assumes "lookup env (xs @ y # ys) = Some e"
wenzelm@18153
   207
  shows "\<exists>b' es' env'.
wenzelm@18153
   208
    lookup env xs = Some (Env b' es') \<and>
wenzelm@18153
   209
    es' y = Some env' \<and>
wenzelm@18153
   210
    lookup env' ys = Some e"
wenzelm@23394
   211
  using assms
wenzelm@20503
   212
proof (induct xs arbitrary: env e)
wenzelm@18153
   213
  case Nil
wenzelm@18153
   214
  from Nil.prems have "lookup env (y # ys) = Some e"
wenzelm@18153
   215
    by simp
wenzelm@18153
   216
  then obtain b' es' env' where
wenzelm@18153
   217
      env: "env = Env b' es'" and
wenzelm@18153
   218
      es': "es' y = Some env'" and
wenzelm@18153
   219
      look': "lookup env' ys = Some e"
wenzelm@18153
   220
    by (auto simp add: lookup_eq split: option.splits env.splits)
wenzelm@18153
   221
  from env have "lookup env [] = Some (Env b' es')" by simp
wenzelm@18153
   222
  with es' look' show ?case by blast
wenzelm@18153
   223
next
wenzelm@18153
   224
  case (Cons x xs)
wenzelm@18153
   225
  from Cons.prems
wenzelm@18153
   226
  obtain b' es' env' where
wenzelm@18153
   227
      env: "env = Env b' es'" and
wenzelm@18153
   228
      es': "es' x = Some env'" and
wenzelm@18153
   229
      look': "lookup env' (xs @ y # ys) = Some e"
wenzelm@18153
   230
    by (auto simp add: lookup_eq split: option.splits env.splits)
wenzelm@18153
   231
  from Cons.hyps [OF look'] obtain b'' es'' env'' where
wenzelm@18153
   232
      upper': "lookup env' xs = Some (Env b'' es'')" and
wenzelm@18153
   233
      es'': "es'' y = Some env''" and
wenzelm@18153
   234
      look'': "lookup env'' ys = Some e"
wenzelm@18153
   235
    by blast
wenzelm@18153
   236
  from env es' upper' have "lookup env (x # xs) = Some (Env b'' es'')"
wenzelm@18153
   237
    by simp
wenzelm@18153
   238
  with es'' look'' show ?case by blast
wenzelm@10943
   239
qed
wenzelm@10943
   240
wenzelm@10943
   241
wenzelm@10943
   242
subsection {* The update operation *}
wenzelm@10943
   243
wenzelm@10943
   244
text {*
wenzelm@10943
   245
  Update at a certain position in a nested environment may either
wenzelm@10943
   246
  delete an existing entry, or overwrite an existing one.  Note that
wenzelm@10943
   247
  update at undefined positions is simple absorbed, i.e.\ the
wenzelm@10943
   248
  environment is left unchanged.
wenzelm@10943
   249
*}
wenzelm@10943
   250
wenzelm@10943
   251
consts
wenzelm@10943
   252
  update :: "'c list => ('a, 'b, 'c) env option
wenzelm@10943
   253
    => ('a, 'b, 'c) env => ('a, 'b, 'c) env"
wenzelm@10943
   254
  update_option :: "'c list => ('a, 'b, 'c) env option
wenzelm@10943
   255
    => ('a, 'b, 'c) env option => ('a, 'b, 'c) env option"
wenzelm@10943
   256
wenzelm@10943
   257
primrec (update)
wenzelm@10943
   258
  "update xs opt (Val a) =
wenzelm@10943
   259
    (if xs = [] then (case opt of None => Val a | Some e => e)
wenzelm@10943
   260
    else Val a)"
wenzelm@10943
   261
  "update xs opt (Env b es) =
wenzelm@10943
   262
    (case xs of
wenzelm@10943
   263
      [] => (case opt of None => Env b es | Some e => e)
wenzelm@10943
   264
    | y # ys => Env b (es (y := update_option ys opt (es y))))"
wenzelm@10943
   265
  "update_option xs opt None =
wenzelm@10943
   266
    (if xs = [] then opt else None)"
wenzelm@10943
   267
  "update_option xs opt (Some e) =
wenzelm@10943
   268
    (if xs = [] then opt else Some (update xs opt e))"
wenzelm@10943
   269
wenzelm@10943
   270
hide const update_option
wenzelm@10943
   271
wenzelm@10943
   272
text {*
wenzelm@10943
   273
  \medskip The characteristic cases of @{term update} are expressed by
wenzelm@10943
   274
  the following equalities.
wenzelm@10943
   275
*}
wenzelm@10943
   276
wenzelm@10943
   277
theorem update_nil_none: "update [] None env = env"
wenzelm@10943
   278
  by (cases env) simp_all
wenzelm@10943
   279
wenzelm@10943
   280
theorem update_nil_some: "update [] (Some e) env = e"
wenzelm@10943
   281
  by (cases env) simp_all
wenzelm@10943
   282
wenzelm@10943
   283
theorem update_cons_val: "update (x # xs) opt (Val a) = Val a"
wenzelm@10943
   284
  by simp
wenzelm@10943
   285
wenzelm@10943
   286
theorem update_cons_nil_env:
wenzelm@10943
   287
    "update [x] opt (Env b es) = Env b (es (x := opt))"
wenzelm@10943
   288
  by (cases "es x") simp_all
wenzelm@10943
   289
wenzelm@10943
   290
theorem update_cons_cons_env:
wenzelm@10943
   291
  "update (x # y # ys) opt (Env b es) =
wenzelm@10943
   292
    Env b (es (x :=
wenzelm@10943
   293
      (case es x of
wenzelm@10943
   294
        None => None
wenzelm@10943
   295
      | Some e => Some (update (y # ys) opt e))))"
wenzelm@10943
   296
  by (cases "es x") simp_all
wenzelm@10943
   297
wenzelm@10943
   298
lemmas update.simps [simp del]
wenzelm@10943
   299
  and update_simps [simp] = update_nil_none update_nil_some
wenzelm@10943
   300
    update_cons_val update_cons_nil_env update_cons_cons_env
wenzelm@10943
   301
wenzelm@10943
   302
lemma update_eq:
wenzelm@10943
   303
  "update xs opt env =
wenzelm@10943
   304
    (case xs of
wenzelm@10943
   305
      [] =>
wenzelm@10943
   306
        (case opt of
wenzelm@10943
   307
          None => env
wenzelm@10943
   308
        | Some e => e)
wenzelm@10943
   309
    | x # xs =>
wenzelm@10943
   310
        (case env of
wenzelm@10943
   311
          Val a => Val a
wenzelm@10943
   312
        | Env b es =>
wenzelm@10943
   313
            (case xs of
wenzelm@10943
   314
              [] => Env b (es (x := opt))
wenzelm@10943
   315
            | y # ys =>
wenzelm@10943
   316
                Env b (es (x :=
wenzelm@10943
   317
                  (case es x of
wenzelm@10943
   318
                    None => None
wenzelm@10943
   319
                  | Some e => Some (update (y # ys) opt e)))))))"
wenzelm@10943
   320
  by (simp split: list.split env.split option.split)
wenzelm@10943
   321
wenzelm@10943
   322
text {*
wenzelm@10943
   323
  \medskip The most basic correspondence of @{term lookup} and @{term
wenzelm@10943
   324
  update} states that after @{term update} at a defined position,
wenzelm@10943
   325
  subsequent @{term lookup} operations would yield the new value.
wenzelm@10943
   326
*}
wenzelm@10943
   327
wenzelm@10943
   328
theorem lookup_update_some:
wenzelm@18153
   329
  assumes "lookup env xs = Some e"
wenzelm@18153
   330
  shows "lookup (update xs (Some env') env) xs = Some env'"
wenzelm@23394
   331
  using assms
wenzelm@20503
   332
proof (induct xs arbitrary: env e)
wenzelm@18153
   333
  case Nil
wenzelm@18153
   334
  then have "env = e" by simp
wenzelm@18153
   335
  then show ?case by simp
wenzelm@18153
   336
next
wenzelm@18153
   337
  case (Cons x xs)
wenzelm@18153
   338
  note hyp = Cons.hyps
wenzelm@18153
   339
    and asm = `lookup env (x # xs) = Some e`
wenzelm@18153
   340
  show ?case
wenzelm@18153
   341
  proof (cases env)
wenzelm@18153
   342
    case (Val a)
wenzelm@18153
   343
    with asm have False by simp
wenzelm@18153
   344
    then show ?thesis ..
wenzelm@10943
   345
  next
wenzelm@18153
   346
    case (Env b es)
wenzelm@18153
   347
    show ?thesis
wenzelm@18153
   348
    proof (cases "es x")
wenzelm@18153
   349
      case None
wenzelm@18153
   350
      with asm Env have False by simp
wenzelm@18153
   351
      then show ?thesis ..
wenzelm@10943
   352
    next
wenzelm@18153
   353
      case (Some e')
wenzelm@18153
   354
      note es = `es x = Some e'`
wenzelm@10943
   355
      show ?thesis
wenzelm@18153
   356
      proof (cases xs)
wenzelm@18153
   357
        case Nil
wenzelm@18153
   358
        with Env show ?thesis by simp
wenzelm@10943
   359
      next
wenzelm@18153
   360
        case (Cons x' xs')
wenzelm@18153
   361
        from asm Env es have "lookup e' xs = Some e" by simp
wenzelm@18153
   362
        then have "lookup (update xs (Some env') e') xs = Some env'" by (rule hyp)
wenzelm@18153
   363
        with Env es Cons show ?thesis by simp
wenzelm@10943
   364
      qed
wenzelm@10943
   365
    qed
wenzelm@18153
   366
  qed
wenzelm@10943
   367
qed
wenzelm@10943
   368
wenzelm@10943
   369
text {*
wenzelm@10943
   370
  \medskip The properties of displaced @{term update} operations are
wenzelm@10943
   371
  analogous to those of @{term lookup} above.  There are two cases:
wenzelm@10943
   372
  below an undefined position @{term update} is absorbed altogether,
wenzelm@10943
   373
  and below a defined positions @{term update} affects subsequent
wenzelm@10943
   374
  @{term lookup} operations in the obvious way.
wenzelm@10943
   375
*}
wenzelm@10943
   376
wenzelm@10943
   377
theorem update_append_none:
wenzelm@18153
   378
  assumes "lookup env xs = None"
wenzelm@18153
   379
  shows "update (xs @ y # ys) opt env = env"
wenzelm@23394
   380
  using assms
wenzelm@20503
   381
proof (induct xs arbitrary: env)
wenzelm@18153
   382
  case Nil
wenzelm@18153
   383
  then have False by simp
wenzelm@18153
   384
  then show ?case ..
wenzelm@18153
   385
next
wenzelm@18153
   386
  case (Cons x xs)
wenzelm@18153
   387
  note hyp = Cons.hyps
wenzelm@18153
   388
    and asm = `lookup env (x # xs) = None`
wenzelm@18153
   389
  show "update ((x # xs) @ y # ys) opt env = env"
wenzelm@18153
   390
  proof (cases env)
wenzelm@18153
   391
    case (Val a)
wenzelm@18153
   392
    then show ?thesis by simp
wenzelm@10943
   393
  next
wenzelm@18153
   394
    case (Env b es)
wenzelm@18153
   395
    show ?thesis
wenzelm@18153
   396
    proof (cases "es x")
wenzelm@18153
   397
      case None
wenzelm@18153
   398
      note es = `es x = None`
wenzelm@18153
   399
      show ?thesis
wenzelm@18153
   400
        by (cases xs) (simp_all add: es Env fun_upd_idem_iff)
wenzelm@10943
   401
    next
wenzelm@18153
   402
      case (Some e)
wenzelm@18153
   403
      note es = `es x = Some e`
wenzelm@10943
   404
      show ?thesis
wenzelm@18153
   405
      proof (cases xs)
wenzelm@18153
   406
        case Nil
wenzelm@18153
   407
        with asm Env Some have False by simp
wenzelm@18153
   408
        then show ?thesis ..
wenzelm@10943
   409
      next
wenzelm@18153
   410
        case (Cons x' xs')
wenzelm@18153
   411
        from asm Env es have "lookup e xs = None" by simp
wenzelm@18153
   412
        then have "update (xs @ y # ys) opt e = e" by (rule hyp)
wenzelm@18153
   413
        with Env es Cons show "update ((x # xs) @ y # ys) opt env = env"
wenzelm@18153
   414
          by (simp add: fun_upd_idem_iff)
wenzelm@10943
   415
      qed
wenzelm@10943
   416
    qed
wenzelm@18153
   417
  qed
wenzelm@10943
   418
qed
wenzelm@10943
   419
wenzelm@10943
   420
theorem update_append_some:
wenzelm@18153
   421
  assumes "lookup env xs = Some e"
wenzelm@18153
   422
  shows "lookup (update (xs @ y # ys) opt env) xs = Some (update (y # ys) opt e)"
wenzelm@23394
   423
  using assms
wenzelm@20503
   424
proof (induct xs arbitrary: env e)
wenzelm@18153
   425
  case Nil
wenzelm@18153
   426
  then have "env = e" by simp
wenzelm@18153
   427
  then show ?case by simp
wenzelm@18153
   428
next
wenzelm@18153
   429
  case (Cons x xs)
wenzelm@18153
   430
  note hyp = Cons.hyps
wenzelm@18153
   431
    and asm = `lookup env (x # xs) = Some e`
wenzelm@18153
   432
  show "lookup (update ((x # xs) @ y # ys) opt env) (x # xs) =
wenzelm@18153
   433
      Some (update (y # ys) opt e)"
wenzelm@18153
   434
  proof (cases env)
wenzelm@18153
   435
    case (Val a)
wenzelm@18153
   436
    with asm have False by simp
wenzelm@18153
   437
    then show ?thesis ..
wenzelm@10943
   438
  next
wenzelm@18153
   439
    case (Env b es)
wenzelm@18153
   440
    show ?thesis
wenzelm@18153
   441
    proof (cases "es x")
wenzelm@18153
   442
      case None
wenzelm@18153
   443
      with asm Env have False by simp
wenzelm@18153
   444
      then show ?thesis ..
wenzelm@10943
   445
    next
wenzelm@18153
   446
      case (Some e')
wenzelm@18153
   447
      note es = `es x = Some e'`
wenzelm@10943
   448
      show ?thesis
wenzelm@18153
   449
      proof (cases xs)
wenzelm@18153
   450
        case Nil
wenzelm@18153
   451
        with asm Env es have "e = e'" by simp
wenzelm@18153
   452
        with Env es Nil show ?thesis by simp
wenzelm@10943
   453
      next
wenzelm@18153
   454
        case (Cons x' xs')
wenzelm@18153
   455
        from asm Env es have "lookup e' xs = Some e" by simp
wenzelm@18153
   456
        then have "lookup (update (xs @ y # ys) opt e') xs =
wenzelm@18153
   457
          Some (update (y # ys) opt e)" by (rule hyp)
wenzelm@18153
   458
        with Env es Cons show ?thesis by simp
wenzelm@10943
   459
      qed
wenzelm@10943
   460
    qed
wenzelm@18153
   461
  qed
wenzelm@10943
   462
qed
wenzelm@10943
   463
wenzelm@10943
   464
text {*
wenzelm@10943
   465
  \medskip Apparently, @{term update} does not affect the result of
wenzelm@10943
   466
  subsequent @{term lookup} operations at independent positions, i.e.\
wenzelm@10943
   467
  in case that the paths for @{term update} and @{term lookup} fork at
wenzelm@10943
   468
  a certain point.
wenzelm@10943
   469
*}
wenzelm@10943
   470
wenzelm@10943
   471
theorem lookup_update_other:
wenzelm@18153
   472
  assumes neq: "y \<noteq> (z::'c)"
wenzelm@18153
   473
  shows "lookup (update (xs @ z # zs) opt env) (xs @ y # ys) =
wenzelm@10943
   474
    lookup env (xs @ y # ys)"
wenzelm@20503
   475
proof (induct xs arbitrary: env)
wenzelm@18153
   476
  case Nil
wenzelm@18153
   477
  show ?case
wenzelm@18153
   478
  proof (cases env)
wenzelm@18153
   479
    case Val
wenzelm@18153
   480
    then show ?thesis by simp
wenzelm@18153
   481
  next
wenzelm@18153
   482
    case Env
wenzelm@18153
   483
    show ?thesis
wenzelm@18153
   484
    proof (cases zs)
wenzelm@18153
   485
      case Nil
wenzelm@18153
   486
      with neq Env show ?thesis by simp
wenzelm@10943
   487
    next
wenzelm@18153
   488
      case Cons
wenzelm@18153
   489
      with neq Env show ?thesis by simp
wenzelm@18153
   490
    qed
wenzelm@18153
   491
  qed
wenzelm@18153
   492
next
wenzelm@18153
   493
  case (Cons x xs)
wenzelm@18153
   494
  note hyp = Cons.hyps
wenzelm@18153
   495
  show ?case
wenzelm@18153
   496
  proof (cases env)
wenzelm@18153
   497
    case Val
wenzelm@18153
   498
    then show ?thesis by simp
wenzelm@18153
   499
  next
wenzelm@18153
   500
    case (Env y es)
wenzelm@18153
   501
    show ?thesis
wenzelm@18153
   502
    proof (cases xs)
wenzelm@18153
   503
      case Nil
wenzelm@10943
   504
      show ?thesis
wenzelm@18153
   505
      proof (cases "es x")
wenzelm@18153
   506
        case None
wenzelm@18153
   507
        with Env Nil show ?thesis by simp
wenzelm@10943
   508
      next
wenzelm@18153
   509
        case Some
wenzelm@18153
   510
        with neq hyp and Env Nil show ?thesis by simp
wenzelm@18153
   511
      qed
wenzelm@18153
   512
    next
wenzelm@18153
   513
      case (Cons x' xs')
wenzelm@18153
   514
      show ?thesis
wenzelm@18153
   515
      proof (cases "es x")
wenzelm@18153
   516
        case None
wenzelm@18153
   517
        with Env Cons show ?thesis by simp
wenzelm@18153
   518
      next
wenzelm@18153
   519
        case Some
wenzelm@18153
   520
        with neq hyp and Env Cons show ?thesis by simp
wenzelm@10943
   521
      qed
wenzelm@10943
   522
    qed
wenzelm@18153
   523
  qed
wenzelm@10943
   524
qed
wenzelm@10943
   525
haftmann@28228
   526
text {* Environments and code generation *}
haftmann@24433
   527
haftmann@28562
   528
lemma [code, code del]:
haftmann@24433
   529
  fixes e1 e2 :: "('b\<Colon>eq, 'a\<Colon>eq, 'c\<Colon>eq) env"
haftmann@26732
   530
  shows "eq_class.eq e1 e2 \<longleftrightarrow> eq_class.eq e1 e2" ..
haftmann@24433
   531
haftmann@28562
   532
lemma eq_env_code [code]:
haftmann@24433
   533
  fixes x y :: "'a\<Colon>eq"
haftmann@24433
   534
    and f g :: "'c\<Colon>{eq, finite} \<Rightarrow> ('b\<Colon>eq, 'a, 'c) env option"
haftmann@26732
   535
  shows "eq_class.eq (Env x f) (Env y g) \<longleftrightarrow>
haftmann@26732
   536
  eq_class.eq x y \<and> (\<forall>z\<in>UNIV. case f z
haftmann@24433
   537
   of None \<Rightarrow> (case g z
haftmann@24433
   538
        of None \<Rightarrow> True | Some _ \<Rightarrow> False)
haftmann@24433
   539
    | Some a \<Rightarrow> (case g z
haftmann@26732
   540
        of None \<Rightarrow> False | Some b \<Rightarrow> eq_class.eq a b))" (is ?env)
haftmann@26732
   541
    and "eq_class.eq (Val a) (Val b) \<longleftrightarrow> eq_class.eq a b"
haftmann@26732
   542
    and "eq_class.eq (Val a) (Env y g) \<longleftrightarrow> False"
haftmann@26732
   543
    and "eq_class.eq (Env x f) (Val b) \<longleftrightarrow> False"
haftmann@26513
   544
proof (unfold eq)
haftmann@24433
   545
  have "f = g \<longleftrightarrow> (\<forall>z. case f z
haftmann@24433
   546
   of None \<Rightarrow> (case g z
haftmann@24433
   547
        of None \<Rightarrow> True | Some _ \<Rightarrow> False)
haftmann@24433
   548
    | Some a \<Rightarrow> (case g z
haftmann@24433
   549
        of None \<Rightarrow> False | Some b \<Rightarrow> a = b))" (is "?lhs = ?rhs")
haftmann@24433
   550
  proof
haftmann@24433
   551
    assume ?lhs
haftmann@24433
   552
    then show ?rhs by (auto split: option.splits)
haftmann@24433
   553
  next
haftmann@24433
   554
    assume assm: ?rhs (is "\<forall>z. ?prop z")
haftmann@24433
   555
    show ?lhs 
haftmann@24433
   556
    proof
haftmann@24433
   557
      fix z
haftmann@24433
   558
      from assm have "?prop z" ..
haftmann@24433
   559
      then show "f z = g z" by (auto split: option.splits)
haftmann@24433
   560
    qed
haftmann@24433
   561
  qed
haftmann@26513
   562
  then show "Env x f = Env y g \<longleftrightarrow>
haftmann@26513
   563
    x = y \<and> (\<forall>z\<in>UNIV. case f z
haftmann@26513
   564
     of None \<Rightarrow> (case g z
haftmann@26513
   565
          of None \<Rightarrow> True | Some _ \<Rightarrow> False)
haftmann@26513
   566
      | Some a \<Rightarrow> (case g z
haftmann@26513
   567
          of None \<Rightarrow> False | Some b \<Rightarrow> a = b))" by simp
haftmann@24433
   568
qed simp_all
haftmann@24433
   569
haftmann@28562
   570
lemma [code, code del]:
haftmann@28228
   571
  "(Code_Eval.term_of :: ('a::{term_of, type}, 'b::{term_of, type}, 'c::{term_of, type}) env \<Rightarrow> term) = Code_Eval.term_of" ..
haftmann@28228
   572
wenzelm@10943
   573
end