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 \<open>gterm\<close> 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 \<close> |
26 \<close> |
27 |
27 |
28 datatype 'f gterm = Apply 'f "'f gterm list" |
28 datatype 'f gterm = Apply 'f "'f gterm list" |
29 |
29 |
37 |
37 |
38 text \<open> |
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 \<open>gterm\<close> can be generalized to a function |
43 over sets. It returns |
43 over sets. It returns |
44 the set of ground terms that can be formed over a set @{text F} of function symbols. For |
44 the set of ground terms that can be formed over a set \<open>F\<close> of function symbols. For |
45 example, we could consider the set of ground terms formed from the finite |
45 example, we could consider the set of ground terms formed from the finite |
46 set @{text "{Number 2, UnaryMinus, Plus}"}. |
46 set \<open>{Number 2, UnaryMinus, Plus}\<close>. |
47 |
47 |
48 This concept is inductive. If we have a list @{text args} of ground terms |
48 This concept is inductive. If we have a list \<open>args\<close> of ground terms |
49 over~@{text F} and a function symbol @{text f} in @{text F}, then we |
49 over~\<open>F\<close> and a function symbol \<open>f\<close> in \<open>F\<close>, then we |
50 can apply @{text f} to @{text args} to obtain another ground term. |
50 can apply \<open>f\<close> to \<open>args\<close> to obtain another ground term. |
51 The only difficulty is that the argument list may be of any length. Hitherto, |
51 The only difficulty is that the argument list may be of any length. Hitherto, |
52 each rule in an inductive definition referred to the inductively |
52 each rule in an inductive definition referred to the inductively |
53 defined set a fixed number of times, typically once or twice. |
53 defined set a fixed number of times, typically once or twice. |
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 \<open>args\<close> 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~\<open>F\<close>. The function @{term set} denotes the set of elements in a given |
58 list. |
58 list. |
59 \<close> |
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" |
83 (*>*) |
83 (*>*) |
84 txt\<open> |
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 \<open>clarify\<close> 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 \<open>intro subsetI\<close>.) 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 \<open>f\<close> belongs |
93 to~@{text F}, which is included in~@{text G}, and that every element of the list @{text args} is |
93 to~\<open>F\<close>, which is included in~\<open>G\<close>, and that every element of the list \<open>args\<close> is |
94 a ground term over~@{text G}. The @{text blast} method finds this chain of reasoning easily. |
94 a ground term over~\<open>G\<close>. The \<open>blast\<close> method finds this chain of reasoning easily. |
95 \<close> |
95 \<close> |
96 (*<*)oops(*>*) |
96 (*<*)oops(*>*) |
97 text \<open> |
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 \<open>gterms\<close> instead |
100 of @{text gterm}? A constant may have the same name as a type. However, |
100 of \<open>gterm\<close>? 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 \<open>gterms.induct\<close> separate from |
103 @{text gterm.induct}. |
103 \<open>gterm.induct\<close>. |
104 \end{warn} |
104 \end{warn} |
105 |
105 |
106 Call a term \textbf{well-formed} if each symbol occurring in it is applied |
106 Call a term \textbf{well-formed} if each symbol occurring in it is applied |
107 to the correct number of arguments. (This number is called the symbol's |
107 to the correct number of arguments. (This number is called the symbol's |
108 \textbf{arity}.) We can express well-formedness by |
108 \textbf{arity}.) We can express well-formedness by |
109 generalizing the inductive definition of |
109 generalizing the inductive definition of |
110 \isa{gterms}. |
110 \isa{gterms}. |
111 Suppose we are given a function called @{text arity}, specifying the arities |
111 Suppose we are given a function called \<open>arity\<close>, 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 \<open>args\<close> of such |
113 terms and a function symbol~@{text f}. If the length of the list matches the |
113 terms and a function symbol~\<open>f\<close>. 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 \<open>f\<close> to \<open>args\<close> yields a well-formed |
115 term. |
115 term. |
116 \<close> |
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" |
124 \<Longrightarrow> (Apply f args) \<in> well_formed_gterm arity" |
124 \<Longrightarrow> (Apply f args) \<in> well_formed_gterm arity" |
125 |
125 |
126 text \<open> |
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 \<open>set\<close> of arguments expresses that all of them are well-formed.% |
130 \index{quantifiers!and inductive definitions|)} |
130 \index{quantifiers!and inductive definitions|)} |
131 \<close> |
131 \<close> |
132 |
132 |
133 subsection\<open>Alternative Definition Using a Monotone Function\<close> |
133 subsection\<open>Alternative Definition Using a Monotone Function\<close> |
134 |
134 |
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 |
141 quantifier by a use of the function @{term lists}. This |
141 quantifier by a use of the function @{term lists}. This |
142 function, from the Isabelle theory of lists, is analogous to the |
142 function, from the Isabelle theory of lists, is analogous to the |
143 function @{term gterms} declared above: if @{text A} is a set then |
143 function @{term gterms} declared above: if \<open>A\<close> is a set then |
144 @{term "lists A"} is the set of lists whose elements belong to |
144 @{term "lists A"} is the set of lists whose elements belong to |
145 @{term A}. |
145 @{term A}. |
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 \<open>args\<close> belongs to |
149 the @{text lists} of well-formed terms. This formulation is more |
149 the \<open>lists\<close> 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 \<close> |
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" |
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 \<open> |
162 text \<open> |
163 We cite the theorem @{text lists_mono} to justify |
163 We cite the theorem \<open>lists_mono\<close> 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)} |
168 Why must the function be monotone? An inductive definition describes |
168 Why must the function be monotone? An inductive definition describes |
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 \<open> |
217 txt \<open> |
218 The @{text clarify} method gives |
218 The \<open>clarify\<close> 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 |
247 is quickly replaced by its two parts: |
247 is quickly replaced by its two parts: |
248 \begin{trivlist} |
248 \begin{trivlist} |
249 \item @{term "args \<in> lists (well_formed_gterm' arity)"} |
249 \item @{term "args \<in> lists (well_formed_gterm' arity)"} |
250 \item @{term "args \<in> lists (well_formed_gterm arity)"} |
250 \item @{term "args \<in> lists (well_formed_gterm arity)"} |
251 \end{trivlist} |
251 \end{trivlist} |
252 Invoking the rule @{text well_formed_gterm.step} completes the proof. The |
252 Invoking the rule \<open>well_formed_gterm.step\<close> completes the proof. The |
253 call to @{text auto} does all this work. |
253 call to \<open>auto\<close> does all this work. |
254 |
254 |
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: |
264 subsection\<open>Another Example of Rule Inversion\<close> |
264 subsection\<open>Another Example of Rule Inversion\<close> |
265 |
265 |
266 text \<open> |
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 \<open>mono_Int\<close> 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 \<close> |
274 \<close> |
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 \<open>elim!\<close> 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 \<close> |
298 \<close> |
299 |
299 |
300 lemma gterms_IntI [rule_format, intro!]: |
300 lemma gterms_IntI [rule_format, intro!]: |
309 txt \<open> |
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 \<open>gterm_Apply_elim\<close>, infers |
315 that every element of @{term args} belongs to |
315 that every element of @{term args} belongs to |
316 @{term "gterms G"}; hence (by the induction hypothesis) it belongs |
316 @{term "gterms G"}; hence (by the induction hypothesis) it belongs |
317 to @{term "gterms (F \<inter> G)"}. Rule inversion also yields |
317 to @{term "gterms (F \<inter> G)"}. Rule inversion also yields |
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 \<open>blast\<close>. |
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 \<close> |
323 \<close> |
324 (*<*)oops(*>*) |
324 (*<*)oops(*>*) |