Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/Isabelle/Doc/Tutorial/Inductive/   (Beweissystem Isabelle Version 2025-1©)  Datei vom 16.11.2025 mit Größe 15 kB image not shown  

Quelle  Advanced.thy

  Sprache: Isabelle
 

(*<*)theory Advanced imports Even begin(*>*)

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.
 

subsectionUniversal 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 is inductiveIf we have a list args of ground terms 
over~F and a function symbol f in Fthen we 
can apply f to args to obtain another ground term
The only difficulty is that the argument list may be of any length. Hitherto, 
each rule in an inductive definition 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: "FG ==> gterms F gterms G"
apply clarify
apply (erule gterms.induct)
apply blast
done
(*<*)
lemma gterms_mono: "FG ==> 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~Gand 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 inductive definition 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~fIf 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!and inductive definitions|)}


subsectionAlternative 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.
functionfrom 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 inductive definition 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.


inductive_set
  well_formed_gterm' :: "('f ==> nat) ==> 'f gterm set"
  for arity :: "'f ==> nat"
where
step[intro!]: "[args lists (well_formed_gterm' arity);
                length args = arity f]
               ==> (Apply f args) well_formed_gterm' arity"
monos lists_mono

text 
 We cite the theorem lists_mono t
using the function 🍋lists.%
\footnote{This particular theorem is installed by default already, but we
include the \isakeyword{monosdeclaration in order to illustrate its syntax.}
@{named_thms [display,indent=0] lists_mono [no_vars] (lists_mono)}
Why must the function be monotone?  An inductive definition 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
inductive definition 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 inductive definition:
\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 to show 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]}
To apply 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!and inductive definitions|)} 


subsectionA 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 function in the inductive definition 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(*>*)


subsectionAnother Example of Rule Inversion

text 
 \index{rule inversion|(}%
 Does 🍋gterms d
function is 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 is also a ground term over their intersection,
🍋F G.


lemma gterms_IntI:
     "t gterms F ==> t gterms G t gterms (FG)"
(*<*)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 to begin
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 (FG)"
apply (erule gterms.induct)
apply blast
done
(*<*)
lemma "t gterms F ==> t gterms G t gterms (FG)"
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 Ghence (by the induction hypothesis) it belongs
to 🍋gterms (F G).  Rule inversion also yields
🍋f G and hence 🍋f F G
All of this reasoning is done by 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}
 

(*<*)

textthe 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"

textthe rest isn't used: too complicated. OK for an exercise though.

inductive_set
  integer_signature :: "(integer_op * (unit list * unit)) set"
where
  Number:     "(Number n, ([], ())) integer_signature"
| UnaryMinus: "(UnaryMinus, ([()], ())) integer_signature"
| Plus:       "(Plus, ([(),()], ())) integer_signature"

inductive_set
  well_typed_gterm' :: "('f ==> 't list * 't) ==> ('f gterm * 't)set"
  for sig :: "'f ==> 't list * 't"
where
step[intro!]: 
    "[args lists(well_typed_gterm' sig);
      sig f = (map snd args, rtype)]
     ==> (Apply f (map fst args), rtype)
          well_typed_gterm' sig"
monos lists_mono


lemma "well_typed_gterm sig well_typed_gterm' sig"
apply clarify
apply (erule well_typed_gterm.induct)
apply auto
done

lemma "well_typed_gterm' sig well_typed_gterm sig"
apply clarify
apply (erule well_typed_gterm'.induct)
apply auto
done


end
(*>*)

Messung V0.5 in Prozent
C=53 H=74 G=64

¤ Dauer der Verarbeitung: 0.30 Sekunden  (vorverarbeitet am  2026-04-25) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

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.