doc-src/IsarAdvanced/Classes/Thy/Classes.thy
changeset 24991 c6f5cc939c29
parent 24628 33137422d7fd
child 25200 f1d2e106f2fe
equal deleted inserted replaced
24990:b924fac38eec 24991:c6f5cc939c29
     1 (* $Id$ *)
     1 (* $Id$ *)
     2 
     2 
     3 (*<*)
     3 (*<*)
     4 theory Classes
     4 theory Classes
     5 imports Main Pretty_Int
     5 imports Main Code_Integer
     6 begin
     6 begin
     7 
     7 
     8 ML {*
     8 ML {*
     9 CodeTarget.code_width := 74;
     9 CodeTarget.code_width := 74;
    10 *}
    10 *}
   108   algebra \cite{Nipkow-Prehofer:1993,nipkow-sorts93,Wenzel:1997:TPHOL}.
   108   algebra \cite{Nipkow-Prehofer:1993,nipkow-sorts93,Wenzel:1997:TPHOL}.
   109 
   109 
   110   From a software enigineering point of view, type classes
   110   From a software enigineering point of view, type classes
   111   correspond to interfaces in object-oriented languages like Java;
   111   correspond to interfaces in object-oriented languages like Java;
   112   so, it is naturally desirable that type classes do not only
   112   so, it is naturally desirable that type classes do not only
   113   provide functions (class operations) but also state specifications
   113   provide functions (class parameters) but also state specifications
   114   implementations must obey.  For example, the @{text "class eq"}
   114   implementations must obey.  For example, the @{text "class eq"}
   115   above could be given the following specification, demanding that
   115   above could be given the following specification, demanding that
   116   @{text "class eq"} is an equivalence relation obeying reflexivity,
   116   @{text "class eq"} is an equivalence relation obeying reflexivity,
   117   symmetry and transitivity:
   117   symmetry and transitivity:
   118 
   118 
   128   SML functors \cite{classes_modules}. 
   128   SML functors \cite{classes_modules}. 
   129   Isabelle/Isar offers a discipline of type classes which brings
   129   Isabelle/Isar offers a discipline of type classes which brings
   130   all those aspects together:
   130   all those aspects together:
   131 
   131 
   132   \begin{enumerate}
   132   \begin{enumerate}
   133     \item specifying abstract operations togehter with
   133     \item specifying abstract parameters together with
   134        corresponding specifications,
   134        corresponding specifications,
   135     \item instantating those abstract operations by a particular
   135     \item instantating those abstract parameters by a particular
   136        type
   136        type
   137     \item in connection with a ``less ad-hoc'' approach to overloading,
   137     \item in connection with a ``less ad-hoc'' approach to overloading,
   138     \item with a direct link to the Isabelle module system
   138     \item with a direct link to the Isabelle module system
   139       (aka locales \cite{kammueller-locales}).
   139       (aka locales \cite{kammueller-locales}).
   140   \end{enumerate}
   140   \end{enumerate}
   157 
   157 
   158 subsection {* Class definition *}
   158 subsection {* Class definition *}
   159 
   159 
   160 text {*
   160 text {*
   161   Depending on an arbitrary type @{text "\<alpha>"}, class @{text
   161   Depending on an arbitrary type @{text "\<alpha>"}, class @{text
   162   "semigroup"} introduces a binary operation @{text "\<circ>"} that is
   162   "semigroup"} introduces a binary operator @{text "\<otimes>"} that is
   163   assumed to be associative:
   163   assumed to be associative:
   164 *}
   164 *}
   165 
   165 
   166     class semigroup = type +
   166     class semigroup = type +
   167       fixes mult :: "\<alpha> \<Rightarrow> \<alpha> \<Rightarrow> \<alpha>"    (infixl "\<^loc>\<otimes>" 70)
   167       fixes mult :: "\<alpha> \<Rightarrow> \<alpha> \<Rightarrow> \<alpha>"    (infixl "\<^loc>\<otimes>" 70)
   168       assumes assoc: "(x \<^loc>\<otimes> y) \<^loc>\<otimes> z = x \<^loc>\<otimes> (y \<^loc>\<otimes> z)"
   168       assumes assoc: "(x \<^loc>\<otimes> y) \<^loc>\<otimes> z = x \<^loc>\<otimes> (y \<^loc>\<otimes> z)"
   169 
   169 
   170 text {*
   170 text {*
   171   \noindent This @{text "\<CLASS>"} specification consists of two
   171   \noindent This @{text "\<CLASS>"} specification consists of two
   172   parts: the \qn{operational} part names the class operation (@{text
   172   parts: the \qn{operational} part names the class parameter (@{text
   173   "\<FIXES>"}), the \qn{logical} part specifies properties on them
   173   "\<FIXES>"}), the \qn{logical} part specifies properties on them
   174   (@{text "\<ASSUMES>"}).  The local @{text "\<FIXES>"} and @{text
   174   (@{text "\<ASSUMES>"}).  The local @{text "\<FIXES>"} and @{text
   175   "\<ASSUMES>"} are lifted to the theory toplevel, yielding the global
   175   "\<ASSUMES>"} are lifted to the theory toplevel, yielding the global
   176   operation @{term [source] "mult \<Colon> \<alpha>\<Colon>semigroup \<Rightarrow> \<alpha> \<Rightarrow> \<alpha>"} and the
   176   parameter @{term [source] "mult \<Colon> \<alpha>\<Colon>semigroup \<Rightarrow> \<alpha> \<Rightarrow> \<alpha>"} and the
   177   global theorem @{text "semigroup.assoc:"}~@{prop [source] "\<And>x y
   177   global theorem @{text "semigroup.assoc:"}~@{prop [source] "\<And>x y
   178   z \<Colon> \<alpha>\<Colon>semigroup. (x \<otimes> y) \<otimes> z = x \<otimes> (y \<otimes> z)"}.
   178   z \<Colon> \<alpha>\<Colon>semigroup. (x \<otimes> y) \<otimes> z = x \<otimes> (y \<otimes> z)"}.
   179 *}
   179 *}
   180 
   180 
   181 
   181 
   182 subsection {* Class instantiation \label{sec:class_inst} *}
   182 subsection {* Class instantiation \label{sec:class_inst} *}
   183 
   183 
   184 text {*
   184 text {*
   185   The concrete type @{text "int"} is made a @{text "semigroup"}
   185   The concrete type @{text "int"} is made a @{text "semigroup"}
   186   instance by providing a suitable definition for the class operation
   186   instance by providing a suitable definition for the class parameter
   187   @{text "mult"} and a proof for the specification of @{text "assoc"}.
   187   @{text "mult"} and a proof for the specification of @{text "assoc"}.
   188 *}
   188 *}
   189 
   189 
   190     instance int :: semigroup
   190     instance int :: semigroup
   191       mult_int_def: "i \<otimes> j \<equiv> i + j"
   191       mult_int_def: "i \<otimes> j \<equiv> i + j"
   215       show "m \<otimes> n \<otimes> q = m \<otimes> (n \<otimes> q)" unfolding mult_nat_def by simp
   215       show "m \<otimes> n \<otimes> q = m \<otimes> (n \<otimes> q)" unfolding mult_nat_def by simp
   216     qed
   216     qed
   217 
   217 
   218 text {*
   218 text {*
   219   \noindent Also @{text "list"}s form a semigroup with @{const "op @"} as
   219   \noindent Also @{text "list"}s form a semigroup with @{const "op @"} as
   220   operation:
   220   parameter:
   221 *}
   221 *}
   222 
   222 
   223     instance list :: (type) semigroup
   223     instance list :: (type) semigroup
   224       mult_list_def: "xs \<otimes> ys \<equiv> xs @ ys"
   224       mult_list_def: "xs \<otimes> ys \<equiv> xs @ ys"
   225     proof
   225     proof
   235 subsection {* Subclasses *}
   235 subsection {* Subclasses *}
   236 
   236 
   237 text {*
   237 text {*
   238   We define a subclass @{text "monoidl"} (a semigroup with a left-hand neutral)
   238   We define a subclass @{text "monoidl"} (a semigroup with a left-hand neutral)
   239   by extending @{text "semigroup"}
   239   by extending @{text "semigroup"}
   240   with one additional operation @{text "neutral"} together
   240   with one additional parameter @{text "neutral"} together
   241   with its property:
   241   with its property:
   242 *}
   242 *}
   243 
   243 
   244     class monoidl = semigroup +
   244     class monoidl = semigroup +
   245       fixes neutral :: "\<alpha>" ("\<^loc>\<one>")
   245       fixes neutral :: "\<alpha>" ("\<^loc>\<one>")
   246       assumes neutl: "\<^loc>\<one> \<^loc>\<otimes> x = x"
   246       assumes neutl: "\<^loc>\<one> \<^loc>\<otimes> x = x"
   247 
   247 
   248 text {*
   248 text {*
   249   \noindent Again, we make some instances, by
   249   \noindent Again, we make some instances, by
   250   providing suitable operation definitions and proofs for the
   250   providing suitable parameter definitions and proofs for the
   251   additional specifications.
   251   additional specifications.
   252 *}
   252 *}
   253 
   253 
   254     instance nat :: monoidl
   254     instance nat :: monoidl
   255       neutral_nat_def: "\<one> \<equiv> 0"
   255       neutral_nat_def: "\<one> \<equiv> 0"
   277       qed
   277       qed
   278     qed  
   278     qed  
   279 
   279 
   280 text {*
   280 text {*
   281   \noindent Fully-fledged monoids are modelled by another subclass
   281   \noindent Fully-fledged monoids are modelled by another subclass
   282   which does not add new operations but tightens the specification:
   282   which does not add new parameters but tightens the specification:
   283 *}
   283 *}
   284 
   284 
   285     class monoid = monoidl +
   285     class monoid = monoidl +
   286       assumes neutr: "x \<^loc>\<otimes> \<^loc>\<one> = x"
   286       assumes neutr: "x \<^loc>\<otimes> \<^loc>\<one> = x"
   287 
   287 
   427   definitions you may use any specification tool
   427   definitions you may use any specification tool
   428   which works together with locales (e.g. \cite{krauss2006}).
   428   which works together with locales (e.g. \cite{krauss2006}).
   429 *}
   429 *}
   430 
   430 
   431 
   431 
   432 (*subsection {* Additional subclass relations *}
   432 subsection {* Additional subclass relations *}
   433 
   433 
   434 text {*
   434 text {*
   435   Any @{text "group"} is also a @{text "monoid"};  this
   435   Any @{text "group"} is also a @{text "monoid"};  this
   436   can be made explicit by claiming an additional subclass relation,
   436   can be made explicit by claiming an additional subclass relation,
   437   together with a proof of the logical difference:
   437   together with a proof of the logical difference:
   438 *}
   438 *}
   439 
   439 
   440     instance advanced group < monoid
   440     subclass (in group) monoid
   441     proof unfold_locales
   441     proof unfold_locales
   442       fix x
   442       fix x
   443       from invl have "x\<^loc>\<div> \<^loc>\<otimes> x = \<^loc>\<one>" by simp
   443       from invl have "x\<^loc>\<div> \<^loc>\<otimes> x = \<^loc>\<one>" by simp
   444       with assoc [symmetric] neutl invl have "x\<^loc>\<div> \<^loc>\<otimes> (x \<^loc>\<otimes> \<^loc>\<one>) = x\<^loc>\<div> \<^loc>\<otimes> x" by simp
   444       with assoc [symmetric] neutl invl have "x\<^loc>\<div> \<^loc>\<otimes> (x \<^loc>\<otimes> \<^loc>\<one>) = x\<^loc>\<div> \<^loc>\<otimes> x" by simp
   445       with left_cancel show "x \<^loc>\<otimes> \<^loc>\<one> = x" by simp
   445       with left_cancel show "x \<^loc>\<otimes> \<^loc>\<one> = x" by simp
   450   and thus conveniently is opened using the @{text unfold_locales}
   450   and thus conveniently is opened using the @{text unfold_locales}
   451   method which only leaves the logical differences still
   451   method which only leaves the logical differences still
   452   open to proof to the user.  After the proof it is propagated
   452   open to proof to the user.  After the proof it is propagated
   453   to the type system, making @{text group} an instance of
   453   to the type system, making @{text group} an instance of
   454   @{text monoid}.  For illustration, a derived definition
   454   @{text monoid}.  For illustration, a derived definition
   455   in @{text group} which uses @{text of_nat}:
   455   in @{text group} which uses @{text pow_nat}:
   456 *}
   456 *}
   457 
   457 
   458     definition (in group)
   458     definition (in group)
   459       pow_int :: "int \<Rightarrow> \<alpha> \<Rightarrow> \<alpha>" where
   459       pow_int :: "int \<Rightarrow> \<alpha> \<Rightarrow> \<alpha>" where
   460       "pow_int k x = (if k >= 0
   460       "pow_int k x = (if k >= 0
   463 
   463 
   464 text {*
   464 text {*
   465   yields the global definition of
   465   yields the global definition of
   466   @{term [source] "pow_int \<Colon> int \<Rightarrow> \<alpha>\<Colon>group \<Rightarrow> \<alpha>\<Colon>group"}
   466   @{term [source] "pow_int \<Colon> int \<Rightarrow> \<alpha>\<Colon>group \<Rightarrow> \<alpha>\<Colon>group"}
   467   with the corresponding theorem @{thm pow_int_def [no_vars]}.
   467   with the corresponding theorem @{thm pow_int_def [no_vars]}.
   468 *} *)
   468 *}
   469 
   469 
   470 
   470 
   471 section {* Further issues *}
   471 section {* Further issues *}
   472 
   472 
   473 subsection {* Code generation *}
   473 subsection {* Code generation *}
   482   lacking type classes (e.g.~SML), type classes
   482   lacking type classes (e.g.~SML), type classes
   483   are implemented by explicit dictionary construction.
   483   are implemented by explicit dictionary construction.
   484   For example, lets go back to the power function:
   484   For example, lets go back to the power function:
   485 *}
   485 *}
   486 
   486 
   487     fun
   487 (*    fun
   488       pow_nat :: "nat \<Rightarrow> \<alpha>\<Colon>group \<Rightarrow> \<alpha>\<Colon>group" where
   488       pow_nat :: "nat \<Rightarrow> \<alpha>\<Colon>group \<Rightarrow> \<alpha>\<Colon>group" where
   489       "pow_nat 0 x = \<one>"
   489       "pow_nat 0 x = \<one>"
   490       | "pow_nat (Suc n) x = x \<otimes> pow_nat n x"
   490       | "pow_nat (Suc n) x = x \<otimes> pow_nat n x"
   491 
   491 
   492     definition
   492     definition
   493       pow_int :: "int \<Rightarrow> \<alpha>\<Colon>group \<Rightarrow> \<alpha>\<Colon>group" where
   493       pow_int :: "int \<Rightarrow> \<alpha>\<Colon>group \<Rightarrow> \<alpha>\<Colon>group" where
   494       "pow_int k x = (if k >= 0
   494       "pow_int k x = (if k >= 0
   495         then pow_nat (nat k) x
   495         then pow_nat (nat k) x
   496         else (pow_nat (nat (- k)) x)\<div>)"
   496         else (pow_nat (nat (- k)) x)\<div>)"*)
   497 
   497 
   498     definition
   498     definition
   499       example :: int where
   499       example :: int where
   500       "example = pow_int 10 (-2)"
   500       "example = pow_int 10 (-2)"
   501 
   501