text‹ The premises of introduction rules may contain universal quantifiers and monotone functions. A universal quantifier lets the rule refer to any number of instances of the inductively defined set. A monotone function lets the rule refer to existing constructions (such as ``list of'') over the inductively defined set. The examples below show how to use the additional expressiveness and how to reason from the resulting definitions. ›
subsection‹Universal Quantifiers in Introduction Rules \label{sec:gterm-datatype}›
text‹ \index{ground terms example|(}% \index{quantifiers!and inductive definitions|(}% As a running example, this section develops the theory of \textbf{ground terms}: terms constructed from constant and function symbols but not variables. To simplify matters further, we regard a constant as a function applied to the null argument list. Let us declare a datatype ‹gterm› f
whose argument is a type of function symbols. ›
datatype 'f gterm = Apply 'f "'f gterm list"
text‹ To try it out, we declare a datatype of some integer operations: integer constants, the unary minus operator and the addition operator. ›
datatype integer_op = Number int | UnaryMinus | Plus
text‹ Now the type 🍋‹integer_op gterm› d
terms built over those symbols.
The type constructor ‹gterm› can be generalized to a function
over sets. It returns
the set of ground terms that can be formed over a set ‹F› of function symbols. For
example, we could consider the set of ground terms formed from the finite
set ‹{Number 2, UnaryMinus, Plus}›.
This concept isinductive. If we have a list ‹args› of ground terms
over~‹F›and a function symbol ‹f›in‹F›, then we
can apply‹f›to‹args›toobtain another ground term.
The only difficulty is that the argument list may be of any length. Hitherto,
each rule in an inductivedefinition referred to the inductively
defined set a fixed number of times, typically once or twice.
A universal quantifier in the premise of the introduction rule
expresses that every element of ‹args› belongs to our inductively defined set: is a ground term
over~‹F›. The function🍋‹set› denotes the set of elements in a given
list. ›
inductive_set
gterms :: "'f set ==> 'f gterm set" for F :: "'f set" where
step[intro!]: "[∀t ∈ set args. t ∈ gterms F; f ∈ F] ==> (Apply f args) ∈ gterms F"
text‹ To demonstrate a proof from this definition, let us show that the function 🍋‹gterms› is\textbf{monotone}. We shall need this concept shortly. ›
lemma gterms_mono: "F⊆G ==> gterms F ⊆ gterms G" apply clarify apply (erule gterms.induct) apply blast done (*<*) lemma gterms_mono: "F⊆G ==> gterms F ⊆ gterms G" apply clarify apply (erule gterms.induct) (*>*) txt‹ Intuitively, this theorem says that enlarging the set of function symbols enlarges the set of ground terms. The proof is a trivial rule induction. First we use the ‹clarify› m 🍋‹gterms F›. (We could have used ‹intro subsetI›.) We then apply rule induction. Here is the resulting subgoal:
@{subgoals[display,indent=0]}
The assumptions state that ‹f› belongs to~‹F›, which is included in~‹G›, and that every element of the list ‹args›is
a ground term over~‹G›. The ‹blast› method finds this chain of reasoning easily. › (*<*)oops(*>*) text‹ \begin{warn} Why do we call this function ‹gterms› i
of ‹gterm›? A constant may have the same name as a type. However,
name clashes could arise in the theorems that Isabelle generates.
Our choice of names keeps ‹gterms.induct› separate from ‹gterm.induct›. \end{warn}
Call a term\textbf{well-formed} if each symbol occurring in it is applied to the correct number of arguments. (This number is called the symbol's \textbf{arity}.) We can express well-formedness by
generalizing the inductivedefinition of \isa{gterms}.
Suppose we are given a function called ‹arity›, specifying the arities
of all symbols. In the inductive step, we have a list ‹args› of such
terms and a function symbol~‹f›. If the length of the list matches the function's arity then applying ‹f›to‹args› yields a well-formed term. ›
inductive_set
well_formed_gterm :: "('f ==> nat) ==> 'f gterm set" for arity :: "'f ==> nat" where
step[intro!]: "[∀t ∈ set args. t ∈ well_formed_gterm arity; length args = arity f] ==> (Apply f args) ∈ well_formed_gterm arity"
text‹ The inductive definition neatly captures the reasoning above. The universal quantification over the ‹set› o \index{quantifiers!andinductive definitions|)} ›
subsection‹Alternative Definition Using a Monotone Function›
text‹ \index{monotone functions!and inductive definitions|(}% An inductive definition may refer to the inductively defined set through an arbitrary monotone function. To demonstrate this powerful feature, let us change the inductive definition above, replacing the quantifier by a use of the function 🍋‹lists›. function, from the Isabelle theory of lists, is analogous to the function🍋‹gterms› declared above: if‹A›is a set then 🍋‹lists A›is the set of lists whose elements belong to 🍋‹A›.
In the inductivedefinition of well-formed terms, examine the one
introduction rule. The first premise states that ‹args› belongs to
the ‹lists› of well-formed terms. This formulation is more
direct, if more obscure, than using a universal quantifier. ›
text‹ We cite the theorem ‹lists_mono› t using the function🍋‹lists›.% \footnote{This particular theoremis installed by default already, but we
include the \isakeyword{monos} declarationin order to illustrate its syntax.}
@{named_thms [display,indent=0] lists_mono [no_vars] (lists_mono)}
Why must the function be monotone? An inductivedefinition describes
an iterative construction: each element of the set is constructed by a
finite number of introduction rule applications. For example, the
elements of \isa{even} are constructed by finitely many applications of
the rules
@{thm [display,indent=0] even.intros [no_vars]}
All references to a set in its inductivedefinition must be positive. Applications of an
introduction rule cannot invalidate previous applications, allowing the
construction process to converge.
The following pair of rules do not constitute an inductivedefinition: \begin{trivlist} \item🍋‹0 ∈ even› \item🍋‹n ∉ even ==> (Suc n) ∈ even› \end{trivlist}
Showing that 4 is even using these rules requires showing that 3 is not
even. It is far from trivial toshow that this set of rules
characterizes the even numbers.
Even with its use of the function\isa{lists}, the premise of our
introduction rule is positive:
@{thm [display,indent=0] (prem 1) step [no_vars]} Toapply the rule we construct a list 🍋‹args› of previously
constructed well-formed terms. We obtain a
new term, 🍋‹Apply f args›. Because 🍋‹lists›is monotone,
applications of the rule remain valid as new terms are constructed.
Further lists of well-formed
terms become available and none are taken away.% \index{monotone functions!andinductive definitions|)} ›
subsection‹A Proof of Equivalence›
text‹ We naturally hope that these two inductive definitions of ``well-formed'' coincide. The equality can be proved by separate inclusions in each direction. Each is a trivial rule induction. ›
lemma"well_formed_gterm arity ⊆ well_formed_gterm' arity" apply clarify apply (erule well_formed_gterm.induct) apply auto done (*<*) lemma"well_formed_gterm arity ⊆ well_formed_gterm' arity" apply clarify apply (erule well_formed_gterm.induct) (*>*) txt‹ The ‹clarify› m
us an element of 🍋‹well_formed_gterm arity› on which to perform induction. The resulting subgoal can be proved automatically:
@{subgoals[display,indent=0]}
This proof resembles the one given in
{\S}\ref{sec:gterm-datatype} above, especially in the form of the induction hypothesis. Next, we consider the opposite inclusion: › (*<*)oops(*>*) lemma"well_formed_gterm' arity ⊆ well_formed_gterm arity" apply clarify apply (erule well_formed_gterm'.induct) apply auto done (*<*) lemma"well_formed_gterm' arity ⊆ well_formed_gterm arity" apply clarify apply (erule well_formed_gterm'.induct) (*>*) txt‹ The proof script is virtually identical, but the subgoal after applying induction may be surprising: @{subgoals[display,indent=0,margin=65]} The induction hypothesis contains an application of 🍋‹lists›.
monotone functionin the inductivedefinition always has this effect. The
subgoal may look uninviting, but fortunately 🍋‹lists› distributes over intersection:
@{named_thms [display,indent=0] lists_Int_eq [no_vars] (lists_Int_eq)}
Thanks to this default simplification rule, the induction hypothesis is quickly replaced by its two parts: \begin{trivlist} \item🍋‹args ∈ lists (well_formed_gterm' arity)› \item🍋‹args ∈ lists (well_formed_gterm arity)› \end{trivlist}
Invoking the rule ‹well_formed_gterm.step› completes the proof. The
call to‹auto› does all this work.
This example is typical of how monotone functions \index{monotone functions} can be used. In particular, many of them
distribute over intersection. Monotonicity implies one direction of
this set equality; we have this theorem:
@{named_thms [display,indent=0] mono_Int [no_vars] (mono_Int)} › (*<*)oops(*>*)
subsection‹Another Example of Rule Inversion›
text‹ \index{rule inversion|(}% Does 🍋‹gterms› d functionis monotone, so ‹mono_Int› gives one of the inclusions. The
opposite inclusion asserts that if🍋‹t›is a ground term over both of the
sets 🍋‹F›and~🍋‹G›then it isalso a ground term over their intersection, 🍋‹F ∩ G›. ›
lemma gterms_IntI: "t ∈ gterms F ==> t ∈ gterms G ⟶ t ∈ gterms (F∩G)" (*<*)oops(*>*) text‹ Attempting this proof, we get the assumption 🍋‹Apply f args ∈ gterms G›,
It looks like a job for rule inversion:\cmmdx{inductive\protect\_cases} ›
inductive_cases gterm_Apply_elim [elim!]: "Apply f args ∈ gterms F"
text‹ Here is the result. @{named_thms [display,indent=0,margin=50] gterm_Apply_elim [no_vars] (gterm_Apply_elim)} This rule replaces an assumption about 🍋‹Apply f args› b
assumptions about 🍋‹f›and~🍋‹args›.
No cases are discarded (there was only one tobegin with) but the rule applies specifically to the pattern 🍋‹Apply f args›.
It can be applied repeatedly as an elimination rule without looping, so we have given the ‹elim!› attribute.
Now we can prove the other half of that distributive law. ›
lemma gterms_IntI [rule_format, intro!]: "t ∈ gterms F ==> t ∈ gterms G ⟶ t ∈ gterms (F∩G)" apply (erule gterms.induct) apply blast done (*<*) lemma"t ∈ gterms F ==> t ∈ gterms G ⟶ t ∈ gterms (F∩G)" apply (erule gterms.induct) (*>*) txt‹ The proof begins with rule induction over the definition of 🍋‹gterms›,
@{subgoals[display,indent=0,margin=65]} To prove this, we assume🍋‹Apply f args ∈ gterms G›. Rule inversion, in the form of ‹gterm_Apply_elim›, infers
that every element of 🍋‹args› belongs to 🍋‹gterms G›; hence (by the induction hypothesis) it belongs to🍋‹gterms (F ∩ G)›. Rule inversion also yields 🍋‹f ∈ G›andhence🍋‹f ∈ F ∩ G›.
All of this reasoning isdoneby‹blast›.
\smallskip
Our distributive law is a trivial consequence of previously-proved results: › (*<*)oops(*>*) lemma gterms_Int_eq [simp]: "gterms (F ∩ G) = gterms F ∩ gterms G" by (blast intro!: mono_Int monoI gterms_mono)
text_raw‹ \index{rule inversion|)}% \index{ground terms example|)} \begin{isamarkuptext} \begin{exercise} A function mapping function symbols to their types is called a \textbf{signature}. Given a type ranging over type symbols, we can represent a function's type by a list of argument types paired with the result type. Complete this inductive definition: \begin{isabelle} ›
inductive_set
well_typed_gterm :: "('f ==> 't list * 't) ==> ('f gterm * 't)set" for sig :: "'f ==> 't list * 't" (*<*) where
step[intro!]: "[∀pair ∈ set args. pair ∈ well_typed_gterm sig; sig f = (map snd args, rtype)] ==> (Apply f (map fst args), rtype) ∈ well_typed_gterm sig" (*>*) text_raw‹ \end{isabelle} \end{exercise} \end{isamarkuptext} ›
(*<*)
text‹the following declaration isn't actually used› primrec
integer_arity :: "integer_op ==> nat" where "integer_arity (Number n) = 0"
| "integer_arity UnaryMinus = 1"
| "integer_arity Plus = 2"
text‹the rest isn't used: too complicated. OK for an exercise though.›
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.