src/HOL/Induct/QuoNestedDataType.thy
author urbanc
Tue Jun 05 09:56:19 2007 +0200 (2007-06-05)
changeset 23243 a37d3e6e8323
parent 22269 7c1e65897693
child 23746 a455e69c31cc
permissions -rw-r--r--
included Class.thy in the compiling process for Nominal/Examples
paulson@15172
     1
(*  Title:      HOL/Induct/QuoNestedDataType
paulson@15172
     2
    ID:         $Id$
paulson@15172
     3
    Author:     Lawrence C Paulson, Cambridge University Computer Laboratory
paulson@15172
     4
    Copyright   2004  University of Cambridge
paulson@15172
     5
paulson@15172
     6
*)
paulson@15172
     7
paulson@15172
     8
header{*Quotienting a Free Algebra Involving Nested Recursion*}
paulson@15172
     9
haftmann@16417
    10
theory QuoNestedDataType imports Main begin
paulson@15172
    11
paulson@15172
    12
subsection{*Defining the Free Algebra*}
paulson@15172
    13
paulson@15172
    14
text{*Messages with encryption and decryption as free constructors.*}
paulson@15172
    15
datatype
paulson@15172
    16
     freeExp = VAR  nat
paulson@15172
    17
	     | PLUS  freeExp freeExp
paulson@15172
    18
	     | FNCALL  nat "freeExp list"
paulson@15172
    19
paulson@15172
    20
text{*The equivalence relation, which makes PLUS associative.*}
paulson@15172
    21
consts  exprel :: "(freeExp * freeExp) set"
paulson@15172
    22
wenzelm@19736
    23
abbreviation
wenzelm@21404
    24
  exp_rel :: "[freeExp, freeExp] => bool"  (infixl "~~" 50) where
wenzelm@19736
    25
  "X ~~ Y == (X,Y) \<in> exprel"
wenzelm@19736
    26
wenzelm@21210
    27
notation (xsymbols)
wenzelm@19736
    28
  exp_rel  (infixl "\<sim>" 50)
wenzelm@21210
    29
notation (HTML output)
wenzelm@19736
    30
  exp_rel  (infixl "\<sim>" 50)
paulson@15172
    31
paulson@15172
    32
text{*The first rule is the desired equation. The next three rules
paulson@15172
    33
make the equations applicable to subterms. The last two rules are symmetry
paulson@15172
    34
and transitivity.*}
paulson@15172
    35
inductive "exprel"
paulson@15172
    36
  intros 
paulson@15172
    37
    ASSOC: "PLUS X (PLUS Y Z) \<sim> PLUS (PLUS X Y) Z"
paulson@15172
    38
    VAR: "VAR N \<sim> VAR N"
paulson@15172
    39
    PLUS: "\<lbrakk>X \<sim> X'; Y \<sim> Y'\<rbrakk> \<Longrightarrow> PLUS X Y \<sim> PLUS X' Y'"
paulson@15172
    40
    FNCALL: "(Xs,Xs') \<in> listrel exprel \<Longrightarrow> FNCALL F Xs \<sim> FNCALL F Xs'"
paulson@15172
    41
    SYM:   "X \<sim> Y \<Longrightarrow> Y \<sim> X"
paulson@15172
    42
    TRANS: "\<lbrakk>X \<sim> Y; Y \<sim> Z\<rbrakk> \<Longrightarrow> X \<sim> Z"
paulson@15172
    43
  monos listrel_mono
paulson@15172
    44
paulson@15172
    45
paulson@15172
    46
text{*Proving that it is an equivalence relation*}
paulson@15172
    47
wenzelm@18460
    48
lemma exprel_refl: "X \<sim> X"
wenzelm@18460
    49
  and list_exprel_refl: "(Xs,Xs) \<in> listrel(exprel)"
berghofe@22269
    50
  by (induct X and Xs) (blast intro: exprel.intros listrel_intros)+
paulson@15172
    51
paulson@15172
    52
theorem equiv_exprel: "equiv UNIV exprel"
wenzelm@18460
    53
