src/Doc/Tutorial/Inductive/Advanced.thy
changeset 67406 23307fd33906
parent 56059 2390391584c2
child 69505 cc2d676d5395
equal deleted inserted replaced
67405:e9ab4ad7bd15 67406:23307fd33906
     1 (*<*)theory Advanced imports Even begin
     1 (*<*)theory Advanced imports Even begin
     2 ML_file "../../antiquote_setup.ML"
     2 ML_file "../../antiquote_setup.ML"
     3 (*>*)
     3 (*>*)
     4 
     4 
     5 text {*
     5 text \<open>
     6 The premises of introduction rules may contain universal quantifiers and
     6 The premises of introduction rules may contain universal quantifiers and
     7 monotone functions.  A universal quantifier lets the rule 
     7 monotone functions.  A universal quantifier lets the rule 
     8 refer to any number of instances of 
     8 refer to any number of instances of 
     9 the inductively defined set.  A monotone function lets the rule refer
     9 the inductively defined set.  A monotone function lets the rule refer
    10 to existing constructions (such as ``list of'') over the inductively defined
    10 to existing constructions (such as ``list of'') over the inductively defined
    11 set.  The examples below show how to use the additional expressiveness
    11 set.  The examples below show how to use the additional expressiveness
    12 and how to reason from the resulting definitions.
    12 and how to reason from the resulting definitions.
    13 *}
    13 \<close>
    14 
    14 
    15 subsection{* Universal Quantifiers in Introduction Rules \label{sec:gterm-datatype} *}
    15 subsection\<open>Universal Quantifiers in Introduction Rules \label{sec:gterm-datatype}\<close>
    16 
    16 
    17 text {*
    17 text \<open>
    18 \index{ground terms example|(}%
    18 \index{ground terms example|(}%
    19 \index{quantifiers!and inductive definitions|(}%
    19 \index{quantifiers!and inductive definitions|(}%
    20 As a running example, this section develops the theory of \textbf{ground
    20 As a running example, this section develops the theory of \textbf{ground
    21 terms}: terms constructed from constant and function 
    21 terms}: terms constructed from constant and function 
    22 symbols but not variables. To simplify matters further, we regard a
    22 symbols but not variables. To simplify matters further, we regard a
    23 constant as a function applied to the null argument  list.  Let us declare a
    23 constant as a function applied to the null argument  list.  Let us declare a
    24 datatype @{text gterm} for the type of ground  terms. It is a type constructor
    24 datatype @{text gterm} for the type of ground  terms. It is a type constructor
    25 whose argument is a type of  function symbols. 
    25 whose argument is a type of  function symbols. 
    26 *}
    26 \<close>
    27 
    27 
    28 datatype 'f gterm = Apply 'f "'f gterm list"
    28 datatype 'f gterm = Apply 'f "'f gterm list"
    29 
    29 
    30 text {*
    30 text \<open>
    31 To try it out, we declare a datatype of some integer operations: 
    31 To try it out, we declare a datatype of some integer operations: 
    32 integer constants, the unary minus operator and the addition 
    32 integer constants, the unary minus operator and the addition 
    33 operator.
    33 operator.
    34 *}
    34 \<close>
    35 
    35 
    36 datatype integer_op = Number int | UnaryMinus | Plus
    36 datatype integer_op = Number int | UnaryMinus | Plus
    37 
    37 
    38 text {*
    38 text \<open>
    39 Now the type @{typ "integer_op gterm"} denotes the ground 
    39 Now the type @{typ "integer_op gterm"} denotes the ground 
    40 terms built over those symbols.
    40 terms built over those symbols.
    41 
    41 
    42 The type constructor @{text gterm} can be generalized to a function 
    42 The type constructor @{text gterm} can be generalized to a function 
    43 over sets.  It returns 
    43 over sets.  It returns 
    54 A universal quantifier in the premise of the introduction rule 
    54 A universal quantifier in the premise of the introduction rule 
    55 expresses that every element of @{text args} belongs
    55 expresses that every element of @{text args} belongs
    56 to our inductively defined set: is a ground term 
    56 to our inductively defined set: is a ground term 
    57 over~@{text F}.  The function @{term set} denotes the set of elements in a given 
    57 over~@{text F}.  The function @{term set} denotes the set of elements in a given 
    58 list. 
    58 list. 
    59 *}
    59 \<close>
    60 
    60 
    61 inductive_set
    61 inductive_set
    62   gterms :: "'f set \<Rightarrow> 'f gterm set"
    62   gterms :: "'f set \<Rightarrow> 'f gterm set"
    63   for F :: "'f set"
    63   for F :: "'f set"
    64 where
    64 where
    65 step[intro!]: "\<lbrakk>\<forall>t \<in> set args. t \<in> gterms F;  f \<in> F\<rbrakk>
    65 step[intro!]: "\<lbrakk>\<forall>t \<in> set args. t \<in> gterms F;  f \<in> F\<rbrakk>
    66                \<Longrightarrow> (Apply f args) \<in> gterms F"
    66                \<Longrightarrow> (Apply f args) \<in> gterms F"
    67 
    67 
    68 text {*
    68 text \<open>
    69 To demonstrate a proof from this definition, let us 
    69 To demonstrate a proof from this definition, let us 
    70 show that the function @{term gterms}
    70 show that the function @{term gterms}
    71 is \textbf{monotone}.  We shall need this concept shortly.
    71 is \textbf{monotone}.  We shall need this concept shortly.
    72 *}
    72 \<close>
    73 
    73 
    74 lemma gterms_mono: "F\<subseteq>G \<Longrightarrow> gterms F \<subseteq> gterms G"
    74 lemma gterms_mono: "F\<subseteq>G \<Longrightarrow> gterms F \<subseteq> gterms G"
    75 apply clarify
    75 apply clarify
    76 apply (erule gterms.induct)
    76 apply (erule gterms.induct)
    77 apply blast
    77 apply blast
    79 (*<*)
    79 (*<*)
    80 lemma gterms_mono: "F\<subseteq>G \<Longrightarrow> gterms F \<subseteq> gterms G"
    80 lemma gterms_mono: "F\<subseteq>G \<Longrightarrow> gterms F \<subseteq> gterms G"
    81 apply clarify
    81 apply clarify
    82 apply (erule gterms.induct)
    82 apply (erule gterms.induct)
    83 (*>*)
    83 (*>*)
    84 txt{*
    84 txt\<open>
    85 Intuitively, this theorem says that
    85 Intuitively, this theorem says that
    86 enlarging the set of function symbols enlarges the set of ground 
    86 enlarging the set of function symbols enlarges the set of ground 
    87 terms. The proof is a trivial rule induction.
    87 terms. The proof is a trivial rule induction.
    88 First we use the @{text clarify} method to assume the existence of an element of
    88 First we use the @{text clarify} method to assume the existence of an element of
    89 @{term "gterms F"}.  (We could have used @{text "intro subsetI"}.)  We then
    89 @{term "gterms F"}.  (We could have used @{text "intro subsetI"}.)  We then
    90 apply rule induction. Here is the resulting subgoal:
    90 apply rule induction. Here is the resulting subgoal:
    91 @{subgoals[display,indent=0]}
    91 @{subgoals[display,indent=0]}
    92 The assumptions state that @{text f} belongs 
    92 The assumptions state that @{text f} belongs 
    93 to~@{text F}, which is included in~@{text G}, and that every element of the list @{text args} is
    93 to~@{text F}, which is included in~@{text G}, and that every element of the list @{text args} is
    94 a ground term over~@{text G}.  The @{text blast} method finds this chain of reasoning easily.  
    94 a ground term over~@{text G}.  The @{text blast} method finds this chain of reasoning easily.  
    95 *}
    95 \<close>
    96 (*<*)oops(*>*)
    96 (*<*)oops(*>*)
    97 text {*
    97 text \<open>
    98 \begin{warn}
    98 \begin{warn}
    99 Why do we call this function @{text gterms} instead 
    99 Why do we call this function @{text gterms} instead 
   100 of @{text gterm}?  A constant may have the same name as a type.  However,
   100 of @{text gterm}?  A constant may have the same name as a type.  However,
   101 name  clashes could arise in the theorems that Isabelle generates. 
   101 name  clashes could arise in the theorems that Isabelle generates. 
   102 Our choice of names keeps @{text gterms.induct} separate from 
   102 Our choice of names keeps @{text gterms.induct} separate from 
   111 Suppose we are given a function called @{text arity}, specifying the arities
   111 Suppose we are given a function called @{text arity}, specifying the arities
   112 of all symbols.  In the inductive step, we have a list @{text args} of such
   112 of all symbols.  In the inductive step, we have a list @{text args} of such
   113 terms and a function  symbol~@{text f}. If the length of the list matches the
   113 terms and a function  symbol~@{text f}. If the length of the list matches the
   114 function's arity  then applying @{text f} to @{text args} yields a well-formed
   114 function's arity  then applying @{text f} to @{text args} yields a well-formed
   115 term.
   115 term.
   116 *}
   116 \<close>
   117 
   117 
   118 inductive_set
   118 inductive_set
   119   well_formed_gterm :: "('f \<Rightarrow> nat) \<Rightarrow> 'f gterm set"
   119   well_formed_gterm :: "('f \<Rightarrow> nat) \<Rightarrow> 'f gterm set"
   120   for arity :: "'f \<Rightarrow> nat"
   120   for arity :: "'f \<Rightarrow> nat"
   121 where
   121 where
   122 step[intro!]: "\<lbrakk>\<forall>t \<in> set args. t \<in> well_formed_gterm arity;  
   122 step[intro!]: "\<lbrakk>\<forall>t \<in> set args. t \<in> well_formed_gterm arity;  
   123                 length args = arity f\<rbrakk>
   123                 length args = arity f\<rbrakk>
   124                \<Longrightarrow> (Apply f args) \<in> well_formed_gterm arity"
   124                \<Longrightarrow> (Apply f args) \<in> well_formed_gterm arity"
   125 
   125 
   126 text {*
   126 text \<open>
   127 The inductive definition neatly captures the reasoning above.
   127 The inductive definition neatly captures the reasoning above.
   128 The universal quantification over the
   128 The universal quantification over the
   129 @{text set} of arguments expresses that all of them are well-formed.%
   129 @{text set} of arguments expresses that all of them are well-formed.%
   130 \index{quantifiers!and inductive definitions|)}
   130 \index{quantifiers!and inductive definitions|)}
   131 *}
   131 \<close>
   132 
   132 
   133 subsection{* Alternative Definition Using a Monotone Function *}
   133 subsection\<open>Alternative Definition Using a Monotone Function\<close>
   134 
   134 
   135 text {*
   135 text \<open>
   136 \index{monotone functions!and inductive definitions|(}% 
   136 \index{monotone functions!and inductive definitions|(}% 
   137 An inductive definition may refer to the
   137 An inductive definition may refer to the
   138 inductively defined  set through an arbitrary monotone function.  To
   138 inductively defined  set through an arbitrary monotone function.  To
   139 demonstrate this powerful feature, let us
   139 demonstrate this powerful feature, let us
   140 change the  inductive definition above, replacing the
   140 change the  inductive definition above, replacing the
   146 
   146 
   147 In the inductive definition of well-formed terms, examine the one
   147 In the inductive definition of well-formed terms, examine the one
   148 introduction rule.  The first premise states that @{text args} belongs to
   148 introduction rule.  The first premise states that @{text args} belongs to
   149 the @{text lists} of well-formed terms.  This formulation is more
   149 the @{text lists} of well-formed terms.  This formulation is more
   150 direct, if more obscure, than using a universal quantifier.
   150 direct, if more obscure, than using a universal quantifier.
   151 *}
   151 \<close>
   152 
   152 
   153 inductive_set
   153 inductive_set
   154   well_formed_gterm' :: "('f \<Rightarrow> nat) \<Rightarrow> 'f gterm set"
   154   well_formed_gterm' :: "('f \<Rightarrow> nat) \<Rightarrow> 'f gterm set"
   155   for arity :: "'f \<Rightarrow> nat"
   155   for arity :: "'f \<Rightarrow> nat"
   156 where
   156 where
   157 step[intro!]: "\<lbrakk>args \<in> lists (well_formed_gterm' arity);  
   157 step[intro!]: "\<lbrakk>args \<in> lists (well_formed_gterm' arity);  
   158                 length args = arity f\<rbrakk>
   158                 length args = arity f\<rbrakk>
   159                \<Longrightarrow> (Apply f args) \<in> well_formed_gterm' arity"
   159                \<Longrightarrow> (Apply f args) \<in> well_formed_gterm' arity"
   160 monos lists_mono
   160 monos lists_mono
   161 
   161 
   162 text {*
   162 text \<open>
   163 We cite the theorem @{text lists_mono} to justify 
   163 We cite the theorem @{text lists_mono} to justify 
   164 using the function @{term lists}.%
   164 using the function @{term lists}.%
   165 \footnote{This particular theorem is installed by default already, but we
   165 \footnote{This particular theorem is installed by default already, but we
   166 include the \isakeyword{monos} declaration in order to illustrate its syntax.}
   166 include the \isakeyword{monos} declaration in order to illustrate its syntax.}
   167 @{named_thms [display,indent=0] lists_mono [no_vars] (lists_mono)}
   167 @{named_thms [display,indent=0] lists_mono [no_vars] (lists_mono)}
   192 new term, @{term "Apply f args"}.  Because @{term lists} is monotone,
   192 new term, @{term "Apply f args"}.  Because @{term lists} is monotone,
   193 applications of the rule remain valid as new terms are constructed.
   193 applications of the rule remain valid as new terms are constructed.
   194 Further lists of well-formed
   194 Further lists of well-formed
   195 terms become available and none are taken away.%
   195 terms become available and none are taken away.%
   196 \index{monotone functions!and inductive definitions|)} 
   196 \index{monotone functions!and inductive definitions|)} 
   197 *}
   197 \<close>
   198 
   198 
   199 subsection{* A Proof of Equivalence *}
   199 subsection\<open>A Proof of Equivalence\<close>
   200 
   200 
   201 text {*
   201 text \<open>
   202 We naturally hope that these two inductive definitions of ``well-formed'' 
   202 We naturally hope that these two inductive definitions of ``well-formed'' 
   203 coincide.  The equality can be proved by separate inclusions in 
   203 coincide.  The equality can be proved by separate inclusions in 
   204 each direction.  Each is a trivial rule induction. 
   204 each direction.  Each is a trivial rule induction. 
   205 *}
   205 \<close>
   206 
   206 
   207 lemma "well_formed_gterm arity \<subseteq> well_formed_gterm' arity"
   207 lemma "well_formed_gterm arity \<subseteq> well_formed_gterm' arity"
   208 apply clarify
   208 apply clarify
   209 apply (erule well_formed_gterm.induct)
   209 apply (erule well_formed_gterm.induct)
   210 apply auto
   210 apply auto
   212 (*<*)
   212 (*<*)
   213 lemma "well_formed_gterm arity \<subseteq> well_formed_gterm' arity"
   213 lemma "well_formed_gterm arity \<subseteq> well_formed_gterm' arity"
   214 apply clarify
   214 apply clarify
   215 apply (erule well_formed_gterm.induct)
   215 apply (erule well_formed_gterm.induct)
   216 (*>*)
   216 (*>*)
   217 txt {*
   217 txt \<open>
   218 The @{text clarify} method gives
   218 The @{text clarify} method gives
   219 us an element of @{term "well_formed_gterm arity"} on which to perform 
   219 us an element of @{term "well_formed_gterm arity"} on which to perform 
   220 induction.  The resulting subgoal can be proved automatically:
   220 induction.  The resulting subgoal can be proved automatically:
   221 @{subgoals[display,indent=0]}
   221 @{subgoals[display,indent=0]}
   222 This proof resembles the one given in
   222 This proof resembles the one given in
   223 {\S}\ref{sec:gterm-datatype} above, especially in the form of the
   223 {\S}\ref{sec:gterm-datatype} above, especially in the form of the
   224 induction hypothesis.  Next, we consider the opposite inclusion:
   224 induction hypothesis.  Next, we consider the opposite inclusion:
   225 *}
   225 \<close>
   226 (*<*)oops(*>*)
   226 (*<*)oops(*>*)
   227 lemma "well_formed_gterm' arity \<subseteq> well_formed_gterm arity"
   227 lemma "well_formed_gterm' arity \<subseteq> well_formed_gterm arity"
   228 apply clarify
   228 apply clarify
   229 apply (erule well_formed_gterm'.induct)
   229 apply (erule well_formed_gterm'.induct)
   230 apply auto
   230 apply auto
   232 (*<*)
   232 (*<*)
   233 lemma "well_formed_gterm' arity \<subseteq> well_formed_gterm arity"
   233 lemma "well_formed_gterm' arity \<subseteq> well_formed_gterm arity"
   234 apply clarify
   234 apply clarify
   235 apply (erule well_formed_gterm'.induct)
   235 apply (erule well_formed_gterm'.induct)
   236 (*>*)
   236 (*>*)
   237 txt {*
   237 txt \<open>
   238 The proof script is virtually identical,
   238 The proof script is virtually identical,
   239 but the subgoal after applying induction may be surprising:
   239 but the subgoal after applying induction may be surprising:
   240 @{subgoals[display,indent=0,margin=65]}
   240 @{subgoals[display,indent=0,margin=65]}
   241 The induction hypothesis contains an application of @{term lists}.  Using a
   241 The induction hypothesis contains an application of @{term lists}.  Using a
   242 monotone function in the inductive definition always has this effect.  The
   242 monotone function in the inductive definition always has this effect.  The
   255 This example is typical of how monotone functions
   255 This example is typical of how monotone functions
   256 \index{monotone functions} can be used.  In particular, many of them
   256 \index{monotone functions} can be used.  In particular, many of them
   257 distribute over intersection.  Monotonicity implies one direction of
   257 distribute over intersection.  Monotonicity implies one direction of
   258 this set equality; we have this theorem:
   258 this set equality; we have this theorem:
   259 @{named_thms [display,indent=0] mono_Int [no_vars] (mono_Int)}
   259 @{named_thms [display,indent=0] mono_Int [no_vars] (mono_Int)}
   260 *}
   260 \<close>
   261 (*<*)oops(*>*)
   261 (*<*)oops(*>*)
   262 
   262 
   263 
   263 
   264 subsection{* Another Example of Rule Inversion *}
   264 subsection\<open>Another Example of Rule Inversion\<close>
   265 
   265 
   266 text {*
   266 text \<open>
   267 \index{rule inversion|(}%
   267 \index{rule inversion|(}%
   268 Does @{term gterms} distribute over intersection?  We have proved that this
   268 Does @{term gterms} distribute over intersection?  We have proved that this
   269 function is monotone, so @{text mono_Int} gives one of the inclusions.  The
   269 function is monotone, so @{text mono_Int} gives one of the inclusions.  The
   270 opposite inclusion asserts that if @{term t} is a ground term over both of the
   270 opposite inclusion asserts that if @{term t} is a ground term over both of the
   271 sets
   271 sets
   272 @{term F} and~@{term G} then it is also a ground term over their intersection,
   272 @{term F} and~@{term G} then it is also a ground term over their intersection,
   273 @{term "F \<inter> G"}.
   273 @{term "F \<inter> G"}.
   274 *}
   274 \<close>
   275 
   275 
   276 lemma gterms_IntI:
   276 lemma gterms_IntI:
   277      "t \<in> gterms F \<Longrightarrow> t \<in> gterms G \<longrightarrow> t \<in> gterms (F\<inter>G)"
   277      "t \<in> gterms F \<Longrightarrow> t \<in> gterms G \<longrightarrow> t \<in> gterms (F\<inter>G)"
   278 (*<*)oops(*>*)
   278 (*<*)oops(*>*)
   279 text {*
   279 text \<open>
   280 Attempting this proof, we get the assumption 
   280 Attempting this proof, we get the assumption 
   281 @{term "Apply f args \<in> gterms G"}, which cannot be broken down. 
   281 @{term "Apply f args \<in> gterms G"}, which cannot be broken down. 
   282 It looks like a job for rule inversion:\cmmdx{inductive\protect\_cases}
   282 It looks like a job for rule inversion:\cmmdx{inductive\protect\_cases}
   283 *}
   283 \<close>
   284 
   284 
   285 inductive_cases gterm_Apply_elim [elim!]: "Apply f args \<in> gterms F"
   285 inductive_cases gterm_Apply_elim [elim!]: "Apply f args \<in> gterms F"
   286 
   286 
   287 text {*
   287 text \<open>
   288 Here is the result.
   288 Here is the result.
   289 @{named_thms [display,indent=0,margin=50] gterm_Apply_elim [no_vars] (gterm_Apply_elim)}
   289 @{named_thms [display,indent=0,margin=50] gterm_Apply_elim [no_vars] (gterm_Apply_elim)}
   290 This rule replaces an assumption about @{term "Apply f args"} by 
   290 This rule replaces an assumption about @{term "Apply f args"} by 
   291 assumptions about @{term f} and~@{term args}.  
   291 assumptions about @{term f} and~@{term args}.  
   292 No cases are discarded (there was only one to begin
   292 No cases are discarded (there was only one to begin
   293 with) but the rule applies specifically to the pattern @{term "Apply f args"}.
   293 with) but the rule applies specifically to the pattern @{term "Apply f args"}.
   294 It can be applied repeatedly as an elimination rule without looping, so we
   294 It can be applied repeatedly as an elimination rule without looping, so we
   295 have given the @{text "elim!"} attribute. 
   295 have given the @{text "elim!"} attribute. 
   296 
   296 
   297 Now we can prove the other half of that distributive law.
   297 Now we can prove the other half of that distributive law.
   298 *}
   298 \<close>
   299 
   299 
   300 lemma gterms_IntI [rule_format, intro!]:
   300 lemma gterms_IntI [rule_format, intro!]:
   301      "t \<in> gterms F \<Longrightarrow> t \<in> gterms G \<longrightarrow> t \<in> gterms (F\<inter>G)"
   301      "t \<in> gterms F \<Longrightarrow> t \<in> gterms G \<longrightarrow> t \<in> gterms (F\<inter>G)"
   302 apply (erule gterms.induct)
   302 apply (erule gterms.induct)
   303 apply blast
   303 apply blast
   304 done
   304 done
   305 (*<*)
   305 (*<*)
   306 lemma "t \<in> gterms F \<Longrightarrow> t \<in> gterms G \<longrightarrow> t \<in> gterms (F\<inter>G)"
   306 lemma "t \<in> gterms F \<Longrightarrow> t \<in> gterms G \<longrightarrow> t \<in> gterms (F\<inter>G)"
   307 apply (erule gterms.induct)
   307 apply (erule gterms.induct)
   308 (*>*)
   308 (*>*)
   309 txt {*
   309 txt \<open>
   310 The proof begins with rule induction over the definition of
   310 The proof begins with rule induction over the definition of
   311 @{term gterms}, which leaves a single subgoal:  
   311 @{term gterms}, which leaves a single subgoal:  
   312 @{subgoals[display,indent=0,margin=65]}
   312 @{subgoals[display,indent=0,margin=65]}
   313 To prove this, we assume @{term "Apply f args \<in> gterms G"}.  Rule inversion,
   313 To prove this, we assume @{term "Apply f args \<in> gterms G"}.  Rule inversion,
   314 in the form of @{text gterm_Apply_elim}, infers
   314 in the form of @{text gterm_Apply_elim}, infers
   318 @{term "f \<in> G"} and hence @{term "f \<in> F \<inter> G"}. 
   318 @{term "f \<in> G"} and hence @{term "f \<in> F \<inter> G"}. 
   319 All of this reasoning is done by @{text blast}.
   319 All of this reasoning is done by @{text blast}.
   320 
   320 
   321 \smallskip
   321 \smallskip
   322 Our distributive law is a trivial consequence of previously-proved results:
   322 Our distributive law is a trivial consequence of previously-proved results:
   323 *}
   323 \<close>
   324 (*<*)oops(*>*)
   324 (*<*)oops(*>*)
   325 lemma gterms_Int_eq [simp]:
   325 lemma gterms_Int_eq [simp]:
   326      "gterms (F \<inter> G) = gterms F \<inter> gterms G"
   326      "gterms (F \<inter> G) = gterms F \<inter> gterms G"
   327 by (blast intro!: mono_Int monoI gterms_mono)
   327 by (blast intro!: mono_Int monoI gterms_mono)
   328 
   328 
   329 text_raw {*
   329 text_raw \<open>
   330 \index{rule inversion|)}%
   330 \index{rule inversion|)}%
   331 \index{ground terms example|)}
   331 \index{ground terms example|)}
   332 
   332 
   333 
   333 
   334 \begin{isamarkuptext}
   334 \begin{isamarkuptext}
   337 types is called a \textbf{signature}.  Given a type 
   337 types is called a \textbf{signature}.  Given a type 
   338 ranging over type symbols, we can represent a function's type by a
   338 ranging over type symbols, we can represent a function's type by a
   339 list of argument types paired with the result type. 
   339 list of argument types paired with the result type. 
   340 Complete this inductive definition:
   340 Complete this inductive definition:
   341 \begin{isabelle}
   341 \begin{isabelle}
   342 *}
   342 \<close>
   343 
   343 
   344 inductive_set
   344 inductive_set
   345   well_typed_gterm :: "('f \<Rightarrow> 't list * 't) \<Rightarrow> ('f gterm * 't)set"
   345   well_typed_gterm :: "('f \<Rightarrow> 't list * 't) \<Rightarrow> ('f gterm * 't)set"
   346   for sig :: "'f \<Rightarrow> 't list * 't"
   346   for sig :: "'f \<Rightarrow> 't list * 't"
   347 (*<*)
   347 (*<*)
   350     "\<lbrakk>\<forall>pair \<in> set args. pair \<in> well_typed_gterm sig; 
   350     "\<lbrakk>\<forall>pair \<in> set args. pair \<in> well_typed_gterm sig; 
   351       sig f = (map snd args, rtype)\<rbrakk>
   351       sig f = (map snd args, rtype)\<rbrakk>
   352      \<Longrightarrow> (Apply f (map fst args), rtype) 
   352      \<Longrightarrow> (Apply f (map fst args), rtype) 
   353          \<in> well_typed_gterm sig"
   353          \<in> well_typed_gterm sig"
   354 (*>*)
   354 (*>*)
   355 text_raw {*
   355 text_raw \<open>
   356 \end{isabelle}
   356 \end{isabelle}
   357 \end{exercise}
   357 \end{exercise}
   358 \end{isamarkuptext}
   358 \end{isamarkuptext}
   359 *}
   359 \<close>
   360 
   360 
   361 (*<*)
   361 (*<*)
   362 
   362 
   363 text{*the following declaration isn't actually used*}
   363 text\<open>the following declaration isn't actually used\<close>
   364 primrec
   364 primrec
   365   integer_arity :: "integer_op \<Rightarrow> nat"
   365   integer_arity :: "integer_op \<Rightarrow> nat"
   366 where
   366 where
   367   "integer_arity (Number n)        = 0"
   367   "integer_arity (Number n)        = 0"
   368 | "integer_arity UnaryMinus        = 1"
   368 | "integer_arity UnaryMinus        = 1"
   369 | "integer_arity Plus              = 2"
   369 | "integer_arity Plus              = 2"
   370 
   370 
   371 text{* the rest isn't used: too complicated.  OK for an exercise though.*}
   371 text\<open>the rest isn't used: too complicated.  OK for an exercise though.\<close>
   372 
   372 
   373 inductive_set
   373 inductive_set
   374   integer_signature :: "(integer_op * (unit list * unit)) set"
   374   integer_signature :: "(integer_op * (unit list * unit)) set"
   375 where
   375 where
   376   Number:     "(Number n,   ([], ())) \<in> integer_signature"
   376   Number:     "(Number n,   ([], ())) \<in> integer_signature"