doc-src/TutorialI/Types/Overloading0.thy
author paulson
Fri, 12 Jan 2001 16:32:01 +0100
changeset 10885 90695f46440b
parent 10538 d1bf9ca9008d
child 11196 bb4ede27fcb7
permissions -rw-r--r--
lcp's pass over the book, chapters 1-8
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
10305
adff80268127 *** empty log message ***
nipkow
parents:
diff changeset
     1
(*<*)theory Overloading0 = Main:(*>*)
adff80268127 *** empty log message ***
nipkow
parents:
diff changeset
     2
10328
bf33cbd76c05 *** empty log message ***
nipkow
parents: 10305
diff changeset
     3
text{* We start with a concept that is required for type classes but already
bf33cbd76c05 *** empty log message ***
nipkow
parents: 10305
diff changeset
     4
useful on its own: \emph{overloading}. Isabelle allows overloading: a
bf33cbd76c05 *** empty log message ***
nipkow
parents: 10305
diff changeset
     5
constant may have multiple definitions at non-overlapping types. *}
bf33cbd76c05 *** empty log message ***
nipkow
parents: 10305
diff changeset
     6
10885
90695f46440b lcp's pass over the book, chapters 1-8
paulson
parents: 10538
diff changeset
     7
subsubsection{*An Initial Example*}
10305
adff80268127 *** empty log message ***
nipkow
parents:
diff changeset
     8
10328
bf33cbd76c05 *** empty log message ***
nipkow
parents: 10305
diff changeset
     9
text{*
bf33cbd76c05 *** empty log message ***
nipkow
parents: 10305
diff changeset
    10
If we want to introduce the notion of an \emph{inverse} for arbitrary types we
10305
adff80268127 *** empty log message ***
nipkow
parents:
diff changeset
    11
give it a polymorphic type *}
adff80268127 *** empty log message ***
nipkow
parents:
diff changeset
    12
adff80268127 *** empty log message ***
nipkow
parents:
diff changeset
    13
consts inverse :: "'a \<Rightarrow> 'a"
adff80268127 *** empty log message ***
nipkow
parents:
diff changeset
    14
adff80268127 *** empty log message ***
nipkow
parents:
diff changeset
    15
text{*\noindent
adff80268127 *** empty log message ***
nipkow
parents:
diff changeset
    16
and provide different definitions at different instances:
adff80268127 *** empty log message ***
nipkow
parents:
diff changeset
    17
*}
adff80268127 *** empty log message ***
nipkow
parents:
diff changeset
    18
adff80268127 *** empty log message ***
nipkow
parents:
diff changeset
    19
defs (overloaded)
adff80268127 *** empty log message ***
nipkow
parents:
diff changeset
    20
inverse_bool: "inverse(b::bool) \<equiv> \<not> b"
adff80268127 *** empty log message ***
nipkow
parents:
diff changeset
    21
inverse_set:  "inverse(A::'a set) \<equiv> -A"
adff80268127 *** empty log message ***
nipkow
parents:
diff changeset
    22
inverse_pair: "inverse(p) \<equiv> (inverse(fst p), inverse(snd p))"
adff80268127 *** empty log message ***
nipkow
parents:
diff changeset
    23
adff80268127 *** empty log message ***
nipkow
parents:
diff changeset
    24
text{*\noindent
adff80268127 *** empty log message ***
nipkow
parents:
diff changeset
    25
Isabelle will not complain because the three definitions do not overlap: no
adff80268127 *** empty log message ***
nipkow
parents:
diff changeset
    26
two of the three types @{typ bool}, @{typ"'a set"} and @{typ"'a \<times> 'b"} have a
adff80268127 *** empty log message ***
nipkow
parents:
diff changeset
    27
common instance. What is more, the recursion in @{thm[source]inverse_pair} is
10538
d1bf9ca9008d *** empty log message ***
nipkow
parents: 10328
diff changeset
    28
benign because the type of @{term[source]inverse} becomes smaller: on the
d1bf9ca9008d *** empty log message ***
nipkow
parents: 10328
diff changeset
    29
left it is @{typ"'a \<times> 'b \<Rightarrow> 'a \<times> 'b"} but on the right @{typ"'a \<Rightarrow> 'a"} and
d1bf9ca9008d *** empty log message ***
nipkow
parents: 10328
diff changeset
    30
@{typ"'b \<Rightarrow> 'b"}. The annotation @{text"(overloaded)"} tells Isabelle that
d1bf9ca9008d *** empty log message ***
nipkow
parents: 10328
diff changeset
    31
the definitions do intentionally define @{term[source]inverse} only at
d1bf9ca9008d *** empty log message ***
nipkow
parents: 10328
diff changeset
    32
instances of its declared type @{typ"'a \<Rightarrow> 'a"} --- this merely supresses
d1bf9ca9008d *** empty log message ***
nipkow
parents: 10328
diff changeset
    33
warnings to that effect.
10305
adff80268127 *** empty log message ***
nipkow
parents:
diff changeset
    34
adff80268127 *** empty log message ***
nipkow
parents:
diff changeset
    35
However, there is nothing to prevent the user from forming terms such as
10538
d1bf9ca9008d *** empty log message ***
nipkow
parents: 10328
diff changeset
    36
@{term[source]"inverse []"} and proving theorems as @{prop[source]"inverse []
d1bf9ca9008d *** empty log message ***
nipkow
parents: 10328
diff changeset
    37
= inverse []"}, although we never defined inverse on lists. We hasten to say
d1bf9ca9008d *** empty log message ***
nipkow
parents: 10328
diff changeset
    38
that there is nothing wrong with such terms and theorems. But it would be
d1bf9ca9008d *** empty log message ***
nipkow
parents: 10328
diff changeset
    39
nice if we could prevent their formation, simply because it is very likely
d1bf9ca9008d *** empty log message ***
nipkow
parents: 10328
diff changeset
    40
that the user did not mean to write what he did. Thus he had better not waste
d1bf9ca9008d *** empty log message ***
nipkow
parents: 10328
diff changeset
    41
his time pursuing it further. This requires the use of type classes.
10305
adff80268127 *** empty log message ***
nipkow
parents:
diff changeset
    42
*}
adff80268127 *** empty log message ***
nipkow
parents:
diff changeset
    43
(*<*)end(*>*)