proof -
wenzelm@18460
    54
  have "reflexive exprel" by (simp add: refl_def exprel_refl)
wenzelm@18460
    55
  moreover have "sym exprel" by (simp add: sym_def, blast intro: exprel.SYM)
wenzelm@18460
    56
  moreover have "trans exprel" by (simp add: trans_def, blast intro: exprel.TRANS)
wenzelm@18460
    57
  ultimately show ?thesis by (simp add: equiv_def)
paulson@15172
    58
qed
paulson@15172
    59
paulson@15172
    60
theorem equiv_list_exprel: "equiv UNIV (listrel exprel)"
wenzelm@18460
    61
  using equiv_listrel [OF equiv_exprel] by simp
paulson@15172
    62
paulson@15172
    63
paulson@15172
    64
lemma FNCALL_Nil: "FNCALL F [] \<sim> FNCALL F []"
paulson@15172
    65
apply (rule exprel.intros) 
berghofe@22269
    66
apply (rule listrel_intros) 
paulson@15172
    67
done
paulson@15172
    68
paulson@15172
    69
lemma FNCALL_Cons:
paulson@15172
    70
     "\<lbrakk>X \<sim> X'; (Xs,Xs') \<in> listrel(exprel)\<rbrakk>
paulson@15172
    71
      \<Longrightarrow> FNCALL F (X#Xs) \<sim> FNCALL F (X'#Xs')"
berghofe@22269
    72
by (blast intro: exprel.intros listrel_intros) 
paulson@15172
    73
paulson@15172
    74
paulson@15172
    75
paulson@15172
    76
subsection{*Some Functions on the Free Algebra*}
paulson@15172
    77
paulson@15172
    78
subsubsection{*The Set of Variables*}
paulson@15172
    79
paulson@15172
    80
text{*A function to return the set of variables present in a message.  It will
paulson@15172
    81
be lifted to the initial algrebra, to serve as an example of that process.
paulson@15172
    82
Note that the "free" refers to the free datatype rather than to the concept
paulson@15172
    83
of a free variable.*}
paulson@15172
    84
consts
paulson@15172
    85
  freevars      :: "freeExp \<Rightarrow> nat set"
paulson@15172
    86
  freevars_list :: "freeExp list \<Rightarrow> nat set"
paulson@15172
    87
paulson@15172
    88
primrec
paulson@15172
    89
   "freevars (VAR N) = {N}"
paulson@15172
    90
   "freevars (PLUS X Y) = freevars X \<union> freevars Y"
paulson@15172
    91
   "freevars (FNCALL F Xs) = freevars_list Xs"
paulson@15172
    92
paulson@15172
    93
   "freevars_list [] = {}"
paulson@15172
    94
   "freevars_list (X # Xs) = freevars X \<union> freevars_list Xs"
paulson@15172
    95
paulson@15172
    96
text{*This theorem lets us prove that the vars function respects the
paulson@15172
    97
equivalence relation.  It also helps us prove that Variable
paulson@15172
    98
  (the abstract constructor) is injective*}
paulson@15172
    99
theorem exprel_imp_eq_freevars: "U \<sim> V \<Longrightarrow> freevars U = freevars V"
wenzelm@18460
   100
apply (induct set: exprel) 
berghofe@22269
   101
apply (erule_tac [4] listrel_induct) 
paulson@15172
   102
apply (simp_all add: Un_assoc)
paulson@15172
   103
done
paulson@15172
   104
paulson@15172
   105
paulson@15172
   106
paulson@15172
   107
subsubsection{*Functions for Freeness*}
paulson@15172
   108
paulson@15172
   109
text{*A discriminator function to distinguish vars, sums and function calls*}
paulson@15172
   110
consts freediscrim :: "freeExp \<Rightarrow> int"
paulson@15172
   111
primrec
paulson@15172
   112
   "freediscrim (VAR N) = 0"
paulson@15172
   113
   "freediscrim (PLUS X Y) = 1"
paulson@15172
   114
   "freediscrim (FNCALL F Xs) = 2"
paulson@15172
   115
paulson@15172
   116
theorem exprel_imp_eq_freediscrim:
paulson@15172
   117
     "U \<sim> V \<Longrightarrow> freediscrim U = freediscrim V"
wenzelm@18460
   118
  by (induct set: exprel) auto
paulson@15172
   119
paulson@15172
   120
paulson@15172
   121
text{*This function, which returns the function name, is used to
paulson@15172
   122
prove part of the injectivity property for FnCall.*}
paulson@15172
   123
consts  freefun :: "freeExp \<Rightarrow> nat"
paulson@15172
   124
paulson@15172
   125
primrec
paulson@15172
   126
   "freefun (VAR N) = 0"
paulson@15172
   127
   "freefun (PLUS X Y) = 0"
paulson@15172
   128
   "freefun (FNCALL F Xs) = F"
paulson@15172
   129
paulson@15172
   130
theorem exprel_imp_eq_freefun:
paulson@15172
   131
     "U \<sim> V \<Longrightarrow> freefun U = freefun V"
berghofe@22269
   132
  by (induct set: exprel) (simp_all add: listrel_intros)
paulson@15172
   133
paulson@15172
   134
paulson@15172
   135
text{*This function, which returns the list of function arguments, is used to
paulson@15172
   136
prove part of the injectivity property for FnCall.*}
paulson@15172
   137
consts  freeargs      :: "freeExp \<Rightarrow> freeExp list"
paulson@15172
   138
primrec
paulson@15172
   139
   "freeargs (VAR N) = []"
paulson@15172
   140
   "freeargs (PLUS X Y) = []"
paulson@15172
   141
   "freeargs (FNCALL F Xs) = Xs"
paulson@15172
   142
paulson@15172
   143
theorem exprel_imp_eqv_freeargs:
paulson@15172
   144
     "U \<sim> V \<Longrightarrow> (freeargs U, freeargs V) \<in> listrel exprel"
wenzelm@18460
   145
apply (induct set: exprel)
berghofe@22269
   146
apply (erule_tac [4] listrel_induct) 
berghofe@22269
   147
apply (simp_all add: listrel_intros)
paulson@15172
   148
apply (blast intro: symD [OF equiv.sym [OF equiv_list_exprel]])
paulson@15172
   149
apply (blast intro: transD [OF equiv.trans [OF equiv_list_exprel]])
paulson@15172
   150
done
paulson@15172
   151
paulson@15172
   152
paulson@15172
   153
paulson@15172
   154
subsection{*The Initial Algebra: A Quotiented Message Type*}
paulson@15172
   155
paulson@15172
   156
paulson@15172
   157
typedef (Exp)  exp = "UNIV//exprel"
paulson@15172
   158
    by (auto simp add: quotient_def)
paulson@15172
   159
paulson@15172
   160
text{*The abstract message constructors*}
paulson@15172
   161
wenzelm@19736
   162
definition
wenzelm@21404
   163
  Var :: "nat \<Rightarrow> exp" where
wenzelm@19736
   164
  "Var N = Abs_Exp(exprel``{VAR N})"
paulson@15172
   165
wenzelm@21404
   166
definition
wenzelm@21404
   167
  Plus :: "[exp,exp] \<Rightarrow> exp" where
wenzelm@19736
   168
   "Plus X Y =
paulson@15172
   169
       Abs_Exp (\<Union>U \<in> Rep_Exp X. \<Union>V \<in> Rep_Exp Y. exprel``{PLUS U V})"
paulson@15172
   170
wenzelm@21404
   171
definition
wenzelm@21404
   172
  FnCall :: "[nat, exp list] \<Rightarrow> exp" where
wenzelm@19736
   173
   "FnCall F Xs =
paulson@15172
   174
       Abs_Exp (\<Union>Us \<in> listset (map Rep_Exp Xs). exprel `` {FNCALL F Us})"
paulson@15172
   175
paulson@15172
   176
paulson@15172
   177
text{*Reduces equality of equivalence classes to the @{term exprel} relation:
paulson@15172
   178
  @{term "(exprel `` {x} = exprel `` {y}) = ((x,y) \<in> exprel)"} *}
paulson@15172
   179
lemmas equiv_exprel_iff = eq_equiv_class_iff [OF equiv_exprel UNIV_I UNIV_I]
paulson@15172
   180
paulson@15172
   181
declare equiv_exprel_iff [simp]
paulson@15172
   182
paulson@15172
   183
paulson@15172
   184
text{*All equivalence classes belong to set of representatives*}
paulson@15172
   185
lemma [simp]: "exprel``{U} \<in> Exp"
paulson@15172
   186
by (auto simp add: Exp_def quotient_def intro: exprel_refl)
paulson@15172
   187
paulson@15172
   188
lemma inj_on_Abs_Exp: "inj_on Abs_Exp Exp"
paulson@15172
   189
apply (rule inj_on_inverseI)
paulson@15172
   190
apply (erule Abs_Exp_inverse)
paulson@15172
   191
done
paulson@15172
   192
paulson@15172
   193
text{*Reduces equality on abstractions to equality on representatives*}
paulson@15172
   194
declare inj_on_Abs_Exp [THEN inj_on_iff, simp]
paulson@15172
   195
paulson@15172
   196
declare Abs_Exp_inverse [simp]
paulson@15172
   197
paulson@15172
   198
paulson@15172
   199
text{*Case analysis on the representation of a exp as an equivalence class.*}
paulson@15172
   200
lemma eq_Abs_Exp [case_names Abs_Exp, cases type: exp]:
paulson@15172
   201
     "(!!U. z = Abs_Exp(exprel``{U}) ==> P) ==> P"
paulson@15172
   202
apply (rule Rep_Exp [of z, unfolded Exp_def, THEN quotientE])
paulson@15172
   203
apply (drule arg_cong [where f=Abs_Exp])
paulson@15172
   204
apply (auto simp add: Rep_Exp_inverse intro: exprel_refl)
paulson@15172
   205
done
paulson@15172
   206
paulson@15172
   207
paulson@15172
   208
subsection{*Every list of abstract expressions can be expressed in terms of a
paulson@15172
   209
  list of concrete expressions*}
paulson@15172
   210
wenzelm@19736
   211
definition
wenzelm@21404
   212
  Abs_ExpList :: "freeExp list => exp list" where
wenzelm@19736
   213
  "Abs_ExpList Xs = map (%U. Abs_Exp(exprel``{U})) Xs"
paulson@15172
   214
paulson@15172
   215
lemma Abs_ExpList_Nil [simp]: "Abs_ExpList [] == []"
paulson@15172
   216
by (simp add: Abs_ExpList_def)
paulson@15172
   217
paulson@15172
   218
lemma Abs_ExpList_Cons [simp]:
paulson@15172
   219
     "Abs_ExpList (X#Xs) == Abs_Exp (exprel``{X}) # Abs_ExpList Xs"
paulson@15172
   220
by (simp add: Abs_ExpList_def)
paulson@15172
   221
paulson@15172
   222
lemma ExpList_rep: "\<exists>Us. z = Abs_ExpList Us"
paulson@15172
   223
apply (induct z)
paulson@15172
   224
apply (rule_tac [2] z=a in eq_Abs_Exp)
paulson@18447
   225
apply (auto simp add: Abs_ExpList_def Cons_eq_map_conv intro: exprel_refl)
paulson@15172
   226
done
paulson@15172
   227
paulson@15172
   228
lemma eq_Abs_ExpList [case_names Abs_ExpList]:
paulson@15172
   229
     "(!!Us. z = Abs_ExpList Us ==> P) ==> P"
paulson@15172
   230
by (rule exE [OF ExpList_rep], blast) 
paulson@15172
   231
paulson@15172
   232
paulson@15172
   233
subsubsection{*Characteristic Equations for the Abstract Constructors*}
paulson@15172
   234
paulson@15172
   235
lemma Plus: "Plus (Abs_Exp(exprel``{U})) (Abs_Exp(exprel``{V})) = 
paulson@15172
   236
             Abs_Exp (exprel``{PLUS U V})"
paulson@15172
   237
proof -
paulson@15172
   238
  have "(\<lambda>U V. exprel `` {PLUS U V}) respects2 exprel"
paulson@15172
   239
    by (simp add: congruent2_def exprel.PLUS)
paulson@15172
   240
  thus ?thesis
paulson@15172
   241
    by (simp add: Plus_def UN_equiv_class2 [OF equiv_exprel equiv_exprel])
paulson@15172
   242
qed
paulson@15172
   243
paulson@15172
   244
text{*It is not clear what to do with FnCall: it's argument is an abstraction
paulson@15172
   245
of an @{typ "exp list"}. Is it just Nil or Cons? What seems to work best is to
paulson@15172
   246
regard an @{typ "exp list"} as a @{term "listrel exprel"} equivalence class*}
paulson@15172
   247
paulson@15172
   248
text{*This theorem is easily proved but never used. There's no obvious way
paulson@15172
   249
even to state the analogous result, @{text FnCall_Cons}.*}
paulson@15172
   250
lemma FnCall_Nil: "FnCall F [] = Abs_Exp (exprel``{FNCALL F []})"
paulson@15172
   251
  by (simp add: FnCall_def)
paulson@15172
   252
paulson@15172
   253
lemma FnCall_respects: 
paulson@15172
   254
     "(\<lambda>Us. exprel `` {FNCALL F Us}) respects (listrel exprel)"
paulson@15172
   255
  by (simp add: congruent_def exprel.FNCALL)
paulson@15172
   256
paulson@15172
   257
lemma FnCall_sing:
paulson@15172
   258
     "FnCall F [Abs_Exp(exprel``{U})] = Abs_Exp (exprel``{FNCALL F [U]})"
paulson@15172
   259
proof -
paulson@15172
   260
  have "(\<lambda>U. exprel `` {FNCALL F [U]}) respects exprel"
berghofe@22269
   261
    by (simp add: congruent_def FNCALL_Cons listrel_intros)
paulson@15172
   262
  thus ?thesis
paulson@15172
   263
    by (simp add: FnCall_def UN_equiv_class [OF equiv_exprel])
paulson@15172
   264
qed
paulson@15172
   265
paulson@15172
   266
lemma listset_Rep_Exp_Abs_Exp:
paulson@15172
   267
     "listset (map Rep_Exp (Abs_ExpList Us)) = listrel exprel `` {Us}";
wenzelm@18460
   268
  by (induct Us) (simp_all add: listrel_Cons Abs_ExpList_def)
paulson@15172
   269
paulson@15172
   270
lemma FnCall:
paulson@15172
   271
     "FnCall F (Abs_ExpList Us) = Abs_Exp (exprel``{FNCALL F Us})"
paulson@15172
   272
proof -
paulson@15172
   273
  have "(\<lambda>Us. exprel `` {FNCALL F Us}) respects (listrel exprel)"
paulson@15172
   274
    by (simp add: congruent_def exprel.FNCALL)
paulson@15172
   275
  thus ?thesis
paulson@15172
   276
    by (simp add: FnCall_def UN_equiv_class [OF equiv_list_exprel]
paulson@15172
   277
                  listset_Rep_Exp_Abs_Exp)
paulson@15172
   278
qed
paulson@15172
   279
paulson@15172
   280
paulson@15172
   281
text{*Establishing this equation is the point of the whole exercise*}
paulson@15172
   282
theorem Plus_assoc: "Plus X (Plus Y Z) = Plus (Plus X Y) Z"
paulson@15172
   283
by (cases X, cases Y, cases Z, simp add: Plus exprel.ASSOC)
paulson@15172
   284
paulson@15172
   285
paulson@15172
   286
paulson@15172
   287
subsection{*The Abstract Function to Return the Set of Variables*}
paulson@15172
   288
wenzelm@19736
   289
definition
wenzelm@21404
   290
  vars :: "exp \<Rightarrow> nat set" where
wenzelm@19736
   291
  "vars X = (\<Union>U \<in> Rep_Exp X. freevars U)"
paulson@15172
   292
paulson@15172
   293
lemma vars_respects: "freevars respects exprel"
paulson@15172
   294
by (simp add: congruent_def exprel_imp_eq_freevars) 
paulson@15172
   295
paulson@15172
   296
text{*The extension of the function @{term vars} to lists*}
paulson@15172
   297
consts vars_list :: "exp list \<Rightarrow> nat set"
paulson@15172
   298
primrec
paulson@15172
   299
   "vars_list []    = {}"
paulson@15172
   300
   "vars_list(E#Es) = vars E \<union> vars_list Es"
paulson@15172
   301
paulson@15172
   302
paulson@15172
   303
text{*Now prove the three equations for @{term vars}*}
paulson@15172
   304
paulson@15172
   305
lemma vars_Variable [simp]: "vars (Var N) = {N}"
paulson@15172
   306
by (simp add: vars_def Var_def 
paulson@15172
   307
              UN_equiv_class [OF equiv_exprel vars_respects]) 
paulson@15172
   308
 
paulson@15172
   309
lemma vars_Plus [simp]: "vars (Plus X Y) = vars X \<union> vars Y"
paulson@15172
   310
apply (cases X, cases Y) 
paulson@15172
   311
apply (simp add: vars_def Plus 
paulson@15172
   312
                 UN_equiv_class [OF equiv_exprel vars_respects]) 
paulson@15172
   313
done
paulson@15172
   314
paulson@15172
   315
lemma vars_FnCall [simp]: "vars (FnCall F Xs) = vars_list Xs"
paulson@15172
   316
apply (cases Xs rule: eq_Abs_ExpList) 
paulson@15172
   317
apply (simp add: FnCall)
paulson@15172
   318
apply (induct_tac Us) 
paulson@15172
   319
apply (simp_all add: vars_def UN_equiv_class [OF equiv_exprel vars_respects])
paulson@15172
   320
done
paulson@15172
   321
paulson@15172
   322
lemma vars_FnCall_Nil: "vars (FnCall F Nil) = {}" 
paulson@15172
   323
by simp
paulson@15172
   324
paulson@15172
   325
lemma vars_FnCall_Cons: "vars (FnCall F (X#Xs)) = vars X \<union> vars_list Xs"
paulson@15172
   326
by simp
paulson@15172
   327
paulson@15172
   328
paulson@15172
   329
subsection{*Injectivity Properties of Some Constructors*}
paulson@15172
   330
paulson@15172
   331
lemma VAR_imp_eq: "VAR m \<sim> VAR n \<Longrightarrow> m = n"
paulson@15172
   332
by (drule exprel_imp_eq_freevars, simp)
paulson@15172
   333
paulson@15172
   334
text{*Can also be proved using the function @{term vars}*}
paulson@15172
   335
lemma Var_Var_eq [iff]: "(Var m = Var n) = (m = n)"
paulson@15172
   336
by (auto simp add: Var_def exprel_refl dest: VAR_imp_eq)
paulson@15172
   337
paulson@15172
   338
lemma VAR_neqv_PLUS: "VAR m \<sim> PLUS X Y \<Longrightarrow> False"
paulson@15172
   339
by (drule exprel_imp_eq_freediscrim, simp)
paulson@15172
   340
paulson@15172
   341
theorem Var_neq_Plus [iff]: "Var N \<noteq> Plus X Y"
paulson@15172
   342
apply (cases X, cases Y) 
paulson@15172
   343
apply (simp add: Var_def Plus) 
paulson@15172
   344
apply (blast dest: VAR_neqv_PLUS) 
paulson@15172
   345
done
paulson@15172
   346
paulson@15172
   347
theorem Var_neq_FnCall [iff]: "Var N \<noteq> FnCall F Xs"
paulson@15172
   348
apply (cases Xs rule: eq_Abs_ExpList) 
paulson@15172
   349
apply (auto simp add: FnCall Var_def)
paulson@15172
   350
apply (drule exprel_imp_eq_freediscrim, simp)
paulson@15172
   351
done
paulson@15172
   352
paulson@15172
   353
subsection{*Injectivity of @{term FnCall}*}
paulson@15172
   354
wenzelm@19736
   355
definition
wenzelm@21404
   356
  "fun" :: "exp \<Rightarrow> nat" where
wenzelm@19736
   357
  "fun X = contents (\<Union>U \<in> Rep_Exp X. {freefun U})"
paulson@15172
   358
paulson@15172
   359
lemma fun_respects: "(%U. {freefun U}) respects exprel"
paulson@15172
   360
by (simp add: congruent_def exprel_imp_eq_freefun) 
paulson@15172
   361
paulson@15172
   362
lemma fun_FnCall [simp]: "fun (FnCall F Xs) = F"
paulson@15172
   363
apply (cases Xs rule: eq_Abs_ExpList) 
paulson@15172
   364
apply (simp add: FnCall fun_def UN_equiv_class [OF equiv_exprel fun_respects])
paulson@15172
   365
done
paulson@15172
   366
wenzelm@19736
   367
definition
wenzelm@21404
   368
  args :: "exp \<Rightarrow> exp list" where
wenzelm@19736
   369
  "args X = contents (\<Union>U \<in> Rep_Exp X. {Abs_ExpList (freeargs U)})"
paulson@15172
   370
paulson@15172
   371
text{*This result can probably be generalized to arbitrary equivalence
paulson@15172
   372
relations, but with little benefit here.*}
paulson@15172
   373
lemma Abs_ExpList_eq:
paulson@15172
   374
     "(y, z) \<in> listrel exprel \<Longrightarrow> Abs_ExpList (y) = Abs_ExpList (z)"
wenzelm@18460
   375
  by (induct set: listrel) simp_all
paulson@15172
   376
paulson@15172
   377
lemma args_respects: "(%U. {Abs_ExpList (freeargs U)}) respects exprel"
paulson@15172
   378
by (simp add: congruent_def Abs_ExpList_eq exprel_imp_eqv_freeargs) 
paulson@15172
   379
paulson@15172
   380
lemma args_FnCall [simp]: "args (FnCall F Xs) = Xs"
paulson@15172
   381
apply (cases Xs rule: eq_Abs_ExpList) 
paulson@15172
   382
apply (simp add: FnCall args_def UN_equiv_class [OF equiv_exprel args_respects])
paulson@15172
   383
done
paulson@15172
   384
paulson@15172
   385
paulson@15172
   386
lemma FnCall_FnCall_eq [iff]:
paulson@15172
   387
     "(FnCall F Xs = FnCall F' Xs') = (F=F' & Xs=Xs')" 
paulson@15172
   388
proof
paulson@15172
   389
  assume "FnCall F Xs = FnCall F' Xs'"
paulson@15172
   390
  hence "fun (FnCall F Xs) = fun (FnCall F' Xs')" 
paulson@15172
   391
    and "args (FnCall F Xs) = args (FnCall F' Xs')" by auto
paulson@15172
   392
  thus "F=F' & Xs=Xs'" by simp
paulson@15172
   393
next
paulson@15172
   394
  assume "F=F' & Xs=Xs'" thus "FnCall F Xs = FnCall F' Xs'" by simp
paulson@15172
   395
qed
paulson@15172
   396
paulson@15172
   397
paulson@15172
   398
subsection{*The Abstract Discriminator*}
paulson@15172
   399
text{*However, as @{text FnCall_Var_neq_Var} illustrates, we don't need this
paulson@15172
   400
function in order to prove discrimination theorems.*}
paulson@15172
   401
wenzelm@19736
   402
definition
wenzelm@21404
   403
  discrim :: "exp \<Rightarrow> int" where
wenzelm@19736
   404
  "discrim X = contents (\<Union>U \<in> Rep_Exp X. {freediscrim U})"
paulson@15172
   405
paulson@15172
   406
lemma discrim_respects: "(\<lambda>U. {freediscrim U}) respects exprel"
paulson@15172
   407
by (simp add: congruent_def exprel_imp_eq_freediscrim) 
paulson@15172
   408
paulson@15172
   409
text{*Now prove the four equations for @{term discrim}*}
paulson@15172
   410
paulson@15172
   411
lemma discrim_Var [simp]: "discrim (Var N) = 0"
paulson@15172
   412
by (simp add: discrim_def Var_def 
paulson@15172
   413
              UN_equiv_class [OF equiv_exprel discrim_respects]) 
paulson@15172
   414
paulson@15172
   415
lemma discrim_Plus [simp]: "discrim (Plus X Y) = 1"
paulson@15172
   416
apply (cases X, cases Y) 
paulson@15172
   417
apply (simp add: discrim_def Plus 
paulson@15172
   418
                 UN_equiv_class [OF equiv_exprel discrim_respects]) 
paulson@15172
   419
done
paulson@15172
   420
paulson@15172
   421
lemma discrim_FnCall [simp]: "discrim (FnCall F Xs) = 2"
paulson@15172
   422
apply (rule_tac z=Xs in eq_Abs_ExpList) 
paulson@15172
   423
apply (simp add: discrim_def FnCall
paulson@15172
   424
                 UN_equiv_class [OF equiv_exprel discrim_respects]) 
paulson@15172
   425
done
paulson@15172
   426
paulson@15172
   427
paulson@15172
   428
text{*The structural induction rule for the abstract type*}
wenzelm@18460
   429
theorem exp_inducts:
paulson@15172
   430
  assumes V:    "\<And>nat. P1 (Var nat)"
paulson@15172
   431
      and P:    "\<And>exp1 exp2. \<lbrakk>P1 exp1; P1 exp2\<rbrakk> \<Longrightarrow> P1 (Plus exp1 exp2)"
paulson@15172
   432
      and F:    "\<And>nat list. P2 list \<Longrightarrow> P1 (FnCall nat list)"
paulson@15172
   433
      and Nil:  "P2 []"
paulson@15172
   434
      and Cons: "\<And>exp list. \<lbrakk>P1 exp; P2 list\<rbrakk> \<Longrightarrow> P2 (exp # list)"
wenzelm@18460
   435
  shows "P1 exp" and "P2 list"
wenzelm@18460
   436
proof -
wenzelm@18460
   437
  obtain U where exp: "exp = (Abs_Exp (exprel `` {U}))" by (cases exp)
wenzelm@18460
   438
  obtain Us where list: "list = Abs_ExpList Us" by (rule eq_Abs_ExpList)
wenzelm@18460
   439
  have "P1 (Abs_Exp (exprel `` {U}))" and "P2 (Abs_ExpList Us)"
paulson@15172
   440
  proof (induct U and Us)
wenzelm@18460
   441
    case (VAR nat)
paulson@15172
   442
    with V show ?case by (simp add: Var_def) 
paulson@15172
   443
  next
paulson@15172
   444
    case (PLUS X Y)
paulson@15172
   445
    with P [of "Abs_Exp (exprel `` {X})" "Abs_Exp (exprel `` {Y})"]
paulson@15172
   446
    show ?case by (simp add: Plus) 
paulson@15172
   447
  next
paulson@15172
   448
    case (FNCALL nat list)
paulson@15172
   449
    with F [of "Abs_ExpList list"]
paulson@15172
   450
    show ?case by (simp add: FnCall) 
paulson@15172
   451
  next
paulson@15172
   452
    case Nil_freeExp
paulson@15172
   453
    with Nil show ?case by simp
paulson@15172
   454
  next
paulson@15172
   455
    case Cons_freeExp
wenzelm@18460
   456
    with Cons show ?case by simp
paulson@15172
   457
  qed
wenzelm@18460
   458
  with exp and list show "P1 exp" and "P2 list" by (simp_all only:)
paulson@15172
   459
qed
paulson@15172
   460
paulson@15172
   461
end