doc-src/TutorialI/Types/Overloading0.thy
author wenzelm
Fri, 10 Nov 2000 19:15:38 +0100
changeset 10448 da7d0e28f746
parent 10328 bf33cbd76c05
child 10538 d1bf9ca9008d
permissions -rw-r--r--
tuned;
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
10305
adff80268127 *** empty log message ***
nipkow
parents:
diff changeset
     7
subsubsection{*An initial example*}
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
adff80268127 *** empty log message ***
nipkow
parents:
diff changeset
    28
benign because the type of @{term inverse} becomes smaller: on the left it is
adff80268127 *** empty log message ***
nipkow
parents:
diff changeset
    29
@{typ"'a \<times> 'b \<Rightarrow> 'a \<times> 'b"} but on the right @{typ"'a \<Rightarrow> 'a"} and @{typ"'b \<Rightarrow>
10328
bf33cbd76c05 *** empty log message ***
nipkow
parents: 10305
diff changeset
    30
'b"}. The annotation @{text"(overloaded)"} tells Isabelle that the definitions do
10305
adff80268127 *** empty log message ***
nipkow
parents:
diff changeset
    31
intentionally define @{term inverse} only at instances of its declared type
adff80268127 *** empty log message ***
nipkow
parents:
diff changeset
    32
@{typ"'a \<Rightarrow> 'a"} --- this merely supresses warnings to that effect.
adff80268127 *** empty log message ***
nipkow
parents:
diff changeset
    33
adff80268127 *** empty log message ***
nipkow
parents:
diff changeset
    34
However, there is nothing to prevent the user from forming terms such as
adff80268127 *** empty log message ***
nipkow
parents:
diff changeset
    35
@{term"inverse []"} and proving theorems as @{prop"inverse [] = inverse []"},
adff80268127 *** empty log message ***
nipkow
parents:
diff changeset
    36
although we never defined inverse on lists. We hasten to say that there is
adff80268127 *** empty log message ***
nipkow
parents:
diff changeset
    37
nothing wrong with such terms and theorems. But it would be nice if we could
adff80268127 *** empty log message ***
nipkow
parents:
diff changeset
    38
prevent their formation, simply because it is very likely that the user did
adff80268127 *** empty log message ***
nipkow
parents:
diff changeset
    39
not mean to write what he did. Thus he had better not waste his time pursuing
adff80268127 *** empty log message ***
nipkow
parents:
diff changeset
    40
it further. This requires the use of type classes.
adff80268127 *** empty log message ***
nipkow
parents:
diff changeset
    41
*}
adff80268127 *** empty log message ***
nipkow
parents:
diff changeset
    42
(*<*)end(*>*)