Merge.
1.1 --- a/Admin/CHECKLIST Wed Mar 04 11:05:02 2009 +0100
1.2 +++ b/Admin/CHECKLIST Wed Mar 04 11:05:29 2009 +0100
1.3 @@ -1,7 +1,7 @@
1.4 Checklist for official releases
1.5 ===============================
1.6
1.7 -- test alice, mosml, polyml-5.0, polyml-4.1.3, polyml-4.1.4, polyml-4.2.0, x86-solaris, x86-cygwin;
1.8 +- test mosml, polyml-5.0, polyml-4.1.3, polyml-4.1.4, polyml-4.2.0, x86-solaris, x86-cygwin;
1.9
1.10 - test ProofGeneral;
1.11
2.1 --- a/Admin/isatest/isatest-stats Wed Mar 04 11:05:02 2009 +0100
2.2 +++ b/Admin/isatest/isatest-stats Wed Mar 04 11:05:29 2009 +0100
2.3 @@ -16,6 +16,7 @@
2.4 HOL-Algebra \
2.5 HOL-Auth \
2.6 HOL-Bali \
2.7 + HOL-Decision_Procs \
2.8 HOL-Extraction \
2.9 HOL-Hoare \
2.10 HOL-HoareParallel \
3.1 --- a/Admin/isatest/settings/sun-poly Wed Mar 04 11:05:02 2009 +0100
3.2 +++ b/Admin/isatest/settings/sun-poly Wed Mar 04 11:05:29 2009 +0100
3.3 @@ -4,7 +4,7 @@
3.4 ML_SYSTEM="polyml-5.1"
3.5 ML_PLATFORM="sparc-solaris"
3.6 ML_HOME="$POLYML_HOME/$ML_PLATFORM"
3.7 - ML_OPTIONS="-H 1500"
3.8 + ML_OPTIONS="-H 800"
3.9
3.10 ISABELLE_HOME_USER=/tmp/isabelle-sun-poly
3.11
4.1 --- a/Admin/makedist Wed Mar 04 11:05:02 2009 +0100
4.2 +++ b/Admin/makedist Wed Mar 04 11:05:29 2009 +0100
4.3 @@ -4,7 +4,7 @@
4.4
4.5 ## global settings
4.6
4.7 -REPOS="https://isabelle.in.tum.de/repos/isabelle"
4.8 +REPOS="http://isabelle.in.tum.de/repos/isabelle"
4.9
4.10 DISTPREFIX=${DISTPREFIX:-~/tmp/isadist}
4.11
4.12 @@ -156,7 +156,7 @@
4.13 rm doc/codegen_process.pdf
4.14 rm -rf doc-src
4.15
4.16 -mkdir contrib
4.17 +mkdir -p contrib
4.18
4.19 cp doc/isabelle*.eps lib/logo
4.20
5.1 --- a/CONTRIBUTORS Wed Mar 04 11:05:02 2009 +0100
5.2 +++ b/CONTRIBUTORS Wed Mar 04 11:05:29 2009 +0100
5.3 @@ -7,10 +7,16 @@
5.4 Contributions to this Isabelle version
5.5 --------------------------------------
5.6
5.7 -* February 2008: Timothy Bourke, NICTA
5.8 +* February 2009: Filip Maric, Univ. of Belgrade
5.9 + A Serbian theory.
5.10 +
5.11 +* February 2009: Jasmin Christian Blanchette, TUM
5.12 + Misc cleanup of HOL/refute.
5.13 +
5.14 +* February 2009: Timothy Bourke, NICTA
5.15 New find_consts command.
5.16
5.17 -* February 2008: Timothy Bourke, NICTA
5.18 +* February 2009: Timothy Bourke, NICTA
5.19 "solves" criterion for find_theorems and auto_solve option
5.20
5.21 * December 2008: Clemens Ballarin, TUM
5.22 @@ -31,6 +37,9 @@
5.23 processes. Additional ATP wrappers, including remote SystemOnTPTP
5.24 services.
5.25
5.26 +* September 2008: Stefan Berghofer, TUM and Marc Bezem, Univ. Bergen
5.27 + Prover for coherent logic.
5.28 +
5.29 * August 2008: Fabian Immler, TUM
5.30 Vampire wrapper script for remote SystemOnTPTP service.
5.31
5.32 @@ -46,7 +55,7 @@
5.33 HOLCF library improvements.
5.34
5.35 * 2007/2008: Stefan Berghofer, TUM
5.36 - HOL-Nominal package improvements.
5.37 + HOL-Nominal package improvements.
5.38
5.39 * March 2008: Markus Reiter, TUM
5.40 HOL/Library/RBT: red-black trees.
6.1 --- a/NEWS Wed Mar 04 11:05:02 2009 +0100
6.2 +++ b/NEWS Wed Mar 04 11:05:29 2009 +0100
6.3 @@ -6,6 +6,10 @@
6.4
6.5 *** General ***
6.6
6.7 +* The main reference manuals (isar-ref, implementation, system) have
6.8 +been updated and extended. Formally checked references as hyperlinks
6.9 +are now available in uniform manner.
6.10 +
6.11 * Simplified main Isabelle executables, with less surprises on
6.12 case-insensitive file-systems (such as Mac OS).
6.13
6.14 @@ -47,9 +51,6 @@
6.15 regular 4-core machine, if the initial heap space is made reasonably
6.16 large (cf. Poly/ML option -H). [Poly/ML 5.2.1 or later]
6.17
6.18 -* The Isabelle System Manual (system) has been updated, with formally
6.19 -checked references as hyperlinks.
6.20 -
6.21 * Generalized Isar history, with support for linear undo, direct state
6.22 addressing etc.
6.23
6.24 @@ -63,6 +64,8 @@
6.25 * There is a new syntactic category "float_const" for signed decimal
6.26 fractions (e.g. 123.45 or -123.45).
6.27
6.28 +* New prover for coherent logic (see src/Tools/coherent.ML).
6.29 +
6.30
6.31 *** Pure ***
6.32
6.33 @@ -111,30 +114,32 @@
6.34 unify_trace_bound = 50 (formerly 25)
6.35 unify_search_bound = 60 (formerly 30)
6.36
6.37 -* Different bookkeeping for code equations:
6.38 - a) On theory merge, the last set of code equations for a particular constant
6.39 - is taken (in accordance with the policy applied by other parts of the
6.40 - code generator framework).
6.41 - b) Code equations stemming from explicit declarations (e.g. code attribute)
6.42 - gain priority over default code equations stemming from definition, primrec,
6.43 - fun etc.
6.44 - INCOMPATIBILITY.
6.45 -
6.46 -* Global versions of theorems stemming from classes do not carry
6.47 -a parameter prefix any longer. INCOMPATIBILITY.
6.48 +* Different bookkeeping for code equations (INCOMPATIBILITY):
6.49 +
6.50 + a) On theory merge, the last set of code equations for a particular
6.51 + constant is taken (in accordance with the policy applied by other
6.52 + parts of the code generator framework).
6.53 +
6.54 + b) Code equations stemming from explicit declarations (e.g. code
6.55 + attribute) gain priority over default code equations stemming
6.56 + from definition, primrec, fun etc.
6.57 +
6.58 +* Global versions of theorems stemming from classes do not carry a
6.59 +parameter prefix any longer. INCOMPATIBILITY.
6.60
6.61 * Dropped locale element "includes". This is a major INCOMPATIBILITY.
6.62 In existing theorem specifications replace the includes element by the
6.63 -respective context elements of the included locale, omitting those that
6.64 -are already present in the theorem specification. Multiple assume
6.65 -elements of a locale should be replaced by a single one involving the
6.66 -locale predicate. In the proof body, declarations (most notably
6.67 -theorems) may be regained by interpreting the respective locales in the
6.68 -proof context as required (command "interpret").
6.69 +respective context elements of the included locale, omitting those
6.70 +that are already present in the theorem specification. Multiple
6.71 +assume elements of a locale should be replaced by a single one
6.72 +involving the locale predicate. In the proof body, declarations (most
6.73 +notably theorems) may be regained by interpreting the respective
6.74 +locales in the proof context as required (command "interpret").
6.75 +
6.76 If using "includes" in replacement of a target solely because the
6.77 parameter types in the theorem are not as general as in the target,
6.78 -consider declaring a new locale with additional type constraints on the
6.79 -parameters (context element "constrains").
6.80 +consider declaring a new locale with additional type constraints on
6.81 +the parameters (context element "constrains").
6.82
6.83 * Dropped "locale (open)". INCOMPATIBILITY.
6.84
6.85 @@ -145,9 +150,9 @@
6.86 * Interpretation commands no longer accept interpretation attributes.
6.87 INCOMPATBILITY.
6.88
6.89 -* Complete re-implementation of locales. INCOMPATIBILITY.
6.90 -The most important changes are listed below. See documentation
6.91 -(forthcoming) and tutorial (also forthcoming) for details.
6.92 +* Complete re-implementation of locales. INCOMPATIBILITY. The most
6.93 +important changes are listed below. See documentation (forthcoming)
6.94 +and tutorial (also forthcoming) for details.
6.95
6.96 - In locale expressions, instantiation replaces renaming. Parameters
6.97 must be declared in a for clause. To aid compatibility with previous
6.98 @@ -161,15 +166,15 @@
6.99
6.100 - More flexible mechanisms to qualify names generated by locale
6.101 expressions. Qualifiers (prefixes) may be specified in locale
6.102 -expressions. Available are normal qualifiers (syntax "name:") and strict
6.103 -qualifiers (syntax "name!:"). The latter must occur in name references
6.104 -and are useful to avoid accidental hiding of names, the former are
6.105 -optional. Qualifiers derived from the parameter names of a locale are no
6.106 -longer generated.
6.107 -
6.108 -- "sublocale l < e" replaces "interpretation l < e". The instantiation
6.109 -clause in "interpretation" and "interpret" (square brackets) is no
6.110 -longer available. Use locale expressions.
6.111 +expressions. Available are normal qualifiers (syntax "name:") and
6.112 +strict qualifiers (syntax "name!:"). The latter must occur in name
6.113 +references and are useful to avoid accidental hiding of names, the
6.114 +former are optional. Qualifiers derived from the parameter names of a
6.115 +locale are no longer generated.
6.116 +
6.117 +- "sublocale l < e" replaces "interpretation l < e". The
6.118 +instantiation clause in "interpretation" and "interpret" (square
6.119 +brackets) is no longer available. Use locale expressions.
6.120
6.121 - When converting proof scripts, be sure to replace qualifiers in
6.122 "interpretation" and "interpret" by strict qualifiers. Qualifiers in
6.123 @@ -183,8 +188,8 @@
6.124 * The 'axiomatization' command now only works within a global theory
6.125 context. INCOMPATIBILITY.
6.126
6.127 -* New find_theorems criterion "solves" matching theorems that
6.128 -directly solve the current goal. Try "find_theorems solves".
6.129 +* New find_theorems criterion "solves" matching theorems that directly
6.130 +solve the current goal. Try "find_theorems solves".
6.131
6.132 * Added an auto solve option, which can be enabled through the
6.133 ProofGeneral Isabelle settings menu (disabled by default).
6.134 @@ -193,14 +198,15 @@
6.135 stated. Any theorems that could solve the lemma directly are listed
6.136 underneath the goal.
6.137
6.138 -* New command find_consts searches for constants based on type and name
6.139 -patterns, e.g.
6.140 +* New command find_consts searches for constants based on type and
6.141 +name patterns, e.g.
6.142
6.143 find_consts "_ => bool"
6.144
6.145 -By default, matching is against subtypes, but it may be restricted to the
6.146 -whole type. Searching by name is possible. Multiple queries are conjunctive
6.147 -and queries may be negated by prefixing them with a hyphen:
6.148 +By default, matching is against subtypes, but it may be restricted to
6.149 +the whole type. Searching by name is possible. Multiple queries are
6.150 +conjunctive and queries may be negated by prefixing them with a
6.151 +hyphen:
6.152
6.153 find_consts strict: "_ => bool" name: "Int" -"int => int"
6.154
6.155 @@ -240,7 +246,7 @@
6.156 src/HOL/Library/Order_Relation.thy ~> src/HOL/
6.157 src/HOL/Library/Parity.thy ~> src/HOL/
6.158 src/HOL/Library/Univ_Poly.thy ~> src/HOL/
6.159 - src/HOL/Real/ContNotDenum.thy ~> src/HOL/
6.160 + src/HOL/Real/ContNotDenum.thy ~> src/HOL/Library/
6.161 src/HOL/Real/Lubs.thy ~> src/HOL/
6.162 src/HOL/Real/PReal.thy ~> src/HOL/
6.163 src/HOL/Real/Rational.thy ~> src/HOL/
6.164 @@ -250,8 +256,8 @@
6.165 src/HOL/Real/Real.thy ~> src/HOL/
6.166 src/HOL/Complex/Complex_Main.thy ~> src/HOL/
6.167 src/HOL/Complex/Complex.thy ~> src/HOL/
6.168 - src/HOL/Complex/FrechetDeriv.thy ~> src/HOL/
6.169 - src/HOL/Complex/Fundamental_Theorem_Algebra.thy ~> src/HOL/
6.170 + src/HOL/Complex/FrechetDeriv.thy ~> src/HOL/Library/
6.171 + src/HOL/Complex/Fundamental_Theorem_Algebra.thy ~> src/HOL/Library/
6.172 src/HOL/Hyperreal/Deriv.thy ~> src/HOL/
6.173 src/HOL/Hyperreal/Fact.thy ~> src/HOL/
6.174 src/HOL/Hyperreal/Integration.thy ~> src/HOL/
6.175 @@ -312,7 +318,7 @@
6.176 process. New thread-based implementation also works on non-Unix
6.177 platforms (Cygwin). Provers are no longer hardwired, but defined
6.178 within the theory via plain ML wrapper functions. Basic Sledgehammer
6.179 -commands are covered in the isar-ref manual
6.180 +commands are covered in the isar-ref manual.
6.181
6.182 * Wrapper scripts for remote SystemOnTPTP service allows to use
6.183 sledgehammer without local ATP installation (Vampire etc.). See also
6.184 @@ -342,6 +348,9 @@
6.185 etc. slightly changed. Some theorems named order_class.* now named
6.186 preorder_class.*.
6.187
6.188 +* HOL/Relation:
6.189 +Renamed "refl" to "refl_on", "reflexive" to "refl, "diag" to "Id_on".
6.190 +
6.191 * HOL/Finite_Set: added a new fold combinator of type
6.192 ('a => 'b => 'b) => 'b => 'a set => 'b
6.193 Occasionally this is more convenient than the old fold combinator which is
6.194 @@ -367,10 +376,60 @@
6.195 mult_div ~> div_mult_self2_is_id
6.196 mult_mod ~> mod_mult_self2_is_0
6.197
6.198 +* HOL/IntDiv: removed many lemmas that are instances of class-based
6.199 +generalizations (from Divides and Ring_and_Field).
6.200 +INCOMPATIBILITY. Rename old lemmas as follows:
6.201 +
6.202 +dvd_diff -> nat_dvd_diff
6.203 +dvd_zminus_iff -> dvd_minus_iff
6.204 +mod_add1_eq -> mod_add_eq
6.205 +mod_mult1_eq -> mod_mult_right_eq
6.206 +mod_mult1_eq' -> mod_mult_left_eq
6.207 +mod_mult_distrib_mod -> mod_mult_eq
6.208 +nat_mod_add_left_eq -> mod_add_left_eq
6.209 +nat_mod_add_right_eq -> mod_add_right_eq
6.210 +nat_mod_div_trivial -> mod_div_trivial
6.211 +nat_mod_mod_trivial -> mod_mod_trivial
6.212 +zdiv_zadd_self1 -> div_add_self1
6.213 +zdiv_zadd_self2 -> div_add_self2
6.214 +zdiv_zmult_self1 -> div_mult_self2_is_id
6.215 +zdiv_zmult_self2 -> div_mult_self1_is_id
6.216 +zdvd_triv_left -> dvd_triv_left
6.217 +zdvd_triv_right -> dvd_triv_right
6.218 +zdvd_zmult_cancel_disj -> dvd_mult_cancel_left
6.219 +zmod_eq0_zdvd_iff -> dvd_eq_mod_eq_0[symmetric]
6.220 +zmod_zadd_left_eq -> mod_add_left_eq
6.221 +zmod_zadd_right_eq -> mod_add_right_eq
6.222 +zmod_zadd_self1 -> mod_add_self1
6.223 +zmod_zadd_self2 -> mod_add_self2
6.224 +zmod_zadd1_eq -> mod_add_eq
6.225 +zmod_zdiff1_eq -> mod_diff_eq
6.226 +zmod_zdvd_zmod -> mod_mod_cancel
6.227 +zmod_zmod_cancel -> mod_mod_cancel
6.228 +zmod_zmult_self1 -> mod_mult_self2_is_0
6.229 +zmod_zmult_self2 -> mod_mult_self1_is_0
6.230 +zmod_1 -> mod_by_1
6.231 +zdiv_1 -> div_by_1
6.232 +zdvd_abs1 -> abs_dvd_iff
6.233 +zdvd_abs2 -> dvd_abs_iff
6.234 +zdvd_refl -> dvd_refl
6.235 +zdvd_trans -> dvd_trans
6.236 +zdvd_zadd -> dvd_add
6.237 +zdvd_zdiff -> dvd_diff
6.238 +zdvd_zminus_iff -> dvd_minus_iff
6.239 +zdvd_zminus2_iff -> minus_dvd_iff
6.240 +zdvd_zmultD -> dvd_mult_right
6.241 +zdvd_zmultD2 -> dvd_mult_left
6.242 +zdvd_zmult_mono -> mult_dvd_mono
6.243 +zdvd_0_right -> dvd_0_right
6.244 +zdvd_0_left -> dvd_0_left_iff
6.245 +zdvd_1_left -> one_dvd
6.246 +zminus_dvd_iff -> minus_dvd_iff
6.247 +
6.248 * HOL/Library/GCD: Curried operations gcd, lcm (for nat) and zgcd,
6.249 zlcm (for int); carried together from various gcd/lcm developements in
6.250 the HOL Distribution. zgcd and zlcm replace former igcd and ilcm;
6.251 -corresponding theorems renamed accordingly. INCOMPATIBILY. To
6.252 +corresponding theorems renamed accordingly. INCOMPATIBILITY. To
6.253 recover tupled syntax, use syntax declarations like:
6.254
6.255 hide (open) const gcd
6.256 @@ -384,7 +443,7 @@
6.257 * HOL/Real/Rational: 'Fract k 0' now equals '0'. INCOMPATIBILITY.
6.258
6.259 * The real numbers offer decimal input syntax: 12.34 is translated into
6.260 - 1234/10^4. This translation is not reversed upon output.
6.261 + 1234/10^2. This translation is not reversed upon output.
6.262
6.263 * New ML antiquotation @{code}: takes constant as argument, generates
6.264 corresponding code in background and inserts name of the corresponding
6.265 @@ -441,6 +500,9 @@
6.266 Suc_Suc_eq ~> nat.inject
6.267 Suc_not_Zero Zero_not_Suc ~> nat.distinct
6.268
6.269 +* The option datatype has been moved to a new theory HOL/Option.thy.
6.270 +Renamed option_map to Option.map.
6.271 +
6.272 * Library/Nat_Infinity: added addition, numeral syntax and more
6.273 instantiations for algebraic structures. Removed some duplicate
6.274 theorems. Changes in simp rules. INCOMPATIBILITY.
6.275 @@ -452,9 +514,8 @@
6.276 *** HOL-Algebra ***
6.277
6.278 * New locales for orders and lattices where the equivalence relation
6.279 - is not restricted to equality. INCOMPATIBILITY: all order and
6.280 - lattice locales use a record structure with field eq for the
6.281 - equivalence.
6.282 +is not restricted to equality. INCOMPATIBILITY: all order and lattice
6.283 +locales use a record structure with field eq for the equivalence.
6.284
6.285 * New theory of factorial domains.
6.286
6.287 @@ -485,6 +546,23 @@
6.288 * Proof of Zorn's Lemma for partial orders.
6.289
6.290
6.291 +*** HOLCF ***
6.292 +
6.293 +* Reimplemented the simplification procedure for proving continuity
6.294 +subgoals. The new simproc is extensible; users can declare additional
6.295 +continuity introduction rules with the attribute [cont2cont].
6.296 +
6.297 +* The continuity simproc now uses a different introduction rule for
6.298 +solving continuity subgoals on terms with lambda abstractions. In
6.299 +some rare cases the new simproc may fail to solve subgoals that the
6.300 +old one could solve, and "simp add: cont2cont_LAM" may be necessary.
6.301 +Potential INCOMPATIBILITY.
6.302 +
6.303 +* The syntax of the fixrec package has changed. The specification
6.304 +syntax now conforms in style to definition, primrec, function, etc.
6.305 +See HOLCF/ex/Fixrec_ex.thy for examples. INCOMPATIBILITY.
6.306 +
6.307 +
6.308 *** ML ***
6.309
6.310 * High-level support for concurrent ML programming, see
7.1 --- a/README_REPOSITORY Wed Mar 04 11:05:02 2009 +0100
7.2 +++ b/README_REPOSITORY Wed Mar 04 11:05:29 2009 +0100
7.3 @@ -32,9 +32,9 @@
7.4 Initial configuration
7.5 ---------------------
7.6
7.7 -Always use Mercurial version 1.0 or later, such as 1.0.1 or 1.0.2.
7.8 +Always use Mercurial versions from the 1.0 or 1.1 branch, or later.
7.9 The old 0.9.x versions do not work in a multi-user environment with
7.10 -shared file spaces.
7.11 +shared file spaces!
7.12
7.13
7.14 The official Isabelle repository can be cloned like this:
7.15 @@ -62,7 +62,8 @@
7.16
7.17 In principle, user names can be chosen freely, but for longterm
7.18 committers of the Isabelle repository the obvious choice is to keep
7.19 -with the old CVS naming scheme.
7.20 +with the old CVS naming scheme. Others should use their regular "full
7.21 +name"; including an email address is optional.
7.22
7.23
7.24 There are other useful configuration to go into $HOME/.hgrc,
7.25 @@ -135,6 +136,29 @@
7.26 hg clone ssh://wenzelm@atbroy100//home/isabelle-repository/repos/isabelle
7.27
7.28
7.29 +Simplified merges
7.30 +-----------------
7.31 +
7.32 +The main idea of Mercurial is to let individual users produce
7.33 +independent branches of development first, but merge with others
7.34 +frequently. The basic hg merge operation is more general than
7.35 +required for the mode of operation with a shared pull/push area. The
7.36 +hg fetch extension accommodates this case nicely, automating trivial
7.37 +merges and requiring manual intervention for actual conflicts only.
7.38 +
7.39 +The fetch extension can be configured via the user's ~/.hgrc like
7.40 +this:
7.41 +
7.42 + [extensions]
7.43 + hgext.fetch =
7.44 +
7.45 + [defaults]
7.46 + fetch = -m "merged"
7.47 +
7.48 +Note that the potential for merge conflicts can be greatly reduced by
7.49 +doing "hg fetch" before any starting local changes!
7.50 +
7.51 +
7.52 Content discipline
7.53 ------------------
7.54
7.55 @@ -172,7 +196,9 @@
7.56 Mercurial provides nice web presentation of incoming changes with
7.57 a digest of log entries; this also includes RSS/Atom news feeds.
7.58 Users should be aware that others will actually read what is
7.59 - written into log messages.
7.60 + written into log messages. There are also add-on browsers,
7.61 + notably hgtk that is part of the TortoiseHg distribution and works
7.62 + for generic Python/GTk platforms.
7.63
7.64 The usual changelog presentation style for the Isabelle repository
7.65 admits log entries that consist of several lines, but without the
7.66 @@ -194,6 +220,3 @@
7.67
7.68 Needless to say, the results from the build process must not be added
7.69 to the repository!
7.70 -
7.71 -
7.72 -Makarius 30-Nov-2008
8.1 --- a/doc-src/AxClass/Group/Group.thy Wed Mar 04 11:05:02 2009 +0100
8.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
8.3 @@ -1,322 +0,0 @@
8.4 -
8.5 -header {* Basic group theory *}
8.6 -
8.7 -theory Group imports Main begin
8.8 -
8.9 -text {*
8.10 - \medskip\noindent The meta-level type system of Isabelle supports
8.11 - \emph{intersections} and \emph{inclusions} of type classes. These
8.12 - directly correspond to intersections and inclusions of type
8.13 - predicates in a purely set theoretic sense. This is sufficient as a
8.14 - means to describe simple hierarchies of structures. As an
8.15 - illustration, we use the well-known example of semigroups, monoids,
8.16 - general groups and Abelian groups.
8.17 -*}
8.18 -
8.19 -subsection {* Monoids and Groups *}
8.20 -
8.21 -text {*
8.22 - First we declare some polymorphic constants required later for the
8.23 - signature parts of our structures.
8.24 -*}
8.25 -
8.26 -consts
8.27 - times :: "'a \<Rightarrow> 'a \<Rightarrow> 'a" (infixl "\<odot>" 70)
8.28 - invers :: "'a \<Rightarrow> 'a" ("(_\<inv>)" [1000] 999)
8.29 - one :: 'a ("\<one>")
8.30 -
8.31 -text {*
8.32 - \noindent Next we define class @{text monoid} of monoids with
8.33 - operations @{text \<odot>} and @{text \<one>}. Note that multiple class
8.34 - axioms are allowed for user convenience --- they simply represent
8.35 - the conjunction of their respective universal closures.
8.36 -*}
8.37 -
8.38 -axclass monoid \<subseteq> type
8.39 - assoc: "(x \<odot> y) \<odot> z = x \<odot> (y \<odot> z)"
8.40 - left_unit: "\<one> \<odot> x = x"
8.41 - right_unit: "x \<odot> \<one> = x"
8.42 -
8.43 -text {*
8.44 - \noindent So class @{text monoid} contains exactly those types
8.45 - @{text \<tau>} where @{text "\<odot> \<Colon> \<tau> \<Rightarrow> \<tau> \<Rightarrow> \<tau>"} and @{text "\<one> \<Colon> \<tau>"}
8.46 - are specified appropriately, such that @{text \<odot>} is associative and
8.47 - @{text \<one>} is a left and right unit element for the @{text \<odot>}
8.48 - operation.
8.49 -*}
8.50 -
8.51 -text {*
8.52 - \medskip Independently of @{text monoid}, we now define a linear
8.53 - hierarchy of semigroups, general groups and Abelian groups. Note
8.54 - that the names of class axioms are automatically qualified with each
8.55 - class name, so we may re-use common names such as @{text assoc}.
8.56 -*}
8.57 -
8.58 -axclass semigroup \<subseteq> type
8.59 - assoc: "(x \<odot> y) \<odot> z = x \<odot> (y \<odot> z)"
8.60 -
8.61 -axclass group \<subseteq> semigroup
8.62 - left_unit: "\<one> \<odot> x = x"
8.63 - left_inverse: "x\<inv> \<odot> x = \<one>"
8.64 -
8.65 -axclass agroup \<subseteq> group
8.66 - commute: "x \<odot> y = y \<odot> x"
8.67 -
8.68 -text {*
8.69 - \noindent Class @{text group} inherits associativity of @{text \<odot>}
8.70 - from @{text semigroup} and adds two further group axioms. Similarly,
8.71 - @{text agroup} is defined as the subset of @{text group} such that
8.72 - for all of its elements @{text \<tau>}, the operation @{text "\<odot> \<Colon> \<tau> \<Rightarrow> \<tau> \<Rightarrow>
8.73 - \<tau>"} is even commutative.
8.74 -*}
8.75 -
8.76 -
8.77 -subsection {* Abstract reasoning *}
8.78 -
8.79 -text {*
8.80 - In a sense, axiomatic type classes may be viewed as \emph{abstract
8.81 - theories}. Above class definitions gives rise to abstract axioms
8.82 - @{text assoc}, @{text left_unit}, @{text left_inverse}, @{text
8.83 - commute}, where any of these contain a type variable @{text "'a \<Colon>
8.84 - c"} that is restricted to types of the corresponding class @{text
8.85 - c}. \emph{Sort constraints} like this express a logical
8.86 - precondition for the whole formula. For example, @{text assoc}
8.87 - states that for all @{text \<tau>}, provided that @{text "\<tau> \<Colon>
8.88 - semigroup"}, the operation @{text "\<odot> \<Colon> \<tau> \<Rightarrow> \<tau> \<Rightarrow> \<tau>"} is associative.
8.89 -
8.90 - \medskip From a technical point of view, abstract axioms are just
8.91 - ordinary Isabelle theorems, which may be used in proofs without
8.92 - special treatment. Such ``abstract proofs'' usually yield new
8.93 - ``abstract theorems''. For example, we may now derive the following
8.94 - well-known laws of general groups.
8.95 -*}
8.96 -
8.97 -theorem group_right_inverse: "x \<odot> x\<inv> = (\<one>\<Colon>'a\<Colon>group)"
8.98 -proof -
8.99 - have "x \<odot> x\<inv> = \<one> \<odot> (x \<odot> x\<inv>)"
8.100 - by (simp only: group_class.left_unit)
8.101 - also have "... = \<one> \<odot> x \<odot> x\<inv>"
8.102 - by (simp only: semigroup_class.assoc)
8.103 - also have "... = (x\<inv>)\<inv> \<odot> x\<inv> \<odot> x \<odot> x\<inv>"
8.104 - by (simp only: group_class.left_inverse)
8.105 - also have "... = (x\<inv>)\<inv> \<odot> (x\<inv> \<odot> x) \<odot> x\<inv>"
8.106 - by (simp only: semigroup_class.assoc)
8.107 - also have "... = (x\<inv>)\<inv> \<odot> \<one> \<odot> x\<inv>"
8.108 - by (simp only: group_class.left_inverse)
8.109 - also have "... = (x\<inv>)\<inv> \<odot> (\<one> \<odot> x\<inv>)"
8.110 - by (simp only: semigroup_class.assoc)
8.111 - also have "... = (x\<inv>)\<inv> \<odot> x\<inv>"
8.112 - by (simp only: group_class.left_unit)
8.113 - also have "... = \<one>"
8.114 - by (simp only: group_class.left_inverse)
8.115 - finally show ?thesis .
8.116 -qed
8.117 -
8.118 -text {*
8.119 - \noindent With @{text group_right_inverse} already available, @{text
8.120 - group_right_unit}\label{thm:group-right-unit} is now established
8.121 - much easier.
8.122 -*}
8.123 -
8.124 -theorem group_right_unit: "x \<odot> \<one> = (x\<Colon>'a\<Colon>group)"
8.125 -proof -
8.126 - have "x \<odot> \<one> = x \<odot> (x\<inv> \<odot> x)"
8.127 - by (simp only: group_class.left_inverse)
8.128 - also have "... = x \<odot> x\<inv> \<odot> x"
8.129 - by (simp only: semigroup_class.assoc)
8.130 - also have "... = \<one> \<odot> x"
8.131 - by (simp only: group_right_inverse)
8.132 - also have "... = x"
8.133 - by (simp only: group_class.left_unit)
8.134 - finally show ?thesis .
8.135 -qed
8.136 -
8.137 -text {*
8.138 - \medskip Abstract theorems may be instantiated to only those types
8.139 - @{text \<tau>} where the appropriate class membership @{text "\<tau> \<Colon> c"} is
8.140 - known at Isabelle's type signature level. Since we have @{text
8.141 - "agroup \<subseteq> group \<subseteq> semigroup"} by definition, all theorems of @{text
8.142 - semigroup} and @{text group} are automatically inherited by @{text
8.143 - group} and @{text agroup}.
8.144 -*}
8.145 -
8.146 -
8.147 -subsection {* Abstract instantiation *}
8.148 -
8.149 -text {*
8.150 - From the definition, the @{text monoid} and @{text group} classes
8.151 - have been independent. Note that for monoids, @{text right_unit}
8.152 - had to be included as an axiom, but for groups both @{text
8.153 - right_unit} and @{text right_inverse} are derivable from the other
8.154 - axioms. With @{text group_right_unit} derived as a theorem of group
8.155 - theory (see page~\pageref{thm:group-right-unit}), we may now
8.156 - instantiate @{text "monoid \<subseteq> semigroup"} and @{text "group \<subseteq>
8.157 - monoid"} properly as follows (cf.\ \figref{fig:monoid-group}).
8.158 -
8.159 - \begin{figure}[htbp]
8.160 - \begin{center}
8.161 - \small
8.162 - \unitlength 0.6mm
8.163 - \begin{picture}(65,90)(0,-10)
8.164 - \put(15,10){\line(0,1){10}} \put(15,30){\line(0,1){10}}
8.165 - \put(15,50){\line(1,1){10}} \put(35,60){\line(1,-1){10}}
8.166 - \put(15,5){\makebox(0,0){@{text agroup}}}
8.167 - \put(15,25){\makebox(0,0){@{text group}}}
8.168 - \put(15,45){\makebox(0,0){@{text semigroup}}}
8.169 - \put(30,65){\makebox(0,0){@{text type}}} \put(50,45){\makebox(0,0){@{text monoid}}}
8.170 - \end{picture}
8.171 - \hspace{4em}
8.172 - \begin{picture}(30,90)(0,0)
8.173 - \put(15,10){\line(0,1){10}} \put(15,30){\line(0,1){10}}
8.174 - \put(15,50){\line(0,1){10}} \put(15,70){\line(0,1){10}}
8.175 - \put(15,5){\makebox(0,0){@{text agroup}}}
8.176 - \put(15,25){\makebox(0,0){@{text group}}}
8.177 - \put(15,45){\makebox(0,0){@{text monoid}}}
8.178 - \put(15,65){\makebox(0,0){@{text semigroup}}}
8.179 - \put(15,85){\makebox(0,0){@{text type}}}
8.180 - \end{picture}
8.181 - \caption{Monoids and groups: according to definition, and by proof}
8.182 - \label{fig:monoid-group}
8.183 - \end{center}
8.184 - \end{figure}
8.185 -*}
8.186 -
8.187 -instance monoid \<subseteq> semigroup
8.188 -proof
8.189 - fix x y z :: "'a\<Colon>monoid"
8.190 - show "x \<odot> y \<odot> z = x \<odot> (y \<odot> z)"
8.191 - by (rule monoid_class.assoc)
8.192 -qed
8.193 -
8.194 -instance group \<subseteq> monoid
8.195 -proof
8.196 - fix x y z :: "'a\<Colon>group"
8.197 - show "x \<odot> y \<odot> z = x \<odot> (y \<odot> z)"
8.198 - by (rule semigroup_class.assoc)
8.199 - show "\<one> \<odot> x = x"
8.200 - by (rule group_class.left_unit)
8.201 - show "x \<odot> \<one> = x"
8.202 - by (rule group_right_unit)
8.203 -qed
8.204 -
8.205 -text {*
8.206 - \medskip The \isakeyword{instance} command sets up an appropriate
8.207 - goal that represents the class inclusion (or type arity, see
8.208 - \secref{sec:inst-arity}) to be proven (see also
8.209 - \cite{isabelle-isar-ref}). The initial proof step causes
8.210 - back-chaining of class membership statements wrt.\ the hierarchy of
8.211 - any classes defined in the current theory; the effect is to reduce
8.212 - to the initial statement to a number of goals that directly
8.213 - correspond to any class axioms encountered on the path upwards
8.214 - through the class hierarchy.
8.215 -*}
8.216 -
8.217 -
8.218 -subsection {* Concrete instantiation \label{sec:inst-arity} *}
8.219 -
8.220 -text {*
8.221 - So far we have covered the case of the form
8.222 - \isakeyword{instance}~@{text "c\<^sub>1 \<subseteq> c\<^sub>2"}, namely
8.223 - \emph{abstract instantiation} --- $c@1$ is more special than @{text
8.224 - "c\<^sub>1"} and thus an instance of @{text "c\<^sub>2"}. Even more
8.225 - interesting for practical applications are \emph{concrete
8.226 - instantiations} of axiomatic type classes. That is, certain simple
8.227 - schemes @{text "(\<alpha>\<^sub>1, \<dots>, \<alpha>\<^sub>n) t \<Colon> c"} of class
8.228 - membership may be established at the logical level and then
8.229 - transferred to Isabelle's type signature level.
8.230 -
8.231 - \medskip As a typical example, we show that type @{typ bool} with
8.232 - exclusive-or as @{text \<odot>} operation, identity as @{text \<inv>}, and
8.233 - @{term False} as @{text \<one>} forms an Abelian group.
8.234 -*}
8.235 -
8.236 -defs (overloaded)
8.237 - times_bool_def: "x \<odot> y \<equiv> x \<noteq> (y\<Colon>bool)"
8.238 - inverse_bool_def: "x\<inv> \<equiv> x\<Colon>bool"
8.239 - unit_bool_def: "\<one> \<equiv> False"
8.240 -
8.241 -text {*
8.242 - \medskip It is important to note that above \isakeyword{defs} are
8.243 - just overloaded meta-level constant definitions, where type classes
8.244 - are not yet involved at all. This form of constant definition with
8.245 - overloading (and optional recursion over the syntactic structure of
8.246 - simple types) are admissible as definitional extensions of plain HOL
8.247 - \cite{Wenzel:1997:TPHOL}. The Haskell-style type system is not
8.248 - required for overloading. Nevertheless, overloaded definitions are
8.249 - best applied in the context of type classes.
8.250 -
8.251 - \medskip Since we have chosen above \isakeyword{defs} of the generic
8.252 - group operations on type @{typ bool} appropriately, the class
8.253 - membership @{text "bool \<Colon> agroup"} may be now derived as follows.
8.254 -*}
8.255 -
8.256 -instance bool :: agroup
8.257 -proof (intro_classes,
8.258 - unfold times_bool_def inverse_bool_def unit_bool_def)
8.259 - fix x y z
8.260 - show "((x \<noteq> y) \<noteq> z) = (x \<noteq> (y \<noteq> z))" by blast
8.261 - show "(False \<noteq> x) = x" by blast
8.262 - show "(x \<noteq> x) = False" by blast
8.263 - show "(x \<noteq> y) = (y \<noteq> x)" by blast
8.264 -qed
8.265 -
8.266 -text {*
8.267 - The result of an \isakeyword{instance} statement is both expressed
8.268 - as a theorem of Isabelle's meta-logic, and as a type arity of the
8.269 - type signature. The latter enables type-inference system to take
8.270 - care of this new instance automatically.
8.271 -
8.272 - \medskip We could now also instantiate our group theory classes to
8.273 - many other concrete types. For example, @{text "int \<Colon> agroup"}
8.274 - (e.g.\ by defining @{text \<odot>} as addition, @{text \<inv>} as negation
8.275 - and @{text \<one>} as zero) or @{text "list \<Colon> (type) semigroup"}
8.276 - (e.g.\ if @{text \<odot>} is defined as list append). Thus, the
8.277 - characteristic constants @{text \<odot>}, @{text \<inv>}, @{text \<one>}
8.278 - really become overloaded, i.e.\ have different meanings on different
8.279 - types.
8.280 -*}
8.281 -
8.282 -
8.283 -subsection {* Lifting and Functors *}
8.284 -
8.285 -text {*
8.286 - As already mentioned above, overloading in the simply-typed HOL
8.287 - systems may include recursion over the syntactic structure of types.
8.288 - That is, definitional equations @{text "c\<^sup>\<tau> \<equiv> t"} may also
8.289 - contain constants of name @{text c} on the right-hand side --- if
8.290 - these have types that are structurally simpler than @{text \<tau>}.
8.291 -
8.292 - This feature enables us to \emph{lift operations}, say to Cartesian
8.293 - products, direct sums or function spaces. Subsequently we lift
8.294 - @{text \<odot>} component-wise to binary products @{typ "'a \<times> 'b"}.
8.295 -*}
8.296 -
8.297 -defs (overloaded)
8.298 - times_prod_def: "p \<odot> q \<equiv> (fst p \<odot> fst q, snd p \<odot> snd q)"
8.299 -
8.300 -text {*
8.301 - It is very easy to see that associativity of @{text \<odot>} on @{typ 'a}
8.302 - and @{text \<odot>} on @{typ 'b} transfers to @{text \<odot>} on @{typ "'a \<times>
8.303 - 'b"}. Hence the binary type constructor @{text \<odot>} maps semigroups
8.304 - to semigroups. This may be established formally as follows.
8.305 -*}
8.306 -
8.307 -instance * :: (semigroup, semigroup) semigroup
8.308 -proof (intro_classes, unfold times_prod_def)
8.309 - fix p q r :: "'a\<Colon>semigroup \<times> 'b\<Colon>semigroup"
8.310 - show
8.311 - "(fst (fst p \<odot> fst q, snd p \<odot> snd q) \<odot> fst r,
8.312 - snd (fst p \<odot> fst q, snd p \<odot> snd q) \<odot> snd r) =
8.313 - (fst p \<odot> fst (fst q \<odot> fst r, snd q \<odot> snd r),
8.314 - snd p \<odot> snd (fst q \<odot> fst r, snd q \<odot> snd r))"
8.315 - by (simp add: semigroup_class.assoc)
8.316 -qed
8.317 -
8.318 -text {*
8.319 - Thus, if we view class instances as ``structures'', then overloaded
8.320 - constant definitions with recursion over types indirectly provide
8.321 - some kind of ``functors'' --- i.e.\ mappings between abstract
8.322 - theories.
8.323 -*}
8.324 -
8.325 -end
9.1 --- a/doc-src/AxClass/Group/Product.thy Wed Mar 04 11:05:02 2009 +0100
9.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
9.3 @@ -1,85 +0,0 @@
9.4 -
9.5 -header {* Syntactic classes *}
9.6 -
9.7 -theory Product imports Main begin
9.8 -
9.9 -text {*
9.10 - \medskip\noindent There is still a feature of Isabelle's type system
9.11 - left that we have not yet discussed. When declaring polymorphic
9.12 - constants @{text "c \<Colon> \<sigma>"}, the type variables occurring in @{text \<sigma>}
9.13 - may be constrained by type classes (or even general sorts) in an
9.14 - arbitrary way. Note that by default, in Isabelle/HOL the
9.15 - declaration @{text "\<odot> \<Colon> 'a \<Rightarrow> 'a \<Rightarrow> 'a"} is actually an abbreviation
9.16 - for @{text "\<odot> \<Colon> 'a\<Colon>type \<Rightarrow> 'a \<Rightarrow> 'a"} Since class @{text type} is the
9.17 - universal class of HOL, this is not really a constraint at all.
9.18 -
9.19 - The @{text product} class below provides a less degenerate example of
9.20 - syntactic type classes.
9.21 -*}
9.22 -
9.23 -axclass
9.24 - product \<subseteq> type
9.25 -consts
9.26 - product :: "'a\<Colon>product \<Rightarrow> 'a \<Rightarrow> 'a" (infixl "\<odot>" 70)
9.27 -
9.28 -text {*
9.29 - Here class @{text product} is defined as subclass of @{text type}
9.30 - without any additional axioms. This effects in logical equivalence
9.31 - of @{text product} and @{text type}, as is reflected by the trivial
9.32 - introduction rule generated for this definition.
9.33 -
9.34 - \medskip So what is the difference of declaring @{text "\<odot> \<Colon>
9.35 - 'a\<Colon>product \<Rightarrow> 'a \<Rightarrow> 'a"} vs.\ declaring @{text "\<odot> \<Colon> 'a\<Colon>type \<Rightarrow> 'a \<Rightarrow>
9.36 - 'a"} anyway? In this particular case where @{text "product \<equiv>
9.37 - type"}, it should be obvious that both declarations are the same
9.38 - from the logic's point of view. It even makes the most sense to
9.39 - remove sort constraints from constant declarations, as far as the
9.40 - purely logical meaning is concerned \cite{Wenzel:1997:TPHOL}.
9.41 -
9.42 - On the other hand there are syntactic differences, of course.
9.43 - Constants @{text \<odot>} on some type @{text \<tau>} are rejected by the
9.44 - type-checker, unless the arity @{text "\<tau> \<Colon> product"} is part of the
9.45 - type signature. In our example, this arity may be always added when
9.46 - required by means of an \isakeyword{instance} with the default proof
9.47 - (double-dot).
9.48 -
9.49 - \medskip Thus, we may observe the following discipline of using
9.50 - syntactic classes. Overloaded polymorphic constants have their type
9.51 - arguments restricted to an associated (logically trivial) class
9.52 - @{text c}. Only immediately before \emph{specifying} these
9.53 - constants on a certain type @{text \<tau>} do we instantiate @{text "\<tau> \<Colon>
9.54 - c"}.
9.55 -
9.56 - This is done for class @{text product} and type @{typ bool} as
9.57 - follows.
9.58 -*}
9.59 -
9.60 -instance bool :: product ..
9.61 -defs (overloaded)
9.62 - product_bool_def: "x \<odot> y \<equiv> x \<and> y"
9.63 -
9.64 -text {*
9.65 - The definition @{text prod_bool_def} becomes syntactically
9.66 - well-formed only after the arity @{text "bool \<Colon> product"} is made
9.67 - known to the type checker.
9.68 -
9.69 - \medskip It is very important to see that above \isakeyword{defs} are
9.70 - not directly connected with \isakeyword{instance} at all! We were
9.71 - just following our convention to specify @{text \<odot>} on @{typ bool}
9.72 - after having instantiated @{text "bool \<Colon> product"}. Isabelle does
9.73 - not require these definitions, which is in contrast to programming
9.74 - languages like Haskell \cite{haskell-report}.
9.75 -
9.76 - \medskip While Isabelle type classes and those of Haskell are almost
9.77 - the same as far as type-checking and type inference are concerned,
9.78 - there are important semantic differences. Haskell classes require
9.79 - their instances to \emph{provide operations} of certain \emph{names}.
9.80 - Therefore, its \texttt{instance} has a \texttt{where} part that tells
9.81 - the system what these ``member functions'' should be.
9.82 -
9.83 - This style of \texttt{instance} would not make much sense in
9.84 - Isabelle's meta-logic, because there is no internal notion of
9.85 - ``providing operations'' or even ``names of functions''.
9.86 -*}
9.87 -
9.88 -end
10.1 --- a/doc-src/AxClass/Group/ROOT.ML Wed Mar 04 11:05:02 2009 +0100
10.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
10.3 @@ -1,4 +0,0 @@
10.4 -
10.5 -use_thy "Semigroups";
10.6 -use_thy "Group";
10.7 -use_thy "Product";
11.1 --- a/doc-src/AxClass/Group/Semigroups.thy Wed Mar 04 11:05:02 2009 +0100
11.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
11.3 @@ -1,54 +0,0 @@
11.4 -
11.5 -header {* Semigroups *}
11.6 -
11.7 -theory Semigroups imports Main begin
11.8 -
11.9 -text {*
11.10 - \medskip\noindent An axiomatic type class is simply a class of types
11.11 - that all meet certain properties, which are also called \emph{class
11.12 - axioms}. Thus, type classes may be also understood as type
11.13 - predicates --- i.e.\ abstractions over a single type argument @{typ
11.14 - 'a}. Class axioms typically contain polymorphic constants that
11.15 - depend on this type @{typ 'a}. These \emph{characteristic
11.16 - constants} behave like operations associated with the ``carrier''
11.17 - type @{typ 'a}.
11.18 -
11.19 - We illustrate these basic concepts by the following formulation of
11.20 - semigroups.
11.21 -*}
11.22 -
11.23 -consts
11.24 - times :: "'a \<Rightarrow> 'a \<Rightarrow> 'a" (infixl "\<odot>" 70)
11.25 -axclass semigroup \<subseteq> type
11.26 - assoc: "(x \<odot> y) \<odot> z = x \<odot> (y \<odot> z)"
11.27 -
11.28 -text {*
11.29 - \noindent Above we have first declared a polymorphic constant @{text
11.30 - "\<odot> \<Colon> 'a \<Rightarrow> 'a \<Rightarrow> 'a"} and then defined the class @{text semigroup} of
11.31 - all types @{text \<tau>} such that @{text "\<odot> \<Colon> \<tau> \<Rightarrow> \<tau> \<Rightarrow> \<tau>"} is indeed an
11.32 - associative operator. The @{text assoc} axiom contains exactly one
11.33 - type variable, which is invisible in the above presentation, though.
11.34 - Also note that free term variables (like @{term x}, @{term y},
11.35 - @{term z}) are allowed for user convenience --- conceptually all of
11.36 - these are bound by outermost universal quantifiers.
11.37 -
11.38 - \medskip In general, type classes may be used to describe
11.39 - \emph{structures} with exactly one carrier @{typ 'a} and a fixed
11.40 - \emph{signature}. Different signatures require different classes.
11.41 - Below, class @{text plus_semigroup} represents semigroups @{text
11.42 - "(\<tau>, \<oplus>\<^sup>\<tau>)"}, while the original @{text semigroup} would
11.43 - correspond to semigroups of the form @{text "(\<tau>, \<odot>\<^sup>\<tau>)"}.
11.44 -*}
11.45 -
11.46 -consts
11.47 - plus :: "'a \<Rightarrow> 'a \<Rightarrow> 'a" (infixl "\<oplus>" 70)
11.48 -axclass plus_semigroup \<subseteq> type
11.49 - assoc: "(x \<oplus> y) \<oplus> z = x \<oplus> (y \<oplus> z)"
11.50 -
11.51 -text {*
11.52 - \noindent Even if classes @{text plus_semigroup} and @{text
11.53 - semigroup} both represent semigroups in a sense, they are certainly
11.54 - not quite the same.
11.55 -*}
11.56 -
11.57 -end
12.1 --- a/doc-src/AxClass/Group/document/Group.tex Wed Mar 04 11:05:02 2009 +0100
12.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
12.3 @@ -1,512 +0,0 @@
12.4 -%
12.5 -\begin{isabellebody}%
12.6 -\def\isabellecontext{Group}%
12.7 -%
12.8 -\isamarkupheader{Basic group theory%
12.9 -}
12.10 -\isamarkuptrue%
12.11 -%
12.12 -\isadelimtheory
12.13 -%
12.14 -\endisadelimtheory
12.15 -%
12.16 -\isatagtheory
12.17 -\isacommand{theory}\isamarkupfalse%
12.18 -\ Group\ \isakeyword{imports}\ Main\ \isakeyword{begin}%
12.19 -\endisatagtheory
12.20 -{\isafoldtheory}%
12.21 -%
12.22 -\isadelimtheory
12.23 -%
12.24 -\endisadelimtheory
12.25 -%
12.26 -\begin{isamarkuptext}%
12.27 -\medskip\noindent The meta-level type system of Isabelle supports
12.28 - \emph{intersections} and \emph{inclusions} of type classes. These
12.29 - directly correspond to intersections and inclusions of type
12.30 - predicates in a purely set theoretic sense. This is sufficient as a
12.31 - means to describe simple hierarchies of structures. As an
12.32 - illustration, we use the well-known example of semigroups, monoids,
12.33 - general groups and Abelian groups.%
12.34 -\end{isamarkuptext}%
12.35 -\isamarkuptrue%
12.36 -%
12.37 -\isamarkupsubsection{Monoids and Groups%
12.38 -}
12.39 -\isamarkuptrue%
12.40 -%
12.41 -\begin{isamarkuptext}%
12.42 -First we declare some polymorphic constants required later for the
12.43 - signature parts of our structures.%
12.44 -\end{isamarkuptext}%
12.45 -\isamarkuptrue%
12.46 -\isacommand{consts}\isamarkupfalse%
12.47 -\isanewline
12.48 -\ \ times\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharprime}a\ {\isasymRightarrow}\ {\isacharprime}a\ {\isasymRightarrow}\ {\isacharprime}a{\isachardoublequoteclose}\ \ \ \ {\isacharparenleft}\isakeyword{infixl}\ {\isachardoublequoteopen}{\isasymodot}{\isachardoublequoteclose}\ {\isadigit{7}}{\isadigit{0}}{\isacharparenright}\isanewline
12.49 -\ \ invers\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharprime}a\ {\isasymRightarrow}\ {\isacharprime}a{\isachardoublequoteclose}\ \ \ \ {\isacharparenleft}{\isachardoublequoteopen}{\isacharparenleft}{\isacharunderscore}{\isasyminv}{\isacharparenright}{\isachardoublequoteclose}\ {\isacharbrackleft}{\isadigit{1}}{\isadigit{0}}{\isadigit{0}}{\isadigit{0}}{\isacharbrackright}\ {\isadigit{9}}{\isadigit{9}}{\isadigit{9}}{\isacharparenright}\isanewline
12.50 -\ \ one\ {\isacharcolon}{\isacharcolon}\ {\isacharprime}a\ \ \ \ {\isacharparenleft}{\isachardoublequoteopen}{\isasymone}{\isachardoublequoteclose}{\isacharparenright}%
12.51 -\begin{isamarkuptext}%
12.52 -\noindent Next we define class \isa{monoid} of monoids with
12.53 - operations \isa{{\isasymodot}} and \isa{{\isasymone}}. Note that multiple class
12.54 - axioms are allowed for user convenience --- they simply represent
12.55 - the conjunction of their respective universal closures.%
12.56 -\end{isamarkuptext}%
12.57 -\isamarkuptrue%
12.58 -\isacommand{axclass}\isamarkupfalse%
12.59 -\ monoid\ {\isasymsubseteq}\ type\isanewline
12.60 -\ \ assoc{\isacharcolon}\ {\isachardoublequoteopen}{\isacharparenleft}x\ {\isasymodot}\ y{\isacharparenright}\ {\isasymodot}\ z\ {\isacharequal}\ x\ {\isasymodot}\ {\isacharparenleft}y\ {\isasymodot}\ z{\isacharparenright}{\isachardoublequoteclose}\isanewline
12.61 -\ \ left{\isacharunderscore}unit{\isacharcolon}\ {\isachardoublequoteopen}{\isasymone}\ {\isasymodot}\ x\ {\isacharequal}\ x{\isachardoublequoteclose}\isanewline
12.62 -\ \ right{\isacharunderscore}unit{\isacharcolon}\ {\isachardoublequoteopen}x\ {\isasymodot}\ {\isasymone}\ {\isacharequal}\ x{\isachardoublequoteclose}%
12.63 -\begin{isamarkuptext}%
12.64 -\noindent So class \isa{monoid} contains exactly those types
12.65 - \isa{{\isasymtau}} where \isa{{\isasymodot}\ {\isasymColon}\ {\isasymtau}\ {\isasymRightarrow}\ {\isasymtau}\ {\isasymRightarrow}\ {\isasymtau}} and \isa{{\isasymone}\ {\isasymColon}\ {\isasymtau}}
12.66 - are specified appropriately, such that \isa{{\isasymodot}} is associative and
12.67 - \isa{{\isasymone}} is a left and right unit element for the \isa{{\isasymodot}}
12.68 - operation.%
12.69 -\end{isamarkuptext}%
12.70 -\isamarkuptrue%
12.71 -%
12.72 -\begin{isamarkuptext}%
12.73 -\medskip Independently of \isa{monoid}, we now define a linear
12.74 - hierarchy of semigroups, general groups and Abelian groups. Note
12.75 - that the names of class axioms are automatically qualified with each
12.76 - class name, so we may re-use common names such as \isa{assoc}.%
12.77 -\end{isamarkuptext}%
12.78 -\isamarkuptrue%
12.79 -\isacommand{axclass}\isamarkupfalse%
12.80 -\ semigroup\ {\isasymsubseteq}\ type\isanewline
12.81 -\ \ assoc{\isacharcolon}\ {\isachardoublequoteopen}{\isacharparenleft}x\ {\isasymodot}\ y{\isacharparenright}\ {\isasymodot}\ z\ {\isacharequal}\ x\ {\isasymodot}\ {\isacharparenleft}y\ {\isasymodot}\ z{\isacharparenright}{\isachardoublequoteclose}\isanewline
12.82 -\isanewline
12.83 -\isacommand{axclass}\isamarkupfalse%
12.84 -\ group\ {\isasymsubseteq}\ semigroup\isanewline
12.85 -\ \ left{\isacharunderscore}unit{\isacharcolon}\ {\isachardoublequoteopen}{\isasymone}\ {\isasymodot}\ x\ {\isacharequal}\ x{\isachardoublequoteclose}\isanewline
12.86 -\ \ left{\isacharunderscore}inverse{\isacharcolon}\ {\isachardoublequoteopen}x{\isasyminv}\ {\isasymodot}\ x\ {\isacharequal}\ {\isasymone}{\isachardoublequoteclose}\isanewline
12.87 -\isanewline
12.88 -\isacommand{axclass}\isamarkupfalse%
12.89 -\ agroup\ {\isasymsubseteq}\ group\isanewline
12.90 -\ \ commute{\isacharcolon}\ {\isachardoublequoteopen}x\ {\isasymodot}\ y\ {\isacharequal}\ y\ {\isasymodot}\ x{\isachardoublequoteclose}%
12.91 -\begin{isamarkuptext}%
12.92 -\noindent Class \isa{group} inherits associativity of \isa{{\isasymodot}}
12.93 - from \isa{semigroup} and adds two further group axioms. Similarly,
12.94 - \isa{agroup} is defined as the subset of \isa{group} such that
12.95 - for all of its elements \isa{{\isasymtau}}, the operation \isa{{\isasymodot}\ {\isasymColon}\ {\isasymtau}\ {\isasymRightarrow}\ {\isasymtau}\ {\isasymRightarrow}\ {\isasymtau}} is even commutative.%
12.96 -\end{isamarkuptext}%
12.97 -\isamarkuptrue%
12.98 -%
12.99 -\isamarkupsubsection{Abstract reasoning%
12.100 -}
12.101 -\isamarkuptrue%
12.102 -%
12.103 -\begin{isamarkuptext}%
12.104 -In a sense, axiomatic type classes may be viewed as \emph{abstract
12.105 - theories}. Above class definitions gives rise to abstract axioms
12.106 - \isa{assoc}, \isa{left{\isacharunderscore}unit}, \isa{left{\isacharunderscore}inverse}, \isa{commute}, where any of these contain a type variable \isa{{\isacharprime}a\ {\isasymColon}\ c} that is restricted to types of the corresponding class \isa{c}. \emph{Sort constraints} like this express a logical
12.107 - precondition for the whole formula. For example, \isa{assoc}
12.108 - states that for all \isa{{\isasymtau}}, provided that \isa{{\isasymtau}\ {\isasymColon}\ semigroup}, the operation \isa{{\isasymodot}\ {\isasymColon}\ {\isasymtau}\ {\isasymRightarrow}\ {\isasymtau}\ {\isasymRightarrow}\ {\isasymtau}} is associative.
12.109 -
12.110 - \medskip From a technical point of view, abstract axioms are just
12.111 - ordinary Isabelle theorems, which may be used in proofs without
12.112 - special treatment. Such ``abstract proofs'' usually yield new
12.113 - ``abstract theorems''. For example, we may now derive the following
12.114 - well-known laws of general groups.%
12.115 -\end{isamarkuptext}%
12.116 -\isamarkuptrue%
12.117 -\isacommand{theorem}\isamarkupfalse%
12.118 -\ group{\isacharunderscore}right{\isacharunderscore}inverse{\isacharcolon}\ {\isachardoublequoteopen}x\ {\isasymodot}\ x{\isasyminv}\ {\isacharequal}\ {\isacharparenleft}{\isasymone}{\isasymColon}{\isacharprime}a{\isasymColon}group{\isacharparenright}{\isachardoublequoteclose}\isanewline
12.119 -%
12.120 -\isadelimproof
12.121 -%
12.122 -\endisadelimproof
12.123 -%
12.124 -\isatagproof
12.125 -\isacommand{proof}\isamarkupfalse%
12.126 -\ {\isacharminus}\isanewline
12.127 -\ \ \isacommand{have}\isamarkupfalse%
12.128 -\ {\isachardoublequoteopen}x\ {\isasymodot}\ x{\isasyminv}\ {\isacharequal}\ {\isasymone}\ {\isasymodot}\ {\isacharparenleft}x\ {\isasymodot}\ x{\isasyminv}{\isacharparenright}{\isachardoublequoteclose}\isanewline
12.129 -\ \ \ \ \isacommand{by}\isamarkupfalse%
12.130 -\ {\isacharparenleft}simp\ only{\isacharcolon}\ group{\isacharunderscore}class{\isachardot}left{\isacharunderscore}unit{\isacharparenright}\isanewline
12.131 -\ \ \isacommand{also}\isamarkupfalse%
12.132 -\ \isacommand{have}\isamarkupfalse%
12.133 -\ {\isachardoublequoteopen}{\isachardot}{\isachardot}{\isachardot}\ {\isacharequal}\ {\isasymone}\ {\isasymodot}\ x\ {\isasymodot}\ x{\isasyminv}{\isachardoublequoteclose}\isanewline
12.134 -\ \ \ \ \isacommand{by}\isamarkupfalse%
12.135 -\ {\isacharparenleft}simp\ only{\isacharcolon}\ semigroup{\isacharunderscore}class{\isachardot}assoc{\isacharparenright}\isanewline
12.136 -\ \ \isacommand{also}\isamarkupfalse%
12.137 -\ \isacommand{have}\isamarkupfalse%
12.138 -\ {\isachardoublequoteopen}{\isachardot}{\isachardot}{\isachardot}\ {\isacharequal}\ {\isacharparenleft}x{\isasyminv}{\isacharparenright}{\isasyminv}\ {\isasymodot}\ x{\isasyminv}\ {\isasymodot}\ x\ {\isasymodot}\ x{\isasyminv}{\isachardoublequoteclose}\isanewline
12.139 -\ \ \ \ \isacommand{by}\isamarkupfalse%
12.140 -\ {\isacharparenleft}simp\ only{\isacharcolon}\ group{\isacharunderscore}class{\isachardot}left{\isacharunderscore}inverse{\isacharparenright}\isanewline
12.141 -\ \ \isacommand{also}\isamarkupfalse%
12.142 -\ \isacommand{have}\isamarkupfalse%
12.143 -\ {\isachardoublequoteopen}{\isachardot}{\isachardot}{\isachardot}\ {\isacharequal}\ {\isacharparenleft}x{\isasyminv}{\isacharparenright}{\isasyminv}\ {\isasymodot}\ {\isacharparenleft}x{\isasyminv}\ {\isasymodot}\ x{\isacharparenright}\ {\isasymodot}\ x{\isasyminv}{\isachardoublequoteclose}\isanewline
12.144 -\ \ \ \ \isacommand{by}\isamarkupfalse%
12.145 -\ {\isacharparenleft}simp\ only{\isacharcolon}\ semigroup{\isacharunderscore}class{\isachardot}assoc{\isacharparenright}\isanewline
12.146 -\ \ \isacommand{also}\isamarkupfalse%
12.147 -\ \isacommand{have}\isamarkupfalse%
12.148 -\ {\isachardoublequoteopen}{\isachardot}{\isachardot}{\isachardot}\ {\isacharequal}\ {\isacharparenleft}x{\isasyminv}{\isacharparenright}{\isasyminv}\ {\isasymodot}\ {\isasymone}\ {\isasymodot}\ x{\isasyminv}{\isachardoublequoteclose}\isanewline
12.149 -\ \ \ \ \isacommand{by}\isamarkupfalse%
12.150 -\ {\isacharparenleft}simp\ only{\isacharcolon}\ group{\isacharunderscore}class{\isachardot}left{\isacharunderscore}inverse{\isacharparenright}\isanewline
12.151 -\ \ \isacommand{also}\isamarkupfalse%
12.152 -\ \isacommand{have}\isamarkupfalse%
12.153 -\ {\isachardoublequoteopen}{\isachardot}{\isachardot}{\isachardot}\ {\isacharequal}\ {\isacharparenleft}x{\isasyminv}{\isacharparenright}{\isasyminv}\ {\isasymodot}\ {\isacharparenleft}{\isasymone}\ {\isasymodot}\ x{\isasyminv}{\isacharparenright}{\isachardoublequoteclose}\isanewline
12.154 -\ \ \ \ \isacommand{by}\isamarkupfalse%
12.155 -\ {\isacharparenleft}simp\ only{\isacharcolon}\ semigroup{\isacharunderscore}class{\isachardot}assoc{\isacharparenright}\isanewline
12.156 -\ \ \isacommand{also}\isamarkupfalse%
12.157 -\ \isacommand{have}\isamarkupfalse%
12.158 -\ {\isachardoublequoteopen}{\isachardot}{\isachardot}{\isachardot}\ {\isacharequal}\ {\isacharparenleft}x{\isasyminv}{\isacharparenright}{\isasyminv}\ {\isasymodot}\ x{\isasyminv}{\isachardoublequoteclose}\isanewline
12.159 -\ \ \ \ \isacommand{by}\isamarkupfalse%
12.160 -\ {\isacharparenleft}simp\ only{\isacharcolon}\ group{\isacharunderscore}class{\isachardot}left{\isacharunderscore}unit{\isacharparenright}\isanewline
12.161 -\ \ \isacommand{also}\isamarkupfalse%
12.162 -\ \isacommand{have}\isamarkupfalse%
12.163 -\ {\isachardoublequoteopen}{\isachardot}{\isachardot}{\isachardot}\ {\isacharequal}\ {\isasymone}{\isachardoublequoteclose}\isanewline
12.164 -\ \ \ \ \isacommand{by}\isamarkupfalse%
12.165 -\ {\isacharparenleft}simp\ only{\isacharcolon}\ group{\isacharunderscore}class{\isachardot}left{\isacharunderscore}inverse{\isacharparenright}\isanewline
12.166 -\ \ \isacommand{finally}\isamarkupfalse%
12.167 -\ \isacommand{show}\isamarkupfalse%
12.168 -\ {\isacharquery}thesis\ \isacommand{{\isachardot}}\isamarkupfalse%
12.169 -\isanewline
12.170 -\isacommand{qed}\isamarkupfalse%
12.171 -%
12.172 -\endisatagproof
12.173 -{\isafoldproof}%
12.174 -%
12.175 -\isadelimproof
12.176 -%
12.177 -\endisadelimproof
12.178 -%
12.179 -\begin{isamarkuptext}%
12.180 -\noindent With \isa{group{\isacharunderscore}right{\isacharunderscore}inverse} already available, \isa{group{\isacharunderscore}right{\isacharunderscore}unit}\label{thm:group-right-unit} is now established
12.181 - much easier.%
12.182 -\end{isamarkuptext}%
12.183 -\isamarkuptrue%
12.184 -\isacommand{theorem}\isamarkupfalse%
12.185 -\ group{\isacharunderscore}right{\isacharunderscore}unit{\isacharcolon}\ {\isachardoublequoteopen}x\ {\isasymodot}\ {\isasymone}\ {\isacharequal}\ {\isacharparenleft}x{\isasymColon}{\isacharprime}a{\isasymColon}group{\isacharparenright}{\isachardoublequoteclose}\isanewline
12.186 -%
12.187 -\isadelimproof
12.188 -%
12.189 -\endisadelimproof
12.190 -%
12.191 -\isatagproof
12.192 -\isacommand{proof}\isamarkupfalse%
12.193 -\ {\isacharminus}\isanewline
12.194 -\ \ \isacommand{have}\isamarkupfalse%
12.195 -\ {\isachardoublequoteopen}x\ {\isasymodot}\ {\isasymone}\ {\isacharequal}\ x\ {\isasymodot}\ {\isacharparenleft}x{\isasyminv}\ {\isasymodot}\ x{\isacharparenright}{\isachardoublequoteclose}\isanewline
12.196 -\ \ \ \ \isacommand{by}\isamarkupfalse%
12.197 -\ {\isacharparenleft}simp\ only{\isacharcolon}\ group{\isacharunderscore}class{\isachardot}left{\isacharunderscore}inverse{\isacharparenright}\isanewline
12.198 -\ \ \isacommand{also}\isamarkupfalse%
12.199 -\ \isacommand{have}\isamarkupfalse%
12.200 -\ {\isachardoublequoteopen}{\isachardot}{\isachardot}{\isachardot}\ {\isacharequal}\ x\ {\isasymodot}\ x{\isasyminv}\ {\isasymodot}\ x{\isachardoublequoteclose}\isanewline
12.201 -\ \ \ \ \isacommand{by}\isamarkupfalse%
12.202 -\ {\isacharparenleft}simp\ only{\isacharcolon}\ semigroup{\isacharunderscore}class{\isachardot}assoc{\isacharparenright}\isanewline
12.203 -\ \ \isacommand{also}\isamarkupfalse%
12.204 -\ \isacommand{have}\isamarkupfalse%
12.205 -\ {\isachardoublequoteopen}{\isachardot}{\isachardot}{\isachardot}\ {\isacharequal}\ {\isasymone}\ {\isasymodot}\ x{\isachardoublequoteclose}\isanewline
12.206 -\ \ \ \ \isacommand{by}\isamarkupfalse%
12.207 -\ {\isacharparenleft}simp\ only{\isacharcolon}\ group{\isacharunderscore}right{\isacharunderscore}inverse{\isacharparenright}\isanewline
12.208 -\ \ \isacommand{also}\isamarkupfalse%
12.209 -\ \isacommand{have}\isamarkupfalse%
12.210 -\ {\isachardoublequoteopen}{\isachardot}{\isachardot}{\isachardot}\ {\isacharequal}\ x{\isachardoublequoteclose}\isanewline
12.211 -\ \ \ \ \isacommand{by}\isamarkupfalse%
12.212 -\ {\isacharparenleft}simp\ only{\isacharcolon}\ group{\isacharunderscore}class{\isachardot}left{\isacharunderscore}unit{\isacharparenright}\isanewline
12.213 -\ \ \isacommand{finally}\isamarkupfalse%
12.214 -\ \isacommand{show}\isamarkupfalse%
12.215 -\ {\isacharquery}thesis\ \isacommand{{\isachardot}}\isamarkupfalse%
12.216 -\isanewline
12.217 -\isacommand{qed}\isamarkupfalse%
12.218 -%
12.219 -\endisatagproof
12.220 -{\isafoldproof}%
12.221 -%
12.222 -\isadelimproof
12.223 -%
12.224 -\endisadelimproof
12.225 -%
12.226 -\begin{isamarkuptext}%
12.227 -\medskip Abstract theorems may be instantiated to only those types
12.228 - \isa{{\isasymtau}} where the appropriate class membership \isa{{\isasymtau}\ {\isasymColon}\ c} is
12.229 - known at Isabelle's type signature level. Since we have \isa{agroup\ {\isasymsubseteq}\ group\ {\isasymsubseteq}\ semigroup} by definition, all theorems of \isa{semigroup} and \isa{group} are automatically inherited by \isa{group} and \isa{agroup}.%
12.230 -\end{isamarkuptext}%
12.231 -\isamarkuptrue%
12.232 -%
12.233 -\isamarkupsubsection{Abstract instantiation%
12.234 -}
12.235 -\isamarkuptrue%
12.236 -%
12.237 -\begin{isamarkuptext}%
12.238 -From the definition, the \isa{monoid} and \isa{group} classes
12.239 - have been independent. Note that for monoids, \isa{right{\isacharunderscore}unit}
12.240 - had to be included as an axiom, but for groups both \isa{right{\isacharunderscore}unit} and \isa{right{\isacharunderscore}inverse} are derivable from the other
12.241 - axioms. With \isa{group{\isacharunderscore}right{\isacharunderscore}unit} derived as a theorem of group
12.242 - theory (see page~\pageref{thm:group-right-unit}), we may now
12.243 - instantiate \isa{monoid\ {\isasymsubseteq}\ semigroup} and \isa{group\ {\isasymsubseteq}\ monoid} properly as follows (cf.\ \figref{fig:monoid-group}).
12.244 -
12.245 - \begin{figure}[htbp]
12.246 - \begin{center}
12.247 - \small
12.248 - \unitlength 0.6mm
12.249 - \begin{picture}(65,90)(0,-10)
12.250 - \put(15,10){\line(0,1){10}} \put(15,30){\line(0,1){10}}
12.251 - \put(15,50){\line(1,1){10}} \put(35,60){\line(1,-1){10}}
12.252 - \put(15,5){\makebox(0,0){\isa{agroup}}}
12.253 - \put(15,25){\makebox(0,0){\isa{group}}}
12.254 - \put(15,45){\makebox(0,0){\isa{semigroup}}}
12.255 - \put(30,65){\makebox(0,0){\isa{type}}} \put(50,45){\makebox(0,0){\isa{monoid}}}
12.256 - \end{picture}
12.257 - \hspace{4em}
12.258 - \begin{picture}(30,90)(0,0)
12.259 - \put(15,10){\line(0,1){10}} \put(15,30){\line(0,1){10}}
12.260 - \put(15,50){\line(0,1){10}} \put(15,70){\line(0,1){10}}
12.261 - \put(15,5){\makebox(0,0){\isa{agroup}}}
12.262 - \put(15,25){\makebox(0,0){\isa{group}}}
12.263 - \put(15,45){\makebox(0,0){\isa{monoid}}}
12.264 - \put(15,65){\makebox(0,0){\isa{semigroup}}}
12.265 - \put(15,85){\makebox(0,0){\isa{type}}}
12.266 - \end{picture}
12.267 - \caption{Monoids and groups: according to definition, and by proof}
12.268 - \label{fig:monoid-group}
12.269 - \end{center}
12.270 - \end{figure}%
12.271 -\end{isamarkuptext}%
12.272 -\isamarkuptrue%
12.273 -\isacommand{instance}\isamarkupfalse%
12.274 -\ monoid\ {\isasymsubseteq}\ semigroup\isanewline
12.275 -%
12.276 -\isadelimproof
12.277 -%
12.278 -\endisadelimproof
12.279 -%
12.280 -\isatagproof
12.281 -\isacommand{proof}\isamarkupfalse%
12.282 -\isanewline
12.283 -\ \ \isacommand{fix}\isamarkupfalse%
12.284 -\ x\ y\ z\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharprime}a{\isasymColon}monoid{\isachardoublequoteclose}\isanewline
12.285 -\ \ \isacommand{show}\isamarkupfalse%
12.286 -\ {\isachardoublequoteopen}x\ {\isasymodot}\ y\ {\isasymodot}\ z\ {\isacharequal}\ x\ {\isasymodot}\ {\isacharparenleft}y\ {\isasymodot}\ z{\isacharparenright}{\isachardoublequoteclose}\isanewline
12.287 -\ \ \ \ \isacommand{by}\isamarkupfalse%
12.288 -\ {\isacharparenleft}rule\ monoid{\isacharunderscore}class{\isachardot}assoc{\isacharparenright}\isanewline
12.289 -\isacommand{qed}\isamarkupfalse%
12.290 -%
12.291 -\endisatagproof
12.292 -{\isafoldproof}%
12.293 -%
12.294 -\isadelimproof
12.295 -\isanewline
12.296 -%
12.297 -\endisadelimproof
12.298 -\isanewline
12.299 -\isacommand{instance}\isamarkupfalse%
12.300 -\ group\ {\isasymsubseteq}\ monoid\isanewline
12.301 -%
12.302 -\isadelimproof
12.303 -%
12.304 -\endisadelimproof
12.305 -%
12.306 -\isatagproof
12.307 -\isacommand{proof}\isamarkupfalse%
12.308 -\isanewline
12.309 -\ \ \isacommand{fix}\isamarkupfalse%
12.310 -\ x\ y\ z\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharprime}a{\isasymColon}group{\isachardoublequoteclose}\isanewline
12.311 -\ \ \isacommand{show}\isamarkupfalse%
12.312 -\ {\isachardoublequoteopen}x\ {\isasymodot}\ y\ {\isasymodot}\ z\ {\isacharequal}\ x\ {\isasymodot}\ {\isacharparenleft}y\ {\isasymodot}\ z{\isacharparenright}{\isachardoublequoteclose}\isanewline
12.313 -\ \ \ \ \isacommand{by}\isamarkupfalse%
12.314 -\ {\isacharparenleft}rule\ semigroup{\isacharunderscore}class{\isachardot}assoc{\isacharparenright}\isanewline
12.315 -\ \ \isacommand{show}\isamarkupfalse%
12.316 -\ {\isachardoublequoteopen}{\isasymone}\ {\isasymodot}\ x\ {\isacharequal}\ x{\isachardoublequoteclose}\isanewline
12.317 -\ \ \ \ \isacommand{by}\isamarkupfalse%
12.318 -\ {\isacharparenleft}rule\ group{\isacharunderscore}class{\isachardot}left{\isacharunderscore}unit{\isacharparenright}\isanewline
12.319 -\ \ \isacommand{show}\isamarkupfalse%
12.320 -\ {\isachardoublequoteopen}x\ {\isasymodot}\ {\isasymone}\ {\isacharequal}\ x{\isachardoublequoteclose}\isanewline
12.321 -\ \ \ \ \isacommand{by}\isamarkupfalse%
12.322 -\ {\isacharparenleft}rule\ group{\isacharunderscore}right{\isacharunderscore}unit{\isacharparenright}\isanewline
12.323 -\isacommand{qed}\isamarkupfalse%
12.324 -%
12.325 -\endisatagproof
12.326 -{\isafoldproof}%
12.327 -%
12.328 -\isadelimproof
12.329 -%
12.330 -\endisadelimproof
12.331 -%
12.332 -\begin{isamarkuptext}%
12.333 -\medskip The \isakeyword{instance} command sets up an appropriate
12.334 - goal that represents the class inclusion (or type arity, see
12.335 - \secref{sec:inst-arity}) to be proven (see also
12.336 - \cite{isabelle-isar-ref}). The initial proof step causes
12.337 - back-chaining of class membership statements wrt.\ the hierarchy of
12.338 - any classes defined in the current theory; the effect is to reduce
12.339 - to the initial statement to a number of goals that directly
12.340 - correspond to any class axioms encountered on the path upwards
12.341 - through the class hierarchy.%
12.342 -\end{isamarkuptext}%
12.343 -\isamarkuptrue%
12.344 -%
12.345 -\isamarkupsubsection{Concrete instantiation \label{sec:inst-arity}%
12.346 -}
12.347 -\isamarkuptrue%
12.348 -%
12.349 -\begin{isamarkuptext}%
12.350 -So far we have covered the case of the form
12.351 - \isakeyword{instance}~\isa{c\isactrlsub {\isadigit{1}}\ {\isasymsubseteq}\ c\isactrlsub {\isadigit{2}}}, namely
12.352 - \emph{abstract instantiation} --- $c@1$ is more special than \isa{c\isactrlsub {\isadigit{1}}} and thus an instance of \isa{c\isactrlsub {\isadigit{2}}}. Even more
12.353 - interesting for practical applications are \emph{concrete
12.354 - instantiations} of axiomatic type classes. That is, certain simple
12.355 - schemes \isa{{\isacharparenleft}{\isasymalpha}\isactrlsub {\isadigit{1}}{\isacharcomma}\ {\isasymdots}{\isacharcomma}\ {\isasymalpha}\isactrlsub n{\isacharparenright}\ t\ {\isasymColon}\ c} of class
12.356 - membership may be established at the logical level and then
12.357 - transferred to Isabelle's type signature level.
12.358 -
12.359 - \medskip As a typical example, we show that type \isa{bool} with
12.360 - exclusive-or as \isa{{\isasymodot}} operation, identity as \isa{{\isasyminv}}, and
12.361 - \isa{False} as \isa{{\isasymone}} forms an Abelian group.%
12.362 -\end{isamarkuptext}%
12.363 -\isamarkuptrue%
12.364 -\isacommand{defs}\isamarkupfalse%
12.365 -\ {\isacharparenleft}\isakeyword{overloaded}{\isacharparenright}\isanewline
12.366 -\ \ times{\isacharunderscore}bool{\isacharunderscore}def{\isacharcolon}\ {\isachardoublequoteopen}x\ {\isasymodot}\ y\ {\isasymequiv}\ x\ {\isasymnoteq}\ {\isacharparenleft}y{\isasymColon}bool{\isacharparenright}{\isachardoublequoteclose}\isanewline
12.367 -\ \ inverse{\isacharunderscore}bool{\isacharunderscore}def{\isacharcolon}\ {\isachardoublequoteopen}x{\isasyminv}\ {\isasymequiv}\ x{\isasymColon}bool{\isachardoublequoteclose}\isanewline
12.368 -\ \ unit{\isacharunderscore}bool{\isacharunderscore}def{\isacharcolon}\ {\isachardoublequoteopen}{\isasymone}\ {\isasymequiv}\ False{\isachardoublequoteclose}%
12.369 -\begin{isamarkuptext}%
12.370 -\medskip It is important to note that above \isakeyword{defs} are
12.371 - just overloaded meta-level constant definitions, where type classes
12.372 - are not yet involved at all. This form of constant definition with
12.373 - overloading (and optional recursion over the syntactic structure of
12.374 - simple types) are admissible as definitional extensions of plain HOL
12.375 - \cite{Wenzel:1997:TPHOL}. The Haskell-style type system is not
12.376 - required for overloading. Nevertheless, overloaded definitions are
12.377 - best applied in the context of type classes.
12.378 -
12.379 - \medskip Since we have chosen above \isakeyword{defs} of the generic
12.380 - group operations on type \isa{bool} appropriately, the class
12.381 - membership \isa{bool\ {\isasymColon}\ agroup} may be now derived as follows.%
12.382 -\end{isamarkuptext}%
12.383 -\isamarkuptrue%
12.384 -\isacommand{instance}\isamarkupfalse%
12.385 -\ bool\ {\isacharcolon}{\isacharcolon}\ agroup\isanewline
12.386 -%
12.387 -\isadelimproof
12.388 -%
12.389 -\endisadelimproof
12.390 -%
12.391 -\isatagproof
12.392 -\isacommand{proof}\isamarkupfalse%
12.393 -\ {\isacharparenleft}intro{\isacharunderscore}classes{\isacharcomma}\isanewline
12.394 -\ \ \ \ unfold\ times{\isacharunderscore}bool{\isacharunderscore}def\ inverse{\isacharunderscore}bool{\isacharunderscore}def\ unit{\isacharunderscore}bool{\isacharunderscore}def{\isacharparenright}\isanewline
12.395 -\ \ \isacommand{fix}\isamarkupfalse%
12.396 -\ x\ y\ z\isanewline
12.397 -\ \ \isacommand{show}\isamarkupfalse%
12.398 -\ {\isachardoublequoteopen}{\isacharparenleft}{\isacharparenleft}x\ {\isasymnoteq}\ y{\isacharparenright}\ {\isasymnoteq}\ z{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}x\ {\isasymnoteq}\ {\isacharparenleft}y\ {\isasymnoteq}\ z{\isacharparenright}{\isacharparenright}{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse%
12.399 -\ blast\isanewline
12.400 -\ \ \isacommand{show}\isamarkupfalse%
12.401 -\ {\isachardoublequoteopen}{\isacharparenleft}False\ {\isasymnoteq}\ x{\isacharparenright}\ {\isacharequal}\ x{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse%
12.402 -\ blast\isanewline
12.403 -\ \ \isacommand{show}\isamarkupfalse%
12.404 -\ {\isachardoublequoteopen}{\isacharparenleft}x\ {\isasymnoteq}\ x{\isacharparenright}\ {\isacharequal}\ False{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse%
12.405 -\ blast\isanewline
12.406 -\ \ \isacommand{show}\isamarkupfalse%
12.407 -\ {\isachardoublequoteopen}{\isacharparenleft}x\ {\isasymnoteq}\ y{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}y\ {\isasymnoteq}\ x{\isacharparenright}{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse%
12.408 -\ blast\isanewline
12.409 -\isacommand{qed}\isamarkupfalse%
12.410 -%
12.411 -\endisatagproof
12.412 -{\isafoldproof}%
12.413 -%
12.414 -\isadelimproof
12.415 -%
12.416 -\endisadelimproof
12.417 -%
12.418 -\begin{isamarkuptext}%
12.419 -The result of an \isakeyword{instance} statement is both expressed
12.420 - as a theorem of Isabelle's meta-logic, and as a type arity of the
12.421 - type signature. The latter enables type-inference system to take
12.422 - care of this new instance automatically.
12.423 -
12.424 - \medskip We could now also instantiate our group theory classes to
12.425 - many other concrete types. For example, \isa{int\ {\isasymColon}\ agroup}
12.426 - (e.g.\ by defining \isa{{\isasymodot}} as addition, \isa{{\isasyminv}} as negation
12.427 - and \isa{{\isasymone}} as zero) or \isa{list\ {\isasymColon}\ {\isacharparenleft}type{\isacharparenright}\ semigroup}
12.428 - (e.g.\ if \isa{{\isasymodot}} is defined as list append). Thus, the
12.429 - characteristic constants \isa{{\isasymodot}}, \isa{{\isasyminv}}, \isa{{\isasymone}}
12.430 - really become overloaded, i.e.\ have different meanings on different
12.431 - types.%
12.432 -\end{isamarkuptext}%
12.433 -\isamarkuptrue%
12.434 -%
12.435 -\isamarkupsubsection{Lifting and Functors%
12.436 -}
12.437 -\isamarkuptrue%
12.438 -%
12.439 -\begin{isamarkuptext}%
12.440 -As already mentioned above, overloading in the simply-typed HOL
12.441 - systems may include recursion over the syntactic structure of types.
12.442 - That is, definitional equations \isa{c\isactrlsup {\isasymtau}\ {\isasymequiv}\ t} may also
12.443 - contain constants of name \isa{c} on the right-hand side --- if
12.444 - these have types that are structurally simpler than \isa{{\isasymtau}}.
12.445 -
12.446 - This feature enables us to \emph{lift operations}, say to Cartesian
12.447 - products, direct sums or function spaces. Subsequently we lift
12.448 - \isa{{\isasymodot}} component-wise to binary products \isa{{\isacharprime}a\ {\isasymtimes}\ {\isacharprime}b}.%
12.449 -\end{isamarkuptext}%
12.450 -\isamarkuptrue%
12.451 -\isacommand{defs}\isamarkupfalse%
12.452 -\ {\isacharparenleft}\isakeyword{overloaded}{\isacharparenright}\isanewline
12.453 -\ \ times{\isacharunderscore}prod{\isacharunderscore}def{\isacharcolon}\ {\isachardoublequoteopen}p\ {\isasymodot}\ q\ {\isasymequiv}\ {\isacharparenleft}fst\ p\ {\isasymodot}\ fst\ q{\isacharcomma}\ snd\ p\ {\isasymodot}\ snd\ q{\isacharparenright}{\isachardoublequoteclose}%
12.454 -\begin{isamarkuptext}%
12.455 -It is very easy to see that associativity of \isa{{\isasymodot}} on \isa{{\isacharprime}a}
12.456 - and \isa{{\isasymodot}} on \isa{{\isacharprime}b} transfers to \isa{{\isasymodot}} on \isa{{\isacharprime}a\ {\isasymtimes}\ {\isacharprime}b}. Hence the binary type constructor \isa{{\isasymodot}} maps semigroups
12.457 - to semigroups. This may be established formally as follows.%
12.458 -\end{isamarkuptext}%
12.459 -\isamarkuptrue%
12.460 -\isacommand{instance}\isamarkupfalse%
12.461 -\ {\isacharasterisk}\ {\isacharcolon}{\isacharcolon}\ {\isacharparenleft}semigroup{\isacharcomma}\ semigroup{\isacharparenright}\ semigroup\isanewline
12.462 -%
12.463 -\isadelimproof
12.464 -%
12.465 -\endisadelimproof
12.466 -%
12.467 -\isatagproof
12.468 -\isacommand{proof}\isamarkupfalse%
12.469 -\ {\isacharparenleft}intro{\isacharunderscore}classes{\isacharcomma}\ unfold\ times{\isacharunderscore}prod{\isacharunderscore}def{\isacharparenright}\isanewline
12.470 -\ \ \isacommand{fix}\isamarkupfalse%
12.471 -\ p\ q\ r\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharprime}a{\isasymColon}semigroup\ {\isasymtimes}\ {\isacharprime}b{\isasymColon}semigroup{\isachardoublequoteclose}\isanewline
12.472 -\ \ \isacommand{show}\isamarkupfalse%
12.473 -\isanewline
12.474 -\ \ \ \ {\isachardoublequoteopen}{\isacharparenleft}fst\ {\isacharparenleft}fst\ p\ {\isasymodot}\ fst\ q{\isacharcomma}\ snd\ p\ {\isasymodot}\ snd\ q{\isacharparenright}\ {\isasymodot}\ fst\ r{\isacharcomma}\isanewline
12.475 -\ \ \ \ \ \ snd\ {\isacharparenleft}fst\ p\ {\isasymodot}\ fst\ q{\isacharcomma}\ snd\ p\ {\isasymodot}\ snd\ q{\isacharparenright}\ {\isasymodot}\ snd\ r{\isacharparenright}\ {\isacharequal}\isanewline
12.476 -\ \ \ \ \ \ \ {\isacharparenleft}fst\ p\ {\isasymodot}\ fst\ {\isacharparenleft}fst\ q\ {\isasymodot}\ fst\ r{\isacharcomma}\ snd\ q\ {\isasymodot}\ snd\ r{\isacharparenright}{\isacharcomma}\isanewline
12.477 -\ \ \ \ \ \ \ \ snd\ p\ {\isasymodot}\ snd\ {\isacharparenleft}fst\ q\ {\isasymodot}\ fst\ r{\isacharcomma}\ snd\ q\ {\isasymodot}\ snd\ r{\isacharparenright}{\isacharparenright}{\isachardoublequoteclose}\isanewline
12.478 -\ \ \ \ \isacommand{by}\isamarkupfalse%
12.479 -\ {\isacharparenleft}simp\ add{\isacharcolon}\ semigroup{\isacharunderscore}class{\isachardot}assoc{\isacharparenright}\isanewline
12.480 -\isacommand{qed}\isamarkupfalse%
12.481 -%
12.482 -\endisatagproof
12.483 -{\isafoldproof}%
12.484 -%
12.485 -\isadelimproof
12.486 -%
12.487 -\endisadelimproof
12.488 -%
12.489 -\begin{isamarkuptext}%
12.490 -Thus, if we view class instances as ``structures'', then overloaded
12.491 - constant definitions with recursion over types indirectly provide
12.492 - some kind of ``functors'' --- i.e.\ mappings between abstract
12.493 - theories.%
12.494 -\end{isamarkuptext}%
12.495 -\isamarkuptrue%
12.496 -%
12.497 -\isadelimtheory
12.498 -%
12.499 -\endisadelimtheory
12.500 -%
12.501 -\isatagtheory
12.502 -\isacommand{end}\isamarkupfalse%
12.503 -%
12.504 -\endisatagtheory
12.505 -{\isafoldtheory}%
12.506 -%
12.507 -\isadelimtheory
12.508 -%
12.509 -\endisadelimtheory
12.510 -\isanewline
12.511 -\end{isabellebody}%
12.512 -%%% Local Variables:
12.513 -%%% mode: latex
12.514 -%%% TeX-master: "root"
12.515 -%%% End:
13.1 --- a/doc-src/AxClass/Group/document/Product.tex Wed Mar 04 11:05:02 2009 +0100
13.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
13.3 @@ -1,133 +0,0 @@
13.4 -%
13.5 -\begin{isabellebody}%
13.6 -\def\isabellecontext{Product}%
13.7 -%
13.8 -\isamarkupheader{Syntactic classes%
13.9 -}
13.10 -\isamarkuptrue%
13.11 -%
13.12 -\isadelimtheory
13.13 -%
13.14 -\endisadelimtheory
13.15 -%
13.16 -\isatagtheory
13.17 -\isacommand{theory}\isamarkupfalse%
13.18 -\ Product\ \isakeyword{imports}\ Main\ \isakeyword{begin}%
13.19 -\endisatagtheory
13.20 -{\isafoldtheory}%
13.21 -%
13.22 -\isadelimtheory
13.23 -%
13.24 -\endisadelimtheory
13.25 -%
13.26 -\begin{isamarkuptext}%
13.27 -\medskip\noindent There is still a feature of Isabelle's type system
13.28 - left that we have not yet discussed. When declaring polymorphic
13.29 - constants \isa{c\ {\isasymColon}\ {\isasymsigma}}, the type variables occurring in \isa{{\isasymsigma}}
13.30 - may be constrained by type classes (or even general sorts) in an
13.31 - arbitrary way. Note that by default, in Isabelle/HOL the
13.32 - declaration \isa{{\isasymodot}\ {\isasymColon}\ {\isacharprime}a\ {\isasymRightarrow}\ {\isacharprime}a\ {\isasymRightarrow}\ {\isacharprime}a} is actually an abbreviation
13.33 - for \isa{{\isasymodot}\ {\isasymColon}\ {\isacharprime}a{\isasymColon}type\ {\isasymRightarrow}\ {\isacharprime}a\ {\isasymRightarrow}\ {\isacharprime}a} Since class \isa{type} is the
13.34 - universal class of HOL, this is not really a constraint at all.
13.35 -
13.36 - The \isa{product} class below provides a less degenerate example of
13.37 - syntactic type classes.%
13.38 -\end{isamarkuptext}%
13.39 -\isamarkuptrue%
13.40 -\isacommand{axclass}\isamarkupfalse%
13.41 -\isanewline
13.42 -\ \ product\ {\isasymsubseteq}\ type\isanewline
13.43 -\isacommand{consts}\isamarkupfalse%
13.44 -\isanewline
13.45 -\ \ product\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharprime}a{\isasymColon}product\ {\isasymRightarrow}\ {\isacharprime}a\ {\isasymRightarrow}\ {\isacharprime}a{\isachardoublequoteclose}\ \ \ \ {\isacharparenleft}\isakeyword{infixl}\ {\isachardoublequoteopen}{\isasymodot}{\isachardoublequoteclose}\ {\isadigit{7}}{\isadigit{0}}{\isacharparenright}%
13.46 -\begin{isamarkuptext}%
13.47 -Here class \isa{product} is defined as subclass of \isa{type}
13.48 - without any additional axioms. This effects in logical equivalence
13.49 - of \isa{product} and \isa{type}, as is reflected by the trivial
13.50 - introduction rule generated for this definition.
13.51 -
13.52 - \medskip So what is the difference of declaring \isa{{\isasymodot}\ {\isasymColon}\ {\isacharprime}a{\isasymColon}product\ {\isasymRightarrow}\ {\isacharprime}a\ {\isasymRightarrow}\ {\isacharprime}a} vs.\ declaring \isa{{\isasymodot}\ {\isasymColon}\ {\isacharprime}a{\isasymColon}type\ {\isasymRightarrow}\ {\isacharprime}a\ {\isasymRightarrow}\ {\isacharprime}a} anyway? In this particular case where \isa{product\ {\isasymequiv}\ type}, it should be obvious that both declarations are the same
13.53 - from the logic's point of view. It even makes the most sense to
13.54 - remove sort constraints from constant declarations, as far as the
13.55 - purely logical meaning is concerned \cite{Wenzel:1997:TPHOL}.
13.56 -
13.57 - On the other hand there are syntactic differences, of course.
13.58 - Constants \isa{{\isasymodot}} on some type \isa{{\isasymtau}} are rejected by the
13.59 - type-checker, unless the arity \isa{{\isasymtau}\ {\isasymColon}\ product} is part of the
13.60 - type signature. In our example, this arity may be always added when
13.61 - required by means of an \isakeyword{instance} with the default proof
13.62 - (double-dot).
13.63 -
13.64 - \medskip Thus, we may observe the following discipline of using
13.65 - syntactic classes. Overloaded polymorphic constants have their type
13.66 - arguments restricted to an associated (logically trivial) class
13.67 - \isa{c}. Only immediately before \emph{specifying} these
13.68 - constants on a certain type \isa{{\isasymtau}} do we instantiate \isa{{\isasymtau}\ {\isasymColon}\ c}.
13.69 -
13.70 - This is done for class \isa{product} and type \isa{bool} as
13.71 - follows.%
13.72 -\end{isamarkuptext}%
13.73 -\isamarkuptrue%
13.74 -\isacommand{instance}\isamarkupfalse%
13.75 -\ bool\ {\isacharcolon}{\isacharcolon}\ product%
13.76 -\isadelimproof
13.77 -\ %
13.78 -\endisadelimproof
13.79 -%
13.80 -\isatagproof
13.81 -\isacommand{{\isachardot}{\isachardot}}\isamarkupfalse%
13.82 -%
13.83 -\endisatagproof
13.84 -{\isafoldproof}%
13.85 -%
13.86 -\isadelimproof
13.87 -%
13.88 -\endisadelimproof
13.89 -\isanewline
13.90 -\isacommand{defs}\isamarkupfalse%
13.91 -\ {\isacharparenleft}\isakeyword{overloaded}{\isacharparenright}\isanewline
13.92 -\ \ product{\isacharunderscore}bool{\isacharunderscore}def{\isacharcolon}\ {\isachardoublequoteopen}x\ {\isasymodot}\ y\ {\isasymequiv}\ x\ {\isasymand}\ y{\isachardoublequoteclose}%
13.93 -\begin{isamarkuptext}%
13.94 -The definition \isa{prod{\isacharunderscore}bool{\isacharunderscore}def} becomes syntactically
13.95 - well-formed only after the arity \isa{bool\ {\isasymColon}\ product} is made
13.96 - known to the type checker.
13.97 -
13.98 - \medskip It is very important to see that above \isakeyword{defs} are
13.99 - not directly connected with \isakeyword{instance} at all! We were
13.100 - just following our convention to specify \isa{{\isasymodot}} on \isa{bool}
13.101 - after having instantiated \isa{bool\ {\isasymColon}\ product}. Isabelle does
13.102 - not require these definitions, which is in contrast to programming
13.103 - languages like Haskell \cite{haskell-report}.
13.104 -
13.105 - \medskip While Isabelle type classes and those of Haskell are almost
13.106 - the same as far as type-checking and type inference are concerned,
13.107 - there are important semantic differences. Haskell classes require
13.108 - their instances to \emph{provide operations} of certain \emph{names}.
13.109 - Therefore, its \texttt{instance} has a \texttt{where} part that tells
13.110 - the system what these ``member functions'' should be.
13.111 -
13.112 - This style of \texttt{instance} would not make much sense in
13.113 - Isabelle's meta-logic, because there is no internal notion of
13.114 - ``providing operations'' or even ``names of functions''.%
13.115 -\end{isamarkuptext}%
13.116 -\isamarkuptrue%
13.117 -%
13.118 -\isadelimtheory
13.119 -%
13.120 -\endisadelimtheory
13.121 -%
13.122 -\isatagtheory
13.123 -\isacommand{end}\isamarkupfalse%
13.124 -%
13.125 -\endisatagtheory
13.126 -{\isafoldtheory}%
13.127 -%
13.128 -\isadelimtheory
13.129 -%
13.130 -\endisadelimtheory
13.131 -\isanewline
13.132 -\end{isabellebody}%
13.133 -%%% Local Variables:
13.134 -%%% mode: latex
13.135 -%%% TeX-master: "root"
13.136 -%%% End:
14.1 --- a/doc-src/AxClass/Group/document/Semigroups.tex Wed Mar 04 11:05:02 2009 +0100
14.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
14.3 @@ -1,88 +0,0 @@
14.4 -%
14.5 -\begin{isabellebody}%
14.6 -\def\isabellecontext{Semigroups}%
14.7 -%
14.8 -\isamarkupheader{Semigroups%
14.9 -}
14.10 -\isamarkuptrue%
14.11 -%
14.12 -\isadelimtheory
14.13 -%
14.14 -\endisadelimtheory
14.15 -%
14.16 -\isatagtheory
14.17 -\isacommand{theory}\isamarkupfalse%
14.18 -\ Semigroups\ \isakeyword{imports}\ Main\ \isakeyword{begin}%
14.19 -\endisatagtheory
14.20 -{\isafoldtheory}%
14.21 -%
14.22 -\isadelimtheory
14.23 -%
14.24 -\endisadelimtheory
14.25 -%
14.26 -\begin{isamarkuptext}%
14.27 -\medskip\noindent An axiomatic type class is simply a class of types
14.28 - that all meet certain properties, which are also called \emph{class
14.29 - axioms}. Thus, type classes may be also understood as type
14.30 - predicates --- i.e.\ abstractions over a single type argument \isa{{\isacharprime}a}. Class axioms typically contain polymorphic constants that
14.31 - depend on this type \isa{{\isacharprime}a}. These \emph{characteristic
14.32 - constants} behave like operations associated with the ``carrier''
14.33 - type \isa{{\isacharprime}a}.
14.34 -
14.35 - We illustrate these basic concepts by the following formulation of
14.36 - semigroups.%
14.37 -\end{isamarkuptext}%
14.38 -\isamarkuptrue%
14.39 -\isacommand{consts}\isamarkupfalse%
14.40 -\isanewline
14.41 -\ \ times\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharprime}a\ {\isasymRightarrow}\ {\isacharprime}a\ {\isasymRightarrow}\ {\isacharprime}a{\isachardoublequoteclose}\ \ \ \ {\isacharparenleft}\isakeyword{infixl}\ {\isachardoublequoteopen}{\isasymodot}{\isachardoublequoteclose}\ {\isadigit{7}}{\isadigit{0}}{\isacharparenright}\isanewline
14.42 -\isacommand{axclass}\isamarkupfalse%
14.43 -\ semigroup\ {\isasymsubseteq}\ type\isanewline
14.44 -\ \ assoc{\isacharcolon}\ {\isachardoublequoteopen}{\isacharparenleft}x\ {\isasymodot}\ y{\isacharparenright}\ {\isasymodot}\ z\ {\isacharequal}\ x\ {\isasymodot}\ {\isacharparenleft}y\ {\isasymodot}\ z{\isacharparenright}{\isachardoublequoteclose}%
14.45 -\begin{isamarkuptext}%
14.46 -\noindent Above we have first declared a polymorphic constant \isa{{\isasymodot}\ {\isasymColon}\ {\isacharprime}a\ {\isasymRightarrow}\ {\isacharprime}a\ {\isasymRightarrow}\ {\isacharprime}a} and then defined the class \isa{semigroup} of
14.47 - all types \isa{{\isasymtau}} such that \isa{{\isasymodot}\ {\isasymColon}\ {\isasymtau}\ {\isasymRightarrow}\ {\isasymtau}\ {\isasymRightarrow}\ {\isasymtau}} is indeed an
14.48 - associative operator. The \isa{assoc} axiom contains exactly one
14.49 - type variable, which is invisible in the above presentation, though.
14.50 - Also note that free term variables (like \isa{x}, \isa{y},
14.51 - \isa{z}) are allowed for user convenience --- conceptually all of
14.52 - these are bound by outermost universal quantifiers.
14.53 -
14.54 - \medskip In general, type classes may be used to describe
14.55 - \emph{structures} with exactly one carrier \isa{{\isacharprime}a} and a fixed
14.56 - \emph{signature}. Different signatures require different classes.
14.57 - Below, class \isa{plus{\isacharunderscore}semigroup} represents semigroups \isa{{\isacharparenleft}{\isasymtau}{\isacharcomma}\ {\isasymoplus}\isactrlsup {\isasymtau}{\isacharparenright}}, while the original \isa{semigroup} would
14.58 - correspond to semigroups of the form \isa{{\isacharparenleft}{\isasymtau}{\isacharcomma}\ {\isasymodot}\isactrlsup {\isasymtau}{\isacharparenright}}.%
14.59 -\end{isamarkuptext}%
14.60 -\isamarkuptrue%
14.61 -\isacommand{consts}\isamarkupfalse%
14.62 -\isanewline
14.63 -\ \ plus\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharprime}a\ {\isasymRightarrow}\ {\isacharprime}a\ {\isasymRightarrow}\ {\isacharprime}a{\isachardoublequoteclose}\ \ \ \ {\isacharparenleft}\isakeyword{infixl}\ {\isachardoublequoteopen}{\isasymoplus}{\isachardoublequoteclose}\ {\isadigit{7}}{\isadigit{0}}{\isacharparenright}\isanewline
14.64 -\isacommand{axclass}\isamarkupfalse%
14.65 -\ plus{\isacharunderscore}semigroup\ {\isasymsubseteq}\ type\isanewline
14.66 -\ \ assoc{\isacharcolon}\ {\isachardoublequoteopen}{\isacharparenleft}x\ {\isasymoplus}\ y{\isacharparenright}\ {\isasymoplus}\ z\ {\isacharequal}\ x\ {\isasymoplus}\ {\isacharparenleft}y\ {\isasymoplus}\ z{\isacharparenright}{\isachardoublequoteclose}%
14.67 -\begin{isamarkuptext}%
14.68 -\noindent Even if classes \isa{plus{\isacharunderscore}semigroup} and \isa{semigroup} both represent semigroups in a sense, they are certainly
14.69 - not quite the same.%
14.70 -\end{isamarkuptext}%
14.71 -\isamarkuptrue%
14.72 -%
14.73 -\isadelimtheory
14.74 -%
14.75 -\endisadelimtheory
14.76 -%
14.77 -\isatagtheory
14.78 -\isacommand{end}\isamarkupfalse%
14.79 -%
14.80 -\endisatagtheory
14.81 -{\isafoldtheory}%
14.82 -%
14.83 -\isadelimtheory
14.84 -%
14.85 -\endisadelimtheory
14.86 -\isanewline
14.87 -\end{isabellebody}%
14.88 -%%% Local Variables:
14.89 -%%% mode: latex
14.90 -%%% TeX-master: "root"
14.91 -%%% End:
15.1 --- a/doc-src/AxClass/IsaMakefile Wed Mar 04 11:05:02 2009 +0100
15.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
15.3 @@ -1,47 +0,0 @@
15.4 -
15.5 -## targets
15.6 -
15.7 -default: Group Nat
15.8 -images:
15.9 -test: Group Nat
15.10 -
15.11 -all: images test
15.12 -
15.13 -
15.14 -## global settings
15.15 -
15.16 -SRC = $(ISABELLE_HOME)/src
15.17 -OUT = $(ISABELLE_OUTPUT)
15.18 -LOG = $(OUT)/log
15.19 -USEDIR = $(ISABELLE_TOOL) usedir -d false -D document
15.20 -
15.21 -
15.22 -## Group
15.23 -
15.24 -Group: HOL $(LOG)/HOL-Group.gz
15.25 -
15.26 -HOL:
15.27 - @cd $(SRC)/HOL; $(ISABELLE_TOOL) make HOL
15.28 -
15.29 -$(LOG)/HOL-Group.gz: $(OUT)/HOL Group/ROOT.ML Group/Group.thy \
15.30 - Group/Product.thy Group/Semigroups.thy
15.31 - @$(USEDIR) $(OUT)/HOL Group
15.32 - @rm -f Group/document/pdfsetup.sty Group/document/session.tex
15.33 -
15.34 -
15.35 -## Nat
15.36 -
15.37 -Nat: FOL $(LOG)/FOL-Nat.gz
15.38 -
15.39 -FOL:
15.40 - @cd $(SRC)/FOL; $(ISABELLE_TOOL) make FOL
15.41 -
15.42 -$(LOG)/FOL-Nat.gz: $(OUT)/FOL Nat/ROOT.ML Nat/NatClass.thy
15.43 - @$(USEDIR) $(OUT)/FOL Nat
15.44 - @rm -f Nat/document/*.sty Nat/document/session.tex
15.45 -
15.46 -
15.47 -## clean
15.48 -
15.49 -clean:
15.50 - @rm -f $(LOG)/HOL-Group.gz $(LOG)/FOL-Nat.gz
16.1 --- a/doc-src/AxClass/Makefile Wed Mar 04 11:05:02 2009 +0100
16.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
16.3 @@ -1,36 +0,0 @@
16.4 -#
16.5 -# $Id$
16.6 -#
16.7 -
16.8 -## targets
16.9 -
16.10 -default: dvi
16.11 -
16.12 -
16.13 -## dependencies
16.14 -
16.15 -include ../Makefile.in
16.16 -
16.17 -NAME = axclass
16.18 -
16.19 -FILES = axclass.tex body.tex ../iman.sty ../extra.sty ../isar.sty \
16.20 - ../isabelle.sty ../isabellesym.sty ../pdfsetup.sty \
16.21 - Group/document/Group.tex Nat/document/NatClass.tex \
16.22 - Group/document/Product.tex Group/document/Semigroups.tex
16.23 -
16.24 -dvi: $(NAME).dvi
16.25 -
16.26 -$(NAME).dvi: $(FILES) isabelle_isar.eps
16.27 - $(LATEX) $(NAME)
16.28 - $(BIBTEX) $(NAME)
16.29 - $(LATEX) $(NAME)
16.30 - $(LATEX) $(NAME)
16.31 -
16.32 -pdf: $(NAME).pdf
16.33 -
16.34 -$(NAME).pdf: $(FILES) isabelle_isar.pdf
16.35 - $(PDFLATEX) $(NAME)
16.36 - $(FIXBOOKMARKS) $(NAME).out
16.37 - $(BIBTEX) $(NAME)
16.38 - $(PDFLATEX) $(NAME)
16.39 - $(PDFLATEX) $(NAME)
17.1 --- a/doc-src/AxClass/Nat/NatClass.thy Wed Mar 04 11:05:02 2009 +0100
17.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
17.3 @@ -1,117 +0,0 @@
17.4 -
17.5 -header {* Defining natural numbers in FOL \label{sec:ex-natclass} *}
17.6 -
17.7 -theory NatClass imports FOL begin
17.8 -
17.9 -text {*
17.10 - \medskip\noindent Axiomatic type classes abstract over exactly one
17.11 - type argument. Thus, any \emph{axiomatic} theory extension where each
17.12 - axiom refers to at most one type variable, may be trivially turned
17.13 - into a \emph{definitional} one.
17.14 -
17.15 - We illustrate this with the natural numbers in
17.16 - Isabelle/FOL.\footnote{See also
17.17 - \url{http://isabelle.in.tum.de/library/FOL/ex/NatClass.html}}
17.18 -*}
17.19 -
17.20 -consts
17.21 - zero :: 'a ("\<zero>")
17.22 - Suc :: "'a \<Rightarrow> 'a"
17.23 - rec :: "'a \<Rightarrow> 'a \<Rightarrow> ('a \<Rightarrow> 'a \<Rightarrow> 'a) \<Rightarrow> 'a"
17.24 -
17.25 -axclass nat \<subseteq> "term"
17.26 - induct: "P(\<zero>) \<Longrightarrow> (\<And>x. P(x) \<Longrightarrow> P(Suc(x))) \<Longrightarrow> P(n)"
17.27 - Suc_inject: "Suc(m) = Suc(n) \<Longrightarrow> m = n"
17.28 - Suc_neq_0: "Suc(m) = \<zero> \<Longrightarrow> R"
17.29 - rec_0: "rec(\<zero>, a, f) = a"
17.30 - rec_Suc: "rec(Suc(m), a, f) = f(m, rec(m, a, f))"
17.31 -
17.32 -constdefs
17.33 - add :: "'a::nat \<Rightarrow> 'a \<Rightarrow> 'a" (infixl "+" 60)
17.34 - "m + n \<equiv> rec(m, n, \<lambda>x y. Suc(y))"
17.35 -
17.36 -text {*
17.37 - This is an abstract version of the plain @{text Nat} theory in
17.38 - FOL.\footnote{See
17.39 - \url{http://isabelle.in.tum.de/library/FOL/ex/Nat.html}} Basically,
17.40 - we have just replaced all occurrences of type @{text nat} by @{typ
17.41 - 'a} and used the natural number axioms to define class @{text nat}.
17.42 - There is only a minor snag, that the original recursion operator
17.43 - @{term rec} had to be made monomorphic.
17.44 -
17.45 - Thus class @{text nat} contains exactly those types @{text \<tau>} that
17.46 - are isomorphic to ``the'' natural numbers (with signature @{term
17.47 - \<zero>}, @{term Suc}, @{term rec}).
17.48 -
17.49 - \medskip What we have done here can be also viewed as \emph{type
17.50 - specification}. Of course, it still remains open if there is some
17.51 - type at all that meets the class axioms. Now a very nice property of
17.52 - axiomatic type classes is that abstract reasoning is always possible
17.53 - --- independent of satisfiability. The meta-logic won't break, even
17.54 - if some classes (or general sorts) turns out to be empty later ---
17.55 - ``inconsistent'' class definitions may be useless, but do not cause
17.56 - any harm.
17.57 -
17.58 - Theorems of the abstract natural numbers may be derived in the same
17.59 - way as for the concrete version. The original proof scripts may be
17.60 - re-used with some trivial changes only (mostly adding some type
17.61 - constraints).
17.62 -*}
17.63 -
17.64 -(*<*)
17.65 -lemma Suc_n_not_n: "Suc(k) ~= (k::'a::nat)"
17.66 -apply (rule_tac n = k in induct)
17.67 -apply (rule notI)
17.68 -apply (erule Suc_neq_0)
17.69 -apply (rule notI)
17.70 -apply (erule notE)
17.71 -apply (erule Suc_inject)
17.72 -done
17.73 -
17.74 -lemma "(k+m)+n = k+(m+n)"
17.75 -apply (rule induct)
17.76 -back
17.77 -back
17.78 -back
17.79 -back
17.80 -back
17.81 -back
17.82 -oops
17.83 -
17.84 -lemma add_0 [simp]: "\<zero>+n = n"
17.85 -apply (unfold add_def)
17.86 -apply (rule rec_0)
17.87 -done
17.88 -
17.89 -lemma add_Suc [simp]: "Suc(m)+n = Suc(m+n)"
17.90 -apply (unfold add_def)
17.91 -apply (rule rec_Suc)
17.92 -done
17.93 -
17.94 -lemma add_assoc: "(k+m)+n = k+(m+n)"
17.95 -apply (rule_tac n = k in induct)
17.96 -apply simp
17.97 -apply simp
17.98 -done
17.99 -
17.100 -lemma add_0_right: "m+\<zero> = m"
17.101 -apply (rule_tac n = m in induct)
17.102 -apply simp
17.103 -apply simp
17.104 -done
17.105 -
17.106 -lemma add_Suc_right: "m+Suc(n) = Suc(m+n)"
17.107 -apply (rule_tac n = m in induct)
17.108 -apply simp_all
17.109 -done
17.110 -
17.111 -lemma
17.112 - assumes prem: "!!n. f(Suc(n)) = Suc(f(n))"
17.113 - shows "f(i+j) = i+f(j)"
17.114 -apply (rule_tac n = i in induct)
17.115 -apply simp
17.116 -apply (simp add: prem)
17.117 -done
17.118 -(*>*)
17.119 -
17.120 -end
17.121 \ No newline at end of file
18.1 --- a/doc-src/AxClass/Nat/ROOT.ML Wed Mar 04 11:05:02 2009 +0100
18.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
18.3 @@ -1,2 +0,0 @@
18.4 -
18.5 -use_thy "NatClass";
19.1 --- a/doc-src/AxClass/Nat/document/NatClass.tex Wed Mar 04 11:05:02 2009 +0100
19.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
19.3 @@ -1,201 +0,0 @@
19.4 -%
19.5 -\begin{isabellebody}%
19.6 -\def\isabellecontext{NatClass}%
19.7 -%
19.8 -\isamarkupheader{Defining natural numbers in FOL \label{sec:ex-natclass}%
19.9 -}
19.10 -\isamarkuptrue%
19.11 -%
19.12 -\isadelimtheory
19.13 -%
19.14 -\endisadelimtheory
19.15 -%
19.16 -\isatagtheory
19.17 -\isacommand{theory}\isamarkupfalse%
19.18 -\ NatClass\ \isakeyword{imports}\ FOL\ \isakeyword{begin}%
19.19 -\endisatagtheory
19.20 -{\isafoldtheory}%
19.21 -%
19.22 -\isadelimtheory
19.23 -%
19.24 -\endisadelimtheory
19.25 -%
19.26 -\begin{isamarkuptext}%
19.27 -\medskip\noindent Axiomatic type classes abstract over exactly one
19.28 - type argument. Thus, any \emph{axiomatic} theory extension where each
19.29 - axiom refers to at most one type variable, may be trivially turned
19.30 - into a \emph{definitional} one.
19.31 -
19.32 - We illustrate this with the natural numbers in
19.33 - Isabelle/FOL.\footnote{See also
19.34 - \url{http://isabelle.in.tum.de/library/FOL/ex/NatClass.html}}%
19.35 -\end{isamarkuptext}%
19.36 -\isamarkuptrue%
19.37 -\isacommand{consts}\isamarkupfalse%
19.38 -\isanewline
19.39 -\ \ zero\ {\isacharcolon}{\isacharcolon}\ {\isacharprime}a\ \ \ \ {\isacharparenleft}{\isachardoublequoteopen}{\isasymzero}{\isachardoublequoteclose}{\isacharparenright}\isanewline
19.40 -\ \ Suc\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharprime}a\ {\isasymRightarrow}\ {\isacharprime}a{\isachardoublequoteclose}\isanewline
19.41 -\ \ rec\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharprime}a\ {\isasymRightarrow}\ {\isacharprime}a\ {\isasymRightarrow}\ {\isacharparenleft}{\isacharprime}a\ {\isasymRightarrow}\ {\isacharprime}a\ {\isasymRightarrow}\ {\isacharprime}a{\isacharparenright}\ {\isasymRightarrow}\ {\isacharprime}a{\isachardoublequoteclose}\isanewline
19.42 -\isanewline
19.43 -\isacommand{axclass}\isamarkupfalse%
19.44 -\ nat\ {\isasymsubseteq}\ {\isachardoublequoteopen}term{\isachardoublequoteclose}\isanewline
19.45 -\ \ induct{\isacharcolon}\ {\isachardoublequoteopen}P{\isacharparenleft}{\isasymzero}{\isacharparenright}\ {\isasymLongrightarrow}\ {\isacharparenleft}{\isasymAnd}x{\isachardot}\ P{\isacharparenleft}x{\isacharparenright}\ {\isasymLongrightarrow}\ P{\isacharparenleft}Suc{\isacharparenleft}x{\isacharparenright}{\isacharparenright}{\isacharparenright}\ {\isasymLongrightarrow}\ P{\isacharparenleft}n{\isacharparenright}{\isachardoublequoteclose}\isanewline
19.46 -\ \ Suc{\isacharunderscore}inject{\isacharcolon}\ {\isachardoublequoteopen}Suc{\isacharparenleft}m{\isacharparenright}\ {\isacharequal}\ Suc{\isacharparenleft}n{\isacharparenright}\ {\isasymLongrightarrow}\ m\ {\isacharequal}\ n{\isachardoublequoteclose}\isanewline
19.47 -\ \ Suc{\isacharunderscore}neq{\isacharunderscore}{\isadigit{0}}{\isacharcolon}\ {\isachardoublequoteopen}Suc{\isacharparenleft}m{\isacharparenright}\ {\isacharequal}\ {\isasymzero}\ {\isasymLongrightarrow}\ R{\isachardoublequoteclose}\isanewline
19.48 -\ \ rec{\isacharunderscore}{\isadigit{0}}{\isacharcolon}\ {\isachardoublequoteopen}rec{\isacharparenleft}{\isasymzero}{\isacharcomma}\ a{\isacharcomma}\ f{\isacharparenright}\ {\isacharequal}\ a{\isachardoublequoteclose}\isanewline
19.49 -\ \ rec{\isacharunderscore}Suc{\isacharcolon}\ {\isachardoublequoteopen}rec{\isacharparenleft}Suc{\isacharparenleft}m{\isacharparenright}{\isacharcomma}\ a{\isacharcomma}\ f{\isacharparenright}\ {\isacharequal}\ f{\isacharparenleft}m{\isacharcomma}\ rec{\isacharparenleft}m{\isacharcomma}\ a{\isacharcomma}\ f{\isacharparenright}{\isacharparenright}{\isachardoublequoteclose}\isanewline
19.50 -\isanewline
19.51 -\isacommand{constdefs}\isamarkupfalse%
19.52 -\isanewline
19.53 -\ \ add\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharprime}a{\isacharcolon}{\isacharcolon}nat\ {\isasymRightarrow}\ {\isacharprime}a\ {\isasymRightarrow}\ {\isacharprime}a{\isachardoublequoteclose}\ \ \ \ {\isacharparenleft}\isakeyword{infixl}\ {\isachardoublequoteopen}{\isacharplus}{\isachardoublequoteclose}\ {\isadigit{6}}{\isadigit{0}}{\isacharparenright}\isanewline
19.54 -\ \ {\isachardoublequoteopen}m\ {\isacharplus}\ n\ {\isasymequiv}\ rec{\isacharparenleft}m{\isacharcomma}\ n{\isacharcomma}\ {\isasymlambda}x\ y{\isachardot}\ Suc{\isacharparenleft}y{\isacharparenright}{\isacharparenright}{\isachardoublequoteclose}%
19.55 -\begin{isamarkuptext}%
19.56 -This is an abstract version of the plain \isa{Nat} theory in
19.57 - FOL.\footnote{See
19.58 - \url{http://isabelle.in.tum.de/library/FOL/ex/Nat.html}} Basically,
19.59 - we have just replaced all occurrences of type \isa{nat} by \isa{{\isacharprime}a} and used the natural number axioms to define class \isa{nat}.
19.60 - There is only a minor snag, that the original recursion operator
19.61 - \isa{rec} had to be made monomorphic.
19.62 -
19.63 - Thus class \isa{nat} contains exactly those types \isa{{\isasymtau}} that
19.64 - are isomorphic to ``the'' natural numbers (with signature \isa{{\isasymzero}}, \isa{Suc}, \isa{rec}).
19.65 -
19.66 - \medskip What we have done here can be also viewed as \emph{type
19.67 - specification}. Of course, it still remains open if there is some
19.68 - type at all that meets the class axioms. Now a very nice property of
19.69 - axiomatic type classes is that abstract reasoning is always possible
19.70 - --- independent of satisfiability. The meta-logic won't break, even
19.71 - if some classes (or general sorts) turns out to be empty later ---
19.72 - ``inconsistent'' class definitions may be useless, but do not cause
19.73 - any harm.
19.74 -
19.75 - Theorems of the abstract natural numbers may be derived in the same
19.76 - way as for the concrete version. The original proof scripts may be
19.77 - re-used with some trivial changes only (mostly adding some type
19.78 - constraints).%
19.79 -\end{isamarkuptext}%
19.80 -\isamarkuptrue%
19.81 -%
19.82 -\isadelimproof
19.83 -%
19.84 -\endisadelimproof
19.85 -%
19.86 -\isatagproof
19.87 -%
19.88 -\endisatagproof
19.89 -{\isafoldproof}%
19.90 -%
19.91 -\isadelimproof
19.92 -%
19.93 -\endisadelimproof
19.94 -%
19.95 -\isadelimproof
19.96 -%
19.97 -\endisadelimproof
19.98 -%
19.99 -\isatagproof
19.100 -%
19.101 -\endisatagproof
19.102 -{\isafoldproof}%
19.103 -%
19.104 -\isadelimproof
19.105 -%
19.106 -\endisadelimproof
19.107 -%
19.108 -\isadelimproof
19.109 -%
19.110 -\endisadelimproof
19.111 -%
19.112 -\isatagproof
19.113 -%
19.114 -\endisatagproof
19.115 -{\isafoldproof}%
19.116 -%
19.117 -\isadelimproof
19.118 -%
19.119 -\endisadelimproof
19.120 -%
19.121 -\isadelimproof
19.122 -%
19.123 -\endisadelimproof
19.124 -%
19.125 -\isatagproof
19.126 -%
19.127 -\endisatagproof
19.128 -{\isafoldproof}%
19.129 -%
19.130 -\isadelimproof
19.131 -%
19.132 -\endisadelimproof
19.133 -%
19.134 -\isadelimproof
19.135 -%
19.136 -\endisadelimproof
19.137 -%
19.138 -\isatagproof
19.139 -%
19.140 -\endisatagproof
19.141 -{\isafoldproof}%
19.142 -%
19.143 -\isadelimproof
19.144 -%
19.145 -\endisadelimproof
19.146 -%
19.147 -\isadelimproof
19.148 -%
19.149 -\endisadelimproof
19.150 -%
19.151 -\isatagproof
19.152 -%
19.153 -\endisatagproof
19.154 -{\isafoldproof}%
19.155 -%
19.156 -\isadelimproof
19.157 -%
19.158 -\endisadelimproof
19.159 -%
19.160 -\isadelimproof
19.161 -%
19.162 -\endisadelimproof
19.163 -%
19.164 -\isatagproof
19.165 -%
19.166 -\endisatagproof
19.167 -{\isafoldproof}%
19.168 -%
19.169 -\isadelimproof
19.170 -%
19.171 -\endisadelimproof
19.172 -%
19.173 -\isadelimproof
19.174 -%
19.175 -\endisadelimproof
19.176 -%
19.177 -\isatagproof
19.178 -%
19.179 -\endisatagproof
19.180 -{\isafoldproof}%
19.181 -%
19.182 -\isadelimproof
19.183 -\isanewline
19.184 -%
19.185 -\endisadelimproof
19.186 -%
19.187 -\isadelimtheory
19.188 -%
19.189 -\endisadelimtheory
19.190 -%
19.191 -\isatagtheory
19.192 -\isacommand{end}\isamarkupfalse%
19.193 -%
19.194 -\endisatagtheory
19.195 -{\isafoldtheory}%
19.196 -%
19.197 -\isadelimtheory
19.198 -%
19.199 -\endisadelimtheory
19.200 -\end{isabellebody}%
19.201 -%%% Local Variables:
19.202 -%%% mode: latex
19.203 -%%% TeX-master: "root"
19.204 -%%% End:
20.1 --- a/doc-src/AxClass/axclass.tex Wed Mar 04 11:05:02 2009 +0100
20.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
20.3 @@ -1,80 +0,0 @@
20.4 -
20.5 -\documentclass[12pt,a4paper,fleqn]{report}
20.6 -\usepackage{graphicx,../iman,../extra,../isar}
20.7 -\usepackage{../isabelle,../isabellesym}
20.8 -\usepackage{../pdfsetup} % last one!
20.9 -
20.10 -\isabellestyle{it}
20.11 -\newcommand{\isasyminv}{\isamath{{}^{-1}}}
20.12 -\renewcommand{\isasymzero}{\isamath{0}}
20.13 -\renewcommand{\isasymone}{\isamath{1}}
20.14 -
20.15 -\newcommand{\secref}[1]{\S\ref{#1}}
20.16 -\newcommand{\figref}[1]{figure~\ref{#1}}
20.17 -
20.18 -\hyphenation{Isabelle}
20.19 -\hyphenation{Isar}
20.20 -\hyphenation{Haskell}
20.21 -
20.22 -\title{\includegraphics[scale=0.5]{isabelle_isar}
20.23 - \\[4ex] Using Axiomatic Type Classes in Isabelle}
20.24 -\author{\emph{Markus Wenzel} \\ TU M\"unchen}
20.25 -
20.26 -
20.27 -\setcounter{secnumdepth}{2} \setcounter{tocdepth}{2}
20.28 -
20.29 -\pagestyle{headings}
20.30 -\sloppy
20.31 -\binperiod %%%treat . like a binary operator
20.32 -
20.33 -
20.34 -\begin{document}
20.35 -
20.36 -\underscoreoff
20.37 -
20.38 -\maketitle
20.39 -
20.40 -\begin{abstract}
20.41 - Isabelle offers order-sorted type classes on top of the simple types of
20.42 - plain Higher-Order Logic. The resulting type system is similar to that of
20.43 - the programming language Haskell. Its interpretation within the logic
20.44 - enables further application, though, apart from restricting polymorphism
20.45 - syntactically. In particular, the concept of \emph{Axiomatic Type Classes}
20.46 - provides a useful light-weight mechanism for hierarchically-structured
20.47 - abstract theories. Subsequently, we demonstrate typical uses of Isabelle's
20.48 - axiomatic type classes to model basic algebraic structures.
20.49 -
20.50 - This document describes axiomatic type classes using Isabelle/Isar theories,
20.51 - with proofs expressed via Isar proof language elements. The new theory
20.52 - format greatly simplifies the arrangement of the overall development, since
20.53 - definitions and proofs may be freely intermixed. Users who prefer tactic
20.54 - scripts over structured proofs do not need to fall back on separate ML
20.55 - scripts, though, but may refer to Isar's tactic emulation commands.
20.56 -\end{abstract}
20.57 -
20.58 -
20.59 -\pagenumbering{roman} \tableofcontents \clearfirst
20.60 -
20.61 -\include{body}
20.62 -
20.63 -%FIXME
20.64 -\nocite{nipkow-types93}
20.65 -\nocite{nipkow-sorts93}
20.66 -\nocite{Wenzel:1997:TPHOL}
20.67 -\nocite{paulson-isa-book}
20.68 -\nocite{isabelle-isar-ref}
20.69 -\nocite{Wenzel:1999:TPHOL}
20.70 -
20.71 -\begingroup
20.72 - \bibliographystyle{plain} \small\raggedright\frenchspacing
20.73 - \bibliography{../manual}
20.74 -\endgroup
20.75 -
20.76 -\end{document}
20.77 -
20.78 -
20.79 -%%% Local Variables:
20.80 -%%% mode: latex
20.81 -%%% TeX-master: t
20.82 -%%% End:
20.83 -% LocalWords: Isabelle FIXME
21.1 --- a/doc-src/AxClass/body.tex Wed Mar 04 11:05:02 2009 +0100
21.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
21.3 @@ -1,166 +0,0 @@
21.4 -
21.5 -\chapter{Introduction}
21.6 -
21.7 -A Haskell-style type-system \cite{haskell-report} with ordered type-classes
21.8 -has been present in Isabelle since 1991 already \cite{nipkow-sorts93}.
21.9 -Initially, classes have mainly served as a \emph{purely syntactic} tool to
21.10 -formulate polymorphic object-logics in a clean way, such as the standard
21.11 -Isabelle formulation of many-sorted FOL \cite{paulson-isa-book}.
21.12 -
21.13 -Applying classes at the \emph{logical level} to provide a simple notion of
21.14 -abstract theories and instantiations to concrete ones, has been long proposed
21.15 -as well \cite{nipkow-types93,nipkow-sorts93}. At that time, Isabelle still
21.16 -lacked built-in support for these \emph{axiomatic type classes}. More
21.17 -importantly, their semantics was not yet fully fleshed out (and unnecessarily
21.18 -complicated, too).
21.19 -
21.20 -Since Isabelle94, actual axiomatic type classes have been an integral part of
21.21 -Isabelle's meta-logic. This very simple implementation is based on a
21.22 -straight-forward extension of traditional simply-typed Higher-Order Logic, by
21.23 -including types qualified by logical predicates and overloaded constant
21.24 -definitions (see \cite{Wenzel:1997:TPHOL} for further details).
21.25 -
21.26 -Yet even until Isabelle99, there used to be still a fundamental methodological
21.27 -problem in using axiomatic type classes conveniently, due to the traditional
21.28 -distinction of Isabelle theory files vs.\ ML proof scripts. This has been
21.29 -finally overcome with the advent of Isabelle/Isar theories
21.30 -\cite{isabelle-isar-ref}: now definitions and proofs may be freely intermixed.
21.31 -This nicely accommodates the usual procedure of defining axiomatic type
21.32 -classes, proving abstract properties, defining operations on concrete types,
21.33 -proving concrete properties for instantiation of classes etc.
21.34 -
21.35 -\medskip
21.36 -
21.37 -So to cut a long story short, the present version of axiomatic type classes
21.38 -now provides an even more useful and convenient mechanism for light-weight
21.39 -abstract theories, without any special technical provisions to be observed by
21.40 -the user.
21.41 -
21.42 -
21.43 -\chapter{Examples}\label{sec:ex}
21.44 -
21.45 -Axiomatic type classes are a concept of Isabelle's meta-logic
21.46 -\cite{paulson-isa-book,Wenzel:1997:TPHOL}. They may be applied to any
21.47 -object-logic that directly uses the meta type system, such as Isabelle/HOL
21.48 -\cite{isabelle-HOL}. Subsequently, we present various examples that are all
21.49 -formulated within HOL, except the one of \secref{sec:ex-natclass} which is in
21.50 -FOL. See also \url{http://isabelle.in.tum.de/library/HOL/AxClasses/} and
21.51 -\url{http://isabelle.in.tum.de/library/FOL/ex/NatClass.html}.
21.52 -
21.53 -\input{Group/document/Semigroups}
21.54 -
21.55 -\input{Group/document/Group}
21.56 -
21.57 -\input{Group/document/Product}
21.58 -
21.59 -\input{Nat/document/NatClass}
21.60 -
21.61 -
21.62 -%% FIXME move some parts to ref or isar-ref manual (!?);
21.63 -
21.64 -% \chapter{The user interface of Isabelle's axclass package}
21.65 -
21.66 -% The actual axiomatic type class package of Isabelle/Pure mainly consists
21.67 -% of two new theory sections: \texttt{axclass} and \texttt{instance}. Some
21.68 -% typical applications of these have already been demonstrated in
21.69 -% \secref{sec:ex}, below their syntax and semantics are presented more
21.70 -% completely.
21.71 -
21.72 -
21.73 -% \section{The axclass section}
21.74 -
21.75 -% Within theory files, \texttt{axclass} introduces an axiomatic type class
21.76 -% definition. Its concrete syntax is:
21.77 -
21.78 -% \begin{matharray}{l}
21.79 -% \texttt{axclass} \\
21.80 -% \ \ c \texttt{ < } c@1\texttt, \ldots\texttt, c@n \\
21.81 -% \ \ id@1\ axm@1 \\
21.82 -% \ \ \vdots \\
21.83 -% \ \ id@m\ axm@m
21.84 -% \emphnd{matharray}
21.85 -
21.86 -% Where $c, c@1, \ldots, c@n$ are classes (category $id$ or
21.87 -% $string$) and $axm@1, \ldots, axm@m$ (with $m \geq
21.88 -% 0$) are formulas (category $string$).
21.89 -
21.90 -% Class $c$ has to be new, and sort $\{c@1, \ldots, c@n\}$ a subsort of
21.91 -% \texttt{logic}. Each class axiom $axm@j$ may contain any term
21.92 -% variables, but at most one type variable (which need not be the same
21.93 -% for all axioms). The sort of this type variable has to be a supersort
21.94 -% of $\{c@1, \ldots, c@n\}$.
21.95 -
21.96 -% \medskip
21.97 -
21.98 -% The \texttt{axclass} section declares $c$ as subclass of $c@1, \ldots,
21.99 -% c@n$ to the type signature.
21.100 -
21.101 -% Furthermore, $axm@1, \ldots, axm@m$ are turned into the
21.102 -% ``abstract axioms'' of $c$ with names $id@1, \ldots,
21.103 -% id@m$. This is done by replacing all occurring type variables
21.104 -% by $\alpha :: c$. Original axioms that do not contain any type
21.105 -% variable will be prefixed by the logical precondition
21.106 -% $\texttt{OFCLASS}(\alpha :: \texttt{logic}, c\texttt{_class})$.
21.107 -
21.108 -% Another axiom of name $c\texttt{I}$ --- the ``class $c$ introduction
21.109 -% rule'' --- is built from the respective universal closures of
21.110 -% $axm@1, \ldots, axm@m$ appropriately.
21.111 -
21.112 -
21.113 -% \section{The instance section}
21.114 -
21.115 -% Section \texttt{instance} proves class inclusions or type arities at the
21.116 -% logical level and then transfers these into the type signature.
21.117 -
21.118 -% Its concrete syntax is:
21.119 -
21.120 -% \begin{matharray}{l}
21.121 -% \texttt{instance} \\
21.122 -% \ \ [\ c@1 \texttt{ < } c@2 \ |\
21.123 -% t \texttt{ ::\ (}sort@1\texttt, \ldots \texttt, sort@n\texttt) sort\ ] \\
21.124 -% \ \ [\ \texttt(name@1 \texttt, \ldots\texttt, name@m\texttt)\ ] \\
21.125 -% \ \ [\ \texttt{\{|} text \texttt{|\}}\ ]
21.126 -% \emphnd{matharray}
21.127 -
21.128 -% Where $c@1, c@2$ are classes and $t$ is an $n$-place type constructor
21.129 -% (all of category $id$ or $string)$. Furthermore,
21.130 -% $sort@i$ are sorts in the usual Isabelle-syntax.
21.131 -
21.132 -% \medskip
21.133 -
21.134 -% Internally, \texttt{instance} first sets up an appropriate goal that
21.135 -% expresses the class inclusion or type arity as a meta-proposition.
21.136 -% Then tactic \texttt{AxClass.axclass_tac} is applied with all preceding
21.137 -% meta-definitions of the current theory file and the user-supplied
21.138 -% witnesses. The latter are $name@1, \ldots, name@m$, where
21.139 -% $id$ refers to an \ML-name of a theorem, and $string$ to an
21.140 -% axiom of the current theory node\footnote{Thus, the user may reference
21.141 -% axioms from above this \texttt{instance} in the theory file. Note
21.142 -% that new axioms appear at the \ML-toplevel only after the file is
21.143 -% processed completely.}.
21.144 -
21.145 -% Tactic \texttt{AxClass.axclass_tac} first unfolds the class definition by
21.146 -% resolving with rule $c\texttt\texttt{I}$, and then applies the witnesses
21.147 -% according to their form: Meta-definitions are unfolded, all other
21.148 -% formulas are repeatedly resolved\footnote{This is done in a way that
21.149 -% enables proper object-\emph{rules} to be used as witnesses for
21.150 -% corresponding class axioms.} with.
21.151 -
21.152 -% The final optional argument $text$ is \ML-code of an arbitrary
21.153 -% user tactic which is applied last to any remaining goals.
21.154 -
21.155 -% \medskip
21.156 -
21.157 -% Because of the complexity of \texttt{instance}'s witnessing mechanisms,
21.158 -% new users of the axclass package are advised to only use the simple
21.159 -% form $\texttt{instance}\ \ldots\ (id@1, \ldots, id@!m)$, where
21.160 -% the identifiers refer to theorems that are appropriate type instances
21.161 -% of the class axioms. This typically requires an auxiliary theory,
21.162 -% though, which defines some constants and then proves these witnesses.
21.163 -
21.164 -
21.165 -%%% Local Variables:
21.166 -%%% mode: latex
21.167 -%%% TeX-master: "axclass"
21.168 -%%% End:
21.169 -% LocalWords: Isabelle FOL
22.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
22.2 +++ b/doc-src/Classes/IsaMakefile Wed Mar 04 11:05:29 2009 +0100
22.3 @@ -0,0 +1,33 @@
22.4 +
22.5 +## targets
22.6 +
22.7 +default: Thy
22.8 +images:
22.9 +test: Thy
22.10 +
22.11 +all: images test
22.12 +
22.13 +
22.14 +## global settings
22.15 +
22.16 +SRC = $(ISABELLE_HOME)/src
22.17 +OUT = $(ISABELLE_OUTPUT)
22.18 +LOG = $(OUT)/log
22.19 +
22.20 +USEDIR = $(ISABELLE_TOOL) usedir -v true -i false -d false -C false -D document
22.21 +
22.22 +
22.23 +## Thy
22.24 +
22.25 +THY = $(LOG)/HOL-Thy.gz
22.26 +
22.27 +Thy: $(THY)
22.28 +
22.29 +$(THY): Thy/ROOT.ML Thy/Setup.thy Thy/Classes.thy ../antiquote_setup.ML ../more_antiquote.ML
22.30 + @$(USEDIR) HOL Thy
22.31 +
22.32 +
22.33 +## clean
22.34 +
22.35 +clean:
22.36 + @rm -f $(THY)
23.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
23.2 +++ b/doc-src/Classes/Makefile Wed Mar 04 11:05:29 2009 +0100
23.3 @@ -0,0 +1,35 @@
23.4 +
23.5 +## targets
23.6 +
23.7 +default: dvi
23.8 +
23.9 +
23.10 +## dependencies
23.11 +
23.12 +include ../Makefile.in
23.13 +
23.14 +NAME = classes
23.15 +
23.16 +FILES = $(NAME).tex classes.tex Thy/document/Classes.tex \
23.17 + style.sty ../iman.sty ../extra.sty ../isar.sty \
23.18 + ../isabelle.sty ../isabellesym.sty ../pdfsetup.sty \
23.19 + ../manual.bib ../proof.sty
23.20 +
23.21 +dvi: $(NAME).dvi
23.22 +
23.23 +$(NAME).dvi: $(FILES) isabelle_isar.eps
23.24 + $(LATEX) $(NAME)
23.25 + $(BIBTEX) $(NAME)
23.26 + $(LATEX) $(NAME)
23.27 + $(LATEX) $(NAME)
23.28 +
23.29 +pdf: $(NAME).pdf
23.30 +
23.31 +$(NAME).pdf: $(FILES) isabelle_isar.pdf
23.32 + $(PDFLATEX) $(NAME)
23.33 + $(BIBTEX) $(NAME)
23.34 + $(PDFLATEX) $(NAME)
23.35 + $(PDFLATEX) $(NAME)
23.36 + $(FIXBOOKMARKS) $(NAME).out
23.37 + $(PDFLATEX) $(NAME)
23.38 + $(PDFLATEX) $(NAME)
24.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
24.2 +++ b/doc-src/Classes/Thy/Classes.thy Wed Mar 04 11:05:29 2009 +0100
24.3 @@ -0,0 +1,634 @@
24.4 +theory Classes
24.5 +imports Main Setup
24.6 +begin
24.7 +
24.8 +section {* Introduction *}
24.9 +
24.10 +text {*
24.11 + Type classes were introduces by Wadler and Blott \cite{wadler89how}
24.12 + into the Haskell language, to allow for a reasonable implementation
24.13 + of overloading\footnote{throughout this tutorial, we are referring
24.14 + to classical Haskell 1.0 type classes, not considering
24.15 + later additions in expressiveness}.
24.16 + As a canonical example, a polymorphic equality function
24.17 + @{text "eq \<Colon> \<alpha> \<Rightarrow> \<alpha> \<Rightarrow> bool"} which is overloaded on different
24.18 + types for @{text "\<alpha>"}, which is achieved by splitting introduction
24.19 + of the @{text eq} function from its overloaded definitions by means
24.20 + of @{text class} and @{text instance} declarations:
24.21 + \footnote{syntax here is a kind of isabellized Haskell}
24.22 +
24.23 + \begin{quote}
24.24 +
24.25 + \noindent@{text "class eq where"} \\
24.26 + \hspace*{2ex}@{text "eq \<Colon> \<alpha> \<Rightarrow> \<alpha> \<Rightarrow> bool"}
24.27 +
24.28 + \medskip\noindent@{text "instance nat \<Colon> eq where"} \\
24.29 + \hspace*{2ex}@{text "eq 0 0 = True"} \\
24.30 + \hspace*{2ex}@{text "eq 0 _ = False"} \\
24.31 + \hspace*{2ex}@{text "eq _ 0 = False"} \\
24.32 + \hspace*{2ex}@{text "eq (Suc n) (Suc m) = eq n m"}
24.33 +
24.34 + \medskip\noindent@{text "instance (\<alpha>\<Colon>eq, \<beta>\<Colon>eq) pair \<Colon> eq where"} \\
24.35 + \hspace*{2ex}@{text "eq (x1, y1) (x2, y2) = eq x1 x2 \<and> eq y1 y2"}
24.36 +
24.37 + \medskip\noindent@{text "class ord extends eq where"} \\
24.38 + \hspace*{2ex}@{text "less_eq \<Colon> \<alpha> \<Rightarrow> \<alpha> \<Rightarrow> bool"} \\
24.39 + \hspace*{2ex}@{text "less \<Colon> \<alpha> \<Rightarrow> \<alpha> \<Rightarrow> bool"}
24.40 +
24.41 + \end{quote}
24.42 +
24.43 + \noindent Type variables are annotated with (finitely many) classes;
24.44 + these annotations are assertions that a particular polymorphic type
24.45 + provides definitions for overloaded functions.
24.46 +
24.47 + Indeed, type classes not only allow for simple overloading
24.48 + but form a generic calculus, an instance of order-sorted
24.49 + algebra \cite{Nipkow-Prehofer:1993,nipkow-sorts93,Wenzel:1997:TPHOL}.
24.50 +
24.51 + From a software engeneering point of view, type classes
24.52 + roughly correspond to interfaces in object-oriented languages like Java;
24.53 + so, it is naturally desirable that type classes do not only
24.54 + provide functions (class parameters) but also state specifications
24.55 + implementations must obey. For example, the @{text "class eq"}
24.56 + above could be given the following specification, demanding that
24.57 + @{text "class eq"} is an equivalence relation obeying reflexivity,
24.58 + symmetry and transitivity:
24.59 +
24.60 + \begin{quote}
24.61 +
24.62 + \noindent@{text "class eq where"} \\
24.63 + \hspace*{2ex}@{text "eq \<Colon> \<alpha> \<Rightarrow> \<alpha> \<Rightarrow> bool"} \\
24.64 + @{text "satisfying"} \\
24.65 + \hspace*{2ex}@{text "refl: eq x x"} \\
24.66 + \hspace*{2ex}@{text "sym: eq x y \<longleftrightarrow> eq x y"} \\
24.67 + \hspace*{2ex}@{text "trans: eq x y \<and> eq y z \<longrightarrow> eq x z"}
24.68 +
24.69 + \end{quote}
24.70 +
24.71 + \noindent From a theoretic point of view, type classes are lightweight
24.72 + modules; Haskell type classes may be emulated by
24.73 + SML functors \cite{classes_modules}.
24.74 + Isabelle/Isar offers a discipline of type classes which brings
24.75 + all those aspects together:
24.76 +
24.77 + \begin{enumerate}
24.78 + \item specifying abstract parameters together with
24.79 + corresponding specifications,
24.80 + \item instantiating those abstract parameters by a particular
24.81 + type
24.82 + \item in connection with a ``less ad-hoc'' approach to overloading,
24.83 + \item with a direct link to the Isabelle module system
24.84 + (aka locales \cite{kammueller-locales}).
24.85 + \end{enumerate}
24.86 +
24.87 + \noindent Isar type classes also directly support code generation
24.88 + in a Haskell like fashion.
24.89 +
24.90 + This tutorial demonstrates common elements of structured specifications
24.91 + and abstract reasoning with type classes by the algebraic hierarchy of
24.92 + semigroups, monoids and groups. Our background theory is that of
24.93 + Isabelle/HOL \cite{isa-tutorial}, for which some
24.94 + familiarity is assumed.
24.95 +
24.96 + Here we merely present the look-and-feel for end users.
24.97 + Internally, those are mapped to more primitive Isabelle concepts.
24.98 + See \cite{Haftmann-Wenzel:2006:classes} for more detail.
24.99 +*}
24.100 +
24.101 +section {* A simple algebra example \label{sec:example} *}
24.102 +
24.103 +subsection {* Class definition *}
24.104 +
24.105 +text {*
24.106 + Depending on an arbitrary type @{text "\<alpha>"}, class @{text
24.107 + "semigroup"} introduces a binary operator @{text "(\<otimes>)"} that is
24.108 + assumed to be associative:
24.109 +*}
24.110 +
24.111 +class %quote semigroup =
24.112 + fixes mult :: "\<alpha> \<Rightarrow> \<alpha> \<Rightarrow> \<alpha>" (infixl "\<otimes>" 70)
24.113 + assumes assoc: "(x \<otimes> y) \<otimes> z = x \<otimes> (y \<otimes> z)"
24.114 +
24.115 +text {*
24.116 + \noindent This @{command class} specification consists of two
24.117 + parts: the \qn{operational} part names the class parameter
24.118 + (@{element "fixes"}), the \qn{logical} part specifies properties on them
24.119 + (@{element "assumes"}). The local @{element "fixes"} and
24.120 + @{element "assumes"} are lifted to the theory toplevel,
24.121 + yielding the global
24.122 + parameter @{term [source] "mult \<Colon> \<alpha>\<Colon>semigroup \<Rightarrow> \<alpha> \<Rightarrow> \<alpha>"} and the
24.123 + global theorem @{fact "semigroup.assoc:"}~@{prop [source] "\<And>x y
24.124 + z \<Colon> \<alpha>\<Colon>semigroup. (x \<otimes> y) \<otimes> z = x \<otimes> (y \<otimes> z)"}.
24.125 +*}
24.126 +
24.127 +
24.128 +subsection {* Class instantiation \label{sec:class_inst} *}
24.129 +
24.130 +text {*
24.131 + The concrete type @{typ int} is made a @{class semigroup}
24.132 + instance by providing a suitable definition for the class parameter
24.133 + @{text "(\<otimes>)"} and a proof for the specification of @{fact assoc}.
24.134 + This is accomplished by the @{command instantiation} target:
24.135 +*}
24.136 +
24.137 +instantiation %quote int :: semigroup
24.138 +begin
24.139 +
24.140 +definition %quote
24.141 + mult_int_def: "i \<otimes> j = i + (j\<Colon>int)"
24.142 +
24.143 +instance %quote proof
24.144 + fix i j k :: int have "(i + j) + k = i + (j + k)" by simp
24.145 + then show "(i \<otimes> j) \<otimes> k = i \<otimes> (j \<otimes> k)"
24.146 + unfolding mult_int_def .
24.147 +qed
24.148 +
24.149 +end %quote
24.150 +
24.151 +text {*
24.152 + \noindent @{command instantiation} allows to define class parameters
24.153 + at a particular instance using common specification tools (here,
24.154 + @{command definition}). The concluding @{command instance}
24.155 + opens a proof that the given parameters actually conform
24.156 + to the class specification. Note that the first proof step
24.157 + is the @{method default} method,
24.158 + which for such instance proofs maps to the @{method intro_classes} method.
24.159 + This boils down an instance judgement to the relevant primitive
24.160 + proof goals and should conveniently always be the first method applied
24.161 + in an instantiation proof.
24.162 +
24.163 + From now on, the type-checker will consider @{typ int}
24.164 + as a @{class semigroup} automatically, i.e.\ any general results
24.165 + are immediately available on concrete instances.
24.166 +
24.167 + \medskip Another instance of @{class semigroup} are the natural numbers:
24.168 +*}
24.169 +
24.170 +instantiation %quote nat :: semigroup
24.171 +begin
24.172 +
24.173 +primrec %quote mult_nat where
24.174 + "(0\<Colon>nat) \<otimes> n = n"
24.175 + | "Suc m \<otimes> n = Suc (m \<otimes> n)"
24.176 +
24.177 +instance %quote proof
24.178 + fix m n q :: nat
24.179 + show "m \<otimes> n \<otimes> q = m \<otimes> (n \<otimes> q)"
24.180 + by (induct m) auto
24.181 +qed
24.182 +
24.183 +end %quote
24.184 +
24.185 +text {*
24.186 + \noindent Note the occurence of the name @{text mult_nat}
24.187 + in the primrec declaration; by default, the local name of
24.188 + a class operation @{text f} to instantiate on type constructor
24.189 + @{text \<kappa>} are mangled as @{text f_\<kappa>}. In case of uncertainty,
24.190 + these names may be inspected using the @{command "print_context"} command
24.191 + or the corresponding ProofGeneral button.
24.192 +*}
24.193 +
24.194 +subsection {* Lifting and parametric types *}
24.195 +
24.196 +text {*
24.197 + Overloaded definitions giving on class instantiation
24.198 + may include recursion over the syntactic structure of types.
24.199 + As a canonical example, we model product semigroups
24.200 + using our simple algebra:
24.201 +*}
24.202 +
24.203 +instantiation %quote * :: (semigroup, semigroup) semigroup
24.204 +begin
24.205 +
24.206 +definition %quote
24.207 + mult_prod_def: "p\<^isub>1 \<otimes> p\<^isub>2 = (fst p\<^isub>1 \<otimes> fst p\<^isub>2, snd p\<^isub>1 \<otimes> snd p\<^isub>2)"
24.208 +
24.209 +instance %quote proof
24.210 + fix p\<^isub>1 p\<^isub>2 p\<^isub>3 :: "\<alpha>\<Colon>semigroup \<times> \<beta>\<Colon>semigroup"
24.211 + show "p\<^isub>1 \<otimes> p\<^isub>2 \<otimes> p\<^isub>3 = p\<^isub>1 \<otimes> (p\<^isub>2 \<otimes> p\<^isub>3)"
24.212 + unfolding mult_prod_def by (simp add: assoc)
24.213 +qed
24.214 +
24.215 +end %quote
24.216 +
24.217 +text {*
24.218 + \noindent Associativity from product semigroups is
24.219 + established using
24.220 + the definition of @{text "(\<otimes>)"} on products and the hypothetical
24.221 + associativity of the type components; these hypotheses
24.222 + are facts due to the @{class semigroup} constraints imposed
24.223 + on the type components by the @{command instance} proposition.
24.224 + Indeed, this pattern often occurs with parametric types
24.225 + and type classes.
24.226 +*}
24.227 +
24.228 +
24.229 +subsection {* Subclassing *}
24.230 +
24.231 +text {*
24.232 + We define a subclass @{text monoidl} (a semigroup with a left-hand neutral)
24.233 + by extending @{class semigroup}
24.234 + with one additional parameter @{text neutral} together
24.235 + with its property:
24.236 +*}
24.237 +
24.238 +class %quote monoidl = semigroup +
24.239 + fixes neutral :: "\<alpha>" ("\<one>")
24.240 + assumes neutl: "\<one> \<otimes> x = x"
24.241 +
24.242 +text {*
24.243 + \noindent Again, we prove some instances, by
24.244 + providing suitable parameter definitions and proofs for the
24.245 + additional specifications. Observe that instantiations
24.246 + for types with the same arity may be simultaneous:
24.247 +*}
24.248 +
24.249 +instantiation %quote nat and int :: monoidl
24.250 +begin
24.251 +
24.252 +definition %quote
24.253 + neutral_nat_def: "\<one> = (0\<Colon>nat)"
24.254 +
24.255 +definition %quote
24.256 + neutral_int_def: "\<one> = (0\<Colon>int)"
24.257 +
24.258 +instance %quote proof
24.259 + fix n :: nat
24.260 + show "\<one> \<otimes> n = n"
24.261 + unfolding neutral_nat_def by simp
24.262 +next
24.263 + fix k :: int
24.264 + show "\<one> \<otimes> k = k"
24.265 + unfolding neutral_int_def mult_int_def by simp
24.266 +qed
24.267 +
24.268 +end %quote
24.269 +
24.270 +instantiation %quote * :: (monoidl, monoidl) monoidl
24.271 +begin
24.272 +
24.273 +definition %quote
24.274 + neutral_prod_def: "\<one> = (\<one>, \<one>)"
24.275 +
24.276 +instance %quote proof
24.277 + fix p :: "\<alpha>\<Colon>monoidl \<times> \<beta>\<Colon>monoidl"
24.278 + show "\<one> \<otimes> p = p"
24.279 + unfolding neutral_prod_def mult_prod_def by (simp add: neutl)
24.280 +qed
24.281 +
24.282 +end %quote
24.283 +
24.284 +text {*
24.285 + \noindent Fully-fledged monoids are modelled by another subclass
24.286 + which does not add new parameters but tightens the specification:
24.287 +*}
24.288 +
24.289 +class %quote monoid = monoidl +
24.290 + assumes neutr: "x \<otimes> \<one> = x"
24.291 +
24.292 +instantiation %quote nat and int :: monoid
24.293 +begin
24.294 +
24.295 +instance %quote proof
24.296 + fix n :: nat
24.297 + show "n \<otimes> \<one> = n"
24.298 + unfolding neutral_nat_def by (induct n) simp_all
24.299 +next
24.300 + fix k :: int
24.301 + show "k \<otimes> \<one> = k"
24.302 + unfolding neutral_int_def mult_int_def by simp
24.303 +qed
24.304 +
24.305 +end %quote
24.306 +
24.307 +instantiation %quote * :: (monoid, monoid) monoid
24.308 +begin
24.309 +
24.310 +instance %quote proof
24.311 + fix p :: "\<alpha>\<Colon>monoid \<times> \<beta>\<Colon>monoid"
24.312 + show "p \<otimes> \<one> = p"
24.313 + unfolding neutral_prod_def mult_prod_def by (simp add: neutr)
24.314 +qed
24.315 +
24.316 +end %quote
24.317 +
24.318 +text {*
24.319 + \noindent To finish our small algebra example, we add a @{text group} class
24.320 + with a corresponding instance:
24.321 +*}
24.322 +
24.323 +class %quote group = monoidl +
24.324 + fixes inverse :: "\<alpha> \<Rightarrow> \<alpha>" ("(_\<div>)" [1000] 999)
24.325 + assumes invl: "x\<div> \<otimes> x = \<one>"
24.326 +
24.327 +instantiation %quote int :: group
24.328 +begin
24.329 +
24.330 +definition %quote
24.331 + inverse_int_def: "i\<div> = - (i\<Colon>int)"
24.332 +
24.333 +instance %quote proof
24.334 + fix i :: int
24.335 + have "-i + i = 0" by simp
24.336 + then show "i\<div> \<otimes> i = \<one>"
24.337 + unfolding mult_int_def neutral_int_def inverse_int_def .
24.338 +qed
24.339 +
24.340 +end %quote
24.341 +
24.342 +
24.343 +section {* Type classes as locales *}
24.344 +
24.345 +subsection {* A look behind the scene *}
24.346 +
24.347 +text {*
24.348 + The example above gives an impression how Isar type classes work
24.349 + in practice. As stated in the introduction, classes also provide
24.350 + a link to Isar's locale system. Indeed, the logical core of a class
24.351 + is nothing else than a locale:
24.352 +*}
24.353 +
24.354 +class %quote idem =
24.355 + fixes f :: "\<alpha> \<Rightarrow> \<alpha>"
24.356 + assumes idem: "f (f x) = f x"
24.357 +
24.358 +text {*
24.359 + \noindent essentially introduces the locale
24.360 +*} (*<*)setup %invisible {* Sign.add_path "foo" *}
24.361 +(*>*)
24.362 +locale %quote idem =
24.363 + fixes f :: "\<alpha> \<Rightarrow> \<alpha>"
24.364 + assumes idem: "f (f x) = f x"
24.365 +
24.366 +text {* \noindent together with corresponding constant(s): *}
24.367 +
24.368 +consts %quote f :: "\<alpha> \<Rightarrow> \<alpha>"
24.369 +
24.370 +text {*
24.371 + \noindent The connection to the type system is done by means
24.372 + of a primitive axclass
24.373 +*} (*<*)setup %invisible {* Sign.add_path "foo" *}
24.374 +(*>*)
24.375 +axclass %quote idem < type
24.376 + idem: "f (f x) = f x" (*<*)setup %invisible {* Sign.parent_path *}(*>*)
24.377 +
24.378 +text {* \noindent together with a corresponding interpretation: *}
24.379 +
24.380 +interpretation %quote idem_class:
24.381 + idem "f \<Colon> (\<alpha>\<Colon>idem) \<Rightarrow> \<alpha>"
24.382 +proof qed (rule idem)
24.383 +
24.384 +text {*
24.385 + \noindent This gives you at hand the full power of the Isabelle module system;
24.386 + conclusions in locale @{text idem} are implicitly propagated
24.387 + to class @{text idem}.
24.388 +*} (*<*)setup %invisible {* Sign.parent_path *}
24.389 +(*>*)
24.390 +subsection {* Abstract reasoning *}
24.391 +
24.392 +text {*
24.393 + Isabelle locales enable reasoning at a general level, while results
24.394 + are implicitly transferred to all instances. For example, we can
24.395 + now establish the @{text "left_cancel"} lemma for groups, which
24.396 + states that the function @{text "(x \<otimes>)"} is injective:
24.397 +*}
24.398 +
24.399 +lemma %quote (in group) left_cancel: "x \<otimes> y = x \<otimes> z \<longleftrightarrow> y = z"
24.400 +proof
24.401 + assume "x \<otimes> y = x \<otimes> z"
24.402 + then have "x\<div> \<otimes> (x \<otimes> y) = x\<div> \<otimes> (x \<otimes> z)" by simp
24.403 + then have "(x\<div> \<otimes> x) \<otimes> y = (x\<div> \<otimes> x) \<otimes> z" using assoc by simp
24.404 + then show "y = z" using neutl and invl by simp
24.405 +next
24.406 + assume "y = z"
24.407 + then show "x \<otimes> y = x \<otimes> z" by simp
24.408 +qed
24.409 +
24.410 +text {*
24.411 + \noindent Here the \qt{@{keyword "in"} @{class group}} target specification
24.412 + indicates that the result is recorded within that context for later
24.413 + use. This local theorem is also lifted to the global one @{fact
24.414 + "group.left_cancel:"} @{prop [source] "\<And>x y z \<Colon> \<alpha>\<Colon>group. x \<otimes> y = x \<otimes>
24.415 + z \<longleftrightarrow> y = z"}. Since type @{text "int"} has been made an instance of
24.416 + @{text "group"} before, we may refer to that fact as well: @{prop
24.417 + [source] "\<And>x y z \<Colon> int. x \<otimes> y = x \<otimes> z \<longleftrightarrow> y = z"}.
24.418 +*}
24.419 +
24.420 +
24.421 +subsection {* Derived definitions *}
24.422 +
24.423 +text {*
24.424 + Isabelle locales support a concept of local definitions
24.425 + in locales:
24.426 +*}
24.427 +
24.428 +primrec %quote (in monoid) pow_nat :: "nat \<Rightarrow> \<alpha> \<Rightarrow> \<alpha>" where
24.429 + "pow_nat 0 x = \<one>"
24.430 + | "pow_nat (Suc n) x = x \<otimes> pow_nat n x"
24.431 +
24.432 +text {*
24.433 + \noindent If the locale @{text group} is also a class, this local
24.434 + definition is propagated onto a global definition of
24.435 + @{term [source] "pow_nat \<Colon> nat \<Rightarrow> \<alpha>\<Colon>monoid \<Rightarrow> \<alpha>\<Colon>monoid"}
24.436 + with corresponding theorems
24.437 +
24.438 + @{thm pow_nat.simps [no_vars]}.
24.439 +
24.440 + \noindent As you can see from this example, for local
24.441 + definitions you may use any specification tool
24.442 + which works together with locales (e.g. \cite{krauss2006}).
24.443 +*}
24.444 +
24.445 +
24.446 +subsection {* A functor analogy *}
24.447 +
24.448 +text {*
24.449 + We introduced Isar classes by analogy to type classes
24.450 + functional programming; if we reconsider this in the
24.451 + context of what has been said about type classes and locales,
24.452 + we can drive this analogy further by stating that type
24.453 + classes essentially correspond to functors which have
24.454 + a canonical interpretation as type classes.
24.455 + Anyway, there is also the possibility of other interpretations.
24.456 + For example, also @{text list}s form a monoid with
24.457 + @{text append} and @{term "[]"} as operations, but it
24.458 + seems inappropriate to apply to lists
24.459 + the same operations as for genuinely algebraic types.
24.460 + In such a case, we simply can do a particular interpretation
24.461 + of monoids for lists:
24.462 +*}
24.463 +
24.464 +interpretation %quote list_monoid!: monoid append "[]"
24.465 + proof qed auto
24.466 +
24.467 +text {*
24.468 + \noindent This enables us to apply facts on monoids
24.469 + to lists, e.g. @{thm list_monoid.neutl [no_vars]}.
24.470 +
24.471 + When using this interpretation pattern, it may also
24.472 + be appropriate to map derived definitions accordingly:
24.473 +*}
24.474 +
24.475 +primrec %quote replicate :: "nat \<Rightarrow> \<alpha> list \<Rightarrow> \<alpha> list" where
24.476 + "replicate 0 _ = []"
24.477 + | "replicate (Suc n) xs = xs @ replicate n xs"
24.478 +
24.479 +interpretation %quote list_monoid!: monoid append "[]" where
24.480 + "monoid.pow_nat append [] = replicate"
24.481 +proof -
24.482 + interpret monoid append "[]" ..
24.483 + show "monoid.pow_nat append [] = replicate"
24.484 + proof
24.485 + fix n
24.486 + show "monoid.pow_nat append [] n = replicate n"
24.487 + by (induct n) auto
24.488 + qed
24.489 +qed intro_locales
24.490 +
24.491 +
24.492 +subsection {* Additional subclass relations *}
24.493 +
24.494 +text {*
24.495 + Any @{text "group"} is also a @{text "monoid"}; this
24.496 + can be made explicit by claiming an additional
24.497 + subclass relation,
24.498 + together with a proof of the logical difference:
24.499 +*}
24.500 +
24.501 +subclass %quote (in group) monoid
24.502 +proof
24.503 + fix x
24.504 + from invl have "x\<div> \<otimes> x = \<one>" by simp
24.505 + with assoc [symmetric] neutl invl have "x\<div> \<otimes> (x \<otimes> \<one>) = x\<div> \<otimes> x" by simp
24.506 + with left_cancel show "x \<otimes> \<one> = x" by simp
24.507 +qed
24.508 +
24.509 +text {*
24.510 + The logical proof is carried out on the locale level.
24.511 + Afterwards it is propagated
24.512 + to the type system, making @{text group} an instance of
24.513 + @{text monoid} by adding an additional edge
24.514 + to the graph of subclass relations
24.515 + (cf.\ \figref{fig:subclass}).
24.516 +
24.517 + \begin{figure}[htbp]
24.518 + \begin{center}
24.519 + \small
24.520 + \unitlength 0.6mm
24.521 + \begin{picture}(40,60)(0,0)
24.522 + \put(20,60){\makebox(0,0){@{text semigroup}}}
24.523 + \put(20,40){\makebox(0,0){@{text monoidl}}}
24.524 + \put(00,20){\makebox(0,0){@{text monoid}}}
24.525 + \put(40,00){\makebox(0,0){@{text group}}}
24.526 + \put(20,55){\vector(0,-1){10}}
24.527 + \put(15,35){\vector(-1,-1){10}}
24.528 + \put(25,35){\vector(1,-3){10}}
24.529 + \end{picture}
24.530 + \hspace{8em}
24.531 + \begin{picture}(40,60)(0,0)
24.532 + \put(20,60){\makebox(0,0){@{text semigroup}}}
24.533 + \put(20,40){\makebox(0,0){@{text monoidl}}}
24.534 + \put(00,20){\makebox(0,0){@{text monoid}}}
24.535 + \put(40,00){\makebox(0,0){@{text group}}}
24.536 + \put(20,55){\vector(0,-1){10}}
24.537 + \put(15,35){\vector(-1,-1){10}}
24.538 + \put(05,15){\vector(3,-1){30}}
24.539 + \end{picture}
24.540 + \caption{Subclass relationship of monoids and groups:
24.541 + before and after establishing the relationship
24.542 + @{text "group \<subseteq> monoid"}; transitive edges are left out.}
24.543 + \label{fig:subclass}
24.544 + \end{center}
24.545 + \end{figure}
24.546 +
24.547 + For illustration, a derived definition
24.548 + in @{text group} which uses @{text pow_nat}:
24.549 +*}
24.550 +
24.551 +definition %quote (in group) pow_int :: "int \<Rightarrow> \<alpha> \<Rightarrow> \<alpha>" where
24.552 + "pow_int k x = (if k >= 0
24.553 + then pow_nat (nat k) x
24.554 + else (pow_nat (nat (- k)) x)\<div>)"
24.555 +
24.556 +text {*
24.557 + \noindent yields the global definition of
24.558 + @{term [source] "pow_int \<Colon> int \<Rightarrow> \<alpha>\<Colon>group \<Rightarrow> \<alpha>\<Colon>group"}
24.559 + with the corresponding theorem @{thm pow_int_def [no_vars]}.
24.560 +*}
24.561 +
24.562 +subsection {* A note on syntax *}
24.563 +
24.564 +text {*
24.565 + As a commodity, class context syntax allows to refer
24.566 + to local class operations and their global counterparts
24.567 + uniformly; type inference resolves ambiguities. For example:
24.568 +*}
24.569 +
24.570 +context %quote semigroup
24.571 +begin
24.572 +
24.573 +term %quote "x \<otimes> y" -- {* example 1 *}
24.574 +term %quote "(x\<Colon>nat) \<otimes> y" -- {* example 2 *}
24.575 +
24.576 +end %quote
24.577 +
24.578 +term %quote "x \<otimes> y" -- {* example 3 *}
24.579 +
24.580 +text {*
24.581 + \noindent Here in example 1, the term refers to the local class operation
24.582 + @{text "mult [\<alpha>]"}, whereas in example 2 the type constraint
24.583 + enforces the global class operation @{text "mult [nat]"}.
24.584 + In the global context in example 3, the reference is
24.585 + to the polymorphic global class operation @{text "mult [?\<alpha> \<Colon> semigroup]"}.
24.586 +*}
24.587 +
24.588 +section {* Further issues *}
24.589 +
24.590 +subsection {* Type classes and code generation *}
24.591 +
24.592 +text {*
24.593 + Turning back to the first motivation for type classes,
24.594 + namely overloading, it is obvious that overloading
24.595 + stemming from @{command class} statements and
24.596 + @{command instantiation}
24.597 + targets naturally maps to Haskell type classes.
24.598 + The code generator framework \cite{isabelle-codegen}
24.599 + takes this into account. Concerning target languages
24.600 + lacking type classes (e.g.~SML), type classes
24.601 + are implemented by explicit dictionary construction.
24.602 + As example, let's go back to the power function:
24.603 +*}
24.604 +
24.605 +definition %quote example :: int where
24.606 + "example = pow_int 10 (-2)"
24.607 +
24.608 +text {*
24.609 + \noindent This maps to Haskell as:
24.610 +*}
24.611 +
24.612 +text %quote {*@{code_stmts example (Haskell)}*}
24.613 +
24.614 +text {*
24.615 + \noindent The whole code in SML with explicit dictionary passing:
24.616 +*}
24.617 +
24.618 +text %quote {*@{code_stmts example (SML)}*}
24.619 +
24.620 +subsection {* Inspecting the type class universe *}
24.621 +
24.622 +text {*
24.623 + To facilitate orientation in complex subclass structures,
24.624 + two diagnostics commands are provided:
24.625 +
24.626 + \begin{description}
24.627 +
24.628 + \item[@{command "print_classes"}] print a list of all classes
24.629 + together with associated operations etc.
24.630 +
24.631 + \item[@{command "class_deps"}] visualizes the subclass relation
24.632 + between all classes as a Hasse diagram.
24.633 +
24.634 + \end{description}
24.635 +*}
24.636 +
24.637 +end
25.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
25.2 +++ b/doc-src/Classes/Thy/ROOT.ML Wed Mar 04 11:05:29 2009 +0100
25.3 @@ -0,0 +1,6 @@
25.4 +
25.5 +(* $Id$ *)
25.6 +
25.7 +no_document use_thy "Setup";
25.8 +
25.9 +use_thy "Classes";
26.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
26.2 +++ b/doc-src/Classes/Thy/Setup.thy Wed Mar 04 11:05:29 2009 +0100
26.3 @@ -0,0 +1,34 @@
26.4 +theory Setup
26.5 +imports Main Code_Integer
26.6 +uses
26.7 + "../../antiquote_setup"
26.8 + "../../more_antiquote"
26.9 +begin
26.10 +
26.11 +ML {* Code_Target.code_width := 74 *}
26.12 +
26.13 +syntax
26.14 + "_alpha" :: "type" ("\<alpha>")
26.15 + "_alpha_ofsort" :: "sort \<Rightarrow> type" ("\<alpha>()\<Colon>_" [0] 1000)
26.16 + "_beta" :: "type" ("\<beta>")
26.17 + "_beta_ofsort" :: "sort \<Rightarrow> type" ("\<beta>()\<Colon>_" [0] 1000)
26.18 +
26.19 +parse_ast_translation {*
26.20 + let
26.21 + fun alpha_ast_tr [] = Syntax.Variable "'a"
26.22 + | alpha_ast_tr asts = raise Syntax.AST ("alpha_ast_tr", asts);
26.23 + fun alpha_ofsort_ast_tr [ast] =
26.24 + Syntax.Appl [Syntax.Constant "_ofsort", Syntax.Variable "'a", ast]
26.25 + | alpha_ofsort_ast_tr asts = raise Syntax.AST ("alpha_ast_tr", asts);
26.26 + fun beta_ast_tr [] = Syntax.Variable "'b"
26.27 + | beta_ast_tr asts = raise Syntax.AST ("beta_ast_tr", asts);
26.28 + fun beta_ofsort_ast_tr [ast] =
26.29 + Syntax.Appl [Syntax.Constant "_ofsort", Syntax.Variable "'b", ast]
26.30 + | beta_ofsort_ast_tr asts = raise Syntax.AST ("beta_ast_tr", asts);
26.31 + in [
26.32 + ("_alpha", alpha_ast_tr), ("_alpha_ofsort", alpha_ofsort_ast_tr),
26.33 + ("_beta", beta_ast_tr), ("_beta_ofsort", beta_ofsort_ast_tr)
26.34 + ] end
26.35 +*}
26.36 +
26.37 +end
26.38 \ No newline at end of file
27.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
27.2 +++ b/doc-src/Classes/Thy/document/Classes.tex Wed Mar 04 11:05:29 2009 +0100
27.3 @@ -0,0 +1,1335 @@
27.4 +%
27.5 +\begin{isabellebody}%
27.6 +\def\isabellecontext{Classes}%
27.7 +%
27.8 +\isadelimtheory
27.9 +%
27.10 +\endisadelimtheory
27.11 +%
27.12 +\isatagtheory
27.13 +\isacommand{theory}\isamarkupfalse%
27.14 +\ Classes\isanewline
27.15 +\isakeyword{imports}\ Main\ Setup\isanewline
27.16 +\isakeyword{begin}%
27.17 +\endisatagtheory
27.18 +{\isafoldtheory}%
27.19 +%
27.20 +\isadelimtheory
27.21 +%
27.22 +\endisadelimtheory
27.23 +%
27.24 +\isamarkupsection{Introduction%
27.25 +}
27.26 +\isamarkuptrue%
27.27 +%
27.28 +\begin{isamarkuptext}%
27.29 +Type classes were introduces by Wadler and Blott \cite{wadler89how}
27.30 + into the Haskell language, to allow for a reasonable implementation
27.31 + of overloading\footnote{throughout this tutorial, we are referring
27.32 + to classical Haskell 1.0 type classes, not considering
27.33 + later additions in expressiveness}.
27.34 + As a canonical example, a polymorphic equality function
27.35 + \isa{eq\ {\isasymColon}\ {\isasymalpha}\ {\isasymRightarrow}\ {\isasymalpha}\ {\isasymRightarrow}\ bool} which is overloaded on different
27.36 + types for \isa{{\isasymalpha}}, which is achieved by splitting introduction
27.37 + of the \isa{eq} function from its overloaded definitions by means
27.38 + of \isa{class} and \isa{instance} declarations:
27.39 + \footnote{syntax here is a kind of isabellized Haskell}
27.40 +
27.41 + \begin{quote}
27.42 +
27.43 + \noindent\isa{class\ eq\ where} \\
27.44 + \hspace*{2ex}\isa{eq\ {\isasymColon}\ {\isasymalpha}\ {\isasymRightarrow}\ {\isasymalpha}\ {\isasymRightarrow}\ bool}
27.45 +
27.46 + \medskip\noindent\isa{instance\ nat\ {\isasymColon}\ eq\ where} \\
27.47 + \hspace*{2ex}\isa{eq\ {\isadigit{0}}\ {\isadigit{0}}\ {\isacharequal}\ True} \\
27.48 + \hspace*{2ex}\isa{eq\ {\isadigit{0}}\ {\isacharunderscore}\ {\isacharequal}\ False} \\
27.49 + \hspace*{2ex}\isa{eq\ {\isacharunderscore}\ {\isadigit{0}}\ {\isacharequal}\ False} \\
27.50 + \hspace*{2ex}\isa{eq\ {\isacharparenleft}Suc\ n{\isacharparenright}\ {\isacharparenleft}Suc\ m{\isacharparenright}\ {\isacharequal}\ eq\ n\ m}
27.51 +
27.52 + \medskip\noindent\isa{instance\ {\isacharparenleft}{\isasymalpha}{\isasymColon}eq{\isacharcomma}\ {\isasymbeta}{\isasymColon}eq{\isacharparenright}\ pair\ {\isasymColon}\ eq\ where} \\
27.53 + \hspace*{2ex}\isa{eq\ {\isacharparenleft}x{\isadigit{1}}{\isacharcomma}\ y{\isadigit{1}}{\isacharparenright}\ {\isacharparenleft}x{\isadigit{2}}{\isacharcomma}\ y{\isadigit{2}}{\isacharparenright}\ {\isacharequal}\ eq\ x{\isadigit{1}}\ x{\isadigit{2}}\ {\isasymand}\ eq\ y{\isadigit{1}}\ y{\isadigit{2}}}
27.54 +
27.55 + \medskip\noindent\isa{class\ ord\ extends\ eq\ where} \\
27.56 + \hspace*{2ex}\isa{less{\isacharunderscore}eq\ {\isasymColon}\ {\isasymalpha}\ {\isasymRightarrow}\ {\isasymalpha}\ {\isasymRightarrow}\ bool} \\
27.57 + \hspace*{2ex}\isa{less\ {\isasymColon}\ {\isasymalpha}\ {\isasymRightarrow}\ {\isasymalpha}\ {\isasymRightarrow}\ bool}
27.58 +
27.59 + \end{quote}
27.60 +
27.61 + \noindent Type variables are annotated with (finitely many) classes;
27.62 + these annotations are assertions that a particular polymorphic type
27.63 + provides definitions for overloaded functions.
27.64 +
27.65 + Indeed, type classes not only allow for simple overloading
27.66 + but form a generic calculus, an instance of order-sorted
27.67 + algebra \cite{Nipkow-Prehofer:1993,nipkow-sorts93,Wenzel:1997:TPHOL}.
27.68 +
27.69 + From a software engeneering point of view, type classes
27.70 + roughly correspond to interfaces in object-oriented languages like Java;
27.71 + so, it is naturally desirable that type classes do not only
27.72 + provide functions (class parameters) but also state specifications
27.73 + implementations must obey. For example, the \isa{class\ eq}
27.74 + above could be given the following specification, demanding that
27.75 + \isa{class\ eq} is an equivalence relation obeying reflexivity,
27.76 + symmetry and transitivity:
27.77 +
27.78 + \begin{quote}
27.79 +
27.80 + \noindent\isa{class\ eq\ where} \\
27.81 + \hspace*{2ex}\isa{eq\ {\isasymColon}\ {\isasymalpha}\ {\isasymRightarrow}\ {\isasymalpha}\ {\isasymRightarrow}\ bool} \\
27.82 + \isa{satisfying} \\
27.83 + \hspace*{2ex}\isa{refl{\isacharcolon}\ eq\ x\ x} \\
27.84 + \hspace*{2ex}\isa{sym{\isacharcolon}\ eq\ x\ y\ {\isasymlongleftrightarrow}\ eq\ x\ y} \\
27.85 + \hspace*{2ex}\isa{trans{\isacharcolon}\ eq\ x\ y\ {\isasymand}\ eq\ y\ z\ {\isasymlongrightarrow}\ eq\ x\ z}
27.86 +
27.87 + \end{quote}
27.88 +
27.89 + \noindent From a theoretic point of view, type classes are lightweight
27.90 + modules; Haskell type classes may be emulated by
27.91 + SML functors \cite{classes_modules}.
27.92 + Isabelle/Isar offers a discipline of type classes which brings
27.93 + all those aspects together:
27.94 +
27.95 + \begin{enumerate}
27.96 + \item specifying abstract parameters together with
27.97 + corresponding specifications,
27.98 + \item instantiating those abstract parameters by a particular
27.99 + type
27.100 + \item in connection with a ``less ad-hoc'' approach to overloading,
27.101 + \item with a direct link to the Isabelle module system
27.102 + (aka locales \cite{kammueller-locales}).
27.103 + \end{enumerate}
27.104 +
27.105 + \noindent Isar type classes also directly support code generation
27.106 + in a Haskell like fashion.
27.107 +
27.108 + This tutorial demonstrates common elements of structured specifications
27.109 + and abstract reasoning with type classes by the algebraic hierarchy of
27.110 + semigroups, monoids and groups. Our background theory is that of
27.111 + Isabelle/HOL \cite{isa-tutorial}, for which some
27.112 + familiarity is assumed.
27.113 +
27.114 + Here we merely present the look-and-feel for end users.
27.115 + Internally, those are mapped to more primitive Isabelle concepts.
27.116 + See \cite{Haftmann-Wenzel:2006:classes} for more detail.%
27.117 +\end{isamarkuptext}%
27.118 +\isamarkuptrue%
27.119 +%
27.120 +\isamarkupsection{A simple algebra example \label{sec:example}%
27.121 +}
27.122 +\isamarkuptrue%
27.123 +%
27.124 +\isamarkupsubsection{Class definition%
27.125 +}
27.126 +\isamarkuptrue%
27.127 +%
27.128 +\begin{isamarkuptext}%
27.129 +Depending on an arbitrary type \isa{{\isasymalpha}}, class \isa{semigroup} introduces a binary operator \isa{{\isacharparenleft}{\isasymotimes}{\isacharparenright}} that is
27.130 + assumed to be associative:%
27.131 +\end{isamarkuptext}%
27.132 +\isamarkuptrue%
27.133 +%
27.134 +\isadelimquote
27.135 +%
27.136 +\endisadelimquote
27.137 +%
27.138 +\isatagquote
27.139 +\isacommand{class}\isamarkupfalse%
27.140 +\ semigroup\ {\isacharequal}\isanewline
27.141 +\ \ \isakeyword{fixes}\ mult\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isasymalpha}\ {\isasymRightarrow}\ {\isasymalpha}\ {\isasymRightarrow}\ {\isasymalpha}{\isachardoublequoteclose}\ \ \ \ {\isacharparenleft}\isakeyword{infixl}\ {\isachardoublequoteopen}{\isasymotimes}{\isachardoublequoteclose}\ {\isadigit{7}}{\isadigit{0}}{\isacharparenright}\isanewline
27.142 +\ \ \isakeyword{assumes}\ assoc{\isacharcolon}\ {\isachardoublequoteopen}{\isacharparenleft}x\ {\isasymotimes}\ y{\isacharparenright}\ {\isasymotimes}\ z\ {\isacharequal}\ x\ {\isasymotimes}\ {\isacharparenleft}y\ {\isasymotimes}\ z{\isacharparenright}{\isachardoublequoteclose}%
27.143 +\endisatagquote
27.144 +{\isafoldquote}%
27.145 +%
27.146 +\isadelimquote
27.147 +%
27.148 +\endisadelimquote
27.149 +%
27.150 +\begin{isamarkuptext}%
27.151 +\noindent This \hyperlink{command.class}{\mbox{\isa{\isacommand{class}}}} specification consists of two
27.152 + parts: the \qn{operational} part names the class parameter
27.153 + (\hyperlink{element.fixes}{\mbox{\isa{\isakeyword{fixes}}}}), the \qn{logical} part specifies properties on them
27.154 + (\hyperlink{element.assumes}{\mbox{\isa{\isakeyword{assumes}}}}). The local \hyperlink{element.fixes}{\mbox{\isa{\isakeyword{fixes}}}} and
27.155 + \hyperlink{element.assumes}{\mbox{\isa{\isakeyword{assumes}}}} are lifted to the theory toplevel,
27.156 + yielding the global
27.157 + parameter \isa{{\isachardoublequote}mult\ {\isasymColon}\ {\isasymalpha}{\isasymColon}semigroup\ {\isasymRightarrow}\ {\isasymalpha}\ {\isasymRightarrow}\ {\isasymalpha}{\isachardoublequote}} and the
27.158 + global theorem \hyperlink{fact.semigroup.assoc:}{\mbox{\isa{semigroup{\isachardot}assoc{\isacharcolon}}}}~\isa{{\isachardoublequote}{\isasymAnd}x\ y\ z\ {\isasymColon}\ {\isasymalpha}{\isasymColon}semigroup{\isachardot}\ {\isacharparenleft}x\ {\isasymotimes}\ y{\isacharparenright}\ {\isasymotimes}\ z\ {\isacharequal}\ x\ {\isasymotimes}\ {\isacharparenleft}y\ {\isasymotimes}\ z{\isacharparenright}{\isachardoublequote}}.%
27.159 +\end{isamarkuptext}%
27.160 +\isamarkuptrue%
27.161 +%
27.162 +\isamarkupsubsection{Class instantiation \label{sec:class_inst}%
27.163 +}
27.164 +\isamarkuptrue%
27.165 +%
27.166 +\begin{isamarkuptext}%
27.167 +The concrete type \isa{int} is made a \isa{semigroup}
27.168 + instance by providing a suitable definition for the class parameter
27.169 + \isa{{\isacharparenleft}{\isasymotimes}{\isacharparenright}} and a proof for the specification of \hyperlink{fact.assoc}{\mbox{\isa{assoc}}}.
27.170 + This is accomplished by the \hyperlink{command.instantiation}{\mbox{\isa{\isacommand{instantiation}}}} target:%
27.171 +\end{isamarkuptext}%
27.172 +\isamarkuptrue%
27.173 +%
27.174 +\isadelimquote
27.175 +%
27.176 +\endisadelimquote
27.177 +%
27.178 +\isatagquote
27.179 +\isacommand{instantiation}\isamarkupfalse%
27.180 +\ int\ {\isacharcolon}{\isacharcolon}\ semigroup\isanewline
27.181 +\isakeyword{begin}\isanewline
27.182 +\isanewline
27.183 +\isacommand{definition}\isamarkupfalse%
27.184 +\isanewline
27.185 +\ \ mult{\isacharunderscore}int{\isacharunderscore}def{\isacharcolon}\ {\isachardoublequoteopen}i\ {\isasymotimes}\ j\ {\isacharequal}\ i\ {\isacharplus}\ {\isacharparenleft}j{\isasymColon}int{\isacharparenright}{\isachardoublequoteclose}\isanewline
27.186 +\isanewline
27.187 +\isacommand{instance}\isamarkupfalse%
27.188 +\ \isacommand{proof}\isamarkupfalse%
27.189 +\isanewline
27.190 +\ \ \isacommand{fix}\isamarkupfalse%
27.191 +\ i\ j\ k\ {\isacharcolon}{\isacharcolon}\ int\ \isacommand{have}\isamarkupfalse%
27.192 +\ {\isachardoublequoteopen}{\isacharparenleft}i\ {\isacharplus}\ j{\isacharparenright}\ {\isacharplus}\ k\ {\isacharequal}\ i\ {\isacharplus}\ {\isacharparenleft}j\ {\isacharplus}\ k{\isacharparenright}{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse%
27.193 +\ simp\isanewline
27.194 +\ \ \isacommand{then}\isamarkupfalse%
27.195 +\ \isacommand{show}\isamarkupfalse%
27.196 +\ {\isachardoublequoteopen}{\isacharparenleft}i\ {\isasymotimes}\ j{\isacharparenright}\ {\isasymotimes}\ k\ {\isacharequal}\ i\ {\isasymotimes}\ {\isacharparenleft}j\ {\isasymotimes}\ k{\isacharparenright}{\isachardoublequoteclose}\isanewline
27.197 +\ \ \ \ \isacommand{unfolding}\isamarkupfalse%
27.198 +\ mult{\isacharunderscore}int{\isacharunderscore}def\ \isacommand{{\isachardot}}\isamarkupfalse%
27.199 +\isanewline
27.200 +\isacommand{qed}\isamarkupfalse%
27.201 +\isanewline
27.202 +\isanewline
27.203 +\isacommand{end}\isamarkupfalse%
27.204 +%
27.205 +\endisatagquote
27.206 +{\isafoldquote}%
27.207 +%
27.208 +\isadelimquote
27.209 +%
27.210 +\endisadelimquote
27.211 +%
27.212 +\begin{isamarkuptext}%
27.213 +\noindent \hyperlink{command.instantiation}{\mbox{\isa{\isacommand{instantiation}}}} allows to define class parameters
27.214 + at a particular instance using common specification tools (here,
27.215 + \hyperlink{command.definition}{\mbox{\isa{\isacommand{definition}}}}). The concluding \hyperlink{command.instance}{\mbox{\isa{\isacommand{instance}}}}
27.216 + opens a proof that the given parameters actually conform
27.217 + to the class specification. Note that the first proof step
27.218 + is the \hyperlink{method.default}{\mbox{\isa{default}}} method,
27.219 + which for such instance proofs maps to the \hyperlink{method.intro-classes}{\mbox{\isa{intro{\isacharunderscore}classes}}} method.
27.220 + This boils down an instance judgement to the relevant primitive
27.221 + proof goals and should conveniently always be the first method applied
27.222 + in an instantiation proof.
27.223 +
27.224 + From now on, the type-checker will consider \isa{int}
27.225 + as a \isa{semigroup} automatically, i.e.\ any general results
27.226 + are immediately available on concrete instances.
27.227 +
27.228 + \medskip Another instance of \isa{semigroup} are the natural numbers:%
27.229 +\end{isamarkuptext}%
27.230 +\isamarkuptrue%
27.231 +%
27.232 +\isadelimquote
27.233 +%
27.234 +\endisadelimquote
27.235 +%
27.236 +\isatagquote
27.237 +\isacommand{instantiation}\isamarkupfalse%
27.238 +\ nat\ {\isacharcolon}{\isacharcolon}\ semigroup\isanewline
27.239 +\isakeyword{begin}\isanewline
27.240 +\isanewline
27.241 +\isacommand{primrec}\isamarkupfalse%
27.242 +\ mult{\isacharunderscore}nat\ \isakeyword{where}\isanewline
27.243 +\ \ {\isachardoublequoteopen}{\isacharparenleft}{\isadigit{0}}{\isasymColon}nat{\isacharparenright}\ {\isasymotimes}\ n\ {\isacharequal}\ n{\isachardoublequoteclose}\isanewline
27.244 +\ \ {\isacharbar}\ {\isachardoublequoteopen}Suc\ m\ {\isasymotimes}\ n\ {\isacharequal}\ Suc\ {\isacharparenleft}m\ {\isasymotimes}\ n{\isacharparenright}{\isachardoublequoteclose}\isanewline
27.245 +\isanewline
27.246 +\isacommand{instance}\isamarkupfalse%
27.247 +\ \isacommand{proof}\isamarkupfalse%
27.248 +\isanewline
27.249 +\ \ \isacommand{fix}\isamarkupfalse%
27.250 +\ m\ n\ q\ {\isacharcolon}{\isacharcolon}\ nat\ \isanewline
27.251 +\ \ \isacommand{show}\isamarkupfalse%
27.252 +\ {\isachardoublequoteopen}m\ {\isasymotimes}\ n\ {\isasymotimes}\ q\ {\isacharequal}\ m\ {\isasymotimes}\ {\isacharparenleft}n\ {\isasymotimes}\ q{\isacharparenright}{\isachardoublequoteclose}\isanewline
27.253 +\ \ \ \ \isacommand{by}\isamarkupfalse%
27.254 +\ {\isacharparenleft}induct\ m{\isacharparenright}\ auto\isanewline
27.255 +\isacommand{qed}\isamarkupfalse%
27.256 +\isanewline
27.257 +\isanewline
27.258 +\isacommand{end}\isamarkupfalse%
27.259 +%
27.260 +\endisatagquote
27.261 +{\isafoldquote}%
27.262 +%
27.263 +\isadelimquote
27.264 +%
27.265 +\endisadelimquote
27.266 +%
27.267 +\begin{isamarkuptext}%
27.268 +\noindent Note the occurence of the name \isa{mult{\isacharunderscore}nat}
27.269 + in the primrec declaration; by default, the local name of
27.270 + a class operation \isa{f} to instantiate on type constructor
27.271 + \isa{{\isasymkappa}} are mangled as \isa{f{\isacharunderscore}{\isasymkappa}}. In case of uncertainty,
27.272 + these names may be inspected using the \hyperlink{command.print-context}{\mbox{\isa{\isacommand{print{\isacharunderscore}context}}}} command
27.273 + or the corresponding ProofGeneral button.%
27.274 +\end{isamarkuptext}%
27.275 +\isamarkuptrue%
27.276 +%
27.277 +\isamarkupsubsection{Lifting and parametric types%
27.278 +}
27.279 +\isamarkuptrue%
27.280 +%
27.281 +\begin{isamarkuptext}%
27.282 +Overloaded definitions giving on class instantiation
27.283 + may include recursion over the syntactic structure of types.
27.284 + As a canonical example, we model product semigroups
27.285 + using our simple algebra:%
27.286 +\end{isamarkuptext}%
27.287 +\isamarkuptrue%
27.288 +%
27.289 +\isadelimquote
27.290 +%
27.291 +\endisadelimquote
27.292 +%
27.293 +\isatagquote
27.294 +\isacommand{instantiation}\isamarkupfalse%
27.295 +\ {\isacharasterisk}\ {\isacharcolon}{\isacharcolon}\ {\isacharparenleft}semigroup{\isacharcomma}\ semigroup{\isacharparenright}\ semigroup\isanewline
27.296 +\isakeyword{begin}\isanewline
27.297 +\isanewline
27.298 +\isacommand{definition}\isamarkupfalse%
27.299 +\isanewline
27.300 +\ \ mult{\isacharunderscore}prod{\isacharunderscore}def{\isacharcolon}\ {\isachardoublequoteopen}p\isactrlisub {\isadigit{1}}\ {\isasymotimes}\ p\isactrlisub {\isadigit{2}}\ {\isacharequal}\ {\isacharparenleft}fst\ p\isactrlisub {\isadigit{1}}\ {\isasymotimes}\ fst\ p\isactrlisub {\isadigit{2}}{\isacharcomma}\ snd\ p\isactrlisub {\isadigit{1}}\ {\isasymotimes}\ snd\ p\isactrlisub {\isadigit{2}}{\isacharparenright}{\isachardoublequoteclose}\isanewline
27.301 +\isanewline
27.302 +\isacommand{instance}\isamarkupfalse%
27.303 +\ \isacommand{proof}\isamarkupfalse%
27.304 +\isanewline
27.305 +\ \ \isacommand{fix}\isamarkupfalse%
27.306 +\ p\isactrlisub {\isadigit{1}}\ p\isactrlisub {\isadigit{2}}\ p\isactrlisub {\isadigit{3}}\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isasymalpha}{\isasymColon}semigroup\ {\isasymtimes}\ {\isasymbeta}{\isasymColon}semigroup{\isachardoublequoteclose}\isanewline
27.307 +\ \ \isacommand{show}\isamarkupfalse%
27.308 +\ {\isachardoublequoteopen}p\isactrlisub {\isadigit{1}}\ {\isasymotimes}\ p\isactrlisub {\isadigit{2}}\ {\isasymotimes}\ p\isactrlisub {\isadigit{3}}\ {\isacharequal}\ p\isactrlisub {\isadigit{1}}\ {\isasymotimes}\ {\isacharparenleft}p\isactrlisub {\isadigit{2}}\ {\isasymotimes}\ p\isactrlisub {\isadigit{3}}{\isacharparenright}{\isachardoublequoteclose}\isanewline
27.309 +\ \ \ \ \isacommand{unfolding}\isamarkupfalse%
27.310 +\ mult{\isacharunderscore}prod{\isacharunderscore}def\ \isacommand{by}\isamarkupfalse%
27.311 +\ {\isacharparenleft}simp\ add{\isacharcolon}\ assoc{\isacharparenright}\isanewline
27.312 +\isacommand{qed}\isamarkupfalse%
27.313 +\ \ \ \ \ \ \isanewline
27.314 +\isanewline
27.315 +\isacommand{end}\isamarkupfalse%
27.316 +%
27.317 +\endisatagquote
27.318 +{\isafoldquote}%
27.319 +%
27.320 +\isadelimquote
27.321 +%
27.322 +\endisadelimquote
27.323 +%
27.324 +\begin{isamarkuptext}%
27.325 +\noindent Associativity from product semigroups is
27.326 + established using
27.327 + the definition of \isa{{\isacharparenleft}{\isasymotimes}{\isacharparenright}} on products and the hypothetical
27.328 + associativity of the type components; these hypotheses
27.329 + are facts due to the \isa{semigroup} constraints imposed
27.330 + on the type components by the \hyperlink{command.instance}{\mbox{\isa{\isacommand{instance}}}} proposition.
27.331 + Indeed, this pattern often occurs with parametric types
27.332 + and type classes.%
27.333 +\end{isamarkuptext}%
27.334 +\isamarkuptrue%
27.335 +%
27.336 +\isamarkupsubsection{Subclassing%
27.337 +}
27.338 +\isamarkuptrue%
27.339 +%
27.340 +\begin{isamarkuptext}%
27.341 +We define a subclass \isa{monoidl} (a semigroup with a left-hand neutral)
27.342 + by extending \isa{semigroup}
27.343 + with one additional parameter \isa{neutral} together
27.344 + with its property:%
27.345 +\end{isamarkuptext}%
27.346 +\isamarkuptrue%
27.347 +%
27.348 +\isadelimquote
27.349 +%
27.350 +\endisadelimquote
27.351 +%
27.352 +\isatagquote
27.353 +\isacommand{class}\isamarkupfalse%
27.354 +\ monoidl\ {\isacharequal}\ semigroup\ {\isacharplus}\isanewline
27.355 +\ \ \isakeyword{fixes}\ neutral\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isasymalpha}{\isachardoublequoteclose}\ {\isacharparenleft}{\isachardoublequoteopen}{\isasymone}{\isachardoublequoteclose}{\isacharparenright}\isanewline
27.356 +\ \ \isakeyword{assumes}\ neutl{\isacharcolon}\ {\isachardoublequoteopen}{\isasymone}\ {\isasymotimes}\ x\ {\isacharequal}\ x{\isachardoublequoteclose}%
27.357 +\endisatagquote
27.358 +{\isafoldquote}%
27.359 +%
27.360 +\isadelimquote
27.361 +%
27.362 +\endisadelimquote
27.363 +%
27.364 +\begin{isamarkuptext}%
27.365 +\noindent Again, we prove some instances, by
27.366 + providing suitable parameter definitions and proofs for the
27.367 + additional specifications. Observe that instantiations
27.368 + for types with the same arity may be simultaneous:%
27.369 +\end{isamarkuptext}%
27.370 +\isamarkuptrue%
27.371 +%
27.372 +\isadelimquote
27.373 +%
27.374 +\endisadelimquote
27.375 +%
27.376 +\isatagquote
27.377 +\isacommand{instantiation}\isamarkupfalse%
27.378 +\ nat\ \isakeyword{and}\ int\ {\isacharcolon}{\isacharcolon}\ monoidl\isanewline
27.379 +\isakeyword{begin}\isanewline
27.380 +\isanewline
27.381 +\isacommand{definition}\isamarkupfalse%
27.382 +\isanewline
27.383 +\ \ neutral{\isacharunderscore}nat{\isacharunderscore}def{\isacharcolon}\ {\isachardoublequoteopen}{\isasymone}\ {\isacharequal}\ {\isacharparenleft}{\isadigit{0}}{\isasymColon}nat{\isacharparenright}{\isachardoublequoteclose}\isanewline
27.384 +\isanewline
27.385 +\isacommand{definition}\isamarkupfalse%
27.386 +\isanewline
27.387 +\ \ neutral{\isacharunderscore}int{\isacharunderscore}def{\isacharcolon}\ {\isachardoublequoteopen}{\isasymone}\ {\isacharequal}\ {\isacharparenleft}{\isadigit{0}}{\isasymColon}int{\isacharparenright}{\isachardoublequoteclose}\isanewline
27.388 +\isanewline
27.389 +\isacommand{instance}\isamarkupfalse%
27.390 +\ \isacommand{proof}\isamarkupfalse%
27.391 +\isanewline
27.392 +\ \ \isacommand{fix}\isamarkupfalse%
27.393 +\ n\ {\isacharcolon}{\isacharcolon}\ nat\isanewline
27.394 +\ \ \isacommand{show}\isamarkupfalse%
27.395 +\ {\isachardoublequoteopen}{\isasymone}\ {\isasymotimes}\ n\ {\isacharequal}\ n{\isachardoublequoteclose}\isanewline
27.396 +\ \ \ \ \isacommand{unfolding}\isamarkupfalse%
27.397 +\ neutral{\isacharunderscore}nat{\isacharunderscore}def\ \isacommand{by}\isamarkupfalse%
27.398 +\ simp\isanewline
27.399 +\isacommand{next}\isamarkupfalse%
27.400 +\isanewline
27.401 +\ \ \isacommand{fix}\isamarkupfalse%
27.402 +\ k\ {\isacharcolon}{\isacharcolon}\ int\isanewline
27.403 +\ \ \isacommand{show}\isamarkupfalse%
27.404 +\ {\isachardoublequoteopen}{\isasymone}\ {\isasymotimes}\ k\ {\isacharequal}\ k{\isachardoublequoteclose}\isanewline
27.405 +\ \ \ \ \isacommand{unfolding}\isamarkupfalse%
27.406 +\ neutral{\isacharunderscore}int{\isacharunderscore}def\ mult{\isacharunderscore}int{\isacharunderscore}def\ \isacommand{by}\isamarkupfalse%
27.407 +\ simp\isanewline
27.408 +\isacommand{qed}\isamarkupfalse%
27.409 +\isanewline
27.410 +\isanewline
27.411 +\isacommand{end}\isamarkupfalse%
27.412 +\isanewline
27.413 +\isanewline
27.414 +\isacommand{instantiation}\isamarkupfalse%
27.415 +\ {\isacharasterisk}\ {\isacharcolon}{\isacharcolon}\ {\isacharparenleft}monoidl{\isacharcomma}\ monoidl{\isacharparenright}\ monoidl\isanewline
27.416 +\isakeyword{begin}\isanewline
27.417 +\isanewline
27.418 +\isacommand{definition}\isamarkupfalse%
27.419 +\isanewline
27.420 +\ \ neutral{\isacharunderscore}prod{\isacharunderscore}def{\isacharcolon}\ {\isachardoublequoteopen}{\isasymone}\ {\isacharequal}\ {\isacharparenleft}{\isasymone}{\isacharcomma}\ {\isasymone}{\isacharparenright}{\isachardoublequoteclose}\isanewline
27.421 +\isanewline
27.422 +\isacommand{instance}\isamarkupfalse%
27.423 +\ \isacommand{proof}\isamarkupfalse%
27.424 +\isanewline
27.425 +\ \ \isacommand{fix}\isamarkupfalse%
27.426 +\ p\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isasymalpha}{\isasymColon}monoidl\ {\isasymtimes}\ {\isasymbeta}{\isasymColon}monoidl{\isachardoublequoteclose}\isanewline
27.427 +\ \ \isacommand{show}\isamarkupfalse%
27.428 +\ {\isachardoublequoteopen}{\isasymone}\ {\isasymotimes}\ p\ {\isacharequal}\ p{\isachardoublequoteclose}\isanewline
27.429 +\ \ \ \ \isacommand{unfolding}\isamarkupfalse%
27.430 +\ neutral{\isacharunderscore}prod{\isacharunderscore}def\ mult{\isacharunderscore}prod{\isacharunderscore}def\ \isacommand{by}\isamarkupfalse%
27.431 +\ {\isacharparenleft}simp\ add{\isacharcolon}\ neutl{\isacharparenright}\isanewline
27.432 +\isacommand{qed}\isamarkupfalse%
27.433 +\isanewline
27.434 +\isanewline
27.435 +\isacommand{end}\isamarkupfalse%
27.436 +%
27.437 +\endisatagquote
27.438 +{\isafoldquote}%
27.439 +%
27.440 +\isadelimquote
27.441 +%
27.442 +\endisadelimquote
27.443 +%
27.444 +\begin{isamarkuptext}%
27.445 +\noindent Fully-fledged monoids are modelled by another subclass
27.446 + which does not add new parameters but tightens the specification:%
27.447 +\end{isamarkuptext}%
27.448 +\isamarkuptrue%
27.449 +%
27.450 +\isadelimquote
27.451 +%
27.452 +\endisadelimquote
27.453 +%
27.454 +\isatagquote
27.455 +\isacommand{class}\isamarkupfalse%
27.456 +\ monoid\ {\isacharequal}\ monoidl\ {\isacharplus}\isanewline
27.457 +\ \ \isakeyword{assumes}\ neutr{\isacharcolon}\ {\isachardoublequoteopen}x\ {\isasymotimes}\ {\isasymone}\ {\isacharequal}\ x{\isachardoublequoteclose}\isanewline
27.458 +\isanewline
27.459 +\isacommand{instantiation}\isamarkupfalse%
27.460 +\ nat\ \isakeyword{and}\ int\ {\isacharcolon}{\isacharcolon}\ monoid\ \isanewline
27.461 +\isakeyword{begin}\isanewline
27.462 +\isanewline
27.463 +\isacommand{instance}\isamarkupfalse%
27.464 +\ \isacommand{proof}\isamarkupfalse%
27.465 +\isanewline
27.466 +\ \ \isacommand{fix}\isamarkupfalse%
27.467 +\ n\ {\isacharcolon}{\isacharcolon}\ nat\isanewline
27.468 +\ \ \isacommand{show}\isamarkupfalse%
27.469 +\ {\isachardoublequoteopen}n\ {\isasymotimes}\ {\isasymone}\ {\isacharequal}\ n{\isachardoublequoteclose}\isanewline
27.470 +\ \ \ \ \isacommand{unfolding}\isamarkupfalse%
27.471 +\ neutral{\isacharunderscore}nat{\isacharunderscore}def\ \isacommand{by}\isamarkupfalse%
27.472 +\ {\isacharparenleft}induct\ n{\isacharparenright}\ simp{\isacharunderscore}all\isanewline
27.473 +\isacommand{next}\isamarkupfalse%
27.474 +\isanewline
27.475 +\ \ \isacommand{fix}\isamarkupfalse%
27.476 +\ k\ {\isacharcolon}{\isacharcolon}\ int\isanewline
27.477 +\ \ \isacommand{show}\isamarkupfalse%
27.478 +\ {\isachardoublequoteopen}k\ {\isasymotimes}\ {\isasymone}\ {\isacharequal}\ k{\isachardoublequoteclose}\isanewline
27.479 +\ \ \ \ \isacommand{unfolding}\isamarkupfalse%
27.480 +\ neutral{\isacharunderscore}int{\isacharunderscore}def\ mult{\isacharunderscore}int{\isacharunderscore}def\ \isacommand{by}\isamarkupfalse%
27.481 +\ simp\isanewline
27.482 +\isacommand{qed}\isamarkupfalse%
27.483 +\isanewline
27.484 +\isanewline
27.485 +\isacommand{end}\isamarkupfalse%
27.486 +\isanewline
27.487 +\isanewline
27.488 +\isacommand{instantiation}\isamarkupfalse%
27.489 +\ {\isacharasterisk}\ {\isacharcolon}{\isacharcolon}\ {\isacharparenleft}monoid{\isacharcomma}\ monoid{\isacharparenright}\ monoid\isanewline
27.490 +\isakeyword{begin}\isanewline
27.491 +\isanewline
27.492 +\isacommand{instance}\isamarkupfalse%
27.493 +\ \isacommand{proof}\isamarkupfalse%
27.494 +\ \isanewline
27.495 +\ \ \isacommand{fix}\isamarkupfalse%
27.496 +\ p\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isasymalpha}{\isasymColon}monoid\ {\isasymtimes}\ {\isasymbeta}{\isasymColon}monoid{\isachardoublequoteclose}\isanewline
27.497 +\ \ \isacommand{show}\isamarkupfalse%
27.498 +\ {\isachardoublequoteopen}p\ {\isasymotimes}\ {\isasymone}\ {\isacharequal}\ p{\isachardoublequoteclose}\isanewline
27.499 +\ \ \ \ \isacommand{unfolding}\isamarkupfalse%
27.500 +\ neutral{\isacharunderscore}prod{\isacharunderscore}def\ mult{\isacharunderscore}prod{\isacharunderscore}def\ \isacommand{by}\isamarkupfalse%
27.501 +\ {\isacharparenleft}simp\ add{\isacharcolon}\ neutr{\isacharparenright}\isanewline
27.502 +\isacommand{qed}\isamarkupfalse%
27.503 +\isanewline
27.504 +\isanewline
27.505 +\isacommand{end}\isamarkupfalse%
27.506 +%
27.507 +\endisatagquote
27.508 +{\isafoldquote}%
27.509 +%
27.510 +\isadelimquote
27.511 +%
27.512 +\endisadelimquote
27.513 +%
27.514 +\begin{isamarkuptext}%
27.515 +\noindent To finish our small algebra example, we add a \isa{group} class
27.516 + with a corresponding instance:%
27.517 +\end{isamarkuptext}%
27.518 +\isamarkuptrue%
27.519 +%
27.520 +\isadelimquote
27.521 +%
27.522 +\endisadelimquote
27.523 +%
27.524 +\isatagquote
27.525 +\isacommand{class}\isamarkupfalse%
27.526 +\ group\ {\isacharequal}\ monoidl\ {\isacharplus}\isanewline
27.527 +\ \ \isakeyword{fixes}\ inverse\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isasymalpha}\ {\isasymRightarrow}\ {\isasymalpha}{\isachardoublequoteclose}\ \ \ \ {\isacharparenleft}{\isachardoublequoteopen}{\isacharparenleft}{\isacharunderscore}{\isasymdiv}{\isacharparenright}{\isachardoublequoteclose}\ {\isacharbrackleft}{\isadigit{1}}{\isadigit{0}}{\isadigit{0}}{\isadigit{0}}{\isacharbrackright}\ {\isadigit{9}}{\isadigit{9}}{\isadigit{9}}{\isacharparenright}\isanewline
27.528 +\ \ \isakeyword{assumes}\ invl{\isacharcolon}\ {\isachardoublequoteopen}x{\isasymdiv}\ {\isasymotimes}\ x\ {\isacharequal}\ {\isasymone}{\isachardoublequoteclose}\isanewline
27.529 +\isanewline
27.530 +\isacommand{instantiation}\isamarkupfalse%
27.531 +\ int\ {\isacharcolon}{\isacharcolon}\ group\isanewline
27.532 +\isakeyword{begin}\isanewline
27.533 +\isanewline
27.534 +\isacommand{definition}\isamarkupfalse%
27.535 +\isanewline
27.536 +\ \ inverse{\isacharunderscore}int{\isacharunderscore}def{\isacharcolon}\ {\isachardoublequoteopen}i{\isasymdiv}\ {\isacharequal}\ {\isacharminus}\ {\isacharparenleft}i{\isasymColon}int{\isacharparenright}{\isachardoublequoteclose}\isanewline
27.537 +\isanewline
27.538 +\isacommand{instance}\isamarkupfalse%
27.539 +\ \isacommand{proof}\isamarkupfalse%
27.540 +\isanewline
27.541 +\ \ \isacommand{fix}\isamarkupfalse%
27.542 +\ i\ {\isacharcolon}{\isacharcolon}\ int\isanewline
27.543 +\ \ \isacommand{have}\isamarkupfalse%
27.544 +\ {\isachardoublequoteopen}{\isacharminus}i\ {\isacharplus}\ i\ {\isacharequal}\ {\isadigit{0}}{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse%
27.545 +\ simp\isanewline
27.546 +\ \ \isacommand{then}\isamarkupfalse%
27.547 +\ \isacommand{show}\isamarkupfalse%
27.548 +\ {\isachardoublequoteopen}i{\isasymdiv}\ {\isasymotimes}\ i\ {\isacharequal}\ {\isasymone}{\isachardoublequoteclose}\isanewline
27.549 +\ \ \ \ \isacommand{unfolding}\isamarkupfalse%
27.550 +\ mult{\isacharunderscore}int{\isacharunderscore}def\ neutral{\isacharunderscore}int{\isacharunderscore}def\ inverse{\isacharunderscore}int{\isacharunderscore}def\ \isacommand{{\isachardot}}\isamarkupfalse%
27.551 +\isanewline
27.552 +\isacommand{qed}\isamarkupfalse%
27.553 +\isanewline
27.554 +\isanewline
27.555 +\isacommand{end}\isamarkupfalse%
27.556 +%
27.557 +\endisatagquote
27.558 +{\isafoldquote}%
27.559 +%
27.560 +\isadelimquote
27.561 +%
27.562 +\endisadelimquote
27.563 +%
27.564 +\isamarkupsection{Type classes as locales%
27.565 +}
27.566 +\isamarkuptrue%
27.567 +%
27.568 +\isamarkupsubsection{A look behind the scene%
27.569 +}
27.570 +\isamarkuptrue%
27.571 +%
27.572 +\begin{isamarkuptext}%
27.573 +The example above gives an impression how Isar type classes work
27.574 + in practice. As stated in the introduction, classes also provide
27.575 + a link to Isar's locale system. Indeed, the logical core of a class
27.576 + is nothing else than a locale:%
27.577 +\end{isamarkuptext}%
27.578 +\isamarkuptrue%
27.579 +%
27.580 +\isadelimquote
27.581 +%
27.582 +\endisadelimquote
27.583 +%
27.584 +\isatagquote
27.585 +\isacommand{class}\isamarkupfalse%
27.586 +\ idem\ {\isacharequal}\isanewline
27.587 +\ \ \isakeyword{fixes}\ f\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isasymalpha}\ {\isasymRightarrow}\ {\isasymalpha}{\isachardoublequoteclose}\isanewline
27.588 +\ \ \isakeyword{assumes}\ idem{\isacharcolon}\ {\isachardoublequoteopen}f\ {\isacharparenleft}f\ x{\isacharparenright}\ {\isacharequal}\ f\ x{\isachardoublequoteclose}%
27.589 +\endisatagquote
27.590 +{\isafoldquote}%
27.591 +%
27.592 +\isadelimquote
27.593 +%
27.594 +\endisadelimquote
27.595 +%
27.596 +\begin{isamarkuptext}%
27.597 +\noindent essentially introduces the locale%
27.598 +\end{isamarkuptext}%
27.599 +\isamarkuptrue%
27.600 +\ %
27.601 +\isadeliminvisible
27.602 +%
27.603 +\endisadeliminvisible
27.604 +%
27.605 +\isataginvisible
27.606 +%
27.607 +\endisataginvisible
27.608 +{\isafoldinvisible}%
27.609 +%
27.610 +\isadeliminvisible
27.611 +%
27.612 +\endisadeliminvisible
27.613 +%
27.614 +\isadelimquote
27.615 +%
27.616 +\endisadelimquote
27.617 +%
27.618 +\isatagquote
27.619 +\isacommand{locale}\isamarkupfalse%
27.620 +\ idem\ {\isacharequal}\isanewline
27.621 +\ \ \isakeyword{fixes}\ f\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isasymalpha}\ {\isasymRightarrow}\ {\isasymalpha}{\isachardoublequoteclose}\isanewline
27.622 +\ \ \isakeyword{assumes}\ idem{\isacharcolon}\ {\isachardoublequoteopen}f\ {\isacharparenleft}f\ x{\isacharparenright}\ {\isacharequal}\ f\ x{\isachardoublequoteclose}%
27.623 +\endisatagquote
27.624 +{\isafoldquote}%
27.625 +%
27.626 +\isadelimquote
27.627 +%
27.628 +\endisadelimquote
27.629 +%
27.630 +\begin{isamarkuptext}%
27.631 +\noindent together with corresponding constant(s):%
27.632 +\end{isamarkuptext}%
27.633 +\isamarkuptrue%
27.634 +%
27.635 +\isadelimquote
27.636 +%
27.637 +\endisadelimquote
27.638 +%
27.639 +\isatagquote
27.640 +\isacommand{consts}\isamarkupfalse%
27.641 +\ f\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isasymalpha}\ {\isasymRightarrow}\ {\isasymalpha}{\isachardoublequoteclose}%
27.642 +\endisatagquote
27.643 +{\isafoldquote}%
27.644 +%
27.645 +\isadelimquote
27.646 +%
27.647 +\endisadelimquote
27.648 +%
27.649 +\begin{isamarkuptext}%
27.650 +\noindent The connection to the type system is done by means
27.651 + of a primitive axclass%
27.652 +\end{isamarkuptext}%
27.653 +\isamarkuptrue%
27.654 +\ %
27.655 +\isadeliminvisible
27.656 +%
27.657 +\endisadeliminvisible
27.658 +%
27.659 +\isataginvisible
27.660 +%
27.661 +\endisataginvisible
27.662 +{\isafoldinvisible}%
27.663 +%
27.664 +\isadeliminvisible
27.665 +%
27.666 +\endisadeliminvisible
27.667 +%
27.668 +\isadelimquote
27.669 +%
27.670 +\endisadelimquote
27.671 +%
27.672 +\isatagquote
27.673 +\isacommand{axclass}\isamarkupfalse%
27.674 +\ idem\ {\isacharless}\ type\isanewline
27.675 +\ \ idem{\isacharcolon}\ {\isachardoublequoteopen}f\ {\isacharparenleft}f\ x{\isacharparenright}\ {\isacharequal}\ f\ x{\isachardoublequoteclose}\ %
27.676 +\endisatagquote
27.677 +{\isafoldquote}%
27.678 +%
27.679 +\isadelimquote
27.680 +%
27.681 +\endisadelimquote
27.682 +%
27.683 +\isadeliminvisible
27.684 +%
27.685 +\endisadeliminvisible
27.686 +%
27.687 +\isataginvisible
27.688 +%
27.689 +\endisataginvisible
27.690 +{\isafoldinvisible}%
27.691 +%
27.692 +\isadeliminvisible
27.693 +%
27.694 +\endisadeliminvisible
27.695 +%
27.696 +\begin{isamarkuptext}%
27.697 +\noindent together with a corresponding interpretation:%
27.698 +\end{isamarkuptext}%
27.699 +\isamarkuptrue%
27.700 +%
27.701 +\isadelimquote
27.702 +%
27.703 +\endisadelimquote
27.704 +%
27.705 +\isatagquote
27.706 +\isacommand{interpretation}\isamarkupfalse%
27.707 +\ idem{\isacharunderscore}class{\isacharcolon}\isanewline
27.708 +\ \ idem\ {\isachardoublequoteopen}f\ {\isasymColon}\ {\isacharparenleft}{\isasymalpha}{\isasymColon}idem{\isacharparenright}\ {\isasymRightarrow}\ {\isasymalpha}{\isachardoublequoteclose}\isanewline
27.709 +\isacommand{proof}\isamarkupfalse%
27.710 +\ \isacommand{qed}\isamarkupfalse%
27.711 +\ {\isacharparenleft}rule\ idem{\isacharparenright}%
27.712 +\endisatagquote
27.713 +{\isafoldquote}%
27.714 +%
27.715 +\isadelimquote
27.716 +%
27.717 +\endisadelimquote
27.718 +%
27.719 +\begin{isamarkuptext}%
27.720 +\noindent This gives you at hand the full power of the Isabelle module system;
27.721 + conclusions in locale \isa{idem} are implicitly propagated
27.722 + to class \isa{idem}.%
27.723 +\end{isamarkuptext}%
27.724 +\isamarkuptrue%
27.725 +\ %
27.726 +\isadeliminvisible
27.727 +%
27.728 +\endisadeliminvisible
27.729 +%
27.730 +\isataginvisible
27.731 +%
27.732 +\endisataginvisible
27.733 +{\isafoldinvisible}%
27.734 +%
27.735 +\isadeliminvisible
27.736 +%
27.737 +\endisadeliminvisible
27.738 +%
27.739 +\isamarkupsubsection{Abstract reasoning%
27.740 +}
27.741 +\isamarkuptrue%
27.742 +%
27.743 +\begin{isamarkuptext}%
27.744 +Isabelle locales enable reasoning at a general level, while results
27.745 + are implicitly transferred to all instances. For example, we can
27.746 + now establish the \isa{left{\isacharunderscore}cancel} lemma for groups, which
27.747 + states that the function \isa{{\isacharparenleft}x\ {\isasymotimes}{\isacharparenright}} is injective:%
27.748 +\end{isamarkuptext}%
27.749 +\isamarkuptrue%
27.750 +%
27.751 +\isadelimquote
27.752 +%
27.753 +\endisadelimquote
27.754 +%
27.755 +\isatagquote
27.756 +\isacommand{lemma}\isamarkupfalse%
27.757 +\ {\isacharparenleft}\isakeyword{in}\ group{\isacharparenright}\ left{\isacharunderscore}cancel{\isacharcolon}\ {\isachardoublequoteopen}x\ {\isasymotimes}\ y\ {\isacharequal}\ x\ {\isasymotimes}\ z\ {\isasymlongleftrightarrow}\ y\ {\isacharequal}\ z{\isachardoublequoteclose}\isanewline
27.758 +\isacommand{proof}\isamarkupfalse%
27.759 +\isanewline
27.760 +\ \ \isacommand{assume}\isamarkupfalse%
27.761 +\ {\isachardoublequoteopen}x\ {\isasymotimes}\ y\ {\isacharequal}\ x\ {\isasymotimes}\ z{\isachardoublequoteclose}\isanewline
27.762 +\ \ \isacommand{then}\isamarkupfalse%
27.763 +\ \isacommand{have}\isamarkupfalse%
27.764 +\ {\isachardoublequoteopen}x{\isasymdiv}\ {\isasymotimes}\ {\isacharparenleft}x\ {\isasymotimes}\ y{\isacharparenright}\ {\isacharequal}\ x{\isasymdiv}\ {\isasymotimes}\ {\isacharparenleft}x\ {\isasymotimes}\ z{\isacharparenright}{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse%
27.765 +\ simp\isanewline
27.766 +\ \ \isacommand{then}\isamarkupfalse%
27.767 +\ \isacommand{have}\isamarkupfalse%
27.768 +\ {\isachardoublequoteopen}{\isacharparenleft}x{\isasymdiv}\ {\isasymotimes}\ x{\isacharparenright}\ {\isasymotimes}\ y\ {\isacharequal}\ {\isacharparenleft}x{\isasymdiv}\ {\isasymotimes}\ x{\isacharparenright}\ {\isasymotimes}\ z{\isachardoublequoteclose}\ \isacommand{using}\isamarkupfalse%
27.769 +\ assoc\ \isacommand{by}\isamarkupfalse%
27.770 +\ simp\isanewline
27.771 +\ \ \isacommand{then}\isamarkupfalse%
27.772 +\ \isacommand{show}\isamarkupfalse%
27.773 +\ {\isachardoublequoteopen}y\ {\isacharequal}\ z{\isachardoublequoteclose}\ \isacommand{using}\isamarkupfalse%
27.774 +\ neutl\ \isakeyword{and}\ invl\ \isacommand{by}\isamarkupfalse%
27.775 +\ simp\isanewline
27.776 +\isacommand{next}\isamarkupfalse%
27.777 +\isanewline
27.778 +\ \ \isacommand{assume}\isamarkupfalse%
27.779 +\ {\isachardoublequoteopen}y\ {\isacharequal}\ z{\isachardoublequoteclose}\isanewline
27.780 +\ \ \isacommand{then}\isamarkupfalse%
27.781 +\ \isacommand{show}\isamarkupfalse%
27.782 +\ {\isachardoublequoteopen}x\ {\isasymotimes}\ y\ {\isacharequal}\ x\ {\isasymotimes}\ z{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse%
27.783 +\ simp\isanewline
27.784 +\isacommand{qed}\isamarkupfalse%
27.785 +%
27.786 +\endisatagquote
27.787 +{\isafoldquote}%
27.788 +%
27.789 +\isadelimquote
27.790 +%
27.791 +\endisadelimquote
27.792 +%
27.793 +\begin{isamarkuptext}%
27.794 +\noindent Here the \qt{\hyperlink{keyword.in}{\mbox{\isa{\isakeyword{in}}}} \isa{group}} target specification
27.795 + indicates that the result is recorded within that context for later
27.796 + use. This local theorem is also lifted to the global one \hyperlink{fact.group.left-cancel:}{\mbox{\isa{group{\isachardot}left{\isacharunderscore}cancel{\isacharcolon}}}} \isa{{\isachardoublequote}{\isasymAnd}x\ y\ z\ {\isasymColon}\ {\isasymalpha}{\isasymColon}group{\isachardot}\ x\ {\isasymotimes}\ y\ {\isacharequal}\ x\ {\isasymotimes}\ z\ {\isasymlongleftrightarrow}\ y\ {\isacharequal}\ z{\isachardoublequote}}. Since type \isa{int} has been made an instance of
27.797 + \isa{group} before, we may refer to that fact as well: \isa{{\isachardoublequote}{\isasymAnd}x\ y\ z\ {\isasymColon}\ int{\isachardot}\ x\ {\isasymotimes}\ y\ {\isacharequal}\ x\ {\isasymotimes}\ z\ {\isasymlongleftrightarrow}\ y\ {\isacharequal}\ z{\isachardoublequote}}.%
27.798 +\end{isamarkuptext}%
27.799 +\isamarkuptrue%
27.800 +%
27.801 +\isamarkupsubsection{Derived definitions%
27.802 +}
27.803 +\isamarkuptrue%
27.804 +%
27.805 +\begin{isamarkuptext}%
27.806 +Isabelle locales support a concept of local definitions
27.807 + in locales:%
27.808 +\end{isamarkuptext}%
27.809 +\isamarkuptrue%
27.810 +%
27.811 +\isadelimquote
27.812 +%
27.813 +\endisadelimquote
27.814 +%
27.815 +\isatagquote
27.816 +\isacommand{primrec}\isamarkupfalse%
27.817 +\ {\isacharparenleft}\isakeyword{in}\ monoid{\isacharparenright}\ pow{\isacharunderscore}nat\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymRightarrow}\ {\isasymalpha}\ {\isasymRightarrow}\ {\isasymalpha}{\isachardoublequoteclose}\ \isakeyword{where}\isanewline
27.818 +\ \ {\isachardoublequoteopen}pow{\isacharunderscore}nat\ {\isadigit{0}}\ x\ {\isacharequal}\ {\isasymone}{\isachardoublequoteclose}\isanewline
27.819 +\ \ {\isacharbar}\ {\isachardoublequoteopen}pow{\isacharunderscore}nat\ {\isacharparenleft}Suc\ n{\isacharparenright}\ x\ {\isacharequal}\ x\ {\isasymotimes}\ pow{\isacharunderscore}nat\ n\ x{\isachardoublequoteclose}%
27.820 +\endisatagquote
27.821 +{\isafoldquote}%
27.822 +%
27.823 +\isadelimquote
27.824 +%
27.825 +\endisadelimquote
27.826 +%
27.827 +\begin{isamarkuptext}%
27.828 +\noindent If the locale \isa{group} is also a class, this local
27.829 + definition is propagated onto a global definition of
27.830 + \isa{{\isachardoublequote}pow{\isacharunderscore}nat\ {\isasymColon}\ nat\ {\isasymRightarrow}\ {\isasymalpha}{\isasymColon}monoid\ {\isasymRightarrow}\ {\isasymalpha}{\isasymColon}monoid{\isachardoublequote}}
27.831 + with corresponding theorems
27.832 +
27.833 + \isa{pow{\isacharunderscore}nat\ {\isadigit{0}}\ x\ {\isacharequal}\ {\isasymone}\isasep\isanewline%
27.834 +pow{\isacharunderscore}nat\ {\isacharparenleft}Suc\ n{\isacharparenright}\ x\ {\isacharequal}\ x\ {\isasymotimes}\ pow{\isacharunderscore}nat\ n\ x}.
27.835 +
27.836 + \noindent As you can see from this example, for local
27.837 + definitions you may use any specification tool
27.838 + which works together with locales (e.g. \cite{krauss2006}).%
27.839 +\end{isamarkuptext}%
27.840 +\isamarkuptrue%
27.841 +%
27.842 +\isamarkupsubsection{A functor analogy%
27.843 +}
27.844 +\isamarkuptrue%
27.845 +%
27.846 +\begin{isamarkuptext}%
27.847 +We introduced Isar classes by analogy to type classes
27.848 + functional programming; if we reconsider this in the
27.849 + context of what has been said about type classes and locales,
27.850 + we can drive this analogy further by stating that type
27.851 + classes essentially correspond to functors which have
27.852 + a canonical interpretation as type classes.
27.853 + Anyway, there is also the possibility of other interpretations.
27.854 + For example, also \isa{list}s form a monoid with
27.855 + \isa{append} and \isa{{\isacharbrackleft}{\isacharbrackright}} as operations, but it
27.856 + seems inappropriate to apply to lists
27.857 + the same operations as for genuinely algebraic types.
27.858 + In such a case, we simply can do a particular interpretation
27.859 + of monoids for lists:%
27.860 +\end{isamarkuptext}%
27.861 +\isamarkuptrue%
27.862 +%
27.863 +\isadelimquote
27.864 +%
27.865 +\endisadelimquote
27.866 +%
27.867 +\isatagquote
27.868 +\isacommand{interpretation}\isamarkupfalse%
27.869 +\ list{\isacharunderscore}monoid{\isacharbang}{\isacharcolon}\ monoid\ append\ {\isachardoublequoteopen}{\isacharbrackleft}{\isacharbrackright}{\isachardoublequoteclose}\isanewline
27.870 +\ \ \isacommand{proof}\isamarkupfalse%
27.871 +\ \isacommand{qed}\isamarkupfalse%
27.872 +\ auto%
27.873 +\endisatagquote
27.874 +{\isafoldquote}%
27.875 +%
27.876 +\isadelimquote
27.877 +%
27.878 +\endisadelimquote
27.879 +%
27.880 +\begin{isamarkuptext}%
27.881 +\noindent This enables us to apply facts on monoids
27.882 + to lists, e.g. \isa{{\isacharbrackleft}{\isacharbrackright}\ {\isacharat}\ x\ {\isacharequal}\ x}.
27.883 +
27.884 + When using this interpretation pattern, it may also
27.885 + be appropriate to map derived definitions accordingly:%
27.886 +\end{isamarkuptext}%
27.887 +\isamarkuptrue%
27.888 +%
27.889 +\isadelimquote
27.890 +%
27.891 +\endisadelimquote
27.892 +%
27.893 +\isatagquote
27.894 +\isacommand{primrec}\isamarkupfalse%
27.895 +\ replicate\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymRightarrow}\ {\isasymalpha}\ list\ {\isasymRightarrow}\ {\isasymalpha}\ list{\isachardoublequoteclose}\ \isakeyword{where}\isanewline
27.896 +\ \ {\isachardoublequoteopen}replicate\ {\isadigit{0}}\ {\isacharunderscore}\ {\isacharequal}\ {\isacharbrackleft}{\isacharbrackright}{\isachardoublequoteclose}\isanewline
27.897 +\ \ {\isacharbar}\ {\isachardoublequoteopen}replicate\ {\isacharparenleft}Suc\ n{\isacharparenright}\ xs\ {\isacharequal}\ xs\ {\isacharat}\ replicate\ n\ xs{\isachardoublequoteclose}\isanewline
27.898 +\isanewline
27.899 +\isacommand{interpretation}\isamarkupfalse%
27.900 +\ list{\isacharunderscore}monoid{\isacharbang}{\isacharcolon}\ monoid\ append\ {\isachardoublequoteopen}{\isacharbrackleft}{\isacharbrackright}{\isachardoublequoteclose}\ \isakeyword{where}\isanewline
27.901 +\ \ {\isachardoublequoteopen}monoid{\isachardot}pow{\isacharunderscore}nat\ append\ {\isacharbrackleft}{\isacharbrackright}\ {\isacharequal}\ replicate{\isachardoublequoteclose}\isanewline
27.902 +\isacommand{proof}\isamarkupfalse%
27.903 +\ {\isacharminus}\isanewline
27.904 +\ \ \isacommand{interpret}\isamarkupfalse%
27.905 +\ monoid\ append\ {\isachardoublequoteopen}{\isacharbrackleft}{\isacharbrackright}{\isachardoublequoteclose}\ \isacommand{{\isachardot}{\isachardot}}\isamarkupfalse%
27.906 +\isanewline
27.907 +\ \ \isacommand{show}\isamarkupfalse%
27.908 +\ {\isachardoublequoteopen}monoid{\isachardot}pow{\isacharunderscore}nat\ append\ {\isacharbrackleft}{\isacharbrackright}\ {\isacharequal}\ replicate{\isachardoublequoteclose}\isanewline
27.909 +\ \ \isacommand{proof}\isamarkupfalse%
27.910 +\isanewline
27.911 +\ \ \ \ \isacommand{fix}\isamarkupfalse%
27.912 +\ n\isanewline
27.913 +\ \ \ \ \isacommand{show}\isamarkupfalse%
27.914 +\ {\isachardoublequoteopen}monoid{\isachardot}pow{\isacharunderscore}nat\ append\ {\isacharbrackleft}{\isacharbrackright}\ n\ {\isacharequal}\ replicate\ n{\isachardoublequoteclose}\isanewline
27.915 +\ \ \ \ \ \ \isacommand{by}\isamarkupfalse%
27.916 +\ {\isacharparenleft}induct\ n{\isacharparenright}\ auto\isanewline
27.917 +\ \ \isacommand{qed}\isamarkupfalse%
27.918 +\isanewline
27.919 +\isacommand{qed}\isamarkupfalse%
27.920 +\ intro{\isacharunderscore}locales%
27.921 +\endisatagquote
27.922 +{\isafoldquote}%
27.923 +%
27.924 +\isadelimquote
27.925 +%
27.926 +\endisadelimquote
27.927 +%
27.928 +\isamarkupsubsection{Additional subclass relations%
27.929 +}
27.930 +\isamarkuptrue%
27.931 +%
27.932 +\begin{isamarkuptext}%
27.933 +Any \isa{group} is also a \isa{monoid}; this
27.934 + can be made explicit by claiming an additional
27.935 + subclass relation,
27.936 + together with a proof of the logical difference:%
27.937 +\end{isamarkuptext}%
27.938 +\isamarkuptrue%
27.939 +%
27.940 +\isadelimquote
27.941 +%
27.942 +\endisadelimquote
27.943 +%
27.944 +\isatagquote
27.945 +\isacommand{subclass}\isamarkupfalse%
27.946 +\ {\isacharparenleft}\isakeyword{in}\ group{\isacharparenright}\ monoid\isanewline
27.947 +\isacommand{proof}\isamarkupfalse%
27.948 +\isanewline
27.949 +\ \ \isacommand{fix}\isamarkupfalse%
27.950 +\ x\isanewline
27.951 +\ \ \isacommand{from}\isamarkupfalse%
27.952 +\ invl\ \isacommand{have}\isamarkupfalse%
27.953 +\ {\isachardoublequoteopen}x{\isasymdiv}\ {\isasymotimes}\ x\ {\isacharequal}\ {\isasymone}{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse%
27.954 +\ simp\isanewline
27.955 +\ \ \isacommand{with}\isamarkupfalse%
27.956 +\ assoc\ {\isacharbrackleft}symmetric{\isacharbrackright}\ neutl\ invl\ \isacommand{have}\isamarkupfalse%
27.957 +\ {\isachardoublequoteopen}x{\isasymdiv}\ {\isasymotimes}\ {\isacharparenleft}x\ {\isasymotimes}\ {\isasymone}{\isacharparenright}\ {\isacharequal}\ x{\isasymdiv}\ {\isasymotimes}\ x{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse%
27.958 +\ simp\isanewline
27.959 +\ \ \isacommand{with}\isamarkupfalse%
27.960 +\ left{\isacharunderscore}cancel\ \isacommand{show}\isamarkupfalse%
27.961 +\ {\isachardoublequoteopen}x\ {\isasymotimes}\ {\isasymone}\ {\isacharequal}\ x{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse%
27.962 +\ simp\isanewline
27.963 +\isacommand{qed}\isamarkupfalse%
27.964 +%
27.965 +\endisatagquote
27.966 +{\isafoldquote}%
27.967 +%
27.968 +\isadelimquote
27.969 +%
27.970 +\endisadelimquote
27.971 +%
27.972 +\begin{isamarkuptext}%
27.973 +The logical proof is carried out on the locale level.
27.974 + Afterwards it is propagated
27.975 + to the type system, making \isa{group} an instance of
27.976 + \isa{monoid} by adding an additional edge
27.977 + to the graph of subclass relations
27.978 + (cf.\ \figref{fig:subclass}).
27.979 +
27.980 + \begin{figure}[htbp]
27.981 + \begin{center}
27.982 + \small
27.983 + \unitlength 0.6mm
27.984 + \begin{picture}(40,60)(0,0)
27.985 + \put(20,60){\makebox(0,0){\isa{semigroup}}}
27.986 + \put(20,40){\makebox(0,0){\isa{monoidl}}}
27.987 + \put(00,20){\makebox(0,0){\isa{monoid}}}
27.988 + \put(40,00){\makebox(0,0){\isa{group}}}
27.989 + \put(20,55){\vector(0,-1){10}}
27.990 + \put(15,35){\vector(-1,-1){10}}
27.991 + \put(25,35){\vector(1,-3){10}}
27.992 + \end{picture}
27.993 + \hspace{8em}
27.994 + \begin{picture}(40,60)(0,0)
27.995 + \put(20,60){\makebox(0,0){\isa{semigroup}}}
27.996 + \put(20,40){\makebox(0,0){\isa{monoidl}}}
27.997 + \put(00,20){\makebox(0,0){\isa{monoid}}}
27.998 + \put(40,00){\makebox(0,0){\isa{group}}}
27.999 + \put(20,55){\vector(0,-1){10}}
27.1000 + \put(15,35){\vector(-1,-1){10}}
27.1001 + \put(05,15){\vector(3,-1){30}}
27.1002 + \end{picture}
27.1003 + \caption{Subclass relationship of monoids and groups:
27.1004 + before and after establishing the relationship
27.1005 + \isa{group\ {\isasymsubseteq}\ monoid}; transitive edges are left out.}
27.1006 + \label{fig:subclass}
27.1007 + \end{center}
27.1008 + \end{figure}
27.1009 +
27.1010 + For illustration, a derived definition
27.1011 + in \isa{group} which uses \isa{pow{\isacharunderscore}nat}:%
27.1012 +\end{isamarkuptext}%
27.1013 +\isamarkuptrue%
27.1014 +%
27.1015 +\isadelimquote
27.1016 +%
27.1017 +\endisadelimquote
27.1018 +%
27.1019 +\isatagquote
27.1020 +\isacommand{definition}\isamarkupfalse%
27.1021 +\ {\isacharparenleft}\isakeyword{in}\ group{\isacharparenright}\ pow{\isacharunderscore}int\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}int\ {\isasymRightarrow}\ {\isasymalpha}\ {\isasymRightarrow}\ {\isasymalpha}{\isachardoublequoteclose}\ \isakeyword{where}\isanewline
27.1022 +\ \ {\isachardoublequoteopen}pow{\isacharunderscore}int\ k\ x\ {\isacharequal}\ {\isacharparenleft}if\ k\ {\isachargreater}{\isacharequal}\ {\isadigit{0}}\isanewline
27.1023 +\ \ \ \ then\ pow{\isacharunderscore}nat\ {\isacharparenleft}nat\ k{\isacharparenright}\ x\isanewline
27.1024 +\ \ \ \ else\ {\isacharparenleft}pow{\isacharunderscore}nat\ {\isacharparenleft}nat\ {\isacharparenleft}{\isacharminus}\ k{\isacharparenright}{\isacharparenright}\ x{\isacharparenright}{\isasymdiv}{\isacharparenright}{\isachardoublequoteclose}%
27.1025 +\endisatagquote
27.1026 +{\isafoldquote}%
27.1027 +%
27.1028 +\isadelimquote
27.1029 +%
27.1030 +\endisadelimquote
27.1031 +%
27.1032 +\begin{isamarkuptext}%
27.1033 +\noindent yields the global definition of
27.1034 + \isa{{\isachardoublequote}pow{\isacharunderscore}int\ {\isasymColon}\ int\ {\isasymRightarrow}\ {\isasymalpha}{\isasymColon}group\ {\isasymRightarrow}\ {\isasymalpha}{\isasymColon}group{\isachardoublequote}}
27.1035 + with the corresponding theorem \isa{pow{\isacharunderscore}int\ k\ x\ {\isacharequal}\ {\isacharparenleft}if\ {\isadigit{0}}\ {\isasymle}\ k\ then\ pow{\isacharunderscore}nat\ {\isacharparenleft}nat\ k{\isacharparenright}\ x\ else\ {\isacharparenleft}pow{\isacharunderscore}nat\ {\isacharparenleft}nat\ {\isacharparenleft}{\isacharminus}\ k{\isacharparenright}{\isacharparenright}\ x{\isacharparenright}{\isasymdiv}{\isacharparenright}}.%
27.1036 +\end{isamarkuptext}%
27.1037 +\isamarkuptrue%
27.1038 +%
27.1039 +\isamarkupsubsection{A note on syntax%
27.1040 +}
27.1041 +\isamarkuptrue%
27.1042 +%
27.1043 +\begin{isamarkuptext}%
27.1044 +As a commodity, class context syntax allows to refer
27.1045 + to local class operations and their global counterparts
27.1046 + uniformly; type inference resolves ambiguities. For example:%
27.1047 +\end{isamarkuptext}%
27.1048 +\isamarkuptrue%
27.1049 +%
27.1050 +\isadelimquote
27.1051 +%
27.1052 +\endisadelimquote
27.1053 +%
27.1054 +\isatagquote
27.1055 +\isacommand{context}\isamarkupfalse%
27.1056 +\ semigroup\isanewline
27.1057 +\isakeyword{begin}\isanewline
27.1058 +\isanewline
27.1059 +\isacommand{term}\isamarkupfalse%
27.1060 +\ {\isachardoublequoteopen}x\ {\isasymotimes}\ y{\isachardoublequoteclose}\ %
27.1061 +\isamarkupcmt{example 1%
27.1062 +}
27.1063 +\isanewline
27.1064 +\isacommand{term}\isamarkupfalse%
27.1065 +\ {\isachardoublequoteopen}{\isacharparenleft}x{\isasymColon}nat{\isacharparenright}\ {\isasymotimes}\ y{\isachardoublequoteclose}\ %
27.1066 +\isamarkupcmt{example 2%
27.1067 +}
27.1068 +\isanewline
27.1069 +\isanewline
27.1070 +\isacommand{end}\isamarkupfalse%
27.1071 +\isanewline
27.1072 +\isanewline
27.1073 +\isacommand{term}\isamarkupfalse%
27.1074 +\ {\isachardoublequoteopen}x\ {\isasymotimes}\ y{\isachardoublequoteclose}\ %
27.1075 +\isamarkupcmt{example 3%
27.1076 +}
27.1077 +%
27.1078 +\endisatagquote
27.1079 +{\isafoldquote}%
27.1080 +%
27.1081 +\isadelimquote
27.1082 +%
27.1083 +\endisadelimquote
27.1084 +%
27.1085 +\begin{isamarkuptext}%
27.1086 +\noindent Here in example 1, the term refers to the local class operation
27.1087 + \isa{mult\ {\isacharbrackleft}{\isasymalpha}{\isacharbrackright}}, whereas in example 2 the type constraint
27.1088 + enforces the global class operation \isa{mult\ {\isacharbrackleft}nat{\isacharbrackright}}.
27.1089 + In the global context in example 3, the reference is
27.1090 + to the polymorphic global class operation \isa{mult\ {\isacharbrackleft}{\isacharquery}{\isasymalpha}\ {\isasymColon}\ semigroup{\isacharbrackright}}.%
27.1091 +\end{isamarkuptext}%
27.1092 +\isamarkuptrue%
27.1093 +%
27.1094 +\isamarkupsection{Further issues%
27.1095 +}
27.1096 +\isamarkuptrue%
27.1097 +%
27.1098 +\isamarkupsubsection{Type classes and code generation%
27.1099 +}
27.1100 +\isamarkuptrue%
27.1101 +%
27.1102 +\begin{isamarkuptext}%
27.1103 +Turning back to the first motivation for type classes,
27.1104 + namely overloading, it is obvious that overloading
27.1105 + stemming from \hyperlink{command.class}{\mbox{\isa{\isacommand{class}}}} statements and
27.1106 + \hyperlink{command.instantiation}{\mbox{\isa{\isacommand{instantiation}}}}
27.1107 + targets naturally maps to Haskell type classes.
27.1108 + The code generator framework \cite{isabelle-codegen}
27.1109 + takes this into account. Concerning target languages
27.1110 + lacking type classes (e.g.~SML), type classes
27.1111 + are implemented by explicit dictionary construction.
27.1112 + As example, let's go back to the power function:%
27.1113 +\end{isamarkuptext}%
27.1114 +\isamarkuptrue%
27.1115 +%
27.1116 +\isadelimquote
27.1117 +%
27.1118 +\endisadelimquote
27.1119 +%
27.1120 +\isatagquote
27.1121 +\isacommand{definition}\isamarkupfalse%
27.1122 +\ example\ {\isacharcolon}{\isacharcolon}\ int\ \isakeyword{where}\isanewline
27.1123 +\ \ {\isachardoublequoteopen}example\ {\isacharequal}\ pow{\isacharunderscore}int\ {\isadigit{1}}{\isadigit{0}}\ {\isacharparenleft}{\isacharminus}{\isadigit{2}}{\isacharparenright}{\isachardoublequoteclose}%
27.1124 +\endisatagquote
27.1125 +{\isafoldquote}%
27.1126 +%
27.1127 +\isadelimquote
27.1128 +%
27.1129 +\endisadelimquote
27.1130 +%
27.1131 +\begin{isamarkuptext}%
27.1132 +\noindent This maps to Haskell as:%
27.1133 +\end{isamarkuptext}%
27.1134 +\isamarkuptrue%
27.1135 +%
27.1136 +\isadelimquote
27.1137 +%
27.1138 +\endisadelimquote
27.1139 +%
27.1140 +\isatagquote
27.1141 +%
27.1142 +\begin{isamarkuptext}%
27.1143 +\isatypewriter%
27.1144 +\noindent%
27.1145 +\hspace*{0pt}module Example where {\char123}\\
27.1146 +\hspace*{0pt}\\
27.1147 +\hspace*{0pt}\\
27.1148 +\hspace*{0pt}data Nat = Zero{\char95}nat | Suc Nat;\\
27.1149 +\hspace*{0pt}\\
27.1150 +\hspace*{0pt}nat{\char95}aux ::~Integer -> Nat -> Nat;\\
27.1151 +\hspace*{0pt}nat{\char95}aux i n = (if i <= 0 then n else nat{\char95}aux (i - 1) (Suc n));\\
27.1152 +\hspace*{0pt}\\
27.1153 +\hspace*{0pt}nat ::~Integer -> Nat;\\
27.1154 +\hspace*{0pt}nat i = nat{\char95}aux i Zero{\char95}nat;\\
27.1155 +\hspace*{0pt}\\
27.1156 +\hspace*{0pt}class Semigroup a where {\char123}\\
27.1157 +\hspace*{0pt} ~mult ::~a -> a -> a;\\
27.1158 +\hspace*{0pt}{\char125};\\
27.1159 +\hspace*{0pt}\\
27.1160 +\hspace*{0pt}class (Semigroup a) => Monoidl a where {\char123}\\
27.1161 +\hspace*{0pt} ~neutral ::~a;\\
27.1162 +\hspace*{0pt}{\char125};\\
27.1163 +\hspace*{0pt}\\
27.1164 +\hspace*{0pt}class (Monoidl a) => Monoid a where {\char123}\\
27.1165 +\hspace*{0pt}{\char125};\\
27.1166 +\hspace*{0pt}\\
27.1167 +\hspace*{0pt}class (Monoid a) => Group a where {\char123}\\
27.1168 +\hspace*{0pt} ~inverse ::~a -> a;\\
27.1169 +\hspace*{0pt}{\char125};\\
27.1170 +\hspace*{0pt}\\
27.1171 +\hspace*{0pt}inverse{\char95}int ::~Integer -> Integer;\\
27.1172 +\hspace*{0pt}inverse{\char95}int i = negate i;\\
27.1173 +\hspace*{0pt}\\
27.1174 +\hspace*{0pt}neutral{\char95}int ::~Integer;\\
27.1175 +\hspace*{0pt}neutral{\char95}int = 0;\\
27.1176 +\hspace*{0pt}\\
27.1177 +\hspace*{0pt}mult{\char95}int ::~Integer -> Integer -> Integer;\\
27.1178 +\hspace*{0pt}mult{\char95}int i j = i + j;\\
27.1179 +\hspace*{0pt}\\
27.1180 +\hspace*{0pt}instance Semigroup Integer where {\char123}\\
27.1181 +\hspace*{0pt} ~mult = mult{\char95}int;\\
27.1182 +\hspace*{0pt}{\char125};\\
27.1183 +\hspace*{0pt}\\
27.1184 +\hspace*{0pt}instance Monoidl Integer where {\char123}\\
27.1185 +\hspace*{0pt} ~neutral = neutral{\char95}int;\\
27.1186 +\hspace*{0pt}{\char125};\\
27.1187 +\hspace*{0pt}\\
27.1188 +\hspace*{0pt}instance Monoid Integer where {\char123}\\
27.1189 +\hspace*{0pt}{\char125};\\
27.1190 +\hspace*{0pt}\\
27.1191 +\hspace*{0pt}instance Group Integer where {\char123}\\
27.1192 +\hspace*{0pt} ~inverse = inverse{\char95}int;\\
27.1193 +\hspace*{0pt}{\char125};\\
27.1194 +\hspace*{0pt}\\
27.1195 +\hspace*{0pt}pow{\char95}nat ::~forall a.~(Monoid a) => Nat -> a -> a;\\
27.1196 +\hspace*{0pt}pow{\char95}nat Zero{\char95}nat x = neutral;\\
27.1197 +\hspace*{0pt}pow{\char95}nat (Suc n) x = mult x (pow{\char95}nat n x);\\
27.1198 +\hspace*{0pt}\\
27.1199 +\hspace*{0pt}pow{\char95}int ::~forall a.~(Group a) => Integer -> a -> a;\\
27.1200 +\hspace*{0pt}pow{\char95}int k x =\\
27.1201 +\hspace*{0pt} ~(if 0 <= k then pow{\char95}nat (nat k) x\\
27.1202 +\hspace*{0pt} ~~~else inverse (pow{\char95}nat (nat (negate k)) x));\\
27.1203 +\hspace*{0pt}\\
27.1204 +\hspace*{0pt}example ::~Integer;\\
27.1205 +\hspace*{0pt}example = pow{\char95}int 10 (-2);\\
27.1206 +\hspace*{0pt}\\
27.1207 +\hspace*{0pt}{\char125}%
27.1208 +\end{isamarkuptext}%
27.1209 +\isamarkuptrue%
27.1210 +%
27.1211 +\endisatagquote
27.1212 +{\isafoldquote}%
27.1213 +%
27.1214 +\isadelimquote
27.1215 +%
27.1216 +\endisadelimquote
27.1217 +%
27.1218 +\begin{isamarkuptext}%
27.1219 +\noindent The whole code in SML with explicit dictionary passing:%
27.1220 +\end{isamarkuptext}%
27.1221 +\isamarkuptrue%
27.1222 +%
27.1223 +\isadelimquote
27.1224 +%
27.1225 +\endisadelimquote
27.1226 +%
27.1227 +\isatagquote
27.1228 +%
27.1229 +\begin{isamarkuptext}%
27.1230 +\isatypewriter%
27.1231 +\noindent%
27.1232 +\hspace*{0pt}structure Example = \\
27.1233 +\hspace*{0pt}struct\\
27.1234 +\hspace*{0pt}\\
27.1235 +\hspace*{0pt}datatype nat = Zero{\char95}nat | Suc of nat;\\
27.1236 +\hspace*{0pt}\\
27.1237 +\hspace*{0pt}fun nat{\char95}aux i n =\\
27.1238 +\hspace*{0pt} ~(if IntInf.<= (i,~(0 :~IntInf.int)) then n\\
27.1239 +\hspace*{0pt} ~~~else nat{\char95}aux (IntInf.- (i,~(1 :~IntInf.int))) (Suc n));\\
27.1240 +\hspace*{0pt}\\
27.1241 +\hspace*{0pt}fun nat i = nat{\char95}aux i Zero{\char95}nat;\\
27.1242 +\hspace*{0pt}\\
27.1243 +\hspace*{0pt}type 'a semigroup = {\char123}mult :~'a -> 'a -> 'a{\char125};\\
27.1244 +\hspace*{0pt}fun mult (A{\char95}:'a semigroup) = {\char35}mult A{\char95};\\
27.1245 +\hspace*{0pt}\\
27.1246 +\hspace*{0pt}type 'a monoidl =\\
27.1247 +\hspace*{0pt} ~{\char123}Classes{\char95}{\char95}semigroup{\char95}monoidl :~'a semigroup,~neutral :~'a{\char125};\\
27.1248 +\hspace*{0pt}fun semigroup{\char95}monoidl (A{\char95}:'a monoidl) = {\char35}Classes{\char95}{\char95}semigroup{\char95}monoidl A{\char95};\\
27.1249 +\hspace*{0pt}fun neutral (A{\char95}:'a monoidl) = {\char35}neutral A{\char95};\\
27.1250 +\hspace*{0pt}\\
27.1251 +\hspace*{0pt}type 'a monoid = {\char123}Classes{\char95}{\char95}monoidl{\char95}monoid :~'a monoidl{\char125};\\
27.1252 +\hspace*{0pt}fun monoidl{\char95}monoid (A{\char95}:'a monoid) = {\char35}Classes{\char95}{\char95}monoidl{\char95}monoid A{\char95};\\
27.1253 +\hspace*{0pt}\\
27.1254 +\hspace*{0pt}type 'a group = {\char123}Classes{\char95}{\char95}monoid{\char95}group :~'a monoid,~inverse :~'a -> 'a{\char125};\\
27.1255 +\hspace*{0pt}fun monoid{\char95}group (A{\char95}:'a group) = {\char35}Classes{\char95}{\char95}monoid{\char95}group A{\char95};\\
27.1256 +\hspace*{0pt}fun inverse (A{\char95}:'a group) = {\char35}inverse A{\char95};\\
27.1257 +\hspace*{0pt}\\
27.1258 +\hspace*{0pt}fun inverse{\char95}int i = IntInf.{\char126}~i;\\
27.1259 +\hspace*{0pt}\\
27.1260 +\hspace*{0pt}val neutral{\char95}int :~IntInf.int = (0 :~IntInf.int)\\
27.1261 +\hspace*{0pt}\\
27.1262 +\hspace*{0pt}fun mult{\char95}int i j = IntInf.+ (i,~j);\\
27.1263 +\hspace*{0pt}\\
27.1264 +\hspace*{0pt}val semigroup{\char95}int = {\char123}mult = mult{\char95}int{\char125}~:~IntInf.int semigroup;\\
27.1265 +\hspace*{0pt}\\
27.1266 +\hspace*{0pt}val monoidl{\char95}int =\\
27.1267 +\hspace*{0pt} ~{\char123}Classes{\char95}{\char95}semigroup{\char95}monoidl = semigroup{\char95}int,~neutral = neutral{\char95}int{\char125}~:\\
27.1268 +\hspace*{0pt} ~IntInf.int monoidl;\\
27.1269 +\hspace*{0pt}\\
27.1270 +\hspace*{0pt}val monoid{\char95}int = {\char123}Classes{\char95}{\char95}monoidl{\char95}monoid = monoidl{\char95}int{\char125}~:\\
27.1271 +\hspace*{0pt} ~IntInf.int monoid;\\
27.1272 +\hspace*{0pt}\\
27.1273 +\hspace*{0pt}val group{\char95}int =\\
27.1274 +\hspace*{0pt} ~{\char123}Classes{\char95}{\char95}monoid{\char95}group = monoid{\char95}int,~inverse = inverse{\char95}int{\char125}~:\\
27.1275 +\hspace*{0pt} ~IntInf.int group;\\
27.1276 +\hspace*{0pt}\\
27.1277 +\hspace*{0pt}fun pow{\char95}nat A{\char95}~Zero{\char95}nat x = neutral (monoidl{\char95}monoid A{\char95})\\
27.1278 +\hspace*{0pt} ~| pow{\char95}nat A{\char95}~(Suc n) x =\\
27.1279 +\hspace*{0pt} ~~~mult ((semigroup{\char95}monoidl o monoidl{\char95}monoid) A{\char95}) x (pow{\char95}nat A{\char95}~n x);\\
27.1280 +\hspace*{0pt}\\
27.1281 +\hspace*{0pt}fun pow{\char95}int A{\char95}~k x =\\
27.1282 +\hspace*{0pt} ~(if IntInf.<= ((0 :~IntInf.int),~k)\\
27.1283 +\hspace*{0pt} ~~~then pow{\char95}nat (monoid{\char95}group A{\char95}) (nat k) x\\
27.1284 +\hspace*{0pt} ~~~else inverse A{\char95}~(pow{\char95}nat (monoid{\char95}group A{\char95}) (nat (IntInf.{\char126}~k)) x));\\
27.1285 +\hspace*{0pt}\\
27.1286 +\hspace*{0pt}val example :~IntInf.int =\\
27.1287 +\hspace*{0pt} ~pow{\char95}int group{\char95}int (10 :~IntInf.int) ({\char126}2 :~IntInf.int)\\
27.1288 +\hspace*{0pt}\\
27.1289 +\hspace*{0pt}end;~(*struct Example*)%
27.1290 +\end{isamarkuptext}%
27.1291 +\isamarkuptrue%
27.1292 +%
27.1293 +\endisatagquote
27.1294 +{\isafoldquote}%
27.1295 +%
27.1296 +\isadelimquote
27.1297 +%
27.1298 +\endisadelimquote
27.1299 +%
27.1300 +\isamarkupsubsection{Inspecting the type class universe%
27.1301 +}
27.1302 +\isamarkuptrue%
27.1303 +%
27.1304 +\begin{isamarkuptext}%
27.1305 +To facilitate orientation in complex subclass structures,
27.1306 + two diagnostics commands are provided:
27.1307 +
27.1308 + \begin{description}
27.1309 +
27.1310 + \item[\hyperlink{command.print-classes}{\mbox{\isa{\isacommand{print{\isacharunderscore}classes}}}}] print a list of all classes
27.1311 + together with associated operations etc.
27.1312 +
27.1313 + \item[\hyperlink{command.class-deps}{\mbox{\isa{\isacommand{class{\isacharunderscore}deps}}}}] visualizes the subclass relation
27.1314 + between all classes as a Hasse diagram.
27.1315 +
27.1316 + \end{description}%
27.1317 +\end{isamarkuptext}%
27.1318 +\isamarkuptrue%
27.1319 +%
27.1320 +\isadelimtheory
27.1321 +%
27.1322 +\endisadelimtheory
27.1323 +%
27.1324 +\isatagtheory
27.1325 +\isacommand{end}\isamarkupfalse%
27.1326 +%
27.1327 +\endisatagtheory
27.1328 +{\isafoldtheory}%
27.1329 +%
27.1330 +\isadelimtheory
27.1331 +%
27.1332 +\endisadelimtheory
27.1333 +\isanewline
27.1334 +\end{isabellebody}%
27.1335 +%%% Local Variables:
27.1336 +%%% mode: latex
27.1337 +%%% TeX-master: "root"
27.1338 +%%% End:
28.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
28.2 +++ b/doc-src/Classes/classes.tex Wed Mar 04 11:05:29 2009 +0100
28.3 @@ -0,0 +1,50 @@
28.4 +
28.5 +\documentclass[12pt,a4paper,fleqn]{article}
28.6 +\usepackage{latexsym,graphicx}
28.7 +\usepackage[refpage]{nomencl}
28.8 +\usepackage{../iman,../extra,../isar,../proof}
28.9 +\usepackage{../isabelle,../isabellesym}
28.10 +\usepackage{style}
28.11 +\usepackage{../pdfsetup}
28.12 +
28.13 +
28.14 +\hyphenation{Isabelle}
28.15 +\hyphenation{Isar}
28.16 +\isadroptag{theory}
28.17 +
28.18 +\title{\includegraphics[scale=0.5]{isabelle_isar}
28.19 + \\[4ex] Haskell-style type classes with Isabelle/Isar}
28.20 +\author{\emph{Florian Haftmann}}
28.21 +
28.22 +\begin{document}
28.23 +
28.24 +\maketitle
28.25 +
28.26 +\begin{abstract}
28.27 + \noindent This tutorial introduces the look-and-feel of Isar type classes
28.28 + to the end-user; Isar type classes are a convenient mechanism
28.29 + for organizing specifications, overcoming some drawbacks
28.30 + of raw axiomatic type classes. Essentially, they combine
28.31 + an operational aspect (in the manner of Haskell) with
28.32 + a logical aspect, both managed uniformly.
28.33 +\end{abstract}
28.34 +
28.35 +\thispagestyle{empty}\clearpage
28.36 +
28.37 +\pagenumbering{roman}
28.38 +\clearfirst
28.39 +
28.40 +\input{Thy/document/Classes.tex}
28.41 +
28.42 +\begingroup
28.43 +\bibliographystyle{plain} \small\raggedright\frenchspacing
28.44 +\bibliography{../manual}
28.45 +\endgroup
28.46 +
28.47 +\end{document}
28.48 +
28.49 +
28.50 +%%% Local Variables:
28.51 +%%% mode: latex
28.52 +%%% TeX-master: t
28.53 +%%% End:
29.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
29.2 +++ b/doc-src/Classes/style.sty Wed Mar 04 11:05:29 2009 +0100
29.3 @@ -0,0 +1,48 @@
29.4 +
29.5 +%% toc
29.6 +\newcommand{\tocentry}[1]{\cleardoublepage\phantomsection\addcontentsline{toc}{chapter}{#1}
29.7 +\@mkboth{\MakeUppercase{#1}}{\MakeUppercase{#1}}}
29.8 +
29.9 +%% paragraphs
29.10 +\setlength{\parindent}{1em}
29.11 +
29.12 +%% references
29.13 +\newcommand{\secref}[1]{\S\ref{#1}}
29.14 +\newcommand{\figref}[1]{figure~\ref{#1}}
29.15 +
29.16 +%% logical markup
29.17 +\newcommand{\strong}[1]{{\bfseries {#1}}}
29.18 +\newcommand{\qn}[1]{\emph{#1}}
29.19 +
29.20 +%% typographic conventions
29.21 +\newcommand{\qt}[1]{``{#1}''}
29.22 +
29.23 +%% verbatim text
29.24 +\newcommand{\isatypewriter}{\fontsize{9pt}{0pt}\tt\renewcommand{\baselinestretch}{1}\setlength{\baselineskip}{9pt}}
29.25 +
29.26 +%% quote environment
29.27 +\isakeeptag{quote}
29.28 +\renewenvironment{quote}
29.29 + {\list{}{\leftmargin2em\rightmargin0pt}\parindent0pt\parskip0pt\item\relax}
29.30 + {\endlist}
29.31 +\renewcommand{\isatagquote}{\begin{quote}}
29.32 +\renewcommand{\endisatagquote}{\end{quote}}
29.33 +\newcommand{\quotebreak}{\\[1.2ex]}
29.34 +
29.35 +%% presentation
29.36 +\setcounter{secnumdepth}{2} \setcounter{tocdepth}{2}
29.37 +
29.38 +%% character detail
29.39 +\renewcommand{\isadigit}[1]{\isamath{#1}}
29.40 +\binperiod
29.41 +\underscoreoff
29.42 +
29.43 +%% format
29.44 +\pagestyle{headings}
29.45 +\isabellestyle{it}
29.46 +
29.47 +
29.48 +%%% Local Variables:
29.49 +%%% mode: latex
29.50 +%%% TeX-master: "implementation"
29.51 +%%% End:
30.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
30.2 +++ b/doc-src/Codegen/IsaMakefile Wed Mar 04 11:05:29 2009 +0100
30.3 @@ -0,0 +1,33 @@
30.4 +
30.5 +## targets
30.6 +
30.7 +default: Thy
30.8 +images:
30.9 +test: Thy
30.10 +
30.11 +all: images test
30.12 +
30.13 +
30.14 +## global settings
30.15 +
30.16 +SRC = $(ISABELLE_HOME)/src
30.17 +OUT = $(ISABELLE_OUTPUT)
30.18 +LOG = $(OUT)/log
30.19 +
30.20 +USEDIR = $(ISABELLE_TOOL) usedir -v true -i false -d false -C false -D document
30.21 +
30.22 +
30.23 +## Thy
30.24 +
30.25 +THY = $(LOG)/HOL-Thy.gz
30.26 +
30.27 +Thy: $(THY)
30.28 +
30.29 +$(THY): Thy/ROOT.ML Thy/*.thy ../antiquote_setup.ML ../more_antiquote.ML
30.30 + @$(USEDIR) HOL Thy
30.31 +
30.32 +
30.33 +## clean
30.34 +
30.35 +clean:
30.36 + @rm -f $(THY)
31.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
31.2 +++ b/doc-src/Codegen/Makefile Wed Mar 04 11:05:29 2009 +0100
31.3 @@ -0,0 +1,35 @@
31.4 +
31.5 +## targets
31.6 +
31.7 +default: dvi
31.8 +
31.9 +
31.10 +## dependencies
31.11 +
31.12 +include ../Makefile.in
31.13 +
31.14 +NAME = codegen
31.15 +
31.16 +FILES = $(NAME).tex Thy/document/*.tex \
31.17 + style.sty ../iman.sty ../extra.sty ../isar.sty \
31.18 + ../isabelle.sty ../isabellesym.sty ../pdfsetup.sty \
31.19 + ../manual.bib ../proof.sty
31.20 +
31.21 +dvi: $(NAME).dvi
31.22 +
31.23 +$(NAME).dvi: $(FILES) isabelle_isar.eps codegen_process.ps
31.24 + $(LATEX) $(NAME)
31.25 + $(BIBTEX) $(NAME)
31.26 + $(LATEX) $(NAME)
31.27 + $(LATEX) $(NAME)
31.28 +
31.29 +pdf: $(NAME).pdf
31.30 +
31.31 +$(NAME).pdf: $(FILES) isabelle_isar.pdf codegen_process.pdf
31.32 + $(PDFLATEX) $(NAME)
31.33 + $(BIBTEX) $(NAME)
31.34 + $(PDFLATEX) $(NAME)
31.35 + $(PDFLATEX) $(NAME)
31.36 + $(FIXBOOKMARKS) $(NAME).out
31.37 + $(PDFLATEX) $(NAME)
31.38 + $(PDFLATEX) $(NAME)
32.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
32.2 +++ b/doc-src/Codegen/Thy/Adaption.thy Wed Mar 04 11:05:29 2009 +0100
32.3 @@ -0,0 +1,360 @@
32.4 +theory Adaption
32.5 +imports Setup
32.6 +begin
32.7 +
32.8 +setup %invisible {* Code_Target.extend_target ("\<SML>", ("SML", K I)) *}
32.9 +
32.10 +section {* Adaption to target languages \label{sec:adaption} *}
32.11 +
32.12 +subsection {* Adapting code generation *}
32.13 +
32.14 +text {*
32.15 + The aspects of code generation introduced so far have two aspects
32.16 + in common:
32.17 +
32.18 + \begin{itemize}
32.19 + \item They act uniformly, without reference to a specific
32.20 + target language.
32.21 + \item They are \emph{safe} in the sense that as long as you trust
32.22 + the code generator meta theory and implementation, you cannot
32.23 + produce programs that yield results which are not derivable
32.24 + in the logic.
32.25 + \end{itemize}
32.26 +
32.27 + \noindent In this section we will introduce means to \emph{adapt} the serialiser
32.28 + to a specific target language, i.e.~to print program fragments
32.29 + in a way which accommodates \qt{already existing} ingredients of
32.30 + a target language environment, for three reasons:
32.31 +
32.32 + \begin{itemize}
32.33 + \item improving readability and aesthetics of generated code
32.34 + \item gaining efficiency
32.35 + \item interface with language parts which have no direct counterpart
32.36 + in @{text "HOL"} (say, imperative data structures)
32.37 + \end{itemize}
32.38 +
32.39 + \noindent Generally, you should avoid using those features yourself
32.40 + \emph{at any cost}:
32.41 +
32.42 + \begin{itemize}
32.43 + \item The safe configuration methods act uniformly on every target language,
32.44 + whereas for adaption you have to treat each target language separate.
32.45 + \item Application is extremely tedious since there is no abstraction
32.46 + which would allow for a static check, making it easy to produce garbage.
32.47 + \item More or less subtle errors can be introduced unconsciously.
32.48 + \end{itemize}
32.49 +
32.50 + \noindent However, even if you ought refrain from setting up adaption
32.51 + yourself, already the @{text "HOL"} comes with some reasonable default
32.52 + adaptions (say, using target language list syntax). There also some
32.53 + common adaption cases which you can setup by importing particular
32.54 + library theories. In order to understand these, we provide some clues here;
32.55 + these however are not supposed to replace a careful study of the sources.
32.56 +*}
32.57 +
32.58 +subsection {* The adaption principle *}
32.59 +
32.60 +text {*
32.61 + The following figure illustrates what \qt{adaption} is conceptually
32.62 + supposed to be:
32.63 +
32.64 + \begin{figure}[here]
32.65 + \begin{tikzpicture}[scale = 0.5]
32.66 + \tikzstyle water=[color = blue, thick]
32.67 + \tikzstyle ice=[color = black, very thick, cap = round, join = round, fill = white]
32.68 + \tikzstyle process=[color = green, semithick, ->]
32.69 + \tikzstyle adaption=[color = red, semithick, ->]
32.70 + \tikzstyle target=[color = black]
32.71 + \foreach \x in {0, ..., 24}
32.72 + \draw[style=water] (\x, 0.25) sin + (0.25, 0.25) cos + (0.25, -0.25) sin
32.73 + + (0.25, -0.25) cos + (0.25, 0.25);
32.74 + \draw[style=ice] (1, 0) --
32.75 + (3, 6) node[above, fill=white] {logic} -- (5, 0) -- cycle;
32.76 + \draw[style=ice] (9, 0) --
32.77 + (11, 6) node[above, fill=white] {intermediate language} -- (13, 0) -- cycle;
32.78 + \draw[style=ice] (15, -6) --
32.79 + (19, 6) node[above, fill=white] {target language} -- (23, -6) -- cycle;
32.80 + \draw[style=process]
32.81 + (3.5, 3) .. controls (7, 5) .. node[fill=white] {translation} (10.5, 3);
32.82 + \draw[style=process]
32.83 + (11.5, 3) .. controls (15, 5) .. node[fill=white] (serialisation) {serialisation} (18.5, 3);
32.84 + \node (adaption) at (11, -2) [style=adaption] {adaption};
32.85 + \node at (19, 3) [rotate=90] {generated};
32.86 + \node at (19.5, -5) {language};
32.87 + \node at (19.5, -3) {library};
32.88 + \node (includes) at (19.5, -1) {includes};
32.89 + \node (reserved) at (16.5, -3) [rotate=72] {reserved}; % proper 71.57
32.90 + \draw[style=process]
32.91 + (includes) -- (serialisation);
32.92 + \draw[style=process]
32.93 + (reserved) -- (serialisation);
32.94 + \draw[style=adaption]
32.95 + (adaption) -- (serialisation);
32.96 + \draw[style=adaption]
32.97 + (adaption) -- (includes);
32.98 + \draw[style=adaption]
32.99 + (adaption) -- (reserved);
32.100 + \end{tikzpicture}
32.101 + \caption{The adaption principle}
32.102 + \label{fig:adaption}
32.103 + \end{figure}
32.104 +
32.105 + \noindent In the tame view, code generation acts as broker between
32.106 + @{text logic}, @{text "intermediate language"} and
32.107 + @{text "target language"} by means of @{text translation} and
32.108 + @{text serialisation}; for the latter, the serialiser has to observe
32.109 + the structure of the @{text language} itself plus some @{text reserved}
32.110 + keywords which have to be avoided for generated code.
32.111 + However, if you consider @{text adaption} mechanisms, the code generated
32.112 + by the serializer is just the tip of the iceberg:
32.113 +
32.114 + \begin{itemize}
32.115 + \item @{text serialisation} can be \emph{parametrised} such that
32.116 + logical entities are mapped to target-specific ones
32.117 + (e.g. target-specific list syntax,
32.118 + see also \secref{sec:adaption_mechanisms})
32.119 + \item Such parametrisations can involve references to a
32.120 + target-specific standard @{text library} (e.g. using
32.121 + the @{text Haskell} @{verbatim Maybe} type instead
32.122 + of the @{text HOL} @{type "option"} type);
32.123 + if such are used, the corresponding identifiers
32.124 + (in our example, @{verbatim Maybe}, @{verbatim Nothing}
32.125 + and @{verbatim Just}) also have to be considered @{text reserved}.
32.126 + \item Even more, the user can enrich the library of the
32.127 + target-language by providing code snippets
32.128 + (\qt{@{text "includes"}}) which are prepended to
32.129 + any generated code (see \secref{sec:include}); this typically
32.130 + also involves further @{text reserved} identifiers.
32.131 + \end{itemize}
32.132 +
32.133 + \noindent As figure \ref{fig:adaption} illustrates, all these adaption mechanisms
32.134 + have to act consistently; it is at the discretion of the user
32.135 + to take care for this.
32.136 +*}
32.137 +
32.138 +subsection {* Common adaption patterns *}
32.139 +
32.140 +text {*
32.141 + The @{theory HOL} @{theory Main} theory already provides a code
32.142 + generator setup
32.143 + which should be suitable for most applications. Common extensions
32.144 + and modifications are available by certain theories of the @{text HOL}
32.145 + library; beside being useful in applications, they may serve
32.146 + as a tutorial for customising the code generator setup (see below
32.147 + \secref{sec:adaption_mechanisms}).
32.148 +
32.149 + \begin{description}
32.150 +
32.151 + \item[@{theory "Code_Integer"}] represents @{text HOL} integers by big
32.152 + integer literals in target languages.
32.153 + \item[@{theory "Code_Char"}] represents @{text HOL} characters by
32.154 + character literals in target languages.
32.155 + \item[@{theory "Code_Char_chr"}] like @{text "Code_Char"},
32.156 + but also offers treatment of character codes; includes
32.157 + @{theory "Code_Char"}.
32.158 + \item[@{theory "Efficient_Nat"}] \label{eff_nat} implements natural numbers by integers,
32.159 + which in general will result in higher efficiency; pattern
32.160 + matching with @{term "0\<Colon>nat"} / @{const "Suc"}
32.161 + is eliminated; includes @{theory "Code_Integer"}
32.162 + and @{theory "Code_Index"}.
32.163 + \item[@{theory "Code_Index"}] provides an additional datatype
32.164 + @{typ index} which is mapped to target-language built-in integers.
32.165 + Useful for code setups which involve e.g. indexing of
32.166 + target-language arrays.
32.167 + \item[@{theory "Code_Message"}] provides an additional datatype
32.168 + @{typ message_string} which is isomorphic to strings;
32.169 + @{typ message_string}s are mapped to target-language strings.
32.170 + Useful for code setups which involve e.g. printing (error) messages.
32.171 +
32.172 + \end{description}
32.173 +
32.174 + \begin{warn}
32.175 + When importing any of these theories, they should form the last
32.176 + items in an import list. Since these theories adapt the
32.177 + code generator setup in a non-conservative fashion,
32.178 + strange effects may occur otherwise.
32.179 + \end{warn}
32.180 +*}
32.181 +
32.182 +
32.183 +subsection {* Parametrising serialisation \label{sec:adaption_mechanisms} *}
32.184 +
32.185 +text {*
32.186 + Consider the following function and its corresponding
32.187 + SML code:
32.188 +*}
32.189 +
32.190 +primrec %quote in_interval :: "nat \<times> nat \<Rightarrow> nat \<Rightarrow> bool" where
32.191 + "in_interval (k, l) n \<longleftrightarrow> k \<le> n \<and> n \<le> l"
32.192 +(*<*)
32.193 +code_type %invisible bool
32.194 + (SML)
32.195 +code_const %invisible True and False and "op \<and>" and Not
32.196 + (SML and and and)
32.197 +(*>*)
32.198 +text %quote {*@{code_stmts in_interval (SML)}*}
32.199 +
32.200 +text {*
32.201 + \noindent Though this is correct code, it is a little bit unsatisfactory:
32.202 + boolean values and operators are materialised as distinguished
32.203 + entities with have nothing to do with the SML-built-in notion
32.204 + of \qt{bool}. This results in less readable code;
32.205 + additionally, eager evaluation may cause programs to
32.206 + loop or break which would perfectly terminate when
32.207 + the existing SML @{verbatim "bool"} would be used. To map
32.208 + the HOL @{typ bool} on SML @{verbatim "bool"}, we may use
32.209 + \qn{custom serialisations}:
32.210 +*}
32.211 +
32.212 +code_type %quotett bool
32.213 + (SML "bool")
32.214 +code_const %quotett True and False and "op \<and>"
32.215 + (SML "true" and "false" and "_ andalso _")
32.216 +
32.217 +text {*
32.218 + \noindent The @{command code_type} command takes a type constructor
32.219 + as arguments together with a list of custom serialisations.
32.220 + Each custom serialisation starts with a target language
32.221 + identifier followed by an expression, which during
32.222 + code serialisation is inserted whenever the type constructor
32.223 + would occur. For constants, @{command code_const} implements
32.224 + the corresponding mechanism. Each ``@{verbatim "_"}'' in
32.225 + a serialisation expression is treated as a placeholder
32.226 + for the type constructor's (the constant's) arguments.
32.227 +*}
32.228 +
32.229 +text %quote {*@{code_stmts in_interval (SML)}*}
32.230 +
32.231 +text {*
32.232 + \noindent This still is not perfect: the parentheses
32.233 + around the \qt{andalso} expression are superfluous.
32.234 + Though the serialiser
32.235 + by no means attempts to imitate the rich Isabelle syntax
32.236 + framework, it provides some common idioms, notably
32.237 + associative infixes with precedences which may be used here:
32.238 +*}
32.239 +
32.240 +code_const %quotett "op \<and>"
32.241 + (SML infixl 1 "andalso")
32.242 +
32.243 +text %quote {*@{code_stmts in_interval (SML)}*}
32.244 +
32.245 +text {*
32.246 + \noindent The attentive reader may ask how we assert that no generated
32.247 + code will accidentally overwrite. For this reason the serialiser has
32.248 + an internal table of identifiers which have to be avoided to be used
32.249 + for new declarations. Initially, this table typically contains the
32.250 + keywords of the target language. It can be extended manually, thus avoiding
32.251 + accidental overwrites, using the @{command "code_reserved"} command:
32.252 +*}
32.253 +
32.254 +code_reserved %quote "\<SML>" bool true false andalso
32.255 +
32.256 +text {*
32.257 + \noindent Next, we try to map HOL pairs to SML pairs, using the
32.258 + infix ``@{verbatim "*"}'' type constructor and parentheses:
32.259 +*}
32.260 +(*<*)
32.261 +code_type %invisible *
32.262 + (SML)
32.263 +code_const %invisible Pair
32.264 + (SML)
32.265 +(*>*)
32.266 +code_type %quotett *
32.267 + (SML infix 2 "*")
32.268 +code_const %quotett Pair
32.269 + (SML "!((_),/ (_))")
32.270 +
32.271 +text {*
32.272 + \noindent The initial bang ``@{verbatim "!"}'' tells the serialiser
32.273 + never to put
32.274 + parentheses around the whole expression (they are already present),
32.275 + while the parentheses around argument place holders
32.276 + tell not to put parentheses around the arguments.
32.277 + The slash ``@{verbatim "/"}'' (followed by arbitrary white space)
32.278 + inserts a space which may be used as a break if necessary
32.279 + during pretty printing.
32.280 +
32.281 + These examples give a glimpse what mechanisms
32.282 + custom serialisations provide; however their usage
32.283 + requires careful thinking in order not to introduce
32.284 + inconsistencies -- or, in other words:
32.285 + custom serialisations are completely axiomatic.
32.286 +
32.287 + A further noteworthy details is that any special
32.288 + character in a custom serialisation may be quoted
32.289 + using ``@{verbatim "'"}''; thus, in
32.290 + ``@{verbatim "fn '_ => _"}'' the first
32.291 + ``@{verbatim "_"}'' is a proper underscore while the
32.292 + second ``@{verbatim "_"}'' is a placeholder.
32.293 +*}
32.294 +
32.295 +
32.296 +subsection {* @{text Haskell} serialisation *}
32.297 +
32.298 +text {*
32.299 + For convenience, the default
32.300 + @{text HOL} setup for @{text Haskell} maps the @{class eq} class to
32.301 + its counterpart in @{text Haskell}, giving custom serialisations
32.302 + for the class @{class eq} (by command @{command code_class}) and its operation
32.303 + @{const HOL.eq}
32.304 +*}
32.305 +
32.306 +code_class %quotett eq
32.307 + (Haskell "Eq")
32.308 +
32.309 +code_const %quotett "op ="
32.310 + (Haskell infixl 4 "==")
32.311 +
32.312 +text {*
32.313 + \noindent A problem now occurs whenever a type which
32.314 + is an instance of @{class eq} in @{text HOL} is mapped
32.315 + on a @{text Haskell}-built-in type which is also an instance
32.316 + of @{text Haskell} @{text Eq}:
32.317 +*}
32.318 +
32.319 +typedecl %quote bar
32.320 +
32.321 +instantiation %quote bar :: eq
32.322 +begin
32.323 +
32.324 +definition %quote "eq_class.eq (x\<Colon>bar) y \<longleftrightarrow> x = y"
32.325 +
32.326 +instance %quote by default (simp add: eq_bar_def)
32.327 +
32.328 +end %quote
32.329 +code_type %quotett bar
32.330 + (Haskell "Integer")
32.331 +
32.332 +text {*
32.333 + \noindent The code generator would produce
32.334 + an additional instance, which of course is rejected by the @{text Haskell}
32.335 + compiler.
32.336 + To suppress this additional instance, use
32.337 + @{text "code_instance"}:
32.338 +*}
32.339 +
32.340 +code_instance %quotett bar :: eq
32.341 + (Haskell -)
32.342 +
32.343 +
32.344 +subsection {* Enhancing the target language context \label{sec:include} *}
32.345 +
32.346 +text {*
32.347 + In rare cases it is necessary to \emph{enrich} the context of a
32.348 + target language; this is accomplished using the @{command "code_include"}
32.349 + command:
32.350 +*}
32.351 +
32.352 +code_include %quotett Haskell "Errno"
32.353 +{*errno i = error ("Error number: " ++ show i)*}
32.354 +
32.355 +code_reserved %quotett Haskell Errno
32.356 +
32.357 +text {*
32.358 + \noindent Such named @{text include}s are then prepended to every generated code.
32.359 + Inspect such code in order to find out how @{command "code_include"} behaves
32.360 + with respect to a particular target language.
32.361 +*}
32.362 +
32.363 +end
33.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
33.2 +++ b/doc-src/Codegen/Thy/Further.thy Wed Mar 04 11:05:29 2009 +0100
33.3 @@ -0,0 +1,112 @@
33.4 +theory Further
33.5 +imports Setup
33.6 +begin
33.7 +
33.8 +section {* Further issues \label{sec:further} *}
33.9 +
33.10 +subsection {* Further reading *}
33.11 +
33.12 +text {*
33.13 + Do dive deeper into the issue of code generation, you should visit
33.14 + the Isabelle/Isar Reference Manual \cite{isabelle-isar-ref} which
33.15 + contains exhaustive syntax diagrams.
33.16 +*}
33.17 +
33.18 +subsection {* Modules *}
33.19 +
33.20 +text {*
33.21 + When invoking the @{command export_code} command it is possible to leave
33.22 + out the @{keyword "module_name"} part; then code is distributed over
33.23 + different modules, where the module name space roughly is induced
33.24 + by the @{text Isabelle} theory name space.
33.25 +
33.26 + Then sometimes the awkward situation occurs that dependencies between
33.27 + definitions introduce cyclic dependencies between modules, which in the
33.28 + @{text Haskell} world leaves you to the mercy of the @{text Haskell} implementation
33.29 + you are using, while for @{text SML}/@{text OCaml} code generation is not possible.
33.30 +
33.31 + A solution is to declare module names explicitly.
33.32 + Let use assume the three cyclically dependent
33.33 + modules are named \emph{A}, \emph{B} and \emph{C}.
33.34 + Then, by stating
33.35 +*}
33.36 +
33.37 +code_modulename %quote SML
33.38 + A ABC
33.39 + B ABC
33.40 + C ABC
33.41 +
33.42 +text {*
33.43 + we explicitly map all those modules on \emph{ABC},
33.44 + resulting in an ad-hoc merge of this three modules
33.45 + at serialisation time.
33.46 +*}
33.47 +
33.48 +subsection {* Evaluation oracle *}
33.49 +
33.50 +text {*
33.51 + Code generation may also be used to \emph{evaluate} expressions
33.52 + (using @{text SML} as target language of course).
33.53 + For instance, the @{command value} allows to reduce an expression to a
33.54 + normal form with respect to the underlying code equations:
33.55 +*}
33.56 +
33.57 +value %quote "42 / (12 :: rat)"
33.58 +
33.59 +text {*
33.60 + \noindent will display @{term "7 / (2 :: rat)"}.
33.61 +
33.62 + The @{method eval} method tries to reduce a goal by code generation to @{term True}
33.63 + and solves it in that case, but fails otherwise:
33.64 +*}
33.65 +
33.66 +lemma %quote "42 / (12 :: rat) = 7 / 2"
33.67 + by %quote eval
33.68 +
33.69 +text {*
33.70 + \noindent The soundness of the @{method eval} method depends crucially
33.71 + on the correctness of the code generator; this is one of the reasons
33.72 + why you should not use adaption (see \secref{sec:adaption}) frivolously.
33.73 +*}
33.74 +
33.75 +subsection {* Code antiquotation *}
33.76 +
33.77 +text {*
33.78 + In scenarios involving techniques like reflection it is quite common
33.79 + that code generated from a theory forms the basis for implementing
33.80 + a proof procedure in @{text SML}. To facilitate interfacing of generated code
33.81 + with system code, the code generator provides a @{text code} antiquotation:
33.82 +*}
33.83 +
33.84 +datatype %quote form = T | F | And form form | Or form form
33.85 +ML %quotett {*
33.86 + fun eval_form @{code T} = true
33.87 + | eval_form @{code F} = false
33.88 + | eval_form (@{code And} (p, q)) =
33.89 + eval_form p andalso eval_form q
33.90 + | eval_form (@{code Or} (p, q)) =
33.91 + eval_form p orelse eval_form q;
33.92 +*}
33.93 +
33.94 +text {*
33.95 + \noindent @{text code} takes as argument the name of a constant; after the
33.96 + whole @{text SML} is read, the necessary code is generated transparently
33.97 + and the corresponding constant names are inserted. This technique also
33.98 + allows to use pattern matching on constructors stemming from compiled
33.99 + @{text datatypes}.
33.100 +
33.101 + For a less simplistic example, theory @{theory Ferrack} is
33.102 + a good reference.
33.103 +*}
33.104 +
33.105 +subsection {* Imperative data structures *}
33.106 +
33.107 +text {*
33.108 + If you consider imperative data structures as inevitable for a specific
33.109 + application, you should consider
33.110 + \emph{Imperative Functional Programming with Isabelle/HOL}
33.111 + (\cite{bulwahn-et-al:2008:imperative});
33.112 + the framework described there is available in theory @{theory Imperative_HOL}.
33.113 +*}
33.114 +
33.115 +end
34.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
34.2 +++ b/doc-src/Codegen/Thy/Introduction.thy Wed Mar 04 11:05:29 2009 +0100
34.3 @@ -0,0 +1,204 @@
34.4 +theory Introduction
34.5 +imports Setup
34.6 +begin
34.7 +
34.8 +section {* Introduction and Overview *}
34.9 +
34.10 +text {*
34.11 + This tutorial introduces a generic code generator for the
34.12 + @{text Isabelle} system.
34.13 + Generic in the sense that the
34.14 + \qn{target language} for which code shall ultimately be
34.15 + generated is not fixed but may be an arbitrary state-of-the-art
34.16 + functional programming language (currently, the implementation
34.17 + supports @{text SML} \cite{SML}, @{text OCaml} \cite{OCaml} and @{text Haskell}
34.18 + \cite{haskell-revised-report}).
34.19 +
34.20 + Conceptually the code generator framework is part
34.21 + of Isabelle's @{theory Pure} meta logic framework; the logic
34.22 + @{theory HOL} which is an extension of @{theory Pure}
34.23 + already comes with a reasonable framework setup and thus provides
34.24 + a good working horse for raising code-generation-driven
34.25 + applications. So, we assume some familiarity and experience
34.26 + with the ingredients of the @{theory HOL} distribution theories.
34.27 + (see also \cite{isa-tutorial}).
34.28 +
34.29 + The code generator aims to be usable with no further ado
34.30 + in most cases while allowing for detailed customisation.
34.31 + This manifests in the structure of this tutorial: after a short
34.32 + conceptual introduction with an example (\secref{sec:intro}),
34.33 + we discuss the generic customisation facilities (\secref{sec:program}).
34.34 + A further section (\secref{sec:adaption}) is dedicated to the matter of
34.35 + \qn{adaption} to specific target language environments. After some
34.36 + further issues (\secref{sec:further}) we conclude with an overview
34.37 + of some ML programming interfaces (\secref{sec:ml}).
34.38 +
34.39 + \begin{warn}
34.40 + Ultimately, the code generator which this tutorial deals with
34.41 + is supposed to replace the existing code generator
34.42 + by Stefan Berghofer \cite{Berghofer-Nipkow:2002}.
34.43 + So, for the moment, there are two distinct code generators
34.44 + in Isabelle. In case of ambiguity, we will refer to the framework
34.45 + described here as @{text "generic code generator"}, to the
34.46 + other as @{text "SML code generator"}.
34.47 + Also note that while the framework itself is
34.48 + object-logic independent, only @{theory HOL} provides a reasonable
34.49 + framework setup.
34.50 + \end{warn}
34.51 +
34.52 +*}
34.53 +
34.54 +subsection {* Code generation via shallow embedding \label{sec:intro} *}
34.55 +
34.56 +text {*
34.57 + The key concept for understanding @{text Isabelle}'s code generation is
34.58 + \emph{shallow embedding}, i.e.~logical entities like constants, types and
34.59 + classes are identified with corresponding concepts in the target language.
34.60 +
34.61 + Inside @{theory HOL}, the @{command datatype} and
34.62 + @{command definition}/@{command primrec}/@{command fun} declarations form
34.63 + the core of a functional programming language. The default code generator setup
34.64 + allows to turn those into functional programs immediately.
34.65 + This means that \qt{naive} code generation can proceed without further ado.
34.66 + For example, here a simple \qt{implementation} of amortised queues:
34.67 +*}
34.68 +
34.69 +datatype %quote 'a queue = AQueue "'a list" "'a list"
34.70 +
34.71 +definition %quote empty :: "'a queue" where
34.72 + "empty = AQueue [] []"
34.73 +
34.74 +primrec %quote enqueue :: "'a \<Rightarrow> 'a queue \<Rightarrow> 'a queue" where
34.75 + "enqueue x (AQueue xs ys) = AQueue (x # xs) ys"
34.76 +
34.77 +fun %quote dequeue :: "'a queue \<Rightarrow> 'a option \<times> 'a queue" where
34.78 + "dequeue (AQueue [] []) = (None, AQueue [] [])"
34.79 + | "dequeue (AQueue xs (y # ys)) = (Some y, AQueue xs ys)"
34.80 + | "dequeue (AQueue xs []) =
34.81 + (case rev xs of y # ys \<Rightarrow> (Some y, AQueue [] ys))"
34.82 +
34.83 +text {* \noindent Then we can generate code e.g.~for @{text SML} as follows: *}
34.84 +
34.85 +export_code %quote empty dequeue enqueue in SML
34.86 + module_name Example file "examples/example.ML"
34.87 +
34.88 +text {* \noindent resulting in the following code: *}
34.89 +
34.90 +text %quote {*@{code_stmts empty enqueue dequeue (SML)}*}
34.91 +
34.92 +text {*
34.93 + \noindent The @{command export_code} command takes a space-separated list of
34.94 + constants for which code shall be generated; anything else needed for those
34.95 + is added implicitly. Then follows a target language identifier
34.96 + (@{text SML}, @{text OCaml} or @{text Haskell}) and a freely chosen module name.
34.97 + A file name denotes the destination to store the generated code. Note that
34.98 + the semantics of the destination depends on the target language: for
34.99 + @{text SML} and @{text OCaml} it denotes a \emph{file}, for @{text Haskell}
34.100 + it denotes a \emph{directory} where a file named as the module name
34.101 + (with extension @{text ".hs"}) is written:
34.102 +*}
34.103 +
34.104 +export_code %quote empty dequeue enqueue in Haskell
34.105 + module_name Example file "examples/"
34.106 +
34.107 +text {*
34.108 + \noindent This is how the corresponding code in @{text Haskell} looks like:
34.109 +*}
34.110 +
34.111 +text %quote {*@{code_stmts empty enqueue dequeue (Haskell)}*}
34.112 +
34.113 +text {*
34.114 + \noindent This demonstrates the basic usage of the @{command export_code} command;
34.115 + for more details see \secref{sec:further}.
34.116 +*}
34.117 +
34.118 +subsection {* Code generator architecture \label{sec:concept} *}
34.119 +
34.120 +text {*
34.121 + What you have seen so far should be already enough in a lot of cases. If you
34.122 + are content with this, you can quit reading here. Anyway, in order to customise
34.123 + and adapt the code generator, it is inevitable to gain some understanding
34.124 + how it works.
34.125 +
34.126 + \begin{figure}[h]
34.127 + \begin{tikzpicture}[x = 4.2cm, y = 1cm]
34.128 + \tikzstyle entity=[rounded corners, draw, thick, color = black, fill = white];
34.129 + \tikzstyle process=[ellipse, draw, thick, color = green, fill = white];
34.130 + \tikzstyle process_arrow=[->, semithick, color = green];
34.131 + \node (HOL) at (0, 4) [style=entity] {@{text "Isabelle/HOL"} theory};
34.132 + \node (eqn) at (2, 2) [style=entity] {code equations};
34.133 + \node (iml) at (2, 0) [style=entity] {intermediate language};
34.134 + \node (seri) at (1, 0) [style=process] {serialisation};
34.135 + \node (SML) at (0, 3) [style=entity] {@{text SML}};
34.136 + \node (OCaml) at (0, 2) [style=entity] {@{text OCaml}};
34.137 + \node (further) at (0, 1) [style=entity] {@{text "\<dots>"}};
34.138 + \node (Haskell) at (0, 0) [style=entity] {@{text Haskell}};
34.139 + \draw [style=process_arrow] (HOL) .. controls (2, 4) ..
34.140 + node [style=process, near start] {selection}
34.141 + node [style=process, near end] {preprocessing}
34.142 + (eqn);
34.143 + \draw [style=process_arrow] (eqn) -- node (transl) [style=process] {translation} (iml);
34.144 + \draw [style=process_arrow] (iml) -- (seri);
34.145 + \draw [style=process_arrow] (seri) -- (SML);
34.146 + \draw [style=process_arrow] (seri) -- (OCaml);
34.147 + \draw [style=process_arrow, dashed] (seri) -- (further);
34.148 + \draw [style=process_arrow] (seri) -- (Haskell);
34.149 + \end{tikzpicture}
34.150 + \caption{Code generator architecture}
34.151 + \label{fig:arch}
34.152 + \end{figure}
34.153 +
34.154 + The code generator employs a notion of executability
34.155 + for three foundational executable ingredients known
34.156 + from functional programming:
34.157 + \emph{code equations}, \emph{datatypes}, and
34.158 + \emph{type classes}. A code equation as a first approximation
34.159 + is a theorem of the form @{text "f t\<^isub>1 t\<^isub>2 \<dots> t\<^isub>n \<equiv> t"}
34.160 + (an equation headed by a constant @{text f} with arguments
34.161 + @{text "t\<^isub>1 t\<^isub>2 \<dots> t\<^isub>n"} and right hand side @{text t}).
34.162 + Code generation aims to turn code equations
34.163 + into a functional program. This is achieved by three major
34.164 + components which operate sequentially, i.e. the result of one is
34.165 + the input
34.166 + of the next in the chain, see diagram \ref{fig:arch}:
34.167 +
34.168 + \begin{itemize}
34.169 +
34.170 + \item Out of the vast collection of theorems proven in a
34.171 + \qn{theory}, a reasonable subset modelling
34.172 + code equations is \qn{selected}.
34.173 +
34.174 + \item On those selected theorems, certain
34.175 + transformations are carried out
34.176 + (\qn{preprocessing}). Their purpose is to turn theorems
34.177 + representing non- or badly executable
34.178 + specifications into equivalent but executable counterparts.
34.179 + The result is a structured collection of \qn{code theorems}.
34.180 +
34.181 + \item Before the selected code equations are continued with,
34.182 + they can be \qn{preprocessed}, i.e. subjected to theorem
34.183 + transformations. This \qn{preprocessor} is an interface which
34.184 + allows to apply
34.185 + the full expressiveness of ML-based theorem transformations
34.186 + to code generation; motivating examples are shown below, see
34.187 + \secref{sec:preproc}.
34.188 + The result of the preprocessing step is a structured collection
34.189 + of code equations.
34.190 +
34.191 + \item These code equations are \qn{translated} to a program
34.192 + in an abstract intermediate language. Think of it as a kind
34.193 + of \qt{Mini-Haskell} with four \qn{statements}: @{text data}
34.194 + (for datatypes), @{text fun} (stemming from code equations),
34.195 + also @{text class} and @{text inst} (for type classes).
34.196 +
34.197 + \item Finally, the abstract program is \qn{serialised} into concrete
34.198 + source code of a target language.
34.199 +
34.200 + \end{itemize}
34.201 +
34.202 + \noindent From these steps, only the two last are carried out outside the logic; by
34.203 + keeping this layer as thin as possible, the amount of code to trust is
34.204 + kept to a minimum.
34.205 +*}
34.206 +
34.207 +end
35.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
35.2 +++ b/doc-src/Codegen/Thy/ML.thy Wed Mar 04 11:05:29 2009 +0100
35.3 @@ -0,0 +1,177 @@
35.4 +theory "ML"
35.5 +imports Setup
35.6 +begin
35.7 +
35.8 +section {* ML system interfaces \label{sec:ml} *}
35.9 +
35.10 +text {*
35.11 + Since the code generator framework not only aims to provide
35.12 + a nice Isar interface but also to form a base for
35.13 + code-generation-based applications, here a short
35.14 + description of the most important ML interfaces.
35.15 +*}
35.16 +
35.17 +subsection {* Executable theory content: @{text Code} *}
35.18 +
35.19 +text {*
35.20 + This Pure module implements the core notions of
35.21 + executable content of a theory.
35.22 +*}
35.23 +
35.24 +subsubsection {* Managing executable content *}
35.25 +
35.26 +text %mlref {*
35.27 + \begin{mldecls}
35.28 + @{index_ML Code.add_eqn: "thm -> theory -> theory"} \\
35.29 + @{index_ML Code.del_eqn: "thm -> theory -> theory"} \\
35.30 + @{index_ML Code.add_eqnl: "string * (thm * bool) list lazy -> theory -> theory"} \\
35.31 + @{index_ML Code.map_pre: "(simpset -> simpset) -> theory -> theory"} \\
35.32 + @{index_ML Code.map_post: "(simpset -> simpset) -> theory -> theory"} \\
35.33 + @{index_ML Code.add_functrans: "string * (theory -> (thm * bool) list -> (thm * bool) list option)
35.34 + -> theory -> theory"} \\
35.35 + @{index_ML Code.del_functrans: "string -> theory -> theory"} \\
35.36 + @{index_ML Code.add_datatype: "(string * typ) list -> theory -> theory"} \\
35.37 + @{index_ML Code.get_datatype: "theory -> string
35.38 + -> (string * sort) list * (string * typ list) list"} \\
35.39 + @{index_ML Code.get_datatype_of_constr: "theory -> string -> string option"}
35.40 + \end{mldecls}
35.41 +
35.42 + \begin{description}
35.43 +
35.44 + \item @{ML Code.add_eqn}~@{text "thm"}~@{text "thy"} adds function
35.45 + theorem @{text "thm"} to executable content.
35.46 +
35.47 + \item @{ML Code.del_eqn}~@{text "thm"}~@{text "thy"} removes function
35.48 + theorem @{text "thm"} from executable content, if present.
35.49 +
35.50 + \item @{ML Code.add_eqnl}~@{text "(const, lthms)"}~@{text "thy"} adds
35.51 + suspended code equations @{text lthms} for constant
35.52 + @{text const} to executable content.
35.53 +
35.54 + \item @{ML Code.map_pre}~@{text "f"}~@{text "thy"} changes
35.55 + the preprocessor simpset.
35.56 +
35.57 + \item @{ML Code.add_functrans}~@{text "(name, f)"}~@{text "thy"} adds
35.58 + function transformer @{text f} (named @{text name}) to executable content;
35.59 + @{text f} is a transformer of the code equations belonging
35.60 + to a certain function definition, depending on the
35.61 + current theory context. Returning @{text NONE} indicates that no
35.62 + transformation took place; otherwise, the whole process will be iterated
35.63 + with the new code equations.
35.64 +
35.65 + \item @{ML Code.del_functrans}~@{text "name"}~@{text "thy"} removes
35.66 + function transformer named @{text name} from executable content.
35.67 +
35.68 + \item @{ML Code.add_datatype}~@{text cs}~@{text thy} adds
35.69 + a datatype to executable content, with generation
35.70 + set @{text cs}.
35.71 +
35.72 + \item @{ML Code.get_datatype_of_constr}~@{text "thy"}~@{text "const"}
35.73 + returns type constructor corresponding to
35.74 + constructor @{text const}; returns @{text NONE}
35.75 + if @{text const} is no constructor.
35.76 +
35.77 + \end{description}
35.78 +*}
35.79 +
35.80 +subsection {* Auxiliary *}
35.81 +
35.82 +text %mlref {*
35.83 + \begin{mldecls}
35.84 + @{index_ML Code_Unit.read_const: "theory -> string -> string"} \\
35.85 + @{index_ML Code_Unit.head_eqn: "theory -> thm -> string * ((string * sort) list * typ)"} \\
35.86 + @{index_ML Code_Unit.rewrite_eqn: "simpset -> thm -> thm"} \\
35.87 + \end{mldecls}
35.88 +
35.89 + \begin{description}
35.90 +
35.91 + \item @{ML Code_Unit.read_const}~@{text thy}~@{text s}
35.92 + reads a constant as a concrete term expression @{text s}.
35.93 +
35.94 + \item @{ML Code_Unit.head_eqn}~@{text thy}~@{text thm}
35.95 + extracts the constant and its type from a code equation @{text thm}.
35.96 +
35.97 + \item @{ML Code_Unit.rewrite_eqn}~@{text ss}~@{text thm}
35.98 + rewrites a code equation @{text thm} with a simpset @{text ss};
35.99 + only arguments and right hand side are rewritten,
35.100 + not the head of the code equation.
35.101 +
35.102 + \end{description}
35.103 +
35.104 +*}
35.105 +
35.106 +subsection {* Implementing code generator applications *}
35.107 +
35.108 +text {*
35.109 + Implementing code generator applications on top
35.110 + of the framework set out so far usually not only
35.111 + involves using those primitive interfaces
35.112 + but also storing code-dependent data and various
35.113 + other things.
35.114 +*}
35.115 +
35.116 +subsubsection {* Data depending on the theory's executable content *}
35.117 +
35.118 +text {*
35.119 + Due to incrementality of code generation, changes in the
35.120 + theory's executable content have to be propagated in a
35.121 + certain fashion. Additionally, such changes may occur
35.122 + not only during theory extension but also during theory
35.123 + merge, which is a little bit nasty from an implementation
35.124 + point of view. The framework provides a solution
35.125 + to this technical challenge by providing a functorial
35.126 + data slot @{ML_functor CodeDataFun}; on instantiation
35.127 + of this functor, the following types and operations
35.128 + are required:
35.129 +
35.130 + \medskip
35.131 + \begin{tabular}{l}
35.132 + @{text "type T"} \\
35.133 + @{text "val empty: T"} \\
35.134 + @{text "val purge: theory \<rightarrow> string list option \<rightarrow> T \<rightarrow> T"}
35.135 + \end{tabular}
35.136 +
35.137 + \begin{description}
35.138 +
35.139 + \item @{text T} the type of data to store.
35.140 +
35.141 + \item @{text empty} initial (empty) data.
35.142 +
35.143 + \item @{text purge}~@{text thy}~@{text consts} propagates changes in executable content;
35.144 + @{text consts} indicates the kind
35.145 + of change: @{ML NONE} stands for a fundamental change
35.146 + which invalidates any existing code, @{text "SOME consts"}
35.147 + hints that executable content for constants @{text consts}
35.148 + has changed.
35.149 +
35.150 + \end{description}
35.151 +
35.152 + \noindent An instance of @{ML_functor CodeDataFun} provides the following
35.153 + interface:
35.154 +
35.155 + \medskip
35.156 + \begin{tabular}{l}
35.157 + @{text "get: theory \<rightarrow> T"} \\
35.158 + @{text "change: theory \<rightarrow> (T \<rightarrow> T) \<rightarrow> T"} \\
35.159 + @{text "change_yield: theory \<rightarrow> (T \<rightarrow> 'a * T) \<rightarrow> 'a * T"}
35.160 + \end{tabular}
35.161 +
35.162 + \begin{description}
35.163 +
35.164 + \item @{text get} retrieval of the current data.
35.165 +
35.166 + \item @{text change} update of current data (cached!)
35.167 + by giving a continuation.
35.168 +
35.169 + \item @{text change_yield} update with side result.
35.170 +
35.171 + \end{description}
35.172 +*}
35.173 +
35.174 +text {*
35.175 + \bigskip
35.176 +
35.177 + \emph{Happy proving, happy hacking!}
35.178 +*}
35.179 +
35.180 +end
36.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
36.2 +++ b/doc-src/Codegen/Thy/Program.thy Wed Mar 04 11:05:29 2009 +0100
36.3 @@ -0,0 +1,526 @@
36.4 +theory Program
36.5 +imports Introduction
36.6 +begin
36.7 +
36.8 +section {* Turning Theories into Programs \label{sec:program} *}
36.9 +
36.10 +subsection {* The @{text "Isabelle/HOL"} default setup *}
36.11 +
36.12 +text {*
36.13 + We have already seen how by default equations stemming from
36.14 + @{command definition}/@{command primrec}/@{command fun}
36.15 + statements are used for code generation. This default behaviour
36.16 + can be changed, e.g. by providing different code equations.
36.17 + All kinds of customisation shown in this section is \emph{safe}
36.18 + in the sense that the user does not have to worry about
36.19 + correctness -- all programs generatable that way are partially
36.20 + correct.
36.21 +*}
36.22 +
36.23 +subsection {* Selecting code equations *}
36.24 +
36.25 +text {*
36.26 + Coming back to our introductory example, we
36.27 + could provide an alternative code equations for @{const dequeue}
36.28 + explicitly:
36.29 +*}
36.30 +
36.31 +lemma %quote [code]:
36.32 + "dequeue (AQueue xs []) =
36.33 + (if xs = [] then (None, AQueue [] [])
36.34 + else dequeue (AQueue [] (rev xs)))"
36.35 + "dequeue (AQueue xs (y # ys)) =
36.36 + (Some y, AQueue xs ys)"
36.37 + by (cases xs, simp_all) (cases "rev xs", simp_all)
36.38 +
36.39 +text {*
36.40 + \noindent The annotation @{text "[code]"} is an @{text Isar}
36.41 + @{text attribute} which states that the given theorems should be
36.42 + considered as code equations for a @{text fun} statement --
36.43 + the corresponding constant is determined syntactically. The resulting code:
36.44 +*}
36.45 +
36.46 +text %quote {*@{code_stmts dequeue (consts) dequeue (Haskell)}*}
36.47 +
36.48 +text {*
36.49 + \noindent You may note that the equality test @{term "xs = []"} has been
36.50 + replaced by the predicate @{term "null xs"}. This is due to the default
36.51 + setup in the \qn{preprocessor} to be discussed further below (\secref{sec:preproc}).
36.52 +
36.53 + Changing the default constructor set of datatypes is also
36.54 + possible. See \secref{sec:datatypes} for an example.
36.55 +
36.56 + As told in \secref{sec:concept}, code generation is based
36.57 + on a structured collection of code theorems.
36.58 + For explorative purpose, this collection
36.59 + may be inspected using the @{command code_thms} command:
36.60 +*}
36.61 +
36.62 +code_thms %quote dequeue
36.63 +
36.64 +text {*
36.65 + \noindent prints a table with \emph{all} code equations
36.66 + for @{const dequeue}, including
36.67 + \emph{all} code equations those equations depend
36.68 + on recursively.
36.69 +
36.70 + Similarly, the @{command code_deps} command shows a graph
36.71 + visualising dependencies between code equations.
36.72 +*}
36.73 +
36.74 +subsection {* @{text class} and @{text instantiation} *}
36.75 +
36.76 +text {*
36.77 + Concerning type classes and code generation, let us examine an example
36.78 + from abstract algebra:
36.79 +*}
36.80 +
36.81 +class %quote semigroup =
36.82 + fixes mult :: "'a \<Rightarrow> 'a \<Rightarrow> 'a" (infixl "\<otimes>" 70)
36.83 + assumes assoc: "(x \<otimes> y) \<otimes> z = x \<otimes> (y \<otimes> z)"
36.84 +
36.85 +class %quote monoid = semigroup +
36.86 + fixes neutral :: 'a ("\<one>")
36.87 + assumes neutl: "\<one> \<otimes> x = x"
36.88 + and neutr: "x \<otimes> \<one> = x"
36.89 +
36.90 +instantiation %quote nat :: monoid
36.91 +begin
36.92 +
36.93 +primrec %quote mult_nat where
36.94 + "0 \<otimes> n = (0\<Colon>nat)"
36.95 + | "Suc m \<otimes> n = n + m \<otimes> n"
36.96 +
36.97 +definition %quote neutral_nat where
36.98 + "\<one> = Suc 0"
36.99 +
36.100 +lemma %quote add_mult_distrib:
36.101 + fixes n m q :: nat
36.102 + shows "(n + m) \<otimes> q = n \<otimes> q + m \<otimes> q"
36.103 + by (induct n) simp_all
36.104 +
36.105 +instance %quote proof
36.106 + fix m n q :: nat
36.107 + show "m \<otimes> n \<otimes> q = m \<otimes> (n \<otimes> q)"
36.108 + by (induct m) (simp_all add: add_mult_distrib)
36.109 + show "\<one> \<otimes> n = n"
36.110 + by (simp add: neutral_nat_def)
36.111 + show "m \<otimes> \<one> = m"
36.112 + by (induct m) (simp_all add: neutral_nat_def)
36.113 +qed
36.114 +
36.115 +end %quote
36.116 +
36.117 +text {*
36.118 + \noindent We define the natural operation of the natural numbers
36.119 + on monoids:
36.120 +*}
36.121 +
36.122 +primrec %quote (in monoid) pow :: "nat \<Rightarrow> 'a \<Rightarrow> 'a" where
36.123 + "pow 0 a = \<one>"
36.124 + | "pow (Suc n) a = a \<otimes> pow n a"
36.125 +
36.126 +text {*
36.127 + \noindent This we use to define the discrete exponentiation function:
36.128 +*}
36.129 +
36.130 +definition %quote bexp :: "nat \<Rightarrow> nat" where
36.131 + "bexp n = pow n (Suc (Suc 0))"
36.132 +
36.133 +text {*
36.134 + \noindent The corresponding code:
36.135 +*}
36.136 +
36.137 +text %quote {*@{code_stmts bexp (Haskell)}*}
36.138 +
36.139 +text {*
36.140 + \noindent This is a convenient place to show how explicit dictionary construction
36.141 + manifests in generated code (here, the same example in @{text SML}):
36.142 +*}
36.143 +
36.144 +text %quote {*@{code_stmts bexp (SML)}*}
36.145 +
36.146 +text {*
36.147 + \noindent Note the parameters with trailing underscore (@{verbatim "A_"})
36.148 + which are the dictionary parameters.
36.149 +*}
36.150 +
36.151 +subsection {* The preprocessor \label{sec:preproc} *}
36.152 +
36.153 +text {*
36.154 + Before selected function theorems are turned into abstract
36.155 + code, a chain of definitional transformation steps is carried
36.156 + out: \emph{preprocessing}. In essence, the preprocessor
36.157 + consists of two components: a \emph{simpset} and \emph{function transformers}.
36.158 +
36.159 + The \emph{simpset} allows to employ the full generality of the Isabelle
36.160 + simplifier. Due to the interpretation of theorems
36.161 + as code equations, rewrites are applied to the right
36.162 + hand side and the arguments of the left hand side of an
36.163 + equation, but never to the constant heading the left hand side.
36.164 + An important special case are \emph{inline theorems} which may be
36.165 + declared and undeclared using the
36.166 + \emph{code inline} or \emph{code inline del} attribute respectively.
36.167 +
36.168 + Some common applications:
36.169 +*}
36.170 +
36.171 +text_raw {*
36.172 + \begin{itemize}
36.173 +*}
36.174 +
36.175 +text {*
36.176 + \item replacing non-executable constructs by executable ones:
36.177 +*}
36.178 +
36.179 +lemma %quote [code inline]:
36.180 + "x \<in> set xs \<longleftrightarrow> x mem xs" by (induct xs) simp_all
36.181 +
36.182 +text {*
36.183 + \item eliminating superfluous constants:
36.184 +*}
36.185 +
36.186 +lemma %quote [code inline]:
36.187 + "1 = Suc 0" by simp
36.188 +
36.189 +text {*
36.190 + \item replacing executable but inconvenient constructs:
36.191 +*}
36.192 +
36.193 +lemma %quote [code inline]:
36.194 + "xs = [] \<longleftrightarrow> List.null xs" by (induct xs) simp_all
36.195 +
36.196 +text_raw {*
36.197 + \end{itemize}
36.198 +*}
36.199 +
36.200 +text {*
36.201 + \noindent \emph{Function transformers} provide a very general interface,
36.202 + transforming a list of function theorems to another
36.203 + list of function theorems, provided that neither the heading
36.204 + constant nor its type change. The @{term "0\<Colon>nat"} / @{const Suc}
36.205 + pattern elimination implemented in
36.206 + theory @{text Efficient_Nat} (see \secref{eff_nat}) uses this
36.207 + interface.
36.208 +
36.209 + \noindent The current setup of the preprocessor may be inspected using
36.210 + the @{command print_codesetup} command.
36.211 + @{command code_thms} provides a convenient
36.212 + mechanism to inspect the impact of a preprocessor setup
36.213 + on code equations.
36.214 +
36.215 + \begin{warn}
36.216 + The attribute \emph{code unfold}
36.217 + associated with the @{text "SML code generator"} also applies to
36.218 + the @{text "generic code generator"}:
36.219 + \emph{code unfold} implies \emph{code inline}.
36.220 + \end{warn}
36.221 +*}
36.222 +
36.223 +subsection {* Datatypes \label{sec:datatypes} *}
36.224 +
36.225 +text {*
36.226 + Conceptually, any datatype is spanned by a set of
36.227 + \emph{constructors} of type @{text "\<tau> = \<dots> \<Rightarrow> \<kappa> \<alpha>\<^isub>1 \<dots> \<alpha>\<^isub>n"} where @{text
36.228 + "{\<alpha>\<^isub>1, \<dots>, \<alpha>\<^isub>n}"} is exactly the set of \emph{all} type variables in
36.229 + @{text "\<tau>"}. The HOL datatype package by default registers any new
36.230 + datatype in the table of datatypes, which may be inspected using the
36.231 + @{command print_codesetup} command.
36.232 +
36.233 + In some cases, it is appropriate to alter or extend this table. As
36.234 + an example, we will develop an alternative representation of the
36.235 + queue example given in \secref{sec:intro}. The amortised
36.236 + representation is convenient for generating code but exposes its
36.237 + \qt{implementation} details, which may be cumbersome when proving
36.238 + theorems about it. Therefore, here a simple, straightforward
36.239 + representation of queues:
36.240 +*}
36.241 +
36.242 +datatype %quote 'a queue = Queue "'a list"
36.243 +
36.244 +definition %quote empty :: "'a queue" where
36.245 + "empty = Queue []"
36.246 +
36.247 +primrec %quote enqueue :: "'a \<Rightarrow> 'a queue \<Rightarrow> 'a queue" where
36.248 + "enqueue x (Queue xs) = Queue (xs @ [x])"
36.249 +
36.250 +fun %quote dequeue :: "'a queue \<Rightarrow> 'a option \<times> 'a queue" where
36.251 + "dequeue (Queue []) = (None, Queue [])"
36.252 + | "dequeue (Queue (x # xs)) = (Some x, Queue xs)"
36.253 +
36.254 +text {*
36.255 + \noindent This we can use directly for proving; for executing,
36.256 + we provide an alternative characterisation:
36.257 +*}
36.258 +
36.259 +definition %quote AQueue :: "'a list \<Rightarrow> 'a list \<Rightarrow> 'a queue" where
36.260 + "AQueue xs ys = Queue (ys @ rev xs)"
36.261 +
36.262 +code_datatype %quote AQueue
36.263 +
36.264 +text {*
36.265 + \noindent Here we define a \qt{constructor} @{const "AQueue"} which
36.266 + is defined in terms of @{text "Queue"} and interprets its arguments
36.267 + according to what the \emph{content} of an amortised queue is supposed
36.268 + to be. Equipped with this, we are able to prove the following equations
36.269 + for our primitive queue operations which \qt{implement} the simple
36.270 + queues in an amortised fashion:
36.271 +*}
36.272 +
36.273 +lemma %quote empty_AQueue [code]:
36.274 + "empty = AQueue [] []"
36.275 + unfolding AQueue_def empty_def by simp
36.276 +
36.277 +lemma %quote enqueue_AQueue [code]:
36.278 + "enqueue x (AQueue xs ys) = AQueue (x # xs) ys"
36.279 + unfolding AQueue_def by simp
36.280 +
36.281 +lemma %quote dequeue_AQueue [code]:
36.282 + "dequeue (AQueue xs []) =
36.283 + (if xs = [] then (None, AQueue [] [])
36.284 + else dequeue (AQueue [] (rev xs)))"
36.285 + "dequeue (AQueue xs (y # ys)) = (Some y, AQueue xs ys)"
36.286 + unfolding AQueue_def by simp_all
36.287 +
36.288 +text {*
36.289 + \noindent For completeness, we provide a substitute for the
36.290 + @{text case} combinator on queues:
36.291 +*}
36.292 +
36.293 +lemma %quote queue_case_AQueue [code]:
36.294 + "queue_case f (AQueue xs ys) = f (ys @ rev xs)"
36.295 + unfolding AQueue_def by simp
36.296 +
36.297 +text {*
36.298 + \noindent The resulting code looks as expected:
36.299 +*}
36.300 +
36.301 +text %quote {*@{code_stmts empty enqueue dequeue (SML)}*}
36.302 +
36.303 +text {*
36.304 + \noindent From this example, it can be glimpsed that using own
36.305 + constructor sets is a little delicate since it changes the set of
36.306 + valid patterns for values of that type. Without going into much
36.307 + detail, here some practical hints:
36.308 +
36.309 + \begin{itemize}
36.310 +
36.311 + \item When changing the constructor set for datatypes, take care
36.312 + to provide alternative equations for the @{text case} combinator.
36.313 +
36.314 + \item Values in the target language need not to be normalised --
36.315 + different values in the target language may represent the same
36.316 + value in the logic.
36.317 +
36.318 + \item Usually, a good methodology to deal with the subtleties of
36.319 + pattern matching is to see the type as an abstract type: provide
36.320 + a set of operations which operate on the concrete representation
36.321 + of the type, and derive further operations by combinations of
36.322 + these primitive ones, without relying on a particular
36.323 + representation.
36.324 +
36.325 + \end{itemize}
36.326 +*}
36.327 +
36.328 +
36.329 +subsection {* Equality and wellsortedness *}
36.330 +
36.331 +text {*
36.332 + Surely you have already noticed how equality is treated
36.333 + by the code generator:
36.334 +*}
36.335 +
36.336 +primrec %quote collect_duplicates :: "'a list \<Rightarrow> 'a list \<Rightarrow> 'a list \<Rightarrow> 'a list" where
36.337 + "collect_duplicates xs ys [] = xs"
36.338 + | "collect_duplicates xs ys (z#zs) = (if z \<in> set xs
36.339 + then if z \<in> set ys
36.340 + then collect_duplicates xs ys zs
36.341 + else collect_duplicates xs (z#ys) zs
36.342 + else collect_duplicates (z#xs) (z#ys) zs)"
36.343 +
36.344 +text {*
36.345 + \noindent The membership test during preprocessing is rewritten,
36.346 + resulting in @{const List.member}, which itself
36.347 + performs an explicit equality check.
36.348 +*}
36.349 +
36.350 +text %quote {*@{code_stmts collect_duplicates (SML)}*}
36.351 +
36.352 +text {*
36.353 + \noindent Obviously, polymorphic equality is implemented the Haskell
36.354 + way using a type class. How is this achieved? HOL introduces
36.355 + an explicit class @{class eq} with a corresponding operation
36.356 + @{const eq_class.eq} such that @{thm eq [no_vars]}.
36.357 + The preprocessing framework does the rest by propagating the
36.358 + @{class eq} constraints through all dependent code equations.
36.359 + For datatypes, instances of @{class eq} are implicitly derived
36.360 + when possible. For other types, you may instantiate @{text eq}
36.361 + manually like any other type class.
36.362 +
36.363 + Though this @{text eq} class is designed to get rarely in
36.364 + the way, a subtlety
36.365 + enters the stage when definitions of overloaded constants
36.366 + are dependent on operational equality. For example, let
36.367 + us define a lexicographic ordering on tuples
36.368 + (also see theory @{theory Product_ord}):
36.369 +*}
36.370 +
36.371 +instantiation %quote "*" :: (order, order) order
36.372 +begin
36.373 +
36.374 +definition %quote [code del]:
36.375 + "x \<le> y \<longleftrightarrow> fst x < fst y \<or> fst x = fst y \<and> snd x \<le> snd y"
36.376 +
36.377 +definition %quote [code del]:
36.378 + "x < y \<longleftrightarrow> fst x < fst y \<or> fst x = fst y \<and> snd x < snd y"
36.379 +
36.380 +instance %quote proof
36.381 +qed (auto simp: less_eq_prod_def less_prod_def intro: order_less_trans)
36.382 +
36.383 +end %quote
36.384 +
36.385 +lemma %quote order_prod [code]:
36.386 + "(x1 \<Colon> 'a\<Colon>order, y1 \<Colon> 'b\<Colon>order) < (x2, y2) \<longleftrightarrow>
36.387 + x1 < x2 \<or> x1 = x2 \<and> y1 < y2"
36.388 + "(x1 \<Colon> 'a\<Colon>order, y1 \<Colon> 'b\<Colon>order) \<le> (x2, y2) \<longleftrightarrow>
36.389 + x1 < x2 \<or> x1 = x2 \<and> y1 \<le> y2"
36.390 + by (simp_all add: less_prod_def less_eq_prod_def)
36.391 +
36.392 +text {*
36.393 + \noindent Then code generation will fail. Why? The definition
36.394 + of @{term "op \<le>"} depends on equality on both arguments,
36.395 + which are polymorphic and impose an additional @{class eq}
36.396 + class constraint, which the preprocessor does not propagate
36.397 + (for technical reasons).
36.398 +
36.399 + The solution is to add @{class eq} explicitly to the first sort arguments in the
36.400 + code theorems:
36.401 +*}
36.402 +
36.403 +lemma %quote order_prod_code [code]:
36.404 + "(x1 \<Colon> 'a\<Colon>{order, eq}, y1 \<Colon> 'b\<Colon>order) < (x2, y2) \<longleftrightarrow>
36.405 + x1 < x2 \<or> x1 = x2 \<and> y1 < y2"
36.406 + "(x1 \<Colon> 'a\<Colon>{order, eq}, y1 \<Colon> 'b\<Colon>order) \<le> (x2, y2) \<longleftrightarrow>
36.407 + x1 < x2 \<or> x1 = x2 \<and> y1 \<le> y2"
36.408 + by (simp_all add: less_prod_def less_eq_prod_def)
36.409 +
36.410 +text {*
36.411 + \noindent Then code generation succeeds:
36.412 +*}
36.413 +
36.414 +text %quote {*@{code_stmts "op \<le> \<Colon> _ \<times> _ \<Rightarrow> _ \<times> _ \<Rightarrow> bool" (SML)}*}
36.415 +
36.416 +text {*
36.417 + In some cases, the automatically derived code equations
36.418 + for equality on a particular type may not be appropriate.
36.419 + As example, watch the following datatype representing
36.420 + monomorphic parametric types (where type constructors
36.421 + are referred to by natural numbers):
36.422 +*}
36.423 +
36.424 +datatype %quote monotype = Mono nat "monotype list"
36.425 +(*<*)
36.426 +lemma monotype_eq:
36.427 + "eq_class.eq (Mono tyco1 typargs1) (Mono tyco2 typargs2) \<equiv>
36.428 + eq_class.eq tyco1 tyco2 \<and> eq_class.eq typargs1 typargs2" by (simp add: eq)
36.429 +(*>*)
36.430 +
36.431 +text {*
36.432 + \noindent Then code generation for SML would fail with a message
36.433 + that the generated code contains illegal mutual dependencies:
36.434 + the theorem @{thm monotype_eq [no_vars]} already requires the
36.435 + instance @{text "monotype \<Colon> eq"}, which itself requires
36.436 + @{thm monotype_eq [no_vars]}; Haskell has no problem with mutually
36.437 + recursive @{text instance} and @{text function} definitions,
36.438 + but the SML serialiser does not support this.
36.439 +
36.440 + In such cases, you have to provide your own equality equations
36.441 + involving auxiliary constants. In our case,
36.442 + @{const [show_types] list_all2} can do the job:
36.443 +*}
36.444 +
36.445 +lemma %quote monotype_eq_list_all2 [code]:
36.446 + "eq_class.eq (Mono tyco1 typargs1) (Mono tyco2 typargs2) \<longleftrightarrow>
36.447 + eq_class.eq tyco1 tyco2 \<and> list_all2 eq_class.eq typargs1 typargs2"
36.448 + by (simp add: eq list_all2_eq [symmetric])
36.449 +
36.450 +text {*
36.451 + \noindent does not depend on instance @{text "monotype \<Colon> eq"}:
36.452 +*}
36.453 +
36.454 +text %quote {*@{code_stmts "eq_class.eq :: monotype \<Rightarrow> monotype \<Rightarrow> bool" (SML)}*}
36.455 +
36.456 +
36.457 +subsection {* Explicit partiality *}
36.458 +
36.459 +text {*
36.460 + Partiality usually enters the game by partial patterns, as
36.461 + in the following example, again for amortised queues:
36.462 +*}
36.463 +
36.464 +definition %quote strict_dequeue :: "'a queue \<Rightarrow> 'a \<times> 'a queue" where
36.465 + "strict_dequeue q = (case dequeue q
36.466 + of (Some x, q') \<Rightarrow> (x, q'))"
36.467 +
36.468 +lemma %quote strict_dequeue_AQueue [code]:
36.469 + "strict_dequeue (AQueue xs (y # ys)) = (y, AQueue xs ys)"
36.470 + "strict_dequeue (AQueue xs []) =
36.471 + (case rev xs of y # ys \<Rightarrow> (y, AQueue [] ys))"
36.472 + by (simp_all add: strict_dequeue_def dequeue_AQueue split: list.splits)
36.473 +
36.474 +text {*
36.475 + \noindent In the corresponding code, there is no equation
36.476 + for the pattern @{term "AQueue [] []"}:
36.477 +*}
36.478 +
36.479 +text %quote {*@{code_stmts strict_dequeue (consts) strict_dequeue (Haskell)}*}
36.480 +
36.481 +text {*
36.482 + \noindent In some cases it is desirable to have this
36.483 + pseudo-\qt{partiality} more explicitly, e.g.~as follows:
36.484 +*}
36.485 +
36.486 +axiomatization %quote empty_queue :: 'a
36.487 +
36.488 +definition %quote strict_dequeue' :: "'a queue \<Rightarrow> 'a \<times> 'a queue" where
36.489 + "strict_dequeue' q = (case dequeue q of (Some x, q') \<Rightarrow> (x, q') | _ \<Rightarrow> empty_queue)"
36.490 +
36.491 +lemma %quote strict_dequeue'_AQueue [code]:
36.492 + "strict_dequeue' (AQueue xs []) = (if xs = [] then empty_queue
36.493 + else strict_dequeue' (AQueue [] (rev xs)))"
36.494 + "strict_dequeue' (AQueue xs (y # ys)) =
36.495 + (y, AQueue xs ys)"
36.496 + by (simp_all add: strict_dequeue'_def dequeue_AQueue split: list.splits)
36.497 +
36.498 +text {*
36.499 + Observe that on the right hand side of the definition of @{const
36.500 + "strict_dequeue'"} the constant @{const empty_queue} occurs
36.501 + which is unspecified.
36.502 +
36.503 + Normally, if constants without any code equations occur in a
36.504 + program, the code generator complains (since in most cases this is
36.505 + not what the user expects). But such constants can also be thought
36.506 + of as function definitions with no equations which always fail,
36.507 + since there is never a successful pattern match on the left hand
36.508 + side. In order to categorise a constant into that category
36.509 + explicitly, use @{command "code_abort"}:
36.510 +*}
36.511 +
36.512 +code_abort %quote empty_queue
36.513 +
36.514 +text {*
36.515 + \noindent Then the code generator will just insert an error or
36.516 + exception at the appropriate position:
36.517 +*}
36.518 +
36.519 +text %quote {*@{code_stmts strict_dequeue' (consts) empty_queue strict_dequeue' (Haskell)}*}
36.520 +
36.521 +text {*
36.522 + \noindent This feature however is rarely needed in practice.
36.523 + Note also that the @{text HOL} default setup already declares
36.524 + @{const undefined} as @{command "code_abort"}, which is most
36.525 + likely to be used in such situations.
36.526 +*}
36.527 +
36.528 +end
36.529 +
36.530 \ No newline at end of file
37.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
37.2 +++ b/doc-src/Codegen/Thy/ROOT.ML Wed Mar 04 11:05:29 2009 +0100
37.3 @@ -0,0 +1,11 @@
37.4 +
37.5 +(* $Id$ *)
37.6 +
37.7 +no_document use_thy "Setup";
37.8 +no_document use_thys ["Efficient_Nat"];
37.9 +
37.10 +use_thy "Introduction";
37.11 +use_thy "Program";
37.12 +use_thy "Adaption";
37.13 +use_thy "Further";
37.14 +use_thy "ML";
38.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
38.2 +++ b/doc-src/Codegen/Thy/Setup.thy Wed Mar 04 11:05:29 2009 +0100
38.3 @@ -0,0 +1,15 @@
38.4 +theory Setup
38.5 +imports Complex_Main
38.6 +uses
38.7 + "../../antiquote_setup.ML"
38.8 + "../../more_antiquote.ML"
38.9 +begin
38.10 +
38.11 +ML {* no_document use_thys
38.12 + ["Efficient_Nat", "Code_Char_chr", "Product_ord", "~~/src/HOL/Imperative_HOL/Imperative_HOL",
38.13 + "~~/src/HOL/Decision_Procs/Ferrack"] *}
38.14 +
38.15 +ML_command {* Code_Target.code_width := 74 *}
38.16 +ML_command {* reset unique_names *}
38.17 +
38.18 +end
39.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
39.2 +++ b/doc-src/Codegen/Thy/document/Adaption.tex Wed Mar 04 11:05:29 2009 +0100
39.3 @@ -0,0 +1,678 @@
39.4 +%
39.5 +\begin{isabellebody}%
39.6 +\def\isabellecontext{Adaption}%
39.7 +%
39.8 +\isadelimtheory
39.9 +%
39.10 +\endisadelimtheory
39.11 +%
39.12 +\isatagtheory
39.13 +\isacommand{theory}\isamarkupfalse%
39.14 +\ Adaption\isanewline
39.15 +\isakeyword{imports}\ Setup\isanewline
39.16 +\isakeyword{begin}%
39.17 +\endisatagtheory
39.18 +{\isafoldtheory}%
39.19 +%
39.20 +\isadelimtheory
39.21 +\isanewline
39.22 +%
39.23 +\endisadelimtheory
39.24 +%
39.25 +\isadeliminvisible
39.26 +\isanewline
39.27 +%
39.28 +\endisadeliminvisible
39.29 +%
39.30 +\isataginvisible
39.31 +\isacommand{setup}\isamarkupfalse%
39.32 +\ {\isacharverbatimopen}\ Code{\isacharunderscore}Target{\isachardot}extend{\isacharunderscore}target\ {\isacharparenleft}{\isachardoublequote}{\isasymSML}{\isachardoublequote}{\isacharcomma}\ {\isacharparenleft}{\isachardoublequote}SML{\isachardoublequote}{\isacharcomma}\ K\ I{\isacharparenright}{\isacharparenright}\ {\isacharverbatimclose}%
39.33 +\endisataginvisible
39.34 +{\isafoldinvisible}%
39.35 +%
39.36 +\isadeliminvisible
39.37 +%
39.38 +\endisadeliminvisible
39.39 +%
39.40 +\isamarkupsection{Adaption to target languages \label{sec:adaption}%
39.41 +}
39.42 +\isamarkuptrue%
39.43 +%
39.44 +\isamarkupsubsection{Adapting code generation%
39.45 +}
39.46 +\isamarkuptrue%
39.47 +%
39.48 +\begin{isamarkuptext}%
39.49 +The aspects of code generation introduced so far have two aspects
39.50 + in common:
39.51 +
39.52 + \begin{itemize}
39.53 + \item They act uniformly, without reference to a specific
39.54 + target language.
39.55 + \item They are \emph{safe} in the sense that as long as you trust
39.56 + the code generator meta theory and implementation, you cannot
39.57 + produce programs that yield results which are not derivable
39.58 + in the logic.
39.59 + \end{itemize}
39.60 +
39.61 + \noindent In this section we will introduce means to \emph{adapt} the serialiser
39.62 + to a specific target language, i.e.~to print program fragments
39.63 + in a way which accommodates \qt{already existing} ingredients of
39.64 + a target language environment, for three reasons:
39.65 +
39.66 + \begin{itemize}
39.67 + \item improving readability and aesthetics of generated code
39.68 + \item gaining efficiency
39.69 + \item interface with language parts which have no direct counterpart
39.70 + in \isa{HOL} (say, imperative data structures)
39.71 + \end{itemize}
39.72 +
39.73 + \noindent Generally, you should avoid using those features yourself
39.74 + \emph{at any cost}:
39.75 +
39.76 + \begin{itemize}
39.77 + \item The safe configuration methods act uniformly on every target language,
39.78 + whereas for adaption you have to treat each target language separate.
39.79 + \item Application is extremely tedious since there is no abstraction
39.80 + which would allow for a static check, making it easy to produce garbage.
39.81 + \item More or less subtle errors can be introduced unconsciously.
39.82 + \end{itemize}
39.83 +
39.84 + \noindent However, even if you ought refrain from setting up adaption
39.85 + yourself, already the \isa{HOL} comes with some reasonable default
39.86 + adaptions (say, using target language list syntax). There also some
39.87 + common adaption cases which you can setup by importing particular
39.88 + library theories. In order to understand these, we provide some clues here;
39.89 + these however are not supposed to replace a careful study of the sources.%
39.90 +\end{isamarkuptext}%
39.91 +\isamarkuptrue%
39.92 +%
39.93 +\isamarkupsubsection{The adaption principle%
39.94 +}
39.95 +\isamarkuptrue%
39.96 +%
39.97 +\begin{isamarkuptext}%
39.98 +The following figure illustrates what \qt{adaption} is conceptually
39.99 + supposed to be:
39.100 +
39.101 + \begin{figure}[here]
39.102 + \begin{tikzpicture}[scale = 0.5]
39.103 + \tikzstyle water=[color = blue, thick]
39.104 + \tikzstyle ice=[color = black, very thick, cap = round, join = round, fill = white]
39.105 + \tikzstyle process=[color = green, semithick, ->]
39.106 + \tikzstyle adaption=[color = red, semithick, ->]
39.107 + \tikzstyle target=[color = black]
39.108 + \foreach \x in {0, ..., 24}
39.109 + \draw[style=water] (\x, 0.25) sin + (0.25, 0.25) cos + (0.25, -0.25) sin
39.110 + + (0.25, -0.25) cos + (0.25, 0.25);
39.111 + \draw[style=ice] (1, 0) --
39.112 + (3, 6) node[above, fill=white] {logic} -- (5, 0) -- cycle;
39.113 + \draw[style=ice] (9, 0) --
39.114 + (11, 6) node[above, fill=white] {intermediate language} -- (13, 0) -- cycle;
39.115 + \draw[style=ice] (15, -6) --
39.116 + (19, 6) node[above, fill=white] {target language} -- (23, -6) -- cycle;
39.117 + \draw[style=process]
39.118 + (3.5, 3) .. controls (7, 5) .. node[fill=white] {translation} (10.5, 3);
39.119 + \draw[style=process]
39.120 + (11.5, 3) .. controls (15, 5) .. node[fill=white] (serialisation) {serialisation} (18.5, 3);
39.121 + \node (adaption) at (11, -2) [style=adaption] {adaption};
39.122 + \node at (19, 3) [rotate=90] {generated};
39.123 + \node at (19.5, -5) {language};
39.124 + \node at (19.5, -3) {library};
39.125 + \node (includes) at (19.5, -1) {includes};
39.126 + \node (reserved) at (16.5, -3) [rotate=72] {reserved}; % proper 71.57
39.127 + \draw[style=process]
39.128 + (includes) -- (serialisation);
39.129 + \draw[style=process]
39.130 + (reserved) -- (serialisation);
39.131 + \draw[style=adaption]
39.132 + (adaption) -- (serialisation);
39.133 + \draw[style=adaption]
39.134 + (adaption) -- (includes);
39.135 + \draw[style=adaption]
39.136 + (adaption) -- (reserved);
39.137 + \end{tikzpicture}
39.138 + \caption{The adaption principle}
39.139 + \label{fig:adaption}
39.140 + \end{figure}
39.141 +
39.142 + \noindent In the tame view, code generation acts as broker between
39.143 + \isa{logic}, \isa{intermediate\ language} and
39.144 + \isa{target\ language} by means of \isa{translation} and
39.145 + \isa{serialisation}; for the latter, the serialiser has to observe
39.146 + the structure of the \isa{language} itself plus some \isa{reserved}
39.147 + keywords which have to be avoided for generated code.
39.148 + However, if you consider \isa{adaption} mechanisms, the code generated
39.149 + by the serializer is just the tip of the iceberg:
39.150 +
39.151 + \begin{itemize}
39.152 + \item \isa{serialisation} can be \emph{parametrised} such that
39.153 + logical entities are mapped to target-specific ones
39.154 + (e.g. target-specific list syntax,
39.155 + see also \secref{sec:adaption_mechanisms})
39.156 + \item Such parametrisations can involve references to a
39.157 + target-specific standard \isa{library} (e.g. using
39.158 + the \isa{Haskell} \verb|Maybe| type instead
39.159 + of the \isa{HOL} \isa{option} type);
39.160 + if such are used, the corresponding identifiers
39.161 + (in our example, \verb|Maybe|, \verb|Nothing|
39.162 + and \verb|Just|) also have to be considered \isa{reserved}.
39.163 + \item Even more, the user can enrich the library of the
39.164 + target-language by providing code snippets
39.165 + (\qt{\isa{includes}}) which are prepended to
39.166 + any generated code (see \secref{sec:include}); this typically
39.167 + also involves further \isa{reserved} identifiers.
39.168 + \end{itemize}
39.169 +
39.170 + \noindent As figure \ref{fig:adaption} illustrates, all these adaption mechanisms
39.171 + have to act consistently; it is at the discretion of the user
39.172 + to take care for this.%
39.173 +\end{isamarkuptext}%
39.174 +\isamarkuptrue%
39.175 +%
39.176 +\isamarkupsubsection{Common adaption patterns%
39.177 +}
39.178 +\isamarkuptrue%
39.179 +%
39.180 +\begin{isamarkuptext}%
39.181 +The \hyperlink{theory.HOL}{\mbox{\isa{HOL}}} \hyperlink{theory.Main}{\mbox{\isa{Main}}} theory already provides a code
39.182 + generator setup
39.183 + which should be suitable for most applications. Common extensions
39.184 + and modifications are available by certain theories of the \isa{HOL}
39.185 + library; beside being useful in applications, they may serve
39.186 + as a tutorial for customising the code generator setup (see below
39.187 + \secref{sec:adaption_mechanisms}).
39.188 +
39.189 + \begin{description}
39.190 +
39.191 + \item[\hyperlink{theory.Code-Integer}{\mbox{\isa{Code{\isacharunderscore}Integer}}}] represents \isa{HOL} integers by big
39.192 + integer literals in target languages.
39.193 + \item[\hyperlink{theory.Code-Char}{\mbox{\isa{Code{\isacharunderscore}Char}}}] represents \isa{HOL} characters by
39.194 + character literals in target languages.
39.195 + \item[\hyperlink{theory.Code-Char-chr}{\mbox{\isa{Code{\isacharunderscore}Char{\isacharunderscore}chr}}}] like \isa{Code{\isacharunderscore}Char},
39.196 + but also offers treatment of character codes; includes
39.197 + \hyperlink{theory.Code-Char}{\mbox{\isa{Code{\isacharunderscore}Char}}}.
39.198 + \item[\hyperlink{theory.Efficient-Nat}{\mbox{\isa{Efficient{\isacharunderscore}Nat}}}] \label{eff_nat} implements natural numbers by integers,
39.199 + which in general will result in higher efficiency; pattern
39.200 + matching with \isa{{\isadigit{0}}} / \isa{Suc}
39.201 + is eliminated; includes \hyperlink{theory.Code-Integer}{\mbox{\isa{Code{\isacharunderscore}Integer}}}
39.202 + and \hyperlink{theory.Code-Index}{\mbox{\isa{Code{\isacharunderscore}Index}}}.
39.203 + \item[\hyperlink{theory.Code-Index}{\mbox{\isa{Code{\isacharunderscore}Index}}}] provides an additional datatype
39.204 + \isa{index} which is mapped to target-language built-in integers.
39.205 + Useful for code setups which involve e.g. indexing of
39.206 + target-language arrays.
39.207 + \item[\hyperlink{theory.Code-Message}{\mbox{\isa{Code{\isacharunderscore}Message}}}] provides an additional datatype
39.208 + \isa{message{\isacharunderscore}string} which is isomorphic to strings;
39.209 + \isa{message{\isacharunderscore}string}s are mapped to target-language strings.
39.210 + Useful for code setups which involve e.g. printing (error) messages.
39.211 +
39.212 + \end{description}
39.213 +
39.214 + \begin{warn}
39.215 + When importing any of these theories, they should form the last
39.216 + items in an import list. Since these theories adapt the
39.217 + code generator setup in a non-conservative fashion,
39.218 + strange effects may occur otherwise.
39.219 + \end{warn}%
39.220 +\end{isamarkuptext}%
39.221 +\isamarkuptrue%
39.222 +%
39.223 +\isamarkupsubsection{Parametrising serialisation \label{sec:adaption_mechanisms}%
39.224 +}
39.225 +\isamarkuptrue%
39.226 +%
39.227 +\begin{isamarkuptext}%
39.228 +Consider the following function and its corresponding
39.229 + SML code:%
39.230 +\end{isamarkuptext}%
39.231 +\isamarkuptrue%
39.232 +%
39.233 +\isadelimquote
39.234 +%
39.235 +\endisadelimquote
39.236 +%
39.237 +\isatagquote
39.238 +\isacommand{primrec}\isamarkupfalse%
39.239 +\ in{\isacharunderscore}interval\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymtimes}\ nat\ {\isasymRightarrow}\ nat\ {\isasymRightarrow}\ bool{\isachardoublequoteclose}\ \isakeyword{where}\isanewline
39.240 +\ \ {\isachardoublequoteopen}in{\isacharunderscore}interval\ {\isacharparenleft}k{\isacharcomma}\ l{\isacharparenright}\ n\ {\isasymlongleftrightarrow}\ k\ {\isasymle}\ n\ {\isasymand}\ n\ {\isasymle}\ l{\isachardoublequoteclose}%
39.241 +\endisatagquote
39.242 +{\isafoldquote}%
39.243 +%
39.244 +\isadelimquote
39.245 +%
39.246 +\endisadelimquote
39.247 +%
39.248 +\isadeliminvisible
39.249 +%
39.250 +\endisadeliminvisible
39.251 +%
39.252 +\isataginvisible
39.253 +%
39.254 +\endisataginvisible
39.255 +{\isafoldinvisible}%
39.256 +%
39.257 +\isadeliminvisible
39.258 +%
39.259 +\endisadeliminvisible
39.260 +%
39.261 +\isadelimquote
39.262 +%
39.263 +\endisadelimquote
39.264 +%
39.265 +\isatagquote
39.266 +%
39.267 +\begin{isamarkuptext}%
39.268 +\isatypewriter%
39.269 +\noindent%
39.270 +\hspace*{0pt}structure Example = \\
39.271 +\hspace*{0pt}struct\\
39.272 +\hspace*{0pt}\\
39.273 +\hspace*{0pt}datatype nat = Zero{\char95}nat | Suc of nat;\\
39.274 +\hspace*{0pt}\\
39.275 +\hspace*{0pt}datatype boola = True | False;\\
39.276 +\hspace*{0pt}\\
39.277 +\hspace*{0pt}fun anda x True = x\\
39.278 +\hspace*{0pt} ~| anda x False = False\\
39.279 +\hspace*{0pt} ~| anda True x = x\\
39.280 +\hspace*{0pt} ~| anda False x = False;\\
39.281 +\hspace*{0pt}\\
39.282 +\hspace*{0pt}fun less{\char95}nat m (Suc n) = less{\char95}eq{\char95}nat m n\\
39.283 +\hspace*{0pt} ~| less{\char95}nat n Zero{\char95}nat = False\\
39.284 +\hspace*{0pt}and less{\char95}eq{\char95}nat (Suc m) n = less{\char95}nat m n\\
39.285 +\hspace*{0pt} ~| less{\char95}eq{\char95}nat Zero{\char95}nat n = True;\\
39.286 +\hspace*{0pt}\\
39.287 +\hspace*{0pt}fun in{\char95}interval (k,~l) n = anda (less{\char95}eq{\char95}nat k n) (less{\char95}eq{\char95}nat n l);\\
39.288 +\hspace*{0pt}\\
39.289 +\hspace*{0pt}end;~(*struct Example*)%
39.290 +\end{isamarkuptext}%
39.291 +\isamarkuptrue%
39.292 +%
39.293 +\endisatagquote
39.294 +{\isafoldquote}%
39.295 +%
39.296 +\isadelimquote
39.297 +%
39.298 +\endisadelimquote
39.299 +%
39.300 +\begin{isamarkuptext}%
39.301 +\noindent Though this is correct code, it is a little bit unsatisfactory:
39.302 + boolean values and operators are materialised as distinguished
39.303 + entities with have nothing to do with the SML-built-in notion
39.304 + of \qt{bool}. This results in less readable code;
39.305 + additionally, eager evaluation may cause programs to
39.306 + loop or break which would perfectly terminate when
39.307 + the existing SML \verb|bool| would be used. To map
39.308 + the HOL \isa{bool} on SML \verb|bool|, we may use
39.309 + \qn{custom serialisations}:%
39.310 +\end{isamarkuptext}%
39.311 +\isamarkuptrue%
39.312 +%
39.313 +\isadelimquotett
39.314 +%
39.315 +\endisadelimquotett
39.316 +%
39.317 +\isatagquotett
39.318 +\isacommand{code{\isacharunderscore}type}\isamarkupfalse%
39.319 +\ bool\isanewline
39.320 +\ \ {\isacharparenleft}SML\ {\isachardoublequoteopen}bool{\isachardoublequoteclose}{\isacharparenright}\isanewline
39.321 +\isacommand{code{\isacharunderscore}const}\isamarkupfalse%
39.322 +\ True\ \isakeyword{and}\ False\ \isakeyword{and}\ {\isachardoublequoteopen}op\ {\isasymand}{\isachardoublequoteclose}\isanewline
39.323 +\ \ {\isacharparenleft}SML\ {\isachardoublequoteopen}true{\isachardoublequoteclose}\ \isakeyword{and}\ {\isachardoublequoteopen}false{\isachardoublequoteclose}\ \isakeyword{and}\ {\isachardoublequoteopen}{\isacharunderscore}\ andalso\ {\isacharunderscore}{\isachardoublequoteclose}{\isacharparenright}%
39.324 +\endisatagquotett
39.325 +{\isafoldquotett}%
39.326 +%
39.327 +\isadelimquotett
39.328 +%
39.329 +\endisadelimquotett
39.330 +%
39.331 +\begin{isamarkuptext}%
39.332 +\noindent The \hyperlink{command.code-type}{\mbox{\isa{\isacommand{code{\isacharunderscore}type}}}} command takes a type constructor
39.333 + as arguments together with a list of custom serialisations.
39.334 + Each custom serialisation starts with a target language
39.335 + identifier followed by an expression, which during
39.336 + code serialisation is inserted whenever the type constructor
39.337 + would occur. For constants, \hyperlink{command.code-const}{\mbox{\isa{\isacommand{code{\isacharunderscore}const}}}} implements
39.338 + the corresponding mechanism. Each ``\verb|_|'' in
39.339 + a serialisation expression is treated as a placeholder
39.340 + for the type constructor's (the constant's) arguments.%
39.341 +\end{isamarkuptext}%
39.342 +\isamarkuptrue%
39.343 +%
39.344 +\isadelimquote
39.345 +%
39.346 +\endisadelimquote
39.347 +%
39.348 +\isatagquote
39.349 +%
39.350 +\begin{isamarkuptext}%
39.351 +\isatypewriter%
39.352 +\noindent%
39.353 +\hspace*{0pt}structure Example = \\
39.354 +\hspace*{0pt}struct\\
39.355 +\hspace*{0pt}\\
39.356 +\hspace*{0pt}datatype nat = Zero{\char95}nat | Suc of nat;\\
39.357 +\hspace*{0pt}\\
39.358 +\hspace*{0pt}fun less{\char95}nat m (Suc n) = less{\char95}eq{\char95}nat m n\\
39.359 +\hspace*{0pt} ~| less{\char95}nat n Zero{\char95}nat = false\\
39.360 +\hspace*{0pt}and less{\char95}eq{\char95}nat (Suc m) n = less{\char95}nat m n\\
39.361 +\hspace*{0pt} ~| less{\char95}eq{\char95}nat Zero{\char95}nat n = true;\\
39.362 +\hspace*{0pt}\\
39.363 +\hspace*{0pt}fun in{\char95}interval (k,~l) n = (less{\char95}eq{\char95}nat k n) andalso (less{\char95}eq{\char95}nat n l);\\
39.364 +\hspace*{0pt}\\
39.365 +\hspace*{0pt}end;~(*struct Example*)%
39.366 +\end{isamarkuptext}%
39.367 +\isamarkuptrue%
39.368 +%
39.369 +\endisatagquote
39.370 +{\isafoldquote}%
39.371 +%
39.372 +\isadelimquote
39.373 +%
39.374 +\endisadelimquote
39.375 +%
39.376 +\begin{isamarkuptext}%
39.377 +\noindent This still is not perfect: the parentheses
39.378 + around the \qt{andalso} expression are superfluous.
39.379 + Though the serialiser
39.380 + by no means attempts to imitate the rich Isabelle syntax
39.381 + framework, it provides some common idioms, notably
39.382 + associative infixes with precedences which may be used here:%
39.383 +\end{isamarkuptext}%
39.384 +\isamarkuptrue%
39.385 +%
39.386 +\isadelimquotett
39.387 +%
39.388 +\endisadelimquotett
39.389 +%
39.390 +\isatagquotett
39.391 +\isacommand{code{\isacharunderscore}const}\isamarkupfalse%
39.392 +\ {\isachardoublequoteopen}op\ {\isasymand}{\isachardoublequoteclose}\isanewline
39.393 +\ \ {\isacharparenleft}SML\ \isakeyword{infixl}\ {\isadigit{1}}\ {\isachardoublequoteopen}andalso{\isachardoublequoteclose}{\isacharparenright}%
39.394 +\endisatagquotett
39.395 +{\isafoldquotett}%
39.396 +%
39.397 +\isadelimquotett
39.398 +%
39.399 +\endisadelimquotett
39.400 +%
39.401 +\isadelimquote
39.402 +%
39.403 +\endisadelimquote
39.404 +%
39.405 +\isatagquote
39.406 +%
39.407 +\begin{isamarkuptext}%
39.408 +\isatypewriter%
39.409 +\noindent%
39.410 +\hspace*{0pt}structure Example = \\
39.411 +\hspace*{0pt}struct\\
39.412 +\hspace*{0pt}\\
39.413 +\hspace*{0pt}datatype nat = Zero{\char95}nat | Suc of nat;\\
39.414 +\hspace*{0pt}\\
39.415 +\hspace*{0pt}fun less{\char95}nat m (Suc n) = less{\char95}eq{\char95}nat m n\\
39.416 +\hspace*{0pt} ~| less{\char95}nat n Zero{\char95}nat = false\\
39.417 +\hspace*{0pt}and less{\char95}eq{\char95}nat (Suc m) n = less{\char95}nat m n\\
39.418 +\hspace*{0pt} ~| less{\char95}eq{\char95}nat Zero{\char95}nat n = true;\\
39.419 +\hspace*{0pt}\\
39.420 +\hspace*{0pt}fun in{\char95}interval (k,~l) n = less{\char95}eq{\char95}nat k n andalso less{\char95}eq{\char95}nat n l;\\
39.421 +\hspace*{0pt}\\
39.422 +\hspace*{0pt}end;~(*struct Example*)%
39.423 +\end{isamarkuptext}%
39.424 +\isamarkuptrue%
39.425 +%
39.426 +\endisatagquote
39.427 +{\isafoldquote}%
39.428 +%
39.429 +\isadelimquote
39.430 +%
39.431 +\endisadelimquote
39.432 +%
39.433 +\begin{isamarkuptext}%
39.434 +\noindent The attentive reader may ask how we assert that no generated
39.435 + code will accidentally overwrite. For this reason the serialiser has
39.436 + an internal table of identifiers which have to be avoided to be used
39.437 + for new declarations. Initially, this table typically contains the
39.438 + keywords of the target language. It can be extended manually, thus avoiding
39.439 + accidental overwrites, using the \hyperlink{command.code-reserved}{\mbox{\isa{\isacommand{code{\isacharunderscore}reserved}}}} command:%
39.440 +\end{isamarkuptext}%
39.441 +\isamarkuptrue%
39.442 +%
39.443 +\isadelimquote
39.444 +%
39.445 +\endisadelimquote
39.446 +%
39.447 +\isatagquote
39.448 +\isacommand{code{\isacharunderscore}reserved}\isamarkupfalse%
39.449 +\ {\isachardoublequoteopen}{\isasymSML}{\isachardoublequoteclose}\ bool\ true\ false\ andalso%
39.450 +\endisatagquote
39.451 +{\isafoldquote}%
39.452 +%
39.453 +\isadelimquote
39.454 +%
39.455 +\endisadelimquote
39.456 +%
39.457 +\begin{isamarkuptext}%
39.458 +\noindent Next, we try to map HOL pairs to SML pairs, using the
39.459 + infix ``\verb|*|'' type constructor and parentheses:%
39.460 +\end{isamarkuptext}%
39.461 +\isamarkuptrue%
39.462 +%
39.463 +\isadeliminvisible
39.464 +%
39.465 +\endisadeliminvisible
39.466 +%
39.467 +\isataginvisible
39.468 +%
39.469 +\endisataginvisible
39.470 +{\isafoldinvisible}%
39.471 +%
39.472 +\isadeliminvisible
39.473 +%
39.474 +\endisadeliminvisible
39.475 +%
39.476 +\isadelimquotett
39.477 +%
39.478 +\endisadelimquotett
39.479 +%
39.480 +\isatagquotett
39.481 +\isacommand{code{\isacharunderscore}type}\isamarkupfalse%
39.482 +\ {\isacharasterisk}\isanewline
39.483 +\ \ {\isacharparenleft}SML\ \isakeyword{infix}\ {\isadigit{2}}\ {\isachardoublequoteopen}{\isacharasterisk}{\isachardoublequoteclose}{\isacharparenright}\isanewline
39.484 +\isacommand{code{\isacharunderscore}const}\isamarkupfalse%
39.485 +\ Pair\isanewline
39.486 +\ \ {\isacharparenleft}SML\ {\isachardoublequoteopen}{\isacharbang}{\isacharparenleft}{\isacharparenleft}{\isacharunderscore}{\isacharparenright}{\isacharcomma}{\isacharslash}\ {\isacharparenleft}{\isacharunderscore}{\isacharparenright}{\isacharparenright}{\isachardoublequoteclose}{\isacharparenright}%
39.487 +\endisatagquotett
39.488 +{\isafoldquotett}%
39.489 +%
39.490 +\isadelimquotett
39.491 +%
39.492 +\endisadelimquotett
39.493 +%
39.494 +\begin{isamarkuptext}%
39.495 +\noindent The initial bang ``\verb|!|'' tells the serialiser
39.496 + never to put
39.497 + parentheses around the whole expression (they are already present),
39.498 + while the parentheses around argument place holders
39.499 + tell not to put parentheses around the arguments.
39.500 + The slash ``\verb|/|'' (followed by arbitrary white space)
39.501 + inserts a space which may be used as a break if necessary
39.502 + during pretty printing.
39.503 +
39.504 + These examples give a glimpse what mechanisms
39.505 + custom serialisations provide; however their usage
39.506 + requires careful thinking in order not to introduce
39.507 + inconsistencies -- or, in other words:
39.508 + custom serialisations are completely axiomatic.
39.509 +
39.510 + A further noteworthy details is that any special
39.511 + character in a custom serialisation may be quoted
39.512 + using ``\verb|'|''; thus, in
39.513 + ``\verb|fn '_ => _|'' the first
39.514 + ``\verb|_|'' is a proper underscore while the
39.515 + second ``\verb|_|'' is a placeholder.%
39.516 +\end{isamarkuptext}%
39.517 +\isamarkuptrue%
39.518 +%
39.519 +\isamarkupsubsection{\isa{Haskell} serialisation%
39.520 +}
39.521 +\isamarkuptrue%
39.522 +%
39.523 +\begin{isamarkuptext}%
39.524 +For convenience, the default
39.525 + \isa{HOL} setup for \isa{Haskell} maps the \isa{eq} class to
39.526 + its counterpart in \isa{Haskell}, giving custom serialisations
39.527 + for the class \isa{eq} (by command \hyperlink{command.code-class}{\mbox{\isa{\isacommand{code{\isacharunderscore}class}}}}) and its operation
39.528 + \isa{eq{\isacharunderscore}class{\isachardot}eq}%
39.529 +\end{isamarkuptext}%
39.530 +\isamarkuptrue%
39.531 +%
39.532 +\isadelimquotett
39.533 +%
39.534 +\endisadelimquotett
39.535 +%
39.536 +\isatagquotett
39.537 +\isacommand{code{\isacharunderscore}class}\isamarkupfalse%
39.538 +\ eq\isanewline
39.539 +\ \ {\isacharparenleft}Haskell\ {\isachardoublequoteopen}Eq{\isachardoublequoteclose}{\isacharparenright}\isanewline
39.540 +\isanewline
39.541 +\isacommand{code{\isacharunderscore}const}\isamarkupfalse%
39.542 +\ {\isachardoublequoteopen}op\ {\isacharequal}{\isachardoublequoteclose}\isanewline
39.543 +\ \ {\isacharparenleft}Haskell\ \isakeyword{infixl}\ {\isadigit{4}}\ {\isachardoublequoteopen}{\isacharequal}{\isacharequal}{\isachardoublequoteclose}{\isacharparenright}%
39.544 +\endisatagquotett
39.545 +{\isafoldquotett}%
39.546 +%
39.547 +\isadelimquotett
39.548 +%
39.549 +\endisadelimquotett
39.550 +%
39.551 +\begin{isamarkuptext}%
39.552 +\noindent A problem now occurs whenever a type which
39.553 + is an instance of \isa{eq} in \isa{HOL} is mapped
39.554 + on a \isa{Haskell}-built-in type which is also an instance
39.555 + of \isa{Haskell} \isa{Eq}:%
39.556 +\end{isamarkuptext}%
39.557 +\isamarkuptrue%
39.558 +%
39.559 +\isadelimquote
39.560 +%
39.561 +\endisadelimquote
39.562 +%
39.563 +\isatagquote
39.564 +\isacommand{typedecl}\isamarkupfalse%
39.565 +\ bar\isanewline
39.566 +\isanewline
39.567 +\isacommand{instantiation}\isamarkupfalse%
39.568 +\ bar\ {\isacharcolon}{\isacharcolon}\ eq\isanewline
39.569 +\isakeyword{begin}\isanewline
39.570 +\isanewline
39.571 +\isacommand{definition}\isamarkupfalse%
39.572 +\ {\isachardoublequoteopen}eq{\isacharunderscore}class{\isachardot}eq\ {\isacharparenleft}x{\isasymColon}bar{\isacharparenright}\ y\ {\isasymlongleftrightarrow}\ x\ {\isacharequal}\ y{\isachardoublequoteclose}\isanewline
39.573 +\isanewline
39.574 +\isacommand{instance}\isamarkupfalse%
39.575 +\ \isacommand{by}\isamarkupfalse%
39.576 +\ default\ {\isacharparenleft}simp\ add{\isacharcolon}\ eq{\isacharunderscore}bar{\isacharunderscore}def{\isacharparenright}\isanewline
39.577 +\isanewline
39.578 +\isacommand{end}\isamarkupfalse%
39.579 +%
39.580 +\endisatagquote
39.581 +{\isafoldquote}%
39.582 +%
39.583 +\isadelimquote
39.584 +%
39.585 +\endisadelimquote
39.586 +\isanewline
39.587 +%
39.588 +\isadelimquotett
39.589 +%
39.590 +\endisadelimquotett
39.591 +%
39.592 +\isatagquotett
39.593 +\isacommand{code{\isacharunderscore}type}\isamarkupfalse%
39.594 +\ bar\isanewline
39.595 +\ \ {\isacharparenleft}Haskell\ {\isachardoublequoteopen}Integer{\isachardoublequoteclose}{\isacharparenright}%
39.596 +\endisatagquotett
39.597 +{\isafoldquotett}%
39.598 +%
39.599 +\isadelimquotett
39.600 +%
39.601 +\endisadelimquotett
39.602 +%
39.603 +\begin{isamarkuptext}%
39.604 +\noindent The code generator would produce
39.605 + an additional instance, which of course is rejected by the \isa{Haskell}
39.606 + compiler.
39.607 + To suppress this additional instance, use
39.608 + \isa{code{\isacharunderscore}instance}:%
39.609 +\end{isamarkuptext}%
39.610 +\isamarkuptrue%
39.611 +%
39.612 +\isadelimquotett
39.613 +%
39.614 +\endisadelimquotett
39.615 +%
39.616 +\isatagquotett
39.617 +\isacommand{code{\isacharunderscore}instance}\isamarkupfalse%
39.618 +\ bar\ {\isacharcolon}{\isacharcolon}\ eq\isanewline
39.619 +\ \ {\isacharparenleft}Haskell\ {\isacharminus}{\isacharparenright}%
39.620 +\endisatagquotett
39.621 +{\isafoldquotett}%
39.622 +%
39.623 +\isadelimquotett
39.624 +%
39.625 +\endisadelimquotett
39.626 +%
39.627 +\isamarkupsubsection{Enhancing the target language context \label{sec:include}%
39.628 +}
39.629 +\isamarkuptrue%
39.630 +%
39.631 +\begin{isamarkuptext}%
39.632 +In rare cases it is necessary to \emph{enrich} the context of a
39.633 + target language; this is accomplished using the \hyperlink{command.code-include}{\mbox{\isa{\isacommand{code{\isacharunderscore}include}}}}
39.634 + command:%
39.635 +\end{isamarkuptext}%
39.636 +\isamarkuptrue%
39.637 +%
39.638 +\isadelimquotett
39.639 +%
39.640 +\endisadelimquotett
39.641 +%
39.642 +\isatagquotett
39.643 +\isacommand{code{\isacharunderscore}include}\isamarkupfalse%
39.644 +\ Haskell\ {\isachardoublequoteopen}Errno{\isachardoublequoteclose}\isanewline
39.645 +{\isacharverbatimopen}errno\ i\ {\isacharequal}\ error\ {\isacharparenleft}{\isachardoublequote}Error\ number{\isacharcolon}\ {\isachardoublequote}\ {\isacharplus}{\isacharplus}\ show\ i{\isacharparenright}{\isacharverbatimclose}\isanewline
39.646 +\isanewline
39.647 +\isacommand{code{\isacharunderscore}reserved}\isamarkupfalse%
39.648 +\ Haskell\ Errno%
39.649 +\endisatagquotett
39.650 +{\isafoldquotett}%
39.651 +%
39.652 +\isadelimquotett
39.653 +%
39.654 +\endisadelimquotett
39.655 +%
39.656 +\begin{isamarkuptext}%
39.657 +\noindent Such named \isa{include}s are then prepended to every generated code.
39.658 + Inspect such code in order to find out how \hyperlink{command.code-include}{\mbox{\isa{\isacommand{code{\isacharunderscore}include}}}} behaves
39.659 + with respect to a particular target language.%
39.660 +\end{isamarkuptext}%
39.661 +\isamarkuptrue%
39.662 +%
39.663 +\isadelimtheory
39.664 +%
39.665 +\endisadelimtheory
39.666 +%
39.667 +\isatagtheory
39.668 +\isacommand{end}\isamarkupfalse%
39.669 +%
39.670 +\endisatagtheory
39.671 +{\isafoldtheory}%
39.672 +%
39.673 +\isadelimtheory
39.674 +%
39.675 +\endisadelimtheory
39.676 +\isanewline
39.677 +\end{isabellebody}%
39.678 +%%% Local Variables:
39.679 +%%% mode: latex
39.680 +%%% TeX-master: "root"
39.681 +%%% End:
40.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
40.2 +++ b/doc-src/Codegen/Thy/document/Codegen.tex Wed Mar 04 11:05:29 2009 +0100
40.3 @@ -0,0 +1,1690 @@
40.4 +%
40.5 +\begin{isabellebody}%
40.6 +\def\isabellecontext{Codegen}%
40.7 +%
40.8 +\isadelimtheory
40.9 +\isanewline
40.10 +\isanewline
40.11 +%
40.12 +\endisadelimtheory
40.13 +%
40.14 +\isatagtheory
40.15 +%
40.16 +\endisatagtheory
40.17 +{\isafoldtheory}%
40.18 +%
40.19 +\isadelimtheory
40.20 +%
40.21 +\endisadelimtheory
40.22 +%
40.23 +\isadelimML
40.24 +%
40.25 +\endisadelimML
40.26 +%
40.27 +\isatagML
40.28 +%
40.29 +\endisatagML
40.30 +{\isafoldML}%
40.31 +%
40.32 +\isadelimML
40.33 +%
40.34 +\endisadelimML
40.35 +%
40.36 +\isamarkupchapter{Code generation from Isabelle theories%
40.37 +}
40.38 +\isamarkuptrue%
40.39 +%
40.40 +\isamarkupsection{Introduction%
40.41 +}
40.42 +\isamarkuptrue%
40.43 +%
40.44 +\isamarkupsubsection{Motivation%
40.45 +}
40.46 +\isamarkuptrue%
40.47 +%
40.48 +\begin{isamarkuptext}%
40.49 +Executing formal specifications as programs is a well-established
40.50 + topic in the theorem proving community. With increasing
40.51 + application of theorem proving systems in the area of
40.52 + software development and verification, its relevance manifests
40.53 + for running test cases and rapid prototyping. In logical
40.54 + calculi like constructive type theory,
40.55 + a notion of executability is implicit due to the nature
40.56 + of the calculus. In contrast, specifications in Isabelle
40.57 + can be highly non-executable. In order to bridge
40.58 + the gap between logic and executable specifications,
40.59 + an explicit non-trivial transformation has to be applied:
40.60 + code generation.
40.61 +
40.62 + This tutorial introduces a generic code generator for the
40.63 + Isabelle system \cite{isa-tutorial}.
40.64 + Generic in the sense that the
40.65 + \qn{target language} for which code shall ultimately be
40.66 + generated is not fixed but may be an arbitrary state-of-the-art
40.67 + functional programming language (currently, the implementation
40.68 + supports SML \cite{SML}, OCaml \cite{OCaml} and Haskell
40.69 + \cite{haskell-revised-report}).
40.70 + We aim to provide a
40.71 + versatile environment
40.72 + suitable for software development and verification,
40.73 + structuring the process
40.74 + of code generation into a small set of orthogonal principles
40.75 + while achieving a big coverage of application areas
40.76 + with maximum flexibility.
40.77 +
40.78 + Conceptually the code generator framework is part
40.79 + of Isabelle's \isa{Pure} meta logic; the object logic
40.80 + \isa{HOL} which is an extension of \isa{Pure}
40.81 + already comes with a reasonable framework setup and thus provides
40.82 + a good working horse for raising code-generation-driven
40.83 + applications. So, we assume some familiarity and experience
40.84 + with the ingredients of the \isa{HOL} \emph{Main} theory
40.85 + (see also \cite{isa-tutorial}).%
40.86 +\end{isamarkuptext}%
40.87 +\isamarkuptrue%
40.88 +%
40.89 +\isamarkupsubsection{Overview%
40.90 +}
40.91 +\isamarkuptrue%
40.92 +%
40.93 +\begin{isamarkuptext}%
40.94 +The code generator aims to be usable with no further ado
40.95 + in most cases while allowing for detailed customization.
40.96 + This manifests in the structure of this tutorial:
40.97 + we start with a generic example \secref{sec:example}
40.98 + and introduce code generation concepts \secref{sec:concept}.
40.99 + Section
40.100 + \secref{sec:basics} explains how to use the framework naively,
40.101 + presuming a reasonable default setup. Then, section
40.102 + \secref{sec:advanced} deals with advanced topics,
40.103 + introducing further aspects of the code generator framework
40.104 + in a motivation-driven manner. Last, section \secref{sec:ml}
40.105 + introduces the framework's internal programming interfaces.
40.106 +
40.107 + \begin{warn}
40.108 + Ultimately, the code generator which this tutorial deals with
40.109 + is supposed to replace the already established code generator
40.110 + by Stefan Berghofer \cite{Berghofer-Nipkow:2002}.
40.111 + So, for the moment, there are two distinct code generators
40.112 + in Isabelle.
40.113 + Also note that while the framework itself is
40.114 + object-logic independent, only \isa{HOL} provides a reasonable
40.115 + framework setup.
40.116 + \end{warn}%
40.117 +\end{isamarkuptext}%
40.118 +\isamarkuptrue%
40.119 +%
40.120 +\isamarkupsection{An example: a simple theory of search trees \label{sec:example}%
40.121 +}
40.122 +\isamarkuptrue%
40.123 +%
40.124 +\begin{isamarkuptext}%
40.125 +When writing executable specifications using \isa{HOL},
40.126 + it is convenient to use
40.127 + three existing packages: the datatype package for defining
40.128 + datatypes, the function package for (recursive) functions,
40.129 + and the class package for overloaded definitions.
40.130 +
40.131 + We develope a small theory of search trees; trees are represented
40.132 + as a datatype with key type \isa{{\isacharprime}a} and value type \isa{{\isacharprime}b}:%
40.133 +\end{isamarkuptext}%
40.134 +\isamarkuptrue%
40.135 +\isacommand{datatype}\isamarkupfalse%
40.136 +\ {\isacharparenleft}{\isacharprime}a{\isacharcomma}\ {\isacharprime}b{\isacharparenright}\ searchtree\ {\isacharequal}\ Leaf\ {\isachardoublequoteopen}{\isacharprime}a{\isasymColon}linorder{\isachardoublequoteclose}\ {\isacharprime}b\isanewline
40.137 +\ \ {\isacharbar}\ Branch\ {\isachardoublequoteopen}{\isacharparenleft}{\isacharprime}a{\isacharcomma}\ {\isacharprime}b{\isacharparenright}\ searchtree{\isachardoublequoteclose}\ {\isachardoublequoteopen}{\isacharprime}a{\isachardoublequoteclose}\ {\isachardoublequoteopen}{\isacharparenleft}{\isacharprime}a{\isacharcomma}\ {\isacharprime}b{\isacharparenright}\ searchtree{\isachardoublequoteclose}%
40.138 +\begin{isamarkuptext}%
40.139 +\noindent Note that we have constrained the type of keys
40.140 + to the class of total orders, \isa{linorder}.
40.141 +
40.142 + We define \isa{find} and \isa{update} functions:%
40.143 +\end{isamarkuptext}%
40.144 +\isamarkuptrue%
40.145 +\isacommand{primrec}\isamarkupfalse%
40.146 +\isanewline
40.147 +\ \ find\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharparenleft}{\isacharprime}a{\isasymColon}linorder{\isacharcomma}\ {\isacharprime}b{\isacharparenright}\ searchtree\ {\isasymRightarrow}\ {\isacharprime}a\ {\isasymRightarrow}\ {\isacharprime}b\ option{\isachardoublequoteclose}\ \isakeyword{where}\isanewline
40.148 +\ \ {\isachardoublequoteopen}find\ {\isacharparenleft}Leaf\ key\ val{\isacharparenright}\ it\ {\isacharequal}\ {\isacharparenleft}if\ it\ {\isacharequal}\ key\ then\ Some\ val\ else\ None{\isacharparenright}{\isachardoublequoteclose}\isanewline
40.149 +\ \ {\isacharbar}\ {\isachardoublequoteopen}find\ {\isacharparenleft}Branch\ t{\isadigit{1}}\ key\ t{\isadigit{2}}{\isacharparenright}\ it\ {\isacharequal}\ {\isacharparenleft}if\ it\ {\isasymle}\ key\ then\ find\ t{\isadigit{1}}\ it\ else\ find\ t{\isadigit{2}}\ it{\isacharparenright}{\isachardoublequoteclose}\isanewline
40.150 +\isanewline
40.151 +\isacommand{fun}\isamarkupfalse%
40.152 +\isanewline
40.153 +\ \ update\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharprime}a{\isasymColon}linorder\ {\isasymtimes}\ {\isacharprime}b\ {\isasymRightarrow}\ {\isacharparenleft}{\isacharprime}a{\isacharcomma}\ {\isacharprime}b{\isacharparenright}\ searchtree\ {\isasymRightarrow}\ {\isacharparenleft}{\isacharprime}a{\isacharcomma}\ {\isacharprime}b{\isacharparenright}\ searchtree{\isachardoublequoteclose}\ \isakeyword{where}\isanewline
40.154 +\ \ {\isachardoublequoteopen}update\ {\isacharparenleft}it{\isacharcomma}\ entry{\isacharparenright}\ {\isacharparenleft}Leaf\ key\ val{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}\isanewline
40.155 +\ \ \ \ if\ it\ {\isacharequal}\ key\ then\ Leaf\ key\ entry\isanewline
40.156 +\ \ \ \ \ \ else\ if\ it\ {\isasymle}\ key\isanewline
40.157 +\ \ \ \ \ \ then\ Branch\ {\isacharparenleft}Leaf\ it\ entry{\isacharparenright}\ it\ {\isacharparenleft}Leaf\ key\ val{\isacharparenright}\isanewline
40.158 +\ \ \ \ \ \ else\ Branch\ {\isacharparenleft}Leaf\ key\ val{\isacharparenright}\ it\ {\isacharparenleft}Leaf\ it\ entry{\isacharparenright}\isanewline
40.159 +\ \ \ {\isacharparenright}{\isachardoublequoteclose}\isanewline
40.160 +\ \ {\isacharbar}\ {\isachardoublequoteopen}update\ {\isacharparenleft}it{\isacharcomma}\ entry{\isacharparenright}\ {\isacharparenleft}Branch\ t{\isadigit{1}}\ key\ t{\isadigit{2}}{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}\isanewline
40.161 +\ \ \ \ if\ it\ {\isasymle}\ key\isanewline
40.162 +\ \ \ \ \ \ then\ {\isacharparenleft}Branch\ {\isacharparenleft}update\ {\isacharparenleft}it{\isacharcomma}\ entry{\isacharparenright}\ t{\isadigit{1}}{\isacharparenright}\ key\ t{\isadigit{2}}{\isacharparenright}\isanewline
40.163 +\ \ \ \ \ \ else\ {\isacharparenleft}Branch\ t{\isadigit{1}}\ key\ {\isacharparenleft}update\ {\isacharparenleft}it{\isacharcomma}\ entry{\isacharparenright}\ t{\isadigit{2}}{\isacharparenright}{\isacharparenright}\isanewline
40.164 +\ \ \ {\isacharparenright}{\isachardoublequoteclose}%
40.165 +\begin{isamarkuptext}%
40.166 +\noindent For testing purpose, we define a small example
40.167 + using natural numbers \isa{nat} (which are a \isa{linorder})
40.168 + as keys and list of nats as values:%
40.169 +\end{isamarkuptext}%
40.170 +\isamarkuptrue%
40.171 +\isacommand{definition}\isamarkupfalse%
40.172 +\isanewline
40.173 +\ \ example\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharparenleft}nat{\isacharcomma}\ nat\ list{\isacharparenright}\ searchtree{\isachardoublequoteclose}\isanewline
40.174 +\isakeyword{where}\isanewline
40.175 +\ \ {\isachardoublequoteopen}example\ {\isacharequal}\ update\ {\isacharparenleft}Suc\ {\isacharparenleft}Suc\ {\isacharparenleft}Suc\ {\isacharparenleft}Suc\ {\isadigit{0}}{\isacharparenright}{\isacharparenright}{\isacharparenright}{\isacharcomma}\ {\isacharbrackleft}Suc\ {\isacharparenleft}Suc\ {\isadigit{0}}{\isacharparenright}{\isacharcomma}\ Suc\ {\isacharparenleft}Suc\ {\isadigit{0}}{\isacharparenright}{\isacharbrackright}{\isacharparenright}\ {\isacharparenleft}update\ {\isacharparenleft}Suc\ {\isacharparenleft}Suc\ {\isacharparenleft}Suc\ {\isadigit{0}}{\isacharparenright}{\isacharparenright}{\isacharcomma}\ {\isacharbrackleft}Suc\ {\isacharparenleft}Suc\ {\isacharparenleft}Suc\ {\isadigit{0}}{\isacharparenright}{\isacharparenright}{\isacharbrackright}{\isacharparenright}\isanewline
40.176 +\ \ \ \ {\isacharparenleft}update\ {\isacharparenleft}Suc\ {\isacharparenleft}Suc\ {\isadigit{0}}{\isacharparenright}{\isacharcomma}\ {\isacharbrackleft}Suc\ {\isacharparenleft}Suc\ {\isadigit{0}}{\isacharparenright}{\isacharbrackright}{\isacharparenright}\ {\isacharparenleft}Leaf\ {\isacharparenleft}Suc\ {\isadigit{0}}{\isacharparenright}\ {\isacharbrackleft}{\isacharbrackright}{\isacharparenright}{\isacharparenright}{\isacharparenright}{\isachardoublequoteclose}%
40.177 +\begin{isamarkuptext}%
40.178 +\noindent Then we generate code%
40.179 +\end{isamarkuptext}%
40.180 +\isamarkuptrue%
40.181 +\isacommand{export{\isacharunderscore}code}\isamarkupfalse%
40.182 +\ example\ \isakeyword{in}\ SML\ \isakeyword{file}\ {\isachardoublequoteopen}examples{\isacharslash}tree{\isachardot}ML{\isachardoublequoteclose}%
40.183 +\begin{isamarkuptext}%
40.184 +\noindent which looks like:
40.185 + \lstsml{Thy/examples/tree.ML}%
40.186 +\end{isamarkuptext}%
40.187 +\isamarkuptrue%
40.188 +%
40.189 +\isamarkupsection{Code generation concepts and process \label{sec:concept}%
40.190 +}
40.191 +\isamarkuptrue%
40.192 +%
40.193 +\begin{isamarkuptext}%
40.194 +\begin{figure}[h]
40.195 + \centering
40.196 + \includegraphics[width=0.7\textwidth]{codegen_process}
40.197 + \caption{code generator -- processing overview}
40.198 + \label{fig:process}
40.199 + \end{figure}
40.200 +
40.201 + The code generator employs a notion of executability
40.202 + for three foundational executable ingredients known
40.203 + from functional programming:
40.204 + \emph{defining equations}, \emph{datatypes}, and
40.205 + \emph{type classes}. A defining equation as a first approximation
40.206 + is a theorem of the form \isa{f\ t\isactrlisub {\isadigit{1}}\ t\isactrlisub {\isadigit{2}}\ {\isasymdots}\ t\isactrlisub n\ {\isasymequiv}\ t}
40.207 + (an equation headed by a constant \isa{f} with arguments
40.208 + \isa{t\isactrlisub {\isadigit{1}}\ t\isactrlisub {\isadigit{2}}\ {\isasymdots}\ t\isactrlisub n} and right hand side \isa{t}).
40.209 + Code generation aims to turn defining equations
40.210 + into a functional program by running through
40.211 + a process (see figure \ref{fig:process}):
40.212 +
40.213 + \begin{itemize}
40.214 +
40.215 + \item Out of the vast collection of theorems proven in a
40.216 + \qn{theory}, a reasonable subset modeling
40.217 + defining equations is \qn{selected}.
40.218 +
40.219 + \item On those selected theorems, certain
40.220 + transformations are carried out
40.221 + (\qn{preprocessing}). Their purpose is to turn theorems
40.222 + representing non- or badly executable
40.223 + specifications into equivalent but executable counterparts.
40.224 + The result is a structured collection of \qn{code theorems}.
40.225 +
40.226 + \item These \qn{code theorems} then are \qn{translated}
40.227 + into an Haskell-like intermediate
40.228 + language.
40.229 +
40.230 + \item Finally, out of the intermediate language the final
40.231 + code in the desired \qn{target language} is \qn{serialized}.
40.232 +
40.233 + \end{itemize}
40.234 +
40.235 + From these steps, only the two last are carried out
40.236 + outside the logic; by keeping this layer as
40.237 + thin as possible, the amount of code to trust is
40.238 + kept to a minimum.%
40.239 +\end{isamarkuptext}%
40.240 +\isamarkuptrue%
40.241 +%
40.242 +\isamarkupsection{Basics \label{sec:basics}%
40.243 +}
40.244 +\isamarkuptrue%
40.245 +%
40.246 +\isamarkupsubsection{Invoking the code generator%
40.247 +}
40.248 +\isamarkuptrue%
40.249 +%
40.250 +\begin{isamarkuptext}%
40.251 +Thanks to a reasonable setup of the \isa{HOL} theories, in
40.252 + most cases code generation proceeds without further ado:%
40.253 +\end{isamarkuptext}%
40.254 +\isamarkuptrue%
40.255 +\isacommand{primrec}\isamarkupfalse%
40.256 +\isanewline
40.257 +\ \ fac\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymRightarrow}\ nat{\isachardoublequoteclose}\ \isakeyword{where}\isanewline
40.258 +\ \ \ \ {\isachardoublequoteopen}fac\ {\isadigit{0}}\ {\isacharequal}\ {\isadigit{1}}{\isachardoublequoteclose}\isanewline
40.259 +\ \ {\isacharbar}\ {\isachardoublequoteopen}fac\ {\isacharparenleft}Suc\ n{\isacharparenright}\ {\isacharequal}\ Suc\ n\ {\isacharasterisk}\ fac\ n{\isachardoublequoteclose}%
40.260 +\begin{isamarkuptext}%
40.261 +\noindent This executable specification is now turned to SML code:%
40.262 +\end{isamarkuptext}%
40.263 +\isamarkuptrue%
40.264 +\isacommand{export{\isacharunderscore}code}\isamarkupfalse%
40.265 +\ fac\ \isakeyword{in}\ SML\ \isakeyword{file}\ {\isachardoublequoteopen}examples{\isacharslash}fac{\isachardot}ML{\isachardoublequoteclose}%
40.266 +\begin{isamarkuptext}%
40.267 +\noindent The \isa{{\isasymEXPORTCODE}} command takes a space-separated list of
40.268 + constants together with \qn{serialization directives}
40.269 + These start with a \qn{target language}
40.270 + identifier, followed by a file specification
40.271 + where to write the generated code to.
40.272 +
40.273 + Internally, the defining equations for all selected
40.274 + constants are taken, including any transitively required
40.275 + constants, datatypes and classes, resulting in the following
40.276 + code:
40.277 +
40.278 + \lstsml{Thy/examples/fac.ML}
40.279 +
40.280 + The code generator will complain when a required
40.281 + ingredient does not provide a executable counterpart,
40.282 + e.g.~generating code
40.283 + for constants not yielding
40.284 + a defining equation (e.g.~the Hilbert choice
40.285 + operation \isa{SOME}):%
40.286 +\end{isamarkuptext}%
40.287 +\isamarkuptrue%
40.288 +%
40.289 +\isadelimML
40.290 +%
40.291 +\endisadelimML
40.292 +%
40.293 +\isatagML
40.294 +%
40.295 +\endisatagML
40.296 +{\isafoldML}%
40.297 +%
40.298 +\isadelimML
40.299 +%
40.300 +\endisadelimML
40.301 +\isacommand{definition}\isamarkupfalse%
40.302 +\isanewline
40.303 +\ \ pick{\isacharunderscore}some\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharprime}a\ list\ {\isasymRightarrow}\ {\isacharprime}a{\isachardoublequoteclose}\ \isakeyword{where}\isanewline
40.304 +\ \ {\isachardoublequoteopen}pick{\isacharunderscore}some\ xs\ {\isacharequal}\ {\isacharparenleft}SOME\ x{\isachardot}\ x\ {\isasymin}\ set\ xs{\isacharparenright}{\isachardoublequoteclose}%
40.305 +\isadelimML
40.306 +%
40.307 +\endisadelimML
40.308 +%
40.309 +\isatagML
40.310 +%
40.311 +\endisatagML
40.312 +{\isafoldML}%
40.313 +%
40.314 +\isadelimML
40.315 +%
40.316 +\endisadelimML
40.317 +\isanewline
40.318 +\isacommand{export{\isacharunderscore}code}\isamarkupfalse%
40.319 +\ pick{\isacharunderscore}some\ \isakeyword{in}\ SML\ \isakeyword{file}\ {\isachardoublequoteopen}examples{\isacharslash}fail{\isacharunderscore}const{\isachardot}ML{\isachardoublequoteclose}%
40.320 +\begin{isamarkuptext}%
40.321 +\noindent will fail.%
40.322 +\end{isamarkuptext}%
40.323 +\isamarkuptrue%
40.324 +%
40.325 +\isamarkupsubsection{Theorem selection%
40.326 +}
40.327 +\isamarkuptrue%
40.328 +%
40.329 +\begin{isamarkuptext}%
40.330 +The list of all defining equations in a theory may be inspected
40.331 + using the \isa{{\isasymPRINTCODESETUP}} command:%
40.332 +\end{isamarkuptext}%
40.333 +\isamarkuptrue%
40.334 +\isacommand{print{\isacharunderscore}codesetup}\isamarkupfalse%
40.335 +%
40.336 +\begin{isamarkuptext}%
40.337 +\noindent which displays a table of constant with corresponding
40.338 + defining equations (the additional stuff displayed
40.339 + shall not bother us for the moment).
40.340 +
40.341 + The typical \isa{HOL} tools are already set up in a way that
40.342 + function definitions introduced by \isa{{\isasymDEFINITION}},
40.343 + \isa{{\isasymPRIMREC}}, \isa{{\isasymFUN}},
40.344 + \isa{{\isasymFUNCTION}}, \isa{{\isasymCONSTDEFS}},
40.345 + \isa{{\isasymRECDEF}} are implicitly propagated
40.346 + to this defining equation table. Specific theorems may be
40.347 + selected using an attribute: \emph{code func}. As example,
40.348 + a weight selector function:%
40.349 +\end{isamarkuptext}%
40.350 +\isamarkuptrue%
40.351 +\isacommand{primrec}\isamarkupfalse%
40.352 +\isanewline
40.353 +\ \ pick\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharparenleft}nat\ {\isasymtimes}\ {\isacharprime}a{\isacharparenright}\ list\ {\isasymRightarrow}\ nat\ {\isasymRightarrow}\ {\isacharprime}a{\isachardoublequoteclose}\ \isakeyword{where}\isanewline
40.354 +\ \ {\isachardoublequoteopen}pick\ {\isacharparenleft}x{\isacharhash}xs{\isacharparenright}\ n\ {\isacharequal}\ {\isacharparenleft}let\ {\isacharparenleft}k{\isacharcomma}\ v{\isacharparenright}\ {\isacharequal}\ x\ in\isanewline
40.355 +\ \ \ \ if\ n\ {\isacharless}\ k\ then\ v\ else\ pick\ xs\ {\isacharparenleft}n\ {\isacharminus}\ k{\isacharparenright}{\isacharparenright}{\isachardoublequoteclose}%
40.356 +\begin{isamarkuptext}%
40.357 +\noindent We want to eliminate the explicit destruction
40.358 + of \isa{x} to \isa{{\isacharparenleft}k{\isacharcomma}\ v{\isacharparenright}}:%
40.359 +\end{isamarkuptext}%
40.360 +\isamarkuptrue%
40.361 +\isacommand{lemma}\isamarkupfalse%
40.362 +\ {\isacharbrackleft}code\ func{\isacharbrackright}{\isacharcolon}\isanewline
40.363 +\ \ {\isachardoublequoteopen}pick\ {\isacharparenleft}{\isacharparenleft}k{\isacharcomma}\ v{\isacharparenright}{\isacharhash}xs{\isacharparenright}\ n\ {\isacharequal}\ {\isacharparenleft}if\ n\ {\isacharless}\ k\ then\ v\ else\ pick\ xs\ {\isacharparenleft}n\ {\isacharminus}\ k{\isacharparenright}{\isacharparenright}{\isachardoublequoteclose}\isanewline
40.364 +%
40.365 +\isadelimproof
40.366 +\ \ %
40.367 +\endisadelimproof
40.368 +%
40.369 +\isatagproof
40.370 +\isacommand{by}\isamarkupfalse%
40.371 +\ simp%
40.372 +\endisatagproof
40.373 +{\isafoldproof}%
40.374 +%
40.375 +\isadelimproof
40.376 +\isanewline
40.377 +%
40.378 +\endisadelimproof
40.379 +\isanewline
40.380 +\isacommand{export{\isacharunderscore}code}\isamarkupfalse%
40.381 +\ pick\ \ \isakeyword{in}\ SML\ \isakeyword{file}\ {\isachardoublequoteopen}examples{\isacharslash}pick{\isadigit{1}}{\isachardot}ML{\isachardoublequoteclose}%
40.382 +\begin{isamarkuptext}%
40.383 +\noindent This theorem now is used for generating code:
40.384 +
40.385 + \lstsml{Thy/examples/pick1.ML}
40.386 +
40.387 + \noindent The policy is that \emph{default equations} stemming from
40.388 + \isa{{\isasymDEFINITION}},
40.389 + \isa{{\isasymPRIMREC}}, \isa{{\isasymFUN}},
40.390 + \isa{{\isasymFUNCTION}}, \isa{{\isasymCONSTDEFS}},
40.391 + \isa{{\isasymRECDEF}} statements are discarded as soon as an
40.392 + equation is explicitly selected by means of \emph{code func}.
40.393 + Further applications of \emph{code func} add theorems incrementally,
40.394 + but syntactic redundancies are implicitly dropped. For example,
40.395 + using a modified version of the \isa{fac} function
40.396 + as defining equation, the then redundant (since
40.397 + syntactically subsumed) original defining equations
40.398 + are dropped.
40.399 +
40.400 + \begin{warn}
40.401 + The attributes \emph{code} and \emph{code del}
40.402 + associated with the existing code generator also apply to
40.403 + the new one: \emph{code} implies \emph{code func},
40.404 + and \emph{code del} implies \emph{code func del}.
40.405 + \end{warn}%
40.406 +\end{isamarkuptext}%
40.407 +\isamarkuptrue%
40.408 +%
40.409 +\isamarkupsubsection{Type classes%
40.410 +}
40.411 +\isamarkuptrue%
40.412 +%
40.413 +\begin{isamarkuptext}%
40.414 +Type classes enter the game via the Isar class package.
40.415 + For a short introduction how to use it, see \cite{isabelle-classes};
40.416 + here we just illustrate its impact on code generation.
40.417 +
40.418 + In a target language, type classes may be represented
40.419 + natively (as in the case of Haskell). For languages
40.420 + like SML, they are implemented using \emph{dictionaries}.
40.421 + Our following example specifies a class \qt{null},
40.422 + assigning to each of its inhabitants a \qt{null} value:%
40.423 +\end{isamarkuptext}%
40.424 +\isamarkuptrue%
40.425 +\isacommand{class}\isamarkupfalse%
40.426 +\ null\ {\isacharequal}\ type\ {\isacharplus}\isanewline
40.427 +\ \ \isakeyword{fixes}\ null\ {\isacharcolon}{\isacharcolon}\ {\isacharprime}a\isanewline
40.428 +\isanewline
40.429 +\isacommand{primrec}\isamarkupfalse%
40.430 +\isanewline
40.431 +\ \ head\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharprime}a{\isasymColon}null\ list\ {\isasymRightarrow}\ {\isacharprime}a{\isachardoublequoteclose}\ \isakeyword{where}\isanewline
40.432 +\ \ {\isachardoublequoteopen}head\ {\isacharbrackleft}{\isacharbrackright}\ {\isacharequal}\ null{\isachardoublequoteclose}\isanewline
40.433 +\ \ {\isacharbar}\ {\isachardoublequoteopen}head\ {\isacharparenleft}x{\isacharhash}xs{\isacharparenright}\ {\isacharequal}\ x{\isachardoublequoteclose}%
40.434 +\begin{isamarkuptext}%
40.435 +\noindent We provide some instances for our \isa{null}:%
40.436 +\end{isamarkuptext}%
40.437 +\isamarkuptrue%
40.438 +\isacommand{instantiation}\isamarkupfalse%
40.439 +\ option\ \isakeyword{and}\ list\ {\isacharcolon}{\isacharcolon}\ {\isacharparenleft}type{\isacharparenright}\ null\isanewline
40.440 +\isakeyword{begin}\isanewline
40.441 +\isanewline
40.442 +\isacommand{definition}\isamarkupfalse%
40.443 +\isanewline
40.444 +\ \ {\isachardoublequoteopen}null\ {\isacharequal}\ None{\isachardoublequoteclose}\isanewline
40.445 +\isanewline
40.446 +\isacommand{definition}\isamarkupfalse%
40.447 +\isanewline
40.448 +\ \ {\isachardoublequoteopen}null\ {\isacharequal}\ {\isacharbrackleft}{\isacharbrackright}{\isachardoublequoteclose}\isanewline
40.449 +\isanewline
40.450 +\isacommand{instance}\isamarkupfalse%
40.451 +%
40.452 +\isadelimproof
40.453 +\ %
40.454 +\endisadelimproof
40.455 +%
40.456 +\isatagproof
40.457 +\isacommand{{\isachardot}{\isachardot}}\isamarkupfalse%
40.458 +%
40.459 +\endisatagproof
40.460 +{\isafoldproof}%
40.461 +%
40.462 +\isadelimproof
40.463 +%
40.464 +\endisadelimproof
40.465 +\isanewline
40.466 +\isanewline
40.467 +\isacommand{end}\isamarkupfalse%
40.468 +%
40.469 +\begin{isamarkuptext}%
40.470 +\noindent Constructing a dummy example:%
40.471 +\end{isamarkuptext}%
40.472 +\isamarkuptrue%
40.473 +\isacommand{definition}\isamarkupfalse%
40.474 +\isanewline
40.475 +\ \ {\isachardoublequoteopen}dummy\ {\isacharequal}\ head\ {\isacharbrackleft}Some\ {\isacharparenleft}Suc\ {\isadigit{0}}{\isacharparenright}{\isacharcomma}\ None{\isacharbrackright}{\isachardoublequoteclose}%
40.476 +\begin{isamarkuptext}%
40.477 +Type classes offer a suitable occasion to introduce
40.478 + the Haskell serializer. Its usage is almost the same
40.479 + as SML, but, in accordance with conventions
40.480 + some Haskell systems enforce, each module ends
40.481 + up in a single file. The module hierarchy is reflected in
40.482 + the file system, with root directory given as file specification.%
40.483 +\end{isamarkuptext}%
40.484 +\isamarkuptrue%
40.485 +\isacommand{export{\isacharunderscore}code}\isamarkupfalse%
40.486 +\ dummy\ \isakeyword{in}\ Haskell\ \isakeyword{file}\ {\isachardoublequoteopen}examples{\isacharslash}{\isachardoublequoteclose}%
40.487 +\begin{isamarkuptext}%
40.488 +\lsthaskell{Thy/examples/Codegen.hs}
40.489 + \noindent (we have left out all other modules).
40.490 +
40.491 + \medskip
40.492 +
40.493 + The whole code in SML with explicit dictionary passing:%
40.494 +\end{isamarkuptext}%
40.495 +\isamarkuptrue%
40.496 +\isacommand{export{\isacharunderscore}code}\isamarkupfalse%
40.497 +\ dummy\ \isakeyword{in}\ SML\ \isakeyword{file}\ {\isachardoublequoteopen}examples{\isacharslash}class{\isachardot}ML{\isachardoublequoteclose}%
40.498 +\begin{isamarkuptext}%
40.499 +\lstsml{Thy/examples/class.ML}
40.500 +
40.501 + \medskip
40.502 +
40.503 + \noindent or in OCaml:%
40.504 +\end{isamarkuptext}%
40.505 +\isamarkuptrue%
40.506 +\isacommand{export{\isacharunderscore}code}\isamarkupfalse%
40.507 +\ dummy\ \isakeyword{in}\ OCaml\ \isakeyword{file}\ {\isachardoublequoteopen}examples{\isacharslash}class{\isachardot}ocaml{\isachardoublequoteclose}%
40.508 +\begin{isamarkuptext}%
40.509 +\lstsml{Thy/examples/class.ocaml}
40.510 +
40.511 + \medskip The explicit association of constants
40.512 + to classes can be inspected using the \isa{{\isasymPRINTCLASSES}}
40.513 + command.%
40.514 +\end{isamarkuptext}%
40.515 +\isamarkuptrue%
40.516 +%
40.517 +\isamarkupsection{Recipes and advanced topics \label{sec:advanced}%
40.518 +}
40.519 +\isamarkuptrue%
40.520 +%
40.521 +\begin{isamarkuptext}%
40.522 +In this tutorial, we do not attempt to give an exhaustive
40.523 + description of the code generator framework; instead,
40.524 + we cast a light on advanced topics by introducing
40.525 + them together with practically motivated examples. Concerning
40.526 + further reading, see
40.527 +
40.528 + \begin{itemize}
40.529 +
40.530 + \item the Isabelle/Isar Reference Manual \cite{isabelle-isar-ref}
40.531 + for exhaustive syntax diagrams.
40.532 + \item or \cite{Haftmann-Nipkow:2007:codegen} which deals with foundational issues
40.533 + of the code generator framework.
40.534 +
40.535 + \end{itemize}%
40.536 +\end{isamarkuptext}%
40.537 +\isamarkuptrue%
40.538 +%
40.539 +\isamarkupsubsection{Library theories \label{sec:library}%
40.540 +}
40.541 +\isamarkuptrue%
40.542 +%
40.543 +\begin{isamarkuptext}%
40.544 +The \isa{HOL} \isa{Main} theory already provides a code
40.545 + generator setup
40.546 + which should be suitable for most applications. Common extensions
40.547 + and modifications are available by certain theories of the \isa{HOL}
40.548 + library; beside being useful in applications, they may serve
40.549 + as a tutorial for customizing the code generator setup.
40.550 +
40.551 + \begin{description}
40.552 +
40.553 + \item[\isa{Code{\isacharunderscore}Integer}] represents \isa{HOL} integers by big
40.554 + integer literals in target languages.
40.555 + \item[\isa{Code{\isacharunderscore}Char}] represents \isa{HOL} characters by
40.556 + character literals in target languages.
40.557 + \item[\isa{Code{\isacharunderscore}Char{\isacharunderscore}chr}] like \isa{Code{\isacharunderscore}Char},
40.558 + but also offers treatment of character codes; includes
40.559 + \isa{Code{\isacharunderscore}Integer}.
40.560 + \item[\isa{Efficient{\isacharunderscore}Nat}] \label{eff_nat} implements natural numbers by integers,
40.561 + which in general will result in higher efficency; pattern
40.562 + matching with \isa{{\isadigit{0}}} / \isa{Suc}
40.563 + is eliminated; includes \isa{Code{\isacharunderscore}Integer}.
40.564 + \item[\isa{Code{\isacharunderscore}Index}] provides an additional datatype
40.565 + \isa{index} which is mapped to target-language built-in integers.
40.566 + Useful for code setups which involve e.g. indexing of
40.567 + target-language arrays.
40.568 + \item[\isa{Code{\isacharunderscore}Message}] provides an additional datatype
40.569 + \isa{message{\isacharunderscore}string} which is isomorphic to strings;
40.570 + \isa{message{\isacharunderscore}string}s are mapped to target-language strings.
40.571 + Useful for code setups which involve e.g. printing (error) messages.
40.572 +
40.573 + \end{description}
40.574 +
40.575 + \begin{warn}
40.576 + When importing any of these theories, they should form the last
40.577 + items in an import list. Since these theories adapt the
40.578 + code generator setup in a non-conservative fashion,
40.579 + strange effects may occur otherwise.
40.580 + \end{warn}%
40.581 +\end{isamarkuptext}%
40.582 +\isamarkuptrue%
40.583 +%
40.584 +\isamarkupsubsection{Preprocessing%
40.585 +}
40.586 +\isamarkuptrue%
40.587 +%
40.588 +\begin{isamarkuptext}%
40.589 +Before selected function theorems are turned into abstract
40.590 + code, a chain of definitional transformation steps is carried
40.591 + out: \emph{preprocessing}. In essence, the preprocessor
40.592 + consists of two components: a \emph{simpset} and \emph{function transformers}.
40.593 +
40.594 + The \emph{simpset} allows to employ the full generality of the Isabelle
40.595 + simplifier. Due to the interpretation of theorems
40.596 + as defining equations, rewrites are applied to the right
40.597 + hand side and the arguments of the left hand side of an
40.598 + equation, but never to the constant heading the left hand side.
40.599 + An important special case are \emph{inline theorems} which may be
40.600 + declared an undeclared using the
40.601 + \emph{code inline} or \emph{code inline del} attribute respectively.
40.602 + Some common applications:%
40.603 +\end{isamarkuptext}%
40.604 +\isamarkuptrue%
40.605 +%
40.606 +\begin{itemize}
40.607 +%
40.608 +\begin{isamarkuptext}%
40.609 +\item replacing non-executable constructs by executable ones:%
40.610 +\end{isamarkuptext}%
40.611 +\isamarkuptrue%
40.612 +\ \ \isacommand{lemma}\isamarkupfalse%
40.613 +\ {\isacharbrackleft}code\ inline{\isacharbrackright}{\isacharcolon}\isanewline
40.614 +\ \ \ \ {\isachardoublequoteopen}x\ {\isasymin}\ set\ xs\ {\isasymlongleftrightarrow}\ x\ mem\ xs{\isachardoublequoteclose}%
40.615 +\isadelimproof
40.616 +\ %
40.617 +\endisadelimproof
40.618 +%
40.619 +\isatagproof
40.620 +\isacommand{by}\isamarkupfalse%
40.621 +\ {\isacharparenleft}induct\ xs{\isacharparenright}\ simp{\isacharunderscore}all%
40.622 +\endisatagproof
40.623 +{\isafoldproof}%
40.624 +%
40.625 +\isadelimproof
40.626 +%
40.627 +\endisadelimproof
40.628 +%
40.629 +\begin{isamarkuptext}%
40.630 +\item eliminating superfluous constants:%
40.631 +\end{isamarkuptext}%
40.632 +\isamarkuptrue%
40.633 +\ \ \isacommand{lemma}\isamarkupfalse%
40.634 +\ {\isacharbrackleft}code\ inline{\isacharbrackright}{\isacharcolon}\isanewline
40.635 +\ \ \ \ {\isachardoublequoteopen}{\isadigit{1}}\ {\isacharequal}\ Suc\ {\isadigit{0}}{\isachardoublequoteclose}%
40.636 +\isadelimproof
40.637 +\ %
40.638 +\endisadelimproof
40.639 +%
40.640 +\isatagproof
40.641 +\isacommand{by}\isamarkupfalse%
40.642 +\ simp%
40.643 +\endisatagproof
40.644 +{\isafoldproof}%
40.645 +%
40.646 +\isadelimproof
40.647 +%
40.648 +\endisadelimproof
40.649 +%
40.650 +\begin{isamarkuptext}%
40.651 +\item replacing executable but inconvenient constructs:%
40.652 +\end{isamarkuptext}%
40.653 +\isamarkuptrue%
40.654 +\ \ \isacommand{lemma}\isamarkupfalse%
40.655 +\ {\isacharbrackleft}code\ inline{\isacharbrackright}{\isacharcolon}\isanewline
40.656 +\ \ \ \ {\isachardoublequoteopen}xs\ {\isacharequal}\ {\isacharbrackleft}{\isacharbrackright}\ {\isasymlongleftrightarrow}\ List{\isachardot}null\ xs{\isachardoublequoteclose}%
40.657 +\isadelimproof
40.658 +\ %
40.659 +\endisadelimproof
40.660 +%
40.661 +\isatagproof
40.662 +\isacommand{by}\isamarkupfalse%
40.663 +\ {\isacharparenleft}induct\ xs{\isacharparenright}\ simp{\isacharunderscore}all%
40.664 +\endisatagproof
40.665 +{\isafoldproof}%
40.666 +%
40.667 +\isadelimproof
40.668 +%
40.669 +\endisadelimproof
40.670 +%
40.671 +\end{itemize}
40.672 +%
40.673 +\begin{isamarkuptext}%
40.674 +\emph{Function transformers} provide a very general interface,
40.675 + transforming a list of function theorems to another
40.676 + list of function theorems, provided that neither the heading
40.677 + constant nor its type change. The \isa{{\isadigit{0}}} / \isa{Suc}
40.678 + pattern elimination implemented in
40.679 + theory \isa{Efficient{\isacharunderscore}Nat} (see \secref{eff_nat}) uses this
40.680 + interface.
40.681 +
40.682 + \noindent The current setup of the preprocessor may be inspected using
40.683 + the \isa{{\isasymPRINTCODESETUP}} command.
40.684 +
40.685 + \begin{warn}
40.686 + The attribute \emph{code unfold}
40.687 + associated with the existing code generator also applies to
40.688 + the new one: \emph{code unfold} implies \emph{code inline}.
40.689 + \end{warn}%
40.690 +\end{isamarkuptext}%
40.691 +\isamarkuptrue%
40.692 +%
40.693 +\isamarkupsubsection{Concerning operational equality%
40.694 +}
40.695 +\isamarkuptrue%
40.696 +%
40.697 +\begin{isamarkuptext}%
40.698 +Surely you have already noticed how equality is treated
40.699 + by the code generator:%
40.700 +\end{isamarkuptext}%
40.701 +\isamarkuptrue%
40.702 +\isacommand{primrec}\isamarkupfalse%
40.703 +\isanewline
40.704 +\ \ collect{\isacharunderscore}duplicates\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharprime}a\ list\ {\isasymRightarrow}\ {\isacharprime}a\ list\ {\isasymRightarrow}\ {\isacharprime}a\ list\ {\isasymRightarrow}\ {\isacharprime}a\ list{\isachardoublequoteclose}\ \isakeyword{where}\isanewline
40.705 +\ \ \ \ {\isachardoublequoteopen}collect{\isacharunderscore}duplicates\ xs\ ys\ {\isacharbrackleft}{\isacharbrackright}\ {\isacharequal}\ xs{\isachardoublequoteclose}\isanewline
40.706 +\ \ {\isacharbar}\ {\isachardoublequoteopen}collect{\isacharunderscore}duplicates\ xs\ ys\ {\isacharparenleft}z{\isacharhash}zs{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}if\ z\ {\isasymin}\ set\ xs\isanewline
40.707 +\ \ \ \ \ \ then\ if\ z\ {\isasymin}\ set\ ys\isanewline
40.708 +\ \ \ \ \ \ \ \ then\ collect{\isacharunderscore}duplicates\ xs\ ys\ zs\isanewline
40.709 +\ \ \ \ \ \ \ \ else\ collect{\isacharunderscore}duplicates\ xs\ {\isacharparenleft}z{\isacharhash}ys{\isacharparenright}\ zs\isanewline
40.710 +\ \ \ \ \ \ else\ collect{\isacharunderscore}duplicates\ {\isacharparenleft}z{\isacharhash}xs{\isacharparenright}\ {\isacharparenleft}z{\isacharhash}ys{\isacharparenright}\ zs{\isacharparenright}{\isachardoublequoteclose}%
40.711 +\begin{isamarkuptext}%
40.712 +The membership test during preprocessing is rewritten,
40.713 + resulting in \isa{op\ mem}, which itself
40.714 + performs an explicit equality check.%
40.715 +\end{isamarkuptext}%
40.716 +\isamarkuptrue%
40.717 +\isacommand{export{\isacharunderscore}code}\isamarkupfalse%
40.718 +\ collect{\isacharunderscore}duplicates\ \isakeyword{in}\ SML\ \isakeyword{file}\ {\isachardoublequoteopen}examples{\isacharslash}collect{\isacharunderscore}duplicates{\isachardot}ML{\isachardoublequoteclose}%
40.719 +\begin{isamarkuptext}%
40.720 +\lstsml{Thy/examples/collect_duplicates.ML}%
40.721 +\end{isamarkuptext}%
40.722 +\isamarkuptrue%
40.723 +%
40.724 +\begin{isamarkuptext}%
40.725 +Obviously, polymorphic equality is implemented the Haskell
40.726 + way using a type class. How is this achieved? HOL introduces
40.727 + an explicit class \isa{eq} with a corresponding operation
40.728 + \isa{eq{\isacharunderscore}class{\isachardot}eq} such that \isa{eq{\isacharunderscore}class{\isachardot}eq\ x\ y\ {\isacharequal}\ {\isacharparenleft}x\ {\isacharequal}\ y{\isacharparenright}}.
40.729 + The preprocessing framework does the rest.
40.730 + For datatypes, instances of \isa{eq} are implicitly derived
40.731 + when possible. For other types, you may instantiate \isa{eq}
40.732 + manually like any other type class.
40.733 +
40.734 + Though this \isa{eq} class is designed to get rarely in
40.735 + the way, a subtlety
40.736 + enters the stage when definitions of overloaded constants
40.737 + are dependent on operational equality. For example, let
40.738 + us define a lexicographic ordering on tuples:%
40.739 +\end{isamarkuptext}%
40.740 +\isamarkuptrue%
40.741 +\isacommand{instantiation}\isamarkupfalse%
40.742 +\ {\isacharasterisk}\ {\isacharcolon}{\isacharcolon}\ {\isacharparenleft}ord{\isacharcomma}\ ord{\isacharparenright}\ ord\isanewline
40.743 +\isakeyword{begin}\isanewline
40.744 +\isanewline
40.745 +\isacommand{definition}\isamarkupfalse%
40.746 +\isanewline
40.747 +\ \ {\isacharbrackleft}code\ func\ del{\isacharbrackright}{\isacharcolon}\ {\isachardoublequoteopen}p{\isadigit{1}}\ {\isacharless}\ p{\isadigit{2}}\ {\isasymlongleftrightarrow}\ {\isacharparenleft}let\ {\isacharparenleft}x{\isadigit{1}}{\isacharcomma}\ y{\isadigit{1}}{\isacharparenright}\ {\isacharequal}\ p{\isadigit{1}}{\isacharsemicolon}\ {\isacharparenleft}x{\isadigit{2}}{\isacharcomma}\ y{\isadigit{2}}{\isacharparenright}\ {\isacharequal}\ p{\isadigit{2}}\ in\isanewline
40.748 +\ \ \ \ x{\isadigit{1}}\ {\isacharless}\ x{\isadigit{2}}\ {\isasymor}\ {\isacharparenleft}x{\isadigit{1}}\ {\isacharequal}\ x{\isadigit{2}}\ {\isasymand}\ y{\isadigit{1}}\ {\isacharless}\ y{\isadigit{2}}{\isacharparenright}{\isacharparenright}{\isachardoublequoteclose}\isanewline
40.749 +\isanewline
40.750 +\isacommand{definition}\isamarkupfalse%
40.751 +\isanewline
40.752 +\ \ {\isacharbrackleft}code\ func\ del{\isacharbrackright}{\isacharcolon}\ {\isachardoublequoteopen}p{\isadigit{1}}\ {\isasymle}\ p{\isadigit{2}}\ {\isasymlongleftrightarrow}\ {\isacharparenleft}let\ {\isacharparenleft}x{\isadigit{1}}{\isacharcomma}\ y{\isadigit{1}}{\isacharparenright}\ {\isacharequal}\ p{\isadigit{1}}{\isacharsemicolon}\ {\isacharparenleft}x{\isadigit{2}}{\isacharcomma}\ y{\isadigit{2}}{\isacharparenright}\ {\isacharequal}\ p{\isadigit{2}}\ in\isanewline
40.753 +\ \ \ \ x{\isadigit{1}}\ {\isacharless}\ x{\isadigit{2}}\ {\isasymor}\ {\isacharparenleft}x{\isadigit{1}}\ {\isacharequal}\ x{\isadigit{2}}\ {\isasymand}\ y{\isadigit{1}}\ {\isasymle}\ y{\isadigit{2}}{\isacharparenright}{\isacharparenright}{\isachardoublequoteclose}\isanewline
40.754 +\isanewline
40.755 +\isacommand{instance}\isamarkupfalse%
40.756 +%
40.757 +\isadelimproof
40.758 +\ %
40.759 +\endisadelimproof
40.760 +%
40.761 +\isatagproof
40.762 +\isacommand{{\isachardot}{\isachardot}}\isamarkupfalse%
40.763 +%
40.764 +\endisatagproof
40.765 +{\isafoldproof}%
40.766 +%
40.767 +\isadelimproof
40.768 +%
40.769 +\endisadelimproof
40.770 +\isanewline
40.771 +\isanewline
40.772 +\isacommand{end}\isamarkupfalse%
40.773 +\isanewline
40.774 +\isanewline
40.775 +\isacommand{lemma}\isamarkupfalse%
40.776 +\ ord{\isacharunderscore}prod\ {\isacharbrackleft}code\ func{\isacharbrackright}{\isacharcolon}\isanewline
40.777 +\ \ {\isachardoublequoteopen}{\isacharparenleft}x{\isadigit{1}}\ {\isasymColon}\ {\isacharprime}a{\isasymColon}ord{\isacharcomma}\ y{\isadigit{1}}\ {\isasymColon}\ {\isacharprime}b{\isasymColon}ord{\isacharparenright}\ {\isacharless}\ {\isacharparenleft}x{\isadigit{2}}{\isacharcomma}\ y{\isadigit{2}}{\isacharparenright}\ {\isasymlongleftrightarrow}\ x{\isadigit{1}}\ {\isacharless}\ x{\isadigit{2}}\ {\isasymor}\ {\isacharparenleft}x{\isadigit{1}}\ {\isacharequal}\ x{\isadigit{2}}\ {\isasymand}\ y{\isadigit{1}}\ {\isacharless}\ y{\isadigit{2}}{\isacharparenright}{\isachardoublequoteclose}\isanewline
40.778 +\ \ {\isachardoublequoteopen}{\isacharparenleft}x{\isadigit{1}}\ {\isasymColon}\ {\isacharprime}a{\isasymColon}ord{\isacharcomma}\ y{\isadigit{1}}\ {\isasymColon}\ {\isacharprime}b{\isasymColon}ord{\isacharparenright}\ {\isasymle}\ {\isacharparenleft}x{\isadigit{2}}{\isacharcomma}\ y{\isadigit{2}}{\isacharparenright}\ {\isasymlongleftrightarrow}\ x{\isadigit{1}}\ {\isacharless}\ x{\isadigit{2}}\ {\isasymor}\ {\isacharparenleft}x{\isadigit{1}}\ {\isacharequal}\ x{\isadigit{2}}\ {\isasymand}\ y{\isadigit{1}}\ {\isasymle}\ y{\isadigit{2}}{\isacharparenright}{\isachardoublequoteclose}\isanewline
40.779 +%
40.780 +\isadelimproof
40.781 +\ \ %
40.782 +\endisadelimproof
40.783 +%
40.784 +\isatagproof
40.785 +\isacommand{unfolding}\isamarkupfalse%
40.786 +\ less{\isacharunderscore}prod{\isacharunderscore}def\ less{\isacharunderscore}eq{\isacharunderscore}prod{\isacharunderscore}def\ \isacommand{by}\isamarkupfalse%
40.787 +\ simp{\isacharunderscore}all%
40.788 +\endisatagproof
40.789 +{\isafoldproof}%
40.790 +%
40.791 +\isadelimproof
40.792 +%
40.793 +\endisadelimproof
40.794 +%
40.795 +\begin{isamarkuptext}%
40.796 +Then code generation will fail. Why? The definition
40.797 + of \isa{op\ {\isasymle}} depends on equality on both arguments,
40.798 + which are polymorphic and impose an additional \isa{eq}
40.799 + class constraint, thus violating the type discipline
40.800 + for class operations.
40.801 +
40.802 + The solution is to add \isa{eq} explicitly to the first sort arguments in the
40.803 + code theorems:%
40.804 +\end{isamarkuptext}%
40.805 +\isamarkuptrue%
40.806 +\isacommand{lemma}\isamarkupfalse%
40.807 +\ ord{\isacharunderscore}prod{\isacharunderscore}code\ {\isacharbrackleft}code\ func{\isacharbrackright}{\isacharcolon}\isanewline
40.808 +\ \ {\isachardoublequoteopen}{\isacharparenleft}x{\isadigit{1}}\ {\isasymColon}\ {\isacharprime}a{\isasymColon}{\isacharbraceleft}ord{\isacharcomma}\ eq{\isacharbraceright}{\isacharcomma}\ y{\isadigit{1}}\ {\isasymColon}\ {\isacharprime}b{\isasymColon}ord{\isacharparenright}\ {\isacharless}\ {\isacharparenleft}x{\isadigit{2}}{\isacharcomma}\ y{\isadigit{2}}{\isacharparenright}\ {\isasymlongleftrightarrow}\isanewline
40.809 +\ \ \ \ x{\isadigit{1}}\ {\isacharless}\ x{\isadigit{2}}\ {\isasymor}\ {\isacharparenleft}x{\isadigit{1}}\ {\isacharequal}\ x{\isadigit{2}}\ {\isasymand}\ y{\isadigit{1}}\ {\isacharless}\ y{\isadigit{2}}{\isacharparenright}{\isachardoublequoteclose}\isanewline
40.810 +\ \ {\isachardoublequoteopen}{\isacharparenleft}x{\isadigit{1}}\ {\isasymColon}\ {\isacharprime}a{\isasymColon}{\isacharbraceleft}ord{\isacharcomma}\ eq{\isacharbraceright}{\isacharcomma}\ y{\isadigit{1}}\ {\isasymColon}\ {\isacharprime}b{\isasymColon}ord{\isacharparenright}\ {\isasymle}\ {\isacharparenleft}x{\isadigit{2}}{\isacharcomma}\ y{\isadigit{2}}{\isacharparenright}\ {\isasymlongleftrightarrow}\isanewline
40.811 +\ \ \ \ x{\isadigit{1}}\ {\isacharless}\ x{\isadigit{2}}\ {\isasymor}\ {\isacharparenleft}x{\isadigit{1}}\ {\isacharequal}\ x{\isadigit{2}}\ {\isasymand}\ y{\isadigit{1}}\ {\isasymle}\ y{\isadigit{2}}{\isacharparenright}{\isachardoublequoteclose}\isanewline
40.812 +%
40.813 +\isadelimproof
40.814 +\ \ %
40.815 +\endisadelimproof
40.816 +%
40.817 +\isatagproof
40.818 +\isacommand{unfolding}\isamarkupfalse%
40.819 +\ ord{\isacharunderscore}prod\ \isacommand{by}\isamarkupfalse%
40.820 +\ rule{\isacharplus}%
40.821 +\endisatagproof
40.822 +{\isafoldproof}%
40.823 +%
40.824 +\isadelimproof
40.825 +%
40.826 +\endisadelimproof
40.827 +%
40.828 +\begin{isamarkuptext}%
40.829 +\noindent Then code generation succeeds:%
40.830 +\end{isamarkuptext}%
40.831 +\isamarkuptrue%
40.832 +\isacommand{export{\isacharunderscore}code}\isamarkupfalse%
40.833 +\ {\isachardoublequoteopen}op\ {\isasymle}\ {\isasymColon}\ {\isacharprime}a{\isasymColon}{\isacharbraceleft}eq{\isacharcomma}\ ord{\isacharbraceright}\ {\isasymtimes}\ {\isacharprime}b{\isasymColon}ord\ {\isasymRightarrow}\ {\isacharprime}a\ {\isasymtimes}\ {\isacharprime}b\ {\isasymRightarrow}\ bool{\isachardoublequoteclose}\isanewline
40.834 +\ \ \isakeyword{in}\ SML\ \isakeyword{file}\ {\isachardoublequoteopen}examples{\isacharslash}lexicographic{\isachardot}ML{\isachardoublequoteclose}%
40.835 +\begin{isamarkuptext}%
40.836 +\lstsml{Thy/examples/lexicographic.ML}%
40.837 +\end{isamarkuptext}%
40.838 +\isamarkuptrue%
40.839 +%
40.840 +\begin{isamarkuptext}%
40.841 +In general, code theorems for overloaded constants may have more
40.842 + restrictive sort constraints than the underlying instance relation
40.843 + between class and type constructor as long as the whole system of
40.844 + constraints is coregular; code theorems violating coregularity
40.845 + are rejected immediately. Consequently, it might be necessary
40.846 + to delete disturbing theorems in the code theorem table,
40.847 + as we have done here with the original definitions \isa{less{\isacharunderscore}prod{\isacharunderscore}def}
40.848 + and \isa{less{\isacharunderscore}eq{\isacharunderscore}prod{\isacharunderscore}def}.
40.849 +
40.850 + In some cases, the automatically derived defining equations
40.851 + for equality on a particular type may not be appropriate.
40.852 + As example, watch the following datatype representing
40.853 + monomorphic parametric types (where type constructors
40.854 + are referred to by natural numbers):%
40.855 +\end{isamarkuptext}%
40.856 +\isamarkuptrue%
40.857 +\isacommand{datatype}\isamarkupfalse%
40.858 +\ monotype\ {\isacharequal}\ Mono\ nat\ {\isachardoublequoteopen}monotype\ list{\isachardoublequoteclose}%
40.859 +\isadelimproof
40.860 +%
40.861 +\endisadelimproof
40.862 +%
40.863 +\isatagproof
40.864 +%
40.865 +\endisatagproof
40.866 +{\isafoldproof}%
40.867 +%
40.868 +\isadelimproof
40.869 +%
40.870 +\endisadelimproof
40.871 +%
40.872 +\begin{isamarkuptext}%
40.873 +Then code generation for SML would fail with a message
40.874 + that the generated code conains illegal mutual dependencies:
40.875 + the theorem \isa{Mono\ tyco{\isadigit{1}}\ typargs{\isadigit{1}}\ {\isacharequal}\ Mono\ tyco{\isadigit{2}}\ typargs{\isadigit{2}}\ {\isasymequiv}\ tyco{\isadigit{1}}\ {\isacharequal}\ tyco{\isadigit{2}}\ {\isasymand}\ typargs{\isadigit{1}}\ {\isacharequal}\ typargs{\isadigit{2}}} already requires the
40.876 + instance \isa{monotype\ {\isasymColon}\ eq}, which itself requires
40.877 + \isa{Mono\ tyco{\isadigit{1}}\ typargs{\isadigit{1}}\ {\isacharequal}\ Mono\ tyco{\isadigit{2}}\ typargs{\isadigit{2}}\ {\isasymequiv}\ tyco{\isadigit{1}}\ {\isacharequal}\ tyco{\isadigit{2}}\ {\isasymand}\ typargs{\isadigit{1}}\ {\isacharequal}\ typargs{\isadigit{2}}}; Haskell has no problem with mutually
40.878 + recursive \isa{instance} and \isa{function} definitions,
40.879 + but the SML serializer does not support this.
40.880 +
40.881 + In such cases, you have to provide you own equality equations
40.882 + involving auxiliary constants. In our case,
40.883 + \isa{list{\isacharunderscore}all{\isadigit{2}}} can do the job:%
40.884 +\end{isamarkuptext}%
40.885 +\isamarkuptrue%
40.886 +\isacommand{lemma}\isamarkupfalse%
40.887 +\ monotype{\isacharunderscore}eq{\isacharunderscore}list{\isacharunderscore}all{\isadigit{2}}\ {\isacharbrackleft}code\ func{\isacharbrackright}{\isacharcolon}\isanewline
40.888 +\ \ {\isachardoublequoteopen}Mono\ tyco{\isadigit{1}}\ typargs{\isadigit{1}}\ {\isacharequal}\ Mono\ tyco{\isadigit{2}}\ typargs{\isadigit{2}}\ {\isasymlongleftrightarrow}\isanewline
40.889 +\ \ \ \ \ tyco{\isadigit{1}}\ {\isacharequal}\ tyco{\isadigit{2}}\ {\isasymand}\ list{\isacharunderscore}all{\isadigit{2}}\ {\isacharparenleft}op\ {\isacharequal}{\isacharparenright}\ typargs{\isadigit{1}}\ typargs{\isadigit{2}}{\isachardoublequoteclose}\isanewline
40.890 +%
40.891 +\isadelimproof
40.892 +\ \ %
40.893 +\endisadelimproof
40.894 +%
40.895 +\isatagproof
40.896 +\isacommand{by}\isamarkupfalse%
40.897 +\ {\isacharparenleft}simp\ add{\isacharcolon}\ list{\isacharunderscore}all{\isadigit{2}}{\isacharunderscore}eq\ {\isacharbrackleft}symmetric{\isacharbrackright}{\isacharparenright}%
40.898 +\endisatagproof
40.899 +{\isafoldproof}%
40.900 +%
40.901 +\isadelimproof
40.902 +%
40.903 +\endisadelimproof
40.904 +%
40.905 +\begin{isamarkuptext}%
40.906 +does not depend on instance \isa{monotype\ {\isasymColon}\ eq}:%
40.907 +\end{isamarkuptext}%
40.908 +\isamarkuptrue%
40.909 +\isacommand{export{\isacharunderscore}code}\isamarkupfalse%
40.910 +\ {\isachardoublequoteopen}op\ {\isacharequal}\ {\isacharcolon}{\isacharcolon}\ monotype\ {\isasymRightarrow}\ monotype\ {\isasymRightarrow}\ bool{\isachardoublequoteclose}\isanewline
40.911 +\ \ \isakeyword{in}\ SML\ \isakeyword{file}\ {\isachardoublequoteopen}examples{\isacharslash}monotype{\isachardot}ML{\isachardoublequoteclose}%
40.912 +\begin{isamarkuptext}%
40.913 +\lstsml{Thy/examples/monotype.ML}%
40.914 +\end{isamarkuptext}%
40.915 +\isamarkuptrue%
40.916 +%
40.917 +\isamarkupsubsection{Programs as sets of theorems%
40.918 +}
40.919 +\isamarkuptrue%
40.920 +%
40.921 +\begin{isamarkuptext}%
40.922 +As told in \secref{sec:concept}, code generation is based
40.923 + on a structured collection of code theorems.
40.924 + For explorative purpose, this collection
40.925 + may be inspected using the \isa{{\isasymCODETHMS}} command:%
40.926 +\end{isamarkuptext}%
40.927 +\isamarkuptrue%
40.928 +\isacommand{code{\isacharunderscore}thms}\isamarkupfalse%
40.929 +\ {\isachardoublequoteopen}op\ mod\ {\isacharcolon}{\isacharcolon}\ nat\ {\isasymRightarrow}\ nat\ {\isasymRightarrow}\ nat{\isachardoublequoteclose}%
40.930 +\begin{isamarkuptext}%
40.931 +\noindent prints a table with \emph{all} defining equations
40.932 + for \isa{op\ mod}, including
40.933 + \emph{all} defining equations those equations depend
40.934 + on recursivly. \isa{{\isasymCODETHMS}} provides a convenient
40.935 + mechanism to inspect the impact of a preprocessor setup
40.936 + on defining equations.
40.937 +
40.938 + Similarly, the \isa{{\isasymCODEDEPS}} command shows a graph
40.939 + visualizing dependencies between defining equations.%
40.940 +\end{isamarkuptext}%
40.941 +\isamarkuptrue%
40.942 +%
40.943 +\isamarkupsubsection{Constructor sets for datatypes%
40.944 +}
40.945 +\isamarkuptrue%
40.946 +%
40.947 +\begin{isamarkuptext}%
40.948 +Conceptually, any datatype is spanned by a set of
40.949 + \emph{constructors} of type \isa{{\isasymtau}\ {\isacharequal}\ {\isasymdots}\ {\isasymRightarrow}\ {\isasymkappa}\ {\isasymalpha}\isactrlisub {\isadigit{1}}\ {\isasymdots}\ {\isasymalpha}\isactrlisub n}
40.950 + where \isa{{\isacharbraceleft}{\isasymalpha}\isactrlisub {\isadigit{1}}{\isacharcomma}\ {\isasymdots}{\isacharcomma}\ {\isasymalpha}\isactrlisub n{\isacharbraceright}} is excactly the set of \emph{all}
40.951 + type variables in \isa{{\isasymtau}}. The HOL datatype package
40.952 + by default registers any new datatype in the table
40.953 + of datatypes, which may be inspected using
40.954 + the \isa{{\isasymPRINTCODESETUP}} command.
40.955 +
40.956 + In some cases, it may be convenient to alter or
40.957 + extend this table; as an example, we will develope an alternative
40.958 + representation of natural numbers as binary digits, whose
40.959 + size does increase logarithmically with its value, not linear
40.960 + \footnote{Indeed, the \isa{Efficient{\isacharunderscore}Nat} theory (see \ref{eff_nat})
40.961 + does something similar}. First, the digit representation:%
40.962 +\end{isamarkuptext}%
40.963 +\isamarkuptrue%
40.964 +\isacommand{definition}\isamarkupfalse%
40.965 +\ Dig{\isadigit{0}}\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymRightarrow}\ nat{\isachardoublequoteclose}\ \isakeyword{where}\isanewline
40.966 +\ \ {\isachardoublequoteopen}Dig{\isadigit{0}}\ n\ {\isacharequal}\ {\isadigit{2}}\ {\isacharasterisk}\ n{\isachardoublequoteclose}\isanewline
40.967 +\isanewline
40.968 +\isacommand{definition}\isamarkupfalse%
40.969 +\ Dig{\isadigit{1}}\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymRightarrow}\ nat{\isachardoublequoteclose}\ \isakeyword{where}\isanewline
40.970 +\ \ {\isachardoublequoteopen}Dig{\isadigit{1}}\ n\ {\isacharequal}\ Suc\ {\isacharparenleft}{\isadigit{2}}\ {\isacharasterisk}\ n{\isacharparenright}{\isachardoublequoteclose}%
40.971 +\begin{isamarkuptext}%
40.972 +\noindent We will use these two ">digits"< to represent natural numbers
40.973 + in binary digits, e.g.:%
40.974 +\end{isamarkuptext}%
40.975 +\isamarkuptrue%
40.976 +\isacommand{lemma}\isamarkupfalse%
40.977 +\ {\isadigit{4}}{\isadigit{2}}{\isacharcolon}\ {\isachardoublequoteopen}{\isadigit{4}}{\isadigit{2}}\ {\isacharequal}\ Dig{\isadigit{0}}\ {\isacharparenleft}Dig{\isadigit{1}}\ {\isacharparenleft}Dig{\isadigit{0}}\ {\isacharparenleft}Dig{\isadigit{1}}\ {\isacharparenleft}Dig{\isadigit{0}}\ {\isadigit{1}}{\isacharparenright}{\isacharparenright}{\isacharparenright}{\isacharparenright}{\isachardoublequoteclose}\isanewline
40.978 +%
40.979 +\isadelimproof
40.980 +\ \ %
40.981 +\endisadelimproof
40.982 +%
40.983 +\isatagproof
40.984 +\isacommand{by}\isamarkupfalse%
40.985 +\ {\isacharparenleft}simp\ add{\isacharcolon}\ Dig{\isadigit{0}}{\isacharunderscore}def\ Dig{\isadigit{1}}{\isacharunderscore}def{\isacharparenright}%
40.986 +\endisatagproof
40.987 +{\isafoldproof}%
40.988 +%
40.989 +\isadelimproof
40.990 +%
40.991 +\endisadelimproof
40.992 +%
40.993 +\begin{isamarkuptext}%
40.994 +\noindent Of course we also have to provide proper code equations for
40.995 + the operations, e.g. \isa{op\ {\isacharplus}}:%
40.996 +\end{isamarkuptext}%
40.997 +\isamarkuptrue%
40.998 +\isacommand{lemma}\isamarkupfalse%
40.999 +\ plus{\isacharunderscore}Dig\ {\isacharbrackleft}code\ func{\isacharbrackright}{\isacharcolon}\isanewline
40.1000 +\ \ {\isachardoublequoteopen}{\isadigit{0}}\ {\isacharplus}\ n\ {\isacharequal}\ n{\isachardoublequoteclose}\isanewline
40.1001 +\ \ {\isachardoublequoteopen}m\ {\isacharplus}\ {\isadigit{0}}\ {\isacharequal}\ m{\isachardoublequoteclose}\isanewline
40.1002 +\ \ {\isachardoublequoteopen}{\isadigit{1}}\ {\isacharplus}\ Dig{\isadigit{0}}\ n\ {\isacharequal}\ Dig{\isadigit{1}}\ n{\isachardoublequoteclose}\isanewline
40.1003 +\ \ {\isachardoublequoteopen}Dig{\isadigit{0}}\ m\ {\isacharplus}\ {\isadigit{1}}\ {\isacharequal}\ Dig{\isadigit{1}}\ m{\isachardoublequoteclose}\isanewline
40.1004 +\ \ {\isachardoublequoteopen}{\isadigit{1}}\ {\isacharplus}\ Dig{\isadigit{1}}\ n\ {\isacharequal}\ Dig{\isadigit{0}}\ {\isacharparenleft}n\ {\isacharplus}\ {\isadigit{1}}{\isacharparenright}{\isachardoublequoteclose}\isanewline
40.1005 +\ \ {\isachardoublequoteopen}Dig{\isadigit{1}}\ m\ {\isacharplus}\ {\isadigit{1}}\ {\isacharequal}\ Dig{\isadigit{0}}\ {\isacharparenleft}m\ {\isacharplus}\ {\isadigit{1}}{\isacharparenright}{\isachardoublequoteclose}\isanewline
40.1006 +\ \ {\isachardoublequoteopen}Dig{\isadigit{0}}\ m\ {\isacharplus}\ Dig{\isadigit{0}}\ n\ {\isacharequal}\ Dig{\isadigit{0}}\ {\isacharparenleft}m\ {\isacharplus}\ n{\isacharparenright}{\isachardoublequoteclose}\isanewline
40.1007 +\ \ {\isachardoublequoteopen}Dig{\isadigit{0}}\ m\ {\isacharplus}\ Dig{\isadigit{1}}\ n\ {\isacharequal}\ Dig{\isadigit{1}}\ {\isacharparenleft}m\ {\isacharplus}\ n{\isacharparenright}{\isachardoublequoteclose}\isanewline
40.1008 +\ \ {\isachardoublequoteopen}Dig{\isadigit{1}}\ m\ {\isacharplus}\ Dig{\isadigit{0}}\ n\ {\isacharequal}\ Dig{\isadigit{1}}\ {\isacharparenleft}m\ {\isacharplus}\ n{\isacharparenright}{\isachardoublequoteclose}\isanewline
40.1009 +\ \ {\isachardoublequoteopen}Dig{\isadigit{1}}\ m\ {\isacharplus}\ Dig{\isadigit{1}}\ n\ {\isacharequal}\ Dig{\isadigit{0}}\ {\isacharparenleft}m\ {\isacharplus}\ n\ {\isacharplus}\ {\isadigit{1}}{\isacharparenright}{\isachardoublequoteclose}\isanewline
40.1010 +%
40.1011 +\isadelimproof
40.1012 +\ \ %
40.1013 +\endisadelimproof
40.1014 +%
40.1015 +\isatagproof
40.1016 +\isacommand{by}\isamarkupfalse%
40.1017 +\ {\isacharparenleft}simp{\isacharunderscore}all\ add{\isacharcolon}\ Dig{\isadigit{0}}{\isacharunderscore}def\ Dig{\isadigit{1}}{\isacharunderscore}def{\isacharparenright}%
40.1018 +\endisatagproof
40.1019 +{\isafoldproof}%
40.1020 +%
40.1021 +\isadelimproof
40.1022 +%
40.1023 +\endisadelimproof
40.1024 +%
40.1025 +\begin{isamarkuptext}%
40.1026 +\noindent We then instruct the code generator to view \isa{{\isadigit{0}}},
40.1027 + \isa{{\isadigit{1}}}, \isa{Dig{\isadigit{0}}} and \isa{Dig{\isadigit{1}}} as
40.1028 + datatype constructors:%
40.1029 +\end{isamarkuptext}%
40.1030 +\isamarkuptrue%
40.1031 +\isacommand{code{\isacharunderscore}datatype}\isamarkupfalse%
40.1032 +\ {\isachardoublequoteopen}{\isadigit{0}}{\isasymColon}nat{\isachardoublequoteclose}\ {\isachardoublequoteopen}{\isadigit{1}}{\isasymColon}nat{\isachardoublequoteclose}\ Dig{\isadigit{0}}\ Dig{\isadigit{1}}%
40.1033 +\begin{isamarkuptext}%
40.1034 +\noindent For the former constructor \isa{Suc}, we provide a code
40.1035 + equation and remove some parts of the default code generator setup
40.1036 + which are an obstacle here:%
40.1037 +\end{isamarkuptext}%
40.1038 +\isamarkuptrue%
40.1039 +\isacommand{lemma}\isamarkupfalse%
40.1040 +\ Suc{\isacharunderscore}Dig\ {\isacharbrackleft}code\ func{\isacharbrackright}{\isacharcolon}\isanewline
40.1041 +\ \ {\isachardoublequoteopen}Suc\ n\ {\isacharequal}\ n\ {\isacharplus}\ {\isadigit{1}}{\isachardoublequoteclose}\isanewline
40.1042 +%
40.1043 +\isadelimproof
40.1044 +\ \ %
40.1045 +\endisadelimproof
40.1046 +%
40.1047 +\isatagproof
40.1048 +\isacommand{by}\isamarkupfalse%
40.1049 +\ simp%
40.1050 +\endisatagproof
40.1051 +{\isafoldproof}%
40.1052 +%
40.1053 +\isadelimproof
40.1054 +\isanewline
40.1055 +%
40.1056 +\endisadelimproof
40.1057 +\isanewline
40.1058 +\isacommand{declare}\isamarkupfalse%
40.1059 +\ One{\isacharunderscore}nat{\isacharunderscore}def\ {\isacharbrackleft}code\ inline\ del{\isacharbrackright}\isanewline
40.1060 +\isacommand{declare}\isamarkupfalse%
40.1061 +\ add{\isacharunderscore}Suc{\isacharunderscore}shift\ {\isacharbrackleft}code\ func\ del{\isacharbrackright}%
40.1062 +\begin{isamarkuptext}%
40.1063 +\noindent This yields the following code:%
40.1064 +\end{isamarkuptext}%
40.1065 +\isamarkuptrue%
40.1066 +\isacommand{export{\isacharunderscore}code}\isamarkupfalse%
40.1067 +\ {\isachardoublequoteopen}op\ {\isacharplus}\ {\isasymColon}\ nat\ {\isasymRightarrow}\ nat\ {\isasymRightarrow}\ nat{\isachardoublequoteclose}\ \ \isakeyword{in}\ SML\ \isakeyword{file}\ {\isachardoublequoteopen}examples{\isacharslash}nat{\isacharunderscore}binary{\isachardot}ML{\isachardoublequoteclose}%
40.1068 +\begin{isamarkuptext}%
40.1069 +\lstsml{Thy/examples/nat_binary.ML}%
40.1070 +\end{isamarkuptext}%
40.1071 +\isamarkuptrue%
40.1072 +%
40.1073 +\begin{isamarkuptext}%
40.1074 +\medskip
40.1075 +
40.1076 + From this example, it can be easily glimpsed that using own constructor sets
40.1077 + is a little delicate since it changes the set of valid patterns for values
40.1078 + of that type. Without going into much detail, here some practical hints:
40.1079 +
40.1080 + \begin{itemize}
40.1081 + \item When changing the constuctor set for datatypes, take care to
40.1082 + provide an alternative for the \isa{case} combinator (e.g. by replacing
40.1083 + it using the preprocessor).
40.1084 + \item Values in the target language need not to be normalized -- different
40.1085 + values in the target language may represent the same value in the
40.1086 + logic (e.g. \isa{Dig{\isadigit{1}}\ {\isadigit{0}}\ {\isacharequal}\ {\isadigit{1}}}).
40.1087 + \item Usually, a good methodology to deal with the subleties of pattern
40.1088 + matching is to see the type as an abstract type: provide a set
40.1089 + of operations which operate on the concrete representation of the type,
40.1090 + and derive further operations by combinations of these primitive ones,
40.1091 + without relying on a particular representation.
40.1092 + \end{itemize}%
40.1093 +\end{isamarkuptext}%
40.1094 +\isamarkuptrue%
40.1095 +%
40.1096 +\isadeliminvisible
40.1097 +%
40.1098 +\endisadeliminvisible
40.1099 +%
40.1100 +\isataginvisible
40.1101 +\isacommand{code{\isacharunderscore}datatype}\isamarkupfalse%
40.1102 +\ {\isachardoublequoteopen}{\isadigit{0}}{\isacharcolon}{\isacharcolon}nat{\isachardoublequoteclose}\ Suc\isanewline
40.1103 +\isacommand{declare}\isamarkupfalse%
40.1104 +\ plus{\isacharunderscore}Dig\ {\isacharbrackleft}code\ func\ del{\isacharbrackright}\isanewline
40.1105 +\isacommand{declare}\isamarkupfalse%
40.1106 +\ One{\isacharunderscore}nat{\isacharunderscore}def\ {\isacharbrackleft}code\ inline{\isacharbrackright}\isanewline
40.1107 +\isacommand{declare}\isamarkupfalse%
40.1108 +\ add{\isacharunderscore}Suc{\isacharunderscore}shift\ {\isacharbrackleft}code\ func{\isacharbrackright}\ \isanewline
40.1109 +\isacommand{lemma}\isamarkupfalse%
40.1110 +\ {\isacharbrackleft}code\ func{\isacharbrackright}{\isacharcolon}\ {\isachardoublequoteopen}{\isadigit{0}}\ {\isacharplus}\ n\ {\isacharequal}\ {\isacharparenleft}n\ {\isasymColon}\ nat{\isacharparenright}{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse%
40.1111 +\ simp%
40.1112 +\endisataginvisible
40.1113 +{\isafoldinvisible}%
40.1114 +%
40.1115 +\isadeliminvisible
40.1116 +%
40.1117 +\endisadeliminvisible
40.1118 +%
40.1119 +\isamarkupsubsection{Customizing serialization%
40.1120 +}
40.1121 +\isamarkuptrue%
40.1122 +%
40.1123 +\isamarkupsubsubsection{Basics%
40.1124 +}
40.1125 +\isamarkuptrue%
40.1126 +%
40.1127 +\begin{isamarkuptext}%
40.1128 +Consider the following function and its corresponding
40.1129 + SML code:%
40.1130 +\end{isamarkuptext}%
40.1131 +\isamarkuptrue%
40.1132 +\isacommand{primrec}\isamarkupfalse%
40.1133 +\isanewline
40.1134 +\ \ in{\isacharunderscore}interval\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymtimes}\ nat\ {\isasymRightarrow}\ nat\ {\isasymRightarrow}\ bool{\isachardoublequoteclose}\ \isakeyword{where}\isanewline
40.1135 +\ \ {\isachardoublequoteopen}in{\isacharunderscore}interval\ {\isacharparenleft}k{\isacharcomma}\ l{\isacharparenright}\ n\ {\isasymlongleftrightarrow}\ k\ {\isasymle}\ n\ {\isasymand}\ n\ {\isasymle}\ l{\isachardoublequoteclose}%
40.1136 +\isadelimtt
40.1137 +%
40.1138 +\endisadelimtt
40.1139 +%
40.1140 +\isatagtt
40.1141 +%
40.1142 +\endisatagtt
40.1143 +{\isafoldtt}%
40.1144 +%
40.1145 +\isadelimtt
40.1146 +%
40.1147 +\endisadelimtt
40.1148 +\isacommand{export{\isacharunderscore}code}\isamarkupfalse%
40.1149 +\ in{\isacharunderscore}interval\ \isakeyword{in}\ SML\ \isakeyword{file}\ {\isachardoublequoteopen}examples{\isacharslash}bool{\isacharunderscore}literal{\isachardot}ML{\isachardoublequoteclose}%
40.1150 +\begin{isamarkuptext}%
40.1151 +\lstsml{Thy/examples/bool_literal.ML}
40.1152 +
40.1153 + \noindent Though this is correct code, it is a little bit unsatisfactory:
40.1154 + boolean values and operators are materialized as distinguished
40.1155 + entities with have nothing to do with the SML-builtin notion
40.1156 + of \qt{bool}. This results in less readable code;
40.1157 + additionally, eager evaluation may cause programs to
40.1158 + loop or break which would perfectly terminate when
40.1159 + the existing SML \qt{bool} would be used. To map
40.1160 + the HOL \qt{bool} on SML \qt{bool}, we may use
40.1161 + \qn{custom serializations}:%
40.1162 +\end{isamarkuptext}%
40.1163 +\isamarkuptrue%
40.1164 +%
40.1165 +\isadelimtt
40.1166 +%
40.1167 +\endisadelimtt
40.1168 +%
40.1169 +\isatagtt
40.1170 +\isacommand{code{\isacharunderscore}type}\isamarkupfalse%
40.1171 +\ bool\isanewline
40.1172 +\ \ {\isacharparenleft}SML\ {\isachardoublequoteopen}bool{\isachardoublequoteclose}{\isacharparenright}\isanewline
40.1173 +\isacommand{code{\isacharunderscore}const}\isamarkupfalse%
40.1174 +\ True\ \isakeyword{and}\ False\ \isakeyword{and}\ {\isachardoublequoteopen}op\ {\isasymand}{\isachardoublequoteclose}\isanewline
40.1175 +\ \ {\isacharparenleft}SML\ {\isachardoublequoteopen}true{\isachardoublequoteclose}\ \isakeyword{and}\ {\isachardoublequoteopen}false{\isachardoublequoteclose}\ \isakeyword{and}\ {\isachardoublequoteopen}{\isacharunderscore}\ andalso\ {\isacharunderscore}{\isachardoublequoteclose}{\isacharparenright}%
40.1176 +\endisatagtt
40.1177 +{\isafoldtt}%
40.1178 +%
40.1179 +\isadelimtt
40.1180 +%
40.1181 +\endisadelimtt
40.1182 +%
40.1183 +\begin{isamarkuptext}%
40.1184 +The \isa{{\isasymCODETYPE}} commad takes a type constructor
40.1185 + as arguments together with a list of custom serializations.
40.1186 + Each custom serialization starts with a target language
40.1187 + identifier followed by an expression, which during
40.1188 + code serialization is inserted whenever the type constructor
40.1189 + would occur. For constants, \isa{{\isasymCODECONST}} implements
40.1190 + the corresponding mechanism. Each ``\verb|_|'' in
40.1191 + a serialization expression is treated as a placeholder
40.1192 + for the type constructor's (the constant's) arguments.%
40.1193 +\end{isamarkuptext}%
40.1194 +\isamarkuptrue%
40.1195 +\isacommand{export{\isacharunderscore}code}\isamarkupfalse%
40.1196 +\ in{\isacharunderscore}interval\ \ \isakeyword{in}\ SML\ \isakeyword{file}\ {\isachardoublequoteopen}examples{\isacharslash}bool{\isacharunderscore}mlbool{\isachardot}ML{\isachardoublequoteclose}%
40.1197 +\begin{isamarkuptext}%
40.1198 +\lstsml{Thy/examples/bool_mlbool.ML}
40.1199 +
40.1200 + \noindent This still is not perfect: the parentheses
40.1201 + around the \qt{andalso} expression are superfluous.
40.1202 + Though the serializer
40.1203 + by no means attempts to imitate the rich Isabelle syntax
40.1204 + framework, it provides some common idioms, notably
40.1205 + associative infixes with precedences which may be used here:%
40.1206 +\end{isamarkuptext}%
40.1207 +\isamarkuptrue%
40.1208 +%
40.1209 +\isadelimtt
40.1210 +%
40.1211 +\endisadelimtt
40.1212 +%
40.1213 +\isatagtt
40.1214 +\isacommand{code{\isacharunderscore}const}\isamarkupfalse%
40.1215 +\ {\isachardoublequoteopen}op\ {\isasymand}{\isachardoublequoteclose}\isanewline
40.1216 +\ \ {\isacharparenleft}SML\ \isakeyword{infixl}\ {\isadigit{1}}\ {\isachardoublequoteopen}andalso{\isachardoublequoteclose}{\isacharparenright}%
40.1217 +\endisatagtt
40.1218 +{\isafoldtt}%
40.1219 +%
40.1220 +\isadelimtt
40.1221 +%
40.1222 +\endisadelimtt
40.1223 +\isanewline
40.1224 +\isanewline
40.1225 +\isacommand{export{\isacharunderscore}code}\isamarkupfalse%
40.1226 +\ in{\isacharunderscore}interval\ \ \isakeyword{in}\ SML\ \isakeyword{file}\ {\isachardoublequoteopen}examples{\isacharslash}bool{\isacharunderscore}infix{\isachardot}ML{\isachardoublequoteclose}%
40.1227 +\begin{isamarkuptext}%
40.1228 +\lstsml{Thy/examples/bool_infix.ML}
40.1229 +
40.1230 + \medskip
40.1231 +
40.1232 + Next, we try to map HOL pairs to SML pairs, using the
40.1233 + infix ``\verb|*|'' type constructor and parentheses:%
40.1234 +\end{isamarkuptext}%
40.1235 +\isamarkuptrue%
40.1236 +%
40.1237 +\isadelimtt
40.1238 +%
40.1239 +\endisadelimtt
40.1240 +%
40.1241 +\isatagtt
40.1242 +\isacommand{code{\isacharunderscore}type}\isamarkupfalse%
40.1243 +\ {\isacharasterisk}\isanewline
40.1244 +\ \ {\isacharparenleft}SML\ \isakeyword{infix}\ {\isadigit{2}}\ {\isachardoublequoteopen}{\isacharasterisk}{\isachardoublequoteclose}{\isacharparenright}\isanewline
40.1245 +\isacommand{code{\isacharunderscore}const}\isamarkupfalse%
40.1246 +\ Pair\isanewline
40.1247 +\ \ {\isacharparenleft}SML\ {\isachardoublequoteopen}{\isacharbang}{\isacharparenleft}{\isacharparenleft}{\isacharunderscore}{\isacharparenright}{\isacharcomma}{\isacharslash}\ {\isacharparenleft}{\isacharunderscore}{\isacharparenright}{\isacharparenright}{\isachardoublequoteclose}{\isacharparenright}%
40.1248 +\endisatagtt
40.1249 +{\isafoldtt}%
40.1250 +%
40.1251 +\isadelimtt
40.1252 +%
40.1253 +\endisadelimtt
40.1254 +%
40.1255 +\begin{isamarkuptext}%
40.1256 +The initial bang ``\verb|!|'' tells the serializer to never put
40.1257 + parentheses around the whole expression (they are already present),
40.1258 + while the parentheses around argument place holders
40.1259 + tell not to put parentheses around the arguments.
40.1260 + The slash ``\verb|/|'' (followed by arbitrary white space)
40.1261 + inserts a space which may be used as a break if necessary
40.1262 + during pretty printing.
40.1263 +
40.1264 + These examples give a glimpse what mechanisms
40.1265 + custom serializations provide; however their usage
40.1266 + requires careful thinking in order not to introduce
40.1267 + inconsistencies -- or, in other words:
40.1268 + custom serializations are completely axiomatic.
40.1269 +
40.1270 + A further noteworthy details is that any special
40.1271 + character in a custom serialization may be quoted
40.1272 + using ``\verb|'|''; thus, in
40.1273 + ``\verb|fn '_ => _|'' the first
40.1274 + ``\verb|_|'' is a proper underscore while the
40.1275 + second ``\verb|_|'' is a placeholder.
40.1276 +
40.1277 + The HOL theories provide further
40.1278 + examples for custom serializations.%
40.1279 +\end{isamarkuptext}%
40.1280 +\isamarkuptrue%
40.1281 +%
40.1282 +\isamarkupsubsubsection{Haskell serialization%
40.1283 +}
40.1284 +\isamarkuptrue%
40.1285 +%
40.1286 +\begin{isamarkuptext}%
40.1287 +For convenience, the default
40.1288 + HOL setup for Haskell maps the \isa{eq} class to
40.1289 + its counterpart in Haskell, giving custom serializations
40.1290 + for the class (\isa{{\isasymCODECLASS}}) and its operation:%
40.1291 +\end{isamarkuptext}%
40.1292 +\isamarkuptrue%
40.1293 +%
40.1294 +\isadelimtt
40.1295 +%
40.1296 +\endisadelimtt
40.1297 +%
40.1298 +\isatagtt
40.1299 +\isacommand{code{\isacharunderscore}class}\isamarkupfalse%
40.1300 +\ eq\isanewline
40.1301 +\ \ {\isacharparenleft}Haskell\ {\isachardoublequoteopen}Eq{\isachardoublequoteclose}\ \isakeyword{where}\ {\isachardoublequoteopen}op\ {\isacharequal}{\isachardoublequoteclose}\ {\isasymequiv}\ {\isachardoublequoteopen}{\isacharparenleft}{\isacharequal}{\isacharequal}{\isacharparenright}{\isachardoublequoteclose}{\isacharparenright}\isanewline
40.1302 +\isanewline
40.1303 +\isacommand{code{\isacharunderscore}const}\isamarkupfalse%
40.1304 +\ {\isachardoublequoteopen}op\ {\isacharequal}{\isachardoublequoteclose}\isanewline
40.1305 +\ \ {\isacharparenleft}Haskell\ \isakeyword{infixl}\ {\isadigit{4}}\ {\isachardoublequoteopen}{\isacharequal}{\isacharequal}{\isachardoublequoteclose}{\isacharparenright}%
40.1306 +\endisatagtt
40.1307 +{\isafoldtt}%
40.1308 +%
40.1309 +\isadelimtt
40.1310 +%
40.1311 +\endisadelimtt
40.1312 +%
40.1313 +\begin{isamarkuptext}%
40.1314 +A problem now occurs whenever a type which
40.1315 + is an instance of \isa{eq} in HOL is mapped
40.1316 + on a Haskell-builtin type which is also an instance
40.1317 + of Haskell \isa{Eq}:%
40.1318 +\end{isamarkuptext}%
40.1319 +\isamarkuptrue%
40.1320 +\isacommand{typedecl}\isamarkupfalse%
40.1321 +\ bar\isanewline
40.1322 +\isanewline
40.1323 +\isacommand{instantiation}\isamarkupfalse%
40.1324 +\ bar\ {\isacharcolon}{\isacharcolon}\ eq\isanewline
40.1325 +\isakeyword{begin}\isanewline
40.1326 +\isanewline
40.1327 +\isacommand{definition}\isamarkupfalse%
40.1328 +\ {\isachardoublequoteopen}eq{\isacharunderscore}class{\isachardot}eq\ {\isacharparenleft}x{\isasymColon}bar{\isacharparenright}\ y\ {\isasymlongleftrightarrow}\ x\ {\isacharequal}\ y{\isachardoublequoteclose}\isanewline
40.1329 +\isanewline
40.1330 +\isacommand{instance}\isamarkupfalse%
40.1331 +%
40.1332 +\isadelimproof
40.1333 +\ %
40.1334 +\endisadelimproof
40.1335 +%
40.1336 +\isatagproof
40.1337 +\isacommand{by}\isamarkupfalse%
40.1338 +\ default\ {\isacharparenleft}simp\ add{\isacharcolon}\ eq{\isacharunderscore}bar{\isacharunderscore}def{\isacharparenright}%
40.1339 +\endisatagproof
40.1340 +{\isafoldproof}%
40.1341 +%
40.1342 +\isadelimproof
40.1343 +%
40.1344 +\endisadelimproof
40.1345 +\isanewline
40.1346 +\isanewline
40.1347 +\isacommand{end}\isamarkupfalse%
40.1348 +\isanewline
40.1349 +%
40.1350 +\isadelimtt
40.1351 +\isanewline
40.1352 +%
40.1353 +\endisadelimtt
40.1354 +%
40.1355 +\isatagtt
40.1356 +\isacommand{code{\isacharunderscore}type}\isamarkupfalse%
40.1357 +\ bar\isanewline
40.1358 +\ \ {\isacharparenleft}Haskell\ {\isachardoublequoteopen}Integer{\isachardoublequoteclose}{\isacharparenright}%
40.1359 +\endisatagtt
40.1360 +{\isafoldtt}%
40.1361 +%
40.1362 +\isadelimtt
40.1363 +%
40.1364 +\endisadelimtt
40.1365 +%
40.1366 +\begin{isamarkuptext}%
40.1367 +The code generator would produce
40.1368 + an additional instance, which of course is rejected.
40.1369 + To suppress this additional instance, use
40.1370 + \isa{{\isasymCODEINSTANCE}}:%
40.1371 +\end{isamarkuptext}%
40.1372 +\isamarkuptrue%
40.1373 +%
40.1374 +\isadelimtt
40.1375 +%
40.1376 +\endisadelimtt
40.1377 +%
40.1378 +\isatagtt
40.1379 +\isacommand{code{\isacharunderscore}instance}\isamarkupfalse%
40.1380 +\ bar\ {\isacharcolon}{\isacharcolon}\ eq\isanewline
40.1381 +\ \ {\isacharparenleft}Haskell\ {\isacharminus}{\isacharparenright}%
40.1382 +\endisatagtt
40.1383 +{\isafoldtt}%
40.1384 +%
40.1385 +\isadelimtt
40.1386 +%
40.1387 +\endisadelimtt
40.1388 +%
40.1389 +\isamarkupsubsubsection{Pretty printing%
40.1390 +}
40.1391 +\isamarkuptrue%
40.1392 +%
40.1393 +\begin{isamarkuptext}%
40.1394 +The serializer provides ML interfaces to set up
40.1395 + pretty serializations for expressions like lists, numerals
40.1396 + and characters; these are
40.1397 + monolithic stubs and should only be used with the
40.1398 + theories introduced in \secref{sec:library}.%
40.1399 +\end{isamarkuptext}%
40.1400 +\isamarkuptrue%
40.1401 +%
40.1402 +\isamarkupsubsection{Cyclic module dependencies%
40.1403 +}
40.1404 +\isamarkuptrue%
40.1405 +%
40.1406 +\begin{isamarkuptext}%
40.1407 +Sometimes the awkward situation occurs that dependencies
40.1408 + between definitions introduce cyclic dependencies
40.1409 + between modules, which in the Haskell world leaves
40.1410 + you to the mercy of the Haskell implementation you are using,
40.1411 + while for SML code generation is not possible.
40.1412 +
40.1413 + A solution is to declare module names explicitly.
40.1414 + Let use assume the three cyclically dependent
40.1415 + modules are named \emph{A}, \emph{B} and \emph{C}.
40.1416 + Then, by stating%
40.1417 +\end{isamarkuptext}%
40.1418 +\isamarkuptrue%
40.1419 +\isacommand{code{\isacharunderscore}modulename}\isamarkupfalse%
40.1420 +\ SML\isanewline
40.1421 +\ \ A\ ABC\isanewline
40.1422 +\ \ B\ ABC\isanewline
40.1423 +\ \ C\ ABC%
40.1424 +\begin{isamarkuptext}%
40.1425 +we explicitly map all those modules on \emph{ABC},
40.1426 + resulting in an ad-hoc merge of this three modules
40.1427 + at serialization time.%
40.1428 +\end{isamarkuptext}%
40.1429 +\isamarkuptrue%
40.1430 +%
40.1431 +\isamarkupsubsection{Incremental code generation%
40.1432 +}
40.1433 +\isamarkuptrue%
40.1434 +%
40.1435 +\begin{isamarkuptext}%
40.1436 +Code generation is \emph{incremental}: theorems
40.1437 + and abstract intermediate code are cached and extended on demand.
40.1438 + The cache may be partially or fully dropped if the underlying
40.1439 + executable content of the theory changes.
40.1440 + Implementation of caching is supposed to transparently
40.1441 + hid away the details from the user. Anyway, caching
40.1442 + reaches the surface by using a slightly more general form
40.1443 + of the \isa{{\isasymCODETHMS}}, \isa{{\isasymCODEDEPS}}
40.1444 + and \isa{{\isasymEXPORTCODE}} commands: the list of constants
40.1445 + may be omitted. Then, all constants with code theorems
40.1446 + in the current cache are referred to.%
40.1447 +\end{isamarkuptext}%
40.1448 +\isamarkuptrue%
40.1449 +%
40.1450 +\isamarkupsection{ML interfaces \label{sec:ml}%
40.1451 +}
40.1452 +\isamarkuptrue%
40.1453 +%
40.1454 +\begin{isamarkuptext}%
40.1455 +Since the code generator framework not only aims to provide
40.1456 + a nice Isar interface but also to form a base for
40.1457 + code-generation-based applications, here a short
40.1458 + description of the most important ML interfaces.%
40.1459 +\end{isamarkuptext}%
40.1460 +\isamarkuptrue%
40.1461 +%
40.1462 +\isamarkupsubsection{Executable theory content: \isa{Code}%
40.1463 +}
40.1464 +\isamarkuptrue%
40.1465 +%
40.1466 +\begin{isamarkuptext}%
40.1467 +This Pure module implements the core notions of
40.1468 + executable content of a theory.%
40.1469 +\end{isamarkuptext}%
40.1470 +\isamarkuptrue%
40.1471 +%
40.1472 +\isamarkupsubsubsection{Managing executable content%
40.1473 +}
40.1474 +\isamarkuptrue%
40.1475 +%
40.1476 +\isadelimmlref
40.1477 +%
40.1478 +\endisadelimmlref
40.1479 +%
40.1480 +\isatagmlref
40.1481 +%
40.1482 +\begin{isamarkuptext}%
40.1483 +\begin{mldecls}
40.1484 + \indexml{Code.add\_func}\verb|Code.add_func: thm -> theory -> theory| \\
40.1485 + \indexml{Code.del\_func}\verb|Code.del_func: thm -> theory -> theory| \\
40.1486 + \indexml{Code.add\_funcl}\verb|Code.add_funcl: string * thm list Susp.T -> theory -> theory| \\
40.1487 + \indexml{Code.map\_pre}\verb|Code.map_pre: (MetaSimplifier.simpset -> MetaSimplifier.simpset) -> theory -> theory| \\
40.1488 + \indexml{Code.map\_post}\verb|Code.map_post: (MetaSimplifier.simpset -> MetaSimplifier.simpset) -> theory -> theory| \\
40.1489 + \indexml{Code.add\_functrans}\verb|Code.add_functrans: string * (theory -> thm list -> thm list option)|\isasep\isanewline%
40.1490 +\verb| -> theory -> theory| \\
40.1491 + \indexml{Code.del\_functrans}\verb|Code.del_functrans: string -> theory -> theory| \\
40.1492 + \indexml{Code.add\_datatype}\verb|Code.add_datatype: (string * typ) list -> theory -> theory| \\
40.1493 + \indexml{Code.get\_datatype}\verb|Code.get_datatype: theory -> string|\isasep\isanewline%
40.1494 +\verb| -> (string * sort) list * (string * typ list) list| \\
40.1495 + \indexml{Code.get\_datatype\_of\_constr}\verb|Code.get_datatype_of_constr: theory -> string -> string option|
40.1496 + \end{mldecls}
40.1497 +
40.1498 + \begin{description}
40.1499 +
40.1500 + \item \verb|Code.add_func|~\isa{thm}~\isa{thy} adds function
40.1501 + theorem \isa{thm} to executable content.
40.1502 +
40.1503 + \item \verb|Code.del_func|~\isa{thm}~\isa{thy} removes function
40.1504 + theorem \isa{thm} from executable content, if present.
40.1505 +
40.1506 + \item \verb|Code.add_funcl|~\isa{{\isacharparenleft}const{\isacharcomma}\ lthms{\isacharparenright}}~\isa{thy} adds
40.1507 + suspended defining equations \isa{lthms} for constant
40.1508 + \isa{const} to executable content.
40.1509 +
40.1510 + \item \verb|Code.map_pre|~\isa{f}~\isa{thy} changes
40.1511 + the preprocessor simpset.
40.1512 +
40.1513 + \item \verb|Code.add_functrans|~\isa{{\isacharparenleft}name{\isacharcomma}\ f{\isacharparenright}}~\isa{thy} adds
40.1514 + function transformer \isa{f} (named \isa{name}) to executable content;
40.1515 + \isa{f} is a transformer of the defining equations belonging
40.1516 + to a certain function definition, depending on the
40.1517 + current theory context. Returning \isa{NONE} indicates that no
40.1518 + transformation took place; otherwise, the whole process will be iterated
40.1519 + with the new defining equations.
40.1520 +
40.1521 + \item \verb|Code.del_functrans|~\isa{name}~\isa{thy} removes
40.1522 + function transformer named \isa{name} from executable content.
40.1523 +
40.1524 + \item \verb|Code.add_datatype|~\isa{cs}~\isa{thy} adds
40.1525 + a datatype to executable content, with generation
40.1526 + set \isa{cs}.
40.1527 +
40.1528 + \item \verb|Code.get_datatype_of_constr|~\isa{thy}~\isa{const}
40.1529 + returns type constructor corresponding to
40.1530 + constructor \isa{const}; returns \isa{NONE}
40.1531 + if \isa{const} is no constructor.
40.1532 +
40.1533 + \end{description}%
40.1534 +\end{isamarkuptext}%
40.1535 +\isamarkuptrue%
40.1536 +%
40.1537 +\endisatagmlref
40.1538 +{\isafoldmlref}%
40.1539 +%
40.1540 +\isadelimmlref
40.1541 +%
40.1542 +\endisadelimmlref
40.1543 +%
40.1544 +\isamarkupsubsection{Auxiliary%
40.1545 +}
40.1546 +\isamarkuptrue%
40.1547 +%
40.1548 +\isadelimmlref
40.1549 +%
40.1550 +\endisadelimmlref
40.1551 +%
40.1552 +\isatagmlref
40.1553 +%
40.1554 +\begin{isamarkuptext}%
40.1555 +\begin{mldecls}
40.1556 + \indexml{Code\_Unit.read\_const}\verb|Code_Unit.read_const: theory -> string -> string| \\
40.1557 + \indexml{Code\_Unit.head\_func}\verb|Code_Unit.head_func: thm -> string * ((string * sort) list * typ)| \\
40.1558 + \indexml{Code\_Unit.rewrite\_func}\verb|Code_Unit.rewrite_func: MetaSimplifier.simpset -> thm -> thm| \\
40.1559 + \end{mldecls}
40.1560 +
40.1561 + \begin{description}
40.1562 +
40.1563 + \item \verb|Code_Unit.read_const|~\isa{thy}~\isa{s}
40.1564 + reads a constant as a concrete term expression \isa{s}.
40.1565 +
40.1566 + \item \verb|Code_Unit.head_func|~\isa{thm}
40.1567 + extracts the constant and its type from a defining equation \isa{thm}.
40.1568 +
40.1569 + \item \verb|Code_Unit.rewrite_func|~\isa{ss}~\isa{thm}
40.1570 + rewrites a defining equation \isa{thm} with a simpset \isa{ss};
40.1571 + only arguments and right hand side are rewritten,
40.1572 + not the head of the defining equation.
40.1573 +
40.1574 + \end{description}%
40.1575 +\end{isamarkuptext}%
40.1576 +\isamarkuptrue%
40.1577 +%
40.1578 +\endisatagmlref
40.1579 +{\isafoldmlref}%
40.1580 +%
40.1581 +\isadelimmlref
40.1582 +%
40.1583 +\endisadelimmlref
40.1584 +%
40.1585 +\isamarkupsubsection{Implementing code generator applications%
40.1586 +}
40.1587 +\isamarkuptrue%
40.1588 +%
40.1589 +\begin{isamarkuptext}%
40.1590 +Implementing code generator applications on top
40.1591 + of the framework set out so far usually not only
40.1592 + involves using those primitive interfaces
40.1593 + but also storing code-dependent data and various
40.1594 + other things.
40.1595 +
40.1596 + \begin{warn}
40.1597 + Some interfaces discussed here have not reached
40.1598 + a final state yet.
40.1599 + Changes likely to occur in future.
40.1600 + \end{warn}%
40.1601 +\end{isamarkuptext}%
40.1602 +\isamarkuptrue%
40.1603 +%
40.1604 +\isamarkupsubsubsection{Data depending on the theory's executable content%
40.1605 +}
40.1606 +\isamarkuptrue%
40.1607 +%
40.1608 +\begin{isamarkuptext}%
40.1609 +Due to incrementality of code generation, changes in the
40.1610 + theory's executable content have to be propagated in a
40.1611 + certain fashion. Additionally, such changes may occur
40.1612 + not only during theory extension but also during theory
40.1613 + merge, which is a little bit nasty from an implementation
40.1614 + point of view. The framework provides a solution
40.1615 + to this technical challenge by providing a functorial
40.1616 + data slot \verb|CodeDataFun|; on instantiation
40.1617 + of this functor, the following types and operations
40.1618 + are required:
40.1619 +
40.1620 + \medskip
40.1621 + \begin{tabular}{l}
40.1622 + \isa{type\ T} \\
40.1623 + \isa{val\ empty{\isacharcolon}\ T} \\
40.1624 + \isa{val\ merge{\isacharcolon}\ Pretty{\isachardot}pp\ {\isasymrightarrow}\ T\ {\isacharasterisk}\ T\ {\isasymrightarrow}\ T} \\
40.1625 + \isa{val\ purge{\isacharcolon}\ theory\ option\ {\isasymrightarrow}\ CodeUnit{\isachardot}const\ list\ option\ {\isasymrightarrow}\ T\ {\isasymrightarrow}\ T}
40.1626 + \end{tabular}
40.1627 +
40.1628 + \begin{description}
40.1629 +
40.1630 + \item \isa{T} the type of data to store.
40.1631 +
40.1632 + \item \isa{empty} initial (empty) data.
40.1633 +
40.1634 + \item \isa{merge} merging two data slots.
40.1635 +
40.1636 + \item \isa{purge}~\isa{thy}~\isa{consts} propagates changes in executable content;
40.1637 + if possible, the current theory context is handed over
40.1638 + as argument \isa{thy} (if there is no current theory context (e.g.~during
40.1639 + theory merge, \verb|NONE|); \isa{consts} indicates the kind
40.1640 + of change: \verb|NONE| stands for a fundamental change
40.1641 + which invalidates any existing code, \isa{SOME\ consts}
40.1642 + hints that executable content for constants \isa{consts}
40.1643 + has changed.
40.1644 +
40.1645 + \end{description}
40.1646 +
40.1647 + An instance of \verb|CodeDataFun| provides the following
40.1648 + interface:
40.1649 +
40.1650 + \medskip
40.1651 + \begin{tabular}{l}
40.1652 + \isa{get{\isacharcolon}\ theory\ {\isasymrightarrow}\ T} \\
40.1653 + \isa{change{\isacharcolon}\ theory\ {\isasymrightarrow}\ {\isacharparenleft}T\ {\isasymrightarrow}\ T{\isacharparenright}\ {\isasymrightarrow}\ T} \\
40.1654 + \isa{change{\isacharunderscore}yield{\isacharcolon}\ theory\ {\isasymrightarrow}\ {\isacharparenleft}T\ {\isasymrightarrow}\ {\isacharprime}a\ {\isacharasterisk}\ T{\isacharparenright}\ {\isasymrightarrow}\ {\isacharprime}a\ {\isacharasterisk}\ T}
40.1655 + \end{tabular}
40.1656 +
40.1657 + \begin{description}
40.1658 +
40.1659 + \item \isa{get} retrieval of the current data.
40.1660 +
40.1661 + \item \isa{change} update of current data (cached!)
40.1662 + by giving a continuation.
40.1663 +
40.1664 + \item \isa{change{\isacharunderscore}yield} update with side result.
40.1665 +
40.1666 + \end{description}%
40.1667 +\end{isamarkuptext}%
40.1668 +\isamarkuptrue%
40.1669 +%
40.1670 +\begin{isamarkuptext}%
40.1671 +\emph{Happy proving, happy hacking!}%
40.1672 +\end{isamarkuptext}%
40.1673 +\isamarkuptrue%
40.1674 +%
40.1675 +\isadelimtheory
40.1676 +%
40.1677 +\endisadelimtheory
40.1678 +%
40.1679 +\isatagtheory
40.1680 +\isacommand{end}\isamarkupfalse%
40.1681 +%
40.1682 +\endisatagtheory
40.1683 +{\isafoldtheory}%
40.1684 +%
40.1685 +\isadelimtheory
40.1686 +%
40.1687 +\endisadelimtheory
40.1688 +\isanewline
40.1689 +\end{isabellebody}%
40.1690 +%%% Local Variables:
40.1691 +%%% mode: latex
40.1692 +%%% TeX-master: "root"
40.1693 +%%% End:
41.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
41.2 +++ b/doc-src/Codegen/Thy/document/Further.tex Wed Mar 04 11:05:29 2009 +0100
41.3 @@ -0,0 +1,246 @@
41.4 +%
41.5 +\begin{isabellebody}%
41.6 +\def\isabellecontext{Further}%
41.7 +%
41.8 +\isadelimtheory
41.9 +%
41.10 +\endisadelimtheory
41.11 +%
41.12 +\isatagtheory
41.13 +\isacommand{theory}\isamarkupfalse%
41.14 +\ Further\isanewline
41.15 +\isakeyword{imports}\ Setup\isanewline
41.16 +\isakeyword{begin}%
41.17 +\endisatagtheory
41.18 +{\isafoldtheory}%
41.19 +%
41.20 +\isadelimtheory
41.21 +%
41.22 +\endisadelimtheory
41.23 +%
41.24 +\isamarkupsection{Further issues \label{sec:further}%
41.25 +}
41.26 +\isamarkuptrue%
41.27 +%
41.28 +\isamarkupsubsection{Further reading%
41.29 +}
41.30 +\isamarkuptrue%
41.31 +%
41.32 +\begin{isamarkuptext}%
41.33 +Do dive deeper into the issue of code generation, you should visit
41.34 + the Isabelle/Isar Reference Manual \cite{isabelle-isar-ref} which
41.35 + contains exhaustive syntax diagrams.%
41.36 +\end{isamarkuptext}%
41.37 +\isamarkuptrue%
41.38 +%
41.39 +\isamarkupsubsection{Modules%
41.40 +}
41.41 +\isamarkuptrue%
41.42 +%
41.43 +\begin{isamarkuptext}%
41.44 +When invoking the \hyperlink{command.export-code}{\mbox{\isa{\isacommand{export{\isacharunderscore}code}}}} command it is possible to leave
41.45 + out the \hyperlink{keyword.module-name}{\mbox{\isa{\isakeyword{module{\isacharunderscore}name}}}} part; then code is distributed over
41.46 + different modules, where the module name space roughly is induced
41.47 + by the \isa{Isabelle} theory name space.
41.48 +
41.49 + Then sometimes the awkward situation occurs that dependencies between
41.50 + definitions introduce cyclic dependencies between modules, which in the
41.51 + \isa{Haskell} world leaves you to the mercy of the \isa{Haskell} implementation
41.52 + you are using, while for \isa{SML}/\isa{OCaml} code generation is not possible.
41.53 +
41.54 + A solution is to declare module names explicitly.
41.55 + Let use assume the three cyclically dependent
41.56 + modules are named \emph{A}, \emph{B} and \emph{C}.
41.57 + Then, by stating%
41.58 +\end{isamarkuptext}%
41.59 +\isamarkuptrue%
41.60 +%
41.61 +\isadelimquote
41.62 +%
41.63 +\endisadelimquote
41.64 +%
41.65 +\isatagquote
41.66 +\isacommand{code{\isacharunderscore}modulename}\isamarkupfalse%
41.67 +\ SML\isanewline
41.68 +\ \ A\ ABC\isanewline
41.69 +\ \ B\ ABC\isanewline
41.70 +\ \ C\ ABC%
41.71 +\endisatagquote
41.72 +{\isafoldquote}%
41.73 +%
41.74 +\isadelimquote
41.75 +%
41.76 +\endisadelimquote
41.77 +%
41.78 +\begin{isamarkuptext}%
41.79 +we explicitly map all those modules on \emph{ABC},
41.80 + resulting in an ad-hoc merge of this three modules
41.81 + at serialisation time.%
41.82 +\end{isamarkuptext}%
41.83 +\isamarkuptrue%
41.84 +%
41.85 +\isamarkupsubsection{Evaluation oracle%
41.86 +}
41.87 +\isamarkuptrue%
41.88 +%
41.89 +\begin{isamarkuptext}%
41.90 +Code generation may also be used to \emph{evaluate} expressions
41.91 + (using \isa{SML} as target language of course).
41.92 + For instance, the \hyperlink{command.value}{\mbox{\isa{\isacommand{value}}}} allows to reduce an expression to a
41.93 + normal form with respect to the underlying code equations:%
41.94 +\end{isamarkuptext}%
41.95 +\isamarkuptrue%
41.96 +%
41.97 +\isadelimquote
41.98 +%
41.99 +\endisadelimquote
41.100 +%
41.101 +\isatagquote
41.102 +\isacommand{value}\isamarkupfalse%
41.103 +\ {\isachardoublequoteopen}{\isadigit{4}}{\isadigit{2}}\ {\isacharslash}\ {\isacharparenleft}{\isadigit{1}}{\isadigit{2}}\ {\isacharcolon}{\isacharcolon}\ rat{\isacharparenright}{\isachardoublequoteclose}%
41.104 +\endisatagquote
41.105 +{\isafoldquote}%
41.106 +%
41.107 +\isadelimquote
41.108 +%
41.109 +\endisadelimquote
41.110 +%
41.111 +\begin{isamarkuptext}%
41.112 +\noindent will display \isa{{\isadigit{7}}\ {\isacharslash}\ {\isadigit{2}}}.
41.113 +
41.114 + The \hyperlink{method.eval}{\mbox{\isa{eval}}} method tries to reduce a goal by code generation to \isa{True}
41.115 + and solves it in that case, but fails otherwise:%
41.116 +\end{isamarkuptext}%
41.117 +\isamarkuptrue%
41.118 +%
41.119 +\isadelimquote
41.120 +%
41.121 +\endisadelimquote
41.122 +%
41.123 +\isatagquote
41.124 +\isacommand{lemma}\isamarkupfalse%
41.125 +\ {\isachardoublequoteopen}{\isadigit{4}}{\isadigit{2}}\ {\isacharslash}\ {\isacharparenleft}{\isadigit{1}}{\isadigit{2}}\ {\isacharcolon}{\isacharcolon}\ rat{\isacharparenright}\ {\isacharequal}\ {\isadigit{7}}\ {\isacharslash}\ {\isadigit{2}}{\isachardoublequoteclose}\isanewline
41.126 +\ \ \isacommand{by}\isamarkupfalse%
41.127 +\ eval%
41.128 +\endisatagquote
41.129 +{\isafoldquote}%
41.130 +%
41.131 +\isadelimquote
41.132 +%
41.133 +\endisadelimquote
41.134 +%
41.135 +\begin{isamarkuptext}%
41.136 +\noindent The soundness of the \hyperlink{method.eval}{\mbox{\isa{eval}}} method depends crucially
41.137 + on the correctness of the code generator; this is one of the reasons
41.138 + why you should not use adaption (see \secref{sec:adaption}) frivolously.%
41.139 +\end{isamarkuptext}%
41.140 +\isamarkuptrue%
41.141 +%
41.142 +\isamarkupsubsection{Code antiquotation%
41.143 +}
41.144 +\isamarkuptrue%
41.145 +%
41.146 +\begin{isamarkuptext}%
41.147 +In scenarios involving techniques like reflection it is quite common
41.148 + that code generated from a theory forms the basis for implementing
41.149 + a proof procedure in \isa{SML}. To facilitate interfacing of generated code
41.150 + with system code, the code generator provides a \isa{code} antiquotation:%
41.151 +\end{isamarkuptext}%
41.152 +\isamarkuptrue%
41.153 +%
41.154 +\isadelimquote
41.155 +%
41.156 +\endisadelimquote
41.157 +%
41.158 +\isatagquote
41.159 +\isacommand{datatype}\isamarkupfalse%
41.160 +\ form\ {\isacharequal}\ T\ {\isacharbar}\ F\ {\isacharbar}\ And\ form\ form\ {\isacharbar}\ Or\ form\ form%
41.161 +\endisatagquote
41.162 +{\isafoldquote}%
41.163 +%
41.164 +\isadelimquote
41.165 +%
41.166 +\endisadelimquote
41.167 +\isanewline
41.168 +%
41.169 +\isadelimquotett
41.170 +%
41.171 +\endisadelimquotett
41.172 +%
41.173 +\isatagquotett
41.174 +\isacommand{ML}\isamarkupfalse%
41.175 +\ {\isacharverbatimopen}\isanewline
41.176 +\ \ fun\ eval{\isacharunderscore}form\ %
41.177 +\isaantiq
41.178 +code\ T%
41.179 +\endisaantiq
41.180 +\ {\isacharequal}\ true\isanewline
41.181 +\ \ \ \ {\isacharbar}\ eval{\isacharunderscore}form\ %
41.182 +\isaantiq
41.183 +code\ F%
41.184 +\endisaantiq
41.185 +\ {\isacharequal}\ false\isanewline
41.186 +\ \ \ \ {\isacharbar}\ eval{\isacharunderscore}form\ {\isacharparenleft}%
41.187 +\isaantiq
41.188 +code\ And%
41.189 +\endisaantiq
41.190 +\ {\isacharparenleft}p{\isacharcomma}\ q{\isacharparenright}{\isacharparenright}\ {\isacharequal}\isanewline
41.191 +\ \ \ \ \ \ \ \ eval{\isacharunderscore}form\ p\ andalso\ eval{\isacharunderscore}form\ q\isanewline
41.192 +\ \ \ \ {\isacharbar}\ eval{\isacharunderscore}form\ {\isacharparenleft}%
41.193 +\isaantiq
41.194 +code\ Or%
41.195 +\endisaantiq
41.196 +\ {\isacharparenleft}p{\isacharcomma}\ q{\isacharparenright}{\isacharparenright}\ {\isacharequal}\isanewline
41.197 +\ \ \ \ \ \ \ \ eval{\isacharunderscore}form\ p\ orelse\ eval{\isacharunderscore}form\ q{\isacharsemicolon}\isanewline
41.198 +{\isacharverbatimclose}%
41.199 +\endisatagquotett
41.200 +{\isafoldquotett}%
41.201 +%
41.202 +\isadelimquotett
41.203 +%
41.204 +\endisadelimquotett
41.205 +%
41.206 +\begin{isamarkuptext}%
41.207 +\noindent \isa{code} takes as argument the name of a constant; after the
41.208 + whole \isa{SML} is read, the necessary code is generated transparently
41.209 + and the corresponding constant names are inserted. This technique also
41.210 + allows to use pattern matching on constructors stemming from compiled
41.211 + \isa{datatypes}.
41.212 +
41.213 + For a less simplistic example, theory \hyperlink{theory.Ferrack}{\mbox{\isa{Ferrack}}} is
41.214 + a good reference.%
41.215 +\end{isamarkuptext}%
41.216 +\isamarkuptrue%
41.217 +%
41.218 +\isamarkupsubsection{Imperative data structures%
41.219 +}
41.220 +\isamarkuptrue%
41.221 +%
41.222 +\begin{isamarkuptext}%
41.223 +If you consider imperative data structures as inevitable for a specific
41.224 + application, you should consider
41.225 + \emph{Imperative Functional Programming with Isabelle/HOL}
41.226 + (\cite{bulwahn-et-al:2008:imperative});
41.227 + the framework described there is available in theory \hyperlink{theory.Imperative-HOL}{\mbox{\isa{Imperative{\isacharunderscore}HOL}}}.%
41.228 +\end{isamarkuptext}%
41.229 +\isamarkuptrue%
41.230 +%
41.231 +\isadelimtheory
41.232 +%
41.233 +\endisadelimtheory
41.234 +%
41.235 +\isatagtheory
41.236 +\isacommand{end}\isamarkupfalse%
41.237 +%
41.238 +\endisatagtheory
41.239 +{\isafoldtheory}%
41.240 +%
41.241 +\isadelimtheory
41.242 +%
41.243 +\endisadelimtheory
41.244 +\isanewline
41.245 +\end{isabellebody}%
41.246 +%%% Local Variables:
41.247 +%%% mode: latex
41.248 +%%% TeX-master: "root"
41.249 +%%% End:
42.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
42.2 +++ b/doc-src/Codegen/Thy/document/Introduction.tex Wed Mar 04 11:05:29 2009 +0100
42.3 @@ -0,0 +1,386 @@
42.4 +%
42.5 +\begin{isabellebody}%
42.6 +\def\isabellecontext{Introduction}%
42.7 +%
42.8 +\isadelimtheory
42.9 +%
42.10 +\endisadelimtheory
42.11 +%
42.12 +\isatagtheory
42.13 +\isacommand{theory}\isamarkupfalse%
42.14 +\ Introduction\isanewline
42.15 +\isakeyword{imports}\ Setup\isanewline
42.16 +\isakeyword{begin}%
42.17 +\endisatagtheory
42.18 +{\isafoldtheory}%
42.19 +%
42.20 +\isadelimtheory
42.21 +%
42.22 +\endisadelimtheory
42.23 +%
42.24 +\isamarkupsection{Introduction and Overview%
42.25 +}
42.26 +\isamarkuptrue%
42.27 +%
42.28 +\begin{isamarkuptext}%
42.29 +This tutorial introduces a generic code generator for the
42.30 + \isa{Isabelle} system.
42.31 + Generic in the sense that the
42.32 + \qn{target language} for which code shall ultimately be
42.33 + generated is not fixed but may be an arbitrary state-of-the-art
42.34 + functional programming language (currently, the implementation
42.35 + supports \isa{SML} \cite{SML}, \isa{OCaml} \cite{OCaml} and \isa{Haskell}
42.36 + \cite{haskell-revised-report}).
42.37 +
42.38 + Conceptually the code generator framework is part
42.39 + of Isabelle's \hyperlink{theory.Pure}{\mbox{\isa{Pure}}} meta logic framework; the logic
42.40 + \hyperlink{theory.HOL}{\mbox{\isa{HOL}}} which is an extension of \hyperlink{theory.Pure}{\mbox{\isa{Pure}}}
42.41 + already comes with a reasonable framework setup and thus provides
42.42 + a good working horse for raising code-generation-driven
42.43 + applications. So, we assume some familiarity and experience
42.44 + with the ingredients of the \hyperlink{theory.HOL}{\mbox{\isa{HOL}}} distribution theories.
42.45 + (see also \cite{isa-tutorial}).
42.46 +
42.47 + The code generator aims to be usable with no further ado
42.48 + in most cases while allowing for detailed customisation.
42.49 + This manifests in the structure of this tutorial: after a short
42.50 + conceptual introduction with an example (\secref{sec:intro}),
42.51 + we discuss the generic customisation facilities (\secref{sec:program}).
42.52 + A further section (\secref{sec:adaption}) is dedicated to the matter of
42.53 + \qn{adaption} to specific target language environments. After some
42.54 + further issues (\secref{sec:further}) we conclude with an overview
42.55 + of some ML programming interfaces (\secref{sec:ml}).
42.56 +
42.57 + \begin{warn}
42.58 + Ultimately, the code generator which this tutorial deals with
42.59 + is supposed to replace the existing code generator
42.60 + by Stefan Berghofer \cite{Berghofer-Nipkow:2002}.
42.61 + So, for the moment, there are two distinct code generators
42.62 + in Isabelle. In case of ambiguity, we will refer to the framework
42.63 + described here as \isa{generic\ code\ generator}, to the
42.64 + other as \isa{SML\ code\ generator}.
42.65 + Also note that while the framework itself is
42.66 + object-logic independent, only \hyperlink{theory.HOL}{\mbox{\isa{HOL}}} provides a reasonable
42.67 + framework setup.
42.68 + \end{warn}%
42.69 +\end{isamarkuptext}%
42.70 +\isamarkuptrue%
42.71 +%
42.72 +\isamarkupsubsection{Code generation via shallow embedding \label{sec:intro}%
42.73 +}
42.74 +\isamarkuptrue%
42.75 +%
42.76 +\begin{isamarkuptext}%
42.77 +The key concept for understanding \isa{Isabelle}'s code generation is
42.78 + \emph{shallow embedding}, i.e.~logical entities like constants, types and
42.79 + classes are identified with corresponding concepts in the target language.
42.80 +
42.81 + Inside \hyperlink{theory.HOL}{\mbox{\isa{HOL}}}, the \hyperlink{command.datatype}{\mbox{\isa{\isacommand{datatype}}}} and
42.82 + \hyperlink{command.definition}{\mbox{\isa{\isacommand{definition}}}}/\hyperlink{command.primrec}{\mbox{\isa{\isacommand{primrec}}}}/\hyperlink{command.fun}{\mbox{\isa{\isacommand{fun}}}} declarations form
42.83 + the core of a functional programming language. The default code generator setup
42.84 + allows to turn those into functional programs immediately.
42.85 + This means that \qt{naive} code generation can proceed without further ado.
42.86 + For example, here a simple \qt{implementation} of amortised queues:%
42.87 +\end{isamarkuptext}%
42.88 +\isamarkuptrue%
42.89 +%
42.90 +\isadelimquote
42.91 +%
42.92 +\endisadelimquote
42.93 +%
42.94 +\isatagquote
42.95 +\isacommand{datatype}\isamarkupfalse%
42.96 +\ {\isacharprime}a\ queue\ {\isacharequal}\ AQueue\ {\isachardoublequoteopen}{\isacharprime}a\ list{\isachardoublequoteclose}\ {\isachardoublequoteopen}{\isacharprime}a\ list{\isachardoublequoteclose}\isanewline
42.97 +\isanewline
42.98 +\isacommand{definition}\isamarkupfalse%
42.99 +\ empty\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharprime}a\ queue{\isachardoublequoteclose}\ \isakeyword{where}\isanewline
42.100 +\ \ {\isachardoublequoteopen}empty\ {\isacharequal}\ AQueue\ {\isacharbrackleft}{\isacharbrackright}\ {\isacharbrackleft}{\isacharbrackright}{\isachardoublequoteclose}\isanewline
42.101 +\isanewline
42.102 +\isacommand{primrec}\isamarkupfalse%
42.103 +\ enqueue\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharprime}a\ {\isasymRightarrow}\ {\isacharprime}a\ queue\ {\isasymRightarrow}\ {\isacharprime}a\ queue{\isachardoublequoteclose}\ \isakeyword{where}\isanewline
42.104 +\ \ {\isachardoublequoteopen}enqueue\ x\ {\isacharparenleft}AQueue\ xs\ ys{\isacharparenright}\ {\isacharequal}\ AQueue\ {\isacharparenleft}x\ {\isacharhash}\ xs{\isacharparenright}\ ys{\isachardoublequoteclose}\isanewline
42.105 +\isanewline
42.106 +\isacommand{fun}\isamarkupfalse%
42.107 +\ dequeue\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharprime}a\ queue\ {\isasymRightarrow}\ {\isacharprime}a\ option\ {\isasymtimes}\ {\isacharprime}a\ queue{\isachardoublequoteclose}\ \isakeyword{where}\isanewline
42.108 +\ \ \ \ {\isachardoublequoteopen}dequeue\ {\isacharparenleft}AQueue\ {\isacharbrackleft}{\isacharbrackright}\ {\isacharbrackleft}{\isacharbrackright}{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}None{\isacharcomma}\ AQueue\ {\isacharbrackleft}{\isacharbrackright}\ {\isacharbrackleft}{\isacharbrackright}{\isacharparenright}{\isachardoublequoteclose}\isanewline
42.109 +\ \ {\isacharbar}\ {\isachardoublequoteopen}dequeue\ {\isacharparenleft}AQueue\ xs\ {\isacharparenleft}y\ {\isacharhash}\ ys{\isacharparenright}{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}Some\ y{\isacharcomma}\ AQueue\ xs\ ys{\isacharparenright}{\isachardoublequoteclose}\isanewline
42.110 +\ \ {\isacharbar}\ {\isachardoublequoteopen}dequeue\ {\isacharparenleft}AQueue\ xs\ {\isacharbrackleft}{\isacharbrackright}{\isacharparenright}\ {\isacharequal}\isanewline
42.111 +\ \ \ \ \ \ {\isacharparenleft}case\ rev\ xs\ of\ y\ {\isacharhash}\ ys\ {\isasymRightarrow}\ {\isacharparenleft}Some\ y{\isacharcomma}\ AQueue\ {\isacharbrackleft}{\isacharbrackright}\ ys{\isacharparenright}{\isacharparenright}{\isachardoublequoteclose}%
42.112 +\endisatagquote
42.113 +{\isafoldquote}%
42.114 +%
42.115 +\isadelimquote
42.116 +%
42.117 +\endisadelimquote
42.118 +%
42.119 +\begin{isamarkuptext}%
42.120 +\noindent Then we can generate code e.g.~for \isa{SML} as follows:%
42.121 +\end{isamarkuptext}%
42.122 +\isamarkuptrue%
42.123 +%
42.124 +\isadelimquote
42.125 +%
42.126 +\endisadelimquote
42.127 +%
42.128 +\isatagquote
42.129 +\isacommand{export{\isacharunderscore}code}\isamarkupfalse%
42.130 +\ empty\ dequeue\ enqueue\ \isakeyword{in}\ SML\isanewline
42.131 +\ \ \isakeyword{module{\isacharunderscore}name}\ Example\ \isakeyword{file}\ {\isachardoublequoteopen}examples{\isacharslash}example{\isachardot}ML{\isachardoublequoteclose}%
42.132 +\endisatagquote
42.133 +{\isafoldquote}%
42.134 +%
42.135 +\isadelimquote
42.136 +%
42.137 +\endisadelimquote
42.138 +%
42.139 +\begin{isamarkuptext}%
42.140 +\noindent resulting in the following code:%
42.141 +\end{isamarkuptext}%
42.142 +\isamarkuptrue%
42.143 +%
42.144 +\isadelimquote
42.145 +%
42.146 +\endisadelimquote
42.147 +%
42.148 +\isatagquote
42.149 +%
42.150 +\begin{isamarkuptext}%
42.151 +\isatypewriter%
42.152 +\noindent%
42.153 +\hspace*{0pt}structure Example = \\
42.154 +\hspace*{0pt}struct\\
42.155 +\hspace*{0pt}\\
42.156 +\hspace*{0pt}fun foldl f a [] = a\\
42.157 +\hspace*{0pt} ~| foldl f a (x ::~xs) = foldl f (f a x) xs;\\
42.158 +\hspace*{0pt}\\
42.159 +\hspace*{0pt}fun rev xs = foldl (fn xsa => fn x => x ::~xsa) [] xs;\\
42.160 +\hspace*{0pt}\\
42.161 +\hspace*{0pt}fun list{\char95}case f1 f2 (a ::~lista) = f2 a lista\\
42.162 +\hspace*{0pt} ~| list{\char95}case f1 f2 [] = f1;\\
42.163 +\hspace*{0pt}\\
42.164 +\hspace*{0pt}datatype 'a queue = AQueue of 'a list * 'a list;\\
42.165 +\hspace*{0pt}\\
42.166 +\hspace*{0pt}val empty :~'a queue = AQueue ([],~[])\\
42.167 +\hspace*{0pt}\\
42.168 +\hspace*{0pt}fun dequeue (AQueue ([],~[])) = (NONE,~AQueue ([],~[]))\\
42.169 +\hspace*{0pt} ~| dequeue (AQueue (xs,~y ::~ys)) = (SOME y,~AQueue (xs,~ys))\\
42.170 +\hspace*{0pt} ~| dequeue (AQueue (v ::~va,~[])) =\\
42.171 +\hspace*{0pt} ~~~let\\
42.172 +\hspace*{0pt} ~~~~~val y ::~ys = rev (v ::~va);\\
42.173 +\hspace*{0pt} ~~~in\\
42.174 +\hspace*{0pt} ~~~~~(SOME y,~AQueue ([],~ys))\\
42.175 +\hspace*{0pt} ~~~end;\\
42.176 +\hspace*{0pt}\\
42.177 +\hspace*{0pt}fun enqueue x (AQueue (xs,~ys)) = AQueue (x ::~xs,~ys);\\
42.178 +\hspace*{0pt}\\
42.179 +\hspace*{0pt}end;~(*struct Example*)%
42.180 +\end{isamarkuptext}%
42.181 +\isamarkuptrue%
42.182 +%
42.183 +\endisatagquote
42.184 +{\isafoldquote}%
42.185 +%
42.186 +\isadelimquote
42.187 +%
42.188 +\endisadelimquote
42.189 +%
42.190 +\begin{isamarkuptext}%
42.191 +\noindent The \hyperlink{command.export-code}{\mbox{\isa{\isacommand{export{\isacharunderscore}code}}}} command takes a space-separated list of
42.192 + constants for which code shall be generated; anything else needed for those
42.193 + is added implicitly. Then follows a target language identifier
42.194 + (\isa{SML}, \isa{OCaml} or \isa{Haskell}) and a freely chosen module name.
42.195 + A file name denotes the destination to store the generated code. Note that
42.196 + the semantics of the destination depends on the target language: for
42.197 + \isa{SML} and \isa{OCaml} it denotes a \emph{file}, for \isa{Haskell}
42.198 + it denotes a \emph{directory} where a file named as the module name
42.199 + (with extension \isa{{\isachardot}hs}) is written:%
42.200 +\end{isamarkuptext}%
42.201 +\isamarkuptrue%
42.202 +%
42.203 +\isadelimquote
42.204 +%
42.205 +\endisadelimquote
42.206 +%
42.207 +\isatagquote
42.208 +\isacommand{export{\isacharunderscore}code}\isamarkupfalse%
42.209 +\ empty\ dequeue\ enqueue\ \isakeyword{in}\ Haskell\isanewline
42.210 +\ \ \isakeyword{module{\isacharunderscore}name}\ Example\ \isakeyword{file}\ {\isachardoublequoteopen}examples{\isacharslash}{\isachardoublequoteclose}%
42.211 +\endisatagquote
42.212 +{\isafoldquote}%
42.213 +%
42.214 +\isadelimquote
42.215 +%
42.216 +\endisadelimquote
42.217 +%
42.218 +\begin{isamarkuptext}%
42.219 +\noindent This is how the corresponding code in \isa{Haskell} looks like:%
42.220 +\end{isamarkuptext}%
42.221 +\isamarkuptrue%
42.222 +%
42.223 +\isadelimquote
42.224 +%
42.225 +\endisadelimquote
42.226 +%
42.227 +\isatagquote
42.228 +%
42.229 +\begin{isamarkuptext}%
42.230 +\isatypewriter%
42.231 +\noindent%
42.232 +\hspace*{0pt}module Example where {\char123}\\
42.233 +\hspace*{0pt}\\
42.234 +\hspace*{0pt}\\
42.235 +\hspace*{0pt}foldla ::~forall a b.~(a -> b -> a) -> a -> [b] -> a;\\
42.236 +\hspace*{0pt}foldla f a [] = a;\\
42.237 +\hspace*{0pt}foldla f a (x :~xs) = foldla f (f a x) xs;\\
42.238 +\hspace*{0pt}\\
42.239 +\hspace*{0pt}rev ::~forall a.~[a] -> [a];\\
42.240 +\hspace*{0pt}rev xs = foldla ({\char92}~xsa x -> x :~xsa) [] xs;\\
42.241 +\hspace*{0pt}\\
42.242 +\hspace*{0pt}list{\char95}case ::~forall t a.~t -> (a -> [a] -> t) -> [a] -> t;\\
42.243 +\hspace*{0pt}list{\char95}case f1 f2 (a :~list) = f2 a list;\\
42.244 +\hspace*{0pt}list{\char95}case f1 f2 [] = f1;\\
42.245 +\hspace*{0pt}\\
42.246 +\hspace*{0pt}data Queue a = AQueue [a] [a];\\
42.247 +\hspace*{0pt}\\
42.248 +\hspace*{0pt}empty ::~forall a.~Queue a;\\
42.249 +\hspace*{0pt}empty = AQueue [] [];\\
42.250 +\hspace*{0pt}\\
42.251 +\hspace*{0pt}dequeue ::~forall a.~Queue a -> (Maybe a,~Queue a);\\
42.252 +\hspace*{0pt}dequeue (AQueue [] []) = (Nothing,~AQueue [] []);\\
42.253 +\hspace*{0pt}dequeue (AQueue xs (y :~ys)) = (Just y,~AQueue xs ys);\\
42.254 +\hspace*{0pt}dequeue (AQueue (v :~va) []) =\\
42.255 +\hspace*{0pt} ~let {\char123}\\
42.256 +\hspace*{0pt} ~~~(y :~ys) = rev (v :~va);\\
42.257 +\hspace*{0pt} ~{\char125}~in (Just y,~AQueue [] ys);\\
42.258 +\hspace*{0pt}\\
42.259 +\hspace*{0pt}enqueue ::~forall a.~a -> Queue a -> Queue a;\\
42.260 +\hspace*{0pt}enqueue x (AQueue xs ys) = AQueue (x :~xs) ys;\\
42.261 +\hspace*{0pt}\\
42.262 +\hspace*{0pt}{\char125}%
42.263 +\end{isamarkuptext}%
42.264 +\isamarkuptrue%
42.265 +%
42.266 +\endisatagquote
42.267 +{\isafoldquote}%
42.268 +%
42.269 +\isadelimquote
42.270 +%
42.271 +\endisadelimquote
42.272 +%
42.273 +\begin{isamarkuptext}%
42.274 +\noindent This demonstrates the basic usage of the \hyperlink{command.export-code}{\mbox{\isa{\isacommand{export{\isacharunderscore}code}}}} command;
42.275 + for more details see \secref{sec:further}.%
42.276 +\end{isamarkuptext}%
42.277 +\isamarkuptrue%
42.278 +%
42.279 +\isamarkupsubsection{Code generator architecture \label{sec:concept}%
42.280 +}
42.281 +\isamarkuptrue%
42.282 +%
42.283 +\begin{isamarkuptext}%
42.284 +What you have seen so far should be already enough in a lot of cases. If you
42.285 + are content with this, you can quit reading here. Anyway, in order to customise
42.286 + and adapt the code generator, it is inevitable to gain some understanding
42.287 + how it works.
42.288 +
42.289 + \begin{figure}[h]
42.290 + \begin{tikzpicture}[x = 4.2cm, y = 1cm]
42.291 + \tikzstyle entity=[rounded corners, draw, thick, color = black, fill = white];
42.292 + \tikzstyle process=[ellipse, draw, thick, color = green, fill = white];
42.293 + \tikzstyle process_arrow=[->, semithick, color = green];
42.294 + \node (HOL) at (0, 4) [style=entity] {\isa{Isabelle{\isacharslash}HOL} theory};
42.295 + \node (eqn) at (2, 2) [style=entity] {code equations};
42.296 + \node (iml) at (2, 0) [style=entity] {intermediate language};
42.297 + \node (seri) at (1, 0) [style=process] {serialisation};
42.298 + \node (SML) at (0, 3) [style=entity] {\isa{SML}};
42.299 + \node (OCaml) at (0, 2) [style=entity] {\isa{OCaml}};
42.300 + \node (further) at (0, 1) [style=entity] {\isa{{\isasymdots}}};
42.301 + \node (Haskell) at (0, 0) [style=entity] {\isa{Haskell}};
42.302 + \draw [style=process_arrow] (HOL) .. controls (2, 4) ..
42.303 + node [style=process, near start] {selection}
42.304 + node [style=process, near end] {preprocessing}
42.305 + (eqn);
42.306 + \draw [style=process_arrow] (eqn) -- node (transl) [style=process] {translation} (iml);
42.307 + \draw [style=process_arrow] (iml) -- (seri);
42.308 + \draw [style=process_arrow] (seri) -- (SML);
42.309 + \draw [style=process_arrow] (seri) -- (OCaml);
42.310 + \draw [style=process_arrow, dashed] (seri) -- (further);
42.311 + \draw [style=process_arrow] (seri) -- (Haskell);
42.312 + \end{tikzpicture}
42.313 + \caption{Code generator architecture}
42.314 + \label{fig:arch}
42.315 + \end{figure}
42.316 +
42.317 + The code generator employs a notion of executability
42.318 + for three foundational executable ingredients known
42.319 + from functional programming:
42.320 + \emph{code equations}, \emph{datatypes}, and
42.321 + \emph{type classes}. A code equation as a first approximation
42.322 + is a theorem of the form \isa{f\ t\isactrlisub {\isadigit{1}}\ t\isactrlisub {\isadigit{2}}\ {\isasymdots}\ t\isactrlisub n\ {\isasymequiv}\ t}
42.323 + (an equation headed by a constant \isa{f} with arguments
42.324 + \isa{t\isactrlisub {\isadigit{1}}\ t\isactrlisub {\isadigit{2}}\ {\isasymdots}\ t\isactrlisub n} and right hand side \isa{t}).
42.325 + Code generation aims to turn code equations
42.326 + into a functional program. This is achieved by three major
42.327 + components which operate sequentially, i.e. the result of one is
42.328 + the input
42.329 + of the next in the chain, see diagram \ref{fig:arch}:
42.330 +
42.331 + \begin{itemize}
42.332 +
42.333 + \item Out of the vast collection of theorems proven in a
42.334 + \qn{theory}, a reasonable subset modelling
42.335 + code equations is \qn{selected}.
42.336 +
42.337 + \item On those selected theorems, certain
42.338 + transformations are carried out
42.339 + (\qn{preprocessing}). Their purpose is to turn theorems
42.340 + representing non- or badly executable
42.341 + specifications into equivalent but executable counterparts.
42.342 + The result is a structured collection of \qn{code theorems}.
42.343 +
42.344 + \item Before the selected code equations are continued with,
42.345 + they can be \qn{preprocessed}, i.e. subjected to theorem
42.346 + transformations. This \qn{preprocessor} is an interface which
42.347 + allows to apply
42.348 + the full expressiveness of ML-based theorem transformations
42.349 + to code generation; motivating examples are shown below, see
42.350 + \secref{sec:preproc}.
42.351 + The result of the preprocessing step is a structured collection
42.352 + of code equations.
42.353 +
42.354 + \item These code equations are \qn{translated} to a program
42.355 + in an abstract intermediate language. Think of it as a kind
42.356 + of \qt{Mini-Haskell} with four \qn{statements}: \isa{data}
42.357 + (for datatypes), \isa{fun} (stemming from code equations),
42.358 + also \isa{class} and \isa{inst} (for type classes).
42.359 +
42.360 + \item Finally, the abstract program is \qn{serialised} into concrete
42.361 + source code of a target language.
42.362 +
42.363 + \end{itemize}
42.364 +
42.365 + \noindent From these steps, only the two last are carried out outside the logic; by
42.366 + keeping this layer as thin as possible, the amount of code to trust is
42.367 + kept to a minimum.%
42.368 +\end{isamarkuptext}%
42.369 +\isamarkuptrue%
42.370 +%
42.371 +\isadelimtheory
42.372 +%
42.373 +\endisadelimtheory
42.374 +%
42.375 +\isatagtheory
42.376 +\isacommand{end}\isamarkupfalse%
42.377 +%
42.378 +\endisatagtheory
42.379 +{\isafoldtheory}%
42.380 +%
42.381 +\isadelimtheory
42.382 +%
42.383 +\endisadelimtheory
42.384 +\isanewline
42.385 +\end{isabellebody}%
42.386 +%%% Local Variables:
42.387 +%%% mode: latex
42.388 +%%% TeX-master: "root"
42.389 +%%% End:
43.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
43.2 +++ b/doc-src/Codegen/Thy/document/ML.tex Wed Mar 04 11:05:29 2009 +0100
43.3 @@ -0,0 +1,255 @@
43.4 +%
43.5 +\begin{isabellebody}%
43.6 +\def\isabellecontext{ML}%
43.7 +%
43.8 +\isadelimtheory
43.9 +%
43.10 +\endisadelimtheory
43.11 +%
43.12 +\isatagtheory
43.13 +\isacommand{theory}\isamarkupfalse%
43.14 +\ {\isachardoublequoteopen}ML{\isachardoublequoteclose}\isanewline
43.15 +\isakeyword{imports}\ Setup\isanewline
43.16 +\isakeyword{begin}%
43.17 +\endisatagtheory
43.18 +{\isafoldtheory}%
43.19 +%
43.20 +\isadelimtheory
43.21 +%
43.22 +\endisadelimtheory
43.23 +%
43.24 +\isamarkupsection{ML system interfaces \label{sec:ml}%
43.25 +}
43.26 +\isamarkuptrue%
43.27 +%
43.28 +\begin{isamarkuptext}%
43.29 +Since the code generator framework not only aims to provide
43.30 + a nice Isar interface but also to form a base for
43.31 + code-generation-based applications, here a short
43.32 + description of the most important ML interfaces.%
43.33 +\end{isamarkuptext}%
43.34 +\isamarkuptrue%
43.35 +%
43.36 +\isamarkupsubsection{Executable theory content: \isa{Code}%
43.37 +}
43.38 +\isamarkuptrue%
43.39 +%
43.40 +\begin{isamarkuptext}%
43.41 +This Pure module implements the core notions of
43.42 + executable content of a theory.%
43.43 +\end{isamarkuptext}%
43.44 +\isamarkuptrue%
43.45 +%
43.46 +\isamarkupsubsubsection{Managing executable content%
43.47 +}
43.48 +\isamarkuptrue%
43.49 +%
43.50 +\isadelimmlref
43.51 +%
43.52 +\endisadelimmlref
43.53 +%
43.54 +\isatagmlref
43.55 +%
43.56 +\begin{isamarkuptext}%
43.57 +\begin{mldecls}
43.58 + \indexdef{}{ML}{Code.add\_eqn}\verb|Code.add_eqn: thm -> theory -> theory| \\
43.59 + \indexdef{}{ML}{Code.del\_eqn}\verb|Code.del_eqn: thm -> theory -> theory| \\
43.60 + \indexdef{}{ML}{Code.add\_eqnl}\verb|Code.add_eqnl: string * (thm * bool) list lazy -> theory -> theory| \\
43.61 + \indexdef{}{ML}{Code.map\_pre}\verb|Code.map_pre: (simpset -> simpset) -> theory -> theory| \\
43.62 + \indexdef{}{ML}{Code.map\_post}\verb|Code.map_post: (simpset -> simpset) -> theory -> theory| \\
43.63 + \indexdef{}{ML}{Code.add\_functrans}\verb|Code.add_functrans: string * (theory -> (thm * bool) list -> (thm * bool) list option)|\isasep\isanewline%
43.64 +\verb| -> theory -> theory| \\
43.65 + \indexdef{}{ML}{Code.del\_functrans}\verb|Code.del_functrans: string -> theory -> theory| \\
43.66 + \indexdef{}{ML}{Code.add\_datatype}\verb|Code.add_datatype: (string * typ) list -> theory -> theory| \\
43.67 + \indexdef{}{ML}{Code.get\_datatype}\verb|Code.get_datatype: theory -> string|\isasep\isanewline%
43.68 +\verb| -> (string * sort) list * (string * typ list) list| \\
43.69 + \indexdef{}{ML}{Code.get\_datatype\_of\_constr}\verb|Code.get_datatype_of_constr: theory -> string -> string option|
43.70 + \end{mldecls}
43.71 +
43.72 + \begin{description}
43.73 +
43.74 + \item \verb|Code.add_eqn|~\isa{thm}~\isa{thy} adds function
43.75 + theorem \isa{thm} to executable content.
43.76 +
43.77 + \item \verb|Code.del_eqn|~\isa{thm}~\isa{thy} removes function
43.78 + theorem \isa{thm} from executable content, if present.
43.79 +
43.80 + \item \verb|Code.add_eqnl|~\isa{{\isacharparenleft}const{\isacharcomma}\ lthms{\isacharparenright}}~\isa{thy} adds
43.81 + suspended code equations \isa{lthms} for constant
43.82 + \isa{const} to executable content.
43.83 +
43.84 + \item \verb|Code.map_pre|~\isa{f}~\isa{thy} changes
43.85 + the preprocessor simpset.
43.86 +
43.87 + \item \verb|Code.add_functrans|~\isa{{\isacharparenleft}name{\isacharcomma}\ f{\isacharparenright}}~\isa{thy} adds
43.88 + function transformer \isa{f} (named \isa{name}) to executable content;
43.89 + \isa{f} is a transformer of the code equations belonging
43.90 + to a certain function definition, depending on the
43.91 + current theory context. Returning \isa{NONE} indicates that no
43.92 + transformation took place; otherwise, the whole process will be iterated
43.93 + with the new code equations.
43.94 +
43.95 + \item \verb|Code.del_functrans|~\isa{name}~\isa{thy} removes
43.96 + function transformer named \isa{name} from executable content.
43.97 +
43.98 + \item \verb|Code.add_datatype|~\isa{cs}~\isa{thy} adds
43.99 + a datatype to executable content, with generation
43.100 + set \isa{cs}.
43.101 +
43.102 + \item \verb|Code.get_datatype_of_constr|~\isa{thy}~\isa{const}
43.103 + returns type constructor corresponding to
43.104 + constructor \isa{const}; returns \isa{NONE}
43.105 + if \isa{const} is no constructor.
43.106 +
43.107 + \end{description}%
43.108 +\end{isamarkuptext}%
43.109 +\isamarkuptrue%
43.110 +%
43.111 +\endisatagmlref
43.112 +{\isafoldmlref}%
43.113 +%
43.114 +\isadelimmlref
43.115 +%
43.116 +\endisadelimmlref
43.117 +%
43.118 +\isamarkupsubsection{Auxiliary%
43.119 +}
43.120 +\isamarkuptrue%
43.121 +%
43.122 +\isadelimmlref
43.123 +%
43.124 +\endisadelimmlref
43.125 +%
43.126 +\isatagmlref
43.127 +%
43.128 +\begin{isamarkuptext}%
43.129 +\begin{mldecls}
43.130 + \indexdef{}{ML}{Code\_Unit.read\_const}\verb|Code_Unit.read_const: theory -> string -> string| \\
43.131 + \indexdef{}{ML}{Code\_Unit.head\_eqn}\verb|Code_Unit.head_eqn: theory -> thm -> string * ((string * sort) list * typ)| \\
43.132 + \indexdef{}{ML}{Code\_Unit.rewrite\_eqn}\verb|Code_Unit.rewrite_eqn: simpset -> thm -> thm| \\
43.133 + \end{mldecls}
43.134 +
43.135 + \begin{description}
43.136 +
43.137 + \item \verb|Code_Unit.read_const|~\isa{thy}~\isa{s}
43.138 + reads a constant as a concrete term expression \isa{s}.
43.139 +
43.140 + \item \verb|Code_Unit.head_eqn|~\isa{thy}~\isa{thm}
43.141 + extracts the constant and its type from a code equation \isa{thm}.
43.142 +
43.143 + \item \verb|Code_Unit.rewrite_eqn|~\isa{ss}~\isa{thm}
43.144 + rewrites a code equation \isa{thm} with a simpset \isa{ss};
43.145 + only arguments and right hand side are rewritten,
43.146 + not the head of the code equation.
43.147 +
43.148 + \end{description}%
43.149 +\end{isamarkuptext}%
43.150 +\isamarkuptrue%
43.151 +%
43.152 +\endisatagmlref
43.153 +{\isafoldmlref}%
43.154 +%
43.155 +\isadelimmlref
43.156 +%
43.157 +\endisadelimmlref
43.158 +%
43.159 +\isamarkupsubsection{Implementing code generator applications%
43.160 +}
43.161 +\isamarkuptrue%
43.162 +%
43.163 +\begin{isamarkuptext}%
43.164 +Implementing code generator applications on top
43.165 + of the framework set out so far usually not only
43.166 + involves using those primitive interfaces
43.167 + but also storing code-dependent data and various
43.168 + other things.%
43.169 +\end{isamarkuptext}%
43.170 +\isamarkuptrue%
43.171 +%
43.172 +\isamarkupsubsubsection{Data depending on the theory's executable content%
43.173 +}
43.174 +\isamarkuptrue%
43.175 +%
43.176 +\begin{isamarkuptext}%
43.177 +Due to incrementality of code generation, changes in the
43.178 + theory's executable content have to be propagated in a
43.179 + certain fashion. Additionally, such changes may occur
43.180 + not only during theory extension but also during theory
43.181 + merge, which is a little bit nasty from an implementation
43.182 + point of view. The framework provides a solution
43.183 + to this technical challenge by providing a functorial
43.184 + data slot \verb|CodeDataFun|; on instantiation
43.185 + of this functor, the following types and operations
43.186 + are required:
43.187 +
43.188 + \medskip
43.189 + \begin{tabular}{l}
43.190 + \isa{type\ T} \\
43.191 + \isa{val\ empty{\isacharcolon}\ T} \\
43.192 + \isa{val\ purge{\isacharcolon}\ theory\ {\isasymrightarrow}\ string\ list\ option\ {\isasymrightarrow}\ T\ {\isasymrightarrow}\ T}
43.193 + \end{tabular}
43.194 +
43.195 + \begin{description}
43.196 +
43.197 + \item \isa{T} the type of data to store.
43.198 +
43.199 + \item \isa{empty} initial (empty) data.
43.200 +
43.201 + \item \isa{purge}~\isa{thy}~\isa{consts} propagates changes in executable content;
43.202 + \isa{consts} indicates the kind
43.203 + of change: \verb|NONE| stands for a fundamental change
43.204 + which invalidates any existing code, \isa{SOME\ consts}
43.205 + hints that executable content for constants \isa{consts}
43.206 + has changed.
43.207 +
43.208 + \end{description}
43.209 +
43.210 + \noindent An instance of \verb|CodeDataFun| provides the following
43.211 + interface:
43.212 +
43.213 + \medskip
43.214 + \begin{tabular}{l}
43.215 + \isa{get{\isacharcolon}\ theory\ {\isasymrightarrow}\ T} \\
43.216 + \isa{change{\isacharcolon}\ theory\ {\isasymrightarrow}\ {\isacharparenleft}T\ {\isasymrightarrow}\ T{\isacharparenright}\ {\isasymrightarrow}\ T} \\
43.217 + \isa{change{\isacharunderscore}yield{\isacharcolon}\ theory\ {\isasymrightarrow}\ {\isacharparenleft}T\ {\isasymrightarrow}\ {\isacharprime}a\ {\isacharasterisk}\ T{\isacharparenright}\ {\isasymrightarrow}\ {\isacharprime}a\ {\isacharasterisk}\ T}
43.218 + \end{tabular}
43.219 +
43.220 + \begin{description}
43.221 +
43.222 + \item \isa{get} retrieval of the current data.
43.223 +
43.224 + \item \isa{change} update of current data (cached!)
43.225 + by giving a continuation.
43.226 +
43.227 + \item \isa{change{\isacharunderscore}yield} update with side result.
43.228 +
43.229 + \end{description}%
43.230 +\end{isamarkuptext}%
43.231 +\isamarkuptrue%
43.232 +%
43.233 +\begin{isamarkuptext}%
43.234 +\bigskip
43.235 +
43.236 + \emph{Happy proving, happy hacking!}%
43.237 +\end{isamarkuptext}%
43.238 +\isamarkuptrue%
43.239 +%
43.240 +\isadelimtheory
43.241 +%
43.242 +\endisadelimtheory
43.243 +%
43.244 +\isatagtheory
43.245 +\isacommand{end}\isamarkupfalse%
43.246 +%
43.247 +\endisatagtheory
43.248 +{\isafoldtheory}%
43.249 +%
43.250 +\isadelimtheory
43.251 +%
43.252 +\endisadelimtheory
43.253 +\isanewline
43.254 +\end{isabellebody}%
43.255 +%%% Local Variables:
43.256 +%%% mode: latex
43.257 +%%% TeX-master: "root"
43.258 +%%% End:
44.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
44.2 +++ b/doc-src/Codegen/Thy/document/Program.tex Wed Mar 04 11:05:29 2009 +0100
44.3 @@ -0,0 +1,1238 @@
44.4 +%
44.5 +\begin{isabellebody}%
44.6 +\def\isabellecontext{Program}%
44.7 +%
44.8 +\isadelimtheory
44.9 +%
44.10 +\endisadelimtheory
44.11 +%
44.12 +\isatagtheory
44.13 +\isacommand{theory}\isamarkupfalse%
44.14 +\ Program\isanewline
44.15 +\isakeyword{imports}\ Introduction\isanewline
44.16 +\isakeyword{begin}%
44.17 +\endisatagtheory
44.18 +{\isafoldtheory}%
44.19 +%
44.20 +\isadelimtheory
44.21 +%
44.22 +\endisadelimtheory
44.23 +%
44.24 +\isamarkupsection{Turning Theories into Programs \label{sec:program}%
44.25 +}
44.26 +\isamarkuptrue%
44.27 +%
44.28 +\isamarkupsubsection{The \isa{Isabelle{\isacharslash}HOL} default setup%
44.29 +}
44.30 +\isamarkuptrue%
44.31 +%
44.32 +\begin{isamarkuptext}%
44.33 +We have already seen how by default equations stemming from
44.34 + \hyperlink{command.definition}{\mbox{\isa{\isacommand{definition}}}}/\hyperlink{command.primrec}{\mbox{\isa{\isacommand{primrec}}}}/\hyperlink{command.fun}{\mbox{\isa{\isacommand{fun}}}}
44.35 + statements are used for code generation. This default behaviour
44.36 + can be changed, e.g. by providing different code equations.
44.37 + All kinds of customisation shown in this section is \emph{safe}
44.38 + in the sense that the user does not have to worry about
44.39 + correctness -- all programs generatable that way are partially
44.40 + correct.%
44.41 +\end{isamarkuptext}%
44.42 +\isamarkuptrue%
44.43 +%
44.44 +\isamarkupsubsection{Selecting code equations%
44.45 +}
44.46 +\isamarkuptrue%
44.47 +%
44.48 +\begin{isamarkuptext}%
44.49 +Coming back to our introductory example, we
44.50 + could provide an alternative code equations for \isa{dequeue}
44.51 + explicitly:%
44.52 +\end{isamarkuptext}%
44.53 +\isamarkuptrue%
44.54 +%
44.55 +\isadelimquote
44.56 +%
44.57 +\endisadelimquote
44.58 +%
44.59 +\isatagquote
44.60 +\isacommand{lemma}\isamarkupfalse%
44.61 +\ {\isacharbrackleft}code{\isacharbrackright}{\isacharcolon}\isanewline
44.62 +\ \ {\isachardoublequoteopen}dequeue\ {\isacharparenleft}AQueue\ xs\ {\isacharbrackleft}{\isacharbrackright}{\isacharparenright}\ {\isacharequal}\isanewline
44.63 +\ \ \ \ \ {\isacharparenleft}if\ xs\ {\isacharequal}\ {\isacharbrackleft}{\isacharbrackright}\ then\ {\isacharparenleft}None{\isacharcomma}\ AQueue\ {\isacharbrackleft}{\isacharbrackright}\ {\isacharbrackleft}{\isacharbrackright}{\isacharparenright}\isanewline
44.64 +\ \ \ \ \ \ \ else\ dequeue\ {\isacharparenleft}AQueue\ {\isacharbrackleft}{\isacharbrackright}\ {\isacharparenleft}rev\ xs{\isacharparenright}{\isacharparenright}{\isacharparenright}{\isachardoublequoteclose}\isanewline
44.65 +\ \ {\isachardoublequoteopen}dequeue\ {\isacharparenleft}AQueue\ xs\ {\isacharparenleft}y\ {\isacharhash}\ ys{\isacharparenright}{\isacharparenright}\ {\isacharequal}\isanewline
44.66 +\ \ \ \ \ {\isacharparenleft}Some\ y{\isacharcomma}\ AQueue\ xs\ ys{\isacharparenright}{\isachardoublequoteclose}\isanewline
44.67 +\ \ \isacommand{by}\isamarkupfalse%
44.68 +\ {\isacharparenleft}cases\ xs{\isacharcomma}\ simp{\isacharunderscore}all{\isacharparenright}\ {\isacharparenleft}cases\ {\isachardoublequoteopen}rev\ xs{\isachardoublequoteclose}{\isacharcomma}\ simp{\isacharunderscore}all{\isacharparenright}%
44.69 +\endisatagquote
44.70 +{\isafoldquote}%
44.71 +%
44.72 +\isadelimquote
44.73 +%
44.74 +\endisadelimquote
44.75 +%
44.76 +\begin{isamarkuptext}%
44.77 +\noindent The annotation \isa{{\isacharbrackleft}code{\isacharbrackright}} is an \isa{Isar}
44.78 + \isa{attribute} which states that the given theorems should be
44.79 + considered as code equations for a \isa{fun} statement --
44.80 + the corresponding constant is determined syntactically. The resulting code:%
44.81 +\end{isamarkuptext}%
44.82 +\isamarkuptrue%
44.83 +%
44.84 +\isadelimquote
44.85 +%
44.86 +\endisadelimquote
44.87 +%
44.88 +\isatagquote
44.89 +%
44.90 +\begin{isamarkuptext}%
44.91 +\isatypewriter%
44.92 +\noindent%
44.93 +\hspace*{0pt}dequeue ::~forall a.~Queue a -> (Maybe a,~Queue a);\\
44.94 +\hspace*{0pt}dequeue (AQueue xs (y :~ys)) = (Just y,~AQueue xs ys);\\
44.95 +\hspace*{0pt}dequeue (AQueue xs []) =\\
44.96 +\hspace*{0pt} ~(if nulla xs then (Nothing,~AQueue [] [])\\
44.97 +\hspace*{0pt} ~~~else dequeue (AQueue [] (rev xs)));%
44.98 +\end{isamarkuptext}%
44.99 +\isamarkuptrue%
44.100 +%
44.101 +\endisatagquote
44.102 +{\isafoldquote}%
44.103 +%
44.104 +\isadelimquote
44.105 +%
44.106 +\endisadelimquote
44.107 +%
44.108 +\begin{isamarkuptext}%
44.109 +\noindent You may note that the equality test \isa{xs\ {\isacharequal}\ {\isacharbrackleft}{\isacharbrackright}} has been
44.110 + replaced by the predicate \isa{null\ xs}. This is due to the default
44.111 + setup in the \qn{preprocessor} to be discussed further below (\secref{sec:preproc}).
44.112 +
44.113 + Changing the default constructor set of datatypes is also
44.114 + possible. See \secref{sec:datatypes} for an example.
44.115 +
44.116 + As told in \secref{sec:concept}, code generation is based
44.117 + on a structured collection of code theorems.
44.118 + For explorative purpose, this collection
44.119 + may be inspected using the \hyperlink{command.code-thms}{\mbox{\isa{\isacommand{code{\isacharunderscore}thms}}}} command:%
44.120 +\end{isamarkuptext}%
44.121 +\isamarkuptrue%
44.122 +%
44.123 +\isadelimquote
44.124 +%
44.125 +\endisadelimquote
44.126 +%
44.127 +\isatagquote
44.128 +\isacommand{code{\isacharunderscore}thms}\isamarkupfalse%
44.129 +\ dequeue%
44.130 +\endisatagquote
44.131 +{\isafoldquote}%
44.132 +%
44.133 +\isadelimquote
44.134 +%
44.135 +\endisadelimquote
44.136 +%
44.137 +\begin{isamarkuptext}%
44.138 +\noindent prints a table with \emph{all} code equations
44.139 + for \isa{dequeue}, including
44.140 + \emph{all} code equations those equations depend
44.141 + on recursively.
44.142 +
44.143 + Similarly, the \hyperlink{command.code-deps}{\mbox{\isa{\isacommand{code{\isacharunderscore}deps}}}} command shows a graph
44.144 + visualising dependencies between code equations.%
44.145 +\end{isamarkuptext}%
44.146 +\isamarkuptrue%
44.147 +%
44.148 +\isamarkupsubsection{\isa{class} and \isa{instantiation}%
44.149 +}
44.150 +\isamarkuptrue%
44.151 +%
44.152 +\begin{isamarkuptext}%
44.153 +Concerning type classes and code generation, let us examine an example
44.154 + from abstract algebra:%
44.155 +\end{isamarkuptext}%
44.156 +\isamarkuptrue%
44.157 +%
44.158 +\isadelimquote
44.159 +%
44.160 +\endisadelimquote
44.161 +%
44.162 +\isatagquote
44.163 +\isacommand{class}\isamarkupfalse%
44.164 +\ semigroup\ {\isacharequal}\isanewline
44.165 +\ \ \isakeyword{fixes}\ mult\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharprime}a\ {\isasymRightarrow}\ {\isacharprime}a\ {\isasymRightarrow}\ {\isacharprime}a{\isachardoublequoteclose}\ {\isacharparenleft}\isakeyword{infixl}\ {\isachardoublequoteopen}{\isasymotimes}{\isachardoublequoteclose}\ {\isadigit{7}}{\isadigit{0}}{\isacharparenright}\isanewline
44.166 +\ \ \isakeyword{assumes}\ assoc{\isacharcolon}\ {\isachardoublequoteopen}{\isacharparenleft}x\ {\isasymotimes}\ y{\isacharparenright}\ {\isasymotimes}\ z\ {\isacharequal}\ x\ {\isasymotimes}\ {\isacharparenleft}y\ {\isasymotimes}\ z{\isacharparenright}{\isachardoublequoteclose}\isanewline
44.167 +\isanewline
44.168 +\isacommand{class}\isamarkupfalse%
44.169 +\ monoid\ {\isacharequal}\ semigroup\ {\isacharplus}\isanewline
44.170 +\ \ \isakeyword{fixes}\ neutral\ {\isacharcolon}{\isacharcolon}\ {\isacharprime}a\ {\isacharparenleft}{\isachardoublequoteopen}{\isasymone}{\isachardoublequoteclose}{\isacharparenright}\isanewline
44.171 +\ \ \isakeyword{assumes}\ neutl{\isacharcolon}\ {\isachardoublequoteopen}{\isasymone}\ {\isasymotimes}\ x\ {\isacharequal}\ x{\isachardoublequoteclose}\isanewline
44.172 +\ \ \ \ \isakeyword{and}\ neutr{\isacharcolon}\ {\isachardoublequoteopen}x\ {\isasymotimes}\ {\isasymone}\ {\isacharequal}\ x{\isachardoublequoteclose}\isanewline
44.173 +\isanewline
44.174 +\isacommand{instantiation}\isamarkupfalse%
44.175 +\ nat\ {\isacharcolon}{\isacharcolon}\ monoid\isanewline
44.176 +\isakeyword{begin}\isanewline
44.177 +\isanewline
44.178 +\isacommand{primrec}\isamarkupfalse%
44.179 +\ mult{\isacharunderscore}nat\ \isakeyword{where}\isanewline
44.180 +\ \ \ \ {\isachardoublequoteopen}{\isadigit{0}}\ {\isasymotimes}\ n\ {\isacharequal}\ {\isacharparenleft}{\isadigit{0}}{\isasymColon}nat{\isacharparenright}{\isachardoublequoteclose}\isanewline
44.181 +\ \ {\isacharbar}\ {\isachardoublequoteopen}Suc\ m\ {\isasymotimes}\ n\ {\isacharequal}\ n\ {\isacharplus}\ m\ {\isasymotimes}\ n{\isachardoublequoteclose}\isanewline
44.182 +\isanewline
44.183 +\isacommand{definition}\isamarkupfalse%
44.184 +\ neutral{\isacharunderscore}nat\ \isakeyword{where}\isanewline
44.185 +\ \ {\isachardoublequoteopen}{\isasymone}\ {\isacharequal}\ Suc\ {\isadigit{0}}{\isachardoublequoteclose}\isanewline
44.186 +\isanewline
44.187 +\isacommand{lemma}\isamarkupfalse%
44.188 +\ add{\isacharunderscore}mult{\isacharunderscore}distrib{\isacharcolon}\isanewline
44.189 +\ \ \isakeyword{fixes}\ n\ m\ q\ {\isacharcolon}{\isacharcolon}\ nat\isanewline
44.190 +\ \ \isakeyword{shows}\ {\isachardoublequoteopen}{\isacharparenleft}n\ {\isacharplus}\ m{\isacharparenright}\ {\isasymotimes}\ q\ {\isacharequal}\ n\ {\isasymotimes}\ q\ {\isacharplus}\ m\ {\isasymotimes}\ q{\isachardoublequoteclose}\isanewline
44.191 +\ \ \isacommand{by}\isamarkupfalse%
44.192 +\ {\isacharparenleft}induct\ n{\isacharparenright}\ simp{\isacharunderscore}all\isanewline
44.193 +\isanewline
44.194 +\isacommand{instance}\isamarkupfalse%
44.195 +\ \isacommand{proof}\isamarkupfalse%
44.196 +\isanewline
44.197 +\ \ \isacommand{fix}\isamarkupfalse%
44.198 +\ m\ n\ q\ {\isacharcolon}{\isacharcolon}\ nat\isanewline
44.199 +\ \ \isacommand{show}\isamarkupfalse%
44.200 +\ {\isachardoublequoteopen}m\ {\isasymotimes}\ n\ {\isasymotimes}\ q\ {\isacharequal}\ m\ {\isasymotimes}\ {\isacharparenleft}n\ {\isasymotimes}\ q{\isacharparenright}{\isachardoublequoteclose}\isanewline
44.201 +\ \ \ \ \isacommand{by}\isamarkupfalse%
44.202 +\ {\isacharparenleft}induct\ m{\isacharparenright}\ {\isacharparenleft}simp{\isacharunderscore}all\ add{\isacharcolon}\ add{\isacharunderscore}mult{\isacharunderscore}distrib{\isacharparenright}\isanewline
44.203 +\ \ \isacommand{show}\isamarkupfalse%
44.204 +\ {\isachardoublequoteopen}{\isasymone}\ {\isasymotimes}\ n\ {\isacharequal}\ n{\isachardoublequoteclose}\isanewline
44.205 +\ \ \ \ \isacommand{by}\isamarkupfalse%
44.206 +\ {\isacharparenleft}simp\ add{\isacharcolon}\ neutral{\isacharunderscore}nat{\isacharunderscore}def{\isacharparenright}\isanewline
44.207 +\ \ \isacommand{show}\isamarkupfalse%
44.208 +\ {\isachardoublequoteopen}m\ {\isasymotimes}\ {\isasymone}\ {\isacharequal}\ m{\isachardoublequoteclose}\isanewline
44.209 +\ \ \ \ \isacommand{by}\isamarkupfalse%
44.210 +\ {\isacharparenleft}induct\ m{\isacharparenright}\ {\isacharparenleft}simp{\isacharunderscore}all\ add{\isacharcolon}\ neutral{\isacharunderscore}nat{\isacharunderscore}def{\isacharparenright}\isanewline
44.211 +\isacommand{qed}\isamarkupfalse%
44.212 +\isanewline
44.213 +\isanewline
44.214 +\isacommand{end}\isamarkupfalse%
44.215 +%
44.216 +\endisatagquote
44.217 +{\isafoldquote}%
44.218 +%
44.219 +\isadelimquote
44.220 +%
44.221 +\endisadelimquote
44.222 +%
44.223 +\begin{isamarkuptext}%
44.224 +\noindent We define the natural operation of the natural numbers
44.225 + on monoids:%
44.226 +\end{isamarkuptext}%
44.227 +\isamarkuptrue%
44.228 +%
44.229 +\isadelimquote
44.230 +%
44.231 +\endisadelimquote
44.232 +%
44.233 +\isatagquote
44.234 +\isacommand{primrec}\isamarkupfalse%
44.235 +\ {\isacharparenleft}\isakeyword{in}\ monoid{\isacharparenright}\ pow\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymRightarrow}\ {\isacharprime}a\ {\isasymRightarrow}\ {\isacharprime}a{\isachardoublequoteclose}\ \isakeyword{where}\isanewline
44.236 +\ \ \ \ {\isachardoublequoteopen}pow\ {\isadigit{0}}\ a\ {\isacharequal}\ {\isasymone}{\isachardoublequoteclose}\isanewline
44.237 +\ \ {\isacharbar}\ {\isachardoublequoteopen}pow\ {\isacharparenleft}Suc\ n{\isacharparenright}\ a\ {\isacharequal}\ a\ {\isasymotimes}\ pow\ n\ a{\isachardoublequoteclose}%
44.238 +\endisatagquote
44.239 +{\isafoldquote}%
44.240 +%
44.241 +\isadelimquote
44.242 +%
44.243 +\endisadelimquote
44.244 +%
44.245 +\begin{isamarkuptext}%
44.246 +\noindent This we use to define the discrete exponentiation function:%
44.247 +\end{isamarkuptext}%
44.248 +\isamarkuptrue%
44.249 +%
44.250 +\isadelimquote
44.251 +%
44.252 +\endisadelimquote
44.253 +%
44.254 +\isatagquote
44.255 +\isacommand{definition}\isamarkupfalse%
44.256 +\ bexp\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymRightarrow}\ nat{\isachardoublequoteclose}\ \isakeyword{where}\isanewline
44.257 +\ \ {\isachardoublequoteopen}bexp\ n\ {\isacharequal}\ pow\ n\ {\isacharparenleft}Suc\ {\isacharparenleft}Suc\ {\isadigit{0}}{\isacharparenright}{\isacharparenright}{\isachardoublequoteclose}%
44.258 +\endisatagquote
44.259 +{\isafoldquote}%
44.260 +%
44.261 +\isadelimquote
44.262 +%
44.263 +\endisadelimquote
44.264 +%
44.265 +\begin{isamarkuptext}%
44.266 +\noindent The corresponding code:%
44.267 +\end{isamarkuptext}%
44.268 +\isamarkuptrue%
44.269 +%
44.270 +\isadelimquote
44.271 +%
44.272 +\endisadelimquote
44.273 +%
44.274 +\isatagquote
44.275 +%
44.276 +\begin{isamarkuptext}%
44.277 +\isatypewriter%
44.278 +\noindent%
44.279 +\hspace*{0pt}module Example where {\char123}\\
44.280 +\hspace*{0pt}\\
44.281 +\hspace*{0pt}\\
44.282 +\hspace*{0pt}data Nat = Zero{\char95}nat | Suc Nat;\\
44.283 +\hspace*{0pt}\\
44.284 +\hspace*{0pt}class Semigroup a where {\char123}\\
44.285 +\hspace*{0pt} ~mult ::~a -> a -> a;\\
44.286 +\hspace*{0pt}{\char125};\\
44.287 +\hspace*{0pt}\\
44.288 +\hspace*{0pt}class (Semigroup a) => Monoid a where {\char123}\\
44.289 +\hspace*{0pt} ~neutral ::~a;\\
44.290 +\hspace*{0pt}{\char125};\\
44.291 +\hspace*{0pt}\\
44.292 +\hspace*{0pt}pow ::~forall a.~(Monoid a) => Nat -> a -> a;\\
44.293 +\hspace*{0pt}pow Zero{\char95}nat a = neutral;\\
44.294 +\hspace*{0pt}pow (Suc n) a = mult a (pow n a);\\
44.295 +\hspace*{0pt}\\
44.296 +\hspace*{0pt}plus{\char95}nat ::~Nat -> Nat -> Nat;\\
44.297 +\hspace*{0pt}plus{\char95}nat (Suc m) n = plus{\char95}nat m (Suc n);\\
44.298 +\hspace*{0pt}plus{\char95}nat Zero{\char95}nat n = n;\\
44.299 +\hspace*{0pt}\\
44.300 +\hspace*{0pt}neutral{\char95}nat ::~Nat;\\
44.301 +\hspace*{0pt}neutral{\char95}nat = Suc Zero{\char95}nat;\\
44.302 +\hspace*{0pt}\\
44.303 +\hspace*{0pt}mult{\char95}nat ::~Nat -> Nat -> Nat;\\
44.304 +\hspace*{0pt}mult{\char95}nat Zero{\char95}nat n = Zero{\char95}nat;\\
44.305 +\hspace*{0pt}mult{\char95}nat (Suc m) n = plus{\char95}nat n (mult{\char95}nat m n);\\
44.306 +\hspace*{0pt}\\
44.307 +\hspace*{0pt}instance Semigroup Nat where {\char123}\\
44.308 +\hspace*{0pt} ~mult = mult{\char95}nat;\\
44.309 +\hspace*{0pt}{\char125};\\
44.310 +\hspace*{0pt}\\
44.311 +\hspace*{0pt}instance Monoid Nat where {\char123}\\
44.312 +\hspace*{0pt} ~neutral = neutral{\char95}nat;\\
44.313 +\hspace*{0pt}{\char125};\\
44.314 +\hspace*{0pt}\\
44.315 +\hspace*{0pt}bexp ::~Nat -> Nat;\\
44.316 +\hspace*{0pt}bexp n = pow n (Suc (Suc Zero{\char95}nat));\\
44.317 +\hspace*{0pt}\\
44.318 +\hspace*{0pt}{\char125}%
44.319 +\end{isamarkuptext}%
44.320 +\isamarkuptrue%
44.321 +%
44.322 +\endisatagquote
44.323 +{\isafoldquote}%
44.324 +%
44.325 +\isadelimquote
44.326 +%
44.327 +\endisadelimquote
44.328 +%
44.329 +\begin{isamarkuptext}%
44.330 +\noindent This is a convenient place to show how explicit dictionary construction
44.331 + manifests in generated code (here, the same example in \isa{SML}):%
44.332 +\end{isamarkuptext}%
44.333 +\isamarkuptrue%
44.334 +%
44.335 +\isadelimquote
44.336 +%
44.337 +\endisadelimquote
44.338 +%
44.339 +\isatagquote
44.340 +%
44.341 +\begin{isamarkuptext}%
44.342 +\isatypewriter%
44.343 +\noindent%
44.344 +\hspace*{0pt}structure Example = \\
44.345 +\hspace*{0pt}struct\\
44.346 +\hspace*{0pt}\\
44.347 +\hspace*{0pt}datatype nat = Zero{\char95}nat | Suc of nat;\\
44.348 +\hspace*{0pt}\\
44.349 +\hspace*{0pt}type 'a semigroup = {\char123}mult :~'a -> 'a -> 'a{\char125};\\
44.350 +\hspace*{0pt}fun mult (A{\char95}:'a semigroup) = {\char35}mult A{\char95};\\
44.351 +\hspace*{0pt}\\
44.352 +\hspace*{0pt}type 'a monoid = {\char123}Program{\char95}{\char95}semigroup{\char95}monoid :~'a semigroup,~neutral :~'a{\char125};\\
44.353 +\hspace*{0pt}fun semigroup{\char95}monoid (A{\char95}:'a monoid) = {\char35}Program{\char95}{\char95}semigroup{\char95}monoid A{\char95};\\
44.354 +\hspace*{0pt}fun neutral (A{\char95}:'a monoid) = {\char35}neutral A{\char95};\\
44.355 +\hspace*{0pt}\\
44.356 +\hspace*{0pt}fun pow A{\char95}~Zero{\char95}nat a = neutral A{\char95}\\
44.357 +\hspace*{0pt} ~| pow A{\char95}~(Suc n) a = mult (semigroup{\char95}monoid A{\char95}) a (pow A{\char95}~n a);\\
44.358 +\hspace*{0pt}\\
44.359 +\hspace*{0pt}fun plus{\char95}nat (Suc m) n = plus{\char95}nat m (Suc n)\\
44.360 +\hspace*{0pt} ~| plus{\char95}nat Zero{\char95}nat n = n;\\
44.361 +\hspace*{0pt}\\
44.362 +\hspace*{0pt}val neutral{\char95}nat :~nat = Suc Zero{\char95}nat\\
44.363 +\hspace*{0pt}\\
44.364 +\hspace*{0pt}fun mult{\char95}nat Zero{\char95}nat n = Zero{\char95}nat\\
44.365 +\hspace*{0pt} ~| mult{\char95}nat (Suc m) n = plus{\char95}nat n (mult{\char95}nat m n);\\
44.366 +\hspace*{0pt}\\
44.367 +\hspace*{0pt}val semigroup{\char95}nat = {\char123}mult = mult{\char95}nat{\char125}~:~nat semigroup;\\
44.368 +\hspace*{0pt}\\
44.369 +\hspace*{0pt}val monoid{\char95}nat =\\
44.370 +\hspace*{0pt} ~{\char123}Program{\char95}{\char95}semigroup{\char95}monoid = semigroup{\char95}nat,~neutral = neutral{\char95}nat{\char125}~:\\
44.371 +\hspace*{0pt} ~nat monoid;\\
44.372 +\hspace*{0pt}\\
44.373 +\hspace*{0pt}fun bexp n = pow monoid{\char95}nat n (Suc (Suc Zero{\char95}nat));\\
44.374 +\hspace*{0pt}\\
44.375 +\hspace*{0pt}end;~(*struct Example*)%
44.376 +\end{isamarkuptext}%
44.377 +\isamarkuptrue%
44.378 +%
44.379 +\endisatagquote
44.380 +{\isafoldquote}%
44.381 +%
44.382 +\isadelimquote
44.383 +%
44.384 +\endisadelimquote
44.385 +%
44.386 +\begin{isamarkuptext}%
44.387 +\noindent Note the parameters with trailing underscore (\verb|A_|)
44.388 + which are the dictionary parameters.%
44.389 +\end{isamarkuptext}%
44.390 +\isamarkuptrue%
44.391 +%
44.392 +\isamarkupsubsection{The preprocessor \label{sec:preproc}%
44.393 +}
44.394 +\isamarkuptrue%
44.395 +%
44.396 +\begin{isamarkuptext}%
44.397 +Before selected function theorems are turned into abstract
44.398 + code, a chain of definitional transformation steps is carried
44.399 + out: \emph{preprocessing}. In essence, the preprocessor
44.400 + consists of two components: a \emph{simpset} and \emph{function transformers}.
44.401 +
44.402 + The \emph{simpset} allows to employ the full generality of the Isabelle
44.403 + simplifier. Due to the interpretation of theorems
44.404 + as code equations, rewrites are applied to the right
44.405 + hand side and the arguments of the left hand side of an
44.406 + equation, but never to the constant heading the left hand side.
44.407 + An important special case are \emph{inline theorems} which may be
44.408 + declared and undeclared using the
44.409 + \emph{code inline} or \emph{code inline del} attribute respectively.
44.410 +
44.411 + Some common applications:%
44.412 +\end{isamarkuptext}%
44.413 +\isamarkuptrue%
44.414 +%
44.415 +\begin{itemize}
44.416 +%
44.417 +\begin{isamarkuptext}%
44.418 +\item replacing non-executable constructs by executable ones:%
44.419 +\end{isamarkuptext}%
44.420 +\isamarkuptrue%
44.421 +%
44.422 +\isadelimquote
44.423 +%
44.424 +\endisadelimquote
44.425 +%
44.426 +\isatagquote
44.427 +\isacommand{lemma}\isamarkupfalse%
44.428 +\ {\isacharbrackleft}code\ inline{\isacharbrackright}{\isacharcolon}\isanewline
44.429 +\ \ {\isachardoublequoteopen}x\ {\isasymin}\ set\ xs\ {\isasymlongleftrightarrow}\ x\ mem\ xs{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse%
44.430 +\ {\isacharparenleft}induct\ xs{\isacharparenright}\ simp{\isacharunderscore}all%
44.431 +\endisatagquote
44.432 +{\isafoldquote}%
44.433 +%
44.434 +\isadelimquote
44.435 +%
44.436 +\endisadelimquote
44.437 +%
44.438 +\begin{isamarkuptext}%
44.439 +\item eliminating superfluous constants:%
44.440 +\end{isamarkuptext}%
44.441 +\isamarkuptrue%
44.442 +%
44.443 +\isadelimquote
44.444 +%
44.445 +\endisadelimquote
44.446 +%
44.447 +\isatagquote
44.448 +\isacommand{lemma}\isamarkupfalse%
44.449 +\ {\isacharbrackleft}code\ inline{\isacharbrackright}{\isacharcolon}\isanewline
44.450 +\ \ {\isachardoublequoteopen}{\isadigit{1}}\ {\isacharequal}\ Suc\ {\isadigit{0}}{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse%
44.451 +\ simp%
44.452 +\endisatagquote
44.453 +{\isafoldquote}%
44.454 +%
44.455 +\isadelimquote
44.456 +%
44.457 +\endisadelimquote
44.458 +%
44.459 +\begin{isamarkuptext}%
44.460 +\item replacing executable but inconvenient constructs:%
44.461 +\end{isamarkuptext}%
44.462 +\isamarkuptrue%
44.463 +%
44.464 +\isadelimquote
44.465 +%
44.466 +\endisadelimquote
44.467 +%
44.468 +\isatagquote
44.469 +\isacommand{lemma}\isamarkupfalse%
44.470 +\ {\isacharbrackleft}code\ inline{\isacharbrackright}{\isacharcolon}\isanewline
44.471 +\ \ {\isachardoublequoteopen}xs\ {\isacharequal}\ {\isacharbrackleft}{\isacharbrackright}\ {\isasymlongleftrightarrow}\ List{\isachardot}null\ xs{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse%
44.472 +\ {\isacharparenleft}induct\ xs{\isacharparenright}\ simp{\isacharunderscore}all%
44.473 +\endisatagquote
44.474 +{\isafoldquote}%
44.475 +%
44.476 +\isadelimquote
44.477 +%
44.478 +\endisadelimquote
44.479 +%
44.480 +\end{itemize}
44.481 +%
44.482 +\begin{isamarkuptext}%
44.483 +\noindent \emph{Function transformers} provide a very general interface,
44.484 + transforming a list of function theorems to another
44.485 + list of function theorems, provided that neither the heading
44.486 + constant nor its type change. The \isa{{\isadigit{0}}} / \isa{Suc}
44.487 + pattern elimination implemented in
44.488 + theory \isa{Efficient{\isacharunderscore}Nat} (see \secref{eff_nat}) uses this
44.489 + interface.
44.490 +
44.491 + \noindent The current setup of the preprocessor may be inspected using
44.492 + the \hyperlink{command.print-codesetup}{\mbox{\isa{\isacommand{print{\isacharunderscore}codesetup}}}} command.
44.493 + \hyperlink{command.code-thms}{\mbox{\isa{\isacommand{code{\isacharunderscore}thms}}}} provides a convenient
44.494 + mechanism to inspect the impact of a preprocessor setup
44.495 + on code equations.
44.496 +
44.497 + \begin{warn}
44.498 + The attribute \emph{code unfold}
44.499 + associated with the \isa{SML\ code\ generator} also applies to
44.500 + the \isa{generic\ code\ generator}:
44.501 + \emph{code unfold} implies \emph{code inline}.
44.502 + \end{warn}%
44.503 +\end{isamarkuptext}%
44.504 +\isamarkuptrue%
44.505 +%
44.506 +\isamarkupsubsection{Datatypes \label{sec:datatypes}%
44.507 +}
44.508 +\isamarkuptrue%
44.509 +%
44.510 +\begin{isamarkuptext}%
44.511 +Conceptually, any datatype is spanned by a set of
44.512 + \emph{constructors} of type \isa{{\isasymtau}\ {\isacharequal}\ {\isasymdots}\ {\isasymRightarrow}\ {\isasymkappa}\ {\isasymalpha}\isactrlisub {\isadigit{1}}\ {\isasymdots}\ {\isasymalpha}\isactrlisub n} where \isa{{\isacharbraceleft}{\isasymalpha}\isactrlisub {\isadigit{1}}{\isacharcomma}\ {\isasymdots}{\isacharcomma}\ {\isasymalpha}\isactrlisub n{\isacharbraceright}} is exactly the set of \emph{all} type variables in
44.513 + \isa{{\isasymtau}}. The HOL datatype package by default registers any new
44.514 + datatype in the table of datatypes, which may be inspected using the
44.515 + \hyperlink{command.print-codesetup}{\mbox{\isa{\isacommand{print{\isacharunderscore}codesetup}}}} command.
44.516 +
44.517 + In some cases, it is appropriate to alter or extend this table. As
44.518 + an example, we will develop an alternative representation of the
44.519 + queue example given in \secref{sec:intro}. The amortised
44.520 + representation is convenient for generating code but exposes its
44.521 + \qt{implementation} details, which may be cumbersome when proving
44.522 + theorems about it. Therefore, here a simple, straightforward
44.523 + representation of queues:%
44.524 +\end{isamarkuptext}%
44.525 +\isamarkuptrue%
44.526 +%
44.527 +\isadelimquote
44.528 +%
44.529 +\endisadelimquote
44.530 +%
44.531 +\isatagquote
44.532 +\isacommand{datatype}\isamarkupfalse%
44.533 +\ {\isacharprime}a\ queue\ {\isacharequal}\ Queue\ {\isachardoublequoteopen}{\isacharprime}a\ list{\isachardoublequoteclose}\isanewline
44.534 +\isanewline
44.535 +\isacommand{definition}\isamarkupfalse%
44.536 +\ empty\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharprime}a\ queue{\isachardoublequoteclose}\ \isakeyword{where}\isanewline
44.537 +\ \ {\isachardoublequoteopen}empty\ {\isacharequal}\ Queue\ {\isacharbrackleft}{\isacharbrackright}{\isachardoublequoteclose}\isanewline
44.538 +\isanewline
44.539 +\isacommand{primrec}\isamarkupfalse%
44.540 +\ enqueue\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharprime}a\ {\isasymRightarrow}\ {\isacharprime}a\ queue\ {\isasymRightarrow}\ {\isacharprime}a\ queue{\isachardoublequoteclose}\ \isakeyword{where}\isanewline
44.541 +\ \ {\isachardoublequoteopen}enqueue\ x\ {\isacharparenleft}Queue\ xs{\isacharparenright}\ {\isacharequal}\ Queue\ {\isacharparenleft}xs\ {\isacharat}\ {\isacharbrackleft}x{\isacharbrackright}{\isacharparenright}{\isachardoublequoteclose}\isanewline
44.542 +\isanewline
44.543 +\isacommand{fun}\isamarkupfalse%
44.544 +\ dequeue\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharprime}a\ queue\ {\isasymRightarrow}\ {\isacharprime}a\ option\ {\isasymtimes}\ {\isacharprime}a\ queue{\isachardoublequoteclose}\ \isakeyword{where}\isanewline
44.545 +\ \ \ \ {\isachardoublequoteopen}dequeue\ {\isacharparenleft}Queue\ {\isacharbrackleft}{\isacharbrackright}{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}None{\isacharcomma}\ Queue\ {\isacharbrackleft}{\isacharbrackright}{\isacharparenright}{\isachardoublequoteclose}\isanewline
44.546 +\ \ {\isacharbar}\ {\isachardoublequoteopen}dequeue\ {\isacharparenleft}Queue\ {\isacharparenleft}x\ {\isacharhash}\ xs{\isacharparenright}{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}Some\ x{\isacharcomma}\ Queue\ xs{\isacharparenright}{\isachardoublequoteclose}%
44.547 +\endisatagquote
44.548 +{\isafoldquote}%
44.549 +%
44.550 +\isadelimquote
44.551 +%
44.552 +\endisadelimquote
44.553 +%
44.554 +\begin{isamarkuptext}%
44.555 +\noindent This we can use directly for proving; for executing,
44.556 + we provide an alternative characterisation:%
44.557 +\end{isamarkuptext}%
44.558 +\isamarkuptrue%
44.559 +%
44.560 +\isadelimquote
44.561 +%
44.562 +\endisadelimquote
44.563 +%
44.564 +\isatagquote
44.565 +\isacommand{definition}\isamarkupfalse%
44.566 +\ AQueue\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharprime}a\ list\ {\isasymRightarrow}\ {\isacharprime}a\ list\ {\isasymRightarrow}\ {\isacharprime}a\ queue{\isachardoublequoteclose}\ \isakeyword{where}\isanewline
44.567 +\ \ {\isachardoublequoteopen}AQueue\ xs\ ys\ {\isacharequal}\ Queue\ {\isacharparenleft}ys\ {\isacharat}\ rev\ xs{\isacharparenright}{\isachardoublequoteclose}\isanewline
44.568 +\isanewline
44.569 +\isacommand{code{\isacharunderscore}datatype}\isamarkupfalse%
44.570 +\ AQueue%
44.571 +\endisatagquote
44.572 +{\isafoldquote}%
44.573 +%
44.574 +\isadelimquote
44.575 +%
44.576 +\endisadelimquote
44.577 +%
44.578 +\begin{isamarkuptext}%
44.579 +\noindent Here we define a \qt{constructor} \isa{AQueue} which
44.580 + is defined in terms of \isa{Queue} and interprets its arguments
44.581 + according to what the \emph{content} of an amortised queue is supposed
44.582 + to be. Equipped with this, we are able to prove the following equations
44.583 + for our primitive queue operations which \qt{implement} the simple
44.584 + queues in an amortised fashion:%
44.585 +\end{isamarkuptext}%
44.586 +\isamarkuptrue%
44.587 +%
44.588 +\isadelimquote
44.589 +%
44.590 +\endisadelimquote
44.591 +%
44.592 +\isatagquote
44.593 +\isacommand{lemma}\isamarkupfalse%
44.594 +\ empty{\isacharunderscore}AQueue\ {\isacharbrackleft}code{\isacharbrackright}{\isacharcolon}\isanewline
44.595 +\ \ {\isachardoublequoteopen}empty\ {\isacharequal}\ AQueue\ {\isacharbrackleft}{\isacharbrackright}\ {\isacharbrackleft}{\isacharbrackright}{\isachardoublequoteclose}\isanewline
44.596 +\ \ \isacommand{unfolding}\isamarkupfalse%
44.597 +\ AQueue{\isacharunderscore}def\ empty{\isacharunderscore}def\ \isacommand{by}\isamarkupfalse%
44.598 +\ simp\isanewline
44.599 +\isanewline
44.600 +\isacommand{lemma}\isamarkupfalse%
44.601 +\ enqueue{\isacharunderscore}AQueue\ {\isacharbrackleft}code{\isacharbrackright}{\isacharcolon}\isanewline
44.602 +\ \ {\isachardoublequoteopen}enqueue\ x\ {\isacharparenleft}AQueue\ xs\ ys{\isacharparenright}\ {\isacharequal}\ AQueue\ {\isacharparenleft}x\ {\isacharhash}\ xs{\isacharparenright}\ ys{\isachardoublequoteclose}\isanewline
44.603 +\ \ \isacommand{unfolding}\isamarkupfalse%
44.604 +\ AQueue{\isacharunderscore}def\ \isacommand{by}\isamarkupfalse%
44.605 +\ simp\isanewline
44.606 +\isanewline
44.607 +\isacommand{lemma}\isamarkupfalse%
44.608 +\ dequeue{\isacharunderscore}AQueue\ {\isacharbrackleft}code{\isacharbrackright}{\isacharcolon}\isanewline
44.609 +\ \ {\isachardoublequoteopen}dequeue\ {\isacharparenleft}AQueue\ xs\ {\isacharbrackleft}{\isacharbrackright}{\isacharparenright}\ {\isacharequal}\isanewline
44.610 +\ \ \ \ {\isacharparenleft}if\ xs\ {\isacharequal}\ {\isacharbrackleft}{\isacharbrackright}\ then\ {\isacharparenleft}None{\isacharcomma}\ AQueue\ {\isacharbrackleft}{\isacharbrackright}\ {\isacharbrackleft}{\isacharbrackright}{\isacharparenright}\isanewline
44.611 +\ \ \ \ else\ dequeue\ {\isacharparenleft}AQueue\ {\isacharbrackleft}{\isacharbrackright}\ {\isacharparenleft}rev\ xs{\isacharparenright}{\isacharparenright}{\isacharparenright}{\isachardoublequoteclose}\isanewline
44.612 +\ \ {\isachardoublequoteopen}dequeue\ {\isacharparenleft}AQueue\ xs\ {\isacharparenleft}y\ {\isacharhash}\ ys{\isacharparenright}{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}Some\ y{\isacharcomma}\ AQueue\ xs\ ys{\isacharparenright}{\isachardoublequoteclose}\isanewline
44.613 +\ \ \isacommand{unfolding}\isamarkupfalse%
44.614 +\ AQueue{\isacharunderscore}def\ \isacommand{by}\isamarkupfalse%
44.615 +\ simp{\isacharunderscore}all%
44.616 +\endisatagquote
44.617 +{\isafoldquote}%
44.618 +%
44.619 +\isadelimquote
44.620 +%
44.621 +\endisadelimquote
44.622 +%
44.623 +\begin{isamarkuptext}%
44.624 +\noindent For completeness, we provide a substitute for the
44.625 + \isa{case} combinator on queues:%
44.626 +\end{isamarkuptext}%
44.627 +\isamarkuptrue%
44.628 +%
44.629 +\isadelimquote
44.630 +%
44.631 +\endisadelimquote
44.632 +%
44.633 +\isatagquote
44.634 +\isacommand{lemma}\isamarkupfalse%
44.635 +\ queue{\isacharunderscore}case{\isacharunderscore}AQueue\ {\isacharbrackleft}code{\isacharbrackright}{\isacharcolon}\isanewline
44.636 +\ \ {\isachardoublequoteopen}queue{\isacharunderscore}case\ f\ {\isacharparenleft}AQueue\ xs\ ys{\isacharparenright}\ {\isacharequal}\ f\ {\isacharparenleft}ys\ {\isacharat}\ rev\ xs{\isacharparenright}{\isachardoublequoteclose}\isanewline
44.637 +\ \ \isacommand{unfolding}\isamarkupfalse%
44.638 +\ AQueue{\isacharunderscore}def\ \isacommand{by}\isamarkupfalse%
44.639 +\ simp%
44.640 +\endisatagquote
44.641 +{\isafoldquote}%
44.642 +%
44.643 +\isadelimquote
44.644 +%
44.645 +\endisadelimquote
44.646 +%
44.647 +\begin{isamarkuptext}%
44.648 +\noindent The resulting code looks as expected:%
44.649 +\end{isamarkuptext}%
44.650 +\isamarkuptrue%
44.651 +%
44.652 +\isadelimquote
44.653 +%
44.654 +\endisadelimquote
44.655 +%
44.656 +\isatagquote
44.657 +%
44.658 +\begin{isamarkuptext}%
44.659 +\isatypewriter%
44.660 +\noindent%
44.661 +\hspace*{0pt}structure Example = \\
44.662 +\hspace*{0pt}struct\\
44.663 +\hspace*{0pt}\\
44.664 +\hspace*{0pt}fun foldl f a [] = a\\
44.665 +\hspace*{0pt} ~| foldl f a (x ::~xs) = foldl f (f a x) xs;\\
44.666 +\hspace*{0pt}\\
44.667 +\hspace*{0pt}fun rev xs = foldl (fn xsa => fn x => x ::~xsa) [] xs;\\
44.668 +\hspace*{0pt}\\
44.669 +\hspace*{0pt}fun null [] = true\\
44.670 +\hspace*{0pt} ~| null (x ::~xs) = false;\\
44.671 +\hspace*{0pt}\\
44.672 +\hspace*{0pt}datatype 'a queue = AQueue of 'a list * 'a list;\\
44.673 +\hspace*{0pt}\\
44.674 +\hspace*{0pt}val empty :~'a queue = AQueue ([],~[])\\
44.675 +\hspace*{0pt}\\
44.676 +\hspace*{0pt}fun dequeue (AQueue (xs,~y ::~ys)) = (SOME y,~AQueue (xs,~ys))\\
44.677 +\hspace*{0pt} ~| dequeue (AQueue (xs,~[])) =\\
44.678 +\hspace*{0pt} ~~~(if null xs then (NONE,~AQueue ([],~[]))\\
44.679 +\hspace*{0pt} ~~~~~else dequeue (AQueue ([],~rev xs)));\\
44.680 +\hspace*{0pt}\\
44.681 +\hspace*{0pt}fun enqueue x (AQueue (xs,~ys)) = AQueue (x ::~xs,~ys);\\
44.682 +\hspace*{0pt}\\
44.683 +\hspace*{0pt}end;~(*struct Example*)%
44.684 +\end{isamarkuptext}%
44.685 +\isamarkuptrue%
44.686 +%
44.687 +\endisatagquote
44.688 +{\isafoldquote}%
44.689 +%
44.690 +\isadelimquote
44.691 +%
44.692 +\endisadelimquote
44.693 +%
44.694 +\begin{isamarkuptext}%
44.695 +\noindent From this example, it can be glimpsed that using own
44.696 + constructor sets is a little delicate since it changes the set of
44.697 + valid patterns for values of that type. Without going into much
44.698 + detail, here some practical hints:
44.699 +
44.700 + \begin{itemize}
44.701 +
44.702 + \item When changing the constructor set for datatypes, take care
44.703 + to provide alternative equations for the \isa{case} combinator.
44.704 +
44.705 + \item Values in the target language need not to be normalised --
44.706 + different values in the target language may represent the same
44.707 + value in the logic.
44.708 +
44.709 + \item Usually, a good methodology to deal with the subtleties of
44.710 + pattern matching is to see the type as an abstract type: provide
44.711 + a set of operations which operate on the concrete representation
44.712 + of the type, and derive further operations by combinations of
44.713 + these primitive ones, without relying on a particular
44.714 + representation.
44.715 +
44.716 + \end{itemize}%
44.717 +\end{isamarkuptext}%
44.718 +\isamarkuptrue%
44.719 +%
44.720 +\isamarkupsubsection{Equality and wellsortedness%
44.721 +}
44.722 +\isamarkuptrue%
44.723 +%
44.724 +\begin{isamarkuptext}%
44.725 +Surely you have already noticed how equality is treated
44.726 + by the code generator:%
44.727 +\end{isamarkuptext}%
44.728 +\isamarkuptrue%
44.729 +%
44.730 +\isadelimquote
44.731 +%
44.732 +\endisadelimquote
44.733 +%
44.734 +\isatagquote
44.735 +\isacommand{primrec}\isamarkupfalse%
44.736 +\ collect{\isacharunderscore}duplicates\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharprime}a\ list\ {\isasymRightarrow}\ {\isacharprime}a\ list\ {\isasymRightarrow}\ {\isacharprime}a\ list\ {\isasymRightarrow}\ {\isacharprime}a\ list{\isachardoublequoteclose}\ \isakeyword{where}\isanewline
44.737 +\ \ {\isachardoublequoteopen}collect{\isacharunderscore}duplicates\ xs\ ys\ {\isacharbrackleft}{\isacharbrackright}\ {\isacharequal}\ xs{\isachardoublequoteclose}\isanewline
44.738 +\ \ {\isacharbar}\ {\isachardoublequoteopen}collect{\isacharunderscore}duplicates\ xs\ ys\ {\isacharparenleft}z{\isacharhash}zs{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}if\ z\ {\isasymin}\ set\ xs\isanewline
44.739 +\ \ \ \ \ \ then\ if\ z\ {\isasymin}\ set\ ys\isanewline
44.740 +\ \ \ \ \ \ \ \ then\ collect{\isacharunderscore}duplicates\ xs\ ys\ zs\isanewline
44.741 +\ \ \ \ \ \ \ \ else\ collect{\isacharunderscore}duplicates\ xs\ {\isacharparenleft}z{\isacharhash}ys{\isacharparenright}\ zs\isanewline
44.742 +\ \ \ \ \ \ else\ collect{\isacharunderscore}duplicates\ {\isacharparenleft}z{\isacharhash}xs{\isacharparenright}\ {\isacharparenleft}z{\isacharhash}ys{\isacharparenright}\ zs{\isacharparenright}{\isachardoublequoteclose}%
44.743 +\endisatagquote
44.744 +{\isafoldquote}%
44.745 +%
44.746 +\isadelimquote
44.747 +%
44.748 +\endisadelimquote
44.749 +%
44.750 +\begin{isamarkuptext}%
44.751 +\noindent The membership test during preprocessing is rewritten,
44.752 + resulting in \isa{op\ mem}, which itself
44.753 + performs an explicit equality check.%
44.754 +\end{isamarkuptext}%
44.755 +\isamarkuptrue%
44.756 +%
44.757 +\isadelimquote
44.758 +%
44.759 +\endisadelimquote
44.760 +%
44.761 +\isatagquote
44.762 +%
44.763 +\begin{isamarkuptext}%
44.764 +\isatypewriter%
44.765 +\noindent%
44.766 +\hspace*{0pt}structure Example = \\
44.767 +\hspace*{0pt}struct\\
44.768 +\hspace*{0pt}\\
44.769 +\hspace*{0pt}type 'a eq = {\char123}eq :~'a -> 'a -> bool{\char125};\\
44.770 +\hspace*{0pt}fun eq (A{\char95}:'a eq) = {\char35}eq A{\char95};\\
44.771 +\hspace*{0pt}\\
44.772 +\hspace*{0pt}fun eqop A{\char95}~a b = eq A{\char95}~a b;\\
44.773 +\hspace*{0pt}\\
44.774 +\hspace*{0pt}fun member A{\char95}~x [] = false\\
44.775 +\hspace*{0pt} ~| member A{\char95}~x (y ::~ys) = eqop A{\char95}~x y orelse member A{\char95}~x ys;\\
44.776 +\hspace*{0pt}\\
44.777 +\hspace*{0pt}fun collect{\char95}duplicates A{\char95}~xs ys [] = xs\\
44.778 +\hspace*{0pt} ~| collect{\char95}duplicates A{\char95}~xs ys (z ::~zs) =\\
44.779 +\hspace*{0pt} ~~~(if member A{\char95}~z xs\\
44.780 +\hspace*{0pt} ~~~~~then (if member A{\char95}~z ys then collect{\char95}duplicates A{\char95}~xs ys zs\\
44.781 +\hspace*{0pt} ~~~~~~~~~~~~else collect{\char95}duplicates A{\char95}~xs (z ::~ys) zs)\\
44.782 +\hspace*{0pt} ~~~~~else collect{\char95}duplicates A{\char95}~(z ::~xs) (z ::~ys) zs);\\
44.783 +\hspace*{0pt}\\
44.784 +\hspace*{0pt}end;~(*struct Example*)%
44.785 +\end{isamarkuptext}%
44.786 +\isamarkuptrue%
44.787 +%
44.788 +\endisatagquote
44.789 +{\isafoldquote}%
44.790 +%
44.791 +\isadelimquote
44.792 +%
44.793 +\endisadelimquote
44.794 +%
44.795 +\begin{isamarkuptext}%
44.796 +\noindent Obviously, polymorphic equality is implemented the Haskell
44.797 + way using a type class. How is this achieved? HOL introduces
44.798 + an explicit class \isa{eq} with a corresponding operation
44.799 + \isa{eq{\isacharunderscore}class{\isachardot}eq} such that \isa{eq{\isacharunderscore}class{\isachardot}eq\ {\isacharequal}\ op\ {\isacharequal}}.
44.800 + The preprocessing framework does the rest by propagating the
44.801 + \isa{eq} constraints through all dependent code equations.
44.802 + For datatypes, instances of \isa{eq} are implicitly derived
44.803 + when possible. For other types, you may instantiate \isa{eq}
44.804 + manually like any other type class.
44.805 +
44.806 + Though this \isa{eq} class is designed to get rarely in
44.807 + the way, a subtlety
44.808 + enters the stage when definitions of overloaded constants
44.809 + are dependent on operational equality. For example, let
44.810 + us define a lexicographic ordering on tuples
44.811 + (also see theory \hyperlink{theory.Product-ord}{\mbox{\isa{Product{\isacharunderscore}ord}}}):%
44.812 +\end{isamarkuptext}%
44.813 +\isamarkuptrue%
44.814 +%
44.815 +\isadelimquote
44.816 +%
44.817 +\endisadelimquote
44.818 +%
44.819 +\isatagquote
44.820 +\isacommand{instantiation}\isamarkupfalse%
44.821 +\ {\isachardoublequoteopen}{\isacharasterisk}{\isachardoublequoteclose}\ {\isacharcolon}{\isacharcolon}\ {\isacharparenleft}order{\isacharcomma}\ order{\isacharparenright}\ order\isanewline
44.822 +\isakeyword{begin}\isanewline
44.823 +\isanewline
44.824 +\isacommand{definition}\isamarkupfalse%
44.825 +\ {\isacharbrackleft}code\ del{\isacharbrackright}{\isacharcolon}\isanewline
44.826 +\ \ {\isachardoublequoteopen}x\ {\isasymle}\ y\ {\isasymlongleftrightarrow}\ fst\ x\ {\isacharless}\ fst\ y\ {\isasymor}\ fst\ x\ {\isacharequal}\ fst\ y\ {\isasymand}\ snd\ x\ {\isasymle}\ snd\ y{\isachardoublequoteclose}\isanewline
44.827 +\isanewline
44.828 +\isacommand{definition}\isamarkupfalse%
44.829 +\ {\isacharbrackleft}code\ del{\isacharbrackright}{\isacharcolon}\isanewline
44.830 +\ \ {\isachardoublequoteopen}x\ {\isacharless}\ y\ {\isasymlongleftrightarrow}\ fst\ x\ {\isacharless}\ fst\ y\ {\isasymor}\ fst\ x\ {\isacharequal}\ fst\ y\ {\isasymand}\ snd\ x\ {\isacharless}\ snd\ y{\isachardoublequoteclose}\isanewline
44.831 +\isanewline
44.832 +\isacommand{instance}\isamarkupfalse%
44.833 +\ \isacommand{proof}\isamarkupfalse%
44.834 +\isanewline
44.835 +\isacommand{qed}\isamarkupfalse%
44.836 +\ {\isacharparenleft}auto\ simp{\isacharcolon}\ less{\isacharunderscore}eq{\isacharunderscore}prod{\isacharunderscore}def\ less{\isacharunderscore}prod{\isacharunderscore}def\ intro{\isacharcolon}\ order{\isacharunderscore}less{\isacharunderscore}trans{\isacharparenright}\isanewline
44.837 +\isanewline
44.838 +\isacommand{end}\isamarkupfalse%
44.839 +\isanewline
44.840 +\isanewline
44.841 +\isacommand{lemma}\isamarkupfalse%
44.842 +\ order{\isacharunderscore}prod\ {\isacharbrackleft}code{\isacharbrackright}{\isacharcolon}\isanewline
44.843 +\ \ {\isachardoublequoteopen}{\isacharparenleft}x{\isadigit{1}}\ {\isasymColon}\ {\isacharprime}a{\isasymColon}order{\isacharcomma}\ y{\isadigit{1}}\ {\isasymColon}\ {\isacharprime}b{\isasymColon}order{\isacharparenright}\ {\isacharless}\ {\isacharparenleft}x{\isadigit{2}}{\isacharcomma}\ y{\isadigit{2}}{\isacharparenright}\ {\isasymlongleftrightarrow}\isanewline
44.844 +\ \ \ \ \ x{\isadigit{1}}\ {\isacharless}\ x{\isadigit{2}}\ {\isasymor}\ x{\isadigit{1}}\ {\isacharequal}\ x{\isadigit{2}}\ {\isasymand}\ y{\isadigit{1}}\ {\isacharless}\ y{\isadigit{2}}{\isachardoublequoteclose}\isanewline
44.845 +\ \ {\isachardoublequoteopen}{\isacharparenleft}x{\isadigit{1}}\ {\isasymColon}\ {\isacharprime}a{\isasymColon}order{\isacharcomma}\ y{\isadigit{1}}\ {\isasymColon}\ {\isacharprime}b{\isasymColon}order{\isacharparenright}\ {\isasymle}\ {\isacharparenleft}x{\isadigit{2}}{\isacharcomma}\ y{\isadigit{2}}{\isacharparenright}\ {\isasymlongleftrightarrow}\isanewline
44.846 +\ \ \ \ \ x{\isadigit{1}}\ {\isacharless}\ x{\isadigit{2}}\ {\isasymor}\ x{\isadigit{1}}\ {\isacharequal}\ x{\isadigit{2}}\ {\isasymand}\ y{\isadigit{1}}\ {\isasymle}\ y{\isadigit{2}}{\isachardoublequoteclose}\isanewline
44.847 +\ \ \isacommand{by}\isamarkupfalse%
44.848 +\ {\isacharparenleft}simp{\isacharunderscore}all\ add{\isacharcolon}\ less{\isacharunderscore}prod{\isacharunderscore}def\ less{\isacharunderscore}eq{\isacharunderscore}prod{\isacharunderscore}def{\isacharparenright}%
44.849 +\endisatagquote
44.850 +{\isafoldquote}%
44.851 +%
44.852 +\isadelimquote
44.853 +%
44.854 +\endisadelimquote
44.855 +%
44.856 +\begin{isamarkuptext}%
44.857 +\noindent Then code generation will fail. Why? The definition
44.858 + of \isa{op\ {\isasymle}} depends on equality on both arguments,
44.859 + which are polymorphic and impose an additional \isa{eq}
44.860 + class constraint, which the preprocessor does not propagate
44.861 + (for technical reasons).
44.862 +
44.863 + The solution is to add \isa{eq} explicitly to the first sort arguments in the
44.864 + code theorems:%
44.865 +\end{isamarkuptext}%
44.866 +\isamarkuptrue%
44.867 +%
44.868 +\isadelimquote
44.869 +%
44.870 +\endisadelimquote
44.871 +%
44.872 +\isatagquote
44.873 +\isacommand{lemma}\isamarkupfalse%
44.874 +\ order{\isacharunderscore}prod{\isacharunderscore}code\ {\isacharbrackleft}code{\isacharbrackright}{\isacharcolon}\isanewline
44.875 +\ \ {\isachardoublequoteopen}{\isacharparenleft}x{\isadigit{1}}\ {\isasymColon}\ {\isacharprime}a{\isasymColon}{\isacharbraceleft}order{\isacharcomma}\ eq{\isacharbraceright}{\isacharcomma}\ y{\isadigit{1}}\ {\isasymColon}\ {\isacharprime}b{\isasymColon}order{\isacharparenright}\ {\isacharless}\ {\isacharparenleft}x{\isadigit{2}}{\isacharcomma}\ y{\isadigit{2}}{\isacharparenright}\ {\isasymlongleftrightarrow}\isanewline
44.876 +\ \ \ \ \ x{\isadigit{1}}\ {\isacharless}\ x{\isadigit{2}}\ {\isasymor}\ x{\isadigit{1}}\ {\isacharequal}\ x{\isadigit{2}}\ {\isasymand}\ y{\isadigit{1}}\ {\isacharless}\ y{\isadigit{2}}{\isachardoublequoteclose}\isanewline
44.877 +\ \ {\isachardoublequoteopen}{\isacharparenleft}x{\isadigit{1}}\ {\isasymColon}\ {\isacharprime}a{\isasymColon}{\isacharbraceleft}order{\isacharcomma}\ eq{\isacharbraceright}{\isacharcomma}\ y{\isadigit{1}}\ {\isasymColon}\ {\isacharprime}b{\isasymColon}order{\isacharparenright}\ {\isasymle}\ {\isacharparenleft}x{\isadigit{2}}{\isacharcomma}\ y{\isadigit{2}}{\isacharparenright}\ {\isasymlongleftrightarrow}\isanewline
44.878 +\ \ \ \ \ x{\isadigit{1}}\ {\isacharless}\ x{\isadigit{2}}\ {\isasymor}\ x{\isadigit{1}}\ {\isacharequal}\ x{\isadigit{2}}\ {\isasymand}\ y{\isadigit{1}}\ {\isasymle}\ y{\isadigit{2}}{\isachardoublequoteclose}\isanewline
44.879 +\ \ \isacommand{by}\isamarkupfalse%
44.880 +\ {\isacharparenleft}simp{\isacharunderscore}all\ add{\isacharcolon}\ less{\isacharunderscore}prod{\isacharunderscore}def\ less{\isacharunderscore}eq{\isacharunderscore}prod{\isacharunderscore}def{\isacharparenright}%
44.881 +\endisatagquote
44.882 +{\isafoldquote}%
44.883 +%
44.884 +\isadelimquote
44.885 +%
44.886 +\endisadelimquote
44.887 +%
44.888 +\begin{isamarkuptext}%
44.889 +\noindent Then code generation succeeds:%
44.890 +\end{isamarkuptext}%
44.891 +\isamarkuptrue%
44.892 +%
44.893 +\isadelimquote
44.894 +%
44.895 +\endisadelimquote
44.896 +%
44.897 +\isatagquote
44.898 +%
44.899 +\begin{isamarkuptext}%
44.900 +\isatypewriter%
44.901 +\noindent%
44.902 +\hspace*{0pt}structure Example = \\
44.903 +\hspace*{0pt}struct\\
44.904 +\hspace*{0pt}\\
44.905 +\hspace*{0pt}type 'a eq = {\char123}eq :~'a -> 'a -> bool{\char125};\\
44.906 +\hspace*{0pt}fun eq (A{\char95}:'a eq) = {\char35}eq A{\char95};\\
44.907 +\hspace*{0pt}\\
44.908 +\hspace*{0pt}type 'a ord = {\char123}less{\char95}eq :~'a -> 'a -> bool,~less :~'a -> 'a -> bool{\char125};\\
44.909 +\hspace*{0pt}fun less{\char95}eq (A{\char95}:'a ord) = {\char35}less{\char95}eq A{\char95};\\
44.910 +\hspace*{0pt}fun less (A{\char95}:'a ord) = {\char35}less A{\char95};\\
44.911 +\hspace*{0pt}\\
44.912 +\hspace*{0pt}fun eqop A{\char95}~a b = eq A{\char95}~a b;\\
44.913 +\hspace*{0pt}\\
44.914 +\hspace*{0pt}type 'a preorder = {\char123}Orderings{\char95}{\char95}ord{\char95}preorder :~'a ord{\char125};\\
44.915 +\hspace*{0pt}fun ord{\char95}preorder (A{\char95}:'a preorder) = {\char35}Orderings{\char95}{\char95}ord{\char95}preorder A{\char95};\\
44.916 +\hspace*{0pt}\\
44.917 +\hspace*{0pt}type 'a order = {\char123}Orderings{\char95}{\char95}preorder{\char95}order :~'a preorder{\char125};\\
44.918 +\hspace*{0pt}fun preorder{\char95}order (A{\char95}:'a order) = {\char35}Orderings{\char95}{\char95}preorder{\char95}order A{\char95};\\
44.919 +\hspace*{0pt}\\
44.920 +\hspace*{0pt}fun less{\char95}eqa (A1{\char95},~A2{\char95}) B{\char95}~(x1,~y1) (x2,~y2) =\\
44.921 +\hspace*{0pt} ~less ((ord{\char95}preorder o preorder{\char95}order) A2{\char95}) x1 x2 orelse\\
44.922 +\hspace*{0pt} ~~~eqop A1{\char95}~x1 x2 andalso\\
44.923 +\hspace*{0pt} ~~~~~less{\char95}eq ((ord{\char95}preorder o preorder{\char95}order) B{\char95}) y1 y2\\
44.924 +\hspace*{0pt} ~| less{\char95}eqa (A1{\char95},~A2{\char95}) B{\char95}~(x1,~y1) (x2,~y2) =\\
44.925 +\hspace*{0pt} ~~~less ((ord{\char95}preorder o preorder{\char95}order) A2{\char95}) x1 x2 orelse\\
44.926 +\hspace*{0pt} ~~~~~eqop A1{\char95}~x1 x2 andalso\\
44.927 +\hspace*{0pt} ~~~~~~~less{\char95}eq ((ord{\char95}preorder o preorder{\char95}order) B{\char95}) y1 y2;\\
44.928 +\hspace*{0pt}\\
44.929 +\hspace*{0pt}end;~(*struct Example*)%
44.930 +\end{isamarkuptext}%
44.931 +\isamarkuptrue%
44.932 +%
44.933 +\endisatagquote
44.934 +{\isafoldquote}%
44.935 +%
44.936 +\isadelimquote
44.937 +%
44.938 +\endisadelimquote
44.939 +%
44.940 +\begin{isamarkuptext}%
44.941 +In some cases, the automatically derived code equations
44.942 + for equality on a particular type may not be appropriate.
44.943 + As example, watch the following datatype representing
44.944 + monomorphic parametric types (where type constructors
44.945 + are referred to by natural numbers):%
44.946 +\end{isamarkuptext}%
44.947 +\isamarkuptrue%
44.948 +%
44.949 +\isadelimquote
44.950 +%
44.951 +\endisadelimquote
44.952 +%
44.953 +\isatagquote
44.954 +\isacommand{datatype}\isamarkupfalse%
44.955 +\ monotype\ {\isacharequal}\ Mono\ nat\ {\isachardoublequoteopen}monotype\ list{\isachardoublequoteclose}%
44.956 +\endisatagquote
44.957 +{\isafoldquote}%
44.958 +%
44.959 +\isadelimquote
44.960 +%
44.961 +\endisadelimquote
44.962 +%
44.963 +\isadelimproof
44.964 +%
44.965 +\endisadelimproof
44.966 +%
44.967 +\isatagproof
44.968 +%
44.969 +\endisatagproof
44.970 +{\isafoldproof}%
44.971 +%
44.972 +\isadelimproof
44.973 +%
44.974 +\endisadelimproof
44.975 +%
44.976 +\begin{isamarkuptext}%
44.977 +\noindent Then code generation for SML would fail with a message
44.978 + that the generated code contains illegal mutual dependencies:
44.979 + the theorem \isa{eq{\isacharunderscore}class{\isachardot}eq\ {\isacharparenleft}Mono\ tyco{\isadigit{1}}\ typargs{\isadigit{1}}{\isacharparenright}\ {\isacharparenleft}Mono\ tyco{\isadigit{2}}\ typargs{\isadigit{2}}{\isacharparenright}\ {\isasymequiv}\ eq{\isacharunderscore}class{\isachardot}eq\ tyco{\isadigit{1}}\ tyco{\isadigit{2}}\ {\isasymand}\ eq{\isacharunderscore}class{\isachardot}eq\ typargs{\isadigit{1}}\ typargs{\isadigit{2}}} already requires the
44.980 + instance \isa{monotype\ {\isasymColon}\ eq}, which itself requires
44.981 + \isa{eq{\isacharunderscore}class{\isachardot}eq\ {\isacharparenleft}Mono\ tyco{\isadigit{1}}\ typargs{\isadigit{1}}{\isacharparenright}\ {\isacharparenleft}Mono\ tyco{\isadigit{2}}\ typargs{\isadigit{2}}{\isacharparenright}\ {\isasymequiv}\ eq{\isacharunderscore}class{\isachardot}eq\ tyco{\isadigit{1}}\ tyco{\isadigit{2}}\ {\isasymand}\ eq{\isacharunderscore}class{\isachardot}eq\ typargs{\isadigit{1}}\ typargs{\isadigit{2}}}; Haskell has no problem with mutually
44.982 + recursive \isa{instance} and \isa{function} definitions,
44.983 + but the SML serialiser does not support this.
44.984 +
44.985 + In such cases, you have to provide your own equality equations
44.986 + involving auxiliary constants. In our case,
44.987 + \isa{list{\isacharunderscore}all{\isadigit{2}}} can do the job:%
44.988 +\end{isamarkuptext}%
44.989 +\isamarkuptrue%
44.990 +%
44.991 +\isadelimquote
44.992 +%
44.993 +\endisadelimquote
44.994 +%
44.995 +\isatagquote
44.996 +\isacommand{lemma}\isamarkupfalse%
44.997 +\ monotype{\isacharunderscore}eq{\isacharunderscore}list{\isacharunderscore}all{\isadigit{2}}\ {\isacharbrackleft}code{\isacharbrackright}{\isacharcolon}\isanewline
44.998 +\ \ {\isachardoublequoteopen}eq{\isacharunderscore}class{\isachardot}eq\ {\isacharparenleft}Mono\ tyco{\isadigit{1}}\ typargs{\isadigit{1}}{\isacharparenright}\ {\isacharparenleft}Mono\ tyco{\isadigit{2}}\ typargs{\isadigit{2}}{\isacharparenright}\ {\isasymlongleftrightarrow}\isanewline
44.999 +\ \ \ \ \ eq{\isacharunderscore}class{\isachardot}eq\ tyco{\isadigit{1}}\ tyco{\isadigit{2}}\ {\isasymand}\ list{\isacharunderscore}all{\isadigit{2}}\ eq{\isacharunderscore}class{\isachardot}eq\ typargs{\isadigit{1}}\ typargs{\isadigit{2}}{\isachardoublequoteclose}\isanewline
44.1000 +\ \ \isacommand{by}\isamarkupfalse%
44.1001 +\ {\isacharparenleft}simp\ add{\isacharcolon}\ eq\ list{\isacharunderscore}all{\isadigit{2}}{\isacharunderscore}eq\ {\isacharbrackleft}symmetric{\isacharbrackright}{\isacharparenright}%
44.1002 +\endisatagquote
44.1003 +{\isafoldquote}%
44.1004 +%
44.1005 +\isadelimquote
44.1006 +%
44.1007 +\endisadelimquote
44.1008 +%
44.1009 +\begin{isamarkuptext}%
44.1010 +\noindent does not depend on instance \isa{monotype\ {\isasymColon}\ eq}:%
44.1011 +\end{isamarkuptext}%
44.1012 +\isamarkuptrue%
44.1013 +%
44.1014 +\isadelimquote
44.1015 +%
44.1016 +\endisadelimquote
44.1017 +%
44.1018 +\isatagquote
44.1019 +%
44.1020 +\begin{isamarkuptext}%
44.1021 +\isatypewriter%
44.1022 +\noindent%
44.1023 +\hspace*{0pt}structure Example = \\
44.1024 +\hspace*{0pt}struct\\
44.1025 +\hspace*{0pt}\\
44.1026 +\hspace*{0pt}datatype nat = Zero{\char95}nat | Suc of nat;\\
44.1027 +\hspace*{0pt}\\
44.1028 +\hspace*{0pt}fun null [] = true\\
44.1029 +\hspace*{0pt} ~| null (x ::~xs) = false;\\
44.1030 +\hspace*{0pt}\\
44.1031 +\hspace*{0pt}fun eq{\char95}nat (Suc a) Zero{\char95}nat = false\\
44.1032 +\hspace*{0pt} ~| eq{\char95}nat Zero{\char95}nat (Suc a) = false\\
44.1033 +\hspace*{0pt} ~| eq{\char95}nat (Suc nat) (Suc nat') = eq{\char95}nat nat nat'\\
44.1034 +\hspace*{0pt} ~| eq{\char95}nat Zero{\char95}nat Zero{\char95}nat = true;\\
44.1035 +\hspace*{0pt}\\
44.1036 +\hspace*{0pt}datatype monotype = Mono of nat * monotype list;\\
44.1037 +\hspace*{0pt}\\
44.1038 +\hspace*{0pt}fun list{\char95}all2 p (x ::~xs) (y ::~ys) = p x y andalso list{\char95}all2 p xs ys\\
44.1039 +\hspace*{0pt} ~| list{\char95}all2 p xs [] = null xs\\
44.1040 +\hspace*{0pt} ~| list{\char95}all2 p [] ys = null ys;\\
44.1041 +\hspace*{0pt}\\
44.1042 +\hspace*{0pt}fun eq{\char95}monotype (Mono (tyco1,~typargs1)) (Mono (tyco2,~typargs2)) =\\
44.1043 +\hspace*{0pt} ~eq{\char95}nat tyco1 tyco2 andalso list{\char95}all2 eq{\char95}monotype typargs1 typargs2;\\
44.1044 +\hspace*{0pt}\\
44.1045 +\hspace*{0pt}end;~(*struct Example*)%
44.1046 +\end{isamarkuptext}%
44.1047 +\isamarkuptrue%
44.1048 +%
44.1049 +\endisatagquote
44.1050 +{\isafoldquote}%
44.1051 +%
44.1052 +\isadelimquote
44.1053 +%
44.1054 +\endisadelimquote
44.1055 +%
44.1056 +\isamarkupsubsection{Explicit partiality%
44.1057 +}
44.1058 +\isamarkuptrue%
44.1059 +%
44.1060 +\begin{isamarkuptext}%
44.1061 +Partiality usually enters the game by partial patterns, as
44.1062 + in the following example, again for amortised queues:%
44.1063 +\end{isamarkuptext}%
44.1064 +\isamarkuptrue%
44.1065 +%
44.1066 +\isadelimquote
44.1067 +%
44.1068 +\endisadelimquote
44.1069 +%
44.1070 +\isatagquote
44.1071 +\isacommand{definition}\isamarkupfalse%
44.1072 +\ strict{\isacharunderscore}dequeue\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharprime}a\ queue\ {\isasymRightarrow}\ {\isacharprime}a\ {\isasymtimes}\ {\isacharprime}a\ queue{\isachardoublequoteclose}\ \isakeyword{where}\isanewline
44.1073 +\ \ {\isachardoublequoteopen}strict{\isacharunderscore}dequeue\ q\ {\isacharequal}\ {\isacharparenleft}case\ dequeue\ q\isanewline
44.1074 +\ \ \ \ of\ {\isacharparenleft}Some\ x{\isacharcomma}\ q{\isacharprime}{\isacharparenright}\ {\isasymRightarrow}\ {\isacharparenleft}x{\isacharcomma}\ q{\isacharprime}{\isacharparenright}{\isacharparenright}{\isachardoublequoteclose}\isanewline
44.1075 +\isanewline
44.1076 +\isacommand{lemma}\isamarkupfalse%
44.1077 +\ strict{\isacharunderscore}dequeue{\isacharunderscore}AQueue\ {\isacharbrackleft}code{\isacharbrackright}{\isacharcolon}\isanewline
44.1078 +\ \ {\isachardoublequoteopen}strict{\isacharunderscore}dequeue\ {\isacharparenleft}AQueue\ xs\ {\isacharparenleft}y\ {\isacharhash}\ ys{\isacharparenright}{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}y{\isacharcomma}\ AQueue\ xs\ ys{\isacharparenright}{\isachardoublequoteclose}\isanewline
44.1079 +\ \ {\isachardoublequoteopen}strict{\isacharunderscore}dequeue\ {\isacharparenleft}AQueue\ xs\ {\isacharbrackleft}{\isacharbrackright}{\isacharparenright}\ {\isacharequal}\isanewline
44.1080 +\ \ \ \ {\isacharparenleft}case\ rev\ xs\ of\ y\ {\isacharhash}\ ys\ {\isasymRightarrow}\ {\isacharparenleft}y{\isacharcomma}\ AQueue\ {\isacharbrackleft}{\isacharbrackright}\ ys{\isacharparenright}{\isacharparenright}{\isachardoublequoteclose}\isanewline
44.1081 +\ \ \isacommand{by}\isamarkupfalse%
44.1082 +\ {\isacharparenleft}simp{\isacharunderscore}all\ add{\isacharcolon}\ strict{\isacharunderscore}dequeue{\isacharunderscore}def\ dequeue{\isacharunderscore}AQueue\ split{\isacharcolon}\ list{\isachardot}splits{\isacharparenright}%
44.1083 +\endisatagquote
44.1084 +{\isafoldquote}%
44.1085 +%
44.1086 +\isadelimquote
44.1087 +%
44.1088 +\endisadelimquote
44.1089 +%
44.1090 +\begin{isamarkuptext}%
44.1091 +\noindent In the corresponding code, there is no equation
44.1092 + for the pattern \isa{AQueue\ {\isacharbrackleft}{\isacharbrackright}\ {\isacharbrackleft}{\isacharbrackright}}:%
44.1093 +\end{isamarkuptext}%
44.1094 +\isamarkuptrue%
44.1095 +%
44.1096 +\isadelimquote
44.1097 +%
44.1098 +\endisadelimquote
44.1099 +%
44.1100 +\isatagquote
44.1101 +%
44.1102 +\begin{isamarkuptext}%
44.1103 +\isatypewriter%
44.1104 +\noindent%
44.1105 +\hspace*{0pt}strict{\char95}dequeue ::~forall a.~Queue a -> (a,~Queue a);\\
44.1106 +\hspace*{0pt}strict{\char95}dequeue (AQueue xs []) =\\
44.1107 +\hspace*{0pt} ~let {\char123}\\
44.1108 +\hspace*{0pt} ~~~(y :~ys) = rev xs;\\
44.1109 +\hspace*{0pt} ~{\char125}~in (y,~AQueue [] ys);\\
44.1110 +\hspace*{0pt}strict{\char95}dequeue (AQueue xs (y :~ys)) = (y,~AQueue xs ys);%
44.1111 +\end{isamarkuptext}%
44.1112 +\isamarkuptrue%
44.1113 +%
44.1114 +\endisatagquote
44.1115 +{\isafoldquote}%
44.1116 +%
44.1117 +\isadelimquote
44.1118 +%
44.1119 +\endisadelimquote
44.1120 +%
44.1121 +\begin{isamarkuptext}%
44.1122 +\noindent In some cases it is desirable to have this
44.1123 + pseudo-\qt{partiality} more explicitly, e.g.~as follows:%
44.1124 +\end{isamarkuptext}%
44.1125 +\isamarkuptrue%
44.1126 +%
44.1127 +\isadelimquote
44.1128 +%
44.1129 +\endisadelimquote
44.1130 +%
44.1131 +\isatagquote
44.1132 +\isacommand{axiomatization}\isamarkupfalse%
44.1133 +\ empty{\isacharunderscore}queue\ {\isacharcolon}{\isacharcolon}\ {\isacharprime}a\isanewline
44.1134 +\isanewline
44.1135 +\isacommand{definition}\isamarkupfalse%
44.1136 +\ strict{\isacharunderscore}dequeue{\isacharprime}\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharprime}a\ queue\ {\isasymRightarrow}\ {\isacharprime}a\ {\isasymtimes}\ {\isacharprime}a\ queue{\isachardoublequoteclose}\ \isakeyword{where}\isanewline
44.1137 +\ \ {\isachardoublequoteopen}strict{\isacharunderscore}dequeue{\isacharprime}\ q\ {\isacharequal}\ {\isacharparenleft}case\ dequeue\ q\ of\ {\isacharparenleft}Some\ x{\isacharcomma}\ q{\isacharprime}{\isacharparenright}\ {\isasymRightarrow}\ {\isacharparenleft}x{\isacharcomma}\ q{\isacharprime}{\isacharparenright}\ {\isacharbar}\ {\isacharunderscore}\ {\isasymRightarrow}\ empty{\isacharunderscore}queue{\isacharparenright}{\isachardoublequoteclose}\isanewline
44.1138 +\isanewline
44.1139 +\isacommand{lemma}\isamarkupfalse%
44.1140 +\ strict{\isacharunderscore}dequeue{\isacharprime}{\isacharunderscore}AQueue\ {\isacharbrackleft}code{\isacharbrackright}{\isacharcolon}\isanewline
44.1141 +\ \ {\isachardoublequoteopen}strict{\isacharunderscore}dequeue{\isacharprime}\ {\isacharparenleft}AQueue\ xs\ {\isacharbrackleft}{\isacharbrackright}{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}if\ xs\ {\isacharequal}\ {\isacharbrackleft}{\isacharbrackright}\ then\ empty{\isacharunderscore}queue\isanewline
44.1142 +\ \ \ \ \ else\ strict{\isacharunderscore}dequeue{\isacharprime}\ {\isacharparenleft}AQueue\ {\isacharbrackleft}{\isacharbrackright}\ {\isacharparenleft}rev\ xs{\isacharparenright}{\isacharparenright}{\isacharparenright}{\isachardoublequoteclose}\isanewline
44.1143 +\ \ {\isachardoublequoteopen}strict{\isacharunderscore}dequeue{\isacharprime}\ {\isacharparenleft}AQueue\ xs\ {\isacharparenleft}y\ {\isacharhash}\ ys{\isacharparenright}{\isacharparenright}\ {\isacharequal}\isanewline
44.1144 +\ \ \ \ \ {\isacharparenleft}y{\isacharcomma}\ AQueue\ xs\ ys{\isacharparenright}{\isachardoublequoteclose}\isanewline
44.1145 +\ \ \isacommand{by}\isamarkupfalse%
44.1146 +\ {\isacharparenleft}simp{\isacharunderscore}all\ add{\isacharcolon}\ strict{\isacharunderscore}dequeue{\isacharprime}{\isacharunderscore}def\ dequeue{\isacharunderscore}AQueue\ split{\isacharcolon}\ list{\isachardot}splits{\isacharparenright}%
44.1147 +\endisatagquote
44.1148 +{\isafoldquote}%
44.1149 +%
44.1150 +\isadelimquote
44.1151 +%
44.1152 +\endisadelimquote
44.1153 +%
44.1154 +\begin{isamarkuptext}%
44.1155 +Observe that on the right hand side of the definition of \isa{strict{\isacharunderscore}dequeue{\isacharprime}} the constant \isa{empty{\isacharunderscore}queue} occurs
44.1156 + which is unspecified.
44.1157 +
44.1158 + Normally, if constants without any code equations occur in a
44.1159 + program, the code generator complains (since in most cases this is
44.1160 + not what the user expects). But such constants can also be thought
44.1161 + of as function definitions with no equations which always fail,
44.1162 + since there is never a successful pattern match on the left hand
44.1163 + side. In order to categorise a constant into that category
44.1164 + explicitly, use \hyperlink{command.code-abort}{\mbox{\isa{\isacommand{code{\isacharunderscore}abort}}}}:%
44.1165 +\end{isamarkuptext}%
44.1166 +\isamarkuptrue%
44.1167 +%
44.1168 +\isadelimquote
44.1169 +%
44.1170 +\endisadelimquote
44.1171 +%
44.1172 +\isatagquote
44.1173 +\isacommand{code{\isacharunderscore}abort}\isamarkupfalse%
44.1174 +\ empty{\isacharunderscore}queue%
44.1175 +\endisatagquote
44.1176 +{\isafoldquote}%
44.1177 +%
44.1178 +\isadelimquote
44.1179 +%
44.1180 +\endisadelimquote
44.1181 +%
44.1182 +\begin{isamarkuptext}%
44.1183 +\noindent Then the code generator will just insert an error or
44.1184 + exception at the appropriate position:%
44.1185 +\end{isamarkuptext}%
44.1186 +\isamarkuptrue%
44.1187 +%
44.1188 +\isadelimquote
44.1189 +%
44.1190 +\endisadelimquote
44.1191 +%
44.1192 +\isatagquote
44.1193 +%
44.1194 +\begin{isamarkuptext}%
44.1195 +\isatypewriter%
44.1196 +\noindent%
44.1197 +\hspace*{0pt}empty{\char95}queue ::~forall a.~a;\\
44.1198 +\hspace*{0pt}empty{\char95}queue = error {\char34}empty{\char95}queue{\char34};\\
44.1199 +\hspace*{0pt}\\
44.1200 +\hspace*{0pt}strict{\char95}dequeue' ::~forall a.~Queue a -> (a,~Queue a);\\
44.1201 +\hspace*{0pt}strict{\char95}dequeue' (AQueue xs (y :~ys)) = (y,~AQueue xs ys);\\
44.1202 +\hspace*{0pt}strict{\char95}dequeue' (AQueue xs []) =\\
44.1203 +\hspace*{0pt} ~(if nulla xs then empty{\char95}queue\\
44.1204 +\hspace*{0pt} ~~~else strict{\char95}dequeue' (AQueue [] (rev xs)));%
44.1205 +\end{isamarkuptext}%
44.1206 +\isamarkuptrue%
44.1207 +%
44.1208 +\endisatagquote
44.1209 +{\isafoldquote}%
44.1210 +%
44.1211 +\isadelimquote
44.1212 +%
44.1213 +\endisadelimquote
44.1214 +%
44.1215 +\begin{isamarkuptext}%
44.1216 +\noindent This feature however is rarely needed in practice.
44.1217 + Note also that the \isa{HOL} default setup already declares
44.1218 + \isa{undefined} as \hyperlink{command.code-abort}{\mbox{\isa{\isacommand{code{\isacharunderscore}abort}}}}, which is most
44.1219 + likely to be used in such situations.%
44.1220 +\end{isamarkuptext}%
44.1221 +\isamarkuptrue%
44.1222 +%
44.1223 +\isadelimtheory
44.1224 +%
44.1225 +\endisadelimtheory
44.1226 +%
44.1227 +\isatagtheory
44.1228 +\isacommand{end}\isamarkupfalse%
44.1229 +%
44.1230 +\endisatagtheory
44.1231 +{\isafoldtheory}%
44.1232 +%
44.1233 +\isadelimtheory
44.1234 +%
44.1235 +\endisadelimtheory
44.1236 +\isanewline
44.1237 +\ \end{isabellebody}%
44.1238 +%%% Local Variables:
44.1239 +%%% mode: latex
44.1240 +%%% TeX-master: "root"
44.1241 +%%% End:
45.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
45.2 +++ b/doc-src/Codegen/Thy/examples/Codegen.hs Wed Mar 04 11:05:29 2009 +0100
45.3 @@ -0,0 +1,23 @@
45.4 +module Codegen where {
45.5 +
45.6 +import qualified Nat;
45.7 +
45.8 +class Null a where {
45.9 + nulla :: a;
45.10 +};
45.11 +
45.12 +heada :: forall a. (Codegen.Null a) => [a] -> a;
45.13 +heada (x : xs) = x;
45.14 +heada [] = Codegen.nulla;
45.15 +
45.16 +null_option :: forall a. Maybe a;
45.17 +null_option = Nothing;
45.18 +
45.19 +instance Codegen.Null (Maybe a) where {
45.20 + nulla = Codegen.null_option;
45.21 +};
45.22 +
45.23 +dummy :: Maybe Nat.Nat;
45.24 +dummy = Codegen.heada [Just (Nat.Suc Nat.Zero_nat), Nothing];
45.25 +
45.26 +}
46.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
46.2 +++ b/doc-src/Codegen/Thy/examples/Example.hs Wed Mar 04 11:05:29 2009 +0100
46.3 @@ -0,0 +1,33 @@
46.4 +{-# OPTIONS_GHC -fglasgow-exts #-}
46.5 +
46.6 +module Example where {
46.7 +
46.8 +
46.9 +foldla :: forall a b. (a -> b -> a) -> a -> [b] -> a;
46.10 +foldla f a [] = a;
46.11 +foldla f a (x : xs) = foldla f (f a x) xs;
46.12 +
46.13 +rev :: forall a. [a] -> [a];
46.14 +rev xs = foldla (\ xsa x -> x : xsa) [] xs;
46.15 +
46.16 +list_case :: forall t a. t -> (a -> [a] -> t) -> [a] -> t;
46.17 +list_case f1 f2 (a : list) = f2 a list;
46.18 +list_case f1 f2 [] = f1;
46.19 +
46.20 +data Queue a = AQueue [a] [a];
46.21 +
46.22 +empty :: forall a. Queue a;
46.23 +empty = AQueue [] [];
46.24 +
46.25 +dequeue :: forall a. Queue a -> (Maybe a, Queue a);
46.26 +dequeue (AQueue [] []) = (Nothing, AQueue [] []);
46.27 +dequeue (AQueue xs (y : ys)) = (Just y, AQueue xs ys);
46.28 +dequeue (AQueue (v : va) []) =
46.29 + let {
46.30 + (y : ys) = rev (v : va);
46.31 + } in (Just y, AQueue [] ys);
46.32 +
46.33 +enqueue :: forall a. a -> Queue a -> Queue a;
46.34 +enqueue x (AQueue xs ys) = AQueue (x : xs) ys;
46.35 +
46.36 +}
47.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
47.2 +++ b/doc-src/Codegen/Thy/examples/arbitrary.ML Wed Mar 04 11:05:29 2009 +0100
47.3 @@ -0,0 +1,9 @@
47.4 +structure Codegen =
47.5 +struct
47.6 +
47.7 +val arbitrary_option : 'a option = NONE;
47.8 +
47.9 +fun dummy_option [] = arbitrary_option
47.10 + | dummy_option (x :: xs) = SOME x;
47.11 +
47.12 +end; (*struct Codegen*)
48.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
48.2 +++ b/doc-src/Codegen/Thy/examples/bool_infix.ML Wed Mar 04 11:05:29 2009 +0100
48.3 @@ -0,0 +1,19 @@
48.4 +structure Nat =
48.5 +struct
48.6 +
48.7 +datatype nat = Suc of nat | Zero_nat;
48.8 +
48.9 +fun less_nat m (Suc n) = less_eq_nat m n
48.10 + | less_nat n Zero_nat = false
48.11 +and less_eq_nat (Suc m) n = less_nat m n
48.12 + | less_eq_nat Zero_nat n = true;
48.13 +
48.14 +end; (*struct Nat*)
48.15 +
48.16 +structure Codegen =
48.17 +struct
48.18 +
48.19 +fun in_interval (k, l) n =
48.20 + Nat.less_eq_nat k n andalso Nat.less_eq_nat n l;
48.21 +
48.22 +end; (*struct Codegen*)
49.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
49.2 +++ b/doc-src/Codegen/Thy/examples/bool_literal.ML Wed Mar 04 11:05:29 2009 +0100
49.3 @@ -0,0 +1,31 @@
49.4 +structure HOL =
49.5 +struct
49.6 +
49.7 +datatype boola = False | True;
49.8 +
49.9 +fun anda x True = x
49.10 + | anda x False = False
49.11 + | anda True x = x
49.12 + | anda False x = False;
49.13 +
49.14 +end; (*struct HOL*)
49.15 +
49.16 +structure Nat =
49.17 +struct
49.18 +
49.19 +datatype nat = Suc of nat | Zero_nat;
49.20 +
49.21 +fun less_nat m (Suc n) = less_eq_nat m n
49.22 + | less_nat n Zero_nat = HOL.False
49.23 +and less_eq_nat (Suc m) n = less_nat m n
49.24 + | less_eq_nat Zero_nat n = HOL.True;
49.25 +
49.26 +end; (*struct Nat*)
49.27 +
49.28 +structure Codegen =
49.29 +struct
49.30 +
49.31 +fun in_interval (k, l) n =
49.32 + HOL.anda (Nat.less_eq_nat k n) (Nat.less_eq_nat n l);
49.33 +
49.34 +end; (*struct Codegen*)
50.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
50.2 +++ b/doc-src/Codegen/Thy/examples/bool_mlbool.ML Wed Mar 04 11:05:29 2009 +0100
50.3 @@ -0,0 +1,19 @@
50.4 +structure Nat =
50.5 +struct
50.6 +
50.7 +datatype nat = Suc of nat | Zero_nat;
50.8 +
50.9 +fun less_nat m (Suc n) = less_eq_nat m n
50.10 + | less_nat n Zero_nat = false
50.11 +and less_eq_nat (Suc m) n = less_nat m n
50.12 + | less_eq_nat Zero_nat n = true;
50.13 +
50.14 +end; (*struct Nat*)
50.15 +
50.16 +structure Codegen =
50.17 +struct
50.18 +
50.19 +fun in_interval (k, l) n =
50.20 + (Nat.less_eq_nat k n) andalso (Nat.less_eq_nat n l);
50.21 +
50.22 +end; (*struct Codegen*)
51.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
51.2 +++ b/doc-src/Codegen/Thy/examples/class.ML Wed Mar 04 11:05:29 2009 +0100
51.3 @@ -0,0 +1,24 @@
51.4 +structure Nat =
51.5 +struct
51.6 +
51.7 +datatype nat = Suc of nat | Zero_nat;
51.8 +
51.9 +end; (*struct Nat*)
51.10 +
51.11 +structure Codegen =
51.12 +struct
51.13 +
51.14 +type 'a null = {null : 'a};
51.15 +fun null (A_:'a null) = #null A_;
51.16 +
51.17 +fun head A_ (x :: xs) = x
51.18 + | head A_ [] = null A_;
51.19 +
51.20 +val null_option : 'a option = NONE;
51.21 +
51.22 +fun null_optiona () = {null = null_option} : ('a option) null;
51.23 +
51.24 +val dummy : Nat.nat option =
51.25 + head (null_optiona ()) [SOME (Nat.Suc Nat.Zero_nat), NONE];
51.26 +
51.27 +end; (*struct Codegen*)
52.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
52.2 +++ b/doc-src/Codegen/Thy/examples/class.ocaml Wed Mar 04 11:05:29 2009 +0100
52.3 @@ -0,0 +1,24 @@
52.4 +module Nat =
52.5 +struct
52.6 +
52.7 +type nat = Suc of nat | Zero_nat;;
52.8 +
52.9 +end;; (*struct Nat*)
52.10 +
52.11 +module Codegen =
52.12 +struct
52.13 +
52.14 +type 'a null = {null : 'a};;
52.15 +let null _A = _A.null;;
52.16 +
52.17 +let rec head _A = function x :: xs -> x
52.18 + | [] -> null _A;;
52.19 +
52.20 +let rec null_option = None;;
52.21 +
52.22 +let null_optiona () = ({null = null_option} : ('a option) null);;
52.23 +
52.24 +let rec dummy
52.25 + = head (null_optiona ()) [Some (Nat.Suc Nat.Zero_nat); None];;
52.26 +
52.27 +end;; (*struct Codegen*)
53.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
53.2 +++ b/doc-src/Codegen/Thy/examples/collect_duplicates.ML Wed Mar 04 11:05:29 2009 +0100
53.3 @@ -0,0 +1,30 @@
53.4 +structure HOL =
53.5 +struct
53.6 +
53.7 +type 'a eq = {eq : 'a -> 'a -> bool};
53.8 +fun eq (A_:'a eq) = #eq A_;
53.9 +
53.10 +fun eqop A_ a = eq A_ a;
53.11 +
53.12 +end; (*struct HOL*)
53.13 +
53.14 +structure List =
53.15 +struct
53.16 +
53.17 +fun member A_ x (y :: ys) =
53.18 + (if HOL.eqop A_ y x then true else member A_ x ys)
53.19 + | member A_ x [] = false;
53.20 +
53.21 +end; (*struct List*)
53.22 +
53.23 +structure Codegen =
53.24 +struct
53.25 +
53.26 +fun collect_duplicates A_ xs ys (z :: zs) =
53.27 + (if List.member A_ z xs
53.28 + then (if List.member A_ z ys then collect_duplicates A_ xs ys zs
53.29 + else collect_duplicates A_ xs (z :: ys) zs)
53.30 + else collect_duplicates A_ (z :: xs) (z :: ys) zs)
53.31 + | collect_duplicates A_ xs ys [] = xs;
53.32 +
53.33 +end; (*struct Codegen*)
54.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
54.2 +++ b/doc-src/Codegen/Thy/examples/dirty_set.ML Wed Mar 04 11:05:29 2009 +0100
54.3 @@ -0,0 +1,102 @@
54.4 +structure ROOT =
54.5 +struct
54.6 +
54.7 +structure Nat =
54.8 +struct
54.9 +
54.10 +datatype nat = Zero_nat | Suc of nat;
54.11 +
54.12 +end; (*struct Nat*)
54.13 +
54.14 +structure Integer =
54.15 +struct
54.16 +
54.17 +datatype bit = B0 | B1;
54.18 +
54.19 +datatype int = Pls | Min | Bit of int * bit | Number_of_int of int;
54.20 +
54.21 +fun pred (Bit (k, B0)) = Bit (pred k, B1)
54.22 + | pred (Bit (k, B1)) = Bit (k, B0)
54.23 + | pred Min = Bit (Min, B0)
54.24 + | pred Pls = Min;
54.25 +
54.26 +fun uminus_int (Number_of_int w) = Number_of_int (uminus_int w)
54.27 + | uminus_int (Bit (k, B0)) = Bit (uminus_int k, B0)
54.28 + | uminus_int (Bit (k, B1)) = Bit (pred (uminus_int k), B1)
54.29 + | uminus_int Min = Bit (Pls, B1)
54.30 + | uminus_int Pls = Pls;
54.31 +
54.32 +fun succ (Bit (k, B0)) = Bit (k, B1)
54.33 + | succ (Bit (k, B1)) = Bit (succ k, B0)
54.34 + | succ Min = Pls
54.35 + | succ Pls = Bit (Pls, B1);
54.36 +
54.37 +fun plus_int (Number_of_int v) (Number_of_int w) =
54.38 + Number_of_int (plus_int v w)
54.39 + | plus_int k Min = pred k
54.40 + | plus_int k Pls = k
54.41 + | plus_int (Bit (k, B1)) (Bit (l, B1)) = Bit (plus_int k (succ l), B0)
54.42 + | plus_int (Bit (k, B1)) (Bit (l, B0)) = Bit (plus_int k l, B1)
54.43 + | plus_int (Bit (k, B0)) (Bit (l, b)) = Bit (plus_int k l, b)
54.44 + | plus_int Min k = pred k
54.45 + | plus_int Pls k = k;
54.46 +
54.47 +fun minus_int (Number_of_int v) (Number_of_int w) =
54.48 + Number_of_int (plus_int v (uminus_int w))
54.49 + | minus_int z w = plus_int z (uminus_int w);
54.50 +
54.51 +fun less_eq_int (Number_of_int k) (Number_of_int l) = less_eq_int k l
54.52 + | less_eq_int (Bit (k1, B1)) (Bit (k2, B0)) = less_int k1 k2
54.53 + | less_eq_int (Bit (k1, v)) (Bit (k2, B1)) = less_eq_int k1 k2
54.54 + | less_eq_int (Bit (k1, B0)) (Bit (k2, v)) = less_eq_int k1 k2
54.55 + | less_eq_int (Bit (k, v)) Min = less_eq_int k Min
54.56 + | less_eq_int (Bit (k, B1)) Pls = less_int k Pls
54.57 + | less_eq_int (Bit (k, B0)) Pls = less_eq_int k Pls
54.58 + | less_eq_int Min (Bit (k, B1)) = less_eq_int Min k
54.59 + | less_eq_int Min (Bit (k, B0)) = less_int Min k
54.60 + | less_eq_int Min Min = true
54.61 + | less_eq_int Min Pls = true
54.62 + | less_eq_int Pls (Bit (k, v)) = less_eq_int Pls k
54.63 + | less_eq_int Pls Min = false
54.64 + | less_eq_int Pls Pls = true
54.65 +and less_int (Number_of_int k) (Number_of_int l) = less_int k l
54.66 + | less_int (Bit (k1, B0)) (Bit (k2, B1)) = less_eq_int k1 k2
54.67 + | less_int (Bit (k1, B1)) (Bit (k2, v)) = less_int k1 k2
54.68 + | less_int (Bit (k1, v)) (Bit (k2, B0)) = less_int k1 k2
54.69 + | less_int (Bit (k, B1)) Min = less_int k Min
54.70 + | less_int (Bit (k, B0)) Min = less_eq_int k Min
54.71 + | less_int (Bit (k, v)) Pls = less_int k Pls
54.72 + | less_int Min (Bit (k, v)) = less_int Min k
54.73 + | less_int Min Min = false
54.74 + | less_int Min Pls = true
54.75 + | less_int Pls (Bit (k, B1)) = less_eq_int Pls k
54.76 + | less_int Pls (Bit (k, B0)) = less_int Pls k
54.77 + | less_int Pls Min = false
54.78 + | less_int Pls Pls = false;
54.79 +
54.80 +fun nat_aux n i =
54.81 + (if less_eq_int i (Number_of_int Pls) then n
54.82 + else nat_aux (Nat.Suc n)
54.83 + (minus_int i (Number_of_int (Bit (Pls, B1)))));
54.84 +
54.85 +fun nat i = nat_aux Nat.Zero_nat i;
54.86 +
54.87 +end; (*struct Integer*)
54.88 +
54.89 +structure Codegen =
54.90 +struct
54.91 +
54.92 +val dummy_set : (Nat.nat -> Nat.nat) list = Nat.Suc :: [];
54.93 +
54.94 +val foobar_set : Nat.nat list =
54.95 + Nat.Zero_nat ::
54.96 + (Nat.Suc Nat.Zero_nat ::
54.97 + (Integer.nat
54.98 + (Integer.Number_of_int
54.99 + (Integer.Bit
54.100 + (Integer.Bit (Integer.Pls, Integer.B1), Integer.B0)))
54.101 + :: []));
54.102 +
54.103 +end; (*struct Codegen*)
54.104 +
54.105 +end; (*struct ROOT*)
55.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
55.2 +++ b/doc-src/Codegen/Thy/examples/example.ML Wed Mar 04 11:05:29 2009 +0100
55.3 @@ -0,0 +1,27 @@
55.4 +structure Example =
55.5 +struct
55.6 +
55.7 +fun foldl f a [] = a
55.8 + | foldl f a (x :: xs) = foldl f (f a x) xs;
55.9 +
55.10 +fun rev xs = foldl (fn xsa => fn x => x :: xsa) [] xs;
55.11 +
55.12 +fun list_case f1 f2 (a :: lista) = f2 a lista
55.13 + | list_case f1 f2 [] = f1;
55.14 +
55.15 +datatype 'a queue = AQueue of 'a list * 'a list;
55.16 +
55.17 +val empty : 'a queue = AQueue ([], [])
55.18 +
55.19 +fun dequeue (AQueue ([], [])) = (NONE, AQueue ([], []))
55.20 + | dequeue (AQueue (xs, y :: ys)) = (SOME y, AQueue (xs, ys))
55.21 + | dequeue (AQueue (v :: va, [])) =
55.22 + let
55.23 + val y :: ys = rev (v :: va);
55.24 + in
55.25 + (SOME y, AQueue ([], ys))
55.26 + end;
55.27 +
55.28 +fun enqueue x (AQueue (xs, ys)) = AQueue (x :: xs, ys);
55.29 +
55.30 +end; (*struct Example*)
56.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
56.2 +++ b/doc-src/Codegen/Thy/examples/fac.ML Wed Mar 04 11:05:29 2009 +0100
56.3 @@ -0,0 +1,22 @@
56.4 +structure Nat =
56.5 +struct
56.6 +
56.7 +datatype nat = Suc of nat | Zero_nat;
56.8 +
56.9 +val one_nat : nat = Suc Zero_nat;
56.10 +
56.11 +fun plus_nat (Suc m) n = plus_nat m (Suc n)
56.12 + | plus_nat Zero_nat n = n;
56.13 +
56.14 +fun times_nat (Suc m) n = plus_nat n (times_nat m n)
56.15 + | times_nat Zero_nat n = Zero_nat;
56.16 +
56.17 +end; (*struct Nat*)
56.18 +
56.19 +structure Codegen =
56.20 +struct
56.21 +
56.22 +fun fac (Nat.Suc n) = Nat.times_nat (Nat.Suc n) (fac n)
56.23 + | fac Nat.Zero_nat = Nat.one_nat;
56.24 +
56.25 +end; (*struct Codegen*)
57.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
57.2 +++ b/doc-src/Codegen/Thy/examples/integers.ML Wed Mar 04 11:05:29 2009 +0100
57.3 @@ -0,0 +1,59 @@
57.4 +structure ROOT =
57.5 +struct
57.6 +
57.7 +structure Integer =
57.8 +struct
57.9 +
57.10 +datatype bit = B0 | B1;
57.11 +
57.12 +datatype int = Pls | Min | Bit of int * bit | Number_of_int of int;
57.13 +
57.14 +fun pred (Bit (k, B0)) = Bit (pred k, B1)
57.15 + | pred (Bit (k, B1)) = Bit (k, B0)
57.16 + | pred Min = Bit (Min, B0)
57.17 + | pred Pls = Min;
57.18 +
57.19 +fun succ (Bit (k, B0)) = Bit (k, B1)
57.20 + | succ (Bit (k, B1)) = Bit (succ k, B0)
57.21 + | succ Min = Pls
57.22 + | succ Pls = Bit (Pls, B1);
57.23 +
57.24 +fun plus_int (Number_of_int v) (Number_of_int w) =
57.25 + Number_of_int (plus_int v w)
57.26 + | plus_int k Min = pred k
57.27 + | plus_int k Pls = k
57.28 + | plus_int (Bit (k, B1)) (Bit (l, B1)) = Bit (plus_int k (succ l), B0)
57.29 + | plus_int (Bit (k, B1)) (Bit (l, B0)) = Bit (plus_int k l, B1)
57.30 + | plus_int (Bit (k, B0)) (Bit (l, b)) = Bit (plus_int k l, b)
57.31 + | plus_int Min k = pred k
57.32 + | plus_int Pls k = k;
57.33 +
57.34 +fun uminus_int (Number_of_int w) = Number_of_int (uminus_int w)
57.35 + | uminus_int (Bit (k, B0)) = Bit (uminus_int k, B0)
57.36 + | uminus_int (Bit (k, B1)) = Bit (pred (uminus_int k), B1)
57.37 + | uminus_int Min = Bit (Pls, B1)
57.38 + | uminus_int Pls = Pls;
57.39 +
57.40 +fun times_int (Number_of_int v) (Number_of_int w) =
57.41 + Number_of_int (times_int v w)
57.42 + | times_int (Bit (k, B0)) l = Bit (times_int k l, B0)
57.43 + | times_int (Bit (k, B1)) l = plus_int (Bit (times_int k l, B0)) l
57.44 + | times_int Min k = uminus_int k
57.45 + | times_int Pls w = Pls;
57.46 +
57.47 +end; (*struct Integer*)
57.48 +
57.49 +structure Codegen =
57.50 +struct
57.51 +
57.52 +fun double_inc k =
57.53 + Integer.plus_int
57.54 + (Integer.times_int
57.55 + (Integer.Number_of_int
57.56 + (Integer.Bit (Integer.Bit (Integer.Pls, Integer.B1), Integer.B0)))
57.57 + k)
57.58 + (Integer.Number_of_int (Integer.Bit (Integer.Pls, Integer.B1)));
57.59 +
57.60 +end; (*struct Codegen*)
57.61 +
57.62 +end; (*struct ROOT*)
58.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
58.2 +++ b/doc-src/Codegen/Thy/examples/lexicographic.ML Wed Mar 04 11:05:29 2009 +0100
58.3 @@ -0,0 +1,19 @@
58.4 +structure HOL =
58.5 +struct
58.6 +
58.7 +type 'a eq = {eq : 'a -> 'a -> bool};
58.8 +fun eq (A_:'a eq) = #eq A_;
58.9 +
58.10 +type 'a ord = {less_eq : 'a -> 'a -> bool, less : 'a -> 'a -> bool};
58.11 +fun less_eq (A_:'a ord) = #less_eq A_;
58.12 +fun less (A_:'a ord) = #less A_;
58.13 +
58.14 +end; (*struct HOL*)
58.15 +
58.16 +structure Codegen =
58.17 +struct
58.18 +
58.19 +fun less_eq (A1_, A2_) B_ (x1, y1) (x2, y2) =
58.20 + HOL.less A2_ x1 x2 orelse HOL.eq A1_ x1 x2 andalso HOL.less_eq B_ y1 y2;
58.21 +
58.22 +end; (*struct Codegen*)
59.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
59.2 +++ b/doc-src/Codegen/Thy/examples/lookup.ML Wed Mar 04 11:05:29 2009 +0100
59.3 @@ -0,0 +1,13 @@
59.4 +structure ROOT =
59.5 +struct
59.6 +
59.7 +structure Codegen =
59.8 +struct
59.9 +
59.10 +fun lookup ((k, v) :: xs) l =
59.11 + (if ((k : string) = l) then SOME v else lookup xs l)
59.12 + | lookup [] l = NONE;
59.13 +
59.14 +end; (*struct Codegen*)
59.15 +
59.16 +end; (*struct ROOT*)
60.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
60.2 +++ b/doc-src/Codegen/Thy/examples/monotype.ML Wed Mar 04 11:05:29 2009 +0100
60.3 @@ -0,0 +1,34 @@
60.4 +structure Nat =
60.5 +struct
60.6 +
60.7 +datatype nat = Suc of nat | Zero_nat;
60.8 +
60.9 +fun eq_nat (Suc a) Zero_nat = false
60.10 + | eq_nat Zero_nat (Suc a) = false
60.11 + | eq_nat (Suc nat) (Suc nat') = eq_nat nat nat'
60.12 + | eq_nat Zero_nat Zero_nat = true;
60.13 +
60.14 +end; (*struct Nat*)
60.15 +
60.16 +structure List =
60.17 +struct
60.18 +
60.19 +fun null (x :: xs) = false
60.20 + | null [] = true;
60.21 +
60.22 +fun list_all2 p (x :: xs) (y :: ys) = p x y andalso list_all2 p xs ys
60.23 + | list_all2 p xs [] = null xs
60.24 + | list_all2 p [] ys = null ys;
60.25 +
60.26 +end; (*struct List*)
60.27 +
60.28 +structure Codegen =
60.29 +struct
60.30 +
60.31 +datatype monotype = Mono of Nat.nat * monotype list;
60.32 +
60.33 +fun eq_monotype (Mono (tyco1, typargs1)) (Mono (tyco2, typargs2)) =
60.34 + Nat.eq_nat tyco1 tyco2 andalso
60.35 + List.list_all2 eq_monotype typargs1 typargs2;
60.36 +
60.37 +end; (*struct Codegen*)
61.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
61.2 +++ b/doc-src/Codegen/Thy/examples/nat_binary.ML Wed Mar 04 11:05:29 2009 +0100
61.3 @@ -0,0 +1,17 @@
61.4 +structure Nat =
61.5 +struct
61.6 +
61.7 +datatype nat = Dig1 of nat | Dig0 of nat | One_nat | Zero_nat;
61.8 +
61.9 +fun plus_nat (Dig1 m) (Dig1 n) = Dig0 (plus_nat (plus_nat m n) One_nat)
61.10 + | plus_nat (Dig1 m) (Dig0 n) = Dig1 (plus_nat m n)
61.11 + | plus_nat (Dig0 m) (Dig1 n) = Dig1 (plus_nat m n)
61.12 + | plus_nat (Dig0 m) (Dig0 n) = Dig0 (plus_nat m n)
61.13 + | plus_nat (Dig1 m) One_nat = Dig0 (plus_nat m One_nat)
61.14 + | plus_nat One_nat (Dig1 n) = Dig0 (plus_nat n One_nat)
61.15 + | plus_nat (Dig0 m) One_nat = Dig1 m
61.16 + | plus_nat One_nat (Dig0 n) = Dig1 n
61.17 + | plus_nat m Zero_nat = m
61.18 + | plus_nat Zero_nat n = n;
61.19 +
61.20 +end; (*struct Nat*)
62.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
62.2 +++ b/doc-src/Codegen/Thy/examples/pick1.ML Wed Mar 04 11:05:29 2009 +0100
62.3 @@ -0,0 +1,44 @@
62.4 +structure HOL =
62.5 +struct
62.6 +
62.7 +fun leta s f = f s;
62.8 +
62.9 +end; (*struct HOL*)
62.10 +
62.11 +structure Nat =
62.12 +struct
62.13 +
62.14 +datatype nat = Suc of nat | Zero_nat;
62.15 +
62.16 +fun less_nat m (Suc n) = less_eq_nat m n
62.17 + | less_nat n Zero_nat = false
62.18 +and less_eq_nat (Suc m) n = less_nat m n
62.19 + | less_eq_nat Zero_nat n = true;
62.20 +
62.21 +fun minus_nat (Suc m) (Suc n) = minus_nat m n
62.22 + | minus_nat Zero_nat n = Zero_nat
62.23 + | minus_nat m Zero_nat = m;
62.24 +
62.25 +end; (*struct Nat*)
62.26 +
62.27 +structure Product_Type =
62.28 +struct
62.29 +
62.30 +fun split f (a, b) = f a b;
62.31 +
62.32 +end; (*struct Product_Type*)
62.33 +
62.34 +structure Codegen =
62.35 +struct
62.36 +
62.37 +fun pick ((k, v) :: xs) n =
62.38 + (if Nat.less_nat n k then v else pick xs (Nat.minus_nat n k))
62.39 + | pick (x :: xs) n =
62.40 + let
62.41 + val a = x;
62.42 + val (k, v) = a;
62.43 + in
62.44 + (if Nat.less_nat n k then v else pick xs (Nat.minus_nat n k))
62.45 + end;
62.46 +
62.47 +end; (*struct Codegen*)
63.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
63.2 +++ b/doc-src/Codegen/Thy/examples/tree.ML Wed Mar 04 11:05:29 2009 +0100
63.3 @@ -0,0 +1,95 @@
63.4 +structure HOL =
63.5 +struct
63.6 +
63.7 +type 'a eq = {eq : 'a -> 'a -> bool};
63.8 +fun eq (A_:'a eq) = #eq A_;
63.9 +
63.10 +type 'a ord = {less_eq : 'a -> 'a -> bool, less : 'a -> 'a -> bool};
63.11 +fun less_eq (A_:'a ord) = #less_eq A_;
63.12 +fun less (A_:'a ord) = #less A_;
63.13 +
63.14 +fun eqop A_ a = eq A_ a;
63.15 +
63.16 +end; (*struct HOL*)
63.17 +
63.18 +structure Orderings =
63.19 +struct
63.20 +
63.21 +type 'a preorder = {Orderings__ord_preorder : 'a HOL.ord};
63.22 +fun ord_preorder (A_:'a preorder) = #Orderings__ord_preorder A_;
63.23 +
63.24 +type 'a order = {Orderings__preorder_order : 'a preorder};
63.25 +fun preorder_order (A_:'a order) = #Orderings__preorder_order A_;
63.26 +
63.27 +type 'a linorder = {Orderings__order_linorder : 'a order};
63.28 +fun order_linorder (A_:'a linorder) = #Orderings__order_linorder A_;
63.29 +
63.30 +end; (*struct Orderings*)
63.31 +
63.32 +structure Nat =
63.33 +struct
63.34 +
63.35 +datatype nat = Suc of nat | Zero_nat;
63.36 +
63.37 +fun eq_nat (Suc a) Zero_nat = false
63.38 + | eq_nat Zero_nat (Suc a) = false
63.39 + | eq_nat (Suc nat) (Suc nat') = eq_nat nat nat'
63.40 + | eq_nat Zero_nat Zero_nat = true;
63.41 +
63.42 +val eq_nata = {eq = eq_nat} : nat HOL.eq;
63.43 +
63.44 +fun less_nat m (Suc n) = less_eq_nat m n
63.45 + | less_nat n Zero_nat = false
63.46 +and less_eq_nat (Suc m) n = less_nat m n
63.47 + | less_eq_nat Zero_nat n = true;
63.48 +
63.49 +val ord_nat = {less_eq = less_eq_nat, less = less_nat} : nat HOL.ord;
63.50 +
63.51 +val preorder_nat = {Orderings__ord_preorder = ord_nat} :
63.52 + nat Orderings.preorder;
63.53 +
63.54 +val order_nat = {Orderings__preorder_order = preorder_nat} :
63.55 + nat Orderings.order;
63.56 +
63.57 +val linorder_nat = {Orderings__order_linorder = order_nat} :
63.58 + nat Orderings.linorder;
63.59 +
63.60 +end; (*struct Nat*)
63.61 +
63.62 +structure Codegen =
63.63 +struct
63.64 +
63.65 +datatype ('a, 'b) searchtree =
63.66 + Branch of ('a, 'b) searchtree * 'a * ('a, 'b) searchtree |
63.67 + Leaf of 'a * 'b;
63.68 +
63.69 +fun update (A1_, A2_) (it, entry) (Leaf (key, vala)) =
63.70 + (if HOL.eqop A1_ it key then Leaf (key, entry)
63.71 + else (if HOL.less_eq
63.72 + ((Orderings.ord_preorder o Orderings.preorder_order o
63.73 + Orderings.order_linorder)
63.74 + A2_)
63.75 + it key
63.76 + then Branch (Leaf (it, entry), it, Leaf (key, vala))
63.77 + else Branch (Leaf (key, vala), it, Leaf (it, entry))))
63.78 + | update (A1_, A2_) (it, entry) (Branch (t1, key, t2)) =
63.79 + (if HOL.less_eq
63.80 + ((Orderings.ord_preorder o Orderings.preorder_order o
63.81 + Orderings.order_linorder)
63.82 + A2_)
63.83 + it key
63.84 + then Branch (update (A1_, A2_) (it, entry) t1, key, t2)
63.85 + else Branch (t1, key, update (A1_, A2_) (it, entry) t2));
63.86 +
63.87 +val example : (Nat.nat, (Nat.nat list)) searchtree =
63.88 + update (Nat.eq_nata, Nat.linorder_nat)
63.89 + (Nat.Suc (Nat.Suc (Nat.Suc (Nat.Suc Nat.Zero_nat))),
63.90 + [Nat.Suc (Nat.Suc Nat.Zero_nat), Nat.Suc (Nat.Suc Nat.Zero_nat)])
63.91 + (update (Nat.eq_nata, Nat.linorder_nat)
63.92 + (Nat.Suc (Nat.Suc (Nat.Suc Nat.Zero_nat)),
63.93 + [Nat.Suc (Nat.Suc (Nat.Suc Nat.Zero_nat))])
63.94 + (update (Nat.eq_nata, Nat.linorder_nat)
63.95 + (Nat.Suc (Nat.Suc Nat.Zero_nat), [Nat.Suc (Nat.Suc Nat.Zero_nat)])
63.96 + (Leaf (Nat.Suc Nat.Zero_nat, []))));
63.97 +
63.98 +end; (*struct Codegen*)
64.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
64.2 +++ b/doc-src/Codegen/codegen.tex Wed Mar 04 11:05:29 2009 +0100
64.3 @@ -0,0 +1,53 @@
64.4 +
64.5 +\documentclass[12pt,a4paper,fleqn]{article}
64.6 +\usepackage{latexsym,graphicx}
64.7 +\usepackage[refpage]{nomencl}
64.8 +\usepackage{../iman,../extra,../isar,../proof}
64.9 +\usepackage{../isabelle,../isabellesym}
64.10 +\usepackage{style}
64.11 +\usepackage{pgf}
64.12 +\usepackage{pgflibraryshapes}
64.13 +\usepackage{tikz}
64.14 +\usepackage{../pdfsetup}
64.15 +
64.16 +\hyphenation{Isabelle}
64.17 +\hyphenation{Isar}
64.18 +\isadroptag{theory}
64.19 +
64.20 +\title{\includegraphics[scale=0.5]{isabelle_isar}
64.21 + \\[4ex] Code generation from Isabelle/HOL theories}
64.22 +\author{\emph{Florian Haftmann}}
64.23 +
64.24 +\begin{document}
64.25 +
64.26 +\maketitle
64.27 +
64.28 +\begin{abstract}
64.29 + \noindent This tutorial gives an introduction to a generic code generator framework in Isabelle
64.30 + for generating executable code in functional programming languages from logical
64.31 + specifications in Isabelle/HOL.
64.32 +\end{abstract}
64.33 +
64.34 +\thispagestyle{empty}\clearpage
64.35 +
64.36 +\pagenumbering{roman}
64.37 +\clearfirst
64.38 +
64.39 +\input{Thy/document/Introduction.tex}
64.40 +\input{Thy/document/Program.tex}
64.41 +\input{Thy/document/Adaption.tex}
64.42 +\input{Thy/document/Further.tex}
64.43 +\input{Thy/document/ML.tex}
64.44 +
64.45 +\begingroup
64.46 +\bibliographystyle{plain} \small\raggedright\frenchspacing
64.47 +\bibliography{../manual}
64.48 +\endgroup
64.49 +
64.50 +\end{document}
64.51 +
64.52 +
64.53 +%%% Local Variables:
64.54 +%%% mode: latex
64.55 +%%% TeX-master: t
64.56 +%%% End:
65.1 Binary file doc-src/Codegen/codegen_process.pdf has changed
66.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
66.2 +++ b/doc-src/Codegen/codegen_process.ps Wed Mar 04 11:05:29 2009 +0100
66.3 @@ -0,0 +1,586 @@
66.4 +%!PS-Adobe-2.0
66.5 +%%Creator: dot version 2.2 (Mon Sep 12 23:33:36 UTC 2005)
66.6 +%%For: (haftmann) Florian Haftmann
66.7 +%%Title: _anonymous_0
66.8 +%%Pages: (atend)
66.9 +%%BoundingBox: 35 35 451 291
66.10 +%%EndComments
66.11 +save
66.12 +%%BeginProlog
66.13 +/DotDict 200 dict def
66.14 +DotDict begin
66.15 +
66.16 +/setupLatin1 {
66.17 +mark
66.18 +/EncodingVector 256 array def
66.19 + EncodingVector 0
66.20 +
66.21 +ISOLatin1Encoding 0 255 getinterval putinterval
66.22 +
66.23 +EncodingVector
66.24 + dup 306 /AE
66.25 + dup 301 /Aacute
66.26 + dup 302 /Acircumflex
66.27 + dup 304 /Adieresis
66.28 + dup 300 /Agrave
66.29 + dup 305 /Aring
66.30 + dup 303 /Atilde
66.31 + dup 307 /Ccedilla
66.32 + dup 311 /Eacute
66.33 + dup 312 /Ecircumflex
66.34 + dup 313 /Edieresis
66.35 + dup 310 /Egrave
66.36 + dup 315 /Iacute
66.37 + dup 316 /Icircumflex
66.38 + dup 317 /Idieresis
66.39 + dup 314 /Igrave
66.40 + dup 334 /Udieresis
66.41 + dup 335 /Yacute
66.42 + dup 376 /thorn
66.43 + dup 337 /germandbls
66.44 + dup 341 /aacute
66.45 + dup 342 /acircumflex
66.46 + dup 344 /adieresis
66.47 + dup 346 /ae
66.48 + dup 340 /agrave
66.49 + dup 345 /aring
66.50 + dup 347 /ccedilla
66.51 + dup 351 /eacute
66.52 + dup 352 /ecircumflex
66.53 + dup 353 /edieresis
66.54 + dup 350 /egrave
66.55 + dup 355 /iacute
66.56 + dup 356 /icircumflex
66.57 + dup 357 /idieresis
66.58 + dup 354 /igrave
66.59 + dup 360 /dcroat
66.60 + dup 361 /ntilde
66.61 + dup 363 /oacute
66.62 + dup 364 /ocircumflex
66.63 + dup 366 /odieresis
66.64 + dup 362 /ograve
66.65 + dup 365 /otilde
66.66 + dup 370 /oslash
66.67 + dup 372 /uacute
66.68 + dup 373 /ucircumflex
66.69 + dup 374 /udieresis
66.70 + dup 371 /ugrave
66.71 + dup 375 /yacute
66.72 + dup 377 /ydieresis
66.73 +
66.74 +% Set up ISO Latin 1 character encoding
66.75 +/starnetISO {
66.76 + dup dup findfont dup length dict begin
66.77 + { 1 index /FID ne { def }{ pop pop } ifelse
66.78 + } forall
66.79 + /Encoding EncodingVector def
66.80 + currentdict end definefont
66.81 +} def
66.82 +/Times-Roman starnetISO def
66.83 +/Times-Italic starnetISO def
66.84 +/Times-Bold starnetISO def
66.85 +/Times-BoldItalic starnetISO def
66.86 +/Helvetica starnetISO def
66.87 +/Helvetica-Oblique starnetISO def
66.88 +/Helvetica-Bold starnetISO def
66.89 +/Helvetica-BoldOblique starnetISO def
66.90 +/Courier starnetISO def
66.91 +/Courier-Oblique starnetISO def
66.92 +/Courier-Bold starnetISO def
66.93 +/Courier-BoldOblique starnetISO def
66.94 +cleartomark
66.95 +} bind def
66.96 +
66.97 +%%BeginResource: procset graphviz 0 0
66.98 +/coord-font-family /Times-Roman def
66.99 +/default-font-family /Times-Roman def
66.100 +/coordfont coord-font-family findfont 8 scalefont def
66.101 +
66.102 +/InvScaleFactor 1.0 def
66.103 +/set_scale {
66.104 + dup 1 exch div /InvScaleFactor exch def
66.105 + dup scale
66.106 +} bind def
66.107 +
66.108 +% styles
66.109 +/solid { [] 0 setdash } bind def
66.110 +/dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def
66.111 +/dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def
66.112 +/invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def
66.113 +/bold { 2 setlinewidth } bind def
66.114 +/filled { } bind def
66.115 +/unfilled { } bind def
66.116 +/rounded { } bind def
66.117 +/diagonals { } bind def
66.118 +
66.119 +% hooks for setting color
66.120 +/nodecolor { sethsbcolor } bind def
66.121 +/edgecolor { sethsbcolor } bind def
66.122 +/graphcolor { sethsbcolor } bind def
66.123 +/nopcolor {pop pop pop} bind def
66.124 +
66.125 +/beginpage { % i j npages
66.126 + /npages exch def
66.127 + /j exch def
66.128 + /i exch def
66.129 + /str 10 string def
66.130 + npages 1 gt {
66.131 + gsave
66.132 + coordfont setfont
66.133 + 0 0 moveto
66.134 + (\() show i str cvs show (,) show j str cvs show (\)) show
66.135 + grestore
66.136 + } if
66.137 +} bind def
66.138 +
66.139 +/set_font {
66.140 + findfont exch
66.141 + scalefont setfont
66.142 +} def
66.143 +
66.144 +% draw aligned label in bounding box aligned to current point
66.145 +/alignedtext { % width adj text
66.146 + /text exch def
66.147 + /adj exch def
66.148 + /width exch def
66.149 + gsave
66.150 + width 0 gt {
66.151 + text stringwidth pop adj mul 0 rmoveto
66.152 + } if
66.153 + [] 0 setdash
66.154 + text show
66.155 + grestore
66.156 +} def
66.157 +
66.158 +/boxprim { % xcorner ycorner xsize ysize
66.159 + 4 2 roll
66.160 + moveto
66.161 + 2 copy
66.162 + exch 0 rlineto
66.163 + 0 exch rlineto
66.164 + pop neg 0 rlineto
66.165 + closepath
66.166 +} bind def
66.167 +
66.168 +/ellipse_path {
66.169 + /ry exch def
66.170 + /rx exch def
66.171 + /y exch def
66.172 + /x exch def
66.173 + matrix currentmatrix
66.174 + newpath
66.175 + x y translate
66.176 + rx ry scale
66.177 + 0 0 1 0 360 arc
66.178 + setmatrix
66.179 +} bind def
66.180 +
66.181 +/endpage { showpage } bind def
66.182 +/showpage { } def
66.183 +
66.184 +/layercolorseq
66.185 + [ % layer color sequence - darkest to lightest
66.186 + [0 0 0]
66.187 + [.2 .8 .8]
66.188 + [.4 .8 .8]
66.189 + [.6 .8 .8]
66.190 + [.8 .8 .8]
66.191 + ]
66.192 +def
66.193 +
66.194 +/layerlen layercolorseq length def
66.195 +
66.196 +/setlayer {/maxlayer exch def /curlayer exch def
66.197 + layercolorseq curlayer 1 sub layerlen mod get
66.198 + aload pop sethsbcolor
66.199 + /nodecolor {nopcolor} def
66.200 + /edgecolor {nopcolor} def
66.201 + /graphcolor {nopcolor} def
66.202 +} bind def
66.203 +
66.204 +/onlayer { curlayer ne {invis} if } def
66.205 +
66.206 +/onlayers {
66.207 + /myupper exch def
66.208 + /mylower exch def
66.209 + curlayer mylower lt
66.210 + curlayer myupper gt
66.211 + or
66.212 + {invis} if
66.213 +} def
66.214 +
66.215 +/curlayer 0 def
66.216 +
66.217 +%%EndResource
66.218 +%%EndProlog
66.219 +%%BeginSetup
66.220 +14 default-font-family set_font
66.221 +1 setmiterlimit
66.222 +% /arrowlength 10 def
66.223 +% /arrowwidth 5 def
66.224 +
66.225 +% make sure pdfmark is harmless for PS-interpreters other than Distiller
66.226 +/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse
66.227 +% make '<<' and '>>' safe on PS Level 1 devices
66.228 +/languagelevel where {pop languagelevel}{1} ifelse
66.229 +2 lt {
66.230 + userdict (<<) cvn ([) cvn load put
66.231 + userdict (>>) cvn ([) cvn load put
66.232 +} if
66.233 +
66.234 +%%EndSetup
66.235 +%%Page: 1 1
66.236 +%%PageBoundingBox: 36 36 451 291
66.237 +%%PageOrientation: Portrait
66.238 +gsave
66.239 +35 35 416 256 boxprim clip newpath
66.240 +36 36 translate
66.241 +0 0 1 beginpage
66.242 +0 0 translate 0 rotate
66.243 +[ /CropBox [36 36 451 291] /PAGES pdfmark
66.244 +0.000 0.000 0.000 graphcolor
66.245 +14.00 /Times-Roman set_font
66.246 +
66.247 +% theory
66.248 +gsave 10 dict begin
66.249 +newpath 93 254 moveto
66.250 +1 254 lineto
66.251 +1 214 lineto
66.252 +93 214 lineto
66.253 +closepath
66.254 +stroke
66.255 +gsave 10 dict begin
66.256 +8 237 moveto
66.257 +(Isabelle/HOL)
66.258 +[4.56 5.52 6.24 6.96 6.24 3.84 3.84 6.24 3.84 10.08 10.08 8.64]
66.259 +xshow
66.260 +16 221 moveto
66.261 +(Isar theory)
66.262 +[4.56 5.52 6.24 4.56 3.6 4.08 6.96 6.24 6.96 4.8 6.96]
66.263 +xshow
66.264 +end grestore
66.265 +end grestore
66.266 +
66.267 +% selection
66.268 +gsave 10 dict begin
66.269 +183 234 38 18 ellipse_path
66.270 +stroke
66.271 +gsave 10 dict begin
66.272 +158 229 moveto
66.273 +(selection)
66.274 +[5.52 6.24 3.84 6.24 6.24 3.84 3.84 6.96 6.96]
66.275 +xshow
66.276 +end grestore
66.277 +end grestore
66.278 +
66.279 +% theory -> selection
66.280 +newpath 94 234 moveto
66.281 +107 234 121 234 135 234 curveto
66.282 +stroke
66.283 +gsave 10 dict begin
66.284 +solid
66.285 +1 setlinewidth
66.286 +0.000 0.000 0.000 edgecolor
66.287 +newpath 135 238 moveto
66.288 +145 234 lineto
66.289 +135 231 lineto
66.290 +closepath
66.291 +fill
66.292 +0.000 0.000 0.000 edgecolor
66.293 +newpath 135 238 moveto
66.294 +145 234 lineto
66.295 +135 231 lineto
66.296 +closepath
66.297 +stroke
66.298 +end grestore
66.299 +
66.300 +% sml
66.301 +gsave 10 dict begin
66.302 +newpath 74 144 moveto
66.303 +20 144 lineto
66.304 +20 108 lineto
66.305 +74 108 lineto
66.306 +closepath
66.307 +stroke
66.308 +gsave 10 dict begin
66.309 +32 121 moveto
66.310 +(SML)
66.311 +[7.68 12.48 8.64]
66.312 +xshow
66.313 +end grestore
66.314 +end grestore
66.315 +
66.316 +% other
66.317 +gsave 10 dict begin
66.318 +gsave 10 dict begin
66.319 +41 67 moveto
66.320 +(...)
66.321 +[3.6 3.6 3.6]
66.322 +xshow
66.323 +end grestore
66.324 +end grestore
66.325 +
66.326 +% haskell
66.327 +gsave 10 dict begin
66.328 +newpath 77 36 moveto
66.329 +17 36 lineto
66.330 +17 0 lineto
66.331 +77 0 lineto
66.332 +closepath
66.333 +stroke
66.334 +gsave 10 dict begin
66.335 +25 13 moveto
66.336 +(Haskell)
66.337 +[10.08 6.24 5.52 6.72 6.24 3.84 3.84]
66.338 +xshow
66.339 +end grestore
66.340 +end grestore
66.341 +
66.342 +% preprocessing
66.343 +gsave 10 dict begin
66.344 +183 180 52 18 ellipse_path
66.345 +stroke
66.346 +gsave 10 dict begin
66.347 +143 175 moveto
66.348 +(preprocessing)
66.349 +[6.96 4.56 6.24 6.96 4.56 6.96 6.24 6.24 5.52 5.52 3.84 6.96 6.96]
66.350 +xshow
66.351 +end grestore
66.352 +end grestore
66.353 +
66.354 +% selection -> preprocessing
66.355 +newpath 183 216 moveto
66.356 +183 213 183 211 183 208 curveto
66.357 +stroke
66.358 +gsave 10 dict begin
66.359 +solid
66.360 +1 setlinewidth
66.361 +0.000 0.000 0.000 edgecolor
66.362 +newpath 187 208 moveto
66.363 +183 198 lineto
66.364 +180 208 lineto
66.365 +closepath
66.366 +fill
66.367 +0.000 0.000 0.000 edgecolor
66.368 +newpath 187 208 moveto
66.369 +183 198 lineto
66.370 +180 208 lineto
66.371 +closepath
66.372 +stroke
66.373 +end grestore
66.374 +
66.375 +% def_eqn
66.376 +gsave 10 dict begin
66.377 +newpath 403 198 moveto
66.378 +283 198 lineto
66.379 +283 162 lineto
66.380 +403 162 lineto
66.381 +closepath
66.382 +stroke
66.383 +gsave 10 dict begin
66.384 +291 175 moveto
66.385 +(defining equations)
66.386 +[6.96 6.24 4.8 3.84 6.96 3.84 6.96 6.96 3.6 6.24 6.72 6.96 6.24 3.84 3.84 6.96 6.96 5.52]
66.387 +xshow
66.388 +end grestore
66.389 +end grestore
66.390 +
66.391 +% preprocessing -> def_eqn
66.392 +newpath 236 180 moveto
66.393 +248 180 260 180 273 180 curveto
66.394 +stroke
66.395 +gsave 10 dict begin
66.396 +solid
66.397 +1 setlinewidth
66.398 +0.000 0.000 0.000 edgecolor
66.399 +newpath 273 184 moveto
66.400 +283 180 lineto
66.401 +273 177 lineto
66.402 +closepath
66.403 +fill
66.404 +0.000 0.000 0.000 edgecolor
66.405 +newpath 273 184 moveto
66.406 +283 180 lineto
66.407 +273 177 lineto
66.408 +closepath
66.409 +stroke
66.410 +end grestore
66.411 +
66.412 +% serialization
66.413 +gsave 10 dict begin
66.414 +183 72 47 18 ellipse_path
66.415 +stroke
66.416 +gsave 10 dict begin
66.417 +148 67 moveto
66.418 +(serialization)
66.419 +[5.52 6.24 4.8 3.84 6.24 3.84 3.84 6.24 6.24 3.84 3.84 6.96 6.96]
66.420 +xshow
66.421 +end grestore
66.422 +end grestore
66.423 +
66.424 +% serialization -> sml
66.425 +newpath 150 85 moveto
66.426 +129 93 104 103 83 111 curveto
66.427 +stroke
66.428 +gsave 10 dict begin
66.429 +solid
66.430 +1 setlinewidth
66.431 +0.000 0.000 0.000 edgecolor
66.432 +newpath 82 108 moveto
66.433 +74 115 lineto
66.434 +85 114 lineto
66.435 +closepath
66.436 +fill
66.437 +0.000 0.000 0.000 edgecolor
66.438 +newpath 82 108 moveto
66.439 +74 115 lineto
66.440 +85 114 lineto
66.441 +closepath
66.442 +stroke
66.443 +end grestore
66.444 +
66.445 +% serialization -> other
66.446 +gsave 10 dict begin
66.447 +dotted
66.448 +newpath 135 72 moveto
66.449 +119 72 100 72 84 72 curveto
66.450 +stroke
66.451 +gsave 10 dict begin
66.452 +solid
66.453 +1 setlinewidth
66.454 +0.000 0.000 0.000 edgecolor
66.455 +newpath 84 69 moveto
66.456 +74 72 lineto
66.457 +84 76 lineto
66.458 +closepath
66.459 +fill
66.460 +0.000 0.000 0.000 edgecolor
66.461 +newpath 84 69 moveto
66.462 +74 72 lineto
66.463 +84 76 lineto
66.464 +closepath
66.465 +stroke
66.466 +end grestore
66.467 +end grestore
66.468 +
66.469 +% serialization -> haskell
66.470 +newpath 150 59 moveto
66.471 +131 51 107 42 86 34 curveto
66.472 +stroke
66.473 +gsave 10 dict begin
66.474 +solid
66.475 +1 setlinewidth
66.476 +0.000 0.000 0.000 edgecolor
66.477 +newpath 88 31 moveto
66.478 +77 30 lineto
66.479 +85 37 lineto
66.480 +closepath
66.481 +fill
66.482 +0.000 0.000 0.000 edgecolor
66.483 +newpath 88 31 moveto
66.484 +77 30 lineto
66.485 +85 37 lineto
66.486 +closepath
66.487 +stroke
66.488 +end grestore
66.489 +
66.490 +% translation
66.491 +gsave 10 dict begin
66.492 +343 126 43 18 ellipse_path
66.493 +stroke
66.494 +gsave 10 dict begin
66.495 +313 121 moveto
66.496 +(translation)
66.497 +[3.84 4.56 6.24 6.96 5.52 3.84 6.24 3.84 3.84 6.96 6.96]
66.498 +xshow
66.499 +end grestore
66.500 +end grestore
66.501 +
66.502 +% def_eqn -> translation
66.503 +newpath 343 162 moveto
66.504 +343 159 343 157 343 154 curveto
66.505 +stroke
66.506 +gsave 10 dict begin
66.507 +solid
66.508 +1 setlinewidth
66.509 +0.000 0.000 0.000 edgecolor
66.510 +newpath 347 154 moveto
66.511 +343 144 lineto
66.512 +340 154 lineto
66.513 +closepath
66.514 +fill
66.515 +0.000 0.000 0.000 edgecolor
66.516 +newpath 347 154 moveto
66.517 +343 144 lineto
66.518 +340 154 lineto
66.519 +closepath
66.520 +stroke
66.521 +end grestore
66.522 +
66.523 +% iml
66.524 +gsave 10 dict begin
66.525 +newpath 413 90 moveto
66.526 +273 90 lineto
66.527 +273 54 lineto
66.528 +413 54 lineto
66.529 +closepath
66.530 +stroke
66.531 +gsave 10 dict begin
66.532 +280 67 moveto
66.533 +(intermediate language)
66.534 +[3.84 6.96 3.84 6.24 4.8 10.8 6.24 6.96 3.84 6.24 3.84 6.24 3.6 3.84 6.24 6.96 6.96 6.96 6.24 6.72 6.24]
66.535 +xshow
66.536 +end grestore
66.537 +end grestore
66.538 +
66.539 +% translation -> iml
66.540 +newpath 343 108 moveto
66.541 +343 105 343 103 343 100 curveto
66.542 +stroke
66.543 +gsave 10 dict begin
66.544 +solid
66.545 +1 setlinewidth
66.546 +0.000 0.000 0.000 edgecolor
66.547 +newpath 347 100 moveto
66.548 +343 90 lineto
66.549 +340 100 lineto
66.550 +closepath
66.551 +fill
66.552 +0.000 0.000 0.000 edgecolor
66.553 +newpath 347 100 moveto
66.554 +343 90 lineto
66.555 +340 100 lineto
66.556 +closepath
66.557 +stroke
66.558 +end grestore
66.559 +
66.560 +% iml -> serialization
66.561 +newpath 272 72 moveto
66.562 +262 72 251 72 241 72 curveto
66.563 +stroke
66.564 +gsave 10 dict begin
66.565 +solid
66.566 +1 setlinewidth
66.567 +0.000 0.000 0.000 edgecolor
66.568 +newpath 241 69 moveto
66.569 +231 72 lineto
66.570 +241 76 lineto
66.571 +closepath
66.572 +fill
66.573 +0.000 0.000 0.000 edgecolor
66.574 +newpath 241 69 moveto
66.575 +231 72 lineto
66.576 +241 76 lineto
66.577 +closepath
66.578 +stroke
66.579 +end grestore
66.580 +endpage
66.581 +showpage
66.582 +grestore
66.583 +%%PageTrailer
66.584 +%%EndPage: 1
66.585 +%%Trailer
66.586 +%%Pages: 1
66.587 +end
66.588 +restore
66.589 +%%EOF
67.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
67.2 +++ b/doc-src/Codegen/style.sty Wed Mar 04 11:05:29 2009 +0100
67.3 @@ -0,0 +1,63 @@
67.4 +
67.5 +%% toc
67.6 +\newcommand{\tocentry}[1]{\cleardoublepage\phantomsection\addcontentsline{toc}{chapter}{#1}
67.7 +\@mkboth{\MakeUppercase{#1}}{\MakeUppercase{#1}}}
67.8 +
67.9 +%% paragraphs
67.10 +\setlength{\parindent}{1em}
67.11 +
67.12 +%% references
67.13 +\newcommand{\secref}[1]{\S\ref{#1}}
67.14 +
67.15 +%% logical markup
67.16 +\newcommand{\strong}[1]{{\bfseries {#1}}}
67.17 +\newcommand{\qn}[1]{\emph{#1}}
67.18 +
67.19 +%% typographic conventions
67.20 +\newcommand{\qt}[1]{``{#1}''}
67.21 +
67.22 +%% verbatim text
67.23 +\newcommand{\isatypewriter}{\fontsize{9pt}{0pt}\tt\renewcommand{\baselinestretch}{1}\setlength{\baselineskip}{9pt}}
67.24 +
67.25 +%% quote environment
67.26 +\isakeeptag{quote}
67.27 +\renewenvironment{quote}
67.28 + {\list{}{\leftmargin2em\rightmargin0pt}\parindent0pt\parskip0pt\item\relax}
67.29 + {\endlist}
67.30 +\renewcommand{\isatagquote}{\begin{quote}}
67.31 +\renewcommand{\endisatagquote}{\end{quote}}
67.32 +\newcommand{\quotebreak}{\\[1.2ex]}
67.33 +
67.34 +\isakeeptag{quotett}
67.35 +\renewcommand{\isatagquotett}{\begin{quote}\isabellestyle{tt}\isastyle}
67.36 +\renewcommand{\endisatagquotett}{\end{quote}\isabellestyle{it}\isastyle}
67.37 +
67.38 +%% a trick
67.39 +\newcommand{\isasymSML}{SML}
67.40 +
67.41 +%% presentation
67.42 +\setcounter{secnumdepth}{2} \setcounter{tocdepth}{2}
67.43 +
67.44 +%% character detail
67.45 +\renewcommand{\isadigit}[1]{\isamath{#1}}
67.46 +\binperiod
67.47 +\underscoreoff
67.48 +
67.49 +%% format
67.50 +\pagestyle{headings}
67.51 +\isabellestyle{it}
67.52 +
67.53 +%% ml reference
67.54 +\newenvironment{mldecls}{\par\noindent\begingroup\footnotesize\def\isanewline{\\}\begin{tabular}{l}}{\end{tabular}\smallskip\endgroup}
67.55 +
67.56 +\isakeeptag{mlref}
67.57 +\renewcommand{\isatagmlref}{\subsection*{\makebox[0pt][r]{\fbox{\ML}~~}Reference}\begingroup\def\isastyletext{\rm}\small}
67.58 +\renewcommand{\endisatagmlref}{\endgroup}
67.59 +
67.60 +\isabellestyle{it}
67.61 +
67.62 +
67.63 +%%% Local Variables:
67.64 +%%% mode: latex
67.65 +%%% TeX-master: "implementation"
67.66 +%%% End:
68.1 --- a/doc-src/Dirs Wed Mar 04 11:05:02 2009 +0100
68.2 +++ b/doc-src/Dirs Wed Mar 04 11:05:29 2009 +0100
68.3 @@ -1,1 +1,1 @@
68.4 -Ref System Logics HOL ZF Inductive TutorialI IsarOverview IsarRef IsarImplementation Locales LaTeXsugar IsarAdvanced/Classes IsarAdvanced/Codegen IsarAdvanced/Functions
68.5 +Intro Ref System Logics HOL ZF Inductive TutorialI IsarOverview IsarRef IsarImplementation Locales LaTeXsugar Classes Codegen Functions
69.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
69.2 +++ b/doc-src/Functions/IsaMakefile Wed Mar 04 11:05:29 2009 +0100
69.3 @@ -0,0 +1,33 @@
69.4 +
69.5 +## targets
69.6 +
69.7 +default: Thy
69.8 +images:
69.9 +test: Thy
69.10 +
69.11 +all: images test
69.12 +
69.13 +
69.14 +## global settings
69.15 +
69.16 +SRC = $(ISABELLE_HOME)/src
69.17 +OUT = $(ISABELLE_OUTPUT)
69.18 +LOG = $(OUT)/log
69.19 +
69.20 +USEDIR = $(ISABELLE_TOOL) usedir -v true -i false -d false -C false -D document
69.21 +
69.22 +
69.23 +## Thy
69.24 +
69.25 +THY = $(LOG)/HOL-Thy.gz
69.26 +
69.27 +Thy: $(THY)
69.28 +
69.29 +$(THY): Thy/ROOT.ML Thy/Functions.thy
69.30 + @$(USEDIR) HOL Thy
69.31 +
69.32 +
69.33 +## clean
69.34 +
69.35 +clean:
69.36 + @rm -f $(THY)
70.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
70.2 +++ b/doc-src/Functions/Makefile Wed Mar 04 11:05:29 2009 +0100
70.3 @@ -0,0 +1,38 @@
70.4 +#
70.5 +# $Id$
70.6 +#
70.7 +
70.8 +## targets
70.9 +
70.10 +default: dvi
70.11 +
70.12 +
70.13 +## dependencies
70.14 +
70.15 +include ../Makefile.in
70.16 +
70.17 +NAME = functions
70.18 +
70.19 +FILES = $(NAME).tex Thy/document/Functions.tex intro.tex conclusion.tex \
70.20 + style.sty ../iman.sty ../extra.sty ../isar.sty \
70.21 + ../isabelle.sty ../isabellesym.sty ../pdfsetup.sty \
70.22 + ../manual.bib ../proof.sty
70.23 +
70.24 +dvi: $(NAME).dvi
70.25 +
70.26 +$(NAME).dvi: $(FILES) isabelle_isar.eps
70.27 + $(LATEX) $(NAME)
70.28 + $(BIBTEX) $(NAME)
70.29 + $(LATEX) $(NAME)
70.30 + $(LATEX) $(NAME)
70.31 +
70.32 +pdf: $(NAME).pdf
70.33 +
70.34 +$(NAME).pdf: $(FILES) isabelle_isar.pdf
70.35 + $(PDFLATEX) $(NAME)
70.36 + $(BIBTEX) $(NAME)
70.37 + $(PDFLATEX) $(NAME)
70.38 + $(PDFLATEX) $(NAME)
70.39 + $(FIXBOOKMARKS) $(NAME).out
70.40 + $(PDFLATEX) $(NAME)
70.41 + $(PDFLATEX) $(NAME)
71.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
71.2 +++ b/doc-src/Functions/Thy/Functions.thy Wed Mar 04 11:05:29 2009 +0100
71.3 @@ -0,0 +1,1264 @@
71.4 +(* Title: doc-src/IsarAdvanced/Functions/Thy/Fundefs.thy
71.5 + Author: Alexander Krauss, TU Muenchen
71.6 +
71.7 +Tutorial for function definitions with the new "function" package.
71.8 +*)
71.9 +
71.10 +theory Functions
71.11 +imports Main
71.12 +begin
71.13 +
71.14 +section {* Function Definitions for Dummies *}
71.15 +
71.16 +text {*
71.17 + In most cases, defining a recursive function is just as simple as other definitions:
71.18 +*}
71.19 +
71.20 +fun fib :: "nat \<Rightarrow> nat"
71.21 +where
71.22 + "fib 0 = 1"
71.23 +| "fib (Suc 0) = 1"
71.24 +| "fib (Suc (Suc n)) = fib n + fib (Suc n)"
71.25 +
71.26 +text {*
71.27 + The syntax is rather self-explanatory: We introduce a function by
71.28 + giving its name, its type,
71.29 + and a set of defining recursive equations.
71.30 + If we leave out the type, the most general type will be
71.31 + inferred, which can sometimes lead to surprises: Since both @{term
71.32 + "1::nat"} and @{text "+"} are overloaded, we would end up
71.33 + with @{text "fib :: nat \<Rightarrow> 'a::{one,plus}"}.
71.34 +*}
71.35 +
71.36 +text {*
71.37 + The function always terminates, since its argument gets smaller in
71.38 + every recursive call.
71.39 + Since HOL is a logic of total functions, termination is a
71.40 + fundamental requirement to prevent inconsistencies\footnote{From the
71.41 + \qt{definition} @{text "f(n) = f(n) + 1"} we could prove
71.42 + @{text "0 = 1"} by subtracting @{text "f(n)"} on both sides.}.
71.43 + Isabelle tries to prove termination automatically when a definition
71.44 + is made. In \S\ref{termination}, we will look at cases where this
71.45 + fails and see what to do then.
71.46 +*}
71.47 +
71.48 +subsection {* Pattern matching *}
71.49 +
71.50 +text {* \label{patmatch}
71.51 + Like in functional programming, we can use pattern matching to
71.52 + define functions. At the moment we will only consider \emph{constructor
71.53 + patterns}, which only consist of datatype constructors and
71.54 + variables. Furthermore, patterns must be linear, i.e.\ all variables
71.55 + on the left hand side of an equation must be distinct. In
71.56 + \S\ref{genpats} we discuss more general pattern matching.
71.57 +
71.58 + If patterns overlap, the order of the equations is taken into
71.59 + account. The following function inserts a fixed element between any
71.60 + two elements of a list:
71.61 +*}
71.62 +
71.63 +fun sep :: "'a \<Rightarrow> 'a list \<Rightarrow> 'a list"
71.64 +where
71.65 + "sep a (x#y#xs) = x # a # sep a (y # xs)"
71.66 +| "sep a xs = xs"
71.67 +
71.68 +text {*
71.69 + Overlapping patterns are interpreted as \qt{increments} to what is
71.70 + already there: The second equation is only meant for the cases where
71.71 + the first one does not match. Consequently, Isabelle replaces it
71.72 + internally by the remaining cases, making the patterns disjoint:
71.73 +*}
71.74 +
71.75 +thm sep.simps
71.76 +
71.77 +text {* @{thm [display] sep.simps[no_vars]} *}
71.78 +
71.79 +text {*
71.80 + \noindent The equations from function definitions are automatically used in
71.81 + simplification:
71.82 +*}
71.83 +
71.84 +lemma "sep 0 [1, 2, 3] = [1, 0, 2, 0, 3]"
71.85 +by simp
71.86 +
71.87 +subsection {* Induction *}
71.88 +
71.89 +text {*
71.90 +
71.91 + Isabelle provides customized induction rules for recursive
71.92 + functions. These rules follow the recursive structure of the
71.93 + definition. Here is the rule @{text sep.induct} arising from the
71.94 + above definition of @{const sep}:
71.95 +
71.96 + @{thm [display] sep.induct}
71.97 +
71.98 + We have a step case for list with at least two elements, and two
71.99 + base cases for the zero- and the one-element list. Here is a simple
71.100 + proof about @{const sep} and @{const map}
71.101 +*}
71.102 +
71.103 +lemma "map f (sep x ys) = sep (f x) (map f ys)"
71.104 +apply (induct x ys rule: sep.induct)
71.105 +
71.106 +txt {*
71.107 + We get three cases, like in the definition.
71.108 +
71.109 + @{subgoals [display]}
71.110 +*}
71.111 +
71.112 +apply auto
71.113 +done
71.114 +text {*
71.115 +
71.116 + With the \cmd{fun} command, you can define about 80\% of the
71.117 + functions that occur in practice. The rest of this tutorial explains
71.118 + the remaining 20\%.
71.119 +*}
71.120 +
71.121 +
71.122 +section {* fun vs.\ function *}
71.123 +
71.124 +text {*
71.125 + The \cmd{fun} command provides a
71.126 + convenient shorthand notation for simple function definitions. In
71.127 + this mode, Isabelle tries to solve all the necessary proof obligations
71.128 + automatically. If any proof fails, the definition is
71.129 + rejected. This can either mean that the definition is indeed faulty,
71.130 + or that the default proof procedures are just not smart enough (or
71.131 + rather: not designed) to handle the definition.
71.132 +
71.133 + By expanding the abbreviation to the more verbose \cmd{function} command, these proof obligations become visible and can be analyzed or
71.134 + solved manually. The expansion from \cmd{fun} to \cmd{function} is as follows:
71.135 +
71.136 +\end{isamarkuptext}
71.137 +
71.138 +
71.139 +\[\left[\;\begin{minipage}{0.25\textwidth}\vspace{6pt}
71.140 +\cmd{fun} @{text "f :: \<tau>"}\\%
71.141 +\cmd{where}\\%
71.142 +\hspace*{2ex}{\it equations}\\%
71.143 +\hspace*{2ex}\vdots\vspace*{6pt}
71.144 +\end{minipage}\right]
71.145 +\quad\equiv\quad
71.146 +\left[\;\begin{minipage}{0.48\textwidth}\vspace{6pt}
71.147 +\cmd{function} @{text "("}\cmd{sequential}@{text ") f :: \<tau>"}\\%
71.148 +\cmd{where}\\%
71.149 +\hspace*{2ex}{\it equations}\\%
71.150 +\hspace*{2ex}\vdots\\%
71.151 +\cmd{by} @{text "pat_completeness auto"}\\%
71.152 +\cmd{termination by} @{text "lexicographic_order"}\vspace{6pt}
71.153 +\end{minipage}
71.154 +\right]\]
71.155 +
71.156 +\begin{isamarkuptext}
71.157 + \vspace*{1em}
71.158 + \noindent Some details have now become explicit:
71.159 +
71.160 + \begin{enumerate}
71.161 + \item The \cmd{sequential} option enables the preprocessing of
71.162 + pattern overlaps which we already saw. Without this option, the equations
71.163 + must already be disjoint and complete. The automatic completion only
71.164 + works with constructor patterns.
71.165 +
71.166 + \item A function definition produces a proof obligation which
71.167 + expresses completeness and compatibility of patterns (we talk about
71.168 + this later). The combination of the methods @{text "pat_completeness"} and
71.169 + @{text "auto"} is used to solve this proof obligation.
71.170 +
71.171 + \item A termination proof follows the definition, started by the
71.172 + \cmd{termination} command. This will be explained in \S\ref{termination}.
71.173 + \end{enumerate}
71.174 + Whenever a \cmd{fun} command fails, it is usually a good idea to
71.175 + expand the syntax to the more verbose \cmd{function} form, to see
71.176 + what is actually going on.
71.177 + *}
71.178 +
71.179 +
71.180 +section {* Termination *}
71.181 +
71.182 +text {*\label{termination}
71.183 + The method @{text "lexicographic_order"} is the default method for
71.184 + termination proofs. It can prove termination of a
71.185 + certain class of functions by searching for a suitable lexicographic
71.186 + combination of size measures. Of course, not all functions have such
71.187 + a simple termination argument. For them, we can specify the termination
71.188 + relation manually.
71.189 +*}
71.190 +
71.191 +subsection {* The {\tt relation} method *}
71.192 +text{*
71.193 + Consider the following function, which sums up natural numbers up to
71.194 + @{text "N"}, using a counter @{text "i"}:
71.195 +*}
71.196 +
71.197 +function sum :: "nat \<Rightarrow> nat \<Rightarrow> nat"
71.198 +where
71.199 + "sum i N = (if i > N then 0 else i + sum (Suc i) N)"
71.200 +by pat_completeness auto
71.201 +
71.202 +text {*
71.203 + \noindent The @{text "lexicographic_order"} method fails on this example, because none of the
71.204 + arguments decreases in the recursive call, with respect to the standard size ordering.
71.205 + To prove termination manually, we must provide a custom wellfounded relation.
71.206 +
71.207 + The termination argument for @{text "sum"} is based on the fact that
71.208 + the \emph{difference} between @{text "i"} and @{text "N"} gets
71.209 + smaller in every step, and that the recursion stops when @{text "i"}
71.210 + is greater than @{text "N"}. Phrased differently, the expression
71.211 + @{text "N + 1 - i"} always decreases.
71.212 +
71.213 + We can use this expression as a measure function suitable to prove termination.
71.214 +*}
71.215 +
71.216 +termination sum
71.217 +apply (relation "measure (\<lambda>(i,N). N + 1 - i)")
71.218 +
71.219 +txt {*
71.220 + The \cmd{termination} command sets up the termination goal for the
71.221 + specified function @{text "sum"}. If the function name is omitted, it
71.222 + implicitly refers to the last function definition.
71.223 +
71.224 + The @{text relation} method takes a relation of
71.225 + type @{typ "('a \<times> 'a) set"}, where @{typ "'a"} is the argument type of
71.226 + the function. If the function has multiple curried arguments, then
71.227 + these are packed together into a tuple, as it happened in the above
71.228 + example.
71.229 +
71.230 + The predefined function @{term[source] "measure :: ('a \<Rightarrow> nat) \<Rightarrow> ('a \<times> 'a) set"} constructs a
71.231 + wellfounded relation from a mapping into the natural numbers (a
71.232 + \emph{measure function}).
71.233 +
71.234 + After the invocation of @{text "relation"}, we must prove that (a)
71.235 + the relation we supplied is wellfounded, and (b) that the arguments
71.236 + of recursive calls indeed decrease with respect to the
71.237 + relation:
71.238 +
71.239 + @{subgoals[display,indent=0]}
71.240 +
71.241 + These goals are all solved by @{text "auto"}:
71.242 +*}
71.243 +
71.244 +apply auto
71.245 +done
71.246 +
71.247 +text {*
71.248 + Let us complicate the function a little, by adding some more
71.249 + recursive calls:
71.250 +*}
71.251 +
71.252 +function foo :: "nat \<Rightarrow> nat \<Rightarrow> nat"
71.253 +where
71.254 + "foo i N = (if i > N
71.255 + then (if N = 0 then 0 else foo 0 (N - 1))
71.256 + else i + foo (Suc i) N)"
71.257 +by pat_completeness auto
71.258 +
71.259 +text {*
71.260 + When @{text "i"} has reached @{text "N"}, it starts at zero again
71.261 + and @{text "N"} is decremented.
71.262 + This corresponds to a nested
71.263 + loop where one index counts up and the other down. Termination can
71.264 + be proved using a lexicographic combination of two measures, namely
71.265 + the value of @{text "N"} and the above difference. The @{const
71.266 + "measures"} combinator generalizes @{text "measure"} by taking a
71.267 + list of measure functions.
71.268 +*}
71.269 +
71.270 +termination
71.271 +by (relation "measures [\<lambda>(i, N). N, \<lambda>(i,N). N + 1 - i]") auto
71.272 +
71.273 +subsection {* How @{text "lexicographic_order"} works *}
71.274 +
71.275 +(*fun fails :: "nat \<Rightarrow> nat list \<Rightarrow> nat"
71.276 +where
71.277 + "fails a [] = a"
71.278 +| "fails a (x#xs) = fails (x + a) (x # xs)"
71.279 +*)
71.280 +
71.281 +text {*
71.282 + To see how the automatic termination proofs work, let's look at an
71.283 + example where it fails\footnote{For a detailed discussion of the
71.284 + termination prover, see \cite{bulwahnKN07}}:
71.285 +
71.286 +\end{isamarkuptext}
71.287 +\cmd{fun} @{text "fails :: \"nat \<Rightarrow> nat list \<Rightarrow> nat\""}\\%
71.288 +\cmd{where}\\%
71.289 +\hspace*{2ex}@{text "\"fails a [] = a\""}\\%
71.290 +|\hspace*{1.5ex}@{text "\"fails a (x#xs) = fails (x + a) (x#xs)\""}\\
71.291 +\begin{isamarkuptext}
71.292 +
71.293 +\noindent Isabelle responds with the following error:
71.294 +
71.295 +\begin{isabelle}
71.296 +*** Unfinished subgoals:\newline
71.297 +*** (a, 1, <):\newline
71.298 +*** \ 1.~@{text "\<And>x. x = 0"}\newline
71.299 +*** (a, 1, <=):\newline
71.300 +*** \ 1.~False\newline
71.301 +*** (a, 2, <):\newline
71.302 +*** \ 1.~False\newline
71.303 +*** Calls:\newline
71.304 +*** a) @{text "(a, x # xs) -->> (x + a, x # xs)"}\newline
71.305 +*** Measures:\newline
71.306 +*** 1) @{text "\<lambda>x. size (fst x)"}\newline
71.307 +*** 2) @{text "\<lambda>x. size (snd x)"}\newline
71.308 +*** Result matrix:\newline
71.309 +*** \ \ \ \ 1\ \ 2 \newline
71.310 +*** a: ? <= \newline
71.311 +*** Could not find lexicographic termination order.\newline
71.312 +*** At command "fun".\newline
71.313 +\end{isabelle}
71.314 +*}
71.315 +
71.316 +
71.317 +text {*
71.318 + The key to this error message is the matrix at the bottom. The rows
71.319 + of that matrix correspond to the different recursive calls (In our
71.320 + case, there is just one). The columns are the function's arguments
71.321 + (expressed through different measure functions, which map the
71.322 + argument tuple to a natural number).
71.323 +
71.324 + The contents of the matrix summarize what is known about argument
71.325 + descents: The second argument has a weak descent (@{text "<="}) at the
71.326 + recursive call, and for the first argument nothing could be proved,
71.327 + which is expressed by @{text "?"}. In general, there are the values
71.328 + @{text "<"}, @{text "<="} and @{text "?"}.
71.329 +
71.330 + For the failed proof attempts, the unfinished subgoals are also
71.331 + printed. Looking at these will often point to a missing lemma.
71.332 +
71.333 +% As a more real example, here is quicksort:
71.334 +*}
71.335 +(*
71.336 +function qs :: "nat list \<Rightarrow> nat list"
71.337 +where
71.338 + "qs [] = []"
71.339 +| "qs (x#xs) = qs [y\<in>xs. y < x] @ x # qs [y\<in>xs. y \<ge> x]"
71.340 +by pat_completeness auto
71.341 +
71.342 +termination apply lexicographic_order
71.343 +
71.344 +text {* If we try @{text "lexicographic_order"} method, we get the
71.345 + following error *}
71.346 +termination by (lexicographic_order simp:l2)
71.347 +
71.348 +lemma l: "x \<le> y \<Longrightarrow> x < Suc y" by arith
71.349 +
71.350 +function
71.351 +
71.352 +*)
71.353 +
71.354 +section {* Mutual Recursion *}
71.355 +
71.356 +text {*
71.357 + If two or more functions call one another mutually, they have to be defined
71.358 + in one step. Here are @{text "even"} and @{text "odd"}:
71.359 +*}
71.360 +
71.361 +function even :: "nat \<Rightarrow> bool"
71.362 + and odd :: "nat \<Rightarrow> bool"
71.363 +where
71.364 + "even 0 = True"
71.365 +| "odd 0 = False"
71.366 +| "even (Suc n) = odd n"
71.367 +| "odd (Suc n) = even n"
71.368 +by pat_completeness auto
71.369 +
71.370 +text {*
71.371 + To eliminate the mutual dependencies, Isabelle internally
71.372 + creates a single function operating on the sum
71.373 + type @{typ "nat + nat"}. Then, @{const even} and @{const odd} are
71.374 + defined as projections. Consequently, termination has to be proved
71.375 + simultaneously for both functions, by specifying a measure on the
71.376 + sum type:
71.377 +*}
71.378 +
71.379 +termination
71.380 +by (relation "measure (\<lambda>x. case x of Inl n \<Rightarrow> n | Inr n \<Rightarrow> n)") auto
71.381 +
71.382 +text {*
71.383 + We could also have used @{text lexicographic_order}, which
71.384 + supports mutual recursive termination proofs to a certain extent.
71.385 +*}
71.386 +
71.387 +subsection {* Induction for mutual recursion *}
71.388 +
71.389 +text {*
71.390 +
71.391 + When functions are mutually recursive, proving properties about them
71.392 + generally requires simultaneous induction. The induction rule @{text "even_odd.induct"}
71.393 + generated from the above definition reflects this.
71.394 +
71.395 + Let us prove something about @{const even} and @{const odd}:
71.396 +*}
71.397 +
71.398 +lemma even_odd_mod2:
71.399 + "even n = (n mod 2 = 0)"
71.400 + "odd n = (n mod 2 = 1)"
71.401 +
71.402 +txt {*
71.403 + We apply simultaneous induction, specifying the induction variable
71.404 + for both goals, separated by \cmd{and}: *}
71.405 +
71.406 +apply (induct n and n rule: even_odd.induct)
71.407 +
71.408 +txt {*
71.409 + We get four subgoals, which correspond to the clauses in the
71.410 + definition of @{const even} and @{const odd}:
71.411 + @{subgoals[display,indent=0]}
71.412 + Simplification solves the first two goals, leaving us with two
71.413 + statements about the @{text "mod"} operation to prove:
71.414 +*}
71.415 +
71.416 +apply simp_all
71.417 +
71.418 +txt {*
71.419 + @{subgoals[display,indent=0]}
71.420 +
71.421 + \noindent These can be handled by Isabelle's arithmetic decision procedures.
71.422 +
71.423 +*}
71.424 +
71.425 +apply arith
71.426 +apply arith
71.427 +done
71.428 +
71.429 +text {*
71.430 + In proofs like this, the simultaneous induction is really essential:
71.431 + Even if we are just interested in one of the results, the other
71.432 + one is necessary to strengthen the induction hypothesis. If we leave
71.433 + out the statement about @{const odd} and just write @{term True} instead,
71.434 + the same proof fails:
71.435 +*}
71.436 +
71.437 +lemma failed_attempt:
71.438 + "even n = (n mod 2 = 0)"
71.439 + "True"
71.440 +apply (induct n rule: even_odd.induct)
71.441 +
71.442 +txt {*
71.443 + \noindent Now the third subgoal is a dead end, since we have no
71.444 + useful induction hypothesis available:
71.445 +
71.446 + @{subgoals[display,indent=0]}
71.447 +*}
71.448 +
71.449 +oops
71.450 +
71.451 +section {* General pattern matching *}
71.452 +text{*\label{genpats} *}
71.453 +
71.454 +subsection {* Avoiding automatic pattern splitting *}
71.455 +
71.456 +text {*
71.457 +
71.458 + Up to now, we used pattern matching only on datatypes, and the
71.459 + patterns were always disjoint and complete, and if they weren't,
71.460 + they were made disjoint automatically like in the definition of
71.461 + @{const "sep"} in \S\ref{patmatch}.
71.462 +
71.463 + This automatic splitting can significantly increase the number of
71.464 + equations involved, and this is not always desirable. The following
71.465 + example shows the problem:
71.466 +
71.467 + Suppose we are modeling incomplete knowledge about the world by a
71.468 + three-valued datatype, which has values @{term "T"}, @{term "F"}
71.469 + and @{term "X"} for true, false and uncertain propositions, respectively.
71.470 +*}
71.471 +
71.472 +datatype P3 = T | F | X
71.473 +
71.474 +text {* \noindent Then the conjunction of such values can be defined as follows: *}
71.475 +
71.476 +fun And :: "P3 \<Rightarrow> P3 \<Rightarrow> P3"
71.477 +where
71.478 + "And T p = p"
71.479 +| "And p T = p"
71.480 +| "And p F = F"
71.481 +| "And F p = F"
71.482 +| "And X X = X"
71.483 +
71.484 +
71.485 +text {*
71.486 + This definition is useful, because the equations can directly be used
71.487 + as simplification rules. But the patterns overlap: For example,
71.488 + the expression @{term "And T T"} is matched by both the first and
71.489 + the second equation. By default, Isabelle makes the patterns disjoint by
71.490 + splitting them up, producing instances:
71.491 +*}
71.492 +
71.493 +thm And.simps
71.494 +
71.495 +text {*
71.496 + @{thm[indent=4] And.simps}
71.497 +
71.498 + \vspace*{1em}
71.499 + \noindent There are several problems with this:
71.500 +
71.501 + \begin{enumerate}
71.502 + \item If the datatype has many constructors, there can be an
71.503 + explosion of equations. For @{const "And"}, we get seven instead of
71.504 + five equations, which can be tolerated, but this is just a small
71.505 + example.
71.506 +
71.507 + \item Since splitting makes the equations \qt{less general}, they
71.508 + do not always match in rewriting. While the term @{term "And x F"}
71.509 + can be simplified to @{term "F"} with the original equations, a
71.510 + (manual) case split on @{term "x"} is now necessary.
71.511 +
71.512 + \item The splitting also concerns the induction rule @{text
71.513 + "And.induct"}. Instead of five premises it now has seven, which
71.514 + means that our induction proofs will have more cases.
71.515 +
71.516 + \item In general, it increases clarity if we get the same definition
71.517 + back which we put in.
71.518 + \end{enumerate}
71.519 +
71.520 + If we do not want the automatic splitting, we can switch it off by
71.521 + leaving out the \cmd{sequential} option. However, we will have to
71.522 + prove that our pattern matching is consistent\footnote{This prevents
71.523 + us from defining something like @{term "f x = True"} and @{term "f x
71.524 + = False"} simultaneously.}:
71.525 +*}
71.526 +
71.527 +function And2 :: "P3 \<Rightarrow> P3 \<Rightarrow> P3"
71.528 +where
71.529 + "And2 T p = p"
71.530 +| "And2 p T = p"
71.531 +| "And2 p F = F"
71.532 +| "And2 F p = F"
71.533 +| "And2 X X = X"
71.534 +
71.535 +txt {*
71.536 + \noindent Now let's look at the proof obligations generated by a
71.537 + function definition. In this case, they are:
71.538 +
71.539 + @{subgoals[display,indent=0]}\vspace{-1.2em}\hspace{3cm}\vdots\vspace{1.2em}
71.540 +
71.541 + The first subgoal expresses the completeness of the patterns. It has
71.542 + the form of an elimination rule and states that every @{term x} of
71.543 + the function's input type must match at least one of the patterns\footnote{Completeness could
71.544 + be equivalently stated as a disjunction of existential statements:
71.545 +@{term "(\<exists>p. x = (T, p)) \<or> (\<exists>p. x = (p, T)) \<or> (\<exists>p. x = (p, F)) \<or>
71.546 + (\<exists>p. x = (F, p)) \<or> (x = (X, X))"}, and you can use the method @{text atomize_elim} to get that form instead.}. If the patterns just involve
71.547 + datatypes, we can solve it with the @{text "pat_completeness"}
71.548 + method:
71.549 +*}
71.550 +
71.551 +apply pat_completeness
71.552 +
71.553 +txt {*
71.554 + The remaining subgoals express \emph{pattern compatibility}. We do
71.555 + allow that an input value matches multiple patterns, but in this
71.556 + case, the result (i.e.~the right hand sides of the equations) must
71.557 + also be equal. For each pair of two patterns, there is one such
71.558 + subgoal. Usually this needs injectivity of the constructors, which
71.559 + is used automatically by @{text "auto"}.
71.560 +*}
71.561 +
71.562 +by auto
71.563 +
71.564 +
71.565 +subsection {* Non-constructor patterns *}
71.566 +
71.567 +text {*
71.568 + Most of Isabelle's basic types take the form of inductive datatypes,
71.569 + and usually pattern matching works on the constructors of such types.
71.570 + However, this need not be always the case, and the \cmd{function}
71.571 + command handles other kind of patterns, too.
71.572 +
71.573 + One well-known instance of non-constructor patterns are
71.574 + so-called \emph{$n+k$-patterns}, which are a little controversial in
71.575 + the functional programming world. Here is the initial fibonacci
71.576 + example with $n+k$-patterns:
71.577 +*}
71.578 +
71.579 +function fib2 :: "nat \<Rightarrow> nat"
71.580 +where
71.581 + "fib2 0 = 1"
71.582 +| "fib2 1 = 1"
71.583 +| "fib2 (n + 2) = fib2 n + fib2 (Suc n)"
71.584 +
71.585 +(*<*)ML_val "goals_limit := 1"(*>*)
71.586 +txt {*
71.587 + This kind of matching is again justified by the proof of pattern
71.588 + completeness and compatibility.
71.589 + The proof obligation for pattern completeness states that every natural number is
71.590 + either @{term "0::nat"}, @{term "1::nat"} or @{term "n +
71.591 + (2::nat)"}:
71.592 +
71.593 + @{subgoals[display,indent=0]}
71.594 +
71.595 + This is an arithmetic triviality, but unfortunately the
71.596 + @{text arith} method cannot handle this specific form of an
71.597 + elimination rule. However, we can use the method @{text
71.598 + "atomize_elim"} to do an ad-hoc conversion to a disjunction of
71.599 + existentials, which can then be solved by the arithmetic decision procedure.
71.600 + Pattern compatibility and termination are automatic as usual.
71.601 +*}
71.602 +(*<*)ML_val "goals_limit := 10"(*>*)
71.603 +apply atomize_elim
71.604 +apply arith
71.605 +apply auto
71.606 +done
71.607 +termination by lexicographic_order
71.608 +text {*
71.609 + We can stretch the notion of pattern matching even more. The
71.610 + following function is not a sensible functional program, but a
71.611 + perfectly valid mathematical definition:
71.612 +*}
71.613 +
71.614 +function ev :: "nat \<Rightarrow> bool"
71.615 +where
71.616 + "ev (2 * n) = True"
71.617 +| "ev (2 * n + 1) = False"
71.618 +apply atomize_elim
71.619 +by arith+
71.620 +termination by (relation "{}") simp
71.621 +
71.622 +text {*
71.623 + This general notion of pattern matching gives you a certain freedom
71.624 + in writing down specifications. However, as always, such freedom should
71.625 + be used with care:
71.626 +
71.627 + If we leave the area of constructor
71.628 + patterns, we have effectively departed from the world of functional
71.629 + programming. This means that it is no longer possible to use the
71.630 + code generator, and expect it to generate ML code for our
71.631 + definitions. Also, such a specification might not work very well together with
71.632 + simplification. Your mileage may vary.
71.633 +*}
71.634 +
71.635 +
71.636 +subsection {* Conditional equations *}
71.637 +
71.638 +text {*
71.639 + The function package also supports conditional equations, which are
71.640 + similar to guards in a language like Haskell. Here is Euclid's
71.641 + algorithm written with conditional patterns\footnote{Note that the
71.642 + patterns are also overlapping in the base case}:
71.643 +*}
71.644 +
71.645 +function gcd :: "nat \<Rightarrow> nat \<Rightarrow> nat"
71.646 +where
71.647 + "gcd x 0 = x"
71.648 +| "gcd 0 y = y"
71.649 +| "x < y \<Longrightarrow> gcd (Suc x) (Suc y) = gcd (Suc x) (y - x)"
71.650 +| "\<not> x < y \<Longrightarrow> gcd (Suc x) (Suc y) = gcd (x - y) (Suc y)"
71.651 +by (atomize_elim, auto, arith)
71.652 +termination by lexicographic_order
71.653 +
71.654 +text {*
71.655 + By now, you can probably guess what the proof obligations for the
71.656 + pattern completeness and compatibility look like.
71.657 +
71.658 + Again, functions with conditional patterns are not supported by the
71.659 + code generator.
71.660 +*}
71.661 +
71.662 +
71.663 +subsection {* Pattern matching on strings *}
71.664 +
71.665 +text {*
71.666 + As strings (as lists of characters) are normal datatypes, pattern
71.667 + matching on them is possible, but somewhat problematic. Consider the
71.668 + following definition:
71.669 +
71.670 +\end{isamarkuptext}
71.671 +\noindent\cmd{fun} @{text "check :: \"string \<Rightarrow> bool\""}\\%
71.672 +\cmd{where}\\%
71.673 +\hspace*{2ex}@{text "\"check (''good'') = True\""}\\%
71.674 +@{text "| \"check s = False\""}
71.675 +\begin{isamarkuptext}
71.676 +
71.677 + \noindent An invocation of the above \cmd{fun} command does not
71.678 + terminate. What is the problem? Strings are lists of characters, and
71.679 + characters are a datatype with a lot of constructors. Splitting the
71.680 + catch-all pattern thus leads to an explosion of cases, which cannot
71.681 + be handled by Isabelle.
71.682 +
71.683 + There are two things we can do here. Either we write an explicit
71.684 + @{text "if"} on the right hand side, or we can use conditional patterns:
71.685 +*}
71.686 +
71.687 +function check :: "string \<Rightarrow> bool"
71.688 +where
71.689 + "check (''good'') = True"
71.690 +| "s \<noteq> ''good'' \<Longrightarrow> check s = False"
71.691 +by auto
71.692 +
71.693 +
71.694 +section {* Partiality *}
71.695 +
71.696 +text {*
71.697 + In HOL, all functions are total. A function @{term "f"} applied to
71.698 + @{term "x"} always has the value @{term "f x"}, and there is no notion
71.699 + of undefinedness.
71.700 + This is why we have to do termination
71.701 + proofs when defining functions: The proof justifies that the
71.702 + function can be defined by wellfounded recursion.
71.703 +
71.704 + However, the \cmd{function} package does support partiality to a
71.705 + certain extent. Let's look at the following function which looks
71.706 + for a zero of a given function f.
71.707 +*}
71.708 +
71.709 +function (*<*)(domintros, tailrec)(*>*)findzero :: "(nat \<Rightarrow> nat) \<Rightarrow> nat \<Rightarrow> nat"
71.710 +where
71.711 + "findzero f n = (if f n = 0 then n else findzero f (Suc n))"
71.712 +by pat_completeness auto
71.713 +(*<*)declare findzero.simps[simp del](*>*)
71.714 +
71.715 +text {*
71.716 + \noindent Clearly, any attempt of a termination proof must fail. And without
71.717 + that, we do not get the usual rules @{text "findzero.simps"} and
71.718 + @{text "findzero.induct"}. So what was the definition good for at all?
71.719 +*}
71.720 +
71.721 +subsection {* Domain predicates *}
71.722 +
71.723 +text {*
71.724 + The trick is that Isabelle has not only defined the function @{const findzero}, but also
71.725 + a predicate @{term "findzero_dom"} that characterizes the values where the function
71.726 + terminates: the \emph{domain} of the function. If we treat a
71.727 + partial function just as a total function with an additional domain
71.728 + predicate, we can derive simplification and
71.729 + induction rules as we do for total functions. They are guarded
71.730 + by domain conditions and are called @{text psimps} and @{text
71.731 + pinduct}:
71.732 +*}
71.733 +
71.734 +text {*
71.735 + \noindent\begin{minipage}{0.79\textwidth}@{thm[display,margin=85] findzero.psimps}\end{minipage}
71.736 + \hfill(@{text "findzero.psimps"})
71.737 + \vspace{1em}
71.738 +
71.739 + \noindent\begin{minipage}{0.79\textwidth}@{thm[display,margin=85] findzero.pinduct}\end{minipage}
71.740 + \hfill(@{text "findzero.pinduct"})
71.741 +*}
71.742 +
71.743 +text {*
71.744 + Remember that all we
71.745 + are doing here is use some tricks to make a total function appear
71.746 + as if it was partial. We can still write the term @{term "findzero
71.747 + (\<lambda>x. 1) 0"} and like any other term of type @{typ nat} it is equal
71.748 + to some natural number, although we might not be able to find out
71.749 + which one. The function is \emph{underdefined}.
71.750 +
71.751 + But it is defined enough to prove something interesting about it. We
71.752 + can prove that if @{term "findzero f n"}
71.753 + terminates, it indeed returns a zero of @{term f}:
71.754 +*}
71.755 +
71.756 +lemma findzero_zero: "findzero_dom (f, n) \<Longrightarrow> f (findzero f n) = 0"
71.757 +
71.758 +txt {* \noindent We apply induction as usual, but using the partial induction
71.759 + rule: *}
71.760 +
71.761 +apply (induct f n rule: findzero.pinduct)
71.762 +
71.763 +txt {* \noindent This gives the following subgoals:
71.764 +
71.765 + @{subgoals[display,indent=0]}
71.766 +
71.767 + \noindent The hypothesis in our lemma was used to satisfy the first premise in
71.768 + the induction rule. However, we also get @{term
71.769 + "findzero_dom (f, n)"} as a local assumption in the induction step. This
71.770 + allows to unfold @{term "findzero f n"} using the @{text psimps}
71.771 + rule, and the rest is trivial. Since the @{text psimps} rules carry the
71.772 + @{text "[simp]"} attribute by default, we just need a single step:
71.773 + *}
71.774 +apply simp
71.775 +done
71.776 +
71.777 +text {*
71.778 + Proofs about partial functions are often not harder than for total
71.779 + functions. Fig.~\ref{findzero_isar} shows a slightly more
71.780 + complicated proof written in Isar. It is verbose enough to show how
71.781 + partiality comes into play: From the partial induction, we get an
71.782 + additional domain condition hypothesis. Observe how this condition
71.783 + is applied when calls to @{term findzero} are unfolded.
71.784 +*}
71.785 +
71.786 +text_raw {*
71.787 +\begin{figure}
71.788 +\hrule\vspace{6pt}
71.789 +\begin{minipage}{0.8\textwidth}
71.790 +\isabellestyle{it}
71.791 +\isastyle\isamarkuptrue
71.792 +*}
71.793 +lemma "\<lbrakk>findzero_dom (f, n); x \<in> {n ..< findzero f n}\<rbrakk> \<Longrightarrow> f x \<noteq> 0"
71.794 +proof (induct rule: findzero.pinduct)
71.795 + fix f n assume dom: "findzero_dom (f, n)"
71.796 + and IH: "\<lbrakk>f n \<noteq> 0; x \<in> {Suc n ..< findzero f (Suc n)}\<rbrakk> \<Longrightarrow> f x \<noteq> 0"
71.797 + and x_range: "x \<in> {n ..< findzero f n}"
71.798 + have "f n \<noteq> 0"
71.799 + proof
71.800 + assume "f n = 0"
71.801 + with dom have "findzero f n = n" by simp
71.802 + with x_range show False by auto
71.803 + qed
71.804 +
71.805 + from x_range have "x = n \<or> x \<in> {Suc n ..< findzero f n}" by auto
71.806 + thus "f x \<noteq> 0"
71.807 + proof
71.808 + assume "x = n"
71.809 + with `f n \<noteq> 0` show ?thesis by simp
71.810 + next
71.811 + assume "x \<in> {Suc n ..< findzero f n}"
71.812 + with dom and `f n \<noteq> 0` have "x \<in> {Suc n ..< findzero f (Suc n)}" by simp
71.813 + with IH and `f n \<noteq> 0`
71.814 + show ?thesis by simp
71.815 + qed
71.816 +qed
71.817 +text_raw {*
71.818 +\isamarkupfalse\isabellestyle{tt}
71.819 +\end{minipage}\vspace{6pt}\hrule
71.820 +\caption{A proof about a partial function}\label{findzero_isar}
71.821 +\end{figure}
71.822 +*}
71.823 +
71.824 +subsection {* Partial termination proofs *}
71.825 +
71.826 +text {*
71.827 + Now that we have proved some interesting properties about our
71.828 + function, we should turn to the domain predicate and see if it is
71.829 + actually true for some values. Otherwise we would have just proved
71.830 + lemmas with @{term False} as a premise.
71.831 +
71.832 + Essentially, we need some introduction rules for @{text
71.833 + findzero_dom}. The function package can prove such domain
71.834 + introduction rules automatically. But since they are not used very
71.835 + often (they are almost never needed if the function is total), this
71.836 + functionality is disabled by default for efficiency reasons. So we have to go
71.837 + back and ask for them explicitly by passing the @{text
71.838 + "(domintros)"} option to the function package:
71.839 +
71.840 +\vspace{1ex}
71.841 +\noindent\cmd{function} @{text "(domintros) findzero :: \"(nat \<Rightarrow> nat) \<Rightarrow> nat \<Rightarrow> nat\""}\\%
71.842 +\cmd{where}\isanewline%
71.843 +\ \ \ldots\\
71.844 +
71.845 + \noindent Now the package has proved an introduction rule for @{text findzero_dom}:
71.846 +*}
71.847 +
71.848 +thm findzero.domintros
71.849 +
71.850 +text {*
71.851 + @{thm[display] findzero.domintros}
71.852 +
71.853 + Domain introduction rules allow to show that a given value lies in the
71.854 + domain of a function, if the arguments of all recursive calls
71.855 + are in the domain as well. They allow to do a \qt{single step} in a
71.856 + termination proof. Usually, you want to combine them with a suitable
71.857 + induction principle.
71.858 +
71.859 + Since our function increases its argument at recursive calls, we
71.860 + need an induction principle which works \qt{backwards}. We will use
71.861 + @{text inc_induct}, which allows to do induction from a fixed number
71.862 + \qt{downwards}:
71.863 +
71.864 + \begin{center}@{thm inc_induct}\hfill(@{text "inc_induct"})\end{center}
71.865 +
71.866 + Figure \ref{findzero_term} gives a detailed Isar proof of the fact
71.867 + that @{text findzero} terminates if there is a zero which is greater
71.868 + or equal to @{term n}. First we derive two useful rules which will
71.869 + solve the base case and the step case of the induction. The
71.870 + induction is then straightforward, except for the unusual induction
71.871 + principle.
71.872 +
71.873 +*}
71.874 +
71.875 +text_raw {*
71.876 +\begin{figure}
71.877 +\hrule\vspace{6pt}
71.878 +\begin{minipage}{0.8\textwidth}
71.879 +\isabellestyle{it}
71.880 +\isastyle\isamarkuptrue
71.881 +*}
71.882 +lemma findzero_termination:
71.883 + assumes "x \<ge> n" and "f x = 0"
71.884 + shows "findzero_dom (f, n)"
71.885 +proof -
71.886 + have base: "findzero_dom (f, x)"
71.887 + by (rule findzero.domintros) (simp add:`f x = 0`)
71.888 +
71.889 + have step: "\<And>i. findzero_dom (f, Suc i)
71.890 + \<Longrightarrow> findzero_dom (f, i)"
71.891 + by (rule findzero.domintros) simp
71.892 +
71.893 + from `x \<ge> n` show ?thesis
71.894 + proof (induct rule:inc_induct)
71.895 + show "findzero_dom (f, x)" by (rule base)
71.896 + next
71.897 + fix i assume "findzero_dom (f, Suc i)"
71.898 + thus "findzero_dom (f, i)" by (rule step)
71.899 + qed
71.900 +qed
71.901 +text_raw {*
71.902 +\isamarkupfalse\isabellestyle{tt}
71.903 +\end{minipage}\vspace{6pt}\hrule
71.904 +\caption{Termination proof for @{text findzero}}\label{findzero_term}
71.905 +\end{figure}
71.906 +*}
71.907 +
71.908 +text {*
71.909 + Again, the proof given in Fig.~\ref{findzero_term} has a lot of
71.910 + detail in order to explain the principles. Using more automation, we
71.911 + can also have a short proof:
71.912 +*}
71.913 +
71.914 +lemma findzero_termination_short:
71.915 + assumes zero: "x >= n"
71.916 + assumes [simp]: "f x = 0"
71.917 + shows "findzero_dom (f, n)"
71.918 +using zero
71.919 +by (induct rule:inc_induct) (auto intro: findzero.domintros)
71.920 +
71.921 +text {*
71.922 + \noindent It is simple to combine the partial correctness result with the
71.923 + termination lemma:
71.924 +*}
71.925 +
71.926 +lemma findzero_total_correctness:
71.927 + "f x = 0 \<Longrightarrow> f (findzero f 0) = 0"
71.928 +by (blast intro: findzero_zero findzero_termination)
71.929 +
71.930 +subsection {* Definition of the domain predicate *}
71.931 +
71.932 +text {*
71.933 + Sometimes it is useful to know what the definition of the domain
71.934 + predicate looks like. Actually, @{text findzero_dom} is just an
71.935 + abbreviation:
71.936 +
71.937 + @{abbrev[display] findzero_dom}
71.938 +
71.939 + The domain predicate is the \emph{accessible part} of a relation @{const
71.940 + findzero_rel}, which was also created internally by the function
71.941 + package. @{const findzero_rel} is just a normal
71.942 + inductive predicate, so we can inspect its definition by
71.943 + looking at the introduction rules @{text findzero_rel.intros}.
71.944 + In our case there is just a single rule:
71.945 +
71.946 + @{thm[display] findzero_rel.intros}
71.947 +
71.948 + The predicate @{const findzero_rel}
71.949 + describes the \emph{recursion relation} of the function
71.950 + definition. The recursion relation is a binary relation on
71.951 + the arguments of the function that relates each argument to its
71.952 + recursive calls. In general, there is one introduction rule for each
71.953 + recursive call.
71.954 +
71.955 + The predicate @{term "accp findzero_rel"} is the accessible part of
71.956 + that relation. An argument belongs to the accessible part, if it can
71.957 + be reached in a finite number of steps (cf.~its definition in @{text
71.958 + "Wellfounded.thy"}).
71.959 +
71.960 + Since the domain predicate is just an abbreviation, you can use
71.961 + lemmas for @{const accp} and @{const findzero_rel} directly. Some
71.962 + lemmas which are occasionally useful are @{text accpI}, @{text
71.963 + accp_downward}, and of course the introduction and elimination rules
71.964 + for the recursion relation @{text "findzero.intros"} and @{text "findzero.cases"}.
71.965 +*}
71.966 +
71.967 +(*lemma findzero_nicer_domintros:
71.968 + "f x = 0 \<Longrightarrow> findzero_dom (f, x)"
71.969 + "findzero_dom (f, Suc x) \<Longrightarrow> findzero_dom (f, x)"
71.970 +by (rule accpI, erule findzero_rel.cases, auto)+
71.971 +*)
71.972 +
71.973 +subsection {* A Useful Special Case: Tail recursion *}
71.974 +
71.975 +text {*
71.976 + The domain predicate is our trick that allows us to model partiality
71.977 + in a world of total functions. The downside of this is that we have
71.978 + to carry it around all the time. The termination proof above allowed
71.979 + us to replace the abstract @{term "findzero_dom (f, n)"} by the more
71.980 + concrete @{term "(x \<ge> n \<and> f x = (0::nat))"}, but the condition is still
71.981 + there and can only be discharged for special cases.
71.982 + In particular, the domain predicate guards the unfolding of our
71.983 + function, since it is there as a condition in the @{text psimp}
71.984 + rules.
71.985 +
71.986 + Now there is an important special case: We can actually get rid
71.987 + of the condition in the simplification rules, \emph{if the function
71.988 + is tail-recursive}. The reason is that for all tail-recursive
71.989 + equations there is a total function satisfying them, even if they
71.990 + are non-terminating.
71.991 +
71.992 +% A function is tail recursive, if each call to the function is either
71.993 +% equal
71.994 +%
71.995 +% So the outer form of the
71.996 +%
71.997 +%if it can be written in the following
71.998 +% form:
71.999 +% {term[display] "f x = (if COND x then BASE x else f (LOOP x))"}
71.1000 +
71.1001 +
71.1002 + The function package internally does the right construction and can
71.1003 + derive the unconditional simp rules, if we ask it to do so. Luckily,
71.1004 + our @{const "findzero"} function is tail-recursive, so we can just go
71.1005 + back and add another option to the \cmd{function} command:
71.1006 +
71.1007 +\vspace{1ex}
71.1008 +\noindent\cmd{function} @{text "(domintros, tailrec) findzero :: \"(nat \<Rightarrow> nat) \<Rightarrow> nat \<Rightarrow> nat\""}\\%
71.1009 +\cmd{where}\isanewline%
71.1010 +\ \ \ldots\\%
71.1011 +
71.1012 +
71.1013 + \noindent Now, we actually get unconditional simplification rules, even
71.1014 + though the function is partial:
71.1015 +*}
71.1016 +
71.1017 +thm findzero.simps
71.1018 +
71.1019 +text {*
71.1020 + @{thm[display] findzero.simps}
71.1021 +
71.1022 + \noindent Of course these would make the simplifier loop, so we better remove
71.1023 + them from the simpset:
71.1024 +*}
71.1025 +
71.1026 +declare findzero.simps[simp del]
71.1027 +
71.1028 +text {*
71.1029 + Getting rid of the domain conditions in the simplification rules is
71.1030 + not only useful because it simplifies proofs. It is also required in
71.1031 + order to use Isabelle's code generator to generate ML code
71.1032 + from a function definition.
71.1033 + Since the code generator only works with equations, it cannot be
71.1034 + used with @{text "psimp"} rules. Thus, in order to generate code for
71.1035 + partial functions, they must be defined as a tail recursion.
71.1036 + Luckily, many functions have a relatively natural tail recursive
71.1037 + definition.
71.1038 +*}
71.1039 +
71.1040 +section {* Nested recursion *}
71.1041 +
71.1042 +text {*
71.1043 + Recursive calls which are nested in one another frequently cause
71.1044 + complications, since their termination proof can depend on a partial
71.1045 + correctness property of the function itself.
71.1046 +
71.1047 + As a small example, we define the \qt{nested zero} function:
71.1048 +*}
71.1049 +
71.1050 +function nz :: "nat \<Rightarrow> nat"
71.1051 +where
71.1052 + "nz 0 = 0"
71.1053 +| "nz (Suc n) = nz (nz n)"
71.1054 +by pat_completeness auto
71.1055 +
71.1056 +text {*
71.1057 + If we attempt to prove termination using the identity measure on
71.1058 + naturals, this fails:
71.1059 +*}
71.1060 +
71.1061 +termination
71.1062 + apply (relation "measure (\<lambda>n. n)")
71.1063 + apply auto
71.1064 +
71.1065 +txt {*
71.1066 + We get stuck with the subgoal
71.1067 +
71.1068 + @{subgoals[display]}
71.1069 +
71.1070 + Of course this statement is true, since we know that @{const nz} is
71.1071 + the zero function. And in fact we have no problem proving this
71.1072 + property by induction.
71.1073 +*}
71.1074 +(*<*)oops(*>*)
71.1075 +lemma nz_is_zero: "nz_dom n \<Longrightarrow> nz n = 0"
71.1076 + by (induct rule:nz.pinduct) auto
71.1077 +
71.1078 +text {*
71.1079 + We formulate this as a partial correctness lemma with the condition
71.1080 + @{term "nz_dom n"}. This allows us to prove it with the @{text
71.1081 + pinduct} rule before we have proved termination. With this lemma,
71.1082 + the termination proof works as expected:
71.1083 +*}
71.1084 +
71.1085 +termination
71.1086 + by (relation "measure (\<lambda>n. n)") (auto simp: nz_is_zero)
71.1087 +
71.1088 +text {*
71.1089 + As a general strategy, one should prove the statements needed for
71.1090 + termination as a partial property first. Then they can be used to do
71.1091 + the termination proof. This also works for less trivial
71.1092 + examples. Figure \ref{f91} defines the 91-function, a well-known
71.1093 + challenge problem due to John McCarthy, and proves its termination.
71.1094 +*}
71.1095 +
71.1096 +text_raw {*
71.1097 +\begin{figure}
71.1098 +\hrule\vspace{6pt}
71.1099 +\begin{minipage}{0.8\textwidth}
71.1100 +\isabellestyle{it}
71.1101 +\isastyle\isamarkuptrue
71.1102 +*}
71.1103 +
71.1104 +function f91 :: "nat \<Rightarrow> nat"
71.1105 +where
71.1106 + "f91 n = (if 100 < n then n - 10 else f91 (f91 (n + 11)))"
71.1107 +by pat_completeness auto
71.1108 +
71.1109 +lemma f91_estimate:
71.1110 + assumes trm: "f91_dom n"
71.1111 + shows "n < f91 n + 11"
71.1112 +using trm by induct auto
71.1113 +
71.1114 +termination
71.1115 +proof
71.1116 + let ?R = "measure (\<lambda>x. 101 - x)"
71.1117 + show "wf ?R" ..
71.1118 +
71.1119 + fix n :: nat assume "\<not> 100 < n" -- "Assumptions for both calls"
71.1120 +
71.1121 + thus "(n + 11, n) \<in> ?R" by simp -- "Inner call"
71.1122 +
71.1123 + assume inner_trm: "f91_dom (n + 11)" -- "Outer call"
71.1124 + with f91_estimate have "n + 11 < f91 (n + 11) + 11" .
71.1125 + with `\<not> 100 < n` show "(f91 (n + 11), n) \<in> ?R" by simp
71.1126 +qed
71.1127 +
71.1128 +text_raw {*
71.1129 +\isamarkupfalse\isabellestyle{tt}
71.1130 +\end{minipage}
71.1131 +\vspace{6pt}\hrule
71.1132 +\caption{McCarthy's 91-function}\label{f91}
71.1133 +\end{figure}
71.1134 +*}
71.1135 +
71.1136 +
71.1137 +section {* Higher-Order Recursion *}
71.1138 +
71.1139 +text {*
71.1140 + Higher-order recursion occurs when recursive calls
71.1141 + are passed as arguments to higher-order combinators such as @{const
71.1142 + map}, @{term filter} etc.
71.1143 + As an example, imagine a datatype of n-ary trees:
71.1144 +*}
71.1145 +
71.1146 +datatype 'a tree =
71.1147 + Leaf 'a
71.1148 +| Branch "'a tree list"
71.1149 +
71.1150 +
71.1151 +text {* \noindent We can define a function which swaps the left and right subtrees recursively, using the
71.1152 + list functions @{const rev} and @{const map}: *}
71.1153 +
71.1154 +fun mirror :: "'a tree \<Rightarrow> 'a tree"
71.1155 +where
71.1156 + "mirror (Leaf n) = Leaf n"
71.1157 +| "mirror (Branch l) = Branch (rev (map mirror l))"
71.1158 +
71.1159 +text {*
71.1160 + Although the definition is accepted without problems, let us look at the termination proof:
71.1161 +*}
71.1162 +
71.1163 +termination proof
71.1164 + txt {*
71.1165 +
71.1166 + As usual, we have to give a wellfounded relation, such that the
71.1167 + arguments of the recursive calls get smaller. But what exactly are
71.1168 + the arguments of the recursive calls when mirror is given as an
71.1169 + argument to @{const map}? Isabelle gives us the
71.1170 + subgoals
71.1171 +
71.1172 + @{subgoals[display,indent=0]}
71.1173 +
71.1174 + So the system seems to know that @{const map} only
71.1175 + applies the recursive call @{term "mirror"} to elements
71.1176 + of @{term "l"}, which is essential for the termination proof.
71.1177 +
71.1178 + This knowledge about @{const map} is encoded in so-called congruence rules,
71.1179 + which are special theorems known to the \cmd{function} command. The
71.1180 + rule for @{const map} is
71.1181 +
71.1182 + @{thm[display] map_cong}
71.1183 +
71.1184 + You can read this in the following way: Two applications of @{const
71.1185 + map} are equal, if the list arguments are equal and the functions
71.1186 + coincide on the elements of the list. This means that for the value
71.1187 + @{term "map f l"} we only have to know how @{term f} behaves on
71.1188 + the elements of @{term l}.
71.1189 +
71.1190 + Usually, one such congruence rule is
71.1191 + needed for each higher-order construct that is used when defining
71.1192 + new functions. In fact, even basic functions like @{const
71.1193 + If} and @{const Let} are handled by this mechanism. The congruence
71.1194 + rule for @{const If} states that the @{text then} branch is only
71.1195 + relevant if the condition is true, and the @{text else} branch only if it
71.1196 + is false:
71.1197 +
71.1198 + @{thm[display] if_cong}
71.1199 +
71.1200 + Congruence rules can be added to the
71.1201 + function package by giving them the @{term fundef_cong} attribute.
71.1202 +
71.1203 + The constructs that are predefined in Isabelle, usually
71.1204 + come with the respective congruence rules.
71.1205 + But if you define your own higher-order functions, you may have to
71.1206 + state and prove the required congruence rules yourself, if you want to use your
71.1207 + functions in recursive definitions.
71.1208 +*}
71.1209 +(*<*)oops(*>*)
71.1210 +
71.1211 +subsection {* Congruence Rules and Evaluation Order *}
71.1212 +
71.1213 +text {*
71.1214 + Higher order logic differs from functional programming languages in
71.1215 + that it has no built-in notion of evaluation order. A program is
71.1216 + just a set of equations, and it is not specified how they must be
71.1217 + evaluated.
71.1218 +
71.1219 + However for the purpose of function definition, we must talk about
71.1220 + evaluation order implicitly, when we reason about termination.
71.1221 + Congruence rules express that a certain evaluation order is
71.1222 + consistent with the logical definition.
71.1223 +
71.1224 + Consider the following function.
71.1225 +*}
71.1226 +
71.1227 +function f :: "nat \<Rightarrow> bool"
71.1228 +where
71.1229 + "f n = (n = 0 \<or> f (n - 1))"
71.1230 +(*<*)by pat_completeness auto(*>*)
71.1231 +
71.1232 +text {*
71.1233 + For this definition, the termination proof fails. The default configuration
71.1234 + specifies no congruence rule for disjunction. We have to add a
71.1235 + congruence rule that specifies left-to-right evaluation order:
71.1236 +
71.1237 + \vspace{1ex}
71.1238 + \noindent @{thm disj_cong}\hfill(@{text "disj_cong"})
71.1239 + \vspace{1ex}
71.1240 +
71.1241 + Now the definition works without problems. Note how the termination
71.1242 + proof depends on the extra condition that we get from the congruence
71.1243 + rule.
71.1244 +
71.1245 + However, as evaluation is not a hard-wired concept, we
71.1246 + could just turn everything around by declaring a different
71.1247 + congruence rule. Then we can make the reverse definition:
71.1248 +*}
71.1249 +
71.1250 +lemma disj_cong2[fundef_cong]:
71.1251 + "(\<not> Q' \<Longrightarrow> P = P') \<Longrightarrow> (Q = Q') \<Longrightarrow> (P \<or> Q) = (P' \<or> Q')"
71.1252 + by blast
71.1253 +
71.1254 +fun f' :: "nat \<Rightarrow> bool"
71.1255 +where
71.1256 + "f' n = (f' (n - 1) \<or> n = 0)"
71.1257 +
71.1258 +text {*
71.1259 + \noindent These examples show that, in general, there is no \qt{best} set of
71.1260 + congruence rules.
71.1261 +
71.1262 + However, such tweaking should rarely be necessary in
71.1263 + practice, as most of the time, the default set of congruence rules
71.1264 + works well.
71.1265 +*}
71.1266 +
71.1267 +end
72.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
72.2 +++ b/doc-src/Functions/Thy/ROOT.ML Wed Mar 04 11:05:29 2009 +0100
72.3 @@ -0,0 +1,4 @@
72.4 +
72.5 +(* $Id$ *)
72.6 +
72.7 +use_thy "Functions";
73.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
73.2 +++ b/doc-src/Functions/Thy/document/Functions.tex Wed Mar 04 11:05:29 2009 +0100
73.3 @@ -0,0 +1,1985 @@
73.4 +%
73.5 +\begin{isabellebody}%
73.6 +\def\isabellecontext{Functions}%
73.7 +%
73.8 +\isadelimtheory
73.9 +\isanewline
73.10 +\isanewline
73.11 +%
73.12 +\endisadelimtheory
73.13 +%
73.14 +\isatagtheory
73.15 +\isacommand{theory}\isamarkupfalse%
73.16 +\ Functions\isanewline
73.17 +\isakeyword{imports}\ Main\isanewline
73.18 +\isakeyword{begin}%
73.19 +\endisatagtheory
73.20 +{\isafoldtheory}%
73.21 +%
73.22 +\isadelimtheory
73.23 +%
73.24 +\endisadelimtheory
73.25 +%
73.26 +\isamarkupsection{Function Definitions for Dummies%
73.27 +}
73.28 +\isamarkuptrue%
73.29 +%
73.30 +\begin{isamarkuptext}%
73.31 +In most cases, defining a recursive function is just as simple as other definitions:%
73.32 +\end{isamarkuptext}%
73.33 +\isamarkuptrue%
73.34 +\isacommand{fun}\isamarkupfalse%
73.35 +\ fib\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymRightarrow}\ nat{\isachardoublequoteclose}\isanewline
73.36 +\isakeyword{where}\isanewline
73.37 +\ \ {\isachardoublequoteopen}fib\ {\isadigit{0}}\ {\isacharequal}\ {\isadigit{1}}{\isachardoublequoteclose}\isanewline
73.38 +{\isacharbar}\ {\isachardoublequoteopen}fib\ {\isacharparenleft}Suc\ {\isadigit{0}}{\isacharparenright}\ {\isacharequal}\ {\isadigit{1}}{\isachardoublequoteclose}\isanewline
73.39 +{\isacharbar}\ {\isachardoublequoteopen}fib\ {\isacharparenleft}Suc\ {\isacharparenleft}Suc\ n{\isacharparenright}{\isacharparenright}\ {\isacharequal}\ fib\ n\ {\isacharplus}\ fib\ {\isacharparenleft}Suc\ n{\isacharparenright}{\isachardoublequoteclose}%
73.40 +\begin{isamarkuptext}%
73.41 +The syntax is rather self-explanatory: We introduce a function by
73.42 + giving its name, its type,
73.43 + and a set of defining recursive equations.
73.44 + If we leave out the type, the most general type will be
73.45 + inferred, which can sometimes lead to surprises: Since both \isa{{\isadigit{1}}} and \isa{{\isacharplus}} are overloaded, we would end up
73.46 + with \isa{fib\ {\isacharcolon}{\isacharcolon}\ nat\ {\isasymRightarrow}\ {\isacharprime}a{\isacharcolon}{\isacharcolon}{\isacharbraceleft}one{\isacharcomma}plus{\isacharbraceright}}.%
73.47 +\end{isamarkuptext}%
73.48 +\isamarkuptrue%
73.49 +%
73.50 +\begin{isamarkuptext}%
73.51 +The function always terminates, since its argument gets smaller in
73.52 + every recursive call.
73.53 + Since HOL is a logic of total functions, termination is a
73.54 + fundamental requirement to prevent inconsistencies\footnote{From the
73.55 + \qt{definition} \isa{f{\isacharparenleft}n{\isacharparenright}\ {\isacharequal}\ f{\isacharparenleft}n{\isacharparenright}\ {\isacharplus}\ {\isadigit{1}}} we could prove
73.56 + \isa{{\isadigit{0}}\ {\isacharequal}\ {\isadigit{1}}} by subtracting \isa{f{\isacharparenleft}n{\isacharparenright}} on both sides.}.
73.57 + Isabelle tries to prove termination automatically when a definition
73.58 + is made. In \S\ref{termination}, we will look at cases where this
73.59 + fails and see what to do then.%
73.60 +\end{isamarkuptext}%
73.61 +\isamarkuptrue%
73.62 +%
73.63 +\isamarkupsubsection{Pattern matching%
73.64 +}
73.65 +\isamarkuptrue%
73.66 +%
73.67 +\begin{isamarkuptext}%
73.68 +\label{patmatch}
73.69 + Like in functional programming, we can use pattern matching to
73.70 + define functions. At the moment we will only consider \emph{constructor
73.71 + patterns}, which only consist of datatype constructors and
73.72 + variables. Furthermore, patterns must be linear, i.e.\ all variables
73.73 + on the left hand side of an equation must be distinct. In
73.74 + \S\ref{genpats} we discuss more general pattern matching.
73.75 +
73.76 + If patterns overlap, the order of the equations is taken into
73.77 + account. The following function inserts a fixed element between any
73.78 + two elements of a list:%
73.79 +\end{isamarkuptext}%
73.80 +\isamarkuptrue%
73.81 +\isacommand{fun}\isamarkupfalse%
73.82 +\ sep\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharprime}a\ {\isasymRightarrow}\ {\isacharprime}a\ list\ {\isasymRightarrow}\ {\isacharprime}a\ list{\isachardoublequoteclose}\isanewline
73.83 +\isakeyword{where}\isanewline
73.84 +\ \ {\isachardoublequoteopen}sep\ a\ {\isacharparenleft}x{\isacharhash}y{\isacharhash}xs{\isacharparenright}\ {\isacharequal}\ x\ {\isacharhash}\ a\ {\isacharhash}\ sep\ a\ {\isacharparenleft}y\ {\isacharhash}\ xs{\isacharparenright}{\isachardoublequoteclose}\isanewline
73.85 +{\isacharbar}\ {\isachardoublequoteopen}sep\ a\ xs\ \ \ \ \ \ \ {\isacharequal}\ xs{\isachardoublequoteclose}%
73.86 +\begin{isamarkuptext}%
73.87 +Overlapping patterns are interpreted as \qt{increments} to what is
73.88 + already there: The second equation is only meant for the cases where
73.89 + the first one does not match. Consequently, Isabelle replaces it
73.90 + internally by the remaining cases, making the patterns disjoint:%
73.91 +\end{isamarkuptext}%
73.92 +\isamarkuptrue%
73.93 +\isacommand{thm}\isamarkupfalse%
73.94 +\ sep{\isachardot}simps%
73.95 +\begin{isamarkuptext}%
73.96 +\begin{isabelle}%
73.97 +sep\ a\ {\isacharparenleft}x\ {\isacharhash}\ y\ {\isacharhash}\ xs{\isacharparenright}\ {\isacharequal}\ x\ {\isacharhash}\ a\ {\isacharhash}\ sep\ a\ {\isacharparenleft}y\ {\isacharhash}\ xs{\isacharparenright}\isasep\isanewline%
73.98 +sep\ a\ {\isacharbrackleft}{\isacharbrackright}\ {\isacharequal}\ {\isacharbrackleft}{\isacharbrackright}\isasep\isanewline%
73.99 +sep\ a\ {\isacharbrackleft}v{\isacharbrackright}\ {\isacharequal}\ {\isacharbrackleft}v{\isacharbrackright}%
73.100 +\end{isabelle}%
73.101 +\end{isamarkuptext}%
73.102 +\isamarkuptrue%
73.103 +%
73.104 +\begin{isamarkuptext}%
73.105 +\noindent The equations from function definitions are automatically used in
73.106 + simplification:%
73.107 +\end{isamarkuptext}%
73.108 +\isamarkuptrue%
73.109 +\isacommand{lemma}\isamarkupfalse%
73.110 +\ {\isachardoublequoteopen}sep\ {\isadigit{0}}\ {\isacharbrackleft}{\isadigit{1}}{\isacharcomma}\ {\isadigit{2}}{\isacharcomma}\ {\isadigit{3}}{\isacharbrackright}\ {\isacharequal}\ {\isacharbrackleft}{\isadigit{1}}{\isacharcomma}\ {\isadigit{0}}{\isacharcomma}\ {\isadigit{2}}{\isacharcomma}\ {\isadigit{0}}{\isacharcomma}\ {\isadigit{3}}{\isacharbrackright}{\isachardoublequoteclose}\isanewline
73.111 +%
73.112 +\isadelimproof
73.113 +%
73.114 +\endisadelimproof
73.115 +%
73.116 +\isatagproof
73.117 +\isacommand{by}\isamarkupfalse%
73.118 +\ simp%
73.119 +\endisatagproof
73.120 +{\isafoldproof}%
73.121 +%
73.122 +\isadelimproof
73.123 +%
73.124 +\endisadelimproof
73.125 +%
73.126 +\isamarkupsubsection{Induction%
73.127 +}
73.128 +\isamarkuptrue%
73.129 +%
73.130 +\begin{isamarkuptext}%
73.131 +Isabelle provides customized induction rules for recursive
73.132 + functions. These rules follow the recursive structure of the
73.133 + definition. Here is the rule \isa{sep{\isachardot}induct} arising from the
73.134 + above definition of \isa{sep}:
73.135 +
73.136 + \begin{isabelle}%
73.137 +{\isasymlbrakk}{\isasymAnd}a\ x\ y\ xs{\isachardot}\ {\isacharquery}P\ a\ {\isacharparenleft}y\ {\isacharhash}\ xs{\isacharparenright}\ {\isasymLongrightarrow}\ {\isacharquery}P\ a\ {\isacharparenleft}x\ {\isacharhash}\ y\ {\isacharhash}\ xs{\isacharparenright}{\isacharsemicolon}\ {\isasymAnd}a{\isachardot}\ {\isacharquery}P\ a\ {\isacharbrackleft}{\isacharbrackright}{\isacharsemicolon}\ {\isasymAnd}a\ v{\isachardot}\ {\isacharquery}P\ a\ {\isacharbrackleft}v{\isacharbrackright}{\isasymrbrakk}\isanewline
73.138 +{\isasymLongrightarrow}\ {\isacharquery}P\ {\isacharquery}a{\isadigit{0}}{\isachardot}{\isadigit{0}}\ {\isacharquery}a{\isadigit{1}}{\isachardot}{\isadigit{0}}%
73.139 +\end{isabelle}
73.140 +
73.141 + We have a step case for list with at least two elements, and two
73.142 + base cases for the zero- and the one-element list. Here is a simple
73.143 + proof about \isa{sep} and \isa{map}%
73.144 +\end{isamarkuptext}%
73.145 +\isamarkuptrue%
73.146 +\isacommand{lemma}\isamarkupfalse%
73.147 +\ {\isachardoublequoteopen}map\ f\ {\isacharparenleft}sep\ x\ ys{\isacharparenright}\ {\isacharequal}\ sep\ {\isacharparenleft}f\ x{\isacharparenright}\ {\isacharparenleft}map\ f\ ys{\isacharparenright}{\isachardoublequoteclose}\isanewline
73.148 +%
73.149 +\isadelimproof
73.150 +%
73.151 +\endisadelimproof
73.152 +%
73.153 +\isatagproof
73.154 +\isacommand{apply}\isamarkupfalse%
73.155 +\ {\isacharparenleft}induct\ x\ ys\ rule{\isacharcolon}\ sep{\isachardot}induct{\isacharparenright}%
73.156 +\begin{isamarkuptxt}%
73.157 +We get three cases, like in the definition.
73.158 +
73.159 + \begin{isabelle}%
73.160 +\ {\isadigit{1}}{\isachardot}\ {\isasymAnd}a\ x\ y\ xs{\isachardot}\isanewline
73.161 +\isaindent{\ {\isadigit{1}}{\isachardot}\ \ \ \ }map\ f\ {\isacharparenleft}sep\ a\ {\isacharparenleft}y\ {\isacharhash}\ xs{\isacharparenright}{\isacharparenright}\ {\isacharequal}\ sep\ {\isacharparenleft}f\ a{\isacharparenright}\ {\isacharparenleft}map\ f\ {\isacharparenleft}y\ {\isacharhash}\ xs{\isacharparenright}{\isacharparenright}\ {\isasymLongrightarrow}\isanewline
73.162 +\isaindent{\ {\isadigit{1}}{\isachardot}\ \ \ \ }map\ f\ {\isacharparenleft}sep\ a\ {\isacharparenleft}x\ {\isacharhash}\ y\ {\isacharhash}\ xs{\isacharparenright}{\isacharparenright}\ {\isacharequal}\ sep\ {\isacharparenleft}f\ a{\isacharparenright}\ {\isacharparenleft}map\ f\ {\isacharparenleft}x\ {\isacharhash}\ y\ {\isacharhash}\ xs{\isacharparenright}{\isacharparenright}\isanewline
73.163 +\ {\isadigit{2}}{\isachardot}\ {\isasymAnd}a{\isachardot}\ map\ f\ {\isacharparenleft}sep\ a\ {\isacharbrackleft}{\isacharbrackright}{\isacharparenright}\ {\isacharequal}\ sep\ {\isacharparenleft}f\ a{\isacharparenright}\ {\isacharparenleft}map\ f\ {\isacharbrackleft}{\isacharbrackright}{\isacharparenright}\isanewline
73.164 +\ {\isadigit{3}}{\isachardot}\ {\isasymAnd}a\ v{\isachardot}\ map\ f\ {\isacharparenleft}sep\ a\ {\isacharbrackleft}v{\isacharbrackright}{\isacharparenright}\ {\isacharequal}\ sep\ {\isacharparenleft}f\ a{\isacharparenright}\ {\isacharparenleft}map\ f\ {\isacharbrackleft}v{\isacharbrackright}{\isacharparenright}%
73.165 +\end{isabelle}%
73.166 +\end{isamarkuptxt}%
73.167 +\isamarkuptrue%
73.168 +\isacommand{apply}\isamarkupfalse%
73.169 +\ auto\ \isanewline
73.170 +\isacommand{done}\isamarkupfalse%
73.171 +%
73.172 +\endisatagproof
73.173 +{\isafoldproof}%
73.174 +%
73.175 +\isadelimproof
73.176 +%
73.177 +\endisadelimproof
73.178 +%
73.179 +\begin{isamarkuptext}%
73.180 +With the \cmd{fun} command, you can define about 80\% of the
73.181 + functions that occur in practice. The rest of this tutorial explains
73.182 + the remaining 20\%.%
73.183 +\end{isamarkuptext}%
73.184 +\isamarkuptrue%
73.185 +%
73.186 +\isamarkupsection{fun vs.\ function%
73.187 +}
73.188 +\isamarkuptrue%
73.189 +%
73.190 +\begin{isamarkuptext}%
73.191 +The \cmd{fun} command provides a
73.192 + convenient shorthand notation for simple function definitions. In
73.193 + this mode, Isabelle tries to solve all the necessary proof obligations
73.194 + automatically. If any proof fails, the definition is
73.195 + rejected. This can either mean that the definition is indeed faulty,
73.196 + or that the default proof procedures are just not smart enough (or
73.197 + rather: not designed) to handle the definition.
73.198 +
73.199 + By expanding the abbreviation to the more verbose \cmd{function} command, these proof obligations become visible and can be analyzed or
73.200 + solved manually. The expansion from \cmd{fun} to \cmd{function} is as follows:
73.201 +
73.202 +\end{isamarkuptext}
73.203 +
73.204 +
73.205 +\[\left[\;\begin{minipage}{0.25\textwidth}\vspace{6pt}
73.206 +\cmd{fun} \isa{f\ {\isacharcolon}{\isacharcolon}\ {\isasymtau}}\\%
73.207 +\cmd{where}\\%
73.208 +\hspace*{2ex}{\it equations}\\%
73.209 +\hspace*{2ex}\vdots\vspace*{6pt}
73.210 +\end{minipage}\right]
73.211 +\quad\equiv\quad
73.212 +\left[\;\begin{minipage}{0.48\textwidth}\vspace{6pt}
73.213 +\cmd{function} \isa{{\isacharparenleft}}\cmd{sequential}\isa{{\isacharparenright}\ f\ {\isacharcolon}{\isacharcolon}\ {\isasymtau}}\\%
73.214 +\cmd{where}\\%
73.215 +\hspace*{2ex}{\it equations}\\%
73.216 +\hspace*{2ex}\vdots\\%
73.217 +\cmd{by} \isa{pat{\isacharunderscore}completeness\ auto}\\%
73.218 +\cmd{termination by} \isa{lexicographic{\isacharunderscore}order}\vspace{6pt}
73.219 +\end{minipage}
73.220 +\right]\]
73.221 +
73.222 +\begin{isamarkuptext}
73.223 + \vspace*{1em}
73.224 + \noindent Some details have now become explicit:
73.225 +
73.226 + \begin{enumerate}
73.227 + \item The \cmd{sequential} option enables the preprocessing of
73.228 + pattern overlaps which we already saw. Without this option, the equations
73.229 + must already be disjoint and complete. The automatic completion only
73.230 + works with constructor patterns.
73.231 +
73.232 + \item A function definition produces a proof obligation which
73.233 + expresses completeness and compatibility of patterns (we talk about
73.234 + this later). The combination of the methods \isa{pat{\isacharunderscore}completeness} and
73.235 + \isa{auto} is used to solve this proof obligation.
73.236 +
73.237 + \item A termination proof follows the definition, started by the
73.238 + \cmd{termination} command. This will be explained in \S\ref{termination}.
73.239 + \end{enumerate}
73.240 + Whenever a \cmd{fun} command fails, it is usually a good idea to
73.241 + expand the syntax to the more verbose \cmd{function} form, to see
73.242 + what is actually going on.%
73.243 +\end{isamarkuptext}%
73.244 +\isamarkuptrue%
73.245 +%
73.246 +\isamarkupsection{Termination%
73.247 +}
73.248 +\isamarkuptrue%
73.249 +%
73.250 +\begin{isamarkuptext}%
73.251 +\label{termination}
73.252 + The method \isa{lexicographic{\isacharunderscore}order} is the default method for
73.253 + termination proofs. It can prove termination of a
73.254 + certain class of functions by searching for a suitable lexicographic
73.255 + combination of size measures. Of course, not all functions have such
73.256 + a simple termination argument. For them, we can specify the termination
73.257 + relation manually.%
73.258 +\end{isamarkuptext}%
73.259 +\isamarkuptrue%
73.260 +%
73.261 +\isamarkupsubsection{The {\tt relation} method%
73.262 +}
73.263 +\isamarkuptrue%
73.264 +%
73.265 +\begin{isamarkuptext}%
73.266 +Consider the following function, which sums up natural numbers up to
73.267 + \isa{N}, using a counter \isa{i}:%
73.268 +\end{isamarkuptext}%
73.269 +\isamarkuptrue%
73.270 +\isacommand{function}\isamarkupfalse%
73.271 +\ sum\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymRightarrow}\ nat\ {\isasymRightarrow}\ nat{\isachardoublequoteclose}\isanewline
73.272 +\isakeyword{where}\isanewline
73.273 +\ \ {\isachardoublequoteopen}sum\ i\ N\ {\isacharequal}\ {\isacharparenleft}if\ i\ {\isachargreater}\ N\ then\ {\isadigit{0}}\ else\ i\ {\isacharplus}\ sum\ {\isacharparenleft}Suc\ i{\isacharparenright}\ N{\isacharparenright}{\isachardoublequoteclose}\isanewline
73.274 +%
73.275 +\isadelimproof
73.276 +%
73.277 +\endisadelimproof
73.278 +%
73.279 +\isatagproof
73.280 +\isacommand{by}\isamarkupfalse%
73.281 +\ pat{\isacharunderscore}completeness\ auto%
73.282 +\endisatagproof
73.283 +{\isafoldproof}%
73.284 +%
73.285 +\isadelimproof
73.286 +%
73.287 +\endisadelimproof
73.288 +%
73.289 +\begin{isamarkuptext}%
73.290 +\noindent The \isa{lexicographic{\isacharunderscore}order} method fails on this example, because none of the
73.291 + arguments decreases in the recursive call, with respect to the standard size ordering.
73.292 + To prove termination manually, we must provide a custom wellfounded relation.
73.293 +
73.294 + The termination argument for \isa{sum} is based on the fact that
73.295 + the \emph{difference} between \isa{i} and \isa{N} gets
73.296 + smaller in every step, and that the recursion stops when \isa{i}
73.297 + is greater than \isa{N}. Phrased differently, the expression
73.298 + \isa{N\ {\isacharplus}\ {\isadigit{1}}\ {\isacharminus}\ i} always decreases.
73.299 +
73.300 + We can use this expression as a measure function suitable to prove termination.%
73.301 +\end{isamarkuptext}%
73.302 +\isamarkuptrue%
73.303 +\isacommand{termination}\isamarkupfalse%
73.304 +\ sum\isanewline
73.305 +%
73.306 +\isadelimproof
73.307 +%
73.308 +\endisadelimproof
73.309 +%
73.310 +\isatagproof
73.311 +\isacommand{apply}\isamarkupfalse%
73.312 +\ {\isacharparenleft}relation\ {\isachardoublequoteopen}measure\ {\isacharparenleft}{\isasymlambda}{\isacharparenleft}i{\isacharcomma}N{\isacharparenright}{\isachardot}\ N\ {\isacharplus}\ {\isadigit{1}}\ {\isacharminus}\ i{\isacharparenright}{\isachardoublequoteclose}{\isacharparenright}%
73.313 +\begin{isamarkuptxt}%
73.314 +The \cmd{termination} command sets up the termination goal for the
73.315 + specified function \isa{sum}. If the function name is omitted, it
73.316 + implicitly refers to the last function definition.
73.317 +
73.318 + The \isa{relation} method takes a relation of
73.319 + type \isa{{\isacharparenleft}{\isacharprime}a\ {\isasymtimes}\ {\isacharprime}a{\isacharparenright}\ set}, where \isa{{\isacharprime}a} is the argument type of
73.320 + the function. If the function has multiple curried arguments, then
73.321 + these are packed together into a tuple, as it happened in the above
73.322 + example.
73.323 +
73.324 + The predefined function \isa{{\isachardoublequote}measure\ {\isacharcolon}{\isacharcolon}\ {\isacharparenleft}{\isacharprime}a\ {\isasymRightarrow}\ nat{\isacharparenright}\ {\isasymRightarrow}\ {\isacharparenleft}{\isacharprime}a\ {\isasymtimes}\ {\isacharprime}a{\isacharparenright}\ set{\isachardoublequote}} constructs a
73.325 + wellfounded relation from a mapping into the natural numbers (a
73.326 + \emph{measure function}).
73.327 +
73.328 + After the invocation of \isa{relation}, we must prove that (a)
73.329 + the relation we supplied is wellfounded, and (b) that the arguments
73.330 + of recursive calls indeed decrease with respect to the
73.331 + relation:
73.332 +
73.333 + \begin{isabelle}%
73.334 +\ {\isadigit{1}}{\isachardot}\ wf\ {\isacharparenleft}measure\ {\isacharparenleft}{\isasymlambda}{\isacharparenleft}i{\isacharcomma}\ N{\isacharparenright}{\isachardot}\ N\ {\isacharplus}\ {\isadigit{1}}\ {\isacharminus}\ i{\isacharparenright}{\isacharparenright}\isanewline
73.335 +\ {\isadigit{2}}{\isachardot}\ {\isasymAnd}i\ N{\isachardot}\ {\isasymnot}\ N\ {\isacharless}\ i\ {\isasymLongrightarrow}\ {\isacharparenleft}{\isacharparenleft}Suc\ i{\isacharcomma}\ N{\isacharparenright}{\isacharcomma}\ i{\isacharcomma}\ N{\isacharparenright}\ {\isasymin}\ measure\ {\isacharparenleft}{\isasymlambda}{\isacharparenleft}i{\isacharcomma}\ N{\isacharparenright}{\isachardot}\ N\ {\isacharplus}\ {\isadigit{1}}\ {\isacharminus}\ i{\isacharparenright}%
73.336 +\end{isabelle}
73.337 +
73.338 + These goals are all solved by \isa{auto}:%
73.339 +\end{isamarkuptxt}%
73.340 +\isamarkuptrue%
73.341 +\isacommand{apply}\isamarkupfalse%
73.342 +\ auto\isanewline
73.343 +\isacommand{done}\isamarkupfalse%
73.344 +%
73.345 +\endisatagproof
73.346 +{\isafoldproof}%
73.347 +%
73.348 +\isadelimproof
73.349 +%
73.350 +\endisadelimproof
73.351 +%
73.352 +\begin{isamarkuptext}%
73.353 +Let us complicate the function a little, by adding some more
73.354 + recursive calls:%
73.355 +\end{isamarkuptext}%
73.356 +\isamarkuptrue%
73.357 +\isacommand{function}\isamarkupfalse%
73.358 +\ foo\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymRightarrow}\ nat\ {\isasymRightarrow}\ nat{\isachardoublequoteclose}\isanewline
73.359 +\isakeyword{where}\isanewline
73.360 +\ \ {\isachardoublequoteopen}foo\ i\ N\ {\isacharequal}\ {\isacharparenleft}if\ i\ {\isachargreater}\ N\ \isanewline
73.361 +\ \ \ \ \ \ \ \ \ \ \ \ \ \ then\ {\isacharparenleft}if\ N\ {\isacharequal}\ {\isadigit{0}}\ then\ {\isadigit{0}}\ else\ foo\ {\isadigit{0}}\ {\isacharparenleft}N\ {\isacharminus}\ {\isadigit{1}}{\isacharparenright}{\isacharparenright}\isanewline
73.362 +\ \ \ \ \ \ \ \ \ \ \ \ \ \ else\ i\ {\isacharplus}\ foo\ {\isacharparenleft}Suc\ i{\isacharparenright}\ N{\isacharparenright}{\isachardoublequoteclose}\isanewline
73.363 +%
73.364 +\isadelimproof
73.365 +%
73.366 +\endisadelimproof
73.367 +%
73.368 +\isatagproof
73.369 +\isacommand{by}\isamarkupfalse%
73.370 +\ pat{\isacharunderscore}completeness\ auto%
73.371 +\endisatagproof
73.372 +{\isafoldproof}%
73.373 +%
73.374 +\isadelimproof
73.375 +%
73.376 +\endisadelimproof
73.377 +%
73.378 +\begin{isamarkuptext}%
73.379 +When \isa{i} has reached \isa{N}, it starts at zero again
73.380 + and \isa{N} is decremented.
73.381 + This corresponds to a nested
73.382 + loop where one index counts up and the other down. Termination can
73.383 + be proved using a lexicographic combination of two measures, namely
73.384 + the value of \isa{N} and the above difference. The \isa{measures} combinator generalizes \isa{measure} by taking a
73.385 + list of measure functions.%
73.386 +\end{isamarkuptext}%
73.387 +\isamarkuptrue%
73.388 +\isacommand{termination}\isamarkupfalse%
73.389 +\ \isanewline
73.390 +%
73.391 +\isadelimproof
73.392 +%
73.393 +\endisadelimproof
73.394 +%
73.395 +\isatagproof
73.396 +\isacommand{by}\isamarkupfalse%
73.397 +\ {\isacharparenleft}relation\ {\isachardoublequoteopen}measures\ {\isacharbrackleft}{\isasymlambda}{\isacharparenleft}i{\isacharcomma}\ N{\isacharparenright}{\isachardot}\ N{\isacharcomma}\ {\isasymlambda}{\isacharparenleft}i{\isacharcomma}N{\isacharparenright}{\isachardot}\ N\ {\isacharplus}\ {\isadigit{1}}\ {\isacharminus}\ i{\isacharbrackright}{\isachardoublequoteclose}{\isacharparenright}\ auto%
73.398 +\endisatagproof
73.399 +{\isafoldproof}%
73.400 +%
73.401 +\isadelimproof
73.402 +%
73.403 +\endisadelimproof
73.404 +%
73.405 +\isamarkupsubsection{How \isa{lexicographic{\isacharunderscore}order} works%
73.406 +}
73.407 +\isamarkuptrue%
73.408 +%
73.409 +\begin{isamarkuptext}%
73.410 +To see how the automatic termination proofs work, let's look at an
73.411 + example where it fails\footnote{For a detailed discussion of the
73.412 + termination prover, see \cite{bulwahnKN07}}:
73.413 +
73.414 +\end{isamarkuptext}
73.415 +\cmd{fun} \isa{fails\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequote}nat\ {\isasymRightarrow}\ nat\ list\ {\isasymRightarrow}\ nat{\isachardoublequote}}\\%
73.416 +\cmd{where}\\%
73.417 +\hspace*{2ex}\isa{{\isachardoublequote}fails\ a\ {\isacharbrackleft}{\isacharbrackright}\ {\isacharequal}\ a{\isachardoublequote}}\\%
73.418 +|\hspace*{1.5ex}\isa{{\isachardoublequote}fails\ a\ {\isacharparenleft}x{\isacharhash}xs{\isacharparenright}\ {\isacharequal}\ fails\ {\isacharparenleft}x\ {\isacharplus}\ a{\isacharparenright}\ {\isacharparenleft}x{\isacharhash}xs{\isacharparenright}{\isachardoublequote}}\\
73.419 +\begin{isamarkuptext}
73.420 +
73.421 +\noindent Isabelle responds with the following error:
73.422 +
73.423 +\begin{isabelle}
73.424 +*** Unfinished subgoals:\newline
73.425 +*** (a, 1, <):\newline
73.426 +*** \ 1.~\isa{{\isasymAnd}x{\isachardot}\ x\ {\isacharequal}\ {\isadigit{0}}}\newline
73.427 +*** (a, 1, <=):\newline
73.428 +*** \ 1.~False\newline
73.429 +*** (a, 2, <):\newline
73.430 +*** \ 1.~False\newline
73.431 +*** Calls:\newline
73.432 +*** a) \isa{{\isacharparenleft}a{\isacharcomma}\ x\ {\isacharhash}\ xs{\isacharparenright}\ {\isacharminus}{\isacharminus}{\isachargreater}{\isachargreater}\ {\isacharparenleft}x\ {\isacharplus}\ a{\isacharcomma}\ x\ {\isacharhash}\ xs{\isacharparenright}}\newline
73.433 +*** Measures:\newline
73.434 +*** 1) \isa{{\isasymlambda}x{\isachardot}\ size\ {\isacharparenleft}fst\ x{\isacharparenright}}\newline
73.435 +*** 2) \isa{{\isasymlambda}x{\isachardot}\ size\ {\isacharparenleft}snd\ x{\isacharparenright}}\newline
73.436 +*** Result matrix:\newline
73.437 +*** \ \ \ \ 1\ \ 2 \newline
73.438 +*** a: ? <= \newline
73.439 +*** Could not find lexicographic termination order.\newline
73.440 +*** At command "fun".\newline
73.441 +\end{isabelle}%
73.442 +\end{isamarkuptext}%
73.443 +\isamarkuptrue%
73.444 +%
73.445 +\begin{isamarkuptext}%
73.446 +The key to this error message is the matrix at the bottom. The rows
73.447 + of that matrix correspond to the different recursive calls (In our
73.448 + case, there is just one). The columns are the function's arguments
73.449 + (expressed through different measure functions, which map the
73.450 + argument tuple to a natural number).
73.451 +
73.452 + The contents of the matrix summarize what is known about argument
73.453 + descents: The second argument has a weak descent (\isa{{\isacharless}{\isacharequal}}) at the
73.454 + recursive call, and for the first argument nothing could be proved,
73.455 + which is expressed by \isa{{\isacharquery}}. In general, there are the values
73.456 + \isa{{\isacharless}}, \isa{{\isacharless}{\isacharequal}} and \isa{{\isacharquery}}.
73.457 +
73.458 + For the failed proof attempts, the unfinished subgoals are also
73.459 + printed. Looking at these will often point to a missing lemma.
73.460 +
73.461 +% As a more real example, here is quicksort:%
73.462 +\end{isamarkuptext}%
73.463 +\isamarkuptrue%
73.464 +%
73.465 +\isamarkupsection{Mutual Recursion%
73.466 +}
73.467 +\isamarkuptrue%
73.468 +%
73.469 +\begin{isamarkuptext}%
73.470 +If two or more functions call one another mutually, they have to be defined
73.471 + in one step. Here are \isa{even} and \isa{odd}:%
73.472 +\end{isamarkuptext}%
73.473 +\isamarkuptrue%
73.474 +\isacommand{function}\isamarkupfalse%
73.475 +\ even\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymRightarrow}\ bool{\isachardoublequoteclose}\isanewline
73.476 +\ \ \ \ \isakeyword{and}\ odd\ \ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymRightarrow}\ bool{\isachardoublequoteclose}\isanewline
73.477 +\isakeyword{where}\isanewline
73.478 +\ \ {\isachardoublequoteopen}even\ {\isadigit{0}}\ {\isacharequal}\ True{\isachardoublequoteclose}\isanewline
73.479 +{\isacharbar}\ {\isachardoublequoteopen}odd\ {\isadigit{0}}\ {\isacharequal}\ False{\isachardoublequoteclose}\isanewline
73.480 +{\isacharbar}\ {\isachardoublequoteopen}even\ {\isacharparenleft}Suc\ n{\isacharparenright}\ {\isacharequal}\ odd\ n{\isachardoublequoteclose}\isanewline
73.481 +{\isacharbar}\ {\isachardoublequoteopen}odd\ {\isacharparenleft}Suc\ n{\isacharparenright}\ {\isacharequal}\ even\ n{\isachardoublequoteclose}\isanewline
73.482 +%
73.483 +\isadelimproof
73.484 +%
73.485 +\endisadelimproof
73.486 +%
73.487 +\isatagproof
73.488 +\isacommand{by}\isamarkupfalse%
73.489 +\ pat{\isacharunderscore}completeness\ auto%
73.490 +\endisatagproof
73.491 +{\isafoldproof}%
73.492 +%
73.493 +\isadelimproof
73.494 +%
73.495 +\endisadelimproof
73.496 +%
73.497 +\begin{isamarkuptext}%
73.498 +To eliminate the mutual dependencies, Isabelle internally
73.499 + creates a single function operating on the sum
73.500 + type \isa{nat\ {\isacharplus}\ nat}. Then, \isa{even} and \isa{odd} are
73.501 + defined as projections. Consequently, termination has to be proved
73.502 + simultaneously for both functions, by specifying a measure on the
73.503 + sum type:%
73.504 +\end{isamarkuptext}%
73.505 +\isamarkuptrue%
73.506 +\isacommand{termination}\isamarkupfalse%
73.507 +\ \isanewline
73.508 +%
73.509 +\isadelimproof
73.510 +%
73.511 +\endisadelimproof
73.512 +%
73.513 +\isatagproof
73.514 +\isacommand{by}\isamarkupfalse%
73.515 +\ {\isacharparenleft}relation\ {\isachardoublequoteopen}measure\ {\isacharparenleft}{\isasymlambda}x{\isachardot}\ case\ x\ of\ Inl\ n\ {\isasymRightarrow}\ n\ {\isacharbar}\ Inr\ n\ {\isasymRightarrow}\ n{\isacharparenright}{\isachardoublequoteclose}{\isacharparenright}\ auto%
73.516 +\endisatagproof
73.517 +{\isafoldproof}%
73.518 +%
73.519 +\isadelimproof
73.520 +%
73.521 +\endisadelimproof
73.522 +%
73.523 +\begin{isamarkuptext}%
73.524 +We could also have used \isa{lexicographic{\isacharunderscore}order}, which
73.525 + supports mutual recursive termination proofs to a certain extent.%
73.526 +\end{isamarkuptext}%
73.527 +\isamarkuptrue%
73.528 +%
73.529 +\isamarkupsubsection{Induction for mutual recursion%
73.530 +}
73.531 +\isamarkuptrue%
73.532 +%
73.533 +\begin{isamarkuptext}%
73.534 +When functions are mutually recursive, proving properties about them
73.535 + generally requires simultaneous induction. The induction rule \isa{even{\isacharunderscore}odd{\isachardot}induct}
73.536 + generated from the above definition reflects this.
73.537 +
73.538 + Let us prove something about \isa{even} and \isa{odd}:%
73.539 +\end{isamarkuptext}%
73.540 +\isamarkuptrue%
73.541 +\isacommand{lemma}\isamarkupfalse%
73.542 +\ even{\isacharunderscore}odd{\isacharunderscore}mod{\isadigit{2}}{\isacharcolon}\isanewline
73.543 +\ \ {\isachardoublequoteopen}even\ n\ {\isacharequal}\ {\isacharparenleft}n\ mod\ {\isadigit{2}}\ {\isacharequal}\ {\isadigit{0}}{\isacharparenright}{\isachardoublequoteclose}\isanewline
73.544 +\ \ {\isachardoublequoteopen}odd\ n\ {\isacharequal}\ {\isacharparenleft}n\ mod\ {\isadigit{2}}\ {\isacharequal}\ {\isadigit{1}}{\isacharparenright}{\isachardoublequoteclose}%
73.545 +\isadelimproof
73.546 +%
73.547 +\endisadelimproof
73.548 +%
73.549 +\isatagproof
73.550 +%
73.551 +\begin{isamarkuptxt}%
73.552 +We apply simultaneous induction, specifying the induction variable
73.553 + for both goals, separated by \cmd{and}:%
73.554 +\end{isamarkuptxt}%
73.555 +\isamarkuptrue%
73.556 +\isacommand{apply}\isamarkupfalse%
73.557 +\ {\isacharparenleft}induct\ n\ \isakeyword{and}\ n\ rule{\isacharcolon}\ even{\isacharunderscore}odd{\isachardot}induct{\isacharparenright}%
73.558 +\begin{isamarkuptxt}%
73.559 +We get four subgoals, which correspond to the clauses in the
73.560 + definition of \isa{even} and \isa{odd}:
73.561 + \begin{isabelle}%
73.562 +\ {\isadigit{1}}{\isachardot}\ even\ {\isadigit{0}}\ {\isacharequal}\ {\isacharparenleft}{\isadigit{0}}\ mod\ {\isadigit{2}}\ {\isacharequal}\ {\isadigit{0}}{\isacharparenright}\isanewline
73.563 +\ {\isadigit{2}}{\isachardot}\ odd\ {\isadigit{0}}\ {\isacharequal}\ {\isacharparenleft}{\isadigit{0}}\ mod\ {\isadigit{2}}\ {\isacharequal}\ {\isadigit{1}}{\isacharparenright}\isanewline
73.564 +\ {\isadigit{3}}{\isachardot}\ {\isasymAnd}n{\isachardot}\ odd\ n\ {\isacharequal}\ {\isacharparenleft}n\ mod\ {\isadigit{2}}\ {\isacharequal}\ {\isadigit{1}}{\isacharparenright}\ {\isasymLongrightarrow}\ even\ {\isacharparenleft}Suc\ n{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}Suc\ n\ mod\ {\isadigit{2}}\ {\isacharequal}\ {\isadigit{0}}{\isacharparenright}\isanewline
73.565 +\ {\isadigit{4}}{\isachardot}\ {\isasymAnd}n{\isachardot}\ even\ n\ {\isacharequal}\ {\isacharparenleft}n\ mod\ {\isadigit{2}}\ {\isacharequal}\ {\isadigit{0}}{\isacharparenright}\ {\isasymLongrightarrow}\ odd\ {\isacharparenleft}Suc\ n{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}Suc\ n\ mod\ {\isadigit{2}}\ {\isacharequal}\ {\isadigit{1}}{\isacharparenright}%
73.566 +\end{isabelle}
73.567 + Simplification solves the first two goals, leaving us with two
73.568 + statements about the \isa{mod} operation to prove:%
73.569 +\end{isamarkuptxt}%
73.570 +\isamarkuptrue%
73.571 +\isacommand{apply}\isamarkupfalse%
73.572 +\ simp{\isacharunderscore}all%
73.573 +\begin{isamarkuptxt}%
73.574 +\begin{isabelle}%
73.575 +\ {\isadigit{1}}{\isachardot}\ {\isasymAnd}n{\isachardot}\ odd\ n\ {\isacharequal}\ {\isacharparenleft}n\ mod\ {\isadigit{2}}\ {\isacharequal}\ Suc\ {\isadigit{0}}{\isacharparenright}\ {\isasymLongrightarrow}\ {\isacharparenleft}n\ mod\ {\isadigit{2}}\ {\isacharequal}\ Suc\ {\isadigit{0}}{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}Suc\ n\ mod\ {\isadigit{2}}\ {\isacharequal}\ {\isadigit{0}}{\isacharparenright}\isanewline
73.576 +\ {\isadigit{2}}{\isachardot}\ {\isasymAnd}n{\isachardot}\ even\ n\ {\isacharequal}\ {\isacharparenleft}n\ mod\ {\isadigit{2}}\ {\isacharequal}\ {\isadigit{0}}{\isacharparenright}\ {\isasymLongrightarrow}\ {\isacharparenleft}n\ mod\ {\isadigit{2}}\ {\isacharequal}\ {\isadigit{0}}{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}Suc\ n\ mod\ {\isadigit{2}}\ {\isacharequal}\ Suc\ {\isadigit{0}}{\isacharparenright}%
73.577 +\end{isabelle}
73.578 +
73.579 + \noindent These can be handled by Isabelle's arithmetic decision procedures.%
73.580 +\end{isamarkuptxt}%
73.581 +\isamarkuptrue%
73.582 +\isacommand{apply}\isamarkupfalse%
73.583 +\ arith\isanewline
73.584 +\isacommand{apply}\isamarkupfalse%
73.585 +\ arith\isanewline
73.586 +\isacommand{done}\isamarkupfalse%
73.587 +%
73.588 +\endisatagproof
73.589 +{\isafoldproof}%
73.590 +%
73.591 +\isadelimproof
73.592 +%
73.593 +\endisadelimproof
73.594 +%
73.595 +\begin{isamarkuptext}%
73.596 +In proofs like this, the simultaneous induction is really essential:
73.597 + Even if we are just interested in one of the results, the other
73.598 + one is necessary to strengthen the induction hypothesis. If we leave
73.599 + out the statement about \isa{odd} and just write \isa{True} instead,
73.600 + the same proof fails:%
73.601 +\end{isamarkuptext}%
73.602 +\isamarkuptrue%
73.603 +\isacommand{lemma}\isamarkupfalse%
73.604 +\ failed{\isacharunderscore}attempt{\isacharcolon}\isanewline
73.605 +\ \ {\isachardoublequoteopen}even\ n\ {\isacharequal}\ {\isacharparenleft}n\ mod\ {\isadigit{2}}\ {\isacharequal}\ {\isadigit{0}}{\isacharparenright}{\isachardoublequoteclose}\isanewline
73.606 +\ \ {\isachardoublequoteopen}True{\isachardoublequoteclose}\isanewline
73.607 +%
73.608 +\isadelimproof
73.609 +%
73.610 +\endisadelimproof
73.611 +%
73.612 +\isatagproof
73.613 +\isacommand{apply}\isamarkupfalse%
73.614 +\ {\isacharparenleft}induct\ n\ rule{\isacharcolon}\ even{\isacharunderscore}odd{\isachardot}induct{\isacharparenright}%
73.615 +\begin{isamarkuptxt}%
73.616 +\noindent Now the third subgoal is a dead end, since we have no
73.617 + useful induction hypothesis available:
73.618 +
73.619 + \begin{isabelle}%
73.620 +\ {\isadigit{1}}{\isachardot}\ even\ {\isadigit{0}}\ {\isacharequal}\ {\isacharparenleft}{\isadigit{0}}\ mod\ {\isadigit{2}}\ {\isacharequal}\ {\isadigit{0}}{\isacharparenright}\isanewline
73.621 +\ {\isadigit{2}}{\isachardot}\ True\isanewline
73.622 +\ {\isadigit{3}}{\isachardot}\ {\isasymAnd}n{\isachardot}\ True\ {\isasymLongrightarrow}\ even\ {\isacharparenleft}Suc\ n{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}Suc\ n\ mod\ {\isadigit{2}}\ {\isacharequal}\ {\isadigit{0}}{\isacharparenright}\isanewline
73.623 +\ {\isadigit{4}}{\isachardot}\ {\isasymAnd}n{\isachardot}\ even\ n\ {\isacharequal}\ {\isacharparenleft}n\ mod\ {\isadigit{2}}\ {\isacharequal}\ {\isadigit{0}}{\isacharparenright}\ {\isasymLongrightarrow}\ True%
73.624 +\end{isabelle}%
73.625 +\end{isamarkuptxt}%
73.626 +\isamarkuptrue%
73.627 +\isacommand{oops}\isamarkupfalse%
73.628 +%
73.629 +\endisatagproof
73.630 +{\isafoldproof}%
73.631 +%
73.632 +\isadelimproof
73.633 +%
73.634 +\endisadelimproof
73.635 +%
73.636 +\isamarkupsection{General pattern matching%
73.637 +}
73.638 +\isamarkuptrue%
73.639 +%
73.640 +\begin{isamarkuptext}%
73.641 +\label{genpats}%
73.642 +\end{isamarkuptext}%
73.643 +\isamarkuptrue%
73.644 +%
73.645 +\isamarkupsubsection{Avoiding automatic pattern splitting%
73.646 +}
73.647 +\isamarkuptrue%
73.648 +%
73.649 +\begin{isamarkuptext}%
73.650 +Up to now, we used pattern matching only on datatypes, and the
73.651 + patterns were always disjoint and complete, and if they weren't,
73.652 + they were made disjoint automatically like in the definition of
73.653 + \isa{sep} in \S\ref{patmatch}.
73.654 +
73.655 + This automatic splitting can significantly increase the number of
73.656 + equations involved, and this is not always desirable. The following
73.657 + example shows the problem:
73.658 +
73.659 + Suppose we are modeling incomplete knowledge about the world by a
73.660 + three-valued datatype, which has values \isa{T}, \isa{F}
73.661 + and \isa{X} for true, false and uncertain propositions, respectively.%
73.662 +\end{isamarkuptext}%
73.663 +\isamarkuptrue%
73.664 +\isacommand{datatype}\isamarkupfalse%
73.665 +\ P{\isadigit{3}}\ {\isacharequal}\ T\ {\isacharbar}\ F\ {\isacharbar}\ X%
73.666 +\begin{isamarkuptext}%
73.667 +\noindent Then the conjunction of such values can be defined as follows:%
73.668 +\end{isamarkuptext}%
73.669 +\isamarkuptrue%
73.670 +\isacommand{fun}\isamarkupfalse%
73.671 +\ And\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}P{\isadigit{3}}\ {\isasymRightarrow}\ P{\isadigit{3}}\ {\isasymRightarrow}\ P{\isadigit{3}}{\isachardoublequoteclose}\isanewline
73.672 +\isakeyword{where}\isanewline
73.673 +\ \ {\isachardoublequoteopen}And\ T\ p\ {\isacharequal}\ p{\isachardoublequoteclose}\isanewline
73.674 +{\isacharbar}\ {\isachardoublequoteopen}And\ p\ T\ {\isacharequal}\ p{\isachardoublequoteclose}\isanewline
73.675 +{\isacharbar}\ {\isachardoublequoteopen}And\ p\ F\ {\isacharequal}\ F{\isachardoublequoteclose}\isanewline
73.676 +{\isacharbar}\ {\isachardoublequoteopen}And\ F\ p\ {\isacharequal}\ F{\isachardoublequoteclose}\isanewline
73.677 +{\isacharbar}\ {\isachardoublequoteopen}And\ X\ X\ {\isacharequal}\ X{\isachardoublequoteclose}%
73.678 +\begin{isamarkuptext}%
73.679 +This definition is useful, because the equations can directly be used
73.680 + as simplification rules. But the patterns overlap: For example,
73.681 + the expression \isa{And\ T\ T} is matched by both the first and
73.682 + the second equation. By default, Isabelle makes the patterns disjoint by
73.683 + splitting them up, producing instances:%
73.684 +\end{isamarkuptext}%
73.685 +\isamarkuptrue%
73.686 +\isacommand{thm}\isamarkupfalse%
73.687 +\ And{\isachardot}simps%
73.688 +\begin{isamarkuptext}%
73.689 +\isa{And\ T\ {\isacharquery}p\ {\isacharequal}\ {\isacharquery}p\isasep\isanewline%
73.690 +And\ F\ T\ {\isacharequal}\ F\isasep\isanewline%
73.691 +And\ X\ T\ {\isacharequal}\ X\isasep\isanewline%
73.692 +And\ F\ F\ {\isacharequal}\ F\isasep\isanewline%
73.693 +And\ X\ F\ {\isacharequal}\ F\isasep\isanewline%
73.694 +And\ F\ X\ {\isacharequal}\ F\isasep\isanewline%
73.695 +And\ X\ X\ {\isacharequal}\ X}
73.696 +
73.697 + \vspace*{1em}
73.698 + \noindent There are several problems with this:
73.699 +
73.700 + \begin{enumerate}
73.701 + \item If the datatype has many constructors, there can be an
73.702 + explosion of equations. For \isa{And}, we get seven instead of
73.703 + five equations, which can be tolerated, but this is just a small
73.704 + example.
73.705 +
73.706 + \item Since splitting makes the equations \qt{less general}, they
73.707 + do not always match in rewriting. While the term \isa{And\ x\ F}
73.708 + can be simplified to \isa{F} with the original equations, a
73.709 + (manual) case split on \isa{x} is now necessary.
73.710 +
73.711 + \item The splitting also concerns the induction rule \isa{And{\isachardot}induct}. Instead of five premises it now has seven, which
73.712 + means that our induction proofs will have more cases.
73.713 +
73.714 + \item In general, it increases clarity if we get the same definition
73.715 + back which we put in.
73.716 + \end{enumerate}
73.717 +
73.718 + If we do not want the automatic splitting, we can switch it off by
73.719 + leaving out the \cmd{sequential} option. However, we will have to
73.720 + prove that our pattern matching is consistent\footnote{This prevents
73.721 + us from defining something like \isa{f\ x\ {\isacharequal}\ True} and \isa{f\ x\ {\isacharequal}\ False} simultaneously.}:%
73.722 +\end{isamarkuptext}%
73.723 +\isamarkuptrue%
73.724 +\isacommand{function}\isamarkupfalse%
73.725 +\ And{\isadigit{2}}\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}P{\isadigit{3}}\ {\isasymRightarrow}\ P{\isadigit{3}}\ {\isasymRightarrow}\ P{\isadigit{3}}{\isachardoublequoteclose}\isanewline
73.726 +\isakeyword{where}\isanewline
73.727 +\ \ {\isachardoublequoteopen}And{\isadigit{2}}\ T\ p\ {\isacharequal}\ p{\isachardoublequoteclose}\isanewline
73.728 +{\isacharbar}\ {\isachardoublequoteopen}And{\isadigit{2}}\ p\ T\ {\isacharequal}\ p{\isachardoublequoteclose}\isanewline
73.729 +{\isacharbar}\ {\isachardoublequoteopen}And{\isadigit{2}}\ p\ F\ {\isacharequal}\ F{\isachardoublequoteclose}\isanewline
73.730 +{\isacharbar}\ {\isachardoublequoteopen}And{\isadigit{2}}\ F\ p\ {\isacharequal}\ F{\isachardoublequoteclose}\isanewline
73.731 +{\isacharbar}\ {\isachardoublequoteopen}And{\isadigit{2}}\ X\ X\ {\isacharequal}\ X{\isachardoublequoteclose}%
73.732 +\isadelimproof
73.733 +%
73.734 +\endisadelimproof
73.735 +%
73.736 +\isatagproof
73.737 +%
73.738 +\begin{isamarkuptxt}%
73.739 +\noindent Now let's look at the proof obligations generated by a
73.740 + function definition. In this case, they are:
73.741 +
73.742 + \begin{isabelle}%
73.743 +\ {\isadigit{1}}{\isachardot}\ {\isasymAnd}P\ x{\isachardot}\ {\isasymlbrakk}{\isasymAnd}p{\isachardot}\ x\ {\isacharequal}\ {\isacharparenleft}T{\isacharcomma}\ p{\isacharparenright}\ {\isasymLongrightarrow}\ P{\isacharsemicolon}\ {\isasymAnd}p{\isachardot}\ x\ {\isacharequal}\ {\isacharparenleft}p{\isacharcomma}\ T{\isacharparenright}\ {\isasymLongrightarrow}\ P{\isacharsemicolon}\ {\isasymAnd}p{\isachardot}\ x\ {\isacharequal}\ {\isacharparenleft}p{\isacharcomma}\ F{\isacharparenright}\ {\isasymLongrightarrow}\ P{\isacharsemicolon}\isanewline
73.744 +\isaindent{\ {\isadigit{1}}{\isachardot}\ {\isasymAnd}P\ x{\isachardot}\ \ }{\isasymAnd}p{\isachardot}\ x\ {\isacharequal}\ {\isacharparenleft}F{\isacharcomma}\ p{\isacharparenright}\ {\isasymLongrightarrow}\ P{\isacharsemicolon}\ x\ {\isacharequal}\ {\isacharparenleft}X{\isacharcomma}\ X{\isacharparenright}\ {\isasymLongrightarrow}\ P{\isasymrbrakk}\isanewline
73.745 +\isaindent{\ {\isadigit{1}}{\isachardot}\ {\isasymAnd}P\ x{\isachardot}\ }{\isasymLongrightarrow}\ P\isanewline
73.746 +\ {\isadigit{2}}{\isachardot}\ {\isasymAnd}p\ pa{\isachardot}\ {\isacharparenleft}T{\isacharcomma}\ p{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}T{\isacharcomma}\ pa{\isacharparenright}\ {\isasymLongrightarrow}\ p\ {\isacharequal}\ pa\isanewline
73.747 +\ {\isadigit{3}}{\isachardot}\ {\isasymAnd}p\ pa{\isachardot}\ {\isacharparenleft}T{\isacharcomma}\ p{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}pa{\isacharcomma}\ T{\isacharparenright}\ {\isasymLongrightarrow}\ p\ {\isacharequal}\ pa\isanewline
73.748 +\ {\isadigit{4}}{\isachardot}\ {\isasymAnd}p\ pa{\isachardot}\ {\isacharparenleft}T{\isacharcomma}\ p{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}pa{\isacharcomma}\ F{\isacharparenright}\ {\isasymLongrightarrow}\ p\ {\isacharequal}\ F\isanewline
73.749 +\ {\isadigit{5}}{\isachardot}\ {\isasymAnd}p\ pa{\isachardot}\ {\isacharparenleft}T{\isacharcomma}\ p{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}F{\isacharcomma}\ pa{\isacharparenright}\ {\isasymLongrightarrow}\ p\ {\isacharequal}\ F\isanewline
73.750 +\ {\isadigit{6}}{\isachardot}\ {\isasymAnd}p{\isachardot}\ {\isacharparenleft}T{\isacharcomma}\ p{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}X{\isacharcomma}\ X{\isacharparenright}\ {\isasymLongrightarrow}\ p\ {\isacharequal}\ X\isanewline
73.751 +\ {\isadigit{7}}{\isachardot}\ {\isasymAnd}p\ pa{\isachardot}\ {\isacharparenleft}p{\isacharcomma}\ T{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}pa{\isacharcomma}\ T{\isacharparenright}\ {\isasymLongrightarrow}\ p\ {\isacharequal}\ pa\isanewline
73.752 +\ {\isadigit{8}}{\isachardot}\ {\isasymAnd}p\ pa{\isachardot}\ {\isacharparenleft}p{\isacharcomma}\ T{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}pa{\isacharcomma}\ F{\isacharparenright}\ {\isasymLongrightarrow}\ p\ {\isacharequal}\ F\isanewline
73.753 +\ {\isadigit{9}}{\isachardot}\ {\isasymAnd}p\ pa{\isachardot}\ {\isacharparenleft}p{\isacharcomma}\ T{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}F{\isacharcomma}\ pa{\isacharparenright}\ {\isasymLongrightarrow}\ p\ {\isacharequal}\ F\isanewline
73.754 +\ {\isadigit{1}}{\isadigit{0}}{\isachardot}\ {\isasymAnd}p{\isachardot}\ {\isacharparenleft}p{\isacharcomma}\ T{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}X{\isacharcomma}\ X{\isacharparenright}\ {\isasymLongrightarrow}\ p\ {\isacharequal}\ X%
73.755 +\end{isabelle}\vspace{-1.2em}\hspace{3cm}\vdots\vspace{1.2em}
73.756 +
73.757 + The first subgoal expresses the completeness of the patterns. It has
73.758 + the form of an elimination rule and states that every \isa{x} of
73.759 + the function's input type must match at least one of the patterns\footnote{Completeness could
73.760 + be equivalently stated as a disjunction of existential statements:
73.761 +\isa{{\isacharparenleft}{\isasymexists}p{\isachardot}\ x\ {\isacharequal}\ {\isacharparenleft}T{\isacharcomma}\ p{\isacharparenright}{\isacharparenright}\ {\isasymor}\ {\isacharparenleft}{\isasymexists}p{\isachardot}\ x\ {\isacharequal}\ {\isacharparenleft}p{\isacharcomma}\ T{\isacharparenright}{\isacharparenright}\ {\isasymor}\ {\isacharparenleft}{\isasymexists}p{\isachardot}\ x\ {\isacharequal}\ {\isacharparenleft}p{\isacharcomma}\ F{\isacharparenright}{\isacharparenright}\ {\isasymor}\ {\isacharparenleft}{\isasymexists}p{\isachardot}\ x\ {\isacharequal}\ {\isacharparenleft}F{\isacharcomma}\ p{\isacharparenright}{\isacharparenright}\ {\isasymor}\ x\ {\isacharequal}\ {\isacharparenleft}X{\isacharcomma}\ X{\isacharparenright}}, and you can use the method \isa{atomize{\isacharunderscore}elim} to get that form instead.}. If the patterns just involve
73.762 + datatypes, we can solve it with the \isa{pat{\isacharunderscore}completeness}
73.763 + method:%
73.764 +\end{isamarkuptxt}%
73.765 +\isamarkuptrue%
73.766 +\isacommand{apply}\isamarkupfalse%
73.767 +\ pat{\isacharunderscore}completeness%
73.768 +\begin{isamarkuptxt}%
73.769 +The remaining subgoals express \emph{pattern compatibility}. We do
73.770 + allow that an input value matches multiple patterns, but in this
73.771 + case, the result (i.e.~the right hand sides of the equations) must
73.772 + also be equal. For each pair of two patterns, there is one such
73.773 + subgoal. Usually this needs injectivity of the constructors, which
73.774 + is used automatically by \isa{auto}.%
73.775 +\end{isamarkuptxt}%
73.776 +\isamarkuptrue%
73.777 +\isacommand{by}\isamarkupfalse%
73.778 +\ auto%
73.779 +\endisatagproof
73.780 +{\isafoldproof}%
73.781 +%
73.782 +\isadelimproof
73.783 +%
73.784 +\endisadelimproof
73.785 +%
73.786 +\isamarkupsubsection{Non-constructor patterns%
73.787 +}
73.788 +\isamarkuptrue%
73.789 +%
73.790 +\begin{isamarkuptext}%
73.791 +Most of Isabelle's basic types take the form of inductive datatypes,
73.792 + and usually pattern matching works on the constructors of such types.
73.793 + However, this need not be always the case, and the \cmd{function}
73.794 + command handles other kind of patterns, too.
73.795 +
73.796 + One well-known instance of non-constructor patterns are
73.797 + so-called \emph{$n+k$-patterns}, which are a little controversial in
73.798 + the functional programming world. Here is the initial fibonacci
73.799 + example with $n+k$-patterns:%
73.800 +\end{isamarkuptext}%
73.801 +\isamarkuptrue%
73.802 +\isacommand{function}\isamarkupfalse%
73.803 +\ fib{\isadigit{2}}\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymRightarrow}\ nat{\isachardoublequoteclose}\isanewline
73.804 +\isakeyword{where}\isanewline
73.805 +\ \ {\isachardoublequoteopen}fib{\isadigit{2}}\ {\isadigit{0}}\ {\isacharequal}\ {\isadigit{1}}{\isachardoublequoteclose}\isanewline
73.806 +{\isacharbar}\ {\isachardoublequoteopen}fib{\isadigit{2}}\ {\isadigit{1}}\ {\isacharequal}\ {\isadigit{1}}{\isachardoublequoteclose}\isanewline
73.807 +{\isacharbar}\ {\isachardoublequoteopen}fib{\isadigit{2}}\ {\isacharparenleft}n\ {\isacharplus}\ {\isadigit{2}}{\isacharparenright}\ {\isacharequal}\ fib{\isadigit{2}}\ n\ {\isacharplus}\ fib{\isadigit{2}}\ {\isacharparenleft}Suc\ n{\isacharparenright}{\isachardoublequoteclose}\isanewline
73.808 +%
73.809 +\isadelimML
73.810 +%
73.811 +\endisadelimML
73.812 +%
73.813 +\isatagML
73.814 +%
73.815 +\endisatagML
73.816 +{\isafoldML}%
73.817 +%
73.818 +\isadelimML
73.819 +%
73.820 +\endisadelimML
73.821 +%
73.822 +\isadelimproof
73.823 +%
73.824 +\endisadelimproof
73.825 +%
73.826 +\isatagproof
73.827 +%
73.828 +\begin{isamarkuptxt}%
73.829 +This kind of matching is again justified by the proof of pattern
73.830 + completeness and compatibility.
73.831 + The proof obligation for pattern completeness states that every natural number is
73.832 + either \isa{{\isadigit{0}}}, \isa{{\isadigit{1}}} or \isa{n\ {\isacharplus}\ {\isadigit{2}}}:
73.833 +
73.834 + \begin{isabelle}%
73.835 +\ {\isadigit{1}}{\isachardot}\ {\isasymAnd}P\ x{\isachardot}\ {\isasymlbrakk}x\ {\isacharequal}\ {\isadigit{0}}\ {\isasymLongrightarrow}\ P{\isacharsemicolon}\ x\ {\isacharequal}\ {\isadigit{1}}\ {\isasymLongrightarrow}\ P{\isacharsemicolon}\ {\isasymAnd}n{\isachardot}\ x\ {\isacharequal}\ n\ {\isacharplus}\ {\isadigit{2}}\ {\isasymLongrightarrow}\ P{\isasymrbrakk}\ {\isasymLongrightarrow}\ P\isanewline
73.836 +\ {\isadigit{2}}{\isachardot}\ {\isadigit{0}}\ {\isacharequal}\ {\isadigit{0}}\ {\isasymLongrightarrow}\ {\isadigit{1}}\ {\isacharequal}\ {\isadigit{1}}\isanewline
73.837 +\ {\isadigit{3}}{\isachardot}\ {\isadigit{0}}\ {\isacharequal}\ {\isadigit{1}}\ {\isasymLongrightarrow}\ {\isadigit{1}}\ {\isacharequal}\ {\isadigit{1}}\isanewline
73.838 +\ {\isadigit{4}}{\isachardot}\ {\isasymAnd}n{\isachardot}\ {\isadigit{0}}\ {\isacharequal}\ n\ {\isacharplus}\ {\isadigit{2}}\ {\isasymLongrightarrow}\ {\isadigit{1}}\ {\isacharequal}\ fib{\isadigit{2}}{\isacharunderscore}sumC\ n\ {\isacharplus}\ fib{\isadigit{2}}{\isacharunderscore}sumC\ {\isacharparenleft}Suc\ n{\isacharparenright}\isanewline
73.839 +\ {\isadigit{5}}{\isachardot}\ {\isadigit{1}}\ {\isacharequal}\ {\isadigit{1}}\ {\isasymLongrightarrow}\ {\isadigit{1}}\ {\isacharequal}\ {\isadigit{1}}\isanewline
73.840 +\ {\isadigit{6}}{\isachardot}\ {\isasymAnd}n{\isachardot}\ {\isadigit{1}}\ {\isacharequal}\ n\ {\isacharplus}\ {\isadigit{2}}\ {\isasymLongrightarrow}\ {\isadigit{1}}\ {\isacharequal}\ fib{\isadigit{2}}{\isacharunderscore}sumC\ n\ {\isacharplus}\ fib{\isadigit{2}}{\isacharunderscore}sumC\ {\isacharparenleft}Suc\ n{\isacharparenright}\isanewline
73.841 +\ {\isadigit{7}}{\isachardot}\ {\isasymAnd}n\ na{\isachardot}\isanewline
73.842 +\isaindent{\ {\isadigit{7}}{\isachardot}\ \ \ \ }n\ {\isacharplus}\ {\isadigit{2}}\ {\isacharequal}\ na\ {\isacharplus}\ {\isadigit{2}}\ {\isasymLongrightarrow}\isanewline
73.843 +\isaindent{\ {\isadigit{7}}{\isachardot}\ \ \ \ }fib{\isadigit{2}}{\isacharunderscore}sumC\ n\ {\isacharplus}\ fib{\isadigit{2}}{\isacharunderscore}sumC\ {\isacharparenleft}Suc\ n{\isacharparenright}\ {\isacharequal}\ fib{\isadigit{2}}{\isacharunderscore}sumC\ na\ {\isacharplus}\ fib{\isadigit{2}}{\isacharunderscore}sumC\ {\isacharparenleft}Suc\ na{\isacharparenright}%
73.844 +\end{isabelle}
73.845 +
73.846 + This is an arithmetic triviality, but unfortunately the
73.847 + \isa{arith} method cannot handle this specific form of an
73.848 + elimination rule. However, we can use the method \isa{atomize{\isacharunderscore}elim} to do an ad-hoc conversion to a disjunction of
73.849 + existentials, which can then be solved by the arithmetic decision procedure.
73.850 + Pattern compatibility and termination are automatic as usual.%
73.851 +\end{isamarkuptxt}%
73.852 +\isamarkuptrue%
73.853 +%
73.854 +\endisatagproof
73.855 +{\isafoldproof}%
73.856 +%
73.857 +\isadelimproof
73.858 +%
73.859 +\endisadelimproof
73.860 +%
73.861 +\isadelimML
73.862 +%
73.863 +\endisadelimML
73.864 +%
73.865 +\isatagML
73.866 +%
73.867 +\endisatagML
73.868 +{\isafoldML}%
73.869 +%
73.870 +\isadelimML
73.871 +%
73.872 +\endisadelimML
73.873 +%
73.874 +\isadelimproof
73.875 +%
73.876 +\endisadelimproof
73.877 +%
73.878 +\isatagproof
73.879 +\isacommand{apply}\isamarkupfalse%
73.880 +\ atomize{\isacharunderscore}elim\isanewline
73.881 +\isacommand{apply}\isamarkupfalse%
73.882 +\ arith\isanewline
73.883 +\isacommand{apply}\isamarkupfalse%
73.884 +\ auto\isanewline
73.885 +\isacommand{done}\isamarkupfalse%
73.886 +%
73.887 +\endisatagproof
73.888 +{\isafoldproof}%
73.889 +%
73.890 +\isadelimproof
73.891 +%
73.892 +\endisadelimproof
73.893 +\isanewline
73.894 +\isacommand{termination}\isamarkupfalse%
73.895 +%
73.896 +\isadelimproof
73.897 +\ %
73.898 +\endisadelimproof
73.899 +%
73.900 +\isatagproof
73.901 +\isacommand{by}\isamarkupfalse%
73.902 +\ lexicographic{\isacharunderscore}order%
73.903 +\endisatagproof
73.904 +{\isafoldproof}%
73.905 +%
73.906 +\isadelimproof
73.907 +%
73.908 +\endisadelimproof
73.909 +%
73.910 +\begin{isamarkuptext}%
73.911 +We can stretch the notion of pattern matching even more. The
73.912 + following function is not a sensible functional program, but a
73.913 + perfectly valid mathematical definition:%
73.914 +\end{isamarkuptext}%
73.915 +\isamarkuptrue%
73.916 +\isacommand{function}\isamarkupfalse%
73.917 +\ ev\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymRightarrow}\ bool{\isachardoublequoteclose}\isanewline
73.918 +\isakeyword{where}\isanewline
73.919 +\ \ {\isachardoublequoteopen}ev\ {\isacharparenleft}{\isadigit{2}}\ {\isacharasterisk}\ n{\isacharparenright}\ {\isacharequal}\ True{\isachardoublequoteclose}\isanewline
73.920 +{\isacharbar}\ {\isachardoublequoteopen}ev\ {\isacharparenleft}{\isadigit{2}}\ {\isacharasterisk}\ n\ {\isacharplus}\ {\isadigit{1}}{\isacharparenright}\ {\isacharequal}\ False{\isachardoublequoteclose}\isanewline
73.921 +%
73.922 +\isadelimproof
73.923 +%
73.924 +\endisadelimproof
73.925 +%
73.926 +\isatagproof
73.927 +\isacommand{apply}\isamarkupfalse%
73.928 +\ atomize{\isacharunderscore}elim\isanewline
73.929 +\isacommand{by}\isamarkupfalse%
73.930 +\ arith{\isacharplus}%
73.931 +\endisatagproof
73.932 +{\isafoldproof}%
73.933 +%
73.934 +\isadelimproof
73.935 +\isanewline
73.936 +%
73.937 +\endisadelimproof
73.938 +\isacommand{termination}\isamarkupfalse%
73.939 +%
73.940 +\isadelimproof
73.941 +\ %
73.942 +\endisadelimproof
73.943 +%
73.944 +\isatagproof
73.945 +\isacommand{by}\isamarkupfalse%
73.946 +\ {\isacharparenleft}relation\ {\isachardoublequoteopen}{\isacharbraceleft}{\isacharbraceright}{\isachardoublequoteclose}{\isacharparenright}\ simp%
73.947 +\endisatagproof
73.948 +{\isafoldproof}%
73.949 +%
73.950 +\isadelimproof
73.951 +%
73.952 +\endisadelimproof
73.953 +%
73.954 +\begin{isamarkuptext}%
73.955 +This general notion of pattern matching gives you a certain freedom
73.956 + in writing down specifications. However, as always, such freedom should
73.957 + be used with care:
73.958 +
73.959 + If we leave the area of constructor
73.960 + patterns, we have effectively departed from the world of functional
73.961 + programming. This means that it is no longer possible to use the
73.962 + code generator, and expect it to generate ML code for our
73.963 + definitions. Also, such a specification might not work very well together with
73.964 + simplification. Your mileage may vary.%
73.965 +\end{isamarkuptext}%
73.966 +\isamarkuptrue%
73.967 +%
73.968 +\isamarkupsubsection{Conditional equations%
73.969 +}
73.970 +\isamarkuptrue%
73.971 +%
73.972 +\begin{isamarkuptext}%
73.973 +The function package also supports conditional equations, which are
73.974 + similar to guards in a language like Haskell. Here is Euclid's
73.975 + algorithm written with conditional patterns\footnote{Note that the
73.976 + patterns are also overlapping in the base case}:%
73.977 +\end{isamarkuptext}%
73.978 +\isamarkuptrue%
73.979 +\isacommand{function}\isamarkupfalse%
73.980 +\ gcd\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymRightarrow}\ nat\ {\isasymRightarrow}\ nat{\isachardoublequoteclose}\isanewline
73.981 +\isakeyword{where}\isanewline
73.982 +\ \ {\isachardoublequoteopen}gcd\ x\ {\isadigit{0}}\ {\isacharequal}\ x{\isachardoublequoteclose}\isanewline
73.983 +{\isacharbar}\ {\isachardoublequoteopen}gcd\ {\isadigit{0}}\ y\ {\isacharequal}\ y{\isachardoublequoteclose}\isanewline
73.984 +{\isacharbar}\ {\isachardoublequoteopen}x\ {\isacharless}\ y\ {\isasymLongrightarrow}\ gcd\ {\isacharparenleft}Suc\ x{\isacharparenright}\ {\isacharparenleft}Suc\ y{\isacharparenright}\ {\isacharequal}\ gcd\ {\isacharparenleft}Suc\ x{\isacharparenright}\ {\isacharparenleft}y\ {\isacharminus}\ x{\isacharparenright}{\isachardoublequoteclose}\isanewline
73.985 +{\isacharbar}\ {\isachardoublequoteopen}{\isasymnot}\ x\ {\isacharless}\ y\ {\isasymLongrightarrow}\ gcd\ {\isacharparenleft}Suc\ x{\isacharparenright}\ {\isacharparenleft}Suc\ y{\isacharparenright}\ {\isacharequal}\ gcd\ {\isacharparenleft}x\ {\isacharminus}\ y{\isacharparenright}\ {\isacharparenleft}Suc\ y{\isacharparenright}{\isachardoublequoteclose}\isanewline
73.986 +%
73.987 +\isadelimproof
73.988 +%
73.989 +\endisadelimproof
73.990 +%
73.991 +\isatagproof
73.992 +\isacommand{by}\isamarkupfalse%
73.993 +\ {\isacharparenleft}atomize{\isacharunderscore}elim{\isacharcomma}\ auto{\isacharcomma}\ arith{\isacharparenright}%
73.994 +\endisatagproof
73.995 +{\isafoldproof}%
73.996 +%
73.997 +\isadelimproof
73.998 +\isanewline
73.999 +%
73.1000 +\endisadelimproof
73.1001 +\isacommand{termination}\isamarkupfalse%
73.1002 +%
73.1003 +\isadelimproof
73.1004 +\ %
73.1005 +\endisadelimproof
73.1006 +%
73.1007 +\isatagproof
73.1008 +\isacommand{by}\isamarkupfalse%
73.1009 +\ lexicographic{\isacharunderscore}order%
73.1010 +\endisatagproof
73.1011 +{\isafoldproof}%
73.1012 +%
73.1013 +\isadelimproof
73.1014 +%
73.1015 +\endisadelimproof
73.1016 +%
73.1017 +\begin{isamarkuptext}%
73.1018 +By now, you can probably guess what the proof obligations for the
73.1019 + pattern completeness and compatibility look like.
73.1020 +
73.1021 + Again, functions with conditional patterns are not supported by the
73.1022 + code generator.%
73.1023 +\end{isamarkuptext}%
73.1024 +\isamarkuptrue%
73.1025 +%
73.1026 +\isamarkupsubsection{Pattern matching on strings%
73.1027 +}
73.1028 +\isamarkuptrue%
73.1029 +%
73.1030 +\begin{isamarkuptext}%
73.1031 +As strings (as lists of characters) are normal datatypes, pattern
73.1032 + matching on them is possible, but somewhat problematic. Consider the
73.1033 + following definition:
73.1034 +
73.1035 +\end{isamarkuptext}
73.1036 +\noindent\cmd{fun} \isa{check\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequote}string\ {\isasymRightarrow}\ bool{\isachardoublequote}}\\%
73.1037 +\cmd{where}\\%
73.1038 +\hspace*{2ex}\isa{{\isachardoublequote}check\ {\isacharparenleft}{\isacharprime}{\isacharprime}good{\isacharprime}{\isacharprime}{\isacharparenright}\ {\isacharequal}\ True{\isachardoublequote}}\\%
73.1039 +\isa{{\isacharbar}\ {\isachardoublequote}check\ s\ {\isacharequal}\ False{\isachardoublequote}}
73.1040 +\begin{isamarkuptext}
73.1041 +
73.1042 + \noindent An invocation of the above \cmd{fun} command does not
73.1043 + terminate. What is the problem? Strings are lists of characters, and
73.1044 + characters are a datatype with a lot of constructors. Splitting the
73.1045 + catch-all pattern thus leads to an explosion of cases, which cannot
73.1046 + be handled by Isabelle.
73.1047 +
73.1048 + There are two things we can do here. Either we write an explicit
73.1049 + \isa{if} on the right hand side, or we can use conditional patterns:%
73.1050 +\end{isamarkuptext}%
73.1051 +\isamarkuptrue%
73.1052 +\isacommand{function}\isamarkupfalse%
73.1053 +\ check\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}string\ {\isasymRightarrow}\ bool{\isachardoublequoteclose}\isanewline
73.1054 +\isakeyword{where}\isanewline
73.1055 +\ \ {\isachardoublequoteopen}check\ {\isacharparenleft}{\isacharprime}{\isacharprime}good{\isacharprime}{\isacharprime}{\isacharparenright}\ {\isacharequal}\ True{\isachardoublequoteclose}\isanewline
73.1056 +{\isacharbar}\ {\isachardoublequoteopen}s\ {\isasymnoteq}\ {\isacharprime}{\isacharprime}good{\isacharprime}{\isacharprime}\ {\isasymLongrightarrow}\ check\ s\ {\isacharequal}\ False{\isachardoublequoteclose}\isanewline
73.1057 +%
73.1058 +\isadelimproof
73.1059 +%
73.1060 +\endisadelimproof
73.1061 +%
73.1062 +\isatagproof
73.1063 +\isacommand{by}\isamarkupfalse%
73.1064 +\ auto%
73.1065 +\endisatagproof
73.1066 +{\isafoldproof}%
73.1067 +%
73.1068 +\isadelimproof
73.1069 +%
73.1070 +\endisadelimproof
73.1071 +%
73.1072 +\isamarkupsection{Partiality%
73.1073 +}
73.1074 +\isamarkuptrue%
73.1075 +%
73.1076 +\begin{isamarkuptext}%
73.1077 +In HOL, all functions are total. A function \isa{f} applied to
73.1078 + \isa{x} always has the value \isa{f\ x}, and there is no notion
73.1079 + of undefinedness.
73.1080 + This is why we have to do termination
73.1081 + proofs when defining functions: The proof justifies that the
73.1082 + function can be defined by wellfounded recursion.
73.1083 +
73.1084 + However, the \cmd{function} package does support partiality to a
73.1085 + certain extent. Let's look at the following function which looks
73.1086 + for a zero of a given function f.%
73.1087 +\end{isamarkuptext}%
73.1088 +\isamarkuptrue%
73.1089 +\isacommand{function}\isamarkupfalse%
73.1090 +\ findzero\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharparenleft}nat\ {\isasymRightarrow}\ nat{\isacharparenright}\ {\isasymRightarrow}\ nat\ {\isasymRightarrow}\ nat{\isachardoublequoteclose}\isanewline
73.1091 +\isakeyword{where}\isanewline
73.1092 +\ \ {\isachardoublequoteopen}findzero\ f\ n\ {\isacharequal}\ {\isacharparenleft}if\ f\ n\ {\isacharequal}\ {\isadigit{0}}\ then\ n\ else\ findzero\ f\ {\isacharparenleft}Suc\ n{\isacharparenright}{\isacharparenright}{\isachardoublequoteclose}\isanewline
73.1093 +%
73.1094 +\isadelimproof
73.1095 +%
73.1096 +\endisadelimproof
73.1097 +%
73.1098 +\isatagproof
73.1099 +\isacommand{by}\isamarkupfalse%
73.1100 +\ pat{\isacharunderscore}completeness\ auto%
73.1101 +\endisatagproof
73.1102 +{\isafoldproof}%
73.1103 +%
73.1104 +\isadelimproof
73.1105 +%
73.1106 +\endisadelimproof
73.1107 +%
73.1108 +\begin{isamarkuptext}%
73.1109 +\noindent Clearly, any attempt of a termination proof must fail. And without
73.1110 + that, we do not get the usual rules \isa{findzero{\isachardot}simps} and
73.1111 + \isa{findzero{\isachardot}induct}. So what was the definition good for at all?%
73.1112 +\end{isamarkuptext}%
73.1113 +\isamarkuptrue%
73.1114 +%
73.1115 +\isamarkupsubsection{Domain predicates%
73.1116 +}
73.1117 +\isamarkuptrue%
73.1118 +%
73.1119 +\begin{isamarkuptext}%
73.1120 +The trick is that Isabelle has not only defined the function \isa{findzero}, but also
73.1121 + a predicate \isa{findzero{\isacharunderscore}dom} that characterizes the values where the function
73.1122 + terminates: the \emph{domain} of the function. If we treat a
73.1123 + partial function just as a total function with an additional domain
73.1124 + predicate, we can derive simplification and
73.1125 + induction rules as we do for total functions. They are guarded
73.1126 + by domain conditions and are called \isa{psimps} and \isa{pinduct}:%
73.1127 +\end{isamarkuptext}%
73.1128 +\isamarkuptrue%
73.1129 +%
73.1130 +\begin{isamarkuptext}%
73.1131 +\noindent\begin{minipage}{0.79\textwidth}\begin{isabelle}%
73.1132 +findzero{\isacharunderscore}dom\ {\isacharparenleft}{\isacharquery}f{\isacharcomma}\ {\isacharquery}n{\isacharparenright}\ {\isasymLongrightarrow}\isanewline
73.1133 +findzero\ {\isacharquery}f\ {\isacharquery}n\ {\isacharequal}\ {\isacharparenleft}if\ {\isacharquery}f\ {\isacharquery}n\ {\isacharequal}\ {\isadigit{0}}\ then\ {\isacharquery}n\ else\ findzero\ {\isacharquery}f\ {\isacharparenleft}Suc\ {\isacharquery}n{\isacharparenright}{\isacharparenright}%
73.1134 +\end{isabelle}\end{minipage}
73.1135 + \hfill(\isa{findzero{\isachardot}psimps})
73.1136 + \vspace{1em}
73.1137 +
73.1138 + \noindent\begin{minipage}{0.79\textwidth}\begin{isabelle}%
73.1139 +{\isasymlbrakk}findzero{\isacharunderscore}dom\ {\isacharparenleft}{\isacharquery}a{\isadigit{0}}{\isachardot}{\isadigit{0}}{\isacharcomma}\ {\isacharquery}a{\isadigit{1}}{\isachardot}{\isadigit{0}}{\isacharparenright}{\isacharsemicolon}\isanewline
73.1140 +\isaindent{\ }{\isasymAnd}f\ n{\isachardot}\ {\isasymlbrakk}findzero{\isacharunderscore}dom\ {\isacharparenleft}f{\isacharcomma}\ n{\isacharparenright}{\isacharsemicolon}\ f\ n\ {\isasymnoteq}\ {\isadigit{0}}\ {\isasymLongrightarrow}\ {\isacharquery}P\ f\ {\isacharparenleft}Suc\ n{\isacharparenright}{\isasymrbrakk}\ {\isasymLongrightarrow}\ {\isacharquery}P\ f\ n{\isasymrbrakk}\isanewline
73.1141 +{\isasymLongrightarrow}\ {\isacharquery}P\ {\isacharquery}a{\isadigit{0}}{\isachardot}{\isadigit{0}}\ {\isacharquery}a{\isadigit{1}}{\isachardot}{\isadigit{0}}%
73.1142 +\end{isabelle}\end{minipage}
73.1143 + \hfill(\isa{findzero{\isachardot}pinduct})%
73.1144 +\end{isamarkuptext}%
73.1145 +\isamarkuptrue%
73.1146 +%
73.1147 +\begin{isamarkuptext}%
73.1148 +Remember that all we
73.1149 + are doing here is use some tricks to make a total function appear
73.1150 + as if it was partial. We can still write the term \isa{findzero\ {\isacharparenleft}{\isasymlambda}x{\isachardot}\ {\isadigit{1}}{\isacharparenright}\ {\isadigit{0}}} and like any other term of type \isa{nat} it is equal
73.1151 + to some natural number, although we might not be able to find out
73.1152 + which one. The function is \emph{underdefined}.
73.1153 +
73.1154 + But it is defined enough to prove something interesting about it. We
73.1155 + can prove that if \isa{findzero\ f\ n}
73.1156 + terminates, it indeed returns a zero of \isa{f}:%
73.1157 +\end{isamarkuptext}%
73.1158 +\isamarkuptrue%
73.1159 +\isacommand{lemma}\isamarkupfalse%
73.1160 +\ findzero{\isacharunderscore}zero{\isacharcolon}\ {\isachardoublequoteopen}findzero{\isacharunderscore}dom\ {\isacharparenleft}f{\isacharcomma}\ n{\isacharparenright}\ {\isasymLongrightarrow}\ f\ {\isacharparenleft}findzero\ f\ n{\isacharparenright}\ {\isacharequal}\ {\isadigit{0}}{\isachardoublequoteclose}%
73.1161 +\isadelimproof
73.1162 +%
73.1163 +\endisadelimproof
73.1164 +%
73.1165 +\isatagproof
73.1166 +%
73.1167 +\begin{isamarkuptxt}%
73.1168 +\noindent We apply induction as usual, but using the partial induction
73.1169 + rule:%
73.1170 +\end{isamarkuptxt}%
73.1171 +\isamarkuptrue%
73.1172 +\isacommand{apply}\isamarkupfalse%
73.1173 +\ {\isacharparenleft}induct\ f\ n\ rule{\isacharcolon}\ findzero{\isachardot}pinduct{\isacharparenright}%
73.1174 +\begin{isamarkuptxt}%
73.1175 +\noindent This gives the following subgoals:
73.1176 +
73.1177 + \begin{isabelle}%
73.1178 +\ {\isadigit{1}}{\isachardot}\ {\isasymAnd}f\ n{\isachardot}\ {\isasymlbrakk}findzero{\isacharunderscore}dom\ {\isacharparenleft}f{\isacharcomma}\ n{\isacharparenright}{\isacharsemicolon}\ f\ n\ {\isasymnoteq}\ {\isadigit{0}}\ {\isasymLongrightarrow}\ f\ {\isacharparenleft}findzero\ f\ {\isacharparenleft}Suc\ n{\isacharparenright}{\isacharparenright}\ {\isacharequal}\ {\isadigit{0}}{\isasymrbrakk}\isanewline
73.1179 +\isaindent{\ {\isadigit{1}}{\isachardot}\ {\isasymAnd}f\ n{\isachardot}\ }{\isasymLongrightarrow}\ f\ {\isacharparenleft}findzero\ f\ n{\isacharparenright}\ {\isacharequal}\ {\isadigit{0}}%
73.1180 +\end{isabelle}
73.1181 +
73.1182 + \noindent The hypothesis in our lemma was used to satisfy the first premise in
73.1183 + the induction rule. However, we also get \isa{findzero{\isacharunderscore}dom\ {\isacharparenleft}f{\isacharcomma}\ n{\isacharparenright}} as a local assumption in the induction step. This
73.1184 + allows to unfold \isa{findzero\ f\ n} using the \isa{psimps}
73.1185 + rule, and the rest is trivial. Since the \isa{psimps} rules carry the
73.1186 + \isa{{\isacharbrackleft}simp{\isacharbrackright}} attribute by default, we just need a single step:%
73.1187 +\end{isamarkuptxt}%
73.1188 +\isamarkuptrue%
73.1189 +\isacommand{apply}\isamarkupfalse%
73.1190 +\ simp\isanewline
73.1191 +\isacommand{done}\isamarkupfalse%
73.1192 +%
73.1193 +\endisatagproof
73.1194 +{\isafoldproof}%
73.1195 +%
73.1196 +\isadelimproof
73.1197 +%
73.1198 +\endisadelimproof
73.1199 +%
73.1200 +\begin{isamarkuptext}%
73.1201 +Proofs about partial functions are often not harder than for total
73.1202 + functions. Fig.~\ref{findzero_isar} shows a slightly more
73.1203 + complicated proof written in Isar. It is verbose enough to show how
73.1204 + partiality comes into play: From the partial induction, we get an
73.1205 + additional domain condition hypothesis. Observe how this condition
73.1206 + is applied when calls to \isa{findzero} are unfolded.%
73.1207 +\end{isamarkuptext}%
73.1208 +\isamarkuptrue%
73.1209 +%
73.1210 +\begin{figure}
73.1211 +\hrule\vspace{6pt}
73.1212 +\begin{minipage}{0.8\textwidth}
73.1213 +\isabellestyle{it}
73.1214 +\isastyle\isamarkuptrue
73.1215 +\isacommand{lemma}\isamarkupfalse%
73.1216 +\ {\isachardoublequoteopen}{\isasymlbrakk}findzero{\isacharunderscore}dom\ {\isacharparenleft}f{\isacharcomma}\ n{\isacharparenright}{\isacharsemicolon}\ x\ {\isasymin}\ {\isacharbraceleft}n\ {\isachardot}{\isachardot}{\isacharless}\ findzero\ f\ n{\isacharbraceright}{\isasymrbrakk}\ {\isasymLongrightarrow}\ f\ x\ {\isasymnoteq}\ {\isadigit{0}}{\isachardoublequoteclose}\isanewline
73.1217 +%
73.1218 +\isadelimproof
73.1219 +%
73.1220 +\endisadelimproof
73.1221 +%
73.1222 +\isatagproof
73.1223 +\isacommand{proof}\isamarkupfalse%
73.1224 +\ {\isacharparenleft}induct\ rule{\isacharcolon}\ findzero{\isachardot}pinduct{\isacharparenright}\isanewline
73.1225 +\ \ \isacommand{fix}\isamarkupfalse%
73.1226 +\ f\ n\ \isacommand{assume}\isamarkupfalse%
73.1227 +\ dom{\isacharcolon}\ {\isachardoublequoteopen}findzero{\isacharunderscore}dom\ {\isacharparenleft}f{\isacharcomma}\ n{\isacharparenright}{\isachardoublequoteclose}\isanewline
73.1228 +\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \isakeyword{and}\ IH{\isacharcolon}\ {\isachardoublequoteopen}{\isasymlbrakk}f\ n\ {\isasymnoteq}\ {\isadigit{0}}{\isacharsemicolon}\ x\ {\isasymin}\ {\isacharbraceleft}Suc\ n\ {\isachardot}{\isachardot}{\isacharless}\ findzero\ f\ {\isacharparenleft}Suc\ n{\isacharparenright}{\isacharbraceright}{\isasymrbrakk}\ {\isasymLongrightarrow}\ f\ x\ {\isasymnoteq}\ {\isadigit{0}}{\isachardoublequoteclose}\isanewline
73.1229 +\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \isakeyword{and}\ x{\isacharunderscore}range{\isacharcolon}\ {\isachardoublequoteopen}x\ {\isasymin}\ {\isacharbraceleft}n\ {\isachardot}{\isachardot}{\isacharless}\ findzero\ f\ n{\isacharbraceright}{\isachardoublequoteclose}\isanewline
73.1230 +\ \ \isacommand{have}\isamarkupfalse%
73.1231 +\ {\isachardoublequoteopen}f\ n\ {\isasymnoteq}\ {\isadigit{0}}{\isachardoublequoteclose}\isanewline
73.1232 +\ \ \isacommand{proof}\isamarkupfalse%
73.1233 +\ \isanewline
73.1234 +\ \ \ \ \isacommand{assume}\isamarkupfalse%
73.1235 +\ {\isachardoublequoteopen}f\ n\ {\isacharequal}\ {\isadigit{0}}{\isachardoublequoteclose}\isanewline
73.1236 +\ \ \ \ \isacommand{with}\isamarkupfalse%
73.1237 +\ dom\ \isacommand{have}\isamarkupfalse%
73.1238 +\ {\isachardoublequoteopen}findzero\ f\ n\ {\isacharequal}\ n{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse%
73.1239 +\ simp\isanewline
73.1240 +\ \ \ \ \isacommand{with}\isamarkupfalse%
73.1241 +\ x{\isacharunderscore}range\ \isacommand{show}\isamarkupfalse%
73.1242 +\ False\ \isacommand{by}\isamarkupfalse%
73.1243 +\ auto\isanewline
73.1244 +\ \ \isacommand{qed}\isamarkupfalse%
73.1245 +\isanewline
73.1246 +\ \ \isanewline
73.1247 +\ \ \isacommand{from}\isamarkupfalse%
73.1248 +\ x{\isacharunderscore}range\ \isacommand{have}\isamarkupfalse%
73.1249 +\ {\isachardoublequoteopen}x\ {\isacharequal}\ n\ {\isasymor}\ x\ {\isasymin}\ {\isacharbraceleft}Suc\ n\ {\isachardot}{\isachardot}{\isacharless}\ findzero\ f\ n{\isacharbraceright}{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse%
73.1250 +\ auto\isanewline
73.1251 +\ \ \isacommand{thus}\isamarkupfalse%
73.1252 +\ {\isachardoublequoteopen}f\ x\ {\isasymnoteq}\ {\isadigit{0}}{\isachardoublequoteclose}\isanewline
73.1253 +\ \ \isacommand{proof}\isamarkupfalse%
73.1254 +\isanewline
73.1255 +\ \ \ \ \isacommand{assume}\isamarkupfalse%
73.1256 +\ {\isachardoublequoteopen}x\ {\isacharequal}\ n{\isachardoublequoteclose}\isanewline
73.1257 +\ \ \ \ \isacommand{with}\isamarkupfalse%
73.1258 +\ {\isacharbackquoteopen}f\ n\ {\isasymnoteq}\ {\isadigit{0}}{\isacharbackquoteclose}\ \isacommand{show}\isamarkupfalse%
73.1259 +\ {\isacharquery}thesis\ \isacommand{by}\isamarkupfalse%
73.1260 +\ simp\isanewline
73.1261 +\ \ \isacommand{next}\isamarkupfalse%
73.1262 +\isanewline
73.1263 +\ \ \ \ \isacommand{assume}\isamarkupfalse%
73.1264 +\ {\isachardoublequoteopen}x\ {\isasymin}\ {\isacharbraceleft}Suc\ n\ {\isachardot}{\isachardot}{\isacharless}\ findzero\ f\ n{\isacharbraceright}{\isachardoublequoteclose}\isanewline
73.1265 +\ \ \ \ \isacommand{with}\isamarkupfalse%
73.1266 +\ dom\ \isakeyword{and}\ {\isacharbackquoteopen}f\ n\ {\isasymnoteq}\ {\isadigit{0}}{\isacharbackquoteclose}\ \isacommand{have}\isamarkupfalse%
73.1267 +\ {\isachardoublequoteopen}x\ {\isasymin}\ {\isacharbraceleft}Suc\ n\ {\isachardot}{\isachardot}{\isacharless}\ findzero\ f\ {\isacharparenleft}Suc\ n{\isacharparenright}{\isacharbraceright}{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse%
73.1268 +\ simp\isanewline
73.1269 +\ \ \ \ \isacommand{with}\isamarkupfalse%
73.1270 +\ IH\ \isakeyword{and}\ {\isacharbackquoteopen}f\ n\ {\isasymnoteq}\ {\isadigit{0}}{\isacharbackquoteclose}\isanewline
73.1271 +\ \ \ \ \isacommand{show}\isamarkupfalse%
73.1272 +\ {\isacharquery}thesis\ \isacommand{by}\isamarkupfalse%
73.1273 +\ simp\isanewline
73.1274 +\ \ \isacommand{qed}\isamarkupfalse%
73.1275 +\isanewline
73.1276 +\isacommand{qed}\isamarkupfalse%
73.1277 +%
73.1278 +\endisatagproof
73.1279 +{\isafoldproof}%
73.1280 +%
73.1281 +\isadelimproof
73.1282 +%
73.1283 +\endisadelimproof
73.1284 +%
73.1285 +\isamarkupfalse\isabellestyle{tt}
73.1286 +\end{minipage}\vspace{6pt}\hrule
73.1287 +\caption{A proof about a partial function}\label{findzero_isar}
73.1288 +\end{figure}
73.1289 +%
73.1290 +\isamarkupsubsection{Partial termination proofs%
73.1291 +}
73.1292 +\isamarkuptrue%
73.1293 +%
73.1294 +\begin{isamarkuptext}%
73.1295 +Now that we have proved some interesting properties about our
73.1296 + function, we should turn to the domain predicate and see if it is
73.1297 + actually true for some values. Otherwise we would have just proved
73.1298 + lemmas with \isa{False} as a premise.
73.1299 +
73.1300 + Essentially, we need some introduction rules for \isa{findzero{\isacharunderscore}dom}. The function package can prove such domain
73.1301 + introduction rules automatically. But since they are not used very
73.1302 + often (they are almost never needed if the function is total), this
73.1303 + functionality is disabled by default for efficiency reasons. So we have to go
73.1304 + back and ask for them explicitly by passing the \isa{{\isacharparenleft}domintros{\isacharparenright}} option to the function package:
73.1305 +
73.1306 +\vspace{1ex}
73.1307 +\noindent\cmd{function} \isa{{\isacharparenleft}domintros{\isacharparenright}\ findzero\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequote}{\isacharparenleft}nat\ {\isasymRightarrow}\ nat{\isacharparenright}\ {\isasymRightarrow}\ nat\ {\isasymRightarrow}\ nat{\isachardoublequote}}\\%
73.1308 +\cmd{where}\isanewline%
73.1309 +\ \ \ldots\\
73.1310 +
73.1311 + \noindent Now the package has proved an introduction rule for \isa{findzero{\isacharunderscore}dom}:%
73.1312 +\end{isamarkuptext}%
73.1313 +\isamarkuptrue%
73.1314 +\isacommand{thm}\isamarkupfalse%
73.1315 +\ findzero{\isachardot}domintros%
73.1316 +\begin{isamarkuptext}%
73.1317 +\begin{isabelle}%
73.1318 +{\isacharparenleft}{\isadigit{0}}\ {\isacharless}\ {\isacharquery}f\ {\isacharquery}n\ {\isasymLongrightarrow}\ findzero{\isacharunderscore}dom\ {\isacharparenleft}{\isacharquery}f{\isacharcomma}\ Suc\ {\isacharquery}n{\isacharparenright}{\isacharparenright}\ {\isasymLongrightarrow}\ findzero{\isacharunderscore}dom\ {\isacharparenleft}{\isacharquery}f{\isacharcomma}\ {\isacharquery}n{\isacharparenright}%
73.1319 +\end{isabelle}
73.1320 +
73.1321 + Domain introduction rules allow to show that a given value lies in the
73.1322 + domain of a function, if the arguments of all recursive calls
73.1323 + are in the domain as well. They allow to do a \qt{single step} in a
73.1324 + termination proof. Usually, you want to combine them with a suitable
73.1325 + induction principle.
73.1326 +
73.1327 + Since our function increases its argument at recursive calls, we
73.1328 + need an induction principle which works \qt{backwards}. We will use
73.1329 + \isa{inc{\isacharunderscore}induct}, which allows to do induction from a fixed number
73.1330 + \qt{downwards}:
73.1331 +
73.1332 + \begin{center}\isa{{\isasymlbrakk}{\isacharquery}i\ {\isasymle}\ {\isacharquery}j{\isacharsemicolon}\ {\isacharquery}P\ {\isacharquery}j{\isacharsemicolon}\ {\isasymAnd}i{\isachardot}\ {\isasymlbrakk}i\ {\isacharless}\ {\isacharquery}j{\isacharsemicolon}\ {\isacharquery}P\ {\isacharparenleft}Suc\ i{\isacharparenright}{\isasymrbrakk}\ {\isasymLongrightarrow}\ {\isacharquery}P\ i{\isasymrbrakk}\ {\isasymLongrightarrow}\ {\isacharquery}P\ {\isacharquery}i}\hfill(\isa{inc{\isacharunderscore}induct})\end{center}
73.1333 +
73.1334 + Figure \ref{findzero_term} gives a detailed Isar proof of the fact
73.1335 + that \isa{findzero} terminates if there is a zero which is greater
73.1336 + or equal to \isa{n}. First we derive two useful rules which will
73.1337 + solve the base case and the step case of the induction. The
73.1338 + induction is then straightforward, except for the unusual induction
73.1339 + principle.%
73.1340 +\end{isamarkuptext}%
73.1341 +\isamarkuptrue%
73.1342 +%
73.1343 +\begin{figure}
73.1344 +\hrule\vspace{6pt}
73.1345 +\begin{minipage}{0.8\textwidth}
73.1346 +\isabellestyle{it}
73.1347 +\isastyle\isamarkuptrue
73.1348 +\isacommand{lemma}\isamarkupfalse%
73.1349 +\ findzero{\isacharunderscore}termination{\isacharcolon}\isanewline
73.1350 +\ \ \isakeyword{assumes}\ {\isachardoublequoteopen}x\ {\isasymge}\ n{\isachardoublequoteclose}\ \isakeyword{and}\ {\isachardoublequoteopen}f\ x\ {\isacharequal}\ {\isadigit{0}}{\isachardoublequoteclose}\isanewline
73.1351 +\ \ \isakeyword{shows}\ {\isachardoublequoteopen}findzero{\isacharunderscore}dom\ {\isacharparenleft}f{\isacharcomma}\ n{\isacharparenright}{\isachardoublequoteclose}\isanewline
73.1352 +%
73.1353 +\isadelimproof
73.1354 +%
73.1355 +\endisadelimproof
73.1356 +%
73.1357 +\isatagproof
73.1358 +\isacommand{proof}\isamarkupfalse%
73.1359 +\ {\isacharminus}\ \isanewline
73.1360 +\ \ \isacommand{have}\isamarkupfalse%
73.1361 +\ base{\isacharcolon}\ {\isachardoublequoteopen}findzero{\isacharunderscore}dom\ {\isacharparenleft}f{\isacharcomma}\ x{\isacharparenright}{\isachardoublequoteclose}\isanewline
73.1362 +\ \ \ \ \isacommand{by}\isamarkupfalse%
73.1363 +\ {\isacharparenleft}rule\ findzero{\isachardot}domintros{\isacharparenright}\ {\isacharparenleft}simp\ add{\isacharcolon}{\isacharbackquoteopen}f\ x\ {\isacharequal}\ {\isadigit{0}}{\isacharbackquoteclose}{\isacharparenright}\isanewline
73.1364 +\isanewline
73.1365 +\ \ \isacommand{have}\isamarkupfalse%
73.1366 +\ step{\isacharcolon}\ {\isachardoublequoteopen}{\isasymAnd}i{\isachardot}\ findzero{\isacharunderscore}dom\ {\isacharparenleft}f{\isacharcomma}\ Suc\ i{\isacharparenright}\ \isanewline
73.1367 +\ \ \ \ {\isasymLongrightarrow}\ findzero{\isacharunderscore}dom\ {\isacharparenleft}f{\isacharcomma}\ i{\isacharparenright}{\isachardoublequoteclose}\isanewline
73.1368 +\ \ \ \ \isacommand{by}\isamarkupfalse%
73.1369 +\ {\isacharparenleft}rule\ findzero{\isachardot}domintros{\isacharparenright}\ simp\isanewline
73.1370 +\isanewline
73.1371 +\ \ \isacommand{from}\isamarkupfalse%
73.1372 +\ {\isacharbackquoteopen}x\ {\isasymge}\ n{\isacharbackquoteclose}\ \isacommand{show}\isamarkupfalse%
73.1373 +\ {\isacharquery}thesis\isanewline
73.1374 +\ \ \isacommand{proof}\isamarkupfalse%
73.1375 +\ {\isacharparenleft}induct\ rule{\isacharcolon}inc{\isacharunderscore}induct{\isacharparenright}\isanewline
73.1376 +\ \ \ \ \isacommand{show}\isamarkupfalse%
73.1377 +\ {\isachardoublequoteopen}findzero{\isacharunderscore}dom\ {\isacharparenleft}f{\isacharcomma}\ x{\isacharparenright}{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse%
73.1378 +\ {\isacharparenleft}rule\ base{\isacharparenright}\isanewline
73.1379 +\ \ \isacommand{next}\isamarkupfalse%
73.1380 +\isanewline
73.1381 +\ \ \ \ \isacommand{fix}\isamarkupfalse%
73.1382 +\ i\ \isacommand{assume}\isamarkupfalse%
73.1383 +\ {\isachardoublequoteopen}findzero{\isacharunderscore}dom\ {\isacharparenleft}f{\isacharcomma}\ Suc\ i{\isacharparenright}{\isachardoublequoteclose}\isanewline
73.1384 +\ \ \ \ \isacommand{thus}\isamarkupfalse%
73.1385 +\ {\isachardoublequoteopen}findzero{\isacharunderscore}dom\ {\isacharparenleft}f{\isacharcomma}\ i{\isacharparenright}{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse%
73.1386 +\ {\isacharparenleft}rule\ step{\isacharparenright}\isanewline
73.1387 +\ \ \isacommand{qed}\isamarkupfalse%
73.1388 +\isanewline
73.1389 +\isacommand{qed}\isamarkupfalse%
73.1390 +%
73.1391 +\endisatagproof
73.1392 +{\isafoldproof}%
73.1393 +%
73.1394 +\isadelimproof
73.1395 +%
73.1396 +\endisadelimproof
73.1397 +%
73.1398 +\isamarkupfalse\isabellestyle{tt}
73.1399 +\end{minipage}\vspace{6pt}\hrule
73.1400 +\caption{Termination proof for \isa{findzero}}\label{findzero_term}
73.1401 +\end{figure}
73.1402 +%
73.1403 +\begin{isamarkuptext}%
73.1404 +Again, the proof given in Fig.~\ref{findzero_term} has a lot of
73.1405 + detail in order to explain the principles. Using more automation, we
73.1406 + can also have a short proof:%
73.1407 +\end{isamarkuptext}%
73.1408 +\isamarkuptrue%
73.1409 +\isacommand{lemma}\isamarkupfalse%
73.1410 +\ findzero{\isacharunderscore}termination{\isacharunderscore}short{\isacharcolon}\isanewline
73.1411 +\ \ \isakeyword{assumes}\ zero{\isacharcolon}\ {\isachardoublequoteopen}x\ {\isachargreater}{\isacharequal}\ n{\isachardoublequoteclose}\ \isanewline
73.1412 +\ \ \isakeyword{assumes}\ {\isacharbrackleft}simp{\isacharbrackright}{\isacharcolon}\ {\isachardoublequoteopen}f\ x\ {\isacharequal}\ {\isadigit{0}}{\isachardoublequoteclose}\isanewline
73.1413 +\ \ \isakeyword{shows}\ {\isachardoublequoteopen}findzero{\isacharunderscore}dom\ {\isacharparenleft}f{\isacharcomma}\ n{\isacharparenright}{\isachardoublequoteclose}\isanewline
73.1414 +%
73.1415 +\isadelimproof
73.1416 +%
73.1417 +\endisadelimproof
73.1418 +%
73.1419 +\isatagproof
73.1420 +\isacommand{using}\isamarkupfalse%
73.1421 +\ zero\isanewline
73.1422 +\isacommand{by}\isamarkupfalse%
73.1423 +\ {\isacharparenleft}induct\ rule{\isacharcolon}inc{\isacharunderscore}induct{\isacharparenright}\ {\isacharparenleft}auto\ intro{\isacharcolon}\ findzero{\isachardot}domintros{\isacharparenright}%
73.1424 +\endisatagproof
73.1425 +{\isafoldproof}%
73.1426 +%
73.1427 +\isadelimproof
73.1428 +%
73.1429 +\endisadelimproof
73.1430 +%
73.1431 +\begin{isamarkuptext}%
73.1432 +\noindent It is simple to combine the partial correctness result with the
73.1433 + termination lemma:%
73.1434 +\end{isamarkuptext}%
73.1435 +\isamarkuptrue%
73.1436 +\isacommand{lemma}\isamarkupfalse%
73.1437 +\ findzero{\isacharunderscore}total{\isacharunderscore}correctness{\isacharcolon}\isanewline
73.1438 +\ \ {\isachardoublequoteopen}f\ x\ {\isacharequal}\ {\isadigit{0}}\ {\isasymLongrightarrow}\ f\ {\isacharparenleft}findzero\ f\ {\isadigit{0}}{\isacharparenright}\ {\isacharequal}\ {\isadigit{0}}{\isachardoublequoteclose}\isanewline
73.1439 +%
73.1440 +\isadelimproof
73.1441 +%
73.1442 +\endisadelimproof
73.1443 +%
73.1444 +\isatagproof
73.1445 +\isacommand{by}\isamarkupfalse%
73.1446 +\ {\isacharparenleft}blast\ intro{\isacharcolon}\ findzero{\isacharunderscore}zero\ findzero{\isacharunderscore}termination{\isacharparenright}%
73.1447 +\endisatagproof
73.1448 +{\isafoldproof}%
73.1449 +%
73.1450 +\isadelimproof
73.1451 +%
73.1452 +\endisadelimproof
73.1453 +%
73.1454 +\isamarkupsubsection{Definition of the domain predicate%
73.1455 +}
73.1456 +\isamarkuptrue%
73.1457 +%
73.1458 +\begin{isamarkuptext}%
73.1459 +Sometimes it is useful to know what the definition of the domain
73.1460 + predicate looks like. Actually, \isa{findzero{\isacharunderscore}dom} is just an
73.1461 + abbreviation:
73.1462 +
73.1463 + \begin{isabelle}%
73.1464 +findzero{\isacharunderscore}dom\ {\isasymequiv}\ accp\ findzero{\isacharunderscore}rel%
73.1465 +\end{isabelle}
73.1466 +
73.1467 + The domain predicate is the \emph{accessible part} of a relation \isa{findzero{\isacharunderscore}rel}, which was also created internally by the function
73.1468 + package. \isa{findzero{\isacharunderscore}rel} is just a normal
73.1469 + inductive predicate, so we can inspect its definition by
73.1470 + looking at the introduction rules \isa{findzero{\isacharunderscore}rel{\isachardot}intros}.
73.1471 + In our case there is just a single rule:
73.1472 +
73.1473 + \begin{isabelle}%
73.1474 +{\isacharquery}f\ {\isacharquery}n\ {\isasymnoteq}\ {\isadigit{0}}\ {\isasymLongrightarrow}\ findzero{\isacharunderscore}rel\ {\isacharparenleft}{\isacharquery}f{\isacharcomma}\ Suc\ {\isacharquery}n{\isacharparenright}\ {\isacharparenleft}{\isacharquery}f{\isacharcomma}\ {\isacharquery}n{\isacharparenright}%
73.1475 +\end{isabelle}
73.1476 +
73.1477 + The predicate \isa{findzero{\isacharunderscore}rel}
73.1478 + describes the \emph{recursion relation} of the function
73.1479 + definition. The recursion relation is a binary relation on
73.1480 + the arguments of the function that relates each argument to its
73.1481 + recursive calls. In general, there is one introduction rule for each
73.1482 + recursive call.
73.1483 +
73.1484 + The predicate \isa{findzero{\isacharunderscore}dom} is the accessible part of
73.1485 + that relation. An argument belongs to the accessible part, if it can
73.1486 + be reached in a finite number of steps (cf.~its definition in \isa{Wellfounded{\isachardot}thy}).
73.1487 +
73.1488 + Since the domain predicate is just an abbreviation, you can use
73.1489 + lemmas for \isa{accp} and \isa{findzero{\isacharunderscore}rel} directly. Some
73.1490 + lemmas which are occasionally useful are \isa{accpI}, \isa{accp{\isacharunderscore}downward}, and of course the introduction and elimination rules
73.1491 + for the recursion relation \isa{findzero{\isachardot}intros} and \isa{findzero{\isachardot}cases}.%
73.1492 +\end{isamarkuptext}%
73.1493 +\isamarkuptrue%
73.1494 +%
73.1495 +\isamarkupsubsection{A Useful Special Case: Tail recursion%
73.1496 +}
73.1497 +\isamarkuptrue%
73.1498 +%
73.1499 +\begin{isamarkuptext}%
73.1500 +The domain predicate is our trick that allows us to model partiality
73.1501 + in a world of total functions. The downside of this is that we have
73.1502 + to carry it around all the time. The termination proof above allowed
73.1503 + us to replace the abstract \isa{findzero{\isacharunderscore}dom\ {\isacharparenleft}f{\isacharcomma}\ n{\isacharparenright}} by the more
73.1504 + concrete \isa{n\ {\isasymle}\ x\ {\isasymand}\ f\ x\ {\isacharequal}\ {\isadigit{0}}}, but the condition is still
73.1505 + there and can only be discharged for special cases.
73.1506 + In particular, the domain predicate guards the unfolding of our
73.1507 + function, since it is there as a condition in the \isa{psimp}
73.1508 + rules.
73.1509 +
73.1510 + Now there is an important special case: We can actually get rid
73.1511 + of the condition in the simplification rules, \emph{if the function
73.1512 + is tail-recursive}. The reason is that for all tail-recursive
73.1513 + equations there is a total function satisfying them, even if they
73.1514 + are non-terminating.
73.1515 +
73.1516 +% A function is tail recursive, if each call to the function is either
73.1517 +% equal
73.1518 +%
73.1519 +% So the outer form of the
73.1520 +%
73.1521 +%if it can be written in the following
73.1522 +% form:
73.1523 +% {term[display] "f x = (if COND x then BASE x else f (LOOP x))"}
73.1524 +
73.1525 +
73.1526 + The function package internally does the right construction and can
73.1527 + derive the unconditional simp rules, if we ask it to do so. Luckily,
73.1528 + our \isa{findzero} function is tail-recursive, so we can just go
73.1529 + back and add another option to the \cmd{function} command:
73.1530 +
73.1531 +\vspace{1ex}
73.1532 +\noindent\cmd{function} \isa{{\isacharparenleft}domintros{\isacharcomma}\ tailrec{\isacharparenright}\ findzero\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequote}{\isacharparenleft}nat\ {\isasymRightarrow}\ nat{\isacharparenright}\ {\isasymRightarrow}\ nat\ {\isasymRightarrow}\ nat{\isachardoublequote}}\\%
73.1533 +\cmd{where}\isanewline%
73.1534 +\ \ \ldots\\%
73.1535 +
73.1536 +
73.1537 + \noindent Now, we actually get unconditional simplification rules, even
73.1538 + though the function is partial:%
73.1539 +\end{isamarkuptext}%
73.1540 +\isamarkuptrue%
73.1541 +\isacommand{thm}\isamarkupfalse%
73.1542 +\ findzero{\isachardot}simps%
73.1543 +\begin{isamarkuptext}%
73.1544 +\begin{isabelle}%
73.1545 +findzero\ {\isacharquery}f\ {\isacharquery}n\ {\isacharequal}\ {\isacharparenleft}if\ {\isacharquery}f\ {\isacharquery}n\ {\isacharequal}\ {\isadigit{0}}\ then\ {\isacharquery}n\ else\ findzero\ {\isacharquery}f\ {\isacharparenleft}Suc\ {\isacharquery}n{\isacharparenright}{\isacharparenright}%
73.1546 +\end{isabelle}
73.1547 +
73.1548 + \noindent Of course these would make the simplifier loop, so we better remove
73.1549 + them from the simpset:%
73.1550 +\end{isamarkuptext}%
73.1551 +\isamarkuptrue%
73.1552 +\isacommand{declare}\isamarkupfalse%
73.1553 +\ findzero{\isachardot}simps{\isacharbrackleft}simp\ del{\isacharbrackright}%
73.1554 +\begin{isamarkuptext}%
73.1555 +Getting rid of the domain conditions in the simplification rules is
73.1556 + not only useful because it simplifies proofs. It is also required in
73.1557 + order to use Isabelle's code generator to generate ML code
73.1558 + from a function definition.
73.1559 + Since the code generator only works with equations, it cannot be
73.1560 + used with \isa{psimp} rules. Thus, in order to generate code for
73.1561 + partial functions, they must be defined as a tail recursion.
73.1562 + Luckily, many functions have a relatively natural tail recursive
73.1563 + definition.%
73.1564 +\end{isamarkuptext}%
73.1565 +\isamarkuptrue%
73.1566 +%
73.1567 +\isamarkupsection{Nested recursion%
73.1568 +}
73.1569 +\isamarkuptrue%
73.1570 +%
73.1571 +\begin{isamarkuptext}%
73.1572 +Recursive calls which are nested in one another frequently cause
73.1573 + complications, since their termination proof can depend on a partial
73.1574 + correctness property of the function itself.
73.1575 +
73.1576 + As a small example, we define the \qt{nested zero} function:%
73.1577 +\end{isamarkuptext}%
73.1578 +\isamarkuptrue%
73.1579 +\isacommand{function}\isamarkupfalse%
73.1580 +\ nz\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymRightarrow}\ nat{\isachardoublequoteclose}\isanewline
73.1581 +\isakeyword{where}\isanewline
73.1582 +\ \ {\isachardoublequoteopen}nz\ {\isadigit{0}}\ {\isacharequal}\ {\isadigit{0}}{\isachardoublequoteclose}\isanewline
73.1583 +{\isacharbar}\ {\isachardoublequoteopen}nz\ {\isacharparenleft}Suc\ n{\isacharparenright}\ {\isacharequal}\ nz\ {\isacharparenleft}nz\ n{\isacharparenright}{\isachardoublequoteclose}\isanewline
73.1584 +%
73.1585 +\isadelimproof
73.1586 +%
73.1587 +\endisadelimproof
73.1588 +%
73.1589 +\isatagproof
73.1590 +\isacommand{by}\isamarkupfalse%
73.1591 +\ pat{\isacharunderscore}completeness\ auto%
73.1592 +\endisatagproof
73.1593 +{\isafoldproof}%
73.1594 +%
73.1595 +\isadelimproof
73.1596 +%
73.1597 +\endisadelimproof
73.1598 +%
73.1599 +\begin{isamarkuptext}%
73.1600 +If we attempt to prove termination using the identity measure on
73.1601 + naturals, this fails:%
73.1602 +\end{isamarkuptext}%
73.1603 +\isamarkuptrue%
73.1604 +\isacommand{termination}\isamarkupfalse%
73.1605 +\isanewline
73.1606 +%
73.1607 +\isadelimproof
73.1608 +\ \ %
73.1609 +\endisadelimproof
73.1610 +%
73.1611 +\isatagproof
73.1612 +\isacommand{apply}\isamarkupfalse%
73.1613 +\ {\isacharparenleft}relation\ {\isachardoublequoteopen}measure\ {\isacharparenleft}{\isasymlambda}n{\isachardot}\ n{\isacharparenright}{\isachardoublequoteclose}{\isacharparenright}\isanewline
73.1614 +\ \ \isacommand{apply}\isamarkupfalse%
73.1615 +\ auto%
73.1616 +\begin{isamarkuptxt}%
73.1617 +We get stuck with the subgoal
73.1618 +
73.1619 + \begin{isabelle}%
73.1620 +\ {\isadigit{1}}{\isachardot}\ {\isasymAnd}n{\isachardot}\ nz{\isacharunderscore}dom\ n\ {\isasymLongrightarrow}\ nz\ n\ {\isacharless}\ Suc\ n%
73.1621 +\end{isabelle}
73.1622 +
73.1623 + Of course this statement is true, since we know that \isa{nz} is
73.1624 + the zero function. And in fact we have no problem proving this
73.1625 + property by induction.%
73.1626 +\end{isamarkuptxt}%
73.1627 +\isamarkuptrue%
73.1628 +%
73.1629 +\endisatagproof
73.1630 +{\isafoldproof}%
73.1631 +%
73.1632 +\isadelimproof
73.1633 +%
73.1634 +\endisadelimproof
73.1635 +\isacommand{lemma}\isamarkupfalse%
73.1636 +\ nz{\isacharunderscore}is{\isacharunderscore}zero{\isacharcolon}\ {\isachardoublequoteopen}nz{\isacharunderscore}dom\ n\ {\isasymLongrightarrow}\ nz\ n\ {\isacharequal}\ {\isadigit{0}}{\isachardoublequoteclose}\isanewline
73.1637 +%
73.1638 +\isadelimproof
73.1639 +\ \ %
73.1640 +\endisadelimproof
73.1641 +%
73.1642 +\isatagproof
73.1643 +\isacommand{by}\isamarkupfalse%
73.1644 +\ {\isacharparenleft}induct\ rule{\isacharcolon}nz{\isachardot}pinduct{\isacharparenright}\ auto%
73.1645 +\endisatagproof
73.1646 +{\isafoldproof}%
73.1647 +%
73.1648 +\isadelimproof
73.1649 +%
73.1650 +\endisadelimproof
73.1651 +%
73.1652 +\begin{isamarkuptext}%
73.1653 +We formulate this as a partial correctness lemma with the condition
73.1654 + \isa{nz{\isacharunderscore}dom\ n}. This allows us to prove it with the \isa{pinduct} rule before we have proved termination. With this lemma,
73.1655 + the termination proof works as expected:%
73.1656 +\end{isamarkuptext}%
73.1657 +\isamarkuptrue%
73.1658 +\isacommand{termination}\isamarkupfalse%
73.1659 +\isanewline
73.1660 +%
73.1661 +\isadelimproof
73.1662 +\ \ %
73.1663 +\endisadelimproof
73.1664 +%
73.1665 +\isatagproof
73.1666 +\isacommand{by}\isamarkupfalse%
73.1667 +\ {\isacharparenleft}relation\ {\isachardoublequoteopen}measure\ {\isacharparenleft}{\isasymlambda}n{\isachardot}\ n{\isacharparenright}{\isachardoublequoteclose}{\isacharparenright}\ {\isacharparenleft}auto\ simp{\isacharcolon}\ nz{\isacharunderscore}is{\isacharunderscore}zero{\isacharparenright}%
73.1668 +\endisatagproof
73.1669 +{\isafoldproof}%
73.1670 +%
73.1671 +\isadelimproof
73.1672 +%
73.1673 +\endisadelimproof
73.1674 +%
73.1675 +\begin{isamarkuptext}%
73.1676 +As a general strategy, one should prove the statements needed for
73.1677 + termination as a partial property first. Then they can be used to do
73.1678 + the termination proof. This also works for less trivial
73.1679 + examples. Figure \ref{f91} defines the 91-function, a well-known
73.1680 + challenge problem due to John McCarthy, and proves its termination.%
73.1681 +\end{isamarkuptext}%
73.1682 +\isamarkuptrue%
73.1683 +%
73.1684 +\begin{figure}
73.1685 +\hrule\vspace{6pt}
73.1686 +\begin{minipage}{0.8\textwidth}
73.1687 +\isabellestyle{it}
73.1688 +\isastyle\isamarkuptrue
73.1689 +\isacommand{function}\isamarkupfalse%
73.1690 +\ f{\isadigit{9}}{\isadigit{1}}\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymRightarrow}\ nat{\isachardoublequoteclose}\isanewline
73.1691 +\isakeyword{where}\isanewline
73.1692 +\ \ {\isachardoublequoteopen}f{\isadigit{9}}{\isadigit{1}}\ n\ {\isacharequal}\ {\isacharparenleft}if\ {\isadigit{1}}{\isadigit{0}}{\isadigit{0}}\ {\isacharless}\ n\ then\ n\ {\isacharminus}\ {\isadigit{1}}{\isadigit{0}}\ else\ f{\isadigit{9}}{\isadigit{1}}\ {\isacharparenleft}f{\isadigit{9}}{\isadigit{1}}\ {\isacharparenleft}n\ {\isacharplus}\ {\isadigit{1}}{\isadigit{1}}{\isacharparenright}{\isacharparenright}{\isacharparenright}{\isachardoublequoteclose}\isanewline
73.1693 +%
73.1694 +\isadelimproof
73.1695 +%
73.1696 +\endisadelimproof
73.1697 +%
73.1698 +\isatagproof
73.1699 +\isacommand{by}\isamarkupfalse%
73.1700 +\ pat{\isacharunderscore}completeness\ auto%
73.1701 +\endisatagproof
73.1702 +{\isafoldproof}%
73.1703 +%
73.1704 +\isadelimproof
73.1705 +\isanewline
73.1706 +%
73.1707 +\endisadelimproof
73.1708 +\isanewline
73.1709 +\isacommand{lemma}\isamarkupfalse%
73.1710 +\ f{\isadigit{9}}{\isadigit{1}}{\isacharunderscore}estimate{\isacharcolon}\ \isanewline
73.1711 +\ \ \isakeyword{assumes}\ trm{\isacharcolon}\ {\isachardoublequoteopen}f{\isadigit{9}}{\isadigit{1}}{\isacharunderscore}dom\ n{\isachardoublequoteclose}\ \isanewline
73.1712 +\ \ \isakeyword{shows}\ {\isachardoublequoteopen}n\ {\isacharless}\ f{\isadigit{9}}{\isadigit{1}}\ n\ {\isacharplus}\ {\isadigit{1}}{\isadigit{1}}{\isachardoublequoteclose}\isanewline
73.1713 +%
73.1714 +\isadelimproof
73.1715 +%
73.1716 +\endisadelimproof
73.1717 +%
73.1718 +\isatagproof
73.1719 +\isacommand{using}\isamarkupfalse%
73.1720 +\ trm\ \isacommand{by}\isamarkupfalse%
73.1721 +\ induct\ auto%
73.1722 +\endisatagproof
73.1723 +{\isafoldproof}%
73.1724 +%
73.1725 +\isadelimproof
73.1726 +\isanewline
73.1727 +%
73.1728 +\endisadelimproof
73.1729 +\isanewline
73.1730 +\isacommand{termination}\isamarkupfalse%
73.1731 +\isanewline
73.1732 +%
73.1733 +\isadelimproof
73.1734 +%
73.1735 +\endisadelimproof
73.1736 +%
73.1737 +\isatagproof
73.1738 +\isacommand{proof}\isamarkupfalse%
73.1739 +\isanewline
73.1740 +\ \ \isacommand{let}\isamarkupfalse%
73.1741 +\ {\isacharquery}R\ {\isacharequal}\ {\isachardoublequoteopen}measure\ {\isacharparenleft}{\isasymlambda}x{\isachardot}\ {\isadigit{1}}{\isadigit{0}}{\isadigit{1}}\ {\isacharminus}\ x{\isacharparenright}{\isachardoublequoteclose}\isanewline
73.1742 +\ \ \isacommand{show}\isamarkupfalse%
73.1743 +\ {\isachardoublequoteopen}wf\ {\isacharquery}R{\isachardoublequoteclose}\ \isacommand{{\isachardot}{\isachardot}}\isamarkupfalse%
73.1744 +\isanewline
73.1745 +\isanewline
73.1746 +\ \ \isacommand{fix}\isamarkupfalse%
73.1747 +\ n\ {\isacharcolon}{\isacharcolon}\ nat\ \isacommand{assume}\isamarkupfalse%
73.1748 +\ {\isachardoublequoteopen}{\isasymnot}\ {\isadigit{1}}{\isadigit{0}}{\isadigit{0}}\ {\isacharless}\ n{\isachardoublequoteclose}\ %
73.1749 +\isamarkupcmt{Assumptions for both calls%
73.1750 +}
73.1751 +\isanewline
73.1752 +\isanewline
73.1753 +\ \ \isacommand{thus}\isamarkupfalse%
73.1754 +\ {\isachardoublequoteopen}{\isacharparenleft}n\ {\isacharplus}\ {\isadigit{1}}{\isadigit{1}}{\isacharcomma}\ n{\isacharparenright}\ {\isasymin}\ {\isacharquery}R{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse%
73.1755 +\ simp\ %
73.1756 +\isamarkupcmt{Inner call%
73.1757 +}
73.1758 +\isanewline
73.1759 +\isanewline
73.1760 +\ \ \isacommand{assume}\isamarkupfalse%
73.1761 +\ inner{\isacharunderscore}trm{\isacharcolon}\ {\isachardoublequoteopen}f{\isadigit{9}}{\isadigit{1}}{\isacharunderscore}dom\ {\isacharparenleft}n\ {\isacharplus}\ {\isadigit{1}}{\isadigit{1}}{\isacharparenright}{\isachardoublequoteclose}\ %
73.1762 +\isamarkupcmt{Outer call%
73.1763 +}
73.1764 +\isanewline
73.1765 +\ \ \isacommand{with}\isamarkupfalse%
73.1766 +\ f{\isadigit{9}}{\isadigit{1}}{\isacharunderscore}estimate\ \isacommand{have}\isamarkupfalse%
73.1767 +\ {\isachardoublequoteopen}n\ {\isacharplus}\ {\isadigit{1}}{\isadigit{1}}\ {\isacharless}\ f{\isadigit{9}}{\isadigit{1}}\ {\isacharparenleft}n\ {\isacharplus}\ {\isadigit{1}}{\isadigit{1}}{\isacharparenright}\ {\isacharplus}\ {\isadigit{1}}{\isadigit{1}}{\isachardoublequoteclose}\ \isacommand{{\isachardot}}\isamarkupfalse%
73.1768 +\isanewline
73.1769 +\ \ \isacommand{with}\isamarkupfalse%
73.1770 +\ {\isacharbackquoteopen}{\isasymnot}\ {\isadigit{1}}{\isadigit{0}}{\isadigit{0}}\ {\isacharless}\ n{\isacharbackquoteclose}\ \isacommand{show}\isamarkupfalse%
73.1771 +\ {\isachardoublequoteopen}{\isacharparenleft}f{\isadigit{9}}{\isadigit{1}}\ {\isacharparenleft}n\ {\isacharplus}\ {\isadigit{1}}{\isadigit{1}}{\isacharparenright}{\isacharcomma}\ n{\isacharparenright}\ {\isasymin}\ {\isacharquery}R{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse%
73.1772 +\ simp\isanewline
73.1773 +\isacommand{qed}\isamarkupfalse%
73.1774 +%
73.1775 +\endisatagproof
73.1776 +{\isafoldproof}%
73.1777 +%
73.1778 +\isadelimproof
73.1779 +%
73.1780 +\endisadelimproof
73.1781 +%
73.1782 +\isamarkupfalse\isabellestyle{tt}
73.1783 +\end{minipage}
73.1784 +\vspace{6pt}\hrule
73.1785 +\caption{McCarthy's 91-function}\label{f91}
73.1786 +\end{figure}
73.1787 +%
73.1788 +\isamarkupsection{Higher-Order Recursion%
73.1789 +}
73.1790 +\isamarkuptrue%
73.1791 +%
73.1792 +\begin{isamarkuptext}%
73.1793 +Higher-order recursion occurs when recursive calls
73.1794 + are passed as arguments to higher-order combinators such as \isa{map}, \isa{filter} etc.
73.1795 + As an example, imagine a datatype of n-ary trees:%
73.1796 +\end{isamarkuptext}%
73.1797 +\isamarkuptrue%
73.1798 +\isacommand{datatype}\isamarkupfalse%
73.1799 +\ {\isacharprime}a\ tree\ {\isacharequal}\ \isanewline
73.1800 +\ \ Leaf\ {\isacharprime}a\ \isanewline
73.1801 +{\isacharbar}\ Branch\ {\isachardoublequoteopen}{\isacharprime}a\ tree\ list{\isachardoublequoteclose}%
73.1802 +\begin{isamarkuptext}%
73.1803 +\noindent We can define a function which swaps the left and right subtrees recursively, using the
73.1804 + list functions \isa{rev} and \isa{map}:%
73.1805 +\end{isamarkuptext}%
73.1806 +\isamarkuptrue%
73.1807 +\isacommand{fun}\isamarkupfalse%
73.1808 +\ mirror\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharprime}a\ tree\ {\isasymRightarrow}\ {\isacharprime}a\ tree{\isachardoublequoteclose}\isanewline
73.1809 +\isakeyword{where}\isanewline
73.1810 +\ \ {\isachardoublequoteopen}mirror\ {\isacharparenleft}Leaf\ n{\isacharparenright}\ {\isacharequal}\ Leaf\ n{\isachardoublequoteclose}\isanewline
73.1811 +{\isacharbar}\ {\isachardoublequoteopen}mirror\ {\isacharparenleft}Branch\ l{\isacharparenright}\ {\isacharequal}\ Branch\ {\isacharparenleft}rev\ {\isacharparenleft}map\ mirror\ l{\isacharparenright}{\isacharparenright}{\isachardoublequoteclose}%
73.1812 +\begin{isamarkuptext}%
73.1813 +Although the definition is accepted without problems, let us look at the termination proof:%
73.1814 +\end{isamarkuptext}%
73.1815 +\isamarkuptrue%
73.1816 +\isacommand{termination}\isamarkupfalse%
73.1817 +%
73.1818 +\isadelimproof
73.1819 +\ %
73.1820 +\endisadelimproof
73.1821 +%
73.1822 +\isatagproof
73.1823 +\isacommand{proof}\isamarkupfalse%
73.1824 +%
73.1825 +\begin{isamarkuptxt}%
73.1826 +As usual, we have to give a wellfounded relation, such that the
73.1827 + arguments of the recursive calls get smaller. But what exactly are
73.1828 + the arguments of the recursive calls when mirror is given as an
73.1829 + argument to \isa{map}? Isabelle gives us the
73.1830 + subgoals
73.1831 +
73.1832 + \begin{isabelle}%
73.1833 +\ {\isadigit{1}}{\isachardot}\ wf\ {\isacharquery}R\isanewline
73.1834 +\ {\isadigit{2}}{\isachardot}\ {\isasymAnd}l\ x{\isachardot}\ x\ {\isasymin}\ set\ l\ {\isasymLongrightarrow}\ {\isacharparenleft}x{\isacharcomma}\ Branch\ l{\isacharparenright}\ {\isasymin}\ {\isacharquery}R%
73.1835 +\end{isabelle}
73.1836 +
73.1837 + So the system seems to know that \isa{map} only
73.1838 + applies the recursive call \isa{mirror} to elements
73.1839 + of \isa{l}, which is essential for the termination proof.
73.1840 +
73.1841 + This knowledge about \isa{map} is encoded in so-called congruence rules,
73.1842 + which are special theorems known to the \cmd{function} command. The
73.1843 + rule for \isa{map} is
73.1844 +
73.1845 + \begin{isabelle}%
73.1846 +{\isasymlbrakk}{\isacharquery}xs\ {\isacharequal}\ {\isacharquery}ys{\isacharsemicolon}\ {\isasymAnd}x{\isachardot}\ x\ {\isasymin}\ set\ {\isacharquery}ys\ {\isasymLongrightarrow}\ {\isacharquery}f\ x\ {\isacharequal}\ {\isacharquery}g\ x{\isasymrbrakk}\ {\isasymLongrightarrow}\ map\ {\isacharquery}f\ {\isacharquery}xs\ {\isacharequal}\ map\ {\isacharquery}g\ {\isacharquery}ys%
73.1847 +\end{isabelle}
73.1848 +
73.1849 + You can read this in the following way: Two applications of \isa{map} are equal, if the list arguments are equal and the functions
73.1850 + coincide on the elements of the list. This means that for the value
73.1851 + \isa{map\ f\ l} we only have to know how \isa{f} behaves on
73.1852 + the elements of \isa{l}.
73.1853 +
73.1854 + Usually, one such congruence rule is
73.1855 + needed for each higher-order construct that is used when defining
73.1856 + new functions. In fact, even basic functions like \isa{If} and \isa{Let} are handled by this mechanism. The congruence
73.1857 + rule for \isa{If} states that the \isa{then} branch is only
73.1858 + relevant if the condition is true, and the \isa{else} branch only if it
73.1859 + is false:
73.1860 +
73.1861 + \begin{isabelle}%
73.1862 +{\isasymlbrakk}{\isacharquery}b\ {\isacharequal}\ {\isacharquery}c{\isacharsemicolon}\ {\isacharquery}c\ {\isasymLongrightarrow}\ {\isacharquery}x\ {\isacharequal}\ {\isacharquery}u{\isacharsemicolon}\ {\isasymnot}\ {\isacharquery}c\ {\isasymLongrightarrow}\ {\isacharquery}y\ {\isacharequal}\ {\isacharquery}v{\isasymrbrakk}\isanewline
73.1863 +{\isasymLongrightarrow}\ {\isacharparenleft}if\ {\isacharquery}b\ then\ {\isacharquery}x\ else\ {\isacharquery}y{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}if\ {\isacharquery}c\ then\ {\isacharquery}u\ else\ {\isacharquery}v{\isacharparenright}%
73.1864 +\end{isabelle}
73.1865 +
73.1866 + Congruence rules can be added to the
73.1867 + function package by giving them the \isa{fundef{\isacharunderscore}cong} attribute.
73.1868 +
73.1869 + The constructs that are predefined in Isabelle, usually
73.1870 + come with the respective congruence rules.
73.1871 + But if you define your own higher-order functions, you may have to
73.1872 + state and prove the required congruence rules yourself, if you want to use your
73.1873 + functions in recursive definitions.%
73.1874 +\end{isamarkuptxt}%
73.1875 +\isamarkuptrue%
73.1876 +%
73.1877 +\endisatagproof
73.1878 +{\isafoldproof}%
73.1879 +%
73.1880 +\isadelimproof
73.1881 +%
73.1882 +\endisadelimproof
73.1883 +%
73.1884 +\isamarkupsubsection{Congruence Rules and Evaluation Order%
73.1885 +}
73.1886 +\isamarkuptrue%
73.1887 +%
73.1888 +\begin{isamarkuptext}%
73.1889 +Higher order logic differs from functional programming languages in
73.1890 + that it has no built-in notion of evaluation order. A program is
73.1891 + just a set of equations, and it is not specified how they must be
73.1892 + evaluated.
73.1893 +
73.1894 + However for the purpose of function definition, we must talk about
73.1895 + evaluation order implicitly, when we reason about termination.
73.1896 + Congruence rules express that a certain evaluation order is
73.1897 + consistent with the logical definition.
73.1898 +
73.1899 + Consider the following function.%
73.1900 +\end{isamarkuptext}%
73.1901 +\isamarkuptrue%
73.1902 +\isacommand{function}\isamarkupfalse%
73.1903 +\ f\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymRightarrow}\ bool{\isachardoublequoteclose}\isanewline
73.1904 +\isakeyword{where}\isanewline
73.1905 +\ \ {\isachardoublequoteopen}f\ n\ {\isacharequal}\ {\isacharparenleft}n\ {\isacharequal}\ {\isadigit{0}}\ {\isasymor}\ f\ {\isacharparenleft}n\ {\isacharminus}\ {\isadigit{1}}{\isacharparenright}{\isacharparenright}{\isachardoublequoteclose}%
73.1906 +\isadelimproof
73.1907 +%
73.1908 +\endisadelimproof
73.1909 +%
73.1910 +\isatagproof
73.1911 +%
73.1912 +\endisatagproof
73.1913 +{\isafoldproof}%
73.1914 +%
73.1915 +\isadelimproof
73.1916 +%
73.1917 +\endisadelimproof
73.1918 +%
73.1919 +\begin{isamarkuptext}%
73.1920 +For this definition, the termination proof fails. The default configuration
73.1921 + specifies no congruence rule for disjunction. We have to add a
73.1922 + congruence rule that specifies left-to-right evaluation order:
73.1923 +
73.1924 + \vspace{1ex}
73.1925 + \noindent \isa{{\isasymlbrakk}{\isacharquery}P\ {\isacharequal}\ {\isacharquery}P{\isacharprime}{\isacharsemicolon}\ {\isasymnot}\ {\isacharquery}P{\isacharprime}\ {\isasymLongrightarrow}\ {\isacharquery}Q\ {\isacharequal}\ {\isacharquery}Q{\isacharprime}{\isasymrbrakk}\ {\isasymLongrightarrow}\ {\isacharparenleft}{\isacharquery}P\ {\isasymor}\ {\isacharquery}Q{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}{\isacharquery}P{\isacharprime}\ {\isasymor}\ {\isacharquery}Q{\isacharprime}{\isacharparenright}}\hfill(\isa{disj{\isacharunderscore}cong})
73.1926 + \vspace{1ex}
73.1927 +
73.1928 + Now the definition works without problems. Note how the termination
73.1929 + proof depends on the extra condition that we get from the congruence
73.1930 + rule.
73.1931 +
73.1932 + However, as evaluation is not a hard-wired concept, we
73.1933 + could just turn everything around by declaring a different
73.1934 + congruence rule. Then we can make the reverse definition:%
73.1935 +\end{isamarkuptext}%
73.1936 +\isamarkuptrue%
73.1937 +\isacommand{lemma}\isamarkupfalse%
73.1938 +\ disj{\isacharunderscore}cong{\isadigit{2}}{\isacharbrackleft}fundef{\isacharunderscore}cong{\isacharbrackright}{\isacharcolon}\ \isanewline
73.1939 +\ \ {\isachardoublequoteopen}{\isacharparenleft}{\isasymnot}\ Q{\isacharprime}\ {\isasymLongrightarrow}\ P\ {\isacharequal}\ P{\isacharprime}{\isacharparenright}\ {\isasymLongrightarrow}\ {\isacharparenleft}Q\ {\isacharequal}\ Q{\isacharprime}{\isacharparenright}\ {\isasymLongrightarrow}\ {\isacharparenleft}P\ {\isasymor}\ Q{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}P{\isacharprime}\ {\isasymor}\ Q{\isacharprime}{\isacharparenright}{\isachardoublequoteclose}\isanewline
73.1940 +%
73.1941 +\isadelimproof
73.1942 +\ \ %
73.1943 +\endisadelimproof
73.1944 +%
73.1945 +\isatagproof
73.1946 +\isacommand{by}\isamarkupfalse%
73.1947 +\ blast%
73.1948 +\endisatagproof
73.1949 +{\isafoldproof}%
73.1950 +%
73.1951 +\isadelimproof
73.1952 +\isanewline
73.1953 +%
73.1954 +\endisadelimproof
73.1955 +\isanewline
73.1956 +\isacommand{fun}\isamarkupfalse%
73.1957 +\ f{\isacharprime}\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymRightarrow}\ bool{\isachardoublequoteclose}\isanewline
73.1958 +\isakeyword{where}\isanewline
73.1959 +\ \ {\isachardoublequoteopen}f{\isacharprime}\ n\ {\isacharequal}\ {\isacharparenleft}f{\isacharprime}\ {\isacharparenleft}n\ {\isacharminus}\ {\isadigit{1}}{\isacharparenright}\ {\isasymor}\ n\ {\isacharequal}\ {\isadigit{0}}{\isacharparenright}{\isachardoublequoteclose}%
73.1960 +\begin{isamarkuptext}%
73.1961 +\noindent These examples show that, in general, there is no \qt{best} set of
73.1962 + congruence rules.
73.1963 +
73.1964 + However, such tweaking should rarely be necessary in
73.1965 + practice, as most of the time, the default set of congruence rules
73.1966 + works well.%
73.1967 +\end{isamarkuptext}%
73.1968 +\isamarkuptrue%
73.1969 +%
73.1970 +\isadelimtheory
73.1971 +%
73.1972 +\endisadelimtheory
73.1973 +%
73.1974 +\isatagtheory
73.1975 +\isacommand{end}\isamarkupfalse%
73.1976 +%
73.1977 +\endisatagtheory
73.1978 +{\isafoldtheory}%
73.1979 +%
73.1980 +\isadelimtheory
73.1981 +%
73.1982 +\endisadelimtheory
73.1983 +\isanewline
73.1984 +\end{isabellebody}%
73.1985 +%%% Local Variables:
73.1986 +%%% mode: latex
73.1987 +%%% TeX-master: "root"
73.1988 +%%% End:
74.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
74.2 +++ b/doc-src/Functions/Thy/document/session.tex Wed Mar 04 11:05:29 2009 +0100
74.3 @@ -0,0 +1,6 @@
74.4 +\input{Functions.tex}
74.5 +
74.6 +%%% Local Variables:
74.7 +%%% mode: latex
74.8 +%%% TeX-master: "root"
74.9 +%%% End:
75.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
75.2 +++ b/doc-src/Functions/conclusion.tex Wed Mar 04 11:05:29 2009 +0100
75.3 @@ -0,0 +1,7 @@
75.4 +\section{Conclusion}
75.5 +
75.6 +\fixme{}
75.7 +
75.8 +
75.9 +
75.10 +
76.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
76.2 +++ b/doc-src/Functions/functions.tex Wed Mar 04 11:05:29 2009 +0100
76.3 @@ -0,0 +1,91 @@
76.4 +
76.5 +\documentclass[a4paper,fleqn]{article}
76.6 +
76.7 +\usepackage{latexsym,graphicx}
76.8 +\usepackage[refpage]{nomencl}
76.9 +\usepackage{../iman,../extra,../isar,../proof}
76.10 +\usepackage{../isabelle,../isabellesym}
76.11 +\usepackage{style}
76.12 +\usepackage{mathpartir}
76.13 +\usepackage{amsthm}
76.14 +\usepackage{../pdfsetup}
76.15 +
76.16 +\newcommand{\cmd}[1]{\isacommand{#1}}
76.17 +
76.18 +\newcommand{\isasymINFIX}{\cmd{infix}}
76.19 +\newcommand{\isasymLOCALE}{\cmd{locale}}
76.20 +\newcommand{\isasymINCLUDES}{\cmd{includes}}
76.21 +\newcommand{\isasymDATATYPE}{\cmd{datatype}}
76.22 +\newcommand{\isasymAXCLASS}{\cmd{axclass}}
76.23 +\newcommand{\isasymDEFINES}{\cmd{defines}}
76.24 +\newcommand{\isasymNOTES}{\cmd{notes}}
76.25 +\newcommand{\isasymCLASS}{\cmd{class}}
76.26 +\newcommand{\isasymINSTANCE}{\cmd{instance}}
76.27 +\newcommand{\isasymLEMMA}{\cmd{lemma}}
76.28 +\newcommand{\isasymPROOF}{\cmd{proof}}
76.29 +\newcommand{\isasymQED}{\cmd{qed}}
76.30 +\newcommand{\isasymFIX}{\cmd{fix}}
76.31 +\newcommand{\isasymASSUME}{\cmd{assume}}
76.32 +\newcommand{\isasymSHOW}{\cmd{show}}
76.33 +\newcommand{\isasymNOTE}{\cmd{note}}
76.34 +\newcommand{\isasymCODEGEN}{\cmd{code\_gen}}
76.35 +\newcommand{\isasymPRINTCODETHMS}{\cmd{print\_codethms}}
76.36 +\newcommand{\isasymFUN}{\cmd{fun}}
76.37 +\newcommand{\isasymFUNCTION}{\cmd{function}}
76.38 +\newcommand{\isasymPRIMREC}{\cmd{primrec}}
76.39 +\newcommand{\isasymRECDEF}{\cmd{recdef}}
76.40 +
76.41 +\newcommand{\qt}[1]{``#1''}
76.42 +\newcommand{\qtt}[1]{"{}{#1}"{}}
76.43 +\newcommand{\qn}[1]{\emph{#1}}
76.44 +\newcommand{\strong}[1]{{\bfseries #1}}
76.45 +\newcommand{\fixme}[1][!]{\strong{FIXME: #1}}
76.46 +
76.47 +\newtheorem{exercise}{Exercise}{\bf}{\itshape}
76.48 +%\newtheorem*{thmstar}{Theorem}{\bf}{\itshape}
76.49 +
76.50 +\hyphenation{Isabelle}
76.51 +\hyphenation{Isar}
76.52 +
76.53 +\isadroptag{theory}
76.54 +\title{Defining Recursive Functions in Isabelle/HOL}
76.55 +\author{Alexander Krauss}
76.56 +
76.57 +\isabellestyle{tt}
76.58 +\renewcommand{\isastyletxt}{\isastyletext}% use same formatting for txt and text
76.59 +
76.60 +\begin{document}
76.61 +
76.62 +\date{\ \\}
76.63 +\maketitle
76.64 +
76.65 +\begin{abstract}
76.66 + This tutorial describes the use of the new \emph{function} package,
76.67 + which provides general recursive function definitions for Isabelle/HOL.
76.68 + We start with very simple examples and then gradually move on to more
76.69 + advanced topics such as manual termination proofs, nested recursion,
76.70 + partiality, tail recursion and congruence rules.
76.71 +\end{abstract}
76.72 +
76.73 +%\thispagestyle{empty}\clearpage
76.74 +
76.75 +%\pagenumbering{roman}
76.76 +%\clearfirst
76.77 +
76.78 +\input{intro.tex}
76.79 +\input{Thy/document/Functions.tex}
76.80 +%\input{conclusion.tex}
76.81 +
76.82 +\begingroup
76.83 +%\tocentry{\bibname}
76.84 +\bibliographystyle{plain} \small\raggedright\frenchspacing
76.85 +\bibliography{../manual}
76.86 +\endgroup
76.87 +
76.88 +\end{document}
76.89 +
76.90 +
76.91 +%%% Local Variables:
76.92 +%%% mode: latex
76.93 +%%% TeX-master: t
76.94 +%%% End:
77.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
77.2 +++ b/doc-src/Functions/intro.tex Wed Mar 04 11:05:29 2009 +0100
77.3 @@ -0,0 +1,55 @@
77.4 +\section{Introduction}
77.5 +
77.6 +Starting from Isabelle 2007, new facilities for recursive
77.7 +function definitions~\cite{krauss2006} are available. They provide
77.8 +better support for general recursive definitions than previous
77.9 +packages. But despite all tool support, function definitions can
77.10 +sometimes be a difficult thing.
77.11 +
77.12 +This tutorial is an example-guided introduction to the practical use
77.13 +of the package and related tools. It should help you get started with
77.14 +defining functions quickly. For the more difficult definitions we will
77.15 +discuss what problems can arise, and how they can be solved.
77.16 +
77.17 +We assume that you have mastered the fundamentals of Isabelle/HOL
77.18 +and are able to write basic specifications and proofs. To start out
77.19 +with Isabelle in general, consult the Isabelle/HOL tutorial
77.20 +\cite{isa-tutorial}.
77.21 +
77.22 +
77.23 +
77.24 +\paragraph{Structure of this tutorial.}
77.25 +Section 2 introduces the syntax and basic operation of the \cmd{fun}
77.26 +command, which provides full automation with reasonable default
77.27 +behavior. The impatient reader can stop after that
77.28 +section, and consult the remaining sections only when needed.
77.29 +Section 3 introduces the more verbose \cmd{function} command which
77.30 +gives fine-grained control. This form should be used
77.31 +whenever the short form fails.
77.32 +After that we discuss more specialized issues:
77.33 +termination, mutual, nested and higher-order recursion, partiality, pattern matching
77.34 +and others.
77.35 +
77.36 +
77.37 +\paragraph{Some background.}
77.38 +Following the LCF tradition, the package is realized as a definitional
77.39 +extension: Recursive definitions are internally transformed into a
77.40 +non-recursive form, such that the function can be defined using
77.41 +standard definition facilities. Then the recursive specification is
77.42 +derived from the primitive definition. This is a complex task, but it
77.43 +is fully automated and mostly transparent to the user. Definitional
77.44 +extensions are valuable because they are conservative by construction:
77.45 +The \qt{new} concept of general wellfounded recursion is completely reduced
77.46 +to existing principles.
77.47 +
77.48 +
77.49 +
77.50 +
77.51 +The new \cmd{function} command, and its short form \cmd{fun} have mostly
77.52 +replaced the traditional \cmd{recdef} command \cite{slind-tfl}. They solve
77.53 +a few of technical issues around \cmd{recdef}, and allow definitions
77.54 +which were not previously possible.
77.55 +
77.56 +
77.57 +
77.58 +
78.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
78.2 +++ b/doc-src/Functions/isabelle_isar.eps Wed Mar 04 11:05:29 2009 +0100
78.3 @@ -0,0 +1,6488 @@
78.4 +%!PS-Adobe-2.0 EPSF-1.2
78.5 +%%Title: isabelle_any
78.6 +%%Creator: FreeHand 5.5
78.7 +%%CreationDate: 24.09.1998 21:04 Uhr
78.8 +%%BoundingBox: 0 0 202 178
78.9 +%%FHPathName:MacSystem:Home:Markus:TUM:Isabelle Logo:export:isabelle_any
78.10 +%ALDOriginalFile:MacSystem:Home:Markus:TUM:Isabelle Logo:export:isabelle_any
78.11 +%ALDBoundingBox: -153 -386 442 456
78.12 +%%FHPageNum:1
78.13 +%%DocumentSuppliedResources: procset Altsys_header 4 0
78.14 +%%ColorUsage: Color
78.15 +%%DocumentProcessColors: Cyan Magenta Yellow Black
78.16 +%%DocumentNeededResources: font Symbol
78.17 +%%+ font ZapfHumanist601BT-Bold
78.18 +%%DocumentFonts: Symbol
78.19 +%%+ ZapfHumanist601BT-Bold
78.20 +%%DocumentNeededFonts: Symbol
78.21 +%%+ ZapfHumanist601BT-Bold
78.22 +%%EndComments
78.23 +%!PS-AdobeFont-1.0: ZapfHumanist601BT-Bold 003.001
78.24 +%%CreationDate: Mon Jun 22 16:09:28 1992
78.25 +%%VMusage: 35200 38400
78.26 +% Bitstream Type 1 Font Program
78.27 +% Copyright 1990-1992 as an unpublished work by Bitstream Inc., Cambridge, MA.
78.28 +% All rights reserved.
78.29 +% Confidential and proprietary to Bitstream Inc.
78.30 +% U.S. GOVERNMENT RESTRICTED RIGHTS
78.31 +% This software typeface product is provided with RESTRICTED RIGHTS. Use,
78.32 +% duplication or disclosure by the Government is subject to restrictions
78.33 +% as set forth in the license agreement and in FAR 52.227-19 (c) (2) (May, 1987),
78.34 +% when applicable, or the applicable provisions of the DOD FAR supplement
78.35 +% 252.227-7013 subdivision (a) (15) (April, 1988) or subdivision (a) (17)
78.36 +% (April, 1988). Contractor/manufacturer is Bitstream Inc.,
78.37 +% 215 First Street, Cambridge, MA 02142.
78.38 +% Bitstream is a registered trademark of Bitstream Inc.
78.39 +11 dict begin
78.40 +/FontInfo 9 dict dup begin
78.41 + /version (003.001) readonly def
78.42 + /Notice (Copyright 1990-1992 as an unpublished work by Bitstream Inc. All rights reserved. Confidential.) readonly def
78.43 + /FullName (Zapf Humanist 601 Bold) readonly def
78.44 + /FamilyName (Zapf Humanist 601) readonly def
78.45 + /Weight (Bold) readonly def
78.46 + /ItalicAngle 0 def
78.47 + /isFixedPitch false def
78.48 + /UnderlinePosition -136 def
78.49 + /UnderlineThickness 85 def
78.50 +end readonly def
78.51 +/FontName /ZapfHumanist601BT-Bold def
78.52 +/PaintType 0 def
78.53 +/FontType 1 def
78.54 +/FontMatrix [0.001 0 0 0.001 0 0] readonly def
78.55 +/Encoding StandardEncoding def
78.56 +/FontBBox {-167 -275 1170 962} readonly def
78.57 +/UniqueID 15530396 def
78.58 +currentdict end
78.59 +currentfile eexec
78.60 +a2951840838a4133839ca9d22e2b99f2b61c767cd675080aacfcb24e19cd
78.61 +1336739bb64994c56737090b4cec92c9945ff0745ef7ffc61bb0a9a3b849
78.62 +e7e98740e56c0b5af787559cc6956ab31e33cf8553d55c0b0e818ef5ec6b
78.63 +f48162eac42e7380ca921dae1c82b38fd6bcf2001abb5d001a56157094cf
78.64 +e27d8f4eac9693e88372d20358b47e0c3876558ebf757a1fbc5c1cddf62b
78.65 +3c57bf727ef1c4879422c142a084d1c7462ac293e097fabe3a3ecfcd8271
78.66 +f259833bac7912707218ec9a3063bf7385e02d8c1058ac06df00b33b8c01
78.67 +8768b278010eb4dd58c7ba59321899741cb7215d8a55bee8d3398c887f02
78.68 +e1f4869387f89141de693fcb429c7884c22dcdeddcaa62b7f5060249dfab
78.69 +cfc351201f7d188b6ed68a228abda4d33b3d269ac09cde172bc045e67449
78.70 +c0f25d224efbe8c9f9d2968a01edbfb039123c365ed0db58ad38aabe015b
78.71 +8881191dd23092f6d53d5c1cd68ebd038e098d32cb24b433b7d5d89c28ee
78.72 +05ea0b6070bb785a2974b5a160ee4cf8b6d8c73445d36720af0530441cd9
78.73 +61bc0c367f1af1ec1c5ab7255ddda153c1868aba58cd5b44835535d85326
78.74 +5d7fed5ff7118adb5d5b76cc3b72e5ff27e21eb857261b3afb7688fca12d
78.75 +1663b0d8bdc1dd47a84b65b47d3e76d3b8fa8b319f17e1bb22b45a7482fd
78.76 +f9ad1b6129e09ae47f15cd2447484cd2d64f59ab0f2f876c81e7d87ccdf9
78.77 +005aa8fc093d02db51a075d571e925f2d309a1c535a1e59d34215c6cd33e
78.78 +3c38997b4956461f376399901a8d0943dca6a335baac93fc8482c0659f04
78.79 +329c6f040b35828ea6dd1bd1858f2a9be4ef77731b5b75a1c536c6bc9479
78.80 +0821e5d88f6e2981835dbfd65ec254ebcf2cf49c917d121cd3bbb476a12b
78.81 +69c15f17d9c17bb15ad1e7d31d2afcf58c8f0ad526d68615a0f1ac3b1d1c
78.82 +d3beafeea3cf56c8f8a66367c70df9159f0b1b3157ccfd010045c4718e0e
78.83 +625c0891e85790c9b97b85517c74c9d55eaca31a01cddc64898bf0eeadf3
78.84 +53391a185e507dcb0a6f52661a56357ac818dfc740a540aadf02f4e7a79d
78.85 +8008a77cd30abde337025b01217d6a68c306abe145b7260c3478fa5f366f
78.86 +b2d37259ead8a8ec2db2f09ae0eb3a682d27b0d73a60935f80254c24426a
78.87 +003a87a29a4370cbf1b2ef1e19ad8466ec725fd5b463d06011a5e0da2258
78.88 +ff6c1483c4532bc21f2ed9b99b929b2800ddefc1a98d12ba085adc210bac
78.89 +e0274b69e24d16af015a51ca73edf779a7534a887aa780337ad966839881
78.90 +edc22ba72038aa1a96a6deba24ad676795da711b92f8cf5f54cb4322ec04
78.91 +40ef9e15b11e3005f3ff69376ecb29bb66e8fc1b685f2b05fb162fcb35aa
78.92 +d7eb2a8ec39b97ab1ff05ef02f8dbbc12085a5cd252cc4010fab7f63dfd5
78.93 +7fa1be86f724d37db5faef17ae8e8e537444e8e9db917b270344183473af
78.94 +7f47d5703a160d8ef1e772438620d3336b2fbcf6433612e4b5e64fae0329
78.95 +8a3c4010c17d93f13ba66d549c69dd58c7d26ddc90285fed831918563a16
78.96 +2a7ac2511e2f18c9eb3df905a9dcba65a31cc1c39f07458abb11b4c60346
78.97 +aea19070e126982f1dde336e79be0ecd69a8afbe2493d064d4d2ff38788b
78.98 +b3038125961302db9761403c3b8019ec641e107425002205a77ae2ae0f4f
78.99 +7550d623dd03f0ec0199f42a9a8b89514e2e21baca9b3c8c96ca48cbf9dc
78.100 +ee6d6241d713e014b49e83ad85e62a6b2f70b58e4cc72d41ea6fcbdd3b5c
78.101 +890c8af0d24200658773b1628c6cc9aaaabb08865ee4c7ff2c513ad7aa23
78.102 +155a321213fa94731683a3e282a0e60aa3c87aade3da231465bdd9097f2c
78.103 +89a1af8e5b9649143f2d9482546501ea97e8bea2f5d5eea97d4f19bb6835
78.104 +3138d3babb2461c08d537491aaede1f23d734c6f099eb5bef6e2ffaaf138
78.105 +e5ab71b8b41599091037e440127a4eaedf208c20c8a2fc62eadab191d1ab
78.106 +4d5531f826aa6b9fff2797a7f54673e0a3fae09a93a0dfafb8b11d60dc69
78.107 +5acf9b7e1a47c31d0b5a0b85b7b50cddff5ac831651d9c7469c2139c7a89
78.108 +7d2f868f36c65156921803eccfdbdd1618595ab6d2a9230ef523a1b5ee51
78.109 +f2a0d200fc0e94aff7f546593ff2a3eb865d129895af01b8ab6e4616fe20
78.110 +9123b6e2b7e0817adc3cdb78ae8b0b1d75f2986ebd8fb24c4de92ac9e8c3
78.111 +6afa520636bcad2e6a03d11c268d97fa578561f6e7523e042c4cc73a0eac
78.112 +7a841907450e83d8e7a8de4db5085f6e8b25dc85b59e018380f4b9523a7f
78.113 +02cbeec989f0221b7681ec427519062b429dcd8fc2e4f81173519f88e2e4
78.114 +3798b90a84060920f6ae789afd6a9182e7fec87cd2d4235d37a65c3f3bcc
78.115 +c742c89cbe5f3e2ba6c4f40ebba162e12569d20684cc167685285a087e7a
78.116 +0a995fe1939bf25c09553512ba2cf77ef21d2ef8da1c73ba6e5826f4099e
78.117 +27d8bc7b3545fc592b75228e70127c15a382774357457cd4586d80dc0bd6
78.118 +065aee32acfd5c0523303cece85a3dbf46853b917618c0330146f527c15b
78.119 +dbb9f6526964368b2b8593eed1551dad75659565d54c6a0a52da7a8e366f
78.120 +dd009ef853491c0fb995e19933cba1dbdc8902721c3ea6017ffdd5851cb8
78.121 +3c8bada46075ac121afe13a70e87529e40693157adcc999ed4657e017adf
78.122 +f7dbac4bc0d204f204c6f47b769aaf714f9ec1d25226f24d0a1b53e28ac5
78.123 +374ab99755852c1431b2486df5fd637e2005a25303345a1c95a15a1189ba
78.124 +f6f6883de1ad46d48427b137c2003d210ab2b2f5680f2633939f289d7553
78.125 +eb943adf8127f1c3ee7d6453b5566393700ad74ab86eb9a89f8b0380af55
78.126 +6b62f51b7dbd0c5dcc9a9fb658944d7ad5845d58dedc2d38200d0ef7cb0f
78.127 +76041dc104ef3ab89c1dc2f6a75635d48051c8a7dd9f5e60253a53957ec8
78.128 +9d1266566d7ed20d79dfc2807b397d7cf056bdaccdb72528a88aa4987682
78.129 +c909b2fe1e35a71c2f29e89a2bf32173967e79610367ce4574ba6a1cc031
78.130 +cfb176fc0313f74f91a866ef9954b95b29caf917a6b919586f54d23cb7ce
78.131 +23305886ae7760ebd6263df0d3c511ac7afc361df78bc2621f66d3268b99
78.132 +078fa59124f0eb9476496c938eb4584e87455dc6f2faa999e938460b31c6
78.133 +28021c652acfa12d4556aa4302bbcd043e60389480b796c3fc0b2e51b81e
78.134 +c2afa4a34335318a1c5a842dcaa120df414acba2e79ab5cc61c99e98108c
78.135 +5cb907a96b30d731131782f9df79aabfc16a20ace8852d047497982e11c8
78.136 +26321addf679de8a96a2d18743f6f2c3b2bc397370b10ad273fcfb76b48b
78.137 +9dad27cf89ca2c370149cd48ab956e9bbce01cbf8e1f0c661b99cf19b36e
78.138 +87b6165dd85ae3f3674525e17d85971093e110520d17f2d6253611e35ec9
78.139 +e17000e48e2926454c1e8eb4098e0115b49536f2c33505eb5e574f7a414b
78.140 +e176398c5ddf6d846ea5ddf2a5e94c0422e0115c57a8c9e56bf8ba962c82
78.141 +698c96bd6138baaca7347e44352cc62df4eeba364954ad921a5a43280980
78.142 +264df4a7fb29d005423179f7bd1d98b4280d62ce23c927551f1ffc2b8f17
78.143 +0a9c23656c0c91b640cdcfdbd88089ffb28d3ac68bad25dbbed82c083696
78.144 +1f9f86a6183cc1061ffdb32279796569d05b31c946955402d0be1fb9f2bf
78.145 +304d1ad8e1e357be49e6e2ee67f7f1e7bc699d46a5f7853fe659ba2e1930
78.146 +0d3e3ea658b9862701dcab08fdd23bf1d751777f25efbe9e02d12b5612b3
78.147 +c3fc2275190346b94ec4024e4ade08e54d75c0b4c48f4956b9182e8ce997
78.148 +74b54da4a9318c099d89f1ce3b6803a95f48b9fb8b845372be25e54478e8
78.149 +49e4707ea03a36e134efa661e4e6250d89649ae074cfd9d6b9e2071c1099
78.150 +3b8a5a5ebc3e1cb228c97565aef7f254e3f90af8a3dd281c83792755719d
78.151 +c6a5b3bab4aa6be5afe9624050eee8dfb13b018f4088c932cd48ace38dfe
78.152 +b1b4218dba8f7fada6628076acf1b54db0c95d4fb12232f1fa9d1ba848f9
78.153 +fe80c65b75d6946c00fe78839142c5302707d9269b24565dbcc551aca060
78.154 +b4d0f99b961dd3cc795a982063ac42e9fc81fc98add42744a9f92e74b00d
78.155 +637ee4606ea2099b6c763493c3159f8e52a90dafca682010c0e92bc9038a
78.156 +10abb066c75c8d97f7ad6fb1a37136e52cf2093c4fa485fe12adad10e4d0
78.157 +83b78b023628ddc5326cbf8392516027a9f3de4945f93488e4a1997efd2a
78.158 +22c2c136dbac1bdb829e082beac48cdd06dcb17bacf09451c7b636bd49a8
78.159 +fc60cb1d2292250bea78e1dd276725ab4c526b66ddabf4e1b2bf0a2571df
78.160 +2490df70735f5da321fac74fe4fab54444e53dace9832cff38a70c58104a
78.161 +4f0c0545dcf7a1a9ecb54e0e32d6d8195d30b2c98a567741fcf325a4ddeb
78.162 +244a1a35676e246ddc835fac13b569f35f22ec93191eca3efbe17ff9a950
78.163 +d08f863710b2bbecec969068c498eb2338b68f3fc3f5447449fe4de2b065
78.164 +e068ecd9255d369b2bb6c4b0b7423774bed69294758aca2bdb1a8d5bf618
78.165 +d3fa09462f7838e8a79b7a53bebe6dacb0a1561eaa074bc6f069f6a06fb2
78.166 +c4a5cb13e2172bce9be659a82665da5cded73da84322bb16aa6e19ac1958
78.167 +7515cb5d2b65e65e803f76700ce5efd3df7fe4ed431fae0e8e286b1d5056
78.168 +a0d18df926b2be7a93c503ab903abd4788680a6201fdc299f2cb5d6a9b6e
78.169 +2048109c8d1fb633a54128938594b2cce86a7e0185e7d59e6536584039ec
78.170 +9e30ff7be6ddba9fdba82de7415fdc47de84d97afb1aa3ba495bd91dee9d
78.171 +f3b21ee1164987dd8510925087cd0919f1085cba6e4dd3c7384d26667f94
78.172 +ad7f736a60d8bd76dfaa4b53c23536fc309ff2317c48ee0107ff2ca4d1b3
78.173 +f78c5a27b901c931128bdb636094ef0cd543a5b62b7dbe10ed83aed5780c
78.174 +a16067a4a7e8b7c5bf8a8e822149bc1b5bcdabe13a7f6aa6eaeff24a42f4
78.175 +a58a2b70f545103540169137fda9abb589f734b6776cb50402d6123ce802
78.176 +10dce05e3697a98c9411cf60a02c278c91e03d540b936cd00c668960e357
78.177 +1aeaf4d94cfb496b259ec0d8fdba9199fb46634ff177bc8d310ea1314eef
78.178 +d46c927a981c58e88743ed4e07d80fe841edee812e3053412bf2e710146c
78.179 +b25dec8ea70c38bb1f6e4db3c2e8ba521963c1584eeb60ea1e9555058f13
78.180 +e98307c13cbd15c26b611f543149b1ddf88dd6296ae703f58daeb67f1b03
78.181 +ab5b24c72d5770cb9d8ed242c4faaad1dd940ada00e98ff3a61799d13355
78.182 +aba916910aa9a6e5ee8af438d0ba8235346fcd139b9d2cb7db7bd3f298a3
78.183 +94ff0aff3b9042f32a004e042c346a5ea35917f229848a9c5a32909b0090
78.184 +4aa715640277a6ada99f8b2927fda22899ff1347f42bac73e2bd4bbf3945
78.185 +55fd7dd30d5c6dadf5c259fdb2455d8c607de1c5da588e20159f18e4e8da
78.186 +b714e532d888a0386c52c2b85964251af003ac9d10c0c8b9b3465e1dde48
78.187 +2e74a29e17a7cf6c9a43b5af1646f0b8508f98e9a1279ec3908073d89dcb
78.188 +aa093e8dd1004c1ecccce0803095b0069d4be7a1eb14b02efc37d137dfe3
78.189 +f0190bc9628069abc257f45d0e050e60c7f5281277937dd986fcd5b94a2b
78.190 +845a1a75addd74a142800f18ef408c08a2c2ad16a93298f148c0ae7d2990
78.191 +ded147f92f053809a60d4f992a227167aad5b5eb2bbe8a4a77dc77a08b72
78.192 +6acb34422e2532eec7e274e4a42d71ee584f5f3df5a3a5b379974ede73ab
78.193 +5f1b0a2dbfcc8cfac4747ca26eb6030dc2f85a104b754432977850c093b9
78.194 +97ed90af711b544ff682e7b1eac82b2b7b44014b09c17ecf084c994a095d
78.195 +9eeef5391305caf093b62ac9916f982a436d521fcf4d75c5b8e4d92266fd
78.196 +e99a58aa39d7693ecd1796b8851761d64bbca39a6d5a0b4533ae47123327
78.197 +f98d0ad0e8b36625cc3647b55459552906d8a1d5766845ffac101980efcf
78.198 +79657e365510be5db557cefef21193ca3cf3dad175ee2e7ae91d174fdc06
78.199 +2ff5c51ffe2f021122e96df042019d3a1883e662537ec1b69c11fbb6e750
78.200 +0132eabf5803c816153ecbff60ca3b3b39708c26cb1751afb2e65d8e5f4a
78.201 +c4397a88fb1f112672fcdd24e4ba545c5b2a7968c17b62f8e2530a8acbff
78.202 +cfca82c64b7abcab84e2c4a0a7ced67b15669301fe9ff2c756e70ff7ce33
78.203 +497be6acc4ac5617e1f043bd8a87416299a39bf17fc31c02d72d75fdc2a1
78.204 +e60669fa4d5e4a49d9afea2f53f4626680e9c0dfca223529efa415c4343a
78.205 +b6067aa800c484457ea050eaaa5d3fafeedd0eec72f327e02c6b3912b5a8
78.206 +c404de4839c9c4a99da42681cde43316606a34c7d2f02269de1aab776857
78.207 +e668f35946af4d618d36d444bdc02b1f63ea25b6260b4fb606ac8575b5c9
78.208 +782a5de4037350d5753b1537537ccb008c454eeb264e6cd4727c999e240e
78.209 +0ac89e95a896b67d54910a3531345f64198ad394b5ceb52881f1dd9e6beb
78.210 +95862dc188d45b3e46aacb5fe40097947dab9bc3c1ee46bfc9b1b3ed6167
78.211 +efd0d65ceb043d7b24c1456676e4baa47b1209a315f199bb3a91f4374cd9
78.212 +cc0b40d3f09f19f8dd8a46915eee55eeeeb3c7b8f437106ee491ef0f4ff9
78.213 +2c5c6f779e0fbe7bd5293964bb645ca362b106abeb773571d9ae83b786a3
78.214 +d5a4ea3ea970daadc46cc5e6037f76fd20e0fffc47cf4e7af9522b91f96b
78.215 +3297720fd45d9bc2200622ad2ca9445556c8a8202b1991bc63da360d021d
78.216 +55be2528e043f803e08da99b91ab9cfc5e65b2655d78206b4aecd445a7b0
78.217 +1caa0d06b0a55e8f04b70b60b04a860c8e1ab439f4910051e3f7441b47c7
78.218 +8aa3ab8519f181a9e833f3242fa58d02ed76bf0031f71f9def8484ecced8
78.219 +b6e41aca56176b6b32a2443d12492c8a0f5ba8a3e227219dfd1dd23fcb48
78.220 +fcfd255dbbf3e198874e607399db8d8498e719f00e9ed8bdd96c88817606
78.221 +357a0063c23854e64ad4e59ddd5060845b2c4cddd00c40081458f8ee02c7
78.222 +303c11747bd104440046bf2d09794fca2c4beb23ed1b66d9ccb9a4dd57ad
78.223 +a24943461ecc00704c916bdc621bfddb17913dfb0f3513b65f3ab015786a
78.224 +caa51ee9546bc8ddf87e2e104137e35ddf8f8d23724e9a53824169bc7cfa
78.225 +99562656e6f1c888d4dbff0b269c5d1e733e5f212d91297610201eb43249
78.226 +35e336dd0052738db2d64f3e89429903bb5c1810009cf766e9a06223dd2f
78.227 +219b706394a121dc029af55c6ada9052af59682ef7c51e121cf16f0319ac
78.228 +0aa9512ef900c548d673fe361da19052808797e958209072e145d46ec8cc
78.229 +a89fafd76630eff30ae979973bdf0f8c9e469d8edd3b1c93731c72f976b7
78.230 +d81142bc15c376403f967affaa5f482efd57c6f91970729d16db851f0ed3
78.231 +ea7d82f409307b5b436886c1beda94a1fa3ab1b60686f6574c844fb2c0b3
78.232 +a07174dc4f27b4fed2f8bd4d5436be4b343e5efdf0400d235bd910255341
78.233 +a20770804a26f8437e9bce6da8e9f8258a343c7aee291f1510be306ae67a
78.234 +ab1d7696453530c02fd153bbe49dbf62baad6146029cbd1656cdb76c952c
78.235 +b93edfee76fe33832930be59636bb947e8ad285f20f663cccf484fba97d6
78.236 +7446c7b6c6f5857428bb1737d9ae801df75d9cb4d7bd59ef7a4cbadde928
78.237 +38f15d232005585d2e40483d2d3e08cc8f398bb43afedb84343c3ba3835d
78.238 +0ba82a86dce859cf655f85e63e41365e0dbefcf511b9a27a2b6e66b2ad3a
78.239 +c657902842287a317e46ceaa93b5088f09d53a65815b44538af90ad3b06b
78.240 +4e5e2dc509f02e30a01e05201c67d4d39582bbe64e20b669f5fd787909a3
78.241 +30fc50a95b31426bbb57a4fbf9feacdc31f98bcf50da7e50c2bfc169c6fd
78.242 +ccf213cdb878653bcea372968ea6e31fd30dd55434cc91c0af22179ce669
78.243 +a05493f195e12432c6173ae2ac3c94fb83f38210014a9f969ea2b44e99f5
78.244 +e5a7317e848d429ad62167a4fc5001149676c0c28cdf59b8d1c5a582f516
78.245 +3eee855312777fee6dacbf993f5c058f355dbde6552dc960d336eee445dd
78.246 +11d53fd21b745d1e5ec317efbbef25e070d0a36797a6081c356ac2328e64
78.247 +e5c55fbc81dc75d9c1575548ece74b8307eef485aa8e28859a2e0435c831
78.248 +23a600efb323c362fe9f02407a5411c41a69566cd50add324b63ab939980
78.249 +b9d7a929ae4887163cfa7acbfc9fabaab8987a1f6906b9881491cd055b94
78.250 +485c968479dbb05b34ed0cd6844729a692978c6928c3392e33e8324ded88
78.251 +814cacdac8128e1425c0091a13558100d7cdbed5992795d94d39c32f32dc
78.252 +621ab6f3b75187a66741f61d6a9c91d791b1cfc3d0e94d4a76302e0c3f2e
78.253 +cbdc51f14f3251aa5c8bb989f0e13ee500b7b7f2f1e52ca970ad8a7b4b99
78.254 +57e93126254297380d67179deb8ff1e99d5cdf7a35c5bb9fa7b402e63234
78.255 +78640344e1f10c378ad23c5cd1aa18e1e0b308db70d3a624a455f8e291a2
78.256 +ee102ad10776208c2d546cb76d89ca8103a8b95f8acc2d2bdc9791324915
78.257 +6c9e05429091071f0c5b76d82c8d1c8a69d840fd460922cd2090624bc218
78.258 +0c9391005926a25042a55e322060807363462e1cdeab309033124ba3a884
78.259 +1db13f39edae04ec52cde9dbde64ddda1ad805141d4230ec76bd81fd98d7
78.260 +0d90fa1aaa26ea551bf687ddd6cdcf3de5a446b266c68434f07d9c0b382d
78.261 +5816c4e22f22cc03ff78064c6dffb12315c6bcbbf5dc510f5aaabf23471a
78.262 +234efceeb4aa2f9af9ea787c014c5587ef162fc5b35e8f4c23b168c6e247
78.263 +41d33dcc11d2a56d3ba9d8eed6e79aebf9f0faf1a3aeb89d792d69041f0b
78.264 +b8fadfc0aa090effc6ae5e2f13cdbf54b5bed69b039eef2627769613b6f1
78.265 +aefe9b66747fe8feaf7455796740f411a770d4a1764f0483719584880f45
78.266 +430e38d3af184145892a08b2add234a3f3ee4ccfc9f6995c02392adafccd
78.267 +722f366d748cfe9373fbf5f878ed47e9d221fd156bb28369df9e7d2b79da
78.268 +76120d135ebaf36cff93beb7e313c2b2de7477176fc19609a1b906c995cd
78.269 +defef08899265b6b8aefb44da1aadefd1c523dce5ca1b84c0c652b3009fd
78.270 +057789892d4d31764f181754b2e0a62c465587585509989a219711a5e4e2
78.271 +5b3b340ca8fdd3f04fef204b1b722b2f6c2ccb00c3cf1a94ba9bdfbfeda9
78.272 +e2a062c6f1ced3b8aae5dae32ade1fca1001f98d0ad0e8b36625cc3647b5
78.273 +5459552906d8a788eb8bc734ccb65fe9582c71df94fd95d22c5323de235c
78.274 +28220fb9a2ccb37362174d8cd5922c9e5a87b51d0668555100a33e33750e
78.275 +f1f795cbed962494a994be7ce8cf71fc58ff4204551b1615ed27cf088171
78.276 +fd000b72462b67935961e7c6c3a05bfd67b9ba094ea2c16fdf486da912e1
78.277 +e97bfd1c17934535e551cede20c001b5d2adb2be4cbad7d6ba0bdeae4b1a
78.278 +a739f90293e67ecbdeea4d35825e092697fb05b215083e3f3d6be260790e
78.279 +2a175fd44eb1c4c16759504827a6eb58a838c4d65fec6eef108495577019
78.280 +15740cac164111892e8d1cc447cd208e243a89ab847d8ebf4fb98bff49e7
78.281 +a3453facf3b0e8cb67590f390173ddba68324531d2e426aed152e12301d7
78.282 +538c1f3c0048a9cc00c009a1a9138460082123209c1e007266fbf236eb72
78.283 +21f87d4ca38a0b699e84ca230ffb5095f90a6528bf2a9118f95ac9ab8d2d
78.284 +ed9eed9b8b27be894b717469758c8d94fa89acc64f530f432d0e5f16c922
78.285 +36d6a63410f099c9e909450fd731d698ef658d8ffc1de14817b850814f68
78.286 +1a4a9be5cc7a71c381974c249f0b209bfdc2e97f9540c96f57bb4d283622
78.287 +00969b82011315289e6a025b137030a0af3b4b42b00fed7cec49df43c59e
78.288 +3b2495a036dd1b17a8e6adae63bfbbd48807c44b5bbf71813355e1b0e58e
78.289 +22b6fb88005fc55565be49c17244901b73ef02fc4eb7669be5af22d89c0d
78.290 +dff0fc6821d810d13e5821d48d4a71d7e463d5b60bc279d0dcf5f8da3a95
78.291 +905b56d6f2be95e6d4243b1048e3b662e62401ffaa3bc3f5f90b0854b8a3
78.292 +8c38039f61fcb359b06bbb7d59e3b39a295dccd6db9a8b83a6f64ef8dc94
78.293 +a77123dd164cfd1c46f1ee51aa19c3d6e7db92a298d10159f2b5eff2caf9
78.294 +dc93a6d267fb65bd900d6adf0c6be598050b6d3a9b3a322ab3c9e880d774
78.295 +1f58016ff97e5f606b5dbd72ba99252c669209bb556dd5be84fdd7c1ce92
78.296 +8a3b3d3aab8d37e6b740227563bb4d60f6bb04052356e1a48d2079feca44
78.297 +7ea17fd06f208426d045dee660d1d6460455f8d20dbc5ae64550bbdf60d7
78.298 +27d96cc9afef842a8c8c78ea2257e6c6d0d207c80cfe399e8874c693274e
78.299 +d2c2022d303ca50a70624b07434fb85040a76a823f446c7454dab4f9c05f
78.300 +10274eb5ba164aa3649d1bc90694316ba5cb3e7df4442e777124cff7ebef
78.301 +53df2320a0c441ab61666493cb43da46d5711c21699de85bc74359444da2
78.302 +e3e397d4c16234f81531505b621aa242a6698886f82b447104b1f1062f60
78.303 +b5c87cea9151bb3c627bfa4532b06fd147c556ed8d61ae30a8719dfb8705
78.304 +f8a6c74368381403640cc57026d3790c49e2bbd1c0e48285ec6ba44de678
78.305 +e3a1394d659c412f09644b83ee1a333a1f51ad8deb4e6d77b3b226ac2c4f
78.306 +fe653411a7976ae7c4a3cb7df309788da6b483f8a7bab4a6990db74362f5
78.307 +bc41d545a320389b2599fd726e426ed9fa2916ece67b058f6a269544e517
78.308 +128bda38d117f402409d0d8f8c88ed509aa2ba882e0c579b45af4be80770
78.309 +22d7269684eaf0f9afc3054316da6611e3fd260d67fb6fe52c9ade5dda24
78.310 +a0050a819ed21342aac9d25194778beb3145f56a66980f620998923521ea
78.311 +3f957b6ed0c5470734af9f416a16427dd03eff9a0e023452097d4ef936d5
78.312 +49a90823cef6de340a1ee02a52851b310cbcf41ae274947a62f9d1d8702a
78.313 +669023e3caf967204a340694b45fecbda4bf9552f6bdc62d43b3b2c3d571
78.314 +9983c182453e22ee34241ab908e667115f7988174684cd70084aefc55caa
78.315 +f5352a88e9dac45d1ea0e032af61fe9a9118a3931b2050fc6db66ab96a39
78.316 +74353b597f34dfd9f72150de23285eda5e555a607d198c291965a7233715
78.317 +3f4946a57af0b440ff8567b01a6f46c6d32fea5f8bf57d89dccbab7da882
78.318 +ee6c9260e89443b1d7db099477492bd0468850df3db668d741123e7ebe3d
78.319 +c21748ab4c5cbeb5de33b8963aecafe76bba0c4f6ed8e8263a116ed85e58
78.320 +fb71ec4ab0071301be7c7d3afd5fa6ad46c0232807bb7fe129e44bfd16e9
78.321 +fd0c8bb5e7cdd86a78b5fb0669093c22eda9151d85b6f58a9c8ead3727c0
78.322 +09850bd31a8b4a873d0a506240bb2aeccb8dcb6369532f21d9b967aa8443
78.323 +fd6d77cb2d65c4678a5fad188db85940f0a187aa1031dcf5b8e0d0cbfb6d
78.324 +b3b96fedec5b249b7a69de9b42dfa605bd622de7a220cce9b66e9f3394d6
78.325 +13487dc5e82c1e619079cd057b1e19ac05ebdfd7c8bf01c6c66fab49e0b6
78.326 +613df9e42beae2f7b9407a2bff8896d8035cea0fd5c11bc5889cb3d90876
78.327 +61766138d2625f42d0244adca65d1bc73989328c0eea0b97c7c766285ab3
78.328 +351ce2b183f774488a8806c33178090a3808f0ce5e339b87cf7add933301
78.329 +ca486742831ca751f0626864ce13172829a8419af5c78794a0eaa17b5bcd
78.330 +fcb684f7d4bb7af15deb432e44dc7dedf56eb8bea08b46f1e8123a49a349
78.331 +a7cbccf833a528f5e22d2d463040e09b91e543a2f33077b3e7b9ecc64f14
78.332 +306186cdae1fc317a6ced7e9b4d51a10bbbcf2fadff876b4d9082e3f4aef
78.333 +dfef230e4232572f4fa33a6e065f6895aa2ea96c5659cb579b023179f0fe
78.334 +de7ba64bbd9362a7b2b8c4eaec254915629e81d01c839096339b99bc9e25
78.335 +84536955feaa52fa20666f65bafd9b2e69c3e8c15d24fa407e7d881679b1
78.336 +789a0e2a695d13553c92c0214c9b7562cd6a9a3d77c8b0c2196cef76dc51
78.337 +d855c1dac37f96eae4cc7bf07e17dc7c08333d7af33c8b2965ea1f23446b
78.338 +3c96c52b30ea628ad572694d145b58a606f90b278290297aa372cff56b6f
78.339 +56f4aad6612eb7c7bd07db4f7d1a70d8044d16d0b5c1605ee02a852ffdb4
78.340 +450147b3f9b87d72dc431b34fcdc899462dcc1b6bb6ab1758b6a589e91e5
78.341 +8f5196251d00133b43749b7a11fb67a22664c5e38e336dbdeb5509c2d9d6
78.342 +2642c07275949df0e2db59314ae0fb34641fc171d3fe1289f919136d853c
78.343 +d9048ee9db50c699c49e27a8df199590bbc65b23b55bb387eed0c73f2db5
78.344 +1cb091f8c22af83103f214199e371f7de1df23f757817200be30610004df
78.345 +81fe8ed6eba79e856fca21a126ca326ad2f313c16e15754663ad6a065e08
78.346 +4050ff005fc899d6e233691b918a093b5f1ffda8839ab23ae66b1bb7b953
78.347 +0a7f896ec55de6fb9faf1b49656ff2e57488cd7f1c44114c75f9d571461f
78.348 +767a6040ffa14e9fb43096f164d60ca530d7cca76d526d1999ac1b52a793
78.349 +28651112a65db1f2564ecf90ea6bf2c9ecf515640719c3fb5e36cfc58591
78.350 +e227793f39b9d3a9025cb10f324a95c29c488724aa74812366ff0b118fc7
78.351 +19f9fd0f202a040be47ec99b46b4dfc3d2a17902a5779c8d52b27231a1bb
78.352 +5cd794c838daddc3e6824ca8297ba669a818c239b389400faf17aa04b802
78.353 +f763029edb9784dfdc42f223e6496a938e613463bf9bbbd59d63300a9ad7
78.354 +4e71865cac4b4e81a5864388c3886e70799c8989188341f7d17cb514cd99
78.355 +3b211883f171ec6402cc361885f4f4b110757bb3e52941a94bfaebb2faa0
78.356 +3e32eb72e25e31abdde82c2a9015478afa0f434ae3f8b97a4bef598d6eda
78.357 +44ffe1915c26ee0e8339d2d45a6a080550f538ded5542c8b96ca2f596979
78.358 +8bb6223e460e857516ab5a3323136ee8fc4b0556a7c39d0cf7acb45e48be
78.359 +4ae9db325e4750b73289e36a61b301795bdb2ca2a8b933be1c09fd0cd2cb
78.360 +8677df171d36ef1519a2269b21e4103b2ee151c513df3e10b2a216d6fb22
78.361 +18bf2005fa7e0f0563ad96661a7f55e1b5b991f8ca285651b2683c6a7c9d
78.362 +2d1941374989b06f2e9b42a6af60193dc758dd8e9fcfc7c1aa06eab47e81
78.363 +bd79660666defac0c6b9e484df9c17a61ce7a61ef73150e8cd406af6da17
78.364 +4d9c2392cc420eddda40f975ffbeacad8ce1b4e14bee29ba8552ff03376f
78.365 +c034784b38dc1d0ab7bc53943d2545b03d39797af8d58d6dffce56a353d9
78.366 +bebc833f04db321ca8642bbb7fcc63ed2349ffa08a33a5d0d78f4fd2c5ea
78.367 +4258e4671e362036f1f67fcef9d878ae2c203fd9c05200c59cc98633e65a
78.368 +99d912ec51d6f74500d5358b70e799a6817f59adfc43365d7bba1fd6766c
78.369 +5c8e76248daf3f01e7a8950fe875d657397797a45e7f99a92887300b6806
78.370 +b86db61e03c4c09d6cf507800aeead874a94e6f665746752937214302045
78.371 +0b19cfa8db69230517183a03a16e5503882ea1e419c333d3e3b73cef6762
78.372 +873ac06bec34c3f736494483442619f5bbadd86f128a5a40b854051893ea
78.373 +8d31dd6656777ad4ac2572d17c6fb21385b053495d1270e65d78334a4115
78.374 +2787ea89b86f97e72718905a11e9c5664837701a3c1c65ccaf26aebe8dab
78.375 +c1207d5da2079c37883d9235708f370203b3b2a8ec3a5bb35fab93dae115
78.376 +aef626dc44b67ca56fac18caf1c22e6fbab93564829a75776630b9c42513
78.377 +721ca0fbb0b402f4d1db8f701d2b29fa60162feaa8a167eb3113c6f57036
78.378 +e8361357913eb24dd38dc6d3bf4c3176a07ffc75cecf8e5940a310f79a8e
78.379 +f590844383d631796ade04a91144d073a9413cff34fb454f1fd75cfbe5e6
78.380 +525c3bd36ddab80138f6c19aad7417d47df1f1e0fc958fb190a8205b5321
78.381 +7c43a4dcb0599be404473d6faebe7240dc402a0e0caa21b56a601b154524
78.382 +f44988e5074c71ae8e1948bb2a2ce72fc24cf3b1813cf7408a6b097aff22
78.383 +f9d285134d09b7053464259531eb7b270cd5f39f81bbf41a36420f61e5f6
78.384 +b429036bbf20e27af1a437becd74c5bbc25ee2519402454fc94d430636e1
78.385 +736fe65a643d9b9d21c9a54eac5a8fed51ff60a47b85a0e9423e330e00cf
78.386 +220c23e056d20aec2fca3e6bc7a61a8366eb940c9bc99fb90e8704e27655
78.387 +20335a983eccc7e20b13745c4b4f30a842f1ba64745718c152697c688c73
78.388 +6cffcf5cc8eb5756201560413117a45ad3d264291cd51404f98448d31474
78.389 +d47d17d201def12867ba679f0e2605de8f3e8135ed0234890cffa68848f0
78.390 +6de427741b34c2ea654251ae8450a152538eb806ace3ecfe86d8c4a137ec
78.391 +c98c6d6cbdc191a5f8f5b5972c70b4896960037b6d4c7c63586a52d5eb59
78.392 +47af8c192eb980d0801fa670bb1d08740819f9da1dd9e153010bf9580a1d
78.393 +0925d8327ea1b88db8d934f40266ddf93e5ea137f267847d826cd7999b33
78.394 +c795d0ac05abe2ec1770dd98eea67912f1939118defc9b379e237d6477bc
78.395 +91ad08e0046b0836fafa1272b0213dce990c90815f5b30d0eb103ac9539c
78.396 +2f7bd2280264cd95b4be84cbc5139a7628ed211905dcb92cbc3180ac9e6b
78.397 +b9ecc3cb08608b2395827d5729781dea49d328ba0c1b4cf2cec9f6bbc822
78.398 +1f2bbbb9d88f9e7682b9ecc06b9705faa8a90a51678183db1e24cc2c4307
78.399 +e16b3c20f08f179ec69df7a8c4261427f5886f9179c493bf2d0ef36640d7
78.400 +79925585724aba69df6d1b4f0bd2a356eedfd74a88bea667b102420c2300
78.401 +ec420e99b9ce8be1472b617e1255a7f43a0b52f11657f1a4dbb624a24886
78.402 +9604fe2062b98f5787d010723e520a4f42a0c3943e151ee627f3d5db90e0
78.403 +7747e1a88a53c4784c8d2b042b9c23c9e436d7d88343171161a364cd8961
78.404 +37a19582a00d774ef01c7c3fc9e9c7be5074c858d2bacd707a6a4f322027
78.405 +137d6ca0421ed9f9c7e7229e867678e5272cfc7156a419e893404ad7dabf
78.406 +a5d8b6fd0787cb4fe1a901c34dd931f1b64f0c470ff807005fb66350d0ea
78.407 +eb84ebef2c2399cd14a4454ea5004bddd99988b39c4134b92121ec77faee
78.408 +55cc716eecc58b594b39c41dcab308efa4458ed71943ec5805dcd0194ddc
78.409 +1ba04a5d3d42d07ac62a907ea25cd2a7e77aba470324d41dc1a3fe088388
78.410 +787b3312f472cb4f23a414fa5f7c7a0cc5d121d7642b5b3f0cf7ca2173af
78.411 +3f878f374938251feb3ce5ddd2d7703fc79a130978ac516daf70ae903799
78.412 +28bea3a4296f48725d578d2e8fb0f932e398404fa8a242024bc011c0ae81
78.413 +7b92bb104712253a5d89c543a744332069e33ca08bd133211d233ef799f2
78.414 +fed6a20a9073021e505def8b79e1279dacc062cfd4dddc2e8e0a7fda5dd6
78.415 +bb5a745f99cccb7ec1df532308da3da0f236c74639c280ea649b2f7ec27d
78.416 +24221470b642567f3b2e1cd0b3ffa65c5ac986b557aa9b444bf470380435
78.417 +abae9b51c6da7ff753810ca7938d8a1c47d2b41fafd236cb5998f3ef365e
78.418 +1f700bb257679ba3a82e235a3e97a667a6ad94412839c96dcd49dd86ccbb
78.419 +6df8ad01756b311e9fd57ccd2eb2f19f035e214804e2b77769319a5389c2
78.420 +35f3ca2a73c616c9ef0984abcba167d7d652b330c68f4f6378aba69628b4
78.421 +2d59eaa2a7e4c782f6eb96f6758d17d35650b15cb5de9bf973b3b6f67c1d
78.422 +f3285be8322fc2b44359640a3ba5d6d7b96142583a00a9a0ef84fbf14046
78.423 +09ad55b2aefe8c5c8f58ed21623bf765f81dbb6cca6d2a51fb7730a14839
78.424 +392cad6b47f5e03448350ab36a37d9ff2b9dab69be5196511072b10cc91f
78.425 +2e6b5160b2b1bd112e6c02d14063a9bb46977b0d4bc79b921fd942f916c9
78.426 +c5708e0d133c8309de2f6ee0b1afc996c889c36de20fbbbfd32878f477cd
78.427 +7735c7c3fa59e9c46e654ea20b4381d9f6c6431082e6918d532bcd539284
78.428 +af0333a783c9e7fd4fa1e4da5ce8fea2ea4037644a24532d65fa5c1ee982
78.429 +89e4b9abaf71a35d308a9b8c337f70babc5fc8dbb0327143707ca5b675c5
78.430 +2d3cf09f7a4f667fcda03d8c82d157e661517787ce6bfb35ea772de13c66
78.431 +2bd24b74ff9ab0fbcf6635d8e06b54b5b3125d17ae13d175cb7922338ec8
78.432 +9d1159fea2110995ce48f7d2b094f06d11d59b3a64a44a83d48c78855e47
78.433 +21243e82d9858401b094a236fa0a90d61863931c30d13b9bf33a35ac0d11
78.434 +a999f2b4dfba6fc187f8c235a5217d777a5a97112e7db6a8a4b06b07d9c9
78.435 +f41820e233c8b58b9e47ac56ad1ddcc0b35dd03976bc776c6ac3692ec0ca
78.436 +f8c75ea7825bc84156468ca7b269d890ec9d4a365b0b31d2f6530185d5e0
78.437 +2acc3ce14eea55ebb5667067825a8682e135d23c78863d32065ddcf1a755
78.438 +e0de6dea7220d1a28416b96db40b1e9f159aeb070c9a9515f301f162b0cf
78.439 +e32c6c89287de6e2b40458e3393826189a10af8517ff5a10c41c9d05d999
78.440 +aa9305a2ee8e7fe46076bc9c5722ee0a140a144ae383e84a8abe70af5d29
78.441 +96a0a896cd499caa0ed7867e7c3aac563763216e7769d12218b584d853ec
78.442 +01db93ca22d0c8d6b286b20b6b26d6ef19f2cebe7030ecaa68d069fac7a0
78.443 +09d61770b5e8f83024a99142f59d88297cb8d093992c3c6c11b043b151e8
78.444 +20df640407d8bc829bfc196bf2901e63c6f16102d03ffb7c54a7a560f5f9
78.445 +5cf8379f4a2eccdcb604bd553e6157b4381940d1b3c768dbfbf2618812f5
78.446 +7fbe744b3d8ad680dd9223d8bf2412ecbb614d05b485e3b4669d22b417f5
78.447 +02cce2d705c208b15fa83b5be77ccfc1c840f385a58ae49fbe6ab4e53912
78.448 +473630e0cfecefab95ebc632a2b10a2103bfe801ca0302542080cfb4cf4d
78.449 +4c241b1a6c8d28114516e3f1bf39dc02db73e6d9a797279acfd79b02a71b
78.450 +ae34860dd0e11b18954129f8dd57c039bb7063a4c92f0f6a1e25f4ae59d6
78.451 +6c1cc6b73a79d6a56f7f2a8a64d571caa8a760f4f485d770d000ddf393ba
78.452 +784bb27b781c47678dd78ae9b5d5e8b57d163c42c7a55e4aae22061686bf
78.453 +aebcede728ff2f65e75955585208c176d100912836b5200a79062d4f09b1
78.454 +ba9465b0e937e289160ec543a4cedbbe0cdb5ecfbb4838138ee9e1ac757d
78.455 +3c5f04fb6b510b389e2f521759e403bfc8ec6bd79e2d40bdd81901c10dd7
78.456 +4620acaac9108940daf03af23f09d3c8b785db562b05e597056406557857
78.457 +e96fc8bea53c2c2ccd0ea6572abb0acacfe29e737173d665ab6dc2995f60
78.458 +807aaa4073a183aed23c26c67eb137c937999fafc63b66a021125e4ee5c1
78.459 +a745ad1fff2bd828dcef392052965ce0e9af7a2c88d730fef69da91083fd
78.460 +83d9fe9f73d42a8dbdcaba85b0fa93b210dbf49cdcbf5d4b69e07375fab1
78.461 +a39038cc51f66f0b10eebe0cc61f697f7025d9755830b2d65f1ad0db91ef
78.462 +ebbfb578053de329935bb28d6ed6c12f748a2f70458990f04d56c35557e3
78.463 +8bc5d2e5de7f52bcf00c3bcce091aaa8852d53ac686f8f407baf3f7c8968
78.464 +69f3b62f44a5e2291aff9d30d7b5c663658a41add74562dbb0f1062f564a
78.465 +9b907846291700151de04c1a55cb945eaa2e7a709218ec56d1becce1c0b7
78.466 +dc41d5f016ae8080c3b07311590a0def35337fc3c844c0ccd04926be9fec
78.467 +509b1255ef12f368d20601b1ac8c68b0a935f987a21de0f8191604e921ea
78.468 +0c04b00dc188fd73499852dbcccd4119ef799472b353be7f7dcc904ddfdb
78.469 +920839f3d4a13bb1796f2dc886f31217845f8d7a543aabbc720311fd0e6d
78.470 +a31ad3daa06d5e7e6270a34304f35ef170a7abe733428e96b0522fddbb5d
78.471 +eb35aacec147067fe066c9ef145246fa3d444d176c274b91fddb8a7bd7ff
78.472 +7cc7693c25895bf931eb321dc9d79f662a17691f9bd1662fecbcecf6d1f9
78.473 +cd8ddcda56d19811f05fa48bcb492feb355b0ec7c04d6046549c56f7799c
78.474 +2cd0d9dade8809de7d510702e525ad9cc82c41b4fb36218e3d72e905c507
78.475 +159076a9c0e4a008ccca17bd594c69f5eee656426f865fc1988d677b72ce
78.476 +b710b29a0aa8f8337552ae30e93bf7c6e5d013555872dba4737dc5f08c0f
78.477 +efd428c66fc8da675373f13f89102688977e18e14dedd7f3b676256b0263
78.478 +b66b013617d9a026794b0d6040c23c5506a98530249633a6beec46117c96
78.479 +ec036eaf6439e25b8e57754af5ebaaf9b57880ad4fc93f002fb03e9fda21
78.480 +df4acb78296b0c49a5a852c134c3b10755177a0dbd6c54ea7a2b9bdac62b
78.481 +5d7f3da649df856478e4baf97899e0f891a96536c283f5c81200c51c6ab6
78.482 +77285450c7f7e96836b6da5660f6cb76782ddfc64b6fc348ebc3ba4a46f7
78.483 +19176296d8c5a31132b3fa7d935a5d777c1dc84d669d564cb4fd689a38ce
78.484 +680d0b3b130caea0be43864826d0d154019fd0d865f1c389cd367cb5248e
78.485 +24640eb6f66603e50581f6fb5aca6cfec1d6dbf4196da10a5e1ebb14e4ca
78.486 +0251c4c8412cc1673d6e7a9666b04b090567efa0b830d2362fd384cb0303
78.487 +8a40290597bdaffe429bb89fb66b9dfcfa92f39d92a8baba7266d144ac04
78.488 +f069093ebb3fcea961ba4497d3628ad207e0c8c4fac0e5f3f2a663a8d05d
78.489 +b6dc33b890ae13d84dce64b495d24cc749b121659373ca31cee09bff2e9e
78.490 +e5b62e89d5faa4482a75f341dd172500a54b98fc108a69a3ea94db696513
78.491 +d4c7691e0095ed3900cd4489ab008b5460b34ae8dedf3721c60de7086605
78.492 +6c391137cf23255c565bf11403bdeecf8bf39ad5e4317a4bb37003b2e7c1
78.493 +400c3b8ed7f63719bddf07908dc2decdb0f68e8ef722851c4420303f6de1
78.494 +b5efc9b2598732fd1f2cbe45a504bd7fbfdafeade3add7274a1e875aba3c
78.495 +4e0abfc6444944b79f95b5009560818f7a0599e5bab4405378fadfe084f1
78.496 +653e5a0166714047e8bd4e4cb116596d8089bae9147ec1d62cd94491af75
78.497 +a1743d58bafa11b63b447c954a8d7fe11d39d969feac8fa93c614f97807d
78.498 +ac62cb7a84a974a0fa555a2e3f0ef662706efcb828ef72e2ea83b29e212d
78.499 +f89ffecabcb08dbb7119203c4c5db823bf4e8b698b763fbd4d21e57940d9
78.500 +1754959d21f3f649d856ac6615eac692ebcbac555f772eb6ba3cece5ebfb
78.501 +cfcc2f3d8dcad7edc697df93aef762cd47cc3ba9e2cdd10940be676efe7a
78.502 +a3749170edb47b7562805e3f8bd978b18057c9110ff8d19b466ea238af32
78.503 +993e2d3021745b238021f824d887d2e01a7ff12fc6f084b35292f4864579
78.504 +406c0f61d0ac7cdf7e4770b424e2ccc22353e6c82bf8ff172973df267ded
78.505 +bdaabc2a742beea02e35b9b253f98de9ca131f802deee2905ca1a6dc4608
78.506 +19a59b4a4265c723007d0215fc8ac2a91ec5f86cd6aac1e370a297103c3a
78.507 +3cff58c7ae201cbaaa8a12c93e95e73974f9abcd678451b1db02ebb2e10c
78.508 +c5abfa573a2ea4219fd1851765649318bb556b728d432ec05a86e9894aad
78.509 +9cdca63d08642655801bb37f28b6e11b958e8e800c8d521ca4aa045fe9ab
78.510 +ac02dc015d18b1901d519181ef60227170a07f3328a6d5fe4c5aedb35fc1
78.511 +3dbe86564a9b1dd4c7ec648880360cdd1742ed4ac409450f1d9681cb5e46
78.512 +5edd1de2a2c7f8ed63436f98e849504ae71bb872683ae107ad5df3ca0b47
78.513 +a5b79513e02d7c540257d465ae4521cb3449d79c931e2ce8c5b0a0a4ac88
78.514 +cef7b9e5f92bf721ad51682d6b6f6c14747f78eaac1891fe29aed4eaf177
78.515 +e3d2fc655ae889c0c30a3575a76c52e95db2f6a4d8ffee9518391954b92d
78.516 +39dae4e97c4022031f8ab390b66ada6dc9ab2de4d1dddf26ac4032981a69
78.517 +08f73d34b4849ae28832cddc0dcd116a47d9262b0f93c24fbfdf8a78e6ae
78.518 +ae3357f3fb89530854257a9db773a1acf5271fc4ca04a06b46dbe661ca11
78.519 +9f45e0080cd129e1a7c23a33f1c48af960761b117d9d91fa5a0ed3e47865
78.520 +b774a322f7dddfda2960b91fa7ba20c8f9eb213251299ae328b28ef54b0f
78.521 +55fd54f8047c555e4045cbd70964e1c953e471408e4f25fe8ca7009bfe44
78.522 +0244b1e30dff518ea7ce5078027baba4e07ecf0ebecb497b4bd88f1ff72e
78.523 +b261f6dffec0ed895e237b5608d31ef479e8c9ae9003039a5fe67252ee39
78.524 +774e1501100c0fcf154f5c5c81c70539e03118ab91f4ce247f6132d46346
78.525 +bbbb126c09d7459c1977e6e367a0c83d14edf7dea081e5f795a7c831fd1b
78.526 +325b33674ec9c2b68029a0e600746329ea2e1b9bdd5cb2b140468e53c108
78.527 +8e8f2567425443f8146ec37101fa4dfccb0e032fff6cdfd76382463551b1
78.528 +ae8ca6cbff0e34a3f75ad400a9573217f8cbb00a6d59ff46e48421e97091
78.529 +cb17f53f20ebeb89609ea55ed6ba4101f2f3ceccbc7ade21202439ef91d8
78.530 +a9a783c22de7e6601b50c4342e094d0eff223494489fa92150425da1b432
78.531 +908423fb3f41e0b115ec1ba592a4f920d15610b9fb33f9912aba67912d05
78.532 +1ee00a13282c1909a3a56c4ed06f2f4d1739dc296b7492aad0446f87a416
78.533 +c6db4d42b504dec3a6756f3d0845ab2d2e151aa5fde12b31a9c3b5ae1cc9
78.534 +d97192bc048f00dead66940004281c4d5a92c20b1f77795cb4f98b8eaa7c
78.535 +be16f9b9d4a34a1a53e0a0deadb4fb4b20d9e8064d3412ea8d2ebd259b8f
78.536 +2f04bf4bf11a5ab7883c99943d762549c3d5866bb6ed85a0e862eafbcfc7
78.537 +03bf4b77cecc0d65bce4df33e0d65456397f231f8cbf66672457cf539817
78.538 +6aa5292fae24695009e55904a04588659a3a23fa11989b925705ab45f954
78.539 +6f862b0e176fddf75b70d9ef7389f750becbffae25d58a1252cc04a79e13
78.540 +fbb6a666fd87cec5562c3e14fd78ad05be28ff3871d6fceff5aa8965bb65
78.541 +67ec76d105a6348e915b27767f5010011e80e0e2f9c34742a4eeba369e66
78.542 +8faf086a45ac9bcdd76c758db01a78602412a4244c759ece0b963d9ea58b
78.543 +0efbf4376bf115288803a54cfcf78584c8af80da2a3324096463e3898285
78.544 +57de6c6354444b12a74d5e66053f6907c48522cae9e93bccdb4632131add
78.545 +52eb374213888125de71994c31dba481b70b2e4c1f10b865d58ef09fc9dd
78.546 +2ca7f69bd2855895256caa5dd6bf7d4d8b341d677c56ca08fd7ba37485b1
78.547 +444af8be0dcdb233a512088936ab4d7fc8c03139df396b7408747b142782
78.548 +d9406db0dcd31368d2f23ddef61b0da3c0704e9049ccf7f904548c3ca963
78.549 +76eadf1ccf77f94c157f5b84f74b0c43466134876a90c5fdc2c53af70c3f
78.550 +f5c2d13cb665fed9016454bac1a629361c8ea62f4b2399233e8587db6e75
78.551 +a9cde3530f20a68ec155d275a4aa6f63aa5cd115244643b54911c954feca
78.552 +d57be2a6c40f1bac38e393969617b066f7d94e8b18dd80fccd0168d4a385
78.553 +f2f1489d1dd41b68d47e5ec66ec568333d1f584e3dca90f1367a990630d0
78.554 +14355be7dc45378aa111c319838edd441f15e125f928e044640f25ffdcc5
78.555 +c116c3f6ce0d4d3195187b22200808366eca9b508ec45e664e562186efec
78.556 +a97b22835d384758849605a01973cd9ffc1657b124950c9d9fa3e18b1a20
78.557 +7156c4f96f08b87824373c2865845d17a0dda71b1d69f5331c5676d0648b
78.558 +ca80a7958a2aa034d7e1e9fafead9248e6e64f9ec327c60ae4f724e1fb95
78.559 +8a71e82ac3842768b27b506b5982311557432dc3f270ae6eab23a42fef70
78.560 +dd0d407a02cbadeb7b8b74a2523cf46a5f61e52b053c2007f75ae053a96d
78.561 +e00646662d027d93f950e516cddff40501c76cd0d7cf76c66b7bcd1998d2
78.562 +7a19f52635c8e27511324aabbb641dd524d11d48a946937b7fa0d89a5dbc
78.563 +4b582d921811b3fd84c2a432dacb67d684a77ac08845e078e2417c7d9e08
78.564 +bd555c5265024aeb55fef4579b46f8c5e79770432c5349d5a65a47ce9338
78.565 +e1b599328bb1dff2a838f732852f3debf4bb9b828f9274d03d7cf813b123
78.566 +687c5e78a26310d87870bfcb0a76bf32aa20e46f6b2826912e562f503aed
78.567 +11e427b7765cd2a68da2ec0609259ff14f57c07963d075e96f8bd2eab9a0
78.568 +dc32714dd8905f2627c6d6f33563436bda2d7fa9a976f88947b84c72f454
78.569 +bf0b66ca84470375d2ff252b4a2df52ab613d0c8ef0465ff1d809ca82025
78.570 +c2122a8f44c56ebfa25690bf6a05675ebb8634ddfd24c3734fe8cb32d6d6
78.571 +c69c72a4951cb959175770b4286d383e7a3f158450945c8a2ccf7e54fb19
78.572 +aa8d2d98a07f0c55f834f2728d89f82a598269750115a02287c4d415cdaa
78.573 +14e1d9e7032684002f90603c0108dd26b40fb569bb21cc63d0da7e9e1873
78.574 +9df0a9c85bc340d2b0940860d95571dc244628c59bab449f057e409e58ca
78.575 +cc3369f4baa8e53c6765a55620e78341dae06e5cdf2fa5e5ba58634b29ee
78.576 +ddfee7f78672e55f18a7debbc30862f278f83f4cc123ab591371f548fbf9
78.577 +bd24b3453b9b57051c2e67edff2104f3a05a9f0cb7efd81c1b1b0a2bbe95
78.578 +21854902526e5d4fa1b3be270811b972e8726623410cec7911c07f871428
78.579 +1caaead97c503714eaadb14ae5923f020093722df1b9d9c055d7d5f95af2
78.580 +a9fbc5ab6f6c2bd655f685534d7dc5fbb5ebded6ccdcf369bd83c644dc62
78.581 +84c2810495888e9d8f464a42228cdc231d5b561c6b210bc493fc1e7bfd66
78.582 +5a6c4055a6a629f571f4f05c15cb2104b4f9d0bd1b1f0ab8252da384eeae
78.583 +f5fd5c663ad7a2c29f65a48a30ed8de196f9eb8ea314c6e86989298146a5
78.584 +589f76f12664c8d008228b33144679d16ff564453b5e4e9f813191b6c99e
78.585 +2680e20a410949ac30691b1428a255b6185b7e3802e8511192e73c376f3d
78.586 +eb807ad2727fbb4b27538b3213da0746231b1c1b595a958466155835c537
78.587 +e0df4a0ef272d4c3f7f2ef011daed38bc58bb0fd7458e48060db98971bd4
78.588 +b24bc7bd0de92573a1c7a80a5fa2b34fbe50271dabeb83aaa4235cb7f63d
78.589 +6a6b399360df8b1235e4e9ab59698930044a98d5e083b5f5a5772309b390
78.590 +9e1ff2a252734b32fee3940f0e1ba61f54dd1d3f6ff0d57c9ae75a302d14
78.591 +b9dd9034279aaca80b6bd05c74bf3d968305a5046910871223a3ef8c77d8
78.592 +25d7e6d3d2809e76064c473d1cd7c05666040b6eba647e34588f49fd70a0
78.593 +3c937933a2272c938d2fd3aa8149f215bb48f3bb45090bcb9a6ace393a44
78.594 +f1a9bda2ad09a5f566b2e8887880afa45a603a63ffe7c188e3eae926a903
78.595 +4f1803368e773f42c7391dff1b9ce8599161515c549aca46aebae7db23ec
78.596 +8f09db0e0f590aab75e8eb890df354b37cd886bdc230369783a4f22ab51e
78.597 +0f623738681b0d3f0099c925b93bbb56411205d63f6c05647b3e460ab354
78.598 +1bf98c59f7f6c2ea8f29d8fe08df254d8a16aab686baf6856c4fed3ec96b
78.599 +0328738183dbc1eebb2a3d301b0390ed8bd128bd8e7801c89941485c3c86
78.600 +22b5f223cb07dca74f0e8643240044e8c376abbd8c82ff98c6dba9b6d244
78.601 +5b6cf4189d63c6acd6e45f07485a0fa55eff370da7e71c26469740a68627
78.602 +a3c297d2bf215121fb67815b7b9403aecca10d21e59fabcbe38f5ca66e7b
78.603 +551b22e28f2d1fd7303d15a42c45bf54b40ef7fc93060ae5164e54f91c55
78.604 +20bd303a98d0667a02a900813b260c0343021ac01872fd62cb6abebc7ad3
78.605 +a4456805159839ca4a3e35db586221169ded66f852e8974e3815d4d7659f
78.606 +6a9bb93585aaf264f06cb6da6a26e51683945224158ea69719b8e4e36eb1
78.607 +01333aac974db8f84b051724cf245fe7a4c86582b5dbb9a5d9318180e33b
78.608 +8d92c22c44b0d18f8ca34dfa4ee9693c1a26fedece01635fc5eac1fefa81
78.609 +32458254ad46dfdfd2be12a1e7f32f3728f286f1d5d4394424a073696b65
78.610 +e3c459aee9310752231fa703faf35e11796c4eeef698f4109ca8c46ee322
78.611 +5dc2e3e04fa787188e583321f8410b68b9624ff60679d3f25c13e5ea7506
78.612 +a3ce8d0bebb99d9a959ad92d8cf909988d9250b310629903d6bfcad4581a
78.613 +504b91b2c91889987f36d6fd0be1d0ee5aac00aa0cb48d78a1f7a64a777f
78.614 +089573ba79452efcc31c8258fb317369feb0d7ccd48cf13da6d1ccb59a4a
78.615 +48ea0b398e590c1169113fed81639e13e96aa268d99cfdb7aee977fbe85f
78.616 +f784853a06642b5521ae0a7f610c9739af31ba7a5157ebbbad999e23794a
78.617 +d2cf25af987dc85dfa29639957cf28e7f2b7671188045130a6e2785f8d8e
78.618 +30e91f0f68c1cc9f2de902952730003e816e4f5703db7a97b4c566f80547
78.619 +42fa77be563ef681a4513b9a68b2b0956551c74545cc9883428dfa72fd5c
78.620 +4eee93256b26bc86ea34f7427cb0c0cc22c0cc343f739c6c0c46d0923675
78.621 +5e04d70587426ef875f8c89ff8492ea23e4e4d763b84a6437a440e69eb70
78.622 +65ab6d8cf5f8444a844e6ef3d158b451d121daea2d0e2b423eea24254226
78.623 +7eff1b4224c4e80af2a7becac1649e4bbef09f39415e9b1e3750d7ac47a1
78.624 +068a4f5ce30840b00574eb4e683e3ec25f6e690feeb0d354568efbc354ba
78.625 +813ca1400734a67693af127b0f636d58b83e91548f98e3d87da7fd7cdebf
78.626 +f3ecb4b9272d1c83d4980170378d32f1d98b87c440881af9ec052510982a
78.627 +0c02ba6743bdc7691a44bae5e044c25304c1a2525cf2c0694494a2e9aa34
78.628 +f36af43ab288807ffa4bd418ad51d98c75f2b2f01abfd834d3305682b6b8
78.629 +62ef69d05962aac485bb4f560583a5dbb74e967eaf6d299160753ec32249
78.630 +bb1d9851d5441cb0c624208e69dc876cd8841a66976b5d7f9c99be68363b
78.631 +8112d33d971f2c4f2a1feca88ba1a794ddb725c5e2e2c248082231059aef
78.632 +729bb5fee5006ab8809f63e162fc0743c047c7984a9e6333b433fa143d73
78.633 +72d4a74fe37314508e04f54dc7a1445e2d6178ec9c041d0cd4fda5cae830
78.634 +4b16feb21f3222261c293a8b058dc708405c1a97ff34eee4ca69ff4e1ee2
78.635 +a03380d52297574e3aa50c8afb826fc94a14e8caa9ba89d6e92913be9e07
78.636 +bf7ae011e6bd142d8952d9c2304735e875d1ddcf82fa9fc0c6449df2acf0
78.637 +d5f6cff6d21ef6b2d29022ed79c4226c97f163284f2311cf34d5b0524a1a
78.638 +a446645b9d05554f8b49075075f0734b3d1ea31410759c174fcc7305d2c1
78.639 +d7128781043cba326251a3375784a506cf32d6a11a4876f85ffa2606fbdf
78.640 +27dd16d64b2108d808e33c409dd33f6e0c6079e47e7196016f261e824fba
78.641 +b0e4f91a189747053e648ad2d942ece8f582f052668b63a23a2fae4c75a5
78.642 +180db7811aac654270ec6e341126e3561429f1d41fe7ba3f1de9f8bbb8d9
78.643 +fc5cebdef869376a2e42dcaa578c0807835e58d75c39f91a83d5c1eb86a1
78.644 +b0f7aab991f65eef030f212d38d10b1913bff71717c06c78d9a1be136f21
78.645 +4be157ba11ba309326c55c23ae8512646751fb82ae200c06bd2e644bed38
78.646 +c7cee826cb587ee8ff378b7fdc00ec316bd4a9c24e2c250cb3d64f8ecbb8
78.647 +7f4d81626d7f1e4491908bf17c48c84bb1736693eb4d0fe634484cdd590f
78.648 +a40ae94d44f348ba683a43004b487f047745fcdfdee2e913328a11a99530
78.649 +9bd117e0e5be4fb25d176d59dc2b1842418141190ed9ae1f33e5354cacfd
78.650 +a5e4bc186119e1461bcd98517e675276ddf0296d3b3cef617dfa36b4759c
78.651 +944fd721e1bf63d45cea90b5817a40d153a2f779e03487cad3c1375425ac
78.652 +8cbabf7f754d16cabe45c65f1be4441908e0969d5a5111c931e724537dea
78.653 +7cd3fbfec9b2f7d3efa747bf586e9218c3106c49276b89fa28f770fa0644
78.654 +fe1f3fe3adf07f59c755a5b39a2ac1d6f23c256a293bf3b31b6b9cf4c622
78.655 +b188d6e7401c038657c78bfde9ba09f508f1bbe3ed79793772cfc928c4da
78.656 +519f7dbf3ff7074284437d2de8d7b7c78829642d924abacf353119e9088d
78.657 +14739935a23667c432806085c3af71ffb7c5fe6b4412b9b1044c1e62ee0a
78.658 +a5ce7e0322bc65a8c7d874270d84136526e52d0c7f9f93199c6bb7301216
78.659 +a19bebcef3c5633f21d012b448d367157ad928e21f8e471e46982bc46a7f
78.660 +df1bf816a86dc62657c4ebf286134b327ce363ab6a66634eaa2a42e99034
78.661 +069fe1302febf06959eab8e7304da4d94a83ac1650a02c38c1c4b7e65c43
78.662 +e3a6fb0213e57ac49e58721a4f36996069caedefeb48f1a59303459d5873
78.663 +f3bedcdb9d00c1cf31130c27b60928f210e1aa5e1c8e04b86d2049f31265
78.664 +9198fa646c53afa9058eb8ceb41bda65f415c79ac92af5790b176de1d300
78.665 +f1c06b782d584f458dbd07d32c427d894f84215a8e7819e295ee98d976d5
78.666 +644f11920ff2f49cb1075c3bb42b9fe4b561362902f11a75669b7e7c4475
78.667 +b65f1ae48834cd67816eb63b58cda2f50bc22eeb0cc965569b476bedded1
78.668 +2701668f609393659b266bb0e37bb27afc90bca271366e34754383363592
78.669 +0f9a3b508aabfe8deef585b07a992460c592a150b325b1e50e4214a2f483
78.670 +e9dfc826c54b488493a96eaa37276f5a9666f0a5388fe388263d2c0cf614
78.671 +c6cd01571da4389f01fcdbd0ade1c435d64c5921b5bf7dbebd5268100a03
78.672 +1e1abb8cbd83873089a9e08cf80276c7e30d2bb40280278c29fa818eb079
78.673 +87623b1cfe13e0b01e27be0a8320b69b5afee820f4705202158b7f3059b3
78.674 +655bc28a754d088fde23d43d6a9389da8bc1cf3e8ea1a6f4328c196e655e
78.675 +42184444d8c0614c7167c91a492c24c8357794c61f5e47cdaf4b38004a5c
78.676 +8fceaa8151e929328bce1b8f67b22034f3f75e4d105283337c3d460e7d99
78.677 +89920c43f5e1449c74ad6ab5ea029cc6e497ea60068451c4ef2132fb87ae
78.678 +049077a156c868b768df4a4c475a532e2a22d999931c64f8bcc18f51d25f
78.679 +0f94fbd3e9e6c094f78da062f80c4aa2b86fa572cc469e629deb4ba0c553
78.680 +55e8422b562ed2f694d0e8e5540144e30841d7593b255edd4a61dd345d5a
78.681 +00e411d2c50d64782a3ebedf945fc31c00d2fe4ca800f5aeeaf12ab399db
78.682 +956362e979bd7ef0787188e43835e5389ac444d13204af6bf1875622f175
78.683 +09f32015c28729cfa3b3cca90308eefaf260e3fd9df10f3e76786b8bc0eb
78.684 +a30e8cd33689aabc55e3ce387cdb89a30573495852a48009cb58a0fd34bd
78.685 +da911159ccacc94698ffb94c5f45f15ecc9e82365174cefbe746f95eee44
78.686 +7a33b4d823487e203478eeb2d8c4bc7b743427778249c56e48fe17d0a501
78.687 +7b693509ddfe1f42bdef97aedcc26ceffa9357dd985cdf2c70bbfc987354
78.688 +6f0aa7df227ec42f9ca2482f58809e3f9650444568c54d3520bd0a7301ef
78.689 +48bfebef1fc4332b5ca851fd786c1ece136fe9e575b69393b5aec2611903
78.690 +fae6e7a5046e2ff350becb8700f209b1131044afd32fed1bc1297b6a2f29
78.691 +6ec3b87f170e92aabacc8867360e4dbce9ea29f0c1df981f6cecc8986767
78.692 +0ccfb4c9faeaad7ca9029b8ff0129fec4a040f80ead041b3bc8af7526675
78.693 +ed9e13204e64d76440a097d77c535d34165bfe9ffcade530abcc75ae224e
78.694 +890d5c110004e218bd827a02ac7340e18bf3684c43e664e0a37d5fd4fd1c
78.695 +4d4489d25a99d542c16e06685652cfa3567da4eb0cb517be1482939da0cd
78.696 +d0ea3519ad1e51bd9dc7b9077375a8cd3b5de9888697e853bacddbbdd1a3
78.697 +0e442e1d6f2d652046821813d0cc0e8f16c97cdd32daf239f5b2b65ef620
78.698 +46f6e9821b2e2ec539302747795fa746318514d38bdf0d0e490c00e114d5
78.699 +03e7fc9a8fb83b14337a5bb4d640b52630f5450bb3bfcf7cecfbb1ef5192
78.700 +ae401265450db197bcfa07315ff95a809bc5fb4249e3a728a817f2580ae3
78.701 +50d8d6577f79c883ab4a3119d9ab98219aed0d1e826023a66da814396058
78.702 +d95e52d9af8bdbcb0454721f27855b686d13bdb473f650c9865f3e04f08d
78.703 +b10f5256a3e59bcf16b12a84bb7ef3b370647cdad5929b722a05f5b3669e
78.704 +14c232bb82fcb9c1dd8155ff4515f4e83c895cafb86754e896f38e5f3beb
78.705 +5d29f1bd99cb8a09c5e50f412f6d8a773b79021ab2c4831aa663c5defc4d
78.706 +553616874dd5bd8b75c7a2af7d029aab5a72528fbc4b5ee3d30d523412c9
78.707 +60b432434017c4cd68b2062d28f307fc287e11663511d1a6b52143afac0d
78.708 +ce0f7ba3f326fb707fb8d2c985dd60090e6664f2344e098a7a1a6448026a
78.709 +2ee651e8141cd7786b6543f512e4c31d25dcaf6652b1eb52706300b771cc
78.710 +0c49295067befc044ea46341927123ad4b7d094784bda7fa7b568853d0b6
78.711 +1e4cc39e1abcc9479f91a2501009ae34ef7d5ff56205cf5288503591cc55
78.712 +c48abcc78daa4804549562afc713a4c11152e6e4331619b2e474a25ffb62
78.713 +7c46112fa4259f07871f8d6882e9a7ec62d20a86a0c502815d0a8f3f5ce7
78.714 +cb4a6a74b6db8e17d54bc919b82c7c729cc05b98855b9d8a0fabd8a9bdfd
78.715 +4333f395607631f57c0473be0fb290c4f40a7aa6ac49208570ffa1d0f849
78.716 +d4871ebcf9ef6f5106301cf54ff8cc9918d6de74d519fccba58bb1c21543
78.717 +f3bca9f43c211b2e5c233ff6dff2c9b56d3f656f6070d13dfd0be04653e4
78.718 +98c670770e01c07b731ca0e2eb56e608828fedaf1a31087f2d43cb4c0074
78.719 +e576769b0830577c86ad5de48ee216df02d7c4e4ec231afd8e76c608fc9d
78.720 +06cc86f38cf4d839e0a0829902f56cf2f86f08b975a6bdd0642d6b4c78e2
78.721 +57cf9a4f52646a952f6a220c36c91db7f44c7f44bddf33328ea8cc01827b
78.722 +5f2d79e3ee6c514a4f8597a847ef5f32c6400736e6ade28faa7bc6e9c6ba
78.723 +e4bbff236fa6dd2b0ed23fc77f92649feba149f82488260b0bea2a4fe1f4
78.724 +65d96d8c51719e5e10d4c17d1b67e700aac36b1ed55c93b4b2604e72f51e
78.725 +b30fbf5b64c6fcaaef764639ebd789f82ed354712c7f9fcd1df257e14c0e
78.726 +8fd59a0eddab684bb1b4176d79b22ad2605bf534e4b8fac2272fbdeaf210
78.727 +0424a2c5cc65f8dd5faa13313dd926128ed466046ee94bd3eb41f3ea5505
78.728 +5a70603a2ae1981bfae8e77d850fc5a5bf1bacb3df9b7cbce68ce7979fad
78.729 +a73c2900526b68236c6d37197b0c521c5b1cf5cbbc89238586eceb99818e
78.730 +aa47ca94ff615233575fe83d0d50d734351e0363030a12300f7b20450946
78.731 +17bb209c346ac1d35402b617d6260fce04ce8b3231ab5c05af30b0f3ccb3
78.732 +3616d3df334c8d963279537563222dfbb705c3e14616ad01927f952e6364
78.733 +4c4b7fa44ac97616c1521facd066aa33b2296dc03682eb6a3b9dd8e5bf62
78.734 +53f10667ecb07bbd50553f1b211067f5cf098b64b84d94ba9ad8b146dc9e
78.735 +8e9be06bc14cfe0945e22fd819856d6996e857c0bb5f292defeb493589f4
78.736 +515700753885d61eee1b8c19e6e94fe2302c07933f949d6bf119d207fb04
78.737 +dae7bcff7578bf33d77e29611c7cf03b2df12c242827ec4c4e5b5343ca3e
78.738 +4f7f38ed337583e30dedd78a082f41d60cbad55d59dbba11af1bd296ed6f
78.739 +e31d2e10d3a8b5ea698e656ff97755a47ddd862d23309e2e6ed3e3e111c0
78.740 +2c3a713d782fe301dbaff0a4225f932576622d1cbae40d20f46958298d01
78.741 +783851c894f2712bfc4736d3802e548a704878e2d139348671fb96d0ddbb
78.742 +f56d9349172caef0dfed4b84d867116d91063dcdf9ec401dfe8abb269ee6
78.743 +0d646bd12e0752313e2ddc272d9f4aeb9d940987596ab623f9198765cec4
78.744 +62f7b6c540c9a70c9a872bd28ea62e056560b61ec51fc68eafe008f20760
78.745 +246e06374ae5a6bd2577217700507978811ec29985ab644e474e41e8a105
78.746 +295fa67ae05e0739e8c7fbc51104522934942f53e1e1df1ec2a66f0a74b5
78.747 +9885cf2c2fad1cab3e2b609f126ac8b7350d5408a7df9ed5c27a10ef6505
78.748 +6f0d877cd7bb902977ba93e6e8520d2d018560ec8143876ad0dcb95b173d
78.749 +af72c0d413bbb5541f14faa57eedb3ac2430e36911d2f486d9ebf9cb6745
78.750 +2ccc763e1e46e7a4b8373e06082176a6c66d045e18f90b4b2ad15802f6ef
78.751 +cf2130cdc627601ecc19887784b6de7fb6a193bc3d057ace29f74199acae
78.752 +69526ba6f7a2c669593f9d0849f12e37201c32c88384e4548a6718cbb2ab
78.753 +714ccc917d93b865ac7d7d4dbd13979843f4f5c1f8b937ef12fcdc9aff50
78.754 +f09d2625f4367ee70a98772a273d8919952102aa03297e3cbcd876da5abd
78.755 +2ceb162b8fe1d9a22ff694495528c09a8819fbfb6946ab205d4b2424f6d5
78.756 +6fa1c704065cb64fb2aa0fdf291fd5e7daa38667e6d8e889be7f4c453da0
78.757 +59c492cd25fcf4a03a6995897145273a66cd6ba999138bc8e2aa7d080f9d
78.758 +231497ed28a9a27b6b0d4785bfaee46fee71b26d6839f2549a14e7ab7347
78.759 +0b6cf368d2d49e74c78d93477828e4582589cb447d795181d3f13dd8ad52
78.760 +3c750df8f19b3260c17a6598b406472a7204dd26c5988911ce9884de9a1d
78.761 +ce33d834becb1dc80efb07f32d3ed6c2a484c5d53746071576c3f67f25ff
78.762 +1558986fe2dc2265b4fff79c07e3f4c6c0ce8319e04c14728ed722cf214f
78.763 +65066148bc817753dfdcc0950bf80dc515002e1a92e7d8936e9b3aa9635a
78.764 +a6d512c68aebc79a62a6bd17a411bba7684e1f06be9bc3d1aca25d50c8bd
78.765 +1d75597194cf87c9ffe04ff28bea91b5b9521fd356ed9e036466137586ee
78.766 +f0a8795486438d0d9707cb2854f12963929edac394c562235ca71376d938
78.767 +e4e1518668180b857d75318bc22e9f0683749047e7649f9e20b35204b6ee
78.768 +60c0d47bebf53179a083f0b4cad5b3327a3faf2cf03753e3e46c05773629
78.769 +7e9bb305f603369cbb568350b2b5c6d23a35c551e0ab28b082e321ef4ed0
78.770 +e2704d35c75b4750af782160c2f2e9aab0e14e541e95b64ebedd66db2c12
78.771 +a8935a60177cab634e20a8871a3a72f4b21c3a34d9dac37176a321c2ce3e
78.772 +e828d140c8445117e7fe4738000c30ffae8e2a48bd618cc8813e38fa0f86
78.773 +92ca634d1e56010987483aa0f08980d91528df3d370ac724acb238e141ab
78.774 +595dcb3da7a769de170edd5763078d1084e2ebefadf8a50a816b50722617
78.775 +c9539dbd68d9062b015639708dd900aecf4f15adb36339c05a9aec7403ed
78.776 +771f9f28c60e52bda3ba6902e06334036c1dfd66d35ed00e3fc0bebf55da
78.777 +416093b5cf512217c47f905ccc91fad879d63dd1380519a02025ddf15d70
78.778 +eaa1bd8cb6be67608fbc5c94796bd09ba35933f64c5e72a26db1ae40ef49
78.779 +af5e972fa44660588292b67ac670bf046cb1f5a7a0d73ffd6df862744786
78.780 +4a56393b0f1b4cfcfa362c74634713093161b29c94a2526b7138aa92fdde
78.781 +b37a8c1f30a6b3837d9500b340515f0412e681f5bf36e7869fa157df18e5
78.782 +c79df3e6aca924d7b7dd2e0d5b87682d7ea6913b26397ac180fb75fabc1b
78.783 +8e156ed542b9d8c83079bccd141c187f90d72694de4f6d08520d11cd454b
78.784 +bd3c2e6d259694fda0c8decc724bdd650163b7f6ce1181590c06de4c0dd8
78.785 +536aba318cabf54782c919e07c2ffa1034143175d05deddfcd7dce6c86a9
78.786 +ec9bf6a4437da474aac2dbce2c91aedc20043f179d5c9120f3dfb1cf6906
78.787 +c27f2ec68cd75035c283e1672ea90d953a23a1515c420b81c3270fa06573
78.788 +4d003eca1bb71a2dacdab67e44f47c266c2ea1776648b62bc110671e6eca
78.789 +4546d3c72c8acd956e10452c32532ed51bf3d0518467fa829efd9c896e8e
78.790 +1e5c7ff6da0b51e872e403470affc95f25e1d2b9b59ddb0472705e14fdc8
78.791 +fc2af16527188508be10d098372cd7eb7d62a85c8d8dd1d0f55ae3ccd0a6
78.792 +5dd6bf776dc187bf4de409d5db3fcc5a6d852848a251f4fb4e01dac5e9b9
78.793 +587fa8c46ce03689709008b34dfb3dc105def80a1b515abcbe06e73fdf7e
78.794 +7136e40cc922fe9a9da1726747e84427f288d934747b6c587490734906b8
78.795 +a91144ac82a57957cffab561714e1ff5148a39499dfc8cc96bf5d87ced17
78.796 +825e8f80cd943d9a73945fb8bc51cf1f9cb39c605491c1bb8f1c4139974a
78.797 +59471ead310d041b1ca1ecd5e9f92007cd8243cb3fb1ec5256444699a9fc
78.798 +ed6cb31eaf0912c16fa480a1cb4a8f4a9cb6a4d9a9903d1e2f674286032b
78.799 +489b8a23ac4719fe435a9fa2d79abdbaba740e69d5ed611421b1aefcd06a
78.800 +362ddbb7b79aac41e3e90657afc0b87a6e8c57ceef70a628efe19f568634
78.801 +50f47b5c6d95870039caa3d07a54e58df064bb5f59dbe9b9a2c7c84d7e0f
78.802 +32386309560a0efa2cbfa27f861b208b2df4a062ffe2c59c057296aaf5c2
78.803 +0f48ffc9ff0692f8cfbd6fc6ed1f3a14537ba40d7267e6b5f69c997a949b
78.804 +26577a9a99db3f53167355c4967dabd522292ddaca3c537bcf303ce76add
78.805 +eb99f6664227a94d6a698dd5a5d40008349376067d057e28e55972264502
78.806 +e035b1f5e33d7b3aeae016f9be50f2aa09aa138d15d7af3c1ccb805f2d5b
78.807 +cd4e9b2b5c288b2af4a25abf0a9093749377c9e8232ba1af17962f85064a
78.808 +23b0a13f11acbb471cc700f9f1b588f72cb63d3d1a95a93502ef74ed212a
78.809 +c452f1a84619bbdf61a1dc79c0d9ba29c7f19b400f682cf66f7705849314
78.810 +f5c8bbf973f2c53bdb060932156bf2c9cd8d36cf6271075500b0e3e6ad49
78.811 +958af46a9dc950f4c29f1ab5dc0a85924f7ffef259f778459c80118b1eb1
78.812 +ed29208d1145b21b19d62f755de4972c57a09b3decb0a8096ab025fe6b9d
78.813 +be49ae35394f0ea40d3693980f97f712b27f0e28d8a549acbf1da63518d0
78.814 +374941effacf63ac3de0523cfac0dcaeb690de5836741fe58917c7ecffc1
78.815 +95e7b560a3e763aa70fc883751bd60ea0a0f893d8e9fe75a66c67e202c24
78.816 +84f66708ae74413c0101fe0b5003be20881345d917203b582a247e6c74a8
78.817 +1d0479f317aba7b9dbbc0a92e91c51fbe8775a44c57699acc9da84ad60fb
78.818 +9629929d1edabbd70b4ef9887ce4ec2469f154fada42de54240cf3302364
78.819 +7c492ba17e6936a4d85e0751df0945463368a803fb40d8ded22abe118250
78.820 +86cfff1878abe5b100bc08b991cda6fdfd579332360f0c3374842edce6ed
78.821 +e43649d6702f34668a29bf387e647f96d78f33395e8d4b3521cb4fb0956d
78.822 +12c924c16eee798cde68e319a358cc3524c753177d976d4e14a2e0cb72a4
78.823 +80cd87bfb842060b1266568af298bbec58a717c577be73ad808e004348f1
78.824 +6aead32a3d57457376ab57197534d6e469ed24474a83618f3ce21df515a1
78.825 +22918f4b62c642de0c8a62315ebe02bcfc529c5b8f7c127085c2d819e29a
78.826 +f44be20fa077ee01a8d427bbe3d97a9d2bafd77f17835279bf135900aee5
78.827 +9bc49582b18d468bf93e47ce0bdd627775264ebe9e4172839a444f928580
78.828 +8c95895b7e23592b2dcd41ee82e966c26aa2143e3057161511796e980998
78.829 +1f2e4ef5868b3bf4576e3546e6407e35cdf14654bcefa7557d09407545a2
78.830 +38173080b4771ea52054736677a8d9749a2b22b46b24fbff93c55aa2274b
78.831 +8c7ddbd751bcaf1df00ccbe1f24a80622aff192fd6db2238db941ec44ae0
78.832 +dd73f6b2f80d89bd0aa30c038583deba14913d38a7b61b54522755e251b2
78.833 +aeca62033a39ec1143b2b960f9cb87f748428bec3243b8164f07d5ff72eb
78.834 +f2ef69347bb933241c2401a96ba5ffa3f9ad060c41f4e6bf7280af65293a
78.835 +bbae49d723dbc4be61d7e13f7a5931a697e7f2c6582dff416341ccf5a24e
78.836 +9a53686a1e13bbe0bb480c19a4e72a5e477bd29f39dce1a17f63f1e8c696
78.837 +d5f8855cefdbf7ce681c7d6ac46798ca9bbdc01f9ad78ce26011ee4b0a55
78.838 +786bb41995e509058610650d4858836fcedfe72b42e1d8ba4d607e7ddbbe
78.839 +3b0222919c85de3cd428fed182f37f0d38e254378c56358e258f8e336126
78.840 +9b1f1acd7f387686e8022326a6bbc1511ed3684e2d2fc9b4e53e83e127e7
78.841 +84da13550e593bbad1c87493f27b60240852e7fa24392fbf3f478f411047
78.842 +3f00a8fdb6dcb8aae629dc7f055d85341d119f7f6951ae612ffa7df82111
78.843 +d1ca48306a57a922cf4c3106f0b5e87efba6815f6de4294c7a0394087067
78.844 +677889d22a3fd86b0796200300d2716445078027fe0c0b05c86ac80d2095
78.845 +ae874324ee6ea3553bcb92fc1522a6d1524f6fa22b71598fbce784a10b5b
78.846 +61e50307ef4409ffb7b38f27800f2185140ed08fc4ab396050b068025a9d
78.847 +e4bddcad201e72ed9b41c4ffd4cee743c9c2345b95c5071442defc8ba5fa
78.848 +9c63c56e209df41d10d93135a8080f7cccacf67e0b0ddb3e0a31df32b83f
78.849 +290b3c536e9949973cdc80aa5c8a4feee20290a95f68e59f54050192de42
78.850 +f27464ee374e4d2451ee8708933b970402c90ca3070843a449d7c3146347
78.851 +1efa666a60fd5cbf55a47e4a3c5c318fc1af944d58d32690a2c7eeef09b2
78.852 +d94721896e1e3e76e44a8efd524ed5d6f5eb9da093d277441546c6828745
78.853 +ad71b6c13f653dd631bc6fc55d0eb4648b7bd9c0eddb13222542f2b6e8d8
78.854 +b80bfab4365f4199a41ac690979285d917de79359a183e6fc254b63e6408
78.855 +6d33e3c029f472f40742a99f92999f302f79994ffd615f1a848194cb56c7
78.856 +12146850f5e400303bf5bcd4e5fdccd1fe2edf5352d525cb15d8327f45a2
78.857 +6e3ac276dc8780c65724d28dc6bf9c7c985840070c35e32859168890d599
78.858 +a884dc2a90194cc2e9cc6a20c6c0ee11b20adf3aff01db48eb8dba7b0c81
78.859 +7fc10cf5a66e8171a2823a4cd22f0e80c82011ae56dd895ae2d3ebe84ff3
78.860 +d521c31453e0909cb9b1cf0b030eb6b7059ec38038cae12d0e1cc4b5b3bf
78.861 +e6c821faac9b8792441e2612aa1ee9318b71f9966d7d3a64abe349be68b1
78.862 +744de7b212f6be73a0e1eb2fa30850acc3d9562f989cb2d4fbfbcd5d3ef7
78.863 +ba55717da1cabf197b06ee4d8650e968518b6103fbe68fcd5aab70bdd21d
78.864 +66f09f96208db67c1b345672486657295a39a7fd689b2c9216c6b46a29dd
78.865 +1283bdba295dfa839a45b86c14f553ff903a6f7a962f035ce90c241f7cde
78.866 +13bab01d8b94d89abdf5288288a5b32879f0532148c188d42233613b7a1a
78.867 +7f68e98e63b44af842b924167da2ab0cab8c470a1696a92a19e190a8e84b
78.868 +1d307b824506e72e68377107166c9c6b6dc0eed258e71e2c6c7d3e63d921
78.869 +39690865d3f347c95070cd9691a025825421be84bd571802c85e2c83ba53
78.870 +841223435a9ced5dead103b470a4c6ae9efcc8b53331c61d0e1e6d3246cd
78.871 +aa1b0da347685121196a07e97d21b10ad34e7031d95c1bafa37b4141bf33
78.872 +a6be401129dcd64086885f4b5f1b25bce75a4cc8be60af35479509e64044
78.873 +d49c8a0c286e4158a5f346ef5fe93a6d4b0a9372233c7434a7a6f9e7ea21
78.874 +30c0b4b9f62e3a74cc5d2916ebdaa51a1ef81fceb6cf221e70002a8a3106
78.875 +bfbccc2d1809dde18e9607fcaac008fabb72e8c50244507f4013c5a268a3
78.876 +6135ead9cc25362c37aa9511589f18d812e6039490f9c599f44e88754ac1
78.877 +4f6c1841d570efde27958c7f1b2c68772584e1d12fea252e3a6ec3b051a7
78.878 +6faebbf6f5101978e24a9ca927c02065e8e49150a55c64dd30757e8a33d5
78.879 +2a788437a9181efb47414dbc22fdeda203d4122137bd045611f68314e12d
78.880 +1d6a5ec270c8919562c03e3af7b0e0deceeddbdaf3eab8fb5632e44dc1e8
78.881 +d46e2396b0236a46659164e33709415e7b347f7f7b87a9224a189ddf5178
78.882 +2cf66c9d385470a51efc88696176f6d3ac3b7b95fa074c981194e22981f5
78.883 +1d925f980393b7102f1f836b12855149ef1a20d2949371ddba037b53a389
78.884 +7617c257bbdfcd74bc51c2b40f8addfe1b5f8bc45aa4d953c0d1d5f4091c
78.885 +6af796af6513c820499969593bfd22f8c6dcde1d2ee2c0ceebb5bd6a1ce4
78.886 +5fa61094e932b380cee381f4485e39b4b1797f2a7d8d90bcbf89b9cb1006
78.887 +2d50fff083743bf318157caac1c0179c87c03a2857fc002979e7cc97feda
78.888 +966b09ceb761d3f55cf07637256c6aa8b8e5cb6aa9739452a330afbe7082
78.889 +975ee39fad5e8106e8ee05771157e92d99003533d922ccc37add065b6236
78.890 +7613d039741f99edc77c230fe8d1baba720a185186662376b947bbe1a686
78.891 +4b42c61ebe1abd40d890751ab8945c629de3b6d2a49809dc693f9e397097
78.892 +cf1e568c258081242460af2de0ca44b7ba2734573967b3bdec0e5e64598c
78.893 +cbf41e630d821491504f414d9b54a3100dd5105a141cf61bd3ec41b67368
78.894 +c8cd366c543754ee800ffee3d19c9cd0d408cc772da10e4d8134964b0a61
78.895 +232e2dfbeacd0fdee12792504bb327a2e1fc44127f8577ca51d380a760b3
78.896 +740e6be46455cbf3917b90f0dfeadaa25d5d9f66cda43ebf9f75e0191a06
78.897 +25ba29666bbe8678822a453d4e876bad4a6b0d4b6cf98feb60339c9eba2a
78.898 +dce4ef7faba428422c503d0210dcf8d884ca9f5094aab9f3b1a2238b569f
78.899 +444748902907cb0d9d7ca33fccdd0cd29bc68e44f7bca5092be6272bc949
78.900 +baae5af92c302bb21f91b6ea8463265680f7c16f45d8ff35392a10eab87e
78.901 +296f3af4478032b5b021db8510deb617941130d45c46fb3647d94b162fe2
78.902 +2738766fb6d76a06ab6803818b27c5ff4205ba668f95b5ec5ce4ce6da545
78.903 +c13ff56f417a4e0b3b8554a1e2a985a167e168adc8c4db28a601a80ab451
78.904 +91bf32acfd8d25c39c2f17fb3bca1296d3d160f25b43b4d6b94f20ffe012
78.905 +b779339b12860dfc897b366e3d400e756f4f9f4d2c86fb9d94c11ebd1450
78.906 +eaf720056e2c39529331bdcb104d113b42c94af2c6a5035750b7ae7fdcba
78.907 +b6116d74bc07a11d4357ecf73d99221dad5cba4a7136425c2a3ac0e092fd
78.908 +606a4ab722195e3b7fdfb5a5e3ccbb85fc701c42bec43b54e964dff3fa04
78.909 +193043eead7681cedae9cce6919949ea60ef5630c4b9263c8f98b4bc74a1
78.910 +63ccf3d0a0bc1deff39b800ac90bd734dda7ecdc73169ad77e129887db80
78.911 +7a253f8807a422eda8a16c9ee9bb8fc0942634bfe035dac9f7e36d09844e
78.912 +39477c043399db4d07b3617da9d6eee76d0fde9201da98b906050748b68d
78.913 +8c944ace3c96e90a3c2b63eae27b9152cb7274fa336866d71b65a57f1bc2
78.914 +bb1f482a67f3993dcb3ff24abb0223f9a026c81b2b33127a1dad8929dec7
78.915 +5d46bdd790eb1addd771c5c3965a2f514d3a128117a44560cc10a729bade
78.916 +4e6c86de7c09a39602235c803902e34f5c176b18e127d71a011dd9a3a61e
78.917 +ebfaa4a4e2a5651be6f4067e5e09bb4f3514d67c2129e4d3ea9568661138
78.918 +1e45af07bd84f883c70577a986416747f3bd8d1bf86d3d7b07e8a350899d
78.919 +3c2dae237bd5ece45faba7a0ba30fcda7b7eec9fbeaa5a94620686d1e403
78.920 +1cd2512e8d89451c7bd8eb432c8862023d66f3f9fcec0d47598e2df59525
78.921 +d673a5ff493d458748cd6341f161a0a3e8996ca5b496508578fe4f653924
78.922 +2ae28bf4b7397c02b726fd5f9d8b898938bb668a546be6e42865f4f030d9
78.923 +5faa289eb24f7b8e249b224a95a2245605d67417a489626df7417855b8d3
78.924 +1c0043cadd2b461d32e1b39ccf409757c37b68f84e752bde6b5bbb847bf1
78.925 +57ea3434802def983d6ce5ceb3e9fbc4911b5484e99bb94dc3f383e50672
78.926 +0e85a91ed378e352838cf02921ee0ea94be01b5a60f9b1f58fcc1b4f527e
78.927 +43725de9b9dadc3ef462fa279bd7138095d4cff2a0563039f71e383430dc
78.928 +f628dc9611b2e3db08fb2da1d5383dc1a3c784e1e64541fde1d9d7f42505
78.929 +de96d3d0a401099fc2879af0293b0eeb143b78cc221f670c0479bc150047
78.930 +0cacb9a282e334e428b527acdfbfc56e6aec8d4d60745c1dc000011b6248
78.931 +d9ab4a17dca7cc74e17d33c0641710b02cb1edb0addc6be214b17e9f845b
78.932 +2d9c8bf03c19e131e00f91f2a393b5f2ae7c3d4ae9021c4d7891d84d5067
78.933 +377ce92836e42eacd7e540824f7ac95360ce116d41d17a50748748971c82
78.934 +27f089a22ee0d21940de854f737547b73c7517addd9bdaab425a6c2908f6
78.935 +87dd990d6cba4d84308bdd4c4435a6480ecfa1a14daabd4d8e2398178e48
78.936 +de28b84f7ce4b61d2e6e64fe043c29a941f6de7621ee6f6d8b506221df05
78.937 +db238b8fe4323cb5f259d4d3d9c94d4ae1ca37d6c34345489c0284171346
78.938 +e9830e2e3c6c167238a7ffe0989d3eac870cd44102cae139469b9d909b5a
78.939 +9c34792f693ac94ecd35d2277080e30a2d24b50391b6f2a3d3b6c81f7ed1
78.940 +a7b218903e7fed7a63269e27d793a2e0b40320ebf447c71f36d40dee002d
78.941 +7257f43c8add31edf2c571123e46fdb413e007cc89e99b6f98d77ab38bff
78.942 +cf140f787e45ffb2c7cc4ddbb59a4e32dfc36e2875f204ac851d757c1236
78.943 +12deb31324ea4c201d27fdab46e9f3988ad2bcfb8e9cfa8c487831a9b0c6
78.944 +60b20fb66b4c77f52359ac96f3b3d189aa0571c1c53db06ddb10f08882db
78.945 +0b1e93e9478d4c75626c5fbdbc6044c4d82684b310ab2af144d12bf36f1a
78.946 +c0bf6249d1da9ab319453594cb19d0e93c4e047fb49229c0cce76d0cece4
78.947 +2e76fabd2425382afe707db032cf617b046a59a2fc1bb3838d98fd5c8053
78.948 +ecb918bc14762e4ca45027623988f434ff4cb08bc9bff5d7de21940e3e03
78.949 +1ee042d9c30662aa76f96213fb5a92047af60f320e4660eadd1ec19d0086
78.950 +072f2202af5f219725f81882f10d1e065a8035a9946d0ca0e48a5e7dcf61
78.951 +0283b834eda01e7d94b3453830daade2aa6c947989b290c02ade0d7b2620
78.952 +813ad177ed82813b6a985d5c0a2d42419bda763d409da085936e33c817ae
78.953 +68e5467eddc30be172de855a0f7f5c527555b3f4d942401b450f08273b1e
78.954 +c5b5352fdb8562a71f276284cf7c27537e628f94bcbffe8d669ea2645752
78.955 +60830f1e65e83a2204cec393f6d92d4f61f317471b4b93039d298ca2cc94
78.956 +eeada0140823a2bcd1573e732e7b4bde7368f2ecca5961ad547f554ae989
78.957 +98d87b7e5d07a85c382bcea1693a697224f41eb8b406bc6a0c3eddfe8b5c
78.958 +f25b11c3e4bd91ea7d6274cd6b3ee7b8f18cc3fd502a324c645568dce9e0
78.959 +d43caa61f7306fd5488fcfc439d85f8160ebf0ac90fc541f9c74d35d7833
78.960 +09309807a639477bb038200738342e50136dc64baa7cc1b879c61f7e1b90
78.961 +e1f2bd4f6e54c4dc97b8e4adeb102979203a31fe26a7f58c609915a95abc
78.962 +4acc263179423f8ab16b04272d5592fc536f29a45cbcdbe15890f119ca9f
78.963 +c7a52eef41dfa5c4fed087eef8e698ba738e300bd58f2a1a10da1198c1f9
78.964 +b60e2032f8384a86aa84027df21cb87977528e3bb9bea1e3a6879c56402e
78.965 +a29063afc6ac0194f4944433f9a5872cf0a2a741382d7f3c0ca7817d5d7c
78.966 +4b8bf53af0f18b1eb54480519cebb61d983157e039b13025e7980eb36f54
78.967 +3451bbb84e470ffd0f98eba80c74f238729dd6278294388a2e06de68a719
78.968 +47b6d478c85f124d14aaa835620e49b7f5a4f21347302c0f0864f7ebaeec
78.969 +d0831c36187cbe9c848736764a31056d2cef27c07cca00033dcddca9a2f3
78.970 +b9ebf28e67257b69cd38bc23c711b6a2f6e4dda9bf5a19da275e6a8d683c
78.971 +723bfbb95a90a344a6f421f0b67ae84c74652288b0597e4c86c28f73808a
78.972 +77455f2948e8df634c2d14f221626b019033f9230c9167982cca9ae6dc37
78.973 +aecbcb49fd9fc1dbf2d11bba7187888721bc42a7f47c23e07d2fc5a7a91c
78.974 +0dfe255a7f9d17e69af1618502a6b90b1dd748c7eaca1e1ebe8b861b04ff
78.975 +e5f628f47eb4e7e65311037d7a5713d7cc3552dc85f452ba74c4f12aecd0
78.976 +d72892c940c3325640d62fe3bbbc71361dce6d54766e1fb99dedcb2d19d2
78.977 +fa6fa21f9116e03952ebbef659816a62db51a9b5b3916ff818518774ccd6
78.978 +79d44100d7236f211f36fa80a4cbafb3db76ba1e7e7f12082b0140eed2cb
78.979 +5e793e24501715c6c170ad4f856a4bf16bb10210025156e635264d3cf18b
78.980 +1fc1e8cd2fcfdc2ab1a24af9087975bfcf6fb703fb36e288e58d0d2ffc98
78.981 +bb4318001d931ad6161dcdf8984e6690e0f6bb07af81bf07445f8f57b355
78.982 +6b960d24e7cd152708489e4d953ab6a155a757e002ead97585e6c5333d7e
78.983 +5aaab2731f047f3490432e0ebf3d0d628eefa8c1f665b9c86aabb0706639
78.984 +5bc372e16378f0d9b439c98e7bf87be73e934995d58e4e70d3ae9a5b54c8
78.985 +87a19f2826a772c39d41805c642354d9bec75b065f148f7c1e435dabbeaf
78.986 +e4a5744e3f2894a928121ab069bffa3218a106a9dbb83971353a7c7a5616
78.987 +d9da66fbb908173f9b07aadcbd4d112cc353e7b70476046ce5a92e86eaff
78.988 +4eec40acc840005f51f55c9f5874216851e9cf3fa431d95d3032e779e356
78.989 +4bdce33966a3a798b170a06c4cc9f73700224c858c36bbf2d0326c337ce9
78.990 +46f69c19a84187fa50afc5b36010f9a7612e3a25e846d49bb907af9505e7
78.991 +d8c78748d7dcb501bbb3d6603e829deee3784f2f3ca583d3738d6d2ecfb8
78.992 +eaa887103606211a3c1b5cd74a3e0e96fb57da91baebaecd3669661e7b1d
78.993 +579ba41928a40a7028acff6cd409e601d23ff66ff2c8acb12e535360d727
78.994 +60d2e988d801930e0e9443d60dcb9f378fa75d58d73e6a3b6e5b26407c82
78.995 +67d50ad97787f8a9b91765e41552283cb67e43e59bf71cf08b9755c8ce47
78.996 +0cf374832c72d1e9702b55bcfc8b5a4e966d5072fb2a72a2108574c58601
78.997 +03082ac8c4bba3e7eeb34d6b13181365a0fbd4e0aa25ffded22008d76f67
78.998 +d44c3e29741961dbe7cbaae1622a9d2c8bca23056d2a609581d5b5e3d697
78.999 +08d7e369b48b08fa69660e0ce3157c24f8d6e59bf2f564ce495d0fca4741
78.1000 +c3a58ec9f924986399480ee547ad1853288e994940bd1d0a2d2519797bf2
78.1001 +8f345e1bb9cbf6997dae764e69c64534e7f9dd98f86b5710ff8b500e1c4d
78.1002 +f509da50c64e213ebdf91978553a5d90908eb554f09b8fc2748c9c405903
78.1003 +e7bfbf0ea7e84254fb6735f09bf865244238e5fed85336c995bc3a3b9948
78.1004 +947a6eb95db4cd1b64c0fccf82d247a2202e9e7eef5a550557625a0192bc
78.1005 +8bcc9e461e52833f6b8729ccd957d5c4b6e07016e864fc02b792c7400ace
78.1006 +d0a8f43c755f87bba6e5c6e1022416e5454cb34a19865d951f7aea527760
78.1007 +53658cbf306ead832244f3062c39a0a121a1157a8e47008163c5bfc88197
78.1008 +be16e9a1ba26a035a16dd38cc28dffb666dd4ba7356c66b7bced9e26e905
78.1009 +4ce25f6d36607d8f5dda1e21ac96a815bb2989f01130ba1aca9aade554fe
78.1010 +effdfef5d6b0d2a01aad92f599f6a12e121010ae6acc6f150f19e7305271
78.1011 +97da761b07530ca19b84b119e5edca1fad18462143b8913d6b3f6864b713
78.1012 +7a93bb9e1bc29c09d660704e8d8292c61072ebfe35c354a2342b2458a353
78.1013 +31d043874380d439388e46688a53bcfe01bc190ef1a6b5dec9d40aafe822
78.1014 +261b28bf3e2d76f3dc4302506ce3387b4aa2a51cd4ba1faa2ed1fd7df664
78.1015 +6772fe9f83d253451eeb0448b444b8ca80cc7cb653c2d1eaa0de6f2b1c72
78.1016 +47e6d24ae72e620e200aff83a557a1aa7a0ce0a9cfbbeae03c31d8cbf1d8
78.1017 +20b53b688ed2ffbd83418d743ee31e3d62216ac7be6c12bc1917548cf670
78.1018 +d69fd2e78d9f7786ada0ea30a6f6d9fbd1f1406337151ffa1d3d40afbe03
78.1019 +728fd1aa2fa8a4f075796b9de9586b71218b4356fb52daa01d3c18cb75ae
78.1020 +d4d33fc809dcb6e3dcf7aee408a0cef21353d76ed480bf522fdfe86e0e0a
78.1021 +b7d097defcb793057f0ce98ea4989a9b6787b14029a4bf10315a2557149a
78.1022 +fe9c91e7d825f7518b343fb556f0177a8f6ca08fbda9913d52997511590e
78.1023 +b9942c9813b4cf4d4aae4919401f2fc11fef0620eb5c40532cdb22d5fad6
78.1024 +919a3a710de6c40d54993b5386636499c866938e33bc703a99c73adc228d
78.1025 +95cac73ff4f4a275c04d0d787b62c6a184dacc4024d23f593e7721be232e
78.1026 +9882fb738160e52ab905f0ce2c76ae6ff2c8bbe118a1acdb3b464178cf01
78.1027 +94bc6a50df1090e9221be11e49f254b06c3236a31569b947ad041d1c6b55
78.1028 +bfdec3c18c791ace0fe2a59504eef64a4eec4b5c8dd38b092745e0d5ad29
78.1029 +276bf02c419c546627672a5764a4904635bff86fd0781d36fbdf13485229
78.1030 +71f355de2b0ad250052f50ad70f61afc870ac7a816561d3232b73360d4ab
78.1031 +2727b2fd045f254c782bb3f1f49d94c6d625047071b7e32da5c6d21a86de
78.1032 +9283fd632074430772bfbd85e0c9ccab1dec16bbc049c3e223bec1b65c8a
78.1033 +9e98cf58b30a74f74f1a842dc91e30c023498e280ac55edd58f4cc731d81
78.1034 +e443d9b9efdf5fea63c9f357320e01b8740eedaeef2495cd02eb2f338b3e
78.1035 +674fb074cc497d7b1937b188da857c2c230e9a931cbc00c85a7a36fa80b4
78.1036 +56588e1bbabbe4ef429a6aef9bd4eb89c5752421bd049aa13f4dcf9b51ce
78.1037 +2503e90bc118fac78a25d187353d6f5d496cd6130b337666f49619cea985
78.1038 +dfbeb7e49c67c1e0f0f8e9ec8ba14624ed0982dcbb69415e4b3c8ddba140
78.1039 +397eb1fc1ddd36c94c374f018873ba41109e45afa51f0e691157d5958c06
78.1040 +26fbc0903ae25e47ee372389cf65472a3e4d9769550bdc42c0b72f9a297c
78.1041 +d5d3c16ec67e06036e740ab664abc9f10b9499269b73ad3678daf4474329
78.1042 +c2c7252c1f0df1e3b5e8f198dfef8325cb1e7e8057897a3d7fb5bb5858e0
78.1043 +cfc0c115bbd7362d8e8ee41862af6eeda681cabbb06f72ebd2ae0b0be45b
78.1044 +a9e1be83f1da30687a655e5d148fcc17d9f53b760810a565f6d2f4cd5da3
78.1045 +5434116edef756adb4d3df544a1de593be988f2bb8d36c34deaac7d9dc15
78.1046 +cba49764f1e03aa09fe21fcd7c74e3d6487ebe219569e019f10dd163046b
78.1047 +c1a3cb2bcbaa8558197cb2c18709a998b4efa8ab8c9a71d2ccf942c17662
78.1048 +1b88dee6b424165d6ce10ac48375e760983818e0085276b1674dd41042e1
78.1049 +a01a8de111c903f74834199b3230bd475d92c6226ef74eb1daaec3475a6a
78.1050 +fcb47644a17c7e390ee3b16bef1c1ca6c55eddc44fbefbdde525921b3047
78.1051 +0d76817bd8ac724739a8e743eb09cf78e88adad527d4f115b8a32ed4898f
78.1052 +45bab3eb802b8168aec061e3ecdb026c056fb9efe7e2df48bd516ccb12ce
78.1053 +00de08ed8be4ee0c41f40f4c8f64483e0ade90a78d6d4fe9203fe0b97c60
78.1054 +3b2f8882bc15a212453c691c52d00fae8a3a26934ff8acf68d4352eef75a
78.1055 +0b10d938e55b7333dda2db0296a69e9775bf82b1aa6d684fd9080fc1c11f
78.1056 +ab4369c7a95a9504063db900a6e345bf6dd99be041230b2e60cc86b8c345
78.1057 +1d84a9c2cb4ab6d74d63dd43dc26eb6b384f5222796d4083dcc3e1651548
78.1058 +d9469f09a33b213a33ac52a6a2e23802d8f8a75c01a607940daab0051410
78.1059 +73a88130bc192f303616adb113c0051b65e12086cb319c0a5323fa7def40
78.1060 +402f5f87a3b2c2cf0e92789985f6775ac2743e1ffe2d0668291059740d45
78.1061 +43bae7a2897e5e658592bf5a72966097742e0702deecb0cb12499eab701d
78.1062 +34ba37a08346217a415e44297a181bbf3744f0a49230ad6f030e11462be9
78.1063 +afc2ae14e0587bc02311b48b8e2122c28cdf14414f3680fa52dbbb63b17f
78.1064 +6ebe4a1204f3c5d6150cbf89a8023890383153838d4dde77d4c8b1b78823
78.1065 +8918c564d3babfe58eeb154307dd1997f5ab7105426e35c279008b2677e4
78.1066 +695c60f956b348799c04b734338018fc27f7de7ad9d73468fdbc5283bd14
78.1067 +c066ddad9a3562f16baae15d72d7bfcb409e1c874e9db1a8cde233b282b9
78.1068 +6e76e9c08d85ddfbd3cce7e64104d0b0e95291bd91f405ff82f41601ee20
78.1069 +8471e613fbbee67f269e4e954c36d1d18ca9880b7cc2b08fc990978efdc5
78.1070 +1d157deefedaa765c1e26ee125d4a2514a41a3b95e9151a824532d7d6486
78.1071 +35ad622718fe71219a697e94c2e64f26424cbb767acdef5cda70e179cd29
78.1072 +b7e318d1c6d3ad26fd5fdcbf2fc221301cc1f10f5ed86b40a1a6bcc01c90
78.1073 +eafd65183e75609610637b99fea57885efe76437df02a2ffc21223d039b5
78.1074 +74955d9a54ff41980eddaa8768c5ad883a0c9150877392b990d63c6805db
78.1075 +7b8d6ab1358cbedaedb6feadb0ee4fb8f9c1ca03a3e755a74227a8930bb7
78.1076 +2ea0a00b48fc626fa14d7d48624aedc31c556f44e982f3ccbde7ee735f73
78.1077 +629ab1b65bcbcf0a3586a920477e8c960219802fcb1bc3a179032b324f8d
78.1078 +c424899b38275886cb5bc771f26a0880767d49cc23426a40a4b6ff8fe48f
78.1079 +d747565fc537565f6d7fd08706accc60f5fbcb45bc785f45ee9b0812366f
78.1080 +ae71b23ec43f3549c8224d78baf18719f05108d5741e681457ead8abc050
78.1081 +462481771a8dc6cfeb98956e163981a98c59ab44d90e9c3a946c453b5071
78.1082 +db0c769f7fb5144c7ab0c9ef1a6db1addcde1d4ae1daee1b4035af256a04
78.1083 +df53926c7a2dcdb94caaf12f986e20929ba4e396f3aa7c93a7abaef1294f
78.1084 +5f13a0dd3c3aaa8fb38da3e15daa32163b7437af683b4f5e64cb14aebbde
78.1085 +8c69ed2e8cdbfb213fc8129af29ca2c06c8f85a5038d688d1fa5d1b54ebe
78.1086 +4dea81a49ce24131f8e6702e7aa4e2cba078d5dd373f894ccb275f49c690
78.1087 +1dc772e1d2f5fb3fe15dbfffac62c87110162074eb72ae4e5e446bf7e650
78.1088 +a554178d0d64d3c07f330f0d99e99f2239cb1597f2e5f443854cdb0f5fab
78.1089 +b28fe62f22e7f3419d017980f325351bb04f8f3c3dc57fee03cc029bd29b
78.1090 +202308d5a800ed2d500d41ace8e54e2557bf25b627883beb8118d800eb94
78.1091 +f4253f855168f7fc8a2d29c5fcb76bb90a6c4e345722b8991a854047f46e
78.1092 +4e97336be85470b6be2b9ba573dbc4967ddcdbfc3b6fc35b0c7f3f2f570c
78.1093 +55dc3fee6d80bc6f46cc7e4d86a0b86f6fa61d062e213d9e442db63fbf11
78.1094 +d03165b44572096995ed342893bb672f6bb55ff8fed944667995f0f89a48
78.1095 +a904c47420f32afd14129c6e2bedffce1f07ea69d550b6909bb5beb4aa08
78.1096 +b0b44f35e018ba5206fdb4df0228462c1fdbb95a429e53eb27bb1b0490db
78.1097 +f07202c3608d0f4ce08570e3d6aa3d4581c569b57bd8c1ea0e4ed3fc5497
78.1098 +e316ecec06e6be582d9170d426f6d22d8c7287b8219945c124941ca8812b
78.1099 +e97efd9105eb6999edc0665016633b3b48820df736125b7c76c9f3a67d93
78.1100 +8a2a0a6b743fd42aebc46a0249be459f16811ac9eba7b63bad7c2e88f175
78.1101 +0eff8da5faaab5659824f9d19b3225aad2ac17c52c523414d3031d08a926
78.1102 +30abf474fe02a32b44d3b7d9fe0c19aec16ca6d018b71d9d395ffaea0788
78.1103 +0d4501d7cdf0f7077a2d63303d09083080d67f1f714a1b271dab9fc9866e
78.1104 +4b0571a171eec8a4e351ba2d02438cd108a33b1106acaad0ccdb051061ea
78.1105 +7f40543748115f29debfb4be4b42cae8762d62114ec6f8ef68c478a8e05d
78.1106 +ecfa18b0368428efec9eafb2353f95e3d71e1636b9d9f94a77e692843255
78.1107 +698576dce13b2b858d2d15ee47cdba3ed08d64b77ab46dd29bba6aac2106
78.1108 +ab847de378cccdaf35c64e50840248915f4fc110992c493cb1b9cd0b483f
78.1109 +0f1abf5e9b018210b477fea28234ffbe5e0bbe01338e0842a89f1e00a0ca
78.1110 +7cdde0b2d7c324d5e17d8d3415ccad703507497ac95360ce660b656e5f66
78.1111 +72a2f50761f3d02ccdc1d5692d7797699b8e2147cfd4817c81a432ff6a5f
78.1112 +39cc54927fa146cbed56a55f85f123c0a94b7553a8819b329d9dd122c502
78.1113 +94e3f6314d5117db89ae7597c4691b6c542979a1ca3d26a8e23d3eb698c7
78.1114 +1841651e08ec771cfb974d6613f2143872c739b62796bd0a45172530793c
78.1115 +28d93a65b59f79c245248d2c09428657a35b0c0e367bf7a4a4f0425b3f4b
78.1116 +485d9f402e164328a4b963f456829a39035c00283d2e4fcb71a42da6d42a
78.1117 +d46cb751287de34e6519c60bb3f1a6ba91f7bfa21dca96ee712af5681701
78.1118 +18ece8a0535d9ba1dd4bd835e004a2f38c5ba43c9b30d17045e5649fbbac
78.1119 +188922e442182d4bdafaefb39e00106a5a7765f3d67850471e3629e526af
78.1120 +8691f935b57bd38465665204a214fef1006ea37dc0781073ced5fc042781
78.1121 +93650393c3cadfddedcc5550ed483bb6355f54600e9758e647f9c9711f1b
78.1122 +e7df05d0e50a698615307c18f6d4886f50188011ba499d03831185915f3f
78.1123 +77c4b9ce708d78423b110776aaaf90396be0381616d1e9b0c1dcf68b6396
78.1124 +82399da2a7323bf42ae5347599ef4ae9e5c135522c5ecb87e201853eb899
78.1125 +db60d24acad17d6b7c2c7ea4dc221f3cb6d6caacd1ac0822ea3242ad9b4d
78.1126 +d15116c3874e3012fad26074a23b3cc7e25d67ef349811dbc6b87b53377f
78.1127 +0cf972040a037ecb91e3406a9bac68c9cab9be9a6bb28e93e3275b177cd5
78.1128 +0b66935cbe8dd3d6a8365625db936b2cfc87d4d6e7322df3dbe6ccda2421
78.1129 +a5e5372566f626a5e9d8bc66959e443286f8eb4bcfdeb6c49a799f1efa69
78.1130 +63260d0ea2d51260baba9207fb246da927fc4c89e9c4dd5848fd4ef6f81a
78.1131 +cd836f5f06ff0fe135cafd7ab512af55a57727dd05a5fe1f7c3c7bbe8ea7
78.1132 +e6680fcb3bbbee1cf2e2c0bba20185f00e2dc3afd42f22de472cdb3eaa5a
78.1133 +ddf8c6fb3682eea5548c51ddca25ca615221127b4438ea535ab3089c9ed9
78.1134 +b971f35245cf831d9461a5da9d57bc4e5606d26535a7414cef6aee2a7b95
78.1135 +bf2276044818ee0f3b0a16532934b8b745d8137b42ec2b28fae7d55fc02c
78.1136 +9ccfa4e0055f8a4be96e1e235c01b8b6ad509b832a3e90161e0a449934e7
78.1137 +4be973c939b31cbc19dad4c58e9be89d242f0ce200548cdd4fa2081ab3f8
78.1138 +e01f358d5db24b7a50eb2096d833378921f561f132cd7988708ee10cffb6
78.1139 +2256201801c667e176b1dfaecde9756d725bef093457805e16f550e8a7de
78.1140 +87ecd46e5b09646b73ee74f890a36867636911e4cda2c46a40e7d57cf297
78.1141 +9696046614c85b1a47ba55c60544ebd3ad7d750d003bda56dd7eed8c4702
78.1142 +f8b319aaeef9d3cdc59b3e63ee93c6e1e857af273eb90909ecf36ef4c276
78.1143 +895c78aa762e5376c5c542f854fba864ebce56e4b0207091139f053c2c08
78.1144 +3b7ddcd0a9909b52100002bc3f8c47bcb19e7a9cb58b1ac03fee95e81195
78.1145 +072d3aa7c8079632725f63425a3550a947834d29ac9a26d0774e90248e18
78.1146 +996731fd9aa53ab62b40ce557d98e874b763d9d629a173f0c7babfc00ae7
78.1147 +82daef5f00cf3608ebeef403dbbc19e16a1d160b889f4a10359d9eacc19d
78.1148 +7b5f126b31720dce7fc35ec861dfa56ea23fa18423ff4e8fe6e53fc6ba16
78.1149 +b95a2b5dec00f614e4f835281ee0b4bf549e7e882689e0b445dd46fc40c9
78.1150 +090e5575fa2c34b02a51ad0bccf6a7bb83ca3b929285e5e9fd054b72c47b
78.1151 +733a66c5abda526b18b2e49d0746e067e63b948a45eab2f4221c5b62ae21
78.1152 +a5d9d7cd8aa9eeb49588891d22c56b14b55ceb6488f02b73ab3b7f6c5555
78.1153 +b75452594658255e4cd58ac4815f2e1bc3888c6777f62aac2f0a57d416c3
78.1154 +765c991f0f9a33d888aeb2d527b482c042ee23783a04a73ad13dfc590a52
78.1155 +f3116f8296cacc7ab29b7d87e7864561a5d0a12bde2d36ee697064f41d1b
78.1156 +ca6ef2f801caab5295d19bf4c02b10c19f73b44635ba48a0806b967d7dfc
78.1157 +ce9a4850171a78532cb30020c0d66b3b1e7c75eaa7894904c181a022e8bc
78.1158 +9b2b8ef1202f3c7d36bcab4742d4a4761bb55b64da0d99685d319f5da8fa
78.1159 +132be6c0483f50e2657ae8af1e28f969440d6ed43eb00e95fd9e1cd490a4
78.1160 +8646f6d008598751f7a41b43fbec7770fe591012b6b0c4ae18775ccc7db5
78.1161 +de0ded2dd53e82c89648d46f0d0cc5d3ac5aa104239608d512a4353b9547
78.1162 +04fe6eb7e73d718323cf9d748b8ec5da01ec9358267de12cc22b05ef0312
78.1163 +e4b6ac5dbb6d06d7f2d911f20d527f504d62547aef136834b3695df8044c
78.1164 +383b6145e824d3931a602f081d9d656f84987a1ef121772f1f5b37a116bb
78.1165 +d2e77d4ccda01411545d24e15ce595db4cd62ee876b8754df0b85b44e011
78.1166 +b82d76ce45795e6c2c58be8690b734a8880a074f303a70da4a1b086a6de6
78.1167 +56c02cc7a4c25258eff18cb0fd868214bb46f972e26509f868d065b3cb14
78.1168 +1c316898cf22293391bd7051ac3a6927aada952a8fd0658ce63357c07f34
78.1169 +acbf8c99a5537da0023e901f0eb5547e1b466b7d982c8c539798b76ee2a2
78.1170 +252437a81a37c3b63f625172d682eeed0b795860b2755f020ef52a138353
78.1171 +003c61be2052cdd7d73b2cdcd26b127660a7b22fc51a6a2f6034f37e3e46
78.1172 +c1d7f83f8b28c7c965993abba1d358362833580d9c63fa85d4cb949f97de
78.1173 +579fb6807b95a58b78f596db50055947dd0d0e597d9687083e9bc0266e86
78.1174 +90b884b27f4094d8fb82ffdbaac4d580340a9ef8aa242be87e54b601af19
78.1175 +87a48d267c04e371ae77163ebd0de3f5297b1060442ecdeac38334844e38
78.1176 +0f294d4be73935fd8a38de7fba6d082c3d9156d7e88f2cfff0459377cbb6
78.1177 +041f37a7e05010753b98e0b67d5827aa312129bb3c3bd883c12323756406
78.1178 +d555720da8a0bb30edcfa760c01ecc2ba3b15fecccf5a10e9f358822e0ff
78.1179 +b64178fce2ea6a1105bfb72df0e4bc499b207ae26b8ea960de48e7ee7010
78.1180 +b4e671dff795e4cdc5b43e81b1604d224f0616ae311f1208859c502c1a10
78.1181 +940e7b9cd11be728bd3a0c8005ae23aea32c1b642812198a6f1aed32cb75
78.1182 +97152b1340dd35ada1b81051e393d38f3740fa9523df6a83b8ca7dbceb33
78.1183 +6e299b54cd998d4dfef804733c76156585e42b7284cbcc4047ba6b290efc
78.1184 +aa60953e98cd2b4bc2893857fa6a339f820142a52ccab0df09a2709df550
78.1185 +f22e5921cbca408e7998cc1cccb8adf6d8f8b71e6685ae59d290fa33f5cd
78.1186 +664d73e434237424060f634262f04e9a71a977556e93b692ddc3aad26d92
78.1187 +97dde71e4def64932151ad572af6e681082e9944ddbec6e7a8bdfd534233
78.1188 +9ca3106ca1ccc80eab14f1655978b137fad8f399df7cbfa2d7d3d9675e0e
78.1189 +9afec37369a8ede2c93145ab3f42a375926946680c215fa16bf7416fc892
78.1190 +bacd806cd424b9f85b47802c4336918f7486af2a03bf0d39b10169d35494
78.1191 +419cb1ab7b8f407897f70c18303e91563b497d70b7181ede6aa0c3efe089
78.1192 +ca6135b34dd1019b298e3677f8da61f864a67023c31eaa716c40cf3d397f
78.1193 +9a1209564c9ec759c37028079661d2a56374203c78b023ec61340bce5d96
78.1194 +e477a4f77e5c0db7c0d1257b4bbbc6f889b17e6eaab045b8adef6f931e4d
78.1195 +0795583d60a6b7002cf61639c6f930671f3b8ac05a1c4e002f4bfc50d8b2
78.1196 +3029fc4dce1b602cc3a5533336271bccc226559ffb127e3a562f92f89824
78.1197 +552b9a70466d5a3c74ae515a222b109d490f26e8fc2d9d72bc8af6d1dcc7
78.1198 +80463c7af81993bac2ce4aece9d95ab736b1dc73e32d1237bc8ec2b52513
78.1199 +36dbabb4ecc7ceb5d18b02043281eb9a3bfdf19bc4853c9b1722ef1cdcf4
78.1200 +fcec534923db2e2653dc48545a9850c0ac2e4594abc9f7d18a0bcf2fadfb
78.1201 +bf085d465a4d10528312f5d790eb9511ca01061c0d94136b99a043bcf278
78.1202 +c18223b1e0f1cc062b32b79e28dec2dc59a0aaa4b5f3506923c83e6a87fa
78.1203 +08a1d941bb644c994491cf7f3b0e2ccf6c8a8ba89376f76dfdb592374f93
78.1204 +528e78e31e0b18719346b9f1486f652638e3120687774030444674cb0778
78.1205 +96385c41f6566819652d825dd58f9a4308ff79b45d7828dcbfebc406e40a
78.1206 +c46e866cb0e3e97d6ce7fcac19a9d0fe39bbde66c5f0cf775eb3b1e6d7e1
78.1207 +1f67e7edb3d5c4facc85c916bf13322b56a0414ca27d145cb740fa2c37cd
78.1208 +8c142d9301f1ac3704cf6a8e93973a07fde5a331cf0cbb370c7ba555de61
78.1209 +18a6cea0ecb2c0e37152390cc57e2e4fb3791ddbc383ee26b6f4006d0d68
78.1210 +4880888011020f856a9de47f45440f127cf27ccaea7d40a3869d39ec7dec
78.1211 +ebc06382d294717644b6118354e15544fd4c6d88df9245c9a83b30e6ce09
78.1212 +e2498dd1df488a019b179cb859889e6ad2838f749e3b038b280ebc8d5c3a
78.1213 +b03e8f15751214691edf0f86281e612d7ec0773c8a5d2b433266402df62f
78.1214 +fcc06879ca196aaf1fc73a5f01ac46b44d6cbe7743ae9a862c20445ae2be
78.1215 +1544f413d010280cc2941900bf3c42ec088cb21b44a915bb810e7666b545
78.1216 +5324465c5943eedcef0c09128a995f431382e2062f5e39f4338c8eba1bca
78.1217 +e553cb60bb8f3e5038ac8073398c49f06dc734b18afa7921ea0d455e6e73
78.1218 +db8ad9f77fb5ba6c28af6b4f18cbe46cf842c82d6c960be1520a5fd929df
78.1219 +ac7e00ede976fb2be0a07f659079a421fca693de89ce9b8fcb42b0176d9d
78.1220 +f3ddd58f921e13e216933d27b49d175b423751c451be7618eaab054d3b8c
78.1221 +23e8dd6fd60182d61e9b5c86b3b764a29a62f913ee7524d8cb33737d7224
78.1222 +d95dc4bb8c2ad6397604a0ffecc8865adcb540e5da1cd769077838515118
78.1223 +ebc9f0b988545c1881dd2e7a8fd73e11bd7ae9085fb4d45526b23a346b0f
78.1224 +e4281ee3d588106db5f7c386c488d8f2f4dd02d4c08e74c1034f987a44e5
78.1225 +d39fd07538de57a42987ce290fb2f6557e8b5cbcaec168f5780927226415
78.1226 +1e11e3667d33b36a793aa53e9e2d1102c9eb30cb3ba0ebac953e0227fe4a
78.1227 +3d3c0eb57e4390c3d35db0c41946e45be2830a1ae33fa25cf2c7c9cb4550
78.1228 +ce9ff6c6e3d628fc7284daa6241604c90dde6339b7f7e7df3733416cdac8
78.1229 +e5291357e4983d74d3582a490438a7fdb0af97001a31990b1de68e6adb48
78.1230 +917daa387e647f9f13312db57310c7dedc2a2ea80800b4f4bbaa99c6b7b2
78.1231 +7ac8345cb659489307e2565ebfd17774642c9ae5d3c18068dc35170c7d58
78.1232 +4cf4173f1baf98137fa249c81f3347e1dadd6b1ba0f50c3b64c1eab183a0
78.1233 +937b0f7278eff101e5267fa6480da7d602844416490c2c2c7eb0d44ac8f4
78.1234 +75cfd611db5ec268db07c0b3608825c3e12834a2b2efaf5e2723c5199c42
78.1235 +6011cf22e64e4c0d31d563f321097935ea0c6fcbf5acd3748d90079f6ab8
78.1236 +687288dc55df29fe7958f566b27b73e2ea30747247f7a2b2add0602c7d64
78.1237 +d23f52e7c96748e6a54ee8c4629b2aab8882169653f0ba7f05236bf14364
78.1238 +244720f3259cbed73a318b29e4a9305deb65a2c9dec8a9d0f9a9f6fae541
78.1239 +83e0f4b9a9a567057a1794945168dc23cec25d1c02ea9242c9fb6d8fc11e
78.1240 +e8874bd80a5226373ae87cea91853d0625c777ceb1f5a6f3debcf2f75a61
78.1241 +460c7b4067f568ecd01f62901ade8bf8fbc5db9c6720420496f0cb48a002
78.1242 +99870773c2e7b12e83987a5d0290d9bbf589ac889bf7d4334a5147187a7f
78.1243 +71008f216ce917ca4cfba5347078f354897fd87ac48af6a6c62711d2eb3a
78.1244 +5882bf3b32c0f1bfda976f850c9dcb97170e78c229a27fd5e292d161ece9
78.1245 +a8c47a223cbdc28e24f79f6429c72b5752a08f917feda941582c36d9acb5
78.1246 +748c86072858d053170fdbf708971a0bd5a8d8034ec769cb72ea88eb5cd7
78.1247 +49f35be6ee5e9b5df6021926cae9dac3f5ec2b33680b12e95fd4ecbf28eb
78.1248 +a0503c10c6f2be6c7c47e9d66a0fae6038441c50e6447892f4aaf0a25ccd
78.1249 +952c2e8b201bb479099f16fc4903993ac18d4667c84c124685ae7648a826
78.1250 +6bc1701cc600964fdcc01258a72104a0e5e9996b34c2691a66fa20f48d7c
78.1251 +2522333dfdabf3785f37dd9b021e8ee29fa10f76f43d5f935996cbf9d98d
78.1252 +92d0a84ce65613f7c4a5052f4c408bf10679fc28a4a9ff848d9e0c4976bb
78.1253 +dfdfb78bb934cd72434db596cb49e199f386a0bda69449ce2e11e3a4f53d
78.1254 +be134c6d7fe452a0927cf6a9a15b2406f8bd354adcde0ce136378baa565f
78.1255 +b9c51a03b1fbe1e166a1f92af26bd9f072250aaa6596a236ba2d5a200c90
78.1256 +a760ca050421abc78223b2e8b2eea958ab23084fa1947574e846e48aeb12
78.1257 +26cebb8b5a92089e9ea771557599e2fff44d75bcf600e76ae7289ba98cf3
78.1258 +98208c5104562834f568ebd62801b988b0a9fdf132b6564566103b3d2d8e
78.1259 +6a099b7fbad8a13b8cd7f6729bb6651fc1019e66c4bd6ff27410bd5cdae7
78.1260 +4010bd68b066bffdb4fd5e3dd9cf7e1a1353f7a4c5157e3ad508f4ca0259
78.1261 +9761b7cdd6a81b3560b8765be3b0432fe4c25dcb4001b00c7fa62874f681
78.1262 +ed22127dc3974605a05be8d8fcf9701f859ffce4dc598091891ab7596ac3
78.1263 +4cd851ecfd2dbbaa2f99dac376f7bb40703fd0700d7499a7c24726bdc9bb
78.1264 +3b88c6a82e52686c1ee945d8825092bc81848a08722ac5a1d24353f95ec8
78.1265 +18f3fa487d9600318091b0ae9874b42bb3cb683a2518b18cc1bd86c6e5e8
78.1266 +3d37c14ef4fe0c77b03a3314995b1e7c1066b98c4375bd1fc5fadee1b024
78.1267 +7ece4f95a0f59978d543910deb2e5761632c74c508269c4e4b9e315bda02
78.1268 +975dc771fc30c8164b9df9172a4e571d8ca578cd2aaeaa0dd083e74cdc2e
78.1269 +d938b984b96d76a64b8c5fd12e63220bbac41e5bcd5ccb6b84bdbf6a02d5
78.1270 +934ac50c654c0853209a6758bcdf560e53566d78987484bb6672ebe93f22
78.1271 +dcba14e3acc132a2d9ae837adde04d8b16
78.1272 +0000000000000000000000000000000000000000000000000000000000000000
78.1273 +0000000000000000000000000000000000000000000000000000000000000000
78.1274 +0000000000000000000000000000000000000000000000000000000000000000
78.1275 +0000000000000000000000000000000000000000000000000000000000000000
78.1276 +0000000000000000000000000000000000000000000000000000000000000000
78.1277 +0000000000000000000000000000000000000000000000000000000000000000
78.1278 +0000000000000000000000000000000000000000000000000000000000000000
78.1279 +0000000000000000000000000000000000000000000000000000000000000000
78.1280 +cleartomark
78.1281 +%%BeginResource: procset Altsys_header 4 0
78.1282 +userdict begin /AltsysDict 245 dict def end
78.1283 +AltsysDict begin
78.1284 +/bdf{bind def}bind def
78.1285 +/xdf{exch def}bdf
78.1286 +/defed{where{pop true}{false}ifelse}bdf
78.1287 +/ndf{1 index where{pop pop pop}{dup xcheck{bind}if def}ifelse}bdf
78.1288 +/d{setdash}bdf
78.1289 +/h{closepath}bdf
78.1290 +/H{}bdf
78.1291 +/J{setlinecap}bdf
78.1292 +/j{setlinejoin}bdf
78.1293 +/M{setmiterlimit}bdf
78.1294 +/n{newpath}bdf
78.1295 +/N{newpath}bdf
78.1296 +/q{gsave}bdf
78.1297 +/Q{grestore}bdf
78.1298 +/w{setlinewidth}bdf
78.1299 +/sepdef{
78.1300 + dup where not
78.1301 + {
78.1302 +AltsysSepDict
78.1303 + }
78.1304 + if
78.1305 + 3 1 roll exch put
78.1306 +}bdf
78.1307 +/st{settransfer}bdf
78.1308 +/colorimage defed /_rci xdf
78.1309 +/_NXLevel2 defed {
78.1310 + _NXLevel2 not {
78.1311 +/colorimage where {
78.1312 +userdict eq {
78.1313 +/_rci false def
78.1314 +} if
78.1315 +} if
78.1316 + } if
78.1317 +} if
78.1318 +/md defed{
78.1319 + md type /dicttype eq {
78.1320 +/colorimage where {
78.1321 +md eq {
78.1322 +/_rci false def
78.1323 +}if
78.1324 +}if
78.1325 +/settransfer where {
78.1326 +md eq {
78.1327 +/st systemdict /settransfer get def
78.1328 +}if
78.1329 +}if
78.1330 + }if
78.1331 +}if
78.1332 +/setstrokeadjust defed
78.1333 +{
78.1334 + true setstrokeadjust
78.1335 + /C{curveto}bdf
78.1336 + /L{lineto}bdf
78.1337 + /m{moveto}bdf
78.1338 +}
78.1339 +{
78.1340 + /dr{transform .25 sub round .25 add
78.1341 +exch .25 sub round .25 add exch itransform}bdf
78.1342 + /C{dr curveto}bdf
78.1343 + /L{dr lineto}bdf
78.1344 + /m{dr moveto}bdf
78.1345 + /setstrokeadjust{pop}bdf
78.1346 +}ifelse
78.1347 +/rectstroke defed /xt xdf
78.1348 +xt {/yt save def} if
78.1349 +/privrectpath {
78.1350 + 4 -2 roll m
78.1351 + dtransform round exch round exch idtransform
78.1352 + 2 copy 0 lt exch 0 lt xor
78.1353 + {dup 0 exch rlineto exch 0 rlineto neg 0 exch rlineto}
78.1354 + {exch dup 0 rlineto exch 0 exch rlineto neg 0 rlineto}
78.1355 + ifelse
78.1356 + closepath
78.1357 +}bdf
78.1358 +/rectclip{newpath privrectpath clip newpath}def
78.1359 +/rectfill{gsave newpath privrectpath fill grestore}def
78.1360 +/rectstroke{gsave newpath privrectpath stroke grestore}def
78.1361 +xt {yt restore} if
78.1362 +/_fonthacksave false def
78.1363 +/currentpacking defed
78.1364 +{
78.1365 + /_bfh {/_fonthacksave currentpacking def false setpacking} bdf
78.1366 + /_efh {_fonthacksave setpacking} bdf
78.1367 +}
78.1368 +{
78.1369 + /_bfh {} bdf
78.1370 + /_efh {} bdf
78.1371 +}ifelse
78.1372 +/packedarray{array astore readonly}ndf
78.1373 +/`
78.1374 +{
78.1375 + false setoverprint
78.1376 +
78.1377 +
78.1378 + /-save0- save def
78.1379 + 5 index concat
78.1380 + pop
78.1381 + storerect left bottom width height rectclip
78.1382 + pop
78.1383 +
78.1384 + /dict_count countdictstack def
78.1385 + /op_count count 1 sub def
78.1386 + userdict begin
78.1387 +
78.1388 + /showpage {} def
78.1389 +
78.1390 + 0 setgray 0 setlinecap 1 setlinewidth
78.1391 + 0 setlinejoin 10 setmiterlimit [] 0 setdash newpath
78.1392 +
78.1393 +} bdf
78.1394 +/currentpacking defed{true setpacking}if
78.1395 +/min{2 copy gt{exch}if pop}bdf
78.1396 +/max{2 copy lt{exch}if pop}bdf
78.1397 +/xformfont { currentfont exch makefont setfont } bdf
78.1398 +/fhnumcolors 1
78.1399 + statusdict begin
78.1400 +/processcolors defed
78.1401 +{
78.1402 +pop processcolors
78.1403 +}
78.1404 +{
78.1405 +/deviceinfo defed {
78.1406 +deviceinfo /Colors known {
78.1407 +pop deviceinfo /Colors get
78.1408 +} if
78.1409 +} if
78.1410 +} ifelse
78.1411 + end
78.1412 +def
78.1413 +/printerRes
78.1414 + gsave
78.1415 + matrix defaultmatrix setmatrix
78.1416 + 72 72 dtransform
78.1417 + abs exch abs
78.1418 + max
78.1419 + grestore
78.1420 + def
78.1421 +/graycalcs
78.1422 +[
78.1423 + {Angle Frequency}
78.1424 + {GrayAngle GrayFrequency}
78.1425 + {0 Width Height matrix defaultmatrix idtransform
78.1426 +dup mul exch dup mul add sqrt 72 exch div}
78.1427 + {0 GrayWidth GrayHeight matrix defaultmatrix idtransform
78.1428 +dup mul exch dup mul add sqrt 72 exch div}
78.1429 +] def
78.1430 +/calcgraysteps {
78.1431 + forcemaxsteps
78.1432 + {
78.1433 +maxsteps
78.1434 + }
78.1435 + {
78.1436 +/currenthalftone defed
78.1437 +{currenthalftone /dicttype eq}{false}ifelse
78.1438 +{
78.1439 +currenthalftone begin
78.1440 +HalftoneType 4 le
78.1441 +{graycalcs HalftoneType 1 sub get exec}
78.1442 +{
78.1443 +HalftoneType 5 eq
78.1444 +{
78.1445 +Default begin
78.1446 +{graycalcs HalftoneType 1 sub get exec}
78.1447 +end
78.1448 +}
78.1449 +{0 60}
78.1450 +ifelse
78.1451 +}
78.1452 +ifelse
78.1453 +end
78.1454 +}
78.1455 +{
78.1456 +currentscreen pop exch
78.1457 +}
78.1458 +ifelse
78.1459 +
78.1460 +printerRes 300 max exch div exch
78.1461 +2 copy
78.1462 +sin mul round dup mul
78.1463 +3 1 roll
78.1464 +cos mul round dup mul
78.1465 +add 1 add
78.1466 +dup maxsteps gt {pop maxsteps} if
78.1467 + }
78.1468 + ifelse
78.1469 +} bdf
78.1470 +/nextrelease defed {
78.1471 + /languagelevel defed not {
78.1472 +/framebuffer defed {
78.1473 +0 40 string framebuffer 9 1 roll 8 {pop} repeat
78.1474 +dup 516 eq exch 520 eq or
78.1475 +{
78.1476 +/fhnumcolors 3 def
78.1477 +/currentscreen {60 0 {pop pop 1}}bdf
78.1478 +/calcgraysteps {maxsteps} bdf
78.1479 +}if
78.1480 +}if
78.1481 + }if
78.1482 +}if
78.1483 +fhnumcolors 1 ne {
78.1484 + /calcgraysteps {maxsteps} bdf
78.1485 +} if
78.1486 +/currentpagedevice defed {
78.1487 +
78.1488 +
78.1489 + currentpagedevice /PreRenderingEnhance known
78.1490 + {
78.1491 +currentpagedevice /PreRenderingEnhance get
78.1492 +{
78.1493 +/calcgraysteps
78.1494 +{
78.1495 +forcemaxsteps
78.1496 +{maxsteps}
78.1497 +{256 maxsteps min}
78.1498 +ifelse
78.1499 +} def
78.1500 +} if
78.1501 + } if
78.1502 +} if
78.1503 +/gradfrequency 144 def
78.1504 +printerRes 1000 lt {
78.1505 + /gradfrequency 72 def
78.1506 +} if
78.1507 +/adjnumsteps {
78.1508 +
78.1509 + dup dtransform abs exch abs max
78.1510 +
78.1511 + printerRes div
78.1512 +
78.1513 + gradfrequency mul
78.1514 + round
78.1515 + 5 max
78.1516 + min
78.1517 +}bdf
78.1518 +/goodsep {
78.1519 + spots exch get 4 get dup sepname eq exch (_vc_Registration) eq or
78.1520 +}bdf
78.1521 +/BeginGradation defed
78.1522 +{/bb{BeginGradation}bdf}
78.1523 +{/bb{}bdf}
78.1524 +ifelse
78.1525 +/EndGradation defed
78.1526 +{/eb{EndGradation}bdf}
78.1527 +{/eb{}bdf}
78.1528 +ifelse
78.1529 +/bottom -0 def
78.1530 +/delta -0 def
78.1531 +/frac -0 def
78.1532 +/height -0 def
78.1533 +/left -0 def
78.1534 +/numsteps1 -0 def
78.1535 +/radius -0 def
78.1536 +/right -0 def
78.1537 +/top -0 def
78.1538 +/width -0 def
78.1539 +/xt -0 def
78.1540 +/yt -0 def
78.1541 +/df currentflat def
78.1542 +/tempstr 1 string def
78.1543 +/clipflatness currentflat def
78.1544 +/inverted?
78.1545 + 0 currenttransfer exec .5 ge def
78.1546 +/tc1 [0 0 0 1] def
78.1547 +/tc2 [0 0 0 1] def
78.1548 +/storerect{/top xdf /right xdf /bottom xdf /left xdf
78.1549 +/width right left sub def /height top bottom sub def}bdf
78.1550 +/concatprocs{
78.1551 + systemdict /packedarray known
78.1552 + {dup type /packedarraytype eq 2 index type /packedarraytype eq or}{false}ifelse
78.1553 + {
78.1554 +/proc2 exch cvlit def /proc1 exch cvlit def
78.1555 +proc1 aload pop proc2 aload pop
78.1556 +proc1 length proc2 length add packedarray cvx
78.1557 + }
78.1558 + {
78.1559 +/proc2 exch cvlit def /proc1 exch cvlit def
78.1560 +/newproc proc1 length proc2 length add array def
78.1561 +newproc 0 proc1 putinterval newproc proc1 length proc2 putinterval
78.1562 +newproc cvx
78.1563 + }ifelse
78.1564 +}bdf
78.1565 +/i{dup 0 eq
78.1566 + {pop df dup}
78.1567 + {dup} ifelse
78.1568 + /clipflatness xdf setflat
78.1569 +}bdf
78.1570 +version cvr 38.0 le
78.1571 +{/setrgbcolor{
78.1572 +currenttransfer exec 3 1 roll
78.1573 +currenttransfer exec 3 1 roll
78.1574 +currenttransfer exec 3 1 roll
78.1575 +setrgbcolor}bdf}if
78.1576 +/vms {/vmsv save def} bdf
78.1577 +/vmr {vmsv restore} bdf
78.1578 +/vmrs{vmsv restore /vmsv save def}bdf
78.1579 +/eomode{
78.1580 + {/filler /eofill load def /clipper /eoclip load def}
78.1581 + {/filler /fill load def /clipper /clip load def}
78.1582 + ifelse
78.1583 +}bdf
78.1584 +/normtaper{}bdf
78.1585 +/logtaper{9 mul 1 add log}bdf
78.1586 +/CD{
78.1587 + /NF exch def
78.1588 + {
78.1589 +exch dup
78.1590 +/FID ne 1 index/UniqueID ne and
78.1591 +{exch NF 3 1 roll put}
78.1592 +{pop pop}
78.1593 +ifelse
78.1594 + }forall
78.1595 + NF
78.1596 +}bdf
78.1597 +/MN{
78.1598 + 1 index length
78.1599 + /Len exch def
78.1600 + dup length Len add
78.1601 + string dup
78.1602 + Len
78.1603 + 4 -1 roll
78.1604 + putinterval
78.1605 + dup
78.1606 + 0
78.1607 + 4 -1 roll
78.1608 + putinterval
78.1609 +}bdf
78.1610 +/RC{4 -1 roll /ourvec xdf 256 string cvs(|______)anchorsearch
78.1611 + {1 index MN cvn/NewN exch def cvn
78.1612 + findfont dup maxlength dict CD dup/FontName NewN put dup
78.1613 + /Encoding ourvec put NewN exch definefont pop}{pop}ifelse}bdf
78.1614 +/RF{
78.1615 + dup
78.1616 + FontDirectory exch
78.1617 + known
78.1618 + {pop 3 -1 roll pop}
78.1619 + {RC}
78.1620 + ifelse
78.1621 +}bdf
78.1622 +/FF{dup 256 string cvs(|______)exch MN cvn dup FontDirectory exch known
78.1623 + {exch pop findfont 3 -1 roll pop}
78.1624 + {pop dup findfont dup maxlength dict CD dup dup
78.1625 + /Encoding exch /Encoding get 256 array copy 7 -1 roll
78.1626 + {3 -1 roll dup 4 -2 roll put}forall put definefont}
78.1627 + ifelse}bdf
78.1628 +/RFJ{
78.1629 + dup
78.1630 + FontDirectory exch
78.1631 + known
78.1632 + {pop 3 -1 roll pop
78.1633 + FontDirectory /Ryumin-Light-83pv-RKSJ-H known
78.1634 + {pop pop /Ryumin-Light-83pv-RKSJ-H dup}if
78.1635 + }
78.1636 + {RC}
78.1637 + ifelse
78.1638 +}bdf
78.1639 +/FFJ{dup 256 string cvs(|______)exch MN cvn dup FontDirectory exch known
78.1640 + {exch pop findfont 3 -1 roll pop}
78.1641 + {pop
78.1642 +dup FontDirectory exch known not
78.1643 + {FontDirectory /Ryumin-Light-83pv-RKSJ-H known
78.1644 +{pop /Ryumin-Light-83pv-RKSJ-H}if
78.1645 + }if
78.1646 + dup findfont dup maxlength dict CD dup dup
78.1647 + /Encoding exch /Encoding get 256 array copy 7 -1 roll
78.1648 + {3 -1 roll dup 4 -2 roll put}forall put definefont}
78.1649 + ifelse}bdf
78.1650 +/fps{
78.1651 + currentflat
78.1652 + exch
78.1653 + dup 0 le{pop 1}if
78.1654 + {
78.1655 +dup setflat 3 index stopped
78.1656 +{1.3 mul dup 3 index gt{pop setflat pop pop stop}if}
78.1657 +{exit}
78.1658 +ifelse
78.1659 + }loop
78.1660 + pop setflat pop pop
78.1661 +}bdf
78.1662 +/fp{100 currentflat fps}bdf
78.1663 +/clipper{clip}bdf
78.1664 +/W{/clipper load 100 clipflatness dup setflat fps}bdf
78.1665 +userdict begin /BDFontDict 29 dict def end
78.1666 +BDFontDict begin
78.1667 +/bu{}def
78.1668 +/bn{}def
78.1669 +/setTxMode{av 70 ge{pop}if pop}def
78.1670 +/gm{m}def
78.1671 +/show{pop}def
78.1672 +/gr{pop}def
78.1673 +/fnt{pop pop pop}def
78.1674 +/fs{pop}def
78.1675 +/fz{pop}def
78.1676 +/lin{pop pop}def
78.1677 +/:M {pop pop} def
78.1678 +/sf {pop} def
78.1679 +/S {pop} def
78.1680 +/@b {pop pop pop pop pop pop pop pop} def
78.1681 +/_bdsave /save load def
78.1682 +/_bdrestore /restore load def
78.1683 +/save { dup /fontsave eq {null} {_bdsave} ifelse } def
78.1684 +/restore { dup null eq { pop } { _bdrestore } ifelse } def
78.1685 +/fontsave null def
78.1686 +end
78.1687 +/MacVec 256 array def
78.1688 +MacVec 0 /Helvetica findfont
78.1689 +/Encoding get 0 128 getinterval putinterval
78.1690 +MacVec 127 /DEL put MacVec 16#27 /quotesingle put MacVec 16#60 /grave put
78.1691 +/NUL/SOH/STX/ETX/EOT/ENQ/ACK/BEL/BS/HT/LF/VT/FF/CR/SO/SI
78.1692 +/DLE/DC1/DC2/DC3/DC4/NAK/SYN/ETB/CAN/EM/SUB/ESC/FS/GS/RS/US
78.1693 +MacVec 0 32 getinterval astore pop
78.1694 +/Adieresis/Aring/Ccedilla/Eacute/Ntilde/Odieresis/Udieresis/aacute
78.1695 +/agrave/acircumflex/adieresis/atilde/aring/ccedilla/eacute/egrave
78.1696 +/ecircumflex/edieresis/iacute/igrave/icircumflex/idieresis/ntilde/oacute
78.1697 +/ograve/ocircumflex/odieresis/otilde/uacute/ugrave/ucircumflex/udieresis
78.1698 +/dagger/degree/cent/sterling/section/bullet/paragraph/germandbls
78.1699 +/registered/copyright/trademark/acute/dieresis/notequal/AE/Oslash
78.1700 +/infinity/plusminus/lessequal/greaterequal/yen/mu/partialdiff/summation
78.1701 +/product/pi/integral/ordfeminine/ordmasculine/Omega/ae/oslash
78.1702 +/questiondown/exclamdown/logicalnot/radical/florin/approxequal/Delta/guillemotleft
78.1703 +/guillemotright/ellipsis/nbspace/Agrave/Atilde/Otilde/OE/oe
78.1704 +/endash/emdash/quotedblleft/quotedblright/quoteleft/quoteright/divide/lozenge
78.1705 +/ydieresis/Ydieresis/fraction/currency/guilsinglleft/guilsinglright/fi/fl
78.1706 +/daggerdbl/periodcentered/quotesinglbase/quotedblbase
78.1707 +/perthousand/Acircumflex/Ecircumflex/Aacute
78.1708 +/Edieresis/Egrave/Iacute/Icircumflex/Idieresis/Igrave/Oacute/Ocircumflex
78.1709 +/apple/Ograve/Uacute/Ucircumflex/Ugrave/dotlessi/circumflex/tilde
78.1710 +/macron/breve/dotaccent/ring/cedilla/hungarumlaut/ogonek/caron
78.1711 +MacVec 128 128 getinterval astore pop
78.1712 +end %. AltsysDict
78.1713 +%%EndResource
78.1714 +%%EndProlog
78.1715 +%%BeginSetup
78.1716 +AltsysDict begin
78.1717 +_bfh
78.1718 +%%IncludeResource: font Symbol
78.1719 +_efh
78.1720 +0 dict dup begin
78.1721 +end
78.1722 +/f0 /Symbol FF def
78.1723 +_bfh
78.1724 +%%IncludeResource: font ZapfHumanist601BT-Bold
78.1725 +_efh
78.1726 +0 dict dup begin
78.1727 +end
78.1728 +/f1 /ZapfHumanist601BT-Bold FF def
78.1729 +end %. AltsysDict
78.1730 +%%EndSetup
78.1731 +AltsysDict begin
78.1732 +/onlyk4{false}ndf
78.1733 +/ccmyk{dup 5 -1 roll sub 0 max exch}ndf
78.1734 +/cmyk2gray{
78.1735 + 4 -1 roll 0.3 mul 4 -1 roll 0.59 mul 4 -1 roll 0.11 mul
78.1736 + add add add 1 min neg 1 add
78.1737 +}bdf
78.1738 +/setcmykcolor{1 exch sub ccmyk ccmyk ccmyk pop setrgbcolor}ndf
78.1739 +/maxcolor {
78.1740 + max max max
78.1741 +} ndf
78.1742 +/maxspot {
78.1743 + pop
78.1744 +} ndf
78.1745 +/setcmykcoloroverprint{4{dup -1 eq{pop 0}if 4 1 roll}repeat setcmykcolor}ndf
78.1746 +/findcmykcustomcolor{5 packedarray}ndf
78.1747 +/setcustomcolor{exch aload pop pop 4{4 index mul 4 1 roll}repeat setcmykcolor pop}ndf
78.1748 +/setseparationgray{setgray}ndf
78.1749 +/setoverprint{pop}ndf
78.1750 +/currentoverprint false ndf
78.1751 +/cmykbufs2gray{
78.1752 + 0 1 2 index length 1 sub
78.1753 + {
78.1754 +4 index 1 index get 0.3 mul
78.1755 +4 index 2 index get 0.59 mul
78.1756 +4 index 3 index get 0.11 mul
78.1757 +4 index 4 index get
78.1758 +add add add cvi 255 min
78.1759 +255 exch sub
78.1760 +2 index 3 1 roll put
78.1761 + }for
78.1762 + 4 1 roll pop pop pop
78.1763 +}bdf
78.1764 +/colorimage{
78.1765 + pop pop
78.1766 + [
78.1767 +5 -1 roll/exec cvx
78.1768 +6 -1 roll/exec cvx
78.1769 +7 -1 roll/exec cvx
78.1770 +8 -1 roll/exec cvx
78.1771 +/cmykbufs2gray cvx
78.1772 + ]cvx
78.1773 + image
78.1774 +}
78.1775 +%. version 47.1 on Linotronic of Postscript defines colorimage incorrectly (rgb model only)
78.1776 +version cvr 47.1 le
78.1777 +statusdict /product get (Lino) anchorsearch{pop pop true}{pop false}ifelse
78.1778 +and{userdict begin bdf end}{ndf}ifelse
78.1779 +fhnumcolors 1 ne {/yt save def} if
78.1780 +/customcolorimage{
78.1781 + aload pop
78.1782 + (_vc_Registration) eq
78.1783 + {
78.1784 +pop pop pop pop separationimage
78.1785 + }
78.1786 + {
78.1787 +/ik xdf /iy xdf /im xdf /ic xdf
78.1788 +ic im iy ik cmyk2gray /xt xdf
78.1789 +currenttransfer
78.1790 +{dup 1.0 exch sub xt mul add}concatprocs
78.1791 +st
78.1792 +image
78.1793 + }
78.1794 + ifelse
78.1795 +}ndf
78.1796 +fhnumcolors 1 ne {yt restore} if
78.1797 +fhnumcolors 3 ne {/yt save def} if
78.1798 +/customcolorimage{
78.1799 + aload pop
78.1800 + (_vc_Registration) eq
78.1801 + {
78.1802 +pop pop pop pop separationimage
78.1803 + }
78.1804 + {
78.1805 +/ik xdf /iy xdf /im xdf /ic xdf
78.1806 +1.0 dup ic ik add min sub
78.1807 +1.0 dup im ik add min sub
78.1808 +1.0 dup iy ik add min sub
78.1809 +/ic xdf /iy xdf /im xdf
78.1810 +currentcolortransfer
78.1811 +4 1 roll
78.1812 +{dup 1.0 exch sub ic mul add}concatprocs 4 1 roll
78.1813 +{dup 1.0 exch sub iy mul add}concatprocs 4 1 roll
78.1814 +{dup 1.0 exch sub im mul add}concatprocs 4 1 roll
78.1815 +setcolortransfer
78.1816 +{/dummy xdf dummy}concatprocs{dummy}{dummy}true 3 colorimage
78.1817 + }
78.1818 + ifelse
78.1819 +}ndf
78.1820 +fhnumcolors 3 ne {yt restore} if
78.1821 +fhnumcolors 4 ne {/yt save def} if
78.1822 +/customcolorimage{
78.1823 + aload pop
78.1824 + (_vc_Registration) eq
78.1825 + {
78.1826 +pop pop pop pop separationimage
78.1827 + }
78.1828 + {
78.1829 +/ik xdf /iy xdf /im xdf /ic xdf
78.1830 +currentcolortransfer
78.1831 +{1.0 exch sub ik mul ik sub 1 add}concatprocs 4 1 roll
78.1832 +{1.0 exch sub iy mul iy sub 1 add}concatprocs 4 1 roll
78.1833 +{1.0 exch sub im mul im sub 1 add}concatprocs 4 1 roll
78.1834 +{1.0 exch sub ic mul ic sub 1 add}concatprocs 4 1 roll
78.1835 +setcolortransfer
78.1836 +{/dummy xdf dummy}concatprocs{dummy}{dummy}{dummy}
78.1837 +true 4 colorimage
78.1838 + }
78.1839 + ifelse
78.1840 +}ndf
78.1841 +fhnumcolors 4 ne {yt restore} if
78.1842 +/separationimage{image}ndf
78.1843 +/newcmykcustomcolor{6 packedarray}ndf
78.1844 +/inkoverprint false ndf
78.1845 +/setinkoverprint{pop}ndf
78.1846 +/setspotcolor {
78.1847 + spots exch get
78.1848 + dup 4 get (_vc_Registration) eq
78.1849 + {pop 1 exch sub setseparationgray}
78.1850 + {0 5 getinterval exch setcustomcolor}
78.1851 + ifelse
78.1852 +}ndf
78.1853 +/currentcolortransfer{currenttransfer dup dup dup}ndf
78.1854 +/setcolortransfer{st pop pop pop}ndf
78.1855 +/fas{}ndf
78.1856 +/sas{}ndf
78.1857 +/fhsetspreadsize{pop}ndf
78.1858 +/filler{fill}bdf
78.1859 +/F{gsave {filler}fp grestore}bdf
78.1860 +/f{closepath F}bdf
78.1861 +/S{gsave {stroke}fp grestore}bdf
78.1862 +/s{closepath S}bdf
78.1863 +/bc4 [0 0 0 0] def
78.1864 +/_lfp4 {
78.1865 + /iosv inkoverprint def
78.1866 + /cosv currentoverprint def
78.1867 + /yt xdf
78.1868 + /xt xdf
78.1869 + /ang xdf
78.1870 + storerect
78.1871 + /taperfcn xdf
78.1872 + /k2 xdf /y2 xdf /m2 xdf /c2 xdf
78.1873 + /k1 xdf /y1 xdf /m1 xdf /c1 xdf
78.1874 + c1 c2 sub abs
78.1875 + m1 m2 sub abs
78.1876 + y1 y2 sub abs
78.1877 + k1 k2 sub abs
78.1878 + maxcolor
78.1879 + calcgraysteps mul abs round
78.1880 + height abs adjnumsteps
78.1881 + dup 2 lt {pop 1} if
78.1882 + 1 sub /numsteps1 xdf
78.1883 + currentflat mark
78.1884 + currentflat clipflatness
78.1885 + /delta top bottom sub numsteps1 1 add div def
78.1886 + /right right left sub def
78.1887 + /botsv top delta sub def
78.1888 + {
78.1889 +{
78.1890 +W
78.1891 +xt yt translate
78.1892 +ang rotate
78.1893 +xt neg yt neg translate
78.1894 +dup setflat
78.1895 +/bottom botsv def
78.1896 +0 1 numsteps1
78.1897 +{
78.1898 +numsteps1 dup 0 eq {pop 0.5 } { div } ifelse
78.1899 +taperfcn /frac xdf
78.1900 +bc4 0 c2 c1 sub frac mul c1 add put
78.1901 +bc4 1 m2 m1 sub frac mul m1 add put
78.1902 +bc4 2 y2 y1 sub frac mul y1 add put
78.1903 +bc4 3 k2 k1 sub frac mul k1 add put
78.1904 +bc4 vc
78.1905 +1 index setflat
78.1906 +{
78.1907 +mark {newpath left bottom right delta rectfill}stopped
78.1908 +{cleartomark exch 1.3 mul dup setflat exch 2 copy gt{stop}if}
78.1909 +{cleartomark exit}ifelse
78.1910 +}loop
78.1911 +/bottom bottom delta sub def
78.1912 +}for
78.1913 +}
78.1914 +gsave stopped grestore
78.1915 +{exch pop 2 index exch 1.3 mul dup 100 gt{cleartomark setflat stop}if}
78.1916 +{exit}ifelse
78.1917 + }loop
78.1918 + cleartomark setflat
78.1919 + iosv setinkoverprint
78.1920 + cosv setoverprint
78.1921 +}bdf
78.1922 +/bcs [0 0] def
78.1923 +/_lfs4 {
78.1924 + /iosv inkoverprint def
78.1925 + /cosv currentoverprint def
78.1926 + /yt xdf
78.1927 + /xt xdf
78.1928 + /ang xdf
78.1929 + storerect
78.1930 + /taperfcn xdf
78.1931 + /tint2 xdf
78.1932 + /tint1 xdf
78.1933 + bcs exch 1 exch put
78.1934 + tint1 tint2 sub abs
78.1935 + bcs 1 get maxspot
78.1936 + calcgraysteps mul abs round
78.1937 + height abs adjnumsteps
78.1938 + dup 2 lt {pop 2} if
78.1939 + 1 sub /numsteps1 xdf
78.1940 + currentflat mark
78.1941 + currentflat clipflatness
78.1942 + /delta top bottom sub numsteps1 1 add div def
78.1943 + /right right left sub def
78.1944 + /botsv top delta sub def
78.1945 + {
78.1946 +{
78.1947 +W
78.1948 +xt yt translate
78.1949 +ang rotate
78.1950 +xt neg yt neg translate
78.1951 +dup setflat
78.1952 +/bottom botsv def
78.1953 +0 1 numsteps1
78.1954 +{
78.1955 +numsteps1 div taperfcn /frac xdf
78.1956 +bcs 0
78.1957 +1.0 tint2 tint1 sub frac mul tint1 add sub
78.1958 +put bcs vc
78.1959 +1 index setflat
78.1960 +{
78.1961 +mark {newpath left bottom right delta rectfill}stopped
78.1962 +{cleartomark exch 1.3 mul dup setflat exch 2 copy gt{stop}if}
78.1963 +{cleartomark exit}ifelse
78.1964 +}loop
78.1965 +/bottom bottom delta sub def
78.1966 +}for
78.1967 +}
78.1968 +gsave stopped grestore
78.1969 +{exch pop 2 index exch 1.3 mul dup 100 gt{cleartomark setflat stop}if}
78.1970 +{exit}ifelse
78.1971 + }loop
78.1972 + cleartomark setflat
78.1973 + iosv setinkoverprint
78.1974 + cosv setoverprint
78.1975 +}bdf
78.1976 +/_rfs4 {
78.1977 + /iosv inkoverprint def
78.1978 + /cosv currentoverprint def
78.1979 + /tint2 xdf
78.1980 + /tint1 xdf
78.1981 + bcs exch 1 exch put
78.1982 + /radius xdf
78.1983 + /yt xdf
78.1984 + /xt xdf
78.1985 + tint1 tint2 sub abs
78.1986 + bcs 1 get maxspot
78.1987 + calcgraysteps mul abs round
78.1988 + radius abs adjnumsteps
78.1989 + dup 2 lt {pop 2} if
78.1990 + 1 sub /numsteps1 xdf
78.1991 + radius numsteps1 div 2 div /halfstep xdf
78.1992 + currentflat mark
78.1993 + currentflat clipflatness
78.1994 + {
78.1995 +{
78.1996 +dup setflat
78.1997 +W
78.1998 +0 1 numsteps1
78.1999 +{
78.2000 +dup /radindex xdf
78.2001 +numsteps1 div /frac xdf
78.2002 +bcs 0
78.2003 +tint2 tint1 sub frac mul tint1 add
78.2004 +put bcs vc
78.2005 +1 index setflat
78.2006 +{
78.2007 +newpath mark xt yt radius 1 frac sub mul halfstep add 0 360
78.2008 +{ arc
78.2009 +radindex numsteps1 ne
78.2010 +{
78.2011 +xt yt
78.2012 +radindex 1 add numsteps1
78.2013 +div 1 exch sub
78.2014 +radius mul halfstep add
78.2015 +dup xt add yt moveto
78.2016 +360 0 arcn
78.2017 +} if
78.2018 +fill
78.2019 +}stopped
78.2020 +{cleartomark exch 1.3 mul dup setflat exch 2 copy gt{stop}if}
78.2021 +{cleartomark exit}ifelse
78.2022 +}loop
78.2023 +}for
78.2024 +}
78.2025 +gsave stopped grestore
78.2026 +{exch pop 2 index exch 1.3 mul dup 100 gt{cleartomark setflat stop}if}
78.2027 +{exit}ifelse
78.2028 + }loop
78.2029 + cleartomark setflat
78.2030 + iosv setinkoverprint
78.2031 + cosv setoverprint
78.2032 +}bdf
78.2033 +/_rfp4 {
78.2034 + /iosv inkoverprint def
78.2035 + /cosv currentoverprint def
78.2036 + /k2 xdf /y2 xdf /m2 xdf /c2 xdf
78.2037 + /k1 xdf /y1 xdf /m1 xdf /c1 xdf
78.2038 + /radius xdf
78.2039 + /yt xdf
78.2040 + /xt xdf
78.2041 + c1 c2 sub abs
78.2042 + m1 m2 sub abs
78.2043 + y1 y2 sub abs
78.2044 + k1 k2 sub abs
78.2045 + maxcolor
78.2046 + calcgraysteps mul abs round
78.2047 + radius abs adjnumsteps
78.2048 + dup 2 lt {pop 1} if
78.2049 + 1 sub /numsteps1 xdf
78.2050 + radius numsteps1 dup 0 eq {pop} {div} ifelse
78.2051 + 2 div /halfstep xdf
78.2052 + currentflat mark
78.2053 + currentflat clipflatness
78.2054 + {
78.2055 +{
78.2056 +dup setflat
78.2057 +W
78.2058 +0 1 numsteps1
78.2059 +{
78.2060 +dup /radindex xdf
78.2061 +numsteps1 dup 0 eq {pop 0.5 } { div } ifelse
78.2062 +/frac xdf
78.2063 +bc4 0 c2 c1 sub frac mul c1 add put
78.2064 +bc4 1 m2 m1 sub frac mul m1 add put
78.2065 +bc4 2 y2 y1 sub frac mul y1 add put
78.2066 +bc4 3 k2 k1 sub frac mul k1 add put
78.2067 +bc4 vc
78.2068 +1 index setflat
78.2069 +{
78.2070 +newpath mark xt yt radius 1 frac sub mul halfstep add 0 360
78.2071 +{ arc
78.2072 +radindex numsteps1 ne
78.2073 +{
78.2074 +xt yt
78.2075 +radindex 1 add
78.2076 +numsteps1 dup 0 eq {pop} {div} ifelse
78.2077 +1 exch sub
78.2078 +radius mul halfstep add
78.2079 +dup xt add yt moveto
78.2080 +360 0 arcn
78.2081 +} if
78.2082 +fill
78.2083 +}stopped
78.2084 +{cleartomark exch 1.3 mul dup setflat exch 2 copy gt{stop}if}
78.2085 +{cleartomark exit}ifelse
78.2086 +}loop
78.2087 +}for
78.2088 +}
78.2089 +gsave stopped grestore
78.2090 +{exch pop 2 index exch 1.3 mul dup 100 gt{cleartomark setflat stop}if}
78.2091 +{exit}ifelse
78.2092 + }loop
78.2093 + cleartomark setflat
78.2094 + iosv setinkoverprint
78.2095 + cosv setoverprint
78.2096 +}bdf
78.2097 +/lfp4{_lfp4}ndf
78.2098 +/lfs4{_lfs4}ndf
78.2099 +/rfs4{_rfs4}ndf
78.2100 +/rfp4{_rfp4}ndf
78.2101 +/cvc [0 0 0 1] def
78.2102 +/vc{
78.2103 + AltsysDict /cvc 2 index put
78.2104 + aload length 4 eq
78.2105 + {setcmykcolor}
78.2106 + {setspotcolor}
78.2107 + ifelse
78.2108 +}bdf
78.2109 +/origmtx matrix currentmatrix def
78.2110 +/ImMatrix matrix currentmatrix def
78.2111 +0 setseparationgray
78.2112 +/imgr {1692 1570.1102 2287.2756 2412 } def
78.2113 +/bleed 0 def
78.2114 +/clpr {1692 1570.1102 2287.2756 2412 } def
78.2115 +/xs 1 def
78.2116 +/ys 1 def
78.2117 +/botx 0 def
78.2118 +/overlap 0 def
78.2119 +/wdist 18 def
78.2120 +0 2 mul fhsetspreadsize
78.2121 +0 0 ne {/df 0 def /clipflatness 0 def} if
78.2122 +/maxsteps 256 def
78.2123 +/forcemaxsteps false def
78.2124 +vms
78.2125 +-1845 -1956 translate
78.2126 +/currentpacking defed{false setpacking}if
78.2127 +/spots[
78.2128 +1 0 0 0 (Process Cyan) false newcmykcustomcolor
78.2129 +0 1 0 0 (Process Magenta) false newcmykcustomcolor
78.2130 +0 0 1 0 (Process Yellow) false newcmykcustomcolor
78.2131 +0 0 0 1 (Process Black) false newcmykcustomcolor
78.2132 +]def
78.2133 +/textopf false def
78.2134 +/curtextmtx{}def
78.2135 +/otw .25 def
78.2136 +/msf{dup/curtextmtx xdf makefont setfont}bdf
78.2137 +/makesetfont/msf load def
78.2138 +/curtextheight{.707104 .707104 curtextmtx dtransform
78.2139 + dup mul exch dup mul add sqrt}bdf
78.2140 +/ta2{
78.2141 +tempstr 2 index gsave exec grestore
78.2142 +cwidth cheight rmoveto
78.2143 +4 index eq{5 index 5 index rmoveto}if
78.2144 +2 index 2 index rmoveto
78.2145 +}bdf
78.2146 +/ta{exch systemdict/cshow known
78.2147 +{{/cheight xdf/cwidth xdf tempstr 0 2 index put ta2}exch cshow}
78.2148 +{{tempstr 0 2 index put tempstr stringwidth/cheight xdf/cwidth xdf ta2}forall}
78.2149 +ifelse 6{pop}repeat}bdf
78.2150 +/sts{/textopf currentoverprint def vc setoverprint
78.2151 +/ts{awidthshow}def exec textopf setoverprint}bdf
78.2152 +/stol{/xt currentlinewidth def
78.2153 + setlinewidth vc newpath
78.2154 + /ts{{false charpath stroke}ta}def exec
78.2155 + xt setlinewidth}bdf
78.2156 +
78.2157 +/strk{/textopf currentoverprint def vc setoverprint
78.2158 + /ts{{false charpath stroke}ta}def exec
78.2159 + textopf setoverprint
78.2160 + }bdf
78.2161 +n
78.2162 +[] 0 d
78.2163 +3.863708 M
78.2164 +1 w
78.2165 +0 j
78.2166 +0 J
78.2167 +false setoverprint
78.2168 +0 i
78.2169 +false eomode
78.2170 +[0 0 0 1] vc
78.2171 +vms
78.2172 +%white border -- disabled
78.2173 +%1845.2293 2127.8588 m
78.2174 +%2045.9437 2127.8588 L
78.2175 +%2045.9437 1956.1412 L
78.2176 +%1845.2293 1956.1412 L
78.2177 +%1845.2293 2127.8588 L
78.2178 +%0.1417 w
78.2179 +%2 J
78.2180 +%2 M
78.2181 +%[0 0 0 0] vc
78.2182 +%s
78.2183 +n
78.2184 +1950.8 2097.2 m
78.2185 +1958.8 2092.5 1967.3 2089 1975.5 2084.9 C
78.2186 +1976.7 2083.5 1976.1 2081.5 1976.7 2079.9 C
78.2187 +1979.6 2081.1 1981.6 2086.8 1985.3 2084 C
78.2188 +1993.4 2079.3 2001.8 2075.8 2010 2071.7 C
78.2189 +2010.5 2071.5 2010.5 2071.1 2010.8 2070.8 C
78.2190 +2011.2 2064.3 2010.9 2057.5 2011 2050.8 C
78.2191 +2015.8 2046.9 2022.2 2046.2 2026.6 2041.7 C
78.2192 +2026.5 2032.5 2026.8 2022.9 2026.4 2014.1 C
78.2193 +2020.4 2008.3 2015 2002.4 2008.8 1997.1 C
78.2194 +2003.8 1996.8 2000.7 2001.2 1996.1 2002.1 C
78.2195 +1995.2 1996.4 1996.9 1990.5 1995.6 1984.8 C
78.2196 +1989.9 1979 1984.5 1973.9 1978.8 1967.8 C
78.2197 +1977.7 1968.6 1976 1967.6 1974.5 1968.3 C
78.2198 +1967.4 1972.5 1960.1 1976.1 1952.7 1979.3 C
78.2199 +1946.8 1976.3 1943.4 1970.7 1938.5 1966.1 C
78.2200 +1933.9 1966.5 1929.4 1968.8 1925.1 1970.7 C
78.2201 +1917.2 1978.2 1906 1977.9 1897.2 1983.4 C
78.2202 +1893.2 1985.6 1889.4 1988.6 1885 1990.1 C
78.2203 +1884.6 1990.6 1883.9 1991 1883.8 1991.6 C
78.2204 +1883.7 2000.4 1884 2009.9 1883.6 2018.9 C
78.2205 +1887.7 2024 1893.2 2028.8 1898 2033.8 C
78.2206 +1899.1 2035.5 1900.9 2036.8 1902.5 2037.9 C
78.2207 +1903.9 2037.3 1905.2 2036.6 1906.4 2035.5 C
78.2208 +1906.3 2039.7 1906.5 2044.6 1906.1 2048.9 C
78.2209 +1906.3 2049.6 1906.7 2050.2 1907.1 2050.8 C
78.2210 +1913.4 2056 1918.5 2062.7 1924.8 2068.1 C
78.2211 +1926.6 2067.9 1928 2066.9 1929.4 2066 C
78.2212 +1930.2 2071 1927.7 2077.1 1930.6 2081.6 C
78.2213 +1936.6 2086.9 1941.5 2092.9 1947.9 2097.9 C
78.2214 +1949 2098.1 1949.9 2097.5 1950.8 2097.2 C
78.2215 +[0 0 0 0.18] vc
78.2216 +f
78.2217 +0.4 w
78.2218 +S
78.2219 +n
78.2220 +1975.2 2084.7 m
78.2221 +1976.6 2083.4 1975.7 2081.1 1976 2079.4 C
78.2222 +1979.3 2079.5 1980.9 2086.2 1984.8 2084 C
78.2223 +1992.9 2078.9 2001.7 2075.6 2010 2071.2 C
78.2224 +2011 2064.6 2010.2 2057.3 2010.8 2050.6 C
78.2225 +2015.4 2046.9 2021.1 2045.9 2025.9 2042.4 C
78.2226 +2026.5 2033.2 2026.8 2022.9 2025.6 2013.9 C
78.2227 +2020.5 2008.1 2014.5 2003.1 2009.3 1997.6 C
78.2228 +2004.1 1996.7 2000.7 2001.6 1995.9 2002.6 C
78.2229 +1995.2 1996.7 1996.3 1990.2 1994.9 1984.6 C
78.2230 +1989.8 1978.7 1983.6 1973.7 1978.4 1968 C
78.2231 +1977.3 1969.3 1976 1967.6 1974.8 1968.5 C
78.2232 +1967.7 1972.7 1960.4 1976.3 1952.9 1979.6 C
78.2233 +1946.5 1976.9 1943.1 1970.5 1937.8 1966.1 C
78.2234 +1928.3 1968.2 1920.6 1974.8 1911.6 1978.4 C
78.2235 +1901.9 1979.7 1893.9 1986.6 1885 1990.6 C
78.2236 +1884.3 1991 1884.3 1991.7 1884 1992.3 C
78.2237 +1884.5 2001 1884.2 2011 1884.3 2019.9 C
78.2238 +1890.9 2025.3 1895.9 2031.9 1902.3 2037.4 C
78.2239 +1904.2 2037.9 1905.6 2034.2 1906.8 2035.7 C
78.2240 +1907.4 2040.9 1905.7 2046.1 1907.3 2050.8 C
78.2241 +1913.6 2056.2 1919.2 2062.6 1925.1 2067.9 C
78.2242 +1926.9 2067.8 1928 2066.3 1929.6 2065.7 C
78.2243 +1929.9 2070.5 1929.2 2076 1930.1 2080.8 C
78.2244 +1936.5 2086.1 1941.6 2092.8 1948.4 2097.6 C
78.2245 +1957.3 2093.3 1966.2 2088.8 1975.2 2084.7 C
78.2246 +[0 0 0 0] vc
78.2247 +f
78.2248 +S
78.2249 +n
78.2250 +1954.8 2093.8 m
78.2251 +1961.6 2090.5 1968.2 2087 1975 2084 C
78.2252 +1975 2082.8 1975.6 2080.9 1974.8 2080.6 C
78.2253 +1974.3 2075.2 1974.6 2069.6 1974.5 2064 C
78.2254 +1977.5 2059.7 1984.5 2060 1988.9 2056.4 C
78.2255 +1989.5 2055.5 1990.5 2055.3 1990.8 2054.4 C
78.2256 +1991.1 2045.7 1991.4 2036.1 1990.6 2027.8 C
78.2257 +1990.7 2026.6 1992 2027.3 1992.8 2027.1 C
78.2258 +1997 2032.4 2002.6 2037.8 2007.6 2042.2 C
78.2259 +2008.7 2042.3 2007.8 2040.6 2007.4 2040 C
78.2260 +2002.3 2035.6 1997.5 2030 1992.8 2025.2 C
78.2261 +1991.6 2024.7 1990.8 2024.9 1990.1 2025.4 C
78.2262 +1989.4 2024.9 1988.1 2025.2 1987.2 2024.4 C
78.2263 +1987.1 2025.8 1988.3 2026.5 1989.4 2026.8 C
78.2264 +1989.4 2026.6 1989.3 2026.2 1989.6 2026.1 C
78.2265 +1989.9 2026.2 1989.9 2026.6 1989.9 2026.8 C
78.2266 +1989.8 2026.6 1990 2026.5 1990.1 2026.4 C
78.2267 +1990.2 2027 1991.1 2028.3 1990.1 2028 C
78.2268 +1989.9 2037.9 1990.5 2044.1 1989.6 2054.2 C
78.2269 +1985.9 2058 1979.7 2057.4 1976 2061.2 C
78.2270 +1974.5 2061.6 1975.2 2059.9 1974.5 2059.5 C
78.2271 +1973.9 2058 1975.6 2057.8 1975 2056.6 C
78.2272 +1974.5 2057.1 1974.6 2055.3 1973.6 2055.9 C
78.2273 +1971.9 2059.3 1974.7 2062.1 1973.1 2065.5 C
78.2274 +1973.1 2071.2 1972.9 2077 1973.3 2082.5 C
78.2275 +1967.7 2085.6 1962 2088 1956.3 2090.7 C
78.2276 +1953.9 2092.4 1951 2093 1948.6 2094.8 C
78.2277 +1943.7 2089.9 1937.9 2084.3 1933 2079.6 C
78.2278 +1931.3 2076.1 1933.2 2071.3 1932.3 2067.2 C
78.2279 +1931.3 2062.9 1933.3 2060.6 1932 2057.6 C
78.2280 +1932.7 2056.5 1930.9 2053.3 1933.2 2051.8 C
78.2281 +1936.8 2050.1 1940.1 2046.9 1944 2046.8 C
78.2282 +1946.3 2049.7 1949.3 2051.9 1952 2054.4 C
78.2283 +1954.5 2054.2 1956.4 2052.3 1958.7 2051.3 C
78.2284 +1960.8 2050 1963.2 2049 1965.6 2048.4 C
78.2285 +1968.3 2050.8 1970.7 2054.3 1973.6 2055.4 C
78.2286 +1973 2052.2 1969.7 2050.4 1967.6 2048.2 C
78.2287 +1967.1 2046.7 1968.8 2046.6 1969.5 2045.8 C
78.2288 +1972.8 2043.3 1980.6 2043.4 1979.3 2038.4 C
78.2289 +1979.4 2038.6 1979.2 2038.7 1979.1 2038.8 C
78.2290 +1978.7 2038.6 1978.9 2038.1 1978.8 2037.6 C
78.2291 +1978.9 2037.9 1978.7 2038 1978.6 2038.1 C
78.2292 +1978.2 2032.7 1978.4 2027.1 1978.4 2021.6 C
78.2293 +1979.3 2021.1 1980 2020.2 1981.5 2020.1 C
78.2294 +1983.5 2020.5 1984 2021.8 1985.1 2023.5 C
78.2295 +1985.7 2024 1987.4 2023.7 1986 2022.8 C
78.2296 +1984.7 2021.7 1983.3 2020.8 1983.9 2018.7 C
78.2297 +1987.2 2015.9 1993 2015.4 1994.9 2011.5 C
78.2298 +1992.2 2004.9 1999.3 2005.2 2002.1 2002.4 C
78.2299 +2005.9 2002.7 2004.8 1997.4 2009.1 1999 C
78.2300 +2011 1999.3 2010 2002.9 2012.7 2002.4 C
78.2301 +2010.2 2000.7 2009.4 1996.1 2005.5 1998.5 C
78.2302 +2002.1 2000.3 1999 2002.5 1995.4 2003.8 C
78.2303 +1995.2 2003.6 1994.9 2003.3 1994.7 2003.1 C
78.2304 +1994.3 1997 1995.6 1991.1 1994.4 1985.3 C
78.2305 +1994.3 1986 1993.8 1985 1994 1985.6 C
78.2306 +1993.8 1995.4 1994.4 2001.6 1993.5 2011.7 C
78.2307 +1989.7 2015.5 1983.6 2014.9 1979.8 2018.7 C
78.2308 +1978.3 2019.1 1979.1 2017.4 1978.4 2017 C
78.2309 +1977.8 2015.5 1979.4 2015.3 1978.8 2014.1 C
78.2310 +1978.4 2014.6 1978.5 2012.8 1977.4 2013.4 C
78.2311 +1975.8 2016.8 1978.5 2019.6 1976.9 2023 C
78.2312 +1977 2028.7 1976.7 2034.5 1977.2 2040 C
78.2313 +1971.6 2043.1 1965.8 2045.6 1960.1 2048.2 C
78.2314 +1957.7 2049.9 1954.8 2050.5 1952.4 2052.3 C
78.2315 +1947.6 2047.4 1941.8 2041.8 1936.8 2037.2 C
78.2316 +1935.2 2033.6 1937.1 2028.8 1936.1 2024.7 C
78.2317 +1935.1 2020.4 1937.1 2018.1 1935.9 2015.1 C
78.2318 +1936.5 2014.1 1934.7 2010.8 1937.1 2009.3 C
78.2319 +1944.4 2004.8 1952 2000.9 1959.9 1997.8 C
78.2320 +1963.9 1997 1963.9 2001.9 1966.8 2003.3 C
78.2321 +1970.3 2006.9 1973.7 2009.9 1976.9 2012.9 C
78.2322 +1977.9 2013 1977.1 2011.4 1976.7 2010.8 C
78.2323 +1971.6 2006.3 1966.8 2000.7 1962 1995.9 C
78.2324 +1960 1995.2 1960.1 1996.6 1958.2 1995.6 C
78.2325 +1957 1997 1955.1 1998.8 1953.2 1998 C
78.2326 +1951.7 1994.5 1954.1 1993.4 1952.9 1991.1 C
78.2327 +1952.1 1990.5 1953.3 1990.2 1953.2 1989.6 C
78.2328 +1954.2 1986.8 1950.9 1981.4 1954.4 1981.2 C
78.2329 +1954.7 1981.6 1954.7 1981.7 1955.1 1982 C
78.2330 +1961.9 1979.1 1967.6 1975 1974.3 1971.6 C
78.2331 +1974.7 1969.8 1976.7 1969.5 1978.4 1969.7 C
78.2332 +1980.3 1970 1979.3 1973.6 1982 1973.1 C
78.2333 +1975.8 1962.2 1968 1975.8 1960.8 1976.7 C
78.2334 +1956.9 1977.4 1953.3 1982.4 1949.1 1978.8 C
78.2335 +1946 1975.8 1941.2 1971 1939.5 1969.2 C
78.2336 +1938.5 1968.6 1938.9 1967.4 1937.8 1966.8 C
78.2337 +1928.7 1969.4 1920.6 1974.5 1912.4 1979.1 C
78.2338 +1904 1980 1896.6 1985 1889.3 1989.4 C
78.2339 +1887.9 1990.4 1885.1 1990.3 1885 1992.5 C
78.2340 +1885.4 2000.6 1885.2 2012.9 1885.2 2019.9 C
78.2341 +1886.1 2022 1889.7 2019.5 1888.4 2022.8 C
78.2342 +1889 2023.3 1889.8 2024.4 1890.3 2024 C
78.2343 +1891.2 2023.5 1891.8 2028.2 1893.4 2026.6 C
78.2344 +1894.2 2026.3 1893.9 2027.3 1894.4 2027.6 C
78.2345 +1893.4 2027.6 1894.7 2028.3 1894.1 2028.5 C
78.2346 +1894.4 2029.6 1896 2030 1896 2029.2 C
78.2347 +1896.2 2029 1896.3 2029 1896.5 2029.2 C
78.2348 +1896.8 2029.8 1897.3 2030 1897 2030.7 C
78.2349 +1896.5 2030.7 1896.9 2031.5 1897.2 2031.6 C
78.2350 +1898.3 2034 1899.5 2030.6 1899.6 2033.3 C
78.2351 +1898.5 2033 1899.6 2034.4 1900.1 2034.8 C
78.2352 +1901.3 2035.8 1903.2 2034.6 1902.5 2036.7 C
78.2353 +1904.4 2036.9 1906.1 2032.2 1907.6 2035.5 C
78.2354 +1907.5 2040.1 1907.7 2044.9 1907.3 2049.4 C
78.2355 +1908 2050.2 1908.3 2051.4 1909.5 2051.6 C
78.2356 +1910.1 2051.1 1911.6 2051.1 1911.4 2052.3 C
78.2357 +1909.7 2052.8 1912.4 2054 1912.6 2054.7 C
78.2358 +1913.4 2055.2 1913 2053.7 1913.6 2054.4 C
78.2359 +1913.6 2054.5 1913.6 2055.3 1913.6 2054.7 C
78.2360 +1913.7 2054.4 1913.9 2054.4 1914 2054.7 C
78.2361 +1914 2054.9 1914.1 2055.3 1913.8 2055.4 C
78.2362 +1913.7 2056 1915.2 2057.6 1916 2057.6 C
78.2363 +1915.9 2057.3 1916.1 2057.2 1916.2 2057.1 C
78.2364 +1917 2056.8 1916.7 2057.7 1917.2 2058 C
78.2365 +1917 2058.3 1916.7 2058.3 1916.4 2058.3 C
78.2366 +1917.1 2059 1917.3 2060.1 1918.4 2060.4 C
78.2367 +1918.1 2059.2 1919.1 2060.6 1919.1 2059.5 C
78.2368 +1919 2060.6 1920.6 2060.1 1919.8 2061.2 C
78.2369 +1919.6 2061.2 1919.3 2061.2 1919.1 2061.2 C
78.2370 +1919.6 2061.9 1921.4 2064.2 1921.5 2062.6 C
78.2371 +1922.4 2062.1 1921.6 2063.9 1922.2 2064.3 C
78.2372 +1922.9 2067.3 1926.1 2064.3 1925.6 2067.2 C
78.2373 +1927.2 2066.8 1928.4 2064.6 1930.1 2065.2 C
78.2374 +1931.8 2067.8 1931 2071.8 1930.8 2074.8 C
78.2375 +1930.6 2076.4 1930.1 2078.6 1930.6 2080.4 C
78.2376 +1936.6 2085.4 1941.8 2091.6 1948.1 2096.9 C
78.2377 +1950.7 2096.7 1952.6 2094.8 1954.8 2093.8 C
78.2378 +[0 0.33 0.33 0.99] vc
78.2379 +f
78.2380 +S
78.2381 +n
78.2382 +1989.4 2080.6 m
78.2383 +1996.1 2077.3 2002.7 2073.8 2009.6 2070.8 C
78.2384 +2009.6 2069.6 2010.2 2067.7 2009.3 2067.4 C
78.2385 +2008.9 2062 2009.1 2056.4 2009.1 2050.8 C
78.2386 +2012.3 2046.6 2019 2046.6 2023.5 2043.2 C
78.2387 +2024 2042.3 2025.1 2042.1 2025.4 2041.2 C
78.2388 +2025.3 2032.7 2025.6 2023.1 2025.2 2014.6 C
78.2389 +2025 2015.3 2024.6 2014.2 2024.7 2014.8 C
78.2390 +2024.5 2024.7 2025.1 2030.9 2024.2 2041 C
78.2391 +2020.4 2044.8 2014.3 2044.2 2010.5 2048 C
78.2392 +2009 2048.4 2009.8 2046.7 2009.1 2046.3 C
78.2393 +2008.5 2044.8 2010.2 2044.6 2009.6 2043.4 C
78.2394 +2009.1 2043.9 2009.2 2042.1 2008.1 2042.7 C
78.2395 +2006.5 2046.1 2009.3 2048.9 2007.6 2052.3 C
78.2396 +2007.7 2058 2007.5 2063.8 2007.9 2069.3 C
78.2397 +2002.3 2072.4 1996.5 2074.8 1990.8 2077.5 C
78.2398 +1988.4 2079.2 1985.6 2079.8 1983.2 2081.6 C
78.2399 +1980.5 2079 1977.9 2076.5 1975.5 2074.1 C
78.2400 +1975.5 2075.1 1975.5 2076.2 1975.5 2077.2 C
78.2401 +1977.8 2079.3 1980.3 2081.6 1982.7 2083.7 C
78.2402 +1985.3 2083.5 1987.1 2081.6 1989.4 2080.6 C
78.2403 +f
78.2404 +S
78.2405 +n
78.2406 +1930.1 2079.9 m
78.2407 +1931.1 2075.6 1929.2 2071.1 1930.8 2067.2 C
78.2408 +1930.3 2066.3 1930.1 2064.6 1928.7 2065.5 C
78.2409 +1927.7 2066.4 1926.5 2067 1925.3 2067.4 C
78.2410 +1924.5 2066.9 1925.6 2065.7 1924.4 2066 C
78.2411 +1924.2 2067.2 1923.6 2065.5 1923.2 2065.7 C
78.2412 +1922.3 2063.6 1917.8 2062.1 1919.6 2060.4 C
78.2413 +1919.3 2060.5 1919.2 2060.3 1919.1 2060.2 C
78.2414 +1919.7 2060.9 1918.2 2061 1917.6 2060.2 C
78.2415 +1917 2059.6 1916.1 2058.8 1916.4 2058 C
78.2416 +1915.5 2058 1917.4 2057.1 1915.7 2057.8 C
78.2417 +1914.8 2057.1 1913.4 2056.2 1913.3 2054.9 C
78.2418 +1913.1 2055.4 1911.3 2054.3 1910.9 2053.2 C
78.2419 +1910.7 2052.9 1910.2 2052.5 1910.7 2052.3 C
78.2420 +1911.1 2052.5 1910.9 2052 1910.9 2051.8 C
78.2421 +1910.5 2051.2 1909.9 2052.6 1909.2 2051.8 C
78.2422 +1908.2 2051.4 1907.8 2050.2 1907.1 2049.4 C
78.2423 +1907.5 2044.8 1907.3 2040 1907.3 2035.2 C
78.2424 +1905.3 2033 1902.8 2039.3 1902.3 2035.7 C
78.2425 +1899.6 2036 1898.4 2032.5 1896.3 2030.7 C
78.2426 +1895.7 2030.1 1897.5 2030 1896.3 2029.7 C
78.2427 +1896.3 2030.6 1895 2029.7 1894.4 2029.2 C
78.2428 +1892.9 2028.1 1894.2 2027.4 1893.6 2027.1 C
78.2429 +1892.1 2027.9 1891.7 2025.6 1890.8 2024.9 C
78.2430 +1891.1 2024.6 1889.1 2024.3 1888.4 2023 C
78.2431 +1887.5 2022.6 1888.2 2021.9 1888.1 2021.3 C
78.2432 +1886.7 2022 1885.2 2020.4 1884.8 2019.2 C
78.2433 +1884.8 2010 1884.6 2000.2 1885 1991.8 C
78.2434 +1886.9 1989.6 1889.9 1989.3 1892.2 1987.5 C
78.2435 +1898.3 1982.7 1905.6 1980.1 1912.8 1978.6 C
78.2436 +1921 1974.2 1928.8 1968.9 1937.8 1966.6 C
78.2437 +1939.8 1968.3 1938.8 1968.3 1940.4 1970 C
78.2438 +1945.4 1972.5 1947.6 1981.5 1954.6 1979.3 C
78.2439 +1952.3 1981 1950.4 1978.4 1948.6 1977.9 C
78.2440 +1945.1 1973.9 1941.1 1970.6 1938 1966.6 C
78.2441 +1928.4 1968.5 1920.6 1974.8 1911.9 1978.8 C
78.2442 +1907.1 1979.2 1902.6 1981.7 1898.2 1983.6 C
78.2443 +1893.9 1986 1889.9 1989 1885.5 1990.8 C
78.2444 +1884.9 1991.2 1884.8 1991.8 1884.5 1992.3 C
78.2445 +1884.9 2001.3 1884.7 2011.1 1884.8 2019.6 C
78.2446 +1890.6 2025 1896.5 2031.2 1902.3 2036.9 C
78.2447 +1904.6 2037.6 1905 2033 1907.3 2035.5 C
78.2448 +1907.2 2040.2 1907 2044.8 1907.1 2049.6 C
78.2449 +1913.6 2055.3 1918.4 2061.5 1925.1 2067.4 C
78.2450 +1927.3 2068.2 1929.6 2062.5 1930.6 2066.9 C
78.2451 +1929.7 2070.7 1930.3 2076 1930.1 2080.1 C
78.2452 +1935.6 2085.7 1941.9 2090.7 1947.2 2096.7 C
78.2453 +1942.2 2091.1 1935.5 2085.2 1930.1 2079.9 C
78.2454 +[0.18 0.18 0 0.78] vc
78.2455 +f
78.2456 +S
78.2457 +n
78.2458 +1930.8 2061.9 m
78.2459 +1930.3 2057.8 1931.8 2053.4 1931.1 2050.4 C
78.2460 +1931.3 2050.3 1931.7 2050.5 1931.6 2050.1 C
78.2461 +1933 2051.1 1934.4 2049.5 1935.9 2048.7 C
78.2462 +1937 2046.5 1939.5 2047.1 1941.2 2045.1 C
78.2463 +1939.7 2042.6 1937.3 2041.2 1935.4 2039.3 C
78.2464 +1934 2039.7 1934.5 2038.1 1933.7 2037.6 C
78.2465 +1934 2033.3 1933.1 2027.9 1934.4 2024.4 C
78.2466 +1934.3 2023.8 1933.9 2022.8 1933 2022.8 C
78.2467 +1931.6 2023.1 1930.5 2024.4 1929.2 2024.9 C
78.2468 +1928.4 2024.5 1929.8 2023.5 1928.7 2023.5 C
78.2469 +1927.7 2024.1 1926.2 2022.6 1925.6 2021.6 C
78.2470 +1926.9 2021.6 1924.8 2020.6 1925.6 2020.4 C
78.2471 +1924.7 2021.7 1923.9 2019.6 1923.2 2019.2 C
78.2472 +1923.3 2018.3 1923.8 2018.1 1923.2 2018 C
78.2473 +1922.9 2017.8 1922.9 2017.5 1922.9 2017.2 C
78.2474 +1922.8 2018.3 1921.3 2017.3 1920.3 2018 C
78.2475 +1916.6 2019.7 1913 2022.1 1910 2024.7 C
78.2476 +1910 2032.9 1910 2041.2 1910 2049.4 C
78.2477 +1915.4 2055.2 1920 2058.7 1925.3 2064.8 C
78.2478 +1927.2 2064 1929 2061.4 1930.8 2061.9 C
78.2479 +[0 0 0 0] vc
78.2480 +f
78.2481 +S
78.2482 +n
78.2483 +1907.6 2030.4 m
78.2484 +1907.5 2027.1 1906.4 2021.7 1908.5 2019.9 C
78.2485 +1908.8 2020.1 1908.9 2019 1909.2 2019.6 C
78.2486 +1910 2019.6 1912 2019.2 1913.1 2018.2 C
78.2487 +1913.7 2016.5 1920.2 2015.7 1917.4 2012.7 C
78.2488 +1918.2 2011.2 1917 2013.8 1917.2 2012 C
78.2489 +1916.9 2012.3 1916 2012.4 1915.2 2012 C
78.2490 +1912.5 2010.5 1916.6 2008.8 1913.6 2009.6 C
78.2491 +1912.6 2009.2 1911.1 2009 1910.9 2007.6 C
78.2492 +1911 1999.2 1911.8 1989.8 1911.2 1982.2 C
78.2493 +1910.1 1981.1 1908.8 1982.2 1907.6 1982.2 C
78.2494 +1900.8 1986.5 1893.2 1988.8 1887.2 1994.2 C
78.2495 +1887.2 2002.4 1887.2 2010.7 1887.2 2018.9 C
78.2496 +1892.6 2024.7 1897.2 2028.2 1902.5 2034.3 C
78.2497 +1904.3 2033.3 1906.2 2032.1 1907.6 2030.4 C
78.2498 +f
78.2499 +S
78.2500 +n
78.2501 +1910.7 2025.4 m
78.2502 +1912.7 2022.4 1916.7 2020.8 1919.8 2018.9 C
78.2503 +1920.2 2018.7 1920.6 2018.6 1921 2018.4 C
78.2504 +1925 2020 1927.4 2028.5 1932 2024.2 C
78.2505 +1932.3 2025 1932.5 2023.7 1932.8 2024.4 C
78.2506 +1932.8 2028 1932.8 2031.5 1932.8 2035 C
78.2507 +1931.9 2033.9 1932.5 2036.3 1932.3 2036.9 C
78.2508 +1933.2 2036.4 1932.5 2038.5 1933 2038.4 C
78.2509 +1933.1 2040.5 1935.6 2042.2 1936.6 2043.2 C
78.2510 +1936.2 2042.4 1935.1 2040.8 1933.7 2040.3 C
78.2511 +1932.2 2034.4 1933.8 2029.8 1933 2023.2 C
78.2512 +1931.1 2024.9 1928.4 2026.4 1926.5 2023.5 C
78.2513 +1925.1 2021.6 1923 2019.8 1921.5 2018.2 C
78.2514 +1917.8 2018.9 1915.2 2022.5 1911.6 2023.5 C
78.2515 +1910.8 2023.8 1911.2 2024.7 1910.4 2025.2 C
78.2516 +1910.9 2031.8 1910.6 2039.1 1910.7 2045.6 C
78.2517 +1910.1 2048 1910.7 2045.9 1911.2 2044.8 C
78.2518 +1910.6 2038.5 1911.2 2031.8 1910.7 2025.4 C
78.2519 +[0.07 0.06 0 0.58] vc
78.2520 +f
78.2521 +S
78.2522 +n
78.2523 +1910.7 2048.9 m
78.2524 +1910.3 2047.4 1911.3 2046.5 1911.6 2045.3 C
78.2525 +1912.9 2045.3 1913.9 2047.1 1915.2 2045.8 C
78.2526 +1915.2 2044.9 1916.6 2043.3 1917.2 2042.9 C
78.2527 +1918.7 2042.9 1919.4 2044.4 1920.5 2043.2 C
78.2528 +1921.2 2042.2 1921.4 2040.9 1922.4 2040.3 C
78.2529 +1924.5 2040.3 1925.7 2040.9 1926.8 2039.6 C
78.2530 +1927.1 2037.9 1926.8 2038.1 1927.7 2037.6 C
78.2531 +1929 2037.5 1930.4 2037 1931.6 2037.2 C
78.2532 +1932.3 2038.2 1933.1 2038.7 1932.8 2040.3 C
78.2533 +1935 2041.8 1935.9 2043.8 1938.5 2044.8 C
78.2534 +1938.6 2045 1938.3 2045.5 1938.8 2045.3 C
78.2535 +1939.1 2042.9 1935.4 2044.2 1935.4 2042.2 C
78.2536 +1932.1 2040.8 1932.8 2037.2 1932 2034.8 C
78.2537 +1932.3 2034 1932.7 2035.4 1932.5 2034.8 C
78.2538 +1931.3 2031.8 1935.5 2020.1 1928.9 2025.9 C
78.2539 +1924.6 2024.7 1922.6 2014.5 1917.4 2020.4 C
78.2540 +1915.5 2022.8 1912 2022.6 1910.9 2025.4 C
78.2541 +1911.5 2031.9 1910.9 2038.8 1911.4 2045.3 C
78.2542 +1911.1 2046.5 1910 2047.4 1910.4 2048.9 C
78.2543 +1915.1 2054.4 1920.4 2058.3 1925.1 2063.8 C
78.2544 +1920.8 2058.6 1914.9 2054.3 1910.7 2048.9 C
78.2545 +[0.4 0.4 0 0] vc
78.2546 +f
78.2547 +S
78.2548 +n
78.2549 +1934.7 2031.9 m
78.2550 +1934.6 2030.7 1934.9 2029.5 1934.4 2028.5 C
78.2551 +1934 2029.5 1934.3 2031.2 1934.2 2032.6 C
78.2552 +1933.8 2031.7 1934.9 2031.6 1934.7 2031.9 C
78.2553 +[0.92 0.92 0 0.67] vc
78.2554 +f
78.2555 +S
78.2556 +n
78.2557 +vmrs
78.2558 +1934.7 2019.4 m
78.2559 +1934.1 2015.3 1935.6 2010.9 1934.9 2007.9 C
78.2560 +1935.1 2007.8 1935.6 2008.1 1935.4 2007.6 C
78.2561 +1936.8 2008.6 1938.2 2007 1939.7 2006.2 C
78.2562 +1940.1 2004.3 1942.7 2005 1943.6 2003.8 C
78.2563 +1945.1 2000.3 1954 2000.8 1950 1996.6 C
78.2564 +1952.1 1993.3 1948.2 1989.2 1951.2 1985.6 C
78.2565 +1953 1981.4 1948.4 1982.3 1947.9 1979.8 C
78.2566 +1945.4 1979.6 1945.1 1975.5 1942.4 1975 C
78.2567 +1942.4 1972.3 1938 1973.6 1938.5 1970.4 C
78.2568 +1937.4 1969 1935.6 1970.1 1934.2 1970.2 C
78.2569 +1927.5 1974.5 1919.8 1976.8 1913.8 1982.2 C
78.2570 +1913.8 1990.4 1913.8 1998.7 1913.8 2006.9 C
78.2571 +1919.3 2012.7 1923.8 2016.2 1929.2 2022.3 C
78.2572 +1931.1 2021.6 1932.8 2018.9 1934.7 2019.4 C
78.2573 +[0 0 0 0] vc
78.2574 +f
78.2575 +0.4 w
78.2576 +2 J
78.2577 +2 M
78.2578 +S
78.2579 +n
78.2580 +2024.2 2038.1 m
78.2581 +2024.1 2029.3 2024.4 2021.7 2024.7 2014.4 C
78.2582 +2024.4 2013.6 2020.6 2013.4 2021.3 2011.2 C
78.2583 +2020.5 2010.3 2018.4 2010.6 2018.9 2008.6 C
78.2584 +2019 2008.8 2018.8 2009 2018.7 2009.1 C
78.2585 +2018.2 2006.7 2015.2 2007.9 2015.3 2005.5 C
78.2586 +2014.7 2004.8 2012.4 2005.1 2013.2 2003.6 C
78.2587 +2012.3 2004.2 2012.8 2002.4 2012.7 2002.6 C
78.2588 +2009.4 2003.3 2011.2 1998.6 2008.4 1999.2 C
78.2589 +2007 1999.1 2006.1 1999.4 2005.7 2000.4 C
78.2590 +2006.9 1998.5 2007.7 2000.5 2009.3 2000.2 C
78.2591 +2009.2 2003.7 2012.4 2002.1 2012.9 2005.2 C
78.2592 +2015.9 2005.6 2015.2 2008.6 2017.7 2008.8 C
78.2593 +2018.4 2009.6 2018.3 2011.4 2019.6 2011 C
78.2594 +2021.1 2011.7 2021.4 2014.8 2023.7 2015.1 C
78.2595 +2023.7 2023.5 2023.9 2031.6 2023.5 2040.5 C
78.2596 +2021.8 2041.7 2020.7 2043.6 2018.4 2043.9 C
78.2597 +2020.8 2042.7 2025.5 2041.8 2024.2 2038.1 C
78.2598 +[0 0.87 0.91 0.83] vc
78.2599 +f
78.2600 +S
78.2601 +n
78.2602 +2023.5 2040 m
78.2603 +2023.5 2031.1 2023.5 2023.4 2023.5 2015.1 C
78.2604 +2020.2 2015 2021.8 2010.3 2018.4 2011 C
78.2605 +2018.6 2007.5 2014.7 2009.3 2014.8 2006.4 C
78.2606 +2011.8 2006.3 2012.2 2002.3 2009.8 2002.4 C
78.2607 +2009.7 2001.5 2009.2 2000.1 2008.4 2000.2 C
78.2608 +2008.7 2000.9 2009.7 2001.2 2009.3 2002.4 C
78.2609 +2008.4 2004.2 2007.5 2003.1 2007.9 2005.5 C
78.2610 +2007.9 2010.8 2007.7 2018.7 2008.1 2023.2 C
78.2611 +2009 2024.3 2007.3 2023.4 2007.9 2024 C
78.2612 +2007.7 2024.6 2007.3 2026.3 2008.6 2027.1 C
78.2613 +2009.7 2026.8 2010 2027.6 2010.5 2028 C
78.2614 +2010.5 2028.2 2010.5 2029.1 2010.5 2028.5 C
78.2615 +2011.5 2028 2010.5 2030 2011.5 2030 C
78.2616 +2014.2 2029.7 2012.9 2032.2 2014.8 2032.6 C
78.2617 +2015.1 2033.6 2015.3 2033 2016 2033.3 C
78.2618 +2017 2033.9 2016.6 2035.4 2017.2 2036.2 C
78.2619 +2018.7 2036.4 2019.2 2039 2021.3 2038.4 C
78.2620 +2021.6 2035.4 2019.7 2029.5 2021.1 2027.3 C
78.2621 +2020.9 2023.5 2021.5 2018.5 2020.6 2016 C
78.2622 +2020.9 2013.9 2021.5 2015.4 2022.3 2014.4 C
78.2623 +2022.2 2015.1 2023.3 2014.8 2023.2 2015.6 C
78.2624 +2022.7 2019.8 2023.3 2024.3 2022.8 2028.5 C
78.2625 +2022.3 2028.2 2022.6 2027.6 2022.5 2027.1 C
78.2626 +2022.5 2027.8 2022.5 2029.2 2022.5 2029.2 C
78.2627 +2022.6 2029.2 2022.7 2029.1 2022.8 2029 C
78.2628 +2023.9 2032.8 2022.6 2037 2023 2040.8 C
78.2629 +2022.3 2041.2 2021.6 2041.5 2021.1 2042.2 C
78.2630 +2022 2041.2 2022.9 2041.4 2023.5 2040 C
78.2631 +[0 1 1 0.23] vc
78.2632 +f
78.2633 +S
78.2634 +n
78.2635 +2009.1 1997.8 m
78.2636 +2003.8 1997.7 2000.1 2002.4 1995.4 2003.1 C
78.2637 +1995 1999.5 1995.2 1995 1995.2 1992 C
78.2638 +1995.2 1995.8 1995 1999.7 1995.4 2003.3 C
78.2639 +2000.3 2002.2 2003.8 1997.9 2009.1 1997.8 C
78.2640 +2012.3 2001.2 2015.6 2004.8 2018.7 2008.1 C
78.2641 +2021.6 2011.2 2027.5 2013.9 2025.9 2019.9 C
78.2642 +2026.1 2017.9 2025.6 2016.2 2025.4 2014.4 C
78.2643 +2020.2 2008.4 2014 2003.6 2009.1 1997.8 C
78.2644 +[0.18 0.18 0 0.78] vc
78.2645 +f
78.2646 +S
78.2647 +n
78.2648 +2009.3 1997.8 m
78.2649 +2008.7 1997.4 2007.9 1997.6 2007.2 1997.6 C
78.2650 +2007.9 1997.6 2008.9 1997.4 2009.6 1997.8 C
78.2651 +2014.7 2003.6 2020.8 2008.8 2025.9 2014.8 C
78.2652 +2025.8 2017.7 2026.1 2014.8 2025.6 2014.1 C
78.2653 +2020.4 2008.8 2014.8 2003.3 2009.3 1997.8 C
78.2654 +[0.07 0.06 0 0.58] vc
78.2655 +f
78.2656 +S
78.2657 +n
78.2658 +2009.6 1997.6 m
78.2659 +2009 1997.1 2008.1 1997.4 2007.4 1997.3 C
78.2660 +2008.1 1997.4 2009 1997.1 2009.6 1997.6 C
78.2661 +2014.8 2003.7 2021.1 2008.3 2025.9 2014.4 C
78.2662 +2021.1 2008.3 2014.7 2003.5 2009.6 1997.6 C
78.2663 +[0.4 0.4 0 0] vc
78.2664 +f
78.2665 +S
78.2666 +n
78.2667 +2021.8 2011.5 m
78.2668 +2021.9 2012.2 2022.3 2013.5 2023.7 2013.6 C
78.2669 +2023.4 2012.7 2022.8 2011.8 2021.8 2011.5 C
78.2670 +[0 0.33 0.33 0.99] vc
78.2671 +f
78.2672 +S
78.2673 +n
78.2674 +2021.1 2042 m
78.2675 +2022.1 2041.1 2020.9 2040.2 2020.6 2039.6 C
78.2676 +2018.4 2039.5 2018.1 2036.9 2016.3 2036.4 C
78.2677 +2015.8 2035.5 2015.3 2033.8 2014.8 2033.6 C
78.2678 +2012.4 2033.8 2013 2030.4 2010.5 2030.2 C
78.2679 +2009.6 2028.9 2009.6 2028.3 2008.4 2028 C
78.2680 +2006.9 2026.7 2007.5 2024.3 2006 2023.2 C
78.2681 +2006.6 2023.2 2005.7 2023.3 2005.7 2023 C
78.2682 +2006.4 2022.5 2006.3 2021.1 2006.7 2020.6 C
78.2683 +2006.6 2015 2006.9 2009 2006.4 2003.8 C
78.2684 +2006.9 2002.5 2007.6 2001.1 2006.9 2000.7 C
78.2685 +2004.6 2003.6 2003 2002.9 2000.2 2004.3 C
78.2686 +1999.3 2005.8 1997.9 2006.3 1996.1 2006.7 C
78.2687 +1995.7 2008.9 1996 2011.1 1995.9 2012.9 C
78.2688 +1993.4 2015.1 1990.5 2016.2 1987.7 2017.7 C
78.2689 +1987.1 2019.3 1991.1 2019.4 1990.4 2021.3 C
78.2690 +1990.5 2021.5 1991.9 2022.3 1992 2023 C
78.2691 +1994.8 2024.4 1996.2 2027.5 1998.5 2030 C
78.2692 +2002.4 2033 2005.2 2037.2 2008.8 2041 C
78.2693 +2010.2 2041.3 2011.6 2042 2011 2043.9 C
78.2694 +2011.2 2044.8 2010.1 2045.3 2010.5 2046.3 C
78.2695 +2013.8 2044.8 2017.5 2043.4 2021.1 2042 C
78.2696 +[0 0.5 0.5 0.2] vc
78.2697 +f
78.2698 +S
78.2699 +n
78.2700 +2019.4 2008.8 m
78.2701 +2018.9 2009.2 2019.3 2009.9 2019.6 2010.3 C
78.2702 +2022.2 2011.5 2020.3 2009.1 2019.4 2008.8 C
78.2703 +[0 0.33 0.33 0.99] vc
78.2704 +f
78.2705 +S
78.2706 +n
78.2707 +2018 2007.4 m
78.2708 +2015.7 2006.7 2015.3 2003.6 2012.9 2002.8 C
78.2709 +2013.5 2003.7 2013.5 2005.1 2015.6 2005.2 C
78.2710 +2016.4 2006.1 2015.7 2007.7 2018 2007.4 C
78.2711 +f
78.2712 +S
78.2713 +n
78.2714 +vmrs
78.2715 +1993.5 2008.8 m
78.2716 +1993.4 2000 1993.7 1992.5 1994 1985.1 C
78.2717 +1993.7 1984.3 1989.9 1984.1 1990.6 1982 C
78.2718 +1989.8 1981.1 1987.7 1981.4 1988.2 1979.3 C
78.2719 +1988.3 1979.6 1988.1 1979.7 1988 1979.8 C
78.2720 +1987.5 1977.5 1984.5 1978.6 1984.6 1976.2 C
78.2721 +1983.9 1975.5 1981.7 1975.8 1982.4 1974.3 C
78.2722 +1981.6 1974.9 1982.1 1973.1 1982 1973.3 C
78.2723 +1979 1973.7 1980 1968.8 1976.9 1969.7 C
78.2724 +1975.9 1969.8 1975.3 1970.3 1975 1971.2 C
78.2725 +1976.2 1969.2 1977 1971.2 1978.6 1970.9 C
78.2726 +1978.5 1974.4 1981.7 1972.8 1982.2 1976 C
78.2727 +1985.2 1976.3 1984.5 1979.3 1987 1979.6 C
78.2728 +1987.7 1980.3 1987.5 1982.1 1988.9 1981.7 C
78.2729 +1990.4 1982.4 1990.7 1985.5 1993 1985.8 C
78.2730 +1992.9 1994.3 1993.2 2002.3 1992.8 2011.2 C
78.2731 +1991.1 2012.4 1990 2014.4 1987.7 2014.6 C
78.2732 +1990.1 2013.4 1994.7 2012.6 1993.5 2008.8 C
78.2733 +[0 0.87 0.91 0.83] vc
78.2734 +f
78.2735 +0.4 w
78.2736 +2 J
78.2737 +2 M
78.2738 +S
78.2739 +n
78.2740 +1992.8 2010.8 m
78.2741 +1992.8 2001.8 1992.8 1994.1 1992.8 1985.8 C
78.2742 +1989.5 1985.7 1991.1 1981.1 1987.7 1981.7 C
78.2743 +1987.9 1978.2 1983.9 1980 1984.1 1977.2 C
78.2744 +1981.1 1977 1981.5 1973 1979.1 1973.1 C
78.2745 +1979 1972.2 1978.5 1970.9 1977.6 1970.9 C
78.2746 +1977.9 1971.6 1979 1971.9 1978.6 1973.1 C
78.2747 +1977.6 1974.9 1976.8 1973.9 1977.2 1976.2 C
78.2748 +1977.2 1981.5 1977 1989.4 1977.4 1994 C
78.2749 +1978.3 1995 1976.6 1994.1 1977.2 1994.7 C
78.2750 +1977 1995.3 1976.6 1997 1977.9 1997.8 C
78.2751 +1979 1997.5 1979.3 1998.3 1979.8 1998.8 C
78.2752 +1979.8 1998.9 1979.8 1999.8 1979.8 1999.2 C
78.2753 +1980.8 1998.7 1979.7 2000.7 1980.8 2000.7 C
78.2754 +1983.5 2000.4 1982.1 2003 1984.1 2003.3 C
78.2755 +1984.4 2004.3 1984.5 2003.7 1985.3 2004 C
78.2756 +1986.3 2004.6 1985.9 2006.1 1986.5 2006.9 C
78.2757 +1988 2007.1 1988.4 2009.7 1990.6 2009.1 C
78.2758 +1990.9 2006.1 1989 2000.2 1990.4 1998 C
78.2759 +1990.2 1994.3 1990.8 1989.2 1989.9 1986.8 C
78.2760 +1990.2 1984.7 1990.8 1986.2 1991.6 1985.1 C
78.2761 +1991.5 1985.9 1992.6 1985.5 1992.5 1986.3 C
78.2762 +1992 1990.5 1992.6 1995 1992 1999.2 C
78.2763 +1991.6 1998.9 1991.9 1998.3 1991.8 1997.8 C
78.2764 +1991.8 1998.5 1991.8 2000 1991.8 2000 C
78.2765 +1991.9 1999.9 1992 1999.8 1992 1999.7 C
78.2766 +1993.2 2003.5 1991.9 2007.7 1992.3 2011.5 C
78.2767 +1991.6 2012 1990.9 2012.2 1990.4 2012.9 C
78.2768 +1991.3 2011.9 1992.2 2012.1 1992.8 2010.8 C
78.2769 +[0 1 1 0.23] vc
78.2770 +f
78.2771 +S
78.2772 +n
78.2773 +1978.4 1968.5 m
78.2774 +1977 1969.2 1975.8 1968.2 1974.5 1969 C
78.2775 +1968.3 1973 1961.6 1976 1955.1 1979.1 C
78.2776 +1962 1975.9 1968.8 1972.5 1975.5 1968.8 C
78.2777 +1976.5 1968.8 1977.6 1968.8 1978.6 1968.8 C
78.2778 +1981.7 1972.1 1984.8 1975.7 1988 1978.8 C
78.2779 +1990.9 1981.9 1996.8 1984.6 1995.2 1990.6 C
78.2780 +1995.3 1988.6 1994.9 1986.9 1994.7 1985.1 C
78.2781 +1989.5 1979.1 1983.3 1974.3 1978.4 1968.5 C
78.2782 +[0.18 0.18 0 0.78] vc
78.2783 +f
78.2784 +S
78.2785 +n
78.2786 +1978.4 1968.3 m
78.2787 +1977.9 1968.7 1977.1 1968.5 1976.4 1968.5 C
78.2788 +1977.3 1968.8 1978.1 1967.9 1978.8 1968.5 C
78.2789 +1984 1974.3 1990.1 1979.5 1995.2 1985.6 C
78.2790 +1995.1 1988.4 1995.3 1985.6 1994.9 1984.8 C
78.2791 +1989.5 1979.4 1983.9 1973.8 1978.4 1968.3 C
78.2792 +[0.07 0.06 0 0.58] vc
78.2793 +f
78.2794 +S
78.2795 +n
78.2796 +1978.6 1968 m
78.2797 +1977.9 1968 1977.4 1968.6 1978.4 1968 C
78.2798 +1983.9 1973.9 1990.1 1979.1 1995.2 1985.1 C
78.2799 +1990.2 1979 1983.8 1974.1 1978.6 1968 C
78.2800 +[0.4 0.4 0 0] vc
78.2801 +f
78.2802 +S
78.2803 +n
78.2804 +1991.1 1982.2 m
78.2805 +1991.2 1982.9 1991.6 1984.2 1993 1984.4 C
78.2806 +1992.6 1983.5 1992.1 1982.5 1991.1 1982.2 C
78.2807 +[0 0.33 0.33 0.99] vc
78.2808 +f
78.2809 +S
78.2810 +n
78.2811 +1990.4 2012.7 m
78.2812 +1991.4 2011.8 1990.2 2010.9 1989.9 2010.3 C
78.2813 +1987.7 2010.2 1987.4 2007.6 1985.6 2007.2 C
78.2814 +1985.1 2006.2 1984.6 2004.5 1984.1 2004.3 C
78.2815 +1981.7 2004.5 1982.3 2001.2 1979.8 2000.9 C
78.2816 +1978.8 1999.6 1978.8 1999.1 1977.6 1998.8 C
78.2817 +1976.1 1997.4 1976.7 1995 1975.2 1994 C
78.2818 +1975.8 1994 1975 1994 1975 1993.7 C
78.2819 +1975.7 1993.2 1975.6 1991.8 1976 1991.3 C
78.2820 +1975.9 1985.7 1976.1 1979.7 1975.7 1974.5 C
78.2821 +1976.2 1973.3 1976.9 1971.8 1976.2 1971.4 C
78.2822 +1973.9 1974.3 1972.2 1973.6 1969.5 1975 C
78.2823 +1967.9 1977.5 1963.8 1977.1 1961.8 1980 C
78.2824 +1959 1980 1957.6 1983 1954.8 1982.9 C
78.2825 +1953.8 1984.2 1954.8 1985.7 1955.1 1987.2 C
78.2826 +1956.2 1989.5 1959.7 1990.1 1959.9 1991.8 C
78.2827 +1965.9 1998 1971.8 2005.2 1978.1 2011.7 C
78.2828 +1979.5 2012 1980.9 2012.7 1980.3 2014.6 C
78.2829 +1980.5 2015.6 1979.4 2016 1979.8 2017 C
78.2830 +1983 2015.6 1986.8 2014.1 1990.4 2012.7 C
78.2831 +[0 0.5 0.5 0.2] vc
78.2832 +f
78.2833 +S
78.2834 +n
78.2835 +1988.7 1979.6 m
78.2836 +1988.2 1979.9 1988.6 1980.6 1988.9 1981 C
78.2837 +1991.4 1982.2 1989.6 1979.9 1988.7 1979.6 C
78.2838 +[0 0.33 0.33 0.99] vc
78.2839 +f
78.2840 +S
78.2841 +n
78.2842 +1987.2 1978.1 m
78.2843 +1985 1977.5 1984.6 1974.3 1982.2 1973.6 C
78.2844 +1982.7 1974.5 1982.8 1975.8 1984.8 1976 C
78.2845 +1985.7 1976.9 1985 1978.4 1987.2 1978.1 C
78.2846 +f
78.2847 +S
78.2848 +n
78.2849 +1975.5 2084 m
78.2850 +1975.5 2082 1975.3 2080 1975.7 2078.2 C
78.2851 +1978.8 2079 1980.9 2085.5 1984.8 2083.5 C
78.2852 +1993 2078.7 2001.6 2075 2010 2070.8 C
78.2853 +2010.1 2064 2009.9 2057.2 2010.3 2050.6 C
78.2854 +2014.8 2046.2 2020.9 2045.7 2025.6 2042 C
78.2855 +2026.1 2035.1 2025.8 2028 2025.9 2021.1 C
78.2856 +2025.8 2027.8 2026.1 2034.6 2025.6 2041.2 C
78.2857 +2022.2 2044.9 2017.6 2046.8 2012.9 2048 C
78.2858 +2012.5 2049.5 2010.4 2049.4 2009.8 2051.1 C
78.2859 +2009.9 2057.6 2009.6 2064.2 2010 2070.5 C
78.2860 +2001.2 2075.4 1992 2079.1 1983.2 2084 C
78.2861 +1980.3 2082.3 1977.8 2079.2 1975.2 2077.5 C
78.2862 +1974.9 2079.9 1977.2 2084.6 1973.3 2085.2 C
78.2863 +1964.7 2088.6 1956.8 2093.7 1948.1 2097.2 C
78.2864 +1949 2097.3 1949.6 2096.9 1950.3 2096.7 C
78.2865 +1958.4 2091.9 1967.1 2088.2 1975.5 2084 C
78.2866 +[0.18 0.18 0 0.78] vc
78.2867 +f
78.2868 +S
78.2869 +n
78.2870 +vmrs
78.2871 +1948.6 2094.5 m
78.2872 +1950.2 2093.7 1951.8 2092.9 1953.4 2092.1 C
78.2873 +1951.8 2092.9 1950.2 2093.7 1948.6 2094.5 C
78.2874 +[0 0.87 0.91 0.83] vc
78.2875 +f
78.2876 +0.4 w
78.2877 +2 J
78.2878 +2 M
78.2879 +S
78.2880 +n
78.2881 +1971.6 2082.3 m
78.2882 +1971.6 2081.9 1970.7 2081.1 1970.9 2081.3 C
78.2883 +1970.7 2081.6 1970.6 2081.6 1970.4 2081.3 C
78.2884 +1970.8 2080.1 1968.7 2081.7 1968.3 2080.8 C
78.2885 +1966.6 2080.9 1966.7 2078 1964.2 2078.2 C
78.2886 +1964.8 2075 1960.1 2075.8 1960.1 2072.9 C
78.2887 +1958 2072.3 1957.5 2069.3 1955.3 2069.3 C
78.2888 +1953.9 2070.9 1948.8 2067.8 1950 2072 C
78.2889 +1949 2074 1943.2 2070.6 1944 2074.8 C
78.2890 +1942.2 2076.6 1937.6 2073.9 1938 2078.2 C
78.2891 +1936.7 2078.6 1935 2078.6 1933.7 2078.2 C
78.2892 +1933.5 2080 1936.8 2080.7 1937.3 2082.8 C
78.2893 +1939.9 2083.5 1940.6 2086.4 1942.6 2088 C
78.2894 +1945.2 2089.2 1946 2091.3 1948.4 2093.6 C
78.2895 +1956 2089.5 1963.9 2086.1 1971.6 2082.3 C
78.2896 +[0 0.01 1 0] vc
78.2897 +f
78.2898 +S
78.2899 +n
78.2900 +1958.2 2089.7 m
78.2901 +1956.4 2090 1955.6 2091.3 1953.9 2091.9 C
78.2902 +1955.6 2091.9 1956.5 2089.7 1958.2 2089.7 C
78.2903 +[0 0.87 0.91 0.83] vc
78.2904 +f
78.2905 +S
78.2906 +n
78.2907 +1929.9 2080.4 m
78.2908 +1929.5 2077.3 1929.7 2073.9 1929.6 2070.8 C
78.2909 +1929.8 2074.1 1929.2 2077.8 1930.1 2080.8 C
78.2910 +1935.8 2085.9 1941.4 2091.3 1946.9 2096.9 C
78.2911 +1941.2 2091 1935.7 2086 1929.9 2080.4 C
78.2912 +[0.4 0.4 0 0] vc
78.2913 +f
78.2914 +S
78.2915 +n
78.2916 +1930.1 2080.4 m
78.2917 +1935.8 2086 1941.5 2090.7 1946.9 2096.7 C
78.2918 +1941.5 2090.9 1935.7 2085.8 1930.1 2080.4 C
78.2919 +[0.07 0.06 0 0.58] vc
78.2920 +f
78.2921 +S
78.2922 +n
78.2923 +1940.9 2087.1 m
78.2924 +1941.7 2088 1944.8 2090.6 1943.6 2089.2 C
78.2925 +1942.5 2089 1941.6 2087.7 1940.9 2087.1 C
78.2926 +[0 0.87 0.91 0.83] vc
78.2927 +f
78.2928 +S
78.2929 +n
78.2930 +1972.8 2082.8 m
78.2931 +1973 2075.3 1972.4 2066.9 1973.3 2059.5 C
78.2932 +1972.5 2058.9 1972.8 2057.3 1973.1 2056.4 C
78.2933 +1974.8 2055.2 1973.4 2055.5 1972.4 2055.4 C
78.2934 +1970.1 2053.2 1967.9 2050.9 1965.6 2048.7 C
78.2935 +1960.9 2049.9 1956.9 2052.7 1952.4 2054.7 C
78.2936 +1949.3 2052.5 1946.3 2049.5 1943.6 2046.8 C
78.2937 +1939.9 2047.7 1936.8 2050.1 1933.5 2051.8 C
78.2938 +1930.9 2054.9 1933.5 2056.2 1932.3 2059.7 C
78.2939 +1933.2 2059.7 1932.2 2060.5 1932.5 2060.2 C
78.2940 +1933.2 2062.5 1931.6 2064.6 1932.5 2067.4 C
78.2941 +1932.9 2069.7 1932.7 2072.2 1932.8 2074.6 C
78.2942 +1933.6 2070.6 1932.2 2066.3 1933 2062.6 C
78.2943 +1934.4 2058.2 1929.8 2053.5 1935.2 2051.1 C
78.2944 +1937.7 2049.7 1940.2 2048 1942.8 2046.8 C
78.2945 +1945.9 2049.2 1948.8 2052 1951.7 2054.7 C
78.2946 +1952.7 2054.7 1953.6 2054.6 1954.4 2054.2 C
78.2947 +1958.1 2052.5 1961.7 2049.3 1965.9 2049.2 C
78.2948 +1968.2 2052.8 1975.2 2055 1972.6 2060.9 C
78.2949 +1973.3 2062.4 1972.2 2065.2 1972.6 2067.6 C
78.2950 +1972.7 2072.6 1972.4 2077.7 1972.8 2082.5 C
78.2951 +1968.1 2084.9 1963.5 2087.5 1958.7 2089.5 C
78.2952 +1963.5 2087.4 1968.2 2085 1972.8 2082.8 C
78.2953 +f
78.2954 +S
78.2955 +n
78.2956 +1935.2 2081.1 m
78.2957 +1936.8 2083.4 1938.6 2084.6 1940.4 2086.6 C
78.2958 +1938.8 2084.4 1936.7 2083.4 1935.2 2081.1 C
78.2959 +f
78.2960 +S
78.2961 +n
78.2962 +1983.2 2081.3 m
78.2963 +1984.8 2080.5 1986.3 2079.7 1988 2078.9 C
78.2964 +1986.3 2079.7 1984.8 2080.5 1983.2 2081.3 C
78.2965 +f
78.2966 +S
78.2967 +n
78.2968 +2006.2 2069.1 m
78.2969 +2006.2 2068.7 2005.2 2067.9 2005.5 2068.1 C
78.2970 +2005.3 2068.4 2005.2 2068.4 2005 2068.1 C
78.2971 +2005.4 2066.9 2003.3 2068.5 2002.8 2067.6 C
78.2972 +2001.2 2067.7 2001.2 2064.8 1998.8 2065 C
78.2973 +1999.4 2061.8 1994.7 2062.6 1994.7 2059.7 C
78.2974 +1992.4 2059.5 1992.4 2055.8 1990.1 2056.8 C
78.2975 +1985.9 2059.5 1981.1 2061 1976.9 2063.8 C
78.2976 +1977.2 2067.6 1974.9 2074.2 1978.8 2075.8 C
78.2977 +1979.6 2077.8 1981.7 2078.4 1982.9 2080.4 C
78.2978 +1990.6 2076.3 1998.5 2072.9 2006.2 2069.1 C
78.2979 +[0 0.01 1 0] vc
78.2980 +f
78.2981 +S
78.2982 +n
78.2983 +vmrs
78.2984 +1992.8 2076.5 m
78.2985 +1991 2076.8 1990.2 2078.1 1988.4 2078.7 C
78.2986 +1990.2 2078.7 1991 2076.5 1992.8 2076.5 C
78.2987 +[0 0.87 0.91 0.83] vc
78.2988 +f
78.2989 +0.4 w
78.2990 +2 J
78.2991 +2 M
78.2992 +S
78.2993 +n
78.2994 +1975.5 2073.4 m
78.2995 +1976.1 2069.7 1973.9 2064.6 1977.4 2062.4 C
78.2996 +1973.9 2064.5 1976.1 2069.9 1975.5 2073.6 C
78.2997 +1976 2074.8 1979.3 2077.4 1978.1 2076 C
78.2998 +1977 2075.7 1975.8 2074.5 1975.5 2073.4 C
78.2999 +f
78.3000 +S
78.3001 +n
78.3002 +2007.4 2069.6 m
78.3003 +2007.6 2062.1 2007 2053.7 2007.9 2046.3 C
78.3004 +2007.1 2045.7 2007.3 2044.1 2007.6 2043.2 C
78.3005 +2009.4 2042 2007.9 2042.3 2006.9 2042.2 C
78.3006 +2002.2 2037.4 1996.7 2032.4 1992.5 2027.3 C
78.3007 +1992 2027.3 1991.6 2027.3 1991.1 2027.3 C
78.3008 +1991.4 2035.6 1991.4 2045.6 1991.1 2054.4 C
78.3009 +1990.5 2055.5 1988.4 2056.6 1990.6 2055.4 C
78.3010 +1991.6 2055.4 1991.6 2054.1 1991.6 2053.2 C
78.3011 +1990.8 2044.7 1991.9 2035.4 1991.6 2027.6 C
78.3012 +1991.8 2027.6 1992 2027.6 1992.3 2027.6 C
78.3013 +1997 2032.8 2002.5 2037.7 2007.2 2042.9 C
78.3014 +2007.3 2044.8 2006.7 2047.4 2007.6 2048.4 C
78.3015 +2006.9 2055.1 2007.1 2062.5 2007.4 2069.3 C
78.3016 +2002.7 2071.7 1998.1 2074.3 1993.2 2076.3 C
78.3017 +1998 2074.2 2002.7 2071.8 2007.4 2069.6 C
78.3018 +f
78.3019 +S
78.3020 +n
78.3021 +2006.7 2069.1 m
78.3022 +2006.3 2068.6 2005.9 2067.7 2005.7 2066.9 C
78.3023 +2005.7 2059.7 2005.9 2051.4 2005.5 2045.1 C
78.3024 +2004.9 2045.3 2004.7 2044.5 2004.3 2045.3 C
78.3025 +2005.1 2045.3 2004.2 2045.8 2004.8 2046 C
78.3026 +2004.8 2052.2 2004.8 2059.2 2004.8 2064.5 C
78.3027 +2005.7 2065.7 2005.1 2065.7 2005 2066.7 C
78.3028 +2003.8 2067 2002.7 2067.2 2001.9 2066.4 C
78.3029 +2001.3 2064.6 1998 2063.1 1998 2061.9 C
78.3030 +1996.1 2062.3 1996.6 2058.3 1994.2 2058.8 C
78.3031 +1992.6 2057.7 1992.7 2054.8 1989.9 2056.6 C
78.3032 +1985.6 2059.3 1980.9 2060.8 1976.7 2063.6 C
78.3033 +1976 2066.9 1976 2071.2 1976.7 2074.6 C
78.3034 +1977.6 2070.8 1973.1 2062.1 1980.5 2061.2 C
78.3035 +1984.3 2060.3 1987.5 2058.2 1990.8 2056.4 C
78.3036 +1991.7 2056.8 1992.9 2057.2 1993.5 2059.2 C
78.3037 +1994.3 2058.6 1994.4 2060.6 1994.7 2059.2 C
78.3038 +1995.3 2062.7 1999.2 2061.4 1998.8 2064.8 C
78.3039 +2001.8 2065.4 2002.5 2068.4 2005.2 2067.4 C
78.3040 +2004.9 2067.9 2006 2068 2006.4 2069.1 C
78.3041 +2001.8 2071.1 1997.4 2073.9 1992.8 2075.8 C
78.3042 +1997.5 2073.8 2002 2071.2 2006.7 2069.1 C
78.3043 +[0 0.2 1 0] vc
78.3044 +f
78.3045 +S
78.3046 +n
78.3047 +1988.7 2056.6 m
78.3048 +1985.1 2058.7 1981.1 2060.1 1977.6 2061.9 C
78.3049 +1981.3 2060.5 1985.6 2058.1 1988.7 2056.6 C
78.3050 +[0 0.87 0.91 0.83] vc
78.3051 +f
78.3052 +S
78.3053 +n
78.3054 +1977.9 2059.5 m
78.3055 +1975.7 2064.5 1973.7 2054.7 1975.2 2060.9 C
78.3056 +1976 2060.6 1977.6 2059.7 1977.9 2059.5 C
78.3057 +f
78.3058 +S
78.3059 +n
78.3060 +1989.6 2051.3 m
78.3061 +1990.1 2042.3 1989.8 2036.6 1989.9 2028 C
78.3062 +1989.8 2027 1990.8 2028.3 1990.1 2027.3 C
78.3063 +1988.9 2026.7 1986.7 2026.9 1986.8 2024.7 C
78.3064 +1987.4 2023 1985.9 2024.6 1985.1 2023.7 C
78.3065 +1984.1 2021.4 1982.5 2020.5 1980.3 2020.6 C
78.3066 +1979.9 2020.8 1979.5 2021.1 1979.3 2021.6 C
78.3067 +1979.7 2025.8 1978.4 2033 1979.6 2038.1 C
78.3068 +1983.7 2042.9 1968.8 2044.6 1978.8 2042.7 C
78.3069 +1979.3 2042.3 1979.6 2041.9 1980 2041.5 C
78.3070 +1980 2034.8 1980 2027 1980 2021.6 C
78.3071 +1981.3 2020.5 1981.7 2021.5 1982.9 2021.8 C
78.3072 +1983.6 2024.7 1986.1 2023.8 1986.8 2026.4 C
78.3073 +1987.1 2027.7 1988.6 2027.1 1989.2 2028.3 C
78.3074 +1989.1 2036.7 1989.3 2044.8 1988.9 2053.7 C
78.3075 +1987.2 2054.9 1986.2 2056.8 1983.9 2057.1 C
78.3076 +1986.3 2055.9 1990.9 2055 1989.6 2051.3 C
78.3077 +f
78.3078 +S
78.3079 +n
78.3080 +1971.6 2078.9 m
78.3081 +1971.4 2070.5 1972.1 2062.2 1971.6 2055.9 C
78.3082 +1969.9 2053.7 1967.6 2051.7 1965.6 2049.6 C
78.3083 +1961.4 2050.4 1957.6 2053.6 1953.4 2055.2 C
78.3084 +1949.8 2055.6 1948.2 2051.2 1945.5 2049.6 C
78.3085 +1945.1 2048.8 1944.5 2047.9 1943.6 2047.5 C
78.3086 +1940.1 2047.8 1937.3 2051 1934 2052.3 C
78.3087 +1933.7 2052.6 1933.7 2053 1933.2 2053.2 C
78.3088 +1933.7 2060.8 1933.4 2067.2 1933.5 2074.6 C
78.3089 +1933.8 2068.1 1934 2060.9 1933.2 2054 C
78.3090 +1935.3 2050.9 1939.3 2049.6 1942.4 2047.5 C
78.3091 +1942.8 2047.5 1943.4 2047.4 1943.8 2047.7 C
78.3092 +1947.1 2050.2 1950.3 2057.9 1955.3 2054.4 C
78.3093 +1955.4 2054.4 1955.5 2054.3 1955.6 2054.2 C
78.3094 +1955.9 2057.6 1956.1 2061.8 1955.3 2064.8 C
78.3095 +1955.4 2064.3 1955.1 2063.8 1955.6 2063.6 C
78.3096 +1956 2066.6 1955.3 2068.7 1958.7 2069.8 C
78.3097 +1959.2 2071.7 1961.4 2071.7 1962 2074.1 C
78.3098 +1964.4 2074.2 1964 2077.7 1967.3 2078.4 C
78.3099 +1967 2079.7 1968.1 2079.9 1969 2080.1 C
78.3100 +1971.1 2079.9 1970 2079.2 1970.4 2078 C
78.3101 +1969.5 2077.2 1970.3 2075.9 1969.7 2075.1 C
78.3102 +1970.1 2069.8 1970.1 2063.6 1969.7 2058.8 C
78.3103 +1969.2 2058.5 1970 2058.1 1970.2 2057.8 C
78.3104 +1970.4 2058.3 1971.2 2057.7 1971.4 2058.3 C
78.3105 +1971.5 2065.3 1971.2 2073.6 1971.6 2081.1 C
78.3106 +1974.1 2081.4 1969.8 2084.3 1972.4 2082.5 C
78.3107 +1971.9 2081.4 1971.6 2080.2 1971.6 2078.9 C
78.3108 +[0 0.4 1 0] vc
78.3109 +f
78.3110 +S
78.3111 +n
78.3112 +1952.4 2052 m
78.3113 +1954.1 2051.3 1955.6 2050.4 1957.2 2049.6 C
78.3114 +1955.6 2050.4 1954.1 2051.3 1952.4 2052 C
78.3115 +[0 0.87 0.91 0.83] vc
78.3116 +f
78.3117 +S
78.3118 +n
78.3119 +1975.5 2039.8 m
78.3120 +1975.5 2039.4 1974.5 2038.7 1974.8 2038.8 C
78.3121 +1974.6 2039.1 1974.5 2039.1 1974.3 2038.8 C
78.3122 +1974.6 2037.6 1972.5 2039.3 1972.1 2038.4 C
78.3123 +1970.4 2038.4 1970.5 2035.5 1968 2035.7 C
78.3124 +1968.6 2032.5 1964 2033.3 1964 2030.4 C
78.3125 +1961.9 2029.8 1961.4 2026.8 1959.2 2026.8 C
78.3126 +1957.7 2028.5 1952.6 2025.3 1953.9 2029.5 C
78.3127 +1952.9 2031.5 1947 2028.2 1947.9 2032.4 C
78.3128 +1946 2034.2 1941.5 2031.5 1941.9 2035.7 C
78.3129 +1940.6 2036.1 1938.9 2036.1 1937.6 2035.7 C
78.3130 +1937.3 2037.5 1940.7 2038.2 1941.2 2040.3 C
78.3131 +1943.7 2041.1 1944.4 2043.9 1946.4 2045.6 C
78.3132 +1949.1 2046.7 1949.9 2048.8 1952.2 2051.1 C
78.3133 +1959.9 2047.1 1967.7 2043.6 1975.5 2039.8 C
78.3134 +[0 0.01 1 0] vc
78.3135 +f
78.3136 +S
78.3137 +n
78.3138 +vmrs
78.3139 +1962 2047.2 m
78.3140 +1960.2 2047.5 1959.5 2048.9 1957.7 2049.4 C
78.3141 +1959.5 2049.5 1960.3 2047.2 1962 2047.2 C
78.3142 +[0 0.87 0.91 0.83] vc
78.3143 +f
78.3144 +0.4 w
78.3145 +2 J
78.3146 +2 M
78.3147 +S
78.3148 +n
78.3149 +2012.4 2046.3 m
78.3150 +2010.3 2051.3 2008.3 2041.5 2009.8 2047.7 C
78.3151 +2010.5 2047.4 2012.2 2046.5 2012.4 2046.3 C
78.3152 +f
78.3153 +S
78.3154 +n
78.3155 +1944.8 2044.6 m
78.3156 +1945.5 2045.6 1948.6 2048.1 1947.4 2046.8 C
78.3157 +1946.3 2046.5 1945.5 2045.2 1944.8 2044.6 C
78.3158 +f
78.3159 +S
78.3160 +n
78.3161 +1987.2 2054.9 m
78.3162 +1983.7 2057.3 1979.6 2058 1976 2060.2 C
78.3163 +1974.7 2058.2 1977.2 2055.8 1974.3 2054.9 C
78.3164 +1973.1 2052 1970.4 2050.2 1968 2048 C
78.3165 +1968 2047.7 1968 2047.4 1968.3 2047.2 C
78.3166 +1969.5 2046.1 1983 2040.8 1972.4 2044.8 C
78.3167 +1971.2 2046.6 1967.9 2046 1968 2048.2 C
78.3168 +1970.5 2050.7 1973.8 2052.6 1974.3 2055.6 C
78.3169 +1975.1 2055 1975.7 2056.7 1975.7 2057.1 C
78.3170 +1975.7 2058.2 1974.8 2059.3 1975.5 2060.4 C
78.3171 +1979.3 2058.2 1983.9 2057.7 1987.2 2054.9 C
78.3172 +[0.18 0.18 0 0.78] vc
78.3173 +f
78.3174 +S
78.3175 +n
78.3176 +1967.8 2047.5 m
78.3177 +1968.5 2047 1969.1 2046.5 1969.7 2046 C
78.3178 +1969.1 2046.5 1968.5 2047 1967.8 2047.5 C
78.3179 +[0 0.87 0.91 0.83] vc
78.3180 +f
78.3181 +S
78.3182 +n
78.3183 +1976.7 2040.3 m
78.3184 +1976.9 2032.8 1976.3 2024.4 1977.2 2017 C
78.3185 +1976.4 2016.5 1976.6 2014.8 1976.9 2013.9 C
78.3186 +1978.7 2012.7 1977.2 2013 1976.2 2012.9 C
78.3187 +1971.5 2008.1 1965.9 2003.1 1961.8 1998 C
78.3188 +1960.9 1998 1960.1 1998 1959.2 1998 C
78.3189 +1951.5 2001.1 1944.3 2005.5 1937.1 2009.6 C
78.3190 +1935 2012.9 1937 2013.6 1936.1 2017.2 C
78.3191 +1937.1 2017.2 1936 2018 1936.4 2017.7 C
78.3192 +1937 2020.1 1935.5 2022.1 1936.4 2024.9 C
78.3193 +1936.8 2027.2 1936.5 2029.7 1936.6 2032.1 C
78.3194 +1937.4 2028.2 1936 2023.8 1936.8 2020.1 C
78.3195 +1938.3 2015.7 1933.6 2011 1939 2008.6 C
78.3196 +1945.9 2004.5 1953.1 2000.3 1960.6 1998.3 C
78.3197 +1960.9 1998.3 1961.3 1998.3 1961.6 1998.3 C
78.3198 +1966.2 2003.5 1971.8 2008.4 1976.4 2013.6 C
78.3199 +1976.6 2015.5 1976 2018.1 1976.9 2019.2 C
78.3200 +1976.1 2025.8 1976.4 2033.2 1976.7 2040 C
78.3201 +1971.9 2042.4 1967.4 2045 1962.5 2047 C
78.3202 +1967.3 2044.9 1972 2042.6 1976.7 2040.3 C
78.3203 +f
78.3204 +S
78.3205 +n
78.3206 +1939 2038.6 m
78.3207 +1940.6 2040.9 1942.5 2042.1 1944.3 2044.1 C
78.3208 +1942.7 2041.9 1940.6 2040.9 1939 2038.6 C
78.3209 +f
78.3210 +S
78.3211 +n
78.3212 +2006.2 2065.7 m
78.3213 +2006 2057.3 2006.7 2049 2006.2 2042.7 C
78.3214 +2002.1 2038.4 1997.7 2033.4 1993 2030 C
78.3215 +1992.9 2029.3 1992.5 2028.6 1992 2028.3 C
78.3216 +1992.1 2036.6 1991.9 2046.2 1992.3 2054.9 C
78.3217 +1990.8 2056.2 1989 2056.7 1987.5 2058 C
78.3218 +1988.7 2057.7 1990.7 2054.4 1993 2056.4 C
78.3219 +1993.4 2058.8 1996 2058.2 1996.6 2060.9 C
78.3220 +1999 2061 1998.5 2064.5 2001.9 2065.2 C
78.3221 +2001.5 2066.5 2002.7 2066.7 2003.6 2066.9 C
78.3222 +2005.7 2066.7 2004.6 2066 2005 2064.8 C
78.3223 +2004 2064 2004.8 2062.7 2004.3 2061.9 C
78.3224 +2004.6 2056.6 2004.6 2050.4 2004.3 2045.6 C
78.3225 +2003.7 2045.3 2004.6 2044.9 2004.8 2044.6 C
78.3226 +2005 2045.1 2005.7 2044.5 2006 2045.1 C
78.3227 +2006 2052.1 2005.8 2060.4 2006.2 2067.9 C
78.3228 +2008.7 2068.2 2004.4 2071.1 2006.9 2069.3 C
78.3229 +2006.4 2068.2 2006.2 2067 2006.2 2065.7 C
78.3230 +[0 0.4 1 0] vc
78.3231 +f
78.3232 +S
78.3233 +n
78.3234 +2021.8 2041.7 m
78.3235 +2018.3 2044.1 2014.1 2044.8 2010.5 2047 C
78.3236 +2009.3 2045 2011.7 2042.6 2008.8 2041.7 C
78.3237 +2004.3 2035.1 1997.6 2030.9 1993 2024.4 C
78.3238 +1992.1 2024 1991.5 2024.3 1990.8 2024 C
78.3239 +1993.2 2023.9 1995.3 2027.1 1996.8 2029 C
78.3240 +2000.4 2032.6 2004.9 2036.9 2008.4 2040.8 C
78.3241 +2008.2 2043.1 2011.4 2042.8 2009.8 2045.8 C
78.3242 +2009.8 2046.3 2009.7 2046.9 2010 2047.2 C
78.3243 +2013.8 2045 2018.5 2044.5 2021.8 2041.7 C
78.3244 +[0.18 0.18 0 0.78] vc
78.3245 +f
78.3246 +S
78.3247 +n
78.3248 +2001.6 2034 m
78.3249 +2000.7 2033.1 1999.9 2032.3 1999 2031.4 C
78.3250 +1999.9 2032.3 2000.7 2033.1 2001.6 2034 C
78.3251 +[0 0.87 0.91 0.83] vc
78.3252 +f
78.3253 +S
78.3254 +n
78.3255 +vmrs
78.3256 +1989.4 2024.4 m
78.3257 +1989.5 2025.4 1988.6 2024.3 1988.9 2024.7 C
78.3258 +1990.5 2025.8 1990.7 2024.2 1992.8 2024.9 C
78.3259 +1993.8 2025.9 1995 2027.1 1995.9 2028 C
78.3260 +1994.3 2026 1991.9 2023.4 1989.4 2024.4 C
78.3261 +[0 0.87 0.91 0.83] vc
78.3262 +f
78.3263 +0.4 w
78.3264 +2 J
78.3265 +2 M
78.3266 +S
78.3267 +n
78.3268 +1984.8 2019.9 m
78.3269 +1984.6 2018.6 1986.3 2017.2 1987.7 2016.8 C
78.3270 +1987.2 2017.5 1982.9 2017.9 1984.4 2020.6 C
78.3271 +1984.1 2019.9 1984.9 2020 1984.8 2019.9 C
78.3272 +f
78.3273 +S
78.3274 +n
78.3275 +1981.7 2017 m
78.3276 +1979.6 2022 1977.6 2012.3 1979.1 2018.4 C
78.3277 +1979.8 2018.1 1981.5 2017.2 1981.7 2017 C
78.3278 +f
78.3279 +S
78.3280 +n
78.3281 +1884.3 2019.2 m
78.3282 +1884.7 2010.5 1884.5 2000.6 1884.5 1991.8 C
78.3283 +1886.6 1989.3 1889.9 1988.9 1892.4 1987 C
78.3284 +1890.8 1988.7 1886 1989.1 1884.3 1992.3 C
78.3285 +1884.7 2001 1884.5 2011.3 1884.5 2019.9 C
78.3286 +1891 2025.1 1895.7 2031.5 1902 2036.9 C
78.3287 +1896.1 2031 1890 2024.9 1884.3 2019.2 C
78.3288 +[0.07 0.06 0 0.58] vc
78.3289 +f
78.3290 +S
78.3291 +n
78.3292 +1884 2019.4 m
78.3293 +1884.5 2010.6 1884.2 2000.4 1884.3 1991.8 C
78.3294 +1884.8 1990.4 1887.8 1989 1884.8 1990.8 C
78.3295 +1884.3 1991.3 1884.3 1992 1884 1992.5 C
78.3296 +1884.5 2001.2 1884.2 2011.1 1884.3 2019.9 C
78.3297 +1887.9 2023.1 1891.1 2026.4 1894.4 2030 C
78.3298 +1891.7 2026.1 1887.1 2022.9 1884 2019.4 C
78.3299 +[0.4 0.4 0 0] vc
78.3300 +f
78.3301 +S
78.3302 +n
78.3303 +1885 2011.7 m
78.3304 +1885 2006.9 1885 2001.9 1885 1997.1 C
78.3305 +1885 2001.9 1885 2006.9 1885 2011.7 C
78.3306 +[0 0.87 0.91 0.83] vc
78.3307 +f
78.3308 +S
78.3309 +n
78.3310 +1975.5 2036.4 m
78.3311 +1975.2 2028 1976 2019.7 1975.5 2013.4 C
78.3312 +1971.1 2008.5 1965.6 2003.6 1961.6 1999 C
78.3313 +1958.8 1998 1956 2000 1953.6 2001.2 C
78.3314 +1948.2 2004.7 1941.9 2006.5 1937.1 2010.8 C
78.3315 +1937.5 2018.3 1937.3 2024.7 1937.3 2032.1 C
78.3316 +1937.6 2025.6 1937.9 2018.4 1937.1 2011.5 C
78.3317 +1937.3 2011 1937.6 2010.5 1937.8 2010 C
78.3318 +1944.6 2005.7 1951.9 2002.3 1959.2 1999 C
78.3319 +1960.1 1998.5 1960.1 1999.8 1960.4 2000.4 C
78.3320 +1959.7 2006.9 1959.7 2014.2 1959.4 2021.1 C
78.3321 +1959 2021.1 1959.2 2021.9 1959.2 2022.3 C
78.3322 +1959.2 2021.9 1959 2021.3 1959.4 2021.1 C
78.3323 +1959.8 2024.1 1959.2 2026.2 1962.5 2027.3 C
78.3324 +1963 2029.2 1965.3 2029.2 1965.9 2031.6 C
78.3325 +1968.3 2031.8 1967.8 2035.2 1971.2 2036 C
78.3326 +1970.8 2037.2 1971.9 2037.5 1972.8 2037.6 C
78.3327 +1974.9 2037.4 1973.9 2036.7 1974.3 2035.5 C
78.3328 +1973.3 2034.7 1974.1 2033.4 1973.6 2032.6 C
78.3329 +1973.9 2027.3 1973.9 2021.1 1973.6 2016.3 C
78.3330 +1973 2016 1973.9 2015.6 1974 2015.3 C
78.3331 +1974.3 2015.9 1975 2015.3 1975.2 2015.8 C
78.3332 +1975.3 2022.8 1975.1 2031.2 1975.5 2038.6 C
78.3333 +1977.9 2039 1973.7 2041.8 1976.2 2040 C
78.3334 +1975.7 2039 1975.5 2037.8 1975.5 2036.4 C
78.3335 +[0 0.4 1 0] vc
78.3336 +f
78.3337 +S
78.3338 +n
78.3339 +1991.1 2012.4 m
78.3340 +1987.5 2014.8 1983.4 2015.6 1979.8 2017.7 C
78.3341 +1978.5 2015.7 1981 2013.3 1978.1 2012.4 C
78.3342 +1973.6 2005.8 1966.8 2001.6 1962.3 1995.2 C
78.3343 +1961.4 1994.7 1960.8 1995 1960.1 1994.7 C
78.3344 +1962.5 1994.6 1964.6 1997.8 1966.1 1999.7 C
78.3345 +1969.7 2003.3 1974.2 2007.6 1977.6 2011.5 C
78.3346 +1977.5 2013.8 1980.6 2013.5 1979.1 2016.5 C
78.3347 +1979.1 2017 1979 2017.6 1979.3 2018 C
78.3348 +1983.1 2015.7 1987.8 2015.2 1991.1 2012.4 C
78.3349 +[0.18 0.18 0 0.78] vc
78.3350 +f
78.3351 +S
78.3352 +n
78.3353 +1970.9 2004.8 m
78.3354 +1970 2003.9 1969.2 2003 1968.3 2002.1 C
78.3355 +1969.2 2003 1970 2003.9 1970.9 2004.8 C
78.3356 +[0 0.87 0.91 0.83] vc
78.3357 +f
78.3358 +S
78.3359 +n
78.3360 +1887.9 1994.9 m
78.3361 +1888.5 1992.3 1891.4 1992.2 1893.2 1990.8 C
78.3362 +1898.4 1987.5 1904 1984.8 1909.5 1982.2 C
78.3363 +1909.7 1982.7 1910.3 1982.1 1910.4 1982.7 C
78.3364 +1909.5 1990.5 1910.1 1996.4 1910 2004.5 C
78.3365 +1909.1 2003.4 1909.7 2005.8 1909.5 2006.4 C
78.3366 +1910.4 2006 1909.7 2008 1910.2 2007.9 C
78.3367 +1911.3 2010.6 1912.5 2012.6 1915.7 2013.4 C
78.3368 +1915.8 2013.7 1915.5 2014.4 1916 2014.4 C
78.3369 +1916.3 2015 1915.4 2016 1915.2 2016 C
78.3370 +1916.1 2015.5 1916.5 2014.5 1916 2013.6 C
78.3371 +1913.4 2013.3 1913.1 2010.5 1910.9 2009.8 C
78.3372 +1910.7 2008.8 1910.4 2007.9 1910.2 2006.9 C
78.3373 +1911.1 1998.8 1909.4 1990.7 1910.7 1982.4 C
78.3374 +1910 1982.1 1908.9 1982.1 1908.3 1982.4 C
78.3375 +1901.9 1986.1 1895 1988.7 1888.8 1993 C
78.3376 +1888 1993.4 1888.4 1994.3 1887.6 1994.7 C
78.3377 +1888.1 2001.3 1887.8 2008.6 1887.9 2015.1 C
78.3378 +1887.3 2017.5 1887.9 2015.4 1888.4 2014.4 C
78.3379 +1887.8 2008 1888.4 2001.3 1887.9 1994.9 C
78.3380 +[0.07 0.06 0 0.58] vc
78.3381 +f
78.3382 +S
78.3383 +n
78.3384 +vmrs
78.3385 +1887.9 2018.4 m
78.3386 +1887.5 2016.9 1888.5 2016 1888.8 2014.8 C
78.3387 +1890.1 2014.8 1891.1 2016.6 1892.4 2015.3 C
78.3388 +1892.4 2014.4 1893.8 2012.9 1894.4 2012.4 C
78.3389 +1895.9 2012.4 1896.6 2013.9 1897.7 2012.7 C
78.3390 +1898.4 2011.7 1898.6 2010.4 1899.6 2009.8 C
78.3391 +1901.7 2009.9 1902.9 2010.4 1904 2009.1 C
78.3392 +1904.3 2007.4 1904 2007.6 1904.9 2007.2 C
78.3393 +1906.2 2007 1907.6 2006.5 1908.8 2006.7 C
78.3394 +1910.6 2008.2 1909.8 2011.5 1912.6 2012 C
78.3395 +1912.4 2013 1913.8 2012.7 1914 2013.2 C
78.3396 +1911.5 2011.1 1909.1 2007.9 1909.2 2004.3 C
78.3397 +1909.5 2003.5 1909.9 2004.9 1909.7 2004.3 C
78.3398 +1909.9 1996.2 1909.3 1990.5 1910.2 1982.7 C
78.3399 +1909.5 1982.6 1909.5 1982.6 1908.8 1982.7 C
78.3400 +1903.1 1985.7 1897 1987.9 1891.7 1992 C
78.3401 +1890.5 1993 1888.2 1992.9 1888.1 1994.9 C
78.3402 +1888.7 2001.4 1888.1 2008.4 1888.6 2014.8 C
78.3403 +1888.3 2016 1887.2 2016.9 1887.6 2018.4 C
78.3404 +1892.3 2023.9 1897.6 2027.9 1902.3 2033.3 C
78.3405 +1898 2028.2 1892.1 2023.8 1887.9 2018.4 C
78.3406 +[0.4 0.4 0 0] vc
78.3407 +f
78.3408 +0.4 w
78.3409 +2 J
78.3410 +2 M
78.3411 +S
78.3412 +n
78.3413 +1910.9 1995.2 m
78.3414 +1910.4 1999.8 1911 2003.3 1910.9 2008.1 C
78.3415 +1910.9 2003.8 1910.9 1999.2 1910.9 1995.2 C
78.3416 +[0.18 0.18 0 0.78] vc
78.3417 +f
78.3418 +S
78.3419 +n
78.3420 +1911.2 2004.3 m
78.3421 +1911.2 2001.9 1911.2 1999.7 1911.2 1997.3 C
78.3422 +1911.2 1999.7 1911.2 2001.9 1911.2 2004.3 C
78.3423 +[0 0.87 0.91 0.83] vc
78.3424 +f
78.3425 +S
78.3426 +n
78.3427 +1958.7 1995.2 m
78.3428 +1959 1995.6 1956.2 1995 1956.5 1996.8 C
78.3429 +1955.8 1997.6 1954.2 1998.5 1953.6 1997.3 C
78.3430 +1953.6 1990.8 1954.9 1989.6 1953.4 1983.9 C
78.3431 +1953.4 1983.3 1953.3 1982.1 1954.4 1982 C
78.3432 +1955.5 1982.6 1956.5 1981.3 1957.5 1981 C
78.3433 +1956.3 1981.8 1954.7 1982.6 1953.9 1981.5 C
78.3434 +1951.4 1983 1954.7 1988.8 1952.9 1990.6 C
78.3435 +1953.8 1990.6 1953.2 1992.7 1953.4 1993.7 C
78.3436 +1953.8 1994.5 1952.3 1996.1 1953.2 1997.8 C
78.3437 +1956.3 1999.4 1957.5 1994 1959.9 1995.6 C
78.3438 +1962 1994.4 1963.7 1997.7 1965.2 1998.8 C
78.3439 +1963.5 1996.7 1961.2 1994.1 1958.7 1995.2 C
78.3440 +f
78.3441 +S
78.3442 +n
78.3443 +1945 2000.7 m
78.3444 +1945.4 1998.7 1945.4 1997.9 1945 1995.9 C
78.3445 +1944.5 1995.3 1944.2 1992.6 1945.7 1993.2 C
78.3446 +1946 1992.2 1948.7 1992.5 1948.4 1990.6 C
78.3447 +1947.5 1990.3 1948.1 1988.7 1947.9 1988.2 C
78.3448 +1948.9 1987.8 1950.5 1986.8 1950.5 1984.6 C
78.3449 +1951.5 1980.9 1946.7 1983 1947.2 1979.8 C
78.3450 +1944.5 1979.9 1945.2 1976.6 1943.1 1976.7 C
78.3451 +1941.8 1975.7 1942.1 1972.7 1939.2 1973.8 C
78.3452 +1938.2 1974.6 1939.3 1971.6 1938.3 1970.9 C
78.3453 +1938.8 1969.2 1933.4 1970.3 1937.3 1970 C
78.3454 +1939.4 1971.2 1937.2 1973 1937.6 1974.3 C
78.3455 +1937.2 1976.3 1937.1 1981.2 1937.8 1984.1 C
78.3456 +1938.8 1982.3 1937.9 1976.6 1938.5 1973.1 C
78.3457 +1938.9 1975 1938.5 1976.4 1939.7 1977.2 C
78.3458 +1939.5 1983.5 1938.9 1991.3 1940.2 1997.3 C
78.3459 +1939.4 1999.1 1938.6 1997.1 1937.8 1997.1 C
78.3460 +1937.4 1996.7 1937.6 1996.1 1937.6 1995.6 C
78.3461 +1936.5 1998.5 1940.1 1998.4 1940.9 2000.7 C
78.3462 +1942.1 2000.4 1943.2 2001.3 1943.1 2002.4 C
78.3463 +1943.6 2003.1 1941.1 2004.6 1942.8 2003.8 C
78.3464 +1943.9 2002.5 1942.6 2000.6 1945 2000.7 C
78.3465 +[0.65 0.65 0 0.42] vc
78.3466 +f
78.3467 +S
78.3468 +n
78.3469 +1914.5 2006.4 m
78.3470 +1914.1 2004.9 1915.2 2004 1915.5 2002.8 C
78.3471 +1916.7 2002.8 1917.8 2004.6 1919.1 2003.3 C
78.3472 +1919 2002.4 1920.4 2000.9 1921 2000.4 C
78.3473 +1922.5 2000.4 1923.2 2001.9 1924.4 2000.7 C
78.3474 +1925 1999.7 1925.3 1998.4 1926.3 1997.8 C
78.3475 +1928.4 1997.9 1929.5 1998.4 1930.6 1997.1 C
78.3476 +1930.9 1995.4 1930.7 1995.6 1931.6 1995.2 C
78.3477 +1932.8 1995 1934.3 1994.5 1935.4 1994.7 C
78.3478 +1936.1 1995.8 1936.9 1996.2 1936.6 1997.8 C
78.3479 +1938.9 1999.4 1939.7 2001.3 1942.4 2002.4 C
78.3480 +1942.4 2002.5 1942.2 2003 1942.6 2002.8 C
78.3481 +1942.9 2000.4 1939.2 2001.8 1939.2 1999.7 C
78.3482 +1936.2 1998.6 1937 1995.3 1935.9 1993.5 C
78.3483 +1937.1 1986.5 1935.2 1977.9 1937.6 1971.2 C
78.3484 +1937.6 1970.3 1936.6 1971 1936.4 1970.4 C
78.3485 +1930.2 1973.4 1924 1976 1918.4 1980 C
78.3486 +1917.2 1981 1914.9 1980.9 1914.8 1982.9 C
78.3487 +1915.3 1989.4 1914.7 1996.4 1915.2 2002.8 C
78.3488 +1914.9 2004 1913.9 2004.9 1914.3 2006.4 C
78.3489 +1919 2011.9 1924.2 2015.9 1928.9 2021.3 C
78.3490 +1924.6 2016.2 1918.7 2011.8 1914.5 2006.4 C
78.3491 +[0.4 0.4 0 0] vc
78.3492 +f
78.3493 +S
78.3494 +n
78.3495 +1914.5 1982.9 m
78.3496 +1915.1 1980.3 1918 1980.2 1919.8 1978.8 C
78.3497 +1925 1975.5 1930.6 1972.8 1936.1 1970.2 C
78.3498 +1939.4 1970.6 1936.1 1974.2 1936.6 1976.4 C
78.3499 +1936.5 1981.9 1936.8 1987.5 1936.4 1992.8 C
78.3500 +1935.9 1992.8 1936.2 1993.5 1936.1 1994 C
78.3501 +1937.1 1993.6 1936.2 1995.9 1936.8 1995.9 C
78.3502 +1937 1998 1939.5 1999.7 1940.4 2000.7 C
78.3503 +1940.1 1998.6 1935 1997.2 1937.6 1993.7 C
78.3504 +1938.3 1985.7 1935.9 1976.8 1937.8 1970.7 C
78.3505 +1936.9 1969.8 1935.4 1970.3 1934.4 1970.7 C
78.3506 +1928.3 1974.4 1921.4 1976.7 1915.5 1981 C
78.3507 +1914.6 1981.4 1915.1 1982.3 1914.3 1982.7 C
78.3508 +1914.7 1989.3 1914.5 1996.6 1914.5 2003.1 C
78.3509 +1913.9 2005.5 1914.5 2003.4 1915 2002.4 C
78.3510 +1914.5 1996 1915.1 1989.3 1914.5 1982.9 C
78.3511 +[0.07 0.06 0 0.58] vc
78.3512 +f
78.3513 +S
78.3514 +n
78.3515 +1939.2 1994.9 m
78.3516 +1939.3 1995 1939.4 1995.1 1939.5 1995.2 C
78.3517 +1939.1 1989 1939.3 1981.6 1939 1976.7 C
78.3518 +1938.6 1976.3 1938.6 1974.6 1938.5 1973.3 C
78.3519 +1938.7 1976.1 1938.1 1979.4 1939 1981.7 C
78.3520 +1937.3 1986 1937.7 1991.6 1938 1996.4 C
78.3521 +1937.3 1994.3 1939.6 1996.2 1939.2 1994.9 C
78.3522 +[0.18 0.18 0 0.78] vc
78.3523 +f
78.3524 +S
78.3525 +n
78.3526 +1938.3 1988.4 m
78.3527 +1938.5 1990.5 1937.9 1994.1 1938.8 1994.7 C
78.3528 +1937.9 1992.6 1939 1990.6 1938.3 1988.4 C
78.3529 +[0 0.87 0.91 0.83] vc
78.3530 +f
78.3531 +S
78.3532 +n
78.3533 +1938.8 1985.8 m
78.3534 +1938.5 1985.9 1938.4 1985.7 1938.3 1985.6 C
78.3535 +1938.4 1986.2 1938 1989.5 1938.8 1987.2 C
78.3536 +1938.8 1986.8 1938.8 1986.3 1938.8 1985.8 C
78.3537 +f
78.3538 +S
78.3539 +n
78.3540 +vmrs
78.3541 +1972.8 2062.1 m
78.3542 +1971.9 2061 1972.5 2059.4 1972.4 2058 C
78.3543 +1972.2 2063.8 1971.9 2073.7 1972.4 2081.3 C
78.3544 +1972.5 2074.9 1971.9 2067.9 1972.8 2062.1 C
78.3545 +[0 1 1 0.36] vc
78.3546 +f
78.3547 +0.4 w
78.3548 +2 J
78.3549 +2 M
78.3550 +S
78.3551 +n
78.3552 +1940.2 2071.7 m
78.3553 +1941.3 2072 1943.1 2072.3 1944 2071.5 C
78.3554 +1943.6 2069.9 1945.2 2069.1 1946 2068.8 C
78.3555 +1950 2071.1 1948.7 2065.9 1951.7 2066.2 C
78.3556 +1953.5 2063.9 1956.9 2069.4 1955.6 2063.8 C
78.3557 +1955.5 2064.2 1955.7 2064.8 1955.3 2065 C
78.3558 +1954.3 2063.7 1956.2 2063.6 1955.6 2062.1 C
78.3559 +1954.5 2060 1958.3 2050.3 1952.2 2055.6 C
78.3560 +1949.1 2053.8 1946 2051 1943.8 2048 C
78.3561 +1940.3 2048 1937.5 2051.3 1934.2 2052.5 C
78.3562 +1933.1 2054.6 1934.4 2057.3 1934 2060 C
78.3563 +1934 2065.1 1934 2069.7 1934 2074.6 C
78.3564 +1934.4 2069 1934.1 2061.5 1934.2 2054.9 C
78.3565 +1934.6 2054.5 1935.3 2054.7 1935.9 2054.7 C
78.3566 +1937 2055.3 1935.9 2056.1 1935.9 2056.8 C
78.3567 +1936.5 2063 1935.6 2070.5 1935.9 2074.6 C
78.3568 +1936.7 2074.4 1937.3 2075.2 1938 2074.6 C
78.3569 +1937.9 2073.6 1939.1 2072.1 1940.2 2071.7 C
78.3570 +[0 0.2 1 0] vc
78.3571 +f
78.3572 +S
78.3573 +n
78.3574 +1933.2 2074.1 m
78.3575 +1933.2 2071.5 1933.2 2069 1933.2 2066.4 C
78.3576 +1933.2 2069 1933.2 2071.5 1933.2 2074.1 C
78.3577 +[0 1 1 0.36] vc
78.3578 +f
78.3579 +S
78.3580 +n
78.3581 +2007.4 2048.9 m
78.3582 +2006.5 2047.8 2007.1 2046.2 2006.9 2044.8 C
78.3583 +2006.7 2050.6 2006.5 2060.5 2006.9 2068.1 C
78.3584 +2007.1 2061.7 2006.5 2054.7 2007.4 2048.9 C
78.3585 +f
78.3586 +S
78.3587 +n
78.3588 +1927.2 2062.4 m
78.3589 +1925.8 2060.1 1928.1 2058.2 1927 2056.4 C
78.3590 +1927.3 2055.5 1926.5 2053.5 1926.8 2051.8 C
78.3591 +1926.8 2052.8 1926 2052.5 1925.3 2052.5 C
78.3592 +1924.1 2052.8 1925 2050.5 1924.4 2050.1 C
78.3593 +1925.3 2050.2 1925.4 2048.8 1926.3 2049.4 C
78.3594 +1926.5 2052.3 1928.4 2047.2 1928.4 2051.1 C
78.3595 +1928.9 2050.5 1929 2051.4 1928.9 2051.8 C
78.3596 +1928.9 2052 1928.9 2052.3 1928.9 2052.5 C
78.3597 +1929.4 2051.4 1928.9 2049 1930.1 2048.2 C
78.3598 +1928.9 2047.1 1930.5 2047.1 1930.4 2046.5 C
78.3599 +1931.9 2046.2 1933.1 2046.1 1934.7 2046.5 C
78.3600 +1934.6 2046.9 1935.2 2047.9 1934.4 2048.4 C
78.3601 +1936.9 2048.1 1933.6 2043.8 1935.9 2043.9 C
78.3602 +1935.7 2043.9 1934.8 2041.3 1933.2 2041.7 C
78.3603 +1932.5 2041.6 1932.4 2039.6 1932.3 2041 C
78.3604 +1930.8 2042.6 1929 2040.6 1927.7 2042 C
78.3605 +1927.5 2041.4 1927.1 2040.9 1927.2 2040.3 C
78.3606 +1927.8 2040.6 1927.4 2039.1 1928.2 2038.6 C
78.3607 +1929.4 2038 1930.5 2038.8 1931.3 2037.9 C
78.3608 +1931.7 2039 1932.5 2038.6 1931.8 2037.6 C
78.3609 +1930.9 2037 1928.7 2037.8 1928.2 2037.9 C
78.3610 +1926.7 2037.8 1928 2039 1927 2038.8 C
78.3611 +1927.4 2040.4 1925.6 2040.8 1925.1 2041 C
78.3612 +1924.3 2040.4 1923.2 2040.5 1922.2 2040.5 C
78.3613 +1921.4 2041.7 1921 2043.9 1919.3 2043.9 C
78.3614 +1918.8 2043.4 1917.2 2043.3 1916.4 2043.4 C
78.3615 +1915.9 2044.4 1915.7 2046 1914.3 2046.5 C
78.3616 +1913.1 2046.6 1912 2044.5 1911.4 2046.3 C
78.3617 +1912.8 2046.5 1913.8 2047.4 1915.7 2047 C
78.3618 +1916.9 2047.7 1915.6 2048.8 1916 2049.4 C
78.3619 +1915.4 2049.3 1913.9 2050.3 1913.3 2051.1 C
78.3620 +1913.9 2054.1 1916 2050.2 1916.7 2053 C
78.3621 +1916.9 2053.8 1915.5 2054.1 1916.7 2054.4 C
78.3622 +1917 2054.7 1920.2 2054.3 1919.3 2056.6 C
78.3623 +1918.8 2056.1 1920.2 2058.6 1920.3 2057.6 C
78.3624 +1921.2 2057.9 1922.1 2057.5 1922.4 2059 C
78.3625 +1922.3 2059.1 1922.2 2059.3 1922 2059.2 C
78.3626 +1922.1 2059.7 1922.4 2060.3 1922.9 2060.7 C
78.3627 +1923.2 2060.1 1923.8 2060.4 1924.6 2060.7 C
78.3628 +1925.9 2062.6 1923.2 2062 1925.6 2063.6 C
78.3629 +1926.1 2063.1 1927.3 2062.5 1927.2 2062.4 C
78.3630 +[0.21 0.21 0 0] vc
78.3631 +f
78.3632 +S
78.3633 +n
78.3634 +1933.2 2063.3 m
78.3635 +1933.2 2060.7 1933.2 2058.2 1933.2 2055.6 C
78.3636 +1933.2 2058.2 1933.2 2060.7 1933.2 2063.3 C
78.3637 +[0 1 1 0.36] vc
78.3638 +f
78.3639 +S
78.3640 +n
78.3641 +1965.2 2049.2 m
78.3642 +1967.1 2050.1 1969.9 2053.7 1972.1 2056.4 C
78.3643 +1970.5 2054 1967.6 2051.3 1965.2 2049.2 C
78.3644 +f
78.3645 +S
78.3646 +n
78.3647 +1991.8 2034.8 m
78.3648 +1991.7 2041.5 1992 2048.5 1991.6 2055.2 C
78.3649 +1990.5 2056.4 1991.9 2054.9 1991.8 2054.4 C
78.3650 +1991.8 2047.9 1991.8 2041.3 1991.8 2034.8 C
78.3651 +f
78.3652 +S
78.3653 +n
78.3654 +1988.9 2053.2 m
78.3655 +1988.9 2044.3 1988.9 2036.6 1988.9 2028.3 C
78.3656 +1985.7 2028.2 1987.2 2023.5 1983.9 2024.2 C
78.3657 +1983.9 2022.4 1982 2021.6 1981 2021.3 C
78.3658 +1980.6 2021.1 1980.6 2021.7 1980.3 2021.6 C
78.3659 +1980.3 2027 1980.3 2034.8 1980.3 2041.5 C
78.3660 +1979.3 2043.2 1977.6 2043 1976.2 2043.6 C
78.3661 +1977.1 2043.8 1978.5 2043.2 1978.8 2044.1 C
78.3662 +1978.5 2045.3 1979.9 2045.3 1980.3 2045.8 C
78.3663 +1980.5 2046.8 1980.7 2046.2 1981.5 2046.5 C
78.3664 +1982.4 2047.1 1982 2048.6 1982.7 2049.4 C
78.3665 +1984.2 2049.6 1984.6 2052.2 1986.8 2051.6 C
78.3666 +1987.1 2048.6 1985.1 2042.7 1986.5 2040.5 C
78.3667 +1986.3 2036.7 1986.9 2031.7 1986 2029.2 C
78.3668 +1986.3 2027.1 1986.9 2028.6 1987.7 2027.6 C
78.3669 +1987.7 2028.3 1988.7 2028 1988.7 2028.8 C
78.3670 +1988.1 2033 1988.7 2037.5 1988.2 2041.7 C
78.3671 +1987.8 2041.4 1988 2040.8 1988 2040.3 C
78.3672 +1988 2041 1988 2042.4 1988 2042.4 C
78.3673 +1988 2042.4 1988.1 2042.3 1988.2 2042.2 C
78.3674 +1989.3 2046 1988 2050.2 1988.4 2054 C
78.3675 +1987.8 2054.4 1987.1 2054.7 1986.5 2055.4 C
78.3676 +1987.4 2054.4 1988.4 2054.6 1988.9 2053.2 C
78.3677 +[0 1 1 0.23] vc
78.3678 +f
78.3679 +S
78.3680 +n
78.3681 +1950.8 2054.4 m
78.3682 +1949.7 2053.4 1948.7 2052.3 1947.6 2051.3 C
78.3683 +1948.7 2052.3 1949.7 2053.4 1950.8 2054.4 C
78.3684 +[0 1 1 0.36] vc
78.3685 +f
78.3686 +S
78.3687 +n
78.3688 +vmrs
78.3689 +2006.7 2043.2 m
78.3690 +2004.5 2040.8 2002.4 2038.4 2000.2 2036 C
78.3691 +2002.4 2038.4 2004.5 2040.8 2006.7 2043.2 C
78.3692 +[0 1 1 0.36] vc
78.3693 +f
78.3694 +0.4 w
78.3695 +2 J
78.3696 +2 M
78.3697 +S
78.3698 +n
78.3699 +1976.7 2019.6 m
78.3700 +1975.8 2018.6 1976.4 2016.9 1976.2 2015.6 C
78.3701 +1976 2021.3 1975.8 2031.2 1976.2 2038.8 C
78.3702 +1976.4 2032.4 1975.8 2025.5 1976.7 2019.6 C
78.3703 +f
78.3704 +S
78.3705 +n
78.3706 +1988.4 2053.5 m
78.3707 +1988.6 2049.2 1988.1 2042.8 1988 2040 C
78.3708 +1988.4 2040.4 1988.1 2041 1988.2 2041.5 C
78.3709 +1988.3 2037.2 1988 2032.7 1988.4 2028.5 C
78.3710 +1987.6 2027.1 1987.2 2028.6 1986.8 2028 C
78.3711 +1985.9 2028.5 1986.5 2029.7 1986.3 2030.4 C
78.3712 +1986.9 2029.8 1986.6 2031 1987 2031.2 C
78.3713 +1987.4 2039.6 1985 2043 1987.2 2050.4 C
78.3714 +1987.2 2051.6 1985.9 2052.3 1984.6 2051.3 C
78.3715 +1981.9 2049.7 1982.9 2047 1980.3 2046.5 C
78.3716 +1980.3 2045.2 1978.1 2046.2 1978.6 2043.9 C
78.3717 +1975.6 2043.3 1979.3 2045.6 1979.6 2046.5 C
78.3718 +1980.8 2046.6 1981.5 2048.5 1982.2 2049.9 C
78.3719 +1983.7 2050.8 1984.8 2052.8 1986.5 2053 C
78.3720 +1986.7 2053.5 1987.5 2054.1 1987 2054.7 C
78.3721 +1987.4 2053.9 1988.3 2054.3 1988.4 2053.5 C
78.3722 +[0 1 1 0.23] vc
78.3723 +f
78.3724 +S
78.3725 +n
78.3726 +1988 2038.1 m
78.3727 +1988 2036.7 1988 2035.4 1988 2034 C
78.3728 +1988 2035.4 1988 2036.7 1988 2038.1 C
78.3729 +[0 1 1 0.36] vc
78.3730 +f
78.3731 +S
78.3732 +n
78.3733 +1999.7 2035.7 m
78.3734 +1997.6 2033.5 1995.4 2031.2 1993.2 2029 C
78.3735 +1995.4 2031.2 1997.6 2033.5 1999.7 2035.7 C
78.3736 +f
78.3737 +S
78.3738 +n
78.3739 +1944 2029.2 m
78.3740 +1945.2 2029.5 1946.9 2029.8 1947.9 2029 C
78.3741 +1947.4 2027.4 1949 2026.7 1949.8 2026.4 C
78.3742 +1953.9 2028.6 1952.6 2023.4 1955.6 2023.7 C
78.3743 +1957.4 2021.4 1960.7 2027 1959.4 2021.3 C
78.3744 +1959.3 2021.7 1959.6 2022.3 1959.2 2022.5 C
78.3745 +1958.1 2021.2 1960.1 2021.1 1959.4 2019.6 C
78.3746 +1959.1 2012.7 1959.9 2005.1 1959.6 1999.2 C
78.3747 +1955.3 2000.1 1951.3 2003.1 1947.2 2005 C
78.3748 +1943.9 2006 1941.2 2008.7 1938 2010 C
78.3749 +1936.9 2012.1 1938.2 2014.8 1937.8 2017.5 C
78.3750 +1937.8 2022.6 1937.8 2027.3 1937.8 2032.1 C
78.3751 +1938.2 2026.5 1938 2019 1938 2012.4 C
78.3752 +1938.5 2012 1939.2 2012.3 1939.7 2012.2 C
78.3753 +1940.8 2012.8 1939.7 2013.6 1939.7 2014.4 C
78.3754 +1940.4 2020.5 1939.4 2028 1939.7 2032.1 C
78.3755 +1940.6 2031.9 1941.2 2032.7 1941.9 2032.1 C
78.3756 +1941.7 2031.2 1943 2029.7 1944 2029.2 C
78.3757 +[0 0.2 1 0] vc
78.3758 +f
78.3759 +S
78.3760 +n
78.3761 +1937.1 2031.6 m
78.3762 +1937.1 2029.1 1937.1 2026.5 1937.1 2024 C
78.3763 +1937.1 2026.5 1937.1 2029.1 1937.1 2031.6 C
78.3764 +[0 1 1 0.36] vc
78.3765 +f
78.3766 +S
78.3767 +n
78.3768 +1991.8 2028 m
78.3769 +1992.5 2027.8 1993.2 2029.9 1994 2030.2 C
78.3770 +1992.9 2029.6 1993.1 2028.1 1991.8 2028 C
78.3771 +[0 1 1 0.23] vc
78.3772 +f
78.3773 +S
78.3774 +n
78.3775 +1991.8 2027.8 m
78.3776 +1992.4 2027.6 1992.6 2028.3 1993 2028.5 C
78.3777 +1992.6 2028.2 1992.2 2027.6 1991.6 2027.8 C
78.3778 +1991.6 2028.5 1991.6 2029.1 1991.6 2029.7 C
78.3779 +1991.6 2029.1 1991.4 2028.3 1991.8 2027.8 C
78.3780 +[0 1 1 0.36] vc
78.3781 +f
78.3782 +S
78.3783 +n
78.3784 +1985.8 2025.4 m
78.3785 +1985.3 2025.2 1984.8 2024.7 1984.1 2024.9 C
78.3786 +1983.3 2025.3 1983.6 2027.3 1983.9 2027.6 C
78.3787 +1985 2028 1986.9 2026.9 1985.8 2025.4 C
78.3788 +[0 1 1 0.23] vc
78.3789 +f
78.3790 +S
78.3791 +n
78.3792 +vmrs
78.3793 +1993.5 2024.4 m
78.3794 +1992.4 2023.7 1991.3 2022.9 1990.1 2023.2 C
78.3795 +1990.7 2023.7 1989.8 2023.8 1989.4 2023.7 C
78.3796 +1989.1 2023.7 1988.6 2023.9 1988.4 2023.5 C
78.3797 +1988.5 2023.2 1988.3 2022.7 1988.7 2022.5 C
78.3798 +1989 2022.6 1988.9 2023 1988.9 2023.2 C
78.3799 +1989.1 2022.8 1990.4 2022.3 1990.6 2021.3 C
78.3800 +1990.4 2021.8 1990 2021.3 1990.1 2021.1 C
78.3801 +1990.1 2020.9 1990.1 2020.1 1990.1 2020.6 C
78.3802 +1989.9 2021.1 1989.5 2020.6 1989.6 2020.4 C
78.3803 +1989.6 2019.8 1988.7 2019.6 1988.2 2019.2 C
78.3804 +1987.5 2018.7 1987.7 2020.2 1987 2019.4 C
78.3805 +1987.5 2020.4 1986 2021.1 1987.5 2021.8 C
78.3806 +1986.8 2023.1 1986.6 2021.1 1986 2021.1 C
78.3807 +1986.1 2020.1 1985.9 2019 1986.3 2018.2 C
78.3808 +1986.7 2018.4 1986.5 2019 1986.5 2019.4 C
78.3809 +1986.5 2018.7 1986.4 2017.8 1987.2 2017.7 C
78.3810 +1986.5 2017.2 1985.5 2019.3 1985.3 2020.4 C
78.3811 +1986.2 2022 1987.3 2023.5 1989.2 2024.2 C
78.3812 +1990.8 2024.3 1991.6 2022.9 1993.2 2024.4 C
78.3813 +1993.8 2025.4 1995 2026.6 1995.9 2027.1 C
78.3814 +1995 2026.5 1994.1 2025.5 1993.5 2024.4 C
78.3815 +[0 1 1 0.36] vc
78.3816 +f
78.3817 +0.4 w
78.3818 +2 J
78.3819 +2 M
78.3820 +[0 0.5 0.5 0.2] vc
78.3821 +S
78.3822 +n
78.3823 +2023 2040.3 m
78.3824 +2023.2 2036 2022.7 2029.6 2022.5 2026.8 C
78.3825 +2022.9 2027.2 2022.7 2027.8 2022.8 2028.3 C
78.3826 +2022.8 2024 2022.6 2019.5 2023 2015.3 C
78.3827 +2022.2 2013.9 2021.7 2015.4 2021.3 2014.8 C
78.3828 +2020.4 2015.3 2021 2016.5 2020.8 2017.2 C
78.3829 +2021.4 2016.6 2021.1 2017.8 2021.6 2018 C
78.3830 +2022 2026.4 2019.6 2029.8 2021.8 2037.2 C
78.3831 +2021.7 2038.4 2020.5 2039.1 2019.2 2038.1 C
78.3832 +2016.5 2036.5 2017.5 2033.8 2014.8 2033.3 C
78.3833 +2014.9 2032 2012.6 2033 2013.2 2030.7 C
78.3834 +2011.9 2030.8 2011.2 2030.1 2010.8 2029.2 C
78.3835 +2010.8 2029.1 2010.8 2028.2 2010.8 2028.8 C
78.3836 +2010 2028.8 2010.4 2026.5 2008.6 2027.3 C
78.3837 +2007.9 2026.6 2007.3 2025.9 2007.9 2027.1 C
78.3838 +2009.7 2028 2010 2030.1 2012.2 2030.9 C
78.3839 +2012.9 2032.1 2013.7 2033.6 2015.1 2033.6 C
78.3840 +2015.7 2035.1 2016.9 2036.7 2018.4 2038.4 C
78.3841 +2019.8 2039.3 2022 2039.4 2021.6 2041.5 C
78.3842 +2021.9 2040.7 2022.9 2041.1 2023 2040.3 C
78.3843 +[0 1 1 0.23] vc
78.3844 +f
78.3845 +S
78.3846 +n
78.3847 +2022.5 2024.9 m
78.3848 +2022.5 2023.5 2022.5 2022.2 2022.5 2020.8 C
78.3849 +2022.5 2022.2 2022.5 2023.5 2022.5 2024.9 C
78.3850 +[0 1 1 0.36] vc
78.3851 +f
78.3852 +S
78.3853 +n
78.3854 +1983.2 2022.8 m
78.3855 +1982.4 2022.5 1982.1 2021.6 1981.2 2022.3 C
78.3856 +1981.1 2022.9 1980.5 2024 1981 2024.2 C
78.3857 +1981.8 2024.6 1982.9 2024.4 1983.2 2022.8 C
78.3858 +[0 1 1 0.23] vc
78.3859 +f
78.3860 +S
78.3861 +n
78.3862 +1931.1 2019.9 m
78.3863 +1929.6 2017.7 1932 2015.7 1930.8 2013.9 C
78.3864 +1931.1 2013 1930.3 2011 1930.6 2009.3 C
78.3865 +1930.6 2010.3 1929.8 2010 1929.2 2010 C
78.3866 +1928 2010.3 1928.8 2008.1 1928.2 2007.6 C
78.3867 +1929.1 2007.8 1929.3 2006.3 1930.1 2006.9 C
78.3868 +1930.3 2009.8 1932.2 2004.8 1932.3 2008.6 C
78.3869 +1932.7 2008 1932.8 2009 1932.8 2009.3 C
78.3870 +1932.8 2009.6 1932.8 2009.8 1932.8 2010 C
78.3871 +1933.2 2009 1932.7 2006.6 1934 2005.7 C
78.3872 +1932.7 2004.6 1934.3 2004.6 1934.2 2004 C
78.3873 +1935.8 2003.7 1937 2003.6 1938.5 2004 C
78.3874 +1938.5 2004.5 1939.1 2005.4 1938.3 2006 C
78.3875 +1940.7 2005.7 1937.4 2001.3 1939.7 2001.4 C
78.3876 +1939.5 2001.4 1938.6 1998.8 1937.1 1999.2 C
78.3877 +1936.3 1999.1 1936.2 1997.1 1936.1 1998.5 C
78.3878 +1934.7 2000.1 1932.9 1998.2 1931.6 1999.5 C
78.3879 +1931.3 1998.9 1930.9 1998.5 1931.1 1997.8 C
78.3880 +1931.6 1998.2 1931.3 1996.6 1932 1996.1 C
78.3881 +1933.2 1995.5 1934.3 1996.4 1935.2 1995.4 C
78.3882 +1935.5 1996.5 1936.3 1996.1 1935.6 1995.2 C
78.3883 +1934.7 1994.5 1932.5 1995.3 1932 1995.4 C
78.3884 +1930.5 1995.3 1931.9 1996.5 1930.8 1996.4 C
78.3885 +1931.2 1997.9 1929.5 1998.3 1928.9 1998.5 C
78.3886 +1928.1 1997.9 1927.1 1998 1926 1998 C
78.3887 +1925.3 1999.2 1924.8 2001.4 1923.2 2001.4 C
78.3888 +1922.6 2000.9 1921 2000.9 1920.3 2000.9 C
78.3889 +1919.7 2001.9 1919.6 2003.5 1918.1 2004 C
78.3890 +1916.9 2004.1 1915.8 2002 1915.2 2003.8 C
78.3891 +1916.7 2004 1917.6 2004.9 1919.6 2004.5 C
78.3892 +1920.7 2005.2 1919.4 2006.3 1919.8 2006.9 C
78.3893 +1919.2 2006.9 1917.7 2007.8 1917.2 2008.6 C
78.3894 +1917.8 2011.6 1919.8 2007.8 1920.5 2010.5 C
78.3895 +1920.8 2011.3 1919.3 2011.6 1920.5 2012 C
78.3896 +1920.8 2012.3 1924 2011.8 1923.2 2014.1 C
78.3897 +1922.6 2013.6 1924.1 2016.1 1924.1 2015.1 C
78.3898 +1925.1 2015.4 1925.9 2015 1926.3 2016.5 C
78.3899 +1926.2 2016.6 1926 2016.8 1925.8 2016.8 C
78.3900 +1925.9 2017.2 1926.2 2017.8 1926.8 2018.2 C
78.3901 +1927.1 2017.6 1927.7 2018 1928.4 2018.2 C
78.3902 +1929.7 2020.1 1927.1 2019.5 1929.4 2021.1 C
78.3903 +1929.9 2020.7 1931.1 2020 1931.1 2019.9 C
78.3904 +[0.21 0.21 0 0] vc
78.3905 +f
78.3906 +S
78.3907 +n
78.3908 +1937.1 2020.8 m
78.3909 +1937.1 2018.3 1937.1 2015.7 1937.1 2013.2 C
78.3910 +1937.1 2015.7 1937.1 2018.3 1937.1 2020.8 C
78.3911 +[0 1 1 0.36] vc
78.3912 +f
78.3913 +S
78.3914 +n
78.3915 +2020.4 2012.2 m
78.3916 +2019.8 2012 2019.3 2011.5 2018.7 2011.7 C
78.3917 +2017.9 2012.1 2018.1 2014.1 2018.4 2014.4 C
78.3918 +2019.6 2014.8 2021.4 2013.7 2020.4 2012.2 C
78.3919 +[0 1 1 0.23] vc
78.3920 +f
78.3921 +S
78.3922 +n
78.3923 +1976 2013.9 m
78.3924 +1973.8 2011.5 1971.6 2009.1 1969.5 2006.7 C
78.3925 +1971.6 2009.1 1973.8 2011.5 1976 2013.9 C
78.3926 +[0 1 1 0.36] vc
78.3927 +f
78.3928 +S
78.3929 +n
78.3930 +1995.4 2012.7 m
78.3931 +1996.1 2010.3 1993.8 2006.2 1997.3 2005.7 C
78.3932 +1998.9 2005.4 2000 2003.7 2001.4 2003.1 C
78.3933 +2003.9 2003.1 2005.3 2001.3 2006.9 1999.7 C
78.3934 +2004.5 2003.5 2000 2002.2 1997.6 2005.7 C
78.3935 +1996.5 2005.9 1994.8 2006.1 1995.2 2007.6 C
78.3936 +1995.7 2009.4 1995.2 2011.6 1994.7 2012.9 C
78.3937 +1992 2015.8 1987.8 2015.7 1985.3 2018.7 C
78.3938 +1988.3 2016.3 1992.3 2015.3 1995.4 2012.7 C
78.3939 +[0.18 0.18 0 0.78] vc
78.3940 +f
78.3941 +S
78.3942 +n
78.3943 +1995.6 2012.4 m
78.3944 +1995.6 2011.2 1995.6 2010 1995.6 2008.8 C
78.3945 +1995.6 2010 1995.6 2011.2 1995.6 2012.4 C
78.3946 +[0 1 1 0.36] vc
78.3947 +f
78.3948 +S
78.3949 +n
78.3950 +vmrs
78.3951 +2017.7 2009.6 m
78.3952 +2016.9 2009.3 2016.7 2008.4 2015.8 2009.1 C
78.3953 +2014.2 2010.6 2016 2010.6 2016.5 2011.5 C
78.3954 +2017.2 2010.9 2018.1 2010.8 2017.7 2009.6 C
78.3955 +[0 1 1 0.23] vc
78.3956 +f
78.3957 +0.4 w
78.3958 +2 J
78.3959 +2 M
78.3960 +S
78.3961 +n
78.3962 +2014.4 2006.4 m
78.3963 +2013.5 2006.8 2012.1 2005.6 2012 2006.7 C
78.3964 +2013 2007.3 2011.9 2009.2 2012.9 2008.4 C
78.3965 +2014.2 2008.3 2014.6 2007.8 2014.4 2006.4 C
78.3966 +f
78.3967 +S
78.3968 +n
78.3969 +1969 2006.4 m
78.3970 +1966.5 2003.8 1964 2001.2 1961.6 1998.5 C
78.3971 +1964 2001.2 1966.5 2003.8 1969 2006.4 C
78.3972 +[0 1 1 0.36] vc
78.3973 +f
78.3974 +S
78.3975 +n
78.3976 +2012 2005.2 m
78.3977 +2012.2 2004.2 2011.4 2003.3 2010.3 2003.3 C
78.3978 +2009 2003.6 2010 2004.7 2009.6 2004.8 C
78.3979 +2009.3 2005.7 2011.4 2006.7 2012 2005.2 C
78.3980 +[0 1 1 0.23] vc
78.3981 +f
78.3982 +S
78.3983 +n
78.3984 +1962.8 1995.2 m
78.3985 +1961.7 1994.4 1960.6 1993.7 1959.4 1994 C
78.3986 +1959.5 1994.9 1957.5 1994.1 1956.8 1994.7 C
78.3987 +1955.9 1995.5 1956.7 1997 1955.1 1997.3 C
78.3988 +1956.9 1996.7 1956.8 1994 1959.2 1994.7 C
78.3989 +1961.1 1991 1968.9 2003.2 1962.8 1995.2 C
78.3990 +[0 1 1 0.36] vc
78.3991 +f
78.3992 +S
78.3993 +n
78.3994 +1954.6 1995.6 m
78.3995 +1955.9 1994.7 1955.1 1989.8 1955.3 1988 C
78.3996 +1954.5 1988.3 1954.9 1986.6 1954.4 1986 C
78.3997 +1955.7 1989.2 1953.9 1991.1 1954.8 1994.2 C
78.3998 +1954.5 1995.9 1953.5 1995.3 1953.9 1997.3 C
78.3999 +1955.3 1998.3 1953.2 1995.5 1954.6 1995.6 C
78.4000 +f
78.4001 +S
78.4002 +n
78.4003 +1992.3 2011 m
78.4004 +1992.5 2006.7 1992 2000.3 1991.8 1997.6 C
78.4005 +1992.2 1997.9 1992 1998.5 1992 1999 C
78.4006 +1992.1 1994.7 1991.9 1990.2 1992.3 1986 C
78.4007 +1991.4 1984.6 1991 1986.1 1990.6 1985.6 C
78.4008 +1989.7 1986 1990.3 1987.2 1990.1 1988 C
78.4009 +1990.7 1987.4 1990.4 1988.5 1990.8 1988.7 C
78.4010 +1991.3 1997.1 1988.9 2000.6 1991.1 2007.9 C
78.4011 +1991 2009.1 1989.8 2009.9 1988.4 2008.8 C
78.4012 +1985.7 2007.2 1986.8 2004.5 1984.1 2004 C
78.4013 +1984.2 2002.7 1981.9 2003.7 1982.4 2001.4 C
78.4014 +1981.2 2001.5 1980.5 2000.8 1980 2000 C
78.4015 +1980 1999.8 1980 1998.9 1980 1999.5 C
78.4016 +1979.3 1999.5 1979.7 1997.2 1977.9 1998 C
78.4017 +1977.2 1997.3 1976.6 1996.7 1977.2 1997.8 C
78.4018 +1979 1998.7 1979.3 2000.8 1981.5 2001.6 C
78.4019 +1982.2 2002.8 1983 2004.3 1984.4 2004.3 C
78.4020 +1985 2005.8 1986.2 2007.5 1987.7 2009.1 C
78.4021 +1989 2010 1991.3 2010.2 1990.8 2012.2 C
78.4022 +1991.2 2011.4 1992.2 2011.8 1992.3 2011 C
78.4023 +[0 1 1 0.23] vc
78.4024 +f
78.4025 +S
78.4026 +n
78.4027 +1991.8 1995.6 m
78.4028 +1991.8 1994.3 1991.8 1992.9 1991.8 1991.6 C
78.4029 +1991.8 1992.9 1991.8 1994.3 1991.8 1995.6 C
78.4030 +[0 1 1 0.36] vc
78.4031 +f
78.4032 +S
78.4033 +n
78.4034 +1959.2 1994.2 m
78.4035 +1958.8 1993.3 1960.7 1993.9 1961.1 1993.7 C
78.4036 +1961.5 1993.9 1961.2 1994.4 1961.8 1994.2 C
78.4037 +1960.9 1994 1960.8 1992.9 1959.9 1992.5 C
78.4038 +1959.6 1993.5 1958.3 1993.5 1958.2 1994.2 C
78.4039 +1958.1 1994.1 1958 1994 1958 1994 C
78.4040 +1957.2 1994.9 1958 1993.4 1956.8 1993 C
78.4041 +1955.6 1992.5 1956 1991 1956.3 1989.9 C
78.4042 +1956.5 1989.8 1956.6 1990 1956.8 1990.1 C
78.4043 +1957.1 1989 1956 1989.1 1955.8 1988.2 C
78.4044 +1955.1 1990.4 1956.2 1995 1954.8 1995.9 C
78.4045 +1954.1 1995.5 1954.5 1996.5 1954.4 1997.1 C
78.4046 +1955 1996.8 1954.8 1997.4 1955.6 1996.8 C
78.4047 +1956 1996 1956.3 1993.2 1958.7 1994.2 C
78.4048 +1958.9 1994.2 1959.7 1994.2 1959.2 1994.2 C
78.4049 +[0 1 1 0.23] vc
78.4050 +f
78.4051 +S
78.4052 +n
78.4053 +1958.2 1994 m
78.4054 +1958.4 1993.5 1959.7 1993.1 1959.9 1992 C
78.4055 +1959.7 1992.5 1959.3 1992 1959.4 1991.8 C
78.4056 +1959.4 1991.6 1959.4 1990.8 1959.4 1991.3 C
78.4057 +1959.2 1991.8 1958.8 1991.3 1958.9 1991.1 C
78.4058 +1958.9 1990.5 1958 1990.3 1957.5 1989.9 C
78.4059 +1956.8 1989.5 1956.9 1991 1956.3 1990.1 C
78.4060 +1956.7 1991 1955.4 1992.1 1956.5 1992.3 C
78.4061 +1956.8 1993.5 1958.3 1992.9 1957.2 1994 C
78.4062 +1957.8 1994.3 1958.1 1992.4 1958.2 1994 C
78.4063 +[0 0.5 0.5 0.2] vc
78.4064 +f
78.4065 +S
78.4066 +n
78.4067 +vmrs
78.4068 +1954.4 1982.7 m
78.4069 +1956.1 1982.7 1954.1 1982.5 1953.9 1982.9 C
78.4070 +1953.9 1983.7 1953.7 1984.7 1954.1 1985.3 C
78.4071 +1954.4 1984.2 1953.6 1983.6 1954.4 1982.7 C
78.4072 +[0 1 1 0.36] vc
78.4073 +f
78.4074 +0.4 w
78.4075 +2 J
78.4076 +2 M
78.4077 +S
78.4078 +n
78.4079 +1989.6 1982.9 m
78.4080 +1989.1 1982.7 1988.6 1982.3 1988 1982.4 C
78.4081 +1987.2 1982.8 1987.4 1984.8 1987.7 1985.1 C
78.4082 +1988.9 1985.6 1990.7 1984.4 1989.6 1982.9 C
78.4083 +[0 1 1 0.23] vc
78.4084 +f
78.4085 +S
78.4086 +n
78.4087 +1987 1980.3 m
78.4088 +1986.2 1980 1986 1979.1 1985.1 1979.8 C
78.4089 +1983.5 1981.4 1985.3 1981.4 1985.8 1982.2 C
78.4090 +1986.5 1981.7 1987.4 1981.5 1987 1980.3 C
78.4091 +f
78.4092 +S
78.4093 +n
78.4094 +1983.6 1977.2 m
78.4095 +1982.7 1977.5 1981.4 1976.3 1981.2 1977.4 C
78.4096 +1982.3 1978 1981.2 1979.9 1982.2 1979.1 C
78.4097 +1983.5 1979 1983.9 1978.5 1983.6 1977.2 C
78.4098 +f
78.4099 +S
78.4100 +n
78.4101 +1981.2 1976 m
78.4102 +1981.5 1974.9 1980.6 1974 1979.6 1974 C
78.4103 +1978.3 1974.3 1979.3 1975.4 1978.8 1975.5 C
78.4104 +1978.6 1976.4 1980.7 1977.4 1981.2 1976 C
78.4105 +f
78.4106 +S
78.4107 +n
78.4108 +1972.1 2082.3 m
78.4109 +1971.8 2081.8 1971.3 2080.9 1971.2 2080.1 C
78.4110 +1971.1 2072.9 1971.3 2064.6 1970.9 2058.3 C
78.4111 +1970.3 2058.5 1970.1 2057.7 1969.7 2058.5 C
78.4112 +1970.6 2058.5 1969.7 2059 1970.2 2059.2 C
78.4113 +1970.2 2065.4 1970.2 2072.4 1970.2 2077.7 C
78.4114 +1971.1 2078.9 1970.6 2078.9 1970.4 2079.9 C
78.4115 +1969.2 2080.2 1968.2 2080.4 1967.3 2079.6 C
78.4116 +1966.8 2077.8 1963.4 2076.3 1963.5 2075.1 C
78.4117 +1961.5 2075.5 1962 2071.5 1959.6 2072 C
78.4118 +1959.2 2070 1956.5 2069.3 1955.8 2067.6 C
78.4119 +1956 2068.4 1955.3 2069.7 1956.5 2069.8 C
78.4120 +1958.6 2068.9 1958.1 2073.5 1960.1 2072.4 C
78.4121 +1960.7 2075.9 1964.7 2074.6 1964.2 2078 C
78.4122 +1967.2 2078.6 1967.9 2081.6 1970.7 2080.6 C
78.4123 +1970.3 2081.1 1971.5 2081.2 1971.9 2082.3 C
78.4124 +1967.2 2084.3 1962.9 2087.1 1958.2 2089 C
78.4125 +1962.9 2087 1967.4 2084.4 1972.1 2082.3 C
78.4126 +[0 0.2 1 0] vc
78.4127 +f
78.4128 +S
78.4129 +n
78.4130 +1971.9 2080.1 m
78.4131 +1971.9 2075.1 1971.9 2070 1971.9 2065 C
78.4132 +1971.9 2070 1971.9 2075.1 1971.9 2080.1 C
78.4133 +[0 1 1 0.23] vc
78.4134 +f
78.4135 +S
78.4136 +n
78.4137 +2010.8 2050.6 m
78.4138 +2013.2 2049 2010.5 2050.1 2010.5 2051.3 C
78.4139 +2010.5 2057.7 2010.5 2064.1 2010.5 2070.5 C
78.4140 +2008.7 2072.4 2006 2073.3 2003.6 2074.4 C
78.4141 +2016.4 2073.7 2008 2058.4 2010.8 2050.6 C
78.4142 +[0.4 0.4 0 0] vc
78.4143 +f
78.4144 +S
78.4145 +n
78.4146 +2006.4 2066.9 m
78.4147 +2006.4 2061.9 2006.4 2056.8 2006.4 2051.8 C
78.4148 +2006.4 2056.8 2006.4 2061.9 2006.4 2066.9 C
78.4149 +[0 1 1 0.23] vc
78.4150 +f
78.4151 +S
78.4152 +n
78.4153 +1971.9 2060.7 m
78.4154 +1972.2 2060.3 1971.4 2068.2 1972.4 2061.9 C
78.4155 +1971.8 2061.6 1972.4 2060.9 1971.9 2060.7 C
78.4156 +f
78.4157 +S
78.4158 +n
78.4159 +vmrs
78.4160 +1986.5 2055.2 m
78.4161 +1987.5 2054.3 1986.3 2053.4 1986 2052.8 C
78.4162 +1983.8 2052.7 1983.6 2050.1 1981.7 2049.6 C
78.4163 +1981.2 2048.7 1980.8 2047 1980.3 2046.8 C
78.4164 +1978.5 2047 1978 2044.6 1976.7 2043.9 C
78.4165 +1974 2044.4 1972 2046.6 1969.2 2047 C
78.4166 +1969 2047.2 1968.8 2047.5 1968.5 2047.7 C
78.4167 +1970.6 2049.6 1973.1 2051.3 1974.3 2054.2 C
78.4168 +1975.7 2054.5 1977 2055.2 1976.4 2057.1 C
78.4169 +1976.7 2058 1975.5 2058.5 1976 2059.5 C
78.4170 +1979.2 2058 1983 2056.6 1986.5 2055.2 C
78.4171 +[0 0.5 0.5 0.2] vc
78.4172 +f
78.4173 +0.4 w
78.4174 +2 J
78.4175 +2 M
78.4176 +S
78.4177 +n
78.4178 +1970.2 2054.2 m
78.4179 +1971.5 2055.3 1972.5 2056.8 1972.1 2058.3 C
78.4180 +1972.8 2056.5 1971.6 2055.6 1970.2 2054.2 C
78.4181 +[0 1 1 0.23] vc
78.4182 +f
78.4183 +S
78.4184 +n
78.4185 +1992 2052.5 m
78.4186 +1992 2053.4 1992.2 2054.4 1991.8 2055.2 C
78.4187 +1992.2 2054.4 1992 2053.4 1992 2052.5 C
78.4188 +f
78.4189 +S
78.4190 +n
78.4191 +1957.2 2053 m
78.4192 +1958.1 2052.6 1959 2052.2 1959.9 2051.8 C
78.4193 +1959 2052.2 1958.1 2052.6 1957.2 2053 C
78.4194 +f
78.4195 +S
78.4196 +n
78.4197 +2006.4 2047.5 m
78.4198 +2006.8 2047.1 2006 2055 2006.9 2048.7 C
78.4199 +2006.4 2048.4 2007 2047.7 2006.4 2047.5 C
78.4200 +f
78.4201 +S
78.4202 +n
78.4203 +2004.8 2041 m
78.4204 +2006.1 2042.1 2007.1 2043.6 2006.7 2045.1 C
78.4205 +2007.3 2043.3 2006.2 2042.4 2004.8 2041 C
78.4206 +f
78.4207 +S
78.4208 +n
78.4209 +1976 2039.8 m
78.4210 +1975.6 2039.3 1975.2 2038.4 1975 2037.6 C
78.4211 +1974.9 2030.4 1975.2 2022.1 1974.8 2015.8 C
78.4212 +1974.2 2016 1974 2015.3 1973.6 2016 C
78.4213 +1974.4 2016 1973.5 2016.5 1974 2016.8 C
78.4214 +1974 2022.9 1974 2030 1974 2035.2 C
78.4215 +1974.9 2036.4 1974.4 2036.4 1974.3 2037.4 C
78.4216 +1973.1 2037.7 1972 2037.9 1971.2 2037.2 C
78.4217 +1970.6 2035.3 1967.3 2033.9 1967.3 2032.6 C
78.4218 +1965.3 2033 1965.9 2029.1 1963.5 2029.5 C
78.4219 +1963 2027.6 1960.4 2026.8 1959.6 2025.2 C
78.4220 +1959.8 2025.9 1959.2 2027.2 1960.4 2027.3 C
78.4221 +1962.5 2026.4 1961.9 2031 1964 2030 C
78.4222 +1964.6 2033.4 1968.5 2032.1 1968 2035.5 C
78.4223 +1971 2036.1 1971.8 2039.1 1974.5 2038.1 C
78.4224 +1974.2 2038.7 1975.3 2038.7 1975.7 2039.8 C
78.4225 +1971 2041.8 1966.7 2044.6 1962 2046.5 C
78.4226 +1966.8 2044.5 1971.3 2041.9 1976 2039.8 C
78.4227 +[0 0.2 1 0] vc
78.4228 +f
78.4229 +S
78.4230 +n
78.4231 +1975.7 2037.6 m
78.4232 +1975.7 2032.6 1975.7 2027.6 1975.7 2022.5 C
78.4233 +1975.7 2027.6 1975.7 2032.6 1975.7 2037.6 C
78.4234 +[0 1 1 0.23] vc
78.4235 +f
78.4236 +S
78.4237 +n
78.4238 +1992 2035.5 m
78.4239 +1992 2034.2 1992 2032.9 1992 2031.6 C
78.4240 +1992 2032.9 1992 2034.2 1992 2035.5 C
78.4241 +f
78.4242 +S
78.4243 +n
78.4244 +2015.3 2036 m
78.4245 +2015.4 2034.1 2013.3 2034 2012.9 2033.3 C
78.4246 +2011.5 2031 2009.3 2029.4 2007.4 2028 C
78.4247 +2006.9 2027.1 2006.6 2023.8 2005 2024.9 C
78.4248 +2004 2024.9 2002.9 2024.9 2001.9 2024.9 C
78.4249 +2001.4 2026.5 2001 2028.4 2003.8 2028.3 C
78.4250 +2006.6 2030.4 2008.9 2033.7 2011.2 2036.2 C
78.4251 +2011.8 2036.4 2012.9 2035.8 2012.9 2036.7 C
78.4252 +2013 2035.5 2015.3 2037.4 2015.3 2036 C
78.4253 +[0 0 0 0] vc
78.4254 +f
78.4255 +S
78.4256 +n
78.4257 +vmrs
78.4258 +2009.1 2030.4 m
78.4259 +2009.1 2029 2007.5 2029.4 2006.9 2028.3 C
78.4260 +2007.2 2027.1 2006.5 2025.5 2005.7 2024.7 C
78.4261 +2004.6 2025.1 2003.1 2024.9 2001.9 2024.9 C
78.4262 +2001.8 2026.2 2000.9 2027 2002.4 2028 C
78.4263 +2004.5 2027.3 2004.9 2029.4 2006.9 2029 C
78.4264 +2007 2030.2 2007.6 2030.7 2008.4 2031.4 C
78.4265 +2008.8 2031.5 2009.1 2031.1 2009.1 2030.4 C
78.4266 +[0 0 0 0.18] vc
78.4267 +f
78.4268 +0.4 w
78.4269 +2 J
78.4270 +2 M
78.4271 +S
78.4272 +n
78.4273 +2003.8 2029.5 m
78.4274 +2003 2029.4 2001.9 2029.1 2002.4 2030.4 C
78.4275 +2003.1 2031.3 2005.2 2030.3 2003.8 2029.5 C
78.4276 +[0 1 1 0.23] vc
78.4277 +f
78.4278 +S
78.4279 +n
78.4280 +1999.2 2025.2 m
78.4281 +1999.1 2025.6 1998 2025.7 1998.8 2026.6 C
78.4282 +2000.9 2028.5 1999.5 2023.4 1999.2 2025.2 C
78.4283 +f
78.4284 +S
78.4285 +n
78.4286 +2007.6 2024.2 m
78.4287 +2007.6 2022.9 2008.4 2024.2 2007.6 2022.8 C
78.4288 +2007.6 2017.5 2007.8 2009.1 2007.4 2003.8 C
78.4289 +2007.9 2003.7 2008.7 2002.8 2009.1 2002.1 C
78.4290 +2009.6 2000.8 2008.3 2000.8 2007.9 2000.2 C
78.4291 +2004.9 2000 2008.9 2001.3 2007.2 2002.1 C
78.4292 +2006.7 2007.7 2007 2015.1 2006.9 2021.1 C
78.4293 +2006.7 2022.1 2005.4 2022.8 2006.2 2023.5 C
78.4294 +2006.6 2023.1 2008 2025.9 2007.6 2024.2 C
78.4295 +f
78.4296 +S
78.4297 +n
78.4298 +1989.9 2023.5 m
78.4299 +1989.5 2022.6 1991.4 2023.2 1991.8 2023 C
78.4300 +1992.2 2023.2 1991.9 2023.7 1992.5 2023.5 C
78.4301 +1991.6 2023.2 1991.6 2022.2 1990.6 2021.8 C
78.4302 +1990.4 2022.8 1989 2022.8 1988.9 2023.5 C
78.4303 +1988.5 2023 1988.7 2022.6 1988.7 2023.5 C
78.4304 +1989.1 2023.5 1990.2 2023.5 1989.9 2023.5 C
78.4305 +f
78.4306 +[0 0.5 0.5 0.2] vc
78.4307 +S
78.4308 +n
78.4309 +2003.3 2023.5 m
78.4310 +2003.1 2023.3 2003.1 2023.2 2003.3 2023 C
78.4311 +2003.7 2023.1 2003.9 2022.9 2003.8 2022.5 C
78.4312 +2003.4 2022.2 2001.2 2022.3 2002.4 2023 C
78.4313 +2002.6 2022.9 2002.7 2023.1 2002.8 2023.2 C
78.4314 +2000.7 2023.7 2003.9 2023.4 2003.3 2023.5 C
78.4315 +[0 1 1 0.23] vc
78.4316 +f
78.4317 +S
78.4318 +n
78.4319 +1986.8 2019.4 m
78.4320 +1987.8 2019.8 1987.5 2018.6 1987.2 2018 C
78.4321 +1986.2 2017.8 1987.3 2020.5 1986.3 2019.2 C
78.4322 +1986.3 2017.7 1986.3 2020.6 1986.3 2021.3 C
78.4323 +1988.5 2023.1 1985.6 2020.3 1986.8 2019.4 C
78.4324 +f
78.4325 +S
78.4326 +n
78.4327 +1975.7 2018.2 m
78.4328 +1976.1 2017.8 1975.2 2025.7 1976.2 2019.4 C
78.4329 +1975.7 2019.2 1976.3 2018.4 1975.7 2018.2 C
78.4330 +f
78.4331 +S
78.4332 +n
78.4333 +1974 2011.7 m
78.4334 +1975.4 2012.8 1976.4 2014.3 1976 2015.8 C
78.4335 +1976.6 2014 1975.5 2013.1 1974 2011.7 C
78.4336 +f
78.4337 +S
78.4338 +n
78.4339 +1984.6 2006.7 m
78.4340 +1984.7 2004.8 1982.6 2004.8 1982.2 2004 C
78.4341 +1980.8 2001.7 1978.6 2000.1 1976.7 1998.8 C
78.4342 +1976.1 1997.8 1975.8 1994.5 1974.3 1995.6 C
78.4343 +1973.3 1995.6 1972.2 1995.6 1971.2 1995.6 C
78.4344 +1970.7 1997.2 1970.3 1999.1 1973.1 1999 C
78.4345 +1975.8 2001.2 1978.2 2004.4 1980.5 2006.9 C
78.4346 +1981.1 2007.1 1982.1 2006.5 1982.2 2007.4 C
78.4347 +1982.3 2006.2 1984.5 2008.1 1984.6 2006.7 C
78.4348 +[0 0 0 0] vc
78.4349 +f
78.4350 +S
78.4351 +n
78.4352 +vmrs
78.4353 +1978.4 2001.2 m
78.4354 +1978.4 1999.7 1976.8 2000.1 1976.2 1999 C
78.4355 +1976.5 1997.8 1975.8 1996.2 1975 1995.4 C
78.4356 +1973.9 1995.8 1972.4 1995.6 1971.2 1995.6 C
78.4357 +1971 1997 1970.2 1997.7 1971.6 1998.8 C
78.4358 +1973.8 1998 1974.2 2000.1 1976.2 1999.7 C
78.4359 +1976.3 2000.9 1976.9 2001.4 1977.6 2002.1 C
78.4360 +1978.1 2002.2 1978.4 2001.8 1978.4 2001.2 C
78.4361 +[0 0 0 0.18] vc
78.4362 +f
78.4363 +0.4 w
78.4364 +2 J
78.4365 +2 M
78.4366 +S
78.4367 +n
78.4368 +1973.1 2000.2 m
78.4369 +1972.3 2000.1 1971.2 1999.8 1971.6 2001.2 C
78.4370 +1972.4 2002 1974.5 2001 1973.1 2000.2 C
78.4371 +[0 1 1 0.23] vc
78.4372 +f
78.4373 +S
78.4374 +n
78.4375 +1960.8 1998.5 m
78.4376 +1961.6 1998.2 1962.6 2000.3 1963.2 2000.9 C
78.4377 +1962.3 2000.1 1962.2 1998.7 1960.8 1998.5 C
78.4378 +f
78.4379 +S
78.4380 +n
78.4381 +1968.5 1995.9 m
78.4382 +1968.4 1996.4 1967.3 1996.4 1968 1997.3 C
78.4383 +1970.1 1999.2 1968.8 1994.1 1968.5 1995.9 C
78.4384 +f
78.4385 +S
78.4386 +n
78.4387 +1976.9 1994.9 m
78.4388 +1976.9 1993.7 1977.6 1994.9 1976.9 1993.5 C
78.4389 +1976.9 1988.2 1977.1 1979.8 1976.7 1974.5 C
78.4390 +1977.2 1974.5 1978 1973.5 1978.4 1972.8 C
78.4391 +1978.8 1971.5 1977.6 1971.5 1977.2 1970.9 C
78.4392 +1974.2 1970.7 1978.2 1972 1976.4 1972.8 C
78.4393 +1976 1978.4 1976.3 1985.8 1976.2 1991.8 C
78.4394 +1976 1992.8 1974.6 1993.5 1975.5 1994.2 C
78.4395 +1975.9 1993.8 1977.3 1996.6 1976.9 1994.9 C
78.4396 +f
78.4397 +S
78.4398 +n
78.4399 +1972.6 1994.2 m
78.4400 +1972.4 1994 1972.4 1993.9 1972.6 1993.7 C
78.4401 +1973 1993.8 1973.1 1993.7 1973.1 1993.2 C
78.4402 +1972.7 1992.9 1970.5 1993.1 1971.6 1993.7 C
78.4403 +1971.9 1993.7 1972 1993.8 1972.1 1994 C
78.4404 +1970 1994.4 1973.1 1994.1 1972.6 1994.2 C
78.4405 +f
78.4406 +S
78.4407 +n
78.4408 +1948.1 2093.8 m
78.4409 +1947 2092.7 1945.9 2091.6 1944.8 2090.4 C
78.4410 +1945.9 2091.6 1947 2092.7 1948.1 2093.8 C
78.4411 +[0 0.4 1 0] vc
78.4412 +f
78.4413 +S
78.4414 +n
78.4415 +1953.4 2091.4 m
78.4416 +1954.8 2090.7 1956.3 2090 1957.7 2089.2 C
78.4417 +1956.3 2090 1954.8 2090.7 1953.4 2091.4 C
78.4418 +[0 0.2 1 0] vc
78.4419 +f
78.4420 +S
78.4421 +n
78.4422 +1954.1 2091.4 m
78.4423 +1956.6 2089.6 1957.2 2089.6 1954.1 2091.4 C
78.4424 +[0 0.4 1 0] vc
78.4425 +f
78.4426 +S
78.4427 +n
78.4428 +1962.3 2087.3 m
78.4429 +1963.7 2086.6 1965.2 2085.9 1966.6 2085.2 C
78.4430 +1965.2 2085.9 1963.7 2086.6 1962.3 2087.3 C
78.4431 +f
78.4432 +S
78.4433 +n
78.4434 +vmrs
78.4435 +1967.1 2084.9 m
78.4436 +1968.3 2084.4 1969.7 2083.8 1970.9 2083.2 C
78.4437 +1969.7 2083.8 1968.3 2084.4 1967.1 2084.9 C
78.4438 +[0 0.4 1 0] vc
78.4439 +f
78.4440 +0.4 w
78.4441 +2 J
78.4442 +2 M
78.4443 +S
78.4444 +n
78.4445 +1982.7 2080.6 m
78.4446 +1981.5 2079.5 1980.5 2078.4 1979.3 2077.2 C
78.4447 +1980.5 2078.4 1981.5 2079.5 1982.7 2080.6 C
78.4448 +f
78.4449 +S
78.4450 +n
78.4451 +1988 2078.2 m
78.4452 +1989.4 2077.5 1990.8 2076.8 1992.3 2076 C
78.4453 +1990.8 2076.8 1989.4 2077.5 1988 2078.2 C
78.4454 +[0 0.2 1 0] vc
78.4455 +f
78.4456 +S
78.4457 +n
78.4458 +1988.7 2078.2 m
78.4459 +1991.1 2076.4 1991.8 2076.4 1988.7 2078.2 C
78.4460 +[0 0.4 1 0] vc
78.4461 +f
78.4462 +S
78.4463 +n
78.4464 +1976.2 2063.8 m
78.4465 +1978.6 2062.2 1976 2063.3 1976 2064.5 C
78.4466 +1976.1 2067.8 1975.5 2071.4 1976.4 2074.4 C
78.4467 +1975.7 2071.1 1975.9 2067.2 1976.2 2063.8 C
78.4468 +f
78.4469 +S
78.4470 +n
78.4471 +1996.8 2074.1 m
78.4472 +1998.3 2073.4 1999.7 2072.7 2001.2 2072 C
78.4473 +1999.7 2072.7 1998.3 2073.4 1996.8 2074.1 C
78.4474 +f
78.4475 +S
78.4476 +n
78.4477 +2001.6 2071.7 m
78.4478 +2002.9 2071.2 2004.2 2070.6 2005.5 2070 C
78.4479 +2004.2 2070.6 2002.9 2071.2 2001.6 2071.7 C
78.4480 +f
78.4481 +S
78.4482 +n
78.4483 +1981.5 2060.7 m
78.4484 +1980.2 2061.2 1978.9 2061.5 1977.9 2062.6 C
78.4485 +1978.9 2061.5 1980.2 2061.2 1981.5 2060.7 C
78.4486 +f
78.4487 +S
78.4488 +n
78.4489 +1982 2060.4 m
78.4490 +1982.7 2060.1 1983.6 2059.8 1984.4 2059.5 C
78.4491 +1983.6 2059.8 1982.7 2060.1 1982 2060.4 C
78.4492 +f
78.4493 +S
78.4494 +n
78.4495 +1952 2051.3 m
78.4496 +1950.8 2050.2 1949.7 2049.1 1948.6 2048 C
78.4497 +1949.7 2049.1 1950.8 2050.2 1952 2051.3 C
78.4498 +f
78.4499 +S
78.4500 +n
78.4501 +vmrs
78.4502 +1977.4 2047.7 m
78.4503 +1975.8 2047.8 1974.8 2046.1 1974.5 2045.3 C
78.4504 +1974.9 2044.4 1976 2044.5 1976.7 2044.8 C
78.4505 +1977.9 2045 1977 2048.4 1979.3 2047.5 C
78.4506 +1979.9 2047.5 1980.8 2048.6 1979.8 2049.2 C
78.4507 +1978.2 2050.4 1980.8 2049.5 1980.3 2049.4 C
78.4508 +1981.4 2049.8 1980.3 2048.4 1980.3 2048 C
78.4509 +1979.8 2047.5 1979 2046.6 1978.4 2046.5 C
78.4510 +1977.3 2045.9 1977.2 2043.3 1975.2 2044.6 C
78.4511 +1974.7 2045.3 1973.6 2045 1973.3 2045.8 C
78.4512 +1975 2046.3 1975.8 2049.8 1978.1 2049.4 C
78.4513 +1978.4 2050.9 1978.7 2048.5 1977.9 2049.2 C
78.4514 +1977.7 2048.7 1977.2 2047.8 1977.4 2047.7 C
78.4515 +[0 0.5 0.5 0.2] vc
78.4516 +f
78.4517 +0.4 w
78.4518 +2 J
78.4519 +2 M
78.4520 +S
78.4521 +n
78.4522 +1957.2 2048.9 m
78.4523 +1958.7 2048.2 1960.1 2047.5 1961.6 2046.8 C
78.4524 +1960.1 2047.5 1958.7 2048.2 1957.2 2048.9 C
78.4525 +[0 0.2 1 0] vc
78.4526 +f
78.4527 +S
78.4528 +n
78.4529 +1958 2048.9 m
78.4530 +1960.4 2047.1 1961.1 2047.1 1958 2048.9 C
78.4531 +[0 0.4 1 0] vc
78.4532 +f
78.4533 +S
78.4534 +n
78.4535 +1966.1 2044.8 m
78.4536 +1967.6 2044.1 1969 2043.4 1970.4 2042.7 C
78.4537 +1969 2043.4 1967.6 2044.1 1966.1 2044.8 C
78.4538 +f
78.4539 +S
78.4540 +n
78.4541 +1970.9 2042.4 m
78.4542 +1972.2 2041.9 1973.5 2041.3 1974.8 2040.8 C
78.4543 +1973.5 2041.3 1972.2 2041.9 1970.9 2042.4 C
78.4544 +f
78.4545 +S
78.4546 +n
78.4547 +2012 2034.5 m
78.4548 +2010.4 2034.6 2009.3 2032.9 2009.1 2032.1 C
78.4549 +2009.4 2031 2010.3 2031.3 2011.2 2031.6 C
78.4550 +2012.5 2031.8 2011.6 2035.2 2013.9 2034.3 C
78.4551 +2014.4 2034.3 2015.4 2035.4 2014.4 2036 C
78.4552 +2012.7 2037.2 2015.3 2036.3 2014.8 2036.2 C
78.4553 +2015.9 2036.6 2014.8 2035.2 2014.8 2034.8 C
78.4554 +2014.4 2034.3 2013.6 2033.4 2012.9 2033.3 C
78.4555 +2011.5 2031 2009.3 2029.4 2007.4 2028 C
78.4556 +2007.5 2026.5 2007.3 2027.9 2007.2 2028.3 C
78.4557 +2007.9 2028.8 2008.7 2029.1 2009.3 2030 C
78.4558 +2009.6 2030.7 2009 2031.9 2008.4 2031.6 C
78.4559 +2006.7 2031 2007.7 2028 2005 2028.8 C
78.4560 +2004.8 2028.6 2004.3 2028.2 2003.8 2028.3 C
78.4561 +2006.6 2030.4 2008.9 2033.7 2011.2 2036.2 C
78.4562 +2011.8 2036.4 2012.9 2035.8 2012.9 2036.7 C
78.4563 +2012.7 2036.1 2011.8 2035 2012 2034.5 C
78.4564 +[0 0.5 0.5 0.2] vc
78.4565 +f
78.4566 +S
78.4567 +n
78.4568 +1981.2 2005.2 m
78.4569 +1979.7 2005.3 1978.6 2003.6 1978.4 2002.8 C
78.4570 +1978.7 2001.8 1979.6 2002.1 1980.5 2002.4 C
78.4571 +1981.8 2002.5 1980.9 2005.9 1983.2 2005 C
78.4572 +1983.7 2005.1 1984.7 2006.1 1983.6 2006.7 C
78.4573 +1982 2007.9 1984.6 2007 1984.1 2006.9 C
78.4574 +1985.2 2007.3 1984.1 2006 1984.1 2005.5 C
78.4575 +1983.6 2005 1982.9 2004.1 1982.2 2004 C
78.4576 +1980.8 2001.7 1978.6 2000.1 1976.7 1998.8 C
78.4577 +1976.7 1997.2 1976.6 1998.6 1976.4 1999 C
78.4578 +1977.2 1999.5 1978 1999.8 1978.6 2000.7 C
78.4579 +1978.8 2001.5 1978.3 2002.7 1977.6 2002.4 C
78.4580 +1976 2001.8 1977 1998.7 1974.3 1999.5 C
78.4581 +1974.1 1999.3 1973.6 1998.9 1973.1 1999 C
78.4582 +1975.8 2001.2 1978.2 2004.4 1980.5 2006.9 C
78.4583 +1981.1 2007.1 1982.1 2006.5 1982.2 2007.4 C
78.4584 +1982 2006.8 1981.1 2005.7 1981.2 2005.2 C
78.4585 +f
78.4586 +S
78.4587 +n
78.4588 +1966.8 1976.4 m
78.4589 +1969.4 1973 1974.4 1974.6 1976.2 1970.4 C
78.4590 +1972.7 1974 1968 1975.1 1964 1977.4 C
78.4591 +1960.9 1979.9 1957.1 1981.8 1953.9 1982.7 C
78.4592 +1958.4 1981.1 1962.6 1978.8 1966.8 1976.4 C
78.4593 +[0.18 0.18 0 0.78] vc
78.4594 +f
78.4595 +S
78.4596 +n
78.4597 +1948.4 2093.8 m
78.4598 +1949.8 2093.1 1951.2 2092.5 1952.7 2091.9 C
78.4599 +1951.2 2092.5 1949.8 2093.1 1948.4 2093.8 C
78.4600 +[0 0.2 1 0] vc
78.4601 +f
78.4602 +S
78.4603 +n
78.4604 +1948.1 2093.6 m
78.4605 +1947.3 2092.8 1946.5 2091.9 1945.7 2091.2 C
78.4606 +1946.5 2091.9 1947.3 2092.8 1948.1 2093.6 C
78.4607 +f
78.4608 +S
78.4609 +n
78.4610 +vmrs
78.4611 +1942.1 2087.8 m
78.4612 +1943.5 2088.4 1944.3 2089.5 1945.2 2090.7 C
78.4613 +1944.8 2089.3 1943.3 2088.3 1942.1 2087.8 C
78.4614 +[0 0.2 1 0] vc
78.4615 +f
78.4616 +0.4 w
78.4617 +2 J
78.4618 +2 M
78.4619 +S
78.4620 +n
78.4621 +1933.5 2078.4 m
78.4622 +1933.5 2078 1933.2 2079 1933.7 2079.4 C
78.4623 +1935 2080.4 1936.2 2081.3 1937.1 2082.8 C
78.4624 +1936.7 2080.7 1933.7 2080.7 1933.5 2078.4 C
78.4625 +f
78.4626 +S
78.4627 +n
78.4628 +1982.9 2080.6 m
78.4629 +1984.4 2079.9 1985.8 2079.3 1987.2 2078.7 C
78.4630 +1985.8 2079.3 1984.4 2079.9 1982.9 2080.6 C
78.4631 +f
78.4632 +S
78.4633 +n
78.4634 +1982.7 2080.4 m
78.4635 +1981.9 2079.6 1981.1 2078.7 1980.3 2078 C
78.4636 +1981.1 2078.7 1981.9 2079.6 1982.7 2080.4 C
78.4637 +f
78.4638 +S
78.4639 +n
78.4640 +1977.4 2075.1 m
78.4641 +1977.9 2075.3 1979.1 2076.4 1979.8 2077.5 C
78.4642 +1979 2076.8 1978.7 2075.1 1977.4 2075.1 C
78.4643 +f
78.4644 +S
78.4645 +n
78.4646 +1952.2 2051.3 m
78.4647 +1953.6 2050.7 1955.1 2050.1 1956.5 2049.4 C
78.4648 +1955.1 2050.1 1953.6 2050.7 1952.2 2051.3 C
78.4649 +f
78.4650 +S
78.4651 +n
78.4652 +1952 2051.1 m
78.4653 +1951.2 2050.3 1950.3 2049.5 1949.6 2048.7 C
78.4654 +1950.3 2049.5 1951.2 2050.3 1952 2051.1 C
78.4655 +f
78.4656 +S
78.4657 +n
78.4658 +1946 2045.3 m
78.4659 +1947.3 2045.9 1948.1 2047 1949.1 2048.2 C
78.4660 +1948.6 2046.8 1947.1 2045.8 1946 2045.3 C
78.4661 +f
78.4662 +S
78.4663 +n
78.4664 +1937.3 2036 m
78.4665 +1937.4 2035.5 1937 2036.5 1937.6 2036.9 C
78.4666 +1938.8 2037.9 1940.1 2038.8 1940.9 2040.3 C
78.4667 +1940.6 2038.2 1937.6 2038.2 1937.3 2036 C
78.4668 +f
78.4669 +S
78.4670 +n
78.4671 +1935.2 2073.2 m
78.4672 +1936.4 2069.9 1935.8 2061.8 1935.6 2056.4 C
78.4673 +1935.8 2055.9 1936.3 2055.7 1936.1 2055.2 C
78.4674 +1935.7 2054.7 1935 2055 1934.4 2054.9 C
78.4675 +1934.4 2061.5 1934.4 2068.7 1934.4 2074.6 C
78.4676 +1935.7 2075.1 1936 2073.7 1935.2 2073.2 C
78.4677 +[0 0.01 1 0] vc
78.4678 +f
78.4679 +S
78.4680 +n
78.4681 +vmrs
78.4682 +1939 2030.7 m
78.4683 +1940.3 2027.4 1939.7 2019.3 1939.5 2013.9 C
78.4684 +1939.7 2013.5 1940.1 2013.2 1940 2012.7 C
78.4685 +1939.5 2012.3 1938.8 2012.5 1938.3 2012.4 C
78.4686 +1938.3 2019 1938.3 2026.2 1938.3 2032.1 C
78.4687 +1939.5 2032.7 1939.8 2031.2 1939 2030.7 C
78.4688 +[0 0.01 1 0] vc
78.4689 +f
78.4690 +0.4 w
78.4691 +2 J
78.4692 +2 M
78.4693 +S
78.4694 +n
78.4695 +1975.2 2077.2 m
78.4696 +1975.3 2077.3 1975.4 2077.4 1975.5 2077.5 C
78.4697 +1974.7 2073.2 1974.9 2067.5 1975.2 2063.6 C
78.4698 +1975.4 2064 1974.6 2063.9 1974.8 2064.3 C
78.4699 +1974.9 2069.9 1974.3 2076.5 1975.2 2081.1 C
78.4700 +1974.9 2079.9 1974.9 2078.4 1975.2 2077.2 C
78.4701 +[0.92 0.92 0 0.67] vc
78.4702 +f
78.4703 +S
78.4704 +n
78.4705 +1930.8 2067.4 m
78.4706 +1931.5 2070.1 1929.6 2072.1 1930.6 2074.6 C
78.4707 +1931 2072.6 1930.8 2069.8 1930.8 2067.4 C
78.4708 +f
78.4709 +S
78.4710 +n
78.4711 +2010 2050.1 m
78.4712 +2009.8 2050.5 2009.5 2050.9 2009.3 2051.1 C
78.4713 +2009.5 2056.7 2008.9 2063.3 2009.8 2067.9 C
78.4714 +2009.5 2062.1 2009.3 2054.7 2010 2050.1 C
78.4715 +f
78.4716 +S
78.4717 +n
78.4718 +1930.1 2060.9 m
78.4719 +1929.3 2057.1 1930.7 2054.8 1929.9 2051.3 C
78.4720 +1930.2 2050.2 1931.1 2049.6 1931.8 2049.2 C
78.4721 +1931.4 2049.6 1930.4 2049.5 1930.1 2050.1 C
78.4722 +1928.4 2054.8 1933.4 2063.5 1925.3 2064.3 C
78.4723 +1927.2 2063.9 1928.5 2062.1 1930.1 2060.9 C
78.4724 +[0.07 0.06 0 0.58] vc
78.4725 +f
78.4726 +S
78.4727 +n
78.4728 +1929.6 2061.2 m
78.4729 +1929.6 2057.6 1929.6 2054.1 1929.6 2050.6 C
78.4730 +1930 2049.9 1930.5 2049.4 1931.1 2049.2 C
78.4731 +1930 2048.6 1930.5 2050.2 1929.4 2049.6 C
78.4732 +1928 2054.4 1932.8 2063 1925.3 2064 C
78.4733 +1926.9 2063.3 1928.3 2062.4 1929.6 2061.2 C
78.4734 +[0.4 0.4 0 0] vc
78.4735 +f
78.4736 +S
78.4737 +n
78.4738 +1930.8 2061.6 m
78.4739 +1930.5 2058 1931.6 2054 1930.8 2051.3 C
78.4740 +1930.3 2054.5 1930.9 2058.5 1930.4 2061.9 C
78.4741 +1930.5 2061.2 1931 2062.2 1930.8 2061.6 C
78.4742 +[0.92 0.92 0 0.67] vc
78.4743 +f
78.4744 +S
78.4745 +n
78.4746 +1941.2 2045.1 m
78.4747 +1939.7 2042.6 1937.3 2041.2 1935.4 2039.3 C
78.4748 +1934.2 2040 1933.7 2036.4 1934 2039.3 C
78.4749 +1934.9 2040.1 1936.1 2039.9 1936.8 2040.8 C
78.4750 +1935.3 2044.2 1942.3 2041.7 1939.5 2046 C
78.4751 +1937.1 2048.5 1940.5 2045.6 1941.2 2045.1 C
78.4752 +f
78.4753 +S
78.4754 +n
78.4755 +1910 2045.8 m
78.4756 +1910 2039.4 1910 2033 1910 2026.6 C
78.4757 +1910 2033 1910 2039.4 1910 2045.8 C
78.4758 +f
78.4759 +S
78.4760 +n
78.4761 +1978.8 2022.3 m
78.4762 +1979.1 2021.7 1979.4 2020.4 1978.6 2021.6 C
78.4763 +1978.6 2026.9 1978.6 2033 1978.6 2037.6 C
78.4764 +1979.2 2037 1979.1 2038.2 1979.1 2038.6 C
78.4765 +1978.7 2033.6 1978.9 2026.8 1978.8 2022.3 C
78.4766 +f
78.4767 +S
78.4768 +n
78.4769 +vmrs
78.4770 +2026.1 2041.2 m
78.4771 +2026.1 2034.8 2026.1 2028.3 2026.1 2021.8 C
78.4772 +2026.1 2028.5 2026.3 2035.4 2025.9 2042 C
78.4773 +2024.4 2042.9 2022.9 2044.1 2021.3 2044.8 C
78.4774 +2023.1 2044 2025.1 2042.8 2026.1 2041.2 C
78.4775 +[0.07 0.06 0 0.58] vc
78.4776 +f
78.4777 +0.4 w
78.4778 +2 J
78.4779 +2 M
78.4780 +S
78.4781 +n
78.4782 +2026.4 2021.8 m
78.4783 +2026.3 2028.5 2026.5 2035.4 2026.1 2042 C
78.4784 +2025.6 2042.8 2024.7 2042.7 2024.2 2043.4 C
78.4785 +2024.7 2042.7 2025.5 2042.7 2026.1 2042.2 C
78.4786 +2026.5 2035.5 2026.3 2027.9 2026.4 2021.8 C
78.4787 +[0.4 0.4 0 0] vc
78.4788 +f
78.4789 +S
78.4790 +n
78.4791 +2025.6 2038.4 m
78.4792 +2025.6 2033 2025.6 2027.6 2025.6 2022.3 C
78.4793 +2025.6 2027.6 2025.6 2033 2025.6 2038.4 C
78.4794 +[0.92 0.92 0 0.67] vc
78.4795 +f
78.4796 +S
78.4797 +n
78.4798 +1934 2023.5 m
78.4799 +1934 2024.7 1933.8 2026 1934.2 2027.1 C
78.4800 +1934 2025.5 1934.7 2024.6 1934 2023.5 C
78.4801 +f
78.4802 +S
78.4803 +n
78.4804 +1928.2 2023.5 m
78.4805 +1928 2024.6 1927.4 2023.1 1926.8 2023.2 C
78.4806 +1926.2 2021 1921.4 2019.3 1923.2 2018 C
78.4807 +1922.7 2016.5 1923.2 2019.3 1922.2 2018.2 C
78.4808 +1924.4 2020.4 1926.2 2023.3 1928.9 2024.9 C
78.4809 +1927.9 2024.2 1929.8 2023.5 1928.2 2023.5 C
78.4810 +[0.18 0.18 0 0.78] vc
78.4811 +f
78.4812 +S
78.4813 +n
78.4814 +1934 2019.2 m
78.4815 +1932 2019.6 1930.8 2022.6 1928.7 2021.8 C
78.4816 +1924.5 2016.5 1918.2 2011.8 1914 2006.7 C
78.4817 +1914 2005.7 1914 2004.6 1914 2003.6 C
78.4818 +1913.6 2004.3 1913.9 2005.8 1913.8 2006.9 C
78.4819 +1919 2012.4 1924.1 2016.5 1929.2 2022.3 C
78.4820 +1931 2021.7 1932.2 2019.8 1934 2019.2 C
78.4821 +f
78.4822 +S
78.4823 +n
78.4824 +1928.7 2024.9 m
78.4825 +1926.3 2022.7 1924.1 2020.4 1921.7 2018.2 C
78.4826 +1924.1 2020.4 1926.3 2022.7 1928.7 2024.9 C
78.4827 +[0.65 0.65 0 0.42] vc
78.4828 +f
78.4829 +S
78.4830 +n
78.4831 +1914.3 2006.7 m
78.4832 +1918.7 2011.8 1924.5 2016.4 1928.9 2021.6 C
78.4833 +1924.2 2016.1 1919 2012.1 1914.3 2006.7 C
78.4834 +[0.07 0.06 0 0.58] vc
78.4835 +f
78.4836 +S
78.4837 +n
78.4838 +1924.8 2020.8 m
78.4839 +1921.2 2016.9 1925.6 2022.5 1926 2021.1 C
78.4840 +1924.2 2021 1926.7 2019.6 1924.8 2020.8 C
78.4841 +[0.92 0.92 0 0.67] vc
78.4842 +f
78.4843 +S
78.4844 +n
78.4845 +1934 2018.4 m
78.4846 +1933.2 2014.7 1934.5 2012.3 1933.7 2008.8 C
78.4847 +1934 2007.8 1935 2007.2 1935.6 2006.7 C
78.4848 +1935.3 2007.1 1934.3 2007 1934 2007.6 C
78.4849 +1932.2 2012.3 1937.2 2021 1929.2 2021.8 C
78.4850 +1931.1 2021.4 1932.3 2019.6 1934 2018.4 C
78.4851 +[0.07 0.06 0 0.58] vc
78.4852 +f
78.4853 +S
78.4854 +n
78.4855 +vmrs
78.4856 +1933.5 2018.7 m
78.4857 +1933.5 2015.1 1933.5 2011.7 1933.5 2008.1 C
78.4858 +1933.8 2007.4 1934.3 2006.9 1934.9 2006.7 C
78.4859 +1933.8 2006.1 1934.3 2007.7 1933.2 2007.2 C
78.4860 +1931.9 2012 1936.7 2020.5 1929.2 2021.6 C
78.4861 +1930.7 2020.8 1932.2 2019.9 1933.5 2018.7 C
78.4862 +[0.4 0.4 0 0] vc
78.4863 +f
78.4864 +0.4 w
78.4865 +2 J
78.4866 +2 M
78.4867 +S
78.4868 +n
78.4869 +1934.7 2019.2 m
78.4870 +1934.3 2015.6 1935.4 2011.5 1934.7 2008.8 C
78.4871 +1934.1 2012 1934.7 2016 1934.2 2019.4 C
78.4872 +1934.4 2018.7 1934.8 2019.8 1934.7 2019.2 C
78.4873 +[0.92 0.92 0 0.67] vc
78.4874 +f
78.4875 +S
78.4876 +n
78.4877 +1917.6 2013.6 m
78.4878 +1917.8 2011.1 1916.8 2014.2 1917.2 2012.2 C
78.4879 +1916.3 2012.9 1914.8 2011.8 1914.3 2010.8 C
78.4880 +1914.2 2010.5 1914.4 2010.4 1914.5 2010.3 C
78.4881 +1913.9 2008.8 1913.9 2011.9 1914.3 2012 C
78.4882 +1916.3 2012 1917.6 2013.6 1916.7 2015.6 C
78.4883 +1913.7 2017.4 1919.6 2014.8 1917.6 2013.6 C
78.4884 +f
78.4885 +S
78.4886 +n
78.4887 +1887.2 2015.3 m
78.4888 +1887.2 2008.9 1887.2 2002.5 1887.2 1996.1 C
78.4889 +1887.2 2002.5 1887.2 2008.9 1887.2 2015.3 C
78.4890 +f
78.4891 +S
78.4892 +n
78.4893 +1916.7 2014.4 m
78.4894 +1917 2012.1 1913 2013 1913.8 2010.8 C
78.4895 +1912.1 2009.8 1910.9 2009.4 1910.7 2007.9 C
78.4896 +1910.4 2010.6 1913.4 2010.4 1914 2012.4 C
78.4897 +1914.9 2012.8 1916.6 2012.9 1916.4 2014.4 C
78.4898 +1916.9 2015.1 1914.5 2016.6 1916.2 2015.8 C
78.4899 +1916.4 2015.3 1916.7 2015 1916.7 2014.4 C
78.4900 +[0.65 0.65 0 0.42] vc
78.4901 +f
78.4902 +S
78.4903 +n
78.4904 +1914 2009.3 m
78.4905 +1912.8 2010.9 1909.6 2005.3 1911.9 2009.8 C
78.4906 +1912.3 2009.6 1913.6 2010.2 1914 2009.3 C
78.4907 +[0.92 0.92 0 0.67] vc
78.4908 +f
78.4909 +S
78.4910 +n
78.4911 +1951.2 1998.8 m
78.4912 +1949 1996.4 1951.5 1994 1950.3 1991.8 C
78.4913 +1949.1 1989.1 1954 1982.7 1948.8 1981.2 C
78.4914 +1949.2 1981.5 1951 1982.4 1950.8 1983.6 C
78.4915 +1951.9 1988.6 1947.1 1986.5 1948.1 1990.4 C
78.4916 +1948.5 1990.3 1948.7 1990.7 1948.6 1991.1 C
78.4917 +1949 1992.5 1947.3 1991.9 1948.1 1992.5 C
78.4918 +1947.1 1992.7 1945.7 1993.5 1945.2 1994.7 C
78.4919 +1944.5 1996.8 1947.7 2000.5 1943.8 2001.4 C
78.4920 +1943.4 2002 1943.7 2004 1942.4 2004.5 C
78.4921 +1945.2 2002.2 1948.9 2000.9 1951.2 1998.8 C
78.4922 +f
78.4923 +S
78.4924 +n
78.4925 +1994.9 1993 m
78.4926 +1995.1 1996.5 1994.5 2000.3 1995.4 2003.6 C
78.4927 +1994.5 2000.3 1995.1 1996.5 1994.9 1993 C
78.4928 +f
78.4929 +S
78.4930 +n
78.4931 +1913.8 2003.3 m
78.4932 +1913.8 1996.9 1913.8 1990.5 1913.8 1984.1 C
78.4933 +1913.8 1990.5 1913.8 1996.9 1913.8 2003.3 C
78.4934 +f
78.4935 +S
78.4936 +n
78.4937 +1941.9 1998 m
78.4938 +1940.5 1997.3 1940.7 1999.4 1940.7 2000 C
78.4939 +1942.8 2001.3 1942.6 1998.8 1941.9 1998 C
78.4940 +[0 0 0 0] vc
78.4941 +f
78.4942 +S
78.4943 +n
78.4944 +vmrs
78.4945 +1942.1 1999.2 m
78.4946 +1942.2 1998.9 1941.8 1998.8 1941.6 1998.5 C
78.4947 +1940.4 1998 1940.7 1999.7 1940.7 2000 C
78.4948 +1941.6 2000.3 1942.6 2000.4 1942.1 1999.2 C
78.4949 +[0.92 0.92 0 0.67] vc
78.4950 +f
78.4951 +0.4 w
78.4952 +2 J
78.4953 +2 M
78.4954 +S
78.4955 +n
78.4956 +1940 1997.1 m
78.4957 +1939.8 1996 1939.7 1995.9 1939.2 1995.2 C
78.4958 +1939.1 1995.3 1938.5 1997.9 1937.8 1996.4 C
78.4959 +1938 1997.3 1939.4 1998.6 1940 1997.1 C
78.4960 +f
78.4961 +S
78.4962 +n
78.4963 +1911.2 1995.9 m
78.4964 +1911.2 1991.6 1911.3 1987.2 1911.4 1982.9 C
78.4965 +1911.3 1987.2 1911.2 1991.6 1911.2 1995.9 C
78.4966 +f
78.4967 +S
78.4968 +n
78.4969 +1947.2 1979.1 m
78.4970 +1945.1 1978.8 1944.6 1975.7 1942.4 1975 C
78.4971 +1940.5 1972.6 1942.2 1973.7 1942.4 1975.7 C
78.4972 +1945.8 1975.5 1944.2 1979.8 1947.6 1979.6 C
78.4973 +1948.3 1982.3 1948.5 1980 1947.2 1979.1 C
78.4974 +f
78.4975 +S
78.4976 +n
78.4977 +1939.5 1973.3 m
78.4978 +1940.1 1972.6 1939.8 1974.2 1940.2 1973.1 C
78.4979 +1939.1 1972.8 1938.8 1968.5 1935.9 1969.7 C
78.4980 +1937.4 1969.2 1938.5 1970.6 1939 1971.4 C
78.4981 +1939.2 1972.7 1938.6 1973.9 1939.5 1973.3 C
78.4982 +f
78.4983 +S
78.4984 +n
78.4985 +1975.2 2073.2 m
78.4986 +1975.2 2070.2 1975.2 2067.2 1975.2 2064.3 C
78.4987 +1975.2 2067.2 1975.2 2070.2 1975.2 2073.2 C
78.4988 +[0.18 0.18 0 0.78] vc
78.4989 +f
78.4990 +S
78.4991 +n
78.4992 +1929.9 2065.7 m
78.4993 +1928.1 2065.6 1926 2068.8 1924.1 2066.9 C
78.4994 +1918.1 2060.9 1912.9 2055.7 1907.1 2049.9 C
78.4995 +1906.7 2047.1 1906.9 2043.9 1906.8 2041 C
78.4996 +1906.8 2043.9 1906.8 2046.8 1906.8 2049.6 C
78.4997 +1913.2 2055.5 1918.7 2061.9 1925.1 2067.6 C
78.4998 +1927.1 2067.9 1928.6 2064.4 1930.1 2066.2 C
78.4999 +1929.7 2070.3 1929.9 2074.7 1929.9 2078.9 C
78.5000 +1929.6 2074.4 1930.5 2070.1 1929.9 2065.7 C
78.5001 +[0.07 0.06 0 0.58] vc
78.5002 +f
78.5003 +S
78.5004 +n
78.5005 +1930.1 2061.6 m
78.5006 +1928.1 2062.1 1927 2065.1 1924.8 2064.3 C
78.5007 +1920.7 2058.9 1914.4 2054.3 1910.2 2049.2 C
78.5008 +1910.2 2048.1 1910.2 2047.1 1910.2 2046 C
78.5009 +1909.8 2046.8 1910 2048.3 1910 2049.4 C
78.5010 +1915.1 2054.9 1920.3 2059 1925.3 2064.8 C
78.5011 +1927.1 2064.2 1928.4 2062.3 1930.1 2061.6 C
78.5012 +[0.18 0.18 0 0.78] vc
78.5013 +f
78.5014 +S
78.5015 +n
78.5016 +1932 2049.9 m
78.5017 +1932.3 2050.3 1932 2050.4 1932.8 2050.4 C
78.5018 +1932 2050.4 1932.2 2049.2 1931.3 2049.6 C
78.5019 +1931.4 2050.5 1930.3 2050.4 1930.4 2051.3 C
78.5020 +1931.1 2051.1 1930.7 2049.4 1932 2049.9 C
78.5021 +f
78.5022 +S
78.5023 +n
78.5024 +1938.3 2046 m
78.5025 +1936.3 2046.8 1935.2 2047.2 1934.2 2048.9 C
78.5026 +1935.3 2047.7 1936.8 2046.2 1938.3 2046 C
78.5027 +[0.4 0.4 0 0] vc
78.5028 +f
78.5029 +S
78.5030 +n
78.5031 +vmrs
78.5032 +1938.3 2047 m
78.5033 +1937.9 2046.9 1936.6 2047.1 1936.1 2048 C
78.5034 +1936.5 2047.5 1937.3 2046.7 1938.3 2047 C
78.5035 +[0.18 0.18 0 0.78] vc
78.5036 +f
78.5037 +0.4 w
78.5038 +2 J
78.5039 +2 M
78.5040 +S
78.5041 +n
78.5042 +1910.2 2043.2 m
78.5043 +1910.1 2037.5 1910 2031.8 1910 2026.1 C
78.5044 +1910 2031.8 1910.1 2037.5 1910.2 2043.2 C
78.5045 +f
78.5046 +S
78.5047 +n
78.5048 +1933.5 2032.1 m
78.5049 +1933.7 2035.2 1932.8 2035.8 1933.7 2038.6 C
78.5050 +1933.3 2036.6 1934.6 2018 1933.5 2032.1 C
78.5051 +f
78.5052 +S
78.5053 +n
78.5054 +1907.3 2021.8 m
78.5055 +1906.6 2025.9 1909.4 2032.6 1903.2 2034 C
78.5056 +1902.8 2034.1 1902.4 2033.9 1902 2033.8 C
78.5057 +1897.9 2028.5 1891.6 2023.8 1887.4 2018.7 C
78.5058 +1887.4 2017.7 1887.4 2016.6 1887.4 2015.6 C
78.5059 +1887 2016.3 1887.2 2017.8 1887.2 2018.9 C
78.5060 +1892.3 2024.4 1897.5 2028.5 1902.5 2034.3 C
78.5061 +1904.3 2033.6 1905.7 2032 1907.3 2030.9 C
78.5062 +1907.3 2027.9 1907.3 2024.9 1907.3 2021.8 C
78.5063 +f
78.5064 +S
78.5065 +n
78.5066 +1933.7 2023.2 m
78.5067 +1932 2021.7 1931.1 2024.9 1929.4 2024.9 C
78.5068 +1931.2 2024.7 1932.4 2021.5 1933.7 2023.2 C
78.5069 +f
78.5070 +S
78.5071 +n
78.5072 +1989.2 2024.4 m
78.5073 +1987.4 2023.7 1985.8 2022.2 1985.1 2020.4 C
78.5074 +1984.6 2020.1 1986 2018.9 1985.1 2019.2 C
78.5075 +1985.6 2020.8 1984.1 2019.4 1984.6 2021.1 C
78.5076 +1986.3 2022.3 1988.1 2025.3 1989.2 2024.4 C
78.5077 +f
78.5078 +S
78.5079 +n
78.5080 +1904.4 2031.9 m
78.5081 +1903 2029.7 1905.3 2027.7 1904.2 2025.9 C
78.5082 +1904.5 2025 1903.7 2023 1904 2021.3 C
78.5083 +1904 2022.3 1903.2 2022 1902.5 2022 C
78.5084 +1901.3 2022.3 1902.2 2020.1 1901.6 2019.6 C
78.5085 +1902.5 2019.8 1902.6 2018.3 1903.5 2018.9 C
78.5086 +1903.7 2021.8 1905.6 2016.8 1905.6 2020.6 C
78.5087 +1905.9 2020 1906.3 2020.8 1906.1 2021.1 C
78.5088 +1905.8 2022.7 1906.7 2020.4 1906.4 2019.9 C
78.5089 +1906.4 2018.5 1908.2 2017.8 1906.8 2016.5 C
78.5090 +1906.9 2015.7 1907.7 2017.1 1907.1 2016.3 C
78.5091 +1908.5 2015.8 1910.3 2015.1 1911.6 2016 C
78.5092 +1912.2 2016.2 1911.9 2018 1911.6 2018 C
78.5093 +1914.5 2017.1 1910.4 2013.6 1913.3 2013.4 C
78.5094 +1912.4 2011.3 1910.5 2011.8 1909.5 2010 C
78.5095 +1910 2010.5 1909 2010.8 1908.8 2011.2 C
78.5096 +1907.5 2009.9 1906.1 2011.7 1904.9 2011.5 C
78.5097 +1904.7 2010.9 1904.3 2010.5 1904.4 2009.8 C
78.5098 +1905 2010.2 1904.6 2008.6 1905.4 2008.1 C
78.5099 +1906.6 2007.5 1907.7 2008.4 1908.5 2007.4 C
78.5100 +1908.9 2008.5 1909.7 2008.1 1909 2007.2 C
78.5101 +1908.1 2006.5 1905.9 2007.3 1905.4 2007.4 C
78.5102 +1903.9 2007.3 1905.2 2008.5 1904.2 2008.4 C
78.5103 +1904.6 2009.9 1902.8 2010.3 1902.3 2010.5 C
78.5104 +1901.5 2009.9 1900.4 2010 1899.4 2010 C
78.5105 +1898.6 2011.2 1898.2 2013.4 1896.5 2013.4 C
78.5106 +1896 2012.9 1894.4 2012.9 1893.6 2012.9 C
78.5107 +1893.1 2013.9 1892.9 2015.5 1891.5 2016 C
78.5108 +1890.3 2016.1 1889.2 2014 1888.6 2015.8 C
78.5109 +1890 2016 1891 2016.9 1892.9 2016.5 C
78.5110 +1894.1 2017.2 1892.8 2018.3 1893.2 2018.9 C
78.5111 +1892.6 2018.9 1891.1 2019.8 1890.5 2020.6 C
78.5112 +1891.1 2023.6 1893.2 2019.8 1893.9 2022.5 C
78.5113 +1894.1 2023.3 1892.7 2023.6 1893.9 2024 C
78.5114 +1894.2 2024.3 1897.4 2023.8 1896.5 2026.1 C
78.5115 +1896 2025.6 1897.4 2028.1 1897.5 2027.1 C
78.5116 +1898.4 2027.4 1899.3 2027 1899.6 2028.5 C
78.5117 +1899.5 2028.6 1899.4 2028.8 1899.2 2028.8 C
78.5118 +1899.3 2029.2 1899.6 2029.8 1900.1 2030.2 C
78.5119 +1900.4 2029.6 1901 2030 1901.8 2030.2 C
78.5120 +1903.1 2032.1 1900.4 2031.5 1902.8 2033.1 C
78.5121 +1903.3 2032.7 1904.5 2032 1904.4 2031.9 C
78.5122 +[0.21 0.21 0 0] vc
78.5123 +f
78.5124 +S
78.5125 +n
78.5126 +1909.2 2019.4 m
78.5127 +1908.8 2020.3 1910.2 2019.8 1909.2 2019.2 C
78.5128 +1908.3 2019.3 1907.6 2020.2 1907.6 2021.3 C
78.5129 +1908.5 2021 1907.6 2019 1909.2 2019.4 C
78.5130 +[0.18 0.18 0 0.78] vc
78.5131 +f
78.5132 +S
78.5133 +n
78.5134 +1915.5 2015.6 m
78.5135 +1913.5 2016.3 1912.4 2016.8 1911.4 2018.4 C
78.5136 +1912.5 2017.2 1914 2015.7 1915.5 2015.6 C
78.5137 +[0.4 0.4 0 0] vc
78.5138 +f
78.5139 +S
78.5140 +n
78.5141 +1915.5 2016.5 m
78.5142 +1915.1 2016.4 1913.8 2016.6 1913.3 2017.5 C
78.5143 +1913.7 2017 1914.5 2016.2 1915.5 2016.5 C
78.5144 +[0.18 0.18 0 0.78] vc
78.5145 +f
78.5146 +S
78.5147 +n
78.5148 +vmrs
78.5149 +1887.4 2012.7 m
78.5150 +1887.3 2007 1887.2 2001.3 1887.2 1995.6 C
78.5151 +1887.2 2001.3 1887.3 2007 1887.4 2012.7 C
78.5152 +[0.18 0.18 0 0.78] vc
78.5153 +f
78.5154 +0.4 w
78.5155 +2 J
78.5156 +2 M
78.5157 +S
78.5158 +n
78.5159 +1935.9 2007.4 m
78.5160 +1936.2 2007.8 1935.8 2007.9 1936.6 2007.9 C
78.5161 +1935.9 2007.9 1936.1 2006.7 1935.2 2007.2 C
78.5162 +1935.2 2008.1 1934.1 2007.9 1934.2 2008.8 C
78.5163 +1935 2008.7 1934.6 2006.9 1935.9 2007.4 C
78.5164 +f
78.5165 +S
78.5166 +n
78.5167 +1942.1 2003.6 m
78.5168 +1940.1 2004.3 1939.1 2004.8 1938 2006.4 C
78.5169 +1939.1 2005.2 1940.6 2003.7 1942.1 2003.6 C
78.5170 +[0.4 0.4 0 0] vc
78.5171 +f
78.5172 +S
78.5173 +n
78.5174 +1942.1 2004.5 m
78.5175 +1941.8 2004.4 1940.4 2004.6 1940 2005.5 C
78.5176 +1940.4 2005 1941.2 2004.2 1942.1 2004.5 C
78.5177 +[0.18 0.18 0 0.78] vc
78.5178 +f
78.5179 +S
78.5180 +n
78.5181 +1914 2000.7 m
78.5182 +1914 1995 1913.9 1989.3 1913.8 1983.6 C
78.5183 +1913.9 1989.3 1914 1995 1914 2000.7 C
78.5184 +f
78.5185 +S
78.5186 +n
78.5187 +1941.6 1998.3 m
78.5188 +1943.4 2001.9 1942.4 1996 1940.9 1998.3 C
78.5189 +1941.2 1998.3 1941.4 1998.3 1941.6 1998.3 C
78.5190 +f
78.5191 +S
78.5192 +n
78.5193 +1954.8 1989.9 m
78.5194 +1953.9 1989.6 1954.7 1991.6 1953.9 1991.1 C
78.5195 +1954.5 1993.1 1953.6 1998 1954.6 1993.2 C
78.5196 +1954 1992.2 1954.7 1990.7 1954.8 1989.9 C
78.5197 +f
78.5198 +S
78.5199 +n
78.5200 +1947.6 1992.5 m
78.5201 +1946.2 1993.5 1944.9 1993 1944.8 1994.7 C
78.5202 +1945.5 1994 1947 1992.2 1947.6 1992.5 C
78.5203 +f
78.5204 +S
78.5205 +n
78.5206 +1910.7 1982.2 m
78.5207 +1910.3 1981.8 1909.7 1982 1909.2 1982 C
78.5208 +1909.7 1982 1910.3 1981.9 1910.7 1982.2 C
78.5209 +1911 1987.1 1910 1992.6 1910.7 1997.3 C
78.5210 +1910.7 1992.3 1910.7 1987.2 1910.7 1982.2 C
78.5211 +[0.65 0.65 0 0.42] vc
78.5212 +f
78.5213 +S
78.5214 +n
78.5215 +1910.9 1992.8 m
78.5216 +1910.9 1991.3 1910.9 1989.7 1910.9 1988.2 C
78.5217 +1910.9 1989.7 1910.9 1991.3 1910.9 1992.8 C
78.5218 +[0.18 0.18 0 0.78] vc
78.5219 +f
78.5220 +S
78.5221 +n
78.5222 +vmrs
78.5223 +1953.6 1983.6 m
78.5224 +1954.1 1985.3 1953.2 1988.6 1954.8 1989.4 C
78.5225 +1954.1 1987.9 1954.4 1985.4 1953.6 1983.6 C
78.5226 +[0.18 0.18 0 0.78] vc
78.5227 +f
78.5228 +0.4 w
78.5229 +2 J
78.5230 +2 M
78.5231 +S
78.5232 +n
78.5233 +1910.7 1982 m
78.5234 +1911.6 1982.9 1911 1984.4 1911.2 1985.6 C
78.5235 +1911 1984.4 1911.6 1982.9 1910.7 1982 C
78.5236 +f
78.5237 +S
78.5238 +n
78.5239 +1947.2 1979.6 m
78.5240 +1947.5 1980.6 1948.3 1980.6 1947.4 1979.6 C
78.5241 +1946.2 1979.4 1945.7 1978.8 1947.2 1979.6 C
78.5242 +f
78.5243 +S
78.5244 +n
78.5245 +1930.4 2061.4 m
78.5246 +1930.4 2058 1930.4 2053.5 1930.4 2051.1 C
78.5247 +1930.7 2054.6 1929.8 2057.4 1930.1 2061.2 C
78.5248 +1929.5 2061.9 1929.7 2061.2 1930.4 2061.4 C
78.5249 +[0.65 0.65 0 0.42] vc
78.5250 +f
78.5251 +S
78.5252 +n
78.5253 +1939.5 2044.8 m
78.5254 +1940 2041.5 1935.2 2044.3 1936.4 2040.8 C
78.5255 +1934.9 2040.9 1934.1 2039.7 1933.5 2038.6 C
78.5256 +1933.3 2035.4 1933.2 2040 1934 2040.3 C
78.5257 +1936.2 2040.6 1936.3 2043.6 1938.5 2043.4 C
78.5258 +1939.7 2044.2 1939.4 2045.6 1938.3 2046.5 C
78.5259 +1939.1 2046.6 1939.6 2045.6 1939.5 2044.8 C
78.5260 +f
78.5261 +S
78.5262 +n
78.5263 +1910.4 2045.3 m
78.5264 +1910.4 2039.5 1910.4 2033.6 1910.4 2027.8 C
78.5265 +1910.4 2033.6 1910.4 2039.5 1910.4 2045.3 C
78.5266 +f
78.5267 +S
78.5268 +n
78.5269 +1906.8 2030.9 m
78.5270 +1907.6 2026.8 1905 2020.8 1909 2018.7 C
78.5271 +1906.5 2018.9 1906.8 2022.4 1906.8 2024.7 C
78.5272 +1906.4 2028.2 1907.9 2032 1903 2033.8 C
78.5273 +1902.2 2034 1903.8 2033.4 1904.2 2033.1 C
78.5274 +1905.1 2032.4 1905.9 2031.5 1906.8 2030.9 C
78.5275 +[0.07 0.06 0 0.58] vc
78.5276 +f
78.5277 +S
78.5278 +n
78.5279 +1907.1 2030.7 m
78.5280 +1907.1 2028.8 1907.1 2027 1907.1 2025.2 C
78.5281 +1907.1 2027 1907.1 2028.8 1907.1 2030.7 C
78.5282 +[0.65 0.65 0 0.42] vc
78.5283 +f
78.5284 +S
78.5285 +n
78.5286 +1932 2023.2 m
78.5287 +1932.2 2023.6 1931.7 2023.7 1931.6 2024 C
78.5288 +1932 2023.7 1932.3 2022.8 1933 2023 C
78.5289 +1933.9 2024.3 1933.3 2026.2 1933.5 2027.8 C
78.5290 +1933.5 2026.4 1934.9 2022.2 1932 2023.2 C
78.5291 +f
78.5292 +S
78.5293 +n
78.5294 +2026.1 2021.6 m
78.5295 +2026.1 2020.8 2026.1 2019.9 2026.1 2019.2 C
78.5296 +2026.1 2019.9 2026.1 2020.8 2026.1 2021.6 C
78.5297 +f
78.5298 +S
78.5299 +n
78.5300 +vmrs
78.5301 +1934.2 2018.9 m
78.5302 +1934.2 2015.5 1934.2 2011 1934.2 2008.6 C
78.5303 +1934.5 2012.1 1933.7 2014.9 1934 2018.7 C
78.5304 +1933.4 2019.5 1933.5 2018.7 1934.2 2018.9 C
78.5305 +[0.65 0.65 0 0.42] vc
78.5306 +f
78.5307 +0.4 w
78.5308 +2 J
78.5309 +2 M
78.5310 +S
78.5311 +n
78.5312 +1887.6 2014.8 m
78.5313 +1887.6 2009 1887.6 2003.1 1887.6 1997.3 C
78.5314 +1887.6 2003.1 1887.6 2009 1887.6 2014.8 C
78.5315 +f
78.5316 +S
78.5317 +n
78.5318 +1914.3 2002.8 m
78.5319 +1914.3 1997 1914.3 1991.1 1914.3 1985.3 C
78.5320 +1914.3 1991.1 1914.3 1997 1914.3 2002.8 C
78.5321 +f
78.5322 +S
78.5323 +n
78.5324 +1995.4 1992.3 m
78.5325 +1995.4 1991.5 1995.4 1990.7 1995.4 1989.9 C
78.5326 +1995.4 1990.7 1995.4 1991.5 1995.4 1992.3 C
78.5327 +f
78.5328 +S
78.5329 +n
78.5330 +1896 1988.4 m
78.5331 +1896.9 1988 1897.8 1987.7 1898.7 1987.2 C
78.5332 +1897.8 1987.7 1896.9 1988 1896 1988.4 C
78.5333 +f
78.5334 +S
78.5335 +n
78.5336 +1899.4 1986.8 m
78.5337 +1900.4 1986.3 1901.3 1985.8 1902.3 1985.3 C
78.5338 +1901.3 1985.8 1900.4 1986.3 1899.4 1986.8 C
78.5339 +f
78.5340 +S
78.5341 +n
78.5342 +1902.8 1985.1 m
78.5343 +1905.2 1984 1905.2 1984 1902.8 1985.1 C
78.5344 +f
78.5345 +S
78.5346 +n
78.5347 +1949.1 1983.4 m
78.5348 +1950.2 1984.4 1947.8 1984.6 1949.3 1985.1 C
78.5349 +1949.5 1984.4 1949.6 1984.1 1949.1 1983.4 C
78.5350 +[0.07 0.06 0 0.58] vc
78.5351 +f
78.5352 +S
78.5353 +n
78.5354 +1906.1 1983.4 m
78.5355 +1908.6 1982 1908.6 1982 1906.1 1983.4 C
78.5356 +[0.65 0.65 0 0.42] vc
78.5357 +f
78.5358 +S
78.5359 +n
78.5360 +1922.7 1976.4 m
78.5361 +1923.6 1976 1924.4 1975.7 1925.3 1975.2 C
78.5362 +1924.4 1975.7 1923.6 1976 1922.7 1976.4 C
78.5363 +f
78.5364 +S
78.5365 +n
78.5366 +vmrs
78.5367 +1926 1974.8 m
78.5368 +1927 1974.3 1928 1973.8 1928.9 1973.3 C
78.5369 +1928 1973.8 1927 1974.3 1926 1974.8 C
78.5370 +[0.65 0.65 0 0.42] vc
78.5371 +f
78.5372 +0.4 w
78.5373 +2 J
78.5374 +2 M
78.5375 +S
78.5376 +n
78.5377 +1929.4 1973.1 m
78.5378 +1931.9 1972 1931.9 1972 1929.4 1973.1 C
78.5379 +f
78.5380 +S
78.5381 +n
78.5382 +1932.8 1971.4 m
78.5383 +1935.3 1970 1935.3 1970 1932.8 1971.4 C
78.5384 +f
78.5385 +S
78.5386 +n
78.5387 +1949.6 2097.2 m
78.5388 +1951.1 2096.4 1952.6 2095.5 1954.1 2094.8 C
78.5389 +1952.6 2095.5 1951.1 2096.4 1949.6 2097.2 C
78.5390 +[0.07 0.06 0 0.58] vc
78.5391 +f
78.5392 +S
78.5393 +n
78.5394 +1955.1 2094.3 m
78.5395 +1956.7 2093.5 1958.3 2092.7 1959.9 2091.9 C
78.5396 +1958.3 2092.7 1956.7 2093.5 1955.1 2094.3 C
78.5397 +f
78.5398 +S
78.5399 +n
78.5400 +1960.4 2091.6 m
78.5401 +1961.3 2091.2 1962.1 2090.9 1963 2090.4 C
78.5402 +1962.1 2090.9 1961.3 2091.2 1960.4 2091.6 C
78.5403 +f
78.5404 +S
78.5405 +n
78.5406 +1963.5 2090.2 m
78.5407 +1964.4 2089.7 1965.2 2089.2 1966.1 2088.8 C
78.5408 +1965.2 2089.2 1964.4 2089.7 1963.5 2090.2 C
78.5409 +f
78.5410 +S
78.5411 +n
78.5412 +1966.6 2088.5 m
78.5413 +1969.5 2087.1 1972.4 2085.8 1975.2 2084.4 C
78.5414 +1972.4 2085.8 1969.5 2087.1 1966.6 2088.5 C
78.5415 +f
78.5416 +S
78.5417 +n
78.5418 +1965.2 2086.1 m
78.5419 +1965.9 2085.7 1966.8 2085.3 1967.6 2084.9 C
78.5420 +1966.8 2085.3 1965.9 2085.7 1965.2 2086.1 C
78.5421 +f
78.5422 +S
78.5423 +n
78.5424 +1968.3 2084.7 m
78.5425 +1969.2 2084.3 1970 2083.9 1970.9 2083.5 C
78.5426 +1970 2083.9 1969.2 2084.3 1968.3 2084.7 C
78.5427 +f
78.5428 +S
78.5429 +n
78.5430 +vmrs
78.5431 +1984.1 2084 m
78.5432 +1985.6 2083.2 1987.2 2082.3 1988.7 2081.6 C
78.5433 +1987.2 2082.3 1985.6 2083.2 1984.1 2084 C
78.5434 +[0.07 0.06 0 0.58] vc
78.5435 +f
78.5436 +0.4 w
78.5437 +2 J
78.5438 +2 M
78.5439 +S
78.5440 +n
78.5441 +1976 2078.7 m
78.5442 +1978.1 2080.1 1980 2082 1982 2083.7 C
78.5443 +1980 2081.9 1977.9 2080.3 1976 2078.2 C
78.5444 +1975.5 2079.9 1975.8 2081.9 1975.7 2083.7 C
78.5445 +1975.8 2082 1975.5 2080.2 1976 2078.7 C
78.5446 +f
78.5447 +S
78.5448 +n
78.5449 +1989.6 2081.1 m
78.5450 +1991.3 2080.3 1992.8 2079.5 1994.4 2078.7 C
78.5451 +1992.8 2079.5 1991.3 2080.3 1989.6 2081.1 C
78.5452 +f
78.5453 +S
78.5454 +n
78.5455 +1933.2 2074.6 m
78.5456 +1932.4 2076.2 1932.8 2077.5 1933 2078.7 C
78.5457 +1933 2077.6 1932.9 2074.8 1933.2 2074.6 C
78.5458 +f
78.5459 +S
78.5460 +n
78.5461 +1994.9 2078.4 m
78.5462 +1995.8 2078 1996.7 2077.7 1997.6 2077.2 C
78.5463 +1996.7 2077.7 1995.8 2078 1994.9 2078.4 C
78.5464 +f
78.5465 +S
78.5466 +n
78.5467 +1998 2077 m
78.5468 +1998.9 2076.5 1999.8 2076 2000.7 2075.6 C
78.5469 +1999.8 2076 1998.9 2076.5 1998 2077 C
78.5470 +f
78.5471 +S
78.5472 +n
78.5473 +2001.2 2075.3 m
78.5474 +2004 2073.9 2006.9 2072.6 2009.8 2071.2 C
78.5475 +2006.9 2072.6 2004 2073.9 2001.2 2075.3 C
78.5476 +f
78.5477 +S
78.5478 +n
78.5479 +1980.5 2060.7 m
78.5480 +1979.9 2060.7 1976.7 2062.8 1975.7 2064.5 C
78.5481 +1975.7 2067.5 1975.7 2070.5 1975.7 2073.4 C
78.5482 +1976.3 2068.7 1973.9 2061.6 1980.5 2060.7 C
78.5483 +f
78.5484 +S
78.5485 +n
78.5486 +1999.7 2072.9 m
78.5487 +2000.5 2072.5 2001.3 2072.1 2002.1 2071.7 C
78.5488 +2001.3 2072.1 2000.5 2072.5 1999.7 2072.9 C
78.5489 +f
78.5490 +S
78.5491 +n
78.5492 +2002.8 2071.5 m
78.5493 +2003.7 2071.1 2004.6 2070.7 2005.5 2070.3 C
78.5494 +2004.6 2070.7 2003.7 2071.1 2002.8 2071.5 C
78.5495 +f
78.5496 +S
78.5497 +n
78.5498 +vmrs
78.5499 +2015.1 2047.5 m
78.5500 +2014.4 2047.5 2011.2 2049.6 2010.3 2051.3 C
78.5501 +2010.3 2057.7 2010.3 2064.1 2010.3 2070.5 C
78.5502 +2010.3 2063.9 2010.1 2057.1 2010.5 2050.6 C
78.5503 +2012 2049.3 2013.5 2048.3 2015.1 2047.5 C
78.5504 +[0.07 0.06 0 0.58] vc
78.5505 +f
78.5506 +0.4 w
78.5507 +2 J
78.5508 +2 M
78.5509 +S
78.5510 +n
78.5511 +1910.4 2049.2 m
78.5512 +1914.8 2054.3 1920.7 2058.9 1925.1 2064 C
78.5513 +1920.4 2058.6 1915.1 2054.6 1910.4 2049.2 C
78.5514 +f
78.5515 +S
78.5516 +n
78.5517 +1988.2 2057.3 m
78.5518 +1989.1 2056.8 1989.9 2056.2 1990.8 2055.6 C
78.5519 +1989.9 2056.2 1989.1 2056.8 1988.2 2057.3 C
78.5520 +f
78.5521 +S
78.5522 +n
78.5523 +1991.6 2051.3 m
78.5524 +1991.6 2046.3 1991.6 2041.2 1991.6 2036.2 C
78.5525 +1991.6 2041.2 1991.6 2046.3 1991.6 2051.3 C
78.5526 +f
78.5527 +S
78.5528 +n
78.5529 +1935.6 2047.5 m
78.5530 +1932.9 2051.7 1939.7 2043.8 1935.6 2047.5 C
78.5531 +f
78.5532 +S
78.5533 +n
78.5534 +1938.8 2043.9 m
78.5535 +1938.1 2043.3 1938.2 2043.7 1937.3 2043.4 C
78.5536 +1938.7 2043 1938.2 2044.9 1939 2045.3 C
78.5537 +1938.2 2045.3 1938.7 2046.6 1937.8 2046.5 C
78.5538 +1939.1 2046.2 1939.1 2044.5 1938.8 2043.9 C
78.5539 +f
78.5540 +S
78.5541 +n
78.5542 +1972.4 2045.6 m
78.5543 +1973.4 2045 1974.5 2044.4 1975.5 2043.9 C
78.5544 +1974.5 2044.4 1973.4 2045 1972.4 2045.6 C
78.5545 +f
78.5546 +S
78.5547 +n
78.5548 +1969 2043.6 m
78.5549 +1969.8 2043.2 1970.6 2042.9 1971.4 2042.4 C
78.5550 +1970.6 2042.9 1969.8 2043.2 1969 2043.6 C
78.5551 +f
78.5552 +S
78.5553 +n
78.5554 +1972.1 2042.2 m
78.5555 +1973 2041.8 1973.9 2041.4 1974.8 2041 C
78.5556 +1973.9 2041.4 1973 2041.8 1972.1 2042.2 C
78.5557 +f
78.5558 +S
78.5559 +n
78.5560 +1906.6 2035 m
78.5561 +1905 2034.7 1904.8 2036.6 1903.5 2036.9 C
78.5562 +1904.9 2037 1905.8 2033.4 1907.1 2035.7 C
78.5563 +1907.1 2037.2 1907.1 2038.6 1907.1 2040 C
78.5564 +1906.9 2038.4 1907.5 2036.4 1906.6 2035 C
78.5565 +f
78.5566 +S
78.5567 +n
78.5568 +vmrs
78.5569 +1937.1 2032.1 m
78.5570 +1936.2 2033.7 1936.6 2035 1936.8 2036.2 C
78.5571 +1936.8 2035.1 1936.8 2032.4 1937.1 2032.1 C
78.5572 +[0.07 0.06 0 0.58] vc
78.5573 +f
78.5574 +0.4 w
78.5575 +2 J
78.5576 +2 M
78.5577 +S
78.5578 +n
78.5579 +1887.6 2018.7 m
78.5580 +1892 2023.8 1897.9 2028.4 1902.3 2033.6 C
78.5581 +1897.6 2028.1 1892.3 2024.1 1887.6 2018.7 C
78.5582 +f
78.5583 +S
78.5584 +n
78.5585 +1999.7 2031.4 m
78.5586 +1998.7 2030.3 1997.6 2029.2 1996.6 2028 C
78.5587 +1997.6 2029.2 1998.7 2030.3 1999.7 2031.4 C
78.5588 +f
78.5589 +S
78.5590 +n
78.5591 +1912.8 2017 m
78.5592 +1910.6 2021.1 1913.6 2015.3 1914.5 2016 C
78.5593 +1914 2016.3 1913.4 2016.7 1912.8 2017 C
78.5594 +f
78.5595 +S
78.5596 +n
78.5597 +1939.5 2005 m
78.5598 +1936.7 2009.2 1943.6 2001.3 1939.5 2005 C
78.5599 +f
78.5600 +S
78.5601 +n
78.5602 +1942.6 2001.4 m
78.5603 +1941.9 2000.8 1942 2001.2 1941.2 2000.9 C
78.5604 +1942.5 2000.6 1942.1 2002.4 1942.8 2002.8 C
78.5605 +1942 2002.8 1942.5 2004.1 1941.6 2004 C
78.5606 +1943 2003.7 1942.9 2002.1 1942.6 2001.4 C
78.5607 +f
78.5608 +S
78.5609 +n
78.5610 +2006.2 2000.7 m
78.5611 +2005.4 2001.5 2004 2002.8 2004 2002.8 C
78.5612 +2004.5 2002.4 2005.5 2001.4 2006.2 2000.7 C
78.5613 +f
78.5614 +S
78.5615 +n
78.5616 +1998.5 2001.6 m
78.5617 +1997.7 2002 1996.8 2002.4 1995.9 2002.6 C
78.5618 +1995.5 1999.3 1995.7 1995.7 1995.6 1992.3 C
78.5619 +1995.6 1995.7 1995.6 1999.2 1995.6 2002.6 C
78.5620 +1996.6 2002.4 1997.7 2002.2 1998.5 2001.6 C
78.5621 +[0.4 0.4 0 0] vc
78.5622 +f
78.5623 +S
78.5624 +n
78.5625 +1996.1 2002.8 m
78.5626 +1995.9 2002.8 1995.8 2002.8 1995.6 2002.8 C
78.5627 +1995.2 1999.5 1995.5 1995.9 1995.4 1992.5 C
78.5628 +1995.4 1995.9 1995.4 1999.4 1995.4 2002.8 C
78.5629 +1996.4 2003.1 1998.2 2001.6 1996.1 2002.8 C
78.5630 +[0.07 0.06 0 0.58] vc
78.5631 +f
78.5632 +S
78.5633 +n
78.5634 +1969 2002.1 m
78.5635 +1968 2001 1966.9 1999.9 1965.9 1998.8 C
78.5636 +1966.9 1999.9 1968 2001 1969 2002.1 C
78.5637 +f
78.5638 +S
78.5639 +n
78.5640 +vmrs
78.5641 +2000 2001.2 m
78.5642 +2002.1 2000 2004.1 1998.9 2006.2 1997.8 C
78.5643 +2004.1 1998.9 2002.1 2000 2000 2001.2 C
78.5644 +[0.07 0.06 0 0.58] vc
78.5645 +f
78.5646 +0.4 w
78.5647 +2 J
78.5648 +2 M
78.5649 +S
78.5650 +n
78.5651 +1895.8 1984.8 m
78.5652 +1898.3 1983.6 1900.8 1982.3 1903.2 1981 C
78.5653 +1900.8 1982.3 1898.3 1983.6 1895.8 1984.8 C
78.5654 +f
78.5655 +S
78.5656 +n
78.5657 +1905.2 1980.3 m
78.5658 +1906.4 1979.9 1907.6 1979.5 1908.8 1979.1 C
78.5659 +1907.6 1979.5 1906.4 1979.9 1905.2 1980.3 C
78.5660 +f
78.5661 +S
78.5662 +n
78.5663 +1964.7 1977.4 m
78.5664 +1963.8 1977.5 1962.5 1980.2 1960.8 1980 C
78.5665 +1962.5 1980.2 1963.3 1978 1964.7 1977.4 C
78.5666 +f
78.5667 +S
78.5668 +n
78.5669 +1952 1979.6 m
78.5670 +1955.2 1979.2 1955.2 1979.2 1952 1979.6 C
78.5671 +f
78.5672 +S
78.5673 +n
78.5674 +1937.8 1966.4 m
78.5675 +1941.2 1969.5 1946.1 1976.4 1951.5 1979.3 C
78.5676 +1946.1 1976.7 1942.8 1970.4 1937.8 1966.4 C
78.5677 +f
78.5678 +S
78.5679 +n
78.5680 +1911.9 1978.6 m
78.5681 +1914.3 1977.4 1916.7 1976.2 1919.1 1975 C
78.5682 +1916.7 1976.2 1914.3 1977.4 1911.9 1978.6 C
78.5683 +f
78.5684 +S
78.5685 +n
78.5686 +1975.5 1971.4 m
78.5687 +1974.6 1972.2 1973.3 1973.6 1973.3 1973.6 C
78.5688 +1973.7 1973.1 1974.8 1972.1 1975.5 1971.4 C
78.5689 +f
78.5690 +S
78.5691 +n
78.5692 +1922.4 1972.8 m
78.5693 +1924.9 1971.6 1927.4 1970.3 1929.9 1969 C
78.5694 +1927.4 1970.3 1924.9 1971.6 1922.4 1972.8 C
78.5695 +f
78.5696 +S
78.5697 +n
78.5698 +1969.2 1971.9 m
78.5699 +1971.1 1970.9 1972.9 1969.8 1974.8 1968.8 C
78.5700 +1972.9 1969.8 1971.1 1970.9 1969.2 1971.9 C
78.5701 +f
78.5702 +S
78.5703 +n
78.5704 +vmrs
78.5705 +1931.8 1968.3 m
78.5706 +1933 1967.9 1934.2 1967.5 1935.4 1967.1 C
78.5707 +1934.2 1967.5 1933 1967.9 1931.8 1968.3 C
78.5708 +[0.07 0.06 0 0.58] vc
78.5709 +f
78.5710 +0.4 w
78.5711 +2 J
78.5712 +2 M
78.5713 +S
78.5714 +n
78.5715 +1940.7 2072.4 m
78.5716 +1941.5 2072.4 1942.3 2072.3 1943.1 2072.2 C
78.5717 +1942.3 2072.3 1941.5 2072.4 1940.7 2072.4 C
78.5718 +[0 0 0 0.18] vc
78.5719 +f
78.5720 +S
78.5721 +n
78.5722 +1948.6 2069.3 m
78.5723 +1947 2069.5 1945.7 2068.9 1944.8 2069.8 C
78.5724 +1945.9 2068.5 1948.4 2070.2 1948.6 2069.3 C
78.5725 +f
78.5726 +S
78.5727 +n
78.5728 +1954.6 2066.4 m
78.5729 +1954.7 2067.9 1955.6 2067.3 1955.6 2068.8 C
78.5730 +1955.4 2067.8 1956 2066.6 1954.6 2066.4 C
78.5731 +f
78.5732 +S
78.5733 +n
78.5734 +1929.2 2061.2 m
78.5735 +1927.8 2062.1 1926.3 2064.1 1924.8 2063.3 C
78.5736 +1926.3 2064.6 1928 2062 1929.2 2061.2 C
78.5737 +f
78.5738 +S
78.5739 +n
78.5740 +1924.4 2067.4 m
78.5741 +1918.5 2061.6 1912.7 2055.9 1906.8 2050.1 C
78.5742 +1912.7 2055.9 1918.5 2061.6 1924.4 2067.4 C
78.5743 +[0.4 0.4 0 0] vc
78.5744 +f
78.5745 +S
78.5746 +n
78.5747 +1924.6 2062.8 m
78.5748 +1923.9 2062.1 1923.2 2061.2 1922.4 2060.4 C
78.5749 +1923.2 2061.2 1923.9 2062.1 1924.6 2062.8 C
78.5750 +[0 0 0 0.18] vc
78.5751 +f
78.5752 +S
78.5753 +n
78.5754 +1919.3 2057.3 m
78.5755 +1917.5 2055.6 1915.7 2053.8 1913.8 2052 C
78.5756 +1915.7 2053.8 1917.5 2055.6 1919.3 2057.3 C
78.5757 +f
78.5758 +S
78.5759 +n
78.5760 +1929.2 2055.2 m
78.5761 +1929.2 2054.2 1929.2 2053.2 1929.2 2052.3 C
78.5762 +1929.2 2053.2 1929.2 2054.2 1929.2 2055.2 C
78.5763 +f
78.5764 +S
78.5765 +n
78.5766 +1926.3 2049.6 m
78.5767 +1925.4 2049 1925.4 2050.5 1924.4 2050.4 C
78.5768 +1925.3 2051.3 1924.5 2051.9 1925.6 2052.5 C
78.5769 +1926.9 2052.6 1926 2050.6 1926.3 2049.6 C
78.5770 +f
78.5771 +S
78.5772 +n
78.5773 +vmrs
78.5774 +1911.2 2046.8 m
78.5775 +1910.1 2048.9 1911.9 2050.1 1913.1 2051.3 C
78.5776 +1912.1 2049.9 1910.6 2048.8 1911.2 2046.8 C
78.5777 +[0 0 0 0.18] vc
78.5778 +f
78.5779 +0.4 w
78.5780 +2 J
78.5781 +2 M
78.5782 +S
78.5783 +n
78.5784 +1934 2048.7 m
78.5785 +1932.6 2048.7 1930.1 2047.7 1929.6 2049.4 C
78.5786 +1930.9 2048.6 1933.3 2049 1934 2048.7 C
78.5787 +f
78.5788 +S
78.5789 +n
78.5790 +1980 2048.4 m
78.5791 +1979.5 2046.8 1976.3 2047.9 1977.2 2045.6 C
78.5792 +1976.8 2045.1 1976.1 2044.7 1975.2 2044.8 C
78.5793 +1973.7 2046 1976.3 2046.4 1976.7 2047.5 C
78.5794 +1977.8 2047.2 1978.2 2050 1979.6 2049.2 C
78.5795 +1980 2049 1979.6 2048.6 1980 2048.4 C
78.5796 +f
78.5797 +S
78.5798 +n
78.5799 +1938.3 2045.6 m
78.5800 +1938.2 2044.4 1936.8 2043.8 1935.9 2043.4 C
78.5801 +1936.4 2044.4 1939.1 2044.3 1937.6 2045.8 C
78.5802 +1937 2046.1 1935.9 2046.1 1935.9 2046.8 C
78.5803 +1936.7 2046.3 1937.8 2046.2 1938.3 2045.6 C
78.5804 +f
78.5805 +S
78.5806 +n
78.5807 +1932.5 2040 m
78.5808 +1932.8 2038.1 1932 2038.9 1932.3 2040.3 C
78.5809 +1933.1 2040.3 1932.7 2041.7 1933.7 2041.5 C
78.5810 +1933.1 2041 1932.9 2040.5 1932.5 2040 C
78.5811 +f
78.5812 +S
78.5813 +n
78.5814 +2014.6 2035.2 m
78.5815 +2014.1 2033.6 2010.9 2034.7 2011.7 2032.4 C
78.5816 +2011.3 2031.9 2009.4 2030.7 2009.3 2032.1 C
78.5817 +2009.5 2033.7 2012.9 2033.8 2012.4 2035.7 C
78.5818 +2013 2036.4 2014.2 2036.5 2014.6 2035.2 C
78.5819 +f
78.5820 +S
78.5821 +n
78.5822 +1906.4 2030.7 m
78.5823 +1905 2031.6 1903.5 2033.6 1902 2032.8 C
78.5824 +1903.4 2034 1905.6 2031.4 1906.4 2030.7 C
78.5825 +f
78.5826 +S
78.5827 +n
78.5828 +1901.8 2037.2 m
78.5829 +1899.5 2034.8 1897.2 2032.5 1894.8 2030.2 C
78.5830 +1897.2 2032.5 1899.5 2034.8 1901.8 2037.2 C
78.5831 +[0.4 0.4 0 0] vc
78.5832 +f
78.5833 +S
78.5834 +n
78.5835 +1901.8 2032.4 m
78.5836 +1901.1 2031.6 1900.4 2030.7 1899.6 2030 C
78.5837 +1900.4 2030.7 1901.1 2031.6 1901.8 2032.4 C
78.5838 +[0 0 0 0.18] vc
78.5839 +f
78.5840 +S
78.5841 +n
78.5842 +1944.5 2030 m
78.5843 +1945.3 2029.9 1946.1 2029.8 1946.9 2029.7 C
78.5844 +1946.1 2029.8 1945.3 2029.9 1944.5 2030 C
78.5845 +f
78.5846 +S
78.5847 +n
78.5848 +vmrs
78.5849 +1997.8 2027.8 m
78.5850 +1997.7 2027.9 1997.6 2028.1 1997.3 2028 C
78.5851 +1997.4 2029.1 1998.5 2029.5 1999.2 2030 C
78.5852 +2000.1 2029.5 1998.9 2028 1997.8 2027.8 C
78.5853 +[0 0 0 0.18] vc
78.5854 +f
78.5855 +0.4 w
78.5856 +2 J
78.5857 +2 M
78.5858 +S
78.5859 +n
78.5860 +1906.4 2029.2 m
78.5861 +1906.4 2026.6 1906.4 2024 1906.4 2021.3 C
78.5862 +1906.4 2024 1906.4 2026.6 1906.4 2029.2 C
78.5863 +f
78.5864 +S
78.5865 +n
78.5866 +2006.2 2025.9 m
78.5867 +2006 2025.9 2005.8 2025.8 2005.7 2025.6 C
78.5868 +2005.7 2025.5 2005.7 2025.3 2005.7 2025.2 C
78.5869 +2004.6 2025.8 2002.7 2024.7 2001.9 2026.1 C
78.5870 +2001.9 2027.9 2007.8 2029.2 2006.2 2025.9 C
78.5871 +[0 0 0 0] vc
78.5872 +f
78.5873 +S
78.5874 +n
78.5875 +1952.4 2026.8 m
78.5876 +1950.9 2027 1949.6 2026.4 1948.6 2027.3 C
78.5877 +1949.7 2026.1 1952.2 2027.7 1952.4 2026.8 C
78.5878 +[0 0 0 0.18] vc
78.5879 +f
78.5880 +S
78.5881 +n
78.5882 +1896.5 2026.8 m
78.5883 +1894.7 2025.1 1892.9 2023.3 1891 2021.6 C
78.5884 +1892.9 2023.3 1894.7 2025.1 1896.5 2026.8 C
78.5885 +f
78.5886 +S
78.5887 +n
78.5888 +1958.4 2024 m
78.5889 +1958.5 2025.5 1959.4 2024.8 1959.4 2026.4 C
78.5890 +1959.3 2025.3 1959.8 2024.1 1958.4 2024 C
78.5891 +f
78.5892 +S
78.5893 +n
78.5894 +1903.5 2019.2 m
78.5895 +1902.6 2018.6 1902.6 2020 1901.6 2019.9 C
78.5896 +1902.5 2020.8 1901.7 2021.4 1902.8 2022 C
78.5897 +1904.1 2022.2 1903.2 2020.1 1903.5 2019.2 C
78.5898 +f
78.5899 +S
78.5900 +n
78.5901 +1933 2018.7 m
78.5902 +1931.7 2019.6 1930.1 2021.6 1928.7 2020.8 C
78.5903 +1930.1 2022.1 1931.8 2019.5 1933 2018.7 C
78.5904 +f
78.5905 +S
78.5906 +n
78.5907 +1888.4 2016.3 m
78.5908 +1887.3 2018.4 1889.1 2019.6 1890.3 2020.8 C
78.5909 +1889.3 2019.5 1887.8 2018.3 1888.4 2016.3 C
78.5910 +f
78.5911 +S
78.5912 +n
78.5913 +1928.4 2020.4 m
78.5914 +1927.7 2019.6 1927 2018.7 1926.3 2018 C
78.5915 +1927 2018.7 1927.7 2019.6 1928.4 2020.4 C
78.5916 +f
78.5917 +S
78.5918 +n
78.5919 +vmrs
78.5920 +1911.2 2018.2 m
78.5921 +1909.8 2018.3 1907.3 2017.2 1906.8 2018.9 C
78.5922 +1908.1 2018.1 1910.5 2018.6 1911.2 2018.2 C
78.5923 +[0 0 0 0.18] vc
78.5924 +f
78.5925 +0.4 w
78.5926 +2 J
78.5927 +2 M
78.5928 +S
78.5929 +n
78.5930 +1915.5 2015.1 m
78.5931 +1915.4 2013.9 1914 2013.3 1913.1 2012.9 C
78.5932 +1913.6 2013.9 1916.3 2013.8 1914.8 2015.3 C
78.5933 +1914.2 2015.6 1913.1 2015.6 1913.1 2016.3 C
78.5934 +1913.9 2015.9 1915 2015.7 1915.5 2015.1 C
78.5935 +f
78.5936 +S
78.5937 +n
78.5938 +1923.2 2014.8 m
78.5939 +1921.3 2013.1 1919.5 2011.3 1917.6 2009.6 C
78.5940 +1919.5 2011.3 1921.3 2013.1 1923.2 2014.8 C
78.5941 +f
78.5942 +S
78.5943 +n
78.5944 +1933 2012.7 m
78.5945 +1933 2011.7 1933 2010.8 1933 2009.8 C
78.5946 +1933 2010.8 1933 2011.7 1933 2012.7 C
78.5947 +f
78.5948 +S
78.5949 +n
78.5950 +1909.7 2008.1 m
78.5951 +1908.9 2009.2 1910.1 2009.9 1910.4 2011 C
78.5952 +1911.1 2010.7 1908.9 2009.7 1909.7 2008.1 C
78.5953 +f
78.5954 +S
78.5955 +n
78.5956 +1930.1 2007.2 m
78.5957 +1929.2 2006.6 1929.2 2008 1928.2 2007.9 C
78.5958 +1929.1 2008.8 1928.4 2009.4 1929.4 2010 C
78.5959 +1930.7 2010.2 1929.9 2008.1 1930.1 2007.2 C
78.5960 +f
78.5961 +S
78.5962 +n
78.5963 +1915 2004.3 m
78.5964 +1914 2006.4 1915.7 2007.6 1916.9 2008.8 C
78.5965 +1915.9 2007.5 1914.4 2006.3 1915 2004.3 C
78.5966 +f
78.5967 +S
78.5968 +n
78.5969 +1937.8 2006.2 m
78.5970 +1936.4 2006.3 1934 2005.2 1933.5 2006.9 C
78.5971 +1934.7 2006.1 1937.1 2006.6 1937.8 2006.2 C
78.5972 +f
78.5973 +S
78.5974 +n
78.5975 +1983.9 2006 m
78.5976 +1983.3 2004.3 1980.2 2005.4 1981 2003.1 C
78.5977 +1980.6 2002.7 1978.7 2001.5 1978.6 2002.8 C
78.5978 +1978.8 2004.4 1982.1 2004.5 1981.7 2006.4 C
78.5979 +1982.3 2007.2 1983.5 2007.2 1983.9 2006 C
78.5980 +f
78.5981 +S
78.5982 +n
78.5983 +1942.1 2003.1 m
78.5984 +1942 2001.9 1940.6 2001.3 1939.7 2000.9 C
78.5985 +1940.2 2001.9 1943 2001.8 1941.4 2003.3 C
78.5986 +1940.9 2003.6 1939.7 2003.6 1939.7 2004.3 C
78.5987 +1940.5 2003.9 1941.6 2003.7 1942.1 2003.1 C
78.5988 +f
78.5989 +S
78.5990 +n
78.5991 +vmrs
78.5992 +1967.1 1998.5 m
78.5993 +1967 1998.6 1966.8 1998.8 1966.6 1998.8 C
78.5994 +1966.7 1999.8 1967.8 2000.2 1968.5 2000.7 C
78.5995 +1969.4 2000.2 1968.2 1998.8 1967.1 1998.5 C
78.5996 +[0 0 0 0.18] vc
78.5997 +f
78.5998 +0.4 w
78.5999 +2 J
78.6000 +2 M
78.6001 +S
78.6002 +n
78.6003 +1936.4 1997.6 m
78.6004 +1936.7 1995.6 1935.8 1996.4 1936.1 1997.8 C
78.6005 +1936.9 1997.9 1936.5 1999.2 1937.6 1999 C
78.6006 +1937 1998.5 1936.8 1998 1936.4 1997.6 C
78.6007 +f
78.6008 +S
78.6009 +n
78.6010 +1975.5 1996.6 m
78.6011 +1975.2 1996.7 1975.1 1996.5 1975 1996.4 C
78.6012 +1975 1996.2 1975 1996.1 1975 1995.9 C
78.6013 +1973.9 1996.5 1972 1995.5 1971.2 1996.8 C
78.6014 +1971.2 1998.6 1977 1999.9 1975.5 1996.6 C
78.6015 +[0 0 0 0] vc
78.6016 +f
78.6017 +S
78.6018 +n
78.6019 +1949.3 2097.4 m
78.6020 +1950.3 2096.9 1951.2 2096.4 1952.2 2096 C
78.6021 +1951.2 2096.4 1950.3 2096.9 1949.3 2097.4 C
78.6022 +[0.4 0.4 0 0] vc
78.6023 +f
78.6024 +S
78.6025 +n
78.6026 +1960.8 2091.6 m
78.6027 +1961.7 2091.2 1962.6 2090.9 1963.5 2090.4 C
78.6028 +1962.6 2090.9 1961.7 2091.2 1960.8 2091.6 C
78.6029 +f
78.6030 +S
78.6031 +n
78.6032 +1964.4 2090 m
78.6033 +1965.7 2089.2 1967 2088.5 1968.3 2087.8 C
78.6034 +1967 2088.5 1965.7 2089.2 1964.4 2090 C
78.6035 +f
78.6036 +S
78.6037 +n
78.6038 +1976 2083.7 m
78.6039 +1976.3 2082.3 1975.2 2079.1 1976.9 2079.4 C
78.6040 +1978.8 2080.7 1980.3 2082.9 1982.2 2084.2 C
78.6041 +1980.6 2083.1 1978.2 2080.2 1976 2078.9 C
78.6042 +1975.6 2081.2 1977 2084.9 1973.8 2085.4 C
78.6043 +1972.2 2086.1 1970.7 2087 1969 2087.6 C
78.6044 +1971.4 2086.5 1974.1 2085.6 1976 2083.7 C
78.6045 +f
78.6046 +S
78.6047 +n
78.6048 +1983.9 2084.2 m
78.6049 +1984.8 2083.7 1985.8 2083.2 1986.8 2082.8 C
78.6050 +1985.8 2083.2 1984.8 2083.7 1983.9 2084.2 C
78.6051 +f
78.6052 +S
78.6053 +n
78.6054 +1995.4 2078.4 m
78.6055 +1996.3 2078 1997.1 2077.7 1998 2077.2 C
78.6056 +1997.1 2077.7 1996.3 2078 1995.4 2078.4 C
78.6057 +f
78.6058 +S
78.6059 +n
78.6060 +1999 2076.8 m
78.6061 +2000.3 2076 2001.6 2075.3 2002.8 2074.6 C
78.6062 +2001.6 2075.3 2000.3 2076 1999 2076.8 C
78.6063 +f
78.6064 +S
78.6065 +n
78.6066 +vmrs
78.6067 +1929.6 2065.7 m
78.6068 +1930.1 2065.6 1929.8 2068.6 1929.9 2070 C
78.6069 +1929.8 2068.6 1930.1 2067 1929.6 2065.7 C
78.6070 +[0.4 0.4 0 0] vc
78.6071 +f
78.6072 +0.4 w
78.6073 +2 J
78.6074 +2 M
78.6075 +S
78.6076 +n
78.6077 +1906.6 2049.4 m
78.6078 +1906.6 2046.7 1906.6 2043.9 1906.6 2041.2 C
78.6079 +1906.6 2043.9 1906.6 2046.7 1906.6 2049.4 C
78.6080 +f
78.6081 +S
78.6082 +n
78.6083 +2016 2047.5 m
78.6084 +2014.8 2048 2013.5 2048.3 2012.4 2049.4 C
78.6085 +2013.5 2048.3 2014.8 2048 2016 2047.5 C
78.6086 +f
78.6087 +S
78.6088 +n
78.6089 +2016.5 2047.2 m
78.6090 +2017.3 2046.9 2018.1 2046.6 2018.9 2046.3 C
78.6091 +2018.1 2046.6 2017.3 2046.9 2016.5 2047.2 C
78.6092 +f
78.6093 +S
78.6094 +n
78.6095 +1912.4 2028.5 m
78.6096 +1911.8 2032.4 1912.4 2037.2 1911.9 2041.2 C
78.6097 +1911.5 2037.2 1911.7 2032.9 1911.6 2028.8 C
78.6098 +1911.6 2033.5 1911.6 2038.9 1911.6 2042.9 C
78.6099 +1912.5 2042.2 1911.6 2043.9 1912.6 2043.6 C
78.6100 +1912.9 2039.3 1913.1 2033.3 1912.4 2028.5 C
78.6101 +[0.21 0.21 0 0] vc
78.6102 +f
78.6103 +S
78.6104 +n
78.6105 +1906.8 2040.8 m
78.6106 +1906.8 2039 1906.8 2037.2 1906.8 2035.5 C
78.6107 +1906.8 2037.2 1906.8 2039 1906.8 2040.8 C
78.6108 +[0.4 0.4 0 0] vc
78.6109 +f
78.6110 +S
78.6111 +n
78.6112 +1905.9 2035.2 m
78.6113 +1904.9 2036.4 1903.7 2037.2 1902.3 2037.4 C
78.6114 +1903.7 2037.2 1904.9 2036.4 1905.9 2035.2 C
78.6115 +f
78.6116 +S
78.6117 +n
78.6118 +1906.1 2031.2 m
78.6119 +1907 2031.1 1906.4 2028 1906.6 2030.7 C
78.6120 +1905.5 2032.1 1904 2032.8 1902.5 2033.6 C
78.6121 +1903.9 2033.2 1905 2032.1 1906.1 2031.2 C
78.6122 +f
78.6123 +S
78.6124 +n
78.6125 +1908.3 2018.7 m
78.6126 +1905.2 2018.6 1907.1 2023.2 1906.6 2025.4 C
78.6127 +1906.8 2023 1905.9 2019.5 1908.3 2018.7 C
78.6128 +f
78.6129 +S
78.6130 +n
78.6131 +1889.6 1998 m
78.6132 +1889 2001.9 1889.6 2006.7 1889.1 2010.8 C
78.6133 +1888.7 2006.7 1888.9 2002.4 1888.8 1998.3 C
78.6134 +1888.8 2003 1888.8 2008.4 1888.8 2012.4 C
78.6135 +1889.7 2011.7 1888.8 2013.4 1889.8 2013.2 C
78.6136 +1890.1 2008.8 1890.3 2002.8 1889.6 1998 C
78.6137 +[0.21 0.21 0 0] vc
78.6138 +f
78.6139 +S
78.6140 +n
78.6141 +vmrs
78.6142 +1999 2001.4 m
78.6143 +2001 2000.3 2003 1999.2 2005 1998 C
78.6144 +2003 1999.2 2001 2000.3 1999 2001.4 C
78.6145 +[0.4 0.4 0 0] vc
78.6146 +f
78.6147 +0.4 w
78.6148 +2 J
78.6149 +2 M
78.6150 +S
78.6151 +n
78.6152 +1916.2 1986 m
78.6153 +1915.7 1989.9 1916.3 1994.7 1915.7 1998.8 C
78.6154 +1915.3 1994.7 1915.5 1990.4 1915.5 1986.3 C
78.6155 +1915.5 1991 1915.5 1996.4 1915.5 2000.4 C
78.6156 +1916.3 1999.7 1915.5 2001.4 1916.4 2001.2 C
78.6157 +1916.7 1996.8 1917 1990.8 1916.2 1986 C
78.6158 +[0.21 0.21 0 0] vc
78.6159 +f
78.6160 +S
78.6161 +n
78.6162 +1886.9 1989.6 m
78.6163 +1887.8 1989.2 1888.7 1988.9 1889.6 1988.4 C
78.6164 +1888.7 1988.9 1887.8 1989.2 1886.9 1989.6 C
78.6165 +[0.4 0.4 0 0] vc
78.6166 +f
78.6167 +S
78.6168 +n
78.6169 +1892.4 1986.8 m
78.6170 +1895.1 1985.1 1897.9 1983.6 1900.6 1982 C
78.6171 +1897.9 1983.6 1895.1 1985.1 1892.4 1986.8 C
78.6172 +f
78.6173 +S
78.6174 +n
78.6175 +1907.3 1979.3 m
78.6176 +1908.5 1978.9 1909.7 1978.5 1910.9 1978.1 C
78.6177 +1909.7 1978.5 1908.5 1978.9 1907.3 1979.3 C
78.6178 +f
78.6179 +S
78.6180 +n
78.6181 +1938.5 1966.6 m
78.6182 +1942.6 1970.1 1945.9 1976.4 1951.7 1979.1 C
78.6183 +1946.2 1976.1 1943.1 1970.9 1938.5 1966.6 C
78.6184 +f
78.6185 +S
78.6186 +n
78.6187 +1955.1 1978.6 m
78.6188 +1955.9 1978.2 1956.7 1977.8 1957.5 1977.4 C
78.6189 +1956.7 1977.8 1955.9 1978.2 1955.1 1978.6 C
78.6190 +f
78.6191 +S
78.6192 +n
78.6193 +1913.6 1977.6 m
78.6194 +1914.5 1977.2 1915.3 1976.9 1916.2 1976.4 C
78.6195 +1915.3 1976.9 1914.5 1977.2 1913.6 1977.6 C
78.6196 +f
78.6197 +S
78.6198 +n
78.6199 +1919.1 1974.8 m
78.6200 +1921.8 1973.1 1924.5 1971.6 1927.2 1970 C
78.6201 +1924.5 1971.6 1921.8 1973.1 1919.1 1974.8 C
78.6202 +f
78.6203 +S
78.6204 +n
78.6205 +1963.5 1974.5 m
78.6206 +1964.5 1974 1965.6 1973.4 1966.6 1972.8 C
78.6207 +1965.6 1973.4 1964.5 1974 1963.5 1974.5 C
78.6208 +f
78.6209 +S
78.6210 +n
78.6211 +vmrs
78.6212 +1967.8 1972.4 m
78.6213 +1970 1971.2 1972.1 1970 1974.3 1968.8 C
78.6214 +1972.1 1970 1970 1971.2 1967.8 1972.4 C
78.6215 +[0.4 0.4 0 0] vc
78.6216 +f
78.6217 +0.4 w
78.6218 +2 J
78.6219 +2 M
78.6220 +S
78.6221 +n
78.6222 +1934 1967.3 m
78.6223 +1935.2 1966.9 1936.4 1966.5 1937.6 1966.1 C
78.6224 +1936.4 1966.5 1935.2 1966.9 1934 1967.3 C
78.6225 +f
78.6226 +S
78.6227 +n
78.6228 +1928.9 2061.2 m
78.6229 +1928.9 2059.2 1928.9 2057.3 1928.9 2055.4 C
78.6230 +1928.9 2057.3 1928.9 2059.2 1928.9 2061.2 C
78.6231 +[0.21 0.21 0 0] vc
78.6232 +f
78.6233 +S
78.6234 +n
78.6235 +1917.2 2047 m
78.6236 +1917.8 2046.5 1919.6 2046.8 1920 2047.2 C
78.6237 +1920 2046.5 1920.9 2046.8 1921 2046.3 C
78.6238 +1921.9 2047.3 1921.3 2044.1 1921.5 2044.1 C
78.6239 +1919.7 2044.8 1915.7 2043.5 1916.2 2046 C
78.6240 +1916.2 2048.3 1917 2045.9 1917.2 2047 C
78.6241 +[0 0 0 0] vc
78.6242 +f
78.6243 +S
78.6244 +n
78.6245 +1922 2044.1 m
78.6246 +1923.5 2043.2 1927 2045.4 1927.5 2042.9 C
78.6247 +1927.1 2042.6 1927.3 2040.9 1927.2 2041.5 C
78.6248 +1924.9 2042.3 1920.9 2040.6 1922 2044.1 C
78.6249 +f
78.6250 +S
78.6251 +n
78.6252 +1934.9 2043.9 m
78.6253 +1935.2 2043.4 1934.4 2042.7 1934 2042.2 C
78.6254 +1933.2 2041.8 1932.4 2042.8 1932.8 2043.2 C
78.6255 +1932.9 2044 1934.3 2043.3 1934.9 2043.9 C
78.6256 +f
78.6257 +S
78.6258 +n
78.6259 +1906.1 2030.7 m
78.6260 +1906.1 2028.8 1906.1 2027 1906.1 2025.2 C
78.6261 +1906.1 2027 1906.1 2028.8 1906.1 2030.7 C
78.6262 +[0.21 0.21 0 0] vc
78.6263 +f
78.6264 +S
78.6265 +n
78.6266 +1932.8 2018.7 m
78.6267 +1932.8 2016.8 1932.8 2014.8 1932.8 2012.9 C
78.6268 +1932.8 2014.8 1932.8 2016.8 1932.8 2018.7 C
78.6269 +f
78.6270 +S
78.6271 +n
78.6272 +1894.4 2016.5 m
78.6273 +1895 2016 1896.8 2016.3 1897.2 2016.8 C
78.6274 +1897.2 2016 1898.1 2016.3 1898.2 2015.8 C
78.6275 +1899.1 2016.8 1898.5 2013.6 1898.7 2013.6 C
78.6276 +1896.9 2014.4 1892.9 2013 1893.4 2015.6 C
78.6277 +1893.4 2017.8 1894.2 2015.4 1894.4 2016.5 C
78.6278 +[0 0 0 0] vc
78.6279 +f
78.6280 +S
78.6281 +n
78.6282 +1899.2 2013.6 m
78.6283 +1900.7 2012.7 1904.2 2014.9 1904.7 2012.4 C
78.6284 +1904.3 2012.1 1904.5 2010.5 1904.4 2011 C
78.6285 +1902.1 2011.8 1898.1 2010.1 1899.2 2013.6 C
78.6286 +f
78.6287 +S
78.6288 +n
78.6289 +vmrs
78.6290 +1912.1 2013.4 m
78.6291 +1912.4 2012.9 1911.6 2012.3 1911.2 2011.7 C
78.6292 +1910.4 2011.4 1909.6 2012.3 1910 2012.7 C
78.6293 +1910.1 2013.5 1911.5 2012.9 1912.1 2013.4 C
78.6294 +[0 0 0 0] vc
78.6295 +f
78.6296 +0.4 w
78.6297 +2 J
78.6298 +2 M
78.6299 +S
78.6300 +n
78.6301 +1921 2004.5 m
78.6302 +1921.6 2004 1923.4 2004.3 1923.9 2004.8 C
78.6303 +1923.8 2004 1924.8 2004.3 1924.8 2003.8 C
78.6304 +1925.7 2004.8 1925.1 2001.6 1925.3 2001.6 C
78.6305 +1923.6 2002.4 1919.6 2001 1920 2003.6 C
78.6306 +1920 2005.8 1920.8 2003.4 1921 2004.5 C
78.6307 +f
78.6308 +S
78.6309 +n
78.6310 +1925.8 2001.6 m
78.6311 +1927.3 2000.7 1930.8 2002.9 1931.3 2000.4 C
78.6312 +1930.9 2000.1 1931.1 1998.5 1931.1 1999 C
78.6313 +1928.7 1999.8 1924.8 1998.1 1925.8 2001.6 C
78.6314 +f
78.6315 +S
78.6316 +n
78.6317 +1938.8 2001.4 m
78.6318 +1939 2000.9 1938.2 2000.3 1937.8 1999.7 C
78.6319 +1937.1 1999.4 1936.2 2000.3 1936.6 2000.7 C
78.6320 +1936.7 2001.5 1938.1 2000.9 1938.8 2001.4 C
78.6321 +f
78.6322 +S
78.6323 +n
78.6324 +1908.6691 2008.1348 m
78.6325 +1897.82 2010.0477 L
78.6326 +1894.1735 1989.3671 L
78.6327 +1905.0226 1987.4542 L
78.6328 +1908.6691 2008.1348 L
78.6329 +n
78.6330 +q
78.6331 +_bfh
78.6332 +%%IncludeResource: font Symbol
78.6333 +_efh
78.6334 +{
78.6335 +f0 [19.696045 -3.4729 3.4729 19.696045 0 0] makesetfont
78.6336 +1895.041763 1994.291153 m
78.6337 +0 0 32 0 0 (l) ts
78.6338 +}
78.6339 +true
78.6340 +[0 0 0 1]sts
78.6341 +Q
78.6342 +1979.2185 1991.7809 m
78.6343 +1960.6353 1998.5452 L
78.6344 +1953.4532 1978.8124 L
78.6345 +1972.0363 1972.0481 L
78.6346 +1979.2185 1991.7809 L
78.6347 +n
78.6348 +q
78.6349 +_bfh
78.6350 +%%IncludeResource: font Symbol
78.6351 +_efh
78.6352 +{
78.6353 +f0 [18.793335 -6.84082 6.84021 18.793335 0 0] makesetfont
78.6354 +1955.163254 1983.510773 m
78.6355 +0 0 32 0 0 (\256) ts
78.6356 +}
78.6357 +true
78.6358 +[0 0 0 1]sts
78.6359 +Q
78.6360 +1952.1544 2066.5423 m
78.6361 +1938.0739 2069.025 L
78.6362 +1934.4274 2048.3444 L
78.6363 +1948.5079 2045.8617 L
78.6364 +1952.1544 2066.5423 L
78.6365 +n
78.6366 +q
78.6367 +_bfh
78.6368 +%%IncludeResource: font Symbol
78.6369 +_efh
78.6370 +{
78.6371 +f0 [19.696045 -3.4729 3.4729 19.696045 0 0] makesetfont
78.6372 +1935.29567 2053.268433 m
78.6373 +0 0 32 0 0 (") ts
78.6374 +}
78.6375 +true
78.6376 +[0 0 0 1]sts
78.6377 +Q
78.6378 +1931.7231 2043.621 m
78.6379 +1919.3084 2048.14 L
78.6380 +1910.6898 2024.4607 L
78.6381 +1923.1046 2019.9417 L
78.6382 +1931.7231 2043.621 L
78.6383 +n
78.6384 +q
78.6385 +_bfh
78.6386 +%%IncludeResource: font Symbol
78.6387 +_efh
78.6388 +{
78.6389 +f0 [22.552002 -8.208984 8.208252 22.552002 0 0] makesetfont
78.6390 +1912.741867 2030.098648 m
78.6391 +0 0 32 0 0 (=) ts
78.6392 +}
78.6393 +true
78.6394 +[0 0 0 1]sts
78.6395 +Q
78.6396 +1944 2024.5 m
78.6397 +1944 2014 L
78.6398 +0.8504 w
78.6399 +0 J
78.6400 +3.863693 M
78.6401 +[0 0 0 1] vc
78.6402 +false setoverprint
78.6403 +S
78.6404 +n
78.6405 +1944.25 2019.1673 m
78.6406 +1952.5 2015.9173 L
78.6407 +S
78.6408 +n
78.6409 +1931.0787 2124.423 m
78.6410 +1855.5505 2043.4285 L
78.6411 +1871.0419 2013.0337 L
78.6412 +1946.5701 2094.0282 L
78.6413 +1931.0787 2124.423 L
78.6414 +n
78.6415 +q
78.6416 +_bfh
78.6417 +%%IncludeResource: font ZapfHumanist601BT-Bold
78.6418 +_efh
78.6419 +{
78.6420 +f1 [22.155762 23.759277 -14.753906 28.947754 0 0] makesetfont
78.6421 +1867.35347 2020.27063 m
78.6422 +0 0 32 0 0 (Isabelle) ts
78.6423 +}
78.6424 +true
78.6425 +[0 0 0 1]sts
78.6426 +Q
78.6427 +1933.5503 1996.9547 m
78.6428 +1922.7012 1998.8677 L
78.6429 +1919.0547 1978.1871 L
78.6430 +1929.9038 1976.2741 L
78.6431 +1933.5503 1996.9547 L
78.6432 +n
78.6433 +q
78.6434 +_bfh
78.6435 +%%IncludeResource: font Symbol
78.6436 +_efh
78.6437 +{
78.6438 +f0 [19.696045 -3.4729 3.4729 19.696045 0 0] makesetfont
78.6439 +1919.922913 1983.111069 m
78.6440 +0 0 32 0 0 (b) ts
78.6441 +}
78.6442 +true
78.6443 +[0 0 0 1]sts
78.6444 +Q
78.6445 +2006.3221 2025.7184 m
78.6446 +1993.8573 2027.9162 L
78.6447 +1990.2108 2007.2356 L
78.6448 +2002.6756 2005.0378 L
78.6449 +2006.3221 2025.7184 L
78.6450 +n
78.6451 +q
78.6452 +_bfh
78.6453 +%%IncludeResource: font Symbol
78.6454 +_efh
78.6455 +{
78.6456 +f0 [19.696045 -3.4729 3.4729 19.696045 0 0] makesetfont
78.6457 +1991.07901 2012.159653 m
78.6458 +0 0 32 0 0 (a) ts
78.6459 +}
78.6460 +true
78.6461 +[0 0 0 1]sts
78.6462 +Q
78.6463 +vmrs
78.6464 +2030.0624 2094.056 m
78.6465 +1956.3187 2120.904 L
78.6466 +1956.321 2095.3175 L
78.6467 +2030.0647 2068.4695 L
78.6468 +2030.0624 2094.056 L
78.6469 +n
78.6470 +q
78.6471 +_bfh
78.6472 +%%IncludeResource: font ZapfHumanist601BT-Bold
78.6473 +_efh
78.6474 +{
78.6475 +f1 [22.898804 -8.336792 -0.002197 24.368408 0 0] makesetfont
78.6476 +1956.320496 2101.409561 m
78.6477 +0 0 32 0 0 (Isar) ts
78.6478 +}
78.6479 +true
78.6480 +[0 0 0 1]sts
78.6481 +Q
78.6482 +vmr
78.6483 +vmr
78.6484 +end
78.6485 +%%Trailer
78.6486 +%%DocumentNeededResources: font Symbol
78.6487 +%%+ font ZapfHumanist601BT-Bold
78.6488 +%%DocumentFonts: Symbol
78.6489 +%%+ ZapfHumanist601BT-Bold
78.6490 +%%DocumentNeededFonts: Symbol
78.6491 +%%+ ZapfHumanist601BT-Bold
79.1 Binary file doc-src/Functions/isabelle_isar.pdf has changed
80.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
80.2 +++ b/doc-src/Functions/mathpartir.sty Wed Mar 04 11:05:29 2009 +0100
80.3 @@ -0,0 +1,421 @@
80.4 +% Mathpartir --- Math Paragraph for Typesetting Inference Rules
80.5 +%
80.6 +% Copyright (C) 2001, 2002, 2003, 2004, 2005 Didier Rémy
80.7 +%
80.8 +% Author : Didier Remy
80.9 +% Version : 1.2.0
80.10 +% Bug Reports : to author
80.11 +% Web Site : http://pauillac.inria.fr/~remy/latex/
80.12 +%
80.13 +% Mathpartir is free software; you can redistribute it and/or modify
80.14 +% it under the terms of the GNU General Public License as published by
80.15 +% the Free Software Foundation; either version 2, or (at your option)
80.16 +% any later version.
80.17 +%
80.18 +% Mathpartir is distributed in the hope that it will be useful,
80.19 +% but WITHOUT ANY WARRANTY; without even the implied warranty of
80.20 +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
80.21 +% GNU General Public License for more details
80.22 +% (http://pauillac.inria.fr/~remy/license/GPL).
80.23 +%
80.24 +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
80.25 +% File mathpartir.sty (LaTeX macros)
80.26 +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
80.27 +
80.28 +\NeedsTeXFormat{LaTeX2e}
80.29 +\ProvidesPackage{mathpartir}
80.30 + [2005/12/20 version 1.2.0 Math Paragraph for Typesetting Inference Rules]
80.31 +
80.32 +%%
80.33 +
80.34 +%% Identification
80.35 +%% Preliminary declarations
80.36 +
80.37 +\RequirePackage {keyval}
80.38 +
80.39 +%% Options
80.40 +%% More declarations
80.41 +
80.42 +%% PART I: Typesetting maths in paragraphe mode
80.43 +
80.44 +\newdimen \mpr@tmpdim
80.45 +
80.46 +% To ensure hevea \hva compatibility, \hva should expands to nothing
80.47 +% in mathpar or in inferrule
80.48 +\let \mpr@hva \empty
80.49 +
80.50 +%% normal paragraph parametters, should rather be taken dynamically
80.51 +\def \mpr@savepar {%
80.52 + \edef \MathparNormalpar
80.53 + {\noexpand \lineskiplimit \the\lineskiplimit
80.54 + \noexpand \lineskip \the\lineskip}%
80.55 + }
80.56 +
80.57 +\def \mpr@rulelineskip {\lineskiplimit=0.3em\lineskip=0.2em plus 0.1em}
80.58 +\def \mpr@lesslineskip {\lineskiplimit=0.6em\lineskip=0.5em plus 0.2em}
80.59 +\def \mpr@lineskip {\lineskiplimit=1.2em\lineskip=1.2em plus 0.2em}
80.60 +\let \MathparLineskip \mpr@lineskip
80.61 +\def \mpr@paroptions {\MathparLineskip}
80.62 +\let \mpr@prebindings \relax
80.63 +
80.64 +\newskip \mpr@andskip \mpr@andskip 2em plus 0.5fil minus 0.5em
80.65 +
80.66 +\def \mpr@goodbreakand
80.67 + {\hskip -\mpr@andskip \penalty -1000\hskip \mpr@andskip}
80.68 +\def \mpr@and {\hskip \mpr@andskip}
80.69 +\def \mpr@andcr {\penalty 50\mpr@and}
80.70 +\def \mpr@cr {\penalty -10000\mpr@and}
80.71 +\def \mpr@eqno #1{\mpr@andcr #1\hskip 0em plus -1fil \penalty 10}
80.72 +
80.73 +\def \mpr@bindings {%
80.74 + \let \and \mpr@andcr
80.75 + \let \par \mpr@andcr
80.76 + \let \\\mpr@cr
80.77 + \let \eqno \mpr@eqno
80.78 + \let \hva \mpr@hva
80.79 + }
80.80 +\let \MathparBindings \mpr@bindings
80.81 +
80.82 +% \@ifundefined {ignorespacesafterend}
80.83 +% {\def \ignorespacesafterend {\aftergroup \ignorespaces}
80.84 +
80.85 +\newenvironment{mathpar}[1][]
80.86 + {$$\mpr@savepar \parskip 0em \hsize \linewidth \centering
80.87 + \vbox \bgroup \mpr@prebindings \mpr@paroptions #1\ifmmode $\else
80.88 + \noindent $\displaystyle\fi
80.89 + \MathparBindings}
80.90 + {\unskip \ifmmode $\fi\egroup $$\ignorespacesafterend}
80.91 +
80.92 +% \def \math@mathpar #1{\setbox0 \hbox {$\displaystyle #1$}\ifnum
80.93 +% \wd0 < \hsize $$\box0$$\else \bmathpar #1\emathpar \fi}
80.94 +
80.95 +%%% HOV BOXES
80.96 +
80.97 +\def \mathvbox@ #1{\hbox \bgroup \mpr@normallineskip
80.98 + \vbox \bgroup \tabskip 0em \let \\ \cr
80.99 + \halign \bgroup \hfil $##$\hfil\cr #1\crcr \egroup \egroup
80.100 + \egroup}
80.101 +
80.102 +\def \mathhvbox@ #1{\setbox0 \hbox {\let \\\qquad $#1$}\ifnum \wd0 < \hsize
80.103 + \box0\else \mathvbox {#1}\fi}
80.104 +
80.105 +
80.106 +%% Part II -- operations on lists
80.107 +
80.108 +\newtoks \mpr@lista
80.109 +\newtoks \mpr@listb
80.110 +
80.111 +\long \def\mpr@cons #1\mpr@to#2{\mpr@lista {\\{#1}}\mpr@listb \expandafter
80.112 +{#2}\edef #2{\the \mpr@lista \the \mpr@listb}}
80.113 +
80.114 +\long \def\mpr@snoc #1\mpr@to#2{\mpr@lista {\\{#1}}\mpr@listb \expandafter
80.115 +{#2}\edef #2{\the \mpr@listb\the\mpr@lista}}
80.116 +
80.117 +\long \def \mpr@concat#1=#2\mpr@to#3{\mpr@lista \expandafter {#2}\mpr@listb
80.118 +\expandafter {#3}\edef #1{\the \mpr@listb\the\mpr@lista}}
80.119 +
80.120 +\def \mpr@head #1\mpr@to #2{\expandafter \mpr@head@ #1\mpr@head@ #1#2}
80.121 +\long \def \mpr@head@ #1#2\mpr@head@ #3#4{\def #4{#1}\def#3{#2}}
80.122 +
80.123 +\def \mpr@flatten #1\mpr@to #2{\expandafter \mpr@flatten@ #1\mpr@flatten@ #1#2}
80.124 +\long \def \mpr@flatten@ \\#1\\#2\mpr@flatten@ #3#4{\def #4{#1}\def #3{\\#2}}
80.125 +
80.126 +\def \mpr@makelist #1\mpr@to #2{\def \mpr@all {#1}%
80.127 + \mpr@lista {\\}\mpr@listb \expandafter {\mpr@all}\edef \mpr@all {\the
80.128 + \mpr@lista \the \mpr@listb \the \mpr@lista}\let #2\empty
80.129 + \def \mpr@stripof ##1##2\mpr@stripend{\def \mpr@stripped{##2}}\loop
80.130 + \mpr@flatten \mpr@all \mpr@to \mpr@one
80.131 + \expandafter \mpr@snoc \mpr@one \mpr@to #2\expandafter \mpr@stripof
80.132 + \mpr@all \mpr@stripend
80.133 + \ifx \mpr@stripped \empty \let \mpr@isempty 0\else \let \mpr@isempty 1\fi
80.134 + \ifx 1\mpr@isempty
80.135 + \repeat
80.136 +}
80.137 +
80.138 +\def \mpr@rev #1\mpr@to #2{\let \mpr@tmp \empty
80.139 + \def \\##1{\mpr@cons ##1\mpr@to \mpr@tmp}#1\let #2\mpr@tmp}
80.140 +
80.141 +%% Part III -- Type inference rules
80.142 +
80.143 +\newif \if@premisse
80.144 +\newbox \mpr@hlist
80.145 +\newbox \mpr@vlist
80.146 +\newif \ifmpr@center \mpr@centertrue
80.147 +\def \mpr@htovlist {%
80.148 + \setbox \mpr@hlist
80.149 + \hbox {\strut
80.150 + \ifmpr@center \hskip -0.5\wd\mpr@hlist\fi
80.151 + \unhbox \mpr@hlist}%
80.152 + \setbox \mpr@vlist
80.153 + \vbox {\if@premisse \box \mpr@hlist \unvbox \mpr@vlist
80.154 + \else \unvbox \mpr@vlist \box \mpr@hlist
80.155 + \fi}%
80.156 +}
80.157 +% OLD version
80.158 +% \def \mpr@htovlist {%
80.159 +% \setbox \mpr@hlist
80.160 +% \hbox {\strut \hskip -0.5\wd\mpr@hlist \unhbox \mpr@hlist}%
80.161 +% \setbox \mpr@vlist
80.162 +% \vbox {\if@premisse \box \mpr@hlist \unvbox \mpr@vlist
80.163 +% \else \unvbox \mpr@vlist \box \mpr@hlist
80.164 +% \fi}%
80.165 +% }
80.166 +
80.167 +\def \mpr@item #1{$\displaystyle #1$}
80.168 +\def \mpr@sep{2em}
80.169 +\def \mpr@blank { }
80.170 +\def \mpr@hovbox #1#2{\hbox
80.171 + \bgroup
80.172 + \ifx #1T\@premissetrue
80.173 + \else \ifx #1B\@premissefalse
80.174 + \else
80.175 + \PackageError{mathpartir}
80.176 + {Premisse orientation should either be T or B}
80.177 + {Fatal error in Package}%
80.178 + \fi \fi
80.179 + \def \@test {#2}\ifx \@test \mpr@blank\else
80.180 + \setbox \mpr@hlist \hbox {}%
80.181 + \setbox \mpr@vlist \vbox {}%
80.182 + \if@premisse \let \snoc \mpr@cons \else \let \snoc \mpr@snoc \fi
80.183 + \let \@hvlist \empty \let \@rev \empty
80.184 + \mpr@tmpdim 0em
80.185 + \expandafter \mpr@makelist #2\mpr@to \mpr@flat
80.186 + \if@premisse \mpr@rev \mpr@flat \mpr@to \@rev \else \let \@rev \mpr@flat \fi
80.187 + \def \\##1{%
80.188 + \def \@test {##1}\ifx \@test \empty
80.189 + \mpr@htovlist
80.190 + \mpr@tmpdim 0em %%% last bug fix not extensively checked
80.191 + \else
80.192 + \setbox0 \hbox{\mpr@item {##1}}\relax
80.193 + \advance \mpr@tmpdim by \wd0
80.194 + %\mpr@tmpdim 1.02\mpr@tmpdim
80.195 + \ifnum \mpr@tmpdim < \hsize
80.196 + \ifnum \wd\mpr@hlist > 0
80.197 + \if@premisse
80.198 + \setbox \mpr@hlist
80.199 + \hbox {\unhbox0 \hskip \mpr@sep \unhbox \mpr@hlist}%
80.200 + \else
80.201 + \setbox \mpr@hlist
80.202 + \hbox {\unhbox \mpr@hlist \hskip \mpr@sep \unhbox0}%
80.203 + \fi
80.204 + \else
80.205 + \setbox \mpr@hlist \hbox {\unhbox0}%
80.206 + \fi
80.207 + \else
80.208 + \ifnum \wd \mpr@hlist > 0
80.209 + \mpr@htovlist
80.210 + \mpr@tmpdim \wd0
80.211 + \fi
80.212 + \setbox \mpr@hlist \hbox {\unhbox0}%
80.213 + \fi
80.214 + \advance \mpr@tmpdim by \mpr@sep
80.215 + \fi
80.216 + }%
80.217 + \@rev
80.218 + \mpr@htovlist
80.219 + \ifmpr@center \hskip \wd\mpr@vlist\fi \box \mpr@vlist
80.220 + \fi
80.221 + \egroup
80.222 +}
80.223 +
80.224 +%%% INFERENCE RULES
80.225 +
80.226 +\@ifundefined{@@over}{%
80.227 + \let\@@over\over % fallback if amsmath is not loaded
80.228 + \let\@@overwithdelims\overwithdelims
80.229 + \let\@@atop\atop \let\@@atopwithdelims\atopwithdelims
80.230 + \let\@@above\above \let\@@abovewithdelims\abovewithdelims
80.231 + }{}
80.232 +
80.233 +%% The default
80.234 +
80.235 +\def \mpr@@fraction #1#2{\hbox {\advance \hsize by -0.5em
80.236 + $\displaystyle {#1\mpr@over #2}$}}
80.237 +\let \mpr@fraction \mpr@@fraction
80.238 +
80.239 +%% A generic solution to arrow
80.240 +
80.241 +\def \mpr@make@fraction #1#2#3#4#5{\hbox {%
80.242 + \def \mpr@tail{#1}%
80.243 + \def \mpr@body{#2}%
80.244 + \def \mpr@head{#3}%
80.245 + \setbox1=\hbox{$#4$}\setbox2=\hbox{$#5$}%
80.246 + \setbox3=\hbox{$\mkern -3mu\mpr@body\mkern -3mu$}%
80.247 + \setbox3=\hbox{$\mkern -3mu \mpr@body\mkern -3mu$}%
80.248 + \dimen0=\dp1\advance\dimen0 by \ht3\relax\dp1\dimen0\relax
80.249 + \dimen0=\ht2\advance\dimen0 by \dp3\relax\ht2\dimen0\relax
80.250 + \setbox0=\hbox {$\box1 \@@atop \box2$}%
80.251 + \dimen0=\wd0\box0
80.252 + \box0 \hskip -\dimen0\relax
80.253 + \hbox to \dimen0 {$%
80.254 + \mathrel{\mpr@tail}\joinrel
80.255 + \xleaders\hbox{\copy3}\hfil\joinrel\mathrel{\mpr@head}%
80.256 + $}}}
80.257 +
80.258 +%% Old stuff should be removed in next version
80.259 +\def \mpr@@reduce #1#2{\hbox
80.260 + {$\lower 0.01pt \mpr@@fraction {#1}{#2}\mkern -15mu\rightarrow$}}
80.261 +\def \mpr@@rewrite #1#2#3{\hbox
80.262 + {$\lower 0.01pt \mpr@@fraction {#2}{#3}\mkern -8mu#1$}}
80.263 +\def \mpr@infercenter #1{\vcenter {\mpr@hovbox{T}{#1}}}
80.264 +
80.265 +\def \mpr@empty {}
80.266 +\def \mpr@inferrule
80.267 + {\bgroup
80.268 + \ifnum \linewidth<\hsize \hsize \linewidth\fi
80.269 + \mpr@rulelineskip
80.270 + \let \and \qquad
80.271 + \let \hva \mpr@hva
80.272 + \let \@rulename \mpr@empty
80.273 + \let \@rule@options \mpr@empty
80.274 + \let \mpr@over \@@over
80.275 + \mpr@inferrule@}
80.276 +\newcommand {\mpr@inferrule@}[3][]
80.277 + {\everymath={\displaystyle}%
80.278 + \def \@test {#2}\ifx \empty \@test
80.279 + \setbox0 \hbox {$\vcenter {\mpr@hovbox{B}{#3}}$}%
80.280 + \else
80.281 + \def \@test {#3}\ifx \empty \@test
80.282 + \setbox0 \hbox {$\vcenter {\mpr@hovbox{T}{#2}}$}%
80.283 + \else
80.284 + \setbox0 \mpr@fraction {\mpr@hovbox{T}{#2}}{\mpr@hovbox{B}{#3}}%
80.285 + \fi \fi
80.286 + \def \@test {#1}\ifx \@test\empty \box0
80.287 + \else \vbox
80.288 +%%% Suggestion de Francois pour les etiquettes longues
80.289 +%%% {\hbox to \wd0 {\RefTirName {#1}\hfil}\box0}\fi
80.290 + {\hbox {\RefTirName {#1}}\box0}\fi
80.291 + \egroup}
80.292 +
80.293 +\def \mpr@vdotfil #1{\vbox to #1{\leaders \hbox{$\cdot$} \vfil}}
80.294 +
80.295 +% They are two forms
80.296 +% \inferrule [label]{[premisses}{conclusions}
80.297 +% or
80.298 +% \inferrule* [options]{[premisses}{conclusions}
80.299 +%
80.300 +% Premisses and conclusions are lists of elements separated by \\
80.301 +% Each \\ produces a break, attempting horizontal breaks if possible,
80.302 +% and vertical breaks if needed.
80.303 +%
80.304 +% An empty element obtained by \\\\ produces a vertical break in all cases.
80.305 +%
80.306 +% The former rule is aligned on the fraction bar.
80.307 +% The optional label appears on top of the rule
80.308 +% The second form to be used in a derivation tree is aligned on the last
80.309 +% line of its conclusion
80.310 +%
80.311 +% The second form can be parameterized, using the key=val interface. The
80.312 +% folloiwng keys are recognized:
80.313 +%
80.314 +% width set the width of the rule to val
80.315 +% narrower set the width of the rule to val\hsize
80.316 +% before execute val at the beginning/left
80.317 +% lab put a label [Val] on top of the rule
80.318 +% lskip add negative skip on the right
80.319 +% left put a left label [Val]
80.320 +% Left put a left label [Val], ignoring its width
80.321 +% right put a right label [Val]
80.322 +% Right put a right label [Val], ignoring its width
80.323 +% leftskip skip negative space on the left-hand side
80.324 +% rightskip skip negative space on the right-hand side
80.325 +% vdots lift the rule by val and fill vertical space with dots
80.326 +% after execute val at the end/right
80.327 +%
80.328 +% Note that most options must come in this order to avoid strange
80.329 +% typesetting (in particular leftskip must preceed left and Left and
80.330 +% rightskip must follow Right or right; vdots must come last
80.331 +% or be only followed by rightskip.
80.332 +%
80.333 +
80.334 +%% Keys that make sence in all kinds of rules
80.335 +\def \mprset #1{\setkeys{mprset}{#1}}
80.336 +\define@key {mprset}{flushleft}[]{\mpr@centerfalse}
80.337 +\define@key {mprset}{center}[]{\mpr@centertrue}
80.338 +\define@key {mprset}{rewrite}[]{\let \mpr@fraction \mpr@@rewrite}
80.339 +\define@key {mprset}{myfraction}[]{\let \mpr@fraction #1}
80.340 +\define@key {mprset}{fraction}[]{\def \mpr@fraction {\mpr@make@fraction #1}}
80.341 +
80.342 +\newbox \mpr@right
80.343 +\define@key {mpr}{flushleft}[]{\mpr@centerfalse}
80.344 +\define@key {mpr}{center}[]{\mpr@centertrue}
80.345 +\define@key {mpr}{rewrite}[]{\let \mpr@fraction \mpr@@rewrite}
80.346 +\define@key {mpr}{myfraction}[]{\let \mpr@fraction #1}
80.347 +\define@key {mpr}{fraction}[]{\def \mpr@fraction {\mpr@make@fraction #1}}
80.348 +\define@key {mpr}{left}{\setbox0 \hbox {$\TirName {#1}\;$}\relax
80.349 + \advance \hsize by -\wd0\box0}
80.350 +\define@key {mpr}{width}{\hsize #1}
80.351 +\define@key {mpr}{sep}{\def\mpr@sep{#1}}
80.352 +\define@key {mpr}{before}{#1}
80.353 +\define@key {mpr}{lab}{\let \RefTirName \TirName \def \mpr@rulename {#1}}
80.354 +\define@key {mpr}{Lab}{\let \RefTirName \TirName \def \mpr@rulename {#1}}
80.355 +\define@key {mpr}{narrower}{\hsize #1\hsize}
80.356 +\define@key {mpr}{leftskip}{\hskip -#1}
80.357 +\define@key {mpr}{reduce}[]{\let \mpr@fraction \mpr@@reduce}
80.358 +\define@key {mpr}{rightskip}
80.359 + {\setbox \mpr@right \hbox {\unhbox \mpr@right \hskip -#1}}
80.360 +\define@key {mpr}{LEFT}{\setbox0 \hbox {$#1$}\relax
80.361 + \advance \hsize by -\wd0\box0}
80.362 +\define@key {mpr}{left}{\setbox0 \hbox {$\TirName {#1}\;$}\relax
80.363 + \advance \hsize by -\wd0\box0}
80.364 +\define@key {mpr}{Left}{\llap{$\TirName {#1}\;$}}
80.365 +\define@key {mpr}{right}
80.366 + {\setbox0 \hbox {$\;\TirName {#1}$}\relax \advance \hsize by -\wd0
80.367 + \setbox \mpr@right \hbox {\unhbox \mpr@right \unhbox0}}
80.368 +\define@key {mpr}{RIGHT}
80.369 + {\setbox0 \hbox {$#1$}\relax \advance \hsize by -\wd0
80.370 + \setbox \mpr@right \hbox {\unhbox \mpr@right \unhbox0}}
80.371 +\define@key {mpr}{Right}
80.372 + {\setbox \mpr@right \hbox {\unhbox \mpr@right \rlap {$\;\TirName {#1}$}}}
80.373 +\define@key {mpr}{vdots}{\def \mpr@vdots {\@@atop \mpr@vdotfil{#1}}}
80.374 +\define@key {mpr}{after}{\edef \mpr@after {\mpr@after #1}}
80.375 +
80.376 +\newdimen \rule@dimen
80.377 +\newcommand \mpr@inferstar@ [3][]{\setbox0
80.378 + \hbox {\let \mpr@rulename \mpr@empty \let \mpr@vdots \relax
80.379 + \setbox \mpr@right \hbox{}%
80.380 + $\setkeys{mpr}{#1}%
80.381 + \ifx \mpr@rulename \mpr@empty \mpr@inferrule {#2}{#3}\else
80.382 + \mpr@inferrule [{\mpr@rulename}]{#2}{#3}\fi
80.383 + \box \mpr@right \mpr@vdots$}
80.384 + \setbox1 \hbox {\strut}
80.385 + \rule@dimen \dp0 \advance \rule@dimen by -\dp1
80.386 + \raise \rule@dimen \box0}
80.387 +
80.388 +\def \mpr@infer {\@ifnextchar *{\mpr@inferstar}{\mpr@inferrule}}
80.389 +\newcommand \mpr@err@skipargs[3][]{}
80.390 +\def \mpr@inferstar*{\ifmmode
80.391 + \let \@do \mpr@inferstar@
80.392 + \else
80.393 + \let \@do \mpr@err@skipargs
80.394 + \PackageError {mathpartir}
80.395 + {\string\inferrule* can only be used in math mode}{}%
80.396 + \fi \@do}
80.397 +
80.398 +
80.399 +%%% Exports
80.400 +
80.401 +% Envirnonment mathpar
80.402 +
80.403 +\let \inferrule \mpr@infer
80.404 +
80.405 +% make a short name \infer is not already defined
80.406 +\@ifundefined {infer}{\let \infer \mpr@infer}{}
80.407 +
80.408 +\def \TirNameStyle #1{\small \textsc{#1}}
80.409 +\def \tir@name #1{\hbox {\small \TirNameStyle{#1}}}
80.410 +\let \TirName \tir@name
80.411 +\let \DefTirName \TirName
80.412 +\let \RefTirName \TirName
80.413 +
80.414 +%%% Other Exports
80.415 +
80.416 +% \let \listcons \mpr@cons
80.417 +% \let \listsnoc \mpr@snoc
80.418 +% \let \listhead \mpr@head
80.419 +% \let \listmake \mpr@makelist
80.420 +
80.421 +
80.422 +
80.423 +
80.424 +\endinput
81.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
81.2 +++ b/doc-src/Functions/style.sty Wed Mar 04 11:05:29 2009 +0100
81.3 @@ -0,0 +1,46 @@
81.4 +%% toc
81.5 +\newcommand{\tocentry}[1]{\cleardoublepage\phantomsection\addcontentsline{toc}{chapter}{#1}
81.6 +\@mkboth{\MakeUppercase{#1}}{\MakeUppercase{#1}}}
81.7 +
81.8 +%% references
81.9 +\newcommand{\secref}[1]{\S\ref{#1}}
81.10 +\newcommand{\chref}[1]{chapter~\ref{#1}}
81.11 +\newcommand{\figref}[1]{figure~\ref{#1}}
81.12 +
81.13 +%% math
81.14 +\newcommand{\text}[1]{\mbox{#1}}
81.15 +\newcommand{\isasymvartheta}{\isamath{\theta}}
81.16 +\newcommand{\isactrlvec}[1]{\emph{$\overline{#1}$}}
81.17 +
81.18 +\setcounter{secnumdepth}{2} \setcounter{tocdepth}{2}
81.19 +
81.20 +\pagestyle{headings}
81.21 +\sloppy
81.22 +\binperiod
81.23 +\underscoreon
81.24 +
81.25 +\renewcommand{\isadigit}[1]{\isamath{#1}}
81.26 +
81.27 +\newenvironment{mldecls}{\par\noindent\begingroup\footnotesize\def\isanewline{\\}\begin{tabular}{l}}{\end{tabular}\smallskip\endgroup}
81.28 +
81.29 +\isafoldtag{FIXME}
81.30 +\isakeeptag{mlref}
81.31 +\renewcommand{\isatagmlref}{\subsection*{\makebox[0pt][r]{\fbox{\ML}~~}Reference}\begingroup\def\isastyletext{\rm}\small}
81.32 +\renewcommand{\endisatagmlref}{\endgroup}
81.33 +
81.34 +\newcommand{\isasymGUESS}{\isakeyword{guess}}
81.35 +\newcommand{\isasymOBTAIN}{\isakeyword{obtain}}
81.36 +\newcommand{\isasymTHEORY}{\isakeyword{theory}}
81.37 +\newcommand{\isasymUSES}{\isakeyword{uses}}
81.38 +\newcommand{\isasymEND}{\isakeyword{end}}
81.39 +\newcommand{\isasymCONSTS}{\isakeyword{consts}}
81.40 +\newcommand{\isasymDEFS}{\isakeyword{defs}}
81.41 +\newcommand{\isasymTHEOREM}{\isakeyword{theorem}}
81.42 +\newcommand{\isasymDEFINITION}{\isakeyword{definition}}
81.43 +
81.44 +\isabellestyle{it}
81.45 +
81.46 +%%% Local Variables:
81.47 +%%% mode: latex
81.48 +%%% TeX-master: "implementation"
81.49 +%%% End:
82.1 --- a/doc-src/Intro/intro.tex Wed Mar 04 11:05:02 2009 +0100
82.2 +++ b/doc-src/Intro/intro.tex Wed Mar 04 11:05:29 2009 +0100
82.3 @@ -7,7 +7,7 @@
82.4 %prth *(\(.*\)); \1;
82.5 %{\\out \(.*\)} {\\out val it = "\1" : thm}
82.6
82.7 -\title{\includegraphics[scale=0.5]{isabelle} \\[4ex] Introduction to Isabelle}
82.8 +\title{\includegraphics[scale=0.5]{isabelle} \\[4ex] Old Introduction to Isabelle}
82.9 \author{{\em Lawrence C. Paulson}\\
82.10 Computer Laboratory \\ University of Cambridge \\
82.11 \texttt{lcp@cl.cam.ac.uk}\\[3ex]
83.1 --- a/doc-src/IsarAdvanced/Classes/IsaMakefile Wed Mar 04 11:05:02 2009 +0100
83.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
83.3 @@ -1,33 +0,0 @@
83.4 -
83.5 -## targets
83.6 -
83.7 -default: Thy
83.8 -images:
83.9 -test: Thy
83.10 -
83.11 -all: images test
83.12 -
83.13 -
83.14 -## global settings
83.15 -
83.16 -SRC = $(ISABELLE_HOME)/src
83.17 -OUT = $(ISABELLE_OUTPUT)
83.18 -LOG = $(OUT)/log
83.19 -
83.20 -USEDIR = $(ISABELLE_TOOL) usedir -v true -i false -d false -C false -D document
83.21 -
83.22 -
83.23 -## Thy
83.24 -
83.25 -THY = $(LOG)/HOL-Thy.gz
83.26 -
83.27 -Thy: $(THY)
83.28 -
83.29 -$(THY): Thy/ROOT.ML Thy/Setup.thy Thy/Classes.thy
83.30 - @$(USEDIR) HOL Thy
83.31 -
83.32 -
83.33 -## clean
83.34 -
83.35 -clean:
83.36 - @rm -f $(THY)
84.1 --- a/doc-src/IsarAdvanced/Classes/Makefile Wed Mar 04 11:05:02 2009 +0100
84.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
84.3 @@ -1,38 +0,0 @@
84.4 -#
84.5 -# $Id$
84.6 -#
84.7 -
84.8 -## targets
84.9 -
84.10 -default: dvi
84.11 -
84.12 -
84.13 -## dependencies
84.14 -
84.15 -include ../Makefile.in
84.16 -
84.17 -NAME = classes
84.18 -
84.19 -FILES = $(NAME).tex classes.tex Thy/document/Classes.tex \
84.20 - style.sty ../../iman.sty ../../extra.sty ../../isar.sty \
84.21 - ../../isabelle.sty ../../isabellesym.sty ../../pdfsetup.sty \
84.22 - ../../manual.bib ../../proof.sty
84.23 -
84.24 -dvi: $(NAME).dvi
84.25 -
84.26 -$(NAME).dvi: $(FILES) isabelle_isar.eps
84.27 - $(LATEX) $(NAME)
84.28 - $(BIBTEX) $(NAME)
84.29 - $(LATEX) $(NAME)
84.30 - $(LATEX) $(NAME)
84.31 -
84.32 -pdf: $(NAME).pdf
84.33 -
84.34 -$(NAME).pdf: $(FILES) isabelle_isar.pdf
84.35 - $(PDFLATEX) $(NAME)
84.36 - $(BIBTEX) $(NAME)
84.37 - $(PDFLATEX) $(NAME)
84.38 - $(PDFLATEX) $(NAME)
84.39 - $(FIXBOOKMARKS) $(NAME).out
84.40 - $(PDFLATEX) $(NAME)
84.41 - $(PDFLATEX) $(NAME)
85.1 --- a/doc-src/IsarAdvanced/Classes/Thy/Classes.thy Wed Mar 04 11:05:02 2009 +0100
85.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
85.3 @@ -1,635 +0,0 @@
85.4 -theory Classes
85.5 -imports Main Setup
85.6 -begin
85.7 -
85.8 -chapter {* Haskell-style classes with Isabelle/Isar *}
85.9 -
85.10 -section {* Introduction *}
85.11 -
85.12 -text {*
85.13 - Type classes were introduces by Wadler and Blott \cite{wadler89how}
85.14 - into the Haskell language, to allow for a reasonable implementation
85.15 - of overloading\footnote{throughout this tutorial, we are referring
85.16 - to classical Haskell 1.0 type classes, not considering
85.17 - later additions in expressiveness}.
85.18 - As a canonical example, a polymorphic equality function
85.19 - @{text "eq \<Colon> \<alpha> \<Rightarrow> \<alpha> \<Rightarrow> bool"} which is overloaded on different
85.20 - types for @{text "\<alpha>"}, which is achieved by splitting introduction
85.21 - of the @{text eq} function from its overloaded definitions by means
85.22 - of @{text class} and @{text instance} declarations:
85.23 -
85.24 - \begin{quote}
85.25 -
85.26 - \noindent@{text "class eq where"}\footnote{syntax here is a kind of isabellized Haskell} \\
85.27 - \hspace*{2ex}@{text "eq \<Colon> \<alpha> \<Rightarrow> \<alpha> \<Rightarrow> bool"}
85.28 -
85.29 - \medskip\noindent@{text "instance nat \<Colon> eq where"} \\
85.30 - \hspace*{2ex}@{text "eq 0 0 = True"} \\
85.31 - \hspace*{2ex}@{text "eq 0 _ = False"} \\
85.32 - \hspace*{2ex}@{text "eq _ 0 = False"} \\
85.33 - \hspace*{2ex}@{text "eq (Suc n) (Suc m) = eq n m"}
85.34 -
85.35 - \medskip\noindent@{text "instance (\<alpha>\<Colon>eq, \<beta>\<Colon>eq) pair \<Colon> eq where"} \\
85.36 - \hspace*{2ex}@{text "eq (x1, y1) (x2, y2) = eq x1 x2 \<and> eq y1 y2"}
85.37 -
85.38 - \medskip\noindent@{text "class ord extends eq where"} \\
85.39 - \hspace*{2ex}@{text "less_eq \<Colon> \<alpha> \<Rightarrow> \<alpha> \<Rightarrow> bool"} \\
85.40 - \hspace*{2ex}@{text "less \<Colon> \<alpha> \<Rightarrow> \<alpha> \<Rightarrow> bool"}
85.41 -
85.42 - \end{quote}
85.43 -
85.44 - \noindent Type variables are annotated with (finitely many) classes;
85.45 - these annotations are assertions that a particular polymorphic type
85.46 - provides definitions for overloaded functions.
85.47 -
85.48 - Indeed, type classes not only allow for simple overloading
85.49 - but form a generic calculus, an instance of order-sorted
85.50 - algebra \cite{Nipkow-Prehofer:1993,nipkow-sorts93,Wenzel:1997:TPHOL}.
85.51 -
85.52 - From a software engeneering point of view, type classes
85.53 - roughly correspond to interfaces in object-oriented languages like Java;
85.54 - so, it is naturally desirable that type classes do not only
85.55 - provide functions (class parameters) but also state specifications
85.56 - implementations must obey. For example, the @{text "class eq"}
85.57 - above could be given the following specification, demanding that
85.58 - @{text "class eq"} is an equivalence relation obeying reflexivity,
85.59 - symmetry and transitivity:
85.60 -
85.61 - \begin{quote}
85.62 -
85.63 - \noindent@{text "class eq where"} \\
85.64 - \hspace*{2ex}@{text "eq \<Colon> \<alpha> \<Rightarrow> \<alpha> \<Rightarrow> bool"} \\
85.65 - @{text "satisfying"} \\
85.66 - \hspace*{2ex}@{text "refl: eq x x"} \\
85.67 - \hspace*{2ex}@{text "sym: eq x y \<longleftrightarrow> eq x y"} \\
85.68 - \hspace*{2ex}@{text "trans: eq x y \<and> eq y z \<longrightarrow> eq x z"}
85.69 -
85.70 - \end{quote}
85.71 -
85.72 - \noindent From a theoretic point of view, type classes are lightweight
85.73 - modules; Haskell type classes may be emulated by
85.74 - SML functors \cite{classes_modules}.
85.75 - Isabelle/Isar offers a discipline of type classes which brings
85.76 - all those aspects together:
85.77 -
85.78 - \begin{enumerate}
85.79 - \item specifying abstract parameters together with
85.80 - corresponding specifications,
85.81 - \item instantiating those abstract parameters by a particular
85.82 - type
85.83 - \item in connection with a ``less ad-hoc'' approach to overloading,
85.84 - \item with a direct link to the Isabelle module system
85.85 - (aka locales \cite{kammueller-locales}).
85.86 - \end{enumerate}
85.87 -
85.88 - \noindent Isar type classes also directly support code generation
85.89 - in a Haskell like fashion.
85.90 -
85.91 - This tutorial demonstrates common elements of structured specifications
85.92 - and abstract reasoning with type classes by the algebraic hierarchy of
85.93 - semigroups, monoids and groups. Our background theory is that of
85.94 - Isabelle/HOL \cite{isa-tutorial}, for which some
85.95 - familiarity is assumed.
85.96 -
85.97 - Here we merely present the look-and-feel for end users.
85.98 - Internally, those are mapped to more primitive Isabelle concepts.
85.99 - See \cite{Haftmann-Wenzel:2006:classes} for more detail.
85.100 -*}
85.101 -
85.102 -section {* A simple algebra example \label{sec:example} *}
85.103 -
85.104 -subsection {* Class definition *}
85.105 -
85.106 -text {*
85.107 - Depending on an arbitrary type @{text "\<alpha>"}, class @{text
85.108 - "semigroup"} introduces a binary operator @{text "(\<otimes>)"} that is
85.109 - assumed to be associative:
85.110 -*}
85.111 -
85.112 -class %quote semigroup =
85.113 - fixes mult :: "\<alpha> \<Rightarrow> \<alpha> \<Rightarrow> \<alpha>" (infixl "\<otimes>" 70)
85.114 - assumes assoc: "(x \<otimes> y) \<otimes> z = x \<otimes> (y \<otimes> z)"
85.115 -
85.116 -text {*
85.117 - \noindent This @{command class} specification consists of two
85.118 - parts: the \qn{operational} part names the class parameter
85.119 - (@{element "fixes"}), the \qn{logical} part specifies properties on them
85.120 - (@{element "assumes"}). The local @{element "fixes"} and
85.121 - @{element "assumes"} are lifted to the theory toplevel,
85.122 - yielding the global
85.123 - parameter @{term [source] "mult \<Colon> \<alpha>\<Colon>semigroup \<Rightarrow> \<alpha> \<Rightarrow> \<alpha>"} and the
85.124 - global theorem @{fact "semigroup.assoc:"}~@{prop [source] "\<And>x y
85.125 - z \<Colon> \<alpha>\<Colon>semigroup. (x \<otimes> y) \<otimes> z = x \<otimes> (y \<otimes> z)"}.
85.126 -*}
85.127 -
85.128 -
85.129 -subsection {* Class instantiation \label{sec:class_inst} *}
85.130 -
85.131 -text {*
85.132 - The concrete type @{typ int} is made a @{class semigroup}
85.133 - instance by providing a suitable definition for the class parameter
85.134 - @{text "(\<otimes>)"} and a proof for the specification of @{fact assoc}.
85.135 - This is accomplished by the @{command instantiation} target:
85.136 -*}
85.137 -
85.138 -instantiation %quote int :: semigroup
85.139 -begin
85.140 -
85.141 -definition %quote
85.142 - mult_int_def: "i \<otimes> j = i + (j\<Colon>int)"
85.143 -
85.144 -instance %quote proof
85.145 - fix i j k :: int have "(i + j) + k = i + (j + k)" by simp
85.146 - then show "(i \<otimes> j) \<otimes> k = i \<otimes> (j \<otimes> k)"
85.147 - unfolding mult_int_def .
85.148 -qed
85.149 -
85.150 -end %quote
85.151 -
85.152 -text {*
85.153 - \noindent @{command instantiation} allows to define class parameters
85.154 - at a particular instance using common specification tools (here,
85.155 - @{command definition}). The concluding @{command instance}
85.156 - opens a proof that the given parameters actually conform
85.157 - to the class specification. Note that the first proof step
85.158 - is the @{method default} method,
85.159 - which for such instance proofs maps to the @{method intro_classes} method.
85.160 - This boils down an instance judgement to the relevant primitive
85.161 - proof goals and should conveniently always be the first method applied
85.162 - in an instantiation proof.
85.163 -
85.164 - From now on, the type-checker will consider @{typ int}
85.165 - as a @{class semigroup} automatically, i.e.\ any general results
85.166 - are immediately available on concrete instances.
85.167 -
85.168 - \medskip Another instance of @{class semigroup} are the natural numbers:
85.169 -*}
85.170 -
85.171 -instantiation %quote nat :: semigroup
85.172 -begin
85.173 -
85.174 -primrec %quote mult_nat where
85.175 - "(0\<Colon>nat) \<otimes> n = n"
85.176 - | "Suc m \<otimes> n = Suc (m \<otimes> n)"
85.177 -
85.178 -instance %quote proof
85.179 - fix m n q :: nat
85.180 - show "m \<otimes> n \<otimes> q = m \<otimes> (n \<otimes> q)"
85.181 - by (induct m) auto
85.182 -qed
85.183 -
85.184 -end %quote
85.185 -
85.186 -text {*
85.187 - \noindent Note the occurence of the name @{text mult_nat}
85.188 - in the primrec declaration; by default, the local name of
85.189 - a class operation @{text f} to instantiate on type constructor
85.190 - @{text \<kappa>} are mangled as @{text f_\<kappa>}. In case of uncertainty,
85.191 - these names may be inspected using the @{command "print_context"} command
85.192 - or the corresponding ProofGeneral button.
85.193 -*}
85.194 -
85.195 -subsection {* Lifting and parametric types *}
85.196 -
85.197 -text {*
85.198 - Overloaded definitions giving on class instantiation
85.199 - may include recursion over the syntactic structure of types.
85.200 - As a canonical example, we model product semigroups
85.201 - using our simple algebra:
85.202 -*}
85.203 -
85.204 -instantiation %quote * :: (semigroup, semigroup) semigroup
85.205 -begin
85.206 -
85.207 -definition %quote
85.208 - mult_prod_def: "p\<^isub>1 \<otimes> p\<^isub>2 = (fst p\<^isub>1 \<otimes> fst p\<^isub>2, snd p\<^isub>1 \<otimes> snd p\<^isub>2)"
85.209 -
85.210 -instance %quote proof
85.211 - fix p\<^isub>1 p\<^isub>2 p\<^isub>3 :: "\<alpha>\<Colon>semigroup \<times> \<beta>\<Colon>semigroup"
85.212 - show "p\<^isub>1 \<otimes> p\<^isub>2 \<otimes> p\<^isub>3 = p\<^isub>1 \<otimes> (p\<^isub>2 \<otimes> p\<^isub>3)"
85.213 - unfolding mult_prod_def by (simp add: assoc)
85.214 -qed
85.215 -
85.216 -end %quote
85.217 -
85.218 -text {*
85.219 - \noindent Associativity from product semigroups is
85.220 - established using
85.221 - the definition of @{text "(\<otimes>)"} on products and the hypothetical
85.222 - associativity of the type components; these hypotheses
85.223 - are facts due to the @{class semigroup} constraints imposed
85.224 - on the type components by the @{command instance} proposition.
85.225 - Indeed, this pattern often occurs with parametric types
85.226 - and type classes.
85.227 -*}
85.228 -
85.229 -
85.230 -subsection {* Subclassing *}
85.231 -
85.232 -text {*
85.233 - We define a subclass @{text monoidl} (a semigroup with a left-hand neutral)
85.234 - by extending @{class semigroup}
85.235 - with one additional parameter @{text neutral} together
85.236 - with its property:
85.237 -*}
85.238 -
85.239 -class %quote monoidl = semigroup +
85.240 - fixes neutral :: "\<alpha>" ("\<one>")
85.241 - assumes neutl: "\<one> \<otimes> x = x"
85.242 -
85.243 -text {*
85.244 - \noindent Again, we prove some instances, by
85.245 - providing suitable parameter definitions and proofs for the
85.246 - additional specifications. Observe that instantiations
85.247 - for types with the same arity may be simultaneous:
85.248 -*}
85.249 -
85.250 -instantiation %quote nat and int :: monoidl
85.251 -begin
85.252 -
85.253 -definition %quote
85.254 - neutral_nat_def: "\<one> = (0\<Colon>nat)"
85.255 -
85.256 -definition %quote
85.257 - neutral_int_def: "\<one> = (0\<Colon>int)"
85.258 -
85.259 -instance %quote proof
85.260 - fix n :: nat
85.261 - show "\<one> \<otimes> n = n"
85.262 - unfolding neutral_nat_def by simp
85.263 -next
85.264 - fix k :: int
85.265 - show "\<one> \<otimes> k = k"
85.266 - unfolding neutral_int_def mult_int_def by simp
85.267 -qed
85.268 -
85.269 -end %quote
85.270 -
85.271 -instantiation %quote * :: (monoidl, monoidl) monoidl
85.272 -begin
85.273 -
85.274 -definition %quote
85.275 - neutral_prod_def: "\<one> = (\<one>, \<one>)"
85.276 -
85.277 -instance %quote proof
85.278 - fix p :: "\<alpha>\<Colon>monoidl \<times> \<beta>\<Colon>monoidl"
85.279 - show "\<one> \<otimes> p = p"
85.280 - unfolding neutral_prod_def mult_prod_def by (simp add: neutl)
85.281 -qed
85.282 -
85.283 -end %quote
85.284 -
85.285 -text {*
85.286 - \noindent Fully-fledged monoids are modelled by another subclass
85.287 - which does not add new parameters but tightens the specification:
85.288 -*}
85.289 -
85.290 -class %quote monoid = monoidl +
85.291 - assumes neutr: "x \<otimes> \<one> = x"
85.292 -
85.293 -instantiation %quote nat and int :: monoid
85.294 -begin
85.295 -
85.296 -instance %quote proof
85.297 - fix n :: nat
85.298 - show "n \<otimes> \<one> = n"
85.299 - unfolding neutral_nat_def by (induct n) simp_all
85.300 -next
85.301 - fix k :: int
85.302 - show "k \<otimes> \<one> = k"
85.303 - unfolding neutral_int_def mult_int_def by simp
85.304 -qed
85.305 -
85.306 -end %quote
85.307 -
85.308 -instantiation %quote * :: (monoid, monoid) monoid
85.309 -begin
85.310 -
85.311 -instance %quote proof
85.312 - fix p :: "\<alpha>\<Colon>monoid \<times> \<beta>\<Colon>monoid"
85.313 - show "p \<otimes> \<one> = p"
85.314 - unfolding neutral_prod_def mult_prod_def by (simp add: neutr)
85.315 -qed
85.316 -
85.317 -end %quote
85.318 -
85.319 -text {*
85.320 - \noindent To finish our small algebra example, we add a @{text group} class
85.321 - with a corresponding instance:
85.322 -*}
85.323 -
85.324 -class %quote group = monoidl +
85.325 - fixes inverse :: "\<alpha> \<Rightarrow> \<alpha>" ("(_\<div>)" [1000] 999)
85.326 - assumes invl: "x\<div> \<otimes> x = \<one>"
85.327 -
85.328 -instantiation %quote int :: group
85.329 -begin
85.330 -
85.331 -definition %quote
85.332 - inverse_int_def: "i\<div> = - (i\<Colon>int)"
85.333 -
85.334 -instance %quote proof
85.335 - fix i :: int
85.336 - have "-i + i = 0" by simp
85.337 - then show "i\<div> \<otimes> i = \<one>"
85.338 - unfolding mult_int_def neutral_int_def inverse_int_def .
85.339 -qed
85.340 -
85.341 -end %quote
85.342 -
85.343 -
85.344 -section {* Type classes as locales *}
85.345 -
85.346 -subsection {* A look behind the scene *}
85.347 -
85.348 -text {*
85.349 - The example above gives an impression how Isar type classes work
85.350 - in practice. As stated in the introduction, classes also provide
85.351 - a link to Isar's locale system. Indeed, the logical core of a class
85.352 - is nothing else than a locale:
85.353 -*}
85.354 -
85.355 -class %quote idem =
85.356 - fixes f :: "\<alpha> \<Rightarrow> \<alpha>"
85.357 - assumes idem: "f (f x) = f x"
85.358 -
85.359 -text {*
85.360 - \noindent essentially introduces the locale
85.361 -*} setup %invisible {* Sign.add_path "foo" *}
85.362 -
85.363 -locale %quote idem =
85.364 - fixes f :: "\<alpha> \<Rightarrow> \<alpha>"
85.365 - assumes idem: "f (f x) = f x"
85.366 -
85.367 -text {* \noindent together with corresponding constant(s): *}
85.368 -
85.369 -consts %quote f :: "\<alpha> \<Rightarrow> \<alpha>"
85.370 -
85.371 -text {*
85.372 - \noindent The connection to the type system is done by means
85.373 - of a primitive axclass
85.374 -*} setup %invisible {* Sign.add_path "foo" *}
85.375 -
85.376 -axclass %quote idem < type
85.377 - idem: "f (f x) = f x" setup %invisible {* Sign.parent_path *}
85.378 -
85.379 -text {* \noindent together with a corresponding interpretation: *}
85.380 -
85.381 -interpretation %quote idem_class:
85.382 - idem "f \<Colon> (\<alpha>\<Colon>idem) \<Rightarrow> \<alpha>"
85.383 -proof qed (rule idem)
85.384 -
85.385 -text {*
85.386 - \noindent This gives you at hand the full power of the Isabelle module system;
85.387 - conclusions in locale @{text idem} are implicitly propagated
85.388 - to class @{text idem}.
85.389 -*} setup %invisible {* Sign.parent_path *}
85.390 -
85.391 -subsection {* Abstract reasoning *}
85.392 -
85.393 -text {*
85.394 - Isabelle locales enable reasoning at a general level, while results
85.395 - are implicitly transferred to all instances. For example, we can
85.396 - now establish the @{text "left_cancel"} lemma for groups, which
85.397 - states that the function @{text "(x \<otimes>)"} is injective:
85.398 -*}
85.399 -
85.400 -lemma %quote (in group) left_cancel: "x \<otimes> y = x \<otimes> z \<longleftrightarrow> y = z"
85.401 -proof
85.402 - assume "x \<otimes> y = x \<otimes> z"
85.403 - then have "x\<div> \<otimes> (x \<otimes> y) = x\<div> \<otimes> (x \<otimes> z)" by simp
85.404 - then have "(x\<div> \<otimes> x) \<otimes> y = (x\<div> \<otimes> x) \<otimes> z" using assoc by simp
85.405 - then show "y = z" using neutl and invl by simp
85.406 -next
85.407 - assume "y = z"
85.408 - then show "x \<otimes> y = x \<otimes> z" by simp
85.409 -qed
85.410 -
85.411 -text {*
85.412 - \noindent Here the \qt{@{keyword "in"} @{class group}} target specification
85.413 - indicates that the result is recorded within that context for later
85.414 - use. This local theorem is also lifted to the global one @{fact
85.415 - "group.left_cancel:"} @{prop [source] "\<And>x y z \<Colon> \<alpha>\<Colon>group. x \<otimes> y = x \<otimes>
85.416 - z \<longleftrightarrow> y = z"}. Since type @{text "int"} has been made an instance of
85.417 - @{text "group"} before, we may refer to that fact as well: @{prop
85.418 - [source] "\<And>x y z \<Colon> int. x \<otimes> y = x \<otimes> z \<longleftrightarrow> y = z"}.
85.419 -*}
85.420 -
85.421 -
85.422 -subsection {* Derived definitions *}
85.423 -
85.424 -text {*
85.425 - Isabelle locales support a concept of local definitions
85.426 - in locales:
85.427 -*}
85.428 -
85.429 -primrec %quote (in monoid) pow_nat :: "nat \<Rightarrow> \<alpha> \<Rightarrow> \<alpha>" where
85.430 - "pow_nat 0 x = \<one>"
85.431 - | "pow_nat (Suc n) x = x \<otimes> pow_nat n x"
85.432 -
85.433 -text {*
85.434 - \noindent If the locale @{text group} is also a class, this local
85.435 - definition is propagated onto a global definition of
85.436 - @{term [source] "pow_nat \<Colon> nat \<Rightarrow> \<alpha>\<Colon>monoid \<Rightarrow> \<alpha>\<Colon>monoid"}
85.437 - with corresponding theorems
85.438 -
85.439 - @{thm pow_nat.simps [no_vars]}.
85.440 -
85.441 - \noindent As you can see from this example, for local
85.442 - definitions you may use any specification tool
85.443 - which works together with locales (e.g. \cite{krauss2006}).
85.444 -*}
85.445 -
85.446 -
85.447 -subsection {* A functor analogy *}
85.448 -
85.449 -text {*
85.450 - We introduced Isar classes by analogy to type classes
85.451 - functional programming; if we reconsider this in the
85.452 - context of what has been said about type classes and locales,
85.453 - we can drive this analogy further by stating that type
85.454 - classes essentially correspond to functors which have
85.455 - a canonical interpretation as type classes.
85.456 - Anyway, there is also the possibility of other interpretations.
85.457 - For example, also @{text list}s form a monoid with
85.458 - @{text append} and @{term "[]"} as operations, but it
85.459 - seems inappropriate to apply to lists
85.460 - the same operations as for genuinely algebraic types.
85.461 - In such a case, we simply can do a particular interpretation
85.462 - of monoids for lists:
85.463 -*}
85.464 -
85.465 -interpretation %quote list_monoid!: monoid append "[]"
85.466 - proof qed auto
85.467 -
85.468 -text {*
85.469 - \noindent This enables us to apply facts on monoids
85.470 - to lists, e.g. @{thm list_monoid.neutl [no_vars]}.
85.471 -
85.472 - When using this interpretation pattern, it may also
85.473 - be appropriate to map derived definitions accordingly:
85.474 -*}
85.475 -
85.476 -primrec %quote replicate :: "nat \<Rightarrow> \<alpha> list \<Rightarrow> \<alpha> list" where
85.477 - "replicate 0 _ = []"
85.478 - | "replicate (Suc n) xs = xs @ replicate n xs"
85.479 -
85.480 -interpretation %quote list_monoid!: monoid append "[]" where
85.481 - "monoid.pow_nat append [] = replicate"
85.482 -proof -
85.483 - interpret monoid append "[]" ..
85.484 - show "monoid.pow_nat append [] = replicate"
85.485 - proof
85.486 - fix n
85.487 - show "monoid.pow_nat append [] n = replicate n"
85.488 - by (induct n) auto
85.489 - qed
85.490 -qed intro_locales
85.491 -
85.492 -
85.493 -subsection {* Additional subclass relations *}
85.494 -
85.495 -text {*
85.496 - Any @{text "group"} is also a @{text "monoid"}; this
85.497 - can be made explicit by claiming an additional
85.498 - subclass relation,
85.499 - together with a proof of the logical difference:
85.500 -*}
85.501 -
85.502 -subclass %quote (in group) monoid
85.503 -proof
85.504 - fix x
85.505 - from invl have "x\<div> \<otimes> x = \<one>" by simp
85.506 - with assoc [symmetric] neutl invl have "x\<div> \<otimes> (x \<otimes> \<one>) = x\<div> \<otimes> x" by simp
85.507 - with left_cancel show "x \<otimes> \<one> = x" by simp
85.508 -qed
85.509 -
85.510 -text {*
85.511 - \noindent The logical proof is carried out on the locale level.
85.512 - Afterwards it is propagated
85.513 - to the type system, making @{text group} an instance of
85.514 - @{text monoid} by adding an additional edge
85.515 - to the graph of subclass relations
85.516 - (cf.\ \figref{fig:subclass}).
85.517 -
85.518 - \begin{figure}[htbp]
85.519 - \begin{center}
85.520 - \small
85.521 - \unitlength 0.6mm
85.522 - \begin{picture}(40,60)(0,0)
85.523 - \put(20,60){\makebox(0,0){@{text semigroup}}}
85.524 - \put(20,40){\makebox(0,0){@{text monoidl}}}
85.525 - \put(00,20){\makebox(0,0){@{text monoid}}}
85.526 - \put(40,00){\makebox(0,0){@{text group}}}
85.527 - \put(20,55){\vector(0,-1){10}}
85.528 - \put(15,35){\vector(-1,-1){10}}
85.529 - \put(25,35){\vector(1,-3){10}}
85.530 - \end{picture}
85.531 - \hspace{8em}
85.532 - \begin{picture}(40,60)(0,0)
85.533 - \put(20,60){\makebox(0,0){@{text semigroup}}}
85.534 - \put(20,40){\makebox(0,0){@{text monoidl}}}
85.535 - \put(00,20){\makebox(0,0){@{text monoid}}}
85.536 - \put(40,00){\makebox(0,0){@{text group}}}
85.537 - \put(20,55){\vector(0,-1){10}}
85.538 - \put(15,35){\vector(-1,-1){10}}
85.539 - \put(05,15){\vector(3,-1){30}}
85.540 - \end{picture}
85.541 - \caption{Subclass relationship of monoids and groups:
85.542 - before and after establishing the relationship
85.543 - @{text "group \<subseteq> monoid"}; transitive edges left out.}
85.544 - \label{fig:subclass}
85.545 - \end{center}
85.546 - \end{figure}
85.547 -7
85.548 - For illustration, a derived definition
85.549 - in @{text group} which uses @{text pow_nat}:
85.550 -*}
85.551 -
85.552 -definition %quote (in group) pow_int :: "int \<Rightarrow> \<alpha> \<Rightarrow> \<alpha>" where
85.553 - "pow_int k x = (if k >= 0
85.554 - then pow_nat (nat k) x
85.555 - else (pow_nat (nat (- k)) x)\<div>)"
85.556 -
85.557 -text {*
85.558 - \noindent yields the global definition of
85.559 - @{term [source] "pow_int \<Colon> int \<Rightarrow> \<alpha>\<Colon>group \<Rightarrow> \<alpha>\<Colon>group"}
85.560 - with the corresponding theorem @{thm pow_int_def [no_vars]}.
85.561 -*}
85.562 -
85.563 -subsection {* A note on syntax *}
85.564 -
85.565 -text {*
85.566 - As a commodity, class context syntax allows to refer
85.567 - to local class operations and their global counterparts
85.568 - uniformly; type inference resolves ambiguities. For example:
85.569 -*}
85.570 -
85.571 -context %quote semigroup
85.572 -begin
85.573 -
85.574 -term %quote "x \<otimes> y" -- {* example 1 *}
85.575 -term %quote "(x\<Colon>nat) \<otimes> y" -- {* example 2 *}
85.576 -
85.577 -end %quote
85.578 -
85.579 -term %quote "x \<otimes> y" -- {* example 3 *}
85.580 -
85.581 -text {*
85.582 - \noindent Here in example 1, the term refers to the local class operation
85.583 - @{text "mult [\<alpha>]"}, whereas in example 2 the type constraint
85.584 - enforces the global class operation @{text "mult [nat]"}.
85.585 - In the global context in example 3, the reference is
85.586 - to the polymorphic global class operation @{text "mult [?\<alpha> \<Colon> semigroup]"}.
85.587 -*}
85.588 -
85.589 -section {* Further issues *}
85.590 -
85.591 -subsection {* Type classes and code generation *}
85.592 -
85.593 -text {*
85.594 - Turning back to the first motivation for type classes,
85.595 - namely overloading, it is obvious that overloading
85.596 - stemming from @{command class} statements and
85.597 - @{command instantiation}
85.598 - targets naturally maps to Haskell type classes.
85.599 - The code generator framework \cite{isabelle-codegen}
85.600 - takes this into account. Concerning target languages
85.601 - lacking type classes (e.g.~SML), type classes
85.602 - are implemented by explicit dictionary construction.
85.603 - As example, let's go back to the power function:
85.604 -*}
85.605 -
85.606 -definition %quote example :: int where
85.607 - "example = pow_int 10 (-2)"
85.608 -
85.609 -text {*
85.610 - \noindent This maps to Haskell as:
85.611 -*}
85.612 -
85.613 -text %quote {*@{code_stmts example (Haskell)}*}
85.614 -
85.615 -text {*
85.616 - \noindent The whole code in SML with explicit dictionary passing:
85.617 -*}
85.618 -
85.619 -text %quote {*@{code_stmts example (SML)}*}
85.620 -
85.621 -subsection {* Inspecting the type class universe *}
85.622 -
85.623 -text {*
85.624 - To facilitate orientation in complex subclass structures,
85.625 - two diagnostics commands are provided:
85.626 -
85.627 - \begin{description}
85.628 -
85.629 - \item[@{command "print_classes"}] print a list of all classes
85.630 - together with associated operations etc.
85.631 -
85.632 - \item[@{command "class_deps"}] visualizes the subclass relation
85.633 - between all classes as a Hasse diagram.
85.634 -
85.635 - \end{description}
85.636 -*}
85.637 -
85.638 -end
86.1 --- a/doc-src/IsarAdvanced/Classes/Thy/ROOT.ML Wed Mar 04 11:05:02 2009 +0100
86.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
86.3 @@ -1,6 +0,0 @@
86.4 -
86.5 -(* $Id$ *)
86.6 -
86.7 -no_document use_thy "Setup";
86.8 -
86.9 -use_thy "Classes";
87.1 --- a/doc-src/IsarAdvanced/Classes/Thy/Setup.thy Wed Mar 04 11:05:02 2009 +0100
87.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
87.3 @@ -1,34 +0,0 @@
87.4 -theory Setup
87.5 -imports Main Code_Integer
87.6 -uses
87.7 - "../../../antiquote_setup"
87.8 - "../../../more_antiquote"
87.9 -begin
87.10 -
87.11 -ML {* Code_Target.code_width := 74 *}
87.12 -
87.13 -syntax
87.14 - "_alpha" :: "type" ("\<alpha>")
87.15 - "_alpha_ofsort" :: "sort \<Rightarrow> type" ("\<alpha>()\<Colon>_" [0] 1000)
87.16 - "_beta" :: "type" ("\<beta>")
87.17 - "_beta_ofsort" :: "sort \<Rightarrow> type" ("\<beta>()\<Colon>_" [0] 1000)
87.18 -
87.19 -parse_ast_translation {*
87.20 - let
87.21 - fun alpha_ast_tr [] = Syntax.Variable "'a"
87.22 - | alpha_ast_tr asts = raise Syntax.AST ("alpha_ast_tr", asts);
87.23 - fun alpha_ofsort_ast_tr [ast] =
87.24 - Syntax.Appl [Syntax.Constant "_ofsort", Syntax.Variable "'a", ast]
87.25 - | alpha_ofsort_ast_tr asts = raise Syntax.AST ("alpha_ast_tr", asts);
87.26 - fun beta_ast_tr [] = Syntax.Variable "'b"
87.27 - | beta_ast_tr asts = raise Syntax.AST ("beta_ast_tr", asts);
87.28 - fun beta_ofsort_ast_tr [ast] =
87.29 - Syntax.Appl [Syntax.Constant "_ofsort", Syntax.Variable "'b", ast]
87.30 - | beta_ofsort_ast_tr asts = raise Syntax.AST ("beta_ast_tr", asts);
87.31 - in [
87.32 - ("_alpha", alpha_ast_tr), ("_alpha_ofsort", alpha_ofsort_ast_tr),
87.33 - ("_beta", beta_ast_tr), ("_beta_ofsort", beta_ofsort_ast_tr)
87.34 - ] end
87.35 -*}
87.36 -
87.37 -end
87.38 \ No newline at end of file
88.1 --- a/doc-src/IsarAdvanced/Classes/Thy/document/Classes.tex Wed Mar 04 11:05:02 2009 +0100
88.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
88.3 @@ -1,1346 +0,0 @@
88.4 -%
88.5 -\begin{isabellebody}%
88.6 -\def\isabellecontext{Classes}%
88.7 -%
88.8 -\isadelimtheory
88.9 -%
88.10 -\endisadelimtheory
88.11 -%
88.12 -\isatagtheory
88.13 -\isacommand{theory}\isamarkupfalse%
88.14 -\ Classes\isanewline
88.15 -\isakeyword{imports}\ Main\ Setup\isanewline
88.16 -\isakeyword{begin}%
88.17 -\endisatagtheory
88.18 -{\isafoldtheory}%
88.19 -%
88.20 -\isadelimtheory
88.21 -%
88.22 -\endisadelimtheory
88.23 -%
88.24 -\isamarkupchapter{Haskell-style classes with Isabelle/Isar%
88.25 -}
88.26 -\isamarkuptrue%
88.27 -%
88.28 -\isamarkupsection{Introduction%
88.29 -}
88.30 -\isamarkuptrue%
88.31 -%
88.32 -\begin{isamarkuptext}%
88.33 -Type classes were introduces by Wadler and Blott \cite{wadler89how}
88.34 - into the Haskell language, to allow for a reasonable implementation
88.35 - of overloading\footnote{throughout this tutorial, we are referring
88.36 - to classical Haskell 1.0 type classes, not considering
88.37 - later additions in expressiveness}.
88.38 - As a canonical example, a polymorphic equality function
88.39 - \isa{eq\ {\isasymColon}\ {\isasymalpha}\ {\isasymRightarrow}\ {\isasymalpha}\ {\isasymRightarrow}\ bool} which is overloaded on different
88.40 - types for \isa{{\isasymalpha}}, which is achieved by splitting introduction
88.41 - of the \isa{eq} function from its overloaded definitions by means
88.42 - of \isa{class} and \isa{instance} declarations:
88.43 -
88.44 - \begin{quote}
88.45 -
88.46 - \noindent\isa{class\ eq\ where}\footnote{syntax here is a kind of isabellized Haskell} \\
88.47 - \hspace*{2ex}\isa{eq\ {\isasymColon}\ {\isasymalpha}\ {\isasymRightarrow}\ {\isasymalpha}\ {\isasymRightarrow}\ bool}
88.48 -
88.49 - \medskip\noindent\isa{instance\ nat\ {\isasymColon}\ eq\ where} \\
88.50 - \hspace*{2ex}\isa{eq\ {\isadigit{0}}\ {\isadigit{0}}\ {\isacharequal}\ True} \\
88.51 - \hspace*{2ex}\isa{eq\ {\isadigit{0}}\ {\isacharunderscore}\ {\isacharequal}\ False} \\
88.52 - \hspace*{2ex}\isa{eq\ {\isacharunderscore}\ {\isadigit{0}}\ {\isacharequal}\ False} \\
88.53 - \hspace*{2ex}\isa{eq\ {\isacharparenleft}Suc\ n{\isacharparenright}\ {\isacharparenleft}Suc\ m{\isacharparenright}\ {\isacharequal}\ eq\ n\ m}
88.54 -
88.55 - \medskip\noindent\isa{instance\ {\isacharparenleft}{\isasymalpha}{\isasymColon}eq{\isacharcomma}\ {\isasymbeta}{\isasymColon}eq{\isacharparenright}\ pair\ {\isasymColon}\ eq\ where} \\
88.56 - \hspace*{2ex}\isa{eq\ {\isacharparenleft}x{\isadigit{1}}{\isacharcomma}\ y{\isadigit{1}}{\isacharparenright}\ {\isacharparenleft}x{\isadigit{2}}{\isacharcomma}\ y{\isadigit{2}}{\isacharparenright}\ {\isacharequal}\ eq\ x{\isadigit{1}}\ x{\isadigit{2}}\ {\isasymand}\ eq\ y{\isadigit{1}}\ y{\isadigit{2}}}
88.57 -
88.58 - \medskip\noindent\isa{class\ ord\ extends\ eq\ where} \\
88.59 - \hspace*{2ex}\isa{less{\isacharunderscore}eq\ {\isasymColon}\ {\isasymalpha}\ {\isasymRightarrow}\ {\isasymalpha}\ {\isasymRightarrow}\ bool} \\
88.60 - \hspace*{2ex}\isa{less\ {\isasymColon}\ {\isasymalpha}\ {\isasymRightarrow}\ {\isasymalpha}\ {\isasymRightarrow}\ bool}
88.61 -
88.62 - \end{quote}
88.63 -
88.64 - \noindent Type variables are annotated with (finitely many) classes;
88.65 - these annotations are assertions that a particular polymorphic type
88.66 - provides definitions for overloaded functions.
88.67 -
88.68 - Indeed, type classes not only allow for simple overloading
88.69 - but form a generic calculus, an instance of order-sorted
88.70 - algebra \cite{Nipkow-Prehofer:1993,nipkow-sorts93,Wenzel:1997:TPHOL}.
88.71 -
88.72 - From a software engeneering point of view, type classes
88.73 - roughly correspond to interfaces in object-oriented languages like Java;
88.74 - so, it is naturally desirable that type classes do not only
88.75 - provide functions (class parameters) but also state specifications
88.76 - implementations must obey. For example, the \isa{class\ eq}
88.77 - above could be given the following specification, demanding that
88.78 - \isa{class\ eq} is an equivalence relation obeying reflexivity,
88.79 - symmetry and transitivity:
88.80 -
88.81 - \begin{quote}
88.82 -
88.83 - \noindent\isa{class\ eq\ where} \\
88.84 - \hspace*{2ex}\isa{eq\ {\isasymColon}\ {\isasymalpha}\ {\isasymRightarrow}\ {\isasymalpha}\ {\isasymRightarrow}\ bool} \\
88.85 - \isa{satisfying} \\
88.86 - \hspace*{2ex}\isa{refl{\isacharcolon}\ eq\ x\ x} \\
88.87 - \hspace*{2ex}\isa{sym{\isacharcolon}\ eq\ x\ y\ {\isasymlongleftrightarrow}\ eq\ x\ y} \\
88.88 - \hspace*{2ex}\isa{trans{\isacharcolon}\ eq\ x\ y\ {\isasymand}\ eq\ y\ z\ {\isasymlongrightarrow}\ eq\ x\ z}
88.89 -
88.90 - \end{quote}
88.91 -
88.92 - \noindent From a theoretic point of view, type classes are lightweight
88.93 - modules; Haskell type classes may be emulated by
88.94 - SML functors \cite{classes_modules}.
88.95 - Isabelle/Isar offers a discipline of type classes which brings
88.96 - all those aspects together:
88.97 -
88.98 - \begin{enumerate}
88.99 - \item specifying abstract parameters together with
88.100 - corresponding specifications,
88.101 - \item instantiating those abstract parameters by a particular
88.102 - type
88.103 - \item in connection with a ``less ad-hoc'' approach to overloading,
88.104 - \item with a direct link to the Isabelle module system
88.105 - (aka locales \cite{kammueller-locales}).
88.106 - \end{enumerate}
88.107 -
88.108 - \noindent Isar type classes also directly support code generation
88.109 - in a Haskell like fashion.
88.110 -
88.111 - This tutorial demonstrates common elements of structured specifications
88.112 - and abstract reasoning with type classes by the algebraic hierarchy of
88.113 - semigroups, monoids and groups. Our background theory is that of
88.114 - Isabelle/HOL \cite{isa-tutorial}, for which some
88.115 - familiarity is assumed.
88.116 -
88.117 - Here we merely present the look-and-feel for end users.
88.118 - Internally, those are mapped to more primitive Isabelle concepts.
88.119 - See \cite{Haftmann-Wenzel:2006:classes} for more detail.%
88.120 -\end{isamarkuptext}%
88.121 -\isamarkuptrue%
88.122 -%
88.123 -\isamarkupsection{A simple algebra example \label{sec:example}%
88.124 -}
88.125 -\isamarkuptrue%
88.126 -%
88.127 -\isamarkupsubsection{Class definition%
88.128 -}
88.129 -\isamarkuptrue%
88.130 -%
88.131 -\begin{isamarkuptext}%
88.132 -Depending on an arbitrary type \isa{{\isasymalpha}}, class \isa{semigroup} introduces a binary operator \isa{{\isacharparenleft}{\isasymotimes}{\isacharparenright}} that is
88.133 - assumed to be associative:%
88.134 -\end{isamarkuptext}%
88.135 -\isamarkuptrue%
88.136 -%
88.137 -\isadelimquote
88.138 -%
88.139 -\endisadelimquote
88.140 -%
88.141 -\isatagquote
88.142 -\isacommand{class}\isamarkupfalse%
88.143 -\ semigroup\ {\isacharequal}\isanewline
88.144 -\ \ \isakeyword{fixes}\ mult\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isasymalpha}\ {\isasymRightarrow}\ {\isasymalpha}\ {\isasymRightarrow}\ {\isasymalpha}{\isachardoublequoteclose}\ \ \ \ {\isacharparenleft}\isakeyword{infixl}\ {\isachardoublequoteopen}{\isasymotimes}{\isachardoublequoteclose}\ {\isadigit{7}}{\isadigit{0}}{\isacharparenright}\isanewline
88.145 -\ \ \isakeyword{assumes}\ assoc{\isacharcolon}\ {\isachardoublequoteopen}{\isacharparenleft}x\ {\isasymotimes}\ y{\isacharparenright}\ {\isasymotimes}\ z\ {\isacharequal}\ x\ {\isasymotimes}\ {\isacharparenleft}y\ {\isasymotimes}\ z{\isacharparenright}{\isachardoublequoteclose}%
88.146 -\endisatagquote
88.147 -{\isafoldquote}%
88.148 -%
88.149 -\isadelimquote
88.150 -%
88.151 -\endisadelimquote
88.152 -%
88.153 -\begin{isamarkuptext}%
88.154 -\noindent This \hyperlink{command.class}{\mbox{\isa{\isacommand{class}}}} specification consists of two
88.155 - parts: the \qn{operational} part names the class parameter
88.156 - (\hyperlink{element.fixes}{\mbox{\isa{\isakeyword{fixes}}}}), the \qn{logical} part specifies properties on them
88.157 - (\hyperlink{element.assumes}{\mbox{\isa{\isakeyword{assumes}}}}). The local \hyperlink{element.fixes}{\mbox{\isa{\isakeyword{fixes}}}} and
88.158 - \hyperlink{element.assumes}{\mbox{\isa{\isakeyword{assumes}}}} are lifted to the theory toplevel,
88.159 - yielding the global
88.160 - parameter \isa{{\isachardoublequote}mult\ {\isasymColon}\ {\isasymalpha}{\isasymColon}semigroup\ {\isasymRightarrow}\ {\isasymalpha}\ {\isasymRightarrow}\ {\isasymalpha}{\isachardoublequote}} and the
88.161 - global theorem \hyperlink{fact.semigroup.assoc:}{\mbox{\isa{semigroup{\isachardot}assoc{\isacharcolon}}}}~\isa{{\isachardoublequote}{\isasymAnd}x\ y\ z\ {\isasymColon}\ {\isasymalpha}{\isasymColon}semigroup{\isachardot}\ {\isacharparenleft}x\ {\isasymotimes}\ y{\isacharparenright}\ {\isasymotimes}\ z\ {\isacharequal}\ x\ {\isasymotimes}\ {\isacharparenleft}y\ {\isasymotimes}\ z{\isacharparenright}{\isachardoublequote}}.%
88.162 -\end{isamarkuptext}%
88.163 -\isamarkuptrue%
88.164 -%
88.165 -\isamarkupsubsection{Class instantiation \label{sec:class_inst}%
88.166 -}
88.167 -\isamarkuptrue%
88.168 -%
88.169 -\begin{isamarkuptext}%
88.170 -The concrete type \isa{int} is made a \isa{semigroup}
88.171 - instance by providing a suitable definition for the class parameter
88.172 - \isa{{\isacharparenleft}{\isasymotimes}{\isacharparenright}} and a proof for the specification of \hyperlink{fact.assoc}{\mbox{\isa{assoc}}}.
88.173 - This is accomplished by the \hyperlink{command.instantiation}{\mbox{\isa{\isacommand{instantiation}}}} target:%
88.174 -\end{isamarkuptext}%
88.175 -\isamarkuptrue%
88.176 -%
88.177 -\isadelimquote
88.178 -%
88.179 -\endisadelimquote
88.180 -%
88.181 -\isatagquote
88.182 -\isacommand{instantiation}\isamarkupfalse%
88.183 -\ int\ {\isacharcolon}{\isacharcolon}\ semigroup\isanewline
88.184 -\isakeyword{begin}\isanewline
88.185 -\isanewline
88.186 -\isacommand{definition}\isamarkupfalse%
88.187 -\isanewline
88.188 -\ \ mult{\isacharunderscore}int{\isacharunderscore}def{\isacharcolon}\ {\isachardoublequoteopen}i\ {\isasymotimes}\ j\ {\isacharequal}\ i\ {\isacharplus}\ {\isacharparenleft}j{\isasymColon}int{\isacharparenright}{\isachardoublequoteclose}\isanewline
88.189 -\isanewline
88.190 -\isacommand{instance}\isamarkupfalse%
88.191 -\ \isacommand{proof}\isamarkupfalse%
88.192 -\isanewline
88.193 -\ \ \isacommand{fix}\isamarkupfalse%
88.194 -\ i\ j\ k\ {\isacharcolon}{\isacharcolon}\ int\ \isacommand{have}\isamarkupfalse%
88.195 -\ {\isachardoublequoteopen}{\isacharparenleft}i\ {\isacharplus}\ j{\isacharparenright}\ {\isacharplus}\ k\ {\isacharequal}\ i\ {\isacharplus}\ {\isacharparenleft}j\ {\isacharplus}\ k{\isacharparenright}{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse%
88.196 -\ simp\isanewline
88.197 -\ \ \isacommand{then}\isamarkupfalse%
88.198 -\ \isacommand{show}\isamarkupfalse%
88.199 -\ {\isachardoublequoteopen}{\isacharparenleft}i\ {\isasymotimes}\ j{\isacharparenright}\ {\isasymotimes}\ k\ {\isacharequal}\ i\ {\isasymotimes}\ {\isacharparenleft}j\ {\isasymotimes}\ k{\isacharparenright}{\isachardoublequoteclose}\isanewline
88.200 -\ \ \ \ \isacommand{unfolding}\isamarkupfalse%
88.201 -\ mult{\isacharunderscore}int{\isacharunderscore}def\ \isacommand{{\isachardot}}\isamarkupfalse%
88.202 -\isanewline
88.203 -\isacommand{qed}\isamarkupfalse%
88.204 -\isanewline
88.205 -\isanewline
88.206 -\isacommand{end}\isamarkupfalse%
88.207 -%
88.208 -\endisatagquote
88.209 -{\isafoldquote}%
88.210 -%
88.211 -\isadelimquote
88.212 -%
88.213 -\endisadelimquote
88.214 -%
88.215 -\begin{isamarkuptext}%
88.216 -\noindent \hyperlink{command.instantiation}{\mbox{\isa{\isacommand{instantiation}}}} allows to define class parameters
88.217 - at a particular instance using common specification tools (here,
88.218 - \hyperlink{command.definition}{\mbox{\isa{\isacommand{definition}}}}). The concluding \hyperlink{command.instance}{\mbox{\isa{\isacommand{instance}}}}
88.219 - opens a proof that the given parameters actually conform
88.220 - to the class specification. Note that the first proof step
88.221 - is the \hyperlink{method.default}{\mbox{\isa{default}}} method,
88.222 - which for such instance proofs maps to the \hyperlink{method.intro-classes}{\mbox{\isa{intro{\isacharunderscore}classes}}} method.
88.223 - This boils down an instance judgement to the relevant primitive
88.224 - proof goals and should conveniently always be the first method applied
88.225 - in an instantiation proof.
88.226 -
88.227 - From now on, the type-checker will consider \isa{int}
88.228 - as a \isa{semigroup} automatically, i.e.\ any general results
88.229 - are immediately available on concrete instances.
88.230 -
88.231 - \medskip Another instance of \isa{semigroup} are the natural numbers:%
88.232 -\end{isamarkuptext}%
88.233 -\isamarkuptrue%
88.234 -%
88.235 -\isadelimquote
88.236 -%
88.237 -\endisadelimquote
88.238 -%
88.239 -\isatagquote
88.240 -\isacommand{instantiation}\isamarkupfalse%
88.241 -\ nat\ {\isacharcolon}{\isacharcolon}\ semigroup\isanewline
88.242 -\isakeyword{begin}\isanewline
88.243 -\isanewline
88.244 -\isacommand{primrec}\isamarkupfalse%
88.245 -\ mult{\isacharunderscore}nat\ \isakeyword{where}\isanewline
88.246 -\ \ {\isachardoublequoteopen}{\isacharparenleft}{\isadigit{0}}{\isasymColon}nat{\isacharparenright}\ {\isasymotimes}\ n\ {\isacharequal}\ n{\isachardoublequoteclose}\isanewline
88.247 -\ \ {\isacharbar}\ {\isachardoublequoteopen}Suc\ m\ {\isasymotimes}\ n\ {\isacharequal}\ Suc\ {\isacharparenleft}m\ {\isasymotimes}\ n{\isacharparenright}{\isachardoublequoteclose}\isanewline
88.248 -\isanewline
88.249 -\isacommand{instance}\isamarkupfalse%
88.250 -\ \isacommand{proof}\isamarkupfalse%
88.251 -\isanewline
88.252 -\ \ \isacommand{fix}\isamarkupfalse%
88.253 -\ m\ n\ q\ {\isacharcolon}{\isacharcolon}\ nat\ \isanewline
88.254 -\ \ \isacommand{show}\isamarkupfalse%
88.255 -\ {\isachardoublequoteopen}m\ {\isasymotimes}\ n\ {\isasymotimes}\ q\ {\isacharequal}\ m\ {\isasymotimes}\ {\isacharparenleft}n\ {\isasymotimes}\ q{\isacharparenright}{\isachardoublequoteclose}\isanewline
88.256 -\ \ \ \ \isacommand{by}\isamarkupfalse%
88.257 -\ {\isacharparenleft}induct\ m{\isacharparenright}\ auto\isanewline
88.258 -\isacommand{qed}\isamarkupfalse%
88.259 -\isanewline
88.260 -\isanewline
88.261 -\isacommand{end}\isamarkupfalse%
88.262 -%
88.263 -\endisatagquote
88.264 -{\isafoldquote}%
88.265 -%
88.266 -\isadelimquote
88.267 -%
88.268 -\endisadelimquote
88.269 -%
88.270 -\begin{isamarkuptext}%
88.271 -\noindent Note the occurence of the name \isa{mult{\isacharunderscore}nat}
88.272 - in the primrec declaration; by default, the local name of
88.273 - a class operation \isa{f} to instantiate on type constructor
88.274 - \isa{{\isasymkappa}} are mangled as \isa{f{\isacharunderscore}{\isasymkappa}}. In case of uncertainty,
88.275 - these names may be inspected using the \hyperlink{command.print-context}{\mbox{\isa{\isacommand{print{\isacharunderscore}context}}}} command
88.276 - or the corresponding ProofGeneral button.%
88.277 -\end{isamarkuptext}%
88.278 -\isamarkuptrue%
88.279 -%
88.280 -\isamarkupsubsection{Lifting and parametric types%
88.281 -}
88.282 -\isamarkuptrue%
88.283 -%
88.284 -\begin{isamarkuptext}%
88.285 -Overloaded definitions giving on class instantiation
88.286 - may include recursion over the syntactic structure of types.
88.287 - As a canonical example, we model product semigroups
88.288 - using our simple algebra:%
88.289 -\end{isamarkuptext}%
88.290 -\isamarkuptrue%
88.291 -%
88.292 -\isadelimquote
88.293 -%
88.294 -\endisadelimquote
88.295 -%
88.296 -\isatagquote
88.297 -\isacommand{instantiation}\isamarkupfalse%
88.298 -\ {\isacharasterisk}\ {\isacharcolon}{\isacharcolon}\ {\isacharparenleft}semigroup{\isacharcomma}\ semigroup{\isacharparenright}\ semigroup\isanewline
88.299 -\isakeyword{begin}\isanewline
88.300 -\isanewline
88.301 -\isacommand{definition}\isamarkupfalse%
88.302 -\isanewline
88.303 -\ \ mult{\isacharunderscore}prod{\isacharunderscore}def{\isacharcolon}\ {\isachardoublequoteopen}p\isactrlisub {\isadigit{1}}\ {\isasymotimes}\ p\isactrlisub {\isadigit{2}}\ {\isacharequal}\ {\isacharparenleft}fst\ p\isactrlisub {\isadigit{1}}\ {\isasymotimes}\ fst\ p\isactrlisub {\isadigit{2}}{\isacharcomma}\ snd\ p\isactrlisub {\isadigit{1}}\ {\isasymotimes}\ snd\ p\isactrlisub {\isadigit{2}}{\isacharparenright}{\isachardoublequoteclose}\isanewline
88.304 -\isanewline
88.305 -\isacommand{instance}\isamarkupfalse%
88.306 -\ \isacommand{proof}\isamarkupfalse%
88.307 -\isanewline
88.308 -\ \ \isacommand{fix}\isamarkupfalse%
88.309 -\ p\isactrlisub {\isadigit{1}}\ p\isactrlisub {\isadigit{2}}\ p\isactrlisub {\isadigit{3}}\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isasymalpha}{\isasymColon}semigroup\ {\isasymtimes}\ {\isasymbeta}{\isasymColon}semigroup{\isachardoublequoteclose}\isanewline
88.310 -\ \ \isacommand{show}\isamarkupfalse%
88.311 -\ {\isachardoublequoteopen}p\isactrlisub {\isadigit{1}}\ {\isasymotimes}\ p\isactrlisub {\isadigit{2}}\ {\isasymotimes}\ p\isactrlisub {\isadigit{3}}\ {\isacharequal}\ p\isactrlisub {\isadigit{1}}\ {\isasymotimes}\ {\isacharparenleft}p\isactrlisub {\isadigit{2}}\ {\isasymotimes}\ p\isactrlisub {\isadigit{3}}{\isacharparenright}{\isachardoublequoteclose}\isanewline
88.312 -\ \ \ \ \isacommand{unfolding}\isamarkupfalse%
88.313 -\ mult{\isacharunderscore}prod{\isacharunderscore}def\ \isacommand{by}\isamarkupfalse%
88.314 -\ {\isacharparenleft}simp\ add{\isacharcolon}\ assoc{\isacharparenright}\isanewline
88.315 -\isacommand{qed}\isamarkupfalse%
88.316 -\ \ \ \ \ \ \isanewline
88.317 -\isanewline
88.318 -\isacommand{end}\isamarkupfalse%
88.319 -%
88.320 -\endisatagquote
88.321 -{\isafoldquote}%
88.322 -%
88.323 -\isadelimquote
88.324 -%
88.325 -\endisadelimquote
88.326 -%
88.327 -\begin{isamarkuptext}%
88.328 -\noindent Associativity from product semigroups is
88.329 - established using
88.330 - the definition of \isa{{\isacharparenleft}{\isasymotimes}{\isacharparenright}} on products and the hypothetical
88.331 - associativity of the type components; these hypotheses
88.332 - are facts due to the \isa{semigroup} constraints imposed
88.333 - on the type components by the \hyperlink{command.instance}{\mbox{\isa{\isacommand{instance}}}} proposition.
88.334 - Indeed, this pattern often occurs with parametric types
88.335 - and type classes.%
88.336 -\end{isamarkuptext}%
88.337 -\isamarkuptrue%
88.338 -%
88.339 -\isamarkupsubsection{Subclassing%
88.340 -}
88.341 -\isamarkuptrue%
88.342 -%
88.343 -\begin{isamarkuptext}%
88.344 -We define a subclass \isa{monoidl} (a semigroup with a left-hand neutral)
88.345 - by extending \isa{semigroup}
88.346 - with one additional parameter \isa{neutral} together
88.347 - with its property:%
88.348 -\end{isamarkuptext}%
88.349 -\isamarkuptrue%
88.350 -%
88.351 -\isadelimquote
88.352 -%
88.353 -\endisadelimquote
88.354 -%
88.355 -\isatagquote
88.356 -\isacommand{class}\isamarkupfalse%
88.357 -\ monoidl\ {\isacharequal}\ semigroup\ {\isacharplus}\isanewline
88.358 -\ \ \isakeyword{fixes}\ neutral\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isasymalpha}{\isachardoublequoteclose}\ {\isacharparenleft}{\isachardoublequoteopen}{\isasymone}{\isachardoublequoteclose}{\isacharparenright}\isanewline
88.359 -\ \ \isakeyword{assumes}\ neutl{\isacharcolon}\ {\isachardoublequoteopen}{\isasymone}\ {\isasymotimes}\ x\ {\isacharequal}\ x{\isachardoublequoteclose}%
88.360 -\endisatagquote
88.361 -{\isafoldquote}%
88.362 -%
88.363 -\isadelimquote
88.364 -%
88.365 -\endisadelimquote
88.366 -%
88.367 -\begin{isamarkuptext}%
88.368 -\noindent Again, we prove some instances, by
88.369 - providing suitable parameter definitions and proofs for the
88.370 - additional specifications. Observe that instantiations
88.371 - for types with the same arity may be simultaneous:%
88.372 -\end{isamarkuptext}%
88.373 -\isamarkuptrue%
88.374 -%
88.375 -\isadelimquote
88.376 -%
88.377 -\endisadelimquote
88.378 -%
88.379 -\isatagquote
88.380 -\isacommand{instantiation}\isamarkupfalse%
88.381 -\ nat\ \isakeyword{and}\ int\ {\isacharcolon}{\isacharcolon}\ monoidl\isanewline
88.382 -\isakeyword{begin}\isanewline
88.383 -\isanewline
88.384 -\isacommand{definition}\isamarkupfalse%
88.385 -\isanewline
88.386 -\ \ neutral{\isacharunderscore}nat{\isacharunderscore}def{\isacharcolon}\ {\isachardoublequoteopen}{\isasymone}\ {\isacharequal}\ {\isacharparenleft}{\isadigit{0}}{\isasymColon}nat{\isacharparenright}{\isachardoublequoteclose}\isanewline
88.387 -\isanewline
88.388 -\isacommand{definition}\isamarkupfalse%
88.389 -\isanewline
88.390 -\ \ neutral{\isacharunderscore}int{\isacharunderscore}def{\isacharcolon}\ {\isachardoublequoteopen}{\isasymone}\ {\isacharequal}\ {\isacharparenleft}{\isadigit{0}}{\isasymColon}int{\isacharparenright}{\isachardoublequoteclose}\isanewline
88.391 -\isanewline
88.392 -\isacommand{instance}\isamarkupfalse%
88.393 -\ \isacommand{proof}\isamarkupfalse%
88.394 -\isanewline
88.395 -\ \ \isacommand{fix}\isamarkupfalse%
88.396 -\ n\ {\isacharcolon}{\isacharcolon}\ nat\isanewline
88.397 -\ \ \isacommand{show}\isamarkupfalse%
88.398 -\ {\isachardoublequoteopen}{\isasymone}\ {\isasymotimes}\ n\ {\isacharequal}\ n{\isachardoublequoteclose}\isanewline
88.399 -\ \ \ \ \isacommand{unfolding}\isamarkupfalse%
88.400 -\ neutral{\isacharunderscore}nat{\isacharunderscore}def\ \isacommand{by}\isamarkupfalse%
88.401 -\ simp\isanewline
88.402 -\isacommand{next}\isamarkupfalse%
88.403 -\isanewline
88.404 -\ \ \isacommand{fix}\isamarkupfalse%
88.405 -\ k\ {\isacharcolon}{\isacharcolon}\ int\isanewline
88.406 -\ \ \isacommand{show}\isamarkupfalse%
88.407 -\ {\isachardoublequoteopen}{\isasymone}\ {\isasymotimes}\ k\ {\isacharequal}\ k{\isachardoublequoteclose}\isanewline
88.408 -\ \ \ \ \isacommand{unfolding}\isamarkupfalse%
88.409 -\ neutral{\isacharunderscore}int{\isacharunderscore}def\ mult{\isacharunderscore}int{\isacharunderscore}def\ \isacommand{by}\isamarkupfalse%
88.410 -\ simp\isanewline
88.411 -\isacommand{qed}\isamarkupfalse%
88.412 -\isanewline
88.413 -\isanewline
88.414 -\isacommand{end}\isamarkupfalse%
88.415 -\isanewline
88.416 -\isanewline
88.417 -\isacommand{instantiation}\isamarkupfalse%
88.418 -\ {\isacharasterisk}\ {\isacharcolon}{\isacharcolon}\ {\isacharparenleft}monoidl{\isacharcomma}\ monoidl{\isacharparenright}\ monoidl\isanewline
88.419 -\isakeyword{begin}\isanewline
88.420 -\isanewline
88.421 -\isacommand{definition}\isamarkupfalse%
88.422 -\isanewline
88.423 -\ \ neutral{\isacharunderscore}prod{\isacharunderscore}def{\isacharcolon}\ {\isachardoublequoteopen}{\isasymone}\ {\isacharequal}\ {\isacharparenleft}{\isasymone}{\isacharcomma}\ {\isasymone}{\isacharparenright}{\isachardoublequoteclose}\isanewline
88.424 -\isanewline
88.425 -\isacommand{instance}\isamarkupfalse%
88.426 -\ \isacommand{proof}\isamarkupfalse%
88.427 -\isanewline
88.428 -\ \ \isacommand{fix}\isamarkupfalse%
88.429 -\ p\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isasymalpha}{\isasymColon}monoidl\ {\isasymtimes}\ {\isasymbeta}{\isasymColon}monoidl{\isachardoublequoteclose}\isanewline
88.430 -\ \ \isacommand{show}\isamarkupfalse%
88.431 -\ {\isachardoublequoteopen}{\isasymone}\ {\isasymotimes}\ p\ {\isacharequal}\ p{\isachardoublequoteclose}\isanewline
88.432 -\ \ \ \ \isacommand{unfolding}\isamarkupfalse%
88.433 -\ neutral{\isacharunderscore}prod{\isacharunderscore}def\ mult{\isacharunderscore}prod{\isacharunderscore}def\ \isacommand{by}\isamarkupfalse%
88.434 -\ {\isacharparenleft}simp\ add{\isacharcolon}\ neutl{\isacharparenright}\isanewline
88.435 -\isacommand{qed}\isamarkupfalse%
88.436 -\isanewline
88.437 -\isanewline
88.438 -\isacommand{end}\isamarkupfalse%
88.439 -%
88.440 -\endisatagquote
88.441 -{\isafoldquote}%
88.442 -%
88.443 -\isadelimquote
88.444 -%
88.445 -\endisadelimquote
88.446 -%
88.447 -\begin{isamarkuptext}%
88.448 -\noindent Fully-fledged monoids are modelled by another subclass
88.449 - which does not add new parameters but tightens the specification:%
88.450 -\end{isamarkuptext}%
88.451 -\isamarkuptrue%
88.452 -%
88.453 -\isadelimquote
88.454 -%
88.455 -\endisadelimquote
88.456 -%
88.457 -\isatagquote
88.458 -\isacommand{class}\isamarkupfalse%
88.459 -\ monoid\ {\isacharequal}\ monoidl\ {\isacharplus}\isanewline
88.460 -\ \ \isakeyword{assumes}\ neutr{\isacharcolon}\ {\isachardoublequoteopen}x\ {\isasymotimes}\ {\isasymone}\ {\isacharequal}\ x{\isachardoublequoteclose}\isanewline
88.461 -\isanewline
88.462 -\isacommand{instantiation}\isamarkupfalse%
88.463 -\ nat\ \isakeyword{and}\ int\ {\isacharcolon}{\isacharcolon}\ monoid\ \isanewline
88.464 -\isakeyword{begin}\isanewline
88.465 -\isanewline
88.466 -\isacommand{instance}\isamarkupfalse%
88.467 -\ \isacommand{proof}\isamarkupfalse%
88.468 -\isanewline
88.469 -\ \ \isacommand{fix}\isamarkupfalse%
88.470 -\ n\ {\isacharcolon}{\isacharcolon}\ nat\isanewline
88.471 -\ \ \isacommand{show}\isamarkupfalse%
88.472 -\ {\isachardoublequoteopen}n\ {\isasymotimes}\ {\isasymone}\ {\isacharequal}\ n{\isachardoublequoteclose}\isanewline
88.473 -\ \ \ \ \isacommand{unfolding}\isamarkupfalse%
88.474 -\ neutral{\isacharunderscore}nat{\isacharunderscore}def\ \isacommand{by}\isamarkupfalse%
88.475 -\ {\isacharparenleft}induct\ n{\isacharparenright}\ simp{\isacharunderscore}all\isanewline
88.476 -\isacommand{next}\isamarkupfalse%
88.477 -\isanewline
88.478 -\ \ \isacommand{fix}\isamarkupfalse%
88.479 -\ k\ {\isacharcolon}{\isacharcolon}\ int\isanewline
88.480 -\ \ \isacommand{show}\isamarkupfalse%
88.481 -\ {\isachardoublequoteopen}k\ {\isasymotimes}\ {\isasymone}\ {\isacharequal}\ k{\isachardoublequoteclose}\isanewline
88.482 -\ \ \ \ \isacommand{unfolding}\isamarkupfalse%
88.483 -\ neutral{\isacharunderscore}int{\isacharunderscore}def\ mult{\isacharunderscore}int{\isacharunderscore}def\ \isacommand{by}\isamarkupfalse%
88.484 -\ simp\isanewline
88.485 -\isacommand{qed}\isamarkupfalse%
88.486 -\isanewline
88.487 -\isanewline
88.488 -\isacommand{end}\isamarkupfalse%
88.489 -\isanewline
88.490 -\isanewline
88.491 -\isacommand{instantiation}\isamarkupfalse%
88.492 -\ {\isacharasterisk}\ {\isacharcolon}{\isacharcolon}\ {\isacharparenleft}monoid{\isacharcomma}\ monoid{\isacharparenright}\ monoid\isanewline
88.493 -\isakeyword{begin}\isanewline
88.494 -\isanewline
88.495 -\isacommand{instance}\isamarkupfalse%
88.496 -\ \isacommand{proof}\isamarkupfalse%
88.497 -\ \isanewline
88.498 -\ \ \isacommand{fix}\isamarkupfalse%
88.499 -\ p\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isasymalpha}{\isasymColon}monoid\ {\isasymtimes}\ {\isasymbeta}{\isasymColon}monoid{\isachardoublequoteclose}\isanewline
88.500 -\ \ \isacommand{show}\isamarkupfalse%
88.501 -\ {\isachardoublequoteopen}p\ {\isasymotimes}\ {\isasymone}\ {\isacharequal}\ p{\isachardoublequoteclose}\isanewline
88.502 -\ \ \ \ \isacommand{unfolding}\isamarkupfalse%
88.503 -\ neutral{\isacharunderscore}prod{\isacharunderscore}def\ mult{\isacharunderscore}prod{\isacharunderscore}def\ \isacommand{by}\isamarkupfalse%
88.504 -\ {\isacharparenleft}simp\ add{\isacharcolon}\ neutr{\isacharparenright}\isanewline
88.505 -\isacommand{qed}\isamarkupfalse%
88.506 -\isanewline
88.507 -\isanewline
88.508 -\isacommand{end}\isamarkupfalse%
88.509 -%
88.510 -\endisatagquote
88.511 -{\isafoldquote}%
88.512 -%
88.513 -\isadelimquote
88.514 -%
88.515 -\endisadelimquote
88.516 -%
88.517 -\begin{isamarkuptext}%
88.518 -\noindent To finish our small algebra example, we add a \isa{group} class
88.519 - with a corresponding instance:%
88.520 -\end{isamarkuptext}%
88.521 -\isamarkuptrue%
88.522 -%
88.523 -\isadelimquote
88.524 -%
88.525 -\endisadelimquote
88.526 -%
88.527 -\isatagquote
88.528 -\isacommand{class}\isamarkupfalse%
88.529 -\ group\ {\isacharequal}\ monoidl\ {\isacharplus}\isanewline
88.530 -\ \ \isakeyword{fixes}\ inverse\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isasymalpha}\ {\isasymRightarrow}\ {\isasymalpha}{\isachardoublequoteclose}\ \ \ \ {\isacharparenleft}{\isachardoublequoteopen}{\isacharparenleft}{\isacharunderscore}{\isasymdiv}{\isacharparenright}{\isachardoublequoteclose}\ {\isacharbrackleft}{\isadigit{1}}{\isadigit{0}}{\isadigit{0}}{\isadigit{0}}{\isacharbrackright}\ {\isadigit{9}}{\isadigit{9}}{\isadigit{9}}{\isacharparenright}\isanewline
88.531 -\ \ \isakeyword{assumes}\ invl{\isacharcolon}\ {\isachardoublequoteopen}x{\isasymdiv}\ {\isasymotimes}\ x\ {\isacharequal}\ {\isasymone}{\isachardoublequoteclose}\isanewline
88.532 -\isanewline
88.533 -\isacommand{instantiation}\isamarkupfalse%
88.534 -\ int\ {\isacharcolon}{\isacharcolon}\ group\isanewline
88.535 -\isakeyword{begin}\isanewline
88.536 -\isanewline
88.537 -\isacommand{definition}\isamarkupfalse%
88.538 -\isanewline
88.539 -\ \ inverse{\isacharunderscore}int{\isacharunderscore}def{\isacharcolon}\ {\isachardoublequoteopen}i{\isasymdiv}\ {\isacharequal}\ {\isacharminus}\ {\isacharparenleft}i{\isasymColon}int{\isacharparenright}{\isachardoublequoteclose}\isanewline
88.540 -\isanewline
88.541 -\isacommand{instance}\isamarkupfalse%
88.542 -\ \isacommand{proof}\isamarkupfalse%
88.543 -\isanewline
88.544 -\ \ \isacommand{fix}\isamarkupfalse%
88.545 -\ i\ {\isacharcolon}{\isacharcolon}\ int\isanewline
88.546 -\ \ \isacommand{have}\isamarkupfalse%
88.547 -\ {\isachardoublequoteopen}{\isacharminus}i\ {\isacharplus}\ i\ {\isacharequal}\ {\isadigit{0}}{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse%
88.548 -\ simp\isanewline
88.549 -\ \ \isacommand{then}\isamarkupfalse%
88.550 -\ \isacommand{show}\isamarkupfalse%
88.551 -\ {\isachardoublequoteopen}i{\isasymdiv}\ {\isasymotimes}\ i\ {\isacharequal}\ {\isasymone}{\isachardoublequoteclose}\isanewline
88.552 -\ \ \ \ \isacommand{unfolding}\isamarkupfalse%
88.553 -\ mult{\isacharunderscore}int{\isacharunderscore}def\ neutral{\isacharunderscore}int{\isacharunderscore}def\ inverse{\isacharunderscore}int{\isacharunderscore}def\ \isacommand{{\isachardot}}\isamarkupfalse%
88.554 -\isanewline
88.555 -\isacommand{qed}\isamarkupfalse%
88.556 -\isanewline
88.557 -\isanewline
88.558 -\isacommand{end}\isamarkupfalse%
88.559 -%
88.560 -\endisatagquote
88.561 -{\isafoldquote}%
88.562 -%
88.563 -\isadelimquote
88.564 -%
88.565 -\endisadelimquote
88.566 -%
88.567 -\isamarkupsection{Type classes as locales%
88.568 -}
88.569 -\isamarkuptrue%
88.570 -%
88.571 -\isamarkupsubsection{A look behind the scene%
88.572 -}
88.573 -\isamarkuptrue%
88.574 -%
88.575 -\begin{isamarkuptext}%
88.576 -The example above gives an impression how Isar type classes work
88.577 - in practice. As stated in the introduction, classes also provide
88.578 - a link to Isar's locale system. Indeed, the logical core of a class
88.579 - is nothing else than a locale:%
88.580 -\end{isamarkuptext}%
88.581 -\isamarkuptrue%
88.582 -%
88.583 -\isadelimquote
88.584 -%
88.585 -\endisadelimquote
88.586 -%
88.587 -\isatagquote
88.588 -\isacommand{class}\isamarkupfalse%
88.589 -\ idem\ {\isacharequal}\isanewline
88.590 -\ \ \isakeyword{fixes}\ f\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isasymalpha}\ {\isasymRightarrow}\ {\isasymalpha}{\isachardoublequoteclose}\isanewline
88.591 -\ \ \isakeyword{assumes}\ idem{\isacharcolon}\ {\isachardoublequoteopen}f\ {\isacharparenleft}f\ x{\isacharparenright}\ {\isacharequal}\ f\ x{\isachardoublequoteclose}%
88.592 -\endisatagquote
88.593 -{\isafoldquote}%
88.594 -%
88.595 -\isadelimquote
88.596 -%
88.597 -\endisadelimquote
88.598 -%
88.599 -\begin{isamarkuptext}%
88.600 -\noindent essentially introduces the locale%
88.601 -\end{isamarkuptext}%
88.602 -\isamarkuptrue%
88.603 -%
88.604 -\isadeliminvisible
88.605 -\ %
88.606 -\endisadeliminvisible
88.607 -%
88.608 -\isataginvisible
88.609 -\isacommand{setup}\isamarkupfalse%
88.610 -\ {\isacharverbatimopen}\ Sign{\isachardot}add{\isacharunderscore}path\ {\isachardoublequote}foo{\isachardoublequote}\ {\isacharverbatimclose}%
88.611 -\endisataginvisible
88.612 -{\isafoldinvisible}%
88.613 -%
88.614 -\isadeliminvisible
88.615 -%
88.616 -\endisadeliminvisible
88.617 -\isanewline
88.618 -%
88.619 -\isadelimquote
88.620 -\isanewline
88.621 -%
88.622 -\endisadelimquote
88.623 -%
88.624 -\isatagquote
88.625 -\isacommand{locale}\isamarkupfalse%
88.626 -\ idem\ {\isacharequal}\isanewline
88.627 -\ \ \isakeyword{fixes}\ f\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isasymalpha}\ {\isasymRightarrow}\ {\isasymalpha}{\isachardoublequoteclose}\isanewline
88.628 -\ \ \isakeyword{assumes}\ idem{\isacharcolon}\ {\isachardoublequoteopen}f\ {\isacharparenleft}f\ x{\isacharparenright}\ {\isacharequal}\ f\ x{\isachardoublequoteclose}%
88.629 -\endisatagquote
88.630 -{\isafoldquote}%
88.631 -%
88.632 -\isadelimquote
88.633 -%
88.634 -\endisadelimquote
88.635 -%
88.636 -\begin{isamarkuptext}%
88.637 -\noindent together with corresponding constant(s):%
88.638 -\end{isamarkuptext}%
88.639 -\isamarkuptrue%
88.640 -%
88.641 -\isadelimquote
88.642 -%
88.643 -\endisadelimquote
88.644 -%
88.645 -\isatagquote
88.646 -\isacommand{consts}\isamarkupfalse%
88.647 -\ f\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isasymalpha}\ {\isasymRightarrow}\ {\isasymalpha}{\isachardoublequoteclose}%
88.648 -\endisatagquote
88.649 -{\isafoldquote}%
88.650 -%
88.651 -\isadelimquote
88.652 -%
88.653 -\endisadelimquote
88.654 -%
88.655 -\begin{isamarkuptext}%
88.656 -\noindent The connection to the type system is done by means
88.657 - of a primitive axclass%
88.658 -\end{isamarkuptext}%
88.659 -\isamarkuptrue%
88.660 -%
88.661 -\isadeliminvisible
88.662 -\ %
88.663 -\endisadeliminvisible
88.664 -%
88.665 -\isataginvisible
88.666 -\isacommand{setup}\isamarkupfalse%
88.667 -\ {\isacharverbatimopen}\ Sign{\isachardot}add{\isacharunderscore}path\ {\isachardoublequote}foo{\isachardoublequote}\ {\isacharverbatimclose}%
88.668 -\endisataginvisible
88.669 -{\isafoldinvisible}%
88.670 -%
88.671 -\isadeliminvisible
88.672 -%
88.673 -\endisadeliminvisible
88.674 -\isanewline
88.675 -%
88.676 -\isadelimquote
88.677 -\isanewline
88.678 -%
88.679 -\endisadelimquote
88.680 -%
88.681 -\isatagquote
88.682 -\isacommand{axclass}\isamarkupfalse%
88.683 -\ idem\ {\isacharless}\ type\isanewline
88.684 -\ \ idem{\isacharcolon}\ {\isachardoublequoteopen}f\ {\isacharparenleft}f\ x{\isacharparenright}\ {\isacharequal}\ f\ x{\isachardoublequoteclose}%
88.685 -\endisatagquote
88.686 -{\isafoldquote}%
88.687 -%
88.688 -\isadelimquote
88.689 -%
88.690 -\endisadelimquote
88.691 -%
88.692 -\isadeliminvisible
88.693 -\ %
88.694 -\endisadeliminvisible
88.695 -%
88.696 -\isataginvisible
88.697 -\isacommand{setup}\isamarkupfalse%
88.698 -\ {\isacharverbatimopen}\ Sign{\isachardot}parent{\isacharunderscore}path\ {\isacharverbatimclose}%
88.699 -\endisataginvisible
88.700 -{\isafoldinvisible}%
88.701 -%
88.702 -\isadeliminvisible
88.703 -%
88.704 -\endisadeliminvisible
88.705 -%
88.706 -\begin{isamarkuptext}%
88.707 -\noindent together with a corresponding interpretation:%
88.708 -\end{isamarkuptext}%
88.709 -\isamarkuptrue%
88.710 -%
88.711 -\isadelimquote
88.712 -%
88.713 -\endisadelimquote
88.714 -%
88.715 -\isatagquote
88.716 -\isacommand{interpretation}\isamarkupfalse%
88.717 -\ idem{\isacharunderscore}class{\isacharcolon}\isanewline
88.718 -\ \ idem\ {\isachardoublequoteopen}f\ {\isasymColon}\ {\isacharparenleft}{\isasymalpha}{\isasymColon}idem{\isacharparenright}\ {\isasymRightarrow}\ {\isasymalpha}{\isachardoublequoteclose}\isanewline
88.719 -\isacommand{proof}\isamarkupfalse%
88.720 -\ \isacommand{qed}\isamarkupfalse%
88.721 -\ {\isacharparenleft}rule\ idem{\isacharparenright}%
88.722 -\endisatagquote
88.723 -{\isafoldquote}%
88.724 -%
88.725 -\isadelimquote
88.726 -%
88.727 -\endisadelimquote
88.728 -%
88.729 -\begin{isamarkuptext}%
88.730 -\noindent This gives you at hand the full power of the Isabelle module system;
88.731 - conclusions in locale \isa{idem} are implicitly propagated
88.732 - to class \isa{idem}.%
88.733 -\end{isamarkuptext}%
88.734 -\isamarkuptrue%
88.735 -%
88.736 -\isadeliminvisible
88.737 -\ %
88.738 -\endisadeliminvisible
88.739 -%
88.740 -\isataginvisible
88.741 -\isacommand{setup}\isamarkupfalse%
88.742 -\ {\isacharverbatimopen}\ Sign{\isachardot}parent{\isacharunderscore}path\ {\isacharverbatimclose}%
88.743 -\endisataginvisible
88.744 -{\isafoldinvisible}%
88.745 -%
88.746 -\isadeliminvisible
88.747 -%
88.748 -\endisadeliminvisible
88.749 -%
88.750 -\isamarkupsubsection{Abstract reasoning%
88.751 -}
88.752 -\isamarkuptrue%
88.753 -%
88.754 -\begin{isamarkuptext}%
88.755 -Isabelle locales enable reasoning at a general level, while results
88.756 - are implicitly transferred to all instances. For example, we can
88.757 - now establish the \isa{left{\isacharunderscore}cancel} lemma for groups, which
88.758 - states that the function \isa{{\isacharparenleft}x\ {\isasymotimes}{\isacharparenright}} is injective:%
88.759 -\end{isamarkuptext}%
88.760 -\isamarkuptrue%
88.761 -%
88.762 -\isadelimquote
88.763 -%
88.764 -\endisadelimquote
88.765 -%
88.766 -\isatagquote
88.767 -\isacommand{lemma}\isamarkupfalse%
88.768 -\ {\isacharparenleft}\isakeyword{in}\ group{\isacharparenright}\ left{\isacharunderscore}cancel{\isacharcolon}\ {\isachardoublequoteopen}x\ {\isasymotimes}\ y\ {\isacharequal}\ x\ {\isasymotimes}\ z\ {\isasymlongleftrightarrow}\ y\ {\isacharequal}\ z{\isachardoublequoteclose}\isanewline
88.769 -\isacommand{proof}\isamarkupfalse%
88.770 -\isanewline
88.771 -\ \ \isacommand{assume}\isamarkupfalse%
88.772 -\ {\isachardoublequoteopen}x\ {\isasymotimes}\ y\ {\isacharequal}\ x\ {\isasymotimes}\ z{\isachardoublequoteclose}\isanewline
88.773 -\ \ \isacommand{then}\isamarkupfalse%
88.774 -\ \isacommand{have}\isamarkupfalse%
88.775 -\ {\isachardoublequoteopen}x{\isasymdiv}\ {\isasymotimes}\ {\isacharparenleft}x\ {\isasymotimes}\ y{\isacharparenright}\ {\isacharequal}\ x{\isasymdiv}\ {\isasymotimes}\ {\isacharparenleft}x\ {\isasymotimes}\ z{\isacharparenright}{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse%
88.776 -\ simp\isanewline
88.777 -\ \ \isacommand{then}\isamarkupfalse%
88.778 -\ \isacommand{have}\isamarkupfalse%
88.779 -\ {\isachardoublequoteopen}{\isacharparenleft}x{\isasymdiv}\ {\isasymotimes}\ x{\isacharparenright}\ {\isasymotimes}\ y\ {\isacharequal}\ {\isacharparenleft}x{\isasymdiv}\ {\isasymotimes}\ x{\isacharparenright}\ {\isasymotimes}\ z{\isachardoublequoteclose}\ \isacommand{using}\isamarkupfalse%
88.780 -\ assoc\ \isacommand{by}\isamarkupfalse%
88.781 -\ simp\isanewline
88.782 -\ \ \isacommand{then}\isamarkupfalse%
88.783 -\ \isacommand{show}\isamarkupfalse%
88.784 -\ {\isachardoublequoteopen}y\ {\isacharequal}\ z{\isachardoublequoteclose}\ \isacommand{using}\isamarkupfalse%
88.785 -\ neutl\ \isakeyword{and}\ invl\ \isacommand{by}\isamarkupfalse%
88.786 -\ simp\isanewline
88.787 -\isacommand{next}\isamarkupfalse%
88.788 -\isanewline
88.789 -\ \ \isacommand{assume}\isamarkupfalse%
88.790 -\ {\isachardoublequoteopen}y\ {\isacharequal}\ z{\isachardoublequoteclose}\isanewline
88.791 -\ \ \isacommand{then}\isamarkupfalse%
88.792 -\ \isacommand{show}\isamarkupfalse%
88.793 -\ {\isachardoublequoteopen}x\ {\isasymotimes}\ y\ {\isacharequal}\ x\ {\isasymotimes}\ z{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse%
88.794 -\ simp\isanewline
88.795 -\isacommand{qed}\isamarkupfalse%
88.796 -%
88.797 -\endisatagquote
88.798 -{\isafoldquote}%
88.799 -%
88.800 -\isadelimquote
88.801 -%
88.802 -\endisadelimquote
88.803 -%
88.804 -\begin{isamarkuptext}%
88.805 -\noindent Here the \qt{\hyperlink{keyword.in}{\mbox{\isa{\isakeyword{in}}}} \isa{group}} target specification
88.806 - indicates that the result is recorded within that context for later
88.807 - use. This local theorem is also lifted to the global one \hyperlink{fact.group.left-cancel:}{\mbox{\isa{group{\isachardot}left{\isacharunderscore}cancel{\isacharcolon}}}} \isa{{\isachardoublequote}{\isasymAnd}x\ y\ z\ {\isasymColon}\ {\isasymalpha}{\isasymColon}group{\isachardot}\ x\ {\isasymotimes}\ y\ {\isacharequal}\ x\ {\isasymotimes}\ z\ {\isasymlongleftrightarrow}\ y\ {\isacharequal}\ z{\isachardoublequote}}. Since type \isa{int} has been made an instance of
88.808 - \isa{group} before, we may refer to that fact as well: \isa{{\isachardoublequote}{\isasymAnd}x\ y\ z\ {\isasymColon}\ int{\isachardot}\ x\ {\isasymotimes}\ y\ {\isacharequal}\ x\ {\isasymotimes}\ z\ {\isasymlongleftrightarrow}\ y\ {\isacharequal}\ z{\isachardoublequote}}.%
88.809 -\end{isamarkuptext}%
88.810 -\isamarkuptrue%
88.811 -%
88.812 -\isamarkupsubsection{Derived definitions%
88.813 -}
88.814 -\isamarkuptrue%
88.815 -%
88.816 -\begin{isamarkuptext}%
88.817 -Isabelle locales support a concept of local definitions
88.818 - in locales:%
88.819 -\end{isamarkuptext}%
88.820 -\isamarkuptrue%
88.821 -%
88.822 -\isadelimquote
88.823 -%
88.824 -\endisadelimquote
88.825 -%
88.826 -\isatagquote
88.827 -\isacommand{primrec}\isamarkupfalse%
88.828 -\ {\isacharparenleft}\isakeyword{in}\ monoid{\isacharparenright}\ pow{\isacharunderscore}nat\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymRightarrow}\ {\isasymalpha}\ {\isasymRightarrow}\ {\isasymalpha}{\isachardoublequoteclose}\ \isakeyword{where}\isanewline
88.829 -\ \ {\isachardoublequoteopen}pow{\isacharunderscore}nat\ {\isadigit{0}}\ x\ {\isacharequal}\ {\isasymone}{\isachardoublequoteclose}\isanewline
88.830 -\ \ {\isacharbar}\ {\isachardoublequoteopen}pow{\isacharunderscore}nat\ {\isacharparenleft}Suc\ n{\isacharparenright}\ x\ {\isacharequal}\ x\ {\isasymotimes}\ pow{\isacharunderscore}nat\ n\ x{\isachardoublequoteclose}%
88.831 -\endisatagquote
88.832 -{\isafoldquote}%
88.833 -%
88.834 -\isadelimquote
88.835 -%
88.836 -\endisadelimquote
88.837 -%
88.838 -\begin{isamarkuptext}%
88.839 -\noindent If the locale \isa{group} is also a class, this local
88.840 - definition is propagated onto a global definition of
88.841 - \isa{{\isachardoublequote}pow{\isacharunderscore}nat\ {\isasymColon}\ nat\ {\isasymRightarrow}\ {\isasymalpha}{\isasymColon}monoid\ {\isasymRightarrow}\ {\isasymalpha}{\isasymColon}monoid{\isachardoublequote}}
88.842 - with corresponding theorems
88.843 -
88.844 - \isa{pow{\isacharunderscore}nat\ {\isadigit{0}}\ x\ {\isacharequal}\ {\isasymone}\isasep\isanewline%
88.845 -pow{\isacharunderscore}nat\ {\isacharparenleft}Suc\ n{\isacharparenright}\ x\ {\isacharequal}\ x\ {\isasymotimes}\ pow{\isacharunderscore}nat\ n\ x}.
88.846 -
88.847 - \noindent As you can see from this example, for local
88.848 - definitions you may use any specification tool
88.849 - which works together with locales (e.g. \cite{krauss2006}).%
88.850 -\end{isamarkuptext}%
88.851 -\isamarkuptrue%
88.852 -%
88.853 -\isamarkupsubsection{A functor analogy%
88.854 -}
88.855 -\isamarkuptrue%
88.856 -%
88.857 -\begin{isamarkuptext}%
88.858 -We introduced Isar classes by analogy to type classes
88.859 - functional programming; if we reconsider this in the
88.860 - context of what has been said about type classes and locales,
88.861 - we can drive this analogy further by stating that type
88.862 - classes essentially correspond to functors which have
88.863 - a canonical interpretation as type classes.
88.864 - Anyway, there is also the possibility of other interpretations.
88.865 - For example, also \isa{list}s form a monoid with
88.866 - \isa{append} and \isa{{\isacharbrackleft}{\isacharbrackright}} as operations, but it
88.867 - seems inappropriate to apply to lists
88.868 - the same operations as for genuinely algebraic types.
88.869 - In such a case, we simply can do a particular interpretation
88.870 - of monoids for lists:%
88.871 -\end{isamarkuptext}%
88.872 -\isamarkuptrue%
88.873 -%
88.874 -\isadelimquote
88.875 -%
88.876 -\endisadelimquote
88.877 -%
88.878 -\isatagquote
88.879 -\isacommand{interpretation}\isamarkupfalse%
88.880 -\ list{\isacharunderscore}monoid{\isacharbang}{\isacharcolon}\ monoid\ append\ {\isachardoublequoteopen}{\isacharbrackleft}{\isacharbrackright}{\isachardoublequoteclose}\isanewline
88.881 -\ \ \isacommand{proof}\isamarkupfalse%
88.882 -\ \isacommand{qed}\isamarkupfalse%
88.883 -\ auto%
88.884 -\endisatagquote
88.885 -{\isafoldquote}%
88.886 -%
88.887 -\isadelimquote
88.888 -%
88.889 -\endisadelimquote
88.890 -%
88.891 -\begin{isamarkuptext}%
88.892 -\noindent This enables us to apply facts on monoids
88.893 - to lists, e.g. \isa{{\isacharbrackleft}{\isacharbrackright}\ {\isacharat}\ x\ {\isacharequal}\ x}.
88.894 -
88.895 - When using this interpretation pattern, it may also
88.896 - be appropriate to map derived definitions accordingly:%
88.897 -\end{isamarkuptext}%
88.898 -\isamarkuptrue%
88.899 -%
88.900 -\isadelimquote
88.901 -%
88.902 -\endisadelimquote
88.903 -%
88.904 -\isatagquote
88.905 -\isacommand{primrec}\isamarkupfalse%
88.906 -\ replicate\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymRightarrow}\ {\isasymalpha}\ list\ {\isasymRightarrow}\ {\isasymalpha}\ list{\isachardoublequoteclose}\ \isakeyword{where}\isanewline
88.907 -\ \ {\isachardoublequoteopen}replicate\ {\isadigit{0}}\ {\isacharunderscore}\ {\isacharequal}\ {\isacharbrackleft}{\isacharbrackright}{\isachardoublequoteclose}\isanewline
88.908 -\ \ {\isacharbar}\ {\isachardoublequoteopen}replicate\ {\isacharparenleft}Suc\ n{\isacharparenright}\ xs\ {\isacharequal}\ xs\ {\isacharat}\ replicate\ n\ xs{\isachardoublequoteclose}\isanewline
88.909 -\isanewline
88.910 -\isacommand{interpretation}\isamarkupfalse%
88.911 -\ list{\isacharunderscore}monoid{\isacharbang}{\isacharcolon}\ monoid\ append\ {\isachardoublequoteopen}{\isacharbrackleft}{\isacharbrackright}{\isachardoublequoteclose}\ \isakeyword{where}\isanewline
88.912 -\ \ {\isachardoublequoteopen}monoid{\isachardot}pow{\isacharunderscore}nat\ append\ {\isacharbrackleft}{\isacharbrackright}\ {\isacharequal}\ replicate{\isachardoublequoteclose}\isanewline
88.913 -\isacommand{proof}\isamarkupfalse%
88.914 -\ {\isacharminus}\isanewline
88.915 -\ \ \isacommand{interpret}\isamarkupfalse%
88.916 -\ monoid\ append\ {\isachardoublequoteopen}{\isacharbrackleft}{\isacharbrackright}{\isachardoublequoteclose}\ \isacommand{{\isachardot}{\isachardot}}\isamarkupfalse%
88.917 -\isanewline
88.918 -\ \ \isacommand{show}\isamarkupfalse%
88.919 -\ {\isachardoublequoteopen}monoid{\isachardot}pow{\isacharunderscore}nat\ append\ {\isacharbrackleft}{\isacharbrackright}\ {\isacharequal}\ replicate{\isachardoublequoteclose}\isanewline
88.920 -\ \ \isacommand{proof}\isamarkupfalse%
88.921 -\isanewline
88.922 -\ \ \ \ \isacommand{fix}\isamarkupfalse%
88.923 -\ n\isanewline
88.924 -\ \ \ \ \isacommand{show}\isamarkupfalse%
88.925 -\ {\isachardoublequoteopen}monoid{\isachardot}pow{\isacharunderscore}nat\ append\ {\isacharbrackleft}{\isacharbrackright}\ n\ {\isacharequal}\ replicate\ n{\isachardoublequoteclose}\isanewline
88.926 -\ \ \ \ \ \ \isacommand{by}\isamarkupfalse%
88.927 -\ {\isacharparenleft}induct\ n{\isacharparenright}\ auto\isanewline
88.928 -\ \ \isacommand{qed}\isamarkupfalse%
88.929 -\isanewline
88.930 -\isacommand{qed}\isamarkupfalse%
88.931 -\ intro{\isacharunderscore}locales%
88.932 -\endisatagquote
88.933 -{\isafoldquote}%
88.934 -%
88.935 -\isadelimquote
88.936 -%
88.937 -\endisadelimquote
88.938 -%
88.939 -\isamarkupsubsection{Additional subclass relations%
88.940 -}
88.941 -\isamarkuptrue%
88.942 -%
88.943 -\begin{isamarkuptext}%
88.944 -Any \isa{group} is also a \isa{monoid}; this
88.945 - can be made explicit by claiming an additional
88.946 - subclass relation,
88.947 - together with a proof of the logical difference:%
88.948 -\end{isamarkuptext}%
88.949 -\isamarkuptrue%
88.950 -%
88.951 -\isadelimquote
88.952 -%
88.953 -\endisadelimquote
88.954 -%
88.955 -\isatagquote
88.956 -\isacommand{subclass}\isamarkupfalse%
88.957 -\ {\isacharparenleft}\isakeyword{in}\ group{\isacharparenright}\ monoid\isanewline
88.958 -\isacommand{proof}\isamarkupfalse%
88.959 -\isanewline
88.960 -\ \ \isacommand{fix}\isamarkupfalse%
88.961 -\ x\isanewline
88.962 -\ \ \isacommand{from}\isamarkupfalse%
88.963 -\ invl\ \isacommand{have}\isamarkupfalse%
88.964 -\ {\isachardoublequoteopen}x{\isasymdiv}\ {\isasymotimes}\ x\ {\isacharequal}\ {\isasymone}{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse%
88.965 -\ simp\isanewline
88.966 -\ \ \isacommand{with}\isamarkupfalse%
88.967 -\ assoc\ {\isacharbrackleft}symmetric{\isacharbrackright}\ neutl\ invl\ \isacommand{have}\isamarkupfalse%
88.968 -\ {\isachardoublequoteopen}x{\isasymdiv}\ {\isasymotimes}\ {\isacharparenleft}x\ {\isasymotimes}\ {\isasymone}{\isacharparenright}\ {\isacharequal}\ x{\isasymdiv}\ {\isasymotimes}\ x{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse%
88.969 -\ simp\isanewline
88.970 -\ \ \isacommand{with}\isamarkupfalse%
88.971 -\ left{\isacharunderscore}cancel\ \isacommand{show}\isamarkupfalse%
88.972 -\ {\isachardoublequoteopen}x\ {\isasymotimes}\ {\isasymone}\ {\isacharequal}\ x{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse%
88.973 -\ simp\isanewline
88.974 -\isacommand{qed}\isamarkupfalse%
88.975 -%
88.976 -\endisatagquote
88.977 -{\isafoldquote}%
88.978 -%
88.979 -\isadelimquote
88.980 -%
88.981 -\endisadelimquote
88.982 -%
88.983 -\begin{isamarkuptext}%
88.984 -\noindent The logical proof is carried out on the locale level.
88.985 - Afterwards it is propagated
88.986 - to the type system, making \isa{group} an instance of
88.987 - \isa{monoid} by adding an additional edge
88.988 - to the graph of subclass relations
88.989 - (cf.\ \figref{fig:subclass}).
88.990 -
88.991 - \begin{figure}[htbp]
88.992 - \begin{center}
88.993 - \small
88.994 - \unitlength 0.6mm
88.995 - \begin{picture}(40,60)(0,0)
88.996 - \put(20,60){\makebox(0,0){\isa{semigroup}}}
88.997 - \put(20,40){\makebox(0,0){\isa{monoidl}}}
88.998 - \put(00,20){\makebox(0,0){\isa{monoid}}}
88.999 - \put(40,00){\makebox(0,0){\isa{group}}}
88.1000 - \put(20,55){\vector(0,-1){10}}
88.1001 - \put(15,35){\vector(-1,-1){10}}
88.1002 - \put(25,35){\vector(1,-3){10}}
88.1003 - \end{picture}
88.1004 - \hspace{8em}
88.1005 - \begin{picture}(40,60)(0,0)
88.1006 - \put(20,60){\makebox(0,0){\isa{semigroup}}}
88.1007 - \put(20,40){\makebox(0,0){\isa{monoidl}}}
88.1008 - \put(00,20){\makebox(0,0){\isa{monoid}}}
88.1009 - \put(40,00){\makebox(0,0){\isa{group}}}
88.1010 - \put(20,55){\vector(0,-1){10}}
88.1011 - \put(15,35){\vector(-1,-1){10}}
88.1012 - \put(05,15){\vector(3,-1){30}}
88.1013 - \end{picture}
88.1014 - \caption{Subclass relationship of monoids and groups:
88.1015 - before and after establishing the relationship
88.1016 - \isa{group\ {\isasymsubseteq}\ monoid}; transitive edges left out.}
88.1017 - \label{fig:subclass}
88.1018 - \end{center}
88.1019 - \end{figure}
88.1020 -7
88.1021 - For illustration, a derived definition
88.1022 - in \isa{group} which uses \isa{pow{\isacharunderscore}nat}:%
88.1023 -\end{isamarkuptext}%
88.1024 -\isamarkuptrue%
88.1025 -%
88.1026 -\isadelimquote
88.1027 -%
88.1028 -\endisadelimquote
88.1029 -%
88.1030 -\isatagquote
88.1031 -\isacommand{definition}\isamarkupfalse%
88.1032 -\ {\isacharparenleft}\isakeyword{in}\ group{\isacharparenright}\ pow{\isacharunderscore}int\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}int\ {\isasymRightarrow}\ {\isasymalpha}\ {\isasymRightarrow}\ {\isasymalpha}{\isachardoublequoteclose}\ \isakeyword{where}\isanewline
88.1033 -\ \ {\isachardoublequoteopen}pow{\isacharunderscore}int\ k\ x\ {\isacharequal}\ {\isacharparenleft}if\ k\ {\isachargreater}{\isacharequal}\ {\isadigit{0}}\isanewline
88.1034 -\ \ \ \ then\ pow{\isacharunderscore}nat\ {\isacharparenleft}nat\ k{\isacharparenright}\ x\isanewline
88.1035 -\ \ \ \ else\ {\isacharparenleft}pow{\isacharunderscore}nat\ {\isacharparenleft}nat\ {\isacharparenleft}{\isacharminus}\ k{\isacharparenright}{\isacharparenright}\ x{\isacharparenright}{\isasymdiv}{\isacharparenright}{\isachardoublequoteclose}%
88.1036 -\endisatagquote
88.1037 -{\isafoldquote}%
88.1038 -%
88.1039 -\isadelimquote
88.1040 -%
88.1041 -\endisadelimquote
88.1042 -%
88.1043 -\begin{isamarkuptext}%
88.1044 -\noindent yields the global definition of
88.1045 - \isa{{\isachardoublequote}pow{\isacharunderscore}int\ {\isasymColon}\ int\ {\isasymRightarrow}\ {\isasymalpha}{\isasymColon}group\ {\isasymRightarrow}\ {\isasymalpha}{\isasymColon}group{\isachardoublequote}}
88.1046 - with the corresponding theorem \isa{pow{\isacharunderscore}int\ k\ x\ {\isacharequal}\ {\isacharparenleft}if\ {\isadigit{0}}\ {\isasymle}\ k\ then\ pow{\isacharunderscore}nat\ {\isacharparenleft}nat\ k{\isacharparenright}\ x\ else\ {\isacharparenleft}pow{\isacharunderscore}nat\ {\isacharparenleft}nat\ {\isacharparenleft}{\isacharminus}\ k{\isacharparenright}{\isacharparenright}\ x{\isacharparenright}{\isasymdiv}{\isacharparenright}}.%
88.1047 -\end{isamarkuptext}%
88.1048 -\isamarkuptrue%
88.1049 -%
88.1050 -\isamarkupsubsection{A note on syntax%
88.1051 -}
88.1052 -\isamarkuptrue%
88.1053 -%
88.1054 -\begin{isamarkuptext}%
88.1055 -As a commodity, class context syntax allows to refer
88.1056 - to local class operations and their global counterparts
88.1057 - uniformly; type inference resolves ambiguities. For example:%
88.1058 -\end{isamarkuptext}%
88.1059 -\isamarkuptrue%
88.1060 -%
88.1061 -\isadelimquote
88.1062 -%
88.1063 -\endisadelimquote
88.1064 -%
88.1065 -\isatagquote
88.1066 -\isacommand{context}\isamarkupfalse%
88.1067 -\ semigroup\isanewline
88.1068 -\isakeyword{begin}\isanewline
88.1069 -\isanewline
88.1070 -\isacommand{term}\isamarkupfalse%
88.1071 -\ {\isachardoublequoteopen}x\ {\isasymotimes}\ y{\isachardoublequoteclose}\ %
88.1072 -\isamarkupcmt{example 1%
88.1073 -}
88.1074 -\isanewline
88.1075 -\isacommand{term}\isamarkupfalse%
88.1076 -\ {\isachardoublequoteopen}{\isacharparenleft}x{\isasymColon}nat{\isacharparenright}\ {\isasymotimes}\ y{\isachardoublequoteclose}\ %
88.1077 -\isamarkupcmt{example 2%
88.1078 -}
88.1079 -\isanewline
88.1080 -\isanewline
88.1081 -\isacommand{end}\isamarkupfalse%
88.1082 -\isanewline
88.1083 -\isanewline
88.1084 -\isacommand{term}\isamarkupfalse%
88.1085 -\ {\isachardoublequoteopen}x\ {\isasymotimes}\ y{\isachardoublequoteclose}\ %
88.1086 -\isamarkupcmt{example 3%
88.1087 -}
88.1088 -%
88.1089 -\endisatagquote
88.1090 -{\isafoldquote}%
88.1091 -%
88.1092 -\isadelimquote
88.1093 -%
88.1094 -\endisadelimquote
88.1095 -%
88.1096 -\begin{isamarkuptext}%
88.1097 -\noindent Here in example 1, the term refers to the local class operation
88.1098 - \isa{mult\ {\isacharbrackleft}{\isasymalpha}{\isacharbrackright}}, whereas in example 2 the type constraint
88.1099 - enforces the global class operation \isa{mult\ {\isacharbrackleft}nat{\isacharbrackright}}.
88.1100 - In the global context in example 3, the reference is
88.1101 - to the polymorphic global class operation \isa{mult\ {\isacharbrackleft}{\isacharquery}{\isasymalpha}\ {\isasymColon}\ semigroup{\isacharbrackright}}.%
88.1102 -\end{isamarkuptext}%
88.1103 -\isamarkuptrue%
88.1104 -%
88.1105 -\isamarkupsection{Further issues%
88.1106 -}
88.1107 -\isamarkuptrue%
88.1108 -%
88.1109 -\isamarkupsubsection{Type classes and code generation%
88.1110 -}
88.1111 -\isamarkuptrue%
88.1112 -%
88.1113 -\begin{isamarkuptext}%
88.1114 -Turning back to the first motivation for type classes,
88.1115 - namely overloading, it is obvious that overloading
88.1116 - stemming from \hyperlink{command.class}{\mbox{\isa{\isacommand{class}}}} statements and
88.1117 - \hyperlink{command.instantiation}{\mbox{\isa{\isacommand{instantiation}}}}
88.1118 - targets naturally maps to Haskell type classes.
88.1119 - The code generator framework \cite{isabelle-codegen}
88.1120 - takes this into account. Concerning target languages
88.1121 - lacking type classes (e.g.~SML), type classes
88.1122 - are implemented by explicit dictionary construction.
88.1123 - As example, let's go back to the power function:%
88.1124 -\end{isamarkuptext}%
88.1125 -\isamarkuptrue%
88.1126 -%
88.1127 -\isadelimquote
88.1128 -%
88.1129 -\endisadelimquote
88.1130 -%
88.1131 -\isatagquote
88.1132 -\isacommand{definition}\isamarkupfalse%
88.1133 -\ example\ {\isacharcolon}{\isacharcolon}\ int\ \isakeyword{where}\isanewline
88.1134 -\ \ {\isachardoublequoteopen}example\ {\isacharequal}\ pow{\isacharunderscore}int\ {\isadigit{1}}{\isadigit{0}}\ {\isacharparenleft}{\isacharminus}{\isadigit{2}}{\isacharparenright}{\isachardoublequoteclose}%
88.1135 -\endisatagquote
88.1136 -{\isafoldquote}%
88.1137 -%
88.1138 -\isadelimquote
88.1139 -%
88.1140 -\endisadelimquote
88.1141 -%
88.1142 -\begin{isamarkuptext}%
88.1143 -\noindent This maps to Haskell as:%
88.1144 -\end{isamarkuptext}%
88.1145 -\isamarkuptrue%
88.1146 -%
88.1147 -\isadelimquote
88.1148 -%
88.1149 -\endisadelimquote
88.1150 -%
88.1151 -\isatagquote
88.1152 -%
88.1153 -\begin{isamarkuptext}%
88.1154 -\isatypewriter%
88.1155 -\noindent%
88.1156 -\hspace*{0pt}module Example where {\char123}\\
88.1157 -\hspace*{0pt}\\
88.1158 -\hspace*{0pt}\\
88.1159 -\hspace*{0pt}data Nat = Suc Nat | Zero{\char95}nat;\\
88.1160 -\hspace*{0pt}\\
88.1161 -\hspace*{0pt}nat{\char95}aux ::~Integer -> Nat -> Nat;\\
88.1162 -\hspace*{0pt}nat{\char95}aux i n = (if i <= 0 then n else nat{\char95}aux (i - 1) (Suc n));\\
88.1163 -\hspace*{0pt}\\
88.1164 -\hspace*{0pt}nat ::~Integer -> Nat;\\
88.1165 -\hspace*{0pt}nat i = nat{\char95}aux i Zero{\char95}nat;\\
88.1166 -\hspace*{0pt}\\
88.1167 -\hspace*{0pt}class Semigroup a where {\char123}\\
88.1168 -\hspace*{0pt} ~mult ::~a -> a -> a;\\
88.1169 -\hspace*{0pt}{\char125};\\
88.1170 -\hspace*{0pt}\\
88.1171 -\hspace*{0pt}class (Semigroup a) => Monoidl a where {\char123}\\
88.1172 -\hspace*{0pt} ~neutral ::~a;\\
88.1173 -\hspace*{0pt}{\char125};\\
88.1174 -\hspace*{0pt}\\
88.1175 -\hspace*{0pt}class (Monoidl a) => Monoid a where {\char123}\\
88.1176 -\hspace*{0pt}{\char125};\\
88.1177 -\hspace*{0pt}\\
88.1178 -\hspace*{0pt}class (Monoid a) => Group a where {\char123}\\
88.1179 -\hspace*{0pt} ~inverse ::~a -> a;\\
88.1180 -\hspace*{0pt}{\char125};\\
88.1181 -\hspace*{0pt}\\
88.1182 -\hspace*{0pt}inverse{\char95}int ::~Integer -> Integer;\\
88.1183 -\hspace*{0pt}inverse{\char95}int i = negate i;\\
88.1184 -\hspace*{0pt}\\
88.1185 -\hspace*{0pt}neutral{\char95}int ::~Integer;\\
88.1186 -\hspace*{0pt}neutral{\char95}int = 0;\\
88.1187 -\hspace*{0pt}\\
88.1188 -\hspace*{0pt}mult{\char95}int ::~Integer -> Integer -> Integer;\\
88.1189 -\hspace*{0pt}mult{\char95}int i j = i + j;\\
88.1190 -\hspace*{0pt}\\
88.1191 -\hspace*{0pt}instance Semigroup Integer where {\char123}\\
88.1192 -\hspace*{0pt} ~mult = mult{\char95}int;\\
88.1193 -\hspace*{0pt}{\char125};\\
88.1194 -\hspace*{0pt}\\
88.1195 -\hspace*{0pt}instance Monoidl Integer where {\char123}\\
88.1196 -\hspace*{0pt} ~neutral = neutral{\char95}int;\\
88.1197 -\hspace*{0pt}{\char125};\\
88.1198 -\hspace*{0pt}\\
88.1199 -\hspace*{0pt}instance Monoid Integer where {\char123}\\
88.1200 -\hspace*{0pt}{\char125};\\
88.1201 -\hspace*{0pt}\\
88.1202 -\hspace*{0pt}instance Group Integer where {\char123}\\
88.1203 -\hspace*{0pt} ~inverse = inverse{\char95}int;\\
88.1204 -\hspace*{0pt}{\char125};\\
88.1205 -\hspace*{0pt}\\
88.1206 -\hspace*{0pt}pow{\char95}nat ::~forall a.~(Monoid a) => Nat -> a -> a;\\
88.1207 -\hspace*{0pt}pow{\char95}nat Zero{\char95}nat x = neutral;\\
88.1208 -\hspace*{0pt}pow{\char95}nat (Suc n) x = mult x (pow{\char95}nat n x);\\
88.1209 -\hspace*{0pt}\\
88.1210 -\hspace*{0pt}pow{\char95}int ::~forall a.~(Group a) => Integer -> a -> a;\\
88.1211 -\hspace*{0pt}pow{\char95}int k x =\\
88.1212 -\hspace*{0pt} ~(if 0 <= k then pow{\char95}nat (nat k) x\\
88.1213 -\hspace*{0pt} ~~~else inverse (pow{\char95}nat (nat (negate k)) x));\\
88.1214 -\hspace*{0pt}\\
88.1215 -\hspace*{0pt}example ::~Integer;\\
88.1216 -\hspace*{0pt}example = pow{\char95}int 10 (-2);\\
88.1217 -\hspace*{0pt}\\
88.1218 -\hspace*{0pt}{\char125}%
88.1219 -\end{isamarkuptext}%
88.1220 -\isamarkuptrue%
88.1221 -%
88.1222 -\endisatagquote
88.1223 -{\isafoldquote}%
88.1224 -%
88.1225 -\isadelimquote
88.1226 -%
88.1227 -\endisadelimquote
88.1228 -%
88.1229 -\begin{isamarkuptext}%
88.1230 -\noindent The whole code in SML with explicit dictionary passing:%
88.1231 -\end{isamarkuptext}%
88.1232 -\isamarkuptrue%
88.1233 -%
88.1234 -\isadelimquote
88.1235 -%
88.1236 -\endisadelimquote
88.1237 -%
88.1238 -\isatagquote
88.1239 -%
88.1240 -\begin{isamarkuptext}%
88.1241 -\isatypewriter%
88.1242 -\noindent%
88.1243 -\hspace*{0pt}structure Example = \\
88.1244 -\hspace*{0pt}struct\\
88.1245 -\hspace*{0pt}\\
88.1246 -\hspace*{0pt}datatype nat = Suc of nat | Zero{\char95}nat;\\
88.1247 -\hspace*{0pt}\\
88.1248 -\hspace*{0pt}fun nat{\char95}aux i n =\\
88.1249 -\hspace*{0pt} ~(if IntInf.<= (i,~(0 :~IntInf.int)) then n\\
88.1250 -\hspace*{0pt} ~~~else nat{\char95}aux (IntInf.- (i,~(1 :~IntInf.int))) (Suc n));\\
88.1251 -\hspace*{0pt}\\
88.1252 -\hspace*{0pt}fun nat i = nat{\char95}aux i Zero{\char95}nat;\\
88.1253 -\hspace*{0pt}\\
88.1254 -\hspace*{0pt}type 'a semigroup = {\char123}mult :~'a -> 'a -> 'a{\char125};\\
88.1255 -\hspace*{0pt}fun mult (A{\char95}:'a semigroup) = {\char35}mult A{\char95};\\
88.1256 -\hspace*{0pt}\\
88.1257 -\hspace*{0pt}type 'a monoidl =\\
88.1258 -\hspace*{0pt} ~{\char123}Classes{\char95}{\char95}semigroup{\char95}monoidl :~'a semigroup,~neutral :~'a{\char125};\\
88.1259 -\hspace*{0pt}fun semigroup{\char95}monoidl (A{\char95}:'a monoidl) = {\char35}Classes{\char95}{\char95}semigroup{\char95}monoidl A{\char95};\\
88.1260 -\hspace*{0pt}fun neutral (A{\char95}:'a monoidl) = {\char35}neutral A{\char95};\\
88.1261 -\hspace*{0pt}\\
88.1262 -\hspace*{0pt}type 'a monoid = {\char123}Classes{\char95}{\char95}monoidl{\char95}monoid :~'a monoidl{\char125};\\
88.1263 -\hspace*{0pt}fun monoidl{\char95}monoid (A{\char95}:'a monoid) = {\char35}Classes{\char95}{\char95}monoidl{\char95}monoid A{\char95};\\
88.1264 -\hspace*{0pt}\\
88.1265 -\hspace*{0pt}type 'a group = {\char123}Classes{\char95}{\char95}monoid{\char95}group :~'a monoid,~inverse :~'a -> 'a{\char125};\\
88.1266 -\hspace*{0pt}fun monoid{\char95}group (A{\char95}:'a group) = {\char35}Classes{\char95}{\char95}monoid{\char95}group A{\char95};\\
88.1267 -\hspace*{0pt}fun inverse (A{\char95}:'a group) = {\char35}inverse A{\char95};\\
88.1268 -\hspace*{0pt}\\
88.1269 -\hspace*{0pt}fun inverse{\char95}int i = IntInf.{\char126}~i;\\
88.1270 -\hspace*{0pt}\\
88.1271 -\hspace*{0pt}val neutral{\char95}int :~IntInf.int = (0 :~IntInf.int)\\
88.1272 -\hspace*{0pt}\\
88.1273 -\hspace*{0pt}fun mult{\char95}int i j = IntInf.+ (i,~j);\\
88.1274 -\hspace*{0pt}\\
88.1275 -\hspace*{0pt}val semigroup{\char95}int = {\char123}mult = mult{\char95}int{\char125}~:~IntInf.int semigroup;\\
88.1276 -\hspace*{0pt}\\
88.1277 -\hspace*{0pt}val monoidl{\char95}int =\\
88.1278 -\hspace*{0pt} ~{\char123}Classes{\char95}{\char95}semigroup{\char95}monoidl = semigroup{\char95}int,~neutral = neutral{\char95}int{\char125}~:\\
88.1279 -\hspace*{0pt} ~IntInf.int monoidl;\\
88.1280 -\hspace*{0pt}\\
88.1281 -\hspace*{0pt}val monoid{\char95}int = {\char123}Classes{\char95}{\char95}monoidl{\char95}monoid = monoidl{\char95}int{\char125}~:\\
88.1282 -\hspace*{0pt} ~IntInf.int monoid;\\
88.1283 -\hspace*{0pt}\\
88.1284 -\hspace*{0pt}val group{\char95}int =\\
88.1285 -\hspace*{0pt} ~{\char123}Classes{\char95}{\char95}monoid{\char95}group = monoid{\char95}int,~inverse = inverse{\char95}int{\char125}~:\\
88.1286 -\hspace*{0pt} ~IntInf.int group;\\
88.1287 -\hspace*{0pt}\\
88.1288 -\hspace*{0pt}fun pow{\char95}nat A{\char95}~Zero{\char95}nat x = neutral (monoidl{\char95}monoid A{\char95})\\
88.1289 -\hspace*{0pt} ~| pow{\char95}nat A{\char95}~(Suc n) x =\\
88.1290 -\hspace*{0pt} ~~~mult ((semigroup{\char95}monoidl o monoidl{\char95}monoid) A{\char95}) x (pow{\char95}nat A{\char95}~n x);\\
88.1291 -\hspace*{0pt}\\
88.1292 -\hspace*{0pt}fun pow{\char95}int A{\char95}~k x =\\
88.1293 -\hspace*{0pt} ~(if IntInf.<= ((0 :~IntInf.int),~k)\\
88.1294 -\hspace*{0pt} ~~~then pow{\char95}nat (monoid{\char95}group A{\char95}) (nat k) x\\
88.1295 -\hspace*{0pt} ~~~else inverse A{\char95}~(pow{\char95}nat (monoid{\char95}group A{\char95}) (nat (IntInf.{\char126}~k)) x));\\
88.1296 -\hspace*{0pt}\\
88.1297 -\hspace*{0pt}val example :~IntInf.int =\\
88.1298 -\hspace*{0pt} ~pow{\char95}int group{\char95}int (10 :~IntInf.int) ({\char126}2 :~IntInf.int)\\
88.1299 -\hspace*{0pt}\\
88.1300 -\hspace*{0pt}end;~(*struct Example*)%
88.1301 -\end{isamarkuptext}%
88.1302 -\isamarkuptrue%
88.1303 -%
88.1304 -\endisatagquote
88.1305 -{\isafoldquote}%
88.1306 -%
88.1307 -\isadelimquote
88.1308 -%
88.1309 -\endisadelimquote
88.1310 -%
88.1311 -\isamarkupsubsection{Inspecting the type class universe%
88.1312 -}
88.1313 -\isamarkuptrue%
88.1314 -%
88.1315 -\begin{isamarkuptext}%
88.1316 -To facilitate orientation in complex subclass structures,
88.1317 - two diagnostics commands are provided:
88.1318 -
88.1319 - \begin{description}
88.1320 -
88.1321 - \item[\hyperlink{command.print-classes}{\mbox{\isa{\isacommand{print{\isacharunderscore}classes}}}}] print a list of all classes
88.1322 - together with associated operations etc.
88.1323 -
88.1324 - \item[\hyperlink{command.class-deps}{\mbox{\isa{\isacommand{class{\isacharunderscore}deps}}}}] visualizes the subclass relation
88.1325 - between all classes as a Hasse diagram.
88.1326 -
88.1327 - \end{description}%
88.1328 -\end{isamarkuptext}%
88.1329 -\isamarkuptrue%
88.1330 -%
88.1331 -\isadelimtheory
88.1332 -%
88.1333 -\endisadelimtheory
88.1334 -%
88.1335 -\isatagtheory
88.1336 -\isacommand{end}\isamarkupfalse%
88.1337 -%
88.1338 -\endisatagtheory
88.1339 -{\isafoldtheory}%
88.1340 -%
88.1341 -\isadelimtheory
88.1342 -%
88.1343 -\endisadelimtheory
88.1344 -\isanewline
88.1345 -\end{isabellebody}%
88.1346 -%%% Local Variables:
88.1347 -%%% mode: latex
88.1348 -%%% TeX-master: "root"
88.1349 -%%% End:
89.1 --- a/doc-src/IsarAdvanced/Classes/classes.tex Wed Mar 04 11:05:02 2009 +0100
89.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
89.3 @@ -1,50 +0,0 @@
89.4 -
89.5 -\documentclass[12pt,a4paper,fleqn]{report}
89.6 -\usepackage{latexsym,graphicx}
89.7 -\usepackage[refpage]{nomencl}
89.8 -\usepackage{../../iman,../../extra,../../isar,../../proof}
89.9 -\usepackage{../../isabelle,../../isabellesym}
89.10 -\usepackage{style}
89.11 -\usepackage{../../pdfsetup}
89.12 -
89.13 -
89.14 -\hyphenation{Isabelle}
89.15 -\hyphenation{Isar}
89.16 -\isadroptag{theory}
89.17 -
89.18 -\title{\includegraphics[scale=0.5]{isabelle_isar}
89.19 - \\[4ex] Haskell-style type classes with Isabelle/Isar}
89.20 -\author{\emph{Florian Haftmann}}
89.21 -
89.22 -\begin{document}
89.23 -
89.24 -\maketitle
89.25 -
89.26 -\begin{abstract}
89.27 - This tutorial introduces the look-and-feel of Isar type classes
89.28 - to the end-user; Isar type classes are a convenient mechanism
89.29 - for organizing specifications, overcoming some drawbacks
89.30 - of raw axiomatic type classes. Essentially, they combine
89.31 - an operational aspect (in the manner of Haskell) with
89.32 - a logical aspect, both managed uniformly.
89.33 -\end{abstract}
89.34 -
89.35 -\thispagestyle{empty}\clearpage
89.36 -
89.37 -\pagenumbering{roman}
89.38 -\clearfirst
89.39 -
89.40 -\input{Thy/document/Classes.tex}
89.41 -
89.42 -\begingroup
89.43 -\bibliographystyle{plain} \small\raggedright\frenchspacing
89.44 -\bibliography{../../manual}
89.45 -\endgroup
89.46 -
89.47 -\end{document}
89.48 -
89.49 -
89.50 -%%% Local Variables:
89.51 -%%% mode: latex
89.52 -%%% TeX-master: t
89.53 -%%% End:
90.1 --- a/doc-src/IsarAdvanced/Classes/style.sty Wed Mar 04 11:05:02 2009 +0100
90.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
90.3 @@ -1,43 +0,0 @@
90.4 -
90.5 -%% toc
90.6 -\newcommand{\tocentry}[1]{\cleardoublepage\phantomsection\addcontentsline{toc}{chapter}{#1}
90.7 -\@mkboth{\MakeUppercase{#1}}{\MakeUppercase{#1}}}
90.8 -
90.9 -%% references
90.10 -\newcommand{\secref}[1]{\S\ref{#1}}
90.11 -\newcommand{\figref}[1]{figure~\ref{#1}}
90.12 -
90.13 -%% logical markup
90.14 -\newcommand{\strong}[1]{{\bfseries {#1}}}
90.15 -\newcommand{\qn}[1]{\emph{#1}}
90.16 -
90.17 -%% typographic conventions
90.18 -\newcommand{\qt}[1]{``{#1}''}
90.19 -
90.20 -%% verbatim text
90.21 -\newcommand{\isatypewriter}{\fontsize{9pt}{0pt}\tt\renewcommand{\baselinestretch}{1}\setlength{\baselineskip}{9pt}}
90.22 -
90.23 -%% quoted segments
90.24 -\makeatletter
90.25 -\isakeeptag{quote}
90.26 -\newenvironment{quotesegment}{\begin{quote}\isa@parindent\parindent\parindent0pt\isa@parskip\parskip\parskip0pt}{\end{quote}}
90.27 -\renewcommand{\isatagquote}{\begin{quotesegment}}
90.28 -\renewcommand{\endisatagquote}{\end{quotesegment}}
90.29 -\makeatother
90.30 -
90.31 -%% presentation
90.32 -\setcounter{secnumdepth}{2} \setcounter{tocdepth}{2}
90.33 -
90.34 -\pagestyle{headings}
90.35 -\binperiod
90.36 -\underscoreoff
90.37 -
90.38 -\renewcommand{\isadigit}[1]{\isamath{#1}}
90.39 -
90.40 -\isabellestyle{it}
90.41 -
90.42 -
90.43 -%%% Local Variables:
90.44 -%%% mode: latex
90.45 -%%% TeX-master: "implementation"
90.46 -%%% End:
91.1 --- a/doc-src/IsarAdvanced/Codegen/IsaMakefile Wed Mar 04 11:05:02 2009 +0100
91.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
91.3 @@ -1,33 +0,0 @@
91.4 -
91.5 -## targets
91.6 -
91.7 -default: Thy
91.8 -images:
91.9 -test: Thy
91.10 -
91.11 -all: images test
91.12 -
91.13 -
91.14 -## global settings
91.15 -
91.16 -SRC = $(ISABELLE_HOME)/src
91.17 -OUT = $(ISABELLE_OUTPUT)
91.18 -LOG = $(OUT)/log
91.19 -
91.20 -USEDIR = $(ISABELLE_TOOL) usedir -v true -i false -d false -C false -D document
91.21 -
91.22 -
91.23 -## Thy
91.24 -
91.25 -THY = $(LOG)/HOL-Thy.gz
91.26 -
91.27 -Thy: $(THY)
91.28 -
91.29 -$(THY): Thy/ROOT.ML Thy/*.thy ../../antiquote_setup.ML
91.30 - @$(USEDIR) HOL Thy
91.31 -
91.32 -
91.33 -## clean
91.34 -
91.35 -clean:
91.36 - @rm -f $(THY)
92.1 --- a/doc-src/IsarAdvanced/Codegen/Makefile Wed Mar 04 11:05:02 2009 +0100
92.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
92.3 @@ -1,38 +0,0 @@
92.4 -#
92.5 -# $Id$
92.6 -#
92.7 -
92.8 -## targets
92.9 -
92.10 -default: dvi
92.11 -
92.12 -
92.13 -## dependencies
92.14 -
92.15 -include ../Makefile.in
92.16 -
92.17 -NAME = codegen
92.18 -
92.19 -FILES = $(NAME).tex Thy/document/*.tex \
92.20 - style.sty ../../iman.sty ../../extra.sty ../../isar.sty \
92.21 - ../../isabelle.sty ../../isabellesym.sty ../../pdfsetup.sty \
92.22 - ../../manual.bib ../../proof.sty
92.23 -
92.24 -dvi: $(NAME).dvi
92.25 -
92.26 -$(NAME).dvi: $(FILES) isabelle_isar.eps codegen_process.ps
92.27 - $(LATEX) $(NAME)
92.28 - $(BIBTEX) $(NAME)
92.29 - $(LATEX) $(NAME)
92.30 - $(LATEX) $(NAME)
92.31 -
92.32 -pdf: $(NAME).pdf
92.33 -
92.34 -$(NAME).pdf: $(FILES) isabelle_isar.pdf codegen_process.pdf
92.35 - $(PDFLATEX) $(NAME)
92.36 - $(BIBTEX) $(NAME)
92.37 - $(PDFLATEX) $(NAME)
92.38 - $(PDFLATEX) $(NAME)
92.39 - $(FIXBOOKMARKS) $(NAME).out
92.40 - $(PDFLATEX) $(NAME)
92.41 - $(PDFLATEX) $(NAME)
93.1 --- a/doc-src/IsarAdvanced/Codegen/Thy/Adaption.thy Wed Mar 04 11:05:02 2009 +0100
93.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
93.3 @@ -1,361 +0,0 @@
93.4 -theory Adaption
93.5 -imports Setup
93.6 -begin
93.7 -
93.8 -setup %invisible {* Code_Target.extend_target ("\<SML>", ("SML", K I)) *}
93.9 -
93.10 -section {* Adaption to target languages \label{sec:adaption} *}
93.11 -
93.12 -subsection {* Adapting code generation *}
93.13 -
93.14 -text {*
93.15 - The aspects of code generation introduced so far have two aspects
93.16 - in common:
93.17 -
93.18 - \begin{itemize}
93.19 - \item They act uniformly, without reference to a specific
93.20 - target language.
93.21 - \item They are \emph{safe} in the sense that as long as you trust
93.22 - the code generator meta theory and implementation, you cannot
93.23 - produce programs that yield results which are not derivable
93.24 - in the logic.
93.25 - \end{itemize}
93.26 -
93.27 - \noindent In this section we will introduce means to \emph{adapt} the serialiser
93.28 - to a specific target language, i.e.~to print program fragments
93.29 - in a way which accommodates \qt{already existing} ingredients of
93.30 - a target language environment, for three reasons:
93.31 -
93.32 - \begin{itemize}
93.33 - \item improving readability and aesthetics of generated code
93.34 - \item gaining efficiency
93.35 - \item interface with language parts which have no direct counterpart
93.36 - in @{text "HOL"} (say, imperative data structures)
93.37 - \end{itemize}
93.38 -
93.39 - \noindent Generally, you should avoid using those features yourself
93.40 - \emph{at any cost}:
93.41 -
93.42 - \begin{itemize}
93.43 - \item The safe configuration methods act uniformly on every target language,
93.44 - whereas for adaption you have to treat each target language separate.
93.45 - \item Application is extremely tedious since there is no abstraction
93.46 - which would allow for a static check, making it easy to produce garbage.
93.47 - \item More or less subtle errors can be introduced unconsciously.
93.48 - \end{itemize}
93.49 -
93.50 - \noindent However, even if you ought refrain from setting up adaption
93.51 - yourself, already the @{text "HOL"} comes with some reasonable default
93.52 - adaptions (say, using target language list syntax). There also some
93.53 - common adaption cases which you can setup by importing particular
93.54 - library theories. In order to understand these, we provide some clues here;
93.55 - these however are not supposed to replace a careful study of the sources.
93.56 -*}
93.57 -
93.58 -subsection {* The adaption principle *}
93.59 -
93.60 -text {*
93.61 - The following figure illustrates what \qt{adaption} is conceptually
93.62 - supposed to be:
93.63 -
93.64 - \begin{figure}[here]
93.65 - \begin{tikzpicture}[scale = 0.5]
93.66 - \tikzstyle water=[color = blue, thick]
93.67 - \tikzstyle ice=[color = black, very thick, cap = round, join = round, fill = white]
93.68 - \tikzstyle process=[color = green, semithick, ->]
93.69 - \tikzstyle adaption=[color = red, semithick, ->]
93.70 - \tikzstyle target=[color = black]
93.71 - \foreach \x in {0, ..., 24}
93.72 - \draw[style=water] (\x, 0.25) sin + (0.25, 0.25) cos + (0.25, -0.25) sin
93.73 - + (0.25, -0.25) cos + (0.25, 0.25);
93.74 - \draw[style=ice] (1, 0) --
93.75 - (3, 6) node[above, fill=white] {logic} -- (5, 0) -- cycle;
93.76 - \draw[style=ice] (9, 0) --
93.77 - (11, 6) node[above, fill=white] {intermediate language} -- (13, 0) -- cycle;
93.78 - \draw[style=ice] (15, -6) --
93.79 - (19, 6) node[above, fill=white] {target language} -- (23, -6) -- cycle;
93.80 - \draw[style=process]
93.81 - (3.5, 3) .. controls (7, 5) .. node[fill=white] {translation} (10.5, 3);
93.82 - \draw[style=process]
93.83 - (11.5, 3) .. controls (15, 5) .. node[fill=white] (serialisation) {serialisation} (18.5, 3);
93.84 - \node (adaption) at (11, -2) [style=adaption] {adaption};
93.85 - \node at (19, 3) [rotate=90] {generated};
93.86 - \node at (19.5, -5) {language};
93.87 - \node at (19.5, -3) {library};
93.88 - \node (includes) at (19.5, -1) {includes};
93.89 - \node (reserved) at (16.5, -3) [rotate=72] {reserved}; % proper 71.57
93.90 - \draw[style=process]
93.91 - (includes) -- (serialisation);
93.92 - \draw[style=process]
93.93 - (reserved) -- (serialisation);
93.94 - \draw[style=adaption]
93.95 - (adaption) -- (serialisation);
93.96 - \draw[style=adaption]
93.97 - (adaption) -- (includes);
93.98 - \draw[style=adaption]
93.99 - (adaption) -- (reserved);
93.100 - \end{tikzpicture}
93.101 - \caption{The adaption principle}
93.102 - \label{fig:adaption}
93.103 - \end{figure}
93.104 -
93.105 - \noindent In the tame view, code generation acts as broker between
93.106 - @{text logic}, @{text "intermediate language"} and
93.107 - @{text "target language"} by means of @{text translation} and
93.108 - @{text serialisation}; for the latter, the serialiser has to observe
93.109 - the structure of the @{text language} itself plus some @{text reserved}
93.110 - keywords which have to be avoided for generated code.
93.111 - However, if you consider @{text adaption} mechanisms, the code generated
93.112 - by the serializer is just the tip of the iceberg:
93.113 -
93.114 - \begin{itemize}
93.115 - \item @{text serialisation} can be \emph{parametrised} such that
93.116 - logical entities are mapped to target-specific ones
93.117 - (e.g. target-specific list syntax,
93.118 - see also \secref{sec:adaption_mechanisms})
93.119 - \item Such parametrisations can involve references to a
93.120 - target-specific standard @{text library} (e.g. using
93.121 - the @{text Haskell} @{verbatim Maybe} type instead
93.122 - of the @{text HOL} @{type "option"} type);
93.123 - if such are used, the corresponding identifiers
93.124 - (in our example, @{verbatim Maybe}, @{verbatim Nothing}
93.125 - and @{verbatim Just}) also have to be considered @{text reserved}.
93.126 - \item Even more, the user can enrich the library of the
93.127 - target-language by providing code snippets
93.128 - (\qt{@{text "includes"}}) which are prepended to
93.129 - any generated code (see \secref{sec:include}); this typically
93.130 - also involves further @{text reserved} identifiers.
93.131 - \end{itemize}
93.132 -
93.133 - \noindent As figure \ref{fig:adaption} illustrates, all these adaption mechanisms
93.134 - have to act consistently; it is at the discretion of the user
93.135 - to take care for this.
93.136 -*}
93.137 -
93.138 -subsection {* Common adaption patterns *}
93.139 -
93.140 -text {*
93.141 - The @{theory HOL} @{theory Main} theory already provides a code
93.142 - generator setup
93.143 - which should be suitable for most applications. Common extensions
93.144 - and modifications are available by certain theories of the @{text HOL}
93.145 - library; beside being useful in applications, they may serve
93.146 - as a tutorial for customising the code generator setup (see below
93.147 - \secref{sec:adaption_mechanisms}).
93.148 -
93.149 - \begin{description}
93.150 -
93.151 - \item[@{theory "Code_Integer"}] represents @{text HOL} integers by big
93.152 - integer literals in target languages.
93.153 - \item[@{theory "Code_Char"}] represents @{text HOL} characters by
93.154 - character literals in target languages.
93.155 - \item[@{theory "Code_Char_chr"}] like @{text "Code_Char"},
93.156 - but also offers treatment of character codes; includes
93.157 - @{theory "Code_Char"}.
93.158 - \item[@{theory "Efficient_Nat"}] \label{eff_nat} implements natural numbers by integers,
93.159 - which in general will result in higher efficiency; pattern
93.160 - matching with @{term "0\<Colon>nat"} / @{const "Suc"}
93.161 - is eliminated; includes @{theory "Code_Integer"}
93.162 - and @{theory "Code_Index"}.
93.163 - \item[@{theory "Code_Index"}] provides an additional datatype
93.164 - @{typ index} which is mapped to target-language built-in integers.
93.165 - Useful for code setups which involve e.g. indexing of
93.166 - target-language arrays.
93.167 - \item[@{theory "Code_Message"}] provides an additional datatype
93.168 - @{typ message_string} which is isomorphic to strings;
93.169 - @{typ message_string}s are mapped to target-language strings.
93.170 - Useful for code setups which involve e.g. printing (error) messages.
93.171 -
93.172 - \end{description}
93.173 -
93.174 - \begin{warn}
93.175 - When importing any of these theories, they should form the last
93.176 - items in an import list. Since these theories adapt the
93.177 - code generator setup in a non-conservative fashion,
93.178 - strange effects may occur otherwise.
93.179 - \end{warn}
93.180 -*}
93.181 -
93.182 -
93.183 -subsection {* Parametrising serialisation \label{sec:adaption_mechanisms} *}
93.184 -
93.185 -text {*
93.186 - Consider the following function and its corresponding
93.187 - SML code:
93.188 -*}
93.189 -
93.190 -primrec %quote in_interval :: "nat \<times> nat \<Rightarrow> nat \<Rightarrow> bool" where
93.191 - "in_interval (k, l) n \<longleftrightarrow> k \<le> n \<and> n \<le> l"
93.192 -(*<*)
93.193 -code_type %invisible bool
93.194 - (SML)
93.195 -code_const %invisible True and False and "op \<and>" and Not
93.196 - (SML and and and)
93.197 -(*>*)
93.198 -text %quote {*@{code_stmts in_interval (SML)}*}
93.199 -
93.200 -text {*
93.201 - \noindent Though this is correct code, it is a little bit unsatisfactory:
93.202 - boolean values and operators are materialised as distinguished
93.203 - entities with have nothing to do with the SML-built-in notion
93.204 - of \qt{bool}. This results in less readable code;
93.205 - additionally, eager evaluation may cause programs to
93.206 - loop or break which would perfectly terminate when
93.207 - the existing SML @{verbatim "bool"} would be used. To map
93.208 - the HOL @{typ bool} on SML @{verbatim "bool"}, we may use
93.209 - \qn{custom serialisations}:
93.210 -*}
93.211 -
93.212 -code_type %quotett bool
93.213 - (SML "bool")
93.214 -code_const %quotett True and False and "op \<and>"
93.215 - (SML "true" and "false" and "_ andalso _")
93.216 -
93.217 -text {*
93.218 - \noindent The @{command code_type} command takes a type constructor
93.219 - as arguments together with a list of custom serialisations.
93.220 - Each custom serialisation starts with a target language
93.221 - identifier followed by an expression, which during
93.222 - code serialisation is inserted whenever the type constructor
93.223 - would occur. For constants, @{command code_const} implements
93.224 - the corresponding mechanism. Each ``@{verbatim "_"}'' in
93.225 - a serialisation expression is treated as a placeholder
93.226 - for the type constructor's (the constant's) arguments.
93.227 -*}
93.228 -
93.229 -text %quote {*@{code_stmts in_interval (SML)}*}
93.230 -
93.231 -text {*
93.232 - \noindent This still is not perfect: the parentheses
93.233 - around the \qt{andalso} expression are superfluous.
93.234 - Though the serialiser
93.235 - by no means attempts to imitate the rich Isabelle syntax
93.236 - framework, it provides some common idioms, notably
93.237 - associative infixes with precedences which may be used here:
93.238 -*}
93.239 -
93.240 -code_const %quotett "op \<and>"
93.241 - (SML infixl 1 "andalso")
93.242 -
93.243 -text %quote {*@{code_stmts in_interval (SML)}*}
93.244 -
93.245 -text {*
93.246 - \noindent The attentive reader may ask how we assert that no generated
93.247 - code will accidentally overwrite. For this reason the serialiser has
93.248 - an internal table of identifiers which have to be avoided to be used
93.249 - for new declarations. Initially, this table typically contains the
93.250 - keywords of the target language. It can be extended manually, thus avoiding
93.251 - accidental overwrites, using the @{command "code_reserved"} command:
93.252 -*}
93.253 -
93.254 -code_reserved %quote "\<SML>" bool true false andalso
93.255 -
93.256 -text {*
93.257 - \noindent Next, we try to map HOL pairs to SML pairs, using the
93.258 - infix ``@{verbatim "*"}'' type constructor and parentheses:
93.259 -*}
93.260 -(*<*)
93.261 -code_type %invisible *
93.262 - (SML)
93.263 -code_const %invisible Pair
93.264 - (SML)
93.265 -(*>*)
93.266 -code_type %quotett *
93.267 - (SML infix 2 "*")
93.268 -code_const %quotett Pair
93.269 - (SML "!((_),/ (_))")
93.270 -
93.271 -text {*
93.272 - \noindent The initial bang ``@{verbatim "!"}'' tells the serialiser
93.273 - never to put
93.274 - parentheses around the whole expression (they are already present),
93.275 - while the parentheses around argument place holders
93.276 - tell not to put parentheses around the arguments.
93.277 - The slash ``@{verbatim "/"}'' (followed by arbitrary white space)
93.278 - inserts a space which may be used as a break if necessary
93.279 - during pretty printing.
93.280 -
93.281 - These examples give a glimpse what mechanisms
93.282 - custom serialisations provide; however their usage
93.283 - requires careful thinking in order not to introduce
93.284 - inconsistencies -- or, in other words:
93.285 - custom serialisations are completely axiomatic.
93.286 -
93.287 - A further noteworthy details is that any special
93.288 - character in a custom serialisation may be quoted
93.289 - using ``@{verbatim "'"}''; thus, in
93.290 - ``@{verbatim "fn '_ => _"}'' the first
93.291 - ``@{verbatim "_"}'' is a proper underscore while the
93.292 - second ``@{verbatim "_"}'' is a placeholder.
93.293 -*}
93.294 -
93.295 -
93.296 -subsection {* @{text Haskell} serialisation *}
93.297 -
93.298 -text {*
93.299 - For convenience, the default
93.300 - @{text HOL} setup for @{text Haskell} maps the @{class eq} class to
93.301 - its counterpart in @{text Haskell}, giving custom serialisations
93.302 - for the class @{class eq} (by command @{command code_class}) and its operation
93.303 - @{const HOL.eq}
93.304 -*}
93.305 -
93.306 -code_class %quotett eq
93.307 - (Haskell "Eq")
93.308 -
93.309 -code_const %quotett "op ="
93.310 - (Haskell infixl 4 "==")
93.311 -
93.312 -text {*
93.313 - \noindent A problem now occurs whenever a type which
93.314 - is an instance of @{class eq} in @{text HOL} is mapped
93.315 - on a @{text Haskell}-built-in type which is also an instance
93.316 - of @{text Haskell} @{text Eq}:
93.317 -*}
93.318 -
93.319 -typedecl %quote bar
93.320 -
93.321 -instantiation %quote bar :: eq
93.322 -begin
93.323 -
93.324 -definition %quote "eq_class.eq (x\<Colon>bar) y \<longleftrightarrow> x = y"
93.325 -
93.326 -instance %quote by default (simp add: eq_bar_def)
93.327 -
93.328 -end %quote
93.329 -
93.330 -code_type %quotett bar
93.331 - (Haskell "Integer")
93.332 -
93.333 -text {*
93.334 - \noindent The code generator would produce
93.335 - an additional instance, which of course is rejected by the @{text Haskell}
93.336 - compiler.
93.337 - To suppress this additional instance, use
93.338 - @{text "code_instance"}:
93.339 -*}
93.340 -
93.341 -code_instance %quotett bar :: eq
93.342 - (Haskell -)
93.343 -
93.344 -
93.345 -subsection {* Enhancing the target language context \label{sec:include} *}
93.346 -
93.347 -text {*
93.348 - In rare cases it is necessary to \emph{enrich} the context of a
93.349 - target language; this is accomplished using the @{command "code_include"}
93.350 - command:
93.351 -*}
93.352 -
93.353 -code_include %quotett Haskell "Errno"
93.354 -{*errno i = error ("Error number: " ++ show i)*}
93.355 -
93.356 -code_reserved %quotett Haskell Errno
93.357 -
93.358 -text {*
93.359 - \noindent Such named @{text include}s are then prepended to every generated code.
93.360 - Inspect such code in order to find out how @{command "code_include"} behaves
93.361 - with respect to a particular target language.
93.362 -*}
93.363 -
93.364 -end
94.1 --- a/doc-src/IsarAdvanced/Codegen/Thy/Codegen.thy Wed Mar 04 11:05:02 2009 +0100
94.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
94.3 @@ -1,2 +0,0 @@
94.4 -
94.5 -end
95.1 --- a/doc-src/IsarAdvanced/Codegen/Thy/Further.thy Wed Mar 04 11:05:02 2009 +0100
95.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
95.3 @@ -1,113 +0,0 @@
95.4 -theory Further
95.5 -imports Setup
95.6 -begin
95.7 -
95.8 -section {* Further issues \label{sec:further} *}
95.9 -
95.10 -subsection {* Further reading *}
95.11 -
95.12 -text {*
95.13 - Do dive deeper into the issue of code generation, you should visit
95.14 - the Isabelle/Isar Reference Manual \cite{isabelle-isar-ref} which
95.15 - contains exhaustive syntax diagrams.
95.16 -*}
95.17 -
95.18 -subsection {* Modules *}
95.19 -
95.20 -text {*
95.21 - When invoking the @{command export_code} command it is possible to leave
95.22 - out the @{keyword "module_name"} part; then code is distributed over
95.23 - different modules, where the module name space roughly is induced
95.24 - by the @{text Isabelle} theory name space.
95.25 -
95.26 - Then sometimes the awkward situation occurs that dependencies between
95.27 - definitions introduce cyclic dependencies between modules, which in the
95.28 - @{text Haskell} world leaves you to the mercy of the @{text Haskell} implementation
95.29 - you are using, while for @{text SML}/@{text OCaml} code generation is not possible.
95.30 -
95.31 - A solution is to declare module names explicitly.
95.32 - Let use assume the three cyclically dependent
95.33 - modules are named \emph{A}, \emph{B} and \emph{C}.
95.34 - Then, by stating
95.35 -*}
95.36 -
95.37 -code_modulename %quote SML
95.38 - A ABC
95.39 - B ABC
95.40 - C ABC
95.41 -
95.42 -text {*
95.43 - we explicitly map all those modules on \emph{ABC},
95.44 - resulting in an ad-hoc merge of this three modules
95.45 - at serialisation time.
95.46 -*}
95.47 -
95.48 -subsection {* Evaluation oracle *}
95.49 -
95.50 -text {*
95.51 - Code generation may also be used to \emph{evaluate} expressions
95.52 - (using @{text SML} as target language of course).
95.53 - For instance, the @{command value} allows to reduce an expression to a
95.54 - normal form with respect to the underlying code equations:
95.55 -*}
95.56 -
95.57 -value %quote "42 / (12 :: rat)"
95.58 -
95.59 -text {*
95.60 - \noindent will display @{term "7 / (2 :: rat)"}.
95.61 -
95.62 - The @{method eval} method tries to reduce a goal by code generation to @{term True}
95.63 - and solves it in that case, but fails otherwise:
95.64 -*}
95.65 -
95.66 -lemma %quote "42 / (12 :: rat) = 7 / 2"
95.67 - by %quote eval
95.68 -
95.69 -text {*
95.70 - \noindent The soundness of the @{method eval} method depends crucially
95.71 - on the correctness of the code generator; this is one of the reasons
95.72 - why you should not use adaption (see \secref{sec:adaption}) frivolously.
95.73 -*}
95.74 -
95.75 -subsection {* Code antiquotation *}
95.76 -
95.77 -text {*
95.78 - In scenarios involving techniques like reflection it is quite common
95.79 - that code generated from a theory forms the basis for implementing
95.80 - a proof procedure in @{text SML}. To facilitate interfacing of generated code
95.81 - with system code, the code generator provides a @{text code} antiquotation:
95.82 -*}
95.83 -
95.84 -datatype %quote form = T | F | And form form | Or form form
95.85 -
95.86 -ML %quote {*
95.87 - fun eval_form @{code T} = true
95.88 - | eval_form @{code F} = false
95.89 - | eval_form (@{code And} (p, q)) =
95.90 - eval_form p andalso eval_form q
95.91 - | eval_form (@{code Or} (p, q)) =
95.92 - eval_form p orelse eval_form q;
95.93 -*}
95.94 -
95.95 -text {*
95.96 - \noindent @{text code} takes as argument the name of a constant; after the
95.97 - whole @{text SML} is read, the necessary code is generated transparently
95.98 - and the corresponding constant names are inserted. This technique also
95.99 - allows to use pattern matching on constructors stemming from compiled
95.100 - @{text datatypes}.
95.101 -
95.102 - For a less simplistic example, theory @{theory Ferrack} is
95.103 - a good reference.
95.104 -*}
95.105 -
95.106 -subsection {* Imperative data structures *}
95.107 -
95.108 -text {*
95.109 - If you consider imperative data structures as inevitable for a specific
95.110 - application, you should consider
95.111 - \emph{Imperative Functional Programming with Isabelle/HOL}
95.112 - (\cite{bulwahn-et-al:2008:imperative});
95.113 - the framework described there is available in theory @{theory Imperative_HOL}.
95.114 -*}
95.115 -
95.116 -end
96.1 --- a/doc-src/IsarAdvanced/Codegen/Thy/Introduction.thy Wed Mar 04 11:05:02 2009 +0100
96.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
96.3 @@ -1,206 +0,0 @@
96.4 -theory Introduction
96.5 -imports Setup
96.6 -begin
96.7 -
96.8 -chapter {* Code generation from @{text "Isabelle/HOL"} theories *}
96.9 -
96.10 -section {* Introduction and Overview *}
96.11 -
96.12 -text {*
96.13 - This tutorial introduces a generic code generator for the
96.14 - @{text Isabelle} system.
96.15 - Generic in the sense that the
96.16 - \qn{target language} for which code shall ultimately be
96.17 - generated is not fixed but may be an arbitrary state-of-the-art
96.18 - functional programming language (currently, the implementation
96.19 - supports @{text SML} \cite{SML}, @{text OCaml} \cite{OCaml} and @{text Haskell}
96.20 - \cite{haskell-revised-report}).
96.21 -
96.22 - Conceptually the code generator framework is part
96.23 - of Isabelle's @{theory Pure} meta logic framework; the logic
96.24 - @{theory HOL} which is an extension of @{theory Pure}
96.25 - already comes with a reasonable framework setup and thus provides
96.26 - a good working horse for raising code-generation-driven
96.27 - applications. So, we assume some familiarity and experience
96.28 - with the ingredients of the @{theory HOL} distribution theories.
96.29 - (see also \cite{isa-tutorial}).
96.30 -
96.31 - The code generator aims to be usable with no further ado
96.32 - in most cases while allowing for detailed customisation.
96.33 - This manifests in the structure of this tutorial: after a short
96.34 - conceptual introduction with an example (\secref{sec:intro}),
96.35 - we discuss the generic customisation facilities (\secref{sec:program}).
96.36 - A further section (\secref{sec:adaption}) is dedicated to the matter of
96.37 - \qn{adaption} to specific target language environments. After some
96.38 - further issues (\secref{sec:further}) we conclude with an overview
96.39 - of some ML programming interfaces (\secref{sec:ml}).
96.40 -
96.41 - \begin{warn}
96.42 - Ultimately, the code generator which this tutorial deals with
96.43 - is supposed to replace the existing code generator
96.44 - by Stefan Berghofer \cite{Berghofer-Nipkow:2002}.
96.45 - So, for the moment, there are two distinct code generators
96.46 - in Isabelle. In case of ambiguity, we will refer to the framework
96.47 - described here as @{text "generic code generator"}, to the
96.48 - other as @{text "SML code generator"}.
96.49 - Also note that while the framework itself is
96.50 - object-logic independent, only @{theory HOL} provides a reasonable
96.51 - framework setup.
96.52 - \end{warn}
96.53 -
96.54 -*}
96.55 -
96.56 -subsection {* Code generation via shallow embedding \label{sec:intro} *}
96.57 -
96.58 -text {*
96.59 - The key concept for understanding @{text Isabelle}'s code generation is
96.60 - \emph{shallow embedding}, i.e.~logical entities like constants, types and
96.61 - classes are identified with corresponding concepts in the target language.
96.62 -
96.63 - Inside @{theory HOL}, the @{command datatype} and
96.64 - @{command definition}/@{command primrec}/@{command fun} declarations form
96.65 - the core of a functional programming language. The default code generator setup
96.66 - allows to turn those into functional programs immediately.
96.67 - This means that \qt{naive} code generation can proceed without further ado.
96.68 - For example, here a simple \qt{implementation} of amortised queues:
96.69 -*}
96.70 -
96.71 -datatype %quote 'a queue = AQueue "'a list" "'a list"
96.72 -
96.73 -definition %quote empty :: "'a queue" where
96.74 - "empty = AQueue [] []"
96.75 -
96.76 -primrec %quote enqueue :: "'a \<Rightarrow> 'a queue \<Rightarrow> 'a queue" where
96.77 - "enqueue x (AQueue xs ys) = AQueue (x # xs) ys"
96.78 -
96.79 -fun %quote dequeue :: "'a queue \<Rightarrow> 'a option \<times> 'a queue" where
96.80 - "dequeue (AQueue [] []) = (None, AQueue [] [])"
96.81 - | "dequeue (AQueue xs (y # ys)) = (Some y, AQueue xs ys)"
96.82 - | "dequeue (AQueue xs []) =
96.83 - (case rev xs of y # ys \<Rightarrow> (Some y, AQueue [] ys))"
96.84 -
96.85 -text {* \noindent Then we can generate code e.g.~for @{text SML} as follows: *}
96.86 -
96.87 -export_code %quote empty dequeue enqueue in SML
96.88 - module_name Example file "examples/example.ML"
96.89 -
96.90 -text {* \noindent resulting in the following code: *}
96.91 -
96.92 -text %quote {*@{code_stmts empty enqueue dequeue (SML)}*}
96.93 -
96.94 -text {*
96.95 - \noindent The @{command export_code} command takes a space-separated list of
96.96 - constants for which code shall be generated; anything else needed for those
96.97 - is added implicitly. Then follows a target language identifier
96.98 - (@{text SML}, @{text OCaml} or @{text Haskell}) and a freely chosen module name.
96.99 - A file name denotes the destination to store the generated code. Note that
96.100 - the semantics of the destination depends on the target language: for
96.101 - @{text SML} and @{text OCaml} it denotes a \emph{file}, for @{text Haskell}
96.102 - it denotes a \emph{directory} where a file named as the module name
96.103 - (with extension @{text ".hs"}) is written:
96.104 -*}
96.105 -
96.106 -export_code %quote empty dequeue enqueue in Haskell
96.107 - module_name Example file "examples/"
96.108 -
96.109 -text {*
96.110 - \noindent This is how the corresponding code in @{text Haskell} looks like:
96.111 -*}
96.112 -
96.113 -text %quote {*@{code_stmts empty enqueue dequeue (Haskell)}*}
96.114 -
96.115 -text {*
96.116 - \noindent This demonstrates the basic usage of the @{command export_code} command;
96.117 - for more details see \secref{sec:further}.
96.118 -*}
96.119 -
96.120 -subsection {* Code generator architecture \label{sec:concept} *}
96.121 -
96.122 -text {*
96.123 - What you have seen so far should be already enough in a lot of cases. If you
96.124 - are content with this, you can quit reading here. Anyway, in order to customise
96.125 - and adapt the code generator, it is inevitable to gain some understanding
96.126 - how it works.
96.127 -
96.128 - \begin{figure}[h]
96.129 - \begin{tikzpicture}[x = 4.2cm, y = 1cm]
96.130 - \tikzstyle entity=[rounded corners, draw, thick, color = black, fill = white];
96.131 - \tikzstyle process=[ellipse, draw, thick, color = green, fill = white];
96.132 - \tikzstyle process_arrow=[->, semithick, color = green];
96.133 - \node (HOL) at (0, 4) [style=entity] {@{text "Isabelle/HOL"} theory};
96.134 - \node (eqn) at (2, 2) [style=entity] {code equations};
96.135 - \node (iml) at (2, 0) [style=entity] {intermediate language};
96.136 - \node (seri) at (1, 0) [style=process] {serialisation};
96.137 - \node (SML) at (0, 3) [style=entity] {@{text SML}};
96.138 - \node (OCaml) at (0, 2) [style=entity] {@{text OCaml}};
96.139 - \node (further) at (0, 1) [style=entity] {@{text "\<dots>"}};
96.140 - \node (Haskell) at (0, 0) [style=entity] {@{text Haskell}};
96.141 - \draw [style=process_arrow] (HOL) .. controls (2, 4) ..
96.142 - node [style=process, near start] {selection}
96.143 - node [style=process, near end] {preprocessing}
96.144 - (eqn);
96.145 - \draw [style=process_arrow] (eqn) -- node (transl) [style=process] {translation} (iml);
96.146 - \draw [style=process_arrow] (iml) -- (seri);
96.147 - \draw [style=process_arrow] (seri) -- (SML);
96.148 - \draw [style=process_arrow] (seri) -- (OCaml);
96.149 - \draw [style=process_arrow, dashed] (seri) -- (further);
96.150 - \draw [style=process_arrow] (seri) -- (Haskell);
96.151 - \end{tikzpicture}
96.152 - \caption{Code generator architecture}
96.153 - \label{fig:arch}
96.154 - \end{figure}
96.155 -
96.156 - The code generator employs a notion of executability
96.157 - for three foundational executable ingredients known
96.158 - from functional programming:
96.159 - \emph{code equations}, \emph{datatypes}, and
96.160 - \emph{type classes}. A code equation as a first approximation
96.161 - is a theorem of the form @{text "f t\<^isub>1 t\<^isub>2 \<dots> t\<^isub>n \<equiv> t"}
96.162 - (an equation headed by a constant @{text f} with arguments
96.163 - @{text "t\<^isub>1 t\<^isub>2 \<dots> t\<^isub>n"} and right hand side @{text t}).
96.164 - Code generation aims to turn code equations
96.165 - into a functional program. This is achieved by three major
96.166 - components which operate sequentially, i.e. the result of one is
96.167 - the input
96.168 - of the next in the chain, see diagram \ref{fig:arch}:
96.169 -
96.170 - \begin{itemize}
96.171 -
96.172 - \item Out of the vast collection of theorems proven in a
96.173 - \qn{theory}, a reasonable subset modelling
96.174 - code equations is \qn{selected}.
96.175 -
96.176 - \item On those selected theorems, certain
96.177 - transformations are carried out
96.178 - (\qn{preprocessing}). Their purpose is to turn theorems
96.179 - representing non- or badly executable
96.180 - specifications into equivalent but executable counterparts.
96.181 - The result is a structured collection of \qn{code theorems}.
96.182 -
96.183 - \item Before the selected code equations are continued with,
96.184 - they can be \qn{preprocessed}, i.e. subjected to theorem
96.185 - transformations. This \qn{preprocessor} is an interface which
96.186 - allows to apply
96.187 - the full expressiveness of ML-based theorem transformations
96.188 - to code generation; motivating examples are shown below, see
96.189 - \secref{sec:preproc}.
96.190 - The result of the preprocessing step is a structured collection
96.191 - of code equations.
96.192 -
96.193 - \item These code equations are \qn{translated} to a program
96.194 - in an abstract intermediate language. Think of it as a kind
96.195 - of \qt{Mini-Haskell} with four \qn{statements}: @{text data}
96.196 - (for datatypes), @{text fun} (stemming from code equations),
96.197 - also @{text class} and @{text inst} (for type classes).
96.198 -
96.199 - \item Finally, the abstract program is \qn{serialised} into concrete
96.200 - source code of a target language.
96.201 -
96.202 - \end{itemize}
96.203 -
96.204 - \noindent From these steps, only the two last are carried out outside the logic; by
96.205 - keeping this layer as thin as possible, the amount of code to trust is
96.206 - kept to a minimum.
96.207 -*}
96.208 -
96.209 -end
97.1 --- a/doc-src/IsarAdvanced/Codegen/Thy/ML.thy Wed Mar 04 11:05:02 2009 +0100
97.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
97.3 @@ -1,177 +0,0 @@
97.4 -theory "ML"
97.5 -imports Setup
97.6 -begin
97.7 -
97.8 -section {* ML system interfaces \label{sec:ml} *}
97.9 -
97.10 -text {*
97.11 - Since the code generator framework not only aims to provide
97.12 - a nice Isar interface but also to form a base for
97.13 - code-generation-based applications, here a short
97.14 - description of the most important ML interfaces.
97.15 -*}
97.16 -
97.17 -subsection {* Executable theory content: @{text Code} *}
97.18 -
97.19 -text {*
97.20 - This Pure module implements the core notions of
97.21 - executable content of a theory.
97.22 -*}
97.23 -
97.24 -subsubsection {* Managing executable content *}
97.25 -
97.26 -text %mlref {*
97.27 - \begin{mldecls}
97.28 - @{index_ML Code.add_eqn: "thm -> theory -> theory"} \\
97.29 - @{index_ML Code.del_eqn: "thm -> theory -> theory"} \\
97.30 - @{index_ML Code.add_eqnl: "string * (thm * bool) list lazy -> theory -> theory"} \\
97.31 - @{index_ML Code.map_pre: "(simpset -> simpset) -> theory -> theory"} \\
97.32 - @{index_ML Code.map_post: "(simpset -> simpset) -> theory -> theory"} \\
97.33 - @{index_ML Code.add_functrans: "string * (theory -> (thm * bool) list -> (thm * bool) list option)
97.34 - -> theory -> theory"} \\
97.35 - @{index_ML Code.del_functrans: "string -> theory -> theory"} \\
97.36 - @{index_ML Code.add_datatype: "(string * typ) list -> theory -> theory"} \\
97.37 - @{index_ML Code.get_datatype: "theory -> string
97.38 - -> (string * sort) list * (string * typ list) list"} \\
97.39 - @{index_ML Code.get_datatype_of_constr: "theory -> string -> string option"}
97.40 - \end{mldecls}
97.41 -
97.42 - \begin{description}
97.43 -
97.44 - \item @{ML Code.add_eqn}~@{text "thm"}~@{text "thy"} adds function
97.45 - theorem @{text "thm"} to executable content.
97.46 -
97.47 - \item @{ML Code.del_eqn}~@{text "thm"}~@{text "thy"} removes function
97.48 - theorem @{text "thm"} from executable content, if present.
97.49 -
97.50 - \item @{ML Code.add_eqnl}~@{text "(const, lthms)"}~@{text "thy"} adds
97.51 - suspended code equations @{text lthms} for constant
97.52 - @{text const} to executable content.
97.53 -
97.54 - \item @{ML Code.map_pre}~@{text "f"}~@{text "thy"} changes
97.55 - the preprocessor simpset.
97.56 -
97.57 - \item @{ML Code.add_functrans}~@{text "(name, f)"}~@{text "thy"} adds
97.58 - function transformer @{text f} (named @{text name}) to executable content;
97.59 - @{text f} is a transformer of the code equations belonging
97.60 - to a certain function definition, depending on the
97.61 - current theory context. Returning @{text NONE} indicates that no
97.62 - transformation took place; otherwise, the whole process will be iterated
97.63 - with the new code equations.
97.64 -
97.65 - \item @{ML Code.del_functrans}~@{text "name"}~@{text "thy"} removes
97.66 - function transformer named @{text name} from executable content.
97.67 -
97.68 - \item @{ML Code.add_datatype}~@{text cs}~@{text thy} adds
97.69 - a datatype to executable content, with generation
97.70 - set @{text cs}.
97.71 -
97.72 - \item @{ML Code.get_datatype_of_constr}~@{text "thy"}~@{text "const"}
97.73 - returns type constructor corresponding to
97.74 - constructor @{text const}; returns @{text NONE}
97.75 - if @{text const} is no constructor.
97.76 -
97.77 - \end{description}
97.78 -*}
97.79 -
97.80 -subsection {* Auxiliary *}
97.81 -
97.82 -text %mlref {*
97.83 - \begin{mldecls}
97.84 - @{index_ML Code_Unit.read_const: "theory -> string -> string"} \\
97.85 - @{index_ML Code_Unit.head_eqn: "theory -> thm -> string * ((string * sort) list * typ)"} \\
97.86 - @{index_ML Code_Unit.rewrite_eqn: "simpset -> thm -> thm"} \\
97.87 - \end{mldecls}
97.88 -
97.89 - \begin{description}
97.90 -
97.91 - \item @{ML Code_Unit.read_const}~@{text thy}~@{text s}
97.92 - reads a constant as a concrete term expression @{text s}.
97.93 -
97.94 - \item @{ML Code_Unit.head_eqn}~@{text thy}~@{text thm}
97.95 - extracts the constant and its type from a code equation @{text thm}.
97.96 -
97.97 - \item @{ML Code_Unit.rewrite_eqn}~@{text ss}~@{text thm}
97.98 - rewrites a code equation @{text thm} with a simpset @{text ss};
97.99 - only arguments and right hand side are rewritten,
97.100 - not the head of the code equation.
97.101 -
97.102 - \end{description}
97.103 -
97.104 -*}
97.105 -
97.106 -subsection {* Implementing code generator applications *}
97.107 -
97.108 -text {*
97.109 - Implementing code generator applications on top
97.110 - of the framework set out so far usually not only
97.111 - involves using those primitive interfaces
97.112 - but also storing code-dependent data and various
97.113 - other things.
97.114 -*}
97.115 -
97.116 -subsubsection {* Data depending on the theory's executable content *}
97.117 -
97.118 -text {*
97.119 - Due to incrementality of code generation, changes in the
97.120 - theory's executable content have to be propagated in a
97.121 - certain fashion. Additionally, such changes may occur
97.122 - not only during theory extension but also during theory
97.123 - merge, which is a little bit nasty from an implementation
97.124 - point of view. The framework provides a solution
97.125 - to this technical challenge by providing a functorial
97.126 - data slot @{ML_functor CodeDataFun}; on instantiation
97.127 - of this functor, the following types and operations
97.128 - are required:
97.129 -
97.130 - \medskip
97.131 - \begin{tabular}{l}
97.132 - @{text "type T"} \\
97.133 - @{text "val empty: T"} \\
97.134 - @{text "val purge: theory \<rightarrow> string list option \<rightarrow> T \<rightarrow> T"}
97.135 - \end{tabular}
97.136 -
97.137 - \begin{description}
97.138 -
97.139 - \item @{text T} the type of data to store.
97.140 -
97.141 - \item @{text empty} initial (empty) data.
97.142 -
97.143 - \item @{text purge}~@{text thy}~@{text consts} propagates changes in executable content;
97.144 - @{text consts} indicates the kind
97.145 - of change: @{ML NONE} stands for a fundamental change
97.146 - which invalidates any existing code, @{text "SOME consts"}
97.147 - hints that executable content for constants @{text consts}
97.148 - has changed.
97.149 -
97.150 - \end{description}
97.151 -
97.152 - \noindent An instance of @{ML_functor CodeDataFun} provides the following
97.153 - interface:
97.154 -
97.155 - \medskip
97.156 - \begin{tabular}{l}
97.157 - @{text "get: theory \<rightarrow> T"} \\
97.158 - @{text "change: theory \<rightarrow> (T \<rightarrow> T) \<rightarrow> T"} \\
97.159 - @{text "change_yield: theory \<rightarrow> (T \<rightarrow> 'a * T) \<rightarrow> 'a * T"}
97.160 - \end{tabular}
97.161 -
97.162 - \begin{description}
97.163 -
97.164 - \item @{text get} retrieval of the current data.
97.165 -
97.166 - \item @{text change} update of current data (cached!)
97.167 - by giving a continuation.
97.168 -
97.169 - \item @{text change_yield} update with side result.
97.170 -
97.171 - \end{description}
97.172 -*}
97.173 -
97.174 -text {*
97.175 - \bigskip
97.176 -
97.177 - \emph{Happy proving, happy hacking!}
97.178 -*}
97.179 -
97.180 -end
98.1 --- a/doc-src/IsarAdvanced/Codegen/Thy/Program.thy Wed Mar 04 11:05:02 2009 +0100
98.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
98.3 @@ -1,534 +0,0 @@
98.4 -theory Program
98.5 -imports Introduction
98.6 -begin
98.7 -
98.8 -section {* Turning Theories into Programs \label{sec:program} *}
98.9 -
98.10 -subsection {* The @{text "Isabelle/HOL"} default setup *}
98.11 -
98.12 -text {*
98.13 - We have already seen how by default equations stemming from
98.14 - @{command definition}/@{command primrec}/@{command fun}
98.15 - statements are used for code generation. This default behaviour
98.16 - can be changed, e.g. by providing different code equations.
98.17 - All kinds of customisation shown in this section is \emph{safe}
98.18 - in the sense that the user does not have to worry about
98.19 - correctness -- all programs generatable that way are partially
98.20 - correct.
98.21 -*}
98.22 -
98.23 -subsection {* Selecting code equations *}
98.24 -
98.25 -text {*
98.26 - Coming back to our introductory example, we
98.27 - could provide an alternative code equations for @{const dequeue}
98.28 - explicitly:
98.29 -*}
98.30 -
98.31 -lemma %quote [code]:
98.32 - "dequeue (AQueue xs []) =
98.33 - (if xs = [] then (None, AQueue [] [])
98.34 - else dequeue (AQueue [] (rev xs)))"
98.35 - "dequeue (AQueue xs (y # ys)) =
98.36 - (Some y, AQueue xs ys)"
98.37 - by (cases xs, simp_all) (cases "rev xs", simp_all)
98.38 -
98.39 -text {*
98.40 - \noindent The annotation @{text "[code]"} is an @{text Isar}
98.41 - @{text attribute} which states that the given theorems should be
98.42 - considered as code equations for a @{text fun} statement --
98.43 - the corresponding constant is determined syntactically. The resulting code:
98.44 -*}
98.45 -
98.46 -text %quote {*@{code_stmts dequeue (consts) dequeue (Haskell)}*}
98.47 -
98.48 -text {*
98.49 - \noindent You may note that the equality test @{term "xs = []"} has been
98.50 - replaced by the predicate @{term "null xs"}. This is due to the default
98.51 - setup in the \qn{preprocessor} to be discussed further below (\secref{sec:preproc}).
98.52 -
98.53 - Changing the default constructor set of datatypes is also
98.54 - possible. See \secref{sec:datatypes} for an example.
98.55 -
98.56 - As told in \secref{sec:concept}, code generation is based
98.57 - on a structured collection of code theorems.
98.58 - For explorative purpose, this collection
98.59 - may be inspected using the @{command code_thms} command:
98.60 -*}
98.61 -
98.62 -code_thms %quote dequeue
98.63 -
98.64 -text {*
98.65 - \noindent prints a table with \emph{all} code equations
98.66 - for @{const dequeue}, including
98.67 - \emph{all} code equations those equations depend
98.68 - on recursively.
98.69 -
98.70 - Similarly, the @{command code_deps} command shows a graph
98.71 - visualising dependencies between code equations.
98.72 -*}
98.73 -
98.74 -subsection {* @{text class} and @{text instantiation} *}
98.75 -
98.76 -text {*
98.77 - Concerning type classes and code generation, let us examine an example
98.78 - from abstract algebra:
98.79 -*}
98.80 -
98.81 -class %quote semigroup =
98.82 - fixes mult :: "'a \<Rightarrow> 'a \<Rightarrow> 'a" (infixl "\<otimes>" 70)
98.83 - assumes assoc: "(x \<otimes> y) \<otimes> z = x \<otimes> (y \<otimes> z)"
98.84 -
98.85 -class %quote monoid = semigroup +
98.86 - fixes neutral :: 'a ("\<one>")
98.87 - assumes neutl: "\<one> \<otimes> x = x"
98.88 - and neutr: "x \<otimes> \<one> = x"
98.89 -
98.90 -instantiation %quote nat :: monoid
98.91 -begin
98.92 -
98.93 -primrec %quote mult_nat where
98.94 - "0 \<otimes> n = (0\<Colon>nat)"
98.95 - | "Suc m \<otimes> n = n + m \<otimes> n"
98.96 -
98.97 -definition %quote neutral_nat where
98.98 - "\<one> = Suc 0"
98.99 -
98.100 -lemma %quote add_mult_distrib:
98.101 - fixes n m q :: nat
98.102 - shows "(n + m) \<otimes> q = n \<otimes> q + m \<otimes> q"
98.103 - by (induct n) simp_all
98.104 -
98.105 -instance %quote proof
98.106 - fix m n q :: nat
98.107 - show "m \<otimes> n \<otimes> q = m \<otimes> (n \<otimes> q)"
98.108 - by (induct m) (simp_all add: add_mult_distrib)
98.109 - show "\<one> \<otimes> n = n"
98.110 - by (simp add: neutral_nat_def)
98.111 - show "m \<otimes> \<one> = m"
98.112 - by (induct m) (simp_all add: neutral_nat_def)
98.113 -qed
98.114 -
98.115 -end %quote
98.116 -
98.117 -text {*
98.118 - \noindent We define the natural operation of the natural numbers
98.119 - on monoids:
98.120 -*}
98.121 -
98.122 -primrec %quote (in monoid) pow :: "nat \<Rightarrow> 'a \<Rightarrow> 'a" where
98.123 - "pow 0 a = \<one>"
98.124 - | "pow (Suc n) a = a \<otimes> pow n a"
98.125 -
98.126 -text {*
98.127 - \noindent This we use to define the discrete exponentiation function:
98.128 -*}
98.129 -
98.130 -definition %quote bexp :: "nat \<Rightarrow> nat" where
98.131 - "bexp n = pow n (Suc (Suc 0))"
98.132 -
98.133 -text {*
98.134 - \noindent The corresponding code:
98.135 -*}
98.136 -
98.137 -text %quote {*@{code_stmts bexp (Haskell)}*}
98.138 -
98.139 -text {*
98.140 - \noindent This is a convenient place to show how explicit dictionary construction
98.141 - manifests in generated code (here, the same example in @{text SML}):
98.142 -*}
98.143 -
98.144 -text %quote {*@{code_stmts bexp (SML)}*}
98.145 -
98.146 -text {*
98.147 - \noindent Note the parameters with trailing underscore (@{verbatim "A_"})
98.148 - which are the dictionary parameters.
98.149 -*}
98.150 -
98.151 -subsection {* The preprocessor \label{sec:preproc} *}
98.152 -
98.153 -text {*
98.154 - Before selected function theorems are turned into abstract
98.155 - code, a chain of definitional transformation steps is carried
98.156 - out: \emph{preprocessing}. In essence, the preprocessor
98.157 - consists of two components: a \emph{simpset} and \emph{function transformers}.
98.158 -
98.159 - The \emph{simpset} allows to employ the full generality of the Isabelle
98.160 - simplifier. Due to the interpretation of theorems
98.161 - as code equations, rewrites are applied to the right
98.162 - hand side and the arguments of the left hand side of an
98.163 - equation, but never to the constant heading the left hand side.
98.164 - An important special case are \emph{inline theorems} which may be
98.165 - declared and undeclared using the
98.166 - \emph{code inline} or \emph{code inline del} attribute respectively.
98.167 -
98.168 - Some common applications:
98.169 -*}
98.170 -
98.171 -text_raw {*
98.172 - \begin{itemize}
98.173 -*}
98.174 -
98.175 -text {*
98.176 - \item replacing non-executable constructs by executable ones:
98.177 -*}
98.178 -
98.179 -lemma %quote [code inline]:
98.180 - "x \<in> set xs \<longleftrightarrow> x mem xs" by (induct xs) simp_all
98.181 -
98.182 -text {*
98.183 - \item eliminating superfluous constants:
98.184 -*}
98.185 -
98.186 -lemma %quote [code inline]:
98.187 - "1 = Suc 0" by simp
98.188 -
98.189 -text {*
98.190 - \item replacing executable but inconvenient constructs:
98.191 -*}
98.192 -
98.193 -lemma %quote [code inline]:
98.194 - "xs = [] \<longleftrightarrow> List.null xs" by (induct xs) simp_all
98.195 -
98.196 -text_raw {*
98.197 - \end{itemize}
98.198 -*}
98.199 -
98.200 -text {*
98.201 - \noindent \emph{Function transformers} provide a very general interface,
98.202 - transforming a list of function theorems to another
98.203 - list of function theorems, provided that neither the heading
98.204 - constant nor its type change. The @{term "0\<Colon>nat"} / @{const Suc}
98.205 - pattern elimination implemented in
98.206 - theory @{text Efficient_Nat} (see \secref{eff_nat}) uses this
98.207 - interface.
98.208 -
98.209 - \noindent The current setup of the preprocessor may be inspected using
98.210 - the @{command print_codesetup} command.
98.211 - @{command code_thms} provides a convenient
98.212 - mechanism to inspect the impact of a preprocessor setup
98.213 - on code equations.
98.214 -
98.215 - \begin{warn}
98.216 - The attribute \emph{code unfold}
98.217 - associated with the @{text "SML code generator"} also applies to
98.218 - the @{text "generic code generator"}:
98.219 - \emph{code unfold} implies \emph{code inline}.
98.220 - \end{warn}
98.221 -*}
98.222 -
98.223 -subsection {* Datatypes \label{sec:datatypes} *}
98.224 -
98.225 -text {*
98.226 - Conceptually, any datatype is spanned by a set of
98.227 - \emph{constructors} of type @{text "\<tau> = \<dots> \<Rightarrow> \<kappa> \<alpha>\<^isub>1 \<dots> \<alpha>\<^isub>n"} where @{text
98.228 - "{\<alpha>\<^isub>1, \<dots>, \<alpha>\<^isub>n}"} is exactly the set of \emph{all} type variables in
98.229 - @{text "\<tau>"}. The HOL datatype package by default registers any new
98.230 - datatype in the table of datatypes, which may be inspected using the
98.231 - @{command print_codesetup} command.
98.232 -
98.233 - In some cases, it is appropriate to alter or extend this table. As
98.234 - an example, we will develop an alternative representation of the
98.235 - queue example given in \secref{sec:intro}. The amortised
98.236 - representation is convenient for generating code but exposes its
98.237 - \qt{implementation} details, which may be cumbersome when proving
98.238 - theorems about it. Therefore, here a simple, straightforward
98.239 - representation of queues:
98.240 -*}
98.241 -
98.242 -datatype %quote 'a queue = Queue "'a list"
98.243 -
98.244 -definition %quote empty :: "'a queue" where
98.245 - "empty = Queue []"
98.246 -
98.247 -primrec %quote enqueue :: "'a \<Rightarrow> 'a queue \<Rightarrow> 'a queue" where
98.248 - "enqueue x (Queue xs) = Queue (xs @ [x])"
98.249 -
98.250 -fun %quote dequeue :: "'a queue \<Rightarrow> 'a option \<times> 'a queue" where
98.251 - "dequeue (Queue []) = (None, Queue [])"
98.252 - | "dequeue (Queue (x # xs)) = (Some x, Queue xs)"
98.253 -
98.254 -text {*
98.255 - \noindent This we can use directly for proving; for executing,
98.256 - we provide an alternative characterisation:
98.257 -*}
98.258 -
98.259 -definition %quote AQueue :: "'a list \<Rightarrow> 'a list \<Rightarrow> 'a queue" where
98.260 - "AQueue xs ys = Queue (ys @ rev xs)"
98.261 -
98.262 -code_datatype %quote AQueue
98.263 -
98.264 -text {*
98.265 - \noindent Here we define a \qt{constructor} @{const "AQueue"} which
98.266 - is defined in terms of @{text "Queue"} and interprets its arguments
98.267 - according to what the \emph{content} of an amortised queue is supposed
98.268 - to be. Equipped with this, we are able to prove the following equations
98.269 - for our primitive queue operations which \qt{implement} the simple
98.270 - queues in an amortised fashion:
98.271 -*}
98.272 -
98.273 -lemma %quote empty_AQueue [code]:
98.274 - "empty = AQueue [] []"
98.275 - unfolding AQueue_def empty_def by simp
98.276 -
98.277 -lemma %quote enqueue_AQueue [code]:
98.278 - "enqueue x (AQueue xs ys) = AQueue (x # xs) ys"
98.279 - unfolding AQueue_def by simp
98.280 -
98.281 -lemma %quote dequeue_AQueue [code]:
98.282 - "dequeue (AQueue xs []) =
98.283 - (if xs = [] then (None, AQueue [] [])
98.284 - else dequeue (AQueue [] (rev xs)))"
98.285 - "dequeue (AQueue xs (y # ys)) = (Some y, AQueue xs ys)"
98.286 - unfolding AQueue_def by simp_all
98.287 -
98.288 -text {*
98.289 - \noindent For completeness, we provide a substitute for the
98.290 - @{text case} combinator on queues:
98.291 -*}
98.292 -
98.293 -definition %quote
98.294 - aqueue_case_def: "aqueue_case = queue_case"
98.295 -
98.296 -lemma %quote aqueue_case [code, code inline]:
98.297 - "queue_case = aqueue_case"
98.298 - unfolding aqueue_case_def ..
98.299 -
98.300 -lemma %quote case_AQueue [code]:
98.301 - "aqueue_case f (AQueue xs ys) = f (ys @ rev xs)"
98.302 - unfolding aqueue_case_def AQueue_def by simp
98.303 -
98.304 -text {*
98.305 - \noindent The resulting code looks as expected:
98.306 -*}
98.307 -
98.308 -text %quote {*@{code_stmts empty enqueue dequeue (SML)}*}
98.309 -
98.310 -text {*
98.311 - \noindent From this example, it can be glimpsed that using own
98.312 - constructor sets is a little delicate since it changes the set of
98.313 - valid patterns for values of that type. Without going into much
98.314 - detail, here some practical hints:
98.315 -
98.316 - \begin{itemize}
98.317 -
98.318 - \item When changing the constructor set for datatypes, take care
98.319 - to provide an alternative for the @{text case} combinator
98.320 - (e.g.~by replacing it using the preprocessor).
98.321 -
98.322 - \item Values in the target language need not to be normalised --
98.323 - different values in the target language may represent the same
98.324 - value in the logic.
98.325 -
98.326 - \item Usually, a good methodology to deal with the subtleties of
98.327 - pattern matching is to see the type as an abstract type: provide
98.328 - a set of operations which operate on the concrete representation
98.329 - of the type, and derive further operations by combinations of
98.330 - these primitive ones, without relying on a particular
98.331 - representation.
98.332 -
98.333 - \end{itemize}
98.334 -*}
98.335 -
98.336 -
98.337 -subsection {* Equality and wellsortedness *}
98.338 -
98.339 -text {*
98.340 - Surely you have already noticed how equality is treated
98.341 - by the code generator:
98.342 -*}
98.343 -
98.344 -primrec %quote collect_duplicates :: "'a list \<Rightarrow> 'a list \<Rightarrow> 'a list \<Rightarrow> 'a list" where
98.345 - "collect_duplicates xs ys [] = xs"
98.346 - | "collect_duplicates xs ys (z#zs) = (if z \<in> set xs
98.347 - then if z \<in> set ys
98.348 - then collect_duplicates xs ys zs
98.349 - else collect_duplicates xs (z#ys) zs
98.350 - else collect_duplicates (z#xs) (z#ys) zs)"
98.351 -
98.352 -text {*
98.353 - \noindent The membership test during preprocessing is rewritten,
98.354 - resulting in @{const List.member}, which itself
98.355 - performs an explicit equality check.
98.356 -*}
98.357 -
98.358 -text %quote {*@{code_stmts collect_duplicates (SML)}*}
98.359 -
98.360 -text {*
98.361 - \noindent Obviously, polymorphic equality is implemented the Haskell
98.362 - way using a type class. How is this achieved? HOL introduces
98.363 - an explicit class @{class eq} with a corresponding operation
98.364 - @{const eq_class.eq} such that @{thm eq [no_vars]}.
98.365 - The preprocessing framework does the rest by propagating the
98.366 - @{class eq} constraints through all dependent code equations.
98.367 - For datatypes, instances of @{class eq} are implicitly derived
98.368 - when possible. For other types, you may instantiate @{text eq}
98.369 - manually like any other type class.
98.370 -
98.371 - Though this @{text eq} class is designed to get rarely in
98.372 - the way, a subtlety
98.373 - enters the stage when definitions of overloaded constants
98.374 - are dependent on operational equality. For example, let
98.375 - us define a lexicographic ordering on tuples
98.376 - (also see theory @{theory Product_ord}):
98.377 -*}
98.378 -
98.379 -instantiation %quote "*" :: (order, order) order
98.380 -begin
98.381 -
98.382 -definition %quote [code del]:
98.383 - "x \<le> y \<longleftrightarrow> fst x < fst y \<or> fst x = fst y \<and> snd x \<le> snd y"
98.384 -
98.385 -definition %quote [code del]:
98.386 - "x < y \<longleftrightarrow> fst x < fst y \<or> fst x = fst y \<and> snd x < snd y"
98.387 -
98.388 -instance %quote proof
98.389 -qed (auto simp: less_eq_prod_def less_prod_def intro: order_less_trans)
98.390 -
98.391 -end %quote
98.392 -
98.393 -lemma %quote order_prod [code]:
98.394 - "(x1 \<Colon> 'a\<Colon>order, y1 \<Colon> 'b\<Colon>order) < (x2, y2) \<longleftrightarrow>
98.395 - x1 < x2 \<or> x1 = x2 \<and> y1 < y2"
98.396 - "(x1 \<Colon> 'a\<Colon>order, y1 \<Colon> 'b\<Colon>order) \<le> (x2, y2) \<longleftrightarrow>
98.397 - x1 < x2 \<or> x1 = x2 \<and> y1 \<le> y2"
98.398 - by (simp_all add: less_prod_def less_eq_prod_def)
98.399 -
98.400 -text {*
98.401 - \noindent Then code generation will fail. Why? The definition
98.402 - of @{term "op \<le>"} depends on equality on both arguments,
98.403 - which are polymorphic and impose an additional @{class eq}
98.404 - class constraint, which the preprocessor does not propagate
98.405 - (for technical reasons).
98.406 -
98.407 - The solution is to add @{class eq} explicitly to the first sort arguments in the
98.408 - code theorems:
98.409 -*}
98.410 -
98.411 -lemma %quote order_prod_code [code]:
98.412 - "(x1 \<Colon> 'a\<Colon>{order, eq}, y1 \<Colon> 'b\<Colon>order) < (x2, y2) \<longleftrightarrow>
98.413 - x1 < x2 \<or> x1 = x2 \<and> y1 < y2"
98.414 - "(x1 \<Colon> 'a\<Colon>{order, eq}, y1 \<Colon> 'b\<Colon>order) \<le> (x2, y2) \<longleftrightarrow>
98.415 - x1 < x2 \<or> x1 = x2 \<and> y1 \<le> y2"
98.416 - by (simp_all add: less_prod_def less_eq_prod_def)
98.417 -
98.418 -text {*
98.419 - \noindent Then code generation succeeds:
98.420 -*}
98.421 -
98.422 -text %quote {*@{code_stmts "op \<le> \<Colon> _ \<times> _ \<Rightarrow> _ \<times> _ \<Rightarrow> bool" (SML)}*}
98.423 -
98.424 -text {*
98.425 - In some cases, the automatically derived code equations
98.426 - for equality on a particular type may not be appropriate.
98.427 - As example, watch the following datatype representing
98.428 - monomorphic parametric types (where type constructors
98.429 - are referred to by natural numbers):
98.430 -*}
98.431 -
98.432 -datatype %quote monotype = Mono nat "monotype list"
98.433 -(*<*)
98.434 -lemma monotype_eq:
98.435 - "eq_class.eq (Mono tyco1 typargs1) (Mono tyco2 typargs2) \<equiv>
98.436 - eq_class.eq tyco1 tyco2 \<and> eq_class.eq typargs1 typargs2" by (simp add: eq)
98.437 -(*>*)
98.438 -
98.439 -text {*
98.440 - \noindent Then code generation for SML would fail with a message
98.441 - that the generated code contains illegal mutual dependencies:
98.442 - the theorem @{thm monotype_eq [no_vars]} already requires the
98.443 - instance @{text "monotype \<Colon> eq"}, which itself requires
98.444 - @{thm monotype_eq [no_vars]}; Haskell has no problem with mutually
98.445 - recursive @{text instance} and @{text function} definitions,
98.446 - but the SML serialiser does not support this.
98.447 -
98.448 - In such cases, you have to provide your own equality equations
98.449 - involving auxiliary constants. In our case,
98.450 - @{const [show_types] list_all2} can do the job:
98.451 -*}
98.452 -
98.453 -lemma %quote monotype_eq_list_all2 [code]:
98.454 - "eq_class.eq (Mono tyco1 typargs1) (Mono tyco2 typargs2) \<longleftrightarrow>
98.455 - eq_class.eq tyco1 tyco2 \<and> list_all2 eq_class.eq typargs1 typargs2"
98.456 - by (simp add: eq list_all2_eq [symmetric])
98.457 -
98.458 -text {*
98.459 - \noindent does not depend on instance @{text "monotype \<Colon> eq"}:
98.460 -*}
98.461 -
98.462 -text %quote {*@{code_stmts "eq_class.eq :: monotype \<Rightarrow> monotype \<Rightarrow> bool" (SML)}*}
98.463 -
98.464 -
98.465 -subsection {* Explicit partiality *}
98.466 -
98.467 -text {*
98.468 - Partiality usually enters the game by partial patterns, as
98.469 - in the following example, again for amortised queues:
98.470 -*}
98.471 -
98.472 -definition %quote strict_dequeue :: "'a queue \<Rightarrow> 'a \<times> 'a queue" where
98.473 - "strict_dequeue q = (case dequeue q
98.474 - of (Some x, q') \<Rightarrow> (x, q'))"
98.475 -
98.476 -lemma %quote strict_dequeue_AQueue [code]:
98.477 - "strict_dequeue (AQueue xs (y # ys)) = (y, AQueue xs ys)"
98.478 - "strict_dequeue (AQueue xs []) =
98.479 - (case rev xs of y # ys \<Rightarrow> (y, AQueue [] ys))"
98.480 - by (simp_all add: strict_dequeue_def dequeue_AQueue split: list.splits)
98.481 -
98.482 -text {*
98.483 - \noindent In the corresponding code, there is no equation
98.484 - for the pattern @{term "AQueue [] []"}:
98.485 -*}
98.486 -
98.487 -text %quote {*@{code_stmts strict_dequeue (consts) strict_dequeue (Haskell)}*}
98.488 -
98.489 -text {*
98.490 - \noindent In some cases it is desirable to have this
98.491 - pseudo-\qt{partiality} more explicitly, e.g.~as follows:
98.492 -*}
98.493 -
98.494 -axiomatization %quote empty_queue :: 'a
98.495 -
98.496 -definition %quote strict_dequeue' :: "'a queue \<Rightarrow> 'a \<times> 'a queue" where
98.497 - "strict_dequeue' q = (case dequeue q of (Some x, q') \<Rightarrow> (x, q') | _ \<Rightarrow> empty_queue)"
98.498 -
98.499 -lemma %quote strict_dequeue'_AQueue [code]:
98.500 - "strict_dequeue' (AQueue xs []) = (if xs = [] then empty_queue
98.501 - else strict_dequeue' (AQueue [] (rev xs)))"
98.502 - "strict_dequeue' (AQueue xs (y # ys)) =
98.503 - (y, AQueue xs ys)"
98.504 - by (simp_all add: strict_dequeue'_def dequeue_AQueue split: list.splits)
98.505 -
98.506 -text {*
98.507 - Observe that on the right hand side of the definition of @{const
98.508 - "strict_dequeue'"} the constant @{const empty_queue} occurs
98.509 - which is unspecified.
98.510 -
98.511 - Normally, if constants without any code equations occur in a
98.512 - program, the code generator complains (since in most cases this is
98.513 - not what the user expects). But such constants can also be thought
98.514 - of as function definitions with no equations which always fail,
98.515 - since there is never a successful pattern match on the left hand
98.516 - side. In order to categorise a constant into that category
98.517 - explicitly, use @{command "code_abort"}:
98.518 -*}
98.519 -
98.520 -code_abort %quote empty_queue
98.521 -
98.522 -text {*
98.523 - \noindent Then the code generator will just insert an error or
98.524 - exception at the appropriate position:
98.525 -*}
98.526 -
98.527 -text %quote {*@{code_stmts strict_dequeue' (consts) empty_queue strict_dequeue' (Haskell)}*}
98.528 -
98.529 -text {*
98.530 - \noindent This feature however is rarely needed in practice.
98.531 - Note also that the @{text HOL} default setup already declares
98.532 - @{const undefined} as @{command "code_abort"}, which is most
98.533 - likely to be used in such situations.
98.534 -*}
98.535 -
98.536 -end
98.537 -
98.538 \ No newline at end of file
99.1 --- a/doc-src/IsarAdvanced/Codegen/Thy/ROOT.ML Wed Mar 04 11:05:02 2009 +0100
99.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
99.3 @@ -1,11 +0,0 @@
99.4 -
99.5 -(* $Id$ *)
99.6 -
99.7 -no_document use_thy "Setup";
99.8 -no_document use_thys ["Efficient_Nat"];
99.9 -
99.10 -use_thy "Introduction";
99.11 -use_thy "Program";
99.12 -use_thy "Adaption";
99.13 -use_thy "Further";
99.14 -use_thy "ML";
100.1 --- a/doc-src/IsarAdvanced/Codegen/Thy/Setup.thy Wed Mar 04 11:05:02 2009 +0100
100.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
100.3 @@ -1,12 +0,0 @@
100.4 -theory Setup
100.5 -imports Complex_Main
100.6 -uses "../../../antiquote_setup.ML" "../../../more_antiquote.ML"
100.7 -begin
100.8 -
100.9 -ML {* no_document use_thys
100.10 - ["Efficient_Nat", "Code_Char_chr", "Product_ord", "~~/src/HOL/Imperative_HOL/Imperative_HOL",
100.11 - "~~/src/HOL/Reflection/Ferrack"] *}
100.12 -
100.13 -ML_val {* Code_Target.code_width := 74 *}
100.14 -
100.15 -end
101.1 --- a/doc-src/IsarAdvanced/Codegen/Thy/document/Adaption.tex Wed Mar 04 11:05:02 2009 +0100
101.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
101.3 @@ -1,679 +0,0 @@
101.4 -%
101.5 -\begin{isabellebody}%
101.6 -\def\isabellecontext{Adaption}%
101.7 -%
101.8 -\isadelimtheory
101.9 -%
101.10 -\endisadelimtheory
101.11 -%
101.12 -\isatagtheory
101.13 -\isacommand{theory}\isamarkupfalse%
101.14 -\ Adaption\isanewline
101.15 -\isakeyword{imports}\ Setup\isanewline
101.16 -\isakeyword{begin}%
101.17 -\endisatagtheory
101.18 -{\isafoldtheory}%
101.19 -%
101.20 -\isadelimtheory
101.21 -\isanewline
101.22 -%
101.23 -\endisadelimtheory
101.24 -%
101.25 -\isadeliminvisible
101.26 -\isanewline
101.27 -%
101.28 -\endisadeliminvisible
101.29 -%
101.30 -\isataginvisible
101.31 -\isacommand{setup}\isamarkupfalse%
101.32 -\ {\isacharverbatimopen}\ Code{\isacharunderscore}Target{\isachardot}extend{\isacharunderscore}target\ {\isacharparenleft}{\isachardoublequote}{\isasymSML}{\isachardoublequote}{\isacharcomma}\ {\isacharparenleft}{\isachardoublequote}SML{\isachardoublequote}{\isacharcomma}\ K\ I{\isacharparenright}{\isacharparenright}\ {\isacharverbatimclose}%
101.33 -\endisataginvisible
101.34 -{\isafoldinvisible}%
101.35 -%
101.36 -\isadeliminvisible
101.37 -%
101.38 -\endisadeliminvisible
101.39 -%
101.40 -\isamarkupsection{Adaption to target languages \label{sec:adaption}%
101.41 -}
101.42 -\isamarkuptrue%
101.43 -%
101.44 -\isamarkupsubsection{Adapting code generation%
101.45 -}
101.46 -\isamarkuptrue%
101.47 -%
101.48 -\begin{isamarkuptext}%
101.49 -The aspects of code generation introduced so far have two aspects
101.50 - in common:
101.51 -
101.52 - \begin{itemize}
101.53 - \item They act uniformly, without reference to a specific
101.54 - target language.
101.55 - \item They are \emph{safe} in the sense that as long as you trust
101.56 - the code generator meta theory and implementation, you cannot
101.57 - produce programs that yield results which are not derivable
101.58 - in the logic.
101.59 - \end{itemize}
101.60 -
101.61 - \noindent In this section we will introduce means to \emph{adapt} the serialiser
101.62 - to a specific target language, i.e.~to print program fragments
101.63 - in a way which accommodates \qt{already existing} ingredients of
101.64 - a target language environment, for three reasons:
101.65 -
101.66 - \begin{itemize}
101.67 - \item improving readability and aesthetics of generated code
101.68 - \item gaining efficiency
101.69 - \item interface with language parts which have no direct counterpart
101.70 - in \isa{HOL} (say, imperative data structures)
101.71 - \end{itemize}
101.72 -
101.73 - \noindent Generally, you should avoid using those features yourself
101.74 - \emph{at any cost}:
101.75 -
101.76 - \begin{itemize}
101.77 - \item The safe configuration methods act uniformly on every target language,
101.78 - whereas for adaption you have to treat each target language separate.
101.79 - \item Application is extremely tedious since there is no abstraction
101.80 - which would allow for a static check, making it easy to produce garbage.
101.81 - \item More or less subtle errors can be introduced unconsciously.
101.82 - \end{itemize}
101.83 -
101.84 - \noindent However, even if you ought refrain from setting up adaption
101.85 - yourself, already the \isa{HOL} comes with some reasonable default
101.86 - adaptions (say, using target language list syntax). There also some
101.87 - common adaption cases which you can setup by importing particular
101.88 - library theories. In order to understand these, we provide some clues here;
101.89 - these however are not supposed to replace a careful study of the sources.%
101.90 -\end{isamarkuptext}%
101.91 -\isamarkuptrue%
101.92 -%
101.93 -\isamarkupsubsection{The adaption principle%
101.94 -}
101.95 -\isamarkuptrue%
101.96 -%
101.97 -\begin{isamarkuptext}%
101.98 -The following figure illustrates what \qt{adaption} is conceptually
101.99 - supposed to be:
101.100 -
101.101 - \begin{figure}[here]
101.102 - \begin{tikzpicture}[scale = 0.5]
101.103 - \tikzstyle water=[color = blue, thick]
101.104 - \tikzstyle ice=[color = black, very thick, cap = round, join = round, fill = white]
101.105 - \tikzstyle process=[color = green, semithick, ->]
101.106 - \tikzstyle adaption=[color = red, semithick, ->]
101.107 - \tikzstyle target=[color = black]
101.108 - \foreach \x in {0, ..., 24}
101.109 - \draw[style=water] (\x, 0.25) sin + (0.25, 0.25) cos + (0.25, -0.25) sin
101.110 - + (0.25, -0.25) cos + (0.25, 0.25);
101.111 - \draw[style=ice] (1, 0) --
101.112 - (3, 6) node[above, fill=white] {logic} -- (5, 0) -- cycle;
101.113 - \draw[style=ice] (9, 0) --
101.114 - (11, 6) node[above, fill=white] {intermediate language} -- (13, 0) -- cycle;
101.115 - \draw[style=ice] (15, -6) --
101.116 - (19, 6) node[above, fill=white] {target language} -- (23, -6) -- cycle;
101.117 - \draw[style=process]
101.118 - (3.5, 3) .. controls (7, 5) .. node[fill=white] {translation} (10.5, 3);
101.119 - \draw[style=process]
101.120 - (11.5, 3) .. controls (15, 5) .. node[fill=white] (serialisation) {serialisation} (18.5, 3);
101.121 - \node (adaption) at (11, -2) [style=adaption] {adaption};
101.122 - \node at (19, 3) [rotate=90] {generated};
101.123 - \node at (19.5, -5) {language};
101.124 - \node at (19.5, -3) {library};
101.125 - \node (includes) at (19.5, -1) {includes};
101.126 - \node (reserved) at (16.5, -3) [rotate=72] {reserved}; % proper 71.57
101.127 - \draw[style=process]
101.128 - (includes) -- (serialisation);
101.129 - \draw[style=process]
101.130 - (reserved) -- (serialisation);
101.131 - \draw[style=adaption]
101.132 - (adaption) -- (serialisation);
101.133 - \draw[style=adaption]
101.134 - (adaption) -- (includes);
101.135 - \draw[style=adaption]
101.136 - (adaption) -- (reserved);
101.137 - \end{tikzpicture}
101.138 - \caption{The adaption principle}
101.139 - \label{fig:adaption}
101.140 - \end{figure}
101.141 -
101.142 - \noindent In the tame view, code generation acts as broker between
101.143 - \isa{logic}, \isa{intermediate\ language} and
101.144 - \isa{target\ language} by means of \isa{translation} and
101.145 - \isa{serialisation}; for the latter, the serialiser has to observe
101.146 - the structure of the \isa{language} itself plus some \isa{reserved}
101.147 - keywords which have to be avoided for generated code.
101.148 - However, if you consider \isa{adaption} mechanisms, the code generated
101.149 - by the serializer is just the tip of the iceberg:
101.150 -
101.151 - \begin{itemize}
101.152 - \item \isa{serialisation} can be \emph{parametrised} such that
101.153 - logical entities are mapped to target-specific ones
101.154 - (e.g. target-specific list syntax,
101.155 - see also \secref{sec:adaption_mechanisms})
101.156 - \item Such parametrisations can involve references to a
101.157 - target-specific standard \isa{library} (e.g. using
101.158 - the \isa{Haskell} \verb|Maybe| type instead
101.159 - of the \isa{HOL} \isa{option} type);
101.160 - if such are used, the corresponding identifiers
101.161 - (in our example, \verb|Maybe|, \verb|Nothing|
101.162 - and \verb|Just|) also have to be considered \isa{reserved}.
101.163 - \item Even more, the user can enrich the library of the
101.164 - target-language by providing code snippets
101.165 - (\qt{\isa{includes}}) which are prepended to
101.166 - any generated code (see \secref{sec:include}); this typically
101.167 - also involves further \isa{reserved} identifiers.
101.168 - \end{itemize}
101.169 -
101.170 - \noindent As figure \ref{fig:adaption} illustrates, all these adaption mechanisms
101.171 - have to act consistently; it is at the discretion of the user
101.172 - to take care for this.%
101.173 -\end{isamarkuptext}%
101.174 -\isamarkuptrue%
101.175 -%
101.176 -\isamarkupsubsection{Common adaption patterns%
101.177 -}
101.178 -\isamarkuptrue%
101.179 -%
101.180 -\begin{isamarkuptext}%
101.181 -The \hyperlink{theory.HOL}{\mbox{\isa{HOL}}} \hyperlink{theory.Main}{\mbox{\isa{Main}}} theory already provides a code
101.182 - generator setup
101.183 - which should be suitable for most applications. Common extensions
101.184 - and modifications are available by certain theories of the \isa{HOL}
101.185 - library; beside being useful in applications, they may serve
101.186 - as a tutorial for customising the code generator setup (see below
101.187 - \secref{sec:adaption_mechanisms}).
101.188 -
101.189 - \begin{description}
101.190 -
101.191 - \item[\hyperlink{theory.Code-Integer}{\mbox{\isa{Code{\isacharunderscore}Integer}}}] represents \isa{HOL} integers by big
101.192 - integer literals in target languages.
101.193 - \item[\hyperlink{theory.Code-Char}{\mbox{\isa{Code{\isacharunderscore}Char}}}] represents \isa{HOL} characters by
101.194 - character literals in target languages.
101.195 - \item[\hyperlink{theory.Code-Char-chr}{\mbox{\isa{Code{\isacharunderscore}Char{\isacharunderscore}chr}}}] like \isa{Code{\isacharunderscore}Char},
101.196 - but also offers treatment of character codes; includes
101.197 - \hyperlink{theory.Code-Char}{\mbox{\isa{Code{\isacharunderscore}Char}}}.
101.198 - \item[\hyperlink{theory.Efficient-Nat}{\mbox{\isa{Efficient{\isacharunderscore}Nat}}}] \label{eff_nat} implements natural numbers by integers,
101.199 - which in general will result in higher efficiency; pattern
101.200 - matching with \isa{{\isadigit{0}}} / \isa{Suc}
101.201 - is eliminated; includes \hyperlink{theory.Code-Integer}{\mbox{\isa{Code{\isacharunderscore}Integer}}}
101.202 - and \hyperlink{theory.Code-Index}{\mbox{\isa{Code{\isacharunderscore}Index}}}.
101.203 - \item[\hyperlink{theory.Code-Index}{\mbox{\isa{Code{\isacharunderscore}Index}}}] provides an additional datatype
101.204 - \isa{index} which is mapped to target-language built-in integers.
101.205 - Useful for code setups which involve e.g. indexing of
101.206 - target-language arrays.
101.207 - \item[\hyperlink{theory.Code-Message}{\mbox{\isa{Code{\isacharunderscore}Message}}}] provides an additional datatype
101.208 - \isa{message{\isacharunderscore}string} which is isomorphic to strings;
101.209 - \isa{message{\isacharunderscore}string}s are mapped to target-language strings.
101.210 - Useful for code setups which involve e.g. printing (error) messages.
101.211 -
101.212 - \end{description}
101.213 -
101.214 - \begin{warn}
101.215 - When importing any of these theories, they should form the last
101.216 - items in an import list. Since these theories adapt the
101.217 - code generator setup in a non-conservative fashion,
101.218 - strange effects may occur otherwise.
101.219 - \end{warn}%
101.220 -\end{isamarkuptext}%
101.221 -\isamarkuptrue%
101.222 -%
101.223 -\isamarkupsubsection{Parametrising serialisation \label{sec:adaption_mechanisms}%
101.224 -}
101.225 -\isamarkuptrue%
101.226 -%
101.227 -\begin{isamarkuptext}%
101.228 -Consider the following function and its corresponding
101.229 - SML code:%
101.230 -\end{isamarkuptext}%
101.231 -\isamarkuptrue%
101.232 -%
101.233 -\isadelimquote
101.234 -%
101.235 -\endisadelimquote
101.236 -%
101.237 -\isatagquote
101.238 -\isacommand{primrec}\isamarkupfalse%
101.239 -\ in{\isacharunderscore}interval\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymtimes}\ nat\ {\isasymRightarrow}\ nat\ {\isasymRightarrow}\ bool{\isachardoublequoteclose}\ \isakeyword{where}\isanewline
101.240 -\ \ {\isachardoublequoteopen}in{\isacharunderscore}interval\ {\isacharparenleft}k{\isacharcomma}\ l{\isacharparenright}\ n\ {\isasymlongleftrightarrow}\ k\ {\isasymle}\ n\ {\isasymand}\ n\ {\isasymle}\ l{\isachardoublequoteclose}%
101.241 -\endisatagquote
101.242 -{\isafoldquote}%
101.243 -%
101.244 -\isadelimquote
101.245 -%
101.246 -\endisadelimquote
101.247 -%
101.248 -\isadeliminvisible
101.249 -%
101.250 -\endisadeliminvisible
101.251 -%
101.252 -\isataginvisible
101.253 -%
101.254 -\endisataginvisible
101.255 -{\isafoldinvisible}%
101.256 -%
101.257 -\isadeliminvisible
101.258 -%
101.259 -\endisadeliminvisible
101.260 -%
101.261 -\isadelimquote
101.262 -%
101.263 -\endisadelimquote
101.264 -%
101.265 -\isatagquote
101.266 -%
101.267 -\begin{isamarkuptext}%
101.268 -\isatypewriter%
101.269 -\noindent%
101.270 -\hspace*{0pt}structure Example = \\
101.271 -\hspace*{0pt}struct\\
101.272 -\hspace*{0pt}\\
101.273 -\hspace*{0pt}datatype nat = Suc of nat | Zero{\char95}nat;\\
101.274 -\hspace*{0pt}\\
101.275 -\hspace*{0pt}datatype boola = False | True;\\
101.276 -\hspace*{0pt}\\
101.277 -\hspace*{0pt}fun anda x True = x\\
101.278 -\hspace*{0pt} ~| anda x False = False\\
101.279 -\hspace*{0pt} ~| anda True x = x\\
101.280 -\hspace*{0pt} ~| anda False x = False;\\
101.281 -\hspace*{0pt}\\
101.282 -\hspace*{0pt}fun less{\char95}nat m (Suc n) = less{\char95}eq{\char95}nat m n\\
101.283 -\hspace*{0pt} ~| less{\char95}nat n Zero{\char95}nat = False\\
101.284 -\hspace*{0pt}and less{\char95}eq{\char95}nat (Suc m) n = less{\char95}nat m n\\
101.285 -\hspace*{0pt} ~| less{\char95}eq{\char95}nat Zero{\char95}nat n = True;\\
101.286 -\hspace*{0pt}\\
101.287 -\hspace*{0pt}fun in{\char95}interval (k,~l) n = anda (less{\char95}eq{\char95}nat k n) (less{\char95}eq{\char95}nat n l);\\
101.288 -\hspace*{0pt}\\
101.289 -\hspace*{0pt}end;~(*struct Example*)%
101.290 -\end{isamarkuptext}%
101.291 -\isamarkuptrue%
101.292 -%
101.293 -\endisatagquote
101.294 -{\isafoldquote}%
101.295 -%
101.296 -\isadelimquote
101.297 -%
101.298 -\endisadelimquote
101.299 -%
101.300 -\begin{isamarkuptext}%
101.301 -\noindent Though this is correct code, it is a little bit unsatisfactory:
101.302 - boolean values and operators are materialised as distinguished
101.303 - entities with have nothing to do with the SML-built-in notion
101.304 - of \qt{bool}. This results in less readable code;
101.305 - additionally, eager evaluation may cause programs to
101.306 - loop or break which would perfectly terminate when
101.307 - the existing SML \verb|bool| would be used. To map
101.308 - the HOL \isa{bool} on SML \verb|bool|, we may use
101.309 - \qn{custom serialisations}:%
101.310 -\end{isamarkuptext}%
101.311 -\isamarkuptrue%
101.312 -%
101.313 -\isadelimquotett
101.314 -%
101.315 -\endisadelimquotett
101.316 -%
101.317 -\isatagquotett
101.318 -\isacommand{code{\isacharunderscore}type}\isamarkupfalse%
101.319 -\ bool\isanewline
101.320 -\ \ {\isacharparenleft}SML\ {\isachardoublequoteopen}bool{\isachardoublequoteclose}{\isacharparenright}\isanewline
101.321 -\isacommand{code{\isacharunderscore}const}\isamarkupfalse%
101.322 -\ True\ \isakeyword{and}\ False\ \isakeyword{and}\ {\isachardoublequoteopen}op\ {\isasymand}{\isachardoublequoteclose}\isanewline
101.323 -\ \ {\isacharparenleft}SML\ {\isachardoublequoteopen}true{\isachardoublequoteclose}\ \isakeyword{and}\ {\isachardoublequoteopen}false{\isachardoublequoteclose}\ \isakeyword{and}\ {\isachardoublequoteopen}{\isacharunderscore}\ andalso\ {\isacharunderscore}{\isachardoublequoteclose}{\isacharparenright}%
101.324 -\endisatagquotett
101.325 -{\isafoldquotett}%
101.326 -%
101.327 -\isadelimquotett
101.328 -%
101.329 -\endisadelimquotett
101.330 -%
101.331 -\begin{isamarkuptext}%
101.332 -\noindent The \hyperlink{command.code-type}{\mbox{\isa{\isacommand{code{\isacharunderscore}type}}}} command takes a type constructor
101.333 - as arguments together with a list of custom serialisations.
101.334 - Each custom serialisation starts with a target language
101.335 - identifier followed by an expression, which during
101.336 - code serialisation is inserted whenever the type constructor
101.337 - would occur. For constants, \hyperlink{command.code-const}{\mbox{\isa{\isacommand{code{\isacharunderscore}const}}}} implements
101.338 - the corresponding mechanism. Each ``\verb|_|'' in
101.339 - a serialisation expression is treated as a placeholder
101.340 - for the type constructor's (the constant's) arguments.%
101.341 -\end{isamarkuptext}%
101.342 -\isamarkuptrue%
101.343 -%
101.344 -\isadelimquote
101.345 -%
101.346 -\endisadelimquote
101.347 -%
101.348 -\isatagquote
101.349 -%
101.350 -\begin{isamarkuptext}%
101.351 -\isatypewriter%
101.352 -\noindent%
101.353 -\hspace*{0pt}structure Example = \\
101.354 -\hspace*{0pt}struct\\
101.355 -\hspace*{0pt}\\
101.356 -\hspace*{0pt}datatype nat = Suc of nat | Zero{\char95}nat;\\
101.357 -\hspace*{0pt}\\
101.358 -\hspace*{0pt}fun less{\char95}nat m (Suc n) = less{\char95}eq{\char95}nat m n\\
101.359 -\hspace*{0pt} ~| less{\char95}nat n Zero{\char95}nat = false\\
101.360 -\hspace*{0pt}and less{\char95}eq{\char95}nat (Suc m) n = less{\char95}nat m n\\
101.361 -\hspace*{0pt} ~| less{\char95}eq{\char95}nat Zero{\char95}nat n = true;\\
101.362 -\hspace*{0pt}\\
101.363 -\hspace*{0pt}fun in{\char95}interval (k,~l) n = (less{\char95}eq{\char95}nat k n) andalso (less{\char95}eq{\char95}nat n l);\\
101.364 -\hspace*{0pt}\\
101.365 -\hspace*{0pt}end;~(*struct Example*)%
101.366 -\end{isamarkuptext}%
101.367 -\isamarkuptrue%
101.368 -%
101.369 -\endisatagquote
101.370 -{\isafoldquote}%
101.371 -%
101.372 -\isadelimquote
101.373 -%
101.374 -\endisadelimquote
101.375 -%
101.376 -\begin{isamarkuptext}%
101.377 -\noindent This still is not perfect: the parentheses
101.378 - around the \qt{andalso} expression are superfluous.
101.379 - Though the serialiser
101.380 - by no means attempts to imitate the rich Isabelle syntax
101.381 - framework, it provides some common idioms, notably
101.382 - associative infixes with precedences which may be used here:%
101.383 -\end{isamarkuptext}%
101.384 -\isamarkuptrue%
101.385 -%
101.386 -\isadelimquotett
101.387 -%
101.388 -\endisadelimquotett
101.389 -%
101.390 -\isatagquotett
101.391 -\isacommand{code{\isacharunderscore}const}\isamarkupfalse%
101.392 -\ {\isachardoublequoteopen}op\ {\isasymand}{\isachardoublequoteclose}\isanewline
101.393 -\ \ {\isacharparenleft}SML\ \isakeyword{infixl}\ {\isadigit{1}}\ {\isachardoublequoteopen}andalso{\isachardoublequoteclose}{\isacharparenright}%
101.394 -\endisatagquotett
101.395 -{\isafoldquotett}%
101.396 -%
101.397 -\isadelimquotett
101.398 -%
101.399 -\endisadelimquotett
101.400 -%
101.401 -\isadelimquote
101.402 -%
101.403 -\endisadelimquote
101.404 -%
101.405 -\isatagquote
101.406 -%
101.407 -\begin{isamarkuptext}%
101.408 -\isatypewriter%
101.409 -\noindent%
101.410 -\hspace*{0pt}structure Example = \\
101.411 -\hspace*{0pt}struct\\
101.412 -\hspace*{0pt}\\
101.413 -\hspace*{0pt}datatype nat = Suc of nat | Zero{\char95}nat;\\
101.414 -\hspace*{0pt}\\
101.415 -\hspace*{0pt}fun less{\char95}nat m (Suc n) = less{\char95}eq{\char95}nat m n\\
101.416 -\hspace*{0pt} ~| less{\char95}nat n Zero{\char95}nat = false\\
101.417 -\hspace*{0pt}and less{\char95}eq{\char95}nat (Suc m) n = less{\char95}nat m n\\
101.418 -\hspace*{0pt} ~| less{\char95}eq{\char95}nat Zero{\char95}nat n = true;\\
101.419 -\hspace*{0pt}\\
101.420 -\hspace*{0pt}fun in{\char95}interval (k,~l) n = less{\char95}eq{\char95}nat k n andalso less{\char95}eq{\char95}nat n l;\\
101.421 -\hspace*{0pt}\\
101.422 -\hspace*{0pt}end;~(*struct Example*)%
101.423 -\end{isamarkuptext}%
101.424 -\isamarkuptrue%
101.425 -%
101.426 -\endisatagquote
101.427 -{\isafoldquote}%
101.428 -%
101.429 -\isadelimquote
101.430 -%
101.431 -\endisadelimquote
101.432 -%
101.433 -\begin{isamarkuptext}%
101.434 -\noindent The attentive reader may ask how we assert that no generated
101.435 - code will accidentally overwrite. For this reason the serialiser has
101.436 - an internal table of identifiers which have to be avoided to be used
101.437 - for new declarations. Initially, this table typically contains the
101.438 - keywords of the target language. It can be extended manually, thus avoiding
101.439 - accidental overwrites, using the \hyperlink{command.code-reserved}{\mbox{\isa{\isacommand{code{\isacharunderscore}reserved}}}} command:%
101.440 -\end{isamarkuptext}%
101.441 -\isamarkuptrue%
101.442 -%
101.443 -\isadelimquote
101.444 -%
101.445 -\endisadelimquote
101.446 -%
101.447 -\isatagquote
101.448 -\isacommand{code{\isacharunderscore}reserved}\isamarkupfalse%
101.449 -\ {\isachardoublequoteopen}{\isasymSML}{\isachardoublequoteclose}\ bool\ true\ false\ andalso%
101.450 -\endisatagquote
101.451 -{\isafoldquote}%
101.452 -%
101.453 -\isadelimquote
101.454 -%
101.455 -\endisadelimquote
101.456 -%
101.457 -\begin{isamarkuptext}%
101.458 -\noindent Next, we try to map HOL pairs to SML pairs, using the
101.459 - infix ``\verb|*|'' type constructor and parentheses:%
101.460 -\end{isamarkuptext}%
101.461 -\isamarkuptrue%
101.462 -%
101.463 -\isadeliminvisible
101.464 -%
101.465 -\endisadeliminvisible
101.466 -%
101.467 -\isataginvisible
101.468 -%
101.469 -\endisataginvisible
101.470 -{\isafoldinvisible}%
101.471 -%
101.472 -\isadeliminvisible
101.473 -%
101.474 -\endisadeliminvisible
101.475 -%
101.476 -\isadelimquotett
101.477 -%
101.478 -\endisadelimquotett
101.479 -%
101.480 -\isatagquotett
101.481 -\isacommand{code{\isacharunderscore}type}\isamarkupfalse%
101.482 -\ {\isacharasterisk}\isanewline
101.483 -\ \ {\isacharparenleft}SML\ \isakeyword{infix}\ {\isadigit{2}}\ {\isachardoublequoteopen}{\isacharasterisk}{\isachardoublequoteclose}{\isacharparenright}\isanewline
101.484 -\isacommand{code{\isacharunderscore}const}\isamarkupfalse%
101.485 -\ Pair\isanewline
101.486 -\ \ {\isacharparenleft}SML\ {\isachardoublequoteopen}{\isacharbang}{\isacharparenleft}{\isacharparenleft}{\isacharunderscore}{\isacharparenright}{\isacharcomma}{\isacharslash}\ {\isacharparenleft}{\isacharunderscore}{\isacharparenright}{\isacharparenright}{\isachardoublequoteclose}{\isacharparenright}%
101.487 -\endisatagquotett
101.488 -{\isafoldquotett}%
101.489 -%
101.490 -\isadelimquotett
101.491 -%
101.492 -\endisadelimquotett
101.493 -%
101.494 -\begin{isamarkuptext}%
101.495 -\noindent The initial bang ``\verb|!|'' tells the serialiser
101.496 - never to put
101.497 - parentheses around the whole expression (they are already present),
101.498 - while the parentheses around argument place holders
101.499 - tell not to put parentheses around the arguments.
101.500 - The slash ``\verb|/|'' (followed by arbitrary white space)
101.501 - inserts a space which may be used as a break if necessary
101.502 - during pretty printing.
101.503 -
101.504 - These examples give a glimpse what mechanisms
101.505 - custom serialisations provide; however their usage
101.506 - requires careful thinking in order not to introduce
101.507 - inconsistencies -- or, in other words:
101.508 - custom serialisations are completely axiomatic.
101.509 -
101.510 - A further noteworthy details is that any special
101.511 - character in a custom serialisation may be quoted
101.512 - using ``\verb|'|''; thus, in
101.513 - ``\verb|fn '_ => _|'' the first
101.514 - ``\verb|_|'' is a proper underscore while the
101.515 - second ``\verb|_|'' is a placeholder.%
101.516 -\end{isamarkuptext}%
101.517 -\isamarkuptrue%
101.518 -%
101.519 -\isamarkupsubsection{\isa{Haskell} serialisation%
101.520 -}
101.521 -\isamarkuptrue%
101.522 -%
101.523 -\begin{isamarkuptext}%
101.524 -For convenience, the default
101.525 - \isa{HOL} setup for \isa{Haskell} maps the \isa{eq} class to
101.526 - its counterpart in \isa{Haskell}, giving custom serialisations
101.527 - for the class \isa{eq} (by command \hyperlink{command.code-class}{\mbox{\isa{\isacommand{code{\isacharunderscore}class}}}}) and its operation
101.528 - \isa{eq{\isacharunderscore}class{\isachardot}eq}%
101.529 -\end{isamarkuptext}%
101.530 -\isamarkuptrue%
101.531 -%
101.532 -\isadelimquotett
101.533 -%
101.534 -\endisadelimquotett
101.535 -%
101.536 -\isatagquotett
101.537 -\isacommand{code{\isacharunderscore}class}\isamarkupfalse%
101.538 -\ eq\isanewline
101.539 -\ \ {\isacharparenleft}Haskell\ {\isachardoublequoteopen}Eq{\isachardoublequoteclose}{\isacharparenright}\isanewline
101.540 -\isanewline
101.541 -\isacommand{code{\isacharunderscore}const}\isamarkupfalse%
101.542 -\ {\isachardoublequoteopen}op\ {\isacharequal}{\isachardoublequoteclose}\isanewline
101.543 -\ \ {\isacharparenleft}Haskell\ \isakeyword{infixl}\ {\isadigit{4}}\ {\isachardoublequoteopen}{\isacharequal}{\isacharequal}{\isachardoublequoteclose}{\isacharparenright}%
101.544 -\endisatagquotett
101.545 -{\isafoldquotett}%
101.546 -%
101.547 -\isadelimquotett
101.548 -%
101.549 -\endisadelimquotett
101.550 -%
101.551 -\begin{isamarkuptext}%
101.552 -\noindent A problem now occurs whenever a type which
101.553 - is an instance of \isa{eq} in \isa{HOL} is mapped
101.554 - on a \isa{Haskell}-built-in type which is also an instance
101.555 - of \isa{Haskell} \isa{Eq}:%
101.556 -\end{isamarkuptext}%
101.557 -\isamarkuptrue%
101.558 -%
101.559 -\isadelimquote
101.560 -%
101.561 -\endisadelimquote
101.562 -%
101.563 -\isatagquote
101.564 -\isacommand{typedecl}\isamarkupfalse%
101.565 -\ bar\isanewline
101.566 -\isanewline
101.567 -\isacommand{instantiation}\isamarkupfalse%
101.568 -\ bar\ {\isacharcolon}{\isacharcolon}\ eq\isanewline
101.569 -\isakeyword{begin}\isanewline
101.570 -\isanewline
101.571 -\isacommand{definition}\isamarkupfalse%
101.572 -\ {\isachardoublequoteopen}eq{\isacharunderscore}class{\isachardot}eq\ {\isacharparenleft}x{\isasymColon}bar{\isacharparenright}\ y\ {\isasymlongleftrightarrow}\ x\ {\isacharequal}\ y{\isachardoublequoteclose}\isanewline
101.573 -\isanewline
101.574 -\isacommand{instance}\isamarkupfalse%
101.575 -\ \isacommand{by}\isamarkupfalse%
101.576 -\ default\ {\isacharparenleft}simp\ add{\isacharcolon}\ eq{\isacharunderscore}bar{\isacharunderscore}def{\isacharparenright}\isanewline
101.577 -\isanewline
101.578 -\isacommand{end}\isamarkupfalse%
101.579 -%
101.580 -\endisatagquote
101.581 -{\isafoldquote}%
101.582 -%
101.583 -\isadelimquote
101.584 -%
101.585 -\endisadelimquote
101.586 -\isanewline
101.587 -%
101.588 -\isadelimquotett
101.589 -\isanewline
101.590 -%
101.591 -\endisadelimquotett
101.592 -%
101.593 -\isatagquotett
101.594 -\isacommand{code{\isacharunderscore}type}\isamarkupfalse%
101.595 -\ bar\isanewline
101.596 -\ \ {\isacharparenleft}Haskell\ {\isachardoublequoteopen}Integer{\isachardoublequoteclose}{\isacharparenright}%
101.597 -\endisatagquotett
101.598 -{\isafoldquotett}%
101.599 -%
101.600 -\isadelimquotett
101.601 -%
101.602 -\endisadelimquotett
101.603 -%
101.604 -\begin{isamarkuptext}%
101.605 -\noindent The code generator would produce
101.606 - an additional instance, which of course is rejected by the \isa{Haskell}
101.607 - compiler.
101.608 - To suppress this additional instance, use
101.609 - \isa{code{\isacharunderscore}instance}:%
101.610 -\end{isamarkuptext}%
101.611 -\isamarkuptrue%
101.612 -%
101.613 -\isadelimquotett
101.614 -%
101.615 -\endisadelimquotett
101.616 -%
101.617 -\isatagquotett
101.618 -\isacommand{code{\isacharunderscore}instance}\isamarkupfalse%
101.619 -\ bar\ {\isacharcolon}{\isacharcolon}\ eq\isanewline
101.620 -\ \ {\isacharparenleft}Haskell\ {\isacharminus}{\isacharparenright}%
101.621 -\endisatagquotett
101.622 -{\isafoldquotett}%
101.623 -%
101.624 -\isadelimquotett
101.625 -%
101.626 -\endisadelimquotett
101.627 -%
101.628 -\isamarkupsubsection{Enhancing the target language context \label{sec:include}%
101.629 -}
101.630 -\isamarkuptrue%
101.631 -%
101.632 -\begin{isamarkuptext}%
101.633 -In rare cases it is necessary to \emph{enrich} the context of a
101.634 - target language; this is accomplished using the \hyperlink{command.code-include}{\mbox{\isa{\isacommand{code{\isacharunderscore}include}}}}
101.635 - command:%
101.636 -\end{isamarkuptext}%
101.637 -\isamarkuptrue%
101.638 -%
101.639 -\isadelimquotett
101.640 -%
101.641 -\endisadelimquotett
101.642 -%
101.643 -\isatagquotett
101.644 -\isacommand{code{\isacharunderscore}include}\isamarkupfalse%
101.645 -\ Haskell\ {\isachardoublequoteopen}Errno{\isachardoublequoteclose}\isanewline
101.646 -{\isacharverbatimopen}errno\ i\ {\isacharequal}\ error\ {\isacharparenleft}{\isachardoublequote}Error\ number{\isacharcolon}\ {\isachardoublequote}\ {\isacharplus}{\isacharplus}\ show\ i{\isacharparenright}{\isacharverbatimclose}\isanewline
101.647 -\isanewline
101.648 -\isacommand{code{\isacharunderscore}reserved}\isamarkupfalse%
101.649 -\ Haskell\ Errno%
101.650 -\endisatagquotett
101.651 -{\isafoldquotett}%
101.652 -%
101.653 -\isadelimquotett
101.654 -%
101.655 -\endisadelimquotett
101.656 -%
101.657 -\begin{isamarkuptext}%
101.658 -\noindent Such named \isa{include}s are then prepended to every generated code.
101.659 - Inspect such code in order to find out how \hyperlink{command.code-include}{\mbox{\isa{\isacommand{code{\isacharunderscore}include}}}} behaves
101.660 - with respect to a particular target language.%
101.661 -\end{isamarkuptext}%
101.662 -\isamarkuptrue%
101.663 -%
101.664 -\isadelimtheory
101.665 -%
101.666 -\endisadelimtheory
101.667 -%
101.668 -\isatagtheory
101.669 -\isacommand{end}\isamarkupfalse%
101.670 -%
101.671 -\endisatagtheory
101.672 -{\isafoldtheory}%
101.673 -%
101.674 -\isadelimtheory
101.675 -%
101.676 -\endisadelimtheory
101.677 -\isanewline
101.678 -\end{isabellebody}%
101.679 -%%% Local Variables:
101.680 -%%% mode: latex
101.681 -%%% TeX-master: "root"
101.682 -%%% End:
102.1 --- a/doc-src/IsarAdvanced/Codegen/Thy/document/Codegen.tex Wed Mar 04 11:05:02 2009 +0100
102.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
102.3 @@ -1,1690 +0,0 @@
102.4 -%
102.5 -\begin{isabellebody}%
102.6 -\def\isabellecontext{Codegen}%
102.7 -%
102.8 -\isadelimtheory
102.9 -\isanewline
102.10 -\isanewline
102.11 -%
102.12 -\endisadelimtheory
102.13 -%
102.14 -\isatagtheory
102.15 -%
102.16 -\endisatagtheory
102.17 -{\isafoldtheory}%
102.18 -%
102.19 -\isadelimtheory
102.20 -%
102.21 -\endisadelimtheory
102.22 -%
102.23 -\isadelimML
102.24 -%
102.25 -\endisadelimML
102.26 -%
102.27 -\isatagML
102.28 -%
102.29 -\endisatagML
102.30 -{\isafoldML}%
102.31 -%
102.32 -\isadelimML
102.33 -%
102.34 -\endisadelimML
102.35 -%
102.36 -\isamarkupchapter{Code generation from Isabelle theories%
102.37 -}
102.38 -\isamarkuptrue%
102.39 -%
102.40 -\isamarkupsection{Introduction%
102.41 -}
102.42 -\isamarkuptrue%
102.43 -%
102.44 -\isamarkupsubsection{Motivation%
102.45 -}
102.46 -\isamarkuptrue%
102.47 -%
102.48 -\begin{isamarkuptext}%
102.49 -Executing formal specifications as programs is a well-established
102.50 - topic in the theorem proving community. With increasing
102.51 - application of theorem proving systems in the area of
102.52 - software development and verification, its relevance manifests
102.53 - for running test cases and rapid prototyping. In logical
102.54 - calculi like constructive type theory,
102.55 - a notion of executability is implicit due to the nature
102.56 - of the calculus. In contrast, specifications in Isabelle
102.57 - can be highly non-executable. In order to bridge
102.58 - the gap between logic and executable specifications,
102.59 - an explicit non-trivial transformation has to be applied:
102.60 - code generation.
102.61 -
102.62 - This tutorial introduces a generic code generator for the
102.63 - Isabelle system \cite{isa-tutorial}.
102.64 - Generic in the sense that the
102.65 - \qn{target language} for which code shall ultimately be
102.66 - generated is not fixed but may be an arbitrary state-of-the-art
102.67 - functional programming language (currently, the implementation
102.68 - supports SML \cite{SML}, OCaml \cite{OCaml} and Haskell
102.69 - \cite{haskell-revised-report}).
102.70 - We aim to provide a
102.71 - versatile environment
102.72 - suitable for software development and verification,
102.73 - structuring the process
102.74 - of code generation into a small set of orthogonal principles
102.75 - while achieving a big coverage of application areas
102.76 - with maximum flexibility.
102.77 -
102.78 - Conceptually the code generator framework is part
102.79 - of Isabelle's \isa{Pure} meta logic; the object logic
102.80 - \isa{HOL} which is an extension of \isa{Pure}
102.81 - already comes with a reasonable framework setup and thus provides
102.82 - a good working horse for raising code-generation-driven
102.83 - applications. So, we assume some familiarity and experience
102.84 - with the ingredients of the \isa{HOL} \emph{Main} theory
102.85 - (see also \cite{isa-tutorial}).%
102.86 -\end{isamarkuptext}%
102.87 -\isamarkuptrue%
102.88 -%
102.89 -\isamarkupsubsection{Overview%
102.90 -}
102.91 -\isamarkuptrue%
102.92 -%
102.93 -\begin{isamarkuptext}%
102.94 -The code generator aims to be usable with no further ado
102.95 - in most cases while allowing for detailed customization.
102.96 - This manifests in the structure of this tutorial:
102.97 - we start with a generic example \secref{sec:example}
102.98 - and introduce code generation concepts \secref{sec:concept}.
102.99 - Section
102.100 - \secref{sec:basics} explains how to use the framework naively,
102.101 - presuming a reasonable default setup. Then, section
102.102 - \secref{sec:advanced} deals with advanced topics,
102.103 - introducing further aspects of the code generator framework
102.104 - in a motivation-driven manner. Last, section \secref{sec:ml}
102.105 - introduces the framework's internal programming interfaces.
102.106 -
102.107 - \begin{warn}
102.108 - Ultimately, the code generator which this tutorial deals with
102.109 - is supposed to replace the already established code generator
102.110 - by Stefan Berghofer \cite{Berghofer-Nipkow:2002}.
102.111 - So, for the moment, there are two distinct code generators
102.112 - in Isabelle.
102.113 - Also note that while the framework itself is
102.114 - object-logic independent, only \isa{HOL} provides a reasonable
102.115 - framework setup.
102.116 - \end{warn}%
102.117 -\end{isamarkuptext}%
102.118 -\isamarkuptrue%
102.119 -%
102.120 -\isamarkupsection{An example: a simple theory of search trees \label{sec:example}%
102.121 -}
102.122 -\isamarkuptrue%
102.123 -%
102.124 -\begin{isamarkuptext}%
102.125 -When writing executable specifications using \isa{HOL},
102.126 - it is convenient to use
102.127 - three existing packages: the datatype package for defining
102.128 - datatypes, the function package for (recursive) functions,
102.129 - and the class package for overloaded definitions.
102.130 -
102.131 - We develope a small theory of search trees; trees are represented
102.132 - as a datatype with key type \isa{{\isacharprime}a} and value type \isa{{\isacharprime}b}:%
102.133 -\end{isamarkuptext}%
102.134 -\isamarkuptrue%
102.135 -\isacommand{datatype}\isamarkupfalse%
102.136 -\ {\isacharparenleft}{\isacharprime}a{\isacharcomma}\ {\isacharprime}b{\isacharparenright}\ searchtree\ {\isacharequal}\ Leaf\ {\isachardoublequoteopen}{\isacharprime}a{\isasymColon}linorder{\isachardoublequoteclose}\ {\isacharprime}b\isanewline
102.137 -\ \ {\isacharbar}\ Branch\ {\isachardoublequoteopen}{\isacharparenleft}{\isacharprime}a{\isacharcomma}\ {\isacharprime}b{\isacharparenright}\ searchtree{\isachardoublequoteclose}\ {\isachardoublequoteopen}{\isacharprime}a{\isachardoublequoteclose}\ {\isachardoublequoteopen}{\isacharparenleft}{\isacharprime}a{\isacharcomma}\ {\isacharprime}b{\isacharparenright}\ searchtree{\isachardoublequoteclose}%
102.138 -\begin{isamarkuptext}%
102.139 -\noindent Note that we have constrained the type of keys
102.140 - to the class of total orders, \isa{linorder}.
102.141 -
102.142 - We define \isa{find} and \isa{update} functions:%
102.143 -\end{isamarkuptext}%
102.144 -\isamarkuptrue%
102.145 -\isacommand{primrec}\isamarkupfalse%
102.146 -\isanewline
102.147 -\ \ find\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharparenleft}{\isacharprime}a{\isasymColon}linorder{\isacharcomma}\ {\isacharprime}b{\isacharparenright}\ searchtree\ {\isasymRightarrow}\ {\isacharprime}a\ {\isasymRightarrow}\ {\isacharprime}b\ option{\isachardoublequoteclose}\ \isakeyword{where}\isanewline
102.148 -\ \ {\isachardoublequoteopen}find\ {\isacharparenleft}Leaf\ key\ val{\isacharparenright}\ it\ {\isacharequal}\ {\isacharparenleft}if\ it\ {\isacharequal}\ key\ then\ Some\ val\ else\ None{\isacharparenright}{\isachardoublequoteclose}\isanewline
102.149 -\ \ {\isacharbar}\ {\isachardoublequoteopen}find\ {\isacharparenleft}Branch\ t{\isadigit{1}}\ key\ t{\isadigit{2}}{\isacharparenright}\ it\ {\isacharequal}\ {\isacharparenleft}if\ it\ {\isasymle}\ key\ then\ find\ t{\isadigit{1}}\ it\ else\ find\ t{\isadigit{2}}\ it{\isacharparenright}{\isachardoublequoteclose}\isanewline
102.150 -\isanewline
102.151 -\isacommand{fun}\isamarkupfalse%
102.152 -\isanewline
102.153 -\ \ update\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharprime}a{\isasymColon}linorder\ {\isasymtimes}\ {\isacharprime}b\ {\isasymRightarrow}\ {\isacharparenleft}{\isacharprime}a{\isacharcomma}\ {\isacharprime}b{\isacharparenright}\ searchtree\ {\isasymRightarrow}\ {\isacharparenleft}{\isacharprime}a{\isacharcomma}\ {\isacharprime}b{\isacharparenright}\ searchtree{\isachardoublequoteclose}\ \isakeyword{where}\isanewline
102.154 -\ \ {\isachardoublequoteopen}update\ {\isacharparenleft}it{\isacharcomma}\ entry{\isacharparenright}\ {\isacharparenleft}Leaf\ key\ val{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}\isanewline
102.155 -\ \ \ \ if\ it\ {\isacharequal}\ key\ then\ Leaf\ key\ entry\isanewline
102.156 -\ \ \ \ \ \ else\ if\ it\ {\isasymle}\ key\isanewline
102.157 -\ \ \ \ \ \ then\ Branch\ {\isacharparenleft}Leaf\ it\ entry{\isacharparenright}\ it\ {\isacharparenleft}Leaf\ key\ val{\isacharparenright}\isanewline
102.158 -\ \ \ \ \ \ else\ Branch\ {\isacharparenleft}Leaf\ key\ val{\isacharparenright}\ it\ {\isacharparenleft}Leaf\ it\ entry{\isacharparenright}\isanewline
102.159 -\ \ \ {\isacharparenright}{\isachardoublequoteclose}\isanewline
102.160 -\ \ {\isacharbar}\ {\isachardoublequoteopen}update\ {\isacharparenleft}it{\isacharcomma}\ entry{\isacharparenright}\ {\isacharparenleft}Branch\ t{\isadigit{1}}\ key\ t{\isadigit{2}}{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}\isanewline
102.161 -\ \ \ \ if\ it\ {\isasymle}\ key\isanewline
102.162 -\ \ \ \ \ \ then\ {\isacharparenleft}Branch\ {\isacharparenleft}update\ {\isacharparenleft}it{\isacharcomma}\ entry{\isacharparenright}\ t{\isadigit{1}}{\isacharparenright}\ key\ t{\isadigit{2}}{\isacharparenright}\isanewline
102.163 -\ \ \ \ \ \ else\ {\isacharparenleft}Branch\ t{\isadigit{1}}\ key\ {\isacharparenleft}update\ {\isacharparenleft}it{\isacharcomma}\ entry{\isacharparenright}\ t{\isadigit{2}}{\isacharparenright}{\isacharparenright}\isanewline
102.164 -\ \ \ {\isacharparenright}{\isachardoublequoteclose}%
102.165 -\begin{isamarkuptext}%
102.166 -\noindent For testing purpose, we define a small example
102.167 - using natural numbers \isa{nat} (which are a \isa{linorder})
102.168 - as keys and list of nats as values:%
102.169 -\end{isamarkuptext}%
102.170 -\isamarkuptrue%
102.171 -\isacommand{definition}\isamarkupfalse%
102.172 -\isanewline
102.173 -\ \ example\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharparenleft}nat{\isacharcomma}\ nat\ list{\isacharparenright}\ searchtree{\isachardoublequoteclose}\isanewline
102.174 -\isakeyword{where}\isanewline
102.175 -\ \ {\isachardoublequoteopen}example\ {\isacharequal}\ update\ {\isacharparenleft}Suc\ {\isacharparenleft}Suc\ {\isacharparenleft}Suc\ {\isacharparenleft}Suc\ {\isadigit{0}}{\isacharparenright}{\isacharparenright}{\isacharparenright}{\isacharcomma}\ {\isacharbrackleft}Suc\ {\isacharparenleft}Suc\ {\isadigit{0}}{\isacharparenright}{\isacharcomma}\ Suc\ {\isacharparenleft}Suc\ {\isadigit{0}}{\isacharparenright}{\isacharbrackright}{\isacharparenright}\ {\isacharparenleft}update\ {\isacharparenleft}Suc\ {\isacharparenleft}Suc\ {\isacharparenleft}Suc\ {\isadigit{0}}{\isacharparenright}{\isacharparenright}{\isacharcomma}\ {\isacharbrackleft}Suc\ {\isacharparenleft}Suc\ {\isacharparenleft}Suc\ {\isadigit{0}}{\isacharparenright}{\isacharparenright}{\isacharbrackright}{\isacharparenright}\isanewline
102.176 -\ \ \ \ {\isacharparenleft}update\ {\isacharparenleft}Suc\ {\isacharparenleft}Suc\ {\isadigit{0}}{\isacharparenright}{\isacharcomma}\ {\isacharbrackleft}Suc\ {\isacharparenleft}Suc\ {\isadigit{0}}{\isacharparenright}{\isacharbrackright}{\isacharparenright}\ {\isacharparenleft}Leaf\ {\isacharparenleft}Suc\ {\isadigit{0}}{\isacharparenright}\ {\isacharbrackleft}{\isacharbrackright}{\isacharparenright}{\isacharparenright}{\isacharparenright}{\isachardoublequoteclose}%
102.177 -\begin{isamarkuptext}%
102.178 -\noindent Then we generate code%
102.179 -\end{isamarkuptext}%
102.180 -\isamarkuptrue%
102.181 -\isacommand{export{\isacharunderscore}code}\isamarkupfalse%
102.182 -\ example\ \isakeyword{in}\ SML\ \isakeyword{file}\ {\isachardoublequoteopen}examples{\isacharslash}tree{\isachardot}ML{\isachardoublequoteclose}%
102.183 -\begin{isamarkuptext}%
102.184 -\noindent which looks like:
102.185 - \lstsml{Thy/examples/tree.ML}%
102.186 -\end{isamarkuptext}%
102.187 -\isamarkuptrue%
102.188 -%
102.189 -\isamarkupsection{Code generation concepts and process \label{sec:concept}%
102.190 -}
102.191 -\isamarkuptrue%
102.192 -%
102.193 -\begin{isamarkuptext}%
102.194 -\begin{figure}[h]
102.195 - \centering
102.196 - \includegraphics[width=0.7\textwidth]{codegen_process}
102.197 - \caption{code generator -- processing overview}
102.198 - \label{fig:process}
102.199 - \end{figure}
102.200 -
102.201 - The code generator employs a notion of executability
102.202 - for three foundational executable ingredients known
102.203 - from functional programming:
102.204 - \emph{defining equations}, \emph{datatypes}, and
102.205 - \emph{type classes}. A defining equation as a first approximation
102.206 - is a theorem of the form \isa{f\ t\isactrlisub {\isadigit{1}}\ t\isactrlisub {\isadigit{2}}\ {\isasymdots}\ t\isactrlisub n\ {\isasymequiv}\ t}
102.207 - (an equation headed by a constant \isa{f} with arguments
102.208 - \isa{t\isactrlisub {\isadigit{1}}\ t\isactrlisub {\isadigit{2}}\ {\isasymdots}\ t\isactrlisub n} and right hand side \isa{t}).
102.209 - Code generation aims to turn defining equations
102.210 - into a functional program by running through
102.211 - a process (see figure \ref{fig:process}):
102.212 -
102.213 - \begin{itemize}
102.214 -
102.215 - \item Out of the vast collection of theorems proven in a
102.216 - \qn{theory}, a reasonable subset modeling
102.217 - defining equations is \qn{selected}.
102.218 -
102.219 - \item On those selected theorems, certain
102.220 - transformations are carried out
102.221 - (\qn{preprocessing}). Their purpose is to turn theorems
102.222 - representing non- or badly executable
102.223 - specifications into equivalent but executable counterparts.
102.224 - The result is a structured collection of \qn{code theorems}.
102.225 -
102.226 - \item These \qn{code theorems} then are \qn{translated}
102.227 - into an Haskell-like intermediate
102.228 - language.
102.229 -
102.230 - \item Finally, out of the intermediate language the final
102.231 - code in the desired \qn{target language} is \qn{serialized}.
102.232 -
102.233 - \end{itemize}
102.234 -
102.235 - From these steps, only the two last are carried out
102.236 - outside the logic; by keeping this layer as
102.237 - thin as possible, the amount of code to trust is
102.238 - kept to a minimum.%
102.239 -\end{isamarkuptext}%
102.240 -\isamarkuptrue%
102.241 -%
102.242 -\isamarkupsection{Basics \label{sec:basics}%
102.243 -}
102.244 -\isamarkuptrue%
102.245 -%
102.246 -\isamarkupsubsection{Invoking the code generator%
102.247 -}
102.248 -\isamarkuptrue%
102.249 -%
102.250 -\begin{isamarkuptext}%
102.251 -Thanks to a reasonable setup of the \isa{HOL} theories, in
102.252 - most cases code generation proceeds without further ado:%
102.253 -\end{isamarkuptext}%
102.254 -\isamarkuptrue%
102.255 -\isacommand{primrec}\isamarkupfalse%
102.256 -\isanewline
102.257 -\ \ fac\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymRightarrow}\ nat{\isachardoublequoteclose}\ \isakeyword{where}\isanewline
102.258 -\ \ \ \ {\isachardoublequoteopen}fac\ {\isadigit{0}}\ {\isacharequal}\ {\isadigit{1}}{\isachardoublequoteclose}\isanewline
102.259 -\ \ {\isacharbar}\ {\isachardoublequoteopen}fac\ {\isacharparenleft}Suc\ n{\isacharparenright}\ {\isacharequal}\ Suc\ n\ {\isacharasterisk}\ fac\ n{\isachardoublequoteclose}%
102.260 -\begin{isamarkuptext}%
102.261 -\noindent This executable specification is now turned to SML code:%
102.262 -\end{isamarkuptext}%
102.263 -\isamarkuptrue%
102.264 -\isacommand{export{\isacharunderscore}code}\isamarkupfalse%
102.265 -\ fac\ \isakeyword{in}\ SML\ \isakeyword{file}\ {\isachardoublequoteopen}examples{\isacharslash}fac{\isachardot}ML{\isachardoublequoteclose}%
102.266 -\begin{isamarkuptext}%
102.267 -\noindent The \isa{{\isasymEXPORTCODE}} command takes a space-separated list of
102.268 - constants together with \qn{serialization directives}
102.269 - These start with a \qn{target language}
102.270 - identifier, followed by a file specification
102.271 - where to write the generated code to.
102.272 -
102.273 - Internally, the defining equations for all selected
102.274 - constants are taken, including any transitively required
102.275 - constants, datatypes and classes, resulting in the following
102.276 - code:
102.277 -
102.278 - \lstsml{Thy/examples/fac.ML}
102.279 -
102.280 - The code generator will complain when a required
102.281 - ingredient does not provide a executable counterpart,
102.282 - e.g.~generating code
102.283 - for constants not yielding
102.284 - a defining equation (e.g.~the Hilbert choice
102.285 - operation \isa{SOME}):%
102.286 -\end{isamarkuptext}%
102.287 -\isamarkuptrue%
102.288 -%
102.289 -\isadelimML
102.290 -%
102.291 -\endisadelimML
102.292 -%
102.293 -\isatagML
102.294 -%
102.295 -\endisatagML
102.296 -{\isafoldML}%
102.297 -%
102.298 -\isadelimML
102.299 -%
102.300 -\endisadelimML
102.301 -\isacommand{definition}\isamarkupfalse%
102.302 -\isanewline
102.303 -\ \ pick{\isacharunderscore}some\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharprime}a\ list\ {\isasymRightarrow}\ {\isacharprime}a{\isachardoublequoteclose}\ \isakeyword{where}\isanewline
102.304 -\ \ {\isachardoublequoteopen}pick{\isacharunderscore}some\ xs\ {\isacharequal}\ {\isacharparenleft}SOME\ x{\isachardot}\ x\ {\isasymin}\ set\ xs{\isacharparenright}{\isachardoublequoteclose}%
102.305 -\isadelimML
102.306 -%
102.307 -\endisadelimML
102.308 -%
102.309 -\isatagML
102.310 -%
102.311 -\endisatagML
102.312 -{\isafoldML}%
102.313 -%
102.314 -\isadelimML
102.315 -%
102.316 -\endisadelimML
102.317 -\isanewline
102.318 -\isacommand{export{\isacharunderscore}code}\isamarkupfalse%
102.319 -\ pick{\isacharunderscore}some\ \isakeyword{in}\ SML\ \isakeyword{file}\ {\isachardoublequoteopen}examples{\isacharslash}fail{\isacharunderscore}const{\isachardot}ML{\isachardoublequoteclose}%
102.320 -\begin{isamarkuptext}%
102.321 -\noindent will fail.%
102.322 -\end{isamarkuptext}%
102.323 -\isamarkuptrue%
102.324 -%
102.325 -\isamarkupsubsection{Theorem selection%
102.326 -}
102.327 -\isamarkuptrue%
102.328 -%
102.329 -\begin{isamarkuptext}%
102.330 -The list of all defining equations in a theory may be inspected
102.331 - using the \isa{{\isasymPRINTCODESETUP}} command:%
102.332 -\end{isamarkuptext}%
102.333 -\isamarkuptrue%
102.334 -\isacommand{print{\isacharunderscore}codesetup}\isamarkupfalse%
102.335 -%
102.336 -\begin{isamarkuptext}%
102.337 -\noindent which displays a table of constant with corresponding
102.338 - defining equations (the additional stuff displayed
102.339 - shall not bother us for the moment).
102.340 -
102.341 - The typical \isa{HOL} tools are already set up in a way that
102.342 - function definitions introduced by \isa{{\isasymDEFINITION}},
102.343 - \isa{{\isasymPRIMREC}}, \isa{{\isasymFUN}},
102.344 - \isa{{\isasymFUNCTION}}, \isa{{\isasymCONSTDEFS}},
102.345 - \isa{{\isasymRECDEF}} are implicitly propagated
102.346 - to this defining equation table. Specific theorems may be
102.347 - selected using an attribute: \emph{code func}. As example,
102.348 - a weight selector function:%
102.349 -\end{isamarkuptext}%
102.350 -\isamarkuptrue%
102.351 -\isacommand{primrec}\isamarkupfalse%
102.352 -\isanewline
102.353 -\ \ pick\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharparenleft}nat\ {\isasymtimes}\ {\isacharprime}a{\isacharparenright}\ list\ {\isasymRightarrow}\ nat\ {\isasymRightarrow}\ {\isacharprime}a{\isachardoublequoteclose}\ \isakeyword{where}\isanewline
102.354 -\ \ {\isachardoublequoteopen}pick\ {\isacharparenleft}x{\isacharhash}xs{\isacharparenright}\ n\ {\isacharequal}\ {\isacharparenleft}let\ {\isacharparenleft}k{\isacharcomma}\ v{\isacharparenright}\ {\isacharequal}\ x\ in\isanewline
102.355 -\ \ \ \ if\ n\ {\isacharless}\ k\ then\ v\ else\ pick\ xs\ {\isacharparenleft}n\ {\isacharminus}\ k{\isacharparenright}{\isacharparenright}{\isachardoublequoteclose}%
102.356 -\begin{isamarkuptext}%
102.357 -\noindent We want to eliminate the explicit destruction
102.358 - of \isa{x} to \isa{{\isacharparenleft}k{\isacharcomma}\ v{\isacharparenright}}:%
102.359 -\end{isamarkuptext}%
102.360 -\isamarkuptrue%
102.361 -\isacommand{lemma}\isamarkupfalse%
102.362 -\ {\isacharbrackleft}code\ func{\isacharbrackright}{\isacharcolon}\isanewline
102.363 -\ \ {\isachardoublequoteopen}pick\ {\isacharparenleft}{\isacharparenleft}k{\isacharcomma}\ v{\isacharparenright}{\isacharhash}xs{\isacharparenright}\ n\ {\isacharequal}\ {\isacharparenleft}if\ n\ {\isacharless}\ k\ then\ v\ else\ pick\ xs\ {\isacharparenleft}n\ {\isacharminus}\ k{\isacharparenright}{\isacharparenright}{\isachardoublequoteclose}\isanewline
102.364 -%
102.365 -\isadelimproof
102.366 -\ \ %
102.367 -\endisadelimproof
102.368 -%
102.369 -\isatagproof
102.370 -\isacommand{by}\isamarkupfalse%
102.371 -\ simp%
102.372 -\endisatagproof
102.373 -{\isafoldproof}%
102.374 -%
102.375 -\isadelimproof
102.376 -\isanewline
102.377 -%
102.378 -\endisadelimproof
102.379 -\isanewline
102.380 -\isacommand{export{\isacharunderscore}code}\isamarkupfalse%
102.381 -\ pick\ \ \isakeyword{in}\ SML\ \isakeyword{file}\ {\isachardoublequoteopen}examples{\isacharslash}pick{\isadigit{1}}{\isachardot}ML{\isachardoublequoteclose}%
102.382 -\begin{isamarkuptext}%
102.383 -\noindent This theorem now is used for generating code:
102.384 -
102.385 - \lstsml{Thy/examples/pick1.ML}
102.386 -
102.387 - \noindent The policy is that \emph{default equations} stemming from
102.388 - \isa{{\isasymDEFINITION}},
102.389 - \isa{{\isasymPRIMREC}}, \isa{{\isasymFUN}},
102.390 - \isa{{\isasymFUNCTION}}, \isa{{\isasymCONSTDEFS}},
102.391 - \isa{{\isasymRECDEF}} statements are discarded as soon as an
102.392 - equation is explicitly selected by means of \emph{code func}.
102.393 - Further applications of \emph{code func} add theorems incrementally,
102.394 - but syntactic redundancies are implicitly dropped. For example,
102.395 - using a modified version of the \isa{fac} function
102.396 - as defining equation, the then redundant (since
102.397 - syntactically subsumed) original defining equations
102.398 - are dropped.
102.399 -
102.400 - \begin{warn}
102.401 - The attributes \emph{code} and \emph{code del}
102.402 - associated with the existing code generator also apply to
102.403 - the new one: \emph{code} implies \emph{code func},
102.404 - and \emph{code del} implies \emph{code func del}.
102.405 - \end{warn}%
102.406 -\end{isamarkuptext}%
102.407 -\isamarkuptrue%
102.408 -%
102.409 -\isamarkupsubsection{Type classes%
102.410 -}
102.411 -\isamarkuptrue%
102.412 -%
102.413 -\begin{isamarkuptext}%
102.414 -Type classes enter the game via the Isar class package.
102.415 - For a short introduction how to use it, see \cite{isabelle-classes};
102.416 - here we just illustrate its impact on code generation.
102.417 -
102.418 - In a target language, type classes may be represented
102.419 - natively (as in the case of Haskell). For languages
102.420 - like SML, they are implemented using \emph{dictionaries}.
102.421 - Our following example specifies a class \qt{null},
102.422 - assigning to each of its inhabitants a \qt{null} value:%
102.423 -\end{isamarkuptext}%
102.424 -\isamarkuptrue%
102.425 -\isacommand{class}\isamarkupfalse%
102.426 -\ null\ {\isacharequal}\ type\ {\isacharplus}\isanewline
102.427 -\ \ \isakeyword{fixes}\ null\ {\isacharcolon}{\isacharcolon}\ {\isacharprime}a\isanewline
102.428 -\isanewline
102.429 -\isacommand{primrec}\isamarkupfalse%
102.430 -\isanewline
102.431 -\ \ head\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharprime}a{\isasymColon}null\ list\ {\isasymRightarrow}\ {\isacharprime}a{\isachardoublequoteclose}\ \isakeyword{where}\isanewline
102.432 -\ \ {\isachardoublequoteopen}head\ {\isacharbrackleft}{\isacharbrackright}\ {\isacharequal}\ null{\isachardoublequoteclose}\isanewline
102.433 -\ \ {\isacharbar}\ {\isachardoublequoteopen}head\ {\isacharparenleft}x{\isacharhash}xs{\isacharparenright}\ {\isacharequal}\ x{\isachardoublequoteclose}%
102.434 -\begin{isamarkuptext}%
102.435 -\noindent We provide some instances for our \isa{null}:%
102.436 -\end{isamarkuptext}%
102.437 -\isamarkuptrue%
102.438 -\isacommand{instantiation}\isamarkupfalse%
102.439 -\ option\ \isakeyword{and}\ list\ {\isacharcolon}{\isacharcolon}\ {\isacharparenleft}type{\isacharparenright}\ null\isanewline
102.440 -\isakeyword{begin}\isanewline
102.441 -\isanewline
102.442 -\isacommand{definition}\isamarkupfalse%
102.443 -\isanewline
102.444 -\ \ {\isachardoublequoteopen}null\ {\isacharequal}\ None{\isachardoublequoteclose}\isanewline
102.445 -\isanewline
102.446 -\isacommand{definition}\isamarkupfalse%
102.447 -\isanewline
102.448 -\ \ {\isachardoublequoteopen}null\ {\isacharequal}\ {\isacharbrackleft}{\isacharbrackright}{\isachardoublequoteclose}\isanewline
102.449 -\isanewline
102.450 -\isacommand{instance}\isamarkupfalse%
102.451 -%
102.452 -\isadelimproof
102.453 -\ %
102.454 -\endisadelimproof
102.455 -%
102.456 -\isatagproof
102.457 -\isacommand{{\isachardot}{\isachardot}}\isamarkupfalse%
102.458 -%
102.459 -\endisatagproof
102.460 -{\isafoldproof}%
102.461 -%
102.462 -\isadelimproof
102.463 -%
102.464 -\endisadelimproof
102.465 -\isanewline
102.466 -\isanewline
102.467 -\isacommand{end}\isamarkupfalse%
102.468 -%
102.469 -\begin{isamarkuptext}%
102.470 -\noindent Constructing a dummy example:%
102.471 -\end{isamarkuptext}%
102.472 -\isamarkuptrue%
102.473 -\isacommand{definition}\isamarkupfalse%
102.474 -\isanewline
102.475 -\ \ {\isachardoublequoteopen}dummy\ {\isacharequal}\ head\ {\isacharbrackleft}Some\ {\isacharparenleft}Suc\ {\isadigit{0}}{\isacharparenright}{\isacharcomma}\ None{\isacharbrackright}{\isachardoublequoteclose}%
102.476 -\begin{isamarkuptext}%
102.477 -Type classes offer a suitable occasion to introduce
102.478 - the Haskell serializer. Its usage is almost the same
102.479 - as SML, but, in accordance with conventions
102.480 - some Haskell systems enforce, each module ends
102.481 - up in a single file. The module hierarchy is reflected in
102.482 - the file system, with root directory given as file specification.%
102.483 -\end{isamarkuptext}%
102.484 -\isamarkuptrue%
102.485 -\isacommand{export{\isacharunderscore}code}\isamarkupfalse%
102.486 -\ dummy\ \isakeyword{in}\ Haskell\ \isakeyword{file}\ {\isachardoublequoteopen}examples{\isacharslash}{\isachardoublequoteclose}%
102.487 -\begin{isamarkuptext}%
102.488 -\lsthaskell{Thy/examples/Codegen.hs}
102.489 - \noindent (we have left out all other modules).
102.490 -
102.491 - \medskip
102.492 -
102.493 - The whole code in SML with explicit dictionary passing:%
102.494 -\end{isamarkuptext}%
102.495 -\isamarkuptrue%
102.496 -\isacommand{export{\isacharunderscore}code}\isamarkupfalse%
102.497 -\ dummy\ \isakeyword{in}\ SML\ \isakeyword{file}\ {\isachardoublequoteopen}examples{\isacharslash}class{\isachardot}ML{\isachardoublequoteclose}%
102.498 -\begin{isamarkuptext}%
102.499 -\lstsml{Thy/examples/class.ML}
102.500 -
102.501 - \medskip
102.502 -
102.503 - \noindent or in OCaml:%
102.504 -\end{isamarkuptext}%
102.505 -\isamarkuptrue%
102.506 -\isacommand{export{\isacharunderscore}code}\isamarkupfalse%
102.507 -\ dummy\ \isakeyword{in}\ OCaml\ \isakeyword{file}\ {\isachardoublequoteopen}examples{\isacharslash}class{\isachardot}ocaml{\isachardoublequoteclose}%
102.508 -\begin{isamarkuptext}%
102.509 -\lstsml{Thy/examples/class.ocaml}
102.510 -
102.511 - \medskip The explicit association of constants
102.512 - to classes can be inspected using the \isa{{\isasymPRINTCLASSES}}
102.513 - command.%
102.514 -\end{isamarkuptext}%
102.515 -\isamarkuptrue%
102.516 -%
102.517 -\isamarkupsection{Recipes and advanced topics \label{sec:advanced}%
102.518 -}
102.519 -\isamarkuptrue%
102.520 -%
102.521 -\begin{isamarkuptext}%
102.522 -In this tutorial, we do not attempt to give an exhaustive
102.523 - description of the code generator framework; instead,
102.524 - we cast a light on advanced topics by introducing
102.525 - them together with practically motivated examples. Concerning
102.526 - further reading, see
102.527 -
102.528 - \begin{itemize}
102.529 -
102.530 - \item the Isabelle/Isar Reference Manual \cite{isabelle-isar-ref}
102.531 - for exhaustive syntax diagrams.
102.532 - \item or \cite{Haftmann-Nipkow:2007:codegen} which deals with foundational issues
102.533 - of the code generator framework.
102.534 -
102.535 - \end{itemize}%
102.536 -\end{isamarkuptext}%
102.537 -\isamarkuptrue%
102.538 -%
102.539 -\isamarkupsubsection{Library theories \label{sec:library}%
102.540 -}
102.541 -\isamarkuptrue%
102.542 -%
102.543 -\begin{isamarkuptext}%
102.544 -The \isa{HOL} \isa{Main} theory already provides a code
102.545 - generator setup
102.546 - which should be suitable for most applications. Common extensions
102.547 - and modifications are available by certain theories of the \isa{HOL}
102.548 - library; beside being useful in applications, they may serve
102.549 - as a tutorial for customizing the code generator setup.
102.550 -
102.551 - \begin{description}
102.552 -
102.553 - \item[\isa{Code{\isacharunderscore}Integer}] represents \isa{HOL} integers by big
102.554 - integer literals in target languages.
102.555 - \item[\isa{Code{\isacharunderscore}Char}] represents \isa{HOL} characters by
102.556 - character literals in target languages.
102.557 - \item[\isa{Code{\isacharunderscore}Char{\isacharunderscore}chr}] like \isa{Code{\isacharunderscore}Char},
102.558 - but also offers treatment of character codes; includes
102.559 - \isa{Code{\isacharunderscore}Integer}.
102.560 - \item[\isa{Efficient{\isacharunderscore}Nat}] \label{eff_nat} implements natural numbers by integers,
102.561 - which in general will result in higher efficency; pattern
102.562 - matching with \isa{{\isadigit{0}}} / \isa{Suc}
102.563 - is eliminated; includes \isa{Code{\isacharunderscore}Integer}.
102.564 - \item[\isa{Code{\isacharunderscore}Index}] provides an additional datatype
102.565 - \isa{index} which is mapped to target-language built-in integers.
102.566 - Useful for code setups which involve e.g. indexing of
102.567 - target-language arrays.
102.568 - \item[\isa{Code{\isacharunderscore}Message}] provides an additional datatype
102.569 - \isa{message{\isacharunderscore}string} which is isomorphic to strings;
102.570 - \isa{message{\isacharunderscore}string}s are mapped to target-language strings.
102.571 - Useful for code setups which involve e.g. printing (error) messages.
102.572 -
102.573 - \end{description}
102.574 -
102.575 - \begin{warn}
102.576 - When importing any of these theories, they should form the last
102.577 - items in an import list. Since these theories adapt the
102.578 - code generator setup in a non-conservative fashion,
102.579 - strange effects may occur otherwise.
102.580 - \end{warn}%
102.581 -\end{isamarkuptext}%
102.582 -\isamarkuptrue%
102.583 -%
102.584 -\isamarkupsubsection{Preprocessing%
102.585 -}
102.586 -\isamarkuptrue%
102.587 -%
102.588 -\begin{isamarkuptext}%
102.589 -Before selected function theorems are turned into abstract
102.590 - code, a chain of definitional transformation steps is carried
102.591 - out: \emph{preprocessing}. In essence, the preprocessor
102.592 - consists of two components: a \emph{simpset} and \emph{function transformers}.
102.593 -
102.594 - The \emph{simpset} allows to employ the full generality of the Isabelle
102.595 - simplifier. Due to the interpretation of theorems
102.596 - as defining equations, rewrites are applied to the right
102.597 - hand side and the arguments of the left hand side of an
102.598 - equation, but never to the constant heading the left hand side.
102.599 - An important special case are \emph{inline theorems} which may be
102.600 - declared an undeclared using the
102.601 - \emph{code inline} or \emph{code inline del} attribute respectively.
102.602 - Some common applications:%
102.603 -\end{isamarkuptext}%
102.604 -\isamarkuptrue%
102.605 -%
102.606 -\begin{itemize}
102.607 -%
102.608 -\begin{isamarkuptext}%
102.609 -\item replacing non-executable constructs by executable ones:%
102.610 -\end{isamarkuptext}%
102.611 -\isamarkuptrue%
102.612 -\ \ \isacommand{lemma}\isamarkupfalse%
102.613 -\ {\isacharbrackleft}code\ inline{\isacharbrackright}{\isacharcolon}\isanewline
102.614 -\ \ \ \ {\isachardoublequoteopen}x\ {\isasymin}\ set\ xs\ {\isasymlongleftrightarrow}\ x\ mem\ xs{\isachardoublequoteclose}%
102.615 -\isadelimproof
102.616 -\ %
102.617 -\endisadelimproof
102.618 -%
102.619 -\isatagproof
102.620 -\isacommand{by}\isamarkupfalse%
102.621 -\ {\isacharparenleft}induct\ xs{\isacharparenright}\ simp{\isacharunderscore}all%
102.622 -\endisatagproof
102.623 -{\isafoldproof}%
102.624 -%
102.625 -\isadelimproof
102.626 -%
102.627 -\endisadelimproof
102.628 -%
102.629 -\begin{isamarkuptext}%
102.630 -\item eliminating superfluous constants:%
102.631 -\end{isamarkuptext}%
102.632 -\isamarkuptrue%
102.633 -\ \ \isacommand{lemma}\isamarkupfalse%
102.634 -\ {\isacharbrackleft}code\ inline{\isacharbrackright}{\isacharcolon}\isanewline
102.635 -\ \ \ \ {\isachardoublequoteopen}{\isadigit{1}}\ {\isacharequal}\ Suc\ {\isadigit{0}}{\isachardoublequoteclose}%
102.636 -\isadelimproof
102.637 -\ %
102.638 -\endisadelimproof
102.639 -%
102.640 -\isatagproof
102.641 -\isacommand{by}\isamarkupfalse%
102.642 -\ simp%
102.643 -\endisatagproof
102.644 -{\isafoldproof}%
102.645 -%
102.646 -\isadelimproof
102.647 -%
102.648 -\endisadelimproof
102.649 -%
102.650 -\begin{isamarkuptext}%
102.651 -\item replacing executable but inconvenient constructs:%
102.652 -\end{isamarkuptext}%
102.653 -\isamarkuptrue%
102.654 -\ \ \isacommand{lemma}\isamarkupfalse%
102.655 -\ {\isacharbrackleft}code\ inline{\isacharbrackright}{\isacharcolon}\isanewline
102.656 -\ \ \ \ {\isachardoublequoteopen}xs\ {\isacharequal}\ {\isacharbrackleft}{\isacharbrackright}\ {\isasymlongleftrightarrow}\ List{\isachardot}null\ xs{\isachardoublequoteclose}%
102.657 -\isadelimproof
102.658 -\ %
102.659 -\endisadelimproof
102.660 -%
102.661 -\isatagproof
102.662 -\isacommand{by}\isamarkupfalse%
102.663 -\ {\isacharparenleft}induct\ xs{\isacharparenright}\ simp{\isacharunderscore}all%
102.664 -\endisatagproof
102.665 -{\isafoldproof}%
102.666 -%
102.667 -\isadelimproof
102.668 -%
102.669 -\endisadelimproof
102.670 -%
102.671 -\end{itemize}
102.672 -%
102.673 -\begin{isamarkuptext}%
102.674 -\emph{Function transformers} provide a very general interface,
102.675 - transforming a list of function theorems to another
102.676 - list of function theorems, provided that neither the heading
102.677 - constant nor its type change. The \isa{{\isadigit{0}}} / \isa{Suc}
102.678 - pattern elimination implemented in
102.679 - theory \isa{Efficient{\isacharunderscore}Nat} (see \secref{eff_nat}) uses this
102.680 - interface.
102.681 -
102.682 - \noindent The current setup of the preprocessor may be inspected using
102.683 - the \isa{{\isasymPRINTCODESETUP}} command.
102.684 -
102.685 - \begin{warn}
102.686 - The attribute \emph{code unfold}
102.687 - associated with the existing code generator also applies to
102.688 - the new one: \emph{code unfold} implies \emph{code inline}.
102.689 - \end{warn}%
102.690 -\end{isamarkuptext}%
102.691 -\isamarkuptrue%
102.692 -%
102.693 -\isamarkupsubsection{Concerning operational equality%
102.694 -}
102.695 -\isamarkuptrue%
102.696 -%
102.697 -\begin{isamarkuptext}%
102.698 -Surely you have already noticed how equality is treated
102.699 - by the code generator:%
102.700 -\end{isamarkuptext}%
102.701 -\isamarkuptrue%
102.702 -\isacommand{primrec}\isamarkupfalse%
102.703 -\isanewline
102.704 -\ \ collect{\isacharunderscore}duplicates\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharprime}a\ list\ {\isasymRightarrow}\ {\isacharprime}a\ list\ {\isasymRightarrow}\ {\isacharprime}a\ list\ {\isasymRightarrow}\ {\isacharprime}a\ list{\isachardoublequoteclose}\ \isakeyword{where}\isanewline
102.705 -\ \ \ \ {\isachardoublequoteopen}collect{\isacharunderscore}duplicates\ xs\ ys\ {\isacharbrackleft}{\isacharbrackright}\ {\isacharequal}\ xs{\isachardoublequoteclose}\isanewline
102.706 -\ \ {\isacharbar}\ {\isachardoublequoteopen}collect{\isacharunderscore}duplicates\ xs\ ys\ {\isacharparenleft}z{\isacharhash}zs{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}if\ z\ {\isasymin}\ set\ xs\isanewline
102.707 -\ \ \ \ \ \ then\ if\ z\ {\isasymin}\ set\ ys\isanewline
102.708 -\ \ \ \ \ \ \ \ then\ collect{\isacharunderscore}duplicates\ xs\ ys\ zs\isanewline
102.709 -\ \ \ \ \ \ \ \ else\ collect{\isacharunderscore}duplicates\ xs\ {\isacharparenleft}z{\isacharhash}ys{\isacharparenright}\ zs\isanewline
102.710 -\ \ \ \ \ \ else\ collect{\isacharunderscore}duplicates\ {\isacharparenleft}z{\isacharhash}xs{\isacharparenright}\ {\isacharparenleft}z{\isacharhash}ys{\isacharparenright}\ zs{\isacharparenright}{\isachardoublequoteclose}%
102.711 -\begin{isamarkuptext}%
102.712 -The membership test during preprocessing is rewritten,
102.713 - resulting in \isa{op\ mem}, which itself
102.714 - performs an explicit equality check.%
102.715 -\end{isamarkuptext}%
102.716 -\isamarkuptrue%
102.717 -\isacommand{export{\isacharunderscore}code}\isamarkupfalse%
102.718 -\ collect{\isacharunderscore}duplicates\ \isakeyword{in}\ SML\ \isakeyword{file}\ {\isachardoublequoteopen}examples{\isacharslash}collect{\isacharunderscore}duplicates{\isachardot}ML{\isachardoublequoteclose}%
102.719 -\begin{isamarkuptext}%
102.720 -\lstsml{Thy/examples/collect_duplicates.ML}%
102.721 -\end{isamarkuptext}%
102.722 -\isamarkuptrue%
102.723 -%
102.724 -\begin{isamarkuptext}%
102.725 -Obviously, polymorphic equality is implemented the Haskell
102.726 - way using a type class. How is this achieved? HOL introduces
102.727 - an explicit class \isa{eq} with a corresponding operation
102.728 - \isa{eq{\isacharunderscore}class{\isachardot}eq} such that \isa{eq{\isacharunderscore}class{\isachardot}eq\ x\ y\ {\isacharequal}\ {\isacharparenleft}x\ {\isacharequal}\ y{\isacharparenright}}.
102.729 - The preprocessing framework does the rest.
102.730 - For datatypes, instances of \isa{eq} are implicitly derived
102.731 - when possible. For other types, you may instantiate \isa{eq}
102.732 - manually like any other type class.
102.733 -
102.734 - Though this \isa{eq} class is designed to get rarely in
102.735 - the way, a subtlety
102.736 - enters the stage when definitions of overloaded constants
102.737 - are dependent on operational equality. For example, let
102.738 - us define a lexicographic ordering on tuples:%
102.739 -\end{isamarkuptext}%
102.740 -\isamarkuptrue%
102.741 -\isacommand{instantiation}\isamarkupfalse%
102.742 -\ {\isacharasterisk}\ {\isacharcolon}{\isacharcolon}\ {\isacharparenleft}ord{\isacharcomma}\ ord{\isacharparenright}\ ord\isanewline
102.743 -\isakeyword{begin}\isanewline
102.744 -\isanewline
102.745 -\isacommand{definition}\isamarkupfalse%
102.746 -\isanewline
102.747 -\ \ {\isacharbrackleft}code\ func\ del{\isacharbrackright}{\isacharcolon}\ {\isachardoublequoteopen}p{\isadigit{1}}\ {\isacharless}\ p{\isadigit{2}}\ {\isasymlongleftrightarrow}\ {\isacharparenleft}let\ {\isacharparenleft}x{\isadigit{1}}{\isacharcomma}\ y{\isadigit{1}}{\isacharparenright}\ {\isacharequal}\ p{\isadigit{1}}{\isacharsemicolon}\ {\isacharparenleft}x{\isadigit{2}}{\isacharcomma}\ y{\isadigit{2}}{\isacharparenright}\ {\isacharequal}\ p{\isadigit{2}}\ in\isanewline
102.748 -\ \ \ \ x{\isadigit{1}}\ {\isacharless}\ x{\isadigit{2}}\ {\isasymor}\ {\isacharparenleft}x{\isadigit{1}}\ {\isacharequal}\ x{\isadigit{2}}\ {\isasymand}\ y{\isadigit{1}}\ {\isacharless}\ y{\isadigit{2}}{\isacharparenright}{\isacharparenright}{\isachardoublequoteclose}\isanewline
102.749 -\isanewline
102.750 -\isacommand{definition}\isamarkupfalse%
102.751 -\isanewline
102.752 -\ \ {\isacharbrackleft}code\ func\ del{\isacharbrackright}{\isacharcolon}\ {\isachardoublequoteopen}p{\isadigit{1}}\ {\isasymle}\ p{\isadigit{2}}\ {\isasymlongleftrightarrow}\ {\isacharparenleft}let\ {\isacharparenleft}x{\isadigit{1}}{\isacharcomma}\ y{\isadigit{1}}{\isacharparenright}\ {\isacharequal}\ p{\isadigit{1}}{\isacharsemicolon}\ {\isacharparenleft}x{\isadigit{2}}{\isacharcomma}\ y{\isadigit{2}}{\isacharparenright}\ {\isacharequal}\ p{\isadigit{2}}\ in\isanewline
102.753 -\ \ \ \ x{\isadigit{1}}\ {\isacharless}\ x{\isadigit{2}}\ {\isasymor}\ {\isacharparenleft}x{\isadigit{1}}\ {\isacharequal}\ x{\isadigit{2}}\ {\isasymand}\ y{\isadigit{1}}\ {\isasymle}\ y{\isadigit{2}}{\isacharparenright}{\isacharparenright}{\isachardoublequoteclose}\isanewline
102.754 -\isanewline
102.755 -\isacommand{instance}\isamarkupfalse%
102.756 -%
102.757 -\isadelimproof
102.758 -\ %
102.759 -\endisadelimproof
102.760 -%
102.761 -\isatagproof
102.762 -\isacommand{{\isachardot}{\isachardot}}\isamarkupfalse%
102.763 -%
102.764 -\endisatagproof
102.765 -{\isafoldproof}%
102.766 -%
102.767 -\isadelimproof
102.768 -%
102.769 -\endisadelimproof
102.770 -\isanewline
102.771 -\isanewline
102.772 -\isacommand{end}\isamarkupfalse%
102.773 -\isanewline
102.774 -\isanewline
102.775 -\isacommand{lemma}\isamarkupfalse%
102.776 -\ ord{\isacharunderscore}prod\ {\isacharbrackleft}code\ func{\isacharbrackright}{\isacharcolon}\isanewline
102.777 -\ \ {\isachardoublequoteopen}{\isacharparenleft}x{\isadigit{1}}\ {\isasymColon}\ {\isacharprime}a{\isasymColon}ord{\isacharcomma}\ y{\isadigit{1}}\ {\isasymColon}\ {\isacharprime}b{\isasymColon}ord{\isacharparenright}\ {\isacharless}\ {\isacharparenleft}x{\isadigit{2}}{\isacharcomma}\ y{\isadigit{2}}{\isacharparenright}\ {\isasymlongleftrightarrow}\ x{\isadigit{1}}\ {\isacharless}\ x{\isadigit{2}}\ {\isasymor}\ {\isacharparenleft}x{\isadigit{1}}\ {\isacharequal}\ x{\isadigit{2}}\ {\isasymand}\ y{\isadigit{1}}\ {\isacharless}\ y{\isadigit{2}}{\isacharparenright}{\isachardoublequoteclose}\isanewline
102.778 -\ \ {\isachardoublequoteopen}{\isacharparenleft}x{\isadigit{1}}\ {\isasymColon}\ {\isacharprime}a{\isasymColon}ord{\isacharcomma}\ y{\isadigit{1}}\ {\isasymColon}\ {\isacharprime}b{\isasymColon}ord{\isacharparenright}\ {\isasymle}\ {\isacharparenleft}x{\isadigit{2}}{\isacharcomma}\ y{\isadigit{2}}{\isacharparenright}\ {\isasymlongleftrightarrow}\ x{\isadigit{1}}\ {\isacharless}\ x{\isadigit{2}}\ {\isasymor}\ {\isacharparenleft}x{\isadigit{1}}\ {\isacharequal}\ x{\isadigit{2}}\ {\isasymand}\ y{\isadigit{1}}\ {\isasymle}\ y{\isadigit{2}}{\isacharparenright}{\isachardoublequoteclose}\isanewline
102.779 -%
102.780 -\isadelimproof
102.781 -\ \ %
102.782 -\endisadelimproof
102.783 -%
102.784 -\isatagproof
102.785 -\isacommand{unfolding}\isamarkupfalse%
102.786 -\ less{\isacharunderscore}prod{\isacharunderscore}def\ less{\isacharunderscore}eq{\isacharunderscore}prod{\isacharunderscore}def\ \isacommand{by}\isamarkupfalse%
102.787 -\ simp{\isacharunderscore}all%
102.788 -\endisatagproof
102.789 -{\isafoldproof}%
102.790 -%
102.791 -\isadelimproof
102.792 -%
102.793 -\endisadelimproof
102.794 -%
102.795 -\begin{isamarkuptext}%
102.796 -Then code generation will fail. Why? The definition
102.797 - of \isa{op\ {\isasymle}} depends on equality on both arguments,
102.798 - which are polymorphic and impose an additional \isa{eq}
102.799 - class constraint, thus violating the type discipline
102.800 - for class operations.
102.801 -
102.802 - The solution is to add \isa{eq} explicitly to the first sort arguments in the
102.803 - code theorems:%
102.804 -\end{isamarkuptext}%
102.805 -\isamarkuptrue%
102.806 -\isacommand{lemma}\isamarkupfalse%
102.807 -\ ord{\isacharunderscore}prod{\isacharunderscore}code\ {\isacharbrackleft}code\ func{\isacharbrackright}{\isacharcolon}\isanewline
102.808 -\ \ {\isachardoublequoteopen}{\isacharparenleft}x{\isadigit{1}}\ {\isasymColon}\ {\isacharprime}a{\isasymColon}{\isacharbraceleft}ord{\isacharcomma}\ eq{\isacharbraceright}{\isacharcomma}\ y{\isadigit{1}}\ {\isasymColon}\ {\isacharprime}b{\isasymColon}ord{\isacharparenright}\ {\isacharless}\ {\isacharparenleft}x{\isadigit{2}}{\isacharcomma}\ y{\isadigit{2}}{\isacharparenright}\ {\isasymlongleftrightarrow}\isanewline
102.809 -\ \ \ \ x{\isadigit{1}}\ {\isacharless}\ x{\isadigit{2}}\ {\isasymor}\ {\isacharparenleft}x{\isadigit{1}}\ {\isacharequal}\ x{\isadigit{2}}\ {\isasymand}\ y{\isadigit{1}}\ {\isacharless}\ y{\isadigit{2}}{\isacharparenright}{\isachardoublequoteclose}\isanewline
102.810 -\ \ {\isachardoublequoteopen}{\isacharparenleft}x{\isadigit{1}}\ {\isasymColon}\ {\isacharprime}a{\isasymColon}{\isacharbraceleft}ord{\isacharcomma}\ eq{\isacharbraceright}{\isacharcomma}\ y{\isadigit{1}}\ {\isasymColon}\ {\isacharprime}b{\isasymColon}ord{\isacharparenright}\ {\isasymle}\ {\isacharparenleft}x{\isadigit{2}}{\isacharcomma}\ y{\isadigit{2}}{\isacharparenright}\ {\isasymlongleftrightarrow}\isanewline
102.811 -\ \ \ \ x{\isadigit{1}}\ {\isacharless}\ x{\isadigit{2}}\ {\isasymor}\ {\isacharparenleft}x{\isadigit{1}}\ {\isacharequal}\ x{\isadigit{2}}\ {\isasymand}\ y{\isadigit{1}}\ {\isasymle}\ y{\isadigit{2}}{\isacharparenright}{\isachardoublequoteclose}\isanewline
102.812 -%
102.813 -\isadelimproof
102.814 -\ \ %
102.815 -\endisadelimproof
102.816 -%
102.817 -\isatagproof
102.818 -\isacommand{unfolding}\isamarkupfalse%
102.819 -\ ord{\isacharunderscore}prod\ \isacommand{by}\isamarkupfalse%
102.820 -\ rule{\isacharplus}%
102.821 -\endisatagproof
102.822 -{\isafoldproof}%
102.823 -%
102.824 -\isadelimproof
102.825 -%
102.826 -\endisadelimproof
102.827 -%
102.828 -\begin{isamarkuptext}%
102.829 -\noindent Then code generation succeeds:%
102.830 -\end{isamarkuptext}%
102.831 -\isamarkuptrue%
102.832 -\isacommand{export{\isacharunderscore}code}\isamarkupfalse%
102.833 -\ {\isachardoublequoteopen}op\ {\isasymle}\ {\isasymColon}\ {\isacharprime}a{\isasymColon}{\isacharbraceleft}eq{\isacharcomma}\ ord{\isacharbraceright}\ {\isasymtimes}\ {\isacharprime}b{\isasymColon}ord\ {\isasymRightarrow}\ {\isacharprime}a\ {\isasymtimes}\ {\isacharprime}b\ {\isasymRightarrow}\ bool{\isachardoublequoteclose}\isanewline
102.834 -\ \ \isakeyword{in}\ SML\ \isakeyword{file}\ {\isachardoublequoteopen}examples{\isacharslash}lexicographic{\isachardot}ML{\isachardoublequoteclose}%
102.835 -\begin{isamarkuptext}%
102.836 -\lstsml{Thy/examples/lexicographic.ML}%
102.837 -\end{isamarkuptext}%
102.838 -\isamarkuptrue%
102.839 -%
102.840 -\begin{isamarkuptext}%
102.841 -In general, code theorems for overloaded constants may have more
102.842 - restrictive sort constraints than the underlying instance relation
102.843 - between class and type constructor as long as the whole system of
102.844 - constraints is coregular; code theorems violating coregularity
102.845 - are rejected immediately. Consequently, it might be necessary
102.846 - to delete disturbing theorems in the code theorem table,
102.847 - as we have done here with the original definitions \isa{less{\isacharunderscore}prod{\isacharunderscore}def}
102.848 - and \isa{less{\isacharunderscore}eq{\isacharunderscore}prod{\isacharunderscore}def}.
102.849 -
102.850 - In some cases, the automatically derived defining equations
102.851 - for equality on a particular type may not be appropriate.
102.852 - As example, watch the following datatype representing
102.853 - monomorphic parametric types (where type constructors
102.854 - are referred to by natural numbers):%
102.855 -\end{isamarkuptext}%
102.856 -\isamarkuptrue%
102.857 -\isacommand{datatype}\isamarkupfalse%
102.858 -\ monotype\ {\isacharequal}\ Mono\ nat\ {\isachardoublequoteopen}monotype\ list{\isachardoublequoteclose}%
102.859 -\isadelimproof
102.860 -%
102.861 -\endisadelimproof
102.862 -%
102.863 -\isatagproof
102.864 -%
102.865 -\endisatagproof
102.866 -{\isafoldproof}%
102.867 -%
102.868 -\isadelimproof
102.869 -%
102.870 -\endisadelimproof
102.871 -%
102.872 -\begin{isamarkuptext}%
102.873 -Then code generation for SML would fail with a message
102.874 - that the generated code conains illegal mutual dependencies:
102.875 - the theorem \isa{Mono\ tyco{\isadigit{1}}\ typargs{\isadigit{1}}\ {\isacharequal}\ Mono\ tyco{\isadigit{2}}\ typargs{\isadigit{2}}\ {\isasymequiv}\ tyco{\isadigit{1}}\ {\isacharequal}\ tyco{\isadigit{2}}\ {\isasymand}\ typargs{\isadigit{1}}\ {\isacharequal}\ typargs{\isadigit{2}}} already requires the
102.876 - instance \isa{monotype\ {\isasymColon}\ eq}, which itself requires
102.877 - \isa{Mono\ tyco{\isadigit{1}}\ typargs{\isadigit{1}}\ {\isacharequal}\ Mono\ tyco{\isadigit{2}}\ typargs{\isadigit{2}}\ {\isasymequiv}\ tyco{\isadigit{1}}\ {\isacharequal}\ tyco{\isadigit{2}}\ {\isasymand}\ typargs{\isadigit{1}}\ {\isacharequal}\ typargs{\isadigit{2}}}; Haskell has no problem with mutually
102.878 - recursive \isa{instance} and \isa{function} definitions,
102.879 - but the SML serializer does not support this.
102.880 -
102.881 - In such cases, you have to provide you own equality equations
102.882 - involving auxiliary constants. In our case,
102.883 - \isa{list{\isacharunderscore}all{\isadigit{2}}} can do the job:%
102.884 -\end{isamarkuptext}%
102.885 -\isamarkuptrue%
102.886 -\isacommand{lemma}\isamarkupfalse%
102.887 -\ monotype{\isacharunderscore}eq{\isacharunderscore}list{\isacharunderscore}all{\isadigit{2}}\ {\isacharbrackleft}code\ func{\isacharbrackright}{\isacharcolon}\isanewline
102.888 -\ \ {\isachardoublequoteopen}Mono\ tyco{\isadigit{1}}\ typargs{\isadigit{1}}\ {\isacharequal}\ Mono\ tyco{\isadigit{2}}\ typargs{\isadigit{2}}\ {\isasymlongleftrightarrow}\isanewline
102.889 -\ \ \ \ \ tyco{\isadigit{1}}\ {\isacharequal}\ tyco{\isadigit{2}}\ {\isasymand}\ list{\isacharunderscore}all{\isadigit{2}}\ {\isacharparenleft}op\ {\isacharequal}{\isacharparenright}\ typargs{\isadigit{1}}\ typargs{\isadigit{2}}{\isachardoublequoteclose}\isanewline
102.890 -%
102.891 -\isadelimproof
102.892 -\ \ %
102.893 -\endisadelimproof
102.894 -%
102.895 -\isatagproof
102.896 -\isacommand{by}\isamarkupfalse%
102.897 -\ {\isacharparenleft}simp\ add{\isacharcolon}\ list{\isacharunderscore}all{\isadigit{2}}{\isacharunderscore}eq\ {\isacharbrackleft}symmetric{\isacharbrackright}{\isacharparenright}%
102.898 -\endisatagproof
102.899 -{\isafoldproof}%
102.900 -%
102.901 -\isadelimproof
102.902 -%
102.903 -\endisadelimproof
102.904 -%
102.905 -\begin{isamarkuptext}%
102.906 -does not depend on instance \isa{monotype\ {\isasymColon}\ eq}:%
102.907 -\end{isamarkuptext}%
102.908 -\isamarkuptrue%
102.909 -\isacommand{export{\isacharunderscore}code}\isamarkupfalse%
102.910 -\ {\isachardoublequoteopen}op\ {\isacharequal}\ {\isacharcolon}{\isacharcolon}\ monotype\ {\isasymRightarrow}\ monotype\ {\isasymRightarrow}\ bool{\isachardoublequoteclose}\isanewline
102.911 -\ \ \isakeyword{in}\ SML\ \isakeyword{file}\ {\isachardoublequoteopen}examples{\isacharslash}monotype{\isachardot}ML{\isachardoublequoteclose}%
102.912 -\begin{isamarkuptext}%
102.913 -\lstsml{Thy/examples/monotype.ML}%
102.914 -\end{isamarkuptext}%
102.915 -\isamarkuptrue%
102.916 -%
102.917 -\isamarkupsubsection{Programs as sets of theorems%
102.918 -}
102.919 -\isamarkuptrue%
102.920 -%
102.921 -\begin{isamarkuptext}%
102.922 -As told in \secref{sec:concept}, code generation is based
102.923 - on a structured collection of code theorems.
102.924 - For explorative purpose, this collection
102.925 - may be inspected using the \isa{{\isasymCODETHMS}} command:%
102.926 -\end{isamarkuptext}%
102.927 -\isamarkuptrue%
102.928 -\isacommand{code{\isacharunderscore}thms}\isamarkupfalse%
102.929 -\ {\isachardoublequoteopen}op\ mod\ {\isacharcolon}{\isacharcolon}\ nat\ {\isasymRightarrow}\ nat\ {\isasymRightarrow}\ nat{\isachardoublequoteclose}%
102.930 -\begin{isamarkuptext}%
102.931 -\noindent prints a table with \emph{all} defining equations
102.932 - for \isa{op\ mod}, including
102.933 - \emph{all} defining equations those equations depend
102.934 - on recursivly. \isa{{\isasymCODETHMS}} provides a convenient
102.935 - mechanism to inspect the impact of a preprocessor setup
102.936 - on defining equations.
102.937 -
102.938 - Similarly, the \isa{{\isasymCODEDEPS}} command shows a graph
102.939 - visualizing dependencies between defining equations.%
102.940 -\end{isamarkuptext}%
102.941 -\isamarkuptrue%
102.942 -%
102.943 -\isamarkupsubsection{Constructor sets for datatypes%
102.944 -}
102.945 -\isamarkuptrue%
102.946 -%
102.947 -\begin{isamarkuptext}%
102.948 -Conceptually, any datatype is spanned by a set of
102.949 - \emph{constructors} of type \isa{{\isasymtau}\ {\isacharequal}\ {\isasymdots}\ {\isasymRightarrow}\ {\isasymkappa}\ {\isasymalpha}\isactrlisub {\isadigit{1}}\ {\isasymdots}\ {\isasymalpha}\isactrlisub n}
102.950 - where \isa{{\isacharbraceleft}{\isasymalpha}\isactrlisub {\isadigit{1}}{\isacharcomma}\ {\isasymdots}{\isacharcomma}\ {\isasymalpha}\isactrlisub n{\isacharbraceright}} is excactly the set of \emph{all}
102.951 - type variables in \isa{{\isasymtau}}. The HOL datatype package
102.952 - by default registers any new datatype in the table
102.953 - of datatypes, which may be inspected using
102.954 - the \isa{{\isasymPRINTCODESETUP}} command.
102.955 -
102.956 - In some cases, it may be convenient to alter or
102.957 - extend this table; as an example, we will develope an alternative
102.958 - representation of natural numbers as binary digits, whose
102.959 - size does increase logarithmically with its value, not linear
102.960 - \footnote{Indeed, the \isa{Efficient{\isacharunderscore}Nat} theory (see \ref{eff_nat})
102.961 - does something similar}. First, the digit representation:%
102.962 -\end{isamarkuptext}%
102.963 -\isamarkuptrue%
102.964 -\isacommand{definition}\isamarkupfalse%
102.965 -\ Dig{\isadigit{0}}\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymRightarrow}\ nat{\isachardoublequoteclose}\ \isakeyword{where}\isanewline
102.966 -\ \ {\isachardoublequoteopen}Dig{\isadigit{0}}\ n\ {\isacharequal}\ {\isadigit{2}}\ {\isacharasterisk}\ n{\isachardoublequoteclose}\isanewline
102.967 -\isanewline
102.968 -\isacommand{definition}\isamarkupfalse%
102.969 -\ Dig{\isadigit{1}}\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymRightarrow}\ nat{\isachardoublequoteclose}\ \isakeyword{where}\isanewline
102.970 -\ \ {\isachardoublequoteopen}Dig{\isadigit{1}}\ n\ {\isacharequal}\ Suc\ {\isacharparenleft}{\isadigit{2}}\ {\isacharasterisk}\ n{\isacharparenright}{\isachardoublequoteclose}%
102.971 -\begin{isamarkuptext}%
102.972 -\noindent We will use these two ">digits"< to represent natural numbers
102.973 - in binary digits, e.g.:%
102.974 -\end{isamarkuptext}%
102.975 -\isamarkuptrue%
102.976 -\isacommand{lemma}\isamarkupfalse%
102.977 -\ {\isadigit{4}}{\isadigit{2}}{\isacharcolon}\ {\isachardoublequoteopen}{\isadigit{4}}{\isadigit{2}}\ {\isacharequal}\ Dig{\isadigit{0}}\ {\isacharparenleft}Dig{\isadigit{1}}\ {\isacharparenleft}Dig{\isadigit{0}}\ {\isacharparenleft}Dig{\isadigit{1}}\ {\isacharparenleft}Dig{\isadigit{0}}\ {\isadigit{1}}{\isacharparenright}{\isacharparenright}{\isacharparenright}{\isacharparenright}{\isachardoublequoteclose}\isanewline
102.978 -%
102.979 -\isadelimproof
102.980 -\ \ %
102.981 -\endisadelimproof
102.982 -%
102.983 -\isatagproof
102.984 -\isacommand{by}\isamarkupfalse%
102.985 -\ {\isacharparenleft}simp\ add{\isacharcolon}\ Dig{\isadigit{0}}{\isacharunderscore}def\ Dig{\isadigit{1}}{\isacharunderscore}def{\isacharparenright}%
102.986 -\endisatagproof
102.987 -{\isafoldproof}%
102.988 -%
102.989 -\isadelimproof
102.990 -%
102.991 -\endisadelimproof
102.992 -%
102.993 -\begin{isamarkuptext}%
102.994 -\noindent Of course we also have to provide proper code equations for
102.995 - the operations, e.g. \isa{op\ {\isacharplus}}:%
102.996 -\end{isamarkuptext}%
102.997 -\isamarkuptrue%
102.998 -\isacommand{lemma}\isamarkupfalse%
102.999 -\ plus{\isacharunderscore}Dig\ {\isacharbrackleft}code\ func{\isacharbrackright}{\isacharcolon}\isanewline
102.1000 -\ \ {\isachardoublequoteopen}{\isadigit{0}}\ {\isacharplus}\ n\ {\isacharequal}\ n{\isachardoublequoteclose}\isanewline
102.1001 -\ \ {\isachardoublequoteopen}m\ {\isacharplus}\ {\isadigit{0}}\ {\isacharequal}\ m{\isachardoublequoteclose}\isanewline
102.1002 -\ \ {\isachardoublequoteopen}{\isadigit{1}}\ {\isacharplus}\ Dig{\isadigit{0}}\ n\ {\isacharequal}\ Dig{\isadigit{1}}\ n{\isachardoublequoteclose}\isanewline
102.1003 -\ \ {\isachardoublequoteopen}Dig{\isadigit{0}}\ m\ {\isacharplus}\ {\isadigit{1}}\ {\isacharequal}\ Dig{\isadigit{1}}\ m{\isachardoublequoteclose}\isanewline
102.1004 -\ \ {\isachardoublequoteopen}{\isadigit{1}}\ {\isacharplus}\ Dig{\isadigit{1}}\ n\ {\isacharequal}\ Dig{\isadigit{0}}\ {\isacharparenleft}n\ {\isacharplus}\ {\isadigit{1}}{\isacharparenright}{\isachardoublequoteclose}\isanewline
102.1005 -\ \ {\isachardoublequoteopen}Dig{\isadigit{1}}\ m\ {\isacharplus}\ {\isadigit{1}}\ {\isacharequal}\ Dig{\isadigit{0}}\ {\isacharparenleft}m\ {\isacharplus}\ {\isadigit{1}}{\isacharparenright}{\isachardoublequoteclose}\isanewline
102.1006 -\ \ {\isachardoublequoteopen}Dig{\isadigit{0}}\ m\ {\isacharplus}\ Dig{\isadigit{0}}\ n\ {\isacharequal}\ Dig{\isadigit{0}}\ {\isacharparenleft}m\ {\isacharplus}\ n{\isacharparenright}{\isachardoublequoteclose}\isanewline
102.1007 -\ \ {\isachardoublequoteopen}Dig{\isadigit{0}}\ m\ {\isacharplus}\ Dig{\isadigit{1}}\ n\ {\isacharequal}\ Dig{\isadigit{1}}\ {\isacharparenleft}m\ {\isacharplus}\ n{\isacharparenright}{\isachardoublequoteclose}\isanewline
102.1008 -\ \ {\isachardoublequoteopen}Dig{\isadigit{1}}\ m\ {\isacharplus}\ Dig{\isadigit{0}}\ n\ {\isacharequal}\ Dig{\isadigit{1}}\ {\isacharparenleft}m\ {\isacharplus}\ n{\isacharparenright}{\isachardoublequoteclose}\isanewline
102.1009 -\ \ {\isachardoublequoteopen}Dig{\isadigit{1}}\ m\ {\isacharplus}\ Dig{\isadigit{1}}\ n\ {\isacharequal}\ Dig{\isadigit{0}}\ {\isacharparenleft}m\ {\isacharplus}\ n\ {\isacharplus}\ {\isadigit{1}}{\isacharparenright}{\isachardoublequoteclose}\isanewline
102.1010 -%
102.1011 -\isadelimproof
102.1012 -\ \ %
102.1013 -\endisadelimproof
102.1014 -%
102.1015 -\isatagproof
102.1016 -\isacommand{by}\isamarkupfalse%
102.1017 -\ {\isacharparenleft}simp{\isacharunderscore}all\ add{\isacharcolon}\ Dig{\isadigit{0}}{\isacharunderscore}def\ Dig{\isadigit{1}}{\isacharunderscore}def{\isacharparenright}%
102.1018 -\endisatagproof
102.1019 -{\isafoldproof}%
102.1020 -%
102.1021 -\isadelimproof
102.1022 -%
102.1023 -\endisadelimproof
102.1024 -%
102.1025 -\begin{isamarkuptext}%
102.1026 -\noindent We then instruct the code generator to view \isa{{\isadigit{0}}},
102.1027 - \isa{{\isadigit{1}}}, \isa{Dig{\isadigit{0}}} and \isa{Dig{\isadigit{1}}} as
102.1028 - datatype constructors:%
102.1029 -\end{isamarkuptext}%
102.1030 -\isamarkuptrue%
102.1031 -\isacommand{code{\isacharunderscore}datatype}\isamarkupfalse%
102.1032 -\ {\isachardoublequoteopen}{\isadigit{0}}{\isasymColon}nat{\isachardoublequoteclose}\ {\isachardoublequoteopen}{\isadigit{1}}{\isasymColon}nat{\isachardoublequoteclose}\ Dig{\isadigit{0}}\ Dig{\isadigit{1}}%
102.1033 -\begin{isamarkuptext}%
102.1034 -\noindent For the former constructor \isa{Suc}, we provide a code
102.1035 - equation and remove some parts of the default code generator setup
102.1036 - which are an obstacle here:%
102.1037 -\end{isamarkuptext}%
102.1038 -\isamarkuptrue%
102.1039 -\isacommand{lemma}\isamarkupfalse%
102.1040 -\ Suc{\isacharunderscore}Dig\ {\isacharbrackleft}code\ func{\isacharbrackright}{\isacharcolon}\isanewline
102.1041 -\ \ {\isachardoublequoteopen}Suc\ n\ {\isacharequal}\ n\ {\isacharplus}\ {\isadigit{1}}{\isachardoublequoteclose}\isanewline
102.1042 -%
102.1043 -\isadelimproof
102.1044 -\ \ %
102.1045 -\endisadelimproof
102.1046 -%
102.1047 -\isatagproof
102.1048 -\isacommand{by}\isamarkupfalse%
102.1049 -\ simp%
102.1050 -\endisatagproof
102.1051 -{\isafoldproof}%
102.1052 -%
102.1053 -\isadelimproof
102.1054 -\isanewline
102.1055 -%
102.1056 -\endisadelimproof
102.1057 -\isanewline
102.1058 -\isacommand{declare}\isamarkupfalse%
102.1059 -\ One{\isacharunderscore}nat{\isacharunderscore}def\ {\isacharbrackleft}code\ inline\ del{\isacharbrackright}\isanewline
102.1060 -\isacommand{declare}\isamarkupfalse%
102.1061 -\ add{\isacharunderscore}Suc{\isacharunderscore}shift\ {\isacharbrackleft}code\ func\ del{\isacharbrackright}%
102.1062 -\begin{isamarkuptext}%
102.1063 -\noindent This yields the following code:%
102.1064 -\end{isamarkuptext}%
102.1065 -\isamarkuptrue%
102.1066 -\isacommand{export{\isacharunderscore}code}\isamarkupfalse%
102.1067 -\ {\isachardoublequoteopen}op\ {\isacharplus}\ {\isasymColon}\ nat\ {\isasymRightarrow}\ nat\ {\isasymRightarrow}\ nat{\isachardoublequoteclose}\ \ \isakeyword{in}\ SML\ \isakeyword{file}\ {\isachardoublequoteopen}examples{\isacharslash}nat{\isacharunderscore}binary{\isachardot}ML{\isachardoublequoteclose}%
102.1068 -\begin{isamarkuptext}%
102.1069 -\lstsml{Thy/examples/nat_binary.ML}%
102.1070 -\end{isamarkuptext}%
102.1071 -\isamarkuptrue%
102.1072 -%
102.1073 -\begin{isamarkuptext}%
102.1074 -\medskip
102.1075 -
102.1076 - From this example, it can be easily glimpsed that using own constructor sets
102.1077 - is a little delicate since it changes the set of valid patterns for values
102.1078 - of that type. Without going into much detail, here some practical hints:
102.1079 -
102.1080 - \begin{itemize}
102.1081 - \item When changing the constuctor set for datatypes, take care to
102.1082 - provide an alternative for the \isa{case} combinator (e.g. by replacing
102.1083 - it using the preprocessor).
102.1084 - \item Values in the target language need not to be normalized -- different
102.1085 - values in the target language may represent the same value in the
102.1086 - logic (e.g. \isa{Dig{\isadigit{1}}\ {\isadigit{0}}\ {\isacharequal}\ {\isadigit{1}}}).
102.1087 - \item Usually, a good methodology to deal with the subleties of pattern
102.1088 - matching is to see the type as an abstract type: provide a set
102.1089 - of operations which operate on the concrete representation of the type,
102.1090 - and derive further operations by combinations of these primitive ones,
102.1091 - without relying on a particular representation.
102.1092 - \end{itemize}%
102.1093 -\end{isamarkuptext}%
102.1094 -\isamarkuptrue%
102.1095 -%
102.1096 -\isadeliminvisible
102.1097 -%
102.1098 -\endisadeliminvisible
102.1099 -%
102.1100 -\isataginvisible
102.1101 -\isacommand{code{\isacharunderscore}datatype}\isamarkupfalse%
102.1102 -\ {\isachardoublequoteopen}{\isadigit{0}}{\isacharcolon}{\isacharcolon}nat{\isachardoublequoteclose}\ Suc\isanewline
102.1103 -\isacommand{declare}\isamarkupfalse%
102.1104 -\ plus{\isacharunderscore}Dig\ {\isacharbrackleft}code\ func\ del{\isacharbrackright}\isanewline
102.1105 -\isacommand{declare}\isamarkupfalse%
102.1106 -\ One{\isacharunderscore}nat{\isacharunderscore}def\ {\isacharbrackleft}code\ inline{\isacharbrackright}\isanewline
102.1107 -\isacommand{declare}\isamarkupfalse%
102.1108 -\ add{\isacharunderscore}Suc{\isacharunderscore}shift\ {\isacharbrackleft}code\ func{\isacharbrackright}\ \isanewline
102.1109 -\isacommand{lemma}\isamarkupfalse%
102.1110 -\ {\isacharbrackleft}code\ func{\isacharbrackright}{\isacharcolon}\ {\isachardoublequoteopen}{\isadigit{0}}\ {\isacharplus}\ n\ {\isacharequal}\ {\isacharparenleft}n\ {\isasymColon}\ nat{\isacharparenright}{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse%
102.1111 -\ simp%
102.1112 -\endisataginvisible
102.1113 -{\isafoldinvisible}%
102.1114 -%
102.1115 -\isadeliminvisible
102.1116 -%
102.1117 -\endisadeliminvisible
102.1118 -%
102.1119 -\isamarkupsubsection{Customizing serialization%
102.1120 -}
102.1121 -\isamarkuptrue%
102.1122 -%
102.1123 -\isamarkupsubsubsection{Basics%
102.1124 -}
102.1125 -\isamarkuptrue%
102.1126 -%
102.1127 -\begin{isamarkuptext}%
102.1128 -Consider the following function and its corresponding
102.1129 - SML code:%
102.1130 -\end{isamarkuptext}%
102.1131 -\isamarkuptrue%
102.1132 -\isacommand{primrec}\isamarkupfalse%
102.1133 -\isanewline
102.1134 -\ \ in{\isacharunderscore}interval\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymtimes}\ nat\ {\isasymRightarrow}\ nat\ {\isasymRightarrow}\ bool{\isachardoublequoteclose}\ \isakeyword{where}\isanewline
102.1135 -\ \ {\isachardoublequoteopen}in{\isacharunderscore}interval\ {\isacharparenleft}k{\isacharcomma}\ l{\isacharparenright}\ n\ {\isasymlongleftrightarrow}\ k\ {\isasymle}\ n\ {\isasymand}\ n\ {\isasymle}\ l{\isachardoublequoteclose}%
102.1136 -\isadelimtt
102.1137 -%
102.1138 -\endisadelimtt
102.1139 -%
102.1140 -\isatagtt
102.1141 -%
102.1142 -\endisatagtt
102.1143 -{\isafoldtt}%
102.1144 -%
102.1145 -\isadelimtt
102.1146 -%
102.1147 -\endisadelimtt
102.1148 -\isacommand{export{\isacharunderscore}code}\isamarkupfalse%
102.1149 -\ in{\isacharunderscore}interval\ \isakeyword{in}\ SML\ \isakeyword{file}\ {\isachardoublequoteopen}examples{\isacharslash}bool{\isacharunderscore}literal{\isachardot}ML{\isachardoublequoteclose}%
102.1150 -\begin{isamarkuptext}%
102.1151 -\lstsml{Thy/examples/bool_literal.ML}
102.1152 -
102.1153 - \noindent Though this is correct code, it is a little bit unsatisfactory:
102.1154 - boolean values and operators are materialized as distinguished
102.1155 - entities with have nothing to do with the SML-builtin notion
102.1156 - of \qt{bool}. This results in less readable code;
102.1157 - additionally, eager evaluation may cause programs to
102.1158 - loop or break which would perfectly terminate when
102.1159 - the existing SML \qt{bool} would be used. To map
102.1160 - the HOL \qt{bool} on SML \qt{bool}, we may use
102.1161 - \qn{custom serializations}:%
102.1162 -\end{isamarkuptext}%
102.1163 -\isamarkuptrue%
102.1164 -%
102.1165 -\isadelimtt
102.1166 -%
102.1167 -\endisadelimtt
102.1168 -%
102.1169 -\isatagtt
102.1170 -\isacommand{code{\isacharunderscore}type}\isamarkupfalse%
102.1171 -\ bool\isanewline
102.1172 -\ \ {\isacharparenleft}SML\ {\isachardoublequoteopen}bool{\isachardoublequoteclose}{\isacharparenright}\isanewline
102.1173 -\isacommand{code{\isacharunderscore}const}\isamarkupfalse%
102.1174 -\ True\ \isakeyword{and}\ False\ \isakeyword{and}\ {\isachardoublequoteopen}op\ {\isasymand}{\isachardoublequoteclose}\isanewline
102.1175 -\ \ {\isacharparenleft}SML\ {\isachardoublequoteopen}true{\isachardoublequoteclose}\ \isakeyword{and}\ {\isachardoublequoteopen}false{\isachardoublequoteclose}\ \isakeyword{and}\ {\isachardoublequoteopen}{\isacharunderscore}\ andalso\ {\isacharunderscore}{\isachardoublequoteclose}{\isacharparenright}%
102.1176 -\endisatagtt
102.1177 -{\isafoldtt}%
102.1178 -%
102.1179 -\isadelimtt
102.1180 -%
102.1181 -\endisadelimtt
102.1182 -%
102.1183 -\begin{isamarkuptext}%
102.1184 -The \isa{{\isasymCODETYPE}} commad takes a type constructor
102.1185 - as arguments together with a list of custom serializations.
102.1186 - Each custom serialization starts with a target language
102.1187 - identifier followed by an expression, which during
102.1188 - code serialization is inserted whenever the type constructor
102.1189 - would occur. For constants, \isa{{\isasymCODECONST}} implements
102.1190 - the corresponding mechanism. Each ``\verb|_|'' in
102.1191 - a serialization expression is treated as a placeholder
102.1192 - for the type constructor's (the constant's) arguments.%
102.1193 -\end{isamarkuptext}%
102.1194 -\isamarkuptrue%
102.1195 -\isacommand{export{\isacharunderscore}code}\isamarkupfalse%
102.1196 -\ in{\isacharunderscore}interval\ \ \isakeyword{in}\ SML\ \isakeyword{file}\ {\isachardoublequoteopen}examples{\isacharslash}bool{\isacharunderscore}mlbool{\isachardot}ML{\isachardoublequoteclose}%
102.1197 -\begin{isamarkuptext}%
102.1198 -\lstsml{Thy/examples/bool_mlbool.ML}
102.1199 -
102.1200 - \noindent This still is not perfect: the parentheses
102.1201 - around the \qt{andalso} expression are superfluous.
102.1202 - Though the serializer
102.1203 - by no means attempts to imitate the rich Isabelle syntax
102.1204 - framework, it provides some common idioms, notably
102.1205 - associative infixes with precedences which may be used here:%
102.1206 -\end{isamarkuptext}%
102.1207 -\isamarkuptrue%
102.1208 -%
102.1209 -\isadelimtt
102.1210 -%
102.1211 -\endisadelimtt
102.1212 -%
102.1213 -\isatagtt
102.1214 -\isacommand{code{\isacharunderscore}const}\isamarkupfalse%
102.1215 -\ {\isachardoublequoteopen}op\ {\isasymand}{\isachardoublequoteclose}\isanewline
102.1216 -\ \ {\isacharparenleft}SML\ \isakeyword{infixl}\ {\isadigit{1}}\ {\isachardoublequoteopen}andalso{\isachardoublequoteclose}{\isacharparenright}%
102.1217 -\endisatagtt
102.1218 -{\isafoldtt}%
102.1219 -%
102.1220 -\isadelimtt
102.1221 -%
102.1222 -\endisadelimtt
102.1223 -\isanewline
102.1224 -\isanewline
102.1225 -\isacommand{export{\isacharunderscore}code}\isamarkupfalse%
102.1226 -\ in{\isacharunderscore}interval\ \ \isakeyword{in}\ SML\ \isakeyword{file}\ {\isachardoublequoteopen}examples{\isacharslash}bool{\isacharunderscore}infix{\isachardot}ML{\isachardoublequoteclose}%
102.1227 -\begin{isamarkuptext}%
102.1228 -\lstsml{Thy/examples/bool_infix.ML}
102.1229 -
102.1230 - \medskip
102.1231 -
102.1232 - Next, we try to map HOL pairs to SML pairs, using the
102.1233 - infix ``\verb|*|'' type constructor and parentheses:%
102.1234 -\end{isamarkuptext}%
102.1235 -\isamarkuptrue%
102.1236 -%
102.1237 -\isadelimtt
102.1238 -%
102.1239 -\endisadelimtt
102.1240 -%
102.1241 -\isatagtt
102.1242 -\isacommand{code{\isacharunderscore}type}\isamarkupfalse%
102.1243 -\ {\isacharasterisk}\isanewline
102.1244 -\ \ {\isacharparenleft}SML\ \isakeyword{infix}\ {\isadigit{2}}\ {\isachardoublequoteopen}{\isacharasterisk}{\isachardoublequoteclose}{\isacharparenright}\isanewline
102.1245 -\isacommand{code{\isacharunderscore}const}\isamarkupfalse%
102.1246 -\ Pair\isanewline
102.1247 -\ \ {\isacharparenleft}SML\ {\isachardoublequoteopen}{\isacharbang}{\isacharparenleft}{\isacharparenleft}{\isacharunderscore}{\isacharparenright}{\isacharcomma}{\isacharslash}\ {\isacharparenleft}{\isacharunderscore}{\isacharparenright}{\isacharparenright}{\isachardoublequoteclose}{\isacharparenright}%
102.1248 -\endisatagtt
102.1249 -{\isafoldtt}%
102.1250 -%
102.1251 -\isadelimtt
102.1252 -%
102.1253 -\endisadelimtt
102.1254 -%
102.1255 -\begin{isamarkuptext}%
102.1256 -The initial bang ``\verb|!|'' tells the serializer to never put
102.1257 - parentheses around the whole expression (they are already present),
102.1258 - while the parentheses around argument place holders
102.1259 - tell not to put parentheses around the arguments.
102.1260 - The slash ``\verb|/|'' (followed by arbitrary white space)
102.1261 - inserts a space which may be used as a break if necessary
102.1262 - during pretty printing.
102.1263 -
102.1264 - These examples give a glimpse what mechanisms
102.1265 - custom serializations provide; however their usage
102.1266 - requires careful thinking in order not to introduce
102.1267 - inconsistencies -- or, in other words:
102.1268 - custom serializations are completely axiomatic.
102.1269 -
102.1270 - A further noteworthy details is that any special
102.1271 - character in a custom serialization may be quoted
102.1272 - using ``\verb|'|''; thus, in
102.1273 - ``\verb|fn '_ => _|'' the first
102.1274 - ``\verb|_|'' is a proper underscore while the
102.1275 - second ``\verb|_|'' is a placeholder.
102.1276 -
102.1277 - The HOL theories provide further
102.1278 - examples for custom serializations.%
102.1279 -\end{isamarkuptext}%
102.1280 -\isamarkuptrue%
102.1281 -%
102.1282 -\isamarkupsubsubsection{Haskell serialization%
102.1283 -}
102.1284 -\isamarkuptrue%
102.1285 -%
102.1286 -\begin{isamarkuptext}%
102.1287 -For convenience, the default
102.1288 - HOL setup for Haskell maps the \isa{eq} class to
102.1289 - its counterpart in Haskell, giving custom serializations
102.1290 - for the class (\isa{{\isasymCODECLASS}}) and its operation:%
102.1291 -\end{isamarkuptext}%
102.1292 -\isamarkuptrue%
102.1293 -%
102.1294 -\isadelimtt
102.1295 -%
102.1296 -\endisadelimtt
102.1297 -%
102.1298 -\isatagtt
102.1299 -\isacommand{code{\isacharunderscore}class}\isamarkupfalse%
102.1300 -\ eq\isanewline
102.1301 -\ \ {\isacharparenleft}Haskell\ {\isachardoublequoteopen}Eq{\isachardoublequoteclose}\ \isakeyword{where}\ {\isachardoublequoteopen}op\ {\isacharequal}{\isachardoublequoteclose}\ {\isasymequiv}\ {\isachardoublequoteopen}{\isacharparenleft}{\isacharequal}{\isacharequal}{\isacharparenright}{\isachardoublequoteclose}{\isacharparenright}\isanewline
102.1302 -\isanewline
102.1303 -\isacommand{code{\isacharunderscore}const}\isamarkupfalse%
102.1304 -\ {\isachardoublequoteopen}op\ {\isacharequal}{\isachardoublequoteclose}\isanewline
102.1305 -\ \ {\isacharparenleft}Haskell\ \isakeyword{infixl}\ {\isadigit{4}}\ {\isachardoublequoteopen}{\isacharequal}{\isacharequal}{\isachardoublequoteclose}{\isacharparenright}%
102.1306 -\endisatagtt
102.1307 -{\isafoldtt}%
102.1308 -%
102.1309 -\isadelimtt
102.1310 -%
102.1311 -\endisadelimtt
102.1312 -%
102.1313 -\begin{isamarkuptext}%
102.1314 -A problem now occurs whenever a type which
102.1315 - is an instance of \isa{eq} in HOL is mapped
102.1316 - on a Haskell-builtin type which is also an instance
102.1317 - of Haskell \isa{Eq}:%
102.1318 -\end{isamarkuptext}%
102.1319 -\isamarkuptrue%
102.1320 -\isacommand{typedecl}\isamarkupfalse%
102.1321 -\ bar\isanewline
102.1322 -\isanewline
102.1323 -\isacommand{instantiation}\isamarkupfalse%
102.1324 -\ bar\ {\isacharcolon}{\isacharcolon}\ eq\isanewline
102.1325 -\isakeyword{begin}\isanewline
102.1326 -\isanewline
102.1327 -\isacommand{definition}\isamarkupfalse%
102.1328 -\ {\isachardoublequoteopen}eq{\isacharunderscore}class{\isachardot}eq\ {\isacharparenleft}x{\isasymColon}bar{\isacharparenright}\ y\ {\isasymlongleftrightarrow}\ x\ {\isacharequal}\ y{\isachardoublequoteclose}\isanewline
102.1329 -\isanewline
102.1330 -\isacommand{instance}\isamarkupfalse%
102.1331 -%
102.1332 -\isadelimproof
102.1333 -\ %
102.1334 -\endisadelimproof
102.1335 -%
102.1336 -\isatagproof
102.1337 -\isacommand{by}\isamarkupfalse%
102.1338 -\ default\ {\isacharparenleft}simp\ add{\isacharcolon}\ eq{\isacharunderscore}bar{\isacharunderscore}def{\isacharparenright}%
102.1339 -\endisatagproof
102.1340 -{\isafoldproof}%
102.1341 -%
102.1342 -\isadelimproof
102.1343 -%
102.1344 -\endisadelimproof
102.1345 -\isanewline
102.1346 -\isanewline
102.1347 -\isacommand{end}\isamarkupfalse%
102.1348 -\isanewline
102.1349 -%
102.1350 -\isadelimtt
102.1351 -\isanewline
102.1352 -%
102.1353 -\endisadelimtt
102.1354 -%
102.1355 -\isatagtt
102.1356 -\isacommand{code{\isacharunderscore}type}\isamarkupfalse%
102.1357 -\ bar\isanewline
102.1358 -\ \ {\isacharparenleft}Haskell\ {\isachardoublequoteopen}Integer{\isachardoublequoteclose}{\isacharparenright}%
102.1359 -\endisatagtt
102.1360 -{\isafoldtt}%
102.1361 -%
102.1362 -\isadelimtt
102.1363 -%
102.1364 -\endisadelimtt
102.1365 -%
102.1366 -\begin{isamarkuptext}%
102.1367 -The code generator would produce
102.1368 - an additional instance, which of course is rejected.
102.1369 - To suppress this additional instance, use
102.1370 - \isa{{\isasymCODEINSTANCE}}:%
102.1371 -\end{isamarkuptext}%
102.1372 -\isamarkuptrue%
102.1373 -%
102.1374 -\isadelimtt
102.1375 -%
102.1376 -\endisadelimtt
102.1377 -%
102.1378 -\isatagtt
102.1379 -\isacommand{code{\isacharunderscore}instance}\isamarkupfalse%
102.1380 -\ bar\ {\isacharcolon}{\isacharcolon}\ eq\isanewline
102.1381 -\ \ {\isacharparenleft}Haskell\ {\isacharminus}{\isacharparenright}%
102.1382 -\endisatagtt
102.1383 -{\isafoldtt}%
102.1384 -%
102.1385 -\isadelimtt
102.1386 -%
102.1387 -\endisadelimtt
102.1388 -%
102.1389 -\isamarkupsubsubsection{Pretty printing%
102.1390 -}
102.1391 -\isamarkuptrue%
102.1392 -%
102.1393 -\begin{isamarkuptext}%
102.1394 -The serializer provides ML interfaces to set up
102.1395 - pretty serializations for expressions like lists, numerals
102.1396 - and characters; these are
102.1397 - monolithic stubs and should only be used with the
102.1398 - theories introduced in \secref{sec:library}.%
102.1399 -\end{isamarkuptext}%
102.1400 -\isamarkuptrue%
102.1401 -%
102.1402 -\isamarkupsubsection{Cyclic module dependencies%
102.1403 -}
102.1404 -\isamarkuptrue%
102.1405 -%
102.1406 -\begin{isamarkuptext}%
102.1407 -Sometimes the awkward situation occurs that dependencies
102.1408 - between definitions introduce cyclic dependencies
102.1409 - between modules, which in the Haskell world leaves
102.1410 - you to the mercy of the Haskell implementation you are using,
102.1411 - while for SML code generation is not possible.
102.1412 -
102.1413 - A solution is to declare module names explicitly.
102.1414 - Let use assume the three cyclically dependent
102.1415 - modules are named \emph{A}, \emph{B} and \emph{C}.
102.1416 - Then, by stating%
102.1417 -\end{isamarkuptext}%
102.1418 -\isamarkuptrue%
102.1419 -\isacommand{code{\isacharunderscore}modulename}\isamarkupfalse%
102.1420 -\ SML\isanewline
102.1421 -\ \ A\ ABC\isanewline
102.1422 -\ \ B\ ABC\isanewline
102.1423 -\ \ C\ ABC%
102.1424 -\begin{isamarkuptext}%
102.1425 -we explicitly map all those modules on \emph{ABC},
102.1426 - resulting in an ad-hoc merge of this three modules
102.1427 - at serialization time.%
102.1428 -\end{isamarkuptext}%
102.1429 -\isamarkuptrue%
102.1430 -%
102.1431 -\isamarkupsubsection{Incremental code generation%
102.1432 -}
102.1433 -\isamarkuptrue%
102.1434 -%
102.1435 -\begin{isamarkuptext}%
102.1436 -Code generation is \emph{incremental}: theorems
102.1437 - and abstract intermediate code are cached and extended on demand.
102.1438 - The cache may be partially or fully dropped if the underlying
102.1439 - executable content of the theory changes.
102.1440 - Implementation of caching is supposed to transparently
102.1441 - hid away the details from the user. Anyway, caching
102.1442 - reaches the surface by using a slightly more general form
102.1443 - of the \isa{{\isasymCODETHMS}}, \isa{{\isasymCODEDEPS}}
102.1444 - and \isa{{\isasymEXPORTCODE}} commands: the list of constants
102.1445 - may be omitted. Then, all constants with code theorems
102.1446 - in the current cache are referred to.%
102.1447 -\end{isamarkuptext}%
102.1448 -\isamarkuptrue%
102.1449 -%
102.1450 -\isamarkupsection{ML interfaces \label{sec:ml}%
102.1451 -}
102.1452 -\isamarkuptrue%
102.1453 -%
102.1454 -\begin{isamarkuptext}%
102.1455 -Since the code generator framework not only aims to provide
102.1456 - a nice Isar interface but also to form a base for
102.1457 - code-generation-based applications, here a short
102.1458 - description of the most important ML interfaces.%
102.1459 -\end{isamarkuptext}%
102.1460 -\isamarkuptrue%
102.1461 -%
102.1462 -\isamarkupsubsection{Executable theory content: \isa{Code}%
102.1463 -}
102.1464 -\isamarkuptrue%
102.1465 -%
102.1466 -\begin{isamarkuptext}%
102.1467 -This Pure module implements the core notions of
102.1468 - executable content of a theory.%
102.1469 -\end{isamarkuptext}%
102.1470 -\isamarkuptrue%
102.1471 -%
102.1472 -\isamarkupsubsubsection{Managing executable content%
102.1473 -}
102.1474 -\isamarkuptrue%
102.1475 -%
102.1476 -\isadelimmlref
102.1477 -%
102.1478 -\endisadelimmlref
102.1479 -%
102.1480 -\isatagmlref
102.1481 -%
102.1482 -\begin{isamarkuptext}%
102.1483 -\begin{mldecls}
102.1484 - \indexml{Code.add\_func}\verb|Code.add_func: thm -> theory -> theory| \\
102.1485 - \indexml{Code.del\_func}\verb|Code.del_func: thm -> theory -> theory| \\
102.1486 - \indexml{Code.add\_funcl}\verb|Code.add_funcl: string * thm list Susp.T -> theory -> theory| \\
102.1487 - \indexml{Code.map\_pre}\verb|Code.map_pre: (MetaSimplifier.simpset -> MetaSimplifier.simpset) -> theory -> theory| \\
102.1488 - \indexml{Code.map\_post}\verb|Code.map_post: (MetaSimplifier.simpset -> MetaSimplifier.simpset) -> theory -> theory| \\
102.1489 - \indexml{Code.add\_functrans}\verb|Code.add_functrans: string * (theory -> thm list -> thm list option)|\isasep\isanewline%
102.1490 -\verb| -> theory -> theory| \\
102.1491 - \indexml{Code.del\_functrans}\verb|Code.del_functrans: string -> theory -> theory| \\
102.1492 - \indexml{Code.add\_datatype}\verb|Code.add_datatype: (string * typ) list -> theory -> theory| \\
102.1493 - \indexml{Code.get\_datatype}\verb|Code.get_datatype: theory -> string|\isasep\isanewline%
102.1494 -\verb| -> (string * sort) list * (string * typ list) list| \\
102.1495 - \indexml{Code.get\_datatype\_of\_constr}\verb|Code.get_datatype_of_constr: theory -> string -> string option|
102.1496 - \end{mldecls}
102.1497 -
102.1498 - \begin{description}
102.1499 -
102.1500 - \item \verb|Code.add_func|~\isa{thm}~\isa{thy} adds function
102.1501 - theorem \isa{thm} to executable content.
102.1502 -
102.1503 - \item \verb|Code.del_func|~\isa{thm}~\isa{thy} removes function
102.1504 - theorem \isa{thm} from executable content, if present.
102.1505 -
102.1506 - \item \verb|Code.add_funcl|~\isa{{\isacharparenleft}const{\isacharcomma}\ lthms{\isacharparenright}}~\isa{thy} adds
102.1507 - suspended defining equations \isa{lthms} for constant
102.1508 - \isa{const} to executable content.
102.1509 -
102.1510 - \item \verb|Code.map_pre|~\isa{f}~\isa{thy} changes
102.1511 - the preprocessor simpset.
102.1512 -
102.1513 - \item \verb|Code.add_functrans|~\isa{{\isacharparenleft}name{\isacharcomma}\ f{\isacharparenright}}~\isa{thy} adds
102.1514 - function transformer \isa{f} (named \isa{name}) to executable content;
102.1515 - \isa{f} is a transformer of the defining equations belonging
102.1516 - to a certain function definition, depending on the
102.1517 - current theory context. Returning \isa{NONE} indicates that no
102.1518 - transformation took place; otherwise, the whole process will be iterated
102.1519 - with the new defining equations.
102.1520 -
102.1521 - \item \verb|Code.del_functrans|~\isa{name}~\isa{thy} removes
102.1522 - function transformer named \isa{name} from executable content.
102.1523 -
102.1524 - \item \verb|Code.add_datatype|~\isa{cs}~\isa{thy} adds
102.1525 - a datatype to executable content, with generation
102.1526 - set \isa{cs}.
102.1527 -
102.1528 - \item \verb|Code.get_datatype_of_constr|~\isa{thy}~\isa{const}
102.1529 - returns type constructor corresponding to
102.1530 - constructor \isa{const}; returns \isa{NONE}
102.1531 - if \isa{const} is no constructor.
102.1532 -
102.1533 - \end{description}%
102.1534 -\end{isamarkuptext}%
102.1535 -\isamarkuptrue%
102.1536 -%
102.1537 -\endisatagmlref
102.1538 -{\isafoldmlref}%
102.1539 -%
102.1540 -\isadelimmlref
102.1541 -%
102.1542 -\endisadelimmlref
102.1543 -%
102.1544 -\isamarkupsubsection{Auxiliary%
102.1545 -}
102.1546 -\isamarkuptrue%
102.1547 -%
102.1548 -\isadelimmlref
102.1549 -%
102.1550 -\endisadelimmlref
102.1551 -%
102.1552 -\isatagmlref
102.1553 -%
102.1554 -\begin{isamarkuptext}%
102.1555 -\begin{mldecls}
102.1556 - \indexml{Code\_Unit.read\_const}\verb|Code_Unit.read_const: theory -> string -> string| \\
102.1557 - \indexml{Code\_Unit.head\_func}\verb|Code_Unit.head_func: thm -> string * ((string * sort) list * typ)| \\
102.1558 - \indexml{Code\_Unit.rewrite\_func}\verb|Code_Unit.rewrite_func: MetaSimplifier.simpset -> thm -> thm| \\
102.1559 - \end{mldecls}
102.1560 -
102.1561 - \begin{description}
102.1562 -
102.1563 - \item \verb|Code_Unit.read_const|~\isa{thy}~\isa{s}
102.1564 - reads a constant as a concrete term expression \isa{s}.
102.1565 -
102.1566 - \item \verb|Code_Unit.head_func|~\isa{thm}
102.1567 - extracts the constant and its type from a defining equation \isa{thm}.
102.1568 -
102.1569 - \item \verb|Code_Unit.rewrite_func|~\isa{ss}~\isa{thm}
102.1570 - rewrites a defining equation \isa{thm} with a simpset \isa{ss};
102.1571 - only arguments and right hand side are rewritten,
102.1572 - not the head of the defining equation.
102.1573 -
102.1574 - \end{description}%
102.1575 -\end{isamarkuptext}%
102.1576 -\isamarkuptrue%
102.1577 -%
102.1578 -\endisatagmlref
102.1579 -{\isafoldmlref}%
102.1580 -%
102.1581 -\isadelimmlref
102.1582 -%
102.1583 -\endisadelimmlref
102.1584 -%
102.1585 -\isamarkupsubsection{Implementing code generator applications%
102.1586 -}
102.1587 -\isamarkuptrue%
102.1588 -%
102.1589 -\begin{isamarkuptext}%
102.1590 -Implementing code generator applications on top
102.1591 - of the framework set out so far usually not only
102.1592 - involves using those primitive interfaces
102.1593 - but also storing code-dependent data and various
102.1594 - other things.
102.1595 -
102.1596 - \begin{warn}
102.1597 - Some interfaces discussed here have not reached
102.1598 - a final state yet.
102.1599 - Changes likely to occur in future.
102.1600 - \end{warn}%
102.1601 -\end{isamarkuptext}%
102.1602 -\isamarkuptrue%
102.1603 -%
102.1604 -\isamarkupsubsubsection{Data depending on the theory's executable content%
102.1605 -}
102.1606 -\isamarkuptrue%
102.1607 -%
102.1608 -\begin{isamarkuptext}%
102.1609 -Due to incrementality of code generation, changes in the
102.1610 - theory's executable content have to be propagated in a
102.1611 - certain fashion. Additionally, such changes may occur
102.1612 - not only during theory extension but also during theory
102.1613 - merge, which is a little bit nasty from an implementation
102.1614 - point of view. The framework provides a solution
102.1615 - to this technical challenge by providing a functorial
102.1616 - data slot \verb|CodeDataFun|; on instantiation
102.1617 - of this functor, the following types and operations
102.1618 - are required:
102.1619 -
102.1620 - \medskip
102.1621 - \begin{tabular}{l}
102.1622 - \isa{type\ T} \\
102.1623 - \isa{val\ empty{\isacharcolon}\ T} \\
102.1624 - \isa{val\ merge{\isacharcolon}\ Pretty{\isachardot}pp\ {\isasymrightarrow}\ T\ {\isacharasterisk}\ T\ {\isasymrightarrow}\ T} \\
102.1625 - \isa{val\ purge{\isacharcolon}\ theory\ option\ {\isasymrightarrow}\ CodeUnit{\isachardot}const\ list\ option\ {\isasymrightarrow}\ T\ {\isasymrightarrow}\ T}
102.1626 - \end{tabular}
102.1627 -
102.1628 - \begin{description}
102.1629 -
102.1630 - \item \isa{T} the type of data to store.
102.1631 -
102.1632 - \item \isa{empty} initial (empty) data.
102.1633 -
102.1634 - \item \isa{merge} merging two data slots.
102.1635 -
102.1636 - \item \isa{purge}~\isa{thy}~\isa{consts} propagates changes in executable content;
102.1637 - if possible, the current theory context is handed over
102.1638 - as argument \isa{thy} (if there is no current theory context (e.g.~during
102.1639 - theory merge, \verb|NONE|); \isa{consts} indicates the kind
102.1640 - of change: \verb|NONE| stands for a fundamental change
102.1641 - which invalidates any existing code, \isa{SOME\ consts}
102.1642 - hints that executable content for constants \isa{consts}
102.1643 - has changed.
102.1644 -
102.1645 - \end{description}
102.1646 -
102.1647 - An instance of \verb|CodeDataFun| provides the following
102.1648 - interface:
102.1649 -
102.1650 - \medskip
102.1651 - \begin{tabular}{l}
102.1652 - \isa{get{\isacharcolon}\ theory\ {\isasymrightarrow}\ T} \\
102.1653 - \isa{change{\isacharcolon}\ theory\ {\isasymrightarrow}\ {\isacharparenleft}T\ {\isasymrightarrow}\ T{\isacharparenright}\ {\isasymrightarrow}\ T} \\
102.1654 - \isa{change{\isacharunderscore}yield{\isacharcolon}\ theory\ {\isasymrightarrow}\ {\isacharparenleft}T\ {\isasymrightarrow}\ {\isacharprime}a\ {\isacharasterisk}\ T{\isacharparenright}\ {\isasymrightarrow}\ {\isacharprime}a\ {\isacharasterisk}\ T}
102.1655 - \end{tabular}
102.1656 -
102.1657 - \begin{description}
102.1658 -
102.1659 - \item \isa{get} retrieval of the current data.
102.1660 -
102.1661 - \item \isa{change} update of current data (cached!)
102.1662 - by giving a continuation.
102.1663 -
102.1664 - \item \isa{change{\isacharunderscore}yield} update with side result.
102.1665 -
102.1666 - \end{description}%
102.1667 -\end{isamarkuptext}%
102.1668 -\isamarkuptrue%
102.1669 -%
102.1670 -\begin{isamarkuptext}%
102.1671 -\emph{Happy proving, happy hacking!}%
102.1672 -\end{isamarkuptext}%
102.1673 -\isamarkuptrue%
102.1674 -%
102.1675 -\isadelimtheory
102.1676 -%
102.1677 -\endisadelimtheory
102.1678 -%
102.1679 -\isatagtheory
102.1680 -\isacommand{end}\isamarkupfalse%
102.1681 -%
102.1682 -\endisatagtheory
102.1683 -{\isafoldtheory}%
102.1684 -%
102.1685 -\isadelimtheory
102.1686 -%
102.1687 -\endisadelimtheory
102.1688 -\isanewline
102.1689 -\end{isabellebody}%
102.1690 -%%% Local Variables:
102.1691 -%%% mode: latex
102.1692 -%%% TeX-master: "root"
102.1693 -%%% End:
103.1 --- a/doc-src/IsarAdvanced/Codegen/Thy/document/Further.tex Wed Mar 04 11:05:02 2009 +0100
103.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
103.3 @@ -1,234 +0,0 @@
103.4 -%
103.5 -\begin{isabellebody}%
103.6 -\def\isabellecontext{Further}%
103.7 -%
103.8 -\isadelimtheory
103.9 -%
103.10 -\endisadelimtheory
103.11 -%
103.12 -\isatagtheory
103.13 -\isacommand{theory}\isamarkupfalse%
103.14 -\ Further\isanewline
103.15 -\isakeyword{imports}\ Setup\isanewline
103.16 -\isakeyword{begin}%
103.17 -\endisatagtheory
103.18 -{\isafoldtheory}%
103.19 -%
103.20 -\isadelimtheory
103.21 -%
103.22 -\endisadelimtheory
103.23 -%
103.24 -\isamarkupsection{Further issues \label{sec:further}%
103.25 -}
103.26 -\isamarkuptrue%
103.27 -%
103.28 -\isamarkupsubsection{Further reading%
103.29 -}
103.30 -\isamarkuptrue%
103.31 -%
103.32 -\begin{isamarkuptext}%
103.33 -Do dive deeper into the issue of code generation, you should visit
103.34 - the Isabelle/Isar Reference Manual \cite{isabelle-isar-ref} which
103.35 - contains exhaustive syntax diagrams.%
103.36 -\end{isamarkuptext}%
103.37 -\isamarkuptrue%
103.38 -%
103.39 -\isamarkupsubsection{Modules%
103.40 -}
103.41 -\isamarkuptrue%
103.42 -%
103.43 -\begin{isamarkuptext}%
103.44 -When invoking the \hyperlink{command.export-code}{\mbox{\isa{\isacommand{export{\isacharunderscore}code}}}} command it is possible to leave
103.45 - out the \hyperlink{keyword.module-name}{\mbox{\isa{\isakeyword{module{\isacharunderscore}name}}}} part; then code is distributed over
103.46 - different modules, where the module name space roughly is induced
103.47 - by the \isa{Isabelle} theory name space.
103.48 -
103.49 - Then sometimes the awkward situation occurs that dependencies between
103.50 - definitions introduce cyclic dependencies between modules, which in the
103.51 - \isa{Haskell} world leaves you to the mercy of the \isa{Haskell} implementation
103.52 - you are using, while for \isa{SML}/\isa{OCaml} code generation is not possible.
103.53 -
103.54 - A solution is to declare module names explicitly.
103.55 - Let use assume the three cyclically dependent
103.56 - modules are named \emph{A}, \emph{B} and \emph{C}.
103.57 - Then, by stating%
103.58 -\end{isamarkuptext}%
103.59 -\isamarkuptrue%
103.60 -%
103.61 -\isadelimquote
103.62 -%
103.63 -\endisadelimquote
103.64 -%
103.65 -\isatagquote
103.66 -\isacommand{code{\isacharunderscore}modulename}\isamarkupfalse%
103.67 -\ SML\isanewline
103.68 -\ \ A\ ABC\isanewline
103.69 -\ \ B\ ABC\isanewline
103.70 -\ \ C\ ABC%
103.71 -\endisatagquote
103.72 -{\isafoldquote}%
103.73 -%
103.74 -\isadelimquote
103.75 -%
103.76 -\endisadelimquote
103.77 -%
103.78 -\begin{isamarkuptext}%
103.79 -we explicitly map all those modules on \emph{ABC},
103.80 - resulting in an ad-hoc merge of this three modules
103.81 - at serialisation time.%
103.82 -\end{isamarkuptext}%
103.83 -\isamarkuptrue%
103.84 -%
103.85 -\isamarkupsubsection{Evaluation oracle%
103.86 -}
103.87 -\isamarkuptrue%
103.88 -%
103.89 -\begin{isamarkuptext}%
103.90 -Code generation may also be used to \emph{evaluate} expressions
103.91 - (using \isa{SML} as target language of course).
103.92 - For instance, the \hyperlink{command.value}{\mbox{\isa{\isacommand{value}}}} allows to reduce an expression to a
103.93 - normal form with respect to the underlying code equations:%
103.94 -\end{isamarkuptext}%
103.95 -\isamarkuptrue%
103.96 -%
103.97 -\isadelimquote
103.98 -%
103.99 -\endisadelimquote
103.100 -%
103.101 -\isatagquote
103.102 -\isacommand{value}\isamarkupfalse%
103.103 -\ {\isachardoublequoteopen}{\isadigit{4}}{\isadigit{2}}\ {\isacharslash}\ {\isacharparenleft}{\isadigit{1}}{\isadigit{2}}\ {\isacharcolon}{\isacharcolon}\ rat{\isacharparenright}{\isachardoublequoteclose}%
103.104 -\endisatagquote
103.105 -{\isafoldquote}%
103.106 -%
103.107 -\isadelimquote
103.108 -%
103.109 -\endisadelimquote
103.110 -%
103.111 -\begin{isamarkuptext}%
103.112 -\noindent will display \isa{{\isadigit{7}}\ {\isacharslash}\ {\isadigit{2}}}.
103.113 -
103.114 - The \hyperlink{method.eval}{\mbox{\isa{eval}}} method tries to reduce a goal by code generation to \isa{True}
103.115 - and solves it in that case, but fails otherwise:%
103.116 -\end{isamarkuptext}%
103.117 -\isamarkuptrue%
103.118 -%
103.119 -\isadelimquote
103.120 -%
103.121 -\endisadelimquote
103.122 -%
103.123 -\isatagquote
103.124 -\isacommand{lemma}\isamarkupfalse%
103.125 -\ {\isachardoublequoteopen}{\isadigit{4}}{\isadigit{2}}\ {\isacharslash}\ {\isacharparenleft}{\isadigit{1}}{\isadigit{2}}\ {\isacharcolon}{\isacharcolon}\ rat{\isacharparenright}\ {\isacharequal}\ {\isadigit{7}}\ {\isacharslash}\ {\isadigit{2}}{\isachardoublequoteclose}\isanewline
103.126 -\ \ \isacommand{by}\isamarkupfalse%
103.127 -\ eval%
103.128 -\endisatagquote
103.129 -{\isafoldquote}%
103.130 -%
103.131 -\isadelimquote
103.132 -%
103.133 -\endisadelimquote
103.134 -%
103.135 -\begin{isamarkuptext}%
103.136 -\noindent The soundness of the \hyperlink{method.eval}{\mbox{\isa{eval}}} method depends crucially
103.137 - on the correctness of the code generator; this is one of the reasons
103.138 - why you should not use adaption (see \secref{sec:adaption}) frivolously.%
103.139 -\end{isamarkuptext}%
103.140 -\isamarkuptrue%
103.141 -%
103.142 -\isamarkupsubsection{Code antiquotation%
103.143 -}
103.144 -\isamarkuptrue%
103.145 -%
103.146 -\begin{isamarkuptext}%
103.147 -In scenarios involving techniques like reflection it is quite common
103.148 - that code generated from a theory forms the basis for implementing
103.149 - a proof procedure in \isa{SML}. To facilitate interfacing of generated code
103.150 - with system code, the code generator provides a \isa{code} antiquotation:%
103.151 -\end{isamarkuptext}%
103.152 -\isamarkuptrue%
103.153 -%
103.154 -\isadelimquote
103.155 -%
103.156 -\endisadelimquote
103.157 -%
103.158 -\isatagquote
103.159 -\isacommand{datatype}\isamarkupfalse%
103.160 -\ form\ {\isacharequal}\ T\ {\isacharbar}\ F\ {\isacharbar}\ And\ form\ form\ {\isacharbar}\ Or\ form\ form\isanewline
103.161 -\isanewline
103.162 -\isacommand{ML}\isamarkupfalse%
103.163 -\ {\isacharverbatimopen}\isanewline
103.164 -\ \ fun\ eval{\isacharunderscore}form\ %
103.165 -\isaantiq
103.166 -code\ T%
103.167 -\endisaantiq
103.168 -\ {\isacharequal}\ true\isanewline
103.169 -\ \ \ \ {\isacharbar}\ eval{\isacharunderscore}form\ %
103.170 -\isaantiq
103.171 -code\ F%
103.172 -\endisaantiq
103.173 -\ {\isacharequal}\ false\isanewline
103.174 -\ \ \ \ {\isacharbar}\ eval{\isacharunderscore}form\ {\isacharparenleft}%
103.175 -\isaantiq
103.176 -code\ And%
103.177 -\endisaantiq
103.178 -\ {\isacharparenleft}p{\isacharcomma}\ q{\isacharparenright}{\isacharparenright}\ {\isacharequal}\isanewline
103.179 -\ \ \ \ \ \ \ \ eval{\isacharunderscore}form\ p\ andalso\ eval{\isacharunderscore}form\ q\isanewline
103.180 -\ \ \ \ {\isacharbar}\ eval{\isacharunderscore}form\ {\isacharparenleft}%
103.181 -\isaantiq
103.182 -code\ Or%
103.183 -\endisaantiq
103.184 -\ {\isacharparenleft}p{\isacharcomma}\ q{\isacharparenright}{\isacharparenright}\ {\isacharequal}\isanewline
103.185 -\ \ \ \ \ \ \ \ eval{\isacharunderscore}form\ p\ orelse\ eval{\isacharunderscore}form\ q{\isacharsemicolon}\isanewline
103.186 -{\isacharverbatimclose}%
103.187 -\endisatagquote
103.188 -{\isafoldquote}%
103.189 -%
103.190 -\isadelimquote
103.191 -%
103.192 -\endisadelimquote
103.193 -%
103.194 -\begin{isamarkuptext}%
103.195 -\noindent \isa{code} takes as argument the name of a constant; after the
103.196 - whole \isa{SML} is read, the necessary code is generated transparently
103.197 - and the corresponding constant names are inserted. This technique also
103.198 - allows to use pattern matching on constructors stemming from compiled
103.199 - \isa{datatypes}.
103.200 -
103.201 - For a less simplistic example, theory \hyperlink{theory.Ferrack}{\mbox{\isa{Ferrack}}} is
103.202 - a good reference.%
103.203 -\end{isamarkuptext}%
103.204 -\isamarkuptrue%
103.205 -%
103.206 -\isamarkupsubsection{Imperative data structures%
103.207 -}
103.208 -\isamarkuptrue%
103.209 -%
103.210 -\begin{isamarkuptext}%
103.211 -If you consider imperative data structures as inevitable for a specific
103.212 - application, you should consider
103.213 - \emph{Imperative Functional Programming with Isabelle/HOL}
103.214 - (\cite{bulwahn-et-al:2008:imperative});
103.215 - the framework described there is available in theory \hyperlink{theory.Imperative-HOL}{\mbox{\isa{Imperative{\isacharunderscore}HOL}}}.%
103.216 -\end{isamarkuptext}%
103.217 -\isamarkuptrue%
103.218 -%
103.219 -\isadelimtheory
103.220 -%
103.221 -\endisadelimtheory
103.222 -%
103.223 -\isatagtheory
103.224 -\isacommand{end}\isamarkupfalse%
103.225 -%
103.226 -\endisatagtheory
103.227 -{\isafoldtheory}%
103.228 -%
103.229 -\isadelimtheory
103.230 -%
103.231 -\endisadelimtheory
103.232 -\isanewline
103.233 -\end{isabellebody}%
103.234 -%%% Local Variables:
103.235 -%%% mode: latex
103.236 -%%% TeX-master: "root"
103.237 -%%% End:
104.1 --- a/doc-src/IsarAdvanced/Codegen/Thy/document/Introduction.tex Wed Mar 04 11:05:02 2009 +0100
104.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
104.3 @@ -1,390 +0,0 @@
104.4 -%
104.5 -\begin{isabellebody}%
104.6 -\def\isabellecontext{Introduction}%
104.7 -%
104.8 -\isadelimtheory
104.9 -%
104.10 -\endisadelimtheory
104.11 -%
104.12 -\isatagtheory
104.13 -\isacommand{theory}\isamarkupfalse%
104.14 -\ Introduction\isanewline
104.15 -\isakeyword{imports}\ Setup\isanewline
104.16 -\isakeyword{begin}%
104.17 -\endisatagtheory
104.18 -{\isafoldtheory}%
104.19 -%
104.20 -\isadelimtheory
104.21 -%
104.22 -\endisadelimtheory
104.23 -%
104.24 -\isamarkupchapter{Code generation from \isa{Isabelle{\isacharslash}HOL} theories%
104.25 -}
104.26 -\isamarkuptrue%
104.27 -%
104.28 -\isamarkupsection{Introduction and Overview%
104.29 -}
104.30 -\isamarkuptrue%
104.31 -%
104.32 -\begin{isamarkuptext}%
104.33 -This tutorial introduces a generic code generator for the
104.34 - \isa{Isabelle} system.
104.35 - Generic in the sense that the
104.36 - \qn{target language} for which code shall ultimately be
104.37 - generated is not fixed but may be an arbitrary state-of-the-art
104.38 - functional programming language (currently, the implementation
104.39 - supports \isa{SML} \cite{SML}, \isa{OCaml} \cite{OCaml} and \isa{Haskell}
104.40 - \cite{haskell-revised-report}).
104.41 -
104.42 - Conceptually the code generator framework is part
104.43 - of Isabelle's \hyperlink{theory.Pure}{\mbox{\isa{Pure}}} meta logic framework; the logic
104.44 - \hyperlink{theory.HOL}{\mbox{\isa{HOL}}} which is an extension of \hyperlink{theory.Pure}{\mbox{\isa{Pure}}}
104.45 - already comes with a reasonable framework setup and thus provides
104.46 - a good working horse for raising code-generation-driven
104.47 - applications. So, we assume some familiarity and experience
104.48 - with the ingredients of the \hyperlink{theory.HOL}{\mbox{\isa{HOL}}} distribution theories.
104.49 - (see also \cite{isa-tutorial}).
104.50 -
104.51 - The code generator aims to be usable with no further ado
104.52 - in most cases while allowing for detailed customisation.
104.53 - This manifests in the structure of this tutorial: after a short
104.54 - conceptual introduction with an example (\secref{sec:intro}),
104.55 - we discuss the generic customisation facilities (\secref{sec:program}).
104.56 - A further section (\secref{sec:adaption}) is dedicated to the matter of
104.57 - \qn{adaption} to specific target language environments. After some
104.58 - further issues (\secref{sec:further}) we conclude with an overview
104.59 - of some ML programming interfaces (\secref{sec:ml}).
104.60 -
104.61 - \begin{warn}
104.62 - Ultimately, the code generator which this tutorial deals with
104.63 - is supposed to replace the existing code generator
104.64 - by Stefan Berghofer \cite{Berghofer-Nipkow:2002}.
104.65 - So, for the moment, there are two distinct code generators
104.66 - in Isabelle. In case of ambiguity, we will refer to the framework
104.67 - described here as \isa{generic\ code\ generator}, to the
104.68 - other as \isa{SML\ code\ generator}.
104.69 - Also note that while the framework itself is
104.70 - object-logic independent, only \hyperlink{theory.HOL}{\mbox{\isa{HOL}}} provides a reasonable
104.71 - framework setup.
104.72 - \end{warn}%
104.73 -\end{isamarkuptext}%
104.74 -\isamarkuptrue%
104.75 -%
104.76 -\isamarkupsubsection{Code generation via shallow embedding \label{sec:intro}%
104.77 -}
104.78 -\isamarkuptrue%
104.79 -%
104.80 -\begin{isamarkuptext}%
104.81 -The key concept for understanding \isa{Isabelle}'s code generation is
104.82 - \emph{shallow embedding}, i.e.~logical entities like constants, types and
104.83 - classes are identified with corresponding concepts in the target language.
104.84 -
104.85 - Inside \hyperlink{theory.HOL}{\mbox{\isa{HOL}}}, the \hyperlink{command.datatype}{\mbox{\isa{\isacommand{datatype}}}} and
104.86 - \hyperlink{command.definition}{\mbox{\isa{\isacommand{definition}}}}/\hyperlink{command.primrec}{\mbox{\isa{\isacommand{primrec}}}}/\hyperlink{command.fun}{\mbox{\isa{\isacommand{fun}}}} declarations form
104.87 - the core of a functional programming language. The default code generator setup
104.88 - allows to turn those into functional programs immediately.
104.89 - This means that \qt{naive} code generation can proceed without further ado.
104.90 - For example, here a simple \qt{implementation} of amortised queues:%
104.91 -\end{isamarkuptext}%
104.92 -\isamarkuptrue%
104.93 -%
104.94 -\isadelimquote
104.95 -%
104.96 -\endisadelimquote
104.97 -%
104.98 -\isatagquote
104.99 -\isacommand{datatype}\isamarkupfalse%
104.100 -\ {\isacharprime}a\ queue\ {\isacharequal}\ AQueue\ {\isachardoublequoteopen}{\isacharprime}a\ list{\isachardoublequoteclose}\ {\isachardoublequoteopen}{\isacharprime}a\ list{\isachardoublequoteclose}\isanewline
104.101 -\isanewline
104.102 -\isacommand{definition}\isamarkupfalse%
104.103 -\ empty\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharprime}a\ queue{\isachardoublequoteclose}\ \isakeyword{where}\isanewline
104.104 -\ \ {\isachardoublequoteopen}empty\ {\isacharequal}\ AQueue\ {\isacharbrackleft}{\isacharbrackright}\ {\isacharbrackleft}{\isacharbrackright}{\isachardoublequoteclose}\isanewline
104.105 -\isanewline
104.106 -\isacommand{primrec}\isamarkupfalse%
104.107 -\ enqueue\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharprime}a\ {\isasymRightarrow}\ {\isacharprime}a\ queue\ {\isasymRightarrow}\ {\isacharprime}a\ queue{\isachardoublequoteclose}\ \isakeyword{where}\isanewline
104.108 -\ \ {\isachardoublequoteopen}enqueue\ x\ {\isacharparenleft}AQueue\ xs\ ys{\isacharparenright}\ {\isacharequal}\ AQueue\ {\isacharparenleft}x\ {\isacharhash}\ xs{\isacharparenright}\ ys{\isachardoublequoteclose}\isanewline
104.109 -\isanewline
104.110 -\isacommand{fun}\isamarkupfalse%
104.111 -\ dequeue\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharprime}a\ queue\ {\isasymRightarrow}\ {\isacharprime}a\ option\ {\isasymtimes}\ {\isacharprime}a\ queue{\isachardoublequoteclose}\ \isakeyword{where}\isanewline
104.112 -\ \ \ \ {\isachardoublequoteopen}dequeue\ {\isacharparenleft}AQueue\ {\isacharbrackleft}{\isacharbrackright}\ {\isacharbrackleft}{\isacharbrackright}{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}None{\isacharcomma}\ AQueue\ {\isacharbrackleft}{\isacharbrackright}\ {\isacharbrackleft}{\isacharbrackright}{\isacharparenright}{\isachardoublequoteclose}\isanewline
104.113 -\ \ {\isacharbar}\ {\isachardoublequoteopen}dequeue\ {\isacharparenleft}AQueue\ xs\ {\isacharparenleft}y\ {\isacharhash}\ ys{\isacharparenright}{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}Some\ y{\isacharcomma}\ AQueue\ xs\ ys{\isacharparenright}{\isachardoublequoteclose}\isanewline
104.114 -\ \ {\isacharbar}\ {\isachardoublequoteopen}dequeue\ {\isacharparenleft}AQueue\ xs\ {\isacharbrackleft}{\isacharbrackright}{\isacharparenright}\ {\isacharequal}\isanewline
104.115 -\ \ \ \ \ \ {\isacharparenleft}case\ rev\ xs\ of\ y\ {\isacharhash}\ ys\ {\isasymRightarrow}\ {\isacharparenleft}Some\ y{\isacharcomma}\ AQueue\ {\isacharbrackleft}{\isacharbrackright}\ ys{\isacharparenright}{\isacharparenright}{\isachardoublequoteclose}%
104.116 -\endisatagquote
104.117 -{\isafoldquote}%
104.118 -%
104.119 -\isadelimquote
104.120 -%
104.121 -\endisadelimquote
104.122 -%
104.123 -\begin{isamarkuptext}%
104.124 -\noindent Then we can generate code e.g.~for \isa{SML} as follows:%
104.125 -\end{isamarkuptext}%
104.126 -\isamarkuptrue%
104.127 -%
104.128 -\isadelimquote
104.129 -%
104.130 -\endisadelimquote
104.131 -%
104.132 -\isatagquote
104.133 -\isacommand{export{\isacharunderscore}code}\isamarkupfalse%
104.134 -\ empty\ dequeue\ enqueue\ \isakeyword{in}\ SML\isanewline
104.135 -\ \ \isakeyword{module{\isacharunderscore}name}\ Example\ \isakeyword{file}\ {\isachardoublequoteopen}examples{\isacharslash}example{\isachardot}ML{\isachardoublequoteclose}%
104.136 -\endisatagquote
104.137 -{\isafoldquote}%
104.138 -%
104.139 -\isadelimquote
104.140 -%
104.141 -\endisadelimquote
104.142 -%
104.143 -\begin{isamarkuptext}%
104.144 -\noindent resulting in the following code:%
104.145 -\end{isamarkuptext}%
104.146 -\isamarkuptrue%
104.147 -%
104.148 -\isadelimquote
104.149 -%
104.150 -\endisadelimquote
104.151 -%
104.152 -\isatagquote
104.153 -%
104.154 -\begin{isamarkuptext}%
104.155 -\isatypewriter%
104.156 -\noindent%
104.157 -\hspace*{0pt}structure Example = \\
104.158 -\hspace*{0pt}struct\\
104.159 -\hspace*{0pt}\\
104.160 -\hspace*{0pt}fun foldl f a [] = a\\
104.161 -\hspace*{0pt} ~| foldl f a (x ::~xs) = foldl f (f a x) xs;\\
104.162 -\hspace*{0pt}\\
104.163 -\hspace*{0pt}fun rev xs = foldl (fn xsa => fn x => x ::~xsa) [] xs;\\
104.164 -\hspace*{0pt}\\
104.165 -\hspace*{0pt}fun list{\char95}case f1 f2 (a ::~lista) = f2 a lista\\
104.166 -\hspace*{0pt} ~| list{\char95}case f1 f2 [] = f1;\\
104.167 -\hspace*{0pt}\\
104.168 -\hspace*{0pt}datatype 'a queue = AQueue of 'a list * 'a list;\\
104.169 -\hspace*{0pt}\\
104.170 -\hspace*{0pt}val empty :~'a queue = AQueue ([],~[])\\
104.171 -\hspace*{0pt}\\
104.172 -\hspace*{0pt}fun dequeue (AQueue ([],~[])) = (NONE,~AQueue ([],~[]))\\
104.173 -\hspace*{0pt} ~| dequeue (AQueue (xs,~y ::~ys)) = (SOME y,~AQueue (xs,~ys))\\
104.174 -\hspace*{0pt} ~| dequeue (AQueue (v ::~va,~[])) =\\
104.175 -\hspace*{0pt} ~~~let\\
104.176 -\hspace*{0pt} ~~~~~val y ::~ys = rev (v ::~va);\\
104.177 -\hspace*{0pt} ~~~in\\
104.178 -\hspace*{0pt} ~~~~~(SOME y,~AQueue ([],~ys))\\
104.179 -\hspace*{0pt} ~~~end;\\
104.180 -\hspace*{0pt}\\
104.181 -\hspace*{0pt}fun enqueue x (AQueue (xs,~ys)) = AQueue (x ::~xs,~ys);\\
104.182 -\hspace*{0pt}\\
104.183 -\hspace*{0pt}end;~(*struct Example*)%
104.184 -\end{isamarkuptext}%
104.185 -\isamarkuptrue%
104.186 -%
104.187 -\endisatagquote
104.188 -{\isafoldquote}%
104.189 -%
104.190 -\isadelimquote
104.191 -%
104.192 -\endisadelimquote
104.193 -%
104.194 -\begin{isamarkuptext}%
104.195 -\noindent The \hyperlink{command.export-code}{\mbox{\isa{\isacommand{export{\isacharunderscore}code}}}} command takes a space-separated list of
104.196 - constants for which code shall be generated; anything else needed for those
104.197 - is added implicitly. Then follows a target language identifier
104.198 - (\isa{SML}, \isa{OCaml} or \isa{Haskell}) and a freely chosen module name.
104.199 - A file name denotes the destination to store the generated code. Note that
104.200 - the semantics of the destination depends on the target language: for
104.201 - \isa{SML} and \isa{OCaml} it denotes a \emph{file}, for \isa{Haskell}
104.202 - it denotes a \emph{directory} where a file named as the module name
104.203 - (with extension \isa{{\isachardot}hs}) is written:%
104.204 -\end{isamarkuptext}%
104.205 -\isamarkuptrue%
104.206 -%
104.207 -\isadelimquote
104.208 -%
104.209 -\endisadelimquote
104.210 -%
104.211 -\isatagquote
104.212 -\isacommand{export{\isacharunderscore}code}\isamarkupfalse%
104.213 -\ empty\ dequeue\ enqueue\ \isakeyword{in}\ Haskell\isanewline
104.214 -\ \ \isakeyword{module{\isacharunderscore}name}\ Example\ \isakeyword{file}\ {\isachardoublequoteopen}examples{\isacharslash}{\isachardoublequoteclose}%
104.215 -\endisatagquote
104.216 -{\isafoldquote}%
104.217 -%
104.218 -\isadelimquote
104.219 -%
104.220 -\endisadelimquote
104.221 -%
104.222 -\begin{isamarkuptext}%
104.223 -\noindent This is how the corresponding code in \isa{Haskell} looks like:%
104.224 -\end{isamarkuptext}%
104.225 -\isamarkuptrue%
104.226 -%
104.227 -\isadelimquote
104.228 -%
104.229 -\endisadelimquote
104.230 -%
104.231 -\isatagquote
104.232 -%
104.233 -\begin{isamarkuptext}%
104.234 -\isatypewriter%
104.235 -\noindent%
104.236 -\hspace*{0pt}module Example where {\char123}\\
104.237 -\hspace*{0pt}\\
104.238 -\hspace*{0pt}\\
104.239 -\hspace*{0pt}foldla ::~forall a b.~(a -> b -> a) -> a -> [b] -> a;\\
104.240 -\hspace*{0pt}foldla f a [] = a;\\
104.241 -\hspace*{0pt}foldla f a (x :~xs) = foldla f (f a x) xs;\\
104.242 -\hspace*{0pt}\\
104.243 -\hspace*{0pt}rev ::~forall a.~[a] -> [a];\\
104.244 -\hspace*{0pt}rev xs = foldla ({\char92}~xsa x -> x :~xsa) [] xs;\\
104.245 -\hspace*{0pt}\\
104.246 -\hspace*{0pt}list{\char95}case ::~forall t a.~t -> (a -> [a] -> t) -> [a] -> t;\\
104.247 -\hspace*{0pt}list{\char95}case f1 f2 (a :~list) = f2 a list;\\
104.248 -\hspace*{0pt}list{\char95}case f1 f2 [] = f1;\\
104.249 -\hspace*{0pt}\\
104.250 -\hspace*{0pt}data Queue a = AQueue [a] [a];\\
104.251 -\hspace*{0pt}\\
104.252 -\hspace*{0pt}empty ::~forall a.~Queue a;\\
104.253 -\hspace*{0pt}empty = AQueue [] [];\\
104.254 -\hspace*{0pt}\\
104.255 -\hspace*{0pt}dequeue ::~forall a.~Queue a -> (Maybe a,~Queue a);\\
104.256 -\hspace*{0pt}dequeue (AQueue [] []) = (Nothing,~AQueue [] []);\\
104.257 -\hspace*{0pt}dequeue (AQueue xs (y :~ys)) = (Just y,~AQueue xs ys);\\
104.258 -\hspace*{0pt}dequeue (AQueue (v :~va) []) =\\
104.259 -\hspace*{0pt} ~let {\char123}\\
104.260 -\hspace*{0pt} ~~~(y :~ys) = rev (v :~va);\\
104.261 -\hspace*{0pt} ~{\char125}~in (Just y,~AQueue [] ys);\\
104.262 -\hspace*{0pt}\\
104.263 -\hspace*{0pt}enqueue ::~forall a.~a -> Queue a -> Queue a;\\
104.264 -\hspace*{0pt}enqueue x (AQueue xs ys) = AQueue (x :~xs) ys;\\
104.265 -\hspace*{0pt}\\
104.266 -\hspace*{0pt}{\char125}%
104.267 -\end{isamarkuptext}%
104.268 -\isamarkuptrue%
104.269 -%
104.270 -\endisatagquote
104.271 -{\isafoldquote}%
104.272 -%
104.273 -\isadelimquote
104.274 -%
104.275 -\endisadelimquote
104.276 -%
104.277 -\begin{isamarkuptext}%
104.278 -\noindent This demonstrates the basic usage of the \hyperlink{command.export-code}{\mbox{\isa{\isacommand{export{\isacharunderscore}code}}}} command;
104.279 - for more details see \secref{sec:further}.%
104.280 -\end{isamarkuptext}%
104.281 -\isamarkuptrue%
104.282 -%
104.283 -\isamarkupsubsection{Code generator architecture \label{sec:concept}%
104.284 -}
104.285 -\isamarkuptrue%
104.286 -%
104.287 -\begin{isamarkuptext}%
104.288 -What you have seen so far should be already enough in a lot of cases. If you
104.289 - are content with this, you can quit reading here. Anyway, in order to customise
104.290 - and adapt the code generator, it is inevitable to gain some understanding
104.291 - how it works.
104.292 -
104.293 - \begin{figure}[h]
104.294 - \begin{tikzpicture}[x = 4.2cm, y = 1cm]
104.295 - \tikzstyle entity=[rounded corners, draw, thick, color = black, fill = white];
104.296 - \tikzstyle process=[ellipse, draw, thick, color = green, fill = white];
104.297 - \tikzstyle process_arrow=[->, semithick, color = green];
104.298 - \node (HOL) at (0, 4) [style=entity] {\isa{Isabelle{\isacharslash}HOL} theory};
104.299 - \node (eqn) at (2, 2) [style=entity] {code equations};
104.300 - \node (iml) at (2, 0) [style=entity] {intermediate language};
104.301 - \node (seri) at (1, 0) [style=process] {serialisation};
104.302 - \node (SML) at (0, 3) [style=entity] {\isa{SML}};
104.303 - \node (OCaml) at (0, 2) [style=entity] {\isa{OCaml}};
104.304 - \node (further) at (0, 1) [style=entity] {\isa{{\isasymdots}}};
104.305 - \node (Haskell) at (0, 0) [style=entity] {\isa{Haskell}};
104.306 - \draw [style=process_arrow] (HOL) .. controls (2, 4) ..
104.307 - node [style=process, near start] {selection}
104.308 - node [style=process, near end] {preprocessing}
104.309 - (eqn);
104.310 - \draw [style=process_arrow] (eqn) -- node (transl) [style=process] {translation} (iml);
104.311 - \draw [style=process_arrow] (iml) -- (seri);
104.312 - \draw [style=process_arrow] (seri) -- (SML);
104.313 - \draw [style=process_arrow] (seri) -- (OCaml);
104.314 - \draw [style=process_arrow, dashed] (seri) -- (further);
104.315 - \draw [style=process_arrow] (seri) -- (Haskell);
104.316 - \end{tikzpicture}
104.317 - \caption{Code generator architecture}
104.318 - \label{fig:arch}
104.319 - \end{figure}
104.320 -
104.321 - The code generator employs a notion of executability
104.322 - for three foundational executable ingredients known
104.323 - from functional programming:
104.324 - \emph{code equations}, \emph{datatypes}, and
104.325 - \emph{type classes}. A code equation as a first approximation
104.326 - is a theorem of the form \isa{f\ t\isactrlisub {\isadigit{1}}\ t\isactrlisub {\isadigit{2}}\ {\isasymdots}\ t\isactrlisub n\ {\isasymequiv}\ t}
104.327 - (an equation headed by a constant \isa{f} with arguments
104.328 - \isa{t\isactrlisub {\isadigit{1}}\ t\isactrlisub {\isadigit{2}}\ {\isasymdots}\ t\isactrlisub n} and right hand side \isa{t}).
104.329 - Code generation aims to turn code equations
104.330 - into a functional program. This is achieved by three major
104.331 - components which operate sequentially, i.e. the result of one is
104.332 - the input
104.333 - of the next in the chain, see diagram \ref{fig:arch}:
104.334 -
104.335 - \begin{itemize}
104.336 -
104.337 - \item Out of the vast collection of theorems proven in a
104.338 - \qn{theory}, a reasonable subset modelling
104.339 - code equations is \qn{selected}.
104.340 -
104.341 - \item On those selected theorems, certain
104.342 - transformations are carried out
104.343 - (\qn{preprocessing}). Their purpose is to turn theorems
104.344 - representing non- or badly executable
104.345 - specifications into equivalent but executable counterparts.
104.346 - The result is a structured collection of \qn{code theorems}.
104.347 -
104.348 - \item Before the selected code equations are continued with,
104.349 - they can be \qn{preprocessed}, i.e. subjected to theorem
104.350 - transformations. This \qn{preprocessor} is an interface which
104.351 - allows to apply
104.352 - the full expressiveness of ML-based theorem transformations
104.353 - to code generation; motivating examples are shown below, see
104.354 - \secref{sec:preproc}.
104.355 - The result of the preprocessing step is a structured collection
104.356 - of code equations.
104.357 -
104.358 - \item These code equations are \qn{translated} to a program
104.359 - in an abstract intermediate language. Think of it as a kind
104.360 - of \qt{Mini-Haskell} with four \qn{statements}: \isa{data}
104.361 - (for datatypes), \isa{fun} (stemming from code equations),
104.362 - also \isa{class} and \isa{inst} (for type classes).
104.363 -
104.364 - \item Finally, the abstract program is \qn{serialised} into concrete
104.365 - source code of a target language.
104.366 -
104.367 - \end{itemize}
104.368 -
104.369 - \noindent From these steps, only the two last are carried out outside the logic; by
104.370 - keeping this layer as thin as possible, the amount of code to trust is
104.371 - kept to a minimum.%
104.372 -\end{isamarkuptext}%
104.373 -\isamarkuptrue%
104.374 -%
104.375 -\isadelimtheory
104.376 -%
104.377 -\endisadelimtheory
104.378 -%
104.379 -\isatagtheory
104.380 -\isacommand{end}\isamarkupfalse%
104.381 -%
104.382 -\endisatagtheory
104.383 -{\isafoldtheory}%
104.384 -%
104.385 -\isadelimtheory
104.386 -%
104.387 -\endisadelimtheory
104.388 -\isanewline
104.389 -\end{isabellebody}%
104.390 -%%% Local Variables:
104.391 -%%% mode: latex
104.392 -%%% TeX-master: "root"
104.393 -%%% End:
105.1 --- a/doc-src/IsarAdvanced/Codegen/Thy/document/ML.tex Wed Mar 04 11:05:02 2009 +0100
105.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
105.3 @@ -1,255 +0,0 @@
105.4 -%
105.5 -\begin{isabellebody}%
105.6 -\def\isabellecontext{ML}%
105.7 -%
105.8 -\isadelimtheory
105.9 -%
105.10 -\endisadelimtheory
105.11 -%
105.12 -\isatagtheory
105.13 -\isacommand{theory}\isamarkupfalse%
105.14 -\ {\isachardoublequoteopen}ML{\isachardoublequoteclose}\isanewline
105.15 -\isakeyword{imports}\ Setup\isanewline
105.16 -\isakeyword{begin}%
105.17 -\endisatagtheory
105.18 -{\isafoldtheory}%
105.19 -%
105.20 -\isadelimtheory
105.21 -%
105.22 -\endisadelimtheory
105.23 -%
105.24 -\isamarkupsection{ML system interfaces \label{sec:ml}%
105.25 -}
105.26 -\isamarkuptrue%
105.27 -%
105.28 -\begin{isamarkuptext}%
105.29 -Since the code generator framework not only aims to provide
105.30 - a nice Isar interface but also to form a base for
105.31 - code-generation-based applications, here a short
105.32 - description of the most important ML interfaces.%
105.33 -\end{isamarkuptext}%
105.34 -\isamarkuptrue%
105.35 -%
105.36 -\isamarkupsubsection{Executable theory content: \isa{Code}%
105.37 -}
105.38 -\isamarkuptrue%
105.39 -%
105.40 -\begin{isamarkuptext}%
105.41 -This Pure module implements the core notions of
105.42 - executable content of a theory.%
105.43 -\end{isamarkuptext}%
105.44 -\isamarkuptrue%
105.45 -%
105.46 -\isamarkupsubsubsection{Managing executable content%
105.47 -}
105.48 -\isamarkuptrue%
105.49 -%
105.50 -\isadelimmlref
105.51 -%
105.52 -\endisadelimmlref
105.53 -%
105.54 -\isatagmlref
105.55 -%
105.56 -\begin{isamarkuptext}%
105.57 -\begin{mldecls}
105.58 - \indexml{Code.add\_eqn}\verb|Code.add_eqn: thm -> theory -> theory| \\
105.59 - \indexml{Code.del\_eqn}\verb|Code.del_eqn: thm -> theory -> theory| \\
105.60 - \indexml{Code.add\_eqnl}\verb|Code.add_eqnl: string * (thm * bool) list lazy -> theory -> theory| \\
105.61 - \indexml{Code.map\_pre}\verb|Code.map_pre: (simpset -> simpset) -> theory -> theory| \\
105.62 - \indexml{Code.map\_post}\verb|Code.map_post: (simpset -> simpset) -> theory -> theory| \\
105.63 - \indexml{Code.add\_functrans}\verb|Code.add_functrans: string * (theory -> (thm * bool) list -> (thm * bool) list option)|\isasep\isanewline%
105.64 -\verb| -> theory -> theory| \\
105.65 - \indexml{Code.del\_functrans}\verb|Code.del_functrans: string -> theory -> theory| \\
105.66 - \indexml{Code.add\_datatype}\verb|Code.add_datatype: (string * typ) list -> theory -> theory| \\
105.67 - \indexml{Code.get\_datatype}\verb|Code.get_datatype: theory -> string|\isasep\isanewline%
105.68 -\verb| -> (string * sort) list * (string * typ list) list| \\
105.69 - \indexml{Code.get\_datatype\_of\_constr}\verb|Code.get_datatype_of_constr: theory -> string -> string option|
105.70 - \end{mldecls}
105.71 -
105.72 - \begin{description}
105.73 -
105.74 - \item \verb|Code.add_eqn|~\isa{thm}~\isa{thy} adds function
105.75 - theorem \isa{thm} to executable content.
105.76 -
105.77 - \item \verb|Code.del_eqn|~\isa{thm}~\isa{thy} removes function
105.78 - theorem \isa{thm} from executable content, if present.
105.79 -
105.80 - \item \verb|Code.add_eqnl|~\isa{{\isacharparenleft}const{\isacharcomma}\ lthms{\isacharparenright}}~\isa{thy} adds
105.81 - suspended code equations \isa{lthms} for constant
105.82 - \isa{const} to executable content.
105.83 -
105.84 - \item \verb|Code.map_pre|~\isa{f}~\isa{thy} changes
105.85 - the preprocessor simpset.
105.86 -
105.87 - \item \verb|Code.add_functrans|~\isa{{\isacharparenleft}name{\isacharcomma}\ f{\isacharparenright}}~\isa{thy} adds
105.88 - function transformer \isa{f} (named \isa{name}) to executable content;
105.89 - \isa{f} is a transformer of the code equations belonging
105.90 - to a certain function definition, depending on the
105.91 - current theory context. Returning \isa{NONE} indicates that no
105.92 - transformation took place; otherwise, the whole process will be iterated
105.93 - with the new code equations.
105.94 -
105.95 - \item \verb|Code.del_functrans|~\isa{name}~\isa{thy} removes
105.96 - function transformer named \isa{name} from executable content.
105.97 -
105.98 - \item \verb|Code.add_datatype|~\isa{cs}~\isa{thy} adds
105.99 - a datatype to executable content, with generation
105.100 - set \isa{cs}.
105.101 -
105.102 - \item \verb|Code.get_datatype_of_constr|~\isa{thy}~\isa{const}
105.103 - returns type constructor corresponding to
105.104 - constructor \isa{const}; returns \isa{NONE}
105.105 - if \isa{const} is no constructor.
105.106 -
105.107 - \end{description}%
105.108 -\end{isamarkuptext}%
105.109 -\isamarkuptrue%
105.110 -%
105.111 -\endisatagmlref
105.112 -{\isafoldmlref}%
105.113 -%
105.114 -\isadelimmlref
105.115 -%
105.116 -\endisadelimmlref
105.117 -%
105.118 -\isamarkupsubsection{Auxiliary%
105.119 -}
105.120 -\isamarkuptrue%
105.121 -%
105.122 -\isadelimmlref
105.123 -%
105.124 -\endisadelimmlref
105.125 -%
105.126 -\isatagmlref
105.127 -%
105.128 -\begin{isamarkuptext}%
105.129 -\begin{mldecls}
105.130 - \indexml{Code\_Unit.read\_const}\verb|Code_Unit.read_const: theory -> string -> string| \\
105.131 - \indexml{Code\_Unit.head\_eqn}\verb|Code_Unit.head_eqn: theory -> thm -> string * ((string * sort) list * typ)| \\
105.132 - \indexml{Code\_Unit.rewrite\_eqn}\verb|Code_Unit.rewrite_eqn: simpset -> thm -> thm| \\
105.133 - \end{mldecls}
105.134 -
105.135 - \begin{description}
105.136 -
105.137 - \item \verb|Code_Unit.read_const|~\isa{thy}~\isa{s}
105.138 - reads a constant as a concrete term expression \isa{s}.
105.139 -
105.140 - \item \verb|Code_Unit.head_eqn|~\isa{thy}~\isa{thm}
105.141 - extracts the constant and its type from a code equation \isa{thm}.
105.142 -
105.143 - \item \verb|Code_Unit.rewrite_eqn|~\isa{ss}~\isa{thm}
105.144 - rewrites a code equation \isa{thm} with a simpset \isa{ss};
105.145 - only arguments and right hand side are rewritten,
105.146 - not the head of the code equation.
105.147 -
105.148 - \end{description}%
105.149 -\end{isamarkuptext}%
105.150 -\isamarkuptrue%
105.151 -%
105.152 -\endisatagmlref
105.153 -{\isafoldmlref}%
105.154 -%
105.155 -\isadelimmlref
105.156 -%
105.157 -\endisadelimmlref
105.158 -%
105.159 -\isamarkupsubsection{Implementing code generator applications%
105.160 -}
105.161 -\isamarkuptrue%
105.162 -%
105.163 -\begin{isamarkuptext}%
105.164 -Implementing code generator applications on top
105.165 - of the framework set out so far usually not only
105.166 - involves using those primitive interfaces
105.167 - but also storing code-dependent data and various
105.168 - other things.%
105.169 -\end{isamarkuptext}%
105.170 -\isamarkuptrue%
105.171 -%
105.172 -\isamarkupsubsubsection{Data depending on the theory's executable content%
105.173 -}
105.174 -\isamarkuptrue%
105.175 -%
105.176 -\begin{isamarkuptext}%
105.177 -Due to incrementality of code generation, changes in the
105.178 - theory's executable content have to be propagated in a
105.179 - certain fashion. Additionally, such changes may occur
105.180 - not only during theory extension but also during theory
105.181 - merge, which is a little bit nasty from an implementation
105.182 - point of view. The framework provides a solution
105.183 - to this technical challenge by providing a functorial
105.184 - data slot \verb|CodeDataFun|; on instantiation
105.185 - of this functor, the following types and operations
105.186 - are required:
105.187 -
105.188 - \medskip
105.189 - \begin{tabular}{l}
105.190 - \isa{type\ T} \\
105.191 - \isa{val\ empty{\isacharcolon}\ T} \\
105.192 - \isa{val\ purge{\isacharcolon}\ theory\ {\isasymrightarrow}\ string\ list\ option\ {\isasymrightarrow}\ T\ {\isasymrightarrow}\ T}
105.193 - \end{tabular}
105.194 -
105.195 - \begin{description}
105.196 -
105.197 - \item \isa{T} the type of data to store.
105.198 -
105.199 - \item \isa{empty} initial (empty) data.
105.200 -
105.201 - \item \isa{purge}~\isa{thy}~\isa{consts} propagates changes in executable content;
105.202 - \isa{consts} indicates the kind
105.203 - of change: \verb|NONE| stands for a fundamental change
105.204 - which invalidates any existing code, \isa{SOME\ consts}
105.205 - hints that executable content for constants \isa{consts}
105.206 - has changed.
105.207 -
105.208 - \end{description}
105.209 -
105.210 - \noindent An instance of \verb|CodeDataFun| provides the following
105.211 - interface:
105.212 -
105.213 - \medskip
105.214 - \begin{tabular}{l}
105.215 - \isa{get{\isacharcolon}\ theory\ {\isasymrightarrow}\ T} \\
105.216 - \isa{change{\isacharcolon}\ theory\ {\isasymrightarrow}\ {\isacharparenleft}T\ {\isasymrightarrow}\ T{\isacharparenright}\ {\isasymrightarrow}\ T} \\
105.217 - \isa{change{\isacharunderscore}yield{\isacharcolon}\ theory\ {\isasymrightarrow}\ {\isacharparenleft}T\ {\isasymrightarrow}\ {\isacharprime}a\ {\isacharasterisk}\ T{\isacharparenright}\ {\isasymrightarrow}\ {\isacharprime}a\ {\isacharasterisk}\ T}
105.218 - \end{tabular}
105.219 -
105.220 - \begin{description}
105.221 -
105.222 - \item \isa{get} retrieval of the current data.
105.223 -
105.224 - \item \isa{change} update of current data (cached!)
105.225 - by giving a continuation.
105.226 -
105.227 - \item \isa{change{\isacharunderscore}yield} update with side result.
105.228 -
105.229 - \end{description}%
105.230 -\end{isamarkuptext}%
105.231 -\isamarkuptrue%
105.232 -%
105.233 -\begin{isamarkuptext}%
105.234 -\bigskip
105.235 -
105.236 - \emph{Happy proving, happy hacking!}%
105.237 -\end{isamarkuptext}%
105.238 -\isamarkuptrue%
105.239 -%
105.240 -\isadelimtheory
105.241 -%
105.242 -\endisadelimtheory
105.243 -%
105.244 -\isatagtheory
105.245 -\isacommand{end}\isamarkupfalse%
105.246 -%
105.247 -\endisatagtheory
105.248 -{\isafoldtheory}%
105.249 -%
105.250 -\isadelimtheory
105.251 -%
105.252 -\endisadelimtheory
105.253 -\isanewline
105.254 -\end{isabellebody}%
105.255 -%%% Local Variables:
105.256 -%%% mode: latex
105.257 -%%% TeX-master: "root"
105.258 -%%% End:
106.1 --- a/doc-src/IsarAdvanced/Codegen/Thy/document/Program.tex Wed Mar 04 11:05:02 2009 +0100
106.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
106.3 @@ -1,1250 +0,0 @@
106.4 -%
106.5 -\begin{isabellebody}%
106.6 -\def\isabellecontext{Program}%
106.7 -%
106.8 -\isadelimtheory
106.9 -%
106.10 -\endisadelimtheory
106.11 -%
106.12 -\isatagtheory
106.13 -\isacommand{theory}\isamarkupfalse%
106.14 -\ Program\isanewline
106.15 -\isakeyword{imports}\ Introduction\isanewline
106.16 -\isakeyword{begin}%
106.17 -\endisatagtheory
106.18 -{\isafoldtheory}%
106.19 -%
106.20 -\isadelimtheory
106.21 -%
106.22 -\endisadelimtheory
106.23 -%
106.24 -\isamarkupsection{Turning Theories into Programs \label{sec:program}%
106.25 -}
106.26 -\isamarkuptrue%
106.27 -%
106.28 -\isamarkupsubsection{The \isa{Isabelle{\isacharslash}HOL} default setup%
106.29 -}
106.30 -\isamarkuptrue%
106.31 -%
106.32 -\begin{isamarkuptext}%
106.33 -We have already seen how by default equations stemming from
106.34 - \hyperlink{command.definition}{\mbox{\isa{\isacommand{definition}}}}/\hyperlink{command.primrec}{\mbox{\isa{\isacommand{primrec}}}}/\hyperlink{command.fun}{\mbox{\isa{\isacommand{fun}}}}
106.35 - statements are used for code generation. This default behaviour
106.36 - can be changed, e.g. by providing different code equations.
106.37 - All kinds of customisation shown in this section is \emph{safe}
106.38 - in the sense that the user does not have to worry about
106.39 - correctness -- all programs generatable that way are partially
106.40 - correct.%
106.41 -\end{isamarkuptext}%
106.42 -\isamarkuptrue%
106.43 -%
106.44 -\isamarkupsubsection{Selecting code equations%
106.45 -}
106.46 -\isamarkuptrue%
106.47 -%
106.48 -\begin{isamarkuptext}%
106.49 -Coming back to our introductory example, we
106.50 - could provide an alternative code equations for \isa{dequeue}
106.51 - explicitly:%
106.52 -\end{isamarkuptext}%
106.53 -\isamarkuptrue%
106.54 -%
106.55 -\isadelimquote
106.56 -%
106.57 -\endisadelimquote
106.58 -%
106.59 -\isatagquote
106.60 -\isacommand{lemma}\isamarkupfalse%
106.61 -\ {\isacharbrackleft}code{\isacharbrackright}{\isacharcolon}\isanewline
106.62 -\ \ {\isachardoublequoteopen}dequeue\ {\isacharparenleft}AQueue\ xs\ {\isacharbrackleft}{\isacharbrackright}{\isacharparenright}\ {\isacharequal}\isanewline
106.63 -\ \ \ \ \ {\isacharparenleft}if\ xs\ {\isacharequal}\ {\isacharbrackleft}{\isacharbrackright}\ then\ {\isacharparenleft}None{\isacharcomma}\ AQueue\ {\isacharbrackleft}{\isacharbrackright}\ {\isacharbrackleft}{\isacharbrackright}{\isacharparenright}\isanewline
106.64 -\ \ \ \ \ \ \ else\ dequeue\ {\isacharparenleft}AQueue\ {\isacharbrackleft}{\isacharbrackright}\ {\isacharparenleft}rev\ xs{\isacharparenright}{\isacharparenright}{\isacharparenright}{\isachardoublequoteclose}\isanewline
106.65 -\ \ {\isachardoublequoteopen}dequeue\ {\isacharparenleft}AQueue\ xs\ {\isacharparenleft}y\ {\isacharhash}\ ys{\isacharparenright}{\isacharparenright}\ {\isacharequal}\isanewline
106.66 -\ \ \ \ \ {\isacharparenleft}Some\ y{\isacharcomma}\ AQueue\ xs\ ys{\isacharparenright}{\isachardoublequoteclose}\isanewline
106.67 -\ \ \isacommand{by}\isamarkupfalse%
106.68 -\ {\isacharparenleft}cases\ xs{\isacharcomma}\ simp{\isacharunderscore}all{\isacharparenright}\ {\isacharparenleft}cases\ {\isachardoublequoteopen}rev\ xs{\isachardoublequoteclose}{\isacharcomma}\ simp{\isacharunderscore}all{\isacharparenright}%
106.69 -\endisatagquote
106.70 -{\isafoldquote}%
106.71 -%
106.72 -\isadelimquote
106.73 -%
106.74 -\endisadelimquote
106.75 -%
106.76 -\begin{isamarkuptext}%
106.77 -\noindent The annotation \isa{{\isacharbrackleft}code{\isacharbrackright}} is an \isa{Isar}
106.78 - \isa{attribute} which states that the given theorems should be
106.79 - considered as code equations for a \isa{fun} statement --
106.80 - the corresponding constant is determined syntactically. The resulting code:%
106.81 -\end{isamarkuptext}%
106.82 -\isamarkuptrue%
106.83 -%
106.84 -\isadelimquote
106.85 -%
106.86 -\endisadelimquote
106.87 -%
106.88 -\isatagquote
106.89 -%
106.90 -\begin{isamarkuptext}%
106.91 -\isatypewriter%
106.92 -\noindent%
106.93 -\hspace*{0pt}dequeue ::~forall a.~Queue a -> (Maybe a,~Queue a);\\
106.94 -\hspace*{0pt}dequeue (AQueue xs (y :~ys)) = (Just y,~AQueue xs ys);\\
106.95 -\hspace*{0pt}dequeue (AQueue xs []) =\\
106.96 -\hspace*{0pt} ~(if nulla xs then (Nothing,~AQueue [] [])\\
106.97 -\hspace*{0pt} ~~~else dequeue (AQueue [] (rev xs)));%
106.98 -\end{isamarkuptext}%
106.99 -\isamarkuptrue%
106.100 -%
106.101 -\endisatagquote
106.102 -{\isafoldquote}%
106.103 -%
106.104 -\isadelimquote
106.105 -%
106.106 -\endisadelimquote
106.107 -%
106.108 -\begin{isamarkuptext}%
106.109 -\noindent You may note that the equality test \isa{xs\ {\isacharequal}\ {\isacharbrackleft}{\isacharbrackright}} has been
106.110 - replaced by the predicate \isa{null\ xs}. This is due to the default
106.111 - setup in the \qn{preprocessor} to be discussed further below (\secref{sec:preproc}).
106.112 -
106.113 - Changing the default constructor set of datatypes is also
106.114 - possible. See \secref{sec:datatypes} for an example.
106.115 -
106.116 - As told in \secref{sec:concept}, code generation is based
106.117 - on a structured collection of code theorems.
106.118 - For explorative purpose, this collection
106.119 - may be inspected using the \hyperlink{command.code-thms}{\mbox{\isa{\isacommand{code{\isacharunderscore}thms}}}} command:%
106.120 -\end{isamarkuptext}%
106.121 -\isamarkuptrue%
106.122 -%
106.123 -\isadelimquote
106.124 -%
106.125 -\endisadelimquote
106.126 -%
106.127 -\isatagquote
106.128 -\isacommand{code{\isacharunderscore}thms}\isamarkupfalse%
106.129 -\ dequeue%
106.130 -\endisatagquote
106.131 -{\isafoldquote}%
106.132 -%
106.133 -\isadelimquote
106.134 -%
106.135 -\endisadelimquote
106.136 -%
106.137 -\begin{isamarkuptext}%
106.138 -\noindent prints a table with \emph{all} code equations
106.139 - for \isa{dequeue}, including
106.140 - \emph{all} code equations those equations depend
106.141 - on recursively.
106.142 -
106.143 - Similarly, the \hyperlink{command.code-deps}{\mbox{\isa{\isacommand{code{\isacharunderscore}deps}}}} command shows a graph
106.144 - visualising dependencies between code equations.%
106.145 -\end{isamarkuptext}%
106.146 -\isamarkuptrue%
106.147 -%
106.148 -\isamarkupsubsection{\isa{class} and \isa{instantiation}%
106.149 -}
106.150 -\isamarkuptrue%
106.151 -%
106.152 -\begin{isamarkuptext}%
106.153 -Concerning type classes and code generation, let us examine an example
106.154 - from abstract algebra:%
106.155 -\end{isamarkuptext}%
106.156 -\isamarkuptrue%
106.157 -%
106.158 -\isadelimquote
106.159 -%
106.160 -\endisadelimquote
106.161 -%
106.162 -\isatagquote
106.163 -\isacommand{class}\isamarkupfalse%
106.164 -\ semigroup\ {\isacharequal}\isanewline
106.165 -\ \ \isakeyword{fixes}\ mult\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharprime}a\ {\isasymRightarrow}\ {\isacharprime}a\ {\isasymRightarrow}\ {\isacharprime}a{\isachardoublequoteclose}\ {\isacharparenleft}\isakeyword{infixl}\ {\isachardoublequoteopen}{\isasymotimes}{\isachardoublequoteclose}\ {\isadigit{7}}{\isadigit{0}}{\isacharparenright}\isanewline
106.166 -\ \ \isakeyword{assumes}\ assoc{\isacharcolon}\ {\isachardoublequoteopen}{\isacharparenleft}x\ {\isasymotimes}\ y{\isacharparenright}\ {\isasymotimes}\ z\ {\isacharequal}\ x\ {\isasymotimes}\ {\isacharparenleft}y\ {\isasymotimes}\ z{\isacharparenright}{\isachardoublequoteclose}\isanewline
106.167 -\isanewline
106.168 -\isacommand{class}\isamarkupfalse%
106.169 -\ monoid\ {\isacharequal}\ semigroup\ {\isacharplus}\isanewline
106.170 -\ \ \isakeyword{fixes}\ neutral\ {\isacharcolon}{\isacharcolon}\ {\isacharprime}a\ {\isacharparenleft}{\isachardoublequoteopen}{\isasymone}{\isachardoublequoteclose}{\isacharparenright}\isanewline
106.171 -\ \ \isakeyword{assumes}\ neutl{\isacharcolon}\ {\isachardoublequoteopen}{\isasymone}\ {\isasymotimes}\ x\ {\isacharequal}\ x{\isachardoublequoteclose}\isanewline
106.172 -\ \ \ \ \isakeyword{and}\ neutr{\isacharcolon}\ {\isachardoublequoteopen}x\ {\isasymotimes}\ {\isasymone}\ {\isacharequal}\ x{\isachardoublequoteclose}\isanewline
106.173 -\isanewline
106.174 -\isacommand{instantiation}\isamarkupfalse%
106.175 -\ nat\ {\isacharcolon}{\isacharcolon}\ monoid\isanewline
106.176 -\isakeyword{begin}\isanewline
106.177 -\isanewline
106.178 -\isacommand{primrec}\isamarkupfalse%
106.179 -\ mult{\isacharunderscore}nat\ \isakeyword{where}\isanewline
106.180 -\ \ \ \ {\isachardoublequoteopen}{\isadigit{0}}\ {\isasymotimes}\ n\ {\isacharequal}\ {\isacharparenleft}{\isadigit{0}}{\isasymColon}nat{\isacharparenright}{\isachardoublequoteclose}\isanewline
106.181 -\ \ {\isacharbar}\ {\isachardoublequoteopen}Suc\ m\ {\isasymotimes}\ n\ {\isacharequal}\ n\ {\isacharplus}\ m\ {\isasymotimes}\ n{\isachardoublequoteclose}\isanewline
106.182 -\isanewline
106.183 -\isacommand{definition}\isamarkupfalse%
106.184 -\ neutral{\isacharunderscore}nat\ \isakeyword{where}\isanewline
106.185 -\ \ {\isachardoublequoteopen}{\isasymone}\ {\isacharequal}\ Suc\ {\isadigit{0}}{\isachardoublequoteclose}\isanewline
106.186 -\isanewline
106.187 -\isacommand{lemma}\isamarkupfalse%
106.188 -\ add{\isacharunderscore}mult{\isacharunderscore}distrib{\isacharcolon}\isanewline
106.189 -\ \ \isakeyword{fixes}\ n\ m\ q\ {\isacharcolon}{\isacharcolon}\ nat\isanewline
106.190 -\ \ \isakeyword{shows}\ {\isachardoublequoteopen}{\isacharparenleft}n\ {\isacharplus}\ m{\isacharparenright}\ {\isasymotimes}\ q\ {\isacharequal}\ n\ {\isasymotimes}\ q\ {\isacharplus}\ m\ {\isasymotimes}\ q{\isachardoublequoteclose}\isanewline
106.191 -\ \ \isacommand{by}\isamarkupfalse%
106.192 -\ {\isacharparenleft}induct\ n{\isacharparenright}\ simp{\isacharunderscore}all\isanewline
106.193 -\isanewline
106.194 -\isacommand{instance}\isamarkupfalse%
106.195 -\ \isacommand{proof}\isamarkupfalse%
106.196 -\isanewline
106.197 -\ \ \isacommand{fix}\isamarkupfalse%
106.198 -\ m\ n\ q\ {\isacharcolon}{\isacharcolon}\ nat\isanewline
106.199 -\ \ \isacommand{show}\isamarkupfalse%
106.200 -\ {\isachardoublequoteopen}m\ {\isasymotimes}\ n\ {\isasymotimes}\ q\ {\isacharequal}\ m\ {\isasymotimes}\ {\isacharparenleft}n\ {\isasymotimes}\ q{\isacharparenright}{\isachardoublequoteclose}\isanewline
106.201 -\ \ \ \ \isacommand{by}\isamarkupfalse%
106.202 -\ {\isacharparenleft}induct\ m{\isacharparenright}\ {\isacharparenleft}simp{\isacharunderscore}all\ add{\isacharcolon}\ add{\isacharunderscore}mult{\isacharunderscore}distrib{\isacharparenright}\isanewline
106.203 -\ \ \isacommand{show}\isamarkupfalse%
106.204 -\ {\isachardoublequoteopen}{\isasymone}\ {\isasymotimes}\ n\ {\isacharequal}\ n{\isachardoublequoteclose}\isanewline
106.205 -\ \ \ \ \isacommand{by}\isamarkupfalse%
106.206 -\ {\isacharparenleft}simp\ add{\isacharcolon}\ neutral{\isacharunderscore}nat{\isacharunderscore}def{\isacharparenright}\isanewline
106.207 -\ \ \isacommand{show}\isamarkupfalse%
106.208 -\ {\isachardoublequoteopen}m\ {\isasymotimes}\ {\isasymone}\ {\isacharequal}\ m{\isachardoublequoteclose}\isanewline
106.209 -\ \ \ \ \isacommand{by}\isamarkupfalse%
106.210 -\ {\isacharparenleft}induct\ m{\isacharparenright}\ {\isacharparenleft}simp{\isacharunderscore}all\ add{\isacharcolon}\ neutral{\isacharunderscore}nat{\isacharunderscore}def{\isacharparenright}\isanewline
106.211 -\isacommand{qed}\isamarkupfalse%
106.212 -\isanewline
106.213 -\isanewline
106.214 -\isacommand{end}\isamarkupfalse%
106.215 -%
106.216 -\endisatagquote
106.217 -{\isafoldquote}%
106.218 -%
106.219 -\isadelimquote
106.220 -%
106.221 -\endisadelimquote
106.222 -%
106.223 -\begin{isamarkuptext}%
106.224 -\noindent We define the natural operation of the natural numbers
106.225 - on monoids:%
106.226 -\end{isamarkuptext}%
106.227 -\isamarkuptrue%
106.228 -%
106.229 -\isadelimquote
106.230 -%
106.231 -\endisadelimquote
106.232 -%
106.233 -\isatagquote
106.234 -\isacommand{primrec}\isamarkupfalse%
106.235 -\ {\isacharparenleft}\isakeyword{in}\ monoid{\isacharparenright}\ pow\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymRightarrow}\ {\isacharprime}a\ {\isasymRightarrow}\ {\isacharprime}a{\isachardoublequoteclose}\ \isakeyword{where}\isanewline
106.236 -\ \ \ \ {\isachardoublequoteopen}pow\ {\isadigit{0}}\ a\ {\isacharequal}\ {\isasymone}{\isachardoublequoteclose}\isanewline
106.237 -\ \ {\isacharbar}\ {\isachardoublequoteopen}pow\ {\isacharparenleft}Suc\ n{\isacharparenright}\ a\ {\isacharequal}\ a\ {\isasymotimes}\ pow\ n\ a{\isachardoublequoteclose}%
106.238 -\endisatagquote
106.239 -{\isafoldquote}%
106.240 -%
106.241 -\isadelimquote
106.242 -%
106.243 -\endisadelimquote
106.244 -%
106.245 -\begin{isamarkuptext}%
106.246 -\noindent This we use to define the discrete exponentiation function:%
106.247 -\end{isamarkuptext}%
106.248 -\isamarkuptrue%
106.249 -%
106.250 -\isadelimquote
106.251 -%
106.252 -\endisadelimquote
106.253 -%
106.254 -\isatagquote
106.255 -\isacommand{definition}\isamarkupfalse%
106.256 -\ bexp\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymRightarrow}\ nat{\isachardoublequoteclose}\ \isakeyword{where}\isanewline
106.257 -\ \ {\isachardoublequoteopen}bexp\ n\ {\isacharequal}\ pow\ n\ {\isacharparenleft}Suc\ {\isacharparenleft}Suc\ {\isadigit{0}}{\isacharparenright}{\isacharparenright}{\isachardoublequoteclose}%
106.258 -\endisatagquote
106.259 -{\isafoldquote}%
106.260 -%
106.261 -\isadelimquote
106.262 -%
106.263 -\endisadelimquote
106.264 -%
106.265 -\begin{isamarkuptext}%
106.266 -\noindent The corresponding code:%
106.267 -\end{isamarkuptext}%
106.268 -\isamarkuptrue%
106.269 -%
106.270 -\isadelimquote
106.271 -%
106.272 -\endisadelimquote
106.273 -%
106.274 -\isatagquote
106.275 -%
106.276 -\begin{isamarkuptext}%
106.277 -\isatypewriter%
106.278 -\noindent%
106.279 -\hspace*{0pt}module Example where {\char123}\\
106.280 -\hspace*{0pt}\\
106.281 -\hspace*{0pt}\\
106.282 -\hspace*{0pt}data Nat = Suc Nat | Zero{\char95}nat;\\
106.283 -\hspace*{0pt}\\
106.284 -\hspace*{0pt}class Semigroup a where {\char123}\\
106.285 -\hspace*{0pt} ~mult ::~a -> a -> a;\\
106.286 -\hspace*{0pt}{\char125};\\
106.287 -\hspace*{0pt}\\
106.288 -\hspace*{0pt}class (Semigroup a) => Monoid a where {\char123}\\
106.289 -\hspace*{0pt} ~neutral ::~a;\\
106.290 -\hspace*{0pt}{\char125};\\
106.291 -\hspace*{0pt}\\
106.292 -\hspace*{0pt}pow ::~forall a.~(Monoid a) => Nat -> a -> a;\\
106.293 -\hspace*{0pt}pow Zero{\char95}nat a = neutral;\\
106.294 -\hspace*{0pt}pow (Suc n) a = mult a (pow n a);\\
106.295 -\hspace*{0pt}\\
106.296 -\hspace*{0pt}plus{\char95}nat ::~Nat -> Nat -> Nat;\\
106.297 -\hspace*{0pt}plus{\char95}nat (Suc m) n = plus{\char95}nat m (Suc n);\\
106.298 -\hspace*{0pt}plus{\char95}nat Zero{\char95}nat n = n;\\
106.299 -\hspace*{0pt}\\
106.300 -\hspace*{0pt}neutral{\char95}nat ::~Nat;\\
106.301 -\hspace*{0pt}neutral{\char95}nat = Suc Zero{\char95}nat;\\
106.302 -\hspace*{0pt}\\
106.303 -\hspace*{0pt}mult{\char95}nat ::~Nat -> Nat -> Nat;\\
106.304 -\hspace*{0pt}mult{\char95}nat Zero{\char95}nat n = Zero{\char95}nat;\\
106.305 -\hspace*{0pt}mult{\char95}nat (Suc m) n = plus{\char95}nat n (mult{\char95}nat m n);\\
106.306 -\hspace*{0pt}\\
106.307 -\hspace*{0pt}instance Semigroup Nat where {\char123}\\
106.308 -\hspace*{0pt} ~mult = mult{\char95}nat;\\
106.309 -\hspace*{0pt}{\char125};\\
106.310 -\hspace*{0pt}\\
106.311 -\hspace*{0pt}instance Monoid Nat where {\char123}\\
106.312 -\hspace*{0pt} ~neutral = neutral{\char95}nat;\\
106.313 -\hspace*{0pt}{\char125};\\
106.314 -\hspace*{0pt}\\
106.315 -\hspace*{0pt}bexp ::~Nat -> Nat;\\
106.316 -\hspace*{0pt}bexp n = pow n (Suc (Suc Zero{\char95}nat));\\
106.317 -\hspace*{0pt}\\
106.318 -\hspace*{0pt}{\char125}%
106.319 -\end{isamarkuptext}%
106.320 -\isamarkuptrue%
106.321 -%
106.322 -\endisatagquote
106.323 -{\isafoldquote}%
106.324 -%
106.325 -\isadelimquote
106.326 -%
106.327 -\endisadelimquote
106.328 -%
106.329 -\begin{isamarkuptext}%
106.330 -\noindent This is a convenient place to show how explicit dictionary construction
106.331 - manifests in generated code (here, the same example in \isa{SML}):%
106.332 -\end{isamarkuptext}%
106.333 -\isamarkuptrue%
106.334 -%
106.335 -\isadelimquote
106.336 -%
106.337 -\endisadelimquote
106.338 -%
106.339 -\isatagquote
106.340 -%
106.341 -\begin{isamarkuptext}%
106.342 -\isatypewriter%
106.343 -\noindent%
106.344 -\hspace*{0pt}structure Example = \\
106.345 -\hspace*{0pt}struct\\
106.346 -\hspace*{0pt}\\
106.347 -\hspace*{0pt}datatype nat = Suc of nat | Zero{\char95}nat;\\
106.348 -\hspace*{0pt}\\
106.349 -\hspace*{0pt}type 'a semigroup = {\char123}mult :~'a -> 'a -> 'a{\char125};\\
106.350 -\hspace*{0pt}fun mult (A{\char95}:'a semigroup) = {\char35}mult A{\char95};\\
106.351 -\hspace*{0pt}\\
106.352 -\hspace*{0pt}type 'a monoid = {\char123}Program{\char95}{\char95}semigroup{\char95}monoid :~'a semigroup,~neutral :~'a{\char125};\\
106.353 -\hspace*{0pt}fun semigroup{\char95}monoid (A{\char95}:'a monoid) = {\char35}Program{\char95}{\char95}semigroup{\char95}monoid A{\char95};\\
106.354 -\hspace*{0pt}fun neutral (A{\char95}:'a monoid) = {\char35}neutral A{\char95};\\
106.355 -\hspace*{0pt}\\
106.356 -\hspace*{0pt}fun pow A{\char95}~Zero{\char95}nat a = neutral A{\char95}\\
106.357 -\hspace*{0pt} ~| pow A{\char95}~(Suc n) a = mult (semigroup{\char95}monoid A{\char95}) a (pow A{\char95}~n a);\\
106.358 -\hspace*{0pt}\\
106.359 -\hspace*{0pt}fun plus{\char95}nat (Suc m) n = plus{\char95}nat m (Suc n)\\
106.360 -\hspace*{0pt} ~| plus{\char95}nat Zero{\char95}nat n = n;\\
106.361 -\hspace*{0pt}\\
106.362 -\hspace*{0pt}val neutral{\char95}nat :~nat = Suc Zero{\char95}nat\\
106.363 -\hspace*{0pt}\\
106.364 -\hspace*{0pt}fun mult{\char95}nat Zero{\char95}nat n = Zero{\char95}nat\\
106.365 -\hspace*{0pt} ~| mult{\char95}nat (Suc m) n = plus{\char95}nat n (mult{\char95}nat m n);\\
106.366 -\hspace*{0pt}\\
106.367 -\hspace*{0pt}val semigroup{\char95}nat = {\char123}mult = mult{\char95}nat{\char125}~:~nat semigroup;\\
106.368 -\hspace*{0pt}\\
106.369 -\hspace*{0pt}val monoid{\char95}nat =\\
106.370 -\hspace*{0pt} ~{\char123}Program{\char95}{\char95}semigroup{\char95}monoid = semigroup{\char95}nat,~neutral = neutral{\char95}nat{\char125}~:\\
106.371 -\hspace*{0pt} ~nat monoid;\\
106.372 -\hspace*{0pt}\\
106.373 -\hspace*{0pt}fun bexp n = pow monoid{\char95}nat n (Suc (Suc Zero{\char95}nat));\\
106.374 -\hspace*{0pt}\\
106.375 -\hspace*{0pt}end;~(*struct Example*)%
106.376 -\end{isamarkuptext}%
106.377 -\isamarkuptrue%
106.378 -%
106.379 -\endisatagquote
106.380 -{\isafoldquote}%
106.381 -%
106.382 -\isadelimquote
106.383 -%
106.384 -\endisadelimquote
106.385 -%
106.386 -\begin{isamarkuptext}%
106.387 -\noindent Note the parameters with trailing underscore (\verb|A_|)
106.388 - which are the dictionary parameters.%
106.389 -\end{isamarkuptext}%
106.390 -\isamarkuptrue%
106.391 -%
106.392 -\isamarkupsubsection{The preprocessor \label{sec:preproc}%
106.393 -}
106.394 -\isamarkuptrue%
106.395 -%
106.396 -\begin{isamarkuptext}%
106.397 -Before selected function theorems are turned into abstract
106.398 - code, a chain of definitional transformation steps is carried
106.399 - out: \emph{preprocessing}. In essence, the preprocessor
106.400 - consists of two components: a \emph{simpset} and \emph{function transformers}.
106.401 -
106.402 - The \emph{simpset} allows to employ the full generality of the Isabelle
106.403 - simplifier. Due to the interpretation of theorems
106.404 - as code equations, rewrites are applied to the right
106.405 - hand side and the arguments of the left hand side of an
106.406 - equation, but never to the constant heading the left hand side.
106.407 - An important special case are \emph{inline theorems} which may be
106.408 - declared and undeclared using the
106.409 - \emph{code inline} or \emph{code inline del} attribute respectively.
106.410 -
106.411 - Some common applications:%
106.412 -\end{isamarkuptext}%
106.413 -\isamarkuptrue%
106.414 -%
106.415 -\begin{itemize}
106.416 -%
106.417 -\begin{isamarkuptext}%
106.418 -\item replacing non-executable constructs by executable ones:%
106.419 -\end{isamarkuptext}%
106.420 -\isamarkuptrue%
106.421 -%
106.422 -\isadelimquote
106.423 -%
106.424 -\endisadelimquote
106.425 -%
106.426 -\isatagquote
106.427 -\isacommand{lemma}\isamarkupfalse%
106.428 -\ {\isacharbrackleft}code\ inline{\isacharbrackright}{\isacharcolon}\isanewline
106.429 -\ \ {\isachardoublequoteopen}x\ {\isasymin}\ set\ xs\ {\isasymlongleftrightarrow}\ x\ mem\ xs{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse%
106.430 -\ {\isacharparenleft}induct\ xs{\isacharparenright}\ simp{\isacharunderscore}all%
106.431 -\endisatagquote
106.432 -{\isafoldquote}%
106.433 -%
106.434 -\isadelimquote
106.435 -%
106.436 -\endisadelimquote
106.437 -%
106.438 -\begin{isamarkuptext}%
106.439 -\item eliminating superfluous constants:%
106.440 -\end{isamarkuptext}%
106.441 -\isamarkuptrue%
106.442 -%
106.443 -\isadelimquote
106.444 -%
106.445 -\endisadelimquote
106.446 -%
106.447 -\isatagquote
106.448 -\isacommand{lemma}\isamarkupfalse%
106.449 -\ {\isacharbrackleft}code\ inline{\isacharbrackright}{\isacharcolon}\isanewline
106.450 -\ \ {\isachardoublequoteopen}{\isadigit{1}}\ {\isacharequal}\ Suc\ {\isadigit{0}}{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse%
106.451 -\ simp%
106.452 -\endisatagquote
106.453 -{\isafoldquote}%
106.454 -%
106.455 -\isadelimquote
106.456 -%
106.457 -\endisadelimquote
106.458 -%
106.459 -\begin{isamarkuptext}%
106.460 -\item replacing executable but inconvenient constructs:%
106.461 -\end{isamarkuptext}%
106.462 -\isamarkuptrue%
106.463 -%
106.464 -\isadelimquote
106.465 -%
106.466 -\endisadelimquote
106.467 -%
106.468 -\isatagquote
106.469 -\isacommand{lemma}\isamarkupfalse%
106.470 -\ {\isacharbrackleft}code\ inline{\isacharbrackright}{\isacharcolon}\isanewline
106.471 -\ \ {\isachardoublequoteopen}xs\ {\isacharequal}\ {\isacharbrackleft}{\isacharbrackright}\ {\isasymlongleftrightarrow}\ List{\isachardot}null\ xs{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse%
106.472 -\ {\isacharparenleft}induct\ xs{\isacharparenright}\ simp{\isacharunderscore}all%
106.473 -\endisatagquote
106.474 -{\isafoldquote}%
106.475 -%
106.476 -\isadelimquote
106.477 -%
106.478 -\endisadelimquote
106.479 -%
106.480 -\end{itemize}
106.481 -%
106.482 -\begin{isamarkuptext}%
106.483 -\noindent \emph{Function transformers} provide a very general interface,
106.484 - transforming a list of function theorems to another
106.485 - list of function theorems, provided that neither the heading
106.486 - constant nor its type change. The \isa{{\isadigit{0}}} / \isa{Suc}
106.487 - pattern elimination implemented in
106.488 - theory \isa{Efficient{\isacharunderscore}Nat} (see \secref{eff_nat}) uses this
106.489 - interface.
106.490 -
106.491 - \noindent The current setup of the preprocessor may be inspected using
106.492 - the \hyperlink{command.print-codesetup}{\mbox{\isa{\isacommand{print{\isacharunderscore}codesetup}}}} command.
106.493 - \hyperlink{command.code-thms}{\mbox{\isa{\isacommand{code{\isacharunderscore}thms}}}} provides a convenient
106.494 - mechanism to inspect the impact of a preprocessor setup
106.495 - on code equations.
106.496 -
106.497 - \begin{warn}
106.498 - The attribute \emph{code unfold}
106.499 - associated with the \isa{SML\ code\ generator} also applies to
106.500 - the \isa{generic\ code\ generator}:
106.501 - \emph{code unfold} implies \emph{code inline}.
106.502 - \end{warn}%
106.503 -\end{isamarkuptext}%
106.504 -\isamarkuptrue%
106.505 -%
106.506 -\isamarkupsubsection{Datatypes \label{sec:datatypes}%
106.507 -}
106.508 -\isamarkuptrue%
106.509 -%
106.510 -\begin{isamarkuptext}%
106.511 -Conceptually, any datatype is spanned by a set of
106.512 - \emph{constructors} of type \isa{{\isasymtau}\ {\isacharequal}\ {\isasymdots}\ {\isasymRightarrow}\ {\isasymkappa}\ {\isasymalpha}\isactrlisub {\isadigit{1}}\ {\isasymdots}\ {\isasymalpha}\isactrlisub n} where \isa{{\isacharbraceleft}{\isasymalpha}\isactrlisub {\isadigit{1}}{\isacharcomma}\ {\isasymdots}{\isacharcomma}\ {\isasymalpha}\isactrlisub n{\isacharbraceright}} is exactly the set of \emph{all} type variables in
106.513 - \isa{{\isasymtau}}. The HOL datatype package by default registers any new
106.514 - datatype in the table of datatypes, which may be inspected using the
106.515 - \hyperlink{command.print-codesetup}{\mbox{\isa{\isacommand{print{\isacharunderscore}codesetup}}}} command.
106.516 -
106.517 - In some cases, it is appropriate to alter or extend this table. As
106.518 - an example, we will develop an alternative representation of the
106.519 - queue example given in \secref{sec:intro}. The amortised
106.520 - representation is convenient for generating code but exposes its
106.521 - \qt{implementation} details, which may be cumbersome when proving
106.522 - theorems about it. Therefore, here a simple, straightforward
106.523 - representation of queues:%
106.524 -\end{isamarkuptext}%
106.525 -\isamarkuptrue%
106.526 -%
106.527 -\isadelimquote
106.528 -%
106.529 -\endisadelimquote
106.530 -%
106.531 -\isatagquote
106.532 -\isacommand{datatype}\isamarkupfalse%
106.533 -\ {\isacharprime}a\ queue\ {\isacharequal}\ Queue\ {\isachardoublequoteopen}{\isacharprime}a\ list{\isachardoublequoteclose}\isanewline
106.534 -\isanewline
106.535 -\isacommand{definition}\isamarkupfalse%
106.536 -\ empty\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharprime}a\ queue{\isachardoublequoteclose}\ \isakeyword{where}\isanewline
106.537 -\ \ {\isachardoublequoteopen}empty\ {\isacharequal}\ Queue\ {\isacharbrackleft}{\isacharbrackright}{\isachardoublequoteclose}\isanewline
106.538 -\isanewline
106.539 -\isacommand{primrec}\isamarkupfalse%
106.540 -\ enqueue\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharprime}a\ {\isasymRightarrow}\ {\isacharprime}a\ queue\ {\isasymRightarrow}\ {\isacharprime}a\ queue{\isachardoublequoteclose}\ \isakeyword{where}\isanewline
106.541 -\ \ {\isachardoublequoteopen}enqueue\ x\ {\isacharparenleft}Queue\ xs{\isacharparenright}\ {\isacharequal}\ Queue\ {\isacharparenleft}xs\ {\isacharat}\ {\isacharbrackleft}x{\isacharbrackright}{\isacharparenright}{\isachardoublequoteclose}\isanewline
106.542 -\isanewline
106.543 -\isacommand{fun}\isamarkupfalse%
106.544 -\ dequeue\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharprime}a\ queue\ {\isasymRightarrow}\ {\isacharprime}a\ option\ {\isasymtimes}\ {\isacharprime}a\ queue{\isachardoublequoteclose}\ \isakeyword{where}\isanewline
106.545 -\ \ \ \ {\isachardoublequoteopen}dequeue\ {\isacharparenleft}Queue\ {\isacharbrackleft}{\isacharbrackright}{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}None{\isacharcomma}\ Queue\ {\isacharbrackleft}{\isacharbrackright}{\isacharparenright}{\isachardoublequoteclose}\isanewline
106.546 -\ \ {\isacharbar}\ {\isachardoublequoteopen}dequeue\ {\isacharparenleft}Queue\ {\isacharparenleft}x\ {\isacharhash}\ xs{\isacharparenright}{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}Some\ x{\isacharcomma}\ Queue\ xs{\isacharparenright}{\isachardoublequoteclose}%
106.547 -\endisatagquote
106.548 -{\isafoldquote}%
106.549 -%
106.550 -\isadelimquote
106.551 -%
106.552 -\endisadelimquote
106.553 -%
106.554 -\begin{isamarkuptext}%
106.555 -\noindent This we can use directly for proving; for executing,
106.556 - we provide an alternative characterisation:%
106.557 -\end{isamarkuptext}%
106.558 -\isamarkuptrue%
106.559 -%
106.560 -\isadelimquote
106.561 -%
106.562 -\endisadelimquote
106.563 -%
106.564 -\isatagquote
106.565 -\isacommand{definition}\isamarkupfalse%
106.566 -\ AQueue\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharprime}a\ list\ {\isasymRightarrow}\ {\isacharprime}a\ list\ {\isasymRightarrow}\ {\isacharprime}a\ queue{\isachardoublequoteclose}\ \isakeyword{where}\isanewline
106.567 -\ \ {\isachardoublequoteopen}AQueue\ xs\ ys\ {\isacharequal}\ Queue\ {\isacharparenleft}ys\ {\isacharat}\ rev\ xs{\isacharparenright}{\isachardoublequoteclose}\isanewline
106.568 -\isanewline
106.569 -\isacommand{code{\isacharunderscore}datatype}\isamarkupfalse%
106.570 -\ AQueue%
106.571 -\endisatagquote
106.572 -{\isafoldquote}%
106.573 -%
106.574 -\isadelimquote
106.575 -%
106.576 -\endisadelimquote
106.577 -%
106.578 -\begin{isamarkuptext}%
106.579 -\noindent Here we define a \qt{constructor} \isa{Program{\isachardot}AQueue} which
106.580 - is defined in terms of \isa{Queue} and interprets its arguments
106.581 - according to what the \emph{content} of an amortised queue is supposed
106.582 - to be. Equipped with this, we are able to prove the following equations
106.583 - for our primitive queue operations which \qt{implement} the simple
106.584 - queues in an amortised fashion:%
106.585 -\end{isamarkuptext}%
106.586 -\isamarkuptrue%
106.587 -%
106.588 -\isadelimquote
106.589 -%
106.590 -\endisadelimquote
106.591 -%
106.592 -\isatagquote
106.593 -\isacommand{lemma}\isamarkupfalse%
106.594 -\ empty{\isacharunderscore}AQueue\ {\isacharbrackleft}code{\isacharbrackright}{\isacharcolon}\isanewline
106.595 -\ \ {\isachardoublequoteopen}empty\ {\isacharequal}\ AQueue\ {\isacharbrackleft}{\isacharbrackright}\ {\isacharbrackleft}{\isacharbrackright}{\isachardoublequoteclose}\isanewline
106.596 -\ \ \isacommand{unfolding}\isamarkupfalse%
106.597 -\ AQueue{\isacharunderscore}def\ empty{\isacharunderscore}def\ \isacommand{by}\isamarkupfalse%
106.598 -\ simp\isanewline
106.599 -\isanewline
106.600 -\isacommand{lemma}\isamarkupfalse%
106.601 -\ enqueue{\isacharunderscore}AQueue\ {\isacharbrackleft}code{\isacharbrackright}{\isacharcolon}\isanewline
106.602 -\ \ {\isachardoublequoteopen}enqueue\ x\ {\isacharparenleft}AQueue\ xs\ ys{\isacharparenright}\ {\isacharequal}\ AQueue\ {\isacharparenleft}x\ {\isacharhash}\ xs{\isacharparenright}\ ys{\isachardoublequoteclose}\isanewline
106.603 -\ \ \isacommand{unfolding}\isamarkupfalse%
106.604 -\ AQueue{\isacharunderscore}def\ \isacommand{by}\isamarkupfalse%
106.605 -\ simp\isanewline
106.606 -\isanewline
106.607 -\isacommand{lemma}\isamarkupfalse%
106.608 -\ dequeue{\isacharunderscore}AQueue\ {\isacharbrackleft}code{\isacharbrackright}{\isacharcolon}\isanewline
106.609 -\ \ {\isachardoublequoteopen}dequeue\ {\isacharparenleft}AQueue\ xs\ {\isacharbrackleft}{\isacharbrackright}{\isacharparenright}\ {\isacharequal}\isanewline
106.610 -\ \ \ \ {\isacharparenleft}if\ xs\ {\isacharequal}\ {\isacharbrackleft}{\isacharbrackright}\ then\ {\isacharparenleft}None{\isacharcomma}\ AQueue\ {\isacharbrackleft}{\isacharbrackright}\ {\isacharbrackleft}{\isacharbrackright}{\isacharparenright}\isanewline
106.611 -\ \ \ \ else\ dequeue\ {\isacharparenleft}AQueue\ {\isacharbrackleft}{\isacharbrackright}\ {\isacharparenleft}rev\ xs{\isacharparenright}{\isacharparenright}{\isacharparenright}{\isachardoublequoteclose}\isanewline
106.612 -\ \ {\isachardoublequoteopen}dequeue\ {\isacharparenleft}AQueue\ xs\ {\isacharparenleft}y\ {\isacharhash}\ ys{\isacharparenright}{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}Some\ y{\isacharcomma}\ AQueue\ xs\ ys{\isacharparenright}{\isachardoublequoteclose}\isanewline
106.613 -\ \ \isacommand{unfolding}\isamarkupfalse%
106.614 -\ AQueue{\isacharunderscore}def\ \isacommand{by}\isamarkupfalse%
106.615 -\ simp{\isacharunderscore}all%
106.616 -\endisatagquote
106.617 -{\isafoldquote}%
106.618 -%
106.619 -\isadelimquote
106.620 -%
106.621 -\endisadelimquote
106.622 -%
106.623 -\begin{isamarkuptext}%
106.624 -\noindent For completeness, we provide a substitute for the
106.625 - \isa{case} combinator on queues:%
106.626 -\end{isamarkuptext}%
106.627 -\isamarkuptrue%
106.628 -%
106.629 -\isadelimquote
106.630 -%
106.631 -\endisadelimquote
106.632 -%
106.633 -\isatagquote
106.634 -\isacommand{definition}\isamarkupfalse%
106.635 -\isanewline
106.636 -\ \ aqueue{\isacharunderscore}case{\isacharunderscore}def{\isacharcolon}\ {\isachardoublequoteopen}aqueue{\isacharunderscore}case\ {\isacharequal}\ queue{\isacharunderscore}case{\isachardoublequoteclose}\isanewline
106.637 -\isanewline
106.638 -\isacommand{lemma}\isamarkupfalse%
106.639 -\ aqueue{\isacharunderscore}case\ {\isacharbrackleft}code{\isacharcomma}\ code\ inline{\isacharbrackright}{\isacharcolon}\isanewline
106.640 -\ \ {\isachardoublequoteopen}queue{\isacharunderscore}case\ {\isacharequal}\ aqueue{\isacharunderscore}case{\isachardoublequoteclose}\isanewline
106.641 -\ \ \isacommand{unfolding}\isamarkupfalse%
106.642 -\ aqueue{\isacharunderscore}case{\isacharunderscore}def\ \isacommand{{\isachardot}{\isachardot}}\isamarkupfalse%
106.643 -\isanewline
106.644 -\isanewline
106.645 -\isacommand{lemma}\isamarkupfalse%
106.646 -\ case{\isacharunderscore}AQueue\ {\isacharbrackleft}code{\isacharbrackright}{\isacharcolon}\isanewline
106.647 -\ \ {\isachardoublequoteopen}aqueue{\isacharunderscore}case\ f\ {\isacharparenleft}AQueue\ xs\ ys{\isacharparenright}\ {\isacharequal}\ f\ {\isacharparenleft}ys\ {\isacharat}\ rev\ xs{\isacharparenright}{\isachardoublequoteclose}\isanewline
106.648 -\ \ \isacommand{unfolding}\isamarkupfalse%
106.649 -\ aqueue{\isacharunderscore}case{\isacharunderscore}def\ AQueue{\isacharunderscore}def\ \isacommand{by}\isamarkupfalse%
106.650 -\ simp%
106.651 -\endisatagquote
106.652 -{\isafoldquote}%
106.653 -%
106.654 -\isadelimquote
106.655 -%
106.656 -\endisadelimquote
106.657 -%
106.658 -\begin{isamarkuptext}%
106.659 -\noindent The resulting code looks as expected:%
106.660 -\end{isamarkuptext}%
106.661 -\isamarkuptrue%
106.662 -%
106.663 -\isadelimquote
106.664 -%
106.665 -\endisadelimquote
106.666 -%
106.667 -\isatagquote
106.668 -%
106.669 -\begin{isamarkuptext}%
106.670 -\isatypewriter%
106.671 -\noindent%
106.672 -\hspace*{0pt}structure Example = \\
106.673 -\hspace*{0pt}struct\\
106.674 -\hspace*{0pt}\\
106.675 -\hspace*{0pt}fun foldl f a [] = a\\
106.676 -\hspace*{0pt} ~| foldl f a (x ::~xs) = foldl f (f a x) xs;\\
106.677 -\hspace*{0pt}\\
106.678 -\hspace*{0pt}fun rev xs = foldl (fn xsa => fn x => x ::~xsa) [] xs;\\
106.679 -\hspace*{0pt}\\
106.680 -\hspace*{0pt}fun null [] = true\\
106.681 -\hspace*{0pt} ~| null (x ::~xs) = false;\\
106.682 -\hspace*{0pt}\\
106.683 -\hspace*{0pt}datatype 'a queue = AQueue of 'a list * 'a list;\\
106.684 -\hspace*{0pt}\\
106.685 -\hspace*{0pt}val empty :~'a queue = AQueue ([],~[])\\
106.686 -\hspace*{0pt}\\
106.687 -\hspace*{0pt}fun dequeue (AQueue (xs,~y ::~ys)) = (SOME y,~AQueue (xs,~ys))\\
106.688 -\hspace*{0pt} ~| dequeue (AQueue (xs,~[])) =\\
106.689 -\hspace*{0pt} ~~~(if null xs then (NONE,~AQueue ([],~[]))\\
106.690 -\hspace*{0pt} ~~~~~else dequeue (AQueue ([],~rev xs)));\\
106.691 -\hspace*{0pt}\\
106.692 -\hspace*{0pt}fun enqueue x (AQueue (xs,~ys)) = AQueue (x ::~xs,~ys);\\
106.693 -\hspace*{0pt}\\
106.694 -\hspace*{0pt}end;~(*struct Example*)%
106.695 -\end{isamarkuptext}%
106.696 -\isamarkuptrue%
106.697 -%
106.698 -\endisatagquote
106.699 -{\isafoldquote}%
106.700 -%
106.701 -\isadelimquote
106.702 -%
106.703 -\endisadelimquote
106.704 -%
106.705 -\begin{isamarkuptext}%
106.706 -\noindent From this example, it can be glimpsed that using own
106.707 - constructor sets is a little delicate since it changes the set of
106.708 - valid patterns for values of that type. Without going into much
106.709 - detail, here some practical hints:
106.710 -
106.711 - \begin{itemize}
106.712 -
106.713 - \item When changing the constructor set for datatypes, take care
106.714 - to provide an alternative for the \isa{case} combinator
106.715 - (e.g.~by replacing it using the preprocessor).
106.716 -
106.717 - \item Values in the target language need not to be normalised --
106.718 - different values in the target language may represent the same
106.719 - value in the logic.
106.720 -
106.721 - \item Usually, a good methodology to deal with the subtleties of
106.722 - pattern matching is to see the type as an abstract type: provide
106.723 - a set of operations which operate on the concrete representation
106.724 - of the type, and derive further operations by combinations of
106.725 - these primitive ones, without relying on a particular
106.726 - representation.
106.727 -
106.728 - \end{itemize}%
106.729 -\end{isamarkuptext}%
106.730 -\isamarkuptrue%
106.731 -%
106.732 -\isamarkupsubsection{Equality and wellsortedness%
106.733 -}
106.734 -\isamarkuptrue%
106.735 -%
106.736 -\begin{isamarkuptext}%
106.737 -Surely you have already noticed how equality is treated
106.738 - by the code generator:%
106.739 -\end{isamarkuptext}%
106.740 -\isamarkuptrue%
106.741 -%
106.742 -\isadelimquote
106.743 -%
106.744 -\endisadelimquote
106.745 -%
106.746 -\isatagquote
106.747 -\isacommand{primrec}\isamarkupfalse%
106.748 -\ collect{\isacharunderscore}duplicates\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharprime}a\ list\ {\isasymRightarrow}\ {\isacharprime}a\ list\ {\isasymRightarrow}\ {\isacharprime}a\ list\ {\isasymRightarrow}\ {\isacharprime}a\ list{\isachardoublequoteclose}\ \isakeyword{where}\isanewline
106.749 -\ \ {\isachardoublequoteopen}collect{\isacharunderscore}duplicates\ xs\ ys\ {\isacharbrackleft}{\isacharbrackright}\ {\isacharequal}\ xs{\isachardoublequoteclose}\isanewline
106.750 -\ \ {\isacharbar}\ {\isachardoublequoteopen}collect{\isacharunderscore}duplicates\ xs\ ys\ {\isacharparenleft}z{\isacharhash}zs{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}if\ z\ {\isasymin}\ set\ xs\isanewline
106.751 -\ \ \ \ \ \ then\ if\ z\ {\isasymin}\ set\ ys\isanewline
106.752 -\ \ \ \ \ \ \ \ then\ collect{\isacharunderscore}duplicates\ xs\ ys\ zs\isanewline
106.753 -\ \ \ \ \ \ \ \ else\ collect{\isacharunderscore}duplicates\ xs\ {\isacharparenleft}z{\isacharhash}ys{\isacharparenright}\ zs\isanewline
106.754 -\ \ \ \ \ \ else\ collect{\isacharunderscore}duplicates\ {\isacharparenleft}z{\isacharhash}xs{\isacharparenright}\ {\isacharparenleft}z{\isacharhash}ys{\isacharparenright}\ zs{\isacharparenright}{\isachardoublequoteclose}%
106.755 -\endisatagquote
106.756 -{\isafoldquote}%
106.757 -%
106.758 -\isadelimquote
106.759 -%
106.760 -\endisadelimquote
106.761 -%
106.762 -\begin{isamarkuptext}%
106.763 -\noindent The membership test during preprocessing is rewritten,
106.764 - resulting in \isa{op\ mem}, which itself
106.765 - performs an explicit equality check.%
106.766 -\end{isamarkuptext}%
106.767 -\isamarkuptrue%
106.768 -%
106.769 -\isadelimquote
106.770 -%
106.771 -\endisadelimquote
106.772 -%
106.773 -\isatagquote
106.774 -%
106.775 -\begin{isamarkuptext}%
106.776 -\isatypewriter%
106.777 -\noindent%
106.778 -\hspace*{0pt}structure Example = \\
106.779 -\hspace*{0pt}struct\\
106.780 -\hspace*{0pt}\\
106.781 -\hspace*{0pt}type 'a eq = {\char123}eq :~'a -> 'a -> bool{\char125};\\
106.782 -\hspace*{0pt}fun eq (A{\char95}:'a eq) = {\char35}eq A{\char95};\\
106.783 -\hspace*{0pt}\\
106.784 -\hspace*{0pt}fun eqop A{\char95}~a b = eq A{\char95}~a b;\\
106.785 -\hspace*{0pt}\\
106.786 -\hspace*{0pt}fun member A{\char95}~x [] = false\\
106.787 -\hspace*{0pt} ~| member A{\char95}~x (y ::~ys) = eqop A{\char95}~x y orelse member A{\char95}~x ys;\\
106.788 -\hspace*{0pt}\\
106.789 -\hspace*{0pt}fun collect{\char95}duplicates A{\char95}~xs ys [] = xs\\
106.790 -\hspace*{0pt} ~| collect{\char95}duplicates A{\char95}~xs ys (z ::~zs) =\\
106.791 -\hspace*{0pt} ~~~(if member A{\char95}~z xs\\
106.792 -\hspace*{0pt} ~~~~~then (if member A{\char95}~z ys then collect{\char95}duplicates A{\char95}~xs ys zs\\
106.793 -\hspace*{0pt} ~~~~~~~~~~~~else collect{\char95}duplicates A{\char95}~xs (z ::~ys) zs)\\
106.794 -\hspace*{0pt} ~~~~~else collect{\char95}duplicates A{\char95}~(z ::~xs) (z ::~ys) zs);\\
106.795 -\hspace*{0pt}\\
106.796 -\hspace*{0pt}end;~(*struct Example*)%
106.797 -\end{isamarkuptext}%
106.798 -\isamarkuptrue%
106.799 -%
106.800 -\endisatagquote
106.801 -{\isafoldquote}%
106.802 -%
106.803 -\isadelimquote
106.804 -%
106.805 -\endisadelimquote
106.806 -%
106.807 -\begin{isamarkuptext}%
106.808 -\noindent Obviously, polymorphic equality is implemented the Haskell
106.809 - way using a type class. How is this achieved? HOL introduces
106.810 - an explicit class \isa{eq} with a corresponding operation
106.811 - \isa{eq{\isacharunderscore}class{\isachardot}eq} such that \isa{eq{\isacharunderscore}class{\isachardot}eq\ {\isacharequal}\ op\ {\isacharequal}}.
106.812 - The preprocessing framework does the rest by propagating the
106.813 - \isa{eq} constraints through all dependent code equations.
106.814 - For datatypes, instances of \isa{eq} are implicitly derived
106.815 - when possible. For other types, you may instantiate \isa{eq}
106.816 - manually like any other type class.
106.817 -
106.818 - Though this \isa{eq} class is designed to get rarely in
106.819 - the way, a subtlety
106.820 - enters the stage when definitions of overloaded constants
106.821 - are dependent on operational equality. For example, let
106.822 - us define a lexicographic ordering on tuples
106.823 - (also see theory \hyperlink{theory.Product-ord}{\mbox{\isa{Product{\isacharunderscore}ord}}}):%
106.824 -\end{isamarkuptext}%
106.825 -\isamarkuptrue%
106.826 -%
106.827 -\isadelimquote
106.828 -%
106.829 -\endisadelimquote
106.830 -%
106.831 -\isatagquote
106.832 -\isacommand{instantiation}\isamarkupfalse%
106.833 -\ {\isachardoublequoteopen}{\isacharasterisk}{\isachardoublequoteclose}\ {\isacharcolon}{\isacharcolon}\ {\isacharparenleft}order{\isacharcomma}\ order{\isacharparenright}\ order\isanewline
106.834 -\isakeyword{begin}\isanewline
106.835 -\isanewline
106.836 -\isacommand{definition}\isamarkupfalse%
106.837 -\ {\isacharbrackleft}code\ del{\isacharbrackright}{\isacharcolon}\isanewline
106.838 -\ \ {\isachardoublequoteopen}x\ {\isasymle}\ y\ {\isasymlongleftrightarrow}\ fst\ x\ {\isacharless}\ fst\ y\ {\isasymor}\ fst\ x\ {\isacharequal}\ fst\ y\ {\isasymand}\ snd\ x\ {\isasymle}\ snd\ y{\isachardoublequoteclose}\isanewline
106.839 -\isanewline
106.840 -\isacommand{definition}\isamarkupfalse%
106.841 -\ {\isacharbrackleft}code\ del{\isacharbrackright}{\isacharcolon}\isanewline
106.842 -\ \ {\isachardoublequoteopen}x\ {\isacharless}\ y\ {\isasymlongleftrightarrow}\ fst\ x\ {\isacharless}\ fst\ y\ {\isasymor}\ fst\ x\ {\isacharequal}\ fst\ y\ {\isasymand}\ snd\ x\ {\isacharless}\ snd\ y{\isachardoublequoteclose}\isanewline
106.843 -\isanewline
106.844 -\isacommand{instance}\isamarkupfalse%
106.845 -\ \isacommand{proof}\isamarkupfalse%
106.846 -\isanewline
106.847 -\isacommand{qed}\isamarkupfalse%
106.848 -\ {\isacharparenleft}auto\ simp{\isacharcolon}\ less{\isacharunderscore}eq{\isacharunderscore}prod{\isacharunderscore}def\ less{\isacharunderscore}prod{\isacharunderscore}def\ intro{\isacharcolon}\ order{\isacharunderscore}less{\isacharunderscore}trans{\isacharparenright}\isanewline
106.849 -\isanewline
106.850 -\isacommand{end}\isamarkupfalse%
106.851 -\isanewline
106.852 -\isanewline
106.853 -\isacommand{lemma}\isamarkupfalse%
106.854 -\ order{\isacharunderscore}prod\ {\isacharbrackleft}code{\isacharbrackright}{\isacharcolon}\isanewline
106.855 -\ \ {\isachardoublequoteopen}{\isacharparenleft}x{\isadigit{1}}\ {\isasymColon}\ {\isacharprime}a{\isasymColon}order{\isacharcomma}\ y{\isadigit{1}}\ {\isasymColon}\ {\isacharprime}b{\isasymColon}order{\isacharparenright}\ {\isacharless}\ {\isacharparenleft}x{\isadigit{2}}{\isacharcomma}\ y{\isadigit{2}}{\isacharparenright}\ {\isasymlongleftrightarrow}\isanewline
106.856 -\ \ \ \ \ x{\isadigit{1}}\ {\isacharless}\ x{\isadigit{2}}\ {\isasymor}\ x{\isadigit{1}}\ {\isacharequal}\ x{\isadigit{2}}\ {\isasymand}\ y{\isadigit{1}}\ {\isacharless}\ y{\isadigit{2}}{\isachardoublequoteclose}\isanewline
106.857 -\ \ {\isachardoublequoteopen}{\isacharparenleft}x{\isadigit{1}}\ {\isasymColon}\ {\isacharprime}a{\isasymColon}order{\isacharcomma}\ y{\isadigit{1}}\ {\isasymColon}\ {\isacharprime}b{\isasymColon}order{\isacharparenright}\ {\isasymle}\ {\isacharparenleft}x{\isadigit{2}}{\isacharcomma}\ y{\isadigit{2}}{\isacharparenright}\ {\isasymlongleftrightarrow}\isanewline
106.858 -\ \ \ \ \ x{\isadigit{1}}\ {\isacharless}\ x{\isadigit{2}}\ {\isasymor}\ x{\isadigit{1}}\ {\isacharequal}\ x{\isadigit{2}}\ {\isasymand}\ y{\isadigit{1}}\ {\isasymle}\ y{\isadigit{2}}{\isachardoublequoteclose}\isanewline
106.859 -\ \ \isacommand{by}\isamarkupfalse%
106.860 -\ {\isacharparenleft}simp{\isacharunderscore}all\ add{\isacharcolon}\ less{\isacharunderscore}prod{\isacharunderscore}def\ less{\isacharunderscore}eq{\isacharunderscore}prod{\isacharunderscore}def{\isacharparenright}%
106.861 -\endisatagquote
106.862 -{\isafoldquote}%
106.863 -%
106.864 -\isadelimquote
106.865 -%
106.866 -\endisadelimquote
106.867 -%
106.868 -\begin{isamarkuptext}%
106.869 -\noindent Then code generation will fail. Why? The definition
106.870 - of \isa{op\ {\isasymle}} depends on equality on both arguments,
106.871 - which are polymorphic and impose an additional \isa{eq}
106.872 - class constraint, which the preprocessor does not propagate
106.873 - (for technical reasons).
106.874 -
106.875 - The solution is to add \isa{eq} explicitly to the first sort arguments in the
106.876 - code theorems:%
106.877 -\end{isamarkuptext}%
106.878 -\isamarkuptrue%
106.879 -%
106.880 -\isadelimquote
106.881 -%
106.882 -\endisadelimquote
106.883 -%
106.884 -\isatagquote
106.885 -\isacommand{lemma}\isamarkupfalse%
106.886 -\ order{\isacharunderscore}prod{\isacharunderscore}code\ {\isacharbrackleft}code{\isacharbrackright}{\isacharcolon}\isanewline
106.887 -\ \ {\isachardoublequoteopen}{\isacharparenleft}x{\isadigit{1}}\ {\isasymColon}\ {\isacharprime}a{\isasymColon}{\isacharbraceleft}order{\isacharcomma}\ eq{\isacharbraceright}{\isacharcomma}\ y{\isadigit{1}}\ {\isasymColon}\ {\isacharprime}b{\isasymColon}order{\isacharparenright}\ {\isacharless}\ {\isacharparenleft}x{\isadigit{2}}{\isacharcomma}\ y{\isadigit{2}}{\isacharparenright}\ {\isasymlongleftrightarrow}\isanewline
106.888 -\ \ \ \ \ x{\isadigit{1}}\ {\isacharless}\ x{\isadigit{2}}\ {\isasymor}\ x{\isadigit{1}}\ {\isacharequal}\ x{\isadigit{2}}\ {\isasymand}\ y{\isadigit{1}}\ {\isacharless}\ y{\isadigit{2}}{\isachardoublequoteclose}\isanewline
106.889 -\ \ {\isachardoublequoteopen}{\isacharparenleft}x{\isadigit{1}}\ {\isasymColon}\ {\isacharprime}a{\isasymColon}{\isacharbraceleft}order{\isacharcomma}\ eq{\isacharbraceright}{\isacharcomma}\ y{\isadigit{1}}\ {\isasymColon}\ {\isacharprime}b{\isasymColon}order{\isacharparenright}\ {\isasymle}\ {\isacharparenleft}x{\isadigit{2}}{\isacharcomma}\ y{\isadigit{2}}{\isacharparenright}\ {\isasymlongleftrightarrow}\isanewline
106.890 -\ \ \ \ \ x{\isadigit{1}}\ {\isacharless}\ x{\isadigit{2}}\ {\isasymor}\ x{\isadigit{1}}\ {\isacharequal}\ x{\isadigit{2}}\ {\isasymand}\ y{\isadigit{1}}\ {\isasymle}\ y{\isadigit{2}}{\isachardoublequoteclose}\isanewline
106.891 -\ \ \isacommand{by}\isamarkupfalse%
106.892 -\ {\isacharparenleft}simp{\isacharunderscore}all\ add{\isacharcolon}\ less{\isacharunderscore}prod{\isacharunderscore}def\ less{\isacharunderscore}eq{\isacharunderscore}prod{\isacharunderscore}def{\isacharparenright}%
106.893 -\endisatagquote
106.894 -{\isafoldquote}%
106.895 -%
106.896 -\isadelimquote
106.897 -%
106.898 -\endisadelimquote
106.899 -%
106.900 -\begin{isamarkuptext}%
106.901 -\noindent Then code generation succeeds:%
106.902 -\end{isamarkuptext}%
106.903 -\isamarkuptrue%
106.904 -%
106.905 -\isadelimquote
106.906 -%
106.907 -\endisadelimquote
106.908 -%
106.909 -\isatagquote
106.910 -%
106.911 -\begin{isamarkuptext}%
106.912 -\isatypewriter%
106.913 -\noindent%
106.914 -\hspace*{0pt}structure Example = \\
106.915 -\hspace*{0pt}struct\\
106.916 -\hspace*{0pt}\\
106.917 -\hspace*{0pt}type 'a eq = {\char123}eq :~'a -> 'a -> bool{\char125};\\
106.918 -\hspace*{0pt}fun eq (A{\char95}:'a eq) = {\char35}eq A{\char95};\\
106.919 -\hspace*{0pt}\\
106.920 -\hspace*{0pt}type 'a ord = {\char123}less{\char95}eq :~'a -> 'a -> bool,~less :~'a -> 'a -> bool{\char125};\\
106.921 -\hspace*{0pt}fun less{\char95}eq (A{\char95}:'a ord) = {\char35}less{\char95}eq A{\char95};\\
106.922 -\hspace*{0pt}fun less (A{\char95}:'a ord) = {\char35}less A{\char95};\\
106.923 -\hspace*{0pt}\\
106.924 -\hspace*{0pt}fun eqop A{\char95}~a b = eq A{\char95}~a b;\\
106.925 -\hspace*{0pt}\\
106.926 -\hspace*{0pt}type 'a preorder = {\char123}Orderings{\char95}{\char95}ord{\char95}preorder :~'a ord{\char125};\\
106.927 -\hspace*{0pt}fun ord{\char95}preorder (A{\char95}:'a preorder) = {\char35}Orderings{\char95}{\char95}ord{\char95}preorder A{\char95};\\
106.928 -\hspace*{0pt}\\
106.929 -\hspace*{0pt}type 'a order = {\char123}Orderings{\char95}{\char95}preorder{\char95}order :~'a preorder{\char125};\\
106.930 -\hspace*{0pt}fun preorder{\char95}order (A{\char95}:'a order) = {\char35}Orderings{\char95}{\char95}preorder{\char95}order A{\char95};\\
106.931 -\hspace*{0pt}\\
106.932 -\hspace*{0pt}fun less{\char95}eqa (A1{\char95},~A2{\char95}) B{\char95}~(x1,~y1) (x2,~y2) =\\
106.933 -\hspace*{0pt} ~less ((ord{\char95}preorder o preorder{\char95}order) A2{\char95}) x1 x2 orelse\\
106.934 -\hspace*{0pt} ~~~eqop A1{\char95}~x1 x2 andalso\\
106.935 -\hspace*{0pt} ~~~~~less{\char95}eq ((ord{\char95}preorder o preorder{\char95}order) B{\char95}) y1 y2\\
106.936 -\hspace*{0pt} ~| less{\char95}eqa (A1{\char95},~A2{\char95}) B{\char95}~(x1,~y1) (x2,~y2) =\\
106.937 -\hspace*{0pt} ~~~less ((ord{\char95}preorder o preorder{\char95}order) A2{\char95}) x1 x2 orelse\\
106.938 -\hspace*{0pt} ~~~~~eqop A1{\char95}~x1 x2 andalso\\
106.939 -\hspace*{0pt} ~~~~~~~less{\char95}eq ((ord{\char95}preorder o preorder{\char95}order) B{\char95}) y1 y2;\\
106.940 -\hspace*{0pt}\\
106.941 -\hspace*{0pt}end;~(*struct Example*)%
106.942 -\end{isamarkuptext}%
106.943 -\isamarkuptrue%
106.944 -%
106.945 -\endisatagquote
106.946 -{\isafoldquote}%
106.947 -%
106.948 -\isadelimquote
106.949 -%
106.950 -\endisadelimquote
106.951 -%
106.952 -\begin{isamarkuptext}%
106.953 -In some cases, the automatically derived code equations
106.954 - for equality on a particular type may not be appropriate.
106.955 - As example, watch the following datatype representing
106.956 - monomorphic parametric types (where type constructors
106.957 - are referred to by natural numbers):%
106.958 -\end{isamarkuptext}%
106.959 -\isamarkuptrue%
106.960 -%
106.961 -\isadelimquote
106.962 -%
106.963 -\endisadelimquote
106.964 -%
106.965 -\isatagquote
106.966 -\isacommand{datatype}\isamarkupfalse%
106.967 -\ monotype\ {\isacharequal}\ Mono\ nat\ {\isachardoublequoteopen}monotype\ list{\isachardoublequoteclose}%
106.968 -\endisatagquote
106.969 -{\isafoldquote}%
106.970 -%
106.971 -\isadelimquote
106.972 -%
106.973 -\endisadelimquote
106.974 -%
106.975 -\isadelimproof
106.976 -%
106.977 -\endisadelimproof
106.978 -%
106.979 -\isatagproof
106.980 -%
106.981 -\endisatagproof
106.982 -{\isafoldproof}%
106.983 -%
106.984 -\isadelimproof
106.985 -%
106.986 -\endisadelimproof
106.987 -%
106.988 -\begin{isamarkuptext}%
106.989 -\noindent Then code generation for SML would fail with a message
106.990 - that the generated code contains illegal mutual dependencies:
106.991 - the theorem \isa{eq{\isacharunderscore}class{\isachardot}eq\ {\isacharparenleft}Mono\ tyco{\isadigit{1}}\ typargs{\isadigit{1}}{\isacharparenright}\ {\isacharparenleft}Mono\ tyco{\isadigit{2}}\ typargs{\isadigit{2}}{\isacharparenright}\ {\isasymequiv}\ eq{\isacharunderscore}class{\isachardot}eq\ tyco{\isadigit{1}}\ tyco{\isadigit{2}}\ {\isasymand}\ eq{\isacharunderscore}class{\isachardot}eq\ typargs{\isadigit{1}}\ typargs{\isadigit{2}}} already requires the
106.992 - instance \isa{monotype\ {\isasymColon}\ eq}, which itself requires
106.993 - \isa{eq{\isacharunderscore}class{\isachardot}eq\ {\isacharparenleft}Mono\ tyco{\isadigit{1}}\ typargs{\isadigit{1}}{\isacharparenright}\ {\isacharparenleft}Mono\ tyco{\isadigit{2}}\ typargs{\isadigit{2}}{\isacharparenright}\ {\isasymequiv}\ eq{\isacharunderscore}class{\isachardot}eq\ tyco{\isadigit{1}}\ tyco{\isadigit{2}}\ {\isasymand}\ eq{\isacharunderscore}class{\isachardot}eq\ typargs{\isadigit{1}}\ typargs{\isadigit{2}}}; Haskell has no problem with mutually
106.994 - recursive \isa{instance} and \isa{function} definitions,
106.995 - but the SML serialiser does not support this.
106.996 -
106.997 - In such cases, you have to provide your own equality equations
106.998 - involving auxiliary constants. In our case,
106.999 - \isa{list{\isacharunderscore}all{\isadigit{2}}} can do the job:%
106.1000 -\end{isamarkuptext}%
106.1001 -\isamarkuptrue%
106.1002 -%
106.1003 -\isadelimquote
106.1004 -%
106.1005 -\endisadelimquote
106.1006 -%
106.1007 -\isatagquote
106.1008 -\isacommand{lemma}\isamarkupfalse%
106.1009 -\ monotype{\isacharunderscore}eq{\isacharunderscore}list{\isacharunderscore}all{\isadigit{2}}\ {\isacharbrackleft}code{\isacharbrackright}{\isacharcolon}\isanewline
106.1010 -\ \ {\isachardoublequoteopen}eq{\isacharunderscore}class{\isachardot}eq\ {\isacharparenleft}Mono\ tyco{\isadigit{1}}\ typargs{\isadigit{1}}{\isacharparenright}\ {\isacharparenleft}Mono\ tyco{\isadigit{2}}\ typargs{\isadigit{2}}{\isacharparenright}\ {\isasymlongleftrightarrow}\isanewline
106.1011 -\ \ \ \ \ eq{\isacharunderscore}class{\isachardot}eq\ tyco{\isadigit{1}}\ tyco{\isadigit{2}}\ {\isasymand}\ list{\isacharunderscore}all{\isadigit{2}}\ eq{\isacharunderscore}class{\isachardot}eq\ typargs{\isadigit{1}}\ typargs{\isadigit{2}}{\isachardoublequoteclose}\isanewline
106.1012 -\ \ \isacommand{by}\isamarkupfalse%
106.1013 -\ {\isacharparenleft}simp\ add{\isacharcolon}\ eq\ list{\isacharunderscore}all{\isadigit{2}}{\isacharunderscore}eq\ {\isacharbrackleft}symmetric{\isacharbrackright}{\isacharparenright}%
106.1014 -\endisatagquote
106.1015 -{\isafoldquote}%
106.1016 -%
106.1017 -\isadelimquote
106.1018 -%
106.1019 -\endisadelimquote
106.1020 -%
106.1021 -\begin{isamarkuptext}%
106.1022 -\noindent does not depend on instance \isa{monotype\ {\isasymColon}\ eq}:%
106.1023 -\end{isamarkuptext}%
106.1024 -\isamarkuptrue%
106.1025 -%
106.1026 -\isadelimquote
106.1027 -%
106.1028 -\endisadelimquote
106.1029 -%
106.1030 -\isatagquote
106.1031 -%
106.1032 -\begin{isamarkuptext}%
106.1033 -\isatypewriter%
106.1034 -\noindent%
106.1035 -\hspace*{0pt}structure Example = \\
106.1036 -\hspace*{0pt}struct\\
106.1037 -\hspace*{0pt}\\
106.1038 -\hspace*{0pt}datatype nat = Suc of nat | Zero{\char95}nat;\\
106.1039 -\hspace*{0pt}\\
106.1040 -\hspace*{0pt}fun null [] = true\\
106.1041 -\hspace*{0pt} ~| null (x ::~xs) = false;\\
106.1042 -\hspace*{0pt}\\
106.1043 -\hspace*{0pt}fun eq{\char95}nat (Suc a) Zero{\char95}nat = false\\
106.1044 -\hspace*{0pt} ~| eq{\char95}nat Zero{\char95}nat (Suc a) = false\\
106.1045 -\hspace*{0pt} ~| eq{\char95}nat (Suc nat) (Suc nat') = eq{\char95}nat nat nat'\\
106.1046 -\hspace*{0pt} ~| eq{\char95}nat Zero{\char95}nat Zero{\char95}nat = true;\\
106.1047 -\hspace*{0pt}\\
106.1048 -\hspace*{0pt}datatype monotype = Mono of nat * monotype list;\\
106.1049 -\hspace*{0pt}\\
106.1050 -\hspace*{0pt}fun list{\char95}all2 p (x ::~xs) (y ::~ys) = p x y andalso list{\char95}all2 p xs ys\\
106.1051 -\hspace*{0pt} ~| list{\char95}all2 p xs [] = null xs\\
106.1052 -\hspace*{0pt} ~| list{\char95}all2 p [] ys = null ys;\\
106.1053 -\hspace*{0pt}\\
106.1054 -\hspace*{0pt}fun eq{\char95}monotype (Mono (tyco1,~typargs1)) (Mono (tyco2,~typargs2)) =\\
106.1055 -\hspace*{0pt} ~eq{\char95}nat tyco1 tyco2 andalso list{\char95}all2 eq{\char95}monotype typargs1 typargs2;\\
106.1056 -\hspace*{0pt}\\
106.1057 -\hspace*{0pt}end;~(*struct Example*)%
106.1058 -\end{isamarkuptext}%
106.1059 -\isamarkuptrue%
106.1060 -%
106.1061 -\endisatagquote
106.1062 -{\isafoldquote}%
106.1063 -%
106.1064 -\isadelimquote
106.1065 -%
106.1066 -\endisadelimquote
106.1067 -%
106.1068 -\isamarkupsubsection{Explicit partiality%
106.1069 -}
106.1070 -\isamarkuptrue%
106.1071 -%
106.1072 -\begin{isamarkuptext}%
106.1073 -Partiality usually enters the game by partial patterns, as
106.1074 - in the following example, again for amortised queues:%
106.1075 -\end{isamarkuptext}%
106.1076 -\isamarkuptrue%
106.1077 -%
106.1078 -\isadelimquote
106.1079 -%
106.1080 -\endisadelimquote
106.1081 -%
106.1082 -\isatagquote
106.1083 -\isacommand{definition}\isamarkupfalse%
106.1084 -\ strict{\isacharunderscore}dequeue\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharprime}a\ queue\ {\isasymRightarrow}\ {\isacharprime}a\ {\isasymtimes}\ {\isacharprime}a\ queue{\isachardoublequoteclose}\ \isakeyword{where}\isanewline
106.1085 -\ \ {\isachardoublequoteopen}strict{\isacharunderscore}dequeue\ q\ {\isacharequal}\ {\isacharparenleft}case\ dequeue\ q\isanewline
106.1086 -\ \ \ \ of\ {\isacharparenleft}Some\ x{\isacharcomma}\ q{\isacharprime}{\isacharparenright}\ {\isasymRightarrow}\ {\isacharparenleft}x{\isacharcomma}\ q{\isacharprime}{\isacharparenright}{\isacharparenright}{\isachardoublequoteclose}\isanewline
106.1087 -\isanewline
106.1088 -\isacommand{lemma}\isamarkupfalse%
106.1089 -\ strict{\isacharunderscore}dequeue{\isacharunderscore}AQueue\ {\isacharbrackleft}code{\isacharbrackright}{\isacharcolon}\isanewline
106.1090 -\ \ {\isachardoublequoteopen}strict{\isacharunderscore}dequeue\ {\isacharparenleft}AQueue\ xs\ {\isacharparenleft}y\ {\isacharhash}\ ys{\isacharparenright}{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}y{\isacharcomma}\ AQueue\ xs\ ys{\isacharparenright}{\isachardoublequoteclose}\isanewline
106.1091 -\ \ {\isachardoublequoteopen}strict{\isacharunderscore}dequeue\ {\isacharparenleft}AQueue\ xs\ {\isacharbrackleft}{\isacharbrackright}{\isacharparenright}\ {\isacharequal}\isanewline
106.1092 -\ \ \ \ {\isacharparenleft}case\ rev\ xs\ of\ y\ {\isacharhash}\ ys\ {\isasymRightarrow}\ {\isacharparenleft}y{\isacharcomma}\ AQueue\ {\isacharbrackleft}{\isacharbrackright}\ ys{\isacharparenright}{\isacharparenright}{\isachardoublequoteclose}\isanewline
106.1093 -\ \ \isacommand{by}\isamarkupfalse%
106.1094 -\ {\isacharparenleft}simp{\isacharunderscore}all\ add{\isacharcolon}\ strict{\isacharunderscore}dequeue{\isacharunderscore}def\ dequeue{\isacharunderscore}AQueue\ split{\isacharcolon}\ list{\isachardot}splits{\isacharparenright}%
106.1095 -\endisatagquote
106.1096 -{\isafoldquote}%
106.1097 -%
106.1098 -\isadelimquote
106.1099 -%
106.1100 -\endisadelimquote
106.1101 -%
106.1102 -\begin{isamarkuptext}%
106.1103 -\noindent In the corresponding code, there is no equation
106.1104 - for the pattern \isa{Program{\isachardot}AQueue\ {\isacharbrackleft}{\isacharbrackright}\ {\isacharbrackleft}{\isacharbrackright}}:%
106.1105 -\end{isamarkuptext}%
106.1106 -\isamarkuptrue%
106.1107 -%
106.1108 -\isadelimquote
106.1109 -%
106.1110 -\endisadelimquote
106.1111 -%
106.1112 -\isatagquote
106.1113 -%
106.1114 -\begin{isamarkuptext}%
106.1115 -\isatypewriter%
106.1116 -\noindent%
106.1117 -\hspace*{0pt}strict{\char95}dequeue ::~forall a.~Queue a -> (a,~Queue a);\\
106.1118 -\hspace*{0pt}strict{\char95}dequeue (AQueue xs []) =\\
106.1119 -\hspace*{0pt} ~let {\char123}\\
106.1120 -\hspace*{0pt} ~~~(y :~ys) = rev xs;\\
106.1121 -\hspace*{0pt} ~{\char125}~in (y,~AQueue [] ys);\\
106.1122 -\hspace*{0pt}strict{\char95}dequeue (AQueue xs (y :~ys)) = (y,~AQueue xs ys);%
106.1123 -\end{isamarkuptext}%
106.1124 -\isamarkuptrue%
106.1125 -%
106.1126 -\endisatagquote
106.1127 -{\isafoldquote}%
106.1128 -%
106.1129 -\isadelimquote
106.1130 -%
106.1131 -\endisadelimquote
106.1132 -%
106.1133 -\begin{isamarkuptext}%
106.1134 -\noindent In some cases it is desirable to have this
106.1135 - pseudo-\qt{partiality} more explicitly, e.g.~as follows:%
106.1136 -\end{isamarkuptext}%
106.1137 -\isamarkuptrue%
106.1138 -%
106.1139 -\isadelimquote
106.1140 -%
106.1141 -\endisadelimquote
106.1142 -%
106.1143 -\isatagquote
106.1144 -\isacommand{axiomatization}\isamarkupfalse%
106.1145 -\ empty{\isacharunderscore}queue\ {\isacharcolon}{\isacharcolon}\ {\isacharprime}a\isanewline
106.1146 -\isanewline
106.1147 -\isacommand{definition}\isamarkupfalse%
106.1148 -\ strict{\isacharunderscore}dequeue{\isacharprime}\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharprime}a\ queue\ {\isasymRightarrow}\ {\isacharprime}a\ {\isasymtimes}\ {\isacharprime}a\ queue{\isachardoublequoteclose}\ \isakeyword{where}\isanewline
106.1149 -\ \ {\isachardoublequoteopen}strict{\isacharunderscore}dequeue{\isacharprime}\ q\ {\isacharequal}\ {\isacharparenleft}case\ dequeue\ q\ of\ {\isacharparenleft}Some\ x{\isacharcomma}\ q{\isacharprime}{\isacharparenright}\ {\isasymRightarrow}\ {\isacharparenleft}x{\isacharcomma}\ q{\isacharprime}{\isacharparenright}\ {\isacharbar}\ {\isacharunderscore}\ {\isasymRightarrow}\ empty{\isacharunderscore}queue{\isacharparenright}{\isachardoublequoteclose}\isanewline
106.1150 -\isanewline
106.1151 -\isacommand{lemma}\isamarkupfalse%
106.1152 -\ strict{\isacharunderscore}dequeue{\isacharprime}{\isacharunderscore}AQueue\ {\isacharbrackleft}code{\isacharbrackright}{\isacharcolon}\isanewline
106.1153 -\ \ {\isachardoublequoteopen}strict{\isacharunderscore}dequeue{\isacharprime}\ {\isacharparenleft}AQueue\ xs\ {\isacharbrackleft}{\isacharbrackright}{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}if\ xs\ {\isacharequal}\ {\isacharbrackleft}{\isacharbrackright}\ then\ empty{\isacharunderscore}queue\isanewline
106.1154 -\ \ \ \ \ else\ strict{\isacharunderscore}dequeue{\isacharprime}\ {\isacharparenleft}AQueue\ {\isacharbrackleft}{\isacharbrackright}\ {\isacharparenleft}rev\ xs{\isacharparenright}{\isacharparenright}{\isacharparenright}{\isachardoublequoteclose}\isanewline
106.1155 -\ \ {\isachardoublequoteopen}strict{\isacharunderscore}dequeue{\isacharprime}\ {\isacharparenleft}AQueue\ xs\ {\isacharparenleft}y\ {\isacharhash}\ ys{\isacharparenright}{\isacharparenright}\ {\isacharequal}\isanewline
106.1156 -\ \ \ \ \ {\isacharparenleft}y{\isacharcomma}\ AQueue\ xs\ ys{\isacharparenright}{\isachardoublequoteclose}\isanewline
106.1157 -\ \ \isacommand{by}\isamarkupfalse%
106.1158 -\ {\isacharparenleft}simp{\isacharunderscore}all\ add{\isacharcolon}\ strict{\isacharunderscore}dequeue{\isacharprime}{\isacharunderscore}def\ dequeue{\isacharunderscore}AQueue\ split{\isacharcolon}\ list{\isachardot}splits{\isacharparenright}%
106.1159 -\endisatagquote
106.1160 -{\isafoldquote}%
106.1161 -%
106.1162 -\isadelimquote
106.1163 -%
106.1164 -\endisadelimquote
106.1165 -%
106.1166 -\begin{isamarkuptext}%
106.1167 -Observe that on the right hand side of the definition of \isa{strict{\isacharunderscore}dequeue{\isacharprime}} the constant \isa{empty{\isacharunderscore}queue} occurs
106.1168 - which is unspecified.
106.1169 -
106.1170 - Normally, if constants without any code equations occur in a
106.1171 - program, the code generator complains (since in most cases this is
106.1172 - not what the user expects). But such constants can also be thought
106.1173 - of as function definitions with no equations which always fail,
106.1174 - since there is never a successful pattern match on the left hand
106.1175 - side. In order to categorise a constant into that category
106.1176 - explicitly, use \hyperlink{command.code-abort}{\mbox{\isa{\isacommand{code{\isacharunderscore}abort}}}}:%
106.1177 -\end{isamarkuptext}%
106.1178 -\isamarkuptrue%
106.1179 -%
106.1180 -\isadelimquote
106.1181 -%
106.1182 -\endisadelimquote
106.1183 -%
106.1184 -\isatagquote
106.1185 -\isacommand{code{\isacharunderscore}abort}\isamarkupfalse%
106.1186 -\ empty{\isacharunderscore}queue%
106.1187 -\endisatagquote
106.1188 -{\isafoldquote}%
106.1189 -%
106.1190 -\isadelimquote
106.1191 -%
106.1192 -\endisadelimquote
106.1193 -%
106.1194 -\begin{isamarkuptext}%
106.1195 -\noindent Then the code generator will just insert an error or
106.1196 - exception at the appropriate position:%
106.1197 -\end{isamarkuptext}%
106.1198 -\isamarkuptrue%
106.1199 -%
106.1200 -\isadelimquote
106.1201 -%
106.1202 -\endisadelimquote
106.1203 -%
106.1204 -\isatagquote
106.1205 -%
106.1206 -\begin{isamarkuptext}%
106.1207 -\isatypewriter%
106.1208 -\noindent%
106.1209 -\hspace*{0pt}empty{\char95}queue ::~forall a.~a;\\
106.1210 -\hspace*{0pt}empty{\char95}queue = error {\char34}empty{\char95}queue{\char34};\\
106.1211 -\hspace*{0pt}\\
106.1212 -\hspace*{0pt}strict{\char95}dequeue' ::~forall a.~Queue a -> (a,~Queue a);\\
106.1213 -\hspace*{0pt}strict{\char95}dequeue' (AQueue xs (y :~ys)) = (y,~AQueue xs ys);\\
106.1214 -\hspace*{0pt}strict{\char95}dequeue' (AQueue xs []) =\\
106.1215 -\hspace*{0pt} ~(if nulla xs then empty{\char95}queue\\
106.1216 -\hspace*{0pt} ~~~else strict{\char95}dequeue' (AQueue [] (rev xs)));%
106.1217 -\end{isamarkuptext}%
106.1218 -\isamarkuptrue%
106.1219 -%
106.1220 -\endisatagquote
106.1221 -{\isafoldquote}%
106.1222 -%
106.1223 -\isadelimquote
106.1224 -%
106.1225 -\endisadelimquote
106.1226 -%
106.1227 -\begin{isamarkuptext}%
106.1228 -\noindent This feature however is rarely needed in practice.
106.1229 - Note also that the \isa{HOL} default setup already declares
106.1230 - \isa{undefined} as \hyperlink{command.code-abort}{\mbox{\isa{\isacommand{code{\isacharunderscore}abort}}}}, which is most
106.1231 - likely to be used in such situations.%
106.1232 -\end{isamarkuptext}%
106.1233 -\isamarkuptrue%
106.1234 -%
106.1235 -\isadelimtheory
106.1236 -%
106.1237 -\endisadelimtheory
106.1238 -%
106.1239 -\isatagtheory
106.1240 -\isacommand{end}\isamarkupfalse%
106.1241 -%
106.1242 -\endisatagtheory
106.1243 -{\isafoldtheory}%
106.1244 -%
106.1245 -\isadelimtheory
106.1246 -%
106.1247 -\endisadelimtheory
106.1248 -\isanewline
106.1249 -\ \end{isabellebody}%
106.1250 -%%% Local Variables:
106.1251 -%%% mode: latex
106.1252 -%%% TeX-master: "root"
106.1253 -%%% End:
107.1 --- a/doc-src/IsarAdvanced/Codegen/Thy/examples/Codegen.hs Wed Mar 04 11:05:02 2009 +0100
107.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
107.3 @@ -1,23 +0,0 @@
107.4 -module Codegen where {
107.5 -
107.6 -import qualified Nat;
107.7 -
107.8 -class Null a where {
107.9 - nulla :: a;
107.10 -};
107.11 -
107.12 -heada :: forall a. (Codegen.Null a) => [a] -> a;
107.13 -heada (x : xs) = x;
107.14 -heada [] = Codegen.nulla;
107.15 -
107.16 -null_option :: forall a. Maybe a;
107.17 -null_option = Nothing;
107.18 -
107.19 -instance Codegen.Null (Maybe a) where {
107.20 - nulla = Codegen.null_option;
107.21 -};
107.22 -
107.23 -dummy :: Maybe Nat.Nat;
107.24 -dummy = Codegen.heada [Just (Nat.Suc Nat.Zero_nat), Nothing];
107.25 -
107.26 -}
108.1 --- a/doc-src/IsarAdvanced/Codegen/Thy/examples/Example.hs Wed Mar 04 11:05:02 2009 +0100
108.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
108.3 @@ -1,33 +0,0 @@
108.4 -{-# OPTIONS_GHC -fglasgow-exts #-}
108.5 -
108.6 -module Example where {
108.7 -
108.8 -
108.9 -foldla :: forall a b. (a -> b -> a) -> a -> [b] -> a;
108.10 -foldla f a [] = a;
108.11 -foldla f a (x : xs) = foldla f (f a x) xs;
108.12 -
108.13 -rev :: forall a. [a] -> [a];
108.14 -rev xs = foldla (\ xsa x -> x : xsa) [] xs;
108.15 -
108.16 -list_case :: forall t a. t -> (a -> [a] -> t) -> [a] -> t;
108.17 -list_case f1 f2 (a : list) = f2 a list;
108.18 -list_case f1 f2 [] = f1;
108.19 -
108.20 -data Queue a = AQueue [a] [a];
108.21 -
108.22 -empty :: forall a. Queue a;
108.23 -empty = AQueue [] [];
108.24 -
108.25 -dequeue :: forall a. Queue a -> (Maybe a, Queue a);
108.26 -dequeue (AQueue [] []) = (Nothing, AQueue [] []);
108.27 -dequeue (AQueue xs (y : ys)) = (Just y, AQueue xs ys);
108.28 -dequeue (AQueue (v : va) []) =
108.29 - let {
108.30 - (y : ys) = rev (v : va);
108.31 - } in (Just y, AQueue [] ys);
108.32 -
108.33 -enqueue :: forall a. a -> Queue a -> Queue a;
108.34 -enqueue x (AQueue xs ys) = AQueue (x : xs) ys;
108.35 -
108.36 -}
109.1 --- a/doc-src/IsarAdvanced/Codegen/Thy/examples/arbitrary.ML Wed Mar 04 11:05:02 2009 +0100
109.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
109.3 @@ -1,9 +0,0 @@
109.4 -structure Codegen =
109.5 -struct
109.6 -
109.7 -val arbitrary_option : 'a option = NONE;
109.8 -
109.9 -fun dummy_option [] = arbitrary_option
109.10 - | dummy_option (x :: xs) = SOME x;
109.11 -
109.12 -end; (*struct Codegen*)
110.1 --- a/doc-src/IsarAdvanced/Codegen/Thy/examples/bool_infix.ML Wed Mar 04 11:05:02 2009 +0100
110.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
110.3 @@ -1,19 +0,0 @@
110.4 -structure Nat =
110.5 -struct
110.6 -
110.7 -datatype nat = Suc of nat | Zero_nat;
110.8 -
110.9 -fun less_nat m (Suc n) = less_eq_nat m n
110.10 - | less_nat n Zero_nat = false
110.11 -and less_eq_nat (Suc m) n = less_nat m n
110.12 - | less_eq_nat Zero_nat n = true;
110.13 -
110.14 -end; (*struct Nat*)
110.15 -
110.16 -structure Codegen =
110.17 -struct
110.18 -
110.19 -fun in_interval (k, l) n =
110.20 - Nat.less_eq_nat k n andalso Nat.less_eq_nat n l;
110.21 -
110.22 -end; (*struct Codegen*)
111.1 --- a/doc-src/IsarAdvanced/Codegen/Thy/examples/bool_literal.ML Wed Mar 04 11:05:02 2009 +0100
111.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
111.3 @@ -1,31 +0,0 @@
111.4 -structure HOL =
111.5 -struct
111.6 -
111.7 -datatype boola = False | True;
111.8 -
111.9 -fun anda x True = x
111.10 - | anda x False = False
111.11 - | anda True x = x
111.12 - | anda False x = False;
111.13 -
111.14 -end; (*struct HOL*)
111.15 -
111.16 -structure Nat =
111.17 -struct
111.18 -
111.19 -datatype nat = Suc of nat | Zero_nat;
111.20 -
111.21 -fun less_nat m (Suc n) = less_eq_nat m n
111.22 - | less_nat n Zero_nat = HOL.False
111.23 -and less_eq_nat (Suc m) n = less_nat m n
111.24 - | less_eq_nat Zero_nat n = HOL.True;
111.25 -
111.26 -end; (*struct Nat*)
111.27 -
111.28 -structure Codegen =
111.29 -struct
111.30 -
111.31 -fun in_interval (k, l) n =
111.32 - HOL.anda (Nat.less_eq_nat k n) (Nat.less_eq_nat n l);
111.33 -
111.34 -end; (*struct Codegen*)
112.1 --- a/doc-src/IsarAdvanced/Codegen/Thy/examples/bool_mlbool.ML Wed Mar 04 11:05:02 2009 +0100
112.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
112.3 @@ -1,19 +0,0 @@
112.4 -structure Nat =
112.5 -struct
112.6 -
112.7 -datatype nat = Suc of nat | Zero_nat;
112.8 -
112.9 -fun less_nat m (Suc n) = less_eq_nat m n
112.10 - | less_nat n Zero_nat = false
112.11 -and less_eq_nat (Suc m) n = less_nat m n
112.12 - | less_eq_nat Zero_nat n = true;
112.13 -
112.14 -end; (*struct Nat*)
112.15 -
112.16 -structure Codegen =
112.17 -struct
112.18 -
112.19 -fun in_interval (k, l) n =
112.20 - (Nat.less_eq_nat k n) andalso (Nat.less_eq_nat n l);
112.21 -
112.22 -end; (*struct Codegen*)
113.1 --- a/doc-src/IsarAdvanced/Codegen/Thy/examples/class.ML Wed Mar 04 11:05:02 2009 +0100
113.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
113.3 @@ -1,24 +0,0 @@
113.4 -structure Nat =
113.5 -struct
113.6 -
113.7 -datatype nat = Suc of nat | Zero_nat;
113.8 -
113.9 -end; (*struct Nat*)
113.10 -
113.11 -structure Codegen =
113.12 -struct
113.13 -
113.14 -type 'a null = {null : 'a};
113.15 -fun null (A_:'a null) = #null A_;
113.16 -
113.17 -fun head A_ (x :: xs) = x
113.18 - | head A_ [] = null A_;
113.19 -
113.20 -val null_option : 'a option = NONE;
113.21 -
113.22 -fun null_optiona () = {null = null_option} : ('a option) null;
113.23 -
113.24 -val dummy : Nat.nat option =
113.25 - head (null_optiona ()) [SOME (Nat.Suc Nat.Zero_nat), NONE];
113.26 -
113.27 -end; (*struct Codegen*)
114.1 --- a/doc-src/IsarAdvanced/Codegen/Thy/examples/class.ocaml Wed Mar 04 11:05:02 2009 +0100
114.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
114.3 @@ -1,24 +0,0 @@
114.4 -module Nat =
114.5 -struct
114.6 -
114.7 -type nat = Suc of nat | Zero_nat;;
114.8 -
114.9 -end;; (*struct Nat*)
114.10 -
114.11 -module Codegen =
114.12 -struct
114.13 -
114.14 -type 'a null = {null : 'a};;
114.15 -let null _A = _A.null;;
114.16 -
114.17 -let rec head _A = function x :: xs -> x
114.18 - | [] -> null _A;;
114.19 -
114.20 -let rec null_option = None;;
114.21 -
114.22 -let null_optiona () = ({null = null_option} : ('a option) null);;
114.23 -
114.24 -let rec dummy
114.25 - = head (null_optiona ()) [Some (Nat.Suc Nat.Zero_nat); None];;
114.26 -
114.27 -end;; (*struct Codegen*)
115.1 --- a/doc-src/IsarAdvanced/Codegen/Thy/examples/collect_duplicates.ML Wed Mar 04 11:05:02 2009 +0100
115.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
115.3 @@ -1,30 +0,0 @@
115.4 -structure HOL =
115.5 -struct
115.6 -
115.7 -type 'a eq = {eq : 'a -> 'a -> bool};
115.8 -fun eq (A_:'a eq) = #eq A_;
115.9 -
115.10 -fun eqop A_ a = eq A_ a;
115.11 -
115.12 -end; (*struct HOL*)
115.13 -
115.14 -structure List =
115.15 -struct
115.16 -
115.17 -fun member A_ x (y :: ys) =
115.18 - (if HOL.eqop A_ y x then true else member A_ x ys)
115.19 - | member A_ x [] = false;
115.20 -
115.21 -end; (*struct List*)
115.22 -
115.23 -structure Codegen =
115.24 -struct
115.25 -
115.26 -fun collect_duplicates A_ xs ys (z :: zs) =
115.27 - (if List.member A_ z xs
115.28 - then (if List.member A_ z ys then collect_duplicates A_ xs ys zs
115.29 - else collect_duplicates A_ xs (z :: ys) zs)
115.30 - else collect_duplicates A_ (z :: xs) (z :: ys) zs)
115.31 - | collect_duplicates A_ xs ys [] = xs;
115.32 -
115.33 -end; (*struct Codegen*)
116.1 --- a/doc-src/IsarAdvanced/Codegen/Thy/examples/dirty_set.ML Wed Mar 04 11:05:02 2009 +0100
116.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
116.3 @@ -1,102 +0,0 @@
116.4 -structure ROOT =
116.5 -struct
116.6 -
116.7 -structure Nat =
116.8 -struct
116.9 -
116.10 -datatype nat = Zero_nat | Suc of nat;
116.11 -
116.12 -end; (*struct Nat*)
116.13 -
116.14 -structure Integer =
116.15 -struct
116.16 -
116.17 -datatype bit = B0 | B1;
116.18 -
116.19 -datatype int = Pls | Min | Bit of int * bit | Number_of_int of int;
116.20 -
116.21 -fun pred (Bit (k, B0)) = Bit (pred k, B1)
116.22 - | pred (Bit (k, B1)) = Bit (k, B0)
116.23 - | pred Min = Bit (Min, B0)
116.24 - | pred Pls = Min;
116.25 -
116.26 -fun uminus_int (Number_of_int w) = Number_of_int (uminus_int w)
116.27 - | uminus_int (Bit (k, B0)) = Bit (uminus_int k, B0)
116.28 - | uminus_int (Bit (k, B1)) = Bit (pred (uminus_int k), B1)
116.29 - | uminus_int Min = Bit (Pls, B1)
116.30 - | uminus_int Pls = Pls;
116.31 -
116.32 -fun succ (Bit (k, B0)) = Bit (k, B1)
116.33 - | succ (Bit (k, B1)) = Bit (succ k, B0)
116.34 - | succ Min = Pls
116.35 - | succ Pls = Bit (Pls, B1);
116.36 -
116.37 -fun plus_int (Number_of_int v) (Number_of_int w) =
116.38 - Number_of_int (plus_int v w)
116.39 - | plus_int k Min = pred k
116.40 - | plus_int k Pls = k
116.41 - | plus_int (Bit (k, B1)) (Bit (l, B1)) = Bit (plus_int k (succ l), B0)
116.42 - | plus_int (Bit (k, B1)) (Bit (l, B0)) = Bit (plus_int k l, B1)
116.43 - | plus_int (Bit (k, B0)) (Bit (l, b)) = Bit (plus_int k l, b)
116.44 - | plus_int Min k = pred k
116.45 - | plus_int Pls k = k;
116.46 -
116.47 -fun minus_int (Number_of_int v) (Number_of_int w) =
116.48 - Number_of_int (plus_int v (uminus_int w))
116.49 - | minus_int z w = plus_int z (uminus_int w);
116.50 -
116.51 -fun less_eq_int (Number_of_int k) (Number_of_int l) = less_eq_int k l
116.52 - | less_eq_int (Bit (k1, B1)) (Bit (k2, B0)) = less_int k1 k2
116.53 - | less_eq_int (Bit (k1, v)) (Bit (k2, B1)) = less_eq_int k1 k2
116.54 - | less_eq_int (Bit (k1, B0)) (Bit (k2, v)) = less_eq_int k1 k2
116.55 - | less_eq_int (Bit (k, v)) Min = less_eq_int k Min
116.56 - | less_eq_int (Bit (k, B1)) Pls = less_int k Pls
116.57 - | less_eq_int (Bit (k, B0)) Pls = less_eq_int k Pls
116.58 - | less_eq_int Min (Bit (k, B1)) = less_eq_int Min k
116.59 - | less_eq_int Min (Bit (k, B0)) = less_int Min k
116.60 - | less_eq_int Min Min = true
116.61 - | less_eq_int Min Pls = true
116.62 - | less_eq_int Pls (Bit (k, v)) = less_eq_int Pls k
116.63 - | less_eq_int Pls Min = false
116.64 - | less_eq_int Pls Pls = true
116.65 -and less_int (Number_of_int k) (Number_of_int l) = less_int k l
116.66 - | less_int (Bit (k1, B0)) (Bit (k2, B1)) = less_eq_int k1 k2
116.67 - | less_int (Bit (k1, B1)) (Bit (k2, v)) = less_int k1 k2
116.68 - | less_int (Bit (k1, v)) (Bit (k2, B0)) = less_int k1 k2
116.69 - | less_int (Bit (k, B1)) Min = less_int k Min
116.70 - | less_int (Bit (k, B0)) Min = less_eq_int k Min
116.71 - | less_int (Bit (k, v)) Pls = less_int k Pls
116.72 - | less_int Min (Bit (k, v)) = less_int Min k
116.73 - | less_int Min Min = false
116.74 - | less_int Min Pls = true
116.75 - | less_int Pls (Bit (k, B1)) = less_eq_int Pls k
116.76 - | less_int Pls (Bit (k, B0)) = less_int Pls k
116.77 - | less_int Pls Min = false
116.78 - | less_int Pls Pls = false;
116.79 -
116.80 -fun nat_aux n i =
116.81 - (if less_eq_int i (Number_of_int Pls) then n
116.82 - else nat_aux (Nat.Suc n)
116.83 - (minus_int i (Number_of_int (Bit (Pls, B1)))));
116.84 -
116.85 -fun nat i = nat_aux Nat.Zero_nat i;
116.86 -
116.87 -end; (*struct Integer*)
116.88 -
116.89 -structure Codegen =
116.90 -struct
116.91 -
116.92 -val dummy_set : (Nat.nat -> Nat.nat) list = Nat.Suc :: [];
116.93 -
116.94 -val foobar_set : Nat.nat list =
116.95 - Nat.Zero_nat ::
116.96 - (Nat.Suc Nat.Zero_nat ::
116.97 - (Integer.nat
116.98 - (Integer.Number_of_int
116.99 - (Integer.Bit
116.100 - (Integer.Bit (Integer.Pls, Integer.B1), Integer.B0)))
116.101 - :: []));
116.102 -
116.103 -end; (*struct Codegen*)
116.104 -
116.105 -end; (*struct ROOT*)
117.1 --- a/doc-src/IsarAdvanced/Codegen/Thy/examples/example.ML Wed Mar 04 11:05:02 2009 +0100
117.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
117.3 @@ -1,27 +0,0 @@
117.4 -structure Example =
117.5 -struct
117.6 -
117.7 -fun foldl f a [] = a
117.8 - | foldl f a (x :: xs) = foldl f (f a x) xs;
117.9 -
117.10 -fun rev xs = foldl (fn xsa => fn x => x :: xsa) [] xs;
117.11 -
117.12 -fun list_case f1 f2 (a :: lista) = f2 a lista
117.13 - | list_case f1 f2 [] = f1;
117.14 -
117.15 -datatype 'a queue = AQueue of 'a list * 'a list;
117.16 -
117.17 -val empty : 'a queue = AQueue ([], [])
117.18 -
117.19 -fun dequeue (AQueue ([], [])) = (NONE, AQueue ([], []))
117.20 - | dequeue (AQueue (xs, y :: ys)) = (SOME y, AQueue (xs, ys))
117.21 - | dequeue (AQueue (v :: va, [])) =
117.22 - let
117.23 - val y :: ys = rev (v :: va);
117.24 - in
117.25 - (SOME y, AQueue ([], ys))
117.26 - end;
117.27 -
117.28 -fun enqueue x (AQueue (xs, ys)) = AQueue (x :: xs, ys);
117.29 -
117.30 -end; (*struct Example*)
118.1 --- a/doc-src/IsarAdvanced/Codegen/Thy/examples/fac.ML Wed Mar 04 11:05:02 2009 +0100
118.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
118.3 @@ -1,22 +0,0 @@
118.4 -structure Nat =
118.5 -struct
118.6 -
118.7 -datatype nat = Suc of nat | Zero_nat;
118.8 -
118.9 -val one_nat : nat = Suc Zero_nat;
118.10 -
118.11 -fun plus_nat (Suc m) n = plus_nat m (Suc n)
118.12 - | plus_nat Zero_nat n = n;
118.13 -
118.14 -fun times_nat (Suc m) n = plus_nat n (times_nat m n)
118.15 - | times_nat Zero_nat n = Zero_nat;
118.16 -
118.17 -end; (*struct Nat*)
118.18 -
118.19 -structure Codegen =
118.20 -struct
118.21 -
118.22 -fun fac (Nat.Suc n) = Nat.times_nat (Nat.Suc n) (fac n)
118.23 - | fac Nat.Zero_nat = Nat.one_nat;
118.24 -
118.25 -end; (*struct Codegen*)
119.1 --- a/doc-src/IsarAdvanced/Codegen/Thy/examples/integers.ML Wed Mar 04 11:05:02 2009 +0100
119.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
119.3 @@ -1,59 +0,0 @@
119.4 -structure ROOT =
119.5 -struct
119.6 -
119.7 -structure Integer =
119.8 -struct
119.9 -
119.10 -datatype bit = B0 | B1;
119.11 -
119.12 -datatype int = Pls | Min | Bit of int * bit | Number_of_int of int;
119.13 -
119.14 -fun pred (Bit (k, B0)) = Bit (pred k, B1)
119.15 - | pred (Bit (k, B1)) = Bit (k, B0)
119.16 - | pred Min = Bit (Min, B0)
119.17 - | pred Pls = Min;
119.18 -
119.19 -fun succ (Bit (k, B0)) = Bit (k, B1)
119.20 - | succ (Bit (k, B1)) = Bit (succ k, B0)
119.21 - | succ Min = Pls
119.22 - | succ Pls = Bit (Pls, B1);
119.23 -
119.24 -fun plus_int (Number_of_int v) (Number_of_int w) =
119.25 - Number_of_int (plus_int v w)
119.26 - | plus_int k Min = pred k
119.27 - | plus_int k Pls = k
119.28 - | plus_int (Bit (k, B1)) (Bit (l, B1)) = Bit (plus_int k (succ l), B0)
119.29 - | plus_int (Bit (k, B1)) (Bit (l, B0)) = Bit (plus_int k l, B1)
119.30 - | plus_int (Bit (k, B0)) (Bit (l, b)) = Bit (plus_int k l, b)
119.31 - | plus_int Min k = pred k
119.32 - | plus_int Pls k = k;
119.33 -
119.34 -fun uminus_int (Number_of_int w) = Number_of_int (uminus_int w)
119.35 - | uminus_int (Bit (k, B0)) = Bit (uminus_int k, B0)
119.36 - | uminus_int (Bit (k, B1)) = Bit (pred (uminus_int k), B1)
119.37 - | uminus_int Min = Bit (Pls, B1)
119.38 - | uminus_int Pls = Pls;
119.39 -
119.40 -fun times_int (Number_of_int v) (Number_of_int w) =
119.41 - Number_of_int (times_int v w)
119.42 - | times_int (Bit (k, B0)) l = Bit (times_int k l, B0)
119.43 - | times_int (Bit (k, B1)) l = plus_int (Bit (times_int k l, B0)) l
119.44 - | times_int Min k = uminus_int k
119.45 - | times_int Pls w = Pls;
119.46 -
119.47 -end; (*struct Integer*)
119.48 -
119.49 -structure Codegen =
119.50 -struct
119.51 -
119.52 -fun double_inc k =
119.53 - Integer.plus_int
119.54 - (Integer.times_int
119.55 - (Integer.Number_of_int
119.56 - (Integer.Bit (Integer.Bit (Integer.Pls, Integer.B1), Integer.B0)))
119.57 - k)
119.58 - (Integer.Number_of_int (Integer.Bit (Integer.Pls, Integer.B1)));
119.59 -
119.60 -end; (*struct Codegen*)
119.61 -
119.62 -end; (*struct ROOT*)
120.1 --- a/doc-src/IsarAdvanced/Codegen/Thy/examples/lexicographic.ML Wed Mar 04 11:05:02 2009 +0100
120.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
120.3 @@ -1,19 +0,0 @@
120.4 -structure HOL =
120.5 -struct
120.6 -
120.7 -type 'a eq = {eq : 'a -> 'a -> bool};
120.8 -fun eq (A_:'a eq) = #eq A_;
120.9 -
120.10 -type 'a ord = {less_eq : 'a -> 'a -> bool, less : 'a -> 'a -> bool};
120.11 -fun less_eq (A_:'a ord) = #less_eq A_;
120.12 -fun less (A_:'a ord) = #less A_;
120.13 -
120.14 -end; (*struct HOL*)
120.15 -
120.16 -structure Codegen =
120.17 -struct
120.18 -
120.19 -fun less_eq (A1_, A2_) B_ (x1, y1) (x2, y2) =
120.20 - HOL.less A2_ x1 x2 orelse HOL.eq A1_ x1 x2 andalso HOL.less_eq B_ y1 y2;
120.21 -
120.22 -end; (*struct Codegen*)
121.1 --- a/doc-src/IsarAdvanced/Codegen/Thy/examples/lookup.ML Wed Mar 04 11:05:02 2009 +0100
121.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
121.3 @@ -1,13 +0,0 @@
121.4 -structure ROOT =
121.5 -struct
121.6 -
121.7 -structure Codegen =
121.8 -struct
121.9 -
121.10 -fun lookup ((k, v) :: xs) l =
121.11 - (if ((k : string) = l) then SOME v else lookup xs l)
121.12 - | lookup [] l = NONE;
121.13 -
121.14 -end; (*struct Codegen*)
121.15 -
121.16 -end; (*struct ROOT*)
122.1 --- a/doc-src/IsarAdvanced/Codegen/Thy/examples/monotype.ML Wed Mar 04 11:05:02 2009 +0100
122.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
122.3 @@ -1,34 +0,0 @@
122.4 -structure Nat =
122.5 -struct
122.6 -
122.7 -datatype nat = Suc of nat | Zero_nat;
122.8 -
122.9 -fun eq_nat (Suc a) Zero_nat = false
122.10 - | eq_nat Zero_nat (Suc a) = false
122.11 - | eq_nat (Suc nat) (Suc nat') = eq_nat nat nat'
122.12 - | eq_nat Zero_nat Zero_nat = true;
122.13 -
122.14 -end; (*struct Nat*)
122.15 -
122.16 -structure List =
122.17 -struct
122.18 -
122.19 -fun null (x :: xs) = false
122.20 - | null [] = true;
122.21 -
122.22 -fun list_all2 p (x :: xs) (y :: ys) = p x y andalso list_all2 p xs ys
122.23 - | list_all2 p xs [] = null xs
122.24 - | list_all2 p [] ys = null ys;
122.25 -
122.26 -end; (*struct List*)
122.27 -
122.28 -structure Codegen =
122.29 -struct
122.30 -
122.31 -datatype monotype = Mono of Nat.nat * monotype list;
122.32 -
122.33 -fun eq_monotype (Mono (tyco1, typargs1)) (Mono (tyco2, typargs2)) =
122.34 - Nat.eq_nat tyco1 tyco2 andalso
122.35 - List.list_all2 eq_monotype typargs1 typargs2;
122.36 -
122.37 -end; (*struct Codegen*)
123.1 --- a/doc-src/IsarAdvanced/Codegen/Thy/examples/nat_binary.ML Wed Mar 04 11:05:02 2009 +0100
123.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
123.3 @@ -1,17 +0,0 @@
123.4 -structure Nat =
123.5 -struct
123.6 -
123.7 -datatype nat = Dig1 of nat | Dig0 of nat | One_nat | Zero_nat;
123.8 -
123.9 -fun plus_nat (Dig1 m) (Dig1 n) = Dig0 (plus_nat (plus_nat m n) One_nat)
123.10 - | plus_nat (Dig1 m) (Dig0 n) = Dig1 (plus_nat m n)
123.11 - | plus_nat (Dig0 m) (Dig1 n) = Dig1 (plus_nat m n)
123.12 - | plus_nat (Dig0 m) (Dig0 n) = Dig0 (plus_nat m n)
123.13 - | plus_nat (Dig1 m) One_nat = Dig0 (plus_nat m One_nat)
123.14 - | plus_nat One_nat (Dig1 n) = Dig0 (plus_nat n One_nat)
123.15 - | plus_nat (Dig0 m) One_nat = Dig1 m
123.16 - | plus_nat One_nat (Dig0 n) = Dig1 n
123.17 - | plus_nat m Zero_nat = m
123.18 - | plus_nat Zero_nat n = n;
123.19 -
123.20 -end; (*struct Nat*)
124.1 --- a/doc-src/IsarAdvanced/Codegen/Thy/examples/pick1.ML Wed Mar 04 11:05:02 2009 +0100
124.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
124.3 @@ -1,44 +0,0 @@
124.4 -structure HOL =
124.5 -struct
124.6 -
124.7 -fun leta s f = f s;
124.8 -
124.9 -end; (*struct HOL*)
124.10 -
124.11 -structure Nat =
124.12 -struct
124.13 -
124.14 -datatype nat = Suc of nat | Zero_nat;
124.15 -
124.16 -fun less_nat m (Suc n) = less_eq_nat m n
124.17 - | less_nat n Zero_nat = false
124.18 -and less_eq_nat (Suc m) n = less_nat m n
124.19 - | less_eq_nat Zero_nat n = true;
124.20 -
124.21 -fun minus_nat (Suc m) (Suc n) = minus_nat m n
124.22 - | minus_nat Zero_nat n = Zero_nat
124.23 - | minus_nat m Zero_nat = m;
124.24 -
124.25 -end; (*struct Nat*)
124.26 -
124.27 -structure Product_Type =
124.28 -struct
124.29 -
124.30 -fun split f (a, b) = f a b;
124.31 -
124.32 -end; (*struct Product_Type*)
124.33 -
124.34 -structure Codegen =
124.35 -struct
124.36 -
124.37 -fun pick ((k, v) :: xs) n =
124.38 - (if Nat.less_nat n k then v else pick xs (Nat.minus_nat n k))
124.39 - | pick (x :: xs) n =
124.40 - let
124.41 - val a = x;
124.42 - val (k, v) = a;
124.43 - in
124.44 - (if Nat.less_nat n k then v else pick xs (Nat.minus_nat n k))
124.45 - end;
124.46 -
124.47 -end; (*struct Codegen*)
125.1 --- a/doc-src/IsarAdvanced/Codegen/Thy/examples/tree.ML Wed Mar 04 11:05:02 2009 +0100
125.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
125.3 @@ -1,95 +0,0 @@
125.4 -structure HOL =
125.5 -struct
125.6 -
125.7 -type 'a eq = {eq : 'a -> 'a -> bool};
125.8 -fun eq (A_:'a eq) = #eq A_;
125.9 -
125.10 -type 'a ord = {less_eq : 'a -> 'a -> bool, less : 'a -> 'a -> bool};
125.11 -fun less_eq (A_:'a ord) = #less_eq A_;
125.12 -fun less (A_:'a ord) = #less A_;
125.13 -
125.14 -fun eqop A_ a = eq A_ a;
125.15 -
125.16 -end; (*struct HOL*)
125.17 -
125.18 -structure Orderings =
125.19 -struct
125.20 -
125.21 -type 'a preorder = {Orderings__ord_preorder : 'a HOL.ord};
125.22 -fun ord_preorder (A_:'a preorder) = #Orderings__ord_preorder A_;
125.23 -
125.24 -type 'a order = {Orderings__preorder_order : 'a preorder};
125.25 -fun preorder_order (A_:'a order) = #Orderings__preorder_order A_;
125.26 -
125.27 -type 'a linorder = {Orderings__order_linorder : 'a order};
125.28 -fun order_linorder (A_:'a linorder) = #Orderings__order_linorder A_;
125.29 -
125.30 -end; (*struct Orderings*)
125.31 -
125.32 -structure Nat =
125.33 -struct
125.34 -
125.35 -datatype nat = Suc of nat | Zero_nat;
125.36 -
125.37 -fun eq_nat (Suc a) Zero_nat = false
125.38 - | eq_nat Zero_nat (Suc a) = false
125.39 - | eq_nat (Suc nat) (Suc nat') = eq_nat nat nat'
125.40 - | eq_nat Zero_nat Zero_nat = true;
125.41 -
125.42 -val eq_nata = {eq = eq_nat} : nat HOL.eq;
125.43 -
125.44 -fun less_nat m (Suc n) = less_eq_nat m n
125.45 - | less_nat n Zero_nat = false
125.46 -and less_eq_nat (Suc m) n = less_nat m n
125.47 - | less_eq_nat Zero_nat n = true;
125.48 -
125.49 -val ord_nat = {less_eq = less_eq_nat, less = less_nat} : nat HOL.ord;
125.50 -
125.51 -val preorder_nat = {Orderings__ord_preorder = ord_nat} :
125.52 - nat Orderings.preorder;
125.53 -
125.54 -val order_nat = {Orderings__preorder_order = preorder_nat} :
125.55 - nat Orderings.order;
125.56 -
125.57 -val linorder_nat = {Orderings__order_linorder = order_nat} :
125.58 - nat Orderings.linorder;
125.59 -
125.60 -end; (*struct Nat*)
125.61 -
125.62 -structure Codegen =
125.63 -struct
125.64 -
125.65 -datatype ('a, 'b) searchtree =
125.66 - Branch of ('a, 'b) searchtree * 'a * ('a, 'b) searchtree |
125.67 - Leaf of 'a * 'b;
125.68 -
125.69 -fun update (A1_, A2_) (it, entry) (Leaf (key, vala)) =
125.70 - (if HOL.eqop A1_ it key then Leaf (key, entry)
125.71 - else (if HOL.less_eq
125.72 - ((Orderings.ord_preorder o Orderings.preorder_order o
125.73 - Orderings.order_linorder)
125.74 - A2_)
125.75 - it key
125.76 - then Branch (Leaf (it, entry), it, Leaf (key, vala))
125.77 - else Branch (Leaf (key, vala), it, Leaf (it, entry))))
125.78 - | update (A1_, A2_) (it, entry) (Branch (t1, key, t2)) =
125.79 - (if HOL.less_eq
125.80 - ((Orderings.ord_preorder o Orderings.preorder_order o
125.81 - Orderings.order_linorder)
125.82 - A2_)
125.83 - it key
125.84 - then Branch (update (A1_, A2_) (it, entry) t1, key, t2)
125.85 - else Branch (t1, key, update (A1_, A2_) (it, entry) t2));
125.86 -
125.87 -val example : (Nat.nat, (Nat.nat list)) searchtree =
125.88 - update (Nat.eq_nata, Nat.linorder_nat)
125.89 - (Nat.Suc (Nat.Suc (Nat.Suc (Nat.Suc Nat.Zero_nat))),
125.90 - [Nat.Suc (Nat.Suc Nat.Zero_nat), Nat.Suc (Nat.Suc Nat.Zero_nat)])
125.91 - (update (Nat.eq_nata, Nat.linorder_nat)
125.92 - (Nat.Suc (Nat.Suc (Nat.Suc Nat.Zero_nat)),
125.93 - [Nat.Suc (Nat.Suc (Nat.Suc Nat.Zero_nat))])
125.94 - (update (Nat.eq_nata, Nat.linorder_nat)
125.95 - (Nat.Suc (Nat.Suc Nat.Zero_nat), [Nat.Suc (Nat.Suc Nat.Zero_nat)])
125.96 - (Leaf (Nat.Suc Nat.Zero_nat, []))));
125.97 -
125.98 -end; (*struct Codegen*)
126.1 --- a/doc-src/IsarAdvanced/Codegen/codegen.tex Wed Mar 04 11:05:02 2009 +0100
126.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
126.3 @@ -1,53 +0,0 @@
126.4 -
126.5 -\documentclass[12pt,a4paper,fleqn]{report}
126.6 -\usepackage{latexsym,graphicx}
126.7 -\usepackage[refpage]{nomencl}
126.8 -\usepackage{../../iman,../../extra,../../isar,../../proof}
126.9 -\usepackage{../../isabelle,../../isabellesym}
126.10 -\usepackage{style}
126.11 -\usepackage{pgf}
126.12 -\usepackage{pgflibraryshapes}
126.13 -\usepackage{tikz}
126.14 -\usepackage{../../pdfsetup}
126.15 -
126.16 -\hyphenation{Isabelle}
126.17 -\hyphenation{Isar}
126.18 -\isadroptag{theory}
126.19 -
126.20 -\title{\includegraphics[scale=0.5]{isabelle_isar}
126.21 - \\[4ex] Code generation from Isabelle/HOL theories}
126.22 -\author{\emph{Florian Haftmann}}
126.23 -
126.24 -\begin{document}
126.25 -
126.26 -\maketitle
126.27 -
126.28 -\begin{abstract}
126.29 - This tutorial gives an introduction to a generic code generator framework in Isabelle
126.30 - for generating executable code in functional programming languages from logical
126.31 - specifications in Isabelle/HOL.
126.32 -\end{abstract}
126.33 -
126.34 -\thispagestyle{empty}\clearpage
126.35 -
126.36 -\pagenumbering{roman}
126.37 -\clearfirst
126.38 -
126.39 -\input{Thy/document/Introduction.tex}
126.40 -\input{Thy/document/Program.tex}
126.41 -\input{Thy/document/Adaption.tex}
126.42 -\input{Thy/document/Further.tex}
126.43 -\input{Thy/document/ML.tex}
126.44 -
126.45 -\begingroup
126.46 -\bibliographystyle{plain} \small\raggedright\frenchspacing
126.47 -\bibliography{../../manual}
126.48 -\endgroup
126.49 -
126.50 -\end{document}
126.51 -
126.52 -
126.53 -%%% Local Variables:
126.54 -%%% mode: latex
126.55 -%%% TeX-master: t
126.56 -%%% End:
127.1 Binary file doc-src/IsarAdvanced/Codegen/codegen_process.pdf has changed
128.1 --- a/doc-src/IsarAdvanced/Codegen/codegen_process.ps Wed Mar 04 11:05:02 2009 +0100
128.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
128.3 @@ -1,586 +0,0 @@
128.4 -%!PS-Adobe-2.0
128.5 -%%Creator: dot version 2.2 (Mon Sep 12 23:33:36 UTC 2005)
128.6 -%%For: (haftmann) Florian Haftmann
128.7 -%%Title: _anonymous_0
128.8 -%%Pages: (atend)
128.9 -%%BoundingBox: 35 35 451 291
128.10 -%%EndComments
128.11 -save
128.12 -%%BeginProlog
128.13 -/DotDict 200 dict def
128.14 -DotDict begin
128.15 -
128.16 -/setupLatin1 {
128.17 -mark
128.18 -/EncodingVector 256 array def
128.19 - EncodingVector 0
128.20 -
128.21 -ISOLatin1Encoding 0 255 getinterval putinterval
128.22 -
128.23 -EncodingVector
128.24 - dup 306 /AE
128.25 - dup 301 /Aacute
128.26 - dup 302 /Acircumflex
128.27 - dup 304 /Adieresis
128.28 - dup 300 /Agrave
128.29 - dup 305 /Aring
128.30 - dup 303 /Atilde
128.31 - dup 307 /Ccedilla
128.32 - dup 311 /Eacute
128.33 - dup 312 /Ecircumflex
128.34 - dup 313 /Edieresis
128.35 - dup 310 /Egrave
128.36 - dup 315 /Iacute
128.37 - dup 316 /Icircumflex
128.38 - dup 317 /Idieresis
128.39 - dup 314 /Igrave
128.40 - dup 334 /Udieresis
128.41 - dup 335 /Yacute
128.42 - dup 376 /thorn
128.43 - dup 337 /germandbls
128.44 - dup 341 /aacute
128.45 - dup 342 /acircumflex
128.46 - dup 344 /adieresis
128.47 - dup 346 /ae
128.48 - dup 340 /agrave
128.49 - dup 345 /aring
128.50 - dup 347 /ccedilla
128.51 - dup 351 /eacute
128.52 - dup 352 /ecircumflex
128.53 - dup 353 /edieresis
128.54 - dup 350 /egrave
128.55 - dup 355 /iacute
128.56 - dup 356 /icircumflex
128.57 - dup 357 /idieresis
128.58 - dup 354 /igrave
128.59 - dup 360 /dcroat
128.60 - dup 361 /ntilde
128.61 - dup 363 /oacute
128.62 - dup 364 /ocircumflex
128.63 - dup 366 /odieresis
128.64 - dup 362 /ograve
128.65 - dup 365 /otilde
128.66 - dup 370 /oslash
128.67 - dup 372 /uacute
128.68 - dup 373 /ucircumflex
128.69 - dup 374 /udieresis
128.70 - dup 371 /ugrave
128.71 - dup 375 /yacute
128.72 - dup 377 /ydieresis
128.73 -
128.74 -% Set up ISO Latin 1 character encoding
128.75 -/starnetISO {
128.76 - dup dup findfont dup length dict begin
128.77 - { 1 index /FID ne { def }{ pop pop } ifelse
128.78 - } forall
128.79 - /Encoding EncodingVector def
128.80 - currentdict end definefont
128.81 -} def
128.82 -/Times-Roman starnetISO def
128.83 -/Times-Italic starnetISO def
128.84 -/Times-Bold starnetISO def
128.85 -/Times-BoldItalic starnetISO def
128.86 -/Helvetica starnetISO def
128.87 -/Helvetica-Oblique starnetISO def
128.88 -/Helvetica-Bold starnetISO def
128.89 -/Helvetica-BoldOblique starnetISO def
128.90 -/Courier starnetISO def
128.91 -/Courier-Oblique starnetISO def
128.92 -/Courier-Bold starnetISO def
128.93 -/Courier-BoldOblique starnetISO def
128.94 -cleartomark
128.95 -} bind def
128.96 -
128.97 -%%BeginResource: procset graphviz 0 0
128.98 -/coord-font-family /Times-Roman def
128.99 -/default-font-family /Times-Roman def
128.100 -/coordfont coord-font-family findfont 8 scalefont def
128.101 -
128.102 -/InvScaleFactor 1.0 def
128.103 -/set_scale {
128.104 - dup 1 exch div /InvScaleFactor exch def
128.105 - dup scale
128.106 -} bind def
128.107 -
128.108 -% styles
128.109 -/solid { [] 0 setdash } bind def
128.110 -/dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def
128.111 -/dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def
128.112 -/invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def
128.113 -/bold { 2 setlinewidth } bind def
128.114 -/filled { } bind def
128.115 -/unfilled { } bind def
128.116 -/rounded { } bind def
128.117 -/diagonals { } bind def
128.118 -
128.119 -% hooks for setting color
128.120 -/nodecolor { sethsbcolor } bind def
128.121 -/edgecolor { sethsbcolor } bind def
128.122 -/graphcolor { sethsbcolor } bind def
128.123 -/nopcolor {pop pop pop} bind def
128.124 -
128.125 -/beginpage { % i j npages
128.126 - /npages exch def
128.127 - /j exch def
128.128 - /i exch def
128.129 - /str 10 string def
128.130 - npages 1 gt {
128.131 - gsave
128.132 - coordfont setfont
128.133 - 0 0 moveto
128.134 - (\() show i str cvs show (,) show j str cvs show (\)) show
128.135 - grestore
128.136 - } if
128.137 -} bind def
128.138 -
128.139 -/set_font {
128.140 - findfont exch
128.141 - scalefont setfont
128.142 -} def
128.143 -
128.144 -% draw aligned label in bounding box aligned to current point
128.145 -/alignedtext { % width adj text
128.146 - /text exch def
128.147 - /adj exch def
128.148 - /width exch def
128.149 - gsave
128.150 - width 0 gt {
128.151 - text stringwidth pop adj mul 0 rmoveto
128.152 - } if
128.153 - [] 0 setdash
128.154 - text show
128.155 - grestore
128.156 -} def
128.157 -
128.158 -/boxprim { % xcorner ycorner xsize ysize
128.159 - 4 2 roll
128.160 - moveto
128.161 - 2 copy
128.162 - exch 0 rlineto
128.163 - 0 exch rlineto
128.164 - pop neg 0 rlineto
128.165 - closepath
128.166 -} bind def
128.167 -
128.168 -/ellipse_path {
128.169 - /ry exch def
128.170 - /rx exch def
128.171 - /y exch def
128.172 - /x exch def
128.173 - matrix currentmatrix
128.174 - newpath
128.175 - x y translate
128.176 - rx ry scale
128.177 - 0 0 1 0 360 arc
128.178 - setmatrix
128.179 -} bind def
128.180 -
128.181 -/endpage { showpage } bind def
128.182 -/showpage { } def
128.183 -
128.184 -/layercolorseq
128.185 - [ % layer color sequence - darkest to lightest
128.186 - [0 0 0]
128.187 - [.2 .8 .8]
128.188 - [.4 .8 .8]
128.189 - [.6 .8 .8]
128.190 - [.8 .8 .8]
128.191 - ]
128.192 -def
128.193 -
128.194 -/layerlen layercolorseq length def
128.195 -
128.196 -/setlayer {/maxlayer exch def /curlayer exch def
128.197 - layercolorseq curlayer 1 sub layerlen mod get
128.198 - aload pop sethsbcolor
128.199 - /nodecolor {nopcolor} def
128.200 - /edgecolor {nopcolor} def
128.201 - /graphcolor {nopcolor} def
128.202 -} bind def
128.203 -
128.204 -/onlayer { curlayer ne {invis} if } def
128.205 -
128.206 -/onlayers {
128.207 - /myupper exch def
128.208 - /mylower exch def
128.209 - curlayer mylower lt
128.210 - curlayer myupper gt
128.211 - or
128.212 - {invis} if
128.213 -} def
128.214 -
128.215 -/curlayer 0 def
128.216 -
128.217 -%%EndResource
128.218 -%%EndProlog
128.219 -%%BeginSetup
128.220 -14 default-font-family set_font
128.221 -1 setmiterlimit
128.222 -% /arrowlength 10 def
128.223 -% /arrowwidth 5 def
128.224 -
128.225 -% make sure pdfmark is harmless for PS-interpreters other than Distiller
128.226 -/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse
128.227 -% make '<<' and '>>' safe on PS Level 1 devices
128.228 -/languagelevel where {pop languagelevel}{1} ifelse
128.229 -2 lt {
128.230 - userdict (<<) cvn ([) cvn load put
128.231 - userdict (>>) cvn ([) cvn load put
128.232 -} if
128.233 -
128.234 -%%EndSetup
128.235 -%%Page: 1 1
128.236 -%%PageBoundingBox: 36 36 451 291
128.237 -%%PageOrientation: Portrait
128.238 -gsave
128.239 -35 35 416 256 boxprim clip newpath
128.240 -36 36 translate
128.241 -0 0 1 beginpage
128.242 -0 0 translate 0 rotate
128.243 -[ /CropBox [36 36 451 291] /PAGES pdfmark
128.244 -0.000 0.000 0.000 graphcolor
128.245 -14.00 /Times-Roman set_font
128.246 -
128.247 -% theory
128.248 -gsave 10 dict begin
128.249 -newpath 93 254 moveto
128.250 -1 254 lineto
128.251 -1 214 lineto
128.252 -93 214 lineto
128.253 -closepath
128.254 -stroke
128.255 -gsave 10 dict begin
128.256 -8 237 moveto
128.257 -(Isabelle/HOL)
128.258 -[4.56 5.52 6.24 6.96 6.24 3.84 3.84 6.24 3.84 10.08 10.08 8.64]
128.259 -xshow
128.260 -16 221 moveto
128.261 -(Isar theory)
128.262 -[4.56 5.52 6.24 4.56 3.6 4.08 6.96 6.24 6.96 4.8 6.96]
128.263 -xshow
128.264 -end grestore
128.265 -end grestore
128.266 -
128.267 -% selection
128.268 -gsave 10 dict begin
128.269 -183 234 38 18 ellipse_path
128.270 -stroke
128.271 -gsave 10 dict begin
128.272 -158 229 moveto
128.273 -(selection)
128.274 -[5.52 6.24 3.84 6.24 6.24 3.84 3.84 6.96 6.96]
128.275 -xshow
128.276 -end grestore
128.277 -end grestore
128.278 -
128.279 -% theory -> selection
128.280 -newpath 94 234 moveto
128.281 -107 234 121 234 135 234 curveto
128.282 -stroke
128.283 -gsave 10 dict begin
128.284 -solid
128.285 -1 setlinewidth
128.286 -0.000 0.000 0.000 edgecolor
128.287 -newpath 135 238 moveto
128.288 -145 234 lineto
128.289 -135 231 lineto
128.290 -closepath
128.291 -fill
128.292 -0.000 0.000 0.000 edgecolor
128.293 -newpath 135 238 moveto
128.294 -145 234 lineto
128.295 -135 231 lineto
128.296 -closepath
128.297 -stroke
128.298 -end grestore
128.299 -
128.300 -% sml
128.301 -gsave 10 dict begin
128.302 -newpath 74 144 moveto
128.303 -20 144 lineto
128.304 -20 108 lineto
128.305 -74 108 lineto
128.306 -closepath
128.307 -stroke
128.308 -gsave 10 dict begin
128.309 -32 121 moveto
128.310 -(SML)
128.311 -[7.68 12.48 8.64]
128.312 -xshow
128.313 -end grestore
128.314 -end grestore
128.315 -
128.316 -% other
128.317 -gsave 10 dict begin
128.318 -gsave 10 dict begin
128.319 -41 67 moveto
128.320 -(...)
128.321 -[3.6 3.6 3.6]
128.322 -xshow
128.323 -end grestore
128.324 -end grestore
128.325 -
128.326 -% haskell
128.327 -gsave 10 dict begin
128.328 -newpath 77 36 moveto
128.329 -17 36 lineto
128.330 -17 0 lineto
128.331 -77 0 lineto
128.332 -closepath
128.333 -stroke
128.334 -gsave 10 dict begin
128.335 -25 13 moveto
128.336 -(Haskell)
128.337 -[10.08 6.24 5.52 6.72 6.24 3.84 3.84]
128.338 -xshow
128.339 -end grestore
128.340 -end grestore
128.341 -
128.342 -% preprocessing
128.343 -gsave 10 dict begin
128.344 -183 180 52 18 ellipse_path
128.345 -stroke
128.346 -gsave 10 dict begin
128.347 -143 175 moveto
128.348 -(preprocessing)
128.349 -[6.96 4.56 6.24 6.96 4.56 6.96 6.24 6.24 5.52 5.52 3.84 6.96 6.96]
128.350 -xshow
128.351 -end grestore
128.352 -end grestore
128.353 -
128.354 -% selection -> preprocessing
128.355 -newpath 183 216 moveto
128.356 -183 213 183 211 183 208 curveto
128.357 -stroke
128.358 -gsave 10 dict begin
128.359 -solid
128.360 -1 setlinewidth
128.361 -0.000 0.000 0.000 edgecolor
128.362 -newpath 187 208 moveto
128.363 -183 198 lineto
128.364 -180 208 lineto
128.365 -closepath
128.366 -fill
128.367 -0.000 0.000 0.000 edgecolor
128.368 -newpath 187 208 moveto
128.369 -183 198 lineto
128.370 -180 208 lineto
128.371 -closepath
128.372 -stroke
128.373 -end grestore
128.374 -
128.375 -% def_eqn
128.376 -gsave 10 dict begin
128.377 -newpath 403 198 moveto
128.378 -283 198 lineto
128.379 -283 162 lineto
128.380 -403 162 lineto
128.381 -closepath
128.382 -stroke
128.383 -gsave 10 dict begin
128.384 -291 175 moveto
128.385 -(defining equations)
128.386 -[6.96 6.24 4.8 3.84 6.96 3.84 6.96 6.96 3.6 6.24 6.72 6.96 6.24 3.84 3.84 6.96 6.96 5.52]
128.387 -xshow
128.388 -end grestore
128.389 -end grestore
128.390 -
128.391 -% preprocessing -> def_eqn
128.392 -newpath 236 180 moveto
128.393 -248 180 260 180 273 180 curveto
128.394 -stroke
128.395 -gsave 10 dict begin
128.396 -solid
128.397 -1 setlinewidth
128.398 -0.000 0.000 0.000 edgecolor
128.399 -newpath 273 184 moveto
128.400 -283 180 lineto
128.401 -273 177 lineto
128.402 -closepath
128.403 -fill
128.404 -0.000 0.000 0.000 edgecolor
128.405 -newpath 273 184 moveto
128.406 -283 180 lineto
128.407 -273 177 lineto
128.408 -closepath
128.409 -stroke
128.410 -end grestore
128.411 -
128.412 -% serialization
128.413 -gsave 10 dict begin
128.414 -183 72 47 18 ellipse_path
128.415 -stroke
128.416 -gsave 10 dict begin
128.417 -148 67 moveto
128.418 -(serialization)
128.419 -[5.52 6.24 4.8 3.84 6.24 3.84 3.84 6.24 6.24 3.84 3.84 6.96 6.96]
128.420 -xshow
128.421 -end grestore
128.422 -end grestore
128.423 -
128.424 -% serialization -> sml
128.425 -newpath 150 85 moveto
128.426 -129 93 104 103 83 111 curveto
128.427 -stroke
128.428 -gsave 10 dict begin
128.429 -solid
128.430 -1 setlinewidth
128.431 -0.000 0.000 0.000 edgecolor
128.432 -newpath 82 108 moveto
128.433 -74 115 lineto
128.434 -85 114 lineto
128.435 -closepath
128.436 -fill
128.437 -0.000 0.000 0.000 edgecolor
128.438 -newpath 82 108 moveto
128.439 -74 115 lineto
128.440 -85 114 lineto
128.441 -closepath
128.442 -stroke
128.443 -end grestore
128.444 -
128.445 -% serialization -> other
128.446 -gsave 10 dict begin
128.447 -dotted
128.448 -newpath 135 72 moveto
128.449 -119 72 100 72 84 72 curveto
128.450 -stroke
128.451 -gsave 10 dict begin
128.452 -solid
128.453 -1 setlinewidth
128.454 -0.000 0.000 0.000 edgecolor
128.455 -newpath 84 69 moveto
128.456 -74 72 lineto
128.457 -84 76 lineto
128.458 -closepath
128.459 -fill
128.460 -0.000 0.000 0.000 edgecolor
128.461 -newpath 84 69 moveto
128.462 -74 72 lineto
128.463 -84 76 lineto
128.464 -closepath
128.465 -stroke
128.466 -end grestore
128.467 -end grestore
128.468 -
128.469 -% serialization -> haskell
128.470 -newpath 150 59 moveto
128.471 -131 51 107 42 86 34 curveto
128.472 -stroke
128.473 -gsave 10 dict begin
128.474 -solid
128.475 -1 setlinewidth
128.476 -0.000 0.000 0.000 edgecolor
128.477 -newpath 88 31 moveto
128.478 -77 30 lineto
128.479 -85 37 lineto
128.480 -closepath
128.481 -fill
128.482 -0.000 0.000 0.000 edgecolor
128.483 -newpath 88 31 moveto
128.484 -77 30 lineto
128.485 -85 37 lineto
128.486 -closepath
128.487 -stroke
128.488 -end grestore
128.489 -
128.490 -% translation
128.491 -gsave 10 dict begin
128.492 -343 126 43 18 ellipse_path
128.493 -stroke
128.494 -gsave 10 dict begin
128.495 -313 121 moveto
128.496 -(translation)
128.497 -[3.84 4.56 6.24 6.96 5.52 3.84 6.24 3.84 3.84 6.96 6.96]
128.498 -xshow
128.499 -end grestore
128.500 -end grestore
128.501 -
128.502 -% def_eqn -> translation
128.503 -newpath 343 162 moveto
128.504 -343 159 343 157 343 154 curveto
128.505 -stroke
128.506 -gsave 10 dict begin
128.507 -solid
128.508 -1 setlinewidth
128.509 -0.000 0.000 0.000 edgecolor
128.510 -newpath 347 154 moveto
128.511 -343 144 lineto
128.512 -340 154 lineto
128.513 -closepath
128.514 -fill
128.515 -0.000 0.000 0.000 edgecolor
128.516 -newpath 347 154 moveto
128.517 -343 144 lineto
128.518 -340 154 lineto
128.519 -closepath
128.520 -stroke
128.521 -end grestore
128.522 -
128.523 -% iml
128.524 -gsave 10 dict begin
128.525 -newpath 413 90 moveto
128.526 -273 90 lineto
128.527 -273 54 lineto
128.528 -413 54 lineto
128.529 -closepath
128.530 -stroke
128.531 -gsave 10 dict begin
128.532 -280 67 moveto
128.533 -(intermediate language)
128.534 -[3.84 6.96 3.84 6.24 4.8 10.8 6.24 6.96 3.84 6.24 3.84 6.24 3.6 3.84 6.24 6.96 6.96 6.96 6.24 6.72 6.24]
128.535 -xshow
128.536 -end grestore
128.537 -end grestore
128.538 -
128.539 -% translation -> iml
128.540 -newpath 343 108 moveto
128.541 -343 105 343 103 343 100 curveto
128.542 -stroke
128.543 -gsave 10 dict begin
128.544 -solid
128.545 -1 setlinewidth
128.546 -0.000 0.000 0.000 edgecolor
128.547 -newpath 347 100 moveto
128.548 -343 90 lineto
128.549 -340 100 lineto
128.550 -closepath
128.551 -fill
128.552 -0.000 0.000 0.000 edgecolor
128.553 -newpath 347 100 moveto
128.554 -343 90 lineto
128.555 -340 100 lineto
128.556 -closepath
128.557 -stroke
128.558 -end grestore
128.559 -
128.560 -% iml -> serialization
128.561 -newpath 272 72 moveto
128.562 -262 72 251 72 241 72 curveto
128.563 -stroke
128.564 -gsave 10 dict begin
128.565 -solid
128.566 -1 setlinewidth
128.567 -0.000 0.000 0.000 edgecolor
128.568 -newpath 241 69 moveto
128.569 -231 72 lineto
128.570 -241 76 lineto
128.571 -closepath
128.572 -fill
128.573 -0.000 0.000 0.000 edgecolor
128.574 -newpath 241 69 moveto
128.575 -231 72 lineto
128.576 -241 76 lineto
128.577 -closepath
128.578 -stroke
128.579 -end grestore
128.580 -endpage
128.581 -showpage
128.582 -grestore
128.583 -%%PageTrailer
128.584 -%%EndPage: 1
128.585 -%%Trailer
128.586 -%%Pages: 1
128.587 -end
128.588 -restore
128.589 -%%EOF
129.1 --- a/doc-src/IsarAdvanced/Codegen/style.sty Wed Mar 04 11:05:02 2009 +0100
129.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
129.3 @@ -1,62 +0,0 @@
129.4 -
129.5 -%% toc
129.6 -\newcommand{\tocentry}[1]{\cleardoublepage\phantomsection\addcontentsline{toc}{chapter}{#1}
129.7 -\@mkboth{\MakeUppercase{#1}}{\MakeUppercase{#1}}}
129.8 -
129.9 -%% references
129.10 -\newcommand{\secref}[1]{\S\ref{#1}}
129.11 -
129.12 -%% index
129.13 -\newcommand{\indexml}[1]{\index{\emph{#1}|bold}}
129.14 -\newcommand{\indexmltype}[1]{\index{\emph{#1} (type)|bold}}
129.15 -\newcommand{\indexmlstructure}[1]{\index{\emph{#1} (structure)|bold}}
129.16 -\newcommand{\indexmlfunctor}[1]{\index{\emph{#1} (functor)|bold}}
129.17 -
129.18 -%% logical markup
129.19 -\newcommand{\strong}[1]{{\bfseries {#1}}}
129.20 -\newcommand{\qn}[1]{\emph{#1}}
129.21 -
129.22 -%% typographic conventions
129.23 -\newcommand{\qt}[1]{``{#1}''}
129.24 -
129.25 -%% verbatim text
129.26 -\newcommand{\isatypewriter}{\fontsize{9pt}{0pt}\tt\renewcommand{\baselinestretch}{1}\setlength{\baselineskip}{9pt}}
129.27 -
129.28 -%% quoted segments
129.29 -\makeatletter
129.30 -\isakeeptag{quote}
129.31 -\newenvironment{quotesegment}{\begin{quote}\isa@parindent\parindent\parindent0pt\isa@parskip\parskip\parskip0pt}{\end{quote}}
129.32 -\renewcommand{\isatagquote}{\begin{quotesegment}}
129.33 -\renewcommand{\endisatagquote}{\end{quotesegment}}
129.34 -\makeatother
129.35 -
129.36 -\isakeeptag{quotett}
129.37 -\renewcommand{\isatagquotett}{\begin{quotesegment}\isabellestyle{tt}\isastyle}
129.38 -\renewcommand{\endisatagquotett}{\end{quotesegment}\isabellestyle{it}\isastyle}
129.39 -
129.40 -%% a trick
129.41 -\newcommand{\isasymSML}{SML}
129.42 -
129.43 -%% presentation
129.44 -\setcounter{secnumdepth}{2} \setcounter{tocdepth}{2}
129.45 -
129.46 -\pagestyle{headings}
129.47 -\binperiod
129.48 -\underscoreoff
129.49 -
129.50 -\renewcommand{\isadigit}[1]{\isamath{#1}}
129.51 -
129.52 -%% ml reference
129.53 -\newenvironment{mldecls}{\par\noindent\begingroup\footnotesize\def\isanewline{\\}\begin{tabular}{l}}{\end{tabular}\smallskip\endgroup}
129.54 -
129.55 -\isakeeptag{mlref}
129.56 -\renewcommand{\isatagmlref}{\subsection*{\makebox[0pt][r]{\fbox{\ML}~~}Reference}\begingroup\def\isastyletext{\rm}\small}
129.57 -\renewcommand{\endisatagmlref}{\endgroup}
129.58 -
129.59 -\isabellestyle{it}
129.60 -
129.61 -
129.62 -%%% Local Variables:
129.63 -%%% mode: latex
129.64 -%%% TeX-master: "implementation"
129.65 -%%% End:
130.1 --- a/doc-src/IsarAdvanced/Functions/IsaMakefile Wed Mar 04 11:05:02 2009 +0100
130.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
130.3 @@ -1,33 +0,0 @@
130.4 -
130.5 -## targets
130.6 -
130.7 -default: Thy
130.8 -images:
130.9 -test: Thy
130.10 -
130.11 -all: images test
130.12 -
130.13 -
130.14 -## global settings
130.15 -
130.16 -SRC = $(ISABELLE_HOME)/src
130.17 -OUT = $(ISABELLE_OUTPUT)
130.18 -LOG = $(OUT)/log
130.19 -
130.20 -USEDIR = $(ISABELLE_TOOL) usedir -v true -i false -d false -C false -D document
130.21 -
130.22 -
130.23 -## Thy
130.24 -
130.25 -THY = $(LOG)/HOL-Thy.gz
130.26 -
130.27 -Thy: $(THY)
130.28 -
130.29 -$(THY): Thy/ROOT.ML Thy/Functions.thy
130.30 - @$(USEDIR) HOL Thy
130.31 -
130.32 -
130.33 -## clean
130.34 -
130.35 -clean:
130.36 - @rm -f $(THY)
131.1 --- a/doc-src/IsarAdvanced/Functions/Makefile Wed Mar 04 11:05:02 2009 +0100
131.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
131.3 @@ -1,38 +0,0 @@
131.4 -#
131.5 -# $Id$
131.6 -#
131.7 -
131.8 -## targets
131.9 -
131.10 -default: dvi
131.11 -
131.12 -
131.13 -## dependencies
131.14 -
131.15 -include ../Makefile.in
131.16 -
131.17 -NAME = functions
131.18 -
131.19 -FILES = $(NAME).tex Thy/document/Functions.tex intro.tex conclusion.tex \
131.20 - style.sty ../../iman.sty ../../extra.sty ../../isar.sty \
131.21 - ../../isabelle.sty ../../isabellesym.sty ../../pdfsetup.sty \
131.22 - ../../manual.bib ../../proof.sty
131.23 -
131.24 -dvi: $(NAME).dvi
131.25 -
131.26 -$(NAME).dvi: $(FILES) isabelle_isar.eps
131.27 - $(LATEX) $(NAME)
131.28 - $(BIBTEX) $(NAME)
131.29 - $(LATEX) $(NAME)
131.30 - $(LATEX) $(NAME)
131.31 -
131.32 -pdf: $(NAME).pdf
131.33 -
131.34 -$(NAME).pdf: $(FILES) isabelle_isar.pdf
131.35 - $(PDFLATEX) $(NAME)
131.36 - $(BIBTEX) $(NAME)
131.37 - $(PDFLATEX) $(NAME)
131.38 - $(PDFLATEX) $(NAME)
131.39 - $(FIXBOOKMARKS) $(NAME).out
131.40 - $(PDFLATEX) $(NAME)
131.41 - $(PDFLATEX) $(NAME)
132.1 --- a/doc-src/IsarAdvanced/Functions/Thy/Functions.thy Wed Mar 04 11:05:02 2009 +0100
132.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
132.3 @@ -1,1264 +0,0 @@
132.4 -(* Title: doc-src/IsarAdvanced/Functions/Thy/Fundefs.thy
132.5 - Author: Alexander Krauss, TU Muenchen
132.6 -
132.7 -Tutorial for function definitions with the new "function" package.
132.8 -*)
132.9 -
132.10 -theory Functions
132.11 -imports Main
132.12 -begin
132.13 -
132.14 -section {* Function Definitions for Dummies *}
132.15 -
132.16 -text {*
132.17 - In most cases, defining a recursive function is just as simple as other definitions:
132.18 -*}
132.19 -
132.20 -fun fib :: "nat \<Rightarrow> nat"
132.21 -where
132.22 - "fib 0 = 1"
132.23 -| "fib (Suc 0) = 1"
132.24 -| "fib (Suc (Suc n)) = fib n + fib (Suc n)"
132.25 -
132.26 -text {*
132.27 - The syntax is rather self-explanatory: We introduce a function by
132.28 - giving its name, its type,
132.29 - and a set of defining recursive equations.
132.30 - If we leave out the type, the most general type will be
132.31 - inferred, which can sometimes lead to surprises: Since both @{term
132.32 - "1::nat"} and @{text "+"} are overloaded, we would end up
132.33 - with @{text "fib :: nat \<Rightarrow> 'a::{one,plus}"}.
132.34 -*}
132.35 -
132.36 -text {*
132.37 - The function always terminates, since its argument gets smaller in
132.38 - every recursive call.
132.39 - Since HOL is a logic of total functions, termination is a
132.40 - fundamental requirement to prevent inconsistencies\footnote{From the
132.41 - \qt{definition} @{text "f(n) = f(n) + 1"} we could prove
132.42 - @{text "0 = 1"} by subtracting @{text "f(n)"} on both sides.}.
132.43 - Isabelle tries to prove termination automatically when a definition
132.44 - is made. In \S\ref{termination}, we will look at cases where this
132.45 - fails and see what to do then.
132.46 -*}
132.47 -
132.48 -subsection {* Pattern matching *}
132.49 -
132.50 -text {* \label{patmatch}
132.51 - Like in functional programming, we can use pattern matching to
132.52 - define functions. At the moment we will only consider \emph{constructor
132.53 - patterns}, which only consist of datatype constructors and
132.54 - variables. Furthermore, patterns must be linear, i.e.\ all variables
132.55 - on the left hand side of an equation must be distinct. In
132.56 - \S\ref{genpats} we discuss more general pattern matching.
132.57 -
132.58 - If patterns overlap, the order of the equations is taken into
132.59 - account. The following function inserts a fixed element between any
132.60 - two elements of a list:
132.61 -*}
132.62 -
132.63 -fun sep :: "'a \<Rightarrow> 'a list \<Rightarrow> 'a list"
132.64 -where
132.65 - "sep a (x#y#xs) = x # a # sep a (y # xs)"
132.66 -| "sep a xs = xs"
132.67 -
132.68 -text {*
132.69 - Overlapping patterns are interpreted as \qt{increments} to what is
132.70 - already there: The second equation is only meant for the cases where
132.71 - the first one does not match. Consequently, Isabelle replaces it
132.72 - internally by the remaining cases, making the patterns disjoint:
132.73 -*}
132.74 -
132.75 -thm sep.simps
132.76 -
132.77 -text {* @{thm [display] sep.simps[no_vars]} *}
132.78 -
132.79 -text {*
132.80 - \noindent The equations from function definitions are automatically used in
132.81 - simplification:
132.82 -*}
132.83 -
132.84 -lemma "sep 0 [1, 2, 3] = [1, 0, 2, 0, 3]"
132.85 -by simp
132.86 -
132.87 -subsection {* Induction *}
132.88 -
132.89 -text {*
132.90 -
132.91 - Isabelle provides customized induction rules for recursive
132.92 - functions. These rules follow the recursive structure of the
132.93 - definition. Here is the rule @{text sep.induct} arising from the
132.94 - above definition of @{const sep}:
132.95 -
132.96 - @{thm [display] sep.induct}
132.97 -
132.98 - We have a step case for list with at least two elements, and two
132.99 - base cases for the zero- and the one-element list. Here is a simple
132.100 - proof about @{const sep} and @{const map}
132.101 -*}
132.102 -
132.103 -lemma "map f (sep x ys) = sep (f x) (map f ys)"
132.104 -apply (induct x ys rule: sep.induct)
132.105 -
132.106 -txt {*
132.107 - We get three cases, like in the definition.
132.108 -
132.109 - @{subgoals [display]}
132.110 -*}
132.111 -
132.112 -apply auto
132.113 -done
132.114 -text {*
132.115 -
132.116 - With the \cmd{fun} command, you can define about 80\% of the
132.117 - functions that occur in practice. The rest of this tutorial explains
132.118 - the remaining 20\%.
132.119 -*}
132.120 -
132.121 -
132.122 -section {* fun vs.\ function *}
132.123 -
132.124 -text {*
132.125 - The \cmd{fun} command provides a
132.126 - convenient shorthand notation for simple function definitions. In
132.127 - this mode, Isabelle tries to solve all the necessary proof obligations
132.128 - automatically. If any proof fails, the definition is
132.129 - rejected. This can either mean that the definition is indeed faulty,
132.130 - or that the default proof procedures are just not smart enough (or
132.131 - rather: not designed) to handle the definition.
132.132 -
132.133 - By expanding the abbreviation to the more verbose \cmd{function} command, these proof obligations become visible and can be analyzed or
132.134 - solved manually. The expansion from \cmd{fun} to \cmd{function} is as follows:
132.135 -
132.136 -\end{isamarkuptext}
132.137 -
132.138 -
132.139 -\[\left[\;\begin{minipage}{0.25\textwidth}\vspace{6pt}
132.140 -\cmd{fun} @{text "f :: \<tau>"}\\%
132.141 -\cmd{where}\\%
132.142 -\hspace*{2ex}{\it equations}\\%
132.143 -\hspace*{2ex}\vdots\vspace*{6pt}
132.144 -\end{minipage}\right]
132.145 -\quad\equiv\quad
132.146 -\left[\;\begin{minipage}{0.48\textwidth}\vspace{6pt}
132.147 -\cmd{function} @{text "("}\cmd{sequential}@{text ") f :: \<tau>"}\\%
132.148 -\cmd{where}\\%
132.149 -\hspace*{2ex}{\it equations}\\%
132.150 -\hspace*{2ex}\vdots\\%
132.151 -\cmd{by} @{text "pat_completeness auto"}\\%
132.152 -\cmd{termination by} @{text "lexicographic_order"}\vspace{6pt}
132.153 -\end{minipage}
132.154 -\right]\]
132.155 -
132.156 -\begin{isamarkuptext}
132.157 - \vspace*{1em}
132.158 - \noindent Some details have now become explicit:
132.159 -
132.160 - \begin{enumerate}
132.161 - \item The \cmd{sequential} option enables the preprocessing of
132.162 - pattern overlaps which we already saw. Without this option, the equations
132.163 - must already be disjoint and complete. The automatic completion only
132.164 - works with constructor patterns.
132.165 -
132.166 - \item A function definition produces a proof obligation which
132.167 - expresses completeness and compatibility of patterns (we talk about
132.168 - this later). The combination of the methods @{text "pat_completeness"} and
132.169 - @{text "auto"} is used to solve this proof obligation.
132.170 -
132.171 - \item A termination proof follows the definition, started by the
132.172 - \cmd{termination} command. This will be explained in \S\ref{termination}.
132.173 - \end{enumerate}
132.174 - Whenever a \cmd{fun} command fails, it is usually a good idea to
132.175 - expand the syntax to the more verbose \cmd{function} form, to see
132.176 - what is actually going on.
132.177 - *}
132.178 -
132.179 -
132.180 -section {* Termination *}
132.181 -
132.182 -text {*\label{termination}
132.183 - The method @{text "lexicographic_order"} is the default method for
132.184 - termination proofs. It can prove termination of a
132.185 - certain class of functions by searching for a suitable lexicographic
132.186 - combination of size measures. Of course, not all functions have such
132.187 - a simple termination argument. For them, we can specify the termination
132.188 - relation manually.
132.189 -*}
132.190 -
132.191 -subsection {* The {\tt relation} method *}
132.192 -text{*
132.193 - Consider the following function, which sums up natural numbers up to
132.194 - @{text "N"}, using a counter @{text "i"}:
132.195 -*}
132.196 -
132.197 -function sum :: "nat \<Rightarrow> nat \<Rightarrow> nat"
132.198 -where
132.199 - "sum i N = (if i > N then 0 else i + sum (Suc i) N)"
132.200 -by pat_completeness auto
132.201 -
132.202 -text {*
132.203 - \noindent The @{text "lexicographic_order"} method fails on this example, because none of the
132.204 - arguments decreases in the recursive call, with respect to the standard size ordering.
132.205 - To prove termination manually, we must provide a custom wellfounded relation.
132.206 -
132.207 - The termination argument for @{text "sum"} is based on the fact that
132.208 - the \emph{difference} between @{text "i"} and @{text "N"} gets
132.209 - smaller in every step, and that the recursion stops when @{text "i"}
132.210 - is greater than @{text "N"}. Phrased differently, the expression
132.211 - @{text "N + 1 - i"} always decreases.
132.212 -
132.213 - We can use this expression as a measure function suitable to prove termination.
132.214 -*}
132.215 -
132.216 -termination sum
132.217 -apply (relation "measure (\<lambda>(i,N). N + 1 - i)")
132.218 -
132.219 -txt {*
132.220 - The \cmd{termination} command sets up the termination goal for the
132.221 - specified function @{text "sum"}. If the function name is omitted, it
132.222 - implicitly refers to the last function definition.
132.223 -
132.224 - The @{text relation} method takes a relation of
132.225 - type @{typ "('a \<times> 'a) set"}, where @{typ "'a"} is the argument type of
132.226 - the function. If the function has multiple curried arguments, then
132.227 - these are packed together into a tuple, as it happened in the above
132.228 - example.
132.229 -
132.230 - The predefined function @{term[source] "measure :: ('a \<Rightarrow> nat) \<Rightarrow> ('a \<times> 'a) set"} constructs a
132.231 - wellfounded relation from a mapping into the natural numbers (a
132.232 - \emph{measure function}).
132.233 -
132.234 - After the invocation of @{text "relation"}, we must prove that (a)
132.235 - the relation we supplied is wellfounded, and (b) that the arguments
132.236 - of recursive calls indeed decrease with respect to the
132.237 - relation:
132.238 -
132.239 - @{subgoals[display,indent=0]}
132.240 -
132.241 - These goals are all solved by @{text "auto"}:
132.242 -*}
132.243 -
132.244 -apply auto
132.245 -done
132.246 -
132.247 -text {*
132.248 - Let us complicate the function a little, by adding some more
132.249 - recursive calls:
132.250 -*}
132.251 -
132.252 -function foo :: "nat \<Rightarrow> nat \<Rightarrow> nat"
132.253 -where
132.254 - "foo i N = (if i > N
132.255 - then (if N = 0 then 0 else foo 0 (N - 1))
132.256 - else i + foo (Suc i) N)"
132.257 -by pat_completeness auto
132.258 -
132.259 -text {*
132.260 - When @{text "i"} has reached @{text "N"}, it starts at zero again
132.261 - and @{text "N"} is decremented.
132.262 - This corresponds to a nested
132.263 - loop where one index counts up and the other down. Termination can
132.264 - be proved using a lexicographic combination of two measures, namely
132.265 - the value of @{text "N"} and the above difference. The @{const
132.266 - "measures"} combinator generalizes @{text "measure"} by taking a
132.267 - list of measure functions.
132.268 -*}
132.269 -
132.270 -termination
132.271 -by (relation "measures [\<lambda>(i, N). N, \<lambda>(i,N). N + 1 - i]") auto
132.272 -
132.273 -subsection {* How @{text "lexicographic_order"} works *}
132.274 -
132.275 -(*fun fails :: "nat \<Rightarrow> nat list \<Rightarrow> nat"
132.276 -where
132.277 - "fails a [] = a"
132.278 -| "fails a (x#xs) = fails (x + a) (x # xs)"
132.279 -*)
132.280 -
132.281 -text {*
132.282 - To see how the automatic termination proofs work, let's look at an
132.283 - example where it fails\footnote{For a detailed discussion of the
132.284 - termination prover, see \cite{bulwahnKN07}}:
132.285 -
132.286 -\end{isamarkuptext}
132.287 -\cmd{fun} @{text "fails :: \"nat \<Rightarrow> nat list \<Rightarrow> nat\""}\\%
132.288 -\cmd{where}\\%
132.289 -\hspace*{2ex}@{text "\"fails a [] = a\""}\\%
132.290 -|\hspace*{1.5ex}@{text "\"fails a (x#xs) = fails (x + a) (x#xs)\""}\\
132.291 -\begin{isamarkuptext}
132.292 -
132.293 -\noindent Isabelle responds with the following error:
132.294 -
132.295 -\begin{isabelle}
132.296 -*** Unfinished subgoals:\newline
132.297 -*** (a, 1, <):\newline
132.298 -*** \ 1.~@{text "\<And>x. x = 0"}\newline
132.299 -*** (a, 1, <=):\newline
132.300 -*** \ 1.~False\newline
132.301 -*** (a, 2, <):\newline
132.302 -*** \ 1.~False\newline
132.303 -*** Calls:\newline
132.304 -*** a) @{text "(a, x # xs) -->> (x + a, x # xs)"}\newline
132.305 -*** Measures:\newline
132.306 -*** 1) @{text "\<lambda>x. size (fst x)"}\newline
132.307 -*** 2) @{text "\<lambda>x. size (snd x)"}\newline
132.308 -*** Result matrix:\newline
132.309 -*** \ \ \ \ 1\ \ 2 \newline
132.310 -*** a: ? <= \newline
132.311 -*** Could not find lexicographic termination order.\newline
132.312 -*** At command "fun".\newline
132.313 -\end{isabelle}
132.314 -*}
132.315 -
132.316 -
132.317 -text {*
132.318 - The key to this error message is the matrix at the bottom. The rows
132.319 - of that matrix correspond to the different recursive calls (In our
132.320 - case, there is just one). The columns are the function's arguments
132.321 - (expressed through different measure functions, which map the
132.322 - argument tuple to a natural number).
132.323 -
132.324 - The contents of the matrix summarize what is known about argument
132.325 - descents: The second argument has a weak descent (@{text "<="}) at the
132.326 - recursive call, and for the first argument nothing could be proved,
132.327 - which is expressed by @{text "?"}. In general, there are the values
132.328 - @{text "<"}, @{text "<="} and @{text "?"}.
132.329 -
132.330 - For the failed proof attempts, the unfinished subgoals are also
132.331 - printed. Looking at these will often point to a missing lemma.
132.332 -
132.333 -% As a more real example, here is quicksort:
132.334 -*}
132.335 -(*
132.336 -function qs :: "nat list \<Rightarrow> nat list"
132.337 -where
132.338 - "qs [] = []"
132.339 -| "qs (x#xs) = qs [y\<in>xs. y < x] @ x # qs [y\<in>xs. y \<ge> x]"
132.340 -by pat_completeness auto
132.341 -
132.342 -termination apply lexicographic_order
132.343 -
132.344 -text {* If we try @{text "lexicographic_order"} method, we get the
132.345 - following error *}
132.346 -termination by (lexicographic_order simp:l2)
132.347 -
132.348 -lemma l: "x \<le> y \<Longrightarrow> x < Suc y" by arith
132.349 -
132.350 -function
132.351 -
132.352 -*)
132.353 -
132.354 -section {* Mutual Recursion *}
132.355 -
132.356 -text {*
132.357 - If two or more functions call one another mutually, they have to be defined
132.358 - in one step. Here are @{text "even"} and @{text "odd"}:
132.359 -*}
132.360 -
132.361 -function even :: "nat \<Rightarrow> bool"
132.362 - and odd :: "nat \<Rightarrow> bool"
132.363 -where
132.364 - "even 0 = True"
132.365 -| "odd 0 = False"
132.366 -| "even (Suc n) = odd n"
132.367 -| "odd (Suc n) = even n"
132.368 -by pat_completeness auto
132.369 -
132.370 -text {*
132.371 - To eliminate the mutual dependencies, Isabelle internally
132.372 - creates a single function operating on the sum
132.373 - type @{typ "nat + nat"}. Then, @{const even} and @{const odd} are
132.374 - defined as projections. Consequently, termination has to be proved
132.375 - simultaneously for both functions, by specifying a measure on the
132.376 - sum type:
132.377 -*}
132.378 -
132.379 -termination
132.380 -by (relation "measure (\<lambda>x. case x of Inl n \<Rightarrow> n | Inr n \<Rightarrow> n)") auto
132.381 -
132.382 -text {*
132.383 - We could also have used @{text lexicographic_order}, which
132.384 - supports mutual recursive termination proofs to a certain extent.
132.385 -*}
132.386 -
132.387 -subsection {* Induction for mutual recursion *}
132.388 -
132.389 -text {*
132.390 -
132.391 - When functions are mutually recursive, proving properties about them
132.392 - generally requires simultaneous induction. The induction rule @{text "even_odd.induct"}
132.393 - generated from the above definition reflects this.
132.394 -
132.395 - Let us prove something about @{const even} and @{const odd}:
132.396 -*}
132.397 -
132.398 -lemma even_odd_mod2:
132.399 - "even n = (n mod 2 = 0)"
132.400 - "odd n = (n mod 2 = 1)"
132.401 -
132.402 -txt {*
132.403 - We apply simultaneous induction, specifying the induction variable
132.404 - for both goals, separated by \cmd{and}: *}
132.405 -
132.406 -apply (induct n and n rule: even_odd.induct)
132.407 -
132.408 -txt {*
132.409 - We get four subgoals, which correspond to the clauses in the
132.410 - definition of @{const even} and @{const odd}:
132.411 - @{subgoals[display,indent=0]}
132.412 - Simplification solves the first two goals, leaving us with two
132.413 - statements about the @{text "mod"} operation to prove:
132.414 -*}
132.415 -
132.416 -apply simp_all
132.417 -
132.418 -txt {*
132.419 - @{subgoals[display,indent=0]}
132.420 -
132.421 - \noindent These can be handled by Isabelle's arithmetic decision procedures.
132.422 -
132.423 -*}
132.424 -
132.425 -apply arith
132.426 -apply arith
132.427 -done
132.428 -
132.429 -text {*
132.430 - In proofs like this, the simultaneous induction is really essential:
132.431 - Even if we are just interested in one of the results, the other
132.432 - one is necessary to strengthen the induction hypothesis. If we leave
132.433 - out the statement about @{const odd} and just write @{term True} instead,
132.434 - the same proof fails:
132.435 -*}
132.436 -
132.437 -lemma failed_attempt:
132.438 - "even n = (n mod 2 = 0)"
132.439 - "True"
132.440 -apply (induct n rule: even_odd.induct)
132.441 -
132.442 -txt {*
132.443 - \noindent Now the third subgoal is a dead end, since we have no
132.444 - useful induction hypothesis available:
132.445 -
132.446 - @{subgoals[display,indent=0]}
132.447 -*}
132.448 -
132.449 -oops
132.450 -
132.451 -section {* General pattern matching *}
132.452 -text{*\label{genpats} *}
132.453 -
132.454 -subsection {* Avoiding automatic pattern splitting *}
132.455 -
132.456 -text {*
132.457 -
132.458 - Up to now, we used pattern matching only on datatypes, and the
132.459 - patterns were always disjoint and complete, and if they weren't,
132.460 - they were made disjoint automatically like in the definition of
132.461 - @{const "sep"} in \S\ref{patmatch}.
132.462 -
132.463 - This automatic splitting can significantly increase the number of
132.464 - equations involved, and this is not always desirable. The following
132.465 - example shows the problem:
132.466 -
132.467 - Suppose we are modeling incomplete knowledge about the world by a
132.468 - three-valued datatype, which has values @{term "T"}, @{term "F"}
132.469 - and @{term "X"} for true, false and uncertain propositions, respectively.
132.470 -*}
132.471 -
132.472 -datatype P3 = T | F | X
132.473 -
132.474 -text {* \noindent Then the conjunction of such values can be defined as follows: *}
132.475 -
132.476 -fun And :: "P3 \<Rightarrow> P3 \<Rightarrow> P3"
132.477 -where
132.478 - "And T p = p"
132.479 -| "And p T = p"
132.480 -| "And p F = F"
132.481 -| "And F p = F"
132.482 -| "And X X = X"
132.483 -
132.484 -
132.485 -text {*
132.486 - This definition is useful, because the equations can directly be used
132.487 - as simplification rules. But the patterns overlap: For example,
132.488 - the expression @{term "And T T"} is matched by both the first and
132.489 - the second equation. By default, Isabelle makes the patterns disjoint by
132.490 - splitting them up, producing instances:
132.491 -*}
132.492 -
132.493 -thm And.simps
132.494 -
132.495 -text {*
132.496 - @{thm[indent=4] And.simps}
132.497 -
132.498 - \vspace*{1em}
132.499 - \noindent There are several problems with this:
132.500 -
132.501 - \begin{enumerate}
132.502 - \item If the datatype has many constructors, there can be an
132.503 - explosion of equations. For @{const "And"}, we get seven instead of
132.504 - five equations, which can be tolerated, but this is just a small
132.505 - example.
132.506 -
132.507 - \item Since splitting makes the equations \qt{less general}, they
132.508 - do not always match in rewriting. While the term @{term "And x F"}
132.509 - can be simplified to @{term "F"} with the original equations, a
132.510 - (manual) case split on @{term "x"} is now necessary.
132.511 -
132.512 - \item The splitting also concerns the induction rule @{text
132.513 - "And.induct"}. Instead of five premises it now has seven, which
132.514 - means that our induction proofs will have more cases.
132.515 -
132.516 - \item In general, it increases clarity if we get the same definition
132.517 - back which we put in.
132.518 - \end{enumerate}
132.519 -
132.520 - If we do not want the automatic splitting, we can switch it off by
132.521 - leaving out the \cmd{sequential} option. However, we will have to
132.522 - prove that our pattern matching is consistent\footnote{This prevents
132.523 - us from defining something like @{term "f x = True"} and @{term "f x
132.524 - = False"} simultaneously.}:
132.525 -*}
132.526 -
132.527 -function And2 :: "P3 \<Rightarrow> P3 \<Rightarrow> P3"
132.528 -where
132.529 - "And2 T p = p"
132.530 -| "And2 p T = p"
132.531 -| "And2 p F = F"
132.532 -| "And2 F p = F"
132.533 -| "And2 X X = X"
132.534 -
132.535 -txt {*
132.536 - \noindent Now let's look at the proof obligations generated by a
132.537 - function definition. In this case, they are:
132.538 -
132.539 - @{subgoals[display,indent=0]}\vspace{-1.2em}\hspace{3cm}\vdots\vspace{1.2em}
132.540 -
132.541 - The first subgoal expresses the completeness of the patterns. It has
132.542 - the form of an elimination rule and states that every @{term x} of
132.543 - the function's input type must match at least one of the patterns\footnote{Completeness could
132.544 - be equivalently stated as a disjunction of existential statements:
132.545 -@{term "(\<exists>p. x = (T, p)) \<or> (\<exists>p. x = (p, T)) \<or> (\<exists>p. x = (p, F)) \<or>
132.546 - (\<exists>p. x = (F, p)) \<or> (x = (X, X))"}, and you can use the method @{text atomize_elim} to get that form instead.}. If the patterns just involve
132.547 - datatypes, we can solve it with the @{text "pat_completeness"}
132.548 - method:
132.549 -*}
132.550 -
132.551 -apply pat_completeness
132.552 -
132.553 -txt {*
132.554 - The remaining subgoals express \emph{pattern compatibility}. We do
132.555 - allow that an input value matches multiple patterns, but in this
132.556 - case, the result (i.e.~the right hand sides of the equations) must
132.557 - also be equal. For each pair of two patterns, there is one such
132.558 - subgoal. Usually this needs injectivity of the constructors, which
132.559 - is used automatically by @{text "auto"}.
132.560 -*}
132.561 -
132.562 -by auto
132.563 -
132.564 -
132.565 -subsection {* Non-constructor patterns *}
132.566 -
132.567 -text {*
132.568 - Most of Isabelle's basic types take the form of inductive datatypes,
132.569 - and usually pattern matching works on the constructors of such types.
132.570 - However, this need not be always the case, and the \cmd{function}
132.571 - command handles other kind of patterns, too.
132.572 -
132.573 - One well-known instance of non-constructor patterns are
132.574 - so-called \emph{$n+k$-patterns}, which are a little controversial in
132.575 - the functional programming world. Here is the initial fibonacci
132.576 - example with $n+k$-patterns:
132.577 -*}
132.578 -
132.579 -function fib2 :: "nat \<Rightarrow> nat"
132.580 -where
132.581 - "fib2 0 = 1"
132.582 -| "fib2 1 = 1"
132.583 -| "fib2 (n + 2) = fib2 n + fib2 (Suc n)"
132.584 -
132.585 -(*<*)ML_val "goals_limit := 1"(*>*)
132.586 -txt {*
132.587 - This kind of matching is again justified by the proof of pattern
132.588 - completeness and compatibility.
132.589 - The proof obligation for pattern completeness states that every natural number is
132.590 - either @{term "0::nat"}, @{term "1::nat"} or @{term "n +
132.591 - (2::nat)"}:
132.592 -
132.593 - @{subgoals[display,indent=0]}
132.594 -
132.595 - This is an arithmetic triviality, but unfortunately the
132.596 - @{text arith} method cannot handle this specific form of an
132.597 - elimination rule. However, we can use the method @{text
132.598 - "atomize_elim"} to do an ad-hoc conversion to a disjunction of
132.599 - existentials, which can then be solved by the arithmetic decision procedure.
132.600 - Pattern compatibility and termination are automatic as usual.
132.601 -*}
132.602 -(*<*)ML_val "goals_limit := 10"(*>*)
132.603 -apply atomize_elim
132.604 -apply arith
132.605 -apply auto
132.606 -done
132.607 -termination by lexicographic_order
132.608 -text {*
132.609 - We can stretch the notion of pattern matching even more. The
132.610 - following function is not a sensible functional program, but a
132.611 - perfectly valid mathematical definition:
132.612 -*}
132.613 -
132.614 -function ev :: "nat \<Rightarrow> bool"
132.615 -where
132.616 - "ev (2 * n) = True"
132.617 -| "ev (2 * n + 1) = False"
132.618 -apply atomize_elim
132.619 -by arith+
132.620 -termination by (relation "{}") simp
132.621 -
132.622 -text {*
132.623 - This general notion of pattern matching gives you a certain freedom
132.624 - in writing down specifications. However, as always, such freedom should
132.625 - be used with care:
132.626 -
132.627 - If we leave the area of constructor
132.628 - patterns, we have effectively departed from the world of functional
132.629 - programming. This means that it is no longer possible to use the
132.630 - code generator, and expect it to generate ML code for our
132.631 - definitions. Also, such a specification might not work very well together with
132.632 - simplification. Your mileage may vary.
132.633 -*}
132.634 -
132.635 -
132.636 -subsection {* Conditional equations *}
132.637 -
132.638 -text {*
132.639 - The function package also supports conditional equations, which are
132.640 - similar to guards in a language like Haskell. Here is Euclid's
132.641 - algorithm written with conditional patterns\footnote{Note that the
132.642 - patterns are also overlapping in the base case}:
132.643 -*}
132.644 -
132.645 -function gcd :: "nat \<Rightarrow> nat \<Rightarrow> nat"
132.646 -where
132.647 - "gcd x 0 = x"
132.648 -| "gcd 0 y = y"
132.649 -| "x < y \<Longrightarrow> gcd (Suc x) (Suc y) = gcd (Suc x) (y - x)"
132.650 -| "\<not> x < y \<Longrightarrow> gcd (Suc x) (Suc y) = gcd (x - y) (Suc y)"
132.651 -by (atomize_elim, auto, arith)
132.652 -termination by lexicographic_order
132.653 -
132.654 -text {*
132.655 - By now, you can probably guess what the proof obligations for the
132.656 - pattern completeness and compatibility look like.
132.657 -
132.658 - Again, functions with conditional patterns are not supported by the
132.659 - code generator.
132.660 -*}
132.661 -
132.662 -
132.663 -subsection {* Pattern matching on strings *}
132.664 -
132.665 -text {*
132.666 - As strings (as lists of characters) are normal datatypes, pattern
132.667 - matching on them is possible, but somewhat problematic. Consider the
132.668 - following definition:
132.669 -
132.670 -\end{isamarkuptext}
132.671 -\noindent\cmd{fun} @{text "check :: \"string \<Rightarrow> bool\""}\\%
132.672 -\cmd{where}\\%
132.673 -\hspace*{2ex}@{text "\"check (''good'') = True\""}\\%
132.674 -@{text "| \"check s = False\""}
132.675 -\begin{isamarkuptext}
132.676 -
132.677 - \noindent An invocation of the above \cmd{fun} command does not
132.678 - terminate. What is the problem? Strings are lists of characters, and
132.679 - characters are a datatype with a lot of constructors. Splitting the
132.680 - catch-all pattern thus leads to an explosion of cases, which cannot
132.681 - be handled by Isabelle.
132.682 -
132.683 - There are two things we can do here. Either we write an explicit
132.684 - @{text "if"} on the right hand side, or we can use conditional patterns:
132.685 -*}
132.686 -
132.687 -function check :: "string \<Rightarrow> bool"
132.688 -where
132.689 - "check (''good'') = True"
132.690 -| "s \<noteq> ''good'' \<Longrightarrow> check s = False"
132.691 -by auto
132.692 -
132.693 -
132.694 -section {* Partiality *}
132.695 -
132.696 -text {*
132.697 - In HOL, all functions are total. A function @{term "f"} applied to
132.698 - @{term "x"} always has the value @{term "f x"}, and there is no notion
132.699 - of undefinedness.
132.700 - This is why we have to do termination
132.701 - proofs when defining functions: The proof justifies that the
132.702 - function can be defined by wellfounded recursion.
132.703 -
132.704 - However, the \cmd{function} package does support partiality to a
132.705 - certain extent. Let's look at the following function which looks
132.706 - for a zero of a given function f.
132.707 -*}
132.708 -
132.709 -function (*<*)(domintros, tailrec)(*>*)findzero :: "(nat \<Rightarrow> nat) \<Rightarrow> nat \<Rightarrow> nat"
132.710 -where
132.711 - "findzero f n = (if f n = 0 then n else findzero f (Suc n))"
132.712 -by pat_completeness auto
132.713 -(*<*)declare findzero.simps[simp del](*>*)
132.714 -
132.715 -text {*
132.716 - \noindent Clearly, any attempt of a termination proof must fail. And without
132.717 - that, we do not get the usual rules @{text "findzero.simps"} and
132.718 - @{text "findzero.induct"}. So what was the definition good for at all?
132.719 -*}
132.720 -
132.721 -subsection {* Domain predicates *}
132.722 -
132.723 -text {*
132.724 - The trick is that Isabelle has not only defined the function @{const findzero}, but also
132.725 - a predicate @{term "findzero_dom"} that characterizes the values where the function
132.726 - terminates: the \emph{domain} of the function. If we treat a
132.727 - partial function just as a total function with an additional domain
132.728 - predicate, we can derive simplification and
132.729 - induction rules as we do for total functions. They are guarded
132.730 - by domain conditions and are called @{text psimps} and @{text
132.731 - pinduct}:
132.732 -*}
132.733 -
132.734 -text {*
132.735 - \noindent\begin{minipage}{0.79\textwidth}@{thm[display,margin=85] findzero.psimps}\end{minipage}
132.736 - \hfill(@{text "findzero.psimps"})
132.737 - \vspace{1em}
132.738 -
132.739 - \noindent\begin{minipage}{0.79\textwidth}@{thm[display,margin=85] findzero.pinduct}\end{minipage}
132.740 - \hfill(@{text "findzero.pinduct"})
132.741 -*}
132.742 -
132.743 -text {*
132.744 - Remember that all we
132.745 - are doing here is use some tricks to make a total function appear
132.746 - as if it was partial. We can still write the term @{term "findzero
132.747 - (\<lambda>x. 1) 0"} and like any other term of type @{typ nat} it is equal
132.748 - to some natural number, although we might not be able to find out
132.749 - which one. The function is \emph{underdefined}.
132.750 -
132.751 - But it is defined enough to prove something interesting about it. We
132.752 - can prove that if @{term "findzero f n"}
132.753 - terminates, it indeed returns a zero of @{term f}:
132.754 -*}
132.755 -
132.756 -lemma findzero_zero: "findzero_dom (f, n) \<Longrightarrow> f (findzero f n) = 0"
132.757 -
132.758 -txt {* \noindent We apply induction as usual, but using the partial induction
132.759 - rule: *}
132.760 -
132.761 -apply (induct f n rule: findzero.pinduct)
132.762 -
132.763 -txt {* \noindent This gives the following subgoals:
132.764 -
132.765 - @{subgoals[display,indent=0]}
132.766 -
132.767 - \noindent The hypothesis in our lemma was used to satisfy the first premise in
132.768 - the induction rule. However, we also get @{term
132.769 - "findzero_dom (f, n)"} as a local assumption in the induction step. This
132.770 - allows to unfold @{term "findzero f n"} using the @{text psimps}
132.771 - rule, and the rest is trivial. Since the @{text psimps} rules carry the
132.772 - @{text "[simp]"} attribute by default, we just need a single step:
132.773 - *}
132.774 -apply simp
132.775 -done
132.776 -
132.777 -text {*
132.778 - Proofs about partial functions are often not harder than for total
132.779 - functions. Fig.~\ref{findzero_isar} shows a slightly more
132.780 - complicated proof written in Isar. It is verbose enough to show how
132.781 - partiality comes into play: From the partial induction, we get an
132.782 - additional domain condition hypothesis. Observe how this condition
132.783 - is applied when calls to @{term findzero} are unfolded.
132.784 -*}
132.785 -
132.786 -text_raw {*
132.787 -\begin{figure}
132.788 -\hrule\vspace{6pt}
132.789 -\begin{minipage}{0.8\textwidth}
132.790 -\isabellestyle{it}
132.791 -\isastyle\isamarkuptrue
132.792 -*}
132.793 -lemma "\<lbrakk>findzero_dom (f, n); x \<in> {n ..< findzero f n}\<rbrakk> \<Longrightarrow> f x \<noteq> 0"
132.794 -proof (induct rule: findzero.pinduct)
132.795 - fix f n assume dom: "findzero_dom (f, n)"
132.796 - and IH: "\<lbrakk>f n \<noteq> 0; x \<in> {Suc n ..< findzero f (Suc n)}\<rbrakk> \<Longrightarrow> f x \<noteq> 0"
132.797 - and x_range: "x \<in> {n ..< findzero f n}"
132.798 - have "f n \<noteq> 0"
132.799 - proof
132.800 - assume "f n = 0"
132.801 - with dom have "findzero f n = n" by simp
132.802 - with x_range show False by auto
132.803 - qed
132.804 -
132.805 - from x_range have "x = n \<or> x \<in> {Suc n ..< findzero f n}" by auto
132.806 - thus "f x \<noteq> 0"
132.807 - proof
132.808 - assume "x = n"
132.809 - with `f n \<noteq> 0` show ?thesis by simp
132.810 - next
132.811 - assume "x \<in> {Suc n ..< findzero f n}"
132.812 - with dom and `f n \<noteq> 0` have "x \<in> {Suc n ..< findzero f (Suc n)}" by simp
132.813 - with IH and `f n \<noteq> 0`
132.814 - show ?thesis by simp
132.815 - qed
132.816 -qed
132.817 -text_raw {*
132.818 -\isamarkupfalse\isabellestyle{tt}
132.819 -\end{minipage}\vspace{6pt}\hrule
132.820 -\caption{A proof about a partial function}\label{findzero_isar}
132.821 -\end{figure}
132.822 -*}
132.823 -
132.824 -subsection {* Partial termination proofs *}
132.825 -
132.826 -text {*
132.827 - Now that we have proved some interesting properties about our
132.828 - function, we should turn to the domain predicate and see if it is
132.829 - actually true for some values. Otherwise we would have just proved
132.830 - lemmas with @{term False} as a premise.
132.831 -
132.832 - Essentially, we need some introduction rules for @{text
132.833 - findzero_dom}. The function package can prove such domain
132.834 - introduction rules automatically. But since they are not used very
132.835 - often (they are almost never needed if the function is total), this
132.836 - functionality is disabled by default for efficiency reasons. So we have to go
132.837 - back and ask for them explicitly by passing the @{text
132.838 - "(domintros)"} option to the function package:
132.839 -
132.840 -\vspace{1ex}
132.841 -\noindent\cmd{function} @{text "(domintros) findzero :: \"(nat \<Rightarrow> nat) \<Rightarrow> nat \<Rightarrow> nat\""}\\%
132.842 -\cmd{where}\isanewline%
132.843 -\ \ \ldots\\
132.844 -
132.845 - \noindent Now the package has proved an introduction rule for @{text findzero_dom}:
132.846 -*}
132.847 -
132.848 -thm findzero.domintros
132.849 -
132.850 -text {*
132.851 - @{thm[display] findzero.domintros}
132.852 -
132.853 - Domain introduction rules allow to show that a given value lies in the
132.854 - domain of a function, if the arguments of all recursive calls
132.855 - are in the domain as well. They allow to do a \qt{single step} in a
132.856 - termination proof. Usually, you want to combine them with a suitable
132.857 - induction principle.
132.858 -
132.859 - Since our function increases its argument at recursive calls, we
132.860 - need an induction principle which works \qt{backwards}. We will use
132.861 - @{text inc_induct}, which allows to do induction from a fixed number
132.862 - \qt{downwards}:
132.863 -
132.864 - \begin{center}@{thm inc_induct}\hfill(@{text "inc_induct"})\end{center}
132.865 -
132.866 - Figure \ref{findzero_term} gives a detailed Isar proof of the fact
132.867 - that @{text findzero} terminates if there is a zero which is greater
132.868 - or equal to @{term n}. First we derive two useful rules which will
132.869 - solve the base case and the step case of the induction. The
132.870 - induction is then straightforward, except for the unusual induction
132.871 - principle.
132.872 -
132.873 -*}
132.874 -
132.875 -text_raw {*
132.876 -\begin{figure}
132.877 -\hrule\vspace{6pt}
132.878 -\begin{minipage}{0.8\textwidth}
132.879 -\isabellestyle{it}
132.880 -\isastyle\isamarkuptrue
132.881 -*}
132.882 -lemma findzero_termination:
132.883 - assumes "x \<ge> n" and "f x = 0"
132.884 - shows "findzero_dom (f, n)"
132.885 -proof -
132.886 - have base: "findzero_dom (f, x)"
132.887 - by (rule findzero.domintros) (simp add:`f x = 0`)
132.888 -
132.889 - have step: "\<And>i. findzero_dom (f, Suc i)
132.890 - \<Longrightarrow> findzero_dom (f, i)"
132.891 - by (rule findzero.domintros) simp
132.892 -
132.893 - from `x \<ge> n` show ?thesis
132.894 - proof (induct rule:inc_induct)
132.895 - show "findzero_dom (f, x)" by (rule base)
132.896 - next
132.897 - fix i assume "findzero_dom (f, Suc i)"
132.898 - thus "findzero_dom (f, i)" by (rule step)
132.899 - qed
132.900 -qed
132.901 -text_raw {*
132.902 -\isamarkupfalse\isabellestyle{tt}
132.903 -\end{minipage}\vspace{6pt}\hrule
132.904 -\caption{Termination proof for @{text findzero}}\label{findzero_term}
132.905 -\end{figure}
132.906 -*}
132.907 -
132.908 -text {*
132.909 - Again, the proof given in Fig.~\ref{findzero_term} has a lot of
132.910 - detail in order to explain the principles. Using more automation, we
132.911 - can also have a short proof:
132.912 -*}
132.913 -
132.914 -lemma findzero_termination_short:
132.915 - assumes zero: "x >= n"
132.916 - assumes [simp]: "f x = 0"
132.917 - shows "findzero_dom (f, n)"
132.918 -using zero
132.919 -by (induct rule:inc_induct) (auto intro: findzero.domintros)
132.920 -
132.921 -text {*
132.922 - \noindent It is simple to combine the partial correctness result with the
132.923 - termination lemma:
132.924 -*}
132.925 -
132.926 -lemma findzero_total_correctness:
132.927 - "f x = 0 \<Longrightarrow> f (findzero f 0) = 0"
132.928 -by (blast intro: findzero_zero findzero_termination)
132.929 -
132.930 -subsection {* Definition of the domain predicate *}
132.931 -
132.932 -text {*
132.933 - Sometimes it is useful to know what the definition of the domain
132.934 - predicate looks like. Actually, @{text findzero_dom} is just an
132.935 - abbreviation:
132.936 -
132.937 - @{abbrev[display] findzero_dom}
132.938 -
132.939 - The domain predicate is the \emph{accessible part} of a relation @{const
132.940 - findzero_rel}, which was also created internally by the function
132.941 - package. @{const findzero_rel} is just a normal
132.942 - inductive predicate, so we can inspect its definition by
132.943 - looking at the introduction rules @{text findzero_rel.intros}.
132.944 - In our case there is just a single rule:
132.945 -
132.946 - @{thm[display] findzero_rel.intros}
132.947 -
132.948 - The predicate @{const findzero_rel}
132.949 - describes the \emph{recursion relation} of the function
132.950 - definition. The recursion relation is a binary relation on
132.951 - the arguments of the function that relates each argument to its
132.952 - recursive calls. In general, there is one introduction rule for each
132.953 - recursive call.
132.954 -
132.955 - The predicate @{term "accp findzero_rel"} is the accessible part of
132.956 - that relation. An argument belongs to the accessible part, if it can
132.957 - be reached in a finite number of steps (cf.~its definition in @{text
132.958 - "Wellfounded.thy"}).
132.959 -
132.960 - Since the domain predicate is just an abbreviation, you can use
132.961 - lemmas for @{const accp} and @{const findzero_rel} directly. Some
132.962 - lemmas which are occasionally useful are @{text accpI}, @{text
132.963 - accp_downward}, and of course the introduction and elimination rules
132.964 - for the recursion relation @{text "findzero.intros"} and @{text "findzero.cases"}.
132.965 -*}
132.966 -
132.967 -(*lemma findzero_nicer_domintros:
132.968 - "f x = 0 \<Longrightarrow> findzero_dom (f, x)"
132.969 - "findzero_dom (f, Suc x) \<Longrightarrow> findzero_dom (f, x)"
132.970 -by (rule accpI, erule findzero_rel.cases, auto)+
132.971 -*)
132.972 -
132.973 -subsection {* A Useful Special Case: Tail recursion *}
132.974 -
132.975 -text {*
132.976 - The domain predicate is our trick that allows us to model partiality
132.977 - in a world of total functions. The downside of this is that we have
132.978 - to carry it around all the time. The termination proof above allowed
132.979 - us to replace the abstract @{term "findzero_dom (f, n)"} by the more
132.980 - concrete @{term "(x \<ge> n \<and> f x = (0::nat))"}, but the condition is still
132.981 - there and can only be discharged for special cases.
132.982 - In particular, the domain predicate guards the unfolding of our
132.983 - function, since it is there as a condition in the @{text psimp}
132.984 - rules.
132.985 -
132.986 - Now there is an important special case: We can actually get rid
132.987 - of the condition in the simplification rules, \emph{if the function
132.988 - is tail-recursive}. The reason is that for all tail-recursive
132.989 - equations there is a total function satisfying them, even if they
132.990 - are non-terminating.
132.991 -
132.992 -% A function is tail recursive, if each call to the function is either
132.993 -% equal
132.994 -%
132.995 -% So the outer form of the
132.996 -%
132.997 -%if it can be written in the following
132.998 -% form:
132.999 -% {term[display] "f x = (if COND x then BASE x else f (LOOP x))"}
132.1000 -
132.1001 -
132.1002 - The function package internally does the right construction and can
132.1003 - derive the unconditional simp rules, if we ask it to do so. Luckily,
132.1004 - our @{const "findzero"} function is tail-recursive, so we can just go
132.1005 - back and add another option to the \cmd{function} command:
132.1006 -
132.1007 -\vspace{1ex}
132.1008 -\noindent\cmd{function} @{text "(domintros, tailrec) findzero :: \"(nat \<Rightarrow> nat) \<Rightarrow> nat \<Rightarrow> nat\""}\\%
132.1009 -\cmd{where}\isanewline%
132.1010 -\ \ \ldots\\%
132.1011 -
132.1012 -
132.1013 - \noindent Now, we actually get unconditional simplification rules, even
132.1014 - though the function is partial:
132.1015 -*}
132.1016 -
132.1017 -thm findzero.simps
132.1018 -
132.1019 -text {*
132.1020 - @{thm[display] findzero.simps}
132.1021 -
132.1022 - \noindent Of course these would make the simplifier loop, so we better remove
132.1023 - them from the simpset:
132.1024 -*}
132.1025 -
132.1026 -declare findzero.simps[simp del]
132.1027 -
132.1028 -text {*
132.1029 - Getting rid of the domain conditions in the simplification rules is
132.1030 - not only useful because it simplifies proofs. It is also required in
132.1031 - order to use Isabelle's code generator to generate ML code
132.1032 - from a function definition.
132.1033 - Since the code generator only works with equations, it cannot be
132.1034 - used with @{text "psimp"} rules. Thus, in order to generate code for
132.1035 - partial functions, they must be defined as a tail recursion.
132.1036 - Luckily, many functions have a relatively natural tail recursive
132.1037 - definition.
132.1038 -*}
132.1039 -
132.1040 -section {* Nested recursion *}
132.1041 -
132.1042 -text {*
132.1043 - Recursive calls which are nested in one another frequently cause
132.1044 - complications, since their termination proof can depend on a partial
132.1045 - correctness property of the function itself.
132.1046 -
132.1047 - As a small example, we define the \qt{nested zero} function:
132.1048 -*}
132.1049 -
132.1050 -function nz :: "nat \<Rightarrow> nat"
132.1051 -where
132.1052 - "nz 0 = 0"
132.1053 -| "nz (Suc n) = nz (nz n)"
132.1054 -by pat_completeness auto
132.1055 -
132.1056 -text {*
132.1057 - If we attempt to prove termination using the identity measure on
132.1058 - naturals, this fails:
132.1059 -*}
132.1060 -
132.1061 -termination
132.1062 - apply (relation "measure (\<lambda>n. n)")
132.1063 - apply auto
132.1064 -
132.1065 -txt {*
132.1066 - We get stuck with the subgoal
132.1067 -
132.1068 - @{subgoals[display]}
132.1069 -
132.1070 - Of course this statement is true, since we know that @{const nz} is
132.1071 - the zero function. And in fact we have no problem proving this
132.1072 - property by induction.
132.1073 -*}
132.1074 -(*<*)oops(*>*)
132.1075 -lemma nz_is_zero: "nz_dom n \<Longrightarrow> nz n = 0"
132.1076 - by (induct rule:nz.pinduct) auto
132.1077 -
132.1078 -text {*
132.1079 - We formulate this as a partial correctness lemma with the condition
132.1080 - @{term "nz_dom n"}. This allows us to prove it with the @{text
132.1081 - pinduct} rule before we have proved termination. With this lemma,
132.1082 - the termination proof works as expected:
132.1083 -*}
132.1084 -
132.1085 -termination
132.1086 - by (relation "measure (\<lambda>n. n)") (auto simp: nz_is_zero)
132.1087 -
132.1088 -text {*
132.1089 - As a general strategy, one should prove the statements needed for
132.1090 - termination as a partial property first. Then they can be used to do
132.1091 - the termination proof. This also works for less trivial
132.1092 - examples. Figure \ref{f91} defines the 91-function, a well-known
132.1093 - challenge problem due to John McCarthy, and proves its termination.
132.1094 -*}
132.1095 -
132.1096 -text_raw {*
132.1097 -\begin{figure}
132.1098 -\hrule\vspace{6pt}
132.1099 -\begin{minipage}{0.8\textwidth}
132.1100 -\isabellestyle{it}
132.1101 -\isastyle\isamarkuptrue
132.1102 -*}
132.1103 -
132.1104 -function f91 :: "nat \<Rightarrow> nat"
132.1105 -where
132.1106 - "f91 n = (if 100 < n then n - 10 else f91 (f91 (n + 11)))"
132.1107 -by pat_completeness auto
132.1108 -
132.1109 -lemma f91_estimate:
132.1110 - assumes trm: "f91_dom n"
132.1111 - shows "n < f91 n + 11"
132.1112 -using trm by induct auto
132.1113 -
132.1114 -termination
132.1115 -proof
132.1116 - let ?R = "measure (\<lambda>x. 101 - x)"
132.1117 - show "wf ?R" ..
132.1118 -
132.1119 - fix n :: nat assume "\<not> 100 < n" -- "Assumptions for both calls"
132.1120 -
132.1121 - thus "(n + 11, n) \<in> ?R" by simp -- "Inner call"
132.1122 -
132.1123 - assume inner_trm: "f91_dom (n + 11)" -- "Outer call"
132.1124 - with f91_estimate have "n + 11 < f91 (n + 11) + 11" .
132.1125 - with `\<not> 100 < n` show "(f91 (n + 11), n) \<in> ?R" by simp
132.1126 -qed
132.1127 -
132.1128 -text_raw {*
132.1129 -\isamarkupfalse\isabellestyle{tt}
132.1130 -\end{minipage}
132.1131 -\vspace{6pt}\hrule
132.1132 -\caption{McCarthy's 91-function}\label{f91}
132.1133 -\end{figure}
132.1134 -*}
132.1135 -
132.1136 -
132.1137 -section {* Higher-Order Recursion *}
132.1138 -
132.1139 -text {*
132.1140 - Higher-order recursion occurs when recursive calls
132.1141 - are passed as arguments to higher-order combinators such as @{const
132.1142 - map}, @{term filter} etc.
132.1143 - As an example, imagine a datatype of n-ary trees:
132.1144 -*}
132.1145 -
132.1146 -datatype 'a tree =
132.1147 - Leaf 'a
132.1148 -| Branch "'a tree list"
132.1149 -
132.1150 -
132.1151 -text {* \noindent We can define a function which swaps the left and right subtrees recursively, using the
132.1152 - list functions @{const rev} and @{const map}: *}
132.1153 -
132.1154 -fun mirror :: "'a tree \<Rightarrow> 'a tree"
132.1155 -where
132.1156 - "mirror (Leaf n) = Leaf n"
132.1157 -| "mirror (Branch l) = Branch (rev (map mirror l))"
132.1158 -
132.1159 -text {*
132.1160 - Although the definition is accepted without problems, let us look at the termination proof:
132.1161 -*}
132.1162 -
132.1163 -termination proof
132.1164 - txt {*
132.1165 -
132.1166 - As usual, we have to give a wellfounded relation, such that the
132.1167 - arguments of the recursive calls get smaller. But what exactly are
132.1168 - the arguments of the recursive calls when mirror is given as an
132.1169 - argument to @{const map}? Isabelle gives us the
132.1170 - subgoals
132.1171 -
132.1172 - @{subgoals[display,indent=0]}
132.1173 -
132.1174 - So the system seems to know that @{const map} only
132.1175 - applies the recursive call @{term "mirror"} to elements
132.1176 - of @{term "l"}, which is essential for the termination proof.
132.1177 -
132.1178 - This knowledge about @{const map} is encoded in so-called congruence rules,
132.1179 - which are special theorems known to the \cmd{function} command. The
132.1180 - rule for @{const map} is
132.1181 -
132.1182 - @{thm[display] map_cong}
132.1183 -
132.1184 - You can read this in the following way: Two applications of @{const
132.1185 - map} are equal, if the list arguments are equal and the functions
132.1186 - coincide on the elements of the list. This means that for the value
132.1187 - @{term "map f l"} we only have to know how @{term f} behaves on
132.1188 - the elements of @{term l}.
132.1189 -
132.1190 - Usually, one such congruence rule is
132.1191 - needed for each higher-order construct that is used when defining
132.1192 - new functions. In fact, even basic functions like @{const
132.1193 - If} and @{const Let} are handled by this mechanism. The congruence
132.1194 - rule for @{const If} states that the @{text then} branch is only
132.1195 - relevant if the condition is true, and the @{text else} branch only if it
132.1196 - is false:
132.1197 -
132.1198 - @{thm[display] if_cong}
132.1199 -
132.1200 - Congruence rules can be added to the
132.1201 - function package by giving them the @{term fundef_cong} attribute.
132.1202 -
132.1203 - The constructs that are predefined in Isabelle, usually
132.1204 - come with the respective congruence rules.
132.1205 - But if you define your own higher-order functions, you may have to
132.1206 - state and prove the required congruence rules yourself, if you want to use your
132.1207 - functions in recursive definitions.
132.1208 -*}
132.1209 -(*<*)oops(*>*)
132.1210 -
132.1211 -subsection {* Congruence Rules and Evaluation Order *}
132.1212 -
132.1213 -text {*
132.1214 - Higher order logic differs from functional programming languages in
132.1215 - that it has no built-in notion of evaluation order. A program is
132.1216 - just a set of equations, and it is not specified how they must be
132.1217 - evaluated.
132.1218 -
132.1219 - However for the purpose of function definition, we must talk about
132.1220 - evaluation order implicitly, when we reason about termination.
132.1221 - Congruence rules express that a certain evaluation order is
132.1222 - consistent with the logical definition.
132.1223 -
132.1224 - Consider the following function.
132.1225 -*}
132.1226 -
132.1227 -function f :: "nat \<Rightarrow> bool"
132.1228 -where
132.1229 - "f n = (n = 0 \<or> f (n - 1))"
132.1230 -(*<*)by pat_completeness auto(*>*)
132.1231 -
132.1232 -text {*
132.1233 - For this definition, the termination proof fails. The default configuration
132.1234 - specifies no congruence rule for disjunction. We have to add a
132.1235 - congruence rule that specifies left-to-right evaluation order:
132.1236 -
132.1237 - \vspace{1ex}
132.1238 - \noindent @{thm disj_cong}\hfill(@{text "disj_cong"})
132.1239 - \vspace{1ex}
132.1240 -
132.1241 - Now the definition works without problems. Note how the termination
132.1242 - proof depends on the extra condition that we get from the congruence
132.1243 - rule.
132.1244 -
132.1245 - However, as evaluation is not a hard-wired concept, we
132.1246 - could just turn everything around by declaring a different
132.1247 - congruence rule. Then we can make the reverse definition:
132.1248 -*}
132.1249 -
132.1250 -lemma disj_cong2[fundef_cong]:
132.1251 - "(\<not> Q' \<Longrightarrow> P = P') \<Longrightarrow> (Q = Q') \<Longrightarrow> (P \<or> Q) = (P' \<or> Q')"
132.1252 - by blast
132.1253 -
132.1254 -fun f' :: "nat \<Rightarrow> bool"
132.1255 -where
132.1256 - "f' n = (f' (n - 1) \<or> n = 0)"
132.1257 -
132.1258 -text {*
132.1259 - \noindent These examples show that, in general, there is no \qt{best} set of
132.1260 - congruence rules.
132.1261 -
132.1262 - However, such tweaking should rarely be necessary in
132.1263 - practice, as most of the time, the default set of congruence rules
132.1264 - works well.
132.1265 -*}
132.1266 -
132.1267 -end
133.1 --- a/doc-src/IsarAdvanced/Functions/Thy/ROOT.ML Wed Mar 04 11:05:02 2009 +0100
133.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
133.3 @@ -1,4 +0,0 @@
133.4 -
133.5 -(* $Id$ *)
133.6 -
133.7 -use_thy "Functions";
134.1 --- a/doc-src/IsarAdvanced/Functions/Thy/document/Functions.tex Wed Mar 04 11:05:02 2009 +0100
134.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
134.3 @@ -1,1985 +0,0 @@
134.4 -%
134.5 -\begin{isabellebody}%
134.6 -\def\isabellecontext{Functions}%
134.7 -%
134.8 -\isadelimtheory
134.9 -\isanewline
134.10 -\isanewline
134.11 -%
134.12 -\endisadelimtheory
134.13 -%
134.14 -\isatagtheory
134.15 -\isacommand{theory}\isamarkupfalse%
134.16 -\ Functions\isanewline
134.17 -\isakeyword{imports}\ Main\isanewline
134.18 -\isakeyword{begin}%
134.19 -\endisatagtheory
134.20 -{\isafoldtheory}%
134.21 -%
134.22 -\isadelimtheory
134.23 -%
134.24 -\endisadelimtheory
134.25 -%
134.26 -\isamarkupsection{Function Definitions for Dummies%
134.27 -}
134.28 -\isamarkuptrue%
134.29 -%
134.30 -\begin{isamarkuptext}%
134.31 -In most cases, defining a recursive function is just as simple as other definitions:%
134.32 -\end{isamarkuptext}%
134.33 -\isamarkuptrue%
134.34 -\isacommand{fun}\isamarkupfalse%
134.35 -\ fib\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymRightarrow}\ nat{\isachardoublequoteclose}\isanewline
134.36 -\isakeyword{where}\isanewline
134.37 -\ \ {\isachardoublequoteopen}fib\ {\isadigit{0}}\ {\isacharequal}\ {\isadigit{1}}{\isachardoublequoteclose}\isanewline
134.38 -{\isacharbar}\ {\isachardoublequoteopen}fib\ {\isacharparenleft}Suc\ {\isadigit{0}}{\isacharparenright}\ {\isacharequal}\ {\isadigit{1}}{\isachardoublequoteclose}\isanewline
134.39 -{\isacharbar}\ {\isachardoublequoteopen}fib\ {\isacharparenleft}Suc\ {\isacharparenleft}Suc\ n{\isacharparenright}{\isacharparenright}\ {\isacharequal}\ fib\ n\ {\isacharplus}\ fib\ {\isacharparenleft}Suc\ n{\isacharparenright}{\isachardoublequoteclose}%
134.40 -\begin{isamarkuptext}%
134.41 -The syntax is rather self-explanatory: We introduce a function by
134.42 - giving its name, its type,
134.43 - and a set of defining recursive equations.
134.44 - If we leave out the type, the most general type will be
134.45 - inferred, which can sometimes lead to surprises: Since both \isa{{\isadigit{1}}} and \isa{{\isacharplus}} are overloaded, we would end up
134.46 - with \isa{fib\ {\isacharcolon}{\isacharcolon}\ nat\ {\isasymRightarrow}\ {\isacharprime}a{\isacharcolon}{\isacharcolon}{\isacharbraceleft}one{\isacharcomma}plus{\isacharbraceright}}.%
134.47 -\end{isamarkuptext}%
134.48 -\isamarkuptrue%
134.49 -%
134.50 -\begin{isamarkuptext}%
134.51 -The function always terminates, since its argument gets smaller in
134.52 - every recursive call.
134.53 - Since HOL is a logic of total functions, termination is a
134.54 - fundamental requirement to prevent inconsistencies\footnote{From the
134.55 - \qt{definition} \isa{f{\isacharparenleft}n{\isacharparenright}\ {\isacharequal}\ f{\isacharparenleft}n{\isacharparenright}\ {\isacharplus}\ {\isadigit{1}}} we could prove
134.56 - \isa{{\isadigit{0}}\ {\isacharequal}\ {\isadigit{1}}} by subtracting \isa{f{\isacharparenleft}n{\isacharparenright}} on both sides.}.
134.57 - Isabelle tries to prove termination automatically when a definition
134.58 - is made. In \S\ref{termination}, we will look at cases where this
134.59 - fails and see what to do then.%
134.60 -\end{isamarkuptext}%
134.61 -\isamarkuptrue%
134.62 -%
134.63 -\isamarkupsubsection{Pattern matching%
134.64 -}
134.65 -\isamarkuptrue%
134.66 -%
134.67 -\begin{isamarkuptext}%
134.68 -\label{patmatch}
134.69 - Like in functional programming, we can use pattern matching to
134.70 - define functions. At the moment we will only consider \emph{constructor
134.71 - patterns}, which only consist of datatype constructors and
134.72 - variables. Furthermore, patterns must be linear, i.e.\ all variables
134.73 - on the left hand side of an equation must be distinct. In
134.74 - \S\ref{genpats} we discuss more general pattern matching.
134.75 -
134.76 - If patterns overlap, the order of the equations is taken into
134.77 - account. The following function inserts a fixed element between any
134.78 - two elements of a list:%
134.79 -\end{isamarkuptext}%
134.80 -\isamarkuptrue%
134.81 -\isacommand{fun}\isamarkupfalse%
134.82 -\ sep\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharprime}a\ {\isasymRightarrow}\ {\isacharprime}a\ list\ {\isasymRightarrow}\ {\isacharprime}a\ list{\isachardoublequoteclose}\isanewline
134.83 -\isakeyword{where}\isanewline
134.84 -\ \ {\isachardoublequoteopen}sep\ a\ {\isacharparenleft}x{\isacharhash}y{\isacharhash}xs{\isacharparenright}\ {\isacharequal}\ x\ {\isacharhash}\ a\ {\isacharhash}\ sep\ a\ {\isacharparenleft}y\ {\isacharhash}\ xs{\isacharparenright}{\isachardoublequoteclose}\isanewline
134.85 -{\isacharbar}\ {\isachardoublequoteopen}sep\ a\ xs\ \ \ \ \ \ \ {\isacharequal}\ xs{\isachardoublequoteclose}%
134.86 -\begin{isamarkuptext}%
134.87 -Overlapping patterns are interpreted as \qt{increments} to what is
134.88 - already there: The second equation is only meant for the cases where
134.89 - the first one does not match. Consequently, Isabelle replaces it
134.90 - internally by the remaining cases, making the patterns disjoint:%
134.91 -\end{isamarkuptext}%
134.92 -\isamarkuptrue%
134.93 -\isacommand{thm}\isamarkupfalse%
134.94 -\ sep{\isachardot}simps%
134.95 -\begin{isamarkuptext}%
134.96 -\begin{isabelle}%
134.97 -sep\ a\ {\isacharparenleft}x\ {\isacharhash}\ y\ {\isacharhash}\ xs{\isacharparenright}\ {\isacharequal}\ x\ {\isacharhash}\ a\ {\isacharhash}\ sep\ a\ {\isacharparenleft}y\ {\isacharhash}\ xs{\isacharparenright}\isasep\isanewline%
134.98 -sep\ a\ {\isacharbrackleft}{\isacharbrackright}\ {\isacharequal}\ {\isacharbrackleft}{\isacharbrackright}\isasep\isanewline%
134.99 -sep\ a\ {\isacharbrackleft}v{\isacharbrackright}\ {\isacharequal}\ {\isacharbrackleft}v{\isacharbrackright}%
134.100 -\end{isabelle}%
134.101 -\end{isamarkuptext}%
134.102 -\isamarkuptrue%
134.103 -%
134.104 -\begin{isamarkuptext}%
134.105 -\noindent The equations from function definitions are automatically used in
134.106 - simplification:%
134.107 -\end{isamarkuptext}%
134.108 -\isamarkuptrue%
134.109 -\isacommand{lemma}\isamarkupfalse%
134.110 -\ {\isachardoublequoteopen}sep\ {\isadigit{0}}\ {\isacharbrackleft}{\isadigit{1}}{\isacharcomma}\ {\isadigit{2}}{\isacharcomma}\ {\isadigit{3}}{\isacharbrackright}\ {\isacharequal}\ {\isacharbrackleft}{\isadigit{1}}{\isacharcomma}\ {\isadigit{0}}{\isacharcomma}\ {\isadigit{2}}{\isacharcomma}\ {\isadigit{0}}{\isacharcomma}\ {\isadigit{3}}{\isacharbrackright}{\isachardoublequoteclose}\isanewline
134.111 -%
134.112 -\isadelimproof
134.113 -%
134.114 -\endisadelimproof
134.115 -%
134.116 -\isatagproof
134.117 -\isacommand{by}\isamarkupfalse%
134.118 -\ simp%
134.119 -\endisatagproof
134.120 -{\isafoldproof}%
134.121 -%
134.122 -\isadelimproof
134.123 -%
134.124 -\endisadelimproof
134.125 -%
134.126 -\isamarkupsubsection{Induction%
134.127 -}
134.128 -\isamarkuptrue%
134.129 -%
134.130 -\begin{isamarkuptext}%
134.131 -Isabelle provides customized induction rules for recursive
134.132 - functions. These rules follow the recursive structure of the
134.133 - definition. Here is the rule \isa{sep{\isachardot}induct} arising from the
134.134 - above definition of \isa{sep}:
134.135 -
134.136 - \begin{isabelle}%
134.137 -{\isasymlbrakk}{\isasymAnd}a\ x\ y\ xs{\isachardot}\ {\isacharquery}P\ a\ {\isacharparenleft}y\ {\isacharhash}\ xs{\isacharparenright}\ {\isasymLongrightarrow}\ {\isacharquery}P\ a\ {\isacharparenleft}x\ {\isacharhash}\ y\ {\isacharhash}\ xs{\isacharparenright}{\isacharsemicolon}\ {\isasymAnd}a{\isachardot}\ {\isacharquery}P\ a\ {\isacharbrackleft}{\isacharbrackright}{\isacharsemicolon}\ {\isasymAnd}a\ v{\isachardot}\ {\isacharquery}P\ a\ {\isacharbrackleft}v{\isacharbrackright}{\isasymrbrakk}\isanewline
134.138 -{\isasymLongrightarrow}\ {\isacharquery}P\ {\isacharquery}a{\isadigit{0}}{\isachardot}{\isadigit{0}}\ {\isacharquery}a{\isadigit{1}}{\isachardot}{\isadigit{0}}%
134.139 -\end{isabelle}
134.140 -
134.141 - We have a step case for list with at least two elements, and two
134.142 - base cases for the zero- and the one-element list. Here is a simple
134.143 - proof about \isa{sep} and \isa{map}%
134.144 -\end{isamarkuptext}%
134.145 -\isamarkuptrue%
134.146 -\isacommand{lemma}\isamarkupfalse%
134.147 -\ {\isachardoublequoteopen}map\ f\ {\isacharparenleft}sep\ x\ ys{\isacharparenright}\ {\isacharequal}\ sep\ {\isacharparenleft}f\ x{\isacharparenright}\ {\isacharparenleft}map\ f\ ys{\isacharparenright}{\isachardoublequoteclose}\isanewline
134.148 -%
134.149 -\isadelimproof
134.150 -%
134.151 -\endisadelimproof
134.152 -%
134.153 -\isatagproof
134.154 -\isacommand{apply}\isamarkupfalse%
134.155 -\ {\isacharparenleft}induct\ x\ ys\ rule{\isacharcolon}\ sep{\isachardot}induct{\isacharparenright}%
134.156 -\begin{isamarkuptxt}%
134.157 -We get three cases, like in the definition.
134.158 -
134.159 - \begin{isabelle}%
134.160 -\ {\isadigit{1}}{\isachardot}\ {\isasymAnd}a\ x\ y\ xs{\isachardot}\isanewline
134.161 -\isaindent{\ {\isadigit{1}}{\isachardot}\ \ \ \ }map\ f\ {\isacharparenleft}sep\ a\ {\isacharparenleft}y\ {\isacharhash}\ xs{\isacharparenright}{\isacharparenright}\ {\isacharequal}\ sep\ {\isacharparenleft}f\ a{\isacharparenright}\ {\isacharparenleft}map\ f\ {\isacharparenleft}y\ {\isacharhash}\ xs{\isacharparenright}{\isacharparenright}\ {\isasymLongrightarrow}\isanewline
134.162 -\isaindent{\ {\isadigit{1}}{\isachardot}\ \ \ \ }map\ f\ {\isacharparenleft}sep\ a\ {\isacharparenleft}x\ {\isacharhash}\ y\ {\isacharhash}\ xs{\isacharparenright}{\isacharparenright}\ {\isacharequal}\ sep\ {\isacharparenleft}f\ a{\isacharparenright}\ {\isacharparenleft}map\ f\ {\isacharparenleft}x\ {\isacharhash}\ y\ {\isacharhash}\ xs{\isacharparenright}{\isacharparenright}\isanewline
134.163 -\ {\isadigit{2}}{\isachardot}\ {\isasymAnd}a{\isachardot}\ map\ f\ {\isacharparenleft}sep\ a\ {\isacharbrackleft}{\isacharbrackright}{\isacharparenright}\ {\isacharequal}\ sep\ {\isacharparenleft}f\ a{\isacharparenright}\ {\isacharparenleft}map\ f\ {\isacharbrackleft}{\isacharbrackright}{\isacharparenright}\isanewline
134.164 -\ {\isadigit{3}}{\isachardot}\ {\isasymAnd}a\ v{\isachardot}\ map\ f\ {\isacharparenleft}sep\ a\ {\isacharbrackleft}v{\isacharbrackright}{\isacharparenright}\ {\isacharequal}\ sep\ {\isacharparenleft}f\ a{\isacharparenright}\ {\isacharparenleft}map\ f\ {\isacharbrackleft}v{\isacharbrackright}{\isacharparenright}%
134.165 -\end{isabelle}%
134.166 -\end{isamarkuptxt}%
134.167 -\isamarkuptrue%
134.168 -\isacommand{apply}\isamarkupfalse%
134.169 -\ auto\ \isanewline
134.170 -\isacommand{done}\isamarkupfalse%
134.171 -%
134.172 -\endisatagproof
134.173 -{\isafoldproof}%
134.174 -%
134.175 -\isadelimproof
134.176 -%
134.177 -\endisadelimproof
134.178 -%
134.179 -\begin{isamarkuptext}%
134.180 -With the \cmd{fun} command, you can define about 80\% of the
134.181 - functions that occur in practice. The rest of this tutorial explains
134.182 - the remaining 20\%.%
134.183 -\end{isamarkuptext}%
134.184 -\isamarkuptrue%
134.185 -%
134.186 -\isamarkupsection{fun vs.\ function%
134.187 -}
134.188 -\isamarkuptrue%
134.189 -%
134.190 -\begin{isamarkuptext}%
134.191 -The \cmd{fun} command provides a
134.192 - convenient shorthand notation for simple function definitions. In
134.193 - this mode, Isabelle tries to solve all the necessary proof obligations
134.194 - automatically. If any proof fails, the definition is
134.195 - rejected. This can either mean that the definition is indeed faulty,
134.196 - or that the default proof procedures are just not smart enough (or
134.197 - rather: not designed) to handle the definition.
134.198 -
134.199 - By expanding the abbreviation to the more verbose \cmd{function} command, these proof obligations become visible and can be analyzed or
134.200 - solved manually. The expansion from \cmd{fun} to \cmd{function} is as follows:
134.201 -
134.202 -\end{isamarkuptext}
134.203 -
134.204 -
134.205 -\[\left[\;\begin{minipage}{0.25\textwidth}\vspace{6pt}
134.206 -\cmd{fun} \isa{f\ {\isacharcolon}{\isacharcolon}\ {\isasymtau}}\\%
134.207 -\cmd{where}\\%
134.208 -\hspace*{2ex}{\it equations}\\%
134.209 -\hspace*{2ex}\vdots\vspace*{6pt}
134.210 -\end{minipage}\right]
134.211 -\quad\equiv\quad
134.212 -\left[\;\begin{minipage}{0.48\textwidth}\vspace{6pt}
134.213 -\cmd{function} \isa{{\isacharparenleft}}\cmd{sequential}\isa{{\isacharparenright}\ f\ {\isacharcolon}{\isacharcolon}\ {\isasymtau}}\\%
134.214 -\cmd{where}\\%
134.215 -\hspace*{2ex}{\it equations}\\%
134.216 -\hspace*{2ex}\vdots\\%
134.217 -\cmd{by} \isa{pat{\isacharunderscore}completeness\ auto}\\%
134.218 -\cmd{termination by} \isa{lexicographic{\isacharunderscore}order}\vspace{6pt}
134.219 -\end{minipage}
134.220 -\right]\]
134.221 -
134.222 -\begin{isamarkuptext}
134.223 - \vspace*{1em}
134.224 - \noindent Some details have now become explicit:
134.225 -
134.226 - \begin{enumerate}
134.227 - \item The \cmd{sequential} option enables the preprocessing of
134.228 - pattern overlaps which we already saw. Without this option, the equations
134.229 - must already be disjoint and complete. The automatic completion only
134.230 - works with constructor patterns.
134.231 -
134.232 - \item A function definition produces a proof obligation which
134.233 - expresses completeness and compatibility of patterns (we talk about
134.234 - this later). The combination of the methods \isa{pat{\isacharunderscore}completeness} and
134.235 - \isa{auto} is used to solve this proof obligation.
134.236 -
134.237 - \item A termination proof follows the definition, started by the
134.238 - \cmd{termination} command. This will be explained in \S\ref{termination}.
134.239 - \end{enumerate}
134.240 - Whenever a \cmd{fun} command fails, it is usually a good idea to
134.241 - expand the syntax to the more verbose \cmd{function} form, to see
134.242 - what is actually going on.%
134.243 -\end{isamarkuptext}%
134.244 -\isamarkuptrue%
134.245 -%
134.246 -\isamarkupsection{Termination%
134.247 -}
134.248 -\isamarkuptrue%
134.249 -%
134.250 -\begin{isamarkuptext}%
134.251 -\label{termination}
134.252 - The method \isa{lexicographic{\isacharunderscore}order} is the default method for
134.253 - termination proofs. It can prove termination of a
134.254 - certain class of functions by searching for a suitable lexicographic
134.255 - combination of size measures. Of course, not all functions have such
134.256 - a simple termination argument. For them, we can specify the termination
134.257 - relation manually.%
134.258 -\end{isamarkuptext}%
134.259 -\isamarkuptrue%
134.260 -%
134.261 -\isamarkupsubsection{The {\tt relation} method%
134.262 -}
134.263 -\isamarkuptrue%
134.264 -%
134.265 -\begin{isamarkuptext}%
134.266 -Consider the following function, which sums up natural numbers up to
134.267 - \isa{N}, using a counter \isa{i}:%
134.268 -\end{isamarkuptext}%
134.269 -\isamarkuptrue%
134.270 -\isacommand{function}\isamarkupfalse%
134.271 -\ sum\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymRightarrow}\ nat\ {\isasymRightarrow}\ nat{\isachardoublequoteclose}\isanewline
134.272 -\isakeyword{where}\isanewline
134.273 -\ \ {\isachardoublequoteopen}sum\ i\ N\ {\isacharequal}\ {\isacharparenleft}if\ i\ {\isachargreater}\ N\ then\ {\isadigit{0}}\ else\ i\ {\isacharplus}\ sum\ {\isacharparenleft}Suc\ i{\isacharparenright}\ N{\isacharparenright}{\isachardoublequoteclose}\isanewline
134.274 -%
134.275 -\isadelimproof
134.276 -%
134.277 -\endisadelimproof
134.278 -%
134.279 -\isatagproof
134.280 -\isacommand{by}\isamarkupfalse%
134.281 -\ pat{\isacharunderscore}completeness\ auto%
134.282 -\endisatagproof
134.283 -{\isafoldproof}%
134.284 -%
134.285 -\isadelimproof
134.286 -%
134.287 -\endisadelimproof
134.288 -%
134.289 -\begin{isamarkuptext}%
134.290 -\noindent The \isa{lexicographic{\isacharunderscore}order} method fails on this example, because none of the
134.291 - arguments decreases in the recursive call, with respect to the standard size ordering.
134.292 - To prove termination manually, we must provide a custom wellfounded relation.
134.293 -
134.294 - The termination argument for \isa{sum} is based on the fact that
134.295 - the \emph{difference} between \isa{i} and \isa{N} gets
134.296 - smaller in every step, and that the recursion stops when \isa{i}
134.297 - is greater than \isa{N}. Phrased differently, the expression
134.298 - \isa{N\ {\isacharplus}\ {\isadigit{1}}\ {\isacharminus}\ i} always decreases.
134.299 -
134.300 - We can use this expression as a measure function suitable to prove termination.%
134.301 -\end{isamarkuptext}%
134.302 -\isamarkuptrue%
134.303 -\isacommand{termination}\isamarkupfalse%
134.304 -\ sum\isanewline
134.305 -%
134.306 -\isadelimproof
134.307 -%
134.308 -\endisadelimproof
134.309 -%
134.310 -\isatagproof
134.311 -\isacommand{apply}\isamarkupfalse%
134.312 -\ {\isacharparenleft}relation\ {\isachardoublequoteopen}measure\ {\isacharparenleft}{\isasymlambda}{\isacharparenleft}i{\isacharcomma}N{\isacharparenright}{\isachardot}\ N\ {\isacharplus}\ {\isadigit{1}}\ {\isacharminus}\ i{\isacharparenright}{\isachardoublequoteclose}{\isacharparenright}%
134.313 -\begin{isamarkuptxt}%
134.314 -The \cmd{termination} command sets up the termination goal for the
134.315 - specified function \isa{sum}. If the function name is omitted, it
134.316 - implicitly refers to the last function definition.
134.317 -
134.318 - The \isa{relation} method takes a relation of
134.319 - type \isa{{\isacharparenleft}{\isacharprime}a\ {\isasymtimes}\ {\isacharprime}a{\isacharparenright}\ set}, where \isa{{\isacharprime}a} is the argument type of
134.320 - the function. If the function has multiple curried arguments, then
134.321 - these are packed together into a tuple, as it happened in the above
134.322 - example.
134.323 -
134.324 - The predefined function \isa{{\isachardoublequote}measure\ {\isacharcolon}{\isacharcolon}\ {\isacharparenleft}{\isacharprime}a\ {\isasymRightarrow}\ nat{\isacharparenright}\ {\isasymRightarrow}\ {\isacharparenleft}{\isacharprime}a\ {\isasymtimes}\ {\isacharprime}a{\isacharparenright}\ set{\isachardoublequote}} constructs a
134.325 - wellfounded relation from a mapping into the natural numbers (a
134.326 - \emph{measure function}).
134.327 -
134.328 - After the invocation of \isa{relation}, we must prove that (a)
134.329 - the relation we supplied is wellfounded, and (b) that the arguments
134.330 - of recursive calls indeed decrease with respect to the
134.331 - relation:
134.332 -
134.333 - \begin{isabelle}%
134.334 -\ {\isadigit{1}}{\isachardot}\ wf\ {\isacharparenleft}measure\ {\isacharparenleft}{\isasymlambda}{\isacharparenleft}i{\isacharcomma}\ N{\isacharparenright}{\isachardot}\ N\ {\isacharplus}\ {\isadigit{1}}\ {\isacharminus}\ i{\isacharparenright}{\isacharparenright}\isanewline
134.335 -\ {\isadigit{2}}{\isachardot}\ {\isasymAnd}i\ N{\isachardot}\ {\isasymnot}\ N\ {\isacharless}\ i\ {\isasymLongrightarrow}\ {\isacharparenleft}{\isacharparenleft}Suc\ i{\isacharcomma}\ N{\isacharparenright}{\isacharcomma}\ i{\isacharcomma}\ N{\isacharparenright}\ {\isasymin}\ measure\ {\isacharparenleft}{\isasymlambda}{\isacharparenleft}i{\isacharcomma}\ N{\isacharparenright}{\isachardot}\ N\ {\isacharplus}\ {\isadigit{1}}\ {\isacharminus}\ i{\isacharparenright}%
134.336 -\end{isabelle}
134.337 -
134.338 - These goals are all solved by \isa{auto}:%
134.339 -\end{isamarkuptxt}%
134.340 -\isamarkuptrue%
134.341 -\isacommand{apply}\isamarkupfalse%
134.342 -\ auto\isanewline
134.343 -\isacommand{done}\isamarkupfalse%
134.344 -%
134.345 -\endisatagproof
134.346 -{\isafoldproof}%
134.347 -%
134.348 -\isadelimproof
134.349 -%
134.350 -\endisadelimproof
134.351 -%
134.352 -\begin{isamarkuptext}%
134.353 -Let us complicate the function a little, by adding some more
134.354 - recursive calls:%
134.355 -\end{isamarkuptext}%
134.356 -\isamarkuptrue%
134.357 -\isacommand{function}\isamarkupfalse%
134.358 -\ foo\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymRightarrow}\ nat\ {\isasymRightarrow}\ nat{\isachardoublequoteclose}\isanewline
134.359 -\isakeyword{where}\isanewline
134.360 -\ \ {\isachardoublequoteopen}foo\ i\ N\ {\isacharequal}\ {\isacharparenleft}if\ i\ {\isachargreater}\ N\ \isanewline
134.361 -\ \ \ \ \ \ \ \ \ \ \ \ \ \ then\ {\isacharparenleft}if\ N\ {\isacharequal}\ {\isadigit{0}}\ then\ {\isadigit{0}}\ else\ foo\ {\isadigit{0}}\ {\isacharparenleft}N\ {\isacharminus}\ {\isadigit{1}}{\isacharparenright}{\isacharparenright}\isanewline
134.362 -\ \ \ \ \ \ \ \ \ \ \ \ \ \ else\ i\ {\isacharplus}\ foo\ {\isacharparenleft}Suc\ i{\isacharparenright}\ N{\isacharparenright}{\isachardoublequoteclose}\isanewline
134.363 -%
134.364 -\isadelimproof
134.365 -%
134.366 -\endisadelimproof
134.367 -%
134.368 -\isatagproof
134.369 -\isacommand{by}\isamarkupfalse%
134.370 -\ pat{\isacharunderscore}completeness\ auto%
134.371 -\endisatagproof
134.372 -{\isafoldproof}%
134.373 -%
134.374 -\isadelimproof
134.375 -%
134.376 -\endisadelimproof
134.377 -%
134.378 -\begin{isamarkuptext}%
134.379 -When \isa{i} has reached \isa{N}, it starts at zero again
134.380 - and \isa{N} is decremented.
134.381 - This corresponds to a nested
134.382 - loop where one index counts up and the other down. Termination can
134.383 - be proved using a lexicographic combination of two measures, namely
134.384 - the value of \isa{N} and the above difference. The \isa{measures} combinator generalizes \isa{measure} by taking a
134.385 - list of measure functions.%
134.386 -\end{isamarkuptext}%
134.387 -\isamarkuptrue%
134.388 -\isacommand{termination}\isamarkupfalse%
134.389 -\ \isanewline
134.390 -%
134.391 -\isadelimproof
134.392 -%
134.393 -\endisadelimproof
134.394 -%
134.395 -\isatagproof
134.396 -\isacommand{by}\isamarkupfalse%
134.397 -\ {\isacharparenleft}relation\ {\isachardoublequoteopen}measures\ {\isacharbrackleft}{\isasymlambda}{\isacharparenleft}i{\isacharcomma}\ N{\isacharparenright}{\isachardot}\ N{\isacharcomma}\ {\isasymlambda}{\isacharparenleft}i{\isacharcomma}N{\isacharparenright}{\isachardot}\ N\ {\isacharplus}\ {\isadigit{1}}\ {\isacharminus}\ i{\isacharbrackright}{\isachardoublequoteclose}{\isacharparenright}\ auto%
134.398 -\endisatagproof
134.399 -{\isafoldproof}%
134.400 -%
134.401 -\isadelimproof
134.402 -%
134.403 -\endisadelimproof
134.404 -%
134.405 -\isamarkupsubsection{How \isa{lexicographic{\isacharunderscore}order} works%
134.406 -}
134.407 -\isamarkuptrue%
134.408 -%
134.409 -\begin{isamarkuptext}%
134.410 -To see how the automatic termination proofs work, let's look at an
134.411 - example where it fails\footnote{For a detailed discussion of the
134.412 - termination prover, see \cite{bulwahnKN07}}:
134.413 -
134.414 -\end{isamarkuptext}
134.415 -\cmd{fun} \isa{fails\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequote}nat\ {\isasymRightarrow}\ nat\ list\ {\isasymRightarrow}\ nat{\isachardoublequote}}\\%
134.416 -\cmd{where}\\%
134.417 -\hspace*{2ex}\isa{{\isachardoublequote}fails\ a\ {\isacharbrackleft}{\isacharbrackright}\ {\isacharequal}\ a{\isachardoublequote}}\\%
134.418 -|\hspace*{1.5ex}\isa{{\isachardoublequote}fails\ a\ {\isacharparenleft}x{\isacharhash}xs{\isacharparenright}\ {\isacharequal}\ fails\ {\isacharparenleft}x\ {\isacharplus}\ a{\isacharparenright}\ {\isacharparenleft}x{\isacharhash}xs{\isacharparenright}{\isachardoublequote}}\\
134.419 -\begin{isamarkuptext}
134.420 -
134.421 -\noindent Isabelle responds with the following error:
134.422 -
134.423 -\begin{isabelle}
134.424 -*** Unfinished subgoals:\newline
134.425 -*** (a, 1, <):\newline
134.426 -*** \ 1.~\isa{{\isasymAnd}x{\isachardot}\ x\ {\isacharequal}\ {\isadigit{0}}}\newline
134.427 -*** (a, 1, <=):\newline
134.428 -*** \ 1.~False\newline
134.429 -*** (a, 2, <):\newline
134.430 -*** \ 1.~False\newline
134.431 -*** Calls:\newline
134.432 -*** a) \isa{{\isacharparenleft}a{\isacharcomma}\ x\ {\isacharhash}\ xs{\isacharparenright}\ {\isacharminus}{\isacharminus}{\isachargreater}{\isachargreater}\ {\isacharparenleft}x\ {\isacharplus}\ a{\isacharcomma}\ x\ {\isacharhash}\ xs{\isacharparenright}}\newline
134.433 -*** Measures:\newline
134.434 -*** 1) \isa{{\isasymlambda}x{\isachardot}\ size\ {\isacharparenleft}fst\ x{\isacharparenright}}\newline
134.435 -*** 2) \isa{{\isasymlambda}x{\isachardot}\ size\ {\isacharparenleft}snd\ x{\isacharparenright}}\newline
134.436 -*** Result matrix:\newline
134.437 -*** \ \ \ \ 1\ \ 2 \newline
134.438 -*** a: ? <= \newline
134.439 -*** Could not find lexicographic termination order.\newline
134.440 -*** At command "fun".\newline
134.441 -\end{isabelle}%
134.442 -\end{isamarkuptext}%
134.443 -\isamarkuptrue%
134.444 -%
134.445 -\begin{isamarkuptext}%
134.446 -The key to this error message is the matrix at the bottom. The rows
134.447 - of that matrix correspond to the different recursive calls (In our
134.448 - case, there is just one). The columns are the function's arguments
134.449 - (expressed through different measure functions, which map the
134.450 - argument tuple to a natural number).
134.451 -
134.452 - The contents of the matrix summarize what is known about argument
134.453 - descents: The second argument has a weak descent (\isa{{\isacharless}{\isacharequal}}) at the
134.454 - recursive call, and for the first argument nothing could be proved,
134.455 - which is expressed by \isa{{\isacharquery}}. In general, there are the values
134.456 - \isa{{\isacharless}}, \isa{{\isacharless}{\isacharequal}} and \isa{{\isacharquery}}.
134.457 -
134.458 - For the failed proof attempts, the unfinished subgoals are also
134.459 - printed. Looking at these will often point to a missing lemma.
134.460 -
134.461 -% As a more real example, here is quicksort:%
134.462 -\end{isamarkuptext}%
134.463 -\isamarkuptrue%
134.464 -%
134.465 -\isamarkupsection{Mutual Recursion%
134.466 -}
134.467 -\isamarkuptrue%
134.468 -%
134.469 -\begin{isamarkuptext}%
134.470 -If two or more functions call one another mutually, they have to be defined
134.471 - in one step. Here are \isa{even} and \isa{odd}:%
134.472 -\end{isamarkuptext}%
134.473 -\isamarkuptrue%
134.474 -\isacommand{function}\isamarkupfalse%
134.475 -\ even\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymRightarrow}\ bool{\isachardoublequoteclose}\isanewline
134.476 -\ \ \ \ \isakeyword{and}\ odd\ \ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymRightarrow}\ bool{\isachardoublequoteclose}\isanewline
134.477 -\isakeyword{where}\isanewline
134.478 -\ \ {\isachardoublequoteopen}even\ {\isadigit{0}}\ {\isacharequal}\ True{\isachardoublequoteclose}\isanewline
134.479 -{\isacharbar}\ {\isachardoublequoteopen}odd\ {\isadigit{0}}\ {\isacharequal}\ False{\isachardoublequoteclose}\isanewline
134.480 -{\isacharbar}\ {\isachardoublequoteopen}even\ {\isacharparenleft}Suc\ n{\isacharparenright}\ {\isacharequal}\ odd\ n{\isachardoublequoteclose}\isanewline
134.481 -{\isacharbar}\ {\isachardoublequoteopen}odd\ {\isacharparenleft}Suc\ n{\isacharparenright}\ {\isacharequal}\ even\ n{\isachardoublequoteclose}\isanewline
134.482 -%
134.483 -\isadelimproof
134.484 -%
134.485 -\endisadelimproof
134.486 -%
134.487 -\isatagproof
134.488 -\isacommand{by}\isamarkupfalse%
134.489 -\ pat{\isacharunderscore}completeness\ auto%
134.490 -\endisatagproof
134.491 -{\isafoldproof}%
134.492 -%
134.493 -\isadelimproof
134.494 -%
134.495 -\endisadelimproof
134.496 -%
134.497 -\begin{isamarkuptext}%
134.498 -To eliminate the mutual dependencies, Isabelle internally
134.499 - creates a single function operating on the sum
134.500 - type \isa{nat\ {\isacharplus}\ nat}. Then, \isa{even} and \isa{odd} are
134.501 - defined as projections. Consequently, termination has to be proved
134.502 - simultaneously for both functions, by specifying a measure on the
134.503 - sum type:%
134.504 -\end{isamarkuptext}%
134.505 -\isamarkuptrue%
134.506 -\isacommand{termination}\isamarkupfalse%
134.507 -\ \isanewline
134.508 -%
134.509 -\isadelimproof
134.510 -%
134.511 -\endisadelimproof
134.512 -%
134.513 -\isatagproof
134.514 -\isacommand{by}\isamarkupfalse%
134.515 -\ {\isacharparenleft}relation\ {\isachardoublequoteopen}measure\ {\isacharparenleft}{\isasymlambda}x{\isachardot}\ case\ x\ of\ Inl\ n\ {\isasymRightarrow}\ n\ {\isacharbar}\ Inr\ n\ {\isasymRightarrow}\ n{\isacharparenright}{\isachardoublequoteclose}{\isacharparenright}\ auto%
134.516 -\endisatagproof
134.517 -{\isafoldproof}%
134.518 -%
134.519 -\isadelimproof
134.520 -%
134.521 -\endisadelimproof
134.522 -%
134.523 -\begin{isamarkuptext}%
134.524 -We could also have used \isa{lexicographic{\isacharunderscore}order}, which
134.525 - supports mutual recursive termination proofs to a certain extent.%
134.526 -\end{isamarkuptext}%
134.527 -\isamarkuptrue%
134.528 -%
134.529 -\isamarkupsubsection{Induction for mutual recursion%
134.530 -}
134.531 -\isamarkuptrue%
134.532 -%
134.533 -\begin{isamarkuptext}%
134.534 -When functions are mutually recursive, proving properties about them
134.535 - generally requires simultaneous induction. The induction rule \isa{even{\isacharunderscore}odd{\isachardot}induct}
134.536 - generated from the above definition reflects this.
134.537 -
134.538 - Let us prove something about \isa{even} and \isa{odd}:%
134.539 -\end{isamarkuptext}%
134.540 -\isamarkuptrue%
134.541 -\isacommand{lemma}\isamarkupfalse%
134.542 -\ even{\isacharunderscore}odd{\isacharunderscore}mod{\isadigit{2}}{\isacharcolon}\isanewline
134.543 -\ \ {\isachardoublequoteopen}even\ n\ {\isacharequal}\ {\isacharparenleft}n\ mod\ {\isadigit{2}}\ {\isacharequal}\ {\isadigit{0}}{\isacharparenright}{\isachardoublequoteclose}\isanewline
134.544 -\ \ {\isachardoublequoteopen}odd\ n\ {\isacharequal}\ {\isacharparenleft}n\ mod\ {\isadigit{2}}\ {\isacharequal}\ {\isadigit{1}}{\isacharparenright}{\isachardoublequoteclose}%
134.545 -\isadelimproof
134.546 -%
134.547 -\endisadelimproof
134.548 -%
134.549 -\isatagproof
134.550 -%
134.551 -\begin{isamarkuptxt}%
134.552 -We apply simultaneous induction, specifying the induction variable
134.553 - for both goals, separated by \cmd{and}:%
134.554 -\end{isamarkuptxt}%
134.555 -\isamarkuptrue%
134.556 -\isacommand{apply}\isamarkupfalse%
134.557 -\ {\isacharparenleft}induct\ n\ \isakeyword{and}\ n\ rule{\isacharcolon}\ even{\isacharunderscore}odd{\isachardot}induct{\isacharparenright}%
134.558 -\begin{isamarkuptxt}%
134.559 -We get four subgoals, which correspond to the clauses in the
134.560 - definition of \isa{even} and \isa{odd}:
134.561 - \begin{isabelle}%
134.562 -\ {\isadigit{1}}{\isachardot}\ even\ {\isadigit{0}}\ {\isacharequal}\ {\isacharparenleft}{\isadigit{0}}\ mod\ {\isadigit{2}}\ {\isacharequal}\ {\isadigit{0}}{\isacharparenright}\isanewline
134.563 -\ {\isadigit{2}}{\isachardot}\ odd\ {\isadigit{0}}\ {\isacharequal}\ {\isacharparenleft}{\isadigit{0}}\ mod\ {\isadigit{2}}\ {\isacharequal}\ {\isadigit{1}}{\isacharparenright}\isanewline
134.564 -\ {\isadigit{3}}{\isachardot}\ {\isasymAnd}n{\isachardot}\ odd\ n\ {\isacharequal}\ {\isacharparenleft}n\ mod\ {\isadigit{2}}\ {\isacharequal}\ {\isadigit{1}}{\isacharparenright}\ {\isasymLongrightarrow}\ even\ {\isacharparenleft}Suc\ n{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}Suc\ n\ mod\ {\isadigit{2}}\ {\isacharequal}\ {\isadigit{0}}{\isacharparenright}\isanewline
134.565 -\ {\isadigit{4}}{\isachardot}\ {\isasymAnd}n{\isachardot}\ even\ n\ {\isacharequal}\ {\isacharparenleft}n\ mod\ {\isadigit{2}}\ {\isacharequal}\ {\isadigit{0}}{\isacharparenright}\ {\isasymLongrightarrow}\ odd\ {\isacharparenleft}Suc\ n{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}Suc\ n\ mod\ {\isadigit{2}}\ {\isacharequal}\ {\isadigit{1}}{\isacharparenright}%
134.566 -\end{isabelle}
134.567 - Simplification solves the first two goals, leaving us with two
134.568 - statements about the \isa{mod} operation to prove:%
134.569 -\end{isamarkuptxt}%
134.570 -\isamarkuptrue%
134.571 -\isacommand{apply}\isamarkupfalse%
134.572 -\ simp{\isacharunderscore}all%
134.573 -\begin{isamarkuptxt}%
134.574 -\begin{isabelle}%
134.575 -\ {\isadigit{1}}{\isachardot}\ {\isasymAnd}n{\isachardot}\ odd\ n\ {\isacharequal}\ {\isacharparenleft}n\ mod\ {\isadigit{2}}\ {\isacharequal}\ Suc\ {\isadigit{0}}{\isacharparenright}\ {\isasymLongrightarrow}\ {\isacharparenleft}n\ mod\ {\isadigit{2}}\ {\isacharequal}\ Suc\ {\isadigit{0}}{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}Suc\ n\ mod\ {\isadigit{2}}\ {\isacharequal}\ {\isadigit{0}}{\isacharparenright}\isanewline
134.576 -\ {\isadigit{2}}{\isachardot}\ {\isasymAnd}n{\isachardot}\ even\ n\ {\isacharequal}\ {\isacharparenleft}n\ mod\ {\isadigit{2}}\ {\isacharequal}\ {\isadigit{0}}{\isacharparenright}\ {\isasymLongrightarrow}\ {\isacharparenleft}n\ mod\ {\isadigit{2}}\ {\isacharequal}\ {\isadigit{0}}{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}Suc\ n\ mod\ {\isadigit{2}}\ {\isacharequal}\ Suc\ {\isadigit{0}}{\isacharparenright}%
134.577 -\end{isabelle}
134.578 -
134.579 - \noindent These can be handled by Isabelle's arithmetic decision procedures.%
134.580 -\end{isamarkuptxt}%
134.581 -\isamarkuptrue%
134.582 -\isacommand{apply}\isamarkupfalse%
134.583 -\ arith\isanewline
134.584 -\isacommand{apply}\isamarkupfalse%
134.585 -\ arith\isanewline
134.586 -\isacommand{done}\isamarkupfalse%
134.587 -%
134.588 -\endisatagproof
134.589 -{\isafoldproof}%
134.590 -%
134.591 -\isadelimproof
134.592 -%
134.593 -\endisadelimproof
134.594 -%
134.595 -\begin{isamarkuptext}%
134.596 -In proofs like this, the simultaneous induction is really essential:
134.597 - Even if we are just interested in one of the results, the other
134.598 - one is necessary to strengthen the induction hypothesis. If we leave
134.599 - out the statement about \isa{odd} and just write \isa{True} instead,
134.600 - the same proof fails:%
134.601 -\end{isamarkuptext}%
134.602 -\isamarkuptrue%
134.603 -\isacommand{lemma}\isamarkupfalse%
134.604 -\ failed{\isacharunderscore}attempt{\isacharcolon}\isanewline
134.605 -\ \ {\isachardoublequoteopen}even\ n\ {\isacharequal}\ {\isacharparenleft}n\ mod\ {\isadigit{2}}\ {\isacharequal}\ {\isadigit{0}}{\isacharparenright}{\isachardoublequoteclose}\isanewline
134.606 -\ \ {\isachardoublequoteopen}True{\isachardoublequoteclose}\isanewline
134.607 -%
134.608 -\isadelimproof
134.609 -%
134.610 -\endisadelimproof
134.611 -%
134.612 -\isatagproof
134.613 -\isacommand{apply}\isamarkupfalse%
134.614 -\ {\isacharparenleft}induct\ n\ rule{\isacharcolon}\ even{\isacharunderscore}odd{\isachardot}induct{\isacharparenright}%
134.615 -\begin{isamarkuptxt}%
134.616 -\noindent Now the third subgoal is a dead end, since we have no
134.617 - useful induction hypothesis available:
134.618 -
134.619 - \begin{isabelle}%
134.620 -\ {\isadigit{1}}{\isachardot}\ even\ {\isadigit{0}}\ {\isacharequal}\ {\isacharparenleft}{\isadigit{0}}\ mod\ {\isadigit{2}}\ {\isacharequal}\ {\isadigit{0}}{\isacharparenright}\isanewline
134.621 -\ {\isadigit{2}}{\isachardot}\ True\isanewline
134.622 -\ {\isadigit{3}}{\isachardot}\ {\isasymAnd}n{\isachardot}\ True\ {\isasymLongrightarrow}\ even\ {\isacharparenleft}Suc\ n{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}Suc\ n\ mod\ {\isadigit{2}}\ {\isacharequal}\ {\isadigit{0}}{\isacharparenright}\isanewline
134.623 -\ {\isadigit{4}}{\isachardot}\ {\isasymAnd}n{\isachardot}\ even\ n\ {\isacharequal}\ {\isacharparenleft}n\ mod\ {\isadigit{2}}\ {\isacharequal}\ {\isadigit{0}}{\isacharparenright}\ {\isasymLongrightarrow}\ True%
134.624 -\end{isabelle}%
134.625 -\end{isamarkuptxt}%
134.626 -\isamarkuptrue%
134.627 -\isacommand{oops}\isamarkupfalse%
134.628 -%
134.629 -\endisatagproof
134.630 -{\isafoldproof}%
134.631 -%
134.632 -\isadelimproof
134.633 -%
134.634 -\endisadelimproof
134.635 -%
134.636 -\isamarkupsection{General pattern matching%
134.637 -}
134.638 -\isamarkuptrue%
134.639 -%
134.640 -\begin{isamarkuptext}%
134.641 -\label{genpats}%
134.642 -\end{isamarkuptext}%
134.643 -\isamarkuptrue%
134.644 -%
134.645 -\isamarkupsubsection{Avoiding automatic pattern splitting%
134.646 -}
134.647 -\isamarkuptrue%
134.648 -%
134.649 -\begin{isamarkuptext}%
134.650 -Up to now, we used pattern matching only on datatypes, and the
134.651 - patterns were always disjoint and complete, and if they weren't,
134.652 - they were made disjoint automatically like in the definition of
134.653 - \isa{sep} in \S\ref{patmatch}.
134.654 -
134.655 - This automatic splitting can significantly increase the number of
134.656 - equations involved, and this is not always desirable. The following
134.657 - example shows the problem:
134.658 -
134.659 - Suppose we are modeling incomplete knowledge about the world by a
134.660 - three-valued datatype, which has values \isa{T}, \isa{F}
134.661 - and \isa{X} for true, false and uncertain propositions, respectively.%
134.662 -\end{isamarkuptext}%
134.663 -\isamarkuptrue%
134.664 -\isacommand{datatype}\isamarkupfalse%
134.665 -\ P{\isadigit{3}}\ {\isacharequal}\ T\ {\isacharbar}\ F\ {\isacharbar}\ X%
134.666 -\begin{isamarkuptext}%
134.667 -\noindent Then the conjunction of such values can be defined as follows:%
134.668 -\end{isamarkuptext}%
134.669 -\isamarkuptrue%
134.670 -\isacommand{fun}\isamarkupfalse%
134.671 -\ And\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}P{\isadigit{3}}\ {\isasymRightarrow}\ P{\isadigit{3}}\ {\isasymRightarrow}\ P{\isadigit{3}}{\isachardoublequoteclose}\isanewline
134.672 -\isakeyword{where}\isanewline
134.673 -\ \ {\isachardoublequoteopen}And\ T\ p\ {\isacharequal}\ p{\isachardoublequoteclose}\isanewline
134.674 -{\isacharbar}\ {\isachardoublequoteopen}And\ p\ T\ {\isacharequal}\ p{\isachardoublequoteclose}\isanewline
134.675 -{\isacharbar}\ {\isachardoublequoteopen}And\ p\ F\ {\isacharequal}\ F{\isachardoublequoteclose}\isanewline
134.676 -{\isacharbar}\ {\isachardoublequoteopen}And\ F\ p\ {\isacharequal}\ F{\isachardoublequoteclose}\isanewline
134.677 -{\isacharbar}\ {\isachardoublequoteopen}And\ X\ X\ {\isacharequal}\ X{\isachardoublequoteclose}%
134.678 -\begin{isamarkuptext}%
134.679 -This definition is useful, because the equations can directly be used
134.680 - as simplification rules. But the patterns overlap: For example,
134.681 - the expression \isa{And\ T\ T} is matched by both the first and
134.682 - the second equation. By default, Isabelle makes the patterns disjoint by
134.683 - splitting them up, producing instances:%
134.684 -\end{isamarkuptext}%
134.685 -\isamarkuptrue%
134.686 -\isacommand{thm}\isamarkupfalse%
134.687 -\ And{\isachardot}simps%
134.688 -\begin{isamarkuptext}%
134.689 -\isa{And\ T\ {\isacharquery}p\ {\isacharequal}\ {\isacharquery}p\isasep\isanewline%
134.690 -And\ F\ T\ {\isacharequal}\ F\isasep\isanewline%
134.691 -And\ X\ T\ {\isacharequal}\ X\isasep\isanewline%
134.692 -And\ F\ F\ {\isacharequal}\ F\isasep\isanewline%
134.693 -And\ X\ F\ {\isacharequal}\ F\isasep\isanewline%
134.694 -And\ F\ X\ {\isacharequal}\ F\isasep\isanewline%
134.695 -And\ X\ X\ {\isacharequal}\ X}
134.696 -
134.697 - \vspace*{1em}
134.698 - \noindent There are several problems with this:
134.699 -
134.700 - \begin{enumerate}
134.701 - \item If the datatype has many constructors, there can be an
134.702 - explosion of equations. For \isa{And}, we get seven instead of
134.703 - five equations, which can be tolerated, but this is just a small
134.704 - example.
134.705 -
134.706 - \item Since splitting makes the equations \qt{less general}, they
134.707 - do not always match in rewriting. While the term \isa{And\ x\ F}
134.708 - can be simplified to \isa{F} with the original equations, a
134.709 - (manual) case split on \isa{x} is now necessary.
134.710 -
134.711 - \item The splitting also concerns the induction rule \isa{And{\isachardot}induct}. Instead of five premises it now has seven, which
134.712 - means that our induction proofs will have more cases.
134.713 -
134.714 - \item In general, it increases clarity if we get the same definition
134.715 - back which we put in.
134.716 - \end{enumerate}
134.717 -
134.718 - If we do not want the automatic splitting, we can switch it off by
134.719 - leaving out the \cmd{sequential} option. However, we will have to
134.720 - prove that our pattern matching is consistent\footnote{This prevents
134.721 - us from defining something like \isa{f\ x\ {\isacharequal}\ True} and \isa{f\ x\ {\isacharequal}\ False} simultaneously.}:%
134.722 -\end{isamarkuptext}%
134.723 -\isamarkuptrue%
134.724 -\isacommand{function}\isamarkupfalse%
134.725 -\ And{\isadigit{2}}\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}P{\isadigit{3}}\ {\isasymRightarrow}\ P{\isadigit{3}}\ {\isasymRightarrow}\ P{\isadigit{3}}{\isachardoublequoteclose}\isanewline
134.726 -\isakeyword{where}\isanewline
134.727 -\ \ {\isachardoublequoteopen}And{\isadigit{2}}\ T\ p\ {\isacharequal}\ p{\isachardoublequoteclose}\isanewline
134.728 -{\isacharbar}\ {\isachardoublequoteopen}And{\isadigit{2}}\ p\ T\ {\isacharequal}\ p{\isachardoublequoteclose}\isanewline
134.729 -{\isacharbar}\ {\isachardoublequoteopen}And{\isadigit{2}}\ p\ F\ {\isacharequal}\ F{\isachardoublequoteclose}\isanewline
134.730 -{\isacharbar}\ {\isachardoublequoteopen}And{\isadigit{2}}\ F\ p\ {\isacharequal}\ F{\isachardoublequoteclose}\isanewline
134.731 -{\isacharbar}\ {\isachardoublequoteopen}And{\isadigit{2}}\ X\ X\ {\isacharequal}\ X{\isachardoublequoteclose}%
134.732 -\isadelimproof
134.733 -%
134.734 -\endisadelimproof
134.735 -%
134.736 -\isatagproof
134.737 -%
134.738 -\begin{isamarkuptxt}%
134.739 -\noindent Now let's look at the proof obligations generated by a
134.740 - function definition. In this case, they are:
134.741 -
134.742 - \begin{isabelle}%
134.743 -\ {\isadigit{1}}{\isachardot}\ {\isasymAnd}P\ x{\isachardot}\ {\isasymlbrakk}{\isasymAnd}p{\isachardot}\ x\ {\isacharequal}\ {\isacharparenleft}T{\isacharcomma}\ p{\isacharparenright}\ {\isasymLongrightarrow}\ P{\isacharsemicolon}\ {\isasymAnd}p{\isachardot}\ x\ {\isacharequal}\ {\isacharparenleft}p{\isacharcomma}\ T{\isacharparenright}\ {\isasymLongrightarrow}\ P{\isacharsemicolon}\ {\isasymAnd}p{\isachardot}\ x\ {\isacharequal}\ {\isacharparenleft}p{\isacharcomma}\ F{\isacharparenright}\ {\isasymLongrightarrow}\ P{\isacharsemicolon}\isanewline
134.744 -\isaindent{\ {\isadigit{1}}{\isachardot}\ {\isasymAnd}P\ x{\isachardot}\ \ }{\isasymAnd}p{\isachardot}\ x\ {\isacharequal}\ {\isacharparenleft}F{\isacharcomma}\ p{\isacharparenright}\ {\isasymLongrightarrow}\ P{\isacharsemicolon}\ x\ {\isacharequal}\ {\isacharparenleft}X{\isacharcomma}\ X{\isacharparenright}\ {\isasymLongrightarrow}\ P{\isasymrbrakk}\isanewline
134.745 -\isaindent{\ {\isadigit{1}}{\isachardot}\ {\isasymAnd}P\ x{\isachardot}\ }{\isasymLongrightarrow}\ P\isanewline
134.746 -\ {\isadigit{2}}{\isachardot}\ {\isasymAnd}p\ pa{\isachardot}\ {\isacharparenleft}T{\isacharcomma}\ p{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}T{\isacharcomma}\ pa{\isacharparenright}\ {\isasymLongrightarrow}\ p\ {\isacharequal}\ pa\isanewline
134.747 -\ {\isadigit{3}}{\isachardot}\ {\isasymAnd}p\ pa{\isachardot}\ {\isacharparenleft}T{\isacharcomma}\ p{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}pa{\isacharcomma}\ T{\isacharparenright}\ {\isasymLongrightarrow}\ p\ {\isacharequal}\ pa\isanewline
134.748 -\ {\isadigit{4}}{\isachardot}\ {\isasymAnd}p\ pa{\isachardot}\ {\isacharparenleft}T{\isacharcomma}\ p{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}pa{\isacharcomma}\ F{\isacharparenright}\ {\isasymLongrightarrow}\ p\ {\isacharequal}\ F\isanewline
134.749 -\ {\isadigit{5}}{\isachardot}\ {\isasymAnd}p\ pa{\isachardot}\ {\isacharparenleft}T{\isacharcomma}\ p{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}F{\isacharcomma}\ pa{\isacharparenright}\ {\isasymLongrightarrow}\ p\ {\isacharequal}\ F\isanewline
134.750 -\ {\isadigit{6}}{\isachardot}\ {\isasymAnd}p{\isachardot}\ {\isacharparenleft}T{\isacharcomma}\ p{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}X{\isacharcomma}\ X{\isacharparenright}\ {\isasymLongrightarrow}\ p\ {\isacharequal}\ X\isanewline
134.751 -\ {\isadigit{7}}{\isachardot}\ {\isasymAnd}p\ pa{\isachardot}\ {\isacharparenleft}p{\isacharcomma}\ T{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}pa{\isacharcomma}\ T{\isacharparenright}\ {\isasymLongrightarrow}\ p\ {\isacharequal}\ pa\isanewline
134.752 -\ {\isadigit{8}}{\isachardot}\ {\isasymAnd}p\ pa{\isachardot}\ {\isacharparenleft}p{\isacharcomma}\ T{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}pa{\isacharcomma}\ F{\isacharparenright}\ {\isasymLongrightarrow}\ p\ {\isacharequal}\ F\isanewline
134.753 -\ {\isadigit{9}}{\isachardot}\ {\isasymAnd}p\ pa{\isachardot}\ {\isacharparenleft}p{\isacharcomma}\ T{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}F{\isacharcomma}\ pa{\isacharparenright}\ {\isasymLongrightarrow}\ p\ {\isacharequal}\ F\isanewline
134.754 -\ {\isadigit{1}}{\isadigit{0}}{\isachardot}\ {\isasymAnd}p{\isachardot}\ {\isacharparenleft}p{\isacharcomma}\ T{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}X{\isacharcomma}\ X{\isacharparenright}\ {\isasymLongrightarrow}\ p\ {\isacharequal}\ X%
134.755 -\end{isabelle}\vspace{-1.2em}\hspace{3cm}\vdots\vspace{1.2em}
134.756 -
134.757 - The first subgoal expresses the completeness of the patterns. It has
134.758 - the form of an elimination rule and states that every \isa{x} of
134.759 - the function's input type must match at least one of the patterns\footnote{Completeness could
134.760 - be equivalently stated as a disjunction of existential statements:
134.761 -\isa{{\isacharparenleft}{\isasymexists}p{\isachardot}\ x\ {\isacharequal}\ {\isacharparenleft}T{\isacharcomma}\ p{\isacharparenright}{\isacharparenright}\ {\isasymor}\ {\isacharparenleft}{\isasymexists}p{\isachardot}\ x\ {\isacharequal}\ {\isacharparenleft}p{\isacharcomma}\ T{\isacharparenright}{\isacharparenright}\ {\isasymor}\ {\isacharparenleft}{\isasymexists}p{\isachardot}\ x\ {\isacharequal}\ {\isacharparenleft}p{\isacharcomma}\ F{\isacharparenright}{\isacharparenright}\ {\isasymor}\ {\isacharparenleft}{\isasymexists}p{\isachardot}\ x\ {\isacharequal}\ {\isacharparenleft}F{\isacharcomma}\ p{\isacharparenright}{\isacharparenright}\ {\isasymor}\ x\ {\isacharequal}\ {\isacharparenleft}X{\isacharcomma}\ X{\isacharparenright}}, and you can use the method \isa{atomize{\isacharunderscore}elim} to get that form instead.}. If the patterns just involve
134.762 - datatypes, we can solve it with the \isa{pat{\isacharunderscore}completeness}
134.763 - method:%
134.764 -\end{isamarkuptxt}%
134.765 -\isamarkuptrue%
134.766 -\isacommand{apply}\isamarkupfalse%
134.767 -\ pat{\isacharunderscore}completeness%
134.768 -\begin{isamarkuptxt}%
134.769 -The remaining subgoals express \emph{pattern compatibility}. We do
134.770 - allow that an input value matches multiple patterns, but in this
134.771 - case, the result (i.e.~the right hand sides of the equations) must
134.772 - also be equal. For each pair of two patterns, there is one such
134.773 - subgoal. Usually this needs injectivity of the constructors, which
134.774 - is used automatically by \isa{auto}.%
134.775 -\end{isamarkuptxt}%
134.776 -\isamarkuptrue%
134.777 -\isacommand{by}\isamarkupfalse%
134.778 -\ auto%
134.779 -\endisatagproof
134.780 -{\isafoldproof}%
134.781 -%
134.782 -\isadelimproof
134.783 -%
134.784 -\endisadelimproof
134.785 -%
134.786 -\isamarkupsubsection{Non-constructor patterns%
134.787 -}
134.788 -\isamarkuptrue%
134.789 -%
134.790 -\begin{isamarkuptext}%
134.791 -Most of Isabelle's basic types take the form of inductive datatypes,
134.792 - and usually pattern matching works on the constructors of such types.
134.793 - However, this need not be always the case, and the \cmd{function}
134.794 - command handles other kind of patterns, too.
134.795 -
134.796 - One well-known instance of non-constructor patterns are
134.797 - so-called \emph{$n+k$-patterns}, which are a little controversial in
134.798 - the functional programming world. Here is the initial fibonacci
134.799 - example with $n+k$-patterns:%
134.800 -\end{isamarkuptext}%
134.801 -\isamarkuptrue%
134.802 -\isacommand{function}\isamarkupfalse%
134.803 -\ fib{\isadigit{2}}\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymRightarrow}\ nat{\isachardoublequoteclose}\isanewline
134.804 -\isakeyword{where}\isanewline
134.805 -\ \ {\isachardoublequoteopen}fib{\isadigit{2}}\ {\isadigit{0}}\ {\isacharequal}\ {\isadigit{1}}{\isachardoublequoteclose}\isanewline
134.806 -{\isacharbar}\ {\isachardoublequoteopen}fib{\isadigit{2}}\ {\isadigit{1}}\ {\isacharequal}\ {\isadigit{1}}{\isachardoublequoteclose}\isanewline
134.807 -{\isacharbar}\ {\isachardoublequoteopen}fib{\isadigit{2}}\ {\isacharparenleft}n\ {\isacharplus}\ {\isadigit{2}}{\isacharparenright}\ {\isacharequal}\ fib{\isadigit{2}}\ n\ {\isacharplus}\ fib{\isadigit{2}}\ {\isacharparenleft}Suc\ n{\isacharparenright}{\isachardoublequoteclose}\isanewline
134.808 -%
134.809 -\isadelimML
134.810 -%
134.811 -\endisadelimML
134.812 -%
134.813 -\isatagML
134.814 -%
134.815 -\endisatagML
134.816 -{\isafoldML}%
134.817 -%
134.818 -\isadelimML
134.819 -%
134.820 -\endisadelimML
134.821 -%
134.822 -\isadelimproof
134.823 -%
134.824 -\endisadelimproof
134.825 -%
134.826 -\isatagproof
134.827 -%
134.828 -\begin{isamarkuptxt}%
134.829 -This kind of matching is again justified by the proof of pattern
134.830 - completeness and compatibility.
134.831 - The proof obligation for pattern completeness states that every natural number is
134.832 - either \isa{{\isadigit{0}}}, \isa{{\isadigit{1}}} or \isa{n\ {\isacharplus}\ {\isadigit{2}}}:
134.833 -
134.834 - \begin{isabelle}%
134.835 -\ {\isadigit{1}}{\isachardot}\ {\isasymAnd}P\ x{\isachardot}\ {\isasymlbrakk}x\ {\isacharequal}\ {\isadigit{0}}\ {\isasymLongrightarrow}\ P{\isacharsemicolon}\ x\ {\isacharequal}\ {\isadigit{1}}\ {\isasymLongrightarrow}\ P{\isacharsemicolon}\ {\isasymAnd}n{\isachardot}\ x\ {\isacharequal}\ n\ {\isacharplus}\ {\isadigit{2}}\ {\isasymLongrightarrow}\ P{\isasymrbrakk}\ {\isasymLongrightarrow}\ P\isanewline
134.836 -\ {\isadigit{2}}{\isachardot}\ {\isadigit{0}}\ {\isacharequal}\ {\isadigit{0}}\ {\isasymLongrightarrow}\ {\isadigit{1}}\ {\isacharequal}\ {\isadigit{1}}\isanewline
134.837 -\ {\isadigit{3}}{\isachardot}\ {\isadigit{0}}\ {\isacharequal}\ {\isadigit{1}}\ {\isasymLongrightarrow}\ {\isadigit{1}}\ {\isacharequal}\ {\isadigit{1}}\isanewline
134.838 -\ {\isadigit{4}}{\isachardot}\ {\isasymAnd}n{\isachardot}\ {\isadigit{0}}\ {\isacharequal}\ n\ {\isacharplus}\ {\isadigit{2}}\ {\isasymLongrightarrow}\ {\isadigit{1}}\ {\isacharequal}\ fib{\isadigit{2}}{\isacharunderscore}sumC\ n\ {\isacharplus}\ fib{\isadigit{2}}{\isacharunderscore}sumC\ {\isacharparenleft}Suc\ n{\isacharparenright}\isanewline
134.839 -\ {\isadigit{5}}{\isachardot}\ {\isadigit{1}}\ {\isacharequal}\ {\isadigit{1}}\ {\isasymLongrightarrow}\ {\isadigit{1}}\ {\isacharequal}\ {\isadigit{1}}\isanewline
134.840 -\ {\isadigit{6}}{\isachardot}\ {\isasymAnd}n{\isachardot}\ {\isadigit{1}}\ {\isacharequal}\ n\ {\isacharplus}\ {\isadigit{2}}\ {\isasymLongrightarrow}\ {\isadigit{1}}\ {\isacharequal}\ fib{\isadigit{2}}{\isacharunderscore}sumC\ n\ {\isacharplus}\ fib{\isadigit{2}}{\isacharunderscore}sumC\ {\isacharparenleft}Suc\ n{\isacharparenright}\isanewline
134.841 -\ {\isadigit{7}}{\isachardot}\ {\isasymAnd}n\ na{\isachardot}\isanewline
134.842 -\isaindent{\ {\isadigit{7}}{\isachardot}\ \ \ \ }n\ {\isacharplus}\ {\isadigit{2}}\ {\isacharequal}\ na\ {\isacharplus}\ {\isadigit{2}}\ {\isasymLongrightarrow}\isanewline
134.843 -\isaindent{\ {\isadigit{7}}{\isachardot}\ \ \ \ }fib{\isadigit{2}}{\isacharunderscore}sumC\ n\ {\isacharplus}\ fib{\isadigit{2}}{\isacharunderscore}sumC\ {\isacharparenleft}Suc\ n{\isacharparenright}\ {\isacharequal}\ fib{\isadigit{2}}{\isacharunderscore}sumC\ na\ {\isacharplus}\ fib{\isadigit{2}}{\isacharunderscore}sumC\ {\isacharparenleft}Suc\ na{\isacharparenright}%
134.844 -\end{isabelle}
134.845 -
134.846 - This is an arithmetic triviality, but unfortunately the
134.847 - \isa{arith} method cannot handle this specific form of an
134.848 - elimination rule. However, we can use the method \isa{atomize{\isacharunderscore}elim} to do an ad-hoc conversion to a disjunction of
134.849 - existentials, which can then be solved by the arithmetic decision procedure.
134.850 - Pattern compatibility and termination are automatic as usual.%
134.851 -\end{isamarkuptxt}%
134.852 -\isamarkuptrue%
134.853 -%
134.854 -\endisatagproof
134.855 -{\isafoldproof}%
134.856 -%
134.857 -\isadelimproof
134.858 -%
134.859 -\endisadelimproof
134.860 -%
134.861 -\isadelimML
134.862 -%
134.863 -\endisadelimML
134.864 -%
134.865 -\isatagML
134.866 -%
134.867 -\endisatagML
134.868 -{\isafoldML}%
134.869 -%
134.870 -\isadelimML
134.871 -%
134.872 -\endisadelimML
134.873 -%
134.874 -\isadelimproof
134.875 -%
134.876 -\endisadelimproof
134.877 -%
134.878 -\isatagproof
134.879 -\isacommand{apply}\isamarkupfalse%
134.880 -\ atomize{\isacharunderscore}elim\isanewline
134.881 -\isacommand{apply}\isamarkupfalse%
134.882 -\ arith\isanewline
134.883 -\isacommand{apply}\isamarkupfalse%
134.884 -\ auto\isanewline
134.885 -\isacommand{done}\isamarkupfalse%
134.886 -%
134.887 -\endisatagproof
134.888 -{\isafoldproof}%
134.889 -%
134.890 -\isadelimproof
134.891 -%
134.892 -\endisadelimproof
134.893 -\isanewline
134.894 -\isacommand{termination}\isamarkupfalse%
134.895 -%
134.896 -\isadelimproof
134.897 -\ %
134.898 -\endisadelimproof
134.899 -%
134.900 -\isatagproof
134.901 -\isacommand{by}\isamarkupfalse%
134.902 -\ lexicographic{\isacharunderscore}order%
134.903 -\endisatagproof
134.904 -{\isafoldproof}%
134.905 -%
134.906 -\isadelimproof
134.907 -%
134.908 -\endisadelimproof
134.909 -%
134.910 -\begin{isamarkuptext}%
134.911 -We can stretch the notion of pattern matching even more. The
134.912 - following function is not a sensible functional program, but a
134.913 - perfectly valid mathematical definition:%
134.914 -\end{isamarkuptext}%
134.915 -\isamarkuptrue%
134.916 -\isacommand{function}\isamarkupfalse%
134.917 -\ ev\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymRightarrow}\ bool{\isachardoublequoteclose}\isanewline
134.918 -\isakeyword{where}\isanewline
134.919 -\ \ {\isachardoublequoteopen}ev\ {\isacharparenleft}{\isadigit{2}}\ {\isacharasterisk}\ n{\isacharparenright}\ {\isacharequal}\ True{\isachardoublequoteclose}\isanewline
134.920 -{\isacharbar}\ {\isachardoublequoteopen}ev\ {\isacharparenleft}{\isadigit{2}}\ {\isacharasterisk}\ n\ {\isacharplus}\ {\isadigit{1}}{\isacharparenright}\ {\isacharequal}\ False{\isachardoublequoteclose}\isanewline
134.921 -%
134.922 -\isadelimproof
134.923 -%
134.924 -\endisadelimproof
134.925 -%
134.926 -\isatagproof
134.927 -\isacommand{apply}\isamarkupfalse%
134.928 -\ atomize{\isacharunderscore}elim\isanewline
134.929 -\isacommand{by}\isamarkupfalse%
134.930 -\ arith{\isacharplus}%
134.931 -\endisatagproof
134.932 -{\isafoldproof}%
134.933 -%
134.934 -\isadelimproof
134.935 -\isanewline
134.936 -%
134.937 -\endisadelimproof
134.938 -\isacommand{termination}\isamarkupfalse%
134.939 -%
134.940 -\isadelimproof
134.941 -\ %
134.942 -\endisadelimproof
134.943 -%
134.944 -\isatagproof
134.945 -\isacommand{by}\isamarkupfalse%
134.946 -\ {\isacharparenleft}relation\ {\isachardoublequoteopen}{\isacharbraceleft}{\isacharbraceright}{\isachardoublequoteclose}{\isacharparenright}\ simp%
134.947 -\endisatagproof
134.948 -{\isafoldproof}%
134.949 -%
134.950 -\isadelimproof
134.951 -%
134.952 -\endisadelimproof
134.953 -%
134.954 -\begin{isamarkuptext}%
134.955 -This general notion of pattern matching gives you a certain freedom
134.956 - in writing down specifications. However, as always, such freedom should
134.957 - be used with care:
134.958 -
134.959 - If we leave the area of constructor
134.960 - patterns, we have effectively departed from the world of functional
134.961 - programming. This means that it is no longer possible to use the
134.962 - code generator, and expect it to generate ML code for our
134.963 - definitions. Also, such a specification might not work very well together with
134.964 - simplification. Your mileage may vary.%
134.965 -\end{isamarkuptext}%
134.966 -\isamarkuptrue%
134.967 -%
134.968 -\isamarkupsubsection{Conditional equations%
134.969 -}
134.970 -\isamarkuptrue%
134.971 -%
134.972 -\begin{isamarkuptext}%
134.973 -The function package also supports conditional equations, which are
134.974 - similar to guards in a language like Haskell. Here is Euclid's
134.975 - algorithm written with conditional patterns\footnote{Note that the
134.976 - patterns are also overlapping in the base case}:%
134.977 -\end{isamarkuptext}%
134.978 -\isamarkuptrue%
134.979 -\isacommand{function}\isamarkupfalse%
134.980 -\ gcd\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymRightarrow}\ nat\ {\isasymRightarrow}\ nat{\isachardoublequoteclose}\isanewline
134.981 -\isakeyword{where}\isanewline
134.982 -\ \ {\isachardoublequoteopen}gcd\ x\ {\isadigit{0}}\ {\isacharequal}\ x{\isachardoublequoteclose}\isanewline
134.983 -{\isacharbar}\ {\isachardoublequoteopen}gcd\ {\isadigit{0}}\ y\ {\isacharequal}\ y{\isachardoublequoteclose}\isanewline
134.984 -{\isacharbar}\ {\isachardoublequoteopen}x\ {\isacharless}\ y\ {\isasymLongrightarrow}\ gcd\ {\isacharparenleft}Suc\ x{\isacharparenright}\ {\isacharparenleft}Suc\ y{\isacharparenright}\ {\isacharequal}\ gcd\ {\isacharparenleft}Suc\ x{\isacharparenright}\ {\isacharparenleft}y\ {\isacharminus}\ x{\isacharparenright}{\isachardoublequoteclose}\isanewline
134.985 -{\isacharbar}\ {\isachardoublequoteopen}{\isasymnot}\ x\ {\isacharless}\ y\ {\isasymLongrightarrow}\ gcd\ {\isacharparenleft}Suc\ x{\isacharparenright}\ {\isacharparenleft}Suc\ y{\isacharparenright}\ {\isacharequal}\ gcd\ {\isacharparenleft}x\ {\isacharminus}\ y{\isacharparenright}\ {\isacharparenleft}Suc\ y{\isacharparenright}{\isachardoublequoteclose}\isanewline
134.986 -%
134.987 -\isadelimproof
134.988 -%
134.989 -\endisadelimproof
134.990 -%
134.991 -\isatagproof
134.992 -\isacommand{by}\isamarkupfalse%
134.993 -\ {\isacharparenleft}atomize{\isacharunderscore}elim{\isacharcomma}\ auto{\isacharcomma}\ arith{\isacharparenright}%
134.994 -\endisatagproof
134.995 -{\isafoldproof}%
134.996 -%
134.997 -\isadelimproof
134.998 -\isanewline
134.999 -%
134.1000 -\endisadelimproof
134.1001 -\isacommand{termination}\isamarkupfalse%
134.1002 -%
134.1003 -\isadelimproof
134.1004 -\ %
134.1005 -\endisadelimproof
134.1006 -%
134.1007 -\isatagproof
134.1008 -\isacommand{by}\isamarkupfalse%
134.1009 -\ lexicographic{\isacharunderscore}order%
134.1010 -\endisatagproof
134.1011 -{\isafoldproof}%
134.1012 -%
134.1013 -\isadelimproof
134.1014 -%
134.1015 -\endisadelimproof
134.1016 -%
134.1017 -\begin{isamarkuptext}%
134.1018 -By now, you can probably guess what the proof obligations for the
134.1019 - pattern completeness and compatibility look like.
134.1020 -
134.1021 - Again, functions with conditional patterns are not supported by the
134.1022 - code generator.%
134.1023 -\end{isamarkuptext}%
134.1024 -\isamarkuptrue%
134.1025 -%
134.1026 -\isamarkupsubsection{Pattern matching on strings%
134.1027 -}
134.1028 -\isamarkuptrue%
134.1029 -%
134.1030 -\begin{isamarkuptext}%
134.1031 -As strings (as lists of characters) are normal datatypes, pattern
134.1032 - matching on them is possible, but somewhat problematic. Consider the
134.1033 - following definition:
134.1034 -
134.1035 -\end{isamarkuptext}
134.1036 -\noindent\cmd{fun} \isa{check\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequote}string\ {\isasymRightarrow}\ bool{\isachardoublequote}}\\%
134.1037 -\cmd{where}\\%
134.1038 -\hspace*{2ex}\isa{{\isachardoublequote}check\ {\isacharparenleft}{\isacharprime}{\isacharprime}good{\isacharprime}{\isacharprime}{\isacharparenright}\ {\isacharequal}\ True{\isachardoublequote}}\\%
134.1039 -\isa{{\isacharbar}\ {\isachardoublequote}check\ s\ {\isacharequal}\ False{\isachardoublequote}}
134.1040 -\begin{isamarkuptext}
134.1041 -
134.1042 - \noindent An invocation of the above \cmd{fun} command does not
134.1043 - terminate. What is the problem? Strings are lists of characters, and
134.1044 - characters are a datatype with a lot of constructors. Splitting the
134.1045 - catch-all pattern thus leads to an explosion of cases, which cannot
134.1046 - be handled by Isabelle.
134.1047 -
134.1048 - There are two things we can do here. Either we write an explicit
134.1049 - \isa{if} on the right hand side, or we can use conditional patterns:%
134.1050 -\end{isamarkuptext}%
134.1051 -\isamarkuptrue%
134.1052 -\isacommand{function}\isamarkupfalse%
134.1053 -\ check\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}string\ {\isasymRightarrow}\ bool{\isachardoublequoteclose}\isanewline
134.1054 -\isakeyword{where}\isanewline
134.1055 -\ \ {\isachardoublequoteopen}check\ {\isacharparenleft}{\isacharprime}{\isacharprime}good{\isacharprime}{\isacharprime}{\isacharparenright}\ {\isacharequal}\ True{\isachardoublequoteclose}\isanewline
134.1056 -{\isacharbar}\ {\isachardoublequoteopen}s\ {\isasymnoteq}\ {\isacharprime}{\isacharprime}good{\isacharprime}{\isacharprime}\ {\isasymLongrightarrow}\ check\ s\ {\isacharequal}\ False{\isachardoublequoteclose}\isanewline
134.1057 -%
134.1058 -\isadelimproof
134.1059 -%
134.1060 -\endisadelimproof
134.1061 -%
134.1062 -\isatagproof
134.1063 -\isacommand{by}\isamarkupfalse%
134.1064 -\ auto%
134.1065 -\endisatagproof
134.1066 -{\isafoldproof}%
134.1067 -%
134.1068 -\isadelimproof
134.1069 -%
134.1070 -\endisadelimproof
134.1071 -%
134.1072 -\isamarkupsection{Partiality%
134.1073 -}
134.1074 -\isamarkuptrue%
134.1075 -%
134.1076 -\begin{isamarkuptext}%
134.1077 -In HOL, all functions are total. A function \isa{f} applied to
134.1078 - \isa{x} always has the value \isa{f\ x}, and there is no notion
134.1079 - of undefinedness.
134.1080 - This is why we have to do termination
134.1081 - proofs when defining functions: The proof justifies that the
134.1082 - function can be defined by wellfounded recursion.
134.1083 -
134.1084 - However, the \cmd{function} package does support partiality to a
134.1085 - certain extent. Let's look at the following function which looks
134.1086 - for a zero of a given function f.%
134.1087 -\end{isamarkuptext}%
134.1088 -\isamarkuptrue%
134.1089 -\isacommand{function}\isamarkupfalse%
134.1090 -\ findzero\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharparenleft}nat\ {\isasymRightarrow}\ nat{\isacharparenright}\ {\isasymRightarrow}\ nat\ {\isasymRightarrow}\ nat{\isachardoublequoteclose}\isanewline
134.1091 -\isakeyword{where}\isanewline
134.1092 -\ \ {\isachardoublequoteopen}findzero\ f\ n\ {\isacharequal}\ {\isacharparenleft}if\ f\ n\ {\isacharequal}\ {\isadigit{0}}\ then\ n\ else\ findzero\ f\ {\isacharparenleft}Suc\ n{\isacharparenright}{\isacharparenright}{\isachardoublequoteclose}\isanewline
134.1093 -%
134.1094 -\isadelimproof
134.1095 -%
134.1096 -\endisadelimproof
134.1097 -%
134.1098 -\isatagproof
134.1099 -\isacommand{by}\isamarkupfalse%
134.1100 -\ pat{\isacharunderscore}completeness\ auto%
134.1101 -\endisatagproof
134.1102 -{\isafoldproof}%
134.1103 -%
134.1104 -\isadelimproof
134.1105 -%
134.1106 -\endisadelimproof
134.1107 -%
134.1108 -\begin{isamarkuptext}%
134.1109 -\noindent Clearly, any attempt of a termination proof must fail. And without
134.1110 - that, we do not get the usual rules \isa{findzero{\isachardot}simp} and
134.1111 - \isa{findzero{\isachardot}induct}. So what was the definition good for at all?%
134.1112 -\end{isamarkuptext}%
134.1113 -\isamarkuptrue%
134.1114 -%
134.1115 -\isamarkupsubsection{Domain predicates%
134.1116 -}
134.1117 -\isamarkuptrue%
134.1118 -%
134.1119 -\begin{isamarkuptext}%
134.1120 -The trick is that Isabelle has not only defined the function \isa{findzero}, but also
134.1121 - a predicate \isa{findzero{\isacharunderscore}dom} that characterizes the values where the function
134.1122 - terminates: the \emph{domain} of the function. If we treat a
134.1123 - partial function just as a total function with an additional domain
134.1124 - predicate, we can derive simplification and
134.1125 - induction rules as we do for total functions. They are guarded
134.1126 - by domain conditions and are called \isa{psimps} and \isa{pinduct}:%
134.1127 -\end{isamarkuptext}%
134.1128 -\isamarkuptrue%
134.1129 -%
134.1130 -\begin{isamarkuptext}%
134.1131 -\noindent\begin{minipage}{0.79\textwidth}\begin{isabelle}%
134.1132 -findzero{\isacharunderscore}dom\ {\isacharparenleft}{\isacharquery}f{\isacharcomma}\ {\isacharquery}n{\isacharparenright}\ {\isasymLongrightarrow}\isanewline
134.1133 -findzero\ {\isacharquery}f\ {\isacharquery}n\ {\isacharequal}\ {\isacharparenleft}if\ {\isacharquery}f\ {\isacharquery}n\ {\isacharequal}\ {\isadigit{0}}\ then\ {\isacharquery}n\ else\ findzero\ {\isacharquery}f\ {\isacharparenleft}Suc\ {\isacharquery}n{\isacharparenright}{\isacharparenright}%
134.1134 -\end{isabelle}\end{minipage}
134.1135 - \hfill(\isa{findzero{\isachardot}psimps})
134.1136 - \vspace{1em}
134.1137 -
134.1138 - \noindent\begin{minipage}{0.79\textwidth}\begin{isabelle}%
134.1139 -{\isasymlbrakk}findzero{\isacharunderscore}dom\ {\isacharparenleft}{\isacharquery}a{\isadigit{0}}{\isachardot}{\isadigit{0}}{\isacharcomma}\ {\isacharquery}a{\isadigit{1}}{\isachardot}{\isadigit{0}}{\isacharparenright}{\isacharsemicolon}\isanewline
134.1140 -\isaindent{\ }{\isasymAnd}f\ n{\isachardot}\ {\isasymlbrakk}findzero{\isacharunderscore}dom\ {\isacharparenleft}f{\isacharcomma}\ n{\isacharparenright}{\isacharsemicolon}\ f\ n\ {\isasymnoteq}\ {\isadigit{0}}\ {\isasymLongrightarrow}\ {\isacharquery}P\ f\ {\isacharparenleft}Suc\ n{\isacharparenright}{\isasymrbrakk}\ {\isasymLongrightarrow}\ {\isacharquery}P\ f\ n{\isasymrbrakk}\isanewline
134.1141 -{\isasymLongrightarrow}\ {\isacharquery}P\ {\isacharquery}a{\isadigit{0}}{\isachardot}{\isadigit{0}}\ {\isacharquery}a{\isadigit{1}}{\isachardot}{\isadigit{0}}%
134.1142 -\end{isabelle}\end{minipage}
134.1143 - \hfill(\isa{findzero{\isachardot}pinduct})%
134.1144 -\end{isamarkuptext}%
134.1145 -\isamarkuptrue%
134.1146 -%
134.1147 -\begin{isamarkuptext}%
134.1148 -Remember that all we
134.1149 - are doing here is use some tricks to make a total function appear
134.1150 - as if it was partial. We can still write the term \isa{findzero\ {\isacharparenleft}{\isasymlambda}x{\isachardot}\ {\isadigit{1}}{\isacharparenright}\ {\isadigit{0}}} and like any other term of type \isa{nat} it is equal
134.1151 - to some natural number, although we might not be able to find out
134.1152 - which one. The function is \emph{underdefined}.
134.1153 -
134.1154 - But it is defined enough to prove something interesting about it. We
134.1155 - can prove that if \isa{findzero\ f\ n}
134.1156 - terminates, it indeed returns a zero of \isa{f}:%
134.1157 -\end{isamarkuptext}%
134.1158 -\isamarkuptrue%
134.1159 -\isacommand{lemma}\isamarkupfalse%
134.1160 -\ findzero{\isacharunderscore}zero{\isacharcolon}\ {\isachardoublequoteopen}findzero{\isacharunderscore}dom\ {\isacharparenleft}f{\isacharcomma}\ n{\isacharparenright}\ {\isasymLongrightarrow}\ f\ {\isacharparenleft}findzero\ f\ n{\isacharparenright}\ {\isacharequal}\ {\isadigit{0}}{\isachardoublequoteclose}%
134.1161 -\isadelimproof
134.1162 -%
134.1163 -\endisadelimproof
134.1164 -%
134.1165 -\isatagproof
134.1166 -%
134.1167 -\begin{isamarkuptxt}%
134.1168 -\noindent We apply induction as usual, but using the partial induction
134.1169 - rule:%
134.1170 -\end{isamarkuptxt}%
134.1171 -\isamarkuptrue%
134.1172 -\isacommand{apply}\isamarkupfalse%
134.1173 -\ {\isacharparenleft}induct\ f\ n\ rule{\isacharcolon}\ findzero{\isachardot}pinduct{\isacharparenright}%
134.1174 -\begin{isamarkuptxt}%
134.1175 -\noindent This gives the following subgoals:
134.1176 -
134.1177 - \begin{isabelle}%
134.1178 -\ {\isadigit{1}}{\isachardot}\ {\isasymAnd}f\ n{\isachardot}\ {\isasymlbrakk}findzero{\isacharunderscore}dom\ {\isacharparenleft}f{\isacharcomma}\ n{\isacharparenright}{\isacharsemicolon}\ f\ n\ {\isasymnoteq}\ {\isadigit{0}}\ {\isasymLongrightarrow}\ f\ {\isacharparenleft}findzero\ f\ {\isacharparenleft}Suc\ n{\isacharparenright}{\isacharparenright}\ {\isacharequal}\ {\isadigit{0}}{\isasymrbrakk}\isanewline
134.1179 -\isaindent{\ {\isadigit{1}}{\isachardot}\ {\isasymAnd}f\ n{\isachardot}\ }{\isasymLongrightarrow}\ f\ {\isacharparenleft}findzero\ f\ n{\isacharparenright}\ {\isacharequal}\ {\isadigit{0}}%
134.1180 -\end{isabelle}
134.1181 -
134.1182 - \noindent The hypothesis in our lemma was used to satisfy the first premise in
134.1183 - the induction rule. However, we also get \isa{findzero{\isacharunderscore}dom\ {\isacharparenleft}f{\isacharcomma}\ n{\isacharparenright}} as a local assumption in the induction step. This
134.1184 - allows to unfold \isa{findzero\ f\ n} using the \isa{psimps}
134.1185 - rule, and the rest is trivial. Since the \isa{psimps} rules carry the
134.1186 - \isa{{\isacharbrackleft}simp{\isacharbrackright}} attribute by default, we just need a single step:%
134.1187 -\end{isamarkuptxt}%
134.1188 -\isamarkuptrue%
134.1189 -\isacommand{apply}\isamarkupfalse%
134.1190 -\ simp\isanewline
134.1191 -\isacommand{done}\isamarkupfalse%
134.1192 -%
134.1193 -\endisatagproof
134.1194 -{\isafoldproof}%
134.1195 -%
134.1196 -\isadelimproof
134.1197 -%
134.1198 -\endisadelimproof
134.1199 -%
134.1200 -\begin{isamarkuptext}%
134.1201 -Proofs about partial functions are often not harder than for total
134.1202 - functions. Fig.~\ref{findzero_isar} shows a slightly more
134.1203 - complicated proof written in Isar. It is verbose enough to show how
134.1204 - partiality comes into play: From the partial induction, we get an
134.1205 - additional domain condition hypothesis. Observe how this condition
134.1206 - is applied when calls to \isa{findzero} are unfolded.%
134.1207 -\end{isamarkuptext}%
134.1208 -\isamarkuptrue%
134.1209 -%
134.1210 -\begin{figure}
134.1211 -\hrule\vspace{6pt}
134.1212 -\begin{minipage}{0.8\textwidth}
134.1213 -\isabellestyle{it}
134.1214 -\isastyle\isamarkuptrue
134.1215 -\isacommand{lemma}\isamarkupfalse%
134.1216 -\ {\isachardoublequoteopen}{\isasymlbrakk}findzero{\isacharunderscore}dom\ {\isacharparenleft}f{\isacharcomma}\ n{\isacharparenright}{\isacharsemicolon}\ x\ {\isasymin}\ {\isacharbraceleft}n\ {\isachardot}{\isachardot}{\isacharless}\ findzero\ f\ n{\isacharbraceright}{\isasymrbrakk}\ {\isasymLongrightarrow}\ f\ x\ {\isasymnoteq}\ {\isadigit{0}}{\isachardoublequoteclose}\isanewline
134.1217 -%
134.1218 -\isadelimproof
134.1219 -%
134.1220 -\endisadelimproof
134.1221 -%
134.1222 -\isatagproof
134.1223 -\isacommand{proof}\isamarkupfalse%
134.1224 -\ {\isacharparenleft}induct\ rule{\isacharcolon}\ findzero{\isachardot}pinduct{\isacharparenright}\isanewline
134.1225 -\ \ \isacommand{fix}\isamarkupfalse%
134.1226 -\ f\ n\ \isacommand{assume}\isamarkupfalse%
134.1227 -\ dom{\isacharcolon}\ {\isachardoublequoteopen}findzero{\isacharunderscore}dom\ {\isacharparenleft}f{\isacharcomma}\ n{\isacharparenright}{\isachardoublequoteclose}\isanewline
134.1228 -\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \isakeyword{and}\ IH{\isacharcolon}\ {\isachardoublequoteopen}{\isasymlbrakk}f\ n\ {\isasymnoteq}\ {\isadigit{0}}{\isacharsemicolon}\ x\ {\isasymin}\ {\isacharbraceleft}Suc\ n\ {\isachardot}{\isachardot}{\isacharless}\ findzero\ f\ {\isacharparenleft}Suc\ n{\isacharparenright}{\isacharbraceright}{\isasymrbrakk}\ {\isasymLongrightarrow}\ f\ x\ {\isasymnoteq}\ {\isadigit{0}}{\isachardoublequoteclose}\isanewline
134.1229 -\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \isakeyword{and}\ x{\isacharunderscore}range{\isacharcolon}\ {\isachardoublequoteopen}x\ {\isasymin}\ {\isacharbraceleft}n\ {\isachardot}{\isachardot}{\isacharless}\ findzero\ f\ n{\isacharbraceright}{\isachardoublequoteclose}\isanewline
134.1230 -\ \ \isacommand{have}\isamarkupfalse%
134.1231 -\ {\isachardoublequoteopen}f\ n\ {\isasymnoteq}\ {\isadigit{0}}{\isachardoublequoteclose}\isanewline
134.1232 -\ \ \isacommand{proof}\isamarkupfalse%
134.1233 -\ \isanewline
134.1234 -\ \ \ \ \isacommand{assume}\isamarkupfalse%
134.1235 -\ {\isachardoublequoteopen}f\ n\ {\isacharequal}\ {\isadigit{0}}{\isachardoublequoteclose}\isanewline
134.1236 -\ \ \ \ \isacommand{with}\isamarkupfalse%
134.1237 -\ dom\ \isacommand{have}\isamarkupfalse%
134.1238 -\ {\isachardoublequoteopen}findzero\ f\ n\ {\isacharequal}\ n{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse%
134.1239 -\ simp\isanewline
134.1240 -\ \ \ \ \isacommand{with}\isamarkupfalse%
134.1241 -\ x{\isacharunderscore}range\ \isacommand{show}\isamarkupfalse%
134.1242 -\ False\ \isacommand{by}\isamarkupfalse%
134.1243 -\ auto\isanewline
134.1244 -\ \ \isacommand{qed}\isamarkupfalse%
134.1245 -\isanewline
134.1246 -\ \ \isanewline
134.1247 -\ \ \isacommand{from}\isamarkupfalse%
134.1248 -\ x{\isacharunderscore}range\ \isacommand{have}\isamarkupfalse%
134.1249 -\ {\isachardoublequoteopen}x\ {\isacharequal}\ n\ {\isasymor}\ x\ {\isasymin}\ {\isacharbraceleft}Suc\ n\ {\isachardot}{\isachardot}{\isacharless}\ findzero\ f\ n{\isacharbraceright}{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse%
134.1250 -\ auto\isanewline
134.1251 -\ \ \isacommand{thus}\isamarkupfalse%
134.1252 -\ {\isachardoublequoteopen}f\ x\ {\isasymnoteq}\ {\isadigit{0}}{\isachardoublequoteclose}\isanewline
134.1253 -\ \ \isacommand{proof}\isamarkupfalse%
134.1254 -\isanewline
134.1255 -\ \ \ \ \isacommand{assume}\isamarkupfalse%
134.1256 -\ {\isachardoublequoteopen}x\ {\isacharequal}\ n{\isachardoublequoteclose}\isanewline
134.1257 -\ \ \ \ \isacommand{with}\isamarkupfalse%
134.1258 -\ {\isacharbackquoteopen}f\ n\ {\isasymnoteq}\ {\isadigit{0}}{\isacharbackquoteclose}\ \isacommand{show}\isamarkupfalse%
134.1259 -\ {\isacharquery}thesis\ \isacommand{by}\isamarkupfalse%
134.1260 -\ simp\isanewline
134.1261 -\ \ \isacommand{next}\isamarkupfalse%
134.1262 -\isanewline
134.1263 -\ \ \ \ \isacommand{assume}\isamarkupfalse%
134.1264 -\ {\isachardoublequoteopen}x\ {\isasymin}\ {\isacharbraceleft}Suc\ n\ {\isachardot}{\isachardot}{\isacharless}\ findzero\ f\ n{\isacharbraceright}{\isachardoublequoteclose}\isanewline
134.1265 -\ \ \ \ \isacommand{with}\isamarkupfalse%
134.1266 -\ dom\ \isakeyword{and}\ {\isacharbackquoteopen}f\ n\ {\isasymnoteq}\ {\isadigit{0}}{\isacharbackquoteclose}\ \isacommand{have}\isamarkupfalse%
134.1267 -\ {\isachardoublequoteopen}x\ {\isasymin}\ {\isacharbraceleft}Suc\ n\ {\isachardot}{\isachardot}{\isacharless}\ findzero\ f\ {\isacharparenleft}Suc\ n{\isacharparenright}{\isacharbraceright}{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse%
134.1268 -\ simp\isanewline
134.1269 -\ \ \ \ \isacommand{with}\isamarkupfalse%
134.1270 -\ IH\ \isakeyword{and}\ {\isacharbackquoteopen}f\ n\ {\isasymnoteq}\ {\isadigit{0}}{\isacharbackquoteclose}\isanewline
134.1271 -\ \ \ \ \isacommand{show}\isamarkupfalse%
134.1272 -\ {\isacharquery}thesis\ \isacommand{by}\isamarkupfalse%
134.1273 -\ simp\isanewline
134.1274 -\ \ \isacommand{qed}\isamarkupfalse%
134.1275 -\isanewline
134.1276 -\isacommand{qed}\isamarkupfalse%
134.1277 -%
134.1278 -\endisatagproof
134.1279 -{\isafoldproof}%
134.1280 -%
134.1281 -\isadelimproof
134.1282 -%
134.1283 -\endisadelimproof
134.1284 -%
134.1285 -\isamarkupfalse\isabellestyle{tt}
134.1286 -\end{minipage}\vspace{6pt}\hrule
134.1287 -\caption{A proof about a partial function}\label{findzero_isar}
134.1288 -\end{figure}
134.1289 -%
134.1290 -\isamarkupsubsection{Partial termination proofs%
134.1291 -}
134.1292 -\isamarkuptrue%
134.1293 -%
134.1294 -\begin{isamarkuptext}%
134.1295 -Now that we have proved some interesting properties about our
134.1296 - function, we should turn to the domain predicate and see if it is
134.1297 - actually true for some values. Otherwise we would have just proved
134.1298 - lemmas with \isa{False} as a premise.
134.1299 -
134.1300 - Essentially, we need some introduction rules for \isa{findzero{\isacharunderscore}dom}. The function package can prove such domain
134.1301 - introduction rules automatically. But since they are not used very
134.1302 - often (they are almost never needed if the function is total), this
134.1303 - functionality is disabled by default for efficiency reasons. So we have to go
134.1304 - back and ask for them explicitly by passing the \isa{{\isacharparenleft}domintros{\isacharparenright}} option to the function package:
134.1305 -
134.1306 -\vspace{1ex}
134.1307 -\noindent\cmd{function} \isa{{\isacharparenleft}domintros{\isacharparenright}\ findzero\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequote}{\isacharparenleft}nat\ {\isasymRightarrow}\ nat{\isacharparenright}\ {\isasymRightarrow}\ nat\ {\isasymRightarrow}\ nat{\isachardoublequote}}\\%
134.1308 -\cmd{where}\isanewline%
134.1309 -\ \ \ldots\\
134.1310 -
134.1311 - \noindent Now the package has proved an introduction rule for \isa{findzero{\isacharunderscore}dom}:%
134.1312 -\end{isamarkuptext}%
134.1313 -\isamarkuptrue%
134.1314 -\isacommand{thm}\isamarkupfalse%
134.1315 -\ findzero{\isachardot}domintros%
134.1316 -\begin{isamarkuptext}%
134.1317 -\begin{isabelle}%
134.1318 -{\isacharparenleft}{\isadigit{0}}\ {\isacharless}\ {\isacharquery}f\ {\isacharquery}n\ {\isasymLongrightarrow}\ findzero{\isacharunderscore}dom\ {\isacharparenleft}{\isacharquery}f{\isacharcomma}\ Suc\ {\isacharquery}n{\isacharparenright}{\isacharparenright}\ {\isasymLongrightarrow}\ findzero{\isacharunderscore}dom\ {\isacharparenleft}{\isacharquery}f{\isacharcomma}\ {\isacharquery}n{\isacharparenright}%
134.1319 -\end{isabelle}
134.1320 -
134.1321 - Domain introduction rules allow to show that a given value lies in the
134.1322 - domain of a function, if the arguments of all recursive calls
134.1323 - are in the domain as well. They allow to do a \qt{single step} in a
134.1324 - termination proof. Usually, you want to combine them with a suitable
134.1325 - induction principle.
134.1326 -
134.1327 - Since our function increases its argument at recursive calls, we
134.1328 - need an induction principle which works \qt{backwards}. We will use
134.1329 - \isa{inc{\isacharunderscore}induct}, which allows to do induction from a fixed number
134.1330 - \qt{downwards}:
134.1331 -
134.1332 - \begin{center}\isa{{\isasymlbrakk}{\isacharquery}i\ {\isasymle}\ {\isacharquery}j{\isacharsemicolon}\ {\isacharquery}P\ {\isacharquery}j{\isacharsemicolon}\ {\isasymAnd}i{\isachardot}\ {\isasymlbrakk}i\ {\isacharless}\ {\isacharquery}j{\isacharsemicolon}\ {\isacharquery}P\ {\isacharparenleft}Suc\ i{\isacharparenright}{\isasymrbrakk}\ {\isasymLongrightarrow}\ {\isacharquery}P\ i{\isasymrbrakk}\ {\isasymLongrightarrow}\ {\isacharquery}P\ {\isacharquery}i}\hfill(\isa{inc{\isacharunderscore}induct})\end{center}
134.1333 -
134.1334 - Figure \ref{findzero_term} gives a detailed Isar proof of the fact
134.1335 - that \isa{findzero} terminates if there is a zero which is greater
134.1336 - or equal to \isa{n}. First we derive two useful rules which will
134.1337 - solve the base case and the step case of the induction. The
134.1338 - induction is then straightforward, except for the unusual induction
134.1339 - principle.%
134.1340 -\end{isamarkuptext}%
134.1341 -\isamarkuptrue%
134.1342 -%
134.1343 -\begin{figure}
134.1344 -\hrule\vspace{6pt}
134.1345 -\begin{minipage}{0.8\textwidth}
134.1346 -\isabellestyle{it}
134.1347 -\isastyle\isamarkuptrue
134.1348 -\isacommand{lemma}\isamarkupfalse%
134.1349 -\ findzero{\isacharunderscore}termination{\isacharcolon}\isanewline
134.1350 -\ \ \isakeyword{assumes}\ {\isachardoublequoteopen}x\ {\isasymge}\ n{\isachardoublequoteclose}\ \isakeyword{and}\ {\isachardoublequoteopen}f\ x\ {\isacharequal}\ {\isadigit{0}}{\isachardoublequoteclose}\isanewline
134.1351 -\ \ \isakeyword{shows}\ {\isachardoublequoteopen}findzero{\isacharunderscore}dom\ {\isacharparenleft}f{\isacharcomma}\ n{\isacharparenright}{\isachardoublequoteclose}\isanewline
134.1352 -%
134.1353 -\isadelimproof
134.1354 -%
134.1355 -\endisadelimproof
134.1356 -%
134.1357 -\isatagproof
134.1358 -\isacommand{proof}\isamarkupfalse%
134.1359 -\ {\isacharminus}\ \isanewline
134.1360 -\ \ \isacommand{have}\isamarkupfalse%
134.1361 -\ base{\isacharcolon}\ {\isachardoublequoteopen}findzero{\isacharunderscore}dom\ {\isacharparenleft}f{\isacharcomma}\ x{\isacharparenright}{\isachardoublequoteclose}\isanewline
134.1362 -\ \ \ \ \isacommand{by}\isamarkupfalse%
134.1363 -\ {\isacharparenleft}rule\ findzero{\isachardot}domintros{\isacharparenright}\ {\isacharparenleft}simp\ add{\isacharcolon}{\isacharbackquoteopen}f\ x\ {\isacharequal}\ {\isadigit{0}}{\isacharbackquoteclose}{\isacharparenright}\isanewline
134.1364 -\isanewline
134.1365 -\ \ \isacommand{have}\isamarkupfalse%
134.1366 -\ step{\isacharcolon}\ {\isachardoublequoteopen}{\isasymAnd}i{\isachardot}\ findzero{\isacharunderscore}dom\ {\isacharparenleft}f{\isacharcomma}\ Suc\ i{\isacharparenright}\ \isanewline
134.1367 -\ \ \ \ {\isasymLongrightarrow}\ findzero{\isacharunderscore}dom\ {\isacharparenleft}f{\isacharcomma}\ i{\isacharparenright}{\isachardoublequoteclose}\isanewline
134.1368 -\ \ \ \ \isacommand{by}\isamarkupfalse%
134.1369 -\ {\isacharparenleft}rule\ findzero{\isachardot}domintros{\isacharparenright}\ simp\isanewline
134.1370 -\isanewline
134.1371 -\ \ \isacommand{from}\isamarkupfalse%
134.1372 -\ {\isacharbackquoteopen}x\ {\isasymge}\ n{\isacharbackquoteclose}\ \isacommand{show}\isamarkupfalse%
134.1373 -\ {\isacharquery}thesis\isanewline
134.1374 -\ \ \isacommand{proof}\isamarkupfalse%
134.1375 -\ {\isacharparenleft}induct\ rule{\isacharcolon}inc{\isacharunderscore}induct{\isacharparenright}\isanewline
134.1376 -\ \ \ \ \isacommand{show}\isamarkupfalse%
134.1377 -\ {\isachardoublequoteopen}findzero{\isacharunderscore}dom\ {\isacharparenleft}f{\isacharcomma}\ x{\isacharparenright}{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse%
134.1378 -\ {\isacharparenleft}rule\ base{\isacharparenright}\isanewline
134.1379 -\ \ \isacommand{next}\isamarkupfalse%
134.1380 -\isanewline
134.1381 -\ \ \ \ \isacommand{fix}\isamarkupfalse%
134.1382 -\ i\ \isacommand{assume}\isamarkupfalse%
134.1383 -\ {\isachardoublequoteopen}findzero{\isacharunderscore}dom\ {\isacharparenleft}f{\isacharcomma}\ Suc\ i{\isacharparenright}{\isachardoublequoteclose}\isanewline
134.1384 -\ \ \ \ \isacommand{thus}\isamarkupfalse%
134.1385 -\ {\isachardoublequoteopen}findzero{\isacharunderscore}dom\ {\isacharparenleft}f{\isacharcomma}\ i{\isacharparenright}{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse%
134.1386 -\ {\isacharparenleft}rule\ step{\isacharparenright}\isanewline
134.1387 -\ \ \isacommand{qed}\isamarkupfalse%
134.1388 -\isanewline
134.1389 -\isacommand{qed}\isamarkupfalse%
134.1390 -%
134.1391 -\endisatagproof
134.1392 -{\isafoldproof}%
134.1393 -%
134.1394 -\isadelimproof
134.1395 -%
134.1396 -\endisadelimproof
134.1397 -%
134.1398 -\isamarkupfalse\isabellestyle{tt}
134.1399 -\end{minipage}\vspace{6pt}\hrule
134.1400 -\caption{Termination proof for \isa{findzero}}\label{findzero_term}
134.1401 -\end{figure}
134.1402 -%
134.1403 -\begin{isamarkuptext}%
134.1404 -Again, the proof given in Fig.~\ref{findzero_term} has a lot of
134.1405 - detail in order to explain the principles. Using more automation, we
134.1406 - can also have a short proof:%
134.1407 -\end{isamarkuptext}%
134.1408 -\isamarkuptrue%
134.1409 -\isacommand{lemma}\isamarkupfalse%
134.1410 -\ findzero{\isacharunderscore}termination{\isacharunderscore}short{\isacharcolon}\isanewline
134.1411 -\ \ \isakeyword{assumes}\ zero{\isacharcolon}\ {\isachardoublequoteopen}x\ {\isachargreater}{\isacharequal}\ n{\isachardoublequoteclose}\ \isanewline
134.1412 -\ \ \isakeyword{assumes}\ {\isacharbrackleft}simp{\isacharbrackright}{\isacharcolon}\ {\isachardoublequoteopen}f\ x\ {\isacharequal}\ {\isadigit{0}}{\isachardoublequoteclose}\isanewline
134.1413 -\ \ \isakeyword{shows}\ {\isachardoublequoteopen}findzero{\isacharunderscore}dom\ {\isacharparenleft}f{\isacharcomma}\ n{\isacharparenright}{\isachardoublequoteclose}\isanewline
134.1414 -%
134.1415 -\isadelimproof
134.1416 -%
134.1417 -\endisadelimproof
134.1418 -%
134.1419 -\isatagproof
134.1420 -\isacommand{using}\isamarkupfalse%
134.1421 -\ zero\isanewline
134.1422 -\isacommand{by}\isamarkupfalse%
134.1423 -\ {\isacharparenleft}induct\ rule{\isacharcolon}inc{\isacharunderscore}induct{\isacharparenright}\ {\isacharparenleft}auto\ intro{\isacharcolon}\ findzero{\isachardot}domintros{\isacharparenright}%
134.1424 -\endisatagproof
134.1425 -{\isafoldproof}%
134.1426 -%
134.1427 -\isadelimproof
134.1428 -%
134.1429 -\endisadelimproof
134.1430 -%
134.1431 -\begin{isamarkuptext}%
134.1432 -\noindent It is simple to combine the partial correctness result with the
134.1433 - termination lemma:%
134.1434 -\end{isamarkuptext}%
134.1435 -\isamarkuptrue%
134.1436 -\isacommand{lemma}\isamarkupfalse%
134.1437 -\ findzero{\isacharunderscore}total{\isacharunderscore}correctness{\isacharcolon}\isanewline
134.1438 -\ \ {\isachardoublequoteopen}f\ x\ {\isacharequal}\ {\isadigit{0}}\ {\isasymLongrightarrow}\ f\ {\isacharparenleft}findzero\ f\ {\isadigit{0}}{\isacharparenright}\ {\isacharequal}\ {\isadigit{0}}{\isachardoublequoteclose}\isanewline
134.1439 -%
134.1440 -\isadelimproof
134.1441 -%
134.1442 -\endisadelimproof
134.1443 -%
134.1444 -\isatagproof
134.1445 -\isacommand{by}\isamarkupfalse%
134.1446 -\ {\isacharparenleft}blast\ intro{\isacharcolon}\ findzero{\isacharunderscore}zero\ findzero{\isacharunderscore}termination{\isacharparenright}%
134.1447 -\endisatagproof
134.1448 -{\isafoldproof}%
134.1449 -%
134.1450 -\isadelimproof
134.1451 -%
134.1452 -\endisadelimproof
134.1453 -%
134.1454 -\isamarkupsubsection{Definition of the domain predicate%
134.1455 -}
134.1456 -\isamarkuptrue%
134.1457 -%
134.1458 -\begin{isamarkuptext}%
134.1459 -Sometimes it is useful to know what the definition of the domain
134.1460 - predicate looks like. Actually, \isa{findzero{\isacharunderscore}dom} is just an
134.1461 - abbreviation:
134.1462 -
134.1463 - \begin{isabelle}%
134.1464 -findzero{\isacharunderscore}dom\ {\isasymequiv}\ accp\ findzero{\isacharunderscore}rel%
134.1465 -\end{isabelle}
134.1466 -
134.1467 - The domain predicate is the \emph{accessible part} of a relation \isa{findzero{\isacharunderscore}rel}, which was also created internally by the function
134.1468 - package. \isa{findzero{\isacharunderscore}rel} is just a normal
134.1469 - inductive predicate, so we can inspect its definition by
134.1470 - looking at the introduction rules \isa{findzero{\isacharunderscore}rel{\isachardot}intros}.
134.1471 - In our case there is just a single rule:
134.1472 -
134.1473 - \begin{isabelle}%
134.1474 -{\isacharquery}f\ {\isacharquery}n\ {\isasymnoteq}\ {\isadigit{0}}\ {\isasymLongrightarrow}\ findzero{\isacharunderscore}rel\ {\isacharparenleft}{\isacharquery}f{\isacharcomma}\ Suc\ {\isacharquery}n{\isacharparenright}\ {\isacharparenleft}{\isacharquery}f{\isacharcomma}\ {\isacharquery}n{\isacharparenright}%
134.1475 -\end{isabelle}
134.1476 -
134.1477 - The predicate \isa{findzero{\isacharunderscore}rel}
134.1478 - describes the \emph{recursion relation} of the function
134.1479 - definition. The recursion relation is a binary relation on
134.1480 - the arguments of the function that relates each argument to its
134.1481 - recursive calls. In general, there is one introduction rule for each
134.1482 - recursive call.
134.1483 -
134.1484 - The predicate \isa{findzero{\isacharunderscore}dom} is the accessible part of
134.1485 - that relation. An argument belongs to the accessible part, if it can
134.1486 - be reached in a finite number of steps (cf.~its definition in \isa{Accessible{\isacharunderscore}Part{\isachardot}thy}).
134.1487 -
134.1488 - Since the domain predicate is just an abbreviation, you can use
134.1489 - lemmas for \isa{accp} and \isa{findzero{\isacharunderscore}rel} directly. Some
134.1490 - lemmas which are occasionally useful are \isa{accpI}, \isa{accp{\isacharunderscore}downward}, and of course the introduction and elimination rules
134.1491 - for the recursion relation \isa{findzero{\isachardot}intros} and \isa{findzero{\isachardot}cases}.%
134.1492 -\end{isamarkuptext}%
134.1493 -\isamarkuptrue%
134.1494 -%
134.1495 -\isamarkupsubsection{A Useful Special Case: Tail recursion%
134.1496 -}
134.1497 -\isamarkuptrue%
134.1498 -%
134.1499 -\begin{isamarkuptext}%
134.1500 -The domain predicate is our trick that allows us to model partiality
134.1501 - in a world of total functions. The downside of this is that we have
134.1502 - to carry it around all the time. The termination proof above allowed
134.1503 - us to replace the abstract \isa{findzero{\isacharunderscore}dom\ {\isacharparenleft}f{\isacharcomma}\ n{\isacharparenright}} by the more
134.1504 - concrete \isa{n\ {\isasymle}\ x\ {\isasymand}\ f\ x\ {\isacharequal}\ {\isadigit{0}}}, but the condition is still
134.1505 - there and can only be discharged for special cases.
134.1506 - In particular, the domain predicate guards the unfolding of our
134.1507 - function, since it is there as a condition in the \isa{psimp}
134.1508 - rules.
134.1509 -
134.1510 - Now there is an important special case: We can actually get rid
134.1511 - of the condition in the simplification rules, \emph{if the function
134.1512 - is tail-recursive}. The reason is that for all tail-recursive
134.1513 - equations there is a total function satisfying them, even if they
134.1514 - are non-terminating.
134.1515 -
134.1516 -% A function is tail recursive, if each call to the function is either
134.1517 -% equal
134.1518 -%
134.1519 -% So the outer form of the
134.1520 -%
134.1521 -%if it can be written in the following
134.1522 -% form:
134.1523 -% {term[display] "f x = (if COND x then BASE x else f (LOOP x))"}
134.1524 -
134.1525 -
134.1526 - The function package internally does the right construction and can
134.1527 - derive the unconditional simp rules, if we ask it to do so. Luckily,
134.1528 - our \isa{findzero} function is tail-recursive, so we can just go
134.1529 - back and add another option to the \cmd{function} command:
134.1530 -
134.1531 -\vspace{1ex}
134.1532 -\noindent\cmd{function} \isa{{\isacharparenleft}domintros{\isacharcomma}\ tailrec{\isacharparenright}\ findzero\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequote}{\isacharparenleft}nat\ {\isasymRightarrow}\ nat{\isacharparenright}\ {\isasymRightarrow}\ nat\ {\isasymRightarrow}\ nat{\isachardoublequote}}\\%
134.1533 -\cmd{where}\isanewline%
134.1534 -\ \ \ldots\\%
134.1535 -
134.1536 -
134.1537 - \noindent Now, we actually get unconditional simplification rules, even
134.1538 - though the function is partial:%
134.1539 -\end{isamarkuptext}%
134.1540 -\isamarkuptrue%
134.1541 -\isacommand{thm}\isamarkupfalse%
134.1542 -\ findzero{\isachardot}simps%
134.1543 -\begin{isamarkuptext}%
134.1544 -\begin{isabelle}%
134.1545 -findzero\ {\isacharquery}f\ {\isacharquery}n\ {\isacharequal}\ {\isacharparenleft}if\ {\isacharquery}f\ {\isacharquery}n\ {\isacharequal}\ {\isadigit{0}}\ then\ {\isacharquery}n\ else\ findzero\ {\isacharquery}f\ {\isacharparenleft}Suc\ {\isacharquery}n{\isacharparenright}{\isacharparenright}%
134.1546 -\end{isabelle}
134.1547 -
134.1548 - \noindent Of course these would make the simplifier loop, so we better remove
134.1549 - them from the simpset:%
134.1550 -\end{isamarkuptext}%
134.1551 -\isamarkuptrue%
134.1552 -\isacommand{declare}\isamarkupfalse%
134.1553 -\ findzero{\isachardot}simps{\isacharbrackleft}simp\ del{\isacharbrackright}%
134.1554 -\begin{isamarkuptext}%
134.1555 -Getting rid of the domain conditions in the simplification rules is
134.1556 - not only useful because it simplifies proofs. It is also required in
134.1557 - order to use Isabelle's code generator to generate ML code
134.1558 - from a function definition.
134.1559 - Since the code generator only works with equations, it cannot be
134.1560 - used with \isa{psimp} rules. Thus, in order to generate code for
134.1561 - partial functions, they must be defined as a tail recursion.
134.1562 - Luckily, many functions have a relatively natural tail recursive
134.1563 - definition.%
134.1564 -\end{isamarkuptext}%
134.1565 -\isamarkuptrue%
134.1566 -%
134.1567 -\isamarkupsection{Nested recursion%
134.1568 -}
134.1569 -\isamarkuptrue%
134.1570 -%
134.1571 -\begin{isamarkuptext}%
134.1572 -Recursive calls which are nested in one another frequently cause
134.1573 - complications, since their termination proof can depend on a partial
134.1574 - correctness property of the function itself.
134.1575 -
134.1576 - As a small example, we define the \qt{nested zero} function:%
134.1577 -\end{isamarkuptext}%
134.1578 -\isamarkuptrue%
134.1579 -\isacommand{function}\isamarkupfalse%
134.1580 -\ nz\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymRightarrow}\ nat{\isachardoublequoteclose}\isanewline
134.1581 -\isakeyword{where}\isanewline
134.1582 -\ \ {\isachardoublequoteopen}nz\ {\isadigit{0}}\ {\isacharequal}\ {\isadigit{0}}{\isachardoublequoteclose}\isanewline
134.1583 -{\isacharbar}\ {\isachardoublequoteopen}nz\ {\isacharparenleft}Suc\ n{\isacharparenright}\ {\isacharequal}\ nz\ {\isacharparenleft}nz\ n{\isacharparenright}{\isachardoublequoteclose}\isanewline
134.1584 -%
134.1585 -\isadelimproof
134.1586 -%
134.1587 -\endisadelimproof
134.1588 -%
134.1589 -\isatagproof
134.1590 -\isacommand{by}\isamarkupfalse%
134.1591 -\ pat{\isacharunderscore}completeness\ auto%
134.1592 -\endisatagproof
134.1593 -{\isafoldproof}%
134.1594 -%
134.1595 -\isadelimproof
134.1596 -%
134.1597 -\endisadelimproof
134.1598 -%
134.1599 -\begin{isamarkuptext}%
134.1600 -If we attempt to prove termination using the identity measure on
134.1601 - naturals, this fails:%
134.1602 -\end{isamarkuptext}%
134.1603 -\isamarkuptrue%
134.1604 -\isacommand{termination}\isamarkupfalse%
134.1605 -\isanewline
134.1606 -%
134.1607 -\isadelimproof
134.1608 -\ \ %
134.1609 -\endisadelimproof
134.1610 -%
134.1611 -\isatagproof
134.1612 -\isacommand{apply}\isamarkupfalse%
134.1613 -\ {\isacharparenleft}relation\ {\isachardoublequoteopen}measure\ {\isacharparenleft}{\isasymlambda}n{\isachardot}\ n{\isacharparenright}{\isachardoublequoteclose}{\isacharparenright}\isanewline
134.1614 -\ \ \isacommand{apply}\isamarkupfalse%
134.1615 -\ auto%
134.1616 -\begin{isamarkuptxt}%
134.1617 -We get stuck with the subgoal
134.1618 -
134.1619 - \begin{isabelle}%
134.1620 -\ {\isadigit{1}}{\isachardot}\ {\isasymAnd}n{\isachardot}\ nz{\isacharunderscore}dom\ n\ {\isasymLongrightarrow}\ nz\ n\ {\isacharless}\ Suc\ n%
134.1621 -\end{isabelle}
134.1622 -
134.1623 - Of course this statement is true, since we know that \isa{nz} is
134.1624 - the zero function. And in fact we have no problem proving this
134.1625 - property by induction.%
134.1626 -\end{isamarkuptxt}%
134.1627 -\isamarkuptrue%
134.1628 -%
134.1629 -\endisatagproof
134.1630 -{\isafoldproof}%
134.1631 -%
134.1632 -\isadelimproof
134.1633 -%
134.1634 -\endisadelimproof
134.1635 -\isacommand{lemma}\isamarkupfalse%
134.1636 -\ nz{\isacharunderscore}is{\isacharunderscore}zero{\isacharcolon}\ {\isachardoublequoteopen}nz{\isacharunderscore}dom\ n\ {\isasymLongrightarrow}\ nz\ n\ {\isacharequal}\ {\isadigit{0}}{\isachardoublequoteclose}\isanewline
134.1637 -%
134.1638 -\isadelimproof
134.1639 -\ \ %
134.1640 -\endisadelimproof
134.1641 -%
134.1642 -\isatagproof
134.1643 -\isacommand{by}\isamarkupfalse%
134.1644 -\ {\isacharparenleft}induct\ rule{\isacharcolon}nz{\isachardot}pinduct{\isacharparenright}\ auto%
134.1645 -\endisatagproof
134.1646 -{\isafoldproof}%
134.1647 -%
134.1648 -\isadelimproof
134.1649 -%
134.1650 -\endisadelimproof
134.1651 -%
134.1652 -\begin{isamarkuptext}%
134.1653 -We formulate this as a partial correctness lemma with the condition
134.1654 - \isa{nz{\isacharunderscore}dom\ n}. This allows us to prove it with the \isa{pinduct} rule before we have proved termination. With this lemma,
134.1655 - the termination proof works as expected:%
134.1656 -\end{isamarkuptext}%
134.1657 -\isamarkuptrue%
134.1658 -\isacommand{termination}\isamarkupfalse%
134.1659 -\isanewline
134.1660 -%
134.1661 -\isadelimproof
134.1662 -\ \ %
134.1663 -\endisadelimproof
134.1664 -%
134.1665 -\isatagproof
134.1666 -\isacommand{by}\isamarkupfalse%
134.1667 -\ {\isacharparenleft}relation\ {\isachardoublequoteopen}measure\ {\isacharparenleft}{\isasymlambda}n{\isachardot}\ n{\isacharparenright}{\isachardoublequoteclose}{\isacharparenright}\ {\isacharparenleft}auto\ simp{\isacharcolon}\ nz{\isacharunderscore}is{\isacharunderscore}zero{\isacharparenright}%
134.1668 -\endisatagproof
134.1669 -{\isafoldproof}%
134.1670 -%
134.1671 -\isadelimproof
134.1672 -%
134.1673 -\endisadelimproof
134.1674 -%
134.1675 -\begin{isamarkuptext}%
134.1676 -As a general strategy, one should prove the statements needed for
134.1677 - termination as a partial property first. Then they can be used to do
134.1678 - the termination proof. This also works for less trivial
134.1679 - examples. Figure \ref{f91} defines the 91-function, a well-known
134.1680 - challenge problem due to John McCarthy, and proves its termination.%
134.1681 -\end{isamarkuptext}%
134.1682 -\isamarkuptrue%
134.1683 -%
134.1684 -\begin{figure}
134.1685 -\hrule\vspace{6pt}
134.1686 -\begin{minipage}{0.8\textwidth}
134.1687 -\isabellestyle{it}
134.1688 -\isastyle\isamarkuptrue
134.1689 -\isacommand{function}\isamarkupfalse%
134.1690 -\ f{\isadigit{9}}{\isadigit{1}}\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymRightarrow}\ nat{\isachardoublequoteclose}\isanewline
134.1691 -\isakeyword{where}\isanewline
134.1692 -\ \ {\isachardoublequoteopen}f{\isadigit{9}}{\isadigit{1}}\ n\ {\isacharequal}\ {\isacharparenleft}if\ {\isadigit{1}}{\isadigit{0}}{\isadigit{0}}\ {\isacharless}\ n\ then\ n\ {\isacharminus}\ {\isadigit{1}}{\isadigit{0}}\ else\ f{\isadigit{9}}{\isadigit{1}}\ {\isacharparenleft}f{\isadigit{9}}{\isadigit{1}}\ {\isacharparenleft}n\ {\isacharplus}\ {\isadigit{1}}{\isadigit{1}}{\isacharparenright}{\isacharparenright}{\isacharparenright}{\isachardoublequoteclose}\isanewline
134.1693 -%
134.1694 -\isadelimproof
134.1695 -%
134.1696 -\endisadelimproof
134.1697 -%
134.1698 -\isatagproof
134.1699 -\isacommand{by}\isamarkupfalse%
134.1700 -\ pat{\isacharunderscore}completeness\ auto%
134.1701 -\endisatagproof
134.1702 -{\isafoldproof}%
134.1703 -%
134.1704 -\isadelimproof
134.1705 -\isanewline
134.1706 -%
134.1707 -\endisadelimproof
134.1708 -\isanewline
134.1709 -\isacommand{lemma}\isamarkupfalse%
134.1710 -\ f{\isadigit{9}}{\isadigit{1}}{\isacharunderscore}estimate{\isacharcolon}\ \isanewline
134.1711 -\ \ \isakeyword{assumes}\ trm{\isacharcolon}\ {\isachardoublequoteopen}f{\isadigit{9}}{\isadigit{1}}{\isacharunderscore}dom\ n{\isachardoublequoteclose}\ \isanewline
134.1712 -\ \ \isakeyword{shows}\ {\isachardoublequoteopen}n\ {\isacharless}\ f{\isadigit{9}}{\isadigit{1}}\ n\ {\isacharplus}\ {\isadigit{1}}{\isadigit{1}}{\isachardoublequoteclose}\isanewline
134.1713 -%
134.1714 -\isadelimproof
134.1715 -%
134.1716 -\endisadelimproof
134.1717 -%
134.1718 -\isatagproof
134.1719 -\isacommand{using}\isamarkupfalse%
134.1720 -\ trm\ \isacommand{by}\isamarkupfalse%
134.1721 -\ induct\ auto%
134.1722 -\endisatagproof
134.1723 -{\isafoldproof}%
134.1724 -%
134.1725 -\isadelimproof
134.1726 -\isanewline
134.1727 -%
134.1728 -\endisadelimproof
134.1729 -\isanewline
134.1730 -\isacommand{termination}\isamarkupfalse%
134.1731 -\isanewline
134.1732 -%
134.1733 -\isadelimproof
134.1734 -%
134.1735 -\endisadelimproof
134.1736 -%
134.1737 -\isatagproof
134.1738 -\isacommand{proof}\isamarkupfalse%
134.1739 -\isanewline
134.1740 -\ \ \isacommand{let}\isamarkupfalse%
134.1741 -\ {\isacharquery}R\ {\isacharequal}\ {\isachardoublequoteopen}measure\ {\isacharparenleft}{\isasymlambda}x{\isachardot}\ {\isadigit{1}}{\isadigit{0}}{\isadigit{1}}\ {\isacharminus}\ x{\isacharparenright}{\isachardoublequoteclose}\isanewline
134.1742 -\ \ \isacommand{show}\isamarkupfalse%
134.1743 -\ {\isachardoublequoteopen}wf\ {\isacharquery}R{\isachardoublequoteclose}\ \isacommand{{\isachardot}{\isachardot}}\isamarkupfalse%
134.1744 -\isanewline
134.1745 -\isanewline
134.1746 -\ \ \isacommand{fix}\isamarkupfalse%
134.1747 -\ n\ {\isacharcolon}{\isacharcolon}\ nat\ \isacommand{assume}\isamarkupfalse%
134.1748 -\ {\isachardoublequoteopen}{\isasymnot}\ {\isadigit{1}}{\isadigit{0}}{\isadigit{0}}\ {\isacharless}\ n{\isachardoublequoteclose}\ %
134.1749 -\isamarkupcmt{Assumptions for both calls%
134.1750 -}
134.1751 -\isanewline
134.1752 -\isanewline
134.1753 -\ \ \isacommand{thus}\isamarkupfalse%
134.1754 -\ {\isachardoublequoteopen}{\isacharparenleft}n\ {\isacharplus}\ {\isadigit{1}}{\isadigit{1}}{\isacharcomma}\ n{\isacharparenright}\ {\isasymin}\ {\isacharquery}R{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse%
134.1755 -\ simp\ %
134.1756 -\isamarkupcmt{Inner call%
134.1757 -}
134.1758 -\isanewline
134.1759 -\isanewline
134.1760 -\ \ \isacommand{assume}\isamarkupfalse%
134.1761 -\ inner{\isacharunderscore}trm{\isacharcolon}\ {\isachardoublequoteopen}f{\isadigit{9}}{\isadigit{1}}{\isacharunderscore}dom\ {\isacharparenleft}n\ {\isacharplus}\ {\isadigit{1}}{\isadigit{1}}{\isacharparenright}{\isachardoublequoteclose}\ %
134.1762 -\isamarkupcmt{Outer call%
134.1763 -}
134.1764 -\isanewline
134.1765 -\ \ \isacommand{with}\isamarkupfalse%
134.1766 -\ f{\isadigit{9}}{\isadigit{1}}{\isacharunderscore}estimate\ \isacommand{have}\isamarkupfalse%
134.1767 -\ {\isachardoublequoteopen}n\ {\isacharplus}\ {\isadigit{1}}{\isadigit{1}}\ {\isacharless}\ f{\isadigit{9}}{\isadigit{1}}\ {\isacharparenleft}n\ {\isacharplus}\ {\isadigit{1}}{\isadigit{1}}{\isacharparenright}\ {\isacharplus}\ {\isadigit{1}}{\isadigit{1}}{\isachardoublequoteclose}\ \isacommand{{\isachardot}}\isamarkupfalse%
134.1768 -\isanewline
134.1769 -\ \ \isacommand{with}\isamarkupfalse%
134.1770 -\ {\isacharbackquoteopen}{\isasymnot}\ {\isadigit{1}}{\isadigit{0}}{\isadigit{0}}\ {\isacharless}\ n{\isacharbackquoteclose}\ \isacommand{show}\isamarkupfalse%
134.1771 -\ {\isachardoublequoteopen}{\isacharparenleft}f{\isadigit{9}}{\isadigit{1}}\ {\isacharparenleft}n\ {\isacharplus}\ {\isadigit{1}}{\isadigit{1}}{\isacharparenright}{\isacharcomma}\ n{\isacharparenright}\ {\isasymin}\ {\isacharquery}R{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse%
134.1772 -\ simp\isanewline
134.1773 -\isacommand{qed}\isamarkupfalse%
134.1774 -%
134.1775 -\endisatagproof
134.1776 -{\isafoldproof}%
134.1777 -%
134.1778 -\isadelimproof
134.1779 -%
134.1780 -\endisadelimproof
134.1781 -%
134.1782 -\isamarkupfalse\isabellestyle{tt}
134.1783 -\end{minipage}
134.1784 -\vspace{6pt}\hrule
134.1785 -\caption{McCarthy's 91-function}\label{f91}
134.1786 -\end{figure}
134.1787 -%
134.1788 -\isamarkupsection{Higher-Order Recursion%
134.1789 -}
134.1790 -\isamarkuptrue%
134.1791 -%
134.1792 -\begin{isamarkuptext}%
134.1793 -Higher-order recursion occurs when recursive calls
134.1794 - are passed as arguments to higher-order combinators such as \isa{map}, \isa{filter} etc.
134.1795 - As an example, imagine a datatype of n-ary trees:%
134.1796 -\end{isamarkuptext}%
134.1797 -\isamarkuptrue%
134.1798 -\isacommand{datatype}\isamarkupfalse%
134.1799 -\ {\isacharprime}a\ tree\ {\isacharequal}\ \isanewline
134.1800 -\ \ Leaf\ {\isacharprime}a\ \isanewline
134.1801 -{\isacharbar}\ Branch\ {\isachardoublequoteopen}{\isacharprime}a\ tree\ list{\isachardoublequoteclose}%
134.1802 -\begin{isamarkuptext}%
134.1803 -\noindent We can define a function which swaps the left and right subtrees recursively, using the
134.1804 - list functions \isa{rev} and \isa{map}:%
134.1805 -\end{isamarkuptext}%
134.1806 -\isamarkuptrue%
134.1807 -\isacommand{fun}\isamarkupfalse%
134.1808 -\ mirror\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharprime}a\ tree\ {\isasymRightarrow}\ {\isacharprime}a\ tree{\isachardoublequoteclose}\isanewline
134.1809 -\isakeyword{where}\isanewline
134.1810 -\ \ {\isachardoublequoteopen}mirror\ {\isacharparenleft}Leaf\ n{\isacharparenright}\ {\isacharequal}\ Leaf\ n{\isachardoublequoteclose}\isanewline
134.1811 -{\isacharbar}\ {\isachardoublequoteopen}mirror\ {\isacharparenleft}Branch\ l{\isacharparenright}\ {\isacharequal}\ Branch\ {\isacharparenleft}rev\ {\isacharparenleft}map\ mirror\ l{\isacharparenright}{\isacharparenright}{\isachardoublequoteclose}%
134.1812 -\begin{isamarkuptext}%
134.1813 -Although the definition is accepted without problems, let us look at the termination proof:%
134.1814 -\end{isamarkuptext}%
134.1815 -\isamarkuptrue%
134.1816 -\isacommand{termination}\isamarkupfalse%
134.1817 -%
134.1818 -\isadelimproof
134.1819 -\ %
134.1820 -\endisadelimproof
134.1821 -%
134.1822 -\isatagproof
134.1823 -\isacommand{proof}\isamarkupfalse%
134.1824 -%
134.1825 -\begin{isamarkuptxt}%
134.1826 -As usual, we have to give a wellfounded relation, such that the
134.1827 - arguments of the recursive calls get smaller. But what exactly are
134.1828 - the arguments of the recursive calls when mirror is given as an
134.1829 - argument to map? Isabelle gives us the
134.1830 - subgoals
134.1831 -
134.1832 - \begin{isabelle}%
134.1833 -\ {\isadigit{1}}{\isachardot}\ wf\ {\isacharquery}R\isanewline
134.1834 -\ {\isadigit{2}}{\isachardot}\ {\isasymAnd}l\ x{\isachardot}\ x\ {\isasymin}\ set\ l\ {\isasymLongrightarrow}\ {\isacharparenleft}x{\isacharcomma}\ Branch\ l{\isacharparenright}\ {\isasymin}\ {\isacharquery}R%
134.1835 -\end{isabelle}
134.1836 -
134.1837 - So the system seems to know that \isa{map} only
134.1838 - applies the recursive call \isa{mirror} to elements
134.1839 - of \isa{l}, which is essential for the termination proof.
134.1840 -
134.1841 - This knowledge about map is encoded in so-called congruence rules,
134.1842 - which are special theorems known to the \cmd{function} command. The
134.1843 - rule for map is
134.1844 -
134.1845 - \begin{isabelle}%
134.1846 -{\isasymlbrakk}{\isacharquery}xs\ {\isacharequal}\ {\isacharquery}ys{\isacharsemicolon}\ {\isasymAnd}x{\isachardot}\ x\ {\isasymin}\ set\ {\isacharquery}ys\ {\isasymLongrightarrow}\ {\isacharquery}f\ x\ {\isacharequal}\ {\isacharquery}g\ x{\isasymrbrakk}\ {\isasymLongrightarrow}\ map\ {\isacharquery}f\ {\isacharquery}xs\ {\isacharequal}\ map\ {\isacharquery}g\ {\isacharquery}ys%
134.1847 -\end{isabelle}
134.1848 -
134.1849 - You can read this in the following way: Two applications of \isa{map} are equal, if the list arguments are equal and the functions
134.1850 - coincide on the elements of the list. This means that for the value
134.1851 - \isa{map\ f\ l} we only have to know how \isa{f} behaves on
134.1852 - the elements of \isa{l}.
134.1853 -
134.1854 - Usually, one such congruence rule is
134.1855 - needed for each higher-order construct that is used when defining
134.1856 - new functions. In fact, even basic functions like \isa{If} and \isa{Let} are handled by this mechanism. The congruence
134.1857 - rule for \isa{If} states that the \isa{then} branch is only
134.1858 - relevant if the condition is true, and the \isa{else} branch only if it
134.1859 - is false:
134.1860 -
134.1861 - \begin{isabelle}%
134.1862 -{\isasymlbrakk}{\isacharquery}b\ {\isacharequal}\ {\isacharquery}c{\isacharsemicolon}\ {\isacharquery}c\ {\isasymLongrightarrow}\ {\isacharquery}x\ {\isacharequal}\ {\isacharquery}u{\isacharsemicolon}\ {\isasymnot}\ {\isacharquery}c\ {\isasymLongrightarrow}\ {\isacharquery}y\ {\isacharequal}\ {\isacharquery}v{\isasymrbrakk}\isanewline
134.1863 -{\isasymLongrightarrow}\ {\isacharparenleft}if\ {\isacharquery}b\ then\ {\isacharquery}x\ else\ {\isacharquery}y{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}if\ {\isacharquery}c\ then\ {\isacharquery}u\ else\ {\isacharquery}v{\isacharparenright}%
134.1864 -\end{isabelle}
134.1865 -
134.1866 - Congruence rules can be added to the
134.1867 - function package by giving them the \isa{fundef{\isacharunderscore}cong} attribute.
134.1868 -
134.1869 - The constructs that are predefined in Isabelle, usually
134.1870 - come with the respective congruence rules.
134.1871 - But if you define your own higher-order functions, you may have to
134.1872 - state and prove the required congruence rules yourself, if you want to use your
134.1873 - functions in recursive definitions.%
134.1874 -\end{isamarkuptxt}%
134.1875 -\isamarkuptrue%
134.1876 -%
134.1877 -\endisatagproof
134.1878 -{\isafoldproof}%
134.1879 -%
134.1880 -\isadelimproof
134.1881 -%
134.1882 -\endisadelimproof
134.1883 -%
134.1884 -\isamarkupsubsection{Congruence Rules and Evaluation Order%
134.1885 -}
134.1886 -\isamarkuptrue%
134.1887 -%
134.1888 -\begin{isamarkuptext}%
134.1889 -Higher order logic differs from functional programming languages in
134.1890 - that it has no built-in notion of evaluation order. A program is
134.1891 - just a set of equations, and it is not specified how they must be
134.1892 - evaluated.
134.1893 -
134.1894 - However for the purpose of function definition, we must talk about
134.1895 - evaluation order implicitly, when we reason about termination.
134.1896 - Congruence rules express that a certain evaluation order is
134.1897 - consistent with the logical definition.
134.1898 -
134.1899 - Consider the following function.%
134.1900 -\end{isamarkuptext}%
134.1901 -\isamarkuptrue%
134.1902 -\isacommand{function}\isamarkupfalse%
134.1903 -\ f\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymRightarrow}\ bool{\isachardoublequoteclose}\isanewline
134.1904 -\isakeyword{where}\isanewline
134.1905 -\ \ {\isachardoublequoteopen}f\ n\ {\isacharequal}\ {\isacharparenleft}n\ {\isacharequal}\ {\isadigit{0}}\ {\isasymor}\ f\ {\isacharparenleft}n\ {\isacharminus}\ {\isadigit{1}}{\isacharparenright}{\isacharparenright}{\isachardoublequoteclose}%
134.1906 -\isadelimproof
134.1907 -%
134.1908 -\endisadelimproof
134.1909 -%
134.1910 -\isatagproof
134.1911 -%
134.1912 -\endisatagproof
134.1913 -{\isafoldproof}%
134.1914 -%
134.1915 -\isadelimproof
134.1916 -%
134.1917 -\endisadelimproof
134.1918 -%
134.1919 -\begin{isamarkuptext}%
134.1920 -For this definition, the termination proof fails. The default configuration
134.1921 - specifies no congruence rule for disjunction. We have to add a
134.1922 - congruence rule that specifies left-to-right evaluation order:
134.1923 -
134.1924 - \vspace{1ex}
134.1925 - \noindent \isa{{\isasymlbrakk}{\isacharquery}P\ {\isacharequal}\ {\isacharquery}P{\isacharprime}{\isacharsemicolon}\ {\isasymnot}\ {\isacharquery}P{\isacharprime}\ {\isasymLongrightarrow}\ {\isacharquery}Q\ {\isacharequal}\ {\isacharquery}Q{\isacharprime}{\isasymrbrakk}\ {\isasymLongrightarrow}\ {\isacharparenleft}{\isacharquery}P\ {\isasymor}\ {\isacharquery}Q{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}{\isacharquery}P{\isacharprime}\ {\isasymor}\ {\isacharquery}Q{\isacharprime}{\isacharparenright}}\hfill(\isa{disj{\isacharunderscore}cong})
134.1926 - \vspace{1ex}
134.1927 -
134.1928 - Now the definition works without problems. Note how the termination
134.1929 - proof depends on the extra condition that we get from the congruence
134.1930 - rule.
134.1931 -
134.1932 - However, as evaluation is not a hard-wired concept, we
134.1933 - could just turn everything around by declaring a different
134.1934 - congruence rule. Then we can make the reverse definition:%
134.1935 -\end{isamarkuptext}%
134.1936 -\isamarkuptrue%
134.1937 -\isacommand{lemma}\isamarkupfalse%
134.1938 -\ disj{\isacharunderscore}cong{\isadigit{2}}{\isacharbrackleft}fundef{\isacharunderscore}cong{\isacharbrackright}{\isacharcolon}\ \isanewline
134.1939 -\ \ {\isachardoublequoteopen}{\isacharparenleft}{\isasymnot}\ Q{\isacharprime}\ {\isasymLongrightarrow}\ P\ {\isacharequal}\ P{\isacharprime}{\isacharparenright}\ {\isasymLongrightarrow}\ {\isacharparenleft}Q\ {\isacharequal}\ Q{\isacharprime}{\isacharparenright}\ {\isasymLongrightarrow}\ {\isacharparenleft}P\ {\isasymor}\ Q{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}P{\isacharprime}\ {\isasymor}\ Q{\isacharprime}{\isacharparenright}{\isachardoublequoteclose}\isanewline
134.1940 -%
134.1941 -\isadelimproof
134.1942 -\ \ %
134.1943 -\endisadelimproof
134.1944 -%
134.1945 -\isatagproof
134.1946 -\isacommand{by}\isamarkupfalse%
134.1947 -\ blast%
134.1948 -\endisatagproof
134.1949 -{\isafoldproof}%
134.1950 -%
134.1951 -\isadelimproof
134.1952 -\isanewline
134.1953 -%
134.1954 -\endisadelimproof
134.1955 -\isanewline
134.1956 -\isacommand{fun}\isamarkupfalse%
134.1957 -\ f{\isacharprime}\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymRightarrow}\ bool{\isachardoublequoteclose}\isanewline
134.1958 -\isakeyword{where}\isanewline
134.1959 -\ \ {\isachardoublequoteopen}f{\isacharprime}\ n\ {\isacharequal}\ {\isacharparenleft}f{\isacharprime}\ {\isacharparenleft}n\ {\isacharminus}\ {\isadigit{1}}{\isacharparenright}\ {\isasymor}\ n\ {\isacharequal}\ {\isadigit{0}}{\isacharparenright}{\isachardoublequoteclose}%
134.1960 -\begin{isamarkuptext}%
134.1961 -\noindent These examples show that, in general, there is no \qt{best} set of
134.1962 - congruence rules.
134.1963 -
134.1964 - However, such tweaking should rarely be necessary in
134.1965 - practice, as most of the time, the default set of congruence rules
134.1966 - works well.%
134.1967 -\end{isamarkuptext}%
134.1968 -\isamarkuptrue%
134.1969 -%
134.1970 -\isadelimtheory
134.1971 -%
134.1972 -\endisadelimtheory
134.1973 -%
134.1974 -\isatagtheory
134.1975 -\isacommand{end}\isamarkupfalse%
134.1976 -%
134.1977 -\endisatagtheory
134.1978 -{\isafoldtheory}%
134.1979 -%
134.1980 -\isadelimtheory
134.1981 -%
134.1982 -\endisadelimtheory
134.1983 -\isanewline
134.1984 -\end{isabellebody}%
134.1985 -%%% Local Variables:
134.1986 -%%% mode: latex
134.1987 -%%% TeX-master: "root"
134.1988 -%%% End:
135.1 --- a/doc-src/IsarAdvanced/Functions/Thy/document/session.tex Wed Mar 04 11:05:02 2009 +0100
135.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
135.3 @@ -1,6 +0,0 @@
135.4 -\input{Functions.tex}
135.5 -
135.6 -%%% Local Variables:
135.7 -%%% mode: latex
135.8 -%%% TeX-master: "root"
135.9 -%%% End:
136.1 --- a/doc-src/IsarAdvanced/Functions/conclusion.tex Wed Mar 04 11:05:02 2009 +0100
136.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
136.3 @@ -1,7 +0,0 @@
136.4 -\section{Conclusion}
136.5 -
136.6 -\fixme{}
136.7 -
136.8 -
136.9 -
136.10 -
137.1 --- a/doc-src/IsarAdvanced/Functions/functions.tex Wed Mar 04 11:05:02 2009 +0100
137.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
137.3 @@ -1,96 +0,0 @@
137.4 -
137.5 -%% $Id$
137.6 -
137.7 -\documentclass[a4paper,fleqn]{article}
137.8 -
137.9 -\usepackage{latexsym,graphicx}
137.10 -\usepackage[refpage]{nomencl}
137.11 -\usepackage{../../iman,../../extra,../../isar,../../proof}
137.12 -\usepackage{../../isabelle,../../isabellesym}
137.13 -\usepackage{style}
137.14 -\usepackage{mathpartir}
137.15 -\usepackage{amsthm}
137.16 -\usepackage{../../pdfsetup}
137.17 -
137.18 -\newcommand{\cmd}[1]{\isacommand{#1}}
137.19 -
137.20 -\newcommand{\isasymINFIX}{\cmd{infix}}
137.21 -\newcommand{\isasymLOCALE}{\cmd{locale}}
137.22 -\newcommand{\isasymINCLUDES}{\cmd{includes}}
137.23 -\newcommand{\isasymDATATYPE}{\cmd{datatype}}
137.24 -\newcommand{\isasymAXCLASS}{\cmd{axclass}}
137.25 -\newcommand{\isasymFIXES}{\cmd{fixes}}
137.26 -\newcommand{\isasymASSUMES}{\cmd{assumes}}
137.27 -\newcommand{\isasymDEFINES}{\cmd{defines}}
137.28 -\newcommand{\isasymNOTES}{\cmd{notes}}
137.29 -\newcommand{\isasymSHOWS}{\cmd{shows}}
137.30 -\newcommand{\isasymCLASS}{\cmd{class}}
137.31 -\newcommand{\isasymINSTANCE}{\cmd{instance}}
137.32 -\newcommand{\isasymLEMMA}{\cmd{lemma}}
137.33 -\newcommand{\isasymPROOF}{\cmd{proof}}
137.34 -\newcommand{\isasymQED}{\cmd{qed}}
137.35 -\newcommand{\isasymFIX}{\cmd{fix}}
137.36 -\newcommand{\isasymASSUME}{\cmd{assume}}
137.37 -\newcommand{\isasymSHOW}{\cmd{show}}
137.38 -\newcommand{\isasymNOTE}{\cmd{note}}
137.39 -\newcommand{\isasymCODEGEN}{\cmd{code\_gen}}
137.40 -\newcommand{\isasymPRINTCODETHMS}{\cmd{print\_codethms}}
137.41 -\newcommand{\isasymFUN}{\cmd{fun}}
137.42 -\newcommand{\isasymFUNCTION}{\cmd{function}}
137.43 -\newcommand{\isasymPRIMREC}{\cmd{primrec}}
137.44 -\newcommand{\isasymRECDEF}{\cmd{recdef}}
137.45 -
137.46 -\newcommand{\qt}[1]{``#1''}
137.47 -\newcommand{\qtt}[1]{"{}{#1}"{}}
137.48 -\newcommand{\qn}[1]{\emph{#1}}
137.49 -\newcommand{\strong}[1]{{\bfseries #1}}
137.50 -\newcommand{\fixme}[1][!]{\strong{FIXME: #1}}
137.51 -
137.52 -\newtheorem{exercise}{Exercise}{\bf}{\itshape}
137.53 -%\newtheorem*{thmstar}{Theorem}{\bf}{\itshape}
137.54 -
137.55 -\hyphenation{Isabelle}
137.56 -\hyphenation{Isar}
137.57 -
137.58 -\isadroptag{theory}
137.59 -\title{Defining Recursive Functions in Isabelle/HOL}
137.60 -\author{Alexander Krauss}
137.61 -
137.62 -\isabellestyle{tt}
137.63 -\renewcommand{\isastyletxt}{\isastyletext}% use same formatting for txt and text
137.64 -
137.65 -\begin{document}
137.66 -
137.67 -\date{\ \\}
137.68 -\maketitle
137.69 -
137.70 -\begin{abstract}
137.71 - This tutorial describes the use of the new \emph{function} package,
137.72 - which provides general recursive function definitions for Isabelle/HOL.
137.73 - We start with very simple examples and then gradually move on to more
137.74 - advanced topics such as manual termination proofs, nested recursion,
137.75 - partiality, tail recursion and congruence rules.
137.76 -\end{abstract}
137.77 -
137.78 -%\thispagestyle{empty}\clearpage
137.79 -
137.80 -%\pagenumbering{roman}
137.81 -%\clearfirst
137.82 -
137.83 -\input{intro.tex}
137.84 -\input{Thy/document/Functions.tex}
137.85 -%\input{conclusion.tex}
137.86 -
137.87 -\begingroup
137.88 -%\tocentry{\bibname}
137.89 -\bibliographystyle{plain} \small\raggedright\frenchspacing
137.90 -\bibliography{../../manual}
137.91 -\endgroup
137.92 -
137.93 -\end{document}
137.94 -
137.95 -
137.96 -%%% Local Variables:
137.97 -%%% mode: latex
137.98 -%%% TeX-master: t
137.99 -%%% End:
138.1 --- a/doc-src/IsarAdvanced/Functions/intro.tex Wed Mar 04 11:05:02 2009 +0100
138.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
138.3 @@ -1,55 +0,0 @@
138.4 -\section{Introduction}
138.5 -
138.6 -Starting from Isabelle 2007, new facilities for recursive
138.7 -function definitions~\cite{krauss2006} are available. They provide
138.8 -better support for general recursive definitions than previous
138.9 -packages. But despite all tool support, function definitions can
138.10 -sometimes be a difficult thing.
138.11 -
138.12 -This tutorial is an example-guided introduction to the practical use
138.13 -of the package and related tools. It should help you get started with
138.14 -defining functions quickly. For the more difficult definitions we will
138.15 -discuss what problems can arise, and how they can be solved.
138.16 -
138.17 -We assume that you have mastered the fundamentals of Isabelle/HOL
138.18 -and are able to write basic specifications and proofs. To start out
138.19 -with Isabelle in general, consult the Isabelle/HOL tutorial
138.20 -\cite{isa-tutorial}.
138.21 -
138.22 -
138.23 -
138.24 -\paragraph{Structure of this tutorial.}
138.25 -Section 2 introduces the syntax and basic operation of the \cmd{fun}
138.26 -command, which provides full automation with reasonable default
138.27 -behavior. The impatient reader can stop after that
138.28 -section, and consult the remaining sections only when needed.
138.29 -Section 3 introduces the more verbose \cmd{function} command which
138.30 -gives fine-grained control. This form should be used
138.31 -whenever the short form fails.
138.32 -After that we discuss more specialized issues:
138.33 -termination, mutual, nested and higher-order recursion, partiality, pattern matching
138.34 -and others.
138.35 -
138.36 -
138.37 -\paragraph{Some background.}
138.38 -Following the LCF tradition, the package is realized as a definitional
138.39 -extension: Recursive definitions are internally transformed into a
138.40 -non-recursive form, such that the function can be defined using
138.41 -standard definition facilities. Then the recursive specification is
138.42 -derived from the primitive definition. This is a complex task, but it
138.43 -is fully automated and mostly transparent to the user. Definitional
138.44 -extensions are valuable because they are conservative by construction:
138.45 -The \qt{new} concept of general wellfounded recursion is completely reduced
138.46 -to existing principles.
138.47 -
138.48 -
138.49 -
138.50 -
138.51 -The new \cmd{function} command, and its short form \cmd{fun} have mostly
138.52 -replaced the traditional \cmd{recdef} command \cite{slind-tfl}. They solve
138.53 -a few of technical issues around \cmd{recdef}, and allow definitions
138.54 -which were not previously possible.
138.55 -
138.56 -
138.57 -
138.58 -
139.1 --- a/doc-src/IsarAdvanced/Functions/isabelle_isar.eps Wed Mar 04 11:05:02 2009 +0100
139.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
139.3 @@ -1,6488 +0,0 @@
139.4 -%!PS-Adobe-2.0 EPSF-1.2
139.5 -%%Title: isabelle_any
139.6 -%%Creator: FreeHand 5.5
139.7 -%%CreationDate: 24.09.1998 21:04 Uhr
139.8 -%%BoundingBox: 0 0 202 178
139.9 -%%FHPathName:MacSystem:Home:Markus:TUM:Isabelle Logo:export:isabelle_any
139.10 -%ALDOriginalFile:MacSystem:Home:Markus:TUM:Isabelle Logo:export:isabelle_any
139.11 -%ALDBoundingBox: -153 -386 442 456
139.12 -%%FHPageNum:1
139.13 -%%DocumentSuppliedResources: procset Altsys_header 4 0
139.14 -%%ColorUsage: Color
139.15 -%%DocumentProcessColors: Cyan Magenta Yellow Black
139.16 -%%DocumentNeededResources: font Symbol
139.17 -%%+ font ZapfHumanist601BT-Bold
139.18 -%%DocumentFonts: Symbol
139.19 -%%+ ZapfHumanist601BT-Bold
139.20 -%%DocumentNeededFonts: Symbol
139.21 -%%+ ZapfHumanist601BT-Bold
139.22 -%%EndComments
139.23 -%!PS-AdobeFont-1.0: ZapfHumanist601BT-Bold 003.001
139.24 -%%CreationDate: Mon Jun 22 16:09:28 1992
139.25 -%%VMusage: 35200 38400
139.26 -% Bitstream Type 1 Font Program
139.27 -% Copyright 1990-1992 as an unpublished work by Bitstream Inc., Cambridge, MA.
139.28 -% All rights reserved.
139.29 -% Confidential and proprietary to Bitstream Inc.
139.30 -% U.S. GOVERNMENT RESTRICTED RIGHTS
139.31 -% This software typeface product is provided with RESTRICTED RIGHTS. Use,
139.32 -% duplication or disclosure by the Government is subject to restrictions
139.33 -% as set forth in the license agreement and in FAR 52.227-19 (c) (2) (May, 1987),
139.34 -% when applicable, or the applicable provisions of the DOD FAR supplement
139.35 -% 252.227-7013 subdivision (a) (15) (April, 1988) or subdivision (a) (17)
139.36 -% (April, 1988). Contractor/manufacturer is Bitstream Inc.,
139.37 -% 215 First Street, Cambridge, MA 02142.
139.38 -% Bitstream is a registered trademark of Bitstream Inc.
139.39 -11 dict begin
139.40 -/FontInfo 9 dict dup begin
139.41 - /version (003.001) readonly def
139.42 - /Notice (Copyright 1990-1992 as an unpublished work by Bitstream Inc. All rights reserved. Confidential.) readonly def
139.43 - /FullName (Zapf Humanist 601 Bold) readonly def
139.44 - /FamilyName (Zapf Humanist 601) readonly def
139.45 - /Weight (Bold) readonly def
139.46 - /ItalicAngle 0 def
139.47 - /isFixedPitch false def
139.48 - /UnderlinePosition -136 def
139.49 - /UnderlineThickness 85 def
139.50 -end readonly def
139.51 -/FontName /ZapfHumanist601BT-Bold def
139.52 -/PaintType 0 def
139.53 -/FontType 1 def
139.54 -/FontMatrix [0.001 0 0 0.001 0 0] readonly def
139.55 -/Encoding StandardEncoding def
139.56 -/FontBBox {-167 -275 1170 962} readonly def
139.57 -/UniqueID 15530396 def
139.58 -currentdict end
139.59 -currentfile eexec
139.60 -a2951840838a4133839ca9d22e2b99f2b61c767cd675080aacfcb24e19cd
139.61 -1336739bb64994c56737090b4cec92c9945ff0745ef7ffc61bb0a9a3b849
139.62 -e7e98740e56c0b5af787559cc6956ab31e33cf8553d55c0b0e818ef5ec6b
139.63 -f48162eac42e7380ca921dae1c82b38fd6bcf2001abb5d001a56157094cf
139.64 -e27d8f4eac9693e88372d20358b47e0c3876558ebf757a1fbc5c1cddf62b
139.65 -3c57bf727ef1c4879422c142a084d1c7462ac293e097fabe3a3ecfcd8271
139.66 -f259833bac7912707218ec9a3063bf7385e02d8c1058ac06df00b33b8c01
139.67 -8768b278010eb4dd58c7ba59321899741cb7215d8a55bee8d3398c887f02
139.68 -e1f4869387f89141de693fcb429c7884c22dcdeddcaa62b7f5060249dfab
139.69 -cfc351201f7d188b6ed68a228abda4d33b3d269ac09cde172bc045e67449
139.70 -c0f25d224efbe8c9f9d2968a01edbfb039123c365ed0db58ad38aabe015b
139.71 -8881191dd23092f6d53d5c1cd68ebd038e098d32cb24b433b7d5d89c28ee
139.72 -05ea0b6070bb785a2974b5a160ee4cf8b6d8c73445d36720af0530441cd9
139.73 -61bc0c367f1af1ec1c5ab7255ddda153c1868aba58cd5b44835535d85326
139.74 -5d7fed5ff7118adb5d5b76cc3b72e5ff27e21eb857261b3afb7688fca12d
139.75 -1663b0d8bdc1dd47a84b65b47d3e76d3b8fa8b319f17e1bb22b45a7482fd
139.76 -f9ad1b6129e09ae47f15cd2447484cd2d64f59ab0f2f876c81e7d87ccdf9
139.77 -005aa8fc093d02db51a075d571e925f2d309a1c535a1e59d34215c6cd33e
139.78 -3c38997b4956461f376399901a8d0943dca6a335baac93fc8482c0659f04
139.79 -329c6f040b35828ea6dd1bd1858f2a9be4ef77731b5b75a1c536c6bc9479
139.80 -0821e5d88f6e2981835dbfd65ec254ebcf2cf49c917d121cd3bbb476a12b
139.81 -69c15f17d9c17bb15ad1e7d31d2afcf58c8f0ad526d68615a0f1ac3b1d1c
139.82 -d3beafeea3cf56c8f8a66367c70df9159f0b1b3157ccfd010045c4718e0e
139.83 -625c0891e85790c9b97b85517c74c9d55eaca31a01cddc64898bf0eeadf3
139.84 -53391a185e507dcb0a6f52661a56357ac818dfc740a540aadf02f4e7a79d
139.85 -8008a77cd30abde337025b01217d6a68c306abe145b7260c3478fa5f366f
139.86 -b2d37259ead8a8ec2db2f09ae0eb3a682d27b0d73a60935f80254c24426a
139.87 -003a87a29a4370cbf1b2ef1e19ad8466ec725fd5b463d06011a5e0da2258
139.88 -ff6c1483c4532bc21f2ed9b99b929b2800ddefc1a98d12ba085adc210bac
139.89 -e0274b69e24d16af015a51ca73edf779a7534a887aa780337ad966839881
139.90 -edc22ba72038aa1a96a6deba24ad676795da711b92f8cf5f54cb4322ec04
139.91 -40ef9e15b11e3005f3ff69376ecb29bb66e8fc1b685f2b05fb162fcb35aa
139.92 -d7eb2a8ec39b97ab1ff05ef02f8dbbc12085a5cd252cc4010fab7f63dfd5
139.93 -7fa1be86f724d37db5faef17ae8e8e537444e8e9db917b270344183473af
139.94 -7f47d5703a160d8ef1e772438620d3336b2fbcf6433612e4b5e64fae0329
139.95 -8a3c4010c17d93f13ba66d549c69dd58c7d26ddc90285fed831918563a16
139.96 -2a7ac2511e2f18c9eb3df905a9dcba65a31cc1c39f07458abb11b4c60346
139.97 -aea19070e126982f1dde336e79be0ecd69a8afbe2493d064d4d2ff38788b
139.98 -b3038125961302db9761403c3b8019ec641e107425002205a77ae2ae0f4f
139.99 -7550d623dd03f0ec0199f42a9a8b89514e2e21baca9b3c8c96ca48cbf9dc
139.100 -ee6d6241d713e014b49e83ad85e62a6b2f70b58e4cc72d41ea6fcbdd3b5c
139.101 -890c8af0d24200658773b1628c6cc9aaaabb08865ee4c7ff2c513ad7aa23
139.102 -155a321213fa94731683a3e282a0e60aa3c87aade3da231465bdd9097f2c
139.103 -89a1af8e5b9649143f2d9482546501ea97e8bea2f5d5eea97d4f19bb6835
139.104 -3138d3babb2461c08d537491aaede1f23d734c6f099eb5bef6e2ffaaf138
139.105 -e5ab71b8b41599091037e440127a4eaedf208c20c8a2fc62eadab191d1ab
139.106 -4d5531f826aa6b9fff2797a7f54673e0a3fae09a93a0dfafb8b11d60dc69
139.107 -5acf9b7e1a47c31d0b5a0b85b7b50cddff5ac831651d9c7469c2139c7a89
139.108 -7d2f868f36c65156921803eccfdbdd1618595ab6d2a9230ef523a1b5ee51
139.109 -f2a0d200fc0e94aff7f546593ff2a3eb865d129895af01b8ab6e4616fe20
139.110 -9123b6e2b7e0817adc3cdb78ae8b0b1d75f2986ebd8fb24c4de92ac9e8c3
139.111 -6afa520636bcad2e6a03d11c268d97fa578561f6e7523e042c4cc73a0eac
139.112 -7a841907450e83d8e7a8de4db5085f6e8b25dc85b59e018380f4b9523a7f
139.113 -02cbeec989f0221b7681ec427519062b429dcd8fc2e4f81173519f88e2e4
139.114 -3798b90a84060920f6ae789afd6a9182e7fec87cd2d4235d37a65c3f3bcc
139.115 -c742c89cbe5f3e2ba6c4f40ebba162e12569d20684cc167685285a087e7a
139.116 -0a995fe1939bf25c09553512ba2cf77ef21d2ef8da1c73ba6e5826f4099e
139.117 -27d8bc7b3545fc592b75228e70127c15a382774357457cd4586d80dc0bd6
139.118 -065aee32acfd5c0523303cece85a3dbf46853b917618c0330146f527c15b
139.119 -dbb9f6526964368b2b8593eed1551dad75659565d54c6a0a52da7a8e366f
139.120 -dd009ef853491c0fb995e19933cba1dbdc8902721c3ea6017ffdd5851cb8
139.121 -3c8bada46075ac121afe13a70e87529e40693157adcc999ed4657e017adf
139.122 -f7dbac4bc0d204f204c6f47b769aaf714f9ec1d25226f24d0a1b53e28ac5
139.123 -374ab99755852c1431b2486df5fd637e2005a25303345a1c95a15a1189ba
139.124 -f6f6883de1ad46d48427b137c2003d210ab2b2f5680f2633939f289d7553
139.125 -eb943adf8127f1c3ee7d6453b5566393700ad74ab86eb9a89f8b0380af55
139.126 -6b62f51b7dbd0c5dcc9a9fb658944d7ad5845d58dedc2d38200d0ef7cb0f
139.127 -76041dc104ef3ab89c1dc2f6a75635d48051c8a7dd9f5e60253a53957ec8
139.128 -9d1266566d7ed20d79dfc2807b397d7cf056bdaccdb72528a88aa4987682
139.129 -c909b2fe1e35a71c2f29e89a2bf32173967e79610367ce4574ba6a1cc031
139.130 -cfb176fc0313f74f91a866ef9954b95b29caf917a6b919586f54d23cb7ce
139.131 -23305886ae7760ebd6263df0d3c511ac7afc361df78bc2621f66d3268b99
139.132 -078fa59124f0eb9476496c938eb4584e87455dc6f2faa999e938460b31c6
139.133 -28021c652acfa12d4556aa4302bbcd043e60389480b796c3fc0b2e51b81e
139.134 -c2afa4a34335318a1c5a842dcaa120df414acba2e79ab5cc61c99e98108c
139.135 -5cb907a96b30d731131782f9df79aabfc16a20ace8852d047497982e11c8
139.136 -26321addf679de8a96a2d18743f6f2c3b2bc397370b10ad273fcfb76b48b
139.137 -9dad27cf89ca2c370149cd48ab956e9bbce01cbf8e1f0c661b99cf19b36e
139.138 -87b6165dd85ae3f3674525e17d85971093e110520d17f2d6253611e35ec9
139.139 -e17000e48e2926454c1e8eb4098e0115b49536f2c33505eb5e574f7a414b
139.140 -e176398c5ddf6d846ea5ddf2a5e94c0422e0115c57a8c9e56bf8ba962c82
139.141 -698c96bd6138baaca7347e44352cc62df4eeba364954ad921a5a43280980
139.142 -264df4a7fb29d005423179f7bd1d98b4280d62ce23c927551f1ffc2b8f17
139.143 -0a9c23656c0c91b640cdcfdbd88089ffb28d3ac68bad25dbbed82c083696
139.144 -1f9f86a6183cc1061ffdb32279796569d05b31c946955402d0be1fb9f2bf
139.145 -304d1ad8e1e357be49e6e2ee67f7f1e7bc699d46a5f7853fe659ba2e1930
139.146 -0d3e3ea658b9862701dcab08fdd23bf1d751777f25efbe9e02d12b5612b3
139.147 -c3fc2275190346b94ec4024e4ade08e54d75c0b4c48f4956b9182e8ce997
139.148 -74b54da4a9318c099d89f1ce3b6803a95f48b9fb8b845372be25e54478e8
139.149 -49e4707ea03a36e134efa661e4e6250d89649ae074cfd9d6b9e2071c1099
139.150 -3b8a5a5ebc3e1cb228c97565aef7f254e3f90af8a3dd281c83792755719d
139.151 -c6a5b3bab4aa6be5afe9624050eee8dfb13b018f4088c932cd48ace38dfe
139.152 -b1b4218dba8f7fada6628076acf1b54db0c95d4fb12232f1fa9d1ba848f9
139.153 -fe80c65b75d6946c00fe78839142c5302707d9269b24565dbcc551aca060
139.154 -b4d0f99b961dd3cc795a982063ac42e9fc81fc98add42744a9f92e74b00d
139.155 -637ee4606ea2099b6c763493c3159f8e52a90dafca682010c0e92bc9038a
139.156 -10abb066c75c8d97f7ad6fb1a37136e52cf2093c4fa485fe12adad10e4d0
139.157 -83b78b023628ddc5326cbf8392516027a9f3de4945f93488e4a1997efd2a
139.158 -22c2c136dbac1bdb829e082beac48cdd06dcb17bacf09451c7b636bd49a8
139.159 -fc60cb1d2292250bea78e1dd276725ab4c526b66ddabf4e1b2bf0a2571df
139.160 -2490df70735f5da321fac74fe4fab54444e53dace9832cff38a70c58104a
139.161 -4f0c0545dcf7a1a9ecb54e0e32d6d8195d30b2c98a567741fcf325a4ddeb
139.162 -244a1a35676e246ddc835fac13b569f35f22ec93191eca3efbe17ff9a950
139.163 -d08f863710b2bbecec969068c498eb2338b68f3fc3f5447449fe4de2b065
139.164 -e068ecd9255d369b2bb6c4b0b7423774bed69294758aca2bdb1a8d5bf618
139.165 -d3fa09462f7838e8a79b7a53bebe6dacb0a1561eaa074bc6f069f6a06fb2
139.166 -c4a5cb13e2172bce9be659a82665da5cded73da84322bb16aa6e19ac1958
139.167 -7515cb5d2b65e65e803f76700ce5efd3df7fe4ed431fae0e8e286b1d5056
139.168 -a0d18df926b2be7a93c503ab903abd4788680a6201fdc299f2cb5d6a9b6e
139.169 -2048109c8d1fb633a54128938594b2cce86a7e0185e7d59e6536584039ec
139.170 -9e30ff7be6ddba9fdba82de7415fdc47de84d97afb1aa3ba495bd91dee9d
139.171 -f3b21ee1164987dd8510925087cd0919f1085cba6e4dd3c7384d26667f94
139.172 -ad7f736a60d8bd76dfaa4b53c23536fc309ff2317c48ee0107ff2ca4d1b3
139.173 -f78c5a27b901c931128bdb636094ef0cd543a5b62b7dbe10ed83aed5780c
139.174 -a16067a4a7e8b7c5bf8a8e822149bc1b5bcdabe13a7f6aa6eaeff24a42f4
139.175 -a58a2b70f545103540169137fda9abb589f734b6776cb50402d6123ce802
139.176 -10dce05e3697a98c9411cf60a02c278c91e03d540b936cd00c668960e357
139.177 -1aeaf4d94cfb496b259ec0d8fdba9199fb46634ff177bc8d310ea1314eef
139.178 -d46c927a981c58e88743ed4e07d80fe841edee812e3053412bf2e710146c
139.179 -b25dec8ea70c38bb1f6e4db3c2e8ba521963c1584eeb60ea1e9555058f13
139.180 -e98307c13cbd15c26b611f543149b1ddf88dd6296ae703f58daeb67f1b03
139.181 -ab5b24c72d5770cb9d8ed242c4faaad1dd940ada00e98ff3a61799d13355
139.182 -aba916910aa9a6e5ee8af438d0ba8235346fcd139b9d2cb7db7bd3f298a3
139.183 -94ff0aff3b9042f32a004e042c346a5ea35917f229848a9c5a32909b0090
139.184 -4aa715640277a6ada99f8b2927fda22899ff1347f42bac73e2bd4bbf3945
139.185 -55fd7dd30d5c6dadf5c259fdb2455d8c607de1c5da588e20159f18e4e8da
139.186 -b714e532d888a0386c52c2b85964251af003ac9d10c0c8b9b3465e1dde48
139.187 -2e74a29e17a7cf6c9a43b5af1646f0b8508f98e9a1279ec3908073d89dcb
139.188 -aa093e8dd1004c1ecccce0803095b0069d4be7a1eb14b02efc37d137dfe3
139.189 -f0190bc9628069abc257f45d0e050e60c7f5281277937dd986fcd5b94a2b
139.190 -845a1a75addd74a142800f18ef408c08a2c2ad16a93298f148c0ae7d2990
139.191 -ded147f92f053809a60d4f992a227167aad5b5eb2bbe8a4a77dc77a08b72
139.192 -6acb34422e2532eec7e274e4a42d71ee584f5f3df5a3a5b379974ede73ab
139.193 -5f1b0a2dbfcc8cfac4747ca26eb6030dc2f85a104b754432977850c093b9
139.194 -97ed90af711b544ff682e7b1eac82b2b7b44014b09c17ecf084c994a095d
139.195 -9eeef5391305caf093b62ac9916f982a436d521fcf4d75c5b8e4d92266fd
139.196 -e99a58aa39d7693ecd1796b8851761d64bbca39a6d5a0b4533ae47123327
139.197 -f98d0ad0e8b36625cc3647b55459552906d8a1d5766845ffac101980efcf
139.198 -79657e365510be5db557cefef21193ca3cf3dad175ee2e7ae91d174fdc06
139.199 -2ff5c51ffe2f021122e96df042019d3a1883e662537ec1b69c11fbb6e750
139.200 -0132eabf5803c816153ecbff60ca3b3b39708c26cb1751afb2e65d8e5f4a
139.201 -c4397a88fb1f112672fcdd24e4ba545c5b2a7968c17b62f8e2530a8acbff
139.202 -cfca82c64b7abcab84e2c4a0a7ced67b15669301fe9ff2c756e70ff7ce33
139.203 -497be6acc4ac5617e1f043bd8a87416299a39bf17fc31c02d72d75fdc2a1
139.204 -e60669fa4d5e4a49d9afea2f53f4626680e9c0dfca223529efa415c4343a
139.205 -b6067aa800c484457ea050eaaa5d3fafeedd0eec72f327e02c6b3912b5a8
139.206 -c404de4839c9c4a99da42681cde43316606a34c7d2f02269de1aab776857
139.207 -e668f35946af4d618d36d444bdc02b1f63ea25b6260b4fb606ac8575b5c9
139.208 -782a5de4037350d5753b1537537ccb008c454eeb264e6cd4727c999e240e
139.209 -0ac89e95a896b67d54910a3531345f64198ad394b5ceb52881f1dd9e6beb
139.210 -95862dc188d45b3e46aacb5fe40097947dab9bc3c1ee46bfc9b1b3ed6167
139.211 -efd0d65ceb043d7b24c1456676e4baa47b1209a315f199bb3a91f4374cd9
139.212 -cc0b40d3f09f19f8dd8a46915eee55eeeeb3c7b8f437106ee491ef0f4ff9
139.213 -2c5c6f779e0fbe7bd5293964bb645ca362b106abeb773571d9ae83b786a3
139.214 -d5a4ea3ea970daadc46cc5e6037f76fd20e0fffc47cf4e7af9522b91f96b
139.215 -3297720fd45d9bc2200622ad2ca9445556c8a8202b1991bc63da360d021d
139.216 -55be2528e043f803e08da99b91ab9cfc5e65b2655d78206b4aecd445a7b0
139.217 -1caa0d06b0a55e8f04b70b60b04a860c8e1ab439f4910051e3f7441b47c7
139.218 -8aa3ab8519f181a9e833f3242fa58d02ed76bf0031f71f9def8484ecced8
139.219 -b6e41aca56176b6b32a2443d12492c8a0f5ba8a3e227219dfd1dd23fcb48
139.220 -fcfd255dbbf3e198874e607399db8d8498e719f00e9ed8bdd96c88817606
139.221 -357a0063c23854e64ad4e59ddd5060845b2c4cddd00c40081458f8ee02c7
139.222 -303c11747bd104440046bf2d09794fca2c4beb23ed1b66d9ccb9a4dd57ad
139.223 -a24943461ecc00704c916bdc621bfddb17913dfb0f3513b65f3ab015786a
139.224 -caa51ee9546bc8ddf87e2e104137e35ddf8f8d23724e9a53824169bc7cfa
139.225 -99562656e6f1c888d4dbff0b269c5d1e733e5f212d91297610201eb43249
139.226 -35e336dd0052738db2d64f3e89429903bb5c1810009cf766e9a06223dd2f
139.227 -219b706394a121dc029af55c6ada9052af59682ef7c51e121cf16f0319ac
139.228 -0aa9512ef900c548d673fe361da19052808797e958209072e145d46ec8cc
139.229 -a89fafd76630eff30ae979973bdf0f8c9e469d8edd3b1c93731c72f976b7
139.230 -d81142bc15c376403f967affaa5f482efd57c6f91970729d16db851f0ed3
139.231 -ea7d82f409307b5b436886c1beda94a1fa3ab1b60686f6574c844fb2c0b3
139.232 -a07174dc4f27b4fed2f8bd4d5436be4b343e5efdf0400d235bd910255341
139.233 -a20770804a26f8437e9bce6da8e9f8258a343c7aee291f1510be306ae67a
139.234 -ab1d7696453530c02fd153bbe49dbf62baad6146029cbd1656cdb76c952c
139.235 -b93edfee76fe33832930be59636bb947e8ad285f20f663cccf484fba97d6
139.236 -7446c7b6c6f5857428bb1737d9ae801df75d9cb4d7bd59ef7a4cbadde928
139.237 -38f15d232005585d2e40483d2d3e08cc8f398bb43afedb84343c3ba3835d
139.238 -0ba82a86dce859cf655f85e63e41365e0dbefcf511b9a27a2b6e66b2ad3a
139.239 -c657902842287a317e46ceaa93b5088f09d53a65815b44538af90ad3b06b
139.240 -4e5e2dc509f02e30a01e05201c67d4d39582bbe64e20b669f5fd787909a3
139.241 -30fc50a95b31426bbb57a4fbf9feacdc31f98bcf50da7e50c2bfc169c6fd
139.242 -ccf213cdb878653bcea372968ea6e31fd30dd55434cc91c0af22179ce669
139.243 -a05493f195e12432c6173ae2ac3c94fb83f38210014a9f969ea2b44e99f5
139.244 -e5a7317e848d429ad62167a4fc5001149676c0c28cdf59b8d1c5a582f516
139.245 -3eee855312777fee6dacbf993f5c058f355dbde6552dc960d336eee445dd
139.246 -11d53fd21b745d1e5ec317efbbef25e070d0a36797a6081c356ac2328e64
139.247 -e5c55fbc81dc75d9c1575548ece74b8307eef485aa8e28859a2e0435c831
139.248 -23a600efb323c362fe9f02407a5411c41a69566cd50add324b63ab939980
139.249 -b9d7a929ae4887163cfa7acbfc9fabaab8987a1f6906b9881491cd055b94
139.250 -485c968479dbb05b34ed0cd6844729a692978c6928c3392e33e8324ded88
139.251 -814cacdac8128e1425c0091a13558100d7cdbed5992795d94d39c32f32dc
139.252 -621ab6f3b75187a66741f61d6a9c91d791b1cfc3d0e94d4a76302e0c3f2e
139.253 -cbdc51f14f3251aa5c8bb989f0e13ee500b7b7f2f1e52ca970ad8a7b4b99
139.254 -57e93126254297380d67179deb8ff1e99d5cdf7a35c5bb9fa7b402e63234
139.255 -78640344e1f10c378ad23c5cd1aa18e1e0b308db70d3a624a455f8e291a2
139.256 -ee102ad10776208c2d546cb76d89ca8103a8b95f8acc2d2bdc9791324915
139.257 -6c9e05429091071f0c5b76d82c8d1c8a69d840fd460922cd2090624bc218
139.258 -0c9391005926a25042a55e322060807363462e1cdeab309033124ba3a884
139.259 -1db13f39edae04ec52cde9dbde64ddda1ad805141d4230ec76bd81fd98d7
139.260 -0d90fa1aaa26ea551bf687ddd6cdcf3de5a446b266c68434f07d9c0b382d
139.261 -5816c4e22f22cc03ff78064c6dffb12315c6bcbbf5dc510f5aaabf23471a
139.262 -234efceeb4aa2f9af9ea787c014c5587ef162fc5b35e8f4c23b168c6e247
139.263 -41d33dcc11d2a56d3ba9d8eed6e79aebf9f0faf1a3aeb89d792d69041f0b
139.264 -b8fadfc0aa090effc6ae5e2f13cdbf54b5bed69b039eef2627769613b6f1
139.265 -aefe9b66747fe8feaf7455796740f411a770d4a1764f0483719584880f45
139.266 -430e38d3af184145892a08b2add234a3f3ee4ccfc9f6995c02392adafccd
139.267 -722f366d748cfe9373fbf5f878ed47e9d221fd156bb28369df9e7d2b79da
139.268 -76120d135ebaf36cff93beb7e313c2b2de7477176fc19609a1b906c995cd
139.269 -defef08899265b6b8aefb44da1aadefd1c523dce5ca1b84c0c652b3009fd
139.270 -057789892d4d31764f181754b2e0a62c465587585509989a219711a5e4e2
139.271 -5b3b340ca8fdd3f04fef204b1b722b2f6c2ccb00c3cf1a94ba9bdfbfeda9
139.272 -e2a062c6f1ced3b8aae5dae32ade1fca1001f98d0ad0e8b36625cc3647b5
139.273 -5459552906d8a788eb8bc734ccb65fe9582c71df94fd95d22c5323de235c
139.274 -28220fb9a2ccb37362174d8cd5922c9e5a87b51d0668555100a33e33750e
139.275 -f1f795cbed962494a994be7ce8cf71fc58ff4204551b1615ed27cf088171
139.276 -fd000b72462b67935961e7c6c3a05bfd67b9ba094ea2c16fdf486da912e1
139.277 -e97bfd1c17934535e551cede20c001b5d2adb2be4cbad7d6ba0bdeae4b1a
139.278 -a739f90293e67ecbdeea4d35825e092697fb05b215083e3f3d6be260790e
139.279 -2a175fd44eb1c4c16759504827a6eb58a838c4d65fec6eef108495577019
139.280 -15740cac164111892e8d1cc447cd208e243a89ab847d8ebf4fb98bff49e7
139.281 -a3453facf3b0e8cb67590f390173ddba68324531d2e426aed152e12301d7
139.282 -538c1f3c0048a9cc00c009a1a9138460082123209c1e007266fbf236eb72
139.283 -21f87d4ca38a0b699e84ca230ffb5095f90a6528bf2a9118f95ac9ab8d2d
139.284 -ed9eed9b8b27be894b717469758c8d94fa89acc64f530f432d0e5f16c922
139.285 -36d6a63410f099c9e909450fd731d698ef658d8ffc1de14817b850814f68
139.286 -1a4a9be5cc7a71c381974c249f0b209bfdc2e97f9540c96f57bb4d283622
139.287 -00969b82011315289e6a025b137030a0af3b4b42b00fed7cec49df43c59e
139.288 -3b2495a036dd1b17a8e6adae63bfbbd48807c44b5bbf71813355e1b0e58e
139.289 -22b6fb88005fc55565be49c17244901b73ef02fc4eb7669be5af22d89c0d
139.290 -dff0fc6821d810d13e5821d48d4a71d7e463d5b60bc279d0dcf5f8da3a95
139.291 -905b56d6f2be95e6d4243b1048e3b662e62401ffaa3bc3f5f90b0854b8a3
139.292 -8c38039f61fcb359b06bbb7d59e3b39a295dccd6db9a8b83a6f64ef8dc94
139.293 -a77123dd164cfd1c46f1ee51aa19c3d6e7db92a298d10159f2b5eff2caf9
139.294 -dc93a6d267fb65bd900d6adf0c6be598050b6d3a9b3a322ab3c9e880d774
139.295 -1f58016ff97e5f606b5dbd72ba99252c669209bb556dd5be84fdd7c1ce92
139.296 -8a3b3d3aab8d37e6b740227563bb4d60f6bb04052356e1a48d2079feca44
139.297 -7ea17fd06f208426d045dee660d1d6460455f8d20dbc5ae64550bbdf60d7
139.298 -27d96cc9afef842a8c8c78ea2257e6c6d0d207c80cfe399e8874c693274e
139.299 -d2c2022d303ca50a70624b07434fb85040a76a823f446c7454dab4f9c05f
139.300 -10274eb5ba164aa3649d1bc90694316ba5cb3e7df4442e777124cff7ebef
139.301 -53df2320a0c441ab61666493cb43da46d5711c21699de85bc74359444da2
139.302 -e3e397d4c16234f81531505b621aa242a6698886f82b447104b1f1062f60
139.303 -b5c87cea9151bb3c627bfa4532b06fd147c556ed8d61ae30a8719dfb8705
139.304 -f8a6c74368381403640cc57026d3790c49e2bbd1c0e48285ec6ba44de678
139.305 -e3a1394d659c412f09644b83ee1a333a1f51ad8deb4e6d77b3b226ac2c4f
139.306 -fe653411a7976ae7c4a3cb7df309788da6b483f8a7bab4a6990db74362f5
139.307 -bc41d545a320389b2599fd726e426ed9fa2916ece67b058f6a269544e517
139.308 -128bda38d117f402409d0d8f8c88ed509aa2ba882e0c579b45af4be80770
139.309 -22d7269684eaf0f9afc3054316da6611e3fd260d67fb6fe52c9ade5dda24
139.310 -a0050a819ed21342aac9d25194778beb3145f56a66980f620998923521ea
139.311 -3f957b6ed0c5470734af9f416a16427dd03eff9a0e023452097d4ef936d5
139.312 -49a90823cef6de340a1ee02a52851b310cbcf41ae274947a62f9d1d8702a
139.313 -669023e3caf967204a340694b45fecbda4bf9552f6bdc62d43b3b2c3d571
139.314 -9983c182453e22ee34241ab908e667115f7988174684cd70084aefc55caa
139.315 -f5352a88e9dac45d1ea0e032af61fe9a9118a3931b2050fc6db66ab96a39
139.316 -74353b597f34dfd9f72150de23285eda5e555a607d198c291965a7233715
139.317 -3f4946a57af0b440ff8567b01a6f46c6d32fea5f8bf57d89dccbab7da882
139.318 -ee6c9260e89443b1d7db099477492bd0468850df3db668d741123e7ebe3d
139.319 -c21748ab4c5cbeb5de33b8963aecafe76bba0c4f6ed8e8263a116ed85e58
139.320 -fb71ec4ab0071301be7c7d3afd5fa6ad46c0232807bb7fe129e44bfd16e9
139.321 -fd0c8bb5e7cdd86a78b5fb0669093c22eda9151d85b6f58a9c8ead3727c0
139.322 -09850bd31a8b4a873d0a506240bb2aeccb8dcb6369532f21d9b967aa8443
139.323 -fd6d77cb2d65c4678a5fad188db85940f0a187aa1031dcf5b8e0d0cbfb6d
139.324 -b3b96fedec5b249b7a69de9b42dfa605bd622de7a220cce9b66e9f3394d6
139.325 -13487dc5e82c1e619079cd057b1e19ac05ebdfd7c8bf01c6c66fab49e0b6
139.326 -613df9e42beae2f7b9407a2bff8896d8035cea0fd5c11bc5889cb3d90876
139.327 -61766138d2625f42d0244adca65d1bc73989328c0eea0b97c7c766285ab3
139.328 -351ce2b183f774488a8806c33178090a3808f0ce5e339b87cf7add933301
139.329 -ca486742831ca751f0626864ce13172829a8419af5c78794a0eaa17b5bcd
139.330 -fcb684f7d4bb7af15deb432e44dc7dedf56eb8bea08b46f1e8123a49a349
139.331 -a7cbccf833a528f5e22d2d463040e09b91e543a2f33077b3e7b9ecc64f14
139.332 -306186cdae1fc317a6ced7e9b4d51a10bbbcf2fadff876b4d9082e3f4aef
139.333 -dfef230e4232572f4fa33a6e065f6895aa2ea96c5659cb579b023179f0fe
139.334 -de7ba64bbd9362a7b2b8c4eaec254915629e81d01c839096339b99bc9e25
139.335 -84536955feaa52fa20666f65bafd9b2e69c3e8c15d24fa407e7d881679b1
139.336 -789a0e2a695d13553c92c0214c9b7562cd6a9a3d77c8b0c2196cef76dc51
139.337 -d855c1dac37f96eae4cc7bf07e17dc7c08333d7af33c8b2965ea1f23446b
139.338 -3c96c52b30ea628ad572694d145b58a606f90b278290297aa372cff56b6f
139.339 -56f4aad6612eb7c7bd07db4f7d1a70d8044d16d0b5c1605ee02a852ffdb4
139.340 -450147b3f9b87d72dc431b34fcdc899462dcc1b6bb6ab1758b6a589e91e5
139.341 -8f5196251d00133b43749b7a11fb67a22664c5e38e336dbdeb5509c2d9d6
139.342 -2642c07275949df0e2db59314ae0fb34641fc171d3fe1289f919136d853c
139.343 -d9048ee9db50c699c49e27a8df199590bbc65b23b55bb387eed0c73f2db5
139.344 -1cb091f8c22af83103f214199e371f7de1df23f757817200be30610004df
139.345 -81fe8ed6eba79e856fca21a126ca326ad2f313c16e15754663ad6a065e08
139.346 -4050ff005fc899d6e233691b918a093b5f1ffda8839ab23ae66b1bb7b953
139.347 -0a7f896ec55de6fb9faf1b49656ff2e57488cd7f1c44114c75f9d571461f
139.348 -767a6040ffa14e9fb43096f164d60ca530d7cca76d526d1999ac1b52a793
139.349 -28651112a65db1f2564ecf90ea6bf2c9ecf515640719c3fb5e36cfc58591
139.350 -e227793f39b9d3a9025cb10f324a95c29c488724aa74812366ff0b118fc7
139.351 -19f9fd0f202a040be47ec99b46b4dfc3d2a17902a5779c8d52b27231a1bb
139.352 -5cd794c838daddc3e6824ca8297ba669a818c239b389400faf17aa04b802
139.353 -f763029edb9784dfdc42f223e6496a938e613463bf9bbbd59d63300a9ad7
139.354 -4e71865cac4b4e81a5864388c3886e70799c8989188341f7d17cb514cd99
139.355 -3b211883f171ec6402cc361885f4f4b110757bb3e52941a94bfaebb2faa0
139.356 -3e32eb72e25e31abdde82c2a9015478afa0f434ae3f8b97a4bef598d6eda
139.357 -44ffe1915c26ee0e8339d2d45a6a080550f538ded5542c8b96ca2f596979
139.358 -8bb6223e460e857516ab5a3323136ee8fc4b0556a7c39d0cf7acb45e48be
139.359 -4ae9db325e4750b73289e36a61b301795bdb2ca2a8b933be1c09fd0cd2cb
139.360 -8677df171d36ef1519a2269b21e4103b2ee151c513df3e10b2a216d6fb22
139.361 -18bf2005fa7e0f0563ad96661a7f55e1b5b991f8ca285651b2683c6a7c9d
139.362 -2d1941374989b06f2e9b42a6af60193dc758dd8e9fcfc7c1aa06eab47e81
139.363 -bd79660666defac0c6b9e484df9c17a61ce7a61ef73150e8cd406af6da17
139.364 -4d9c2392cc420eddda40f975ffbeacad8ce1b4e14bee29ba8552ff03376f
139.365 -c034784b38dc1d0ab7bc53943d2545b03d39797af8d58d6dffce56a353d9
139.366 -bebc833f04db321ca8642bbb7fcc63ed2349ffa08a33a5d0d78f4fd2c5ea
139.367 -4258e4671e362036f1f67fcef9d878ae2c203fd9c05200c59cc98633e65a
139.368 -99d912ec51d6f74500d5358b70e799a6817f59adfc43365d7bba1fd6766c
139.369 -5c8e76248daf3f01e7a8950fe875d657397797a45e7f99a92887300b6806
139.370 -b86db61e03c4c09d6cf507800aeead874a94e6f665746752937214302045
139.371 -0b19cfa8db69230517183a03a16e5503882ea1e419c333d3e3b73cef6762
139.372 -873ac06bec34c3f736494483442619f5bbadd86f128a5a40b854051893ea
139.373 -8d31dd6656777ad4ac2572d17c6fb21385b053495d1270e65d78334a4115
139.374 -2787ea89b86f97e72718905a11e9c5664837701a3c1c65ccaf26aebe8dab
139.375 -c1207d5da2079c37883d9235708f370203b3b2a8ec3a5bb35fab93dae115
139.376 -aef626dc44b67ca56fac18caf1c22e6fbab93564829a75776630b9c42513
139.377 -721ca0fbb0b402f4d1db8f701d2b29fa60162feaa8a167eb3113c6f57036
139.378 -e8361357913eb24dd38dc6d3bf4c3176a07ffc75cecf8e5940a310f79a8e
139.379 -f590844383d631796ade04a91144d073a9413cff34fb454f1fd75cfbe5e6
139.380 -525c3bd36ddab80138f6c19aad7417d47df1f1e0fc958fb190a8205b5321
139.381 -7c43a4dcb0599be404473d6faebe7240dc402a0e0caa21b56a601b154524
139.382 -f44988e5074c71ae8e1948bb2a2ce72fc24cf3b1813cf7408a6b097aff22
139.383 -f9d285134d09b7053464259531eb7b270cd5f39f81bbf41a36420f61e5f6
139.384 -b429036bbf20e27af1a437becd74c5bbc25ee2519402454fc94d430636e1
139.385 -736fe65a643d9b9d21c9a54eac5a8fed51ff60a47b85a0e9423e330e00cf
139.386 -220c23e056d20aec2fca3e6bc7a61a8366eb940c9bc99fb90e8704e27655
139.387 -20335a983eccc7e20b13745c4b4f30a842f1ba64745718c152697c688c73
139.388 -6cffcf5cc8eb5756201560413117a45ad3d264291cd51404f98448d31474
139.389 -d47d17d201def12867ba679f0e2605de8f3e8135ed0234890cffa68848f0
139.390 -6de427741b34c2ea654251ae8450a152538eb806ace3ecfe86d8c4a137ec
139.391 -c98c6d6cbdc191a5f8f5b5972c70b4896960037b6d4c7c63586a52d5eb59
139.392 -47af8c192eb980d0801fa670bb1d08740819f9da1dd9e153010bf9580a1d
139.393 -0925d8327ea1b88db8d934f40266ddf93e5ea137f267847d826cd7999b33
139.394 -c795d0ac05abe2ec1770dd98eea67912f1939118defc9b379e237d6477bc
139.395 -91ad08e0046b0836fafa1272b0213dce990c90815f5b30d0eb103ac9539c
139.396 -2f7bd2280264cd95b4be84cbc5139a7628ed211905dcb92cbc3180ac9e6b
139.397 -b9ecc3cb08608b2395827d5729781dea49d328ba0c1b4cf2cec9f6bbc822
139.398 -1f2bbbb9d88f9e7682b9ecc06b9705faa8a90a51678183db1e24cc2c4307
139.399 -e16b3c20f08f179ec69df7a8c4261427f5886f9179c493bf2d0ef36640d7
139.400 -79925585724aba69df6d1b4f0bd2a356eedfd74a88bea667b102420c2300
139.401 -ec420e99b9ce8be1472b617e1255a7f43a0b52f11657f1a4dbb624a24886
139.402 -9604fe2062b98f5787d010723e520a4f42a0c3943e151ee627f3d5db90e0
139.403 -7747e1a88a53c4784c8d2b042b9c23c9e436d7d88343171161a364cd8961
139.404 -37a19582a00d774ef01c7c3fc9e9c7be5074c858d2bacd707a6a4f322027
139.405 -137d6ca0421ed9f9c7e7229e867678e5272cfc7156a419e893404ad7dabf
139.406 -a5d8b6fd0787cb4fe1a901c34dd931f1b64f0c470ff807005fb66350d0ea
139.407 -eb84ebef2c2399cd14a4454ea5004bddd99988b39c4134b92121ec77faee
139.408 -55cc716eecc58b594b39c41dcab308efa4458ed71943ec5805dcd0194ddc
139.409 -1ba04a5d3d42d07ac62a907ea25cd2a7e77aba470324d41dc1a3fe088388
139.410 -787b3312f472cb4f23a414fa5f7c7a0cc5d121d7642b5b3f0cf7ca2173af
139.411 -3f878f374938251feb3ce5ddd2d7703fc79a130978ac516daf70ae903799
139.412 -28bea3a4296f48725d578d2e8fb0f932e398404fa8a242024bc011c0ae81
139.413 -7b92bb104712253a5d89c543a744332069e33ca08bd133211d233ef799f2
139.414 -fed6a20a9073021e505def8b79e1279dacc062cfd4dddc2e8e0a7fda5dd6
139.415 -bb5a745f99cccb7ec1df532308da3da0f236c74639c280ea649b2f7ec27d
139.416 -24221470b642567f3b2e1cd0b3ffa65c5ac986b557aa9b444bf470380435
139.417 -abae9b51c6da7ff753810ca7938d8a1c47d2b41fafd236cb5998f3ef365e
139.418 -1f700bb257679ba3a82e235a3e97a667a6ad94412839c96dcd49dd86ccbb
139.419 -6df8ad01756b311e9fd57ccd2eb2f19f035e214804e2b77769319a5389c2
139.420 -35f3ca2a73c616c9ef0984abcba167d7d652b330c68f4f6378aba69628b4
139.421 -2d59eaa2a7e4c782f6eb96f6758d17d35650b15cb5de9bf973b3b6f67c1d
139.422 -f3285be8322fc2b44359640a3ba5d6d7b96142583a00a9a0ef84fbf14046
139.423 -09ad55b2aefe8c5c8f58ed21623bf765f81dbb6cca6d2a51fb7730a14839
139.424 -392cad6b47f5e03448350ab36a37d9ff2b9dab69be5196511072b10cc91f
139.425 -2e6b5160b2b1bd112e6c02d14063a9bb46977b0d4bc79b921fd942f916c9
139.426 -c5708e0d133c8309de2f6ee0b1afc996c889c36de20fbbbfd32878f477cd
139.427 -7735c7c3fa59e9c46e654ea20b4381d9f6c6431082e6918d532bcd539284
139.428 -af0333a783c9e7fd4fa1e4da5ce8fea2ea4037644a24532d65fa5c1ee982
139.429 -89e4b9abaf71a35d308a9b8c337f70babc5fc8dbb0327143707ca5b675c5
139.430 -2d3cf09f7a4f667fcda03d8c82d157e661517787ce6bfb35ea772de13c66
139.431 -2bd24b74ff9ab0fbcf6635d8e06b54b5b3125d17ae13d175cb7922338ec8
139.432 -9d1159fea2110995ce48f7d2b094f06d11d59b3a64a44a83d48c78855e47
139.433 -21243e82d9858401b094a236fa0a90d61863931c30d13b9bf33a35ac0d11
139.434 -a999f2b4dfba6fc187f8c235a5217d777a5a97112e7db6a8a4b06b07d9c9
139.435 -f41820e233c8b58b9e47ac56ad1ddcc0b35dd03976bc776c6ac3692ec0ca
139.436 -f8c75ea7825bc84156468ca7b269d890ec9d4a365b0b31d2f6530185d5e0
139.437 -2acc3ce14eea55ebb5667067825a8682e135d23c78863d32065ddcf1a755
139.438 -e0de6dea7220d1a28416b96db40b1e9f159aeb070c9a9515f301f162b0cf
139.439 -e32c6c89287de6e2b40458e3393826189a10af8517ff5a10c41c9d05d999
139.440 -aa9305a2ee8e7fe46076bc9c5722ee0a140a144ae383e84a8abe70af5d29
139.441 -96a0a896cd499caa0ed7867e7c3aac563763216e7769d12218b584d853ec
139.442 -01db93ca22d0c8d6b286b20b6b26d6ef19f2cebe7030ecaa68d069fac7a0
139.443 -09d61770b5e8f83024a99142f59d88297cb8d093992c3c6c11b043b151e8
139.444 -20df640407d8bc829bfc196bf2901e63c6f16102d03ffb7c54a7a560f5f9
139.445 -5cf8379f4a2eccdcb604bd553e6157b4381940d1b3c768dbfbf2618812f5
139.446 -7fbe744b3d8ad680dd9223d8bf2412ecbb614d05b485e3b4669d22b417f5
139.447 -02cce2d705c208b15fa83b5be77ccfc1c840f385a58ae49fbe6ab4e53912
139.448 -473630e0cfecefab95ebc632a2b10a2103bfe801ca0302542080cfb4cf4d
139.449 -4c241b1a6c8d28114516e3f1bf39dc02db73e6d9a797279acfd79b02a71b
139.450 -ae34860dd0e11b18954129f8dd57c039bb7063a4c92f0f6a1e25f4ae59d6
139.451 -6c1cc6b73a79d6a56f7f2a8a64d571caa8a760f4f485d770d000ddf393ba
139.452 -784bb27b781c47678dd78ae9b5d5e8b57d163c42c7a55e4aae22061686bf
139.453 -aebcede728ff2f65e75955585208c176d100912836b5200a79062d4f09b1
139.454 -ba9465b0e937e289160ec543a4cedbbe0cdb5ecfbb4838138ee9e1ac757d
139.455 -3c5f04fb6b510b389e2f521759e403bfc8ec6bd79e2d40bdd81901c10dd7
139.456 -4620acaac9108940daf03af23f09d3c8b785db562b05e597056406557857
139.457 -e96fc8bea53c2c2ccd0ea6572abb0acacfe29e737173d665ab6dc2995f60
139.458 -807aaa4073a183aed23c26c67eb137c937999fafc63b66a021125e4ee5c1
139.459 -a745ad1fff2bd828dcef392052965ce0e9af7a2c88d730fef69da91083fd
139.460 -83d9fe9f73d42a8dbdcaba85b0fa93b210dbf49cdcbf5d4b69e07375fab1
139.461 -a39038cc51f66f0b10eebe0cc61f697f7025d9755830b2d65f1ad0db91ef
139.462 -ebbfb578053de329935bb28d6ed6c12f748a2f70458990f04d56c35557e3
139.463 -8bc5d2e5de7f52bcf00c3bcce091aaa8852d53ac686f8f407baf3f7c8968
139.464 -69f3b62f44a5e2291aff9d30d7b5c663658a41add74562dbb0f1062f564a
139.465 -9b907846291700151de04c1a55cb945eaa2e7a709218ec56d1becce1c0b7
139.466 -dc41d5f016ae8080c3b07311590a0def35337fc3c844c0ccd04926be9fec
139.467 -509b1255ef12f368d20601b1ac8c68b0a935f987a21de0f8191604e921ea
139.468 -0c04b00dc188fd73499852dbcccd4119ef799472b353be7f7dcc904ddfdb
139.469 -920839f3d4a13bb1796f2dc886f31217845f8d7a543aabbc720311fd0e6d
139.470 -a31ad3daa06d5e7e6270a34304f35ef170a7abe733428e96b0522fddbb5d
139.471 -eb35aacec147067fe066c9ef145246fa3d444d176c274b91fddb8a7bd7ff
139.472 -7cc7693c25895bf931eb321dc9d79f662a17691f9bd1662fecbcecf6d1f9
139.473 -cd8ddcda56d19811f05fa48bcb492feb355b0ec7c04d6046549c56f7799c
139.474 -2cd0d9dade8809de7d510702e525ad9cc82c41b4fb36218e3d72e905c507
139.475 -159076a9c0e4a008ccca17bd594c69f5eee656426f865fc1988d677b72ce
139.476 -b710b29a0aa8f8337552ae30e93bf7c6e5d013555872dba4737dc5f08c0f
139.477 -efd428c66fc8da675373f13f89102688977e18e14dedd7f3b676256b0263
139.478 -b66b013617d9a026794b0d6040c23c5506a98530249633a6beec46117c96
139.479 -ec036eaf6439e25b8e57754af5ebaaf9b57880ad4fc93f002fb03e9fda21
139.480 -df4acb78296b0c49a5a852c134c3b10755177a0dbd6c54ea7a2b9bdac62b
139.481 -5d7f3da649df856478e4baf97899e0f891a96536c283f5c81200c51c6ab6
139.482 -77285450c7f7e96836b6da5660f6cb76782ddfc64b6fc348ebc3ba4a46f7
139.483 -19176296d8c5a31132b3fa7d935a5d777c1dc84d669d564cb4fd689a38ce
139.484 -680d0b3b130caea0be43864826d0d154019fd0d865f1c389cd367cb5248e
139.485 -24640eb6f66603e50581f6fb5aca6cfec1d6dbf4196da10a5e1ebb14e4ca
139.486 -0251c4c8412cc1673d6e7a9666b04b090567efa0b830d2362fd384cb0303
139.487 -8a40290597bdaffe429bb89fb66b9dfcfa92f39d92a8baba7266d144ac04
139.488 -f069093ebb3fcea961ba4497d3628ad207e0c8c4fac0e5f3f2a663a8d05d
139.489 -b6dc33b890ae13d84dce64b495d24cc749b121659373ca31cee09bff2e9e
139.490 -e5b62e89d5faa4482a75f341dd172500a54b98fc108a69a3ea94db696513
139.491 -d4c7691e0095ed3900cd4489ab008b5460b34ae8dedf3721c60de7086605
139.492 -6c391137cf23255c565bf11403bdeecf8bf39ad5e4317a4bb37003b2e7c1
139.493 -400c3b8ed7f63719bddf07908dc2decdb0f68e8ef722851c4420303f6de1
139.494 -b5efc9b2598732fd1f2cbe45a504bd7fbfdafeade3add7274a1e875aba3c
139.495 -4e0abfc6444944b79f95b5009560818f7a0599e5bab4405378fadfe084f1
139.496 -653e5a0166714047e8bd4e4cb116596d8089bae9147ec1d62cd94491af75
139.497 -a1743d58bafa11b63b447c954a8d7fe11d39d969feac8fa93c614f97807d
139.498 -ac62cb7a84a974a0fa555a2e3f0ef662706efcb828ef72e2ea83b29e212d
139.499 -f89ffecabcb08dbb7119203c4c5db823bf4e8b698b763fbd4d21e57940d9
139.500 -1754959d21f3f649d856ac6615eac692ebcbac555f772eb6ba3cece5ebfb
139.501 -cfcc2f3d8dcad7edc697df93aef762cd47cc3ba9e2cdd10940be676efe7a
139.502 -a3749170edb47b7562805e3f8bd978b18057c9110ff8d19b466ea238af32
139.503 -993e2d3021745b238021f824d887d2e01a7ff12fc6f084b35292f4864579
139.504 -406c0f61d0ac7cdf7e4770b424e2ccc22353e6c82bf8ff172973df267ded
139.505 -bdaabc2a742beea02e35b9b253f98de9ca131f802deee2905ca1a6dc4608
139.506 -19a59b4a4265c723007d0215fc8ac2a91ec5f86cd6aac1e370a297103c3a
139.507 -3cff58c7ae201cbaaa8a12c93e95e73974f9abcd678451b1db02ebb2e10c
139.508 -c5abfa573a2ea4219fd1851765649318bb556b728d432ec05a86e9894aad
139.509 -9cdca63d08642655801bb37f28b6e11b958e8e800c8d521ca4aa045fe9ab
139.510 -ac02dc015d18b1901d519181ef60227170a07f3328a6d5fe4c5aedb35fc1
139.511 -3dbe86564a9b1dd4c7ec648880360cdd1742ed4ac409450f1d9681cb5e46
139.512 -5edd1de2a2c7f8ed63436f98e849504ae71bb872683ae107ad5df3ca0b47
139.513 -a5b79513e02d7c540257d465ae4521cb3449d79c931e2ce8c5b0a0a4ac88
139.514 -cef7b9e5f92bf721ad51682d6b6f6c14747f78eaac1891fe29aed4eaf177
139.515 -e3d2fc655ae889c0c30a3575a76c52e95db2f6a4d8ffee9518391954b92d
139.516 -39dae4e97c4022031f8ab390b66ada6dc9ab2de4d1dddf26ac4032981a69
139.517 -08f73d34b4849ae28832cddc0dcd116a47d9262b0f93c24fbfdf8a78e6ae
139.518 -ae3357f3fb89530854257a9db773a1acf5271fc4ca04a06b46dbe661ca11
139.519 -9f45e0080cd129e1a7c23a33f1c48af960761b117d9d91fa5a0ed3e47865
139.520 -b774a322f7dddfda2960b91fa7ba20c8f9eb213251299ae328b28ef54b0f
139.521 -55fd54f8047c555e4045cbd70964e1c953e471408e4f25fe8ca7009bfe44
139.522 -0244b1e30dff518ea7ce5078027baba4e07ecf0ebecb497b4bd88f1ff72e
139.523 -b261f6dffec0ed895e237b5608d31ef479e8c9ae9003039a5fe67252ee39
139.524 -774e1501100c0fcf154f5c5c81c70539e03118ab91f4ce247f6132d46346
139.525 -bbbb126c09d7459c1977e6e367a0c83d14edf7dea081e5f795a7c831fd1b
139.526 -325b33674ec9c2b68029a0e600746329ea2e1b9bdd5cb2b140468e53c108
139.527 -8e8f2567425443f8146ec37101fa4dfccb0e032fff6cdfd76382463551b1
139.528 -ae8ca6cbff0e34a3f75ad400a9573217f8cbb00a6d59ff46e48421e97091
139.529 -cb17f53f20ebeb89609ea55ed6ba4101f2f3ceccbc7ade21202439ef91d8
139.530 -a9a783c22de7e6601b50c4342e094d0eff223494489fa92150425da1b432
139.531 -908423fb3f41e0b115ec1ba592a4f920d15610b9fb33f9912aba67912d05
139.532 -1ee00a13282c1909a3a56c4ed06f2f4d1739dc296b7492aad0446f87a416
139.533 -c6db4d42b504dec3a6756f3d0845ab2d2e151aa5fde12b31a9c3b5ae1cc9
139.534 -d97192bc048f00dead66940004281c4d5a92c20b1f77795cb4f98b8eaa7c
139.535 -be16f9b9d4a34a1a53e0a0deadb4fb4b20d9e8064d3412ea8d2ebd259b8f
139.536 -2f04bf4bf11a5ab7883c99943d762549c3d5866bb6ed85a0e862eafbcfc7
139.537 -03bf4b77cecc0d65bce4df33e0d65456397f231f8cbf66672457cf539817
139.538 -6aa5292fae24695009e55904a04588659a3a23fa11989b925705ab45f954
139.539 -6f862b0e176fddf75b70d9ef7389f750becbffae25d58a1252cc04a79e13
139.540 -fbb6a666fd87cec5562c3e14fd78ad05be28ff3871d6fceff5aa8965bb65
139.541 -67ec76d105a6348e915b27767f5010011e80e0e2f9c34742a4eeba369e66
139.542 -8faf086a45ac9bcdd76c758db01a78602412a4244c759ece0b963d9ea58b
139.543 -0efbf4376bf115288803a54cfcf78584c8af80da2a3324096463e3898285
139.544 -57de6c6354444b12a74d5e66053f6907c48522cae9e93bccdb4632131add
139.545 -52eb374213888125de71994c31dba481b70b2e4c1f10b865d58ef09fc9dd
139.546 -2ca7f69bd2855895256caa5dd6bf7d4d8b341d677c56ca08fd7ba37485b1
139.547 -444af8be0dcdb233a512088936ab4d7fc8c03139df396b7408747b142782
139.548 -d9406db0dcd31368d2f23ddef61b0da3c0704e9049ccf7f904548c3ca963
139.549 -76eadf1ccf77f94c157f5b84f74b0c43466134876a90c5fdc2c53af70c3f
139.550 -f5c2d13cb665fed9016454bac1a629361c8ea62f4b2399233e8587db6e75
139.551 -a9cde3530f20a68ec155d275a4aa6f63aa5cd115244643b54911c954feca
139.552 -d57be2a6c40f1bac38e393969617b066f7d94e8b18dd80fccd0168d4a385
139.553 -f2f1489d1dd41b68d47e5ec66ec568333d1f584e3dca90f1367a990630d0
139.554 -14355be7dc45378aa111c319838edd441f15e125f928e044640f25ffdcc5
139.555 -c116c3f6ce0d4d3195187b22200808366eca9b508ec45e664e562186efec
139.556 -a97b22835d384758849605a01973cd9ffc1657b124950c9d9fa3e18b1a20
139.557 -7156c4f96f08b87824373c2865845d17a0dda71b1d69f5331c5676d0648b
139.558 -ca80a7958a2aa034d7e1e9fafead9248e6e64f9ec327c60ae4f724e1fb95
139.559 -8a71e82ac3842768b27b506b5982311557432dc3f270ae6eab23a42fef70
139.560 -dd0d407a02cbadeb7b8b74a2523cf46a5f61e52b053c2007f75ae053a96d
139.561 -e00646662d027d93f950e516cddff40501c76cd0d7cf76c66b7bcd1998d2
139.562 -7a19f52635c8e27511324aabbb641dd524d11d48a946937b7fa0d89a5dbc
139.563 -4b582d921811b3fd84c2a432dacb67d684a77ac08845e078e2417c7d9e08
139.564 -bd555c5265024aeb55fef4579b46f8c5e79770432c5349d5a65a47ce9338
139.565 -e1b599328bb1dff2a838f732852f3debf4bb9b828f9274d03d7cf813b123
139.566 -687c5e78a26310d87870bfcb0a76bf32aa20e46f6b2826912e562f503aed
139.567 -11e427b7765cd2a68da2ec0609259ff14f57c07963d075e96f8bd2eab9a0
139.568 -dc32714dd8905f2627c6d6f33563436bda2d7fa9a976f88947b84c72f454
139.569 -bf0b66ca84470375d2ff252b4a2df52ab613d0c8ef0465ff1d809ca82025
139.570 -c2122a8f44c56ebfa25690bf6a05675ebb8634ddfd24c3734fe8cb32d6d6
139.571 -c69c72a4951cb959175770b4286d383e7a3f158450945c8a2ccf7e54fb19
139.572 -aa8d2d98a07f0c55f834f2728d89f82a598269750115a02287c4d415cdaa
139.573 -14e1d9e7032684002f90603c0108dd26b40fb569bb21cc63d0da7e9e1873
139.574 -9df0a9c85bc340d2b0940860d95571dc244628c59bab449f057e409e58ca
139.575 -cc3369f4baa8e53c6765a55620e78341dae06e5cdf2fa5e5ba58634b29ee
139.576 -ddfee7f78672e55f18a7debbc30862f278f83f4cc123ab591371f548fbf9
139.577 -bd24b3453b9b57051c2e67edff2104f3a05a9f0cb7efd81c1b1b0a2bbe95
139.578 -21854902526e5d4fa1b3be270811b972e8726623410cec7911c07f871428
139.579 -1caaead97c503714eaadb14ae5923f020093722df1b9d9c055d7d5f95af2
139.580 -a9fbc5ab6f6c2bd655f685534d7dc5fbb5ebded6ccdcf369bd83c644dc62
139.581 -84c2810495888e9d8f464a42228cdc231d5b561c6b210bc493fc1e7bfd66
139.582 -5a6c4055a6a629f571f4f05c15cb2104b4f9d0bd1b1f0ab8252da384eeae
139.583 -f5fd5c663ad7a2c29f65a48a30ed8de196f9eb8ea314c6e86989298146a5
139.584 -589f76f12664c8d008228b33144679d16ff564453b5e4e9f813191b6c99e
139.585 -2680e20a410949ac30691b1428a255b6185b7e3802e8511192e73c376f3d
139.586 -eb807ad2727fbb4b27538b3213da0746231b1c1b595a958466155835c537
139.587 -e0df4a0ef272d4c3f7f2ef011daed38bc58bb0fd7458e48060db98971bd4
139.588 -b24bc7bd0de92573a1c7a80a5fa2b34fbe50271dabeb83aaa4235cb7f63d
139.589 -6a6b399360df8b1235e4e9ab59698930044a98d5e083b5f5a5772309b390
139.590 -9e1ff2a252734b32fee3940f0e1ba61f54dd1d3f6ff0d57c9ae75a302d14
139.591 -b9dd9034279aaca80b6bd05c74bf3d968305a5046910871223a3ef8c77d8
139.592 -25d7e6d3d2809e76064c473d1cd7c05666040b6eba647e34588f49fd70a0
139.593 -3c937933a2272c938d2fd3aa8149f215bb48f3bb45090bcb9a6ace393a44
139.594 -f1a9bda2ad09a5f566b2e8887880afa45a603a63ffe7c188e3eae926a903
139.595 -4f1803368e773f42c7391dff1b9ce8599161515c549aca46aebae7db23ec
139.596 -8f09db0e0f590aab75e8eb890df354b37cd886bdc230369783a4f22ab51e
139.597 -0f623738681b0d3f0099c925b93bbb56411205d63f6c05647b3e460ab354
139.598 -1bf98c59f7f6c2ea8f29d8fe08df254d8a16aab686baf6856c4fed3ec96b
139.599 -0328738183dbc1eebb2a3d301b0390ed8bd128bd8e7801c89941485c3c86
139.600 -22b5f223cb07dca74f0e8643240044e8c376abbd8c82ff98c6dba9b6d244
139.601 -5b6cf4189d63c6acd6e45f07485a0fa55eff370da7e71c26469740a68627
139.602 -a3c297d2bf215121fb67815b7b9403aecca10d21e59fabcbe38f5ca66e7b
139.603 -551b22e28f2d1fd7303d15a42c45bf54b40ef7fc93060ae5164e54f91c55
139.604 -20bd303a98d0667a02a900813b260c0343021ac01872fd62cb6abebc7ad3
139.605 -a4456805159839ca4a3e35db586221169ded66f852e8974e3815d4d7659f
139.606 -6a9bb93585aaf264f06cb6da6a26e51683945224158ea69719b8e4e36eb1
139.607 -01333aac974db8f84b051724cf245fe7a4c86582b5dbb9a5d9318180e33b
139.608 -8d92c22c44b0d18f8ca34dfa4ee9693c1a26fedece01635fc5eac1fefa81
139.609 -32458254ad46dfdfd2be12a1e7f32f3728f286f1d5d4394424a073696b65
139.610 -e3c459aee9310752231fa703faf35e11796c4eeef698f4109ca8c46ee322
139.611 -5dc2e3e04fa787188e583321f8410b68b9624ff60679d3f25c13e5ea7506
139.612 -a3ce8d0bebb99d9a959ad92d8cf909988d9250b310629903d6bfcad4581a
139.613 -504b91b2c91889987f36d6fd0be1d0ee5aac00aa0cb48d78a1f7a64a777f
139.614 -089573ba79452efcc31c8258fb317369feb0d7ccd48cf13da6d1ccb59a4a
139.615 -48ea0b398e590c1169113fed81639e13e96aa268d99cfdb7aee977fbe85f
139.616 -f784853a06642b5521ae0a7f610c9739af31ba7a5157ebbbad999e23794a
139.617 -d2cf25af987dc85dfa29639957cf28e7f2b7671188045130a6e2785f8d8e
139.618 -30e91f0f68c1cc9f2de902952730003e816e4f5703db7a97b4c566f80547
139.619 -42fa77be563ef681a4513b9a68b2b0956551c74545cc9883428dfa72fd5c
139.620 -4eee93256b26bc86ea34f7427cb0c0cc22c0cc343f739c6c0c46d0923675
139.621 -5e04d70587426ef875f8c89ff8492ea23e4e4d763b84a6437a440e69eb70
139.622 -65ab6d8cf5f8444a844e6ef3d158b451d121daea2d0e2b423eea24254226
139.623 -7eff1b4224c4e80af2a7becac1649e4bbef09f39415e9b1e3750d7ac47a1
139.624 -068a4f5ce30840b00574eb4e683e3ec25f6e690feeb0d354568efbc354ba
139.625 -813ca1400734a67693af127b0f636d58b83e91548f98e3d87da7fd7cdebf
139.626 -f3ecb4b9272d1c83d4980170378d32f1d98b87c440881af9ec052510982a
139.627 -0c02ba6743bdc7691a44bae5e044c25304c1a2525cf2c0694494a2e9aa34
139.628 -f36af43ab288807ffa4bd418ad51d98c75f2b2f01abfd834d3305682b6b8
139.629 -62ef69d05962aac485bb4f560583a5dbb74e967eaf6d299160753ec32249
139.630 -bb1d9851d5441cb0c624208e69dc876cd8841a66976b5d7f9c99be68363b
139.631 -8112d33d971f2c4f2a1feca88ba1a794ddb725c5e2e2c248082231059aef
139.632 -729bb5fee5006ab8809f63e162fc0743c047c7984a9e6333b433fa143d73
139.633 -72d4a74fe37314508e04f54dc7a1445e2d6178ec9c041d0cd4fda5cae830
139.634 -4b16feb21f3222261c293a8b058dc708405c1a97ff34eee4ca69ff4e1ee2
139.635 -a03380d52297574e3aa50c8afb826fc94a14e8caa9ba89d6e92913be9e07
139.636 -bf7ae011e6bd142d8952d9c2304735e875d1ddcf82fa9fc0c6449df2acf0
139.637 -d5f6cff6d21ef6b2d29022ed79c4226c97f163284f2311cf34d5b0524a1a
139.638 -a446645b9d05554f8b49075075f0734b3d1ea31410759c174fcc7305d2c1
139.639 -d7128781043cba326251a3375784a506cf32d6a11a4876f85ffa2606fbdf
139.640 -27dd16d64b2108d808e33c409dd33f6e0c6079e47e7196016f261e824fba
139.641 -b0e4f91a189747053e648ad2d942ece8f582f052668b63a23a2fae4c75a5
139.642 -180db7811aac654270ec6e341126e3561429f1d41fe7ba3f1de9f8bbb8d9
139.643 -fc5cebdef869376a2e42dcaa578c0807835e58d75c39f91a83d5c1eb86a1
139.644 -b0f7aab991f65eef030f212d38d10b1913bff71717c06c78d9a1be136f21
139.645 -4be157ba11ba309326c55c23ae8512646751fb82ae200c06bd2e644bed38
139.646 -c7cee826cb587ee8ff378b7fdc00ec316bd4a9c24e2c250cb3d64f8ecbb8
139.647 -7f4d81626d7f1e4491908bf17c48c84bb1736693eb4d0fe634484cdd590f
139.648 -a40ae94d44f348ba683a43004b487f047745fcdfdee2e913328a11a99530
139.649 -9bd117e0e5be4fb25d176d59dc2b1842418141190ed9ae1f33e5354cacfd
139.650 -a5e4bc186119e1461bcd98517e675276ddf0296d3b3cef617dfa36b4759c
139.651 -944fd721e1bf63d45cea90b5817a40d153a2f779e03487cad3c1375425ac
139.652 -8cbabf7f754d16cabe45c65f1be4441908e0969d5a5111c931e724537dea
139.653 -7cd3fbfec9b2f7d3efa747bf586e9218c3106c49276b89fa28f770fa0644
139.654 -fe1f3fe3adf07f59c755a5b39a2ac1d6f23c256a293bf3b31b6b9cf4c622
139.655 -b188d6e7401c038657c78bfde9ba09f508f1bbe3ed79793772cfc928c4da
139.656 -519f7dbf3ff7074284437d2de8d7b7c78829642d924abacf353119e9088d
139.657 -14739935a23667c432806085c3af71ffb7c5fe6b4412b9b1044c1e62ee0a
139.658 -a5ce7e0322bc65a8c7d874270d84136526e52d0c7f9f93199c6bb7301216
139.659 -a19bebcef3c5633f21d012b448d367157ad928e21f8e471e46982bc46a7f
139.660 -df1bf816a86dc62657c4ebf286134b327ce363ab6a66634eaa2a42e99034
139.661 -069fe1302febf06959eab8e7304da4d94a83ac1650a02c38c1c4b7e65c43
139.662 -e3a6fb0213e57ac49e58721a4f36996069caedefeb48f1a59303459d5873
139.663 -f3bedcdb9d00c1cf31130c27b60928f210e1aa5e1c8e04b86d2049f31265
139.664 -9198fa646c53afa9058eb8ceb41bda65f415c79ac92af5790b176de1d300
139.665 -f1c06b782d584f458dbd07d32c427d894f84215a8e7819e295ee98d976d5
139.666 -644f11920ff2f49cb1075c3bb42b9fe4b561362902f11a75669b7e7c4475
139.667 -b65f1ae48834cd67816eb63b58cda2f50bc22eeb0cc965569b476bedded1
139.668 -2701668f609393659b266bb0e37bb27afc90bca271366e34754383363592
139.669 -0f9a3b508aabfe8deef585b07a992460c592a150b325b1e50e4214a2f483
139.670 -e9dfc826c54b488493a96eaa37276f5a9666f0a5388fe388263d2c0cf614
139.671 -c6cd01571da4389f01fcdbd0ade1c435d64c5921b5bf7dbebd5268100a03
139.672 -1e1abb8cbd83873089a9e08cf80276c7e30d2bb40280278c29fa818eb079
139.673 -87623b1cfe13e0b01e27be0a8320b69b5afee820f4705202158b7f3059b3
139.674 -655bc28a754d088fde23d43d6a9389da8bc1cf3e8ea1a6f4328c196e655e
139.675 -42184444d8c0614c7167c91a492c24c8357794c61f5e47cdaf4b38004a5c
139.676 -8fceaa8151e929328bce1b8f67b22034f3f75e4d105283337c3d460e7d99
139.677 -89920c43f5e1449c74ad6ab5ea029cc6e497ea60068451c4ef2132fb87ae
139.678 -049077a156c868b768df4a4c475a532e2a22d999931c64f8bcc18f51d25f
139.679 -0f94fbd3e9e6c094f78da062f80c4aa2b86fa572cc469e629deb4ba0c553
139.680 -55e8422b562ed2f694d0e8e5540144e30841d7593b255edd4a61dd345d5a
139.681 -00e411d2c50d64782a3ebedf945fc31c00d2fe4ca800f5aeeaf12ab399db
139.682 -956362e979bd7ef0787188e43835e5389ac444d13204af6bf1875622f175
139.683 -09f32015c28729cfa3b3cca90308eefaf260e3fd9df10f3e76786b8bc0eb
139.684 -a30e8cd33689aabc55e3ce387cdb89a30573495852a48009cb58a0fd34bd
139.685 -da911159ccacc94698ffb94c5f45f15ecc9e82365174cefbe746f95eee44
139.686 -7a33b4d823487e203478eeb2d8c4bc7b743427778249c56e48fe17d0a501
139.687 -7b693509ddfe1f42bdef97aedcc26ceffa9357dd985cdf2c70bbfc987354
139.688 -6f0aa7df227ec42f9ca2482f58809e3f9650444568c54d3520bd0a7301ef
139.689 -48bfebef1fc4332b5ca851fd786c1ece136fe9e575b69393b5aec2611903
139.690 -fae6e7a5046e2ff350becb8700f209b1131044afd32fed1bc1297b6a2f29
139.691 -6ec3b87f170e92aabacc8867360e4dbce9ea29f0c1df981f6cecc8986767
139.692 -0ccfb4c9faeaad7ca9029b8ff0129fec4a040f80ead041b3bc8af7526675
139.693 -ed9e13204e64d76440a097d77c535d34165bfe9ffcade530abcc75ae224e
139.694 -890d5c110004e218bd827a02ac7340e18bf3684c43e664e0a37d5fd4fd1c
139.695 -4d4489d25a99d542c16e06685652cfa3567da4eb0cb517be1482939da0cd
139.696 -d0ea3519ad1e51bd9dc7b9077375a8cd3b5de9888697e853bacddbbdd1a3
139.697 -0e442e1d6f2d652046821813d0cc0e8f16c97cdd32daf239f5b2b65ef620
139.698 -46f6e9821b2e2ec539302747795fa746318514d38bdf0d0e490c00e114d5
139.699 -03e7fc9a8fb83b14337a5bb4d640b52630f5450bb3bfcf7cecfbb1ef5192
139.700 -ae401265450db197bcfa07315ff95a809bc5fb4249e3a728a817f2580ae3
139.701 -50d8d6577f79c883ab4a3119d9ab98219aed0d1e826023a66da814396058
139.702 -d95e52d9af8bdbcb0454721f27855b686d13bdb473f650c9865f3e04f08d
139.703 -b10f5256a3e59bcf16b12a84bb7ef3b370647cdad5929b722a05f5b3669e
139.704 -14c232bb82fcb9c1dd8155ff4515f4e83c895cafb86754e896f38e5f3beb
139.705 -5d29f1bd99cb8a09c5e50f412f6d8a773b79021ab2c4831aa663c5defc4d
139.706 -553616874dd5bd8b75c7a2af7d029aab5a72528fbc4b5ee3d30d523412c9
139.707 -60b432434017c4cd68b2062d28f307fc287e11663511d1a6b52143afac0d
139.708 -ce0f7ba3f326fb707fb8d2c985dd60090e6664f2344e098a7a1a6448026a
139.709 -2ee651e8141cd7786b6543f512e4c31d25dcaf6652b1eb52706300b771cc
139.710 -0c49295067befc044ea46341927123ad4b7d094784bda7fa7b568853d0b6
139.711 -1e4cc39e1abcc9479f91a2501009ae34ef7d5ff56205cf5288503591cc55
139.712 -c48abcc78daa4804549562afc713a4c11152e6e4331619b2e474a25ffb62
139.713 -7c46112fa4259f07871f8d6882e9a7ec62d20a86a0c502815d0a8f3f5ce7
139.714 -cb4a6a74b6db8e17d54bc919b82c7c729cc05b98855b9d8a0fabd8a9bdfd
139.715 -4333f395607631f57c0473be0fb290c4f40a7aa6ac49208570ffa1d0f849
139.716 -d4871ebcf9ef6f5106301cf54ff8cc9918d6de74d519fccba58bb1c21543
139.717 -f3bca9f43c211b2e5c233ff6dff2c9b56d3f656f6070d13dfd0be04653e4
139.718 -98c670770e01c07b731ca0e2eb56e608828fedaf1a31087f2d43cb4c0074
139.719 -e576769b0830577c86ad5de48ee216df02d7c4e4ec231afd8e76c608fc9d
139.720 -06cc86f38cf4d839e0a0829902f56cf2f86f08b975a6bdd0642d6b4c78e2
139.721 -57cf9a4f52646a952f6a220c36c91db7f44c7f44bddf33328ea8cc01827b
139.722 -5f2d79e3ee6c514a4f8597a847ef5f32c6400736e6ade28faa7bc6e9c6ba
139.723 -e4bbff236fa6dd2b0ed23fc77f92649feba149f82488260b0bea2a4fe1f4
139.724 -65d96d8c51719e5e10d4c17d1b67e700aac36b1ed55c93b4b2604e72f51e
139.725 -b30fbf5b64c6fcaaef764639ebd789f82ed354712c7f9fcd1df257e14c0e
139.726 -8fd59a0eddab684bb1b4176d79b22ad2605bf534e4b8fac2272fbdeaf210
139.727 -0424a2c5cc65f8dd5faa13313dd926128ed466046ee94bd3eb41f3ea5505
139.728 -5a70603a2ae1981bfae8e77d850fc5a5bf1bacb3df9b7cbce68ce7979fad
139.729 -a73c2900526b68236c6d37197b0c521c5b1cf5cbbc89238586eceb99818e
139.730 -aa47ca94ff615233575fe83d0d50d734351e0363030a12300f7b20450946
139.731 -17bb209c346ac1d35402b617d6260fce04ce8b3231ab5c05af30b0f3ccb3
139.732 -3616d3df334c8d963279537563222dfbb705c3e14616ad01927f952e6364
139.733 -4c4b7fa44ac97616c1521facd066aa33b2296dc03682eb6a3b9dd8e5bf62
139.734 -53f10667ecb07bbd50553f1b211067f5cf098b64b84d94ba9ad8b146dc9e
139.735 -8e9be06bc14cfe0945e22fd819856d6996e857c0bb5f292defeb493589f4
139.736 -515700753885d61eee1b8c19e6e94fe2302c07933f949d6bf119d207fb04
139.737 -dae7bcff7578bf33d77e29611c7cf03b2df12c242827ec4c4e5b5343ca3e
139.738 -4f7f38ed337583e30dedd78a082f41d60cbad55d59dbba11af1bd296ed6f
139.739 -e31d2e10d3a8b5ea698e656ff97755a47ddd862d23309e2e6ed3e3e111c0
139.740 -2c3a713d782fe301dbaff0a4225f932576622d1cbae40d20f46958298d01
139.741 -783851c894f2712bfc4736d3802e548a704878e2d139348671fb96d0ddbb
139.742 -f56d9349172caef0dfed4b84d867116d91063dcdf9ec401dfe8abb269ee6
139.743 -0d646bd12e0752313e2ddc272d9f4aeb9d940987596ab623f9198765cec4
139.744 -62f7b6c540c9a70c9a872bd28ea62e056560b61ec51fc68eafe008f20760
139.745 -246e06374ae5a6bd2577217700507978811ec29985ab644e474e41e8a105
139.746 -295fa67ae05e0739e8c7fbc51104522934942f53e1e1df1ec2a66f0a74b5
139.747 -9885cf2c2fad1cab3e2b609f126ac8b7350d5408a7df9ed5c27a10ef6505
139.748 -6f0d877cd7bb902977ba93e6e8520d2d018560ec8143876ad0dcb95b173d
139.749 -af72c0d413bbb5541f14faa57eedb3ac2430e36911d2f486d9ebf9cb6745
139.750 -2ccc763e1e46e7a4b8373e06082176a6c66d045e18f90b4b2ad15802f6ef
139.751 -cf2130cdc627601ecc19887784b6de7fb6a193bc3d057ace29f74199acae
139.752 -69526ba6f7a2c669593f9d0849f12e37201c32c88384e4548a6718cbb2ab
139.753 -714ccc917d93b865ac7d7d4dbd13979843f4f5c1f8b937ef12fcdc9aff50
139.754 -f09d2625f4367ee70a98772a273d8919952102aa03297e3cbcd876da5abd
139.755 -2ceb162b8fe1d9a22ff694495528c09a8819fbfb6946ab205d4b2424f6d5
139.756 -6fa1c704065cb64fb2aa0fdf291fd5e7daa38667e6d8e889be7f4c453da0
139.757 -59c492cd25fcf4a03a6995897145273a66cd6ba999138bc8e2aa7d080f9d
139.758 -231497ed28a9a27b6b0d4785bfaee46fee71b26d6839f2549a14e7ab7347
139.759 -0b6cf368d2d49e74c78d93477828e4582589cb447d795181d3f13dd8ad52
139.760 -3c750df8f19b3260c17a6598b406472a7204dd26c5988911ce9884de9a1d
139.761 -ce33d834becb1dc80efb07f32d3ed6c2a484c5d53746071576c3f67f25ff
139.762 -1558986fe2dc2265b4fff79c07e3f4c6c0ce8319e04c14728ed722cf214f
139.763 -65066148bc817753dfdcc0950bf80dc515002e1a92e7d8936e9b3aa9635a
139.764 -a6d512c68aebc79a62a6bd17a411bba7684e1f06be9bc3d1aca25d50c8bd
139.765 -1d75597194cf87c9ffe04ff28bea91b5b9521fd356ed9e036466137586ee
139.766 -f0a8795486438d0d9707cb2854f12963929edac394c562235ca71376d938
139.767 -e4e1518668180b857d75318bc22e9f0683749047e7649f9e20b35204b6ee
139.768 -60c0d47bebf53179a083f0b4cad5b3327a3faf2cf03753e3e46c05773629
139.769 -7e9bb305f603369cbb568350b2b5c6d23a35c551e0ab28b082e321ef4ed0
139.770 -e2704d35c75b4750af782160c2f2e9aab0e14e541e95b64ebedd66db2c12
139.771 -a8935a60177cab634e20a8871a3a72f4b21c3a34d9dac37176a321c2ce3e
139.772 -e828d140c8445117e7fe4738000c30ffae8e2a48bd618cc8813e38fa0f86
139.773 -92ca634d1e56010987483aa0f08980d91528df3d370ac724acb238e141ab
139.774 -595dcb3da7a769de170edd5763078d1084e2ebefadf8a50a816b50722617
139.775 -c9539dbd68d9062b015639708dd900aecf4f15adb36339c05a9aec7403ed
139.776 -771f9f28c60e52bda3ba6902e06334036c1dfd66d35ed00e3fc0bebf55da
139.777 -416093b5cf512217c47f905ccc91fad879d63dd1380519a02025ddf15d70
139.778 -eaa1bd8cb6be67608fbc5c94796bd09ba35933f64c5e72a26db1ae40ef49
139.779 -af5e972fa44660588292b67ac670bf046cb1f5a7a0d73ffd6df862744786
139.780 -4a56393b0f1b4cfcfa362c74634713093161b29c94a2526b7138aa92fdde
139.781 -b37a8c1f30a6b3837d9500b340515f0412e681f5bf36e7869fa157df18e5
139.782 -c79df3e6aca924d7b7dd2e0d5b87682d7ea6913b26397ac180fb75fabc1b
139.783 -8e156ed542b9d8c83079bccd141c187f90d72694de4f6d08520d11cd454b
139.784 -bd3c2e6d259694fda0c8decc724bdd650163b7f6ce1181590c06de4c0dd8
139.785 -536aba318cabf54782c919e07c2ffa1034143175d05deddfcd7dce6c86a9
139.786 -ec9bf6a4437da474aac2dbce2c91aedc20043f179d5c9120f3dfb1cf6906
139.787 -c27f2ec68cd75035c283e1672ea90d953a23a1515c420b81c3270fa06573
139.788 -4d003eca1bb71a2dacdab67e44f47c266c2ea1776648b62bc110671e6eca
139.789 -4546d3c72c8acd956e10452c32532ed51bf3d0518467fa829efd9c896e8e
139.790 -1e5c7ff6da0b51e872e403470affc95f25e1d2b9b59ddb0472705e14fdc8
139.791 -fc2af16527188508be10d098372cd7eb7d62a85c8d8dd1d0f55ae3ccd0a6
139.792 -5dd6bf776dc187bf4de409d5db3fcc5a6d852848a251f4fb4e01dac5e9b9
139.793 -587fa8c46ce03689709008b34dfb3dc105def80a1b515abcbe06e73fdf7e
139.794 -7136e40cc922fe9a9da1726747e84427f288d934747b6c587490734906b8
139.795 -a91144ac82a57957cffab561714e1ff5148a39499dfc8cc96bf5d87ced17
139.796 -825e8f80cd943d9a73945fb8bc51cf1f9cb39c605491c1bb8f1c4139974a
139.797 -59471ead310d041b1ca1ecd5e9f92007cd8243cb3fb1ec5256444699a9fc
139.798 -ed6cb31eaf0912c16fa480a1cb4a8f4a9cb6a4d9a9903d1e2f674286032b
139.799 -489b8a23ac4719fe435a9fa2d79abdbaba740e69d5ed611421b1aefcd06a
139.800 -362ddbb7b79aac41e3e90657afc0b87a6e8c57ceef70a628efe19f568634
139.801 -50f47b5c6d95870039caa3d07a54e58df064bb5f59dbe9b9a2c7c84d7e0f
139.802 -32386309560a0efa2cbfa27f861b208b2df4a062ffe2c59c057296aaf5c2
139.803 -0f48ffc9ff0692f8cfbd6fc6ed1f3a14537ba40d7267e6b5f69c997a949b
139.804 -26577a9a99db3f53167355c4967dabd522292ddaca3c537bcf303ce76add
139.805 -eb99f6664227a94d6a698dd5a5d40008349376067d057e28e55972264502
139.806 -e035b1f5e33d7b3aeae016f9be50f2aa09aa138d15d7af3c1ccb805f2d5b
139.807 -cd4e9b2b5c288b2af4a25abf0a9093749377c9e8232ba1af17962f85064a
139.808 -23b0a13f11acbb471cc700f9f1b588f72cb63d3d1a95a93502ef74ed212a
139.809 -c452f1a84619bbdf61a1dc79c0d9ba29c7f19b400f682cf66f7705849314
139.810 -f5c8bbf973f2c53bdb060932156bf2c9cd8d36cf6271075500b0e3e6ad49
139.811 -958af46a9dc950f4c29f1ab5dc0a85924f7ffef259f778459c80118b1eb1
139.812 -ed29208d1145b21b19d62f755de4972c57a09b3decb0a8096ab025fe6b9d
139.813 -be49ae35394f0ea40d3693980f97f712b27f0e28d8a549acbf1da63518d0
139.814 -374941effacf63ac3de0523cfac0dcaeb690de5836741fe58917c7ecffc1
139.815 -95e7b560a3e763aa70fc883751bd60ea0a0f893d8e9fe75a66c67e202c24
139.816 -84f66708ae74413c0101fe0b5003be20881345d917203b582a247e6c74a8
139.817 -1d0479f317aba7b9dbbc0a92e91c51fbe8775a44c57699acc9da84ad60fb
139.818 -9629929d1edabbd70b4ef9887ce4ec2469f154fada42de54240cf3302364
139.819 -7c492ba17e6936a4d85e0751df0945463368a803fb40d8ded22abe118250
139.820 -86cfff1878abe5b100bc08b991cda6fdfd579332360f0c3374842edce6ed
139.821 -e43649d6702f34668a29bf387e647f96d78f33395e8d4b3521cb4fb0956d
139.822 -12c924c16eee798cde68e319a358cc3524c753177d976d4e14a2e0cb72a4
139.823 -80cd87bfb842060b1266568af298bbec58a717c577be73ad808e004348f1
139.824 -6aead32a3d57457376ab57197534d6e469ed24474a83618f3ce21df515a1
139.825 -22918f4b62c642de0c8a62315ebe02bcfc529c5b8f7c127085c2d819e29a
139.826 -f44be20fa077ee01a8d427bbe3d97a9d2bafd77f17835279bf135900aee5
139.827 -9bc49582b18d468bf93e47ce0bdd627775264ebe9e4172839a444f928580
139.828 -8c95895b7e23592b2dcd41ee82e966c26aa2143e3057161511796e980998
139.829 -1f2e4ef5868b3bf4576e3546e6407e35cdf14654bcefa7557d09407545a2
139.830 -38173080b4771ea52054736677a8d9749a2b22b46b24fbff93c55aa2274b
139.831 -8c7ddbd751bcaf1df00ccbe1f24a80622aff192fd6db2238db941ec44ae0
139.832 -dd73f6b2f80d89bd0aa30c038583deba14913d38a7b61b54522755e251b2
139.833 -aeca62033a39ec1143b2b960f9cb87f748428bec3243b8164f07d5ff72eb
139.834 -f2ef69347bb933241c2401a96ba5ffa3f9ad060c41f4e6bf7280af65293a
139.835 -bbae49d723dbc4be61d7e13f7a5931a697e7f2c6582dff416341ccf5a24e
139.836 -9a53686a1e13bbe0bb480c19a4e72a5e477bd29f39dce1a17f63f1e8c696
139.837 -d5f8855cefdbf7ce681c7d6ac46798ca9bbdc01f9ad78ce26011ee4b0a55
139.838 -786bb41995e509058610650d4858836fcedfe72b42e1d8ba4d607e7ddbbe
139.839 -3b0222919c85de3cd428fed182f37f0d38e254378c56358e258f8e336126
139.840 -9b1f1acd7f387686e8022326a6bbc1511ed3684e2d2fc9b4e53e83e127e7
139.841 -84da13550e593bbad1c87493f27b60240852e7fa24392fbf3f478f411047
139.842 -3f00a8fdb6dcb8aae629dc7f055d85341d119f7f6951ae612ffa7df82111
139.843 -d1ca48306a57a922cf4c3106f0b5e87efba6815f6de4294c7a0394087067
139.844 -677889d22a3fd86b0796200300d2716445078027fe0c0b05c86ac80d2095
139.845 -ae874324ee6ea3553bcb92fc1522a6d1524f6fa22b71598fbce784a10b5b
139.846 -61e50307ef4409ffb7b38f27800f2185140ed08fc4ab396050b068025a9d
139.847 -e4bddcad201e72ed9b41c4ffd4cee743c9c2345b95c5071442defc8ba5fa
139.848 -9c63c56e209df41d10d93135a8080f7cccacf67e0b0ddb3e0a31df32b83f
139.849 -290b3c536e9949973cdc80aa5c8a4feee20290a95f68e59f54050192de42
139.850 -f27464ee374e4d2451ee8708933b970402c90ca3070843a449d7c3146347
139.851 -1efa666a60fd5cbf55a47e4a3c5c318fc1af944d58d32690a2c7eeef09b2
139.852 -d94721896e1e3e76e44a8efd524ed5d6f5eb9da093d277441546c6828745
139.853 -ad71b6c13f653dd631bc6fc55d0eb4648b7bd9c0eddb13222542f2b6e8d8
139.854 -b80bfab4365f4199a41ac690979285d917de79359a183e6fc254b63e6408
139.855 -6d33e3c029f472f40742a99f92999f302f79994ffd615f1a848194cb56c7
139.856 -12146850f5e400303bf5bcd4e5fdccd1fe2edf5352d525cb15d8327f45a2
139.857 -6e3ac276dc8780c65724d28dc6bf9c7c985840070c35e32859168890d599
139.858 -a884dc2a90194cc2e9cc6a20c6c0ee11b20adf3aff01db48eb8dba7b0c81
139.859 -7fc10cf5a66e8171a2823a4cd22f0e80c82011ae56dd895ae2d3ebe84ff3
139.860 -d521c31453e0909cb9b1cf0b030eb6b7059ec38038cae12d0e1cc4b5b3bf
139.861 -e6c821faac9b8792441e2612aa1ee9318b71f9966d7d3a64abe349be68b1
139.862 -744de7b212f6be73a0e1eb2fa30850acc3d9562f989cb2d4fbfbcd5d3ef7
139.863 -ba55717da1cabf197b06ee4d8650e968518b6103fbe68fcd5aab70bdd21d
139.864 -66f09f96208db67c1b345672486657295a39a7fd689b2c9216c6b46a29dd
139.865 -1283bdba295dfa839a45b86c14f553ff903a6f7a962f035ce90c241f7cde
139.866 -13bab01d8b94d89abdf5288288a5b32879f0532148c188d42233613b7a1a
139.867 -7f68e98e63b44af842b924167da2ab0cab8c470a1696a92a19e190a8e84b
139.868 -1d307b824506e72e68377107166c9c6b6dc0eed258e71e2c6c7d3e63d921
139.869 -39690865d3f347c95070cd9691a025825421be84bd571802c85e2c83ba53
139.870 -841223435a9ced5dead103b470a4c6ae9efcc8b53331c61d0e1e6d3246cd
139.871 -aa1b0da347685121196a07e97d21b10ad34e7031d95c1bafa37b4141bf33
139.872 -a6be401129dcd64086885f4b5f1b25bce75a4cc8be60af35479509e64044
139.873 -d49c8a0c286e4158a5f346ef5fe93a6d4b0a9372233c7434a7a6f9e7ea21
139.874 -30c0b4b9f62e3a74cc5d2916ebdaa51a1ef81fceb6cf221e70002a8a3106
139.875 -bfbccc2d1809dde18e9607fcaac008fabb72e8c50244507f4013c5a268a3
139.876 -6135ead9cc25362c37aa9511589f18d812e6039490f9c599f44e88754ac1
139.877 -4f6c1841d570efde27958c7f1b2c68772584e1d12fea252e3a6ec3b051a7
139.878 -6faebbf6f5101978e24a9ca927c02065e8e49150a55c64dd30757e8a33d5
139.879 -2a788437a9181efb47414dbc22fdeda203d4122137bd045611f68314e12d
139.880 -1d6a5ec270c8919562c03e3af7b0e0deceeddbdaf3eab8fb5632e44dc1e8
139.881 -d46e2396b0236a46659164e33709415e7b347f7f7b87a9224a189ddf5178
139.882 -2cf66c9d385470a51efc88696176f6d3ac3b7b95fa074c981194e22981f5
139.883 -1d925f980393b7102f1f836b12855149ef1a20d2949371ddba037b53a389
139.884 -7617c257bbdfcd74bc51c2b40f8addfe1b5f8bc45aa4d953c0d1d5f4091c
139.885 -6af796af6513c820499969593bfd22f8c6dcde1d2ee2c0ceebb5bd6a1ce4
139.886 -5fa61094e932b380cee381f4485e39b4b1797f2a7d8d90bcbf89b9cb1006
139.887 -2d50fff083743bf318157caac1c0179c87c03a2857fc002979e7cc97feda
139.888 -966b09ceb761d3f55cf07637256c6aa8b8e5cb6aa9739452a330afbe7082
139.889 -975ee39fad5e8106e8ee05771157e92d99003533d922ccc37add065b6236
139.890 -7613d039741f99edc77c230fe8d1baba720a185186662376b947bbe1a686
139.891 -4b42c61ebe1abd40d890751ab8945c629de3b6d2a49809dc693f9e397097
139.892 -cf1e568c258081242460af2de0ca44b7ba2734573967b3bdec0e5e64598c
139.893 -cbf41e630d821491504f414d9b54a3100dd5105a141cf61bd3ec41b67368
139.894 -c8cd366c543754ee800ffee3d19c9cd0d408cc772da10e4d8134964b0a61
139.895 -232e2dfbeacd0fdee12792504bb327a2e1fc44127f8577ca51d380a760b3
139.896 -740e6be46455cbf3917b90f0dfeadaa25d5d9f66cda43ebf9f75e0191a06
139.897 -25ba29666bbe8678822a453d4e876bad4a6b0d4b6cf98feb60339c9eba2a
139.898 -dce4ef7faba428422c503d0210dcf8d884ca9f5094aab9f3b1a2238b569f
139.899 -444748902907cb0d9d7ca33fccdd0cd29bc68e44f7bca5092be6272bc949
139.900 -baae5af92c302bb21f91b6ea8463265680f7c16f45d8ff35392a10eab87e
139.901 -296f3af4478032b5b021db8510deb617941130d45c46fb3647d94b162fe2
139.902 -2738766fb6d76a06ab6803818b27c5ff4205ba668f95b5ec5ce4ce6da545
139.903 -c13ff56f417a4e0b3b8554a1e2a985a167e168adc8c4db28a601a80ab451
139.904 -91bf32acfd8d25c39c2f17fb3bca1296d3d160f25b43b4d6b94f20ffe012
139.905 -b779339b12860dfc897b366e3d400e756f4f9f4d2c86fb9d94c11ebd1450
139.906 -eaf720056e2c39529331bdcb104d113b42c94af2c6a5035750b7ae7fdcba
139.907 -b6116d74bc07a11d4357ecf73d99221dad5cba4a7136425c2a3ac0e092fd
139.908 -606a4ab722195e3b7fdfb5a5e3ccbb85fc701c42bec43b54e964dff3fa04
139.909 -193043eead7681cedae9cce6919949ea60ef5630c4b9263c8f98b4bc74a1
139.910 -63ccf3d0a0bc1deff39b800ac90bd734dda7ecdc73169ad77e129887db80
139.911 -7a253f8807a422eda8a16c9ee9bb8fc0942634bfe035dac9f7e36d09844e
139.912 -39477c043399db4d07b3617da9d6eee76d0fde9201da98b906050748b68d
139.913 -8c944ace3c96e90a3c2b63eae27b9152cb7274fa336866d71b65a57f1bc2
139.914 -bb1f482a67f3993dcb3ff24abb0223f9a026c81b2b33127a1dad8929dec7
139.915 -5d46bdd790eb1addd771c5c3965a2f514d3a128117a44560cc10a729bade
139.916 -4e6c86de7c09a39602235c803902e34f5c176b18e127d71a011dd9a3a61e
139.917 -ebfaa4a4e2a5651be6f4067e5e09bb4f3514d67c2129e4d3ea9568661138
139.918 -1e45af07bd84f883c70577a986416747f3bd8d1bf86d3d7b07e8a350899d
139.919 -3c2dae237bd5ece45faba7a0ba30fcda7b7eec9fbeaa5a94620686d1e403
139.920 -1cd2512e8d89451c7bd8eb432c8862023d66f3f9fcec0d47598e2df59525
139.921 -d673a5ff493d458748cd6341f161a0a3e8996ca5b496508578fe4f653924
139.922 -2ae28bf4b7397c02b726fd5f9d8b898938bb668a546be6e42865f4f030d9
139.923 -5faa289eb24f7b8e249b224a95a2245605d67417a489626df7417855b8d3
139.924 -1c0043cadd2b461d32e1b39ccf409757c37b68f84e752bde6b5bbb847bf1
139.925 -57ea3434802def983d6ce5ceb3e9fbc4911b5484e99bb94dc3f383e50672
139.926 -0e85a91ed378e352838cf02921ee0ea94be01b5a60f9b1f58fcc1b4f527e
139.927 -43725de9b9dadc3ef462fa279bd7138095d4cff2a0563039f71e383430dc
139.928 -f628dc9611b2e3db08fb2da1d5383dc1a3c784e1e64541fde1d9d7f42505
139.929 -de96d3d0a401099fc2879af0293b0eeb143b78cc221f670c0479bc150047
139.930 -0cacb9a282e334e428b527acdfbfc56e6aec8d4d60745c1dc000011b6248
139.931 -d9ab4a17dca7cc74e17d33c0641710b02cb1edb0addc6be214b17e9f845b
139.932 -2d9c8bf03c19e131e00f91f2a393b5f2ae7c3d4ae9021c4d7891d84d5067
139.933 -377ce92836e42eacd7e540824f7ac95360ce116d41d17a50748748971c82
139.934 -27f089a22ee0d21940de854f737547b73c7517addd9bdaab425a6c2908f6
139.935 -87dd990d6cba4d84308bdd4c4435a6480ecfa1a14daabd4d8e2398178e48
139.936 -de28b84f7ce4b61d2e6e64fe043c29a941f6de7621ee6f6d8b506221df05
139.937 -db238b8fe4323cb5f259d4d3d9c94d4ae1ca37d6c34345489c0284171346
139.938 -e9830e2e3c6c167238a7ffe0989d3eac870cd44102cae139469b9d909b5a
139.939 -9c34792f693ac94ecd35d2277080e30a2d24b50391b6f2a3d3b6c81f7ed1
139.940 -a7b218903e7fed7a63269e27d793a2e0b40320ebf447c71f36d40dee002d
139.941 -7257f43c8add31edf2c571123e46fdb413e007cc89e99b6f98d77ab38bff
139.942 -cf140f787e45ffb2c7cc4ddbb59a4e32dfc36e2875f204ac851d757c1236
139.943 -12deb31324ea4c201d27fdab46e9f3988ad2bcfb8e9cfa8c487831a9b0c6
139.944 -60b20fb66b4c77f52359ac96f3b3d189aa0571c1c53db06ddb10f08882db
139.945 -0b1e93e9478d4c75626c5fbdbc6044c4d82684b310ab2af144d12bf36f1a
139.946 -c0bf6249d1da9ab319453594cb19d0e93c4e047fb49229c0cce76d0cece4
139.947 -2e76fabd2425382afe707db032cf617b046a59a2fc1bb3838d98fd5c8053
139.948 -ecb918bc14762e4ca45027623988f434ff4cb08bc9bff5d7de21940e3e03
139.949 -1ee042d9c30662aa76f96213fb5a92047af60f320e4660eadd1ec19d0086
139.950 -072f2202af5f219725f81882f10d1e065a8035a9946d0ca0e48a5e7dcf61
139.951 -0283b834eda01e7d94b3453830daade2aa6c947989b290c02ade0d7b2620
139.952 -813ad177ed82813b6a985d5c0a2d42419bda763d409da085936e33c817ae
139.953 -68e5467eddc30be172de855a0f7f5c527555b3f4d942401b450f08273b1e
139.954 -c5b5352fdb8562a71f276284cf7c27537e628f94bcbffe8d669ea2645752
139.955 -60830f1e65e83a2204cec393f6d92d4f61f317471b4b93039d298ca2cc94
139.956 -eeada0140823a2bcd1573e732e7b4bde7368f2ecca5961ad547f554ae989
139.957 -98d87b7e5d07a85c382bcea1693a697224f41eb8b406bc6a0c3eddfe8b5c
139.958 -f25b11c3e4bd91ea7d6274cd6b3ee7b8f18cc3fd502a324c645568dce9e0
139.959 -d43caa61f7306fd5488fcfc439d85f8160ebf0ac90fc541f9c74d35d7833
139.960 -09309807a639477bb038200738342e50136dc64baa7cc1b879c61f7e1b90
139.961 -e1f2bd4f6e54c4dc97b8e4adeb102979203a31fe26a7f58c609915a95abc
139.962 -4acc263179423f8ab16b04272d5592fc536f29a45cbcdbe15890f119ca9f
139.963 -c7a52eef41dfa5c4fed087eef8e698ba738e300bd58f2a1a10da1198c1f9
139.964 -b60e2032f8384a86aa84027df21cb87977528e3bb9bea1e3a6879c56402e
139.965 -a29063afc6ac0194f4944433f9a5872cf0a2a741382d7f3c0ca7817d5d7c
139.966 -4b8bf53af0f18b1eb54480519cebb61d983157e039b13025e7980eb36f54
139.967 -3451bbb84e470ffd0f98eba80c74f238729dd6278294388a2e06de68a719
139.968 -47b6d478c85f124d14aaa835620e49b7f5a4f21347302c0f0864f7ebaeec
139.969 -d0831c36187cbe9c848736764a31056d2cef27c07cca00033dcddca9a2f3
139.970 -b9ebf28e67257b69cd38bc23c711b6a2f6e4dda9bf5a19da275e6a8d683c
139.971 -723bfbb95a90a344a6f421f0b67ae84c74652288b0597e4c86c28f73808a
139.972 -77455f2948e8df634c2d14f221626b019033f9230c9167982cca9ae6dc37
139.973 -aecbcb49fd9fc1dbf2d11bba7187888721bc42a7f47c23e07d2fc5a7a91c
139.974 -0dfe255a7f9d17e69af1618502a6b90b1dd748c7eaca1e1ebe8b861b04ff
139.975 -e5f628f47eb4e7e65311037d7a5713d7cc3552dc85f452ba74c4f12aecd0
139.976 -d72892c940c3325640d62fe3bbbc71361dce6d54766e1fb99dedcb2d19d2
139.977 -fa6fa21f9116e03952ebbef659816a62db51a9b5b3916ff818518774ccd6
139.978 -79d44100d7236f211f36fa80a4cbafb3db76ba1e7e7f12082b0140eed2cb
139.979 -5e793e24501715c6c170ad4f856a4bf16bb10210025156e635264d3cf18b
139.980 -1fc1e8cd2fcfdc2ab1a24af9087975bfcf6fb703fb36e288e58d0d2ffc98
139.981 -bb4318001d931ad6161dcdf8984e6690e0f6bb07af81bf07445f8f57b355
139.982 -6b960d24e7cd152708489e4d953ab6a155a757e002ead97585e6c5333d7e
139.983 -5aaab2731f047f3490432e0ebf3d0d628eefa8c1f665b9c86aabb0706639
139.984 -5bc372e16378f0d9b439c98e7bf87be73e934995d58e4e70d3ae9a5b54c8
139.985 -87a19f2826a772c39d41805c642354d9bec75b065f148f7c1e435dabbeaf
139.986 -e4a5744e3f2894a928121ab069bffa3218a106a9dbb83971353a7c7a5616
139.987 -d9da66fbb908173f9b07aadcbd4d112cc353e7b70476046ce5a92e86eaff
139.988 -4eec40acc840005f51f55c9f5874216851e9cf3fa431d95d3032e779e356
139.989 -4bdce33966a3a798b170a06c4cc9f73700224c858c36bbf2d0326c337ce9
139.990 -46f69c19a84187fa50afc5b36010f9a7612e3a25e846d49bb907af9505e7
139.991 -d8c78748d7dcb501bbb3d6603e829deee3784f2f3ca583d3738d6d2ecfb8
139.992 -eaa887103606211a3c1b5cd74a3e0e96fb57da91baebaecd3669661e7b1d
139.993 -579ba41928a40a7028acff6cd409e601d23ff66ff2c8acb12e535360d727
139.994 -60d2e988d801930e0e9443d60dcb9f378fa75d58d73e6a3b6e5b26407c82
139.995 -67d50ad97787f8a9b91765e41552283cb67e43e59bf71cf08b9755c8ce47
139.996 -0cf374832c72d1e9702b55bcfc8b5a4e966d5072fb2a72a2108574c58601
139.997 -03082ac8c4bba3e7eeb34d6b13181365a0fbd4e0aa25ffded22008d76f67
139.998 -d44c3e29741961dbe7cbaae1622a9d2c8bca23056d2a609581d5b5e3d697
139.999 -08d7e369b48b08fa69660e0ce3157c24f8d6e59bf2f564ce495d0fca4741
139.1000 -c3a58ec9f924986399480ee547ad1853288e994940bd1d0a2d2519797bf2
139.1001 -8f345e1bb9cbf6997dae764e69c64534e7f9dd98f86b5710ff8b500e1c4d
139.1002 -f509da50c64e213ebdf91978553a5d90908eb554f09b8fc2748c9c405903
139.1003 -e7bfbf0ea7e84254fb6735f09bf865244238e5fed85336c995bc3a3b9948
139.1004 -947a6eb95db4cd1b64c0fccf82d247a2202e9e7eef5a550557625a0192bc
139.1005 -8bcc9e461e52833f6b8729ccd957d5c4b6e07016e864fc02b792c7400ace
139.1006 -d0a8f43c755f87bba6e5c6e1022416e5454cb34a19865d951f7aea527760
139.1007 -53658cbf306ead832244f3062c39a0a121a1157a8e47008163c5bfc88197
139.1008 -be16e9a1ba26a035a16dd38cc28dffb666dd4ba7356c66b7bced9e26e905
139.1009 -4ce25f6d36607d8f5dda1e21ac96a815bb2989f01130ba1aca9aade554fe
139.1010 -effdfef5d6b0d2a01aad92f599f6a12e121010ae6acc6f150f19e7305271
139.1011 -97da761b07530ca19b84b119e5edca1fad18462143b8913d6b3f6864b713
139.1012 -7a93bb9e1bc29c09d660704e8d8292c61072ebfe35c354a2342b2458a353
139.1013 -31d043874380d439388e46688a53bcfe01bc190ef1a6b5dec9d40aafe822
139.1014 -261b28bf3e2d76f3dc4302506ce3387b4aa2a51cd4ba1faa2ed1fd7df664
139.1015 -6772fe9f83d253451eeb0448b444b8ca80cc7cb653c2d1eaa0de6f2b1c72
139.1016 -47e6d24ae72e620e200aff83a557a1aa7a0ce0a9cfbbeae03c31d8cbf1d8
139.1017 -20b53b688ed2ffbd83418d743ee31e3d62216ac7be6c12bc1917548cf670
139.1018 -d69fd2e78d9f7786ada0ea30a6f6d9fbd1f1406337151ffa1d3d40afbe03
139.1019 -728fd1aa2fa8a4f075796b9de9586b71218b4356fb52daa01d3c18cb75ae
139.1020 -d4d33fc809dcb6e3dcf7aee408a0cef21353d76ed480bf522fdfe86e0e0a
139.1021 -b7d097defcb793057f0ce98ea4989a9b6787b14029a4bf10315a2557149a
139.1022 -fe9c91e7d825f7518b343fb556f0177a8f6ca08fbda9913d52997511590e
139.1023 -b9942c9813b4cf4d4aae4919401f2fc11fef0620eb5c40532cdb22d5fad6
139.1024 -919a3a710de6c40d54993b5386636499c866938e33bc703a99c73adc228d
139.1025 -95cac73ff4f4a275c04d0d787b62c6a184dacc4024d23f593e7721be232e
139.1026 -9882fb738160e52ab905f0ce2c76ae6ff2c8bbe118a1acdb3b464178cf01
139.1027 -94bc6a50df1090e9221be11e49f254b06c3236a31569b947ad041d1c6b55
139.1028 -bfdec3c18c791ace0fe2a59504eef64a4eec4b5c8dd38b092745e0d5ad29
139.1029 -276bf02c419c546627672a5764a4904635bff86fd0781d36fbdf13485229
139.1030 -71f355de2b0ad250052f50ad70f61afc870ac7a816561d3232b73360d4ab
139.1031 -2727b2fd045f254c782bb3f1f49d94c6d625047071b7e32da5c6d21a86de
139.1032 -9283fd632074430772bfbd85e0c9ccab1dec16bbc049c3e223bec1b65c8a
139.1033 -9e98cf58b30a74f74f1a842dc91e30c023498e280ac55edd58f4cc731d81
139.1034 -e443d9b9efdf5fea63c9f357320e01b8740eedaeef2495cd02eb2f338b3e
139.1035 -674fb074cc497d7b1937b188da857c2c230e9a931cbc00c85a7a36fa80b4
139.1036 -56588e1bbabbe4ef429a6aef9bd4eb89c5752421bd049aa13f4dcf9b51ce
139.1037 -2503e90bc118fac78a25d187353d6f5d496cd6130b337666f49619cea985
139.1038 -dfbeb7e49c67c1e0f0f8e9ec8ba14624ed0982dcbb69415e4b3c8ddba140
139.1039 -397eb1fc1ddd36c94c374f018873ba41109e45afa51f0e691157d5958c06
139.1040 -26fbc0903ae25e47ee372389cf65472a3e4d9769550bdc42c0b72f9a297c
139.1041 -d5d3c16ec67e06036e740ab664abc9f10b9499269b73ad3678daf4474329
139.1042 -c2c7252c1f0df1e3b5e8f198dfef8325cb1e7e8057897a3d7fb5bb5858e0
139.1043 -cfc0c115bbd7362d8e8ee41862af6eeda681cabbb06f72ebd2ae0b0be45b
139.1044 -a9e1be83f1da30687a655e5d148fcc17d9f53b760810a565f6d2f4cd5da3
139.1045 -5434116edef756adb4d3df544a1de593be988f2bb8d36c34deaac7d9dc15
139.1046 -cba49764f1e03aa09fe21fcd7c74e3d6487ebe219569e019f10dd163046b
139.1047 -c1a3cb2bcbaa8558197cb2c18709a998b4efa8ab8c9a71d2ccf942c17662
139.1048 -1b88dee6b424165d6ce10ac48375e760983818e0085276b1674dd41042e1
139.1049 -a01a8de111c903f74834199b3230bd475d92c6226ef74eb1daaec3475a6a
139.1050 -fcb47644a17c7e390ee3b16bef1c1ca6c55eddc44fbefbdde525921b3047
139.1051 -0d76817bd8ac724739a8e743eb09cf78e88adad527d4f115b8a32ed4898f
139.1052 -45bab3eb802b8168aec061e3ecdb026c056fb9efe7e2df48bd516ccb12ce
139.1053 -00de08ed8be4ee0c41f40f4c8f64483e0ade90a78d6d4fe9203fe0b97c60
139.1054 -3b2f8882bc15a212453c691c52d00fae8a3a26934ff8acf68d4352eef75a
139.1055 -0b10d938e55b7333dda2db0296a69e9775bf82b1aa6d684fd9080fc1c11f
139.1056 -ab4369c7a95a9504063db900a6e345bf6dd99be041230b2e60cc86b8c345
139.1057 -1d84a9c2cb4ab6d74d63dd43dc26eb6b384f5222796d4083dcc3e1651548
139.1058 -d9469f09a33b213a33ac52a6a2e23802d8f8a75c01a607940daab0051410
139.1059 -73a88130bc192f303616adb113c0051b65e12086cb319c0a5323fa7def40
139.1060 -402f5f87a3b2c2cf0e92789985f6775ac2743e1ffe2d0668291059740d45
139.1061 -43bae7a2897e5e658592bf5a72966097742e0702deecb0cb12499eab701d
139.1062 -34ba37a08346217a415e44297a181bbf3744f0a49230ad6f030e11462be9
139.1063 -afc2ae14e0587bc02311b48b8e2122c28cdf14414f3680fa52dbbb63b17f
139.1064 -6ebe4a1204f3c5d6150cbf89a8023890383153838d4dde77d4c8b1b78823
139.1065 -8918c564d3babfe58eeb154307dd1997f5ab7105426e35c279008b2677e4
139.1066 -695c60f956b348799c04b734338018fc27f7de7ad9d73468fdbc5283bd14
139.1067 -c066ddad9a3562f16baae15d72d7bfcb409e1c874e9db1a8cde233b282b9
139.1068 -6e76e9c08d85ddfbd3cce7e64104d0b0e95291bd91f405ff82f41601ee20
139.1069 -8471e613fbbee67f269e4e954c36d1d18ca9880b7cc2b08fc990978efdc5
139.1070 -1d157deefedaa765c1e26ee125d4a2514a41a3b95e9151a824532d7d6486
139.1071 -35ad622718fe71219a697e94c2e64f26424cbb767acdef5cda70e179cd29
139.1072 -b7e318d1c6d3ad26fd5fdcbf2fc221301cc1f10f5ed86b40a1a6bcc01c90
139.1073 -eafd65183e75609610637b99fea57885efe76437df02a2ffc21223d039b5
139.1074 -74955d9a54ff41980eddaa8768c5ad883a0c9150877392b990d63c6805db
139.1075 -7b8d6ab1358cbedaedb6feadb0ee4fb8f9c1ca03a3e755a74227a8930bb7
139.1076 -2ea0a00b48fc626fa14d7d48624aedc31c556f44e982f3ccbde7ee735f73
139.1077 -629ab1b65bcbcf0a3586a920477e8c960219802fcb1bc3a179032b324f8d
139.1078 -c424899b38275886cb5bc771f26a0880767d49cc23426a40a4b6ff8fe48f
139.1079 -d747565fc537565f6d7fd08706accc60f5fbcb45bc785f45ee9b0812366f
139.1080 -ae71b23ec43f3549c8224d78baf18719f05108d5741e681457ead8abc050
139.1081 -462481771a8dc6cfeb98956e163981a98c59ab44d90e9c3a946c453b5071
139.1082 -db0c769f7fb5144c7ab0c9ef1a6db1addcde1d4ae1daee1b4035af256a04
139.1083 -df53926c7a2dcdb94caaf12f986e20929ba4e396f3aa7c93a7abaef1294f
139.1084 -5f13a0dd3c3aaa8fb38da3e15daa32163b7437af683b4f5e64cb14aebbde
139.1085 -8c69ed2e8cdbfb213fc8129af29ca2c06c8f85a5038d688d1fa5d1b54ebe
139.1086 -4dea81a49ce24131f8e6702e7aa4e2cba078d5dd373f894ccb275f49c690
139.1087 -1dc772e1d2f5fb3fe15dbfffac62c87110162074eb72ae4e5e446bf7e650
139.1088 -a554178d0d64d3c07f330f0d99e99f2239cb1597f2e5f443854cdb0f5fab
139.1089 -b28fe62f22e7f3419d017980f325351bb04f8f3c3dc57fee03cc029bd29b
139.1090 -202308d5a800ed2d500d41ace8e54e2557bf25b627883beb8118d800eb94
139.1091 -f4253f855168f7fc8a2d29c5fcb76bb90a6c4e345722b8991a854047f46e
139.1092 -4e97336be85470b6be2b9ba573dbc4967ddcdbfc3b6fc35b0c7f3f2f570c
139.1093 -55dc3fee6d80bc6f46cc7e4d86a0b86f6fa61d062e213d9e442db63fbf11
139.1094 -d03165b44572096995ed342893bb672f6bb55ff8fed944667995f0f89a48
139.1095 -a904c47420f32afd14129c6e2bedffce1f07ea69d550b6909bb5beb4aa08
139.1096 -b0b44f35e018ba5206fdb4df0228462c1fdbb95a429e53eb27bb1b0490db
139.1097 -f07202c3608d0f4ce08570e3d6aa3d4581c569b57bd8c1ea0e4ed3fc5497
139.1098 -e316ecec06e6be582d9170d426f6d22d8c7287b8219945c124941ca8812b
139.1099 -e97efd9105eb6999edc0665016633b3b48820df736125b7c76c9f3a67d93
139.1100 -8a2a0a6b743fd42aebc46a0249be459f16811ac9eba7b63bad7c2e88f175
139.1101 -0eff8da5faaab5659824f9d19b3225aad2ac17c52c523414d3031d08a926
139.1102 -30abf474fe02a32b44d3b7d9fe0c19aec16ca6d018b71d9d395ffaea0788
139.1103 -0d4501d7cdf0f7077a2d63303d09083080d67f1f714a1b271dab9fc9866e
139.1104 -4b0571a171eec8a4e351ba2d02438cd108a33b1106acaad0ccdb051061ea
139.1105 -7f40543748115f29debfb4be4b42cae8762d62114ec6f8ef68c478a8e05d
139.1106 -ecfa18b0368428efec9eafb2353f95e3d71e1636b9d9f94a77e692843255
139.1107 -698576dce13b2b858d2d15ee47cdba3ed08d64b77ab46dd29bba6aac2106
139.1108 -ab847de378cccdaf35c64e50840248915f4fc110992c493cb1b9cd0b483f
139.1109 -0f1abf5e9b018210b477fea28234ffbe5e0bbe01338e0842a89f1e00a0ca
139.1110 -7cdde0b2d7c324d5e17d8d3415ccad703507497ac95360ce660b656e5f66
139.1111 -72a2f50761f3d02ccdc1d5692d7797699b8e2147cfd4817c81a432ff6a5f
139.1112 -39cc54927fa146cbed56a55f85f123c0a94b7553a8819b329d9dd122c502
139.1113 -94e3f6314d5117db89ae7597c4691b6c542979a1ca3d26a8e23d3eb698c7
139.1114 -1841651e08ec771cfb974d6613f2143872c739b62796bd0a45172530793c
139.1115 -28d93a65b59f79c245248d2c09428657a35b0c0e367bf7a4a4f0425b3f4b
139.1116 -485d9f402e164328a4b963f456829a39035c00283d2e4fcb71a42da6d42a
139.1117 -d46cb751287de34e6519c60bb3f1a6ba91f7bfa21dca96ee712af5681701
139.1118 -18ece8a0535d9ba1dd4bd835e004a2f38c5ba43c9b30d17045e5649fbbac
139.1119 -188922e442182d4bdafaefb39e00106a5a7765f3d67850471e3629e526af
139.1120 -8691f935b57bd38465665204a214fef1006ea37dc0781073ced5fc042781
139.1121 -93650393c3cadfddedcc5550ed483bb6355f54600e9758e647f9c9711f1b
139.1122 -e7df05d0e50a698615307c18f6d4886f50188011ba499d03831185915f3f
139.1123 -77c4b9ce708d78423b110776aaaf90396be0381616d1e9b0c1dcf68b6396
139.1124 -82399da2a7323bf42ae5347599ef4ae9e5c135522c5ecb87e201853eb899
139.1125 -db60d24acad17d6b7c2c7ea4dc221f3cb6d6caacd1ac0822ea3242ad9b4d
139.1126 -d15116c3874e3012fad26074a23b3cc7e25d67ef349811dbc6b87b53377f
139.1127 -0cf972040a037ecb91e3406a9bac68c9cab9be9a6bb28e93e3275b177cd5
139.1128 -0b66935cbe8dd3d6a8365625db936b2cfc87d4d6e7322df3dbe6ccda2421
139.1129 -a5e5372566f626a5e9d8bc66959e443286f8eb4bcfdeb6c49a799f1efa69
139.1130 -63260d0ea2d51260baba9207fb246da927fc4c89e9c4dd5848fd4ef6f81a
139.1131 -cd836f5f06ff0fe135cafd7ab512af55a57727dd05a5fe1f7c3c7bbe8ea7
139.1132 -e6680fcb3bbbee1cf2e2c0bba20185f00e2dc3afd42f22de472cdb3eaa5a
139.1133 -ddf8c6fb3682eea5548c51ddca25ca615221127b4438ea535ab3089c9ed9
139.1134 -b971f35245cf831d9461a5da9d57bc4e5606d26535a7414cef6aee2a7b95
139.1135 -bf2276044818ee0f3b0a16532934b8b745d8137b42ec2b28fae7d55fc02c
139.1136 -9ccfa4e0055f8a4be96e1e235c01b8b6ad509b832a3e90161e0a449934e7
139.1137 -4be973c939b31cbc19dad4c58e9be89d242f0ce200548cdd4fa2081ab3f8
139.1138 -e01f358d5db24b7a50eb2096d833378921f561f132cd7988708ee10cffb6
139.1139 -2256201801c667e176b1dfaecde9756d725bef093457805e16f550e8a7de
139.1140 -87ecd46e5b09646b73ee74f890a36867636911e4cda2c46a40e7d57cf297
139.1141 -9696046614c85b1a47ba55c60544ebd3ad7d750d003bda56dd7eed8c4702
139.1142 -f8b319aaeef9d3cdc59b3e63ee93c6e1e857af273eb90909ecf36ef4c276
139.1143 -895c78aa762e5376c5c542f854fba864ebce56e4b0207091139f053c2c08
139.1144 -3b7ddcd0a9909b52100002bc3f8c47bcb19e7a9cb58b1ac03fee95e81195
139.1145 -072d3aa7c8079632725f63425a3550a947834d29ac9a26d0774e90248e18
139.1146 -996731fd9aa53ab62b40ce557d98e874b763d9d629a173f0c7babfc00ae7
139.1147 -82daef5f00cf3608ebeef403dbbc19e16a1d160b889f4a10359d9eacc19d
139.1148 -7b5f126b31720dce7fc35ec861dfa56ea23fa18423ff4e8fe6e53fc6ba16
139.1149 -b95a2b5dec00f614e4f835281ee0b4bf549e7e882689e0b445dd46fc40c9
139.1150 -090e5575fa2c34b02a51ad0bccf6a7bb83ca3b929285e5e9fd054b72c47b
139.1151 -733a66c5abda526b18b2e49d0746e067e63b948a45eab2f4221c5b62ae21
139.1152 -a5d9d7cd8aa9eeb49588891d22c56b14b55ceb6488f02b73ab3b7f6c5555
139.1153 -b75452594658255e4cd58ac4815f2e1bc3888c6777f62aac2f0a57d416c3
139.1154 -765c991f0f9a33d888aeb2d527b482c042ee23783a04a73ad13dfc590a52
139.1155 -f3116f8296cacc7ab29b7d87e7864561a5d0a12bde2d36ee697064f41d1b
139.1156 -ca6ef2f801caab5295d19bf4c02b10c19f73b44635ba48a0806b967d7dfc
139.1157 -ce9a4850171a78532cb30020c0d66b3b1e7c75eaa7894904c181a022e8bc
139.1158 -9b2b8ef1202f3c7d36bcab4742d4a4761bb55b64da0d99685d319f5da8fa
139.1159 -132be6c0483f50e2657ae8af1e28f969440d6ed43eb00e95fd9e1cd490a4
139.1160 -8646f6d008598751f7a41b43fbec7770fe591012b6b0c4ae18775ccc7db5
139.1161 -de0ded2dd53e82c89648d46f0d0cc5d3ac5aa104239608d512a4353b9547
139.1162 -04fe6eb7e73d718323cf9d748b8ec5da01ec9358267de12cc22b05ef0312
139.1163 -e4b6ac5dbb6d06d7f2d911f20d527f504d62547aef136834b3695df8044c
139.1164 -383b6145e824d3931a602f081d9d656f84987a1ef121772f1f5b37a116bb
139.1165 -d2e77d4ccda01411545d24e15ce595db4cd62ee876b8754df0b85b44e011
139.1166 -b82d76ce45795e6c2c58be8690b734a8880a074f303a70da4a1b086a6de6
139.1167 -56c02cc7a4c25258eff18cb0fd868214bb46f972e26509f868d065b3cb14
139.1168 -1c316898cf22293391bd7051ac3a6927aada952a8fd0658ce63357c07f34
139.1169 -acbf8c99a5537da0023e901f0eb5547e1b466b7d982c8c539798b76ee2a2
139.1170 -252437a81a37c3b63f625172d682eeed0b795860b2755f020ef52a138353
139.1171 -003c61be2052cdd7d73b2cdcd26b127660a7b22fc51a6a2f6034f37e3e46
139.1172 -c1d7f83f8b28c7c965993abba1d358362833580d9c63fa85d4cb949f97de
139.1173 -579fb6807b95a58b78f596db50055947dd0d0e597d9687083e9bc0266e86
139.1174 -90b884b27f4094d8fb82ffdbaac4d580340a9ef8aa242be87e54b601af19
139.1175 -87a48d267c04e371ae77163ebd0de3f5297b1060442ecdeac38334844e38
139.1176 -0f294d4be73935fd8a38de7fba6d082c3d9156d7e88f2cfff0459377cbb6
139.1177 -041f37a7e05010753b98e0b67d5827aa312129bb3c3bd883c12323756406
139.1178 -d555720da8a0bb30edcfa760c01ecc2ba3b15fecccf5a10e9f358822e0ff
139.1179 -b64178fce2ea6a1105bfb72df0e4bc499b207ae26b8ea960de48e7ee7010
139.1180 -b4e671dff795e4cdc5b43e81b1604d224f0616ae311f1208859c502c1a10
139.1181 -940e7b9cd11be728bd3a0c8005ae23aea32c1b642812198a6f1aed32cb75
139.1182 -97152b1340dd35ada1b81051e393d38f3740fa9523df6a83b8ca7dbceb33
139.1183 -6e299b54cd998d4dfef804733c76156585e42b7284cbcc4047ba6b290efc
139.1184 -aa60953e98cd2b4bc2893857fa6a339f820142a52ccab0df09a2709df550
139.1185 -f22e5921cbca408e7998cc1cccb8adf6d8f8b71e6685ae59d290fa33f5cd
139.1186 -664d73e434237424060f634262f04e9a71a977556e93b692ddc3aad26d92
139.1187 -97dde71e4def64932151ad572af6e681082e9944ddbec6e7a8bdfd534233
139.1188 -9ca3106ca1ccc80eab14f1655978b137fad8f399df7cbfa2d7d3d9675e0e
139.1189 -9afec37369a8ede2c93145ab3f42a375926946680c215fa16bf7416fc892
139.1190 -bacd806cd424b9f85b47802c4336918f7486af2a03bf0d39b10169d35494
139.1191 -419cb1ab7b8f407897f70c18303e91563b497d70b7181ede6aa0c3efe089
139.1192 -ca6135b34dd1019b298e3677f8da61f864a67023c31eaa716c40cf3d397f
139.1193 -9a1209564c9ec759c37028079661d2a56374203c78b023ec61340bce5d96
139.1194 -e477a4f77e5c0db7c0d1257b4bbbc6f889b17e6eaab045b8adef6f931e4d
139.1195 -0795583d60a6b7002cf61639c6f930671f3b8ac05a1c4e002f4bfc50d8b2
139.1196 -3029fc4dce1b602cc3a5533336271bccc226559ffb127e3a562f92f89824
139.1197 -552b9a70466d5a3c74ae515a222b109d490f26e8fc2d9d72bc8af6d1dcc7
139.1198 -80463c7af81993bac2ce4aece9d95ab736b1dc73e32d1237bc8ec2b52513
139.1199 -36dbabb4ecc7ceb5d18b02043281eb9a3bfdf19bc4853c9b1722ef1cdcf4
139.1200 -fcec534923db2e2653dc48545a9850c0ac2e4594abc9f7d18a0bcf2fadfb
139.1201 -bf085d465a4d10528312f5d790eb9511ca01061c0d94136b99a043bcf278
139.1202 -c18223b1e0f1cc062b32b79e28dec2dc59a0aaa4b5f3506923c83e6a87fa
139.1203 -08a1d941bb644c994491cf7f3b0e2ccf6c8a8ba89376f76dfdb592374f93
139.1204 -528e78e31e0b18719346b9f1486f652638e3120687774030444674cb0778
139.1205 -96385c41f6566819652d825dd58f9a4308ff79b45d7828dcbfebc406e40a
139.1206 -c46e866cb0e3e97d6ce7fcac19a9d0fe39bbde66c5f0cf775eb3b1e6d7e1
139.1207 -1f67e7edb3d5c4facc85c916bf13322b56a0414ca27d145cb740fa2c37cd
139.1208 -8c142d9301f1ac3704cf6a8e93973a07fde5a331cf0cbb370c7ba555de61
139.1209 -18a6cea0ecb2c0e37152390cc57e2e4fb3791ddbc383ee26b6f4006d0d68
139.1210 -4880888011020f856a9de47f45440f127cf27ccaea7d40a3869d39ec7dec
139.1211 -ebc06382d294717644b6118354e15544fd4c6d88df9245c9a83b30e6ce09
139.1212 -e2498dd1df488a019b179cb859889e6ad2838f749e3b038b280ebc8d5c3a
139.1213 -b03e8f15751214691edf0f86281e612d7ec0773c8a5d2b433266402df62f
139.1214 -fcc06879ca196aaf1fc73a5f01ac46b44d6cbe7743ae9a862c20445ae2be
139.1215 -1544f413d010280cc2941900bf3c42ec088cb21b44a915bb810e7666b545
139.1216 -5324465c5943eedcef0c09128a995f431382e2062f5e39f4338c8eba1bca
139.1217 -e553cb60bb8f3e5038ac8073398c49f06dc734b18afa7921ea0d455e6e73
139.1218 -db8ad9f77fb5ba6c28af6b4f18cbe46cf842c82d6c960be1520a5fd929df
139.1219 -ac7e00ede976fb2be0a07f659079a421fca693de89ce9b8fcb42b0176d9d
139.1220 -f3ddd58f921e13e216933d27b49d175b423751c451be7618eaab054d3b8c
139.1221 -23e8dd6fd60182d61e9b5c86b3b764a29a62f913ee7524d8cb33737d7224
139.1222 -d95dc4bb8c2ad6397604a0ffecc8865adcb540e5da1cd769077838515118
139.1223 -ebc9f0b988545c1881dd2e7a8fd73e11bd7ae9085fb4d45526b23a346b0f
139.1224 -e4281ee3d588106db5f7c386c488d8f2f4dd02d4c08e74c1034f987a44e5
139.1225 -d39fd07538de57a42987ce290fb2f6557e8b5cbcaec168f5780927226415
139.1226 -1e11e3667d33b36a793aa53e9e2d1102c9eb30cb3ba0ebac953e0227fe4a
139.1227 -3d3c0eb57e4390c3d35db0c41946e45be2830a1ae33fa25cf2c7c9cb4550
139.1228 -ce9ff6c6e3d628fc7284daa6241604c90dde6339b7f7e7df3733416cdac8
139.1229 -e5291357e4983d74d3582a490438a7fdb0af97001a31990b1de68e6adb48
139.1230 -917daa387e647f9f13312db57310c7dedc2a2ea80800b4f4bbaa99c6b7b2
139.1231 -7ac8345cb659489307e2565ebfd17774642c9ae5d3c18068dc35170c7d58
139.1232 -4cf4173f1baf98137fa249c81f3347e1dadd6b1ba0f50c3b64c1eab183a0
139.1233 -937b0f7278eff101e5267fa6480da7d602844416490c2c2c7eb0d44ac8f4
139.1234 -75cfd611db5ec268db07c0b3608825c3e12834a2b2efaf5e2723c5199c42
139.1235 -6011cf22e64e4c0d31d563f321097935ea0c6fcbf5acd3748d90079f6ab8
139.1236 -687288dc55df29fe7958f566b27b73e2ea30747247f7a2b2add0602c7d64
139.1237 -d23f52e7c96748e6a54ee8c4629b2aab8882169653f0ba7f05236bf14364
139.1238 -244720f3259cbed73a318b29e4a9305deb65a2c9dec8a9d0f9a9f6fae541
139.1239 -83e0f4b9a9a567057a1794945168dc23cec25d1c02ea9242c9fb6d8fc11e
139.1240 -e8874bd80a5226373ae87cea91853d0625c777ceb1f5a6f3debcf2f75a61
139.1241 -460c7b4067f568ecd01f62901ade8bf8fbc5db9c6720420496f0cb48a002
139.1242 -99870773c2e7b12e83987a5d0290d9bbf589ac889bf7d4334a5147187a7f
139.1243 -71008f216ce917ca4cfba5347078f354897fd87ac48af6a6c62711d2eb3a
139.1244 -5882bf3b32c0f1bfda976f850c9dcb97170e78c229a27fd5e292d161ece9
139.1245 -a8c47a223cbdc28e24f79f6429c72b5752a08f917feda941582c36d9acb5
139.1246 -748c86072858d053170fdbf708971a0bd5a8d8034ec769cb72ea88eb5cd7
139.1247 -49f35be6ee5e9b5df6021926cae9dac3f5ec2b33680b12e95fd4ecbf28eb
139.1248 -a0503c10c6f2be6c7c47e9d66a0fae6038441c50e6447892f4aaf0a25ccd
139.1249 -952c2e8b201bb479099f16fc4903993ac18d4667c84c124685ae7648a826
139.1250 -6bc1701cc600964fdcc01258a72104a0e5e9996b34c2691a66fa20f48d7c
139.1251 -2522333dfdabf3785f37dd9b021e8ee29fa10f76f43d5f935996cbf9d98d
139.1252 -92d0a84ce65613f7c4a5052f4c408bf10679fc28a4a9ff848d9e0c4976bb
139.1253 -dfdfb78bb934cd72434db596cb49e199f386a0bda69449ce2e11e3a4f53d
139.1254 -be134c6d7fe452a0927cf6a9a15b2406f8bd354adcde0ce136378baa565f
139.1255 -b9c51a03b1fbe1e166a1f92af26bd9f072250aaa6596a236ba2d5a200c90
139.1256 -a760ca050421abc78223b2e8b2eea958ab23084fa1947574e846e48aeb12
139.1257 -26cebb8b5a92089e9ea771557599e2fff44d75bcf600e76ae7289ba98cf3
139.1258 -98208c5104562834f568ebd62801b988b0a9fdf132b6564566103b3d2d8e
139.1259 -6a099b7fbad8a13b8cd7f6729bb6651fc1019e66c4bd6ff27410bd5cdae7
139.1260 -4010bd68b066bffdb4fd5e3dd9cf7e1a1353f7a4c5157e3ad508f4ca0259
139.1261 -9761b7cdd6a81b3560b8765be3b0432fe4c25dcb4001b00c7fa62874f681
139.1262 -ed22127dc3974605a05be8d8fcf9701f859ffce4dc598091891ab7596ac3
139.1263 -4cd851ecfd2dbbaa2f99dac376f7bb40703fd0700d7499a7c24726bdc9bb
139.1264 -3b88c6a82e52686c1ee945d8825092bc81848a08722ac5a1d24353f95ec8
139.1265 -18f3fa487d9600318091b0ae9874b42bb3cb683a2518b18cc1bd86c6e5e8
139.1266 -3d37c14ef4fe0c77b03a3314995b1e7c1066b98c4375bd1fc5fadee1b024
139.1267 -7ece4f95a0f59978d543910deb2e5761632c74c508269c4e4b9e315bda02
139.1268 -975dc771fc30c8164b9df9172a4e571d8ca578cd2aaeaa0dd083e74cdc2e
139.1269 -d938b984b96d76a64b8c5fd12e63220bbac41e5bcd5ccb6b84bdbf6a02d5
139.1270 -934ac50c654c0853209a6758bcdf560e53566d78987484bb6672ebe93f22
139.1271 -dcba14e3acc132a2d9ae837adde04d8b16
139.1272 -0000000000000000000000000000000000000000000000000000000000000000
139.1273 -0000000000000000000000000000000000000000000000000000000000000000
139.1274 -0000000000000000000000000000000000000000000000000000000000000000
139.1275 -0000000000000000000000000000000000000000000000000000000000000000
139.1276 -0000000000000000000000000000000000000000000000000000000000000000
139.1277 -0000000000000000000000000000000000000000000000000000000000000000
139.1278 -0000000000000000000000000000000000000000000000000000000000000000
139.1279 -0000000000000000000000000000000000000000000000000000000000000000
139.1280 -cleartomark
139.1281 -%%BeginResource: procset Altsys_header 4 0
139.1282 -userdict begin /AltsysDict 245 dict def end
139.1283 -AltsysDict begin
139.1284 -/bdf{bind def}bind def
139.1285 -/xdf{exch def}bdf
139.1286 -/defed{where{pop true}{false}ifelse}bdf
139.1287 -/ndf{1 index where{pop pop pop}{dup xcheck{bind}if def}ifelse}bdf
139.1288 -/d{setdash}bdf
139.1289 -/h{closepath}bdf
139.1290 -/H{}bdf
139.1291 -/J{setlinecap}bdf
139.1292 -/j{setlinejoin}bdf
139.1293 -/M{setmiterlimit}bdf
139.1294 -/n{newpath}bdf
139.1295 -/N{newpath}bdf
139.1296 -/q{gsave}bdf
139.1297 -/Q{grestore}bdf
139.1298 -/w{setlinewidth}bdf
139.1299 -/sepdef{
139.1300 - dup where not
139.1301 - {
139.1302 -AltsysSepDict
139.1303 - }
139.1304 - if
139.1305 - 3 1 roll exch put
139.1306 -}bdf
139.1307 -/st{settransfer}bdf
139.1308 -/colorimage defed /_rci xdf
139.1309 -/_NXLevel2 defed {
139.1310 - _NXLevel2 not {
139.1311 -/colorimage where {
139.1312 -userdict eq {
139.1313 -/_rci false def
139.1314 -} if
139.1315 -} if
139.1316 - } if
139.1317 -} if
139.1318 -/md defed{
139.1319 - md type /dicttype eq {
139.1320 -/colorimage where {
139.1321 -md eq {
139.1322 -/_rci false def
139.1323 -}if
139.1324 -}if
139.1325 -/settransfer where {
139.1326 -md eq {
139.1327 -/st systemdict /settransfer get def
139.1328 -}if
139.1329 -}if
139.1330 - }if
139.1331 -}if
139.1332 -/setstrokeadjust defed
139.1333 -{
139.1334 - true setstrokeadjust
139.1335 - /C{curveto}bdf
139.1336 - /L{lineto}bdf
139.1337 - /m{moveto}bdf
139.1338 -}
139.1339 -{
139.1340 - /dr{transform .25 sub round .25 add
139.1341 -exch .25 sub round .25 add exch itransform}bdf
139.1342 - /C{dr curveto}bdf
139.1343 - /L{dr lineto}bdf
139.1344 - /m{dr moveto}bdf
139.1345 - /setstrokeadjust{pop}bdf
139.1346 -}ifelse
139.1347 -/rectstroke defed /xt xdf
139.1348 -xt {/yt save def} if
139.1349 -/privrectpath {
139.1350 - 4 -2 roll m
139.1351 - dtransform round exch round exch idtransform
139.1352 - 2 copy 0 lt exch 0 lt xor
139.1353 - {dup 0 exch rlineto exch 0 rlineto neg 0 exch rlineto}
139.1354 - {exch dup 0 rlineto exch 0 exch rlineto neg 0 rlineto}
139.1355 - ifelse
139.1356 - closepath
139.1357 -}bdf
139.1358 -/rectclip{newpath privrectpath clip newpath}def
139.1359 -/rectfill{gsave newpath privrectpath fill grestore}def
139.1360 -/rectstroke{gsave newpath privrectpath stroke grestore}def
139.1361 -xt {yt restore} if
139.1362 -/_fonthacksave false def
139.1363 -/currentpacking defed
139.1364 -{
139.1365 - /_bfh {/_fonthacksave currentpacking def false setpacking} bdf
139.1366 - /_efh {_fonthacksave setpacking} bdf
139.1367 -}
139.1368 -{
139.1369 - /_bfh {} bdf
139.1370 - /_efh {} bdf
139.1371 -}ifelse
139.1372 -/packedarray{array astore readonly}ndf
139.1373 -/`
139.1374 -{
139.1375 - false setoverprint
139.1376 -
139.1377 -
139.1378 - /-save0- save def
139.1379 - 5 index concat
139.1380 - pop
139.1381 - storerect left bottom width height rectclip
139.1382 - pop
139.1383 -
139.1384 - /dict_count countdictstack def
139.1385 - /op_count count 1 sub def
139.1386 - userdict begin
139.1387 -
139.1388 - /showpage {} def
139.1389 -
139.1390 - 0 setgray 0 setlinecap 1 setlinewidth
139.1391 - 0 setlinejoin 10 setmiterlimit [] 0 setdash newpath
139.1392 -
139.1393 -} bdf
139.1394 -/currentpacking defed{true setpacking}if
139.1395 -/min{2 copy gt{exch}if pop}bdf
139.1396 -/max{2 copy lt{exch}if pop}bdf
139.1397 -/xformfont { currentfont exch makefont setfont } bdf
139.1398 -/fhnumcolors 1
139.1399 - statusdict begin
139.1400 -/processcolors defed
139.1401 -{
139.1402 -pop processcolors
139.1403 -}
139.1404 -{
139.1405 -/deviceinfo defed {
139.1406 -deviceinfo /Colors known {
139.1407 -pop deviceinfo /Colors get
139.1408 -} if
139.1409 -} if
139.1410 -} ifelse
139.1411 - end
139.1412 -def
139.1413 -/printerRes
139.1414 - gsave
139.1415 - matrix defaultmatrix setmatrix
139.1416 - 72 72 dtransform
139.1417 - abs exch abs
139.1418 - max
139.1419 - grestore
139.1420 - def
139.1421 -/graycalcs
139.1422 -[
139.1423 - {Angle Frequency}
139.1424 - {GrayAngle GrayFrequency}
139.1425 - {0 Width Height matrix defaultmatrix idtransform
139.1426 -dup mul exch dup mul add sqrt 72 exch div}
139.1427 - {0 GrayWidth GrayHeight matrix defaultmatrix idtransform
139.1428 -dup mul exch dup mul add sqrt 72 exch div}
139.1429 -] def
139.1430 -/calcgraysteps {
139.1431 - forcemaxsteps
139.1432 - {
139.1433 -maxsteps
139.1434 - }
139.1435 - {
139.1436 -/currenthalftone defed
139.1437 -{currenthalftone /dicttype eq}{false}ifelse
139.1438 -{
139.1439 -currenthalftone begin
139.1440 -HalftoneType 4 le
139.1441 -{graycalcs HalftoneType 1 sub get exec}
139.1442 -{
139.1443 -HalftoneType 5 eq
139.1444 -{
139.1445 -Default begin
139.1446 -{graycalcs HalftoneType 1 sub get exec}
139.1447 -end
139.1448 -}
139.1449 -{0 60}
139.1450 -ifelse
139.1451 -}
139.1452 -ifelse
139.1453 -end
139.1454 -}
139.1455 -{
139.1456 -currentscreen pop exch
139.1457 -}
139.1458 -ifelse
139.1459 -
139.1460 -printerRes 300 max exch div exch
139.1461 -2 copy
139.1462 -sin mul round dup mul
139.1463 -3 1 roll
139.1464 -cos mul round dup mul
139.1465 -add 1 add
139.1466 -dup maxsteps gt {pop maxsteps} if
139.1467 - }
139.1468 - ifelse
139.1469 -} bdf
139.1470 -/nextrelease defed {
139.1471 - /languagelevel defed not {
139.1472 -/framebuffer defed {
139.1473 -0 40 string framebuffer 9 1 roll 8 {pop} repeat
139.1474 -dup 516 eq exch 520 eq or
139.1475 -{
139.1476 -/fhnumcolors 3 def
139.1477 -/currentscreen {60 0 {pop pop 1}}bdf
139.1478 -/calcgraysteps {maxsteps} bdf
139.1479 -}if
139.1480 -}if
139.1481 - }if
139.1482 -}if
139.1483 -fhnumcolors 1 ne {
139.1484 - /calcgraysteps {maxsteps} bdf
139.1485 -} if
139.1486 -/currentpagedevice defed {
139.1487 -
139.1488 -
139.1489 - currentpagedevice /PreRenderingEnhance known
139.1490 - {
139.1491 -currentpagedevice /PreRenderingEnhance get
139.1492 -{
139.1493 -/calcgraysteps
139.1494 -{
139.1495 -forcemaxsteps
139.1496 -{maxsteps}
139.1497 -{256 maxsteps min}
139.1498 -ifelse
139.1499 -} def
139.1500 -} if
139.1501 - } if
139.1502 -} if
139.1503 -/gradfrequency 144 def
139.1504 -printerRes 1000 lt {
139.1505 - /gradfrequency 72 def
139.1506 -} if
139.1507 -/adjnumsteps {
139.1508 -
139.1509 - dup dtransform abs exch abs max
139.1510 -
139.1511 - printerRes div
139.1512 -
139.1513 - gradfrequency mul
139.1514 - round
139.1515 - 5 max
139.1516 - min
139.1517 -}bdf
139.1518 -/goodsep {
139.1519 - spots exch get 4 get dup sepname eq exch (_vc_Registration) eq or
139.1520 -}bdf
139.1521 -/BeginGradation defed
139.1522 -{/bb{BeginGradation}bdf}
139.1523 -{/bb{}bdf}
139.1524 -ifelse
139.1525 -/EndGradation defed
139.1526 -{/eb{EndGradation}bdf}
139.1527 -{/eb{}bdf}
139.1528 -ifelse
139.1529 -/bottom -0 def
139.1530 -/delta -0 def
139.1531 -/frac -0 def
139.1532 -/height -0 def
139.1533 -/left -0 def
139.1534 -/numsteps1 -0 def
139.1535 -/radius -0 def
139.1536 -/right -0 def
139.1537 -/top -0 def
139.1538 -/width -0 def
139.1539 -/xt -0 def
139.1540 -/yt -0 def
139.1541 -/df currentflat def
139.1542 -/tempstr 1 string def
139.1543 -/clipflatness currentflat def
139.1544 -/inverted?
139.1545 - 0 currenttransfer exec .5 ge def
139.1546 -/tc1 [0 0 0 1] def
139.1547 -/tc2 [0 0 0 1] def
139.1548 -/storerect{/top xdf /right xdf /bottom xdf /left xdf
139.1549 -/width right left sub def /height top bottom sub def}bdf
139.1550 -/concatprocs{
139.1551 - systemdict /packedarray known
139.1552 - {dup type /packedarraytype eq 2 index type /packedarraytype eq or}{false}ifelse
139.1553 - {
139.1554 -/proc2 exch cvlit def /proc1 exch cvlit def
139.1555 -proc1 aload pop proc2 aload pop
139.1556 -proc1 length proc2 length add packedarray cvx
139.1557 - }
139.1558 - {
139.1559 -/proc2 exch cvlit def /proc1 exch cvlit def
139.1560 -/newproc proc1 length proc2 length add array def
139.1561 -newproc 0 proc1 putinterval newproc proc1 length proc2 putinterval
139.1562 -newproc cvx
139.1563 - }ifelse
139.1564 -}bdf
139.1565 -/i{dup 0 eq
139.1566 - {pop df dup}
139.1567 - {dup} ifelse
139.1568 - /clipflatness xdf setflat
139.1569 -}bdf
139.1570 -version cvr 38.0 le
139.1571 -{/setrgbcolor{
139.1572 -currenttransfer exec 3 1 roll
139.1573 -currenttransfer exec 3 1 roll
139.1574 -currenttransfer exec 3 1 roll
139.1575 -setrgbcolor}bdf}if
139.1576 -/vms {/vmsv save def} bdf
139.1577 -/vmr {vmsv restore} bdf
139.1578 -/vmrs{vmsv restore /vmsv save def}bdf
139.1579 -/eomode{
139.1580 - {/filler /eofill load def /clipper /eoclip load def}
139.1581 - {/filler /fill load def /clipper /clip load def}
139.1582 - ifelse
139.1583 -}bdf
139.1584 -/normtaper{}bdf
139.1585 -/logtaper{9 mul 1 add log}bdf
139.1586 -/CD{
139.1587 - /NF exch def
139.1588 - {
139.1589 -exch dup
139.1590 -/FID ne 1 index/UniqueID ne and
139.1591 -{exch NF 3 1 roll put}
139.1592 -{pop pop}
139.1593 -ifelse
139.1594 - }forall
139.1595 - NF
139.1596 -}bdf
139.1597 -/MN{
139.1598 - 1 index length
139.1599 - /Len exch def
139.1600 - dup length Len add
139.1601 - string dup
139.1602 - Len
139.1603 - 4 -1 roll
139.1604 - putinterval
139.1605 - dup
139.1606 - 0
139.1607 - 4 -1 roll
139.1608 - putinterval
139.1609 -}bdf
139.1610 -/RC{4 -1 roll /ourvec xdf 256 string cvs(|______)anchorsearch
139.1611 - {1 index MN cvn/NewN exch def cvn
139.1612 - findfont dup maxlength dict CD dup/FontName NewN put dup
139.1613 - /Encoding ourvec put NewN exch definefont pop}{pop}ifelse}bdf
139.1614 -/RF{
139.1615 - dup
139.1616 - FontDirectory exch
139.1617 - known
139.1618 - {pop 3 -1 roll pop}
139.1619 - {RC}
139.1620 - ifelse
139.1621 -}bdf
139.1622 -/FF{dup 256 string cvs(|______)exch MN cvn dup FontDirectory exch known
139.1623 - {exch pop findfont 3 -1 roll pop}
139.1624 - {pop dup findfont dup maxlength dict CD dup dup
139.1625 - /Encoding exch /Encoding get 256 array copy 7 -1 roll
139.1626 - {3 -1 roll dup 4 -2 roll put}forall put definefont}
139.1627 - ifelse}bdf
139.1628 -/RFJ{
139.1629 - dup
139.1630 - FontDirectory exch
139.1631 - known
139.1632 - {pop 3 -1 roll pop
139.1633 - FontDirectory /Ryumin-Light-83pv-RKSJ-H known
139.1634 - {pop pop /Ryumin-Light-83pv-RKSJ-H dup}if
139.1635 - }
139.1636 - {RC}
139.1637 - ifelse
139.1638 -}bdf
139.1639 -/FFJ{dup 256 string cvs(|______)exch MN cvn dup FontDirectory exch known
139.1640 - {exch pop findfont 3 -1 roll pop}
139.1641 - {pop
139.1642 -dup FontDirectory exch known not
139.1643 - {FontDirectory /Ryumin-Light-83pv-RKSJ-H known
139.1644 -{pop /Ryumin-Light-83pv-RKSJ-H}if
139.1645 - }if
139.1646 - dup findfont dup maxlength dict CD dup dup
139.1647 - /Encoding exch /Encoding get 256 array copy 7 -1 roll
139.1648 - {3 -1 roll dup 4 -2 roll put}forall put definefont}
139.1649 - ifelse}bdf
139.1650 -/fps{
139.1651 - currentflat
139.1652 - exch
139.1653 - dup 0 le{pop 1}if
139.1654 - {
139.1655 -dup setflat 3 index stopped
139.1656 -{1.3 mul dup 3 index gt{pop setflat pop pop stop}if}
139.1657 -{exit}
139.1658 -ifelse
139.1659 - }loop
139.1660 - pop setflat pop pop
139.1661 -}bdf
139.1662 -/fp{100 currentflat fps}bdf
139.1663 -/clipper{clip}bdf
139.1664 -/W{/clipper load 100 clipflatness dup setflat fps}bdf
139.1665 -userdict begin /BDFontDict 29 dict def end
139.1666 -BDFontDict begin
139.1667 -/bu{}def
139.1668 -/bn{}def
139.1669 -/setTxMode{av 70 ge{pop}if pop}def
139.1670 -/gm{m}def
139.1671 -/show{pop}def
139.1672 -/gr{pop}def
139.1673 -/fnt{pop pop pop}def
139.1674 -/fs{pop}def
139.1675 -/fz{pop}def
139.1676 -/lin{pop pop}def
139.1677 -/:M {pop pop} def
139.1678 -/sf {pop} def
139.1679 -/S {pop} def
139.1680 -/@b {pop pop pop pop pop pop pop pop} def
139.1681 -/_bdsave /save load def
139.1682 -/_bdrestore /restore load def
139.1683 -/save { dup /fontsave eq {null} {_bdsave} ifelse } def
139.1684 -/restore { dup null eq { pop } { _bdrestore } ifelse } def
139.1685 -/fontsave null def
139.1686 -end
139.1687 -/MacVec 256 array def
139.1688 -MacVec 0 /Helvetica findfont
139.1689 -/Encoding get 0 128 getinterval putinterval
139.1690 -MacVec 127 /DEL put MacVec 16#27 /quotesingle put MacVec 16#60 /grave put
139.1691 -/NUL/SOH/STX/ETX/EOT/ENQ/ACK/BEL/BS/HT/LF/VT/FF/CR/SO/SI
139.1692 -/DLE/DC1/DC2/DC3/DC4/NAK/SYN/ETB/CAN/EM/SUB/ESC/FS/GS/RS/US
139.1693 -MacVec 0 32 getinterval astore pop
139.1694 -/Adieresis/Aring/Ccedilla/Eacute/Ntilde/Odieresis/Udieresis/aacute
139.1695 -/agrave/acircumflex/adieresis/atilde/aring/ccedilla/eacute/egrave
139.1696 -/ecircumflex/edieresis/iacute/igrave/icircumflex/idieresis/ntilde/oacute
139.1697 -/ograve/ocircumflex/odieresis/otilde/uacute/ugrave/ucircumflex/udieresis
139.1698 -/dagger/degree/cent/sterling/section/bullet/paragraph/germandbls
139.1699 -/registered/copyright/trademark/acute/dieresis/notequal/AE/Oslash
139.1700 -/infinity/plusminus/lessequal/greaterequal/yen/mu/partialdiff/summation
139.1701 -/product/pi/integral/ordfeminine/ordmasculine/Omega/ae/oslash
139.1702 -/questiondown/exclamdown/logicalnot/radical/florin/approxequal/Delta/guillemotleft
139.1703 -/guillemotright/ellipsis/nbspace/Agrave/Atilde/Otilde/OE/oe
139.1704 -/endash/emdash/quotedblleft/quotedblright/quoteleft/quoteright/divide/lozenge
139.1705 -/ydieresis/Ydieresis/fraction/currency/guilsinglleft/guilsinglright/fi/fl
139.1706 -/daggerdbl/periodcentered/quotesinglbase/quotedblbase
139.1707 -/perthousand/Acircumflex/Ecircumflex/Aacute
139.1708 -/Edieresis/Egrave/Iacute/Icircumflex/Idieresis/Igrave/Oacute/Ocircumflex
139.1709 -/apple/Ograve/Uacute/Ucircumflex/Ugrave/dotlessi/circumflex/tilde
139.1710 -/macron/breve/dotaccent/ring/cedilla/hungarumlaut/ogonek/caron
139.1711 -MacVec 128 128 getinterval astore pop
139.1712 -end %. AltsysDict
139.1713 -%%EndResource
139.1714 -%%EndProlog
139.1715 -%%BeginSetup
139.1716 -AltsysDict begin
139.1717 -_bfh
139.1718 -%%IncludeResource: font Symbol
139.1719 -_efh
139.1720 -0 dict dup begin
139.1721 -end
139.1722 -/f0 /Symbol FF def
139.1723 -_bfh
139.1724 -%%IncludeResource: font ZapfHumanist601BT-Bold
139.1725 -_efh
139.1726 -0 dict dup begin
139.1727 -end
139.1728 -/f1 /ZapfHumanist601BT-Bold FF def
139.1729 -end %. AltsysDict
139.1730 -%%EndSetup
139.1731 -AltsysDict begin
139.1732 -/onlyk4{false}ndf
139.1733 -/ccmyk{dup 5 -1 roll sub 0 max exch}ndf
139.1734 -/cmyk2gray{
139.1735 - 4 -1 roll 0.3 mul 4 -1 roll 0.59 mul 4 -1 roll 0.11 mul
139.1736 - add add add 1 min neg 1 add
139.1737 -}bdf
139.1738 -/setcmykcolor{1 exch sub ccmyk ccmyk ccmyk pop setrgbcolor}ndf
139.1739 -/maxcolor {
139.1740 - max max max
139.1741 -} ndf
139.1742 -/maxspot {
139.1743 - pop
139.1744 -} ndf
139.1745 -/setcmykcoloroverprint{4{dup -1 eq{pop 0}if 4 1 roll}repeat setcmykcolor}ndf
139.1746 -/findcmykcustomcolor{5 packedarray}ndf
139.1747 -/setcustomcolor{exch aload pop pop 4{4 index mul 4 1 roll}repeat setcmykcolor pop}ndf
139.1748 -/setseparationgray{setgray}ndf
139.1749 -/setoverprint{pop}ndf
139.1750 -/currentoverprint false ndf
139.1751 -/cmykbufs2gray{
139.1752 - 0 1 2 index length 1 sub
139.1753 - {
139.1754 -4 index 1 index get 0.3 mul
139.1755 -4 index 2 index get 0.59 mul
139.1756 -4 index 3 index get 0.11 mul
139.1757 -4 index 4 index get
139.1758 -add add add cvi 255 min
139.1759 -255 exch sub
139.1760 -2 index 3 1 roll put
139.1761 - }for
139.1762 - 4 1 roll pop pop pop
139.1763 -}bdf
139.1764 -/colorimage{
139.1765 - pop pop
139.1766 - [
139.1767 -5 -1 roll/exec cvx
139.1768 -6 -1 roll/exec cvx
139.1769 -7 -1 roll/exec cvx
139.1770 -8 -1 roll/exec cvx
139.1771 -/cmykbufs2gray cvx
139.1772 - ]cvx
139.1773 - image
139.1774 -}
139.1775 -%. version 47.1 on Linotronic of Postscript defines colorimage incorrectly (rgb model only)
139.1776 -version cvr 47.1 le
139.1777 -statusdict /product get (Lino) anchorsearch{pop pop true}{pop false}ifelse
139.1778 -and{userdict begin bdf end}{ndf}ifelse
139.1779 -fhnumcolors 1 ne {/yt save def} if
139.1780 -/customcolorimage{
139.1781 - aload pop
139.1782 - (_vc_Registration) eq
139.1783 - {
139.1784 -pop pop pop pop separationimage
139.1785 - }
139.1786 - {
139.1787 -/ik xdf /iy xdf /im xdf /ic xdf
139.1788 -ic im iy ik cmyk2gray /xt xdf
139.1789 -currenttransfer
139.1790 -{dup 1.0 exch sub xt mul add}concatprocs
139.1791 -st
139.1792 -image
139.1793 - }
139.1794 - ifelse
139.1795 -}ndf
139.1796 -fhnumcolors 1 ne {yt restore} if
139.1797 -fhnumcolors 3 ne {/yt save def} if
139.1798 -/customcolorimage{
139.1799 - aload pop
139.1800 - (_vc_Registration) eq
139.1801 - {
139.1802 -pop pop pop pop separationimage
139.1803 - }
139.1804 - {
139.1805 -/ik xdf /iy xdf /im xdf /ic xdf
139.1806 -1.0 dup ic ik add min sub
139.1807 -1.0 dup im ik add min sub
139.1808 -1.0 dup iy ik add min sub
139.1809 -/ic xdf /iy xdf /im xdf
139.1810 -currentcolortransfer
139.1811 -4 1 roll
139.1812 -{dup 1.0 exch sub ic mul add}concatprocs 4 1 roll
139.1813 -{dup 1.0 exch sub iy mul add}concatprocs 4 1 roll
139.1814 -{dup 1.0 exch sub im mul add}concatprocs 4 1 roll
139.1815 -setcolortransfer
139.1816 -{/dummy xdf dummy}concatprocs{dummy}{dummy}true 3 colorimage
139.1817 - }
139.1818 - ifelse
139.1819 -}ndf
139.1820 -fhnumcolors 3 ne {yt restore} if
139.1821 -fhnumcolors 4 ne {/yt save def} if
139.1822 -/customcolorimage{
139.1823 - aload pop
139.1824 - (_vc_Registration) eq
139.1825 - {
139.1826 -pop pop pop pop separationimage
139.1827 - }
139.1828 - {
139.1829 -/ik xdf /iy xdf /im xdf /ic xdf
139.1830 -currentcolortransfer
139.1831 -{1.0 exch sub ik mul ik sub 1 add}concatprocs 4 1 roll
139.1832 -{1.0 exch sub iy mul iy sub 1 add}concatprocs 4 1 roll
139.1833 -{1.0 exch sub im mul im sub 1 add}concatprocs 4 1 roll
139.1834 -{1.0 exch sub ic mul ic sub 1 add}concatprocs 4 1 roll
139.1835 -setcolortransfer
139.1836 -{/dummy xdf dummy}concatprocs{dummy}{dummy}{dummy}
139.1837 -true 4 colorimage
139.1838 - }
139.1839 - ifelse
139.1840 -}ndf
139.1841 -fhnumcolors 4 ne {yt restore} if
139.1842 -/separationimage{image}ndf
139.1843 -/newcmykcustomcolor{6 packedarray}ndf
139.1844 -/inkoverprint false ndf
139.1845 -/setinkoverprint{pop}ndf
139.1846 -/setspotcolor {
139.1847 - spots exch get
139.1848 - dup 4 get (_vc_Registration) eq
139.1849 - {pop 1 exch sub setseparationgray}
139.1850 - {0 5 getinterval exch setcustomcolor}
139.1851 - ifelse
139.1852 -}ndf
139.1853 -/currentcolortransfer{currenttransfer dup dup dup}ndf
139.1854 -/setcolortransfer{st pop pop pop}ndf
139.1855 -/fas{}ndf
139.1856 -/sas{}ndf
139.1857 -/fhsetspreadsize{pop}ndf
139.1858 -/filler{fill}bdf
139.1859 -/F{gsave {filler}fp grestore}bdf
139.1860 -/f{closepath F}bdf
139.1861 -/S{gsave {stroke}fp grestore}bdf
139.1862 -/s{closepath S}bdf
139.1863 -/bc4 [0 0 0 0] def
139.1864 -/_lfp4 {
139.1865 - /iosv inkoverprint def
139.1866 - /cosv currentoverprint def
139.1867 - /yt xdf
139.1868 - /xt xdf
139.1869 - /ang xdf
139.1870 - storerect
139.1871 - /taperfcn xdf
139.1872 - /k2 xdf /y2 xdf /m2 xdf /c2 xdf
139.1873 - /k1 xdf /y1 xdf /m1 xdf /c1 xdf
139.1874 - c1 c2 sub abs
139.1875 - m1 m2 sub abs
139.1876 - y1 y2 sub abs
139.1877 - k1 k2 sub abs
139.1878 - maxcolor
139.1879 - calcgraysteps mul abs round
139.1880 - height abs adjnumsteps
139.1881 - dup 2 lt {pop 1} if
139.1882 - 1 sub /numsteps1 xdf
139.1883 - currentflat mark
139.1884 - currentflat clipflatness
139.1885 - /delta top bottom sub numsteps1 1 add div def
139.1886 - /right right left sub def
139.1887 - /botsv top delta sub def
139.1888 - {
139.1889 -{
139.1890 -W
139.1891 -xt yt translate
139.1892 -ang rotate
139.1893 -xt neg yt neg translate
139.1894 -dup setflat
139.1895 -/bottom botsv def
139.1896 -0 1 numsteps1
139.1897 -{
139.1898 -numsteps1 dup 0 eq {pop 0.5 } { div } ifelse
139.1899 -taperfcn /frac xdf
139.1900 -bc4 0 c2 c1 sub frac mul c1 add put
139.1901 -bc4 1 m2 m1 sub frac mul m1 add put
139.1902 -bc4 2 y2 y1 sub frac mul y1 add put
139.1903 -bc4 3 k2 k1 sub frac mul k1 add put
139.1904 -bc4 vc
139.1905 -1 index setflat
139.1906 -{
139.1907 -mark {newpath left bottom right delta rectfill}stopped
139.1908 -{cleartomark exch 1.3 mul dup setflat exch 2 copy gt{stop}if}
139.1909 -{cleartomark exit}ifelse
139.1910 -}loop
139.1911 -/bottom bottom delta sub def
139.1912 -}for
139.1913 -}
139.1914 -gsave stopped grestore
139.1915 -{exch pop 2 index exch 1.3 mul dup 100 gt{cleartomark setflat stop}if}
139.1916 -{exit}ifelse
139.1917 - }loop
139.1918 - cleartomark setflat
139.1919 - iosv setinkoverprint
139.1920 - cosv setoverprint
139.1921 -}bdf
139.1922 -/bcs [0 0] def
139.1923 -/_lfs4 {
139.1924 - /iosv inkoverprint def
139.1925 - /cosv currentoverprint def
139.1926 - /yt xdf
139.1927 - /xt xdf
139.1928 - /ang xdf
139.1929 - storerect
139.1930 - /taperfcn xdf
139.1931 - /tint2 xdf
139.1932 - /tint1 xdf
139.1933 - bcs exch 1 exch put
139.1934 - tint1 tint2 sub abs
139.1935 - bcs 1 get maxspot
139.1936 - calcgraysteps mul abs round
139.1937 - height abs adjnumsteps
139.1938 - dup 2 lt {pop 2} if
139.1939 - 1 sub /numsteps1 xdf
139.1940 - currentflat mark
139.1941 - currentflat clipflatness
139.1942 - /delta top bottom sub numsteps1 1 add div def
139.1943 - /right right left sub def
139.1944 - /botsv top delta sub def
139.1945 - {
139.1946 -{
139.1947 -W
139.1948 -xt yt translate
139.1949 -ang rotate
139.1950 -xt neg yt neg translate
139.1951 -dup setflat
139.1952 -/bottom botsv def
139.1953 -0 1 numsteps1
139.1954 -{
139.1955 -numsteps1 div taperfcn /frac xdf
139.1956 -bcs 0
139.1957 -1.0 tint2 tint1 sub frac mul tint1 add sub
139.1958 -put bcs vc
139.1959 -1 index setflat
139.1960 -{
139.1961 -mark {newpath left bottom right delta rectfill}stopped
139.1962 -{cleartomark exch 1.3 mul dup setflat exch 2 copy gt{stop}if}
139.1963 -{cleartomark exit}ifelse
139.1964 -}loop
139.1965 -/bottom bottom delta sub def
139.1966 -}for
139.1967 -}
139.1968 -gsave stopped grestore
139.1969 -{exch pop 2 index exch 1.3 mul dup 100 gt{cleartomark setflat stop}if}
139.1970 -{exit}ifelse
139.1971 - }loop
139.1972 - cleartomark setflat
139.1973 - iosv setinkoverprint
139.1974 - cosv setoverprint
139.1975 -}bdf
139.1976 -/_rfs4 {
139.1977 - /iosv inkoverprint def
139.1978 - /cosv currentoverprint def
139.1979 - /tint2 xdf
139.1980 - /tint1 xdf
139.1981 - bcs exch 1 exch put
139.1982 - /radius xdf
139.1983 - /yt xdf
139.1984 - /xt xdf
139.1985 - tint1 tint2 sub abs
139.1986 - bcs 1 get maxspot
139.1987 - calcgraysteps mul abs round
139.1988 - radius abs adjnumsteps
139.1989 - dup 2 lt {pop 2} if
139.1990 - 1 sub /numsteps1 xdf
139.1991 - radius numsteps1 div 2 div /halfstep xdf
139.1992 - currentflat mark
139.1993 - currentflat clipflatness
139.1994 - {
139.1995 -{
139.1996 -dup setflat
139.1997 -W
139.1998 -0 1 numsteps1
139.1999 -{
139.2000 -dup /radindex xdf
139.2001 -numsteps1 div /frac xdf
139.2002 -bcs 0
139.2003 -tint2 tint1 sub frac mul tint1 add
139.2004 -put bcs vc
139.2005 -1 index setflat
139.2006 -{
139.2007 -newpath mark xt yt radius 1 frac sub mul halfstep add 0 360
139.2008 -{ arc
139.2009 -radindex numsteps1 ne
139.2010 -{
139.2011 -xt yt
139.2012 -radindex 1 add numsteps1
139.2013 -div 1 exch sub
139.2014 -radius mul halfstep add
139.2015 -dup xt add yt moveto
139.2016 -360 0 arcn
139.2017 -} if
139.2018 -fill
139.2019 -}stopped
139.2020 -{cleartomark exch 1.3 mul dup setflat exch 2 copy gt{stop}if}
139.2021 -{cleartomark exit}ifelse
139.2022 -}loop
139.2023 -}for
139.2024 -}
139.2025 -gsave stopped grestore
139.2026 -{exch pop 2 index exch 1.3 mul dup 100 gt{cleartomark setflat stop}if}
139.2027 -{exit}ifelse
139.2028 - }loop
139.2029 - cleartomark setflat
139.2030 - iosv setinkoverprint
139.2031 - cosv setoverprint
139.2032 -}bdf
139.2033 -/_rfp4 {
139.2034 - /iosv inkoverprint def
139.2035 - /cosv currentoverprint def
139.2036 - /k2 xdf /y2 xdf /m2 xdf /c2 xdf
139.2037 - /k1 xdf /y1 xdf /m1 xdf /c1 xdf
139.2038 - /radius xdf
139.2039 - /yt xdf
139.2040 - /xt xdf
139.2041 - c1 c2 sub abs
139.2042 - m1 m2 sub abs
139.2043 - y1 y2 sub abs
139.2044 - k1 k2 sub abs
139.2045 - maxcolor
139.2046 - calcgraysteps mul abs round
139.2047 - radius abs adjnumsteps
139.2048 - dup 2 lt {pop 1} if
139.2049 - 1 sub /numsteps1 xdf
139.2050 - radius numsteps1 dup 0 eq {pop} {div} ifelse
139.2051 - 2 div /halfstep xdf
139.2052 - currentflat mark
139.2053 - currentflat clipflatness
139.2054 - {
139.2055 -{
139.2056 -dup setflat
139.2057 -W
139.2058 -0 1 numsteps1
139.2059 -{
139.2060 -dup /radindex xdf
139.2061 -numsteps1 dup 0 eq {pop 0.5 } { div } ifelse
139.2062 -/frac xdf
139.2063 -bc4 0 c2 c1 sub frac mul c1 add put
139.2064 -bc4 1 m2 m1 sub frac mul m1 add put
139.2065 -bc4 2 y2 y1 sub frac mul y1 add put
139.2066 -bc4 3 k2 k1 sub frac mul k1 add put
139.2067 -bc4 vc
139.2068 -1 index setflat
139.2069 -{
139.2070 -newpath mark xt yt radius 1 frac sub mul halfstep add 0 360
139.2071 -{ arc
139.2072 -radindex numsteps1 ne
139.2073 -{
139.2074 -xt yt
139.2075 -radindex 1 add
139.2076 -numsteps1 dup 0 eq {pop} {div} ifelse
139.2077 -1 exch sub
139.2078 -radius mul halfstep add
139.2079 -dup xt add yt moveto
139.2080 -360 0 arcn
139.2081 -} if
139.2082 -fill
139.2083 -}stopped
139.2084 -{cleartomark exch 1.3 mul dup setflat exch 2 copy gt{stop}if}
139.2085 -{cleartomark exit}ifelse
139.2086 -}loop
139.2087 -}for
139.2088 -}
139.2089 -gsave stopped grestore
139.2090 -{exch pop 2 index exch 1.3 mul dup 100 gt{cleartomark setflat stop}if}
139.2091 -{exit}ifelse
139.2092 - }loop
139.2093 - cleartomark setflat
139.2094 - iosv setinkoverprint
139.2095 - cosv setoverprint
139.2096 -}bdf
139.2097 -/lfp4{_lfp4}ndf
139.2098 -/lfs4{_lfs4}ndf
139.2099 -/rfs4{_rfs4}ndf
139.2100 -/rfp4{_rfp4}ndf
139.2101 -/cvc [0 0 0 1] def
139.2102 -/vc{
139.2103 - AltsysDict /cvc 2 index put
139.2104 - aload length 4 eq
139.2105 - {setcmykcolor}
139.2106 - {setspotcolor}
139.2107 - ifelse
139.2108 -}bdf
139.2109 -/origmtx matrix currentmatrix def
139.2110 -/ImMatrix matrix currentmatrix def
139.2111 -0 setseparationgray
139.2112 -/imgr {1692 1570.1102 2287.2756 2412 } def
139.2113 -/bleed 0 def
139.2114 -/clpr {1692 1570.1102 2287.2756 2412 } def
139.2115 -/xs 1 def
139.2116 -/ys 1 def
139.2117 -/botx 0 def
139.2118 -/overlap 0 def
139.2119 -/wdist 18 def
139.2120 -0 2 mul fhsetspreadsize
139.2121 -0 0 ne {/df 0 def /clipflatness 0 def} if
139.2122 -/maxsteps 256 def
139.2123 -/forcemaxsteps false def
139.2124 -vms
139.2125 --1845 -1956 translate
139.2126 -/currentpacking defed{false setpacking}if
139.2127 -/spots[
139.2128 -1 0 0 0 (Process Cyan) false newcmykcustomcolor
139.2129 -0 1 0 0 (Process Magenta) false newcmykcustomcolor
139.2130 -0 0 1 0 (Process Yellow) false newcmykcustomcolor
139.2131 -0 0 0 1 (Process Black) false newcmykcustomcolor
139.2132 -]def
139.2133 -/textopf false def
139.2134 -/curtextmtx{}def
139.2135 -/otw .25 def
139.2136 -/msf{dup/curtextmtx xdf makefont setfont}bdf
139.2137 -/makesetfont/msf load def
139.2138 -/curtextheight{.707104 .707104 curtextmtx dtransform
139.2139 - dup mul exch dup mul add sqrt}bdf
139.2140 -/ta2{
139.2141 -tempstr 2 index gsave exec grestore
139.2142 -cwidth cheight rmoveto
139.2143 -4 index eq{5 index 5 index rmoveto}if
139.2144 -2 index 2 index rmoveto
139.2145 -}bdf
139.2146 -/ta{exch systemdict/cshow known
139.2147 -{{/cheight xdf/cwidth xdf tempstr 0 2 index put ta2}exch cshow}
139.2148 -{{tempstr 0 2 index put tempstr stringwidth/cheight xdf/cwidth xdf ta2}forall}
139.2149 -ifelse 6{pop}repeat}bdf
139.2150 -/sts{/textopf currentoverprint def vc setoverprint
139.2151 -/ts{awidthshow}def exec textopf setoverprint}bdf
139.2152 -/stol{/xt currentlinewidth def
139.2153 - setlinewidth vc newpath
139.2154 - /ts{{false charpath stroke}ta}def exec
139.2155 - xt setlinewidth}bdf
139.2156 -
139.2157 -/strk{/textopf currentoverprint def vc setoverprint
139.2158 - /ts{{false charpath stroke}ta}def exec
139.2159 - textopf setoverprint
139.2160 - }bdf
139.2161 -n
139.2162 -[] 0 d
139.2163 -3.863708 M
139.2164 -1 w
139.2165 -0 j
139.2166 -0 J
139.2167 -false setoverprint
139.2168 -0 i
139.2169 -false eomode
139.2170 -[0 0 0 1] vc
139.2171 -vms
139.2172 -%white border -- disabled
139.2173 -%1845.2293 2127.8588 m
139.2174 -%2045.9437 2127.8588 L
139.2175 -%2045.9437 1956.1412 L
139.2176 -%1845.2293 1956.1412 L
139.2177 -%1845.2293 2127.8588 L
139.2178 -%0.1417 w
139.2179 -%2 J
139.2180 -%2 M
139.2181 -%[0 0 0 0] vc
139.2182 -%s
139.2183 -n
139.2184 -1950.8 2097.2 m
139.2185 -1958.8 2092.5 1967.3 2089 1975.5 2084.9 C
139.2186 -1976.7 2083.5 1976.1 2081.5 1976.7 2079.9 C
139.2187 -1979.6 2081.1 1981.6 2086.8 1985.3 2084 C
139.2188 -1993.4 2079.3 2001.8 2075.8 2010 2071.7 C
139.2189 -2010.5 2071.5 2010.5 2071.1 2010.8 2070.8 C
139.2190 -2011.2 2064.3 2010.9 2057.5 2011 2050.8 C
139.2191 -2015.8 2046.9 2022.2 2046.2 2026.6 2041.7 C
139.2192 -2026.5 2032.5 2026.8 2022.9 2026.4 2014.1 C
139.2193 -2020.4 2008.3 2015 2002.4 2008.8 1997.1 C
139.2194 -2003.8 1996.8 2000.7 2001.2 1996.1 2002.1 C
139.2195 -1995.2 1996.4 1996.9 1990.5 1995.6 1984.8 C
139.2196 -1989.9 1979 1984.5 1973.9 1978.8 1967.8 C
139.2197 -1977.7 1968.6 1976 1967.6 1974.5 1968.3 C
139.2198 -1967.4 1972.5 1960.1 1976.1 1952.7 1979.3 C
139.2199 -1946.8 1976.3 1943.4 1970.7 1938.5 1966.1 C
139.2200 -1933.9 1966.5 1929.4 1968.8 1925.1 1970.7 C
139.2201 -1917.2 1978.2 1906 1977.9 1897.2 1983.4 C
139.2202 -1893.2 1985.6 1889.4 1988.6 1885 1990.1 C
139.2203 -1884.6 1990.6 1883.9 1991 1883.8 1991.6 C
139.2204 -1883.7 2000.4 1884 2009.9 1883.6 2018.9 C
139.2205 -1887.7 2024 1893.2 2028.8 1898 2033.8 C
139.2206 -1899.1 2035.5 1900.9 2036.8 1902.5 2037.9 C
139.2207 -1903.9 2037.3 1905.2 2036.6 1906.4 2035.5 C
139.2208 -1906.3 2039.7 1906.5 2044.6 1906.1 2048.9 C
139.2209 -1906.3 2049.6 1906.7 2050.2 1907.1 2050.8 C
139.2210 -1913.4 2056 1918.5 2062.7 1924.8 2068.1 C
139.2211 -1926.6 2067.9 1928 2066.9 1929.4 2066 C
139.2212 -1930.2 2071 1927.7 2077.1 1930.6 2081.6 C
139.2213 -1936.6 2086.9 1941.5 2092.9 1947.9 2097.9 C
139.2214 -1949 2098.1 1949.9 2097.5 1950.8 2097.2 C
139.2215 -[0 0 0 0.18] vc
139.2216 -f
139.2217 -0.4 w
139.2218 -S
139.2219 -n
139.2220 -1975.2 2084.7 m
139.2221 -1976.6 2083.4 1975.7 2081.1 1976 2079.4 C
139.2222 -1979.3 2079.5 1980.9 2086.2 1984.8 2084 C
139.2223 -1992.9 2078.9 2001.7 2075.6 2010 2071.2 C
139.2224 -2011 2064.6 2010.2 2057.3 2010.8 2050.6 C
139.2225 -2015.4 2046.9 2021.1 2045.9 2025.9 2042.4 C
139.2226 -2026.5 2033.2 2026.8 2022.9 2025.6 2013.9 C
139.2227 -2020.5 2008.1 2014.5 2003.1 2009.3 1997.6 C
139.2228 -2004.1 1996.7 2000.7 2001.6 1995.9 2002.6 C
139.2229 -1995.2 1996.7 1996.3 1990.2 1994.9 1984.6 C
139.2230 -1989.8 1978.7 1983.6 1973.7 1978.4 1968 C
139.2231 -1977.3 1969.3 1976 1967.6 1974.8 1968.5 C
139.2232 -1967.7 1972.7 1960.4 1976.3 1952.9 1979.6 C
139.2233 -1946.5 1976.9 1943.1 1970.5 1937.8 1966.1 C
139.2234 -1928.3 1968.2 1920.6 1974.8 1911.6 1978.4 C
139.2235 -1901.9 1979.7 1893.9 1986.6 1885 1990.6 C
139.2236 -1884.3 1991 1884.3 1991.7 1884 1992.3 C
139.2237 -1884.5 2001 1884.2 2011 1884.3 2019.9 C
139.2238 -1890.9 2025.3 1895.9 2031.9 1902.3 2037.4 C
139.2239 -1904.2 2037.9 1905.6 2034.2 1906.8 2035.7 C
139.2240 -1907.4 2040.9 1905.7 2046.1 1907.3 2050.8 C
139.2241 -1913.6 2056.2 1919.2 2062.6 1925.1 2067.9 C
139.2242 -1926.9 2067.8 1928 2066.3 1929.6 2065.7 C
139.2243 -1929.9 2070.5 1929.2 2076 1930.1 2080.8 C
139.2244 -1936.5 2086.1 1941.6 2092.8 1948.4 2097.6 C
139.2245 -1957.3 2093.3 1966.2 2088.8 1975.2 2084.7 C
139.2246 -[0 0 0 0] vc
139.2247 -f
139.2248 -S
139.2249 -n
139.2250 -1954.8 2093.8 m
139.2251 -1961.6 2090.5 1968.2 2087 1975 2084 C
139.2252 -1975 2082.8 1975.6 2080.9 1974.8 2080.6 C
139.2253 -1974.3 2075.2 1974.6 2069.6 1974.5 2064 C
139.2254 -1977.5 2059.7 1984.5 2060 1988.9 2056.4 C
139.2255 -1989.5 2055.5 1990.5 2055.3 1990.8 2054.4 C
139.2256 -1991.1 2045.7 1991.4 2036.1 1990.6 2027.8 C
139.2257 -1990.7 2026.6 1992 2027.3 1992.8 2027.1 C
139.2258 -1997 2032.4 2002.6 2037.8 2007.6 2042.2 C
139.2259 -2008.7 2042.3 2007.8 2040.6 2007.4 2040 C
139.2260 -2002.3 2035.6 1997.5 2030 1992.8 2025.2 C
139.2261 -1991.6 2024.7 1990.8 2024.9 1990.1 2025.4 C
139.2262 -1989.4 2024.9 1988.1 2025.2 1987.2 2024.4 C
139.2263 -1987.1 2025.8 1988.3 2026.5 1989.4 2026.8 C
139.2264 -1989.4 2026.6 1989.3 2026.2 1989.6 2026.1 C
139.2265 -1989.9 2026.2 1989.9 2026.6 1989.9 2026.8 C
139.2266 -1989.8 2026.6 1990 2026.5 1990.1 2026.4 C
139.2267 -1990.2 2027 1991.1 2028.3 1990.1 2028 C
139.2268 -1989.9 2037.9 1990.5 2044.1 1989.6 2054.2 C
139.2269 -1985.9 2058 1979.7 2057.4 1976 2061.2 C
139.2270 -1974.5 2061.6 1975.2 2059.9 1974.5 2059.5 C
139.2271 -1973.9 2058 1975.6 2057.8 1975 2056.6 C
139.2272 -1974.5 2057.1 1974.6 2055.3 1973.6 2055.9 C
139.2273 -1971.9 2059.3 1974.7 2062.1 1973.1 2065.5 C
139.2274 -1973.1 2071.2 1972.9 2077 1973.3 2082.5 C
139.2275 -1967.7 2085.6 1962 2088 1956.3 2090.7 C
139.2276 -1953.9 2092.4 1951 2093 1948.6 2094.8 C
139.2277 -1943.7 2089.9 1937.9 2084.3 1933 2079.6 C
139.2278 -1931.3 2076.1 1933.2 2071.3 1932.3 2067.2 C
139.2279 -1931.3 2062.9 1933.3 2060.6 1932 2057.6 C
139.2280 -1932.7 2056.5 1930.9 2053.3 1933.2 2051.8 C
139.2281 -1936.8 2050.1 1940.1 2046.9 1944 2046.8 C
139.2282 -1946.3 2049.7 1949.3 2051.9 1952 2054.4 C
139.2283 -1954.5 2054.2 1956.4 2052.3 1958.7 2051.3 C
139.2284 -1960.8 2050 1963.2 2049 1965.6 2048.4 C
139.2285 -1968.3 2050.8 1970.7 2054.3 1973.6 2055.4 C
139.2286 -1973 2052.2 1969.7 2050.4 1967.6 2048.2 C
139.2287 -1967.1 2046.7 1968.8 2046.6 1969.5 2045.8 C
139.2288 -1972.8 2043.3 1980.6 2043.4 1979.3 2038.4 C
139.2289 -1979.4 2038.6 1979.2 2038.7 1979.1 2038.8 C
139.2290 -1978.7 2038.6 1978.9 2038.1 1978.8 2037.6 C
139.2291 -1978.9 2037.9 1978.7 2038 1978.6 2038.1 C
139.2292 -1978.2 2032.7 1978.4 2027.1 1978.4 2021.6 C
139.2293 -1979.3 2021.1 1980 2020.2 1981.5 2020.1 C
139.2294 -1983.5 2020.5 1984 2021.8 1985.1 2023.5 C
139.2295 -1985.7 2024 1987.4 2023.7 1986 2022.8 C
139.2296 -1984.7 2021.7 1983.3 2020.8 1983.9 2018.7 C
139.2297 -1987.2 2015.9 1993 2015.4 1994.9 2011.5 C
139.2298 -1992.2 2004.9 1999.3 2005.2 2002.1 2002.4 C
139.2299 -2005.9 2002.7 2004.8 1997.4 2009.1 1999 C
139.2300 -2011 1999.3 2010 2002.9 2012.7 2002.4 C
139.2301 -2010.2 2000.7 2009.4 1996.1 2005.5 1998.5 C
139.2302 -2002.1 2000.3 1999 2002.5 1995.4 2003.8 C
139.2303 -1995.2 2003.6 1994.9 2003.3 1994.7 2003.1 C
139.2304 -1994.3 1997 1995.6 1991.1 1994.4 1985.3 C
139.2305 -1994.3 1986 1993.8 1985 1994 1985.6 C
139.2306 -1993.8 1995.4 1994.4 2001.6 1993.5 2011.7 C
139.2307 -1989.7 2015.5 1983.6 2014.9 1979.8 2018.7 C
139.2308 -1978.3 2019.1 1979.1 2017.4 1978.4 2017 C
139.2309 -1977.8 2015.5 1979.4 2015.3 1978.8 2014.1 C
139.2310 -1978.4 2014.6 1978.5 2012.8 1977.4 2013.4 C
139.2311 -1975.8 2016.8 1978.5 2019.6 1976.9 2023 C
139.2312 -1977 2028.7 1976.7 2034.5 1977.2 2040 C
139.2313 -1971.6 2043.1 1965.8 2045.6 1960.1 2048.2 C
139.2314 -1957.7 2049.9 1954.8 2050.5 1952.4 2052.3 C
139.2315 -1947.6 2047.4 1941.8 2041.8 1936.8 2037.2 C
139.2316 -1935.2 2033.6 1937.1 2028.8 1936.1 2024.7 C
139.2317 -1935.1 2020.4 1937.1 2018.1 1935.9 2015.1 C
139.2318 -1936.5 2014.1 1934.7 2010.8 1937.1 2009.3 C
139.2319 -1944.4 2004.8 1952 2000.9 1959.9 1997.8 C
139.2320 -1963.9 1997 1963.9 2001.9 1966.8 2003.3 C
139.2321 -1970.3 2006.9 1973.7 2009.9 1976.9 2012.9 C
139.2322 -1977.9 2013 1977.1 2011.4 1976.7 2010.8 C
139.2323 -1971.6 2006.3 1966.8 2000.7 1962 1995.9 C
139.2324 -1960 1995.2 1960.1 1996.6 1958.2 1995.6 C
139.2325 -1957 1997 1955.1 1998.8 1953.2 1998 C
139.2326 -1951.7 1994.5 1954.1 1993.4 1952.9 1991.1 C
139.2327 -1952.1 1990.5 1953.3 1990.2 1953.2 1989.6 C
139.2328 -1954.2 1986.8 1950.9 1981.4 1954.4 1981.2 C
139.2329 -1954.7 1981.6 1954.7 1981.7 1955.1 1982 C
139.2330 -1961.9 1979.1 1967.6 1975 1974.3 1971.6 C
139.2331 -1974.7 1969.8 1976.7 1969.5 1978.4 1969.7 C
139.2332 -1980.3 1970 1979.3 1973.6 1982 1973.1 C
139.2333 -1975.8 1962.2 1968 1975.8 1960.8 1976.7 C
139.2334 -1956.9 1977.4 1953.3 1982.4 1949.1 1978.8 C
139.2335 -1946 1975.8 1941.2 1971 1939.5 1969.2 C
139.2336 -1938.5 1968.6 1938.9 1967.4 1937.8 1966.8 C
139.2337 -1928.7 1969.4 1920.6 1974.5 1912.4 1979.1 C
139.2338 -1904 1980 1896.6 1985 1889.3 1989.4 C
139.2339 -1887.9 1990.4 1885.1 1990.3 1885 1992.5 C
139.2340 -1885.4 2000.6 1885.2 2012.9 1885.2 2019.9 C
139.2341 -1886.1 2022 1889.7 2019.5 1888.4 2022.8 C
139.2342 -1889 2023.3 1889.8 2024.4 1890.3 2024 C
139.2343 -1891.2 2023.5 1891.8 2028.2 1893.4 2026.6 C
139.2344 -1894.2 2026.3 1893.9 2027.3 1894.4 2027.6 C
139.2345 -1893.4 2027.6 1894.7 2028.3 1894.1 2028.5 C
139.2346 -1894.4 2029.6 1896 2030 1896 2029.2 C
139.2347 -1896.2 2029 1896.3 2029 1896.5 2029.2 C
139.2348 -1896.8 2029.8 1897.3 2030 1897 2030.7 C
139.2349 -1896.5 2030.7 1896.9 2031.5 1897.2 2031.6 C
139.2350 -1898.3 2034 1899.5 2030.6 1899.6 2033.3 C
139.2351 -1898.5 2033 1899.6 2034.4 1900.1 2034.8 C
139.2352 -1901.3 2035.8 1903.2 2034.6 1902.5 2036.7 C
139.2353 -1904.4 2036.9 1906.1 2032.2 1907.6 2035.5 C
139.2354 -1907.5 2040.1 1907.7 2044.9 1907.3 2049.4 C
139.2355 -1908 2050.2 1908.3 2051.4 1909.5 2051.6 C
139.2356 -1910.1 2051.1 1911.6 2051.1 1911.4 2052.3 C
139.2357 -1909.7 2052.8 1912.4 2054 1912.6 2054.7 C
139.2358 -1913.4 2055.2 1913 2053.7 1913.6 2054.4 C
139.2359 -1913.6 2054.5 1913.6 2055.3 1913.6 2054.7 C
139.2360 -1913.7 2054.4 1913.9 2054.4 1914 2054.7 C
139.2361 -1914 2054.9 1914.1 2055.3 1913.8 2055.4 C
139.2362 -1913.7 2056 1915.2 2057.6 1916 2057.6 C
139.2363 -1915.9 2057.3 1916.1 2057.2 1916.2 2057.1 C
139.2364 -1917 2056.8 1916.7 2057.7 1917.2 2058 C
139.2365 -1917 2058.3 1916.7 2058.3 1916.4 2058.3 C
139.2366 -1917.1 2059 1917.3 2060.1 1918.4 2060.4 C
139.2367 -1918.1 2059.2 1919.1 2060.6 1919.1 2059.5 C
139.2368 -1919 2060.6 1920.6 2060.1 1919.8 2061.2 C
139.2369 -1919.6 2061.2 1919.3 2061.2 1919.1 2061.2 C
139.2370 -1919.6 2061.9 1921.4 2064.2 1921.5 2062.6 C
139.2371 -1922.4 2062.1 1921.6 2063.9 1922.2 2064.3 C
139.2372 -1922.9 2067.3 1926.1 2064.3 1925.6 2067.2 C
139.2373 -1927.2 2066.8 1928.4 2064.6 1930.1 2065.2 C
139.2374 -1931.8 2067.8 1931 2071.8 1930.8 2074.8 C
139.2375 -1930.6 2076.4 1930.1 2078.6 1930.6 2080.4 C
139.2376 -1936.6 2085.4 1941.8 2091.6 1948.1 2096.9 C
139.2377 -1950.7 2096.7 1952.6 2094.8 1954.8 2093.8 C
139.2378 -[0 0.33 0.33 0.99] vc
139.2379 -f
139.2380 -S
139.2381 -n
139.2382 -1989.4 2080.6 m
139.2383 -1996.1 2077.3 2002.7 2073.8 2009.6 2070.8 C
139.2384 -2009.6 2069.6 2010.2 2067.7 2009.3 2067.4 C
139.2385 -2008.9 2062 2009.1 2056.4 2009.1 2050.8 C
139.2386 -2012.3 2046.6 2019 2046.6 2023.5 2043.2 C
139.2387 -2024 2042.3 2025.1 2042.1 2025.4 2041.2 C
139.2388 -2025.3 2032.7 2025.6 2023.1 2025.2 2014.6 C
139.2389 -2025 2015.3 2024.6 2014.2 2024.7 2014.8 C
139.2390 -2024.5 2024.7 2025.1 2030.9 2024.2 2041 C
139.2391 -2020.4 2044.8 2014.3 2044.2 2010.5 2048 C
139.2392 -2009 2048.4 2009.8 2046.7 2009.1 2046.3 C
139.2393 -2008.5 2044.8 2010.2 2044.6 2009.6 2043.4 C
139.2394 -2009.1 2043.9 2009.2 2042.1 2008.1 2042.7 C
139.2395 -2006.5 2046.1 2009.3 2048.9 2007.6 2052.3 C
139.2396 -2007.7 2058 2007.5 2063.8 2007.9 2069.3 C
139.2397 -2002.3 2072.4 1996.5 2074.8 1990.8 2077.5 C
139.2398 -1988.4 2079.2 1985.6 2079.8 1983.2 2081.6 C
139.2399 -1980.5 2079 1977.9 2076.5 1975.5 2074.1 C
139.2400 -1975.5 2075.1 1975.5 2076.2 1975.5 2077.2 C
139.2401 -1977.8 2079.3 1980.3 2081.6 1982.7 2083.7 C
139.2402 -1985.3 2083.5 1987.1 2081.6 1989.4 2080.6 C
139.2403 -f
139.2404 -S
139.2405 -n
139.2406 -1930.1 2079.9 m
139.2407 -1931.1 2075.6 1929.2 2071.1 1930.8 2067.2 C
139.2408 -1930.3 2066.3 1930.1 2064.6 1928.7 2065.5 C
139.2409 -1927.7 2066.4 1926.5 2067 1925.3 2067.4 C
139.2410 -1924.5 2066.9 1925.6 2065.7 1924.4 2066 C
139.2411 -1924.2 2067.2 1923.6 2065.5 1923.2 2065.7 C
139.2412 -1922.3 2063.6 1917.8 2062.1 1919.6 2060.4 C
139.2413 -1919.3 2060.5 1919.2 2060.3 1919.1 2060.2 C
139.2414 -1919.7 2060.9 1918.2 2061 1917.6 2060.2 C
139.2415 -1917 2059.6 1916.1 2058.8 1916.4 2058 C
139.2416 -1915.5 2058 1917.4 2057.1 1915.7 2057.8 C
139.2417 -1914.8 2057.1 1913.4 2056.2 1913.3 2054.9 C
139.2418 -1913.1 2055.4 1911.3 2054.3 1910.9 2053.2 C
139.2419 -1910.7 2052.9 1910.2 2052.5 1910.7 2052.3 C
139.2420 -1911.1 2052.5 1910.9 2052 1910.9 2051.8 C
139.2421 -1910.5 2051.2 1909.9 2052.6 1909.2 2051.8 C
139.2422 -1908.2 2051.4 1907.8 2050.2 1907.1 2049.4 C
139.2423 -1907.5 2044.8 1907.3 2040 1907.3 2035.2 C
139.2424 -1905.3 2033 1902.8 2039.3 1902.3 2035.7 C
139.2425 -1899.6 2036 1898.4 2032.5 1896.3 2030.7 C
139.2426 -1895.7 2030.1 1897.5 2030 1896.3 2029.7 C
139.2427 -1896.3 2030.6 1895 2029.7 1894.4 2029.2 C
139.2428 -1892.9 2028.1 1894.2 2027.4 1893.6 2027.1 C
139.2429 -1892.1 2027.9 1891.7 2025.6 1890.8 2024.9 C
139.2430 -1891.1 2024.6 1889.1 2024.3 1888.4 2023 C
139.2431 -1887.5 2022.6 1888.2 2021.9 1888.1 2021.3 C
139.2432 -1886.7 2022 1885.2 2020.4 1884.8 2019.2 C
139.2433 -1884.8 2010 1884.6 2000.2 1885 1991.8 C
139.2434 -1886.9 1989.6 1889.9 1989.3 1892.2 1987.5 C
139.2435 -1898.3 1982.7 1905.6 1980.1 1912.8 1978.6 C
139.2436 -1921 1974.2 1928.8 1968.9 1937.8 1966.6 C
139.2437 -1939.8 1968.3 1938.8 1968.3 1940.4 1970 C
139.2438 -1945.4 1972.5 1947.6 1981.5 1954.6 1979.3 C
139.2439 -1952.3 1981 1950.4 1978.4 1948.6 1977.9 C
139.2440 -1945.1 1973.9 1941.1 1970.6 1938 1966.6 C
139.2441 -1928.4 1968.5 1920.6 1974.8 1911.9 1978.8 C
139.2442 -1907.1 1979.2 1902.6 1981.7 1898.2 1983.6 C
139.2443 -1893.9 1986 1889.9 1989 1885.5 1990.8 C
139.2444 -1884.9 1991.2 1884.8 1991.8 1884.5 1992.3 C
139.2445 -1884.9 2001.3 1884.7 2011.1 1884.8 2019.6 C
139.2446 -1890.6 2025 1896.5 2031.2 1902.3 2036.9 C
139.2447 -1904.6 2037.6 1905 2033 1907.3 2035.5 C
139.2448 -1907.2 2040.2 1907 2044.8 1907.1 2049.6 C
139.2449 -1913.6 2055.3 1918.4 2061.5 1925.1 2067.4 C
139.2450 -1927.3 2068.2 1929.6 2062.5 1930.6 2066.9 C
139.2451 -1929.7 2070.7 1930.3 2076 1930.1 2080.1 C
139.2452 -1935.6 2085.7 1941.9 2090.7 1947.2 2096.7 C
139.2453 -1942.2 2091.1 1935.5 2085.2 1930.1 2079.9 C
139.2454 -[0.18 0.18 0 0.78] vc
139.2455 -f
139.2456 -S
139.2457 -n
139.2458 -1930.8 2061.9 m
139.2459 -1930.3 2057.8 1931.8 2053.4 1931.1 2050.4 C
139.2460 -1931.3 2050.3 1931.7 2050.5 1931.6 2050.1 C
139.2461 -1933 2051.1 1934.4 2049.5 1935.9 2048.7 C
139.2462 -1937 2046.5 1939.5 2047.1 1941.2 2045.1 C
139.2463 -1939.7 2042.6 1937.3 2041.2 1935.4 2039.3 C
139.2464 -1934 2039.7 1934.5 2038.1 1933.7 2037.6 C
139.2465 -1934 2033.3 1933.1 2027.9 1934.4 2024.4 C
139.2466 -1934.3 2023.8 1933.9 2022.8 1933 2022.8 C
139.2467 -1931.6 2023.1 1930.5 2024.4 1929.2 2024.9 C
139.2468 -1928.4 2024.5 1929.8 2023.5 1928.7 2023.5 C
139.2469 -1927.7 2024.1 1926.2 2022.6 1925.6 2021.6 C
139.2470 -1926.9 2021.6 1924.8 2020.6 1925.6 2020.4 C
139.2471 -1924.7 2021.7 1923.9 2019.6 1923.2 2019.2 C
139.2472 -1923.3 2018.3 1923.8 2018.1 1923.2 2018 C
139.2473 -1922.9 2017.8 1922.9 2017.5 1922.9 2017.2 C
139.2474 -1922.8 2018.3 1921.3 2017.3 1920.3 2018 C
139.2475 -1916.6 2019.7 1913 2022.1 1910 2024.7 C
139.2476 -1910 2032.9 1910 2041.2 1910 2049.4 C
139.2477 -1915.4 2055.2 1920 2058.7 1925.3 2064.8 C
139.2478 -1927.2 2064 1929 2061.4 1930.8 2061.9 C
139.2479 -[0 0 0 0] vc
139.2480 -f
139.2481 -S
139.2482 -n
139.2483 -1907.6 2030.4 m
139.2484 -1907.5 2027.1 1906.4 2021.7 1908.5 2019.9 C
139.2485 -1908.8 2020.1 1908.9 2019 1909.2 2019.6 C
139.2486 -1910 2019.6 1912 2019.2 1913.1 2018.2 C
139.2487 -1913.7 2016.5 1920.2 2015.7 1917.4 2012.7 C
139.2488 -1918.2 2011.2 1917 2013.8 1917.2 2012 C
139.2489 -1916.9 2012.3 1916 2012.4 1915.2 2012 C
139.2490 -1912.5 2010.5 1916.6 2008.8 1913.6 2009.6 C
139.2491 -1912.6 2009.2 1911.1 2009 1910.9 2007.6 C
139.2492 -1911 1999.2 1911.8 1989.8 1911.2 1982.2 C
139.2493 -1910.1 1981.1 1908.8 1982.2 1907.6 1982.2 C
139.2494 -1900.8 1986.5 1893.2 1988.8 1887.2 1994.2 C
139.2495 -1887.2 2002.4 1887.2 2010.7 1887.2 2018.9 C
139.2496 -1892.6 2024.7 1897.2 2028.2 1902.5 2034.3 C
139.2497 -1904.3 2033.3 1906.2 2032.1 1907.6 2030.4 C
139.2498 -f
139.2499 -S
139.2500 -n
139.2501 -1910.7 2025.4 m
139.2502 -1912.7 2022.4 1916.7 2020.8 1919.8 2018.9 C
139.2503 -1920.2 2018.7 1920.6 2018.6 1921 2018.4 C
139.2504 -1925 2020 1927.4 2028.5 1932 2024.2 C
139.2505 -1932.3 2025 1932.5 2023.7 1932.8 2024.4 C
139.2506 -1932.8 2028 1932.8 2031.5 1932.8 2035 C
139.2507 -1931.9 2033.9 1932.5 2036.3 1932.3 2036.9 C
139.2508 -1933.2 2036.4 1932.5 2038.5 1933 2038.4 C
139.2509 -1933.1 2040.5 1935.6 2042.2 1936.6 2043.2 C
139.2510 -1936.2 2042.4 1935.1 2040.8 1933.7 2040.3 C
139.2511 -1932.2 2034.4 1933.8 2029.8 1933 2023.2 C
139.2512 -1931.1 2024.9 1928.4 2026.4 1926.5 2023.5 C
139.2513 -1925.1 2021.6 1923 2019.8 1921.5 2018.2 C
139.2514 -1917.8 2018.9 1915.2 2022.5 1911.6 2023.5 C
139.2515 -1910.8 2023.8 1911.2 2024.7 1910.4 2025.2 C
139.2516 -1910.9 2031.8 1910.6 2039.1 1910.7 2045.6 C
139.2517 -1910.1 2048 1910.7 2045.9 1911.2 2044.8 C
139.2518 -1910.6 2038.5 1911.2 2031.8 1910.7 2025.4 C
139.2519 -[0.07 0.06 0 0.58] vc
139.2520 -f
139.2521 -S
139.2522 -n
139.2523 -1910.7 2048.9 m
139.2524 -1910.3 2047.4 1911.3 2046.5 1911.6 2045.3 C
139.2525 -1912.9 2045.3 1913.9 2047.1 1915.2 2045.8 C
139.2526 -1915.2 2044.9 1916.6 2043.3 1917.2 2042.9 C
139.2527 -1918.7 2042.9 1919.4 2044.4 1920.5 2043.2 C
139.2528 -1921.2 2042.2 1921.4 2040.9 1922.4 2040.3 C
139.2529 -1924.5 2040.3 1925.7 2040.9 1926.8 2039.6 C
139.2530 -1927.1 2037.9 1926.8 2038.1 1927.7 2037.6 C
139.2531 -1929 2037.5 1930.4 2037 1931.6 2037.2 C
139.2532 -1932.3 2038.2 1933.1 2038.7 1932.8 2040.3 C
139.2533 -1935 2041.8 1935.9 2043.8 1938.5 2044.8 C
139.2534 -1938.6 2045 1938.3 2045.5 1938.8 2045.3 C
139.2535 -1939.1 2042.9 1935.4 2044.2 1935.4 2042.2 C
139.2536 -1932.1 2040.8 1932.8 2037.2 1932 2034.8 C
139.2537 -1932.3 2034 1932.7 2035.4 1932.5 2034.8 C
139.2538 -1931.3 2031.8 1935.5 2020.1 1928.9 2025.9 C
139.2539 -1924.6 2024.7 1922.6 2014.5 1917.4 2020.4 C
139.2540 -1915.5 2022.8 1912 2022.6 1910.9 2025.4 C
139.2541 -1911.5 2031.9 1910.9 2038.8 1911.4 2045.3 C
139.2542 -1911.1 2046.5 1910 2047.4 1910.4 2048.9 C
139.2543 -1915.1 2054.4 1920.4 2058.3 1925.1 2063.8 C
139.2544 -1920.8 2058.6 1914.9 2054.3 1910.7 2048.9 C
139.2545 -[0.4 0.4 0 0] vc
139.2546 -f
139.2547 -S
139.2548 -n
139.2549 -1934.7 2031.9 m
139.2550 -1934.6 2030.7 1934.9 2029.5 1934.4 2028.5 C
139.2551 -1934 2029.5 1934.3 2031.2 1934.2 2032.6 C
139.2552 -1933.8 2031.7 1934.9 2031.6 1934.7 2031.9 C
139.2553 -[0.92 0.92 0 0.67] vc
139.2554 -f
139.2555 -S
139.2556 -n
139.2557 -vmrs
139.2558 -1934.7 2019.4 m
139.2559 -1934.1 2015.3 1935.6 2010.9 1934.9 2007.9 C
139.2560 -1935.1 2007.8 1935.6 2008.1 1935.4 2007.6 C
139.2561 -1936.8 2008.6 1938.2 2007 1939.7 2006.2 C
139.2562 -1940.1 2004.3 1942.7 2005 1943.6 2003.8 C
139.2563 -1945.1 2000.3 1954 2000.8 1950 1996.6 C
139.2564 -1952.1 1993.3 1948.2 1989.2 1951.2 1985.6 C
139.2565 -1953 1981.4 1948.4 1982.3 1947.9 1979.8 C
139.2566 -1945.4 1979.6 1945.1 1975.5 1942.4 1975 C
139.2567 -1942.4 1972.3 1938 1973.6 1938.5 1970.4 C
139.2568 -1937.4 1969 1935.6 1970.1 1934.2 1970.2 C
139.2569 -1927.5 1974.5 1919.8 1976.8 1913.8 1982.2 C
139.2570 -1913.8 1990.4 1913.8 1998.7 1913.8 2006.9 C
139.2571 -1919.3 2012.7 1923.8 2016.2 1929.2 2022.3 C
139.2572 -1931.1 2021.6 1932.8 2018.9 1934.7 2019.4 C
139.2573 -[0 0 0 0] vc
139.2574 -f
139.2575 -0.4 w
139.2576 -2 J
139.2577 -2 M
139.2578 -S
139.2579 -n
139.2580 -2024.2 2038.1 m
139.2581 -2024.1 2029.3 2024.4 2021.7 2024.7 2014.4 C
139.2582 -2024.4 2013.6 2020.6 2013.4 2021.3 2011.2 C
139.2583 -2020.5 2010.3 2018.4 2010.6 2018.9 2008.6 C
139.2584 -2019 2008.8 2018.8 2009 2018.7 2009.1 C
139.2585 -2018.2 2006.7 2015.2 2007.9 2015.3 2005.5 C
139.2586 -2014.7 2004.8 2012.4 2005.1 2013.2 2003.6 C
139.2587 -2012.3 2004.2 2012.8 2002.4 2012.7 2002.6 C
139.2588 -2009.4 2003.3 2011.2 1998.6 2008.4 1999.2 C
139.2589 -2007 1999.1 2006.1 1999.4 2005.7 2000.4 C
139.2590 -2006.9 1998.5 2007.7 2000.5 2009.3 2000.2 C
139.2591 -2009.2 2003.7 2012.4 2002.1 2012.9 2005.2 C
139.2592 -2015.9 2005.6 2015.2 2008.6 2017.7 2008.8 C
139.2593 -2018.4 2009.6 2018.3 2011.4 2019.6 2011 C
139.2594 -2021.1 2011.7 2021.4 2014.8 2023.7 2015.1 C
139.2595 -2023.7 2023.5 2023.9 2031.6 2023.5 2040.5 C
139.2596 -2021.8 2041.7 2020.7 2043.6 2018.4 2043.9 C
139.2597 -2020.8 2042.7 2025.5 2041.8 2024.2 2038.1 C
139.2598 -[0 0.87 0.91 0.83] vc
139.2599 -f
139.2600 -S
139.2601 -n
139.2602 -2023.5 2040 m
139.2603 -2023.5 2031.1 2023.5 2023.4 2023.5 2015.1 C
139.2604 -2020.2 2015 2021.8 2010.3 2018.4 2011 C
139.2605 -2018.6 2007.5 2014.7 2009.3 2014.8 2006.4 C
139.2606 -2011.8 2006.3 2012.2 2002.3 2009.8 2002.4 C
139.2607 -2009.7 2001.5 2009.2 2000.1 2008.4 2000.2 C
139.2608 -2008.7 2000.9 2009.7 2001.2 2009.3 2002.4 C
139.2609 -2008.4 2004.2 2007.5 2003.1 2007.9 2005.5 C
139.2610 -2007.9 2010.8 2007.7 2018.7 2008.1 2023.2 C
139.2611 -2009 2024.3 2007.3 2023.4 2007.9 2024 C
139.2612 -2007.7 2024.6 2007.3 2026.3 2008.6 2027.1 C
139.2613 -2009.7 2026.8 2010 2027.6 2010.5 2028 C
139.2614 -2010.5 2028.2 2010.5 2029.1 2010.5 2028.5 C
139.2615 -2011.5 2028 2010.5 2030 2011.5 2030 C
139.2616 -2014.2 2029.7 2012.9 2032.2 2014.8 2032.6 C
139.2617 -2015.1 2033.6 2015.3 2033 2016 2033.3 C
139.2618 -2017 2033.9 2016.6 2035.4 2017.2 2036.2 C
139.2619 -2018.7 2036.4 2019.2 2039 2021.3 2038.4 C
139.2620 -2021.6 2035.4 2019.7 2029.5 2021.1 2027.3 C
139.2621 -2020.9 2023.5 2021.5 2018.5 2020.6 2016 C
139.2622 -2020.9 2013.9 2021.5 2015.4 2022.3 2014.4 C
139.2623 -2022.2 2015.1 2023.3 2014.8 2023.2 2015.6 C
139.2624 -2022.7 2019.8 2023.3 2024.3 2022.8 2028.5 C
139.2625 -2022.3 2028.2 2022.6 2027.6 2022.5 2027.1 C
139.2626 -2022.5 2027.8 2022.5 2029.2 2022.5 2029.2 C
139.2627 -2022.6 2029.2 2022.7 2029.1 2022.8 2029 C
139.2628 -2023.9 2032.8 2022.6 2037 2023 2040.8 C
139.2629 -2022.3 2041.2 2021.6 2041.5 2021.1 2042.2 C
139.2630 -2022 2041.2 2022.9 2041.4 2023.5 2040 C
139.2631 -[0 1 1 0.23] vc
139.2632 -f
139.2633 -S
139.2634 -n
139.2635 -2009.1 1997.8 m
139.2636 -2003.8 1997.7 2000.1 2002.4 1995.4 2003.1 C
139.2637 -1995 1999.5 1995.2 1995 1995.2 1992 C
139.2638 -1995.2 1995.8 1995 1999.7 1995.4 2003.3 C
139.2639 -2000.3 2002.2 2003.8 1997.9 2009.1 1997.8 C
139.2640 -2012.3 2001.2 2015.6 2004.8 2018.7 2008.1 C
139.2641 -2021.6 2011.2 2027.5 2013.9 2025.9 2019.9 C
139.2642 -2026.1 2017.9 2025.6 2016.2 2025.4 2014.4 C
139.2643 -2020.2 2008.4 2014 2003.6 2009.1 1997.8 C
139.2644 -[0.18 0.18 0 0.78] vc
139.2645 -f
139.2646 -S
139.2647 -n
139.2648 -2009.3 1997.8 m
139.2649 -2008.7 1997.4 2007.9 1997.6 2007.2 1997.6 C
139.2650 -2007.9 1997.6 2008.9 1997.4 2009.6 1997.8 C
139.2651 -2014.7 2003.6 2020.8 2008.8 2025.9 2014.8 C
139.2652 -2025.8 2017.7 2026.1 2014.8 2025.6 2014.1 C
139.2653 -2020.4 2008.8 2014.8 2003.3 2009.3 1997.8 C
139.2654 -[0.07 0.06 0 0.58] vc
139.2655 -f
139.2656 -S
139.2657 -n
139.2658 -2009.6 1997.6 m
139.2659 -2009 1997.1 2008.1 1997.4 2007.4 1997.3 C
139.2660 -2008.1 1997.4 2009 1997.1 2009.6 1997.6 C
139.2661 -2014.8 2003.7 2021.1 2008.3 2025.9 2014.4 C
139.2662 -2021.1 2008.3 2014.7 2003.5 2009.6 1997.6 C
139.2663 -[0.4 0.4 0 0] vc
139.2664 -f
139.2665 -S
139.2666 -n
139.2667 -2021.8 2011.5 m
139.2668 -2021.9 2012.2 2022.3 2013.5 2023.7 2013.6 C
139.2669 -2023.4 2012.7 2022.8 2011.8 2021.8 2011.5 C
139.2670 -[0 0.33 0.33 0.99] vc
139.2671 -f
139.2672 -S
139.2673 -n
139.2674 -2021.1 2042 m
139.2675 -2022.1 2041.1 2020.9 2040.2 2020.6 2039.6 C
139.2676 -2018.4 2039.5 2018.1 2036.9 2016.3 2036.4 C
139.2677 -2015.8 2035.5 2015.3 2033.8 2014.8 2033.6 C
139.2678 -2012.4 2033.8 2013 2030.4 2010.5 2030.2 C
139.2679 -2009.6 2028.9 2009.6 2028.3 2008.4 2028 C
139.2680 -2006.9 2026.7 2007.5 2024.3 2006 2023.2 C
139.2681 -2006.6 2023.2 2005.7 2023.3 2005.7 2023 C
139.2682 -2006.4 2022.5 2006.3 2021.1 2006.7 2020.6 C
139.2683 -2006.6 2015 2006.9 2009 2006.4 2003.8 C
139.2684 -2006.9 2002.5 2007.6 2001.1 2006.9 2000.7 C
139.2685 -2004.6 2003.6 2003 2002.9 2000.2 2004.3 C
139.2686 -1999.3 2005.8 1997.9 2006.3 1996.1 2006.7 C
139.2687 -1995.7 2008.9 1996 2011.1 1995.9 2012.9 C
139.2688 -1993.4 2015.1 1990.5 2016.2 1987.7 2017.7 C
139.2689 -1987.1 2019.3 1991.1 2019.4 1990.4 2021.3 C
139.2690 -1990.5 2021.5 1991.9 2022.3 1992 2023 C
139.2691 -1994.8 2024.4 1996.2 2027.5 1998.5 2030 C
139.2692 -2002.4 2033 2005.2 2037.2 2008.8 2041 C
139.2693 -2010.2 2041.3 2011.6 2042 2011 2043.9 C
139.2694 -2011.2 2044.8 2010.1 2045.3 2010.5 2046.3 C
139.2695 -2013.8 2044.8 2017.5 2043.4 2021.1 2042 C
139.2696 -[0 0.5 0.5 0.2] vc
139.2697 -f
139.2698 -S
139.2699 -n
139.2700 -2019.4 2008.8 m
139.2701 -2018.9 2009.2 2019.3 2009.9 2019.6 2010.3 C
139.2702 -2022.2 2011.5 2020.3 2009.1 2019.4 2008.8 C
139.2703 -[0 0.33 0.33 0.99] vc
139.2704 -f
139.2705 -S
139.2706 -n
139.2707 -2018 2007.4 m
139.2708 -2015.7 2006.7 2015.3 2003.6 2012.9 2002.8 C
139.2709 -2013.5 2003.7 2013.5 2005.1 2015.6 2005.2 C
139.2710 -2016.4 2006.1 2015.7 2007.7 2018 2007.4 C
139.2711 -f
139.2712 -S
139.2713 -n
139.2714 -vmrs
139.2715 -1993.5 2008.8 m
139.2716 -1993.4 2000 1993.7 1992.5 1994 1985.1 C
139.2717 -1993.7 1984.3 1989.9 1984.1 1990.6 1982 C
139.2718 -1989.8 1981.1 1987.7 1981.4 1988.2 1979.3 C
139.2719 -1988.3 1979.6 1988.1 1979.7 1988 1979.8 C
139.2720 -1987.5 1977.5 1984.5 1978.6 1984.6 1976.2 C
139.2721 -1983.9 1975.5 1981.7 1975.8 1982.4 1974.3 C
139.2722 -1981.6 1974.9 1982.1 1973.1 1982 1973.3 C
139.2723 -1979 1973.7 1980 1968.8 1976.9 1969.7 C
139.2724 -1975.9 1969.8 1975.3 1970.3 1975 1971.2 C
139.2725 -1976.2 1969.2 1977 1971.2 1978.6 1970.9 C
139.2726 -1978.5 1974.4 1981.7 1972.8 1982.2 1976 C
139.2727 -1985.2 1976.3 1984.5 1979.3 1987 1979.6 C
139.2728 -1987.7 1980.3 1987.5 1982.1 1988.9 1981.7 C
139.2729 -1990.4 1982.4 1990.7 1985.5 1993 1985.8 C
139.2730 -1992.9 1994.3 1993.2 2002.3 1992.8 2011.2 C
139.2731 -1991.1 2012.4 1990 2014.4 1987.7 2014.6 C
139.2732 -1990.1 2013.4 1994.7 2012.6 1993.5 2008.8 C
139.2733 -[0 0.87 0.91 0.83] vc
139.2734 -f
139.2735 -0.4 w
139.2736 -2 J
139.2737 -2 M
139.2738 -S
139.2739 -n
139.2740 -1992.8 2010.8 m
139.2741 -1992.8 2001.8 1992.8 1994.1 1992.8 1985.8 C
139.2742 -1989.5 1985.7 1991.1 1981.1 1987.7 1981.7 C
139.2743 -1987.9 1978.2 1983.9 1980 1984.1 1977.2 C
139.2744 -1981.1 1977 1981.5 1973 1979.1 1973.1 C
139.2745 -1979 1972.2 1978.5 1970.9 1977.6 1970.9 C
139.2746 -1977.9 1971.6 1979 1971.9 1978.6 1973.1 C
139.2747 -1977.6 1974.9 1976.8 1973.9 1977.2 1976.2 C
139.2748 -1977.2 1981.5 1977 1989.4 1977.4 1994 C
139.2749 -1978.3 1995 1976.6 1994.1 1977.2 1994.7 C
139.2750 -1977 1995.3 1976.6 1997 1977.9 1997.8 C
139.2751 -1979 1997.5 1979.3 1998.3 1979.8 1998.8 C
139.2752 -1979.8 1998.9 1979.8 1999.8 1979.8 1999.2 C
139.2753 -1980.8 1998.7 1979.7 2000.7 1980.8 2000.7 C
139.2754 -1983.5 2000.4 1982.1 2003 1984.1 2003.3 C
139.2755 -1984.4 2004.3 1984.5 2003.7 1985.3 2004 C
139.2756 -1986.3 2004.6 1985.9 2006.1 1986.5 2006.9 C
139.2757 -1988 2007.1 1988.4 2009.7 1990.6 2009.1 C
139.2758 -1990.9 2006.1 1989 2000.2 1990.4 1998 C
139.2759 -1990.2 1994.3 1990.8 1989.2 1989.9 1986.8 C
139.2760 -1990.2 1984.7 1990.8 1986.2 1991.6 1985.1 C
139.2761 -1991.5 1985.9 1992.6 1985.5 1992.5 1986.3 C
139.2762 -1992 1990.5 1992.6 1995 1992 1999.2 C
139.2763 -1991.6 1998.9 1991.9 1998.3 1991.8 1997.8 C
139.2764 -1991.8 1998.5 1991.8 2000 1991.8 2000 C
139.2765 -1991.9 1999.9 1992 1999.8 1992 1999.7 C
139.2766 -1993.2 2003.5 1991.9 2007.7 1992.3 2011.5 C
139.2767 -1991.6 2012 1990.9 2012.2 1990.4 2012.9 C
139.2768 -1991.3 2011.9 1992.2 2012.1 1992.8 2010.8 C
139.2769 -[0 1 1 0.23] vc
139.2770 -f
139.2771 -S
139.2772 -n
139.2773 -1978.4 1968.5 m
139.2774 -1977 1969.2 1975.8 1968.2 1974.5 1969 C
139.2775 -1968.3 1973 1961.6 1976 1955.1 1979.1 C
139.2776 -1962 1975.9 1968.8 1972.5 1975.5 1968.8 C
139.2777 -1976.5 1968.8 1977.6 1968.8 1978.6 1968.8 C
139.2778 -1981.7 1972.1 1984.8 1975.7 1988 1978.8 C
139.2779 -1990.9 1981.9 1996.8 1984.6 1995.2 1990.6 C
139.2780 -1995.3 1988.6 1994.9 1986.9 1994.7 1985.1 C
139.2781 -1989.5 1979.1 1983.3 1974.3 1978.4 1968.5 C
139.2782 -[0.18 0.18 0 0.78] vc
139.2783 -f
139.2784 -S
139.2785 -n
139.2786 -1978.4 1968.3 m
139.2787 -1977.9 1968.7 1977.1 1968.5 1976.4 1968.5 C
139.2788 -1977.3 1968.8 1978.1 1967.9 1978.8 1968.5 C
139.2789 -1984 1974.3 1990.1 1979.5 1995.2 1985.6 C
139.2790 -1995.1 1988.4 1995.3 1985.6 1994.9 1984.8 C
139.2791 -1989.5 1979.4 1983.9 1973.8 1978.4 1968.3 C
139.2792 -[0.07 0.06 0 0.58] vc
139.2793 -f
139.2794 -S
139.2795 -n
139.2796 -1978.6 1968 m
139.2797 -1977.9 1968 1977.4 1968.6 1978.4 1968 C
139.2798 -1983.9 1973.9 1990.1 1979.1 1995.2 1985.1 C
139.2799 -1990.2 1979 1983.8 1974.1 1978.6 1968 C
139.2800 -[0.4 0.4 0 0] vc
139.2801 -f
139.2802 -S
139.2803 -n
139.2804 -1991.1 1982.2 m
139.2805 -1991.2 1982.9 1991.6 1984.2 1993 1984.4 C
139.2806 -1992.6 1983.5 1992.1 1982.5 1991.1 1982.2 C
139.2807 -[0 0.33 0.33 0.99] vc
139.2808 -f
139.2809 -S
139.2810 -n
139.2811 -1990.4 2012.7 m
139.2812 -1991.4 2011.8 1990.2 2010.9 1989.9 2010.3 C
139.2813 -1987.7 2010.2 1987.4 2007.6 1985.6 2007.2 C
139.2814 -1985.1 2006.2 1984.6 2004.5 1984.1 2004.3 C
139.2815 -1981.7 2004.5 1982.3 2001.2 1979.8 2000.9 C
139.2816 -1978.8 1999.6 1978.8 1999.1 1977.6 1998.8 C
139.2817 -1976.1 1997.4 1976.7 1995 1975.2 1994 C
139.2818 -1975.8 1994 1975 1994 1975 1993.7 C
139.2819 -1975.7 1993.2 1975.6 1991.8 1976 1991.3 C
139.2820 -1975.9 1985.7 1976.1 1979.7 1975.7 1974.5 C
139.2821 -1976.2 1973.3 1976.9 1971.8 1976.2 1971.4 C
139.2822 -1973.9 1974.3 1972.2 1973.6 1969.5 1975 C
139.2823 -1967.9 1977.5 1963.8 1977.1 1961.8 1980 C
139.2824 -1959 1980 1957.6 1983 1954.8 1982.9 C
139.2825 -1953.8 1984.2 1954.8 1985.7 1955.1 1987.2 C
139.2826 -1956.2 1989.5 1959.7 1990.1 1959.9 1991.8 C
139.2827 -1965.9 1998 1971.8 2005.2 1978.1 2011.7 C
139.2828 -1979.5 2012 1980.9 2012.7 1980.3 2014.6 C
139.2829 -1980.5 2015.6 1979.4 2016 1979.8 2017 C
139.2830 -1983 2015.6 1986.8 2014.1 1990.4 2012.7 C
139.2831 -[0 0.5 0.5 0.2] vc
139.2832 -f
139.2833 -S
139.2834 -n
139.2835 -1988.7 1979.6 m
139.2836 -1988.2 1979.9 1988.6 1980.6 1988.9 1981 C
139.2837 -1991.4 1982.2 1989.6 1979.9 1988.7 1979.6 C
139.2838 -[0 0.33 0.33 0.99] vc
139.2839 -f
139.2840 -S
139.2841 -n
139.2842 -1987.2 1978.1 m
139.2843 -1985 1977.5 1984.6 1974.3 1982.2 1973.6 C
139.2844 -1982.7 1974.5 1982.8 1975.8 1984.8 1976 C
139.2845 -1985.7 1976.9 1985 1978.4 1987.2 1978.1 C
139.2846 -f
139.2847 -S
139.2848 -n
139.2849 -1975.5 2084 m
139.2850 -1975.5 2082 1975.3 2080 1975.7 2078.2 C
139.2851 -1978.8 2079 1980.9 2085.5 1984.8 2083.5 C
139.2852 -1993 2078.7 2001.6 2075 2010 2070.8 C
139.2853 -2010.1 2064 2009.9 2057.2 2010.3 2050.6 C
139.2854 -2014.8 2046.2 2020.9 2045.7 2025.6 2042 C
139.2855 -2026.1 2035.1 2025.8 2028 2025.9 2021.1 C
139.2856 -2025.8 2027.8 2026.1 2034.6 2025.6 2041.2 C
139.2857 -2022.2 2044.9 2017.6 2046.8 2012.9 2048 C
139.2858 -2012.5 2049.5 2010.4 2049.4 2009.8 2051.1 C
139.2859 -2009.9 2057.6 2009.6 2064.2 2010 2070.5 C
139.2860 -2001.2 2075.4 1992 2079.1 1983.2 2084 C
139.2861 -1980.3 2082.3 1977.8 2079.2 1975.2 2077.5 C
139.2862 -1974.9 2079.9 1977.2 2084.6 1973.3 2085.2 C
139.2863 -1964.7 2088.6 1956.8 2093.7 1948.1 2097.2 C
139.2864 -1949 2097.3 1949.6 2096.9 1950.3 2096.7 C
139.2865 -1958.4 2091.9 1967.1 2088.2 1975.5 2084 C
139.2866 -[0.18 0.18 0 0.78] vc
139.2867 -f
139.2868 -S
139.2869 -n
139.2870 -vmrs
139.2871 -1948.6 2094.5 m
139.2872 -1950.2 2093.7 1951.8 2092.9 1953.4 2092.1 C
139.2873 -1951.8 2092.9 1950.2 2093.7 1948.6 2094.5 C
139.2874 -[0 0.87 0.91 0.83] vc
139.2875 -f
139.2876 -0.4 w
139.2877 -2 J
139.2878 -2 M
139.2879 -S
139.2880 -n
139.2881 -1971.6 2082.3 m
139.2882 -1971.6 2081.9 1970.7 2081.1 1970.9 2081.3 C
139.2883 -1970.7 2081.6 1970.6 2081.6 1970.4 2081.3 C
139.2884 -1970.8 2080.1 1968.7 2081.7 1968.3 2080.8 C
139.2885 -1966.6 2080.9 1966.7 2078 1964.2 2078.2 C
139.2886 -1964.8 2075 1960.1 2075.8 1960.1 2072.9 C
139.2887 -1958 2072.3 1957.5 2069.3 1955.3 2069.3 C
139.2888 -1953.9 2070.9 1948.8 2067.8 1950 2072 C
139.2889 -1949 2074 1943.2 2070.6 1944 2074.8 C
139.2890 -1942.2 2076.6 1937.6 2073.9 1938 2078.2 C
139.2891 -1936.7 2078.6 1935 2078.6 1933.7 2078.2 C
139.2892 -1933.5 2080 1936.8 2080.7 1937.3 2082.8 C
139.2893 -1939.9 2083.5 1940.6 2086.4 1942.6 2088 C
139.2894 -1945.2 2089.2 1946 2091.3 1948.4 2093.6 C
139.2895 -1956 2089.5 1963.9 2086.1 1971.6 2082.3 C
139.2896 -[0 0.01 1 0] vc
139.2897 -f
139.2898 -S
139.2899 -n
139.2900 -1958.2 2089.7 m
139.2901 -1956.4 2090 1955.6 2091.3 1953.9 2091.9 C
139.2902 -1955.6 2091.9 1956.5 2089.7 1958.2 2089.7 C
139.2903 -[0 0.87 0.91 0.83] vc
139.2904 -f
139.2905 -S
139.2906 -n
139.2907 -1929.9 2080.4 m
139.2908 -1929.5 2077.3 1929.7 2073.9 1929.6 2070.8 C
139.2909 -1929.8 2074.1 1929.2 2077.8 1930.1 2080.8 C
139.2910 -1935.8 2085.9 1941.4 2091.3 1946.9 2096.9 C
139.2911 -1941.2 2091 1935.7 2086 1929.9 2080.4 C
139.2912 -[0.4 0.4 0 0] vc
139.2913 -f
139.2914 -S
139.2915 -n
139.2916 -1930.1 2080.4 m
139.2917 -1935.8 2086 1941.5 2090.7 1946.9 2096.7 C
139.2918 -1941.5 2090.9 1935.7 2085.8 1930.1 2080.4 C
139.2919 -[0.07 0.06 0 0.58] vc
139.2920 -f
139.2921 -S
139.2922 -n
139.2923 -1940.9 2087.1 m
139.2924 -1941.7 2088 1944.8 2090.6 1943.6 2089.2 C
139.2925 -1942.5 2089 1941.6 2087.7 1940.9 2087.1 C
139.2926 -[0 0.87 0.91 0.83] vc
139.2927 -f
139.2928 -S
139.2929 -n
139.2930 -1972.8 2082.8 m
139.2931 -1973 2075.3 1972.4 2066.9 1973.3 2059.5 C
139.2932 -1972.5 2058.9 1972.8 2057.3 1973.1 2056.4 C
139.2933 -1974.8 2055.2 1973.4 2055.5 1972.4 2055.4 C
139.2934 -1970.1 2053.2 1967.9 2050.9 1965.6 2048.7 C
139.2935 -1960.9 2049.9 1956.9 2052.7 1952.4 2054.7 C
139.2936 -1949.3 2052.5 1946.3 2049.5 1943.6 2046.8 C
139.2937 -1939.9 2047.7 1936.8 2050.1 1933.5 2051.8 C
139.2938 -1930.9 2054.9 1933.5 2056.2 1932.3 2059.7 C
139.2939 -1933.2 2059.7 1932.2 2060.5 1932.5 2060.2 C
139.2940 -1933.2 2062.5 1931.6 2064.6 1932.5 2067.4 C
139.2941 -1932.9 2069.7 1932.7 2072.2 1932.8 2074.6 C
139.2942 -1933.6 2070.6 1932.2 2066.3 1933 2062.6 C
139.2943 -1934.4 2058.2 1929.8 2053.5 1935.2 2051.1 C
139.2944 -1937.7 2049.7 1940.2 2048 1942.8 2046.8 C
139.2945 -1945.9 2049.2 1948.8 2052 1951.7 2054.7 C
139.2946 -1952.7 2054.7 1953.6 2054.6 1954.4 2054.2 C
139.2947 -1958.1 2052.5 1961.7 2049.3 1965.9 2049.2 C
139.2948 -1968.2 2052.8 1975.2 2055 1972.6 2060.9 C
139.2949 -1973.3 2062.4 1972.2 2065.2 1972.6 2067.6 C
139.2950 -1972.7 2072.6 1972.4 2077.7 1972.8 2082.5 C
139.2951 -1968.1 2084.9 1963.5 2087.5 1958.7 2089.5 C
139.2952 -1963.5 2087.4 1968.2 2085 1972.8 2082.8 C
139.2953 -f
139.2954 -S
139.2955 -n
139.2956 -1935.2 2081.1 m
139.2957 -1936.8 2083.4 1938.6 2084.6 1940.4 2086.6 C
139.2958 -1938.8 2084.4 1936.7 2083.4 1935.2 2081.1 C
139.2959 -f
139.2960 -S
139.2961 -n
139.2962 -1983.2 2081.3 m
139.2963 -1984.8 2080.5 1986.3 2079.7 1988 2078.9 C
139.2964 -1986.3 2079.7 1984.8 2080.5 1983.2 2081.3 C
139.2965 -f
139.2966 -S
139.2967 -n
139.2968 -2006.2 2069.1 m
139.2969 -2006.2 2068.7 2005.2 2067.9 2005.5 2068.1 C
139.2970 -2005.3 2068.4 2005.2 2068.4 2005 2068.1 C
139.2971 -2005.4 2066.9 2003.3 2068.5 2002.8 2067.6 C
139.2972 -2001.2 2067.7 2001.2 2064.8 1998.8 2065 C
139.2973 -1999.4 2061.8 1994.7 2062.6 1994.7 2059.7 C
139.2974 -1992.4 2059.5 1992.4 2055.8 1990.1 2056.8 C
139.2975 -1985.9 2059.5 1981.1 2061 1976.9 2063.8 C
139.2976 -1977.2 2067.6 1974.9 2074.2 1978.8 2075.8 C
139.2977 -1979.6 2077.8 1981.7 2078.4 1982.9 2080.4 C
139.2978 -1990.6 2076.3 1998.5 2072.9 2006.2 2069.1 C
139.2979 -[0 0.01 1 0] vc
139.2980 -f
139.2981 -S
139.2982 -n
139.2983 -vmrs
139.2984 -1992.8 2076.5 m
139.2985 -1991 2076.8 1990.2 2078.1 1988.4 2078.7 C
139.2986 -1990.2 2078.7 1991 2076.5 1992.8 2076.5 C
139.2987 -[0 0.87 0.91 0.83] vc
139.2988 -f
139.2989 -0.4 w
139.2990 -2 J
139.2991 -2 M
139.2992 -S
139.2993 -n
139.2994 -1975.5 2073.4 m
139.2995 -1976.1 2069.7 1973.9 2064.6 1977.4 2062.4 C
139.2996 -1973.9 2064.5 1976.1 2069.9 1975.5 2073.6 C
139.2997 -1976 2074.8 1979.3 2077.4 1978.1 2076 C
139.2998 -1977 2075.7 1975.8 2074.5 1975.5 2073.4 C
139.2999 -f
139.3000 -S
139.3001 -n
139.3002 -2007.4 2069.6 m
139.3003 -2007.6 2062.1 2007 2053.7 2007.9 2046.3 C
139.3004 -2007.1 2045.7 2007.3 2044.1 2007.6 2043.2 C
139.3005 -2009.4 2042 2007.9 2042.3 2006.9 2042.2 C
139.3006 -2002.2 2037.4 1996.7 2032.4 1992.5 2027.3 C
139.3007 -1992 2027.3 1991.6 2027.3 1991.1 2027.3 C
139.3008 -1991.4 2035.6 1991.4 2045.6 1991.1 2054.4 C
139.3009 -1990.5 2055.5 1988.4 2056.6 1990.6 2055.4 C
139.3010 -1991.6 2055.4 1991.6 2054.1 1991.6 2053.2 C
139.3011 -1990.8 2044.7 1991.9 2035.4 1991.6 2027.6 C
139.3012 -1991.8 2027.6 1992 2027.6 1992.3 2027.6 C
139.3013 -1997 2032.8 2002.5 2037.7 2007.2 2042.9 C
139.3014 -2007.3 2044.8 2006.7 2047.4 2007.6 2048.4 C
139.3015 -2006.9 2055.1 2007.1 2062.5 2007.4 2069.3 C
139.3016 -2002.7 2071.7 1998.1 2074.3 1993.2 2076.3 C
139.3017 -1998 2074.2 2002.7 2071.8 2007.4 2069.6 C
139.3018 -f
139.3019 -S
139.3020 -n
139.3021 -2006.7 2069.1 m
139.3022 -2006.3 2068.6 2005.9 2067.7 2005.7 2066.9 C
139.3023 -2005.7 2059.7 2005.9 2051.4 2005.5 2045.1 C
139.3024 -2004.9 2045.3 2004.7 2044.5 2004.3 2045.3 C
139.3025 -2005.1 2045.3 2004.2 2045.8 2004.8 2046 C
139.3026 -2004.8 2052.2 2004.8 2059.2 2004.8 2064.5 C
139.3027 -2005.7 2065.7 2005.1 2065.7 2005 2066.7 C
139.3028 -2003.8 2067 2002.7 2067.2 2001.9 2066.4 C
139.3029 -2001.3 2064.6 1998 2063.1 1998 2061.9 C
139.3030 -1996.1 2062.3 1996.6 2058.3 1994.2 2058.8 C
139.3031 -1992.6 2057.7 1992.7 2054.8 1989.9 2056.6 C
139.3032 -1985.6 2059.3 1980.9 2060.8 1976.7 2063.6 C
139.3033 -1976 2066.9 1976 2071.2 1976.7 2074.6 C
139.3034 -1977.6 2070.8 1973.1 2062.1 1980.5 2061.2 C
139.3035 -1984.3 2060.3 1987.5 2058.2 1990.8 2056.4 C
139.3036 -1991.7 2056.8 1992.9 2057.2 1993.5 2059.2 C
139.3037 -1994.3 2058.6 1994.4 2060.6 1994.7 2059.2 C
139.3038 -1995.3 2062.7 1999.2 2061.4 1998.8 2064.8 C
139.3039 -2001.8 2065.4 2002.5 2068.4 2005.2 2067.4 C
139.3040 -2004.9 2067.9 2006 2068 2006.4 2069.1 C
139.3041 -2001.8 2071.1 1997.4 2073.9 1992.8 2075.8 C
139.3042 -1997.5 2073.8 2002 2071.2 2006.7 2069.1 C
139.3043 -[0 0.2 1 0] vc
139.3044 -f
139.3045 -S
139.3046 -n
139.3047 -1988.7 2056.6 m
139.3048 -1985.1 2058.7 1981.1 2060.1 1977.6 2061.9 C
139.3049 -1981.3 2060.5 1985.6 2058.1 1988.7 2056.6 C
139.3050 -[0 0.87 0.91 0.83] vc
139.3051 -f
139.3052 -S
139.3053 -n
139.3054 -1977.9 2059.5 m
139.3055 -1975.7 2064.5 1973.7 2054.7 1975.2 2060.9 C
139.3056 -1976 2060.6 1977.6 2059.7 1977.9 2059.5 C
139.3057 -f
139.3058 -S
139.3059 -n
139.3060 -1989.6 2051.3 m
139.3061 -1990.1 2042.3 1989.8 2036.6 1989.9 2028 C
139.3062 -1989.8 2027 1990.8 2028.3 1990.1 2027.3 C
139.3063 -1988.9 2026.7 1986.7 2026.9 1986.8 2024.7 C
139.3064 -1987.4 2023 1985.9 2024.6 1985.1 2023.7 C
139.3065 -1984.1 2021.4 1982.5 2020.5 1980.3 2020.6 C
139.3066 -1979.9 2020.8 1979.5 2021.1 1979.3 2021.6 C
139.3067 -1979.7 2025.8 1978.4 2033 1979.6 2038.1 C
139.3068 -1983.7 2042.9 1968.8 2044.6 1978.8 2042.7 C
139.3069 -1979.3 2042.3 1979.6 2041.9 1980 2041.5 C
139.3070 -1980 2034.8 1980 2027 1980 2021.6 C
139.3071 -1981.3 2020.5 1981.7 2021.5 1982.9 2021.8 C
139.3072 -1983.6 2024.7 1986.1 2023.8 1986.8 2026.4 C
139.3073 -1987.1 2027.7 1988.6 2027.1 1989.2 2028.3 C
139.3074 -1989.1 2036.7 1989.3 2044.8 1988.9 2053.7 C
139.3075 -1987.2 2054.9 1986.2 2056.8 1983.9 2057.1 C
139.3076 -1986.3 2055.9 1990.9 2055 1989.6 2051.3 C
139.3077 -f
139.3078 -S
139.3079 -n
139.3080 -1971.6 2078.9 m
139.3081 -1971.4 2070.5 1972.1 2062.2 1971.6 2055.9 C
139.3082 -1969.9 2053.7 1967.6 2051.7 1965.6 2049.6 C
139.3083 -1961.4 2050.4 1957.6 2053.6 1953.4 2055.2 C
139.3084 -1949.8 2055.6 1948.2 2051.2 1945.5 2049.6 C
139.3085 -1945.1 2048.8 1944.5 2047.9 1943.6 2047.5 C
139.3086 -1940.1 2047.8 1937.3 2051 1934 2052.3 C
139.3087 -1933.7 2052.6 1933.7 2053 1933.2 2053.2 C
139.3088 -1933.7 2060.8 1933.4 2067.2 1933.5 2074.6 C
139.3089 -1933.8 2068.1 1934 2060.9 1933.2 2054 C
139.3090 -1935.3 2050.9 1939.3 2049.6 1942.4 2047.5 C
139.3091 -1942.8 2047.5 1943.4 2047.4 1943.8 2047.7 C
139.3092 -1947.1 2050.2 1950.3 2057.9 1955.3 2054.4 C
139.3093 -1955.4 2054.4 1955.5 2054.3 1955.6 2054.2 C
139.3094 -1955.9 2057.6 1956.1 2061.8 1955.3 2064.8 C
139.3095 -1955.4 2064.3 1955.1 2063.8 1955.6 2063.6 C
139.3096 -1956 2066.6 1955.3 2068.7 1958.7 2069.8 C
139.3097 -1959.2 2071.7 1961.4 2071.7 1962 2074.1 C
139.3098 -1964.4 2074.2 1964 2077.7 1967.3 2078.4 C
139.3099 -1967 2079.7 1968.1 2079.9 1969 2080.1 C
139.3100 -1971.1 2079.9 1970 2079.2 1970.4 2078 C
139.3101 -1969.5 2077.2 1970.3 2075.9 1969.7 2075.1 C
139.3102 -1970.1 2069.8 1970.1 2063.6 1969.7 2058.8 C
139.3103 -1969.2 2058.5 1970 2058.1 1970.2 2057.8 C
139.3104 -1970.4 2058.3 1971.2 2057.7 1971.4 2058.3 C
139.3105 -1971.5 2065.3 1971.2 2073.6 1971.6 2081.1 C
139.3106 -1974.1 2081.4 1969.8 2084.3 1972.4 2082.5 C
139.3107 -1971.9 2081.4 1971.6 2080.2 1971.6 2078.9 C
139.3108 -[0 0.4 1 0] vc
139.3109 -f
139.3110 -S
139.3111 -n
139.3112 -1952.4 2052 m
139.3113 -1954.1 2051.3 1955.6 2050.4 1957.2 2049.6 C
139.3114 -1955.6 2050.4 1954.1 2051.3 1952.4 2052 C
139.3115 -[0 0.87 0.91 0.83] vc
139.3116 -f
139.3117 -S
139.3118 -n
139.3119 -1975.5 2039.8 m
139.3120 -1975.5 2039.4 1974.5 2038.7 1974.8 2038.8 C
139.3121 -1974.6 2039.1 1974.5 2039.1 1974.3 2038.8 C
139.3122 -1974.6 2037.6 1972.5 2039.3 1972.1 2038.4 C
139.3123 -1970.4 2038.4 1970.5 2035.5 1968 2035.7 C
139.3124 -1968.6 2032.5 1964 2033.3 1964 2030.4 C
139.3125 -1961.9 2029.8 1961.4 2026.8 1959.2 2026.8 C
139.3126 -1957.7 2028.5 1952.6 2025.3 1953.9 2029.5 C
139.3127 -1952.9 2031.5 1947 2028.2 1947.9 2032.4 C
139.3128 -1946 2034.2 1941.5 2031.5 1941.9 2035.7 C
139.3129 -1940.6 2036.1 1938.9 2036.1 1937.6 2035.7 C
139.3130 -1937.3 2037.5 1940.7 2038.2 1941.2 2040.3 C
139.3131 -1943.7 2041.1 1944.4 2043.9 1946.4 2045.6 C
139.3132 -1949.1 2046.7 1949.9 2048.8 1952.2 2051.1 C
139.3133 -1959.9 2047.1 1967.7 2043.6 1975.5 2039.8 C
139.3134 -[0 0.01 1 0] vc
139.3135 -f
139.3136 -S
139.3137 -n
139.3138 -vmrs
139.3139 -1962 2047.2 m
139.3140 -1960.2 2047.5 1959.5 2048.9 1957.7 2049.4 C
139.3141 -1959.5 2049.5 1960.3 2047.2 1962 2047.2 C
139.3142 -[0 0.87 0.91 0.83] vc
139.3143 -f
139.3144 -0.4 w
139.3145 -2 J
139.3146 -2 M
139.3147 -S
139.3148 -n
139.3149 -2012.4 2046.3 m
139.3150 -2010.3 2051.3 2008.3 2041.5 2009.8 2047.7 C
139.3151 -2010.5 2047.4 2012.2 2046.5 2012.4 2046.3 C
139.3152 -f
139.3153 -S
139.3154 -n
139.3155 -1944.8 2044.6 m
139.3156 -1945.5 2045.6 1948.6 2048.1 1947.4 2046.8 C
139.3157 -1946.3 2046.5 1945.5 2045.2 1944.8 2044.6 C
139.3158 -f
139.3159 -S
139.3160 -n
139.3161 -1987.2 2054.9 m
139.3162 -1983.7 2057.3 1979.6 2058 1976 2060.2 C
139.3163 -1974.7 2058.2 1977.2 2055.8 1974.3 2054.9 C
139.3164 -1973.1 2052 1970.4 2050.2 1968 2048 C
139.3165 -1968 2047.7 1968 2047.4 1968.3 2047.2 C
139.3166 -1969.5 2046.1 1983 2040.8 1972.4 2044.8 C
139.3167 -1971.2 2046.6 1967.9 2046 1968 2048.2 C
139.3168 -1970.5 2050.7 1973.8 2052.6 1974.3 2055.6 C
139.3169 -1975.1 2055 1975.7 2056.7 1975.7 2057.1 C
139.3170 -1975.7 2058.2 1974.8 2059.3 1975.5 2060.4 C
139.3171 -1979.3 2058.2 1983.9 2057.7 1987.2 2054.9 C
139.3172 -[0.18 0.18 0 0.78] vc
139.3173 -f
139.3174 -S
139.3175 -n
139.3176 -1967.8 2047.5 m
139.3177 -1968.5 2047 1969.1 2046.5 1969.7 2046 C
139.3178 -1969.1 2046.5 1968.5 2047 1967.8 2047.5 C
139.3179 -[0 0.87 0.91 0.83] vc
139.3180 -f
139.3181 -S
139.3182 -n
139.3183 -1976.7 2040.3 m
139.3184 -1976.9 2032.8 1976.3 2024.4 1977.2 2017 C
139.3185 -1976.4 2016.5 1976.6 2014.8 1976.9 2013.9 C
139.3186 -1978.7 2012.7 1977.2 2013 1976.2 2012.9 C
139.3187 -1971.5 2008.1 1965.9 2003.1 1961.8 1998 C
139.3188 -1960.9 1998 1960.1 1998 1959.2 1998 C
139.3189 -1951.5 2001.1 1944.3 2005.5 1937.1 2009.6 C
139.3190 -1935 2012.9 1937 2013.6 1936.1 2017.2 C
139.3191 -1937.1 2017.2 1936 2018 1936.4 2017.7 C
139.3192 -1937 2020.1 1935.5 2022.1 1936.4 2024.9 C
139.3193 -1936.8 2027.2 1936.5 2029.7 1936.6 2032.1 C
139.3194 -1937.4 2028.2 1936 2023.8 1936.8 2020.1 C
139.3195 -1938.3 2015.7 1933.6 2011 1939 2008.6 C
139.3196 -1945.9 2004.5 1953.1 2000.3 1960.6 1998.3 C
139.3197 -1960.9 1998.3 1961.3 1998.3 1961.6 1998.3 C
139.3198 -1966.2 2003.5 1971.8 2008.4 1976.4 2013.6 C
139.3199 -1976.6 2015.5 1976 2018.1 1976.9 2019.2 C
139.3200 -1976.1 2025.8 1976.4 2033.2 1976.7 2040 C
139.3201 -1971.9 2042.4 1967.4 2045 1962.5 2047 C
139.3202 -1967.3 2044.9 1972 2042.6 1976.7 2040.3 C
139.3203 -f
139.3204 -S
139.3205 -n
139.3206 -1939 2038.6 m
139.3207 -1940.6 2040.9 1942.5 2042.1 1944.3 2044.1 C
139.3208 -1942.7 2041.9 1940.6 2040.9 1939 2038.6 C
139.3209 -f
139.3210 -S
139.3211 -n
139.3212 -2006.2 2065.7 m
139.3213 -2006 2057.3 2006.7 2049 2006.2 2042.7 C
139.3214 -2002.1 2038.4 1997.7 2033.4 1993 2030 C
139.3215 -1992.9 2029.3 1992.5 2028.6 1992 2028.3 C
139.3216 -1992.1 2036.6 1991.9 2046.2 1992.3 2054.9 C
139.3217 -1990.8 2056.2 1989 2056.7 1987.5 2058 C
139.3218 -1988.7 2057.7 1990.7 2054.4 1993 2056.4 C
139.3219 -1993.4 2058.8 1996 2058.2 1996.6 2060.9 C
139.3220 -1999 2061 1998.5 2064.5 2001.9 2065.2 C
139.3221 -2001.5 2066.5 2002.7 2066.7 2003.6 2066.9 C
139.3222 -2005.7 2066.7 2004.6 2066 2005 2064.8 C
139.3223 -2004 2064 2004.8 2062.7 2004.3 2061.9 C
139.3224 -2004.6 2056.6 2004.6 2050.4 2004.3 2045.6 C
139.3225 -2003.7 2045.3 2004.6 2044.9 2004.8 2044.6 C
139.3226 -2005 2045.1 2005.7 2044.5 2006 2045.1 C
139.3227 -2006 2052.1 2005.8 2060.4 2006.2 2067.9 C
139.3228 -2008.7 2068.2 2004.4 2071.1 2006.9 2069.3 C
139.3229 -2006.4 2068.2 2006.2 2067 2006.2 2065.7 C
139.3230 -[0 0.4 1 0] vc
139.3231 -f
139.3232 -S
139.3233 -n
139.3234 -2021.8 2041.7 m
139.3235 -2018.3 2044.1 2014.1 2044.8 2010.5 2047 C
139.3236 -2009.3 2045 2011.7 2042.6 2008.8 2041.7 C
139.3237 -2004.3 2035.1 1997.6 2030.9 1993 2024.4 C
139.3238 -1992.1 2024 1991.5 2024.3 1990.8 2024 C
139.3239 -1993.2 2023.9 1995.3 2027.1 1996.8 2029 C
139.3240 -2000.4 2032.6 2004.9 2036.9 2008.4 2040.8 C
139.3241 -2008.2 2043.1 2011.4 2042.8 2009.8 2045.8 C
139.3242 -2009.8 2046.3 2009.7 2046.9 2010 2047.2 C
139.3243 -2013.8 2045 2018.5 2044.5 2021.8 2041.7 C
139.3244 -[0.18 0.18 0 0.78] vc
139.3245 -f
139.3246 -S
139.3247 -n
139.3248 -2001.6 2034 m
139.3249 -2000.7 2033.1 1999.9 2032.3 1999 2031.4 C
139.3250 -1999.9 2032.3 2000.7 2033.1 2001.6 2034 C
139.3251 -[0 0.87 0.91 0.83] vc
139.3252 -f
139.3253 -S
139.3254 -n
139.3255 -vmrs
139.3256 -1989.4 2024.4 m
139.3257 -1989.5 2025.4 1988.6 2024.3 1988.9 2024.7 C
139.3258 -1990.5 2025.8 1990.7 2024.2 1992.8 2024.9 C
139.3259 -1993.8 2025.9 1995 2027.1 1995.9 2028 C
139.3260 -1994.3 2026 1991.9 2023.4 1989.4 2024.4 C
139.3261 -[0 0.87 0.91 0.83] vc
139.3262 -f
139.3263 -0.4 w
139.3264 -2 J
139.3265 -2 M
139.3266 -S
139.3267 -n
139.3268 -1984.8 2019.9 m
139.3269 -1984.6 2018.6 1986.3 2017.2 1987.7 2016.8 C
139.3270 -1987.2 2017.5 1982.9 2017.9 1984.4 2020.6 C
139.3271 -1984.1 2019.9 1984.9 2020 1984.8 2019.9 C
139.3272 -f
139.3273 -S
139.3274 -n
139.3275 -1981.7 2017 m
139.3276 -1979.6 2022 1977.6 2012.3 1979.1 2018.4 C
139.3277 -1979.8 2018.1 1981.5 2017.2 1981.7 2017 C
139.3278 -f
139.3279 -S
139.3280 -n
139.3281 -1884.3 2019.2 m
139.3282 -1884.7 2010.5 1884.5 2000.6 1884.5 1991.8 C
139.3283 -1886.6 1989.3 1889.9 1988.9 1892.4 1987 C
139.3284 -1890.8 1988.7 1886 1989.1 1884.3 1992.3 C
139.3285 -1884.7 2001 1884.5 2011.3 1884.5 2019.9 C
139.3286 -1891 2025.1 1895.7 2031.5 1902 2036.9 C
139.3287 -1896.1 2031 1890 2024.9 1884.3 2019.2 C
139.3288 -[0.07 0.06 0 0.58] vc
139.3289 -f
139.3290 -S
139.3291 -n
139.3292 -1884 2019.4 m
139.3293 -1884.5 2010.6 1884.2 2000.4 1884.3 1991.8 C
139.3294 -1884.8 1990.4 1887.8 1989 1884.8 1990.8 C
139.3295 -1884.3 1991.3 1884.3 1992 1884 1992.5 C
139.3296 -1884.5 2001.2 1884.2 2011.1 1884.3 2019.9 C
139.3297 -1887.9 2023.1 1891.1 2026.4 1894.4 2030 C
139.3298 -1891.7 2026.1 1887.1 2022.9 1884 2019.4 C
139.3299 -[0.4 0.4 0 0] vc
139.3300 -f
139.3301 -S
139.3302 -n
139.3303 -1885 2011.7 m
139.3304 -1885 2006.9 1885 2001.9 1885 1997.1 C
139.3305 -1885 2001.9 1885 2006.9 1885 2011.7 C
139.3306 -[0 0.87 0.91 0.83] vc
139.3307 -f
139.3308 -S
139.3309 -n
139.3310 -1975.5 2036.4 m
139.3311 -1975.2 2028 1976 2019.7 1975.5 2013.4 C
139.3312 -1971.1 2008.5 1965.6 2003.6 1961.6 1999 C
139.3313 -1958.8 1998 1956 2000 1953.6 2001.2 C
139.3314 -1948.2 2004.7 1941.9 2006.5 1937.1 2010.8 C
139.3315 -1937.5 2018.3 1937.3 2024.7 1937.3 2032.1 C
139.3316 -1937.6 2025.6 1937.9 2018.4 1937.1 2011.5 C
139.3317 -1937.3 2011 1937.6 2010.5 1937.8 2010 C
139.3318 -1944.6 2005.7 1951.9 2002.3 1959.2 1999 C
139.3319 -1960.1 1998.5 1960.1 1999.8 1960.4 2000.4 C
139.3320 -1959.7 2006.9 1959.7 2014.2 1959.4 2021.1 C
139.3321 -1959 2021.1 1959.2 2021.9 1959.2 2022.3 C
139.3322 -1959.2 2021.9 1959 2021.3 1959.4 2021.1 C
139.3323 -1959.8 2024.1 1959.2 2026.2 1962.5 2027.3 C
139.3324 -1963 2029.2 1965.3 2029.2 1965.9 2031.6 C
139.3325 -1968.3 2031.8 1967.8 2035.2 1971.2 2036 C
139.3326 -1970.8 2037.2 1971.9 2037.5 1972.8 2037.6 C
139.3327 -1974.9 2037.4 1973.9 2036.7 1974.3 2035.5 C
139.3328 -1973.3 2034.7 1974.1 2033.4 1973.6 2032.6 C
139.3329 -1973.9 2027.3 1973.9 2021.1 1973.6 2016.3 C
139.3330 -1973 2016 1973.9 2015.6 1974 2015.3 C
139.3331 -1974.3 2015.9 1975 2015.3 1975.2 2015.8 C
139.3332 -1975.3 2022.8 1975.1 2031.2 1975.5 2038.6 C
139.3333 -1977.9 2039 1973.7 2041.8 1976.2 2040 C
139.3334 -1975.7 2039 1975.5 2037.8 1975.5 2036.4 C
139.3335 -[0 0.4 1 0] vc
139.3336 -f
139.3337 -S
139.3338 -n
139.3339 -1991.1 2012.4 m
139.3340 -1987.5 2014.8 1983.4 2015.6 1979.8 2017.7 C
139.3341 -1978.5 2015.7 1981 2013.3 1978.1 2012.4 C
139.3342 -1973.6 2005.8 1966.8 2001.6 1962.3 1995.2 C
139.3343 -1961.4 1994.7 1960.8 1995 1960.1 1994.7 C
139.3344 -1962.5 1994.6 1964.6 1997.8 1966.1 1999.7 C
139.3345 -1969.7 2003.3 1974.2 2007.6 1977.6 2011.5 C
139.3346 -1977.5 2013.8 1980.6 2013.5 1979.1 2016.5 C
139.3347 -1979.1 2017 1979 2017.6 1979.3 2018 C
139.3348 -1983.1 2015.7 1987.8 2015.2 1991.1 2012.4 C
139.3349 -[0.18 0.18 0 0.78] vc
139.3350 -f
139.3351 -S
139.3352 -n
139.3353 -1970.9 2004.8 m
139.3354 -1970 2003.9 1969.2 2003 1968.3 2002.1 C
139.3355 -1969.2 2003 1970 2003.9 1970.9 2004.8 C
139.3356 -[0 0.87 0.91 0.83] vc
139.3357 -f
139.3358 -S
139.3359 -n
139.3360 -1887.9 1994.9 m
139.3361 -1888.5 1992.3 1891.4 1992.2 1893.2 1990.8 C
139.3362 -1898.4 1987.5 1904 1984.8 1909.5 1982.2 C
139.3363 -1909.7 1982.7 1910.3 1982.1 1910.4 1982.7 C
139.3364 -1909.5 1990.5 1910.1 1996.4 1910 2004.5 C
139.3365 -1909.1 2003.4 1909.7 2005.8 1909.5 2006.4 C
139.3366 -1910.4 2006 1909.7 2008 1910.2 2007.9 C
139.3367 -1911.3 2010.6 1912.5 2012.6 1915.7 2013.4 C
139.3368 -1915.8 2013.7 1915.5 2014.4 1916 2014.4 C
139.3369 -1916.3 2015 1915.4 2016 1915.2 2016 C
139.3370 -1916.1 2015.5 1916.5 2014.5 1916 2013.6 C
139.3371 -1913.4 2013.3 1913.1 2010.5 1910.9 2009.8 C
139.3372 -1910.7 2008.8 1910.4 2007.9 1910.2 2006.9 C
139.3373 -1911.1 1998.8 1909.4 1990.7 1910.7 1982.4 C
139.3374 -1910 1982.1 1908.9 1982.1 1908.3 1982.4 C
139.3375 -1901.9 1986.1 1895 1988.7 1888.8 1993 C
139.3376 -1888 1993.4 1888.4 1994.3 1887.6 1994.7 C
139.3377 -1888.1 2001.3 1887.8 2008.6 1887.9 2015.1 C
139.3378 -1887.3 2017.5 1887.9 2015.4 1888.4 2014.4 C
139.3379 -1887.8 2008 1888.4 2001.3 1887.9 1994.9 C
139.3380 -[0.07 0.06 0 0.58] vc
139.3381 -f
139.3382 -S
139.3383 -n
139.3384 -vmrs
139.3385 -1887.9 2018.4 m
139.3386 -1887.5 2016.9 1888.5 2016 1888.8 2014.8 C
139.3387 -1890.1 2014.8 1891.1 2016.6 1892.4 2015.3 C
139.3388 -1892.4 2014.4 1893.8 2012.9 1894.4 2012.4 C
139.3389 -1895.9 2012.4 1896.6 2013.9 1897.7 2012.7 C
139.3390 -1898.4 2011.7 1898.6 2010.4 1899.6 2009.8 C
139.3391 -1901.7 2009.9 1902.9 2010.4 1904 2009.1 C
139.3392 -1904.3 2007.4 1904 2007.6 1904.9 2007.2 C
139.3393 -1906.2 2007 1907.6 2006.5 1908.8 2006.7 C
139.3394 -1910.6 2008.2 1909.8 2011.5 1912.6 2012 C
139.3395 -1912.4 2013 1913.8 2012.7 1914 2013.2 C
139.3396 -1911.5 2011.1 1909.1 2007.9 1909.2 2004.3 C
139.3397 -1909.5 2003.5 1909.9 2004.9 1909.7 2004.3 C
139.3398 -1909.9 1996.2 1909.3 1990.5 1910.2 1982.7 C
139.3399 -1909.5 1982.6 1909.5 1982.6 1908.8 1982.7 C
139.3400 -1903.1 1985.7 1897 1987.9 1891.7 1992 C
139.3401 -1890.5 1993 1888.2 1992.9 1888.1 1994.9 C
139.3402 -1888.7 2001.4 1888.1 2008.4 1888.6 2014.8 C
139.3403 -1888.3 2016 1887.2 2016.9 1887.6 2018.4 C
139.3404 -1892.3 2023.9 1897.6 2027.9 1902.3 2033.3 C
139.3405 -1898 2028.2 1892.1 2023.8 1887.9 2018.4 C
139.3406 -[0.4 0.4 0 0] vc
139.3407 -f
139.3408 -0.4 w
139.3409 -2 J
139.3410 -2 M
139.3411 -S
139.3412 -n
139.3413 -1910.9 1995.2 m
139.3414 -1910.4 1999.8 1911 2003.3 1910.9 2008.1 C
139.3415 -1910.9 2003.8 1910.9 1999.2 1910.9 1995.2 C
139.3416 -[0.18 0.18 0 0.78] vc
139.3417 -f
139.3418 -S
139.3419 -n
139.3420 -1911.2 2004.3 m
139.3421 -1911.2 2001.9 1911.2 1999.7 1911.2 1997.3 C
139.3422 -1911.2 1999.7 1911.2 2001.9 1911.2 2004.3 C
139.3423 -[0 0.87 0.91 0.83] vc
139.3424 -f
139.3425 -S
139.3426 -n
139.3427 -1958.7 1995.2 m
139.3428 -1959 1995.6 1956.2 1995 1956.5 1996.8 C
139.3429 -1955.8 1997.6 1954.2 1998.5 1953.6 1997.3 C
139.3430 -1953.6 1990.8 1954.9 1989.6 1953.4 1983.9 C
139.3431 -1953.4 1983.3 1953.3 1982.1 1954.4 1982 C
139.3432 -1955.5 1982.6 1956.5 1981.3 1957.5 1981 C
139.3433 -1956.3 1981.8 1954.7 1982.6 1953.9 1981.5 C
139.3434 -1951.4 1983 1954.7 1988.8 1952.9 1990.6 C
139.3435 -1953.8 1990.6 1953.2 1992.7 1953.4 1993.7 C
139.3436 -1953.8 1994.5 1952.3 1996.1 1953.2 1997.8 C
139.3437 -1956.3 1999.4 1957.5 1994 1959.9 1995.6 C
139.3438 -1962 1994.4 1963.7 1997.7 1965.2 1998.8 C
139.3439 -1963.5 1996.7 1961.2 1994.1 1958.7 1995.2 C
139.3440 -f
139.3441 -S
139.3442 -n
139.3443 -1945 2000.7 m
139.3444 -1945.4 1998.7 1945.4 1997.9 1945 1995.9 C
139.3445 -1944.5 1995.3 1944.2 1992.6 1945.7 1993.2 C
139.3446 -1946 1992.2 1948.7 1992.5 1948.4 1990.6 C
139.3447 -1947.5 1990.3 1948.1 1988.7 1947.9 1988.2 C
139.3448 -1948.9 1987.8 1950.5 1986.8 1950.5 1984.6 C
139.3449 -1951.5 1980.9 1946.7 1983 1947.2 1979.8 C
139.3450 -1944.5 1979.9 1945.2 1976.6 1943.1 1976.7 C
139.3451 -1941.8 1975.7 1942.1 1972.7 1939.2 1973.8 C
139.3452 -1938.2 1974.6 1939.3 1971.6 1938.3 1970.9 C
139.3453 -1938.8 1969.2 1933.4 1970.3 1937.3 1970 C
139.3454 -1939.4 1971.2 1937.2 1973 1937.6 1974.3 C
139.3455 -1937.2 1976.3 1937.1 1981.2 1937.8 1984.1 C
139.3456 -1938.8 1982.3 1937.9 1976.6 1938.5 1973.1 C
139.3457 -1938.9 1975 1938.5 1976.4 1939.7 1977.2 C
139.3458 -1939.5 1983.5 1938.9 1991.3 1940.2 1997.3 C
139.3459 -1939.4 1999.1 1938.6 1997.1 1937.8 1997.1 C
139.3460 -1937.4 1996.7 1937.6 1996.1 1937.6 1995.6 C
139.3461 -1936.5 1998.5 1940.1 1998.4 1940.9 2000.7 C
139.3462 -1942.1 2000.4 1943.2 2001.3 1943.1 2002.4 C
139.3463 -1943.6 2003.1 1941.1 2004.6 1942.8 2003.8 C
139.3464 -1943.9 2002.5 1942.6 2000.6 1945 2000.7 C
139.3465 -[0.65 0.65 0 0.42] vc
139.3466 -f
139.3467 -S
139.3468 -n
139.3469 -1914.5 2006.4 m
139.3470 -1914.1 2004.9 1915.2 2004 1915.5 2002.8 C
139.3471 -1916.7 2002.8 1917.8 2004.6 1919.1 2003.3 C
139.3472 -1919 2002.4 1920.4 2000.9 1921 2000.4 C
139.3473 -1922.5 2000.4 1923.2 2001.9 1924.4 2000.7 C
139.3474 -1925 1999.7 1925.3 1998.4 1926.3 1997.8 C
139.3475 -1928.4 1997.9 1929.5 1998.4 1930.6 1997.1 C
139.3476 -1930.9 1995.4 1930.7 1995.6 1931.6 1995.2 C
139.3477 -1932.8 1995 1934.3 1994.5 1935.4 1994.7 C
139.3478 -1936.1 1995.8 1936.9 1996.2 1936.6 1997.8 C
139.3479 -1938.9 1999.4 1939.7 2001.3 1942.4 2002.4 C
139.3480 -1942.4 2002.5 1942.2 2003 1942.6 2002.8 C
139.3481 -1942.9 2000.4 1939.2 2001.8 1939.2 1999.7 C
139.3482 -1936.2 1998.6 1937 1995.3 1935.9 1993.5 C
139.3483 -1937.1 1986.5 1935.2 1977.9 1937.6 1971.2 C
139.3484 -1937.6 1970.3 1936.6 1971 1936.4 1970.4 C
139.3485 -1930.2 1973.4 1924 1976 1918.4 1980 C
139.3486 -1917.2 1981 1914.9 1980.9 1914.8 1982.9 C
139.3487 -1915.3 1989.4 1914.7 1996.4 1915.2 2002.8 C
139.3488 -1914.9 2004 1913.9 2004.9 1914.3 2006.4 C
139.3489 -1919 2011.9 1924.2 2015.9 1928.9 2021.3 C
139.3490 -1924.6 2016.2 1918.7 2011.8 1914.5 2006.4 C
139.3491 -[0.4 0.4 0 0] vc
139.3492 -f
139.3493 -S
139.3494 -n
139.3495 -1914.5 1982.9 m
139.3496 -1915.1 1980.3 1918 1980.2 1919.8 1978.8 C
139.3497 -1925 1975.5 1930.6 1972.8 1936.1 1970.2 C
139.3498 -1939.4 1970.6 1936.1 1974.2 1936.6 1976.4 C
139.3499 -1936.5 1981.9 1936.8 1987.5 1936.4 1992.8 C
139.3500 -1935.9 1992.8 1936.2 1993.5 1936.1 1994 C
139.3501 -1937.1 1993.6 1936.2 1995.9 1936.8 1995.9 C
139.3502 -1937 1998 1939.5 1999.7 1940.4 2000.7 C
139.3503 -1940.1 1998.6 1935 1997.2 1937.6 1993.7 C
139.3504 -1938.3 1985.7 1935.9 1976.8 1937.8 1970.7 C
139.3505 -1936.9 1969.8 1935.4 1970.3 1934.4 1970.7 C
139.3506 -1928.3 1974.4 1921.4 1976.7 1915.5 1981 C
139.3507 -1914.6 1981.4 1915.1 1982.3 1914.3 1982.7 C
139.3508 -1914.7 1989.3 1914.5 1996.6 1914.5 2003.1 C
139.3509 -1913.9 2005.5 1914.5 2003.4 1915 2002.4 C
139.3510 -1914.5 1996 1915.1 1989.3 1914.5 1982.9 C
139.3511 -[0.07 0.06 0 0.58] vc
139.3512 -f
139.3513 -S
139.3514 -n
139.3515 -1939.2 1994.9 m
139.3516 -1939.3 1995 1939.4 1995.1 1939.5 1995.2 C
139.3517 -1939.1 1989 1939.3 1981.6 1939 1976.7 C
139.3518 -1938.6 1976.3 1938.6 1974.6 1938.5 1973.3 C
139.3519 -1938.7 1976.1 1938.1 1979.4 1939 1981.7 C
139.3520 -1937.3 1986 1937.7 1991.6 1938 1996.4 C
139.3521 -1937.3 1994.3 1939.6 1996.2 1939.2 1994.9 C
139.3522 -[0.18 0.18 0 0.78] vc
139.3523 -f
139.3524 -S
139.3525 -n
139.3526 -1938.3 1988.4 m
139.3527 -1938.5 1990.5 1937.9 1994.1 1938.8 1994.7 C
139.3528 -1937.9 1992.6 1939 1990.6 1938.3 1988.4 C
139.3529 -[0 0.87 0.91 0.83] vc
139.3530 -f
139.3531 -S
139.3532 -n
139.3533 -1938.8 1985.8 m
139.3534 -1938.5 1985.9 1938.4 1985.7 1938.3 1985.6 C
139.3535 -1938.4 1986.2 1938 1989.5 1938.8 1987.2 C
139.3536 -1938.8 1986.8 1938.8 1986.3 1938.8 1985.8 C
139.3537 -f
139.3538 -S
139.3539 -n
139.3540 -vmrs
139.3541 -1972.8 2062.1 m
139.3542 -1971.9 2061 1972.5 2059.4 1972.4 2058 C
139.3543 -1972.2 2063.8 1971.9 2073.7 1972.4 2081.3 C
139.3544 -1972.5 2074.9 1971.9 2067.9 1972.8 2062.1 C
139.3545 -[0 1 1 0.36] vc
139.3546 -f
139.3547 -0.4 w
139.3548 -2 J
139.3549 -2 M
139.3550 -S
139.3551 -n
139.3552 -1940.2 2071.7 m
139.3553 -1941.3 2072 1943.1 2072.3 1944 2071.5 C
139.3554 -1943.6 2069.9 1945.2 2069.1 1946 2068.8 C
139.3555 -1950 2071.1 1948.7 2065.9 1951.7 2066.2 C
139.3556 -1953.5 2063.9 1956.9 2069.4 1955.6 2063.8 C
139.3557 -1955.5 2064.2 1955.7 2064.8 1955.3 2065 C
139.3558 -1954.3 2063.7 1956.2 2063.6 1955.6 2062.1 C
139.3559 -1954.5 2060 1958.3 2050.3 1952.2 2055.6 C
139.3560 -1949.1 2053.8 1946 2051 1943.8 2048 C
139.3561 -1940.3 2048 1937.5 2051.3 1934.2 2052.5 C
139.3562 -1933.1 2054.6 1934.4 2057.3 1934 2060 C
139.3563 -1934 2065.1 1934 2069.7 1934 2074.6 C
139.3564 -1934.4 2069 1934.1 2061.5 1934.2 2054.9 C
139.3565 -1934.6 2054.5 1935.3 2054.7 1935.9 2054.7 C
139.3566 -1937 2055.3 1935.9 2056.1 1935.9 2056.8 C
139.3567 -1936.5 2063 1935.6 2070.5 1935.9 2074.6 C
139.3568 -1936.7 2074.4 1937.3 2075.2 1938 2074.6 C
139.3569 -1937.9 2073.6 1939.1 2072.1 1940.2 2071.7 C
139.3570 -[0 0.2 1 0] vc
139.3571 -f
139.3572 -S
139.3573 -n
139.3574 -1933.2 2074.1 m
139.3575 -1933.2 2071.5 1933.2 2069 1933.2 2066.4 C
139.3576 -1933.2 2069 1933.2 2071.5 1933.2 2074.1 C
139.3577 -[0 1 1 0.36] vc
139.3578 -f
139.3579 -S
139.3580 -n
139.3581 -2007.4 2048.9 m
139.3582 -2006.5 2047.8 2007.1 2046.2 2006.9 2044.8 C
139.3583 -2006.7 2050.6 2006.5 2060.5 2006.9 2068.1 C
139.3584 -2007.1 2061.7 2006.5 2054.7 2007.4 2048.9 C
139.3585 -f
139.3586 -S
139.3587 -n
139.3588 -1927.2 2062.4 m
139.3589 -1925.8 2060.1 1928.1 2058.2 1927 2056.4 C
139.3590 -1927.3 2055.5 1926.5 2053.5 1926.8 2051.8 C
139.3591 -1926.8 2052.8 1926 2052.5 1925.3 2052.5 C
139.3592 -1924.1 2052.8 1925 2050.5 1924.4 2050.1 C
139.3593 -1925.3 2050.2 1925.4 2048.8 1926.3 2049.4 C
139.3594 -1926.5 2052.3 1928.4 2047.2 1928.4 2051.1 C
139.3595 -1928.9 2050.5 1929 2051.4 1928.9 2051.8 C
139.3596 -1928.9 2052 1928.9 2052.3 1928.9 2052.5 C
139.3597 -1929.4 2051.4 1928.9 2049 1930.1 2048.2 C
139.3598 -1928.9 2047.1 1930.5 2047.1 1930.4 2046.5 C
139.3599 -1931.9 2046.2 1933.1 2046.1 1934.7 2046.5 C
139.3600 -1934.6 2046.9 1935.2 2047.9 1934.4 2048.4 C
139.3601 -1936.9 2048.1 1933.6 2043.8 1935.9 2043.9 C
139.3602 -1935.7 2043.9 1934.8 2041.3 1933.2 2041.7 C
139.3603 -1932.5 2041.6 1932.4 2039.6 1932.3 2041 C
139.3604 -1930.8 2042.6 1929 2040.6 1927.7 2042 C
139.3605 -1927.5 2041.4 1927.1 2040.9 1927.2 2040.3 C
139.3606 -1927.8 2040.6 1927.4 2039.1 1928.2 2038.6 C
139.3607 -1929.4 2038 1930.5 2038.8 1931.3 2037.9 C
139.3608 -1931.7 2039 1932.5 2038.6 1931.8 2037.6 C
139.3609 -1930.9 2037 1928.7 2037.8 1928.2 2037.9 C
139.3610 -1926.7 2037.8 1928 2039 1927 2038.8 C
139.3611 -1927.4 2040.4 1925.6 2040.8 1925.1 2041 C
139.3612 -1924.3 2040.4 1923.2 2040.5 1922.2 2040.5 C
139.3613 -1921.4 2041.7 1921 2043.9 1919.3 2043.9 C
139.3614 -1918.8 2043.4 1917.2 2043.3 1916.4 2043.4 C
139.3615 -1915.9 2044.4 1915.7 2046 1914.3 2046.5 C
139.3616 -1913.1 2046.6 1912 2044.5 1911.4 2046.3 C
139.3617 -1912.8 2046.5 1913.8 2047.4 1915.7 2047 C
139.3618 -1916.9 2047.7 1915.6 2048.8 1916 2049.4 C
139.3619 -1915.4 2049.3 1913.9 2050.3 1913.3 2051.1 C
139.3620 -1913.9 2054.1 1916 2050.2 1916.7 2053 C
139.3621 -1916.9 2053.8 1915.5 2054.1 1916.7 2054.4 C
139.3622 -1917 2054.7 1920.2 2054.3 1919.3 2056.6 C
139.3623 -1918.8 2056.1 1920.2 2058.6 1920.3 2057.6 C
139.3624 -1921.2 2057.9 1922.1 2057.5 1922.4 2059 C
139.3625 -1922.3 2059.1 1922.2 2059.3 1922 2059.2 C
139.3626 -1922.1 2059.7 1922.4 2060.3 1922.9 2060.7 C
139.3627 -1923.2 2060.1 1923.8 2060.4 1924.6 2060.7 C
139.3628 -1925.9 2062.6 1923.2 2062 1925.6 2063.6 C
139.3629 -1926.1 2063.1 1927.3 2062.5 1927.2 2062.4 C
139.3630 -[0.21 0.21 0 0] vc
139.3631 -f
139.3632 -S
139.3633 -n
139.3634 -1933.2 2063.3 m
139.3635 -1933.2 2060.7 1933.2 2058.2 1933.2 2055.6 C
139.3636 -1933.2 2058.2 1933.2 2060.7 1933.2 2063.3 C
139.3637 -[0 1 1 0.36] vc
139.3638 -f
139.3639 -S
139.3640 -n
139.3641 -1965.2 2049.2 m
139.3642 -1967.1 2050.1 1969.9 2053.7 1972.1 2056.4 C
139.3643 -1970.5 2054 1967.6 2051.3 1965.2 2049.2 C
139.3644 -f
139.3645 -S
139.3646 -n
139.3647 -1991.8 2034.8 m
139.3648 -1991.7 2041.5 1992 2048.5 1991.6 2055.2 C
139.3649 -1990.5 2056.4 1991.9 2054.9 1991.8 2054.4 C
139.3650 -1991.8 2047.9 1991.8 2041.3 1991.8 2034.8 C
139.3651 -f
139.3652 -S
139.3653 -n
139.3654 -1988.9 2053.2 m
139.3655 -1988.9 2044.3 1988.9 2036.6 1988.9 2028.3 C
139.3656 -1985.7 2028.2 1987.2 2023.5 1983.9 2024.2 C
139.3657 -1983.9 2022.4 1982 2021.6 1981 2021.3 C
139.3658 -1980.6 2021.1 1980.6 2021.7 1980.3 2021.6 C
139.3659 -1980.3 2027 1980.3 2034.8 1980.3 2041.5 C
139.3660 -1979.3 2043.2 1977.6 2043 1976.2 2043.6 C
139.3661 -1977.1 2043.8 1978.5 2043.2 1978.8 2044.1 C
139.3662 -1978.5 2045.3 1979.9 2045.3 1980.3 2045.8 C
139.3663 -1980.5 2046.8 1980.7 2046.2 1981.5 2046.5 C
139.3664 -1982.4 2047.1 1982 2048.6 1982.7 2049.4 C
139.3665 -1984.2 2049.6 1984.6 2052.2 1986.8 2051.6 C
139.3666 -1987.1 2048.6 1985.1 2042.7 1986.5 2040.5 C
139.3667 -1986.3 2036.7 1986.9 2031.7 1986 2029.2 C
139.3668 -1986.3 2027.1 1986.9 2028.6 1987.7 2027.6 C
139.3669 -1987.7 2028.3 1988.7 2028 1988.7 2028.8 C
139.3670 -1988.1 2033 1988.7 2037.5 1988.2 2041.7 C
139.3671 -1987.8 2041.4 1988 2040.8 1988 2040.3 C
139.3672 -1988 2041 1988 2042.4 1988 2042.4 C
139.3673 -1988 2042.4 1988.1 2042.3 1988.2 2042.2 C
139.3674 -1989.3 2046 1988 2050.2 1988.4 2054 C
139.3675 -1987.8 2054.4 1987.1 2054.7 1986.5 2055.4 C
139.3676 -1987.4 2054.4 1988.4 2054.6 1988.9 2053.2 C
139.3677 -[0 1 1 0.23] vc
139.3678 -f
139.3679 -S
139.3680 -n
139.3681 -1950.8 2054.4 m
139.3682 -1949.7 2053.4 1948.7 2052.3 1947.6 2051.3 C
139.3683 -1948.7 2052.3 1949.7 2053.4 1950.8 2054.4 C
139.3684 -[0 1 1 0.36] vc
139.3685 -f
139.3686 -S
139.3687 -n
139.3688 -vmrs
139.3689 -2006.7 2043.2 m
139.3690 -2004.5 2040.8 2002.4 2038.4 2000.2 2036 C
139.3691 -2002.4 2038.4 2004.5 2040.8 2006.7 2043.2 C
139.3692 -[0 1 1 0.36] vc
139.3693 -f
139.3694 -0.4 w
139.3695 -2 J
139.3696 -2 M
139.3697 -S
139.3698 -n
139.3699 -1976.7 2019.6 m
139.3700 -1975.8 2018.6 1976.4 2016.9 1976.2 2015.6 C
139.3701 -1976 2021.3 1975.8 2031.2 1976.2 2038.8 C
139.3702 -1976.4 2032.4 1975.8 2025.5 1976.7 2019.6 C
139.3703 -f
139.3704 -S
139.3705 -n
139.3706 -1988.4 2053.5 m
139.3707 -1988.6 2049.2 1988.1 2042.8 1988 2040 C
139.3708 -1988.4 2040.4 1988.1 2041 1988.2 2041.5 C
139.3709 -1988.3 2037.2 1988 2032.7 1988.4 2028.5 C
139.3710 -1987.6 2027.1 1987.2 2028.6 1986.8 2028 C
139.3711 -1985.9 2028.5 1986.5 2029.7 1986.3 2030.4 C
139.3712 -1986.9 2029.8 1986.6 2031 1987 2031.2 C
139.3713 -1987.4 2039.6 1985 2043 1987.2 2050.4 C
139.3714 -1987.2 2051.6 1985.9 2052.3 1984.6 2051.3 C
139.3715 -1981.9 2049.7 1982.9 2047 1980.3 2046.5 C
139.3716 -1980.3 2045.2 1978.1 2046.2 1978.6 2043.9 C
139.3717 -1975.6 2043.3 1979.3 2045.6 1979.6 2046.5 C
139.3718 -1980.8 2046.6 1981.5 2048.5 1982.2 2049.9 C
139.3719 -1983.7 2050.8 1984.8 2052.8 1986.5 2053 C
139.3720 -1986.7 2053.5 1987.5 2054.1 1987 2054.7 C
139.3721 -1987.4 2053.9 1988.3 2054.3 1988.4 2053.5 C
139.3722 -[0 1 1 0.23] vc
139.3723 -f
139.3724 -S
139.3725 -n
139.3726 -1988 2038.1 m
139.3727 -1988 2036.7 1988 2035.4 1988 2034 C
139.3728 -1988 2035.4 1988 2036.7 1988 2038.1 C
139.3729 -[0 1 1 0.36] vc
139.3730 -f
139.3731 -S
139.3732 -n
139.3733 -1999.7 2035.7 m
139.3734 -1997.6 2033.5 1995.4 2031.2 1993.2 2029 C
139.3735 -1995.4 2031.2 1997.6 2033.5 1999.7 2035.7 C
139.3736 -f
139.3737 -S
139.3738 -n
139.3739 -1944 2029.2 m
139.3740 -1945.2 2029.5 1946.9 2029.8 1947.9 2029 C
139.3741 -1947.4 2027.4 1949 2026.7 1949.8 2026.4 C
139.3742 -1953.9 2028.6 1952.6 2023.4 1955.6 2023.7 C
139.3743 -1957.4 2021.4 1960.7 2027 1959.4 2021.3 C
139.3744 -1959.3 2021.7 1959.6 2022.3 1959.2 2022.5 C
139.3745 -1958.1 2021.2 1960.1 2021.1 1959.4 2019.6 C
139.3746 -1959.1 2012.7 1959.9 2005.1 1959.6 1999.2 C
139.3747 -1955.3 2000.1 1951.3 2003.1 1947.2 2005 C
139.3748 -1943.9 2006 1941.2 2008.7 1938 2010 C
139.3749 -1936.9 2012.1 1938.2 2014.8 1937.8 2017.5 C
139.3750 -1937.8 2022.6 1937.8 2027.3 1937.8 2032.1 C
139.3751 -1938.2 2026.5 1938 2019 1938 2012.4 C
139.3752 -1938.5 2012 1939.2 2012.3 1939.7 2012.2 C
139.3753 -1940.8 2012.8 1939.7 2013.6 1939.7 2014.4 C
139.3754 -1940.4 2020.5 1939.4 2028 1939.7 2032.1 C
139.3755 -1940.6 2031.9 1941.2 2032.7 1941.9 2032.1 C
139.3756 -1941.7 2031.2 1943 2029.7 1944 2029.2 C
139.3757 -[0 0.2 1 0] vc
139.3758 -f
139.3759 -S
139.3760 -n
139.3761 -1937.1 2031.6 m
139.3762 -1937.1 2029.1 1937.1 2026.5 1937.1 2024 C
139.3763 -1937.1 2026.5 1937.1 2029.1 1937.1 2031.6 C
139.3764 -[0 1 1 0.36] vc
139.3765 -f
139.3766 -S
139.3767 -n
139.3768 -1991.8 2028 m
139.3769 -1992.5 2027.8 1993.2 2029.9 1994 2030.2 C
139.3770 -1992.9 2029.6 1993.1 2028.1 1991.8 2028 C
139.3771 -[0 1 1 0.23] vc
139.3772 -f
139.3773 -S
139.3774 -n
139.3775 -1991.8 2027.8 m
139.3776 -1992.4 2027.6 1992.6 2028.3 1993 2028.5 C
139.3777 -1992.6 2028.2 1992.2 2027.6 1991.6 2027.8 C
139.3778 -1991.6 2028.5 1991.6 2029.1 1991.6 2029.7 C
139.3779 -1991.6 2029.1 1991.4 2028.3 1991.8 2027.8 C
139.3780 -[0 1 1 0.36] vc
139.3781 -f
139.3782 -S
139.3783 -n
139.3784 -1985.8 2025.4 m
139.3785 -1985.3 2025.2 1984.8 2024.7 1984.1 2024.9 C
139.3786 -1983.3 2025.3 1983.6 2027.3 1983.9 2027.6 C
139.3787 -1985 2028 1986.9 2026.9 1985.8 2025.4 C
139.3788 -[0 1 1 0.23] vc
139.3789 -f
139.3790 -S
139.3791 -n
139.3792 -vmrs
139.3793 -1993.5 2024.4 m
139.3794 -1992.4 2023.7 1991.3 2022.9 1990.1 2023.2 C
139.3795 -1990.7 2023.7 1989.8 2023.8 1989.4 2023.7 C
139.3796 -1989.1 2023.7 1988.6 2023.9 1988.4 2023.5 C
139.3797 -1988.5 2023.2 1988.3 2022.7 1988.7 2022.5 C
139.3798 -1989 2022.6 1988.9 2023 1988.9 2023.2 C
139.3799 -1989.1 2022.8 1990.4 2022.3 1990.6 2021.3 C
139.3800 -1990.4 2021.8 1990 2021.3 1990.1 2021.1 C
139.3801 -1990.1 2020.9 1990.1 2020.1 1990.1 2020.6 C
139.3802 -1989.9 2021.1 1989.5 2020.6 1989.6 2020.4 C
139.3803 -1989.6 2019.8 1988.7 2019.6 1988.2 2019.2 C
139.3804 -1987.5 2018.7 1987.7 2020.2 1987 2019.4 C
139.3805 -1987.5 2020.4 1986 2021.1 1987.5 2021.8 C
139.3806 -1986.8 2023.1 1986.6 2021.1 1986 2021.1 C
139.3807 -1986.1 2020.1 1985.9 2019 1986.3 2018.2 C
139.3808 -1986.7 2018.4 1986.5 2019 1986.5 2019.4 C
139.3809 -1986.5 2018.7 1986.4 2017.8 1987.2 2017.7 C
139.3810 -1986.5 2017.2 1985.5 2019.3 1985.3 2020.4 C
139.3811 -1986.2 2022 1987.3 2023.5 1989.2 2024.2 C
139.3812 -1990.8 2024.3 1991.6 2022.9 1993.2 2024.4 C
139.3813 -1993.8 2025.4 1995 2026.6 1995.9 2027.1 C
139.3814 -1995 2026.5 1994.1 2025.5 1993.5 2024.4 C
139.3815 -[0 1 1 0.36] vc
139.3816 -f
139.3817 -0.4 w
139.3818 -2 J
139.3819 -2 M
139.3820 -[0 0.5 0.5 0.2] vc
139.3821 -S
139.3822 -n
139.3823 -2023 2040.3 m
139.3824 -2023.2 2036 2022.7 2029.6 2022.5 2026.8 C
139.3825 -2022.9 2027.2 2022.7 2027.8 2022.8 2028.3 C
139.3826 -2022.8 2024 2022.6 2019.5 2023 2015.3 C
139.3827 -2022.2 2013.9 2021.7 2015.4 2021.3 2014.8 C
139.3828 -2020.4 2015.3 2021 2016.5 2020.8 2017.2 C
139.3829 -2021.4 2016.6 2021.1 2017.8 2021.6 2018 C
139.3830 -2022 2026.4 2019.6 2029.8 2021.8 2037.2 C
139.3831 -2021.7 2038.4 2020.5 2039.1 2019.2 2038.1 C
139.3832 -2016.5 2036.5 2017.5 2033.8 2014.8 2033.3 C
139.3833 -2014.9 2032 2012.6 2033 2013.2 2030.7 C
139.3834 -2011.9 2030.8 2011.2 2030.1 2010.8 2029.2 C
139.3835 -2010.8 2029.1 2010.8 2028.2 2010.8 2028.8 C
139.3836 -2010 2028.8 2010.4 2026.5 2008.6 2027.3 C
139.3837 -2007.9 2026.6 2007.3 2025.9 2007.9 2027.1 C
139.3838 -2009.7 2028 2010 2030.1 2012.2 2030.9 C
139.3839 -2012.9 2032.1 2013.7 2033.6 2015.1 2033.6 C
139.3840 -2015.7 2035.1 2016.9 2036.7 2018.4 2038.4 C
139.3841 -2019.8 2039.3 2022 2039.4 2021.6 2041.5 C
139.3842 -2021.9 2040.7 2022.9 2041.1 2023 2040.3 C
139.3843 -[0 1 1 0.23] vc
139.3844 -f
139.3845 -S
139.3846 -n
139.3847 -2022.5 2024.9 m
139.3848 -2022.5 2023.5 2022.5 2022.2 2022.5 2020.8 C
139.3849 -2022.5 2022.2 2022.5 2023.5 2022.5 2024.9 C
139.3850 -[0 1 1 0.36] vc
139.3851 -f
139.3852 -S
139.3853 -n
139.3854 -1983.2 2022.8 m
139.3855 -1982.4 2022.5 1982.1 2021.6 1981.2 2022.3 C
139.3856 -1981.1 2022.9 1980.5 2024 1981 2024.2 C
139.3857 -1981.8 2024.6 1982.9 2024.4 1983.2 2022.8 C
139.3858 -[0 1 1 0.23] vc
139.3859 -f
139.3860 -S
139.3861 -n
139.3862 -1931.1 2019.9 m
139.3863 -1929.6 2017.7 1932 2015.7 1930.8 2013.9 C
139.3864 -1931.1 2013 1930.3 2011 1930.6 2009.3 C
139.3865 -1930.6 2010.3 1929.8 2010 1929.2 2010 C
139.3866 -1928 2010.3 1928.8 2008.1 1928.2 2007.6 C
139.3867 -1929.1 2007.8 1929.3 2006.3 1930.1 2006.9 C
139.3868 -1930.3 2009.8 1932.2 2004.8 1932.3 2008.6 C
139.3869 -1932.7 2008 1932.8 2009 1932.8 2009.3 C
139.3870 -1932.8 2009.6 1932.8 2009.8 1932.8 2010 C
139.3871 -1933.2 2009 1932.7 2006.6 1934 2005.7 C
139.3872 -1932.7 2004.6 1934.3 2004.6 1934.2 2004 C
139.3873 -1935.8 2003.7 1937 2003.6 1938.5 2004 C
139.3874 -1938.5 2004.5 1939.1 2005.4 1938.3 2006 C
139.3875 -1940.7 2005.7 1937.4 2001.3 1939.7 2001.4 C
139.3876 -1939.5 2001.4 1938.6 1998.8 1937.1 1999.2 C
139.3877 -1936.3 1999.1 1936.2 1997.1 1936.1 1998.5 C
139.3878 -1934.7 2000.1 1932.9 1998.2 1931.6 1999.5 C
139.3879 -1931.3 1998.9 1930.9 1998.5 1931.1 1997.8 C
139.3880 -1931.6 1998.2 1931.3 1996.6 1932 1996.1 C
139.3881 -1933.2 1995.5 1934.3 1996.4 1935.2 1995.4 C
139.3882 -1935.5 1996.5 1936.3 1996.1 1935.6 1995.2 C
139.3883 -1934.7 1994.5 1932.5 1995.3 1932 1995.4 C
139.3884 -1930.5 1995.3 1931.9 1996.5 1930.8 1996.4 C
139.3885 -1931.2 1997.9 1929.5 1998.3 1928.9 1998.5 C
139.3886 -1928.1 1997.9 1927.1 1998 1926 1998 C
139.3887 -1925.3 1999.2 1924.8 2001.4 1923.2 2001.4 C
139.3888 -1922.6 2000.9 1921 2000.9 1920.3 2000.9 C
139.3889 -1919.7 2001.9 1919.6 2003.5 1918.1 2004 C
139.3890 -1916.9 2004.1 1915.8 2002 1915.2 2003.8 C
139.3891 -1916.7 2004 1917.6 2004.9 1919.6 2004.5 C
139.3892 -1920.7 2005.2 1919.4 2006.3 1919.8 2006.9 C
139.3893 -1919.2 2006.9 1917.7 2007.8 1917.2 2008.6 C
139.3894 -1917.8 2011.6 1919.8 2007.8 1920.5 2010.5 C
139.3895 -1920.8 2011.3 1919.3 2011.6 1920.5 2012 C
139.3896 -1920.8 2012.3 1924 2011.8 1923.2 2014.1 C
139.3897 -1922.6 2013.6 1924.1 2016.1 1924.1 2015.1 C
139.3898 -1925.1 2015.4 1925.9 2015 1926.3 2016.5 C
139.3899 -1926.2 2016.6 1926 2016.8 1925.8 2016.8 C
139.3900 -1925.9 2017.2 1926.2 2017.8 1926.8 2018.2 C
139.3901 -1927.1 2017.6 1927.7 2018 1928.4 2018.2 C
139.3902 -1929.7 2020.1 1927.1 2019.5 1929.4 2021.1 C
139.3903 -1929.9 2020.7 1931.1 2020 1931.1 2019.9 C
139.3904 -[0.21 0.21 0 0] vc
139.3905 -f
139.3906 -S
139.3907 -n
139.3908 -1937.1 2020.8 m
139.3909 -1937.1 2018.3 1937.1 2015.7 1937.1 2013.2 C
139.3910 -1937.1 2015.7 1937.1 2018.3 1937.1 2020.8 C
139.3911 -[0 1 1 0.36] vc
139.3912 -f
139.3913 -S
139.3914 -n
139.3915 -2020.4 2012.2 m
139.3916 -2019.8 2012 2019.3 2011.5 2018.7 2011.7 C
139.3917 -2017.9 2012.1 2018.1 2014.1 2018.4 2014.4 C
139.3918 -2019.6 2014.8 2021.4 2013.7 2020.4 2012.2 C
139.3919 -[0 1 1 0.23] vc
139.3920 -f
139.3921 -S
139.3922 -n
139.3923 -1976 2013.9 m
139.3924 -1973.8 2011.5 1971.6 2009.1 1969.5 2006.7 C
139.3925 -1971.6 2009.1 1973.8 2011.5 1976 2013.9 C
139.3926 -[0 1 1 0.36] vc
139.3927 -f
139.3928 -S
139.3929 -n
139.3930 -1995.4 2012.7 m
139.3931 -1996.1 2010.3 1993.8 2006.2 1997.3 2005.7 C
139.3932 -1998.9 2005.4 2000 2003.7 2001.4 2003.1 C
139.3933 -2003.9 2003.1 2005.3 2001.3 2006.9 1999.7 C
139.3934 -2004.5 2003.5 2000 2002.2 1997.6 2005.7 C
139.3935 -1996.5 2005.9 1994.8 2006.1 1995.2 2007.6 C
139.3936 -1995.7 2009.4 1995.2 2011.6 1994.7 2012.9 C
139.3937 -1992 2015.8 1987.8 2015.7 1985.3 2018.7 C
139.3938 -1988.3 2016.3 1992.3 2015.3 1995.4 2012.7 C
139.3939 -[0.18 0.18 0 0.78] vc
139.3940 -f
139.3941 -S
139.3942 -n
139.3943 -1995.6 2012.4 m
139.3944 -1995.6 2011.2 1995.6 2010 1995.6 2008.8 C
139.3945 -1995.6 2010 1995.6 2011.2 1995.6 2012.4 C
139.3946 -[0 1 1 0.36] vc
139.3947 -f
139.3948 -S
139.3949 -n
139.3950 -vmrs
139.3951 -2017.7 2009.6 m
139.3952 -2016.9 2009.3 2016.7 2008.4 2015.8 2009.1 C
139.3953 -2014.2 2010.6 2016 2010.6 2016.5 2011.5 C
139.3954 -2017.2 2010.9 2018.1 2010.8 2017.7 2009.6 C
139.3955 -[0 1 1 0.23] vc
139.3956 -f
139.3957 -0.4 w
139.3958 -2 J
139.3959 -2 M
139.3960 -S
139.3961 -n
139.3962 -2014.4 2006.4 m
139.3963 -2013.5 2006.8 2012.1 2005.6 2012 2006.7 C
139.3964 -2013 2007.3 2011.9 2009.2 2012.9 2008.4 C
139.3965 -2014.2 2008.3 2014.6 2007.8 2014.4 2006.4 C
139.3966 -f
139.3967 -S
139.3968 -n
139.3969 -1969 2006.4 m
139.3970 -1966.5 2003.8 1964 2001.2 1961.6 1998.5 C
139.3971 -1964 2001.2 1966.5 2003.8 1969 2006.4 C
139.3972 -[0 1 1 0.36] vc
139.3973 -f
139.3974 -S
139.3975 -n
139.3976 -2012 2005.2 m
139.3977 -2012.2 2004.2 2011.4 2003.3 2010.3 2003.3 C
139.3978 -2009 2003.6 2010 2004.7 2009.6 2004.8 C
139.3979 -2009.3 2005.7 2011.4 2006.7 2012 2005.2 C
139.3980 -[0 1 1 0.23] vc
139.3981 -f
139.3982 -S
139.3983 -n
139.3984 -1962.8 1995.2 m
139.3985 -1961.7 1994.4 1960.6 1993.7 1959.4 1994 C
139.3986 -1959.5 1994.9 1957.5 1994.1 1956.8 1994.7 C
139.3987 -1955.9 1995.5 1956.7 1997 1955.1 1997.3 C
139.3988 -1956.9 1996.7 1956.8 1994 1959.2 1994.7 C
139.3989 -1961.1 1991 1968.9 2003.2 1962.8 1995.2 C
139.3990 -[0 1 1 0.36] vc
139.3991 -f
139.3992 -S
139.3993 -n
139.3994 -1954.6 1995.6 m
139.3995 -1955.9 1994.7 1955.1 1989.8 1955.3 1988 C
139.3996 -1954.5 1988.3 1954.9 1986.6 1954.4 1986 C
139.3997 -1955.7 1989.2 1953.9 1991.1 1954.8 1994.2 C
139.3998 -1954.5 1995.9 1953.5 1995.3 1953.9 1997.3 C
139.3999 -1955.3 1998.3 1953.2 1995.5 1954.6 1995.6 C
139.4000 -f
139.4001 -S
139.4002 -n
139.4003 -1992.3 2011 m
139.4004 -1992.5 2006.7 1992 2000.3 1991.8 1997.6 C
139.4005 -1992.2 1997.9 1992 1998.5 1992 1999 C
139.4006 -1992.1 1994.7 1991.9 1990.2 1992.3 1986 C
139.4007 -1991.4 1984.6 1991 1986.1 1990.6 1985.6 C
139.4008 -1989.7 1986 1990.3 1987.2 1990.1 1988 C
139.4009 -1990.7 1987.4 1990.4 1988.5 1990.8 1988.7 C
139.4010 -1991.3 1997.1 1988.9 2000.6 1991.1 2007.9 C
139.4011 -1991 2009.1 1989.8 2009.9 1988.4 2008.8 C
139.4012 -1985.7 2007.2 1986.8 2004.5 1984.1 2004 C
139.4013 -1984.2 2002.7 1981.9 2003.7 1982.4 2001.4 C
139.4014 -1981.2 2001.5 1980.5 2000.8 1980 2000 C
139.4015 -1980 1999.8 1980 1998.9 1980 1999.5 C
139.4016 -1979.3 1999.5 1979.7 1997.2 1977.9 1998 C
139.4017 -1977.2 1997.3 1976.6 1996.7 1977.2 1997.8 C
139.4018 -1979 1998.7 1979.3 2000.8 1981.5 2001.6 C
139.4019 -1982.2 2002.8 1983 2004.3 1984.4 2004.3 C
139.4020 -1985 2005.8 1986.2 2007.5 1987.7 2009.1 C
139.4021 -1989 2010 1991.3 2010.2 1990.8 2012.2 C
139.4022 -1991.2 2011.4 1992.2 2011.8 1992.3 2011 C
139.4023 -[0 1 1 0.23] vc
139.4024 -f
139.4025 -S
139.4026 -n
139.4027 -1991.8 1995.6 m
139.4028 -1991.8 1994.3 1991.8 1992.9 1991.8 1991.6 C
139.4029 -1991.8 1992.9 1991.8 1994.3 1991.8 1995.6 C
139.4030 -[0 1 1 0.36] vc
139.4031 -f
139.4032 -S
139.4033 -n
139.4034 -1959.2 1994.2 m
139.4035 -1958.8 1993.3 1960.7 1993.9 1961.1 1993.7 C
139.4036 -1961.5 1993.9 1961.2 1994.4 1961.8 1994.2 C
139.4037 -1960.9 1994 1960.8 1992.9 1959.9 1992.5 C
139.4038 -1959.6 1993.5 1958.3 1993.5 1958.2 1994.2 C
139.4039 -1958.1 1994.1 1958 1994 1958 1994 C
139.4040 -1957.2 1994.9 1958 1993.4 1956.8 1993 C
139.4041 -1955.6 1992.5 1956 1991 1956.3 1989.9 C
139.4042 -1956.5 1989.8 1956.6 1990 1956.8 1990.1 C
139.4043 -1957.1 1989 1956 1989.1 1955.8 1988.2 C
139.4044 -1955.1 1990.4 1956.2 1995 1954.8 1995.9 C
139.4045 -1954.1 1995.5 1954.5 1996.5 1954.4 1997.1 C
139.4046 -1955 1996.8 1954.8 1997.4 1955.6 1996.8 C
139.4047 -1956 1996 1956.3 1993.2 1958.7 1994.2 C
139.4048 -1958.9 1994.2 1959.7 1994.2 1959.2 1994.2 C
139.4049 -[0 1 1 0.23] vc
139.4050 -f
139.4051 -S
139.4052 -n
139.4053 -1958.2 1994 m
139.4054 -1958.4 1993.5 1959.7 1993.1 1959.9 1992 C
139.4055 -1959.7 1992.5 1959.3 1992 1959.4 1991.8 C
139.4056 -1959.4 1991.6 1959.4 1990.8 1959.4 1991.3 C
139.4057 -1959.2 1991.8 1958.8 1991.3 1958.9 1991.1 C
139.4058 -1958.9 1990.5 1958 1990.3 1957.5 1989.9 C
139.4059 -1956.8 1989.5 1956.9 1991 1956.3 1990.1 C
139.4060 -1956.7 1991 1955.4 1992.1 1956.5 1992.3 C
139.4061 -1956.8 1993.5 1958.3 1992.9 1957.2 1994 C
139.4062 -1957.8 1994.3 1958.1 1992.4 1958.2 1994 C
139.4063 -[0 0.5 0.5 0.2] vc
139.4064 -f
139.4065 -S
139.4066 -n
139.4067 -vmrs
139.4068 -1954.4 1982.7 m
139.4069 -1956.1 1982.7 1954.1 1982.5 1953.9 1982.9 C
139.4070 -1953.9 1983.7 1953.7 1984.7 1954.1 1985.3 C
139.4071 -1954.4 1984.2 1953.6 1983.6 1954.4 1982.7 C
139.4072 -[0 1 1 0.36] vc
139.4073 -f
139.4074 -0.4 w
139.4075 -2 J
139.4076 -2 M
139.4077 -S
139.4078 -n
139.4079 -1989.6 1982.9 m
139.4080 -1989.1 1982.7 1988.6 1982.3 1988 1982.4 C
139.4081 -1987.2 1982.8 1987.4 1984.8 1987.7 1985.1 C
139.4082 -1988.9 1985.6 1990.7 1984.4 1989.6 1982.9 C
139.4083 -[0 1 1 0.23] vc
139.4084 -f
139.4085 -S
139.4086 -n
139.4087 -1987 1980.3 m
139.4088 -1986.2 1980 1986 1979.1 1985.1 1979.8 C
139.4089 -1983.5 1981.4 1985.3 1981.4 1985.8 1982.2 C
139.4090 -1986.5 1981.7 1987.4 1981.5 1987 1980.3 C
139.4091 -f
139.4092 -S
139.4093 -n
139.4094 -1983.6 1977.2 m
139.4095 -1982.7 1977.5 1981.4 1976.3 1981.2 1977.4 C
139.4096 -1982.3 1978 1981.2 1979.9 1982.2 1979.1 C
139.4097 -1983.5 1979 1983.9 1978.5 1983.6 1977.2 C
139.4098 -f
139.4099 -S
139.4100 -n
139.4101 -1981.2 1976 m
139.4102 -1981.5 1974.9 1980.6 1974 1979.6 1974 C
139.4103 -1978.3 1974.3 1979.3 1975.4 1978.8 1975.5 C
139.4104 -1978.6 1976.4 1980.7 1977.4 1981.2 1976 C
139.4105 -f
139.4106 -S
139.4107 -n
139.4108 -1972.1 2082.3 m
139.4109 -1971.8 2081.8 1971.3 2080.9 1971.2 2080.1 C
139.4110 -1971.1 2072.9 1971.3 2064.6 1970.9 2058.3 C
139.4111 -1970.3 2058.5 1970.1 2057.7 1969.7 2058.5 C
139.4112 -1970.6 2058.5 1969.7 2059 1970.2 2059.2 C
139.4113 -1970.2 2065.4 1970.2 2072.4 1970.2 2077.7 C
139.4114 -1971.1 2078.9 1970.6 2078.9 1970.4 2079.9 C
139.4115 -1969.2 2080.2 1968.2 2080.4 1967.3 2079.6 C
139.4116 -1966.8 2077.8 1963.4 2076.3 1963.5 2075.1 C
139.4117 -1961.5 2075.5 1962 2071.5 1959.6 2072 C
139.4118 -1959.2 2070 1956.5 2069.3 1955.8 2067.6 C
139.4119 -1956 2068.4 1955.3 2069.7 1956.5 2069.8 C
139.4120 -1958.6 2068.9 1958.1 2073.5 1960.1 2072.4 C
139.4121 -1960.7 2075.9 1964.7 2074.6 1964.2 2078 C
139.4122 -1967.2 2078.6 1967.9 2081.6 1970.7 2080.6 C
139.4123 -1970.3 2081.1 1971.5 2081.2 1971.9 2082.3 C
139.4124 -1967.2 2084.3 1962.9 2087.1 1958.2 2089 C
139.4125 -1962.9 2087 1967.4 2084.4 1972.1 2082.3 C
139.4126 -[0 0.2 1 0] vc
139.4127 -f
139.4128 -S
139.4129 -n
139.4130 -1971.9 2080.1 m
139.4131 -1971.9 2075.1 1971.9 2070 1971.9 2065 C
139.4132 -1971.9 2070 1971.9 2075.1 1971.9 2080.1 C
139.4133 -[0 1 1 0.23] vc
139.4134 -f
139.4135 -S
139.4136 -n
139.4137 -2010.8 2050.6 m
139.4138 -2013.2 2049 2010.5 2050.1 2010.5 2051.3 C
139.4139 -2010.5 2057.7 2010.5 2064.1 2010.5 2070.5 C
139.4140 -2008.7 2072.4 2006 2073.3 2003.6 2074.4 C
139.4141 -2016.4 2073.7 2008 2058.4 2010.8 2050.6 C
139.4142 -[0.4 0.4 0 0] vc
139.4143 -f
139.4144 -S
139.4145 -n
139.4146 -2006.4 2066.9 m
139.4147 -2006.4 2061.9 2006.4 2056.8 2006.4 2051.8 C
139.4148 -2006.4 2056.8 2006.4 2061.9 2006.4 2066.9 C
139.4149 -[0 1 1 0.23] vc
139.4150 -f
139.4151 -S
139.4152 -n
139.4153 -1971.9 2060.7 m
139.4154 -1972.2 2060.3 1971.4 2068.2 1972.4 2061.9 C
139.4155 -1971.8 2061.6 1972.4 2060.9 1971.9 2060.7 C
139.4156 -f
139.4157 -S
139.4158 -n
139.4159 -vmrs
139.4160 -1986.5 2055.2 m
139.4161 -1987.5 2054.3 1986.3 2053.4 1986 2052.8 C
139.4162 -1983.8 2052.7 1983.6 2050.1 1981.7 2049.6 C
139.4163 -1981.2 2048.7 1980.8 2047 1980.3 2046.8 C
139.4164 -1978.5 2047 1978 2044.6 1976.7 2043.9 C
139.4165 -1974 2044.4 1972 2046.6 1969.2 2047 C
139.4166 -1969 2047.2 1968.8 2047.5 1968.5 2047.7 C
139.4167 -1970.6 2049.6 1973.1 2051.3 1974.3 2054.2 C
139.4168 -1975.7 2054.5 1977 2055.2 1976.4 2057.1 C
139.4169 -1976.7 2058 1975.5 2058.5 1976 2059.5 C
139.4170 -1979.2 2058 1983 2056.6 1986.5 2055.2 C
139.4171 -[0 0.5 0.5 0.2] vc
139.4172 -f
139.4173 -0.4 w
139.4174 -2 J
139.4175 -2 M
139.4176 -S
139.4177 -n
139.4178 -1970.2 2054.2 m
139.4179 -1971.5 2055.3 1972.5 2056.8 1972.1 2058.3 C
139.4180 -1972.8 2056.5 1971.6 2055.6 1970.2 2054.2 C
139.4181 -[0 1 1 0.23] vc
139.4182 -f
139.4183 -S
139.4184 -n
139.4185 -1992 2052.5 m
139.4186 -1992 2053.4 1992.2 2054.4 1991.8 2055.2 C
139.4187 -1992.2 2054.4 1992 2053.4 1992 2052.5 C
139.4188 -f
139.4189 -S
139.4190 -n
139.4191 -1957.2 2053 m
139.4192 -1958.1 2052.6 1959 2052.2 1959.9 2051.8 C
139.4193 -1959 2052.2 1958.1 2052.6 1957.2 2053 C
139.4194 -f
139.4195 -S
139.4196 -n
139.4197 -2006.4 2047.5 m
139.4198 -2006.8 2047.1 2006 2055 2006.9 2048.7 C
139.4199 -2006.4 2048.4 2007 2047.7 2006.4 2047.5 C
139.4200 -f
139.4201 -S
139.4202 -n
139.4203 -2004.8 2041 m
139.4204 -2006.1 2042.1 2007.1 2043.6 2006.7 2045.1 C
139.4205 -2007.3 2043.3 2006.2 2042.4 2004.8 2041 C
139.4206 -f
139.4207 -S
139.4208 -n
139.4209 -1976 2039.8 m
139.4210 -1975.6 2039.3 1975.2 2038.4 1975 2037.6 C
139.4211 -1974.9 2030.4 1975.2 2022.1 1974.8 2015.8 C
139.4212 -1974.2 2016 1974 2015.3 1973.6 2016 C
139.4213 -1974.4 2016 1973.5 2016.5 1974 2016.8 C
139.4214 -1974 2022.9 1974 2030 1974 2035.2 C
139.4215 -1974.9 2036.4 1974.4 2036.4 1974.3 2037.4 C
139.4216 -1973.1 2037.7 1972 2037.9 1971.2 2037.2 C
139.4217 -1970.6 2035.3 1967.3 2033.9 1967.3 2032.6 C
139.4218 -1965.3 2033 1965.9 2029.1 1963.5 2029.5 C
139.4219 -1963 2027.6 1960.4 2026.8 1959.6 2025.2 C
139.4220 -1959.8 2025.9 1959.2 2027.2 1960.4 2027.3 C
139.4221 -1962.5 2026.4 1961.9 2031 1964 2030 C
139.4222 -1964.6 2033.4 1968.5 2032.1 1968 2035.5 C
139.4223 -1971 2036.1 1971.8 2039.1 1974.5 2038.1 C
139.4224 -1974.2 2038.7 1975.3 2038.7 1975.7 2039.8 C
139.4225 -1971 2041.8 1966.7 2044.6 1962 2046.5 C
139.4226 -1966.8 2044.5 1971.3 2041.9 1976 2039.8 C
139.4227 -[0 0.2 1 0] vc
139.4228 -f
139.4229 -S
139.4230 -n
139.4231 -1975.7 2037.6 m
139.4232 -1975.7 2032.6 1975.7 2027.6 1975.7 2022.5 C
139.4233 -1975.7 2027.6 1975.7 2032.6 1975.7 2037.6 C
139.4234 -[0 1 1 0.23] vc
139.4235 -f
139.4236 -S
139.4237 -n
139.4238 -1992 2035.5 m
139.4239 -1992 2034.2 1992 2032.9 1992 2031.6 C
139.4240 -1992 2032.9 1992 2034.2 1992 2035.5 C
139.4241 -f
139.4242 -S
139.4243 -n
139.4244 -2015.3 2036 m
139.4245 -2015.4 2034.1 2013.3 2034 2012.9 2033.3 C
139.4246 -2011.5 2031 2009.3 2029.4 2007.4 2028 C
139.4247 -2006.9 2027.1 2006.6 2023.8 2005 2024.9 C
139.4248 -2004 2024.9 2002.9 2024.9 2001.9 2024.9 C
139.4249 -2001.4 2026.5 2001 2028.4 2003.8 2028.3 C
139.4250 -2006.6 2030.4 2008.9 2033.7 2011.2 2036.2 C
139.4251 -2011.8 2036.4 2012.9 2035.8 2012.9 2036.7 C
139.4252 -2013 2035.5 2015.3 2037.4 2015.3 2036 C
139.4253 -[0 0 0 0] vc
139.4254 -f
139.4255 -S
139.4256 -n
139.4257 -vmrs
139.4258 -2009.1 2030.4 m
139.4259 -2009.1 2029 2007.5 2029.4 2006.9 2028.3 C
139.4260 -2007.2 2027.1 2006.5 2025.5 2005.7 2024.7 C
139.4261 -2004.6 2025.1 2003.1 2024.9 2001.9 2024.9 C
139.4262 -2001.8 2026.2 2000.9 2027 2002.4 2028 C
139.4263 -2004.5 2027.3 2004.9 2029.4 2006.9 2029 C
139.4264 -2007 2030.2 2007.6 2030.7 2008.4 2031.4 C
139.4265 -2008.8 2031.5 2009.1 2031.1 2009.1 2030.4 C
139.4266 -[0 0 0 0.18] vc
139.4267 -f
139.4268 -0.4 w
139.4269 -2 J
139.4270 -2 M
139.4271 -S
139.4272 -n
139.4273 -2003.8 2029.5 m
139.4274 -2003 2029.4 2001.9 2029.1 2002.4 2030.4 C
139.4275 -2003.1 2031.3 2005.2 2030.3 2003.8 2029.5 C
139.4276 -[0 1 1 0.23] vc
139.4277 -f
139.4278 -S
139.4279 -n
139.4280 -1999.2 2025.2 m
139.4281 -1999.1 2025.6 1998 2025.7 1998.8 2026.6 C
139.4282 -2000.9 2028.5 1999.5 2023.4 1999.2 2025.2 C
139.4283 -f
139.4284 -S
139.4285 -n
139.4286 -2007.6 2024.2 m
139.4287 -2007.6 2022.9 2008.4 2024.2 2007.6 2022.8 C
139.4288 -2007.6 2017.5 2007.8 2009.1 2007.4 2003.8 C
139.4289 -2007.9 2003.7 2008.7 2002.8 2009.1 2002.1 C
139.4290 -2009.6 2000.8 2008.3 2000.8 2007.9 2000.2 C
139.4291 -2004.9 2000 2008.9 2001.3 2007.2 2002.1 C
139.4292 -2006.7 2007.7 2007 2015.1 2006.9 2021.1 C
139.4293 -2006.7 2022.1 2005.4 2022.8 2006.2 2023.5 C
139.4294 -2006.6 2023.1 2008 2025.9 2007.6 2024.2 C
139.4295 -f
139.4296 -S
139.4297 -n
139.4298 -1989.9 2023.5 m
139.4299 -1989.5 2022.6 1991.4 2023.2 1991.8 2023 C
139.4300 -1992.2 2023.2 1991.9 2023.7 1992.5 2023.5 C
139.4301 -1991.6 2023.2 1991.6 2022.2 1990.6 2021.8 C
139.4302 -1990.4 2022.8 1989 2022.8 1988.9 2023.5 C
139.4303 -1988.5 2023 1988.7 2022.6 1988.7 2023.5 C
139.4304 -1989.1 2023.5 1990.2 2023.5 1989.9 2023.5 C
139.4305 -f
139.4306 -[0 0.5 0.5 0.2] vc
139.4307 -S
139.4308 -n
139.4309 -2003.3 2023.5 m
139.4310 -2003.1 2023.3 2003.1 2023.2 2003.3 2023 C
139.4311 -2003.7 2023.1 2003.9 2022.9 2003.8 2022.5 C
139.4312 -2003.4 2022.2 2001.2 2022.3 2002.4 2023 C
139.4313 -2002.6 2022.9 2002.7 2023.1 2002.8 2023.2 C
139.4314 -2000.7 2023.7 2003.9 2023.4 2003.3 2023.5 C
139.4315 -[0 1 1 0.23] vc
139.4316 -f
139.4317 -S
139.4318 -n
139.4319 -1986.8 2019.4 m
139.4320 -1987.8 2019.8 1987.5 2018.6 1987.2 2018 C
139.4321 -1986.2 2017.8 1987.3 2020.5 1986.3 2019.2 C
139.4322 -1986.3 2017.7 1986.3 2020.6 1986.3 2021.3 C
139.4323 -1988.5 2023.1 1985.6 2020.3 1986.8 2019.4 C
139.4324 -f
139.4325 -S
139.4326 -n
139.4327 -1975.7 2018.2 m
139.4328 -1976.1 2017.8 1975.2 2025.7 1976.2 2019.4 C
139.4329 -1975.7 2019.2 1976.3 2018.4 1975.7 2018.2 C
139.4330 -f
139.4331 -S
139.4332 -n
139.4333 -1974 2011.7 m
139.4334 -1975.4 2012.8 1976.4 2014.3 1976 2015.8 C
139.4335 -1976.6 2014 1975.5 2013.1 1974 2011.7 C
139.4336 -f
139.4337 -S
139.4338 -n
139.4339 -1984.6 2006.7 m
139.4340 -1984.7 2004.8 1982.6 2004.8 1982.2 2004 C
139.4341 -1980.8 2001.7 1978.6 2000.1 1976.7 1998.8 C
139.4342 -1976.1 1997.8 1975.8 1994.5 1974.3 1995.6 C
139.4343 -1973.3 1995.6 1972.2 1995.6 1971.2 1995.6 C
139.4344 -1970.7 1997.2 1970.3 1999.1 1973.1 1999 C
139.4345 -1975.8 2001.2 1978.2 2004.4 1980.5 2006.9 C
139.4346 -1981.1 2007.1 1982.1 2006.5 1982.2 2007.4 C
139.4347 -1982.3 2006.2 1984.5 2008.1 1984.6 2006.7 C
139.4348 -[0 0 0 0] vc
139.4349 -f
139.4350 -S
139.4351 -n
139.4352 -vmrs
139.4353 -1978.4 2001.2 m
139.4354 -1978.4 1999.7 1976.8 2000.1 1976.2 1999 C
139.4355 -1976.5 1997.8 1975.8 1996.2 1975 1995.4 C
139.4356 -1973.9 1995.8 1972.4 1995.6 1971.2 1995.6 C
139.4357 -1971 1997 1970.2 1997.7 1971.6 1998.8 C
139.4358 -1973.8 1998 1974.2 2000.1 1976.2 1999.7 C
139.4359 -1976.3 2000.9 1976.9 2001.4 1977.6 2002.1 C
139.4360 -1978.1 2002.2 1978.4 2001.8 1978.4 2001.2 C
139.4361 -[0 0 0 0.18] vc
139.4362 -f
139.4363 -0.4 w
139.4364 -2 J
139.4365 -2 M
139.4366 -S
139.4367 -n
139.4368 -1973.1 2000.2 m
139.4369 -1972.3 2000.1 1971.2 1999.8 1971.6 2001.2 C
139.4370 -1972.4 2002 1974.5 2001 1973.1 2000.2 C
139.4371 -[0 1 1 0.23] vc
139.4372 -f
139.4373 -S
139.4374 -n
139.4375 -1960.8 1998.5 m
139.4376 -1961.6 1998.2 1962.6 2000.3 1963.2 2000.9 C
139.4377 -1962.3 2000.1 1962.2 1998.7 1960.8 1998.5 C
139.4378 -f
139.4379 -S
139.4380 -n
139.4381 -1968.5 1995.9 m
139.4382 -1968.4 1996.4 1967.3 1996.4 1968 1997.3 C
139.4383 -1970.1 1999.2 1968.8 1994.1 1968.5 1995.9 C
139.4384 -f
139.4385 -S
139.4386 -n
139.4387 -1976.9 1994.9 m
139.4388 -1976.9 1993.7 1977.6 1994.9 1976.9 1993.5 C
139.4389 -1976.9 1988.2 1977.1 1979.8 1976.7 1974.5 C
139.4390 -1977.2 1974.5 1978 1973.5 1978.4 1972.8 C
139.4391 -1978.8 1971.5 1977.6 1971.5 1977.2 1970.9 C
139.4392 -1974.2 1970.7 1978.2 1972 1976.4 1972.8 C
139.4393 -1976 1978.4 1976.3 1985.8 1976.2 1991.8 C
139.4394 -1976 1992.8 1974.6 1993.5 1975.5 1994.2 C
139.4395 -1975.9 1993.8 1977.3 1996.6 1976.9 1994.9 C
139.4396 -f
139.4397 -S
139.4398 -n
139.4399 -1972.6 1994.2 m
139.4400 -1972.4 1994 1972.4 1993.9 1972.6 1993.7 C
139.4401 -1973 1993.8 1973.1 1993.7 1973.1 1993.2 C
139.4402 -1972.7 1992.9 1970.5 1993.1 1971.6 1993.7 C
139.4403 -1971.9 1993.7 1972 1993.8 1972.1 1994 C
139.4404 -1970 1994.4 1973.1 1994.1 1972.6 1994.2 C
139.4405 -f
139.4406 -S
139.4407 -n
139.4408 -1948.1 2093.8 m
139.4409 -1947 2092.7 1945.9 2091.6 1944.8 2090.4 C
139.4410 -1945.9 2091.6 1947 2092.7 1948.1 2093.8 C
139.4411 -[0 0.4 1 0] vc
139.4412 -f
139.4413 -S
139.4414 -n
139.4415 -1953.4 2091.4 m
139.4416 -1954.8 2090.7 1956.3 2090 1957.7 2089.2 C
139.4417 -1956.3 2090 1954.8 2090.7 1953.4 2091.4 C
139.4418 -[0 0.2 1 0] vc
139.4419 -f
139.4420 -S
139.4421 -n
139.4422 -1954.1 2091.4 m
139.4423 -1956.6 2089.6 1957.2 2089.6 1954.1 2091.4 C
139.4424 -[0 0.4 1 0] vc
139.4425 -f
139.4426 -S
139.4427 -n
139.4428 -1962.3 2087.3 m
139.4429 -1963.7 2086.6 1965.2 2085.9 1966.6 2085.2 C
139.4430 -1965.2 2085.9 1963.7 2086.6 1962.3 2087.3 C
139.4431 -f
139.4432 -S
139.4433 -n
139.4434 -vmrs
139.4435 -1967.1 2084.9 m
139.4436 -1968.3 2084.4 1969.7 2083.8 1970.9 2083.2 C
139.4437 -1969.7 2083.8 1968.3 2084.4 1967.1 2084.9 C
139.4438 -[0 0.4 1 0] vc
139.4439 -f
139.4440 -0.4 w
139.4441 -2 J
139.4442 -2 M
139.4443 -S
139.4444 -n
139.4445 -1982.7 2080.6 m
139.4446 -1981.5 2079.5 1980.5 2078.4 1979.3 2077.2 C
139.4447 -1980.5 2078.4 1981.5 2079.5 1982.7 2080.6 C
139.4448 -f
139.4449 -S
139.4450 -n
139.4451 -1988 2078.2 m
139.4452 -1989.4 2077.5 1990.8 2076.8 1992.3 2076 C
139.4453 -1990.8 2076.8 1989.4 2077.5 1988 2078.2 C
139.4454 -[0 0.2 1 0] vc
139.4455 -f
139.4456 -S
139.4457 -n
139.4458 -1988.7 2078.2 m
139.4459 -1991.1 2076.4 1991.8 2076.4 1988.7 2078.2 C
139.4460 -[0 0.4 1 0] vc
139.4461 -f
139.4462 -S
139.4463 -n
139.4464 -1976.2 2063.8 m
139.4465 -1978.6 2062.2 1976 2063.3 1976 2064.5 C
139.4466 -1976.1 2067.8 1975.5 2071.4 1976.4 2074.4 C
139.4467 -1975.7 2071.1 1975.9 2067.2 1976.2 2063.8 C
139.4468 -f
139.4469 -S
139.4470 -n
139.4471 -1996.8 2074.1 m
139.4472 -1998.3 2073.4 1999.7 2072.7 2001.2 2072 C
139.4473 -1999.7 2072.7 1998.3 2073.4 1996.8 2074.1 C
139.4474 -f
139.4475 -S
139.4476 -n
139.4477 -2001.6 2071.7 m
139.4478 -2002.9 2071.2 2004.2 2070.6 2005.5 2070 C
139.4479 -2004.2 2070.6 2002.9 2071.2 2001.6 2071.7 C
139.4480 -f
139.4481 -S
139.4482 -n
139.4483 -1981.5 2060.7 m
139.4484 -1980.2 2061.2 1978.9 2061.5 1977.9 2062.6 C
139.4485 -1978.9 2061.5 1980.2 2061.2 1981.5 2060.7 C
139.4486 -f
139.4487 -S
139.4488 -n
139.4489 -1982 2060.4 m
139.4490 -1982.7 2060.1 1983.6 2059.8 1984.4 2059.5 C
139.4491 -1983.6 2059.8 1982.7 2060.1 1982 2060.4 C
139.4492 -f
139.4493 -S
139.4494 -n
139.4495 -1952 2051.3 m
139.4496 -1950.8 2050.2 1949.7 2049.1 1948.6 2048 C
139.4497 -1949.7 2049.1 1950.8 2050.2 1952 2051.3 C
139.4498 -f
139.4499 -S
139.4500 -n
139.4501 -vmrs
139.4502 -1977.4 2047.7 m
139.4503 -1975.8 2047.8 1974.8 2046.1 1974.5 2045.3 C
139.4504 -1974.9 2044.4 1976 2044.5 1976.7 2044.8 C
139.4505 -1977.9 2045 1977 2048.4 1979.3 2047.5 C
139.4506 -1979.9 2047.5 1980.8 2048.6 1979.8 2049.2 C
139.4507 -1978.2 2050.4 1980.8 2049.5 1980.3 2049.4 C
139.4508 -1981.4 2049.8 1980.3 2048.4 1980.3 2048 C
139.4509 -1979.8 2047.5 1979 2046.6 1978.4 2046.5 C
139.4510 -1977.3 2045.9 1977.2 2043.3 1975.2 2044.6 C
139.4511 -1974.7 2045.3 1973.6 2045 1973.3 2045.8 C
139.4512 -1975 2046.3 1975.8 2049.8 1978.1 2049.4 C
139.4513 -1978.4 2050.9 1978.7 2048.5 1977.9 2049.2 C
139.4514 -1977.7 2048.7 1977.2 2047.8 1977.4 2047.7 C
139.4515 -[0 0.5 0.5 0.2] vc
139.4516 -f
139.4517 -0.4 w
139.4518 -2 J
139.4519 -2 M
139.4520 -S
139.4521 -n
139.4522 -1957.2 2048.9 m
139.4523 -1958.7 2048.2 1960.1 2047.5 1961.6 2046.8 C
139.4524 -1960.1 2047.5 1958.7 2048.2 1957.2 2048.9 C
139.4525 -[0 0.2 1 0] vc
139.4526 -f
139.4527 -S
139.4528 -n
139.4529 -1958 2048.9 m
139.4530 -1960.4 2047.1 1961.1 2047.1 1958 2048.9 C
139.4531 -[0 0.4 1 0] vc
139.4532 -f
139.4533 -S
139.4534 -n
139.4535 -1966.1 2044.8 m
139.4536 -1967.6 2044.1 1969 2043.4 1970.4 2042.7 C
139.4537 -1969 2043.4 1967.6 2044.1 1966.1 2044.8 C
139.4538 -f
139.4539 -S
139.4540 -n
139.4541 -1970.9 2042.4 m
139.4542 -1972.2 2041.9 1973.5 2041.3 1974.8 2040.8 C
139.4543 -1973.5 2041.3 1972.2 2041.9 1970.9 2042.4 C
139.4544 -f
139.4545 -S
139.4546 -n
139.4547 -2012 2034.5 m
139.4548 -2010.4 2034.6 2009.3 2032.9 2009.1 2032.1 C
139.4549 -2009.4 2031 2010.3 2031.3 2011.2 2031.6 C
139.4550 -2012.5 2031.8 2011.6 2035.2 2013.9 2034.3 C
139.4551 -2014.4 2034.3 2015.4 2035.4 2014.4 2036 C
139.4552 -2012.7 2037.2 2015.3 2036.3 2014.8 2036.2 C
139.4553 -2015.9 2036.6 2014.8 2035.2 2014.8 2034.8 C
139.4554 -2014.4 2034.3 2013.6 2033.4 2012.9 2033.3 C
139.4555 -2011.5 2031 2009.3 2029.4 2007.4 2028 C
139.4556 -2007.5 2026.5 2007.3 2027.9 2007.2 2028.3 C
139.4557 -2007.9 2028.8 2008.7 2029.1 2009.3 2030 C
139.4558 -2009.6 2030.7 2009 2031.9 2008.4 2031.6 C
139.4559 -2006.7 2031 2007.7 2028 2005 2028.8 C
139.4560 -2004.8 2028.6 2004.3 2028.2 2003.8 2028.3 C
139.4561 -2006.6 2030.4 2008.9 2033.7 2011.2 2036.2 C
139.4562 -2011.8 2036.4 2012.9 2035.8 2012.9 2036.7 C
139.4563 -2012.7 2036.1 2011.8 2035 2012 2034.5 C
139.4564 -[0 0.5 0.5 0.2] vc
139.4565 -f
139.4566 -S
139.4567 -n
139.4568 -1981.2 2005.2 m
139.4569 -1979.7 2005.3 1978.6 2003.6 1978.4 2002.8 C
139.4570 -1978.7 2001.8 1979.6 2002.1 1980.5 2002.4 C
139.4571 -1981.8 2002.5 1980.9 2005.9 1983.2 2005 C
139.4572 -1983.7 2005.1 1984.7 2006.1 1983.6 2006.7 C
139.4573 -1982 2007.9 1984.6 2007 1984.1 2006.9 C
139.4574 -1985.2 2007.3 1984.1 2006 1984.1 2005.5 C
139.4575 -1983.6 2005 1982.9 2004.1 1982.2 2004 C
139.4576 -1980.8 2001.7 1978.6 2000.1 1976.7 1998.8 C
139.4577 -1976.7 1997.2 1976.6 1998.6 1976.4 1999 C
139.4578 -1977.2 1999.5 1978 1999.8 1978.6 2000.7 C
139.4579 -1978.8 2001.5 1978.3 2002.7 1977.6 2002.4 C
139.4580 -1976 2001.8 1977 1998.7 1974.3 1999.5 C
139.4581 -1974.1 1999.3 1973.6 1998.9 1973.1 1999 C
139.4582 -1975.8 2001.2 1978.2 2004.4 1980.5 2006.9 C
139.4583 -1981.1 2007.1 1982.1 2006.5 1982.2 2007.4 C
139.4584 -1982 2006.8 1981.1 2005.7 1981.2 2005.2 C
139.4585 -f
139.4586 -S
139.4587 -n
139.4588 -1966.8 1976.4 m
139.4589 -1969.4 1973 1974.4 1974.6 1976.2 1970.4 C
139.4590 -1972.7 1974 1968 1975.1 1964 1977.4 C
139.4591 -1960.9 1979.9 1957.1 1981.8 1953.9 1982.7 C
139.4592 -1958.4 1981.1 1962.6 1978.8 1966.8 1976.4 C
139.4593 -[0.18 0.18 0 0.78] vc
139.4594 -f
139.4595 -S
139.4596 -n
139.4597 -1948.4 2093.8 m
139.4598 -1949.8 2093.1 1951.2 2092.5 1952.7 2091.9 C
139.4599 -1951.2 2092.5 1949.8 2093.1 1948.4 2093.8 C
139.4600 -[0 0.2 1 0] vc
139.4601 -f
139.4602 -S
139.4603 -n
139.4604 -1948.1 2093.6 m
139.4605 -1947.3 2092.8 1946.5 2091.9 1945.7 2091.2 C
139.4606 -1946.5 2091.9 1947.3 2092.8 1948.1 2093.6 C
139.4607 -f
139.4608 -S
139.4609 -n
139.4610 -vmrs
139.4611 -1942.1 2087.8 m
139.4612 -1943.5 2088.4 1944.3 2089.5 1945.2 2090.7 C
139.4613 -1944.8 2089.3 1943.3 2088.3 1942.1 2087.8 C
139.4614 -[0 0.2 1 0] vc
139.4615 -f
139.4616 -0.4 w
139.4617 -2 J
139.4618 -2 M
139.4619 -S
139.4620 -n
139.4621 -1933.5 2078.4 m
139.4622 -1933.5 2078 1933.2 2079 1933.7 2079.4 C
139.4623 -1935 2080.4 1936.2 2081.3 1937.1 2082.8 C
139.4624 -1936.7 2080.7 1933.7 2080.7 1933.5 2078.4 C
139.4625 -f
139.4626 -S
139.4627 -n
139.4628 -1982.9 2080.6 m
139.4629 -1984.4 2079.9 1985.8 2079.3 1987.2 2078.7 C
139.4630 -1985.8 2079.3 1984.4 2079.9 1982.9 2080.6 C
139.4631 -f
139.4632 -S
139.4633 -n
139.4634 -1982.7 2080.4 m
139.4635 -1981.9 2079.6 1981.1 2078.7 1980.3 2078 C
139.4636 -1981.1 2078.7 1981.9 2079.6 1982.7 2080.4 C
139.4637 -f
139.4638 -S
139.4639 -n
139.4640 -1977.4 2075.1 m
139.4641 -1977.9 2075.3 1979.1 2076.4 1979.8 2077.5 C
139.4642 -1979 2076.8 1978.7 2075.1 1977.4 2075.1 C
139.4643 -f
139.4644 -S
139.4645 -n
139.4646 -1952.2 2051.3 m
139.4647 -1953.6 2050.7 1955.1 2050.1 1956.5 2049.4 C
139.4648 -1955.1 2050.1 1953.6 2050.7 1952.2 2051.3 C
139.4649 -f
139.4650 -S
139.4651 -n
139.4652 -1952 2051.1 m
139.4653 -1951.2 2050.3 1950.3 2049.5 1949.6 2048.7 C
139.4654 -1950.3 2049.5 1951.2 2050.3 1952 2051.1 C
139.4655 -f
139.4656 -S
139.4657 -n
139.4658 -1946 2045.3 m
139.4659 -1947.3 2045.9 1948.1 2047 1949.1 2048.2 C
139.4660 -1948.6 2046.8 1947.1 2045.8 1946 2045.3 C
139.4661 -f
139.4662 -S
139.4663 -n
139.4664 -1937.3 2036 m
139.4665 -1937.4 2035.5 1937 2036.5 1937.6 2036.9 C
139.4666 -1938.8 2037.9 1940.1 2038.8 1940.9 2040.3 C
139.4667 -1940.6 2038.2 1937.6 2038.2 1937.3 2036 C
139.4668 -f
139.4669 -S
139.4670 -n
139.4671 -1935.2 2073.2 m
139.4672 -1936.4 2069.9 1935.8 2061.8 1935.6 2056.4 C
139.4673 -1935.8 2055.9 1936.3 2055.7 1936.1 2055.2 C
139.4674 -1935.7 2054.7 1935 2055 1934.4 2054.9 C
139.4675 -1934.4 2061.5 1934.4 2068.7 1934.4 2074.6 C
139.4676 -1935.7 2075.1 1936 2073.7 1935.2 2073.2 C
139.4677 -[0 0.01 1 0] vc
139.4678 -f
139.4679 -S
139.4680 -n
139.4681 -vmrs
139.4682 -1939 2030.7 m
139.4683 -1940.3 2027.4 1939.7 2019.3 1939.5 2013.9 C
139.4684 -1939.7 2013.5 1940.1 2013.2 1940 2012.7 C
139.4685 -1939.5 2012.3 1938.8 2012.5 1938.3 2012.4 C
139.4686 -1938.3 2019 1938.3 2026.2 1938.3 2032.1 C
139.4687 -1939.5 2032.7 1939.8 2031.2 1939 2030.7 C
139.4688 -[0 0.01 1 0] vc
139.4689 -f
139.4690 -0.4 w
139.4691 -2 J
139.4692 -2 M
139.4693 -S
139.4694 -n
139.4695 -1975.2 2077.2 m
139.4696 -1975.3 2077.3 1975.4 2077.4 1975.5 2077.5 C
139.4697 -1974.7 2073.2 1974.9 2067.5 1975.2 2063.6 C
139.4698 -1975.4 2064 1974.6 2063.9 1974.8 2064.3 C
139.4699 -1974.9 2069.9 1974.3 2076.5 1975.2 2081.1 C
139.4700 -1974.9 2079.9 1974.9 2078.4 1975.2 2077.2 C
139.4701 -[0.92 0.92 0 0.67] vc
139.4702 -f
139.4703 -S
139.4704 -n
139.4705 -1930.8 2067.4 m
139.4706 -1931.5 2070.1 1929.6 2072.1 1930.6 2074.6 C
139.4707 -1931 2072.6 1930.8 2069.8 1930.8 2067.4 C
139.4708 -f
139.4709 -S
139.4710 -n
139.4711 -2010 2050.1 m
139.4712 -2009.8 2050.5 2009.5 2050.9 2009.3 2051.1 C
139.4713 -2009.5 2056.7 2008.9 2063.3 2009.8 2067.9 C
139.4714 -2009.5 2062.1 2009.3 2054.7 2010 2050.1 C
139.4715 -f
139.4716 -S
139.4717 -n
139.4718 -1930.1 2060.9 m
139.4719 -1929.3 2057.1 1930.7 2054.8 1929.9 2051.3 C
139.4720 -1930.2 2050.2 1931.1 2049.6 1931.8 2049.2 C
139.4721 -1931.4 2049.6 1930.4 2049.5 1930.1 2050.1 C
139.4722 -1928.4 2054.8 1933.4 2063.5 1925.3 2064.3 C
139.4723 -1927.2 2063.9 1928.5 2062.1 1930.1 2060.9 C
139.4724 -[0.07 0.06 0 0.58] vc
139.4725 -f
139.4726 -S
139.4727 -n
139.4728 -1929.6 2061.2 m
139.4729 -1929.6 2057.6 1929.6 2054.1 1929.6 2050.6 C
139.4730 -1930 2049.9 1930.5 2049.4 1931.1 2049.2 C
139.4731 -1930 2048.6 1930.5 2050.2 1929.4 2049.6 C
139.4732 -1928 2054.4 1932.8 2063 1925.3 2064 C
139.4733 -1926.9 2063.3 1928.3 2062.4 1929.6 2061.2 C
139.4734 -[0.4 0.4 0 0] vc
139.4735 -f
139.4736 -S
139.4737 -n
139.4738 -1930.8 2061.6 m
139.4739 -1930.5 2058 1931.6 2054 1930.8 2051.3 C
139.4740 -1930.3 2054.5 1930.9 2058.5 1930.4 2061.9 C
139.4741 -1930.5 2061.2 1931 2062.2 1930.8 2061.6 C
139.4742 -[0.92 0.92 0 0.67] vc
139.4743 -f
139.4744 -S
139.4745 -n
139.4746 -1941.2 2045.1 m
139.4747 -1939.7 2042.6 1937.3 2041.2 1935.4 2039.3 C
139.4748 -1934.2 2040 1933.7 2036.4 1934 2039.3 C
139.4749 -1934.9 2040.1 1936.1 2039.9 1936.8 2040.8 C
139.4750 -1935.3 2044.2 1942.3 2041.7 1939.5 2046 C
139.4751 -1937.1 2048.5 1940.5 2045.6 1941.2 2045.1 C
139.4752 -f
139.4753 -S
139.4754 -n
139.4755 -1910 2045.8 m
139.4756 -1910 2039.4 1910 2033 1910 2026.6 C
139.4757 -1910 2033 1910 2039.4 1910 2045.8 C
139.4758 -f
139.4759 -S
139.4760 -n
139.4761 -1978.8 2022.3 m
139.4762 -1979.1 2021.7 1979.4 2020.4 1978.6 2021.6 C
139.4763 -1978.6 2026.9 1978.6 2033 1978.6 2037.6 C
139.4764 -1979.2 2037 1979.1 2038.2 1979.1 2038.6 C
139.4765 -1978.7 2033.6 1978.9 2026.8 1978.8 2022.3 C
139.4766 -f
139.4767 -S
139.4768 -n
139.4769 -vmrs
139.4770 -2026.1 2041.2 m
139.4771 -2026.1 2034.8 2026.1 2028.3 2026.1 2021.8 C
139.4772 -2026.1 2028.5 2026.3 2035.4 2025.9 2042 C
139.4773 -2024.4 2042.9 2022.9 2044.1 2021.3 2044.8 C
139.4774 -2023.1 2044 2025.1 2042.8 2026.1 2041.2 C
139.4775 -[0.07 0.06 0 0.58] vc
139.4776 -f
139.4777 -0.4 w
139.4778 -2 J
139.4779 -2 M
139.4780 -S
139.4781 -n
139.4782 -2026.4 2021.8 m
139.4783 -2026.3 2028.5 2026.5 2035.4 2026.1 2042 C
139.4784 -2025.6 2042.8 2024.7 2042.7 2024.2 2043.4 C
139.4785 -2024.7 2042.7 2025.5 2042.7 2026.1 2042.2 C
139.4786 -2026.5 2035.5 2026.3 2027.9 2026.4 2021.8 C
139.4787 -[0.4 0.4 0 0] vc
139.4788 -f
139.4789 -S
139.4790 -n
139.4791 -2025.6 2038.4 m
139.4792 -2025.6 2033 2025.6 2027.6 2025.6 2022.3 C
139.4793 -2025.6 2027.6 2025.6 2033 2025.6 2038.4 C
139.4794 -[0.92 0.92 0 0.67] vc
139.4795 -f
139.4796 -S
139.4797 -n
139.4798 -1934 2023.5 m
139.4799 -1934 2024.7 1933.8 2026 1934.2 2027.1 C
139.4800 -1934 2025.5 1934.7 2024.6 1934 2023.5 C
139.4801 -f
139.4802 -S
139.4803 -n
139.4804 -1928.2 2023.5 m
139.4805 -1928 2024.6 1927.4 2023.1 1926.8 2023.2 C
139.4806 -1926.2 2021 1921.4 2019.3 1923.2 2018 C
139.4807 -1922.7 2016.5 1923.2 2019.3 1922.2 2018.2 C
139.4808 -1924.4 2020.4 1926.2 2023.3 1928.9 2024.9 C
139.4809 -1927.9 2024.2 1929.8 2023.5 1928.2 2023.5 C
139.4810 -[0.18 0.18 0 0.78] vc
139.4811 -f
139.4812 -S
139.4813 -n
139.4814 -1934 2019.2 m
139.4815 -1932 2019.6 1930.8 2022.6 1928.7 2021.8 C
139.4816 -1924.5 2016.5 1918.2 2011.8 1914 2006.7 C
139.4817 -1914 2005.7 1914 2004.6 1914 2003.6 C
139.4818 -1913.6 2004.3 1913.9 2005.8 1913.8 2006.9 C
139.4819 -1919 2012.4 1924.1 2016.5 1929.2 2022.3 C
139.4820 -1931 2021.7 1932.2 2019.8 1934 2019.2 C
139.4821 -f
139.4822 -S
139.4823 -n
139.4824 -1928.7 2024.9 m
139.4825 -1926.3 2022.7 1924.1 2020.4 1921.7 2018.2 C
139.4826 -1924.1 2020.4 1926.3 2022.7 1928.7 2024.9 C
139.4827 -[0.65 0.65 0 0.42] vc
139.4828 -f
139.4829 -S
139.4830 -n
139.4831 -1914.3 2006.7 m
139.4832 -1918.7 2011.8 1924.5 2016.4 1928.9 2021.6 C
139.4833 -1924.2 2016.1 1919 2012.1 1914.3 2006.7 C
139.4834 -[0.07 0.06 0 0.58] vc
139.4835 -f
139.4836 -S
139.4837 -n
139.4838 -1924.8 2020.8 m
139.4839 -1921.2 2016.9 1925.6 2022.5 1926 2021.1 C
139.4840 -1924.2 2021 1926.7 2019.6 1924.8 2020.8 C
139.4841 -[0.92 0.92 0 0.67] vc
139.4842 -f
139.4843 -S
139.4844 -n
139.4845 -1934 2018.4 m
139.4846 -1933.2 2014.7 1934.5 2012.3 1933.7 2008.8 C
139.4847 -1934 2007.8 1935 2007.2 1935.6 2006.7 C
139.4848 -1935.3 2007.1 1934.3 2007 1934 2007.6 C
139.4849 -1932.2 2012.3 1937.2 2021 1929.2 2021.8 C
139.4850 -1931.1 2021.4 1932.3 2019.6 1934 2018.4 C
139.4851 -[0.07 0.06 0 0.58] vc
139.4852 -f
139.4853 -S
139.4854 -n
139.4855 -vmrs
139.4856 -1933.5 2018.7 m
139.4857 -1933.5 2015.1 1933.5 2011.7 1933.5 2008.1 C
139.4858 -1933.8 2007.4 1934.3 2006.9 1934.9 2006.7 C
139.4859 -1933.8 2006.1 1934.3 2007.7 1933.2 2007.2 C
139.4860 -1931.9 2012 1936.7 2020.5 1929.2 2021.6 C
139.4861 -1930.7 2020.8 1932.2 2019.9 1933.5 2018.7 C
139.4862 -[0.4 0.4 0 0] vc
139.4863 -f
139.4864 -0.4 w
139.4865 -2 J
139.4866 -2 M
139.4867 -S
139.4868 -n
139.4869 -1934.7 2019.2 m
139.4870 -1934.3 2015.6 1935.4 2011.5 1934.7 2008.8 C
139.4871 -1934.1 2012 1934.7 2016 1934.2 2019.4 C
139.4872 -1934.4 2018.7 1934.8 2019.8 1934.7 2019.2 C
139.4873 -[0.92 0.92 0 0.67] vc
139.4874 -f
139.4875 -S
139.4876 -n
139.4877 -1917.6 2013.6 m
139.4878 -1917.8 2011.1 1916.8 2014.2 1917.2 2012.2 C
139.4879 -1916.3 2012.9 1914.8 2011.8 1914.3 2010.8 C
139.4880 -1914.2 2010.5 1914.4 2010.4 1914.5 2010.3 C
139.4881 -1913.9 2008.8 1913.9 2011.9 1914.3 2012 C
139.4882 -1916.3 2012 1917.6 2013.6 1916.7 2015.6 C
139.4883 -1913.7 2017.4 1919.6 2014.8 1917.6 2013.6 C
139.4884 -f
139.4885 -S
139.4886 -n
139.4887 -1887.2 2015.3 m
139.4888 -1887.2 2008.9 1887.2 2002.5 1887.2 1996.1 C
139.4889 -1887.2 2002.5 1887.2 2008.9 1887.2 2015.3 C
139.4890 -f
139.4891 -S
139.4892 -n
139.4893 -1916.7 2014.4 m
139.4894 -1917 2012.1 1913 2013 1913.8 2010.8 C
139.4895 -1912.1 2009.8 1910.9 2009.4 1910.7 2007.9 C
139.4896 -1910.4 2010.6 1913.4 2010.4 1914 2012.4 C
139.4897 -1914.9 2012.8 1916.6 2012.9 1916.4 2014.4 C
139.4898 -1916.9 2015.1 1914.5 2016.6 1916.2 2015.8 C
139.4899 -1916.4 2015.3 1916.7 2015 1916.7 2014.4 C
139.4900 -[0.65 0.65 0 0.42] vc
139.4901 -f
139.4902 -S
139.4903 -n
139.4904 -1914 2009.3 m
139.4905 -1912.8 2010.9 1909.6 2005.3 1911.9 2009.8 C
139.4906 -1912.3 2009.6 1913.6 2010.2 1914 2009.3 C
139.4907 -[0.92 0.92 0 0.67] vc
139.4908 -f
139.4909 -S
139.4910 -n
139.4911 -1951.2 1998.8 m
139.4912 -1949 1996.4 1951.5 1994 1950.3 1991.8 C
139.4913 -1949.1 1989.1 1954 1982.7 1948.8 1981.2 C
139.4914 -1949.2 1981.5 1951 1982.4 1950.8 1983.6 C
139.4915 -1951.9 1988.6 1947.1 1986.5 1948.1 1990.4 C
139.4916 -1948.5 1990.3 1948.7 1990.7 1948.6 1991.1 C
139.4917 -1949 1992.5 1947.3 1991.9 1948.1 1992.5 C
139.4918 -1947.1 1992.7 1945.7 1993.5 1945.2 1994.7 C
139.4919 -1944.5 1996.8 1947.7 2000.5 1943.8 2001.4 C
139.4920 -1943.4 2002 1943.7 2004 1942.4 2004.5 C
139.4921 -1945.2 2002.2 1948.9 2000.9 1951.2 1998.8 C
139.4922 -f
139.4923 -S
139.4924 -n
139.4925 -1994.9 1993 m
139.4926 -1995.1 1996.5 1994.5 2000.3 1995.4 2003.6 C
139.4927 -1994.5 2000.3 1995.1 1996.5 1994.9 1993 C
139.4928 -f
139.4929 -S
139.4930 -n
139.4931 -1913.8 2003.3 m
139.4932 -1913.8 1996.9 1913.8 1990.5 1913.8 1984.1 C
139.4933 -1913.8 1990.5 1913.8 1996.9 1913.8 2003.3 C
139.4934 -f
139.4935 -S
139.4936 -n
139.4937 -1941.9 1998 m
139.4938 -1940.5 1997.3 1940.7 1999.4 1940.7 2000 C
139.4939 -1942.8 2001.3 1942.6 1998.8 1941.9 1998 C
139.4940 -[0 0 0 0] vc
139.4941 -f
139.4942 -S
139.4943 -n
139.4944 -vmrs
139.4945 -1942.1 1999.2 m
139.4946 -1942.2 1998.9 1941.8 1998.8 1941.6 1998.5 C
139.4947 -1940.4 1998 1940.7 1999.7 1940.7 2000 C
139.4948 -1941.6 2000.3 1942.6 2000.4 1942.1 1999.2 C
139.4949 -[0.92 0.92 0 0.67] vc
139.4950 -f
139.4951 -0.4 w
139.4952 -2 J
139.4953 -2 M
139.4954 -S
139.4955 -n
139.4956 -1940 1997.1 m
139.4957 -1939.8 1996 1939.7 1995.9 1939.2 1995.2 C
139.4958 -1939.1 1995.3 1938.5 1997.9 1937.8 1996.4 C
139.4959 -1938 1997.3 1939.4 1998.6 1940 1997.1 C
139.4960 -f
139.4961 -S
139.4962 -n
139.4963 -1911.2 1995.9 m
139.4964 -1911.2 1991.6 1911.3 1987.2 1911.4 1982.9 C
139.4965 -1911.3 1987.2 1911.2 1991.6 1911.2 1995.9 C
139.4966 -f
139.4967 -S
139.4968 -n
139.4969 -1947.2 1979.1 m
139.4970 -1945.1 1978.8 1944.6 1975.7 1942.4 1975 C
139.4971 -1940.5 1972.6 1942.2 1973.7 1942.4 1975.7 C
139.4972 -1945.8 1975.5 1944.2 1979.8 1947.6 1979.6 C
139.4973 -1948.3 1982.3 1948.5 1980 1947.2 1979.1 C
139.4974 -f
139.4975 -S
139.4976 -n
139.4977 -1939.5 1973.3 m
139.4978 -1940.1 1972.6 1939.8 1974.2 1940.2 1973.1 C
139.4979 -1939.1 1972.8 1938.8 1968.5 1935.9 1969.7 C
139.4980 -1937.4 1969.2 1938.5 1970.6 1939 1971.4 C
139.4981 -1939.2 1972.7 1938.6 1973.9 1939.5 1973.3 C
139.4982 -f
139.4983 -S
139.4984 -n
139.4985 -1975.2 2073.2 m
139.4986 -1975.2 2070.2 1975.2 2067.2 1975.2 2064.3 C
139.4987 -1975.2 2067.2 1975.2 2070.2 1975.2 2073.2 C
139.4988 -[0.18 0.18 0 0.78] vc
139.4989 -f
139.4990 -S
139.4991 -n
139.4992 -1929.9 2065.7 m
139.4993 -1928.1 2065.6 1926 2068.8 1924.1 2066.9 C
139.4994 -1918.1 2060.9 1912.9 2055.7 1907.1 2049.9 C
139.4995 -1906.7 2047.1 1906.9 2043.9 1906.8 2041 C
139.4996 -1906.8 2043.9 1906.8 2046.8 1906.8 2049.6 C
139.4997 -1913.2 2055.5 1918.7 2061.9 1925.1 2067.6 C
139.4998 -1927.1 2067.9 1928.6 2064.4 1930.1 2066.2 C
139.4999 -1929.7 2070.3 1929.9 2074.7 1929.9 2078.9 C
139.5000 -1929.6 2074.4 1930.5 2070.1 1929.9 2065.7 C
139.5001 -[0.07 0.06 0 0.58] vc
139.5002 -f
139.5003 -S
139.5004 -n
139.5005 -1930.1 2061.6 m
139.5006 -1928.1 2062.1 1927 2065.1 1924.8 2064.3 C
139.5007 -1920.7 2058.9 1914.4 2054.3 1910.2 2049.2 C
139.5008 -1910.2 2048.1 1910.2 2047.1 1910.2 2046 C
139.5009 -1909.8 2046.8 1910 2048.3 1910 2049.4 C
139.5010 -1915.1 2054.9 1920.3 2059 1925.3 2064.8 C
139.5011 -1927.1 2064.2 1928.4 2062.3 1930.1 2061.6 C
139.5012 -[0.18 0.18 0 0.78] vc
139.5013 -f
139.5014 -S
139.5015 -n
139.5016 -1932 2049.9 m
139.5017 -1932.3 2050.3 1932 2050.4 1932.8 2050.4 C
139.5018 -1932 2050.4 1932.2 2049.2 1931.3 2049.6 C
139.5019 -1931.4 2050.5 1930.3 2050.4 1930.4 2051.3 C
139.5020 -1931.1 2051.1 1930.7 2049.4 1932 2049.9 C
139.5021 -f
139.5022 -S
139.5023 -n
139.5024 -1938.3 2046 m
139.5025 -1936.3 2046.8 1935.2 2047.2 1934.2 2048.9 C
139.5026 -1935.3 2047.7 1936.8 2046.2 1938.3 2046 C
139.5027 -[0.4 0.4 0 0] vc
139.5028 -f
139.5029 -S
139.5030 -n
139.5031 -vmrs
139.5032 -1938.3 2047 m
139.5033 -1937.9 2046.9 1936.6 2047.1 1936.1 2048 C
139.5034 -1936.5 2047.5 1937.3 2046.7 1938.3 2047 C
139.5035 -[0.18 0.18 0 0.78] vc
139.5036 -f
139.5037 -0.4 w
139.5038 -2 J
139.5039 -2 M
139.5040 -S
139.5041 -n
139.5042 -1910.2 2043.2 m
139.5043 -1910.1 2037.5 1910 2031.8 1910 2026.1 C
139.5044 -1910 2031.8 1910.1 2037.5 1910.2 2043.2 C
139.5045 -f
139.5046 -S
139.5047 -n
139.5048 -1933.5 2032.1 m
139.5049 -1933.7 2035.2 1932.8 2035.8 1933.7 2038.6 C
139.5050 -1933.3 2036.6 1934.6 2018 1933.5 2032.1 C
139.5051 -f
139.5052 -S
139.5053 -n
139.5054 -1907.3 2021.8 m
139.5055 -1906.6 2025.9 1909.4 2032.6 1903.2 2034 C
139.5056 -1902.8 2034.1 1902.4 2033.9 1902 2033.8 C
139.5057 -1897.9 2028.5 1891.6 2023.8 1887.4 2018.7 C
139.5058 -1887.4 2017.7 1887.4 2016.6 1887.4 2015.6 C
139.5059 -1887 2016.3 1887.2 2017.8 1887.2 2018.9 C
139.5060 -1892.3 2024.4 1897.5 2028.5 1902.5 2034.3 C
139.5061 -1904.3 2033.6 1905.7 2032 1907.3 2030.9 C
139.5062 -1907.3 2027.9 1907.3 2024.9 1907.3 2021.8 C
139.5063 -f
139.5064 -S
139.5065 -n
139.5066 -1933.7 2023.2 m
139.5067 -1932 2021.7 1931.1 2024.9 1929.4 2024.9 C
139.5068 -1931.2 2024.7 1932.4 2021.5 1933.7 2023.2 C
139.5069 -f
139.5070 -S
139.5071 -n
139.5072 -1989.2 2024.4 m
139.5073 -1987.4 2023.7 1985.8 2022.2 1985.1 2020.4 C
139.5074 -1984.6 2020.1 1986 2018.9 1985.1 2019.2 C
139.5075 -1985.6 2020.8 1984.1 2019.4 1984.6 2021.1 C
139.5076 -1986.3 2022.3 1988.1 2025.3 1989.2 2024.4 C
139.5077 -f
139.5078 -S
139.5079 -n
139.5080 -1904.4 2031.9 m
139.5081 -1903 2029.7 1905.3 2027.7 1904.2 2025.9 C
139.5082 -1904.5 2025 1903.7 2023 1904 2021.3 C
139.5083 -1904 2022.3 1903.2 2022 1902.5 2022 C
139.5084 -1901.3 2022.3 1902.2 2020.1 1901.6 2019.6 C
139.5085 -1902.5 2019.8 1902.6 2018.3 1903.5 2018.9 C
139.5086 -1903.7 2021.8 1905.6 2016.8 1905.6 2020.6 C
139.5087 -1905.9 2020 1906.3 2020.8 1906.1 2021.1 C
139.5088 -1905.8 2022.7 1906.7 2020.4 1906.4 2019.9 C
139.5089 -1906.4 2018.5 1908.2 2017.8 1906.8 2016.5 C
139.5090 -1906.9 2015.7 1907.7 2017.1 1907.1 2016.3 C
139.5091 -1908.5 2015.8 1910.3 2015.1 1911.6 2016 C
139.5092 -1912.2 2016.2 1911.9 2018 1911.6 2018 C
139.5093 -1914.5 2017.1 1910.4 2013.6 1913.3 2013.4 C
139.5094 -1912.4 2011.3 1910.5 2011.8 1909.5 2010 C
139.5095 -1910 2010.5 1909 2010.8 1908.8 2011.2 C
139.5096 -1907.5 2009.9 1906.1 2011.7 1904.9 2011.5 C
139.5097 -1904.7 2010.9 1904.3 2010.5 1904.4 2009.8 C
139.5098 -1905 2010.2 1904.6 2008.6 1905.4 2008.1 C
139.5099 -1906.6 2007.5 1907.7 2008.4 1908.5 2007.4 C
139.5100 -1908.9 2008.5 1909.7 2008.1 1909 2007.2 C
139.5101 -1908.1 2006.5 1905.9 2007.3 1905.4 2007.4 C
139.5102 -1903.9 2007.3 1905.2 2008.5 1904.2 2008.4 C
139.5103 -1904.6 2009.9 1902.8 2010.3 1902.3 2010.5 C
139.5104 -1901.5 2009.9 1900.4 2010 1899.4 2010 C
139.5105 -1898.6 2011.2 1898.2 2013.4 1896.5 2013.4 C
139.5106 -1896 2012.9 1894.4 2012.9 1893.6 2012.9 C
139.5107 -1893.1 2013.9 1892.9 2015.5 1891.5 2016 C
139.5108 -1890.3 2016.1 1889.2 2014 1888.6 2015.8 C
139.5109 -1890 2016 1891 2016.9 1892.9 2016.5 C
139.5110 -1894.1 2017.2 1892.8 2018.3 1893.2 2018.9 C
139.5111 -1892.6 2018.9 1891.1 2019.8 1890.5 2020.6 C
139.5112 -1891.1 2023.6 1893.2 2019.8 1893.9 2022.5 C
139.5113 -1894.1 2023.3 1892.7 2023.6 1893.9 2024 C
139.5114 -1894.2 2024.3 1897.4 2023.8 1896.5 2026.1 C
139.5115 -1896 2025.6 1897.4 2028.1 1897.5 2027.1 C
139.5116 -1898.4 2027.4 1899.3 2027 1899.6 2028.5 C
139.5117 -1899.5 2028.6 1899.4 2028.8 1899.2 2028.8 C
139.5118 -1899.3 2029.2 1899.6 2029.8 1900.1 2030.2 C
139.5119 -1900.4 2029.6 1901 2030 1901.8 2030.2 C
139.5120 -1903.1 2032.1 1900.4 2031.5 1902.8 2033.1 C
139.5121 -1903.3 2032.7 1904.5 2032 1904.4 2031.9 C
139.5122 -[0.21 0.21 0 0] vc
139.5123 -f
139.5124 -S
139.5125 -n
139.5126 -1909.2 2019.4 m
139.5127 -1908.8 2020.3 1910.2 2019.8 1909.2 2019.2 C
139.5128 -1908.3 2019.3 1907.6 2020.2 1907.6 2021.3 C
139.5129 -1908.5 2021 1907.6 2019 1909.2 2019.4 C
139.5130 -[0.18 0.18 0 0.78] vc
139.5131 -f
139.5132 -S
139.5133 -n
139.5134 -1915.5 2015.6 m
139.5135 -1913.5 2016.3 1912.4 2016.8 1911.4 2018.4 C
139.5136 -1912.5 2017.2 1914 2015.7 1915.5 2015.6 C
139.5137 -[0.4 0.4 0 0] vc
139.5138 -f
139.5139 -S
139.5140 -n
139.5141 -1915.5 2016.5 m
139.5142 -1915.1 2016.4 1913.8 2016.6 1913.3 2017.5 C
139.5143 -1913.7 2017 1914.5 2016.2 1915.5 2016.5 C
139.5144 -[0.18 0.18 0 0.78] vc
139.5145 -f
139.5146 -S
139.5147 -n
139.5148 -vmrs
139.5149 -1887.4 2012.7 m
139.5150 -1887.3 2007 1887.2 2001.3 1887.2 1995.6 C
139.5151 -1887.2 2001.3 1887.3 2007 1887.4 2012.7 C
139.5152 -[0.18 0.18 0 0.78] vc
139.5153 -f
139.5154 -0.4 w
139.5155 -2 J
139.5156 -2 M
139.5157 -S
139.5158 -n
139.5159 -1935.9 2007.4 m
139.5160 -1936.2 2007.8 1935.8 2007.9 1936.6 2007.9 C
139.5161 -1935.9 2007.9 1936.1 2006.7 1935.2 2007.2 C
139.5162 -1935.2 2008.1 1934.1 2007.9 1934.2 2008.8 C
139.5163 -1935 2008.7 1934.6 2006.9 1935.9 2007.4 C
139.5164 -f
139.5165 -S
139.5166 -n
139.5167 -1942.1 2003.6 m
139.5168 -1940.1 2004.3 1939.1 2004.8 1938 2006.4 C
139.5169 -1939.1 2005.2 1940.6 2003.7 1942.1 2003.6 C
139.5170 -[0.4 0.4 0 0] vc
139.5171 -f
139.5172 -S
139.5173 -n
139.5174 -1942.1 2004.5 m
139.5175 -1941.8 2004.4 1940.4 2004.6 1940 2005.5 C
139.5176 -1940.4 2005 1941.2 2004.2 1942.1 2004.5 C
139.5177 -[0.18 0.18 0 0.78] vc
139.5178 -f
139.5179 -S
139.5180 -n
139.5181 -1914 2000.7 m
139.5182 -1914 1995 1913.9 1989.3 1913.8 1983.6 C
139.5183 -1913.9 1989.3 1914 1995 1914 2000.7 C
139.5184 -f
139.5185 -S
139.5186 -n
139.5187 -1941.6 1998.3 m
139.5188 -1943.4 2001.9 1942.4 1996 1940.9 1998.3 C
139.5189 -1941.2 1998.3 1941.4 1998.3 1941.6 1998.3 C
139.5190 -f
139.5191 -S
139.5192 -n
139.5193 -1954.8 1989.9 m
139.5194 -1953.9 1989.6 1954.7 1991.6 1953.9 1991.1 C
139.5195 -1954.5 1993.1 1953.6 1998 1954.6 1993.2 C
139.5196 -1954 1992.2 1954.7 1990.7 1954.8 1989.9 C
139.5197 -f
139.5198 -S
139.5199 -n
139.5200 -1947.6 1992.5 m
139.5201 -1946.2 1993.5 1944.9 1993 1944.8 1994.7 C
139.5202 -1945.5 1994 1947 1992.2 1947.6 1992.5 C
139.5203 -f
139.5204 -S
139.5205 -n
139.5206 -1910.7 1982.2 m
139.5207 -1910.3 1981.8 1909.7 1982 1909.2 1982 C
139.5208 -1909.7 1982 1910.3 1981.9 1910.7 1982.2 C
139.5209 -1911 1987.1 1910 1992.6 1910.7 1997.3 C
139.5210 -1910.7 1992.3 1910.7 1987.2 1910.7 1982.2 C
139.5211 -[0.65 0.65 0 0.42] vc
139.5212 -f
139.5213 -S
139.5214 -n
139.5215 -1910.9 1992.8 m
139.5216 -1910.9 1991.3 1910.9 1989.7 1910.9 1988.2 C
139.5217 -1910.9 1989.7 1910.9 1991.3 1910.9 1992.8 C
139.5218 -[0.18 0.18 0 0.78] vc
139.5219 -f
139.5220 -S
139.5221 -n
139.5222 -vmrs
139.5223 -1953.6 1983.6 m
139.5224 -1954.1 1985.3 1953.2 1988.6 1954.8 1989.4 C
139.5225 -1954.1 1987.9 1954.4 1985.4 1953.6 1983.6 C
139.5226 -[0.18 0.18 0 0.78] vc
139.5227 -f
139.5228 -0.4 w
139.5229 -2 J
139.5230 -2 M
139.5231 -S
139.5232 -n
139.5233 -1910.7 1982 m
139.5234 -1911.6 1982.9 1911 1984.4 1911.2 1985.6 C
139.5235 -1911 1984.4 1911.6 1982.9 1910.7 1982 C
139.5236 -f
139.5237 -S
139.5238 -n
139.5239 -1947.2 1979.6 m
139.5240 -1947.5 1980.6 1948.3 1980.6 1947.4 1979.6 C
139.5241 -1946.2 1979.4 1945.7 1978.8 1947.2 1979.6 C
139.5242 -f
139.5243 -S
139.5244 -n
139.5245 -1930.4 2061.4 m
139.5246 -1930.4 2058 1930.4 2053.5 1930.4 2051.1 C
139.5247 -1930.7 2054.6 1929.8 2057.4 1930.1 2061.2 C
139.5248 -1929.5 2061.9 1929.7 2061.2 1930.4 2061.4 C
139.5249 -[0.65 0.65 0 0.42] vc
139.5250 -f
139.5251 -S
139.5252 -n
139.5253 -1939.5 2044.8 m
139.5254 -1940 2041.5 1935.2 2044.3 1936.4 2040.8 C
139.5255 -1934.9 2040.9 1934.1 2039.7 1933.5 2038.6 C
139.5256 -1933.3 2035.4 1933.2 2040 1934 2040.3 C
139.5257 -1936.2 2040.6 1936.3 2043.6 1938.5 2043.4 C
139.5258 -1939.7 2044.2 1939.4 2045.6 1938.3 2046.5 C
139.5259 -1939.1 2046.6 1939.6 2045.6 1939.5 2044.8 C
139.5260 -f
139.5261 -S
139.5262 -n
139.5263 -1910.4 2045.3 m
139.5264 -1910.4 2039.5 1910.4 2033.6 1910.4 2027.8 C
139.5265 -1910.4 2033.6 1910.4 2039.5 1910.4 2045.3 C
139.5266 -f
139.5267 -S
139.5268 -n
139.5269 -1906.8 2030.9 m
139.5270 -1907.6 2026.8 1905 2020.8 1909 2018.7 C
139.5271 -1906.5 2018.9 1906.8 2022.4 1906.8 2024.7 C
139.5272 -1906.4 2028.2 1907.9 2032 1903 2033.8 C
139.5273 -1902.2 2034 1903.8 2033.4 1904.2 2033.1 C
139.5274 -1905.1 2032.4 1905.9 2031.5 1906.8 2030.9 C
139.5275 -[0.07 0.06 0 0.58] vc
139.5276 -f
139.5277 -S
139.5278 -n
139.5279 -1907.1 2030.7 m
139.5280 -1907.1 2028.8 1907.1 2027 1907.1 2025.2 C
139.5281 -1907.1 2027 1907.1 2028.8 1907.1 2030.7 C
139.5282 -[0.65 0.65 0 0.42] vc
139.5283 -f
139.5284 -S
139.5285 -n
139.5286 -1932 2023.2 m
139.5287 -1932.2 2023.6 1931.7 2023.7 1931.6 2024 C
139.5288 -1932 2023.7 1932.3 2022.8 1933 2023 C
139.5289 -1933.9 2024.3 1933.3 2026.2 1933.5 2027.8 C
139.5290 -1933.5 2026.4 1934.9 2022.2 1932 2023.2 C
139.5291 -f
139.5292 -S
139.5293 -n
139.5294 -2026.1 2021.6 m
139.5295 -2026.1 2020.8 2026.1 2019.9 2026.1 2019.2 C
139.5296 -2026.1 2019.9 2026.1 2020.8 2026.1 2021.6 C
139.5297 -f
139.5298 -S
139.5299 -n
139.5300 -vmrs
139.5301 -1934.2 2018.9 m
139.5302 -1934.2 2015.5 1934.2 2011 1934.2 2008.6 C
139.5303 -1934.5 2012.1 1933.7 2014.9 1934 2018.7 C
139.5304 -1933.4 2019.5 1933.5 2018.7 1934.2 2018.9 C
139.5305 -[0.65 0.65 0 0.42] vc
139.5306 -f
139.5307 -0.4 w
139.5308 -2 J
139.5309 -2 M
139.5310 -S
139.5311 -n
139.5312 -1887.6 2014.8 m
139.5313 -1887.6 2009 1887.6 2003.1 1887.6 1997.3 C
139.5314 -1887.6 2003.1 1887.6 2009 1887.6 2014.8 C
139.5315 -f
139.5316 -S
139.5317 -n
139.5318 -1914.3 2002.8 m
139.5319 -1914.3 1997 1914.3 1991.1 1914.3 1985.3 C
139.5320 -1914.3 1991.1 1914.3 1997 1914.3 2002.8 C
139.5321 -f
139.5322 -S
139.5323 -n
139.5324 -1995.4 1992.3 m
139.5325 -1995.4 1991.5 1995.4 1990.7 1995.4 1989.9 C
139.5326 -1995.4 1990.7 1995.4 1991.5 1995.4 1992.3 C
139.5327 -f
139.5328 -S
139.5329 -n
139.5330 -1896 1988.4 m
139.5331 -1896.9 1988 1897.8 1987.7 1898.7 1987.2 C
139.5332 -1897.8 1987.7 1896.9 1988 1896 1988.4 C
139.5333 -f
139.5334 -S
139.5335 -n
139.5336 -1899.4 1986.8 m
139.5337 -1900.4 1986.3 1901.3 1985.8 1902.3 1985.3 C
139.5338 -1901.3 1985.8 1900.4 1986.3 1899.4 1986.8 C
139.5339 -f
139.5340 -S
139.5341 -n
139.5342 -1902.8 1985.1 m
139.5343 -1905.2 1984 1905.2 1984 1902.8 1985.1 C
139.5344 -f
139.5345 -S
139.5346 -n
139.5347 -1949.1 1983.4 m
139.5348 -1950.2 1984.4 1947.8 1984.6 1949.3 1985.1 C
139.5349 -1949.5 1984.4 1949.6 1984.1 1949.1 1983.4 C
139.5350 -[0.07 0.06 0 0.58] vc
139.5351 -f
139.5352 -S
139.5353 -n
139.5354 -1906.1 1983.4 m
139.5355 -1908.6 1982 1908.6 1982 1906.1 1983.4 C
139.5356 -[0.65 0.65 0 0.42] vc
139.5357 -f
139.5358 -S
139.5359 -n
139.5360 -1922.7 1976.4 m
139.5361 -1923.6 1976 1924.4 1975.7 1925.3 1975.2 C
139.5362 -1924.4 1975.7 1923.6 1976 1922.7 1976.4 C
139.5363 -f
139.5364 -S
139.5365 -n
139.5366 -vmrs
139.5367 -1926 1974.8 m
139.5368 -1927 1974.3 1928 1973.8 1928.9 1973.3 C
139.5369 -1928 1973.8 1927 1974.3 1926 1974.8 C
139.5370 -[0.65 0.65 0 0.42] vc
139.5371 -f
139.5372 -0.4 w
139.5373 -2 J
139.5374 -2 M
139.5375 -S
139.5376 -n
139.5377 -1929.4 1973.1 m
139.5378 -1931.9 1972 1931.9 1972 1929.4 1973.1 C
139.5379 -f
139.5380 -S
139.5381 -n
139.5382 -1932.8 1971.4 m
139.5383 -1935.3 1970 1935.3 1970 1932.8 1971.4 C
139.5384 -f
139.5385 -S
139.5386 -n
139.5387 -1949.6 2097.2 m
139.5388 -1951.1 2096.4 1952.6 2095.5 1954.1 2094.8 C
139.5389 -1952.6 2095.5 1951.1 2096.4 1949.6 2097.2 C
139.5390 -[0.07 0.06 0 0.58] vc
139.5391 -f
139.5392 -S
139.5393 -n
139.5394 -1955.1 2094.3 m
139.5395 -1956.7 2093.5 1958.3 2092.7 1959.9 2091.9 C
139.5396 -1958.3 2092.7 1956.7 2093.5 1955.1 2094.3 C
139.5397 -f
139.5398 -S
139.5399 -n
139.5400 -1960.4 2091.6 m
139.5401 -1961.3 2091.2 1962.1 2090.9 1963 2090.4 C
139.5402 -1962.1 2090.9 1961.3 2091.2 1960.4 2091.6 C
139.5403 -f
139.5404 -S
139.5405 -n
139.5406 -1963.5 2090.2 m
139.5407 -1964.4 2089.7 1965.2 2089.2 1966.1 2088.8 C
139.5408 -1965.2 2089.2 1964.4 2089.7 1963.5 2090.2 C
139.5409 -f
139.5410 -S
139.5411 -n
139.5412 -1966.6 2088.5 m
139.5413 -1969.5 2087.1 1972.4 2085.8 1975.2 2084.4 C
139.5414 -1972.4 2085.8 1969.5 2087.1 1966.6 2088.5 C
139.5415 -f
139.5416 -S
139.5417 -n
139.5418 -1965.2 2086.1 m
139.5419 -1965.9 2085.7 1966.8 2085.3 1967.6 2084.9 C
139.5420 -1966.8 2085.3 1965.9 2085.7 1965.2 2086.1 C
139.5421 -f
139.5422 -S
139.5423 -n
139.5424 -1968.3 2084.7 m
139.5425 -1969.2 2084.3 1970 2083.9 1970.9 2083.5 C
139.5426 -1970 2083.9 1969.2 2084.3 1968.3 2084.7 C
139.5427 -f
139.5428 -S
139.5429 -n
139.5430 -vmrs
139.5431 -1984.1 2084 m
139.5432 -1985.6 2083.2 1987.2 2082.3 1988.7 2081.6 C
139.5433 -1987.2 2082.3 1985.6 2083.2 1984.1 2084 C
139.5434 -[0.07 0.06 0 0.58] vc
139.5435 -f
139.5436 -0.4 w
139.5437 -2 J
139.5438 -2 M
139.5439 -S
139.5440 -n
139.5441 -1976 2078.7 m
139.5442 -1978.1 2080.1 1980 2082 1982 2083.7 C
139.5443 -1980 2081.9 1977.9 2080.3 1976 2078.2 C
139.5444 -1975.5 2079.9 1975.8 2081.9 1975.7 2083.7 C
139.5445 -1975.8 2082 1975.5 2080.2 1976 2078.7 C
139.5446 -f
139.5447 -S
139.5448 -n
139.5449 -1989.6 2081.1 m
139.5450 -1991.3 2080.3 1992.8 2079.5 1994.4 2078.7 C
139.5451 -1992.8 2079.5 1991.3 2080.3 1989.6 2081.1 C
139.5452 -f
139.5453 -S
139.5454 -n
139.5455 -1933.2 2074.6 m
139.5456 -1932.4 2076.2 1932.8 2077.5 1933 2078.7 C
139.5457 -1933 2077.6 1932.9 2074.8 1933.2 2074.6 C
139.5458 -f
139.5459 -S
139.5460 -n
139.5461 -1994.9 2078.4 m
139.5462 -1995.8 2078 1996.7 2077.7 1997.6 2077.2 C
139.5463 -1996.7 2077.7 1995.8 2078 1994.9 2078.4 C
139.5464 -f
139.5465 -S
139.5466 -n
139.5467 -1998 2077 m
139.5468 -1998.9 2076.5 1999.8 2076 2000.7 2075.6 C
139.5469 -1999.8 2076 1998.9 2076.5 1998 2077 C
139.5470 -f
139.5471 -S
139.5472 -n
139.5473 -2001.2 2075.3 m
139.5474 -2004 2073.9 2006.9 2072.6 2009.8 2071.2 C
139.5475 -2006.9 2072.6 2004 2073.9 2001.2 2075.3 C
139.5476 -f
139.5477 -S
139.5478 -n
139.5479 -1980.5 2060.7 m
139.5480 -1979.9 2060.7 1976.7 2062.8 1975.7 2064.5 C
139.5481 -1975.7 2067.5 1975.7 2070.5 1975.7 2073.4 C
139.5482 -1976.3 2068.7 1973.9 2061.6 1980.5 2060.7 C
139.5483 -f
139.5484 -S
139.5485 -n
139.5486 -1999.7 2072.9 m
139.5487 -2000.5 2072.5 2001.3 2072.1 2002.1 2071.7 C
139.5488 -2001.3 2072.1 2000.5 2072.5 1999.7 2072.9 C
139.5489 -f
139.5490 -S
139.5491 -n
139.5492 -2002.8 2071.5 m
139.5493 -2003.7 2071.1 2004.6 2070.7 2005.5 2070.3 C
139.5494 -2004.6 2070.7 2003.7 2071.1 2002.8 2071.5 C
139.5495 -f
139.5496 -S
139.5497 -n
139.5498 -vmrs
139.5499 -2015.1 2047.5 m
139.5500 -2014.4 2047.5 2011.2 2049.6 2010.3 2051.3 C
139.5501 -2010.3 2057.7 2010.3 2064.1 2010.3 2070.5 C
139.5502 -2010.3 2063.9 2010.1 2057.1 2010.5 2050.6 C
139.5503 -2012 2049.3 2013.5 2048.3 2015.1 2047.5 C
139.5504 -[0.07 0.06 0 0.58] vc
139.5505 -f
139.5506 -0.4 w
139.5507 -2 J
139.5508 -2 M
139.5509 -S
139.5510 -n
139.5511 -1910.4 2049.2 m
139.5512 -1914.8 2054.3 1920.7 2058.9 1925.1 2064 C
139.5513 -1920.4 2058.6 1915.1 2054.6 1910.4 2049.2 C
139.5514 -f
139.5515 -S
139.5516 -n
139.5517 -1988.2 2057.3 m
139.5518 -1989.1 2056.8 1989.9 2056.2 1990.8 2055.6 C
139.5519 -1989.9 2056.2 1989.1 2056.8 1988.2 2057.3 C
139.5520 -f
139.5521 -S
139.5522 -n
139.5523 -1991.6 2051.3 m
139.5524 -1991.6 2046.3 1991.6 2041.2 1991.6 2036.2 C
139.5525 -1991.6 2041.2 1991.6 2046.3 1991.6 2051.3 C
139.5526 -f
139.5527 -S
139.5528 -n
139.5529 -1935.6 2047.5 m
139.5530 -1932.9 2051.7 1939.7 2043.8 1935.6 2047.5 C
139.5531 -f
139.5532 -S
139.5533 -n
139.5534 -1938.8 2043.9 m
139.5535 -1938.1 2043.3 1938.2 2043.7 1937.3 2043.4 C
139.5536 -1938.7 2043 1938.2 2044.9 1939 2045.3 C
139.5537 -1938.2 2045.3 1938.7 2046.6 1937.8 2046.5 C
139.5538 -1939.1 2046.2 1939.1 2044.5 1938.8 2043.9 C
139.5539 -f
139.5540 -S
139.5541 -n
139.5542 -1972.4 2045.6 m
139.5543 -1973.4 2045 1974.5 2044.4 1975.5 2043.9 C
139.5544 -1974.5 2044.4 1973.4 2045 1972.4 2045.6 C
139.5545 -f
139.5546 -S
139.5547 -n
139.5548 -1969 2043.6 m
139.5549 -1969.8 2043.2 1970.6 2042.9 1971.4 2042.4 C
139.5550 -1970.6 2042.9 1969.8 2043.2 1969 2043.6 C
139.5551 -f
139.5552 -S
139.5553 -n
139.5554 -1972.1 2042.2 m
139.5555 -1973 2041.8 1973.9 2041.4 1974.8 2041 C
139.5556 -1973.9 2041.4 1973 2041.8 1972.1 2042.2 C
139.5557 -f
139.5558 -S
139.5559 -n
139.5560 -1906.6 2035 m
139.5561 -1905 2034.7 1904.8 2036.6 1903.5 2036.9 C
139.5562 -1904.9 2037 1905.8 2033.4 1907.1 2035.7 C
139.5563 -1907.1 2037.2 1907.1 2038.6 1907.1 2040 C
139.5564 -1906.9 2038.4 1907.5 2036.4 1906.6 2035 C
139.5565 -f
139.5566 -S
139.5567 -n
139.5568 -vmrs
139.5569 -1937.1 2032.1 m
139.5570 -1936.2 2033.7 1936.6 2035 1936.8 2036.2 C
139.5571 -1936.8 2035.1 1936.8 2032.4 1937.1 2032.1 C
139.5572 -[0.07 0.06 0 0.58] vc
139.5573 -f
139.5574 -0.4 w
139.5575 -2 J
139.5576 -2 M
139.5577 -S
139.5578 -n
139.5579 -1887.6 2018.7 m
139.5580 -1892 2023.8 1897.9 2028.4 1902.3 2033.6 C
139.5581 -1897.6 2028.1 1892.3 2024.1 1887.6 2018.7 C
139.5582 -f
139.5583 -S
139.5584 -n
139.5585 -1999.7 2031.4 m
139.5586 -1998.7 2030.3 1997.6 2029.2 1996.6 2028 C
139.5587 -1997.6 2029.2 1998.7 2030.3 1999.7 2031.4 C
139.5588 -f
139.5589 -S
139.5590 -n
139.5591 -1912.8 2017 m
139.5592 -1910.6 2021.1 1913.6 2015.3 1914.5 2016 C
139.5593 -1914 2016.3 1913.4 2016.7 1912.8 2017 C
139.5594 -f
139.5595 -S
139.5596 -n
139.5597 -1939.5 2005 m
139.5598 -1936.7 2009.2 1943.6 2001.3 1939.5 2005 C
139.5599 -f
139.5600 -S
139.5601 -n
139.5602 -1942.6 2001.4 m
139.5603 -1941.9 2000.8 1942 2001.2 1941.2 2000.9 C
139.5604 -1942.5 2000.6 1942.1 2002.4 1942.8 2002.8 C
139.5605 -1942 2002.8 1942.5 2004.1 1941.6 2004 C
139.5606 -1943 2003.7 1942.9 2002.1 1942.6 2001.4 C
139.5607 -f
139.5608 -S
139.5609 -n
139.5610 -2006.2 2000.7 m
139.5611 -2005.4 2001.5 2004 2002.8 2004 2002.8 C
139.5612 -2004.5 2002.4 2005.5 2001.4 2006.2 2000.7 C
139.5613 -f
139.5614 -S
139.5615 -n
139.5616 -1998.5 2001.6 m
139.5617 -1997.7 2002 1996.8 2002.4 1995.9 2002.6 C
139.5618 -1995.5 1999.3 1995.7 1995.7 1995.6 1992.3 C
139.5619 -1995.6 1995.7 1995.6 1999.2 1995.6 2002.6 C
139.5620 -1996.6 2002.4 1997.7 2002.2 1998.5 2001.6 C
139.5621 -[0.4 0.4 0 0] vc
139.5622 -f
139.5623 -S
139.5624 -n
139.5625 -1996.1 2002.8 m
139.5626 -1995.9 2002.8 1995.8 2002.8 1995.6 2002.8 C
139.5627 -1995.2 1999.5 1995.5 1995.9 1995.4 1992.5 C
139.5628 -1995.4 1995.9 1995.4 1999.4 1995.4 2002.8 C
139.5629 -1996.4 2003.1 1998.2 2001.6 1996.1 2002.8 C
139.5630 -[0.07 0.06 0 0.58] vc
139.5631 -f
139.5632 -S
139.5633 -n
139.5634 -1969 2002.1 m
139.5635 -1968 2001 1966.9 1999.9 1965.9 1998.8 C
139.5636 -1966.9 1999.9 1968 2001 1969 2002.1 C
139.5637 -f
139.5638 -S
139.5639 -n
139.5640 -vmrs
139.5641 -2000 2001.2 m
139.5642 -2002.1 2000 2004.1 1998.9 2006.2 1997.8 C
139.5643 -2004.1 1998.9 2002.1 2000 2000 2001.2 C
139.5644 -[0.07 0.06 0 0.58] vc
139.5645 -f
139.5646 -0.4 w
139.5647 -2 J
139.5648 -2 M
139.5649 -S
139.5650 -n
139.5651 -1895.8 1984.8 m
139.5652 -1898.3 1983.6 1900.8 1982.3 1903.2 1981 C
139.5653 -1900.8 1982.3 1898.3 1983.6 1895.8 1984.8 C
139.5654 -f
139.5655 -S
139.5656 -n
139.5657 -1905.2 1980.3 m
139.5658 -1906.4 1979.9 1907.6 1979.5 1908.8 1979.1 C
139.5659 -1907.6 1979.5 1906.4 1979.9 1905.2 1980.3 C
139.5660 -f
139.5661 -S
139.5662 -n
139.5663 -1964.7 1977.4 m
139.5664 -1963.8 1977.5 1962.5 1980.2 1960.8 1980 C
139.5665 -1962.5 1980.2 1963.3 1978 1964.7 1977.4 C
139.5666 -f
139.5667 -S
139.5668 -n
139.5669 -1952 1979.6 m
139.5670 -1955.2 1979.2 1955.2 1979.2 1952 1979.6 C
139.5671 -f
139.5672 -S
139.5673 -n
139.5674 -1937.8 1966.4 m
139.5675 -1941.2 1969.5 1946.1 1976.4 1951.5 1979.3 C
139.5676 -1946.1 1976.7 1942.8 1970.4 1937.8 1966.4 C
139.5677 -f
139.5678 -S
139.5679 -n
139.5680 -1911.9 1978.6 m
139.5681 -1914.3 1977.4 1916.7 1976.2 1919.1 1975 C
139.5682 -1916.7 1976.2 1914.3 1977.4 1911.9 1978.6 C
139.5683 -f
139.5684 -S
139.5685 -n
139.5686 -1975.5 1971.4 m
139.5687 -1974.6 1972.2 1973.3 1973.6 1973.3 1973.6 C
139.5688 -1973.7 1973.1 1974.8 1972.1 1975.5 1971.4 C
139.5689 -f
139.5690 -S
139.5691 -n
139.5692 -1922.4 1972.8 m
139.5693 -1924.9 1971.6 1927.4 1970.3 1929.9 1969 C
139.5694 -1927.4 1970.3 1924.9 1971.6 1922.4 1972.8 C
139.5695 -f
139.5696 -S
139.5697 -n
139.5698 -1969.2 1971.9 m
139.5699 -1971.1 1970.9 1972.9 1969.8 1974.8 1968.8 C
139.5700 -1972.9 1969.8 1971.1 1970.9 1969.2 1971.9 C
139.5701 -f
139.5702 -S
139.5703 -n
139.5704 -vmrs
139.5705 -1931.8 1968.3 m
139.5706 -1933 1967.9 1934.2 1967.5 1935.4 1967.1 C
139.5707 -1934.2 1967.5 1933 1967.9 1931.8 1968.3 C
139.5708 -[0.07 0.06 0 0.58] vc
139.5709 -f
139.5710 -0.4 w
139.5711 -2 J
139.5712 -2 M
139.5713 -S
139.5714 -n
139.5715 -1940.7 2072.4 m
139.5716 -1941.5 2072.4 1942.3 2072.3 1943.1 2072.2 C
139.5717 -1942.3 2072.3 1941.5 2072.4 1940.7 2072.4 C
139.5718 -[0 0 0 0.18] vc
139.5719 -f
139.5720 -S
139.5721 -n
139.5722 -1948.6 2069.3 m
139.5723 -1947 2069.5 1945.7 2068.9 1944.8 2069.8 C
139.5724 -1945.9 2068.5 1948.4 2070.2 1948.6 2069.3 C
139.5725 -f
139.5726 -S
139.5727 -n
139.5728 -1954.6 2066.4 m
139.5729 -1954.7 2067.9 1955.6 2067.3 1955.6 2068.8 C
139.5730 -1955.4 2067.8 1956 2066.6 1954.6 2066.4 C
139.5731 -f
139.5732 -S
139.5733 -n
139.5734 -1929.2 2061.2 m
139.5735 -1927.8 2062.1 1926.3 2064.1 1924.8 2063.3 C
139.5736 -1926.3 2064.6 1928 2062 1929.2 2061.2 C
139.5737 -f
139.5738 -S
139.5739 -n
139.5740 -1924.4 2067.4 m
139.5741 -1918.5 2061.6 1912.7 2055.9 1906.8 2050.1 C
139.5742 -1912.7 2055.9 1918.5 2061.6 1924.4 2067.4 C
139.5743 -[0.4 0.4 0 0] vc
139.5744 -f
139.5745 -S
139.5746 -n
139.5747 -1924.6 2062.8 m
139.5748 -1923.9 2062.1 1923.2 2061.2 1922.4 2060.4 C
139.5749 -1923.2 2061.2 1923.9 2062.1 1924.6 2062.8 C
139.5750 -[0 0 0 0.18] vc
139.5751 -f
139.5752 -S
139.5753 -n
139.5754 -1919.3 2057.3 m
139.5755 -1917.5 2055.6 1915.7 2053.8 1913.8 2052 C
139.5756 -1915.7 2053.8 1917.5 2055.6 1919.3 2057.3 C
139.5757 -f
139.5758 -S
139.5759 -n
139.5760 -1929.2 2055.2 m
139.5761 -1929.2 2054.2 1929.2 2053.2 1929.2 2052.3 C
139.5762 -1929.2 2053.2 1929.2 2054.2 1929.2 2055.2 C
139.5763 -f
139.5764 -S
139.5765 -n
139.5766 -1926.3 2049.6 m
139.5767 -1925.4 2049 1925.4 2050.5 1924.4 2050.4 C
139.5768 -1925.3 2051.3 1924.5 2051.9 1925.6 2052.5 C
139.5769 -1926.9 2052.6 1926 2050.6 1926.3 2049.6 C
139.5770 -f
139.5771 -S
139.5772 -n
139.5773 -vmrs
139.5774 -1911.2 2046.8 m
139.5775 -1910.1 2048.9 1911.9 2050.1 1913.1 2051.3 C
139.5776 -1912.1 2049.9 1910.6 2048.8 1911.2 2046.8 C
139.5777 -[0 0 0 0.18] vc
139.5778 -f
139.5779 -0.4 w
139.5780 -2 J
139.5781 -2 M
139.5782 -S
139.5783 -n
139.5784 -1934 2048.7 m
139.5785 -1932.6 2048.7 1930.1 2047.7 1929.6 2049.4 C
139.5786 -1930.9 2048.6 1933.3 2049 1934 2048.7 C
139.5787 -f
139.5788 -S
139.5789 -n
139.5790 -1980 2048.4 m
139.5791 -1979.5 2046.8 1976.3 2047.9 1977.2 2045.6 C
139.5792 -1976.8 2045.1 1976.1 2044.7 1975.2 2044.8 C
139.5793 -1973.7 2046 1976.3 2046.4 1976.7 2047.5 C
139.5794 -1977.8 2047.2 1978.2 2050 1979.6 2049.2 C
139.5795 -1980 2049 1979.6 2048.6 1980 2048.4 C
139.5796 -f
139.5797 -S
139.5798 -n
139.5799 -1938.3 2045.6 m
139.5800 -1938.2 2044.4 1936.8 2043.8 1935.9 2043.4 C
139.5801 -1936.4 2044.4 1939.1 2044.3 1937.6 2045.8 C
139.5802 -1937 2046.1 1935.9 2046.1 1935.9 2046.8 C
139.5803 -1936.7 2046.3 1937.8 2046.2 1938.3 2045.6 C
139.5804 -f
139.5805 -S
139.5806 -n
139.5807 -1932.5 2040 m
139.5808 -1932.8 2038.1 1932 2038.9 1932.3 2040.3 C
139.5809 -1933.1 2040.3 1932.7 2041.7 1933.7 2041.5 C
139.5810 -1933.1 2041 1932.9 2040.5 1932.5 2040 C
139.5811 -f
139.5812 -S
139.5813 -n
139.5814 -2014.6 2035.2 m
139.5815 -2014.1 2033.6 2010.9 2034.7 2011.7 2032.4 C
139.5816 -2011.3 2031.9 2009.4 2030.7 2009.3 2032.1 C
139.5817 -2009.5 2033.7 2012.9 2033.8 2012.4 2035.7 C
139.5818 -2013 2036.4 2014.2 2036.5 2014.6 2035.2 C
139.5819 -f
139.5820 -S
139.5821 -n
139.5822 -1906.4 2030.7 m
139.5823 -1905 2031.6 1903.5 2033.6 1902 2032.8 C
139.5824 -1903.4 2034 1905.6 2031.4 1906.4 2030.7 C
139.5825 -f
139.5826 -S
139.5827 -n
139.5828 -1901.8 2037.2 m
139.5829 -1899.5 2034.8 1897.2 2032.5 1894.8 2030.2 C
139.5830 -1897.2 2032.5 1899.5 2034.8 1901.8 2037.2 C
139.5831 -[0.4 0.4 0 0] vc
139.5832 -f
139.5833 -S
139.5834 -n
139.5835 -1901.8 2032.4 m
139.5836 -1901.1 2031.6 1900.4 2030.7 1899.6 2030 C
139.5837 -1900.4 2030.7 1901.1 2031.6 1901.8 2032.4 C
139.5838 -[0 0 0 0.18] vc
139.5839 -f
139.5840 -S
139.5841 -n
139.5842 -1944.5 2030 m
139.5843 -1945.3 2029.9 1946.1 2029.8 1946.9 2029.7 C
139.5844 -1946.1 2029.8 1945.3 2029.9 1944.5 2030 C
139.5845 -f
139.5846 -S
139.5847 -n
139.5848 -vmrs
139.5849 -1997.8 2027.8 m
139.5850 -1997.7 2027.9 1997.6 2028.1 1997.3 2028 C
139.5851 -1997.4 2029.1 1998.5 2029.5 1999.2 2030 C
139.5852 -2000.1 2029.5 1998.9 2028 1997.8 2027.8 C
139.5853 -[0 0 0 0.18] vc
139.5854 -f
139.5855 -0.4 w
139.5856 -2 J
139.5857 -2 M
139.5858 -S
139.5859 -n
139.5860 -1906.4 2029.2 m
139.5861 -1906.4 2026.6 1906.4 2024 1906.4 2021.3 C
139.5862 -1906.4 2024 1906.4 2026.6 1906.4 2029.2 C
139.5863 -f
139.5864 -S
139.5865 -n
139.5866 -2006.2 2025.9 m
139.5867 -2006 2025.9 2005.8 2025.8 2005.7 2025.6 C
139.5868 -2005.7 2025.5 2005.7 2025.3 2005.7 2025.2 C
139.5869 -2004.6 2025.8 2002.7 2024.7 2001.9 2026.1 C
139.5870 -2001.9 2027.9 2007.8 2029.2 2006.2 2025.9 C
139.5871 -[0 0 0 0] vc
139.5872 -f
139.5873 -S
139.5874 -n
139.5875 -1952.4 2026.8 m
139.5876 -1950.9 2027 1949.6 2026.4 1948.6 2027.3 C
139.5877 -1949.7 2026.1 1952.2 2027.7 1952.4 2026.8 C
139.5878 -[0 0 0 0.18] vc
139.5879 -f
139.5880 -S
139.5881 -n
139.5882 -1896.5 2026.8 m
139.5883 -1894.7 2025.1 1892.9 2023.3 1891 2021.6 C
139.5884 -1892.9 2023.3 1894.7 2025.1 1896.5 2026.8 C
139.5885 -f
139.5886 -S
139.5887 -n
139.5888 -1958.4 2024 m
139.5889 -1958.5 2025.5 1959.4 2024.8 1959.4 2026.4 C
139.5890 -1959.3 2025.3 1959.8 2024.1 1958.4 2024 C
139.5891 -f
139.5892 -S
139.5893 -n
139.5894 -1903.5 2019.2 m
139.5895 -1902.6 2018.6 1902.6 2020 1901.6 2019.9 C
139.5896 -1902.5 2020.8 1901.7 2021.4 1902.8 2022 C
139.5897 -1904.1 2022.2 1903.2 2020.1 1903.5 2019.2 C
139.5898 -f
139.5899 -S
139.5900 -n
139.5901 -1933 2018.7 m
139.5902 -1931.7 2019.6 1930.1 2021.6 1928.7 2020.8 C
139.5903 -1930.1 2022.1 1931.8 2019.5 1933 2018.7 C
139.5904 -f
139.5905 -S
139.5906 -n
139.5907 -1888.4 2016.3 m
139.5908 -1887.3 2018.4 1889.1 2019.6 1890.3 2020.8 C
139.5909 -1889.3 2019.5 1887.8 2018.3 1888.4 2016.3 C
139.5910 -f
139.5911 -S
139.5912 -n
139.5913 -1928.4 2020.4 m
139.5914 -1927.7 2019.6 1927 2018.7 1926.3 2018 C
139.5915 -1927 2018.7 1927.7 2019.6 1928.4 2020.4 C
139.5916 -f
139.5917 -S
139.5918 -n
139.5919 -vmrs
139.5920 -1911.2 2018.2 m
139.5921 -1909.8 2018.3 1907.3 2017.2 1906.8 2018.9 C
139.5922 -1908.1 2018.1 1910.5 2018.6 1911.2 2018.2 C
139.5923 -[0 0 0 0.18] vc
139.5924 -f
139.5925 -0.4 w
139.5926 -2 J
139.5927 -2 M
139.5928 -S
139.5929 -n
139.5930 -1915.5 2015.1 m
139.5931 -1915.4 2013.9 1914 2013.3 1913.1 2012.9 C
139.5932 -1913.6 2013.9 1916.3 2013.8 1914.8 2015.3 C
139.5933 -1914.2 2015.6 1913.1 2015.6 1913.1 2016.3 C
139.5934 -1913.9 2015.9 1915 2015.7 1915.5 2015.1 C
139.5935 -f
139.5936 -S
139.5937 -n
139.5938 -1923.2 2014.8 m
139.5939 -1921.3 2013.1 1919.5 2011.3 1917.6 2009.6 C
139.5940 -1919.5 2011.3 1921.3 2013.1 1923.2 2014.8 C
139.5941 -f
139.5942 -S
139.5943 -n
139.5944 -1933 2012.7 m
139.5945 -1933 2011.7 1933 2010.8 1933 2009.8 C
139.5946 -1933 2010.8 1933 2011.7 1933 2012.7 C
139.5947 -f
139.5948 -S
139.5949 -n
139.5950 -1909.7 2008.1 m
139.5951 -1908.9 2009.2 1910.1 2009.9 1910.4 2011 C
139.5952 -1911.1 2010.7 1908.9 2009.7 1909.7 2008.1 C
139.5953 -f
139.5954 -S
139.5955 -n
139.5956 -1930.1 2007.2 m
139.5957 -1929.2 2006.6 1929.2 2008 1928.2 2007.9 C
139.5958 -1929.1 2008.8 1928.4 2009.4 1929.4 2010 C
139.5959 -1930.7 2010.2 1929.9 2008.1 1930.1 2007.2 C
139.5960 -f
139.5961 -S
139.5962 -n
139.5963 -1915 2004.3 m
139.5964 -1914 2006.4 1915.7 2007.6 1916.9 2008.8 C
139.5965 -1915.9 2007.5 1914.4 2006.3 1915 2004.3 C
139.5966 -f
139.5967 -S
139.5968 -n
139.5969 -1937.8 2006.2 m
139.5970 -1936.4 2006.3 1934 2005.2 1933.5 2006.9 C
139.5971 -1934.7 2006.1 1937.1 2006.6 1937.8 2006.2 C
139.5972 -f
139.5973 -S
139.5974 -n
139.5975 -1983.9 2006 m
139.5976 -1983.3 2004.3 1980.2 2005.4 1981 2003.1 C
139.5977 -1980.6 2002.7 1978.7 2001.5 1978.6 2002.8 C
139.5978 -1978.8 2004.4 1982.1 2004.5 1981.7 2006.4 C
139.5979 -1982.3 2007.2 1983.5 2007.2 1983.9 2006 C
139.5980 -f
139.5981 -S
139.5982 -n
139.5983 -1942.1 2003.1 m
139.5984 -1942 2001.9 1940.6 2001.3 1939.7 2000.9 C
139.5985 -1940.2 2001.9 1943 2001.8 1941.4 2003.3 C
139.5986 -1940.9 2003.6 1939.7 2003.6 1939.7 2004.3 C
139.5987 -1940.5 2003.9 1941.6 2003.7 1942.1 2003.1 C
139.5988 -f
139.5989 -S
139.5990 -n
139.5991 -vmrs
139.5992 -1967.1 1998.5 m
139.5993 -1967 1998.6 1966.8 1998.8 1966.6 1998.8 C
139.5994 -1966.7 1999.8 1967.8 2000.2 1968.5 2000.7 C
139.5995 -1969.4 2000.2 1968.2 1998.8 1967.1 1998.5 C
139.5996 -[0 0 0 0.18] vc
139.5997 -f
139.5998 -0.4 w
139.5999 -2 J
139.6000 -2 M
139.6001 -S
139.6002 -n
139.6003 -1936.4 1997.6 m
139.6004 -1936.7 1995.6 1935.8 1996.4 1936.1 1997.8 C
139.6005 -1936.9 1997.9 1936.5 1999.2 1937.6 1999 C
139.6006 -1937 1998.5 1936.8 1998 1936.4 1997.6 C
139.6007 -f
139.6008 -S
139.6009 -n
139.6010 -1975.5 1996.6 m
139.6011 -1975.2 1996.7 1975.1 1996.5 1975 1996.4 C
139.6012 -1975 1996.2 1975 1996.1 1975 1995.9 C
139.6013 -1973.9 1996.5 1972 1995.5 1971.2 1996.8 C
139.6014 -1971.2 1998.6 1977 1999.9 1975.5 1996.6 C
139.6015 -[0 0 0 0] vc
139.6016 -f
139.6017 -S
139.6018 -n
139.6019 -1949.3 2097.4 m
139.6020 -1950.3 2096.9 1951.2 2096.4 1952.2 2096 C
139.6021 -1951.2 2096.4 1950.3 2096.9 1949.3 2097.4 C
139.6022 -[0.4 0.4 0 0] vc
139.6023 -f
139.6024 -S
139.6025 -n
139.6026 -1960.8 2091.6 m
139.6027 -1961.7 2091.2 1962.6 2090.9 1963.5 2090.4 C
139.6028 -1962.6 2090.9 1961.7 2091.2 1960.8 2091.6 C
139.6029 -f
139.6030 -S
139.6031 -n
139.6032 -1964.4 2090 m
139.6033 -1965.7 2089.2 1967 2088.5 1968.3 2087.8 C
139.6034 -1967 2088.5 1965.7 2089.2 1964.4 2090 C
139.6035 -f
139.6036 -S
139.6037 -n
139.6038 -1976 2083.7 m
139.6039 -1976.3 2082.3 1975.2 2079.1 1976.9 2079.4 C
139.6040 -1978.8 2080.7 1980.3 2082.9 1982.2 2084.2 C
139.6041 -1980.6 2083.1 1978.2 2080.2 1976 2078.9 C
139.6042 -1975.6 2081.2 1977 2084.9 1973.8 2085.4 C
139.6043 -1972.2 2086.1 1970.7 2087 1969 2087.6 C
139.6044 -1971.4 2086.5 1974.1 2085.6 1976 2083.7 C
139.6045 -f
139.6046 -S
139.6047 -n
139.6048 -1983.9 2084.2 m
139.6049 -1984.8 2083.7 1985.8 2083.2 1986.8 2082.8 C
139.6050 -1985.8 2083.2 1984.8 2083.7 1983.9 2084.2 C
139.6051 -f
139.6052 -S
139.6053 -n
139.6054 -1995.4 2078.4 m
139.6055 -1996.3 2078 1997.1 2077.7 1998 2077.2 C
139.6056 -1997.1 2077.7 1996.3 2078 1995.4 2078.4 C
139.6057 -f
139.6058 -S
139.6059 -n
139.6060 -1999 2076.8 m
139.6061 -2000.3 2076 2001.6 2075.3 2002.8 2074.6 C
139.6062 -2001.6 2075.3 2000.3 2076 1999 2076.8 C
139.6063 -f
139.6064 -S
139.6065 -n
139.6066 -vmrs
139.6067 -1929.6 2065.7 m
139.6068 -1930.1 2065.6 1929.8 2068.6 1929.9 2070 C
139.6069 -1929.8 2068.6 1930.1 2067 1929.6 2065.7 C
139.6070 -[0.4 0.4 0 0] vc
139.6071 -f
139.6072 -0.4 w
139.6073 -2 J
139.6074 -2 M
139.6075 -S
139.6076 -n
139.6077 -1906.6 2049.4 m
139.6078 -1906.6 2046.7 1906.6 2043.9 1906.6 2041.2 C
139.6079 -1906.6 2043.9 1906.6 2046.7 1906.6 2049.4 C
139.6080 -f
139.6081 -S
139.6082 -n
139.6083 -2016 2047.5 m
139.6084 -2014.8 2048 2013.5 2048.3 2012.4 2049.4 C
139.6085 -2013.5 2048.3 2014.8 2048 2016 2047.5 C
139.6086 -f
139.6087 -S
139.6088 -n
139.6089 -2016.5 2047.2 m
139.6090 -2017.3 2046.9 2018.1 2046.6 2018.9 2046.3 C
139.6091 -2018.1 2046.6 2017.3 2046.9 2016.5 2047.2 C
139.6092 -f
139.6093 -S
139.6094 -n
139.6095 -1912.4 2028.5 m
139.6096 -1911.8 2032.4 1912.4 2037.2 1911.9 2041.2 C
139.6097 -1911.5 2037.2 1911.7 2032.9 1911.6 2028.8 C
139.6098 -1911.6 2033.5 1911.6 2038.9 1911.6 2042.9 C
139.6099 -1912.5 2042.2 1911.6 2043.9 1912.6 2043.6 C
139.6100 -1912.9 2039.3 1913.1 2033.3 1912.4 2028.5 C
139.6101 -[0.21 0.21 0 0] vc
139.6102 -f
139.6103 -S
139.6104 -n
139.6105 -1906.8 2040.8 m
139.6106 -1906.8 2039 1906.8 2037.2 1906.8 2035.5 C
139.6107 -1906.8 2037.2 1906.8 2039 1906.8 2040.8 C
139.6108 -[0.4 0.4 0 0] vc
139.6109 -f
139.6110 -S
139.6111 -n
139.6112 -1905.9 2035.2 m
139.6113 -1904.9 2036.4 1903.7 2037.2 1902.3 2037.4 C
139.6114 -1903.7 2037.2 1904.9 2036.4 1905.9 2035.2 C
139.6115 -f
139.6116 -S
139.6117 -n
139.6118 -1906.1 2031.2 m
139.6119 -1907 2031.1 1906.4 2028 1906.6 2030.7 C
139.6120 -1905.5 2032.1 1904 2032.8 1902.5 2033.6 C
139.6121 -1903.9 2033.2 1905 2032.1 1906.1 2031.2 C
139.6122 -f
139.6123 -S
139.6124 -n
139.6125 -1908.3 2018.7 m
139.6126 -1905.2 2018.6 1907.1 2023.2 1906.6 2025.4 C
139.6127 -1906.8 2023 1905.9 2019.5 1908.3 2018.7 C
139.6128 -f
139.6129 -S
139.6130 -n
139.6131 -1889.6 1998 m
139.6132 -1889 2001.9 1889.6 2006.7 1889.1 2010.8 C
139.6133 -1888.7 2006.7 1888.9 2002.4 1888.8 1998.3 C
139.6134 -1888.8 2003 1888.8 2008.4 1888.8 2012.4 C
139.6135 -1889.7 2011.7 1888.8 2013.4 1889.8 2013.2 C
139.6136 -1890.1 2008.8 1890.3 2002.8 1889.6 1998 C
139.6137 -[0.21 0.21 0 0] vc
139.6138 -f
139.6139 -S
139.6140 -n
139.6141 -vmrs
139.6142 -1999 2001.4 m
139.6143 -2001 2000.3 2003 1999.2 2005 1998 C
139.6144 -2003 1999.2 2001 2000.3 1999 2001.4 C
139.6145 -[0.4 0.4 0 0] vc
139.6146 -f
139.6147 -0.4 w
139.6148 -2 J
139.6149 -2 M
139.6150 -S
139.6151 -n
139.6152 -1916.2 1986 m
139.6153 -1915.7 1989.9 1916.3 1994.7 1915.7 1998.8 C
139.6154 -1915.3 1994.7 1915.5 1990.4 1915.5 1986.3 C
139.6155 -1915.5 1991 1915.5 1996.4 1915.5 2000.4 C
139.6156 -1916.3 1999.7 1915.5 2001.4 1916.4 2001.2 C
139.6157 -1916.7 1996.8 1917 1990.8 1916.2 1986 C
139.6158 -[0.21 0.21 0 0] vc
139.6159 -f
139.6160 -S
139.6161 -n
139.6162 -1886.9 1989.6 m
139.6163 -1887.8 1989.2 1888.7 1988.9 1889.6 1988.4 C
139.6164 -1888.7 1988.9 1887.8 1989.2 1886.9 1989.6 C
139.6165 -[0.4 0.4 0 0] vc
139.6166 -f
139.6167 -S
139.6168 -n
139.6169 -1892.4 1986.8 m
139.6170 -1895.1 1985.1 1897.9 1983.6 1900.6 1982 C
139.6171 -1897.9 1983.6 1895.1 1985.1 1892.4 1986.8 C
139.6172 -f
139.6173 -S
139.6174 -n
139.6175 -1907.3 1979.3 m
139.6176 -1908.5 1978.9 1909.7 1978.5 1910.9 1978.1 C
139.6177 -1909.7 1978.5 1908.5 1978.9 1907.3 1979.3 C
139.6178 -f
139.6179 -S
139.6180 -n
139.6181 -1938.5 1966.6 m
139.6182 -1942.6 1970.1 1945.9 1976.4 1951.7 1979.1 C
139.6183 -1946.2 1976.1 1943.1 1970.9 1938.5 1966.6 C
139.6184 -f
139.6185 -S
139.6186 -n
139.6187 -1955.1 1978.6 m
139.6188 -1955.9 1978.2 1956.7 1977.8 1957.5 1977.4 C
139.6189 -1956.7 1977.8 1955.9 1978.2 1955.1 1978.6 C
139.6190 -f
139.6191 -S
139.6192 -n
139.6193 -1913.6 1977.6 m
139.6194 -1914.5 1977.2 1915.3 1976.9 1916.2 1976.4 C
139.6195 -1915.3 1976.9 1914.5 1977.2 1913.6 1977.6 C
139.6196 -f
139.6197 -S
139.6198 -n
139.6199 -1919.1 1974.8 m
139.6200 -1921.8 1973.1 1924.5 1971.6 1927.2 1970 C
139.6201 -1924.5 1971.6 1921.8 1973.1 1919.1 1974.8 C
139.6202 -f
139.6203 -S
139.6204 -n
139.6205 -1963.5 1974.5 m
139.6206 -1964.5 1974 1965.6 1973.4 1966.6 1972.8 C
139.6207 -1965.6 1973.4 1964.5 1974 1963.5 1974.5 C
139.6208 -f
139.6209 -S
139.6210 -n
139.6211 -vmrs
139.6212 -1967.8 1972.4 m
139.6213 -1970 1971.2 1972.1 1970 1974.3 1968.8 C
139.6214 -1972.1 1970 1970 1971.2 1967.8 1972.4 C
139.6215 -[0.4 0.4 0 0] vc
139.6216 -f
139.6217 -0.4 w
139.6218 -2 J
139.6219 -2 M
139.6220 -S
139.6221 -n
139.6222 -1934 1967.3 m
139.6223 -1935.2 1966.9 1936.4 1966.5 1937.6 1966.1 C
139.6224 -1936.4 1966.5 1935.2 1966.9 1934 1967.3 C
139.6225 -f
139.6226 -S
139.6227 -n
139.6228 -1928.9 2061.2 m
139.6229 -1928.9 2059.2 1928.9 2057.3 1928.9 2055.4 C
139.6230 -1928.9 2057.3 1928.9 2059.2 1928.9 2061.2 C
139.6231 -[0.21 0.21 0 0] vc
139.6232 -f
139.6233 -S
139.6234 -n
139.6235 -1917.2 2047 m
139.6236 -1917.8 2046.5 1919.6 2046.8 1920 2047.2 C
139.6237 -1920 2046.5 1920.9 2046.8 1921 2046.3 C
139.6238 -1921.9 2047.3 1921.3 2044.1 1921.5 2044.1 C
139.6239 -1919.7 2044.8 1915.7 2043.5 1916.2 2046 C
139.6240 -1916.2 2048.3 1917 2045.9 1917.2 2047 C
139.6241 -[0 0 0 0] vc
139.6242 -f
139.6243 -S
139.6244 -n
139.6245 -1922 2044.1 m
139.6246 -1923.5 2043.2 1927 2045.4 1927.5 2042.9 C
139.6247 -1927.1 2042.6 1927.3 2040.9 1927.2 2041.5 C
139.6248 -1924.9 2042.3 1920.9 2040.6 1922 2044.1 C
139.6249 -f
139.6250 -S
139.6251 -n
139.6252 -1934.9 2043.9 m
139.6253 -1935.2 2043.4 1934.4 2042.7 1934 2042.2 C
139.6254 -1933.2 2041.8 1932.4 2042.8 1932.8 2043.2 C
139.6255 -1932.9 2044 1934.3 2043.3 1934.9 2043.9 C
139.6256 -f
139.6257 -S
139.6258 -n
139.6259 -1906.1 2030.7 m
139.6260 -1906.1 2028.8 1906.1 2027 1906.1 2025.2 C
139.6261 -1906.1 2027 1906.1 2028.8 1906.1 2030.7 C
139.6262 -[0.21 0.21 0 0] vc
139.6263 -f
139.6264 -S
139.6265 -n
139.6266 -1932.8 2018.7 m
139.6267 -1932.8 2016.8 1932.8 2014.8 1932.8 2012.9 C
139.6268 -1932.8 2014.8 1932.8 2016.8 1932.8 2018.7 C
139.6269 -f
139.6270 -S
139.6271 -n
139.6272 -1894.4 2016.5 m
139.6273 -1895 2016 1896.8 2016.3 1897.2 2016.8 C
139.6274 -1897.2 2016 1898.1 2016.3 1898.2 2015.8 C
139.6275 -1899.1 2016.8 1898.5 2013.6 1898.7 2013.6 C
139.6276 -1896.9 2014.4 1892.9 2013 1893.4 2015.6 C
139.6277 -1893.4 2017.8 1894.2 2015.4 1894.4 2016.5 C
139.6278 -[0 0 0 0] vc
139.6279 -f
139.6280 -S
139.6281 -n
139.6282 -1899.2 2013.6 m
139.6283 -1900.7 2012.7 1904.2 2014.9 1904.7 2012.4 C
139.6284 -1904.3 2012.1 1904.5 2010.5 1904.4 2011 C
139.6285 -1902.1 2011.8 1898.1 2010.1 1899.2 2013.6 C
139.6286 -f
139.6287 -S
139.6288 -n
139.6289 -vmrs
139.6290 -1912.1 2013.4 m
139.6291 -1912.4 2012.9 1911.6 2012.3 1911.2 2011.7 C
139.6292 -1910.4 2011.4 1909.6 2012.3 1910 2012.7 C
139.6293 -1910.1 2013.5 1911.5 2012.9 1912.1 2013.4 C
139.6294 -[0 0 0 0] vc
139.6295 -f
139.6296 -0.4 w
139.6297 -2 J
139.6298 -2 M
139.6299 -S
139.6300 -n
139.6301 -1921 2004.5 m
139.6302 -1921.6 2004 1923.4 2004.3 1923.9 2004.8 C
139.6303 -1923.8 2004 1924.8 2004.3 1924.8 2003.8 C
139.6304 -1925.7 2004.8 1925.1 2001.6 1925.3 2001.6 C
139.6305 -1923.6 2002.4 1919.6 2001 1920 2003.6 C
139.6306 -1920 2005.8 1920.8 2003.4 1921 2004.5 C
139.6307 -f
139.6308 -S
139.6309 -n
139.6310 -1925.8 2001.6 m
139.6311 -1927.3 2000.7 1930.8 2002.9 1931.3 2000.4 C
139.6312 -1930.9 2000.1 1931.1 1998.5 1931.1 1999 C
139.6313 -1928.7 1999.8 1924.8 1998.1 1925.8 2001.6 C
139.6314 -f
139.6315 -S
139.6316 -n
139.6317 -1938.8 2001.4 m
139.6318 -1939 2000.9 1938.2 2000.3 1937.8 1999.7 C
139.6319 -1937.1 1999.4 1936.2 2000.3 1936.6 2000.7 C
139.6320 -1936.7 2001.5 1938.1 2000.9 1938.8 2001.4 C
139.6321 -f
139.6322 -S
139.6323 -n
139.6324 -1908.6691 2008.1348 m
139.6325 -1897.82 2010.0477 L
139.6326 -1894.1735 1989.3671 L
139.6327 -1905.0226 1987.4542 L
139.6328 -1908.6691 2008.1348 L
139.6329 -n
139.6330 -q
139.6331 -_bfh
139.6332 -%%IncludeResource: font Symbol
139.6333 -_efh
139.6334 -{
139.6335 -f0 [19.696045 -3.4729 3.4729 19.696045 0 0] makesetfont
139.6336 -1895.041763 1994.291153 m
139.6337 -0 0 32 0 0 (l) ts
139.6338 -}
139.6339 -true
139.6340 -[0 0 0 1]sts
139.6341 -Q
139.6342 -1979.2185 1991.7809 m
139.6343 -1960.6353 1998.5452 L
139.6344 -1953.4532 1978.8124 L
139.6345 -1972.0363 1972.0481 L
139.6346 -1979.2185 1991.7809 L
139.6347 -n
139.6348 -q
139.6349 -_bfh
139.6350 -%%IncludeResource: font Symbol
139.6351 -_efh
139.6352 -{
139.6353 -f0 [18.793335 -6.84082 6.84021 18.793335 0 0] makesetfont
139.6354 -1955.163254 1983.510773 m
139.6355 -0 0 32 0 0 (\256) ts
139.6356 -}
139.6357 -true
139.6358 -[0 0 0 1]sts
139.6359 -Q
139.6360 -1952.1544 2066.5423 m
139.6361 -1938.0739 2069.025 L
139.6362 -1934.4274 2048.3444 L
139.6363 -1948.5079 2045.8617 L
139.6364 -1952.1544 2066.5423 L
139.6365 -n
139.6366 -q
139.6367 -_bfh
139.6368 -%%IncludeResource: font Symbol
139.6369 -_efh
139.6370 -{
139.6371 -f0 [19.696045 -3.4729 3.4729 19.696045 0 0] makesetfont
139.6372 -1935.29567 2053.268433 m
139.6373 -0 0 32 0 0 (") ts
139.6374 -}
139.6375 -true
139.6376 -[0 0 0 1]sts
139.6377 -Q
139.6378 -1931.7231 2043.621 m
139.6379 -1919.3084 2048.14 L
139.6380 -1910.6898 2024.4607 L
139.6381 -1923.1046 2019.9417 L
139.6382 -1931.7231 2043.621 L
139.6383 -n
139.6384 -q
139.6385 -_bfh
139.6386 -%%IncludeResource: font Symbol
139.6387 -_efh
139.6388 -{
139.6389 -f0 [22.552002 -8.208984 8.208252 22.552002 0 0] makesetfont
139.6390 -1912.741867 2030.098648 m
139.6391 -0 0 32 0 0 (=) ts
139.6392 -}
139.6393 -true
139.6394 -[0 0 0 1]sts
139.6395 -Q
139.6396 -1944 2024.5 m
139.6397 -1944 2014 L
139.6398 -0.8504 w
139.6399 -0 J
139.6400 -3.863693 M
139.6401 -[0 0 0 1] vc
139.6402 -false setoverprint
139.6403 -S
139.6404 -n
139.6405 -1944.25 2019.1673 m
139.6406 -1952.5 2015.9173 L
139.6407 -S
139.6408 -n
139.6409 -1931.0787 2124.423 m
139.6410 -1855.5505 2043.4285 L
139.6411 -1871.0419 2013.0337 L
139.6412 -1946.5701 2094.0282 L
139.6413 -1931.0787 2124.423 L
139.6414 -n
139.6415 -q
139.6416 -_bfh
139.6417 -%%IncludeResource: font ZapfHumanist601BT-Bold
139.6418 -_efh
139.6419 -{
139.6420 -f1 [22.155762 23.759277 -14.753906 28.947754 0 0] makesetfont
139.6421 -1867.35347 2020.27063 m
139.6422 -0 0 32 0 0 (Isabelle) ts
139.6423 -}
139.6424 -true
139.6425 -[0 0 0 1]sts
139.6426 -Q
139.6427 -1933.5503 1996.9547 m
139.6428 -1922.7012 1998.8677 L
139.6429 -1919.0547 1978.1871 L
139.6430 -1929.9038 1976.2741 L
139.6431 -1933.5503 1996.9547 L
139.6432 -n
139.6433 -q
139.6434 -_bfh
139.6435 -%%IncludeResource: font Symbol
139.6436 -_efh
139.6437 -{
139.6438 -f0 [19.696045 -3.4729 3.4729 19.696045 0 0] makesetfont
139.6439 -1919.922913 1983.111069 m
139.6440 -0 0 32 0 0 (b) ts
139.6441 -}
139.6442 -true
139.6443 -[0 0 0 1]sts
139.6444 -Q
139.6445 -2006.3221 2025.7184 m
139.6446 -1993.8573 2027.9162 L
139.6447 -1990.2108 2007.2356 L
139.6448 -2002.6756 2005.0378 L
139.6449 -2006.3221 2025.7184 L
139.6450 -n
139.6451 -q
139.6452 -_bfh
139.6453 -%%IncludeResource: font Symbol
139.6454 -_efh
139.6455 -{
139.6456 -f0 [19.696045 -3.4729 3.4729 19.696045 0 0] makesetfont
139.6457 -1991.07901 2012.159653 m
139.6458 -0 0 32 0 0 (a) ts
139.6459 -}
139.6460 -true
139.6461 -[0 0 0 1]sts
139.6462 -Q
139.6463 -vmrs
139.6464 -2030.0624 2094.056 m
139.6465 -1956.3187 2120.904 L
139.6466 -1956.321 2095.3175 L
139.6467 -2030.0647 2068.4695 L
139.6468 -2030.0624 2094.056 L
139.6469 -n
139.6470 -q
139.6471 -_bfh
139.6472 -%%IncludeResource: font ZapfHumanist601BT-Bold
139.6473 -_efh
139.6474 -{
139.6475 -f1 [22.898804 -8.336792 -0.002197 24.368408 0 0] makesetfont
139.6476 -1956.320496 2101.409561 m
139.6477 -0 0 32 0 0 (Isar) ts
139.6478 -}
139.6479 -true
139.6480 -[0 0 0 1]sts
139.6481 -Q
139.6482 -vmr
139.6483 -vmr
139.6484 -end
139.6485 -%%Trailer
139.6486 -%%DocumentNeededResources: font Symbol
139.6487 -%%+ font ZapfHumanist601BT-Bold
139.6488 -%%DocumentFonts: Symbol
139.6489 -%%+ ZapfHumanist601BT-Bold
139.6490 -%%DocumentNeededFonts: Symbol
139.6491 -%%+ ZapfHumanist601BT-Bold
140.1 Binary file doc-src/IsarAdvanced/Functions/isabelle_isar.pdf has changed
141.1 --- a/doc-src/IsarAdvanced/Functions/mathpartir.sty Wed Mar 04 11:05:02 2009 +0100
141.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
141.3 @@ -1,421 +0,0 @@
141.4 -% Mathpartir --- Math Paragraph for Typesetting Inference Rules
141.5 -%
141.6 -% Copyright (C) 2001, 2002, 2003, 2004, 2005 Didier Rémy
141.7 -%
141.8 -% Author : Didier Remy
141.9 -% Version : 1.2.0
141.10 -% Bug Reports : to author
141.11 -% Web Site : http://pauillac.inria.fr/~remy/latex/
141.12 -%
141.13 -% Mathpartir is free software; you can redistribute it and/or modify
141.14 -% it under the terms of the GNU General Public License as published by
141.15 -% the Free Software Foundation; either version 2, or (at your option)
141.16 -% any later version.
141.17 -%
141.18 -% Mathpartir is distributed in the hope that it will be useful,
141.19 -% but WITHOUT ANY WARRANTY; without even the implied warranty of
141.20 -% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
141.21 -% GNU General Public License for more details
141.22 -% (http://pauillac.inria.fr/~remy/license/GPL).
141.23 -%
141.24 -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
141.25 -% File mathpartir.sty (LaTeX macros)
141.26 -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
141.27 -
141.28 -\NeedsTeXFormat{LaTeX2e}
141.29 -\ProvidesPackage{mathpartir}
141.30 - [2005/12/20 version 1.2.0 Math Paragraph for Typesetting Inference Rules]
141.31 -
141.32 -%%
141.33 -
141.34 -%% Identification
141.35 -%% Preliminary declarations
141.36 -
141.37 -\RequirePackage {keyval}
141.38 -
141.39 -%% Options
141.40 -%% More declarations
141.41 -
141.42 -%% PART I: Typesetting maths in paragraphe mode
141.43 -
141.44 -\newdimen \mpr@tmpdim
141.45 -
141.46 -% To ensure hevea \hva compatibility, \hva should expands to nothing
141.47 -% in mathpar or in inferrule
141.48 -\let \mpr@hva \empty
141.49 -
141.50 -%% normal paragraph parametters, should rather be taken dynamically
141.51 -\def \mpr@savepar {%
141.52 - \edef \MathparNormalpar
141.53 - {\noexpand \lineskiplimit \the\lineskiplimit
141.54 - \noexpand \lineskip \the\lineskip}%
141.55 - }
141.56 -
141.57 -\def \mpr@rulelineskip {\lineskiplimit=0.3em\lineskip=0.2em plus 0.1em}
141.58 -\def \mpr@lesslineskip {\lineskiplimit=0.6em\lineskip=0.5em plus 0.2em}
141.59 -\def \mpr@lineskip {\lineskiplimit=1.2em\lineskip=1.2em plus 0.2em}
141.60 -\let \MathparLineskip \mpr@lineskip
141.61 -\def \mpr@paroptions {\MathparLineskip}
141.62 -\let \mpr@prebindings \relax
141.63 -
141.64 -\newskip \mpr@andskip \mpr@andskip 2em plus 0.5fil minus 0.5em
141.65 -
141.66 -\def \mpr@goodbreakand
141.67 - {\hskip -\mpr@andskip \penalty -1000\hskip \mpr@andskip}
141.68 -\def \mpr@and {\hskip \mpr@andskip}
141.69 -\def \mpr@andcr {\penalty 50\mpr@and}
141.70 -\def \mpr@cr {\penalty -10000\mpr@and}
141.71 -\def \mpr@eqno #1{\mpr@andcr #1\hskip 0em plus -1fil \penalty 10}
141.72 -
141.73 -\def \mpr@bindings {%
141.74 - \let \and \mpr@andcr
141.75 - \let \par \mpr@andcr
141.76 - \let \\\mpr@cr
141.77 - \let \eqno \mpr@eqno
141.78 - \let \hva \mpr@hva
141.79 - }
141.80 -\let \MathparBindings \mpr@bindings
141.81 -
141.82 -% \@ifundefined {ignorespacesafterend}
141.83 -% {\def \ignorespacesafterend {\aftergroup \ignorespaces}
141.84 -
141.85 -\newenvironment{mathpar}[1][]
141.86 - {$$\mpr@savepar \parskip 0em \hsize \linewidth \centering
141.87 - \vbox \bgroup \mpr@prebindings \mpr@paroptions #1\ifmmode $\else
141.88 - \noindent $\displaystyle\fi
141.89 - \MathparBindings}
141.90 - {\unskip \ifmmode $\fi\egroup $$\ignorespacesafterend}
141.91 -
141.92 -% \def \math@mathpar #1{\setbox0 \hbox {$\displaystyle #1$}\ifnum
141.93 -% \wd0 < \hsize $$\box0$$\else \bmathpar #1\emathpar \fi}
141.94 -
141.95 -%%% HOV BOXES
141.96 -
141.97 -\def \mathvbox@ #1{\hbox \bgroup \mpr@normallineskip
141.98 - \vbox \bgroup \tabskip 0em \let \\ \cr
141.99 - \halign \bgroup \hfil $##$\hfil\cr #1\crcr \egroup \egroup
141.100 - \egroup}
141.101 -
141.102 -\def \mathhvbox@ #1{\setbox0 \hbox {\let \\\qquad $#1$}\ifnum \wd0 < \hsize
141.103 - \box0\else \mathvbox {#1}\fi}
141.104 -
141.105 -
141.106 -%% Part II -- operations on lists
141.107 -
141.108 -\newtoks \mpr@lista
141.109 -\newtoks \mpr@listb
141.110 -
141.111 -\long \def\mpr@cons #1\mpr@to#2{\mpr@lista {\\{#1}}\mpr@listb \expandafter
141.112 -{#2}\edef #2{\the \mpr@lista \the \mpr@listb}}
141.113 -
141.114 -\long \def\mpr@snoc #1\mpr@to#2{\mpr@lista {\\{#1}}\mpr@listb \expandafter
141.115 -{#2}\edef #2{\the \mpr@listb\the\mpr@lista}}
141.116 -
141.117 -\long \def \mpr@concat#1=#2\mpr@to#3{\mpr@lista \expandafter {#2}\mpr@listb
141.118 -\expandafter {#3}\edef #1{\the \mpr@listb\the\mpr@lista}}
141.119 -
141.120 -\def \mpr@head #1\mpr@to #2{\expandafter \mpr@head@ #1\mpr@head@ #1#2}
141.121 -\long \def \mpr@head@ #1#2\mpr@head@ #3#4{\def #4{#1}\def#3{#2}}
141.122 -
141.123 -\def \mpr@flatten #1\mpr@to #2{\expandafter \mpr@flatten@ #1\mpr@flatten@ #1#2}
141.124 -\long \def \mpr@flatten@ \\#1\\#2\mpr@flatten@ #3#4{\def #4{#1}\def #3{\\#2}}
141.125 -
141.126 -\def \mpr@makelist #1\mpr@to #2{\def \mpr@all {#1}%
141.127 - \mpr@lista {\\}\mpr@listb \expandafter {\mpr@all}\edef \mpr@all {\the
141.128 - \mpr@lista \the \mpr@listb \the \mpr@lista}\let #2\empty
141.129 - \def \mpr@stripof ##1##2\mpr@stripend{\def \mpr@stripped{##2}}\loop
141.130 - \mpr@flatten \mpr@all \mpr@to \mpr@one
141.131 - \expandafter \mpr@snoc \mpr@one \mpr@to #2\expandafter \mpr@stripof
141.132 - \mpr@all \mpr@stripend
141.133 - \ifx \mpr@stripped \empty \let \mpr@isempty 0\else \let \mpr@isempty 1\fi
141.134 - \ifx 1\mpr@isempty
141.135 - \repeat
141.136 -}
141.137 -
141.138 -\def \mpr@rev #1\mpr@to #2{\let \mpr@tmp \empty
141.139 - \def \\##1{\mpr@cons ##1\mpr@to \mpr@tmp}#1\let #2\mpr@tmp}
141.140 -
141.141 -%% Part III -- Type inference rules
141.142 -
141.143 -\newif \if@premisse
141.144 -\newbox \mpr@hlist
141.145 -\newbox \mpr@vlist
141.146 -\newif \ifmpr@center \mpr@centertrue
141.147 -\def \mpr@htovlist {%
141.148 - \setbox \mpr@hlist
141.149 - \hbox {\strut
141.150 - \ifmpr@center \hskip -0.5\wd\mpr@hlist\fi
141.151 - \unhbox \mpr@hlist}%
141.152 - \setbox \mpr@vlist
141.153 - \vbox {\if@premisse \box \mpr@hlist \unvbox \mpr@vlist
141.154 - \else \unvbox \mpr@vlist \box \mpr@hlist
141.155 - \fi}%
141.156 -}
141.157 -% OLD version
141.158 -% \def \mpr@htovlist {%
141.159 -% \setbox \mpr@hlist
141.160 -% \hbox {\strut \hskip -0.5\wd\mpr@hlist \unhbox \mpr@hlist}%
141.161 -% \setbox \mpr@vlist
141.162 -% \vbox {\if@premisse \box \mpr@hlist \unvbox \mpr@vlist
141.163 -% \else \unvbox \mpr@vlist \box \mpr@hlist
141.164 -% \fi}%
141.165 -% }
141.166 -
141.167 -\def \mpr@item #1{$\displaystyle #1$}
141.168 -\def \mpr@sep{2em}
141.169 -\def \mpr@blank { }
141.170 -\def \mpr@hovbox #1#2{\hbox
141.171 - \bgroup
141.172 - \ifx #1T\@premissetrue
141.173 - \else \ifx #1B\@premissefalse
141.174 - \else
141.175 - \PackageError{mathpartir}
141.176 - {Premisse orientation should either be T or B}
141.177 - {Fatal error in Package}%
141.178 - \fi \fi
141.179 - \def \@test {#2}\ifx \@test \mpr@blank\else
141.180 - \setbox \mpr@hlist \hbox {}%
141.181 - \setbox \mpr@vlist \vbox {}%
141.182 - \if@premisse \let \snoc \mpr@cons \else \let \snoc \mpr@snoc \fi
141.183 - \let \@hvlist \empty \let \@rev \empty
141.184 - \mpr@tmpdim 0em
141.185 - \expandafter \mpr@makelist #2\mpr@to \mpr@flat
141.186 - \if@premisse \mpr@rev \mpr@flat \mpr@to \@rev \else \let \@rev \mpr@flat \fi
141.187 - \def \\##1{%
141.188 - \def \@test {##1}\ifx \@test \empty
141.189 - \mpr@htovlist
141.190 - \mpr@tmpdim 0em %%% last bug fix not extensively checked
141.191 - \else
141.192 - \setbox0 \hbox{\mpr@item {##1}}\relax
141.193 - \advance \mpr@tmpdim by \wd0
141.194 - %\mpr@tmpdim 1.02\mpr@tmpdim
141.195 - \ifnum \mpr@tmpdim < \hsize
141.196 - \ifnum \wd\mpr@hlist > 0
141.197 - \if@premisse
141.198 - \setbox \mpr@hlist
141.199 - \hbox {\unhbox0 \hskip \mpr@sep \unhbox \mpr@hlist}%
141.200 - \else
141.201 - \setbox \mpr@hlist
141.202 - \hbox {\unhbox \mpr@hlist \hskip \mpr@sep \unhbox0}%
141.203 - \fi
141.204 - \else
141.205 - \setbox \mpr@hlist \hbox {\unhbox0}%
141.206 - \fi
141.207 - \else
141.208 - \ifnum \wd \mpr@hlist > 0
141.209 - \mpr@htovlist
141.210 - \mpr@tmpdim \wd0
141.211 - \fi
141.212 - \setbox \mpr@hlist \hbox {\unhbox0}%
141.213 - \fi
141.214 - \advance \mpr@tmpdim by \mpr@sep
141.215 - \fi
141.216 - }%
141.217 - \@rev
141.218 - \mpr@htovlist
141.219 - \ifmpr@center \hskip \wd\mpr@vlist\fi \box \mpr@vlist
141.220 - \fi
141.221 - \egroup
141.222 -}
141.223 -
141.224 -%%% INFERENCE RULES
141.225 -
141.226 -\@ifundefined{@@over}{%
141.227 - \let\@@over\over % fallback if amsmath is not loaded
141.228 - \let\@@overwithdelims\overwithdelims
141.229 - \let\@@atop\atop \let\@@atopwithdelims\atopwithdelims
141.230 - \let\@@above\above \let\@@abovewithdelims\abovewithdelims
141.231 - }{}
141.232 -
141.233 -%% The default
141.234 -
141.235 -\def \mpr@@fraction #1#2{\hbox {\advance \hsize by -0.5em
141.236 - $\displaystyle {#1\mpr@over #2}$}}
141.237 -\let \mpr@fraction \mpr@@fraction
141.238 -
141.239 -%% A generic solution to arrow
141.240 -
141.241 -\def \mpr@make@fraction #1#2#3#4#5{\hbox {%
141.242 - \def \mpr@tail{#1}%
141.243 - \def \mpr@body{#2}%
141.244 - \def \mpr@head{#3}%
141.245 - \setbox1=\hbox{$#4$}\setbox2=\hbox{$#5$}%
141.246 - \setbox3=\hbox{$\mkern -3mu\mpr@body\mkern -3mu$}%
141.247 - \setbox3=\hbox{$\mkern -3mu \mpr@body\mkern -3mu$}%
141.248 - \dimen0=\dp1\advance\dimen0 by \ht3\relax\dp1\dimen0\relax
141.249 - \dimen0=\ht2\advance\dimen0 by \dp3\relax\ht2\dimen0\relax
141.250 - \setbox0=\hbox {$\box1 \@@atop \box2$}%
141.251 - \dimen0=\wd0\box0
141.252 - \box0 \hskip -\dimen0\relax
141.253 - \hbox to \dimen0 {$%
141.254 - \mathrel{\mpr@tail}\joinrel
141.255 - \xleaders\hbox{\copy3}\hfil\joinrel\mathrel{\mpr@head}%
141.256 - $}}}
141.257 -
141.258 -%% Old stuff should be removed in next version
141.259 -\def \mpr@@reduce #1#2{\hbox
141.260 - {$\lower 0.01pt \mpr@@fraction {#1}{#2}\mkern -15mu\rightarrow$}}
141.261 -\def \mpr@@rewrite #1#2#3{\hbox
141.262 - {$\lower 0.01pt \mpr@@fraction {#2}{#3}\mkern -8mu#1$}}
141.263 -\def \mpr@infercenter #1{\vcenter {\mpr@hovbox{T}{#1}}}
141.264 -
141.265 -\def \mpr@empty {}
141.266 -\def \mpr@inferrule
141.267 - {\bgroup
141.268 - \ifnum \linewidth<\hsize \hsize \linewidth\fi
141.269 - \mpr@rulelineskip
141.270 - \let \and \qquad
141.271 - \let \hva \mpr@hva
141.272 - \let \@rulename \mpr@empty
141.273 - \let \@rule@options \mpr@empty
141.274 - \let \mpr@over \@@over
141.275 - \mpr@inferrule@}
141.276 -\newcommand {\mpr@inferrule@}[3][]
141.277 - {\everymath={\displaystyle}%
141.278 - \def \@test {#2}\ifx \empty \@test
141.279 - \setbox0 \hbox {$\vcenter {\mpr@hovbox{B}{#3}}$}%
141.280 - \else
141.281 - \def \@test {#3}\ifx \empty \@test
141.282 - \setbox0 \hbox {$\vcenter {\mpr@hovbox{T}{#2}}$}%
141.283 - \else
141.284 - \setbox0 \mpr@fraction {\mpr@hovbox{T}{#2}}{\mpr@hovbox{B}{#3}}%
141.285 - \fi \fi
141.286 - \def \@test {#1}\ifx \@test\empty \box0
141.287 - \else \vbox
141.288 -%%% Suggestion de Francois pour les etiquettes longues
141.289 -%%% {\hbox to \wd0 {\RefTirName {#1}\hfil}\box0}\fi
141.290 - {\hbox {\RefTirName {#1}}\box0}\fi
141.291 - \egroup}
141.292 -
141.293 -\def \mpr@vdotfil #1{\vbox to #1{\leaders \hbox{$\cdot$} \vfil}}
141.294 -
141.295 -% They are two forms
141.296 -% \inferrule [label]{[premisses}{conclusions}
141.297 -% or
141.298 -% \inferrule* [options]{[premisses}{conclusions}
141.299 -%
141.300 -% Premisses and conclusions are lists of elements separated by \\
141.301 -% Each \\ produces a break, attempting horizontal breaks if possible,
141.302 -% and vertical breaks if needed.
141.303 -%
141.304 -% An empty element obtained by \\\\ produces a vertical break in all cases.
141.305 -%
141.306 -% The former rule is aligned on the fraction bar.
141.307 -% The optional label appears on top of the rule
141.308 -% The second form to be used in a derivation tree is aligned on the last
141.309 -% line of its conclusion
141.310 -%
141.311 -% The second form can be parameterized, using the key=val interface. The
141.312 -% folloiwng keys are recognized:
141.313 -%
141.314 -% width set the width of the rule to val
141.315 -% narrower set the width of the rule to val\hsize
141.316 -% before execute val at the beginning/left
141.317 -% lab put a label [Val] on top of the rule
141.318 -% lskip add negative skip on the right
141.319 -% left put a left label [Val]
141.320 -% Left put a left label [Val], ignoring its width
141.321 -% right put a right label [Val]
141.322 -% Right put a right label [Val], ignoring its width
141.323 -% leftskip skip negative space on the left-hand side
141.324 -% rightskip skip negative space on the right-hand side
141.325 -% vdots lift the rule by val and fill vertical space with dots
141.326 -% after execute val at the end/right
141.327 -%
141.328 -% Note that most options must come in this order to avoid strange
141.329 -% typesetting (in particular leftskip must preceed left and Left and
141.330 -% rightskip must follow Right or right; vdots must come last
141.331 -% or be only followed by rightskip.
141.332 -%
141.333 -
141.334 -%% Keys that make sence in all kinds of rules
141.335 -\def \mprset #1{\setkeys{mprset}{#1}}
141.336 -\define@key {mprset}{flushleft}[]{\mpr@centerfalse}
141.337 -\define@key {mprset}{center}[]{\mpr@centertrue}
141.338 -\define@key {mprset}{rewrite}[]{\let \mpr@fraction \mpr@@rewrite}
141.339 -\define@key {mprset}{myfraction}[]{\let \mpr@fraction #1}
141.340 -\define@key {mprset}{fraction}[]{\def \mpr@fraction {\mpr@make@fraction #1}}
141.341 -
141.342 -\newbox \mpr@right
141.343 -\define@key {mpr}{flushleft}[]{\mpr@centerfalse}
141.344 -\define@key {mpr}{center}[]{\mpr@centertrue}
141.345 -\define@key {mpr}{rewrite}[]{\let \mpr@fraction \mpr@@rewrite}
141.346 -\define@key {mpr}{myfraction}[]{\let \mpr@fraction #1}
141.347 -\define@key {mpr}{fraction}[]{\def \mpr@fraction {\mpr@make@fraction #1}}
141.348 -\define@key {mpr}{left}{\setbox0 \hbox {$\TirName {#1}\;$}\relax
141.349 - \advance \hsize by -\wd0\box0}
141.350 -\define@key {mpr}{width}{\hsize #1}
141.351 -\define@key {mpr}{sep}{\def\mpr@sep{#1}}
141.352 -\define@key {mpr}{before}{#1}
141.353 -\define@key {mpr}{lab}{\let \RefTirName \TirName \def \mpr@rulename {#1}}
141.354 -\define@key {mpr}{Lab}{\let \RefTirName \TirName \def \mpr@rulename {#1}}
141.355 -\define@key {mpr}{narrower}{\hsize #1\hsize}
141.356 -\define@key {mpr}{leftskip}{\hskip -#1}
141.357 -\define@key {mpr}{reduce}[]{\let \mpr@fraction \mpr@@reduce}
141.358 -\define@key {mpr}{rightskip}
141.359 - {\setbox \mpr@right \hbox {\unhbox \mpr@right \hskip -#1}}
141.360 -\define@key {mpr}{LEFT}{\setbox0 \hbox {$#1$}\relax
141.361 - \advance \hsize by -\wd0\box0}
141.362 -\define@key {mpr}{left}{\setbox0 \hbox {$\TirName {#1}\;$}\relax
141.363 - \advance \hsize by -\wd0\box0}
141.364 -\define@key {mpr}{Left}{\llap{$\TirName {#1}\;$}}
141.365 -\define@key {mpr}{right}
141.366 - {\setbox0 \hbox {$\;\TirName {#1}$}\relax \advance \hsize by -\wd0
141.367 - \setbox \mpr@right \hbox {\unhbox \mpr@right \unhbox0}}
141.368 -\define@key {mpr}{RIGHT}
141.369 - {\setbox0 \hbox {$#1$}\relax \advance \hsize by -\wd0
141.370 - \setbox \mpr@right \hbox {\unhbox \mpr@right \unhbox0}}
141.371 -\define@key {mpr}{Right}
141.372 - {\setbox \mpr@right \hbox {\unhbox \mpr@right \rlap {$\;\TirName {#1}$}}}
141.373 -\define@key {mpr}{vdots}{\def \mpr@vdots {\@@atop \mpr@vdotfil{#1}}}
141.374 -\define@key {mpr}{after}{\edef \mpr@after {\mpr@after #1}}
141.375 -
141.376 -\newdimen \rule@dimen
141.377 -\newcommand \mpr@inferstar@ [3][]{\setbox0
141.378 - \hbox {\let \mpr@rulename \mpr@empty \let \mpr@vdots \relax
141.379 - \setbox \mpr@right \hbox{}%
141.380 - $\setkeys{mpr}{#1}%
141.381 - \ifx \mpr@rulename \mpr@empty \mpr@inferrule {#2}{#3}\else
141.382 - \mpr@inferrule [{\mpr@rulename}]{#2}{#3}\fi
141.383 - \box \mpr@right \mpr@vdots$}
141.384 - \setbox1 \hbox {\strut}
141.385 - \rule@dimen \dp0 \advance \rule@dimen by -\dp1
141.386 - \raise \rule@dimen \box0}
141.387 -
141.388 -\def \mpr@infer {\@ifnextchar *{\mpr@inferstar}{\mpr@inferrule}}
141.389 -\newcommand \mpr@err@skipargs[3][]{}
141.390 -\def \mpr@inferstar*{\ifmmode
141.391 - \let \@do \mpr@inferstar@
141.392 - \else
141.393 - \let \@do \mpr@err@skipargs
141.394 - \PackageError {mathpartir}
141.395 - {\string\inferrule* can only be used in math mode}{}%
141.396 - \fi \@do}
141.397 -
141.398 -
141.399 -%%% Exports
141.400 -
141.401 -% Envirnonment mathpar
141.402 -
141.403 -\let \inferrule \mpr@infer
141.404 -
141.405 -% make a short name \infer is not already defined
141.406 -\@ifundefined {infer}{\let \infer \mpr@infer}{}
141.407 -
141.408 -\def \TirNameStyle #1{\small \textsc{#1}}
141.409 -\def \tir@name #1{\hbox {\small \TirNameStyle{#1}}}
141.410 -\let \TirName \tir@name
141.411 -\let \DefTirName \TirName
141.412 -\let \RefTirName \TirName
141.413 -
141.414 -%%% Other Exports
141.415 -
141.416 -% \let \listcons \mpr@cons
141.417 -% \let \listsnoc \mpr@snoc
141.418 -% \let \listhead \mpr@head
141.419 -% \let \listmake \mpr@makelist
141.420 -
141.421 -
141.422 -
141.423 -
141.424 -\endinput
142.1 --- a/doc-src/IsarAdvanced/Functions/style.sty Wed Mar 04 11:05:02 2009 +0100
142.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
142.3 @@ -1,62 +0,0 @@
142.4 -
142.5 -%% $Id$
142.6 -
142.7 -%% toc
142.8 -\newcommand{\tocentry}[1]{\cleardoublepage\phantomsection\addcontentsline{toc}{chapter}{#1}
142.9 -\@mkboth{\MakeUppercase{#1}}{\MakeUppercase{#1}}}
142.10 -
142.11 -%% references
142.12 -\newcommand{\secref}[1]{\S\ref{#1}}
142.13 -\newcommand{\chref}[1]{chapter~\ref{#1}}
142.14 -\newcommand{\figref}[1]{figure~\ref{#1}}
142.15 -
142.16 -%% glossary
142.17 -\renewcommand{\glossary}[2]{\nomenclature{\bf #1}{#2}}
142.18 -\newcommand{\seeglossary}[1]{\emph{#1}}
142.19 -\newcommand{\glossaryname}{Glossary}
142.20 -\renewcommand{\nomname}{\glossaryname}
142.21 -\renewcommand{\pagedeclaration}[1]{\nobreak\quad\dotfill~page~\bold{#1}}
142.22 -
142.23 -%% index
142.24 -\newcommand{\indexml}[1]{\index{\emph{#1}|bold}}
142.25 -\newcommand{\indexmltype}[1]{\index{\emph{#1} (type)|bold}}
142.26 -\newcommand{\indexmlstructure}[1]{\index{\emph{#1} (structure)|bold}}
142.27 -\newcommand{\indexmlfunctor}[1]{\index{\emph{#1} (functor)|bold}}
142.28 -
142.29 -%% math
142.30 -\newcommand{\text}[1]{\mbox{#1}}
142.31 -\newcommand{\isasymvartheta}{\isamath{\theta}}
142.32 -\newcommand{\isactrlvec}[1]{\emph{$\overline{#1}$}}
142.33 -
142.34 -\setcounter{secnumdepth}{2} \setcounter{tocdepth}{2}
142.35 -
142.36 -\pagestyle{headings}
142.37 -\sloppy
142.38 -\binperiod
142.39 -\underscoreon
142.40 -
142.41 -\renewcommand{\isadigit}[1]{\isamath{#1}}
142.42 -
142.43 -\newenvironment{mldecls}{\par\noindent\begingroup\footnotesize\def\isanewline{\\}\begin{tabular}{l}}{\end{tabular}\smallskip\endgroup}
142.44 -
142.45 -\isafoldtag{FIXME}
142.46 -\isakeeptag{mlref}
142.47 -\renewcommand{\isatagmlref}{\subsection*{\makebox[0pt][r]{\fbox{\ML}~~}Reference}\begingroup\def\isastyletext{\rm}\small}
142.48 -\renewcommand{\endisatagmlref}{\endgroup}
142.49 -
142.50 -\newcommand{\isasymGUESS}{\isakeyword{guess}}
142.51 -\newcommand{\isasymOBTAIN}{\isakeyword{obtain}}
142.52 -\newcommand{\isasymTHEORY}{\isakeyword{theory}}
142.53 -\newcommand{\isasymUSES}{\isakeyword{uses}}
142.54 -\newcommand{\isasymEND}{\isakeyword{end}}
142.55 -\newcommand{\isasymCONSTS}{\isakeyword{consts}}
142.56 -\newcommand{\isasymDEFS}{\isakeyword{defs}}
142.57 -\newcommand{\isasymTHEOREM}{\isakeyword{theorem}}
142.58 -\newcommand{\isasymDEFINITION}{\isakeyword{definition}}
142.59 -
142.60 -\isabellestyle{it}
142.61 -
142.62 -%%% Local Variables:
142.63 -%%% mode: latex
142.64 -%%% TeX-master: "implementation"
142.65 -%%% End:
143.1 --- a/doc-src/IsarAdvanced/Makefile.in Wed Mar 04 11:05:02 2009 +0100
143.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
143.3 @@ -1,13 +0,0 @@
143.4 -# $Id$
143.5 -#
143.6 -
143.7 -include ../../Makefile.in
143.8 -
143.9 -SEDINDEX = ../../sedindex
143.10 -FIXBOOKMARKS = perl -pi ../../fixbookmarks.pl
143.11 -
143.12 -isabelle_isar.eps:
143.13 - test -r isabelle_isar.eps || ln -s ../../gfx/isabelle_isar.eps .
143.14 -
143.15 -isabelle_isar.pdf:
143.16 - test -r isabelle_isar.pdf || ln -s ../../gfx/isabelle_isar.pdf .
144.1 --- a/doc-src/IsarImplementation/IsaMakefile Wed Mar 04 11:05:02 2009 +0100
144.2 +++ b/doc-src/IsarImplementation/IsaMakefile Wed Mar 04 11:05:29 2009 +0100
144.3 @@ -21,9 +21,10 @@
144.4
144.5 Thy: $(LOG)/Pure-Thy.gz
144.6
144.7 -$(LOG)/Pure-Thy.gz: Thy/ROOT.ML Thy/base.thy Thy/integration.thy Thy/isar.thy \
144.8 - Thy/locale.thy Thy/logic.thy Thy/prelim.thy Thy/proof.thy Thy/tactic.thy \
144.9 - Thy/ML.thy ../antiquote_setup.ML
144.10 +$(LOG)/Pure-Thy.gz: Thy/ROOT.ML Thy/Base.thy Thy/Integration.thy \
144.11 + Thy/Isar.thy Thy/Local_Theory.thy Thy/Logic.thy Thy/Prelim.thy \
144.12 + Thy/Proof.thy Thy/Syntax.thy Thy/Tactic.thy Thy/ML.thy \
144.13 + ../antiquote_setup.ML
144.14 @$(USEDIR) Pure Thy
144.15
144.16
145.1 --- a/doc-src/IsarImplementation/Makefile Wed Mar 04 11:05:02 2009 +0100
145.2 +++ b/doc-src/IsarImplementation/Makefile Wed Mar 04 11:05:29 2009 +0100
145.3 @@ -1,6 +1,3 @@
145.4 -#
145.5 -# $Id$
145.6 -#
145.7
145.8 ## targets
145.9
145.10 @@ -11,16 +8,14 @@
145.11
145.12 include ../Makefile.in
145.13
145.14 -MAKEGLOSSARY = ./makeglossary
145.15 -
145.16 NAME = implementation
145.17
145.18 -FILES = implementation.tex intro.tex Thy/document/prelim.tex \
145.19 - Thy/document/logic.tex Thy/document/tactic.tex \
145.20 - Thy/document/proof.tex Thy/document/locale.tex \
145.21 - Thy/document/integration.tex style.sty ../iman.sty ../extra.sty \
145.22 - ../isar.sty ../isabelle.sty ../isabellesym.sty ../pdfsetup.sty \
145.23 - ../manual.bib ../proof.sty
145.24 +FILES = ../extra.sty ../iman.sty ../isabelle.sty ../isabellesym.sty \
145.25 + ../isar.sty ../manual.bib ../pdfsetup.sty ../proof.sty \
145.26 + Thy/document/Integration.tex Thy/document/Local_Theory.tex \
145.27 + Thy/document/Logic.tex Thy/document/Prelim.tex \
145.28 + Thy/document/Proof.tex Thy/document/Syntax.tex \
145.29 + Thy/document/Tactic.tex implementation.tex style.sty
145.30
145.31 dvi: $(NAME).dvi
145.32
145.33 @@ -29,7 +24,6 @@
145.34 $(BIBTEX) $(NAME)
145.35 $(LATEX) $(NAME)
145.36 $(LATEX) $(NAME)
145.37 - $(MAKEGLOSSARY) $(NAME)
145.38 $(SEDINDEX) $(NAME)
145.39 $(LATEX) $(NAME)
145.40 $(LATEX) $(NAME)
145.41 @@ -41,7 +35,6 @@
145.42 $(BIBTEX) $(NAME)
145.43 $(PDFLATEX) $(NAME)
145.44 $(PDFLATEX) $(NAME)
145.45 - $(MAKEGLOSSARY) $(NAME)
145.46 $(SEDINDEX) $(NAME)
145.47 $(FIXBOOKMARKS) $(NAME).out
145.48 $(PDFLATEX) $(NAME)
146.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
146.2 +++ b/doc-src/IsarImplementation/Thy/Local_Theory.thy Wed Mar 04 11:05:29 2009 +0100
146.3 @@ -0,0 +1,168 @@
146.4 +theory Local_Theory
146.5 +imports Base
146.6 +begin
146.7 +
146.8 +chapter {* Local theory specifications *}
146.9 +
146.10 +text {*
146.11 + A \emph{local theory} combines aspects of both theory and proof
146.12 + context (cf.\ \secref{sec:context}), such that definitional
146.13 + specifications may be given relatively to parameters and
146.14 + assumptions. A local theory is represented as a regular proof
146.15 + context, augmented by administrative data about the \emph{target
146.16 + context}.
146.17 +
146.18 + The target is usually derived from the background theory by adding
146.19 + local @{text "\<FIX>"} and @{text "\<ASSUME>"} elements, plus
146.20 + suitable modifications of non-logical context data (e.g.\ a special
146.21 + type-checking discipline). Once initialized, the target is ready to
146.22 + absorb definitional primitives: @{text "\<DEFINE>"} for terms and
146.23 + @{text "\<NOTE>"} for theorems. Such definitions may get
146.24 + transformed in a target-specific way, but the programming interface
146.25 + hides such details.
146.26 +
146.27 + Isabelle/Pure provides target mechanisms for locales, type-classes,
146.28 + type-class instantiations, and general overloading. In principle,
146.29 + users can implement new targets as well, but this rather arcane
146.30 + discipline is beyond the scope of this manual. In contrast,
146.31 + implementing derived definitional packages to be used within a local
146.32 + theory context is quite easy: the interfaces are even simpler and
146.33 + more abstract than the underlying primitives for raw theories.
146.34 +
146.35 + Many definitional packages for local theories are available in
146.36 + Isabelle. Although a few old packages only work for global
146.37 + theories, the local theory interface is already the standard way of
146.38 + implementing definitional packages in Isabelle.
146.39 +*}
146.40 +
146.41 +
146.42 +section {* Definitional elements *}
146.43 +
146.44 +text {*
146.45 + There are separate elements @{text "\<DEFINE> c \<equiv> t"} for terms, and
146.46 + @{text "\<NOTE> b = thm"} for theorems. Types are treated
146.47 + implicitly, according to Hindley-Milner discipline (cf.\
146.48 + \secref{sec:variables}). These definitional primitives essentially
146.49 + act like @{text "let"}-bindings within a local context that may
146.50 + already contain earlier @{text "let"}-bindings and some initial
146.51 + @{text "\<lambda>"}-bindings. Thus we gain \emph{dependent definitions}
146.52 + that are relative to an initial axiomatic context. The following
146.53 + diagram illustrates this idea of axiomatic elements versus
146.54 + definitional elements:
146.55 +
146.56 + \begin{center}
146.57 + \begin{tabular}{|l|l|l|}
146.58 + \hline
146.59 + & @{text "\<lambda>"}-binding & @{text "let"}-binding \\
146.60 + \hline
146.61 + types & fixed @{text "\<alpha>"} & arbitrary @{text "\<beta>"} \\
146.62 + terms & @{text "\<FIX> x :: \<tau>"} & @{text "\<DEFINE> c \<equiv> t"} \\
146.63 + theorems & @{text "\<ASSUME> a: A"} & @{text "\<NOTE> b = \<^BG>B\<^EN>"} \\
146.64 + \hline
146.65 + \end{tabular}
146.66 + \end{center}
146.67 +
146.68 + A user package merely needs to produce suitable @{text "\<DEFINE>"}
146.69 + and @{text "\<NOTE>"} elements according to the application. For
146.70 + example, a package for inductive definitions might first @{text
146.71 + "\<DEFINE>"} a certain predicate as some fixed-point construction,
146.72 + then @{text "\<NOTE>"} a proven result about monotonicity of the
146.73 + functor involved here, and then produce further derived concepts via
146.74 + additional @{text "\<DEFINE>"} and @{text "\<NOTE>"} elements.
146.75 +
146.76 + The cumulative sequence of @{text "\<DEFINE>"} and @{text "\<NOTE>"}
146.77 + produced at package runtime is managed by the local theory
146.78 + infrastructure by means of an \emph{auxiliary context}. Thus the
146.79 + system holds up the impression of working within a fully abstract
146.80 + situation with hypothetical entities: @{text "\<DEFINE> c \<equiv> t"}
146.81 + always results in a literal fact @{text "\<^BG>c \<equiv> t\<^EN>"}, where
146.82 + @{text "c"} is a fixed variable @{text "c"}. The details about
146.83 + global constants, name spaces etc. are handled internally.
146.84 +
146.85 + So the general structure of a local theory is a sandwich of three
146.86 + layers:
146.87 +
146.88 + \begin{center}
146.89 + \framebox{\quad auxiliary context \quad\framebox{\quad target context \quad\framebox{\quad background theory\quad}}}
146.90 + \end{center}
146.91 +
146.92 + \noindent When a definitional package is finished, the auxiliary
146.93 + context is reset to the target context. The target now holds
146.94 + definitions for terms and theorems that stem from the hypothetical
146.95 + @{text "\<DEFINE>"} and @{text "\<NOTE>"} elements, transformed by
146.96 + the particular target policy (see
146.97 + \cite[\S4--5]{Haftmann-Wenzel:2009} for details).
146.98 +*}
146.99 +
146.100 +text %mlref {*
146.101 + \begin{mldecls}
146.102 + @{index_ML_type local_theory: Proof.context} \\
146.103 + @{index_ML TheoryTarget.init: "string option -> theory -> local_theory"} \\[1ex]
146.104 + @{index_ML LocalTheory.define: "string ->
146.105 + (binding * mixfix) * (Attrib.binding * term) -> local_theory ->
146.106 + (term * (string * thm)) * local_theory"} \\
146.107 + @{index_ML LocalTheory.note: "string ->
146.108 + Attrib.binding * thm list -> local_theory ->
146.109 + (string * thm list) * local_theory"} \\
146.110 + \end{mldecls}
146.111 +
146.112 + \begin{description}
146.113 +
146.114 + \item @{ML_type local_theory} represents local theories. Although
146.115 + this is merely an alias for @{ML_type Proof.context}, it is
146.116 + semantically a subtype of the same: a @{ML_type local_theory} holds
146.117 + target information as special context data. Subtyping means that
146.118 + any value @{text "lthy:"}~@{ML_type local_theory} can be also used
146.119 + with operations on expecting a regular @{text "ctxt:"}~@{ML_type
146.120 + Proof.context}.
146.121 +
146.122 + \item @{ML TheoryTarget.init}~@{text "NONE thy"} initializes a
146.123 + trivial local theory from the given background theory.
146.124 + Alternatively, @{text "SOME name"} may be given to initialize a
146.125 + @{command locale} or @{command class} context (a fully-qualified
146.126 + internal name is expected here). This is useful for experimentation
146.127 + --- normally the Isar toplevel already takes care to initialize the
146.128 + local theory context.
146.129 +
146.130 + \item @{ML LocalTheory.define}~@{text "kind ((b, mx), (a, rhs))
146.131 + lthy"} defines a local entity according to the specification that is
146.132 + given relatively to the current @{text "lthy"} context. In
146.133 + particular the term of the RHS may refer to earlier local entities
146.134 + from the auxiliary context, or hypothetical parameters from the
146.135 + target context. The result is the newly defined term (which is
146.136 + always a fixed variable with exactly the same name as specified for
146.137 + the LHS), together with an equational theorem that states the
146.138 + definition as a hypothetical fact.
146.139 +
146.140 + Unless an explicit name binding is given for the RHS, the resulting
146.141 + fact will be called @{text "b_def"}. Any given attributes are
146.142 + applied to that same fact --- immediately in the auxiliary context
146.143 + \emph{and} in any transformed versions stemming from target-specific
146.144 + policies or any later interpretations of results from the target
146.145 + context (think of @{command locale} and @{command interpretation},
146.146 + for example). This means that attributes should be usually plain
146.147 + declarations such as @{attribute simp}, while non-trivial rules like
146.148 + @{attribute simplified} are better avoided.
146.149 +
146.150 + The @{text kind} determines the theorem kind tag of the resulting
146.151 + fact. Typical examples are @{ML Thm.definitionK}, @{ML
146.152 + Thm.theoremK}, or @{ML Thm.internalK}.
146.153 +
146.154 + \item @{ML LocalTheory.note}~@{text "kind (a, ths) lthy"} is
146.155 + analogous to @{ML LocalTheory.define}, but defines facts instead of
146.156 + terms. There is also a slightly more general variant @{ML
146.157 + LocalTheory.notes} that defines several facts (with attribute
146.158 + expressions) simultaneously.
146.159 +
146.160 + This is essentially the internal version of the @{command lemmas}
146.161 + command, or @{command declare} if an empty name binding is given.
146.162 +
146.163 + \end{description}
146.164 +*}
146.165 +
146.166 +
146.167 +section {* Morphisms and declarations *}
146.168 +
146.169 +text FIXME
146.170 +
146.171 +end
147.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
147.2 +++ b/doc-src/IsarImplementation/Thy/Syntax.thy Wed Mar 04 11:05:29 2009 +0100
147.3 @@ -0,0 +1,9 @@
147.4 +theory Syntax
147.5 +imports Base
147.6 +begin
147.7 +
147.8 +chapter {* Syntax and type-checking *}
147.9 +
147.10 +text FIXME
147.11 +
147.12 +end
148.1 --- a/doc-src/IsarImplementation/Thy/base.thy Wed Mar 04 11:05:02 2009 +0100
148.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
148.3 @@ -1,9 +0,0 @@
148.4 -
148.5 -(* $Id$ *)
148.6 -
148.7 -theory base
148.8 -imports Pure
148.9 -uses "../../antiquote_setup.ML"
148.10 -begin
148.11 -
148.12 -end
149.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
149.2 +++ b/doc-src/IsarImplementation/Thy/document/Local_Theory.tex Wed Mar 04 11:05:29 2009 +0100
149.3 @@ -0,0 +1,220 @@
149.4 +%
149.5 +\begin{isabellebody}%
149.6 +\def\isabellecontext{Local{\isacharunderscore}Theory}%
149.7 +%
149.8 +\isadelimtheory
149.9 +%
149.10 +\endisadelimtheory
149.11 +%
149.12 +\isatagtheory
149.13 +\isacommand{theory}\isamarkupfalse%
149.14 +\ Local{\isacharunderscore}Theory\isanewline
149.15 +\isakeyword{imports}\ Base\isanewline
149.16 +\isakeyword{begin}%
149.17 +\endisatagtheory
149.18 +{\isafoldtheory}%
149.19 +%
149.20 +\isadelimtheory
149.21 +%
149.22 +\endisadelimtheory
149.23 +%
149.24 +\isamarkupchapter{Local theory specifications%
149.25 +}
149.26 +\isamarkuptrue%
149.27 +%
149.28 +\begin{isamarkuptext}%
149.29 +A \emph{local theory} combines aspects of both theory and proof
149.30 + context (cf.\ \secref{sec:context}), such that definitional
149.31 + specifications may be given relatively to parameters and
149.32 + assumptions. A local theory is represented as a regular proof
149.33 + context, augmented by administrative data about the \emph{target
149.34 + context}.
149.35 +
149.36 + The target is usually derived from the background theory by adding
149.37 + local \isa{{\isasymFIX}} and \isa{{\isasymASSUME}} elements, plus
149.38 + suitable modifications of non-logical context data (e.g.\ a special
149.39 + type-checking discipline). Once initialized, the target is ready to
149.40 + absorb definitional primitives: \isa{{\isasymDEFINE}} for terms and
149.41 + \isa{{\isasymNOTE}} for theorems. Such definitions may get
149.42 + transformed in a target-specific way, but the programming interface
149.43 + hides such details.
149.44 +
149.45 + Isabelle/Pure provides target mechanisms for locales, type-classes,
149.46 + type-class instantiations, and general overloading. In principle,
149.47 + users can implement new targets as well, but this rather arcane
149.48 + discipline is beyond the scope of this manual. In contrast,
149.49 + implementing derived definitional packages to be used within a local
149.50 + theory context is quite easy: the interfaces are even simpler and
149.51 + more abstract than the underlying primitives for raw theories.
149.52 +
149.53 + Many definitional packages for local theories are available in
149.54 + Isabelle. Although a few old packages only work for global
149.55 + theories, the local theory interface is already the standard way of
149.56 + implementing definitional packages in Isabelle.%
149.57 +\end{isamarkuptext}%
149.58 +\isamarkuptrue%
149.59 +%
149.60 +\isamarkupsection{Definitional elements%
149.61 +}
149.62 +\isamarkuptrue%
149.63 +%
149.64 +\begin{isamarkuptext}%
149.65 +There are separate elements \isa{{\isasymDEFINE}\ c\ {\isasymequiv}\ t} for terms, and
149.66 + \isa{{\isasymNOTE}\ b\ {\isacharequal}\ thm} for theorems. Types are treated
149.67 + implicitly, according to Hindley-Milner discipline (cf.\
149.68 + \secref{sec:variables}). These definitional primitives essentially
149.69 + act like \isa{let}-bindings within a local context that may
149.70 + already contain earlier \isa{let}-bindings and some initial
149.71 + \isa{{\isasymlambda}}-bindings. Thus we gain \emph{dependent definitions}
149.72 + that are relative to an initial axiomatic context. The following
149.73 + diagram illustrates this idea of axiomatic elements versus
149.74 + definitional elements:
149.75 +
149.76 + \begin{center}
149.77 + \begin{tabular}{|l|l|l|}
149.78 + \hline
149.79 + & \isa{{\isasymlambda}}-binding & \isa{let}-binding \\
149.80 + \hline
149.81 + types & fixed \isa{{\isasymalpha}} & arbitrary \isa{{\isasymbeta}} \\
149.82 + terms & \isa{{\isasymFIX}\ x\ {\isacharcolon}{\isacharcolon}\ {\isasymtau}} & \isa{{\isasymDEFINE}\ c\ {\isasymequiv}\ t} \\
149.83 + theorems & \isa{{\isasymASSUME}\ a{\isacharcolon}\ A} & \isa{{\isasymNOTE}\ b\ {\isacharequal}\ \isactrlBG B\isactrlEN } \\
149.84 + \hline
149.85 + \end{tabular}
149.86 + \end{center}
149.87 +
149.88 + A user package merely needs to produce suitable \isa{{\isasymDEFINE}}
149.89 + and \isa{{\isasymNOTE}} elements according to the application. For
149.90 + example, a package for inductive definitions might first \isa{{\isasymDEFINE}} a certain predicate as some fixed-point construction,
149.91 + then \isa{{\isasymNOTE}} a proven result about monotonicity of the
149.92 + functor involved here, and then produce further derived concepts via
149.93 + additional \isa{{\isasymDEFINE}} and \isa{{\isasymNOTE}} elements.
149.94 +
149.95 + The cumulative sequence of \isa{{\isasymDEFINE}} and \isa{{\isasymNOTE}}
149.96 + produced at package runtime is managed by the local theory
149.97 + infrastructure by means of an \emph{auxiliary context}. Thus the
149.98 + system holds up the impression of working within a fully abstract
149.99 + situation with hypothetical entities: \isa{{\isasymDEFINE}\ c\ {\isasymequiv}\ t}
149.100 + always results in a literal fact \isa{\isactrlBG c\ {\isasymequiv}\ t\isactrlEN }, where
149.101 + \isa{c} is a fixed variable \isa{c}. The details about
149.102 + global constants, name spaces etc. are handled internally.
149.103 +
149.104 + So the general structure of a local theory is a sandwich of three
149.105 + layers:
149.106 +
149.107 + \begin{center}
149.108 + \framebox{\quad auxiliary context \quad\framebox{\quad target context \quad\framebox{\quad background theory\quad}}}
149.109 + \end{center}
149.110 +
149.111 + \noindent When a definitional package is finished, the auxiliary
149.112 + context is reset to the target context. The target now holds
149.113 + definitions for terms and theorems that stem from the hypothetical
149.114 + \isa{{\isasymDEFINE}} and \isa{{\isasymNOTE}} elements, transformed by
149.115 + the particular target policy (see
149.116 + \cite[\S4--5]{Haftmann-Wenzel:2009} for details).%
149.117 +\end{isamarkuptext}%
149.118 +\isamarkuptrue%
149.119 +%
149.120 +\isadelimmlref
149.121 +%
149.122 +\endisadelimmlref
149.123 +%
149.124 +\isatagmlref
149.125 +%
149.126 +\begin{isamarkuptext}%
149.127 +\begin{mldecls}
149.128 + \indexdef{}{ML type}{local\_theory}\verb|type local_theory = Proof.context| \\
149.129 + \indexdef{}{ML}{TheoryTarget.init}\verb|TheoryTarget.init: string option -> theory -> local_theory| \\[1ex]
149.130 + \indexdef{}{ML}{LocalTheory.define}\verb|LocalTheory.define: string ->|\isasep\isanewline%
149.131 +\verb| (binding * mixfix) * (Attrib.binding * term) -> local_theory ->|\isasep\isanewline%
149.132 +\verb| (term * (string * thm)) * local_theory| \\
149.133 + \indexdef{}{ML}{LocalTheory.note}\verb|LocalTheory.note: string ->|\isasep\isanewline%
149.134 +\verb| Attrib.binding * thm list -> local_theory ->|\isasep\isanewline%
149.135 +\verb| (string * thm list) * local_theory| \\
149.136 + \end{mldecls}
149.137 +
149.138 + \begin{description}
149.139 +
149.140 + \item \verb|local_theory| represents local theories. Although
149.141 + this is merely an alias for \verb|Proof.context|, it is
149.142 + semantically a subtype of the same: a \verb|local_theory| holds
149.143 + target information as special context data. Subtyping means that
149.144 + any value \isa{lthy{\isacharcolon}}~\verb|local_theory| can be also used
149.145 + with operations on expecting a regular \isa{ctxt{\isacharcolon}}~\verb|Proof.context|.
149.146 +
149.147 + \item \verb|TheoryTarget.init|~\isa{NONE\ thy} initializes a
149.148 + trivial local theory from the given background theory.
149.149 + Alternatively, \isa{SOME\ name} may be given to initialize a
149.150 + \hyperlink{command.locale}{\mbox{\isa{\isacommand{locale}}}} or \hyperlink{command.class}{\mbox{\isa{\isacommand{class}}}} context (a fully-qualified
149.151 + internal name is expected here). This is useful for experimentation
149.152 + --- normally the Isar toplevel already takes care to initialize the
149.153 + local theory context.
149.154 +
149.155 + \item \verb|LocalTheory.define|~\isa{kind\ {\isacharparenleft}{\isacharparenleft}b{\isacharcomma}\ mx{\isacharparenright}{\isacharcomma}\ {\isacharparenleft}a{\isacharcomma}\ rhs{\isacharparenright}{\isacharparenright}\ lthy} defines a local entity according to the specification that is
149.156 + given relatively to the current \isa{lthy} context. In
149.157 + particular the term of the RHS may refer to earlier local entities
149.158 + from the auxiliary context, or hypothetical parameters from the
149.159 + target context. The result is the newly defined term (which is
149.160 + always a fixed variable with exactly the same name as specified for
149.161 + the LHS), together with an equational theorem that states the
149.162 + definition as a hypothetical fact.
149.163 +
149.164 + Unless an explicit name binding is given for the RHS, the resulting
149.165 + fact will be called \isa{b{\isacharunderscore}def}. Any given attributes are
149.166 + applied to that same fact --- immediately in the auxiliary context
149.167 + \emph{and} in any transformed versions stemming from target-specific
149.168 + policies or any later interpretations of results from the target
149.169 + context (think of \hyperlink{command.locale}{\mbox{\isa{\isacommand{locale}}}} and \hyperlink{command.interpretation}{\mbox{\isa{\isacommand{interpretation}}}},
149.170 + for example). This means that attributes should be usually plain
149.171 + declarations such as \hyperlink{attribute.simp}{\mbox{\isa{simp}}}, while non-trivial rules like
149.172 + \hyperlink{attribute.simplified}{\mbox{\isa{simplified}}} are better avoided.
149.173 +
149.174 + The \isa{kind} determines the theorem kind tag of the resulting
149.175 + fact. Typical examples are \verb|Thm.definitionK|, \verb|Thm.theoremK|, or \verb|Thm.internalK|.
149.176 +
149.177 + \item \verb|LocalTheory.note|~\isa{kind\ {\isacharparenleft}a{\isacharcomma}\ ths{\isacharparenright}\ lthy} is
149.178 + analogous to \verb|LocalTheory.define|, but defines facts instead of
149.179 + terms. There is also a slightly more general variant \verb|LocalTheory.notes| that defines several facts (with attribute
149.180 + expressions) simultaneously.
149.181 +
149.182 + This is essentially the internal version of the \hyperlink{command.lemmas}{\mbox{\isa{\isacommand{lemmas}}}}
149.183 + command, or \hyperlink{command.declare}{\mbox{\isa{\isacommand{declare}}}} if an empty name binding is given.
149.184 +
149.185 + \end{description}%
149.186 +\end{isamarkuptext}%
149.187 +\isamarkuptrue%
149.188 +%
149.189 +\endisatagmlref
149.190 +{\isafoldmlref}%
149.191 +%
149.192 +\isadelimmlref
149.193 +%
149.194 +\endisadelimmlref
149.195 +%
149.196 +\isamarkupsection{Morphisms and declarations%
149.197 +}
149.198 +\isamarkuptrue%
149.199 +%
149.200 +\begin{isamarkuptext}%
149.201 +FIXME%
149.202 +\end{isamarkuptext}%
149.203 +\isamarkuptrue%
149.204 +%
149.205 +\isadelimtheory
149.206 +%
149.207 +\endisadelimtheory
149.208 +%
149.209 +\isatagtheory
149.210 +\isacommand{end}\isamarkupfalse%
149.211 +%
149.212 +\endisatagtheory
149.213 +{\isafoldtheory}%
149.214 +%
149.215 +\isadelimtheory
149.216 +%
149.217 +\endisadelimtheory
149.218 +\isanewline
149.219 +\end{isabellebody}%
149.220 +%%% Local Variables:
149.221 +%%% mode: latex
149.222 +%%% TeX-master: "root"
149.223 +%%% End:
150.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
150.2 +++ b/doc-src/IsarImplementation/Thy/document/Syntax.tex Wed Mar 04 11:05:29 2009 +0100
150.3 @@ -0,0 +1,48 @@
150.4 +%
150.5 +\begin{isabellebody}%
150.6 +\def\isabellecontext{Syntax}%
150.7 +%
150.8 +\isadelimtheory
150.9 +%
150.10 +\endisadelimtheory
150.11 +%
150.12 +\isatagtheory
150.13 +\isacommand{theory}\isamarkupfalse%
150.14 +\ Syntax\isanewline
150.15 +\isakeyword{imports}\ Base\isanewline
150.16 +\isakeyword{begin}%
150.17 +\endisatagtheory
150.18 +{\isafoldtheory}%
150.19 +%
150.20 +\isadelimtheory
150.21 +%
150.22 +\endisadelimtheory
150.23 +%
150.24 +\isamarkupchapter{Syntax and type-checking%
150.25 +}
150.26 +\isamarkuptrue%
150.27 +%
150.28 +\begin{isamarkuptext}%
150.29 +FIXME%
150.30 +\end{isamarkuptext}%
150.31 +\isamarkuptrue%
150.32 +%
150.33 +\isadelimtheory
150.34 +%
150.35 +\endisadelimtheory
150.36 +%
150.37 +\isatagtheory
150.38 +\isacommand{end}\isamarkupfalse%
150.39 +%
150.40 +\endisatagtheory
150.41 +{\isafoldtheory}%
150.42 +%
150.43 +\isadelimtheory
150.44 +%
150.45 +\endisadelimtheory
150.46 +\isanewline
150.47 +\end{isabellebody}%
150.48 +%%% Local Variables:
150.49 +%%% mode: latex
150.50 +%%% TeX-master: "root"
150.51 +%%% End:
151.1 --- a/doc-src/IsarImplementation/Thy/document/base.tex Wed Mar 04 11:05:02 2009 +0100
151.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
151.3 @@ -1,32 +0,0 @@
151.4 -%
151.5 -\begin{isabellebody}%
151.6 -\def\isabellecontext{base}%
151.7 -%
151.8 -\isadelimtheory
151.9 -\isanewline
151.10 -\isanewline
151.11 -\isanewline
151.12 -%
151.13 -\endisadelimtheory
151.14 -%
151.15 -\isatagtheory
151.16 -\isacommand{theory}\isamarkupfalse%
151.17 -\ base\isanewline
151.18 -\isakeyword{imports}\ Pure\isanewline
151.19 -\isakeyword{uses}\ {\isachardoublequoteopen}{\isachardot}{\isachardot}{\isacharslash}{\isachardot}{\isachardot}{\isacharslash}antiquote{\isacharunderscore}setup{\isachardot}ML{\isachardoublequoteclose}\isanewline
151.20 -\isakeyword{begin}\isanewline
151.21 -\isanewline
151.22 -\isacommand{end}\isamarkupfalse%
151.23 -%
151.24 -\endisatagtheory
151.25 -{\isafoldtheory}%
151.26 -%
151.27 -\isadelimtheory
151.28 -\isanewline
151.29 -%
151.30 -\endisadelimtheory
151.31 -\end{isabellebody}%
151.32 -%%% Local Variables:
151.33 -%%% mode: latex
151.34 -%%% TeX-master: "root"
151.35 -%%% End:
152.1 --- a/doc-src/IsarImplementation/Thy/document/integration.tex Wed Mar 04 11:05:02 2009 +0100
152.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
152.3 @@ -1,521 +0,0 @@
152.4 -%
152.5 -\begin{isabellebody}%
152.6 -\def\isabellecontext{integration}%
152.7 -%
152.8 -\isadelimtheory
152.9 -\isanewline
152.10 -\isanewline
152.11 -\isanewline
152.12 -%
152.13 -\endisadelimtheory
152.14 -%
152.15 -\isatagtheory
152.16 -\isacommand{theory}\isamarkupfalse%
152.17 -\ integration\ \isakeyword{imports}\ base\ \isakeyword{begin}%
152.18 -\endisatagtheory
152.19 -{\isafoldtheory}%
152.20 -%
152.21 -\isadelimtheory
152.22 -%
152.23 -\endisadelimtheory
152.24 -%
152.25 -\isamarkupchapter{System integration%
152.26 -}
152.27 -\isamarkuptrue%
152.28 -%
152.29 -\isamarkupsection{Isar toplevel \label{sec:isar-toplevel}%
152.30 -}
152.31 -\isamarkuptrue%
152.32 -%
152.33 -\begin{isamarkuptext}%
152.34 -The Isar toplevel may be considered the centeral hub of the
152.35 - Isabelle/Isar system, where all key components and sub-systems are
152.36 - integrated into a single read-eval-print loop of Isar commands. We
152.37 - shall even incorporate the existing {\ML} toplevel of the compiler
152.38 - and run-time system (cf.\ \secref{sec:ML-toplevel}).
152.39 -
152.40 - Isabelle/Isar departs from the original ``LCF system architecture''
152.41 - where {\ML} was really The Meta Language for defining theories and
152.42 - conducting proofs. Instead, {\ML} now only serves as the
152.43 - implementation language for the system (and user extensions), while
152.44 - the specific Isar toplevel supports the concepts of theory and proof
152.45 - development natively. This includes the graph structure of theories
152.46 - and the block structure of proofs, support for unlimited undo,
152.47 - facilities for tracing, debugging, timing, profiling etc.
152.48 -
152.49 - \medskip The toplevel maintains an implicit state, which is
152.50 - transformed by a sequence of transitions -- either interactively or
152.51 - in batch-mode. In interactive mode, Isar state transitions are
152.52 - encapsulated as safe transactions, such that both failure and undo
152.53 - are handled conveniently without destroying the underlying draft
152.54 - theory (cf.~\secref{sec:context-theory}). In batch mode,
152.55 - transitions operate in a linear (destructive) fashion, such that
152.56 - error conditions abort the present attempt to construct a theory or
152.57 - proof altogether.
152.58 -
152.59 - The toplevel state is a disjoint sum of empty \isa{toplevel}, or
152.60 - \isa{theory}, or \isa{proof}. On entering the main Isar loop we
152.61 - start with an empty toplevel. A theory is commenced by giving a
152.62 - \isa{{\isasymTHEORY}} header; within a theory we may issue theory
152.63 - commands such as \isa{{\isasymDEFINITION}}, or state a \isa{{\isasymTHEOREM}} to be proven. Now we are within a proof state, with a
152.64 - rich collection of Isar proof commands for structured proof
152.65 - composition, or unstructured proof scripts. When the proof is
152.66 - concluded we get back to the theory, which is then updated by
152.67 - storing the resulting fact. Further theory declarations or theorem
152.68 - statements with proofs may follow, until we eventually conclude the
152.69 - theory development by issuing \isa{{\isasymEND}}. The resulting theory
152.70 - is then stored within the theory database and we are back to the
152.71 - empty toplevel.
152.72 -
152.73 - In addition to these proper state transformations, there are also
152.74 - some diagnostic commands for peeking at the toplevel state without
152.75 - modifying it (e.g.\ \isakeyword{thm}, \isakeyword{term},
152.76 - \isakeyword{print-cases}).%
152.77 -\end{isamarkuptext}%
152.78 -\isamarkuptrue%
152.79 -%
152.80 -\isadelimmlref
152.81 -%
152.82 -\endisadelimmlref
152.83 -%
152.84 -\isatagmlref
152.85 -%
152.86 -\begin{isamarkuptext}%
152.87 -\begin{mldecls}
152.88 - \indexmltype{Toplevel.state}\verb|type Toplevel.state| \\
152.89 - \indexml{Toplevel.UNDEF}\verb|Toplevel.UNDEF: exn| \\
152.90 - \indexml{Toplevel.is\_toplevel}\verb|Toplevel.is_toplevel: Toplevel.state -> bool| \\
152.91 - \indexml{Toplevel.theory\_of}\verb|Toplevel.theory_of: Toplevel.state -> theory| \\
152.92 - \indexml{Toplevel.proof\_of}\verb|Toplevel.proof_of: Toplevel.state -> Proof.state| \\
152.93 - \indexml{Toplevel.debug}\verb|Toplevel.debug: bool ref| \\
152.94 - \indexml{Toplevel.timing}\verb|Toplevel.timing: bool ref| \\
152.95 - \indexml{Toplevel.profiling}\verb|Toplevel.profiling: int ref| \\
152.96 - \end{mldecls}
152.97 -
152.98 - \begin{description}
152.99 -
152.100 - \item \verb|Toplevel.state| represents Isar toplevel states,
152.101 - which are normally manipulated through the concept of toplevel
152.102 - transitions only (\secref{sec:toplevel-transition}). Also note that
152.103 - a raw toplevel state is subject to the same linearity restrictions
152.104 - as a theory context (cf.~\secref{sec:context-theory}).
152.105 -
152.106 - \item \verb|Toplevel.UNDEF| is raised for undefined toplevel
152.107 - operations. Many operations work only partially for certain cases,
152.108 - since \verb|Toplevel.state| is a sum type.
152.109 -
152.110 - \item \verb|Toplevel.is_toplevel|~\isa{state} checks for an empty
152.111 - toplevel state.
152.112 -
152.113 - \item \verb|Toplevel.theory_of|~\isa{state} selects the theory of
152.114 - a theory or proof (!), otherwise raises \verb|Toplevel.UNDEF|.
152.115 -
152.116 - \item \verb|Toplevel.proof_of|~\isa{state} selects the Isar proof
152.117 - state if available, otherwise raises \verb|Toplevel.UNDEF|.
152.118 -
152.119 - \item \verb|set Toplevel.debug| makes the toplevel print further
152.120 - details about internal error conditions, exceptions being raised
152.121 - etc.
152.122 -
152.123 - \item \verb|set Toplevel.timing| makes the toplevel print timing
152.124 - information for each Isar command being executed.
152.125 -
152.126 - \item \verb|Toplevel.profiling|~\verb|:=|~\isa{n} controls
152.127 - low-level profiling of the underlying {\ML} runtime system. For
152.128 - Poly/ML, \isa{n\ {\isacharequal}\ {\isadigit{1}}} means time and \isa{n\ {\isacharequal}\ {\isadigit{2}}} space
152.129 - profiling.
152.130 -
152.131 - \end{description}%
152.132 -\end{isamarkuptext}%
152.133 -\isamarkuptrue%
152.134 -%
152.135 -\endisatagmlref
152.136 -{\isafoldmlref}%
152.137 -%
152.138 -\isadelimmlref
152.139 -%
152.140 -\endisadelimmlref
152.141 -%
152.142 -\isamarkupsubsection{Toplevel transitions \label{sec:toplevel-transition}%
152.143 -}
152.144 -\isamarkuptrue%
152.145 -%
152.146 -\begin{isamarkuptext}%
152.147 -An Isar toplevel transition consists of a partial function on the
152.148 - toplevel state, with additional information for diagnostics and
152.149 - error reporting: there are fields for command name, source position,
152.150 - optional source text, as well as flags for interactive-only commands
152.151 - (which issue a warning in batch-mode), printing of result state,
152.152 - etc.
152.153 -
152.154 - The operational part is represented as the sequential union of a
152.155 - list of partial functions, which are tried in turn until the first
152.156 - one succeeds. This acts like an outer case-expression for various
152.157 - alternative state transitions. For example, \isakeyword{qed} acts
152.158 - differently for a local proofs vs.\ the global ending of the main
152.159 - proof.
152.160 -
152.161 - Toplevel transitions are composed via transition transformers.
152.162 - Internally, Isar commands are put together from an empty transition
152.163 - extended by name and source position (and optional source text). It
152.164 - is then left to the individual command parser to turn the given
152.165 - concrete syntax into a suitable transition transformer that adjoin
152.166 - actual operations on a theory or proof state etc.%
152.167 -\end{isamarkuptext}%
152.168 -\isamarkuptrue%
152.169 -%
152.170 -\isadelimmlref
152.171 -%
152.172 -\endisadelimmlref
152.173 -%
152.174 -\isatagmlref
152.175 -%
152.176 -\begin{isamarkuptext}%
152.177 -\begin{mldecls}
152.178 - \indexml{Toplevel.print}\verb|Toplevel.print: Toplevel.transition -> Toplevel.transition| \\
152.179 - \indexml{Toplevel.no\_timing}\verb|Toplevel.no_timing: Toplevel.transition -> Toplevel.transition| \\
152.180 - \indexml{Toplevel.keep}\verb|Toplevel.keep: (Toplevel.state -> unit) ->|\isasep\isanewline%
152.181 -\verb| Toplevel.transition -> Toplevel.transition| \\
152.182 - \indexml{Toplevel.theory}\verb|Toplevel.theory: (theory -> theory) ->|\isasep\isanewline%
152.183 -\verb| Toplevel.transition -> Toplevel.transition| \\
152.184 - \indexml{Toplevel.theory\_to\_proof}\verb|Toplevel.theory_to_proof: (theory -> Proof.state) ->|\isasep\isanewline%
152.185 -\verb| Toplevel.transition -> Toplevel.transition| \\
152.186 - \indexml{Toplevel.proof}\verb|Toplevel.proof: (Proof.state -> Proof.state) ->|\isasep\isanewline%
152.187 -\verb| Toplevel.transition -> Toplevel.transition| \\
152.188 - \indexml{Toplevel.proofs}\verb|Toplevel.proofs: (Proof.state -> Proof.state Seq.seq) ->|\isasep\isanewline%
152.189 -\verb| Toplevel.transition -> Toplevel.transition| \\
152.190 - \indexml{Toplevel.end\_proof}\verb|Toplevel.end_proof: (bool -> Proof.state -> Proof.context) ->|\isasep\isanewline%
152.191 -\verb| Toplevel.transition -> Toplevel.transition| \\
152.192 - \end{mldecls}
152.193 -
152.194 - \begin{description}
152.195 -
152.196 - \item \verb|Toplevel.print|~\isa{tr} sets the print flag, which
152.197 - causes the toplevel loop to echo the result state (in interactive
152.198 - mode).
152.199 -
152.200 - \item \verb|Toplevel.no_timing|~\isa{tr} indicates that the
152.201 - transition should never show timing information, e.g.\ because it is
152.202 - a diagnostic command.
152.203 -
152.204 - \item \verb|Toplevel.keep|~\isa{tr} adjoins a diagnostic
152.205 - function.
152.206 -
152.207 - \item \verb|Toplevel.theory|~\isa{tr} adjoins a theory
152.208 - transformer.
152.209 -
152.210 - \item \verb|Toplevel.theory_to_proof|~\isa{tr} adjoins a global
152.211 - goal function, which turns a theory into a proof state. The theory
152.212 - may be changed before entering the proof; the generic Isar goal
152.213 - setup includes an argument that specifies how to apply the proven
152.214 - result to the theory, when the proof is finished.
152.215 -
152.216 - \item \verb|Toplevel.proof|~\isa{tr} adjoins a deterministic
152.217 - proof command, with a singleton result.
152.218 -
152.219 - \item \verb|Toplevel.proofs|~\isa{tr} adjoins a general proof
152.220 - command, with zero or more result states (represented as a lazy
152.221 - list).
152.222 -
152.223 - \item \verb|Toplevel.end_proof|~\isa{tr} adjoins a concluding
152.224 - proof command, that returns the resulting theory, after storing the
152.225 - resulting facts in the context etc.
152.226 -
152.227 - \end{description}%
152.228 -\end{isamarkuptext}%
152.229 -\isamarkuptrue%
152.230 -%
152.231 -\endisatagmlref
152.232 -{\isafoldmlref}%
152.233 -%
152.234 -\isadelimmlref
152.235 -%
152.236 -\endisadelimmlref
152.237 -%
152.238 -\isamarkupsubsection{Toplevel control%
152.239 -}
152.240 -\isamarkuptrue%
152.241 -%
152.242 -\begin{isamarkuptext}%
152.243 -There are a few special control commands that modify the behavior
152.244 - the toplevel itself, and only make sense in interactive mode. Under
152.245 - normal circumstances, the user encounters these only implicitly as
152.246 - part of the protocol between the Isabelle/Isar system and a
152.247 - user-interface such as ProofGeneral.
152.248 -
152.249 - \begin{description}
152.250 -
152.251 - \item \isacommand{undo} follows the three-level hierarchy of empty
152.252 - toplevel vs.\ theory vs.\ proof: undo within a proof reverts to the
152.253 - previous proof context, undo after a proof reverts to the theory
152.254 - before the initial goal statement, undo of a theory command reverts
152.255 - to the previous theory value, undo of a theory header discontinues
152.256 - the current theory development and removes it from the theory
152.257 - database (\secref{sec:theory-database}).
152.258 -
152.259 - \item \isacommand{kill} aborts the current level of development:
152.260 - kill in a proof context reverts to the theory before the initial
152.261 - goal statement, kill in a theory context aborts the current theory
152.262 - development, removing it from the database.
152.263 -
152.264 - \item \isacommand{exit} drops out of the Isar toplevel into the
152.265 - underlying {\ML} toplevel (\secref{sec:ML-toplevel}). The Isar
152.266 - toplevel state is preserved and may be continued later.
152.267 -
152.268 - \item \isacommand{quit} terminates the Isabelle/Isar process without
152.269 - saving.
152.270 -
152.271 - \end{description}%
152.272 -\end{isamarkuptext}%
152.273 -\isamarkuptrue%
152.274 -%
152.275 -\isamarkupsection{ML toplevel \label{sec:ML-toplevel}%
152.276 -}
152.277 -\isamarkuptrue%
152.278 -%
152.279 -\begin{isamarkuptext}%
152.280 -The {\ML} toplevel provides a read-compile-eval-print loop for {\ML}
152.281 - values, types, structures, and functors. {\ML} declarations operate
152.282 - on the global system state, which consists of the compiler
152.283 - environment plus the values of {\ML} reference variables. There is
152.284 - no clean way to undo {\ML} declarations, except for reverting to a
152.285 - previously saved state of the whole Isabelle process. {\ML} input
152.286 - is either read interactively from a TTY, or from a string (usually
152.287 - within a theory text), or from a source file (usually loaded from a
152.288 - theory).
152.289 -
152.290 - Whenever the {\ML} toplevel is active, the current Isabelle theory
152.291 - context is passed as an internal reference variable. Thus {\ML}
152.292 - code may access the theory context during compilation, it may even
152.293 - change the value of a theory being under construction --- while
152.294 - observing the usual linearity restrictions
152.295 - (cf.~\secref{sec:context-theory}).%
152.296 -\end{isamarkuptext}%
152.297 -\isamarkuptrue%
152.298 -%
152.299 -\isadelimmlref
152.300 -%
152.301 -\endisadelimmlref
152.302 -%
152.303 -\isatagmlref
152.304 -%
152.305 -\begin{isamarkuptext}%
152.306 -\begin{mldecls}
152.307 - \indexml{the\_context}\verb|the_context: unit -> theory| \\
152.308 - \indexml{Context.$>$$>$ }\verb|Context.>> : (Context.generic -> Context.generic) -> unit| \\
152.309 - \end{mldecls}
152.310 -
152.311 - \begin{description}
152.312 -
152.313 - \item \verb|the_context ()| refers to the theory context of the
152.314 - {\ML} toplevel --- at compile time! {\ML} code needs to take care
152.315 - to refer to \verb|the_context ()| correctly. Recall that
152.316 - evaluation of a function body is delayed until actual runtime.
152.317 - Moreover, persistent {\ML} toplevel bindings to an unfinished theory
152.318 - should be avoided: code should either project out the desired
152.319 - information immediately, or produce an explicit \verb|theory_ref| (cf.\ \secref{sec:context-theory}).
152.320 -
152.321 - \item \verb|Context.>>|~\isa{f} applies context transformation
152.322 - \isa{f} to the implicit context of the {\ML} toplevel.
152.323 -
152.324 - \end{description}
152.325 -
152.326 - It is very important to note that the above functions are really
152.327 - restricted to the compile time, even though the {\ML} compiler is
152.328 - invoked at runtime! The majority of {\ML} code uses explicit
152.329 - functional arguments of a theory or proof context instead. Thus it
152.330 - may be invoked for an arbitrary context later on, without having to
152.331 - worry about any operational details.
152.332 -
152.333 - \bigskip
152.334 -
152.335 - \begin{mldecls}
152.336 - \indexml{Isar.main}\verb|Isar.main: unit -> unit| \\
152.337 - \indexml{Isar.loop}\verb|Isar.loop: unit -> unit| \\
152.338 - \indexml{Isar.state}\verb|Isar.state: unit -> Toplevel.state| \\
152.339 - \indexml{Isar.exn}\verb|Isar.exn: unit -> (exn * string) option| \\
152.340 - \indexml{Isar.context}\verb|Isar.context: unit -> Proof.context| \\
152.341 - \indexml{Isar.goal}\verb|Isar.goal: unit -> thm| \\
152.342 - \end{mldecls}
152.343 -
152.344 - \begin{description}
152.345 -
152.346 - \item \verb|Isar.main ()| invokes the Isar toplevel from {\ML},
152.347 - initializing an empty toplevel state.
152.348 -
152.349 - \item \verb|Isar.loop ()| continues the Isar toplevel with the
152.350 - current state, after having dropped out of the Isar toplevel loop.
152.351 -
152.352 - \item \verb|Isar.state ()| and \verb|Isar.exn ()| get current
152.353 - toplevel state and error condition, respectively. This only works
152.354 - after having dropped out of the Isar toplevel loop.
152.355 -
152.356 - \item \verb|Isar.context ()| produces the proof context from \verb|Isar.state ()|, analogous to \verb|Context.proof_of|
152.357 - (\secref{sec:generic-context}).
152.358 -
152.359 - \item \verb|Isar.goal ()| picks the tactical goal from \verb|Isar.state ()|, represented as a theorem according to
152.360 - \secref{sec:tactical-goals}.
152.361 -
152.362 - \end{description}%
152.363 -\end{isamarkuptext}%
152.364 -\isamarkuptrue%
152.365 -%
152.366 -\endisatagmlref
152.367 -{\isafoldmlref}%
152.368 -%
152.369 -\isadelimmlref
152.370 -%
152.371 -\endisadelimmlref
152.372 -%
152.373 -\isamarkupsection{Theory database \label{sec:theory-database}%
152.374 -}
152.375 -\isamarkuptrue%
152.376 -%
152.377 -\begin{isamarkuptext}%
152.378 -The theory database maintains a collection of theories, together
152.379 - with some administrative information about their original sources,
152.380 - which are held in an external store (i.e.\ some directory within the
152.381 - regular file system).
152.382 -
152.383 - The theory database is organized as a directed acyclic graph;
152.384 - entries are referenced by theory name. Although some additional
152.385 - interfaces allow to include a directory specification as well, this
152.386 - is only a hint to the underlying theory loader. The internal theory
152.387 - name space is flat!
152.388 -
152.389 - Theory \isa{A} is associated with the main theory file \isa{A}\verb,.thy,, which needs to be accessible through the theory
152.390 - loader path. Any number of additional {\ML} source files may be
152.391 - associated with each theory, by declaring these dependencies in the
152.392 - theory header as \isa{{\isasymUSES}}, and loading them consecutively
152.393 - within the theory context. The system keeps track of incoming {\ML}
152.394 - sources and associates them with the current theory. The file
152.395 - \isa{A}\verb,.ML, is loaded after a theory has been concluded, in
152.396 - order to support legacy proof {\ML} proof scripts.
152.397 -
152.398 - The basic internal actions of the theory database are \isa{update}, \isa{outdate}, and \isa{remove}:
152.399 -
152.400 - \begin{itemize}
152.401 -
152.402 - \item \isa{update\ A} introduces a link of \isa{A} with a
152.403 - \isa{theory} value of the same name; it asserts that the theory
152.404 - sources are now consistent with that value;
152.405 -
152.406 - \item \isa{outdate\ A} invalidates the link of a theory database
152.407 - entry to its sources, but retains the present theory value;
152.408 -
152.409 - \item \isa{remove\ A} deletes entry \isa{A} from the theory
152.410 - database.
152.411 -
152.412 - \end{itemize}
152.413 -
152.414 - These actions are propagated to sub- or super-graphs of a theory
152.415 - entry as expected, in order to preserve global consistency of the
152.416 - state of all loaded theories with the sources of the external store.
152.417 - This implies certain causalities between actions: \isa{update}
152.418 - or \isa{outdate} of an entry will \isa{outdate} all
152.419 - descendants; \isa{remove} will \isa{remove} all descendants.
152.420 -
152.421 - \medskip There are separate user-level interfaces to operate on the
152.422 - theory database directly or indirectly. The primitive actions then
152.423 - just happen automatically while working with the system. In
152.424 - particular, processing a theory header \isa{{\isasymTHEORY}\ A\ {\isasymIMPORTS}\ B\isactrlsub {\isadigit{1}}\ {\isasymdots}\ B\isactrlsub n\ {\isasymBEGIN}} ensures that the
152.425 - sub-graph of the collective imports \isa{B\isactrlsub {\isadigit{1}}\ {\isasymdots}\ B\isactrlsub n}
152.426 - is up-to-date, too. Earlier theories are reloaded as required, with
152.427 - \isa{update} actions proceeding in topological order according to
152.428 - theory dependencies. There may be also a wave of implied \isa{outdate} actions for derived theory nodes until a stable situation
152.429 - is achieved eventually.%
152.430 -\end{isamarkuptext}%
152.431 -\isamarkuptrue%
152.432 -%
152.433 -\isadelimmlref
152.434 -%
152.435 -\endisadelimmlref
152.436 -%
152.437 -\isatagmlref
152.438 -%
152.439 -\begin{isamarkuptext}%
152.440 -\begin{mldecls}
152.441 - \indexml{theory}\verb|theory: string -> theory| \\
152.442 - \indexml{use\_thy}\verb|use_thy: string -> unit| \\
152.443 - \indexml{use\_thys}\verb|use_thys: string list -> unit| \\
152.444 - \indexml{ThyInfo.touch\_thy}\verb|ThyInfo.touch_thy: string -> unit| \\
152.445 - \indexml{ThyInfo.remove\_thy}\verb|ThyInfo.remove_thy: string -> unit| \\[1ex]
152.446 - \indexml{ThyInfo.begin\_theory}\verb|ThyInfo.begin_theory|\verb|: ... -> bool -> theory| \\
152.447 - \indexml{ThyInfo.end\_theory}\verb|ThyInfo.end_theory: theory -> unit| \\
152.448 - \indexml{ThyInfo.register\_theory}\verb|ThyInfo.register_theory: theory -> unit| \\[1ex]
152.449 - \verb|datatype action = Update |\verb,|,\verb| Outdate |\verb,|,\verb| Remove| \\
152.450 - \indexml{ThyInfo.add\_hook}\verb|ThyInfo.add_hook: (ThyInfo.action -> string -> unit) -> unit| \\
152.451 - \end{mldecls}
152.452 -
152.453 - \begin{description}
152.454 -
152.455 - \item \verb|theory|~\isa{A} retrieves the theory value presently
152.456 - associated with name \isa{A}. Note that the result might be
152.457 - outdated.
152.458 -
152.459 - \item \verb|use_thy|~\isa{A} ensures that theory \isa{A} is fully
152.460 - up-to-date wrt.\ the external file store, reloading outdated
152.461 - ancestors as required.
152.462 -
152.463 - \item \verb|use_thys| is similar to \verb|use_thy|, but handles
152.464 - several theories simultaneously. Thus it acts like processing the
152.465 - import header of a theory, without performing the merge of the
152.466 - result, though.
152.467 -
152.468 - \item \verb|ThyInfo.touch_thy|~\isa{A} performs and \isa{outdate} action
152.469 - on theory \isa{A} and all descendants.
152.470 -
152.471 - \item \verb|ThyInfo.remove_thy|~\isa{A} deletes theory \isa{A} and all
152.472 - descendants from the theory database.
152.473 -
152.474 - \item \verb|ThyInfo.begin_theory| is the basic operation behind a
152.475 - \isa{{\isasymTHEORY}} header declaration. This is {\ML} functions is
152.476 - normally not invoked directly.
152.477 -
152.478 - \item \verb|ThyInfo.end_theory| concludes the loading of a theory
152.479 - proper and stores the result in the theory database.
152.480 -
152.481 - \item \verb|ThyInfo.register_theory|~\isa{text\ thy} registers an
152.482 - existing theory value with the theory loader database. There is no
152.483 - management of associated sources.
152.484 -
152.485 - \item \verb|ThyInfo.add_hook|~\isa{f} registers function \isa{f} as a hook for theory database actions. The function will be
152.486 - invoked with the action and theory name being involved; thus derived
152.487 - actions may be performed in associated system components, e.g.\
152.488 - maintaining the state of an editor for the theory sources.
152.489 -
152.490 - The kind and order of actions occurring in practice depends both on
152.491 - user interactions and the internal process of resolving theory
152.492 - imports. Hooks should not rely on a particular policy here! Any
152.493 - exceptions raised by the hook are ignored.
152.494 -
152.495 - \end{description}%
152.496 -\end{isamarkuptext}%
152.497 -\isamarkuptrue%
152.498 -%
152.499 -\endisatagmlref
152.500 -{\isafoldmlref}%
152.501 -%
152.502 -\isadelimmlref
152.503 -%
152.504 -\endisadelimmlref
152.505 -%
152.506 -\isadelimtheory
152.507 -%
152.508 -\endisadelimtheory
152.509 -%
152.510 -\isatagtheory
152.511 -\isacommand{end}\isamarkupfalse%
152.512 -%
152.513 -\endisatagtheory
152.514 -{\isafoldtheory}%
152.515 -%
152.516 -\isadelimtheory
152.517 -%
152.518 -\endisadelimtheory
152.519 -\isanewline
152.520 -\end{isabellebody}%
152.521 -%%% Local Variables:
152.522 -%%% mode: latex
152.523 -%%% TeX-master: "root"
152.524 -%%% End:
153.1 --- a/doc-src/IsarImplementation/Thy/document/isar.tex Wed Mar 04 11:05:02 2009 +0100
153.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
153.3 @@ -1,91 +0,0 @@
153.4 -%
153.5 -\begin{isabellebody}%
153.6 -\def\isabellecontext{isar}%
153.7 -%
153.8 -\isadelimtheory
153.9 -\isanewline
153.10 -\isanewline
153.11 -\isanewline
153.12 -%
153.13 -\endisadelimtheory
153.14 -%
153.15 -\isatagtheory
153.16 -\isacommand{theory}\isamarkupfalse%
153.17 -\ isar\ \isakeyword{imports}\ base\ \isakeyword{begin}%
153.18 -\endisatagtheory
153.19 -{\isafoldtheory}%
153.20 -%
153.21 -\isadelimtheory
153.22 -%
153.23 -\endisadelimtheory
153.24 -%
153.25 -\isamarkupchapter{Isar proof texts%
153.26 -}
153.27 -\isamarkuptrue%
153.28 -%
153.29 -\isamarkupsection{Proof context%
153.30 -}
153.31 -\isamarkuptrue%
153.32 -%
153.33 -\begin{isamarkuptext}%
153.34 -FIXME%
153.35 -\end{isamarkuptext}%
153.36 -\isamarkuptrue%
153.37 -%
153.38 -\isamarkupsection{Proof state \label{sec:isar-proof-state}%
153.39 -}
153.40 -\isamarkuptrue%
153.41 -%
153.42 -\begin{isamarkuptext}%
153.43 -FIXME
153.44 -
153.45 -\glossary{Proof state}{The whole configuration of a structured proof,
153.46 -consisting of a \seeglossary{proof context} and an optional
153.47 -\seeglossary{structured goal}. Internally, an Isar proof state is
153.48 -organized as a stack to accomodate block structure of proof texts.
153.49 -For historical reasons, a low-level \seeglossary{tactical goal} is
153.50 -occasionally called ``proof state'' as well.}
153.51 -
153.52 -\glossary{Structured goal}{FIXME}
153.53 -
153.54 -\glossary{Goal}{See \seeglossary{tactical goal} or \seeglossary{structured goal}. \norefpage}%
153.55 -\end{isamarkuptext}%
153.56 -\isamarkuptrue%
153.57 -%
153.58 -\isamarkupsection{Proof methods%
153.59 -}
153.60 -\isamarkuptrue%
153.61 -%
153.62 -\begin{isamarkuptext}%
153.63 -FIXME%
153.64 -\end{isamarkuptext}%
153.65 -\isamarkuptrue%
153.66 -%
153.67 -\isamarkupsection{Attributes%
153.68 -}
153.69 -\isamarkuptrue%
153.70 -%
153.71 -\begin{isamarkuptext}%
153.72 -FIXME ?!%
153.73 -\end{isamarkuptext}%
153.74 -\isamarkuptrue%
153.75 -%
153.76 -\isadelimtheory
153.77 -%
153.78 -\endisadelimtheory
153.79 -%
153.80 -\isatagtheory
153.81 -\isacommand{end}\isamarkupfalse%
153.82 -%
153.83 -\endisatagtheory
153.84 -{\isafoldtheory}%
153.85 -%
153.86 -\isadelimtheory
153.87 -%
153.88 -\endisadelimtheory
153.89 -\isanewline
153.90 -\end{isabellebody}%
153.91 -%%% Local Variables:
153.92 -%%% mode: latex
153.93 -%%% TeX-master: "root"
153.94 -%%% End:
154.1 --- a/doc-src/IsarImplementation/Thy/document/locale.tex Wed Mar 04 11:05:02 2009 +0100
154.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
154.3 @@ -1,73 +0,0 @@
154.4 -%
154.5 -\begin{isabellebody}%
154.6 -\def\isabellecontext{locale}%
154.7 -%
154.8 -\isadelimtheory
154.9 -\isanewline
154.10 -\isanewline
154.11 -\isanewline
154.12 -%
154.13 -\endisadelimtheory
154.14 -%
154.15 -\isatagtheory
154.16 -\isacommand{theory}\isamarkupfalse%
154.17 -\ {\isachardoublequoteopen}locale{\isachardoublequoteclose}\ \isakeyword{imports}\ base\ \isakeyword{begin}%
154.18 -\endisatagtheory
154.19 -{\isafoldtheory}%
154.20 -%
154.21 -\isadelimtheory
154.22 -%
154.23 -\endisadelimtheory
154.24 -%
154.25 -\isamarkupchapter{Structured specifications%
154.26 -}
154.27 -\isamarkuptrue%
154.28 -%
154.29 -\isamarkupsection{Specification elements%
154.30 -}
154.31 -\isamarkuptrue%
154.32 -%
154.33 -\begin{isamarkuptext}%
154.34 -FIXME%
154.35 -\end{isamarkuptext}%
154.36 -\isamarkuptrue%
154.37 -%
154.38 -\isamarkupsection{Type-inference%
154.39 -}
154.40 -\isamarkuptrue%
154.41 -%
154.42 -\begin{isamarkuptext}%
154.43 -FIXME%
154.44 -\end{isamarkuptext}%
154.45 -\isamarkuptrue%
154.46 -%
154.47 -\isamarkupsection{Local theories%
154.48 -}
154.49 -\isamarkuptrue%
154.50 -%
154.51 -\begin{isamarkuptext}%
154.52 -FIXME
154.53 -
154.54 - \glossary{Local theory}{FIXME}%
154.55 -\end{isamarkuptext}%
154.56 -\isamarkuptrue%
154.57 -%
154.58 -\isadelimtheory
154.59 -%
154.60 -\endisadelimtheory
154.61 -%
154.62 -\isatagtheory
154.63 -\isacommand{end}\isamarkupfalse%
154.64 -%
154.65 -\endisatagtheory
154.66 -{\isafoldtheory}%
154.67 -%
154.68 -\isadelimtheory
154.69 -%
154.70 -\endisadelimtheory
154.71 -\isanewline
154.72 -\end{isabellebody}%
154.73 -%%% Local Variables:
154.74 -%%% mode: latex
154.75 -%%% TeX-master: "root"
154.76 -%%% End:
155.1 --- a/doc-src/IsarImplementation/Thy/document/logic.tex Wed Mar 04 11:05:02 2009 +0100
155.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
155.3 @@ -1,886 +0,0 @@
155.4 -%
155.5 -\begin{isabellebody}%
155.6 -\def\isabellecontext{logic}%
155.7 -%
155.8 -\isadelimtheory
155.9 -%
155.10 -\endisadelimtheory
155.11 -%
155.12 -\isatagtheory
155.13 -\isacommand{theory}\isamarkupfalse%
155.14 -\ logic\ \isakeyword{imports}\ base\ \isakeyword{begin}%
155.15 -\endisatagtheory
155.16 -{\isafoldtheory}%
155.17 -%
155.18 -\isadelimtheory
155.19 -%
155.20 -\endisadelimtheory
155.21 -%
155.22 -\isamarkupchapter{Primitive logic \label{ch:logic}%
155.23 -}
155.24 -\isamarkuptrue%
155.25 -%
155.26 -\begin{isamarkuptext}%
155.27 -The logical foundations of Isabelle/Isar are that of the Pure logic,
155.28 - which has been introduced as a natural-deduction framework in
155.29 - \cite{paulson700}. This is essentially the same logic as ``\isa{{\isasymlambda}HOL}'' in the more abstract setting of Pure Type Systems (PTS)
155.30 - \cite{Barendregt-Geuvers:2001}, although there are some key
155.31 - differences in the specific treatment of simple types in
155.32 - Isabelle/Pure.
155.33 -
155.34 - Following type-theoretic parlance, the Pure logic consists of three
155.35 - levels of \isa{{\isasymlambda}}-calculus with corresponding arrows, \isa{{\isasymRightarrow}} for syntactic function space (terms depending on terms), \isa{{\isasymAnd}} for universal quantification (proofs depending on terms), and
155.36 - \isa{{\isasymLongrightarrow}} for implication (proofs depending on proofs).
155.37 -
155.38 - Derivations are relative to a logical theory, which declares type
155.39 - constructors, constants, and axioms. Theory declarations support
155.40 - schematic polymorphism, which is strictly speaking outside the
155.41 - logic.\footnote{This is the deeper logical reason, why the theory
155.42 - context \isa{{\isasymTheta}} is separate from the proof context \isa{{\isasymGamma}}
155.43 - of the core calculus.}%
155.44 -\end{isamarkuptext}%
155.45 -\isamarkuptrue%
155.46 -%
155.47 -\isamarkupsection{Types \label{sec:types}%
155.48 -}
155.49 -\isamarkuptrue%
155.50 -%
155.51 -\begin{isamarkuptext}%
155.52 -The language of types is an uninterpreted order-sorted first-order
155.53 - algebra; types are qualified by ordered type classes.
155.54 -
155.55 - \medskip A \emph{type class} is an abstract syntactic entity
155.56 - declared in the theory context. The \emph{subclass relation} \isa{c\isactrlisub {\isadigit{1}}\ {\isasymsubseteq}\ c\isactrlisub {\isadigit{2}}} is specified by stating an acyclic
155.57 - generating relation; the transitive closure is maintained
155.58 - internally. The resulting relation is an ordering: reflexive,
155.59 - transitive, and antisymmetric.
155.60 -
155.61 - A \emph{sort} is a list of type classes written as \isa{s\ {\isacharequal}\ {\isacharbraceleft}c\isactrlisub {\isadigit{1}}{\isacharcomma}\ {\isasymdots}{\isacharcomma}\ c\isactrlisub m{\isacharbraceright}}, which represents symbolic
155.62 - intersection. Notationally, the curly braces are omitted for
155.63 - singleton intersections, i.e.\ any class \isa{c} may be read as
155.64 - a sort \isa{{\isacharbraceleft}c{\isacharbraceright}}. The ordering on type classes is extended to
155.65 - sorts according to the meaning of intersections: \isa{{\isacharbraceleft}c\isactrlisub {\isadigit{1}}{\isacharcomma}\ {\isasymdots}\ c\isactrlisub m{\isacharbraceright}\ {\isasymsubseteq}\ {\isacharbraceleft}d\isactrlisub {\isadigit{1}}{\isacharcomma}\ {\isasymdots}{\isacharcomma}\ d\isactrlisub n{\isacharbraceright}} iff
155.66 - \isa{{\isasymforall}j{\isachardot}\ {\isasymexists}i{\isachardot}\ c\isactrlisub i\ {\isasymsubseteq}\ d\isactrlisub j}. The empty intersection
155.67 - \isa{{\isacharbraceleft}{\isacharbraceright}} refers to the universal sort, which is the largest
155.68 - element wrt.\ the sort order. The intersections of all (finitely
155.69 - many) classes declared in the current theory are the minimal
155.70 - elements wrt.\ the sort order.
155.71 -
155.72 - \medskip A \emph{fixed type variable} is a pair of a basic name
155.73 - (starting with a \isa{{\isacharprime}} character) and a sort constraint, e.g.\
155.74 - \isa{{\isacharparenleft}{\isacharprime}a{\isacharcomma}\ s{\isacharparenright}} which is usually printed as \isa{{\isasymalpha}\isactrlisub s}.
155.75 - A \emph{schematic type variable} is a pair of an indexname and a
155.76 - sort constraint, e.g.\ \isa{{\isacharparenleft}{\isacharparenleft}{\isacharprime}a{\isacharcomma}\ {\isadigit{0}}{\isacharparenright}{\isacharcomma}\ s{\isacharparenright}} which is usually
155.77 - printed as \isa{{\isacharquery}{\isasymalpha}\isactrlisub s}.
155.78 -
155.79 - Note that \emph{all} syntactic components contribute to the identity
155.80 - of type variables, including the sort constraint. The core logic
155.81 - handles type variables with the same name but different sorts as
155.82 - different, although some outer layers of the system make it hard to
155.83 - produce anything like this.
155.84 -
155.85 - A \emph{type constructor} \isa{{\isasymkappa}} is a \isa{k}-ary operator
155.86 - on types declared in the theory. Type constructor application is
155.87 - written postfix as \isa{{\isacharparenleft}{\isasymalpha}\isactrlisub {\isadigit{1}}{\isacharcomma}\ {\isasymdots}{\isacharcomma}\ {\isasymalpha}\isactrlisub k{\isacharparenright}{\isasymkappa}}. For
155.88 - \isa{k\ {\isacharequal}\ {\isadigit{0}}} the argument tuple is omitted, e.g.\ \isa{prop}
155.89 - instead of \isa{{\isacharparenleft}{\isacharparenright}prop}. For \isa{k\ {\isacharequal}\ {\isadigit{1}}} the parentheses
155.90 - are omitted, e.g.\ \isa{{\isasymalpha}\ list} instead of \isa{{\isacharparenleft}{\isasymalpha}{\isacharparenright}list}.
155.91 - Further notation is provided for specific constructors, notably the
155.92 - right-associative infix \isa{{\isasymalpha}\ {\isasymRightarrow}\ {\isasymbeta}} instead of \isa{{\isacharparenleft}{\isasymalpha}{\isacharcomma}\ {\isasymbeta}{\isacharparenright}fun}.
155.93 -
155.94 - A \emph{type} is defined inductively over type variables and type
155.95 - constructors as follows: \isa{{\isasymtau}\ {\isacharequal}\ {\isasymalpha}\isactrlisub s\ {\isacharbar}\ {\isacharquery}{\isasymalpha}\isactrlisub s\ {\isacharbar}\ {\isacharparenleft}{\isasymtau}\isactrlsub {\isadigit{1}}{\isacharcomma}\ {\isasymdots}{\isacharcomma}\ {\isasymtau}\isactrlsub k{\isacharparenright}{\isasymkappa}}.
155.96 -
155.97 - A \emph{type abbreviation} is a syntactic definition \isa{{\isacharparenleft}\isactrlvec {\isasymalpha}{\isacharparenright}{\isasymkappa}\ {\isacharequal}\ {\isasymtau}} of an arbitrary type expression \isa{{\isasymtau}} over
155.98 - variables \isa{\isactrlvec {\isasymalpha}}. Type abbreviations appear as type
155.99 - constructors in the syntax, but are expanded before entering the
155.100 - logical core.
155.101 -
155.102 - A \emph{type arity} declares the image behavior of a type
155.103 - constructor wrt.\ the algebra of sorts: \isa{{\isasymkappa}\ {\isacharcolon}{\isacharcolon}\ {\isacharparenleft}s\isactrlisub {\isadigit{1}}{\isacharcomma}\ {\isasymdots}{\isacharcomma}\ s\isactrlisub k{\isacharparenright}s} means that \isa{{\isacharparenleft}{\isasymtau}\isactrlisub {\isadigit{1}}{\isacharcomma}\ {\isasymdots}{\isacharcomma}\ {\isasymtau}\isactrlisub k{\isacharparenright}{\isasymkappa}} is
155.104 - of sort \isa{s} if every argument type \isa{{\isasymtau}\isactrlisub i} is
155.105 - of sort \isa{s\isactrlisub i}. Arity declarations are implicitly
155.106 - completed, i.e.\ \isa{{\isasymkappa}\ {\isacharcolon}{\isacharcolon}\ {\isacharparenleft}\isactrlvec s{\isacharparenright}c} entails \isa{{\isasymkappa}\ {\isacharcolon}{\isacharcolon}\ {\isacharparenleft}\isactrlvec s{\isacharparenright}c{\isacharprime}} for any \isa{c{\isacharprime}\ {\isasymsupseteq}\ c}.
155.107 -
155.108 - \medskip The sort algebra is always maintained as \emph{coregular},
155.109 - which means that type arities are consistent with the subclass
155.110 - relation: for any type constructor \isa{{\isasymkappa}}, and classes \isa{c\isactrlisub {\isadigit{1}}\ {\isasymsubseteq}\ c\isactrlisub {\isadigit{2}}}, and arities \isa{{\isasymkappa}\ {\isacharcolon}{\isacharcolon}\ {\isacharparenleft}\isactrlvec s\isactrlisub {\isadigit{1}}{\isacharparenright}c\isactrlisub {\isadigit{1}}} and \isa{{\isasymkappa}\ {\isacharcolon}{\isacharcolon}\ {\isacharparenleft}\isactrlvec s\isactrlisub {\isadigit{2}}{\isacharparenright}c\isactrlisub {\isadigit{2}}} holds \isa{\isactrlvec s\isactrlisub {\isadigit{1}}\ {\isasymsubseteq}\ \isactrlvec s\isactrlisub {\isadigit{2}}} component-wise.
155.111 -
155.112 - The key property of a coregular order-sorted algebra is that sort
155.113 - constraints can be solved in a most general fashion: for each type
155.114 - constructor \isa{{\isasymkappa}} and sort \isa{s} there is a most general
155.115 - vector of argument sorts \isa{{\isacharparenleft}s\isactrlisub {\isadigit{1}}{\isacharcomma}\ {\isasymdots}{\isacharcomma}\ s\isactrlisub k{\isacharparenright}} such
155.116 - that a type scheme \isa{{\isacharparenleft}{\isasymalpha}\isactrlbsub s\isactrlisub {\isadigit{1}}\isactrlesub {\isacharcomma}\ {\isasymdots}{\isacharcomma}\ {\isasymalpha}\isactrlbsub s\isactrlisub k\isactrlesub {\isacharparenright}{\isasymkappa}} is of sort \isa{s}.
155.117 - Consequently, type unification has most general solutions (modulo
155.118 - equivalence of sorts), so type-inference produces primary types as
155.119 - expected \cite{nipkow-prehofer}.%
155.120 -\end{isamarkuptext}%
155.121 -\isamarkuptrue%
155.122 -%
155.123 -\isadelimmlref
155.124 -%
155.125 -\endisadelimmlref
155.126 -%
155.127 -\isatagmlref
155.128 -%
155.129 -\begin{isamarkuptext}%
155.130 -\begin{mldecls}
155.131 - \indexmltype{class}\verb|type class| \\
155.132 - \indexmltype{sort}\verb|type sort| \\
155.133 - \indexmltype{arity}\verb|type arity| \\
155.134 - \indexmltype{typ}\verb|type typ| \\
155.135 - \indexml{map\_atyps}\verb|map_atyps: (typ -> typ) -> typ -> typ| \\
155.136 - \indexml{fold\_atyps}\verb|fold_atyps: (typ -> 'a -> 'a) -> typ -> 'a -> 'a| \\
155.137 - \end{mldecls}
155.138 - \begin{mldecls}
155.139 - \indexml{Sign.subsort}\verb|Sign.subsort: theory -> sort * sort -> bool| \\
155.140 - \indexml{Sign.of\_sort}\verb|Sign.of_sort: theory -> typ * sort -> bool| \\
155.141 - \indexml{Sign.add\_types}\verb|Sign.add_types: (string * int * mixfix) list -> theory -> theory| \\
155.142 - \indexml{Sign.add\_tyabbrs\_i}\verb|Sign.add_tyabbrs_i: |\isasep\isanewline%
155.143 -\verb| (string * string list * typ * mixfix) list -> theory -> theory| \\
155.144 - \indexml{Sign.primitive\_class}\verb|Sign.primitive_class: string * class list -> theory -> theory| \\
155.145 - \indexml{Sign.primitive\_classrel}\verb|Sign.primitive_classrel: class * class -> theory -> theory| \\
155.146 - \indexml{Sign.primitive\_arity}\verb|Sign.primitive_arity: arity -> theory -> theory| \\
155.147 - \end{mldecls}
155.148 -
155.149 - \begin{description}
155.150 -
155.151 - \item \verb|class| represents type classes; this is an alias for
155.152 - \verb|string|.
155.153 -
155.154 - \item \verb|sort| represents sorts; this is an alias for
155.155 - \verb|class list|.
155.156 -
155.157 - \item \verb|arity| represents type arities; this is an alias for
155.158 - triples of the form \isa{{\isacharparenleft}{\isasymkappa}{\isacharcomma}\ \isactrlvec s{\isacharcomma}\ s{\isacharparenright}} for \isa{{\isasymkappa}\ {\isacharcolon}{\isacharcolon}\ {\isacharparenleft}\isactrlvec s{\isacharparenright}s} described above.
155.159 -
155.160 - \item \verb|typ| represents types; this is a datatype with
155.161 - constructors \verb|TFree|, \verb|TVar|, \verb|Type|.
155.162 -
155.163 - \item \verb|map_atyps|~\isa{f\ {\isasymtau}} applies the mapping \isa{f}
155.164 - to all atomic types (\verb|TFree|, \verb|TVar|) occurring in \isa{{\isasymtau}}.
155.165 -
155.166 - \item \verb|fold_atyps|~\isa{f\ {\isasymtau}} iterates the operation \isa{f} over all occurrences of atomic types (\verb|TFree|, \verb|TVar|)
155.167 - in \isa{{\isasymtau}}; the type structure is traversed from left to right.
155.168 -
155.169 - \item \verb|Sign.subsort|~\isa{thy\ {\isacharparenleft}s\isactrlisub {\isadigit{1}}{\isacharcomma}\ s\isactrlisub {\isadigit{2}}{\isacharparenright}}
155.170 - tests the subsort relation \isa{s\isactrlisub {\isadigit{1}}\ {\isasymsubseteq}\ s\isactrlisub {\isadigit{2}}}.
155.171 -
155.172 - \item \verb|Sign.of_sort|~\isa{thy\ {\isacharparenleft}{\isasymtau}{\isacharcomma}\ s{\isacharparenright}} tests whether type
155.173 - \isa{{\isasymtau}} is of sort \isa{s}.
155.174 -
155.175 - \item \verb|Sign.add_types|~\isa{{\isacharbrackleft}{\isacharparenleft}{\isasymkappa}{\isacharcomma}\ k{\isacharcomma}\ mx{\isacharparenright}{\isacharcomma}\ {\isasymdots}{\isacharbrackright}} declares a new
155.176 - type constructors \isa{{\isasymkappa}} with \isa{k} arguments and
155.177 - optional mixfix syntax.
155.178 -
155.179 - \item \verb|Sign.add_tyabbrs_i|~\isa{{\isacharbrackleft}{\isacharparenleft}{\isasymkappa}{\isacharcomma}\ \isactrlvec {\isasymalpha}{\isacharcomma}\ {\isasymtau}{\isacharcomma}\ mx{\isacharparenright}{\isacharcomma}\ {\isasymdots}{\isacharbrackright}}
155.180 - defines a new type abbreviation \isa{{\isacharparenleft}\isactrlvec {\isasymalpha}{\isacharparenright}{\isasymkappa}\ {\isacharequal}\ {\isasymtau}} with
155.181 - optional mixfix syntax.
155.182 -
155.183 - \item \verb|Sign.primitive_class|~\isa{{\isacharparenleft}c{\isacharcomma}\ {\isacharbrackleft}c\isactrlisub {\isadigit{1}}{\isacharcomma}\ {\isasymdots}{\isacharcomma}\ c\isactrlisub n{\isacharbrackright}{\isacharparenright}} declares a new class \isa{c}, together with class
155.184 - relations \isa{c\ {\isasymsubseteq}\ c\isactrlisub i}, for \isa{i\ {\isacharequal}\ {\isadigit{1}}{\isacharcomma}\ {\isasymdots}{\isacharcomma}\ n}.
155.185 -
155.186 - \item \verb|Sign.primitive_classrel|~\isa{{\isacharparenleft}c\isactrlisub {\isadigit{1}}{\isacharcomma}\ c\isactrlisub {\isadigit{2}}{\isacharparenright}} declares the class relation \isa{c\isactrlisub {\isadigit{1}}\ {\isasymsubseteq}\ c\isactrlisub {\isadigit{2}}}.
155.187 -
155.188 - \item \verb|Sign.primitive_arity|~\isa{{\isacharparenleft}{\isasymkappa}{\isacharcomma}\ \isactrlvec s{\isacharcomma}\ s{\isacharparenright}} declares
155.189 - the arity \isa{{\isasymkappa}\ {\isacharcolon}{\isacharcolon}\ {\isacharparenleft}\isactrlvec s{\isacharparenright}s}.
155.190 -
155.191 - \end{description}%
155.192 -\end{isamarkuptext}%
155.193 -\isamarkuptrue%
155.194 -%
155.195 -\endisatagmlref
155.196 -{\isafoldmlref}%
155.197 -%
155.198 -\isadelimmlref
155.199 -%
155.200 -\endisadelimmlref
155.201 -%
155.202 -\isamarkupsection{Terms \label{sec:terms}%
155.203 -}
155.204 -\isamarkuptrue%
155.205 -%
155.206 -\begin{isamarkuptext}%
155.207 -\glossary{Term}{FIXME}
155.208 -
155.209 - The language of terms is that of simply-typed \isa{{\isasymlambda}}-calculus
155.210 - with de-Bruijn indices for bound variables (cf.\ \cite{debruijn72}
155.211 - or \cite{paulson-ml2}), with the types being determined determined
155.212 - by the corresponding binders. In contrast, free variables and
155.213 - constants are have an explicit name and type in each occurrence.
155.214 -
155.215 - \medskip A \emph{bound variable} is a natural number \isa{b},
155.216 - which accounts for the number of intermediate binders between the
155.217 - variable occurrence in the body and its binding position. For
155.218 - example, the de-Bruijn term \isa{{\isasymlambda}\isactrlbsub nat\isactrlesub {\isachardot}\ {\isasymlambda}\isactrlbsub nat\isactrlesub {\isachardot}\ {\isadigit{1}}\ {\isacharplus}\ {\isadigit{0}}} would
155.219 - correspond to \isa{{\isasymlambda}x\isactrlbsub nat\isactrlesub {\isachardot}\ {\isasymlambda}y\isactrlbsub nat\isactrlesub {\isachardot}\ x\ {\isacharplus}\ y} in a named
155.220 - representation. Note that a bound variable may be represented by
155.221 - different de-Bruijn indices at different occurrences, depending on
155.222 - the nesting of abstractions.
155.223 -
155.224 - A \emph{loose variable} is a bound variable that is outside the
155.225 - scope of local binders. The types (and names) for loose variables
155.226 - can be managed as a separate context, that is maintained as a stack
155.227 - of hypothetical binders. The core logic operates on closed terms,
155.228 - without any loose variables.
155.229 -
155.230 - A \emph{fixed variable} is a pair of a basic name and a type, e.g.\
155.231 - \isa{{\isacharparenleft}x{\isacharcomma}\ {\isasymtau}{\isacharparenright}} which is usually printed \isa{x\isactrlisub {\isasymtau}}. A
155.232 - \emph{schematic variable} is a pair of an indexname and a type,
155.233 - e.g.\ \isa{{\isacharparenleft}{\isacharparenleft}x{\isacharcomma}\ {\isadigit{0}}{\isacharparenright}{\isacharcomma}\ {\isasymtau}{\isacharparenright}} which is usually printed as \isa{{\isacharquery}x\isactrlisub {\isasymtau}}.
155.234 -
155.235 - \medskip A \emph{constant} is a pair of a basic name and a type,
155.236 - e.g.\ \isa{{\isacharparenleft}c{\isacharcomma}\ {\isasymtau}{\isacharparenright}} which is usually printed as \isa{c\isactrlisub {\isasymtau}}. Constants are declared in the context as polymorphic
155.237 - families \isa{c\ {\isacharcolon}{\isacharcolon}\ {\isasymsigma}}, meaning that all substitution instances
155.238 - \isa{c\isactrlisub {\isasymtau}} for \isa{{\isasymtau}\ {\isacharequal}\ {\isasymsigma}{\isasymvartheta}} are valid.
155.239 -
155.240 - The vector of \emph{type arguments} of constant \isa{c\isactrlisub {\isasymtau}}
155.241 - wrt.\ the declaration \isa{c\ {\isacharcolon}{\isacharcolon}\ {\isasymsigma}} is defined as the codomain of
155.242 - the matcher \isa{{\isasymvartheta}\ {\isacharequal}\ {\isacharbraceleft}{\isacharquery}{\isasymalpha}\isactrlisub {\isadigit{1}}\ {\isasymmapsto}\ {\isasymtau}\isactrlisub {\isadigit{1}}{\isacharcomma}\ {\isasymdots}{\isacharcomma}\ {\isacharquery}{\isasymalpha}\isactrlisub n\ {\isasymmapsto}\ {\isasymtau}\isactrlisub n{\isacharbraceright}} presented in canonical order \isa{{\isacharparenleft}{\isasymtau}\isactrlisub {\isadigit{1}}{\isacharcomma}\ {\isasymdots}{\isacharcomma}\ {\isasymtau}\isactrlisub n{\isacharparenright}}. Within a given theory context,
155.243 - there is a one-to-one correspondence between any constant \isa{c\isactrlisub {\isasymtau}} and the application \isa{c{\isacharparenleft}{\isasymtau}\isactrlisub {\isadigit{1}}{\isacharcomma}\ {\isasymdots}{\isacharcomma}\ {\isasymtau}\isactrlisub n{\isacharparenright}} of its type arguments. For example, with \isa{plus\ {\isacharcolon}{\isacharcolon}\ {\isasymalpha}\ {\isasymRightarrow}\ {\isasymalpha}\ {\isasymRightarrow}\ {\isasymalpha}}, the instance \isa{plus\isactrlbsub nat\ {\isasymRightarrow}\ nat\ {\isasymRightarrow}\ nat\isactrlesub } corresponds to \isa{plus{\isacharparenleft}nat{\isacharparenright}}.
155.244 -
155.245 - Constant declarations \isa{c\ {\isacharcolon}{\isacharcolon}\ {\isasymsigma}} may contain sort constraints
155.246 - for type variables in \isa{{\isasymsigma}}. These are observed by
155.247 - type-inference as expected, but \emph{ignored} by the core logic.
155.248 - This means the primitive logic is able to reason with instances of
155.249 - polymorphic constants that the user-level type-checker would reject
155.250 - due to violation of type class restrictions.
155.251 -
155.252 - \medskip An \emph{atomic} term is either a variable or constant. A
155.253 - \emph{term} is defined inductively over atomic terms, with
155.254 - abstraction and application as follows: \isa{t\ {\isacharequal}\ b\ {\isacharbar}\ x\isactrlisub {\isasymtau}\ {\isacharbar}\ {\isacharquery}x\isactrlisub {\isasymtau}\ {\isacharbar}\ c\isactrlisub {\isasymtau}\ {\isacharbar}\ {\isasymlambda}\isactrlisub {\isasymtau}{\isachardot}\ t\ {\isacharbar}\ t\isactrlisub {\isadigit{1}}\ t\isactrlisub {\isadigit{2}}}.
155.255 - Parsing and printing takes care of converting between an external
155.256 - representation with named bound variables. Subsequently, we shall
155.257 - use the latter notation instead of internal de-Bruijn
155.258 - representation.
155.259 -
155.260 - The inductive relation \isa{t\ {\isacharcolon}{\isacharcolon}\ {\isasymtau}} assigns a (unique) type to a
155.261 - term according to the structure of atomic terms, abstractions, and
155.262 - applicatins:
155.263 - \[
155.264 - \infer{\isa{a\isactrlisub {\isasymtau}\ {\isacharcolon}{\isacharcolon}\ {\isasymtau}}}{}
155.265 - \qquad
155.266 - \infer{\isa{{\isacharparenleft}{\isasymlambda}x\isactrlsub {\isasymtau}{\isachardot}\ t{\isacharparenright}\ {\isacharcolon}{\isacharcolon}\ {\isasymtau}\ {\isasymRightarrow}\ {\isasymsigma}}}{\isa{t\ {\isacharcolon}{\isacharcolon}\ {\isasymsigma}}}
155.267 - \qquad
155.268 - \infer{\isa{t\ u\ {\isacharcolon}{\isacharcolon}\ {\isasymsigma}}}{\isa{t\ {\isacharcolon}{\isacharcolon}\ {\isasymtau}\ {\isasymRightarrow}\ {\isasymsigma}} & \isa{u\ {\isacharcolon}{\isacharcolon}\ {\isasymtau}}}
155.269 - \]
155.270 - A \emph{well-typed term} is a term that can be typed according to these rules.
155.271 -
155.272 - Typing information can be omitted: type-inference is able to
155.273 - reconstruct the most general type of a raw term, while assigning
155.274 - most general types to all of its variables and constants.
155.275 - Type-inference depends on a context of type constraints for fixed
155.276 - variables, and declarations for polymorphic constants.
155.277 -
155.278 - The identity of atomic terms consists both of the name and the type
155.279 - component. This means that different variables \isa{x\isactrlbsub {\isasymtau}\isactrlisub {\isadigit{1}}\isactrlesub } and \isa{x\isactrlbsub {\isasymtau}\isactrlisub {\isadigit{2}}\isactrlesub } may become the same after type
155.280 - instantiation. Some outer layers of the system make it hard to
155.281 - produce variables of the same name, but different types. In
155.282 - contrast, mixed instances of polymorphic constants occur frequently.
155.283 -
155.284 - \medskip The \emph{hidden polymorphism} of a term \isa{t\ {\isacharcolon}{\isacharcolon}\ {\isasymsigma}}
155.285 - is the set of type variables occurring in \isa{t}, but not in
155.286 - \isa{{\isasymsigma}}. This means that the term implicitly depends on type
155.287 - arguments that are not accounted in the result type, i.e.\ there are
155.288 - different type instances \isa{t{\isasymvartheta}\ {\isacharcolon}{\isacharcolon}\ {\isasymsigma}} and \isa{t{\isasymvartheta}{\isacharprime}\ {\isacharcolon}{\isacharcolon}\ {\isasymsigma}} with the same type. This slightly
155.289 - pathological situation notoriously demands additional care.
155.290 -
155.291 - \medskip A \emph{term abbreviation} is a syntactic definition \isa{c\isactrlisub {\isasymsigma}\ {\isasymequiv}\ t} of a closed term \isa{t} of type \isa{{\isasymsigma}},
155.292 - without any hidden polymorphism. A term abbreviation looks like a
155.293 - constant in the syntax, but is expanded before entering the logical
155.294 - core. Abbreviations are usually reverted when printing terms, using
155.295 - \isa{t\ {\isasymrightarrow}\ c\isactrlisub {\isasymsigma}} as rules for higher-order rewriting.
155.296 -
155.297 - \medskip Canonical operations on \isa{{\isasymlambda}}-terms include \isa{{\isasymalpha}{\isasymbeta}{\isasymeta}}-conversion: \isa{{\isasymalpha}}-conversion refers to capture-free
155.298 - renaming of bound variables; \isa{{\isasymbeta}}-conversion contracts an
155.299 - abstraction applied to an argument term, substituting the argument
155.300 - in the body: \isa{{\isacharparenleft}{\isasymlambda}x{\isachardot}\ b{\isacharparenright}a} becomes \isa{b{\isacharbrackleft}a{\isacharslash}x{\isacharbrackright}}; \isa{{\isasymeta}}-conversion contracts vacuous application-abstraction: \isa{{\isasymlambda}x{\isachardot}\ f\ x} becomes \isa{f}, provided that the bound variable
155.301 - does not occur in \isa{f}.
155.302 -
155.303 - Terms are normally treated modulo \isa{{\isasymalpha}}-conversion, which is
155.304 - implicit in the de-Bruijn representation. Names for bound variables
155.305 - in abstractions are maintained separately as (meaningless) comments,
155.306 - mostly for parsing and printing. Full \isa{{\isasymalpha}{\isasymbeta}{\isasymeta}}-conversion is
155.307 - commonplace in various standard operations (\secref{sec:obj-rules})
155.308 - that are based on higher-order unification and matching.%
155.309 -\end{isamarkuptext}%
155.310 -\isamarkuptrue%
155.311 -%
155.312 -\isadelimmlref
155.313 -%
155.314 -\endisadelimmlref
155.315 -%
155.316 -\isatagmlref
155.317 -%
155.318 -\begin{isamarkuptext}%
155.319 -\begin{mldecls}
155.320 - \indexmltype{term}\verb|type term| \\
155.321 - \indexml{op aconv}\verb|op aconv: term * term -> bool| \\
155.322 - \indexml{map\_types}\verb|map_types: (typ -> typ) -> term -> term| \\
155.323 - \indexml{fold\_types}\verb|fold_types: (typ -> 'a -> 'a) -> term -> 'a -> 'a| \\
155.324 - \indexml{map\_aterms}\verb|map_aterms: (term -> term) -> term -> term| \\
155.325 - \indexml{fold\_aterms}\verb|fold_aterms: (term -> 'a -> 'a) -> term -> 'a -> 'a| \\
155.326 - \end{mldecls}
155.327 - \begin{mldecls}
155.328 - \indexml{fastype\_of}\verb|fastype_of: term -> typ| \\
155.329 - \indexml{lambda}\verb|lambda: term -> term -> term| \\
155.330 - \indexml{betapply}\verb|betapply: term * term -> term| \\
155.331 - \indexml{Sign.declare\_const}\verb|Sign.declare_const: Properties.T -> (binding * typ) * mixfix ->|\isasep\isanewline%
155.332 -\verb| theory -> term * theory| \\
155.333 - \indexml{Sign.add\_abbrev}\verb|Sign.add_abbrev: string -> Properties.T -> binding * term ->|\isasep\isanewline%
155.334 -\verb| theory -> (term * term) * theory| \\
155.335 - \indexml{Sign.const\_typargs}\verb|Sign.const_typargs: theory -> string * typ -> typ list| \\
155.336 - \indexml{Sign.const\_instance}\verb|Sign.const_instance: theory -> string * typ list -> typ| \\
155.337 - \end{mldecls}
155.338 -
155.339 - \begin{description}
155.340 -
155.341 - \item \verb|term| represents de-Bruijn terms, with comments in
155.342 - abstractions, and explicitly named free variables and constants;
155.343 - this is a datatype with constructors \verb|Bound|, \verb|Free|, \verb|Var|, \verb|Const|, \verb|Abs|, \verb|op $|.
155.344 -
155.345 - \item \isa{t}~\verb|aconv|~\isa{u} checks \isa{{\isasymalpha}}-equivalence of two terms. This is the basic equality relation
155.346 - on type \verb|term|; raw datatype equality should only be used
155.347 - for operations related to parsing or printing!
155.348 -
155.349 - \item \verb|map_types|~\isa{f\ t} applies the mapping \isa{f} to all types occurring in \isa{t}.
155.350 -
155.351 - \item \verb|fold_types|~\isa{f\ t} iterates the operation \isa{f} over all occurrences of types in \isa{t}; the term
155.352 - structure is traversed from left to right.
155.353 -
155.354 - \item \verb|map_aterms|~\isa{f\ t} applies the mapping \isa{f}
155.355 - to all atomic terms (\verb|Bound|, \verb|Free|, \verb|Var|, \verb|Const|) occurring in \isa{t}.
155.356 -
155.357 - \item \verb|fold_aterms|~\isa{f\ t} iterates the operation \isa{f} over all occurrences of atomic terms (\verb|Bound|, \verb|Free|,
155.358 - \verb|Var|, \verb|Const|) in \isa{t}; the term structure is
155.359 - traversed from left to right.
155.360 -
155.361 - \item \verb|fastype_of|~\isa{t} determines the type of a
155.362 - well-typed term. This operation is relatively slow, despite the
155.363 - omission of any sanity checks.
155.364 -
155.365 - \item \verb|lambda|~\isa{a\ b} produces an abstraction \isa{{\isasymlambda}a{\isachardot}\ b}, where occurrences of the atomic term \isa{a} in the
155.366 - body \isa{b} are replaced by bound variables.
155.367 -
155.368 - \item \verb|betapply|~\isa{{\isacharparenleft}t{\isacharcomma}\ u{\isacharparenright}} produces an application \isa{t\ u}, with topmost \isa{{\isasymbeta}}-conversion if \isa{t} is an
155.369 - abstraction.
155.370 -
155.371 - \item \verb|Sign.declare_const|~\isa{properties\ {\isacharparenleft}{\isacharparenleft}c{\isacharcomma}\ {\isasymsigma}{\isacharparenright}{\isacharcomma}\ mx{\isacharparenright}}
155.372 - declares a new constant \isa{c\ {\isacharcolon}{\isacharcolon}\ {\isasymsigma}} with optional mixfix
155.373 - syntax.
155.374 -
155.375 - \item \verb|Sign.add_abbrev|~\isa{print{\isacharunderscore}mode\ properties\ {\isacharparenleft}c{\isacharcomma}\ t{\isacharparenright}}
155.376 - introduces a new term abbreviation \isa{c\ {\isasymequiv}\ t}.
155.377 -
155.378 - \item \verb|Sign.const_typargs|~\isa{thy\ {\isacharparenleft}c{\isacharcomma}\ {\isasymtau}{\isacharparenright}} and \verb|Sign.const_instance|~\isa{thy\ {\isacharparenleft}c{\isacharcomma}\ {\isacharbrackleft}{\isasymtau}\isactrlisub {\isadigit{1}}{\isacharcomma}\ {\isasymdots}{\isacharcomma}\ {\isasymtau}\isactrlisub n{\isacharbrackright}{\isacharparenright}}
155.379 - convert between two representations of polymorphic constants: full
155.380 - type instance vs.\ compact type arguments form.
155.381 -
155.382 - \end{description}%
155.383 -\end{isamarkuptext}%
155.384 -\isamarkuptrue%
155.385 -%
155.386 -\endisatagmlref
155.387 -{\isafoldmlref}%
155.388 -%
155.389 -\isadelimmlref
155.390 -%
155.391 -\endisadelimmlref
155.392 -%
155.393 -\isamarkupsection{Theorems \label{sec:thms}%
155.394 -}
155.395 -\isamarkuptrue%
155.396 -%
155.397 -\begin{isamarkuptext}%
155.398 -\glossary{Proposition}{FIXME A \seeglossary{term} of
155.399 - \seeglossary{type} \isa{prop}. Internally, there is nothing
155.400 - special about propositions apart from their type, but the concrete
155.401 - syntax enforces a clear distinction. Propositions are structured
155.402 - via implication \isa{A\ {\isasymLongrightarrow}\ B} or universal quantification \isa{{\isasymAnd}x{\isachardot}\ B\ x} --- anything else is considered atomic. The canonical
155.403 - form for propositions is that of a \seeglossary{Hereditary Harrop
155.404 - Formula}. FIXME}
155.405 -
155.406 - \glossary{Theorem}{A proven proposition within a certain theory and
155.407 - proof context, formally \isa{{\isasymGamma}\ {\isasymturnstile}\isactrlsub {\isasymTheta}\ {\isasymphi}}; both contexts are
155.408 - rarely spelled out explicitly. Theorems are usually normalized
155.409 - according to the \seeglossary{HHF} format. FIXME}
155.410 -
155.411 - \glossary{Fact}{Sometimes used interchangeably for
155.412 - \seeglossary{theorem}. Strictly speaking, a list of theorems,
155.413 - essentially an extra-logical conjunction. Facts emerge either as
155.414 - local assumptions, or as results of local goal statements --- both
155.415 - may be simultaneous, hence the list representation. FIXME}
155.416 -
155.417 - \glossary{Schematic variable}{FIXME}
155.418 -
155.419 - \glossary{Fixed variable}{A variable that is bound within a certain
155.420 - proof context; an arbitrary-but-fixed entity within a portion of
155.421 - proof text. FIXME}
155.422 -
155.423 - \glossary{Free variable}{Synonymous for \seeglossary{fixed
155.424 - variable}. FIXME}
155.425 -
155.426 - \glossary{Bound variable}{FIXME}
155.427 -
155.428 - \glossary{Variable}{See \seeglossary{schematic variable},
155.429 - \seeglossary{fixed variable}, \seeglossary{bound variable}, or
155.430 - \seeglossary{type variable}. The distinguishing feature of
155.431 - different variables is their binding scope. FIXME}
155.432 -
155.433 - A \emph{proposition} is a well-typed term of type \isa{prop}, a
155.434 - \emph{theorem} is a proven proposition (depending on a context of
155.435 - hypotheses and the background theory). Primitive inferences include
155.436 - plain natural deduction rules for the primary connectives \isa{{\isasymAnd}} and \isa{{\isasymLongrightarrow}} of the framework. There is also a builtin
155.437 - notion of equality/equivalence \isa{{\isasymequiv}}.%
155.438 -\end{isamarkuptext}%
155.439 -\isamarkuptrue%
155.440 -%
155.441 -\isamarkupsubsection{Primitive connectives and rules \label{sec:prim-rules}%
155.442 -}
155.443 -\isamarkuptrue%
155.444 -%
155.445 -\begin{isamarkuptext}%
155.446 -The theory \isa{Pure} contains constant declarations for the
155.447 - primitive connectives \isa{{\isasymAnd}}, \isa{{\isasymLongrightarrow}}, and \isa{{\isasymequiv}} of
155.448 - the logical framework, see \figref{fig:pure-connectives}. The
155.449 - derivability judgment \isa{A\isactrlisub {\isadigit{1}}{\isacharcomma}\ {\isasymdots}{\isacharcomma}\ A\isactrlisub n\ {\isasymturnstile}\ B} is
155.450 - defined inductively by the primitive inferences given in
155.451 - \figref{fig:prim-rules}, with the global restriction that the
155.452 - hypotheses must \emph{not} contain any schematic variables. The
155.453 - builtin equality is conceptually axiomatized as shown in
155.454 - \figref{fig:pure-equality}, although the implementation works
155.455 - directly with derived inferences.
155.456 -
155.457 - \begin{figure}[htb]
155.458 - \begin{center}
155.459 - \begin{tabular}{ll}
155.460 - \isa{all\ {\isacharcolon}{\isacharcolon}\ {\isacharparenleft}{\isasymalpha}\ {\isasymRightarrow}\ prop{\isacharparenright}\ {\isasymRightarrow}\ prop} & universal quantification (binder \isa{{\isasymAnd}}) \\
155.461 - \isa{{\isasymLongrightarrow}\ {\isacharcolon}{\isacharcolon}\ prop\ {\isasymRightarrow}\ prop\ {\isasymRightarrow}\ prop} & implication (right associative infix) \\
155.462 - \isa{{\isasymequiv}\ {\isacharcolon}{\isacharcolon}\ {\isasymalpha}\ {\isasymRightarrow}\ {\isasymalpha}\ {\isasymRightarrow}\ prop} & equality relation (infix) \\
155.463 - \end{tabular}
155.464 - \caption{Primitive connectives of Pure}\label{fig:pure-connectives}
155.465 - \end{center}
155.466 - \end{figure}
155.467 -
155.468 - \begin{figure}[htb]
155.469 - \begin{center}
155.470 - \[
155.471 - \infer[\isa{{\isacharparenleft}axiom{\isacharparenright}}]{\isa{{\isasymturnstile}\ A}}{\isa{A\ {\isasymin}\ {\isasymTheta}}}
155.472 - \qquad
155.473 - \infer[\isa{{\isacharparenleft}assume{\isacharparenright}}]{\isa{A\ {\isasymturnstile}\ A}}{}
155.474 - \]
155.475 - \[
155.476 - \infer[\isa{{\isacharparenleft}{\isasymAnd}{\isacharunderscore}intro{\isacharparenright}}]{\isa{{\isasymGamma}\ {\isasymturnstile}\ {\isasymAnd}x{\isachardot}\ b{\isacharbrackleft}x{\isacharbrackright}}}{\isa{{\isasymGamma}\ {\isasymturnstile}\ b{\isacharbrackleft}x{\isacharbrackright}} & \isa{x\ {\isasymnotin}\ {\isasymGamma}}}
155.477 - \qquad
155.478 - \infer[\isa{{\isacharparenleft}{\isasymAnd}{\isacharunderscore}elim{\isacharparenright}}]{\isa{{\isasymGamma}\ {\isasymturnstile}\ b{\isacharbrackleft}a{\isacharbrackright}}}{\isa{{\isasymGamma}\ {\isasymturnstile}\ {\isasymAnd}x{\isachardot}\ b{\isacharbrackleft}x{\isacharbrackright}}}
155.479 - \]
155.480 - \[
155.481 - \infer[\isa{{\isacharparenleft}{\isasymLongrightarrow}{\isacharunderscore}intro{\isacharparenright}}]{\isa{{\isasymGamma}\ {\isacharminus}\ A\ {\isasymturnstile}\ A\ {\isasymLongrightarrow}\ B}}{\isa{{\isasymGamma}\ {\isasymturnstile}\ B}}
155.482 - \qquad
155.483 - \infer[\isa{{\isacharparenleft}{\isasymLongrightarrow}{\isacharunderscore}elim{\isacharparenright}}]{\isa{{\isasymGamma}\isactrlsub {\isadigit{1}}\ {\isasymunion}\ {\isasymGamma}\isactrlsub {\isadigit{2}}\ {\isasymturnstile}\ B}}{\isa{{\isasymGamma}\isactrlsub {\isadigit{1}}\ {\isasymturnstile}\ A\ {\isasymLongrightarrow}\ B} & \isa{{\isasymGamma}\isactrlsub {\isadigit{2}}\ {\isasymturnstile}\ A}}
155.484 - \]
155.485 - \caption{Primitive inferences of Pure}\label{fig:prim-rules}
155.486 - \end{center}
155.487 - \end{figure}
155.488 -
155.489 - \begin{figure}[htb]
155.490 - \begin{center}
155.491 - \begin{tabular}{ll}
155.492 - \isa{{\isasymturnstile}\ {\isacharparenleft}{\isasymlambda}x{\isachardot}\ b{\isacharbrackleft}x{\isacharbrackright}{\isacharparenright}\ a\ {\isasymequiv}\ b{\isacharbrackleft}a{\isacharbrackright}} & \isa{{\isasymbeta}}-conversion \\
155.493 - \isa{{\isasymturnstile}\ x\ {\isasymequiv}\ x} & reflexivity \\
155.494 - \isa{{\isasymturnstile}\ x\ {\isasymequiv}\ y\ {\isasymLongrightarrow}\ P\ x\ {\isasymLongrightarrow}\ P\ y} & substitution \\
155.495 - \isa{{\isasymturnstile}\ {\isacharparenleft}{\isasymAnd}x{\isachardot}\ f\ x\ {\isasymequiv}\ g\ x{\isacharparenright}\ {\isasymLongrightarrow}\ f\ {\isasymequiv}\ g} & extensionality \\
155.496 - \isa{{\isasymturnstile}\ {\isacharparenleft}A\ {\isasymLongrightarrow}\ B{\isacharparenright}\ {\isasymLongrightarrow}\ {\isacharparenleft}B\ {\isasymLongrightarrow}\ A{\isacharparenright}\ {\isasymLongrightarrow}\ A\ {\isasymequiv}\ B} & logical equivalence \\
155.497 - \end{tabular}
155.498 - \caption{Conceptual axiomatization of Pure equality}\label{fig:pure-equality}
155.499 - \end{center}
155.500 - \end{figure}
155.501 -
155.502 - The introduction and elimination rules for \isa{{\isasymAnd}} and \isa{{\isasymLongrightarrow}} are analogous to formation of dependently typed \isa{{\isasymlambda}}-terms representing the underlying proof objects. Proof terms
155.503 - are irrelevant in the Pure logic, though; they cannot occur within
155.504 - propositions. The system provides a runtime option to record
155.505 - explicit proof terms for primitive inferences. Thus all three
155.506 - levels of \isa{{\isasymlambda}}-calculus become explicit: \isa{{\isasymRightarrow}} for
155.507 - terms, and \isa{{\isasymAnd}{\isacharslash}{\isasymLongrightarrow}} for proofs (cf.\
155.508 - \cite{Berghofer-Nipkow:2000:TPHOL}).
155.509 -
155.510 - Observe that locally fixed parameters (as in \isa{{\isasymAnd}{\isacharunderscore}intro}) need
155.511 - not be recorded in the hypotheses, because the simple syntactic
155.512 - types of Pure are always inhabitable. ``Assumptions'' \isa{x\ {\isacharcolon}{\isacharcolon}\ {\isasymtau}} for type-membership are only present as long as some \isa{x\isactrlisub {\isasymtau}} occurs in the statement body.\footnote{This is the key
155.513 - difference to ``\isa{{\isasymlambda}HOL}'' in the PTS framework
155.514 - \cite{Barendregt-Geuvers:2001}, where hypotheses \isa{x\ {\isacharcolon}\ A} are
155.515 - treated uniformly for propositions and types.}
155.516 -
155.517 - \medskip The axiomatization of a theory is implicitly closed by
155.518 - forming all instances of type and term variables: \isa{{\isasymturnstile}\ A{\isasymvartheta}} holds for any substitution instance of an axiom
155.519 - \isa{{\isasymturnstile}\ A}. By pushing substitutions through derivations
155.520 - inductively, we also get admissible \isa{generalize} and \isa{instance} rules as shown in \figref{fig:subst-rules}.
155.521 -
155.522 - \begin{figure}[htb]
155.523 - \begin{center}
155.524 - \[
155.525 - \infer{\isa{{\isasymGamma}\ {\isasymturnstile}\ B{\isacharbrackleft}{\isacharquery}{\isasymalpha}{\isacharbrackright}}}{\isa{{\isasymGamma}\ {\isasymturnstile}\ B{\isacharbrackleft}{\isasymalpha}{\isacharbrackright}} & \isa{{\isasymalpha}\ {\isasymnotin}\ {\isasymGamma}}}
155.526 - \quad
155.527 - \infer[\quad\isa{{\isacharparenleft}generalize{\isacharparenright}}]{\isa{{\isasymGamma}\ {\isasymturnstile}\ B{\isacharbrackleft}{\isacharquery}x{\isacharbrackright}}}{\isa{{\isasymGamma}\ {\isasymturnstile}\ B{\isacharbrackleft}x{\isacharbrackright}} & \isa{x\ {\isasymnotin}\ {\isasymGamma}}}
155.528 - \]
155.529 - \[
155.530 - \infer{\isa{{\isasymGamma}\ {\isasymturnstile}\ B{\isacharbrackleft}{\isasymtau}{\isacharbrackright}}}{\isa{{\isasymGamma}\ {\isasymturnstile}\ B{\isacharbrackleft}{\isacharquery}{\isasymalpha}{\isacharbrackright}}}
155.531 - \quad
155.532 - \infer[\quad\isa{{\isacharparenleft}instantiate{\isacharparenright}}]{\isa{{\isasymGamma}\ {\isasymturnstile}\ B{\isacharbrackleft}t{\isacharbrackright}}}{\isa{{\isasymGamma}\ {\isasymturnstile}\ B{\isacharbrackleft}{\isacharquery}x{\isacharbrackright}}}
155.533 - \]
155.534 - \caption{Admissible substitution rules}\label{fig:subst-rules}
155.535 - \end{center}
155.536 - \end{figure}
155.537 -
155.538 - Note that \isa{instantiate} does not require an explicit
155.539 - side-condition, because \isa{{\isasymGamma}} may never contain schematic
155.540 - variables.
155.541 -
155.542 - In principle, variables could be substituted in hypotheses as well,
155.543 - but this would disrupt the monotonicity of reasoning: deriving
155.544 - \isa{{\isasymGamma}{\isasymvartheta}\ {\isasymturnstile}\ B{\isasymvartheta}} from \isa{{\isasymGamma}\ {\isasymturnstile}\ B} is
155.545 - correct, but \isa{{\isasymGamma}{\isasymvartheta}\ {\isasymsupseteq}\ {\isasymGamma}} does not necessarily hold:
155.546 - the result belongs to a different proof context.
155.547 -
155.548 - \medskip An \emph{oracle} is a function that produces axioms on the
155.549 - fly. Logically, this is an instance of the \isa{axiom} rule
155.550 - (\figref{fig:prim-rules}), but there is an operational difference.
155.551 - The system always records oracle invocations within derivations of
155.552 - theorems. Tracing plain axioms (and named theorems) is optional.
155.553 -
155.554 - Axiomatizations should be limited to the bare minimum, typically as
155.555 - part of the initial logical basis of an object-logic formalization.
155.556 - Later on, theories are usually developed in a strictly definitional
155.557 - fashion, by stating only certain equalities over new constants.
155.558 -
155.559 - A \emph{simple definition} consists of a constant declaration \isa{c\ {\isacharcolon}{\isacharcolon}\ {\isasymsigma}} together with an axiom \isa{{\isasymturnstile}\ c\ {\isasymequiv}\ t}, where \isa{t\ {\isacharcolon}{\isacharcolon}\ {\isasymsigma}} is a closed term without any hidden polymorphism. The RHS
155.560 - may depend on further defined constants, but not \isa{c} itself.
155.561 - Definitions of functions may be presented as \isa{c\ \isactrlvec x\ {\isasymequiv}\ t} instead of the puristic \isa{c\ {\isasymequiv}\ {\isasymlambda}\isactrlvec x{\isachardot}\ t}.
155.562 -
155.563 - An \emph{overloaded definition} consists of a collection of axioms
155.564 - for the same constant, with zero or one equations \isa{c{\isacharparenleft}{\isacharparenleft}\isactrlvec {\isasymalpha}{\isacharparenright}{\isasymkappa}{\isacharparenright}\ {\isasymequiv}\ t} for each type constructor \isa{{\isasymkappa}} (for
155.565 - distinct variables \isa{\isactrlvec {\isasymalpha}}). The RHS may mention
155.566 - previously defined constants as above, or arbitrary constants \isa{d{\isacharparenleft}{\isasymalpha}\isactrlisub i{\isacharparenright}} for some \isa{{\isasymalpha}\isactrlisub i} projected from \isa{\isactrlvec {\isasymalpha}}. Thus overloaded definitions essentially work by
155.567 - primitive recursion over the syntactic structure of a single type
155.568 - argument.%
155.569 -\end{isamarkuptext}%
155.570 -\isamarkuptrue%
155.571 -%
155.572 -\isadelimmlref
155.573 -%
155.574 -\endisadelimmlref
155.575 -%
155.576 -\isatagmlref
155.577 -%
155.578 -\begin{isamarkuptext}%
155.579 -\begin{mldecls}
155.580 - \indexmltype{ctyp}\verb|type ctyp| \\
155.581 - \indexmltype{cterm}\verb|type cterm| \\
155.582 - \indexml{Thm.ctyp\_of}\verb|Thm.ctyp_of: theory -> typ -> ctyp| \\
155.583 - \indexml{Thm.cterm\_of}\verb|Thm.cterm_of: theory -> term -> cterm| \\
155.584 - \end{mldecls}
155.585 - \begin{mldecls}
155.586 - \indexmltype{thm}\verb|type thm| \\
155.587 - \indexml{proofs}\verb|proofs: int ref| \\
155.588 - \indexml{Thm.assume}\verb|Thm.assume: cterm -> thm| \\
155.589 - \indexml{Thm.forall\_intr}\verb|Thm.forall_intr: cterm -> thm -> thm| \\
155.590 - \indexml{Thm.forall\_elim}\verb|Thm.forall_elim: cterm -> thm -> thm| \\
155.591 - \indexml{Thm.implies\_intr}\verb|Thm.implies_intr: cterm -> thm -> thm| \\
155.592 - \indexml{Thm.implies\_elim}\verb|Thm.implies_elim: thm -> thm -> thm| \\
155.593 - \indexml{Thm.generalize}\verb|Thm.generalize: string list * string list -> int -> thm -> thm| \\
155.594 - \indexml{Thm.instantiate}\verb|Thm.instantiate: (ctyp * ctyp) list * (cterm * cterm) list -> thm -> thm| \\
155.595 - \indexml{Thm.axiom}\verb|Thm.axiom: theory -> string -> thm| \\
155.596 - \indexml{Thm.add\_oracle}\verb|Thm.add_oracle: bstring * ('a -> cterm) -> theory|\isasep\isanewline%
155.597 -\verb| -> (string * ('a -> thm)) * theory| \\
155.598 - \end{mldecls}
155.599 - \begin{mldecls}
155.600 - \indexml{Theory.add\_axioms\_i}\verb|Theory.add_axioms_i: (binding * term) list -> theory -> theory| \\
155.601 - \indexml{Theory.add\_deps}\verb|Theory.add_deps: string -> string * typ -> (string * typ) list -> theory -> theory| \\
155.602 - \indexml{Theory.add\_defs\_i}\verb|Theory.add_defs_i: bool -> bool -> (binding * term) list -> theory -> theory| \\
155.603 - \end{mldecls}
155.604 -
155.605 - \begin{description}
155.606 -
155.607 - \item \verb|ctyp| and \verb|cterm| represent certified types
155.608 - and terms, respectively. These are abstract datatypes that
155.609 - guarantee that its values have passed the full well-formedness (and
155.610 - well-typedness) checks, relative to the declarations of type
155.611 - constructors, constants etc. in the theory.
155.612 -
155.613 - \item \verb|ctyp_of|~\isa{thy\ {\isasymtau}} and \verb|cterm_of|~\isa{thy\ t} explicitly checks types and terms, respectively. This also
155.614 - involves some basic normalizations, such expansion of type and term
155.615 - abbreviations from the theory context.
155.616 -
155.617 - Re-certification is relatively slow and should be avoided in tight
155.618 - reasoning loops. There are separate operations to decompose
155.619 - certified entities (including actual theorems).
155.620 -
155.621 - \item \verb|thm| represents proven propositions. This is an
155.622 - abstract datatype that guarantees that its values have been
155.623 - constructed by basic principles of the \verb|Thm| module.
155.624 - Every \verb|thm| value contains a sliding back-reference to the
155.625 - enclosing theory, cf.\ \secref{sec:context-theory}.
155.626 -
155.627 - \item \verb|proofs| determines the detail of proof recording within
155.628 - \verb|thm| values: \verb|0| records only oracles, \verb|1| records
155.629 - oracles, axioms and named theorems, \verb|2| records full proof
155.630 - terms.
155.631 -
155.632 - \item \verb|Thm.assume|, \verb|Thm.forall_intr|, \verb|Thm.forall_elim|, \verb|Thm.implies_intr|, and \verb|Thm.implies_elim|
155.633 - correspond to the primitive inferences of \figref{fig:prim-rules}.
155.634 -
155.635 - \item \verb|Thm.generalize|~\isa{{\isacharparenleft}\isactrlvec {\isasymalpha}{\isacharcomma}\ \isactrlvec x{\isacharparenright}}
155.636 - corresponds to the \isa{generalize} rules of
155.637 - \figref{fig:subst-rules}. Here collections of type and term
155.638 - variables are generalized simultaneously, specified by the given
155.639 - basic names.
155.640 -
155.641 - \item \verb|Thm.instantiate|~\isa{{\isacharparenleft}\isactrlvec {\isasymalpha}\isactrlisub s{\isacharcomma}\ \isactrlvec x\isactrlisub {\isasymtau}{\isacharparenright}} corresponds to the \isa{instantiate} rules
155.642 - of \figref{fig:subst-rules}. Type variables are substituted before
155.643 - term variables. Note that the types in \isa{\isactrlvec x\isactrlisub {\isasymtau}}
155.644 - refer to the instantiated versions.
155.645 -
155.646 - \item \verb|Thm.axiom|~\isa{thy\ name} retrieves a named
155.647 - axiom, cf.\ \isa{axiom} in \figref{fig:prim-rules}.
155.648 -
155.649 - \item \verb|Thm.add_oracle|~\isa{{\isacharparenleft}name{\isacharcomma}\ oracle{\isacharparenright}} produces a named
155.650 - oracle rule, essentially generating arbitrary axioms on the fly,
155.651 - cf.\ \isa{axiom} in \figref{fig:prim-rules}.
155.652 -
155.653 - \item \verb|Theory.add_axioms_i|~\isa{{\isacharbrackleft}{\isacharparenleft}name{\isacharcomma}\ A{\isacharparenright}{\isacharcomma}\ {\isasymdots}{\isacharbrackright}} declares
155.654 - arbitrary propositions as axioms.
155.655 -
155.656 - \item \verb|Theory.add_deps|~\isa{name\ c\isactrlisub {\isasymtau}\ \isactrlvec d\isactrlisub {\isasymsigma}} declares dependencies of a named specification
155.657 - for constant \isa{c\isactrlisub {\isasymtau}}, relative to existing
155.658 - specifications for constants \isa{\isactrlvec d\isactrlisub {\isasymsigma}}.
155.659 -
155.660 - \item \verb|Theory.add_defs_i|~\isa{unchecked\ overloaded\ {\isacharbrackleft}{\isacharparenleft}name{\isacharcomma}\ c\ \isactrlvec x\ {\isasymequiv}\ t{\isacharparenright}{\isacharcomma}\ {\isasymdots}{\isacharbrackright}} states a definitional axiom for an existing
155.661 - constant \isa{c}. Dependencies are recorded (cf.\ \verb|Theory.add_deps|), unless the \isa{unchecked} option is set.
155.662 -
155.663 - \end{description}%
155.664 -\end{isamarkuptext}%
155.665 -\isamarkuptrue%
155.666 -%
155.667 -\endisatagmlref
155.668 -{\isafoldmlref}%
155.669 -%
155.670 -\isadelimmlref
155.671 -%
155.672 -\endisadelimmlref
155.673 -%
155.674 -\isamarkupsubsection{Auxiliary definitions%
155.675 -}
155.676 -\isamarkuptrue%
155.677 -%
155.678 -\begin{isamarkuptext}%
155.679 -Theory \isa{Pure} provides a few auxiliary definitions, see
155.680 - \figref{fig:pure-aux}. These special constants are normally not
155.681 - exposed to the user, but appear in internal encodings.
155.682 -
155.683 - \begin{figure}[htb]
155.684 - \begin{center}
155.685 - \begin{tabular}{ll}
155.686 - \isa{conjunction\ {\isacharcolon}{\isacharcolon}\ prop\ {\isasymRightarrow}\ prop\ {\isasymRightarrow}\ prop} & (infix \isa{{\isacharampersand}}) \\
155.687 - \isa{{\isasymturnstile}\ A\ {\isacharampersand}\ B\ {\isasymequiv}\ {\isacharparenleft}{\isasymAnd}C{\isachardot}\ {\isacharparenleft}A\ {\isasymLongrightarrow}\ B\ {\isasymLongrightarrow}\ C{\isacharparenright}\ {\isasymLongrightarrow}\ C{\isacharparenright}} \\[1ex]
155.688 - \isa{prop\ {\isacharcolon}{\isacharcolon}\ prop\ {\isasymRightarrow}\ prop} & (prefix \isa{{\isacharhash}}, suppressed) \\
155.689 - \isa{{\isacharhash}A\ {\isasymequiv}\ A} \\[1ex]
155.690 - \isa{term\ {\isacharcolon}{\isacharcolon}\ {\isasymalpha}\ {\isasymRightarrow}\ prop} & (prefix \isa{TERM}) \\
155.691 - \isa{term\ x\ {\isasymequiv}\ {\isacharparenleft}{\isasymAnd}A{\isachardot}\ A\ {\isasymLongrightarrow}\ A{\isacharparenright}} \\[1ex]
155.692 - \isa{TYPE\ {\isacharcolon}{\isacharcolon}\ {\isasymalpha}\ itself} & (prefix \isa{TYPE}) \\
155.693 - \isa{{\isacharparenleft}unspecified{\isacharparenright}} \\
155.694 - \end{tabular}
155.695 - \caption{Definitions of auxiliary connectives}\label{fig:pure-aux}
155.696 - \end{center}
155.697 - \end{figure}
155.698 -
155.699 - Derived conjunction rules include introduction \isa{A\ {\isasymLongrightarrow}\ B\ {\isasymLongrightarrow}\ A\ {\isacharampersand}\ B}, and destructions \isa{A\ {\isacharampersand}\ B\ {\isasymLongrightarrow}\ A} and \isa{A\ {\isacharampersand}\ B\ {\isasymLongrightarrow}\ B}.
155.700 - Conjunction allows to treat simultaneous assumptions and conclusions
155.701 - uniformly. For example, multiple claims are intermediately
155.702 - represented as explicit conjunction, but this is refined into
155.703 - separate sub-goals before the user continues the proof; the final
155.704 - result is projected into a list of theorems (cf.\
155.705 - \secref{sec:tactical-goals}).
155.706 -
155.707 - The \isa{prop} marker (\isa{{\isacharhash}}) makes arbitrarily complex
155.708 - propositions appear as atomic, without changing the meaning: \isa{{\isasymGamma}\ {\isasymturnstile}\ A} and \isa{{\isasymGamma}\ {\isasymturnstile}\ {\isacharhash}A} are interchangeable. See
155.709 - \secref{sec:tactical-goals} for specific operations.
155.710 -
155.711 - The \isa{term} marker turns any well-typed term into a derivable
155.712 - proposition: \isa{{\isasymturnstile}\ TERM\ t} holds unconditionally. Although
155.713 - this is logically vacuous, it allows to treat terms and proofs
155.714 - uniformly, similar to a type-theoretic framework.
155.715 -
155.716 - The \isa{TYPE} constructor is the canonical representative of
155.717 - the unspecified type \isa{{\isasymalpha}\ itself}; it essentially injects the
155.718 - language of types into that of terms. There is specific notation
155.719 - \isa{TYPE{\isacharparenleft}{\isasymtau}{\isacharparenright}} for \isa{TYPE\isactrlbsub {\isasymtau}\ itself\isactrlesub }.
155.720 - Although being devoid of any particular meaning, the \isa{TYPE{\isacharparenleft}{\isasymtau}{\isacharparenright}} accounts for the type \isa{{\isasymtau}} within the term
155.721 - language. In particular, \isa{TYPE{\isacharparenleft}{\isasymalpha}{\isacharparenright}} may be used as formal
155.722 - argument in primitive definitions, in order to circumvent hidden
155.723 - polymorphism (cf.\ \secref{sec:terms}). For example, \isa{c\ TYPE{\isacharparenleft}{\isasymalpha}{\isacharparenright}\ {\isasymequiv}\ A{\isacharbrackleft}{\isasymalpha}{\isacharbrackright}} defines \isa{c\ {\isacharcolon}{\isacharcolon}\ {\isasymalpha}\ itself\ {\isasymRightarrow}\ prop} in terms of
155.724 - a proposition \isa{A} that depends on an additional type
155.725 - argument, which is essentially a predicate on types.%
155.726 -\end{isamarkuptext}%
155.727 -\isamarkuptrue%
155.728 -%
155.729 -\isadelimmlref
155.730 -%
155.731 -\endisadelimmlref
155.732 -%
155.733 -\isatagmlref
155.734 -%
155.735 -\begin{isamarkuptext}%
155.736 -\begin{mldecls}
155.737 - \indexml{Conjunction.intr}\verb|Conjunction.intr: thm -> thm -> thm| \\
155.738 - \indexml{Conjunction.elim}\verb|Conjunction.elim: thm -> thm * thm| \\
155.739 - \indexml{Drule.mk\_term}\verb|Drule.mk_term: cterm -> thm| \\
155.740 - \indexml{Drule.dest\_term}\verb|Drule.dest_term: thm -> cterm| \\
155.741 - \indexml{Logic.mk\_type}\verb|Logic.mk_type: typ -> term| \\
155.742 - \indexml{Logic.dest\_type}\verb|Logic.dest_type: term -> typ| \\
155.743 - \end{mldecls}
155.744 -
155.745 - \begin{description}
155.746 -
155.747 - \item \verb|Conjunction.intr| derives \isa{A\ {\isacharampersand}\ B} from \isa{A} and \isa{B}.
155.748 -
155.749 - \item \verb|Conjunction.elim| derives \isa{A} and \isa{B}
155.750 - from \isa{A\ {\isacharampersand}\ B}.
155.751 -
155.752 - \item \verb|Drule.mk_term| derives \isa{TERM\ t}.
155.753 -
155.754 - \item \verb|Drule.dest_term| recovers term \isa{t} from \isa{TERM\ t}.
155.755 -
155.756 - \item \verb|Logic.mk_type|~\isa{{\isasymtau}} produces the term \isa{TYPE{\isacharparenleft}{\isasymtau}{\isacharparenright}}.
155.757 -
155.758 - \item \verb|Logic.dest_type|~\isa{TYPE{\isacharparenleft}{\isasymtau}{\isacharparenright}} recovers the type
155.759 - \isa{{\isasymtau}}.
155.760 -
155.761 - \end{description}%
155.762 -\end{isamarkuptext}%
155.763 -\isamarkuptrue%
155.764 -%
155.765 -\endisatagmlref
155.766 -{\isafoldmlref}%
155.767 -%
155.768 -\isadelimmlref
155.769 -%
155.770 -\endisadelimmlref
155.771 -%
155.772 -\isamarkupsection{Object-level rules \label{sec:obj-rules}%
155.773 -}
155.774 -\isamarkuptrue%
155.775 -%
155.776 -\isadelimFIXME
155.777 -%
155.778 -\endisadelimFIXME
155.779 -%
155.780 -\isatagFIXME
155.781 -%
155.782 -\begin{isamarkuptext}%
155.783 -FIXME
155.784 -
155.785 - A \emph{rule} is any Pure theorem in HHF normal form; there is a
155.786 - separate calculus for rule composition, which is modeled after
155.787 - Gentzen's Natural Deduction \cite{Gentzen:1935}, but allows
155.788 - rules to be nested arbitrarily, similar to \cite{extensions91}.
155.789 -
155.790 - Normally, all theorems accessible to the user are proper rules.
155.791 - Low-level inferences are occasional required internally, but the
155.792 - result should be always presented in canonical form. The higher
155.793 - interfaces of Isabelle/Isar will always produce proper rules. It is
155.794 - important to maintain this invariant in add-on applications!
155.795 -
155.796 - There are two main principles of rule composition: \isa{resolution} (i.e.\ backchaining of rules) and \isa{by{\isacharminus}assumption} (i.e.\ closing a branch); both principles are
155.797 - combined in the variants of \isa{elim{\isacharminus}resolution} and \isa{dest{\isacharminus}resolution}. Raw \isa{composition} is occasionally
155.798 - useful as well, also it is strictly speaking outside of the proper
155.799 - rule calculus.
155.800 -
155.801 - Rules are treated modulo general higher-order unification, which is
155.802 - unification modulo the equational theory of \isa{{\isasymalpha}{\isasymbeta}{\isasymeta}}-conversion
155.803 - on \isa{{\isasymlambda}}-terms. Moreover, propositions are understood modulo
155.804 - the (derived) equivalence \isa{{\isacharparenleft}A\ {\isasymLongrightarrow}\ {\isacharparenleft}{\isasymAnd}x{\isachardot}\ B\ x{\isacharparenright}{\isacharparenright}\ {\isasymequiv}\ {\isacharparenleft}{\isasymAnd}x{\isachardot}\ A\ {\isasymLongrightarrow}\ B\ x{\isacharparenright}}.
155.805 -
155.806 - This means that any operations within the rule calculus may be
155.807 - subject to spontaneous \isa{{\isasymalpha}{\isasymbeta}{\isasymeta}}-HHF conversions. It is common
155.808 - practice not to contract or expand unnecessarily. Some mechanisms
155.809 - prefer an one form, others the opposite, so there is a potential
155.810 - danger to produce some oscillation!
155.811 -
155.812 - Only few operations really work \emph{modulo} HHF conversion, but
155.813 - expect a normal form: quantifiers \isa{{\isasymAnd}} before implications
155.814 - \isa{{\isasymLongrightarrow}} at each level of nesting.
155.815 -
155.816 -\glossary{Hereditary Harrop Formula}{The set of propositions in HHF
155.817 -format is defined inductively as \isa{H\ {\isacharequal}\ {\isacharparenleft}{\isasymAnd}x\isactrlsup {\isacharasterisk}{\isachardot}\ H\isactrlsup {\isacharasterisk}\ {\isasymLongrightarrow}\ A{\isacharparenright}}, for variables \isa{x} and atomic propositions \isa{A}.
155.818 -Any proposition may be put into HHF form by normalizing with the rule
155.819 -\isa{{\isacharparenleft}A\ {\isasymLongrightarrow}\ {\isacharparenleft}{\isasymAnd}x{\isachardot}\ B\ x{\isacharparenright}{\isacharparenright}\ {\isasymequiv}\ {\isacharparenleft}{\isasymAnd}x{\isachardot}\ A\ {\isasymLongrightarrow}\ B\ x{\isacharparenright}}. In Isabelle, the outermost
155.820 -quantifier prefix is represented via \seeglossary{schematic
155.821 -variables}, such that the top-level structure is merely that of a
155.822 -\seeglossary{Horn Clause}}.
155.823 -
155.824 -\glossary{HHF}{See \seeglossary{Hereditary Harrop Formula}.}
155.825 -
155.826 -
155.827 - \[
155.828 - \infer[\isa{{\isacharparenleft}assumption{\isacharparenright}}]{\isa{C{\isasymvartheta}}}
155.829 - {\isa{{\isacharparenleft}{\isasymAnd}\isactrlvec x{\isachardot}\ \isactrlvec H\ \isactrlvec x\ {\isasymLongrightarrow}\ A\ \isactrlvec x{\isacharparenright}\ {\isasymLongrightarrow}\ C} & \isa{A{\isasymvartheta}\ {\isacharequal}\ H\isactrlsub i{\isasymvartheta}}~~\text{(for some~\isa{i})}}
155.830 - \]
155.831 -
155.832 -
155.833 - \[
155.834 - \infer[\isa{{\isacharparenleft}compose{\isacharparenright}}]{\isa{\isactrlvec A{\isasymvartheta}\ {\isasymLongrightarrow}\ C{\isasymvartheta}}}
155.835 - {\isa{\isactrlvec A\ {\isasymLongrightarrow}\ B} & \isa{B{\isacharprime}\ {\isasymLongrightarrow}\ C} & \isa{B{\isasymvartheta}\ {\isacharequal}\ B{\isacharprime}{\isasymvartheta}}}
155.836 - \]
155.837 -
155.838 -
155.839 - \[
155.840 - \infer[\isa{{\isacharparenleft}{\isasymAnd}{\isacharunderscore}lift{\isacharparenright}}]{\isa{{\isacharparenleft}{\isasymAnd}\isactrlvec x{\isachardot}\ \isactrlvec A\ {\isacharparenleft}{\isacharquery}\isactrlvec a\ \isactrlvec x{\isacharparenright}{\isacharparenright}\ {\isasymLongrightarrow}\ {\isacharparenleft}{\isasymAnd}\isactrlvec x{\isachardot}\ B\ {\isacharparenleft}{\isacharquery}\isactrlvec a\ \isactrlvec x{\isacharparenright}{\isacharparenright}}}{\isa{\isactrlvec A\ {\isacharquery}\isactrlvec a\ {\isasymLongrightarrow}\ B\ {\isacharquery}\isactrlvec a}}
155.841 - \]
155.842 - \[
155.843 - \infer[\isa{{\isacharparenleft}{\isasymLongrightarrow}{\isacharunderscore}lift{\isacharparenright}}]{\isa{{\isacharparenleft}\isactrlvec H\ {\isasymLongrightarrow}\ \isactrlvec A{\isacharparenright}\ {\isasymLongrightarrow}\ {\isacharparenleft}\isactrlvec H\ {\isasymLongrightarrow}\ B{\isacharparenright}}}{\isa{\isactrlvec A\ {\isasymLongrightarrow}\ B}}
155.844 - \]
155.845 -
155.846 - The \isa{resolve} scheme is now acquired from \isa{{\isasymAnd}{\isacharunderscore}lift},
155.847 - \isa{{\isasymLongrightarrow}{\isacharunderscore}lift}, and \isa{compose}.
155.848 -
155.849 - \[
155.850 - \infer[\isa{{\isacharparenleft}resolution{\isacharparenright}}]
155.851 - {\isa{{\isacharparenleft}{\isasymAnd}\isactrlvec x{\isachardot}\ \isactrlvec H\ \isactrlvec x\ {\isasymLongrightarrow}\ \isactrlvec A\ {\isacharparenleft}{\isacharquery}\isactrlvec a\ \isactrlvec x{\isacharparenright}{\isacharparenright}{\isasymvartheta}\ {\isasymLongrightarrow}\ C{\isasymvartheta}}}
155.852 - {\begin{tabular}{l}
155.853 - \isa{\isactrlvec A\ {\isacharquery}\isactrlvec a\ {\isasymLongrightarrow}\ B\ {\isacharquery}\isactrlvec a} \\
155.854 - \isa{{\isacharparenleft}{\isasymAnd}\isactrlvec x{\isachardot}\ \isactrlvec H\ \isactrlvec x\ {\isasymLongrightarrow}\ B{\isacharprime}\ \isactrlvec x{\isacharparenright}\ {\isasymLongrightarrow}\ C} \\
155.855 - \isa{{\isacharparenleft}{\isasymlambda}\isactrlvec x{\isachardot}\ B\ {\isacharparenleft}{\isacharquery}\isactrlvec a\ \isactrlvec x{\isacharparenright}{\isacharparenright}{\isasymvartheta}\ {\isacharequal}\ B{\isacharprime}{\isasymvartheta}} \\
155.856 - \end{tabular}}
155.857 - \]
155.858 -
155.859 -
155.860 - FIXME \isa{elim{\isacharunderscore}resolution}, \isa{dest{\isacharunderscore}resolution}%
155.861 -\end{isamarkuptext}%
155.862 -\isamarkuptrue%
155.863 -%
155.864 -\endisatagFIXME
155.865 -{\isafoldFIXME}%
155.866 -%
155.867 -\isadelimFIXME
155.868 -%
155.869 -\endisadelimFIXME
155.870 -%
155.871 -\isadelimtheory
155.872 -%
155.873 -\endisadelimtheory
155.874 -%
155.875 -\isatagtheory
155.876 -\isacommand{end}\isamarkupfalse%
155.877 -%
155.878 -\endisatagtheory
155.879 -{\isafoldtheory}%
155.880 -%
155.881 -\isadelimtheory
155.882 -%
155.883 -\endisadelimtheory
155.884 -\isanewline
155.885 -\end{isabellebody}%
155.886 -%%% Local Variables:
155.887 -%%% mode: latex
155.888 -%%% TeX-master: "root"
155.889 -%%% End:
156.1 --- a/doc-src/IsarImplementation/Thy/document/prelim.tex Wed Mar 04 11:05:02 2009 +0100
156.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
156.3 @@ -1,911 +0,0 @@
156.4 -%
156.5 -\begin{isabellebody}%
156.6 -\def\isabellecontext{prelim}%
156.7 -%
156.8 -\isadelimtheory
156.9 -\isanewline
156.10 -\isanewline
156.11 -\isanewline
156.12 -%
156.13 -\endisadelimtheory
156.14 -%
156.15 -\isatagtheory
156.16 -\isacommand{theory}\isamarkupfalse%
156.17 -\ prelim\ \isakeyword{imports}\ base\ \isakeyword{begin}%
156.18 -\endisatagtheory
156.19 -{\isafoldtheory}%
156.20 -%
156.21 -\isadelimtheory
156.22 -%
156.23 -\endisadelimtheory
156.24 -%
156.25 -\isamarkupchapter{Preliminaries%
156.26 -}
156.27 -\isamarkuptrue%
156.28 -%
156.29 -\isamarkupsection{Contexts \label{sec:context}%
156.30 -}
156.31 -\isamarkuptrue%
156.32 -%
156.33 -\begin{isamarkuptext}%
156.34 -A logical context represents the background that is required for
156.35 - formulating statements and composing proofs. It acts as a medium to
156.36 - produce formal content, depending on earlier material (declarations,
156.37 - results etc.).
156.38 -
156.39 - For example, derivations within the Isabelle/Pure logic can be
156.40 - described as a judgment \isa{{\isasymGamma}\ {\isasymturnstile}\isactrlsub {\isasymTheta}\ {\isasymphi}}, which means that a
156.41 - proposition \isa{{\isasymphi}} is derivable from hypotheses \isa{{\isasymGamma}}
156.42 - within the theory \isa{{\isasymTheta}}. There are logical reasons for
156.43 - keeping \isa{{\isasymTheta}} and \isa{{\isasymGamma}} separate: theories can be
156.44 - liberal about supporting type constructors and schematic
156.45 - polymorphism of constants and axioms, while the inner calculus of
156.46 - \isa{{\isasymGamma}\ {\isasymturnstile}\ {\isasymphi}} is strictly limited to Simple Type Theory (with
156.47 - fixed type variables in the assumptions).
156.48 -
156.49 - \medskip Contexts and derivations are linked by the following key
156.50 - principles:
156.51 -
156.52 - \begin{itemize}
156.53 -
156.54 - \item Transfer: monotonicity of derivations admits results to be
156.55 - transferred into a \emph{larger} context, i.e.\ \isa{{\isasymGamma}\ {\isasymturnstile}\isactrlsub {\isasymTheta}\ {\isasymphi}} implies \isa{{\isasymGamma}{\isacharprime}\ {\isasymturnstile}\isactrlsub {\isasymTheta}\isactrlsub {\isacharprime}\ {\isasymphi}} for contexts \isa{{\isasymTheta}{\isacharprime}\ {\isasymsupseteq}\ {\isasymTheta}} and \isa{{\isasymGamma}{\isacharprime}\ {\isasymsupseteq}\ {\isasymGamma}}.
156.56 -
156.57 - \item Export: discharge of hypotheses admits results to be exported
156.58 - into a \emph{smaller} context, i.e.\ \isa{{\isasymGamma}{\isacharprime}\ {\isasymturnstile}\isactrlsub {\isasymTheta}\ {\isasymphi}}
156.59 - implies \isa{{\isasymGamma}\ {\isasymturnstile}\isactrlsub {\isasymTheta}\ {\isasymDelta}\ {\isasymLongrightarrow}\ {\isasymphi}} where \isa{{\isasymGamma}{\isacharprime}\ {\isasymsupseteq}\ {\isasymGamma}} and
156.60 - \isa{{\isasymDelta}\ {\isacharequal}\ {\isasymGamma}{\isacharprime}\ {\isacharminus}\ {\isasymGamma}}. Note that \isa{{\isasymTheta}} remains unchanged here,
156.61 - only the \isa{{\isasymGamma}} part is affected.
156.62 -
156.63 - \end{itemize}
156.64 -
156.65 - \medskip By modeling the main characteristics of the primitive
156.66 - \isa{{\isasymTheta}} and \isa{{\isasymGamma}} above, and abstracting over any
156.67 - particular logical content, we arrive at the fundamental notions of
156.68 - \emph{theory context} and \emph{proof context} in Isabelle/Isar.
156.69 - These implement a certain policy to manage arbitrary \emph{context
156.70 - data}. There is a strongly-typed mechanism to declare new kinds of
156.71 - data at compile time.
156.72 -
156.73 - The internal bootstrap process of Isabelle/Pure eventually reaches a
156.74 - stage where certain data slots provide the logical content of \isa{{\isasymTheta}} and \isa{{\isasymGamma}} sketched above, but this does not stop there!
156.75 - Various additional data slots support all kinds of mechanisms that
156.76 - are not necessarily part of the core logic.
156.77 -
156.78 - For example, there would be data for canonical introduction and
156.79 - elimination rules for arbitrary operators (depending on the
156.80 - object-logic and application), which enables users to perform
156.81 - standard proof steps implicitly (cf.\ the \isa{rule} method
156.82 - \cite{isabelle-isar-ref}).
156.83 -
156.84 - \medskip Thus Isabelle/Isar is able to bring forth more and more
156.85 - concepts successively. In particular, an object-logic like
156.86 - Isabelle/HOL continues the Isabelle/Pure setup by adding specific
156.87 - components for automated reasoning (classical reasoner, tableau
156.88 - prover, structured induction etc.) and derived specification
156.89 - mechanisms (inductive predicates, recursive functions etc.). All of
156.90 - this is ultimately based on the generic data management by theory
156.91 - and proof contexts introduced here.%
156.92 -\end{isamarkuptext}%
156.93 -\isamarkuptrue%
156.94 -%
156.95 -\isamarkupsubsection{Theory context \label{sec:context-theory}%
156.96 -}
156.97 -\isamarkuptrue%
156.98 -%
156.99 -\begin{isamarkuptext}%
156.100 -\glossary{Theory}{FIXME}
156.101 -
156.102 - A \emph{theory} is a data container with explicit named and unique
156.103 - identifier. Theories are related by a (nominal) sub-theory
156.104 - relation, which corresponds to the dependency graph of the original
156.105 - construction; each theory is derived from a certain sub-graph of
156.106 - ancestor theories.
156.107 -
156.108 - The \isa{merge} operation produces the least upper bound of two
156.109 - theories, which actually degenerates into absorption of one theory
156.110 - into the other (due to the nominal sub-theory relation).
156.111 -
156.112 - The \isa{begin} operation starts a new theory by importing
156.113 - several parent theories and entering a special \isa{draft} mode,
156.114 - which is sustained until the final \isa{end} operation. A draft
156.115 - theory acts like a linear type, where updates invalidate earlier
156.116 - versions. An invalidated draft is called ``stale''.
156.117 -
156.118 - The \isa{checkpoint} operation produces an intermediate stepping
156.119 - stone that will survive the next update: both the original and the
156.120 - changed theory remain valid and are related by the sub-theory
156.121 - relation. Checkpointing essentially recovers purely functional
156.122 - theory values, at the expense of some extra internal bookkeeping.
156.123 -
156.124 - The \isa{copy} operation produces an auxiliary version that has
156.125 - the same data content, but is unrelated to the original: updates of
156.126 - the copy do not affect the original, neither does the sub-theory
156.127 - relation hold.
156.128 -
156.129 - \medskip The example in \figref{fig:ex-theory} below shows a theory
156.130 - graph derived from \isa{Pure}, with theory \isa{Length}
156.131 - importing \isa{Nat} and \isa{List}. The body of \isa{Length} consists of a sequence of updates, working mostly on
156.132 - drafts. Intermediate checkpoints may occur as well, due to the
156.133 - history mechanism provided by the Isar top-level, cf.\
156.134 - \secref{sec:isar-toplevel}.
156.135 -
156.136 - \begin{figure}[htb]
156.137 - \begin{center}
156.138 - \begin{tabular}{rcccl}
156.139 - & & \isa{Pure} \\
156.140 - & & \isa{{\isasymdown}} \\
156.141 - & & \isa{FOL} \\
156.142 - & $\swarrow$ & & $\searrow$ & \\
156.143 - \isa{Nat} & & & & \isa{List} \\
156.144 - & $\searrow$ & & $\swarrow$ \\
156.145 - & & \isa{Length} \\
156.146 - & & \multicolumn{3}{l}{~~\hyperlink{keyword.imports}{\mbox{\isa{\isakeyword{imports}}}}} \\
156.147 - & & \multicolumn{3}{l}{~~\hyperlink{keyword.begin}{\mbox{\isa{\isakeyword{begin}}}}} \\
156.148 - & & $\vdots$~~ \\
156.149 - & & \isa{{\isasymbullet}}~~ \\
156.150 - & & $\vdots$~~ \\
156.151 - & & \isa{{\isasymbullet}}~~ \\
156.152 - & & $\vdots$~~ \\
156.153 - & & \multicolumn{3}{l}{~~\hyperlink{command.end}{\mbox{\isa{\isacommand{end}}}}} \\
156.154 - \end{tabular}
156.155 - \caption{A theory definition depending on ancestors}\label{fig:ex-theory}
156.156 - \end{center}
156.157 - \end{figure}
156.158 -
156.159 - \medskip There is a separate notion of \emph{theory reference} for
156.160 - maintaining a live link to an evolving theory context: updates on
156.161 - drafts are propagated automatically. Dynamic updating stops after
156.162 - an explicit \isa{end} only.
156.163 -
156.164 - Derived entities may store a theory reference in order to indicate
156.165 - the context they belong to. This implicitly assumes monotonic
156.166 - reasoning, because the referenced context may become larger without
156.167 - further notice.%
156.168 -\end{isamarkuptext}%
156.169 -\isamarkuptrue%
156.170 -%
156.171 -\isadelimmlref
156.172 -%
156.173 -\endisadelimmlref
156.174 -%
156.175 -\isatagmlref
156.176 -%
156.177 -\begin{isamarkuptext}%
156.178 -\begin{mldecls}
156.179 - \indexmltype{theory}\verb|type theory| \\
156.180 - \indexml{Theory.subthy}\verb|Theory.subthy: theory * theory -> bool| \\
156.181 - \indexml{Theory.merge}\verb|Theory.merge: theory * theory -> theory| \\
156.182 - \indexml{Theory.checkpoint}\verb|Theory.checkpoint: theory -> theory| \\
156.183 - \indexml{Theory.copy}\verb|Theory.copy: theory -> theory| \\
156.184 - \end{mldecls}
156.185 - \begin{mldecls}
156.186 - \indexmltype{theory\_ref}\verb|type theory_ref| \\
156.187 - \indexml{Theory.deref}\verb|Theory.deref: theory_ref -> theory| \\
156.188 - \indexml{Theory.check\_thy}\verb|Theory.check_thy: theory -> theory_ref| \\
156.189 - \end{mldecls}
156.190 -
156.191 - \begin{description}
156.192 -
156.193 - \item \verb|theory| represents theory contexts. This is
156.194 - essentially a linear type! Most operations destroy the original
156.195 - version, which then becomes ``stale''.
156.196 -
156.197 - \item \verb|Theory.subthy|~\isa{{\isacharparenleft}thy\isactrlsub {\isadigit{1}}{\isacharcomma}\ thy\isactrlsub {\isadigit{2}}{\isacharparenright}}
156.198 - compares theories according to the inherent graph structure of the
156.199 - construction. This sub-theory relation is a nominal approximation
156.200 - of inclusion (\isa{{\isasymsubseteq}}) of the corresponding content.
156.201 -
156.202 - \item \verb|Theory.merge|~\isa{{\isacharparenleft}thy\isactrlsub {\isadigit{1}}{\isacharcomma}\ thy\isactrlsub {\isadigit{2}}{\isacharparenright}}
156.203 - absorbs one theory into the other. This fails for unrelated
156.204 - theories!
156.205 -
156.206 - \item \verb|Theory.checkpoint|~\isa{thy} produces a safe
156.207 - stepping stone in the linear development of \isa{thy}. The next
156.208 - update will result in two related, valid theories.
156.209 -
156.210 - \item \verb|Theory.copy|~\isa{thy} produces a variant of \isa{thy} that holds a copy of the same data. The result is not
156.211 - related to the original; the original is unchanched.
156.212 -
156.213 - \item \verb|theory_ref| represents a sliding reference to an
156.214 - always valid theory; updates on the original are propagated
156.215 - automatically.
156.216 -
156.217 - \item \verb|Theory.deref|~\isa{thy{\isacharunderscore}ref} turns a \verb|theory_ref| into an \verb|theory| value. As the referenced
156.218 - theory evolves monotonically over time, later invocations of \verb|Theory.deref| may refer to a larger context.
156.219 -
156.220 - \item \verb|Theory.check_thy|~\isa{thy} produces a \verb|theory_ref| from a valid \verb|theory| value.
156.221 -
156.222 - \end{description}%
156.223 -\end{isamarkuptext}%
156.224 -\isamarkuptrue%
156.225 -%
156.226 -\endisatagmlref
156.227 -{\isafoldmlref}%
156.228 -%
156.229 -\isadelimmlref
156.230 -%
156.231 -\endisadelimmlref
156.232 -%
156.233 -\isamarkupsubsection{Proof context \label{sec:context-proof}%
156.234 -}
156.235 -\isamarkuptrue%
156.236 -%
156.237 -\begin{isamarkuptext}%
156.238 -\glossary{Proof context}{The static context of a structured proof,
156.239 - acts like a local ``theory'' of the current portion of Isar proof
156.240 - text, generalizes the idea of local hypotheses \isa{{\isasymGamma}} in
156.241 - judgments \isa{{\isasymGamma}\ {\isasymturnstile}\ {\isasymphi}} of natural deduction calculi. There is a
156.242 - generic notion of introducing and discharging hypotheses.
156.243 - Arbritrary auxiliary context data may be adjoined.}
156.244 -
156.245 - A proof context is a container for pure data with a back-reference
156.246 - to the theory it belongs to. The \isa{init} operation creates a
156.247 - proof context from a given theory. Modifications to draft theories
156.248 - are propagated to the proof context as usual, but there is also an
156.249 - explicit \isa{transfer} operation to force resynchronization
156.250 - with more substantial updates to the underlying theory. The actual
156.251 - context data does not require any special bookkeeping, thanks to the
156.252 - lack of destructive features.
156.253 -
156.254 - Entities derived in a proof context need to record inherent logical
156.255 - requirements explicitly, since there is no separate context
156.256 - identification as for theories. For example, hypotheses used in
156.257 - primitive derivations (cf.\ \secref{sec:thms}) are recorded
156.258 - separately within the sequent \isa{{\isasymGamma}\ {\isasymturnstile}\ {\isasymphi}}, just to make double
156.259 - sure. Results could still leak into an alien proof context do to
156.260 - programming errors, but Isabelle/Isar includes some extra validity
156.261 - checks in critical positions, notably at the end of a sub-proof.
156.262 -
156.263 - Proof contexts may be manipulated arbitrarily, although the common
156.264 - discipline is to follow block structure as a mental model: a given
156.265 - context is extended consecutively, and results are exported back
156.266 - into the original context. Note that the Isar proof states model
156.267 - block-structured reasoning explicitly, using a stack of proof
156.268 - contexts internally, cf.\ \secref{sec:isar-proof-state}.%
156.269 -\end{isamarkuptext}%
156.270 -\isamarkuptrue%
156.271 -%
156.272 -\isadelimmlref
156.273 -%
156.274 -\endisadelimmlref
156.275 -%
156.276 -\isatagmlref
156.277 -%
156.278 -\begin{isamarkuptext}%
156.279 -\begin{mldecls}
156.280 - \indexmltype{Proof.context}\verb|type Proof.context| \\
156.281 - \indexml{ProofContext.init}\verb|ProofContext.init: theory -> Proof.context| \\
156.282 - \indexml{ProofContext.theory\_of}\verb|ProofContext.theory_of: Proof.context -> theory| \\
156.283 - \indexml{ProofContext.transfer}\verb|ProofContext.transfer: theory -> Proof.context -> Proof.context| \\
156.284 - \end{mldecls}
156.285 -
156.286 - \begin{description}
156.287 -
156.288 - \item \verb|Proof.context| represents proof contexts. Elements
156.289 - of this type are essentially pure values, with a sliding reference
156.290 - to the background theory.
156.291 -
156.292 - \item \verb|ProofContext.init|~\isa{thy} produces a proof context
156.293 - derived from \isa{thy}, initializing all data.
156.294 -
156.295 - \item \verb|ProofContext.theory_of|~\isa{ctxt} selects the
156.296 - background theory from \isa{ctxt}, dereferencing its internal
156.297 - \verb|theory_ref|.
156.298 -
156.299 - \item \verb|ProofContext.transfer|~\isa{thy\ ctxt} promotes the
156.300 - background theory of \isa{ctxt} to the super theory \isa{thy}.
156.301 -
156.302 - \end{description}%
156.303 -\end{isamarkuptext}%
156.304 -\isamarkuptrue%
156.305 -%
156.306 -\endisatagmlref
156.307 -{\isafoldmlref}%
156.308 -%
156.309 -\isadelimmlref
156.310 -%
156.311 -\endisadelimmlref
156.312 -%
156.313 -\isamarkupsubsection{Generic contexts \label{sec:generic-context}%
156.314 -}
156.315 -\isamarkuptrue%
156.316 -%
156.317 -\begin{isamarkuptext}%
156.318 -A generic context is the disjoint sum of either a theory or proof
156.319 - context. Occasionally, this enables uniform treatment of generic
156.320 - context data, typically extra-logical information. Operations on
156.321 - generic contexts include the usual injections, partial selections,
156.322 - and combinators for lifting operations on either component of the
156.323 - disjoint sum.
156.324 -
156.325 - Moreover, there are total operations \isa{theory{\isacharunderscore}of} and \isa{proof{\isacharunderscore}of} to convert a generic context into either kind: a theory
156.326 - can always be selected from the sum, while a proof context might
156.327 - have to be constructed by an ad-hoc \isa{init} operation.%
156.328 -\end{isamarkuptext}%
156.329 -\isamarkuptrue%
156.330 -%
156.331 -\isadelimmlref
156.332 -%
156.333 -\endisadelimmlref
156.334 -%
156.335 -\isatagmlref
156.336 -%
156.337 -\begin{isamarkuptext}%
156.338 -\begin{mldecls}
156.339 - \indexmltype{Context.generic}\verb|type Context.generic| \\
156.340 - \indexml{Context.theory\_of}\verb|Context.theory_of: Context.generic -> theory| \\
156.341 - \indexml{Context.proof\_of}\verb|Context.proof_of: Context.generic -> Proof.context| \\
156.342 - \end{mldecls}
156.343 -
156.344 - \begin{description}
156.345 -
156.346 - \item \verb|Context.generic| is the direct sum of \verb|theory| and \verb|Proof.context|, with the datatype
156.347 - constructors \verb|Context.Theory| and \verb|Context.Proof|.
156.348 -
156.349 - \item \verb|Context.theory_of|~\isa{context} always produces a
156.350 - theory from the generic \isa{context}, using \verb|ProofContext.theory_of| as required.
156.351 -
156.352 - \item \verb|Context.proof_of|~\isa{context} always produces a
156.353 - proof context from the generic \isa{context}, using \verb|ProofContext.init| as required (note that this re-initializes the
156.354 - context data with each invocation).
156.355 -
156.356 - \end{description}%
156.357 -\end{isamarkuptext}%
156.358 -\isamarkuptrue%
156.359 -%
156.360 -\endisatagmlref
156.361 -{\isafoldmlref}%
156.362 -%
156.363 -\isadelimmlref
156.364 -%
156.365 -\endisadelimmlref
156.366 -%
156.367 -\isamarkupsubsection{Context data \label{sec:context-data}%
156.368 -}
156.369 -\isamarkuptrue%
156.370 -%
156.371 -\begin{isamarkuptext}%
156.372 -The main purpose of theory and proof contexts is to manage arbitrary
156.373 - data. New data types can be declared incrementally at compile time.
156.374 - There are separate declaration mechanisms for any of the three kinds
156.375 - of contexts: theory, proof, generic.
156.376 -
156.377 - \paragraph{Theory data} may refer to destructive entities, which are
156.378 - maintained in direct correspondence to the linear evolution of
156.379 - theory values, including explicit copies.\footnote{Most existing
156.380 - instances of destructive theory data are merely historical relics
156.381 - (e.g.\ the destructive theorem storage, and destructive hints for
156.382 - the Simplifier and Classical rules).} A theory data declaration
156.383 - needs to implement the following SML signature:
156.384 -
156.385 - \medskip
156.386 - \begin{tabular}{ll}
156.387 - \isa{{\isasymtype}\ T} & representing type \\
156.388 - \isa{{\isasymval}\ empty{\isacharcolon}\ T} & empty default value \\
156.389 - \isa{{\isasymval}\ copy{\isacharcolon}\ T\ {\isasymrightarrow}\ T} & refresh impure data \\
156.390 - \isa{{\isasymval}\ extend{\isacharcolon}\ T\ {\isasymrightarrow}\ T} & re-initialize on import \\
156.391 - \isa{{\isasymval}\ merge{\isacharcolon}\ T\ {\isasymtimes}\ T\ {\isasymrightarrow}\ T} & join on import \\
156.392 - \end{tabular}
156.393 - \medskip
156.394 -
156.395 - \noindent The \isa{empty} value acts as initial default for
156.396 - \emph{any} theory that does not declare actual data content; \isa{copy} maintains persistent integrity for impure data, it is just
156.397 - the identity for pure values; \isa{extend} is acts like a
156.398 - unitary version of \isa{merge}, both operations should also
156.399 - include the functionality of \isa{copy} for impure data.
156.400 -
156.401 - \paragraph{Proof context data} is purely functional. A declaration
156.402 - needs to implement the following SML signature:
156.403 -
156.404 - \medskip
156.405 - \begin{tabular}{ll}
156.406 - \isa{{\isasymtype}\ T} & representing type \\
156.407 - \isa{{\isasymval}\ init{\isacharcolon}\ theory\ {\isasymrightarrow}\ T} & produce initial value \\
156.408 - \end{tabular}
156.409 - \medskip
156.410 -
156.411 - \noindent The \isa{init} operation is supposed to produce a pure
156.412 - value from the given background theory.
156.413 -
156.414 - \paragraph{Generic data} provides a hybrid interface for both theory
156.415 - and proof data. The declaration is essentially the same as for
156.416 - (pure) theory data, without \isa{copy}. The \isa{init}
156.417 - operation for proof contexts merely selects the current data value
156.418 - from the background theory.
156.419 -
156.420 - \bigskip A data declaration of type \isa{T} results in the
156.421 - following interface:
156.422 -
156.423 - \medskip
156.424 - \begin{tabular}{ll}
156.425 - \isa{init{\isacharcolon}\ theory\ {\isasymrightarrow}\ theory} \\
156.426 - \isa{get{\isacharcolon}\ context\ {\isasymrightarrow}\ T} \\
156.427 - \isa{put{\isacharcolon}\ T\ {\isasymrightarrow}\ context\ {\isasymrightarrow}\ context} \\
156.428 - \isa{map{\isacharcolon}\ {\isacharparenleft}T\ {\isasymrightarrow}\ T{\isacharparenright}\ {\isasymrightarrow}\ context\ {\isasymrightarrow}\ context} \\
156.429 - \end{tabular}
156.430 - \medskip
156.431 -
156.432 - \noindent Here \isa{init} is only applicable to impure theory
156.433 - data to install a fresh copy persistently (destructive update on
156.434 - uninitialized has no permanent effect). The other operations provide
156.435 - access for the particular kind of context (theory, proof, or generic
156.436 - context). Note that this is a safe interface: there is no other way
156.437 - to access the corresponding data slot of a context. By keeping
156.438 - these operations private, a component may maintain abstract values
156.439 - authentically, without other components interfering.%
156.440 -\end{isamarkuptext}%
156.441 -\isamarkuptrue%
156.442 -%
156.443 -\isadelimmlref
156.444 -%
156.445 -\endisadelimmlref
156.446 -%
156.447 -\isatagmlref
156.448 -%
156.449 -\begin{isamarkuptext}%
156.450 -\begin{mldecls}
156.451 - \indexmlfunctor{TheoryDataFun}\verb|functor TheoryDataFun| \\
156.452 - \indexmlfunctor{ProofDataFun}\verb|functor ProofDataFun| \\
156.453 - \indexmlfunctor{GenericDataFun}\verb|functor GenericDataFun| \\
156.454 - \end{mldecls}
156.455 -
156.456 - \begin{description}
156.457 -
156.458 - \item \verb|TheoryDataFun|\isa{{\isacharparenleft}spec{\isacharparenright}} declares data for
156.459 - type \verb|theory| according to the specification provided as
156.460 - argument structure. The resulting structure provides data init and
156.461 - access operations as described above.
156.462 -
156.463 - \item \verb|ProofDataFun|\isa{{\isacharparenleft}spec{\isacharparenright}} is analogous to
156.464 - \verb|TheoryDataFun| for type \verb|Proof.context|.
156.465 -
156.466 - \item \verb|GenericDataFun|\isa{{\isacharparenleft}spec{\isacharparenright}} is analogous to
156.467 - \verb|TheoryDataFun| for type \verb|Context.generic|.
156.468 -
156.469 - \end{description}%
156.470 -\end{isamarkuptext}%
156.471 -\isamarkuptrue%
156.472 -%
156.473 -\endisatagmlref
156.474 -{\isafoldmlref}%
156.475 -%
156.476 -\isadelimmlref
156.477 -%
156.478 -\endisadelimmlref
156.479 -%
156.480 -\isamarkupsection{Names \label{sec:names}%
156.481 -}
156.482 -\isamarkuptrue%
156.483 -%
156.484 -\begin{isamarkuptext}%
156.485 -In principle, a name is just a string, but there are various
156.486 - convention for encoding additional structure. For example, ``\isa{Foo{\isachardot}bar{\isachardot}baz}'' is considered as a qualified name consisting of
156.487 - three basic name components. The individual constituents of a name
156.488 - may have further substructure, e.g.\ the string
156.489 - ``\verb,\,\verb,<alpha>,'' encodes as a single symbol.%
156.490 -\end{isamarkuptext}%
156.491 -\isamarkuptrue%
156.492 -%
156.493 -\isamarkupsubsection{Strings of symbols%
156.494 -}
156.495 -\isamarkuptrue%
156.496 -%
156.497 -\begin{isamarkuptext}%
156.498 -\glossary{Symbol}{The smallest unit of text in Isabelle, subsumes
156.499 - plain ASCII characters as well as an infinite collection of named
156.500 - symbols (for greek, math etc.).}
156.501 -
156.502 - A \emph{symbol} constitutes the smallest textual unit in Isabelle
156.503 - --- raw characters are normally not encountered at all. Isabelle
156.504 - strings consist of a sequence of symbols, represented as a packed
156.505 - string or a list of strings. Each symbol is in itself a small
156.506 - string, which has either one of the following forms:
156.507 -
156.508 - \begin{enumerate}
156.509 -
156.510 - \item a single ASCII character ``\isa{c}'', for example
156.511 - ``\verb,a,'',
156.512 -
156.513 - \item a regular symbol ``\verb,\,\verb,<,\isa{ident}\verb,>,'',
156.514 - for example ``\verb,\,\verb,<alpha>,'',
156.515 -
156.516 - \item a control symbol ``\verb,\,\verb,<^,\isa{ident}\verb,>,'',
156.517 - for example ``\verb,\,\verb,<^bold>,'',
156.518 -
156.519 - \item a raw symbol ``\verb,\,\verb,<^raw:,\isa{text}\verb,>,''
156.520 - where \isa{text} constists of printable characters excluding
156.521 - ``\verb,.,'' and ``\verb,>,'', for example
156.522 - ``\verb,\,\verb,<^raw:$\sum_{i = 1}^n$>,'',
156.523 -
156.524 - \item a numbered raw control symbol ``\verb,\,\verb,<^raw,\isa{n}\verb,>, where \isa{n} consists of digits, for example
156.525 - ``\verb,\,\verb,<^raw42>,''.
156.526 -
156.527 - \end{enumerate}
156.528 -
156.529 - \noindent The \isa{ident} syntax for symbol names is \isa{letter\ {\isacharparenleft}letter\ {\isacharbar}\ digit{\isacharparenright}\isactrlsup {\isacharasterisk}}, where \isa{letter\ {\isacharequal}\ A{\isachardot}{\isachardot}Za{\isachardot}{\isachardot}z} and \isa{digit\ {\isacharequal}\ {\isadigit{0}}{\isachardot}{\isachardot}{\isadigit{9}}}. There are infinitely many
156.530 - regular symbols and control symbols, but a fixed collection of
156.531 - standard symbols is treated specifically. For example,
156.532 - ``\verb,\,\verb,<alpha>,'' is classified as a letter, which means it
156.533 - may occur within regular Isabelle identifiers.
156.534 -
156.535 - Since the character set underlying Isabelle symbols is 7-bit ASCII
156.536 - and 8-bit characters are passed through transparently, Isabelle may
156.537 - also process Unicode/UCS data in UTF-8 encoding. Unicode provides
156.538 - its own collection of mathematical symbols, but there is no built-in
156.539 - link to the standard collection of Isabelle.
156.540 -
156.541 - \medskip Output of Isabelle symbols depends on the print mode
156.542 - (\secref{FIXME}). For example, the standard {\LaTeX} setup of the
156.543 - Isabelle document preparation system would present
156.544 - ``\verb,\,\verb,<alpha>,'' as \isa{{\isasymalpha}}, and
156.545 - ``\verb,\,\verb,<^bold>,\verb,\,\verb,<alpha>,'' as \isa{\isactrlbold {\isasymalpha}}.%
156.546 -\end{isamarkuptext}%
156.547 -\isamarkuptrue%
156.548 -%
156.549 -\isadelimmlref
156.550 -%
156.551 -\endisadelimmlref
156.552 -%
156.553 -\isatagmlref
156.554 -%
156.555 -\begin{isamarkuptext}%
156.556 -\begin{mldecls}
156.557 - \indexmltype{Symbol.symbol}\verb|type Symbol.symbol| \\
156.558 - \indexml{Symbol.explode}\verb|Symbol.explode: string -> Symbol.symbol list| \\
156.559 - \indexml{Symbol.is\_letter}\verb|Symbol.is_letter: Symbol.symbol -> bool| \\
156.560 - \indexml{Symbol.is\_digit}\verb|Symbol.is_digit: Symbol.symbol -> bool| \\
156.561 - \indexml{Symbol.is\_quasi}\verb|Symbol.is_quasi: Symbol.symbol -> bool| \\
156.562 - \indexml{Symbol.is\_blank}\verb|Symbol.is_blank: Symbol.symbol -> bool| \\
156.563 - \end{mldecls}
156.564 - \begin{mldecls}
156.565 - \indexmltype{Symbol.sym}\verb|type Symbol.sym| \\
156.566 - \indexml{Symbol.decode}\verb|Symbol.decode: Symbol.symbol -> Symbol.sym| \\
156.567 - \end{mldecls}
156.568 -
156.569 - \begin{description}
156.570 -
156.571 - \item \verb|Symbol.symbol| represents individual Isabelle
156.572 - symbols; this is an alias for \verb|string|.
156.573 -
156.574 - \item \verb|Symbol.explode|~\isa{str} produces a symbol list
156.575 - from the packed form. This function supercedes \verb|String.explode| for virtually all purposes of manipulating text in
156.576 - Isabelle!
156.577 -
156.578 - \item \verb|Symbol.is_letter|, \verb|Symbol.is_digit|, \verb|Symbol.is_quasi|, \verb|Symbol.is_blank| classify standard
156.579 - symbols according to fixed syntactic conventions of Isabelle, cf.\
156.580 - \cite{isabelle-isar-ref}.
156.581 -
156.582 - \item \verb|Symbol.sym| is a concrete datatype that represents
156.583 - the different kinds of symbols explicitly, with constructors \verb|Symbol.Char|, \verb|Symbol.Sym|, \verb|Symbol.Ctrl|, \verb|Symbol.Raw|.
156.584 -
156.585 - \item \verb|Symbol.decode| converts the string representation of a
156.586 - symbol into the datatype version.
156.587 -
156.588 - \end{description}%
156.589 -\end{isamarkuptext}%
156.590 -\isamarkuptrue%
156.591 -%
156.592 -\endisatagmlref
156.593 -{\isafoldmlref}%
156.594 -%
156.595 -\isadelimmlref
156.596 -%
156.597 -\endisadelimmlref
156.598 -%
156.599 -\isamarkupsubsection{Basic names \label{sec:basic-names}%
156.600 -}
156.601 -\isamarkuptrue%
156.602 -%
156.603 -\begin{isamarkuptext}%
156.604 -A \emph{basic name} essentially consists of a single Isabelle
156.605 - identifier. There are conventions to mark separate classes of basic
156.606 - names, by attaching a suffix of underscores (\isa{{\isacharunderscore}}): one
156.607 - underscore means \emph{internal name}, two underscores means
156.608 - \emph{Skolem name}, three underscores means \emph{internal Skolem
156.609 - name}.
156.610 -
156.611 - For example, the basic name \isa{foo} has the internal version
156.612 - \isa{foo{\isacharunderscore}}, with Skolem versions \isa{foo{\isacharunderscore}{\isacharunderscore}} and \isa{foo{\isacharunderscore}{\isacharunderscore}{\isacharunderscore}}, respectively.
156.613 -
156.614 - These special versions provide copies of the basic name space, apart
156.615 - from anything that normally appears in the user text. For example,
156.616 - system generated variables in Isar proof contexts are usually marked
156.617 - as internal, which prevents mysterious name references like \isa{xaa} to appear in the text.
156.618 -
156.619 - \medskip Manipulating binding scopes often requires on-the-fly
156.620 - renamings. A \emph{name context} contains a collection of already
156.621 - used names. The \isa{declare} operation adds names to the
156.622 - context.
156.623 -
156.624 - The \isa{invents} operation derives a number of fresh names from
156.625 - a given starting point. For example, the first three names derived
156.626 - from \isa{a} are \isa{a}, \isa{b}, \isa{c}.
156.627 -
156.628 - The \isa{variants} operation produces fresh names by
156.629 - incrementing tentative names as base-26 numbers (with digits \isa{a{\isachardot}{\isachardot}z}) until all clashes are resolved. For example, name \isa{foo} results in variants \isa{fooa}, \isa{foob}, \isa{fooc}, \dots, \isa{fooaa}, \isa{fooab} etc.; each renaming
156.630 - step picks the next unused variant from this sequence.%
156.631 -\end{isamarkuptext}%
156.632 -\isamarkuptrue%
156.633 -%
156.634 -\isadelimmlref
156.635 -%
156.636 -\endisadelimmlref
156.637 -%
156.638 -\isatagmlref
156.639 -%
156.640 -\begin{isamarkuptext}%
156.641 -\begin{mldecls}
156.642 - \indexml{Name.internal}\verb|Name.internal: string -> string| \\
156.643 - \indexml{Name.skolem}\verb|Name.skolem: string -> string| \\
156.644 - \end{mldecls}
156.645 - \begin{mldecls}
156.646 - \indexmltype{Name.context}\verb|type Name.context| \\
156.647 - \indexml{Name.context}\verb|Name.context: Name.context| \\
156.648 - \indexml{Name.declare}\verb|Name.declare: string -> Name.context -> Name.context| \\
156.649 - \indexml{Name.invents}\verb|Name.invents: Name.context -> string -> int -> string list| \\
156.650 - \indexml{Name.variants}\verb|Name.variants: string list -> Name.context -> string list * Name.context| \\
156.651 - \end{mldecls}
156.652 -
156.653 - \begin{description}
156.654 -
156.655 - \item \verb|Name.internal|~\isa{name} produces an internal name
156.656 - by adding one underscore.
156.657 -
156.658 - \item \verb|Name.skolem|~\isa{name} produces a Skolem name by
156.659 - adding two underscores.
156.660 -
156.661 - \item \verb|Name.context| represents the context of already used
156.662 - names; the initial value is \verb|Name.context|.
156.663 -
156.664 - \item \verb|Name.declare|~\isa{name} enters a used name into the
156.665 - context.
156.666 -
156.667 - \item \verb|Name.invents|~\isa{context\ name\ n} produces \isa{n} fresh names derived from \isa{name}.
156.668 -
156.669 - \item \verb|Name.variants|~\isa{names\ context} produces fresh
156.670 - varians of \isa{names}; the result is entered into the context.
156.671 -
156.672 - \end{description}%
156.673 -\end{isamarkuptext}%
156.674 -\isamarkuptrue%
156.675 -%
156.676 -\endisatagmlref
156.677 -{\isafoldmlref}%
156.678 -%
156.679 -\isadelimmlref
156.680 -%
156.681 -\endisadelimmlref
156.682 -%
156.683 -\isamarkupsubsection{Indexed names%
156.684 -}
156.685 -\isamarkuptrue%
156.686 -%
156.687 -\begin{isamarkuptext}%
156.688 -An \emph{indexed name} (or \isa{indexname}) is a pair of a basic
156.689 - name and a natural number. This representation allows efficient
156.690 - renaming by incrementing the second component only. The canonical
156.691 - way to rename two collections of indexnames apart from each other is
156.692 - this: determine the maximum index \isa{maxidx} of the first
156.693 - collection, then increment all indexes of the second collection by
156.694 - \isa{maxidx\ {\isacharplus}\ {\isadigit{1}}}; the maximum index of an empty collection is
156.695 - \isa{{\isacharminus}{\isadigit{1}}}.
156.696 -
156.697 - Occasionally, basic names and indexed names are injected into the
156.698 - same pair type: the (improper) indexname \isa{{\isacharparenleft}x{\isacharcomma}\ {\isacharminus}{\isadigit{1}}{\isacharparenright}} is used
156.699 - to encode basic names.
156.700 -
156.701 - \medskip Isabelle syntax observes the following rules for
156.702 - representing an indexname \isa{{\isacharparenleft}x{\isacharcomma}\ i{\isacharparenright}} as a packed string:
156.703 -
156.704 - \begin{itemize}
156.705 -
156.706 - \item \isa{{\isacharquery}x} if \isa{x} does not end with a digit and \isa{i\ {\isacharequal}\ {\isadigit{0}}},
156.707 -
156.708 - \item \isa{{\isacharquery}xi} if \isa{x} does not end with a digit,
156.709 -
156.710 - \item \isa{{\isacharquery}x{\isachardot}i} otherwise.
156.711 -
156.712 - \end{itemize}
156.713 -
156.714 - Indexnames may acquire large index numbers over time. Results are
156.715 - normalized towards \isa{{\isadigit{0}}} at certain checkpoints, notably at
156.716 - the end of a proof. This works by producing variants of the
156.717 - corresponding basic name components. For example, the collection
156.718 - \isa{{\isacharquery}x{\isadigit{1}}{\isacharcomma}\ {\isacharquery}x{\isadigit{7}}{\isacharcomma}\ {\isacharquery}x{\isadigit{4}}{\isadigit{2}}} becomes \isa{{\isacharquery}x{\isacharcomma}\ {\isacharquery}xa{\isacharcomma}\ {\isacharquery}xb}.%
156.719 -\end{isamarkuptext}%
156.720 -\isamarkuptrue%
156.721 -%
156.722 -\isadelimmlref
156.723 -%
156.724 -\endisadelimmlref
156.725 -%
156.726 -\isatagmlref
156.727 -%
156.728 -\begin{isamarkuptext}%
156.729 -\begin{mldecls}
156.730 - \indexmltype{indexname}\verb|type indexname| \\
156.731 - \end{mldecls}
156.732 -
156.733 - \begin{description}
156.734 -
156.735 - \item \verb|indexname| represents indexed names. This is an
156.736 - abbreviation for \verb|string * int|. The second component is
156.737 - usually non-negative, except for situations where \isa{{\isacharparenleft}x{\isacharcomma}\ {\isacharminus}{\isadigit{1}}{\isacharparenright}}
156.738 - is used to embed basic names into this type.
156.739 -
156.740 - \end{description}%
156.741 -\end{isamarkuptext}%
156.742 -\isamarkuptrue%
156.743 -%
156.744 -\endisatagmlref
156.745 -{\isafoldmlref}%
156.746 -%
156.747 -\isadelimmlref
156.748 -%
156.749 -\endisadelimmlref
156.750 -%
156.751 -\isamarkupsubsection{Qualified names and name spaces%
156.752 -}
156.753 -\isamarkuptrue%
156.754 -%
156.755 -\begin{isamarkuptext}%
156.756 -A \emph{qualified name} consists of a non-empty sequence of basic
156.757 - name components. The packed representation uses a dot as separator,
156.758 - as in ``\isa{A{\isachardot}b{\isachardot}c}''. The last component is called \emph{base}
156.759 - name, the remaining prefix \emph{qualifier} (which may be empty).
156.760 - The idea of qualified names is to encode nested structures by
156.761 - recording the access paths as qualifiers. For example, an item
156.762 - named ``\isa{A{\isachardot}b{\isachardot}c}'' may be understood as a local entity \isa{c}, within a local structure \isa{b}, within a global
156.763 - structure \isa{A}. Typically, name space hierarchies consist of
156.764 - 1--2 levels of qualification, but this need not be always so.
156.765 -
156.766 - The empty name is commonly used as an indication of unnamed
156.767 - entities, whenever this makes any sense. The basic operations on
156.768 - qualified names are smart enough to pass through such improper names
156.769 - unchanged.
156.770 -
156.771 - \medskip A \isa{naming} policy tells how to turn a name
156.772 - specification into a fully qualified internal name (by the \isa{full} operation), and how fully qualified names may be accessed
156.773 - externally. For example, the default naming policy is to prefix an
156.774 - implicit path: \isa{full\ x} produces \isa{path{\isachardot}x}, and the
156.775 - standard accesses for \isa{path{\isachardot}x} include both \isa{x} and
156.776 - \isa{path{\isachardot}x}. Normally, the naming is implicit in the theory or
156.777 - proof context; there are separate versions of the corresponding.
156.778 -
156.779 - \medskip A \isa{name\ space} manages a collection of fully
156.780 - internalized names, together with a mapping between external names
156.781 - and internal names (in both directions). The corresponding \isa{intern} and \isa{extern} operations are mostly used for
156.782 - parsing and printing only! The \isa{declare} operation augments
156.783 - a name space according to the accesses determined by the naming
156.784 - policy.
156.785 -
156.786 - \medskip As a general principle, there is a separate name space for
156.787 - each kind of formal entity, e.g.\ logical constant, type
156.788 - constructor, type class, theorem. It is usually clear from the
156.789 - occurrence in concrete syntax (or from the scope) which kind of
156.790 - entity a name refers to. For example, the very same name \isa{c} may be used uniformly for a constant, type constructor, and
156.791 - type class.
156.792 -
156.793 - There are common schemes to name theorems systematically, according
156.794 - to the name of the main logical entity involved, e.g.\ \isa{c{\isachardot}intro} for a canonical theorem related to constant \isa{c}.
156.795 - This technique of mapping names from one space into another requires
156.796 - some care in order to avoid conflicts. In particular, theorem names
156.797 - derived from a type constructor or type class are better suffixed in
156.798 - addition to the usual qualification, e.g.\ \isa{c{\isacharunderscore}type{\isachardot}intro}
156.799 - and \isa{c{\isacharunderscore}class{\isachardot}intro} for theorems related to type \isa{c}
156.800 - and class \isa{c}, respectively.%
156.801 -\end{isamarkuptext}%
156.802 -\isamarkuptrue%
156.803 -%
156.804 -\isadelimmlref
156.805 -%
156.806 -\endisadelimmlref
156.807 -%
156.808 -\isatagmlref
156.809 -%
156.810 -\begin{isamarkuptext}%
156.811 -\begin{mldecls}
156.812 - \indexml{NameSpace.base}\verb|NameSpace.base: string -> string| \\
156.813 - \indexml{NameSpace.qualifier}\verb|NameSpace.qualifier: string -> string| \\
156.814 - \indexml{NameSpace.append}\verb|NameSpace.append: string -> string -> string| \\
156.815 - \indexml{NameSpace.implode}\verb|NameSpace.implode: string list -> string| \\
156.816 - \indexml{NameSpace.explode}\verb|NameSpace.explode: string -> string list| \\
156.817 - \end{mldecls}
156.818 - \begin{mldecls}
156.819 - \indexmltype{NameSpace.naming}\verb|type NameSpace.naming| \\
156.820 - \indexml{NameSpace.default\_naming}\verb|NameSpace.default_naming: NameSpace.naming| \\
156.821 - \indexml{NameSpace.add\_path}\verb|NameSpace.add_path: string -> NameSpace.naming -> NameSpace.naming| \\
156.822 - \indexml{NameSpace.full\_name}\verb|NameSpace.full_name: NameSpace.naming -> binding -> string| \\
156.823 - \end{mldecls}
156.824 - \begin{mldecls}
156.825 - \indexmltype{NameSpace.T}\verb|type NameSpace.T| \\
156.826 - \indexml{NameSpace.empty}\verb|NameSpace.empty: NameSpace.T| \\
156.827 - \indexml{NameSpace.merge}\verb|NameSpace.merge: NameSpace.T * NameSpace.T -> NameSpace.T| \\
156.828 - \indexml{NameSpace.declare}\verb|NameSpace.declare: NameSpace.naming -> binding -> NameSpace.T -> string * NameSpace.T| \\
156.829 - \indexml{NameSpace.intern}\verb|NameSpace.intern: NameSpace.T -> string -> string| \\
156.830 - \indexml{NameSpace.extern}\verb|NameSpace.extern: NameSpace.T -> string -> string| \\
156.831 - \end{mldecls}
156.832 -
156.833 - \begin{description}
156.834 -
156.835 - \item \verb|NameSpace.base|~\isa{name} returns the base name of a
156.836 - qualified name.
156.837 -
156.838 - \item \verb|NameSpace.qualifier|~\isa{name} returns the qualifier
156.839 - of a qualified name.
156.840 -
156.841 - \item \verb|NameSpace.append|~\isa{name\isactrlisub {\isadigit{1}}\ name\isactrlisub {\isadigit{2}}}
156.842 - appends two qualified names.
156.843 -
156.844 - \item \verb|NameSpace.implode|~\isa{name} and \verb|NameSpace.explode|~\isa{names} convert between the packed string
156.845 - representation and the explicit list form of qualified names.
156.846 -
156.847 - \item \verb|NameSpace.naming| represents the abstract concept of
156.848 - a naming policy.
156.849 -
156.850 - \item \verb|NameSpace.default_naming| is the default naming policy.
156.851 - In a theory context, this is usually augmented by a path prefix
156.852 - consisting of the theory name.
156.853 -
156.854 - \item \verb|NameSpace.add_path|~\isa{path\ naming} augments the
156.855 - naming policy by extending its path component.
156.856 -
156.857 - \item \verb|NameSpace.full_name|\isa{naming\ binding} turns a name
156.858 - binding (usually a basic name) into the fully qualified
156.859 - internal name, according to the given naming policy.
156.860 -
156.861 - \item \verb|NameSpace.T| represents name spaces.
156.862 -
156.863 - \item \verb|NameSpace.empty| and \verb|NameSpace.merge|~\isa{{\isacharparenleft}space\isactrlisub {\isadigit{1}}{\isacharcomma}\ space\isactrlisub {\isadigit{2}}{\isacharparenright}} are the canonical operations for
156.864 - maintaining name spaces according to theory data management
156.865 - (\secref{sec:context-data}).
156.866 -
156.867 - \item \verb|NameSpace.declare|~\isa{naming\ bindings\ space} enters a
156.868 - name binding as fully qualified internal name into the name space,
156.869 - with external accesses determined by the naming policy.
156.870 -
156.871 - \item \verb|NameSpace.intern|~\isa{space\ name} internalizes a
156.872 - (partially qualified) external name.
156.873 -
156.874 - This operation is mostly for parsing! Note that fully qualified
156.875 - names stemming from declarations are produced via \verb|NameSpace.full_name| and \verb|NameSpace.declare|
156.876 - (or their derivatives for \verb|theory| and
156.877 - \verb|Proof.context|).
156.878 -
156.879 - \item \verb|NameSpace.extern|~\isa{space\ name} externalizes a
156.880 - (fully qualified) internal name.
156.881 -
156.882 - This operation is mostly for printing! Note unqualified names are
156.883 - produced via \verb|NameSpace.base|.
156.884 -
156.885 - \end{description}%
156.886 -\end{isamarkuptext}%
156.887 -\isamarkuptrue%
156.888 -%
156.889 -\endisatagmlref
156.890 -{\isafoldmlref}%
156.891 -%
156.892 -\isadelimmlref
156.893 -%
156.894 -\endisadelimmlref
156.895 -%
156.896 -\isadelimtheory
156.897 -%
156.898 -\endisadelimtheory
156.899 -%
156.900 -\isatagtheory
156.901 -\isacommand{end}\isamarkupfalse%
156.902 -%
156.903 -\endisatagtheory
156.904 -{\isafoldtheory}%
156.905 -%
156.906 -\isadelimtheory
156.907 -%
156.908 -\endisadelimtheory
156.909 -\isanewline
156.910 -\end{isabellebody}%
156.911 -%%% Local Variables:
156.912 -%%% mode: latex
156.913 -%%% TeX-master: "root"
156.914 -%%% End:
157.1 --- a/doc-src/IsarImplementation/Thy/document/proof.tex Wed Mar 04 11:05:02 2009 +0100
157.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
157.3 @@ -1,396 +0,0 @@
157.4 -%
157.5 -\begin{isabellebody}%
157.6 -\def\isabellecontext{proof}%
157.7 -%
157.8 -\isadelimtheory
157.9 -\isanewline
157.10 -\isanewline
157.11 -\isanewline
157.12 -%
157.13 -\endisadelimtheory
157.14 -%
157.15 -\isatagtheory
157.16 -\isacommand{theory}\isamarkupfalse%
157.17 -\ {\isachardoublequoteopen}proof{\isachardoublequoteclose}\ \isakeyword{imports}\ base\ \isakeyword{begin}%
157.18 -\endisatagtheory
157.19 -{\isafoldtheory}%
157.20 -%
157.21 -\isadelimtheory
157.22 -%
157.23 -\endisadelimtheory
157.24 -%
157.25 -\isamarkupchapter{Structured proofs%
157.26 -}
157.27 -\isamarkuptrue%
157.28 -%
157.29 -\isamarkupsection{Variables \label{sec:variables}%
157.30 -}
157.31 -\isamarkuptrue%
157.32 -%
157.33 -\begin{isamarkuptext}%
157.34 -Any variable that is not explicitly bound by \isa{{\isasymlambda}}-abstraction
157.35 - is considered as ``free''. Logically, free variables act like
157.36 - outermost universal quantification at the sequent level: \isa{A\isactrlisub {\isadigit{1}}{\isacharparenleft}x{\isacharparenright}{\isacharcomma}\ {\isasymdots}{\isacharcomma}\ A\isactrlisub n{\isacharparenleft}x{\isacharparenright}\ {\isasymturnstile}\ B{\isacharparenleft}x{\isacharparenright}} means that the result
157.37 - holds \emph{for all} values of \isa{x}. Free variables for
157.38 - terms (not types) can be fully internalized into the logic: \isa{{\isasymturnstile}\ B{\isacharparenleft}x{\isacharparenright}} and \isa{{\isasymturnstile}\ {\isasymAnd}x{\isachardot}\ B{\isacharparenleft}x{\isacharparenright}} are interchangeable, provided
157.39 - that \isa{x} does not occur elsewhere in the context.
157.40 - Inspecting \isa{{\isasymturnstile}\ {\isasymAnd}x{\isachardot}\ B{\isacharparenleft}x{\isacharparenright}} more closely, we see that inside the
157.41 - quantifier, \isa{x} is essentially ``arbitrary, but fixed'',
157.42 - while from outside it appears as a place-holder for instantiation
157.43 - (thanks to \isa{{\isasymAnd}} elimination).
157.44 -
157.45 - The Pure logic represents the idea of variables being either inside
157.46 - or outside the current scope by providing separate syntactic
157.47 - categories for \emph{fixed variables} (e.g.\ \isa{x}) vs.\
157.48 - \emph{schematic variables} (e.g.\ \isa{{\isacharquery}x}). Incidently, a
157.49 - universal result \isa{{\isasymturnstile}\ {\isasymAnd}x{\isachardot}\ B{\isacharparenleft}x{\isacharparenright}} has the HHF normal form \isa{{\isasymturnstile}\ B{\isacharparenleft}{\isacharquery}x{\isacharparenright}}, which represents its generality nicely without requiring
157.50 - an explicit quantifier. The same principle works for type
157.51 - variables: \isa{{\isasymturnstile}\ B{\isacharparenleft}{\isacharquery}{\isasymalpha}{\isacharparenright}} represents the idea of ``\isa{{\isasymturnstile}\ {\isasymforall}{\isasymalpha}{\isachardot}\ B{\isacharparenleft}{\isasymalpha}{\isacharparenright}}'' without demanding a truly polymorphic framework.
157.52 -
157.53 - \medskip Additional care is required to treat type variables in a
157.54 - way that facilitates type-inference. In principle, term variables
157.55 - depend on type variables, which means that type variables would have
157.56 - to be declared first. For example, a raw type-theoretic framework
157.57 - would demand the context to be constructed in stages as follows:
157.58 - \isa{{\isasymGamma}\ {\isacharequal}\ {\isasymalpha}{\isacharcolon}\ type{\isacharcomma}\ x{\isacharcolon}\ {\isasymalpha}{\isacharcomma}\ a{\isacharcolon}\ A{\isacharparenleft}x\isactrlisub {\isasymalpha}{\isacharparenright}}.
157.59 -
157.60 - We allow a slightly less formalistic mode of operation: term
157.61 - variables \isa{x} are fixed without specifying a type yet
157.62 - (essentially \emph{all} potential occurrences of some instance
157.63 - \isa{x\isactrlisub {\isasymtau}} are fixed); the first occurrence of \isa{x}
157.64 - within a specific term assigns its most general type, which is then
157.65 - maintained consistently in the context. The above example becomes
157.66 - \isa{{\isasymGamma}\ {\isacharequal}\ x{\isacharcolon}\ term{\isacharcomma}\ {\isasymalpha}{\isacharcolon}\ type{\isacharcomma}\ A{\isacharparenleft}x\isactrlisub {\isasymalpha}{\isacharparenright}}, where type \isa{{\isasymalpha}} is fixed \emph{after} term \isa{x}, and the constraint
157.67 - \isa{x\ {\isacharcolon}{\isacharcolon}\ {\isasymalpha}} is an implicit consequence of the occurrence of
157.68 - \isa{x\isactrlisub {\isasymalpha}} in the subsequent proposition.
157.69 -
157.70 - This twist of dependencies is also accommodated by the reverse
157.71 - operation of exporting results from a context: a type variable
157.72 - \isa{{\isasymalpha}} is considered fixed as long as it occurs in some fixed
157.73 - term variable of the context. For example, exporting \isa{x{\isacharcolon}\ term{\isacharcomma}\ {\isasymalpha}{\isacharcolon}\ type\ {\isasymturnstile}\ x\isactrlisub {\isasymalpha}\ {\isacharequal}\ x\isactrlisub {\isasymalpha}} produces in the first step
157.74 - \isa{x{\isacharcolon}\ term\ {\isasymturnstile}\ x\isactrlisub {\isasymalpha}\ {\isacharequal}\ x\isactrlisub {\isasymalpha}} for fixed \isa{{\isasymalpha}},
157.75 - and only in the second step \isa{{\isasymturnstile}\ {\isacharquery}x\isactrlisub {\isacharquery}\isactrlisub {\isasymalpha}\ {\isacharequal}\ {\isacharquery}x\isactrlisub {\isacharquery}\isactrlisub {\isasymalpha}} for schematic \isa{{\isacharquery}x} and \isa{{\isacharquery}{\isasymalpha}}.
157.76 -
157.77 - \medskip The Isabelle/Isar proof context manages the gory details of
157.78 - term vs.\ type variables, with high-level principles for moving the
157.79 - frontier between fixed and schematic variables.
157.80 -
157.81 - The \isa{add{\isacharunderscore}fixes} operation explictly declares fixed
157.82 - variables; the \isa{declare{\isacharunderscore}term} operation absorbs a term into
157.83 - a context by fixing new type variables and adding syntactic
157.84 - constraints.
157.85 -
157.86 - The \isa{export} operation is able to perform the main work of
157.87 - generalizing term and type variables as sketched above, assuming
157.88 - that fixing variables and terms have been declared properly.
157.89 -
157.90 - There \isa{import} operation makes a generalized fact a genuine
157.91 - part of the context, by inventing fixed variables for the schematic
157.92 - ones. The effect can be reversed by using \isa{export} later,
157.93 - potentially with an extended context; the result is equivalent to
157.94 - the original modulo renaming of schematic variables.
157.95 -
157.96 - The \isa{focus} operation provides a variant of \isa{import}
157.97 - for nested propositions (with explicit quantification): \isa{{\isasymAnd}x\isactrlisub {\isadigit{1}}\ {\isasymdots}\ x\isactrlisub n{\isachardot}\ B{\isacharparenleft}x\isactrlisub {\isadigit{1}}{\isacharcomma}\ {\isasymdots}{\isacharcomma}\ x\isactrlisub n{\isacharparenright}} is
157.98 - decomposed by inventing fixed variables \isa{x\isactrlisub {\isadigit{1}}{\isacharcomma}\ {\isasymdots}{\isacharcomma}\ x\isactrlisub n} for the body.%
157.99 -\end{isamarkuptext}%
157.100 -\isamarkuptrue%
157.101 -%
157.102 -\isadelimmlref
157.103 -%
157.104 -\endisadelimmlref
157.105 -%
157.106 -\isatagmlref
157.107 -%
157.108 -\begin{isamarkuptext}%
157.109 -\begin{mldecls}
157.110 - \indexml{Variable.add\_fixes}\verb|Variable.add_fixes: |\isasep\isanewline%
157.111 -\verb| string list -> Proof.context -> string list * Proof.context| \\
157.112 - \indexml{Variable.variant\_fixes}\verb|Variable.variant_fixes: |\isasep\isanewline%
157.113 -\verb| string list -> Proof.context -> string list * Proof.context| \\
157.114 - \indexml{Variable.declare\_term}\verb|Variable.declare_term: term -> Proof.context -> Proof.context| \\
157.115 - \indexml{Variable.declare\_constraints}\verb|Variable.declare_constraints: term -> Proof.context -> Proof.context| \\
157.116 - \indexml{Variable.export}\verb|Variable.export: Proof.context -> Proof.context -> thm list -> thm list| \\
157.117 - \indexml{Variable.polymorphic}\verb|Variable.polymorphic: Proof.context -> term list -> term list| \\
157.118 - \indexml{Variable.import\_thms}\verb|Variable.import_thms: bool -> thm list -> Proof.context ->|\isasep\isanewline%
157.119 -\verb| ((ctyp list * cterm list) * thm list) * Proof.context| \\
157.120 - \indexml{Variable.focus}\verb|Variable.focus: cterm -> Proof.context -> (cterm list * cterm) * Proof.context| \\
157.121 - \end{mldecls}
157.122 -
157.123 - \begin{description}
157.124 -
157.125 - \item \verb|Variable.add_fixes|~\isa{xs\ ctxt} fixes term
157.126 - variables \isa{xs}, returning the resulting internal names. By
157.127 - default, the internal representation coincides with the external
157.128 - one, which also means that the given variables must not be fixed
157.129 - already. There is a different policy within a local proof body: the
157.130 - given names are just hints for newly invented Skolem variables.
157.131 -
157.132 - \item \verb|Variable.variant_fixes| is similar to \verb|Variable.add_fixes|, but always produces fresh variants of the given
157.133 - names.
157.134 -
157.135 - \item \verb|Variable.declare_term|~\isa{t\ ctxt} declares term
157.136 - \isa{t} to belong to the context. This automatically fixes new
157.137 - type variables, but not term variables. Syntactic constraints for
157.138 - type and term variables are declared uniformly, though.
157.139 -
157.140 - \item \verb|Variable.declare_constraints|~\isa{t\ ctxt} declares
157.141 - syntactic constraints from term \isa{t}, without making it part
157.142 - of the context yet.
157.143 -
157.144 - \item \verb|Variable.export|~\isa{inner\ outer\ thms} generalizes
157.145 - fixed type and term variables in \isa{thms} according to the
157.146 - difference of the \isa{inner} and \isa{outer} context,
157.147 - following the principles sketched above.
157.148 -
157.149 - \item \verb|Variable.polymorphic|~\isa{ctxt\ ts} generalizes type
157.150 - variables in \isa{ts} as far as possible, even those occurring
157.151 - in fixed term variables. The default policy of type-inference is to
157.152 - fix newly introduced type variables, which is essentially reversed
157.153 - with \verb|Variable.polymorphic|: here the given terms are detached
157.154 - from the context as far as possible.
157.155 -
157.156 - \item \verb|Variable.import_thms|~\isa{open\ thms\ ctxt} invents fixed
157.157 - type and term variables for the schematic ones occurring in \isa{thms}. The \isa{open} flag indicates whether the fixed names
157.158 - should be accessible to the user, otherwise newly introduced names
157.159 - are marked as ``internal'' (\secref{sec:names}).
157.160 -
157.161 - \item \verb|Variable.focus|~\isa{B} decomposes the outermost \isa{{\isasymAnd}} prefix of proposition \isa{B}.
157.162 -
157.163 - \end{description}%
157.164 -\end{isamarkuptext}%
157.165 -\isamarkuptrue%
157.166 -%
157.167 -\endisatagmlref
157.168 -{\isafoldmlref}%
157.169 -%
157.170 -\isadelimmlref
157.171 -%
157.172 -\endisadelimmlref
157.173 -%
157.174 -\isamarkupsection{Assumptions \label{sec:assumptions}%
157.175 -}
157.176 -\isamarkuptrue%
157.177 -%
157.178 -\begin{isamarkuptext}%
157.179 -An \emph{assumption} is a proposition that it is postulated in the
157.180 - current context. Local conclusions may use assumptions as
157.181 - additional facts, but this imposes implicit hypotheses that weaken
157.182 - the overall statement.
157.183 -
157.184 - Assumptions are restricted to fixed non-schematic statements, i.e.\
157.185 - all generality needs to be expressed by explicit quantifiers.
157.186 - Nevertheless, the result will be in HHF normal form with outermost
157.187 - quantifiers stripped. For example, by assuming \isa{{\isasymAnd}x\ {\isacharcolon}{\isacharcolon}\ {\isasymalpha}{\isachardot}\ P\ x} we get \isa{{\isasymAnd}x\ {\isacharcolon}{\isacharcolon}\ {\isasymalpha}{\isachardot}\ P\ x\ {\isasymturnstile}\ P\ {\isacharquery}x} for schematic \isa{{\isacharquery}x}
157.188 - of fixed type \isa{{\isasymalpha}}. Local derivations accumulate more and
157.189 - more explicit references to hypotheses: \isa{A\isactrlisub {\isadigit{1}}{\isacharcomma}\ {\isasymdots}{\isacharcomma}\ A\isactrlisub n\ {\isasymturnstile}\ B} where \isa{A\isactrlisub {\isadigit{1}}{\isacharcomma}\ {\isasymdots}{\isacharcomma}\ A\isactrlisub n} needs to
157.190 - be covered by the assumptions of the current context.
157.191 -
157.192 - \medskip The \isa{add{\isacharunderscore}assms} operation augments the context by
157.193 - local assumptions, which are parameterized by an arbitrary \isa{export} rule (see below).
157.194 -
157.195 - The \isa{export} operation moves facts from a (larger) inner
157.196 - context into a (smaller) outer context, by discharging the
157.197 - difference of the assumptions as specified by the associated export
157.198 - rules. Note that the discharged portion is determined by the
157.199 - difference contexts, not the facts being exported! There is a
157.200 - separate flag to indicate a goal context, where the result is meant
157.201 - to refine an enclosing sub-goal of a structured proof state (cf.\
157.202 - \secref{sec:isar-proof-state}).
157.203 -
157.204 - \medskip The most basic export rule discharges assumptions directly
157.205 - by means of the \isa{{\isasymLongrightarrow}} introduction rule:
157.206 - \[
157.207 - \infer[(\isa{{\isasymLongrightarrow}{\isacharunderscore}intro})]{\isa{{\isasymGamma}\ {\isacharbackslash}\ A\ {\isasymturnstile}\ A\ {\isasymLongrightarrow}\ B}}{\isa{{\isasymGamma}\ {\isasymturnstile}\ B}}
157.208 - \]
157.209 -
157.210 - The variant for goal refinements marks the newly introduced
157.211 - premises, which causes the canonical Isar goal refinement scheme to
157.212 - enforce unification with local premises within the goal:
157.213 - \[
157.214 - \infer[(\isa{{\isacharhash}{\isasymLongrightarrow}{\isacharunderscore}intro})]{\isa{{\isasymGamma}\ {\isacharbackslash}\ A\ {\isasymturnstile}\ {\isacharhash}A\ {\isasymLongrightarrow}\ B}}{\isa{{\isasymGamma}\ {\isasymturnstile}\ B}}
157.215 - \]
157.216 -
157.217 - \medskip Alternative versions of assumptions may perform arbitrary
157.218 - transformations on export, as long as the corresponding portion of
157.219 - hypotheses is removed from the given facts. For example, a local
157.220 - definition works by fixing \isa{x} and assuming \isa{x\ {\isasymequiv}\ t},
157.221 - with the following export rule to reverse the effect:
157.222 - \[
157.223 - \infer[(\isa{{\isasymequiv}{\isacharminus}expand})]{\isa{{\isasymGamma}\ {\isacharbackslash}\ x\ {\isasymequiv}\ t\ {\isasymturnstile}\ B\ t}}{\isa{{\isasymGamma}\ {\isasymturnstile}\ B\ x}}
157.224 - \]
157.225 - This works, because the assumption \isa{x\ {\isasymequiv}\ t} was introduced in
157.226 - a context with \isa{x} being fresh, so \isa{x} does not
157.227 - occur in \isa{{\isasymGamma}} here.%
157.228 -\end{isamarkuptext}%
157.229 -\isamarkuptrue%
157.230 -%
157.231 -\isadelimmlref
157.232 -%
157.233 -\endisadelimmlref
157.234 -%
157.235 -\isatagmlref
157.236 -%
157.237 -\begin{isamarkuptext}%
157.238 -\begin{mldecls}
157.239 - \indexmltype{Assumption.export}\verb|type Assumption.export| \\
157.240 - \indexml{Assumption.assume}\verb|Assumption.assume: cterm -> thm| \\
157.241 - \indexml{Assumption.add\_assms}\verb|Assumption.add_assms: Assumption.export ->|\isasep\isanewline%
157.242 -\verb| cterm list -> Proof.context -> thm list * Proof.context| \\
157.243 - \indexml{Assumption.add\_assumes}\verb|Assumption.add_assumes: |\isasep\isanewline%
157.244 -\verb| cterm list -> Proof.context -> thm list * Proof.context| \\
157.245 - \indexml{Assumption.export}\verb|Assumption.export: bool -> Proof.context -> Proof.context -> thm -> thm| \\
157.246 - \end{mldecls}
157.247 -
157.248 - \begin{description}
157.249 -
157.250 - \item \verb|Assumption.export| represents arbitrary export
157.251 - rules, which is any function of type \verb|bool -> cterm list -> thm -> thm|,
157.252 - where the \verb|bool| indicates goal mode, and the \verb|cterm list| the collection of assumptions to be discharged
157.253 - simultaneously.
157.254 -
157.255 - \item \verb|Assumption.assume|~\isa{A} turns proposition \isa{A} into a raw assumption \isa{A\ {\isasymturnstile}\ A{\isacharprime}}, where the conclusion
157.256 - \isa{A{\isacharprime}} is in HHF normal form.
157.257 -
157.258 - \item \verb|Assumption.add_assms|~\isa{r\ As} augments the context
157.259 - by assumptions \isa{As} with export rule \isa{r}. The
157.260 - resulting facts are hypothetical theorems as produced by the raw
157.261 - \verb|Assumption.assume|.
157.262 -
157.263 - \item \verb|Assumption.add_assumes|~\isa{As} is a special case of
157.264 - \verb|Assumption.add_assms| where the export rule performs \isa{{\isasymLongrightarrow}{\isacharunderscore}intro} or \isa{{\isacharhash}{\isasymLongrightarrow}{\isacharunderscore}intro}, depending on goal mode.
157.265 -
157.266 - \item \verb|Assumption.export|~\isa{is{\isacharunderscore}goal\ inner\ outer\ thm}
157.267 - exports result \isa{thm} from the the \isa{inner} context
157.268 - back into the \isa{outer} one; \isa{is{\isacharunderscore}goal\ {\isacharequal}\ true} means
157.269 - this is a goal context. The result is in HHF normal form. Note
157.270 - that \verb|ProofContext.export| combines \verb|Variable.export|
157.271 - and \verb|Assumption.export| in the canonical way.
157.272 -
157.273 - \end{description}%
157.274 -\end{isamarkuptext}%
157.275 -\isamarkuptrue%
157.276 -%
157.277 -\endisatagmlref
157.278 -{\isafoldmlref}%
157.279 -%
157.280 -\isadelimmlref
157.281 -%
157.282 -\endisadelimmlref
157.283 -%
157.284 -\isamarkupsection{Results \label{sec:results}%
157.285 -}
157.286 -\isamarkuptrue%
157.287 -%
157.288 -\begin{isamarkuptext}%
157.289 -Local results are established by monotonic reasoning from facts
157.290 - within a context. This allows common combinations of theorems,
157.291 - e.g.\ via \isa{{\isasymAnd}{\isacharslash}{\isasymLongrightarrow}} elimination, resolution rules, or equational
157.292 - reasoning, see \secref{sec:thms}. Unaccounted context manipulations
157.293 - should be avoided, notably raw \isa{{\isasymAnd}{\isacharslash}{\isasymLongrightarrow}} introduction or ad-hoc
157.294 - references to free variables or assumptions not present in the proof
157.295 - context.
157.296 -
157.297 - \medskip The \isa{SUBPROOF} combinator allows to structure a
157.298 - tactical proof recursively by decomposing a selected sub-goal:
157.299 - \isa{{\isacharparenleft}{\isasymAnd}x{\isachardot}\ A{\isacharparenleft}x{\isacharparenright}\ {\isasymLongrightarrow}\ B{\isacharparenleft}x{\isacharparenright}{\isacharparenright}\ {\isasymLongrightarrow}\ {\isasymdots}} is turned into \isa{B{\isacharparenleft}x{\isacharparenright}\ {\isasymLongrightarrow}\ {\isasymdots}}
157.300 - after fixing \isa{x} and assuming \isa{A{\isacharparenleft}x{\isacharparenright}}. This means
157.301 - the tactic needs to solve the conclusion, but may use the premise as
157.302 - a local fact, for locally fixed variables.
157.303 -
157.304 - The \isa{prove} operation provides an interface for structured
157.305 - backwards reasoning under program control, with some explicit sanity
157.306 - checks of the result. The goal context can be augmented by
157.307 - additional fixed variables (cf.\ \secref{sec:variables}) and
157.308 - assumptions (cf.\ \secref{sec:assumptions}), which will be available
157.309 - as local facts during the proof and discharged into implications in
157.310 - the result. Type and term variables are generalized as usual,
157.311 - according to the context.
157.312 -
157.313 - The \isa{obtain} operation produces results by eliminating
157.314 - existing facts by means of a given tactic. This acts like a dual
157.315 - conclusion: the proof demonstrates that the context may be augmented
157.316 - by certain fixed variables and assumptions. See also
157.317 - \cite{isabelle-isar-ref} for the user-level \isa{{\isasymOBTAIN}} and
157.318 - \isa{{\isasymGUESS}} elements. Final results, which may not refer to
157.319 - the parameters in the conclusion, need to exported explicitly into
157.320 - the original context.%
157.321 -\end{isamarkuptext}%
157.322 -\isamarkuptrue%
157.323 -%
157.324 -\isadelimmlref
157.325 -%
157.326 -\endisadelimmlref
157.327 -%
157.328 -\isatagmlref
157.329 -%
157.330 -\begin{isamarkuptext}%
157.331 -\begin{mldecls}
157.332 - \indexml{SUBPROOF}\verb|SUBPROOF: ({context: Proof.context, schematics: ctyp list * cterm list,|\isasep\isanewline%
157.333 -\verb| params: cterm list, asms: cterm list, concl: cterm,|\isasep\isanewline%
157.334 -\verb| prems: thm list} -> tactic) -> Proof.context -> int -> tactic| \\
157.335 - \end{mldecls}
157.336 - \begin{mldecls}
157.337 - \indexml{Goal.prove}\verb|Goal.prove: Proof.context -> string list -> term list -> term ->|\isasep\isanewline%
157.338 -\verb| ({prems: thm list, context: Proof.context} -> tactic) -> thm| \\
157.339 - \indexml{Goal.prove\_multi}\verb|Goal.prove_multi: Proof.context -> string list -> term list -> term list ->|\isasep\isanewline%
157.340 -\verb| ({prems: thm list, context: Proof.context} -> tactic) -> thm list| \\
157.341 - \end{mldecls}
157.342 - \begin{mldecls}
157.343 - \indexml{Obtain.result}\verb|Obtain.result: (Proof.context -> tactic) ->|\isasep\isanewline%
157.344 -\verb| thm list -> Proof.context -> (cterm list * thm list) * Proof.context| \\
157.345 - \end{mldecls}
157.346 -
157.347 - \begin{description}
157.348 -
157.349 - \item \verb|SUBPROOF|~\isa{tac} decomposes the structure of a
157.350 - particular sub-goal, producing an extended context and a reduced
157.351 - goal, which needs to be solved by the given tactic. All schematic
157.352 - parameters of the goal are imported into the context as fixed ones,
157.353 - which may not be instantiated in the sub-proof.
157.354 -
157.355 - \item \verb|Goal.prove|~\isa{ctxt\ xs\ As\ C\ tac} states goal \isa{C} in the context augmented by fixed variables \isa{xs} and
157.356 - assumptions \isa{As}, and applies tactic \isa{tac} to solve
157.357 - it. The latter may depend on the local assumptions being presented
157.358 - as facts. The result is in HHF normal form.
157.359 -
157.360 - \item \verb|Goal.prove_multi| is simular to \verb|Goal.prove|, but
157.361 - states several conclusions simultaneously. The goal is encoded by
157.362 - means of Pure conjunction; \verb|Goal.conjunction_tac| will turn this
157.363 - into a collection of individual subgoals.
157.364 -
157.365 - \item \verb|Obtain.result|~\isa{tac\ thms\ ctxt} eliminates the
157.366 - given facts using a tactic, which results in additional fixed
157.367 - variables and assumptions in the context. Final results need to be
157.368 - exported explicitly.
157.369 -
157.370 - \end{description}%
157.371 -\end{isamarkuptext}%
157.372 -\isamarkuptrue%
157.373 -%
157.374 -\endisatagmlref
157.375 -{\isafoldmlref}%
157.376 -%
157.377 -\isadelimmlref
157.378 -%
157.379 -\endisadelimmlref
157.380 -%
157.381 -\isadelimtheory
157.382 -%
157.383 -\endisadelimtheory
157.384 -%
157.385 -\isatagtheory
157.386 -\isacommand{end}\isamarkupfalse%
157.387 -%
157.388 -\endisatagtheory
157.389 -{\isafoldtheory}%
157.390 -%
157.391 -\isadelimtheory
157.392 -%
157.393 -\endisadelimtheory
157.394 -\isanewline
157.395 -\end{isabellebody}%
157.396 -%%% Local Variables:
157.397 -%%% mode: latex
157.398 -%%% TeX-master: "root"
157.399 -%%% End:
158.1 --- a/doc-src/IsarImplementation/Thy/document/tactic.tex Wed Mar 04 11:05:02 2009 +0100
158.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
158.3 @@ -1,512 +0,0 @@
158.4 -%
158.5 -\begin{isabellebody}%
158.6 -\def\isabellecontext{tactic}%
158.7 -%
158.8 -\isadelimtheory
158.9 -\isanewline
158.10 -\isanewline
158.11 -\isanewline
158.12 -%
158.13 -\endisadelimtheory
158.14 -%
158.15 -\isatagtheory
158.16 -\isacommand{theory}\isamarkupfalse%
158.17 -\ tactic\ \isakeyword{imports}\ base\ \isakeyword{begin}%
158.18 -\endisatagtheory
158.19 -{\isafoldtheory}%
158.20 -%
158.21 -\isadelimtheory
158.22 -%
158.23 -\endisadelimtheory
158.24 -%
158.25 -\isamarkupchapter{Tactical reasoning%
158.26 -}
158.27 -\isamarkuptrue%
158.28 -%
158.29 -\begin{isamarkuptext}%
158.30 -Tactical reasoning works by refining the initial claim in a
158.31 - backwards fashion, until a solved form is reached. A \isa{goal}
158.32 - consists of several subgoals that need to be solved in order to
158.33 - achieve the main statement; zero subgoals means that the proof may
158.34 - be finished. A \isa{tactic} is a refinement operation that maps
158.35 - a goal to a lazy sequence of potential successors. A \isa{tactical} is a combinator for composing tactics.%
158.36 -\end{isamarkuptext}%
158.37 -\isamarkuptrue%
158.38 -%
158.39 -\isamarkupsection{Goals \label{sec:tactical-goals}%
158.40 -}
158.41 -\isamarkuptrue%
158.42 -%
158.43 -\begin{isamarkuptext}%
158.44 -Isabelle/Pure represents a goal\glossary{Tactical goal}{A theorem of
158.45 - \seeglossary{Horn Clause} form stating that a number of subgoals
158.46 - imply the main conclusion, which is marked as a protected
158.47 - proposition.} as a theorem stating that the subgoals imply the main
158.48 - goal: \isa{A\isactrlsub {\isadigit{1}}\ {\isasymLongrightarrow}\ {\isasymdots}\ {\isasymLongrightarrow}\ A\isactrlsub n\ {\isasymLongrightarrow}\ C}. The outermost goal
158.49 - structure is that of a Horn Clause\glossary{Horn Clause}{An iterated
158.50 - implication \isa{A\isactrlsub {\isadigit{1}}\ {\isasymLongrightarrow}\ {\isasymdots}\ {\isasymLongrightarrow}\ A\isactrlsub n\ {\isasymLongrightarrow}\ C}, without any
158.51 - outermost quantifiers. Strictly speaking, propositions \isa{A\isactrlsub i} need to be atomic in Horn Clauses, but Isabelle admits
158.52 - arbitrary substructure here (nested \isa{{\isasymLongrightarrow}} and \isa{{\isasymAnd}}
158.53 - connectives).}: i.e.\ an iterated implication without any
158.54 - quantifiers\footnote{Recall that outermost \isa{{\isasymAnd}x{\isachardot}\ {\isasymphi}{\isacharbrackleft}x{\isacharbrackright}} is
158.55 - always represented via schematic variables in the body: \isa{{\isasymphi}{\isacharbrackleft}{\isacharquery}x{\isacharbrackright}}. These variables may get instantiated during the course of
158.56 - reasoning.}. For \isa{n\ {\isacharequal}\ {\isadigit{0}}} a goal is called ``solved''.
158.57 -
158.58 - The structure of each subgoal \isa{A\isactrlsub i} is that of a general
158.59 - Hereditary Harrop Formula \isa{{\isasymAnd}x\isactrlsub {\isadigit{1}}\ {\isasymdots}\ {\isasymAnd}x\isactrlsub k{\isachardot}\ H\isactrlsub {\isadigit{1}}\ {\isasymLongrightarrow}\ {\isasymdots}\ {\isasymLongrightarrow}\ H\isactrlsub m\ {\isasymLongrightarrow}\ B} in
158.60 - normal form. Here \isa{x\isactrlsub {\isadigit{1}}{\isacharcomma}\ {\isasymdots}{\isacharcomma}\ x\isactrlsub k} are goal parameters, i.e.\
158.61 - arbitrary-but-fixed entities of certain types, and \isa{H\isactrlsub {\isadigit{1}}{\isacharcomma}\ {\isasymdots}{\isacharcomma}\ H\isactrlsub m} are goal hypotheses, i.e.\ facts that may be assumed locally.
158.62 - Together, this forms the goal context of the conclusion \isa{B} to
158.63 - be established. The goal hypotheses may be again arbitrary
158.64 - Hereditary Harrop Formulas, although the level of nesting rarely
158.65 - exceeds 1--2 in practice.
158.66 -
158.67 - The main conclusion \isa{C} is internally marked as a protected
158.68 - proposition\glossary{Protected proposition}{An arbitrarily
158.69 - structured proposition \isa{C} which is forced to appear as
158.70 - atomic by wrapping it into a propositional identity operator;
158.71 - notation \isa{{\isacharhash}C}. Protecting a proposition prevents basic
158.72 - inferences from entering into that structure for the time being.},
158.73 - which is represented explicitly by the notation \isa{{\isacharhash}C}. This
158.74 - ensures that the decomposition into subgoals and main conclusion is
158.75 - well-defined for arbitrarily structured claims.
158.76 -
158.77 - \medskip Basic goal management is performed via the following
158.78 - Isabelle/Pure rules:
158.79 -
158.80 - \[
158.81 - \infer[\isa{{\isacharparenleft}init{\isacharparenright}}]{\isa{C\ {\isasymLongrightarrow}\ {\isacharhash}C}}{} \qquad
158.82 - \infer[\isa{{\isacharparenleft}finish{\isacharparenright}}]{\isa{C}}{\isa{{\isacharhash}C}}
158.83 - \]
158.84 -
158.85 - \medskip The following low-level variants admit general reasoning
158.86 - with protected propositions:
158.87 -
158.88 - \[
158.89 - \infer[\isa{{\isacharparenleft}protect{\isacharparenright}}]{\isa{{\isacharhash}C}}{\isa{C}} \qquad
158.90 - \infer[\isa{{\isacharparenleft}conclude{\isacharparenright}}]{\isa{A\isactrlsub {\isadigit{1}}\ {\isasymLongrightarrow}\ {\isasymdots}\ {\isasymLongrightarrow}\ A\isactrlsub n\ {\isasymLongrightarrow}\ C}}{\isa{A\isactrlsub {\isadigit{1}}\ {\isasymLongrightarrow}\ {\isasymdots}\ {\isasymLongrightarrow}\ A\isactrlsub n\ {\isasymLongrightarrow}\ {\isacharhash}C}}
158.91 - \]%
158.92 -\end{isamarkuptext}%
158.93 -\isamarkuptrue%
158.94 -%
158.95 -\isadelimmlref
158.96 -%
158.97 -\endisadelimmlref
158.98 -%
158.99 -\isatagmlref
158.100 -%
158.101 -\begin{isamarkuptext}%
158.102 -\begin{mldecls}
158.103 - \indexml{Goal.init}\verb|Goal.init: cterm -> thm| \\
158.104 - \indexml{Goal.finish}\verb|Goal.finish: thm -> thm| \\
158.105 - \indexml{Goal.protect}\verb|Goal.protect: thm -> thm| \\
158.106 - \indexml{Goal.conclude}\verb|Goal.conclude: thm -> thm| \\
158.107 - \end{mldecls}
158.108 -
158.109 - \begin{description}
158.110 -
158.111 - \item \verb|Goal.init|~\isa{C} initializes a tactical goal from
158.112 - the well-formed proposition \isa{C}.
158.113 -
158.114 - \item \verb|Goal.finish|~\isa{thm} checks whether theorem
158.115 - \isa{thm} is a solved goal (no subgoals), and concludes the
158.116 - result by removing the goal protection.
158.117 -
158.118 - \item \verb|Goal.protect|~\isa{thm} protects the full statement
158.119 - of theorem \isa{thm}.
158.120 -
158.121 - \item \verb|Goal.conclude|~\isa{thm} removes the goal
158.122 - protection, even if there are pending subgoals.
158.123 -
158.124 - \end{description}%
158.125 -\end{isamarkuptext}%
158.126 -\isamarkuptrue%
158.127 -%
158.128 -\endisatagmlref
158.129 -{\isafoldmlref}%
158.130 -%
158.131 -\isadelimmlref
158.132 -%
158.133 -\endisadelimmlref
158.134 -%
158.135 -\isamarkupsection{Tactics%
158.136 -}
158.137 -\isamarkuptrue%
158.138 -%
158.139 -\begin{isamarkuptext}%
158.140 -A \isa{tactic} is a function \isa{goal\ {\isasymrightarrow}\ goal\isactrlsup {\isacharasterisk}\isactrlsup {\isacharasterisk}} that
158.141 - maps a given goal state (represented as a theorem, cf.\
158.142 - \secref{sec:tactical-goals}) to a lazy sequence of potential
158.143 - successor states. The underlying sequence implementation is lazy
158.144 - both in head and tail, and is purely functional in \emph{not}
158.145 - supporting memoing.\footnote{The lack of memoing and the strict
158.146 - nature of SML requires some care when working with low-level
158.147 - sequence operations, to avoid duplicate or premature evaluation of
158.148 - results.}
158.149 -
158.150 - An \emph{empty result sequence} means that the tactic has failed: in
158.151 - a compound tactic expressions other tactics might be tried instead,
158.152 - or the whole refinement step might fail outright, producing a
158.153 - toplevel error message. When implementing tactics from scratch, one
158.154 - should take care to observe the basic protocol of mapping regular
158.155 - error conditions to an empty result; only serious faults should
158.156 - emerge as exceptions.
158.157 -
158.158 - By enumerating \emph{multiple results}, a tactic can easily express
158.159 - the potential outcome of an internal search process. There are also
158.160 - combinators for building proof tools that involve search
158.161 - systematically, see also \secref{sec:tacticals}.
158.162 -
158.163 - \medskip As explained in \secref{sec:tactical-goals}, a goal state
158.164 - essentially consists of a list of subgoals that imply the main goal
158.165 - (conclusion). Tactics may operate on all subgoals or on a
158.166 - particularly specified subgoal, but must not change the main
158.167 - conclusion (apart from instantiating schematic goal variables).
158.168 -
158.169 - Tactics with explicit \emph{subgoal addressing} are of the form
158.170 - \isa{int\ {\isasymrightarrow}\ tactic} and may be applied to a particular subgoal
158.171 - (counting from 1). If the subgoal number is out of range, the
158.172 - tactic should fail with an empty result sequence, but must not raise
158.173 - an exception!
158.174 -
158.175 - Operating on a particular subgoal means to replace it by an interval
158.176 - of zero or more subgoals in the same place; other subgoals must not
158.177 - be affected, apart from instantiating schematic variables ranging
158.178 - over the whole goal state.
158.179 -
158.180 - A common pattern of composing tactics with subgoal addressing is to
158.181 - try the first one, and then the second one only if the subgoal has
158.182 - not been solved yet. Special care is required here to avoid bumping
158.183 - into unrelated subgoals that happen to come after the original
158.184 - subgoal. Assuming that there is only a single initial subgoal is a
158.185 - very common error when implementing tactics!
158.186 -
158.187 - Tactics with internal subgoal addressing should expose the subgoal
158.188 - index as \isa{int} argument in full generality; a hardwired
158.189 - subgoal 1 inappropriate.
158.190 -
158.191 - \medskip The main well-formedness conditions for proper tactics are
158.192 - summarized as follows.
158.193 -
158.194 - \begin{itemize}
158.195 -
158.196 - \item General tactic failure is indicated by an empty result, only
158.197 - serious faults may produce an exception.
158.198 -
158.199 - \item The main conclusion must not be changed, apart from
158.200 - instantiating schematic variables.
158.201 -
158.202 - \item A tactic operates either uniformly on all subgoals, or
158.203 - specifically on a selected subgoal (without bumping into unrelated
158.204 - subgoals).
158.205 -
158.206 - \item Range errors in subgoal addressing produce an empty result.
158.207 -
158.208 - \end{itemize}
158.209 -
158.210 - Some of these conditions are checked by higher-level goal
158.211 - infrastructure (\secref{sec:results}); others are not checked
158.212 - explicitly, and violating them merely results in ill-behaved tactics
158.213 - experienced by the user (e.g.\ tactics that insist in being
158.214 - applicable only to singleton goals, or disallow composition with
158.215 - basic tacticals).%
158.216 -\end{isamarkuptext}%
158.217 -\isamarkuptrue%
158.218 -%
158.219 -\isadelimmlref
158.220 -%
158.221 -\endisadelimmlref
158.222 -%
158.223 -\isatagmlref
158.224 -%
158.225 -\begin{isamarkuptext}%
158.226 -\begin{mldecls}
158.227 - \indexmltype{tactic}\verb|type tactic = thm -> thm Seq.seq| \\
158.228 - \indexml{no\_tac}\verb|no_tac: tactic| \\
158.229 - \indexml{all\_tac}\verb|all_tac: tactic| \\
158.230 - \indexml{print\_tac}\verb|print_tac: string -> tactic| \\[1ex]
158.231 - \indexml{PRIMITIVE}\verb|PRIMITIVE: (thm -> thm) -> tactic| \\[1ex]
158.232 - \indexml{SUBGOAL}\verb|SUBGOAL: (term * int -> tactic) -> int -> tactic| \\
158.233 - \indexml{CSUBGOAL}\verb|CSUBGOAL: (cterm * int -> tactic) -> int -> tactic| \\
158.234 - \end{mldecls}
158.235 -
158.236 - \begin{description}
158.237 -
158.238 - \item \verb|tactic| represents tactics. The well-formedness
158.239 - conditions described above need to be observed. See also \hyperlink{file.~~/src/Pure/General/seq.ML}{\mbox{\isa{\isatt{{\isachartilde}{\isachartilde}{\isacharslash}src{\isacharslash}Pure{\isacharslash}General{\isacharslash}seq{\isachardot}ML}}}} for the underlying implementation of
158.240 - lazy sequences.
158.241 -
158.242 - \item \verb|int -> tactic| represents tactics with explicit
158.243 - subgoal addressing, with well-formedness conditions as described
158.244 - above.
158.245 -
158.246 - \item \verb|no_tac| is a tactic that always fails, returning the
158.247 - empty sequence.
158.248 -
158.249 - \item \verb|all_tac| is a tactic that always succeeds, returning a
158.250 - singleton sequence with unchanged goal state.
158.251 -
158.252 - \item \verb|print_tac|~\isa{message} is like \verb|all_tac|, but
158.253 - prints a message together with the goal state on the tracing
158.254 - channel.
158.255 -
158.256 - \item \verb|PRIMITIVE|~\isa{rule} turns a primitive inference rule
158.257 - into a tactic with unique result. Exception \verb|THM| is considered
158.258 - a regular tactic failure and produces an empty result; other
158.259 - exceptions are passed through.
158.260 -
158.261 - \item \verb|SUBGOAL|~\isa{{\isacharparenleft}fn\ {\isacharparenleft}subgoal{\isacharcomma}\ i{\isacharparenright}\ {\isacharequal}{\isachargreater}\ tactic{\isacharparenright}} is the
158.262 - most basic form to produce a tactic with subgoal addressing. The
158.263 - given abstraction over the subgoal term and subgoal number allows to
158.264 - peek at the relevant information of the full goal state. The
158.265 - subgoal range is checked as required above.
158.266 -
158.267 - \item \verb|CSUBGOAL| is similar to \verb|SUBGOAL|, but passes the
158.268 - subgoal as \verb|cterm| instead of raw \verb|term|. This
158.269 - avoids expensive re-certification in situations where the subgoal is
158.270 - used directly for primitive inferences.
158.271 -
158.272 - \end{description}%
158.273 -\end{isamarkuptext}%
158.274 -\isamarkuptrue%
158.275 -%
158.276 -\endisatagmlref
158.277 -{\isafoldmlref}%
158.278 -%
158.279 -\isadelimmlref
158.280 -%
158.281 -\endisadelimmlref
158.282 -%
158.283 -\isamarkupsubsection{Resolution and assumption tactics \label{sec:resolve-assume-tac}%
158.284 -}
158.285 -\isamarkuptrue%
158.286 -%
158.287 -\begin{isamarkuptext}%
158.288 -\emph{Resolution} is the most basic mechanism for refining a
158.289 - subgoal using a theorem as object-level rule.
158.290 - \emph{Elim-resolution} is particularly suited for elimination rules:
158.291 - it resolves with a rule, proves its first premise by assumption, and
158.292 - finally deletes that assumption from any new subgoals.
158.293 - \emph{Destruct-resolution} is like elim-resolution, but the given
158.294 - destruction rules are first turned into canonical elimination
158.295 - format. \emph{Forward-resolution} is like destruct-resolution, but
158.296 - without deleting the selected assumption. The \isa{r{\isacharslash}e{\isacharslash}d{\isacharslash}f}
158.297 - naming convention is maintained for several different kinds of
158.298 - resolution rules and tactics.
158.299 -
158.300 - Assumption tactics close a subgoal by unifying some of its premises
158.301 - against its conclusion.
158.302 -
158.303 - \medskip All the tactics in this section operate on a subgoal
158.304 - designated by a positive integer. Other subgoals might be affected
158.305 - indirectly, due to instantiation of schematic variables.
158.306 -
158.307 - There are various sources of non-determinism, the tactic result
158.308 - sequence enumerates all possibilities of the following choices (if
158.309 - applicable):
158.310 -
158.311 - \begin{enumerate}
158.312 -
158.313 - \item selecting one of the rules given as argument to the tactic;
158.314 -
158.315 - \item selecting a subgoal premise to eliminate, unifying it against
158.316 - the first premise of the rule;
158.317 -
158.318 - \item unifying the conclusion of the subgoal to the conclusion of
158.319 - the rule.
158.320 -
158.321 - \end{enumerate}
158.322 -
158.323 - Recall that higher-order unification may produce multiple results
158.324 - that are enumerated here.%
158.325 -\end{isamarkuptext}%
158.326 -\isamarkuptrue%
158.327 -%
158.328 -\isadelimmlref
158.329 -%
158.330 -\endisadelimmlref
158.331 -%
158.332 -\isatagmlref
158.333 -%
158.334 -\begin{isamarkuptext}%
158.335 -\begin{mldecls}
158.336 - \indexml{resolve\_tac}\verb|resolve_tac: thm list -> int -> tactic| \\
158.337 - \indexml{eresolve\_tac}\verb|eresolve_tac: thm list -> int -> tactic| \\
158.338 - \indexml{dresolve\_tac}\verb|dresolve_tac: thm list -> int -> tactic| \\
158.339 - \indexml{forward\_tac}\verb|forward_tac: thm list -> int -> tactic| \\[1ex]
158.340 - \indexml{assume\_tac}\verb|assume_tac: int -> tactic| \\
158.341 - \indexml{eq\_assume\_tac}\verb|eq_assume_tac: int -> tactic| \\[1ex]
158.342 - \indexml{match\_tac}\verb|match_tac: thm list -> int -> tactic| \\
158.343 - \indexml{ematch\_tac}\verb|ematch_tac: thm list -> int -> tactic| \\
158.344 - \indexml{dmatch\_tac}\verb|dmatch_tac: thm list -> int -> tactic| \\
158.345 - \end{mldecls}
158.346 -
158.347 - \begin{description}
158.348 -
158.349 - \item \verb|resolve_tac|~\isa{thms\ i} refines the goal state
158.350 - using the given theorems, which should normally be introduction
158.351 - rules. The tactic resolves a rule's conclusion with subgoal \isa{i}, replacing it by the corresponding versions of the rule's
158.352 - premises.
158.353 -
158.354 - \item \verb|eresolve_tac|~\isa{thms\ i} performs elim-resolution
158.355 - with the given theorems, which should normally be elimination rules.
158.356 -
158.357 - \item \verb|dresolve_tac|~\isa{thms\ i} performs
158.358 - destruct-resolution with the given theorems, which should normally
158.359 - be destruction rules. This replaces an assumption by the result of
158.360 - applying one of the rules.
158.361 -
158.362 - \item \verb|forward_tac| is like \verb|dresolve_tac| except that the
158.363 - selected assumption is not deleted. It applies a rule to an
158.364 - assumption, adding the result as a new assumption.
158.365 -
158.366 - \item \verb|assume_tac|~\isa{i} attempts to solve subgoal \isa{i}
158.367 - by assumption (modulo higher-order unification).
158.368 -
158.369 - \item \verb|eq_assume_tac| is similar to \verb|assume_tac|, but checks
158.370 - only for immediate \isa{{\isasymalpha}}-convertibility instead of using
158.371 - unification. It succeeds (with a unique next state) if one of the
158.372 - assumptions is equal to the subgoal's conclusion. Since it does not
158.373 - instantiate variables, it cannot make other subgoals unprovable.
158.374 -
158.375 - \item \verb|match_tac|, \verb|ematch_tac|, and \verb|dmatch_tac| are
158.376 - similar to \verb|resolve_tac|, \verb|eresolve_tac|, and \verb|dresolve_tac|, respectively, but do not instantiate schematic
158.377 - variables in the goal state.
158.378 -
158.379 - Flexible subgoals are not updated at will, but are left alone.
158.380 - Strictly speaking, matching means to treat the unknowns in the goal
158.381 - state as constants; these tactics merely discard unifiers that would
158.382 - update the goal state.
158.383 -
158.384 - \end{description}%
158.385 -\end{isamarkuptext}%
158.386 -\isamarkuptrue%
158.387 -%
158.388 -\endisatagmlref
158.389 -{\isafoldmlref}%
158.390 -%
158.391 -\isadelimmlref
158.392 -%
158.393 -\endisadelimmlref
158.394 -%
158.395 -\isamarkupsubsection{Explicit instantiation within a subgoal context%
158.396 -}
158.397 -\isamarkuptrue%
158.398 -%
158.399 -\begin{isamarkuptext}%
158.400 -The main resolution tactics (\secref{sec:resolve-assume-tac})
158.401 - use higher-order unification, which works well in many practical
158.402 - situations despite its daunting theoretical properties.
158.403 - Nonetheless, there are important problem classes where unguided
158.404 - higher-order unification is not so useful. This typically involves
158.405 - rules like universal elimination, existential introduction, or
158.406 - equational substitution. Here the unification problem involves
158.407 - fully flexible \isa{{\isacharquery}P\ {\isacharquery}x} schemes, which are hard to manage
158.408 - without further hints.
158.409 -
158.410 - By providing a (small) rigid term for \isa{{\isacharquery}x} explicitly, the
158.411 - remaining unification problem is to assign a (large) term to \isa{{\isacharquery}P}, according to the shape of the given subgoal. This is
158.412 - sufficiently well-behaved in most practical situations.
158.413 -
158.414 - \medskip Isabelle provides separate versions of the standard \isa{r{\isacharslash}e{\isacharslash}d{\isacharslash}f} resolution tactics that allow to provide explicit
158.415 - instantiations of unknowns of the given rule, wrt.\ terms that refer
158.416 - to the implicit context of the selected subgoal.
158.417 -
158.418 - An instantiation consists of a list of pairs of the form \isa{{\isacharparenleft}{\isacharquery}x{\isacharcomma}\ t{\isacharparenright}}, where \isa{{\isacharquery}x} is a schematic variable occurring in
158.419 - the given rule, and \isa{t} is a term from the current proof
158.420 - context, augmented by the local goal parameters of the selected
158.421 - subgoal; cf.\ the \isa{focus} operation described in
158.422 - \secref{sec:variables}.
158.423 -
158.424 - Entering the syntactic context of a subgoal is a brittle operation,
158.425 - because its exact form is somewhat accidental, and the choice of
158.426 - bound variable names depends on the presence of other local and
158.427 - global names. Explicit renaming of subgoal parameters prior to
158.428 - explicit instantiation might help to achieve a bit more robustness.
158.429 -
158.430 - Type instantiations may be given as well, via pairs like \isa{{\isacharparenleft}{\isacharquery}{\isacharprime}a{\isacharcomma}\ {\isasymtau}{\isacharparenright}}. Type instantiations are distinguished from term
158.431 - instantiations by the syntactic form of the schematic variable.
158.432 - Types are instantiated before terms are. Since term instantiation
158.433 - already performs type-inference as expected, explicit type
158.434 - instantiations are seldom necessary.%
158.435 -\end{isamarkuptext}%
158.436 -\isamarkuptrue%
158.437 -%
158.438 -\isadelimmlref
158.439 -%
158.440 -\endisadelimmlref
158.441 -%
158.442 -\isatagmlref
158.443 -%
158.444 -\begin{isamarkuptext}%
158.445 -\begin{mldecls}
158.446 - \indexml{res\_inst\_tac}\verb|res_inst_tac: Proof.context -> (indexname * string) list -> thm -> int -> tactic| \\
158.447 - \indexml{eres\_inst\_tac}\verb|eres_inst_tac: Proof.context -> (indexname * string) list -> thm -> int -> tactic| \\
158.448 - \indexml{dres\_inst\_tac}\verb|dres_inst_tac: Proof.context -> (indexname * string) list -> thm -> int -> tactic| \\
158.449 - \indexml{forw\_inst\_tac}\verb|forw_inst_tac: Proof.context -> (indexname * string) list -> thm -> int -> tactic| \\[1ex]
158.450 - \indexml{rename\_tac}\verb|rename_tac: string list -> int -> tactic| \\
158.451 - \end{mldecls}
158.452 -
158.453 - \begin{description}
158.454 -
158.455 - \item \verb|res_inst_tac|~\isa{ctxt\ insts\ thm\ i} instantiates the
158.456 - rule \isa{thm} with the instantiations \isa{insts}, as described
158.457 - above, and then performs resolution on subgoal \isa{i}.
158.458 -
158.459 - \item \verb|eres_inst_tac| is like \verb|res_inst_tac|, but performs
158.460 - elim-resolution.
158.461 -
158.462 - \item \verb|dres_inst_tac| is like \verb|res_inst_tac|, but performs
158.463 - destruct-resolution.
158.464 -
158.465 - \item \verb|forw_inst_tac| is like \verb|dres_inst_tac| except that
158.466 - the selected assumption is not deleted.
158.467 -
158.468 - \item \verb|rename_tac|~\isa{names\ i} renames the innermost
158.469 - parameters of subgoal \isa{i} according to the provided \isa{names} (which need to be distinct indentifiers).
158.470 -
158.471 - \end{description}%
158.472 -\end{isamarkuptext}%
158.473 -\isamarkuptrue%
158.474 -%
158.475 -\endisatagmlref
158.476 -{\isafoldmlref}%
158.477 -%
158.478 -\isadelimmlref
158.479 -%
158.480 -\endisadelimmlref
158.481 -%
158.482 -\isamarkupsection{Tacticals \label{sec:tacticals}%
158.483 -}
158.484 -\isamarkuptrue%
158.485 -%
158.486 -\begin{isamarkuptext}%
158.487 -FIXME
158.488 -
158.489 -\glossary{Tactical}{A functional combinator for building up complex
158.490 -tactics from simpler ones. Typical tactical perform sequential
158.491 -composition, disjunction (choice), iteration, or goal addressing.
158.492 -Various search strategies may be expressed via tacticals.}%
158.493 -\end{isamarkuptext}%
158.494 -\isamarkuptrue%
158.495 -%
158.496 -\isadelimtheory
158.497 -%
158.498 -\endisadelimtheory
158.499 -%
158.500 -\isatagtheory
158.501 -\isacommand{end}\isamarkupfalse%
158.502 -%
158.503 -\endisatagtheory
158.504 -{\isafoldtheory}%
158.505 -%
158.506 -\isadelimtheory
158.507 -%
158.508 -\endisadelimtheory
158.509 -\isanewline
158.510 -\isanewline
158.511 -\end{isabellebody}%
158.512 -%%% Local Variables:
158.513 -%%% mode: latex
158.514 -%%% TeX-master: "root"
158.515 -%%% End:
159.1 --- a/doc-src/IsarImplementation/Thy/integration.thy Wed Mar 04 11:05:02 2009 +0100
159.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
159.3 @@ -1,426 +0,0 @@
159.4 -
159.5 -(* $Id$ *)
159.6 -
159.7 -theory integration imports base begin
159.8 -
159.9 -chapter {* System integration *}
159.10 -
159.11 -section {* Isar toplevel \label{sec:isar-toplevel} *}
159.12 -
159.13 -text {* The Isar toplevel may be considered the centeral hub of the
159.14 - Isabelle/Isar system, where all key components and sub-systems are
159.15 - integrated into a single read-eval-print loop of Isar commands. We
159.16 - shall even incorporate the existing {\ML} toplevel of the compiler
159.17 - and run-time system (cf.\ \secref{sec:ML-toplevel}).
159.18 -
159.19 - Isabelle/Isar departs from the original ``LCF system architecture''
159.20 - where {\ML} was really The Meta Language for defining theories and
159.21 - conducting proofs. Instead, {\ML} now only serves as the
159.22 - implementation language for the system (and user extensions), while
159.23 - the specific Isar toplevel supports the concepts of theory and proof
159.24 - development natively. This includes the graph structure of theories
159.25 - and the block structure of proofs, support for unlimited undo,
159.26 - facilities for tracing, debugging, timing, profiling etc.
159.27 -
159.28 - \medskip The toplevel maintains an implicit state, which is
159.29 - transformed by a sequence of transitions -- either interactively or
159.30 - in batch-mode. In interactive mode, Isar state transitions are
159.31 - encapsulated as safe transactions, such that both failure and undo
159.32 - are handled conveniently without destroying the underlying draft
159.33 - theory (cf.~\secref{sec:context-theory}). In batch mode,
159.34 - transitions operate in a linear (destructive) fashion, such that
159.35 - error conditions abort the present attempt to construct a theory or
159.36 - proof altogether.
159.37 -
159.38 - The toplevel state is a disjoint sum of empty @{text toplevel}, or
159.39 - @{text theory}, or @{text proof}. On entering the main Isar loop we
159.40 - start with an empty toplevel. A theory is commenced by giving a
159.41 - @{text \<THEORY>} header; within a theory we may issue theory
159.42 - commands such as @{text \<DEFINITION>}, or state a @{text
159.43 - \<THEOREM>} to be proven. Now we are within a proof state, with a
159.44 - rich collection of Isar proof commands for structured proof
159.45 - composition, or unstructured proof scripts. When the proof is
159.46 - concluded we get back to the theory, which is then updated by
159.47 - storing the resulting fact. Further theory declarations or theorem
159.48 - statements with proofs may follow, until we eventually conclude the
159.49 - theory development by issuing @{text \<END>}. The resulting theory
159.50 - is then stored within the theory database and we are back to the
159.51 - empty toplevel.
159.52 -
159.53 - In addition to these proper state transformations, there are also
159.54 - some diagnostic commands for peeking at the toplevel state without
159.55 - modifying it (e.g.\ \isakeyword{thm}, \isakeyword{term},
159.56 - \isakeyword{print-cases}).
159.57 -*}
159.58 -
159.59 -text %mlref {*
159.60 - \begin{mldecls}
159.61 - @{index_ML_type Toplevel.state} \\
159.62 - @{index_ML Toplevel.UNDEF: "exn"} \\
159.63 - @{index_ML Toplevel.is_toplevel: "Toplevel.state -> bool"} \\
159.64 - @{index_ML Toplevel.theory_of: "Toplevel.state -> theory"} \\
159.65 - @{index_ML Toplevel.proof_of: "Toplevel.state -> Proof.state"} \\
159.66 - @{index_ML Toplevel.debug: "bool ref"} \\
159.67 - @{index_ML Toplevel.timing: "bool ref"} \\
159.68 - @{index_ML Toplevel.profiling: "int ref"} \\
159.69 - \end{mldecls}
159.70 -
159.71 - \begin{description}
159.72 -
159.73 - \item @{ML_type Toplevel.state} represents Isar toplevel states,
159.74 - which are normally manipulated through the concept of toplevel
159.75 - transitions only (\secref{sec:toplevel-transition}). Also note that
159.76 - a raw toplevel state is subject to the same linearity restrictions
159.77 - as a theory context (cf.~\secref{sec:context-theory}).
159.78 -
159.79 - \item @{ML Toplevel.UNDEF} is raised for undefined toplevel
159.80 - operations. Many operations work only partially for certain cases,
159.81 - since @{ML_type Toplevel.state} is a sum type.
159.82 -
159.83 - \item @{ML Toplevel.is_toplevel}~@{text "state"} checks for an empty
159.84 - toplevel state.
159.85 -
159.86 - \item @{ML Toplevel.theory_of}~@{text "state"} selects the theory of
159.87 - a theory or proof (!), otherwise raises @{ML Toplevel.UNDEF}.
159.88 -
159.89 - \item @{ML Toplevel.proof_of}~@{text "state"} selects the Isar proof
159.90 - state if available, otherwise raises @{ML Toplevel.UNDEF}.
159.91 -
159.92 - \item @{ML "set Toplevel.debug"} makes the toplevel print further
159.93 - details about internal error conditions, exceptions being raised
159.94 - etc.
159.95 -
159.96 - \item @{ML "set Toplevel.timing"} makes the toplevel print timing
159.97 - information for each Isar command being executed.
159.98 -
159.99 - \item @{ML Toplevel.profiling}~@{verbatim ":="}~@{text "n"} controls
159.100 - low-level profiling of the underlying {\ML} runtime system. For
159.101 - Poly/ML, @{text "n = 1"} means time and @{text "n = 2"} space
159.102 - profiling.
159.103 -
159.104 - \end{description}
159.105 -*}
159.106 -
159.107 -
159.108 -subsection {* Toplevel transitions \label{sec:toplevel-transition} *}
159.109 -
159.110 -text {*
159.111 - An Isar toplevel transition consists of a partial function on the
159.112 - toplevel state, with additional information for diagnostics and
159.113 - error reporting: there are fields for command name, source position,
159.114 - optional source text, as well as flags for interactive-only commands
159.115 - (which issue a warning in batch-mode), printing of result state,
159.116 - etc.
159.117 -
159.118 - The operational part is represented as the sequential union of a
159.119 - list of partial functions, which are tried in turn until the first
159.120 - one succeeds. This acts like an outer case-expression for various
159.121 - alternative state transitions. For example, \isakeyword{qed} acts
159.122 - differently for a local proofs vs.\ the global ending of the main
159.123 - proof.
159.124 -
159.125 - Toplevel transitions are composed via transition transformers.
159.126 - Internally, Isar commands are put together from an empty transition
159.127 - extended by name and source position (and optional source text). It
159.128 - is then left to the individual command parser to turn the given
159.129 - concrete syntax into a suitable transition transformer that adjoin
159.130 - actual operations on a theory or proof state etc.
159.131 -*}
159.132 -
159.133 -text %mlref {*
159.134 - \begin{mldecls}
159.135 - @{index_ML Toplevel.print: "Toplevel.transition -> Toplevel.transition"} \\
159.136 - @{index_ML Toplevel.no_timing: "Toplevel.transition -> Toplevel.transition"} \\
159.137 - @{index_ML Toplevel.keep: "(Toplevel.state -> unit) ->
159.138 - Toplevel.transition -> Toplevel.transition"} \\
159.139 - @{index_ML Toplevel.theory: "(theory -> theory) ->
159.140 - Toplevel.transition -> Toplevel.transition"} \\
159.141 - @{index_ML Toplevel.theory_to_proof: "(theory -> Proof.state) ->
159.142 - Toplevel.transition -> Toplevel.transition"} \\
159.143 - @{index_ML Toplevel.proof: "(Proof.state -> Proof.state) ->
159.144 - Toplevel.transition -> Toplevel.transition"} \\
159.145 - @{index_ML Toplevel.proofs: "(Proof.state -> Proof.state Seq.seq) ->
159.146 - Toplevel.transition -> Toplevel.transition"} \\
159.147 - @{index_ML Toplevel.end_proof: "(bool -> Proof.state -> Proof.context) ->
159.148 - Toplevel.transition -> Toplevel.transition"} \\
159.149 - \end{mldecls}
159.150 -
159.151 - \begin{description}
159.152 -
159.153 - \item @{ML Toplevel.print}~@{text "tr"} sets the print flag, which
159.154 - causes the toplevel loop to echo the result state (in interactive
159.155 - mode).
159.156 -
159.157 - \item @{ML Toplevel.no_timing}~@{text "tr"} indicates that the
159.158 - transition should never show timing information, e.g.\ because it is
159.159 - a diagnostic command.
159.160 -
159.161 - \item @{ML Toplevel.keep}~@{text "tr"} adjoins a diagnostic
159.162 - function.
159.163 -
159.164 - \item @{ML Toplevel.theory}~@{text "tr"} adjoins a theory
159.165 - transformer.
159.166 -
159.167 - \item @{ML Toplevel.theory_to_proof}~@{text "tr"} adjoins a global
159.168 - goal function, which turns a theory into a proof state. The theory
159.169 - may be changed before entering the proof; the generic Isar goal
159.170 - setup includes an argument that specifies how to apply the proven
159.171 - result to the theory, when the proof is finished.
159.172 -
159.173 - \item @{ML Toplevel.proof}~@{text "tr"} adjoins a deterministic
159.174 - proof command, with a singleton result.
159.175 -
159.176 - \item @{ML Toplevel.proofs}~@{text "tr"} adjoins a general proof
159.177 - command, with zero or more result states (represented as a lazy
159.178 - list).
159.179 -
159.180 - \item @{ML Toplevel.end_proof}~@{text "tr"} adjoins a concluding
159.181 - proof command, that returns the resulting theory, after storing the
159.182 - resulting facts in the context etc.
159.183 -
159.184 - \end{description}
159.185 -*}
159.186 -
159.187 -
159.188 -subsection {* Toplevel control *}
159.189 -
159.190 -text {*
159.191 - There are a few special control commands that modify the behavior
159.192 - the toplevel itself, and only make sense in interactive mode. Under
159.193 - normal circumstances, the user encounters these only implicitly as
159.194 - part of the protocol between the Isabelle/Isar system and a
159.195 - user-interface such as ProofGeneral.
159.196 -
159.197 - \begin{description}
159.198 -
159.199 - \item \isacommand{undo} follows the three-level hierarchy of empty
159.200 - toplevel vs.\ theory vs.\ proof: undo within a proof reverts to the
159.201 - previous proof context, undo after a proof reverts to the theory
159.202 - before the initial goal statement, undo of a theory command reverts
159.203 - to the previous theory value, undo of a theory header discontinues
159.204 - the current theory development and removes it from the theory
159.205 - database (\secref{sec:theory-database}).
159.206 -
159.207 - \item \isacommand{kill} aborts the current level of development:
159.208 - kill in a proof context reverts to the theory before the initial
159.209 - goal statement, kill in a theory context aborts the current theory
159.210 - development, removing it from the database.
159.211 -
159.212 - \item \isacommand{exit} drops out of the Isar toplevel into the
159.213 - underlying {\ML} toplevel (\secref{sec:ML-toplevel}). The Isar
159.214 - toplevel state is preserved and may be continued later.
159.215 -
159.216 - \item \isacommand{quit} terminates the Isabelle/Isar process without
159.217 - saving.
159.218 -
159.219 - \end{description}
159.220 -*}
159.221 -
159.222 -
159.223 -section {* ML toplevel \label{sec:ML-toplevel} *}
159.224 -
159.225 -text {*
159.226 - The {\ML} toplevel provides a read-compile-eval-print loop for {\ML}
159.227 - values, types, structures, and functors. {\ML} declarations operate
159.228 - on the global system state, which consists of the compiler
159.229 - environment plus the values of {\ML} reference variables. There is
159.230 - no clean way to undo {\ML} declarations, except for reverting to a
159.231 - previously saved state of the whole Isabelle process. {\ML} input
159.232 - is either read interactively from a TTY, or from a string (usually
159.233 - within a theory text), or from a source file (usually loaded from a
159.234 - theory).
159.235 -
159.236 - Whenever the {\ML} toplevel is active, the current Isabelle theory
159.237 - context is passed as an internal reference variable. Thus {\ML}
159.238 - code may access the theory context during compilation, it may even
159.239 - change the value of a theory being under construction --- while
159.240 - observing the usual linearity restrictions
159.241 - (cf.~\secref{sec:context-theory}).
159.242 -*}
159.243 -
159.244 -text %mlref {*
159.245 - \begin{mldecls}
159.246 - @{index_ML the_context: "unit -> theory"} \\
159.247 - @{index_ML "Context.>> ": "(Context.generic -> Context.generic) -> unit"} \\
159.248 - \end{mldecls}
159.249 -
159.250 - \begin{description}
159.251 -
159.252 - \item @{ML "the_context ()"} refers to the theory context of the
159.253 - {\ML} toplevel --- at compile time! {\ML} code needs to take care
159.254 - to refer to @{ML "the_context ()"} correctly. Recall that
159.255 - evaluation of a function body is delayed until actual runtime.
159.256 - Moreover, persistent {\ML} toplevel bindings to an unfinished theory
159.257 - should be avoided: code should either project out the desired
159.258 - information immediately, or produce an explicit @{ML_type
159.259 - theory_ref} (cf.\ \secref{sec:context-theory}).
159.260 -
159.261 - \item @{ML "Context.>>"}~@{text f} applies context transformation
159.262 - @{text f} to the implicit context of the {\ML} toplevel.
159.263 -
159.264 - \end{description}
159.265 -
159.266 - It is very important to note that the above functions are really
159.267 - restricted to the compile time, even though the {\ML} compiler is
159.268 - invoked at runtime! The majority of {\ML} code uses explicit
159.269 - functional arguments of a theory or proof context instead. Thus it
159.270 - may be invoked for an arbitrary context later on, without having to
159.271 - worry about any operational details.
159.272 -
159.273 - \bigskip
159.274 -
159.275 - \begin{mldecls}
159.276 - @{index_ML Isar.main: "unit -> unit"} \\
159.277 - @{index_ML Isar.loop: "unit -> unit"} \\
159.278 - @{index_ML Isar.state: "unit -> Toplevel.state"} \\
159.279 - @{index_ML Isar.exn: "unit -> (exn * string) option"} \\
159.280 - @{index_ML Isar.context: "unit -> Proof.context"} \\
159.281 - @{index_ML Isar.goal: "unit -> thm"} \\
159.282 - \end{mldecls}
159.283 -
159.284 - \begin{description}
159.285 -
159.286 - \item @{ML "Isar.main ()"} invokes the Isar toplevel from {\ML},
159.287 - initializing an empty toplevel state.
159.288 -
159.289 - \item @{ML "Isar.loop ()"} continues the Isar toplevel with the
159.290 - current state, after having dropped out of the Isar toplevel loop.
159.291 -
159.292 - \item @{ML "Isar.state ()"} and @{ML "Isar.exn ()"} get current
159.293 - toplevel state and error condition, respectively. This only works
159.294 - after having dropped out of the Isar toplevel loop.
159.295 -
159.296 - \item @{ML "Isar.context ()"} produces the proof context from @{ML
159.297 - "Isar.state ()"}, analogous to @{ML Context.proof_of}
159.298 - (\secref{sec:generic-context}).
159.299 -
159.300 - \item @{ML "Isar.goal ()"} picks the tactical goal from @{ML
159.301 - "Isar.state ()"}, represented as a theorem according to
159.302 - \secref{sec:tactical-goals}.
159.303 -
159.304 - \end{description}
159.305 -*}
159.306 -
159.307 -
159.308 -section {* Theory database \label{sec:theory-database} *}
159.309 -
159.310 -text {*
159.311 - The theory database maintains a collection of theories, together
159.312 - with some administrative information about their original sources,
159.313 - which are held in an external store (i.e.\ some directory within the
159.314 - regular file system).
159.315 -
159.316 - The theory database is organized as a directed acyclic graph;
159.317 - entries are referenced by theory name. Although some additional
159.318 - interfaces allow to include a directory specification as well, this
159.319 - is only a hint to the underlying theory loader. The internal theory
159.320 - name space is flat!
159.321 -
159.322 - Theory @{text A} is associated with the main theory file @{text
159.323 - A}\verb,.thy,, which needs to be accessible through the theory
159.324 - loader path. Any number of additional {\ML} source files may be
159.325 - associated with each theory, by declaring these dependencies in the
159.326 - theory header as @{text \<USES>}, and loading them consecutively
159.327 - within the theory context. The system keeps track of incoming {\ML}
159.328 - sources and associates them with the current theory. The file
159.329 - @{text A}\verb,.ML, is loaded after a theory has been concluded, in
159.330 - order to support legacy proof {\ML} proof scripts.
159.331 -
159.332 - The basic internal actions of the theory database are @{text
159.333 - "update"}, @{text "outdate"}, and @{text "remove"}:
159.334 -
159.335 - \begin{itemize}
159.336 -
159.337 - \item @{text "update A"} introduces a link of @{text "A"} with a
159.338 - @{text "theory"} value of the same name; it asserts that the theory
159.339 - sources are now consistent with that value;
159.340 -
159.341 - \item @{text "outdate A"} invalidates the link of a theory database
159.342 - entry to its sources, but retains the present theory value;
159.343 -
159.344 - \item @{text "remove A"} deletes entry @{text "A"} from the theory
159.345 - database.
159.346 -
159.347 - \end{itemize}
159.348 -
159.349 - These actions are propagated to sub- or super-graphs of a theory
159.350 - entry as expected, in order to preserve global consistency of the
159.351 - state of all loaded theories with the sources of the external store.
159.352 - This implies certain causalities between actions: @{text "update"}
159.353 - or @{text "outdate"} of an entry will @{text "outdate"} all
159.354 - descendants; @{text "remove"} will @{text "remove"} all descendants.
159.355 -
159.356 - \medskip There are separate user-level interfaces to operate on the
159.357 - theory database directly or indirectly. The primitive actions then
159.358 - just happen automatically while working with the system. In
159.359 - particular, processing a theory header @{text "\<THEORY> A
159.360 - \<IMPORTS> B\<^sub>1 \<dots> B\<^sub>n \<BEGIN>"} ensures that the
159.361 - sub-graph of the collective imports @{text "B\<^sub>1 \<dots> B\<^sub>n"}
159.362 - is up-to-date, too. Earlier theories are reloaded as required, with
159.363 - @{text update} actions proceeding in topological order according to
159.364 - theory dependencies. There may be also a wave of implied @{text
159.365 - outdate} actions for derived theory nodes until a stable situation
159.366 - is achieved eventually.
159.367 -*}
159.368 -
159.369 -text %mlref {*
159.370 - \begin{mldecls}
159.371 - @{index_ML theory: "string -> theory"} \\
159.372 - @{index_ML use_thy: "string -> unit"} \\
159.373 - @{index_ML use_thys: "string list -> unit"} \\
159.374 - @{index_ML ThyInfo.touch_thy: "string -> unit"} \\
159.375 - @{index_ML ThyInfo.remove_thy: "string -> unit"} \\[1ex]
159.376 - @{index_ML ThyInfo.begin_theory}@{verbatim ": ... -> bool -> theory"} \\
159.377 - @{index_ML ThyInfo.end_theory: "theory -> unit"} \\
159.378 - @{index_ML ThyInfo.register_theory: "theory -> unit"} \\[1ex]
159.379 - @{verbatim "datatype action = Update | Outdate | Remove"} \\
159.380 - @{index_ML ThyInfo.add_hook: "(ThyInfo.action -> string -> unit) -> unit"} \\
159.381 - \end{mldecls}
159.382 -
159.383 - \begin{description}
159.384 -
159.385 - \item @{ML theory}~@{text A} retrieves the theory value presently
159.386 - associated with name @{text A}. Note that the result might be
159.387 - outdated.
159.388 -
159.389 - \item @{ML use_thy}~@{text A} ensures that theory @{text A} is fully
159.390 - up-to-date wrt.\ the external file store, reloading outdated
159.391 - ancestors as required.
159.392 -
159.393 - \item @{ML use_thys} is similar to @{ML use_thy}, but handles
159.394 - several theories simultaneously. Thus it acts like processing the
159.395 - import header of a theory, without performing the merge of the
159.396 - result, though.
159.397 -
159.398 - \item @{ML ThyInfo.touch_thy}~@{text A} performs and @{text outdate} action
159.399 - on theory @{text A} and all descendants.
159.400 -
159.401 - \item @{ML ThyInfo.remove_thy}~@{text A} deletes theory @{text A} and all
159.402 - descendants from the theory database.
159.403 -
159.404 - \item @{ML ThyInfo.begin_theory} is the basic operation behind a
159.405 - @{text \<THEORY>} header declaration. This is {\ML} functions is
159.406 - normally not invoked directly.
159.407 -
159.408 - \item @{ML ThyInfo.end_theory} concludes the loading of a theory
159.409 - proper and stores the result in the theory database.
159.410 -
159.411 - \item @{ML ThyInfo.register_theory}~@{text "text thy"} registers an
159.412 - existing theory value with the theory loader database. There is no
159.413 - management of associated sources.
159.414 -
159.415 - \item @{ML "ThyInfo.add_hook"}~@{text f} registers function @{text
159.416 - f} as a hook for theory database actions. The function will be
159.417 - invoked with the action and theory name being involved; thus derived
159.418 - actions may be performed in associated system components, e.g.\
159.419 - maintaining the state of an editor for the theory sources.
159.420 -
159.421 - The kind and order of actions occurring in practice depends both on
159.422 - user interactions and the internal process of resolving theory
159.423 - imports. Hooks should not rely on a particular policy here! Any
159.424 - exceptions raised by the hook are ignored.
159.425 -
159.426 - \end{description}
159.427 -*}
159.428 -
159.429 -end
160.1 --- a/doc-src/IsarImplementation/Thy/isar.thy Wed Mar 04 11:05:02 2009 +0100
160.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
160.3 @@ -1,41 +0,0 @@
160.4 -
160.5 -(* $Id$ *)
160.6 -
160.7 -theory isar imports base begin
160.8 -
160.9 -chapter {* Isar proof texts *}
160.10 -
160.11 -section {* Proof context *}
160.12 -
160.13 -text FIXME
160.14 -
160.15 -
160.16 -section {* Proof state \label{sec:isar-proof-state} *}
160.17 -
160.18 -text {*
160.19 - FIXME
160.20 -
160.21 -\glossary{Proof state}{The whole configuration of a structured proof,
160.22 -consisting of a \seeglossary{proof context} and an optional
160.23 -\seeglossary{structured goal}. Internally, an Isar proof state is
160.24 -organized as a stack to accomodate block structure of proof texts.
160.25 -For historical reasons, a low-level \seeglossary{tactical goal} is
160.26 -occasionally called ``proof state'' as well.}
160.27 -
160.28 -\glossary{Structured goal}{FIXME}
160.29 -
160.30 -\glossary{Goal}{See \seeglossary{tactical goal} or \seeglossary{structured goal}. \norefpage}
160.31 -
160.32 -
160.33 -*}
160.34 -
160.35 -section {* Proof methods *}
160.36 -
160.37 -text FIXME
160.38 -
160.39 -section {* Attributes *}
160.40 -
160.41 -text "FIXME ?!"
160.42 -
160.43 -
160.44 -end
161.1 --- a/doc-src/IsarImplementation/Thy/locale.thy Wed Mar 04 11:05:02 2009 +0100
161.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
161.3 @@ -1,26 +0,0 @@
161.4 -
161.5 -(* $Id$ *)
161.6 -
161.7 -theory "locale" imports base begin
161.8 -
161.9 -chapter {* Structured specifications *}
161.10 -
161.11 -section {* Specification elements *}
161.12 -
161.13 -text FIXME
161.14 -
161.15 -
161.16 -section {* Type-inference *}
161.17 -
161.18 -text FIXME
161.19 -
161.20 -
161.21 -section {* Local theories *}
161.22 -
161.23 -text {*
161.24 - FIXME
161.25 -
161.26 - \glossary{Local theory}{FIXME}
161.27 -*}
161.28 -
161.29 -end
162.1 --- a/doc-src/IsarImplementation/Thy/logic.thy Wed Mar 04 11:05:02 2009 +0100
162.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
162.3 @@ -1,851 +0,0 @@
162.4 -theory logic imports base begin
162.5 -
162.6 -chapter {* Primitive logic \label{ch:logic} *}
162.7 -
162.8 -text {*
162.9 - The logical foundations of Isabelle/Isar are that of the Pure logic,
162.10 - which has been introduced as a natural-deduction framework in
162.11 - \cite{paulson700}. This is essentially the same logic as ``@{text
162.12 - "\<lambda>HOL"}'' in the more abstract setting of Pure Type Systems (PTS)
162.13 - \cite{Barendregt-Geuvers:2001}, although there are some key
162.14 - differences in the specific treatment of simple types in
162.15 - Isabelle/Pure.
162.16 -
162.17 - Following type-theoretic parlance, the Pure logic consists of three
162.18 - levels of @{text "\<lambda>"}-calculus with corresponding arrows, @{text
162.19 - "\<Rightarrow>"} for syntactic function space (terms depending on terms), @{text
162.20 - "\<And>"} for universal quantification (proofs depending on terms), and
162.21 - @{text "\<Longrightarrow>"} for implication (proofs depending on proofs).
162.22 -
162.23 - Derivations are relative to a logical theory, which declares type
162.24 - constructors, constants, and axioms. Theory declarations support
162.25 - schematic polymorphism, which is strictly speaking outside the
162.26 - logic.\footnote{This is the deeper logical reason, why the theory
162.27 - context @{text "\<Theta>"} is separate from the proof context @{text "\<Gamma>"}
162.28 - of the core calculus.}
162.29 -*}
162.30 -
162.31 -
162.32 -section {* Types \label{sec:types} *}
162.33 -
162.34 -text {*
162.35 - The language of types is an uninterpreted order-sorted first-order
162.36 - algebra; types are qualified by ordered type classes.
162.37 -
162.38 - \medskip A \emph{type class} is an abstract syntactic entity
162.39 - declared in the theory context. The \emph{subclass relation} @{text
162.40 - "c\<^isub>1 \<subseteq> c\<^isub>2"} is specified by stating an acyclic
162.41 - generating relation; the transitive closure is maintained
162.42 - internally. The resulting relation is an ordering: reflexive,
162.43 - transitive, and antisymmetric.
162.44 -
162.45 - A \emph{sort} is a list of type classes written as @{text "s =
162.46 - {c\<^isub>1, \<dots>, c\<^isub>m}"}, which represents symbolic
162.47 - intersection. Notationally, the curly braces are omitted for
162.48 - singleton intersections, i.e.\ any class @{text "c"} may be read as
162.49 - a sort @{text "{c}"}. The ordering on type classes is extended to
162.50 - sorts according to the meaning of intersections: @{text
162.51 - "{c\<^isub>1, \<dots> c\<^isub>m} \<subseteq> {d\<^isub>1, \<dots>, d\<^isub>n}"} iff
162.52 - @{text "\<forall>j. \<exists>i. c\<^isub>i \<subseteq> d\<^isub>j"}. The empty intersection
162.53 - @{text "{}"} refers to the universal sort, which is the largest
162.54 - element wrt.\ the sort order. The intersections of all (finitely
162.55 - many) classes declared in the current theory are the minimal
162.56 - elements wrt.\ the sort order.
162.57 -
162.58 - \medskip A \emph{fixed type variable} is a pair of a basic name
162.59 - (starting with a @{text "'"} character) and a sort constraint, e.g.\
162.60 - @{text "('a, s)"} which is usually printed as @{text "\<alpha>\<^isub>s"}.
162.61 - A \emph{schematic type variable} is a pair of an indexname and a
162.62 - sort constraint, e.g.\ @{text "(('a, 0), s)"} which is usually
162.63 - printed as @{text "?\<alpha>\<^isub>s"}.
162.64 -
162.65 - Note that \emph{all} syntactic components contribute to the identity
162.66 - of type variables, including the sort constraint. The core logic
162.67 - handles type variables with the same name but different sorts as
162.68 - different, although some outer layers of the system make it hard to
162.69 - produce anything like this.
162.70 -
162.71 - A \emph{type constructor} @{text "\<kappa>"} is a @{text "k"}-ary operator
162.72 - on types declared in the theory. Type constructor application is
162.73 - written postfix as @{text "(\<alpha>\<^isub>1, \<dots>, \<alpha>\<^isub>k)\<kappa>"}. For
162.74 - @{text "k = 0"} the argument tuple is omitted, e.g.\ @{text "prop"}
162.75 - instead of @{text "()prop"}. For @{text "k = 1"} the parentheses
162.76 - are omitted, e.g.\ @{text "\<alpha> list"} instead of @{text "(\<alpha>)list"}.
162.77 - Further notation is provided for specific constructors, notably the
162.78 - right-associative infix @{text "\<alpha> \<Rightarrow> \<beta>"} instead of @{text "(\<alpha>,
162.79 - \<beta>)fun"}.
162.80 -
162.81 - A \emph{type} is defined inductively over type variables and type
162.82 - constructors as follows: @{text "\<tau> = \<alpha>\<^isub>s | ?\<alpha>\<^isub>s |
162.83 - (\<tau>\<^sub>1, \<dots>, \<tau>\<^sub>k)\<kappa>"}.
162.84 -
162.85 - A \emph{type abbreviation} is a syntactic definition @{text
162.86 - "(\<^vec>\<alpha>)\<kappa> = \<tau>"} of an arbitrary type expression @{text "\<tau>"} over
162.87 - variables @{text "\<^vec>\<alpha>"}. Type abbreviations appear as type
162.88 - constructors in the syntax, but are expanded before entering the
162.89 - logical core.
162.90 -
162.91 - A \emph{type arity} declares the image behavior of a type
162.92 - constructor wrt.\ the algebra of sorts: @{text "\<kappa> :: (s\<^isub>1, \<dots>,
162.93 - s\<^isub>k)s"} means that @{text "(\<tau>\<^isub>1, \<dots>, \<tau>\<^isub>k)\<kappa>"} is
162.94 - of sort @{text "s"} if every argument type @{text "\<tau>\<^isub>i"} is
162.95 - of sort @{text "s\<^isub>i"}. Arity declarations are implicitly
162.96 - completed, i.e.\ @{text "\<kappa> :: (\<^vec>s)c"} entails @{text "\<kappa> ::
162.97 - (\<^vec>s)c'"} for any @{text "c' \<supseteq> c"}.
162.98 -
162.99 - \medskip The sort algebra is always maintained as \emph{coregular},
162.100 - which means that type arities are consistent with the subclass
162.101 - relation: for any type constructor @{text "\<kappa>"}, and classes @{text
162.102 - "c\<^isub>1 \<subseteq> c\<^isub>2"}, and arities @{text "\<kappa> ::
162.103 - (\<^vec>s\<^isub>1)c\<^isub>1"} and @{text "\<kappa> ::
162.104 - (\<^vec>s\<^isub>2)c\<^isub>2"} holds @{text "\<^vec>s\<^isub>1 \<subseteq>
162.105 - \<^vec>s\<^isub>2"} component-wise.
162.106 -
162.107 - The key property of a coregular order-sorted algebra is that sort
162.108 - constraints can be solved in a most general fashion: for each type
162.109 - constructor @{text "\<kappa>"} and sort @{text "s"} there is a most general
162.110 - vector of argument sorts @{text "(s\<^isub>1, \<dots>, s\<^isub>k)"} such
162.111 - that a type scheme @{text "(\<alpha>\<^bsub>s\<^isub>1\<^esub>, \<dots>,
162.112 - \<alpha>\<^bsub>s\<^isub>k\<^esub>)\<kappa>"} is of sort @{text "s"}.
162.113 - Consequently, type unification has most general solutions (modulo
162.114 - equivalence of sorts), so type-inference produces primary types as
162.115 - expected \cite{nipkow-prehofer}.
162.116 -*}
162.117 -
162.118 -text %mlref {*
162.119 - \begin{mldecls}
162.120 - @{index_ML_type class} \\
162.121 - @{index_ML_type sort} \\
162.122 - @{index_ML_type arity} \\
162.123 - @{index_ML_type typ} \\
162.124 - @{index_ML map_atyps: "(typ -> typ) -> typ -> typ"} \\
162.125 - @{index_ML fold_atyps: "(typ -> 'a -> 'a) -> typ -> 'a -> 'a"} \\
162.126 - \end{mldecls}
162.127 - \begin{mldecls}
162.128 - @{index_ML Sign.subsort: "theory -> sort * sort -> bool"} \\
162.129 - @{index_ML Sign.of_sort: "theory -> typ * sort -> bool"} \\
162.130 - @{index_ML Sign.add_types: "(string * int * mixfix) list -> theory -> theory"} \\
162.131 - @{index_ML Sign.add_tyabbrs_i: "
162.132 - (string * string list * typ * mixfix) list -> theory -> theory"} \\
162.133 - @{index_ML Sign.primitive_class: "string * class list -> theory -> theory"} \\
162.134 - @{index_ML Sign.primitive_classrel: "class * class -> theory -> theory"} \\
162.135 - @{index_ML Sign.primitive_arity: "arity -> theory -> theory"} \\
162.136 - \end{mldecls}
162.137 -
162.138 - \begin{description}
162.139 -
162.140 - \item @{ML_type class} represents type classes; this is an alias for
162.141 - @{ML_type string}.
162.142 -
162.143 - \item @{ML_type sort} represents sorts; this is an alias for
162.144 - @{ML_type "class list"}.
162.145 -
162.146 - \item @{ML_type arity} represents type arities; this is an alias for
162.147 - triples of the form @{text "(\<kappa>, \<^vec>s, s)"} for @{text "\<kappa> ::
162.148 - (\<^vec>s)s"} described above.
162.149 -
162.150 - \item @{ML_type typ} represents types; this is a datatype with
162.151 - constructors @{ML TFree}, @{ML TVar}, @{ML Type}.
162.152 -
162.153 - \item @{ML map_atyps}~@{text "f \<tau>"} applies the mapping @{text "f"}
162.154 - to all atomic types (@{ML TFree}, @{ML TVar}) occurring in @{text
162.155 - "\<tau>"}.
162.156 -
162.157 - \item @{ML fold_atyps}~@{text "f \<tau>"} iterates the operation @{text
162.158 - "f"} over all occurrences of atomic types (@{ML TFree}, @{ML TVar})
162.159 - in @{text "\<tau>"}; the type structure is traversed from left to right.
162.160 -
162.161 - \item @{ML Sign.subsort}~@{text "thy (s\<^isub>1, s\<^isub>2)"}
162.162 - tests the subsort relation @{text "s\<^isub>1 \<subseteq> s\<^isub>2"}.
162.163 -
162.164 - \item @{ML Sign.of_sort}~@{text "thy (\<tau>, s)"} tests whether type
162.165 - @{text "\<tau>"} is of sort @{text "s"}.
162.166 -
162.167 - \item @{ML Sign.add_types}~@{text "[(\<kappa>, k, mx), \<dots>]"} declares a new
162.168 - type constructors @{text "\<kappa>"} with @{text "k"} arguments and
162.169 - optional mixfix syntax.
162.170 -
162.171 - \item @{ML Sign.add_tyabbrs_i}~@{text "[(\<kappa>, \<^vec>\<alpha>, \<tau>, mx), \<dots>]"}
162.172 - defines a new type abbreviation @{text "(\<^vec>\<alpha>)\<kappa> = \<tau>"} with
162.173 - optional mixfix syntax.
162.174 -
162.175 - \item @{ML Sign.primitive_class}~@{text "(c, [c\<^isub>1, \<dots>,
162.176 - c\<^isub>n])"} declares a new class @{text "c"}, together with class
162.177 - relations @{text "c \<subseteq> c\<^isub>i"}, for @{text "i = 1, \<dots>, n"}.
162.178 -
162.179 - \item @{ML Sign.primitive_classrel}~@{text "(c\<^isub>1,
162.180 - c\<^isub>2)"} declares the class relation @{text "c\<^isub>1 \<subseteq>
162.181 - c\<^isub>2"}.
162.182 -
162.183 - \item @{ML Sign.primitive_arity}~@{text "(\<kappa>, \<^vec>s, s)"} declares
162.184 - the arity @{text "\<kappa> :: (\<^vec>s)s"}.
162.185 -
162.186 - \end{description}
162.187 -*}
162.188 -
162.189 -
162.190 -
162.191 -section {* Terms \label{sec:terms} *}
162.192 -
162.193 -text {*
162.194 - \glossary{Term}{FIXME}
162.195 -
162.196 - The language of terms is that of simply-typed @{text "\<lambda>"}-calculus
162.197 - with de-Bruijn indices for bound variables (cf.\ \cite{debruijn72}
162.198 - or \cite{paulson-ml2}), with the types being determined determined
162.199 - by the corresponding binders. In contrast, free variables and
162.200 - constants are have an explicit name and type in each occurrence.
162.201 -
162.202 - \medskip A \emph{bound variable} is a natural number @{text "b"},
162.203 - which accounts for the number of intermediate binders between the
162.204 - variable occurrence in the body and its binding position. For
162.205 - example, the de-Bruijn term @{text
162.206 - "\<lambda>\<^bsub>nat\<^esub>. \<lambda>\<^bsub>nat\<^esub>. 1 + 0"} would
162.207 - correspond to @{text
162.208 - "\<lambda>x\<^bsub>nat\<^esub>. \<lambda>y\<^bsub>nat\<^esub>. x + y"} in a named
162.209 - representation. Note that a bound variable may be represented by
162.210 - different de-Bruijn indices at different occurrences, depending on
162.211 - the nesting of abstractions.
162.212 -
162.213 - A \emph{loose variable} is a bound variable that is outside the
162.214 - scope of local binders. The types (and names) for loose variables
162.215 - can be managed as a separate context, that is maintained as a stack
162.216 - of hypothetical binders. The core logic operates on closed terms,
162.217 - without any loose variables.
162.218 -
162.219 - A \emph{fixed variable} is a pair of a basic name and a type, e.g.\
162.220 - @{text "(x, \<tau>)"} which is usually printed @{text "x\<^isub>\<tau>"}. A
162.221 - \emph{schematic variable} is a pair of an indexname and a type,
162.222 - e.g.\ @{text "((x, 0), \<tau>)"} which is usually printed as @{text
162.223 - "?x\<^isub>\<tau>"}.
162.224 -
162.225 - \medskip A \emph{constant} is a pair of a basic name and a type,
162.226 - e.g.\ @{text "(c, \<tau>)"} which is usually printed as @{text
162.227 - "c\<^isub>\<tau>"}. Constants are declared in the context as polymorphic
162.228 - families @{text "c :: \<sigma>"}, meaning that all substitution instances
162.229 - @{text "c\<^isub>\<tau>"} for @{text "\<tau> = \<sigma>\<vartheta>"} are valid.
162.230 -
162.231 - The vector of \emph{type arguments} of constant @{text "c\<^isub>\<tau>"}
162.232 - wrt.\ the declaration @{text "c :: \<sigma>"} is defined as the codomain of
162.233 - the matcher @{text "\<vartheta> = {?\<alpha>\<^isub>1 \<mapsto> \<tau>\<^isub>1, \<dots>,
162.234 - ?\<alpha>\<^isub>n \<mapsto> \<tau>\<^isub>n}"} presented in canonical order @{text
162.235 - "(\<tau>\<^isub>1, \<dots>, \<tau>\<^isub>n)"}. Within a given theory context,
162.236 - there is a one-to-one correspondence between any constant @{text
162.237 - "c\<^isub>\<tau>"} and the application @{text "c(\<tau>\<^isub>1, \<dots>,
162.238 - \<tau>\<^isub>n)"} of its type arguments. For example, with @{text "plus
162.239 - :: \<alpha> \<Rightarrow> \<alpha> \<Rightarrow> \<alpha>"}, the instance @{text "plus\<^bsub>nat \<Rightarrow> nat \<Rightarrow>
162.240 - nat\<^esub>"} corresponds to @{text "plus(nat)"}.
162.241 -
162.242 - Constant declarations @{text "c :: \<sigma>"} may contain sort constraints
162.243 - for type variables in @{text "\<sigma>"}. These are observed by
162.244 - type-inference as expected, but \emph{ignored} by the core logic.
162.245 - This means the primitive logic is able to reason with instances of
162.246 - polymorphic constants that the user-level type-checker would reject
162.247 - due to violation of type class restrictions.
162.248 -
162.249 - \medskip An \emph{atomic} term is either a variable or constant. A
162.250 - \emph{term} is defined inductively over atomic terms, with
162.251 - abstraction and application as follows: @{text "t = b | x\<^isub>\<tau> |
162.252 - ?x\<^isub>\<tau> | c\<^isub>\<tau> | \<lambda>\<^isub>\<tau>. t | t\<^isub>1 t\<^isub>2"}.
162.253 - Parsing and printing takes care of converting between an external
162.254 - representation with named bound variables. Subsequently, we shall
162.255 - use the latter notation instead of internal de-Bruijn
162.256 - representation.
162.257 -
162.258 - The inductive relation @{text "t :: \<tau>"} assigns a (unique) type to a
162.259 - term according to the structure of atomic terms, abstractions, and
162.260 - applicatins:
162.261 - \[
162.262 - \infer{@{text "a\<^isub>\<tau> :: \<tau>"}}{}
162.263 - \qquad
162.264 - \infer{@{text "(\<lambda>x\<^sub>\<tau>. t) :: \<tau> \<Rightarrow> \<sigma>"}}{@{text "t :: \<sigma>"}}
162.265 - \qquad
162.266 - \infer{@{text "t u :: \<sigma>"}}{@{text "t :: \<tau> \<Rightarrow> \<sigma>"} & @{text "u :: \<tau>"}}
162.267 - \]
162.268 - A \emph{well-typed term} is a term that can be typed according to these rules.
162.269 -
162.270 - Typing information can be omitted: type-inference is able to
162.271 - reconstruct the most general type of a raw term, while assigning
162.272 - most general types to all of its variables and constants.
162.273 - Type-inference depends on a context of type constraints for fixed
162.274 - variables, and declarations for polymorphic constants.
162.275 -
162.276 - The identity of atomic terms consists both of the name and the type
162.277 - component. This means that different variables @{text
162.278 - "x\<^bsub>\<tau>\<^isub>1\<^esub>"} and @{text
162.279 - "x\<^bsub>\<tau>\<^isub>2\<^esub>"} may become the same after type
162.280 - instantiation. Some outer layers of the system make it hard to
162.281 - produce variables of the same name, but different types. In
162.282 - contrast, mixed instances of polymorphic constants occur frequently.
162.283 -
162.284 - \medskip The \emph{hidden polymorphism} of a term @{text "t :: \<sigma>"}
162.285 - is the set of type variables occurring in @{text "t"}, but not in
162.286 - @{text "\<sigma>"}. This means that the term implicitly depends on type
162.287 - arguments that are not accounted in the result type, i.e.\ there are
162.288 - different type instances @{text "t\<vartheta> :: \<sigma>"} and @{text
162.289 - "t\<vartheta>' :: \<sigma>"} with the same type. This slightly
162.290 - pathological situation notoriously demands additional care.
162.291 -
162.292 - \medskip A \emph{term abbreviation} is a syntactic definition @{text
162.293 - "c\<^isub>\<sigma> \<equiv> t"} of a closed term @{text "t"} of type @{text "\<sigma>"},
162.294 - without any hidden polymorphism. A term abbreviation looks like a
162.295 - constant in the syntax, but is expanded before entering the logical
162.296 - core. Abbreviations are usually reverted when printing terms, using
162.297 - @{text "t \<rightarrow> c\<^isub>\<sigma>"} as rules for higher-order rewriting.
162.298 -
162.299 - \medskip Canonical operations on @{text "\<lambda>"}-terms include @{text
162.300 - "\<alpha>\<beta>\<eta>"}-conversion: @{text "\<alpha>"}-conversion refers to capture-free
162.301 - renaming of bound variables; @{text "\<beta>"}-conversion contracts an
162.302 - abstraction applied to an argument term, substituting the argument
162.303 - in the body: @{text "(\<lambda>x. b)a"} becomes @{text "b[a/x]"}; @{text
162.304 - "\<eta>"}-conversion contracts vacuous application-abstraction: @{text
162.305 - "\<lambda>x. f x"} becomes @{text "f"}, provided that the bound variable
162.306 - does not occur in @{text "f"}.
162.307 -
162.308 - Terms are normally treated modulo @{text "\<alpha>"}-conversion, which is
162.309 - implicit in the de-Bruijn representation. Names for bound variables
162.310 - in abstractions are maintained separately as (meaningless) comments,
162.311 - mostly for parsing and printing. Full @{text "\<alpha>\<beta>\<eta>"}-conversion is
162.312 - commonplace in various standard operations (\secref{sec:obj-rules})
162.313 - that are based on higher-order unification and matching.
162.314 -*}
162.315 -
162.316 -text %mlref {*
162.317 - \begin{mldecls}
162.318 - @{index_ML_type term} \\
162.319 - @{index_ML "op aconv": "term * term -> bool"} \\
162.320 - @{index_ML map_types: "(typ -> typ) -> term -> term"} \\
162.321 - @{index_ML fold_types: "(typ -> 'a -> 'a) -> term -> 'a -> 'a"} \\
162.322 - @{index_ML map_aterms: "(term -> term) -> term -> term"} \\
162.323 - @{index_ML fold_aterms: "(term -> 'a -> 'a) -> term -> 'a -> 'a"} \\
162.324 - \end{mldecls}
162.325 - \begin{mldecls}
162.326 - @{index_ML fastype_of: "term -> typ"} \\
162.327 - @{index_ML lambda: "term -> term -> term"} \\
162.328 - @{index_ML betapply: "term * term -> term"} \\
162.329 - @{index_ML Sign.declare_const: "Properties.T -> (binding * typ) * mixfix ->
162.330 - theory -> term * theory"} \\
162.331 - @{index_ML Sign.add_abbrev: "string -> Properties.T -> binding * term ->
162.332 - theory -> (term * term) * theory"} \\
162.333 - @{index_ML Sign.const_typargs: "theory -> string * typ -> typ list"} \\
162.334 - @{index_ML Sign.const_instance: "theory -> string * typ list -> typ"} \\
162.335 - \end{mldecls}
162.336 -
162.337 - \begin{description}
162.338 -
162.339 - \item @{ML_type term} represents de-Bruijn terms, with comments in
162.340 - abstractions, and explicitly named free variables and constants;
162.341 - this is a datatype with constructors @{ML Bound}, @{ML Free}, @{ML
162.342 - Var}, @{ML Const}, @{ML Abs}, @{ML "op $"}.
162.343 -
162.344 - \item @{text "t"}~@{ML aconv}~@{text "u"} checks @{text
162.345 - "\<alpha>"}-equivalence of two terms. This is the basic equality relation
162.346 - on type @{ML_type term}; raw datatype equality should only be used
162.347 - for operations related to parsing or printing!
162.348 -
162.349 - \item @{ML map_types}~@{text "f t"} applies the mapping @{text
162.350 - "f"} to all types occurring in @{text "t"}.
162.351 -
162.352 - \item @{ML fold_types}~@{text "f t"} iterates the operation @{text
162.353 - "f"} over all occurrences of types in @{text "t"}; the term
162.354 - structure is traversed from left to right.
162.355 -
162.356 - \item @{ML map_aterms}~@{text "f t"} applies the mapping @{text "f"}
162.357 - to all atomic terms (@{ML Bound}, @{ML Free}, @{ML Var}, @{ML
162.358 - Const}) occurring in @{text "t"}.
162.359 -
162.360 - \item @{ML fold_aterms}~@{text "f t"} iterates the operation @{text
162.361 - "f"} over all occurrences of atomic terms (@{ML Bound}, @{ML Free},
162.362 - @{ML Var}, @{ML Const}) in @{text "t"}; the term structure is
162.363 - traversed from left to right.
162.364 -
162.365 - \item @{ML fastype_of}~@{text "t"} determines the type of a
162.366 - well-typed term. This operation is relatively slow, despite the
162.367 - omission of any sanity checks.
162.368 -
162.369 - \item @{ML lambda}~@{text "a b"} produces an abstraction @{text
162.370 - "\<lambda>a. b"}, where occurrences of the atomic term @{text "a"} in the
162.371 - body @{text "b"} are replaced by bound variables.
162.372 -
162.373 - \item @{ML betapply}~@{text "(t, u)"} produces an application @{text
162.374 - "t u"}, with topmost @{text "\<beta>"}-conversion if @{text "t"} is an
162.375 - abstraction.
162.376 -
162.377 - \item @{ML Sign.declare_const}~@{text "properties ((c, \<sigma>), mx)"}
162.378 - declares a new constant @{text "c :: \<sigma>"} with optional mixfix
162.379 - syntax.
162.380 -
162.381 - \item @{ML Sign.add_abbrev}~@{text "print_mode properties (c, t)"}
162.382 - introduces a new term abbreviation @{text "c \<equiv> t"}.
162.383 -
162.384 - \item @{ML Sign.const_typargs}~@{text "thy (c, \<tau>)"} and @{ML
162.385 - Sign.const_instance}~@{text "thy (c, [\<tau>\<^isub>1, \<dots>, \<tau>\<^isub>n])"}
162.386 - convert between two representations of polymorphic constants: full
162.387 - type instance vs.\ compact type arguments form.
162.388 -
162.389 - \end{description}
162.390 -*}
162.391 -
162.392 -
162.393 -section {* Theorems \label{sec:thms} *}
162.394 -
162.395 -text {*
162.396 - \glossary{Proposition}{FIXME A \seeglossary{term} of
162.397 - \seeglossary{type} @{text "prop"}. Internally, there is nothing
162.398 - special about propositions apart from their type, but the concrete
162.399 - syntax enforces a clear distinction. Propositions are structured
162.400 - via implication @{text "A \<Longrightarrow> B"} or universal quantification @{text
162.401 - "\<And>x. B x"} --- anything else is considered atomic. The canonical
162.402 - form for propositions is that of a \seeglossary{Hereditary Harrop
162.403 - Formula}. FIXME}
162.404 -
162.405 - \glossary{Theorem}{A proven proposition within a certain theory and
162.406 - proof context, formally @{text "\<Gamma> \<turnstile>\<^sub>\<Theta> \<phi>"}; both contexts are
162.407 - rarely spelled out explicitly. Theorems are usually normalized
162.408 - according to the \seeglossary{HHF} format. FIXME}
162.409 -
162.410 - \glossary{Fact}{Sometimes used interchangeably for
162.411 - \seeglossary{theorem}. Strictly speaking, a list of theorems,
162.412 - essentially an extra-logical conjunction. Facts emerge either as
162.413 - local assumptions, or as results of local goal statements --- both
162.414 - may be simultaneous, hence the list representation. FIXME}
162.415 -
162.416 - \glossary{Schematic variable}{FIXME}
162.417 -
162.418 - \glossary{Fixed variable}{A variable that is bound within a certain
162.419 - proof context; an arbitrary-but-fixed entity within a portion of
162.420 - proof text. FIXME}
162.421 -
162.422 - \glossary{Free variable}{Synonymous for \seeglossary{fixed
162.423 - variable}. FIXME}
162.424 -
162.425 - \glossary{Bound variable}{FIXME}
162.426 -
162.427 - \glossary{Variable}{See \seeglossary{schematic variable},
162.428 - \seeglossary{fixed variable}, \seeglossary{bound variable}, or
162.429 - \seeglossary{type variable}. The distinguishing feature of
162.430 - different variables is their binding scope. FIXME}
162.431 -
162.432 - A \emph{proposition} is a well-typed term of type @{text "prop"}, a
162.433 - \emph{theorem} is a proven proposition (depending on a context of
162.434 - hypotheses and the background theory). Primitive inferences include
162.435 - plain natural deduction rules for the primary connectives @{text
162.436 - "\<And>"} and @{text "\<Longrightarrow>"} of the framework. There is also a builtin
162.437 - notion of equality/equivalence @{text "\<equiv>"}.
162.438 -*}
162.439 -
162.440 -subsection {* Primitive connectives and rules \label{sec:prim-rules} *}
162.441 -
162.442 -text {*
162.443 - The theory @{text "Pure"} contains constant declarations for the
162.444 - primitive connectives @{text "\<And>"}, @{text "\<Longrightarrow>"}, and @{text "\<equiv>"} of
162.445 - the logical framework, see \figref{fig:pure-connectives}. The
162.446 - derivability judgment @{text "A\<^isub>1, \<dots>, A\<^isub>n \<turnstile> B"} is
162.447 - defined inductively by the primitive inferences given in
162.448 - \figref{fig:prim-rules}, with the global restriction that the
162.449 - hypotheses must \emph{not} contain any schematic variables. The
162.450 - builtin equality is conceptually axiomatized as shown in
162.451 - \figref{fig:pure-equality}, although the implementation works
162.452 - directly with derived inferences.
162.453 -
162.454 - \begin{figure}[htb]
162.455 - \begin{center}
162.456 - \begin{tabular}{ll}
162.457 - @{text "all :: (\<alpha> \<Rightarrow> prop) \<Rightarrow> prop"} & universal quantification (binder @{text "\<And>"}) \\
162.458 - @{text "\<Longrightarrow> :: prop \<Rightarrow> prop \<Rightarrow> prop"} & implication (right associative infix) \\
162.459 - @{text "\<equiv> :: \<alpha> \<Rightarrow> \<alpha> \<Rightarrow> prop"} & equality relation (infix) \\
162.460 - \end{tabular}
162.461 - \caption{Primitive connectives of Pure}\label{fig:pure-connectives}
162.462 - \end{center}
162.463 - \end{figure}
162.464 -
162.465 - \begin{figure}[htb]
162.466 - \begin{center}
162.467 - \[
162.468 - \infer[@{text "(axiom)"}]{@{text "\<turnstile> A"}}{@{text "A \<in> \<Theta>"}}
162.469 - \qquad
162.470 - \infer[@{text "(assume)"}]{@{text "A \<turnstile> A"}}{}
162.471 - \]
162.472 - \[
162.473 - \infer[@{text "(\<And>_intro)"}]{@{text "\<Gamma> \<turnstile> \<And>x. b[x]"}}{@{text "\<Gamma> \<turnstile> b[x]"} & @{text "x \<notin> \<Gamma>"}}
162.474 - \qquad
162.475 - \infer[@{text "(\<And>_elim)"}]{@{text "\<Gamma> \<turnstile> b[a]"}}{@{text "\<Gamma> \<turnstile> \<And>x. b[x]"}}
162.476 - \]
162.477 - \[
162.478 - \infer[@{text "(\<Longrightarrow>_intro)"}]{@{text "\<Gamma> - A \<turnstile> A \<Longrightarrow> B"}}{@{text "\<Gamma> \<turnstile> B"}}
162.479 - \qquad
162.480 - \infer[@{text "(\<Longrightarrow>_elim)"}]{@{text "\<Gamma>\<^sub>1 \<union> \<Gamma>\<^sub>2 \<turnstile> B"}}{@{text "\<Gamma>\<^sub>1 \<turnstile> A \<Longrightarrow> B"} & @{text "\<Gamma>\<^sub>2 \<turnstile> A"}}
162.481 - \]
162.482 - \caption{Primitive inferences of Pure}\label{fig:prim-rules}
162.483 - \end{center}
162.484 - \end{figure}
162.485 -
162.486 - \begin{figure}[htb]
162.487 - \begin{center}
162.488 - \begin{tabular}{ll}
162.489 - @{text "\<turnstile> (\<lambda>x. b[x]) a \<equiv> b[a]"} & @{text "\<beta>"}-conversion \\
162.490 - @{text "\<turnstile> x \<equiv> x"} & reflexivity \\
162.491 - @{text "\<turnstile> x \<equiv> y \<Longrightarrow> P x \<Longrightarrow> P y"} & substitution \\
162.492 - @{text "\<turnstile> (\<And>x. f x \<equiv> g x) \<Longrightarrow> f \<equiv> g"} & extensionality \\
162.493 - @{text "\<turnstile> (A \<Longrightarrow> B) \<Longrightarrow> (B \<Longrightarrow> A) \<Longrightarrow> A \<equiv> B"} & logical equivalence \\
162.494 - \end{tabular}
162.495 - \caption{Conceptual axiomatization of Pure equality}\label{fig:pure-equality}
162.496 - \end{center}
162.497 - \end{figure}
162.498 -
162.499 - The introduction and elimination rules for @{text "\<And>"} and @{text
162.500 - "\<Longrightarrow>"} are analogous to formation of dependently typed @{text
162.501 - "\<lambda>"}-terms representing the underlying proof objects. Proof terms
162.502 - are irrelevant in the Pure logic, though; they cannot occur within
162.503 - propositions. The system provides a runtime option to record
162.504 - explicit proof terms for primitive inferences. Thus all three
162.505 - levels of @{text "\<lambda>"}-calculus become explicit: @{text "\<Rightarrow>"} for
162.506 - terms, and @{text "\<And>/\<Longrightarrow>"} for proofs (cf.\
162.507 - \cite{Berghofer-Nipkow:2000:TPHOL}).
162.508 -
162.509 - Observe that locally fixed parameters (as in @{text "\<And>_intro"}) need
162.510 - not be recorded in the hypotheses, because the simple syntactic
162.511 - types of Pure are always inhabitable. ``Assumptions'' @{text "x ::
162.512 - \<tau>"} for type-membership are only present as long as some @{text
162.513 - "x\<^isub>\<tau>"} occurs in the statement body.\footnote{This is the key
162.514 - difference to ``@{text "\<lambda>HOL"}'' in the PTS framework
162.515 - \cite{Barendregt-Geuvers:2001}, where hypotheses @{text "x : A"} are
162.516 - treated uniformly for propositions and types.}
162.517 -
162.518 - \medskip The axiomatization of a theory is implicitly closed by
162.519 - forming all instances of type and term variables: @{text "\<turnstile>
162.520 - A\<vartheta>"} holds for any substitution instance of an axiom
162.521 - @{text "\<turnstile> A"}. By pushing substitutions through derivations
162.522 - inductively, we also get admissible @{text "generalize"} and @{text
162.523 - "instance"} rules as shown in \figref{fig:subst-rules}.
162.524 -
162.525 - \begin{figure}[htb]
162.526 - \begin{center}
162.527 - \[
162.528 - \infer{@{text "\<Gamma> \<turnstile> B[?\<alpha>]"}}{@{text "\<Gamma> \<turnstile> B[\<alpha>]"} & @{text "\<alpha> \<notin> \<Gamma>"}}
162.529 - \quad
162.530 - \infer[\quad@{text "(generalize)"}]{@{text "\<Gamma> \<turnstile> B[?x]"}}{@{text "\<Gamma> \<turnstile> B[x]"} & @{text "x \<notin> \<Gamma>"}}
162.531 - \]
162.532 - \[
162.533 - \infer{@{text "\<Gamma> \<turnstile> B[\<tau>]"}}{@{text "\<Gamma> \<turnstile> B[?\<alpha>]"}}
162.534 - \quad
162.535 - \infer[\quad@{text "(instantiate)"}]{@{text "\<Gamma> \<turnstile> B[t]"}}{@{text "\<Gamma> \<turnstile> B[?x]"}}
162.536 - \]
162.537 - \caption{Admissible substitution rules}\label{fig:subst-rules}
162.538 - \end{center}
162.539 - \end{figure}
162.540 -
162.541 - Note that @{text "instantiate"} does not require an explicit
162.542 - side-condition, because @{text "\<Gamma>"} may never contain schematic
162.543 - variables.
162.544 -
162.545 - In principle, variables could be substituted in hypotheses as well,
162.546 - but this would disrupt the monotonicity of reasoning: deriving
162.547 - @{text "\<Gamma>\<vartheta> \<turnstile> B\<vartheta>"} from @{text "\<Gamma> \<turnstile> B"} is
162.548 - correct, but @{text "\<Gamma>\<vartheta> \<supseteq> \<Gamma>"} does not necessarily hold:
162.549 - the result belongs to a different proof context.
162.550 -
162.551 - \medskip An \emph{oracle} is a function that produces axioms on the
162.552 - fly. Logically, this is an instance of the @{text "axiom"} rule
162.553 - (\figref{fig:prim-rules}), but there is an operational difference.
162.554 - The system always records oracle invocations within derivations of
162.555 - theorems. Tracing plain axioms (and named theorems) is optional.
162.556 -
162.557 - Axiomatizations should be limited to the bare minimum, typically as
162.558 - part of the initial logical basis of an object-logic formalization.
162.559 - Later on, theories are usually developed in a strictly definitional
162.560 - fashion, by stating only certain equalities over new constants.
162.561 -
162.562 - A \emph{simple definition} consists of a constant declaration @{text
162.563 - "c :: \<sigma>"} together with an axiom @{text "\<turnstile> c \<equiv> t"}, where @{text "t
162.564 - :: \<sigma>"} is a closed term without any hidden polymorphism. The RHS
162.565 - may depend on further defined constants, but not @{text "c"} itself.
162.566 - Definitions of functions may be presented as @{text "c \<^vec>x \<equiv>
162.567 - t"} instead of the puristic @{text "c \<equiv> \<lambda>\<^vec>x. t"}.
162.568 -
162.569 - An \emph{overloaded definition} consists of a collection of axioms
162.570 - for the same constant, with zero or one equations @{text
162.571 - "c((\<^vec>\<alpha>)\<kappa>) \<equiv> t"} for each type constructor @{text "\<kappa>"} (for
162.572 - distinct variables @{text "\<^vec>\<alpha>"}). The RHS may mention
162.573 - previously defined constants as above, or arbitrary constants @{text
162.574 - "d(\<alpha>\<^isub>i)"} for some @{text "\<alpha>\<^isub>i"} projected from @{text
162.575 - "\<^vec>\<alpha>"}. Thus overloaded definitions essentially work by
162.576 - primitive recursion over the syntactic structure of a single type
162.577 - argument.
162.578 -*}
162.579 -
162.580 -text %mlref {*
162.581 - \begin{mldecls}
162.582 - @{index_ML_type ctyp} \\
162.583 - @{index_ML_type cterm} \\
162.584 - @{index_ML Thm.ctyp_of: "theory -> typ -> ctyp"} \\
162.585 - @{index_ML Thm.cterm_of: "theory -> term -> cterm"} \\
162.586 - \end{mldecls}
162.587 - \begin{mldecls}
162.588 - @{index_ML_type thm} \\
162.589 - @{index_ML proofs: "int ref"} \\
162.590 - @{index_ML Thm.assume: "cterm -> thm"} \\
162.591 - @{index_ML Thm.forall_intr: "cterm -> thm -> thm"} \\
162.592 - @{index_ML Thm.forall_elim: "cterm -> thm -> thm"} \\
162.593 - @{index_ML Thm.implies_intr: "cterm -> thm -> thm"} \\
162.594 - @{index_ML Thm.implies_elim: "thm -> thm -> thm"} \\
162.595 - @{index_ML Thm.generalize: "string list * string list -> int -> thm -> thm"} \\
162.596 - @{index_ML Thm.instantiate: "(ctyp * ctyp) list * (cterm * cterm) list -> thm -> thm"} \\
162.597 - @{index_ML Thm.axiom: "theory -> string -> thm"} \\
162.598 - @{index_ML Thm.add_oracle: "bstring * ('a -> cterm) -> theory
162.599 - -> (string * ('a -> thm)) * theory"} \\
162.600 - \end{mldecls}
162.601 - \begin{mldecls}
162.602 - @{index_ML Theory.add_axioms_i: "(binding * term) list -> theory -> theory"} \\
162.603 - @{index_ML Theory.add_deps: "string -> string * typ -> (string * typ) list -> theory -> theory"} \\
162.604 - @{index_ML Theory.add_defs_i: "bool -> bool -> (binding * term) list -> theory -> theory"} \\
162.605 - \end{mldecls}
162.606 -
162.607 - \begin{description}
162.608 -
162.609 - \item @{ML_type ctyp} and @{ML_type cterm} represent certified types
162.610 - and terms, respectively. These are abstract datatypes that
162.611 - guarantee that its values have passed the full well-formedness (and
162.612 - well-typedness) checks, relative to the declarations of type
162.613 - constructors, constants etc. in the theory.
162.614 -
162.615 - \item @{ML ctyp_of}~@{text "thy \<tau>"} and @{ML cterm_of}~@{text "thy
162.616 - t"} explicitly checks types and terms, respectively. This also
162.617 - involves some basic normalizations, such expansion of type and term
162.618 - abbreviations from the theory context.
162.619 -
162.620 - Re-certification is relatively slow and should be avoided in tight
162.621 - reasoning loops. There are separate operations to decompose
162.622 - certified entities (including actual theorems).
162.623 -
162.624 - \item @{ML_type thm} represents proven propositions. This is an
162.625 - abstract datatype that guarantees that its values have been
162.626 - constructed by basic principles of the @{ML_struct Thm} module.
162.627 - Every @{ML thm} value contains a sliding back-reference to the
162.628 - enclosing theory, cf.\ \secref{sec:context-theory}.
162.629 -
162.630 - \item @{ML proofs} determines the detail of proof recording within
162.631 - @{ML_type thm} values: @{ML 0} records only oracles, @{ML 1} records
162.632 - oracles, axioms and named theorems, @{ML 2} records full proof
162.633 - terms.
162.634 -
162.635 - \item @{ML Thm.assume}, @{ML Thm.forall_intr}, @{ML
162.636 - Thm.forall_elim}, @{ML Thm.implies_intr}, and @{ML Thm.implies_elim}
162.637 - correspond to the primitive inferences of \figref{fig:prim-rules}.
162.638 -
162.639 - \item @{ML Thm.generalize}~@{text "(\<^vec>\<alpha>, \<^vec>x)"}
162.640 - corresponds to the @{text "generalize"} rules of
162.641 - \figref{fig:subst-rules}. Here collections of type and term
162.642 - variables are generalized simultaneously, specified by the given
162.643 - basic names.
162.644 -
162.645 - \item @{ML Thm.instantiate}~@{text "(\<^vec>\<alpha>\<^isub>s,
162.646 - \<^vec>x\<^isub>\<tau>)"} corresponds to the @{text "instantiate"} rules
162.647 - of \figref{fig:subst-rules}. Type variables are substituted before
162.648 - term variables. Note that the types in @{text "\<^vec>x\<^isub>\<tau>"}
162.649 - refer to the instantiated versions.
162.650 -
162.651 - \item @{ML Thm.axiom}~@{text "thy name"} retrieves a named
162.652 - axiom, cf.\ @{text "axiom"} in \figref{fig:prim-rules}.
162.653 -
162.654 - \item @{ML Thm.add_oracle}~@{text "(name, oracle)"} produces a named
162.655 - oracle rule, essentially generating arbitrary axioms on the fly,
162.656 - cf.\ @{text "axiom"} in \figref{fig:prim-rules}.
162.657 -
162.658 - \item @{ML Theory.add_axioms_i}~@{text "[(name, A), \<dots>]"} declares
162.659 - arbitrary propositions as axioms.
162.660 -
162.661 - \item @{ML Theory.add_deps}~@{text "name c\<^isub>\<tau>
162.662 - \<^vec>d\<^isub>\<sigma>"} declares dependencies of a named specification
162.663 - for constant @{text "c\<^isub>\<tau>"}, relative to existing
162.664 - specifications for constants @{text "\<^vec>d\<^isub>\<sigma>"}.
162.665 -
162.666 - \item @{ML Theory.add_defs_i}~@{text "unchecked overloaded [(name, c
162.667 - \<^vec>x \<equiv> t), \<dots>]"} states a definitional axiom for an existing
162.668 - constant @{text "c"}. Dependencies are recorded (cf.\ @{ML
162.669 - Theory.add_deps}), unless the @{text "unchecked"} option is set.
162.670 -
162.671 - \end{description}
162.672 -*}
162.673 -
162.674 -
162.675 -subsection {* Auxiliary definitions *}
162.676 -
162.677 -text {*
162.678 - Theory @{text "Pure"} provides a few auxiliary definitions, see
162.679 - \figref{fig:pure-aux}. These special constants are normally not
162.680 - exposed to the user, but appear in internal encodings.
162.681 -
162.682 - \begin{figure}[htb]
162.683 - \begin{center}
162.684 - \begin{tabular}{ll}
162.685 - @{text "conjunction :: prop \<Rightarrow> prop \<Rightarrow> prop"} & (infix @{text "&"}) \\
162.686 - @{text "\<turnstile> A & B \<equiv> (\<And>C. (A \<Longrightarrow> B \<Longrightarrow> C) \<Longrightarrow> C)"} \\[1ex]
162.687 - @{text "prop :: prop \<Rightarrow> prop"} & (prefix @{text "#"}, suppressed) \\
162.688 - @{text "#A \<equiv> A"} \\[1ex]
162.689 - @{text "term :: \<alpha> \<Rightarrow> prop"} & (prefix @{text "TERM"}) \\
162.690 - @{text "term x \<equiv> (\<And>A. A \<Longrightarrow> A)"} \\[1ex]
162.691 - @{text "TYPE :: \<alpha> itself"} & (prefix @{text "TYPE"}) \\
162.692 - @{text "(unspecified)"} \\
162.693 - \end{tabular}
162.694 - \caption{Definitions of auxiliary connectives}\label{fig:pure-aux}
162.695 - \end{center}
162.696 - \end{figure}
162.697 -
162.698 - Derived conjunction rules include introduction @{text "A \<Longrightarrow> B \<Longrightarrow> A &
162.699 - B"}, and destructions @{text "A & B \<Longrightarrow> A"} and @{text "A & B \<Longrightarrow> B"}.
162.700 - Conjunction allows to treat simultaneous assumptions and conclusions
162.701 - uniformly. For example, multiple claims are intermediately
162.702 - represented as explicit conjunction, but this is refined into
162.703 - separate sub-goals before the user continues the proof; the final
162.704 - result is projected into a list of theorems (cf.\
162.705 - \secref{sec:tactical-goals}).
162.706 -
162.707 - The @{text "prop"} marker (@{text "#"}) makes arbitrarily complex
162.708 - propositions appear as atomic, without changing the meaning: @{text
162.709 - "\<Gamma> \<turnstile> A"} and @{text "\<Gamma> \<turnstile> #A"} are interchangeable. See
162.710 - \secref{sec:tactical-goals} for specific operations.
162.711 -
162.712 - The @{text "term"} marker turns any well-typed term into a derivable
162.713 - proposition: @{text "\<turnstile> TERM t"} holds unconditionally. Although
162.714 - this is logically vacuous, it allows to treat terms and proofs
162.715 - uniformly, similar to a type-theoretic framework.
162.716 -
162.717 - The @{text "TYPE"} constructor is the canonical representative of
162.718 - the unspecified type @{text "\<alpha> itself"}; it essentially injects the
162.719 - language of types into that of terms. There is specific notation
162.720 - @{text "TYPE(\<tau>)"} for @{text "TYPE\<^bsub>\<tau>
162.721 - itself\<^esub>"}.
162.722 - Although being devoid of any particular meaning, the @{text
162.723 - "TYPE(\<tau>)"} accounts for the type @{text "\<tau>"} within the term
162.724 - language. In particular, @{text "TYPE(\<alpha>)"} may be used as formal
162.725 - argument in primitive definitions, in order to circumvent hidden
162.726 - polymorphism (cf.\ \secref{sec:terms}). For example, @{text "c
162.727 - TYPE(\<alpha>) \<equiv> A[\<alpha>]"} defines @{text "c :: \<alpha> itself \<Rightarrow> prop"} in terms of
162.728 - a proposition @{text "A"} that depends on an additional type
162.729 - argument, which is essentially a predicate on types.
162.730 -*}
162.731 -
162.732 -text %mlref {*
162.733 - \begin{mldecls}
162.734 - @{index_ML Conjunction.intr: "thm -> thm -> thm"} \\
162.735 - @{index_ML Conjunction.elim: "thm -> thm * thm"} \\
162.736 - @{index_ML Drule.mk_term: "cterm -> thm"} \\
162.737 - @{index_ML Drule.dest_term: "thm -> cterm"} \\
162.738 - @{index_ML Logic.mk_type: "typ -> term"} \\
162.739 - @{index_ML Logic.dest_type: "term -> typ"} \\
162.740 - \end{mldecls}
162.741 -
162.742 - \begin{description}
162.743 -
162.744 - \item @{ML Conjunction.intr} derives @{text "A & B"} from @{text
162.745 - "A"} and @{text "B"}.
162.746 -
162.747 - \item @{ML Conjunction.elim} derives @{text "A"} and @{text "B"}
162.748 - from @{text "A & B"}.
162.749 -
162.750 - \item @{ML Drule.mk_term} derives @{text "TERM t"}.
162.751 -
162.752 - \item @{ML Drule.dest_term} recovers term @{text "t"} from @{text
162.753 - "TERM t"}.
162.754 -
162.755 - \item @{ML Logic.mk_type}~@{text "\<tau>"} produces the term @{text
162.756 - "TYPE(\<tau>)"}.
162.757 -
162.758 - \item @{ML Logic.dest_type}~@{text "TYPE(\<tau>)"} recovers the type
162.759 - @{text "\<tau>"}.
162.760 -
162.761 - \end{description}
162.762 -*}
162.763 -
162.764 -
162.765 -section {* Object-level rules \label{sec:obj-rules} *}
162.766 -
162.767 -text %FIXME {*
162.768 -
162.769 -FIXME
162.770 -
162.771 - A \emph{rule} is any Pure theorem in HHF normal form; there is a
162.772 - separate calculus for rule composition, which is modeled after
162.773 - Gentzen's Natural Deduction \cite{Gentzen:1935}, but allows
162.774 - rules to be nested arbitrarily, similar to \cite{extensions91}.
162.775 -
162.776 - Normally, all theorems accessible to the user are proper rules.
162.777 - Low-level inferences are occasional required internally, but the
162.778 - result should be always presented in canonical form. The higher
162.779 - interfaces of Isabelle/Isar will always produce proper rules. It is
162.780 - important to maintain this invariant in add-on applications!
162.781 -
162.782 - There are two main principles of rule composition: @{text
162.783 - "resolution"} (i.e.\ backchaining of rules) and @{text
162.784 - "by-assumption"} (i.e.\ closing a branch); both principles are
162.785 - combined in the variants of @{text "elim-resolution"} and @{text
162.786 - "dest-resolution"}. Raw @{text "composition"} is occasionally
162.787 - useful as well, also it is strictly speaking outside of the proper
162.788 - rule calculus.
162.789 -
162.790 - Rules are treated modulo general higher-order unification, which is
162.791 - unification modulo the equational theory of @{text "\<alpha>\<beta>\<eta>"}-conversion
162.792 - on @{text "\<lambda>"}-terms. Moreover, propositions are understood modulo
162.793 - the (derived) equivalence @{text "(A \<Longrightarrow> (\<And>x. B x)) \<equiv> (\<And>x. A \<Longrightarrow> B x)"}.
162.794 -
162.795 - This means that any operations within the rule calculus may be
162.796 - subject to spontaneous @{text "\<alpha>\<beta>\<eta>"}-HHF conversions. It is common
162.797 - practice not to contract or expand unnecessarily. Some mechanisms
162.798 - prefer an one form, others the opposite, so there is a potential
162.799 - danger to produce some oscillation!
162.800 -
162.801 - Only few operations really work \emph{modulo} HHF conversion, but
162.802 - expect a normal form: quantifiers @{text "\<And>"} before implications
162.803 - @{text "\<Longrightarrow>"} at each level of nesting.
162.804 -
162.805 -\glossary{Hereditary Harrop Formula}{The set of propositions in HHF
162.806 -format is defined inductively as @{text "H = (\<And>x\<^sup>*. H\<^sup>* \<Longrightarrow>
162.807 -A)"}, for variables @{text "x"} and atomic propositions @{text "A"}.
162.808 -Any proposition may be put into HHF form by normalizing with the rule
162.809 -@{text "(A \<Longrightarrow> (\<And>x. B x)) \<equiv> (\<And>x. A \<Longrightarrow> B x)"}. In Isabelle, the outermost
162.810 -quantifier prefix is represented via \seeglossary{schematic
162.811 -variables}, such that the top-level structure is merely that of a
162.812 -\seeglossary{Horn Clause}}.
162.813 -
162.814 -\glossary{HHF}{See \seeglossary{Hereditary Harrop Formula}.}
162.815 -
162.816 -
162.817 - \[
162.818 - \infer[@{text "(assumption)"}]{@{text "C\<vartheta>"}}
162.819 - {@{text "(\<And>\<^vec>x. \<^vec>H \<^vec>x \<Longrightarrow> A \<^vec>x) \<Longrightarrow> C"} & @{text "A\<vartheta> = H\<^sub>i\<vartheta>"}~~\text{(for some~@{text i})}}
162.820 - \]
162.821 -
162.822 -
162.823 - \[
162.824 - \infer[@{text "(compose)"}]{@{text "\<^vec>A\<vartheta> \<Longrightarrow> C\<vartheta>"}}
162.825 - {@{text "\<^vec>A \<Longrightarrow> B"} & @{text "B' \<Longrightarrow> C"} & @{text "B\<vartheta> = B'\<vartheta>"}}
162.826 - \]
162.827 -
162.828 -
162.829 - \[
162.830 - \infer[@{text "(\<And>_lift)"}]{@{text "(\<And>\<^vec>x. \<^vec>A (?\<^vec>a \<^vec>x)) \<Longrightarrow> (\<And>\<^vec>x. B (?\<^vec>a \<^vec>x))"}}{@{text "\<^vec>A ?\<^vec>a \<Longrightarrow> B ?\<^vec>a"}}
162.831 - \]
162.832 - \[
162.833 - \infer[@{text "(\<Longrightarrow>_lift)"}]{@{text "(\<^vec>H \<Longrightarrow> \<^vec>A) \<Longrightarrow> (\<^vec>H \<Longrightarrow> B)"}}{@{text "\<^vec>A \<Longrightarrow> B"}}
162.834 - \]
162.835 -
162.836 - The @{text resolve} scheme is now acquired from @{text "\<And>_lift"},
162.837 - @{text "\<Longrightarrow>_lift"}, and @{text compose}.
162.838 -
162.839 - \[
162.840 - \infer[@{text "(resolution)"}]
162.841 - {@{text "(\<And>\<^vec>x. \<^vec>H \<^vec>x \<Longrightarrow> \<^vec>A (?\<^vec>a \<^vec>x))\<vartheta> \<Longrightarrow> C\<vartheta>"}}
162.842 - {\begin{tabular}{l}
162.843 - @{text "\<^vec>A ?\<^vec>a \<Longrightarrow> B ?\<^vec>a"} \\
162.844 - @{text "(\<And>\<^vec>x. \<^vec>H \<^vec>x \<Longrightarrow> B' \<^vec>x) \<Longrightarrow> C"} \\
162.845 - @{text "(\<lambda>\<^vec>x. B (?\<^vec>a \<^vec>x))\<vartheta> = B'\<vartheta>"} \\
162.846 - \end{tabular}}
162.847 - \]
162.848 -
162.849 -
162.850 - FIXME @{text "elim_resolution"}, @{text "dest_resolution"}
162.851 -*}
162.852 -
162.853 -
162.854 -end
163.1 --- a/doc-src/IsarImplementation/Thy/prelim.thy Wed Mar 04 11:05:02 2009 +0100
163.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
163.3 @@ -1,779 +0,0 @@
163.4 -
163.5 -(* $Id$ *)
163.6 -
163.7 -theory prelim imports base begin
163.8 -
163.9 -chapter {* Preliminaries *}
163.10 -
163.11 -section {* Contexts \label{sec:context} *}
163.12 -
163.13 -text {*
163.14 - A logical context represents the background that is required for
163.15 - formulating statements and composing proofs. It acts as a medium to
163.16 - produce formal content, depending on earlier material (declarations,
163.17 - results etc.).
163.18 -
163.19 - For example, derivations within the Isabelle/Pure logic can be
163.20 - described as a judgment @{text "\<Gamma> \<turnstile>\<^sub>\<Theta> \<phi>"}, which means that a
163.21 - proposition @{text "\<phi>"} is derivable from hypotheses @{text "\<Gamma>"}
163.22 - within the theory @{text "\<Theta>"}. There are logical reasons for
163.23 - keeping @{text "\<Theta>"} and @{text "\<Gamma>"} separate: theories can be
163.24 - liberal about supporting type constructors and schematic
163.25 - polymorphism of constants and axioms, while the inner calculus of
163.26 - @{text "\<Gamma> \<turnstile> \<phi>"} is strictly limited to Simple Type Theory (with
163.27 - fixed type variables in the assumptions).
163.28 -
163.29 - \medskip Contexts and derivations are linked by the following key
163.30 - principles:
163.31 -
163.32 - \begin{itemize}
163.33 -
163.34 - \item Transfer: monotonicity of derivations admits results to be
163.35 - transferred into a \emph{larger} context, i.e.\ @{text "\<Gamma> \<turnstile>\<^sub>\<Theta>
163.36 - \<phi>"} implies @{text "\<Gamma>' \<turnstile>\<^sub>\<Theta>\<^sub>' \<phi>"} for contexts @{text "\<Theta>'
163.37 - \<supseteq> \<Theta>"} and @{text "\<Gamma>' \<supseteq> \<Gamma>"}.
163.38 -
163.39 - \item Export: discharge of hypotheses admits results to be exported
163.40 - into a \emph{smaller} context, i.e.\ @{text "\<Gamma>' \<turnstile>\<^sub>\<Theta> \<phi>"}
163.41 - implies @{text "\<Gamma> \<turnstile>\<^sub>\<Theta> \<Delta> \<Longrightarrow> \<phi>"} where @{text "\<Gamma>' \<supseteq> \<Gamma>"} and
163.42 - @{text "\<Delta> = \<Gamma>' - \<Gamma>"}. Note that @{text "\<Theta>"} remains unchanged here,
163.43 - only the @{text "\<Gamma>"} part is affected.
163.44 -
163.45 - \end{itemize}
163.46 -
163.47 - \medskip By modeling the main characteristics of the primitive
163.48 - @{text "\<Theta>"} and @{text "\<Gamma>"} above, and abstracting over any
163.49 - particular logical content, we arrive at the fundamental notions of
163.50 - \emph{theory context} and \emph{proof context} in Isabelle/Isar.
163.51 - These implement a certain policy to manage arbitrary \emph{context
163.52 - data}. There is a strongly-typed mechanism to declare new kinds of
163.53 - data at compile time.
163.54 -
163.55 - The internal bootstrap process of Isabelle/Pure eventually reaches a
163.56 - stage where certain data slots provide the logical content of @{text
163.57 - "\<Theta>"} and @{text "\<Gamma>"} sketched above, but this does not stop there!
163.58 - Various additional data slots support all kinds of mechanisms that
163.59 - are not necessarily part of the core logic.
163.60 -
163.61 - For example, there would be data for canonical introduction and
163.62 - elimination rules for arbitrary operators (depending on the
163.63 - object-logic and application), which enables users to perform
163.64 - standard proof steps implicitly (cf.\ the @{text "rule"} method
163.65 - \cite{isabelle-isar-ref}).
163.66 -
163.67 - \medskip Thus Isabelle/Isar is able to bring forth more and more
163.68 - concepts successively. In particular, an object-logic like
163.69 - Isabelle/HOL continues the Isabelle/Pure setup by adding specific
163.70 - components for automated reasoning (classical reasoner, tableau
163.71 - prover, structured induction etc.) and derived specification
163.72 - mechanisms (inductive predicates, recursive functions etc.). All of
163.73 - this is ultimately based on the generic data management by theory
163.74 - and proof contexts introduced here.
163.75 -*}
163.76 -
163.77 -
163.78 -subsection {* Theory context \label{sec:context-theory} *}
163.79 -
163.80 -text {*
163.81 - \glossary{Theory}{FIXME}
163.82 -
163.83 - A \emph{theory} is a data container with explicit named and unique
163.84 - identifier. Theories are related by a (nominal) sub-theory
163.85 - relation, which corresponds to the dependency graph of the original
163.86 - construction; each theory is derived from a certain sub-graph of
163.87 - ancestor theories.
163.88 -
163.89 - The @{text "merge"} operation produces the least upper bound of two
163.90 - theories, which actually degenerates into absorption of one theory
163.91 - into the other (due to the nominal sub-theory relation).
163.92 -
163.93 - The @{text "begin"} operation starts a new theory by importing
163.94 - several parent theories and entering a special @{text "draft"} mode,
163.95 - which is sustained until the final @{text "end"} operation. A draft
163.96 - theory acts like a linear type, where updates invalidate earlier
163.97 - versions. An invalidated draft is called ``stale''.
163.98 -
163.99 - The @{text "checkpoint"} operation produces an intermediate stepping
163.100 - stone that will survive the next update: both the original and the
163.101 - changed theory remain valid and are related by the sub-theory
163.102 - relation. Checkpointing essentially recovers purely functional
163.103 - theory values, at the expense of some extra internal bookkeeping.
163.104 -
163.105 - The @{text "copy"} operation produces an auxiliary version that has
163.106 - the same data content, but is unrelated to the original: updates of
163.107 - the copy do not affect the original, neither does the sub-theory
163.108 - relation hold.
163.109 -
163.110 - \medskip The example in \figref{fig:ex-theory} below shows a theory
163.111 - graph derived from @{text "Pure"}, with theory @{text "Length"}
163.112 - importing @{text "Nat"} and @{text "List"}. The body of @{text
163.113 - "Length"} consists of a sequence of updates, working mostly on
163.114 - drafts. Intermediate checkpoints may occur as well, due to the
163.115 - history mechanism provided by the Isar top-level, cf.\
163.116 - \secref{sec:isar-toplevel}.
163.117 -
163.118 - \begin{figure}[htb]
163.119 - \begin{center}
163.120 - \begin{tabular}{rcccl}
163.121 - & & @{text "Pure"} \\
163.122 - & & @{text "\<down>"} \\
163.123 - & & @{text "FOL"} \\
163.124 - & $\swarrow$ & & $\searrow$ & \\
163.125 - @{text "Nat"} & & & & @{text "List"} \\
163.126 - & $\searrow$ & & $\swarrow$ \\
163.127 - & & @{text "Length"} \\
163.128 - & & \multicolumn{3}{l}{~~@{keyword "imports"}} \\
163.129 - & & \multicolumn{3}{l}{~~@{keyword "begin"}} \\
163.130 - & & $\vdots$~~ \\
163.131 - & & @{text "\<bullet>"}~~ \\
163.132 - & & $\vdots$~~ \\
163.133 - & & @{text "\<bullet>"}~~ \\
163.134 - & & $\vdots$~~ \\
163.135 - & & \multicolumn{3}{l}{~~@{command "end"}} \\
163.136 - \end{tabular}
163.137 - \caption{A theory definition depending on ancestors}\label{fig:ex-theory}
163.138 - \end{center}
163.139 - \end{figure}
163.140 -
163.141 - \medskip There is a separate notion of \emph{theory reference} for
163.142 - maintaining a live link to an evolving theory context: updates on
163.143 - drafts are propagated automatically. Dynamic updating stops after
163.144 - an explicit @{text "end"} only.
163.145 -
163.146 - Derived entities may store a theory reference in order to indicate
163.147 - the context they belong to. This implicitly assumes monotonic
163.148 - reasoning, because the referenced context may become larger without
163.149 - further notice.
163.150 -*}
163.151 -
163.152 -text %mlref {*
163.153 - \begin{mldecls}
163.154 - @{index_ML_type theory} \\
163.155 - @{index_ML Theory.subthy: "theory * theory -> bool"} \\
163.156 - @{index_ML Theory.merge: "theory * theory -> theory"} \\
163.157 - @{index_ML Theory.checkpoint: "theory -> theory"} \\
163.158 - @{index_ML Theory.copy: "theory -> theory"} \\
163.159 - \end{mldecls}
163.160 - \begin{mldecls}
163.161 - @{index_ML_type theory_ref} \\
163.162 - @{index_ML Theory.deref: "theory_ref -> theory"} \\
163.163 - @{index_ML Theory.check_thy: "theory -> theory_ref"} \\
163.164 - \end{mldecls}
163.165 -
163.166 - \begin{description}
163.167 -
163.168 - \item @{ML_type theory} represents theory contexts. This is
163.169 - essentially a linear type! Most operations destroy the original
163.170 - version, which then becomes ``stale''.
163.171 -
163.172 - \item @{ML "Theory.subthy"}~@{text "(thy\<^sub>1, thy\<^sub>2)"}
163.173 - compares theories according to the inherent graph structure of the
163.174 - construction. This sub-theory relation is a nominal approximation
163.175 - of inclusion (@{text "\<subseteq>"}) of the corresponding content.
163.176 -
163.177 - \item @{ML "Theory.merge"}~@{text "(thy\<^sub>1, thy\<^sub>2)"}
163.178 - absorbs one theory into the other. This fails for unrelated
163.179 - theories!
163.180 -
163.181 - \item @{ML "Theory.checkpoint"}~@{text "thy"} produces a safe
163.182 - stepping stone in the linear development of @{text "thy"}. The next
163.183 - update will result in two related, valid theories.
163.184 -
163.185 - \item @{ML "Theory.copy"}~@{text "thy"} produces a variant of @{text
163.186 - "thy"} that holds a copy of the same data. The result is not
163.187 - related to the original; the original is unchanched.
163.188 -
163.189 - \item @{ML_type theory_ref} represents a sliding reference to an
163.190 - always valid theory; updates on the original are propagated
163.191 - automatically.
163.192 -
163.193 - \item @{ML "Theory.deref"}~@{text "thy_ref"} turns a @{ML_type
163.194 - "theory_ref"} into an @{ML_type "theory"} value. As the referenced
163.195 - theory evolves monotonically over time, later invocations of @{ML
163.196 - "Theory.deref"} may refer to a larger context.
163.197 -
163.198 - \item @{ML "Theory.check_thy"}~@{text "thy"} produces a @{ML_type
163.199 - "theory_ref"} from a valid @{ML_type "theory"} value.
163.200 -
163.201 - \end{description}
163.202 -*}
163.203 -
163.204 -
163.205 -subsection {* Proof context \label{sec:context-proof} *}
163.206 -
163.207 -text {*
163.208 - \glossary{Proof context}{The static context of a structured proof,
163.209 - acts like a local ``theory'' of the current portion of Isar proof
163.210 - text, generalizes the idea of local hypotheses @{text "\<Gamma>"} in
163.211 - judgments @{text "\<Gamma> \<turnstile> \<phi>"} of natural deduction calculi. There is a
163.212 - generic notion of introducing and discharging hypotheses.
163.213 - Arbritrary auxiliary context data may be adjoined.}
163.214 -
163.215 - A proof context is a container for pure data with a back-reference
163.216 - to the theory it belongs to. The @{text "init"} operation creates a
163.217 - proof context from a given theory. Modifications to draft theories
163.218 - are propagated to the proof context as usual, but there is also an
163.219 - explicit @{text "transfer"} operation to force resynchronization
163.220 - with more substantial updates to the underlying theory. The actual
163.221 - context data does not require any special bookkeeping, thanks to the
163.222 - lack of destructive features.
163.223 -
163.224 - Entities derived in a proof context need to record inherent logical
163.225 - requirements explicitly, since there is no separate context
163.226 - identification as for theories. For example, hypotheses used in
163.227 - primitive derivations (cf.\ \secref{sec:thms}) are recorded
163.228 - separately within the sequent @{text "\<Gamma> \<turnstile> \<phi>"}, just to make double
163.229 - sure. Results could still leak into an alien proof context do to
163.230 - programming errors, but Isabelle/Isar includes some extra validity
163.231 - checks in critical positions, notably at the end of a sub-proof.
163.232 -
163.233 - Proof contexts may be manipulated arbitrarily, although the common
163.234 - discipline is to follow block structure as a mental model: a given
163.235 - context is extended consecutively, and results are exported back
163.236 - into the original context. Note that the Isar proof states model
163.237 - block-structured reasoning explicitly, using a stack of proof
163.238 - contexts internally, cf.\ \secref{sec:isar-proof-state}.
163.239 -*}
163.240 -
163.241 -text %mlref {*
163.242 - \begin{mldecls}
163.243 - @{index_ML_type Proof.context} \\
163.244 - @{index_ML ProofContext.init: "theory -> Proof.context"} \\
163.245 - @{index_ML ProofContext.theory_of: "Proof.context -> theory"} \\
163.246 - @{index_ML ProofContext.transfer: "theory -> Proof.context -> Proof.context"} \\
163.247 - \end{mldecls}
163.248 -
163.249 - \begin{description}
163.250 -
163.251 - \item @{ML_type Proof.context} represents proof contexts. Elements
163.252 - of this type are essentially pure values, with a sliding reference
163.253 - to the background theory.
163.254 -
163.255 - \item @{ML ProofContext.init}~@{text "thy"} produces a proof context
163.256 - derived from @{text "thy"}, initializing all data.
163.257 -
163.258 - \item @{ML ProofContext.theory_of}~@{text "ctxt"} selects the
163.259 - background theory from @{text "ctxt"}, dereferencing its internal
163.260 - @{ML_type theory_ref}.
163.261 -
163.262 - \item @{ML ProofContext.transfer}~@{text "thy ctxt"} promotes the
163.263 - background theory of @{text "ctxt"} to the super theory @{text
163.264 - "thy"}.
163.265 -
163.266 - \end{description}
163.267 -*}
163.268 -
163.269 -
163.270 -subsection {* Generic contexts \label{sec:generic-context} *}
163.271 -
163.272 -text {*
163.273 - A generic context is the disjoint sum of either a theory or proof
163.274 - context. Occasionally, this enables uniform treatment of generic
163.275 - context data, typically extra-logical information. Operations on
163.276 - generic contexts include the usual injections, partial selections,
163.277 - and combinators for lifting operations on either component of the
163.278 - disjoint sum.
163.279 -
163.280 - Moreover, there are total operations @{text "theory_of"} and @{text
163.281 - "proof_of"} to convert a generic context into either kind: a theory
163.282 - can always be selected from the sum, while a proof context might
163.283 - have to be constructed by an ad-hoc @{text "init"} operation.
163.284 -*}
163.285 -
163.286 -text %mlref {*
163.287 - \begin{mldecls}
163.288 - @{index_ML_type Context.generic} \\
163.289 - @{index_ML Context.theory_of: "Context.generic -> theory"} \\
163.290 - @{index_ML Context.proof_of: "Context.generic -> Proof.context"} \\
163.291 - \end{mldecls}
163.292 -
163.293 - \begin{description}
163.294 -
163.295 - \item @{ML_type Context.generic} is the direct sum of @{ML_type
163.296 - "theory"} and @{ML_type "Proof.context"}, with the datatype
163.297 - constructors @{ML "Context.Theory"} and @{ML "Context.Proof"}.
163.298 -
163.299 - \item @{ML Context.theory_of}~@{text "context"} always produces a
163.300 - theory from the generic @{text "context"}, using @{ML
163.301 - "ProofContext.theory_of"} as required.
163.302 -
163.303 - \item @{ML Context.proof_of}~@{text "context"} always produces a
163.304 - proof context from the generic @{text "context"}, using @{ML
163.305 - "ProofContext.init"} as required (note that this re-initializes the
163.306 - context data with each invocation).
163.307 -
163.308 - \end{description}
163.309 -*}
163.310 -
163.311 -
163.312 -subsection {* Context data \label{sec:context-data} *}
163.313 -
163.314 -text {*
163.315 - The main purpose of theory and proof contexts is to manage arbitrary
163.316 - data. New data types can be declared incrementally at compile time.
163.317 - There are separate declaration mechanisms for any of the three kinds
163.318 - of contexts: theory, proof, generic.
163.319 -
163.320 - \paragraph{Theory data} may refer to destructive entities, which are
163.321 - maintained in direct correspondence to the linear evolution of
163.322 - theory values, including explicit copies.\footnote{Most existing
163.323 - instances of destructive theory data are merely historical relics
163.324 - (e.g.\ the destructive theorem storage, and destructive hints for
163.325 - the Simplifier and Classical rules).} A theory data declaration
163.326 - needs to implement the following SML signature:
163.327 -
163.328 - \medskip
163.329 - \begin{tabular}{ll}
163.330 - @{text "\<type> T"} & representing type \\
163.331 - @{text "\<val> empty: T"} & empty default value \\
163.332 - @{text "\<val> copy: T \<rightarrow> T"} & refresh impure data \\
163.333 - @{text "\<val> extend: T \<rightarrow> T"} & re-initialize on import \\
163.334 - @{text "\<val> merge: T \<times> T \<rightarrow> T"} & join on import \\
163.335 - \end{tabular}
163.336 - \medskip
163.337 -
163.338 - \noindent The @{text "empty"} value acts as initial default for
163.339 - \emph{any} theory that does not declare actual data content; @{text
163.340 - "copy"} maintains persistent integrity for impure data, it is just
163.341 - the identity for pure values; @{text "extend"} is acts like a
163.342 - unitary version of @{text "merge"}, both operations should also
163.343 - include the functionality of @{text "copy"} for impure data.
163.344 -
163.345 - \paragraph{Proof context data} is purely functional. A declaration
163.346 - needs to implement the following SML signature:
163.347 -
163.348 - \medskip
163.349 - \begin{tabular}{ll}
163.350 - @{text "\<type> T"} & representing type \\
163.351 - @{text "\<val> init: theory \<rightarrow> T"} & produce initial value \\
163.352 - \end{tabular}
163.353 - \medskip
163.354 -
163.355 - \noindent The @{text "init"} operation is supposed to produce a pure
163.356 - value from the given background theory.
163.357 -
163.358 - \paragraph{Generic data} provides a hybrid interface for both theory
163.359 - and proof data. The declaration is essentially the same as for
163.360 - (pure) theory data, without @{text "copy"}. The @{text "init"}
163.361 - operation for proof contexts merely selects the current data value
163.362 - from the background theory.
163.363 -
163.364 - \bigskip A data declaration of type @{text "T"} results in the
163.365 - following interface:
163.366 -
163.367 - \medskip
163.368 - \begin{tabular}{ll}
163.369 - @{text "init: theory \<rightarrow> theory"} \\
163.370 - @{text "get: context \<rightarrow> T"} \\
163.371 - @{text "put: T \<rightarrow> context \<rightarrow> context"} \\
163.372 - @{text "map: (T \<rightarrow> T) \<rightarrow> context \<rightarrow> context"} \\
163.373 - \end{tabular}
163.374 - \medskip
163.375 -
163.376 - \noindent Here @{text "init"} is only applicable to impure theory
163.377 - data to install a fresh copy persistently (destructive update on
163.378 - uninitialized has no permanent effect). The other operations provide
163.379 - access for the particular kind of context (theory, proof, or generic
163.380 - context). Note that this is a safe interface: there is no other way
163.381 - to access the corresponding data slot of a context. By keeping
163.382 - these operations private, a component may maintain abstract values
163.383 - authentically, without other components interfering.
163.384 -*}
163.385 -
163.386 -text %mlref {*
163.387 - \begin{mldecls}
163.388 - @{index_ML_functor TheoryDataFun} \\
163.389 - @{index_ML_functor ProofDataFun} \\
163.390 - @{index_ML_functor GenericDataFun} \\
163.391 - \end{mldecls}
163.392 -
163.393 - \begin{description}
163.394 -
163.395 - \item @{ML_functor TheoryDataFun}@{text "(spec)"} declares data for
163.396 - type @{ML_type theory} according to the specification provided as
163.397 - argument structure. The resulting structure provides data init and
163.398 - access operations as described above.
163.399 -
163.400 - \item @{ML_functor ProofDataFun}@{text "(spec)"} is analogous to
163.401 - @{ML_functor TheoryDataFun} for type @{ML_type Proof.context}.
163.402 -
163.403 - \item @{ML_functor GenericDataFun}@{text "(spec)"} is analogous to
163.404 - @{ML_functor TheoryDataFun} for type @{ML_type Context.generic}.
163.405 -
163.406 - \end{description}
163.407 -*}
163.408 -
163.409 -
163.410 -section {* Names \label{sec:names} *}
163.411 -
163.412 -text {*
163.413 - In principle, a name is just a string, but there are various
163.414 - convention for encoding additional structure. For example, ``@{text
163.415 - "Foo.bar.baz"}'' is considered as a qualified name consisting of
163.416 - three basic name components. The individual constituents of a name
163.417 - may have further substructure, e.g.\ the string
163.418 - ``\verb,\,\verb,<alpha>,'' encodes as a single symbol.
163.419 -*}
163.420 -
163.421 -
163.422 -subsection {* Strings of symbols *}
163.423 -
163.424 -text {*
163.425 - \glossary{Symbol}{The smallest unit of text in Isabelle, subsumes
163.426 - plain ASCII characters as well as an infinite collection of named
163.427 - symbols (for greek, math etc.).}
163.428 -
163.429 - A \emph{symbol} constitutes the smallest textual unit in Isabelle
163.430 - --- raw characters are normally not encountered at all. Isabelle
163.431 - strings consist of a sequence of symbols, represented as a packed
163.432 - string or a list of strings. Each symbol is in itself a small
163.433 - string, which has either one of the following forms:
163.434 -
163.435 - \begin{enumerate}
163.436 -
163.437 - \item a single ASCII character ``@{text "c"}'', for example
163.438 - ``\verb,a,'',
163.439 -
163.440 - \item a regular symbol ``\verb,\,\verb,<,@{text "ident"}\verb,>,'',
163.441 - for example ``\verb,\,\verb,<alpha>,'',
163.442 -
163.443 - \item a control symbol ``\verb,\,\verb,<^,@{text "ident"}\verb,>,'',
163.444 - for example ``\verb,\,\verb,<^bold>,'',
163.445 -
163.446 - \item a raw symbol ``\verb,\,\verb,<^raw:,@{text text}\verb,>,''
163.447 - where @{text text} constists of printable characters excluding
163.448 - ``\verb,.,'' and ``\verb,>,'', for example
163.449 - ``\verb,\,\verb,<^raw:$\sum_{i = 1}^n$>,'',
163.450 -
163.451 - \item a numbered raw control symbol ``\verb,\,\verb,<^raw,@{text
163.452 - n}\verb,>, where @{text n} consists of digits, for example
163.453 - ``\verb,\,\verb,<^raw42>,''.
163.454 -
163.455 - \end{enumerate}
163.456 -
163.457 - \noindent The @{text "ident"} syntax for symbol names is @{text
163.458 - "letter (letter | digit)\<^sup>*"}, where @{text "letter =
163.459 - A..Za..z"} and @{text "digit = 0..9"}. There are infinitely many
163.460 - regular symbols and control symbols, but a fixed collection of
163.461 - standard symbols is treated specifically. For example,
163.462 - ``\verb,\,\verb,<alpha>,'' is classified as a letter, which means it
163.463 - may occur within regular Isabelle identifiers.
163.464 -
163.465 - Since the character set underlying Isabelle symbols is 7-bit ASCII
163.466 - and 8-bit characters are passed through transparently, Isabelle may
163.467 - also process Unicode/UCS data in UTF-8 encoding. Unicode provides
163.468 - its own collection of mathematical symbols, but there is no built-in
163.469 - link to the standard collection of Isabelle.
163.470 -
163.471 - \medskip Output of Isabelle symbols depends on the print mode
163.472 - (\secref{FIXME}). For example, the standard {\LaTeX} setup of the
163.473 - Isabelle document preparation system would present
163.474 - ``\verb,\,\verb,<alpha>,'' as @{text "\<alpha>"}, and
163.475 - ``\verb,\,\verb,<^bold>,\verb,\,\verb,<alpha>,'' as @{text
163.476 - "\<^bold>\<alpha>"}.
163.477 -*}
163.478 -
163.479 -text %mlref {*
163.480 - \begin{mldecls}
163.481 - @{index_ML_type "Symbol.symbol"} \\
163.482 - @{index_ML Symbol.explode: "string -> Symbol.symbol list"} \\
163.483 - @{index_ML Symbol.is_letter: "Symbol.symbol -> bool"} \\
163.484 - @{index_ML Symbol.is_digit: "Symbol.symbol -> bool"} \\
163.485 - @{index_ML Symbol.is_quasi: "Symbol.symbol -> bool"} \\
163.486 - @{index_ML Symbol.is_blank: "Symbol.symbol -> bool"} \\
163.487 - \end{mldecls}
163.488 - \begin{mldecls}
163.489 - @{index_ML_type "Symbol.sym"} \\
163.490 - @{index_ML Symbol.decode: "Symbol.symbol -> Symbol.sym"} \\
163.491 - \end{mldecls}
163.492 -
163.493 - \begin{description}
163.494 -
163.495 - \item @{ML_type "Symbol.symbol"} represents individual Isabelle
163.496 - symbols; this is an alias for @{ML_type "string"}.
163.497 -
163.498 - \item @{ML "Symbol.explode"}~@{text "str"} produces a symbol list
163.499 - from the packed form. This function supercedes @{ML
163.500 - "String.explode"} for virtually all purposes of manipulating text in
163.501 - Isabelle!
163.502 -
163.503 - \item @{ML "Symbol.is_letter"}, @{ML "Symbol.is_digit"}, @{ML
163.504 - "Symbol.is_quasi"}, @{ML "Symbol.is_blank"} classify standard
163.505 - symbols according to fixed syntactic conventions of Isabelle, cf.\
163.506 - \cite{isabelle-isar-ref}.
163.507 -
163.508 - \item @{ML_type "Symbol.sym"} is a concrete datatype that represents
163.509 - the different kinds of symbols explicitly, with constructors @{ML
163.510 - "Symbol.Char"}, @{ML "Symbol.Sym"}, @{ML "Symbol.Ctrl"}, @{ML
163.511 - "Symbol.Raw"}.
163.512 -
163.513 - \item @{ML "Symbol.decode"} converts the string representation of a
163.514 - symbol into the datatype version.
163.515 -
163.516 - \end{description}
163.517 -*}
163.518 -
163.519 -
163.520 -subsection {* Basic names \label{sec:basic-names} *}
163.521 -
163.522 -text {*
163.523 - A \emph{basic name} essentially consists of a single Isabelle
163.524 - identifier. There are conventions to mark separate classes of basic
163.525 - names, by attaching a suffix of underscores (@{text "_"}): one
163.526 - underscore means \emph{internal name}, two underscores means
163.527 - \emph{Skolem name}, three underscores means \emph{internal Skolem
163.528 - name}.
163.529 -
163.530 - For example, the basic name @{text "foo"} has the internal version
163.531 - @{text "foo_"}, with Skolem versions @{text "foo__"} and @{text
163.532 - "foo___"}, respectively.
163.533 -
163.534 - These special versions provide copies of the basic name space, apart
163.535 - from anything that normally appears in the user text. For example,
163.536 - system generated variables in Isar proof contexts are usually marked
163.537 - as internal, which prevents mysterious name references like @{text
163.538 - "xaa"} to appear in the text.
163.539 -
163.540 - \medskip Manipulating binding scopes often requires on-the-fly
163.541 - renamings. A \emph{name context} contains a collection of already
163.542 - used names. The @{text "declare"} operation adds names to the
163.543 - context.
163.544 -
163.545 - The @{text "invents"} operation derives a number of fresh names from
163.546 - a given starting point. For example, the first three names derived
163.547 - from @{text "a"} are @{text "a"}, @{text "b"}, @{text "c"}.
163.548 -
163.549 - The @{text "variants"} operation produces fresh names by
163.550 - incrementing tentative names as base-26 numbers (with digits @{text
163.551 - "a..z"}) until all clashes are resolved. For example, name @{text
163.552 - "foo"} results in variants @{text "fooa"}, @{text "foob"}, @{text
163.553 - "fooc"}, \dots, @{text "fooaa"}, @{text "fooab"} etc.; each renaming
163.554 - step picks the next unused variant from this sequence.
163.555 -*}
163.556 -
163.557 -text %mlref {*
163.558 - \begin{mldecls}
163.559 - @{index_ML Name.internal: "string -> string"} \\
163.560 - @{index_ML Name.skolem: "string -> string"} \\
163.561 - \end{mldecls}
163.562 - \begin{mldecls}
163.563 - @{index_ML_type Name.context} \\
163.564 - @{index_ML Name.context: Name.context} \\
163.565 - @{index_ML Name.declare: "string -> Name.context -> Name.context"} \\
163.566 - @{index_ML Name.invents: "Name.context -> string -> int -> string list"} \\
163.567 - @{index_ML Name.variants: "string list -> Name.context -> string list * Name.context"} \\
163.568 - \end{mldecls}
163.569 -
163.570 - \begin{description}
163.571 -
163.572 - \item @{ML Name.internal}~@{text "name"} produces an internal name
163.573 - by adding one underscore.
163.574 -
163.575 - \item @{ML Name.skolem}~@{text "name"} produces a Skolem name by
163.576 - adding two underscores.
163.577 -
163.578 - \item @{ML_type Name.context} represents the context of already used
163.579 - names; the initial value is @{ML "Name.context"}.
163.580 -
163.581 - \item @{ML Name.declare}~@{text "name"} enters a used name into the
163.582 - context.
163.583 -
163.584 - \item @{ML Name.invents}~@{text "context name n"} produces @{text
163.585 - "n"} fresh names derived from @{text "name"}.
163.586 -
163.587 - \item @{ML Name.variants}~@{text "names context"} produces fresh
163.588 - varians of @{text "names"}; the result is entered into the context.
163.589 -
163.590 - \end{description}
163.591 -*}
163.592 -
163.593 -
163.594 -subsection {* Indexed names *}
163.595 -
163.596 -text {*
163.597 - An \emph{indexed name} (or @{text "indexname"}) is a pair of a basic
163.598 - name and a natural number. This representation allows efficient
163.599 - renaming by incrementing the second component only. The canonical
163.600 - way to rename two collections of indexnames apart from each other is
163.601 - this: determine the maximum index @{text "maxidx"} of the first
163.602 - collection, then increment all indexes of the second collection by
163.603 - @{text "maxidx + 1"}; the maximum index of an empty collection is
163.604 - @{text "-1"}.
163.605 -
163.606 - Occasionally, basic names and indexed names are injected into the
163.607 - same pair type: the (improper) indexname @{text "(x, -1)"} is used
163.608 - to encode basic names.
163.609 -
163.610 - \medskip Isabelle syntax observes the following rules for
163.611 - representing an indexname @{text "(x, i)"} as a packed string:
163.612 -
163.613 - \begin{itemize}
163.614 -
163.615 - \item @{text "?x"} if @{text "x"} does not end with a digit and @{text "i = 0"},
163.616 -
163.617 - \item @{text "?xi"} if @{text "x"} does not end with a digit,
163.618 -
163.619 - \item @{text "?x.i"} otherwise.
163.620 -
163.621 - \end{itemize}
163.622 -
163.623 - Indexnames may acquire large index numbers over time. Results are
163.624 - normalized towards @{text "0"} at certain checkpoints, notably at
163.625 - the end of a proof. This works by producing variants of the
163.626 - corresponding basic name components. For example, the collection
163.627 - @{text "?x1, ?x7, ?x42"} becomes @{text "?x, ?xa, ?xb"}.
163.628 -*}
163.629 -
163.630 -text %mlref {*
163.631 - \begin{mldecls}
163.632 - @{index_ML_type indexname} \\
163.633 - \end{mldecls}
163.634 -
163.635 - \begin{description}
163.636 -
163.637 - \item @{ML_type indexname} represents indexed names. This is an
163.638 - abbreviation for @{ML_type "string * int"}. The second component is
163.639 - usually non-negative, except for situations where @{text "(x, -1)"}
163.640 - is used to embed basic names into this type.
163.641 -
163.642 - \end{description}
163.643 -*}
163.644 -
163.645 -
163.646 -subsection {* Qualified names and name spaces *}
163.647 -
163.648 -text {*
163.649 - A \emph{qualified name} consists of a non-empty sequence of basic
163.650 - name components. The packed representation uses a dot as separator,
163.651 - as in ``@{text "A.b.c"}''. The last component is called \emph{base}
163.652 - name, the remaining prefix \emph{qualifier} (which may be empty).
163.653 - The idea of qualified names is to encode nested structures by
163.654 - recording the access paths as qualifiers. For example, an item
163.655 - named ``@{text "A.b.c"}'' may be understood as a local entity @{text
163.656 - "c"}, within a local structure @{text "b"}, within a global
163.657 - structure @{text "A"}. Typically, name space hierarchies consist of
163.658 - 1--2 levels of qualification, but this need not be always so.
163.659 -
163.660 - The empty name is commonly used as an indication of unnamed
163.661 - entities, whenever this makes any sense. The basic operations on
163.662 - qualified names are smart enough to pass through such improper names
163.663 - unchanged.
163.664 -
163.665 - \medskip A @{text "naming"} policy tells how to turn a name
163.666 - specification into a fully qualified internal name (by the @{text
163.667 - "full"} operation), and how fully qualified names may be accessed
163.668 - externally. For example, the default naming policy is to prefix an
163.669 - implicit path: @{text "full x"} produces @{text "path.x"}, and the
163.670 - standard accesses for @{text "path.x"} include both @{text "x"} and
163.671 - @{text "path.x"}. Normally, the naming is implicit in the theory or
163.672 - proof context; there are separate versions of the corresponding.
163.673 -
163.674 - \medskip A @{text "name space"} manages a collection of fully
163.675 - internalized names, together with a mapping between external names
163.676 - and internal names (in both directions). The corresponding @{text
163.677 - "intern"} and @{text "extern"} operations are mostly used for
163.678 - parsing and printing only! The @{text "declare"} operation augments
163.679 - a name space according to the accesses determined by the naming
163.680 - policy.
163.681 -
163.682 - \medskip As a general principle, there is a separate name space for
163.683 - each kind of formal entity, e.g.\ logical constant, type
163.684 - constructor, type class, theorem. It is usually clear from the
163.685 - occurrence in concrete syntax (or from the scope) which kind of
163.686 - entity a name refers to. For example, the very same name @{text
163.687 - "c"} may be used uniformly for a constant, type constructor, and
163.688 - type class.
163.689 -
163.690 - There are common schemes to name theorems systematically, according
163.691 - to the name of the main logical entity involved, e.g.\ @{text
163.692 - "c.intro"} for a canonical theorem related to constant @{text "c"}.
163.693 - This technique of mapping names from one space into another requires
163.694 - some care in order to avoid conflicts. In particular, theorem names
163.695 - derived from a type constructor or type class are better suffixed in
163.696 - addition to the usual qualification, e.g.\ @{text "c_type.intro"}
163.697 - and @{text "c_class.intro"} for theorems related to type @{text "c"}
163.698 - and class @{text "c"}, respectively.
163.699 -*}
163.700 -
163.701 -text %mlref {*
163.702 - \begin{mldecls}
163.703 - @{index_ML NameSpace.base: "string -> string"} \\
163.704 - @{index_ML NameSpace.qualifier: "string -> string"} \\
163.705 - @{index_ML NameSpace.append: "string -> string -> string"} \\
163.706 - @{index_ML NameSpace.implode: "string list -> string"} \\
163.707 - @{index_ML NameSpace.explode: "string -> string list"} \\
163.708 - \end{mldecls}
163.709 - \begin{mldecls}
163.710 - @{index_ML_type NameSpace.naming} \\
163.711 - @{index_ML NameSpace.default_naming: NameSpace.naming} \\
163.712 - @{index_ML NameSpace.add_path: "string -> NameSpace.naming -> NameSpace.naming"} \\
163.713 - @{index_ML NameSpace.full_name: "NameSpace.naming -> binding -> string"} \\
163.714 - \end{mldecls}
163.715 - \begin{mldecls}
163.716 - @{index_ML_type NameSpace.T} \\
163.717 - @{index_ML NameSpace.empty: NameSpace.T} \\
163.718 - @{index_ML NameSpace.merge: "NameSpace.T * NameSpace.T -> NameSpace.T"} \\
163.719 - @{index_ML NameSpace.declare: "NameSpace.naming -> binding -> NameSpace.T -> string * NameSpace.T"} \\
163.720 - @{index_ML NameSpace.intern: "NameSpace.T -> string -> string"} \\
163.721 - @{index_ML NameSpace.extern: "NameSpace.T -> string -> string"} \\
163.722 - \end{mldecls}
163.723 -
163.724 - \begin{description}
163.725 -
163.726 - \item @{ML NameSpace.base}~@{text "name"} returns the base name of a
163.727 - qualified name.
163.728 -
163.729 - \item @{ML NameSpace.qualifier}~@{text "name"} returns the qualifier
163.730 - of a qualified name.
163.731 -
163.732 - \item @{ML NameSpace.append}~@{text "name\<^isub>1 name\<^isub>2"}
163.733 - appends two qualified names.
163.734 -
163.735 - \item @{ML NameSpace.implode}~@{text "name"} and @{ML
163.736 - NameSpace.explode}~@{text "names"} convert between the packed string
163.737 - representation and the explicit list form of qualified names.
163.738 -
163.739 - \item @{ML_type NameSpace.naming} represents the abstract concept of
163.740 - a naming policy.
163.741 -
163.742 - \item @{ML NameSpace.default_naming} is the default naming policy.
163.743 - In a theory context, this is usually augmented by a path prefix
163.744 - consisting of the theory name.
163.745 -
163.746 - \item @{ML NameSpace.add_path}~@{text "path naming"} augments the
163.747 - naming policy by extending its path component.
163.748 -
163.749 - \item @{ML NameSpace.full_name}@{text "naming binding"} turns a name
163.750 - binding (usually a basic name) into the fully qualified
163.751 - internal name, according to the given naming policy.
163.752 -
163.753 - \item @{ML_type NameSpace.T} represents name spaces.
163.754 -
163.755 - \item @{ML NameSpace.empty} and @{ML NameSpace.merge}~@{text
163.756 - "(space\<^isub>1, space\<^isub>2)"} are the canonical operations for
163.757 - maintaining name spaces according to theory data management
163.758 - (\secref{sec:context-data}).
163.759 -
163.760 - \item @{ML NameSpace.declare}~@{text "naming bindings space"} enters a
163.761 - name binding as fully qualified internal name into the name space,
163.762 - with external accesses determined by the naming policy.
163.763 -
163.764 - \item @{ML NameSpace.intern}~@{text "space name"} internalizes a
163.765 - (partially qualified) external name.
163.766 -
163.767 - This operation is mostly for parsing! Note that fully qualified
163.768 - names stemming from declarations are produced via @{ML
163.769 - "NameSpace.full_name"} and @{ML "NameSpace.declare"}
163.770 - (or their derivatives for @{ML_type theory} and
163.771 - @{ML_type Proof.context}).
163.772 -
163.773 - \item @{ML NameSpace.extern}~@{text "space name"} externalizes a
163.774 - (fully qualified) internal name.
163.775 -
163.776 - This operation is mostly for printing! Note unqualified names are
163.777 - produced via @{ML NameSpace.base}.
163.778 -
163.779 - \end{description}
163.780 -*}
163.781 -
163.782 -end
164.1 --- a/doc-src/IsarImplementation/Thy/proof.thy Wed Mar 04 11:05:02 2009 +0100
164.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
164.3 @@ -1,332 +0,0 @@
164.4 -
164.5 -(* $Id$ *)
164.6 -
164.7 -theory "proof" imports base begin
164.8 -
164.9 -chapter {* Structured proofs *}
164.10 -
164.11 -section {* Variables \label{sec:variables} *}
164.12 -
164.13 -text {*
164.14 - Any variable that is not explicitly bound by @{text "\<lambda>"}-abstraction
164.15 - is considered as ``free''. Logically, free variables act like
164.16 - outermost universal quantification at the sequent level: @{text
164.17 - "A\<^isub>1(x), \<dots>, A\<^isub>n(x) \<turnstile> B(x)"} means that the result
164.18 - holds \emph{for all} values of @{text "x"}. Free variables for
164.19 - terms (not types) can be fully internalized into the logic: @{text
164.20 - "\<turnstile> B(x)"} and @{text "\<turnstile> \<And>x. B(x)"} are interchangeable, provided
164.21 - that @{text "x"} does not occur elsewhere in the context.
164.22 - Inspecting @{text "\<turnstile> \<And>x. B(x)"} more closely, we see that inside the
164.23 - quantifier, @{text "x"} is essentially ``arbitrary, but fixed'',
164.24 - while from outside it appears as a place-holder for instantiation
164.25 - (thanks to @{text "\<And>"} elimination).
164.26 -
164.27 - The Pure logic represents the idea of variables being either inside
164.28 - or outside the current scope by providing separate syntactic
164.29 - categories for \emph{fixed variables} (e.g.\ @{text "x"}) vs.\
164.30 - \emph{schematic variables} (e.g.\ @{text "?x"}). Incidently, a
164.31 - universal result @{text "\<turnstile> \<And>x. B(x)"} has the HHF normal form @{text
164.32 - "\<turnstile> B(?x)"}, which represents its generality nicely without requiring
164.33 - an explicit quantifier. The same principle works for type
164.34 - variables: @{text "\<turnstile> B(?\<alpha>)"} represents the idea of ``@{text "\<turnstile>
164.35 - \<forall>\<alpha>. B(\<alpha>)"}'' without demanding a truly polymorphic framework.
164.36 -
164.37 - \medskip Additional care is required to treat type variables in a
164.38 - way that facilitates type-inference. In principle, term variables
164.39 - depend on type variables, which means that type variables would have
164.40 - to be declared first. For example, a raw type-theoretic framework
164.41 - would demand the context to be constructed in stages as follows:
164.42 - @{text "\<Gamma> = \<alpha>: type, x: \<alpha>, a: A(x\<^isub>\<alpha>)"}.
164.43 -
164.44 - We allow a slightly less formalistic mode of operation: term
164.45 - variables @{text "x"} are fixed without specifying a type yet
164.46 - (essentially \emph{all} potential occurrences of some instance
164.47 - @{text "x\<^isub>\<tau>"} are fixed); the first occurrence of @{text "x"}
164.48 - within a specific term assigns its most general type, which is then
164.49 - maintained consistently in the context. The above example becomes
164.50 - @{text "\<Gamma> = x: term, \<alpha>: type, A(x\<^isub>\<alpha>)"}, where type @{text
164.51 - "\<alpha>"} is fixed \emph{after} term @{text "x"}, and the constraint
164.52 - @{text "x :: \<alpha>"} is an implicit consequence of the occurrence of
164.53 - @{text "x\<^isub>\<alpha>"} in the subsequent proposition.
164.54 -
164.55 - This twist of dependencies is also accommodated by the reverse
164.56 - operation of exporting results from a context: a type variable
164.57 - @{text "\<alpha>"} is considered fixed as long as it occurs in some fixed
164.58 - term variable of the context. For example, exporting @{text "x:
164.59 - term, \<alpha>: type \<turnstile> x\<^isub>\<alpha> = x\<^isub>\<alpha>"} produces in the first step
164.60 - @{text "x: term \<turnstile> x\<^isub>\<alpha> = x\<^isub>\<alpha>"} for fixed @{text "\<alpha>"},
164.61 - and only in the second step @{text "\<turnstile> ?x\<^isub>?\<^isub>\<alpha> =
164.62 - ?x\<^isub>?\<^isub>\<alpha>"} for schematic @{text "?x"} and @{text "?\<alpha>"}.
164.63 -
164.64 - \medskip The Isabelle/Isar proof context manages the gory details of
164.65 - term vs.\ type variables, with high-level principles for moving the
164.66 - frontier between fixed and schematic variables.
164.67 -
164.68 - The @{text "add_fixes"} operation explictly declares fixed
164.69 - variables; the @{text "declare_term"} operation absorbs a term into
164.70 - a context by fixing new type variables and adding syntactic
164.71 - constraints.
164.72 -
164.73 - The @{text "export"} operation is able to perform the main work of
164.74 - generalizing term and type variables as sketched above, assuming
164.75 - that fixing variables and terms have been declared properly.
164.76 -
164.77 - There @{text "import"} operation makes a generalized fact a genuine
164.78 - part of the context, by inventing fixed variables for the schematic
164.79 - ones. The effect can be reversed by using @{text "export"} later,
164.80 - potentially with an extended context; the result is equivalent to
164.81 - the original modulo renaming of schematic variables.
164.82 -
164.83 - The @{text "focus"} operation provides a variant of @{text "import"}
164.84 - for nested propositions (with explicit quantification): @{text
164.85 - "\<And>x\<^isub>1 \<dots> x\<^isub>n. B(x\<^isub>1, \<dots>, x\<^isub>n)"} is
164.86 - decomposed by inventing fixed variables @{text "x\<^isub>1, \<dots>,
164.87 - x\<^isub>n"} for the body.
164.88 -*}
164.89 -
164.90 -text %mlref {*
164.91 - \begin{mldecls}
164.92 - @{index_ML Variable.add_fixes: "
164.93 - string list -> Proof.context -> string list * Proof.context"} \\
164.94 - @{index_ML Variable.variant_fixes: "
164.95 - string list -> Proof.context -> string list * Proof.context"} \\
164.96 - @{index_ML Variable.declare_term: "term -> Proof.context -> Proof.context"} \\
164.97 - @{index_ML Variable.declare_constraints: "term -> Proof.context -> Proof.context"} \\
164.98 - @{index_ML Variable.export: "Proof.context -> Proof.context -> thm list -> thm list"} \\
164.99 - @{index_ML Variable.polymorphic: "Proof.context -> term list -> term list"} \\
164.100 - @{index_ML Variable.import_thms: "bool -> thm list -> Proof.context ->
164.101 - ((ctyp list * cterm list) * thm list) * Proof.context"} \\
164.102 - @{index_ML Variable.focus: "cterm -> Proof.context -> (cterm list * cterm) * Proof.context"} \\
164.103 - \end{mldecls}
164.104 -
164.105 - \begin{description}
164.106 -
164.107 - \item @{ML Variable.add_fixes}~@{text "xs ctxt"} fixes term
164.108 - variables @{text "xs"}, returning the resulting internal names. By
164.109 - default, the internal representation coincides with the external
164.110 - one, which also means that the given variables must not be fixed
164.111 - already. There is a different policy within a local proof body: the
164.112 - given names are just hints for newly invented Skolem variables.
164.113 -
164.114 - \item @{ML Variable.variant_fixes} is similar to @{ML
164.115 - Variable.add_fixes}, but always produces fresh variants of the given
164.116 - names.
164.117 -
164.118 - \item @{ML Variable.declare_term}~@{text "t ctxt"} declares term
164.119 - @{text "t"} to belong to the context. This automatically fixes new
164.120 - type variables, but not term variables. Syntactic constraints for
164.121 - type and term variables are declared uniformly, though.
164.122 -
164.123 - \item @{ML Variable.declare_constraints}~@{text "t ctxt"} declares
164.124 - syntactic constraints from term @{text "t"}, without making it part
164.125 - of the context yet.
164.126 -
164.127 - \item @{ML Variable.export}~@{text "inner outer thms"} generalizes
164.128 - fixed type and term variables in @{text "thms"} according to the
164.129 - difference of the @{text "inner"} and @{text "outer"} context,
164.130 - following the principles sketched above.
164.131 -
164.132 - \item @{ML Variable.polymorphic}~@{text "ctxt ts"} generalizes type
164.133 - variables in @{text "ts"} as far as possible, even those occurring
164.134 - in fixed term variables. The default policy of type-inference is to
164.135 - fix newly introduced type variables, which is essentially reversed
164.136 - with @{ML Variable.polymorphic}: here the given terms are detached
164.137 - from the context as far as possible.
164.138 -
164.139 - \item @{ML Variable.import_thms}~@{text "open thms ctxt"} invents fixed
164.140 - type and term variables for the schematic ones occurring in @{text
164.141 - "thms"}. The @{text "open"} flag indicates whether the fixed names
164.142 - should be accessible to the user, otherwise newly introduced names
164.143 - are marked as ``internal'' (\secref{sec:names}).
164.144 -
164.145 - \item @{ML Variable.focus}~@{text B} decomposes the outermost @{text
164.146 - "\<And>"} prefix of proposition @{text "B"}.
164.147 -
164.148 - \end{description}
164.149 -*}
164.150 -
164.151 -
164.152 -section {* Assumptions \label{sec:assumptions} *}
164.153 -
164.154 -text {*
164.155 - An \emph{assumption} is a proposition that it is postulated in the
164.156 - current context. Local conclusions may use assumptions as
164.157 - additional facts, but this imposes implicit hypotheses that weaken
164.158 - the overall statement.
164.159 -
164.160 - Assumptions are restricted to fixed non-schematic statements, i.e.\
164.161 - all generality needs to be expressed by explicit quantifiers.
164.162 - Nevertheless, the result will be in HHF normal form with outermost
164.163 - quantifiers stripped. For example, by assuming @{text "\<And>x :: \<alpha>. P
164.164 - x"} we get @{text "\<And>x :: \<alpha>. P x \<turnstile> P ?x"} for schematic @{text "?x"}
164.165 - of fixed type @{text "\<alpha>"}. Local derivations accumulate more and
164.166 - more explicit references to hypotheses: @{text "A\<^isub>1, \<dots>,
164.167 - A\<^isub>n \<turnstile> B"} where @{text "A\<^isub>1, \<dots>, A\<^isub>n"} needs to
164.168 - be covered by the assumptions of the current context.
164.169 -
164.170 - \medskip The @{text "add_assms"} operation augments the context by
164.171 - local assumptions, which are parameterized by an arbitrary @{text
164.172 - "export"} rule (see below).
164.173 -
164.174 - The @{text "export"} operation moves facts from a (larger) inner
164.175 - context into a (smaller) outer context, by discharging the
164.176 - difference of the assumptions as specified by the associated export
164.177 - rules. Note that the discharged portion is determined by the
164.178 - difference contexts, not the facts being exported! There is a
164.179 - separate flag to indicate a goal context, where the result is meant
164.180 - to refine an enclosing sub-goal of a structured proof state (cf.\
164.181 - \secref{sec:isar-proof-state}).
164.182 -
164.183 - \medskip The most basic export rule discharges assumptions directly
164.184 - by means of the @{text "\<Longrightarrow>"} introduction rule:
164.185 - \[
164.186 - \infer[(@{text "\<Longrightarrow>_intro"})]{@{text "\<Gamma> \\ A \<turnstile> A \<Longrightarrow> B"}}{@{text "\<Gamma> \<turnstile> B"}}
164.187 - \]
164.188 -
164.189 - The variant for goal refinements marks the newly introduced
164.190 - premises, which causes the canonical Isar goal refinement scheme to
164.191 - enforce unification with local premises within the goal:
164.192 - \[
164.193 - \infer[(@{text "#\<Longrightarrow>_intro"})]{@{text "\<Gamma> \\ A \<turnstile> #A \<Longrightarrow> B"}}{@{text "\<Gamma> \<turnstile> B"}}
164.194 - \]
164.195 -
164.196 - \medskip Alternative versions of assumptions may perform arbitrary
164.197 - transformations on export, as long as the corresponding portion of
164.198 - hypotheses is removed from the given facts. For example, a local
164.199 - definition works by fixing @{text "x"} and assuming @{text "x \<equiv> t"},
164.200 - with the following export rule to reverse the effect:
164.201 - \[
164.202 - \infer[(@{text "\<equiv>-expand"})]{@{text "\<Gamma> \\ x \<equiv> t \<turnstile> B t"}}{@{text "\<Gamma> \<turnstile> B x"}}
164.203 - \]
164.204 - This works, because the assumption @{text "x \<equiv> t"} was introduced in
164.205 - a context with @{text "x"} being fresh, so @{text "x"} does not
164.206 - occur in @{text "\<Gamma>"} here.
164.207 -*}
164.208 -
164.209 -text %mlref {*
164.210 - \begin{mldecls}
164.211 - @{index_ML_type Assumption.export} \\
164.212 - @{index_ML Assumption.assume: "cterm -> thm"} \\
164.213 - @{index_ML Assumption.add_assms:
164.214 - "Assumption.export ->
164.215 - cterm list -> Proof.context -> thm list * Proof.context"} \\
164.216 - @{index_ML Assumption.add_assumes: "
164.217 - cterm list -> Proof.context -> thm list * Proof.context"} \\
164.218 - @{index_ML Assumption.export: "bool -> Proof.context -> Proof.context -> thm -> thm"} \\
164.219 - \end{mldecls}
164.220 -
164.221 - \begin{description}
164.222 -
164.223 - \item @{ML_type Assumption.export} represents arbitrary export
164.224 - rules, which is any function of type @{ML_type "bool -> cterm list -> thm -> thm"},
164.225 - where the @{ML_type "bool"} indicates goal mode, and the @{ML_type
164.226 - "cterm list"} the collection of assumptions to be discharged
164.227 - simultaneously.
164.228 -
164.229 - \item @{ML Assumption.assume}~@{text "A"} turns proposition @{text
164.230 - "A"} into a raw assumption @{text "A \<turnstile> A'"}, where the conclusion
164.231 - @{text "A'"} is in HHF normal form.
164.232 -
164.233 - \item @{ML Assumption.add_assms}~@{text "r As"} augments the context
164.234 - by assumptions @{text "As"} with export rule @{text "r"}. The
164.235 - resulting facts are hypothetical theorems as produced by the raw
164.236 - @{ML Assumption.assume}.
164.237 -
164.238 - \item @{ML Assumption.add_assumes}~@{text "As"} is a special case of
164.239 - @{ML Assumption.add_assms} where the export rule performs @{text
164.240 - "\<Longrightarrow>_intro"} or @{text "#\<Longrightarrow>_intro"}, depending on goal mode.
164.241 -
164.242 - \item @{ML Assumption.export}~@{text "is_goal inner outer thm"}
164.243 - exports result @{text "thm"} from the the @{text "inner"} context
164.244 - back into the @{text "outer"} one; @{text "is_goal = true"} means
164.245 - this is a goal context. The result is in HHF normal form. Note
164.246 - that @{ML "ProofContext.export"} combines @{ML "Variable.export"}
164.247 - and @{ML "Assumption.export"} in the canonical way.
164.248 -
164.249 - \end{description}
164.250 -*}
164.251 -
164.252 -
164.253 -section {* Results \label{sec:results} *}
164.254 -
164.255 -text {*
164.256 - Local results are established by monotonic reasoning from facts
164.257 - within a context. This allows common combinations of theorems,
164.258 - e.g.\ via @{text "\<And>/\<Longrightarrow>"} elimination, resolution rules, or equational
164.259 - reasoning, see \secref{sec:thms}. Unaccounted context manipulations
164.260 - should be avoided, notably raw @{text "\<And>/\<Longrightarrow>"} introduction or ad-hoc
164.261 - references to free variables or assumptions not present in the proof
164.262 - context.
164.263 -
164.264 - \medskip The @{text "SUBPROOF"} combinator allows to structure a
164.265 - tactical proof recursively by decomposing a selected sub-goal:
164.266 - @{text "(\<And>x. A(x) \<Longrightarrow> B(x)) \<Longrightarrow> \<dots>"} is turned into @{text "B(x) \<Longrightarrow> \<dots>"}
164.267 - after fixing @{text "x"} and assuming @{text "A(x)"}. This means
164.268 - the tactic needs to solve the conclusion, but may use the premise as
164.269 - a local fact, for locally fixed variables.
164.270 -
164.271 - The @{text "prove"} operation provides an interface for structured
164.272 - backwards reasoning under program control, with some explicit sanity
164.273 - checks of the result. The goal context can be augmented by
164.274 - additional fixed variables (cf.\ \secref{sec:variables}) and
164.275 - assumptions (cf.\ \secref{sec:assumptions}), which will be available
164.276 - as local facts during the proof and discharged into implications in
164.277 - the result. Type and term variables are generalized as usual,
164.278 - according to the context.
164.279 -
164.280 - The @{text "obtain"} operation produces results by eliminating
164.281 - existing facts by means of a given tactic. This acts like a dual
164.282 - conclusion: the proof demonstrates that the context may be augmented
164.283 - by certain fixed variables and assumptions. See also
164.284 - \cite{isabelle-isar-ref} for the user-level @{text "\<OBTAIN>"} and
164.285 - @{text "\<GUESS>"} elements. Final results, which may not refer to
164.286 - the parameters in the conclusion, need to exported explicitly into
164.287 - the original context.
164.288 -*}
164.289 -
164.290 -text %mlref {*
164.291 - \begin{mldecls}
164.292 - @{index_ML SUBPROOF:
164.293 - "({context: Proof.context, schematics: ctyp list * cterm list,
164.294 - params: cterm list, asms: cterm list, concl: cterm,
164.295 - prems: thm list} -> tactic) -> Proof.context -> int -> tactic"} \\
164.296 - \end{mldecls}
164.297 - \begin{mldecls}
164.298 - @{index_ML Goal.prove: "Proof.context -> string list -> term list -> term ->
164.299 - ({prems: thm list, context: Proof.context} -> tactic) -> thm"} \\
164.300 - @{index_ML Goal.prove_multi: "Proof.context -> string list -> term list -> term list ->
164.301 - ({prems: thm list, context: Proof.context} -> tactic) -> thm list"} \\
164.302 - \end{mldecls}
164.303 - \begin{mldecls}
164.304 - @{index_ML Obtain.result: "(Proof.context -> tactic) ->
164.305 - thm list -> Proof.context -> (cterm list * thm list) * Proof.context"} \\
164.306 - \end{mldecls}
164.307 -
164.308 - \begin{description}
164.309 -
164.310 - \item @{ML SUBPROOF}~@{text "tac"} decomposes the structure of a
164.311 - particular sub-goal, producing an extended context and a reduced
164.312 - goal, which needs to be solved by the given tactic. All schematic
164.313 - parameters of the goal are imported into the context as fixed ones,
164.314 - which may not be instantiated in the sub-proof.
164.315 -
164.316 - \item @{ML Goal.prove}~@{text "ctxt xs As C tac"} states goal @{text
164.317 - "C"} in the context augmented by fixed variables @{text "xs"} and
164.318 - assumptions @{text "As"}, and applies tactic @{text "tac"} to solve
164.319 - it. The latter may depend on the local assumptions being presented
164.320 - as facts. The result is in HHF normal form.
164.321 -
164.322 - \item @{ML Goal.prove_multi} is simular to @{ML Goal.prove}, but
164.323 - states several conclusions simultaneously. The goal is encoded by
164.324 - means of Pure conjunction; @{ML Goal.conjunction_tac} will turn this
164.325 - into a collection of individual subgoals.
164.326 -
164.327 - \item @{ML Obtain.result}~@{text "tac thms ctxt"} eliminates the
164.328 - given facts using a tactic, which results in additional fixed
164.329 - variables and assumptions in the context. Final results need to be
164.330 - exported explicitly.
164.331 -
164.332 - \end{description}
164.333 -*}
164.334 -
164.335 -end
165.1 --- a/doc-src/IsarImplementation/Thy/tactic.thy Wed Mar 04 11:05:02 2009 +0100
165.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
165.3 @@ -1,420 +0,0 @@
165.4 -
165.5 -(* $Id$ *)
165.6 -
165.7 -theory tactic imports base begin
165.8 -
165.9 -chapter {* Tactical reasoning *}
165.10 -
165.11 -text {*
165.12 - Tactical reasoning works by refining the initial claim in a
165.13 - backwards fashion, until a solved form is reached. A @{text "goal"}
165.14 - consists of several subgoals that need to be solved in order to
165.15 - achieve the main statement; zero subgoals means that the proof may
165.16 - be finished. A @{text "tactic"} is a refinement operation that maps
165.17 - a goal to a lazy sequence of potential successors. A @{text
165.18 - "tactical"} is a combinator for composing tactics.
165.19 -*}
165.20 -
165.21 -
165.22 -section {* Goals \label{sec:tactical-goals} *}
165.23 -
165.24 -text {*
165.25 - Isabelle/Pure represents a goal\glossary{Tactical goal}{A theorem of
165.26 - \seeglossary{Horn Clause} form stating that a number of subgoals
165.27 - imply the main conclusion, which is marked as a protected
165.28 - proposition.} as a theorem stating that the subgoals imply the main
165.29 - goal: @{text "A\<^sub>1 \<Longrightarrow> \<dots> \<Longrightarrow> A\<^sub>n \<Longrightarrow> C"}. The outermost goal
165.30 - structure is that of a Horn Clause\glossary{Horn Clause}{An iterated
165.31 - implication @{text "A\<^sub>1 \<Longrightarrow> \<dots> \<Longrightarrow> A\<^sub>n \<Longrightarrow> C"}, without any
165.32 - outermost quantifiers. Strictly speaking, propositions @{text
165.33 - "A\<^sub>i"} need to be atomic in Horn Clauses, but Isabelle admits
165.34 - arbitrary substructure here (nested @{text "\<Longrightarrow>"} and @{text "\<And>"}
165.35 - connectives).}: i.e.\ an iterated implication without any
165.36 - quantifiers\footnote{Recall that outermost @{text "\<And>x. \<phi>[x]"} is
165.37 - always represented via schematic variables in the body: @{text
165.38 - "\<phi>[?x]"}. These variables may get instantiated during the course of
165.39 - reasoning.}. For @{text "n = 0"} a goal is called ``solved''.
165.40 -
165.41 - The structure of each subgoal @{text "A\<^sub>i"} is that of a general
165.42 - Hereditary Harrop Formula @{text "\<And>x\<^sub>1 \<dots> \<And>x\<^sub>k. H\<^sub>1 \<Longrightarrow> \<dots> \<Longrightarrow> H\<^sub>m \<Longrightarrow> B"} in
165.43 - normal form. Here @{text "x\<^sub>1, \<dots>, x\<^sub>k"} are goal parameters, i.e.\
165.44 - arbitrary-but-fixed entities of certain types, and @{text "H\<^sub>1, \<dots>,
165.45 - H\<^sub>m"} are goal hypotheses, i.e.\ facts that may be assumed locally.
165.46 - Together, this forms the goal context of the conclusion @{text B} to
165.47 - be established. The goal hypotheses may be again arbitrary
165.48 - Hereditary Harrop Formulas, although the level of nesting rarely
165.49 - exceeds 1--2 in practice.
165.50 -
165.51 - The main conclusion @{text C} is internally marked as a protected
165.52 - proposition\glossary{Protected proposition}{An arbitrarily
165.53 - structured proposition @{text "C"} which is forced to appear as
165.54 - atomic by wrapping it into a propositional identity operator;
165.55 - notation @{text "#C"}. Protecting a proposition prevents basic
165.56 - inferences from entering into that structure for the time being.},
165.57 - which is represented explicitly by the notation @{text "#C"}. This
165.58 - ensures that the decomposition into subgoals and main conclusion is
165.59 - well-defined for arbitrarily structured claims.
165.60 -
165.61 - \medskip Basic goal management is performed via the following
165.62 - Isabelle/Pure rules:
165.63 -
165.64 - \[
165.65 - \infer[@{text "(init)"}]{@{text "C \<Longrightarrow> #C"}}{} \qquad
165.66 - \infer[@{text "(finish)"}]{@{text "C"}}{@{text "#C"}}
165.67 - \]
165.68 -
165.69 - \medskip The following low-level variants admit general reasoning
165.70 - with protected propositions:
165.71 -
165.72 - \[
165.73 - \infer[@{text "(protect)"}]{@{text "#C"}}{@{text "C"}} \qquad
165.74 - \infer[@{text "(conclude)"}]{@{text "A\<^sub>1 \<Longrightarrow> \<dots> \<Longrightarrow> A\<^sub>n \<Longrightarrow> C"}}{@{text "A\<^sub>1 \<Longrightarrow> \<dots> \<Longrightarrow> A\<^sub>n \<Longrightarrow> #C"}}
165.75 - \]
165.76 -*}
165.77 -
165.78 -text %mlref {*
165.79 - \begin{mldecls}
165.80 - @{index_ML Goal.init: "cterm -> thm"} \\
165.81 - @{index_ML Goal.finish: "thm -> thm"} \\
165.82 - @{index_ML Goal.protect: "thm -> thm"} \\
165.83 - @{index_ML Goal.conclude: "thm -> thm"} \\
165.84 - \end{mldecls}
165.85 -
165.86 - \begin{description}
165.87 -
165.88 - \item @{ML "Goal.init"}~@{text C} initializes a tactical goal from
165.89 - the well-formed proposition @{text C}.
165.90 -
165.91 - \item @{ML "Goal.finish"}~@{text "thm"} checks whether theorem
165.92 - @{text "thm"} is a solved goal (no subgoals), and concludes the
165.93 - result by removing the goal protection.
165.94 -
165.95 - \item @{ML "Goal.protect"}~@{text "thm"} protects the full statement
165.96 - of theorem @{text "thm"}.
165.97 -
165.98 - \item @{ML "Goal.conclude"}~@{text "thm"} removes the goal
165.99 - protection, even if there are pending subgoals.
165.100 -
165.101 - \end{description}
165.102 -*}
165.103 -
165.104 -
165.105 -section {* Tactics *}
165.106 -
165.107 -text {* A @{text "tactic"} is a function @{text "goal \<rightarrow> goal\<^sup>*\<^sup>*"} that
165.108 - maps a given goal state (represented as a theorem, cf.\
165.109 - \secref{sec:tactical-goals}) to a lazy sequence of potential
165.110 - successor states. The underlying sequence implementation is lazy
165.111 - both in head and tail, and is purely functional in \emph{not}
165.112 - supporting memoing.\footnote{The lack of memoing and the strict
165.113 - nature of SML requires some care when working with low-level
165.114 - sequence operations, to avoid duplicate or premature evaluation of
165.115 - results.}
165.116 -
165.117 - An \emph{empty result sequence} means that the tactic has failed: in
165.118 - a compound tactic expressions other tactics might be tried instead,
165.119 - or the whole refinement step might fail outright, producing a
165.120 - toplevel error message. When implementing tactics from scratch, one
165.121 - should take care to observe the basic protocol of mapping regular
165.122 - error conditions to an empty result; only serious faults should
165.123 - emerge as exceptions.
165.124 -
165.125 - By enumerating \emph{multiple results}, a tactic can easily express
165.126 - the potential outcome of an internal search process. There are also
165.127 - combinators for building proof tools that involve search
165.128 - systematically, see also \secref{sec:tacticals}.
165.129 -
165.130 - \medskip As explained in \secref{sec:tactical-goals}, a goal state
165.131 - essentially consists of a list of subgoals that imply the main goal
165.132 - (conclusion). Tactics may operate on all subgoals or on a
165.133 - particularly specified subgoal, but must not change the main
165.134 - conclusion (apart from instantiating schematic goal variables).
165.135 -
165.136 - Tactics with explicit \emph{subgoal addressing} are of the form
165.137 - @{text "int \<rightarrow> tactic"} and may be applied to a particular subgoal
165.138 - (counting from 1). If the subgoal number is out of range, the
165.139 - tactic should fail with an empty result sequence, but must not raise
165.140 - an exception!
165.141 -
165.142 - Operating on a particular subgoal means to replace it by an interval
165.143 - of zero or more subgoals in the same place; other subgoals must not
165.144 - be affected, apart from instantiating schematic variables ranging
165.145 - over the whole goal state.
165.146 -
165.147 - A common pattern of composing tactics with subgoal addressing is to
165.148 - try the first one, and then the second one only if the subgoal has
165.149 - not been solved yet. Special care is required here to avoid bumping
165.150 - into unrelated subgoals that happen to come after the original
165.151 - subgoal. Assuming that there is only a single initial subgoal is a
165.152 - very common error when implementing tactics!
165.153 -
165.154 - Tactics with internal subgoal addressing should expose the subgoal
165.155 - index as @{text "int"} argument in full generality; a hardwired
165.156 - subgoal 1 inappropriate.
165.157 -
165.158 - \medskip The main well-formedness conditions for proper tactics are
165.159 - summarized as follows.
165.160 -
165.161 - \begin{itemize}
165.162 -
165.163 - \item General tactic failure is indicated by an empty result, only
165.164 - serious faults may produce an exception.
165.165 -
165.166 - \item The main conclusion must not be changed, apart from
165.167 - instantiating schematic variables.
165.168 -
165.169 - \item A tactic operates either uniformly on all subgoals, or
165.170 - specifically on a selected subgoal (without bumping into unrelated
165.171 - subgoals).
165.172 -
165.173 - \item Range errors in subgoal addressing produce an empty result.
165.174 -
165.175 - \end{itemize}
165.176 -
165.177 - Some of these conditions are checked by higher-level goal
165.178 - infrastructure (\secref{sec:results}); others are not checked
165.179 - explicitly, and violating them merely results in ill-behaved tactics
165.180 - experienced by the user (e.g.\ tactics that insist in being
165.181 - applicable only to singleton goals, or disallow composition with
165.182 - basic tacticals).
165.183 -*}
165.184 -
165.185 -text %mlref {*
165.186 - \begin{mldecls}
165.187 - @{index_ML_type tactic: "thm -> thm Seq.seq"} \\
165.188 - @{index_ML no_tac: tactic} \\
165.189 - @{index_ML all_tac: tactic} \\
165.190 - @{index_ML print_tac: "string -> tactic"} \\[1ex]
165.191 - @{index_ML PRIMITIVE: "(thm -> thm) -> tactic"} \\[1ex]
165.192 - @{index_ML SUBGOAL: "(term * int -> tactic) -> int -> tactic"} \\
165.193 - @{index_ML CSUBGOAL: "(cterm * int -> tactic) -> int -> tactic"} \\
165.194 - \end{mldecls}
165.195 -
165.196 - \begin{description}
165.197 -
165.198 - \item @{ML_type tactic} represents tactics. The well-formedness
165.199 - conditions described above need to be observed. See also @{"file"
165.200 - "~~/src/Pure/General/seq.ML"} for the underlying implementation of
165.201 - lazy sequences.
165.202 -
165.203 - \item @{ML_type "int -> tactic"} represents tactics with explicit
165.204 - subgoal addressing, with well-formedness conditions as described
165.205 - above.
165.206 -
165.207 - \item @{ML no_tac} is a tactic that always fails, returning the
165.208 - empty sequence.
165.209 -
165.210 - \item @{ML all_tac} is a tactic that always succeeds, returning a
165.211 - singleton sequence with unchanged goal state.
165.212 -
165.213 - \item @{ML print_tac}~@{text "message"} is like @{ML all_tac}, but
165.214 - prints a message together with the goal state on the tracing
165.215 - channel.
165.216 -
165.217 - \item @{ML PRIMITIVE}~@{text rule} turns a primitive inference rule
165.218 - into a tactic with unique result. Exception @{ML THM} is considered
165.219 - a regular tactic failure and produces an empty result; other
165.220 - exceptions are passed through.
165.221 -
165.222 - \item @{ML SUBGOAL}~@{text "(fn (subgoal, i) => tactic)"} is the
165.223 - most basic form to produce a tactic with subgoal addressing. The
165.224 - given abstraction over the subgoal term and subgoal number allows to
165.225 - peek at the relevant information of the full goal state. The
165.226 - subgoal range is checked as required above.
165.227 -
165.228 - \item @{ML CSUBGOAL} is similar to @{ML SUBGOAL}, but passes the
165.229 - subgoal as @{ML_type cterm} instead of raw @{ML_type term}. This
165.230 - avoids expensive re-certification in situations where the subgoal is
165.231 - used directly for primitive inferences.
165.232 -
165.233 - \end{description}
165.234 -*}
165.235 -
165.236 -
165.237 -subsection {* Resolution and assumption tactics \label{sec:resolve-assume-tac} *}
165.238 -
165.239 -text {* \emph{Resolution} is the most basic mechanism for refining a
165.240 - subgoal using a theorem as object-level rule.
165.241 - \emph{Elim-resolution} is particularly suited for elimination rules:
165.242 - it resolves with a rule, proves its first premise by assumption, and
165.243 - finally deletes that assumption from any new subgoals.
165.244 - \emph{Destruct-resolution} is like elim-resolution, but the given
165.245 - destruction rules are first turned into canonical elimination
165.246 - format. \emph{Forward-resolution} is like destruct-resolution, but
165.247 - without deleting the selected assumption. The @{text "r/e/d/f"}
165.248 - naming convention is maintained for several different kinds of
165.249 - resolution rules and tactics.
165.250 -
165.251 - Assumption tactics close a subgoal by unifying some of its premises
165.252 - against its conclusion.
165.253 -
165.254 - \medskip All the tactics in this section operate on a subgoal
165.255 - designated by a positive integer. Other subgoals might be affected
165.256 - indirectly, due to instantiation of schematic variables.
165.257 -
165.258 - There are various sources of non-determinism, the tactic result
165.259 - sequence enumerates all possibilities of the following choices (if
165.260 - applicable):
165.261 -
165.262 - \begin{enumerate}
165.263 -
165.264 - \item selecting one of the rules given as argument to the tactic;
165.265 -
165.266 - \item selecting a subgoal premise to eliminate, unifying it against
165.267 - the first premise of the rule;
165.268 -
165.269 - \item unifying the conclusion of the subgoal to the conclusion of
165.270 - the rule.
165.271 -
165.272 - \end{enumerate}
165.273 -
165.274 - Recall that higher-order unification may produce multiple results
165.275 - that are enumerated here.
165.276 -*}
165.277 -
165.278 -text %mlref {*
165.279 - \begin{mldecls}
165.280 - @{index_ML resolve_tac: "thm list -> int -> tactic"} \\
165.281 - @{index_ML eresolve_tac: "thm list -> int -> tactic"} \\
165.282 - @{index_ML dresolve_tac: "thm list -> int -> tactic"} \\
165.283 - @{index_ML forward_tac: "thm list -> int -> tactic"} \\[1ex]
165.284 - @{index_ML assume_tac: "int -> tactic"} \\
165.285 - @{index_ML eq_assume_tac: "int -> tactic"} \\[1ex]
165.286 - @{index_ML match_tac: "thm list -> int -> tactic"} \\
165.287 - @{index_ML ematch_tac: "thm list -> int -> tactic"} \\
165.288 - @{index_ML dmatch_tac: "thm list -> int -> tactic"} \\
165.289 - \end{mldecls}
165.290 -
165.291 - \begin{description}
165.292 -
165.293 - \item @{ML resolve_tac}~@{text "thms i"} refines the goal state
165.294 - using the given theorems, which should normally be introduction
165.295 - rules. The tactic resolves a rule's conclusion with subgoal @{text
165.296 - i}, replacing it by the corresponding versions of the rule's
165.297 - premises.
165.298 -
165.299 - \item @{ML eresolve_tac}~@{text "thms i"} performs elim-resolution
165.300 - with the given theorems, which should normally be elimination rules.
165.301 -
165.302 - \item @{ML dresolve_tac}~@{text "thms i"} performs
165.303 - destruct-resolution with the given theorems, which should normally
165.304 - be destruction rules. This replaces an assumption by the result of
165.305 - applying one of the rules.
165.306 -
165.307 - \item @{ML forward_tac} is like @{ML dresolve_tac} except that the
165.308 - selected assumption is not deleted. It applies a rule to an
165.309 - assumption, adding the result as a new assumption.
165.310 -
165.311 - \item @{ML assume_tac}~@{text i} attempts to solve subgoal @{text i}
165.312 - by assumption (modulo higher-order unification).
165.313 -
165.314 - \item @{ML eq_assume_tac} is similar to @{ML assume_tac}, but checks
165.315 - only for immediate @{text "\<alpha>"}-convertibility instead of using
165.316 - unification. It succeeds (with a unique next state) if one of the
165.317 - assumptions is equal to the subgoal's conclusion. Since it does not
165.318 - instantiate variables, it cannot make other subgoals unprovable.
165.319 -
165.320 - \item @{ML match_tac}, @{ML ematch_tac}, and @{ML dmatch_tac} are
165.321 - similar to @{ML resolve_tac}, @{ML eresolve_tac}, and @{ML
165.322 - dresolve_tac}, respectively, but do not instantiate schematic
165.323 - variables in the goal state.
165.324 -
165.325 - Flexible subgoals are not updated at will, but are left alone.
165.326 - Strictly speaking, matching means to treat the unknowns in the goal
165.327 - state as constants; these tactics merely discard unifiers that would
165.328 - update the goal state.
165.329 -
165.330 - \end{description}
165.331 -*}
165.332 -
165.333 -
165.334 -subsection {* Explicit instantiation within a subgoal context *}
165.335 -
165.336 -text {* The main resolution tactics (\secref{sec:resolve-assume-tac})
165.337 - use higher-order unification, which works well in many practical
165.338 - situations despite its daunting theoretical properties.
165.339 - Nonetheless, there are important problem classes where unguided
165.340 - higher-order unification is not so useful. This typically involves
165.341 - rules like universal elimination, existential introduction, or
165.342 - equational substitution. Here the unification problem involves
165.343 - fully flexible @{text "?P ?x"} schemes, which are hard to manage
165.344 - without further hints.
165.345 -
165.346 - By providing a (small) rigid term for @{text "?x"} explicitly, the
165.347 - remaining unification problem is to assign a (large) term to @{text
165.348 - "?P"}, according to the shape of the given subgoal. This is
165.349 - sufficiently well-behaved in most practical situations.
165.350 -
165.351 - \medskip Isabelle provides separate versions of the standard @{text
165.352 - "r/e/d/f"} resolution tactics that allow to provide explicit
165.353 - instantiations of unknowns of the given rule, wrt.\ terms that refer
165.354 - to the implicit context of the selected subgoal.
165.355 -
165.356 - An instantiation consists of a list of pairs of the form @{text
165.357 - "(?x, t)"}, where @{text ?x} is a schematic variable occurring in
165.358 - the given rule, and @{text t} is a term from the current proof
165.359 - context, augmented by the local goal parameters of the selected
165.360 - subgoal; cf.\ the @{text "focus"} operation described in
165.361 - \secref{sec:variables}.
165.362 -
165.363 - Entering the syntactic context of a subgoal is a brittle operation,
165.364 - because its exact form is somewhat accidental, and the choice of
165.365 - bound variable names depends on the presence of other local and
165.366 - global names. Explicit renaming of subgoal parameters prior to
165.367 - explicit instantiation might help to achieve a bit more robustness.
165.368 -
165.369 - Type instantiations may be given as well, via pairs like @{text
165.370 - "(?'a, \<tau>)"}. Type instantiations are distinguished from term
165.371 - instantiations by the syntactic form of the schematic variable.
165.372 - Types are instantiated before terms are. Since term instantiation
165.373 - already performs type-inference as expected, explicit type
165.374 - instantiations are seldom necessary.
165.375 -*}
165.376 -
165.377 -text %mlref {*
165.378 - \begin{mldecls}
165.379 - @{index_ML res_inst_tac: "Proof.context -> (indexname * string) list -> thm -> int -> tactic"} \\
165.380 - @{index_ML eres_inst_tac: "Proof.context -> (indexname * string) list -> thm -> int -> tactic"} \\
165.381 - @{index_ML dres_inst_tac: "Proof.context -> (indexname * string) list -> thm -> int -> tactic"} \\
165.382 - @{index_ML forw_inst_tac: "Proof.context -> (indexname * string) list -> thm -> int -> tactic"} \\[1ex]
165.383 - @{index_ML rename_tac: "string list -> int -> tactic"} \\
165.384 - \end{mldecls}
165.385 -
165.386 - \begin{description}
165.387 -
165.388 - \item @{ML res_inst_tac}~@{text "ctxt insts thm i"} instantiates the
165.389 - rule @{text thm} with the instantiations @{text insts}, as described
165.390 - above, and then performs resolution on subgoal @{text i}.
165.391 -
165.392 - \item @{ML eres_inst_tac} is like @{ML res_inst_tac}, but performs
165.393 - elim-resolution.
165.394 -
165.395 - \item @{ML dres_inst_tac} is like @{ML res_inst_tac}, but performs
165.396 - destruct-resolution.
165.397 -
165.398 - \item @{ML forw_inst_tac} is like @{ML dres_inst_tac} except that
165.399 - the selected assumption is not deleted.
165.400 -
165.401 - \item @{ML rename_tac}~@{text "names i"} renames the innermost
165.402 - parameters of subgoal @{text i} according to the provided @{text
165.403 - names} (which need to be distinct indentifiers).
165.404 -
165.405 - \end{description}
165.406 -*}
165.407 -
165.408 -
165.409 -section {* Tacticals \label{sec:tacticals} *}
165.410 -
165.411 -text {*
165.412 -
165.413 -FIXME
165.414 -
165.415 -\glossary{Tactical}{A functional combinator for building up complex
165.416 -tactics from simpler ones. Typical tactical perform sequential
165.417 -composition, disjunction (choice), iteration, or goal addressing.
165.418 -Various search strategies may be expressed via tacticals.}
165.419 -
165.420 -*}
165.421 -
165.422 -end
165.423 -
166.1 --- a/doc-src/IsarImplementation/Thy/unused.thy Wed Mar 04 11:05:02 2009 +0100
166.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
166.3 @@ -1,79 +0,0 @@
166.4 -
166.5 -section {* Sessions and document preparation *}
166.6 -
166.7 -section {* Structured output *}
166.8 -
166.9 -subsection {* Pretty printing *}
166.10 -
166.11 -text FIXME
166.12 -
166.13 -subsection {* Output channels *}
166.14 -
166.15 -text FIXME
166.16 -
166.17 -subsection {* Print modes \label{sec:print-mode} *}
166.18 -
166.19 -text FIXME
166.20 -
166.21 -text {*
166.22 -
166.23 -
166.24 - \medskip The general concept supports block-structured reasoning
166.25 - nicely, with arbitrary mechanisms for introducing local assumptions.
166.26 - The common reasoning pattern is as follows:
166.27 -
166.28 - \medskip
166.29 - \begin{tabular}{l}
166.30 - @{text "add_assms e\<^isub>1 A\<^isub>1"} \\
166.31 - @{text "\<dots>"} \\
166.32 - @{text "add_assms e\<^isub>n A\<^isub>n"} \\
166.33 - @{text "export"} \\
166.34 - \end{tabular}
166.35 - \medskip
166.36 -
166.37 - \noindent The final @{text "export"} will turn any fact @{text
166.38 - "A\<^isub>1, \<dots>, A\<^isub>n \<turnstile> B"} into some @{text "\<turnstile> B'"}, by
166.39 - applying the export rules @{text "e\<^isub>1, \<dots>, e\<^isub>n"}
166.40 - inside-out.
166.41 -
166.42 -
166.43 - A \emph{fixed variable} acts like a local constant in the current
166.44 - context, representing some simple type @{text "\<alpha>"}, or some value
166.45 - @{text "x: \<tau>"} (for a fixed type expression @{text "\<tau>"}). A
166.46 - \emph{schematic variable} acts like a placeholder for arbitrary
166.47 - elements, similar to outermost quantification. The division between
166.48 - fixed and schematic variables tells which abstract entities are
166.49 - inside and outside the current context.
166.50 -
166.51 -
166.52 - @{index_ML Variable.trade: "Proof.context -> (thm list -> thm list) -> thm list -> thm list"} \\
166.53 -
166.54 -
166.55 -
166.56 - \item @{ML Variable.trade} composes @{ML Variable.import} and @{ML
166.57 - Variable.export}, i.e.\ it provides a view on facts with all
166.58 - variables being fixed in the current context.
166.59 -
166.60 -
166.61 - In practice, super-contexts emerge either by merging existing ones,
166.62 - or by adding explicit declarations. For example, new theories are
166.63 - usually derived by importing existing theories from the library
166.64 - @{text "\<Theta> = \<Theta>\<^sub>1 + \<dots> + \<Theta>\<^isub>n"}, or
166.65 -
166.66 -
166.67 -
166.68 - The Isar toplevel works differently for interactive developments
166.69 - vs.\ batch processing of theory sources. For example, diagnostic
166.70 - commands produce a warning batch mode, because they are considered
166.71 - alien to the final theory document being produced eventually.
166.72 - Moreover, full @{text undo} with intermediate checkpoints to protect
166.73 - against destroying theories accidentally are limited to interactive
166.74 - mode. In batch mode there is only a single strictly linear stream
166.75 - of potentially desctructive theory transformations.
166.76 -
166.77 - \item @{ML Toplevel.empty} is an empty transition; the Isar command
166.78 - dispatcher internally applies @{ML Toplevel.name} (for the command)
166.79 - name and @{ML Toplevel.position} for the source position.
166.80 -
166.81 -*}
166.82 -
167.1 --- a/doc-src/IsarImplementation/checkglossary Wed Mar 04 11:05:02 2009 +0100
167.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
167.3 @@ -1,28 +0,0 @@
167.4 -#!/usr/bin/env perl
167.5 -# $Id$
167.6 -
167.7 -use strict;
167.8 -
167.9 -my %defs = ();
167.10 -my %refs = ();
167.11 -
167.12 -while (<ARGV>) {
167.13 - if (m,\\glossaryentry\{\w*\\bf *((\w|\s)+)@,) {
167.14 - $defs{lc $1} = 1;
167.15 - }
167.16 - while (m,\\seeglossary *\{((\w|\s)+)\},g) {
167.17 - $refs{lc $1} = 1;
167.18 - }
167.19 -}
167.20 -
167.21 -print "Glossary definitions:\n";
167.22 -foreach (sort(keys(%defs))) {
167.23 - print " \"$_\"\n";
167.24 -}
167.25 -
167.26 -foreach (keys(%refs)) {
167.27 - s,s$,,;
167.28 - if (!defined($defs{$_})) {
167.29 - print "### Undefined glossary reference: \"$_\"\n";
167.30 - }
167.31 -}
168.1 --- a/doc-src/IsarImplementation/intro.tex Wed Mar 04 11:05:02 2009 +0100
168.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
168.3 @@ -1,13 +0,0 @@
168.4 -
168.5 -%% $Id$
168.6 -
168.7 -\chapter{Introduction}
168.8 -
168.9 -FIXME
168.10 -
168.11 -\nocite{Wenzel-PhD}
168.12 -
168.13 -%%% Local Variables:
168.14 -%%% mode: latex
168.15 -%%% TeX-master: "implementation"
168.16 -%%% End:
169.1 --- a/doc-src/IsarImplementation/makeglossary Wed Mar 04 11:05:02 2009 +0100
169.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
169.3 @@ -1,6 +0,0 @@
169.4 -#!/bin/sh
169.5 -# $Id$
169.6 -
169.7 -NAME="$1"
169.8 -makeindex -s nomencl -o "${NAME}.gls" "${NAME}.glo"
169.9 -./checkglossary "${NAME}.glo"
170.1 --- a/doc-src/IsarOverview/Isar/document/.cvsignore Wed Mar 04 11:05:02 2009 +0100
170.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
170.3 @@ -1,2 +0,0 @@
170.4 -*.sty
170.5 -session.tex
170.6 \ No newline at end of file
171.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
171.2 +++ b/doc-src/IsarRef/Thy/First_Order_Logic.thy Wed Mar 04 11:05:29 2009 +0100
171.3 @@ -0,0 +1,520 @@
171.4 +
171.5 +header {* Example: First-Order Logic *}
171.6 +
171.7 +theory %visible First_Order_Logic
171.8 +imports Pure
171.9 +begin
171.10 +
171.11 +text {*
171.12 + \noindent In order to commence a new object-logic within
171.13 + Isabelle/Pure we introduce abstract syntactic categories @{text "i"}
171.14 + for individuals and @{text "o"} for object-propositions. The latter
171.15 + is embedded into the language of Pure propositions by means of a
171.16 + separate judgment.
171.17 +*}
171.18 +
171.19 +typedecl i
171.20 +typedecl o
171.21 +
171.22 +judgment
171.23 + Trueprop :: "o \<Rightarrow> prop" ("_" 5)
171.24 +
171.25 +text {*
171.26 + \noindent Note that the object-logic judgement is implicit in the
171.27 + syntax: writing @{prop A} produces @{term "Trueprop A"} internally.
171.28 + From the Pure perspective this means ``@{prop A} is derivable in the
171.29 + object-logic''.
171.30 +*}
171.31 +
171.32 +
171.33 +subsection {* Equational reasoning \label{sec:framework-ex-equal} *}
171.34 +
171.35 +text {*
171.36 + Equality is axiomatized as a binary predicate on individuals, with
171.37 + reflexivity as introduction, and substitution as elimination
171.38 + principle. Note that the latter is particularly convenient in a
171.39 + framework like Isabelle, because syntactic congruences are
171.40 + implicitly produced by unification of @{term "B x"} against
171.41 + expressions containing occurrences of @{term x}.
171.42 +*}
171.43 +
171.44 +axiomatization
171.45 + equal :: "i \<Rightarrow> i \<Rightarrow> o" (infix "=" 50)
171.46 +where
171.47 + refl [intro]: "x = x" and
171.48 + subst [elim]: "x = y \<Longrightarrow> B x \<Longrightarrow> B y"
171.49 +
171.50 +text {*
171.51 + \noindent Substitution is very powerful, but also hard to control in
171.52 + full generality. We derive some common symmetry~/ transitivity
171.53 + schemes of as particular consequences.
171.54 +*}
171.55 +
171.56 +theorem sym [sym]:
171.57 + assumes "x = y"
171.58 + shows "y = x"
171.59 +proof -
171.60 + have "x = x" ..
171.61 + with `x = y` show "y = x" ..
171.62 +qed
171.63 +
171.64 +theorem forw_subst [trans]:
171.65 + assumes "y = x" and "B x"
171.66 + shows "B y"
171.67 +proof -
171.68 + from `y = x` have "x = y" ..
171.69 + from this and `B x` show "B y" ..
171.70 +qed
171.71 +
171.72 +theorem back_subst [trans]:
171.73 + assumes "B x" and "x = y"
171.74 + shows "B y"
171.75 +proof -
171.76 + from `x = y` and `B x`
171.77 + show "B y" ..
171.78 +qed
171.79 +
171.80 +theorem trans [trans]:
171.81 + assumes "x = y" and "y = z"
171.82 + shows "x = z"
171.83 +proof -
171.84 + from `y = z` and `x = y`
171.85 + show "x = z" ..
171.86 +qed
171.87 +
171.88 +
171.89 +subsection {* Basic group theory *}
171.90 +
171.91 +text {*
171.92 + As an example for equational reasoning we consider some bits of
171.93 + group theory. The subsequent locale definition postulates group
171.94 + operations and axioms; we also derive some consequences of this
171.95 + specification.
171.96 +*}
171.97 +
171.98 +locale group =
171.99 + fixes prod :: "i \<Rightarrow> i \<Rightarrow> i" (infix "\<circ>" 70)
171.100 + and inv :: "i \<Rightarrow> i" ("(_\<inverse>)" [1000] 999)
171.101 + and unit :: i ("1")
171.102 + assumes assoc: "(x \<circ> y) \<circ> z = x \<circ> (y \<circ> z)"
171.103 + and left_unit: "1 \<circ> x = x"
171.104 + and left_inv: "x\<inverse> \<circ> x = 1"
171.105 +begin
171.106 +
171.107 +theorem right_inv: "x \<circ> x\<inverse> = 1"
171.108 +proof -
171.109 + have "x \<circ> x\<inverse> = 1 \<circ> (x \<circ> x\<inverse>)" by (rule left_unit [symmetric])
171.110 + also have "\<dots> = (1 \<circ> x) \<circ> x\<inverse>" by (rule assoc [symmetric])
171.111 + also have "1 = (x\<inverse>)\<inverse> \<circ> x\<inverse>" by (rule left_inv [symmetric])
171.112 + also have "\<dots> \<circ> x = (x\<inverse>)\<inverse> \<circ> (x\<inverse> \<circ> x)" by (rule assoc)
171.113 + also have "x\<inverse> \<circ> x = 1" by (rule left_inv)
171.114 + also have "((x\<inverse>)\<inverse> \<circ> \<dots>) \<circ> x\<inverse> = (x\<inverse>)\<inverse> \<circ> (1 \<circ> x\<inverse>)" by (rule assoc)
171.115 + also have "1 \<circ> x\<inverse> = x\<inverse>" by (rule left_unit)
171.116 + also have "(x\<inverse>)\<inverse> \<circ> \<dots> = 1" by (rule left_inv)
171.117 + finally show "x \<circ> x\<inverse> = 1" .
171.118 +qed
171.119 +
171.120 +theorem right_unit: "x \<circ> 1 = x"
171.121 +proof -
171.122 + have "1 = x\<inverse> \<circ> x" by (rule left_inv [symmetric])
171.123 + also have "x \<circ> \<dots> = (x \<circ> x\<inverse>) \<circ> x" by (rule assoc [symmetric])
171.124 + also have "x \<circ> x\<inverse> = 1" by (rule right_inv)
171.125 + also have "\<dots> \<circ> x = x" by (rule left_unit)
171.126 + finally show "x \<circ> 1 = x" .
171.127 +qed
171.128 +
171.129 +text {*
171.130 + \noindent Reasoning from basic axioms is often tedious. Our proofs
171.131 + work by producing various instances of the given rules (potentially
171.132 + the symmetric form) using the pattern ``@{command have}~@{text
171.133 + eq}~@{command "by"}~@{text "(rule r)"}'' and composing the chain of
171.134 + results via @{command also}/@{command finally}. These steps may
171.135 + involve any of the transitivity rules declared in
171.136 + \secref{sec:framework-ex-equal}, namely @{thm trans} in combining
171.137 + the first two results in @{thm right_inv} and in the final steps of
171.138 + both proofs, @{thm forw_subst} in the first combination of @{thm
171.139 + right_unit}, and @{thm back_subst} in all other calculational steps.
171.140 +
171.141 + Occasional substitutions in calculations are adequate, but should
171.142 + not be over-emphasized. The other extreme is to compose a chain by
171.143 + plain transitivity only, with replacements occurring always in
171.144 + topmost position. For example:
171.145 +*}
171.146 +
171.147 +(*<*)
171.148 +theorem "\<And>A. PROP A \<Longrightarrow> PROP A"
171.149 +proof -
171.150 + assume [symmetric, defn]: "\<And>x y. (x \<equiv> y) \<equiv> Trueprop (x = y)"
171.151 +(*>*)
171.152 + have "x \<circ> 1 = x \<circ> (x\<inverse> \<circ> x)" unfolding left_inv ..
171.153 + also have "\<dots> = (x \<circ> x\<inverse>) \<circ> x" unfolding assoc ..
171.154 + also have "\<dots> = 1 \<circ> x" unfolding right_inv ..
171.155 + also have "\<dots> = x" unfolding left_unit ..
171.156 + finally have "x \<circ> 1 = x" .
171.157 +(*<*)
171.158 +qed
171.159 +(*>*)
171.160 +
171.161 +text {*
171.162 + \noindent Here we have re-used the built-in mechanism for unfolding
171.163 + definitions in order to normalize each equational problem. A more
171.164 + realistic object-logic would include proper setup for the Simplifier
171.165 + (\secref{sec:simplifier}), the main automated tool for equational
171.166 + reasoning in Isabelle. Then ``@{command unfolding}~@{thm
171.167 + left_inv}~@{command ".."}'' would become ``@{command "by"}~@{text
171.168 + "(simp only: left_inv)"}'' etc.
171.169 +*}
171.170 +
171.171 +end
171.172 +
171.173 +
171.174 +subsection {* Propositional logic \label{sec:framework-ex-prop} *}
171.175 +
171.176 +text {*
171.177 + We axiomatize basic connectives of propositional logic: implication,
171.178 + disjunction, and conjunction. The associated rules are modeled
171.179 + after Gentzen's system of Natural Deduction \cite{Gentzen:1935}.
171.180 +*}
171.181 +
171.182 +axiomatization
171.183 + imp :: "o \<Rightarrow> o \<Rightarrow> o" (infixr "\<longrightarrow>" 25) where
171.184 + impI [intro]: "(A \<Longrightarrow> B) \<Longrightarrow> A \<longrightarrow> B" and
171.185 + impD [dest]: "(A \<longrightarrow> B) \<Longrightarrow> A \<Longrightarrow> B"
171.186 +
171.187 +axiomatization
171.188 + disj :: "o \<Rightarrow> o \<Rightarrow> o" (infixr "\<or>" 30) where
171.189 + disjI\<^isub>1 [intro]: "A \<Longrightarrow> A \<or> B" and
171.190 + disjI\<^isub>2 [intro]: "B \<Longrightarrow> A \<or> B" and
171.191 + disjE [elim]: "A \<or> B \<Longrightarrow> (A \<Longrightarrow> C) \<Longrightarrow> (B \<Longrightarrow> C) \<Longrightarrow> C"
171.192 +
171.193 +axiomatization
171.194 + conj :: "o \<Rightarrow> o \<Rightarrow> o" (infixr "\<and>" 35) where
171.195 + conjI [intro]: "A \<Longrightarrow> B \<Longrightarrow> A \<and> B" and
171.196 + conjD\<^isub>1: "A \<and> B \<Longrightarrow> A" and
171.197 + conjD\<^isub>2: "A \<and> B \<Longrightarrow> B"
171.198 +
171.199 +text {*
171.200 + \noindent The conjunctive destructions have the disadvantage that
171.201 + decomposing @{prop "A \<and> B"} involves an immediate decision which
171.202 + component should be projected. The more convenient simultaneous
171.203 + elimination @{prop "A \<and> B \<Longrightarrow> (A \<Longrightarrow> B \<Longrightarrow> C) \<Longrightarrow> C"} can be derived as
171.204 + follows:
171.205 +*}
171.206 +
171.207 +theorem conjE [elim]:
171.208 + assumes "A \<and> B"
171.209 + obtains A and B
171.210 +proof
171.211 + from `A \<and> B` show A by (rule conjD\<^isub>1)
171.212 + from `A \<and> B` show B by (rule conjD\<^isub>2)
171.213 +qed
171.214 +
171.215 +text {*
171.216 + \noindent Here is an example of swapping conjuncts with a single
171.217 + intermediate elimination step:
171.218 +*}
171.219 +
171.220 +(*<*)
171.221 +lemma "\<And>A. PROP A \<Longrightarrow> PROP A"
171.222 +proof -
171.223 +(*>*)
171.224 + assume "A \<and> B"
171.225 + then obtain B and A ..
171.226 + then have "B \<and> A" ..
171.227 +(*<*)
171.228 +qed
171.229 +(*>*)
171.230 +
171.231 +text {*
171.232 + \noindent Note that the analogous elimination rule for disjunction
171.233 + ``@{text "\<ASSUMES> A \<or> B \<OBTAINS> A \<BBAR> B"}'' coincides with
171.234 + the original axiomatization of @{thm disjE}.
171.235 +
171.236 + \medskip We continue propositional logic by introducing absurdity
171.237 + with its characteristic elimination. Plain truth may then be
171.238 + defined as a proposition that is trivially true.
171.239 +*}
171.240 +
171.241 +axiomatization
171.242 + false :: o ("\<bottom>") where
171.243 + falseE [elim]: "\<bottom> \<Longrightarrow> A"
171.244 +
171.245 +definition
171.246 + true :: o ("\<top>") where
171.247 + "\<top> \<equiv> \<bottom> \<longrightarrow> \<bottom>"
171.248 +
171.249 +theorem trueI [intro]: \<top>
171.250 + unfolding true_def ..
171.251 +
171.252 +text {*
171.253 + \medskip\noindent Now negation represents an implication towards
171.254 + absurdity:
171.255 +*}
171.256 +
171.257 +definition
171.258 + not :: "o \<Rightarrow> o" ("\<not> _" [40] 40) where
171.259 + "\<not> A \<equiv> A \<longrightarrow> \<bottom>"
171.260 +
171.261 +theorem notI [intro]:
171.262 + assumes "A \<Longrightarrow> \<bottom>"
171.263 + shows "\<not> A"
171.264 +unfolding not_def
171.265 +proof
171.266 + assume A
171.267 + then show \<bottom> by (rule `A \<Longrightarrow> \<bottom>`)
171.268 +qed
171.269 +
171.270 +theorem notE [elim]:
171.271 + assumes "\<not> A" and A
171.272 + shows B
171.273 +proof -
171.274 + from `\<not> A` have "A \<longrightarrow> \<bottom>" unfolding not_def .
171.275 + from `A \<longrightarrow> \<bottom>` and `A` have \<bottom> ..
171.276 + then show B ..
171.277 +qed
171.278 +
171.279 +
171.280 +subsection {* Classical logic *}
171.281 +
171.282 +text {*
171.283 + Subsequently we state the principle of classical contradiction as a
171.284 + local assumption. Thus we refrain from forcing the object-logic
171.285 + into the classical perspective. Within that context, we may derive
171.286 + well-known consequences of the classical principle.
171.287 +*}
171.288 +
171.289 +locale classical =
171.290 + assumes classical: "(\<not> C \<Longrightarrow> C) \<Longrightarrow> C"
171.291 +begin
171.292 +
171.293 +theorem double_negation:
171.294 + assumes "\<not> \<not> C"
171.295 + shows C
171.296 +proof (rule classical)
171.297 + assume "\<not> C"
171.298 + with `\<not> \<not> C` show C ..
171.299 +qed
171.300 +
171.301 +theorem tertium_non_datur: "C \<or> \<not> C"
171.302 +proof (rule double_negation)
171.303 + show "\<not> \<not> (C \<or> \<not> C)"
171.304 + proof
171.305 + assume "\<not> (C \<or> \<not> C)"
171.306 + have "\<not> C"
171.307 + proof
171.308 + assume C then have "C \<or> \<not> C" ..
171.309 + with `\<not> (C \<or> \<not> C)` show \<bottom> ..
171.310 + qed
171.311 + then have "C \<or> \<not> C" ..
171.312 + with `\<not> (C \<or> \<not> C)` show \<bottom> ..
171.313 + qed
171.314 +qed
171.315 +
171.316 +text {*
171.317 + \noindent These examples illustrate both classical reasoning and
171.318 + non-trivial propositional proofs in general. All three rules
171.319 + characterize classical logic independently, but the original rule is
171.320 + already the most convenient to use, because it leaves the conclusion
171.321 + unchanged. Note that @{prop "(\<not> C \<Longrightarrow> C) \<Longrightarrow> C"} fits again into our
171.322 + format for eliminations, despite the additional twist that the
171.323 + context refers to the main conclusion. So we may write @{thm
171.324 + classical} as the Isar statement ``@{text "\<OBTAINS> \<not> thesis"}''.
171.325 + This also explains nicely how classical reasoning really works:
171.326 + whatever the main @{text thesis} might be, we may always assume its
171.327 + negation!
171.328 +*}
171.329 +
171.330 +end
171.331 +
171.332 +
171.333 +subsection {* Quantifiers \label{sec:framework-ex-quant} *}
171.334 +
171.335 +text {*
171.336 + Representing quantifiers is easy, thanks to the higher-order nature
171.337 + of the underlying framework. According to the well-known technique
171.338 + introduced by Church \cite{church40}, quantifiers are operators on
171.339 + predicates, which are syntactically represented as @{text "\<lambda>"}-terms
171.340 + of type @{typ "i \<Rightarrow> o"}. Binder notation turns @{text "All (\<lambda>x. B
171.341 + x)"} into @{text "\<forall>x. B x"} etc.
171.342 +*}
171.343 +
171.344 +axiomatization
171.345 + All :: "(i \<Rightarrow> o) \<Rightarrow> o" (binder "\<forall>" 10) where
171.346 + allI [intro]: "(\<And>x. B x) \<Longrightarrow> \<forall>x. B x" and
171.347 + allD [dest]: "(\<forall>x. B x) \<Longrightarrow> B a"
171.348 +
171.349 +axiomatization
171.350 + Ex :: "(i \<Rightarrow> o) \<Rightarrow> o" (binder "\<exists>" 10) where
171.351 + exI [intro]: "B a \<Longrightarrow> (\<exists>x. B x)" and
171.352 + exE [elim]: "(\<exists>x. B x) \<Longrightarrow> (\<And>x. B x \<Longrightarrow> C) \<Longrightarrow> C"
171.353 +
171.354 +text {*
171.355 + \noindent The statement of @{thm exE} corresponds to ``@{text
171.356 + "\<ASSUMES> \<exists>x. B x \<OBTAINS> x \<WHERE> B x"}'' in Isar. In the
171.357 + subsequent example we illustrate quantifier reasoning involving all
171.358 + four rules:
171.359 +*}
171.360 +
171.361 +theorem
171.362 + assumes "\<exists>x. \<forall>y. R x y"
171.363 + shows "\<forall>y. \<exists>x. R x y"
171.364 +proof -- {* @{text "\<forall>"} introduction *}
171.365 + obtain x where "\<forall>y. R x y" using `\<exists>x. \<forall>y. R x y` .. -- {* @{text "\<exists>"} elimination *}
171.366 + fix y have "R x y" using `\<forall>y. R x y` .. -- {* @{text "\<forall>"} destruction *}
171.367 + then show "\<exists>x. R x y" .. -- {* @{text "\<exists>"} introduction *}
171.368 +qed
171.369 +
171.370 +
171.371 +subsection {* Canonical reasoning patterns *}
171.372 +
171.373 +text {*
171.374 + The main rules of first-order predicate logic from
171.375 + \secref{sec:framework-ex-prop} and \secref{sec:framework-ex-quant}
171.376 + can now be summarized as follows, using the native Isar statement
171.377 + format of \secref{sec:framework-stmt}.
171.378 +
171.379 + \medskip
171.380 + \begin{tabular}{l}
171.381 + @{text "impI: \<ASSUMES> A \<Longrightarrow> B \<SHOWS> A \<longrightarrow> B"} \\
171.382 + @{text "impD: \<ASSUMES> A \<longrightarrow> B \<AND> A \<SHOWS> B"} \\[1ex]
171.383 +
171.384 + @{text "disjI\<^isub>1: \<ASSUMES> A \<SHOWS> A \<or> B"} \\
171.385 + @{text "disjI\<^isub>2: \<ASSUMES> B \<SHOWS> A \<or> B"} \\
171.386 + @{text "disjE: \<ASSUMES> A \<or> B \<OBTAINS> A \<BBAR> B"} \\[1ex]
171.387 +
171.388 + @{text "conjI: \<ASSUMES> A \<AND> B \<SHOWS> A \<and> B"} \\
171.389 + @{text "conjE: \<ASSUMES> A \<and> B \<OBTAINS> A \<AND> B"} \\[1ex]
171.390 +
171.391 + @{text "falseE: \<ASSUMES> \<bottom> \<SHOWS> A"} \\
171.392 + @{text "trueI: \<SHOWS> \<top>"} \\[1ex]
171.393 +
171.394 + @{text "notI: \<ASSUMES> A \<Longrightarrow> \<bottom> \<SHOWS> \<not> A"} \\
171.395 + @{text "notE: \<ASSUMES> \<not> A \<AND> A \<SHOWS> B"} \\[1ex]
171.396 +
171.397 + @{text "allI: \<ASSUMES> \<And>x. B x \<SHOWS> \<forall>x. B x"} \\
171.398 + @{text "allE: \<ASSUMES> \<forall>x. B x \<SHOWS> B a"} \\[1ex]
171.399 +
171.400 + @{text "exI: \<ASSUMES> B a \<SHOWS> \<exists>x. B x"} \\
171.401 + @{text "exE: \<ASSUMES> \<exists>x. B x \<OBTAINS> a \<WHERE> B a"}
171.402 + \end{tabular}
171.403 + \medskip
171.404 +
171.405 + \noindent This essentially provides a declarative reading of Pure
171.406 + rules as Isar reasoning patterns: the rule statements tells how a
171.407 + canonical proof outline shall look like. Since the above rules have
171.408 + already been declared as @{attribute (Pure) intro}, @{attribute
171.409 + (Pure) elim}, @{attribute (Pure) dest} --- each according to its
171.410 + particular shape --- we can immediately write Isar proof texts as
171.411 + follows:
171.412 +*}
171.413 +
171.414 +(*<*)
171.415 +theorem "\<And>A. PROP A \<Longrightarrow> PROP A"
171.416 +proof -
171.417 +(*>*)
171.418 +
171.419 + txt_raw {*\begin{minipage}[t]{0.4\textwidth}*}(*<*)next(*>*)
171.420 +
171.421 + have "A \<longrightarrow> B"
171.422 + proof
171.423 + assume A
171.424 + show B sorry %noproof
171.425 + qed
171.426 +
171.427 + txt_raw {*\end{minipage}\qquad\begin{minipage}[t]{0.4\textwidth}*}(*<*)next(*>*)
171.428 +
171.429 + have "A \<longrightarrow> B" and A sorry %noproof
171.430 + then have B ..
171.431 +
171.432 + txt_raw {*\end{minipage}\\[3ex]\begin{minipage}[t]{0.4\textwidth}*}(*<*)next(*>*)
171.433 +
171.434 + have A sorry %noproof
171.435 + then have "A \<or> B" ..
171.436 +
171.437 + have B sorry %noproof
171.438 + then have "A \<or> B" ..
171.439 +
171.440 + txt_raw {*\end{minipage}\qquad\begin{minipage}[t]{0.4\textwidth}*}(*<*)next(*>*)
171.441 +
171.442 + have "A \<or> B" sorry %noproof
171.443 + then have C
171.444 + proof
171.445 + assume A
171.446 + then show C sorry %noproof
171.447 + next
171.448 + assume B
171.449 + then show C sorry %noproof
171.450 + qed
171.451 +
171.452 + txt_raw {*\end{minipage}\\[3ex]\begin{minipage}[t]{0.4\textwidth}*}(*<*)next(*>*)
171.453 +
171.454 + have A and B sorry %noproof
171.455 + then have "A \<and> B" ..
171.456 +
171.457 + txt_raw {*\end{minipage}\qquad\begin{minipage}[t]{0.4\textwidth}*}(*<*)next(*>*)
171.458 +
171.459 + have "A \<and> B" sorry %noproof
171.460 + then obtain A and B ..
171.461 +
171.462 + txt_raw {*\end{minipage}\\[3ex]\begin{minipage}[t]{0.4\textwidth}*}(*<*)next(*>*)
171.463 +
171.464 + have "\<bottom>" sorry %noproof
171.465 + then have A ..
171.466 +
171.467 + txt_raw {*\end{minipage}\qquad\begin{minipage}[t]{0.4\textwidth}*}(*<*)next(*>*)
171.468 +
171.469 + have "\<top>" ..
171.470 +
171.471 + txt_raw {*\end{minipage}\\[3ex]\begin{minipage}[t]{0.4\textwidth}*}(*<*)next(*>*)
171.472 +
171.473 + have "\<not> A"
171.474 + proof
171.475 + assume A
171.476 + then show "\<bottom>" sorry %noproof
171.477 + qed
171.478 +
171.479 + txt_raw {*\end{minipage}\qquad\begin{minipage}[t]{0.4\textwidth}*}(*<*)next(*>*)
171.480 +
171.481 + have "\<not> A" and A sorry %noproof
171.482 + then have B ..
171.483 +
171.484 + txt_raw {*\end{minipage}\\[3ex]\begin{minipage}[t]{0.4\textwidth}*}(*<*)next(*>*)
171.485 +
171.486 + have "\<forall>x. B x"
171.487 + proof
171.488 + fix x
171.489 + show "B x" sorry %noproof
171.490 + qed
171.491 +
171.492 + txt_raw {*\end{minipage}\qquad\begin{minipage}[t]{0.4\textwidth}*}(*<*)next(*>*)
171.493 +
171.494 + have "\<forall>x. B x" sorry %noproof
171.495 + then have "B a" ..
171.496 +
171.497 + txt_raw {*\end{minipage}\\[3ex]\begin{minipage}[t]{0.4\textwidth}*}(*<*)next(*>*)
171.498 +
171.499 + have "\<exists>x. B x"
171.500 + proof
171.501 + show "B a" sorry %noproof
171.502 + qed
171.503 +
171.504 + txt_raw {*\end{minipage}\qquad\begin{minipage}[t]{0.4\textwidth}*}(*<*)next(*>*)
171.505 +
171.506 + have "\<exists>x. B x" sorry %noproof
171.507 + then obtain a where "B a" ..
171.508 +
171.509 + txt_raw {*\end{minipage}*}
171.510 +
171.511 +(*<*)
171.512 +qed
171.513 +(*>*)
171.514 +
171.515 +text {*
171.516 + \bigskip\noindent Of course, these proofs are merely examples. As
171.517 + sketched in \secref{sec:framework-subproof}, there is a fair amount
171.518 + of flexibility in expressing Pure deductions in Isar. Here the user
171.519 + is asked to express himself adequately, aiming at proof texts of
171.520 + literary quality.
171.521 +*}
171.522 +
171.523 +end %visible
172.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
172.2 +++ b/doc-src/IsarRef/Thy/Framework.thy Wed Mar 04 11:05:29 2009 +0100
172.3 @@ -0,0 +1,1017 @@
172.4 +theory Framework
172.5 +imports Main
172.6 +begin
172.7 +
172.8 +chapter {* The Isabelle/Isar Framework \label{ch:isar-framework} *}
172.9 +
172.10 +text {*
172.11 + Isabelle/Isar
172.12 + \cite{Wenzel:1999:TPHOL,Wenzel-PhD,Nipkow-TYPES02,Wenzel-Paulson:2006,Wenzel:2006:Festschrift}
172.13 + is intended as a generic framework for developing formal
172.14 + mathematical documents with full proof checking. Definitions and
172.15 + proofs are organized as theories. An assembly of theory sources may
172.16 + be presented as a printed document; see also
172.17 + \chref{ch:document-prep}.
172.18 +
172.19 + The main objective of Isar is the design of a human-readable
172.20 + structured proof language, which is called the ``primary proof
172.21 + format'' in Isar terminology. Such a primary proof language is
172.22 + somewhere in the middle between the extremes of primitive proof
172.23 + objects and actual natural language. In this respect, Isar is a bit
172.24 + more formalistic than Mizar
172.25 + \cite{Trybulec:1993:MizarFeatures,Rudnicki:1992:MizarOverview,Wiedijk:1999:Mizar},
172.26 + using logical symbols for certain reasoning schemes where Mizar
172.27 + would prefer English words; see \cite{Wenzel-Wiedijk:2002} for
172.28 + further comparisons of these systems.
172.29 +
172.30 + So Isar challenges the traditional way of recording informal proofs
172.31 + in mathematical prose, as well as the common tendency to see fully
172.32 + formal proofs directly as objects of some logical calculus (e.g.\
172.33 + @{text "\<lambda>"}-terms in a version of type theory). In fact, Isar is
172.34 + better understood as an interpreter of a simple block-structured
172.35 + language for describing the data flow of local facts and goals,
172.36 + interspersed with occasional invocations of proof methods.
172.37 + Everything is reduced to logical inferences internally, but these
172.38 + steps are somewhat marginal compared to the overall bookkeeping of
172.39 + the interpretation process. Thanks to careful design of the syntax
172.40 + and semantics of Isar language elements, a formal record of Isar
172.41 + instructions may later appear as an intelligible text to the
172.42 + attentive reader.
172.43 +
172.44 + The Isar proof language has emerged from careful analysis of some
172.45 + inherent virtues of the existing logical framework of Isabelle/Pure
172.46 + \cite{paulson-found,paulson700}, notably composition of higher-order
172.47 + natural deduction rules, which is a generalization of Gentzen's
172.48 + original calculus \cite{Gentzen:1935}. The approach of generic
172.49 + inference systems in Pure is continued by Isar towards actual proof
172.50 + texts.
172.51 +
172.52 + Concrete applications require another intermediate layer: an
172.53 + object-logic. Isabelle/HOL \cite{isa-tutorial} (simply-typed
172.54 + set-theory) is being used most of the time; Isabelle/ZF
172.55 + \cite{isabelle-ZF} is less extensively developed, although it would
172.56 + probably fit better for classical mathematics.
172.57 +
172.58 + \medskip In order to illustrate natural deduction in Isar, we shall
172.59 + refer to the background theory and library of Isabelle/HOL. This
172.60 + includes common notions of predicate logic, naive set-theory etc.\
172.61 + using fairly standard mathematical notation. From the perspective
172.62 + of generic natural deduction there is nothing special about the
172.63 + logical connectives of HOL (@{text "\<and>"}, @{text "\<or>"}, @{text "\<forall>"},
172.64 + @{text "\<exists>"}, etc.), only the resulting reasoning principles are
172.65 + relevant to the user. There are similar rules available for
172.66 + set-theory operators (@{text "\<inter>"}, @{text "\<union>"}, @{text "\<Inter>"}, @{text
172.67 + "\<Union>"}, etc.), or any other theory developed in the library (lattice
172.68 + theory, topology etc.).
172.69 +
172.70 + Subsequently we briefly review fragments of Isar proof texts
172.71 + corresponding directly to such general deduction schemes. The
172.72 + examples shall refer to set-theory, to minimize the danger of
172.73 + understanding connectives of predicate logic as something special.
172.74 +
172.75 + \medskip The following deduction performs @{text "\<inter>"}-introduction,
172.76 + working forwards from assumptions towards the conclusion. We give
172.77 + both the Isar text, and depict the primitive rule involved, as
172.78 + determined by unification of the problem against rules that are
172.79 + declared in the library context.
172.80 +*}
172.81 +
172.82 +text_raw {*\medskip\begin{minipage}{0.6\textwidth}*}
172.83 +
172.84 +(*<*)
172.85 +lemma True
172.86 +proof
172.87 +(*>*)
172.88 + assume "x \<in> A" and "x \<in> B"
172.89 + then have "x \<in> A \<inter> B" ..
172.90 +(*<*)
172.91 +qed
172.92 +(*>*)
172.93 +
172.94 +text_raw {*\end{minipage}\begin{minipage}{0.4\textwidth}*}
172.95 +
172.96 +text {*
172.97 + \infer{@{prop "x \<in> A \<inter> B"}}{@{prop "x \<in> A"} & @{prop "x \<in> B"}}
172.98 +*}
172.99 +
172.100 +text_raw {*\end{minipage}*}
172.101 +
172.102 +text {*
172.103 + \medskip\noindent Note that @{command assume} augments the proof
172.104 + context, @{command then} indicates that the current fact shall be
172.105 + used in the next step, and @{command have} states an intermediate
172.106 + goal. The two dots ``@{command ".."}'' refer to a complete proof of
172.107 + this claim, using the indicated facts and a canonical rule from the
172.108 + context. We could have been more explicit here by spelling out the
172.109 + final proof step via the @{command "by"} command:
172.110 +*}
172.111 +
172.112 +(*<*)
172.113 +lemma True
172.114 +proof
172.115 +(*>*)
172.116 + assume "x \<in> A" and "x \<in> B"
172.117 + then have "x \<in> A \<inter> B" by (rule IntI)
172.118 +(*<*)
172.119 +qed
172.120 +(*>*)
172.121 +
172.122 +text {*
172.123 + \noindent The format of the @{text "\<inter>"}-introduction rule represents
172.124 + the most basic inference, which proceeds from given premises to a
172.125 + conclusion, without any nested proof context involved.
172.126 +
172.127 + The next example performs backwards introduction on @{term "\<Inter>\<A>"},
172.128 + the intersection of all sets within a given set. This requires a
172.129 + nested proof of set membership within a local context, where @{term
172.130 + A} is an arbitrary-but-fixed member of the collection:
172.131 +*}
172.132 +
172.133 +text_raw {*\medskip\begin{minipage}{0.6\textwidth}*}
172.134 +
172.135 +(*<*)
172.136 +lemma True
172.137 +proof
172.138 +(*>*)
172.139 + have "x \<in> \<Inter>\<A>"
172.140 + proof
172.141 + fix A
172.142 + assume "A \<in> \<A>"
172.143 + show "x \<in> A" sorry %noproof
172.144 + qed
172.145 +(*<*)
172.146 +qed
172.147 +(*>*)
172.148 +
172.149 +text_raw {*\end{minipage}\begin{minipage}{0.4\textwidth}*}
172.150 +
172.151 +text {*
172.152 + \infer{@{prop "x \<in> \<Inter>\<A>"}}{\infer*{@{prop "x \<in> A"}}{@{text "[A][A \<in> \<A>]"}}}
172.153 +*}
172.154 +
172.155 +text_raw {*\end{minipage}*}
172.156 +
172.157 +text {*
172.158 + \medskip\noindent This Isar reasoning pattern again refers to the
172.159 + primitive rule depicted above. The system determines it in the
172.160 + ``@{command proof}'' step, which could have been spelt out more
172.161 + explicitly as ``@{command proof}~@{text "(rule InterI)"}''. Note
172.162 + that the rule involves both a local parameter @{term "A"} and an
172.163 + assumption @{prop "A \<in> \<A>"} in the nested reasoning. This kind of
172.164 + compound rule typically demands a genuine sub-proof in Isar, working
172.165 + backwards rather than forwards as seen before. In the proof body we
172.166 + encounter the @{command fix}-@{command assume}-@{command show}
172.167 + outline of nested sub-proofs that is typical for Isar. The final
172.168 + @{command show} is like @{command have} followed by an additional
172.169 + refinement of the enclosing claim, using the rule derived from the
172.170 + proof body.
172.171 +
172.172 + \medskip The next example involves @{term "\<Union>\<A>"}, which can be
172.173 + characterized as the set of all @{term "x"} such that @{prop "\<exists>A. x
172.174 + \<in> A \<and> A \<in> \<A>"}. The elimination rule for @{prop "x \<in> \<Union>\<A>"} does
172.175 + not mention @{text "\<exists>"} and @{text "\<and>"} at all, but admits to obtain
172.176 + directly a local @{term "A"} such that @{prop "x \<in> A"} and @{prop "A
172.177 + \<in> \<A>"} hold. This corresponds to the following Isar proof and
172.178 + inference rule, respectively:
172.179 +*}
172.180 +
172.181 +text_raw {*\medskip\begin{minipage}{0.6\textwidth}*}
172.182 +
172.183 +(*<*)
172.184 +lemma True
172.185 +proof
172.186 +(*>*)
172.187 + assume "x \<in> \<Union>\<A>"
172.188 + then have C
172.189 + proof
172.190 + fix A
172.191 + assume "x \<in> A" and "A \<in> \<A>"
172.192 + show C sorry %noproof
172.193 + qed
172.194 +(*<*)
172.195 +qed
172.196 +(*>*)
172.197 +
172.198 +text_raw {*\end{minipage}\begin{minipage}{0.4\textwidth}*}
172.199 +
172.200 +text {*
172.201 + \infer{@{prop "C"}}{@{prop "x \<in> \<Union>\<A>"} & \infer*{@{prop "C"}~}{@{text "[A][x \<in> A, A \<in> \<A>]"}}}
172.202 +*}
172.203 +
172.204 +text_raw {*\end{minipage}*}
172.205 +
172.206 +text {*
172.207 + \medskip\noindent Although the Isar proof follows the natural
172.208 + deduction rule closely, the text reads not as natural as
172.209 + anticipated. There is a double occurrence of an arbitrary
172.210 + conclusion @{prop "C"}, which represents the final result, but is
172.211 + irrelevant for now. This issue arises for any elimination rule
172.212 + involving local parameters. Isar provides the derived language
172.213 + element @{command obtain}, which is able to perform the same
172.214 + elimination proof more conveniently:
172.215 +*}
172.216 +
172.217 +(*<*)
172.218 +lemma True
172.219 +proof
172.220 +(*>*)
172.221 + assume "x \<in> \<Union>\<A>"
172.222 + then obtain A where "x \<in> A" and "A \<in> \<A>" ..
172.223 +(*<*)
172.224 +qed
172.225 +(*>*)
172.226 +
172.227 +text {*
172.228 + \noindent Here we avoid to mention the final conclusion @{prop "C"}
172.229 + and return to plain forward reasoning. The rule involved in the
172.230 + ``@{command ".."}'' proof is the same as before.
172.231 +*}
172.232 +
172.233 +
172.234 +section {* The Pure framework \label{sec:framework-pure} *}
172.235 +
172.236 +text {*
172.237 + The Pure logic \cite{paulson-found,paulson700} is an intuitionistic
172.238 + fragment of higher-order logic \cite{church40}. In type-theoretic
172.239 + parlance, there are three levels of @{text "\<lambda>"}-calculus with
172.240 + corresponding arrows @{text "\<Rightarrow>"}/@{text "\<And>"}/@{text "\<Longrightarrow>"}:
172.241 +
172.242 + \medskip
172.243 + \begin{tabular}{ll}
172.244 + @{text "\<alpha> \<Rightarrow> \<beta>"} & syntactic function space (terms depending on terms) \\
172.245 + @{text "\<And>x. B(x)"} & universal quantification (proofs depending on terms) \\
172.246 + @{text "A \<Longrightarrow> B"} & implication (proofs depending on proofs) \\
172.247 + \end{tabular}
172.248 + \medskip
172.249 +
172.250 + \noindent Here only the types of syntactic terms, and the
172.251 + propositions of proof terms have been shown. The @{text
172.252 + "\<lambda>"}-structure of proofs can be recorded as an optional feature of
172.253 + the Pure inference kernel \cite{Berghofer-Nipkow:2000:TPHOL}, but
172.254 + the formal system can never depend on them due to \emph{proof
172.255 + irrelevance}.
172.256 +
172.257 + On top of this most primitive layer of proofs, Pure implements a
172.258 + generic calculus for nested natural deduction rules, similar to
172.259 + \cite{Schroeder-Heister:1984}. Here object-logic inferences are
172.260 + internalized as formulae over @{text "\<And>"} and @{text "\<Longrightarrow>"}.
172.261 + Combining such rule statements may involve higher-order unification
172.262 + \cite{paulson-natural}.
172.263 +*}
172.264 +
172.265 +
172.266 +subsection {* Primitive inferences *}
172.267 +
172.268 +text {*
172.269 + Term syntax provides explicit notation for abstraction @{text "\<lambda>x ::
172.270 + \<alpha>. b(x)"} and application @{text "b a"}, while types are usually
172.271 + implicit thanks to type-inference; terms of type @{text "prop"} are
172.272 + called propositions. Logical statements are composed via @{text "\<And>x
172.273 + :: \<alpha>. B(x)"} and @{text "A \<Longrightarrow> B"}. Primitive reasoning operates on
172.274 + judgments of the form @{text "\<Gamma> \<turnstile> \<phi>"}, with standard introduction
172.275 + and elimination rules for @{text "\<And>"} and @{text "\<Longrightarrow>"} that refer to
172.276 + fixed parameters @{text "x\<^isub>1, \<dots>, x\<^isub>m"} and hypotheses
172.277 + @{text "A\<^isub>1, \<dots>, A\<^isub>n"} from the context @{text "\<Gamma>"};
172.278 + the corresponding proof terms are left implicit. The subsequent
172.279 + inference rules define @{text "\<Gamma> \<turnstile> \<phi>"} inductively, relative to a
172.280 + collection of axioms:
172.281 +
172.282 + \[
172.283 + \infer{@{text "\<turnstile> A"}}{(@{text "A"} \text{~axiom})}
172.284 + \qquad
172.285 + \infer{@{text "A \<turnstile> A"}}{}
172.286 + \]
172.287 +
172.288 + \[
172.289 + \infer{@{text "\<Gamma> \<turnstile> \<And>x. B(x)"}}{@{text "\<Gamma> \<turnstile> B(x)"} & @{text "x \<notin> \<Gamma>"}}
172.290 + \qquad
172.291 + \infer{@{text "\<Gamma> \<turnstile> B(a)"}}{@{text "\<Gamma> \<turnstile> \<And>x. B(x)"}}
172.292 + \]
172.293 +
172.294 + \[
172.295 + \infer{@{text "\<Gamma> - A \<turnstile> A \<Longrightarrow> B"}}{@{text "\<Gamma> \<turnstile> B"}}
172.296 + \qquad
172.297 + \infer{@{text "\<Gamma>\<^sub>1 \<union> \<Gamma>\<^sub>2 \<turnstile> B"}}{@{text "\<Gamma>\<^sub>1 \<turnstile> A \<Longrightarrow> B"} & @{text "\<Gamma>\<^sub>2 \<turnstile> A"}}
172.298 + \]
172.299 +
172.300 + Furthermore, Pure provides a built-in equality @{text "\<equiv> :: \<alpha> \<Rightarrow> \<alpha> \<Rightarrow>
172.301 + prop"} with axioms for reflexivity, substitution, extensionality,
172.302 + and @{text "\<alpha>\<beta>\<eta>"}-conversion on @{text "\<lambda>"}-terms.
172.303 +
172.304 + \medskip An object-logic introduces another layer on top of Pure,
172.305 + e.g.\ with types @{text "i"} for individuals and @{text "o"} for
172.306 + propositions, term constants @{text "Trueprop :: o \<Rightarrow> prop"} as
172.307 + (implicit) derivability judgment and connectives like @{text "\<and> :: o
172.308 + \<Rightarrow> o \<Rightarrow> o"} or @{text "\<forall> :: (i \<Rightarrow> o) \<Rightarrow> o"}, and axioms for object-level
172.309 + rules such as @{text "conjI: A \<Longrightarrow> B \<Longrightarrow> A \<and> B"} or @{text "allI: (\<And>x. B
172.310 + x) \<Longrightarrow> \<forall>x. B x"}. Derived object rules are represented as theorems of
172.311 + Pure. After the initial object-logic setup, further axiomatizations
172.312 + are usually avoided; plain definitions and derived principles are
172.313 + used exclusively.
172.314 +*}
172.315 +
172.316 +
172.317 +subsection {* Reasoning with rules \label{sec:framework-resolution} *}
172.318 +
172.319 +text {*
172.320 + Primitive inferences mostly serve foundational purposes. The main
172.321 + reasoning mechanisms of Pure operate on nested natural deduction
172.322 + rules expressed as formulae, using @{text "\<And>"} to bind local
172.323 + parameters and @{text "\<Longrightarrow>"} to express entailment. Multiple
172.324 + parameters and premises are represented by repeating these
172.325 + connectives in a right-associative manner.
172.326 +
172.327 + Since @{text "\<And>"} and @{text "\<Longrightarrow>"} commute thanks to the theorem
172.328 + @{prop "(A \<Longrightarrow> (\<And>x. B x)) \<equiv> (\<And>x. A \<Longrightarrow> B x)"}, we may assume w.l.o.g.\
172.329 + that rule statements always observe the normal form where
172.330 + quantifiers are pulled in front of implications at each level of
172.331 + nesting. This means that any Pure proposition may be presented as a
172.332 + \emph{Hereditary Harrop Formula} \cite{Miller:1991} which is of the
172.333 + form @{text "\<And>x\<^isub>1 \<dots> x\<^isub>m. H\<^isub>1 \<Longrightarrow> \<dots> H\<^isub>n \<Longrightarrow>
172.334 + A"} for @{text "m, n \<ge> 0"}, and @{text "A"} atomic, and @{text
172.335 + "H\<^isub>1, \<dots>, H\<^isub>n"} being recursively of the same format.
172.336 + Following the convention that outermost quantifiers are implicit,
172.337 + Horn clauses @{text "A\<^isub>1 \<Longrightarrow> \<dots> A\<^isub>n \<Longrightarrow> A"} are a special
172.338 + case of this.
172.339 +
172.340 + For example, @{text "\<inter>"}-introduction rule encountered before is
172.341 + represented as a Pure theorem as follows:
172.342 + \[
172.343 + @{text "IntI:"}~@{prop "x \<in> A \<Longrightarrow> x \<in> B \<Longrightarrow> x \<in> A \<inter> B"}
172.344 + \]
172.345 +
172.346 + \noindent This is a plain Horn clause, since no further nesting on
172.347 + the left is involved. The general @{text "\<Inter>"}-introduction
172.348 + corresponds to a Hereditary Harrop Formula with one additional level
172.349 + of nesting:
172.350 + \[
172.351 + @{text "InterI:"}~@{prop "(\<And>A. A \<in> \<A> \<Longrightarrow> x \<in> A) \<Longrightarrow> x \<in> \<Inter>\<A>"}
172.352 + \]
172.353 +
172.354 + \medskip Goals are also represented as rules: @{text "A\<^isub>1 \<Longrightarrow>
172.355 + \<dots> A\<^isub>n \<Longrightarrow> C"} states that the sub-goals @{text "A\<^isub>1, \<dots>,
172.356 + A\<^isub>n"} entail the result @{text "C"}; for @{text "n = 0"} the
172.357 + goal is finished. To allow @{text "C"} being a rule statement
172.358 + itself, we introduce the protective marker @{text "# :: prop \<Rightarrow>
172.359 + prop"}, which is defined as identity and hidden from the user. We
172.360 + initialize and finish goal states as follows:
172.361 +
172.362 + \[
172.363 + \begin{array}{c@ {\qquad}c}
172.364 + \infer[(@{inference_def init})]{@{text "C \<Longrightarrow> #C"}}{} &
172.365 + \infer[(@{inference_def finish})]{@{text C}}{@{text "#C"}}
172.366 + \end{array}
172.367 + \]
172.368 +
172.369 + \noindent Goal states are refined in intermediate proof steps until
172.370 + a finished form is achieved. Here the two main reasoning principles
172.371 + are @{inference resolution}, for back-chaining a rule against a
172.372 + sub-goal (replacing it by zero or more sub-goals), and @{inference
172.373 + assumption}, for solving a sub-goal (finding a short-circuit with
172.374 + local assumptions). Below @{text "\<^vec>x"} stands for @{text
172.375 + "x\<^isub>1, \<dots>, x\<^isub>n"} (@{text "n \<ge> 0"}).
172.376 +
172.377 + \[
172.378 + \infer[(@{inference_def resolution})]
172.379 + {@{text "(\<And>\<^vec>x. \<^vec>H \<^vec>x \<Longrightarrow> \<^vec>A (\<^vec>a \<^vec>x))\<vartheta> \<Longrightarrow> C\<vartheta>"}}
172.380 + {\begin{tabular}{rl}
172.381 + @{text "rule:"} &
172.382 + @{text "\<^vec>A \<^vec>a \<Longrightarrow> B \<^vec>a"} \\
172.383 + @{text "goal:"} &
172.384 + @{text "(\<And>\<^vec>x. \<^vec>H \<^vec>x \<Longrightarrow> B' \<^vec>x) \<Longrightarrow> C"} \\
172.385 + @{text "goal unifier:"} &
172.386 + @{text "(\<lambda>\<^vec>x. B (\<^vec>a \<^vec>x))\<vartheta> = B'\<vartheta>"} \\
172.387 + \end{tabular}}
172.388 + \]
172.389 +
172.390 + \medskip
172.391 +
172.392 + \[
172.393 + \infer[(@{inference_def assumption})]{@{text "C\<vartheta>"}}
172.394 + {\begin{tabular}{rl}
172.395 + @{text "goal:"} &
172.396 + @{text "(\<And>\<^vec>x. \<^vec>H \<^vec>x \<Longrightarrow> A \<^vec>x) \<Longrightarrow> C"} \\
172.397 + @{text "assm unifier:"} & @{text "A\<vartheta> = H\<^sub>i\<vartheta>"}~~\text{(for some~@{text "H\<^sub>i"})} \\
172.398 + \end{tabular}}
172.399 + \]
172.400 +
172.401 + The following trace illustrates goal-oriented reasoning in
172.402 + Isabelle/Pure:
172.403 +
172.404 + {\footnotesize
172.405 + \medskip
172.406 + \begin{tabular}{r@ {\quad}l}
172.407 + @{text "(A \<and> B \<Longrightarrow> B \<and> A) \<Longrightarrow> #(A \<and> B \<Longrightarrow> B \<and> A)"} & @{text "(init)"} \\
172.408 + @{text "(A \<and> B \<Longrightarrow> B) \<Longrightarrow> (A \<and> B \<Longrightarrow> A) \<Longrightarrow> #\<dots>"} & @{text "(resolution B \<Longrightarrow> A \<Longrightarrow> B \<and> A)"} \\
172.409 + @{text "(A \<and> B \<Longrightarrow> A \<and> B) \<Longrightarrow> (A \<and> B \<Longrightarrow> A) \<Longrightarrow> #\<dots>"} & @{text "(resolution A \<and> B \<Longrightarrow> B)"} \\
172.410 + @{text "(A \<and> B \<Longrightarrow> A) \<Longrightarrow> #\<dots>"} & @{text "(assumption)"} \\
172.411 + @{text "(A \<and> B \<Longrightarrow> B \<and> A) \<Longrightarrow> #\<dots>"} & @{text "(resolution A \<and> B \<Longrightarrow> A)"} \\
172.412 + @{text "#\<dots>"} & @{text "(assumption)"} \\
172.413 + @{text "A \<and> B \<Longrightarrow> B \<and> A"} & @{text "(finish)"} \\
172.414 + \end{tabular}
172.415 + \medskip
172.416 + }
172.417 +
172.418 + Compositions of @{inference assumption} after @{inference
172.419 + resolution} occurs quite often, typically in elimination steps.
172.420 + Traditional Isabelle tactics accommodate this by a combined
172.421 + @{inference_def elim_resolution} principle. In contrast, Isar uses
172.422 + a slightly more refined combination, where the assumptions to be
172.423 + closed are marked explicitly, using again the protective marker
172.424 + @{text "#"}:
172.425 +
172.426 + \[
172.427 + \infer[(@{inference refinement})]
172.428 + {@{text "(\<And>\<^vec>x. \<^vec>H \<^vec>x \<Longrightarrow> \<^vec>G' (\<^vec>a \<^vec>x))\<vartheta> \<Longrightarrow> C\<vartheta>"}}
172.429 + {\begin{tabular}{rl}
172.430 + @{text "sub\<dash>proof:"} &
172.431 + @{text "\<^vec>G \<^vec>a \<Longrightarrow> B \<^vec>a"} \\
172.432 + @{text "goal:"} &
172.433 + @{text "(\<And>\<^vec>x. \<^vec>H \<^vec>x \<Longrightarrow> B' \<^vec>x) \<Longrightarrow> C"} \\
172.434 + @{text "goal unifier:"} &
172.435 + @{text "(\<lambda>\<^vec>x. B (\<^vec>a \<^vec>x))\<vartheta> = B'\<vartheta>"} \\
172.436 + @{text "assm unifiers:"} &
172.437 + @{text "(\<lambda>\<^vec>x. G\<^sub>j (\<^vec>a \<^vec>x))\<vartheta> = #H\<^sub>i\<vartheta>"} \\
172.438 + & \quad (for each marked @{text "G\<^sub>j"} some @{text "#H\<^sub>i"}) \\
172.439 + \end{tabular}}
172.440 + \]
172.441 +
172.442 + \noindent Here the @{text "sub\<dash>proof"} rule stems from the
172.443 + main @{command fix}-@{command assume}-@{command show} outline of
172.444 + Isar (cf.\ \secref{sec:framework-subproof}): each assumption
172.445 + indicated in the text results in a marked premise @{text "G"} above.
172.446 + The marking enforces resolution against one of the sub-goal's
172.447 + premises. Consequently, @{command fix}-@{command assume}-@{command
172.448 + show} enables to fit the result of a sub-proof quite robustly into a
172.449 + pending sub-goal, while maintaining a good measure of flexibility.
172.450 +*}
172.451 +
172.452 +
172.453 +section {* The Isar proof language \label{sec:framework-isar} *}
172.454 +
172.455 +text {*
172.456 + Structured proofs are presented as high-level expressions for
172.457 + composing entities of Pure (propositions, facts, and goals). The
172.458 + Isar proof language allows to organize reasoning within the
172.459 + underlying rule calculus of Pure, but Isar is not another logical
172.460 + calculus!
172.461 +
172.462 + Isar is an exercise in sound minimalism. Approximately half of the
172.463 + language is introduced as primitive, the rest defined as derived
172.464 + concepts. The following grammar describes the core language
172.465 + (category @{text "proof"}), which is embedded into theory
172.466 + specification elements such as @{command theorem}; see also
172.467 + \secref{sec:framework-stmt} for the separate category @{text
172.468 + "statement"}.
172.469 +
172.470 + \medskip
172.471 + \begin{tabular}{rcl}
172.472 + @{text "theory\<dash>stmt"} & = & @{command "theorem"}~@{text "statement proof |"}~~@{command "definition"}~@{text "\<dots> | \<dots>"} \\[1ex]
172.473 +
172.474 + @{text "proof"} & = & @{text "prfx\<^sup>*"}~@{command "proof"}~@{text "method\<^sup>? stmt\<^sup>*"}~@{command "qed"}~@{text "method\<^sup>?"} \\[1ex]
172.475 +
172.476 + @{text prfx} & = & @{command "using"}~@{text "facts"} \\
172.477 + & @{text "|"} & @{command "unfolding"}~@{text "facts"} \\
172.478 +
172.479 + @{text stmt} & = & @{command "{"}~@{text "stmt\<^sup>*"}~@{command "}"} \\
172.480 + & @{text "|"} & @{command "next"} \\
172.481 + & @{text "|"} & @{command "note"}~@{text "name = facts"} \\
172.482 + & @{text "|"} & @{command "let"}~@{text "term = term"} \\
172.483 + & @{text "|"} & @{command "fix"}~@{text "var\<^sup>+"} \\
172.484 + & @{text "|"} & @{command assume}~@{text "\<guillemotleft>inference\<guillemotright> name: props"} \\
172.485 + & @{text "|"} & @{command "then"}@{text "\<^sup>?"}~@{text goal} \\
172.486 + @{text goal} & = & @{command "have"}~@{text "name: props proof"} \\
172.487 + & @{text "|"} & @{command "show"}~@{text "name: props proof"} \\
172.488 + \end{tabular}
172.489 +
172.490 + \medskip Simultaneous propositions or facts may be separated by the
172.491 + @{keyword "and"} keyword.
172.492 +
172.493 + \medskip The syntax for terms and propositions is inherited from
172.494 + Pure (and the object-logic). A @{text "pattern"} is a @{text
172.495 + "term"} with schematic variables, to be bound by higher-order
172.496 + matching.
172.497 +
172.498 + \medskip Facts may be referenced by name or proposition. For
172.499 + example, the result of ``@{command have}~@{text "a: A \<langle>proof\<rangle>"}''
172.500 + becomes available both as @{text "a"} and
172.501 + \isacharbackquoteopen@{text "A"}\isacharbackquoteclose. Moreover,
172.502 + fact expressions may involve attributes that modify either the
172.503 + theorem or the background context. For example, the expression
172.504 + ``@{text "a [OF b]"}'' refers to the composition of two facts
172.505 + according to the @{inference resolution} inference of
172.506 + \secref{sec:framework-resolution}, while ``@{text "a [intro]"}''
172.507 + declares a fact as introduction rule in the context.
172.508 +
172.509 + The special fact called ``@{fact this}'' always refers to the last
172.510 + result, as produced by @{command note}, @{command assume}, @{command
172.511 + have}, or @{command show}. Since @{command note} occurs
172.512 + frequently together with @{command then} we provide some
172.513 + abbreviations:
172.514 +
172.515 + \medskip
172.516 + \begin{tabular}{rcl}
172.517 + @{command from}~@{text a} & @{text "\<equiv>"} & @{command note}~@{text a}~@{command then} \\
172.518 + @{command with}~@{text a} & @{text "\<equiv>"} & @{command from}~@{text "a \<AND> this"} \\
172.519 + \end{tabular}
172.520 + \medskip
172.521 +
172.522 + The @{text "method"} category is essentially a parameter and may be
172.523 + populated later. Methods use the facts indicated by @{command
172.524 + "then"} or @{command using}, and then operate on the goal state.
172.525 + Some basic methods are predefined: ``@{method "-"}'' leaves the goal
172.526 + unchanged, ``@{method this}'' applies the facts as rules to the
172.527 + goal, ``@{method "rule"}'' applies the facts to another rule and the
172.528 + result to the goal (both ``@{method this}'' and ``@{method rule}''
172.529 + refer to @{inference resolution} of
172.530 + \secref{sec:framework-resolution}). The secondary arguments to
172.531 + ``@{method rule}'' may be specified explicitly as in ``@{text "(rule
172.532 + a)"}'', or picked from the context. In the latter case, the system
172.533 + first tries rules declared as @{attribute (Pure) elim} or
172.534 + @{attribute (Pure) dest}, followed by those declared as @{attribute
172.535 + (Pure) intro}.
172.536 +
172.537 + The default method for @{command proof} is ``@{method rule}''
172.538 + (arguments picked from the context), for @{command qed} it is
172.539 + ``@{method "-"}''. Further abbreviations for terminal proof steps
172.540 + are ``@{command "by"}~@{text "method\<^sub>1 method\<^sub>2"}'' for
172.541 + ``@{command proof}~@{text "method\<^sub>1"}~@{command qed}~@{text
172.542 + "method\<^sub>2"}'', and ``@{command ".."}'' for ``@{command
172.543 + "by"}~@{method rule}, and ``@{command "."}'' for ``@{command
172.544 + "by"}~@{method this}''. The @{command unfolding} element operates
172.545 + directly on the current facts and goal by applying equalities.
172.546 +
172.547 + \medskip Block structure can be indicated explicitly by ``@{command
172.548 + "{"}~@{text "\<dots>"}~@{command "}"}'', although the body of a sub-proof
172.549 + already involves implicit nesting. In any case, @{command next}
172.550 + jumps into the next section of a block, i.e.\ it acts like closing
172.551 + an implicit block scope and opening another one; there is no direct
172.552 + correspondence to subgoals here.
172.553 +
172.554 + The remaining elements @{command fix} and @{command assume} build up
172.555 + a local context (see \secref{sec:framework-context}), while
172.556 + @{command show} refines a pending sub-goal by the rule resulting
172.557 + from a nested sub-proof (see \secref{sec:framework-subproof}).
172.558 + Further derived concepts will support calculational reasoning (see
172.559 + \secref{sec:framework-calc}).
172.560 +*}
172.561 +
172.562 +
172.563 +subsection {* Context elements \label{sec:framework-context} *}
172.564 +
172.565 +text {*
172.566 + In judgments @{text "\<Gamma> \<turnstile> \<phi>"} of the primitive framework, @{text "\<Gamma>"}
172.567 + essentially acts like a proof context. Isar elaborates this idea
172.568 + towards a higher-level notion, with additional information for
172.569 + type-inference, term abbreviations, local facts, hypotheses etc.
172.570 +
172.571 + The element @{command fix}~@{text "x :: \<alpha>"} declares a local
172.572 + parameter, i.e.\ an arbitrary-but-fixed entity of a given type; in
172.573 + results exported from the context, @{text "x"} may become anything.
172.574 + The @{command assume}~@{text "\<guillemotleft>inference\<guillemotright>"} element provides a
172.575 + general interface to hypotheses: ``@{command assume}~@{text
172.576 + "\<guillemotleft>inference\<guillemotright> A"}'' produces @{text "A \<turnstile> A"} locally, while the
172.577 + included inference tells how to discharge @{text A} from results
172.578 + @{text "A \<turnstile> B"} later on. There is no user-syntax for @{text
172.579 + "\<guillemotleft>inference\<guillemotright>"}, i.e.\ it may only occur internally when derived
172.580 + commands are defined in ML.
172.581 +
172.582 + At the user-level, the default inference for @{command assume} is
172.583 + @{inference discharge} as given below. The additional variants
172.584 + @{command presume} and @{command def} are defined as follows:
172.585 +
172.586 + \medskip
172.587 + \begin{tabular}{rcl}
172.588 + @{command presume}~@{text A} & @{text "\<equiv>"} & @{command assume}~@{text "\<guillemotleft>weak\<dash>discharge\<guillemotright> A"} \\
172.589 + @{command def}~@{text "x \<equiv> a"} & @{text "\<equiv>"} & @{command fix}~@{text x}~@{command assume}~@{text "\<guillemotleft>expansion\<guillemotright> x \<equiv> a"} \\
172.590 + \end{tabular}
172.591 + \medskip
172.592 +
172.593 + \[
172.594 + \infer[(@{inference_def discharge})]{@{text "\<strut>\<Gamma> - A \<turnstile> #A \<Longrightarrow> B"}}{@{text "\<strut>\<Gamma> \<turnstile> B"}}
172.595 + \]
172.596 + \[
172.597 + \infer[(@{inference_def "weak\<dash>discharge"})]{@{text "\<strut>\<Gamma> - A \<turnstile> A \<Longrightarrow> B"}}{@{text "\<strut>\<Gamma> \<turnstile> B"}}
172.598 + \]
172.599 + \[
172.600 + \infer[(@{inference_def expansion})]{@{text "\<strut>\<Gamma> - (x \<equiv> a) \<turnstile> B a"}}{@{text "\<strut>\<Gamma> \<turnstile> B x"}}
172.601 + \]
172.602 +
172.603 + \medskip Note that @{inference discharge} and @{inference
172.604 + "weak\<dash>discharge"} differ in the marker for @{prop A}, which is
172.605 + relevant when the result of a @{command fix}-@{command
172.606 + assume}-@{command show} outline is composed with a pending goal,
172.607 + cf.\ \secref{sec:framework-subproof}.
172.608 +
172.609 + The most interesting derived context element in Isar is @{command
172.610 + obtain} \cite[\S5.3]{Wenzel-PhD}, which supports generalized
172.611 + elimination steps in a purely forward manner. The @{command obtain}
172.612 + command takes a specification of parameters @{text "\<^vec>x"} and
172.613 + assumptions @{text "\<^vec>A"} to be added to the context, together
172.614 + with a proof of a case rule stating that this extension is
172.615 + conservative (i.e.\ may be removed from closed results later on):
172.616 +
172.617 + \medskip
172.618 + \begin{tabular}{l}
172.619 + @{text "\<langle>facts\<rangle>"}~~@{command obtain}~@{text "\<^vec>x \<WHERE> \<^vec>A \<^vec>x \<langle>proof\<rangle> \<equiv>"} \\[0.5ex]
172.620 + \quad @{command have}~@{text "case: \<And>thesis. (\<And>\<^vec>x. \<^vec>A \<^vec>x \<Longrightarrow> thesis) \<Longrightarrow> thesis\<rangle>"} \\
172.621 + \quad @{command proof}~@{method "-"} \\
172.622 + \qquad @{command fix}~@{text thesis} \\
172.623 + \qquad @{command assume}~@{text "[intro]: \<And>\<^vec>x. \<^vec>A \<^vec>x \<Longrightarrow> thesis"} \\
172.624 + \qquad @{command show}~@{text thesis}~@{command using}~@{text "\<langle>facts\<rangle> \<langle>proof\<rangle>"} \\
172.625 + \quad @{command qed} \\
172.626 + \quad @{command fix}~@{text "\<^vec>x"}~@{command assume}~@{text "\<guillemotleft>elimination case\<guillemotright> \<^vec>A \<^vec>x"} \\
172.627 + \end{tabular}
172.628 + \medskip
172.629 +
172.630 + \[
172.631 + \infer[(@{inference elimination})]{@{text "\<Gamma> \<turnstile> B"}}{
172.632 + \begin{tabular}{rl}
172.633 + @{text "case:"} &
172.634 + @{text "\<Gamma> \<turnstile> \<And>thesis. (\<And>\<^vec>x. \<^vec>A \<^vec>x \<Longrightarrow> thesis) \<Longrightarrow> thesis"} \\[0.2ex]
172.635 + @{text "result:"} &
172.636 + @{text "\<Gamma> \<union> \<^vec>A \<^vec>y \<turnstile> B"} \\[0.2ex]
172.637 + \end{tabular}}
172.638 + \]
172.639 +
172.640 + \noindent Here the name ``@{text thesis}'' is a specific convention
172.641 + for an arbitrary-but-fixed proposition; in the primitive natural
172.642 + deduction rules shown before we have occasionally used @{text C}.
172.643 + The whole statement of ``@{command obtain}~@{text x}~@{keyword
172.644 + "where"}~@{text "A x"}'' may be read as a claim that @{text "A x"}
172.645 + may be assumed for some arbitrary-but-fixed @{text "x"}. Also note
172.646 + that ``@{command obtain}~@{text "A \<AND> B"}'' without parameters
172.647 + is similar to ``@{command have}~@{text "A \<AND> B"}'', but the
172.648 + latter involves multiple sub-goals.
172.649 +
172.650 + \medskip The subsequent Isar proof texts explain all context
172.651 + elements introduced above using the formal proof language itself.
172.652 + After finishing a local proof within a block, we indicate the
172.653 + exported result via @{command note}.
172.654 +*}
172.655 +
172.656 +(*<*)
172.657 +theorem True
172.658 +proof
172.659 +(*>*)
172.660 + txt_raw {* \begin{minipage}[t]{0.4\textwidth} *}
172.661 + {
172.662 + fix x
172.663 + have "B x" sorry %noproof
172.664 + }
172.665 + note `\<And>x. B x`
172.666 + txt_raw {* \end{minipage}\quad\begin{minipage}[t]{0.4\textwidth} *}(*<*)next(*>*)
172.667 + {
172.668 + assume A
172.669 + have B sorry %noproof
172.670 + }
172.671 + note `A \<Longrightarrow> B`
172.672 + txt_raw {* \end{minipage}\\[3ex]\begin{minipage}[t]{0.4\textwidth} *}(*<*)next(*>*)
172.673 + {
172.674 + def x \<equiv> a
172.675 + have "B x" sorry %noproof
172.676 + }
172.677 + note `B a`
172.678 + txt_raw {* \end{minipage}\quad\begin{minipage}[t]{0.4\textwidth} *}(*<*)next(*>*)
172.679 + {
172.680 + obtain x where "A x" sorry %noproof
172.681 + have B sorry %noproof
172.682 + }
172.683 + note `B`
172.684 + txt_raw {* \end{minipage} *}
172.685 +(*<*)
172.686 +qed
172.687 +(*>*)
172.688 +
172.689 +text {*
172.690 + \bigskip\noindent This illustrates the meaning of Isar context
172.691 + elements without goals getting in between.
172.692 +*}
172.693 +
172.694 +subsection {* Structured statements \label{sec:framework-stmt} *}
172.695 +
172.696 +text {*
172.697 + The category @{text "statement"} of top-level theorem specifications
172.698 + is defined as follows:
172.699 +
172.700 + \medskip
172.701 + \begin{tabular}{rcl}
172.702 + @{text "statement"} & @{text "\<equiv>"} & @{text "name: props \<AND> \<dots>"} \\
172.703 + & @{text "|"} & @{text "context\<^sup>* conclusion"} \\[0.5ex]
172.704 +
172.705 + @{text "context"} & @{text "\<equiv>"} & @{text "\<FIXES> vars \<AND> \<dots>"} \\
172.706 + & @{text "|"} & @{text "\<ASSUMES> name: props \<AND> \<dots>"} \\
172.707 +
172.708 + @{text "conclusion"} & @{text "\<equiv>"} & @{text "\<SHOWS> name: props \<AND> \<dots>"} \\
172.709 + & @{text "|"} & @{text "\<OBTAINS> vars \<AND> \<dots> \<WHERE> name: props \<AND> \<dots>"} \\
172.710 + & & \quad @{text "\<BBAR> \<dots>"} \\
172.711 + \end{tabular}
172.712 +
172.713 + \medskip\noindent A simple @{text "statement"} consists of named
172.714 + propositions. The full form admits local context elements followed
172.715 + by the actual conclusions, such as ``@{keyword "fixes"}~@{text
172.716 + x}~@{keyword "assumes"}~@{text "A x"}~@{keyword "shows"}~@{text "B
172.717 + x"}''. The final result emerges as a Pure rule after discharging
172.718 + the context: @{prop "\<And>x. A x \<Longrightarrow> B x"}.
172.719 +
172.720 + The @{keyword "obtains"} variant is another abbreviation defined
172.721 + below; unlike @{command obtain} (cf.\
172.722 + \secref{sec:framework-context}) there may be several ``cases''
172.723 + separated by ``@{text "\<BBAR>"}'', each consisting of several
172.724 + parameters (@{text "vars"}) and several premises (@{text "props"}).
172.725 + This specifies multi-branch elimination rules.
172.726 +
172.727 + \medskip
172.728 + \begin{tabular}{l}
172.729 + @{text "\<OBTAINS> \<^vec>x \<WHERE> \<^vec>A \<^vec>x \<BBAR> \<dots> \<equiv>"} \\[0.5ex]
172.730 + \quad @{text "\<FIXES> thesis"} \\
172.731 + \quad @{text "\<ASSUMES> [intro]: \<And>\<^vec>x. \<^vec>A \<^vec>x \<Longrightarrow> thesis \<AND> \<dots>"} \\
172.732 + \quad @{text "\<SHOWS> thesis"} \\
172.733 + \end{tabular}
172.734 + \medskip
172.735 +
172.736 + Presenting structured statements in such an ``open'' format usually
172.737 + simplifies the subsequent proof, because the outer structure of the
172.738 + problem is already laid out directly. E.g.\ consider the following
172.739 + canonical patterns for @{text "\<SHOWS>"} and @{text "\<OBTAINS>"},
172.740 + respectively:
172.741 +*}
172.742 +
172.743 +text_raw {*\begin{minipage}{0.5\textwidth}*}
172.744 +
172.745 +theorem
172.746 + fixes x and y
172.747 + assumes "A x" and "B y"
172.748 + shows "C x y"
172.749 +proof -
172.750 + from `A x` and `B y`
172.751 + show "C x y" sorry %noproof
172.752 +qed
172.753 +
172.754 +text_raw {*\end{minipage}\begin{minipage}{0.5\textwidth}*}
172.755 +
172.756 +theorem
172.757 + obtains x and y
172.758 + where "A x" and "B y"
172.759 +proof -
172.760 + have "A a" and "B b" sorry %noproof
172.761 + then show thesis ..
172.762 +qed
172.763 +
172.764 +text_raw {*\end{minipage}*}
172.765 +
172.766 +text {*
172.767 + \medskip\noindent Here local facts \isacharbackquoteopen@{text "A
172.768 + x"}\isacharbackquoteclose\ and \isacharbackquoteopen@{text "B
172.769 + y"}\isacharbackquoteclose\ are referenced immediately; there is no
172.770 + need to decompose the logical rule structure again. In the second
172.771 + proof the final ``@{command then}~@{command show}~@{text
172.772 + thesis}~@{command ".."}'' involves the local rule case @{text "\<And>x
172.773 + y. A x \<Longrightarrow> B y \<Longrightarrow> thesis"} for the particular instance of terms @{text
172.774 + "a"} and @{text "b"} produced in the body.
172.775 +*}
172.776 +
172.777 +
172.778 +subsection {* Structured proof refinement \label{sec:framework-subproof} *}
172.779 +
172.780 +text {*
172.781 + By breaking up the grammar for the Isar proof language, we may
172.782 + understand a proof text as a linear sequence of individual proof
172.783 + commands. These are interpreted as transitions of the Isar virtual
172.784 + machine (Isar/VM), which operates on a block-structured
172.785 + configuration in single steps. This allows users to write proof
172.786 + texts in an incremental manner, and inspect intermediate
172.787 + configurations for debugging.
172.788 +
172.789 + The basic idea is analogous to evaluating algebraic expressions on a
172.790 + stack machine: @{text "(a + b) \<cdot> c"} then corresponds to a sequence
172.791 + of single transitions for each symbol @{text "(, a, +, b, ), \<cdot>, c"}.
172.792 + In Isar the algebraic values are facts or goals, and the operations
172.793 + are inferences.
172.794 +
172.795 + \medskip The Isar/VM state maintains a stack of nodes, each node
172.796 + contains the local proof context, the linguistic mode, and a pending
172.797 + goal (optional). The mode determines the type of transition that
172.798 + may be performed next, it essentially alternates between forward and
172.799 + backward reasoning, with an intermediate stage for chained facts
172.800 + (see \figref{fig:isar-vm}).
172.801 +
172.802 + \begin{figure}[htb]
172.803 + \begin{center}
172.804 + \includegraphics[width=0.8\textwidth]{Thy/document/isar-vm}
172.805 + \end{center}
172.806 + \caption{Isar/VM modes}\label{fig:isar-vm}
172.807 + \end{figure}
172.808 +
172.809 + For example, in @{text "state"} mode Isar acts like a mathematical
172.810 + scratch-pad, accepting declarations like @{command fix}, @{command
172.811 + assume}, and claims like @{command have}, @{command show}. A goal
172.812 + statement changes the mode to @{text "prove"}, which means that we
172.813 + may now refine the problem via @{command unfolding} or @{command
172.814 + proof}. Then we are again in @{text "state"} mode of a proof body,
172.815 + which may issue @{command show} statements to solve pending
172.816 + sub-goals. A concluding @{command qed} will return to the original
172.817 + @{text "state"} mode one level upwards. The subsequent Isar/VM
172.818 + trace indicates block structure, linguistic mode, goal state, and
172.819 + inferences:
172.820 +*}
172.821 +
172.822 +text_raw {* \begingroup\footnotesize *}
172.823 +(*<*)lemma True
172.824 +proof
172.825 +(*>*)
172.826 + txt_raw {* \begin{minipage}[t]{0.18\textwidth} *}
172.827 + have "A \<longrightarrow> B"
172.828 + proof
172.829 + assume A
172.830 + show B
172.831 + sorry %noproof
172.832 + qed
172.833 + txt_raw {* \end{minipage}\quad
172.834 +\begin{minipage}[t]{0.06\textwidth}
172.835 +@{text "begin"} \\
172.836 +\\
172.837 +\\
172.838 +@{text "begin"} \\
172.839 +@{text "end"} \\
172.840 +@{text "end"} \\
172.841 +\end{minipage}
172.842 +\begin{minipage}[t]{0.08\textwidth}
172.843 +@{text "prove"} \\
172.844 +@{text "state"} \\
172.845 +@{text "state"} \\
172.846 +@{text "prove"} \\
172.847 +@{text "state"} \\
172.848 +@{text "state"} \\
172.849 +\end{minipage}\begin{minipage}[t]{0.35\textwidth}
172.850 +@{text "(A \<longrightarrow> B) \<Longrightarrow> #(A \<longrightarrow> B)"} \\
172.851 +@{text "(A \<Longrightarrow> B) \<Longrightarrow> #(A \<longrightarrow> B)"} \\
172.852 +\\
172.853 +\\
172.854 +@{text "#(A \<longrightarrow> B)"} \\
172.855 +@{text "A \<longrightarrow> B"} \\
172.856 +\end{minipage}\begin{minipage}[t]{0.4\textwidth}
172.857 +@{text "(init)"} \\
172.858 +@{text "(resolution impI)"} \\
172.859 +\\
172.860 +\\
172.861 +@{text "(refinement #A \<Longrightarrow> B)"} \\
172.862 +@{text "(finish)"} \\
172.863 +\end{minipage} *}
172.864 +(*<*)
172.865 +qed
172.866 +(*>*)
172.867 +text_raw {* \endgroup *}
172.868 +
172.869 +text {*
172.870 + \noindent Here the @{inference refinement} inference from
172.871 + \secref{sec:framework-resolution} mediates composition of Isar
172.872 + sub-proofs nicely. Observe that this principle incorporates some
172.873 + degree of freedom in proof composition. In particular, the proof
172.874 + body allows parameters and assumptions to be re-ordered, or commuted
172.875 + according to Hereditary Harrop Form. Moreover, context elements
172.876 + that are not used in a sub-proof may be omitted altogether. For
172.877 + example:
172.878 +*}
172.879 +
172.880 +text_raw {*\begin{minipage}{0.5\textwidth}*}
172.881 +
172.882 +(*<*)
172.883 +lemma True
172.884 +proof
172.885 +(*>*)
172.886 + have "\<And>x y. A x \<Longrightarrow> B y \<Longrightarrow> C x y"
172.887 + proof -
172.888 + fix x and y
172.889 + assume "A x" and "B y"
172.890 + show "C x y" sorry %noproof
172.891 + qed
172.892 +
172.893 +txt_raw {*\end{minipage}\begin{minipage}{0.5\textwidth}*}
172.894 +
172.895 +(*<*)
172.896 +next
172.897 +(*>*)
172.898 + have "\<And>x y. A x \<Longrightarrow> B y \<Longrightarrow> C x y"
172.899 + proof -
172.900 + fix x assume "A x"
172.901 + fix y assume "B y"
172.902 + show "C x y" sorry %noproof
172.903 + qed
172.904 +
172.905 +txt_raw {*\end{minipage}\\[3ex]\begin{minipage}{0.5\textwidth}*}
172.906 +
172.907 +(*<*)
172.908 +next
172.909 +(*>*)
172.910 + have "\<And>x y. A x \<Longrightarrow> B y \<Longrightarrow> C x y"
172.911 + proof -
172.912 + fix y assume "B y"
172.913 + fix x assume "A x"
172.914 + show "C x y" sorry
172.915 + qed
172.916 +
172.917 +txt_raw {*\end{minipage}\begin{minipage}{0.5\textwidth}*}
172.918 +(*<*)
172.919 +next
172.920 +(*>*)
172.921 + have "\<And>x y. A x \<Longrightarrow> B y \<Longrightarrow> C x y"
172.922 + proof -
172.923 + fix y assume "B y"
172.924 + fix x
172.925 + show "C x y" sorry
172.926 + qed
172.927 +(*<*)
172.928 +qed
172.929 +(*>*)
172.930 +
172.931 +text_raw {*\end{minipage}*}
172.932 +
172.933 +text {*
172.934 + \medskip\noindent Such ``peephole optimizations'' of Isar texts are
172.935 + practically important to improve readability, by rearranging
172.936 + contexts elements according to the natural flow of reasoning in the
172.937 + body, while still observing the overall scoping rules.
172.938 +
172.939 + \medskip This illustrates the basic idea of structured proof
172.940 + processing in Isar. The main mechanisms are based on natural
172.941 + deduction rule composition within the Pure framework. In
172.942 + particular, there are no direct operations on goal states within the
172.943 + proof body. Moreover, there is no hidden automated reasoning
172.944 + involved, just plain unification.
172.945 +*}
172.946 +
172.947 +
172.948 +subsection {* Calculational reasoning \label{sec:framework-calc} *}
172.949 +
172.950 +text {*
172.951 + The existing Isar infrastructure is sufficiently flexible to support
172.952 + calculational reasoning (chains of transitivity steps) as derived
172.953 + concept. The generic proof elements introduced below depend on
172.954 + rules declared as @{attribute trans} in the context. It is left to
172.955 + the object-logic to provide a suitable rule collection for mixed
172.956 + relations of @{text "="}, @{text "<"}, @{text "\<le>"}, @{text "\<subset>"},
172.957 + @{text "\<subseteq>"} etc. Due to the flexibility of rule composition
172.958 + (\secref{sec:framework-resolution}), substitution of equals by
172.959 + equals is covered as well, even substitution of inequalities
172.960 + involving monotonicity conditions; see also \cite[\S6]{Wenzel-PhD}
172.961 + and \cite{Bauer-Wenzel:2001}.
172.962 +
172.963 + The generic calculational mechanism is based on the observation that
172.964 + rules such as @{text "trans:"}~@{prop "x = y \<Longrightarrow> y = z \<Longrightarrow> x = z"}
172.965 + proceed from the premises towards the conclusion in a deterministic
172.966 + fashion. Thus we may reason in forward mode, feeding intermediate
172.967 + results into rules selected from the context. The course of
172.968 + reasoning is organized by maintaining a secondary fact called
172.969 + ``@{fact calculation}'', apart from the primary ``@{fact this}''
172.970 + already provided by the Isar primitives. In the definitions below,
172.971 + @{attribute OF} refers to @{inference resolution}
172.972 + (\secref{sec:framework-resolution}) with multiple rule arguments,
172.973 + and @{text "trans"} represents to a suitable rule from the context:
172.974 +
172.975 + \begin{matharray}{rcl}
172.976 + @{command "also"}@{text "\<^sub>0"} & \equiv & @{command "note"}~@{text "calculation = this"} \\
172.977 + @{command "also"}@{text "\<^sub>n\<^sub>+\<^sub>1"} & \equiv & @{command "note"}~@{text "calculation = trans [OF calculation this]"} \\[0.5ex]
172.978 + @{command "finally"} & \equiv & @{command "also"}~@{command "from"}~@{text calculation} \\
172.979 + \end{matharray}
172.980 +
172.981 + \noindent The start of a calculation is determined implicitly in the
172.982 + text: here @{command also} sets @{fact calculation} to the current
172.983 + result; any subsequent occurrence will update @{fact calculation} by
172.984 + combination with the next result and a transitivity rule. The
172.985 + calculational sequence is concluded via @{command finally}, where
172.986 + the final result is exposed for use in a concluding claim.
172.987 +
172.988 + Here is a canonical proof pattern, using @{command have} to
172.989 + establish the intermediate results:
172.990 +*}
172.991 +
172.992 +(*<*)
172.993 +lemma True
172.994 +proof
172.995 +(*>*)
172.996 + have "a = b" sorry
172.997 + also have "\<dots> = c" sorry
172.998 + also have "\<dots> = d" sorry
172.999 + finally have "a = d" .
172.1000 +(*<*)
172.1001 +qed
172.1002 +(*>*)
172.1003 +
172.1004 +text {*
172.1005 + \noindent The term ``@{text "\<dots>"}'' above is a special abbreviation
172.1006 + provided by the Isabelle/Isar syntax layer: it statically refers to
172.1007 + the right-hand side argument of the previous statement given in the
172.1008 + text. Thus it happens to coincide with relevant sub-expressions in
172.1009 + the calculational chain, but the exact correspondence is dependent
172.1010 + on the transitivity rules being involved.
172.1011 +
172.1012 + \medskip Symmetry rules such as @{prop "x = y \<Longrightarrow> y = x"} are like
172.1013 + transitivities with only one premise. Isar maintains a separate
172.1014 + rule collection declared via the @{attribute sym} attribute, to be
172.1015 + used in fact expressions ``@{text "a [symmetric]"}'', or single-step
172.1016 + proofs ``@{command assume}~@{text "x = y"}~@{command then}~@{command
172.1017 + have}~@{text "y = x"}~@{command ".."}''.
172.1018 +*}
172.1019 +
172.1020 +end
172.1021 \ No newline at end of file
173.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
173.2 +++ b/doc-src/IsarRef/Thy/document/First_Order_Logic.tex Wed Mar 04 11:05:29 2009 +0100
173.3 @@ -0,0 +1,1417 @@
173.4 +%
173.5 +\begin{isabellebody}%
173.6 +\def\isabellecontext{First{\isacharunderscore}Order{\isacharunderscore}Logic}%
173.7 +%
173.8 +\isamarkupheader{Example: First-Order Logic%
173.9 +}
173.10 +\isamarkuptrue%
173.11 +%
173.12 +\isadelimvisible
173.13 +%
173.14 +\endisadelimvisible
173.15 +%
173.16 +\isatagvisible
173.17 +\isacommand{theory}\isamarkupfalse%
173.18 +\ First{\isacharunderscore}Order{\isacharunderscore}Logic\isanewline
173.19 +\isakeyword{imports}\ Pure\isanewline
173.20 +\isakeyword{begin}%
173.21 +\endisatagvisible
173.22 +{\isafoldvisible}%
173.23 +%
173.24 +\isadelimvisible
173.25 +%
173.26 +\endisadelimvisible
173.27 +%
173.28 +\begin{isamarkuptext}%
173.29 +\noindent In order to commence a new object-logic within
173.30 + Isabelle/Pure we introduce abstract syntactic categories \isa{{\isachardoublequote}i{\isachardoublequote}}
173.31 + for individuals and \isa{{\isachardoublequote}o{\isachardoublequote}} for object-propositions. The latter
173.32 + is embedded into the language of Pure propositions by means of a
173.33 + separate judgment.%
173.34 +\end{isamarkuptext}%
173.35 +\isamarkuptrue%
173.36 +\isacommand{typedecl}\isamarkupfalse%
173.37 +\ i\isanewline
173.38 +\isacommand{typedecl}\isamarkupfalse%
173.39 +\ o\isanewline
173.40 +\isanewline
173.41 +\isacommand{judgment}\isamarkupfalse%
173.42 +\isanewline
173.43 +\ \ Trueprop\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}o\ {\isasymRightarrow}\ prop{\isachardoublequoteclose}\ \ \ \ {\isacharparenleft}{\isachardoublequoteopen}{\isacharunderscore}{\isachardoublequoteclose}\ {\isadigit{5}}{\isacharparenright}%
173.44 +\begin{isamarkuptext}%
173.45 +\noindent Note that the object-logic judgement is implicit in the
173.46 + syntax: writing \isa{A} produces \isa{{\isachardoublequote}Trueprop\ A{\isachardoublequote}} internally.
173.47 + From the Pure perspective this means ``\isa{A} is derivable in the
173.48 + object-logic''.%
173.49 +\end{isamarkuptext}%
173.50 +\isamarkuptrue%
173.51 +%
173.52 +\isamarkupsubsection{Equational reasoning \label{sec:framework-ex-equal}%
173.53 +}
173.54 +\isamarkuptrue%
173.55 +%
173.56 +\begin{isamarkuptext}%
173.57 +Equality is axiomatized as a binary predicate on individuals, with
173.58 + reflexivity as introduction, and substitution as elimination
173.59 + principle. Note that the latter is particularly convenient in a
173.60 + framework like Isabelle, because syntactic congruences are
173.61 + implicitly produced by unification of \isa{{\isachardoublequote}B\ x{\isachardoublequote}} against
173.62 + expressions containing occurrences of \isa{x}.%
173.63 +\end{isamarkuptext}%
173.64 +\isamarkuptrue%
173.65 +\isacommand{axiomatization}\isamarkupfalse%
173.66 +\isanewline
173.67 +\ \ equal\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}i\ {\isasymRightarrow}\ i\ {\isasymRightarrow}\ o{\isachardoublequoteclose}\ \ {\isacharparenleft}\isakeyword{infix}\ {\isachardoublequoteopen}{\isacharequal}{\isachardoublequoteclose}\ {\isadigit{5}}{\isadigit{0}}{\isacharparenright}\isanewline
173.68 +\isakeyword{where}\isanewline
173.69 +\ \ refl\ {\isacharbrackleft}intro{\isacharbrackright}{\isacharcolon}\ {\isachardoublequoteopen}x\ {\isacharequal}\ x{\isachardoublequoteclose}\ \isakeyword{and}\isanewline
173.70 +\ \ subst\ {\isacharbrackleft}elim{\isacharbrackright}{\isacharcolon}\ {\isachardoublequoteopen}x\ {\isacharequal}\ y\ {\isasymLongrightarrow}\ B\ x\ {\isasymLongrightarrow}\ B\ y{\isachardoublequoteclose}%
173.71 +\begin{isamarkuptext}%
173.72 +\noindent Substitution is very powerful, but also hard to control in
173.73 + full generality. We derive some common symmetry~/ transitivity
173.74 + schemes of as particular consequences.%
173.75 +\end{isamarkuptext}%
173.76 +\isamarkuptrue%
173.77 +\isacommand{theorem}\isamarkupfalse%
173.78 +\ sym\ {\isacharbrackleft}sym{\isacharbrackright}{\isacharcolon}\isanewline
173.79 +\ \ \isakeyword{assumes}\ {\isachardoublequoteopen}x\ {\isacharequal}\ y{\isachardoublequoteclose}\isanewline
173.80 +\ \ \isakeyword{shows}\ {\isachardoublequoteopen}y\ {\isacharequal}\ x{\isachardoublequoteclose}\isanewline
173.81 +%
173.82 +\isadelimproof
173.83 +%
173.84 +\endisadelimproof
173.85 +%
173.86 +\isatagproof
173.87 +\isacommand{proof}\isamarkupfalse%
173.88 +\ {\isacharminus}\isanewline
173.89 +\ \ \isacommand{have}\isamarkupfalse%
173.90 +\ {\isachardoublequoteopen}x\ {\isacharequal}\ x{\isachardoublequoteclose}\ \isacommand{{\isachardot}{\isachardot}}\isamarkupfalse%
173.91 +\isanewline
173.92 +\ \ \isacommand{with}\isamarkupfalse%
173.93 +\ {\isacharbackquoteopen}x\ {\isacharequal}\ y{\isacharbackquoteclose}\ \isacommand{show}\isamarkupfalse%
173.94 +\ {\isachardoublequoteopen}y\ {\isacharequal}\ x{\isachardoublequoteclose}\ \isacommand{{\isachardot}{\isachardot}}\isamarkupfalse%
173.95 +\isanewline
173.96 +\isacommand{qed}\isamarkupfalse%
173.97 +%
173.98 +\endisatagproof
173.99 +{\isafoldproof}%
173.100 +%
173.101 +\isadelimproof
173.102 +\isanewline
173.103 +%
173.104 +\endisadelimproof
173.105 +\isanewline
173.106 +\isacommand{theorem}\isamarkupfalse%
173.107 +\ forw{\isacharunderscore}subst\ {\isacharbrackleft}trans{\isacharbrackright}{\isacharcolon}\isanewline
173.108 +\ \ \isakeyword{assumes}\ {\isachardoublequoteopen}y\ {\isacharequal}\ x{\isachardoublequoteclose}\ \isakeyword{and}\ {\isachardoublequoteopen}B\ x{\isachardoublequoteclose}\isanewline
173.109 +\ \ \isakeyword{shows}\ {\isachardoublequoteopen}B\ y{\isachardoublequoteclose}\isanewline
173.110 +%
173.111 +\isadelimproof
173.112 +%
173.113 +\endisadelimproof
173.114 +%
173.115 +\isatagproof
173.116 +\isacommand{proof}\isamarkupfalse%
173.117 +\ {\isacharminus}\isanewline
173.118 +\ \ \isacommand{from}\isamarkupfalse%
173.119 +\ {\isacharbackquoteopen}y\ {\isacharequal}\ x{\isacharbackquoteclose}\ \isacommand{have}\isamarkupfalse%
173.120 +\ {\isachardoublequoteopen}x\ {\isacharequal}\ y{\isachardoublequoteclose}\ \isacommand{{\isachardot}{\isachardot}}\isamarkupfalse%
173.121 +\isanewline
173.122 +\ \ \isacommand{from}\isamarkupfalse%
173.123 +\ this\ \isakeyword{and}\ {\isacharbackquoteopen}B\ x{\isacharbackquoteclose}\ \isacommand{show}\isamarkupfalse%
173.124 +\ {\isachardoublequoteopen}B\ y{\isachardoublequoteclose}\ \isacommand{{\isachardot}{\isachardot}}\isamarkupfalse%
173.125 +\isanewline
173.126 +\isacommand{qed}\isamarkupfalse%
173.127 +%
173.128 +\endisatagproof
173.129 +{\isafoldproof}%
173.130 +%
173.131 +\isadelimproof
173.132 +\isanewline
173.133 +%
173.134 +\endisadelimproof
173.135 +\isanewline
173.136 +\isacommand{theorem}\isamarkupfalse%
173.137 +\ back{\isacharunderscore}subst\ {\isacharbrackleft}trans{\isacharbrackright}{\isacharcolon}\isanewline
173.138 +\ \ \isakeyword{assumes}\ {\isachardoublequoteopen}B\ x{\isachardoublequoteclose}\ \isakeyword{and}\ {\isachardoublequoteopen}x\ {\isacharequal}\ y{\isachardoublequoteclose}\isanewline
173.139 +\ \ \isakeyword{shows}\ {\isachardoublequoteopen}B\ y{\isachardoublequoteclose}\isanewline
173.140 +%
173.141 +\isadelimproof
173.142 +%
173.143 +\endisadelimproof
173.144 +%
173.145 +\isatagproof
173.146 +\isacommand{proof}\isamarkupfalse%
173.147 +\ {\isacharminus}\isanewline
173.148 +\ \ \isacommand{from}\isamarkupfalse%
173.149 +\ {\isacharbackquoteopen}x\ {\isacharequal}\ y{\isacharbackquoteclose}\ \isakeyword{and}\ {\isacharbackquoteopen}B\ x{\isacharbackquoteclose}\isanewline
173.150 +\ \ \isacommand{show}\isamarkupfalse%
173.151 +\ {\isachardoublequoteopen}B\ y{\isachardoublequoteclose}\ \isacommand{{\isachardot}{\isachardot}}\isamarkupfalse%
173.152 +\isanewline
173.153 +\isacommand{qed}\isamarkupfalse%
173.154 +%
173.155 +\endisatagproof
173.156 +{\isafoldproof}%
173.157 +%
173.158 +\isadelimproof
173.159 +\isanewline
173.160 +%
173.161 +\endisadelimproof
173.162 +\isanewline
173.163 +\isacommand{theorem}\isamarkupfalse%
173.164 +\ trans\ {\isacharbrackleft}trans{\isacharbrackright}{\isacharcolon}\isanewline
173.165 +\ \ \isakeyword{assumes}\ {\isachardoublequoteopen}x\ {\isacharequal}\ y{\isachardoublequoteclose}\ \isakeyword{and}\ {\isachardoublequoteopen}y\ {\isacharequal}\ z{\isachardoublequoteclose}\isanewline
173.166 +\ \ \isakeyword{shows}\ {\isachardoublequoteopen}x\ {\isacharequal}\ z{\isachardoublequoteclose}\isanewline
173.167 +%
173.168 +\isadelimproof
173.169 +%
173.170 +\endisadelimproof
173.171 +%
173.172 +\isatagproof
173.173 +\isacommand{proof}\isamarkupfalse%
173.174 +\ {\isacharminus}\isanewline
173.175 +\ \ \isacommand{from}\isamarkupfalse%
173.176 +\ {\isacharbackquoteopen}y\ {\isacharequal}\ z{\isacharbackquoteclose}\ \isakeyword{and}\ {\isacharbackquoteopen}x\ {\isacharequal}\ y{\isacharbackquoteclose}\isanewline
173.177 +\ \ \isacommand{show}\isamarkupfalse%
173.178 +\ {\isachardoublequoteopen}x\ {\isacharequal}\ z{\isachardoublequoteclose}\ \isacommand{{\isachardot}{\isachardot}}\isamarkupfalse%
173.179 +\isanewline
173.180 +\isacommand{qed}\isamarkupfalse%
173.181 +%
173.182 +\endisatagproof
173.183 +{\isafoldproof}%
173.184 +%
173.185 +\isadelimproof
173.186 +%
173.187 +\endisadelimproof
173.188 +%
173.189 +\isamarkupsubsection{Basic group theory%
173.190 +}
173.191 +\isamarkuptrue%
173.192 +%
173.193 +\begin{isamarkuptext}%
173.194 +As an example for equational reasoning we consider some bits of
173.195 + group theory. The subsequent locale definition postulates group
173.196 + operations and axioms; we also derive some consequences of this
173.197 + specification.%
173.198 +\end{isamarkuptext}%
173.199 +\isamarkuptrue%
173.200 +\isacommand{locale}\isamarkupfalse%
173.201 +\ group\ {\isacharequal}\isanewline
173.202 +\ \ \isakeyword{fixes}\ prod\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}i\ {\isasymRightarrow}\ i\ {\isasymRightarrow}\ i{\isachardoublequoteclose}\ \ {\isacharparenleft}\isakeyword{infix}\ {\isachardoublequoteopen}{\isasymcirc}{\isachardoublequoteclose}\ {\isadigit{7}}{\isadigit{0}}{\isacharparenright}\isanewline
173.203 +\ \ \ \ \isakeyword{and}\ inv\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}i\ {\isasymRightarrow}\ i{\isachardoublequoteclose}\ \ {\isacharparenleft}{\isachardoublequoteopen}{\isacharparenleft}{\isacharunderscore}{\isasyminverse}{\isacharparenright}{\isachardoublequoteclose}\ {\isacharbrackleft}{\isadigit{1}}{\isadigit{0}}{\isadigit{0}}{\isadigit{0}}{\isacharbrackright}\ {\isadigit{9}}{\isadigit{9}}{\isadigit{9}}{\isacharparenright}\isanewline
173.204 +\ \ \ \ \isakeyword{and}\ unit\ {\isacharcolon}{\isacharcolon}\ i\ \ {\isacharparenleft}{\isachardoublequoteopen}{\isadigit{1}}{\isachardoublequoteclose}{\isacharparenright}\isanewline
173.205 +\ \ \isakeyword{assumes}\ assoc{\isacharcolon}\ {\isachardoublequoteopen}{\isacharparenleft}x\ {\isasymcirc}\ y{\isacharparenright}\ {\isasymcirc}\ z\ {\isacharequal}\ x\ {\isasymcirc}\ {\isacharparenleft}y\ {\isasymcirc}\ z{\isacharparenright}{\isachardoublequoteclose}\isanewline
173.206 +\ \ \ \ \isakeyword{and}\ left{\isacharunderscore}unit{\isacharcolon}\ \ {\isachardoublequoteopen}{\isadigit{1}}\ {\isasymcirc}\ x\ {\isacharequal}\ x{\isachardoublequoteclose}\isanewline
173.207 +\ \ \ \ \isakeyword{and}\ left{\isacharunderscore}inv{\isacharcolon}\ {\isachardoublequoteopen}x{\isasyminverse}\ {\isasymcirc}\ x\ {\isacharequal}\ {\isadigit{1}}{\isachardoublequoteclose}\isanewline
173.208 +\isakeyword{begin}\isanewline
173.209 +\isanewline
173.210 +\isacommand{theorem}\isamarkupfalse%
173.211 +\ right{\isacharunderscore}inv{\isacharcolon}\ {\isachardoublequoteopen}x\ {\isasymcirc}\ x{\isasyminverse}\ {\isacharequal}\ {\isadigit{1}}{\isachardoublequoteclose}\isanewline
173.212 +%
173.213 +\isadelimproof
173.214 +%
173.215 +\endisadelimproof
173.216 +%
173.217 +\isatagproof
173.218 +\isacommand{proof}\isamarkupfalse%
173.219 +\ {\isacharminus}\isanewline
173.220 +\ \ \isacommand{have}\isamarkupfalse%
173.221 +\ {\isachardoublequoteopen}x\ {\isasymcirc}\ x{\isasyminverse}\ {\isacharequal}\ {\isadigit{1}}\ {\isasymcirc}\ {\isacharparenleft}x\ {\isasymcirc}\ x{\isasyminverse}{\isacharparenright}{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse%
173.222 +\ {\isacharparenleft}rule\ left{\isacharunderscore}unit\ {\isacharbrackleft}symmetric{\isacharbrackright}{\isacharparenright}\isanewline
173.223 +\ \ \isacommand{also}\isamarkupfalse%
173.224 +\ \isacommand{have}\isamarkupfalse%
173.225 +\ {\isachardoublequoteopen}{\isasymdots}\ {\isacharequal}\ {\isacharparenleft}{\isadigit{1}}\ {\isasymcirc}\ x{\isacharparenright}\ {\isasymcirc}\ x{\isasyminverse}{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse%
173.226 +\ {\isacharparenleft}rule\ assoc\ {\isacharbrackleft}symmetric{\isacharbrackright}{\isacharparenright}\isanewline
173.227 +\ \ \isacommand{also}\isamarkupfalse%
173.228 +\ \isacommand{have}\isamarkupfalse%
173.229 +\ {\isachardoublequoteopen}{\isadigit{1}}\ {\isacharequal}\ {\isacharparenleft}x{\isasyminverse}{\isacharparenright}{\isasyminverse}\ {\isasymcirc}\ x{\isasyminverse}{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse%
173.230 +\ {\isacharparenleft}rule\ left{\isacharunderscore}inv\ {\isacharbrackleft}symmetric{\isacharbrackright}{\isacharparenright}\isanewline
173.231 +\ \ \isacommand{also}\isamarkupfalse%
173.232 +\ \isacommand{have}\isamarkupfalse%
173.233 +\ {\isachardoublequoteopen}{\isasymdots}\ {\isasymcirc}\ x\ {\isacharequal}\ {\isacharparenleft}x{\isasyminverse}{\isacharparenright}{\isasyminverse}\ {\isasymcirc}\ {\isacharparenleft}x{\isasyminverse}\ {\isasymcirc}\ x{\isacharparenright}{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse%
173.234 +\ {\isacharparenleft}rule\ assoc{\isacharparenright}\isanewline
173.235 +\ \ \isacommand{also}\isamarkupfalse%
173.236 +\ \isacommand{have}\isamarkupfalse%
173.237 +\ {\isachardoublequoteopen}x{\isasyminverse}\ {\isasymcirc}\ x\ {\isacharequal}\ {\isadigit{1}}{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse%
173.238 +\ {\isacharparenleft}rule\ left{\isacharunderscore}inv{\isacharparenright}\isanewline
173.239 +\ \ \isacommand{also}\isamarkupfalse%
173.240 +\ \isacommand{have}\isamarkupfalse%
173.241 +\ {\isachardoublequoteopen}{\isacharparenleft}{\isacharparenleft}x{\isasyminverse}{\isacharparenright}{\isasyminverse}\ {\isasymcirc}\ {\isasymdots}{\isacharparenright}\ {\isasymcirc}\ x{\isasyminverse}\ {\isacharequal}\ {\isacharparenleft}x{\isasyminverse}{\isacharparenright}{\isasyminverse}\ {\isasymcirc}\ {\isacharparenleft}{\isadigit{1}}\ {\isasymcirc}\ x{\isasyminverse}{\isacharparenright}{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse%
173.242 +\ {\isacharparenleft}rule\ assoc{\isacharparenright}\isanewline
173.243 +\ \ \isacommand{also}\isamarkupfalse%
173.244 +\ \isacommand{have}\isamarkupfalse%
173.245 +\ {\isachardoublequoteopen}{\isadigit{1}}\ {\isasymcirc}\ x{\isasyminverse}\ {\isacharequal}\ x{\isasyminverse}{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse%
173.246 +\ {\isacharparenleft}rule\ left{\isacharunderscore}unit{\isacharparenright}\isanewline
173.247 +\ \ \isacommand{also}\isamarkupfalse%
173.248 +\ \isacommand{have}\isamarkupfalse%
173.249 +\ {\isachardoublequoteopen}{\isacharparenleft}x{\isasyminverse}{\isacharparenright}{\isasyminverse}\ {\isasymcirc}\ {\isasymdots}\ {\isacharequal}\ {\isadigit{1}}{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse%
173.250 +\ {\isacharparenleft}rule\ left{\isacharunderscore}inv{\isacharparenright}\isanewline
173.251 +\ \ \isacommand{finally}\isamarkupfalse%
173.252 +\ \isacommand{show}\isamarkupfalse%
173.253 +\ {\isachardoublequoteopen}x\ {\isasymcirc}\ x{\isasyminverse}\ {\isacharequal}\ {\isadigit{1}}{\isachardoublequoteclose}\ \isacommand{{\isachardot}}\isamarkupfalse%
173.254 +\isanewline
173.255 +\isacommand{qed}\isamarkupfalse%
173.256 +%
173.257 +\endisatagproof
173.258 +{\isafoldproof}%
173.259 +%
173.260 +\isadelimproof
173.261 +\isanewline
173.262 +%
173.263 +\endisadelimproof
173.264 +\isanewline
173.265 +\isacommand{theorem}\isamarkupfalse%
173.266 +\ right{\isacharunderscore}unit{\isacharcolon}\ {\isachardoublequoteopen}x\ {\isasymcirc}\ {\isadigit{1}}\ {\isacharequal}\ x{\isachardoublequoteclose}\isanewline
173.267 +%
173.268 +\isadelimproof
173.269 +%
173.270 +\endisadelimproof
173.271 +%
173.272 +\isatagproof
173.273 +\isacommand{proof}\isamarkupfalse%
173.274 +\ {\isacharminus}\isanewline
173.275 +\ \ \isacommand{have}\isamarkupfalse%
173.276 +\ {\isachardoublequoteopen}{\isadigit{1}}\ {\isacharequal}\ x{\isasyminverse}\ {\isasymcirc}\ x{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse%
173.277 +\ {\isacharparenleft}rule\ left{\isacharunderscore}inv\ {\isacharbrackleft}symmetric{\isacharbrackright}{\isacharparenright}\isanewline
173.278 +\ \ \isacommand{also}\isamarkupfalse%
173.279 +\ \isacommand{have}\isamarkupfalse%
173.280 +\ {\isachardoublequoteopen}x\ {\isasymcirc}\ {\isasymdots}\ {\isacharequal}\ {\isacharparenleft}x\ {\isasymcirc}\ x{\isasyminverse}{\isacharparenright}\ {\isasymcirc}\ x{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse%
173.281 +\ {\isacharparenleft}rule\ assoc\ {\isacharbrackleft}symmetric{\isacharbrackright}{\isacharparenright}\isanewline
173.282 +\ \ \isacommand{also}\isamarkupfalse%
173.283 +\ \isacommand{have}\isamarkupfalse%
173.284 +\ {\isachardoublequoteopen}x\ {\isasymcirc}\ x{\isasyminverse}\ {\isacharequal}\ {\isadigit{1}}{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse%
173.285 +\ {\isacharparenleft}rule\ right{\isacharunderscore}inv{\isacharparenright}\isanewline
173.286 +\ \ \isacommand{also}\isamarkupfalse%
173.287 +\ \isacommand{have}\isamarkupfalse%
173.288 +\ {\isachardoublequoteopen}{\isasymdots}\ {\isasymcirc}\ x\ {\isacharequal}\ x{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse%
173.289 +\ {\isacharparenleft}rule\ left{\isacharunderscore}unit{\isacharparenright}\isanewline
173.290 +\ \ \isacommand{finally}\isamarkupfalse%
173.291 +\ \isacommand{show}\isamarkupfalse%
173.292 +\ {\isachardoublequoteopen}x\ {\isasymcirc}\ {\isadigit{1}}\ {\isacharequal}\ x{\isachardoublequoteclose}\ \isacommand{{\isachardot}}\isamarkupfalse%
173.293 +\isanewline
173.294 +\isacommand{qed}\isamarkupfalse%
173.295 +%
173.296 +\endisatagproof
173.297 +{\isafoldproof}%
173.298 +%
173.299 +\isadelimproof
173.300 +%
173.301 +\endisadelimproof
173.302 +%
173.303 +\begin{isamarkuptext}%
173.304 +\noindent Reasoning from basic axioms is often tedious. Our proofs
173.305 + work by producing various instances of the given rules (potentially
173.306 + the symmetric form) using the pattern ``\hyperlink{command.have}{\mbox{\isa{\isacommand{have}}}}~\isa{eq}~\hyperlink{command.by}{\mbox{\isa{\isacommand{by}}}}~\isa{{\isachardoublequote}{\isacharparenleft}rule\ r{\isacharparenright}{\isachardoublequote}}'' and composing the chain of
173.307 + results via \hyperlink{command.also}{\mbox{\isa{\isacommand{also}}}}/\hyperlink{command.finally}{\mbox{\isa{\isacommand{finally}}}}. These steps may
173.308 + involve any of the transitivity rules declared in
173.309 + \secref{sec:framework-ex-equal}, namely \isa{trans} in combining
173.310 + the first two results in \isa{right{\isacharunderscore}inv} and in the final steps of
173.311 + both proofs, \isa{forw{\isacharunderscore}subst} in the first combination of \isa{right{\isacharunderscore}unit}, and \isa{back{\isacharunderscore}subst} in all other calculational steps.
173.312 +
173.313 + Occasional substitutions in calculations are adequate, but should
173.314 + not be over-emphasized. The other extreme is to compose a chain by
173.315 + plain transitivity only, with replacements occurring always in
173.316 + topmost position. For example:%
173.317 +\end{isamarkuptext}%
173.318 +\isamarkuptrue%
173.319 +%
173.320 +\isadelimproof
173.321 +%
173.322 +\endisadelimproof
173.323 +%
173.324 +\isatagproof
173.325 +\ \ \isacommand{have}\isamarkupfalse%
173.326 +\ {\isachardoublequoteopen}x\ {\isasymcirc}\ {\isadigit{1}}\ {\isacharequal}\ x\ {\isasymcirc}\ {\isacharparenleft}x{\isasyminverse}\ {\isasymcirc}\ x{\isacharparenright}{\isachardoublequoteclose}\ \isacommand{unfolding}\isamarkupfalse%
173.327 +\ left{\isacharunderscore}inv\ \isacommand{{\isachardot}{\isachardot}}\isamarkupfalse%
173.328 +\isanewline
173.329 +\ \ \isacommand{also}\isamarkupfalse%
173.330 +\ \isacommand{have}\isamarkupfalse%
173.331 +\ {\isachardoublequoteopen}{\isasymdots}\ {\isacharequal}\ {\isacharparenleft}x\ {\isasymcirc}\ x{\isasyminverse}{\isacharparenright}\ {\isasymcirc}\ x{\isachardoublequoteclose}\ \isacommand{unfolding}\isamarkupfalse%
173.332 +\ assoc\ \isacommand{{\isachardot}{\isachardot}}\isamarkupfalse%
173.333 +\isanewline
173.334 +\ \ \isacommand{also}\isamarkupfalse%
173.335 +\ \isacommand{have}\isamarkupfalse%
173.336 +\ {\isachardoublequoteopen}{\isasymdots}\ {\isacharequal}\ {\isadigit{1}}\ {\isasymcirc}\ x{\isachardoublequoteclose}\ \isacommand{unfolding}\isamarkupfalse%
173.337 +\ right{\isacharunderscore}inv\ \isacommand{{\isachardot}{\isachardot}}\isamarkupfalse%
173.338 +\isanewline
173.339 +\ \ \isacommand{also}\isamarkupfalse%
173.340 +\ \isacommand{have}\isamarkupfalse%
173.341 +\ {\isachardoublequoteopen}{\isasymdots}\ {\isacharequal}\ x{\isachardoublequoteclose}\ \isacommand{unfolding}\isamarkupfalse%
173.342 +\ left{\isacharunderscore}unit\ \isacommand{{\isachardot}{\isachardot}}\isamarkupfalse%
173.343 +\isanewline
173.344 +\ \ \isacommand{finally}\isamarkupfalse%
173.345 +\ \isacommand{have}\isamarkupfalse%
173.346 +\ {\isachardoublequoteopen}x\ {\isasymcirc}\ {\isadigit{1}}\ {\isacharequal}\ x{\isachardoublequoteclose}\ \isacommand{{\isachardot}}\isamarkupfalse%
173.347 +%
173.348 +\endisatagproof
173.349 +{\isafoldproof}%
173.350 +%
173.351 +\isadelimproof
173.352 +%
173.353 +\endisadelimproof
173.354 +%
173.355 +\begin{isamarkuptext}%
173.356 +\noindent Here we have re-used the built-in mechanism for unfolding
173.357 + definitions in order to normalize each equational problem. A more
173.358 + realistic object-logic would include proper setup for the Simplifier
173.359 + (\secref{sec:simplifier}), the main automated tool for equational
173.360 + reasoning in Isabelle. Then ``\hyperlink{command.unfolding}{\mbox{\isa{\isacommand{unfolding}}}}~\isa{left{\isacharunderscore}inv}~\hyperlink{command.ddot}{\mbox{\isa{\isacommand{{\isachardot}{\isachardot}}}}}'' would become ``\hyperlink{command.by}{\mbox{\isa{\isacommand{by}}}}~\isa{{\isachardoublequote}{\isacharparenleft}simp\ only{\isacharcolon}\ left{\isacharunderscore}inv{\isacharparenright}{\isachardoublequote}}'' etc.%
173.361 +\end{isamarkuptext}%
173.362 +\isamarkuptrue%
173.363 +\isacommand{end}\isamarkupfalse%
173.364 +%
173.365 +\isamarkupsubsection{Propositional logic \label{sec:framework-ex-prop}%
173.366 +}
173.367 +\isamarkuptrue%
173.368 +%
173.369 +\begin{isamarkuptext}%
173.370 +We axiomatize basic connectives of propositional logic: implication,
173.371 + disjunction, and conjunction. The associated rules are modeled
173.372 + after Gentzen's system of Natural Deduction \cite{Gentzen:1935}.%
173.373 +\end{isamarkuptext}%
173.374 +\isamarkuptrue%
173.375 +\isacommand{axiomatization}\isamarkupfalse%
173.376 +\isanewline
173.377 +\ \ imp\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}o\ {\isasymRightarrow}\ o\ {\isasymRightarrow}\ o{\isachardoublequoteclose}\ \ {\isacharparenleft}\isakeyword{infixr}\ {\isachardoublequoteopen}{\isasymlongrightarrow}{\isachardoublequoteclose}\ {\isadigit{2}}{\isadigit{5}}{\isacharparenright}\ \isakeyword{where}\isanewline
173.378 +\ \ impI\ {\isacharbrackleft}intro{\isacharbrackright}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharparenleft}A\ {\isasymLongrightarrow}\ B{\isacharparenright}\ {\isasymLongrightarrow}\ A\ {\isasymlongrightarrow}\ B{\isachardoublequoteclose}\ \isakeyword{and}\isanewline
173.379 +\ \ impD\ {\isacharbrackleft}dest{\isacharbrackright}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharparenleft}A\ {\isasymlongrightarrow}\ B{\isacharparenright}\ {\isasymLongrightarrow}\ A\ {\isasymLongrightarrow}\ B{\isachardoublequoteclose}\isanewline
173.380 +\isanewline
173.381 +\isacommand{axiomatization}\isamarkupfalse%
173.382 +\isanewline
173.383 +\ \ disj\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}o\ {\isasymRightarrow}\ o\ {\isasymRightarrow}\ o{\isachardoublequoteclose}\ \ {\isacharparenleft}\isakeyword{infixr}\ {\isachardoublequoteopen}{\isasymor}{\isachardoublequoteclose}\ {\isadigit{3}}{\isadigit{0}}{\isacharparenright}\ \isakeyword{where}\isanewline
173.384 +\ \ disjI\isactrlisub {\isadigit{1}}\ {\isacharbrackleft}intro{\isacharbrackright}{\isacharcolon}\ {\isachardoublequoteopen}A\ {\isasymLongrightarrow}\ A\ {\isasymor}\ B{\isachardoublequoteclose}\ \isakeyword{and}\isanewline
173.385 +\ \ disjI\isactrlisub {\isadigit{2}}\ {\isacharbrackleft}intro{\isacharbrackright}{\isacharcolon}\ {\isachardoublequoteopen}B\ {\isasymLongrightarrow}\ A\ {\isasymor}\ B{\isachardoublequoteclose}\ \isakeyword{and}\isanewline
173.386 +\ \ disjE\ {\isacharbrackleft}elim{\isacharbrackright}{\isacharcolon}\ {\isachardoublequoteopen}A\ {\isasymor}\ B\ {\isasymLongrightarrow}\ {\isacharparenleft}A\ {\isasymLongrightarrow}\ C{\isacharparenright}\ {\isasymLongrightarrow}\ {\isacharparenleft}B\ {\isasymLongrightarrow}\ C{\isacharparenright}\ {\isasymLongrightarrow}\ C{\isachardoublequoteclose}\isanewline
173.387 +\isanewline
173.388 +\isacommand{axiomatization}\isamarkupfalse%
173.389 +\isanewline
173.390 +\ \ conj\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}o\ {\isasymRightarrow}\ o\ {\isasymRightarrow}\ o{\isachardoublequoteclose}\ \ {\isacharparenleft}\isakeyword{infixr}\ {\isachardoublequoteopen}{\isasymand}{\isachardoublequoteclose}\ {\isadigit{3}}{\isadigit{5}}{\isacharparenright}\ \isakeyword{where}\isanewline
173.391 +\ \ conjI\ {\isacharbrackleft}intro{\isacharbrackright}{\isacharcolon}\ {\isachardoublequoteopen}A\ {\isasymLongrightarrow}\ B\ {\isasymLongrightarrow}\ A\ {\isasymand}\ B{\isachardoublequoteclose}\ \isakeyword{and}\isanewline
173.392 +\ \ conjD\isactrlisub {\isadigit{1}}{\isacharcolon}\ {\isachardoublequoteopen}A\ {\isasymand}\ B\ {\isasymLongrightarrow}\ A{\isachardoublequoteclose}\ \isakeyword{and}\isanewline
173.393 +\ \ conjD\isactrlisub {\isadigit{2}}{\isacharcolon}\ {\isachardoublequoteopen}A\ {\isasymand}\ B\ {\isasymLongrightarrow}\ B{\isachardoublequoteclose}%
173.394 +\begin{isamarkuptext}%
173.395 +\noindent The conjunctive destructions have the disadvantage that
173.396 + decomposing \isa{{\isachardoublequote}A\ {\isasymand}\ B{\isachardoublequote}} involves an immediate decision which
173.397 + component should be projected. The more convenient simultaneous
173.398 + elimination \isa{{\isachardoublequote}A\ {\isasymand}\ B\ {\isasymLongrightarrow}\ {\isacharparenleft}A\ {\isasymLongrightarrow}\ B\ {\isasymLongrightarrow}\ C{\isacharparenright}\ {\isasymLongrightarrow}\ C{\isachardoublequote}} can be derived as
173.399 + follows:%
173.400 +\end{isamarkuptext}%
173.401 +\isamarkuptrue%
173.402 +\isacommand{theorem}\isamarkupfalse%
173.403 +\ conjE\ {\isacharbrackleft}elim{\isacharbrackright}{\isacharcolon}\isanewline
173.404 +\ \ \isakeyword{assumes}\ {\isachardoublequoteopen}A\ {\isasymand}\ B{\isachardoublequoteclose}\isanewline
173.405 +\ \ \isakeyword{obtains}\ A\ \isakeyword{and}\ B\isanewline
173.406 +%
173.407 +\isadelimproof
173.408 +%
173.409 +\endisadelimproof
173.410 +%
173.411 +\isatagproof
173.412 +\isacommand{proof}\isamarkupfalse%
173.413 +\isanewline
173.414 +\ \ \isacommand{from}\isamarkupfalse%
173.415 +\ {\isacharbackquoteopen}A\ {\isasymand}\ B{\isacharbackquoteclose}\ \isacommand{show}\isamarkupfalse%
173.416 +\ A\ \isacommand{by}\isamarkupfalse%
173.417 +\ {\isacharparenleft}rule\ conjD\isactrlisub {\isadigit{1}}{\isacharparenright}\isanewline
173.418 +\ \ \isacommand{from}\isamarkupfalse%
173.419 +\ {\isacharbackquoteopen}A\ {\isasymand}\ B{\isacharbackquoteclose}\ \isacommand{show}\isamarkupfalse%
173.420 +\ B\ \isacommand{by}\isamarkupfalse%
173.421 +\ {\isacharparenleft}rule\ conjD\isactrlisub {\isadigit{2}}{\isacharparenright}\isanewline
173.422 +\isacommand{qed}\isamarkupfalse%
173.423 +%
173.424 +\endisatagproof
173.425 +{\isafoldproof}%
173.426 +%
173.427 +\isadelimproof
173.428 +%
173.429 +\endisadelimproof
173.430 +%
173.431 +\begin{isamarkuptext}%
173.432 +\noindent Here is an example of swapping conjuncts with a single
173.433 + intermediate elimination step:%
173.434 +\end{isamarkuptext}%
173.435 +\isamarkuptrue%
173.436 +%
173.437 +\isadelimproof
173.438 +%
173.439 +\endisadelimproof
173.440 +%
173.441 +\isatagproof
173.442 +\ \ \isacommand{assume}\isamarkupfalse%
173.443 +\ {\isachardoublequoteopen}A\ {\isasymand}\ B{\isachardoublequoteclose}\isanewline
173.444 +\ \ \isacommand{then}\isamarkupfalse%
173.445 +\ \isacommand{obtain}\isamarkupfalse%
173.446 +\ B\ \isakeyword{and}\ A\ \isacommand{{\isachardot}{\isachardot}}\isamarkupfalse%
173.447 +\isanewline
173.448 +\ \ \isacommand{then}\isamarkupfalse%
173.449 +\ \isacommand{have}\isamarkupfalse%
173.450 +\ {\isachardoublequoteopen}B\ {\isasymand}\ A{\isachardoublequoteclose}\ \isacommand{{\isachardot}{\isachardot}}\isamarkupfalse%
173.451 +%
173.452 +\endisatagproof
173.453 +{\isafoldproof}%
173.454 +%
173.455 +\isadelimproof
173.456 +%
173.457 +\endisadelimproof
173.458 +%
173.459 +\begin{isamarkuptext}%
173.460 +\noindent Note that the analogous elimination rule for disjunction
173.461 + ``\isa{{\isachardoublequote}{\isasymASSUMES}\ A\ {\isasymor}\ B\ {\isasymOBTAINS}\ A\ {\isasymBBAR}\ B{\isachardoublequote}}'' coincides with
173.462 + the original axiomatization of \isa{disjE}.
173.463 +
173.464 + \medskip We continue propositional logic by introducing absurdity
173.465 + with its characteristic elimination. Plain truth may then be
173.466 + defined as a proposition that is trivially true.%
173.467 +\end{isamarkuptext}%
173.468 +\isamarkuptrue%
173.469 +\isacommand{axiomatization}\isamarkupfalse%
173.470 +\isanewline
173.471 +\ \ false\ {\isacharcolon}{\isacharcolon}\ o\ \ {\isacharparenleft}{\isachardoublequoteopen}{\isasymbottom}{\isachardoublequoteclose}{\isacharparenright}\ \isakeyword{where}\isanewline
173.472 +\ \ falseE\ {\isacharbrackleft}elim{\isacharbrackright}{\isacharcolon}\ {\isachardoublequoteopen}{\isasymbottom}\ {\isasymLongrightarrow}\ A{\isachardoublequoteclose}\isanewline
173.473 +\isanewline
173.474 +\isacommand{definition}\isamarkupfalse%
173.475 +\isanewline
173.476 +\ \ true\ {\isacharcolon}{\isacharcolon}\ o\ \ {\isacharparenleft}{\isachardoublequoteopen}{\isasymtop}{\isachardoublequoteclose}{\isacharparenright}\ \isakeyword{where}\isanewline
173.477 +\ \ {\isachardoublequoteopen}{\isasymtop}\ {\isasymequiv}\ {\isasymbottom}\ {\isasymlongrightarrow}\ {\isasymbottom}{\isachardoublequoteclose}\isanewline
173.478 +\isanewline
173.479 +\isacommand{theorem}\isamarkupfalse%
173.480 +\ trueI\ {\isacharbrackleft}intro{\isacharbrackright}{\isacharcolon}\ {\isasymtop}\isanewline
173.481 +%
173.482 +\isadelimproof
173.483 +\ \ %
173.484 +\endisadelimproof
173.485 +%
173.486 +\isatagproof
173.487 +\isacommand{unfolding}\isamarkupfalse%
173.488 +\ true{\isacharunderscore}def\ \isacommand{{\isachardot}{\isachardot}}\isamarkupfalse%
173.489 +%
173.490 +\endisatagproof
173.491 +{\isafoldproof}%
173.492 +%
173.493 +\isadelimproof
173.494 +%
173.495 +\endisadelimproof
173.496 +%
173.497 +\begin{isamarkuptext}%
173.498 +\medskip\noindent Now negation represents an implication towards
173.499 + absurdity:%
173.500 +\end{isamarkuptext}%
173.501 +\isamarkuptrue%
173.502 +\isacommand{definition}\isamarkupfalse%
173.503 +\isanewline
173.504 +\ \ not\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}o\ {\isasymRightarrow}\ o{\isachardoublequoteclose}\ \ {\isacharparenleft}{\isachardoublequoteopen}{\isasymnot}\ {\isacharunderscore}{\isachardoublequoteclose}\ {\isacharbrackleft}{\isadigit{4}}{\isadigit{0}}{\isacharbrackright}\ {\isadigit{4}}{\isadigit{0}}{\isacharparenright}\ \isakeyword{where}\isanewline
173.505 +\ \ {\isachardoublequoteopen}{\isasymnot}\ A\ {\isasymequiv}\ A\ {\isasymlongrightarrow}\ {\isasymbottom}{\isachardoublequoteclose}\isanewline
173.506 +\isanewline
173.507 +\isacommand{theorem}\isamarkupfalse%
173.508 +\ notI\ {\isacharbrackleft}intro{\isacharbrackright}{\isacharcolon}\isanewline
173.509 +\ \ \isakeyword{assumes}\ {\isachardoublequoteopen}A\ {\isasymLongrightarrow}\ {\isasymbottom}{\isachardoublequoteclose}\isanewline
173.510 +\ \ \isakeyword{shows}\ {\isachardoublequoteopen}{\isasymnot}\ A{\isachardoublequoteclose}\isanewline
173.511 +%
173.512 +\isadelimproof
173.513 +%
173.514 +\endisadelimproof
173.515 +%
173.516 +\isatagproof
173.517 +\isacommand{unfolding}\isamarkupfalse%
173.518 +\ not{\isacharunderscore}def\isanewline
173.519 +\isacommand{proof}\isamarkupfalse%
173.520 +\isanewline
173.521 +\ \ \isacommand{assume}\isamarkupfalse%
173.522 +\ A\isanewline
173.523 +\ \ \isacommand{then}\isamarkupfalse%
173.524 +\ \isacommand{show}\isamarkupfalse%
173.525 +\ {\isasymbottom}\ \isacommand{by}\isamarkupfalse%
173.526 +\ {\isacharparenleft}rule\ {\isacharbackquoteopen}A\ {\isasymLongrightarrow}\ {\isasymbottom}{\isacharbackquoteclose}{\isacharparenright}\isanewline
173.527 +\isacommand{qed}\isamarkupfalse%
173.528 +%
173.529 +\endisatagproof
173.530 +{\isafoldproof}%
173.531 +%
173.532 +\isadelimproof
173.533 +\isanewline
173.534 +%
173.535 +\endisadelimproof
173.536 +\isanewline
173.537 +\isacommand{theorem}\isamarkupfalse%
173.538 +\ notE\ {\isacharbrackleft}elim{\isacharbrackright}{\isacharcolon}\isanewline
173.539 +\ \ \isakeyword{assumes}\ {\isachardoublequoteopen}{\isasymnot}\ A{\isachardoublequoteclose}\ \isakeyword{and}\ A\isanewline
173.540 +\ \ \isakeyword{shows}\ B\isanewline
173.541 +%
173.542 +\isadelimproof
173.543 +%
173.544 +\endisadelimproof
173.545 +%
173.546 +\isatagproof
173.547 +\isacommand{proof}\isamarkupfalse%
173.548 +\ {\isacharminus}\isanewline
173.549 +\ \ \isacommand{from}\isamarkupfalse%
173.550 +\ {\isacharbackquoteopen}{\isasymnot}\ A{\isacharbackquoteclose}\ \isacommand{have}\isamarkupfalse%
173.551 +\ {\isachardoublequoteopen}A\ {\isasymlongrightarrow}\ {\isasymbottom}{\isachardoublequoteclose}\ \isacommand{unfolding}\isamarkupfalse%
173.552 +\ not{\isacharunderscore}def\ \isacommand{{\isachardot}}\isamarkupfalse%
173.553 +\isanewline
173.554 +\ \ \isacommand{from}\isamarkupfalse%
173.555 +\ {\isacharbackquoteopen}A\ {\isasymlongrightarrow}\ {\isasymbottom}{\isacharbackquoteclose}\ \isakeyword{and}\ {\isacharbackquoteopen}A{\isacharbackquoteclose}\ \isacommand{have}\isamarkupfalse%
173.556 +\ {\isasymbottom}\ \isacommand{{\isachardot}{\isachardot}}\isamarkupfalse%
173.557 +\isanewline
173.558 +\ \ \isacommand{then}\isamarkupfalse%
173.559 +\ \isacommand{show}\isamarkupfalse%
173.560 +\ B\ \isacommand{{\isachardot}{\isachardot}}\isamarkupfalse%
173.561 +\isanewline
173.562 +\isacommand{qed}\isamarkupfalse%
173.563 +%
173.564 +\endisatagproof
173.565 +{\isafoldproof}%
173.566 +%
173.567 +\isadelimproof
173.568 +%
173.569 +\endisadelimproof
173.570 +%
173.571 +\isamarkupsubsection{Classical logic%
173.572 +}
173.573 +\isamarkuptrue%
173.574 +%
173.575 +\begin{isamarkuptext}%
173.576 +Subsequently we state the principle of classical contradiction as a
173.577 + local assumption. Thus we refrain from forcing the object-logic
173.578 + into the classical perspective. Within that context, we may derive
173.579 + well-known consequences of the classical principle.%
173.580 +\end{isamarkuptext}%
173.581 +\isamarkuptrue%
173.582 +\isacommand{locale}\isamarkupfalse%
173.583 +\ classical\ {\isacharequal}\isanewline
173.584 +\ \ \isakeyword{assumes}\ classical{\isacharcolon}\ {\isachardoublequoteopen}{\isacharparenleft}{\isasymnot}\ C\ {\isasymLongrightarrow}\ C{\isacharparenright}\ {\isasymLongrightarrow}\ C{\isachardoublequoteclose}\isanewline
173.585 +\isakeyword{begin}\isanewline
173.586 +\isanewline
173.587 +\isacommand{theorem}\isamarkupfalse%
173.588 +\ double{\isacharunderscore}negation{\isacharcolon}\isanewline
173.589 +\ \ \isakeyword{assumes}\ {\isachardoublequoteopen}{\isasymnot}\ {\isasymnot}\ C{\isachardoublequoteclose}\isanewline
173.590 +\ \ \isakeyword{shows}\ C\isanewline
173.591 +%
173.592 +\isadelimproof
173.593 +%
173.594 +\endisadelimproof
173.595 +%
173.596 +\isatagproof
173.597 +\isacommand{proof}\isamarkupfalse%
173.598 +\ {\isacharparenleft}rule\ classical{\isacharparenright}\isanewline
173.599 +\ \ \isacommand{assume}\isamarkupfalse%
173.600 +\ {\isachardoublequoteopen}{\isasymnot}\ C{\isachardoublequoteclose}\isanewline
173.601 +\ \ \isacommand{with}\isamarkupfalse%
173.602 +\ {\isacharbackquoteopen}{\isasymnot}\ {\isasymnot}\ C{\isacharbackquoteclose}\ \isacommand{show}\isamarkupfalse%
173.603 +\ C\ \isacommand{{\isachardot}{\isachardot}}\isamarkupfalse%
173.604 +\isanewline
173.605 +\isacommand{qed}\isamarkupfalse%
173.606 +%
173.607 +\endisatagproof
173.608 +{\isafoldproof}%
173.609 +%
173.610 +\isadelimproof
173.611 +\isanewline
173.612 +%
173.613 +\endisadelimproof
173.614 +\isanewline
173.615 +\isacommand{theorem}\isamarkupfalse%
173.616 +\ tertium{\isacharunderscore}non{\isacharunderscore}datur{\isacharcolon}\ {\isachardoublequoteopen}C\ {\isasymor}\ {\isasymnot}\ C{\isachardoublequoteclose}\isanewline
173.617 +%
173.618 +\isadelimproof
173.619 +%
173.620 +\endisadelimproof
173.621 +%
173.622 +\isatagproof
173.623 +\isacommand{proof}\isamarkupfalse%
173.624 +\ {\isacharparenleft}rule\ double{\isacharunderscore}negation{\isacharparenright}\isanewline
173.625 +\ \ \isacommand{show}\isamarkupfalse%
173.626 +\ {\isachardoublequoteopen}{\isasymnot}\ {\isasymnot}\ {\isacharparenleft}C\ {\isasymor}\ {\isasymnot}\ C{\isacharparenright}{\isachardoublequoteclose}\isanewline
173.627 +\ \ \isacommand{proof}\isamarkupfalse%
173.628 +\isanewline
173.629 +\ \ \ \ \isacommand{assume}\isamarkupfalse%
173.630 +\ {\isachardoublequoteopen}{\isasymnot}\ {\isacharparenleft}C\ {\isasymor}\ {\isasymnot}\ C{\isacharparenright}{\isachardoublequoteclose}\isanewline
173.631 +\ \ \ \ \isacommand{have}\isamarkupfalse%
173.632 +\ {\isachardoublequoteopen}{\isasymnot}\ C{\isachardoublequoteclose}\isanewline
173.633 +\ \ \ \ \isacommand{proof}\isamarkupfalse%
173.634 +\isanewline
173.635 +\ \ \ \ \ \ \isacommand{assume}\isamarkupfalse%
173.636 +\ C\ \isacommand{then}\isamarkupfalse%
173.637 +\ \isacommand{have}\isamarkupfalse%
173.638 +\ {\isachardoublequoteopen}C\ {\isasymor}\ {\isasymnot}\ C{\isachardoublequoteclose}\ \isacommand{{\isachardot}{\isachardot}}\isamarkupfalse%
173.639 +\isanewline
173.640 +\ \ \ \ \ \ \isacommand{with}\isamarkupfalse%
173.641 +\ {\isacharbackquoteopen}{\isasymnot}\ {\isacharparenleft}C\ {\isasymor}\ {\isasymnot}\ C{\isacharparenright}{\isacharbackquoteclose}\ \isacommand{show}\isamarkupfalse%
173.642 +\ {\isasymbottom}\ \isacommand{{\isachardot}{\isachardot}}\isamarkupfalse%
173.643 +\isanewline
173.644 +\ \ \ \ \isacommand{qed}\isamarkupfalse%
173.645 +\isanewline
173.646 +\ \ \ \ \isacommand{then}\isamarkupfalse%
173.647 +\ \isacommand{have}\isamarkupfalse%
173.648 +\ {\isachardoublequoteopen}C\ {\isasymor}\ {\isasymnot}\ C{\isachardoublequoteclose}\ \isacommand{{\isachardot}{\isachardot}}\isamarkupfalse%
173.649 +\isanewline
173.650 +\ \ \ \ \isacommand{with}\isamarkupfalse%
173.651 +\ {\isacharbackquoteopen}{\isasymnot}\ {\isacharparenleft}C\ {\isasymor}\ {\isasymnot}\ C{\isacharparenright}{\isacharbackquoteclose}\ \isacommand{show}\isamarkupfalse%
173.652 +\ {\isasymbottom}\ \isacommand{{\isachardot}{\isachardot}}\isamarkupfalse%
173.653 +\isanewline
173.654 +\ \ \isacommand{qed}\isamarkupfalse%
173.655 +\isanewline
173.656 +\isacommand{qed}\isamarkupfalse%
173.657 +%
173.658 +\endisatagproof
173.659 +{\isafoldproof}%
173.660 +%
173.661 +\isadelimproof
173.662 +%
173.663 +\endisadelimproof
173.664 +%
173.665 +\begin{isamarkuptext}%
173.666 +\noindent These examples illustrate both classical reasoning and
173.667 + non-trivial propositional proofs in general. All three rules
173.668 + characterize classical logic independently, but the original rule is
173.669 + already the most convenient to use, because it leaves the conclusion
173.670 + unchanged. Note that \isa{{\isachardoublequote}{\isacharparenleft}{\isasymnot}\ C\ {\isasymLongrightarrow}\ C{\isacharparenright}\ {\isasymLongrightarrow}\ C{\isachardoublequote}} fits again into our
173.671 + format for eliminations, despite the additional twist that the
173.672 + context refers to the main conclusion. So we may write \isa{classical} as the Isar statement ``\isa{{\isachardoublequote}{\isasymOBTAINS}\ {\isasymnot}\ thesis{\isachardoublequote}}''.
173.673 + This also explains nicely how classical reasoning really works:
173.674 + whatever the main \isa{thesis} might be, we may always assume its
173.675 + negation!%
173.676 +\end{isamarkuptext}%
173.677 +\isamarkuptrue%
173.678 +\isacommand{end}\isamarkupfalse%
173.679 +%
173.680 +\isamarkupsubsection{Quantifiers \label{sec:framework-ex-quant}%
173.681 +}
173.682 +\isamarkuptrue%
173.683 +%
173.684 +\begin{isamarkuptext}%
173.685 +Representing quantifiers is easy, thanks to the higher-order nature
173.686 + of the underlying framework. According to the well-known technique
173.687 + introduced by Church \cite{church40}, quantifiers are operators on
173.688 + predicates, which are syntactically represented as \isa{{\isachardoublequote}{\isasymlambda}{\isachardoublequote}}-terms
173.689 + of type \isa{{\isachardoublequote}i\ {\isasymRightarrow}\ o{\isachardoublequote}}. Binder notation turns \isa{{\isachardoublequote}All\ {\isacharparenleft}{\isasymlambda}x{\isachardot}\ B\ x{\isacharparenright}{\isachardoublequote}} into \isa{{\isachardoublequote}{\isasymforall}x{\isachardot}\ B\ x{\isachardoublequote}} etc.%
173.690 +\end{isamarkuptext}%
173.691 +\isamarkuptrue%
173.692 +\isacommand{axiomatization}\isamarkupfalse%
173.693 +\isanewline
173.694 +\ \ All\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharparenleft}i\ {\isasymRightarrow}\ o{\isacharparenright}\ {\isasymRightarrow}\ o{\isachardoublequoteclose}\ \ {\isacharparenleft}\isakeyword{binder}\ {\isachardoublequoteopen}{\isasymforall}{\isachardoublequoteclose}\ {\isadigit{1}}{\isadigit{0}}{\isacharparenright}\ \isakeyword{where}\isanewline
173.695 +\ \ allI\ {\isacharbrackleft}intro{\isacharbrackright}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharparenleft}{\isasymAnd}x{\isachardot}\ B\ x{\isacharparenright}\ {\isasymLongrightarrow}\ {\isasymforall}x{\isachardot}\ B\ x{\isachardoublequoteclose}\ \isakeyword{and}\isanewline
173.696 +\ \ allD\ {\isacharbrackleft}dest{\isacharbrackright}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharparenleft}{\isasymforall}x{\isachardot}\ B\ x{\isacharparenright}\ {\isasymLongrightarrow}\ B\ a{\isachardoublequoteclose}\isanewline
173.697 +\isanewline
173.698 +\isacommand{axiomatization}\isamarkupfalse%
173.699 +\isanewline
173.700 +\ \ Ex\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharparenleft}i\ {\isasymRightarrow}\ o{\isacharparenright}\ {\isasymRightarrow}\ o{\isachardoublequoteclose}\ \ {\isacharparenleft}\isakeyword{binder}\ {\isachardoublequoteopen}{\isasymexists}{\isachardoublequoteclose}\ {\isadigit{1}}{\isadigit{0}}{\isacharparenright}\ \isakeyword{where}\isanewline
173.701 +\ \ exI\ {\isacharbrackleft}intro{\isacharbrackright}{\isacharcolon}\ {\isachardoublequoteopen}B\ a\ {\isasymLongrightarrow}\ {\isacharparenleft}{\isasymexists}x{\isachardot}\ B\ x{\isacharparenright}{\isachardoublequoteclose}\ \isakeyword{and}\isanewline
173.702 +\ \ exE\ {\isacharbrackleft}elim{\isacharbrackright}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharparenleft}{\isasymexists}x{\isachardot}\ B\ x{\isacharparenright}\ {\isasymLongrightarrow}\ {\isacharparenleft}{\isasymAnd}x{\isachardot}\ B\ x\ {\isasymLongrightarrow}\ C{\isacharparenright}\ {\isasymLongrightarrow}\ C{\isachardoublequoteclose}%
173.703 +\begin{isamarkuptext}%
173.704 +\noindent The statement of \isa{exE} corresponds to ``\isa{{\isachardoublequote}{\isasymASSUMES}\ {\isasymexists}x{\isachardot}\ B\ x\ {\isasymOBTAINS}\ x\ {\isasymWHERE}\ B\ x{\isachardoublequote}}'' in Isar. In the
173.705 + subsequent example we illustrate quantifier reasoning involving all
173.706 + four rules:%
173.707 +\end{isamarkuptext}%
173.708 +\isamarkuptrue%
173.709 +\isacommand{theorem}\isamarkupfalse%
173.710 +\isanewline
173.711 +\ \ \isakeyword{assumes}\ {\isachardoublequoteopen}{\isasymexists}x{\isachardot}\ {\isasymforall}y{\isachardot}\ R\ x\ y{\isachardoublequoteclose}\isanewline
173.712 +\ \ \isakeyword{shows}\ {\isachardoublequoteopen}{\isasymforall}y{\isachardot}\ {\isasymexists}x{\isachardot}\ R\ x\ y{\isachardoublequoteclose}\isanewline
173.713 +%
173.714 +\isadelimproof
173.715 +%
173.716 +\endisadelimproof
173.717 +%
173.718 +\isatagproof
173.719 +\isacommand{proof}\isamarkupfalse%
173.720 +\ \ \ \ %
173.721 +\isamarkupcmt{\isa{{\isachardoublequote}{\isasymforall}{\isachardoublequote}} introduction%
173.722 +}
173.723 +\isanewline
173.724 +\ \ \isacommand{obtain}\isamarkupfalse%
173.725 +\ x\ \isakeyword{where}\ {\isachardoublequoteopen}{\isasymforall}y{\isachardot}\ R\ x\ y{\isachardoublequoteclose}\ \isacommand{using}\isamarkupfalse%
173.726 +\ {\isacharbackquoteopen}{\isasymexists}x{\isachardot}\ {\isasymforall}y{\isachardot}\ R\ x\ y{\isacharbackquoteclose}\ \isacommand{{\isachardot}{\isachardot}}\isamarkupfalse%
173.727 +\ \ \ \ %
173.728 +\isamarkupcmt{\isa{{\isachardoublequote}{\isasymexists}{\isachardoublequote}} elimination%
173.729 +}
173.730 +\isanewline
173.731 +\ \ \isacommand{fix}\isamarkupfalse%
173.732 +\ y\ \isacommand{have}\isamarkupfalse%
173.733 +\ {\isachardoublequoteopen}R\ x\ y{\isachardoublequoteclose}\ \isacommand{using}\isamarkupfalse%
173.734 +\ {\isacharbackquoteopen}{\isasymforall}y{\isachardot}\ R\ x\ y{\isacharbackquoteclose}\ \isacommand{{\isachardot}{\isachardot}}\isamarkupfalse%
173.735 +\ \ \ \ %
173.736 +\isamarkupcmt{\isa{{\isachardoublequote}{\isasymforall}{\isachardoublequote}} destruction%
173.737 +}
173.738 +\isanewline
173.739 +\ \ \isacommand{then}\isamarkupfalse%
173.740 +\ \isacommand{show}\isamarkupfalse%
173.741 +\ {\isachardoublequoteopen}{\isasymexists}x{\isachardot}\ R\ x\ y{\isachardoublequoteclose}\ \isacommand{{\isachardot}{\isachardot}}\isamarkupfalse%
173.742 +\ \ \ \ %
173.743 +\isamarkupcmt{\isa{{\isachardoublequote}{\isasymexists}{\isachardoublequote}} introduction%
173.744 +}
173.745 +\isanewline
173.746 +\isacommand{qed}\isamarkupfalse%
173.747 +%
173.748 +\endisatagproof
173.749 +{\isafoldproof}%
173.750 +%
173.751 +\isadelimproof
173.752 +%
173.753 +\endisadelimproof
173.754 +%
173.755 +\isamarkupsubsection{Canonical reasoning patterns%
173.756 +}
173.757 +\isamarkuptrue%
173.758 +%
173.759 +\begin{isamarkuptext}%
173.760 +The main rules of first-order predicate logic from
173.761 + \secref{sec:framework-ex-prop} and \secref{sec:framework-ex-quant}
173.762 + can now be summarized as follows, using the native Isar statement
173.763 + format of \secref{sec:framework-stmt}.
173.764 +
173.765 + \medskip
173.766 + \begin{tabular}{l}
173.767 + \isa{{\isachardoublequote}impI{\isacharcolon}\ {\isasymASSUMES}\ A\ {\isasymLongrightarrow}\ B\ {\isasymSHOWS}\ A\ {\isasymlongrightarrow}\ B{\isachardoublequote}} \\
173.768 + \isa{{\isachardoublequote}impD{\isacharcolon}\ {\isasymASSUMES}\ A\ {\isasymlongrightarrow}\ B\ {\isasymAND}\ A\ {\isasymSHOWS}\ B{\isachardoublequote}} \\[1ex]
173.769 +
173.770 + \isa{{\isachardoublequote}disjI\isactrlisub {\isadigit{1}}{\isacharcolon}\ {\isasymASSUMES}\ A\ {\isasymSHOWS}\ A\ {\isasymor}\ B{\isachardoublequote}} \\
173.771 + \isa{{\isachardoublequote}disjI\isactrlisub {\isadigit{2}}{\isacharcolon}\ {\isasymASSUMES}\ B\ {\isasymSHOWS}\ A\ {\isasymor}\ B{\isachardoublequote}} \\
173.772 + \isa{{\isachardoublequote}disjE{\isacharcolon}\ {\isasymASSUMES}\ A\ {\isasymor}\ B\ {\isasymOBTAINS}\ A\ {\isasymBBAR}\ B{\isachardoublequote}} \\[1ex]
173.773 +
173.774 + \isa{{\isachardoublequote}conjI{\isacharcolon}\ {\isasymASSUMES}\ A\ {\isasymAND}\ B\ {\isasymSHOWS}\ A\ {\isasymand}\ B{\isachardoublequote}} \\
173.775 + \isa{{\isachardoublequote}conjE{\isacharcolon}\ {\isasymASSUMES}\ A\ {\isasymand}\ B\ {\isasymOBTAINS}\ A\ {\isasymAND}\ B{\isachardoublequote}} \\[1ex]
173.776 +
173.777 + \isa{{\isachardoublequote}falseE{\isacharcolon}\ {\isasymASSUMES}\ {\isasymbottom}\ {\isasymSHOWS}\ A{\isachardoublequote}} \\
173.778 + \isa{{\isachardoublequote}trueI{\isacharcolon}\ {\isasymSHOWS}\ {\isasymtop}{\isachardoublequote}} \\[1ex]
173.779 +
173.780 + \isa{{\isachardoublequote}notI{\isacharcolon}\ {\isasymASSUMES}\ A\ {\isasymLongrightarrow}\ {\isasymbottom}\ {\isasymSHOWS}\ {\isasymnot}\ A{\isachardoublequote}} \\
173.781 + \isa{{\isachardoublequote}notE{\isacharcolon}\ {\isasymASSUMES}\ {\isasymnot}\ A\ {\isasymAND}\ A\ {\isasymSHOWS}\ B{\isachardoublequote}} \\[1ex]
173.782 +
173.783 + \isa{{\isachardoublequote}allI{\isacharcolon}\ {\isasymASSUMES}\ {\isasymAnd}x{\isachardot}\ B\ x\ {\isasymSHOWS}\ {\isasymforall}x{\isachardot}\ B\ x{\isachardoublequote}} \\
173.784 + \isa{{\isachardoublequote}allE{\isacharcolon}\ {\isasymASSUMES}\ {\isasymforall}x{\isachardot}\ B\ x\ {\isasymSHOWS}\ B\ a{\isachardoublequote}} \\[1ex]
173.785 +
173.786 + \isa{{\isachardoublequote}exI{\isacharcolon}\ {\isasymASSUMES}\ B\ a\ {\isasymSHOWS}\ {\isasymexists}x{\isachardot}\ B\ x{\isachardoublequote}} \\
173.787 + \isa{{\isachardoublequote}exE{\isacharcolon}\ {\isasymASSUMES}\ {\isasymexists}x{\isachardot}\ B\ x\ {\isasymOBTAINS}\ a\ {\isasymWHERE}\ B\ a{\isachardoublequote}}
173.788 + \end{tabular}
173.789 + \medskip
173.790 +
173.791 + \noindent This essentially provides a declarative reading of Pure
173.792 + rules as Isar reasoning patterns: the rule statements tells how a
173.793 + canonical proof outline shall look like. Since the above rules have
173.794 + already been declared as \hyperlink{attribute.Pure.intro}{\mbox{\isa{intro}}}, \hyperlink{attribute.Pure.elim}{\mbox{\isa{elim}}}, \hyperlink{attribute.Pure.dest}{\mbox{\isa{dest}}} --- each according to its
173.795 + particular shape --- we can immediately write Isar proof texts as
173.796 + follows:%
173.797 +\end{isamarkuptext}%
173.798 +\isamarkuptrue%
173.799 +%
173.800 +\isadelimproof
173.801 +%
173.802 +\endisadelimproof
173.803 +%
173.804 +\isatagproof
173.805 +%
173.806 +\begin{minipage}[t]{0.4\textwidth}
173.807 +\isanewline
173.808 +\ \ \isacommand{have}\isamarkupfalse%
173.809 +\ {\isachardoublequoteopen}A\ {\isasymlongrightarrow}\ B{\isachardoublequoteclose}\isanewline
173.810 +\ \ \isacommand{proof}\isamarkupfalse%
173.811 +\isanewline
173.812 +\ \ \ \ \isacommand{assume}\isamarkupfalse%
173.813 +\ A\isanewline
173.814 +\ \ \ \ \isacommand{show}\isamarkupfalse%
173.815 +\ B%
173.816 +\endisatagproof
173.817 +{\isafoldproof}%
173.818 +%
173.819 +\isadelimproof
173.820 +%
173.821 +\endisadelimproof
173.822 +%
173.823 +\isadelimnoproof
173.824 +\ %
173.825 +\endisadelimnoproof
173.826 +%
173.827 +\isatagnoproof
173.828 +\isacommand{sorry}\isamarkupfalse%
173.829 +%
173.830 +\endisatagnoproof
173.831 +{\isafoldnoproof}%
173.832 +%
173.833 +\isadelimnoproof
173.834 +\isanewline
173.835 +%
173.836 +\endisadelimnoproof
173.837 +%
173.838 +\isadelimproof
173.839 +\ \ %
173.840 +\endisadelimproof
173.841 +%
173.842 +\isatagproof
173.843 +\isacommand{qed}\isamarkupfalse%
173.844 +%
173.845 +\end{minipage}\qquad\begin{minipage}[t]{0.4\textwidth}
173.846 +\isanewline
173.847 +\ \ \isacommand{have}\isamarkupfalse%
173.848 +\ {\isachardoublequoteopen}A\ {\isasymlongrightarrow}\ B{\isachardoublequoteclose}\ \isakeyword{and}\ A%
173.849 +\endisatagproof
173.850 +{\isafoldproof}%
173.851 +%
173.852 +\isadelimproof
173.853 +%
173.854 +\endisadelimproof
173.855 +%
173.856 +\isadelimnoproof
173.857 +\ %
173.858 +\endisadelimnoproof
173.859 +%
173.860 +\isatagnoproof
173.861 +\isacommand{sorry}\isamarkupfalse%
173.862 +%
173.863 +\endisatagnoproof
173.864 +{\isafoldnoproof}%
173.865 +%
173.866 +\isadelimnoproof
173.867 +\isanewline
173.868 +%
173.869 +\endisadelimnoproof
173.870 +%
173.871 +\isadelimproof
173.872 +\ \ %
173.873 +\endisadelimproof
173.874 +%
173.875 +\isatagproof
173.876 +\isacommand{then}\isamarkupfalse%
173.877 +\ \isacommand{have}\isamarkupfalse%
173.878 +\ B\ \isacommand{{\isachardot}{\isachardot}}\isamarkupfalse%
173.879 +%
173.880 +\end{minipage}\\[3ex]\begin{minipage}[t]{0.4\textwidth}
173.881 +\isanewline
173.882 +\ \ \isacommand{have}\isamarkupfalse%
173.883 +\ A%
173.884 +\endisatagproof
173.885 +{\isafoldproof}%
173.886 +%
173.887 +\isadelimproof
173.888 +%
173.889 +\endisadelimproof
173.890 +%
173.891 +\isadelimnoproof
173.892 +\ %
173.893 +\endisadelimnoproof
173.894 +%
173.895 +\isatagnoproof
173.896 +\isacommand{sorry}\isamarkupfalse%
173.897 +%
173.898 +\endisatagnoproof
173.899 +{\isafoldnoproof}%
173.900 +%
173.901 +\isadelimnoproof
173.902 +\isanewline
173.903 +%
173.904 +\endisadelimnoproof
173.905 +%
173.906 +\isadelimproof
173.907 +\ \ %
173.908 +\endisadelimproof
173.909 +%
173.910 +\isatagproof
173.911 +\isacommand{then}\isamarkupfalse%
173.912 +\ \isacommand{have}\isamarkupfalse%
173.913 +\ {\isachardoublequoteopen}A\ {\isasymor}\ B{\isachardoublequoteclose}\ \isacommand{{\isachardot}{\isachardot}}\isamarkupfalse%
173.914 +\isanewline
173.915 +\isanewline
173.916 +\ \ \isacommand{have}\isamarkupfalse%
173.917 +\ B%
173.918 +\endisatagproof
173.919 +{\isafoldproof}%
173.920 +%
173.921 +\isadelimproof
173.922 +%
173.923 +\endisadelimproof
173.924 +%
173.925 +\isadelimnoproof
173.926 +\ %
173.927 +\endisadelimnoproof
173.928 +%
173.929 +\isatagnoproof
173.930 +\isacommand{sorry}\isamarkupfalse%
173.931 +%
173.932 +\endisatagnoproof
173.933 +{\isafoldnoproof}%
173.934 +%
173.935 +\isadelimnoproof
173.936 +\isanewline
173.937 +%
173.938 +\endisadelimnoproof
173.939 +%
173.940 +\isadelimproof
173.941 +\ \ %
173.942 +\endisadelimproof
173.943 +%
173.944 +\isatagproof
173.945 +\isacommand{then}\isamarkupfalse%
173.946 +\ \isacommand{have}\isamarkupfalse%
173.947 +\ {\isachardoublequoteopen}A\ {\isasymor}\ B{\isachardoublequoteclose}\ \isacommand{{\isachardot}{\isachardot}}\isamarkupfalse%
173.948 +%
173.949 +\end{minipage}\qquad\begin{minipage}[t]{0.4\textwidth}
173.950 +\isanewline
173.951 +\ \ \isacommand{have}\isamarkupfalse%
173.952 +\ {\isachardoublequoteopen}A\ {\isasymor}\ B{\isachardoublequoteclose}%
173.953 +\endisatagproof
173.954 +{\isafoldproof}%
173.955 +%
173.956 +\isadelimproof
173.957 +%
173.958 +\endisadelimproof
173.959 +%
173.960 +\isadelimnoproof
173.961 +\ %
173.962 +\endisadelimnoproof
173.963 +%
173.964 +\isatagnoproof
173.965 +\isacommand{sorry}\isamarkupfalse%
173.966 +%
173.967 +\endisatagnoproof
173.968 +{\isafoldnoproof}%
173.969 +%
173.970 +\isadelimnoproof
173.971 +\isanewline
173.972 +%
173.973 +\endisadelimnoproof
173.974 +%
173.975 +\isadelimproof
173.976 +\ \ %
173.977 +\endisadelimproof
173.978 +%
173.979 +\isatagproof
173.980 +\isacommand{then}\isamarkupfalse%
173.981 +\ \isacommand{have}\isamarkupfalse%
173.982 +\ C\isanewline
173.983 +\ \ \isacommand{proof}\isamarkupfalse%
173.984 +\isanewline
173.985 +\ \ \ \ \isacommand{assume}\isamarkupfalse%
173.986 +\ A\isanewline
173.987 +\ \ \ \ \isacommand{then}\isamarkupfalse%
173.988 +\ \isacommand{show}\isamarkupfalse%
173.989 +\ C%
173.990 +\endisatagproof
173.991 +{\isafoldproof}%
173.992 +%
173.993 +\isadelimproof
173.994 +%
173.995 +\endisadelimproof
173.996 +%
173.997 +\isadelimnoproof
173.998 +\ %
173.999 +\endisadelimnoproof
173.1000 +%
173.1001 +\isatagnoproof
173.1002 +\isacommand{sorry}\isamarkupfalse%
173.1003 +%
173.1004 +\endisatagnoproof
173.1005 +{\isafoldnoproof}%
173.1006 +%
173.1007 +\isadelimnoproof
173.1008 +\isanewline
173.1009 +%
173.1010 +\endisadelimnoproof
173.1011 +%
173.1012 +\isadelimproof
173.1013 +\ \ %
173.1014 +\endisadelimproof
173.1015 +%
173.1016 +\isatagproof
173.1017 +\isacommand{next}\isamarkupfalse%
173.1018 +\isanewline
173.1019 +\ \ \ \ \isacommand{assume}\isamarkupfalse%
173.1020 +\ B\isanewline
173.1021 +\ \ \ \ \isacommand{then}\isamarkupfalse%
173.1022 +\ \isacommand{show}\isamarkupfalse%
173.1023 +\ C%
173.1024 +\endisatagproof
173.1025 +{\isafoldproof}%
173.1026 +%
173.1027 +\isadelimproof
173.1028 +%
173.1029 +\endisadelimproof
173.1030 +%
173.1031 +\isadelimnoproof
173.1032 +\ %
173.1033 +\endisadelimnoproof
173.1034 +%
173.1035 +\isatagnoproof
173.1036 +\isacommand{sorry}\isamarkupfalse%
173.1037 +%
173.1038 +\endisatagnoproof
173.1039 +{\isafoldnoproof}%
173.1040 +%
173.1041 +\isadelimnoproof
173.1042 +\isanewline
173.1043 +%
173.1044 +\endisadelimnoproof
173.1045 +%
173.1046 +\isadelimproof
173.1047 +\ \ %
173.1048 +\endisadelimproof
173.1049 +%
173.1050 +\isatagproof
173.1051 +\isacommand{qed}\isamarkupfalse%
173.1052 +%
173.1053 +\end{minipage}\\[3ex]\begin{minipage}[t]{0.4\textwidth}
173.1054 +\isanewline
173.1055 +\ \ \isacommand{have}\isamarkupfalse%
173.1056 +\ A\ \isakeyword{and}\ B%
173.1057 +\endisatagproof
173.1058 +{\isafoldproof}%
173.1059 +%
173.1060 +\isadelimproof
173.1061 +%
173.1062 +\endisadelimproof
173.1063 +%
173.1064 +\isadelimnoproof
173.1065 +\ %
173.1066 +\endisadelimnoproof
173.1067 +%
173.1068 +\isatagnoproof
173.1069 +\isacommand{sorry}\isamarkupfalse%
173.1070 +%
173.1071 +\endisatagnoproof
173.1072 +{\isafoldnoproof}%
173.1073 +%
173.1074 +\isadelimnoproof
173.1075 +\isanewline
173.1076 +%
173.1077 +\endisadelimnoproof
173.1078 +%
173.1079 +\isadelimproof
173.1080 +\ \ %
173.1081 +\endisadelimproof
173.1082 +%
173.1083 +\isatagproof
173.1084 +\isacommand{then}\isamarkupfalse%
173.1085 +\ \isacommand{have}\isamarkupfalse%
173.1086 +\ {\isachardoublequoteopen}A\ {\isasymand}\ B{\isachardoublequoteclose}\ \isacommand{{\isachardot}{\isachardot}}\isamarkupfalse%
173.1087 +%
173.1088 +\end{minipage}\qquad\begin{minipage}[t]{0.4\textwidth}
173.1089 +\isanewline
173.1090 +\ \ \isacommand{have}\isamarkupfalse%
173.1091 +\ {\isachardoublequoteopen}A\ {\isasymand}\ B{\isachardoublequoteclose}%
173.1092 +\endisatagproof
173.1093 +{\isafoldproof}%
173.1094 +%
173.1095 +\isadelimproof
173.1096 +%
173.1097 +\endisadelimproof
173.1098 +%
173.1099 +\isadelimnoproof
173.1100 +\ %
173.1101 +\endisadelimnoproof
173.1102 +%
173.1103 +\isatagnoproof
173.1104 +\isacommand{sorry}\isamarkupfalse%
173.1105 +%
173.1106 +\endisatagnoproof
173.1107 +{\isafoldnoproof}%
173.1108 +%
173.1109 +\isadelimnoproof
173.1110 +\isanewline
173.1111 +%
173.1112 +\endisadelimnoproof
173.1113 +%
173.1114 +\isadelimproof
173.1115 +\ \ %
173.1116 +\endisadelimproof
173.1117 +%
173.1118 +\isatagproof
173.1119 +\isacommand{then}\isamarkupfalse%
173.1120 +\ \isacommand{obtain}\isamarkupfalse%
173.1121 +\ A\ \isakeyword{and}\ B\ \isacommand{{\isachardot}{\isachardot}}\isamarkupfalse%
173.1122 +%
173.1123 +\end{minipage}\\[3ex]\begin{minipage}[t]{0.4\textwidth}
173.1124 +\isanewline
173.1125 +\ \ \isacommand{have}\isamarkupfalse%
173.1126 +\ {\isachardoublequoteopen}{\isasymbottom}{\isachardoublequoteclose}%
173.1127 +\endisatagproof
173.1128 +{\isafoldproof}%
173.1129 +%
173.1130 +\isadelimproof
173.1131 +%
173.1132 +\endisadelimproof
173.1133 +%
173.1134 +\isadelimnoproof
173.1135 +\ %
173.1136 +\endisadelimnoproof
173.1137 +%
173.1138 +\isatagnoproof
173.1139 +\isacommand{sorry}\isamarkupfalse%
173.1140 +%
173.1141 +\endisatagnoproof
173.1142 +{\isafoldnoproof}%
173.1143 +%
173.1144 +\isadelimnoproof
173.1145 +\isanewline
173.1146 +%
173.1147 +\endisadelimnoproof
173.1148 +%
173.1149 +\isadelimproof
173.1150 +\ \ %
173.1151 +\endisadelimproof
173.1152 +%
173.1153 +\isatagproof
173.1154 +\isacommand{then}\isamarkupfalse%
173.1155 +\ \isacommand{have}\isamarkupfalse%
173.1156 +\ A\ \isacommand{{\isachardot}{\isachardot}}\isamarkupfalse%
173.1157 +%
173.1158 +\end{minipage}\qquad\begin{minipage}[t]{0.4\textwidth}
173.1159 +\isanewline
173.1160 +\ \ \isacommand{have}\isamarkupfalse%
173.1161 +\ {\isachardoublequoteopen}{\isasymtop}{\isachardoublequoteclose}\ \isacommand{{\isachardot}{\isachardot}}\isamarkupfalse%
173.1162 +%
173.1163 +\end{minipage}\\[3ex]\begin{minipage}[t]{0.4\textwidth}
173.1164 +\isanewline
173.1165 +\ \ \isacommand{have}\isamarkupfalse%
173.1166 +\ {\isachardoublequoteopen}{\isasymnot}\ A{\isachardoublequoteclose}\isanewline
173.1167 +\ \ \isacommand{proof}\isamarkupfalse%
173.1168 +\isanewline
173.1169 +\ \ \ \ \isacommand{assume}\isamarkupfalse%
173.1170 +\ A\isanewline
173.1171 +\ \ \ \ \isacommand{then}\isamarkupfalse%
173.1172 +\ \isacommand{show}\isamarkupfalse%
173.1173 +\ {\isachardoublequoteopen}{\isasymbottom}{\isachardoublequoteclose}%
173.1174 +\endisatagproof
173.1175 +{\isafoldproof}%
173.1176 +%
173.1177 +\isadelimproof
173.1178 +%
173.1179 +\endisadelimproof
173.1180 +%
173.1181 +\isadelimnoproof
173.1182 +\ %
173.1183 +\endisadelimnoproof
173.1184 +%
173.1185 +\isatagnoproof
173.1186 +\isacommand{sorry}\isamarkupfalse%
173.1187 +%
173.1188 +\endisatagnoproof
173.1189 +{\isafoldnoproof}%
173.1190 +%
173.1191 +\isadelimnoproof
173.1192 +\isanewline
173.1193 +%
173.1194 +\endisadelimnoproof
173.1195 +%
173.1196 +\isadelimproof
173.1197 +\ \ %
173.1198 +\endisadelimproof
173.1199 +%
173.1200 +\isatagproof
173.1201 +\isacommand{qed}\isamarkupfalse%
173.1202 +%
173.1203 +\end{minipage}\qquad\begin{minipage}[t]{0.4\textwidth}
173.1204 +\isanewline
173.1205 +\ \ \isacommand{have}\isamarkupfalse%
173.1206 +\ {\isachardoublequoteopen}{\isasymnot}\ A{\isachardoublequoteclose}\ \isakeyword{and}\ A%
173.1207 +\endisatagproof
173.1208 +{\isafoldproof}%
173.1209 +%
173.1210 +\isadelimproof
173.1211 +%
173.1212 +\endisadelimproof
173.1213 +%
173.1214 +\isadelimnoproof
173.1215 +\ %
173.1216 +\endisadelimnoproof
173.1217 +%
173.1218 +\isatagnoproof
173.1219 +\isacommand{sorry}\isamarkupfalse%
173.1220 +%
173.1221 +\endisatagnoproof
173.1222 +{\isafoldnoproof}%
173.1223 +%
173.1224 +\isadelimnoproof
173.1225 +\isanewline
173.1226 +%
173.1227 +\endisadelimnoproof
173.1228 +%
173.1229 +\isadelimproof
173.1230 +\ \ %
173.1231 +\endisadelimproof
173.1232 +%
173.1233 +\isatagproof
173.1234 +\isacommand{then}\isamarkupfalse%
173.1235 +\ \isacommand{have}\isamarkupfalse%
173.1236 +\ B\ \isacommand{{\isachardot}{\isachardot}}\isamarkupfalse%
173.1237 +%
173.1238 +\end{minipage}\\[3ex]\begin{minipage}[t]{0.4\textwidth}
173.1239 +\isanewline
173.1240 +\ \ \isacommand{have}\isamarkupfalse%
173.1241 +\ {\isachardoublequoteopen}{\isasymforall}x{\isachardot}\ B\ x{\isachardoublequoteclose}\isanewline
173.1242 +\ \ \isacommand{proof}\isamarkupfalse%
173.1243 +\isanewline
173.1244 +\ \ \ \ \isacommand{fix}\isamarkupfalse%
173.1245 +\ x\isanewline
173.1246 +\ \ \ \ \isacommand{show}\isamarkupfalse%
173.1247 +\ {\isachardoublequoteopen}B\ x{\isachardoublequoteclose}%
173.1248 +\endisatagproof
173.1249 +{\isafoldproof}%
173.1250 +%
173.1251 +\isadelimproof
173.1252 +%
173.1253 +\endisadelimproof
173.1254 +%
173.1255 +\isadelimnoproof
173.1256 +\ %
173.1257 +\endisadelimnoproof
173.1258 +%
173.1259 +\isatagnoproof
173.1260 +\isacommand{sorry}\isamarkupfalse%
173.1261 +%
173.1262 +\endisatagnoproof
173.1263 +{\isafoldnoproof}%
173.1264 +%
173.1265 +\isadelimnoproof
173.1266 +\isanewline
173.1267 +%
173.1268 +\endisadelimnoproof
173.1269 +%
173.1270 +\isadelimproof
173.1271 +\ \ %
173.1272 +\endisadelimproof
173.1273 +%
173.1274 +\isatagproof
173.1275 +\isacommand{qed}\isamarkupfalse%
173.1276 +%
173.1277 +\end{minipage}\qquad\begin{minipage}[t]{0.4\textwidth}
173.1278 +\isanewline
173.1279 +\ \ \isacommand{have}\isamarkupfalse%
173.1280 +\ {\isachardoublequoteopen}{\isasymforall}x{\isachardot}\ B\ x{\isachardoublequoteclose}%
173.1281 +\endisatagproof
173.1282 +{\isafoldproof}%
173.1283 +%
173.1284 +\isadelimproof
173.1285 +%
173.1286 +\endisadelimproof
173.1287 +%
173.1288 +\isadelimnoproof
173.1289 +\ %
173.1290 +\endisadelimnoproof
173.1291 +%
173.1292 +\isatagnoproof
173.1293 +\isacommand{sorry}\isamarkupfalse%
173.1294 +%
173.1295 +\endisatagnoproof
173.1296 +{\isafoldnoproof}%
173.1297 +%
173.1298 +\isadelimnoproof
173.1299 +\isanewline
173.1300 +%
173.1301 +\endisadelimnoproof
173.1302 +%
173.1303 +\isadelimproof
173.1304 +\ \ %
173.1305 +\endisadelimproof
173.1306 +%
173.1307 +\isatagproof
173.1308 +\isacommand{then}\isamarkupfalse%
173.1309 +\ \isacommand{have}\isamarkupfalse%
173.1310 +\ {\isachardoublequoteopen}B\ a{\isachardoublequoteclose}\ \isacommand{{\isachardot}{\isachardot}}\isamarkupfalse%
173.1311 +%
173.1312 +\end{minipage}\\[3ex]\begin{minipage}[t]{0.4\textwidth}
173.1313 +\isanewline
173.1314 +\ \ \isacommand{have}\isamarkupfalse%
173.1315 +\ {\isachardoublequoteopen}{\isasymexists}x{\isachardot}\ B\ x{\isachardoublequoteclose}\isanewline
173.1316 +\ \ \isacommand{proof}\isamarkupfalse%
173.1317 +\isanewline
173.1318 +\ \ \ \ \isacommand{show}\isamarkupfalse%
173.1319 +\ {\isachardoublequoteopen}B\ a{\isachardoublequoteclose}%
173.1320 +\endisatagproof
173.1321 +{\isafoldproof}%
173.1322 +%
173.1323 +\isadelimproof
173.1324 +%
173.1325 +\endisadelimproof
173.1326 +%
173.1327 +\isadelimnoproof
173.1328 +\ %
173.1329 +\endisadelimnoproof
173.1330 +%
173.1331 +\isatagnoproof
173.1332 +\isacommand{sorry}\isamarkupfalse%
173.1333 +%
173.1334 +\endisatagnoproof
173.1335 +{\isafoldnoproof}%
173.1336 +%
173.1337 +\isadelimnoproof
173.1338 +\isanewline
173.1339 +%
173.1340 +\endisadelimnoproof
173.1341 +%
173.1342 +\isadelimproof
173.1343 +\ \ %
173.1344 +\endisadelimproof
173.1345 +%
173.1346 +\isatagproof
173.1347 +\isacommand{qed}\isamarkupfalse%
173.1348 +%
173.1349 +\end{minipage}\qquad\begin{minipage}[t]{0.4\textwidth}
173.1350 +\isanewline
173.1351 +\ \ \isacommand{have}\isamarkupfalse%
173.1352 +\ {\isachardoublequoteopen}{\isasymexists}x{\isachardot}\ B\ x{\isachardoublequoteclose}%
173.1353 +\endisatagproof
173.1354 +{\isafoldproof}%
173.1355 +%
173.1356 +\isadelimproof
173.1357 +%
173.1358 +\endisadelimproof
173.1359 +%
173.1360 +\isadelimnoproof
173.1361 +\ %
173.1362 +\endisadelimnoproof
173.1363 +%
173.1364 +\isatagnoproof
173.1365 +\isacommand{sorry}\isamarkupfalse%
173.1366 +%
173.1367 +\endisatagnoproof
173.1368 +{\isafoldnoproof}%
173.1369 +%
173.1370 +\isadelimnoproof
173.1371 +\isanewline
173.1372 +%
173.1373 +\endisadelimnoproof
173.1374 +%
173.1375 +\isadelimproof
173.1376 +\ \ %
173.1377 +\endisadelimproof
173.1378 +%
173.1379 +\isatagproof
173.1380 +\isacommand{then}\isamarkupfalse%
173.1381 +\ \isacommand{obtain}\isamarkupfalse%
173.1382 +\ a\ \isakeyword{where}\ {\isachardoublequoteopen}B\ a{\isachardoublequoteclose}\ \isacommand{{\isachardot}{\isachardot}}\isamarkupfalse%
173.1383 +%
173.1384 +\end{minipage}
173.1385 +%
173.1386 +\endisatagproof
173.1387 +{\isafoldproof}%
173.1388 +%
173.1389 +\isadelimproof
173.1390 +%
173.1391 +\endisadelimproof
173.1392 +%
173.1393 +\begin{isamarkuptext}%
173.1394 +\bigskip\noindent Of course, these proofs are merely examples. As
173.1395 + sketched in \secref{sec:framework-subproof}, there is a fair amount
173.1396 + of flexibility in expressing Pure deductions in Isar. Here the user
173.1397 + is asked to express himself adequately, aiming at proof texts of
173.1398 + literary quality.%
173.1399 +\end{isamarkuptext}%
173.1400 +\isamarkuptrue%
173.1401 +%
173.1402 +\isadelimvisible
173.1403 +%
173.1404 +\endisadelimvisible
173.1405 +%
173.1406 +\isatagvisible
173.1407 +\isacommand{end}\isamarkupfalse%
173.1408 +%
173.1409 +\endisatagvisible
173.1410 +{\isafoldvisible}%
173.1411 +%
173.1412 +\isadelimvisible
173.1413 +%
173.1414 +\endisadelimvisible
173.1415 +\isanewline
173.1416 +\end{isabellebody}%
173.1417 +%%% Local Variables:
173.1418 +%%% mode: latex
173.1419 +%%% TeX-master: "root"
173.1420 +%%% End:
174.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
174.2 +++ b/doc-src/IsarRef/Thy/document/Framework.tex Wed Mar 04 11:05:29 2009 +0100
174.3 @@ -0,0 +1,1518 @@
174.4 +%
174.5 +\begin{isabellebody}%
174.6 +\def\isabellecontext{Framework}%
174.7 +%
174.8 +\isadelimtheory
174.9 +%
174.10 +\endisadelimtheory
174.11 +%
174.12 +\isatagtheory
174.13 +\isacommand{theory}\isamarkupfalse%
174.14 +\ Framework\isanewline
174.15 +\isakeyword{imports}\ Main\isanewline
174.16 +\isakeyword{begin}%
174.17 +\endisatagtheory
174.18 +{\isafoldtheory}%
174.19 +%
174.20 +\isadelimtheory
174.21 +%
174.22 +\endisadelimtheory
174.23 +%
174.24 +\isamarkupchapter{The Isabelle/Isar Framework \label{ch:isar-framework}%
174.25 +}
174.26 +\isamarkuptrue%
174.27 +%
174.28 +\begin{isamarkuptext}%
174.29 +Isabelle/Isar
174.30 + \cite{Wenzel:1999:TPHOL,Wenzel-PhD,Nipkow-TYPES02,Wenzel-Paulson:2006,Wenzel:2006:Festschrift}
174.31 + is intended as a generic framework for developing formal
174.32 + mathematical documents with full proof checking. Definitions and
174.33 + proofs are organized as theories. An assembly of theory sources may
174.34 + be presented as a printed document; see also
174.35 + \chref{ch:document-prep}.
174.36 +
174.37 + The main objective of Isar is the design of a human-readable
174.38 + structured proof language, which is called the ``primary proof
174.39 + format'' in Isar terminology. Such a primary proof language is
174.40 + somewhere in the middle between the extremes of primitive proof
174.41 + objects and actual natural language. In this respect, Isar is a bit
174.42 + more formalistic than Mizar
174.43 + \cite{Trybulec:1993:MizarFeatures,Rudnicki:1992:MizarOverview,Wiedijk:1999:Mizar},
174.44 + using logical symbols for certain reasoning schemes where Mizar
174.45 + would prefer English words; see \cite{Wenzel-Wiedijk:2002} for
174.46 + further comparisons of these systems.
174.47 +
174.48 + So Isar challenges the traditional way of recording informal proofs
174.49 + in mathematical prose, as well as the common tendency to see fully
174.50 + formal proofs directly as objects of some logical calculus (e.g.\
174.51 + \isa{{\isachardoublequote}{\isasymlambda}{\isachardoublequote}}-terms in a version of type theory). In fact, Isar is
174.52 + better understood as an interpreter of a simple block-structured
174.53 + language for describing the data flow of local facts and goals,
174.54 + interspersed with occasional invocations of proof methods.
174.55 + Everything is reduced to logical inferences internally, but these
174.56 + steps are somewhat marginal compared to the overall bookkeeping of
174.57 + the interpretation process. Thanks to careful design of the syntax
174.58 + and semantics of Isar language elements, a formal record of Isar
174.59 + instructions may later appear as an intelligible text to the
174.60 + attentive reader.
174.61 +
174.62 + The Isar proof language has emerged from careful analysis of some
174.63 + inherent virtues of the existing logical framework of Isabelle/Pure
174.64 + \cite{paulson-found,paulson700}, notably composition of higher-order
174.65 + natural deduction rules, which is a generalization of Gentzen's
174.66 + original calculus \cite{Gentzen:1935}. The approach of generic
174.67 + inference systems in Pure is continued by Isar towards actual proof
174.68 + texts.
174.69 +
174.70 + Concrete applications require another intermediate layer: an
174.71 + object-logic. Isabelle/HOL \cite{isa-tutorial} (simply-typed
174.72 + set-theory) is being used most of the time; Isabelle/ZF
174.73 + \cite{isabelle-ZF} is less extensively developed, although it would
174.74 + probably fit better for classical mathematics.
174.75 +
174.76 + \medskip In order to illustrate natural deduction in Isar, we shall
174.77 + refer to the background theory and library of Isabelle/HOL. This
174.78 + includes common notions of predicate logic, naive set-theory etc.\
174.79 + using fairly standard mathematical notation. From the perspective
174.80 + of generic natural deduction there is nothing special about the
174.81 + logical connectives of HOL (\isa{{\isachardoublequote}{\isasymand}{\isachardoublequote}}, \isa{{\isachardoublequote}{\isasymor}{\isachardoublequote}}, \isa{{\isachardoublequote}{\isasymforall}{\isachardoublequote}},
174.82 + \isa{{\isachardoublequote}{\isasymexists}{\isachardoublequote}}, etc.), only the resulting reasoning principles are
174.83 + relevant to the user. There are similar rules available for
174.84 + set-theory operators (\isa{{\isachardoublequote}{\isasyminter}{\isachardoublequote}}, \isa{{\isachardoublequote}{\isasymunion}{\isachardoublequote}}, \isa{{\isachardoublequote}{\isasymInter}{\isachardoublequote}}, \isa{{\isachardoublequote}{\isasymUnion}{\isachardoublequote}}, etc.), or any other theory developed in the library (lattice
174.85 + theory, topology etc.).
174.86 +
174.87 + Subsequently we briefly review fragments of Isar proof texts
174.88 + corresponding directly to such general deduction schemes. The
174.89 + examples shall refer to set-theory, to minimize the danger of
174.90 + understanding connectives of predicate logic as something special.
174.91 +
174.92 + \medskip The following deduction performs \isa{{\isachardoublequote}{\isasyminter}{\isachardoublequote}}-introduction,
174.93 + working forwards from assumptions towards the conclusion. We give
174.94 + both the Isar text, and depict the primitive rule involved, as
174.95 + determined by unification of the problem against rules that are
174.96 + declared in the library context.%
174.97 +\end{isamarkuptext}%
174.98 +\isamarkuptrue%
174.99 +%
174.100 +\medskip\begin{minipage}{0.6\textwidth}
174.101 +%
174.102 +\isadelimproof
174.103 +%
174.104 +\endisadelimproof
174.105 +%
174.106 +\isatagproof
174.107 +\ \ \ \ \isacommand{assume}\isamarkupfalse%
174.108 +\ {\isachardoublequoteopen}x\ {\isasymin}\ A{\isachardoublequoteclose}\ \isakeyword{and}\ {\isachardoublequoteopen}x\ {\isasymin}\ B{\isachardoublequoteclose}\isanewline
174.109 +\ \ \ \ \isacommand{then}\isamarkupfalse%
174.110 +\ \isacommand{have}\isamarkupfalse%
174.111 +\ {\isachardoublequoteopen}x\ {\isasymin}\ A\ {\isasyminter}\ B{\isachardoublequoteclose}\ \isacommand{{\isachardot}{\isachardot}}\isamarkupfalse%
174.112 +%
174.113 +\endisatagproof
174.114 +{\isafoldproof}%
174.115 +%
174.116 +\isadelimproof
174.117 +%
174.118 +\endisadelimproof
174.119 +%
174.120 +\end{minipage}\begin{minipage}{0.4\textwidth}
174.121 +%
174.122 +\begin{isamarkuptext}%
174.123 +\infer{\isa{{\isachardoublequote}x\ {\isasymin}\ A\ {\isasyminter}\ B{\isachardoublequote}}}{\isa{{\isachardoublequote}x\ {\isasymin}\ A{\isachardoublequote}} & \isa{{\isachardoublequote}x\ {\isasymin}\ B{\isachardoublequote}}}%
174.124 +\end{isamarkuptext}%
174.125 +\isamarkuptrue%
174.126 +%
174.127 +\end{minipage}
174.128 +%
174.129 +\begin{isamarkuptext}%
174.130 +\medskip\noindent Note that \hyperlink{command.assume}{\mbox{\isa{\isacommand{assume}}}} augments the proof
174.131 + context, \hyperlink{command.then}{\mbox{\isa{\isacommand{then}}}} indicates that the current fact shall be
174.132 + used in the next step, and \hyperlink{command.have}{\mbox{\isa{\isacommand{have}}}} states an intermediate
174.133 + goal. The two dots ``\hyperlink{command.ddot}{\mbox{\isa{\isacommand{{\isachardot}{\isachardot}}}}}'' refer to a complete proof of
174.134 + this claim, using the indicated facts and a canonical rule from the
174.135 + context. We could have been more explicit here by spelling out the
174.136 + final proof step via the \hyperlink{command.by}{\mbox{\isa{\isacommand{by}}}} command:%
174.137 +\end{isamarkuptext}%
174.138 +\isamarkuptrue%
174.139 +%
174.140 +\isadelimproof
174.141 +%
174.142 +\endisadelimproof
174.143 +%
174.144 +\isatagproof
174.145 +\ \ \ \ \isacommand{assume}\isamarkupfalse%
174.146 +\ {\isachardoublequoteopen}x\ {\isasymin}\ A{\isachardoublequoteclose}\ \isakeyword{and}\ {\isachardoublequoteopen}x\ {\isasymin}\ B{\isachardoublequoteclose}\isanewline
174.147 +\ \ \ \ \isacommand{then}\isamarkupfalse%
174.148 +\ \isacommand{have}\isamarkupfalse%
174.149 +\ {\isachardoublequoteopen}x\ {\isasymin}\ A\ {\isasyminter}\ B{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse%
174.150 +\ {\isacharparenleft}rule\ IntI{\isacharparenright}%
174.151 +\endisatagproof
174.152 +{\isafoldproof}%
174.153 +%
174.154 +\isadelimproof
174.155 +%
174.156 +\endisadelimproof
174.157 +%
174.158 +\begin{isamarkuptext}%
174.159 +\noindent The format of the \isa{{\isachardoublequote}{\isasyminter}{\isachardoublequote}}-introduction rule represents
174.160 + the most basic inference, which proceeds from given premises to a
174.161 + conclusion, without any nested proof context involved.
174.162 +
174.163 + The next example performs backwards introduction on \isa{{\isachardoublequote}{\isasymInter}{\isasymA}{\isachardoublequote}},
174.164 + the intersection of all sets within a given set. This requires a
174.165 + nested proof of set membership within a local context, where \isa{A} is an arbitrary-but-fixed member of the collection:%
174.166 +\end{isamarkuptext}%
174.167 +\isamarkuptrue%
174.168 +%
174.169 +\medskip\begin{minipage}{0.6\textwidth}
174.170 +%
174.171 +\isadelimproof
174.172 +%
174.173 +\endisadelimproof
174.174 +%
174.175 +\isatagproof
174.176 +\ \ \ \ \isacommand{have}\isamarkupfalse%
174.177 +\ {\isachardoublequoteopen}x\ {\isasymin}\ {\isasymInter}{\isasymA}{\isachardoublequoteclose}\isanewline
174.178 +\ \ \ \ \isacommand{proof}\isamarkupfalse%
174.179 +\isanewline
174.180 +\ \ \ \ \ \ \isacommand{fix}\isamarkupfalse%
174.181 +\ A\isanewline
174.182 +\ \ \ \ \ \ \isacommand{assume}\isamarkupfalse%
174.183 +\ {\isachardoublequoteopen}A\ {\isasymin}\ {\isasymA}{\isachardoublequoteclose}\isanewline
174.184 +\ \ \ \ \ \ \isacommand{show}\isamarkupfalse%
174.185 +\ {\isachardoublequoteopen}x\ {\isasymin}\ A{\isachardoublequoteclose}%
174.186 +\endisatagproof
174.187 +{\isafoldproof}%
174.188 +%
174.189 +\isadelimproof
174.190 +%
174.191 +\endisadelimproof
174.192 +%
174.193 +\isadelimnoproof
174.194 +\ %
174.195 +\endisadelimnoproof
174.196 +%
174.197 +\isatagnoproof
174.198 +\isacommand{sorry}\isamarkupfalse%
174.199 +%
174.200 +\endisatagnoproof
174.201 +{\isafoldnoproof}%
174.202 +%
174.203 +\isadelimnoproof
174.204 +\isanewline
174.205 +%
174.206 +\endisadelimnoproof
174.207 +%
174.208 +\isadelimproof
174.209 +\ \ \ \ %
174.210 +\endisadelimproof
174.211 +%
174.212 +\isatagproof
174.213 +\isacommand{qed}\isamarkupfalse%
174.214 +%
174.215 +\endisatagproof
174.216 +{\isafoldproof}%
174.217 +%
174.218 +\isadelimproof
174.219 +%
174.220 +\endisadelimproof
174.221 +%
174.222 +\end{minipage}\begin{minipage}{0.4\textwidth}
174.223 +%
174.224 +\begin{isamarkuptext}%
174.225 +\infer{\isa{{\isachardoublequote}x\ {\isasymin}\ {\isasymInter}{\isasymA}{\isachardoublequote}}}{\infer*{\isa{{\isachardoublequote}x\ {\isasymin}\ A{\isachardoublequote}}}{\isa{{\isachardoublequote}{\isacharbrackleft}A{\isacharbrackright}{\isacharbrackleft}A\ {\isasymin}\ {\isasymA}{\isacharbrackright}{\isachardoublequote}}}}%
174.226 +\end{isamarkuptext}%
174.227 +\isamarkuptrue%
174.228 +%
174.229 +\end{minipage}
174.230 +%
174.231 +\begin{isamarkuptext}%
174.232 +\medskip\noindent This Isar reasoning pattern again refers to the
174.233 + primitive rule depicted above. The system determines it in the
174.234 + ``\hyperlink{command.proof}{\mbox{\isa{\isacommand{proof}}}}'' step, which could have been spelt out more
174.235 + explicitly as ``\hyperlink{command.proof}{\mbox{\isa{\isacommand{proof}}}}~\isa{{\isachardoublequote}{\isacharparenleft}rule\ InterI{\isacharparenright}{\isachardoublequote}}''. Note
174.236 + that the rule involves both a local parameter \isa{{\isachardoublequote}A{\isachardoublequote}} and an
174.237 + assumption \isa{{\isachardoublequote}A\ {\isasymin}\ {\isasymA}{\isachardoublequote}} in the nested reasoning. This kind of
174.238 + compound rule typically demands a genuine sub-proof in Isar, working
174.239 + backwards rather than forwards as seen before. In the proof body we
174.240 + encounter the \hyperlink{command.fix}{\mbox{\isa{\isacommand{fix}}}}-\hyperlink{command.assume}{\mbox{\isa{\isacommand{assume}}}}-\hyperlink{command.show}{\mbox{\isa{\isacommand{show}}}}
174.241 + outline of nested sub-proofs that is typical for Isar. The final
174.242 + \hyperlink{command.show}{\mbox{\isa{\isacommand{show}}}} is like \hyperlink{command.have}{\mbox{\isa{\isacommand{have}}}} followed by an additional
174.243 + refinement of the enclosing claim, using the rule derived from the
174.244 + proof body.
174.245 +
174.246 + \medskip The next example involves \isa{{\isachardoublequote}{\isasymUnion}{\isasymA}{\isachardoublequote}}, which can be
174.247 + characterized as the set of all \isa{{\isachardoublequote}x{\isachardoublequote}} such that \isa{{\isachardoublequote}{\isasymexists}A{\isachardot}\ x\ {\isasymin}\ A\ {\isasymand}\ A\ {\isasymin}\ {\isasymA}{\isachardoublequote}}. The elimination rule for \isa{{\isachardoublequote}x\ {\isasymin}\ {\isasymUnion}{\isasymA}{\isachardoublequote}} does
174.248 + not mention \isa{{\isachardoublequote}{\isasymexists}{\isachardoublequote}} and \isa{{\isachardoublequote}{\isasymand}{\isachardoublequote}} at all, but admits to obtain
174.249 + directly a local \isa{{\isachardoublequote}A{\isachardoublequote}} such that \isa{{\isachardoublequote}x\ {\isasymin}\ A{\isachardoublequote}} and \isa{{\isachardoublequote}A\ {\isasymin}\ {\isasymA}{\isachardoublequote}} hold. This corresponds to the following Isar proof and
174.250 + inference rule, respectively:%
174.251 +\end{isamarkuptext}%
174.252 +\isamarkuptrue%
174.253 +%
174.254 +\medskip\begin{minipage}{0.6\textwidth}
174.255 +%
174.256 +\isadelimproof
174.257 +%
174.258 +\endisadelimproof
174.259 +%
174.260 +\isatagproof
174.261 +\ \ \ \ \isacommand{assume}\isamarkupfalse%
174.262 +\ {\isachardoublequoteopen}x\ {\isasymin}\ {\isasymUnion}{\isasymA}{\isachardoublequoteclose}\isanewline
174.263 +\ \ \ \ \isacommand{then}\isamarkupfalse%
174.264 +\ \isacommand{have}\isamarkupfalse%
174.265 +\ C\isanewline
174.266 +\ \ \ \ \isacommand{proof}\isamarkupfalse%
174.267 +\isanewline
174.268 +\ \ \ \ \ \ \isacommand{fix}\isamarkupfalse%
174.269 +\ A\isanewline
174.270 +\ \ \ \ \ \ \isacommand{assume}\isamarkupfalse%
174.271 +\ {\isachardoublequoteopen}x\ {\isasymin}\ A{\isachardoublequoteclose}\ \isakeyword{and}\ {\isachardoublequoteopen}A\ {\isasymin}\ {\isasymA}{\isachardoublequoteclose}\isanewline
174.272 +\ \ \ \ \ \ \isacommand{show}\isamarkupfalse%
174.273 +\ C%
174.274 +\endisatagproof
174.275 +{\isafoldproof}%
174.276 +%
174.277 +\isadelimproof
174.278 +%
174.279 +\endisadelimproof
174.280 +%
174.281 +\isadelimnoproof
174.282 +\ %
174.283 +\endisadelimnoproof
174.284 +%
174.285 +\isatagnoproof
174.286 +\isacommand{sorry}\isamarkupfalse%
174.287 +%
174.288 +\endisatagnoproof
174.289 +{\isafoldnoproof}%
174.290 +%
174.291 +\isadelimnoproof
174.292 +\isanewline
174.293 +%
174.294 +\endisadelimnoproof
174.295 +%
174.296 +\isadelimproof
174.297 +\ \ \ \ %
174.298 +\endisadelimproof
174.299 +%
174.300 +\isatagproof
174.301 +\isacommand{qed}\isamarkupfalse%
174.302 +%
174.303 +\endisatagproof
174.304 +{\isafoldproof}%
174.305 +%
174.306 +\isadelimproof
174.307 +%
174.308 +\endisadelimproof
174.309 +%
174.310 +\end{minipage}\begin{minipage}{0.4\textwidth}
174.311 +%
174.312 +\begin{isamarkuptext}%
174.313 +\infer{\isa{{\isachardoublequote}C{\isachardoublequote}}}{\isa{{\isachardoublequote}x\ {\isasymin}\ {\isasymUnion}{\isasymA}{\isachardoublequote}} & \infer*{\isa{{\isachardoublequote}C{\isachardoublequote}}~}{\isa{{\isachardoublequote}{\isacharbrackleft}A{\isacharbrackright}{\isacharbrackleft}x\ {\isasymin}\ A{\isacharcomma}\ A\ {\isasymin}\ {\isasymA}{\isacharbrackright}{\isachardoublequote}}}}%
174.314 +\end{isamarkuptext}%
174.315 +\isamarkuptrue%
174.316 +%
174.317 +\end{minipage}
174.318 +%
174.319 +\begin{isamarkuptext}%
174.320 +\medskip\noindent Although the Isar proof follows the natural
174.321 + deduction rule closely, the text reads not as natural as
174.322 + anticipated. There is a double occurrence of an arbitrary
174.323 + conclusion \isa{{\isachardoublequote}C{\isachardoublequote}}, which represents the final result, but is
174.324 + irrelevant for now. This issue arises for any elimination rule
174.325 + involving local parameters. Isar provides the derived language
174.326 + element \hyperlink{command.obtain}{\mbox{\isa{\isacommand{obtain}}}}, which is able to perform the same
174.327 + elimination proof more conveniently:%
174.328 +\end{isamarkuptext}%
174.329 +\isamarkuptrue%
174.330 +%
174.331 +\isadelimproof
174.332 +%
174.333 +\endisadelimproof
174.334 +%
174.335 +\isatagproof
174.336 +\ \ \ \ \isacommand{assume}\isamarkupfalse%
174.337 +\ {\isachardoublequoteopen}x\ {\isasymin}\ {\isasymUnion}{\isasymA}{\isachardoublequoteclose}\isanewline
174.338 +\ \ \ \ \isacommand{then}\isamarkupfalse%
174.339 +\ \isacommand{obtain}\isamarkupfalse%
174.340 +\ A\ \isakeyword{where}\ {\isachardoublequoteopen}x\ {\isasymin}\ A{\isachardoublequoteclose}\ \isakeyword{and}\ {\isachardoublequoteopen}A\ {\isasymin}\ {\isasymA}{\isachardoublequoteclose}\ \isacommand{{\isachardot}{\isachardot}}\isamarkupfalse%
174.341 +%
174.342 +\endisatagproof
174.343 +{\isafoldproof}%
174.344 +%
174.345 +\isadelimproof
174.346 +%
174.347 +\endisadelimproof
174.348 +%
174.349 +\begin{isamarkuptext}%
174.350 +\noindent Here we avoid to mention the final conclusion \isa{{\isachardoublequote}C{\isachardoublequote}}
174.351 + and return to plain forward reasoning. The rule involved in the
174.352 + ``\hyperlink{command.ddot}{\mbox{\isa{\isacommand{{\isachardot}{\isachardot}}}}}'' proof is the same as before.%
174.353 +\end{isamarkuptext}%
174.354 +\isamarkuptrue%
174.355 +%
174.356 +\isamarkupsection{The Pure framework \label{sec:framework-pure}%
174.357 +}
174.358 +\isamarkuptrue%
174.359 +%
174.360 +\begin{isamarkuptext}%
174.361 +The Pure logic \cite{paulson-found,paulson700} is an intuitionistic
174.362 + fragment of higher-order logic \cite{church40}. In type-theoretic
174.363 + parlance, there are three levels of \isa{{\isachardoublequote}{\isasymlambda}{\isachardoublequote}}-calculus with
174.364 + corresponding arrows \isa{{\isachardoublequote}{\isasymRightarrow}{\isachardoublequote}}/\isa{{\isachardoublequote}{\isasymAnd}{\isachardoublequote}}/\isa{{\isachardoublequote}{\isasymLongrightarrow}{\isachardoublequote}}:
174.365 +
174.366 + \medskip
174.367 + \begin{tabular}{ll}
174.368 + \isa{{\isachardoublequote}{\isasymalpha}\ {\isasymRightarrow}\ {\isasymbeta}{\isachardoublequote}} & syntactic function space (terms depending on terms) \\
174.369 + \isa{{\isachardoublequote}{\isasymAnd}x{\isachardot}\ B{\isacharparenleft}x{\isacharparenright}{\isachardoublequote}} & universal quantification (proofs depending on terms) \\
174.370 + \isa{{\isachardoublequote}A\ {\isasymLongrightarrow}\ B{\isachardoublequote}} & implication (proofs depending on proofs) \\
174.371 + \end{tabular}
174.372 + \medskip
174.373 +
174.374 + \noindent Here only the types of syntactic terms, and the
174.375 + propositions of proof terms have been shown. The \isa{{\isachardoublequote}{\isasymlambda}{\isachardoublequote}}-structure of proofs can be recorded as an optional feature of
174.376 + the Pure inference kernel \cite{Berghofer-Nipkow:2000:TPHOL}, but
174.377 + the formal system can never depend on them due to \emph{proof
174.378 + irrelevance}.
174.379 +
174.380 + On top of this most primitive layer of proofs, Pure implements a
174.381 + generic calculus for nested natural deduction rules, similar to
174.382 + \cite{Schroeder-Heister:1984}. Here object-logic inferences are
174.383 + internalized as formulae over \isa{{\isachardoublequote}{\isasymAnd}{\isachardoublequote}} and \isa{{\isachardoublequote}{\isasymLongrightarrow}{\isachardoublequote}}.
174.384 + Combining such rule statements may involve higher-order unification
174.385 + \cite{paulson-natural}.%
174.386 +\end{isamarkuptext}%
174.387 +\isamarkuptrue%
174.388 +%
174.389 +\isamarkupsubsection{Primitive inferences%
174.390 +}
174.391 +\isamarkuptrue%
174.392 +%
174.393 +\begin{isamarkuptext}%
174.394 +Term syntax provides explicit notation for abstraction \isa{{\isachardoublequote}{\isasymlambda}x\ {\isacharcolon}{\isacharcolon}\ {\isasymalpha}{\isachardot}\ b{\isacharparenleft}x{\isacharparenright}{\isachardoublequote}} and application \isa{{\isachardoublequote}b\ a{\isachardoublequote}}, while types are usually
174.395 + implicit thanks to type-inference; terms of type \isa{{\isachardoublequote}prop{\isachardoublequote}} are
174.396 + called propositions. Logical statements are composed via \isa{{\isachardoublequote}{\isasymAnd}x\ {\isacharcolon}{\isacharcolon}\ {\isasymalpha}{\isachardot}\ B{\isacharparenleft}x{\isacharparenright}{\isachardoublequote}} and \isa{{\isachardoublequote}A\ {\isasymLongrightarrow}\ B{\isachardoublequote}}. Primitive reasoning operates on
174.397 + judgments of the form \isa{{\isachardoublequote}{\isasymGamma}\ {\isasymturnstile}\ {\isasymphi}{\isachardoublequote}}, with standard introduction
174.398 + and elimination rules for \isa{{\isachardoublequote}{\isasymAnd}{\isachardoublequote}} and \isa{{\isachardoublequote}{\isasymLongrightarrow}{\isachardoublequote}} that refer to
174.399 + fixed parameters \isa{{\isachardoublequote}x\isactrlisub {\isadigit{1}}{\isacharcomma}\ {\isasymdots}{\isacharcomma}\ x\isactrlisub m{\isachardoublequote}} and hypotheses
174.400 + \isa{{\isachardoublequote}A\isactrlisub {\isadigit{1}}{\isacharcomma}\ {\isasymdots}{\isacharcomma}\ A\isactrlisub n{\isachardoublequote}} from the context \isa{{\isachardoublequote}{\isasymGamma}{\isachardoublequote}};
174.401 + the corresponding proof terms are left implicit. The subsequent
174.402 + inference rules define \isa{{\isachardoublequote}{\isasymGamma}\ {\isasymturnstile}\ {\isasymphi}{\isachardoublequote}} inductively, relative to a
174.403 + collection of axioms:
174.404 +
174.405 + \[
174.406 + \infer{\isa{{\isachardoublequote}{\isasymturnstile}\ A{\isachardoublequote}}}{(\isa{{\isachardoublequote}A{\isachardoublequote}} \text{~axiom})}
174.407 + \qquad
174.408 + \infer{\isa{{\isachardoublequote}A\ {\isasymturnstile}\ A{\isachardoublequote}}}{}
174.409 + \]
174.410 +
174.411 + \[
174.412 + \infer{\isa{{\isachardoublequote}{\isasymGamma}\ {\isasymturnstile}\ {\isasymAnd}x{\isachardot}\ B{\isacharparenleft}x{\isacharparenright}{\isachardoublequote}}}{\isa{{\isachardoublequote}{\isasymGamma}\ {\isasymturnstile}\ B{\isacharparenleft}x{\isacharparenright}{\isachardoublequote}} & \isa{{\isachardoublequote}x\ {\isasymnotin}\ {\isasymGamma}{\isachardoublequote}}}
174.413 + \qquad
174.414 + \infer{\isa{{\isachardoublequote}{\isasymGamma}\ {\isasymturnstile}\ B{\isacharparenleft}a{\isacharparenright}{\isachardoublequote}}}{\isa{{\isachardoublequote}{\isasymGamma}\ {\isasymturnstile}\ {\isasymAnd}x{\isachardot}\ B{\isacharparenleft}x{\isacharparenright}{\isachardoublequote}}}
174.415 + \]
174.416 +
174.417 + \[
174.418 + \infer{\isa{{\isachardoublequote}{\isasymGamma}\ {\isacharminus}\ A\ {\isasymturnstile}\ A\ {\isasymLongrightarrow}\ B{\isachardoublequote}}}{\isa{{\isachardoublequote}{\isasymGamma}\ {\isasymturnstile}\ B{\isachardoublequote}}}
174.419 + \qquad
174.420 + \infer{\isa{{\isachardoublequote}{\isasymGamma}\isactrlsub {\isadigit{1}}\ {\isasymunion}\ {\isasymGamma}\isactrlsub {\isadigit{2}}\ {\isasymturnstile}\ B{\isachardoublequote}}}{\isa{{\isachardoublequote}{\isasymGamma}\isactrlsub {\isadigit{1}}\ {\isasymturnstile}\ A\ {\isasymLongrightarrow}\ B{\isachardoublequote}} & \isa{{\isachardoublequote}{\isasymGamma}\isactrlsub {\isadigit{2}}\ {\isasymturnstile}\ A{\isachardoublequote}}}
174.421 + \]
174.422 +
174.423 + Furthermore, Pure provides a built-in equality \isa{{\isachardoublequote}{\isasymequiv}\ {\isacharcolon}{\isacharcolon}\ {\isasymalpha}\ {\isasymRightarrow}\ {\isasymalpha}\ {\isasymRightarrow}\ prop{\isachardoublequote}} with axioms for reflexivity, substitution, extensionality,
174.424 + and \isa{{\isachardoublequote}{\isasymalpha}{\isasymbeta}{\isasymeta}{\isachardoublequote}}-conversion on \isa{{\isachardoublequote}{\isasymlambda}{\isachardoublequote}}-terms.
174.425 +
174.426 + \medskip An object-logic introduces another layer on top of Pure,
174.427 + e.g.\ with types \isa{{\isachardoublequote}i{\isachardoublequote}} for individuals and \isa{{\isachardoublequote}o{\isachardoublequote}} for
174.428 + propositions, term constants \isa{{\isachardoublequote}Trueprop\ {\isacharcolon}{\isacharcolon}\ o\ {\isasymRightarrow}\ prop{\isachardoublequote}} as
174.429 + (implicit) derivability judgment and connectives like \isa{{\isachardoublequote}{\isasymand}\ {\isacharcolon}{\isacharcolon}\ o\ {\isasymRightarrow}\ o\ {\isasymRightarrow}\ o{\isachardoublequote}} or \isa{{\isachardoublequote}{\isasymforall}\ {\isacharcolon}{\isacharcolon}\ {\isacharparenleft}i\ {\isasymRightarrow}\ o{\isacharparenright}\ {\isasymRightarrow}\ o{\isachardoublequote}}, and axioms for object-level
174.430 + rules such as \isa{{\isachardoublequote}conjI{\isacharcolon}\ A\ {\isasymLongrightarrow}\ B\ {\isasymLongrightarrow}\ A\ {\isasymand}\ B{\isachardoublequote}} or \isa{{\isachardoublequote}allI{\isacharcolon}\ {\isacharparenleft}{\isasymAnd}x{\isachardot}\ B\ x{\isacharparenright}\ {\isasymLongrightarrow}\ {\isasymforall}x{\isachardot}\ B\ x{\isachardoublequote}}. Derived object rules are represented as theorems of
174.431 + Pure. After the initial object-logic setup, further axiomatizations
174.432 + are usually avoided; plain definitions and derived principles are
174.433 + used exclusively.%
174.434 +\end{isamarkuptext}%
174.435 +\isamarkuptrue%
174.436 +%
174.437 +\isamarkupsubsection{Reasoning with rules \label{sec:framework-resolution}%
174.438 +}
174.439 +\isamarkuptrue%
174.440 +%
174.441 +\begin{isamarkuptext}%
174.442 +Primitive inferences mostly serve foundational purposes. The main
174.443 + reasoning mechanisms of Pure operate on nested natural deduction
174.444 + rules expressed as formulae, using \isa{{\isachardoublequote}{\isasymAnd}{\isachardoublequote}} to bind local
174.445 + parameters and \isa{{\isachardoublequote}{\isasymLongrightarrow}{\isachardoublequote}} to express entailment. Multiple
174.446 + parameters and premises are represented by repeating these
174.447 + connectives in a right-associative manner.
174.448 +
174.449 + Since \isa{{\isachardoublequote}{\isasymAnd}{\isachardoublequote}} and \isa{{\isachardoublequote}{\isasymLongrightarrow}{\isachardoublequote}} commute thanks to the theorem
174.450 + \isa{{\isachardoublequote}{\isacharparenleft}A\ {\isasymLongrightarrow}\ {\isacharparenleft}{\isasymAnd}x{\isachardot}\ B\ x{\isacharparenright}{\isacharparenright}\ {\isasymequiv}\ {\isacharparenleft}{\isasymAnd}x{\isachardot}\ A\ {\isasymLongrightarrow}\ B\ x{\isacharparenright}{\isachardoublequote}}, we may assume w.l.o.g.\
174.451 + that rule statements always observe the normal form where
174.452 + quantifiers are pulled in front of implications at each level of
174.453 + nesting. This means that any Pure proposition may be presented as a
174.454 + \emph{Hereditary Harrop Formula} \cite{Miller:1991} which is of the
174.455 + form \isa{{\isachardoublequote}{\isasymAnd}x\isactrlisub {\isadigit{1}}\ {\isasymdots}\ x\isactrlisub m{\isachardot}\ H\isactrlisub {\isadigit{1}}\ {\isasymLongrightarrow}\ {\isasymdots}\ H\isactrlisub n\ {\isasymLongrightarrow}\ A{\isachardoublequote}} for \isa{{\isachardoublequote}m{\isacharcomma}\ n\ {\isasymge}\ {\isadigit{0}}{\isachardoublequote}}, and \isa{{\isachardoublequote}A{\isachardoublequote}} atomic, and \isa{{\isachardoublequote}H\isactrlisub {\isadigit{1}}{\isacharcomma}\ {\isasymdots}{\isacharcomma}\ H\isactrlisub n{\isachardoublequote}} being recursively of the same format.
174.456 + Following the convention that outermost quantifiers are implicit,
174.457 + Horn clauses \isa{{\isachardoublequote}A\isactrlisub {\isadigit{1}}\ {\isasymLongrightarrow}\ {\isasymdots}\ A\isactrlisub n\ {\isasymLongrightarrow}\ A{\isachardoublequote}} are a special
174.458 + case of this.
174.459 +
174.460 + For example, \isa{{\isachardoublequote}{\isasyminter}{\isachardoublequote}}-introduction rule encountered before is
174.461 + represented as a Pure theorem as follows:
174.462 + \[
174.463 + \isa{{\isachardoublequote}IntI{\isacharcolon}{\isachardoublequote}}~\isa{{\isachardoublequote}x\ {\isasymin}\ A\ {\isasymLongrightarrow}\ x\ {\isasymin}\ B\ {\isasymLongrightarrow}\ x\ {\isasymin}\ A\ {\isasyminter}\ B{\isachardoublequote}}
174.464 + \]
174.465 +
174.466 + \noindent This is a plain Horn clause, since no further nesting on
174.467 + the left is involved. The general \isa{{\isachardoublequote}{\isasymInter}{\isachardoublequote}}-introduction
174.468 + corresponds to a Hereditary Harrop Formula with one additional level
174.469 + of nesting:
174.470 + \[
174.471 + \isa{{\isachardoublequote}InterI{\isacharcolon}{\isachardoublequote}}~\isa{{\isachardoublequote}{\isacharparenleft}{\isasymAnd}A{\isachardot}\ A\ {\isasymin}\ {\isasymA}\ {\isasymLongrightarrow}\ x\ {\isasymin}\ A{\isacharparenright}\ {\isasymLongrightarrow}\ x\ {\isasymin}\ {\isasymInter}{\isasymA}{\isachardoublequote}}
174.472 + \]
174.473 +
174.474 + \medskip Goals are also represented as rules: \isa{{\isachardoublequote}A\isactrlisub {\isadigit{1}}\ {\isasymLongrightarrow}\ {\isasymdots}\ A\isactrlisub n\ {\isasymLongrightarrow}\ C{\isachardoublequote}} states that the sub-goals \isa{{\isachardoublequote}A\isactrlisub {\isadigit{1}}{\isacharcomma}\ {\isasymdots}{\isacharcomma}\ A\isactrlisub n{\isachardoublequote}} entail the result \isa{{\isachardoublequote}C{\isachardoublequote}}; for \isa{{\isachardoublequote}n\ {\isacharequal}\ {\isadigit{0}}{\isachardoublequote}} the
174.475 + goal is finished. To allow \isa{{\isachardoublequote}C{\isachardoublequote}} being a rule statement
174.476 + itself, we introduce the protective marker \isa{{\isachardoublequote}{\isacharhash}\ {\isacharcolon}{\isacharcolon}\ prop\ {\isasymRightarrow}\ prop{\isachardoublequote}}, which is defined as identity and hidden from the user. We
174.477 + initialize and finish goal states as follows:
174.478 +
174.479 + \[
174.480 + \begin{array}{c@ {\qquad}c}
174.481 + \infer[(\indexdef{}{inference}{init}\hypertarget{inference.init}{\hyperlink{inference.init}{\mbox{\isa{init}}}})]{\isa{{\isachardoublequote}C\ {\isasymLongrightarrow}\ {\isacharhash}C{\isachardoublequote}}}{} &
174.482 + \infer[(\indexdef{}{inference}{finish}\hypertarget{inference.finish}{\hyperlink{inference.finish}{\mbox{\isa{finish}}}})]{\isa{C}}{\isa{{\isachardoublequote}{\isacharhash}C{\isachardoublequote}}}
174.483 + \end{array}
174.484 + \]
174.485 +
174.486 + \noindent Goal states are refined in intermediate proof steps until
174.487 + a finished form is achieved. Here the two main reasoning principles
174.488 + are \hyperlink{inference.resolution}{\mbox{\isa{resolution}}}, for back-chaining a rule against a
174.489 + sub-goal (replacing it by zero or more sub-goals), and \hyperlink{inference.assumption}{\mbox{\isa{assumption}}}, for solving a sub-goal (finding a short-circuit with
174.490 + local assumptions). Below \isa{{\isachardoublequote}\isactrlvec x{\isachardoublequote}} stands for \isa{{\isachardoublequote}x\isactrlisub {\isadigit{1}}{\isacharcomma}\ {\isasymdots}{\isacharcomma}\ x\isactrlisub n{\isachardoublequote}} (\isa{{\isachardoublequote}n\ {\isasymge}\ {\isadigit{0}}{\isachardoublequote}}).
174.491 +
174.492 + \[
174.493 + \infer[(\indexdef{}{inference}{resolution}\hypertarget{inference.resolution}{\hyperlink{inference.resolution}{\mbox{\isa{resolution}}}})]
174.494 + {\isa{{\isachardoublequote}{\isacharparenleft}{\isasymAnd}\isactrlvec x{\isachardot}\ \isactrlvec H\ \isactrlvec x\ {\isasymLongrightarrow}\ \isactrlvec A\ {\isacharparenleft}\isactrlvec a\ \isactrlvec x{\isacharparenright}{\isacharparenright}{\isasymvartheta}\ {\isasymLongrightarrow}\ C{\isasymvartheta}{\isachardoublequote}}}
174.495 + {\begin{tabular}{rl}
174.496 + \isa{{\isachardoublequote}rule{\isacharcolon}{\isachardoublequote}} &
174.497 + \isa{{\isachardoublequote}\isactrlvec A\ \isactrlvec a\ {\isasymLongrightarrow}\ B\ \isactrlvec a{\isachardoublequote}} \\
174.498 + \isa{{\isachardoublequote}goal{\isacharcolon}{\isachardoublequote}} &
174.499 + \isa{{\isachardoublequote}{\isacharparenleft}{\isasymAnd}\isactrlvec x{\isachardot}\ \isactrlvec H\ \isactrlvec x\ {\isasymLongrightarrow}\ B{\isacharprime}\ \isactrlvec x{\isacharparenright}\ {\isasymLongrightarrow}\ C{\isachardoublequote}} \\
174.500 + \isa{{\isachardoublequote}goal\ unifier{\isacharcolon}{\isachardoublequote}} &
174.501 + \isa{{\isachardoublequote}{\isacharparenleft}{\isasymlambda}\isactrlvec x{\isachardot}\ B\ {\isacharparenleft}\isactrlvec a\ \isactrlvec x{\isacharparenright}{\isacharparenright}{\isasymvartheta}\ {\isacharequal}\ B{\isacharprime}{\isasymvartheta}{\isachardoublequote}} \\
174.502 + \end{tabular}}
174.503 + \]
174.504 +
174.505 + \medskip
174.506 +
174.507 + \[
174.508 + \infer[(\indexdef{}{inference}{assumption}\hypertarget{inference.assumption}{\hyperlink{inference.assumption}{\mbox{\isa{assumption}}}})]{\isa{{\isachardoublequote}C{\isasymvartheta}{\isachardoublequote}}}
174.509 + {\begin{tabular}{rl}
174.510 + \isa{{\isachardoublequote}goal{\isacharcolon}{\isachardoublequote}} &
174.511 + \isa{{\isachardoublequote}{\isacharparenleft}{\isasymAnd}\isactrlvec x{\isachardot}\ \isactrlvec H\ \isactrlvec x\ {\isasymLongrightarrow}\ A\ \isactrlvec x{\isacharparenright}\ {\isasymLongrightarrow}\ C{\isachardoublequote}} \\
174.512 + \isa{{\isachardoublequote}assm\ unifier{\isacharcolon}{\isachardoublequote}} & \isa{{\isachardoublequote}A{\isasymvartheta}\ {\isacharequal}\ H\isactrlsub i{\isasymvartheta}{\isachardoublequote}}~~\text{(for some~\isa{{\isachardoublequote}H\isactrlsub i{\isachardoublequote}})} \\
174.513 + \end{tabular}}
174.514 + \]
174.515 +
174.516 + The following trace illustrates goal-oriented reasoning in
174.517 + Isabelle/Pure:
174.518 +
174.519 + {\footnotesize
174.520 + \medskip
174.521 + \begin{tabular}{r@ {\quad}l}
174.522 + \isa{{\isachardoublequote}{\isacharparenleft}A\ {\isasymand}\ B\ {\isasymLongrightarrow}\ B\ {\isasymand}\ A{\isacharparenright}\ {\isasymLongrightarrow}\ {\isacharhash}{\isacharparenleft}A\ {\isasymand}\ B\ {\isasymLongrightarrow}\ B\ {\isasymand}\ A{\isacharparenright}{\isachardoublequote}} & \isa{{\isachardoublequote}{\isacharparenleft}init{\isacharparenright}{\isachardoublequote}} \\
174.523 + \isa{{\isachardoublequote}{\isacharparenleft}A\ {\isasymand}\ B\ {\isasymLongrightarrow}\ B{\isacharparenright}\ {\isasymLongrightarrow}\ {\isacharparenleft}A\ {\isasymand}\ B\ {\isasymLongrightarrow}\ A{\isacharparenright}\ {\isasymLongrightarrow}\ {\isacharhash}{\isasymdots}{\isachardoublequote}} & \isa{{\isachardoublequote}{\isacharparenleft}resolution\ B\ {\isasymLongrightarrow}\ A\ {\isasymLongrightarrow}\ B\ {\isasymand}\ A{\isacharparenright}{\isachardoublequote}} \\
174.524 + \isa{{\isachardoublequote}{\isacharparenleft}A\ {\isasymand}\ B\ {\isasymLongrightarrow}\ A\ {\isasymand}\ B{\isacharparenright}\ {\isasymLongrightarrow}\ {\isacharparenleft}A\ {\isasymand}\ B\ {\isasymLongrightarrow}\ A{\isacharparenright}\ {\isasymLongrightarrow}\ {\isacharhash}{\isasymdots}{\isachardoublequote}} & \isa{{\isachardoublequote}{\isacharparenleft}resolution\ A\ {\isasymand}\ B\ {\isasymLongrightarrow}\ B{\isacharparenright}{\isachardoublequote}} \\
174.525 + \isa{{\isachardoublequote}{\isacharparenleft}A\ {\isasymand}\ B\ {\isasymLongrightarrow}\ A{\isacharparenright}\ {\isasymLongrightarrow}\ {\isacharhash}{\isasymdots}{\isachardoublequote}} & \isa{{\isachardoublequote}{\isacharparenleft}assumption{\isacharparenright}{\isachardoublequote}} \\
174.526 + \isa{{\isachardoublequote}{\isacharparenleft}A\ {\isasymand}\ B\ {\isasymLongrightarrow}\ B\ {\isasymand}\ A{\isacharparenright}\ {\isasymLongrightarrow}\ {\isacharhash}{\isasymdots}{\isachardoublequote}} & \isa{{\isachardoublequote}{\isacharparenleft}resolution\ A\ {\isasymand}\ B\ {\isasymLongrightarrow}\ A{\isacharparenright}{\isachardoublequote}} \\
174.527 + \isa{{\isachardoublequote}{\isacharhash}{\isasymdots}{\isachardoublequote}} & \isa{{\isachardoublequote}{\isacharparenleft}assumption{\isacharparenright}{\isachardoublequote}} \\
174.528 + \isa{{\isachardoublequote}A\ {\isasymand}\ B\ {\isasymLongrightarrow}\ B\ {\isasymand}\ A{\isachardoublequote}} & \isa{{\isachardoublequote}{\isacharparenleft}finish{\isacharparenright}{\isachardoublequote}} \\
174.529 + \end{tabular}
174.530 + \medskip
174.531 + }
174.532 +
174.533 + Compositions of \hyperlink{inference.assumption}{\mbox{\isa{assumption}}} after \hyperlink{inference.resolution}{\mbox{\isa{resolution}}} occurs quite often, typically in elimination steps.
174.534 + Traditional Isabelle tactics accommodate this by a combined
174.535 + \indexdef{}{inference}{elim\_resolution}\hypertarget{inference.elim-resolution}{\hyperlink{inference.elim-resolution}{\mbox{\isa{elim{\isacharunderscore}resolution}}}} principle. In contrast, Isar uses
174.536 + a slightly more refined combination, where the assumptions to be
174.537 + closed are marked explicitly, using again the protective marker
174.538 + \isa{{\isachardoublequote}{\isacharhash}{\isachardoublequote}}:
174.539 +
174.540 + \[
174.541 + \infer[(\hyperlink{inference.refinement}{\mbox{\isa{refinement}}})]
174.542 + {\isa{{\isachardoublequote}{\isacharparenleft}{\isasymAnd}\isactrlvec x{\isachardot}\ \isactrlvec H\ \isactrlvec x\ {\isasymLongrightarrow}\ \isactrlvec G{\isacharprime}\ {\isacharparenleft}\isactrlvec a\ \isactrlvec x{\isacharparenright}{\isacharparenright}{\isasymvartheta}\ {\isasymLongrightarrow}\ C{\isasymvartheta}{\isachardoublequote}}}
174.543 + {\begin{tabular}{rl}
174.544 + \isa{{\isachardoublequote}sub{\isasymdash}proof{\isacharcolon}{\isachardoublequote}} &
174.545 + \isa{{\isachardoublequote}\isactrlvec G\ \isactrlvec a\ {\isasymLongrightarrow}\ B\ \isactrlvec a{\isachardoublequote}} \\
174.546 + \isa{{\isachardoublequote}goal{\isacharcolon}{\isachardoublequote}} &
174.547 + \isa{{\isachardoublequote}{\isacharparenleft}{\isasymAnd}\isactrlvec x{\isachardot}\ \isactrlvec H\ \isactrlvec x\ {\isasymLongrightarrow}\ B{\isacharprime}\ \isactrlvec x{\isacharparenright}\ {\isasymLongrightarrow}\ C{\isachardoublequote}} \\
174.548 + \isa{{\isachardoublequote}goal\ unifier{\isacharcolon}{\isachardoublequote}} &
174.549 + \isa{{\isachardoublequote}{\isacharparenleft}{\isasymlambda}\isactrlvec x{\isachardot}\ B\ {\isacharparenleft}\isactrlvec a\ \isactrlvec x{\isacharparenright}{\isacharparenright}{\isasymvartheta}\ {\isacharequal}\ B{\isacharprime}{\isasymvartheta}{\isachardoublequote}} \\
174.550 + \isa{{\isachardoublequote}assm\ unifiers{\isacharcolon}{\isachardoublequote}} &
174.551 + \isa{{\isachardoublequote}{\isacharparenleft}{\isasymlambda}\isactrlvec x{\isachardot}\ G\isactrlsub j\ {\isacharparenleft}\isactrlvec a\ \isactrlvec x{\isacharparenright}{\isacharparenright}{\isasymvartheta}\ {\isacharequal}\ {\isacharhash}H\isactrlsub i{\isasymvartheta}{\isachardoublequote}} \\
174.552 + & \quad (for each marked \isa{{\isachardoublequote}G\isactrlsub j{\isachardoublequote}} some \isa{{\isachardoublequote}{\isacharhash}H\isactrlsub i{\isachardoublequote}}) \\
174.553 + \end{tabular}}
174.554 + \]
174.555 +
174.556 + \noindent Here the \isa{{\isachardoublequote}sub{\isasymdash}proof{\isachardoublequote}} rule stems from the
174.557 + main \hyperlink{command.fix}{\mbox{\isa{\isacommand{fix}}}}-\hyperlink{command.assume}{\mbox{\isa{\isacommand{assume}}}}-\hyperlink{command.show}{\mbox{\isa{\isacommand{show}}}} outline of
174.558 + Isar (cf.\ \secref{sec:framework-subproof}): each assumption
174.559 + indicated in the text results in a marked premise \isa{{\isachardoublequote}G{\isachardoublequote}} above.
174.560 + The marking enforces resolution against one of the sub-goal's
174.561 + premises. Consequently, \hyperlink{command.fix}{\mbox{\isa{\isacommand{fix}}}}-\hyperlink{command.assume}{\mbox{\isa{\isacommand{assume}}}}-\hyperlink{command.show}{\mbox{\isa{\isacommand{show}}}} enables to fit the result of a sub-proof quite robustly into a
174.562 + pending sub-goal, while maintaining a good measure of flexibility.%
174.563 +\end{isamarkuptext}%
174.564 +\isamarkuptrue%
174.565 +%
174.566 +\isamarkupsection{The Isar proof language \label{sec:framework-isar}%
174.567 +}
174.568 +\isamarkuptrue%
174.569 +%
174.570 +\begin{isamarkuptext}%
174.571 +Structured proofs are presented as high-level expressions for
174.572 + composing entities of Pure (propositions, facts, and goals). The
174.573 + Isar proof language allows to organize reasoning within the
174.574 + underlying rule calculus of Pure, but Isar is not another logical
174.575 + calculus!
174.576 +
174.577 + Isar is an exercise in sound minimalism. Approximately half of the
174.578 + language is introduced as primitive, the rest defined as derived
174.579 + concepts. The following grammar describes the core language
174.580 + (category \isa{{\isachardoublequote}proof{\isachardoublequote}}), which is embedded into theory
174.581 + specification elements such as \hyperlink{command.theorem}{\mbox{\isa{\isacommand{theorem}}}}; see also
174.582 + \secref{sec:framework-stmt} for the separate category \isa{{\isachardoublequote}statement{\isachardoublequote}}.
174.583 +
174.584 + \medskip
174.585 + \begin{tabular}{rcl}
174.586 + \isa{{\isachardoublequote}theory{\isasymdash}stmt{\isachardoublequote}} & = & \hyperlink{command.theorem}{\mbox{\isa{\isacommand{theorem}}}}~\isa{{\isachardoublequote}statement\ proof\ \ {\isacharbar}{\isachardoublequote}}~~\hyperlink{command.definition}{\mbox{\isa{\isacommand{definition}}}}~\isa{{\isachardoublequote}{\isasymdots}\ \ {\isacharbar}\ \ {\isasymdots}{\isachardoublequote}} \\[1ex]
174.587 +
174.588 + \isa{{\isachardoublequote}proof{\isachardoublequote}} & = & \isa{{\isachardoublequote}prfx\isactrlsup {\isacharasterisk}{\isachardoublequote}}~\hyperlink{command.proof}{\mbox{\isa{\isacommand{proof}}}}~\isa{{\isachardoublequote}method\isactrlsup {\isacharquery}\ stmt\isactrlsup {\isacharasterisk}{\isachardoublequote}}~\hyperlink{command.qed}{\mbox{\isa{\isacommand{qed}}}}~\isa{{\isachardoublequote}method\isactrlsup {\isacharquery}{\isachardoublequote}} \\[1ex]
174.589 +
174.590 + \isa{prfx} & = & \hyperlink{command.using}{\mbox{\isa{\isacommand{using}}}}~\isa{{\isachardoublequote}facts{\isachardoublequote}} \\
174.591 + & \isa{{\isachardoublequote}{\isacharbar}{\isachardoublequote}} & \hyperlink{command.unfolding}{\mbox{\isa{\isacommand{unfolding}}}}~\isa{{\isachardoublequote}facts{\isachardoublequote}} \\
174.592 +
174.593 + \isa{stmt} & = & \hyperlink{command.braceleft}{\mbox{\isa{\isacommand{{\isacharbraceleft}}}}}~\isa{{\isachardoublequote}stmt\isactrlsup {\isacharasterisk}{\isachardoublequote}}~\hyperlink{command.braceright}{\mbox{\isa{\isacommand{{\isacharbraceright}}}}} \\
174.594 + & \isa{{\isachardoublequote}{\isacharbar}{\isachardoublequote}} & \hyperlink{command.next}{\mbox{\isa{\isacommand{next}}}} \\
174.595 + & \isa{{\isachardoublequote}{\isacharbar}{\isachardoublequote}} & \hyperlink{command.note}{\mbox{\isa{\isacommand{note}}}}~\isa{{\isachardoublequote}name\ {\isacharequal}\ facts{\isachardoublequote}} \\
174.596 + & \isa{{\isachardoublequote}{\isacharbar}{\isachardoublequote}} & \hyperlink{command.let}{\mbox{\isa{\isacommand{let}}}}~\isa{{\isachardoublequote}term\ {\isacharequal}\ term{\isachardoublequote}} \\
174.597 + & \isa{{\isachardoublequote}{\isacharbar}{\isachardoublequote}} & \hyperlink{command.fix}{\mbox{\isa{\isacommand{fix}}}}~\isa{{\isachardoublequote}var\isactrlsup {\isacharplus}{\isachardoublequote}} \\
174.598 + & \isa{{\isachardoublequote}{\isacharbar}{\isachardoublequote}} & \hyperlink{command.assume}{\mbox{\isa{\isacommand{assume}}}}~\isa{{\isachardoublequote}{\isasymguillemotleft}inference{\isasymguillemotright}\ name{\isacharcolon}\ props{\isachardoublequote}} \\
174.599 + & \isa{{\isachardoublequote}{\isacharbar}{\isachardoublequote}} & \hyperlink{command.then}{\mbox{\isa{\isacommand{then}}}}\isa{{\isachardoublequote}\isactrlsup {\isacharquery}{\isachardoublequote}}~\isa{goal} \\
174.600 + \isa{goal} & = & \hyperlink{command.have}{\mbox{\isa{\isacommand{have}}}}~\isa{{\isachardoublequote}name{\isacharcolon}\ props\ proof{\isachardoublequote}} \\
174.601 + & \isa{{\isachardoublequote}{\isacharbar}{\isachardoublequote}} & \hyperlink{command.show}{\mbox{\isa{\isacommand{show}}}}~\isa{{\isachardoublequote}name{\isacharcolon}\ props\ proof{\isachardoublequote}} \\
174.602 + \end{tabular}
174.603 +
174.604 + \medskip Simultaneous propositions or facts may be separated by the
174.605 + \hyperlink{keyword.and}{\mbox{\isa{\isakeyword{and}}}} keyword.
174.606 +
174.607 + \medskip The syntax for terms and propositions is inherited from
174.608 + Pure (and the object-logic). A \isa{{\isachardoublequote}pattern{\isachardoublequote}} is a \isa{{\isachardoublequote}term{\isachardoublequote}} with schematic variables, to be bound by higher-order
174.609 + matching.
174.610 +
174.611 + \medskip Facts may be referenced by name or proposition. For
174.612 + example, the result of ``\hyperlink{command.have}{\mbox{\isa{\isacommand{have}}}}~\isa{{\isachardoublequote}a{\isacharcolon}\ A\ {\isasymlangle}proof{\isasymrangle}{\isachardoublequote}}''
174.613 + becomes available both as \isa{{\isachardoublequote}a{\isachardoublequote}} and
174.614 + \isacharbackquoteopen\isa{{\isachardoublequote}A{\isachardoublequote}}\isacharbackquoteclose. Moreover,
174.615 + fact expressions may involve attributes that modify either the
174.616 + theorem or the background context. For example, the expression
174.617 + ``\isa{{\isachardoublequote}a\ {\isacharbrackleft}OF\ b{\isacharbrackright}{\isachardoublequote}}'' refers to the composition of two facts
174.618 + according to the \hyperlink{inference.resolution}{\mbox{\isa{resolution}}} inference of
174.619 + \secref{sec:framework-resolution}, while ``\isa{{\isachardoublequote}a\ {\isacharbrackleft}intro{\isacharbrackright}{\isachardoublequote}}''
174.620 + declares a fact as introduction rule in the context.
174.621 +
174.622 + The special fact called ``\hyperlink{fact.this}{\mbox{\isa{this}}}'' always refers to the last
174.623 + result, as produced by \hyperlink{command.note}{\mbox{\isa{\isacommand{note}}}}, \hyperlink{command.assume}{\mbox{\isa{\isacommand{assume}}}}, \hyperlink{command.have}{\mbox{\isa{\isacommand{have}}}}, or \hyperlink{command.show}{\mbox{\isa{\isacommand{show}}}}. Since \hyperlink{command.note}{\mbox{\isa{\isacommand{note}}}} occurs
174.624 + frequently together with \hyperlink{command.then}{\mbox{\isa{\isacommand{then}}}} we provide some
174.625 + abbreviations:
174.626 +
174.627 + \medskip
174.628 + \begin{tabular}{rcl}
174.629 + \hyperlink{command.from}{\mbox{\isa{\isacommand{from}}}}~\isa{a} & \isa{{\isachardoublequote}{\isasymequiv}{\isachardoublequote}} & \hyperlink{command.note}{\mbox{\isa{\isacommand{note}}}}~\isa{a}~\hyperlink{command.then}{\mbox{\isa{\isacommand{then}}}} \\
174.630 + \hyperlink{command.with}{\mbox{\isa{\isacommand{with}}}}~\isa{a} & \isa{{\isachardoublequote}{\isasymequiv}{\isachardoublequote}} & \hyperlink{command.from}{\mbox{\isa{\isacommand{from}}}}~\isa{{\isachardoublequote}a\ {\isasymAND}\ this{\isachardoublequote}} \\
174.631 + \end{tabular}
174.632 + \medskip
174.633 +
174.634 + The \isa{{\isachardoublequote}method{\isachardoublequote}} category is essentially a parameter and may be
174.635 + populated later. Methods use the facts indicated by \hyperlink{command.then}{\mbox{\isa{\isacommand{then}}}} or \hyperlink{command.using}{\mbox{\isa{\isacommand{using}}}}, and then operate on the goal state.
174.636 + Some basic methods are predefined: ``\hyperlink{method.-}{\mbox{\isa{{\isacharminus}}}}'' leaves the goal
174.637 + unchanged, ``\hyperlink{method.this}{\mbox{\isa{this}}}'' applies the facts as rules to the
174.638 + goal, ``\hyperlink{method.rule}{\mbox{\isa{rule}}}'' applies the facts to another rule and the
174.639 + result to the goal (both ``\hyperlink{method.this}{\mbox{\isa{this}}}'' and ``\hyperlink{method.rule}{\mbox{\isa{rule}}}''
174.640 + refer to \hyperlink{inference.resolution}{\mbox{\isa{resolution}}} of
174.641 + \secref{sec:framework-resolution}). The secondary arguments to
174.642 + ``\hyperlink{method.rule}{\mbox{\isa{rule}}}'' may be specified explicitly as in ``\isa{{\isachardoublequote}{\isacharparenleft}rule\ a{\isacharparenright}{\isachardoublequote}}'', or picked from the context. In the latter case, the system
174.643 + first tries rules declared as \hyperlink{attribute.Pure.elim}{\mbox{\isa{elim}}} or
174.644 + \hyperlink{attribute.Pure.dest}{\mbox{\isa{dest}}}, followed by those declared as \hyperlink{attribute.Pure.intro}{\mbox{\isa{intro}}}.
174.645 +
174.646 + The default method for \hyperlink{command.proof}{\mbox{\isa{\isacommand{proof}}}} is ``\hyperlink{method.rule}{\mbox{\isa{rule}}}''
174.647 + (arguments picked from the context), for \hyperlink{command.qed}{\mbox{\isa{\isacommand{qed}}}} it is
174.648 + ``\hyperlink{method.-}{\mbox{\isa{{\isacharminus}}}}''. Further abbreviations for terminal proof steps
174.649 + are ``\hyperlink{command.by}{\mbox{\isa{\isacommand{by}}}}~\isa{{\isachardoublequote}method\isactrlsub {\isadigit{1}}\ method\isactrlsub {\isadigit{2}}{\isachardoublequote}}'' for
174.650 + ``\hyperlink{command.proof}{\mbox{\isa{\isacommand{proof}}}}~\isa{{\isachardoublequote}method\isactrlsub {\isadigit{1}}{\isachardoublequote}}~\hyperlink{command.qed}{\mbox{\isa{\isacommand{qed}}}}~\isa{{\isachardoublequote}method\isactrlsub {\isadigit{2}}{\isachardoublequote}}'', and ``\hyperlink{command.ddot}{\mbox{\isa{\isacommand{{\isachardot}{\isachardot}}}}}'' for ``\hyperlink{command.by}{\mbox{\isa{\isacommand{by}}}}~\hyperlink{method.rule}{\mbox{\isa{rule}}}, and ``\hyperlink{command.dot}{\mbox{\isa{\isacommand{{\isachardot}}}}}'' for ``\hyperlink{command.by}{\mbox{\isa{\isacommand{by}}}}~\hyperlink{method.this}{\mbox{\isa{this}}}''. The \hyperlink{command.unfolding}{\mbox{\isa{\isacommand{unfolding}}}} element operates
174.651 + directly on the current facts and goal by applying equalities.
174.652 +
174.653 + \medskip Block structure can be indicated explicitly by ``\hyperlink{command.braceleft}{\mbox{\isa{\isacommand{{\isacharbraceleft}}}}}~\isa{{\isachardoublequote}{\isasymdots}{\isachardoublequote}}~\hyperlink{command.braceright}{\mbox{\isa{\isacommand{{\isacharbraceright}}}}}'', although the body of a sub-proof
174.654 + already involves implicit nesting. In any case, \hyperlink{command.next}{\mbox{\isa{\isacommand{next}}}}
174.655 + jumps into the next section of a block, i.e.\ it acts like closing
174.656 + an implicit block scope and opening another one; there is no direct
174.657 + correspondence to subgoals here.
174.658 +
174.659 + The remaining elements \hyperlink{command.fix}{\mbox{\isa{\isacommand{fix}}}} and \hyperlink{command.assume}{\mbox{\isa{\isacommand{assume}}}} build up
174.660 + a local context (see \secref{sec:framework-context}), while
174.661 + \hyperlink{command.show}{\mbox{\isa{\isacommand{show}}}} refines a pending sub-goal by the rule resulting
174.662 + from a nested sub-proof (see \secref{sec:framework-subproof}).
174.663 + Further derived concepts will support calculational reasoning (see
174.664 + \secref{sec:framework-calc}).%
174.665 +\end{isamarkuptext}%
174.666 +\isamarkuptrue%
174.667 +%
174.668 +\isamarkupsubsection{Context elements \label{sec:framework-context}%
174.669 +}
174.670 +\isamarkuptrue%
174.671 +%
174.672 +\begin{isamarkuptext}%
174.673 +In judgments \isa{{\isachardoublequote}{\isasymGamma}\ {\isasymturnstile}\ {\isasymphi}{\isachardoublequote}} of the primitive framework, \isa{{\isachardoublequote}{\isasymGamma}{\isachardoublequote}}
174.674 + essentially acts like a proof context. Isar elaborates this idea
174.675 + towards a higher-level notion, with additional information for
174.676 + type-inference, term abbreviations, local facts, hypotheses etc.
174.677 +
174.678 + The element \hyperlink{command.fix}{\mbox{\isa{\isacommand{fix}}}}~\isa{{\isachardoublequote}x\ {\isacharcolon}{\isacharcolon}\ {\isasymalpha}{\isachardoublequote}} declares a local
174.679 + parameter, i.e.\ an arbitrary-but-fixed entity of a given type; in
174.680 + results exported from the context, \isa{{\isachardoublequote}x{\isachardoublequote}} may become anything.
174.681 + The \hyperlink{command.assume}{\mbox{\isa{\isacommand{assume}}}}~\isa{{\isachardoublequote}{\isasymguillemotleft}inference{\isasymguillemotright}{\isachardoublequote}} element provides a
174.682 + general interface to hypotheses: ``\hyperlink{command.assume}{\mbox{\isa{\isacommand{assume}}}}~\isa{{\isachardoublequote}{\isasymguillemotleft}inference{\isasymguillemotright}\ A{\isachardoublequote}}'' produces \isa{{\isachardoublequote}A\ {\isasymturnstile}\ A{\isachardoublequote}} locally, while the
174.683 + included inference tells how to discharge \isa{A} from results
174.684 + \isa{{\isachardoublequote}A\ {\isasymturnstile}\ B{\isachardoublequote}} later on. There is no user-syntax for \isa{{\isachardoublequote}{\isasymguillemotleft}inference{\isasymguillemotright}{\isachardoublequote}}, i.e.\ it may only occur internally when derived
174.685 + commands are defined in ML.
174.686 +
174.687 + At the user-level, the default inference for \hyperlink{command.assume}{\mbox{\isa{\isacommand{assume}}}} is
174.688 + \hyperlink{inference.discharge}{\mbox{\isa{discharge}}} as given below. The additional variants
174.689 + \hyperlink{command.presume}{\mbox{\isa{\isacommand{presume}}}} and \hyperlink{command.def}{\mbox{\isa{\isacommand{def}}}} are defined as follows:
174.690 +
174.691 + \medskip
174.692 + \begin{tabular}{rcl}
174.693 + \hyperlink{command.presume}{\mbox{\isa{\isacommand{presume}}}}~\isa{A} & \isa{{\isachardoublequote}{\isasymequiv}{\isachardoublequote}} & \hyperlink{command.assume}{\mbox{\isa{\isacommand{assume}}}}~\isa{{\isachardoublequote}{\isasymguillemotleft}weak{\isasymdash}discharge{\isasymguillemotright}\ A{\isachardoublequote}} \\
174.694 + \hyperlink{command.def}{\mbox{\isa{\isacommand{def}}}}~\isa{{\isachardoublequote}x\ {\isasymequiv}\ a{\isachardoublequote}} & \isa{{\isachardoublequote}{\isasymequiv}{\isachardoublequote}} & \hyperlink{command.fix}{\mbox{\isa{\isacommand{fix}}}}~\isa{x}~\hyperlink{command.assume}{\mbox{\isa{\isacommand{assume}}}}~\isa{{\isachardoublequote}{\isasymguillemotleft}expansion{\isasymguillemotright}\ x\ {\isasymequiv}\ a{\isachardoublequote}} \\
174.695 + \end{tabular}
174.696 + \medskip
174.697 +
174.698 + \[
174.699 + \infer[(\indexdef{}{inference}{discharge}\hypertarget{inference.discharge}{\hyperlink{inference.discharge}{\mbox{\isa{discharge}}}})]{\isa{{\isachardoublequote}{\isasymstrut}{\isasymGamma}\ {\isacharminus}\ A\ {\isasymturnstile}\ {\isacharhash}A\ {\isasymLongrightarrow}\ B{\isachardoublequote}}}{\isa{{\isachardoublequote}{\isasymstrut}{\isasymGamma}\ {\isasymturnstile}\ B{\isachardoublequote}}}
174.700 + \]
174.701 + \[
174.702 + \infer[(\indexdef{}{inference}{weak-discharge}\hypertarget{inference.weak-discharge}{\hyperlink{inference.weak-discharge}{\mbox{\isa{weak{\isasymdash}discharge}}}})]{\isa{{\isachardoublequote}{\isasymstrut}{\isasymGamma}\ {\isacharminus}\ A\ {\isasymturnstile}\ A\ {\isasymLongrightarrow}\ B{\isachardoublequote}}}{\isa{{\isachardoublequote}{\isasymstrut}{\isasymGamma}\ {\isasymturnstile}\ B{\isachardoublequote}}}
174.703 + \]
174.704 + \[
174.705 + \infer[(\indexdef{}{inference}{expansion}\hypertarget{inference.expansion}{\hyperlink{inference.expansion}{\mbox{\isa{expansion}}}})]{\isa{{\isachardoublequote}{\isasymstrut}{\isasymGamma}\ {\isacharminus}\ {\isacharparenleft}x\ {\isasymequiv}\ a{\isacharparenright}\ {\isasymturnstile}\ B\ a{\isachardoublequote}}}{\isa{{\isachardoublequote}{\isasymstrut}{\isasymGamma}\ {\isasymturnstile}\ B\ x{\isachardoublequote}}}
174.706 + \]
174.707 +
174.708 + \medskip Note that \hyperlink{inference.discharge}{\mbox{\isa{discharge}}} and \hyperlink{inference.weak-discharge}{\mbox{\isa{weak{\isasymdash}discharge}}} differ in the marker for \isa{A}, which is
174.709 + relevant when the result of a \hyperlink{command.fix}{\mbox{\isa{\isacommand{fix}}}}-\hyperlink{command.assume}{\mbox{\isa{\isacommand{assume}}}}-\hyperlink{command.show}{\mbox{\isa{\isacommand{show}}}} outline is composed with a pending goal,
174.710 + cf.\ \secref{sec:framework-subproof}.
174.711 +
174.712 + The most interesting derived context element in Isar is \hyperlink{command.obtain}{\mbox{\isa{\isacommand{obtain}}}} \cite[\S5.3]{Wenzel-PhD}, which supports generalized
174.713 + elimination steps in a purely forward manner. The \hyperlink{command.obtain}{\mbox{\isa{\isacommand{obtain}}}}
174.714 + command takes a specification of parameters \isa{{\isachardoublequote}\isactrlvec x{\isachardoublequote}} and
174.715 + assumptions \isa{{\isachardoublequote}\isactrlvec A{\isachardoublequote}} to be added to the context, together
174.716 + with a proof of a case rule stating that this extension is
174.717 + conservative (i.e.\ may be removed from closed results later on):
174.718 +
174.719 + \medskip
174.720 + \begin{tabular}{l}
174.721 + \isa{{\isachardoublequote}{\isasymlangle}facts{\isasymrangle}{\isachardoublequote}}~~\hyperlink{command.obtain}{\mbox{\isa{\isacommand{obtain}}}}~\isa{{\isachardoublequote}\isactrlvec x\ {\isasymWHERE}\ \isactrlvec A\ \isactrlvec x\ \ {\isasymlangle}proof{\isasymrangle}\ {\isasymequiv}{\isachardoublequote}} \\[0.5ex]
174.722 + \quad \hyperlink{command.have}{\mbox{\isa{\isacommand{have}}}}~\isa{{\isachardoublequote}case{\isacharcolon}\ {\isasymAnd}thesis{\isachardot}\ {\isacharparenleft}{\isasymAnd}\isactrlvec x{\isachardot}\ \isactrlvec A\ \isactrlvec x\ {\isasymLongrightarrow}\ thesis{\isacharparenright}\ {\isasymLongrightarrow}\ thesis{\isasymrangle}{\isachardoublequote}} \\
174.723 + \quad \hyperlink{command.proof}{\mbox{\isa{\isacommand{proof}}}}~\hyperlink{method.-}{\mbox{\isa{{\isacharminus}}}} \\
174.724 + \qquad \hyperlink{command.fix}{\mbox{\isa{\isacommand{fix}}}}~\isa{thesis} \\
174.725 + \qquad \hyperlink{command.assume}{\mbox{\isa{\isacommand{assume}}}}~\isa{{\isachardoublequote}{\isacharbrackleft}intro{\isacharbrackright}{\isacharcolon}\ {\isasymAnd}\isactrlvec x{\isachardot}\ \isactrlvec A\ \isactrlvec x\ {\isasymLongrightarrow}\ thesis{\isachardoublequote}} \\
174.726 + \qquad \hyperlink{command.show}{\mbox{\isa{\isacommand{show}}}}~\isa{thesis}~\hyperlink{command.using}{\mbox{\isa{\isacommand{using}}}}~\isa{{\isachardoublequote}{\isasymlangle}facts{\isasymrangle}\ {\isasymlangle}proof{\isasymrangle}{\isachardoublequote}} \\
174.727 + \quad \hyperlink{command.qed}{\mbox{\isa{\isacommand{qed}}}} \\
174.728 + \quad \hyperlink{command.fix}{\mbox{\isa{\isacommand{fix}}}}~\isa{{\isachardoublequote}\isactrlvec x{\isachardoublequote}}~\hyperlink{command.assume}{\mbox{\isa{\isacommand{assume}}}}~\isa{{\isachardoublequote}{\isasymguillemotleft}elimination\ case{\isasymguillemotright}\ \isactrlvec A\ \isactrlvec x{\isachardoublequote}} \\
174.729 + \end{tabular}
174.730 + \medskip
174.731 +
174.732 + \[
174.733 + \infer[(\hyperlink{inference.elimination}{\mbox{\isa{elimination}}})]{\isa{{\isachardoublequote}{\isasymGamma}\ {\isasymturnstile}\ B{\isachardoublequote}}}{
174.734 + \begin{tabular}{rl}
174.735 + \isa{{\isachardoublequote}case{\isacharcolon}{\isachardoublequote}} &
174.736 + \isa{{\isachardoublequote}{\isasymGamma}\ {\isasymturnstile}\ {\isasymAnd}thesis{\isachardot}\ {\isacharparenleft}{\isasymAnd}\isactrlvec x{\isachardot}\ \isactrlvec A\ \isactrlvec x\ {\isasymLongrightarrow}\ thesis{\isacharparenright}\ {\isasymLongrightarrow}\ thesis{\isachardoublequote}} \\[0.2ex]
174.737 + \isa{{\isachardoublequote}result{\isacharcolon}{\isachardoublequote}} &
174.738 + \isa{{\isachardoublequote}{\isasymGamma}\ {\isasymunion}\ \isactrlvec A\ \isactrlvec y\ {\isasymturnstile}\ B{\isachardoublequote}} \\[0.2ex]
174.739 + \end{tabular}}
174.740 + \]
174.741 +
174.742 + \noindent Here the name ``\isa{thesis}'' is a specific convention
174.743 + for an arbitrary-but-fixed proposition; in the primitive natural
174.744 + deduction rules shown before we have occasionally used \isa{C}.
174.745 + The whole statement of ``\hyperlink{command.obtain}{\mbox{\isa{\isacommand{obtain}}}}~\isa{x}~\hyperlink{keyword.where}{\mbox{\isa{\isakeyword{where}}}}~\isa{{\isachardoublequote}A\ x{\isachardoublequote}}'' may be read as a claim that \isa{{\isachardoublequote}A\ x{\isachardoublequote}}
174.746 + may be assumed for some arbitrary-but-fixed \isa{{\isachardoublequote}x{\isachardoublequote}}. Also note
174.747 + that ``\hyperlink{command.obtain}{\mbox{\isa{\isacommand{obtain}}}}~\isa{{\isachardoublequote}A\ {\isasymAND}\ B{\isachardoublequote}}'' without parameters
174.748 + is similar to ``\hyperlink{command.have}{\mbox{\isa{\isacommand{have}}}}~\isa{{\isachardoublequote}A\ {\isasymAND}\ B{\isachardoublequote}}'', but the
174.749 + latter involves multiple sub-goals.
174.750 +
174.751 + \medskip The subsequent Isar proof texts explain all context
174.752 + elements introduced above using the formal proof language itself.
174.753 + After finishing a local proof within a block, we indicate the
174.754 + exported result via \hyperlink{command.note}{\mbox{\isa{\isacommand{note}}}}.%
174.755 +\end{isamarkuptext}%
174.756 +\isamarkuptrue%
174.757 +%
174.758 +\isadelimproof
174.759 +%
174.760 +\endisadelimproof
174.761 +%
174.762 +\isatagproof
174.763 +%
174.764 +\begin{minipage}[t]{0.4\textwidth}
174.765 +\ \ \isacommand{{\isacharbraceleft}}\isamarkupfalse%
174.766 +\isanewline
174.767 +\ \ \ \ \isacommand{fix}\isamarkupfalse%
174.768 +\ x\isanewline
174.769 +\ \ \ \ \isacommand{have}\isamarkupfalse%
174.770 +\ {\isachardoublequoteopen}B\ x{\isachardoublequoteclose}%
174.771 +\endisatagproof
174.772 +{\isafoldproof}%
174.773 +%
174.774 +\isadelimproof
174.775 +%
174.776 +\endisadelimproof
174.777 +%
174.778 +\isadelimnoproof
174.779 +\ %
174.780 +\endisadelimnoproof
174.781 +%
174.782 +\isatagnoproof
174.783 +\isacommand{sorry}\isamarkupfalse%
174.784 +%
174.785 +\endisatagnoproof
174.786 +{\isafoldnoproof}%
174.787 +%
174.788 +\isadelimnoproof
174.789 +\isanewline
174.790 +%
174.791 +\endisadelimnoproof
174.792 +%
174.793 +\isadelimproof
174.794 +\ \ %
174.795 +\endisadelimproof
174.796 +%
174.797 +\isatagproof
174.798 +\isacommand{{\isacharbraceright}}\isamarkupfalse%
174.799 +\isanewline
174.800 +\ \ \isacommand{note}\isamarkupfalse%
174.801 +\ {\isacharbackquoteopen}{\isasymAnd}x{\isachardot}\ B\ x{\isacharbackquoteclose}%
174.802 +\end{minipage}\quad\begin{minipage}[t]{0.4\textwidth}
174.803 +\ \ \isacommand{{\isacharbraceleft}}\isamarkupfalse%
174.804 +\isanewline
174.805 +\ \ \ \ \isacommand{assume}\isamarkupfalse%
174.806 +\ A\isanewline
174.807 +\ \ \ \ \isacommand{have}\isamarkupfalse%
174.808 +\ B%
174.809 +\endisatagproof
174.810 +{\isafoldproof}%
174.811 +%
174.812 +\isadelimproof
174.813 +%
174.814 +\endisadelimproof
174.815 +%
174.816 +\isadelimnoproof
174.817 +\ %
174.818 +\endisadelimnoproof
174.819 +%
174.820 +\isatagnoproof
174.821 +\isacommand{sorry}\isamarkupfalse%
174.822 +%
174.823 +\endisatagnoproof
174.824 +{\isafoldnoproof}%
174.825 +%
174.826 +\isadelimnoproof
174.827 +\isanewline
174.828 +%
174.829 +\endisadelimnoproof
174.830 +%
174.831 +\isadelimproof
174.832 +\ \ %
174.833 +\endisadelimproof
174.834 +%
174.835 +\isatagproof
174.836 +\isacommand{{\isacharbraceright}}\isamarkupfalse%
174.837 +\isanewline
174.838 +\ \ \isacommand{note}\isamarkupfalse%
174.839 +\ {\isacharbackquoteopen}A\ {\isasymLongrightarrow}\ B{\isacharbackquoteclose}%
174.840 +\end{minipage}\\[3ex]\begin{minipage}[t]{0.4\textwidth}
174.841 +\ \ \isacommand{{\isacharbraceleft}}\isamarkupfalse%
174.842 +\isanewline
174.843 +\ \ \ \ \isacommand{def}\isamarkupfalse%
174.844 +\ x\ {\isasymequiv}\ a\isanewline
174.845 +\ \ \ \ \isacommand{have}\isamarkupfalse%
174.846 +\ {\isachardoublequoteopen}B\ x{\isachardoublequoteclose}%
174.847 +\endisatagproof
174.848 +{\isafoldproof}%
174.849 +%
174.850 +\isadelimproof
174.851 +%
174.852 +\endisadelimproof
174.853 +%
174.854 +\isadelimnoproof
174.855 +\ %
174.856 +\endisadelimnoproof
174.857 +%
174.858 +\isatagnoproof
174.859 +\isacommand{sorry}\isamarkupfalse%
174.860 +%
174.861 +\endisatagnoproof
174.862 +{\isafoldnoproof}%
174.863 +%
174.864 +\isadelimnoproof
174.865 +\isanewline
174.866 +%
174.867 +\endisadelimnoproof
174.868 +%
174.869 +\isadelimproof
174.870 +\ \ %
174.871 +\endisadelimproof
174.872 +%
174.873 +\isatagproof
174.874 +\isacommand{{\isacharbraceright}}\isamarkupfalse%
174.875 +\isanewline
174.876 +\ \ \isacommand{note}\isamarkupfalse%
174.877 +\ {\isacharbackquoteopen}B\ a{\isacharbackquoteclose}%
174.878 +\end{minipage}\quad\begin{minipage}[t]{0.4\textwidth}
174.879 +\ \ \isacommand{{\isacharbraceleft}}\isamarkupfalse%
174.880 +\isanewline
174.881 +\ \ \ \ \isacommand{obtain}\isamarkupfalse%
174.882 +\ x\ \isakeyword{where}\ {\isachardoublequoteopen}A\ x{\isachardoublequoteclose}%
174.883 +\endisatagproof
174.884 +{\isafoldproof}%
174.885 +%
174.886 +\isadelimproof
174.887 +%
174.888 +\endisadelimproof
174.889 +%
174.890 +\isadelimnoproof
174.891 +\ %
174.892 +\endisadelimnoproof
174.893 +%
174.894 +\isatagnoproof
174.895 +\isacommand{sorry}\isamarkupfalse%
174.896 +%
174.897 +\endisatagnoproof
174.898 +{\isafoldnoproof}%
174.899 +%
174.900 +\isadelimnoproof
174.901 +\isanewline
174.902 +%
174.903 +\endisadelimnoproof
174.904 +%
174.905 +\isadelimproof
174.906 +\ \ \ \ %
174.907 +\endisadelimproof
174.908 +%
174.909 +\isatagproof
174.910 +\isacommand{have}\isamarkupfalse%
174.911 +\ B%
174.912 +\endisatagproof
174.913 +{\isafoldproof}%
174.914 +%
174.915 +\isadelimproof
174.916 +%
174.917 +\endisadelimproof
174.918 +%
174.919 +\isadelimnoproof
174.920 +\ %
174.921 +\endisadelimnoproof
174.922 +%
174.923 +\isatagnoproof
174.924 +\isacommand{sorry}\isamarkupfalse%
174.925 +%
174.926 +\endisatagnoproof
174.927 +{\isafoldnoproof}%
174.928 +%
174.929 +\isadelimnoproof
174.930 +\isanewline
174.931 +%
174.932 +\endisadelimnoproof
174.933 +%
174.934 +\isadelimproof
174.935 +\ \ %
174.936 +\endisadelimproof
174.937 +%
174.938 +\isatagproof
174.939 +\isacommand{{\isacharbraceright}}\isamarkupfalse%
174.940 +\isanewline
174.941 +\ \ \isacommand{note}\isamarkupfalse%
174.942 +\ {\isacharbackquoteopen}B{\isacharbackquoteclose}%
174.943 +\end{minipage}
174.944 +%
174.945 +\endisatagproof
174.946 +{\isafoldproof}%
174.947 +%
174.948 +\isadelimproof
174.949 +%
174.950 +\endisadelimproof
174.951 +%
174.952 +\begin{isamarkuptext}%
174.953 +\bigskip\noindent This illustrates the meaning of Isar context
174.954 + elements without goals getting in between.%
174.955 +\end{isamarkuptext}%
174.956 +\isamarkuptrue%
174.957 +%
174.958 +\isamarkupsubsection{Structured statements \label{sec:framework-stmt}%
174.959 +}
174.960 +\isamarkuptrue%
174.961 +%
174.962 +\begin{isamarkuptext}%
174.963 +The category \isa{{\isachardoublequote}statement{\isachardoublequote}} of top-level theorem specifications
174.964 + is defined as follows:
174.965 +
174.966 + \medskip
174.967 + \begin{tabular}{rcl}
174.968 + \isa{{\isachardoublequote}statement{\isachardoublequote}} & \isa{{\isachardoublequote}{\isasymequiv}{\isachardoublequote}} & \isa{{\isachardoublequote}name{\isacharcolon}\ props\ {\isasymAND}\ {\isasymdots}{\isachardoublequote}} \\
174.969 + & \isa{{\isachardoublequote}{\isacharbar}{\isachardoublequote}} & \isa{{\isachardoublequote}context\isactrlsup {\isacharasterisk}\ conclusion{\isachardoublequote}} \\[0.5ex]
174.970 +
174.971 + \isa{{\isachardoublequote}context{\isachardoublequote}} & \isa{{\isachardoublequote}{\isasymequiv}{\isachardoublequote}} & \isa{{\isachardoublequote}{\isasymFIXES}\ vars\ {\isasymAND}\ {\isasymdots}{\isachardoublequote}} \\
174.972 + & \isa{{\isachardoublequote}{\isacharbar}{\isachardoublequote}} & \isa{{\isachardoublequote}{\isasymASSUMES}\ name{\isacharcolon}\ props\ {\isasymAND}\ {\isasymdots}{\isachardoublequote}} \\
174.973 +
174.974 + \isa{{\isachardoublequote}conclusion{\isachardoublequote}} & \isa{{\isachardoublequote}{\isasymequiv}{\isachardoublequote}} & \isa{{\isachardoublequote}{\isasymSHOWS}\ name{\isacharcolon}\ props\ {\isasymAND}\ {\isasymdots}{\isachardoublequote}} \\
174.975 + & \isa{{\isachardoublequote}{\isacharbar}{\isachardoublequote}} & \isa{{\isachardoublequote}{\isasymOBTAINS}\ vars\ {\isasymAND}\ {\isasymdots}\ {\isasymWHERE}\ name{\isacharcolon}\ props\ {\isasymAND}\ {\isasymdots}{\isachardoublequote}} \\
174.976 + & & \quad \isa{{\isachardoublequote}{\isasymBBAR}\ {\isasymdots}{\isachardoublequote}} \\
174.977 + \end{tabular}
174.978 +
174.979 + \medskip\noindent A simple \isa{{\isachardoublequote}statement{\isachardoublequote}} consists of named
174.980 + propositions. The full form admits local context elements followed
174.981 + by the actual conclusions, such as ``\hyperlink{keyword.fixes}{\mbox{\isa{\isakeyword{fixes}}}}~\isa{x}~\hyperlink{keyword.assumes}{\mbox{\isa{\isakeyword{assumes}}}}~\isa{{\isachardoublequote}A\ x{\isachardoublequote}}~\hyperlink{keyword.shows}{\mbox{\isa{\isakeyword{shows}}}}~\isa{{\isachardoublequote}B\ x{\isachardoublequote}}''. The final result emerges as a Pure rule after discharging
174.982 + the context: \isa{{\isachardoublequote}{\isasymAnd}x{\isachardot}\ A\ x\ {\isasymLongrightarrow}\ B\ x{\isachardoublequote}}.
174.983 +
174.984 + The \hyperlink{keyword.obtains}{\mbox{\isa{\isakeyword{obtains}}}} variant is another abbreviation defined
174.985 + below; unlike \hyperlink{command.obtain}{\mbox{\isa{\isacommand{obtain}}}} (cf.\
174.986 + \secref{sec:framework-context}) there may be several ``cases''
174.987 + separated by ``\isa{{\isachardoublequote}{\isasymBBAR}{\isachardoublequote}}'', each consisting of several
174.988 + parameters (\isa{{\isachardoublequote}vars{\isachardoublequote}}) and several premises (\isa{{\isachardoublequote}props{\isachardoublequote}}).
174.989 + This specifies multi-branch elimination rules.
174.990 +
174.991 + \medskip
174.992 + \begin{tabular}{l}
174.993 + \isa{{\isachardoublequote}{\isasymOBTAINS}\ \isactrlvec x\ {\isasymWHERE}\ \isactrlvec A\ \isactrlvec x\ \ \ {\isasymBBAR}\ \ \ {\isasymdots}\ \ \ {\isasymequiv}{\isachardoublequote}} \\[0.5ex]
174.994 + \quad \isa{{\isachardoublequote}{\isasymFIXES}\ thesis{\isachardoublequote}} \\
174.995 + \quad \isa{{\isachardoublequote}{\isasymASSUMES}\ {\isacharbrackleft}intro{\isacharbrackright}{\isacharcolon}\ {\isasymAnd}\isactrlvec x{\isachardot}\ \isactrlvec A\ \isactrlvec x\ {\isasymLongrightarrow}\ thesis\ \ {\isasymAND}\ \ {\isasymdots}{\isachardoublequote}} \\
174.996 + \quad \isa{{\isachardoublequote}{\isasymSHOWS}\ thesis{\isachardoublequote}} \\
174.997 + \end{tabular}
174.998 + \medskip
174.999 +
174.1000 + Presenting structured statements in such an ``open'' format usually
174.1001 + simplifies the subsequent proof, because the outer structure of the
174.1002 + problem is already laid out directly. E.g.\ consider the following
174.1003 + canonical patterns for \isa{{\isachardoublequote}{\isasymSHOWS}{\isachardoublequote}} and \isa{{\isachardoublequote}{\isasymOBTAINS}{\isachardoublequote}},
174.1004 + respectively:%
174.1005 +\end{isamarkuptext}%
174.1006 +\isamarkuptrue%
174.1007 +%
174.1008 +\begin{minipage}{0.5\textwidth}
174.1009 +\isacommand{theorem}\isamarkupfalse%
174.1010 +\isanewline
174.1011 +\ \ \isakeyword{fixes}\ x\ \isakeyword{and}\ y\isanewline
174.1012 +\ \ \isakeyword{assumes}\ {\isachardoublequoteopen}A\ x{\isachardoublequoteclose}\ \isakeyword{and}\ {\isachardoublequoteopen}B\ y{\isachardoublequoteclose}\isanewline
174.1013 +\ \ \isakeyword{shows}\ {\isachardoublequoteopen}C\ x\ y{\isachardoublequoteclose}\isanewline
174.1014 +%
174.1015 +\isadelimproof
174.1016 +%
174.1017 +\endisadelimproof
174.1018 +%
174.1019 +\isatagproof
174.1020 +\isacommand{proof}\isamarkupfalse%
174.1021 +\ {\isacharminus}\isanewline
174.1022 +\ \ \isacommand{from}\isamarkupfalse%
174.1023 +\ {\isacharbackquoteopen}A\ x{\isacharbackquoteclose}\ \isakeyword{and}\ {\isacharbackquoteopen}B\ y{\isacharbackquoteclose}\isanewline
174.1024 +\ \ \isacommand{show}\isamarkupfalse%
174.1025 +\ {\isachardoublequoteopen}C\ x\ y{\isachardoublequoteclose}%
174.1026 +\endisatagproof
174.1027 +{\isafoldproof}%
174.1028 +%
174.1029 +\isadelimproof
174.1030 +%
174.1031 +\endisadelimproof
174.1032 +%
174.1033 +\isadelimnoproof
174.1034 +\ %
174.1035 +\endisadelimnoproof
174.1036 +%
174.1037 +\isatagnoproof
174.1038 +\isacommand{sorry}\isamarkupfalse%
174.1039 +%
174.1040 +\endisatagnoproof
174.1041 +{\isafoldnoproof}%
174.1042 +%
174.1043 +\isadelimnoproof
174.1044 +\isanewline
174.1045 +%
174.1046 +\endisadelimnoproof
174.1047 +%
174.1048 +\isadelimproof
174.1049 +%
174.1050 +\endisadelimproof
174.1051 +%
174.1052 +\isatagproof
174.1053 +\isacommand{qed}\isamarkupfalse%
174.1054 +%
174.1055 +\endisatagproof
174.1056 +{\isafoldproof}%
174.1057 +%
174.1058 +\isadelimproof
174.1059 +%
174.1060 +\endisadelimproof
174.1061 +%
174.1062 +\end{minipage}\begin{minipage}{0.5\textwidth}
174.1063 +\isacommand{theorem}\isamarkupfalse%
174.1064 +\isanewline
174.1065 +\ \ \isakeyword{obtains}\ x\ \isakeyword{and}\ y\isanewline
174.1066 +\ \ \isakeyword{where}\ {\isachardoublequoteopen}A\ x{\isachardoublequoteclose}\ \isakeyword{and}\ {\isachardoublequoteopen}B\ y{\isachardoublequoteclose}\isanewline
174.1067 +%
174.1068 +\isadelimproof
174.1069 +%
174.1070 +\endisadelimproof
174.1071 +%
174.1072 +\isatagproof
174.1073 +\isacommand{proof}\isamarkupfalse%
174.1074 +\ {\isacharminus}\isanewline
174.1075 +\ \ \isacommand{have}\isamarkupfalse%
174.1076 +\ {\isachardoublequoteopen}A\ a{\isachardoublequoteclose}\ \isakeyword{and}\ {\isachardoublequoteopen}B\ b{\isachardoublequoteclose}%
174.1077 +\endisatagproof
174.1078 +{\isafoldproof}%
174.1079 +%
174.1080 +\isadelimproof
174.1081 +%
174.1082 +\endisadelimproof
174.1083 +%
174.1084 +\isadelimnoproof
174.1085 +\ %
174.1086 +\endisadelimnoproof
174.1087 +%
174.1088 +\isatagnoproof
174.1089 +\isacommand{sorry}\isamarkupfalse%
174.1090 +%
174.1091 +\endisatagnoproof
174.1092 +{\isafoldnoproof}%
174.1093 +%
174.1094 +\isadelimnoproof
174.1095 +\isanewline
174.1096 +%
174.1097 +\endisadelimnoproof
174.1098 +%
174.1099 +\isadelimproof
174.1100 +\ \ %
174.1101 +\endisadelimproof
174.1102 +%
174.1103 +\isatagproof
174.1104 +\isacommand{then}\isamarkupfalse%
174.1105 +\ \isacommand{show}\isamarkupfalse%
174.1106 +\ thesis\ \isacommand{{\isachardot}{\isachardot}}\isamarkupfalse%
174.1107 +\isanewline
174.1108 +\isacommand{qed}\isamarkupfalse%
174.1109 +%
174.1110 +\endisatagproof
174.1111 +{\isafoldproof}%
174.1112 +%
174.1113 +\isadelimproof
174.1114 +%
174.1115 +\endisadelimproof
174.1116 +%
174.1117 +\end{minipage}
174.1118 +%
174.1119 +\begin{isamarkuptext}%
174.1120 +\medskip\noindent Here local facts \isacharbackquoteopen\isa{{\isachardoublequote}A\ x{\isachardoublequote}}\isacharbackquoteclose\ and \isacharbackquoteopen\isa{{\isachardoublequote}B\ y{\isachardoublequote}}\isacharbackquoteclose\ are referenced immediately; there is no
174.1121 + need to decompose the logical rule structure again. In the second
174.1122 + proof the final ``\hyperlink{command.then}{\mbox{\isa{\isacommand{then}}}}~\hyperlink{command.show}{\mbox{\isa{\isacommand{show}}}}~\isa{thesis}~\hyperlink{command.ddot}{\mbox{\isa{\isacommand{{\isachardot}{\isachardot}}}}}'' involves the local rule case \isa{{\isachardoublequote}{\isasymAnd}x\ y{\isachardot}\ A\ x\ {\isasymLongrightarrow}\ B\ y\ {\isasymLongrightarrow}\ thesis{\isachardoublequote}} for the particular instance of terms \isa{{\isachardoublequote}a{\isachardoublequote}} and \isa{{\isachardoublequote}b{\isachardoublequote}} produced in the body.%
174.1123 +\end{isamarkuptext}%
174.1124 +\isamarkuptrue%
174.1125 +%
174.1126 +\isamarkupsubsection{Structured proof refinement \label{sec:framework-subproof}%
174.1127 +}
174.1128 +\isamarkuptrue%
174.1129 +%
174.1130 +\begin{isamarkuptext}%
174.1131 +By breaking up the grammar for the Isar proof language, we may
174.1132 + understand a proof text as a linear sequence of individual proof
174.1133 + commands. These are interpreted as transitions of the Isar virtual
174.1134 + machine (Isar/VM), which operates on a block-structured
174.1135 + configuration in single steps. This allows users to write proof
174.1136 + texts in an incremental manner, and inspect intermediate
174.1137 + configurations for debugging.
174.1138 +
174.1139 + The basic idea is analogous to evaluating algebraic expressions on a
174.1140 + stack machine: \isa{{\isachardoublequote}{\isacharparenleft}a\ {\isacharplus}\ b{\isacharparenright}\ {\isasymcdot}\ c{\isachardoublequote}} then corresponds to a sequence
174.1141 + of single transitions for each symbol \isa{{\isachardoublequote}{\isacharparenleft}{\isacharcomma}\ a{\isacharcomma}\ {\isacharplus}{\isacharcomma}\ b{\isacharcomma}\ {\isacharparenright}{\isacharcomma}\ {\isasymcdot}{\isacharcomma}\ c{\isachardoublequote}}.
174.1142 + In Isar the algebraic values are facts or goals, and the operations
174.1143 + are inferences.
174.1144 +
174.1145 + \medskip The Isar/VM state maintains a stack of nodes, each node
174.1146 + contains the local proof context, the linguistic mode, and a pending
174.1147 + goal (optional). The mode determines the type of transition that
174.1148 + may be performed next, it essentially alternates between forward and
174.1149 + backward reasoning, with an intermediate stage for chained facts
174.1150 + (see \figref{fig:isar-vm}).
174.1151 +
174.1152 + \begin{figure}[htb]
174.1153 + \begin{center}
174.1154 + \includegraphics[width=0.8\textwidth]{Thy/document/isar-vm}
174.1155 + \end{center}
174.1156 + \caption{Isar/VM modes}\label{fig:isar-vm}
174.1157 + \end{figure}
174.1158 +
174.1159 + For example, in \isa{{\isachardoublequote}state{\isachardoublequote}} mode Isar acts like a mathematical
174.1160 + scratch-pad, accepting declarations like \hyperlink{command.fix}{\mbox{\isa{\isacommand{fix}}}}, \hyperlink{command.assume}{\mbox{\isa{\isacommand{assume}}}}, and claims like \hyperlink{command.have}{\mbox{\isa{\isacommand{have}}}}, \hyperlink{command.show}{\mbox{\isa{\isacommand{show}}}}. A goal
174.1161 + statement changes the mode to \isa{{\isachardoublequote}prove{\isachardoublequote}}, which means that we
174.1162 + may now refine the problem via \hyperlink{command.unfolding}{\mbox{\isa{\isacommand{unfolding}}}} or \hyperlink{command.proof}{\mbox{\isa{\isacommand{proof}}}}. Then we are again in \isa{{\isachardoublequote}state{\isachardoublequote}} mode of a proof body,
174.1163 + which may issue \hyperlink{command.show}{\mbox{\isa{\isacommand{show}}}} statements to solve pending
174.1164 + sub-goals. A concluding \hyperlink{command.qed}{\mbox{\isa{\isacommand{qed}}}} will return to the original
174.1165 + \isa{{\isachardoublequote}state{\isachardoublequote}} mode one level upwards. The subsequent Isar/VM
174.1166 + trace indicates block structure, linguistic mode, goal state, and
174.1167 + inferences:%
174.1168 +\end{isamarkuptext}%
174.1169 +\isamarkuptrue%
174.1170 +%
174.1171 +\begingroup\footnotesize
174.1172 +%
174.1173 +\isadelimproof
174.1174 +%
174.1175 +\endisadelimproof
174.1176 +%
174.1177 +\isatagproof
174.1178 +%
174.1179 +\begin{minipage}[t]{0.18\textwidth}
174.1180 +\ \ \isacommand{have}\isamarkupfalse%
174.1181 +\ {\isachardoublequoteopen}A\ {\isasymlongrightarrow}\ B{\isachardoublequoteclose}\isanewline
174.1182 +\ \ \isacommand{proof}\isamarkupfalse%
174.1183 +\isanewline
174.1184 +\ \ \ \ \isacommand{assume}\isamarkupfalse%
174.1185 +\ A\isanewline
174.1186 +\ \ \ \ \isacommand{show}\isamarkupfalse%
174.1187 +\ B%
174.1188 +\endisatagproof
174.1189 +{\isafoldproof}%
174.1190 +%
174.1191 +\isadelimproof
174.1192 +\isanewline
174.1193 +%
174.1194 +\endisadelimproof
174.1195 +%
174.1196 +\isadelimnoproof
174.1197 +\ \ \ \ \ \ %
174.1198 +\endisadelimnoproof
174.1199 +%
174.1200 +\isatagnoproof
174.1201 +\isacommand{sorry}\isamarkupfalse%
174.1202 +%
174.1203 +\endisatagnoproof
174.1204 +{\isafoldnoproof}%
174.1205 +%
174.1206 +\isadelimnoproof
174.1207 +\isanewline
174.1208 +%
174.1209 +\endisadelimnoproof
174.1210 +%
174.1211 +\isadelimproof
174.1212 +\ \ %
174.1213 +\endisadelimproof
174.1214 +%
174.1215 +\isatagproof
174.1216 +\isacommand{qed}\isamarkupfalse%
174.1217 +%
174.1218 +\end{minipage}\quad
174.1219 +\begin{minipage}[t]{0.06\textwidth}
174.1220 +\isa{{\isachardoublequote}begin{\isachardoublequote}} \\
174.1221 +\\
174.1222 +\\
174.1223 +\isa{{\isachardoublequote}begin{\isachardoublequote}} \\
174.1224 +\isa{{\isachardoublequote}end{\isachardoublequote}} \\
174.1225 +\isa{{\isachardoublequote}end{\isachardoublequote}} \\
174.1226 +\end{minipage}
174.1227 +\begin{minipage}[t]{0.08\textwidth}
174.1228 +\isa{{\isachardoublequote}prove{\isachardoublequote}} \\
174.1229 +\isa{{\isachardoublequote}state{\isachardoublequote}} \\
174.1230 +\isa{{\isachardoublequote}state{\isachardoublequote}} \\
174.1231 +\isa{{\isachardoublequote}prove{\isachardoublequote}} \\
174.1232 +\isa{{\isachardoublequote}state{\isachardoublequote}} \\
174.1233 +\isa{{\isachardoublequote}state{\isachardoublequote}} \\
174.1234 +\end{minipage}\begin{minipage}[t]{0.35\textwidth}
174.1235 +\isa{{\isachardoublequote}{\isacharparenleft}A\ {\isasymlongrightarrow}\ B{\isacharparenright}\ {\isasymLongrightarrow}\ {\isacharhash}{\isacharparenleft}A\ {\isasymlongrightarrow}\ B{\isacharparenright}{\isachardoublequote}} \\
174.1236 +\isa{{\isachardoublequote}{\isacharparenleft}A\ {\isasymLongrightarrow}\ B{\isacharparenright}\ {\isasymLongrightarrow}\ {\isacharhash}{\isacharparenleft}A\ {\isasymlongrightarrow}\ B{\isacharparenright}{\isachardoublequote}} \\
174.1237 +\\
174.1238 +\\
174.1239 +\isa{{\isachardoublequote}{\isacharhash}{\isacharparenleft}A\ {\isasymlongrightarrow}\ B{\isacharparenright}{\isachardoublequote}} \\
174.1240 +\isa{{\isachardoublequote}A\ {\isasymlongrightarrow}\ B{\isachardoublequote}} \\
174.1241 +\end{minipage}\begin{minipage}[t]{0.4\textwidth}
174.1242 +\isa{{\isachardoublequote}{\isacharparenleft}init{\isacharparenright}{\isachardoublequote}} \\
174.1243 +\isa{{\isachardoublequote}{\isacharparenleft}resolution\ impI{\isacharparenright}{\isachardoublequote}} \\
174.1244 +\\
174.1245 +\\
174.1246 +\isa{{\isachardoublequote}{\isacharparenleft}refinement\ {\isacharhash}A\ {\isasymLongrightarrow}\ B{\isacharparenright}{\isachardoublequote}} \\
174.1247 +\isa{{\isachardoublequote}{\isacharparenleft}finish{\isacharparenright}{\isachardoublequote}} \\
174.1248 +\end{minipage}
174.1249 +%
174.1250 +\endisatagproof
174.1251 +{\isafoldproof}%
174.1252 +%
174.1253 +\isadelimproof
174.1254 +%
174.1255 +\endisadelimproof
174.1256 +%
174.1257 +\endgroup
174.1258 +%
174.1259 +\begin{isamarkuptext}%
174.1260 +\noindent Here the \hyperlink{inference.refinement}{\mbox{\isa{refinement}}} inference from
174.1261 + \secref{sec:framework-resolution} mediates composition of Isar
174.1262 + sub-proofs nicely. Observe that this principle incorporates some
174.1263 + degree of freedom in proof composition. In particular, the proof
174.1264 + body allows parameters and assumptions to be re-ordered, or commuted
174.1265 + according to Hereditary Harrop Form. Moreover, context elements
174.1266 + that are not used in a sub-proof may be omitted altogether. For
174.1267 + example:%
174.1268 +\end{isamarkuptext}%
174.1269 +\isamarkuptrue%
174.1270 +%
174.1271 +\begin{minipage}{0.5\textwidth}
174.1272 +%
174.1273 +\isadelimproof
174.1274 +%
174.1275 +\endisadelimproof
174.1276 +%
174.1277 +\isatagproof
174.1278 +\ \ \isacommand{have}\isamarkupfalse%
174.1279 +\ {\isachardoublequoteopen}{\isasymAnd}x\ y{\isachardot}\ A\ x\ {\isasymLongrightarrow}\ B\ y\ {\isasymLongrightarrow}\ C\ x\ y{\isachardoublequoteclose}\isanewline
174.1280 +\ \ \isacommand{proof}\isamarkupfalse%
174.1281 +\ {\isacharminus}\isanewline
174.1282 +\ \ \ \ \isacommand{fix}\isamarkupfalse%
174.1283 +\ x\ \isakeyword{and}\ y\isanewline
174.1284 +\ \ \ \ \isacommand{assume}\isamarkupfalse%
174.1285 +\ {\isachardoublequoteopen}A\ x{\isachardoublequoteclose}\ \isakeyword{and}\ {\isachardoublequoteopen}B\ y{\isachardoublequoteclose}\isanewline
174.1286 +\ \ \ \ \isacommand{show}\isamarkupfalse%
174.1287 +\ {\isachardoublequoteopen}C\ x\ y{\isachardoublequoteclose}%
174.1288 +\endisatagproof
174.1289 +{\isafoldproof}%
174.1290 +%
174.1291 +\isadelimproof
174.1292 +%
174.1293 +\endisadelimproof
174.1294 +%
174.1295 +\isadelimnoproof
174.1296 +\ %
174.1297 +\endisadelimnoproof
174.1298 +%
174.1299 +\isatagnoproof
174.1300 +\isacommand{sorry}\isamarkupfalse%
174.1301 +%
174.1302 +\endisatagnoproof
174.1303 +{\isafoldnoproof}%
174.1304 +%
174.1305 +\isadelimnoproof
174.1306 +\isanewline
174.1307 +%
174.1308 +\endisadelimnoproof
174.1309 +%
174.1310 +\isadelimproof
174.1311 +\ \ %
174.1312 +\endisadelimproof
174.1313 +%
174.1314 +\isatagproof
174.1315 +\isacommand{qed}\isamarkupfalse%
174.1316 +%
174.1317 +\end{minipage}\begin{minipage}{0.5\textwidth}
174.1318 +\ \ \isacommand{have}\isamarkupfalse%
174.1319 +\ {\isachardoublequoteopen}{\isasymAnd}x\ y{\isachardot}\ A\ x\ {\isasymLongrightarrow}\ B\ y\ {\isasymLongrightarrow}\ C\ x\ y{\isachardoublequoteclose}\isanewline
174.1320 +\ \ \isacommand{proof}\isamarkupfalse%
174.1321 +\ {\isacharminus}\isanewline
174.1322 +\ \ \ \ \isacommand{fix}\isamarkupfalse%
174.1323 +\ x\ \isacommand{assume}\isamarkupfalse%
174.1324 +\ {\isachardoublequoteopen}A\ x{\isachardoublequoteclose}\isanewline
174.1325 +\ \ \ \ \isacommand{fix}\isamarkupfalse%
174.1326 +\ y\ \isacommand{assume}\isamarkupfalse%
174.1327 +\ {\isachardoublequoteopen}B\ y{\isachardoublequoteclose}\isanewline
174.1328 +\ \ \ \ \isacommand{show}\isamarkupfalse%
174.1329 +\ {\isachardoublequoteopen}C\ x\ y{\isachardoublequoteclose}%
174.1330 +\endisatagproof
174.1331 +{\isafoldproof}%
174.1332 +%
174.1333 +\isadelimproof
174.1334 +%
174.1335 +\endisadelimproof
174.1336 +%
174.1337 +\isadelimnoproof
174.1338 +\ %
174.1339 +\endisadelimnoproof
174.1340 +%
174.1341 +\isatagnoproof
174.1342 +\isacommand{sorry}\isamarkupfalse%
174.1343 +%
174.1344 +\endisatagnoproof
174.1345 +{\isafoldnoproof}%
174.1346 +%
174.1347 +\isadelimnoproof
174.1348 +\isanewline
174.1349 +%
174.1350 +\endisadelimnoproof
174.1351 +%
174.1352 +\isadelimproof
174.1353 +\ \ %
174.1354 +\endisadelimproof
174.1355 +%
174.1356 +\isatagproof
174.1357 +\isacommand{qed}\isamarkupfalse%
174.1358 +%
174.1359 +\end{minipage}\\[3ex]\begin{minipage}{0.5\textwidth}
174.1360 +\ \ \isacommand{have}\isamarkupfalse%
174.1361 +\ {\isachardoublequoteopen}{\isasymAnd}x\ y{\isachardot}\ A\ x\ {\isasymLongrightarrow}\ B\ y\ {\isasymLongrightarrow}\ C\ x\ y{\isachardoublequoteclose}\isanewline
174.1362 +\ \ \isacommand{proof}\isamarkupfalse%
174.1363 +\ {\isacharminus}\isanewline
174.1364 +\ \ \ \ \isacommand{fix}\isamarkupfalse%
174.1365 +\ y\ \isacommand{assume}\isamarkupfalse%
174.1366 +\ {\isachardoublequoteopen}B\ y{\isachardoublequoteclose}\isanewline
174.1367 +\ \ \ \ \isacommand{fix}\isamarkupfalse%
174.1368 +\ x\ \isacommand{assume}\isamarkupfalse%
174.1369 +\ {\isachardoublequoteopen}A\ x{\isachardoublequoteclose}\isanewline
174.1370 +\ \ \ \ \isacommand{show}\isamarkupfalse%
174.1371 +\ {\isachardoublequoteopen}C\ x\ y{\isachardoublequoteclose}\ \isacommand{sorry}\isamarkupfalse%
174.1372 +\isanewline
174.1373 +\ \ \isacommand{qed}\isamarkupfalse%
174.1374 +%
174.1375 +\end{minipage}\begin{minipage}{0.5\textwidth}
174.1376 +\ \ \isacommand{have}\isamarkupfalse%
174.1377 +\ {\isachardoublequoteopen}{\isasymAnd}x\ y{\isachardot}\ A\ x\ {\isasymLongrightarrow}\ B\ y\ {\isasymLongrightarrow}\ C\ x\ y{\isachardoublequoteclose}\isanewline
174.1378 +\ \ \isacommand{proof}\isamarkupfalse%
174.1379 +\ {\isacharminus}\isanewline
174.1380 +\ \ \ \ \isacommand{fix}\isamarkupfalse%
174.1381 +\ y\ \isacommand{assume}\isamarkupfalse%
174.1382 +\ {\isachardoublequoteopen}B\ y{\isachardoublequoteclose}\isanewline
174.1383 +\ \ \ \ \isacommand{fix}\isamarkupfalse%
174.1384 +\ x\isanewline
174.1385 +\ \ \ \ \isacommand{show}\isamarkupfalse%
174.1386 +\ {\isachardoublequoteopen}C\ x\ y{\isachardoublequoteclose}\ \isacommand{sorry}\isamarkupfalse%
174.1387 +\isanewline
174.1388 +\ \ \isacommand{qed}\isamarkupfalse%
174.1389 +%
174.1390 +\endisatagproof
174.1391 +{\isafoldproof}%
174.1392 +%
174.1393 +\isadelimproof
174.1394 +%
174.1395 +\endisadelimproof
174.1396 +%
174.1397 +\end{minipage}
174.1398 +%
174.1399 +\begin{isamarkuptext}%
174.1400 +\medskip\noindent Such ``peephole optimizations'' of Isar texts are
174.1401 + practically important to improve readability, by rearranging
174.1402 + contexts elements according to the natural flow of reasoning in the
174.1403 + body, while still observing the overall scoping rules.
174.1404 +
174.1405 + \medskip This illustrates the basic idea of structured proof
174.1406 + processing in Isar. The main mechanisms are based on natural
174.1407 + deduction rule composition within the Pure framework. In
174.1408 + particular, there are no direct operations on goal states within the
174.1409 + proof body. Moreover, there is no hidden automated reasoning
174.1410 + involved, just plain unification.%
174.1411 +\end{isamarkuptext}%
174.1412 +\isamarkuptrue%
174.1413 +%
174.1414 +\isamarkupsubsection{Calculational reasoning \label{sec:framework-calc}%
174.1415 +}
174.1416 +\isamarkuptrue%
174.1417 +%
174.1418 +\begin{isamarkuptext}%
174.1419 +The existing Isar infrastructure is sufficiently flexible to support
174.1420 + calculational reasoning (chains of transitivity steps) as derived
174.1421 + concept. The generic proof elements introduced below depend on
174.1422 + rules declared as \hyperlink{attribute.trans}{\mbox{\isa{trans}}} in the context. It is left to
174.1423 + the object-logic to provide a suitable rule collection for mixed
174.1424 + relations of \isa{{\isachardoublequote}{\isacharequal}{\isachardoublequote}}, \isa{{\isachardoublequote}{\isacharless}{\isachardoublequote}}, \isa{{\isachardoublequote}{\isasymle}{\isachardoublequote}}, \isa{{\isachardoublequote}{\isasymsubset}{\isachardoublequote}},
174.1425 + \isa{{\isachardoublequote}{\isasymsubseteq}{\isachardoublequote}} etc. Due to the flexibility of rule composition
174.1426 + (\secref{sec:framework-resolution}), substitution of equals by
174.1427 + equals is covered as well, even substitution of inequalities
174.1428 + involving monotonicity conditions; see also \cite[\S6]{Wenzel-PhD}
174.1429 + and \cite{Bauer-Wenzel:2001}.
174.1430 +
174.1431 + The generic calculational mechanism is based on the observation that
174.1432 + rules such as \isa{{\isachardoublequote}trans{\isacharcolon}{\isachardoublequote}}~\isa{{\isachardoublequote}x\ {\isacharequal}\ y\ {\isasymLongrightarrow}\ y\ {\isacharequal}\ z\ {\isasymLongrightarrow}\ x\ {\isacharequal}\ z{\isachardoublequote}}
174.1433 + proceed from the premises towards the conclusion in a deterministic
174.1434 + fashion. Thus we may reason in forward mode, feeding intermediate
174.1435 + results into rules selected from the context. The course of
174.1436 + reasoning is organized by maintaining a secondary fact called
174.1437 + ``\hyperlink{fact.calculation}{\mbox{\isa{calculation}}}'', apart from the primary ``\hyperlink{fact.this}{\mbox{\isa{this}}}''
174.1438 + already provided by the Isar primitives. In the definitions below,
174.1439 + \hyperlink{attribute.OF}{\mbox{\isa{OF}}} refers to \hyperlink{inference.resolution}{\mbox{\isa{resolution}}}
174.1440 + (\secref{sec:framework-resolution}) with multiple rule arguments,
174.1441 + and \isa{{\isachardoublequote}trans{\isachardoublequote}} represents to a suitable rule from the context:
174.1442 +
174.1443 + \begin{matharray}{rcl}
174.1444 + \hyperlink{command.also}{\mbox{\isa{\isacommand{also}}}}\isa{{\isachardoublequote}\isactrlsub {\isadigit{0}}{\isachardoublequote}} & \equiv & \hyperlink{command.note}{\mbox{\isa{\isacommand{note}}}}~\isa{{\isachardoublequote}calculation\ {\isacharequal}\ this{\isachardoublequote}} \\
174.1445 + \hyperlink{command.also}{\mbox{\isa{\isacommand{also}}}}\isa{{\isachardoublequote}\isactrlsub n\isactrlsub {\isacharplus}\isactrlsub {\isadigit{1}}{\isachardoublequote}} & \equiv & \hyperlink{command.note}{\mbox{\isa{\isacommand{note}}}}~\isa{{\isachardoublequote}calculation\ {\isacharequal}\ trans\ {\isacharbrackleft}OF\ calculation\ this{\isacharbrackright}{\isachardoublequote}} \\[0.5ex]
174.1446 + \hyperlink{command.finally}{\mbox{\isa{\isacommand{finally}}}} & \equiv & \hyperlink{command.also}{\mbox{\isa{\isacommand{also}}}}~\hyperlink{command.from}{\mbox{\isa{\isacommand{from}}}}~\isa{calculation} \\
174.1447 + \end{matharray}
174.1448 +
174.1449 + \noindent The start of a calculation is determined implicitly in the
174.1450 + text: here \hyperlink{command.also}{\mbox{\isa{\isacommand{also}}}} sets \hyperlink{fact.calculation}{\mbox{\isa{calculation}}} to the current
174.1451 + result; any subsequent occurrence will update \hyperlink{fact.calculation}{\mbox{\isa{calculation}}} by
174.1452 + combination with the next result and a transitivity rule. The
174.1453 + calculational sequence is concluded via \hyperlink{command.finally}{\mbox{\isa{\isacommand{finally}}}}, where
174.1454 + the final result is exposed for use in a concluding claim.
174.1455 +
174.1456 + Here is a canonical proof pattern, using \hyperlink{command.have}{\mbox{\isa{\isacommand{have}}}} to
174.1457 + establish the intermediate results:%
174.1458 +\end{isamarkuptext}%
174.1459 +\isamarkuptrue%
174.1460 +%
174.1461 +\isadelimproof
174.1462 +%
174.1463 +\endisadelimproof
174.1464 +%
174.1465 +\isatagproof
174.1466 +\ \ \isacommand{have}\isamarkupfalse%
174.1467 +\ {\isachardoublequoteopen}a\ {\isacharequal}\ b{\isachardoublequoteclose}\ \isacommand{sorry}\isamarkupfalse%
174.1468 +\isanewline
174.1469 +\ \ \isacommand{also}\isamarkupfalse%
174.1470 +\ \isacommand{have}\isamarkupfalse%
174.1471 +\ {\isachardoublequoteopen}{\isasymdots}\ {\isacharequal}\ c{\isachardoublequoteclose}\ \isacommand{sorry}\isamarkupfalse%
174.1472 +\isanewline
174.1473 +\ \ \isacommand{also}\isamarkupfalse%
174.1474 +\ \isacommand{have}\isamarkupfalse%
174.1475 +\ {\isachardoublequoteopen}{\isasymdots}\ {\isacharequal}\ d{\isachardoublequoteclose}\ \isacommand{sorry}\isamarkupfalse%
174.1476 +\isanewline
174.1477 +\ \ \isacommand{finally}\isamarkupfalse%
174.1478 +\ \isacommand{have}\isamarkupfalse%
174.1479 +\ {\isachardoublequoteopen}a\ {\isacharequal}\ d{\isachardoublequoteclose}\ \isacommand{{\isachardot}}\isamarkupfalse%
174.1480 +%
174.1481 +\endisatagproof
174.1482 +{\isafoldproof}%
174.1483 +%
174.1484 +\isadelimproof
174.1485 +%
174.1486 +\endisadelimproof
174.1487 +%
174.1488 +\begin{isamarkuptext}%
174.1489 +\noindent The term ``\isa{{\isachardoublequote}{\isasymdots}{\isachardoublequote}}'' above is a special abbreviation
174.1490 + provided by the Isabelle/Isar syntax layer: it statically refers to
174.1491 + the right-hand side argument of the previous statement given in the
174.1492 + text. Thus it happens to coincide with relevant sub-expressions in
174.1493 + the calculational chain, but the exact correspondence is dependent
174.1494 + on the transitivity rules being involved.
174.1495 +
174.1496 + \medskip Symmetry rules such as \isa{{\isachardoublequote}x\ {\isacharequal}\ y\ {\isasymLongrightarrow}\ y\ {\isacharequal}\ x{\isachardoublequote}} are like
174.1497 + transitivities with only one premise. Isar maintains a separate
174.1498 + rule collection declared via the \hyperlink{attribute.sym}{\mbox{\isa{sym}}} attribute, to be
174.1499 + used in fact expressions ``\isa{{\isachardoublequote}a\ {\isacharbrackleft}symmetric{\isacharbrackright}{\isachardoublequote}}'', or single-step
174.1500 + proofs ``\hyperlink{command.assume}{\mbox{\isa{\isacommand{assume}}}}~\isa{{\isachardoublequote}x\ {\isacharequal}\ y{\isachardoublequote}}~\hyperlink{command.then}{\mbox{\isa{\isacommand{then}}}}~\hyperlink{command.have}{\mbox{\isa{\isacommand{have}}}}~\isa{{\isachardoublequote}y\ {\isacharequal}\ x{\isachardoublequote}}~\hyperlink{command.ddot}{\mbox{\isa{\isacommand{{\isachardot}{\isachardot}}}}}''.%
174.1501 +\end{isamarkuptext}%
174.1502 +\isamarkuptrue%
174.1503 +%
174.1504 +\isadelimtheory
174.1505 +%
174.1506 +\endisadelimtheory
174.1507 +%
174.1508 +\isatagtheory
174.1509 +\isacommand{end}\isamarkupfalse%
174.1510 +%
174.1511 +\endisatagtheory
174.1512 +{\isafoldtheory}%
174.1513 +%
174.1514 +\isadelimtheory
174.1515 +%
174.1516 +\endisadelimtheory
174.1517 +\end{isabellebody}%
174.1518 +%%% Local Variables:
174.1519 +%%% mode: latex
174.1520 +%%% TeX-master: "root"
174.1521 +%%% End:
175.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
175.2 +++ b/doc-src/IsarRef/Thy/document/isar-vm.eps Wed Mar 04 11:05:29 2009 +0100
175.3 @@ -0,0 +1,2694 @@
175.4 +%!PS-Adobe-3.0 EPSF-3.0
175.5 +%%Creator: inkscape 0.46
175.6 +%%Pages: 1
175.7 +%%Orientation: Portrait
175.8 +%%BoundingBox: 0 0 435 173
175.9 +%%HiResBoundingBox: 0 0 435 173
175.10 +%%EndComments
175.11 +%%BeginSetup
175.12 +%%EndSetup
175.13 +%%Page: 1 1
175.14 +0 173 translate
175.15 +0.8 -0.8 scale
175.16 +0 0 0 setrgbcolor
175.17 +[] 0 setdash
175.18 +1 setlinewidth
175.19 +0 setlinejoin
175.20 +0 setlinecap
175.21 +gsave [1 0 0 1 0 0] concat
175.22 +gsave [1 0 0 1 -44.641342 -76.87234] concat
175.23 +gsave [1 0 0 1 70.838012 79.725562] concat
175.24 +0 0 0 setrgbcolor
175.25 +[] 0 setdash
175.26 +0.99921262 setlinewidth
175.27 +1 setlinejoin
175.28 +1 setlinecap
175.29 +newpath
175.30 +229.77649 131.52507 moveto
175.31 +265.28729 131.52507 lineto
175.32 +275.08072 131.52507 282.96496 139.40931 282.96496 149.20274 curveto
175.33 +282.96496 166.99701 lineto
175.34 +282.96496 176.79043 275.08072 184.67467 265.28729 184.67467 curveto
175.35 +229.77649 184.67467 lineto
175.36 +219.98306 184.67467 212.09882 176.79043 212.09882 166.99701 curveto
175.37 +212.09882 149.20274 lineto
175.38 +212.09882 139.40931 219.98306 131.52507 229.77649 131.52507 curveto
175.39 +closepath
175.40 +stroke
175.41 +gsave
175.42 +0 0 0 setrgbcolor
175.43 +newpath
175.44 +231.92252 155.58815 moveto
175.45 +231.92252 157.8694 lineto
175.46 +231.5423 157.60899 231.15949 157.41628 230.77408 157.29128 curveto
175.47 +230.39386 157.16628 229.99803 157.10378 229.58658 157.10378 curveto
175.48 +228.80532 157.10378 228.19595 157.33295 227.75845 157.79128 curveto
175.49 +227.32616 158.24441 227.11001 158.87982 227.11002 159.69753 curveto
175.50 +227.11001 160.51524 227.32616 161.15326 227.75845 161.61159 curveto
175.51 +228.19595 162.06471 228.80532 162.29128 229.58658 162.29128 curveto
175.52 +230.02407 162.29128 230.43813 162.22617 230.82877 162.09596 curveto
175.53 +231.22459 161.96576 231.58917 161.77305 231.92252 161.51784 curveto
175.54 +231.92252 163.8069 lineto
175.55 +231.48501 163.96836 231.0397 164.08815 230.58658 164.16628 curveto
175.56 +230.13866 164.24961 229.68813 164.29127 229.23502 164.29128 curveto
175.57 +227.65689 164.29127 226.42251 163.88763 225.53189 163.08034 curveto
175.58 +224.64126 162.26784 224.19595 161.14024 224.19595 159.69753 curveto
175.59 +224.19595 158.25482 224.64126 157.12982 225.53189 156.32253 curveto
175.60 +226.42251 155.51003 227.65689 155.10378 229.23502 155.10378 curveto
175.61 +229.69334 155.10378 230.14386 155.14545 230.58658 155.22878 curveto
175.62 +231.03449 155.30691 231.4798 155.4267 231.92252 155.58815 curveto
175.63 +fill
175.64 +grestore
175.65 +gsave
175.66 +0 0 0 setrgbcolor
175.67 +newpath
175.68 +243.14908 158.73659 moveto
175.69 +243.14908 164.06471 lineto
175.70 +240.33658 164.06471 lineto
175.71 +240.33658 163.19753 lineto
175.72 +240.33658 160.00221 lineto
175.73 +240.33657 159.23659 240.31834 158.71055 240.28189 158.42409 curveto
175.74 +240.25063 158.13764 240.19334 157.9267 240.11002 157.79128 curveto
175.75 +240.00063 157.60899 239.8522 157.46836 239.6647 157.3694 curveto
175.76 +239.4772 157.26524 239.26366 157.21316 239.02408 157.21315 curveto
175.77 +238.44074 157.21316 237.98241 157.43972 237.64908 157.89284 curveto
175.78 +237.31574 158.34076 237.14907 158.96316 237.14908 159.76003 curveto
175.79 +237.14908 164.06471 lineto
175.80 +234.3522 164.06471 lineto
175.81 +234.3522 151.90846 lineto
175.82 +237.14908 151.90846 lineto
175.83 +237.14908 156.59596 lineto
175.84 +237.57095 156.08555 238.01887 155.71055 238.49283 155.47096 curveto
175.85 +238.96678 155.22618 239.49022 155.10378 240.06314 155.10378 curveto
175.86 +241.07355 155.10378 241.83917 155.41368 242.36002 156.03346 curveto
175.87 +242.88605 156.65326 243.14907 157.5543 243.14908 158.73659 curveto
175.88 +fill
175.89 +grestore
175.90 +gsave
175.91 +0 0 0 setrgbcolor
175.92 +newpath
175.93 +249.68033 160.12721 moveto
175.94 +249.09699 160.12722 248.65689 160.22617 248.36002 160.42409 curveto
175.95 +248.06835 160.62201 247.92251 160.91367 247.92252 161.29909 curveto
175.96 +247.92251 161.65326 248.0397 161.9319 248.27408 162.13503 curveto
175.97 +248.51366 162.33294 248.84439 162.4319 249.26627 162.4319 curveto
175.98 +249.7923 162.4319 250.23501 162.2444 250.59439 161.8694 curveto
175.99 +250.95376 161.48919 251.13345 161.01524 251.13345 160.44753 curveto
175.100 +251.13345 160.12721 lineto
175.101 +249.68033 160.12721 lineto
175.102 +253.95377 159.07253 moveto
175.103 +253.95377 164.06471 lineto
175.104 +251.13345 164.06471 lineto
175.105 +251.13345 162.76784 lineto
175.106 +250.75845 163.29909 250.33657 163.68711 249.86783 163.9319 curveto
175.107 +249.39907 164.17148 248.82876 164.29127 248.15689 164.29128 curveto
175.108 +247.25064 164.29127 246.51366 164.02825 245.94595 163.50221 curveto
175.109 +245.38345 162.97096 245.1022 162.28346 245.1022 161.43971 curveto
175.110 +245.1022 160.41367 245.45376 159.66107 246.15689 159.1819 curveto
175.111 +246.86522 158.70274 247.9746 158.46316 249.48502 158.46315 curveto
175.112 +251.13345 158.46315 lineto
175.113 +251.13345 158.2444 lineto
175.114 +251.13345 157.8017 250.95897 157.47878 250.61002 157.27565 curveto
175.115 +250.26105 157.06732 249.71678 156.96316 248.9772 156.96315 curveto
175.116 +248.37824 156.96316 247.82095 157.02305 247.30533 157.14284 curveto
175.117 +246.7897 157.26264 246.31053 157.44232 245.86783 157.6819 curveto
175.118 +245.86783 155.54909 lineto
175.119 +246.46678 155.40326 247.06835 155.29389 247.67252 155.22096 curveto
175.120 +248.27668 155.14285 248.88084 155.10378 249.48502 155.10378 curveto
175.121 +251.06313 155.10378 252.20115 155.41628 252.89908 156.04128 curveto
175.122 +253.60219 156.66107 253.95376 157.67149 253.95377 159.07253 curveto
175.123 +fill
175.124 +grestore
175.125 +gsave
175.126 +0 0 0 setrgbcolor
175.127 +newpath
175.128 +256.57095 155.31471 moveto
175.129 +259.36783 155.31471 lineto
175.130 +259.36783 164.06471 lineto
175.131 +256.57095 164.06471 lineto
175.132 +256.57095 155.31471 lineto
175.133 +256.57095 151.90846 moveto
175.134 +259.36783 151.90846 lineto
175.135 +259.36783 154.18971 lineto
175.136 +256.57095 154.18971 lineto
175.137 +256.57095 151.90846 lineto
175.138 +fill
175.139 +grestore
175.140 +gsave
175.141 +0 0 0 setrgbcolor
175.142 +newpath
175.143 +270.86783 158.73659 moveto
175.144 +270.86783 164.06471 lineto
175.145 +268.05533 164.06471 lineto
175.146 +268.05533 163.19753 lineto
175.147 +268.05533 159.98659 lineto
175.148 +268.05532 159.23138 268.03709 158.71055 268.00064 158.42409 curveto
175.149 +267.96938 158.13764 267.91209 157.9267 267.82877 157.79128 curveto
175.150 +267.71938 157.60899 267.57095 157.46836 267.38345 157.3694 curveto
175.151 +267.19595 157.26524 266.98241 157.21316 266.74283 157.21315 curveto
175.152 +266.15949 157.21316 265.70116 157.43972 265.36783 157.89284 curveto
175.153 +265.03449 158.34076 264.86782 158.96316 264.86783 159.76003 curveto
175.154 +264.86783 164.06471 lineto
175.155 +262.07095 164.06471 lineto
175.156 +262.07095 155.31471 lineto
175.157 +264.86783 155.31471 lineto
175.158 +264.86783 156.59596 lineto
175.159 +265.2897 156.08555 265.73762 155.71055 266.21158 155.47096 curveto
175.160 +266.68553 155.22618 267.20897 155.10378 267.78189 155.10378 curveto
175.161 +268.7923 155.10378 269.55792 155.41368 270.07877 156.03346 curveto
175.162 +270.6048 156.65326 270.86782 157.5543 270.86783 158.73659 curveto
175.163 +fill
175.164 +grestore
175.165 +grestore
175.166 +0 0 0 setrgbcolor
175.167 +[] 0 setdash
175.168 +0.99921262 setlinewidth
175.169 +0 setlinejoin
175.170 +0 setlinecap
175.171 +newpath
175.172 +424.72469 236.82544 moveto
175.173 +356.83209 236.82544 lineto
175.174 +356.83209 236.82544 lineto
175.175 +stroke
175.176 +gsave [-0.39968505 4.8945685e-17 -4.8945685e-17 -0.39968505 356.83209 236.82544] concat
175.177 +gsave
175.178 +0 0 0 setrgbcolor
175.179 +newpath
175.180 +5.77 0 moveto
175.181 +-2.88 5 lineto
175.182 +-2.88 -5 lineto
175.183 +5.77 0 lineto
175.184 +closepath
175.185 +eofill
175.186 +grestore
175.187 +0 0 0 setrgbcolor
175.188 +[] 0 setdash
175.189 +1.25 setlinewidth
175.190 +0 setlinejoin
175.191 +0 setlinecap
175.192 +newpath
175.193 +5.77 0 moveto
175.194 +-2.88 5 lineto
175.195 +-2.88 -5 lineto
175.196 +5.77 0 lineto
175.197 +closepath
175.198 +stroke
175.199 +grestore
175.200 +0 0 0 setrgbcolor
175.201 +[] 0 setdash
175.202 +0.99921268 setlinewidth
175.203 +0 setlinejoin
175.204 +0 setlinecap
175.205 +newpath
175.206 +282.35183 236.82544 moveto
175.207 +215.11403 236.82544 lineto
175.208 +215.11403 236.82544 lineto
175.209 +stroke
175.210 +gsave [-0.39968507 4.8945688e-17 -4.8945688e-17 -0.39968507 215.11403 236.82544] concat
175.211 +gsave
175.212 +0 0 0 setrgbcolor
175.213 +newpath
175.214 +5.77 0 moveto
175.215 +-2.88 5 lineto
175.216 +-2.88 -5 lineto
175.217 +5.77 0 lineto
175.218 +closepath
175.219 +eofill
175.220 +grestore
175.221 +0 0 0 setrgbcolor
175.222 +[] 0 setdash
175.223 +1.25 setlinewidth
175.224 +0 setlinejoin
175.225 +0 setlinecap
175.226 +newpath
175.227 +5.77 0 moveto
175.228 +-2.88 5 lineto
175.229 +-2.88 -5 lineto
175.230 +5.77 0 lineto
175.231 +closepath
175.232 +stroke
175.233 +grestore
175.234 +0 0 0 setrgbcolor
175.235 +[] 0 setdash
175.236 +0.99999994 setlinewidth
175.237 +0 setlinejoin
175.238 +0 setlinecap
175.239 +newpath
175.240 +424.69726 192.5341 moveto
175.241 +215.13005 192.5341 lineto
175.242 +stroke
175.243 +gsave [-0.39999998 4.8984251e-17 -4.8984251e-17 -0.39999998 215.13005 192.5341] concat
175.244 +gsave
175.245 +0 0 0 setrgbcolor
175.246 +newpath
175.247 +5.77 0 moveto
175.248 +-2.88 5 lineto
175.249 +-2.88 -5 lineto
175.250 +5.77 0 lineto
175.251 +closepath
175.252 +eofill
175.253 +grestore
175.254 +0 0 0 setrgbcolor
175.255 +[] 0 setdash
175.256 +1.25 setlinewidth
175.257 +0 setlinejoin
175.258 +0 setlinecap
175.259 +newpath
175.260 +5.77 0 moveto
175.261 +-2.88 5 lineto
175.262 +-2.88 -5 lineto
175.263 +5.77 0 lineto
175.264 +closepath
175.265 +stroke
175.266 +grestore
175.267 +0 0 0 setrgbcolor
175.268 +[] 0 setdash
175.269 +1 setlinewidth
175.270 +0 setlinejoin
175.271 +0 setlinecap
175.272 +newpath
175.273 +211.98429 148.24276 moveto
175.274 +422.13162 148.24276 lineto
175.275 +stroke
175.276 +gsave [0.4 0 0 0.4 422.13162 148.24276] concat
175.277 +gsave
175.278 +0 0 0 setrgbcolor
175.279 +newpath
175.280 +5.77 0 moveto
175.281 +-2.88 5 lineto
175.282 +-2.88 -5 lineto
175.283 +5.77 0 lineto
175.284 +closepath
175.285 +eofill
175.286 +grestore
175.287 +0 0 0 setrgbcolor
175.288 +[] 0 setdash
175.289 +1.25 setlinewidth
175.290 +0 setlinejoin
175.291 +0 setlinecap
175.292 +newpath
175.293 +5.77 0 moveto
175.294 +-2.88 5 lineto
175.295 +-2.88 -5 lineto
175.296 +5.77 0 lineto
175.297 +closepath
175.298 +stroke
175.299 +grestore
175.300 +gsave [1 0 0 1 70.866146 78.725567] concat
175.301 +0 0 0 setrgbcolor
175.302 +[] 0 setdash
175.303 +0.99921262 setlinewidth
175.304 +1 setlinejoin
175.305 +1 setlinecap
175.306 +newpath
175.307 +88.044201 42.942394 moveto
175.308 +123.555 42.942394 lineto
175.309 +133.34843 42.942394 141.23267 50.826635 141.23267 60.620064 curveto
175.310 +141.23267 166.99701 lineto
175.311 +141.23267 176.79044 133.34843 184.67468 123.555 184.67468 curveto
175.312 +88.044201 184.67468 lineto
175.313 +78.250772 184.67468 70.366531 176.79044 70.366531 166.99701 curveto
175.314 +70.366531 60.620064 lineto
175.315 +70.366531 50.826635 78.250772 42.942394 88.044201 42.942394 curveto
175.316 +closepath
175.317 +stroke
175.318 +gsave
175.319 +0 0 0 setrgbcolor
175.320 +newpath
175.321 +83.823044 115.35931 moveto
175.322 +83.823044 119.95306 lineto
175.323 +81.026169 119.95306 lineto
175.324 +81.026169 107.87494 lineto
175.325 +83.823044 107.87494 lineto
175.326 +83.823044 109.15619 lineto
175.327 +84.208456 108.64578 84.635539 108.27078 85.104294 108.03119 curveto
175.328 +85.573038 107.78641 86.1121 107.66401 86.721481 107.664 curveto
175.329 +87.799598 107.66401 88.685014 108.0937 89.377731 108.95306 curveto
175.330 +90.070429 109.80724 90.416783 110.9088 90.416794 112.25775 curveto
175.331 +90.416783 113.60671 90.070429 114.71088 89.377731 115.57025 curveto
175.332 +88.685014 116.42442 87.799598 116.8515 86.721481 116.8515 curveto
175.333 +86.1121 116.8515 85.573038 116.73171 85.104294 116.49213 curveto
175.334 +84.635539 116.24734 84.208456 115.86973 83.823044 115.35931 curveto
175.335 +85.682419 109.69525 moveto
175.336 +85.083455 109.69526 84.622518 109.91661 84.299606 110.35931 curveto
175.337 +83.981894 110.79682 83.82304 111.42963 83.823044 112.25775 curveto
175.338 +83.82304 113.08588 83.981894 113.7213 84.299606 114.164 curveto
175.339 +84.622518 114.6015 85.083455 114.82025 85.682419 114.82025 curveto
175.340 +86.281371 114.82025 86.737099 114.6015 87.049606 114.164 curveto
175.341 +87.367307 113.7265 87.526161 113.09109 87.526169 112.25775 curveto
175.342 +87.526161 111.42442 87.367307 110.78901 87.049606 110.3515 curveto
175.343 +86.737099 109.91401 86.281371 109.69526 85.682419 109.69525 curveto
175.344 +fill
175.345 +grestore
175.346 +gsave
175.347 +0 0 0 setrgbcolor
175.348 +newpath
175.349 +98.994919 110.25775 moveto
175.350 +98.75012 110.14317 98.505328 110.05984 98.260544 110.00775 curveto
175.351 +98.020954 109.95047 97.778766 109.92182 97.533981 109.92181 curveto
175.352 +96.815226 109.92182 96.260539 110.15359 95.869919 110.61713 curveto
175.353 +95.484498 111.07547 95.29179 111.73432 95.291794 112.59369 curveto
175.354 +95.291794 116.62494 lineto
175.355 +92.494919 116.62494 lineto
175.356 +92.494919 107.87494 lineto
175.357 +95.291794 107.87494 lineto
175.358 +95.291794 109.31244 lineto
175.359 +95.651164 108.73953 96.062622 108.32286 96.526169 108.06244 curveto
175.360 +96.994913 107.79682 97.554808 107.66401 98.205856 107.664 curveto
175.361 +98.299599 107.66401 98.401162 107.66922 98.510544 107.67963 curveto
175.362 +98.619911 107.68484 98.778765 107.70047 98.987106 107.7265 curveto
175.363 +98.994919 110.25775 lineto
175.364 +fill
175.365 +grestore
175.366 +gsave
175.367 +0 0 0 setrgbcolor
175.368 +newpath
175.369 +104.56523 109.664 moveto
175.370 +103.94543 109.66401 103.47148 109.88797 103.14336 110.33588 curveto
175.371 +102.82044 110.77859 102.65898 111.41922 102.65898 112.25775 curveto
175.372 +102.65898 113.0963 102.82044 113.73953 103.14336 114.18744 curveto
175.373 +103.47148 114.63015 103.94543 114.8515 104.56523 114.8515 curveto
175.374 +105.1746 114.8515 105.64075 114.63015 105.96367 114.18744 curveto
175.375 +106.28658 113.73953 106.44804 113.0963 106.44804 112.25775 curveto
175.376 +106.44804 111.41922 106.28658 110.77859 105.96367 110.33588 curveto
175.377 +105.64075 109.88797 105.1746 109.66401 104.56523 109.664 curveto
175.378 +104.56523 107.664 moveto
175.379 +106.07043 107.66401 107.24491 108.07026 108.08867 108.88275 curveto
175.380 +108.93762 109.69526 109.3621 110.82026 109.36211 112.25775 curveto
175.381 +109.3621 113.69525 108.93762 114.82025 108.08867 115.63275 curveto
175.382 +107.24491 116.44525 106.07043 116.8515 104.56523 116.8515 curveto
175.383 +103.05481 116.8515 101.87252 116.44525 101.01836 115.63275 curveto
175.384 +100.1694 114.82025 99.744918 113.69525 99.744919 112.25775 curveto
175.385 +99.744918 110.82026 100.1694 109.69526 101.01836 108.88275 curveto
175.386 +101.87252 108.07026 103.05481 107.66401 104.56523 107.664 curveto
175.387 +fill
175.388 +grestore
175.389 +gsave
175.390 +0 0 0 setrgbcolor
175.391 +newpath
175.392 +110.29961 107.87494 moveto
175.393 +113.09648 107.87494 lineto
175.394 +115.27617 113.92181 lineto
175.395 +117.44804 107.87494 lineto
175.396 +120.25273 107.87494 lineto
175.397 +116.80742 116.62494 lineto
175.398 +113.73711 116.62494 lineto
175.399 +110.29961 107.87494 lineto
175.400 +fill
175.401 +grestore
175.402 +gsave
175.403 +0 0 0 setrgbcolor
175.404 +newpath
175.405 +130.57304 112.2265 moveto
175.406 +130.57304 113.02338 lineto
175.407 +124.03398 113.02338 lineto
175.408 +124.10169 113.67963 124.33866 114.17182 124.74492 114.49994 curveto
175.409 +125.15116 114.82807 125.71887 114.99213 126.44804 114.99213 curveto
175.410 +127.03658 114.99213 127.63814 114.90619 128.25273 114.73431 curveto
175.411 +128.87251 114.55723 129.50793 114.29161 130.15898 113.93744 curveto
175.412 +130.15898 116.09369 lineto
175.413 +129.49751 116.34369 128.83606 116.53119 128.17461 116.65619 curveto
175.414 +127.51314 116.7864 126.85168 116.8515 126.19023 116.8515 curveto
175.415 +124.60689 116.8515 123.37512 116.45046 122.49492 115.64838 curveto
175.416 +121.61992 114.84109 121.18242 113.71088 121.18242 112.25775 curveto
175.417 +121.18242 110.83067 121.61211 109.70828 122.47148 108.89056 curveto
175.418 +123.33606 108.07286 124.52356 107.66401 126.03398 107.664 curveto
175.419 +127.40897 107.66401 128.50793 108.07807 129.33086 108.90619 curveto
175.420 +130.15897 109.73432 130.57303 110.84109 130.57304 112.2265 curveto
175.421 +127.69804 111.29681 moveto
175.422 +127.69804 110.76557 127.54179 110.33849 127.22929 110.01556 curveto
175.423 +126.922 109.68745 126.51835 109.52338 126.01836 109.52338 curveto
175.424 +125.47668 109.52338 125.03658 109.67703 124.69804 109.98431 curveto
175.425 +124.3595 110.2864 124.14856 110.7239 124.06523 111.29681 curveto
175.426 +127.69804 111.29681 lineto
175.427 +fill
175.428 +grestore
175.429 +grestore
175.430 +0 0 0 setrgbcolor
175.431 +[] 0 setdash
175.432 +1 setlinewidth
175.433 +0 setlinejoin
175.434 +0 setlinecap
175.435 +newpath
175.436 +176.66575 92.035445 moveto
175.437 +176.66575 118.61025 lineto
175.438 +stroke
175.439 +gsave [2.4492127e-17 0.4 -0.4 2.4492127e-17 176.66575 118.61025] concat
175.440 +gsave
175.441 +0 0 0 setrgbcolor
175.442 +newpath
175.443 +5.77 0 moveto
175.444 +-2.88 5 lineto
175.445 +-2.88 -5 lineto
175.446 +5.77 0 lineto
175.447 +closepath
175.448 +eofill
175.449 +grestore
175.450 +0 0 0 setrgbcolor
175.451 +[] 0 setdash
175.452 +1.25 setlinewidth
175.453 +0 setlinejoin
175.454 +0 setlinecap
175.455 +newpath
175.456 +5.77 0 moveto
175.457 +-2.88 5 lineto
175.458 +-2.88 -5 lineto
175.459 +5.77 0 lineto
175.460 +closepath
175.461 +stroke
175.462 +grestore
175.463 +gsave [0.2378166 0 0 -0.2269133 90.621413 253.06251] concat
175.464 +0 0 0 setrgbcolor
175.465 +[] 0 setdash
175.466 +4.3013706 setlinewidth
175.467 +1 setlinejoin
175.468 +1 setlinecap
175.469 +newpath
175.470 +208.65508 282.05865 moveto
175.471 +193.86388 310.15339 141.95677 326.09523 92.790977 317.64312 curveto
175.472 +43.625187 309.19101 15.726964 279.5298 30.518156 251.43506 curveto
175.473 +45.309349 223.34033 97.216466 207.39848 146.38226 215.85059 curveto
175.474 +177.29043 221.16403 199.42278 233.82562 208.68579 251.49353 curveto
175.475 +stroke
175.476 +gsave [0.79891445 1.5238182 -1.5238182 0.79891445 208.68579 251.49353] concat
175.477 +gsave
175.478 +0 0 0 setrgbcolor
175.479 +newpath
175.480 +5.77 0 moveto
175.481 +-2.88 5 lineto
175.482 +-2.88 -5 lineto
175.483 +5.77 0 lineto
175.484 +closepath
175.485 +eofill
175.486 +grestore
175.487 +0 0 0 setrgbcolor
175.488 +[] 0 setdash
175.489 +1.25 setlinewidth
175.490 +0 setlinejoin
175.491 +0 setlinecap
175.492 +newpath
175.493 +5.77 0 moveto
175.494 +-2.88 5 lineto
175.495 +-2.88 -5 lineto
175.496 +5.77 0 lineto
175.497 +closepath
175.498 +stroke
175.499 +grestore
175.500 +grestore
175.501 +gsave [1 0 0 1 70.866151 78.725565] concat
175.502 +0 0 0 setrgbcolor
175.503 +[] 0 setdash
175.504 +0.99921262 setlinewidth
175.505 +1 setlinejoin
175.506 +1 setlinecap
175.507 +newpath
175.508 +371.50879 42.942394 moveto
175.509 +407.01959 42.942394 lineto
175.510 +416.81302 42.942394 424.69726 50.826635 424.69726 60.620064 curveto
175.511 +424.69726 166.99701 lineto
175.512 +424.69726 176.79044 416.81302 184.67468 407.01959 184.67468 curveto
175.513 +371.50879 184.67468 lineto
175.514 +361.71536 184.67468 353.83112 176.79044 353.83112 166.99701 curveto
175.515 +353.83112 60.620064 lineto
175.516 +353.83112 50.826635 361.71536 42.942394 371.50879 42.942394 curveto
175.517 +closepath
175.518 +stroke
175.519 +gsave
175.520 +0 0 0 setrgbcolor
175.521 +newpath
175.522 +374.16263 110.83588 moveto
175.523 +374.16263 112.96088 lineto
175.524 +373.56366 112.71088 372.98554 112.52338 372.42825 112.39838 curveto
175.525 +371.87096 112.27338 371.34491 112.21088 370.85013 112.21088 curveto
175.526 +370.31887 112.21088 369.92304 112.27859 369.66263 112.414 curveto
175.527 +369.40742 112.54422 369.27981 112.74734 369.27982 113.02338 curveto
175.528 +369.27981 113.24734 369.37617 113.41922 369.56888 113.539 curveto
175.529 +369.76679 113.6588 370.11835 113.74734 370.62357 113.80463 curveto
175.530 +371.11575 113.87494 lineto
175.531 +372.54804 114.05724 373.51158 114.35671 374.00638 114.77338 curveto
175.532 +374.50116 115.19005 374.74856 115.84369 374.74857 116.73431 curveto
175.533 +374.74856 117.66661 374.40481 118.36713 373.71732 118.83588 curveto
175.534 +373.02981 119.30463 372.00377 119.539 370.63919 119.539 curveto
175.535 +370.06106 119.539 369.4621 119.49213 368.84232 119.39838 curveto
175.536 +368.22773 119.30983 367.59492 119.17442 366.94388 118.99213 curveto
175.537 +366.94388 116.86713 lineto
175.538 +367.50117 117.13796 368.07148 117.34109 368.65482 117.4765 curveto
175.539 +369.24335 117.61192 369.83971 117.67963 370.44388 117.67963 curveto
175.540 +370.99075 117.67963 371.40221 117.60411 371.67825 117.45306 curveto
175.541 +371.95429 117.30202 372.09231 117.07807 372.09232 116.78119 curveto
175.542 +372.09231 116.53119 371.99596 116.3463 371.80325 116.2265 curveto
175.543 +371.61575 116.1015 371.23814 116.00515 370.67044 115.93744 curveto
175.544 +370.17825 115.87494 lineto
175.545 +368.93346 115.71869 368.06106 115.42963 367.56107 115.00775 curveto
175.546 +367.06106 114.58588 366.81106 113.94526 366.81107 113.08588 curveto
175.547 +366.81106 112.1588 367.12877 111.4713 367.76419 111.02338 curveto
175.548 +368.3996 110.57547 369.37356 110.35151 370.68607 110.3515 curveto
175.549 +371.20169 110.35151 371.74335 110.39057 372.31107 110.46869 curveto
175.550 +372.87877 110.54682 373.49595 110.66922 374.16263 110.83588 curveto
175.551 +fill
175.552 +grestore
175.553 +gsave
175.554 +0 0 0 setrgbcolor
175.555 +newpath
175.556 +379.91263 108.07806 moveto
175.557 +379.91263 110.56244 lineto
175.558 +382.79544 110.56244 lineto
175.559 +382.79544 112.56244 lineto
175.560 +379.91263 112.56244 lineto
175.561 +379.91263 116.27338 lineto
175.562 +379.91262 116.67963 379.99335 116.95567 380.15482 117.1015 curveto
175.563 +380.31627 117.24213 380.63658 117.31244 381.11575 117.31244 curveto
175.564 +382.55325 117.31244 lineto
175.565 +382.55325 119.31244 lineto
175.566 +380.15482 119.31244 lineto
175.567 +379.05065 119.31244 378.26679 119.08327 377.80325 118.62494 curveto
175.568 +377.34492 118.1614 377.11575 117.37755 377.11575 116.27338 curveto
175.569 +377.11575 112.56244 lineto
175.570 +375.72513 112.56244 lineto
175.571 +375.72513 110.56244 lineto
175.572 +377.11575 110.56244 lineto
175.573 +377.11575 108.07806 lineto
175.574 +379.91263 108.07806 lineto
175.575 +fill
175.576 +grestore
175.577 +gsave
175.578 +0 0 0 setrgbcolor
175.579 +newpath
175.580 +388.43607 115.37494 moveto
175.581 +387.85273 115.37494 387.41262 115.4739 387.11575 115.67181 curveto
175.582 +386.82408 115.86973 386.67825 116.1614 386.67825 116.54681 curveto
175.583 +386.67825 116.90098 386.79544 117.17963 387.02982 117.38275 curveto
175.584 +387.26939 117.58067 387.60012 117.67963 388.022 117.67963 curveto
175.585 +388.54804 117.67963 388.99075 117.49213 389.35013 117.11713 curveto
175.586 +389.7095 116.73692 389.88918 116.26296 389.88919 115.69525 curveto
175.587 +389.88919 115.37494 lineto
175.588 +388.43607 115.37494 lineto
175.589 +392.7095 114.32025 moveto
175.590 +392.7095 119.31244 lineto
175.591 +389.88919 119.31244 lineto
175.592 +389.88919 118.01556 lineto
175.593 +389.51418 118.54681 389.09231 118.93484 388.62357 119.17963 curveto
175.594 +388.15481 119.41921 387.5845 119.539 386.91263 119.539 curveto
175.595 +386.00638 119.539 385.2694 119.27598 384.70169 118.74994 curveto
175.596 +384.13919 118.21869 383.85794 117.53119 383.85794 116.68744 curveto
175.597 +383.85794 115.6614 384.2095 114.9088 384.91263 114.42963 curveto
175.598 +385.62096 113.95047 386.73033 113.71088 388.24075 113.71088 curveto
175.599 +389.88919 113.71088 lineto
175.600 +389.88919 113.49213 lineto
175.601 +389.88918 113.04942 389.7147 112.72651 389.36575 112.52338 curveto
175.602 +389.01679 112.31505 388.47252 112.21088 387.73294 112.21088 curveto
175.603 +387.13398 112.21088 386.57669 112.27078 386.06107 112.39056 curveto
175.604 +385.54544 112.51036 385.06627 112.69005 384.62357 112.92963 curveto
175.605 +384.62357 110.79681 lineto
175.606 +385.22252 110.65099 385.82408 110.54161 386.42825 110.46869 curveto
175.607 +387.03242 110.39057 387.63658 110.35151 388.24075 110.3515 curveto
175.608 +389.81887 110.35151 390.95689 110.66401 391.65482 111.289 curveto
175.609 +392.35793 111.9088 392.70949 112.91922 392.7095 114.32025 curveto
175.610 +fill
175.611 +grestore
175.612 +gsave
175.613 +0 0 0 setrgbcolor
175.614 +newpath
175.615 +398.38138 108.07806 moveto
175.616 +398.38138 110.56244 lineto
175.617 +401.26419 110.56244 lineto
175.618 +401.26419 112.56244 lineto
175.619 +398.38138 112.56244 lineto
175.620 +398.38138 116.27338 lineto
175.621 +398.38137 116.67963 398.4621 116.95567 398.62357 117.1015 curveto
175.622 +398.78502 117.24213 399.10533 117.31244 399.5845 117.31244 curveto
175.623 +401.022 117.31244 lineto
175.624 +401.022 119.31244 lineto
175.625 +398.62357 119.31244 lineto
175.626 +397.5194 119.31244 396.73554 119.08327 396.272 118.62494 curveto
175.627 +395.81367 118.1614 395.5845 117.37755 395.5845 116.27338 curveto
175.628 +395.5845 112.56244 lineto
175.629 +394.19388 112.56244 lineto
175.630 +394.19388 110.56244 lineto
175.631 +395.5845 110.56244 lineto
175.632 +395.5845 108.07806 lineto
175.633 +398.38138 108.07806 lineto
175.634 +fill
175.635 +grestore
175.636 +gsave
175.637 +0 0 0 setrgbcolor
175.638 +newpath
175.639 +411.71732 114.914 moveto
175.640 +411.71732 115.71088 lineto
175.641 +405.17825 115.71088 lineto
175.642 +405.24596 116.36713 405.48294 116.85932 405.88919 117.18744 curveto
175.643 +406.29544 117.51557 406.86314 117.67963 407.59232 117.67963 curveto
175.644 +408.18085 117.67963 408.78241 117.59369 409.397 117.42181 curveto
175.645 +410.01679 117.24473 410.6522 116.97911 411.30325 116.62494 curveto
175.646 +411.30325 118.78119 lineto
175.647 +410.64179 119.03119 409.98033 119.21869 409.31888 119.34369 curveto
175.648 +408.65741 119.4739 407.99596 119.539 407.3345 119.539 curveto
175.649 +405.75117 119.539 404.5194 119.13796 403.63919 118.33588 curveto
175.650 +402.76419 117.52859 402.32669 116.39838 402.32669 114.94525 curveto
175.651 +402.32669 113.51817 402.75638 112.39578 403.61575 111.57806 curveto
175.652 +404.48033 110.76036 405.66783 110.35151 407.17825 110.3515 curveto
175.653 +408.55325 110.35151 409.6522 110.76557 410.47513 111.59369 curveto
175.654 +411.30324 112.42182 411.71731 113.52859 411.71732 114.914 curveto
175.655 +408.84232 113.98431 moveto
175.656 +408.84231 113.45307 408.68606 113.02599 408.37357 112.70306 curveto
175.657 +408.06627 112.37495 407.66262 112.21088 407.16263 112.21088 curveto
175.658 +406.62096 112.21088 406.18085 112.36453 405.84232 112.67181 curveto
175.659 +405.50377 112.9739 405.29283 113.4114 405.2095 113.98431 curveto
175.660 +408.84232 113.98431 lineto
175.661 +fill
175.662 +grestore
175.663 +grestore
175.664 +0 0 0 setrgbcolor
175.665 +[] 0 setdash
175.666 +1 setlinewidth
175.667 +0 setlinejoin
175.668 +0 setlinecap
175.669 +newpath
175.670 +460.13031 263.40024 moveto
175.671 +460.13031 289.97505 lineto
175.672 +stroke
175.673 +gsave [2.4492127e-17 0.4 -0.4 2.4492127e-17 460.13031 289.97505] concat
175.674 +gsave
175.675 +0 0 0 setrgbcolor
175.676 +newpath
175.677 +5.77 0 moveto
175.678 +-2.88 5 lineto
175.679 +-2.88 -5 lineto
175.680 +5.77 0 lineto
175.681 +closepath
175.682 +eofill
175.683 +grestore
175.684 +0 0 0 setrgbcolor
175.685 +[] 0 setdash
175.686 +1.25 setlinewidth
175.687 +0 setlinejoin
175.688 +0 setlinecap
175.689 +newpath
175.690 +5.77 0 moveto
175.691 +-2.88 5 lineto
175.692 +-2.88 -5 lineto
175.693 +5.77 0 lineto
175.694 +closepath
175.695 +stroke
175.696 +grestore
175.697 +gsave [-0.2378166 0 0 0.2269133 546.17466 132.00569] concat
175.698 +0 0 0 setrgbcolor
175.699 +[] 0 setdash
175.700 +4.3013706 setlinewidth
175.701 +1 setlinejoin
175.702 +1 setlinecap
175.703 +newpath
175.704 +208.65508 282.05865 moveto
175.705 +193.86388 310.15339 141.95677 326.09523 92.790977 317.64312 curveto
175.706 +43.625187 309.19101 15.726964 279.5298 30.518156 251.43506 curveto
175.707 +45.309349 223.34033 97.216466 207.39848 146.38226 215.85059 curveto
175.708 +177.29043 221.16403 199.42278 233.82562 208.68579 251.49353 curveto
175.709 +stroke
175.710 +gsave [0.79891445 1.5238182 -1.5238182 0.79891445 208.68579 251.49353] concat
175.711 +gsave
175.712 +0 0 0 setrgbcolor
175.713 +newpath
175.714 +5.77 0 moveto
175.715 +-2.88 5 lineto
175.716 +-2.88 -5 lineto
175.717 +5.77 0 lineto
175.718 +closepath
175.719 +eofill
175.720 +grestore
175.721 +0 0 0 setrgbcolor
175.722 +[] 0 setdash
175.723 +1.25 setlinewidth
175.724 +0 setlinejoin
175.725 +0 setlinecap
175.726 +newpath
175.727 +5.77 0 moveto
175.728 +-2.88 5 lineto
175.729 +-2.88 -5 lineto
175.730 +5.77 0 lineto
175.731 +closepath
175.732 +stroke
175.733 +grestore
175.734 +grestore
175.735 +gsave [-0.2378166 0 0 0.2269133 546.17465 87.714359] concat
175.736 +0 0 0 setrgbcolor
175.737 +[] 0 setdash
175.738 +4.3013706 setlinewidth
175.739 +2 setlinejoin
175.740 +1 setlinecap
175.741 +newpath
175.742 +208.65508 282.05865 moveto
175.743 +193.86388 310.15339 141.95677 326.09523 92.790977 317.64312 curveto
175.744 +43.625187 309.19101 15.726964 279.5298 30.518156 251.43506 curveto
175.745 +45.309349 223.34033 97.216466 207.39848 146.38226 215.85059 curveto
175.746 +177.29043 221.16403 199.42278 233.82562 208.68579 251.49353 curveto
175.747 +stroke
175.748 +gsave [0.79891445 1.5238182 -1.5238182 0.79891445 208.68579 251.49353] concat
175.749 +gsave
175.750 +0 0 0 setrgbcolor
175.751 +newpath
175.752 +5.77 0 moveto
175.753 +-2.88 5 lineto
175.754 +-2.88 -5 lineto
175.755 +5.77 0 lineto
175.756 +closepath
175.757 +eofill
175.758 +grestore
175.759 +0 0 0 setrgbcolor
175.760 +[] 0 setdash
175.761 +1.25 setlinewidth
175.762 +0 setlinejoin
175.763 +0 setlinecap
175.764 +newpath
175.765 +5.77 0 moveto
175.766 +-2.88 5 lineto
175.767 +-2.88 -5 lineto
175.768 +5.77 0 lineto
175.769 +closepath
175.770 +stroke
175.771 +grestore
175.772 +grestore
175.773 +gsave [-0.2378166 0 0 0.2269133 546.17465 176.29703] concat
175.774 +0 0 0 setrgbcolor
175.775 +[] 0 setdash
175.776 +4.3013706 setlinewidth
175.777 +1 setlinejoin
175.778 +1 setlinecap
175.779 +newpath
175.780 +208.65508 282.05865 moveto
175.781 +193.86388 310.15339 141.95677 326.09523 92.790977 317.64312 curveto
175.782 +43.625187 309.19101 15.726964 279.5298 30.518156 251.43506 curveto
175.783 +45.309349 223.34033 97.216466 207.39848 146.38226 215.85059 curveto
175.784 +177.29043 221.16403 199.42278 233.82562 208.68579 251.49353 curveto
175.785 +stroke
175.786 +gsave [0.79891445 1.5238182 -1.5238182 0.79891445 208.68579 251.49353] concat
175.787 +gsave
175.788 +0 0 0 setrgbcolor
175.789 +newpath
175.790 +5.77 0 moveto
175.791 +-2.88 5 lineto
175.792 +-2.88 -5 lineto
175.793 +5.77 0 lineto
175.794 +closepath
175.795 +eofill
175.796 +grestore
175.797 +0 0 0 setrgbcolor
175.798 +[] 0 setdash
175.799 +1.25 setlinewidth
175.800 +0 setlinejoin
175.801 +0 setlinecap
175.802 +newpath
175.803 +5.77 0 moveto
175.804 +-2.88 5 lineto
175.805 +-2.88 -5 lineto
175.806 +5.77 0 lineto
175.807 +closepath
175.808 +stroke
175.809 +grestore
175.810 +grestore
175.811 +gsave [0 0.2378166 0.2269133 0 399.60191 71.056696] concat
175.812 +0 0 0 setrgbcolor
175.813 +[] 0 setdash
175.814 +4.3013706 setlinewidth
175.815 +1 setlinejoin
175.816 +1 setlinecap
175.817 +newpath
175.818 +208.65508 282.05865 moveto
175.819 +193.86388 310.15339 141.95677 326.09523 92.790977 317.64312 curveto
175.820 +43.625187 309.19101 15.726964 279.5298 30.518156 251.43506 curveto
175.821 +45.309349 223.34033 97.216466 207.39848 146.38226 215.85059 curveto
175.822 +177.29043 221.16403 199.42278 233.82562 208.68579 251.49353 curveto
175.823 +stroke
175.824 +gsave [0.79891445 1.5238182 -1.5238182 0.79891445 208.68579 251.49353] concat
175.825 +gsave
175.826 +0 0 0 setrgbcolor
175.827 +newpath
175.828 +5.77 0 moveto
175.829 +-2.88 5 lineto
175.830 +-2.88 -5 lineto
175.831 +5.77 0 lineto
175.832 +closepath
175.833 +eofill
175.834 +grestore
175.835 +0 0 0 setrgbcolor
175.836 +[] 0 setdash
175.837 +1.25 setlinewidth
175.838 +0 setlinejoin
175.839 +0 setlinecap
175.840 +newpath
175.841 +5.77 0 moveto
175.842 +-2.88 5 lineto
175.843 +-2.88 -5 lineto
175.844 +5.77 0 lineto
175.845 +closepath
175.846 +stroke
175.847 +grestore
175.848 +grestore
175.849 +gsave [1 0 0 1 17.216929 6.5104864] concat
175.850 +grestore
175.851 +gsave
175.852 +0 0 0 setrgbcolor
175.853 +newpath
175.854 +187.35507 103.05839 moveto
175.855 +187.35507 104.61112 lineto
175.856 +189.20566 104.61112 lineto
175.857 +189.20566 105.30936 lineto
175.858 +187.35507 105.30936 lineto
175.859 +187.35507 108.27811 lineto
175.860 +187.35507 108.72408 187.41529 109.01054 187.53574 109.13749 curveto
175.861 +187.65943 109.26444 187.90846 109.32792 188.28281 109.32792 curveto
175.862 +189.20566 109.32792 lineto
175.863 +189.20566 110.07987 lineto
175.864 +188.28281 110.07987 lineto
175.865 +187.58944 110.07987 187.11093 109.95129 186.84726 109.69413 curveto
175.866 +186.58359 109.43371 186.45175 108.96171 186.45175 108.27811 curveto
175.867 +186.45175 105.30936 lineto
175.868 +185.79257 105.30936 lineto
175.869 +185.79257 104.61112 lineto
175.870 +186.45175 104.61112 lineto
175.871 +186.45175 103.05839 lineto
175.872 +187.35507 103.05839 lineto
175.873 +fill
175.874 +grestore
175.875 +gsave
175.876 +0 0 0 setrgbcolor
175.877 +newpath
175.878 +194.93808 106.77909 moveto
175.879 +194.93808 110.07987 lineto
175.880 +194.03964 110.07987 lineto
175.881 +194.03964 106.80839 lineto
175.882 +194.03964 106.29081 193.93873 105.90344 193.73691 105.64628 curveto
175.883 +193.53508 105.38912 193.23235 105.26054 192.8287 105.26054 curveto
175.884 +192.34368 105.26054 191.96119 105.41516 191.68124 105.7244 curveto
175.885 +191.40129 106.03365 191.26132 106.4552 191.26132 106.98905 curveto
175.886 +191.26132 110.07987 lineto
175.887 +190.358 110.07987 lineto
175.888 +190.358 102.48222 lineto
175.889 +191.26132 102.48222 lineto
175.890 +191.26132 105.46073 lineto
175.891 +191.47616 105.13196 191.72844 104.88619 192.01816 104.72343 curveto
175.892 +192.31112 104.56067 192.64804 104.47929 193.0289 104.47929 curveto
175.893 +193.65715 104.47929 194.13241 104.6746 194.45468 105.06522 curveto
175.894 +194.77694 105.4526 194.93807 106.02389 194.93808 106.77909 curveto
175.895 +fill
175.896 +grestore
175.897 +gsave
175.898 +0 0 0 setrgbcolor
175.899 +newpath
175.900 +201.41757 107.12089 moveto
175.901 +201.41757 107.56034 lineto
175.902 +197.28671 107.56034 lineto
175.903 +197.32577 108.17883 197.51132 108.65084 197.84335 108.97636 curveto
175.904 +198.17864 109.29862 198.64413 109.45976 199.23984 109.45975 curveto
175.905 +199.58489 109.45976 199.91854 109.41744 200.24081 109.3328 curveto
175.906 +200.56633 109.24817 200.8886 109.12121 201.20761 108.95194 curveto
175.907 +201.20761 109.80155 lineto
175.908 +200.88534 109.93827 200.55494 110.04244 200.2164 110.11405 curveto
175.909 +199.87785 110.18567 199.53443 110.22147 199.18613 110.22147 curveto
175.910 +198.31373 110.22147 197.622 109.96757 197.11093 109.45975 curveto
175.911 +196.60312 108.95194 196.34921 108.2651 196.34921 107.39921 curveto
175.912 +196.34921 106.50403 196.5901 105.79439 197.07187 105.2703 curveto
175.913 +197.55689 104.74296 198.20956 104.47929 199.02988 104.47929 curveto
175.914 +199.76555 104.47929 200.3466 104.71692 200.77304 105.19218 curveto
175.915 +201.20272 105.66419 201.41757 106.30709 201.41757 107.12089 curveto
175.916 +200.51913 106.85722 moveto
175.917 +200.51262 106.36568 200.37427 105.97343 200.1041 105.68046 curveto
175.918 +199.83716 105.38749 199.48235 105.24101 199.03964 105.241 curveto
175.919 +198.53834 105.24101 198.13632 105.38261 197.83359 105.66581 curveto
175.920 +197.53411 105.94902 197.36158 106.34778 197.31601 106.8621 curveto
175.921 +200.51913 106.85722 lineto
175.922 +fill
175.923 +grestore
175.924 +gsave
175.925 +0 0 0 setrgbcolor
175.926 +newpath
175.927 +205.01132 105.241 moveto
175.928 +204.52955 105.24101 204.14869 105.42981 203.86874 105.80741 curveto
175.929 +203.58879 106.18176 203.44882 106.69609 203.44882 107.35038 curveto
175.930 +203.44882 108.00468 203.58717 108.52063 203.86386 108.89823 curveto
175.931 +204.14381 109.27258 204.52629 109.45976 205.01132 109.45975 curveto
175.932 +205.48983 109.45976 205.86907 109.27095 206.14902 108.89335 curveto
175.933 +206.42896 108.51575 206.56893 108.00142 206.56894 107.35038 curveto
175.934 +206.56893 106.7026 206.42896 106.1899 206.14902 105.81229 curveto
175.935 +205.86907 105.43144 205.48983 105.24101 205.01132 105.241 curveto
175.936 +205.01132 104.47929 moveto
175.937 +205.79257 104.47929 206.40617 104.7332 206.85214 105.241 curveto
175.938 +207.2981 105.74882 207.52108 106.45195 207.52109 107.35038 curveto
175.939 +207.52108 108.24556 207.2981 108.94869 206.85214 109.45975 curveto
175.940 +206.40617 109.96757 205.79257 110.22147 205.01132 110.22147 curveto
175.941 +204.22681 110.22147 203.61158 109.96757 203.16562 109.45975 curveto
175.942 +202.72291 108.94869 202.50156 108.24556 202.50156 107.35038 curveto
175.943 +202.50156 106.45195 202.72291 105.74882 203.16562 105.241 curveto
175.944 +203.61158 104.7332 204.22681 104.47929 205.01132 104.47929 curveto
175.945 +fill
175.946 +grestore
175.947 +gsave
175.948 +0 0 0 setrgbcolor
175.949 +newpath
175.950 +212.17441 105.45097 moveto
175.951 +212.07349 105.39238 211.96282 105.35006 211.84238 105.32401 curveto
175.952 +211.72519 105.29472 211.59498 105.28007 211.45175 105.28007 curveto
175.953 +210.94394 105.28007 210.55331 105.44609 210.27988 105.77811 curveto
175.954 +210.00969 106.10689 209.8746 106.58053 209.8746 107.19901 curveto
175.955 +209.8746 110.07987 lineto
175.956 +208.97128 110.07987 lineto
175.957 +208.97128 104.61112 lineto
175.958 +209.8746 104.61112 lineto
175.959 +209.8746 105.46073 lineto
175.960 +210.0634 105.12871 210.30917 104.88294 210.61191 104.72343 curveto
175.961 +210.91464 104.56067 211.28248 104.47929 211.71542 104.47929 curveto
175.962 +211.77727 104.47929 211.84563 104.48417 211.9205 104.49393 curveto
175.963 +211.99537 104.50045 212.07838 104.51184 212.16953 104.52811 curveto
175.964 +212.17441 105.45097 lineto
175.965 +fill
175.966 +grestore
175.967 +gsave
175.968 +0 0 0 setrgbcolor
175.969 +newpath
175.970 +217.58945 107.12089 moveto
175.971 +217.58945 107.56034 lineto
175.972 +213.45859 107.56034 lineto
175.973 +213.49765 108.17883 213.6832 108.65084 214.01523 108.97636 curveto
175.974 +214.35051 109.29862 214.81601 109.45976 215.41171 109.45975 curveto
175.975 +215.75676 109.45976 216.09042 109.41744 216.41269 109.3328 curveto
175.976 +216.73821 109.24817 217.06047 109.12121 217.37949 108.95194 curveto
175.977 +217.37949 109.80155 lineto
175.978 +217.05722 109.93827 216.72681 110.04244 216.38828 110.11405 curveto
175.979 +216.04973 110.18567 215.70631 110.22147 215.358 110.22147 curveto
175.980 +214.4856 110.22147 213.79387 109.96757 213.28281 109.45975 curveto
175.981 +212.77499 108.95194 212.52109 108.2651 212.52109 107.39921 curveto
175.982 +212.52109 106.50403 212.76197 105.79439 213.24374 105.2703 curveto
175.983 +213.72877 104.74296 214.38144 104.47929 215.20175 104.47929 curveto
175.984 +215.93742 104.47929 216.51848 104.71692 216.94492 105.19218 curveto
175.985 +217.3746 105.66419 217.58944 106.30709 217.58945 107.12089 curveto
175.986 +216.69101 106.85722 moveto
175.987 +216.68449 106.36568 216.54615 105.97343 216.27597 105.68046 curveto
175.988 +216.00904 105.38749 215.65422 105.24101 215.21152 105.241 curveto
175.989 +214.71021 105.24101 214.30819 105.38261 214.00546 105.66581 curveto
175.990 +213.70598 105.94902 213.53346 106.34778 213.48788 106.8621 curveto
175.991 +216.69101 106.85722 lineto
175.992 +fill
175.993 +grestore
175.994 +gsave
175.995 +0 0 0 setrgbcolor
175.996 +newpath
175.997 +223.32187 105.66093 moveto
175.998 +223.54647 105.25729 223.81503 104.95943 224.12753 104.76737 curveto
175.999 +224.44003 104.57532 224.80786 104.47929 225.23105 104.47929 curveto
175.1000 +225.8007 104.47929 226.24016 104.67949 226.54941 105.07987 curveto
175.1001 +226.85864 105.47701 227.01327 106.04342 227.01328 106.77909 curveto
175.1002 +227.01328 110.07987 lineto
175.1003 +226.10995 110.07987 lineto
175.1004 +226.10995 106.80839 lineto
175.1005 +226.10995 106.2843 226.01717 105.89531 225.83163 105.6414 curveto
175.1006 +225.64608 105.38749 225.36288 105.26054 224.98203 105.26054 curveto
175.1007 +224.51652 105.26054 224.14869 105.41516 223.87851 105.7244 curveto
175.1008 +223.60832 106.03365 223.47323 106.4552 223.47324 106.98905 curveto
175.1009 +223.47324 110.07987 lineto
175.1010 +222.56992 110.07987 lineto
175.1011 +222.56992 106.80839 lineto
175.1012 +222.56991 106.28105 222.47714 105.89205 222.2916 105.6414 curveto
175.1013 +222.10604 105.38749 221.81959 105.26054 221.43222 105.26054 curveto
175.1014 +220.97323 105.26054 220.60865 105.41679 220.33847 105.72929 curveto
175.1015 +220.06829 106.03854 219.9332 106.45846 219.9332 106.98905 curveto
175.1016 +219.9332 110.07987 lineto
175.1017 +219.02988 110.07987 lineto
175.1018 +219.02988 104.61112 lineto
175.1019 +219.9332 104.61112 lineto
175.1020 +219.9332 105.46073 lineto
175.1021 +220.13827 105.12545 220.38404 104.87805 220.6705 104.71854 curveto
175.1022 +220.95696 104.55904 221.29713 104.47929 221.69101 104.47929 curveto
175.1023 +222.08814 104.47929 222.42505 104.5802 222.70175 104.78202 curveto
175.1024 +222.98169 104.98385 223.1884 105.27682 223.32187 105.66093 curveto
175.1025 +fill
175.1026 +grestore
175.1027 +gsave [1 0 0 1 17.216929 6.5104864] concat
175.1028 +grestore
175.1029 +gsave
175.1030 +0 0 0 setrgbcolor
175.1031 +newpath
175.1032 +470.46808 277.74594 moveto
175.1033 +470.46808 278.40675 470.60317 278.92596 470.87335 279.30356 curveto
175.1034 +471.14679 279.67791 471.52114 279.86508 471.9964 279.86508 curveto
175.1035 +472.47166 279.86508 472.846 279.67791 473.11945 279.30356 curveto
175.1036 +473.39288 278.92596 473.5296 278.40675 473.5296 277.74594 curveto
175.1037 +473.5296 277.08514 473.39288 276.56756 473.11945 276.19321 curveto
175.1038 +472.846 275.81561 472.47166 275.62681 471.9964 275.6268 curveto
175.1039 +471.52114 275.62681 471.14679 275.81561 470.87335 276.19321 curveto
175.1040 +470.60317 276.56756 470.46808 277.08514 470.46808 277.74594 curveto
175.1041 +473.5296 279.65512 moveto
175.1042 +473.3408 279.98064 473.10154 280.22315 472.81183 280.38266 curveto
175.1043 +472.52537 280.53891 472.18032 280.61703 471.77667 280.61703 curveto
175.1044 +471.11586 280.61703 470.57713 280.35336 470.16046 279.82602 curveto
175.1045 +469.74705 279.29868 469.54034 278.60532 469.54034 277.74594 curveto
175.1046 +469.54034 276.88657 469.74705 276.19321 470.16046 275.66586 curveto
175.1047 +470.57713 275.13852 471.11586 274.87485 471.77667 274.87485 curveto
175.1048 +472.18032 274.87485 472.52537 274.95461 472.81183 275.11411 curveto
175.1049 +473.10154 275.27036 473.3408 275.51125 473.5296 275.83676 curveto
175.1050 +473.5296 275.00668 lineto
175.1051 +474.42804 275.00668 lineto
175.1052 +474.42804 282.55551 lineto
175.1053 +473.5296 282.55551 lineto
175.1054 +473.5296 279.65512 lineto
175.1055 +fill
175.1056 +grestore
175.1057 +gsave
175.1058 +0 0 0 setrgbcolor
175.1059 +newpath
175.1060 +480.95636 277.51645 moveto
175.1061 +480.95636 277.9559 lineto
175.1062 +476.8255 277.9559 lineto
175.1063 +476.86456 278.57439 477.05011 279.0464 477.38214 279.37192 curveto
175.1064 +477.71743 279.69418 478.18292 279.85532 478.77863 279.85532 curveto
175.1065 +479.12367 279.85532 479.45733 279.813 479.7796 279.72836 curveto
175.1066 +480.10512 279.64373 480.42738 279.51678 480.7464 279.3475 curveto
175.1067 +480.7464 280.19711 lineto
175.1068 +480.42413 280.33383 480.09372 280.438 479.75519 280.50961 curveto
175.1069 +479.41664 280.58123 479.07322 280.61703 478.72491 280.61703 curveto
175.1070 +477.85252 280.61703 477.16079 280.36313 476.64972 279.85532 curveto
175.1071 +476.14191 279.3475 475.888 278.66066 475.888 277.79477 curveto
175.1072 +475.888 276.89959 476.12889 276.18996 476.61066 275.66586 curveto
175.1073 +477.09568 275.13852 477.74835 274.87485 478.56866 274.87485 curveto
175.1074 +479.30434 274.87485 479.88539 275.11248 480.31183 275.58774 curveto
175.1075 +480.74151 276.05975 480.95635 276.70265 480.95636 277.51645 curveto
175.1076 +480.05792 277.25278 moveto
175.1077 +480.05141 276.76124 479.91306 276.36899 479.64288 276.07602 curveto
175.1078 +479.37595 275.78306 479.02113 275.63657 478.57843 275.63657 curveto
175.1079 +478.07713 275.63657 477.67511 275.77817 477.37238 276.06137 curveto
175.1080 +477.07289 276.34458 476.90037 276.74334 476.8548 277.25766 curveto
175.1081 +480.05792 277.25278 lineto
175.1082 +fill
175.1083 +grestore
175.1084 +gsave
175.1085 +0 0 0 setrgbcolor
175.1086 +newpath
175.1087 +486.0296 275.83676 moveto
175.1088 +486.0296 272.87778 lineto
175.1089 +486.92804 272.87778 lineto
175.1090 +486.92804 280.47543 lineto
175.1091 +486.0296 280.47543 lineto
175.1092 +486.0296 279.65512 lineto
175.1093 +485.8408 279.98064 485.60154 280.22315 485.31183 280.38266 curveto
175.1094 +485.02537 280.53891 484.68032 280.61703 484.27667 280.61703 curveto
175.1095 +483.61586 280.61703 483.07713 280.35336 482.66046 279.82602 curveto
175.1096 +482.24705 279.29868 482.04034 278.60532 482.04034 277.74594 curveto
175.1097 +482.04034 276.88657 482.24705 276.19321 482.66046 275.66586 curveto
175.1098 +483.07713 275.13852 483.61586 274.87485 484.27667 274.87485 curveto
175.1099 +484.68032 274.87485 485.02537 274.95461 485.31183 275.11411 curveto
175.1100 +485.60154 275.27036 485.8408 275.51125 486.0296 275.83676 curveto
175.1101 +482.96808 277.74594 moveto
175.1102 +482.96808 278.40675 483.10317 278.92596 483.37335 279.30356 curveto
175.1103 +483.64679 279.67791 484.02114 279.86508 484.4964 279.86508 curveto
175.1104 +484.97166 279.86508 485.346 279.67791 485.61945 279.30356 curveto
175.1105 +485.89288 278.92596 486.0296 278.40675 486.0296 277.74594 curveto
175.1106 +486.0296 277.08514 485.89288 276.56756 485.61945 276.19321 curveto
175.1107 +485.346 275.81561 484.97166 275.62681 484.4964 275.6268 curveto
175.1108 +484.02114 275.62681 483.64679 275.81561 483.37335 276.19321 curveto
175.1109 +483.10317 276.56756 482.96808 277.08514 482.96808 277.74594 curveto
175.1110 +fill
175.1111 +grestore
175.1112 +gsave
175.1113 +0 0 0 setrgbcolor
175.1114 +newpath
175.1115 +550.54895 236.85474 moveto
175.1116 +550.54895 237.51555 550.68404 238.03475 550.95422 238.41235 curveto
175.1117 +551.22766 238.7867 551.60201 238.97388 552.07727 238.97388 curveto
175.1118 +552.55253 238.97388 552.92688 238.7867 553.20032 238.41235 curveto
175.1119 +553.47375 238.03475 553.61047 237.51555 553.61047 236.85474 curveto
175.1120 +553.61047 236.19393 553.47375 235.67635 553.20032 235.302 curveto
175.1121 +552.92688 234.9244 552.55253 234.7356 552.07727 234.7356 curveto
175.1122 +551.60201 234.7356 551.22766 234.9244 550.95422 235.302 curveto
175.1123 +550.68404 235.67635 550.54895 236.19393 550.54895 236.85474 curveto
175.1124 +553.61047 238.76392 moveto
175.1125 +553.42167 239.08944 553.18241 239.33195 552.8927 239.49146 curveto
175.1126 +552.60624 239.64771 552.26119 239.72583 551.85754 239.72583 curveto
175.1127 +551.19673 239.72583 550.658 239.46216 550.24133 238.93481 curveto
175.1128 +549.82792 238.40747 549.62122 237.71411 549.62122 236.85474 curveto
175.1129 +549.62122 235.99536 549.82792 235.30201 550.24133 234.77466 curveto
175.1130 +550.658 234.24732 551.19673 233.98365 551.85754 233.98364 curveto
175.1131 +552.26119 233.98365 552.60624 234.0634 552.8927 234.2229 curveto
175.1132 +553.18241 234.37916 553.42167 234.62004 553.61047 234.94556 curveto
175.1133 +553.61047 234.11548 lineto
175.1134 +554.50891 234.11548 lineto
175.1135 +554.50891 241.66431 lineto
175.1136 +553.61047 241.66431 lineto
175.1137 +553.61047 238.76392 lineto
175.1138 +fill
175.1139 +grestore
175.1140 +gsave
175.1141 +0 0 0 setrgbcolor
175.1142 +newpath
175.1143 +561.03723 236.62524 moveto
175.1144 +561.03723 237.0647 lineto
175.1145 +556.90637 237.0647 lineto
175.1146 +556.94543 237.68319 557.13098 238.15519 557.46301 238.48071 curveto
175.1147 +557.7983 238.80298 558.26379 238.96411 558.8595 238.96411 curveto
175.1148 +559.20455 238.96411 559.5382 238.92179 559.86047 238.83716 curveto
175.1149 +560.18599 238.75252 560.50825 238.62557 560.82727 238.4563 curveto
175.1150 +560.82727 239.30591 lineto
175.1151 +560.505 239.44263 560.1746 239.54679 559.83606 239.61841 curveto
175.1152 +559.49751 239.69002 559.15409 239.72583 558.80579 239.72583 curveto
175.1153 +557.93339 239.72583 557.24166 239.47192 556.73059 238.96411 curveto
175.1154 +556.22278 238.4563 555.96887 237.76945 555.96887 236.90356 curveto
175.1155 +555.96887 236.00839 556.20976 235.29875 556.69153 234.77466 curveto
175.1156 +557.17655 234.24732 557.82922 233.98365 558.64954 233.98364 curveto
175.1157 +559.38521 233.98365 559.96626 234.22128 560.3927 234.69653 curveto
175.1158 +560.82238 235.16854 561.03723 235.81145 561.03723 236.62524 curveto
175.1159 +560.13879 236.36157 moveto
175.1160 +560.13228 235.87004 559.99393 235.47779 559.72375 235.18481 curveto
175.1161 +559.45682 234.89185 559.10201 234.74537 558.6593 234.74536 curveto
175.1162 +558.158 234.74537 557.75598 234.88697 557.45325 235.17017 curveto
175.1163 +557.15377 235.45337 556.98124 235.85214 556.93567 236.36646 curveto
175.1164 +560.13879 236.36157 lineto
175.1165 +fill
175.1166 +grestore
175.1167 +gsave
175.1168 +0 0 0 setrgbcolor
175.1169 +newpath
175.1170 +566.11047 234.94556 moveto
175.1171 +566.11047 231.98657 lineto
175.1172 +567.00891 231.98657 lineto
175.1173 +567.00891 239.58423 lineto
175.1174 +566.11047 239.58423 lineto
175.1175 +566.11047 238.76392 lineto
175.1176 +565.92167 239.08944 565.68241 239.33195 565.3927 239.49146 curveto
175.1177 +565.10624 239.64771 564.76119 239.72583 564.35754 239.72583 curveto
175.1178 +563.69673 239.72583 563.158 239.46216 562.74133 238.93481 curveto
175.1179 +562.32792 238.40747 562.12122 237.71411 562.12122 236.85474 curveto
175.1180 +562.12122 235.99536 562.32792 235.30201 562.74133 234.77466 curveto
175.1181 +563.158 234.24732 563.69673 233.98365 564.35754 233.98364 curveto
175.1182 +564.76119 233.98365 565.10624 234.0634 565.3927 234.2229 curveto
175.1183 +565.68241 234.37916 565.92167 234.62004 566.11047 234.94556 curveto
175.1184 +563.04895 236.85474 moveto
175.1185 +563.04895 237.51555 563.18404 238.03475 563.45422 238.41235 curveto
175.1186 +563.72766 238.7867 564.10201 238.97388 564.57727 238.97388 curveto
175.1187 +565.05253 238.97388 565.42688 238.7867 565.70032 238.41235 curveto
175.1188 +565.97375 238.03475 566.11047 237.51555 566.11047 236.85474 curveto
175.1189 +566.11047 236.19393 565.97375 235.67635 565.70032 235.302 curveto
175.1190 +565.42688 234.9244 565.05253 234.7356 564.57727 234.7356 curveto
175.1191 +564.10201 234.7356 563.72766 234.9244 563.45422 235.302 curveto
175.1192 +563.18404 235.67635 563.04895 236.19393 563.04895 236.85474 curveto
175.1193 +fill
175.1194 +grestore
175.1195 +gsave
175.1196 +0 0 0 setrgbcolor
175.1197 +newpath
175.1198 +553.10266 183.66447 moveto
175.1199 +553.10266 184.41154 lineto
175.1200 +552.24329 184.41154 lineto
175.1201 +551.92102 184.41155 551.69641 184.47666 551.56946 184.60686 curveto
175.1202 +551.44576 184.73707 551.38391 184.97145 551.38391 185.30998 curveto
175.1203 +551.38391 185.79338 lineto
175.1204 +552.8634 185.79338 lineto
175.1205 +552.8634 186.49162 lineto
175.1206 +551.38391 186.49162 lineto
175.1207 +551.38391 191.26213 lineto
175.1208 +550.48059 191.26213 lineto
175.1209 +550.48059 186.49162 lineto
175.1210 +549.62122 186.49162 lineto
175.1211 +549.62122 185.79338 lineto
175.1212 +550.48059 185.79338 lineto
175.1213 +550.48059 185.41252 lineto
175.1214 +550.48059 184.8038 550.62219 184.3611 550.9054 184.0844 curveto
175.1215 +551.1886 183.80446 551.63782 183.66448 552.25305 183.66447 curveto
175.1216 +553.10266 183.66447 lineto
175.1217 +fill
175.1218 +grestore
175.1219 +gsave
175.1220 +0 0 0 setrgbcolor
175.1221 +newpath
175.1222 +553.84973 185.79338 moveto
175.1223 +554.74817 185.79338 lineto
175.1224 +554.74817 191.26213 lineto
175.1225 +553.84973 191.26213 lineto
175.1226 +553.84973 185.79338 lineto
175.1227 +553.84973 183.66447 moveto
175.1228 +554.74817 183.66447 lineto
175.1229 +554.74817 184.80217 lineto
175.1230 +553.84973 184.80217 lineto
175.1231 +553.84973 183.66447 lineto
175.1232 +fill
175.1233 +grestore
175.1234 +gsave
175.1235 +0 0 0 setrgbcolor
175.1236 +newpath
175.1237 +561.16907 185.79338 moveto
175.1238 +559.19153 188.45451 lineto
175.1239 +561.27161 191.26213 lineto
175.1240 +560.21204 191.26213 lineto
175.1241 +558.62024 189.11369 lineto
175.1242 +557.02844 191.26213 lineto
175.1243 +555.96887 191.26213 lineto
175.1244 +558.0929 188.4008 lineto
175.1245 +556.14954 185.79338 lineto
175.1246 +557.20911 185.79338 lineto
175.1247 +558.6593 187.74162 lineto
175.1248 +560.1095 185.79338 lineto
175.1249 +561.16907 185.79338 lineto
175.1250 +fill
175.1251 +grestore
175.1252 +gsave
175.1253 +0 0 0 setrgbcolor
175.1254 +newpath
175.1255 +552.81946 198.51311 moveto
175.1256 +552.09354 198.51311 551.59061 198.59612 551.31067 198.76213 curveto
175.1257 +551.03072 198.92815 550.89075 199.21135 550.89075 199.61174 curveto
175.1258 +550.89075 199.93075 550.99491 200.18466 551.20325 200.37346 curveto
175.1259 +551.41483 200.55901 551.70129 200.65178 552.06262 200.65178 curveto
175.1260 +552.56067 200.65178 552.95943 200.476 553.25891 200.12444 curveto
175.1261 +553.56164 199.76962 553.71301 199.29924 553.71301 198.7133 curveto
175.1262 +553.71301 198.51311 lineto
175.1263 +552.81946 198.51311 lineto
175.1264 +554.61145 198.14201 moveto
175.1265 +554.61145 201.26213 lineto
175.1266 +553.71301 201.26213 lineto
175.1267 +553.71301 200.43205 lineto
175.1268 +553.50793 200.76408 553.2524 201.00985 552.94641 201.16936 curveto
175.1269 +552.64042 201.32561 552.26607 201.40373 551.82336 201.40373 curveto
175.1270 +551.26347 201.40373 550.8175 201.24748 550.48547 200.93498 curveto
175.1271 +550.1567 200.61923 549.99231 200.19768 549.99231 199.67033 curveto
175.1272 +549.99231 199.0551 550.19739 198.59123 550.60754 198.27873 curveto
175.1273 +551.02095 197.96624 551.63619 197.80999 552.45325 197.80998 curveto
175.1274 +553.71301 197.80998 lineto
175.1275 +553.71301 197.72209 lineto
175.1276 +553.71301 197.30868 553.57629 196.98967 553.30286 196.76506 curveto
175.1277 +553.03267 196.5372 552.65181 196.42327 552.16028 196.42326 curveto
175.1278 +551.84778 196.42327 551.54341 196.4607 551.24719 196.53557 curveto
175.1279 +550.95097 196.61044 550.66614 196.72275 550.3927 196.87248 curveto
175.1280 +550.3927 196.0424 lineto
175.1281 +550.72147 195.91546 551.04049 195.82106 551.34973 195.7592 curveto
175.1282 +551.65897 195.6941 551.96008 195.66155 552.25305 195.66154 curveto
175.1283 +553.04406 195.66155 553.63488 195.86663 554.02551 196.27678 curveto
175.1284 +554.41613 196.68694 554.61144 197.30868 554.61145 198.14201 curveto
175.1285 +fill
175.1286 +grestore
175.1287 +gsave
175.1288 +0 0 0 setrgbcolor
175.1289 +newpath
175.1290 +559.95325 195.95451 moveto
175.1291 +559.95325 196.80412 lineto
175.1292 +559.69934 196.67392 559.43567 196.57626 559.16223 196.51115 curveto
175.1293 +558.88879 196.44605 558.60559 196.4135 558.31262 196.4135 curveto
175.1294 +557.86666 196.4135 557.53137 196.48186 557.30676 196.61858 curveto
175.1295 +557.08541 196.7553 556.97473 196.96038 556.97473 197.23381 curveto
175.1296 +556.97473 197.44215 557.05448 197.60654 557.21399 197.72697 curveto
175.1297 +557.37349 197.84417 557.69413 197.95647 558.1759 198.06389 curveto
175.1298 +558.48352 198.13225 lineto
175.1299 +559.12154 198.26897 559.57401 198.46265 559.84094 198.7133 curveto
175.1300 +560.11112 198.9607 560.24621 199.30738 560.24622 199.75334 curveto
175.1301 +560.24621 200.26116 560.04439 200.66317 559.64075 200.9594 curveto
175.1302 +559.24035 201.25562 558.6886 201.40373 557.98547 201.40373 curveto
175.1303 +557.6925 201.40373 557.38651 201.37444 557.0675 201.31584 curveto
175.1304 +556.75175 201.2605 556.41809 201.17587 556.06653 201.06194 curveto
175.1305 +556.06653 200.1342 lineto
175.1306 +556.39856 200.30673 556.72571 200.43694 557.04797 200.52483 curveto
175.1307 +557.37024 200.60946 557.68925 200.65178 558.005 200.65178 curveto
175.1308 +558.42818 200.65178 558.7537 200.58017 558.98157 200.43694 curveto
175.1309 +559.20943 200.29045 559.32336 200.08537 559.32336 199.8217 curveto
175.1310 +559.32336 199.57756 559.24035 199.39039 559.07434 199.26018 curveto
175.1311 +558.91158 199.12997 558.55188 199.00465 557.99524 198.8842 curveto
175.1312 +557.68274 198.81096 lineto
175.1313 +557.1261 198.69377 556.72408 198.51474 556.47668 198.27385 curveto
175.1314 +556.22929 198.02971 556.10559 197.69605 556.10559 197.27287 curveto
175.1315 +556.10559 196.75855 556.28788 196.36142 556.65247 196.08147 curveto
175.1316 +557.01705 195.80152 557.53463 195.66155 558.2052 195.66154 curveto
175.1317 +558.53723 195.66155 558.84973 195.68596 559.1427 195.73479 curveto
175.1318 +559.43567 195.78362 559.70585 195.85686 559.95325 195.95451 curveto
175.1319 +fill
175.1320 +grestore
175.1321 +gsave
175.1322 +0 0 0 setrgbcolor
175.1323 +newpath
175.1324 +565.16809 195.95451 moveto
175.1325 +565.16809 196.80412 lineto
175.1326 +564.91418 196.67392 564.65051 196.57626 564.37708 196.51115 curveto
175.1327 +564.10363 196.44605 563.82043 196.4135 563.52747 196.4135 curveto
175.1328 +563.0815 196.4135 562.74621 196.48186 562.52161 196.61858 curveto
175.1329 +562.30025 196.7553 562.18957 196.96038 562.18958 197.23381 curveto
175.1330 +562.18957 197.44215 562.26933 197.60654 562.42883 197.72697 curveto
175.1331 +562.58834 197.84417 562.90897 197.95647 563.39075 198.06389 curveto
175.1332 +563.69836 198.13225 lineto
175.1333 +564.33638 198.26897 564.78886 198.46265 565.05579 198.7133 curveto
175.1334 +565.32596 198.9607 565.46105 199.30738 565.46106 199.75334 curveto
175.1335 +565.46105 200.26116 565.25923 200.66317 564.85559 200.9594 curveto
175.1336 +564.4552 201.25562 563.90344 201.40373 563.20032 201.40373 curveto
175.1337 +562.90735 201.40373 562.60136 201.37444 562.28235 201.31584 curveto
175.1338 +561.96659 201.2605 561.63293 201.17587 561.28137 201.06194 curveto
175.1339 +561.28137 200.1342 lineto
175.1340 +561.6134 200.30673 561.94055 200.43694 562.26282 200.52483 curveto
175.1341 +562.58508 200.60946 562.90409 200.65178 563.21985 200.65178 curveto
175.1342 +563.64302 200.65178 563.96854 200.58017 564.19641 200.43694 curveto
175.1343 +564.42427 200.29045 564.5382 200.08537 564.53821 199.8217 curveto
175.1344 +564.5382 199.57756 564.4552 199.39039 564.28918 199.26018 curveto
175.1345 +564.12642 199.12997 563.76672 199.00465 563.21008 198.8842 curveto
175.1346 +562.89758 198.81096 lineto
175.1347 +562.34094 198.69377 561.93892 198.51474 561.69153 198.27385 curveto
175.1348 +561.44413 198.02971 561.32043 197.69605 561.32043 197.27287 curveto
175.1349 +561.32043 196.75855 561.50273 196.36142 561.86731 196.08147 curveto
175.1350 +562.23189 195.80152 562.74947 195.66155 563.42004 195.66154 curveto
175.1351 +563.75207 195.66155 564.06457 195.68596 564.35754 195.73479 curveto
175.1352 +564.65051 195.78362 564.92069 195.85686 565.16809 195.95451 curveto
175.1353 +fill
175.1354 +grestore
175.1355 +gsave
175.1356 +0 0 0 setrgbcolor
175.1357 +newpath
175.1358 +566.80383 199.10393 moveto
175.1359 +566.80383 195.79338 lineto
175.1360 +567.70227 195.79338 lineto
175.1361 +567.70227 199.06975 lineto
175.1362 +567.70227 199.58733 567.80318 199.97632 568.005 200.23674 curveto
175.1363 +568.20683 200.4939 568.50956 200.62248 568.91321 200.62248 curveto
175.1364 +569.39823 200.62248 569.78072 200.46786 570.06067 200.15862 curveto
175.1365 +570.34387 199.84937 570.48547 199.42782 570.48547 198.89397 curveto
175.1366 +570.48547 195.79338 lineto
175.1367 +571.38391 195.79338 lineto
175.1368 +571.38391 201.26213 lineto
175.1369 +570.48547 201.26213 lineto
175.1370 +570.48547 200.42229 lineto
175.1371 +570.26737 200.75432 570.01346 201.00171 569.72375 201.16447 curveto
175.1372 +569.43729 201.32398 569.10363 201.40373 568.72278 201.40373 curveto
175.1373 +568.09452 201.40373 567.61763 201.20842 567.29211 200.81779 curveto
175.1374 +566.96659 200.42717 566.80383 199.85588 566.80383 199.10393 curveto
175.1375 +fill
175.1376 +grestore
175.1377 +gsave
175.1378 +0 0 0 setrgbcolor
175.1379 +newpath
175.1380 +577.50208 196.84319 moveto
175.1381 +577.72668 196.43954 577.99523 196.14169 578.30774 195.94963 curveto
175.1382 +578.62023 195.75758 578.98807 195.66155 579.41125 195.66154 curveto
175.1383 +579.98091 195.66155 580.42036 195.86175 580.72961 196.26213 curveto
175.1384 +581.03885 196.65927 581.19347 197.22568 581.19348 197.96135 curveto
175.1385 +581.19348 201.26213 lineto
175.1386 +580.29016 201.26213 lineto
175.1387 +580.29016 197.99065 lineto
175.1388 +580.29015 197.46656 580.19738 197.07756 580.01184 196.82365 curveto
175.1389 +579.82629 196.56975 579.54308 196.4428 579.16223 196.44279 curveto
175.1390 +578.69673 196.4428 578.32889 196.59742 578.05872 196.90666 curveto
175.1391 +577.78853 197.21591 577.65344 197.63746 577.65344 198.17131 curveto
175.1392 +577.65344 201.26213 lineto
175.1393 +576.75012 201.26213 lineto
175.1394 +576.75012 197.99065 lineto
175.1395 +576.75012 197.46331 576.65734 197.07431 576.4718 196.82365 curveto
175.1396 +576.28625 196.56975 575.99979 196.4428 575.61243 196.44279 curveto
175.1397 +575.15344 196.4428 574.78886 196.59905 574.51868 196.91154 curveto
175.1398 +574.24849 197.22079 574.1134 197.64072 574.1134 198.17131 curveto
175.1399 +574.1134 201.26213 lineto
175.1400 +573.21008 201.26213 lineto
175.1401 +573.21008 195.79338 lineto
175.1402 +574.1134 195.79338 lineto
175.1403 +574.1134 196.64299 lineto
175.1404 +574.31848 196.30771 574.56425 196.06031 574.85071 195.9008 curveto
175.1405 +575.13716 195.7413 575.47733 195.66155 575.87122 195.66154 curveto
175.1406 +576.26835 195.66155 576.60526 195.76246 576.88196 195.96428 curveto
175.1407 +577.1619 196.16611 577.36861 196.45908 577.50208 196.84319 curveto
175.1408 +fill
175.1409 +grestore
175.1410 +gsave
175.1411 +0 0 0 setrgbcolor
175.1412 +newpath
175.1413 +587.66809 198.30315 moveto
175.1414 +587.66809 198.7426 lineto
175.1415 +583.53723 198.7426 lineto
175.1416 +583.57629 199.36109 583.76184 199.8331 584.09387 200.15862 curveto
175.1417 +584.42916 200.48088 584.89465 200.64201 585.49036 200.64201 curveto
175.1418 +585.8354 200.64201 586.16906 200.5997 586.49133 200.51506 curveto
175.1419 +586.81685 200.43043 587.13911 200.30347 587.45813 200.1342 curveto
175.1420 +587.45813 200.98381 lineto
175.1421 +587.13586 201.12053 586.80546 201.2247 586.46692 201.29631 curveto
175.1422 +586.12837 201.36792 585.78495 201.40373 585.43665 201.40373 curveto
175.1423 +584.56425 201.40373 583.87252 201.14983 583.36145 200.64201 curveto
175.1424 +582.85364 200.1342 582.59973 199.44735 582.59973 198.58147 curveto
175.1425 +582.59973 197.68629 582.84062 196.97665 583.32239 196.45256 curveto
175.1426 +583.80741 195.92522 584.46008 195.66155 585.2804 195.66154 curveto
175.1427 +586.01607 195.66155 586.59712 195.89918 587.02356 196.37444 curveto
175.1428 +587.45324 196.84645 587.66809 197.48935 587.66809 198.30315 curveto
175.1429 +586.76965 198.03947 moveto
175.1430 +586.76314 197.54794 586.62479 197.15569 586.35461 196.86272 curveto
175.1431 +586.08768 196.56975 585.73287 196.42327 585.29016 196.42326 curveto
175.1432 +584.78886 196.42327 584.38684 196.56487 584.08411 196.84807 curveto
175.1433 +583.78463 197.13128 583.6121 197.53004 583.56653 198.04436 curveto
175.1434 +586.76965 198.03947 lineto
175.1435 +fill
175.1436 +grestore
175.1437 +gsave
175.1438 +0 0 0 setrgbcolor
175.1439 +newpath
175.1440 +553.82532 147.89853 moveto
175.1441 +553.82532 148.60165 lineto
175.1442 +553.52258 148.60165 lineto
175.1443 +552.71203 148.60165 552.16841 148.48121 551.89172 148.24033 curveto
175.1444 +551.61828 147.99944 551.48156 147.5193 551.48157 146.7999 curveto
175.1445 +551.48157 145.6329 lineto
175.1446 +551.48156 145.14137 551.39367 144.8012 551.2179 144.6124 curveto
175.1447 +551.04211 144.4236 550.7231 144.3292 550.26086 144.32919 curveto
175.1448 +549.96301 144.32919 lineto
175.1449 +549.96301 143.63095 lineto
175.1450 +550.26086 143.63095 lineto
175.1451 +550.72636 143.63095 551.04537 143.53818 551.2179 143.35263 curveto
175.1452 +551.39367 143.16383 551.48156 142.82692 551.48157 142.34189 curveto
175.1453 +551.48157 141.17001 lineto
175.1454 +551.48156 140.45062 551.61828 139.9721 551.89172 139.73447 curveto
175.1455 +552.16841 139.49359 552.71203 139.37315 553.52258 139.37314 curveto
175.1456 +553.82532 139.37314 lineto
175.1457 +553.82532 140.07138 lineto
175.1458 +553.49329 140.07138 lineto
175.1459 +553.0343 140.07139 552.73482 140.143 552.59485 140.28622 curveto
175.1460 +552.45487 140.42946 552.38488 140.73057 552.38489 141.18954 curveto
175.1461 +552.38489 142.40048 lineto
175.1462 +552.38488 142.91155 552.31001 143.28265 552.16028 143.51376 curveto
175.1463 +552.01379 143.74489 551.76151 143.90114 551.40344 143.98251 curveto
175.1464 +551.76477 144.07041 552.01867 144.22991 552.16516 144.46103 curveto
175.1465 +552.31164 144.69215 552.38488 145.06162 552.38489 145.56943 curveto
175.1466 +552.38489 146.78036 lineto
175.1467 +552.38488 147.23935 552.45487 147.54046 552.59485 147.68369 curveto
175.1468 +552.73482 147.82691 553.0343 147.89853 553.49329 147.89853 curveto
175.1469 +553.82532 147.89853 lineto
175.1470 +fill
175.1471 +grestore
175.1472 +gsave
175.1473 +0 0 0 setrgbcolor
175.1474 +newpath
175.1475 +fill
175.1476 +grestore
175.1477 +gsave
175.1478 +0 0 0 setrgbcolor
175.1479 +newpath
175.1480 +559.51379 147.89853 moveto
175.1481 +559.85559 147.89853 lineto
175.1482 +560.31132 147.89853 560.60754 147.82854 560.74426 147.68857 curveto
175.1483 +560.88423 147.54859 560.95422 147.24586 560.95422 146.78036 curveto
175.1484 +560.95422 145.56943 lineto
175.1485 +560.95422 145.06162 561.02746 144.69215 561.17395 144.46103 curveto
175.1486 +561.32043 144.22991 561.57434 144.07041 561.93567 143.98251 curveto
175.1487 +561.57434 143.90114 561.32043 143.74489 561.17395 143.51376 curveto
175.1488 +561.02746 143.28265 560.95422 142.91155 560.95422 142.40048 curveto
175.1489 +560.95422 141.18954 lineto
175.1490 +560.95422 140.72731 560.88423 140.4262 560.74426 140.28622 curveto
175.1491 +560.60754 140.143 560.31132 140.07139 559.85559 140.07138 curveto
175.1492 +559.51379 140.07138 lineto
175.1493 +559.51379 139.37314 lineto
175.1494 +559.82141 139.37314 lineto
175.1495 +560.63196 139.37315 561.17232 139.49359 561.4425 139.73447 curveto
175.1496 +561.71594 139.9721 561.85266 140.45062 561.85266 141.17001 curveto
175.1497 +561.85266 142.34189 lineto
175.1498 +561.85266 142.82692 561.94055 143.16383 562.11633 143.35263 curveto
175.1499 +562.29211 143.53818 562.61112 143.63095 563.07336 143.63095 curveto
175.1500 +563.3761 143.63095 lineto
175.1501 +563.3761 144.32919 lineto
175.1502 +563.07336 144.32919 lineto
175.1503 +562.61112 144.3292 562.29211 144.4236 562.11633 144.6124 curveto
175.1504 +561.94055 144.8012 561.85266 145.14137 561.85266 145.6329 curveto
175.1505 +561.85266 146.7999 lineto
175.1506 +561.85266 147.5193 561.71594 147.99944 561.4425 148.24033 curveto
175.1507 +561.17232 148.48121 560.63196 148.60165 559.82141 148.60165 curveto
175.1508 +559.51379 148.60165 lineto
175.1509 +559.51379 147.89853 lineto
175.1510 +fill
175.1511 +grestore
175.1512 +gsave
175.1513 +0 0 0 setrgbcolor
175.1514 +newpath
175.1515 +554.20129 153.67001 moveto
175.1516 +554.20129 156.97079 lineto
175.1517 +553.30286 156.97079 lineto
175.1518 +553.30286 153.69931 lineto
175.1519 +553.30285 153.18174 553.20194 152.79437 553.00012 152.5372 curveto
175.1520 +552.7983 152.28004 552.49556 152.15146 552.09192 152.15146 curveto
175.1521 +551.60689 152.15146 551.2244 152.30609 550.94446 152.61533 curveto
175.1522 +550.66451 152.92457 550.52453 153.34612 550.52454 153.87997 curveto
175.1523 +550.52454 156.97079 lineto
175.1524 +549.62122 156.97079 lineto
175.1525 +549.62122 151.50204 lineto
175.1526 +550.52454 151.50204 lineto
175.1527 +550.52454 152.35165 lineto
175.1528 +550.73938 152.02288 550.99166 151.77711 551.28137 151.61435 curveto
175.1529 +551.57434 151.45159 551.91125 151.37021 552.29211 151.37021 curveto
175.1530 +552.92037 151.37021 553.39563 151.56553 553.7179 151.95615 curveto
175.1531 +554.04016 152.34352 554.20129 152.91481 554.20129 153.67001 curveto
175.1532 +fill
175.1533 +grestore
175.1534 +gsave
175.1535 +0 0 0 setrgbcolor
175.1536 +newpath
175.1537 +560.68079 154.01181 moveto
175.1538 +560.68079 154.45126 lineto
175.1539 +556.54993 154.45126 lineto
175.1540 +556.58899 155.06975 556.77453 155.54176 557.10657 155.86728 curveto
175.1541 +557.44185 156.18955 557.90735 156.35068 558.50305 156.35068 curveto
175.1542 +558.8481 156.35068 559.18176 156.30836 559.50403 156.22372 curveto
175.1543 +559.82954 156.13909 560.15181 156.01214 560.47083 155.84286 curveto
175.1544 +560.47083 156.69247 lineto
175.1545 +560.14855 156.82919 559.81815 156.93336 559.47961 157.00497 curveto
175.1546 +559.14107 157.07659 558.79764 157.1124 558.44934 157.1124 curveto
175.1547 +557.57694 157.1124 556.88521 156.85849 556.37415 156.35068 curveto
175.1548 +555.86633 155.84287 555.61243 155.15602 555.61243 154.29013 curveto
175.1549 +555.61243 153.39495 555.85331 152.68532 556.33508 152.16122 curveto
175.1550 +556.82011 151.63389 557.47278 151.37021 558.29309 151.37021 curveto
175.1551 +559.02876 151.37021 559.60982 151.60784 560.03625 152.0831 curveto
175.1552 +560.46594 152.55511 560.68078 153.19801 560.68079 154.01181 curveto
175.1553 +559.78235 153.74814 moveto
175.1554 +559.77583 153.25661 559.63749 152.86435 559.36731 152.57138 curveto
175.1555 +559.10038 152.27842 558.74556 152.13193 558.30286 152.13193 curveto
175.1556 +557.80155 152.13193 557.39953 152.27353 557.0968 152.55673 curveto
175.1557 +556.79732 152.83994 556.62479 153.2387 556.57922 153.75302 curveto
175.1558 +559.78235 153.74814 lineto
175.1559 +fill
175.1560 +grestore
175.1561 +gsave
175.1562 +0 0 0 setrgbcolor
175.1563 +newpath
175.1564 +566.52551 151.50204 moveto
175.1565 +564.54797 154.16318 lineto
175.1566 +566.62805 156.97079 lineto
175.1567 +565.56848 156.97079 lineto
175.1568 +563.97668 154.82236 lineto
175.1569 +562.38489 156.97079 lineto
175.1570 +561.32532 156.97079 lineto
175.1571 +563.44934 154.10947 lineto
175.1572 +561.50598 151.50204 lineto
175.1573 +562.56555 151.50204 lineto
175.1574 +564.01575 153.45029 lineto
175.1575 +565.46594 151.50204 lineto
175.1576 +566.52551 151.50204 lineto
175.1577 +fill
175.1578 +grestore
175.1579 +gsave
175.1580 +0 0 0 setrgbcolor
175.1581 +newpath
175.1582 +568.78625 149.94931 moveto
175.1583 +568.78625 151.50204 lineto
175.1584 +570.63684 151.50204 lineto
175.1585 +570.63684 152.20029 lineto
175.1586 +568.78625 152.20029 lineto
175.1587 +568.78625 155.16904 lineto
175.1588 +568.78625 155.615 568.84647 155.90146 568.96692 156.02841 curveto
175.1589 +569.09061 156.15537 569.33964 156.21884 569.71399 156.21884 curveto
175.1590 +570.63684 156.21884 lineto
175.1591 +570.63684 156.97079 lineto
175.1592 +569.71399 156.97079 lineto
175.1593 +569.02063 156.97079 568.54211 156.84221 568.27844 156.58505 curveto
175.1594 +568.01477 156.32464 567.88293 155.85263 567.88293 155.16904 curveto
175.1595 +567.88293 152.20029 lineto
175.1596 +567.22375 152.20029 lineto
175.1597 +567.22375 151.50204 lineto
175.1598 +567.88293 151.50204 lineto
175.1599 +567.88293 149.94931 lineto
175.1600 +568.78625 149.94931 lineto
175.1601 +fill
175.1602 +grestore
175.1603 +gsave
175.1604 +0 0 0 setrgbcolor
175.1605 +newpath
175.1606 +483.33514 94.963516 moveto
175.1607 +483.33514 98.264297 lineto
175.1608 +482.43671 98.264297 lineto
175.1609 +482.43671 94.992813 lineto
175.1610 +482.4367 94.475239 482.33579 94.087869 482.13397 93.830704 curveto
175.1611 +481.93215 93.573547 481.62941 93.444966 481.22577 93.444962 curveto
175.1612 +480.74074 93.444966 480.35825 93.599589 480.07831 93.908829 curveto
175.1613 +479.79836 94.218078 479.65838 94.639627 479.65839 95.173477 curveto
175.1614 +479.65839 98.264297 lineto
175.1615 +478.75507 98.264297 lineto
175.1616 +478.75507 92.795547 lineto
175.1617 +479.65839 92.795547 lineto
175.1618 +479.65839 93.645157 lineto
175.1619 +479.87323 93.316386 480.12551 93.070618 480.41522 92.907852 curveto
175.1620 +480.70819 92.745097 481.0451 92.663717 481.42596 92.663712 curveto
175.1621 +482.05422 92.663717 482.52948 92.859029 482.85175 93.249649 curveto
175.1622 +483.17401 93.637023 483.33514 94.208312 483.33514 94.963516 curveto
175.1623 +fill
175.1624 +grestore
175.1625 +gsave
175.1626 +0 0 0 setrgbcolor
175.1627 +newpath
175.1628 +487.25604 93.42543 moveto
175.1629 +486.77427 93.425435 486.39341 93.614237 486.11346 93.991837 curveto
175.1630 +485.83351 94.366189 485.69354 94.880512 485.69354 95.534805 curveto
175.1631 +485.69354 96.189104 485.83189 96.705054 486.10858 97.082657 curveto
175.1632 +486.38853 97.457007 486.77101 97.644181 487.25604 97.64418 curveto
175.1633 +487.73455 97.644181 488.11379 97.455379 488.39374 97.077774 curveto
175.1634 +488.67368 96.700171 488.81366 96.185849 488.81366 95.534805 curveto
175.1635 +488.81366 94.887022 488.67368 94.374327 488.39374 93.996719 curveto
175.1636 +488.11379 93.615865 487.73455 93.425435 487.25604 93.42543 curveto
175.1637 +487.25604 92.663712 moveto
175.1638 +488.03729 92.663717 488.65089 92.917623 489.09686 93.42543 curveto
175.1639 +489.54282 93.933247 489.7658 94.636371 489.76581 95.534805 curveto
175.1640 +489.7658 96.429989 489.54282 97.133114 489.09686 97.64418 curveto
175.1641 +488.65089 98.151993 488.03729 98.405899 487.25604 98.405899 curveto
175.1642 +486.47153 98.405899 485.8563 98.151993 485.41034 97.64418 curveto
175.1643 +484.96763 97.133114 484.74628 96.429989 484.74628 95.534805 curveto
175.1644 +484.74628 94.636371 484.96763 93.933247 485.41034 93.42543 curveto
175.1645 +485.8563 92.917623 486.47153 92.663717 487.25604 92.663712 curveto
175.1646 +fill
175.1647 +grestore
175.1648 +gsave
175.1649 +0 0 0 setrgbcolor
175.1650 +newpath
175.1651 +492.13885 91.242813 moveto
175.1652 +492.13885 92.795547 lineto
175.1653 +493.98944 92.795547 lineto
175.1654 +493.98944 93.49379 lineto
175.1655 +492.13885 93.49379 lineto
175.1656 +492.13885 96.46254 lineto
175.1657 +492.13885 96.908505 492.19907 97.194963 492.31952 97.321915 curveto
175.1658 +492.44321 97.448869 492.69224 97.512345 493.06659 97.512344 curveto
175.1659 +493.98944 97.512344 lineto
175.1660 +493.98944 98.264297 lineto
175.1661 +493.06659 98.264297 lineto
175.1662 +492.37323 98.264297 491.89471 98.135717 491.63104 97.878555 curveto
175.1663 +491.36737 97.618139 491.23553 97.146135 491.23553 96.46254 curveto
175.1664 +491.23553 93.49379 lineto
175.1665 +490.57635 93.49379 lineto
175.1666 +490.57635 92.795547 lineto
175.1667 +491.23553 92.795547 lineto
175.1668 +491.23553 91.242813 lineto
175.1669 +492.13885 91.242813 lineto
175.1670 +fill
175.1671 +grestore
175.1672 +gsave
175.1673 +0 0 0 setrgbcolor
175.1674 +newpath
175.1675 +499.8537 95.305313 moveto
175.1676 +499.8537 95.744766 lineto
175.1677 +495.72284 95.744766 lineto
175.1678 +495.7619 96.363258 495.94745 96.835262 496.27948 97.160782 curveto
175.1679 +496.61476 97.483048 497.08026 97.644181 497.67596 97.64418 curveto
175.1680 +498.02101 97.644181 498.35467 97.601863 498.67694 97.517227 curveto
175.1681 +499.00246 97.432593 499.32472 97.30564 499.64374 97.136368 curveto
175.1682 +499.64374 97.985977 lineto
175.1683 +499.32147 98.122696 498.99106 98.226863 498.65253 98.298477 curveto
175.1684 +498.31398 98.370092 497.97056 98.405899 497.62225 98.405899 curveto
175.1685 +496.74986 98.405899 496.05812 98.151993 495.54706 97.64418 curveto
175.1686 +495.03924 97.136369 494.78534 96.449521 494.78534 95.583633 curveto
175.1687 +494.78534 94.688455 495.02622 93.97882 495.508 93.454727 curveto
175.1688 +495.99302 92.927389 496.64569 92.663717 497.466 92.663712 curveto
175.1689 +498.20168 92.663717 498.78273 92.901347 499.20917 93.376602 curveto
175.1690 +499.63885 93.848612 499.85369 94.491515 499.8537 95.305313 curveto
175.1691 +498.95526 95.041641 moveto
175.1692 +498.94875 94.550108 498.8104 94.157856 498.54022 93.864883 curveto
175.1693 +498.27329 93.571919 497.91847 93.425435 497.47577 93.42543 curveto
175.1694 +496.97446 93.425435 496.57245 93.567037 496.26971 93.850235 curveto
175.1695 +495.97023 94.133442 495.79771 94.532205 495.75214 95.046524 curveto
175.1696 +498.95526 95.041641 lineto
175.1697 +fill
175.1698 +grestore
175.1699 +gsave
175.1700 +0 0 0 setrgbcolor
175.1701 +newpath
175.1702 +478.78925 100.66664 moveto
175.1703 +479.68768 100.66664 lineto
175.1704 +479.68768 108.2643 lineto
175.1705 +478.78925 108.2643 lineto
175.1706 +478.78925 100.66664 lineto
175.1707 +fill
175.1708 +grestore
175.1709 +gsave
175.1710 +0 0 0 setrgbcolor
175.1711 +newpath
175.1712 +486.24042 105.30531 moveto
175.1713 +486.24042 105.74477 lineto
175.1714 +482.10956 105.74477 lineto
175.1715 +482.14862 106.36326 482.33417 106.83526 482.6662 107.16078 curveto
175.1716 +483.00148 107.48305 483.46698 107.64418 484.06268 107.64418 curveto
175.1717 +484.40773 107.64418 484.74139 107.60186 485.06366 107.51723 curveto
175.1718 +485.38918 107.43259 485.71144 107.30564 486.03046 107.13637 curveto
175.1719 +486.03046 107.98598 lineto
175.1720 +485.70819 108.1227 485.37778 108.22686 485.03925 108.29848 curveto
175.1721 +484.7007 108.37009 484.35728 108.4059 484.00897 108.4059 curveto
175.1722 +483.13657 108.4059 482.44484 108.15199 481.93378 107.64418 curveto
175.1723 +481.42596 107.13637 481.17206 106.44952 481.17206 105.58363 curveto
175.1724 +481.17206 104.68845 481.41294 103.97882 481.89471 103.45473 curveto
175.1725 +482.37974 102.92739 483.03241 102.66372 483.85272 102.66371 curveto
175.1726 +484.5884 102.66372 485.16945 102.90135 485.59589 103.3766 curveto
175.1727 +486.02557 103.84861 486.24041 104.49151 486.24042 105.30531 curveto
175.1728 +485.34198 105.04164 moveto
175.1729 +485.33546 104.55011 485.19712 104.15786 484.92694 103.86488 curveto
175.1730 +484.66001 103.57192 484.30519 103.42544 483.86249 103.42543 curveto
175.1731 +483.36118 103.42544 482.95917 103.56704 482.65643 103.85023 curveto
175.1732 +482.35695 104.13344 482.18443 104.5322 482.13885 105.04652 curveto
175.1733 +485.34198 105.04164 lineto
175.1734 +fill
175.1735 +grestore
175.1736 +gsave
175.1737 +0 0 0 setrgbcolor
175.1738 +newpath
175.1739 +488.6037 101.24281 moveto
175.1740 +488.6037 102.79555 lineto
175.1741 +490.45428 102.79555 lineto
175.1742 +490.45428 103.49379 lineto
175.1743 +488.6037 103.49379 lineto
175.1744 +488.6037 106.46254 lineto
175.1745 +488.6037 106.9085 488.66392 107.19496 488.78436 107.32191 curveto
175.1746 +488.90806 107.44887 489.15708 107.51235 489.53143 107.51234 curveto
175.1747 +490.45428 107.51234 lineto
175.1748 +490.45428 108.2643 lineto
175.1749 +489.53143 108.2643 lineto
175.1750 +488.83807 108.2643 488.35956 108.13572 488.09589 107.87856 curveto
175.1751 +487.83221 107.61814 487.70038 107.14613 487.70038 106.46254 curveto
175.1752 +487.70038 103.49379 lineto
175.1753 +487.0412 103.49379 lineto
175.1754 +487.0412 102.79555 lineto
175.1755 +487.70038 102.79555 lineto
175.1756 +487.70038 101.24281 lineto
175.1757 +488.6037 101.24281 lineto
175.1758 +fill
175.1759 +grestore
175.1760 +gsave
175.1761 +0 0 0 setrgbcolor
175.1762 +newpath
175.1763 +44.641342 188.13469 moveto
175.1764 +44.641342 184.82414 lineto
175.1765 +45.53978 184.82414 lineto
175.1766 +45.53978 188.10051 lineto
175.1767 +45.539778 188.61809 45.640689 189.00709 45.842514 189.2675 curveto
175.1768 +46.044335 189.52466 46.347069 189.65324 46.750717 189.65324 curveto
175.1769 +47.23574 189.65324 47.618226 189.49862 47.898178 189.18938 curveto
175.1770 +48.181377 188.88013 48.322978 188.45858 48.322983 187.92473 curveto
175.1771 +48.322983 184.82414 lineto
175.1772 +49.22142 184.82414 lineto
175.1773 +49.22142 190.29289 lineto
175.1774 +48.322983 190.29289 lineto
175.1775 +48.322983 189.45305 lineto
175.1776 +48.10488 189.78508 47.850974 190.03248 47.561264 190.19524 curveto
175.1777 +47.274802 190.35474 46.941144 190.43449 46.560287 190.43449 curveto
175.1778 +45.93203 190.43449 45.455143 190.23918 45.129623 189.84856 curveto
175.1779 +44.804102 189.45793 44.641341 188.88664 44.641342 188.13469 curveto
175.1780 +fill
175.1781 +grestore
175.1782 +gsave
175.1783 +0 0 0 setrgbcolor
175.1784 +newpath
175.1785 +54.5681 184.98528 moveto
175.1786 +54.5681 185.83488 lineto
175.1787 +54.31419 185.70468 54.050518 185.60702 53.777084 185.54192 curveto
175.1788 +53.503643 185.47682 53.220441 185.44426 52.927475 185.44426 curveto
175.1789 +52.481509 185.44426 52.146223 185.51262 51.921616 185.64934 curveto
175.1790 +51.70026 185.78606 51.589583 185.99114 51.589584 186.26457 curveto
175.1791 +51.589583 186.47291 51.669335 186.6373 51.828842 186.75774 curveto
175.1792 +51.988346 186.87493 52.308983 186.98723 52.790756 187.09465 curveto
175.1793 +53.098373 187.16301 lineto
175.1794 +53.736391 187.29973 54.188864 187.49342 54.455795 187.74406 curveto
175.1795 +54.725973 187.99146 54.861064 188.33814 54.861069 188.7841 curveto
175.1796 +54.861064 189.29192 54.659241 189.69393 54.2556 189.99016 curveto
175.1797 +53.855206 190.28638 53.303448 190.43449 52.600327 190.43449 curveto
175.1798 +52.307356 190.43449 52.001366 190.4052 51.682358 190.3466 curveto
175.1799 +51.366601 190.29126 51.032943 190.20663 50.681381 190.0927 curveto
175.1800 +50.681381 189.16496 lineto
175.1801 +51.013412 189.33749 51.34056 189.4677 51.662827 189.55559 curveto
175.1802 +51.98509 189.64022 52.3041 189.68254 52.619858 189.68254 curveto
175.1803 +53.043032 189.68254 53.368552 189.61093 53.59642 189.4677 curveto
175.1804 +53.824281 189.32121 53.938213 189.11614 53.938217 188.85246 curveto
175.1805 +53.938213 188.60832 53.855206 188.42115 53.689194 188.29094 curveto
175.1806 +53.52643 188.16073 53.16673 188.03541 52.610092 187.91496 curveto
175.1807 +52.297592 187.84172 lineto
175.1808 +51.74095 187.72454 51.338932 187.5455 51.091537 187.30461 curveto
175.1809 +50.844141 187.06047 50.720443 186.72682 50.720444 186.30363 curveto
175.1810 +50.720443 185.78932 50.902735 185.39218 51.267319 185.11223 curveto
175.1811 +51.631901 184.83229 52.149478 184.69231 52.820053 184.69231 curveto
175.1812 +53.152081 184.69231 53.464581 184.71673 53.757553 184.76555 curveto
175.1813 +54.050518 184.81438 54.3207 184.88762 54.5681 184.98528 curveto
175.1814 +fill
175.1815 +grestore
175.1816 +gsave
175.1817 +0 0 0 setrgbcolor
175.1818 +newpath
175.1819 +56.296616 184.82414 moveto
175.1820 +57.195053 184.82414 lineto
175.1821 +57.195053 190.29289 lineto
175.1822 +56.296616 190.29289 lineto
175.1823 +56.296616 184.82414 lineto
175.1824 +56.296616 182.69524 moveto
175.1825 +57.195053 182.69524 lineto
175.1826 +57.195053 183.83293 lineto
175.1827 +56.296616 183.83293 lineto
175.1828 +56.296616 182.69524 lineto
175.1829 +fill
175.1830 +grestore
175.1831 +gsave
175.1832 +0 0 0 setrgbcolor
175.1833 +newpath
175.1834 +63.615952 186.99211 moveto
175.1835 +63.615952 190.29289 lineto
175.1836 +62.717514 190.29289 lineto
175.1837 +62.717514 187.02141 lineto
175.1838 +62.717509 186.50383 62.616598 186.11646 62.41478 185.8593 curveto
175.1839 +62.212953 185.60214 61.910219 185.47356 61.506577 185.47356 curveto
175.1840 +61.021548 185.47356 60.639061 185.62818 60.359116 185.93742 curveto
175.1841 +60.079166 186.24667 59.939192 186.66822 59.939194 187.20207 curveto
175.1842 +59.939194 190.29289 lineto
175.1843 +59.035873 190.29289 lineto
175.1844 +59.035873 184.82414 lineto
175.1845 +59.939194 184.82414 lineto
175.1846 +59.939194 185.67375 lineto
175.1847 +60.154035 185.34498 60.406314 185.09921 60.69603 184.93645 curveto
175.1848 +60.988996 184.77369 61.325909 184.69231 61.706772 184.69231 curveto
175.1849 +62.335023 184.69231 62.810283 184.88762 63.132553 185.27824 curveto
175.1850 +63.454813 185.66562 63.615946 186.23691 63.615952 186.99211 curveto
175.1851 +fill
175.1852 +grestore
175.1853 +gsave
175.1854 +0 0 0 setrgbcolor
175.1855 +newpath
175.1856 +69.016342 187.49504 moveto
175.1857 +69.016338 186.844 68.881247 186.33945 68.611069 185.98137 curveto
175.1858 +68.344138 185.6233 67.968162 185.44426 67.483139 185.44426 curveto
175.1859 +67.001366 185.44426 66.625389 185.6233 66.355209 185.98137 curveto
175.1860 +66.088281 186.33945 65.954817 186.844 65.954819 187.49504 curveto
175.1861 +65.954817 188.14283 66.088281 188.64576 66.355209 189.00383 curveto
175.1862 +66.625389 189.3619 67.001366 189.54094 67.483139 189.54094 curveto
175.1863 +67.968162 189.54094 68.344138 189.3619 68.611069 189.00383 curveto
175.1864 +68.881247 188.64576 69.016338 188.14283 69.016342 187.49504 curveto
175.1865 +69.91478 189.61418 moveto
175.1866 +69.914774 190.54517 69.708069 191.2369 69.294662 191.68938 curveto
175.1867 +68.881247 192.1451 68.248109 192.37297 67.395248 192.37297 curveto
175.1868 +67.079491 192.37297 66.781639 192.34855 66.501694 192.29973 curveto
175.1869 +66.221744 192.25415 65.949934 192.18254 65.686264 192.08488 curveto
175.1870 +65.686264 191.21086 lineto
175.1871 +65.949934 191.35409 66.210351 191.45988 66.467514 191.52824 curveto
175.1872 +66.724673 191.5966 66.986717 191.63078 67.253647 191.63078 curveto
175.1873 +67.842836 191.63078 68.283916 191.47616 68.576889 191.16692 curveto
175.1874 +68.869853 190.86093 69.016338 190.39706 69.016342 189.77531 curveto
175.1875 +69.016342 189.33098 lineto
175.1876 +68.830791 189.65324 68.593161 189.89413 68.303452 190.05363 curveto
175.1877 +68.013734 190.21314 67.667055 190.29289 67.263412 190.29289 curveto
175.1878 +66.592837 190.29289 66.052473 190.03736 65.642319 189.52629 curveto
175.1879 +65.232162 189.01522 65.027084 188.33814 65.027084 187.49504 curveto
175.1880 +65.027084 186.64869 65.232162 185.96998 65.642319 185.45891 curveto
175.1881 +66.052473 184.94785 66.592837 184.69231 67.263412 184.69231 curveto
175.1882 +67.667055 184.69231 68.013734 184.77206 68.303452 184.93156 curveto
175.1883 +68.593161 185.09107 68.830791 185.33196 69.016342 185.65422 curveto
175.1884 +69.016342 184.82414 lineto
175.1885 +69.91478 184.82414 lineto
175.1886 +69.91478 189.61418 lineto
175.1887 +fill
175.1888 +grestore
175.1889 +gsave
175.1890 +0 0 0 setrgbcolor
175.1891 +newpath
175.1892 +44.641342 198.13469 moveto
175.1893 +44.641342 194.82414 lineto
175.1894 +45.53978 194.82414 lineto
175.1895 +45.53978 198.10051 lineto
175.1896 +45.539778 198.61809 45.640689 199.00709 45.842514 199.2675 curveto
175.1897 +46.044335 199.52466 46.347069 199.65324 46.750717 199.65324 curveto
175.1898 +47.23574 199.65324 47.618226 199.49862 47.898178 199.18938 curveto
175.1899 +48.181377 198.88013 48.322978 198.45858 48.322983 197.92473 curveto
175.1900 +48.322983 194.82414 lineto
175.1901 +49.22142 194.82414 lineto
175.1902 +49.22142 200.29289 lineto
175.1903 +48.322983 200.29289 lineto
175.1904 +48.322983 199.45305 lineto
175.1905 +48.10488 199.78508 47.850974 200.03248 47.561264 200.19524 curveto
175.1906 +47.274802 200.35474 46.941144 200.43449 46.560287 200.43449 curveto
175.1907 +45.93203 200.43449 45.455143 200.23918 45.129623 199.84856 curveto
175.1908 +44.804102 199.45793 44.641341 198.88664 44.641342 198.13469 curveto
175.1909 +fill
175.1910 +grestore
175.1911 +gsave
175.1912 +0 0 0 setrgbcolor
175.1913 +newpath
175.1914 +55.62767 196.99211 moveto
175.1915 +55.62767 200.29289 lineto
175.1916 +54.729233 200.29289 lineto
175.1917 +54.729233 197.02141 lineto
175.1918 +54.729228 196.50383 54.628317 196.11646 54.426498 195.8593 curveto
175.1919 +54.224671 195.60214 53.921937 195.47356 53.518295 195.47356 curveto
175.1920 +53.033266 195.47356 52.65078 195.62818 52.370834 195.93742 curveto
175.1921 +52.090884 196.24667 51.950911 196.66822 51.950912 197.20207 curveto
175.1922 +51.950912 200.29289 lineto
175.1923 +51.047592 200.29289 lineto
175.1924 +51.047592 194.82414 lineto
175.1925 +51.950912 194.82414 lineto
175.1926 +51.950912 195.67375 lineto
175.1927 +52.165754 195.34498 52.418033 195.09921 52.707748 194.93645 curveto
175.1928 +53.000714 194.77369 53.337628 194.69231 53.718491 194.69231 curveto
175.1929 +54.346742 194.69231 54.822002 194.88762 55.144272 195.27824 curveto
175.1930 +55.466532 195.66562 55.627665 196.23691 55.62767 196.99211 curveto
175.1931 +fill
175.1932 +grestore
175.1933 +gsave
175.1934 +0 0 0 setrgbcolor
175.1935 +newpath
175.1936 +60.197983 192.69524 moveto
175.1937 +60.197983 193.44231 lineto
175.1938 +59.338608 193.44231 lineto
175.1939 +59.01634 193.44231 58.79173 193.50742 58.66478 193.63762 curveto
175.1940 +58.54108 193.76783 58.479231 194.00221 58.479233 194.34074 curveto
175.1941 +58.479233 194.82414 lineto
175.1942 +59.958725 194.82414 lineto
175.1943 +59.958725 195.52238 lineto
175.1944 +58.479233 195.52238 lineto
175.1945 +58.479233 200.29289 lineto
175.1946 +57.575912 200.29289 lineto
175.1947 +57.575912 195.52238 lineto
175.1948 +56.716537 195.52238 lineto
175.1949 +56.716537 194.82414 lineto
175.1950 +57.575912 194.82414 lineto
175.1951 +57.575912 194.44328 lineto
175.1952 +57.575911 193.83457 57.717513 193.39186 58.000717 193.11516 curveto
175.1953 +58.283918 192.83522 58.733137 192.69524 59.348373 192.69524 curveto
175.1954 +60.197983 192.69524 lineto
175.1955 +fill
175.1956 +grestore
175.1957 +gsave
175.1958 +0 0 0 setrgbcolor
175.1959 +newpath
175.1960 +63.064194 195.45403 moveto
175.1961 +62.58242 195.45403 62.201561 195.64283 61.921616 196.02043 curveto
175.1962 +61.641666 196.39478 61.501692 196.90911 61.501694 197.5634 curveto
175.1963 +61.501692 198.2177 61.640038 198.73365 61.916733 199.11125 curveto
175.1964 +62.196679 199.4856 62.579165 199.67278 63.064194 199.67278 curveto
175.1965 +63.542706 199.67278 63.921937 199.48397 64.201889 199.10637 curveto
175.1966 +64.481832 198.72877 64.621806 198.21444 64.621811 197.5634 curveto
175.1967 +64.621806 196.91562 64.481832 196.40292 64.201889 196.02531 curveto
175.1968 +63.921937 195.64446 63.542706 195.45403 63.064194 195.45403 curveto
175.1969 +63.064194 194.69231 moveto
175.1970 +63.84544 194.69231 64.459046 194.94622 64.905014 195.45403 curveto
175.1971 +65.350972 195.96184 65.573954 196.66497 65.573959 197.5634 curveto
175.1972 +65.573954 198.45858 65.350972 199.16171 64.905014 199.67278 curveto
175.1973 +64.459046 200.18059 63.84544 200.43449 63.064194 200.43449 curveto
175.1974 +62.279686 200.43449 61.664452 200.18059 61.218491 199.67278 curveto
175.1975 +60.775781 199.16171 60.554428 198.45858 60.554428 197.5634 curveto
175.1976 +60.554428 196.66497 60.775781 195.96184 61.218491 195.45403 curveto
175.1977 +61.664452 194.94622 62.279686 194.69231 63.064194 194.69231 curveto
175.1978 +fill
175.1979 +grestore
175.1980 +gsave
175.1981 +0 0 0 setrgbcolor
175.1982 +newpath
175.1983 +67.058334 192.69524 moveto
175.1984 +67.956772 192.69524 lineto
175.1985 +67.956772 200.29289 lineto
175.1986 +67.058334 200.29289 lineto
175.1987 +67.058334 192.69524 lineto
175.1988 +fill
175.1989 +grestore
175.1990 +gsave
175.1991 +0 0 0 setrgbcolor
175.1992 +newpath
175.1993 +73.430405 195.65422 moveto
175.1994 +73.430405 192.69524 lineto
175.1995 +74.328842 192.69524 lineto
175.1996 +74.328842 200.29289 lineto
175.1997 +73.430405 200.29289 lineto
175.1998 +73.430405 199.47258 lineto
175.1999 +73.241598 199.7981 73.002341 200.04061 72.712631 200.20012 curveto
175.2000 +72.426169 200.35637 72.081118 200.43449 71.677475 200.43449 curveto
175.2001 +71.016666 200.43449 70.477929 200.17082 70.061264 199.64348 curveto
175.2002 +69.647852 199.11614 69.441146 198.42278 69.441147 197.5634 curveto
175.2003 +69.441146 196.70403 69.647852 196.01067 70.061264 195.48332 curveto
175.2004 +70.477929 194.95598 71.016666 194.69231 71.677475 194.69231 curveto
175.2005 +72.081118 194.69231 72.426169 194.77206 72.712631 194.93156 curveto
175.2006 +73.002341 195.08782 73.241598 195.3287 73.430405 195.65422 curveto
175.2007 +70.368881 197.5634 moveto
175.2008 +70.36888 198.22421 70.503971 198.74341 70.774155 199.12102 curveto
175.2009 +71.04759 199.49537 71.421939 199.68254 71.897202 199.68254 curveto
175.2010 +72.372458 199.68254 72.746807 199.49537 73.020248 199.12102 curveto
175.2011 +73.293682 198.74341 73.4304 198.22421 73.430405 197.5634 curveto
175.2012 +73.4304 196.9026 73.293682 196.38502 73.020248 196.01067 curveto
175.2013 +72.746807 195.63307 72.372458 195.44426 71.897202 195.44426 curveto
175.2014 +71.421939 195.44426 71.04759 195.63307 70.774155 196.01067 curveto
175.2015 +70.503971 196.38502 70.36888 196.9026 70.368881 197.5634 curveto
175.2016 +fill
175.2017 +grestore
175.2018 +gsave
175.2019 +0 0 0 setrgbcolor
175.2020 +newpath
175.2021 +76.179428 194.82414 moveto
175.2022 +77.077866 194.82414 lineto
175.2023 +77.077866 200.29289 lineto
175.2024 +76.179428 200.29289 lineto
175.2025 +76.179428 194.82414 lineto
175.2026 +76.179428 192.69524 moveto
175.2027 +77.077866 192.69524 lineto
175.2028 +77.077866 193.83293 lineto
175.2029 +76.179428 193.83293 lineto
175.2030 +76.179428 192.69524 lineto
175.2031 +fill
175.2032 +grestore
175.2033 +gsave
175.2034 +0 0 0 setrgbcolor
175.2035 +newpath
175.2036 +83.498764 196.99211 moveto
175.2037 +83.498764 200.29289 lineto
175.2038 +82.600327 200.29289 lineto
175.2039 +82.600327 197.02141 lineto
175.2040 +82.600322 196.50383 82.499411 196.11646 82.297592 195.8593 curveto
175.2041 +82.095765 195.60214 81.793031 195.47356 81.389389 195.47356 curveto
175.2042 +80.90436 195.47356 80.521874 195.62818 80.241928 195.93742 curveto
175.2043 +79.961978 196.24667 79.822004 196.66822 79.822006 197.20207 curveto
175.2044 +79.822006 200.29289 lineto
175.2045 +78.918686 200.29289 lineto
175.2046 +78.918686 194.82414 lineto
175.2047 +79.822006 194.82414 lineto
175.2048 +79.822006 195.67375 lineto
175.2049 +80.036848 195.34498 80.289126 195.09921 80.578842 194.93645 curveto
175.2050 +80.871808 194.77369 81.208722 194.69231 81.589584 194.69231 curveto
175.2051 +82.217835 194.69231 82.693095 194.88762 83.015366 195.27824 curveto
175.2052 +83.337626 195.66562 83.498759 196.23691 83.498764 196.99211 curveto
175.2053 +fill
175.2054 +grestore
175.2055 +gsave
175.2056 +0 0 0 setrgbcolor
175.2057 +newpath
175.2058 +88.899155 197.49504 moveto
175.2059 +88.89915 196.844 88.764059 196.33945 88.493881 195.98137 curveto
175.2060 +88.22695 195.6233 87.850974 195.44426 87.365952 195.44426 curveto
175.2061 +86.884178 195.44426 86.508202 195.6233 86.238022 195.98137 curveto
175.2062 +85.971093 196.33945 85.83763 196.844 85.837631 197.49504 curveto
175.2063 +85.83763 198.14283 85.971093 198.64576 86.238022 199.00383 curveto
175.2064 +86.508202 199.3619 86.884178 199.54094 87.365952 199.54094 curveto
175.2065 +87.850974 199.54094 88.22695 199.3619 88.493881 199.00383 curveto
175.2066 +88.764059 198.64576 88.89915 198.14283 88.899155 197.49504 curveto
175.2067 +89.797592 199.61418 moveto
175.2068 +89.797587 200.54517 89.590881 201.2369 89.177475 201.68938 curveto
175.2069 +88.764059 202.1451 88.130922 202.37297 87.278061 202.37297 curveto
175.2070 +86.962303 202.37297 86.664452 202.34855 86.384506 202.29973 curveto
175.2071 +86.104557 202.25415 85.832747 202.18254 85.569077 202.08488 curveto
175.2072 +85.569077 201.21086 lineto
175.2073 +85.832747 201.35409 86.093163 201.45988 86.350327 201.52824 curveto
175.2074 +86.607486 201.5966 86.86953 201.63078 87.136459 201.63078 curveto
175.2075 +87.725649 201.63078 88.166729 201.47616 88.459702 201.16692 curveto
175.2076 +88.752666 200.86093 88.89915 200.39706 88.899155 199.77531 curveto
175.2077 +88.899155 199.33098 lineto
175.2078 +88.713603 199.65324 88.475973 199.89413 88.186264 200.05363 curveto
175.2079 +87.896547 200.21314 87.549868 200.29289 87.146225 200.29289 curveto
175.2080 +86.47565 200.29289 85.935286 200.03736 85.525131 199.52629 curveto
175.2081 +85.114974 199.01522 84.909896 198.33814 84.909897 197.49504 curveto
175.2082 +84.909896 196.64869 85.114974 195.96998 85.525131 195.45891 curveto
175.2083 +85.935286 194.94785 86.47565 194.69231 87.146225 194.69231 curveto
175.2084 +87.549868 194.69231 87.896547 194.77206 88.186264 194.93156 curveto
175.2085 +88.475973 195.09107 88.713603 195.33196 88.899155 195.65422 curveto
175.2086 +88.899155 194.82414 lineto
175.2087 +89.797592 194.82414 lineto
175.2088 +89.797592 199.61418 lineto
175.2089 +fill
175.2090 +grestore
175.2091 +gsave
175.2092 +0 0 0 setrgbcolor
175.2093 +newpath
175.2094 +380.48996 223.50369 moveto
175.2095 +380.48996 225.05643 lineto
175.2096 +382.34055 225.05643 lineto
175.2097 +382.34055 225.75467 lineto
175.2098 +380.48996 225.75467 lineto
175.2099 +380.48996 228.72342 lineto
175.2100 +380.48996 229.16938 380.55018 229.45584 380.67062 229.58279 curveto
175.2101 +380.79432 229.70975 381.04334 229.77322 381.41769 229.77322 curveto
175.2102 +382.34055 229.77322 lineto
175.2103 +382.34055 230.52518 lineto
175.2104 +381.41769 230.52518 lineto
175.2105 +380.72433 230.52518 380.24582 230.3966 379.98215 230.13943 curveto
175.2106 +379.71847 229.87902 379.58664 229.40701 379.58664 228.72342 curveto
175.2107 +379.58664 225.75467 lineto
175.2108 +378.92746 225.75467 lineto
175.2109 +378.92746 225.05643 lineto
175.2110 +379.58664 225.05643 lineto
175.2111 +379.58664 223.50369 lineto
175.2112 +380.48996 223.50369 lineto
175.2113 +fill
175.2114 +grestore
175.2115 +gsave
175.2116 +0 0 0 setrgbcolor
175.2117 +newpath
175.2118 +388.07297 227.2244 moveto
175.2119 +388.07297 230.52518 lineto
175.2120 +387.17453 230.52518 lineto
175.2121 +387.17453 227.25369 lineto
175.2122 +387.17453 226.73612 387.07361 226.34875 386.8718 226.09158 curveto
175.2123 +386.66997 225.83443 386.36723 225.70585 385.96359 225.70584 curveto
175.2124 +385.47856 225.70585 385.09608 225.86047 384.81613 226.16971 curveto
175.2125 +384.53618 226.47896 384.39621 226.90051 384.39621 227.43436 curveto
175.2126 +384.39621 230.52518 lineto
175.2127 +383.49289 230.52518 lineto
175.2128 +383.49289 222.92752 lineto
175.2129 +384.39621 222.92752 lineto
175.2130 +384.39621 225.90604 lineto
175.2131 +384.61105 225.57727 384.86333 225.3315 385.15305 225.16873 curveto
175.2132 +385.44601 225.00598 385.78293 224.9246 386.16379 224.92459 curveto
175.2133 +386.79204 224.9246 387.2673 225.11991 387.58957 225.51053 curveto
175.2134 +387.91183 225.8979 388.07296 226.46919 388.07297 227.2244 curveto
175.2135 +fill
175.2136 +grestore
175.2137 +gsave
175.2138 +0 0 0 setrgbcolor
175.2139 +newpath
175.2140 +394.55246 227.56619 moveto
175.2141 +394.55246 228.00565 lineto
175.2142 +390.4216 228.00565 lineto
175.2143 +390.46066 228.62414 390.64621 229.09614 390.97824 229.42166 curveto
175.2144 +391.31353 229.74393 391.77902 229.90506 392.37473 229.90506 curveto
175.2145 +392.71977 229.90506 393.05343 229.86274 393.3757 229.77811 curveto
175.2146 +393.70122 229.69347 394.02348 229.56652 394.3425 229.39725 curveto
175.2147 +394.3425 230.24686 lineto
175.2148 +394.02023 230.38358 393.68982 230.48774 393.35129 230.55936 curveto
175.2149 +393.01274 230.63097 392.66932 230.66678 392.32101 230.66678 curveto
175.2150 +391.44862 230.66678 390.75688 230.41287 390.24582 229.90506 curveto
175.2151 +389.73801 229.39725 389.4841 228.7104 389.4841 227.84451 curveto
175.2152 +389.4841 226.94933 389.72498 226.2397 390.20676 225.71561 curveto
175.2153 +390.69178 225.18827 391.34445 224.9246 392.16476 224.92459 curveto
175.2154 +392.90044 224.9246 393.48149 225.16223 393.90793 225.63748 curveto
175.2155 +394.33761 226.10949 394.55245 226.75239 394.55246 227.56619 curveto
175.2156 +393.65402 227.30252 moveto
175.2157 +393.64751 226.81099 393.50916 226.41874 393.23898 226.12576 curveto
175.2158 +392.97205 225.8328 392.61723 225.68631 392.17453 225.68631 curveto
175.2159 +391.67323 225.68631 391.27121 225.82792 390.96848 226.11111 curveto
175.2160 +390.66899 226.39432 390.49647 226.79308 390.4509 227.3074 curveto
175.2161 +393.65402 227.30252 lineto
175.2162 +fill
175.2163 +grestore
175.2164 +gsave
175.2165 +0 0 0 setrgbcolor
175.2166 +newpath
175.2167 +400.57297 227.2244 moveto
175.2168 +400.57297 230.52518 lineto
175.2169 +399.67453 230.52518 lineto
175.2170 +399.67453 227.25369 lineto
175.2171 +399.67453 226.73612 399.57361 226.34875 399.3718 226.09158 curveto
175.2172 +399.16997 225.83443 398.86723 225.70585 398.46359 225.70584 curveto
175.2173 +397.97856 225.70585 397.59608 225.86047 397.31613 226.16971 curveto
175.2174 +397.03618 226.47896 396.89621 226.90051 396.89621 227.43436 curveto
175.2175 +396.89621 230.52518 lineto
175.2176 +395.99289 230.52518 lineto
175.2177 +395.99289 225.05643 lineto
175.2178 +396.89621 225.05643 lineto
175.2179 +396.89621 225.90604 lineto
175.2180 +397.11105 225.57727 397.36333 225.3315 397.65305 225.16873 curveto
175.2181 +397.94601 225.00598 398.28293 224.9246 398.66379 224.92459 curveto
175.2182 +399.29204 224.9246 399.7673 225.11991 400.08957 225.51053 curveto
175.2183 +400.41183 225.8979 400.57296 226.46919 400.57297 227.2244 curveto
175.2184 +fill
175.2185 +grestore
175.2186 +gsave
175.2187 +0 0 0 setrgbcolor
175.2188 +newpath
175.2189 +239.47623 229.75269 moveto
175.2190 +239.47623 233.05347 lineto
175.2191 +238.57779 233.05347 lineto
175.2192 +238.57779 229.78198 lineto
175.2193 +238.57778 229.26441 238.47687 228.87704 238.27505 228.61987 curveto
175.2194 +238.07323 228.36272 237.77049 228.23414 237.36685 228.23413 curveto
175.2195 +236.88182 228.23414 236.49934 228.38876 236.21939 228.698 curveto
175.2196 +235.93944 229.00725 235.79947 229.4288 235.79947 229.96265 curveto
175.2197 +235.79947 233.05347 lineto
175.2198 +234.89615 233.05347 lineto
175.2199 +234.89615 225.45581 lineto
175.2200 +235.79947 225.45581 lineto
175.2201 +235.79947 228.43433 lineto
175.2202 +236.01431 228.10556 236.26659 227.85979 236.5563 227.69702 curveto
175.2203 +236.84927 227.53427 237.18618 227.45289 237.56705 227.45288 curveto
175.2204 +238.1953 227.45289 238.67056 227.6482 238.99283 228.03882 curveto
175.2205 +239.31509 228.42619 239.47622 228.99748 239.47623 229.75269 curveto
175.2206 +fill
175.2207 +grestore
175.2208 +gsave
175.2209 +0 0 0 setrgbcolor
175.2210 +newpath
175.2211 +243.76334 230.30444 moveto
175.2212 +243.03742 230.30445 242.53449 230.38745 242.25455 230.55347 curveto
175.2213 +241.9746 230.71948 241.83462 231.00269 241.83463 231.40308 curveto
175.2214 +241.83462 231.72209 241.93879 231.97599 242.14713 232.16479 curveto
175.2215 +242.35871 232.35034 242.64517 232.44312 243.0065 232.44312 curveto
175.2216 +243.50454 232.44312 243.90331 232.26733 244.20279 231.91577 curveto
175.2217 +244.50552 231.56096 244.65689 231.09058 244.65689 230.50464 curveto
175.2218 +244.65689 230.30444 lineto
175.2219 +243.76334 230.30444 lineto
175.2220 +245.55533 229.93335 moveto
175.2221 +245.55533 233.05347 lineto
175.2222 +244.65689 233.05347 lineto
175.2223 +244.65689 232.22339 lineto
175.2224 +244.45181 232.55542 244.19628 232.80119 243.89029 232.96069 curveto
175.2225 +243.5843 233.11694 243.20995 233.19507 242.76724 233.19507 curveto
175.2226 +242.20734 233.19507 241.76138 233.03882 241.42935 232.72632 curveto
175.2227 +241.10057 232.41056 240.93619 231.98901 240.93619 231.46167 curveto
175.2228 +240.93619 230.84644 241.14127 230.38257 241.55142 230.07007 curveto
175.2229 +241.96483 229.75757 242.58007 229.60132 243.39713 229.60132 curveto
175.2230 +244.65689 229.60132 lineto
175.2231 +244.65689 229.51343 lineto
175.2232 +244.65689 229.10002 244.52017 228.78101 244.24673 228.5564 curveto
175.2233 +243.97655 228.32854 243.59569 228.2146 243.10416 228.2146 curveto
175.2234 +242.79165 228.2146 242.48729 228.25204 242.19107 228.3269 curveto
175.2235 +241.89485 228.40178 241.61001 228.51408 241.33658 228.66382 curveto
175.2236 +241.33658 227.83374 lineto
175.2237 +241.66535 227.70679 241.98436 227.61239 242.29361 227.55054 curveto
175.2238 +242.60285 227.48544 242.90396 227.45289 243.19693 227.45288 curveto
175.2239 +243.98794 227.45289 244.57876 227.65796 244.96939 228.06812 curveto
175.2240 +245.36001 228.47828 245.55532 229.10002 245.55533 229.93335 curveto
175.2241 +fill
175.2242 +grestore
175.2243 +gsave
175.2244 +0 0 0 setrgbcolor
175.2245 +newpath
175.2246 +246.76627 227.58472 moveto
175.2247 +247.71841 227.58472 lineto
175.2248 +249.4274 232.17456 lineto
175.2249 +251.13638 227.58472 lineto
175.2250 +252.08853 227.58472 lineto
175.2251 +250.03775 233.05347 lineto
175.2252 +248.81705 233.05347 lineto
175.2253 +246.76627 227.58472 lineto
175.2254 +fill
175.2255 +grestore
175.2256 +gsave
175.2257 +0 0 0 setrgbcolor
175.2258 +newpath
175.2259 +258.0065 230.09448 moveto
175.2260 +258.0065 230.53394 lineto
175.2261 +253.87564 230.53394 lineto
175.2262 +253.9147 231.15243 254.10025 231.62443 254.43228 231.94995 curveto
175.2263 +254.76757 232.27222 255.23306 232.43335 255.82877 232.43335 curveto
175.2264 +256.17381 232.43335 256.50747 232.39103 256.82974 232.3064 curveto
175.2265 +257.15526 232.22176 257.47752 232.09481 257.79654 231.92554 curveto
175.2266 +257.79654 232.77515 lineto
175.2267 +257.47427 232.91187 257.14387 233.01603 256.80533 233.08765 curveto
175.2268 +256.46678 233.15926 256.12336 233.19507 255.77505 233.19507 curveto
175.2269 +254.90266 233.19507 254.21093 232.94116 253.69986 232.43335 curveto
175.2270 +253.19205 231.92554 252.93814 231.23869 252.93814 230.3728 curveto
175.2271 +252.93814 229.47762 253.17903 228.76799 253.6608 228.2439 curveto
175.2272 +254.14582 227.71656 254.79849 227.45289 255.6188 227.45288 curveto
175.2273 +256.35448 227.45289 256.93553 227.69052 257.36197 228.16577 curveto
175.2274 +257.79165 228.63778 258.00649 229.28068 258.0065 230.09448 curveto
175.2275 +257.10806 229.83081 moveto
175.2276 +257.10155 229.33928 256.9632 228.94703 256.69302 228.65405 curveto
175.2277 +256.42609 228.36109 256.07128 228.2146 255.62857 228.2146 curveto
175.2278 +255.12727 228.2146 254.72525 228.35621 254.42252 228.6394 curveto
175.2279 +254.12303 228.92261 253.95051 229.32137 253.90494 229.83569 curveto
175.2280 +257.10806 229.83081 lineto
175.2281 +fill
175.2282 +grestore
175.2283 +gsave
175.2284 +0 0 0 setrgbcolor
175.2285 +newpath
175.2286 +238.41666 242.74585 moveto
175.2287 +238.41666 243.59546 lineto
175.2288 +238.16275 243.46526 237.89907 243.3676 237.62564 243.30249 curveto
175.2289 +237.3522 243.23739 237.069 243.20484 236.77603 243.20483 curveto
175.2290 +236.33007 243.20484 235.99478 243.2732 235.77017 243.40991 curveto
175.2291 +235.54882 243.54664 235.43814 243.75171 235.43814 244.02515 curveto
175.2292 +235.43814 244.23348 235.51789 244.39787 235.6774 244.51831 curveto
175.2293 +235.8369 244.6355 236.15754 244.74781 236.63931 244.85522 curveto
175.2294 +236.94693 244.92358 lineto
175.2295 +237.58495 245.06031 238.03742 245.25399 238.30435 245.50464 curveto
175.2296 +238.57453 245.75204 238.70962 246.09872 238.70963 246.54468 curveto
175.2297 +238.70962 247.05249 238.5078 247.45451 238.10416 247.75073 curveto
175.2298 +237.70376 248.04696 237.152 248.19507 236.44888 248.19507 curveto
175.2299 +236.15591 248.19507 235.84992 248.16577 235.53091 248.10718 curveto
175.2300 +235.21516 248.05184 234.8815 247.9672 234.52994 247.85327 curveto
175.2301 +234.52994 246.92554 lineto
175.2302 +234.86197 247.09806 235.18912 247.22827 235.51138 247.31616 curveto
175.2303 +235.83365 247.4008 236.15266 247.44312 236.46841 247.44312 curveto
175.2304 +236.89159 247.44312 237.21711 247.3715 237.44498 247.22827 curveto
175.2305 +237.67284 247.08179 237.78677 246.87671 237.78677 246.61304 curveto
175.2306 +237.78677 246.3689 237.70376 246.18172 237.53775 246.05151 curveto
175.2307 +237.37499 245.92131 237.01529 245.79598 236.45865 245.67554 curveto
175.2308 +236.14615 245.60229 lineto
175.2309 +235.58951 245.48511 235.18749 245.30607 234.94009 245.06519 curveto
175.2310 +234.6927 244.82105 234.569 244.48739 234.569 244.06421 curveto
175.2311 +234.569 243.54989 234.75129 243.15276 235.11588 242.8728 curveto
175.2312 +235.48046 242.59286 235.99803 242.45289 236.66861 242.45288 curveto
175.2313 +237.00064 242.45289 237.31314 242.4773 237.60611 242.52612 curveto
175.2314 +237.89907 242.57496 238.16926 242.6482 238.41666 242.74585 curveto
175.2315 +fill
175.2316 +grestore
175.2317 +gsave
175.2318 +0 0 0 setrgbcolor
175.2319 +newpath
175.2320 +244.69107 244.75269 moveto
175.2321 +244.69107 248.05347 lineto
175.2322 +243.79263 248.05347 lineto
175.2323 +243.79263 244.78198 lineto
175.2324 +243.79263 244.26441 243.69172 243.87704 243.4899 243.61987 curveto
175.2325 +243.28807 243.36272 242.98534 243.23414 242.5817 243.23413 curveto
175.2326 +242.09667 243.23414 241.71418 243.38876 241.43423 243.698 curveto
175.2327 +241.15428 244.00725 241.01431 244.4288 241.01431 244.96265 curveto
175.2328 +241.01431 248.05347 lineto
175.2329 +240.11099 248.05347 lineto
175.2330 +240.11099 240.45581 lineto
175.2331 +241.01431 240.45581 lineto
175.2332 +241.01431 243.43433 lineto
175.2333 +241.22915 243.10556 241.48143 242.85979 241.77115 242.69702 curveto
175.2334 +242.06411 242.53427 242.40103 242.45289 242.78189 242.45288 curveto
175.2335 +243.41014 242.45289 243.8854 242.6482 244.20767 243.03882 curveto
175.2336 +244.52993 243.42619 244.69107 243.99748 244.69107 244.75269 curveto
175.2337 +fill
175.2338 +grestore
175.2339 +gsave
175.2340 +0 0 0 setrgbcolor
175.2341 +newpath
175.2342 +248.61197 243.2146 moveto
175.2343 +248.1302 243.2146 247.74934 243.40341 247.46939 243.78101 curveto
175.2344 +247.18944 244.15536 247.04947 244.66968 247.04947 245.32397 curveto
175.2345 +247.04947 245.97827 247.18781 246.49422 247.46451 246.87183 curveto
175.2346 +247.74445 247.24618 248.12694 247.43335 248.61197 247.43335 curveto
175.2347 +249.09048 247.43335 249.46971 247.24455 249.74966 246.86694 curveto
175.2348 +250.02961 246.48934 250.16958 245.97502 250.16959 245.32397 curveto
175.2349 +250.16958 244.67619 250.02961 244.1635 249.74966 243.78589 curveto
175.2350 +249.46971 243.40503 249.09048 243.2146 248.61197 243.2146 curveto
175.2351 +248.61197 242.45288 moveto
175.2352 +249.39322 242.45289 250.00682 242.70679 250.45279 243.2146 curveto
175.2353 +250.89875 243.72242 251.12173 244.42554 251.12173 245.32397 curveto
175.2354 +251.12173 246.21916 250.89875 246.92228 250.45279 247.43335 curveto
175.2355 +250.00682 247.94116 249.39322 248.19507 248.61197 248.19507 curveto
175.2356 +247.82746 248.19507 247.21223 247.94116 246.76627 247.43335 curveto
175.2357 +246.32356 246.92228 246.1022 246.21916 246.1022 245.32397 curveto
175.2358 +246.1022 244.42554 246.32356 243.72242 246.76627 243.2146 curveto
175.2359 +247.21223 242.70679 247.82746 242.45289 248.61197 242.45288 curveto
175.2360 +fill
175.2361 +grestore
175.2362 +gsave
175.2363 +0 0 0 setrgbcolor
175.2364 +newpath
175.2365 +252.08365 242.58472 moveto
175.2366 +252.98209 242.58472 lineto
175.2367 +254.10513 246.85229 lineto
175.2368 +255.2233 242.58472 lineto
175.2369 +256.28287 242.58472 lineto
175.2370 +257.40591 246.85229 lineto
175.2371 +258.52408 242.58472 lineto
175.2372 +259.42252 242.58472 lineto
175.2373 +257.99185 248.05347 lineto
175.2374 +256.93228 248.05347 lineto
175.2375 +255.75552 243.57104 lineto
175.2376 +254.57388 248.05347 lineto
175.2377 +253.51431 248.05347 lineto
175.2378 +252.08365 242.58472 lineto
175.2379 +fill
175.2380 +grestore
175.2381 +gsave
175.2382 +0 0 0 setrgbcolor
175.2383 +newpath
175.2384 +311.38464 185.46135 moveto
175.2385 +311.38464 188.76213 lineto
175.2386 +310.48621 188.76213 lineto
175.2387 +310.48621 185.49065 lineto
175.2388 +310.4862 184.97307 310.38529 184.5857 310.18347 184.32854 curveto
175.2389 +309.98164 184.07138 309.67891 183.9428 309.27527 183.94279 curveto
175.2390 +308.79024 183.9428 308.40775 184.09742 308.12781 184.40666 curveto
175.2391 +307.84786 184.71591 307.70788 185.13746 307.70789 185.67131 curveto
175.2392 +307.70789 188.76213 lineto
175.2393 +306.80457 188.76213 lineto
175.2394 +306.80457 181.16447 lineto
175.2395 +307.70789 181.16447 lineto
175.2396 +307.70789 184.14299 lineto
175.2397 +307.92273 183.81422 308.17501 183.56845 308.46472 183.40569 curveto
175.2398 +308.75769 183.24293 309.0946 183.16155 309.47546 183.16154 curveto
175.2399 +310.10371 183.16155 310.57897 183.35686 310.90125 183.74748 curveto
175.2400 +311.22351 184.13486 311.38464 184.70615 311.38464 185.46135 curveto
175.2401 +fill
175.2402 +grestore
175.2403 +gsave
175.2404 +0 0 0 setrgbcolor
175.2405 +newpath
175.2406 +315.67175 186.01311 moveto
175.2407 +314.94584 186.01311 314.44291 186.09612 314.16296 186.26213 curveto
175.2408 +313.88301 186.42815 313.74304 186.71135 313.74304 187.11174 curveto
175.2409 +313.74304 187.43075 313.84721 187.68466 314.05554 187.87346 curveto
175.2410 +314.26713 188.05901 314.55359 188.15178 314.91492 188.15178 curveto
175.2411 +315.41296 188.15178 315.81172 187.976 316.11121 187.62444 curveto
175.2412 +316.41394 187.26962 316.5653 186.79924 316.56531 186.2133 curveto
175.2413 +316.56531 186.01311 lineto
175.2414 +315.67175 186.01311 lineto
175.2415 +317.46375 185.64201 moveto
175.2416 +317.46375 188.76213 lineto
175.2417 +316.56531 188.76213 lineto
175.2418 +316.56531 187.93205 lineto
175.2419 +316.36023 188.26408 316.10469 188.50985 315.79871 188.66936 curveto
175.2420 +315.49271 188.82561 315.11836 188.90373 314.67566 188.90373 curveto
175.2421 +314.11576 188.90373 313.6698 188.74748 313.33777 188.43498 curveto
175.2422 +313.00899 188.11923 312.8446 187.69768 312.8446 187.17033 curveto
175.2423 +312.8446 186.5551 313.04968 186.09123 313.45984 185.77873 curveto
175.2424 +313.87325 185.46624 314.48848 185.30999 315.30554 185.30998 curveto
175.2425 +316.56531 185.30998 lineto
175.2426 +316.56531 185.22209 lineto
175.2427 +316.5653 184.80868 316.42858 184.48967 316.15515 184.26506 curveto
175.2428 +315.88497 184.0372 315.50411 183.92327 315.01257 183.92326 curveto
175.2429 +314.70007 183.92327 314.39571 183.9607 314.09949 184.03557 curveto
175.2430 +313.80326 184.11044 313.51843 184.22275 313.245 184.37248 curveto
175.2431 +313.245 183.5424 lineto
175.2432 +313.57377 183.41546 313.89278 183.32106 314.20203 183.2592 curveto
175.2433 +314.51127 183.1941 314.81238 183.16155 315.10535 183.16154 curveto
175.2434 +315.89636 183.16155 316.48718 183.36663 316.87781 183.77678 curveto
175.2435 +317.26843 184.18694 317.46374 184.80868 317.46375 185.64201 curveto
175.2436 +fill
175.2437 +grestore
175.2438 +gsave
175.2439 +0 0 0 setrgbcolor
175.2440 +newpath
175.2441 +318.67468 183.29338 moveto
175.2442 +319.62683 183.29338 lineto
175.2443 +321.33582 187.88322 lineto
175.2444 +323.0448 183.29338 lineto
175.2445 +323.99695 183.29338 lineto
175.2446 +321.94617 188.76213 lineto
175.2447 +320.72546 188.76213 lineto
175.2448 +318.67468 183.29338 lineto
175.2449 +fill
175.2450 +grestore
175.2451 +gsave
175.2452 +0 0 0 setrgbcolor
175.2453 +newpath
175.2454 +329.91492 185.80315 moveto
175.2455 +329.91492 186.2426 lineto
175.2456 +325.78406 186.2426 lineto
175.2457 +325.82312 186.86109 326.00867 187.3331 326.3407 187.65862 curveto
175.2458 +326.67598 187.98088 327.14148 188.14201 327.73718 188.14201 curveto
175.2459 +328.08223 188.14201 328.41589 188.0997 328.73816 188.01506 curveto
175.2460 +329.06368 187.93043 329.38594 187.80347 329.70496 187.6342 curveto
175.2461 +329.70496 188.48381 lineto
175.2462 +329.38269 188.62053 329.05228 188.7247 328.71375 188.79631 curveto
175.2463 +328.3752 188.86792 328.03178 188.90373 327.68347 188.90373 curveto
175.2464 +326.81107 188.90373 326.11934 188.64983 325.60828 188.14201 curveto
175.2465 +325.10046 187.6342 324.84656 186.94735 324.84656 186.08147 curveto
175.2466 +324.84656 185.18629 325.08744 184.47665 325.56921 183.95256 curveto
175.2467 +326.05424 183.42522 326.70691 183.16155 327.52722 183.16154 curveto
175.2468 +328.26289 183.16155 328.84395 183.39918 329.27039 183.87444 curveto
175.2469 +329.70007 184.34645 329.91491 184.98935 329.91492 185.80315 curveto
175.2470 +329.01648 185.53947 moveto
175.2471 +329.00996 185.04794 328.87162 184.65569 328.60144 184.36272 curveto
175.2472 +328.33451 184.06975 327.97969 183.92327 327.53699 183.92326 curveto
175.2473 +327.03568 183.92327 326.63366 184.06487 326.33093 184.34807 curveto
175.2474 +326.03145 184.63128 325.85893 185.03004 325.81335 185.54436 curveto
175.2475 +329.01648 185.53947 lineto
175.2476 +fill
175.2477 +grestore
175.2478 +gsave
175.2479 +0 0 0 setrgbcolor
175.2480 +newpath
175.2481 +310.32507 198.45451 moveto
175.2482 +310.32507 199.30412 lineto
175.2483 +310.07116 199.17392 309.80749 199.07626 309.53406 199.01115 curveto
175.2484 +309.26062 198.94605 308.97741 198.9135 308.68445 198.9135 curveto
175.2485 +308.23848 198.9135 307.9032 198.98186 307.67859 199.11858 curveto
175.2486 +307.45723 199.2553 307.34656 199.46038 307.34656 199.73381 curveto
175.2487 +307.34656 199.94215 307.42631 200.10654 307.58582 200.22697 curveto
175.2488 +307.74532 200.34417 308.06596 200.45647 308.54773 200.56389 curveto
175.2489 +308.85535 200.63225 lineto
175.2490 +309.49336 200.76897 309.94584 200.96265 310.21277 201.2133 curveto
175.2491 +310.48295 201.4607 310.61804 201.80738 310.61804 202.25334 curveto
175.2492 +310.61804 202.76116 310.41621 203.16317 310.01257 203.4594 curveto
175.2493 +309.61218 203.75562 309.06042 203.90373 308.3573 203.90373 curveto
175.2494 +308.06433 203.90373 307.75834 203.87444 307.43933 203.81584 curveto
175.2495 +307.12357 203.7605 306.78992 203.67587 306.43835 203.56194 curveto
175.2496 +306.43835 202.6342 lineto
175.2497 +306.77038 202.80673 307.09753 202.93694 307.4198 203.02483 curveto
175.2498 +307.74206 203.10946 308.06107 203.15178 308.37683 203.15178 curveto
175.2499 +308.80001 203.15178 309.12553 203.08017 309.35339 202.93694 curveto
175.2500 +309.58125 202.79045 309.69519 202.58537 309.69519 202.3217 curveto
175.2501 +309.69519 202.07756 309.61218 201.89039 309.44617 201.76018 curveto
175.2502 +309.2834 201.62997 308.9237 201.50465 308.36707 201.3842 curveto
175.2503 +308.05457 201.31096 lineto
175.2504 +307.49792 201.19377 307.09591 201.01474 306.84851 200.77385 curveto
175.2505 +306.60111 200.52971 306.47742 200.19605 306.47742 199.77287 curveto
175.2506 +306.47742 199.25855 306.65971 198.86142 307.02429 198.58147 curveto
175.2507 +307.38887 198.30152 307.90645 198.16155 308.57703 198.16154 curveto
175.2508 +308.90905 198.16155 309.22155 198.18596 309.51453 198.23479 curveto
175.2509 +309.80749 198.28362 310.07767 198.35686 310.32507 198.45451 curveto
175.2510 +fill
175.2511 +grestore
175.2512 +gsave
175.2513 +0 0 0 setrgbcolor
175.2514 +newpath
175.2515 +316.59949 200.46135 moveto
175.2516 +316.59949 203.76213 lineto
175.2517 +315.70105 203.76213 lineto
175.2518 +315.70105 200.49065 lineto
175.2519 +315.70105 199.97307 315.60013 199.5857 315.39832 199.32854 curveto
175.2520 +315.19649 199.07138 314.89375 198.9428 314.49011 198.94279 curveto
175.2521 +314.00508 198.9428 313.6226 199.09742 313.34265 199.40666 curveto
175.2522 +313.0627 199.71591 312.92273 200.13746 312.92273 200.67131 curveto
175.2523 +312.92273 203.76213 lineto
175.2524 +312.01941 203.76213 lineto
175.2525 +312.01941 196.16447 lineto
175.2526 +312.92273 196.16447 lineto
175.2527 +312.92273 199.14299 lineto
175.2528 +313.13757 198.81422 313.38985 198.56845 313.67957 198.40569 curveto
175.2529 +313.97253 198.24293 314.30945 198.16155 314.69031 198.16154 curveto
175.2530 +315.31856 198.16155 315.79382 198.35686 316.11609 198.74748 curveto
175.2531 +316.43835 199.13486 316.59948 199.70615 316.59949 200.46135 curveto
175.2532 +fill
175.2533 +grestore
175.2534 +gsave
175.2535 +0 0 0 setrgbcolor
175.2536 +newpath
175.2537 +320.52039 198.92326 moveto
175.2538 +320.03861 198.92327 319.65775 199.11207 319.37781 199.48967 curveto
175.2539 +319.09786 199.86402 318.95788 200.37835 318.95789 201.03264 curveto
175.2540 +318.95788 201.68694 319.09623 202.20289 319.37292 202.58049 curveto
175.2541 +319.65287 202.95484 320.03536 203.14201 320.52039 203.14201 curveto
175.2542 +320.9989 203.14201 321.37813 202.95321 321.65808 202.57561 curveto
175.2543 +321.93802 202.198 322.078 201.68368 322.078 201.03264 curveto
175.2544 +322.078 200.38486 321.93802 199.87216 321.65808 199.49455 curveto
175.2545 +321.37813 199.1137 320.9989 198.92327 320.52039 198.92326 curveto
175.2546 +320.52039 198.16154 moveto
175.2547 +321.30163 198.16155 321.91524 198.41546 322.36121 198.92326 curveto
175.2548 +322.80716 199.43108 323.03015 200.1342 323.03015 201.03264 curveto
175.2549 +323.03015 201.92782 322.80716 202.63095 322.36121 203.14201 curveto
175.2550 +321.91524 203.64983 321.30163 203.90373 320.52039 203.90373 curveto
175.2551 +319.73588 203.90373 319.12064 203.64983 318.67468 203.14201 curveto
175.2552 +318.23197 202.63095 318.01062 201.92782 318.01062 201.03264 curveto
175.2553 +318.01062 200.1342 318.23197 199.43108 318.67468 198.92326 curveto
175.2554 +319.12064 198.41546 319.73588 198.16155 320.52039 198.16154 curveto
175.2555 +fill
175.2556 +grestore
175.2557 +gsave
175.2558 +0 0 0 setrgbcolor
175.2559 +newpath
175.2560 +323.99207 198.29338 moveto
175.2561 +324.8905 198.29338 lineto
175.2562 +326.01355 202.56096 lineto
175.2563 +327.13171 198.29338 lineto
175.2564 +328.19128 198.29338 lineto
175.2565 +329.31433 202.56096 lineto
175.2566 +330.4325 198.29338 lineto
175.2567 +331.33093 198.29338 lineto
175.2568 +329.90027 203.76213 lineto
175.2569 +328.8407 203.76213 lineto
175.2570 +327.66394 199.27971 lineto
175.2571 +326.4823 203.76213 lineto
175.2572 +325.42273 203.76213 lineto
175.2573 +323.99207 198.29338 lineto
175.2574 +fill
175.2575 +grestore
175.2576 +gsave
175.2577 +0 0 0 setrgbcolor
175.2578 +newpath
175.2579 +305.63477 140.25864 moveto
175.2580 +305.63477 143.15903 lineto
175.2581 +304.73145 143.15903 lineto
175.2582 +304.73145 135.6102 lineto
175.2583 +305.63477 135.6102 lineto
175.2584 +305.63477 136.44028 lineto
175.2585 +305.82357 136.11476 306.0612 135.87388 306.34766 135.71762 curveto
175.2586 +306.63737 135.55812 306.98242 135.47837 307.38281 135.47836 curveto
175.2587 +308.04687 135.47837 308.58561 135.74204 308.99902 136.26938 curveto
175.2588 +309.41568 136.79673 309.62402 137.49009 309.62402 138.34946 curveto
175.2589 +309.62402 139.20883 309.41568 139.90219 308.99902 140.42953 curveto
175.2590 +308.58561 140.95688 308.04687 141.22055 307.38281 141.22055 curveto
175.2591 +306.98242 141.22055 306.63737 141.14243 306.34766 140.98618 curveto
175.2592 +306.0612 140.82667 305.82357 140.58416 305.63477 140.25864 curveto
175.2593 +308.69141 138.34946 moveto
175.2594 +308.6914 137.68865 308.55468 137.17108 308.28125 136.79672 curveto
175.2595 +308.01106 136.41912 307.63834 136.23032 307.16309 136.23032 curveto
175.2596 +306.68782 136.23032 306.31347 136.41912 306.04004 136.79672 curveto
175.2597 +305.76985 137.17108 305.63476 137.68865 305.63477 138.34946 curveto
175.2598 +305.63476 139.01027 305.76985 139.52947 306.04004 139.90707 curveto
175.2599 +306.31347 140.28142 306.68782 140.4686 307.16309 140.4686 curveto
175.2600 +307.63834 140.4686 308.01106 140.28142 308.28125 139.90707 curveto
175.2601 +308.55468 139.52947 308.6914 139.01027 308.69141 138.34946 curveto
175.2602 +fill
175.2603 +grestore
175.2604 +gsave
175.2605 +0 0 0 setrgbcolor
175.2606 +newpath
175.2607 +314.28223 136.45004 moveto
175.2608 +314.18131 136.39145 314.07063 136.34914 313.9502 136.32309 curveto
175.2609 +313.833 136.2938 313.7028 136.27915 313.55957 136.27914 curveto
175.2610 +313.05175 136.27915 312.66113 136.44516 312.3877 136.77719 curveto
175.2611 +312.11751 137.10597 311.98242 137.5796 311.98242 138.19809 curveto
175.2612 +311.98242 141.07895 lineto
175.2613 +311.0791 141.07895 lineto
175.2614 +311.0791 135.6102 lineto
175.2615 +311.98242 135.6102 lineto
175.2616 +311.98242 136.45981 lineto
175.2617 +312.17122 136.12778 312.41699 135.88201 312.71973 135.7225 curveto
175.2618 +313.02246 135.55975 313.3903 135.47837 313.82324 135.47836 curveto
175.2619 +313.88509 135.47837 313.95345 135.48325 314.02832 135.49301 curveto
175.2620 +314.10319 135.49953 314.18619 135.51092 314.27734 135.52719 curveto
175.2621 +314.28223 136.45004 lineto
175.2622 +fill
175.2623 +grestore
175.2624 +gsave
175.2625 +0 0 0 setrgbcolor
175.2626 +newpath
175.2627 +317.13867 136.24008 moveto
175.2628 +316.6569 136.24009 316.27604 136.42889 315.99609 136.80649 curveto
175.2629 +315.71614 137.18084 315.57617 137.69516 315.57617 138.34946 curveto
175.2630 +315.57617 139.00376 315.71452 139.51971 315.99121 139.89731 curveto
175.2631 +316.27116 140.27166 316.65364 140.45883 317.13867 140.45883 curveto
175.2632 +317.61718 140.45883 317.99642 140.27003 318.27637 139.89243 curveto
175.2633 +318.55631 139.51482 318.69628 139.0005 318.69629 138.34946 curveto
175.2634 +318.69628 137.70167 318.55631 137.18898 318.27637 136.81137 curveto
175.2635 +317.99642 136.43052 317.61718 136.24009 317.13867 136.24008 curveto
175.2636 +317.13867 135.47836 moveto
175.2637 +317.91992 135.47837 318.53352 135.73227 318.97949 136.24008 curveto
175.2638 +319.42545 136.7479 319.64843 137.45102 319.64844 138.34946 curveto
175.2639 +319.64843 139.24464 319.42545 139.94777 318.97949 140.45883 curveto
175.2640 +318.53352 140.96664 317.91992 141.22055 317.13867 141.22055 curveto
175.2641 +316.35416 141.22055 315.73893 140.96664 315.29297 140.45883 curveto
175.2642 +314.85026 139.94777 314.62891 139.24464 314.62891 138.34946 curveto
175.2643 +314.62891 137.45102 314.85026 136.7479 315.29297 136.24008 curveto
175.2644 +315.73893 135.73227 316.35416 135.47837 317.13867 135.47836 curveto
175.2645 +fill
175.2646 +grestore
175.2647 +gsave
175.2648 +0 0 0 setrgbcolor
175.2649 +newpath
175.2650 +323.25195 136.24008 moveto
175.2651 +322.77018 136.24009 322.38932 136.42889 322.10938 136.80649 curveto
175.2652 +321.82943 137.18084 321.68945 137.69516 321.68945 138.34946 curveto
175.2653 +321.68945 139.00376 321.8278 139.51971 322.10449 139.89731 curveto
175.2654 +322.38444 140.27166 322.76692 140.45883 323.25195 140.45883 curveto
175.2655 +323.73047 140.45883 324.1097 140.27003 324.38965 139.89243 curveto
175.2656 +324.66959 139.51482 324.80957 139.0005 324.80957 138.34946 curveto
175.2657 +324.80957 137.70167 324.66959 137.18898 324.38965 136.81137 curveto
175.2658 +324.1097 136.43052 323.73047 136.24009 323.25195 136.24008 curveto
175.2659 +323.25195 135.47836 moveto
175.2660 +324.0332 135.47837 324.64681 135.73227 325.09277 136.24008 curveto
175.2661 +325.53873 136.7479 325.76171 137.45102 325.76172 138.34946 curveto
175.2662 +325.76171 139.24464 325.53873 139.94777 325.09277 140.45883 curveto
175.2663 +324.64681 140.96664 324.0332 141.22055 323.25195 141.22055 curveto
175.2664 +322.46745 141.22055 321.85221 140.96664 321.40625 140.45883 curveto
175.2665 +320.96354 139.94777 320.74219 139.24464 320.74219 138.34946 curveto
175.2666 +320.74219 137.45102 320.96354 136.7479 321.40625 136.24008 curveto
175.2667 +321.85221 135.73227 322.46745 135.47837 323.25195 135.47836 curveto
175.2668 +fill
175.2669 +grestore
175.2670 +gsave
175.2671 +0 0 0 setrgbcolor
175.2672 +newpath
175.2673 +330.01465 133.48129 moveto
175.2674 +330.01465 134.22836 lineto
175.2675 +329.15527 134.22836 lineto
175.2676 +328.83301 134.22837 328.6084 134.29347 328.48145 134.42368 curveto
175.2677 +328.35775 134.55389 328.2959 134.78827 328.2959 135.1268 curveto
175.2678 +328.2959 135.6102 lineto
175.2679 +329.77539 135.6102 lineto
175.2680 +329.77539 136.30844 lineto
175.2681 +328.2959 136.30844 lineto
175.2682 +328.2959 141.07895 lineto
175.2683 +327.39258 141.07895 lineto
175.2684 +327.39258 136.30844 lineto
175.2685 +326.5332 136.30844 lineto
175.2686 +326.5332 135.6102 lineto
175.2687 +327.39258 135.6102 lineto
175.2688 +327.39258 135.22934 lineto
175.2689 +327.39258 134.62062 327.53418 134.17791 327.81738 133.90121 curveto
175.2690 +328.10058 133.62127 328.5498 133.4813 329.16504 133.48129 curveto
175.2691 +330.01465 133.48129 lineto
175.2692 +fill
175.2693 +grestore
175.2694 +grestore
175.2695 +grestore
175.2696 +showpage
175.2697 +%%EOF
176.1 Binary file doc-src/IsarRef/Thy/document/isar-vm.pdf has changed
177.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
177.2 +++ b/doc-src/IsarRef/Thy/document/isar-vm.svg Wed Mar 04 11:05:29 2009 +0100
177.3 @@ -0,0 +1,460 @@
177.4 +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
177.5 +<!-- Created with Inkscape (http://www.inkscape.org/) -->
177.6 +<svg
177.7 + xmlns:dc="http://purl.org/dc/elements/1.1/"
177.8 + xmlns:cc="http://creativecommons.org/ns#"
177.9 + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
177.10 + xmlns:svg="http://www.w3.org/2000/svg"
177.11 + xmlns="http://www.w3.org/2000/svg"
177.12 + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
177.13 + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
177.14 + width="543.02673"
177.15 + height="215.66071"
177.16 + id="svg2"
177.17 + sodipodi:version="0.32"
177.18 + inkscape:version="0.46"
177.19 + version="1.0"
177.20 + sodipodi:docname="isar-vm.svg"
177.21 + inkscape:output_extension="org.inkscape.output.svg.inkscape">
177.22 + <defs
177.23 + id="defs4">
177.24 + <marker
177.25 + inkscape:stockid="TriangleOutM"
177.26 + orient="auto"
177.27 + refY="0"
177.28 + refX="0"
177.29 + id="TriangleOutM"
177.30 + style="overflow:visible">
177.31 + <path
177.32 + id="path4130"
177.33 + d="M 5.77,0 L -2.88,5 L -2.88,-5 L 5.77,0 z"
177.34 + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
177.35 + transform="scale(0.4,0.4)" />
177.36 + </marker>
177.37 + <marker
177.38 + inkscape:stockid="Arrow1Mend"
177.39 + orient="auto"
177.40 + refY="0"
177.41 + refX="0"
177.42 + id="Arrow1Mend"
177.43 + style="overflow:visible">
177.44 + <path
177.45 + id="path3993"
177.46 + d="M 0,0 L 5,-5 L -12.5,0 L 5,5 L 0,0 z"
177.47 + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
177.48 + transform="matrix(-0.4,0,0,-0.4,-4,0)" />
177.49 + </marker>
177.50 + <marker
177.51 + inkscape:stockid="Arrow1Lend"
177.52 + orient="auto"
177.53 + refY="0"
177.54 + refX="0"
177.55 + id="Arrow1Lend"
177.56 + style="overflow:visible">
177.57 + <path
177.58 + id="path3207"
177.59 + d="M 0,0 L 5,-5 L -12.5,0 L 5,5 L 0,0 z"
177.60 + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
177.61 + transform="matrix(-0.8,0,0,-0.8,-10,0)" />
177.62 + </marker>
177.63 + <marker
177.64 + inkscape:stockid="Arrow1Lstart"
177.65 + orient="auto"
177.66 + refY="0"
177.67 + refX="0"
177.68 + id="Arrow1Lstart"
177.69 + style="overflow:visible">
177.70 + <path
177.71 + id="path3204"
177.72 + d="M 0,0 L 5,-5 L -12.5,0 L 5,5 L 0,0 z"
177.73 + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
177.74 + transform="matrix(0.8,0,0,0.8,10,0)" />
177.75 + </marker>
177.76 + <inkscape:perspective
177.77 + sodipodi:type="inkscape:persp3d"
177.78 + inkscape:vp_x="0 : 526.18109 : 1"
177.79 + inkscape:vp_y="0 : 1000 : 0"
177.80 + inkscape:vp_z="744.09448 : 526.18109 : 1"
177.81 + inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
177.82 + id="perspective10" />
177.83 + </defs>
177.84 + <sodipodi:namedview
177.85 + id="base"
177.86 + pagecolor="#ffffff"
177.87 + bordercolor="#666666"
177.88 + borderopacity="1.0"
177.89 + gridtolerance="10"
177.90 + guidetolerance="10"
177.91 + objecttolerance="10"
177.92 + inkscape:pageopacity="0.0"
177.93 + inkscape:pageshadow="2"
177.94 + inkscape:zoom="1.4142136"
177.95 + inkscape:cx="305.44602"
177.96 + inkscape:cy="38.897723"
177.97 + inkscape:document-units="mm"
177.98 + inkscape:current-layer="layer1"
177.99 + showgrid="true"
177.100 + inkscape:snap-global="true"
177.101 + units="mm"
177.102 + inkscape:window-width="1226"
177.103 + inkscape:window-height="951"
177.104 + inkscape:window-x="28"
177.105 + inkscape:window-y="47">
177.106 + <inkscape:grid
177.107 + type="xygrid"
177.108 + id="grid2383"
177.109 + visible="true"
177.110 + enabled="true"
177.111 + units="mm"
177.112 + spacingx="2.5mm"
177.113 + spacingy="2.5mm"
177.114 + empspacing="2" />
177.115 + </sodipodi:namedview>
177.116 + <metadata
177.117 + id="metadata7">
177.118 + <rdf:RDF>
177.119 + <cc:Work
177.120 + rdf:about="">
177.121 + <dc:format>image/svg+xml</dc:format>
177.122 + <dc:type
177.123 + rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
177.124 + </cc:Work>
177.125 + </rdf:RDF>
177.126 + </metadata>
177.127 + <g
177.128 + inkscape:label="Layer 1"
177.129 + inkscape:groupmode="layer"
177.130 + id="layer1"
177.131 + transform="translate(-44.641342,-76.87234)">
177.132 + <g
177.133 + id="g3448"
177.134 + transform="translate(70.838012,79.725562)">
177.135 + <rect
177.136 + ry="17.67767"
177.137 + y="131.52507"
177.138 + x="212.09882"
177.139 + height="53.149605"
177.140 + width="70.866142"
177.141 + id="rect3407"
177.142 + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.99921262;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
177.143 + <text
177.144 + sodipodi:linespacing="100%"
177.145 + id="text3409"
177.146 + y="164.06471"
177.147 + x="223.50845"
177.148 + style="font-size:18px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
177.149 + xml:space="preserve"><tspan
177.150 + style="font-size:16px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans Bold"
177.151 + y="164.06471"
177.152 + x="223.50845"
177.153 + id="tspan3411"
177.154 + sodipodi:role="line">chain</tspan></text>
177.155 + </g>
177.156 + <path
177.157 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:0.99921262;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#TriangleOutM);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
177.158 + d="M 424.72469,236.82544 L 356.83209,236.82544 L 356.83209,236.82544"
177.159 + id="path3458" />
177.160 + <path
177.161 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:0.99921268;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#TriangleOutM);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
177.162 + d="M 282.35183,236.82544 L 215.11403,236.82544 L 215.11403,236.82544"
177.163 + id="path4771" />
177.164 + <path
177.165 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:0.99999994px;stroke-linecap:butt;stroke-linejoin:miter;marker-start:none;marker-mid:none;marker-end:url(#TriangleOutM);stroke-opacity:1"
177.166 + d="M 424.69726,192.5341 L 215.13005,192.5341"
177.167 + id="path4773" />
177.168 + <path
177.169 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#TriangleOutM);stroke-opacity:1"
177.170 + d="M 211.98429,148.24276 L 422.13162,148.24276"
177.171 + id="path6883" />
177.172 + <g
177.173 + id="g3443"
177.174 + transform="translate(70.866146,78.725567)">
177.175 + <rect
177.176 + ry="17.67767"
177.177 + y="42.942394"
177.178 + x="70.366531"
177.179 + height="141.73228"
177.180 + width="70.866142"
177.181 + id="rect2586"
177.182 + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.99921262;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
177.183 + <text
177.184 + sodipodi:linespacing="100%"
177.185 + id="text3370"
177.186 + y="116.62494"
177.187 + x="79.682419"
177.188 + style="font-size:18px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
177.189 + xml:space="preserve"><tspan
177.190 + style="font-size:16px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans Bold"
177.191 + y="116.62494"
177.192 + x="79.682419"
177.193 + id="tspan3372"
177.194 + sodipodi:role="line">prove</tspan></text>
177.195 + </g>
177.196 + <path
177.197 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#TriangleOutM);stroke-opacity:1"
177.198 + d="M 176.66575,92.035445 L 176.66575,118.61025"
177.199 + id="path7412" />
177.200 + <path
177.201 + sodipodi:type="arc"
177.202 + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:4.30137062;stroke-linecap:round;stroke-linejoin:round;marker-end:url(#TriangleOutM);stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
177.203 + id="path9011"
177.204 + sodipodi:cx="119.58662"
177.205 + sodipodi:cy="266.74686"
177.206 + sodipodi:rx="93.01181"
177.207 + sodipodi:ry="53.149605"
177.208 + d="M 208.65508,282.05865 A 93.01181,53.149605 0 1 1 208.68579,251.49353"
177.209 + transform="matrix(0.2378166,0,0,-0.2269133,90.621413,253.06251)"
177.210 + sodipodi:start="0.29223018"
177.211 + sodipodi:end="5.9921036"
177.212 + sodipodi:open="true" />
177.213 + <g
177.214 + id="g3453"
177.215 + transform="translate(70.866151,78.725565)">
177.216 + <rect
177.217 + ry="17.67767"
177.218 + y="42.942394"
177.219 + x="353.83112"
177.220 + height="141.73228"
177.221 + width="70.866142"
177.222 + id="rect3381"
177.223 + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.99921262;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
177.224 + <text
177.225 + sodipodi:linespacing="100%"
177.226 + id="text3383"
177.227 + y="119.31244"
177.228 + x="365.98294"
177.229 + style="font-size:18px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
177.230 + xml:space="preserve"><tspan
177.231 + style="font-size:16px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans Bold"
177.232 + y="119.31244"
177.233 + x="365.98294"
177.234 + sodipodi:role="line"
177.235 + id="tspan3387">state</tspan></text>
177.236 + </g>
177.237 + <path
177.238 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#TriangleOutM);stroke-opacity:1"
177.239 + d="M 460.13031,263.40024 L 460.13031,289.97505"
177.240 + id="path7941" />
177.241 + <path
177.242 + sodipodi:type="arc"
177.243 + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:4.30137062;stroke-linecap:round;stroke-linejoin:round;marker-end:url(#TriangleOutM);stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
177.244 + id="path10594"
177.245 + sodipodi:cx="119.58662"
177.246 + sodipodi:cy="266.74686"
177.247 + sodipodi:rx="93.01181"
177.248 + sodipodi:ry="53.149605"
177.249 + d="M 208.65508,282.05865 A 93.01181,53.149605 0 1 1 208.68579,251.49353"
177.250 + transform="matrix(-0.2378166,0,0,0.2269133,546.17466,132.00569)"
177.251 + sodipodi:start="0.29223018"
177.252 + sodipodi:end="5.9921036"
177.253 + sodipodi:open="true" />
177.254 + <path
177.255 + sodipodi:type="arc"
177.256 + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:4.30137062;stroke-linecap:round;stroke-linejoin:bevel;marker-end:url(#TriangleOutM);stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
177.257 + id="path12210"
177.258 + sodipodi:cx="119.58662"
177.259 + sodipodi:cy="266.74686"
177.260 + sodipodi:rx="93.01181"
177.261 + sodipodi:ry="53.149605"
177.262 + d="M 208.65508,282.05865 A 93.01181,53.149605 0 1 1 208.68579,251.49353"
177.263 + transform="matrix(-0.2378166,0,0,0.2269133,546.17465,87.714359)"
177.264 + sodipodi:start="0.29223018"
177.265 + sodipodi:end="5.9921036"
177.266 + sodipodi:open="true" />
177.267 + <path
177.268 + sodipodi:type="arc"
177.269 + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:4.30137062;stroke-linecap:round;stroke-linejoin:round;marker-start:none;marker-end:url(#TriangleOutM);stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
177.270 + id="path12212"
177.271 + sodipodi:cx="119.58662"
177.272 + sodipodi:cy="266.74686"
177.273 + sodipodi:rx="93.01181"
177.274 + sodipodi:ry="53.149605"
177.275 + d="M 208.65508,282.05865 A 93.01181,53.149605 0 1 1 208.68579,251.49353"
177.276 + transform="matrix(-0.2378166,0,0,0.2269133,546.17465,176.29703)"
177.277 + sodipodi:start="0.29223018"
177.278 + sodipodi:end="5.9921036"
177.279 + sodipodi:open="true" />
177.280 + <path
177.281 + sodipodi:type="arc"
177.282 + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:4.30137062;stroke-linecap:round;stroke-linejoin:round;marker-end:url(#TriangleOutM);stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
177.283 + id="path12214"
177.284 + sodipodi:cx="119.58662"
177.285 + sodipodi:cy="266.74686"
177.286 + sodipodi:rx="93.01181"
177.287 + sodipodi:ry="53.149605"
177.288 + d="M 208.65508,282.05865 A 93.01181,53.149605 0 1 1 208.68579,251.49353"
177.289 + transform="matrix(0,0.2378166,0.2269133,0,399.60191,71.056696)"
177.290 + sodipodi:start="0.29223018"
177.291 + sodipodi:end="5.9921036"
177.292 + sodipodi:open="true" />
177.293 + <text
177.294 + xml:space="preserve"
177.295 + style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
177.296 + x="173.49998"
177.297 + y="97.094513"
177.298 + id="text19307"
177.299 + sodipodi:linespacing="100%"
177.300 + transform="translate(17.216929,6.5104864)"><tspan
177.301 + sodipodi:role="line"
177.302 + id="tspan19309"
177.303 + x="173.49998"
177.304 + y="97.094513" /></text>
177.305 + <text
177.306 + xml:space="preserve"
177.307 + style="font-size:10px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
177.308 + x="185.52402"
177.309 + y="110.07987"
177.310 + id="text19311"
177.311 + sodipodi:linespacing="100%"><tspan
177.312 + sodipodi:role="line"
177.313 + id="tspan19313"
177.314 + x="185.52402"
177.315 + y="110.07987">theorem</tspan></text>
177.316 + <text
177.317 + xml:space="preserve"
177.318 + style="font-size:10px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
177.319 + x="389.99997"
177.320 + y="11.594519"
177.321 + id="text19315"
177.322 + sodipodi:linespacing="100%"
177.323 + transform="translate(17.216929,6.5104864)"><tspan
177.324 + sodipodi:role="line"
177.325 + id="tspan19317"
177.326 + x="389.99997"
177.327 + y="11.594519" /></text>
177.328 + <text
177.329 + xml:space="preserve"
177.330 + style="font-size:10px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
177.331 + x="468.98859"
177.332 + y="280.47543"
177.333 + id="text19319"
177.334 + sodipodi:linespacing="100%"><tspan
177.335 + sodipodi:role="line"
177.336 + id="tspan19321"
177.337 + x="468.98859"
177.338 + y="280.47543">qed</tspan></text>
177.339 + <text
177.340 + xml:space="preserve"
177.341 + style="font-size:10px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
177.342 + x="549.06946"
177.343 + y="239.58423"
177.344 + id="text19323"
177.345 + sodipodi:linespacing="100%"><tspan
177.346 + sodipodi:role="line"
177.347 + id="tspan19325"
177.348 + x="549.06946"
177.349 + y="239.58423">qed</tspan></text>
177.350 + <text
177.351 + xml:space="preserve"
177.352 + style="font-size:10px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
177.353 + x="549.39172"
177.354 + y="191.26213"
177.355 + id="text19327"
177.356 + sodipodi:linespacing="100%"><tspan
177.357 + sodipodi:role="line"
177.358 + id="tspan19329"
177.359 + x="549.39172"
177.360 + y="191.26213">fix</tspan><tspan
177.361 + sodipodi:role="line"
177.362 + x="549.39172"
177.363 + y="201.26213"
177.364 + id="tspan19331">assume</tspan></text>
177.365 + <text
177.366 + xml:space="preserve"
177.367 + style="font-size:10px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
177.368 + x="548.71301"
177.369 + y="146.97079"
177.370 + id="text19333"
177.371 + sodipodi:linespacing="100%"><tspan
177.372 + sodipodi:role="line"
177.373 + id="tspan19335"
177.374 + x="548.71301"
177.375 + y="146.97079">{ }</tspan><tspan
177.376 + sodipodi:role="line"
177.377 + x="548.71301"
177.378 + y="156.97079"
177.379 + id="tspan19337">next</tspan></text>
177.380 + <text
177.381 + xml:space="preserve"
177.382 + style="font-size:10px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
177.383 + x="477.84686"
177.384 + y="98.264297"
177.385 + id="text19339"
177.386 + sodipodi:linespacing="100%"><tspan
177.387 + sodipodi:role="line"
177.388 + x="477.84686"
177.389 + y="98.264297"
177.390 + id="tspan19343">note</tspan><tspan
177.391 + sodipodi:role="line"
177.392 + x="477.84686"
177.393 + y="108.2643"
177.394 + id="tspan19358">let</tspan></text>
177.395 + <text
177.396 + xml:space="preserve"
177.397 + style="font-size:10px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
177.398 + x="43.791733"
177.399 + y="190.29289"
177.400 + id="text19345"
177.401 + sodipodi:linespacing="100%"><tspan
177.402 + sodipodi:role="line"
177.403 + id="tspan19347"
177.404 + x="43.791733"
177.405 + y="190.29289">using</tspan><tspan
177.406 + sodipodi:role="line"
177.407 + x="43.791733"
177.408 + y="200.29289"
177.409 + id="tspan19349">unfolding</tspan></text>
177.410 + <text
177.411 + xml:space="preserve"
177.412 + style="font-size:10px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
177.413 + x="378.65891"
177.414 + y="230.52518"
177.415 + id="text19360"
177.416 + sodipodi:linespacing="100%"><tspan
177.417 + sodipodi:role="line"
177.418 + id="tspan19362"
177.419 + x="378.65891"
177.420 + y="230.52518">then</tspan></text>
177.421 + <text
177.422 + xml:space="preserve"
177.423 + style="font-size:10px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:150%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
177.424 + x="233.98795"
177.425 + y="233.05347"
177.426 + id="text19364"
177.427 + sodipodi:linespacing="150%"><tspan
177.428 + sodipodi:role="line"
177.429 + x="233.98795"
177.430 + y="233.05347"
177.431 + id="tspan19368">have</tspan><tspan
177.432 + sodipodi:role="line"
177.433 + x="233.98795"
177.434 + y="248.05347"
177.435 + id="tspan19370">show</tspan></text>
177.436 + <text
177.437 + xml:space="preserve"
177.438 + style="font-size:10px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:150%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
177.439 + x="305.89636"
177.440 + y="188.76213"
177.441 + id="text19374"
177.442 + sodipodi:linespacing="150%"><tspan
177.443 + sodipodi:role="line"
177.444 + x="305.89636"
177.445 + y="188.76213"
177.446 + id="tspan19376">have</tspan><tspan
177.447 + sodipodi:role="line"
177.448 + x="305.89636"
177.449 + y="203.76213"
177.450 + id="tspan19378">show</tspan></text>
177.451 + <text
177.452 + xml:space="preserve"
177.453 + style="font-size:10px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
177.454 + x="303.82324"
177.455 + y="141.07895"
177.456 + id="text19380"
177.457 + sodipodi:linespacing="100%"><tspan
177.458 + sodipodi:role="line"
177.459 + id="tspan19382"
177.460 + x="303.82324"
177.461 + y="141.07895">proof</tspan></text>
177.462 + </g>
177.463 +</svg>
178.1 --- a/doc-src/Locales/.cvsignore Wed Mar 04 11:05:02 2009 +0100
178.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
178.3 @@ -1,2 +0,0 @@
178.4 -locales.out
178.5 -locales.pdf
179.1 --- a/doc-src/Ref/goals.tex Wed Mar 04 11:05:02 2009 +0100
179.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
179.3 @@ -1,722 +0,0 @@
179.4 -%% $Id$
179.5 -\chapter{Proof Management: The Subgoal Module}
179.6 -\index{proofs|(}
179.7 -\index{subgoal module|(}
179.8 -\index{reading!goals|see{proofs, starting}}
179.9 -
179.10 -The subgoal module stores the current proof state\index{proof state} and
179.11 -many previous states; commands can produce new states or return to previous
179.12 -ones. The {\em state list\/} at level $n$ is a list of pairs
179.13 -\[ [(\psi@n,\Psi@n),\; (\psi@{n-1},\Psi@{n-1}),\; \ldots,\; (\psi@0,[])] \]
179.14 -where $\psi@n$ is the current proof state, $\psi@{n-1}$ is the previous
179.15 -one, \ldots, and $\psi@0$ is the initial proof state. The $\Psi@i$ are
179.16 -sequences (lazy lists) of proof states, storing branch points where a
179.17 -tactic returned a list longer than one. The state lists permit various
179.18 -forms of backtracking.
179.19 -
179.20 -Chopping elements from the state list reverts to previous proof states.
179.21 -Besides this, the \ttindex{undo} command keeps a list of state lists. The
179.22 -module actually maintains a stack of state lists, to support several
179.23 -proofs at the same time.
179.24 -
179.25 -The subgoal module always contains some proof state. At the start of the
179.26 -Isabelle session, this state consists of a dummy formula.
179.27 -
179.28 -
179.29 -\section{Basic commands}
179.30 -Most proofs begin with \texttt{Goal} or \texttt{Goalw} and require no other
179.31 -commands than \texttt{by}, \texttt{chop} and \texttt{undo}. They typically end
179.32 -with a call to \texttt{qed}.
179.33 -\subsection{Starting a backward proof}
179.34 -\index{proofs!starting}
179.35 -\begin{ttbox}
179.36 -Goal : string -> thm list
179.37 -Goalw : thm list -> string -> thm list
179.38 -goal : theory -> string -> thm list
179.39 -goalw : theory -> thm list -> string -> thm list
179.40 -goalw_cterm : thm list -> cterm -> thm list
179.41 -premises : unit -> thm list
179.42 -\end{ttbox}
179.43 -
179.44 -The goal commands start a new proof by setting the goal. They replace
179.45 -the current state list by a new one consisting of the initial proof
179.46 -state. They also empty the \ttindex{undo} list; this command cannot
179.47 -be undone!
179.48 -
179.49 -They all return a list of meta-hypotheses taken from the main goal. If
179.50 -this list is non-empty, bind its value to an \ML{} identifier by typing
179.51 -something like
179.52 -\begin{ttbox}
179.53 -val prems = goal{\it theory\/ formula};
179.54 -\end{ttbox}\index{assumptions!of main goal}
179.55 -These assumptions typically serve as the premises when you are
179.56 -deriving a rule. They are also stored internally and can be retrieved
179.57 -later by the function \texttt{premises}. When the proof is finished,
179.58 -\texttt{qed} compares the stored assumptions with the actual
179.59 -assumptions in the proof state.
179.60 -
179.61 -The capital versions of \texttt{Goal} are the basic user level
179.62 -commands and should be preferred over the more primitive lowercase
179.63 -\texttt{goal} commands. Apart from taking the current theory context
179.64 -as implicit argument, the former ones try to be smart in handling
179.65 -meta-hypotheses when deriving rules. Thus \texttt{prems} have to be
179.66 -seldom bound explicitly, the effect is as if \texttt{cut_facts_tac}
179.67 -had been called automatically.
179.68 -
179.69 -\index{definitions!unfolding}
179.70 -Some of the commands unfold definitions using meta-rewrite rules. This
179.71 -expansion affects both the initial subgoal and the premises, which would
179.72 -otherwise require use of \texttt{rewrite_goals_tac} and
179.73 -\texttt{rewrite_rule}.
179.74 -
179.75 -\begin{ttdescription}
179.76 -\item[\ttindexbold{Goal} {\it formula};] begins a new proof, where
179.77 - {\it formula\/} is written as an \ML\ string.
179.78 -
179.79 -\item[\ttindexbold{Goalw} {\it defs} {\it formula};] is like
179.80 - \texttt{Goal} but also applies the list of {\it defs\/} as
179.81 - meta-rewrite rules to the first subgoal and the premises.
179.82 - \index{meta-rewriting}
179.83 -
179.84 -\item[\ttindexbold{goal} {\it theory} {\it formula};]
179.85 -begins a new proof, where {\it theory} is usually an \ML\ identifier
179.86 -and the {\it formula\/} is written as an \ML\ string.
179.87 -
179.88 -\item[\ttindexbold{goalw} {\it theory} {\it defs} {\it formula};]
179.89 -is like \texttt{goal} but also applies the list of {\it defs\/} as
179.90 -meta-rewrite rules to the first subgoal and the premises.
179.91 -\index{meta-rewriting}
179.92 -
179.93 -\item[\ttindexbold{goalw_cterm} {\it defs} {\it ct};] is
179.94 - a version of \texttt{goalw} intended for programming. The main
179.95 - goal is supplied as a cterm, not as a string. See also
179.96 - \texttt{prove_goalw_cterm}, \S\ref{sec:executing-batch}.
179.97 -
179.98 -\item[\ttindexbold{premises}()]
179.99 -returns the list of meta-hypotheses associated with the current proof (in
179.100 -case you forgot to bind them to an \ML{} identifier).
179.101 -\end{ttdescription}
179.102 -
179.103 -
179.104 -\subsection{Applying a tactic}
179.105 -\index{tactics!commands for applying}
179.106 -\begin{ttbox}
179.107 -by : tactic -> unit
179.108 -byev : tactic list -> unit
179.109 -\end{ttbox}
179.110 -These commands extend the state list. They apply a tactic to the current
179.111 -proof state. If the tactic succeeds, it returns a non-empty sequence of
179.112 -next states. The head of the sequence becomes the next state, while the
179.113 -tail is retained for backtracking (see~\texttt{back}).
179.114 -\begin{ttdescription} \item[\ttindexbold{by} {\it tactic};]
179.115 -applies the {\it tactic\/} to the proof state.
179.116 -
179.117 -\item[\ttindexbold{byev} {\it tactics};]
179.118 -applies the list of {\it tactics}, one at a time. It is useful for testing
179.119 -calls to \texttt{prove_goal}, and abbreviates \texttt{by (EVERY {\it
179.120 -tactics})}.
179.121 -\end{ttdescription}
179.122 -
179.123 -\noindent{\it Error indications:}\nobreak
179.124 -\begin{itemize}
179.125 -\item {\footnotesize\tt "by:\ tactic failed"} means that the tactic
179.126 - returned an empty sequence when applied to the current proof state.
179.127 -\item {\footnotesize\tt "Warning:\ same as previous level"} means that the
179.128 - new proof state is identical to the previous state.
179.129 -\item{\footnotesize\tt "Warning:\ signature of proof state has changed"}
179.130 - means that some rule was applied whose theory is outside the theory of
179.131 - the initial proof state. This could signify a mistake such as expressing
179.132 - the goal in intuitionistic logic and proving it using classical logic.
179.133 -\end{itemize}
179.134 -
179.135 -\subsection{Extracting and storing the proved theorem}
179.136 -\label{ExtractingAndStoringTheProvedTheorem}
179.137 -\index{theorems!extracting proved}
179.138 -\begin{ttbox}
179.139 -qed : string -> unit
179.140 -no_qed : unit -> unit
179.141 -result : unit -> thm
179.142 -uresult : unit -> thm
179.143 -bind_thm : string * thm -> unit
179.144 -bind_thms : string * thm list -> unit
179.145 -store_thm : string * thm -> thm
179.146 -store_thms : string * thm list -> thm list
179.147 -\end{ttbox}
179.148 -\begin{ttdescription}
179.149 -\item[\ttindexbold{qed} $name$;] is the usual way of ending a proof.
179.150 - It combines \texttt{result} and \texttt{bind_thm}: it gets the theorem
179.151 - using \texttt{result()} and stores it the theorem database associated
179.152 - with its theory. See below for details.
179.153 -
179.154 -\item[\ttindexbold{no_qed}();] indicates that the proof is not concluded by a
179.155 - proper \texttt{qed} command. This is a do-nothing operation, it merely
179.156 - helps user interfaces such as Proof~General \cite{proofgeneral} to figure
179.157 - out the structure of the {\ML} text.
179.158 -
179.159 -\item[\ttindexbold{result}()]\index{assumptions!of main goal}
179.160 - returns the final theorem, after converting the free variables to
179.161 - schematics. It discharges the assumptions supplied to the matching
179.162 - \texttt{goal} command.
179.163 -
179.164 - It raises an exception unless the proof state passes certain checks. There
179.165 - must be no assumptions other than those supplied to \texttt{goal}. There
179.166 - must be no subgoals. The theorem proved must be a (first-order) instance
179.167 - of the original goal, as stated in the \texttt{goal} command. This allows
179.168 - {\bf answer extraction} --- instantiation of variables --- but no other
179.169 - changes to the main goal. The theorem proved must have the same signature
179.170 - as the initial proof state.
179.171 -
179.172 - These checks are needed because an Isabelle tactic can return any proof
179.173 - state at all.
179.174 -
179.175 -\item[\ttindexbold{uresult}()] is like \texttt{result()} but omits the checks.
179.176 - It is needed when the initial goal contains function unknowns, when
179.177 - definitions are unfolded in the main goal (by calling
179.178 - \ttindex{rewrite_tac}),\index{definitions!unfolding} or when
179.179 - \ttindex{assume_ax} has been used.
179.180 -
179.181 -\item[\ttindexbold{bind_thm} ($name$, $thm$);]\index{theorems!storing}
179.182 - stores \texttt{standard $thm$} (see \S\ref{MiscellaneousForwardRules})
179.183 - in the theorem database associated with its theory and in the {\ML}
179.184 - variable $name$. The theorem can be retrieved from the database
179.185 - using \texttt{get_thm} (see \S\ref{BasicOperationsOnTheories}).
179.186 -
179.187 -\item[\ttindexbold{store_thm} ($name$, $thm$)]\index{theorems!storing}
179.188 - stores $thm$ in the theorem database associated with its theory and
179.189 - returns that theorem.
179.190 -
179.191 -\item[\ttindexbold{bind_thms} \textrm{and} \ttindexbold{store_thms}] are similar to
179.192 - \texttt{bind_thm} and \texttt{store_thm}, but store lists of theorems.
179.193 -
179.194 -\end{ttdescription}
179.195 -
179.196 -The name argument of \texttt{qed}, \texttt{bind_thm} etc.\ may be the empty
179.197 -string as well; in that case the result is \emph{not} stored, but proper
179.198 -checks and presentation of the result still apply.
179.199 -
179.200 -
179.201 -\subsection{Extracting axioms and stored theorems}
179.202 -\index{theories!axioms of}\index{axioms!extracting}
179.203 -\index{theories!theorems of}\index{theorems!extracting}
179.204 -\begin{ttbox}
179.205 -thm : xstring -> thm
179.206 -thms : xstring -> thm list
179.207 -get_axiom : theory -> xstring -> thm
179.208 -get_thm : theory -> xstring -> thm
179.209 -get_thms : theory -> xstring -> thm list
179.210 -axioms_of : theory -> (string * thm) list
179.211 -thms_of : theory -> (string * thm) list
179.212 -assume_ax : theory -> string -> thm
179.213 -\end{ttbox}
179.214 -\begin{ttdescription}
179.215 -
179.216 -\item[\ttindexbold{thm} $name$] is the basic user function for
179.217 - extracting stored theorems from the current theory context.
179.218 -
179.219 -\item[\ttindexbold{thms} $name$] is like \texttt{thm}, but returns a
179.220 - whole list associated with $name$ rather than a single theorem.
179.221 - Typically this will be collections stored by packages, e.g.\
179.222 - \verb|list.simps|.
179.223 -
179.224 -\item[\ttindexbold{get_axiom} $thy$ $name$] returns an axiom with the
179.225 - given $name$ from $thy$ or any of its ancestors, raising exception
179.226 - \xdx{THEORY} if none exists. Merging theories can cause several
179.227 - axioms to have the same name; {\tt get_axiom} returns an arbitrary
179.228 - one. Usually, axioms are also stored as theorems and may be
179.229 - retrieved via \texttt{get_thm} as well.
179.230 -
179.231 -\item[\ttindexbold{get_thm} $thy$ $name$] is analogous to {\tt
179.232 - get_axiom}, but looks for a theorem stored in the theory's
179.233 - database. Like {\tt get_axiom} it searches all parents of a theory
179.234 - if the theorem is not found directly in $thy$.
179.235 -
179.236 -\item[\ttindexbold{get_thms} $thy$ $name$] is like \texttt{get_thm}
179.237 - for retrieving theorem lists stored within the theory. It returns a
179.238 - singleton list if $name$ actually refers to a theorem rather than a
179.239 - theorem list.
179.240 -
179.241 -\item[\ttindexbold{axioms_of} $thy$] returns the axioms of this theory
179.242 - node, not including the ones of its ancestors.
179.243 -
179.244 -\item[\ttindexbold{thms_of} $thy$] returns all theorems stored within
179.245 - the database of this theory node, not including the ones of its
179.246 - ancestors.
179.247 -
179.248 -\item[\ttindexbold{assume_ax} $thy$ $formula$] reads the {\it formula}
179.249 - using the syntax of $thy$, following the same conventions as axioms
179.250 - in a theory definition. You can thus pretend that {\it formula} is
179.251 - an axiom and use the resulting theorem like an axiom. Actually {\tt
179.252 - assume_ax} returns an assumption; \ttindex{qed} and
179.253 - \ttindex{result} complain about additional assumptions, but
179.254 - \ttindex{uresult} does not.
179.255 -
179.256 -For example, if {\it formula} is
179.257 -\hbox{\tt a=b ==> b=a} then the resulting theorem has the form
179.258 -\hbox{\verb'?a=?b ==> ?b=?a [!!a b. a=b ==> b=a]'}
179.259 -\end{ttdescription}
179.260 -
179.261 -
179.262 -\subsection{Retrieving theorems}
179.263 -\index{theorems!retrieving}
179.264 -
179.265 -The following functions retrieve theorems (together with their names)
179.266 -from the theorem database that is associated with the current proof
179.267 -state's theory. They can only find theorems that have explicitly been
179.268 -stored in the database using \ttindex{qed}, \ttindex{bind_thm} or
179.269 -related functions.
179.270 -\begin{ttbox}
179.271 -findI : int -> (string * thm) list
179.272 -findE : int -> int -> (string * thm) list
179.273 -findEs : int -> (string * thm) list
179.274 -thms_containing : xstring list -> (string * thm) list
179.275 -\end{ttbox}
179.276 -\begin{ttdescription}
179.277 -\item[\ttindexbold{findI} $i$]\index{assumptions!of main goal}
179.278 - returns all ``introduction rules'' applicable to subgoal $i$ --- all
179.279 - theorems whose conclusion matches (rather than unifies with) subgoal
179.280 - $i$. Useful in connection with \texttt{resolve_tac}.
179.281 -
179.282 -\item[\ttindexbold{findE} $n$ $i$] returns all ``elimination rules''
179.283 - applicable to premise $n$ of subgoal $i$ --- all those theorems whose
179.284 - first premise matches premise $n$ of subgoal $i$. Useful in connection with
179.285 - \texttt{eresolve_tac} and \texttt{dresolve_tac}.
179.286 -
179.287 -\item[\ttindexbold{findEs} $i$] returns all ``elimination rules'' applicable
179.288 - to subgoal $i$ --- all those theorems whose first premise matches some
179.289 - premise of subgoal $i$. Useful in connection with \texttt{eresolve_tac} and
179.290 - \texttt{dresolve_tac}.
179.291 -
179.292 -\item[\ttindexbold{thms_containing} $consts$] returns all theorems that
179.293 - contain \emph{all} of the given constants.
179.294 -\end{ttdescription}
179.295 -
179.296 -
179.297 -\subsection{Undoing and backtracking}
179.298 -\begin{ttbox}
179.299 -chop : unit -> unit
179.300 -choplev : int -> unit
179.301 -back : unit -> unit
179.302 -undo : unit -> unit
179.303 -\end{ttbox}
179.304 -\begin{ttdescription}
179.305 -\item[\ttindexbold{chop}();]
179.306 -deletes the top level of the state list, cancelling the last \ttindex{by}
179.307 -command. It provides a limited undo facility, and the \texttt{undo} command
179.308 -can cancel it.
179.309 -
179.310 -\item[\ttindexbold{choplev} {\it n};]
179.311 -truncates the state list to level~{\it n}, if $n\geq0$. A negative value
179.312 -of~$n$ refers to the $n$th previous level:
179.313 -\hbox{\verb|choplev ~1|} has the same effect as \texttt{chop}.
179.314 -
179.315 -\item[\ttindexbold{back}();]
179.316 -searches the state list for a non-empty branch point, starting from the top
179.317 -level. The first one found becomes the current proof state --- the most
179.318 -recent alternative branch is taken. This is a form of interactive
179.319 -backtracking.
179.320 -
179.321 -\item[\ttindexbold{undo}();]
179.322 -cancels the most recent change to the proof state by the commands \ttindex{by},
179.323 -\texttt{chop}, \texttt{choplev}, and~\texttt{back}. It {\bf cannot}
179.324 -cancel \texttt{goal} or \texttt{undo} itself. It can be repeated to
179.325 -cancel a series of commands.
179.326 -\end{ttdescription}
179.327 -
179.328 -\goodbreak
179.329 -\noindent{\it Error indications for {\tt back}:}\par\nobreak
179.330 -\begin{itemize}
179.331 -\item{\footnotesize\tt"Warning:\ same as previous choice at this level"}
179.332 - means \texttt{back} found a non-empty branch point, but that it contained
179.333 - the same proof state as the current one.
179.334 -\item{\footnotesize\tt "Warning:\ signature of proof state has changed"}
179.335 - means the signature of the alternative proof state differs from that of
179.336 - the current state.
179.337 -\item {\footnotesize\tt "back:\ no alternatives"} means \texttt{back} could
179.338 - find no alternative proof state.
179.339 -\end{itemize}
179.340 -
179.341 -\subsection{Printing the proof state}\label{sec:goals-printing}
179.342 -\index{proof state!printing of}
179.343 -\begin{ttbox}
179.344 -pr : unit -> unit
179.345 -prlev : int -> unit
179.346 -prlim : int -> unit
179.347 -goals_limit: int ref \hfill{\bf initially 10}
179.348 -\end{ttbox}
179.349 -See also the printing control options described
179.350 -in~\S\ref{sec:printing-control}.
179.351 -\begin{ttdescription}
179.352 -\item[\ttindexbold{pr}();]
179.353 -prints the current proof state.
179.354 -
179.355 -\item[\ttindexbold{prlev} {\it n};]
179.356 -prints the proof state at level {\it n}, if $n\geq0$. A negative value
179.357 -of~$n$ refers to the $n$th previous level. This command allows
179.358 -you to review earlier stages of the proof.
179.359 -
179.360 -\item[\ttindexbold{prlim} {\it k};]
179.361 -prints the current proof state, limiting the number of subgoals to~$k$. It
179.362 -updates \texttt{goals_limit} (see below) and is helpful when there are many
179.363 -subgoals.
179.364 -
179.365 -\item[\ttindexbold{goals_limit} := {\it k};]
179.366 -specifies~$k$ as the maximum number of subgoals to print.
179.367 -\end{ttdescription}
179.368 -
179.369 -
179.370 -\subsection{Timing}
179.371 -\index{timing statistics}\index{proofs!timing}
179.372 -\begin{ttbox}
179.373 -timing: bool ref \hfill{\bf initially false}
179.374 -\end{ttbox}
179.375 -
179.376 -\begin{ttdescription}
179.377 -\item[set \ttindexbold{timing};] enables global timing in Isabelle. In
179.378 - particular, this makes the \ttindex{by} and \ttindex{prove_goal} commands
179.379 - display how much processor time was spent. This information is
179.380 - compiler-dependent.
179.381 -\end{ttdescription}
179.382 -
179.383 -
179.384 -\section{Shortcuts for applying tactics}
179.385 -\index{shortcuts!for \texttt{by} commands}
179.386 -These commands call \ttindex{by} with common tactics. Their chief purpose
179.387 -is to minimise typing, although the scanning shortcuts are useful in their
179.388 -own right. Chapter~\ref{tactics} explains the tactics themselves.
179.389 -
179.390 -\subsection{Refining a given subgoal}
179.391 -\begin{ttbox}
179.392 -ba : int -> unit
179.393 -br : thm -> int -> unit
179.394 -be : thm -> int -> unit
179.395 -bd : thm -> int -> unit
179.396 -brs : thm list -> int -> unit
179.397 -bes : thm list -> int -> unit
179.398 -bds : thm list -> int -> unit
179.399 -\end{ttbox}
179.400 -
179.401 -\begin{ttdescription}
179.402 -\item[\ttindexbold{ba} {\it i};]
179.403 -performs \texttt{by (assume_tac {\it i});}
179.404 -
179.405 -\item[\ttindexbold{br} {\it thm} {\it i};]
179.406 -performs \texttt{by (resolve_tac [{\it thm}] {\it i});}
179.407 -
179.408 -\item[\ttindexbold{be} {\it thm} {\it i};]
179.409 -performs \texttt{by (eresolve_tac [{\it thm}] {\it i});}
179.410 -
179.411 -\item[\ttindexbold{bd} {\it thm} {\it i};]
179.412 -performs \texttt{by (dresolve_tac [{\it thm}] {\it i});}
179.413 -
179.414 -\item[\ttindexbold{brs} {\it thms} {\it i};]
179.415 -performs \texttt{by (resolve_tac {\it thms} {\it i});}
179.416 -
179.417 -\item[\ttindexbold{bes} {\it thms} {\it i};]
179.418 -performs \texttt{by (eresolve_tac {\it thms} {\it i});}
179.419 -
179.420 -\item[\ttindexbold{bds} {\it thms} {\it i};]
179.421 -performs \texttt{by (dresolve_tac {\it thms} {\it i});}
179.422 -\end{ttdescription}
179.423 -
179.424 -
179.425 -\subsection{Scanning shortcuts}
179.426 -These shortcuts scan for a suitable subgoal (starting from subgoal~1).
179.427 -They refine the first subgoal for which the tactic succeeds. Thus, they
179.428 -require less typing than \texttt{br}, etc. They display the selected
179.429 -subgoal's number; please watch this, for it may not be what you expect!
179.430 -
179.431 -\begin{ttbox}
179.432 -fa : unit -> unit
179.433 -fr : thm -> unit
179.434 -fe : thm -> unit
179.435 -fd : thm -> unit
179.436 -frs : thm list -> unit
179.437 -fes : thm list -> unit
179.438 -fds : thm list -> unit
179.439 -\end{ttbox}
179.440 -
179.441 -\begin{ttdescription}
179.442 -\item[\ttindexbold{fa}();]
179.443 -solves some subgoal by assumption.
179.444 -
179.445 -\item[\ttindexbold{fr} {\it thm};]
179.446 -refines some subgoal using \texttt{resolve_tac [{\it thm}]}
179.447 -
179.448 -\item[\ttindexbold{fe} {\it thm};]
179.449 -refines some subgoal using \texttt{eresolve_tac [{\it thm}]}
179.450 -
179.451 -\item[\ttindexbold{fd} {\it thm};]
179.452 -refines some subgoal using \texttt{dresolve_tac [{\it thm}]}
179.453 -
179.454 -\item[\ttindexbold{frs} {\it thms};]
179.455 -refines some subgoal using \texttt{resolve_tac {\it thms}}
179.456 -
179.457 -\item[\ttindexbold{fes} {\it thms};]
179.458 -refines some subgoal using \texttt{eresolve_tac {\it thms}}
179.459 -
179.460 -\item[\ttindexbold{fds} {\it thms};]
179.461 -refines some subgoal using \texttt{dresolve_tac {\it thms}}
179.462 -\end{ttdescription}
179.463 -
179.464 -\subsection{Other shortcuts}
179.465 -\begin{ttbox}
179.466 -bw : thm -> unit
179.467 -bws : thm list -> unit
179.468 -ren : string -> int -> unit
179.469 -\end{ttbox}
179.470 -\begin{ttdescription}
179.471 -\item[\ttindexbold{bw} {\it def};] performs \texttt{by
179.472 - (rewrite_goals_tac [{\it def}]);} It unfolds definitions in the
179.473 - subgoals (but not the main goal), by meta-rewriting with the given
179.474 - definition (see also \S\ref{sec:rewrite_goals}).
179.475 - \index{meta-rewriting}
179.476 -
179.477 -\item[\ttindexbold{bws}]
179.478 -is like \texttt{bw} but takes a list of definitions.
179.479 -
179.480 -\item[\ttindexbold{ren} {\it names} {\it i};]
179.481 -performs \texttt{by (rename_tac {\it names} {\it i});} it renames
179.482 -parameters in subgoal~$i$. (Ignore the message {\footnotesize\tt Warning:\
179.483 - same as previous level}.)
179.484 -\index{parameters!renaming}
179.485 -\end{ttdescription}
179.486 -
179.487 -
179.488 -\section{Executing batch proofs}\label{sec:executing-batch}
179.489 -\index{batch execution}%
179.490 -To save space below, let type \texttt{tacfn} abbreviate \texttt{thm list ->
179.491 - tactic list}, which is the type of a tactical proof.
179.492 -\begin{ttbox}
179.493 -prove_goal : theory -> string -> tacfn -> thm
179.494 -qed_goal : string -> theory -> string -> tacfn -> unit
179.495 -prove_goalw: theory -> thm list -> string -> tacfn -> thm
179.496 -qed_goalw : string -> theory -> thm list -> string -> tacfn -> unit
179.497 -prove_goalw_cterm: thm list -> cterm -> tacfn -> thm
179.498 -\end{ttbox}
179.499 -These batch functions create an initial proof state, then apply a tactic to
179.500 -it, yielding a sequence of final proof states. The head of the sequence is
179.501 -returned, provided it is an instance of the theorem originally proposed.
179.502 -The forms \texttt{prove_goal}, \texttt{prove_goalw} and
179.503 -\texttt{prove_goalw_cterm} are analogous to \texttt{goal}, \texttt{goalw} and
179.504 -\texttt{goalw_cterm}.
179.505 -
179.506 -The tactic is specified by a function from theorem lists to tactic lists.
179.507 -The function is applied to the list of meta-assumptions taken from
179.508 -the main goal. The resulting tactics are applied in sequence (using {\tt
179.509 - EVERY}). For example, a proof consisting of the commands
179.510 -\begin{ttbox}
179.511 -val prems = goal {\it theory} {\it formula};
179.512 -by \(tac@1\); \ldots by \(tac@n\);
179.513 -qed "my_thm";
179.514 -\end{ttbox}
179.515 -can be transformed to an expression as follows:
179.516 -\begin{ttbox}
179.517 -qed_goal "my_thm" {\it theory} {\it formula}
179.518 - (fn prems=> [ \(tac@1\), \ldots, \(tac@n\) ]);
179.519 -\end{ttbox}
179.520 -The methods perform identical processing of the initial {\it formula} and
179.521 -the final proof state. But \texttt{prove_goal} executes the tactic as a
179.522 -atomic operation, bypassing the subgoal module; the current interactive
179.523 -proof is unaffected.
179.524 -%
179.525 -\begin{ttdescription}
179.526 -\item[\ttindexbold{prove_goal} {\it theory} {\it formula} {\it tacsf};]
179.527 -executes a proof of the {\it formula\/} in the given {\it theory}, using
179.528 -the given tactic function.
179.529 -
179.530 -\item[\ttindexbold{qed_goal} $name$ $theory$ $formula$ $tacsf$;] acts
179.531 - like \texttt{prove_goal} but it also stores the resulting theorem in the
179.532 - theorem database associated with its theory and in the {\ML}
179.533 - variable $name$ (see \S\ref{ExtractingAndStoringTheProvedTheorem}).
179.534 -
179.535 -\item[\ttindexbold{prove_goalw} {\it theory} {\it defs} {\it formula}
179.536 - {\it tacsf};]\index{meta-rewriting}
179.537 -is like \texttt{prove_goal} but also applies the list of {\it defs\/} as
179.538 -meta-rewrite rules to the first subgoal and the premises.
179.539 -
179.540 -\item[\ttindexbold{qed_goalw} $name$ $theory$ $defs$ $formula$ $tacsf$;]
179.541 -is analogous to \texttt{qed_goal}.
179.542 -
179.543 -\item[\ttindexbold{prove_goalw_cterm} {\it defs} {\it ct}
179.544 - {\it tacsf};]
179.545 -is a version of \texttt{prove_goalw} intended for programming. The main
179.546 -goal is supplied as a cterm, not as a string. A cterm carries a theory with
179.547 - it, and can be created from a term~$t$ by
179.548 -\begin{ttbox}
179.549 -cterm_of (sign_of thy) \(t\)
179.550 -\end{ttbox}
179.551 - \index{*cterm_of}\index{*sign_of}
179.552 -\end{ttdescription}
179.553 -
179.554 -
179.555 -\section{Internal proofs}
179.556 -
179.557 -\begin{ttbox}
179.558 -Tactic.prove: Sign.sg -> string list -> term list -> term ->
179.559 - (thm list -> tactic) -> thm
179.560 -Tactic.prove_standard: Sign.sg -> string list -> term list -> term ->
179.561 - (thm list -> tactic) -> thm
179.562 -\end{ttbox}
179.563 -
179.564 -These functions provide a clean internal interface for programmed proofs. The
179.565 -special overhead of top-level statements (cf.\ \verb,prove_goalw_cterm,) is
179.566 -omitted. Statements may be established within a local contexts of fixed
179.567 -variables and assumptions, which are the only hypotheses to be discharged in
179.568 -the result.
179.569 -
179.570 -\begin{ttdescription}
179.571 -\item[\ttindexbold{Tactic.prove}~$sg~xs~As~C~tacf$] establishes the result
179.572 - $\Forall xs. As \Imp C$ via the given tactic (which is a function taking the
179.573 - assumptions as local premises).
179.574 -
179.575 -\item[\ttindexbold{Tactic.prove_standard}] is simular to \verb,Tactic.prove,,
179.576 - but performs the \verb,standard, operation on the result, essentially
179.577 - turning it into a top-level statement. Never do this for local proofs
179.578 - within other proof tools!
179.579 -
179.580 -\end{ttdescription}
179.581 -
179.582 -
179.583 -\section{Managing multiple proofs}
179.584 -\index{proofs!managing multiple}
179.585 -You may save the current state of the subgoal module and resume work on it
179.586 -later. This serves two purposes.
179.587 -\begin{enumerate}
179.588 -\item At some point, you may be uncertain of the next step, and
179.589 -wish to experiment.
179.590 -
179.591 -\item During a proof, you may see that a lemma should be proved first.
179.592 -\end{enumerate}
179.593 -Each saved proof state consists of a list of levels; \ttindex{chop} behaves
179.594 -independently for each of the saved proofs. In addition, each saved state
179.595 -carries a separate \ttindex{undo} list.
179.596 -
179.597 -\subsection{The stack of proof states}
179.598 -\index{proofs!stacking}
179.599 -\begin{ttbox}
179.600 -push_proof : unit -> unit
179.601 -pop_proof : unit -> thm list
179.602 -rotate_proof : unit -> thm list
179.603 -\end{ttbox}
179.604 -The subgoal module maintains a stack of proof states. Most subgoal
179.605 -commands affect only the top of the stack. The \ttindex{Goal} command {\em
179.606 -replaces\/} the top of the stack; the only command that pushes a proof on the
179.607 -stack is \texttt{push_proof}.
179.608 -
179.609 -To save some point of the proof, call \texttt{push_proof}. You may now
179.610 -state a lemma using \texttt{goal}, or simply continue to apply tactics.
179.611 -Later, you can return to the saved point by calling \texttt{pop_proof} or
179.612 -\texttt{rotate_proof}.
179.613 -
179.614 -To view the entire stack, call \texttt{rotate_proof} repeatedly; as it rotates
179.615 -the stack, it prints the new top element.
179.616 -
179.617 -\begin{ttdescription}
179.618 -\item[\ttindexbold{push_proof}();]
179.619 -duplicates the top element of the stack, pushing a copy of the current
179.620 -proof state on to the stack.
179.621 -
179.622 -\item[\ttindexbold{pop_proof}();]
179.623 -discards the top element of the stack. It returns the list of
179.624 -assumptions associated with the new proof; you should bind these to an
179.625 -\ML\ identifier. They can also be obtained by calling \ttindex{premises}.
179.626 -
179.627 -\item[\ttindexbold{rotate_proof}();]
179.628 -\index{assumptions!of main goal}
179.629 -rotates the stack, moving the top element to the bottom. It returns the
179.630 -list of assumptions associated with the new proof.
179.631 -\end{ttdescription}
179.632 -
179.633 -
179.634 -\subsection{Saving and restoring proof states}
179.635 -\index{proofs!saving and restoring}
179.636 -\begin{ttbox}
179.637 -save_proof : unit -> proof
179.638 -restore_proof : proof -> thm list
179.639 -\end{ttbox}
179.640 -States of the subgoal module may be saved as \ML\ values of
179.641 -type~\mltydx{proof}, and later restored.
179.642 -
179.643 -\begin{ttdescription}
179.644 -\item[\ttindexbold{save_proof}();]
179.645 -returns the current state, which is on top of the stack.
179.646 -
179.647 -\item[\ttindexbold{restore_proof} {\it prf};]\index{assumptions!of main goal}
179.648 - replaces the top of the stack by~{\it prf}. It returns the list of
179.649 - assumptions associated with the new proof.
179.650 -\end{ttdescription}
179.651 -
179.652 -
179.653 -\section{*Debugging and inspecting}
179.654 -\index{tactics!debugging}
179.655 -These functions can be useful when you are debugging a tactic. They refer
179.656 -to the current proof state stored in the subgoal module. A tactic
179.657 -should never call them; it should operate on the proof state supplied as its
179.658 -argument.
179.659 -
179.660 -\subsection{Reading and printing terms}
179.661 -\index{terms!reading of}\index{terms!printing of}\index{types!printing of}
179.662 -\begin{ttbox}
179.663 -read : string -> term
179.664 -prin : term -> unit
179.665 -printyp : typ -> unit
179.666 -\end{ttbox}
179.667 -These read and print terms (or types) using the syntax associated with the
179.668 -proof state.
179.669 -
179.670 -\begin{ttdescription}
179.671 -\item[\ttindexbold{read} {\it string}]
179.672 -reads the {\it string} as a term, without type-checking.
179.673 -
179.674 -\item[\ttindexbold{prin} {\it t};]
179.675 -prints the term~$t$ at the terminal.
179.676 -
179.677 -\item[\ttindexbold{printyp} {\it T};]
179.678 -prints the type~$T$ at the terminal.
179.679 -\end{ttdescription}
179.680 -
179.681 -\subsection{Inspecting the proof state}
179.682 -\index{proofs!inspecting the state}
179.683 -\begin{ttbox}
179.684 -topthm : unit -> thm
179.685 -getgoal : int -> term
179.686 -gethyps : int -> thm list
179.687 -\end{ttbox}
179.688 -
179.689 -\begin{ttdescription}
179.690 -\item[\ttindexbold{topthm}()]
179.691 -returns the proof state as an Isabelle theorem. This is what \ttindex{by}
179.692 -would supply to a tactic at this point. It omits the post-processing of
179.693 -\ttindex{result} and \ttindex{uresult}.
179.694 -
179.695 -\item[\ttindexbold{getgoal} {\it i}]
179.696 -returns subgoal~$i$ of the proof state, as a term. You may print
179.697 -this using \texttt{prin}, though you may have to examine the internal
179.698 -data structure in order to locate the problem!
179.699 -
179.700 -\item[\ttindexbold{gethyps} {\it i}]
179.701 - returns the hypotheses of subgoal~$i$ as meta-level assumptions. In
179.702 - these theorems, the subgoal's parameters become free variables. This
179.703 - command is supplied for debugging uses of \ttindex{METAHYPS}.
179.704 -\end{ttdescription}
179.705 -
179.706 -
179.707 -\subsection{Filtering lists of rules}
179.708 -\begin{ttbox}
179.709 -filter_goal: (term*term->bool) -> thm list -> int -> thm list
179.710 -\end{ttbox}
179.711 -
179.712 -\begin{ttdescription}
179.713 -\item[\ttindexbold{filter_goal} {\it could} {\it ths} {\it i}]
179.714 -applies \texttt{filter_thms {\it could}} to subgoal~$i$ of the proof
179.715 -state and returns the list of theorems that survive the filtering.
179.716 -\end{ttdescription}
179.717 -
179.718 -\index{subgoal module|)}
179.719 -\index{proofs|)}
179.720 -
179.721 -
179.722 -%%% Local Variables:
179.723 -%%% mode: latex
179.724 -%%% TeX-master: "ref"
179.725 -%%% End:
180.1 --- a/doc-src/Ref/theory-syntax.tex Wed Mar 04 11:05:02 2009 +0100
180.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
180.3 @@ -1,178 +0,0 @@
180.4 -%% $Id$
180.5 -
180.6 -\appendix
180.7 -\newlinechar=-1 %mathsing.sty sets \newlinechar=`\|, which would cause mayhem
180.8 -
180.9 -\chapter{Syntax of Isabelle Theories}\label{app:TheorySyntax}
180.10 -
180.11 -Below we present the full syntax of theory definition files as provided by
180.12 -Pure Isabelle --- object-logics may add their own sections.
180.13 -\S\ref{sec:ref-defining-theories} explains the meanings of these constructs.
180.14 -The syntax obeys the following conventions:
180.15 -\begin{itemize}
180.16 -\item {\tt Typewriter font} denotes terminal symbols.
180.17 -
180.18 -\item $id$, $tid$, $nat$, $string$ and $longident$ are the lexical
180.19 - classes of identifiers, type identifiers, natural numbers, quoted
180.20 - strings (without the need for \verb$\$\dots\verb$\$ between lines)
180.21 - and long qualified \ML{} identifiers.
180.22 - The categories $id$, $tid$, $nat$ are fully defined in \iflabelundefined{Defining-Logics}%
180.23 - {{\it The Isabelle Reference Manual}, chapter `Defining Logics'}%
180.24 - {\S\ref{Defining-Logics}}.
180.25 -
180.26 -\item $text$ is all text from the current position to the end of file,
180.27 - $verbatim$ is any text enclosed in \verb.{|.\dots\verb.|}.
180.28 -
180.29 -\item Comments in theories take the form {\tt (*}\dots{\tt*)} and may
180.30 - be nested, just as in \ML.
180.31 -\end{itemize}
180.32 -
180.33 -\begin{rail}
180.34 -
180.35 -theoryDef : id '=' (name + '+') ('+' extension | ())
180.36 - ;
180.37 -
180.38 -name : id | string
180.39 - ;
180.40 -
180.41 -extension : (section +) 'end' ( () | ml )
180.42 - ;
180.43 -
180.44 -section : classes
180.45 - | default
180.46 - | types
180.47 - | arities
180.48 - | nonterminals
180.49 - | consts
180.50 - | syntax
180.51 - | trans
180.52 - | defs
180.53 - | constdefs
180.54 - | rules
180.55 - | axclass
180.56 - | instance
180.57 - | oracle
180.58 - | locale
180.59 - | local
180.60 - | global
180.61 - | setup
180.62 - ;
180.63 -
180.64 -classes : 'classes' ( classDecl + )
180.65 - ;
180.66 -
180.67 -classDecl : (id (() | '<' (id + ',')))
180.68 - ;
180.69 -
180.70 -default : 'default' sort
180.71 - ;
180.72 -
180.73 -sort : id
180.74 - | lbrace (id * ',') rbrace
180.75 - ;
180.76 -
180.77 -types : 'types' ( ( typeDecl ( () | '(' infix ')' ) ) + )
180.78 - ;
180.79 -
180.80 -infix : ( 'infixr' | 'infixl' ) (() | string) nat
180.81 - ;
180.82 -
180.83 -typeDecl : typevarlist name
180.84 - ( () | '=' ( string | type ) );
180.85 -
180.86 -typevarlist : () | tid | '(' ( tid + ',' ) ')';
180.87 -
180.88 -type : simpleType | '(' type ')' | type '=>' type |
180.89 - '[' ( type + "," ) ']' '=>' type;
180.90 -
180.91 -simpleType: id | ( tid ( () | '::' id ) ) |
180.92 - '(' ( type + "," ) ')' id | simpleType id
180.93 - ;
180.94 -
180.95 -arities : 'arities' ((name + ',') '::' arity +)
180.96 - ;
180.97 -
180.98 -arity : ( () | '(' (sort + ',') ')' ) sort
180.99 - ;
180.100 -
180.101 -nonterminals : 'nonterminals' (name+)
180.102 - ;
180.103 -
180.104 -consts : 'consts' ( mixfixConstDecl + )
180.105 - ;
180.106 -
180.107 -syntax : 'syntax' (() | mode) ( mixfixConstDecl + );
180.108 -
180.109 -mode : '(' name (() | 'output') ')'
180.110 - ;
180.111 -
180.112 -mixfixConstDecl : constDecl (() | ( '(' mixfix ')' ))
180.113 - ;
180.114 -
180.115 -constDecl : ( name + ',') '::' (string | type);
180.116 -
180.117 -mixfix : string ( () | ( () | ('[' (nat + ',') ']')) nat )
180.118 - | infix
180.119 - | 'binder' string nat ;
180.120 -
180.121 -trans : 'translations' ( pat ( '==' | '=>' | '<=' ) pat + )
180.122 - ;
180.123 -
180.124 -pat : ( () | ( '(' id ')' ) ) string;
180.125 -
180.126 -rules : 'rules' (( id string ) + )
180.127 - ;
180.128 -
180.129 -defs : 'defs' (( id string ) + )
180.130 - ;
180.131 -
180.132 -constdefs : 'constdefs' (name '::' (string | type) (() | mixfix) string +)
180.133 - ;
180.134 -
180.135 -axclass : 'axclass' classDecl (() | ( id string ) +)
180.136 - ;
180.137 -
180.138 -instance : 'instance' ( name '<' name | name '::' arity) witness
180.139 - ;
180.140 -
180.141 -witness : (() | '(' ((string | id | longident) + ',') ')') (() | verbatim)
180.142 - ;
180.143 -
180.144 -locale : 'locale' name '=' ( () | name '+' ) localeBody
180.145 - ;
180.146 -
180.147 -localeBody : localeConsts ( () | localeAsms ) ( () | localeDefs )
180.148 - ;
180.149 -
180.150 -localeConsts: ( 'fixes' ( ( (name '::' ( string | type )) ( () | '(' mixfix ')' ) ) + ) )
180.151 - ;
180.152 -
180.153 -
180.154 -localeAsms: ( 'assumes' ( ( id string ) + ) )
180.155 - ;
180.156 -
180.157 -localeDefs: ( 'defines' ( ( id string ) +) )
180.158 - ;
180.159 -
180.160 -oracle : 'oracle' name '=' name
180.161 - ;
180.162 -
180.163 -local : 'local'
180.164 - ;
180.165 -
180.166 -global : 'global'
180.167 - ;
180.168 -
180.169 -setup : 'setup' (id | longident)
180.170 - ;
180.171 -
180.172 -ml : 'ML' text
180.173 - ;
180.174 -
180.175 -\end{rail}
180.176 -
180.177 -
180.178 -%%% Local Variables:
180.179 -%%% mode: latex
180.180 -%%% TeX-master: "ref"
180.181 -%%% End:
181.1 --- a/lib/browser/.cvsignore Wed Mar 04 11:05:02 2009 +0100
181.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
181.3 @@ -1,1 +0,0 @@
181.4 -GraphBrowser.jar
182.1 --- a/lib/browser/GraphBrowser/.cvsignore Wed Mar 04 11:05:02 2009 +0100
182.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
182.3 @@ -1,1 +0,0 @@
182.4 -*.class
183.1 --- a/lib/browser/awtUtilities/.cvsignore Wed Mar 04 11:05:02 2009 +0100
183.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
183.3 @@ -1,1 +0,0 @@
183.4 -*.class
184.1 --- a/src/FOL/ex/IffOracle.thy Wed Mar 04 11:05:02 2009 +0100
184.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
184.3 @@ -1,77 +0,0 @@
184.4 -(* Title: FOL/ex/IffOracle.thy
184.5 - ID: $Id$
184.6 - Author: Lawrence C Paulson, Cambridge University Computer Laboratory
184.7 - Copyright 1996 University of Cambridge
184.8 -*)
184.9 -
184.10 -header {* Example of Declaring an Oracle *}
184.11 -
184.12 -theory IffOracle
184.13 -imports FOL
184.14 -begin
184.15 -
184.16 -subsection {* Oracle declaration *}
184.17 -
184.18 -text {*
184.19 - This oracle makes tautologies of the form @{text "P <-> P <-> P <-> P"}.
184.20 - The length is specified by an integer, which is checked to be even
184.21 - and positive.
184.22 -*}
184.23 -
184.24 -oracle iff_oracle = {*
184.25 - let
184.26 - fun mk_iff 1 = Var (("P", 0), @{typ o})
184.27 - | mk_iff n = FOLogic.iff $ Var (("P", 0), @{typ o}) $ mk_iff (n - 1);
184.28 - in
184.29 - fn (thy, n) =>
184.30 - if n > 0 andalso n mod 2 = 0
184.31 - then Thm.cterm_of thy (FOLogic.mk_Trueprop (mk_iff n))
184.32 - else raise Fail ("iff_oracle: " ^ string_of_int n)
184.33 - end
184.34 -*}
184.35 -
184.36 -
184.37 -subsection {* Oracle as low-level rule *}
184.38 -
184.39 -ML {* iff_oracle (@{theory}, 2) *}
184.40 -ML {* iff_oracle (@{theory}, 10) *}
184.41 -ML {* Thm.proof_of (iff_oracle (@{theory}, 10)) *}
184.42 -
184.43 -text {* These oracle calls had better fail. *}
184.44 -
184.45 -ML {*
184.46 - (iff_oracle (@{theory}, 5); error "?")
184.47 - handle Fail _ => warning "Oracle failed, as expected"
184.48 -*}
184.49 -
184.50 -ML {*
184.51 - (iff_oracle (@{theory}, 1); error "?")
184.52 - handle Fail _ => warning "Oracle failed, as expected"
184.53 -*}
184.54 -
184.55 -
184.56 -subsection {* Oracle as proof method *}
184.57 -
184.58 -method_setup iff = {*
184.59 - Method.simple_args OuterParse.nat (fn n => fn ctxt =>
184.60 - Method.SIMPLE_METHOD
184.61 - (HEADGOAL (Tactic.rtac (iff_oracle (ProofContext.theory_of ctxt, n)))
184.62 - handle Fail _ => no_tac))
184.63 -*} "iff oracle"
184.64 -
184.65 -
184.66 -lemma "A <-> A"
184.67 - by (iff 2)
184.68 -
184.69 -lemma "A <-> A <-> A <-> A <-> A <-> A <-> A <-> A <-> A <-> A"
184.70 - by (iff 10)
184.71 -
184.72 -lemma "A <-> A <-> A <-> A <-> A"
184.73 - apply (iff 5)?
184.74 - oops
184.75 -
184.76 -lemma A
184.77 - apply (iff 1)?
184.78 - oops
184.79 -
184.80 -end
185.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
185.2 +++ b/src/FOL/ex/Iff_Oracle.thy Wed Mar 04 11:05:29 2009 +0100
185.3 @@ -0,0 +1,76 @@
185.4 +(* Title: FOL/ex/Iff_Oracle.thy
185.5 + Author: Lawrence C Paulson, Cambridge University Computer Laboratory
185.6 + Copyright 1996 University of Cambridge
185.7 +*)
185.8 +
185.9 +header {* Example of Declaring an Oracle *}
185.10 +
185.11 +theory Iff_Oracle
185.12 +imports FOL
185.13 +begin
185.14 +
185.15 +subsection {* Oracle declaration *}
185.16 +
185.17 +text {*
185.18 + This oracle makes tautologies of the form @{text "P <-> P <-> P <-> P"}.
185.19 + The length is specified by an integer, which is checked to be even
185.20 + and positive.
185.21 +*}
185.22 +
185.23 +oracle iff_oracle = {*
185.24 + let
185.25 + fun mk_iff 1 = Var (("P", 0), @{typ o})
185.26 + | mk_iff n = FOLogic.iff $ Var (("P", 0), @{typ o}) $ mk_iff (n - 1);
185.27 + in
185.28 + fn (thy, n) =>
185.29 + if n > 0 andalso n mod 2 = 0
185.30 + then Thm.cterm_of thy (FOLogic.mk_Trueprop (mk_iff n))
185.31 + else raise Fail ("iff_oracle: " ^ string_of_int n)
185.32 + end
185.33 +*}
185.34 +
185.35 +
185.36 +subsection {* Oracle as low-level rule *}
185.37 +
185.38 +ML {* iff_oracle (@{theory}, 2) *}
185.39 +ML {* iff_oracle (@{theory}, 10) *}
185.40 +ML {* Thm.proof_of (iff_oracle (@{theory}, 10)) *}
185.41 +
185.42 +text {* These oracle calls had better fail. *}
185.43 +
185.44 +ML {*
185.45 + (iff_oracle (@{theory}, 5); error "?")
185.46 + handle Fail _ => warning "Oracle failed, as expected"
185.47 +*}
185.48 +
185.49 +ML {*
185.50 + (iff_oracle (@{theory}, 1); error "?")
185.51 + handle Fail _ => warning "Oracle failed, as expected"
185.52 +*}
185.53 +
185.54 +
185.55 +subsection {* Oracle as proof method *}
185.56 +
185.57 +method_setup iff = {*
185.58 + Method.simple_args OuterParse.nat (fn n => fn ctxt =>
185.59 + Method.SIMPLE_METHOD
185.60 + (HEADGOAL (Tactic.rtac (iff_oracle (ProofContext.theory_of ctxt, n)))
185.61 + handle Fail _ => no_tac))
185.62 +*} "iff oracle"
185.63 +
185.64 +
185.65 +lemma "A <-> A"
185.66 + by (iff 2)
185.67 +
185.68 +lemma "A <-> A <-> A <-> A <-> A <-> A <-> A <-> A <-> A <-> A"
185.69 + by (iff 10)
185.70 +
185.71 +lemma "A <-> A <-> A <-> A <-> A"
185.72 + apply (iff 5)?
185.73 + oops
185.74 +
185.75 +lemma A
185.76 + apply (iff 1)?
185.77 + oops
185.78 +
185.79 +end
186.1 --- a/src/FOL/ex/NatClass.thy Wed Mar 04 11:05:02 2009 +0100
186.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
186.3 @@ -1,90 +0,0 @@
186.4 -(* Title: FOL/ex/NatClass.thy
186.5 - ID: $Id$
186.6 - Author: Markus Wenzel, TU Muenchen
186.7 -*)
186.8 -
186.9 -theory NatClass
186.10 -imports FOL
186.11 -begin
186.12 -
186.13 -text {*
186.14 - This is an abstract version of theory @{text "Nat"}. Instead of
186.15 - axiomatizing a single type @{text nat} we define the class of all
186.16 - these types (up to isomorphism).
186.17 -
186.18 - Note: The @{text rec} operator had to be made \emph{monomorphic},
186.19 - because class axioms may not contain more than one type variable.
186.20 -*}
186.21 -
186.22 -consts
186.23 - 0 :: 'a ("0")
186.24 - Suc :: "'a => 'a"
186.25 - rec :: "['a, 'a, ['a, 'a] => 'a] => 'a"
186.26 -
186.27 -axclass
186.28 - nat < "term"
186.29 - induct: "[| P(0); !!x. P(x) ==> P(Suc(x)) |] ==> P(n)"
186.30 - Suc_inject: "Suc(m) = Suc(n) ==> m = n"
186.31 - Suc_neq_0: "Suc(m) = 0 ==> R"
186.32 - rec_0: "rec(0, a, f) = a"
186.33 - rec_Suc: "rec(Suc(m), a, f) = f(m, rec(m, a, f))"
186.34 -
186.35 -definition
186.36 - add :: "['a::nat, 'a] => 'a" (infixl "+" 60) where
186.37 - "m + n = rec(m, n, %x y. Suc(y))"
186.38 -
186.39 -lemma Suc_n_not_n: "Suc(k) ~= (k::'a::nat)"
186.40 -apply (rule_tac n = k in induct)
186.41 -apply (rule notI)
186.42 -apply (erule Suc_neq_0)
186.43 -apply (rule notI)
186.44 -apply (erule notE)
186.45 -apply (erule Suc_inject)
186.46 -done
186.47 -
186.48 -lemma "(k+m)+n = k+(m+n)"
186.49 -apply (rule induct)
186.50 -back
186.51 -back
186.52 -back
186.53 -back
186.54 -back
186.55 -back
186.56 -oops
186.57 -
186.58 -lemma add_0 [simp]: "0+n = n"
186.59 -apply (unfold add_def)
186.60 -apply (rule rec_0)
186.61 -done
186.62 -
186.63 -lemma add_Suc [simp]: "Suc(m)+n = Suc(m+n)"
186.64 -apply (unfold add_def)
186.65 -apply (rule rec_Suc)
186.66 -done
186.67 -
186.68 -lemma add_assoc: "(k+m)+n = k+(m+n)"
186.69 -apply (rule_tac n = k in induct)
186.70 -apply simp
186.71 -apply simp
186.72 -done
186.73 -
186.74 -lemma add_0_right: "m+0 = m"
186.75 -apply (rule_tac n = m in induct)
186.76 -apply simp
186.77 -apply simp
186.78 -done
186.79 -
186.80 -lemma add_Suc_right: "m+Suc(n) = Suc(m+n)"
186.81 -apply (rule_tac n = m in induct)
186.82 -apply simp_all
186.83 -done
186.84 -
186.85 -lemma
186.86 - assumes prem: "!!n. f(Suc(n)) = Suc(f(n))"
186.87 - shows "f(i+j) = i+f(j)"
186.88 -apply (rule_tac n = i in induct)
186.89 -apply simp
186.90 -apply (simp add: prem)
186.91 -done
186.92 -
186.93 -end
187.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
187.2 +++ b/src/FOL/ex/Nat_Class.thy Wed Mar 04 11:05:29 2009 +0100
187.3 @@ -0,0 +1,88 @@
187.4 +(* Title: FOL/ex/Nat_Class.thy
187.5 + Author: Markus Wenzel, TU Muenchen
187.6 +*)
187.7 +
187.8 +theory Nat_Class
187.9 +imports FOL
187.10 +begin
187.11 +
187.12 +text {*
187.13 + This is an abstract version of theory @{text Nat}. Instead of
187.14 + axiomatizing a single type @{text nat} we define the class of all
187.15 + these types (up to isomorphism).
187.16 +
187.17 + Note: The @{text rec} operator had to be made \emph{monomorphic},
187.18 + because class axioms may not contain more than one type variable.
187.19 +*}
187.20 +
187.21 +class nat =
187.22 + fixes Zero :: 'a ("0")
187.23 + and Suc :: "'a \<Rightarrow> 'a"
187.24 + and rec :: "'a \<Rightarrow> 'a \<Rightarrow> ('a \<Rightarrow> 'a \<Rightarrow> 'a) \<Rightarrow> 'a"
187.25 + assumes induct: "P(0) \<Longrightarrow> (\<And>x. P(x) \<Longrightarrow> P(Suc(x))) \<Longrightarrow> P(n)"
187.26 + and Suc_inject: "Suc(m) = Suc(n) \<Longrightarrow> m = n"
187.27 + and Suc_neq_Zero: "Suc(m) = 0 \<Longrightarrow> R"
187.28 + and rec_Zero: "rec(0, a, f) = a"
187.29 + and rec_Suc: "rec(Suc(m), a, f) = f(m, rec(m, a, f))"
187.30 +begin
187.31 +
187.32 +definition
187.33 + add :: "'a \<Rightarrow> 'a \<Rightarrow> 'a" (infixl "+" 60) where
187.34 + "m + n = rec(m, n, \<lambda>x y. Suc(y))"
187.35 +
187.36 +lemma Suc_n_not_n: "Suc(k) \<noteq> (k::'a)"
187.37 + apply (rule_tac n = k in induct)
187.38 + apply (rule notI)
187.39 + apply (erule Suc_neq_Zero)
187.40 + apply (rule notI)
187.41 + apply (erule notE)
187.42 + apply (erule Suc_inject)
187.43 + done
187.44 +
187.45 +lemma "(k + m) + n = k + (m + n)"
187.46 + apply (rule induct)
187.47 + back
187.48 + back
187.49 + back
187.50 + back
187.51 + back
187.52 + oops
187.53 +
187.54 +lemma add_Zero [simp]: "0 + n = n"
187.55 + apply (unfold add_def)
187.56 + apply (rule rec_Zero)
187.57 + done
187.58 +
187.59 +lemma add_Suc [simp]: "Suc(m) + n = Suc(m + n)"
187.60 + apply (unfold add_def)
187.61 + apply (rule rec_Suc)
187.62 + done
187.63 +
187.64 +lemma add_assoc: "(k + m) + n = k + (m + n)"
187.65 + apply (rule_tac n = k in induct)
187.66 + apply simp
187.67 + apply simp
187.68 + done
187.69 +
187.70 +lemma add_Zero_right: "m + 0 = m"
187.71 + apply (rule_tac n = m in induct)
187.72 + apply simp
187.73 + apply simp
187.74 + done
187.75 +
187.76 +lemma add_Suc_right: "m + Suc(n) = Suc(m + n)"
187.77 + apply (rule_tac n = m in induct)
187.78 + apply simp_all
187.79 + done
187.80 +
187.81 +lemma
187.82 + assumes prem: "\<And>n. f(Suc(n)) = Suc(f(n))"
187.83 + shows "f(i + j) = i + f(j)"
187.84 + apply (rule_tac n = i in induct)
187.85 + apply simp
187.86 + apply (simp add: prem)
187.87 + done
187.88 +
187.89 +end
187.90 +
187.91 +end
188.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
188.2 +++ b/src/HOL/Archimedean_Field.thy Wed Mar 04 11:05:29 2009 +0100
188.3 @@ -0,0 +1,400 @@
188.4 +(* Title: Archimedean_Field.thy
188.5 + Author: Brian Huffman
188.6 +*)
188.7 +
188.8 +header {* Archimedean Fields, Floor and Ceiling Functions *}
188.9 +
188.10 +theory Archimedean_Field
188.11 +imports Main
188.12 +begin
188.13 +
188.14 +subsection {* Class of Archimedean fields *}
188.15 +
188.16 +text {* Archimedean fields have no infinite elements. *}
188.17 +
188.18 +class archimedean_field = ordered_field + number_ring +
188.19 + assumes ex_le_of_int: "\<exists>z. x \<le> of_int z"
188.20 +
188.21 +lemma ex_less_of_int:
188.22 + fixes x :: "'a::archimedean_field" shows "\<exists>z. x < of_int z"
188.23 +proof -
188.24 + from ex_le_of_int obtain z where "x \<le> of_int z" ..
188.25 + then have "x < of_int (z + 1)" by simp
188.26 + then show ?thesis ..
188.27 +qed
188.28 +
188.29 +lemma ex_of_int_less:
188.30 + fixes x :: "'a::archimedean_field" shows "\<exists>z. of_int z < x"
188.31 +proof -
188.32 + from ex_less_of_int obtain z where "- x < of_int z" ..
188.33 + then have "of_int (- z) < x" by simp
188.34 + then show ?thesis ..
188.35 +qed
188.36 +
188.37 +lemma ex_less_of_nat:
188.38 + fixes x :: "'a::archimedean_field" shows "\<exists>n. x < of_nat n"
188.39 +proof -
188.40 + obtain z where "x < of_int z" using ex_less_of_int ..
188.41 + also have "\<dots> \<le> of_int (int (nat z))" by simp
188.42 + also have "\<dots> = of_nat (nat z)" by (simp only: of_int_of_nat_eq)
188.43 + finally show ?thesis ..
188.44 +qed
188.45 +
188.46 +lemma ex_le_of_nat:
188.47 + fixes x :: "'a::archimedean_field" shows "\<exists>n. x \<le> of_nat n"
188.48 +proof -
188.49 + obtain n where "x < of_nat n" using ex_less_of_nat ..
188.50 + then have "x \<le> of_nat n" by simp
188.51 + then show ?thesis ..
188.52 +qed
188.53 +
188.54 +text {* Archimedean fields have no infinitesimal elements. *}
188.55 +
188.56 +lemma ex_inverse_of_nat_Suc_less:
188.57 + fixes x :: "'a::archimedean_field"
188.58 + assumes "0 < x" shows "\<exists>n. inverse (of_nat (Suc n)) < x"
188.59 +proof -
188.60 + from `0 < x` have "0 < inverse x"
188.61 + by (rule positive_imp_inverse_positive)
188.62 + obtain n where "inverse x < of_nat n"
188.63 + using ex_less_of_nat ..
188.64 + then obtain m where "inverse x < of_nat (Suc m)"
188.65 + using `0 < inverse x` by (cases n) (simp_all del: of_nat_Suc)
188.66 + then have "inverse (of_nat (Suc m)) < inverse (inverse x)"
188.67 + using `0 < inverse x` by (rule less_imp_inverse_less)
188.68 + then have "inverse (of_nat (Suc m)) < x"
188.69 + using `0 < x` by (simp add: nonzero_inverse_inverse_eq)
188.70 + then show ?thesis ..
188.71 +qed
188.72 +
188.73 +lemma ex_inverse_of_nat_less:
188.74 + fixes x :: "'a::archimedean_field"
188.75 + assumes "0 < x" shows "\<exists>n>0. inverse (of_nat n) < x"
188.76 + using ex_inverse_of_nat_Suc_less [OF `0 < x`] by auto
188.77 +
188.78 +lemma ex_less_of_nat_mult:
188.79 + fixes x :: "'a::archimedean_field"
188.80 + assumes "0 < x" shows "\<exists>n. y < of_nat n * x"
188.81 +proof -
188.82 + obtain n where "y / x < of_nat n" using ex_less_of_nat ..
188.83 + with `0 < x` have "y < of_nat n * x" by (simp add: pos_divide_less_eq)
188.84 + then show ?thesis ..
188.85 +qed
188.86 +
188.87 +
188.88 +subsection {* Existence and uniqueness of floor function *}
188.89 +
188.90 +lemma exists_least_lemma:
188.91 + assumes "\<not> P 0" and "\<exists>n. P n"
188.92 + shows "\<exists>n. \<not> P n \<and> P (Suc n)"
188.93 +proof -
188.94 + from `\<exists>n. P n` have "P (Least P)" by (rule LeastI_ex)
188.95 + with `\<not> P 0` obtain n where "Least P = Suc n"
188.96 + by (cases "Least P") auto
188.97 + then have "n < Least P" by simp
188.98 + then have "\<not> P n" by (rule not_less_Least)
188.99 + then have "\<not> P n \<and> P (Suc n)"
188.100 + using `P (Least P)` `Least P = Suc n` by simp
188.101 + then show ?thesis ..
188.102 +qed
188.103 +
188.104 +lemma floor_exists:
188.105 + fixes x :: "'a::archimedean_field"
188.106 + shows "\<exists>z. of_int z \<le> x \<and> x < of_int (z + 1)"
188.107 +proof (cases)
188.108 + assume "0 \<le> x"
188.109 + then have "\<not> x < of_nat 0" by simp
188.110 + then have "\<exists>n. \<not> x < of_nat n \<and> x < of_nat (Suc n)"
188.111 + using ex_less_of_nat by (rule exists_least_lemma)
188.112 + then obtain n where "\<not> x < of_nat n \<and> x < of_nat (Suc n)" ..
188.113 + then have "of_int (int n) \<le> x \<and> x < of_int (int n + 1)" by simp
188.114 + then show ?thesis ..
188.115 +next
188.116 + assume "\<not> 0 \<le> x"
188.117 + then have "\<not> - x \<le> of_nat 0" by simp
188.118 + then have "\<exists>n. \<not> - x \<le> of_nat n \<and> - x \<le> of_nat (Suc n)"
188.119 + using ex_le_of_nat by (rule exists_least_lemma)
188.120 + then obtain n where "\<not> - x \<le> of_nat n \<and> - x \<le> of_nat (Suc n)" ..
188.121 + then have "of_int (- int n - 1) \<le> x \<and> x < of_int (- int n - 1 + 1)" by simp
188.122 + then show ?thesis ..
188.123 +qed
188.124 +
188.125 +lemma floor_exists1:
188.126 + fixes x :: "'a::archimedean_field"
188.127 + shows "\<exists>!z. of_int z \<le> x \<and> x < of_int (z + 1)"
188.128 +proof (rule ex_ex1I)
188.129 + show "\<exists>z. of_int z \<le> x \<and> x < of_int (z + 1)"
188.130 + by (rule floor_exists)
188.131 +next
188.132 + fix y z assume
188.133 + "of_int y \<le> x \<and> x < of_int (y + 1)"
188.134 + "of_int z \<le> x \<and> x < of_int (z + 1)"
188.135 + then have
188.136 + "of_int y \<le> x" "x < of_int (y + 1)"
188.137 + "of_int z \<le> x" "x < of_int (z + 1)"
188.138 + by simp_all
188.139 + from le_less_trans [OF `of_int y \<le> x` `x < of_int (z + 1)`]
188.140 + le_less_trans [OF `of_int z \<le> x` `x < of_int (y + 1)`]
188.141 + show "y = z" by (simp del: of_int_add)
188.142 +qed
188.143 +
188.144 +
188.145 +subsection {* Floor function *}
188.146 +
188.147 +definition
188.148 + floor :: "'a::archimedean_field \<Rightarrow> int" where
188.149 + [code del]: "floor x = (THE z. of_int z \<le> x \<and> x < of_int (z + 1))"
188.150 +
188.151 +notation (xsymbols)
188.152 + floor ("\<lfloor>_\<rfloor>")
188.153 +
188.154 +notation (HTML output)
188.155 + floor ("\<lfloor>_\<rfloor>")
188.156 +
188.157 +lemma floor_correct: "of_int (floor x) \<le> x \<and> x < of_int (floor x + 1)"
188.158 + unfolding floor_def using floor_exists1 by (rule theI')
188.159 +
188.160 +lemma floor_unique: "\<lbrakk>of_int z \<le> x; x < of_int z + 1\<rbrakk> \<Longrightarrow> floor x = z"
188.161 + using floor_correct [of x] floor_exists1 [of x] by auto
188.162 +
188.163 +lemma of_int_floor_le: "of_int (floor x) \<le> x"
188.164 + using floor_correct ..
188.165 +
188.166 +lemma le_floor_iff: "z \<le> floor x \<longleftrightarrow> of_int z \<le> x"
188.167 +proof
188.168 + assume "z \<le> floor x"
188.169 + then have "(of_int z :: 'a) \<le> of_int (floor x)" by simp
188.170 + also have "of_int (floor x) \<le> x" by (rule of_int_floor_le)
188.171 + finally show "of_int z \<le> x" .
188.172 +next
188.173 + assume "of_int z \<le> x"
188.174 + also have "x < of_int (floor x + 1)" using floor_correct ..
188.175 + finally show "z \<le> floor x" by (simp del: of_int_add)
188.176 +qed
188.177 +
188.178 +lemma floor_less_iff: "floor x < z \<longleftrightarrow> x < of_int z"
188.179 + by (simp add: not_le [symmetric] le_floor_iff)
188.180 +
188.181 +lemma less_floor_iff: "z < floor x \<longleftrightarrow> of_int z + 1 \<le> x"
188.182 + using le_floor_iff [of "z + 1" x] by auto
188.183 +
188.184 +lemma floor_le_iff: "floor x \<le> z \<longleftrightarrow> x < of_int z + 1"
188.185 + by (simp add: not_less [symmetric] less_floor_iff)
188.186 +
188.187 +lemma floor_mono: assumes "x \<le> y" shows "floor x \<le> floor y"
188.188 +proof -
188.189 + have "of_int (floor x) \<le> x" by (rule of_int_floor_le)
188.190 + also note `x \<le> y`
188.191 + finally show ?thesis by (simp add: le_floor_iff)
188.192 +qed
188.193 +
188.194 +lemma floor_less_cancel: "floor x < floor y \<Longrightarrow> x < y"
188.195 + by (auto simp add: not_le [symmetric] floor_mono)
188.196 +
188.197 +lemma floor_of_int [simp]: "floor (of_int z) = z"
188.198 + by (rule floor_unique) simp_all
188.199 +
188.200 +lemma floor_of_nat [simp]: "floor (of_nat n) = int n"
188.201 + using floor_of_int [of "of_nat n"] by simp
188.202 +
188.203 +text {* Floor with numerals *}
188.204 +
188.205 +lemma floor_zero [simp]: "floor 0 = 0"
188.206 + using floor_of_int [of 0] by simp
188.207 +
188.208 +lemma floor_one [simp]: "floor 1 = 1"
188.209 + using floor_of_int [of 1] by simp
188.210 +
188.211 +lemma floor_number_of [simp]: "floor (number_of v) = number_of v"
188.212 + using floor_of_int [of "number_of v"] by simp
188.213 +
188.214 +lemma zero_le_floor [simp]: "0 \<le> floor x \<longleftrightarrow> 0 \<le> x"
188.215 + by (simp add: le_floor_iff)
188.216 +
188.217 +lemma one_le_floor [simp]: "1 \<le> floor x \<longleftrightarrow> 1 \<le> x"
188.218 + by (simp add: le_floor_iff)
188.219 +
188.220 +lemma number_of_le_floor [simp]: "number_of v \<le> floor x \<longleftrightarrow> number_of v \<le> x"
188.221 + by (simp add: le_floor_iff)
188.222 +
188.223 +lemma zero_less_floor [simp]: "0 < floor x \<longleftrightarrow> 1 \<le> x"
188.224 + by (simp add: less_floor_iff)
188.225 +
188.226 +lemma one_less_floor [simp]: "1 < floor x \<longleftrightarrow> 2 \<le> x"
188.227 + by (simp add: less_floor_iff)
188.228 +
188.229 +lemma number_of_less_floor [simp]:
188.230 + "number_of v < floor x \<longleftrightarrow> number_of v + 1 \<le> x"
188.231 + by (simp add: less_floor_iff)
188.232 +
188.233 +lemma floor_le_zero [simp]: "floor x \<le> 0 \<longleftrightarrow> x < 1"
188.234 + by (simp add: floor_le_iff)
188.235 +
188.236 +lemma floor_le_one [simp]: "floor x \<le> 1 \<longleftrightarrow> x < 2"
188.237 + by (simp add: floor_le_iff)
188.238 +
188.239 +lemma floor_le_number_of [simp]:
188.240 + "floor x \<le> number_of v \<longleftrightarrow> x < number_of v + 1"
188.241 + by (simp add: floor_le_iff)
188.242 +
188.243 +lemma floor_less_zero [simp]: "floor x < 0 \<longleftrightarrow> x < 0"
188.244 + by (simp add: floor_less_iff)
188.245 +
188.246 +lemma floor_less_one [simp]: "floor x < 1 \<longleftrightarrow> x < 1"
188.247 + by (simp add: floor_less_iff)
188.248 +
188.249 +lemma floor_less_number_of [simp]:
188.250 + "floor x < number_of v \<longleftrightarrow> x < number_of v"
188.251 + by (simp add: floor_less_iff)
188.252 +
188.253 +text {* Addition and subtraction of integers *}
188.254 +
188.255 +lemma floor_add_of_int [simp]: "floor (x + of_int z) = floor x + z"
188.256 + using floor_correct [of x] by (simp add: floor_unique)
188.257 +
188.258 +lemma floor_add_number_of [simp]:
188.259 + "floor (x + number_of v) = floor x + number_of v"
188.260 + using floor_add_of_int [of x "number_of v"] by simp
188.261 +
188.262 +lemma floor_add_one [simp]: "floor (x + 1) = floor x + 1"
188.263 + using floor_add_of_int [of x 1] by simp
188.264 +
188.265 +lemma floor_diff_of_int [simp]: "floor (x - of_int z) = floor x - z"
188.266 + using floor_add_of_int [of x "- z"] by (simp add: algebra_simps)
188.267 +
188.268 +lemma floor_diff_number_of [simp]:
188.269 + "floor (x - number_of v) = floor x - number_of v"
188.270 + using floor_diff_of_int [of x "number_of v"] by simp
188.271 +
188.272 +lemma floor_diff_one [simp]: "floor (x - 1) = floor x - 1"
188.273 + using floor_diff_of_int [of x 1] by simp
188.274 +
188.275 +
188.276 +subsection {* Ceiling function *}
188.277 +
188.278 +definition
188.279 + ceiling :: "'a::archimedean_field \<Rightarrow> int" where
188.280 + [code del]: "ceiling x = - floor (- x)"
188.281 +
188.282 +notation (xsymbols)
188.283 + ceiling ("\<lceil>_\<rceil>")
188.284 +
188.285 +notation (HTML output)
188.286 + ceiling ("\<lceil>_\<rceil>")
188.287 +
188.288 +lemma ceiling_correct: "of_int (ceiling x) - 1 < x \<and> x \<le> of_int (ceiling x)"
188.289 + unfolding ceiling_def using floor_correct [of "- x"] by simp
188.290 +
188.291 +lemma ceiling_unique: "\<lbrakk>of_int z - 1 < x; x \<le> of_int z\<rbrakk> \<Longrightarrow> ceiling x = z"
188.292 + unfolding ceiling_def using floor_unique [of "- z" "- x"] by simp
188.293 +
188.294 +lemma le_of_int_ceiling: "x \<le> of_int (ceiling x)"
188.295 + using ceiling_correct ..
188.296 +
188.297 +lemma ceiling_le_iff: "ceiling x \<le> z \<longleftrightarrow> x \<le> of_int z"
188.298 + unfolding ceiling_def using le_floor_iff [of "- z" "- x"] by auto
188.299 +
188.300 +lemma less_ceiling_iff: "z < ceiling x \<longleftrightarrow> of_int z < x"
188.301 + by (simp add: not_le [symmetric] ceiling_le_iff)
188.302 +
188.303 +lemma ceiling_less_iff: "ceiling x < z \<longleftrightarrow> x \<le> of_int z - 1"
188.304 + using ceiling_le_iff [of x "z - 1"] by simp
188.305 +
188.306 +lemma le_ceiling_iff: "z \<le> ceiling x \<longleftrightarrow> of_int z - 1 < x"
188.307 + by (simp add: not_less [symmetric] ceiling_less_iff)
188.308 +
188.309 +lemma ceiling_mono: "x \<ge> y \<Longrightarrow> ceiling x \<ge> ceiling y"
188.310 + unfolding ceiling_def by (simp add: floor_mono)
188.311 +
188.312 +lemma ceiling_less_cancel: "ceiling x < ceiling y \<Longrightarrow> x < y"
188.313 + by (auto simp add: not_le [symmetric] ceiling_mono)
188.314 +
188.315 +lemma ceiling_of_int [simp]: "ceiling (of_int z) = z"
188.316 + by (rule ceiling_unique) simp_all
188.317 +
188.318 +lemma ceiling_of_nat [simp]: "ceiling (of_nat n) = int n"
188.319 + using ceiling_of_int [of "of_nat n"] by simp
188.320 +
188.321 +text {* Ceiling with numerals *}
188.322 +
188.323 +lemma ceiling_zero [simp]: "ceiling 0 = 0"
188.324 + using ceiling_of_int [of 0] by simp
188.325 +
188.326 +lemma ceiling_one [simp]: "ceiling 1 = 1"
188.327 + using ceiling_of_int [of 1] by simp
188.328 +
188.329 +lemma ceiling_number_of [simp]: "ceiling (number_of v) = number_of v"
188.330 + using ceiling_of_int [of "number_of v"] by simp
188.331 +
188.332 +lemma ceiling_le_zero [simp]: "ceiling x \<le> 0 \<longleftrightarrow> x \<le> 0"
188.333 + by (simp add: ceiling_le_iff)
188.334 +
188.335 +lemma ceiling_le_one [simp]: "ceiling x \<le> 1 \<longleftrightarrow> x \<le> 1"
188.336 + by (simp add: ceiling_le_iff)
188.337 +
188.338 +lemma ceiling_le_number_of [simp]:
188.339 + "ceiling x \<le> number_of v \<longleftrightarrow> x \<le> number_of v"
188.340 + by (simp add: ceiling_le_iff)
188.341 +
188.342 +lemma ceiling_less_zero [simp]: "ceiling x < 0 \<longleftrightarrow> x \<le> -1"
188.343 + by (simp add: ceiling_less_iff)
188.344 +
188.345 +lemma ceiling_less_one [simp]: "ceiling x < 1 \<longleftrightarrow> x \<le> 0"
188.346 + by (simp add: ceiling_less_iff)
188.347 +
188.348 +lemma ceiling_less_number_of [simp]:
188.349 + "ceiling x < number_of v \<longleftrightarrow> x \<le> number_of v - 1"
188.350 + by (simp add: ceiling_less_iff)
188.351 +
188.352 +lemma zero_le_ceiling [simp]: "0 \<le> ceiling x \<longleftrightarrow> -1 < x"
188.353 + by (simp add: le_ceiling_iff)
188.354 +
188.355 +lemma one_le_ceiling [simp]: "1 \<le> ceiling x \<longleftrightarrow> 0 < x"
188.356 + by (simp add: le_ceiling_iff)
188.357 +
188.358 +lemma number_of_le_ceiling [simp]:
188.359 + "number_of v \<le> ceiling x\<longleftrightarrow> number_of v - 1 < x"
188.360 + by (simp add: le_ceiling_iff)
188.361 +
188.362 +lemma zero_less_ceiling [simp]: "0 < ceiling x \<longleftrightarrow> 0 < x"
188.363 + by (simp add: less_ceiling_iff)
188.364 +
188.365 +lemma one_less_ceiling [simp]: "1 < ceiling x \<longleftrightarrow> 1 < x"
188.366 + by (simp add: less_ceiling_iff)
188.367 +
188.368 +lemma number_of_less_ceiling [simp]:
188.369 + "number_of v < ceiling x \<longleftrightarrow> number_of v < x"
188.370 + by (simp add: less_ceiling_iff)
188.371 +
188.372 +text {* Addition and subtraction of integers *}
188.373 +
188.374 +lemma ceiling_add_of_int [simp]: "ceiling (x + of_int z) = ceiling x + z"
188.375 + using ceiling_correct [of x] by (simp add: ceiling_unique)
188.376 +
188.377 +lemma ceiling_add_number_of [simp]:
188.378 + "ceiling (x + number_of v) = ceiling x + number_of v"
188.379 + using ceiling_add_of_int [of x "number_of v"] by simp
188.380 +
188.381 +lemma ceiling_add_one [simp]: "ceiling (x + 1) = ceiling x + 1"
188.382 + using ceiling_add_of_int [of x 1] by simp
188.383 +
188.384 +lemma ceiling_diff_of_int [simp]: "ceiling (x - of_int z) = ceiling x - z"
188.385 + using ceiling_add_of_int [of x "- z"] by (simp add: algebra_simps)
188.386 +
188.387 +lemma ceiling_diff_number_of [simp]:
188.388 + "ceiling (x - number_of v) = ceiling x - number_of v"
188.389 + using ceiling_diff_of_int [of x "number_of v"] by simp
188.390 +
188.391 +lemma ceiling_diff_one [simp]: "ceiling (x - 1) = ceiling x - 1"
188.392 + using ceiling_diff_of_int [of x 1] by simp
188.393 +
188.394 +
188.395 +subsection {* Negation *}
188.396 +
188.397 +lemma floor_minus: "floor (- x) = - ceiling x"
188.398 + unfolding ceiling_def by simp
188.399 +
188.400 +lemma ceiling_minus: "ceiling (- x) = - floor x"
188.401 + unfolding ceiling_def by simp
188.402 +
188.403 +end
189.1 --- a/src/HOL/AxClasses/Group.thy Wed Mar 04 11:05:02 2009 +0100
189.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
189.3 @@ -1,124 +0,0 @@
189.4 -(* Title: HOL/AxClasses/Group.thy
189.5 - ID: $Id$
189.6 - Author: Markus Wenzel, TU Muenchen
189.7 -*)
189.8 -
189.9 -theory Group imports Main begin
189.10 -
189.11 -subsection {* Monoids and Groups *}
189.12 -
189.13 -consts
189.14 - times :: "'a => 'a => 'a" (infixl "[*]" 70)
189.15 - invers :: "'a => 'a"
189.16 - one :: 'a
189.17 -
189.18 -
189.19 -axclass monoid < type
189.20 - assoc: "(x [*] y) [*] z = x [*] (y [*] z)"
189.21 - left_unit: "one [*] x = x"
189.22 - right_unit: "x [*] one = x"
189.23 -
189.24 -axclass semigroup < type
189.25 - assoc: "(x [*] y) [*] z = x [*] (y [*] z)"
189.26 -
189.27 -axclass group < semigroup
189.28 - left_unit: "one [*] x = x"
189.29 - left_inverse: "invers x [*] x = one"
189.30 -
189.31 -axclass agroup < group
189.32 - commute: "x [*] y = y [*] x"
189.33 -
189.34 -
189.35 -subsection {* Abstract reasoning *}
189.36 -
189.37 -theorem group_right_inverse: "x [*] invers x = (one::'a::group)"
189.38 -proof -
189.39 - have "x [*] invers x = one [*] (x [*] invers x)"
189.40 - by (simp only: group_class.left_unit)
189.41 - also have "... = one [*] x [*] invers x"
189.42 - by (simp only: semigroup_class.assoc)
189.43 - also have "... = invers (invers x) [*] invers x [*] x [*] invers x"
189.44 - by (simp only: group_class.left_inverse)
189.45 - also have "... = invers (invers x) [*] (invers x [*] x) [*] invers x"
189.46 - by (simp only: semigroup_class.assoc)
189.47 - also have "... = invers (invers x) [*] one [*] invers x"
189.48 - by (simp only: group_class.left_inverse)
189.49 - also have "... = invers (invers x) [*] (one [*] invers x)"
189.50 - by (simp only: semigroup_class.assoc)
189.51 - also have "... = invers (invers x) [*] invers x"
189.52 - by (simp only: group_class.left_unit)
189.53 - also have "... = one"
189.54 - by (simp only: group_class.left_inverse)
189.55 - finally show ?thesis .
189.56 -qed
189.57 -
189.58 -theorem group_right_unit: "x [*] one = (x::'a::group)"
189.59 -proof -
189.60 - have "x [*] one = x [*] (invers x [*] x)"
189.61 - by (simp only: group_class.left_inverse)
189.62 - also have "... = x [*] invers x [*] x"
189.63 - by (simp only: semigroup_class.assoc)
189.64 - also have "... = one [*] x"
189.65 - by (simp only: group_right_inverse)
189.66 - also have "... = x"
189.67 - by (simp only: group_class.left_unit)
189.68 - finally show ?thesis .
189.69 -qed
189.70 -
189.71 -
189.72 -subsection {* Abstract instantiation *}
189.73 -
189.74 -instance monoid < semigroup
189.75 -proof intro_classes
189.76 - fix x y z :: "'a::monoid"
189.77 - show "x [*] y [*] z = x [*] (y [*] z)"
189.78 - by (rule monoid_class.assoc)
189.79 -qed
189.80 -
189.81 -instance group < monoid
189.82 -proof intro_classes
189.83 - fix x y z :: "'a::group"
189.84 - show "x [*] y [*] z = x [*] (y [*] z)"
189.85 - by (rule semigroup_class.assoc)
189.86 - show "one [*] x = x"
189.87 - by (rule group_class.left_unit)
189.88 - show "x [*] one = x"
189.89 - by (rule group_right_unit)
189.90 -qed
189.91 -
189.92 -
189.93 -subsection {* Concrete instantiation *}
189.94 -
189.95 -defs (overloaded)
189.96 - times_bool_def: "x [*] y == x ~= (y::bool)"
189.97 - inverse_bool_def: "invers x == x::bool"
189.98 - unit_bool_def: "one == False"
189.99 -
189.100 -instance bool :: agroup
189.101 -proof (intro_classes,
189.102 - unfold times_bool_def inverse_bool_def unit_bool_def)
189.103 - fix x y z
189.104 - show "((x ~= y) ~= z) = (x ~= (y ~= z))" by blast
189.105 - show "(False ~= x) = x" by blast
189.106 - show "(x ~= x) = False" by blast
189.107 - show "(x ~= y) = (y ~= x)" by blast
189.108 -qed
189.109 -
189.110 -
189.111 -subsection {* Lifting and Functors *}
189.112 -
189.113 -defs (overloaded)
189.114 - times_prod_def: "p [*] q == (fst p [*] fst q, snd p [*] snd q)"
189.115 -
189.116 -instance * :: (semigroup, semigroup) semigroup
189.117 -proof (intro_classes, unfold times_prod_def)
189.118 - fix p q r :: "'a::semigroup * 'b::semigroup"
189.119 - show
189.120 - "(fst (fst p [*] fst q, snd p [*] snd q) [*] fst r,
189.121 - snd (fst p [*] fst q, snd p [*] snd q) [*] snd r) =
189.122 - (fst p [*] fst (fst q [*] fst r, snd q [*] snd r),
189.123 - snd p [*] snd (fst q [*] fst r, snd q [*] snd r))"
189.124 - by (simp add: semigroup_class.assoc)
189.125 -qed
189.126 -
189.127 -end
190.1 --- a/src/HOL/AxClasses/Lattice/OrdInsts.thy Wed Mar 04 11:05:02 2009 +0100
190.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
190.3 @@ -1,43 +0,0 @@
190.4 -(* Title: OrdInsts.thy
190.5 - ID: $Id$
190.6 - Author: Markus Wenzel, TU Muenchen
190.7 -
190.8 -Some order instantiations.
190.9 -*)
190.10 -
190.11 -OrdInsts = OrdDefs +
190.12 -
190.13 -
190.14 -(* binary / general products of quasi_orders / orders *)
190.15 -
190.16 -instance
190.17 - "*" :: (quasi_order, quasi_order) quasi_order (le_prod_refl, le_prod_trans)
190.18 -
190.19 -instance
190.20 - "*" :: (partial_order, partial_order) partial_order (le_prod_antisym)
190.21 -
190.22 -
190.23 -instance
190.24 - fun :: (term, quasi_order) quasi_order (le_fun_refl, le_fun_trans)
190.25 -
190.26 -instance
190.27 - fun :: (term, partial_order) partial_order (le_fun_antisym)
190.28 -
190.29 -
190.30 -(* duals of quasi orders / partial orders / linear orders *)
190.31 -
190.32 -instance
190.33 - dual :: (quasi_order) quasi_order (le_dual_refl, le_dual_trans)
190.34 -
190.35 -instance
190.36 - dual :: (partial_order) partial_order (le_dual_antisym)
190.37 -
190.38 -
190.39 -(*FIXME: had to be moved to LatInsts.thy due to some unpleasant
190.40 - 'feature' in Pure/type.ML
190.41 -
190.42 -instance
190.43 - dual :: (linear_order) linear_order (le_dual_lin)
190.44 -*)
190.45 -
190.46 -end
191.1 --- a/src/HOL/AxClasses/Product.thy Wed Mar 04 11:05:02 2009 +0100
191.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
191.3 @@ -1,20 +0,0 @@
191.4 -(* Title: HOL/AxClasses/Product.thy
191.5 - ID: $Id$
191.6 - Author: Markus Wenzel, TU Muenchen
191.7 -*)
191.8 -
191.9 -theory Product imports Main begin
191.10 -
191.11 -axclass product < type
191.12 -
191.13 -consts
191.14 - product :: "'a::product => 'a => 'a" (infixl "[*]" 70)
191.15 -
191.16 -
191.17 -instance bool :: product
191.18 - by intro_classes
191.19 -
191.20 -defs (overloaded)
191.21 - product_bool_def: "x [*] y == x & y"
191.22 -
191.23 -end
192.1 --- a/src/HOL/AxClasses/README.html Wed Mar 04 11:05:02 2009 +0100
192.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
192.3 @@ -1,20 +0,0 @@
192.4 -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
192.5 -
192.6 -<!-- $Id$ -->
192.7 -
192.8 -<html>
192.9 -
192.10 -<head>
192.11 - <meta http-equiv="content-type" content="text/html;charset=iso-8859-1">
192.12 - <title>HOL/AxClasses</title>
192.13 -</head>
192.14 -
192.15 -<body>
192.16 -<h1>HOL/AxClasses</h1>
192.17 -
192.18 -These are the HOL examples of the tutorial <a
192.19 -href="http://isabelle.in.tum.de/dist/Isabelle/doc/axclass.pdf">Using Axiomatic Type
192.20 -Classes in Isabelle</a>. See also FOL/ex/NatClass for the natural
192.21 -number example.
192.22 -</body>
192.23 -</html>
193.1 --- a/src/HOL/AxClasses/ROOT.ML Wed Mar 04 11:05:02 2009 +0100
193.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
193.3 @@ -1,3 +0,0 @@
193.4 -(* $Id$ *)
193.5 -
193.6 -use_thys ["Semigroups", "Group", "Product"];
194.1 --- a/src/HOL/AxClasses/Semigroups.thy Wed Mar 04 11:05:02 2009 +0100
194.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
194.3 @@ -1,21 +0,0 @@
194.4 -(* Title: HOL/AxClasses/Semigroups.thy
194.5 - ID: $Id$
194.6 - Author: Markus Wenzel, TU Muenchen
194.7 -*)
194.8 -
194.9 -theory Semigroups imports Main begin
194.10 -
194.11 -consts
194.12 - times :: "'a => 'a => 'a" (infixl "[*]" 70)
194.13 -
194.14 -axclass semigroup < type
194.15 - assoc: "(x [*] y) [*] z = x [*] (y [*] z)"
194.16 -
194.17 -
194.18 -consts
194.19 - plus :: "'a => 'a => 'a" (infixl "[+]" 70)
194.20 -
194.21 -axclass plus_semigroup < type
194.22 - assoc: "(x [+] y) [+] z = x [+] (y [+] z)"
194.23 -
194.24 -end
195.1 --- a/src/HOL/Bali/Basis.thy Wed Mar 04 11:05:02 2009 +0100
195.2 +++ b/src/HOL/Bali/Basis.thy Wed Mar 04 11:05:29 2009 +0100
195.3 @@ -251,8 +251,8 @@
195.4 Oex :: "[pttrn, 'a option, bool] => bool" ("(3\<exists>_\<in>_:/ _)" [0,0,10] 10)
195.5
195.6 translations
195.7 - "! x:A: P" == "! x:o2s A. P"
195.8 - "? x:A: P" == "? x:o2s A. P"
195.9 + "! x:A: P" == "! x:CONST Option.set A. P"
195.10 + "? x:A: P" == "? x:CONST Option.set A. P"
195.11
195.12 section "Special map update"
195.13
196.1 --- a/src/HOL/Bali/Conform.thy Wed Mar 04 11:05:02 2009 +0100
196.2 +++ b/src/HOL/Bali/Conform.thy Wed Mar 04 11:05:29 2009 +0100
196.3 @@ -102,7 +102,7 @@
196.4 constdefs
196.5
196.6 conf :: "prog \<Rightarrow> st \<Rightarrow> val \<Rightarrow> ty \<Rightarrow> bool" ("_,_\<turnstile>_\<Colon>\<preceq>_" [71,71,71,71] 70)
196.7 - "G,s\<turnstile>v\<Colon>\<preceq>T \<equiv> \<exists>T'\<in>typeof (\<lambda>a. option_map obj_ty (heap s a)) v:G\<turnstile>T'\<preceq>T"
196.8 + "G,s\<turnstile>v\<Colon>\<preceq>T \<equiv> \<exists>T'\<in>typeof (\<lambda>a. Option.map obj_ty (heap s a)) v:G\<turnstile>T'\<preceq>T"
196.9
196.10 lemma conf_cong [simp]: "G,set_locals l s\<turnstile>v\<Colon>\<preceq>T = G,s\<turnstile>v\<Colon>\<preceq>T"
196.11 by (auto simp: conf_def)
197.1 --- a/src/HOL/Bali/Decl.thy Wed Mar 04 11:05:02 2009 +0100
197.2 +++ b/src/HOL/Bali/Decl.thy Wed Mar 04 11:05:29 2009 +0100
197.3 @@ -801,7 +801,7 @@
197.4 "imethds G I
197.5 \<equiv> iface_rec (G,I)
197.6 (\<lambda>I i ts. (Un_tables ts) \<oplus>\<oplus>
197.7 - (o2s \<circ> table_of (map (\<lambda>(s,m). (s,I,m)) (imethods i))))"
197.8 + (Option.set \<circ> table_of (map (\<lambda>(s,m). (s,I,m)) (imethods i))))"
197.9
197.10
197.11
198.1 --- a/src/HOL/Bali/DeclConcepts.thy Wed Mar 04 11:05:02 2009 +0100
198.2 +++ b/src/HOL/Bali/DeclConcepts.thy Wed Mar 04 11:05:29 2009 +0100
198.3 @@ -1385,7 +1385,7 @@
198.4 "imethds G I
198.5 \<equiv> iface_rec (G,I)
198.6 (\<lambda>I i ts. (Un_tables ts) \<oplus>\<oplus>
198.7 - (o2s \<circ> table_of (map (\<lambda>(s,m). (s,I,m)) (imethods i))))"
198.8 + (Option.set \<circ> table_of (map (\<lambda>(s,m). (s,I,m)) (imethods i))))"
198.9 text {* methods of an interface, with overriding and inheritance, cf. 9.2 *}
198.10
198.11 constdefs
198.12 @@ -1528,7 +1528,7 @@
198.13
198.14 lemma imethds_rec: "\<lbrakk>iface G I = Some i; ws_prog G\<rbrakk> \<Longrightarrow>
198.15 imethds G I = Un_tables ((\<lambda>J. imethds G J)`set (isuperIfs i)) \<oplus>\<oplus>
198.16 - (o2s \<circ> table_of (map (\<lambda>(s,mh). (s,I,mh)) (imethods i)))"
198.17 + (Option.set \<circ> table_of (map (\<lambda>(s,mh). (s,I,mh)) (imethods i)))"
198.18 apply (unfold imethds_def)
198.19 apply (rule iface_rec [THEN trans])
198.20 apply auto
199.1 --- a/src/HOL/Bali/Example.thy Wed Mar 04 11:05:02 2009 +0100
199.2 +++ b/src/HOL/Bali/Example.thy Wed Mar 04 11:05:29 2009 +0100
199.3 @@ -458,7 +458,7 @@
199.4 lemmas methd_rec' = methd_rec [OF _ ws_tprg]
199.5
199.6 lemma imethds_HasFoo [simp]:
199.7 - "imethds tprg HasFoo = o2s \<circ> empty(foo_sig\<mapsto>(HasFoo, foo_mhead))"
199.8 + "imethds tprg HasFoo = Option.set \<circ> empty(foo_sig\<mapsto>(HasFoo, foo_mhead))"
199.9 apply (rule trans)
199.10 apply (rule imethds_rec')
199.11 apply (auto simp add: HasFooInt_def)
200.1 --- a/src/HOL/Bali/State.thy Wed Mar 04 11:05:02 2009 +0100
200.2 +++ b/src/HOL/Bali/State.thy Wed Mar 04 11:05:29 2009 +0100
200.3 @@ -146,7 +146,7 @@
200.4 fields_table::
200.5 "prog \<Rightarrow> qtname \<Rightarrow> (fspec \<Rightarrow> field \<Rightarrow> bool) \<Rightarrow> (fspec, ty) table"
200.6 "fields_table G C P
200.7 - \<equiv> option_map type \<circ> table_of (filter (split P) (DeclConcepts.fields G C))"
200.8 + \<equiv> Option.map type \<circ> table_of (filter (split P) (DeclConcepts.fields G C))"
200.9
200.10 lemma fields_table_SomeI:
200.11 "\<lbrakk>table_of (DeclConcepts.fields G C) n = Some f; P n f\<rbrakk>
200.12 @@ -258,8 +258,8 @@
200.13 lookup_obj :: "st \<Rightarrow> val \<Rightarrow> obj"
200.14
200.15 translations
200.16 - "val_this s" == "the (locals s This)"
200.17 - "lookup_obj s a'" == "the (heap s (the_Addr a'))"
200.18 + "val_this s" == "CONST the (locals s This)"
200.19 + "lookup_obj s a'" == "CONST the (heap s (the_Addr a'))"
200.20
200.21 subsection "memory allocation"
200.22
200.23 @@ -290,7 +290,7 @@
200.24 init_vals :: "('a, ty) table \<Rightarrow> ('a, val) table"
200.25
200.26 translations
200.27 - "init_vals vs" == "CONST option_map default_val \<circ> vs"
200.28 + "init_vals vs" == "CONST Option.map default_val \<circ> vs"
200.29
200.30 lemma init_arr_comps_base [simp]: "init_vals (arr_comps T 0) = empty"
200.31 apply (unfold arr_comps_def in_bounds_def)
200.32 @@ -315,12 +315,12 @@
200.33 lupd :: "lname \<Rightarrow> val \<Rightarrow> st \<Rightarrow> st" ("lupd'(_\<mapsto>_')"[10,10]1000)
200.34 "lupd vn v \<equiv> st_case (\<lambda>g l. st g (l(vn\<mapsto>v)))"
200.35
200.36 - upd_gobj :: "oref \<Rightarrow> vn \<Rightarrow> val \<Rightarrow> st \<Rightarrow> st"
200.37 + upd_gobj :: "oref \<Rightarrow> vn \<Rightarrow> val \<Rightarrow> st \<Rightarrow> st"
200.38 "upd_gobj r n v \<equiv> st_case (\<lambda>g l. st (chg_map (upd_obj n v) r g) l)"
200.39
200.40 set_locals :: "locals \<Rightarrow> st \<Rightarrow> st"
200.41 "set_locals l \<equiv> st_case (\<lambda>g l'. st g l)"
200.42 -
200.43 +
200.44 init_obj :: "prog \<Rightarrow> obj_tag \<Rightarrow> oref \<Rightarrow> st \<Rightarrow> st"
200.45 "init_obj G oi r \<equiv> gupd(r\<mapsto>\<lparr>tag=oi, values=init_vals (var_tys G oi r)\<rparr>)"
200.46
201.1 --- a/src/HOL/Bali/Table.thy Wed Mar 04 11:05:02 2009 +0100
201.2 +++ b/src/HOL/Bali/Table.thy Wed Mar 04 11:05:29 2009 +0100
201.3 @@ -194,7 +194,7 @@
201.4 done
201.5
201.6 lemma Ball_set_tableD:
201.7 - "\<lbrakk>(\<forall> (x,y)\<in> set l. P x y); x \<in> o2s (table_of l xa)\<rbrakk> \<Longrightarrow> P xa x"
201.8 + "\<lbrakk>(\<forall> (x,y)\<in> set l. P x y); x \<in> Option.set (table_of l xa)\<rbrakk> \<Longrightarrow> P xa x"
201.9 apply (frule Ball_set_table)
201.10 by auto
201.11
202.1 --- a/src/HOL/Bali/WellForm.thy Wed Mar 04 11:05:02 2009 +0100
202.2 +++ b/src/HOL/Bali/WellForm.thy Wed Mar 04 11:05:29 2009 +0100
202.3 @@ -236,7 +236,7 @@
202.4 under (\<lambda> new old. accmodi old \<noteq> Private)
202.5 entails (\<lambda>new old. G\<turnstile>resTy new\<preceq>resTy old \<and>
202.6 is_static new = is_static old)) \<and>
202.7 - (o2s \<circ> table_of (imethods i)
202.8 + (Option.set \<circ> table_of (imethods i)
202.9 hidings Un_tables((\<lambda>J.(imethds G J))`set (isuperIfs i))
202.10 entails (\<lambda>new old. G\<turnstile>resTy new\<preceq>resTy old))"
202.11
202.12 @@ -248,7 +248,7 @@
202.13
202.14 lemma wf_idecl_hidings:
202.15 "wf_idecl G (I, i) \<Longrightarrow>
202.16 - (\<lambda>s. o2s (table_of (imethods i) s))
202.17 + (\<lambda>s. Option.set (table_of (imethods i) s))
202.18 hidings Un_tables ((\<lambda>J. imethds G J) ` set (isuperIfs i))
202.19 entails \<lambda>new old. G\<turnstile>resTy new\<preceq>resTy old"
202.20 apply (unfold wf_idecl_def o_def)
202.21 @@ -751,7 +751,7 @@
202.22 show "\<not>is_static im \<and> accmodi im = Public"
202.23 proof -
202.24 let ?inherited = "Un_tables (imethds G ` set (isuperIfs i))"
202.25 - let ?new = "(o2s \<circ> table_of (map (\<lambda>(s, mh). (s, I, mh)) (imethods i)))"
202.26 + let ?new = "(Option.set \<circ> table_of (map (\<lambda>(s, mh). (s, I, mh)) (imethods i)))"
202.27 from if_I wf im have imethds:"im \<in> (?inherited \<oplus>\<oplus> ?new) sig"
202.28 by (simp add: imethds_rec)
202.29 from wf if_I have
202.30 @@ -1783,7 +1783,7 @@
202.31 by (blast dest: subint1D)
202.32
202.33 let ?newMethods
202.34 - = "(o2s \<circ> table_of (map (\<lambda>(sig, mh). (sig, I, mh)) (imethods i)))"
202.35 + = "(Option.set \<circ> table_of (map (\<lambda>(sig, mh). (sig, I, mh)) (imethods i)))"
202.36 show "?Concl I"
202.37 proof (cases "?newMethods sig = {}")
202.38 case True
202.39 @@ -1864,7 +1864,7 @@
202.40 apply (drule (1) wf_prog_idecl)
202.41 apply (frule (3) imethds_wf_mhead [OF _ _ wf_idecl_supD [THEN conjunct1
202.42 [THEN is_acc_ifaceD [THEN conjunct1]]]])
202.43 -apply (case_tac "(o2s \<circ> table_of (map (\<lambda>(s, mh). (s, y, mh)) (imethods i)))
202.44 +apply (case_tac "(Option.set \<circ> table_of (map (\<lambda>(s, mh). (s, y, mh)) (imethods i)))
202.45 sig ={}")
202.46 apply force
202.47
203.1 --- a/src/HOL/Bali/WellType.thy Wed Mar 04 11:05:02 2009 +0100
203.2 +++ b/src/HOL/Bali/WellType.thy Wed Mar 04 11:05:29 2009 +0100
203.3 @@ -87,11 +87,11 @@
203.4 defs
203.5 cmheads_def:
203.6 "cmheads G S C
203.7 - \<equiv> \<lambda>sig. (\<lambda>(Cls,mthd). (ClassT Cls,(mhead mthd))) ` o2s (accmethd G S C sig)"
203.8 + \<equiv> \<lambda>sig. (\<lambda>(Cls,mthd). (ClassT Cls,(mhead mthd))) ` Option.set (accmethd G S C sig)"
203.9 Objectmheads_def:
203.10 "Objectmheads G S
203.11 \<equiv> \<lambda>sig. (\<lambda>(Cls,mthd). (ClassT Cls,(mhead mthd)))
203.12 - ` o2s (filter_tab (\<lambda>sig m. accmodi m \<noteq> Private) (accmethd G S Object) sig)"
203.13 + ` Option.set (filter_tab (\<lambda>sig m. accmodi m \<noteq> Private) (accmethd G S Object) sig)"
203.14 accObjectmheads_def:
203.15 "accObjectmheads G S T
203.16 \<equiv> if G\<turnstile>RefT T accessible_in (pid S)
204.1 --- a/src/HOL/Datatype.thy Wed Mar 04 11:05:02 2009 +0100
204.2 +++ b/src/HOL/Datatype.thy Wed Mar 04 11:05:29 2009 +0100
204.3 @@ -576,122 +576,4 @@
204.4
204.5 hide (open) const Suml Sumr Projl Projr
204.6
204.7 -
204.8 -subsection {* The option datatype *}
204.9 -
204.10 -datatype 'a option = None | Some 'a
204.11 -
204.12 -lemma not_None_eq [iff]: "(x ~= None) = (EX y. x = Some y)"
204.13 - by (induct x) auto
204.14 -
204.15 -lemma not_Some_eq [iff]: "(ALL y. x ~= Some y) = (x = None)"
204.16 - by (induct x) auto
204.17 -
204.18 -text{*Although it may appear that both of these equalities are helpful
204.19 -only when applied to assumptions, in practice it seems better to give
204.20 -them the uniform iff attribute. *}
204.21 -
204.22 -lemma option_caseE:
204.23 - assumes c: "(case x of None => P | Some y => Q y)"
204.24 - obtains
204.25 - (None) "x = None" and P
204.26 - | (Some) y where "x = Some y" and "Q y"
204.27 - using c by (cases x) simp_all
204.28 -
204.29 -lemma insert_None_conv_UNIV: "insert None (range Some) = UNIV"
204.30 - by (rule set_ext, case_tac x) auto
204.31 -
204.32 -lemma inj_Some [simp]: "inj_on Some A"
204.33 - by (rule inj_onI) simp
204.34 -
204.35 -
204.36 -subsubsection {* Operations *}
204.37 -
204.38 -consts
204.39 - the :: "'a option => 'a"
204.40 -primrec
204.41 - "the (Some x) = x"
204.42 -
204.43 -consts
204.44 - o2s :: "'a option => 'a set"
204.45 -primrec
204.46 - "o2s None = {}"
204.47 - "o2s (Some x) = {x}"
204.48 -
204.49 -lemma ospec [dest]: "(ALL x:o2s A. P x) ==> A = Some x ==> P x"
204.50 - by simp
204.51 -
204.52 -declaration {* fn _ =>
204.53 - Classical.map_cs (fn cs => cs addSD2 ("ospec", thm "ospec"))
204.54 -*}
204.55 -
204.56 -lemma elem_o2s [iff]: "(x : o2s xo) = (xo = Some x)"
204.57 - by (cases xo) auto
204.58 -
204.59 -lemma o2s_empty_eq [simp]: "(o2s xo = {}) = (xo = None)"
204.60 - by (cases xo) auto
204.61 -
204.62 -definition
204.63 - option_map :: "('a \<Rightarrow> 'b) \<Rightarrow> 'a option \<Rightarrow> 'b option"
204.64 -where
204.65 - [code del]: "option_map = (%f y. case y of None => None | Some x => Some (f x))"
204.66 -
204.67 -lemma option_map_None [simp, code]: "option_map f None = None"
204.68 - by (simp add: option_map_def)
204.69 -
204.70 -lemma option_map_Some [simp, code]: "option_map f (Some x) = Some (f x)"
204.71 - by (simp add: option_map_def)
204.72 -
204.73 -lemma option_map_is_None [iff]:
204.74 - "(option_map f opt = None) = (opt = None)"
204.75 - by (simp add: option_map_def split add: option.split)
204.76 -
204.77 -lemma option_map_eq_Some [iff]:
204.78 - "(option_map f xo = Some y) = (EX z. xo = Some z & f z = y)"
204.79 - by (simp add: option_map_def split add: option.split)
204.80 -
204.81 -lemma option_map_comp:
204.82 - "option_map f (option_map g opt) = option_map (f o g) opt"
204.83 - by (simp add: option_map_def split add: option.split)
204.84 -
204.85 -lemma option_map_o_sum_case [simp]:
204.86 - "option_map f o sum_case g h = sum_case (option_map f o g) (option_map f o h)"
204.87 - by (rule ext) (simp split: sum.split)
204.88 -
204.89 -
204.90 -subsubsection {* Code generator setup *}
204.91 -
204.92 -definition
204.93 - is_none :: "'a option \<Rightarrow> bool" where
204.94 - is_none_none [code post, symmetric, code inline]: "is_none x \<longleftrightarrow> x = None"
204.95 -
204.96 -lemma is_none_code [code]:
204.97 - shows "is_none None \<longleftrightarrow> True"
204.98 - and "is_none (Some x) \<longleftrightarrow> False"
204.99 - unfolding is_none_none [symmetric] by simp_all
204.100 -
204.101 -hide (open) const is_none
204.102 -
204.103 -code_type option
204.104 - (SML "_ option")
204.105 - (OCaml "_ option")
204.106 - (Haskell "Maybe _")
204.107 -
204.108 -code_const None and Some
204.109 - (SML "NONE" and "SOME")
204.110 - (OCaml "None" and "Some _")
204.111 - (Haskell "Nothing" and "Just")
204.112 -
204.113 -code_instance option :: eq
204.114 - (Haskell -)
204.115 -
204.116 -code_const "eq_class.eq \<Colon> 'a\<Colon>eq option \<Rightarrow> 'a option \<Rightarrow> bool"
204.117 - (Haskell infixl 4 "==")
204.118 -
204.119 -code_reserved SML
204.120 - option NONE SOME
204.121 -
204.122 -code_reserved OCaml
204.123 - option None Some
204.124 -
204.125 end
205.1 --- a/src/HOL/Extraction.thy Wed Mar 04 11:05:02 2009 +0100
205.2 +++ b/src/HOL/Extraction.thy Wed Mar 04 11:05:29 2009 +0100
205.3 @@ -6,7 +6,7 @@
205.4 header {* Program extraction for HOL *}
205.5
205.6 theory Extraction
205.7 -imports Datatype
205.8 +imports Option
205.9 uses "Tools/rewrite_hol_proof.ML"
205.10 begin
205.11
206.1 --- a/src/HOL/FrechetDeriv.thy Wed Mar 04 11:05:02 2009 +0100
206.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
206.3 @@ -1,503 +0,0 @@
206.4 -(* Title : FrechetDeriv.thy
206.5 - ID : $Id$
206.6 - Author : Brian Huffman
206.7 -*)
206.8 -
206.9 -header {* Frechet Derivative *}
206.10 -
206.11 -theory FrechetDeriv
206.12 -imports Lim
206.13 -begin
206.14 -
206.15 -definition
206.16 - fderiv ::
206.17 - "['a::real_normed_vector \<Rightarrow> 'b::real_normed_vector, 'a, 'a \<Rightarrow> 'b] \<Rightarrow> bool"
206.18 - -- {* Frechet derivative: D is derivative of function f at x *}
206.19 - ("(FDERIV (_)/ (_)/ :> (_))" [1000, 1000, 60] 60) where
206.20 - "FDERIV f x :> D = (bounded_linear D \<and>
206.21 - (\<lambda>h. norm (f (x + h) - f x - D h) / norm h) -- 0 --> 0)"
206.22 -
206.23 -lemma FDERIV_I:
206.24 - "\<lbrakk>bounded_linear D; (\<lambda>h. norm (f (x + h) - f x - D h) / norm h) -- 0 --> 0\<rbrakk>
206.25 - \<Longrightarrow> FDERIV f x :> D"
206.26 -by (simp add: fderiv_def)
206.27 -
206.28 -lemma FDERIV_D:
206.29 - "FDERIV f x :> D \<Longrightarrow> (\<lambda>h. norm (f (x + h) - f x - D h) / norm h) -- 0 --> 0"
206.30 -by (simp add: fderiv_def)
206.31 -
206.32 -lemma FDERIV_bounded_linear: "FDERIV f x :> D \<Longrightarrow> bounded_linear D"
206.33 -by (simp add: fderiv_def)
206.34 -
206.35 -lemma bounded_linear_zero:
206.36 - "bounded_linear (\<lambda>x::'a::real_normed_vector. 0::'b::real_normed_vector)"
206.37 -proof
206.38 - show "(0::'b) = 0 + 0" by simp
206.39 - fix r show "(0::'b) = scaleR r 0" by simp
206.40 - have "\<forall>x::'a. norm (0::'b) \<le> norm x * 0" by simp
206.41 - thus "\<exists>K. \<forall>x::'a. norm (0::'b) \<le> norm x * K" ..
206.42 -qed
206.43 -
206.44 -lemma FDERIV_const: "FDERIV (\<lambda>x. k) x :> (\<lambda>h. 0)"
206.45 -by (simp add: fderiv_def bounded_linear_zero)
206.46 -
206.47 -lemma bounded_linear_ident:
206.48 - "bounded_linear (\<lambda>x::'a::real_normed_vector. x)"
206.49 -proof
206.50 - fix x y :: 'a show "x + y = x + y" by simp
206.51 - fix r and x :: 'a show "scaleR r x = scaleR r x" by simp
206.52 - have "\<forall>x::'a. norm x \<le> norm x * 1" by simp
206.53 - thus "\<exists>K. \<forall>x::'a. norm x \<le> norm x * K" ..
206.54 -qed
206.55 -
206.56 -lemma FDERIV_ident: "FDERIV (\<lambda>x. x) x :> (\<lambda>h. h)"
206.57 -by (simp add: fderiv_def bounded_linear_ident)
206.58 -
206.59 -subsection {* Addition *}
206.60 -
206.61 -lemma add_diff_add:
206.62 - fixes a b c d :: "'a::ab_group_add"
206.63 - shows "(a + c) - (b + d) = (a - b) + (c - d)"
206.64 -by simp
206.65 -
206.66 -lemma bounded_linear_add:
206.67 - assumes "bounded_linear f"
206.68 - assumes "bounded_linear g"
206.69 - shows "bounded_linear (\<lambda>x. f x + g x)"
206.70 -proof -
206.71 - interpret f: bounded_linear f by fact
206.72 - interpret g: bounded_linear g by fact
206.73 - show ?thesis apply (unfold_locales)
206.74 - apply (simp only: f.add g.add add_ac)
206.75 - apply (simp only: f.scaleR g.scaleR scaleR_right_distrib)
206.76 - apply (rule f.pos_bounded [THEN exE], rename_tac Kf)
206.77 - apply (rule g.pos_bounded [THEN exE], rename_tac Kg)
206.78 - apply (rule_tac x="Kf + Kg" in exI, safe)
206.79 - apply (subst right_distrib)
206.80 - apply (rule order_trans [OF norm_triangle_ineq])
206.81 - apply (rule add_mono, erule spec, erule spec)
206.82 - done
206.83 -qed
206.84 -
206.85 -lemma norm_ratio_ineq:
206.86 - fixes x y :: "'a::real_normed_vector"
206.87 - fixes h :: "'b::real_normed_vector"
206.88 - shows "norm (x + y) / norm h \<le> norm x / norm h + norm y / norm h"
206.89 -apply (rule ord_le_eq_trans)
206.90 -apply (rule divide_right_mono)
206.91 -apply (rule norm_triangle_ineq)
206.92 -apply (rule norm_ge_zero)
206.93 -apply (rule add_divide_distrib)
206.94 -done
206.95 -
206.96 -lemma FDERIV_add:
206.97 - assumes f: "FDERIV f x :> F"
206.98 - assumes g: "FDERIV g x :> G"
206.99 - shows "FDERIV (\<lambda>x. f x + g x) x :> (\<lambda>h. F h + G h)"
206.100 -proof (rule FDERIV_I)
206.101 - show "bounded_linear (\<lambda>h. F h + G h)"
206.102 - apply (rule bounded_linear_add)
206.103 - apply (rule FDERIV_bounded_linear [OF f])
206.104 - apply (rule FDERIV_bounded_linear [OF g])
206.105 - done
206.106 -next
206.107 - have f': "(\<lambda>h. norm (f (x + h) - f x - F h) / norm h) -- 0 --> 0"
206.108 - using f by (rule FDERIV_D)
206.109 - have g': "(\<lambda>h. norm (g (x + h) - g x - G h) / norm h) -- 0 --> 0"
206.110 - using g by (rule FDERIV_D)
206.111 - from f' g'
206.112 - have "(\<lambda>h. norm (f (x + h) - f x - F h) / norm h
206.113 - + norm (g (x + h) - g x - G h) / norm h) -- 0 --> 0"
206.114 - by (rule LIM_add_zero)
206.115 - thus "(\<lambda>h. norm (f (x + h) + g (x + h) - (f x + g x) - (F h + G h))
206.116 - / norm h) -- 0 --> 0"
206.117 - apply (rule real_LIM_sandwich_zero)
206.118 - apply (simp add: divide_nonneg_pos)
206.119 - apply (simp only: add_diff_add)
206.120 - apply (rule norm_ratio_ineq)
206.121 - done
206.122 -qed
206.123 -
206.124 -subsection {* Subtraction *}
206.125 -
206.126 -lemma bounded_linear_minus:
206.127 - assumes "bounded_linear f"
206.128 - shows "bounded_linear (\<lambda>x. - f x)"
206.129 -proof -
206.130 - interpret f: bounded_linear f by fact
206.131 - show ?thesis apply (unfold_locales)
206.132 - apply (simp add: f.add)
206.133 - apply (simp add: f.scaleR)
206.134 - apply (simp add: f.bounded)
206.135 - done
206.136 -qed
206.137 -
206.138 -lemma FDERIV_minus:
206.139 - "FDERIV f x :> F \<Longrightarrow> FDERIV (\<lambda>x. - f x) x :> (\<lambda>h. - F h)"
206.140 -apply (rule FDERIV_I)
206.141 -apply (rule bounded_linear_minus)
206.142 -apply (erule FDERIV_bounded_linear)
206.143 -apply (simp only: fderiv_def minus_diff_minus norm_minus_cancel)
206.144 -done
206.145 -
206.146 -lemma FDERIV_diff:
206.147 - "\<lbrakk>FDERIV f x :> F; FDERIV g x :> G\<rbrakk>
206.148 - \<Longrightarrow> FDERIV (\<lambda>x. f x - g x) x :> (\<lambda>h. F h - G h)"
206.149 -by (simp only: diff_minus FDERIV_add FDERIV_minus)
206.150 -
206.151 -subsection {* Continuity *}
206.152 -
206.153 -lemma FDERIV_isCont:
206.154 - assumes f: "FDERIV f x :> F"
206.155 - shows "isCont f x"
206.156 -proof -
206.157 - from f interpret F: bounded_linear "F" by (rule FDERIV_bounded_linear)
206.158 - have "(\<lambda>h. norm (f (x + h) - f x - F h) / norm h) -- 0 --> 0"
206.159 - by (rule FDERIV_D [OF f])
206.160 - hence "(\<lambda>h. norm (f (x + h) - f x - F h) / norm h * norm h) -- 0 --> 0"
206.161 - by (intro LIM_mult_zero LIM_norm_zero LIM_ident)
206.162 - hence "(\<lambda>h. norm (f (x + h) - f x - F h)) -- 0 --> 0"
206.163 - by (simp cong: LIM_cong)
206.164 - hence "(\<lambda>h. f (x + h) - f x - F h) -- 0 --> 0"
206.165 - by (rule LIM_norm_zero_cancel)
206.166 - hence "(\<lambda>h. f (x + h) - f x - F h + F h) -- 0 --> 0"
206.167 - by (intro LIM_add_zero F.LIM_zero LIM_ident)
206.168 - hence "(\<lambda>h. f (x + h) - f x) -- 0 --> 0"
206.169 - by simp
206.170 - thus "isCont f x"
206.171 - unfolding isCont_iff by (rule LIM_zero_cancel)
206.172 -qed
206.173 -
206.174 -subsection {* Composition *}
206.175 -
206.176 -lemma real_divide_cancel_lemma:
206.177 - fixes a b c :: real
206.178 - shows "(b = 0 \<Longrightarrow> a = 0) \<Longrightarrow> (a / b) * (b / c) = a / c"
206.179 -by simp
206.180 -
206.181 -lemma bounded_linear_compose:
206.182 - assumes "bounded_linear f"
206.183 - assumes "bounded_linear g"
206.184 - shows "bounded_linear (\<lambda>x. f (g x))"
206.185 -proof -
206.186 - interpret f: bounded_linear f by fact
206.187 - interpret g: bounded_linear g by fact
206.188 - show ?thesis proof (unfold_locales)
206.189 - fix x y show "f (g (x + y)) = f (g x) + f (g y)"
206.190 - by (simp only: f.add g.add)
206.191 - next
206.192 - fix r x show "f (g (scaleR r x)) = scaleR r (f (g x))"
206.193 - by (simp only: f.scaleR g.scaleR)
206.194 - next
206.195 - from f.pos_bounded
206.196 - obtain Kf where f: "\<And>x. norm (f x) \<le> norm x * Kf" and Kf: "0 < Kf" by fast
206.197 - from g.pos_bounded
206.198 - obtain Kg where g: "\<And>x. norm (g x) \<le> norm x * Kg" by fast
206.199 - show "\<exists>K. \<forall>x. norm (f (g x)) \<le> norm x * K"
206.200 - proof (intro exI allI)
206.201 - fix x
206.202 - have "norm (f (g x)) \<le> norm (g x) * Kf"
206.203 - using f .
206.204 - also have "\<dots> \<le> (norm x * Kg) * Kf"
206.205 - using g Kf [THEN order_less_imp_le] by (rule mult_right_mono)
206.206 - also have "(norm x * Kg) * Kf = norm x * (Kg * Kf)"
206.207 - by (rule mult_assoc)
206.208 - finally show "norm (f (g x)) \<le> norm x * (Kg * Kf)" .
206.209 - qed
206.210 - qed
206.211 -qed
206.212 -
206.213 -lemma FDERIV_compose:
206.214 - fixes f :: "'a::real_normed_vector \<Rightarrow> 'b::real_normed_vector"
206.215 - fixes g :: "'b::real_normed_vector \<Rightarrow> 'c::real_normed_vector"
206.216 - assumes f: "FDERIV f x :> F"
206.217 - assumes g: "FDERIV g (f x) :> G"
206.218 - shows "FDERIV (\<lambda>x. g (f x)) x :> (\<lambda>h. G (F h))"
206.219 -proof (rule FDERIV_I)
206.220 - from FDERIV_bounded_linear [OF g] FDERIV_bounded_linear [OF f]
206.221 - show "bounded_linear (\<lambda>h. G (F h))"
206.222 - by (rule bounded_linear_compose)
206.223 -next
206.224 - let ?Rf = "\<lambda>h. f (x + h) - f x - F h"
206.225 - let ?Rg = "\<lambda>k. g (f x + k) - g (f x) - G k"
206.226 - let ?k = "\<lambda>h. f (x + h) - f x"
206.227 - let ?Nf = "\<lambda>h. norm (?Rf h) / norm h"
206.228 - let ?Ng = "\<lambda>h. norm (?Rg (?k h)) / norm (?k h)"
206.229 - from f interpret F!: bounded_linear "F" by (rule FDERIV_bounded_linear)
206.230 - from g interpret G!: bounded_linear "G" by (rule FDERIV_bounded_linear)
206.231 - from F.bounded obtain kF where kF: "\<And>x. norm (F x) \<le> norm x * kF" by fast
206.232 - from G.bounded obtain kG where kG: "\<And>x. norm (G x) \<le> norm x * kG" by fast
206.233 -
206.234 - let ?fun2 = "\<lambda>h. ?Nf h * kG + ?Ng h * (?Nf h + kF)"
206.235 -
206.236 - show "(\<lambda>h. norm (g (f (x + h)) - g (f x) - G (F h)) / norm h) -- 0 --> 0"
206.237 - proof (rule real_LIM_sandwich_zero)
206.238 - have Nf: "?Nf -- 0 --> 0"
206.239 - using FDERIV_D [OF f] .
206.240 -
206.241 - have Ng1: "isCont (\<lambda>k. norm (?Rg k) / norm k) 0"
206.242 - by (simp add: isCont_def FDERIV_D [OF g])
206.243 - have Ng2: "?k -- 0 --> 0"
206.244 - apply (rule LIM_zero)
206.245 - apply (fold isCont_iff)
206.246 - apply (rule FDERIV_isCont [OF f])
206.247 - done
206.248 - have Ng: "?Ng -- 0 --> 0"
206.249 - using isCont_LIM_compose [OF Ng1 Ng2] by simp
206.250 -
206.251 - have "(\<lambda>h. ?Nf h * kG + ?Ng h * (?Nf h + kF))
206.252 - -- 0 --> 0 * kG + 0 * (0 + kF)"
206.253 - by (intro LIM_add LIM_mult LIM_const Nf Ng)
206.254 - thus "(\<lambda>h. ?Nf h * kG + ?Ng h * (?Nf h + kF)) -- 0 --> 0"
206.255 - by simp
206.256 - next
206.257 - fix h::'a assume h: "h \<noteq> 0"
206.258 - thus "0 \<le> norm (g (f (x + h)) - g (f x) - G (F h)) / norm h"
206.259 - by (simp add: divide_nonneg_pos)
206.260 - next
206.261 - fix h::'a assume h: "h \<noteq> 0"
206.262 - have "g (f (x + h)) - g (f x) - G (F h) = G (?Rf h) + ?Rg (?k h)"
206.263 - by (simp add: G.diff)
206.264 - hence "norm (g (f (x + h)) - g (f x) - G (F h)) / norm h
206.265 - = norm (G (?Rf h) + ?Rg (?k h)) / norm h"
206.266 - by (rule arg_cong)
206.267 - also have "\<dots> \<le> norm (G (?Rf h)) / norm h + norm (?Rg (?k h)) / norm h"
206.268 - by (rule norm_ratio_ineq)
206.269 - also have "\<dots> \<le> ?Nf h * kG + ?Ng h * (?Nf h + kF)"
206.270 - proof (rule add_mono)
206.271 - show "norm (G (?Rf h)) / norm h \<le> ?Nf h * kG"
206.272 - apply (rule ord_le_eq_trans)
206.273 - apply (rule divide_right_mono [OF kG norm_ge_zero])
206.274 - apply simp
206.275 - done
206.276 - next
206.277 - have "norm (?Rg (?k h)) / norm h = ?Ng h * (norm (?k h) / norm h)"
206.278 - apply (rule real_divide_cancel_lemma [symmetric])
206.279 - apply (simp add: G.zero)
206.280 - done
206.281 - also have "\<dots> \<le> ?Ng h * (?Nf h + kF)"
206.282 - proof (rule mult_left_mono)
206.283 - have "norm (?k h) / norm h = norm (?Rf h + F h) / norm h"
206.284 - by simp
206.285 - also have "\<dots> \<le> ?Nf h + norm (F h) / norm h"
206.286 - by (rule norm_ratio_ineq)
206.287 - also have "\<dots> \<le> ?Nf h + kF"
206.288 - apply (rule add_left_mono)
206.289 - apply (subst pos_divide_le_eq, simp add: h)
206.290 - apply (subst mult_commute)
206.291 - apply (rule kF)
206.292 - done
206.293 - finally show "norm (?k h) / norm h \<le> ?Nf h + kF" .
206.294 - next
206.295 - show "0 \<le> ?Ng h"
206.296 - apply (case_tac "f (x + h) - f x = 0", simp)
206.297 - apply (rule divide_nonneg_pos [OF norm_ge_zero])
206.298 - apply simp
206.299 - done
206.300 - qed
206.301 - finally show "norm (?Rg (?k h)) / norm h \<le> ?Ng h * (?Nf h + kF)" .
206.302 - qed
206.303 - finally show "norm (g (f (x + h)) - g (f x) - G (F h)) / norm h
206.304 - \<le> ?Nf h * kG + ?Ng h * (?Nf h + kF)" .
206.305 - qed
206.306 -qed
206.307 -
206.308 -subsection {* Product Rule *}
206.309 -
206.310 -lemma (in bounded_bilinear) FDERIV_lemma:
206.311 - "a' ** b' - a ** b - (a ** B + A ** b)
206.312 - = a ** (b' - b - B) + (a' - a - A) ** b' + A ** (b' - b)"
206.313 -by (simp add: diff_left diff_right)
206.314 -
206.315 -lemma (in bounded_bilinear) FDERIV:
206.316 - fixes x :: "'d::real_normed_vector"
206.317 - assumes f: "FDERIV f x :> F"
206.318 - assumes g: "FDERIV g x :> G"
206.319 - shows "FDERIV (\<lambda>x. f x ** g x) x :> (\<lambda>h. f x ** G h + F h ** g x)"
206.320 -proof (rule FDERIV_I)
206.321 - show "bounded_linear (\<lambda>h. f x ** G h + F h ** g x)"
206.322 - apply (rule bounded_linear_add)
206.323 - apply (rule bounded_linear_compose [OF bounded_linear_right])
206.324 - apply (rule FDERIV_bounded_linear [OF g])
206.325 - apply (rule bounded_linear_compose [OF bounded_linear_left])
206.326 - apply (rule FDERIV_bounded_linear [OF f])
206.327 - done
206.328 -next
206.329 - from bounded_linear.bounded [OF FDERIV_bounded_linear [OF f]]
206.330 - obtain KF where norm_F: "\<And>x. norm (F x) \<le> norm x * KF" by fast
206.331 -
206.332 - from pos_bounded obtain K where K: "0 < K" and norm_prod:
206.333 - "\<And>a b. norm (a ** b) \<le> norm a * norm b * K" by fast
206.334 -
206.335 - let ?Rf = "\<lambda>h. f (x + h) - f x - F h"
206.336 - let ?Rg = "\<lambda>h. g (x + h) - g x - G h"
206.337 -
206.338 - let ?fun1 = "\<lambda>h.
206.339 - norm (f x ** ?Rg h + ?Rf h ** g (x + h) + F h ** (g (x + h) - g x)) /
206.340 - norm h"
206.341 -
206.342 - let ?fun2 = "\<lambda>h.
206.343 - norm (f x) * (norm (?Rg h) / norm h) * K +
206.344 - norm (?Rf h) / norm h * norm (g (x + h)) * K +
206.345 - KF * norm (g (x + h) - g x) * K"
206.346 -
206.347 - have "?fun1 -- 0 --> 0"
206.348 - proof (rule real_LIM_sandwich_zero)
206.349 - from f g isCont_iff [THEN iffD1, OF FDERIV_isCont [OF g]]
206.350 - have "?fun2 -- 0 -->
206.351 - norm (f x) * 0 * K + 0 * norm (g x) * K + KF * norm (0::'b) * K"
206.352 - by (intro LIM_add LIM_mult LIM_const LIM_norm LIM_zero FDERIV_D)
206.353 - thus "?fun2 -- 0 --> 0"
206.354 - by simp
206.355 - next
206.356 - fix h::'d assume "h \<noteq> 0"
206.357 - thus "0 \<le> ?fun1 h"
206.358 - by (simp add: divide_nonneg_pos)
206.359 - next
206.360 - fix h::'d assume "h \<noteq> 0"
206.361 - have "?fun1 h \<le> (norm (f x) * norm (?Rg h) * K +
206.362 - norm (?Rf h) * norm (g (x + h)) * K +
206.363 - norm h * KF * norm (g (x + h) - g x) * K) / norm h"
206.364 - by (intro
206.365 - divide_right_mono mult_mono'
206.366 - order_trans [OF norm_triangle_ineq add_mono]
206.367 - order_trans [OF norm_prod mult_right_mono]
206.368 - mult_nonneg_nonneg order_refl norm_ge_zero norm_F
206.369 - K [THEN order_less_imp_le]
206.370 - )
206.371 - also have "\<dots> = ?fun2 h"
206.372 - by (simp add: add_divide_distrib)
206.373 - finally show "?fun1 h \<le> ?fun2 h" .
206.374 - qed
206.375 - thus "(\<lambda>h.
206.376 - norm (f (x + h) ** g (x + h) - f x ** g x - (f x ** G h + F h ** g x))
206.377 - / norm h) -- 0 --> 0"
206.378 - by (simp only: FDERIV_lemma)
206.379 -qed
206.380 -
206.381 -lemmas FDERIV_mult = mult.FDERIV
206.382 -
206.383 -lemmas FDERIV_scaleR = scaleR.FDERIV
206.384 -
206.385 -
206.386 -subsection {* Powers *}
206.387 -
206.388 -lemma FDERIV_power_Suc:
206.389 - fixes x :: "'a::{real_normed_algebra,recpower,comm_ring_1}"
206.390 - shows "FDERIV (\<lambda>x. x ^ Suc n) x :> (\<lambda>h. (1 + of_nat n) * x ^ n * h)"
206.391 - apply (induct n)
206.392 - apply (simp add: power_Suc FDERIV_ident)
206.393 - apply (drule FDERIV_mult [OF FDERIV_ident])
206.394 - apply (simp only: of_nat_Suc left_distrib mult_1_left)
206.395 - apply (simp only: power_Suc right_distrib add_ac mult_ac)
206.396 -done
206.397 -
206.398 -lemma FDERIV_power:
206.399 - fixes x :: "'a::{real_normed_algebra,recpower,comm_ring_1}"
206.400 - shows "FDERIV (\<lambda>x. x ^ n) x :> (\<lambda>h. of_nat n * x ^ (n - 1) * h)"
206.401 - apply (cases n)
206.402 - apply (simp add: FDERIV_const)
206.403 - apply (simp add: FDERIV_power_Suc)
206.404 - done
206.405 -
206.406 -
206.407 -subsection {* Inverse *}
206.408 -
206.409 -lemma inverse_diff_inverse:
206.410 - "\<lbrakk>(a::'a::division_ring) \<noteq> 0; b \<noteq> 0\<rbrakk>
206.411 - \<Longrightarrow> inverse a - inverse b = - (inverse a * (a - b) * inverse b)"
206.412 -by (simp add: right_diff_distrib left_diff_distrib mult_assoc)
206.413 -
206.414 -lemmas bounded_linear_mult_const =
206.415 - mult.bounded_linear_left [THEN bounded_linear_compose]
206.416 -
206.417 -lemmas bounded_linear_const_mult =
206.418 - mult.bounded_linear_right [THEN bounded_linear_compose]
206.419 -
206.420 -lemma FDERIV_inverse:
206.421 - fixes x :: "'a::real_normed_div_algebra"
206.422 - assumes x: "x \<noteq> 0"
206.423 - shows "FDERIV inverse x :> (\<lambda>h. - (inverse x * h * inverse x))"
206.424 - (is "FDERIV ?inv _ :> _")
206.425 -proof (rule FDERIV_I)
206.426 - show "bounded_linear (\<lambda>h. - (?inv x * h * ?inv x))"
206.427 - apply (rule bounded_linear_minus)
206.428 - apply (rule bounded_linear_mult_const)
206.429 - apply (rule bounded_linear_const_mult)
206.430 - apply (rule bounded_linear_ident)
206.431 - done
206.432 -next
206.433 - show "(\<lambda>h. norm (?inv (x + h) - ?inv x - - (?inv x * h * ?inv x)) / norm h)
206.434 - -- 0 --> 0"
206.435 - proof (rule LIM_equal2)
206.436 - show "0 < norm x" using x by simp
206.437 - next
206.438 - fix h::'a
206.439 - assume 1: "h \<noteq> 0"
206.440 - assume "norm (h - 0) < norm x"
206.441 - hence "h \<noteq> -x" by clarsimp
206.442 - hence 2: "x + h \<noteq> 0"
206.443 - apply (rule contrapos_nn)
206.444 - apply (rule sym)
206.445 - apply (erule equals_zero_I)
206.446 - done
206.447 - show "norm (?inv (x + h) - ?inv x - - (?inv x * h * ?inv x)) / norm h
206.448 - = norm ((?inv (x + h) - ?inv x) * h * ?inv x) / norm h"
206.449 - apply (subst inverse_diff_inverse [OF 2 x])
206.450 - apply (subst minus_diff_minus)
206.451 - apply (subst norm_minus_cancel)
206.452 - apply (simp add: left_diff_distrib)
206.453 - done
206.454 - next
206.455 - show "(\<lambda>h. norm ((?inv (x + h) - ?inv x) * h * ?inv x) / norm h)
206.456 - -- 0 --> 0"
206.457 - proof (rule real_LIM_sandwich_zero)
206.458 - show "(\<lambda>h. norm (?inv (x + h) - ?inv x) * norm (?inv x))
206.459 - -- 0 --> 0"
206.460 - apply (rule LIM_mult_left_zero)
206.461 - apply (rule LIM_norm_zero)
206.462 - apply (rule LIM_zero)
206.463 - apply (rule LIM_offset_zero)
206.464 - apply (rule LIM_inverse)
206.465 - apply (rule LIM_ident)
206.466 - apply (rule x)
206.467 - done
206.468 - next
206.469 - fix h::'a assume h: "h \<noteq> 0"
206.470 - show "0 \<le> norm ((?inv (x + h) - ?inv x) * h * ?inv x) / norm h"
206.471 - apply (rule divide_nonneg_pos)
206.472 - apply (rule norm_ge_zero)
206.473 - apply (simp add: h)
206.474 - done
206.475 - next
206.476 - fix h::'a assume h: "h \<noteq> 0"
206.477 - have "norm ((?inv (x + h) - ?inv x) * h * ?inv x) / norm h
206.478 - \<le> norm (?inv (x + h) - ?inv x) * norm h * norm (?inv x) / norm h"
206.479 - apply (rule divide_right_mono [OF _ norm_ge_zero])
206.480 - apply (rule order_trans [OF norm_mult_ineq])
206.481 - apply (rule mult_right_mono [OF _ norm_ge_zero])
206.482 - apply (rule norm_mult_ineq)
206.483 - done
206.484 - also have "\<dots> = norm (?inv (x + h) - ?inv x) * norm (?inv x)"
206.485 - by simp
206.486 - finally show "norm ((?inv (x + h) - ?inv x) * h * ?inv x) / norm h
206.487 - \<le> norm (?inv (x + h) - ?inv x) * norm (?inv x)" .
206.488 - qed
206.489 - qed
206.490 -qed
206.491 -
206.492 -subsection {* Alternate definition *}
206.493 -
206.494 -lemma field_fderiv_def:
206.495 - fixes x :: "'a::real_normed_field" shows
206.496 - "FDERIV f x :> (\<lambda>h. h * D) = (\<lambda>h. (f (x + h) - f x) / h) -- 0 --> D"
206.497 - apply (unfold fderiv_def)
206.498 - apply (simp add: mult.bounded_linear_left)
206.499 - apply (simp cong: LIM_cong add: nonzero_norm_divide [symmetric])
206.500 - apply (subst diff_divide_distrib)
206.501 - apply (subst times_divide_eq_left [symmetric])
206.502 - apply (simp cong: LIM_cong)
206.503 - apply (simp add: LIM_norm_zero_iff LIM_zero_iff)
206.504 -done
206.505 -
206.506 -end
207.1 --- a/src/HOL/Import/Generate-HOL/GenHOL4Base.thy Wed Mar 04 11:05:02 2009 +0100
207.2 +++ b/src/HOL/Import/Generate-HOL/GenHOL4Base.thy Wed Mar 04 11:05:29 2009 +0100
207.3 @@ -88,14 +88,14 @@
207.4 import_theory option;
207.5
207.6 type_maps
207.7 - option > Datatype.option;
207.8 + option > Option.option;
207.9
207.10 const_maps
207.11 - NONE > Datatype.option.None
207.12 - SOME > Datatype.option.Some
207.13 - option_case > Datatype.option.option_case
207.14 - OPTION_MAP > Datatype.option_map
207.15 - THE > Datatype.the
207.16 + NONE > Option.option.None
207.17 + SOME > Option.option.Some
207.18 + option_case > Option.option.option_case
207.19 + OPTION_MAP > Option.map
207.20 + THE > Option.the
207.21 IS_SOME > HOL4Compat.IS_SOME
207.22 IS_NONE > HOL4Compat.IS_NONE
207.23 OPTION_JOIN > HOL4Compat.OPTION_JOIN;
208.1 --- a/src/HOL/Import/HOL4Compat.thy Wed Mar 04 11:05:02 2009 +0100
208.2 +++ b/src/HOL/Import/HOL4Compat.thy Wed Mar 04 11:05:29 2009 +0100
208.3 @@ -73,7 +73,7 @@
208.4 lemma option_case_def: "(!u f. option_case u f None = u) & (!u f x. option_case u f (Some x) = f x)"
208.5 by simp
208.6
208.7 -lemma OPTION_MAP_DEF: "(!f x. option_map f (Some x) = Some (f x)) & (!f. option_map f None = None)"
208.8 +lemma OPTION_MAP_DEF: "(!f x. Option.map f (Some x) = Some (f x)) & (!f. Option.map f None = None)"
208.9 by simp
208.10
208.11 consts
209.1 --- a/src/HOL/IsaMakefile Wed Mar 04 11:05:02 2009 +0100
209.2 +++ b/src/HOL/IsaMakefile Wed Mar 04 11:05:29 2009 +0100
209.3 @@ -127,6 +127,7 @@
209.4 Nat.thy \
209.5 OrderedGroup.thy \
209.6 Orderings.thy \
209.7 + Option.thy \
209.8 Plain.thy \
209.9 Power.thy \
209.10 Predicate.thy \
210.1 --- a/src/HOL/Library/AssocList.thy Wed Mar 04 11:05:02 2009 +0100
210.2 +++ b/src/HOL/Library/AssocList.thy Wed Mar 04 11:05:29 2009 +0100
210.3 @@ -429,7 +429,7 @@
210.4
210.5 subsection {* @{const map_ran} *}
210.6
210.7 -lemma map_ran_conv: "map_of (map_ran f al) k = option_map (f k) (map_of al k)"
210.8 +lemma map_ran_conv: "map_of (map_ran f al) k = Option.map (f k) (map_of al k)"
210.9 by (induct al) auto
210.10
210.11 lemma dom_map_ran: "fst ` set (map_ran f al) = fst ` set al"
211.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
211.2 +++ b/src/HOL/Library/Bit.thy Wed Mar 04 11:05:29 2009 +0100
211.3 @@ -0,0 +1,122 @@
211.4 +(* Title: Bit.thy
211.5 + Author: Brian Huffman
211.6 +*)
211.7 +
211.8 +header {* The Field of Integers mod 2 *}
211.9 +
211.10 +theory Bit
211.11 +imports Main
211.12 +begin
211.13 +
211.14 +subsection {* Bits as a datatype *}
211.15 +
211.16 +typedef (open) bit = "UNIV :: bool set" ..
211.17 +
211.18 +instantiation bit :: "{zero, one}"
211.19 +begin
211.20 +
211.21 +definition zero_bit_def:
211.22 + "0 = Abs_bit False"
211.23 +
211.24 +definition one_bit_def:
211.25 + "1 = Abs_bit True"
211.26 +
211.27 +instance ..
211.28 +
211.29 +end
211.30 +
211.31 +rep_datatype (bit) "0::bit" "1::bit"
211.32 +proof -
211.33 + fix P and x :: bit
211.34 + assume "P (0::bit)" and "P (1::bit)"
211.35 + then have "\<forall>b. P (Abs_bit b)"
211.36 + unfolding zero_bit_def one_bit_def
211.37 + by (simp add: all_bool_eq)
211.38 + then show "P x"
211.39 + by (induct x) simp
211.40 +next
211.41 + show "(0::bit) \<noteq> (1::bit)"
211.42 + unfolding zero_bit_def one_bit_def
211.43 + by (simp add: Abs_bit_inject)
211.44 +qed
211.45 +
211.46 +lemma bit_not_0_iff [iff]: "(x::bit) \<noteq> 0 \<longleftrightarrow> x = 1"
211.47 + by (induct x) simp_all
211.48 +
211.49 +lemma bit_not_1_iff [iff]: "(x::bit) \<noteq> 1 \<longleftrightarrow> x = 0"
211.50 + by (induct x) simp_all
211.51 +
211.52 +
211.53 +subsection {* Type @{typ bit} forms a field *}
211.54 +
211.55 +instantiation bit :: "{field, division_by_zero}"
211.56 +begin
211.57 +
211.58 +definition plus_bit_def:
211.59 + "x + y = (case x of 0 \<Rightarrow> y | 1 \<Rightarrow> (case y of 0 \<Rightarrow> 1 | 1 \<Rightarrow> 0))"
211.60 +
211.61 +definition times_bit_def:
211.62 + "x * y = (case x of 0 \<Rightarrow> 0 | 1 \<Rightarrow> y)"
211.63 +
211.64 +definition uminus_bit_def [simp]:
211.65 + "- x = (x :: bit)"
211.66 +
211.67 +definition minus_bit_def [simp]:
211.68 + "x - y = (x + y :: bit)"
211.69 +
211.70 +definition inverse_bit_def [simp]:
211.71 + "inverse x = (x :: bit)"
211.72 +
211.73 +definition divide_bit_def [simp]:
211.74 + "x / y = (x * y :: bit)"
211.75 +
211.76 +lemmas field_bit_defs =
211.77 + plus_bit_def times_bit_def minus_bit_def uminus_bit_def
211.78 + divide_bit_def inverse_bit_def
211.79 +
211.80 +instance proof
211.81 +qed (unfold field_bit_defs, auto split: bit.split)
211.82 +
211.83 +end
211.84 +
211.85 +lemma bit_add_self: "x + x = (0 :: bit)"
211.86 + unfolding plus_bit_def by (simp split: bit.split)
211.87 +
211.88 +lemma bit_mult_eq_1_iff [simp]: "x * y = (1 :: bit) \<longleftrightarrow> x = 1 \<and> y = 1"
211.89 + unfolding times_bit_def by (simp split: bit.split)
211.90 +
211.91 +text {* Not sure whether the next two should be simp rules. *}
211.92 +
211.93 +lemma bit_add_eq_0_iff: "x + y = (0 :: bit) \<longleftrightarrow> x = y"
211.94 + unfolding plus_bit_def by (simp split: bit.split)
211.95 +
211.96 +lemma bit_add_eq_1_iff: "x + y = (1 :: bit) \<longleftrightarrow> x \<noteq> y"
211.97 + unfolding plus_bit_def by (simp split: bit.split)
211.98 +
211.99 +
211.100 +subsection {* Numerals at type @{typ bit} *}
211.101 +
211.102 +instantiation bit :: number_ring
211.103 +begin
211.104 +
211.105 +definition number_of_bit_def:
211.106 + "(number_of w :: bit) = of_int w"
211.107 +
211.108 +instance proof
211.109 +qed (rule number_of_bit_def)
211.110 +
211.111 +end
211.112 +
211.113 +text {* All numerals reduce to either 0 or 1. *}
211.114 +
211.115 +lemma bit_minus1 [simp]: "-1 = (1 :: bit)"
211.116 + by (simp only: number_of_Min uminus_bit_def)
211.117 +
211.118 +lemma bit_number_of_even [simp]: "number_of (Int.Bit0 w) = (0 :: bit)"
211.119 + by (simp only: number_of_Bit0 add_0_left bit_add_self)
211.120 +
211.121 +lemma bit_number_of_odd [simp]: "number_of (Int.Bit1 w) = (1 :: bit)"
211.122 + by (simp only: number_of_Bit1 add_assoc bit_add_self
211.123 + monoid_add_class.add_0_right)
211.124 +
211.125 +end
212.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
212.2 +++ b/src/HOL/Library/FrechetDeriv.thy Wed Mar 04 11:05:29 2009 +0100
212.3 @@ -0,0 +1,503 @@
212.4 +(* Title : FrechetDeriv.thy
212.5 + ID : $Id$
212.6 + Author : Brian Huffman
212.7 +*)
212.8 +
212.9 +header {* Frechet Derivative *}
212.10 +
212.11 +theory FrechetDeriv
212.12 +imports Lim
212.13 +begin
212.14 +
212.15 +definition
212.16 + fderiv ::
212.17 + "['a::real_normed_vector \<Rightarrow> 'b::real_normed_vector, 'a, 'a \<Rightarrow> 'b] \<Rightarrow> bool"
212.18 + -- {* Frechet derivative: D is derivative of function f at x *}
212.19 + ("(FDERIV (_)/ (_)/ :> (_))" [1000, 1000, 60] 60) where
212.20 + "FDERIV f x :> D = (bounded_linear D \<and>
212.21 + (\<lambda>h. norm (f (x + h) - f x - D h) / norm h) -- 0 --> 0)"
212.22 +
212.23 +lemma FDERIV_I:
212.24 + "\<lbrakk>bounded_linear D; (\<lambda>h. norm (f (x + h) - f x - D h) / norm h) -- 0 --> 0\<rbrakk>
212.25 + \<Longrightarrow> FDERIV f x :> D"
212.26 +by (simp add: fderiv_def)
212.27 +
212.28 +lemma FDERIV_D:
212.29 + "FDERIV f x :> D \<Longrightarrow> (\<lambda>h. norm (f (x + h) - f x - D h) / norm h) -- 0 --> 0"
212.30 +by (simp add: fderiv_def)
212.31 +
212.32 +lemma FDERIV_bounded_linear: "FDERIV f x :> D \<Longrightarrow> bounded_linear D"
212.33 +by (simp add: fderiv_def)
212.34 +
212.35 +lemma bounded_linear_zero:
212.36 + "bounded_linear (\<lambda>x::'a::real_normed_vector. 0::'b::real_normed_vector)"
212.37 +proof
212.38 + show "(0::'b) = 0 + 0" by simp
212.39 + fix r show "(0::'b) = scaleR r 0" by simp
212.40 + have "\<forall>x::'a. norm (0::'b) \<le> norm x * 0" by simp
212.41 + thus "\<exists>K. \<forall>x::'a. norm (0::'b) \<le> norm x * K" ..
212.42 +qed
212.43 +
212.44 +lemma FDERIV_const: "FDERIV (\<lambda>x. k) x :> (\<lambda>h. 0)"
212.45 +by (simp add: fderiv_def bounded_linear_zero)
212.46 +
212.47 +lemma bounded_linear_ident:
212.48 + "bounded_linear (\<lambda>x::'a::real_normed_vector. x)"
212.49 +proof
212.50 + fix x y :: 'a show "x + y = x + y" by simp
212.51 + fix r and x :: 'a show "scaleR r x = scaleR r x" by simp
212.52 + have "\<forall>x::'a. norm x \<le> norm x * 1" by simp
212.53 + thus "\<exists>K. \<forall>x::'a. norm x \<le> norm x * K" ..
212.54 +qed
212.55 +
212.56 +lemma FDERIV_ident: "FDERIV (\<lambda>x. x) x :> (\<lambda>h. h)"
212.57 +by (simp add: fderiv_def bounded_linear_ident)
212.58 +
212.59 +subsection {* Addition *}
212.60 +
212.61 +lemma add_diff_add:
212.62 + fixes a b c d :: "'a::ab_group_add"
212.63 + shows "(a + c) - (b + d) = (a - b) + (c - d)"
212.64 +by simp
212.65 +
212.66 +lemma bounded_linear_add:
212.67 + assumes "bounded_linear f"
212.68 + assumes "bounded_linear g"
212.69 + shows "bounded_linear (\<lambda>x. f x + g x)"
212.70 +proof -
212.71 + interpret f: bounded_linear f by fact
212.72 + interpret g: bounded_linear g by fact
212.73 + show ?thesis apply (unfold_locales)
212.74 + apply (simp only: f.add g.add add_ac)
212.75 + apply (simp only: f.scaleR g.scaleR scaleR_right_distrib)
212.76 + apply (rule f.pos_bounded [THEN exE], rename_tac Kf)
212.77 + apply (rule g.pos_bounded [THEN exE], rename_tac Kg)
212.78 + apply (rule_tac x="Kf + Kg" in exI, safe)
212.79 + apply (subst right_distrib)
212.80 + apply (rule order_trans [OF norm_triangle_ineq])
212.81 + apply (rule add_mono, erule spec, erule spec)
212.82 + done
212.83 +qed
212.84 +
212.85 +lemma norm_ratio_ineq:
212.86 + fixes x y :: "'a::real_normed_vector"
212.87 + fixes h :: "'b::real_normed_vector"
212.88 + shows "norm (x + y) / norm h \<le> norm x / norm h + norm y / norm h"
212.89 +apply (rule ord_le_eq_trans)
212.90 +apply (rule divide_right_mono)
212.91 +apply (rule norm_triangle_ineq)
212.92 +apply (rule norm_ge_zero)
212.93 +apply (rule add_divide_distrib)
212.94 +done
212.95 +
212.96 +lemma FDERIV_add:
212.97 + assumes f: "FDERIV f x :> F"
212.98 + assumes g: "FDERIV g x :> G"
212.99 + shows "FDERIV (\<lambda>x. f x + g x) x :> (\<lambda>h. F h + G h)"
212.100 +proof (rule FDERIV_I)
212.101 + show "bounded_linear (\<lambda>h. F h + G h)"
212.102 + apply (rule bounded_linear_add)
212.103 + apply (rule FDERIV_bounded_linear [OF f])
212.104 + apply (rule FDERIV_bounded_linear [OF g])
212.105 + done
212.106 +next
212.107 + have f': "(\<lambda>h. norm (f (x + h) - f x - F h) / norm h) -- 0 --> 0"
212.108 + using f by (rule FDERIV_D)
212.109 + have g': "(\<lambda>h. norm (g (x + h) - g x - G h) / norm h) -- 0 --> 0"
212.110 + using g by (rule FDERIV_D)
212.111 + from f' g'
212.112 + have "(\<lambda>h. norm (f (x + h) - f x - F h) / norm h
212.113 + + norm (g (x + h) - g x - G h) / norm h) -- 0 --> 0"
212.114 + by (rule LIM_add_zero)
212.115 + thus "(\<lambda>h. norm (f (x + h) + g (x + h) - (f x + g x) - (F h + G h))
212.116 + / norm h) -- 0 --> 0"
212.117 + apply (rule real_LIM_sandwich_zero)
212.118 + apply (simp add: divide_nonneg_pos)
212.119 + apply (simp only: add_diff_add)
212.120 + apply (rule norm_ratio_ineq)
212.121 + done
212.122 +qed
212.123 +
212.124 +subsection {* Subtraction *}
212.125 +
212.126 +lemma bounded_linear_minus:
212.127 + assumes "bounded_linear f"
212.128 + shows "bounded_linear (\<lambda>x. - f x)"
212.129 +proof -
212.130 + interpret f: bounded_linear f by fact
212.131 + show ?thesis apply (unfold_locales)
212.132 + apply (simp add: f.add)
212.133 + apply (simp add: f.scaleR)
212.134 + apply (simp add: f.bounded)
212.135 + done
212.136 +qed
212.137 +
212.138 +lemma FDERIV_minus:
212.139 + "FDERIV f x :> F \<Longrightarrow> FDERIV (\<lambda>x. - f x) x :> (\<lambda>h. - F h)"
212.140 +apply (rule FDERIV_I)
212.141 +apply (rule bounded_linear_minus)
212.142 +apply (erule FDERIV_bounded_linear)
212.143 +apply (simp only: fderiv_def minus_diff_minus norm_minus_cancel)
212.144 +done
212.145 +
212.146 +lemma FDERIV_diff:
212.147 + "\<lbrakk>FDERIV f x :> F; FDERIV g x :> G\<rbrakk>
212.148 + \<Longrightarrow> FDERIV (\<lambda>x. f x - g x) x :> (\<lambda>h. F h - G h)"
212.149 +by (simp only: diff_minus FDERIV_add FDERIV_minus)
212.150 +
212.151 +subsection {* Continuity *}
212.152 +
212.153 +lemma FDERIV_isCont:
212.154 + assumes f: "FDERIV f x :> F"
212.155 + shows "isCont f x"
212.156 +proof -
212.157 + from f interpret F: bounded_linear "F" by (rule FDERIV_bounded_linear)
212.158 + have "(\<lambda>h. norm (f (x + h) - f x - F h) / norm h) -- 0 --> 0"
212.159 + by (rule FDERIV_D [OF f])
212.160 + hence "(\<lambda>h. norm (f (x + h) - f x - F h) / norm h * norm h) -- 0 --> 0"
212.161 + by (intro LIM_mult_zero LIM_norm_zero LIM_ident)
212.162 + hence "(\<lambda>h. norm (f (x + h) - f x - F h)) -- 0 --> 0"
212.163 + by (simp cong: LIM_cong)
212.164 + hence "(\<lambda>h. f (x + h) - f x - F h) -- 0 --> 0"
212.165 + by (rule LIM_norm_zero_cancel)
212.166 + hence "(\<lambda>h. f (x + h) - f x - F h + F h) -- 0 --> 0"
212.167 + by (intro LIM_add_zero F.LIM_zero LIM_ident)
212.168 + hence "(\<lambda>h. f (x + h) - f x) -- 0 --> 0"
212.169 + by simp
212.170 + thus "isCont f x"
212.171 + unfolding isCont_iff by (rule LIM_zero_cancel)
212.172 +qed
212.173 +
212.174 +subsection {* Composition *}
212.175 +
212.176 +lemma real_divide_cancel_lemma:
212.177 + fixes a b c :: real
212.178 + shows "(b = 0 \<Longrightarrow> a = 0) \<Longrightarrow> (a / b) * (b / c) = a / c"
212.179 +by simp
212.180 +
212.181 +lemma bounded_linear_compose:
212.182 + assumes "bounded_linear f"
212.183 + assumes "bounded_linear g"
212.184 + shows "bounded_linear (\<lambda>x. f (g x))"
212.185 +proof -
212.186 + interpret f: bounded_linear f by fact
212.187 + interpret g: bounded_linear g by fact
212.188 + show ?thesis proof (unfold_locales)
212.189 + fix x y show "f (g (x + y)) = f (g x) + f (g y)"
212.190 + by (simp only: f.add g.add)
212.191 + next
212.192 + fix r x show "f (g (scaleR r x)) = scaleR r (f (g x))"
212.193 + by (simp only: f.scaleR g.scaleR)
212.194 + next
212.195 + from f.pos_bounded
212.196 + obtain Kf where f: "\<And>x. norm (f x) \<le> norm x * Kf" and Kf: "0 < Kf" by fast
212.197 + from g.pos_bounded
212.198 + obtain Kg where g: "\<And>x. norm (g x) \<le> norm x * Kg" by fast
212.199 + show "\<exists>K. \<forall>x. norm (f (g x)) \<le> norm x * K"
212.200 + proof (intro exI allI)
212.201 + fix x
212.202 + have "norm (f (g x)) \<le> norm (g x) * Kf"
212.203 + using f .
212.204 + also have "\<dots> \<le> (norm x * Kg) * Kf"
212.205 + using g Kf [THEN order_less_imp_le] by (rule mult_right_mono)
212.206 + also have "(norm x * Kg) * Kf = norm x * (Kg * Kf)"
212.207 + by (rule mult_assoc)
212.208 + finally show "norm (f (g x)) \<le> norm x * (Kg * Kf)" .
212.209 + qed
212.210 + qed
212.211 +qed
212.212 +
212.213 +lemma FDERIV_compose:
212.214 + fixes f :: "'a::real_normed_vector \<Rightarrow> 'b::real_normed_vector"
212.215 + fixes g :: "'b::real_normed_vector \<Rightarrow> 'c::real_normed_vector"
212.216 + assumes f: "FDERIV f x :> F"
212.217 + assumes g: "FDERIV g (f x) :> G"
212.218 + shows "FDERIV (\<lambda>x. g (f x)) x :> (\<lambda>h. G (F h))"
212.219 +proof (rule FDERIV_I)
212.220 + from FDERIV_bounded_linear [OF g] FDERIV_bounded_linear [OF f]
212.221 + show "bounded_linear (\<lambda>h. G (F h))"
212.222 + by (rule bounded_linear_compose)
212.223 +next
212.224 + let ?Rf = "\<lambda>h. f (x + h) - f x - F h"
212.225 + let ?Rg = "\<lambda>k. g (f x + k) - g (f x) - G k"
212.226 + let ?k = "\<lambda>h. f (x + h) - f x"
212.227 + let ?Nf = "\<lambda>h. norm (?Rf h) / norm h"
212.228 + let ?Ng = "\<lambda>h. norm (?Rg (?k h)) / norm (?k h)"
212.229 + from f interpret F!: bounded_linear "F" by (rule FDERIV_bounded_linear)
212.230 + from g interpret G!: bounded_linear "G" by (rule FDERIV_bounded_linear)
212.231 + from F.bounded obtain kF where kF: "\<And>x. norm (F x) \<le> norm x * kF" by fast
212.232 + from G.bounded obtain kG where kG: "\<And>x. norm (G x) \<le> norm x * kG" by fast
212.233 +
212.234 + let ?fun2 = "\<lambda>h. ?Nf h * kG + ?Ng h * (?Nf h + kF)"
212.235 +
212.236 + show "(\<lambda>h. norm (g (f (x + h)) - g (f x) - G (F h)) / norm h) -- 0 --> 0"
212.237 + proof (rule real_LIM_sandwich_zero)
212.238 + have Nf: "?Nf -- 0 --> 0"
212.239 + using FDERIV_D [OF f] .
212.240 +
212.241 + have Ng1: "isCont (\<lambda>k. norm (?Rg k) / norm k) 0"
212.242 + by (simp add: isCont_def FDERIV_D [OF g])
212.243 + have Ng2: "?k -- 0 --> 0"
212.244 + apply (rule LIM_zero)
212.245 + apply (fold isCont_iff)
212.246 + apply (rule FDERIV_isCont [OF f])
212.247 + done
212.248 + have Ng: "?Ng -- 0 --> 0"
212.249 + using isCont_LIM_compose [OF Ng1 Ng2] by simp
212.250 +
212.251 + have "(\<lambda>h. ?Nf h * kG + ?Ng h * (?Nf h + kF))
212.252 + -- 0 --> 0 * kG + 0 * (0 + kF)"
212.253 + by (intro LIM_add LIM_mult LIM_const Nf Ng)
212.254 + thus "(\<lambda>h. ?Nf h * kG + ?Ng h * (?Nf h + kF)) -- 0 --> 0"
212.255 + by simp
212.256 + next
212.257 + fix h::'a assume h: "h \<noteq> 0"
212.258 + thus "0 \<le> norm (g (f (x + h)) - g (f x) - G (F h)) / norm h"
212.259 + by (simp add: divide_nonneg_pos)
212.260 + next
212.261 + fix h::'a assume h: "h \<noteq> 0"
212.262 + have "g (f (x + h)) - g (f x) - G (F h) = G (?Rf h) + ?Rg (?k h)"
212.263 + by (simp add: G.diff)
212.264 + hence "norm (g (f (x + h)) - g (f x) - G (F h)) / norm h
212.265 + = norm (G (?Rf h) + ?Rg (?k h)) / norm h"
212.266 + by (rule arg_cong)
212.267 + also have "\<dots> \<le> norm (G (?Rf h)) / norm h + norm (?Rg (?k h)) / norm h"
212.268 + by (rule norm_ratio_ineq)
212.269 + also have "\<dots> \<le> ?Nf h * kG + ?Ng h * (?Nf h + kF)"
212.270 + proof (rule add_mono)
212.271 + show "norm (G (?Rf h)) / norm h \<le> ?Nf h * kG"
212.272 + apply (rule ord_le_eq_trans)
212.273 + apply (rule divide_right_mono [OF kG norm_ge_zero])
212.274 + apply simp
212.275 + done
212.276 + next
212.277 + have "norm (?Rg (?k h)) / norm h = ?Ng h * (norm (?k h) / norm h)"
212.278 + apply (rule real_divide_cancel_lemma [symmetric])
212.279 + apply (simp add: G.zero)
212.280 + done
212.281 + also have "\<dots> \<le> ?Ng h * (?Nf h + kF)"
212.282 + proof (rule mult_left_mono)
212.283 + have "norm (?k h) / norm h = norm (?Rf h + F h) / norm h"
212.284 + by simp
212.285 + also have "\<dots> \<le> ?Nf h + norm (F h) / norm h"
212.286 + by (rule norm_ratio_ineq)
212.287 + also have "\<dots> \<le> ?Nf h + kF"
212.288 + apply (rule add_left_mono)
212.289 + apply (subst pos_divide_le_eq, simp add: h)
212.290 + apply (subst mult_commute)
212.291 + apply (rule kF)
212.292 + done
212.293 + finally show "norm (?k h) / norm h \<le> ?Nf h + kF" .
212.294 + next
212.295 + show "0 \<le> ?Ng h"
212.296 + apply (case_tac "f (x + h) - f x = 0", simp)
212.297 + apply (rule divide_nonneg_pos [OF norm_ge_zero])
212.298 + apply simp
212.299 + done
212.300 + qed
212.301 + finally show "norm (?Rg (?k h)) / norm h \<le> ?Ng h * (?Nf h + kF)" .
212.302 + qed
212.303 + finally show "norm (g (f (x + h)) - g (f x) - G (F h)) / norm h
212.304 + \<le> ?Nf h * kG + ?Ng h * (?Nf h + kF)" .
212.305 + qed
212.306 +qed
212.307 +
212.308 +subsection {* Product Rule *}
212.309 +
212.310 +lemma (in bounded_bilinear) FDERIV_lemma:
212.311 + "a' ** b' - a ** b - (a ** B + A ** b)
212.312 + = a ** (b' - b - B) + (a' - a - A) ** b' + A ** (b' - b)"
212.313 +by (simp add: diff_left diff_right)
212.314 +
212.315 +lemma (in bounded_bilinear) FDERIV:
212.316 + fixes x :: "'d::real_normed_vector"
212.317 + assumes f: "FDERIV f x :> F"
212.318 + assumes g: "FDERIV g x :> G"
212.319 + shows "FDERIV (\<lambda>x. f x ** g x) x :> (\<lambda>h. f x ** G h + F h ** g x)"
212.320 +proof (rule FDERIV_I)
212.321 + show "bounded_linear (\<lambda>h. f x ** G h + F h ** g x)"
212.322 + apply (rule bounded_linear_add)
212.323 + apply (rule bounded_linear_compose [OF bounded_linear_right])
212.324 + apply (rule FDERIV_bounded_linear [OF g])
212.325 + apply (rule bounded_linear_compose [OF bounded_linear_left])
212.326 + apply (rule FDERIV_bounded_linear [OF f])
212.327 + done
212.328 +next
212.329 + from bounded_linear.bounded [OF FDERIV_bounded_linear [OF f]]
212.330 + obtain KF where norm_F: "\<And>x. norm (F x) \<le> norm x * KF" by fast
212.331 +
212.332 + from pos_bounded obtain K where K: "0 < K" and norm_prod:
212.333 + "\<And>a b. norm (a ** b) \<le> norm a * norm b * K" by fast
212.334 +
212.335 + let ?Rf = "\<lambda>h. f (x + h) - f x - F h"
212.336 + let ?Rg = "\<lambda>h. g (x + h) - g x - G h"
212.337 +
212.338 + let ?fun1 = "\<lambda>h.
212.339 + norm (f x ** ?Rg h + ?Rf h ** g (x + h) + F h ** (g (x + h) - g x)) /
212.340 + norm h"
212.341 +
212.342 + let ?fun2 = "\<lambda>h.
212.343 + norm (f x) * (norm (?Rg h) / norm h) * K +
212.344 + norm (?Rf h) / norm h * norm (g (x + h)) * K +
212.345 + KF * norm (g (x + h) - g x) * K"
212.346 +
212.347 + have "?fun1 -- 0 --> 0"
212.348 + proof (rule real_LIM_sandwich_zero)
212.349 + from f g isCont_iff [THEN iffD1, OF FDERIV_isCont [OF g]]
212.350 + have "?fun2 -- 0 -->
212.351 + norm (f x) * 0 * K + 0 * norm (g x) * K + KF * norm (0::'b) * K"
212.352 + by (intro LIM_add LIM_mult LIM_const LIM_norm LIM_zero FDERIV_D)
212.353 + thus "?fun2 -- 0 --> 0"
212.354 + by simp
212.355 + next
212.356 + fix h::'d assume "h \<noteq> 0"
212.357 + thus "0 \<le> ?fun1 h"
212.358 + by (simp add: divide_nonneg_pos)
212.359 + next
212.360 + fix h::'d assume "h \<noteq> 0"
212.361 + have "?fun1 h \<le> (norm (f x) * norm (?Rg h) * K +
212.362 + norm (?Rf h) * norm (g (x + h)) * K +
212.363 + norm h * KF * norm (g (x + h) - g x) * K) / norm h"
212.364 + by (intro
212.365 + divide_right_mono mult_mono'
212.366 + order_trans [OF norm_triangle_ineq add_mono]
212.367 + order_trans [OF norm_prod mult_right_mono]
212.368 + mult_nonneg_nonneg order_refl norm_ge_zero norm_F
212.369 + K [THEN order_less_imp_le]
212.370 + )
212.371 + also have "\<dots> = ?fun2 h"
212.372 + by (simp add: add_divide_distrib)
212.373 + finally show "?fun1 h \<le> ?fun2 h" .
212.374 + qed
212.375 + thus "(\<lambda>h.
212.376 + norm (f (x + h) ** g (x + h) - f x ** g x - (f x ** G h + F h ** g x))
212.377 + / norm h) -- 0 --> 0"
212.378 + by (simp only: FDERIV_lemma)
212.379 +qed
212.380 +
212.381 +lemmas FDERIV_mult = mult.FDERIV
212.382 +
212.383 +lemmas FDERIV_scaleR = scaleR.FDERIV
212.384 +
212.385 +
212.386 +subsection {* Powers *}
212.387 +
212.388 +lemma FDERIV_power_Suc:
212.389 + fixes x :: "'a::{real_normed_algebra,recpower,comm_ring_1}"
212.390 + shows "FDERIV (\<lambda>x. x ^ Suc n) x :> (\<lambda>h. (1 + of_nat n) * x ^ n * h)"
212.391 + apply (induct n)
212.392 + apply (simp add: power_Suc FDERIV_ident)
212.393 + apply (drule FDERIV_mult [OF FDERIV_ident])
212.394 + apply (simp only: of_nat_Suc left_distrib mult_1_left)
212.395 + apply (simp only: power_Suc right_distrib add_ac mult_ac)
212.396 +done
212.397 +
212.398 +lemma FDERIV_power:
212.399 + fixes x :: "'a::{real_normed_algebra,recpower,comm_ring_1}"
212.400 + shows "FDERIV (\<lambda>x. x ^ n) x :> (\<lambda>h. of_nat n * x ^ (n - 1) * h)"
212.401 + apply (cases n)
212.402 + apply (simp add: FDERIV_const)
212.403 + apply (simp add: FDERIV_power_Suc)
212.404 + done
212.405 +
212.406 +
212.407 +subsection {* Inverse *}
212.408 +
212.409 +lemma inverse_diff_inverse:
212.410 + "\<lbrakk>(a::'a::division_ring) \<noteq> 0; b \<noteq> 0\<rbrakk>
212.411 + \<Longrightarrow> inverse a - inverse b = - (inverse a * (a - b) * inverse b)"
212.412 +by (simp add: right_diff_distrib left_diff_distrib mult_assoc)
212.413 +
212.414 +lemmas bounded_linear_mult_const =
212.415 + mult.bounded_linear_left [THEN bounded_linear_compose]
212.416 +
212.417 +lemmas bounded_linear_const_mult =
212.418 + mult.bounded_linear_right [THEN bounded_linear_compose]
212.419 +
212.420 +lemma FDERIV_inverse:
212.421 + fixes x :: "'a::real_normed_div_algebra"
212.422 + assumes x: "x \<noteq> 0"
212.423 + shows "FDERIV inverse x :> (\<lambda>h. - (inverse x * h * inverse x))"
212.424 + (is "FDERIV ?inv _ :> _")
212.425 +proof (rule FDERIV_I)
212.426 + show "bounded_linear (\<lambda>h. - (?inv x * h * ?inv x))"
212.427 + apply (rule bounded_linear_minus)
212.428 + apply (rule bounded_linear_mult_const)
212.429 + apply (rule bounded_linear_const_mult)
212.430 + apply (rule bounded_linear_ident)
212.431 + done
212.432 +next
212.433 + show "(\<lambda>h. norm (?inv (x + h) - ?inv x - - (?inv x * h * ?inv x)) / norm h)
212.434 + -- 0 --> 0"
212.435 + proof (rule LIM_equal2)
212.436 + show "0 < norm x" using x by simp
212.437 + next
212.438 + fix h::'a
212.439 + assume 1: "h \<noteq> 0"
212.440 + assume "norm (h - 0) < norm x"
212.441 + hence "h \<noteq> -x" by clarsimp
212.442 + hence 2: "x + h \<noteq> 0"
212.443 + apply (rule contrapos_nn)
212.444 + apply (rule sym)
212.445 + apply (erule equals_zero_I)
212.446 + done
212.447 + show "norm (?inv (x + h) - ?inv x - - (?inv x * h * ?inv x)) / norm h
212.448 + = norm ((?inv (x + h) - ?inv x) * h * ?inv x) / norm h"
212.449 + apply (subst inverse_diff_inverse [OF 2 x])
212.450 + apply (subst minus_diff_minus)
212.451 + apply (subst norm_minus_cancel)
212.452 + apply (simp add: left_diff_distrib)
212.453 + done
212.454 + next
212.455 + show "(\<lambda>h. norm ((?inv (x + h) - ?inv x) * h * ?inv x) / norm h)
212.456 + -- 0 --> 0"
212.457 + proof (rule real_LIM_sandwich_zero)
212.458 + show "(\<lambda>h. norm (?inv (x + h) - ?inv x) * norm (?inv x))
212.459 + -- 0 --> 0"
212.460 + apply (rule LIM_mult_left_zero)
212.461 + apply (rule LIM_norm_zero)
212.462 + apply (rule LIM_zero)
212.463 + apply (rule LIM_offset_zero)
212.464 + apply (rule LIM_inverse)
212.465 + apply (rule LIM_ident)
212.466 + apply (rule x)
212.467 + done
212.468 + next
212.469 + fix h::'a assume h: "h \<noteq> 0"
212.470 + show "0 \<le> norm ((?inv (x + h) - ?inv x) * h * ?inv x) / norm h"
212.471 + apply (rule divide_nonneg_pos)
212.472 + apply (rule norm_ge_zero)
212.473 + apply (simp add: h)
212.474 + done
212.475 + next
212.476 + fix h::'a assume h: "h \<noteq> 0"
212.477 + have "norm ((?inv (x + h) - ?inv x) * h * ?inv x) / norm h
212.478 + \<le> norm (?inv (x + h) - ?inv x) * norm h * norm (?inv x) / norm h"
212.479 + apply (rule divide_right_mono [OF _ norm_ge_zero])
212.480 + apply (rule order_trans [OF norm_mult_ineq])
212.481 + apply (rule mult_right_mono [OF _ norm_ge_zero])
212.482 + apply (rule norm_mult_ineq)
212.483 + done
212.484 + also have "\<dots> = norm (?inv (x + h) - ?inv x) * norm (?inv x)"
212.485 + by simp
212.486 + finally show "norm ((?inv (x + h) - ?inv x) * h * ?inv x) / norm h
212.487 + \<le> norm (?inv (x + h) - ?inv x) * norm (?inv x)" .
212.488 + qed
212.489 + qed
212.490 +qed
212.491 +
212.492 +subsection {* Alternate definition *}
212.493 +
212.494 +lemma field_fderiv_def:
212.495 + fixes x :: "'a::real_normed_field" shows
212.496 + "FDERIV f x :> (\<lambda>h. h * D) = (\<lambda>h. (f (x + h) - f x) / h) -- 0 --> D"
212.497 + apply (unfold fderiv_def)
212.498 + apply (simp add: mult.bounded_linear_left)
212.499 + apply (simp cong: LIM_cong add: nonzero_norm_divide [symmetric])
212.500 + apply (subst diff_divide_distrib)
212.501 + apply (subst times_divide_eq_left [symmetric])
212.502 + apply (simp cong: LIM_cong)
212.503 + apply (simp add: LIM_norm_zero_iff LIM_zero_iff)
212.504 +done
212.505 +
212.506 +end
213.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
213.2 +++ b/src/HOL/Library/Inner_Product.thy Wed Mar 04 11:05:29 2009 +0100
213.3 @@ -0,0 +1,296 @@
213.4 +(* Title: Inner_Product.thy
213.5 + Author: Brian Huffman
213.6 +*)
213.7 +
213.8 +header {* Inner Product Spaces and the Gradient Derivative *}
213.9 +
213.10 +theory Inner_Product
213.11 +imports Complex FrechetDeriv
213.12 +begin
213.13 +
213.14 +subsection {* Real inner product spaces *}
213.15 +
213.16 +class real_inner = real_vector + sgn_div_norm +
213.17 + fixes inner :: "'a \<Rightarrow> 'a \<Rightarrow> real"
213.18 + assumes inner_commute: "inner x y = inner y x"
213.19 + and inner_left_distrib: "inner (x + y) z = inner x z + inner y z"
213.20 + and inner_scaleR_left: "inner (scaleR r x) y = r * (inner x y)"
213.21 + and inner_ge_zero [simp]: "0 \<le> inner x x"
213.22 + and inner_eq_zero_iff [simp]: "inner x x = 0 \<longleftrightarrow> x = 0"
213.23 + and norm_eq_sqrt_inner: "norm x = sqrt (inner x x)"
213.24 +begin
213.25 +
213.26 +lemma inner_zero_left [simp]: "inner 0 x = 0"
213.27 + using inner_left_distrib [of 0 0 x] by simp
213.28 +
213.29 +lemma inner_minus_left [simp]: "inner (- x) y = - inner x y"
213.30 + using inner_left_distrib [of x "- x" y] by simp
213.31 +
213.32 +lemma inner_diff_left: "inner (x - y) z = inner x z - inner y z"
213.33 + by (simp add: diff_minus inner_left_distrib)
213.34 +
213.35 +text {* Transfer distributivity rules to right argument. *}
213.36 +
213.37 +lemma inner_right_distrib: "inner x (y + z) = inner x y + inner x z"
213.38 + using inner_left_distrib [of y z x] by (simp only: inner_commute)
213.39 +
213.40 +lemma inner_scaleR_right: "inner x (scaleR r y) = r * (inner x y)"
213.41 + using inner_scaleR_left [of r y x] by (simp only: inner_commute)
213.42 +
213.43 +lemma inner_zero_right [simp]: "inner x 0 = 0"
213.44 + using inner_zero_left [of x] by (simp only: inner_commute)
213.45 +
213.46 +lemma inner_minus_right [simp]: "inner x (- y) = - inner x y"
213.47 + using inner_minus_left [of y x] by (simp only: inner_commute)
213.48 +
213.49 +lemma inner_diff_right: "inner x (y - z) = inner x y - inner x z"
213.50 + using inner_diff_left [of y z x] by (simp only: inner_commute)
213.51 +
213.52 +lemmas inner_distrib = inner_left_distrib inner_right_distrib
213.53 +lemmas inner_diff = inner_diff_left inner_diff_right
213.54 +lemmas inner_scaleR = inner_scaleR_left inner_scaleR_right
213.55 +
213.56 +lemma inner_gt_zero_iff [simp]: "0 < inner x x \<longleftrightarrow> x \<noteq> 0"
213.57 + by (simp add: order_less_le)
213.58 +
213.59 +lemma power2_norm_eq_inner: "(norm x)\<twosuperior> = inner x x"
213.60 + by (simp add: norm_eq_sqrt_inner)
213.61 +
213.62 +lemma Cauchy_Schwarz_ineq:
213.63 + "(inner x y)\<twosuperior> \<le> inner x x * inner y y"
213.64 +proof (cases)
213.65 + assume "y = 0"
213.66 + thus ?thesis by simp
213.67 +next
213.68 + assume y: "y \<noteq> 0"
213.69 + let ?r = "inner x y / inner y y"
213.70 + have "0 \<le> inner (x - scaleR ?r y) (x - scaleR ?r y)"
213.71 + by (rule inner_ge_zero)
213.72 + also have "\<dots> = inner x x - inner y x * ?r"
213.73 + by (simp add: inner_diff inner_scaleR)
213.74 + also have "\<dots> = inner x x - (inner x y)\<twosuperior> / inner y y"
213.75 + by (simp add: power2_eq_square inner_commute)
213.76 + finally have "0 \<le> inner x x - (inner x y)\<twosuperior> / inner y y" .
213.77 + hence "(inner x y)\<twosuperior> / inner y y \<le> inner x x"
213.78 + by (simp add: le_diff_eq)
213.79 + thus "(inner x y)\<twosuperior> \<le> inner x x * inner y y"
213.80 + by (simp add: pos_divide_le_eq y)
213.81 +qed
213.82 +
213.83 +lemma Cauchy_Schwarz_ineq2:
213.84 + "\<bar>inner x y\<bar> \<le> norm x * norm y"
213.85 +proof (rule power2_le_imp_le)
213.86 + have "(inner x y)\<twosuperior> \<le> inner x x * inner y y"
213.87 + using Cauchy_Schwarz_ineq .
213.88 + thus "\<bar>inner x y\<bar>\<twosuperior> \<le> (norm x * norm y)\<twosuperior>"
213.89 + by (simp add: power_mult_distrib power2_norm_eq_inner)
213.90 + show "0 \<le> norm x * norm y"
213.91 + unfolding norm_eq_sqrt_inner
213.92 + by (intro mult_nonneg_nonneg real_sqrt_ge_zero inner_ge_zero)
213.93 +qed
213.94 +
213.95 +subclass real_normed_vector
213.96 +proof
213.97 + fix a :: real and x y :: 'a
213.98 + show "0 \<le> norm x"
213.99 + unfolding norm_eq_sqrt_inner by simp
213.100 + show "norm x = 0 \<longleftrightarrow> x = 0"
213.101 + unfolding norm_eq_sqrt_inner by simp
213.102 + show "norm (x + y) \<le> norm x + norm y"
213.103 + proof (rule power2_le_imp_le)
213.104 + have "inner x y \<le> norm x * norm y"
213.105 + by (rule order_trans [OF abs_ge_self Cauchy_Schwarz_ineq2])
213.106 + thus "(norm (x + y))\<twosuperior> \<le> (norm x + norm y)\<twosuperior>"
213.107 + unfolding power2_sum power2_norm_eq_inner
213.108 + by (simp add: inner_distrib inner_commute)
213.109 + show "0 \<le> norm x + norm y"
213.110 + unfolding norm_eq_sqrt_inner
213.111 + by (simp add: add_nonneg_nonneg)
213.112 + qed
213.113 + have "sqrt (a\<twosuperior> * inner x x) = \<bar>a\<bar> * sqrt (inner x x)"
213.114 + by (simp add: real_sqrt_mult_distrib)
213.115 + then show "norm (a *\<^sub>R x) = \<bar>a\<bar> * norm x"
213.116 + unfolding norm_eq_sqrt_inner
213.117 + by (simp add: inner_scaleR power2_eq_square mult_assoc)
213.118 +qed
213.119 +
213.120 +end
213.121 +
213.122 +interpretation inner!:
213.123 + bounded_bilinear "inner::'a::real_inner \<Rightarrow> 'a \<Rightarrow> real"
213.124 +proof
213.125 + fix x y z :: 'a and r :: real
213.126 + show "inner (x + y) z = inner x z + inner y z"
213.127 + by (rule inner_left_distrib)
213.128 + show "inner x (y + z) = inner x y + inner x z"
213.129 + by (rule inner_right_distrib)
213.130 + show "inner (scaleR r x) y = scaleR r (inner x y)"
213.131 + unfolding real_scaleR_def by (rule inner_scaleR_left)
213.132 + show "inner x (scaleR r y) = scaleR r (inner x y)"
213.133 + unfolding real_scaleR_def by (rule inner_scaleR_right)
213.134 + show "\<exists>K. \<forall>x y::'a. norm (inner x y) \<le> norm x * norm y * K"
213.135 + proof
213.136 + show "\<forall>x y::'a. norm (inner x y) \<le> norm x * norm y * 1"
213.137 + by (simp add: Cauchy_Schwarz_ineq2)
213.138 + qed
213.139 +qed
213.140 +
213.141 +interpretation inner_left!:
213.142 + bounded_linear "\<lambda>x::'a::real_inner. inner x y"
213.143 + by (rule inner.bounded_linear_left)
213.144 +
213.145 +interpretation inner_right!:
213.146 + bounded_linear "\<lambda>y::'a::real_inner. inner x y"
213.147 + by (rule inner.bounded_linear_right)
213.148 +
213.149 +
213.150 +subsection {* Class instances *}
213.151 +
213.152 +instantiation real :: real_inner
213.153 +begin
213.154 +
213.155 +definition inner_real_def [simp]: "inner = op *"
213.156 +
213.157 +instance proof
213.158 + fix x y z r :: real
213.159 + show "inner x y = inner y x"
213.160 + unfolding inner_real_def by (rule mult_commute)
213.161 + show "inner (x + y) z = inner x z + inner y z"
213.162 + unfolding inner_real_def by (rule left_distrib)
213.163 + show "inner (scaleR r x) y = r * inner x y"
213.164 + unfolding inner_real_def real_scaleR_def by (rule mult_assoc)
213.165 + show "0 \<le> inner x x"
213.166 + unfolding inner_real_def by simp
213.167 + show "inner x x = 0 \<longleftrightarrow> x = 0"
213.168 + unfolding inner_real_def by simp
213.169 + show "norm x = sqrt (inner x x)"
213.170 + unfolding inner_real_def by simp
213.171 +qed
213.172 +
213.173 +end
213.174 +
213.175 +instantiation complex :: real_inner
213.176 +begin
213.177 +
213.178 +definition inner_complex_def:
213.179 + "inner x y = Re x * Re y + Im x * Im y"
213.180 +
213.181 +instance proof
213.182 + fix x y z :: complex and r :: real
213.183 + show "inner x y = inner y x"
213.184 + unfolding inner_complex_def by (simp add: mult_commute)
213.185 + show "inner (x + y) z = inner x z + inner y z"
213.186 + unfolding inner_complex_def by (simp add: left_distrib)
213.187 + show "inner (scaleR r x) y = r * inner x y"
213.188 + unfolding inner_complex_def by (simp add: right_distrib)
213.189 + show "0 \<le> inner x x"
213.190 + unfolding inner_complex_def by (simp add: add_nonneg_nonneg)
213.191 + show "inner x x = 0 \<longleftrightarrow> x = 0"
213.192 + unfolding inner_complex_def
213.193 + by (simp add: add_nonneg_eq_0_iff complex_Re_Im_cancel_iff)
213.194 + show "norm x = sqrt (inner x x)"
213.195 + unfolding inner_complex_def complex_norm_def
213.196 + by (simp add: power2_eq_square)
213.197 +qed
213.198 +
213.199 +end
213.200 +
213.201 +
213.202 +subsection {* Gradient derivative *}
213.203 +
213.204 +definition
213.205 + gderiv ::
213.206 + "['a::real_inner \<Rightarrow> real, 'a, 'a] \<Rightarrow> bool"
213.207 + ("(GDERIV (_)/ (_)/ :> (_))" [1000, 1000, 60] 60)
213.208 +where
213.209 + "GDERIV f x :> D \<longleftrightarrow> FDERIV f x :> (\<lambda>h. inner h D)"
213.210 +
213.211 +lemma deriv_fderiv: "DERIV f x :> D \<longleftrightarrow> FDERIV f x :> (\<lambda>h. h * D)"
213.212 + by (simp only: deriv_def field_fderiv_def)
213.213 +
213.214 +lemma gderiv_deriv [simp]: "GDERIV f x :> D \<longleftrightarrow> DERIV f x :> D"
213.215 + by (simp only: gderiv_def deriv_fderiv inner_real_def)
213.216 +
213.217 +lemma GDERIV_DERIV_compose:
213.218 + "\<lbrakk>GDERIV f x :> df; DERIV g (f x) :> dg\<rbrakk>
213.219 + \<Longrightarrow> GDERIV (\<lambda>x. g (f x)) x :> scaleR dg df"
213.220 + unfolding gderiv_def deriv_fderiv
213.221 + apply (drule (1) FDERIV_compose)
213.222 + apply (simp add: inner_scaleR_right mult_ac)
213.223 + done
213.224 +
213.225 +lemma FDERIV_subst: "\<lbrakk>FDERIV f x :> df; df = d\<rbrakk> \<Longrightarrow> FDERIV f x :> d"
213.226 + by simp
213.227 +
213.228 +lemma GDERIV_subst: "\<lbrakk>GDERIV f x :> df; df = d\<rbrakk> \<Longrightarrow> GDERIV f x :> d"
213.229 + by simp
213.230 +
213.231 +lemma GDERIV_const: "GDERIV (\<lambda>x. k) x :> 0"
213.232 + unfolding gderiv_def inner_right.zero by (rule FDERIV_const)
213.233 +
213.234 +lemma GDERIV_add:
213.235 + "\<lbrakk>GDERIV f x :> df; GDERIV g x :> dg\<rbrakk>
213.236 + \<Longrightarrow> GDERIV (\<lambda>x. f x + g x) x :> df + dg"
213.237 + unfolding gderiv_def inner_right.add by (rule FDERIV_add)
213.238 +
213.239 +lemma GDERIV_minus:
213.240 + "GDERIV f x :> df \<Longrightarrow> GDERIV (\<lambda>x. - f x) x :> - df"
213.241 + unfolding gderiv_def inner_right.minus by (rule FDERIV_minus)
213.242 +
213.243 +lemma GDERIV_diff:
213.244 + "\<lbrakk>GDERIV f x :> df; GDERIV g x :> dg\<rbrakk>
213.245 + \<Longrightarrow> GDERIV (\<lambda>x. f x - g x) x :> df - dg"
213.246 + unfolding gderiv_def inner_right.diff by (rule FDERIV_diff)
213.247 +
213.248 +lemma GDERIV_scaleR:
213.249 + "\<lbrakk>DERIV f x :> df; GDERIV g x :> dg\<rbrakk>
213.250 + \<Longrightarrow> GDERIV (\<lambda>x. scaleR (f x) (g x)) x
213.251 + :> (scaleR (f x) dg + scaleR df (g x))"
213.252 + unfolding gderiv_def deriv_fderiv inner_right.add inner_right.scaleR
213.253 + apply (rule FDERIV_subst)
213.254 + apply (erule (1) scaleR.FDERIV)
213.255 + apply (simp add: mult_ac)
213.256 + done
213.257 +
213.258 +lemma GDERIV_mult:
213.259 + "\<lbrakk>GDERIV f x :> df; GDERIV g x :> dg\<rbrakk>
213.260 + \<Longrightarrow> GDERIV (\<lambda>x. f x * g x) x :> scaleR (f x) dg + scaleR (g x) df"
213.261 + unfolding gderiv_def
213.262 + apply (rule FDERIV_subst)
213.263 + apply (erule (1) FDERIV_mult)
213.264 + apply (simp add: inner_distrib inner_scaleR mult_ac)
213.265 + done
213.266 +
213.267 +lemma GDERIV_inverse:
213.268 + "\<lbrakk>GDERIV f x :> df; f x \<noteq> 0\<rbrakk>
213.269 + \<Longrightarrow> GDERIV (\<lambda>x. inverse (f x)) x :> - (inverse (f x))\<twosuperior> *\<^sub>R df"
213.270 + apply (erule GDERIV_DERIV_compose)
213.271 + apply (erule DERIV_inverse [folded numeral_2_eq_2])
213.272 + done
213.273 +
213.274 +lemma GDERIV_norm:
213.275 + assumes "x \<noteq> 0" shows "GDERIV (\<lambda>x. norm x) x :> sgn x"
213.276 +proof -
213.277 + have 1: "FDERIV (\<lambda>x. inner x x) x :> (\<lambda>h. inner x h + inner h x)"
213.278 + by (intro inner.FDERIV FDERIV_ident)
213.279 + have 2: "(\<lambda>h. inner x h + inner h x) = (\<lambda>h. inner h (scaleR 2 x))"
213.280 + by (simp add: expand_fun_eq inner_scaleR inner_commute)
213.281 + have "0 < inner x x" using `x \<noteq> 0` by simp
213.282 + then have 3: "DERIV sqrt (inner x x) :> (inverse (sqrt (inner x x)) / 2)"
213.283 + by (rule DERIV_real_sqrt)
213.284 + have 4: "(inverse (sqrt (inner x x)) / 2) *\<^sub>R 2 *\<^sub>R x = sgn x"
213.285 + by (simp add: sgn_div_norm norm_eq_sqrt_inner)
213.286 + show ?thesis
213.287 + unfolding norm_eq_sqrt_inner
213.288 + apply (rule GDERIV_subst [OF _ 4])
213.289 + apply (rule GDERIV_DERIV_compose [where g=sqrt and df="scaleR 2 x"])
213.290 + apply (subst gderiv_def)
213.291 + apply (rule FDERIV_subst [OF _ 2])
213.292 + apply (rule 1)
213.293 + apply (rule 3)
213.294 + done
213.295 +qed
213.296 +
213.297 +lemmas FDERIV_norm = GDERIV_norm [unfolded gderiv_def]
213.298 +
213.299 +end
214.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
214.2 +++ b/src/HOL/Library/Poly_Deriv.thy Wed Mar 04 11:05:29 2009 +0100
214.3 @@ -0,0 +1,316 @@
214.4 +(* Title: Poly_Deriv.thy
214.5 + Author: Amine Chaieb
214.6 + Ported to new Polynomial library by Brian Huffman
214.7 +*)
214.8 +
214.9 +header{* Polynomials and Differentiation *}
214.10 +
214.11 +theory Poly_Deriv
214.12 +imports Deriv Polynomial
214.13 +begin
214.14 +
214.15 +subsection {* Derivatives of univariate polynomials *}
214.16 +
214.17 +definition
214.18 + pderiv :: "'a::real_normed_field poly \<Rightarrow> 'a poly" where
214.19 + "pderiv = poly_rec 0 (\<lambda>a p p'. p + pCons 0 p')"
214.20 +
214.21 +lemma pderiv_0 [simp]: "pderiv 0 = 0"
214.22 + unfolding pderiv_def by (simp add: poly_rec_0)
214.23 +
214.24 +lemma pderiv_pCons: "pderiv (pCons a p) = p + pCons 0 (pderiv p)"
214.25 + unfolding pderiv_def by (simp add: poly_rec_pCons)
214.26 +
214.27 +lemma coeff_pderiv: "coeff (pderiv p) n = of_nat (Suc n) * coeff p (Suc n)"
214.28 + apply (induct p arbitrary: n, simp)
214.29 + apply (simp add: pderiv_pCons coeff_pCons algebra_simps split: nat.split)
214.30 + done
214.31 +
214.32 +lemma pderiv_eq_0_iff: "pderiv p = 0 \<longleftrightarrow> degree p = 0"
214.33 + apply (rule iffI)
214.34 + apply (cases p, simp)
214.35 + apply (simp add: expand_poly_eq coeff_pderiv del: of_nat_Suc)
214.36 + apply (simp add: expand_poly_eq coeff_pderiv coeff_eq_0)
214.37 + done
214.38 +
214.39 +lemma degree_pderiv: "degree (pderiv p) = degree p - 1"
214.40 + apply (rule order_antisym [OF degree_le])
214.41 + apply (simp add: coeff_pderiv coeff_eq_0)
214.42 + apply (cases "degree p", simp)
214.43 + apply (rule le_degree)
214.44 + apply (simp add: coeff_pderiv del: of_nat_Suc)
214.45 + apply (rule subst, assumption)
214.46 + apply (rule leading_coeff_neq_0, clarsimp)
214.47 + done
214.48 +
214.49 +lemma pderiv_singleton [simp]: "pderiv [:a:] = 0"
214.50 +by (simp add: pderiv_pCons)
214.51 +
214.52 +lemma pderiv_add: "pderiv (p + q) = pderiv p + pderiv q"
214.53 +by (rule poly_ext, simp add: coeff_pderiv algebra_simps)
214.54 +
214.55 +lemma pderiv_minus: "pderiv (- p) = - pderiv p"
214.56 +by (rule poly_ext, simp add: coeff_pderiv)
214.57 +
214.58 +lemma pderiv_diff: "pderiv (p - q) = pderiv p - pderiv q"
214.59 +by (rule poly_ext, simp add: coeff_pderiv algebra_simps)
214.60 +
214.61 +lemma pderiv_smult: "pderiv (smult a p) = smult a (pderiv p)"
214.62 +by (rule poly_ext, simp add: coeff_pderiv algebra_simps)
214.63 +
214.64 +lemma pderiv_mult: "pderiv (p * q) = p * pderiv q + q * pderiv p"
214.65 +apply (induct p)
214.66 +apply simp
214.67 +apply (simp add: pderiv_add pderiv_smult pderiv_pCons algebra_simps)
214.68 +done
214.69 +
214.70 +lemma pderiv_power_Suc:
214.71 + "pderiv (p ^ Suc n) = smult (of_nat (Suc n)) (p ^ n) * pderiv p"
214.72 +apply (induct n)
214.73 +apply simp
214.74 +apply (subst power_Suc)
214.75 +apply (subst pderiv_mult)
214.76 +apply (erule ssubst)
214.77 +apply (simp add: smult_add_left algebra_simps)
214.78 +done
214.79 +
214.80 +lemma DERIV_cmult2: "DERIV f x :> D ==> DERIV (%x. (f x) * c :: real) x :> D * c"
214.81 +by (simp add: DERIV_cmult mult_commute [of _ c])
214.82 +
214.83 +lemma DERIV_pow2: "DERIV (%x. x ^ Suc n) x :> real (Suc n) * (x ^ n)"
214.84 +by (rule lemma_DERIV_subst, rule DERIV_pow, simp)
214.85 +declare DERIV_pow2 [simp] DERIV_pow [simp]
214.86 +
214.87 +lemma DERIV_add_const: "DERIV f x :> D ==> DERIV (%x. a + f x :: 'a::real_normed_field) x :> D"
214.88 +by (rule lemma_DERIV_subst, rule DERIV_add, auto)
214.89 +
214.90 +lemma poly_DERIV[simp]: "DERIV (%x. poly p x) x :> poly (pderiv p) x"
214.91 +apply (induct p)
214.92 +apply simp
214.93 +apply (simp add: pderiv_pCons)
214.94 +apply (rule lemma_DERIV_subst)
214.95 +apply (rule DERIV_add DERIV_mult DERIV_const DERIV_ident | assumption)+
214.96 +apply simp
214.97 +done
214.98 +
214.99 +text{* Consequences of the derivative theorem above*}
214.100 +
214.101 +lemma poly_differentiable[simp]: "(%x. poly p x) differentiable (x::real)"
214.102 +apply (simp add: differentiable_def)
214.103 +apply (blast intro: poly_DERIV)
214.104 +done
214.105 +
214.106 +lemma poly_isCont[simp]: "isCont (%x. poly p x) (x::real)"
214.107 +by (rule poly_DERIV [THEN DERIV_isCont])
214.108 +
214.109 +lemma poly_IVT_pos: "[| a < b; poly p (a::real) < 0; 0 < poly p b |]
214.110 + ==> \<exists>x. a < x & x < b & (poly p x = 0)"
214.111 +apply (cut_tac f = "%x. poly p x" and a = a and b = b and y = 0 in IVT_objl)
214.112 +apply (auto simp add: order_le_less)
214.113 +done
214.114 +
214.115 +lemma poly_IVT_neg: "[| (a::real) < b; 0 < poly p a; poly p b < 0 |]
214.116 + ==> \<exists>x. a < x & x < b & (poly p x = 0)"
214.117 +by (insert poly_IVT_pos [where p = "- p" ]) simp
214.118 +
214.119 +lemma poly_MVT: "(a::real) < b ==>
214.120 + \<exists>x. a < x & x < b & (poly p b - poly p a = (b - a) * poly (pderiv p) x)"
214.121 +apply (drule_tac f = "poly p" in MVT, auto)
214.122 +apply (rule_tac x = z in exI)
214.123 +apply (auto simp add: real_mult_left_cancel poly_DERIV [THEN DERIV_unique])
214.124 +done
214.125 +
214.126 +text{*Lemmas for Derivatives*}
214.127 +
214.128 +lemma order_unique_lemma:
214.129 + fixes p :: "'a::idom poly"
214.130 + assumes "[:-a, 1:] ^ n dvd p \<and> \<not> [:-a, 1:] ^ Suc n dvd p"
214.131 + shows "n = order a p"
214.132 +unfolding Polynomial.order_def
214.133 +apply (rule Least_equality [symmetric])
214.134 +apply (rule assms [THEN conjunct2])
214.135 +apply (erule contrapos_np)
214.136 +apply (rule power_le_dvd)
214.137 +apply (rule assms [THEN conjunct1])
214.138 +apply simp
214.139 +done
214.140 +
214.141 +lemma lemma_order_pderiv1:
214.142 + "pderiv ([:- a, 1:] ^ Suc n * q) = [:- a, 1:] ^ Suc n * pderiv q +
214.143 + smult (of_nat (Suc n)) (q * [:- a, 1:] ^ n)"
214.144 +apply (simp only: pderiv_mult pderiv_power_Suc)
214.145 +apply (simp del: power_poly_Suc of_nat_Suc add: pderiv_pCons)
214.146 +done
214.147 +
214.148 +lemma dvd_add_cancel1:
214.149 + fixes a b c :: "'a::comm_ring_1"
214.150 + shows "a dvd b + c \<Longrightarrow> a dvd b \<Longrightarrow> a dvd c"
214.151 + by (drule (1) Ring_and_Field.dvd_diff, simp)
214.152 +
214.153 +lemma lemma_order_pderiv [rule_format]:
214.154 + "\<forall>p q a. 0 < n &
214.155 + pderiv p \<noteq> 0 &
214.156 + p = [:- a, 1:] ^ n * q & ~ [:- a, 1:] dvd q
214.157 + --> n = Suc (order a (pderiv p))"
214.158 + apply (cases "n", safe, rename_tac n p q a)
214.159 + apply (rule order_unique_lemma)
214.160 + apply (rule conjI)
214.161 + apply (subst lemma_order_pderiv1)
214.162 + apply (rule dvd_add)
214.163 + apply (rule dvd_mult2)
214.164 + apply (rule le_imp_power_dvd, simp)
214.165 + apply (rule dvd_smult)
214.166 + apply (rule dvd_mult)
214.167 + apply (rule dvd_refl)
214.168 + apply (subst lemma_order_pderiv1)
214.169 + apply (erule contrapos_nn) back
214.170 + apply (subgoal_tac "[:- a, 1:] ^ Suc n dvd q * [:- a, 1:] ^ n")
214.171 + apply (simp del: mult_pCons_left)
214.172 + apply (drule dvd_add_cancel1)
214.173 + apply (simp del: mult_pCons_left)
214.174 + apply (drule dvd_smult_cancel, simp del: of_nat_Suc)
214.175 + apply assumption
214.176 +done
214.177 +
214.178 +lemma order_decomp:
214.179 + "p \<noteq> 0
214.180 + ==> \<exists>q. p = [:-a, 1:] ^ (order a p) * q &
214.181 + ~([:-a, 1:] dvd q)"
214.182 +apply (drule order [where a=a])
214.183 +apply (erule conjE)
214.184 +apply (erule dvdE)
214.185 +apply (rule exI)
214.186 +apply (rule conjI, assumption)
214.187 +apply (erule contrapos_nn)
214.188 +apply (erule ssubst) back
214.189 +apply (subst power_Suc2)
214.190 +apply (erule mult_dvd_mono [OF dvd_refl])
214.191 +done
214.192 +
214.193 +lemma order_pderiv: "[| pderiv p \<noteq> 0; order a p \<noteq> 0 |]
214.194 + ==> (order a p = Suc (order a (pderiv p)))"
214.195 +apply (case_tac "p = 0", simp)
214.196 +apply (drule_tac a = a and p = p in order_decomp)
214.197 +using neq0_conv
214.198 +apply (blast intro: lemma_order_pderiv)
214.199 +done
214.200 +
214.201 +lemma order_mult: "p * q \<noteq> 0 \<Longrightarrow> order a (p * q) = order a p + order a q"
214.202 +proof -
214.203 + def i \<equiv> "order a p"
214.204 + def j \<equiv> "order a q"
214.205 + def t \<equiv> "[:-a, 1:]"
214.206 + have t_dvd_iff: "\<And>u. t dvd u \<longleftrightarrow> poly u a = 0"
214.207 + unfolding t_def by (simp add: dvd_iff_poly_eq_0)
214.208 + assume "p * q \<noteq> 0"
214.209 + then show "order a (p * q) = i + j"
214.210 + apply clarsimp
214.211 + apply (drule order [where a=a and p=p, folded i_def t_def])
214.212 + apply (drule order [where a=a and p=q, folded j_def t_def])
214.213 + apply clarify
214.214 + apply (rule order_unique_lemma [symmetric], fold t_def)
214.215 + apply (erule dvdE)+
214.216 + apply (simp add: power_add t_dvd_iff)
214.217 + done
214.218 +qed
214.219 +
214.220 +text{*Now justify the standard squarefree decomposition, i.e. f / gcd(f,f'). *}
214.221 +
214.222 +lemma order_divides: "[:-a, 1:] ^ n dvd p \<longleftrightarrow> p = 0 \<or> n \<le> order a p"
214.223 +apply (cases "p = 0", auto)
214.224 +apply (drule order_2 [where a=a and p=p])
214.225 +apply (erule contrapos_np)
214.226 +apply (erule power_le_dvd)
214.227 +apply simp
214.228 +apply (erule power_le_dvd [OF order_1])
214.229 +done
214.230 +
214.231 +lemma poly_squarefree_decomp_order:
214.232 + assumes "pderiv p \<noteq> 0"
214.233 + and p: "p = q * d"
214.234 + and p': "pderiv p = e * d"
214.235 + and d: "d = r * p + s * pderiv p"
214.236 + shows "order a q = (if order a p = 0 then 0 else 1)"
214.237 +proof (rule classical)
214.238 + assume 1: "order a q \<noteq> (if order a p = 0 then 0 else 1)"
214.239 + from `pderiv p \<noteq> 0` have "p \<noteq> 0" by auto
214.240 + with p have "order a p = order a q + order a d"
214.241 + by (simp add: order_mult)
214.242 + with 1 have "order a p \<noteq> 0" by (auto split: if_splits)
214.243 + have "order a (pderiv p) = order a e + order a d"
214.244 + using `pderiv p \<noteq> 0` `pderiv p = e * d` by (simp add: order_mult)
214.245 + have "order a p = Suc (order a (pderiv p))"
214.246 + using `pderiv p \<noteq> 0` `order a p \<noteq> 0` by (rule order_pderiv)
214.247 + have "d \<noteq> 0" using `p \<noteq> 0` `p = q * d` by simp
214.248 + have "([:-a, 1:] ^ (order a (pderiv p))) dvd d"
214.249 + apply (simp add: d)
214.250 + apply (rule dvd_add)
214.251 + apply (rule dvd_mult)
214.252 + apply (simp add: order_divides `p \<noteq> 0`
214.253 + `order a p = Suc (order a (pderiv p))`)
214.254 + apply (rule dvd_mult)
214.255 + apply (simp add: order_divides)
214.256 + done
214.257 + then have "order a (pderiv p) \<le> order a d"
214.258 + using `d \<noteq> 0` by (simp add: order_divides)
214.259 + show ?thesis
214.260 + using `order a p = order a q + order a d`
214.261 + using `order a (pderiv p) = order a e + order a d`
214.262 + using `order a p = Suc (order a (pderiv p))`
214.263 + using `order a (pderiv p) \<le> order a d`
214.264 + by auto
214.265 +qed
214.266 +
214.267 +lemma poly_squarefree_decomp_order2: "[| pderiv p \<noteq> 0;
214.268 + p = q * d;
214.269 + pderiv p = e * d;
214.270 + d = r * p + s * pderiv p
214.271 + |] ==> \<forall>a. order a q = (if order a p = 0 then 0 else 1)"
214.272 +apply (blast intro: poly_squarefree_decomp_order)
214.273 +done
214.274 +
214.275 +lemma order_pderiv2: "[| pderiv p \<noteq> 0; order a p \<noteq> 0 |]
214.276 + ==> (order a (pderiv p) = n) = (order a p = Suc n)"
214.277 +apply (auto dest: order_pderiv)
214.278 +done
214.279 +
214.280 +definition
214.281 + rsquarefree :: "'a::idom poly => bool" where
214.282 + "rsquarefree p = (p \<noteq> 0 & (\<forall>a. (order a p = 0) | (order a p = 1)))"
214.283 +
214.284 +lemma pderiv_iszero: "pderiv p = 0 \<Longrightarrow> \<exists>h. p = [:h:]"
214.285 +apply (simp add: pderiv_eq_0_iff)
214.286 +apply (case_tac p, auto split: if_splits)
214.287 +done
214.288 +
214.289 +lemma rsquarefree_roots:
214.290 + "rsquarefree p = (\<forall>a. ~(poly p a = 0 & poly (pderiv p) a = 0))"
214.291 +apply (simp add: rsquarefree_def)
214.292 +apply (case_tac "p = 0", simp, simp)
214.293 +apply (case_tac "pderiv p = 0")
214.294 +apply simp
214.295 +apply (drule pderiv_iszero, clarify)
214.296 +apply simp
214.297 +apply (rule allI)
214.298 +apply (cut_tac p = "[:h:]" and a = a in order_root)
214.299 +apply simp
214.300 +apply (auto simp add: order_root order_pderiv2)
214.301 +apply (erule_tac x="a" in allE, simp)
214.302 +done
214.303 +
214.304 +lemma poly_squarefree_decomp:
214.305 + assumes "pderiv p \<noteq> 0"
214.306 + and "p = q * d"
214.307 + and "pderiv p = e * d"
214.308 + and "d = r * p + s * pderiv p"
214.309 + shows "rsquarefree q & (\<forall>a. (poly q a = 0) = (poly p a = 0))"
214.310 +proof -
214.311 + from `pderiv p \<noteq> 0` have "p \<noteq> 0" by auto
214.312 + with `p = q * d` have "q \<noteq> 0" by simp
214.313 + have "\<forall>a. order a q = (if order a p = 0 then 0 else 1)"
214.314 + using assms by (rule poly_squarefree_decomp_order2)
214.315 + with `p \<noteq> 0` `q \<noteq> 0` show ?thesis
214.316 + by (simp add: rsquarefree_def order_root)
214.317 +qed
214.318 +
214.319 +end
215.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
215.2 +++ b/src/HOL/Library/Polynomial.thy Wed Mar 04 11:05:29 2009 +0100
215.3 @@ -0,0 +1,1463 @@
215.4 +(* Title: HOL/Polynomial.thy
215.5 + Author: Brian Huffman
215.6 + Based on an earlier development by Clemens Ballarin
215.7 +*)
215.8 +
215.9 +header {* Univariate Polynomials *}
215.10 +
215.11 +theory Polynomial
215.12 +imports Plain SetInterval Main
215.13 +begin
215.14 +
215.15 +subsection {* Definition of type @{text poly} *}
215.16 +
215.17 +typedef (Poly) 'a poly = "{f::nat \<Rightarrow> 'a::zero. \<exists>n. \<forall>i>n. f i = 0}"
215.18 + morphisms coeff Abs_poly
215.19 + by auto
215.20 +
215.21 +lemma expand_poly_eq: "p = q \<longleftrightarrow> (\<forall>n. coeff p n = coeff q n)"
215.22 +by (simp add: coeff_inject [symmetric] expand_fun_eq)
215.23 +
215.24 +lemma poly_ext: "(\<And>n. coeff p n = coeff q n) \<Longrightarrow> p = q"
215.25 +by (simp add: expand_poly_eq)
215.26 +
215.27 +
215.28 +subsection {* Degree of a polynomial *}
215.29 +
215.30 +definition
215.31 + degree :: "'a::zero poly \<Rightarrow> nat" where
215.32 + "degree p = (LEAST n. \<forall>i>n. coeff p i = 0)"
215.33 +
215.34 +lemma coeff_eq_0: "degree p < n \<Longrightarrow> coeff p n = 0"
215.35 +proof -
215.36 + have "coeff p \<in> Poly"
215.37 + by (rule coeff)
215.38 + hence "\<exists>n. \<forall>i>n. coeff p i = 0"
215.39 + unfolding Poly_def by simp
215.40 + hence "\<forall>i>degree p. coeff p i = 0"
215.41 + unfolding degree_def by (rule LeastI_ex)
215.42 + moreover assume "degree p < n"
215.43 + ultimately show ?thesis by simp
215.44 +qed
215.45 +
215.46 +lemma le_degree: "coeff p n \<noteq> 0 \<Longrightarrow> n \<le> degree p"
215.47 + by (erule contrapos_np, rule coeff_eq_0, simp)
215.48 +
215.49 +lemma degree_le: "\<forall>i>n. coeff p i = 0 \<Longrightarrow> degree p \<le> n"
215.50 + unfolding degree_def by (erule Least_le)
215.51 +
215.52 +lemma less_degree_imp: "n < degree p \<Longrightarrow> \<exists>i>n. coeff p i \<noteq> 0"
215.53 + unfolding degree_def by (drule not_less_Least, simp)
215.54 +
215.55 +
215.56 +subsection {* The zero polynomial *}
215.57 +
215.58 +instantiation poly :: (zero) zero
215.59 +begin
215.60 +
215.61 +definition
215.62 + zero_poly_def: "0 = Abs_poly (\<lambda>n. 0)"
215.63 +
215.64 +instance ..
215.65 +end
215.66 +
215.67 +lemma coeff_0 [simp]: "coeff 0 n = 0"
215.68 + unfolding zero_poly_def
215.69 + by (simp add: Abs_poly_inverse Poly_def)
215.70 +
215.71 +lemma degree_0 [simp]: "degree 0 = 0"
215.72 + by (rule order_antisym [OF degree_le le0]) simp
215.73 +
215.74 +lemma leading_coeff_neq_0:
215.75 + assumes "p \<noteq> 0" shows "coeff p (degree p) \<noteq> 0"
215.76 +proof (cases "degree p")
215.77 + case 0
215.78 + from `p \<noteq> 0` have "\<exists>n. coeff p n \<noteq> 0"
215.79 + by (simp add: expand_poly_eq)
215.80 + then obtain n where "coeff p n \<noteq> 0" ..
215.81 + hence "n \<le> degree p" by (rule le_degree)
215.82 + with `coeff p n \<noteq> 0` and `degree p = 0`
215.83 + show "coeff p (degree p) \<noteq> 0" by simp
215.84 +next
215.85 + case (Suc n)
215.86 + from `degree p = Suc n` have "n < degree p" by simp
215.87 + hence "\<exists>i>n. coeff p i \<noteq> 0" by (rule less_degree_imp)
215.88 + then obtain i where "n < i" and "coeff p i \<noteq> 0" by fast
215.89 + from `degree p = Suc n` and `n < i` have "degree p \<le> i" by simp
215.90 + also from `coeff p i \<noteq> 0` have "i \<le> degree p" by (rule le_degree)
215.91 + finally have "degree p = i" .
215.92 + with `coeff p i \<noteq> 0` show "coeff p (degree p) \<noteq> 0" by simp
215.93 +qed
215.94 +
215.95 +lemma leading_coeff_0_iff [simp]: "coeff p (degree p) = 0 \<longleftrightarrow> p = 0"
215.96 + by (cases "p = 0", simp, simp add: leading_coeff_neq_0)
215.97 +
215.98 +
215.99 +subsection {* List-style constructor for polynomials *}
215.100 +
215.101 +definition
215.102 + pCons :: "'a::zero \<Rightarrow> 'a poly \<Rightarrow> 'a poly"
215.103 +where
215.104 + [code del]: "pCons a p = Abs_poly (nat_case a (coeff p))"
215.105 +
215.106 +syntax
215.107 + "_poly" :: "args \<Rightarrow> 'a poly" ("[:(_):]")
215.108 +
215.109 +translations
215.110 + "[:x, xs:]" == "CONST pCons x [:xs:]"
215.111 + "[:x:]" == "CONST pCons x 0"
215.112 + "[:x:]" <= "CONST pCons x (_constrain 0 t)"
215.113 +
215.114 +lemma Poly_nat_case: "f \<in> Poly \<Longrightarrow> nat_case a f \<in> Poly"
215.115 + unfolding Poly_def by (auto split: nat.split)
215.116 +
215.117 +lemma coeff_pCons:
215.118 + "coeff (pCons a p) = nat_case a (coeff p)"
215.119 + unfolding pCons_def
215.120 + by (simp add: Abs_poly_inverse Poly_nat_case coeff)
215.121 +
215.122 +lemma coeff_pCons_0 [simp]: "coeff (pCons a p) 0 = a"
215.123 + by (simp add: coeff_pCons)
215.124 +
215.125 +lemma coeff_pCons_Suc [simp]: "coeff (pCons a p) (Suc n) = coeff p n"
215.126 + by (simp add: coeff_pCons)
215.127 +
215.128 +lemma degree_pCons_le: "degree (pCons a p) \<le> Suc (degree p)"
215.129 +by (rule degree_le, simp add: coeff_eq_0 coeff_pCons split: nat.split)
215.130 +
215.131 +lemma degree_pCons_eq:
215.132 + "p \<noteq> 0 \<Longrightarrow> degree (pCons a p) = Suc (degree p)"
215.133 +apply (rule order_antisym [OF degree_pCons_le])
215.134 +apply (rule le_degree, simp)
215.135 +done
215.136 +
215.137 +lemma degree_pCons_0: "degree (pCons a 0) = 0"
215.138 +apply (rule order_antisym [OF _ le0])
215.139 +apply (rule degree_le, simp add: coeff_pCons split: nat.split)
215.140 +done
215.141 +
215.142 +lemma degree_pCons_eq_if [simp]:
215.143 + "degree (pCons a p) = (if p = 0 then 0 else Suc (degree p))"
215.144 +apply (cases "p = 0", simp_all)
215.145 +apply (rule order_antisym [OF _ le0])
215.146 +apply (rule degree_le, simp add: coeff_pCons split: nat.split)
215.147 +apply (rule order_antisym [OF degree_pCons_le])
215.148 +apply (rule le_degree, simp)
215.149 +done
215.150 +
215.151 +lemma pCons_0_0 [simp]: "pCons 0 0 = 0"
215.152 +by (rule poly_ext, simp add: coeff_pCons split: nat.split)
215.153 +
215.154 +lemma pCons_eq_iff [simp]:
215.155 + "pCons a p = pCons b q \<longleftrightarrow> a = b \<and> p = q"
215.156 +proof (safe)
215.157 + assume "pCons a p = pCons b q"
215.158 + then have "coeff (pCons a p) 0 = coeff (pCons b q) 0" by simp
215.159 + then show "a = b" by simp
215.160 +next
215.161 + assume "pCons a p = pCons b q"
215.162 + then have "\<forall>n. coeff (pCons a p) (Suc n) =
215.163 + coeff (pCons b q) (Suc n)" by simp
215.164 + then show "p = q" by (simp add: expand_poly_eq)
215.165 +qed
215.166 +
215.167 +lemma pCons_eq_0_iff [simp]: "pCons a p = 0 \<longleftrightarrow> a = 0 \<and> p = 0"
215.168 + using pCons_eq_iff [of a p 0 0] by simp
215.169 +
215.170 +lemma Poly_Suc: "f \<in> Poly \<Longrightarrow> (\<lambda>n. f (Suc n)) \<in> Poly"
215.171 + unfolding Poly_def
215.172 + by (clarify, rule_tac x=n in exI, simp)
215.173 +
215.174 +lemma pCons_cases [cases type: poly]:
215.175 + obtains (pCons) a q where "p = pCons a q"
215.176 +proof
215.177 + show "p = pCons (coeff p 0) (Abs_poly (\<lambda>n. coeff p (Suc n)))"
215.178 + by (rule poly_ext)
215.179 + (simp add: Abs_poly_inverse Poly_Suc coeff coeff_pCons
215.180 + split: nat.split)
215.181 +qed
215.182 +
215.183 +lemma pCons_induct [case_names 0 pCons, induct type: poly]:
215.184 + assumes zero: "P 0"
215.185 + assumes pCons: "\<And>a p. P p \<Longrightarrow> P (pCons a p)"
215.186 + shows "P p"
215.187 +proof (induct p rule: measure_induct_rule [where f=degree])
215.188 + case (less p)
215.189 + obtain a q where "p = pCons a q" by (rule pCons_cases)
215.190 + have "P q"
215.191 + proof (cases "q = 0")
215.192 + case True
215.193 + then show "P q" by (simp add: zero)
215.194 + next
215.195 + case False
215.196 + then have "degree (pCons a q) = Suc (degree q)"
215.197 + by (rule degree_pCons_eq)
215.198 + then have "degree q < degree p"
215.199 + using `p = pCons a q` by simp
215.200 + then show "P q"
215.201 + by (rule less.hyps)
215.202 + qed
215.203 + then have "P (pCons a q)"
215.204 + by (rule pCons)
215.205 + then show ?case
215.206 + using `p = pCons a q` by simp
215.207 +qed
215.208 +
215.209 +
215.210 +subsection {* Recursion combinator for polynomials *}
215.211 +
215.212 +function
215.213 + poly_rec :: "'b \<Rightarrow> ('a::zero \<Rightarrow> 'a poly \<Rightarrow> 'b \<Rightarrow> 'b) \<Rightarrow> 'a poly \<Rightarrow> 'b"
215.214 +where
215.215 + poly_rec_pCons_eq_if [simp del, code del]:
215.216 + "poly_rec z f (pCons a p) = f a p (if p = 0 then z else poly_rec z f p)"
215.217 +by (case_tac x, rename_tac q, case_tac q, auto)
215.218 +
215.219 +termination poly_rec
215.220 +by (relation "measure (degree \<circ> snd \<circ> snd)", simp)
215.221 + (simp add: degree_pCons_eq)
215.222 +
215.223 +lemma poly_rec_0:
215.224 + "f 0 0 z = z \<Longrightarrow> poly_rec z f 0 = z"
215.225 + using poly_rec_pCons_eq_if [of z f 0 0] by simp
215.226 +
215.227 +lemma poly_rec_pCons:
215.228 + "f 0 0 z = z \<Longrightarrow> poly_rec z f (pCons a p) = f a p (poly_rec z f p)"
215.229 + by (simp add: poly_rec_pCons_eq_if poly_rec_0)
215.230 +
215.231 +
215.232 +subsection {* Monomials *}
215.233 +
215.234 +definition
215.235 + monom :: "'a \<Rightarrow> nat \<Rightarrow> 'a::zero poly" where
215.236 + "monom a m = Abs_poly (\<lambda>n. if m = n then a else 0)"
215.237 +
215.238 +lemma coeff_monom [simp]: "coeff (monom a m) n = (if m=n then a else 0)"
215.239 + unfolding monom_def
215.240 + by (subst Abs_poly_inverse, auto simp add: Poly_def)
215.241 +
215.242 +lemma monom_0: "monom a 0 = pCons a 0"
215.243 + by (rule poly_ext, simp add: coeff_pCons split: nat.split)
215.244 +
215.245 +lemma monom_Suc: "monom a (Suc n) = pCons 0 (monom a n)"
215.246 + by (rule poly_ext, simp add: coeff_pCons split: nat.split)
215.247 +
215.248 +lemma monom_eq_0 [simp]: "monom 0 n = 0"
215.249 + by (rule poly_ext) simp
215.250 +
215.251 +lemma monom_eq_0_iff [simp]: "monom a n = 0 \<longleftrightarrow> a = 0"
215.252 + by (simp add: expand_poly_eq)
215.253 +
215.254 +lemma monom_eq_iff [simp]: "monom a n = monom b n \<longleftrightarrow> a = b"
215.255 + by (simp add: expand_poly_eq)
215.256 +
215.257 +lemma degree_monom_le: "degree (monom a n) \<le> n"
215.258 + by (rule degree_le, simp)
215.259 +
215.260 +lemma degree_monom_eq: "a \<noteq> 0 \<Longrightarrow> degree (monom a n) = n"
215.261 + apply (rule order_antisym [OF degree_monom_le])
215.262 + apply (rule le_degree, simp)
215.263 + done
215.264 +
215.265 +
215.266 +subsection {* Addition and subtraction *}
215.267 +
215.268 +instantiation poly :: (comm_monoid_add) comm_monoid_add
215.269 +begin
215.270 +
215.271 +definition
215.272 + plus_poly_def [code del]:
215.273 + "p + q = Abs_poly (\<lambda>n. coeff p n + coeff q n)"
215.274 +
215.275 +lemma Poly_add:
215.276 + fixes f g :: "nat \<Rightarrow> 'a"
215.277 + shows "\<lbrakk>f \<in> Poly; g \<in> Poly\<rbrakk> \<Longrightarrow> (\<lambda>n. f n + g n) \<in> Poly"
215.278 + unfolding Poly_def
215.279 + apply (clarify, rename_tac m n)
215.280 + apply (rule_tac x="max m n" in exI, simp)
215.281 + done
215.282 +
215.283 +lemma coeff_add [simp]:
215.284 + "coeff (p + q) n = coeff p n + coeff q n"
215.285 + unfolding plus_poly_def
215.286 + by (simp add: Abs_poly_inverse coeff Poly_add)
215.287 +
215.288 +instance proof
215.289 + fix p q r :: "'a poly"
215.290 + show "(p + q) + r = p + (q + r)"
215.291 + by (simp add: expand_poly_eq add_assoc)
215.292 + show "p + q = q + p"
215.293 + by (simp add: expand_poly_eq add_commute)
215.294 + show "0 + p = p"
215.295 + by (simp add: expand_poly_eq)
215.296 +qed
215.297 +
215.298 +end
215.299 +
215.300 +instance poly :: (cancel_comm_monoid_add) cancel_comm_monoid_add
215.301 +proof
215.302 + fix p q r :: "'a poly"
215.303 + assume "p + q = p + r" thus "q = r"
215.304 + by (simp add: expand_poly_eq)
215.305 +qed
215.306 +
215.307 +instantiation poly :: (ab_group_add) ab_group_add
215.308 +begin
215.309 +
215.310 +definition
215.311 + uminus_poly_def [code del]:
215.312 + "- p = Abs_poly (\<lambda>n. - coeff p n)"
215.313 +
215.314 +definition
215.315 + minus_poly_def [code del]:
215.316 + "p - q = Abs_poly (\<lambda>n. coeff p n - coeff q n)"
215.317 +
215.318 +lemma Poly_minus:
215.319 + fixes f :: "nat \<Rightarrow> 'a"
215.320 + shows "f \<in> Poly \<Longrightarrow> (\<lambda>n. - f n) \<in> Poly"
215.321 + unfolding Poly_def by simp
215.322 +
215.323 +lemma Poly_diff:
215.324 + fixes f g :: "nat \<Rightarrow> 'a"
215.325 + shows "\<lbrakk>f \<in> Poly; g \<in> Poly\<rbrakk> \<Longrightarrow> (\<lambda>n. f n - g n) \<in> Poly"
215.326 + unfolding diff_minus by (simp add: Poly_add Poly_minus)
215.327 +
215.328 +lemma coeff_minus [simp]: "coeff (- p) n = - coeff p n"
215.329 + unfolding uminus_poly_def
215.330 + by (simp add: Abs_poly_inverse coeff Poly_minus)
215.331 +
215.332 +lemma coeff_diff [simp]:
215.333 + "coeff (p - q) n = coeff p n - coeff q n"
215.334 + unfolding minus_poly_def
215.335 + by (simp add: Abs_poly_inverse coeff Poly_diff)
215.336 +
215.337 +instance proof
215.338 + fix p q :: "'a poly"
215.339 + show "- p + p = 0"
215.340 + by (simp add: expand_poly_eq)
215.341 + show "p - q = p + - q"
215.342 + by (simp add: expand_poly_eq diff_minus)
215.343 +qed
215.344 +
215.345 +end
215.346 +
215.347 +lemma add_pCons [simp]:
215.348 + "pCons a p + pCons b q = pCons (a + b) (p + q)"
215.349 + by (rule poly_ext, simp add: coeff_pCons split: nat.split)
215.350 +
215.351 +lemma minus_pCons [simp]:
215.352 + "- pCons a p = pCons (- a) (- p)"
215.353 + by (rule poly_ext, simp add: coeff_pCons split: nat.split)
215.354 +
215.355 +lemma diff_pCons [simp]:
215.356 + "pCons a p - pCons b q = pCons (a - b) (p - q)"
215.357 + by (rule poly_ext, simp add: coeff_pCons split: nat.split)
215.358 +
215.359 +lemma degree_add_le_max: "degree (p + q) \<le> max (degree p) (degree q)"
215.360 + by (rule degree_le, auto simp add: coeff_eq_0)
215.361 +
215.362 +lemma degree_add_le:
215.363 + "\<lbrakk>degree p \<le> n; degree q \<le> n\<rbrakk> \<Longrightarrow> degree (p + q) \<le> n"
215.364 + by (auto intro: order_trans degree_add_le_max)
215.365 +
215.366 +lemma degree_add_less:
215.367 + "\<lbrakk>degree p < n; degree q < n\<rbrakk> \<Longrightarrow> degree (p + q) < n"
215.368 + by (auto intro: le_less_trans degree_add_le_max)
215.369 +
215.370 +lemma degree_add_eq_right:
215.371 + "degree p < degree q \<Longrightarrow> degree (p + q) = degree q"
215.372 + apply (cases "q = 0", simp)
215.373 + apply (rule order_antisym)
215.374 + apply (simp add: degree_add_le)
215.375 + apply (rule le_degree)
215.376 + apply (simp add: coeff_eq_0)
215.377 + done
215.378 +
215.379 +lemma degree_add_eq_left:
215.380 + "degree q < degree p \<Longrightarrow> degree (p + q) = degree p"
215.381 + using degree_add_eq_right [of q p]
215.382 + by (simp add: add_commute)
215.383 +
215.384 +lemma degree_minus [simp]: "degree (- p) = degree p"
215.385 + unfolding degree_def by simp
215.386 +
215.387 +lemma degree_diff_le_max: "degree (p - q) \<le> max (degree p) (degree q)"
215.388 + using degree_add_le [where p=p and q="-q"]
215.389 + by (simp add: diff_minus)
215.390 +
215.391 +lemma degree_diff_le:
215.392 + "\<lbrakk>degree p \<le> n; degree q \<le> n\<rbrakk> \<Longrightarrow> degree (p - q) \<le> n"
215.393 + by (simp add: diff_minus degree_add_le)
215.394 +
215.395 +lemma degree_diff_less:
215.396 + "\<lbrakk>degree p < n; degree q < n\<rbrakk> \<Longrightarrow> degree (p - q) < n"
215.397 + by (simp add: diff_minus degree_add_less)
215.398 +
215.399 +lemma add_monom: "monom a n + monom b n = monom (a + b) n"
215.400 + by (rule poly_ext) simp
215.401 +
215.402 +lemma diff_monom: "monom a n - monom b n = monom (a - b) n"
215.403 + by (rule poly_ext) simp
215.404 +
215.405 +lemma minus_monom: "- monom a n = monom (-a) n"
215.406 + by (rule poly_ext) simp
215.407 +
215.408 +lemma coeff_setsum: "coeff (\<Sum>x\<in>A. p x) i = (\<Sum>x\<in>A. coeff (p x) i)"
215.409 + by (cases "finite A", induct set: finite, simp_all)
215.410 +
215.411 +lemma monom_setsum: "monom (\<Sum>x\<in>A. a x) n = (\<Sum>x\<in>A. monom (a x) n)"
215.412 + by (rule poly_ext) (simp add: coeff_setsum)
215.413 +
215.414 +
215.415 +subsection {* Multiplication by a constant *}
215.416 +
215.417 +definition
215.418 + smult :: "'a::comm_semiring_0 \<Rightarrow> 'a poly \<Rightarrow> 'a poly" where
215.419 + "smult a p = Abs_poly (\<lambda>n. a * coeff p n)"
215.420 +
215.421 +lemma Poly_smult:
215.422 + fixes f :: "nat \<Rightarrow> 'a::comm_semiring_0"
215.423 + shows "f \<in> Poly \<Longrightarrow> (\<lambda>n. a * f n) \<in> Poly"
215.424 + unfolding Poly_def
215.425 + by (clarify, rule_tac x=n in exI, simp)
215.426 +
215.427 +lemma coeff_smult [simp]: "coeff (smult a p) n = a * coeff p n"
215.428 + unfolding smult_def
215.429 + by (simp add: Abs_poly_inverse Poly_smult coeff)
215.430 +
215.431 +lemma degree_smult_le: "degree (smult a p) \<le> degree p"
215.432 + by (rule degree_le, simp add: coeff_eq_0)
215.433 +
215.434 +lemma smult_smult [simp]: "smult a (smult b p) = smult (a * b) p"
215.435 + by (rule poly_ext, simp add: mult_assoc)
215.436 +
215.437 +lemma smult_0_right [simp]: "smult a 0 = 0"
215.438 + by (rule poly_ext, simp)
215.439 +
215.440 +lemma smult_0_left [simp]: "smult 0 p = 0"
215.441 + by (rule poly_ext, simp)
215.442 +
215.443 +lemma smult_1_left [simp]: "smult (1::'a::comm_semiring_1) p = p"
215.444 + by (rule poly_ext, simp)
215.445 +
215.446 +lemma smult_add_right:
215.447 + "smult a (p + q) = smult a p + smult a q"
215.448 + by (rule poly_ext, simp add: algebra_simps)
215.449 +
215.450 +lemma smult_add_left:
215.451 + "smult (a + b) p = smult a p + smult b p"
215.452 + by (rule poly_ext, simp add: algebra_simps)
215.453 +
215.454 +lemma smult_minus_right [simp]:
215.455 + "smult (a::'a::comm_ring) (- p) = - smult a p"
215.456 + by (rule poly_ext, simp)
215.457 +
215.458 +lemma smult_minus_left [simp]:
215.459 + "smult (- a::'a::comm_ring) p = - smult a p"
215.460 + by (rule poly_ext, simp)
215.461 +
215.462 +lemma smult_diff_right:
215.463 + "smult (a::'a::comm_ring) (p - q) = smult a p - smult a q"
215.464 + by (rule poly_ext, simp add: algebra_simps)
215.465 +
215.466 +lemma smult_diff_left:
215.467 + "smult (a - b::'a::comm_ring) p = smult a p - smult b p"
215.468 + by (rule poly_ext, simp add: algebra_simps)
215.469 +
215.470 +lemmas smult_distribs =
215.471 + smult_add_left smult_add_right
215.472 + smult_diff_left smult_diff_right
215.473 +
215.474 +lemma smult_pCons [simp]:
215.475 + "smult a (pCons b p) = pCons (a * b) (smult a p)"
215.476 + by (rule poly_ext, simp add: coeff_pCons split: nat.split)
215.477 +
215.478 +lemma smult_monom: "smult a (monom b n) = monom (a * b) n"
215.479 + by (induct n, simp add: monom_0, simp add: monom_Suc)
215.480 +
215.481 +lemma degree_smult_eq [simp]:
215.482 + fixes a :: "'a::idom"
215.483 + shows "degree (smult a p) = (if a = 0 then 0 else degree p)"
215.484 + by (cases "a = 0", simp, simp add: degree_def)
215.485 +
215.486 +lemma smult_eq_0_iff [simp]:
215.487 + fixes a :: "'a::idom"
215.488 + shows "smult a p = 0 \<longleftrightarrow> a = 0 \<or> p = 0"
215.489 + by (simp add: expand_poly_eq)
215.490 +
215.491 +
215.492 +subsection {* Multiplication of polynomials *}
215.493 +
215.494 +text {* TODO: move to SetInterval.thy *}
215.495 +lemma setsum_atMost_Suc_shift:
215.496 + fixes f :: "nat \<Rightarrow> 'a::comm_monoid_add"
215.497 + shows "(\<Sum>i\<le>Suc n. f i) = f 0 + (\<Sum>i\<le>n. f (Suc i))"
215.498 +proof (induct n)
215.499 + case 0 show ?case by simp
215.500 +next
215.501 + case (Suc n) note IH = this
215.502 + have "(\<Sum>i\<le>Suc (Suc n). f i) = (\<Sum>i\<le>Suc n. f i) + f (Suc (Suc n))"
215.503 + by (rule setsum_atMost_Suc)
215.504 + also have "(\<Sum>i\<le>Suc n. f i) = f 0 + (\<Sum>i\<le>n. f (Suc i))"
215.505 + by (rule IH)
215.506 + also have "f 0 + (\<Sum>i\<le>n. f (Suc i)) + f (Suc (Suc n)) =
215.507 + f 0 + ((\<Sum>i\<le>n. f (Suc i)) + f (Suc (Suc n)))"
215.508 + by (rule add_assoc)
215.509 + also have "(\<Sum>i\<le>n. f (Suc i)) + f (Suc (Suc n)) = (\<Sum>i\<le>Suc n. f (Suc i))"
215.510 + by (rule setsum_atMost_Suc [symmetric])
215.511 + finally show ?case .
215.512 +qed
215.513 +
215.514 +instantiation poly :: (comm_semiring_0) comm_semiring_0
215.515 +begin
215.516 +
215.517 +definition
215.518 + times_poly_def [code del]:
215.519 + "p * q = poly_rec 0 (\<lambda>a p pq. smult a q + pCons 0 pq) p"
215.520 +
215.521 +lemma mult_poly_0_left: "(0::'a poly) * q = 0"
215.522 + unfolding times_poly_def by (simp add: poly_rec_0)
215.523 +
215.524 +lemma mult_pCons_left [simp]:
215.525 + "pCons a p * q = smult a q + pCons 0 (p * q)"
215.526 + unfolding times_poly_def by (simp add: poly_rec_pCons)
215.527 +
215.528 +lemma mult_poly_0_right: "p * (0::'a poly) = 0"
215.529 + by (induct p, simp add: mult_poly_0_left, simp)
215.530 +
215.531 +lemma mult_pCons_right [simp]:
215.532 + "p * pCons a q = smult a p + pCons 0 (p * q)"
215.533 + by (induct p, simp add: mult_poly_0_left, simp add: algebra_simps)
215.534 +
215.535 +lemmas mult_poly_0 = mult_poly_0_left mult_poly_0_right
215.536 +
215.537 +lemma mult_smult_left [simp]: "smult a p * q = smult a (p * q)"
215.538 + by (induct p, simp add: mult_poly_0, simp add: smult_add_right)
215.539 +
215.540 +lemma mult_smult_right [simp]: "p * smult a q = smult a (p * q)"
215.541 + by (induct q, simp add: mult_poly_0, simp add: smult_add_right)
215.542 +
215.543 +lemma mult_poly_add_left:
215.544 + fixes p q r :: "'a poly"
215.545 + shows "(p + q) * r = p * r + q * r"
215.546 + by (induct r, simp add: mult_poly_0,
215.547 + simp add: smult_distribs algebra_simps)
215.548 +
215.549 +instance proof
215.550 + fix p q r :: "'a poly"
215.551 + show 0: "0 * p = 0"
215.552 + by (rule mult_poly_0_left)
215.553 + show "p * 0 = 0"
215.554 + by (rule mult_poly_0_right)
215.555 + show "(p + q) * r = p * r + q * r"
215.556 + by (rule mult_poly_add_left)
215.557 + show "(p * q) * r = p * (q * r)"
215.558 + by (induct p, simp add: mult_poly_0, simp add: mult_poly_add_left)
215.559 + show "p * q = q * p"
215.560 + by (induct p, simp add: mult_poly_0, simp)
215.561 +qed
215.562 +
215.563 +end
215.564 +
215.565 +instance poly :: (comm_semiring_0_cancel) comm_semiring_0_cancel ..
215.566 +
215.567 +lemma coeff_mult:
215.568 + "coeff (p * q) n = (\<Sum>i\<le>n. coeff p i * coeff q (n-i))"
215.569 +proof (induct p arbitrary: n)
215.570 + case 0 show ?case by simp
215.571 +next
215.572 + case (pCons a p n) thus ?case
215.573 + by (cases n, simp, simp add: setsum_atMost_Suc_shift
215.574 + del: setsum_atMost_Suc)
215.575 +qed
215.576 +
215.577 +lemma degree_mult_le: "degree (p * q) \<le> degree p + degree q"
215.578 +apply (rule degree_le)
215.579 +apply (induct p)
215.580 +apply simp
215.581 +apply (simp add: coeff_eq_0 coeff_pCons split: nat.split)
215.582 +done
215.583 +
215.584 +lemma mult_monom: "monom a m * monom b n = monom (a * b) (m + n)"
215.585 + by (induct m, simp add: monom_0 smult_monom, simp add: monom_Suc)
215.586 +
215.587 +
215.588 +subsection {* The unit polynomial and exponentiation *}
215.589 +
215.590 +instantiation poly :: (comm_semiring_1) comm_semiring_1
215.591 +begin
215.592 +
215.593 +definition
215.594 + one_poly_def:
215.595 + "1 = pCons 1 0"
215.596 +
215.597 +instance proof
215.598 + fix p :: "'a poly" show "1 * p = p"
215.599 + unfolding one_poly_def
215.600 + by simp
215.601 +next
215.602 + show "0 \<noteq> (1::'a poly)"
215.603 + unfolding one_poly_def by simp
215.604 +qed
215.605 +
215.606 +end
215.607 +
215.608 +instance poly :: (comm_semiring_1_cancel) comm_semiring_1_cancel ..
215.609 +
215.610 +lemma coeff_1 [simp]: "coeff 1 n = (if n = 0 then 1 else 0)"
215.611 + unfolding one_poly_def
215.612 + by (simp add: coeff_pCons split: nat.split)
215.613 +
215.614 +lemma degree_1 [simp]: "degree 1 = 0"
215.615 + unfolding one_poly_def
215.616 + by (rule degree_pCons_0)
215.617 +
215.618 +text {* Lemmas about divisibility *}
215.619 +
215.620 +lemma dvd_smult: "p dvd q \<Longrightarrow> p dvd smult a q"
215.621 +proof -
215.622 + assume "p dvd q"
215.623 + then obtain k where "q = p * k" ..
215.624 + then have "smult a q = p * smult a k" by simp
215.625 + then show "p dvd smult a q" ..
215.626 +qed
215.627 +
215.628 +lemma dvd_smult_cancel:
215.629 + fixes a :: "'a::field"
215.630 + shows "p dvd smult a q \<Longrightarrow> a \<noteq> 0 \<Longrightarrow> p dvd q"
215.631 + by (drule dvd_smult [where a="inverse a"]) simp
215.632 +
215.633 +lemma dvd_smult_iff:
215.634 + fixes a :: "'a::field"
215.635 + shows "a \<noteq> 0 \<Longrightarrow> p dvd smult a q \<longleftrightarrow> p dvd q"
215.636 + by (safe elim!: dvd_smult dvd_smult_cancel)
215.637 +
215.638 +instantiation poly :: (comm_semiring_1) recpower
215.639 +begin
215.640 +
215.641 +primrec power_poly where
215.642 + power_poly_0: "(p::'a poly) ^ 0 = 1"
215.643 +| power_poly_Suc: "(p::'a poly) ^ (Suc n) = p * p ^ n"
215.644 +
215.645 +instance
215.646 + by default simp_all
215.647 +
215.648 +end
215.649 +
215.650 +lemma degree_power_le: "degree (p ^ n) \<le> degree p * n"
215.651 +by (induct n, simp, auto intro: order_trans degree_mult_le)
215.652 +
215.653 +instance poly :: (comm_ring) comm_ring ..
215.654 +
215.655 +instance poly :: (comm_ring_1) comm_ring_1 ..
215.656 +
215.657 +instantiation poly :: (comm_ring_1) number_ring
215.658 +begin
215.659 +
215.660 +definition
215.661 + "number_of k = (of_int k :: 'a poly)"
215.662 +
215.663 +instance
215.664 + by default (rule number_of_poly_def)
215.665 +
215.666 +end
215.667 +
215.668 +
215.669 +subsection {* Polynomials form an integral domain *}
215.670 +
215.671 +lemma coeff_mult_degree_sum:
215.672 + "coeff (p * q) (degree p + degree q) =
215.673 + coeff p (degree p) * coeff q (degree q)"
215.674 + by (induct p, simp, simp add: coeff_eq_0)
215.675 +
215.676 +instance poly :: (idom) idom
215.677 +proof
215.678 + fix p q :: "'a poly"
215.679 + assume "p \<noteq> 0" and "q \<noteq> 0"
215.680 + have "coeff (p * q) (degree p + degree q) =
215.681 + coeff p (degree p) * coeff q (degree q)"
215.682 + by (rule coeff_mult_degree_sum)
215.683 + also have "coeff p (degree p) * coeff q (degree q) \<noteq> 0"
215.684 + using `p \<noteq> 0` and `q \<noteq> 0` by simp
215.685 + finally have "\<exists>n. coeff (p * q) n \<noteq> 0" ..
215.686 + thus "p * q \<noteq> 0" by (simp add: expand_poly_eq)
215.687 +qed
215.688 +
215.689 +lemma degree_mult_eq:
215.690 + fixes p q :: "'a::idom poly"
215.691 + shows "\<lbrakk>p \<noteq> 0; q \<noteq> 0\<rbrakk> \<Longrightarrow> degree (p * q) = degree p + degree q"
215.692 +apply (rule order_antisym [OF degree_mult_le le_degree])
215.693 +apply (simp add: coeff_mult_degree_sum)
215.694 +done
215.695 +
215.696 +lemma dvd_imp_degree_le:
215.697 + fixes p q :: "'a::idom poly"
215.698 + shows "\<lbrakk>p dvd q; q \<noteq> 0\<rbrakk> \<Longrightarrow> degree p \<le> degree q"
215.699 + by (erule dvdE, simp add: degree_mult_eq)
215.700 +
215.701 +
215.702 +subsection {* Polynomials form an ordered integral domain *}
215.703 +
215.704 +definition
215.705 + pos_poly :: "'a::ordered_idom poly \<Rightarrow> bool"
215.706 +where
215.707 + "pos_poly p \<longleftrightarrow> 0 < coeff p (degree p)"
215.708 +
215.709 +lemma pos_poly_pCons:
215.710 + "pos_poly (pCons a p) \<longleftrightarrow> pos_poly p \<or> (p = 0 \<and> 0 < a)"
215.711 + unfolding pos_poly_def by simp
215.712 +
215.713 +lemma not_pos_poly_0 [simp]: "\<not> pos_poly 0"
215.714 + unfolding pos_poly_def by simp
215.715 +
215.716 +lemma pos_poly_add: "\<lbrakk>pos_poly p; pos_poly q\<rbrakk> \<Longrightarrow> pos_poly (p + q)"
215.717 + apply (induct p arbitrary: q, simp)
215.718 + apply (case_tac q, force simp add: pos_poly_pCons add_pos_pos)
215.719 + done
215.720 +
215.721 +lemma pos_poly_mult: "\<lbrakk>pos_poly p; pos_poly q\<rbrakk> \<Longrightarrow> pos_poly (p * q)"
215.722 + unfolding pos_poly_def
215.723 + apply (subgoal_tac "p \<noteq> 0 \<and> q \<noteq> 0")
215.724 + apply (simp add: degree_mult_eq coeff_mult_degree_sum mult_pos_pos)
215.725 + apply auto
215.726 + done
215.727 +
215.728 +lemma pos_poly_total: "p = 0 \<or> pos_poly p \<or> pos_poly (- p)"
215.729 +by (induct p) (auto simp add: pos_poly_pCons)
215.730 +
215.731 +instantiation poly :: (ordered_idom) ordered_idom
215.732 +begin
215.733 +
215.734 +definition
215.735 + [code del]:
215.736 + "x < y \<longleftrightarrow> pos_poly (y - x)"
215.737 +
215.738 +definition
215.739 + [code del]:
215.740 + "x \<le> y \<longleftrightarrow> x = y \<or> pos_poly (y - x)"
215.741 +
215.742 +definition
215.743 + [code del]:
215.744 + "abs (x::'a poly) = (if x < 0 then - x else x)"
215.745 +
215.746 +definition
215.747 + [code del]:
215.748 + "sgn (x::'a poly) = (if x = 0 then 0 else if 0 < x then 1 else - 1)"
215.749 +
215.750 +instance proof
215.751 + fix x y :: "'a poly"
215.752 + show "x < y \<longleftrightarrow> x \<le> y \<and> \<not> y \<le> x"
215.753 + unfolding less_eq_poly_def less_poly_def
215.754 + apply safe
215.755 + apply simp
215.756 + apply (drule (1) pos_poly_add)
215.757 + apply simp
215.758 + done
215.759 +next
215.760 + fix x :: "'a poly" show "x \<le> x"
215.761 + unfolding less_eq_poly_def by simp
215.762 +next
215.763 + fix x y z :: "'a poly"
215.764 + assume "x \<le> y" and "y \<le> z" thus "x \<le> z"
215.765 + unfolding less_eq_poly_def
215.766 + apply safe
215.767 + apply (drule (1) pos_poly_add)
215.768 + apply (simp add: algebra_simps)
215.769 + done
215.770 +next
215.771 + fix x y :: "'a poly"
215.772 + assume "x \<le> y" and "y \<le> x" thus "x = y"
215.773 + unfolding less_eq_poly_def
215.774 + apply safe
215.775 + apply (drule (1) pos_poly_add)
215.776 + apply simp
215.777 + done
215.778 +next
215.779 + fix x y z :: "'a poly"
215.780 + assume "x \<le> y" thus "z + x \<le> z + y"
215.781 + unfolding less_eq_poly_def
215.782 + apply safe
215.783 + apply (simp add: algebra_simps)
215.784 + done
215.785 +next
215.786 + fix x y :: "'a poly"
215.787 + show "x \<le> y \<or> y \<le> x"
215.788 + unfolding less_eq_poly_def
215.789 + using pos_poly_total [of "x - y"]
215.790 + by auto
215.791 +next
215.792 + fix x y z :: "'a poly"
215.793 + assume "x < y" and "0 < z"
215.794 + thus "z * x < z * y"
215.795 + unfolding less_poly_def
215.796 + by (simp add: right_diff_distrib [symmetric] pos_poly_mult)
215.797 +next
215.798 + fix x :: "'a poly"
215.799 + show "\<bar>x\<bar> = (if x < 0 then - x else x)"
215.800 + by (rule abs_poly_def)
215.801 +next
215.802 + fix x :: "'a poly"
215.803 + show "sgn x = (if x = 0 then 0 else if 0 < x then 1 else - 1)"
215.804 + by (rule sgn_poly_def)
215.805 +qed
215.806 +
215.807 +end
215.808 +
215.809 +text {* TODO: Simplification rules for comparisons *}
215.810 +
215.811 +
215.812 +subsection {* Long division of polynomials *}
215.813 +
215.814 +definition
215.815 + pdivmod_rel :: "'a::field poly \<Rightarrow> 'a poly \<Rightarrow> 'a poly \<Rightarrow> 'a poly \<Rightarrow> bool"
215.816 +where
215.817 + [code del]:
215.818 + "pdivmod_rel x y q r \<longleftrightarrow>
215.819 + x = q * y + r \<and> (if y = 0 then q = 0 else r = 0 \<or> degree r < degree y)"
215.820 +
215.821 +lemma pdivmod_rel_0:
215.822 + "pdivmod_rel 0 y 0 0"
215.823 + unfolding pdivmod_rel_def by simp
215.824 +
215.825 +lemma pdivmod_rel_by_0:
215.826 + "pdivmod_rel x 0 0 x"
215.827 + unfolding pdivmod_rel_def by simp
215.828 +
215.829 +lemma eq_zero_or_degree_less:
215.830 + assumes "degree p \<le> n" and "coeff p n = 0"
215.831 + shows "p = 0 \<or> degree p < n"
215.832 +proof (cases n)
215.833 + case 0
215.834 + with `degree p \<le> n` and `coeff p n = 0`
215.835 + have "coeff p (degree p) = 0" by simp
215.836 + then have "p = 0" by simp
215.837 + then show ?thesis ..
215.838 +next
215.839 + case (Suc m)
215.840 + have "\<forall>i>n. coeff p i = 0"
215.841 + using `degree p \<le> n` by (simp add: coeff_eq_0)
215.842 + then have "\<forall>i\<ge>n. coeff p i = 0"
215.843 + using `coeff p n = 0` by (simp add: le_less)
215.844 + then have "\<forall>i>m. coeff p i = 0"
215.845 + using `n = Suc m` by (simp add: less_eq_Suc_le)
215.846 + then have "degree p \<le> m"
215.847 + by (rule degree_le)
215.848 + then have "degree p < n"
215.849 + using `n = Suc m` by (simp add: less_Suc_eq_le)
215.850 + then show ?thesis ..
215.851 +qed
215.852 +
215.853 +lemma pdivmod_rel_pCons:
215.854 + assumes rel: "pdivmod_rel x y q r"
215.855 + assumes y: "y \<noteq> 0"
215.856 + assumes b: "b = coeff (pCons a r) (degree y) / coeff y (degree y)"
215.857 + shows "pdivmod_rel (pCons a x) y (pCons b q) (pCons a r - smult b y)"
215.858 + (is "pdivmod_rel ?x y ?q ?r")
215.859 +proof -
215.860 + have x: "x = q * y + r" and r: "r = 0 \<or> degree r < degree y"
215.861 + using assms unfolding pdivmod_rel_def by simp_all
215.862 +
215.863 + have 1: "?x = ?q * y + ?r"
215.864 + using b x by simp
215.865 +
215.866 + have 2: "?r = 0 \<or> degree ?r < degree y"
215.867 + proof (rule eq_zero_or_degree_less)
215.868 + show "degree ?r \<le> degree y"
215.869 + proof (rule degree_diff_le)
215.870 + show "degree (pCons a r) \<le> degree y"
215.871 + using r by auto
215.872 + show "degree (smult b y) \<le> degree y"
215.873 + by (rule degree_smult_le)
215.874 + qed
215.875 + next
215.876 + show "coeff ?r (degree y) = 0"
215.877 + using `y \<noteq> 0` unfolding b by simp
215.878 + qed
215.879 +
215.880 + from 1 2 show ?thesis
215.881 + unfolding pdivmod_rel_def
215.882 + using `y \<noteq> 0` by simp
215.883 +qed
215.884 +
215.885 +lemma pdivmod_rel_exists: "\<exists>q r. pdivmod_rel x y q r"
215.886 +apply (cases "y = 0")
215.887 +apply (fast intro!: pdivmod_rel_by_0)
215.888 +apply (induct x)
215.889 +apply (fast intro!: pdivmod_rel_0)
215.890 +apply (fast intro!: pdivmod_rel_pCons)
215.891 +done
215.892 +
215.893 +lemma pdivmod_rel_unique:
215.894 + assumes 1: "pdivmod_rel x y q1 r1"
215.895 + assumes 2: "pdivmod_rel x y q2 r2"
215.896 + shows "q1 = q2 \<and> r1 = r2"
215.897 +proof (cases "y = 0")
215.898 + assume "y = 0" with assms show ?thesis
215.899 + by (simp add: pdivmod_rel_def)
215.900 +next
215.901 + assume [simp]: "y \<noteq> 0"
215.902 + from 1 have q1: "x = q1 * y + r1" and r1: "r1 = 0 \<or> degree r1 < degree y"
215.903 + unfolding pdivmod_rel_def by simp_all
215.904 + from 2 have q2: "x = q2 * y + r2" and r2: "r2 = 0 \<or> degree r2 < degree y"
215.905 + unfolding pdivmod_rel_def by simp_all
215.906 + from q1 q2 have q3: "(q1 - q2) * y = r2 - r1"
215.907 + by (simp add: algebra_simps)
215.908 + from r1 r2 have r3: "(r2 - r1) = 0 \<or> degree (r2 - r1) < degree y"
215.909 + by (auto intro: degree_diff_less)
215.910 +
215.911 + show "q1 = q2 \<and> r1 = r2"
215.912 + proof (rule ccontr)
215.913 + assume "\<not> (q1 = q2 \<and> r1 = r2)"
215.914 + with q3 have "q1 \<noteq> q2" and "r1 \<noteq> r2" by auto
215.915 + with r3 have "degree (r2 - r1) < degree y" by simp
215.916 + also have "degree y \<le> degree (q1 - q2) + degree y" by simp
215.917 + also have "\<dots> = degree ((q1 - q2) * y)"
215.918 + using `q1 \<noteq> q2` by (simp add: degree_mult_eq)
215.919 + also have "\<dots> = degree (r2 - r1)"
215.920 + using q3 by simp
215.921 + finally have "degree (r2 - r1) < degree (r2 - r1)" .
215.922 + then show "False" by simp
215.923 + qed
215.924 +qed
215.925 +
215.926 +lemma pdivmod_rel_0_iff: "pdivmod_rel 0 y q r \<longleftrightarrow> q = 0 \<and> r = 0"
215.927 +by (auto dest: pdivmod_rel_unique intro: pdivmod_rel_0)
215.928 +
215.929 +lemma pdivmod_rel_by_0_iff: "pdivmod_rel x 0 q r \<longleftrightarrow> q = 0 \<and> r = x"
215.930 +by (auto dest: pdivmod_rel_unique intro: pdivmod_rel_by_0)
215.931 +
215.932 +lemmas pdivmod_rel_unique_div =
215.933 + pdivmod_rel_unique [THEN conjunct1, standard]
215.934 +
215.935 +lemmas pdivmod_rel_unique_mod =
215.936 + pdivmod_rel_unique [THEN conjunct2, standard]
215.937 +
215.938 +instantiation poly :: (field) ring_div
215.939 +begin
215.940 +
215.941 +definition div_poly where
215.942 + [code del]: "x div y = (THE q. \<exists>r. pdivmod_rel x y q r)"
215.943 +
215.944 +definition mod_poly where
215.945 + [code del]: "x mod y = (THE r. \<exists>q. pdivmod_rel x y q r)"
215.946 +
215.947 +lemma div_poly_eq:
215.948 + "pdivmod_rel x y q r \<Longrightarrow> x div y = q"
215.949 +unfolding div_poly_def
215.950 +by (fast elim: pdivmod_rel_unique_div)
215.951 +
215.952 +lemma mod_poly_eq:
215.953 + "pdivmod_rel x y q r \<Longrightarrow> x mod y = r"
215.954 +unfolding mod_poly_def
215.955 +by (fast elim: pdivmod_rel_unique_mod)
215.956 +
215.957 +lemma pdivmod_rel:
215.958 + "pdivmod_rel x y (x div y) (x mod y)"
215.959 +proof -
215.960 + from pdivmod_rel_exists
215.961 + obtain q r where "pdivmod_rel x y q r" by fast
215.962 + thus ?thesis
215.963 + by (simp add: div_poly_eq mod_poly_eq)
215.964 +qed
215.965 +
215.966 +instance proof
215.967 + fix x y :: "'a poly"
215.968 + show "x div y * y + x mod y = x"
215.969 + using pdivmod_rel [of x y]
215.970 + by (simp add: pdivmod_rel_def)
215.971 +next
215.972 + fix x :: "'a poly"
215.973 + have "pdivmod_rel x 0 0 x"
215.974 + by (rule pdivmod_rel_by_0)
215.975 + thus "x div 0 = 0"
215.976 + by (rule div_poly_eq)
215.977 +next
215.978 + fix y :: "'a poly"
215.979 + have "pdivmod_rel 0 y 0 0"
215.980 + by (rule pdivmod_rel_0)
215.981 + thus "0 div y = 0"
215.982 + by (rule div_poly_eq)
215.983 +next
215.984 + fix x y z :: "'a poly"
215.985 + assume "y \<noteq> 0"
215.986 + hence "pdivmod_rel (x + z * y) y (z + x div y) (x mod y)"
215.987 + using pdivmod_rel [of x y]
215.988 + by (simp add: pdivmod_rel_def left_distrib)
215.989 + thus "(x + z * y) div y = z + x div y"
215.990 + by (rule div_poly_eq)
215.991 +qed
215.992 +
215.993 +end
215.994 +
215.995 +lemma degree_mod_less:
215.996 + "y \<noteq> 0 \<Longrightarrow> x mod y = 0 \<or> degree (x mod y) < degree y"
215.997 + using pdivmod_rel [of x y]
215.998 + unfolding pdivmod_rel_def by simp
215.999 +
215.1000 +lemma div_poly_less: "degree x < degree y \<Longrightarrow> x div y = 0"
215.1001 +proof -
215.1002 + assume "degree x < degree y"
215.1003 + hence "pdivmod_rel x y 0 x"
215.1004 + by (simp add: pdivmod_rel_def)
215.1005 + thus "x div y = 0" by (rule div_poly_eq)
215.1006 +qed
215.1007 +
215.1008 +lemma mod_poly_less: "degree x < degree y \<Longrightarrow> x mod y = x"
215.1009 +proof -
215.1010 + assume "degree x < degree y"
215.1011 + hence "pdivmod_rel x y 0 x"
215.1012 + by (simp add: pdivmod_rel_def)
215.1013 + thus "x mod y = x" by (rule mod_poly_eq)
215.1014 +qed
215.1015 +
215.1016 +lemma pdivmod_rel_smult_left:
215.1017 + "pdivmod_rel x y q r
215.1018 + \<Longrightarrow> pdivmod_rel (smult a x) y (smult a q) (smult a r)"
215.1019 + unfolding pdivmod_rel_def by (simp add: smult_add_right)
215.1020 +
215.1021 +lemma div_smult_left: "(smult a x) div y = smult a (x div y)"
215.1022 + by (rule div_poly_eq, rule pdivmod_rel_smult_left, rule pdivmod_rel)
215.1023 +
215.1024 +lemma mod_smult_left: "(smult a x) mod y = smult a (x mod y)"
215.1025 + by (rule mod_poly_eq, rule pdivmod_rel_smult_left, rule pdivmod_rel)
215.1026 +
215.1027 +lemma poly_div_minus_left [simp]:
215.1028 + fixes x y :: "'a::field poly"
215.1029 + shows "(- x) div y = - (x div y)"
215.1030 + using div_smult_left [of "- 1::'a"] by simp
215.1031 +
215.1032 +lemma poly_mod_minus_left [simp]:
215.1033 + fixes x y :: "'a::field poly"
215.1034 + shows "(- x) mod y = - (x mod y)"
215.1035 + using mod_smult_left [of "- 1::'a"] by simp
215.1036 +
215.1037 +lemma pdivmod_rel_smult_right:
215.1038 + "\<lbrakk>a \<noteq> 0; pdivmod_rel x y q r\<rbrakk>
215.1039 + \<Longrightarrow> pdivmod_rel x (smult a y) (smult (inverse a) q) r"
215.1040 + unfolding pdivmod_rel_def by simp
215.1041 +
215.1042 +lemma div_smult_right:
215.1043 + "a \<noteq> 0 \<Longrightarrow> x div (smult a y) = smult (inverse a) (x div y)"
215.1044 + by (rule div_poly_eq, erule pdivmod_rel_smult_right, rule pdivmod_rel)
215.1045 +
215.1046 +lemma mod_smult_right: "a \<noteq> 0 \<Longrightarrow> x mod (smult a y) = x mod y"
215.1047 + by (rule mod_poly_eq, erule pdivmod_rel_smult_right, rule pdivmod_rel)
215.1048 +
215.1049 +lemma poly_div_minus_right [simp]:
215.1050 + fixes x y :: "'a::field poly"
215.1051 + shows "x div (- y) = - (x div y)"
215.1052 + using div_smult_right [of "- 1::'a"]
215.1053 + by (simp add: nonzero_inverse_minus_eq)
215.1054 +
215.1055 +lemma poly_mod_minus_right [simp]:
215.1056 + fixes x y :: "'a::field poly"
215.1057 + shows "x mod (- y) = x mod y"
215.1058 + using mod_smult_right [of "- 1::'a"] by simp
215.1059 +
215.1060 +lemma pdivmod_rel_mult:
215.1061 + "\<lbrakk>pdivmod_rel x y q r; pdivmod_rel q z q' r'\<rbrakk>
215.1062 + \<Longrightarrow> pdivmod_rel x (y * z) q' (y * r' + r)"
215.1063 +apply (cases "z = 0", simp add: pdivmod_rel_def)
215.1064 +apply (cases "y = 0", simp add: pdivmod_rel_by_0_iff pdivmod_rel_0_iff)
215.1065 +apply (cases "r = 0")
215.1066 +apply (cases "r' = 0")
215.1067 +apply (simp add: pdivmod_rel_def)
215.1068 +apply (simp add: pdivmod_rel_def ring_simps degree_mult_eq)
215.1069 +apply (cases "r' = 0")
215.1070 +apply (simp add: pdivmod_rel_def degree_mult_eq)
215.1071 +apply (simp add: pdivmod_rel_def ring_simps)
215.1072 +apply (simp add: degree_mult_eq degree_add_less)
215.1073 +done
215.1074 +
215.1075 +lemma poly_div_mult_right:
215.1076 + fixes x y z :: "'a::field poly"
215.1077 + shows "x div (y * z) = (x div y) div z"
215.1078 + by (rule div_poly_eq, rule pdivmod_rel_mult, (rule pdivmod_rel)+)
215.1079 +
215.1080 +lemma poly_mod_mult_right:
215.1081 + fixes x y z :: "'a::field poly"
215.1082 + shows "x mod (y * z) = y * (x div y mod z) + x mod y"
215.1083 + by (rule mod_poly_eq, rule pdivmod_rel_mult, (rule pdivmod_rel)+)
215.1084 +
215.1085 +lemma mod_pCons:
215.1086 + fixes a and x
215.1087 + assumes y: "y \<noteq> 0"
215.1088 + defines b: "b \<equiv> coeff (pCons a (x mod y)) (degree y) / coeff y (degree y)"
215.1089 + shows "(pCons a x) mod y = (pCons a (x mod y) - smult b y)"
215.1090 +unfolding b
215.1091 +apply (rule mod_poly_eq)
215.1092 +apply (rule pdivmod_rel_pCons [OF pdivmod_rel y refl])
215.1093 +done
215.1094 +
215.1095 +
215.1096 +subsection {* Evaluation of polynomials *}
215.1097 +
215.1098 +definition
215.1099 + poly :: "'a::comm_semiring_0 poly \<Rightarrow> 'a \<Rightarrow> 'a" where
215.1100 + "poly = poly_rec (\<lambda>x. 0) (\<lambda>a p f x. a + x * f x)"
215.1101 +
215.1102 +lemma poly_0 [simp]: "poly 0 x = 0"
215.1103 + unfolding poly_def by (simp add: poly_rec_0)
215.1104 +
215.1105 +lemma poly_pCons [simp]: "poly (pCons a p) x = a + x * poly p x"
215.1106 + unfolding poly_def by (simp add: poly_rec_pCons)
215.1107 +
215.1108 +lemma poly_1 [simp]: "poly 1 x = 1"
215.1109 + unfolding one_poly_def by simp
215.1110 +
215.1111 +lemma poly_monom:
215.1112 + fixes a x :: "'a::{comm_semiring_1,recpower}"
215.1113 + shows "poly (monom a n) x = a * x ^ n"
215.1114 + by (induct n, simp add: monom_0, simp add: monom_Suc power_Suc mult_ac)
215.1115 +
215.1116 +lemma poly_add [simp]: "poly (p + q) x = poly p x + poly q x"
215.1117 + apply (induct p arbitrary: q, simp)
215.1118 + apply (case_tac q, simp, simp add: algebra_simps)
215.1119 + done
215.1120 +
215.1121 +lemma poly_minus [simp]:
215.1122 + fixes x :: "'a::comm_ring"
215.1123 + shows "poly (- p) x = - poly p x"
215.1124 + by (induct p, simp_all)
215.1125 +
215.1126 +lemma poly_diff [simp]:
215.1127 + fixes x :: "'a::comm_ring"
215.1128 + shows "poly (p - q) x = poly p x - poly q x"
215.1129 + by (simp add: diff_minus)
215.1130 +
215.1131 +lemma poly_setsum: "poly (\<Sum>k\<in>A. p k) x = (\<Sum>k\<in>A. poly (p k) x)"
215.1132 + by (cases "finite A", induct set: finite, simp_all)
215.1133 +
215.1134 +lemma poly_smult [simp]: "poly (smult a p) x = a * poly p x"
215.1135 + by (induct p, simp, simp add: algebra_simps)
215.1136 +
215.1137 +lemma poly_mult [simp]: "poly (p * q) x = poly p x * poly q x"
215.1138 + by (induct p, simp_all, simp add: algebra_simps)
215.1139 +
215.1140 +lemma poly_power [simp]:
215.1141 + fixes p :: "'a::{comm_semiring_1,recpower} poly"
215.1142 + shows "poly (p ^ n) x = poly p x ^ n"
215.1143 + by (induct n, simp, simp add: power_Suc)
215.1144 +
215.1145 +
215.1146 +subsection {* Synthetic division *}
215.1147 +
215.1148 +text {*
215.1149 + Synthetic division is simply division by the
215.1150 + linear polynomial @{term "x - c"}.
215.1151 +*}
215.1152 +
215.1153 +definition
215.1154 + synthetic_divmod :: "'a::comm_semiring_0 poly \<Rightarrow> 'a \<Rightarrow> 'a poly \<times> 'a"
215.1155 +where [code del]:
215.1156 + "synthetic_divmod p c =
215.1157 + poly_rec (0, 0) (\<lambda>a p (q, r). (pCons r q, a + c * r)) p"
215.1158 +
215.1159 +definition
215.1160 + synthetic_div :: "'a::comm_semiring_0 poly \<Rightarrow> 'a \<Rightarrow> 'a poly"
215.1161 +where
215.1162 + "synthetic_div p c = fst (synthetic_divmod p c)"
215.1163 +
215.1164 +lemma synthetic_divmod_0 [simp]:
215.1165 + "synthetic_divmod 0 c = (0, 0)"
215.1166 + unfolding synthetic_divmod_def
215.1167 + by (simp add: poly_rec_0)
215.1168 +
215.1169 +lemma synthetic_divmod_pCons [simp]:
215.1170 + "synthetic_divmod (pCons a p) c =
215.1171 + (\<lambda>(q, r). (pCons r q, a + c * r)) (synthetic_divmod p c)"
215.1172 + unfolding synthetic_divmod_def
215.1173 + by (simp add: poly_rec_pCons)
215.1174 +
215.1175 +lemma snd_synthetic_divmod: "snd (synthetic_divmod p c) = poly p c"
215.1176 + by (induct p, simp, simp add: split_def)
215.1177 +
215.1178 +lemma synthetic_div_0 [simp]: "synthetic_div 0 c = 0"
215.1179 + unfolding synthetic_div_def by simp
215.1180 +
215.1181 +lemma synthetic_div_pCons [simp]:
215.1182 + "synthetic_div (pCons a p) c = pCons (poly p c) (synthetic_div p c)"
215.1183 + unfolding synthetic_div_def
215.1184 + by (simp add: split_def snd_synthetic_divmod)
215.1185 +
215.1186 +lemma synthetic_div_eq_0_iff:
215.1187 + "synthetic_div p c = 0 \<longleftrightarrow> degree p = 0"
215.1188 + by (induct p, simp, case_tac p, simp)
215.1189 +
215.1190 +lemma degree_synthetic_div:
215.1191 + "degree (synthetic_div p c) = degree p - 1"
215.1192 + by (induct p, simp, simp add: synthetic_div_eq_0_iff)
215.1193 +
215.1194 +lemma synthetic_div_correct:
215.1195 + "p + smult c (synthetic_div p c) = pCons (poly p c) (synthetic_div p c)"
215.1196 + by (induct p) simp_all
215.1197 +
215.1198 +lemma synthetic_div_unique_lemma: "smult c p = pCons a p \<Longrightarrow> p = 0"
215.1199 +by (induct p arbitrary: a) simp_all
215.1200 +
215.1201 +lemma synthetic_div_unique:
215.1202 + "p + smult c q = pCons r q \<Longrightarrow> r = poly p c \<and> q = synthetic_div p c"
215.1203 +apply (induct p arbitrary: q r)
215.1204 +apply (simp, frule synthetic_div_unique_lemma, simp)
215.1205 +apply (case_tac q, force)
215.1206 +done
215.1207 +
215.1208 +lemma synthetic_div_correct':
215.1209 + fixes c :: "'a::comm_ring_1"
215.1210 + shows "[:-c, 1:] * synthetic_div p c + [:poly p c:] = p"
215.1211 + using synthetic_div_correct [of p c]
215.1212 + by (simp add: algebra_simps)
215.1213 +
215.1214 +lemma poly_eq_0_iff_dvd:
215.1215 + fixes c :: "'a::idom"
215.1216 + shows "poly p c = 0 \<longleftrightarrow> [:-c, 1:] dvd p"
215.1217 +proof
215.1218 + assume "poly p c = 0"
215.1219 + with synthetic_div_correct' [of c p]
215.1220 + have "p = [:-c, 1:] * synthetic_div p c" by simp
215.1221 + then show "[:-c, 1:] dvd p" ..
215.1222 +next
215.1223 + assume "[:-c, 1:] dvd p"
215.1224 + then obtain k where "p = [:-c, 1:] * k" by (rule dvdE)
215.1225 + then show "poly p c = 0" by simp
215.1226 +qed
215.1227 +
215.1228 +lemma dvd_iff_poly_eq_0:
215.1229 + fixes c :: "'a::idom"
215.1230 + shows "[:c, 1:] dvd p \<longleftrightarrow> poly p (-c) = 0"
215.1231 + by (simp add: poly_eq_0_iff_dvd)
215.1232 +
215.1233 +lemma poly_roots_finite:
215.1234 + fixes p :: "'a::idom poly"
215.1235 + shows "p \<noteq> 0 \<Longrightarrow> finite {x. poly p x = 0}"
215.1236 +proof (induct n \<equiv> "degree p" arbitrary: p)
215.1237 + case (0 p)
215.1238 + then obtain a where "a \<noteq> 0" and "p = [:a:]"
215.1239 + by (cases p, simp split: if_splits)
215.1240 + then show "finite {x. poly p x = 0}" by simp
215.1241 +next
215.1242 + case (Suc n p)
215.1243 + show "finite {x. poly p x = 0}"
215.1244 + proof (cases "\<exists>x. poly p x = 0")
215.1245 + case False
215.1246 + then show "finite {x. poly p x = 0}" by simp
215.1247 + next
215.1248 + case True
215.1249 + then obtain a where "poly p a = 0" ..
215.1250 + then have "[:-a, 1:] dvd p" by (simp only: poly_eq_0_iff_dvd)
215.1251 + then obtain k where k: "p = [:-a, 1:] * k" ..
215.1252 + with `p \<noteq> 0` have "k \<noteq> 0" by auto
215.1253 + with k have "degree p = Suc (degree k)"
215.1254 + by (simp add: degree_mult_eq del: mult_pCons_left)
215.1255 + with `Suc n = degree p` have "n = degree k" by simp
215.1256 + with `k \<noteq> 0` have "finite {x. poly k x = 0}" by (rule Suc.hyps)
215.1257 + then have "finite (insert a {x. poly k x = 0})" by simp
215.1258 + then show "finite {x. poly p x = 0}"
215.1259 + by (simp add: k uminus_add_conv_diff Collect_disj_eq
215.1260 + del: mult_pCons_left)
215.1261 + qed
215.1262 +qed
215.1263 +
215.1264 +lemma poly_zero:
215.1265 + fixes p :: "'a::{idom,ring_char_0} poly"
215.1266 + shows "poly p = poly 0 \<longleftrightarrow> p = 0"
215.1267 +apply (cases "p = 0", simp_all)
215.1268 +apply (drule poly_roots_finite)
215.1269 +apply (auto simp add: infinite_UNIV_char_0)
215.1270 +done
215.1271 +
215.1272 +lemma poly_eq_iff:
215.1273 + fixes p q :: "'a::{idom,ring_char_0} poly"
215.1274 + shows "poly p = poly q \<longleftrightarrow> p = q"
215.1275 + using poly_zero [of "p - q"]
215.1276 + by (simp add: expand_fun_eq)
215.1277 +
215.1278 +
215.1279 +subsection {* Composition of polynomials *}
215.1280 +
215.1281 +definition
215.1282 + pcompose :: "'a::comm_semiring_0 poly \<Rightarrow> 'a poly \<Rightarrow> 'a poly"
215.1283 +where
215.1284 + "pcompose p q = poly_rec 0 (\<lambda>a _ c. [:a:] + q * c) p"
215.1285 +
215.1286 +lemma pcompose_0 [simp]: "pcompose 0 q = 0"
215.1287 + unfolding pcompose_def by (simp add: poly_rec_0)
215.1288 +
215.1289 +lemma pcompose_pCons:
215.1290 + "pcompose (pCons a p) q = [:a:] + q * pcompose p q"
215.1291 + unfolding pcompose_def by (simp add: poly_rec_pCons)
215.1292 +
215.1293 +lemma poly_pcompose: "poly (pcompose p q) x = poly p (poly q x)"
215.1294 + by (induct p) (simp_all add: pcompose_pCons)
215.1295 +
215.1296 +lemma degree_pcompose_le:
215.1297 + "degree (pcompose p q) \<le> degree p * degree q"
215.1298 +apply (induct p, simp)
215.1299 +apply (simp add: pcompose_pCons, clarify)
215.1300 +apply (rule degree_add_le, simp)
215.1301 +apply (rule order_trans [OF degree_mult_le], simp)
215.1302 +done
215.1303 +
215.1304 +
215.1305 +subsection {* Order of polynomial roots *}
215.1306 +
215.1307 +definition
215.1308 + order :: "'a::idom \<Rightarrow> 'a poly \<Rightarrow> nat"
215.1309 +where
215.1310 + [code del]:
215.1311 + "order a p = (LEAST n. \<not> [:-a, 1:] ^ Suc n dvd p)"
215.1312 +
215.1313 +lemma coeff_linear_power:
215.1314 + fixes a :: "'a::comm_semiring_1"
215.1315 + shows "coeff ([:a, 1:] ^ n) n = 1"
215.1316 +apply (induct n, simp_all)
215.1317 +apply (subst coeff_eq_0)
215.1318 +apply (auto intro: le_less_trans degree_power_le)
215.1319 +done
215.1320 +
215.1321 +lemma degree_linear_power:
215.1322 + fixes a :: "'a::comm_semiring_1"
215.1323 + shows "degree ([:a, 1:] ^ n) = n"
215.1324 +apply (rule order_antisym)
215.1325 +apply (rule ord_le_eq_trans [OF degree_power_le], simp)
215.1326 +apply (rule le_degree, simp add: coeff_linear_power)
215.1327 +done
215.1328 +
215.1329 +lemma order_1: "[:-a, 1:] ^ order a p dvd p"
215.1330 +apply (cases "p = 0", simp)
215.1331 +apply (cases "order a p", simp)
215.1332 +apply (subgoal_tac "nat < (LEAST n. \<not> [:-a, 1:] ^ Suc n dvd p)")
215.1333 +apply (drule not_less_Least, simp)
215.1334 +apply (fold order_def, simp)
215.1335 +done
215.1336 +
215.1337 +lemma order_2: "p \<noteq> 0 \<Longrightarrow> \<not> [:-a, 1:] ^ Suc (order a p) dvd p"
215.1338 +unfolding order_def
215.1339 +apply (rule LeastI_ex)
215.1340 +apply (rule_tac x="degree p" in exI)
215.1341 +apply (rule notI)
215.1342 +apply (drule (1) dvd_imp_degree_le)
215.1343 +apply (simp only: degree_linear_power)
215.1344 +done
215.1345 +
215.1346 +lemma order:
215.1347 + "p \<noteq> 0 \<Longrightarrow> [:-a, 1:] ^ order a p dvd p \<and> \<not> [:-a, 1:] ^ Suc (order a p) dvd p"
215.1348 +by (rule conjI [OF order_1 order_2])
215.1349 +
215.1350 +lemma order_degree:
215.1351 + assumes p: "p \<noteq> 0"
215.1352 + shows "order a p \<le> degree p"
215.1353 +proof -
215.1354 + have "order a p = degree ([:-a, 1:] ^ order a p)"
215.1355 + by (simp only: degree_linear_power)
215.1356 + also have "\<dots> \<le> degree p"
215.1357 + using order_1 p by (rule dvd_imp_degree_le)
215.1358 + finally show ?thesis .
215.1359 +qed
215.1360 +
215.1361 +lemma order_root: "poly p a = 0 \<longleftrightarrow> p = 0 \<or> order a p \<noteq> 0"
215.1362 +apply (cases "p = 0", simp_all)
215.1363 +apply (rule iffI)
215.1364 +apply (rule ccontr, simp)
215.1365 +apply (frule order_2 [where a=a], simp)
215.1366 +apply (simp add: poly_eq_0_iff_dvd)
215.1367 +apply (simp add: poly_eq_0_iff_dvd)
215.1368 +apply (simp only: order_def)
215.1369 +apply (drule not_less_Least, simp)
215.1370 +done
215.1371 +
215.1372 +
215.1373 +subsection {* Configuration of the code generator *}
215.1374 +
215.1375 +code_datatype "0::'a::zero poly" pCons
215.1376 +
215.1377 +declare pCons_0_0 [code post]
215.1378 +
215.1379 +instantiation poly :: ("{zero,eq}") eq
215.1380 +begin
215.1381 +
215.1382 +definition [code del]:
215.1383 + "eq_class.eq (p::'a poly) q \<longleftrightarrow> p = q"
215.1384 +
215.1385 +instance
215.1386 + by default (rule eq_poly_def)
215.1387 +
215.1388 +end
215.1389 +
215.1390 +lemma eq_poly_code [code]:
215.1391 + "eq_class.eq (0::_ poly) (0::_ poly) \<longleftrightarrow> True"
215.1392 + "eq_class.eq (0::_ poly) (pCons b q) \<longleftrightarrow> eq_class.eq 0 b \<and> eq_class.eq 0 q"
215.1393 + "eq_class.eq (pCons a p) (0::_ poly) \<longleftrightarrow> eq_class.eq a 0 \<and> eq_class.eq p 0"
215.1394 + "eq_class.eq (pCons a p) (pCons b q) \<longleftrightarrow> eq_class.eq a b \<and> eq_class.eq p q"
215.1395 +unfolding eq by simp_all
215.1396 +
215.1397 +lemmas coeff_code [code] =
215.1398 + coeff_0 coeff_pCons_0 coeff_pCons_Suc
215.1399 +
215.1400 +lemmas degree_code [code] =
215.1401 + degree_0 degree_pCons_eq_if
215.1402 +
215.1403 +lemmas monom_poly_code [code] =
215.1404 + monom_0 monom_Suc
215.1405 +
215.1406 +lemma add_poly_code [code]:
215.1407 + "0 + q = (q :: _ poly)"
215.1408 + "p + 0 = (p :: _ poly)"
215.1409 + "pCons a p + pCons b q = pCons (a + b) (p + q)"
215.1410 +by simp_all
215.1411 +
215.1412 +lemma minus_poly_code [code]:
215.1413 + "- 0 = (0 :: _ poly)"
215.1414 + "- pCons a p = pCons (- a) (- p)"
215.1415 +by simp_all
215.1416 +
215.1417 +lemma diff_poly_code [code]:
215.1418 + "0 - q = (- q :: _ poly)"
215.1419 + "p - 0 = (p :: _ poly)"
215.1420 + "pCons a p - pCons b q = pCons (a - b) (p - q)"
215.1421 +by simp_all
215.1422 +
215.1423 +lemmas smult_poly_code [code] =
215.1424 + smult_0_right smult_pCons
215.1425 +
215.1426 +lemma mult_poly_code [code]:
215.1427 + "0 * q = (0 :: _ poly)"
215.1428 + "pCons a p * q = smult a q + pCons 0 (p * q)"
215.1429 +by simp_all
215.1430 +
215.1431 +lemmas poly_code [code] =
215.1432 + poly_0 poly_pCons
215.1433 +
215.1434 +lemmas synthetic_divmod_code [code] =
215.1435 + synthetic_divmod_0 synthetic_divmod_pCons
215.1436 +
215.1437 +text {* code generator setup for div and mod *}
215.1438 +
215.1439 +definition
215.1440 + pdivmod :: "'a::field poly \<Rightarrow> 'a poly \<Rightarrow> 'a poly \<times> 'a poly"
215.1441 +where
215.1442 + [code del]: "pdivmod x y = (x div y, x mod y)"
215.1443 +
215.1444 +lemma div_poly_code [code]: "x div y = fst (pdivmod x y)"
215.1445 + unfolding pdivmod_def by simp
215.1446 +
215.1447 +lemma mod_poly_code [code]: "x mod y = snd (pdivmod x y)"
215.1448 + unfolding pdivmod_def by simp
215.1449 +
215.1450 +lemma pdivmod_0 [code]: "pdivmod 0 y = (0, 0)"
215.1451 + unfolding pdivmod_def by simp
215.1452 +
215.1453 +lemma pdivmod_pCons [code]:
215.1454 + "pdivmod (pCons a x) y =
215.1455 + (if y = 0 then (0, pCons a x) else
215.1456 + (let (q, r) = pdivmod x y;
215.1457 + b = coeff (pCons a r) (degree y) / coeff y (degree y)
215.1458 + in (pCons b q, pCons a r - smult b y)))"
215.1459 +apply (simp add: pdivmod_def Let_def, safe)
215.1460 +apply (rule div_poly_eq)
215.1461 +apply (erule pdivmod_rel_pCons [OF pdivmod_rel _ refl])
215.1462 +apply (rule mod_poly_eq)
215.1463 +apply (erule pdivmod_rel_pCons [OF pdivmod_rel _ refl])
215.1464 +done
215.1465 +
215.1466 +end
216.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
216.2 +++ b/src/HOL/Library/Product_Vector.thy Wed Mar 04 11:05:29 2009 +0100
216.3 @@ -0,0 +1,273 @@
216.4 +(* Title: HOL/Library/Product_Vector.thy
216.5 + Author: Brian Huffman
216.6 +*)
216.7 +
216.8 +header {* Cartesian Products as Vector Spaces *}
216.9 +
216.10 +theory Product_Vector
216.11 +imports Inner_Product Product_plus
216.12 +begin
216.13 +
216.14 +subsection {* Product is a real vector space *}
216.15 +
216.16 +instantiation "*" :: (real_vector, real_vector) real_vector
216.17 +begin
216.18 +
216.19 +definition scaleR_prod_def:
216.20 + "scaleR r A = (scaleR r (fst A), scaleR r (snd A))"
216.21 +
216.22 +lemma fst_scaleR [simp]: "fst (scaleR r A) = scaleR r (fst A)"
216.23 + unfolding scaleR_prod_def by simp
216.24 +
216.25 +lemma snd_scaleR [simp]: "snd (scaleR r A) = scaleR r (snd A)"
216.26 + unfolding scaleR_prod_def by simp
216.27 +
216.28 +lemma scaleR_Pair [simp]: "scaleR r (a, b) = (scaleR r a, scaleR r b)"
216.29 + unfolding scaleR_prod_def by simp
216.30 +
216.31 +instance proof
216.32 + fix a b :: real and x y :: "'a \<times> 'b"
216.33 + show "scaleR a (x + y) = scaleR a x + scaleR a y"
216.34 + by (simp add: expand_prod_eq scaleR_right_distrib)
216.35 + show "scaleR (a + b) x = scaleR a x + scaleR b x"
216.36 + by (simp add: expand_prod_eq scaleR_left_distrib)
216.37 + show "scaleR a (scaleR b x) = scaleR (a * b) x"
216.38 + by (simp add: expand_prod_eq)
216.39 + show "scaleR 1 x = x"
216.40 + by (simp add: expand_prod_eq)
216.41 +qed
216.42 +
216.43 +end
216.44 +
216.45 +subsection {* Product is a normed vector space *}
216.46 +
216.47 +instantiation
216.48 + "*" :: (real_normed_vector, real_normed_vector) real_normed_vector
216.49 +begin
216.50 +
216.51 +definition norm_prod_def:
216.52 + "norm x = sqrt ((norm (fst x))\<twosuperior> + (norm (snd x))\<twosuperior>)"
216.53 +
216.54 +definition sgn_prod_def:
216.55 + "sgn (x::'a \<times> 'b) = scaleR (inverse (norm x)) x"
216.56 +
216.57 +lemma norm_Pair: "norm (a, b) = sqrt ((norm a)\<twosuperior> + (norm b)\<twosuperior>)"
216.58 + unfolding norm_prod_def by simp
216.59 +
216.60 +instance proof
216.61 + fix r :: real and x y :: "'a \<times> 'b"
216.62 + show "0 \<le> norm x"
216.63 + unfolding norm_prod_def by simp
216.64 + show "norm x = 0 \<longleftrightarrow> x = 0"
216.65 + unfolding norm_prod_def
216.66 + by (simp add: expand_prod_eq)
216.67 + show "norm (x + y) \<le> norm x + norm y"
216.68 + unfolding norm_prod_def
216.69 + apply (rule order_trans [OF _ real_sqrt_sum_squares_triangle_ineq])
216.70 + apply (simp add: add_mono power_mono norm_triangle_ineq)
216.71 + done
216.72 + show "norm (scaleR r x) = \<bar>r\<bar> * norm x"
216.73 + unfolding norm_prod_def
216.74 + apply (simp add: norm_scaleR power_mult_distrib)
216.75 + apply (simp add: right_distrib [symmetric])
216.76 + apply (simp add: real_sqrt_mult_distrib)
216.77 + done
216.78 + show "sgn x = scaleR (inverse (norm x)) x"
216.79 + by (rule sgn_prod_def)
216.80 +qed
216.81 +
216.82 +end
216.83 +
216.84 +subsection {* Product is an inner product space *}
216.85 +
216.86 +instantiation "*" :: (real_inner, real_inner) real_inner
216.87 +begin
216.88 +
216.89 +definition inner_prod_def:
216.90 + "inner x y = inner (fst x) (fst y) + inner (snd x) (snd y)"
216.91 +
216.92 +lemma inner_Pair [simp]: "inner (a, b) (c, d) = inner a c + inner b d"
216.93 + unfolding inner_prod_def by simp
216.94 +
216.95 +instance proof
216.96 + fix r :: real
216.97 + fix x y z :: "'a::real_inner * 'b::real_inner"
216.98 + show "inner x y = inner y x"
216.99 + unfolding inner_prod_def
216.100 + by (simp add: inner_commute)
216.101 + show "inner (x + y) z = inner x z + inner y z"
216.102 + unfolding inner_prod_def
216.103 + by (simp add: inner_left_distrib)
216.104 + show "inner (scaleR r x) y = r * inner x y"
216.105 + unfolding inner_prod_def
216.106 + by (simp add: inner_scaleR_left right_distrib)
216.107 + show "0 \<le> inner x x"
216.108 + unfolding inner_prod_def
216.109 + by (intro add_nonneg_nonneg inner_ge_zero)
216.110 + show "inner x x = 0 \<longleftrightarrow> x = 0"
216.111 + unfolding inner_prod_def expand_prod_eq
216.112 + by (simp add: add_nonneg_eq_0_iff)
216.113 + show "norm x = sqrt (inner x x)"
216.114 + unfolding norm_prod_def inner_prod_def
216.115 + by (simp add: power2_norm_eq_inner)
216.116 +qed
216.117 +
216.118 +end
216.119 +
216.120 +subsection {* Pair operations are linear and continuous *}
216.121 +
216.122 +interpretation fst!: bounded_linear fst
216.123 + apply (unfold_locales)
216.124 + apply (rule fst_add)
216.125 + apply (rule fst_scaleR)
216.126 + apply (rule_tac x="1" in exI, simp add: norm_Pair)
216.127 + done
216.128 +
216.129 +interpretation snd!: bounded_linear snd
216.130 + apply (unfold_locales)
216.131 + apply (rule snd_add)
216.132 + apply (rule snd_scaleR)
216.133 + apply (rule_tac x="1" in exI, simp add: norm_Pair)
216.134 + done
216.135 +
216.136 +text {* TODO: move to NthRoot *}
216.137 +lemma sqrt_add_le_add_sqrt:
216.138 + assumes x: "0 \<le> x" and y: "0 \<le> y"
216.139 + shows "sqrt (x + y) \<le> sqrt x + sqrt y"
216.140 +apply (rule power2_le_imp_le)
216.141 +apply (simp add: real_sum_squared_expand add_nonneg_nonneg x y)
216.142 +apply (simp add: mult_nonneg_nonneg x y)
216.143 +apply (simp add: add_nonneg_nonneg x y)
216.144 +done
216.145 +
216.146 +lemma bounded_linear_Pair:
216.147 + assumes f: "bounded_linear f"
216.148 + assumes g: "bounded_linear g"
216.149 + shows "bounded_linear (\<lambda>x. (f x, g x))"
216.150 +proof
216.151 + interpret f: bounded_linear f by fact
216.152 + interpret g: bounded_linear g by fact
216.153 + fix x y and r :: real
216.154 + show "(f (x + y), g (x + y)) = (f x, g x) + (f y, g y)"
216.155 + by (simp add: f.add g.add)
216.156 + show "(f (r *\<^sub>R x), g (r *\<^sub>R x)) = r *\<^sub>R (f x, g x)"
216.157 + by (simp add: f.scaleR g.scaleR)
216.158 + obtain Kf where "0 < Kf" and norm_f: "\<And>x. norm (f x) \<le> norm x * Kf"
216.159 + using f.pos_bounded by fast
216.160 + obtain Kg where "0 < Kg" and norm_g: "\<And>x. norm (g x) \<le> norm x * Kg"
216.161 + using g.pos_bounded by fast
216.162 + have "\<forall>x. norm (f x, g x) \<le> norm x * (Kf + Kg)"
216.163 + apply (rule allI)
216.164 + apply (simp add: norm_Pair)
216.165 + apply (rule order_trans [OF sqrt_add_le_add_sqrt], simp, simp)
216.166 + apply (simp add: right_distrib)
216.167 + apply (rule add_mono [OF norm_f norm_g])
216.168 + done
216.169 + then show "\<exists>K. \<forall>x. norm (f x, g x) \<le> norm x * K" ..
216.170 +qed
216.171 +
216.172 +text {*
216.173 + TODO: The next three proofs are nearly identical to each other.
216.174 + Is there a good way to factor out the common parts?
216.175 +*}
216.176 +
216.177 +lemma LIMSEQ_Pair:
216.178 + assumes "X ----> a" and "Y ----> b"
216.179 + shows "(\<lambda>n. (X n, Y n)) ----> (a, b)"
216.180 +proof (rule LIMSEQ_I)
216.181 + fix r :: real assume "0 < r"
216.182 + then have "0 < r / sqrt 2" (is "0 < ?s")
216.183 + by (simp add: divide_pos_pos)
216.184 + obtain M where M: "\<forall>n\<ge>M. norm (X n - a) < ?s"
216.185 + using LIMSEQ_D [OF `X ----> a` `0 < ?s`] ..
216.186 + obtain N where N: "\<forall>n\<ge>N. norm (Y n - b) < ?s"
216.187 + using LIMSEQ_D [OF `Y ----> b` `0 < ?s`] ..
216.188 + have "\<forall>n\<ge>max M N. norm ((X n, Y n) - (a, b)) < r"
216.189 + using M N by (simp add: real_sqrt_sum_squares_less norm_Pair)
216.190 + then show "\<exists>n0. \<forall>n\<ge>n0. norm ((X n, Y n) - (a, b)) < r" ..
216.191 +qed
216.192 +
216.193 +lemma Cauchy_Pair:
216.194 + assumes "Cauchy X" and "Cauchy Y"
216.195 + shows "Cauchy (\<lambda>n. (X n, Y n))"
216.196 +proof (rule CauchyI)
216.197 + fix r :: real assume "0 < r"
216.198 + then have "0 < r / sqrt 2" (is "0 < ?s")
216.199 + by (simp add: divide_pos_pos)
216.200 + obtain M where M: "\<forall>m\<ge>M. \<forall>n\<ge>M. norm (X m - X n) < ?s"
216.201 + using CauchyD [OF `Cauchy X` `0 < ?s`] ..
216.202 + obtain N where N: "\<forall>m\<ge>N. \<forall>n\<ge>N. norm (Y m - Y n) < ?s"
216.203 + using CauchyD [OF `Cauchy Y` `0 < ?s`] ..
216.204 + have "\<forall>m\<ge>max M N. \<forall>n\<ge>max M N. norm ((X m, Y m) - (X n, Y n)) < r"
216.205 + using M N by (simp add: real_sqrt_sum_squares_less norm_Pair)
216.206 + then show "\<exists>n0. \<forall>m\<ge>n0. \<forall>n\<ge>n0. norm ((X m, Y m) - (X n, Y n)) < r" ..
216.207 +qed
216.208 +
216.209 +lemma LIM_Pair:
216.210 + assumes "f -- x --> a" and "g -- x --> b"
216.211 + shows "(\<lambda>x. (f x, g x)) -- x --> (a, b)"
216.212 +proof (rule LIM_I)
216.213 + fix r :: real assume "0 < r"
216.214 + then have "0 < r / sqrt 2" (is "0 < ?e")
216.215 + by (simp add: divide_pos_pos)
216.216 + obtain s where s: "0 < s"
216.217 + "\<forall>z. z \<noteq> x \<and> norm (z - x) < s \<longrightarrow> norm (f z - a) < ?e"
216.218 + using LIM_D [OF `f -- x --> a` `0 < ?e`] by fast
216.219 + obtain t where t: "0 < t"
216.220 + "\<forall>z. z \<noteq> x \<and> norm (z - x) < t \<longrightarrow> norm (g z - b) < ?e"
216.221 + using LIM_D [OF `g -- x --> b` `0 < ?e`] by fast
216.222 + have "0 < min s t \<and>
216.223 + (\<forall>z. z \<noteq> x \<and> norm (z - x) < min s t \<longrightarrow> norm ((f z, g z) - (a, b)) < r)"
216.224 + using s t by (simp add: real_sqrt_sum_squares_less norm_Pair)
216.225 + then show
216.226 + "\<exists>s>0. \<forall>z. z \<noteq> x \<and> norm (z - x) < s \<longrightarrow> norm ((f z, g z) - (a, b)) < r" ..
216.227 +qed
216.228 +
216.229 +lemma isCont_Pair [simp]:
216.230 + "\<lbrakk>isCont f x; isCont g x\<rbrakk> \<Longrightarrow> isCont (\<lambda>x. (f x, g x)) x"
216.231 + unfolding isCont_def by (rule LIM_Pair)
216.232 +
216.233 +
216.234 +subsection {* Product is a complete vector space *}
216.235 +
216.236 +instance "*" :: (banach, banach) banach
216.237 +proof
216.238 + fix X :: "nat \<Rightarrow> 'a \<times> 'b" assume "Cauchy X"
216.239 + have 1: "(\<lambda>n. fst (X n)) ----> lim (\<lambda>n. fst (X n))"
216.240 + using fst.Cauchy [OF `Cauchy X`]
216.241 + by (simp add: Cauchy_convergent_iff convergent_LIMSEQ_iff)
216.242 + have 2: "(\<lambda>n. snd (X n)) ----> lim (\<lambda>n. snd (X n))"
216.243 + using snd.Cauchy [OF `Cauchy X`]
216.244 + by (simp add: Cauchy_convergent_iff convergent_LIMSEQ_iff)
216.245 + have "X ----> (lim (\<lambda>n. fst (X n)), lim (\<lambda>n. snd (X n)))"
216.246 + using LIMSEQ_Pair [OF 1 2] by simp
216.247 + then show "convergent X"
216.248 + by (rule convergentI)
216.249 +qed
216.250 +
216.251 +subsection {* Frechet derivatives involving pairs *}
216.252 +
216.253 +lemma FDERIV_Pair:
216.254 + assumes f: "FDERIV f x :> f'" and g: "FDERIV g x :> g'"
216.255 + shows "FDERIV (\<lambda>x. (f x, g x)) x :> (\<lambda>h. (f' h, g' h))"
216.256 +apply (rule FDERIV_I)
216.257 +apply (rule bounded_linear_Pair)
216.258 +apply (rule FDERIV_bounded_linear [OF f])
216.259 +apply (rule FDERIV_bounded_linear [OF g])
216.260 +apply (simp add: norm_Pair)
216.261 +apply (rule real_LIM_sandwich_zero)
216.262 +apply (rule LIM_add_zero)
216.263 +apply (rule FDERIV_D [OF f])
216.264 +apply (rule FDERIV_D [OF g])
216.265 +apply (rename_tac h)
216.266 +apply (simp add: divide_nonneg_pos)
216.267 +apply (rename_tac h)
216.268 +apply (subst add_divide_distrib [symmetric])
216.269 +apply (rule divide_right_mono [OF _ norm_ge_zero])
216.270 +apply (rule order_trans [OF sqrt_add_le_add_sqrt])
216.271 +apply simp
216.272 +apply simp
216.273 +apply simp
216.274 +done
216.275 +
216.276 +end
217.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
217.2 +++ b/src/HOL/Library/Product_plus.thy Wed Mar 04 11:05:29 2009 +0100
217.3 @@ -0,0 +1,115 @@
217.4 +(* Title: HOL/Library/Product_plus.thy
217.5 + Author: Brian Huffman
217.6 +*)
217.7 +
217.8 +header {* Additive group operations on product types *}
217.9 +
217.10 +theory Product_plus
217.11 +imports Main
217.12 +begin
217.13 +
217.14 +subsection {* Operations *}
217.15 +
217.16 +instantiation "*" :: (zero, zero) zero
217.17 +begin
217.18 +
217.19 +definition zero_prod_def: "0 = (0, 0)"
217.20 +
217.21 +instance ..
217.22 +end
217.23 +
217.24 +instantiation "*" :: (plus, plus) plus
217.25 +begin
217.26 +
217.27 +definition plus_prod_def:
217.28 + "x + y = (fst x + fst y, snd x + snd y)"
217.29 +
217.30 +instance ..
217.31 +end
217.32 +
217.33 +instantiation "*" :: (minus, minus) minus
217.34 +begin
217.35 +
217.36 +definition minus_prod_def:
217.37 + "x - y = (fst x - fst y, snd x - snd y)"
217.38 +
217.39 +instance ..
217.40 +end
217.41 +
217.42 +instantiation "*" :: (uminus, uminus) uminus
217.43 +begin
217.44 +
217.45 +definition uminus_prod_def:
217.46 + "- x = (- fst x, - snd x)"
217.47 +
217.48 +instance ..
217.49 +end
217.50 +
217.51 +lemma fst_zero [simp]: "fst 0 = 0"
217.52 + unfolding zero_prod_def by simp
217.53 +
217.54 +lemma snd_zero [simp]: "snd 0 = 0"
217.55 + unfolding zero_prod_def by simp
217.56 +
217.57 +lemma fst_add [simp]: "fst (x + y) = fst x + fst y"
217.58 + unfolding plus_prod_def by simp
217.59 +
217.60 +lemma snd_add [simp]: "snd (x + y) = snd x + snd y"
217.61 + unfolding plus_prod_def by simp
217.62 +
217.63 +lemma fst_diff [simp]: "fst (x - y) = fst x - fst y"
217.64 + unfolding minus_prod_def by simp
217.65 +
217.66 +lemma snd_diff [simp]: "snd (x - y) = snd x - snd y"
217.67 + unfolding minus_prod_def by simp
217.68 +
217.69 +lemma fst_uminus [simp]: "fst (- x) = - fst x"
217.70 + unfolding uminus_prod_def by simp
217.71 +
217.72 +lemma snd_uminus [simp]: "snd (- x) = - snd x"
217.73 + unfolding uminus_prod_def by simp
217.74 +
217.75 +lemma add_Pair [simp]: "(a, b) + (c, d) = (a + c, b + d)"
217.76 + unfolding plus_prod_def by simp
217.77 +
217.78 +lemma diff_Pair [simp]: "(a, b) - (c, d) = (a - c, b - d)"
217.79 + unfolding minus_prod_def by simp
217.80 +
217.81 +lemma uminus_Pair [simp, code]: "- (a, b) = (- a, - b)"
217.82 + unfolding uminus_prod_def by simp
217.83 +
217.84 +lemmas expand_prod_eq = Pair_fst_snd_eq
217.85 +
217.86 +
217.87 +subsection {* Class instances *}
217.88 +
217.89 +instance "*" :: (semigroup_add, semigroup_add) semigroup_add
217.90 + by default (simp add: expand_prod_eq add_assoc)
217.91 +
217.92 +instance "*" :: (ab_semigroup_add, ab_semigroup_add) ab_semigroup_add
217.93 + by default (simp add: expand_prod_eq add_commute)
217.94 +
217.95 +instance "*" :: (monoid_add, monoid_add) monoid_add
217.96 + by default (simp_all add: expand_prod_eq)
217.97 +
217.98 +instance "*" :: (comm_monoid_add, comm_monoid_add) comm_monoid_add
217.99 + by default (simp add: expand_prod_eq)
217.100 +
217.101 +instance "*" ::
217.102 + (cancel_semigroup_add, cancel_semigroup_add) cancel_semigroup_add
217.103 + by default (simp_all add: expand_prod_eq)
217.104 +
217.105 +instance "*" ::
217.106 + (cancel_ab_semigroup_add, cancel_ab_semigroup_add) cancel_ab_semigroup_add
217.107 + by default (simp add: expand_prod_eq)
217.108 +
217.109 +instance "*" ::
217.110 + (cancel_comm_monoid_add, cancel_comm_monoid_add) cancel_comm_monoid_add ..
217.111 +
217.112 +instance "*" :: (group_add, group_add) group_add
217.113 + by default (simp_all add: expand_prod_eq diff_minus)
217.114 +
217.115 +instance "*" :: (ab_group_add, ab_group_add) ab_group_add
217.116 + by default (simp_all add: expand_prod_eq)
217.117 +
217.118 +end
218.1 --- a/src/HOL/Library/RBT.thy Wed Mar 04 11:05:02 2009 +0100
218.2 +++ b/src/HOL/Library/RBT.thy Wed Mar 04 11:05:29 2009 +0100
218.3 @@ -891,7 +891,7 @@
218.4 theorem mapwk_isrbt[simp]: "isrbt (mapwithkey f t) = isrbt t"
218.5 unfolding isrbt_def by (simp add: mapwk_inv1 mapwk_inv2 mapwk_st mapwk_treec)
218.6
218.7 -theorem map_of_mapwk[simp]: "map_of (mapwithkey f t) x = option_map (f x) (map_of t x)"
218.8 +theorem map_of_mapwk[simp]: "map_of (mapwithkey f t) x = Option.map (f x) (map_of t x)"
218.9 by (induct t) auto
218.10
218.11 definition map
218.12 @@ -899,7 +899,7 @@
218.13
218.14 theorem map_keys[simp]: "keys (map f t) = keys t" unfolding map_def by simp
218.15 theorem map_isrbt[simp]: "isrbt (map f t) = isrbt t" unfolding map_def by simp
218.16 -theorem map_of_map[simp]: "map_of (map f t) = option_map f o map_of t"
218.17 +theorem map_of_map[simp]: "map_of (map f t) = Option.map f o map_of t"
218.18 by (rule ext) (simp add:map_def)
218.19
218.20 subsection {* Fold *}
219.1 --- a/src/HOL/Map.thy Wed Mar 04 11:05:02 2009 +0100
219.2 +++ b/src/HOL/Map.thy Wed Mar 04 11:05:29 2009 +0100
219.3 @@ -242,17 +242,17 @@
219.4 "map_of xs k = Some z \<Longrightarrow> P k z \<Longrightarrow> map_of (filter (split P) xs) k = Some z"
219.5 by (induct xs) auto
219.6
219.7 -lemma map_of_map: "map_of (map (%(a,b). (a,f b)) xs) x = option_map f (map_of xs x)"
219.8 +lemma map_of_map: "map_of (map (%(a,b). (a,f b)) xs) x = Option.map f (map_of xs x)"
219.9 by (induct xs) auto
219.10
219.11
219.12 -subsection {* @{term [source] option_map} related *}
219.13 +subsection {* @{const Option.map} related *}
219.14
219.15 -lemma option_map_o_empty [simp]: "option_map f o empty = empty"
219.16 +lemma option_map_o_empty [simp]: "Option.map f o empty = empty"
219.17 by (rule ext) simp
219.18
219.19 lemma option_map_o_map_upd [simp]:
219.20 - "option_map f o m(a|->b) = (option_map f o m)(a|->f b)"
219.21 + "Option.map f o m(a|->b) = (Option.map f o m)(a|->f b)"
219.22 by (rule ext) simp
219.23
219.24
220.1 --- a/src/HOL/MicroJava/BV/Effect.thy Wed Mar 04 11:05:02 2009 +0100
220.2 +++ b/src/HOL/MicroJava/BV/Effect.thy Wed Mar 04 11:05:29 2009 +0100
220.3 @@ -105,7 +105,7 @@
220.4 (xcpt_names (i,G,pc,et))"
220.5
220.6 norm_eff :: "instr \<Rightarrow> jvm_prog \<Rightarrow> state_type option \<Rightarrow> state_type option"
220.7 - "norm_eff i G == option_map (\<lambda>s. eff' (i,G,s))"
220.8 + "norm_eff i G == Option.map (\<lambda>s. eff' (i,G,s))"
220.9
220.10 eff :: "instr \<Rightarrow> jvm_prog \<Rightarrow> p_count \<Rightarrow> exception_table \<Rightarrow> state_type option \<Rightarrow> succ_type"
220.11 "eff i G pc et s == (map (\<lambda>pc'. (pc',norm_eff i G s)) (succs i pc)) @ (xcpt_eff i G pc s et)"
221.1 --- a/src/HOL/MicroJava/BV/Opt.thy Wed Mar 04 11:05:02 2009 +0100
221.2 +++ b/src/HOL/MicroJava/BV/Opt.thy Wed Mar 04 11:05:29 2009 +0100
221.3 @@ -286,8 +286,8 @@
221.4
221.5 lemma option_map_in_optionI:
221.6 "\<lbrakk> ox : opt S; !x:S. ox = Some x \<longrightarrow> f x : S \<rbrakk>
221.7 - \<Longrightarrow> option_map f ox : opt S";
221.8 -apply (unfold option_map_def)
221.9 + \<Longrightarrow> Option.map f ox : opt S";
221.10 +apply (unfold Option.map_def)
221.11 apply (simp split: option.split)
221.12 apply blast
221.13 done
222.1 --- a/src/HOL/MicroJava/Comp/AuxLemmas.thy Wed Mar 04 11:05:02 2009 +0100
222.2 +++ b/src/HOL/MicroJava/Comp/AuxLemmas.thy Wed Mar 04 11:05:29 2009 +0100
222.3 @@ -126,11 +126,11 @@
222.4 by (induct xs,auto)
222.5
222.6 lemma map_of_map2: "\<forall> x \<in> set xs. (fst (f x)) = (fst x) \<Longrightarrow>
222.7 - map_of (map f xs) a = option_map (\<lambda> b. (snd (f (a, b)))) (map_of xs a)"
222.8 + map_of (map f xs) a = Option.map (\<lambda> b. (snd (f (a, b)))) (map_of xs a)"
222.9 by (induct xs, auto)
222.10
222.11 -lemma option_map_of [simp]: "(option_map f (map_of xs k) = None) = ((map_of xs k) = None)"
222.12 -by (simp add: option_map_def split: option.split)
222.13 +lemma option_map_of [simp]: "(Option.map f (map_of xs k) = None) = ((map_of xs k) = None)"
222.14 +by (simp add: Option.map_def split: option.split)
222.15
222.16
222.17
223.1 --- a/src/HOL/MicroJava/Comp/CorrCompTp.thy Wed Mar 04 11:05:02 2009 +0100
223.2 +++ b/src/HOL/MicroJava/Comp/CorrCompTp.thy Wed Mar 04 11:05:29 2009 +0100
223.3 @@ -553,7 +553,7 @@
223.4
223.5 lemma match_xctable_offset: "
223.6 (match_exception_table G cn (pc + n) (offset_xctable n et)) =
223.7 - (option_map (\<lambda> pc'. pc' + n) (match_exception_table G cn pc et))"
223.8 + (Option.map (\<lambda> pc'. pc' + n) (match_exception_table G cn pc et))"
223.9 apply (induct et)
223.10 apply (simp add: offset_xctable_def)+
223.11 apply (case_tac "match_exception_entry G cn pc a")
223.12 @@ -675,7 +675,7 @@
223.13 in app_jumps_lem)
223.14 apply (simp add: nth_append)+
223.15 (* subgoal \<exists> st. mt ! pc'' = Some st *)
223.16 - apply (simp add: norm_eff_def option_map_def nth_append)
223.17 + apply (simp add: norm_eff_def Option.map_def nth_append)
223.18 apply (case_tac "mt ! pc''")
223.19 apply simp+
223.20 done
224.1 --- a/src/HOL/MicroJava/Comp/LemmasComp.thy Wed Mar 04 11:05:02 2009 +0100
224.2 +++ b/src/HOL/MicroJava/Comp/LemmasComp.thy Wed Mar 04 11:05:29 2009 +0100
224.3 @@ -271,7 +271,7 @@
224.4 lemma map_of_map_fst: "\<lbrakk> inj f;
224.5 \<forall>x\<in>set xs. fst (f x) = fst x; \<forall>x\<in>set xs. fst (g x) = fst x \<rbrakk>
224.6 \<Longrightarrow> map_of (map g xs) k
224.7 - = option_map (\<lambda> e. (snd (g ((inv f) (k, e))))) (map_of (map f xs) k)"
224.8 + = Option.map (\<lambda> e. (snd (g ((inv f) (k, e))))) (map_of (map f xs) k)"
224.9 apply (induct xs)
224.10 apply simp
224.11 apply (simp del: split_paired_All)
224.12 @@ -288,13 +288,13 @@
224.13
224.14 lemma comp_method [rule_format (no_asm)]: "\<lbrakk> ws_prog G; is_class G C\<rbrakk> \<Longrightarrow>
224.15 ((method (comp G, C) S) =
224.16 - option_map (\<lambda> (D,rT,b). (D, rT, mtd_mb (compMethod G D (S, rT, b))))
224.17 + Option.map (\<lambda> (D,rT,b). (D, rT, mtd_mb (compMethod G D (S, rT, b))))
224.18 (method (G, C) S))"
224.19 apply (simp add: method_def)
224.20 apply (frule wf_subcls1)
224.21 apply (simp add: comp_class_rec)
224.22 apply (simp add: map_compose [THEN sym] split_iter split_compose del: map_compose)
224.23 -apply (rule_tac R="%x y. ((x S) = (option_map (\<lambda>(D, rT, b).
224.24 +apply (rule_tac R="%x y. ((x S) = (Option.map (\<lambda>(D, rT, b).
224.25 (D, rT, snd (snd (compMethod G D (S, rT, b))))) (y S)))"
224.26 in class_rec_relation)
224.27 apply assumption
225.1 --- a/src/HOL/MicroJava/J/Conform.thy Wed Mar 04 11:05:02 2009 +0100
225.2 +++ b/src/HOL/MicroJava/J/Conform.thy Wed Mar 04 11:05:29 2009 +0100
225.3 @@ -17,7 +17,7 @@
225.4
225.5 conf :: "'c prog => aheap => val => ty => bool"
225.6 ("_,_ |- _ ::<= _" [51,51,51,51] 50)
225.7 - "G,h|-v::<=T == \<exists>T'. typeof (option_map obj_ty o h) v = Some T' \<and> G\<turnstile>T'\<preceq>T"
225.8 + "G,h|-v::<=T == \<exists>T'. typeof (Option.map obj_ty o h) v = Some T' \<and> G\<turnstile>T'\<preceq>T"
225.9
225.10 lconf :: "'c prog => aheap => ('a \<rightharpoonup> val) => ('a \<rightharpoonup> ty) => bool"
225.11 ("_,_ |- _ [::<=] _" [51,51,51,51] 50)
226.1 --- a/src/HOL/MicroJava/J/Exceptions.thy Wed Mar 04 11:05:02 2009 +0100
226.2 +++ b/src/HOL/MicroJava/J/Exceptions.thy Wed Mar 04 11:05:29 2009 +0100
226.3 @@ -21,7 +21,7 @@
226.4 cname_of :: "aheap \<Rightarrow> val \<Rightarrow> cname"
226.5
226.6 translations
226.7 - "cname_of hp v" == "fst (the (hp (the_Addr v)))"
226.8 + "cname_of hp v" == "fst (CONST the (hp (the_Addr v)))"
226.9
226.10
226.11 constdefs
227.1 --- a/src/HOL/MicroJava/J/State.thy Wed Mar 04 11:05:02 2009 +0100
227.2 +++ b/src/HOL/MicroJava/J/State.thy Wed Mar 04 11:05:29 2009 +0100
227.3 @@ -41,7 +41,7 @@
227.4 "Norm s" == "(None,s)"
227.5 "abrupt" => "fst"
227.6 "store" => "snd"
227.7 - "lookup_obj s a'" == "the (heap s (the_Addr a'))"
227.8 + "lookup_obj s a'" == "CONST the (heap s (the_Addr a'))"
227.9
227.10
227.11 constdefs
228.1 --- a/src/HOL/NanoJava/State.thy Wed Mar 04 11:05:02 2009 +0100
228.2 +++ b/src/HOL/NanoJava/State.thy Wed Mar 04 11:05:29 2009 +0100
228.3 @@ -33,7 +33,7 @@
228.4 constdefs
228.5
228.6 init_vars:: "('a \<rightharpoonup> 'b) => ('a \<rightharpoonup> val)"
228.7 - "init_vars m == option_map (\<lambda>T. Null) o m"
228.8 + "init_vars m == Option.map (\<lambda>T. Null) o m"
228.9
228.10 text {* private: *}
228.11 types heap = "loc \<rightharpoonup> obj"
229.1 --- a/src/HOL/Nominal/nominal_atoms.ML Wed Mar 04 11:05:02 2009 +0100
229.2 +++ b/src/HOL/Nominal/nominal_atoms.ML Wed Mar 04 11:05:29 2009 +0100
229.3 @@ -539,7 +539,7 @@
229.4 thy
229.5 |> AxClass.prove_arity ("fun",[[cls_name],[cls_name]],[cls_name]) (pt_proof pt_thm_fun)
229.6 |> AxClass.prove_arity ("Nominal.noption",[[cls_name]],[cls_name]) (pt_proof pt_thm_noptn)
229.7 - |> AxClass.prove_arity ("Datatype.option",[[cls_name]],[cls_name]) (pt_proof pt_thm_optn)
229.8 + |> AxClass.prove_arity ("Option.option",[[cls_name]],[cls_name]) (pt_proof pt_thm_optn)
229.9 |> AxClass.prove_arity ("List.list",[[cls_name]],[cls_name]) (pt_proof pt_thm_list)
229.10 |> AxClass.prove_arity ("*",[[cls_name],[cls_name]],[cls_name]) (pt_proof pt_thm_prod)
229.11 |> AxClass.prove_arity ("Nominal.nprod",[[cls_name],[cls_name]],[cls_name])
229.12 @@ -606,7 +606,7 @@
229.13 |> AxClass.prove_arity ("Nominal.nprod",[[cls_name],[cls_name]],[cls_name])
229.14 (fs_proof fs_thm_nprod)
229.15 |> AxClass.prove_arity ("List.list",[[cls_name]],[cls_name]) (fs_proof fs_thm_list)
229.16 - |> AxClass.prove_arity ("Datatype.option",[[cls_name]],[cls_name]) (fs_proof fs_thm_optn)
229.17 + |> AxClass.prove_arity ("Option.option",[[cls_name]],[cls_name]) (fs_proof fs_thm_optn)
229.18 end) ak_names thy20;
229.19
229.20 (******** cp_<ak>_<ai> class instances ********)
229.21 @@ -687,7 +687,7 @@
229.22 |> AxClass.prove_arity ("*",[[cls_name],[cls_name]],[cls_name]) (cp_proof cp_thm_prod)
229.23 |> AxClass.prove_arity ("List.list",[[cls_name]],[cls_name]) (cp_proof cp_thm_list)
229.24 |> AxClass.prove_arity ("fun",[[cls_name],[cls_name]],[cls_name]) (cp_proof cp_thm_fun)
229.25 - |> AxClass.prove_arity ("Datatype.option",[[cls_name]],[cls_name]) (cp_proof cp_thm_optn)
229.26 + |> AxClass.prove_arity ("Option.option",[[cls_name]],[cls_name]) (cp_proof cp_thm_optn)
229.27 |> AxClass.prove_arity ("Nominal.noption",[[cls_name]],[cls_name]) (cp_proof cp_thm_noptn)
229.28 end) ak_names thy) ak_names thy25;
229.29
230.1 --- a/src/HOL/Polynomial.thy Wed Mar 04 11:05:02 2009 +0100
230.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
230.3 @@ -1,1305 +0,0 @@
230.4 -(* Title: HOL/Polynomial.thy
230.5 - Author: Brian Huffman
230.6 - Based on an earlier development by Clemens Ballarin
230.7 -*)
230.8 -
230.9 -header {* Univariate Polynomials *}
230.10 -
230.11 -theory Polynomial
230.12 -imports Plain SetInterval Main
230.13 -begin
230.14 -
230.15 -subsection {* Definition of type @{text poly} *}
230.16 -
230.17 -typedef (Poly) 'a poly = "{f::nat \<Rightarrow> 'a::zero. \<exists>n. \<forall>i>n. f i = 0}"
230.18 - morphisms coeff Abs_poly
230.19 - by auto
230.20 -
230.21 -lemma expand_poly_eq: "p = q \<longleftrightarrow> (\<forall>n. coeff p n = coeff q n)"
230.22 -by (simp add: coeff_inject [symmetric] expand_fun_eq)
230.23 -
230.24 -lemma poly_ext: "(\<And>n. coeff p n = coeff q n) \<Longrightarrow> p = q"
230.25 -by (simp add: expand_poly_eq)
230.26 -
230.27 -
230.28 -subsection {* Degree of a polynomial *}
230.29 -
230.30 -definition
230.31 - degree :: "'a::zero poly \<Rightarrow> nat" where
230.32 - "degree p = (LEAST n. \<forall>i>n. coeff p i = 0)"
230.33 -
230.34 -lemma coeff_eq_0: "degree p < n \<Longrightarrow> coeff p n = 0"
230.35 -proof -
230.36 - have "coeff p \<in> Poly"
230.37 - by (rule coeff)
230.38 - hence "\<exists>n. \<forall>i>n. coeff p i = 0"
230.39 - unfolding Poly_def by simp
230.40 - hence "\<forall>i>degree p. coeff p i = 0"
230.41 - unfolding degree_def by (rule LeastI_ex)
230.42 - moreover assume "degree p < n"
230.43 - ultimately show ?thesis by simp
230.44 -qed
230.45 -
230.46 -lemma le_degree: "coeff p n \<noteq> 0 \<Longrightarrow> n \<le> degree p"
230.47 - by (erule contrapos_np, rule coeff_eq_0, simp)
230.48 -
230.49 -lemma degree_le: "\<forall>i>n. coeff p i = 0 \<Longrightarrow> degree p \<le> n"
230.50 - unfolding degree_def by (erule Least_le)
230.51 -
230.52 -lemma less_degree_imp: "n < degree p \<Longrightarrow> \<exists>i>n. coeff p i \<noteq> 0"
230.53 - unfolding degree_def by (drule not_less_Least, simp)
230.54 -
230.55 -
230.56 -subsection {* The zero polynomial *}
230.57 -
230.58 -instantiation poly :: (zero) zero
230.59 -begin
230.60 -
230.61 -definition
230.62 - zero_poly_def: "0 = Abs_poly (\<lambda>n. 0)"
230.63 -
230.64 -instance ..
230.65 -end
230.66 -
230.67 -lemma coeff_0 [simp]: "coeff 0 n = 0"
230.68 - unfolding zero_poly_def
230.69 - by (simp add: Abs_poly_inverse Poly_def)
230.70 -
230.71 -lemma degree_0 [simp]: "degree 0 = 0"
230.72 - by (rule order_antisym [OF degree_le le0]) simp
230.73 -
230.74 -lemma leading_coeff_neq_0:
230.75 - assumes "p \<noteq> 0" shows "coeff p (degree p) \<noteq> 0"
230.76 -proof (cases "degree p")
230.77 - case 0
230.78 - from `p \<noteq> 0` have "\<exists>n. coeff p n \<noteq> 0"
230.79 - by (simp add: expand_poly_eq)
230.80 - then obtain n where "coeff p n \<noteq> 0" ..
230.81 - hence "n \<le> degree p" by (rule le_degree)
230.82 - with `coeff p n \<noteq> 0` and `degree p = 0`
230.83 - show "coeff p (degree p) \<noteq> 0" by simp
230.84 -next
230.85 - case (Suc n)
230.86 - from `degree p = Suc n` have "n < degree p" by simp
230.87 - hence "\<exists>i>n. coeff p i \<noteq> 0" by (rule less_degree_imp)
230.88 - then obtain i where "n < i" and "coeff p i \<noteq> 0" by fast
230.89 - from `degree p = Suc n` and `n < i` have "degree p \<le> i" by simp
230.90 - also from `coeff p i \<noteq> 0` have "i \<le> degree p" by (rule le_degree)
230.91 - finally have "degree p = i" .
230.92 - with `coeff p i \<noteq> 0` show "coeff p (degree p) \<noteq> 0" by simp
230.93 -qed
230.94 -
230.95 -lemma leading_coeff_0_iff [simp]: "coeff p (degree p) = 0 \<longleftrightarrow> p = 0"
230.96 - by (cases "p = 0", simp, simp add: leading_coeff_neq_0)
230.97 -
230.98 -
230.99 -subsection {* List-style constructor for polynomials *}
230.100 -
230.101 -definition
230.102 - pCons :: "'a::zero \<Rightarrow> 'a poly \<Rightarrow> 'a poly"
230.103 -where
230.104 - [code del]: "pCons a p = Abs_poly (nat_case a (coeff p))"
230.105 -
230.106 -syntax
230.107 - "_poly" :: "args \<Rightarrow> 'a poly" ("[:(_):]")
230.108 -
230.109 -translations
230.110 - "[:x, xs:]" == "CONST pCons x [:xs:]"
230.111 - "[:x:]" == "CONST pCons x 0"
230.112 -
230.113 -lemma Poly_nat_case: "f \<in> Poly \<Longrightarrow> nat_case a f \<in> Poly"
230.114 - unfolding Poly_def by (auto split: nat.split)
230.115 -
230.116 -lemma coeff_pCons:
230.117 - "coeff (pCons a p) = nat_case a (coeff p)"
230.118 - unfolding pCons_def
230.119 - by (simp add: Abs_poly_inverse Poly_nat_case coeff)
230.120 -
230.121 -lemma coeff_pCons_0 [simp]: "coeff (pCons a p) 0 = a"
230.122 - by (simp add: coeff_pCons)
230.123 -
230.124 -lemma coeff_pCons_Suc [simp]: "coeff (pCons a p) (Suc n) = coeff p n"
230.125 - by (simp add: coeff_pCons)
230.126 -
230.127 -lemma degree_pCons_le: "degree (pCons a p) \<le> Suc (degree p)"
230.128 -by (rule degree_le, simp add: coeff_eq_0 coeff_pCons split: nat.split)
230.129 -
230.130 -lemma degree_pCons_eq:
230.131 - "p \<noteq> 0 \<Longrightarrow> degree (pCons a p) = Suc (degree p)"
230.132 -apply (rule order_antisym [OF degree_pCons_le])
230.133 -apply (rule le_degree, simp)
230.134 -done
230.135 -
230.136 -lemma degree_pCons_0: "degree (pCons a 0) = 0"
230.137 -apply (rule order_antisym [OF _ le0])
230.138 -apply (rule degree_le, simp add: coeff_pCons split: nat.split)
230.139 -done
230.140 -
230.141 -lemma degree_pCons_eq_if [simp]:
230.142 - "degree (pCons a p) = (if p = 0 then 0 else Suc (degree p))"
230.143 -apply (cases "p = 0", simp_all)
230.144 -apply (rule order_antisym [OF _ le0])
230.145 -apply (rule degree_le, simp add: coeff_pCons split: nat.split)
230.146 -apply (rule order_antisym [OF degree_pCons_le])
230.147 -apply (rule le_degree, simp)
230.148 -done
230.149 -
230.150 -lemma pCons_0_0 [simp]: "pCons 0 0 = 0"
230.151 -by (rule poly_ext, simp add: coeff_pCons split: nat.split)
230.152 -
230.153 -lemma pCons_eq_iff [simp]:
230.154 - "pCons a p = pCons b q \<longleftrightarrow> a = b \<and> p = q"
230.155 -proof (safe)
230.156 - assume "pCons a p = pCons b q"
230.157 - then have "coeff (pCons a p) 0 = coeff (pCons b q) 0" by simp
230.158 - then show "a = b" by simp
230.159 -next
230.160 - assume "pCons a p = pCons b q"
230.161 - then have "\<forall>n. coeff (pCons a p) (Suc n) =
230.162 - coeff (pCons b q) (Suc n)" by simp
230.163 - then show "p = q" by (simp add: expand_poly_eq)
230.164 -qed
230.165 -
230.166 -lemma pCons_eq_0_iff [simp]: "pCons a p = 0 \<longleftrightarrow> a = 0 \<and> p = 0"
230.167 - using pCons_eq_iff [of a p 0 0] by simp
230.168 -
230.169 -lemma Poly_Suc: "f \<in> Poly \<Longrightarrow> (\<lambda>n. f (Suc n)) \<in> Poly"
230.170 - unfolding Poly_def
230.171 - by (clarify, rule_tac x=n in exI, simp)
230.172 -
230.173 -lemma pCons_cases [cases type: poly]:
230.174 - obtains (pCons) a q where "p = pCons a q"
230.175 -proof
230.176 - show "p = pCons (coeff p 0) (Abs_poly (\<lambda>n. coeff p (Suc n)))"
230.177 - by (rule poly_ext)
230.178 - (simp add: Abs_poly_inverse Poly_Suc coeff coeff_pCons
230.179 - split: nat.split)
230.180 -qed
230.181 -
230.182 -lemma pCons_induct [case_names 0 pCons, induct type: poly]:
230.183 - assumes zero: "P 0"
230.184 - assumes pCons: "\<And>a p. P p \<Longrightarrow> P (pCons a p)"
230.185 - shows "P p"
230.186 -proof (induct p rule: measure_induct_rule [where f=degree])
230.187 - case (less p)
230.188 - obtain a q where "p = pCons a q" by (rule pCons_cases)
230.189 - have "P q"
230.190 - proof (cases "q = 0")
230.191 - case True
230.192 - then show "P q" by (simp add: zero)
230.193 - next
230.194 - case False
230.195 - then have "degree (pCons a q) = Suc (degree q)"
230.196 - by (rule degree_pCons_eq)
230.197 - then have "degree q < degree p"
230.198 - using `p = pCons a q` by simp
230.199 - then show "P q"
230.200 - by (rule less.hyps)
230.201 - qed
230.202 - then have "P (pCons a q)"
230.203 - by (rule pCons)
230.204 - then show ?case
230.205 - using `p = pCons a q` by simp
230.206 -qed
230.207 -
230.208 -
230.209 -subsection {* Recursion combinator for polynomials *}
230.210 -
230.211 -function
230.212 - poly_rec :: "'b \<Rightarrow> ('a::zero \<Rightarrow> 'a poly \<Rightarrow> 'b \<Rightarrow> 'b) \<Rightarrow> 'a poly \<Rightarrow> 'b"
230.213 -where
230.214 - poly_rec_pCons_eq_if [simp del, code del]:
230.215 - "poly_rec z f (pCons a p) = f a p (if p = 0 then z else poly_rec z f p)"
230.216 -by (case_tac x, rename_tac q, case_tac q, auto)
230.217 -
230.218 -termination poly_rec
230.219 -by (relation "measure (degree \<circ> snd \<circ> snd)", simp)
230.220 - (simp add: degree_pCons_eq)
230.221 -
230.222 -lemma poly_rec_0:
230.223 - "f 0 0 z = z \<Longrightarrow> poly_rec z f 0 = z"
230.224 - using poly_rec_pCons_eq_if [of z f 0 0] by simp
230.225 -
230.226 -lemma poly_rec_pCons:
230.227 - "f 0 0 z = z \<Longrightarrow> poly_rec z f (pCons a p) = f a p (poly_rec z f p)"
230.228 - by (simp add: poly_rec_pCons_eq_if poly_rec_0)
230.229 -
230.230 -
230.231 -subsection {* Monomials *}
230.232 -
230.233 -definition
230.234 - monom :: "'a \<Rightarrow> nat \<Rightarrow> 'a::zero poly" where
230.235 - "monom a m = Abs_poly (\<lambda>n. if m = n then a else 0)"
230.236 -
230.237 -lemma coeff_monom [simp]: "coeff (monom a m) n = (if m=n then a else 0)"
230.238 - unfolding monom_def
230.239 - by (subst Abs_poly_inverse, auto simp add: Poly_def)
230.240 -
230.241 -lemma monom_0: "monom a 0 = pCons a 0"
230.242 - by (rule poly_ext, simp add: coeff_pCons split: nat.split)
230.243 -
230.244 -lemma monom_Suc: "monom a (Suc n) = pCons 0 (monom a n)"
230.245 - by (rule poly_ext, simp add: coeff_pCons split: nat.split)
230.246 -
230.247 -lemma monom_eq_0 [simp]: "monom 0 n = 0"
230.248 - by (rule poly_ext) simp
230.249 -
230.250 -lemma monom_eq_0_iff [simp]: "monom a n = 0 \<longleftrightarrow> a = 0"
230.251 - by (simp add: expand_poly_eq)
230.252 -
230.253 -lemma monom_eq_iff [simp]: "monom a n = monom b n \<longleftrightarrow> a = b"
230.254 - by (simp add: expand_poly_eq)
230.255 -
230.256 -lemma degree_monom_le: "degree (monom a n) \<le> n"
230.257 - by (rule degree_le, simp)
230.258 -
230.259 -lemma degree_monom_eq: "a \<noteq> 0 \<Longrightarrow> degree (monom a n) = n"
230.260 - apply (rule order_antisym [OF degree_monom_le])
230.261 - apply (rule le_degree, simp)
230.262 - done
230.263 -
230.264 -
230.265 -subsection {* Addition and subtraction *}
230.266 -
230.267 -instantiation poly :: (comm_monoid_add) comm_monoid_add
230.268 -begin
230.269 -
230.270 -definition
230.271 - plus_poly_def [code del]:
230.272 - "p + q = Abs_poly (\<lambda>n. coeff p n + coeff q n)"
230.273 -
230.274 -lemma Poly_add:
230.275 - fixes f g :: "nat \<Rightarrow> 'a"
230.276 - shows "\<lbrakk>f \<in> Poly; g \<in> Poly\<rbrakk> \<Longrightarrow> (\<lambda>n. f n + g n) \<in> Poly"
230.277 - unfolding Poly_def
230.278 - apply (clarify, rename_tac m n)
230.279 - apply (rule_tac x="max m n" in exI, simp)
230.280 - done
230.281 -
230.282 -lemma coeff_add [simp]:
230.283 - "coeff (p + q) n = coeff p n + coeff q n"
230.284 - unfolding plus_poly_def
230.285 - by (simp add: Abs_poly_inverse coeff Poly_add)
230.286 -
230.287 -instance proof
230.288 - fix p q r :: "'a poly"
230.289 - show "(p + q) + r = p + (q + r)"
230.290 - by (simp add: expand_poly_eq add_assoc)
230.291 - show "p + q = q + p"
230.292 - by (simp add: expand_poly_eq add_commute)
230.293 - show "0 + p = p"
230.294 - by (simp add: expand_poly_eq)
230.295 -qed
230.296 -
230.297 -end
230.298 -
230.299 -instance poly :: (cancel_comm_monoid_add) cancel_comm_monoid_add
230.300 -proof
230.301 - fix p q r :: "'a poly"
230.302 - assume "p + q = p + r" thus "q = r"
230.303 - by (simp add: expand_poly_eq)
230.304 -qed
230.305 -
230.306 -instantiation poly :: (ab_group_add) ab_group_add
230.307 -begin
230.308 -
230.309 -definition
230.310 - uminus_poly_def [code del]:
230.311 - "- p = Abs_poly (\<lambda>n. - coeff p n)"
230.312 -
230.313 -definition
230.314 - minus_poly_def [code del]:
230.315 - "p - q = Abs_poly (\<lambda>n. coeff p n - coeff q n)"
230.316 -
230.317 -lemma Poly_minus:
230.318 - fixes f :: "nat \<Rightarrow> 'a"
230.319 - shows "f \<in> Poly \<Longrightarrow> (\<lambda>n. - f n) \<in> Poly"
230.320 - unfolding Poly_def by simp
230.321 -
230.322 -lemma Poly_diff:
230.323 - fixes f g :: "nat \<Rightarrow> 'a"
230.324 - shows "\<lbrakk>f \<in> Poly; g \<in> Poly\<rbrakk> \<Longrightarrow> (\<lambda>n. f n - g n) \<in> Poly"
230.325 - unfolding diff_minus by (simp add: Poly_add Poly_minus)
230.326 -
230.327 -lemma coeff_minus [simp]: "coeff (- p) n = - coeff p n"
230.328 - unfolding uminus_poly_def
230.329 - by (simp add: Abs_poly_inverse coeff Poly_minus)
230.330 -
230.331 -lemma coeff_diff [simp]:
230.332 - "coeff (p - q) n = coeff p n - coeff q n"
230.333 - unfolding minus_poly_def
230.334 - by (simp add: Abs_poly_inverse coeff Poly_diff)
230.335 -
230.336 -instance proof
230.337 - fix p q :: "'a poly"
230.338 - show "- p + p = 0"
230.339 - by (simp add: expand_poly_eq)
230.340 - show "p - q = p + - q"
230.341 - by (simp add: expand_poly_eq diff_minus)
230.342 -qed
230.343 -
230.344 -end
230.345 -
230.346 -lemma add_pCons [simp]:
230.347 - "pCons a p + pCons b q = pCons (a + b) (p + q)"
230.348 - by (rule poly_ext, simp add: coeff_pCons split: nat.split)
230.349 -
230.350 -lemma minus_pCons [simp]:
230.351 - "- pCons a p = pCons (- a) (- p)"
230.352 - by (rule poly_ext, simp add: coeff_pCons split: nat.split)
230.353 -
230.354 -lemma diff_pCons [simp]:
230.355 - "pCons a p - pCons b q = pCons (a - b) (p - q)"
230.356 - by (rule poly_ext, simp add: coeff_pCons split: nat.split)
230.357 -
230.358 -lemma degree_add_le_max: "degree (p + q) \<le> max (degree p) (degree q)"
230.359 - by (rule degree_le, auto simp add: coeff_eq_0)
230.360 -
230.361 -lemma degree_add_le:
230.362 - "\<lbrakk>degree p \<le> n; degree q \<le> n\<rbrakk> \<Longrightarrow> degree (p + q) \<le> n"
230.363 - by (auto intro: order_trans degree_add_le_max)
230.364 -
230.365 -lemma degree_add_less:
230.366 - "\<lbrakk>degree p < n; degree q < n\<rbrakk> \<Longrightarrow> degree (p + q) < n"
230.367 - by (auto intro: le_less_trans degree_add_le_max)
230.368 -
230.369 -lemma degree_add_eq_right:
230.370 - "degree p < degree q \<Longrightarrow> degree (p + q) = degree q"
230.371 - apply (cases "q = 0", simp)
230.372 - apply (rule order_antisym)
230.373 - apply (simp add: degree_add_le)
230.374 - apply (rule le_degree)
230.375 - apply (simp add: coeff_eq_0)
230.376 - done
230.377 -
230.378 -lemma degree_add_eq_left:
230.379 - "degree q < degree p \<Longrightarrow> degree (p + q) = degree p"
230.380 - using degree_add_eq_right [of q p]
230.381 - by (simp add: add_commute)
230.382 -
230.383 -lemma degree_minus [simp]: "degree (- p) = degree p"
230.384 - unfolding degree_def by simp
230.385 -
230.386 -lemma degree_diff_le_max: "degree (p - q) \<le> max (degree p) (degree q)"
230.387 - using degree_add_le [where p=p and q="-q"]
230.388 - by (simp add: diff_minus)
230.389 -
230.390 -lemma degree_diff_le:
230.391 - "\<lbrakk>degree p \<le> n; degree q \<le> n\<rbrakk> \<Longrightarrow> degree (p - q) \<le> n"
230.392 - by (simp add: diff_minus degree_add_le)
230.393 -
230.394 -lemma degree_diff_less:
230.395 - "\<lbrakk>degree p < n; degree q < n\<rbrakk> \<Longrightarrow> degree (p - q) < n"
230.396 - by (simp add: diff_minus degree_add_less)
230.397 -
230.398 -lemma add_monom: "monom a n + monom b n = monom (a + b) n"
230.399 - by (rule poly_ext) simp
230.400 -
230.401 -lemma diff_monom: "monom a n - monom b n = monom (a - b) n"
230.402 - by (rule poly_ext) simp
230.403 -
230.404 -lemma minus_monom: "- monom a n = monom (-a) n"
230.405 - by (rule poly_ext) simp
230.406 -
230.407 -lemma coeff_setsum: "coeff (\<Sum>x\<in>A. p x) i = (\<Sum>x\<in>A. coeff (p x) i)"
230.408 - by (cases "finite A", induct set: finite, simp_all)
230.409 -
230.410 -lemma monom_setsum: "monom (\<Sum>x\<in>A. a x) n = (\<Sum>x\<in>A. monom (a x) n)"
230.411 - by (rule poly_ext) (simp add: coeff_setsum)
230.412 -
230.413 -
230.414 -subsection {* Multiplication by a constant *}
230.415 -
230.416 -definition
230.417 - smult :: "'a::comm_semiring_0 \<Rightarrow> 'a poly \<Rightarrow> 'a poly" where
230.418 - "smult a p = Abs_poly (\<lambda>n. a * coeff p n)"
230.419 -
230.420 -lemma Poly_smult:
230.421 - fixes f :: "nat \<Rightarrow> 'a::comm_semiring_0"
230.422 - shows "f \<in> Poly \<Longrightarrow> (\<lambda>n. a * f n) \<in> Poly"
230.423 - unfolding Poly_def
230.424 - by (clarify, rule_tac x=n in exI, simp)
230.425 -
230.426 -lemma coeff_smult [simp]: "coeff (smult a p) n = a * coeff p n"
230.427 - unfolding smult_def
230.428 - by (simp add: Abs_poly_inverse Poly_smult coeff)
230.429 -
230.430 -lemma degree_smult_le: "degree (smult a p) \<le> degree p"
230.431 - by (rule degree_le, simp add: coeff_eq_0)
230.432 -
230.433 -lemma smult_smult [simp]: "smult a (smult b p) = smult (a * b) p"
230.434 - by (rule poly_ext, simp add: mult_assoc)
230.435 -
230.436 -lemma smult_0_right [simp]: "smult a 0 = 0"
230.437 - by (rule poly_ext, simp)
230.438 -
230.439 -lemma smult_0_left [simp]: "smult 0 p = 0"
230.440 - by (rule poly_ext, simp)
230.441 -
230.442 -lemma smult_1_left [simp]: "smult (1::'a::comm_semiring_1) p = p"
230.443 - by (rule poly_ext, simp)
230.444 -
230.445 -lemma smult_add_right:
230.446 - "smult a (p + q) = smult a p + smult a q"
230.447 - by (rule poly_ext, simp add: algebra_simps)
230.448 -
230.449 -lemma smult_add_left:
230.450 - "smult (a + b) p = smult a p + smult b p"
230.451 - by (rule poly_ext, simp add: algebra_simps)
230.452 -
230.453 -lemma smult_minus_right [simp]:
230.454 - "smult (a::'a::comm_ring) (- p) = - smult a p"
230.455 - by (rule poly_ext, simp)
230.456 -
230.457 -lemma smult_minus_left [simp]:
230.458 - "smult (- a::'a::comm_ring) p = - smult a p"
230.459 - by (rule poly_ext, simp)
230.460 -
230.461 -lemma smult_diff_right:
230.462 - "smult (a::'a::comm_ring) (p - q) = smult a p - smult a q"
230.463 - by (rule poly_ext, simp add: algebra_simps)
230.464 -
230.465 -lemma smult_diff_left:
230.466 - "smult (a - b::'a::comm_ring) p = smult a p - smult b p"
230.467 - by (rule poly_ext, simp add: algebra_simps)
230.468 -
230.469 -lemmas smult_distribs =
230.470 - smult_add_left smult_add_right
230.471 - smult_diff_left smult_diff_right
230.472 -
230.473 -lemma smult_pCons [simp]:
230.474 - "smult a (pCons b p) = pCons (a * b) (smult a p)"
230.475 - by (rule poly_ext, simp add: coeff_pCons split: nat.split)
230.476 -
230.477 -lemma smult_monom: "smult a (monom b n) = monom (a * b) n"
230.478 - by (induct n, simp add: monom_0, simp add: monom_Suc)
230.479 -
230.480 -lemma degree_smult_eq [simp]:
230.481 - fixes a :: "'a::idom"
230.482 - shows "degree (smult a p) = (if a = 0 then 0 else degree p)"
230.483 - by (cases "a = 0", simp, simp add: degree_def)
230.484 -
230.485 -lemma smult_eq_0_iff [simp]:
230.486 - fixes a :: "'a::idom"
230.487 - shows "smult a p = 0 \<longleftrightarrow> a = 0 \<or> p = 0"
230.488 - by (simp add: expand_poly_eq)
230.489 -
230.490 -
230.491 -subsection {* Multiplication of polynomials *}
230.492 -
230.493 -text {* TODO: move to SetInterval.thy *}
230.494 -lemma setsum_atMost_Suc_shift:
230.495 - fixes f :: "nat \<Rightarrow> 'a::comm_monoid_add"
230.496 - shows "(\<Sum>i\<le>Suc n. f i) = f 0 + (\<Sum>i\<le>n. f (Suc i))"
230.497 -proof (induct n)
230.498 - case 0 show ?case by simp
230.499 -next
230.500 - case (Suc n) note IH = this
230.501 - have "(\<Sum>i\<le>Suc (Suc n). f i) = (\<Sum>i\<le>Suc n. f i) + f (Suc (Suc n))"
230.502 - by (rule setsum_atMost_Suc)
230.503 - also have "(\<Sum>i\<le>Suc n. f i) = f 0 + (\<Sum>i\<le>n. f (Suc i))"
230.504 - by (rule IH)
230.505 - also have "f 0 + (\<Sum>i\<le>n. f (Suc i)) + f (Suc (Suc n)) =
230.506 - f 0 + ((\<Sum>i\<le>n. f (Suc i)) + f (Suc (Suc n)))"
230.507 - by (rule add_assoc)
230.508 - also have "(\<Sum>i\<le>n. f (Suc i)) + f (Suc (Suc n)) = (\<Sum>i\<le>Suc n. f (Suc i))"
230.509 - by (rule setsum_atMost_Suc [symmetric])
230.510 - finally show ?case .
230.511 -qed
230.512 -
230.513 -instantiation poly :: (comm_semiring_0) comm_semiring_0
230.514 -begin
230.515 -
230.516 -definition
230.517 - times_poly_def [code del]:
230.518 - "p * q = poly_rec 0 (\<lambda>a p pq. smult a q + pCons 0 pq) p"
230.519 -
230.520 -lemma mult_poly_0_left: "(0::'a poly) * q = 0"
230.521 - unfolding times_poly_def by (simp add: poly_rec_0)
230.522 -
230.523 -lemma mult_pCons_left [simp]:
230.524 - "pCons a p * q = smult a q + pCons 0 (p * q)"
230.525 - unfolding times_poly_def by (simp add: poly_rec_pCons)
230.526 -
230.527 -lemma mult_poly_0_right: "p * (0::'a poly) = 0"
230.528 - by (induct p, simp add: mult_poly_0_left, simp)
230.529 -
230.530 -lemma mult_pCons_right [simp]:
230.531 - "p * pCons a q = smult a p + pCons 0 (p * q)"
230.532 - by (induct p, simp add: mult_poly_0_left, simp add: algebra_simps)
230.533 -
230.534 -lemmas mult_poly_0 = mult_poly_0_left mult_poly_0_right
230.535 -
230.536 -lemma mult_smult_left [simp]: "smult a p * q = smult a (p * q)"
230.537 - by (induct p, simp add: mult_poly_0, simp add: smult_add_right)
230.538 -
230.539 -lemma mult_smult_right [simp]: "p * smult a q = smult a (p * q)"
230.540 - by (induct q, simp add: mult_poly_0, simp add: smult_add_right)
230.541 -
230.542 -lemma mult_poly_add_left:
230.543 - fixes p q r :: "'a poly"
230.544 - shows "(p + q) * r = p * r + q * r"
230.545 - by (induct r, simp add: mult_poly_0,
230.546 - simp add: smult_distribs algebra_simps)
230.547 -
230.548 -instance proof
230.549 - fix p q r :: "'a poly"
230.550 - show 0: "0 * p = 0"
230.551 - by (rule mult_poly_0_left)
230.552 - show "p * 0 = 0"
230.553 - by (rule mult_poly_0_right)
230.554 - show "(p + q) * r = p * r + q * r"
230.555 - by (rule mult_poly_add_left)
230.556 - show "(p * q) * r = p * (q * r)"
230.557 - by (induct p, simp add: mult_poly_0, simp add: mult_poly_add_left)
230.558 - show "p * q = q * p"
230.559 - by (induct p, simp add: mult_poly_0, simp)
230.560 -qed
230.561 -
230.562 -end
230.563 -
230.564 -instance poly :: (comm_semiring_0_cancel) comm_semiring_0_cancel ..
230.565 -
230.566 -lemma coeff_mult:
230.567 - "coeff (p * q) n = (\<Sum>i\<le>n. coeff p i * coeff q (n-i))"
230.568 -proof (induct p arbitrary: n)
230.569 - case 0 show ?case by simp
230.570 -next
230.571 - case (pCons a p n) thus ?case
230.572 - by (cases n, simp, simp add: setsum_atMost_Suc_shift
230.573 - del: setsum_atMost_Suc)
230.574 -qed
230.575 -
230.576 -lemma degree_mult_le: "degree (p * q) \<le> degree p + degree q"
230.577 -apply (rule degree_le)
230.578 -apply (induct p)
230.579 -apply simp
230.580 -apply (simp add: coeff_eq_0 coeff_pCons split: nat.split)
230.581 -done
230.582 -
230.583 -lemma mult_monom: "monom a m * monom b n = monom (a * b) (m + n)"
230.584 - by (induct m, simp add: monom_0 smult_monom, simp add: monom_Suc)
230.585 -
230.586 -
230.587 -subsection {* The unit polynomial and exponentiation *}
230.588 -
230.589 -instantiation poly :: (comm_semiring_1) comm_semiring_1
230.590 -begin
230.591 -
230.592 -definition
230.593 - one_poly_def:
230.594 - "1 = pCons 1 0"
230.595 -
230.596 -instance proof
230.597 - fix p :: "'a poly" show "1 * p = p"
230.598 - unfolding one_poly_def
230.599 - by simp
230.600 -next
230.601 - show "0 \<noteq> (1::'a poly)"
230.602 - unfolding one_poly_def by simp
230.603 -qed
230.604 -
230.605 -end
230.606 -
230.607 -instance poly :: (comm_semiring_1_cancel) comm_semiring_1_cancel ..
230.608 -
230.609 -lemma coeff_1 [simp]: "coeff 1 n = (if n = 0 then 1 else 0)"
230.610 - unfolding one_poly_def
230.611 - by (simp add: coeff_pCons split: nat.split)
230.612 -
230.613 -lemma degree_1 [simp]: "degree 1 = 0"
230.614 - unfolding one_poly_def
230.615 - by (rule degree_pCons_0)
230.616 -
230.617 -instantiation poly :: (comm_semiring_1) recpower
230.618 -begin
230.619 -
230.620 -primrec power_poly where
230.621 - power_poly_0: "(p::'a poly) ^ 0 = 1"
230.622 -| power_poly_Suc: "(p::'a poly) ^ (Suc n) = p * p ^ n"
230.623 -
230.624 -instance
230.625 - by default simp_all
230.626 -
230.627 -end
230.628 -
230.629 -instance poly :: (comm_ring) comm_ring ..
230.630 -
230.631 -instance poly :: (comm_ring_1) comm_ring_1 ..
230.632 -
230.633 -instantiation poly :: (comm_ring_1) number_ring
230.634 -begin
230.635 -
230.636 -definition
230.637 - "number_of k = (of_int k :: 'a poly)"
230.638 -
230.639 -instance
230.640 - by default (rule number_of_poly_def)
230.641 -
230.642 -end
230.643 -
230.644 -
230.645 -subsection {* Polynomials form an integral domain *}
230.646 -
230.647 -lemma coeff_mult_degree_sum:
230.648 - "coeff (p * q) (degree p + degree q) =
230.649 - coeff p (degree p) * coeff q (degree q)"
230.650 - by (induct p, simp, simp add: coeff_eq_0)
230.651 -
230.652 -instance poly :: (idom) idom
230.653 -proof
230.654 - fix p q :: "'a poly"
230.655 - assume "p \<noteq> 0" and "q \<noteq> 0"
230.656 - have "coeff (p * q) (degree p + degree q) =
230.657 - coeff p (degree p) * coeff q (degree q)"
230.658 - by (rule coeff_mult_degree_sum)
230.659 - also have "coeff p (degree p) * coeff q (degree q) \<noteq> 0"
230.660 - using `p \<noteq> 0` and `q \<noteq> 0` by simp
230.661 - finally have "\<exists>n. coeff (p * q) n \<noteq> 0" ..
230.662 - thus "p * q \<noteq> 0" by (simp add: expand_poly_eq)
230.663 -qed
230.664 -
230.665 -lemma degree_mult_eq:
230.666 - fixes p q :: "'a::idom poly"
230.667 - shows "\<lbrakk>p \<noteq> 0; q \<noteq> 0\<rbrakk> \<Longrightarrow> degree (p * q) = degree p + degree q"
230.668 -apply (rule order_antisym [OF degree_mult_le le_degree])
230.669 -apply (simp add: coeff_mult_degree_sum)
230.670 -done
230.671 -
230.672 -lemma dvd_imp_degree_le:
230.673 - fixes p q :: "'a::idom poly"
230.674 - shows "\<lbrakk>p dvd q; q \<noteq> 0\<rbrakk> \<Longrightarrow> degree p \<le> degree q"
230.675 - by (erule dvdE, simp add: degree_mult_eq)
230.676 -
230.677 -
230.678 -subsection {* Polynomials form an ordered integral domain *}
230.679 -
230.680 -definition
230.681 - pos_poly :: "'a::ordered_idom poly \<Rightarrow> bool"
230.682 -where
230.683 - "pos_poly p \<longleftrightarrow> 0 < coeff p (degree p)"
230.684 -
230.685 -lemma pos_poly_pCons:
230.686 - "pos_poly (pCons a p) \<longleftrightarrow> pos_poly p \<or> (p = 0 \<and> 0 < a)"
230.687 - unfolding pos_poly_def by simp
230.688 -
230.689 -lemma not_pos_poly_0 [simp]: "\<not> pos_poly 0"
230.690 - unfolding pos_poly_def by simp
230.691 -
230.692 -lemma pos_poly_add: "\<lbrakk>pos_poly p; pos_poly q\<rbrakk> \<Longrightarrow> pos_poly (p + q)"
230.693 - apply (induct p arbitrary: q, simp)
230.694 - apply (case_tac q, force simp add: pos_poly_pCons add_pos_pos)
230.695 - done
230.696 -
230.697 -lemma pos_poly_mult: "\<lbrakk>pos_poly p; pos_poly q\<rbrakk> \<Longrightarrow> pos_poly (p * q)"
230.698 - unfolding pos_poly_def
230.699 - apply (subgoal_tac "p \<noteq> 0 \<and> q \<noteq> 0")
230.700 - apply (simp add: degree_mult_eq coeff_mult_degree_sum mult_pos_pos)
230.701 - apply auto
230.702 - done
230.703 -
230.704 -lemma pos_poly_total: "p = 0 \<or> pos_poly p \<or> pos_poly (- p)"
230.705 -by (induct p) (auto simp add: pos_poly_pCons)
230.706 -
230.707 -instantiation poly :: (ordered_idom) ordered_idom
230.708 -begin
230.709 -
230.710 -definition
230.711 - [code del]:
230.712 - "x < y \<longleftrightarrow> pos_poly (y - x)"
230.713 -
230.714 -definition
230.715 - [code del]:
230.716 - "x \<le> y \<longleftrightarrow> x = y \<or> pos_poly (y - x)"
230.717 -
230.718 -definition
230.719 - [code del]:
230.720 - "abs (x::'a poly) = (if x < 0 then - x else x)"
230.721 -
230.722 -definition
230.723 - [code del]:
230.724 - "sgn (x::'a poly) = (if x = 0 then 0 else if 0 < x then 1 else - 1)"
230.725 -
230.726 -instance proof
230.727 - fix x y :: "'a poly"
230.728 - show "x < y \<longleftrightarrow> x \<le> y \<and> \<not> y \<le> x"
230.729 - unfolding less_eq_poly_def less_poly_def
230.730 - apply safe
230.731 - apply simp
230.732 - apply (drule (1) pos_poly_add)
230.733 - apply simp
230.734 - done
230.735 -next
230.736 - fix x :: "'a poly" show "x \<le> x"
230.737 - unfolding less_eq_poly_def by simp
230.738 -next
230.739 - fix x y z :: "'a poly"
230.740 - assume "x \<le> y" and "y \<le> z" thus "x \<le> z"
230.741 - unfolding less_eq_poly_def
230.742 - apply safe
230.743 - apply (drule (1) pos_poly_add)
230.744 - apply (simp add: algebra_simps)
230.745 - done
230.746 -next
230.747 - fix x y :: "'a poly"
230.748 - assume "x \<le> y" and "y \<le> x" thus "x = y"
230.749 - unfolding less_eq_poly_def
230.750 - apply safe
230.751 - apply (drule (1) pos_poly_add)
230.752 - apply simp
230.753 - done
230.754 -next
230.755 - fix x y z :: "'a poly"
230.756 - assume "x \<le> y" thus "z + x \<le> z + y"
230.757 - unfolding less_eq_poly_def
230.758 - apply safe
230.759 - apply (simp add: algebra_simps)
230.760 - done
230.761 -next
230.762 - fix x y :: "'a poly"
230.763 - show "x \<le> y \<or> y \<le> x"
230.764 - unfolding less_eq_poly_def
230.765 - using pos_poly_total [of "x - y"]
230.766 - by auto
230.767 -next
230.768 - fix x y z :: "'a poly"
230.769 - assume "x < y" and "0 < z"
230.770 - thus "z * x < z * y"
230.771 - unfolding less_poly_def
230.772 - by (simp add: right_diff_distrib [symmetric] pos_poly_mult)
230.773 -next
230.774 - fix x :: "'a poly"
230.775 - show "\<bar>x\<bar> = (if x < 0 then - x else x)"
230.776 - by (rule abs_poly_def)
230.777 -next
230.778 - fix x :: "'a poly"
230.779 - show "sgn x = (if x = 0 then 0 else if 0 < x then 1 else - 1)"
230.780 - by (rule sgn_poly_def)
230.781 -qed
230.782 -
230.783 -end
230.784 -
230.785 -text {* TODO: Simplification rules for comparisons *}
230.786 -
230.787 -
230.788 -subsection {* Long division of polynomials *}
230.789 -
230.790 -definition
230.791 - pdivmod_rel :: "'a::field poly \<Rightarrow> 'a poly \<Rightarrow> 'a poly \<Rightarrow> 'a poly \<Rightarrow> bool"
230.792 -where
230.793 - [code del]:
230.794 - "pdivmod_rel x y q r \<longleftrightarrow>
230.795 - x = q * y + r \<and> (if y = 0 then q = 0 else r = 0 \<or> degree r < degree y)"
230.796 -
230.797 -lemma pdivmod_rel_0:
230.798 - "pdivmod_rel 0 y 0 0"
230.799 - unfolding pdivmod_rel_def by simp
230.800 -
230.801 -lemma pdivmod_rel_by_0:
230.802 - "pdivmod_rel x 0 0 x"
230.803 - unfolding pdivmod_rel_def by simp
230.804 -
230.805 -lemma eq_zero_or_degree_less:
230.806 - assumes "degree p \<le> n" and "coeff p n = 0"
230.807 - shows "p = 0 \<or> degree p < n"
230.808 -proof (cases n)
230.809 - case 0
230.810 - with `degree p \<le> n` and `coeff p n = 0`
230.811 - have "coeff p (degree p) = 0" by simp
230.812 - then have "p = 0" by simp
230.813 - then show ?thesis ..
230.814 -next
230.815 - case (Suc m)
230.816 - have "\<forall>i>n. coeff p i = 0"
230.817 - using `degree p \<le> n` by (simp add: coeff_eq_0)
230.818 - then have "\<forall>i\<ge>n. coeff p i = 0"
230.819 - using `coeff p n = 0` by (simp add: le_less)
230.820 - then have "\<forall>i>m. coeff p i = 0"
230.821 - using `n = Suc m` by (simp add: less_eq_Suc_le)
230.822 - then have "degree p \<le> m"
230.823 - by (rule degree_le)
230.824 - then have "degree p < n"
230.825 - using `n = Suc m` by (simp add: less_Suc_eq_le)
230.826 - then show ?thesis ..
230.827 -qed
230.828 -
230.829 -lemma pdivmod_rel_pCons:
230.830 - assumes rel: "pdivmod_rel x y q r"
230.831 - assumes y: "y \<noteq> 0"
230.832 - assumes b: "b = coeff (pCons a r) (degree y) / coeff y (degree y)"
230.833 - shows "pdivmod_rel (pCons a x) y (pCons b q) (pCons a r - smult b y)"
230.834 - (is "pdivmod_rel ?x y ?q ?r")
230.835 -proof -
230.836 - have x: "x = q * y + r" and r: "r = 0 \<or> degree r < degree y"
230.837 - using assms unfolding pdivmod_rel_def by simp_all
230.838 -
230.839 - have 1: "?x = ?q * y + ?r"
230.840 - using b x by simp
230.841 -
230.842 - have 2: "?r = 0 \<or> degree ?r < degree y"
230.843 - proof (rule eq_zero_or_degree_less)
230.844 - show "degree ?r \<le> degree y"
230.845 - proof (rule degree_diff_le)
230.846 - show "degree (pCons a r) \<le> degree y"
230.847 - using r by auto
230.848 - show "degree (smult b y) \<le> degree y"
230.849 - by (rule degree_smult_le)
230.850 - qed
230.851 - next
230.852 - show "coeff ?r (degree y) = 0"
230.853 - using `y \<noteq> 0` unfolding b by simp
230.854 - qed
230.855 -
230.856 - from 1 2 show ?thesis
230.857 - unfolding pdivmod_rel_def
230.858 - using `y \<noteq> 0` by simp
230.859 -qed
230.860 -
230.861 -lemma pdivmod_rel_exists: "\<exists>q r. pdivmod_rel x y q r"
230.862 -apply (cases "y = 0")
230.863 -apply (fast intro!: pdivmod_rel_by_0)
230.864 -apply (induct x)
230.865 -apply (fast intro!: pdivmod_rel_0)
230.866 -apply (fast intro!: pdivmod_rel_pCons)
230.867 -done
230.868 -
230.869 -lemma pdivmod_rel_unique:
230.870 - assumes 1: "pdivmod_rel x y q1 r1"
230.871 - assumes 2: "pdivmod_rel x y q2 r2"
230.872 - shows "q1 = q2 \<and> r1 = r2"
230.873 -proof (cases "y = 0")
230.874 - assume "y = 0" with assms show ?thesis
230.875 - by (simp add: pdivmod_rel_def)
230.876 -next
230.877 - assume [simp]: "y \<noteq> 0"
230.878 - from 1 have q1: "x = q1 * y + r1" and r1: "r1 = 0 \<or> degree r1 < degree y"
230.879 - unfolding pdivmod_rel_def by simp_all
230.880 - from 2 have q2: "x = q2 * y + r2" and r2: "r2 = 0 \<or> degree r2 < degree y"
230.881 - unfolding pdivmod_rel_def by simp_all
230.882 - from q1 q2 have q3: "(q1 - q2) * y = r2 - r1"
230.883 - by (simp add: algebra_simps)
230.884 - from r1 r2 have r3: "(r2 - r1) = 0 \<or> degree (r2 - r1) < degree y"
230.885 - by (auto intro: degree_diff_less)
230.886 -
230.887 - show "q1 = q2 \<and> r1 = r2"
230.888 - proof (rule ccontr)
230.889 - assume "\<not> (q1 = q2 \<and> r1 = r2)"
230.890 - with q3 have "q1 \<noteq> q2" and "r1 \<noteq> r2" by auto
230.891 - with r3 have "degree (r2 - r1) < degree y" by simp
230.892 - also have "degree y \<le> degree (q1 - q2) + degree y" by simp
230.893 - also have "\<dots> = degree ((q1 - q2) * y)"
230.894 - using `q1 \<noteq> q2` by (simp add: degree_mult_eq)
230.895 - also have "\<dots> = degree (r2 - r1)"
230.896 - using q3 by simp
230.897 - finally have "degree (r2 - r1) < degree (r2 - r1)" .
230.898 - then show "False" by simp
230.899 - qed
230.900 -qed
230.901 -
230.902 -lemma pdivmod_rel_0_iff: "pdivmod_rel 0 y q r \<longleftrightarrow> q = 0 \<and> r = 0"
230.903 -by (auto dest: pdivmod_rel_unique intro: pdivmod_rel_0)
230.904 -
230.905 -lemma pdivmod_rel_by_0_iff: "pdivmod_rel x 0 q r \<longleftrightarrow> q = 0 \<and> r = x"
230.906 -by (auto dest: pdivmod_rel_unique intro: pdivmod_rel_by_0)
230.907 -
230.908 -lemmas pdivmod_rel_unique_div =
230.909 - pdivmod_rel_unique [THEN conjunct1, standard]
230.910 -
230.911 -lemmas pdivmod_rel_unique_mod =
230.912 - pdivmod_rel_unique [THEN conjunct2, standard]
230.913 -
230.914 -instantiation poly :: (field) ring_div
230.915 -begin
230.916 -
230.917 -definition div_poly where
230.918 - [code del]: "x div y = (THE q. \<exists>r. pdivmod_rel x y q r)"
230.919 -
230.920 -definition mod_poly where
230.921 - [code del]: "x mod y = (THE r. \<exists>q. pdivmod_rel x y q r)"
230.922 -
230.923 -lemma div_poly_eq:
230.924 - "pdivmod_rel x y q r \<Longrightarrow> x div y = q"
230.925 -unfolding div_poly_def
230.926 -by (fast elim: pdivmod_rel_unique_div)
230.927 -
230.928 -lemma mod_poly_eq:
230.929 - "pdivmod_rel x y q r \<Longrightarrow> x mod y = r"
230.930 -unfolding mod_poly_def
230.931 -by (fast elim: pdivmod_rel_unique_mod)
230.932 -
230.933 -lemma pdivmod_rel:
230.934 - "pdivmod_rel x y (x div y) (x mod y)"
230.935 -proof -
230.936 - from pdivmod_rel_exists
230.937 - obtain q r where "pdivmod_rel x y q r" by fast
230.938 - thus ?thesis
230.939 - by (simp add: div_poly_eq mod_poly_eq)
230.940 -qed
230.941 -
230.942 -instance proof
230.943 - fix x y :: "'a poly"
230.944 - show "x div y * y + x mod y = x"
230.945 - using pdivmod_rel [of x y]
230.946 - by (simp add: pdivmod_rel_def)
230.947 -next
230.948 - fix x :: "'a poly"
230.949 - have "pdivmod_rel x 0 0 x"
230.950 - by (rule pdivmod_rel_by_0)
230.951 - thus "x div 0 = 0"
230.952 - by (rule div_poly_eq)
230.953 -next
230.954 - fix y :: "'a poly"
230.955 - have "pdivmod_rel 0 y 0 0"
230.956 - by (rule pdivmod_rel_0)
230.957 - thus "0 div y = 0"
230.958 - by (rule div_poly_eq)
230.959 -next
230.960 - fix x y z :: "'a poly"
230.961 - assume "y \<noteq> 0"
230.962 - hence "pdivmod_rel (x + z * y) y (z + x div y) (x mod y)"
230.963 - using pdivmod_rel [of x y]
230.964 - by (simp add: pdivmod_rel_def left_distrib)
230.965 - thus "(x + z * y) div y = z + x div y"
230.966 - by (rule div_poly_eq)
230.967 -qed
230.968 -
230.969 -end
230.970 -
230.971 -lemma degree_mod_less:
230.972 - "y \<noteq> 0 \<Longrightarrow> x mod y = 0 \<or> degree (x mod y) < degree y"
230.973 - using pdivmod_rel [of x y]
230.974 - unfolding pdivmod_rel_def by simp
230.975 -
230.976 -lemma div_poly_less: "degree x < degree y \<Longrightarrow> x div y = 0"
230.977 -proof -
230.978 - assume "degree x < degree y"
230.979 - hence "pdivmod_rel x y 0 x"
230.980 - by (simp add: pdivmod_rel_def)
230.981 - thus "x div y = 0" by (rule div_poly_eq)
230.982 -qed
230.983 -
230.984 -lemma mod_poly_less: "degree x < degree y \<Longrightarrow> x mod y = x"
230.985 -proof -
230.986 - assume "degree x < degree y"
230.987 - hence "pdivmod_rel x y 0 x"
230.988 - by (simp add: pdivmod_rel_def)
230.989 - thus "x mod y = x" by (rule mod_poly_eq)
230.990 -qed
230.991 -
230.992 -lemma pdivmod_rel_smult_left:
230.993 - "pdivmod_rel x y q r
230.994 - \<Longrightarrow> pdivmod_rel (smult a x) y (smult a q) (smult a r)"
230.995 - unfolding pdivmod_rel_def by (simp add: smult_add_right)
230.996 -
230.997 -lemma div_smult_left: "(smult a x) div y = smult a (x div y)"
230.998 - by (rule div_poly_eq, rule pdivmod_rel_smult_left, rule pdivmod_rel)
230.999 -
230.1000 -lemma mod_smult_left: "(smult a x) mod y = smult a (x mod y)"
230.1001 - by (rule mod_poly_eq, rule pdivmod_rel_smult_left, rule pdivmod_rel)
230.1002 -
230.1003 -lemma pdivmod_rel_smult_right:
230.1004 - "\<lbrakk>a \<noteq> 0; pdivmod_rel x y q r\<rbrakk>
230.1005 - \<Longrightarrow> pdivmod_rel x (smult a y) (smult (inverse a) q) r"
230.1006 - unfolding pdivmod_rel_def by simp
230.1007 -
230.1008 -lemma div_smult_right:
230.1009 - "a \<noteq> 0 \<Longrightarrow> x div (smult a y) = smult (inverse a) (x div y)"
230.1010 - by (rule div_poly_eq, erule pdivmod_rel_smult_right, rule pdivmod_rel)
230.1011 -
230.1012 -lemma mod_smult_right: "a \<noteq> 0 \<Longrightarrow> x mod (smult a y) = x mod y"
230.1013 - by (rule mod_poly_eq, erule pdivmod_rel_smult_right, rule pdivmod_rel)
230.1014 -
230.1015 -lemma pdivmod_rel_mult:
230.1016 - "\<lbrakk>pdivmod_rel x y q r; pdivmod_rel q z q' r'\<rbrakk>
230.1017 - \<Longrightarrow> pdivmod_rel x (y * z) q' (y * r' + r)"
230.1018 -apply (cases "z = 0", simp add: pdivmod_rel_def)
230.1019 -apply (cases "y = 0", simp add: pdivmod_rel_by_0_iff pdivmod_rel_0_iff)
230.1020 -apply (cases "r = 0")
230.1021 -apply (cases "r' = 0")
230.1022 -apply (simp add: pdivmod_rel_def)
230.1023 -apply (simp add: pdivmod_rel_def ring_simps degree_mult_eq)
230.1024 -apply (cases "r' = 0")
230.1025 -apply (simp add: pdivmod_rel_def degree_mult_eq)
230.1026 -apply (simp add: pdivmod_rel_def ring_simps)
230.1027 -apply (simp add: degree_mult_eq degree_add_less)
230.1028 -done
230.1029 -
230.1030 -lemma poly_div_mult_right:
230.1031 - fixes x y z :: "'a::field poly"
230.1032 - shows "x div (y * z) = (x div y) div z"
230.1033 - by (rule div_poly_eq, rule pdivmod_rel_mult, (rule pdivmod_rel)+)
230.1034 -
230.1035 -lemma poly_mod_mult_right:
230.1036 - fixes x y z :: "'a::field poly"
230.1037 - shows "x mod (y * z) = y * (x div y mod z) + x mod y"
230.1038 - by (rule mod_poly_eq, rule pdivmod_rel_mult, (rule pdivmod_rel)+)
230.1039 -
230.1040 -lemma mod_pCons:
230.1041 - fixes a and x
230.1042 - assumes y: "y \<noteq> 0"
230.1043 - defines b: "b \<equiv> coeff (pCons a (x mod y)) (degree y) / coeff y (degree y)"
230.1044 - shows "(pCons a x) mod y = (pCons a (x mod y) - smult b y)"
230.1045 -unfolding b
230.1046 -apply (rule mod_poly_eq)
230.1047 -apply (rule pdivmod_rel_pCons [OF pdivmod_rel y refl])
230.1048 -done
230.1049 -
230.1050 -
230.1051 -subsection {* Evaluation of polynomials *}
230.1052 -
230.1053 -definition
230.1054 - poly :: "'a::comm_semiring_0 poly \<Rightarrow> 'a \<Rightarrow> 'a" where
230.1055 - "poly = poly_rec (\<lambda>x. 0) (\<lambda>a p f x. a + x * f x)"
230.1056 -
230.1057 -lemma poly_0 [simp]: "poly 0 x = 0"
230.1058 - unfolding poly_def by (simp add: poly_rec_0)
230.1059 -
230.1060 -lemma poly_pCons [simp]: "poly (pCons a p) x = a + x * poly p x"
230.1061 - unfolding poly_def by (simp add: poly_rec_pCons)
230.1062 -
230.1063 -lemma poly_1 [simp]: "poly 1 x = 1"
230.1064 - unfolding one_poly_def by simp
230.1065 -
230.1066 -lemma poly_monom:
230.1067 - fixes a x :: "'a::{comm_semiring_1,recpower}"
230.1068 - shows "poly (monom a n) x = a * x ^ n"
230.1069 - by (induct n, simp add: monom_0, simp add: monom_Suc power_Suc mult_ac)
230.1070 -
230.1071 -lemma poly_add [simp]: "poly (p + q) x = poly p x + poly q x"
230.1072 - apply (induct p arbitrary: q, simp)
230.1073 - apply (case_tac q, simp, simp add: algebra_simps)
230.1074 - done
230.1075 -
230.1076 -lemma poly_minus [simp]:
230.1077 - fixes x :: "'a::comm_ring"
230.1078 - shows "poly (- p) x = - poly p x"
230.1079 - by (induct p, simp_all)
230.1080 -
230.1081 -lemma poly_diff [simp]:
230.1082 - fixes x :: "'a::comm_ring"
230.1083 - shows "poly (p - q) x = poly p x - poly q x"
230.1084 - by (simp add: diff_minus)
230.1085 -
230.1086 -lemma poly_setsum: "poly (\<Sum>k\<in>A. p k) x = (\<Sum>k\<in>A. poly (p k) x)"
230.1087 - by (cases "finite A", induct set: finite, simp_all)
230.1088 -
230.1089 -lemma poly_smult [simp]: "poly (smult a p) x = a * poly p x"
230.1090 - by (induct p, simp, simp add: algebra_simps)
230.1091 -
230.1092 -lemma poly_mult [simp]: "poly (p * q) x = poly p x * poly q x"
230.1093 - by (induct p, simp_all, simp add: algebra_simps)
230.1094 -
230.1095 -lemma poly_power [simp]:
230.1096 - fixes p :: "'a::{comm_semiring_1,recpower} poly"
230.1097 - shows "poly (p ^ n) x = poly p x ^ n"
230.1098 - by (induct n, simp, simp add: power_Suc)
230.1099 -
230.1100 -
230.1101 -subsection {* Synthetic division *}
230.1102 -
230.1103 -definition
230.1104 - synthetic_divmod :: "'a::comm_semiring_0 poly \<Rightarrow> 'a \<Rightarrow> 'a poly \<times> 'a"
230.1105 -where [code del]:
230.1106 - "synthetic_divmod p c =
230.1107 - poly_rec (0, 0) (\<lambda>a p (q, r). (pCons r q, a + c * r)) p"
230.1108 -
230.1109 -definition
230.1110 - synthetic_div :: "'a::comm_semiring_0 poly \<Rightarrow> 'a \<Rightarrow> 'a poly"
230.1111 -where
230.1112 - "synthetic_div p c = fst (synthetic_divmod p c)"
230.1113 -
230.1114 -lemma synthetic_divmod_0 [simp]:
230.1115 - "synthetic_divmod 0 c = (0, 0)"
230.1116 - unfolding synthetic_divmod_def
230.1117 - by (simp add: poly_rec_0)
230.1118 -
230.1119 -lemma synthetic_divmod_pCons [simp]:
230.1120 - "synthetic_divmod (pCons a p) c =
230.1121 - (\<lambda>(q, r). (pCons r q, a + c * r)) (synthetic_divmod p c)"
230.1122 - unfolding synthetic_divmod_def
230.1123 - by (simp add: poly_rec_pCons)
230.1124 -
230.1125 -lemma snd_synthetic_divmod: "snd (synthetic_divmod p c) = poly p c"
230.1126 - by (induct p, simp, simp add: split_def)
230.1127 -
230.1128 -lemma synthetic_div_0 [simp]: "synthetic_div 0 c = 0"
230.1129 - unfolding synthetic_div_def by simp
230.1130 -
230.1131 -lemma synthetic_div_pCons [simp]:
230.1132 - "synthetic_div (pCons a p) c = pCons (poly p c) (synthetic_div p c)"
230.1133 - unfolding synthetic_div_def
230.1134 - by (simp add: split_def snd_synthetic_divmod)
230.1135 -
230.1136 -lemma synthetic_div_eq_0_iff:
230.1137 - "synthetic_div p c = 0 \<longleftrightarrow> degree p = 0"
230.1138 - by (induct p, simp, case_tac p, simp)
230.1139 -
230.1140 -lemma degree_synthetic_div:
230.1141 - "degree (synthetic_div p c) = degree p - 1"
230.1142 - by (induct p, simp, simp add: synthetic_div_eq_0_iff)
230.1143 -
230.1144 -lemma synthetic_div_correct:
230.1145 - "p + smult c (synthetic_div p c) = pCons (poly p c) (synthetic_div p c)"
230.1146 - by (induct p) simp_all
230.1147 -
230.1148 -lemma synthetic_div_unique_lemma: "smult c p = pCons a p \<Longrightarrow> p = 0"
230.1149 -by (induct p arbitrary: a) simp_all
230.1150 -
230.1151 -lemma synthetic_div_unique:
230.1152 - "p + smult c q = pCons r q \<Longrightarrow> r = poly p c \<and> q = synthetic_div p c"
230.1153 -apply (induct p arbitrary: q r)
230.1154 -apply (simp, frule synthetic_div_unique_lemma, simp)
230.1155 -apply (case_tac q, force)
230.1156 -done
230.1157 -
230.1158 -lemma synthetic_div_correct':
230.1159 - fixes c :: "'a::comm_ring_1"
230.1160 - shows "[:-c, 1:] * synthetic_div p c + [:poly p c:] = p"
230.1161 - using synthetic_div_correct [of p c]
230.1162 - by (simp add: algebra_simps)
230.1163 -
230.1164 -lemma poly_eq_0_iff_dvd:
230.1165 - fixes c :: "'a::idom"
230.1166 - shows "poly p c = 0 \<longleftrightarrow> [:-c, 1:] dvd p"
230.1167 -proof
230.1168 - assume "poly p c = 0"
230.1169 - with synthetic_div_correct' [of c p]
230.1170 - have "p = [:-c, 1:] * synthetic_div p c" by simp
230.1171 - then show "[:-c, 1:] dvd p" ..
230.1172 -next
230.1173 - assume "[:-c, 1:] dvd p"
230.1174 - then obtain k where "p = [:-c, 1:] * k" by (rule dvdE)
230.1175 - then show "poly p c = 0" by simp
230.1176 -qed
230.1177 -
230.1178 -lemma dvd_iff_poly_eq_0:
230.1179 - fixes c :: "'a::idom"
230.1180 - shows "[:c, 1:] dvd p \<longleftrightarrow> poly p (-c) = 0"
230.1181 - by (simp add: poly_eq_0_iff_dvd)
230.1182 -
230.1183 -lemma poly_roots_finite:
230.1184 - fixes p :: "'a::idom poly"
230.1185 - shows "p \<noteq> 0 \<Longrightarrow> finite {x. poly p x = 0}"
230.1186 -proof (induct n \<equiv> "degree p" arbitrary: p)
230.1187 - case (0 p)
230.1188 - then obtain a where "a \<noteq> 0" and "p = [:a:]"
230.1189 - by (cases p, simp split: if_splits)
230.1190 - then show "finite {x. poly p x = 0}" by simp
230.1191 -next
230.1192 - case (Suc n p)
230.1193 - show "finite {x. poly p x = 0}"
230.1194 - proof (cases "\<exists>x. poly p x = 0")
230.1195 - case False
230.1196 - then show "finite {x. poly p x = 0}" by simp
230.1197 - next
230.1198 - case True
230.1199 - then obtain a where "poly p a = 0" ..
230.1200 - then have "[:-a, 1:] dvd p" by (simp only: poly_eq_0_iff_dvd)
230.1201 - then obtain k where k: "p = [:-a, 1:] * k" ..
230.1202 - with `p \<noteq> 0` have "k \<noteq> 0" by auto
230.1203 - with k have "degree p = Suc (degree k)"
230.1204 - by (simp add: degree_mult_eq del: mult_pCons_left)
230.1205 - with `Suc n = degree p` have "n = degree k" by simp
230.1206 - with `k \<noteq> 0` have "finite {x. poly k x = 0}" by (rule Suc.hyps)
230.1207 - then have "finite (insert a {x. poly k x = 0})" by simp
230.1208 - then show "finite {x. poly p x = 0}"
230.1209 - by (simp add: k uminus_add_conv_diff Collect_disj_eq
230.1210 - del: mult_pCons_left)
230.1211 - qed
230.1212 -qed
230.1213 -
230.1214 -
230.1215 -subsection {* Configuration of the code generator *}
230.1216 -
230.1217 -code_datatype "0::'a::zero poly" pCons
230.1218 -
230.1219 -declare pCons_0_0 [code post]
230.1220 -
230.1221 -instantiation poly :: ("{zero,eq}") eq
230.1222 -begin
230.1223 -
230.1224 -definition [code del]:
230.1225 - "eq_class.eq (p::'a poly) q \<longleftrightarrow> p = q"
230.1226 -
230.1227 -instance
230.1228 - by default (rule eq_poly_def)
230.1229 -
230.1230 -end
230.1231 -
230.1232 -lemma eq_poly_code [code]:
230.1233 - "eq_class.eq (0::_ poly) (0::_ poly) \<longleftrightarrow> True"
230.1234 - "eq_class.eq (0::_ poly) (pCons b q) \<longleftrightarrow> eq_class.eq 0 b \<and> eq_class.eq 0 q"
230.1235 - "eq_class.eq (pCons a p) (0::_ poly) \<longleftrightarrow> eq_class.eq a 0 \<and> eq_class.eq p 0"
230.1236 - "eq_class.eq (pCons a p) (pCons b q) \<longleftrightarrow> eq_class.eq a b \<and> eq_class.eq p q"
230.1237 -unfolding eq by simp_all
230.1238 -
230.1239 -lemmas coeff_code [code] =
230.1240 - coeff_0 coeff_pCons_0 coeff_pCons_Suc
230.1241 -
230.1242 -lemmas degree_code [code] =
230.1243 - degree_0 degree_pCons_eq_if
230.1244 -
230.1245 -lemmas monom_poly_code [code] =
230.1246 - monom_0 monom_Suc
230.1247 -
230.1248 -lemma add_poly_code [code]:
230.1249 - "0 + q = (q :: _ poly)"
230.1250 - "p + 0 = (p :: _ poly)"
230.1251 - "pCons a p + pCons b q = pCons (a + b) (p + q)"
230.1252 -by simp_all
230.1253 -
230.1254 -lemma minus_poly_code [code]:
230.1255 - "- 0 = (0 :: _ poly)"
230.1256 - "- pCons a p = pCons (- a) (- p)"
230.1257 -by simp_all
230.1258 -
230.1259 -lemma diff_poly_code [code]:
230.1260 - "0 - q = (- q :: _ poly)"
230.1261 - "p - 0 = (p :: _ poly)"
230.1262 - "pCons a p - pCons b q = pCons (a - b) (p - q)"
230.1263 -by simp_all
230.1264 -
230.1265 -lemmas smult_poly_code [code] =
230.1266 - smult_0_right smult_pCons
230.1267 -
230.1268 -lemma mult_poly_code [code]:
230.1269 - "0 * q = (0 :: _ poly)"
230.1270 - "pCons a p * q = smult a q + pCons 0 (p * q)"
230.1271 -by simp_all
230.1272 -
230.1273 -lemmas poly_code [code] =
230.1274 - poly_0 poly_pCons
230.1275 -
230.1276 -lemmas synthetic_divmod_code [code] =
230.1277 - synthetic_divmod_0 synthetic_divmod_pCons
230.1278 -
230.1279 -text {* code generator setup for div and mod *}
230.1280 -
230.1281 -definition
230.1282 - pdivmod :: "'a::field poly \<Rightarrow> 'a poly \<Rightarrow> 'a poly \<times> 'a poly"
230.1283 -where
230.1284 - [code del]: "pdivmod x y = (x div y, x mod y)"
230.1285 -
230.1286 -lemma div_poly_code [code]: "x div y = fst (pdivmod x y)"
230.1287 - unfolding pdivmod_def by simp
230.1288 -
230.1289 -lemma mod_poly_code [code]: "x mod y = snd (pdivmod x y)"
230.1290 - unfolding pdivmod_def by simp
230.1291 -
230.1292 -lemma pdivmod_0 [code]: "pdivmod 0 y = (0, 0)"
230.1293 - unfolding pdivmod_def by simp
230.1294 -
230.1295 -lemma pdivmod_pCons [code]:
230.1296 - "pdivmod (pCons a x) y =
230.1297 - (if y = 0 then (0, pCons a x) else
230.1298 - (let (q, r) = pdivmod x y;
230.1299 - b = coeff (pCons a r) (degree y) / coeff y (degree y)
230.1300 - in (pCons b q, pCons a r - smult b y)))"
230.1301 -apply (simp add: pdivmod_def Let_def, safe)
230.1302 -apply (rule div_poly_eq)
230.1303 -apply (erule pdivmod_rel_pCons [OF pdivmod_rel _ refl])
230.1304 -apply (rule mod_poly_eq)
230.1305 -apply (erule pdivmod_rel_pCons [OF pdivmod_rel _ refl])
230.1306 -done
230.1307 -
230.1308 -end
231.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
231.2 +++ b/src/HOL/ex/Serbian.thy Wed Mar 04 11:05:29 2009 +0100
231.3 @@ -0,0 +1,217 @@
231.4 +(* -*- coding: utf-8 -*- :encoding=utf-8:
231.5 + Author: Filip Maric
231.6 +
231.7 +Example theory involving Unicode characters (UTF-8 encoding) --
231.8 +Conversion between Serbian cyrillic and latin letters (ÑрпÑка ћирилица и латиница)
231.9 +*)
231.10 +
231.11 +header {* A Serbian theory *}
231.12 +
231.13 +theory Serbian
231.14 +imports Main
231.15 +begin
231.16 +
231.17 +text{* Serbian cyrillic letters *}
231.18 +datatype azbuka =
231.19 + azbA ("Ð")
231.20 +| azbB ("Б")
231.21 +| azbV ("Ð’")
231.22 +| azbG ("Г")
231.23 +| azbD ("Д")
231.24 +| azbDj ("Ђ")
231.25 +| azbE ("Е")
231.26 +| azbZv ("Ж")
231.27 +| azbZ ("З")
231.28 +| azbI ("И")
231.29 +| azbJ ("Ј")
231.30 +| azbK ("К")
231.31 +| azbL ("Л")
231.32 +| azbLj ("Љ")
231.33 +| azbM ("М")
231.34 +| azbN ("Ð")
231.35 +| azbNj ("Њ")
231.36 +| azbO ("О")
231.37 +| azbP ("П")
231.38 +| azbR ("Ð ")
231.39 +| azbS ("С")
231.40 +| azbT ("Т")
231.41 +| azbC' ("Ћ")
231.42 +| azbU ("У")
231.43 +| azbF ("Ф")
231.44 +| azbH ("Ð¥")
231.45 +| azbC ("Ц")
231.46 +| azbCv ("Ч")
231.47 +| azbDzv ("Ð")
231.48 +| azbSv ("Ш")
231.49 +| azbSpc
231.50 +
231.51 +thm azbuka.induct
231.52 +
231.53 +text{* Serbian latin letters *}
231.54 +datatype abeceda =
231.55 + abcA ("A")
231.56 +| abcB ("B")
231.57 +| abcC ("C")
231.58 +| abcCv ("Č")
231.59 +| abcC' ("Ć")
231.60 +| abcD ("D")
231.61 +| abcE ("E")
231.62 +| abcF ("F")
231.63 +| abcG ("G")
231.64 +| abcH ("H")
231.65 +| abcI ("I")
231.66 +| abcJ ("J")
231.67 +| abcK ("K")
231.68 +| abcL ("L")
231.69 +| abcM ("M")
231.70 +| abcN ("N")
231.71 +| abcO ("O")
231.72 +| abcP ("P")
231.73 +| abcR ("R")
231.74 +| abcS ("S")
231.75 +| abcSv ("Å ")
231.76 +| abcT ("T")
231.77 +| abcU ("U")
231.78 +| abcV ("V")
231.79 +| abcZ ("Z")
231.80 +| abcvZ ("Ž")
231.81 +| abcSpc
231.82 +
231.83 +thm abeceda.induct
231.84 +
231.85 +
231.86 +text{* Conversion from cyrillic to latin -
231.87 + this conversion is valid in all cases *}
231.88 +primrec azb2abc_aux :: "azbuka \<Rightarrow> abeceda list"
231.89 +where
231.90 + "azb2abc_aux Ð = [A]"
231.91 +| "azb2abc_aux Б = [B]"
231.92 +| "azb2abc_aux Ð’ = [V]"
231.93 +| "azb2abc_aux Г = [G]"
231.94 +| "azb2abc_aux Д = [D]"
231.95 +| "azb2abc_aux Ђ = [D, J]"
231.96 +| "azb2abc_aux Е = [E]"
231.97 +| "azb2abc_aux Ж = [Ž]"
231.98 +| "azb2abc_aux З = [Z]"
231.99 +| "azb2abc_aux И = [I]"
231.100 +| "azb2abc_aux Ј = [J]"
231.101 +| "azb2abc_aux К = [K]"
231.102 +| "azb2abc_aux Л = [L]"
231.103 +| "azb2abc_aux Љ = [L, J]"
231.104 +| "azb2abc_aux М = [M]"
231.105 +| "azb2abc_aux Ð = [N]"
231.106 +| "azb2abc_aux Њ = [N, J]"
231.107 +| "azb2abc_aux О = [O]"
231.108 +| "azb2abc_aux П = [P]"
231.109 +| "azb2abc_aux Ð = [R]"
231.110 +| "azb2abc_aux С = [S]"
231.111 +| "azb2abc_aux Т = [T]"
231.112 +| "azb2abc_aux Ћ = [Ć]"
231.113 +| "azb2abc_aux У = [U]"
231.114 +| "azb2abc_aux Ф = [F]"
231.115 +| "azb2abc_aux Х = [H]"
231.116 +| "azb2abc_aux Ц = [C]"
231.117 +| "azb2abc_aux Ч = [Č]"
231.118 +| "azb2abc_aux Р= [D, Ž]"
231.119 +| "azb2abc_aux Ш = [Š]"
231.120 +| "azb2abc_aux azbSpc = [abcSpc]"
231.121 +
231.122 +primrec azb2abc :: "azbuka list \<Rightarrow> abeceda list"
231.123 +where
231.124 + "azb2abc [] = []"
231.125 +| "azb2abc (x # xs) = azb2abc_aux x @ azb2abc xs"
231.126 +
231.127 +value "azb2abc [Д, О, Б, Ð, Ð , azbSpc, Д, Ð, Ð, azbSpc, С, Ð’, И, Ðœ, Ð]"
231.128 +value "azb2abc [Љ, У, Б, И, Ч, И, Ц, Ð, azbSpc, Ð, Ð, azbSpc, П, О, Љ, У]"
231.129 +
231.130 +text{* The conversion from latin to cyrillic -
231.131 + this conversion is valid in most cases but there are some exceptions *}
231.132 +primrec abc2azb_aux :: "abeceda \<Rightarrow> azbuka"
231.133 +where
231.134 + "abc2azb_aux A = Ð"
231.135 +| "abc2azb_aux B = Б"
231.136 +| "abc2azb_aux C = Ц"
231.137 +| "abc2azb_aux Č = Ч"
231.138 +| "abc2azb_aux Ć = Ћ"
231.139 +| "abc2azb_aux D = Д"
231.140 +| "abc2azb_aux E = Е"
231.141 +| "abc2azb_aux F = Ф"
231.142 +| "abc2azb_aux G = Г"
231.143 +| "abc2azb_aux H = Х"
231.144 +| "abc2azb_aux I = И"
231.145 +| "abc2azb_aux J = Ј"
231.146 +| "abc2azb_aux K = К"
231.147 +| "abc2azb_aux L = Л"
231.148 +| "abc2azb_aux M = М"
231.149 +| "abc2azb_aux N = Ð"
231.150 +| "abc2azb_aux O = О"
231.151 +| "abc2azb_aux P = П"
231.152 +| "abc2azb_aux R = Ð "
231.153 +| "abc2azb_aux S = С"
231.154 +| "abc2azb_aux Š= Ш"
231.155 +| "abc2azb_aux T = Т"
231.156 +| "abc2azb_aux U = У"
231.157 +| "abc2azb_aux V = Ð’"
231.158 +| "abc2azb_aux Z = З"
231.159 +| "abc2azb_aux Ž = Ж"
231.160 +| "abc2azb_aux abcSpc = azbSpc"
231.161 +
231.162 +fun abc2azb :: "abeceda list \<Rightarrow> azbuka list"
231.163 +where
231.164 + "abc2azb [] = []"
231.165 +| "abc2azb [x] = [abc2azb_aux x]"
231.166 +| "abc2azb (x1 # x2 # xs) =
231.167 + (if x1 = D \<and> x2 = J then
231.168 + Ђ # abc2azb xs
231.169 + else if x1 = L \<and> x2 = J then
231.170 + Љ # abc2azb xs
231.171 + else if x1 = N \<and> x2 = J then
231.172 + Њ # abc2azb xs
231.173 + else if x1 = D \<and> x2 = Ž then
231.174 + Ð # abc2azb xs
231.175 + else
231.176 + abc2azb_aux x1 # abc2azb (x2 # xs)
231.177 + )"
231.178 +
231.179 +value "abc2azb [D, O, B, A, R, abcSpc, D, A, N, abcSpc, S, V, I, M, A]"
231.180 +value "abc2azb [L, J, U, B, I, Č, I, C, A, abcSpc, N, A, abcSpc, P, O, L, J, U]"
231.181 +
231.182 +text{* Here are some invalid conversions *}
231.183 +lemma "abc2azb [N, A, D, Ž, I, V, E, T, I] = [Ð, Ð, Ð, И, Ð’, Е, Т, И]"
231.184 + by simp
231.185 +text{* but it should be: ÐÐДЖИВЕТИ *}
231.186 +lemma "abc2azb [I, N, J, E, K, C, I, J, A] = [И, Њ, Е, К, Ц, И, Ј, Ð]"
231.187 + by simp
231.188 +text{* but it should be: ИÐЈЕКЦИЈР*}
231.189 +
231.190 +text{* The conversion fails for all cyrrilic words that contain ÐЈ ЛЈ ДЈ ДЖ *}
231.191 +
231.192 +
231.193 +text{* Idempotency in one direction *}
231.194 +lemma [simp]: "azb2abc_aux (abc2azb_aux x) = [x]"
231.195 + by (cases x) auto
231.196 +
231.197 +lemma [simp]: "abc2azb (Ž # xs) = Ж # abc2azb xs"
231.198 + by (cases xs) auto
231.199 +
231.200 +lemma [simp]: "abc2azb (J # xs) = Ј # abc2azb xs"
231.201 + by (cases xs) auto
231.202 +
231.203 +theorem "azb2abc (abc2azb x) = x"
231.204 +proof (induct x)
231.205 + case (Cons x1 xs)
231.206 + thus ?case
231.207 + proof (cases xs)
231.208 + case (Cons x2 xss)
231.209 + thus ?thesis
231.210 + using `azb2abc (abc2azb xs) = xs`
231.211 + by auto
231.212 + qed simp
231.213 +qed simp
231.214 +
231.215 +text{* Idempotency in the other direction does not hold *}
231.216 +lemma "abc2azb (azb2abc [И, Ð, Ј, Е, К, Ц, И, Ј, Ð]) \<noteq> [И, Ð, Ј, Е, К, Ц, И, Ј, Ð]"
231.217 + by simp
231.218 +text{* It fails for all cyrrilic words that contain ÐЈ ЛЈ ДЈ ДЖ *}
231.219 +
231.220 +end
232.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
232.2 +++ b/src/HOLCF/ex/Powerdomain_ex.thy Wed Mar 04 11:05:29 2009 +0100
232.3 @@ -0,0 +1,118 @@
232.4 +(* Title: HOLCF/ex/Powerdomain_ex.thy
232.5 + Author: Brian Huffman
232.6 +*)
232.7 +
232.8 +header {* Powerdomain examples *}
232.9 +
232.10 +theory Powerdomain_ex
232.11 +imports HOLCF
232.12 +begin
232.13 +
232.14 +defaultsort bifinite
232.15 +
232.16 +subsection {* Monadic sorting example *}
232.17 +
232.18 +domain ordering = LT | EQ | GT
232.19 +
232.20 +declare ordering.rews [simp]
232.21 +
232.22 +definition
232.23 + compare :: "int lift \<rightarrow> int lift \<rightarrow> ordering" where
232.24 + "compare = (FLIFT x y. if x < y then LT else if x = y then EQ else GT)"
232.25 +
232.26 +definition
232.27 + is_le :: "int lift \<rightarrow> int lift \<rightarrow> tr" where
232.28 + "is_le = (\<Lambda> x y. case compare\<cdot>x\<cdot>y of LT \<Rightarrow> TT | EQ \<Rightarrow> TT | GT \<Rightarrow> FF)"
232.29 +
232.30 +definition
232.31 + is_less :: "int lift \<rightarrow> int lift \<rightarrow> tr" where
232.32 + "is_less = (\<Lambda> x y. case compare\<cdot>x\<cdot>y of LT \<Rightarrow> TT | EQ \<Rightarrow> FF | GT \<Rightarrow> FF)"
232.33 +
232.34 +definition
232.35 + r1 :: "(int lift \<times> 'a) \<rightarrow> (int lift \<times> 'a) \<rightarrow> tr convex_pd" where
232.36 + "r1 = (\<Lambda> \<langle>x,_\<rangle> \<langle>y,_\<rangle>. case compare\<cdot>x\<cdot>y of
232.37 + LT \<Rightarrow> {TT}\<natural> |
232.38 + EQ \<Rightarrow> {TT, FF}\<natural> |
232.39 + GT \<Rightarrow> {FF}\<natural>)"
232.40 +
232.41 +definition
232.42 + r2 :: "(int lift \<times> 'a) \<rightarrow> (int lift \<times> 'a) \<rightarrow> tr convex_pd" where
232.43 + "r2 = (\<Lambda> \<langle>x,_\<rangle> \<langle>y,_\<rangle>. {is_le\<cdot>x\<cdot>y, is_less\<cdot>x\<cdot>y}\<natural>)"
232.44 +
232.45 +lemma r1_r2: "r1\<cdot>\<langle>x,a\<rangle>\<cdot>\<langle>y,b\<rangle> = (r2\<cdot>\<langle>x,a\<rangle>\<cdot>\<langle>y,b\<rangle> :: tr convex_pd)"
232.46 +apply (simp add: r1_def r2_def)
232.47 +apply (simp add: is_le_def is_less_def)
232.48 +apply (cases "compare\<cdot>x\<cdot>y" rule: ordering.casedist)
232.49 +apply simp_all
232.50 +done
232.51 +
232.52 +
232.53 +subsection {* Picking a leaf from a tree *}
232.54 +
232.55 +domain 'a tree =
232.56 + Node (lazy "'a tree") (lazy "'a tree") |
232.57 + Leaf (lazy "'a")
232.58 +
232.59 +fixrec
232.60 + mirror :: "'a tree \<rightarrow> 'a tree"
232.61 +where
232.62 + mirror_Leaf: "mirror\<cdot>(Leaf\<cdot>a) = Leaf\<cdot>a"
232.63 +| mirror_Node: "mirror\<cdot>(Node\<cdot>l\<cdot>r) = Node\<cdot>(mirror\<cdot>r)\<cdot>(mirror\<cdot>l)"
232.64 +
232.65 +fixpat
232.66 + mirror_strict [simp]: "mirror\<cdot>\<bottom>"
232.67 +
232.68 +fixrec
232.69 + pick :: "'a tree \<rightarrow> 'a convex_pd"
232.70 +where
232.71 + pick_Leaf: "pick\<cdot>(Leaf\<cdot>a) = {a}\<natural>"
232.72 +| pick_Node: "pick\<cdot>(Node\<cdot>l\<cdot>r) = pick\<cdot>l +\<natural> pick\<cdot>r"
232.73 +
232.74 +fixpat
232.75 + pick_strict [simp]: "pick\<cdot>\<bottom>"
232.76 +
232.77 +lemma pick_mirror: "pick\<cdot>(mirror\<cdot>t) = pick\<cdot>t"
232.78 +by (induct t rule: tree.ind)
232.79 + (simp_all add: convex_plus_ac)
232.80 +
232.81 +fixrec tree1 :: "int lift tree"
232.82 +where "tree1 = Node\<cdot>(Node\<cdot>(Leaf\<cdot>(Def 1))\<cdot>(Leaf\<cdot>(Def 2)))
232.83 + \<cdot>(Node\<cdot>(Leaf\<cdot>(Def 3))\<cdot>(Leaf\<cdot>(Def 4)))"
232.84 +
232.85 +fixrec tree2 :: "int lift tree"
232.86 +where "tree2 = Node\<cdot>(Node\<cdot>(Leaf\<cdot>(Def 1))\<cdot>(Leaf\<cdot>(Def 2)))
232.87 + \<cdot>(Node\<cdot>\<bottom>\<cdot>(Leaf\<cdot>(Def 4)))"
232.88 +
232.89 +fixrec tree3 :: "int lift tree"
232.90 +where "tree3 = Node\<cdot>(Node\<cdot>(Leaf\<cdot>(Def 1))\<cdot>tree3)
232.91 + \<cdot>(Node\<cdot>(Leaf\<cdot>(Def 3))\<cdot>(Leaf\<cdot>(Def 4)))"
232.92 +
232.93 +declare tree1_simps tree2_simps tree3_simps [simp del]
232.94 +
232.95 +lemma pick_tree1:
232.96 + "pick\<cdot>tree1 = {Def 1, Def 2, Def 3, Def 4}\<natural>"
232.97 +apply (subst tree1_simps)
232.98 +apply simp
232.99 +apply (simp add: convex_plus_ac)
232.100 +done
232.101 +
232.102 +lemma pick_tree2:
232.103 + "pick\<cdot>tree2 = {Def 1, Def 2, \<bottom>, Def 4}\<natural>"
232.104 +apply (subst tree2_simps)
232.105 +apply simp
232.106 +apply (simp add: convex_plus_ac)
232.107 +done
232.108 +
232.109 +lemma pick_tree3:
232.110 + "pick\<cdot>tree3 = {Def 1, \<bottom>, Def 3, Def 4}\<natural>"
232.111 +apply (subst tree3_simps)
232.112 +apply simp
232.113 +apply (induct rule: tree3_induct)
232.114 +apply simp
232.115 +apply simp
232.116 +apply (simp add: convex_plus_ac)
232.117 +apply simp
232.118 +apply (simp add: convex_plus_ac)
232.119 +done
232.120 +
232.121 +end
233.1 --- a/src/Provers/coherent.ML Wed Mar 04 11:05:02 2009 +0100
233.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
233.3 @@ -1,233 +0,0 @@
233.4 -(* Title: Provers/coherent.ML
233.5 - Author: Stefan Berghofer, TU Muenchen
233.6 - Author: Marc Bezem, Institutt for Informatikk, Universitetet i Bergen
233.7 -
233.8 -Prover for coherent logic, see e.g.
233.9 -
233.10 - Marc Bezem and Thierry Coquand, Automating Coherent Logic, LPAR 2005
233.11 -
233.12 -for a description of the algorithm.
233.13 -*)
233.14 -
233.15 -signature COHERENT_DATA =
233.16 -sig
233.17 - val atomize_elimL: thm
233.18 - val atomize_exL: thm
233.19 - val atomize_conjL: thm
233.20 - val atomize_disjL: thm
233.21 - val operator_names: string list
233.22 -end;
233.23 -
233.24 -signature COHERENT =
233.25 -sig
233.26 - val verbose: bool ref
233.27 - val show_facts: bool ref
233.28 - val coherent_tac: thm list -> Proof.context -> int -> tactic
233.29 - val coherent_meth: thm list -> Proof.context -> Proof.method
233.30 - val setup: theory -> theory
233.31 -end;
233.32 -
233.33 -functor CoherentFun(Data: COHERENT_DATA) : COHERENT =
233.34 -struct
233.35 -
233.36 -val verbose = ref false;
233.37 -
233.38 -fun message f = if !verbose then tracing (f ()) else ();
233.39 -
233.40 -datatype cl_prf =
233.41 - ClPrf of thm * (Type.tyenv * Envir.tenv) * ((indexname * typ) * term) list *
233.42 - int list * (term list * cl_prf) list;
233.43 -
233.44 -val is_atomic = not o exists_Const (member (op =) Data.operator_names o #1);
233.45 -
233.46 -local open Conv in
233.47 -
233.48 -fun rulify_elim_conv ct =
233.49 - if is_atomic (Logic.strip_imp_concl (term_of ct)) then all_conv ct
233.50 - else concl_conv (length (Logic.strip_imp_prems (term_of ct)))
233.51 - (rewr_conv (symmetric Data.atomize_elimL) then_conv
233.52 - MetaSimplifier.rewrite true (map symmetric
233.53 - [Data.atomize_exL, Data.atomize_conjL, Data.atomize_disjL])) ct
233.54 -
233.55 -end;
233.56 -
233.57 -fun rulify_elim th = MetaSimplifier.norm_hhf (Conv.fconv_rule rulify_elim_conv th);
233.58 -
233.59 -(* Decompose elimination rule of the form
233.60 - A1 ==> ... ==> Am ==> (!!xs1. Bs1 ==> P) ==> ... ==> (!!xsn. Bsn ==> P) ==> P
233.61 -*)
233.62 -fun dest_elim prop =
233.63 - let
233.64 - val prems = Logic.strip_imp_prems prop;
233.65 - val concl = Logic.strip_imp_concl prop;
233.66 - val (prems1, prems2) =
233.67 - take_suffix (fn t => Logic.strip_assums_concl t = concl) prems;
233.68 - in
233.69 - (prems1,
233.70 - if null prems2 then [([], [concl])]
233.71 - else map (fn t =>
233.72 - (map snd (Logic.strip_params t), Logic.strip_assums_hyp t)) prems2)
233.73 - end;
233.74 -
233.75 -fun mk_rule th =
233.76 - let
233.77 - val th' = rulify_elim th;
233.78 - val (prems, cases) = dest_elim (prop_of th')
233.79 - in (th', prems, cases) end;
233.80 -
233.81 -fun mk_dom ts = fold (fn t =>
233.82 - Typtab.map_default (fastype_of t, []) (fn us => us @ [t])) ts Typtab.empty;
233.83 -
233.84 -val empty_env = (Vartab.empty, Vartab.empty);
233.85 -
233.86 -(* Find matcher that makes conjunction valid in given state *)
233.87 -fun valid_conj ctxt facts env [] = Seq.single (env, [])
233.88 - | valid_conj ctxt facts env (t :: ts) =
233.89 - Seq.maps (fn (u, x) => Seq.map (apsnd (cons x))
233.90 - (valid_conj ctxt facts
233.91 - (Pattern.match (ProofContext.theory_of ctxt) (t, u) env) ts
233.92 - handle Pattern.MATCH => Seq.empty))
233.93 - (Seq.of_list (sort (int_ord o pairself snd) (Net.unify_term facts t)));
233.94 -
233.95 -(* Instantiate variables that only occur free in conlusion *)
233.96 -fun inst_extra_vars ctxt dom cs =
233.97 - let
233.98 - val vs = fold Term.add_vars (maps snd cs) [];
233.99 - fun insts [] inst = Seq.single inst
233.100 - | insts ((ixn, T) :: vs') inst = Seq.maps
233.101 - (fn t => insts vs' (((ixn, T), t) :: inst))
233.102 - (Seq.of_list (case Typtab.lookup dom T of
233.103 - NONE => error ("Unknown domain: " ^
233.104 - Syntax.string_of_typ ctxt T ^ "\nfor term(s) " ^
233.105 - commas (maps (map (Syntax.string_of_term ctxt) o snd) cs))
233.106 - | SOME ts => ts))
233.107 - in Seq.map (fn inst =>
233.108 - (inst, map (apsnd (map (subst_Vars (map (apfst fst) inst)))) cs))
233.109 - (insts vs [])
233.110 - end;
233.111 -
233.112 -(* Check whether disjunction is valid in given state *)
233.113 -fun is_valid_disj ctxt facts [] = false
233.114 - | is_valid_disj ctxt facts ((Ts, ts) :: ds) =
233.115 - let val vs = rev (map_index (fn (i, T) => Var (("x", i), T)) Ts)
233.116 - in case Seq.pull (valid_conj ctxt facts empty_env
233.117 - (map (fn t => subst_bounds (vs, t)) ts)) of
233.118 - SOME _ => true
233.119 - | NONE => is_valid_disj ctxt facts ds
233.120 - end;
233.121 -
233.122 -val show_facts = ref false;
233.123 -
233.124 -fun string_of_facts ctxt s facts = space_implode "\n"
233.125 - (s :: map (Syntax.string_of_term ctxt)
233.126 - (map fst (sort (int_ord o pairself snd) (Net.content facts)))) ^ "\n\n";
233.127 -
233.128 -fun print_facts ctxt facts =
233.129 - if !show_facts then message (fn () => string_of_facts ctxt "Facts:" facts)
233.130 - else ();
233.131 -
233.132 -fun valid ctxt rules goal dom facts nfacts nparams =
233.133 - let val seq = Seq.of_list rules |> Seq.maps (fn (th, ps, cs) =>
233.134 - valid_conj ctxt facts empty_env ps |> Seq.maps (fn (env as (tye, _), is) =>
233.135 - let val cs' = map (fn (Ts, ts) =>
233.136 - (map (Envir.typ_subst_TVars tye) Ts, map (Envir.subst_vars env) ts)) cs
233.137 - in
233.138 - inst_extra_vars ctxt dom cs' |>
233.139 - Seq.map_filter (fn (inst, cs'') =>
233.140 - if is_valid_disj ctxt facts cs'' then NONE
233.141 - else SOME (th, env, inst, is, cs''))
233.142 - end))
233.143 - in
233.144 - case Seq.pull seq of
233.145 - NONE => (tracing (string_of_facts ctxt "Countermodel found:" facts); NONE)
233.146 - | SOME ((th, env, inst, is, cs), _) =>
233.147 - if cs = [([], [goal])] then SOME (ClPrf (th, env, inst, is, []))
233.148 - else
233.149 - (case valid_cases ctxt rules goal dom facts nfacts nparams cs of
233.150 - NONE => NONE
233.151 - | SOME prfs => SOME (ClPrf (th, env, inst, is, prfs)))
233.152 - end
233.153 -
233.154 -and valid_cases ctxt rules goal dom facts nfacts nparams [] = SOME []
233.155 - | valid_cases ctxt rules goal dom facts nfacts nparams ((Ts, ts) :: ds) =
233.156 - let
233.157 - val _ = message (fn () => "case " ^ commas (map (Syntax.string_of_term ctxt) ts));
233.158 - val params = rev (map_index (fn (i, T) =>
233.159 - Free ("par" ^ string_of_int (nparams + i), T)) Ts);
233.160 - val ts' = map_index (fn (i, t) =>
233.161 - (subst_bounds (params, t), nfacts + i)) ts;
233.162 - val dom' = fold (fn (T, p) =>
233.163 - Typtab.map_default (T, []) (fn ps => ps @ [p]))
233.164 - (Ts ~~ params) dom;
233.165 - val facts' = fold (fn (t, i) => Net.insert_term op =
233.166 - (t, (t, i))) ts' facts
233.167 - in
233.168 - case valid ctxt rules goal dom' facts'
233.169 - (nfacts + length ts) (nparams + length Ts) of
233.170 - NONE => NONE
233.171 - | SOME prf => (case valid_cases ctxt rules goal dom facts nfacts nparams ds of
233.172 - NONE => NONE
233.173 - | SOME prfs => SOME ((params, prf) :: prfs))
233.174 - end;
233.175 -
233.176 -(** proof replaying **)
233.177 -
233.178 -fun thm_of_cl_prf thy goal asms (ClPrf (th, (tye, env), insts, is, prfs)) =
233.179 - let
233.180 - val _ = message (fn () => space_implode "\n"
233.181 - ("asms:" :: map Display.string_of_thm asms) ^ "\n\n");
233.182 - val th' = Drule.implies_elim_list
233.183 - (Thm.instantiate
233.184 - (map (fn (ixn, (S, T)) =>
233.185 - (Thm.ctyp_of thy (TVar ((ixn, S))), Thm.ctyp_of thy T))
233.186 - (Vartab.dest tye),
233.187 - map (fn (ixn, (T, t)) =>
233.188 - (Thm.cterm_of thy (Var (ixn, Envir.typ_subst_TVars tye T)),
233.189 - Thm.cterm_of thy t)) (Vartab.dest env) @
233.190 - map (fn (ixnT, t) =>
233.191 - (Thm.cterm_of thy (Var ixnT), Thm.cterm_of thy t)) insts) th)
233.192 - (map (nth asms) is);
233.193 - val (_, cases) = dest_elim (prop_of th')
233.194 - in
233.195 - case (cases, prfs) of
233.196 - ([([], [_])], []) => th'
233.197 - | ([([], [_])], [([], prf)]) => thm_of_cl_prf thy goal (asms @ [th']) prf
233.198 - | _ => Drule.implies_elim_list
233.199 - (Thm.instantiate (Thm.match
233.200 - (Drule.strip_imp_concl (cprop_of th'), goal)) th')
233.201 - (map (thm_of_case_prf thy goal asms) (prfs ~~ cases))
233.202 - end
233.203 -
233.204 -and thm_of_case_prf thy goal asms ((params, prf), (_, asms')) =
233.205 - let
233.206 - val cparams = map (cterm_of thy) params;
233.207 - val asms'' = map (cterm_of thy o curry subst_bounds (rev params)) asms'
233.208 - in
233.209 - Drule.forall_intr_list cparams (Drule.implies_intr_list asms''
233.210 - (thm_of_cl_prf thy goal (asms @ map Thm.assume asms'') prf))
233.211 - end;
233.212 -
233.213 -
233.214 -(** external interface **)
233.215 -
233.216 -fun coherent_tac rules ctxt = SUBPROOF (fn {prems, concl, params, context, ...} =>
233.217 - rtac (rulify_elim_conv concl RS equal_elim_rule2) 1 THEN
233.218 - SUBPROOF (fn {prems = prems', concl, context, ...} =>
233.219 - let val xs = map term_of params @
233.220 - map (fn (_, s) => Free (s, the (Variable.default_type context s)))
233.221 - (Variable.fixes_of context)
233.222 - in
233.223 - case valid context (map mk_rule (prems' @ prems @ rules)) (term_of concl)
233.224 - (mk_dom xs) Net.empty 0 0 of
233.225 - NONE => no_tac
233.226 - | SOME prf =>
233.227 - rtac (thm_of_cl_prf (ProofContext.theory_of context) concl [] prf) 1
233.228 - end) context 1) ctxt;
233.229 -
233.230 -fun coherent_meth rules ctxt =
233.231 - Method.METHOD (fn facts => coherent_tac (facts @ rules) ctxt 1);
233.232 -
233.233 -val setup = Method.add_method
233.234 - ("coherent", Method.thms_ctxt_args coherent_meth, "Prove coherent formula");
233.235 -
233.236 -end;
234.1 --- a/src/Provers/eqsubst.ML Wed Mar 04 11:05:02 2009 +0100
234.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
234.3 @@ -1,575 +0,0 @@
234.4 -(* Title: Provers/eqsubst.ML
234.5 - Author: Lucas Dixon, University of Edinburgh
234.6 -
234.7 -A proof method to perform a substiution using an equation.
234.8 -*)
234.9 -
234.10 -signature EQSUBST =
234.11 -sig
234.12 - (* a type abbreviation for match information *)
234.13 - type match =
234.14 - ((indexname * (sort * typ)) list (* type instantiations *)
234.15 - * (indexname * (typ * term)) list) (* term instantiations *)
234.16 - * (string * typ) list (* fake named type abs env *)
234.17 - * (string * typ) list (* type abs env *)
234.18 - * term (* outer term *)
234.19 -
234.20 - type searchinfo =
234.21 - theory
234.22 - * int (* maxidx *)
234.23 - * Zipper.T (* focusterm to search under *)
234.24 -
234.25 - exception eqsubst_occL_exp of
234.26 - string * int list * Thm.thm list * int * Thm.thm
234.27 -
234.28 - (* low level substitution functions *)
234.29 - val apply_subst_in_asm :
234.30 - int ->
234.31 - Thm.thm ->
234.32 - Thm.thm ->
234.33 - (Thm.cterm list * int * 'a * Thm.thm) * match -> Thm.thm Seq.seq
234.34 - val apply_subst_in_concl :
234.35 - int ->
234.36 - Thm.thm ->
234.37 - Thm.cterm list * Thm.thm ->
234.38 - Thm.thm -> match -> Thm.thm Seq.seq
234.39 -
234.40 - (* matching/unification within zippers *)
234.41 - val clean_match_z :
234.42 - Context.theory -> Term.term -> Zipper.T -> match option
234.43 - val clean_unify_z :
234.44 - Context.theory -> int -> Term.term -> Zipper.T -> match Seq.seq
234.45 -
234.46 - (* skipping things in seq seq's *)
234.47 -
234.48 - (* skipping non-empty sub-sequences but when we reach the end
234.49 - of the seq, remembering how much we have left to skip. *)
234.50 - datatype 'a skipseq = SkipMore of int
234.51 - | SkipSeq of 'a Seq.seq Seq.seq;
234.52 -
234.53 - val skip_first_asm_occs_search :
234.54 - ('a -> 'b -> 'c Seq.seq Seq.seq) ->
234.55 - 'a -> int -> 'b -> 'c skipseq
234.56 - val skip_first_occs_search :
234.57 - int -> ('a -> 'b -> 'c Seq.seq Seq.seq) -> 'a -> 'b -> 'c Seq.seq
234.58 - val skipto_skipseq : int -> 'a Seq.seq Seq.seq -> 'a skipseq
234.59 -
234.60 - (* tactics *)
234.61 - val eqsubst_asm_tac :
234.62 - Proof.context ->
234.63 - int list -> Thm.thm list -> int -> Thm.thm -> Thm.thm Seq.seq
234.64 - val eqsubst_asm_tac' :
234.65 - Proof.context ->
234.66 - (searchinfo -> int -> Term.term -> match skipseq) ->
234.67 - int -> Thm.thm -> int -> Thm.thm -> Thm.thm Seq.seq
234.68 - val eqsubst_tac :
234.69 - Proof.context ->
234.70 - int list -> (* list of occurences to rewrite, use [0] for any *)
234.71 - Thm.thm list -> int -> Thm.thm -> Thm.thm Seq.seq
234.72 - val eqsubst_tac' :
234.73 - Proof.context -> (* proof context *)
234.74 - (searchinfo -> Term.term -> match Seq.seq) (* search function *)
234.75 - -> Thm.thm (* equation theorem to rewrite with *)
234.76 - -> int (* subgoal number in goal theorem *)
234.77 - -> Thm.thm (* goal theorem *)
234.78 - -> Thm.thm Seq.seq (* rewritten goal theorem *)
234.79 -
234.80 -
234.81 - val fakefree_badbounds :
234.82 - (string * Term.typ) list ->
234.83 - Term.term ->
234.84 - (string * Term.typ) list * (string * Term.typ) list * Term.term
234.85 -
234.86 - val mk_foo_match :
234.87 - (Term.term -> Term.term) ->
234.88 - ('a * Term.typ) list -> Term.term -> Term.term
234.89 -
234.90 - (* preparing substitution *)
234.91 - val prep_meta_eq : Proof.context -> Thm.thm -> Thm.thm list
234.92 - val prep_concl_subst :
234.93 - int -> Thm.thm -> (Thm.cterm list * Thm.thm) * searchinfo
234.94 - val prep_subst_in_asm :
234.95 - int -> Thm.thm -> int ->
234.96 - (Thm.cterm list * int * int * Thm.thm) * searchinfo
234.97 - val prep_subst_in_asms :
234.98 - int -> Thm.thm ->
234.99 - ((Thm.cterm list * int * int * Thm.thm) * searchinfo) list
234.100 - val prep_zipper_match :
234.101 - Zipper.T -> Term.term * ((string * Term.typ) list * (string * Term.typ) list * Term.term)
234.102 -
234.103 - (* search for substitutions *)
234.104 - val valid_match_start : Zipper.T -> bool
234.105 - val search_lr_all : Zipper.T -> Zipper.T Seq.seq
234.106 - val search_lr_valid : (Zipper.T -> bool) -> Zipper.T -> Zipper.T Seq.seq
234.107 - val searchf_lr_unify_all :
234.108 - searchinfo -> Term.term -> match Seq.seq Seq.seq
234.109 - val searchf_lr_unify_valid :
234.110 - searchinfo -> Term.term -> match Seq.seq Seq.seq
234.111 - val searchf_bt_unify_valid :
234.112 - searchinfo -> Term.term -> match Seq.seq Seq.seq
234.113 -
234.114 - (* syntax tools *)
234.115 - val ith_syntax : Args.T list -> int list * Args.T list
234.116 - val options_syntax : Args.T list -> bool * Args.T list
234.117 -
234.118 - (* Isar level hooks *)
234.119 - val eqsubst_asm_meth : Proof.context -> int list -> Thm.thm list -> Proof.method
234.120 - val eqsubst_meth : Proof.context -> int list -> Thm.thm list -> Proof.method
234.121 - val subst_meth : Method.src -> Proof.context -> Proof.method
234.122 - val setup : theory -> theory
234.123 -
234.124 -end;
234.125 -
234.126 -structure EqSubst
234.127 -: EQSUBST
234.128 -= struct
234.129 -
234.130 -structure Z = Zipper;
234.131 -
234.132 -(* changes object "=" to meta "==" which prepares a given rewrite rule *)
234.133 -fun prep_meta_eq ctxt =
234.134 - let val (_, {mk_rews = {mk, ...}, ...}) = Simplifier.rep_ss (Simplifier.local_simpset_of ctxt)
234.135 - in mk #> map Drule.zero_var_indexes end;
234.136 -
234.137 -
234.138 - (* a type abriviation for match information *)
234.139 - type match =
234.140 - ((indexname * (sort * typ)) list (* type instantiations *)
234.141 - * (indexname * (typ * term)) list) (* term instantiations *)
234.142 - * (string * typ) list (* fake named type abs env *)
234.143 - * (string * typ) list (* type abs env *)
234.144 - * term (* outer term *)
234.145 -
234.146 - type searchinfo =
234.147 - theory
234.148 - * int (* maxidx *)
234.149 - * Zipper.T (* focusterm to search under *)
234.150 -
234.151 -
234.152 -(* skipping non-empty sub-sequences but when we reach the end
234.153 - of the seq, remembering how much we have left to skip. *)
234.154 -datatype 'a skipseq = SkipMore of int
234.155 - | SkipSeq of 'a Seq.seq Seq.seq;
234.156 -(* given a seqseq, skip the first m non-empty seq's, note deficit *)
234.157 -fun skipto_skipseq m s =
234.158 - let
234.159 - fun skip_occs n sq =
234.160 - case Seq.pull sq of
234.161 - NONE => SkipMore n
234.162 - | SOME (h,t) =>
234.163 - (case Seq.pull h of NONE => skip_occs n t
234.164 - | SOME _ => if n <= 1 then SkipSeq (Seq.cons h t)
234.165 - else skip_occs (n - 1) t)
234.166 - in (skip_occs m s) end;
234.167 -
234.168 -(* note: outerterm is the taget with the match replaced by a bound
234.169 - variable : ie: "P lhs" beocmes "%x. P x"
234.170 - insts is the types of instantiations of vars in lhs
234.171 - and typinsts is the type instantiations of types in the lhs
234.172 - Note: Final rule is the rule lifted into the ontext of the
234.173 - taget thm. *)
234.174 -fun mk_foo_match mkuptermfunc Ts t =
234.175 - let
234.176 - val ty = Term.type_of t
234.177 - val bigtype = (rev (map snd Ts)) ---> ty
234.178 - fun mk_foo 0 t = t
234.179 - | mk_foo i t = mk_foo (i - 1) (t $ (Bound (i - 1)))
234.180 - val num_of_bnds = (length Ts)
234.181 - (* foo_term = "fooabs y0 ... yn" where y's are local bounds *)
234.182 - val foo_term = mk_foo num_of_bnds (Bound num_of_bnds)
234.183 - in Abs("fooabs", bigtype, mkuptermfunc foo_term) end;
234.184 -
234.185 -(* T is outer bound vars, n is number of locally bound vars *)
234.186 -(* THINK: is order of Ts correct...? or reversed? *)
234.187 -fun fakefree_badbounds Ts t =
234.188 - let val (FakeTs,Ts,newnames) =
234.189 - List.foldr (fn ((n,ty),(FakeTs,Ts,usednames)) =>
234.190 - let val newname = Name.variant usednames n
234.191 - in ((RWTools.mk_fake_bound_name newname,ty)::FakeTs,
234.192 - (newname,ty)::Ts,
234.193 - newname::usednames) end)
234.194 - ([],[],[])
234.195 - Ts
234.196 - in (FakeTs, Ts, Term.subst_bounds (map Free FakeTs, t)) end;
234.197 -
234.198 -(* before matching we need to fake the bound vars that are missing an
234.199 -abstraction. In this function we additionally construct the
234.200 -abstraction environment, and an outer context term (with the focus
234.201 -abstracted out) for use in rewriting with RWInst.rw *)
234.202 -fun prep_zipper_match z =
234.203 - let
234.204 - val t = Z.trm z
234.205 - val c = Z.ctxt z
234.206 - val Ts = Z.C.nty_ctxt c
234.207 - val (FakeTs', Ts', t') = fakefree_badbounds Ts t
234.208 - val absterm = mk_foo_match (Z.C.apply c) Ts' t'
234.209 - in
234.210 - (t', (FakeTs', Ts', absterm))
234.211 - end;
234.212 -
234.213 -(* Matching and Unification with exception handled *)
234.214 -fun clean_match thy (a as (pat, t)) =
234.215 - let val (tyenv, tenv) = Pattern.match thy a (Vartab.empty, Vartab.empty)
234.216 - in SOME (Vartab.dest tyenv, Vartab.dest tenv)
234.217 - end handle Pattern.MATCH => NONE;
234.218 -
234.219 -(* given theory, max var index, pat, tgt; returns Seq of instantiations *)
234.220 -fun clean_unify thry ix (a as (pat, tgt)) =
234.221 - let
234.222 - (* type info will be re-derived, maybe this can be cached
234.223 - for efficiency? *)
234.224 - val pat_ty = Term.type_of pat;
234.225 - val tgt_ty = Term.type_of tgt;
234.226 - (* is it OK to ignore the type instantiation info?
234.227 - or should I be using it? *)
234.228 - val typs_unify =
234.229 - SOME (Sign.typ_unify thry (pat_ty, tgt_ty) (Vartab.empty, ix))
234.230 - handle Type.TUNIFY => NONE;
234.231 - in
234.232 - case typs_unify of
234.233 - SOME (typinsttab, ix2) =>
234.234 - let
234.235 - (* is it right to throw away the flexes?
234.236 - or should I be using them somehow? *)
234.237 - fun mk_insts env =
234.238 - (Vartab.dest (Envir.type_env env),
234.239 - Envir.alist_of env);
234.240 - val initenv = Envir.Envir {asol = Vartab.empty,
234.241 - iTs = typinsttab, maxidx = ix2};
234.242 - val useq = Unify.smash_unifiers thry [a] initenv
234.243 - handle UnequalLengths => Seq.empty
234.244 - | Term.TERM _ => Seq.empty;
234.245 - fun clean_unify' useq () =
234.246 - (case (Seq.pull useq) of
234.247 - NONE => NONE
234.248 - | SOME (h,t) => SOME (mk_insts h, Seq.make (clean_unify' t)))
234.249 - handle UnequalLengths => NONE
234.250 - | Term.TERM _ => NONE
234.251 - in
234.252 - (Seq.make (clean_unify' useq))
234.253 - end
234.254 - | NONE => Seq.empty
234.255 - end;
234.256 -
234.257 -(* Matching and Unification for zippers *)
234.258 -(* Note: Ts is a modified version of the original names of the outer
234.259 -bound variables. New names have been introduced to make sure they are
234.260 -unique w.r.t all names in the term and each other. usednames' is
234.261 -oldnames + new names. *)
234.262 -fun clean_match_z thy pat z =
234.263 - let val (t, (FakeTs,Ts,absterm)) = prep_zipper_match z in
234.264 - case clean_match thy (pat, t) of
234.265 - NONE => NONE
234.266 - | SOME insts => SOME (insts, FakeTs, Ts, absterm) end;
234.267 -(* ix = max var index *)
234.268 -fun clean_unify_z sgn ix pat z =
234.269 - let val (t, (FakeTs, Ts,absterm)) = prep_zipper_match z in
234.270 - Seq.map (fn insts => (insts, FakeTs, Ts, absterm))
234.271 - (clean_unify sgn ix (t, pat)) end;
234.272 -
234.273 -
234.274 -(* FOR DEBUGGING...
234.275 -type trace_subst_errT = int (* subgoal *)
234.276 - * thm (* thm with all goals *)
234.277 - * (Thm.cterm list (* certified free var placeholders for vars *)
234.278 - * thm) (* trivial thm of goal concl *)
234.279 - (* possible matches/unifiers *)
234.280 - * thm (* rule *)
234.281 - * (((indexname * typ) list (* type instantiations *)
234.282 - * (indexname * term) list ) (* term instantiations *)
234.283 - * (string * typ) list (* Type abs env *)
234.284 - * term) (* outer term *);
234.285 -
234.286 -val trace_subst_err = (ref NONE : trace_subst_errT option ref);
234.287 -val trace_subst_search = ref false;
234.288 -exception trace_subst_exp of trace_subst_errT;
234.289 -*)
234.290 -
234.291 -
234.292 -fun bot_left_leaf_of (l $ r) = bot_left_leaf_of l
234.293 - | bot_left_leaf_of (Abs(s,ty,t)) = bot_left_leaf_of t
234.294 - | bot_left_leaf_of x = x;
234.295 -
234.296 -(* Avoid considering replacing terms which have a var at the head as
234.297 - they always succeed trivially, and uninterestingly. *)
234.298 -fun valid_match_start z =
234.299 - (case bot_left_leaf_of (Z.trm z) of
234.300 - Var _ => false
234.301 - | _ => true);
234.302 -
234.303 -(* search from top, left to right, then down *)
234.304 -val search_lr_all = ZipperSearch.all_bl_ur;
234.305 -
234.306 -(* search from top, left to right, then down *)
234.307 -fun search_lr_valid validf =
234.308 - let
234.309 - fun sf_valid_td_lr z =
234.310 - let val here = if validf z then [Z.Here z] else [] in
234.311 - case Z.trm z
234.312 - of _ $ _ => [Z.LookIn (Z.move_down_left z)]
234.313 - @ here
234.314 - @ [Z.LookIn (Z.move_down_right z)]
234.315 - | Abs _ => here @ [Z.LookIn (Z.move_down_abs z)]
234.316 - | _ => here
234.317 - end;
234.318 - in Z.lzy_search sf_valid_td_lr end;
234.319 -
234.320 -(* search from bottom to top, left to right *)
234.321 -
234.322 -fun search_bt_valid validf =
234.323 - let
234.324 - fun sf_valid_td_lr z =
234.325 - let val here = if validf z then [Z.Here z] else [] in
234.326 - case Z.trm z
234.327 - of _ $ _ => [Z.LookIn (Z.move_down_left z),
234.328 - Z.LookIn (Z.move_down_right z)] @ here
234.329 - | Abs _ => [Z.LookIn (Z.move_down_abs z)] @ here
234.330 - | _ => here
234.331 - end;
234.332 - in Z.lzy_search sf_valid_td_lr end;
234.333 -
234.334 -fun searchf_unify_gen f (sgn, maxidx, z) lhs =
234.335 - Seq.map (clean_unify_z sgn maxidx lhs)
234.336 - (Z.limit_apply f z);
234.337 -
234.338 -(* search all unifications *)
234.339 -val searchf_lr_unify_all =
234.340 - searchf_unify_gen search_lr_all;
234.341 -
234.342 -(* search only for 'valid' unifiers (non abs subterms and non vars) *)
234.343 -val searchf_lr_unify_valid =
234.344 - searchf_unify_gen (search_lr_valid valid_match_start);
234.345 -
234.346 -val searchf_bt_unify_valid =
234.347 - searchf_unify_gen (search_bt_valid valid_match_start);
234.348 -
234.349 -(* apply a substitution in the conclusion of the theorem th *)
234.350 -(* cfvs are certified free var placeholders for goal params *)
234.351 -(* conclthm is a theorem of for just the conclusion *)
234.352 -(* m is instantiation/match information *)
234.353 -(* rule is the equation for substitution *)
234.354 -fun apply_subst_in_concl i th (cfvs, conclthm) rule m =
234.355 - (RWInst.rw m rule conclthm)
234.356 - |> IsaND.unfix_frees cfvs
234.357 - |> RWInst.beta_eta_contract
234.358 - |> (fn r => Tactic.rtac r i th);
234.359 -
234.360 -(* substitute within the conclusion of goal i of gth, using a meta
234.361 -equation rule. Note that we assume rule has var indicies zero'd *)
234.362 -fun prep_concl_subst i gth =
234.363 - let
234.364 - val th = Thm.incr_indexes 1 gth;
234.365 - val tgt_term = Thm.prop_of th;
234.366 -
234.367 - val sgn = Thm.theory_of_thm th;
234.368 - val ctermify = Thm.cterm_of sgn;
234.369 - val trivify = Thm.trivial o ctermify;
234.370 -
234.371 - val (fixedbody, fvs) = IsaND.fix_alls_term i tgt_term;
234.372 - val cfvs = rev (map ctermify fvs);
234.373 -
234.374 - val conclterm = Logic.strip_imp_concl fixedbody;
234.375 - val conclthm = trivify conclterm;
234.376 - val maxidx = Thm.maxidx_of th;
234.377 - val ft = ((Z.move_down_right (* ==> *)
234.378 - o Z.move_down_left (* Trueprop *)
234.379 - o Z.mktop
234.380 - o Thm.prop_of) conclthm)
234.381 - in
234.382 - ((cfvs, conclthm), (sgn, maxidx, ft))
234.383 - end;
234.384 -
234.385 -(* substitute using an object or meta level equality *)
234.386 -fun eqsubst_tac' ctxt searchf instepthm i th =
234.387 - let
234.388 - val (cvfsconclthm, searchinfo) = prep_concl_subst i th;
234.389 - val stepthms = Seq.of_list (prep_meta_eq ctxt instepthm);
234.390 - fun rewrite_with_thm r =
234.391 - let val (lhs,_) = Logic.dest_equals (Thm.concl_of r);
234.392 - in searchf searchinfo lhs
234.393 - |> Seq.maps (apply_subst_in_concl i th cvfsconclthm r) end;
234.394 - in stepthms |> Seq.maps rewrite_with_thm end;
234.395 -
234.396 -
234.397 -(* distinct subgoals *)
234.398 -fun distinct_subgoals th =
234.399 - the_default th (SINGLE distinct_subgoals_tac th);
234.400 -
234.401 -(* General substitution of multiple occurances using one of
234.402 - the given theorems*)
234.403 -
234.404 -
234.405 -exception eqsubst_occL_exp of
234.406 - string * (int list) * (thm list) * int * thm;
234.407 -fun skip_first_occs_search occ srchf sinfo lhs =
234.408 - case (skipto_skipseq occ (srchf sinfo lhs)) of
234.409 - SkipMore _ => Seq.empty
234.410 - | SkipSeq ss => Seq.flat ss;
234.411 -
234.412 -(* The occL is a list of integers indicating which occurence
234.413 -w.r.t. the search order, to rewrite. Backtracking will also find later
234.414 -occurences, but all earlier ones are skipped. Thus you can use [0] to
234.415 -just find all rewrites. *)
234.416 -
234.417 -fun eqsubst_tac ctxt occL thms i th =
234.418 - let val nprems = Thm.nprems_of th in
234.419 - if nprems < i then Seq.empty else
234.420 - let val thmseq = (Seq.of_list thms)
234.421 - fun apply_occ occ th =
234.422 - thmseq |> Seq.maps
234.423 - (fn r => eqsubst_tac'
234.424 - ctxt
234.425 - (skip_first_occs_search
234.426 - occ searchf_lr_unify_valid) r
234.427 - (i + ((Thm.nprems_of th) - nprems))
234.428 - th);
234.429 - val sortedoccL =
234.430 - Library.sort (Library.rev_order o Library.int_ord) occL;
234.431 - in
234.432 - Seq.map distinct_subgoals (Seq.EVERY (map apply_occ sortedoccL) th)
234.433 - end
234.434 - end
234.435 - handle THM _ => raise eqsubst_occL_exp ("THM",occL,thms,i,th);
234.436 -
234.437 -
234.438 -(* inthms are the given arguments in Isar, and treated as eqstep with
234.439 - the first one, then the second etc *)
234.440 -fun eqsubst_meth ctxt occL inthms =
234.441 - Method.SIMPLE_METHOD' (eqsubst_tac ctxt occL inthms);
234.442 -
234.443 -(* apply a substitution inside assumption j, keeps asm in the same place *)
234.444 -fun apply_subst_in_asm i th rule ((cfvs, j, ngoalprems, pth),m) =
234.445 - let
234.446 - val th2 = Thm.rotate_rule (j - 1) i th; (* put premice first *)
234.447 - val preelimrule =
234.448 - (RWInst.rw m rule pth)
234.449 - |> (Seq.hd o prune_params_tac)
234.450 - |> Thm.permute_prems 0 ~1 (* put old asm first *)
234.451 - |> IsaND.unfix_frees cfvs (* unfix any global params *)
234.452 - |> RWInst.beta_eta_contract; (* normal form *)
234.453 - (* val elimrule =
234.454 - preelimrule
234.455 - |> Tactic.make_elim (* make into elim rule *)
234.456 - |> Thm.lift_rule (th2, i); (* lift into context *)
234.457 - *)
234.458 - in
234.459 - (* ~j because new asm starts at back, thus we subtract 1 *)
234.460 - Seq.map (Thm.rotate_rule (~j) ((Thm.nprems_of rule) + i))
234.461 - (Tactic.dtac preelimrule i th2)
234.462 -
234.463 - (* (Thm.bicompose
234.464 - false (* use unification *)
234.465 - (true, (* elim resolution *)
234.466 - elimrule, (2 + (Thm.nprems_of rule)) - ngoalprems)
234.467 - i th2) *)
234.468 - end;
234.469 -
234.470 -
234.471 -(* prepare to substitute within the j'th premise of subgoal i of gth,
234.472 -using a meta-level equation. Note that we assume rule has var indicies
234.473 -zero'd. Note that we also assume that premt is the j'th premice of
234.474 -subgoal i of gth. Note the repetition of work done for each
234.475 -assumption, i.e. this can be made more efficient for search over
234.476 -multiple assumptions. *)
234.477 -fun prep_subst_in_asm i gth j =
234.478 - let
234.479 - val th = Thm.incr_indexes 1 gth;
234.480 - val tgt_term = Thm.prop_of th;
234.481 -
234.482 - val sgn = Thm.theory_of_thm th;
234.483 - val ctermify = Thm.cterm_of sgn;
234.484 - val trivify = Thm.trivial o ctermify;
234.485 -
234.486 - val (fixedbody, fvs) = IsaND.fix_alls_term i tgt_term;
234.487 - val cfvs = rev (map ctermify fvs);
234.488 -
234.489 - val asmt = nth (Logic.strip_imp_prems fixedbody) (j - 1);
234.490 - val asm_nprems = length (Logic.strip_imp_prems asmt);
234.491 -
234.492 - val pth = trivify asmt;
234.493 - val maxidx = Thm.maxidx_of th;
234.494 -
234.495 - val ft = ((Z.move_down_right (* trueprop *)
234.496 - o Z.mktop
234.497 - o Thm.prop_of) pth)
234.498 - in ((cfvs, j, asm_nprems, pth), (sgn, maxidx, ft)) end;
234.499 -
234.500 -(* prepare subst in every possible assumption *)
234.501 -fun prep_subst_in_asms i gth =
234.502 - map (prep_subst_in_asm i gth)
234.503 - ((fn l => Library.upto (1, length l))
234.504 - (Logic.prems_of_goal (Thm.prop_of gth) i));
234.505 -
234.506 -
234.507 -(* substitute in an assumption using an object or meta level equality *)
234.508 -fun eqsubst_asm_tac' ctxt searchf skipocc instepthm i th =
234.509 - let
234.510 - val asmpreps = prep_subst_in_asms i th;
234.511 - val stepthms = Seq.of_list (prep_meta_eq ctxt instepthm);
234.512 - fun rewrite_with_thm r =
234.513 - let val (lhs,_) = Logic.dest_equals (Thm.concl_of r)
234.514 - fun occ_search occ [] = Seq.empty
234.515 - | occ_search occ ((asminfo, searchinfo)::moreasms) =
234.516 - (case searchf searchinfo occ lhs of
234.517 - SkipMore i => occ_search i moreasms
234.518 - | SkipSeq ss =>
234.519 - Seq.append (Seq.map (Library.pair asminfo) (Seq.flat ss))
234.520 - (occ_search 1 moreasms))
234.521 - (* find later substs also *)
234.522 - in
234.523 - occ_search skipocc asmpreps |> Seq.maps (apply_subst_in_asm i th r)
234.524 - end;
234.525 - in stepthms |> Seq.maps rewrite_with_thm end;
234.526 -
234.527 -
234.528 -fun skip_first_asm_occs_search searchf sinfo occ lhs =
234.529 - skipto_skipseq occ (searchf sinfo lhs);
234.530 -
234.531 -fun eqsubst_asm_tac ctxt occL thms i th =
234.532 - let val nprems = Thm.nprems_of th
234.533 - in
234.534 - if nprems < i then Seq.empty else
234.535 - let val thmseq = (Seq.of_list thms)
234.536 - fun apply_occ occK th =
234.537 - thmseq |> Seq.maps
234.538 - (fn r =>
234.539 - eqsubst_asm_tac' ctxt (skip_first_asm_occs_search
234.540 - searchf_lr_unify_valid) occK r
234.541 - (i + ((Thm.nprems_of th) - nprems))
234.542 - th);
234.543 - val sortedoccs =
234.544 - Library.sort (Library.rev_order o Library.int_ord) occL
234.545 - in
234.546 - Seq.map distinct_subgoals
234.547 - (Seq.EVERY (map apply_occ sortedoccs) th)
234.548 - end
234.549 - end
234.550 - handle THM _ => raise eqsubst_occL_exp ("THM",occL,thms,i,th);
234.551 -
234.552 -(* inthms are the given arguments in Isar, and treated as eqstep with
234.553 - the first one, then the second etc *)
234.554 -fun eqsubst_asm_meth ctxt occL inthms =
234.555 - Method.SIMPLE_METHOD' (eqsubst_asm_tac ctxt occL inthms);
234.556 -
234.557 -(* syntax for options, given "(asm)" will give back true, without
234.558 - gives back false *)
234.559 -val options_syntax =
234.560 - (Args.parens (Args.$$$ "asm") >> (K true)) ||
234.561 - (Scan.succeed false);
234.562 -
234.563 -val ith_syntax =
234.564 - Scan.optional (Args.parens (Scan.repeat OuterParse.nat)) [0];
234.565 -
234.566 -(* combination method that takes a flag (true indicates that subst
234.567 -should be done to an assumption, false = apply to the conclusion of
234.568 -the goal) as well as the theorems to use *)
234.569 -fun subst_meth src =
234.570 - Method.syntax ((Scan.lift options_syntax) -- (Scan.lift ith_syntax) -- Attrib.thms) src
234.571 - #> (fn (((asmflag, occL), inthms), ctxt) =>
234.572 - (if asmflag then eqsubst_asm_meth else eqsubst_meth) ctxt occL inthms);
234.573 -
234.574 -
234.575 -val setup =
234.576 - Method.add_method ("subst", subst_meth, "single-step substitution");
234.577 -
234.578 -end;
235.1 --- a/src/Provers/project_rule.ML Wed Mar 04 11:05:02 2009 +0100
235.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
235.3 @@ -1,63 +0,0 @@
235.4 -(* Title: Provers/project_rule.ML
235.5 - ID: $Id$
235.6 - Author: Makarius
235.7 -
235.8 -Transform mutual rule:
235.9 - HH ==> (x1:A1 --> P1 x1) & ... & (xn:An --> Pn xn)
235.10 -into projection:
235.11 - xi:Ai ==> HH ==> Pi xi
235.12 -*)
235.13 -
235.14 -signature PROJECT_RULE_DATA =
235.15 -sig
235.16 - val conjunct1: thm
235.17 - val conjunct2: thm
235.18 - val mp: thm
235.19 -end;
235.20 -
235.21 -signature PROJECT_RULE =
235.22 -sig
235.23 - val project: Proof.context -> int -> thm -> thm
235.24 - val projects: Proof.context -> int list -> thm -> thm list
235.25 - val projections: Proof.context -> thm -> thm list
235.26 -end;
235.27 -
235.28 -functor ProjectRuleFun(Data: PROJECT_RULE_DATA): PROJECT_RULE =
235.29 -struct
235.30 -
235.31 -fun conj1 th = th RS Data.conjunct1;
235.32 -fun conj2 th = th RS Data.conjunct2;
235.33 -fun imp th = th RS Data.mp;
235.34 -
235.35 -fun projects ctxt is raw_rule =
235.36 - let
235.37 - fun proj 1 th = the_default th (try conj1 th)
235.38 - | proj k th = proj (k - 1) (conj2 th);
235.39 - fun prems k th =
235.40 - (case try imp th of
235.41 - NONE => (k, th)
235.42 - | SOME th' => prems (k + 1) th');
235.43 - val ((_, [rule]), ctxt') = Variable.import_thms true [raw_rule] ctxt;
235.44 - fun result i =
235.45 - rule
235.46 - |> proj i
235.47 - |> prems 0 |-> (fn k =>
235.48 - Thm.permute_prems 0 (~ k)
235.49 - #> singleton (Variable.export ctxt' ctxt)
235.50 - #> Drule.zero_var_indexes
235.51 - #> RuleCases.save raw_rule
235.52 - #> RuleCases.add_consumes k);
235.53 - in map result is end;
235.54 -
235.55 -fun project ctxt i th = hd (projects ctxt [i] th);
235.56 -
235.57 -fun projections ctxt raw_rule =
235.58 - let
235.59 - fun projs k th =
235.60 - (case try conj2 th of
235.61 - NONE => k
235.62 - | SOME th' => projs (k + 1) th');
235.63 - val ((_, [rule]), _) = Variable.import_thms true [raw_rule] ctxt;
235.64 - in projects ctxt (1 upto projs 1 rule) raw_rule end;
235.65 -
235.66 -end;
236.1 --- a/src/Pure/Isar/find_consts.ML Wed Mar 04 11:05:02 2009 +0100
236.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
236.3 @@ -1,120 +0,0 @@
236.4 -(* Title: find_consts.ML
236.5 - Author: Timothy Bourke and Gerwin Klein, NICTA
236.6 -
236.7 - Hoogle-like (http://www-users.cs.york.ac.uk/~ndm/hoogle) searching by type
236.8 - over constants, but matching is not fuzzy
236.9 -*)
236.10 -
236.11 -signature FIND_CONSTS =
236.12 -sig
236.13 - datatype criterion = Strict of string
236.14 - | Loose of string
236.15 - | Name of string
236.16 -
236.17 - val default_criteria : (bool * criterion) list ref
236.18 -
236.19 - val find_consts : Proof.context -> (bool * criterion) list -> unit
236.20 -end;
236.21 -
236.22 -structure FindConsts : FIND_CONSTS =
236.23 -struct
236.24 -
236.25 -datatype criterion = Strict of string
236.26 - | Loose of string
236.27 - | Name of string;
236.28 -
236.29 -val default_criteria = ref [(false, Name ".sko_")];
236.30 -
236.31 -fun add_tye (_, (_, t)) n = size_of_typ t + n;
236.32 -
236.33 -fun matches_subtype thy typat = let
236.34 - val p = can (fn ty => Sign.typ_match thy (typat, ty) Vartab.empty);
236.35 -
236.36 - fun fs [] = false
236.37 - | fs (t::ts) = f t orelse fs ts
236.38 -
236.39 - and f (t as Type (_, ars)) = p t orelse fs ars
236.40 - | f t = p t;
236.41 - in f end;
236.42 -
236.43 -fun check_const p (nm, (ty, _)) = if p (nm, ty)
236.44 - then SOME (size_of_typ ty)
236.45 - else NONE;
236.46 -
236.47 -fun opt_not f (c as (_, (ty, _))) = if is_some (f c)
236.48 - then NONE else SOME (size_of_typ ty);
236.49 -
236.50 -fun filter_const (_, NONE) = NONE
236.51 - | filter_const (f, (SOME (c, r))) = Option.map
236.52 - (pair c o ((curry Int.min) r)) (f c);
236.53 -
236.54 -fun pretty_criterion (b, c) =
236.55 - let
236.56 - fun prfx s = if b then s else "-" ^ s;
236.57 - in
236.58 - (case c of
236.59 - Strict pat => Pretty.str (prfx "strict: " ^ quote pat)
236.60 - | Loose pat => Pretty.str (prfx (quote pat))
236.61 - | Name name => Pretty.str (prfx "name: " ^ quote name))
236.62 - end;
236.63 -
236.64 -fun pretty_const ctxt (nm, ty) = let
236.65 - val ty' = Logic.unvarifyT ty;
236.66 - in
236.67 - Pretty.block [Pretty.quote (Pretty.str nm), Pretty.fbrk,
236.68 - Pretty.str "::", Pretty.brk 1,
236.69 - Pretty.quote (Syntax.pretty_typ ctxt ty')]
236.70 - end;
236.71 -
236.72 -fun find_consts ctxt raw_criteria = let
236.73 - val start = start_timing ();
236.74 -
236.75 - val thy = ProofContext.theory_of ctxt;
236.76 - val low_ranking = 10000;
236.77 -
236.78 - fun make_pattern crit = ProofContext.read_term_pattern ctxt ("_::" ^ crit)
236.79 - |> type_of;
236.80 -
236.81 - fun make_match (Strict arg) =
236.82 - let val qty = make_pattern arg; in
236.83 - fn (_, (ty, _)) => let
236.84 - val tye = Sign.typ_match thy (qty, ty) Vartab.empty;
236.85 - val sub_size = Vartab.fold add_tye tye 0;
236.86 - in SOME sub_size end handle MATCH => NONE
236.87 - end
236.88 -
236.89 - | make_match (Loose arg) =
236.90 - check_const (matches_subtype thy (make_pattern arg) o snd)
236.91 -
236.92 - | make_match (Name arg) = check_const (match_string arg o fst);
236.93 -
236.94 - fun make_criterion (b, crit) = (if b then I else opt_not) (make_match crit);
236.95 - val criteria = map make_criterion ((!default_criteria) @ raw_criteria);
236.96 -
236.97 - val (_, consts) = (#constants o Consts.dest o Sign.consts_of) thy;
236.98 - fun eval_entry c = foldl filter_const (SOME (c, low_ranking)) criteria;
236.99 -
236.100 - val matches = Symtab.fold (cons o eval_entry) consts []
236.101 - |> map_filter I
236.102 - |> sort (rev_order o int_ord o pairself snd)
236.103 - |> map ((apsnd fst) o fst);
236.104 -
236.105 - val end_msg = " in " ^
236.106 - (List.nth (String.tokens Char.isSpace (end_timing start), 3))
236.107 - ^ " secs"
236.108 - in
236.109 - Pretty.big_list "searched for:" (map pretty_criterion raw_criteria)
236.110 - :: Pretty.str ""
236.111 - :: (Pretty.str o concat)
236.112 - (if null matches
236.113 - then ["nothing found", end_msg]
236.114 - else ["found ", (string_of_int o length) matches,
236.115 - " constants", end_msg, ":"])
236.116 - :: Pretty.str ""
236.117 - :: map (pretty_const ctxt) matches
236.118 - |> Pretty.chunks
236.119 - |> Pretty.writeln
236.120 - end handle ERROR s => Output.error_msg s
236.121 -
236.122 -end;
236.123 -
237.1 --- a/src/Pure/Isar/find_theorems.ML Wed Mar 04 11:05:02 2009 +0100
237.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
237.3 @@ -1,378 +0,0 @@
237.4 -(* Title: Pure/Isar/find_theorems.ML
237.5 - Author: Rafal Kolanski and Gerwin Klein, NICTA
237.6 -
237.7 -Retrieve theorems from proof context.
237.8 -*)
237.9 -
237.10 -signature FIND_THEOREMS =
237.11 -sig
237.12 - val limit: int ref
237.13 - val tac_limit: int ref
237.14 -
237.15 - datatype 'term criterion =
237.16 - Name of string | Intro | Elim | Dest | Solves | Simp of 'term |
237.17 - Pattern of 'term
237.18 -
237.19 - val find_theorems: Proof.context -> thm option -> bool ->
237.20 - (bool * string criterion) list -> (Facts.ref * thm) list
237.21 -
237.22 - val print_theorems: Proof.context -> thm option -> int option -> bool ->
237.23 - (bool * string criterion) list -> unit
237.24 -end;
237.25 -
237.26 -structure FindTheorems: FIND_THEOREMS =
237.27 -struct
237.28 -
237.29 -(** search criteria **)
237.30 -
237.31 -datatype 'term criterion =
237.32 - Name of string | Intro | Elim | Dest | Solves | Simp of 'term |
237.33 - Pattern of 'term;
237.34 -
237.35 -fun read_criterion _ (Name name) = Name name
237.36 - | read_criterion _ Intro = Intro
237.37 - | read_criterion _ Elim = Elim
237.38 - | read_criterion _ Dest = Dest
237.39 - | read_criterion _ Solves = Solves
237.40 - | read_criterion ctxt (Simp str) = Simp (ProofContext.read_term_pattern ctxt str)
237.41 - | read_criterion ctxt (Pattern str) = Pattern (ProofContext.read_term_pattern ctxt str);
237.42 -
237.43 -fun pretty_criterion ctxt (b, c) =
237.44 - let
237.45 - fun prfx s = if b then s else "-" ^ s;
237.46 - in
237.47 - (case c of
237.48 - Name name => Pretty.str (prfx "name: " ^ quote name)
237.49 - | Intro => Pretty.str (prfx "intro")
237.50 - | Elim => Pretty.str (prfx "elim")
237.51 - | Dest => Pretty.str (prfx "dest")
237.52 - | Solves => Pretty.str (prfx "solves")
237.53 - | Simp pat => Pretty.block [Pretty.str (prfx "simp:"), Pretty.brk 1,
237.54 - Pretty.quote (Syntax.pretty_term ctxt (Term.show_dummy_patterns pat))]
237.55 - | Pattern pat => Pretty.enclose (prfx " \"") "\""
237.56 - [Syntax.pretty_term ctxt (Term.show_dummy_patterns pat)])
237.57 - end;
237.58 -
237.59 -(** search criterion filters **)
237.60 -
237.61 -(*generated filters are to be of the form
237.62 - input: (Facts.ref * thm)
237.63 - output: (p:int, s:int) option, where
237.64 - NONE indicates no match
237.65 - p is the primary sorting criterion
237.66 - (eg. number of assumptions in the theorem)
237.67 - s is the secondary sorting criterion
237.68 - (eg. size of the substitution for intro, elim and dest)
237.69 - when applying a set of filters to a thm, fold results in:
237.70 - (biggest p, sum of all s)
237.71 - currently p and s only matter for intro, elim, dest and simp filters,
237.72 - otherwise the default ordering is used.
237.73 -*)
237.74 -
237.75 -
237.76 -(* matching theorems *)
237.77 -
237.78 -fun is_nontrivial thy = Term.is_Const o Term.head_of o ObjectLogic.drop_judgment thy;
237.79 -
237.80 -(*extract terms from term_src, refine them to the parts that concern us,
237.81 - if po try match them against obj else vice versa.
237.82 - trivial matches are ignored.
237.83 - returns: smallest substitution size*)
237.84 -fun is_matching_thm (extract_terms, refine_term) ctxt po obj term_src =
237.85 - let
237.86 - val thy = ProofContext.theory_of ctxt;
237.87 -
237.88 - fun matches pat =
237.89 - is_nontrivial thy pat andalso
237.90 - Pattern.matches thy (if po then (pat, obj) else (obj, pat));
237.91 -
237.92 - fun substsize pat =
237.93 - let val (_, subst) =
237.94 - Pattern.match thy (if po then (pat, obj) else (obj, pat)) (Vartab.empty, Vartab.empty)
237.95 - in Vartab.fold (fn (_, (_, t)) => fn n => size_of_term t + n) subst 0 end;
237.96 -
237.97 - fun bestmatch [] = NONE
237.98 - | bestmatch xs = SOME (foldr1 Int.min xs);
237.99 -
237.100 - val match_thm = matches o refine_term;
237.101 - in
237.102 - map (substsize o refine_term) (filter match_thm (extract_terms term_src))
237.103 - |> bestmatch
237.104 - end;
237.105 -
237.106 -
237.107 -(* filter_name *)
237.108 -
237.109 -fun filter_name str_pat (thmref, _) =
237.110 - if match_string str_pat (Facts.name_of_ref thmref)
237.111 - then SOME (0, 0) else NONE;
237.112 -
237.113 -(* filter intro/elim/dest/solves rules *)
237.114 -
237.115 -fun filter_dest ctxt goal (_, thm) =
237.116 - let
237.117 - val extract_dest =
237.118 - (fn thm => if Thm.no_prems thm then [] else [Thm.full_prop_of thm],
237.119 - hd o Logic.strip_imp_prems);
237.120 - val prems = Logic.prems_of_goal goal 1;
237.121 -
237.122 - fun try_subst prem = is_matching_thm extract_dest ctxt true prem thm;
237.123 - val successful = prems |> map_filter try_subst;
237.124 - in
237.125 - (*if possible, keep best substitution (one with smallest size)*)
237.126 - (*dest rules always have assumptions, so a dest with one
237.127 - assumption is as good as an intro rule with none*)
237.128 - if not (null successful)
237.129 - then SOME (Thm.nprems_of thm - 1, foldr1 Int.min successful) else NONE
237.130 - end;
237.131 -
237.132 -fun filter_intro ctxt goal (_, thm) =
237.133 - let
237.134 - val extract_intro = (single o Thm.full_prop_of, Logic.strip_imp_concl);
237.135 - val concl = Logic.concl_of_goal goal 1;
237.136 - val ss = is_matching_thm extract_intro ctxt true concl thm;
237.137 - in
237.138 - if is_some ss then SOME (Thm.nprems_of thm, the ss) else NONE
237.139 - end;
237.140 -
237.141 -fun filter_elim ctxt goal (_, thm) =
237.142 - if not (Thm.no_prems thm) then
237.143 - let
237.144 - val rule = Thm.full_prop_of thm;
237.145 - val prems = Logic.prems_of_goal goal 1;
237.146 - val goal_concl = Logic.concl_of_goal goal 1;
237.147 - val rule_mp = hd (Logic.strip_imp_prems rule);
237.148 - val rule_concl = Logic.strip_imp_concl rule;
237.149 - fun combine t1 t2 = Const ("*combine*", dummyT --> dummyT) $ (t1 $ t2);
237.150 - val rule_tree = combine rule_mp rule_concl;
237.151 - fun goal_tree prem = combine prem goal_concl;
237.152 - fun try_subst prem =
237.153 - is_matching_thm (single, I) ctxt true (goal_tree prem) rule_tree;
237.154 - val successful = prems |> map_filter try_subst;
237.155 - in
237.156 - (*elim rules always have assumptions, so an elim with one
237.157 - assumption is as good as an intro rule with none*)
237.158 - if is_nontrivial (ProofContext.theory_of ctxt) (Thm.major_prem_of thm)
237.159 - andalso not (null successful)
237.160 - then SOME (Thm.nprems_of thm - 1, foldr1 Int.min successful) else NONE
237.161 - end
237.162 - else NONE
237.163 -
237.164 -val tac_limit = ref 5;
237.165 -
237.166 -fun filter_solves ctxt goal = let
237.167 - val baregoal = Logic.get_goal (prop_of goal) 1;
237.168 -
237.169 - fun etacn thm i = Seq.take (!tac_limit) o etac thm i;
237.170 - fun try_thm thm = if Thm.no_prems thm then rtac thm 1 goal
237.171 - else (etacn thm THEN_ALL_NEW
237.172 - (Goal.norm_hhf_tac THEN'
237.173 - Method.assumption_tac ctxt)) 1 goal;
237.174 - in
237.175 - fn (_, thm) => if (is_some o Seq.pull o try_thm) thm
237.176 - then SOME (Thm.nprems_of thm, 0) else NONE
237.177 - end;
237.178 -
237.179 -(* filter_simp *)
237.180 -
237.181 -fun filter_simp ctxt t (_, thm) =
237.182 - let
237.183 - val (_, {mk_rews = {mk, ...}, ...}) =
237.184 - Simplifier.rep_ss (Simplifier.local_simpset_of ctxt);
237.185 - val extract_simp =
237.186 - (map Thm.full_prop_of o mk, #1 o Logic.dest_equals o Logic.strip_imp_concl);
237.187 - val ss = is_matching_thm extract_simp ctxt false t thm
237.188 - in
237.189 - if is_some ss then SOME (Thm.nprems_of thm, the ss) else NONE
237.190 - end;
237.191 -
237.192 -
237.193 -(* filter_pattern *)
237.194 -
237.195 -fun get_names t = (Term.add_const_names t []) union (Term.add_free_names t []);
237.196 -fun get_thm_names (_, thm) = get_names (Thm.full_prop_of thm);
237.197 - (* Including all constants and frees is only sound because
237.198 - matching uses higher-order patterns. If full matching
237.199 - were used, then constants that may be subject to
237.200 - beta-reduction after substitution of frees should
237.201 - not be included for LHS set because they could be
237.202 - thrown away by the substituted function.
237.203 - e.g. for (?F 1 2) do not include 1 or 2, if it were
237.204 - possible for ?F to be (% x y. 3)
237.205 - The largest possible set should always be included on
237.206 - the RHS. *)
237.207 -
237.208 -fun filter_pattern ctxt pat = let
237.209 - val pat_consts = get_names pat;
237.210 -
237.211 - fun check (t, NONE) = check (t, SOME (get_thm_names t))
237.212 - | check ((_, thm), c as SOME thm_consts) =
237.213 - (if pat_consts subset_string thm_consts
237.214 - andalso (Pattern.matches_subterm (ProofContext.theory_of ctxt)
237.215 - (pat, Thm.full_prop_of thm))
237.216 - then SOME (0, 0) else NONE, c);
237.217 - in check end;
237.218 -
237.219 -(* interpret criteria as filters *)
237.220 -
237.221 -local
237.222 -
237.223 -fun err_no_goal c =
237.224 - error ("Current goal required for " ^ c ^ " search criterion");
237.225 -
237.226 -val fix_goal = Thm.prop_of;
237.227 -val fix_goalo = Option.map fix_goal;
237.228 -
237.229 -fun filter_crit _ _ (Name name) = apfst (filter_name name)
237.230 - | filter_crit _ NONE Intro = err_no_goal "intro"
237.231 - | filter_crit _ NONE Elim = err_no_goal "elim"
237.232 - | filter_crit _ NONE Dest = err_no_goal "dest"
237.233 - | filter_crit _ NONE Solves = err_no_goal "solves"
237.234 - | filter_crit ctxt (SOME goal) Intro = apfst (filter_intro ctxt
237.235 - (fix_goal goal))
237.236 - | filter_crit ctxt (SOME goal) Elim = apfst (filter_elim ctxt
237.237 - (fix_goal goal))
237.238 - | filter_crit ctxt (SOME goal) Dest = apfst (filter_dest ctxt
237.239 - (fix_goal goal))
237.240 - | filter_crit ctxt (SOME goal) Solves = apfst (filter_solves ctxt goal)
237.241 - | filter_crit ctxt _ (Simp pat) = apfst (filter_simp ctxt pat)
237.242 - | filter_crit ctxt _ (Pattern pat) = filter_pattern ctxt pat;
237.243 -
237.244 -fun opt_not x = if is_some x then NONE else SOME (0, 0);
237.245 -
237.246 -fun opt_add (SOME (a, x)) (SOME (b, y)) = SOME (Int.max (a, b), x + y : int)
237.247 - | opt_add _ _ = NONE;
237.248 -
237.249 -fun app_filters thm = let
237.250 - fun app (NONE, _, _) = NONE
237.251 - | app (SOME v, consts, []) = SOME (v, thm)
237.252 - | app (r, consts, f::fs) = let val (r', consts') = f (thm, consts)
237.253 - in app (opt_add r r', consts', fs) end;
237.254 - in app end;
237.255 -
237.256 -in
237.257 -
237.258 -fun filter_criterion ctxt opt_goal (b, c) =
237.259 - (if b then I else (apfst opt_not)) o filter_crit ctxt opt_goal c;
237.260 -
237.261 -fun all_filters filters thms =
237.262 - let
237.263 - fun eval_filters thm = app_filters thm (SOME (0, 0), NONE, filters);
237.264 -
237.265 - (*filters return: (number of assumptions, substitution size) option, so
237.266 - sort (desc. in both cases) according to number of assumptions first,
237.267 - then by the substitution size*)
237.268 - fun thm_ord (((p0, s0), _), ((p1, s1), _)) =
237.269 - prod_ord int_ord int_ord ((p1, s1), (p0, s0));
237.270 - in map_filter eval_filters thms |> sort thm_ord |> map #2 end;
237.271 -
237.272 -end;
237.273 -
237.274 -
237.275 -(* removing duplicates, preferring nicer names, roughly n log n *)
237.276 -
237.277 -local
237.278 -
237.279 -val index_ord = option_ord (K EQUAL);
237.280 -val hidden_ord = bool_ord o pairself NameSpace.is_hidden;
237.281 -val qual_ord = int_ord o pairself (length o NameSpace.explode);
237.282 -val txt_ord = int_ord o pairself size;
237.283 -
237.284 -fun nicer_name (x, i) (y, j) =
237.285 - (case hidden_ord (x, y) of EQUAL =>
237.286 - (case index_ord (i, j) of EQUAL =>
237.287 - (case qual_ord (x, y) of EQUAL => txt_ord (x, y) | ord => ord)
237.288 - | ord => ord)
237.289 - | ord => ord) <> GREATER;
237.290 -
237.291 -fun rem_cdups nicer xs =
237.292 - let
237.293 - fun rem_c rev_seen [] = rev rev_seen
237.294 - | rem_c rev_seen [x] = rem_c (x :: rev_seen) []
237.295 - | rem_c rev_seen ((x as ((n, t), _)) :: (y as ((n', t'), _)) :: xs) =
237.296 - if Thm.eq_thm_prop (t, t')
237.297 - then rem_c rev_seen ((if nicer n n' then x else y) :: xs)
237.298 - else rem_c (x :: rev_seen) (y :: xs)
237.299 - in rem_c [] xs end;
237.300 -
237.301 -in
237.302 -
237.303 -fun nicer_shortest ctxt = let
237.304 - val ns = ProofContext.theory_of ctxt
237.305 - |> PureThy.facts_of
237.306 - |> Facts.space_of;
237.307 -
237.308 - val len_sort = sort (int_ord o (pairself size));
237.309 - fun shorten s = (case len_sort (NameSpace.get_accesses ns s) of
237.310 - [] => s
237.311 - | s'::_ => s');
237.312 -
237.313 - fun nicer (Facts.Named ((x, _), i)) (Facts.Named ((y, _), j)) =
237.314 - nicer_name (shorten x, i) (shorten y, j)
237.315 - | nicer (Facts.Fact _) (Facts.Named _) = true
237.316 - | nicer (Facts.Named _) (Facts.Fact _) = false;
237.317 - in nicer end;
237.318 -
237.319 -fun rem_thm_dups nicer xs =
237.320 - xs ~~ (1 upto length xs)
237.321 - |> sort (TermOrd.fast_term_ord o pairself (Thm.prop_of o #2 o #1))
237.322 - |> rem_cdups nicer
237.323 - |> sort (int_ord o pairself #2)
237.324 - |> map #1;
237.325 -
237.326 -end;
237.327 -
237.328 -
237.329 -(* print_theorems *)
237.330 -
237.331 -fun all_facts_of ctxt =
237.332 - maps Facts.selections
237.333 - (Facts.dest_static [] (PureThy.facts_of (ProofContext.theory_of ctxt)) @
237.334 - Facts.dest_static [] (ProofContext.facts_of ctxt));
237.335 -
237.336 -val limit = ref 40;
237.337 -
237.338 -fun find_theorems ctxt opt_goal rem_dups raw_criteria =
237.339 - let
237.340 - val add_prems = Seq.hd o (TRY (Method.insert_tac
237.341 - (Assumption.prems_of ctxt) 1));
237.342 - val opt_goal' = Option.map add_prems opt_goal;
237.343 -
237.344 - val criteria = map (apsnd (read_criterion ctxt)) raw_criteria;
237.345 - val filters = map (filter_criterion ctxt opt_goal') criteria;
237.346 -
237.347 - val raw_matches = all_filters filters (all_facts_of ctxt);
237.348 -
237.349 - val matches =
237.350 - if rem_dups
237.351 - then rem_thm_dups (nicer_shortest ctxt) raw_matches
237.352 - else raw_matches;
237.353 - in matches end;
237.354 -
237.355 -fun print_theorems ctxt opt_goal opt_limit rem_dups raw_criteria = let
237.356 - val start = start_timing ();
237.357 -
237.358 - val criteria = map (apsnd (read_criterion ctxt)) raw_criteria;
237.359 - val matches = find_theorems ctxt opt_goal rem_dups raw_criteria;
237.360 -
237.361 - val len = length matches;
237.362 - val lim = the_default (! limit) opt_limit;
237.363 - val thms = Library.drop (len - lim, matches);
237.364 -
237.365 - val end_msg = " in " ^
237.366 - (List.nth (String.tokens Char.isSpace (end_timing start), 3))
237.367 - ^ " secs"
237.368 - in
237.369 - Pretty.big_list "searched for:" (map (pretty_criterion ctxt) criteria)
237.370 - :: Pretty.str "" ::
237.371 - (if null thms then [Pretty.str ("nothing found" ^ end_msg)]
237.372 - else
237.373 - [Pretty.str ("found " ^ string_of_int len ^ " theorems" ^
237.374 - (if len <= lim then ""
237.375 - else " (" ^ string_of_int lim ^ " displayed)")
237.376 - ^ end_msg ^ ":"), Pretty.str ""] @
237.377 - map Display.pretty_fact thms)
237.378 - |> Pretty.chunks |> Pretty.writeln
237.379 - end
237.380 -
237.381 -end;
238.1 --- a/src/Pure/Isar/isar.ML Wed Mar 04 11:05:02 2009 +0100
238.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
238.3 @@ -1,379 +0,0 @@
238.4 -(* Title: Pure/Isar/isar.ML
238.5 - Author: Makarius
238.6 -
238.7 -The global Isabelle/Isar state and main read-eval-print loop.
238.8 -*)
238.9 -
238.10 -signature ISAR =
238.11 -sig
238.12 - val init: unit -> unit
238.13 - val exn: unit -> (exn * string) option
238.14 - val state: unit -> Toplevel.state
238.15 - val context: unit -> Proof.context
238.16 - val goal: unit -> thm
238.17 - val print: unit -> unit
238.18 - val >> : Toplevel.transition -> bool
238.19 - val >>> : Toplevel.transition list -> unit
238.20 - val linear_undo: int -> unit
238.21 - val undo: int -> unit
238.22 - val kill: unit -> unit
238.23 - val kill_proof: unit -> unit
238.24 - val crashes: exn list ref
238.25 - val toplevel_loop: {init: bool, welcome: bool, sync: bool, secure: bool} -> unit
238.26 - val loop: unit -> unit
238.27 - val main: unit -> unit
238.28 -
238.29 - type id = string
238.30 - val no_id: id
238.31 - val create_command: Toplevel.transition -> id
238.32 - val insert_command: id -> id -> unit
238.33 - val remove_command: id -> unit
238.34 -end;
238.35 -
238.36 -structure Isar: ISAR =
238.37 -struct
238.38 -
238.39 -
238.40 -(** TTY model -- SINGLE-THREADED! **)
238.41 -
238.42 -(* the global state *)
238.43 -
238.44 -type history = (Toplevel.state * Toplevel.transition) list;
238.45 - (*previous state, state transition -- regular commands only*)
238.46 -
238.47 -local
238.48 - val global_history = ref ([]: history);
238.49 - val global_state = ref Toplevel.toplevel;
238.50 - val global_exn = ref (NONE: (exn * string) option);
238.51 -in
238.52 -
238.53 -fun edit_history count f = NAMED_CRITICAL "Isar" (fn () =>
238.54 - let
238.55 - fun edit 0 (st, hist) = (global_history := hist; global_state := st; global_exn := NONE)
238.56 - | edit n (st, hist) = edit (n - 1) (f st hist);
238.57 - in edit count (! global_state, ! global_history) end);
238.58 -
238.59 -fun state () = NAMED_CRITICAL "Isar" (fn () => ! global_state);
238.60 -fun set_state state = NAMED_CRITICAL "Isar" (fn () => global_state := state);
238.61 -
238.62 -fun exn () = NAMED_CRITICAL "Isar" (fn () => ! global_exn);
238.63 -fun set_exn exn = NAMED_CRITICAL "Isar" (fn () => global_exn := exn);
238.64 -
238.65 -end;
238.66 -
238.67 -
238.68 -fun init () = edit_history 1 (K (K (Toplevel.toplevel, [])));
238.69 -
238.70 -fun context () = Toplevel.context_of (state ())
238.71 - handle Toplevel.UNDEF => error "Unknown context";
238.72 -
238.73 -fun goal () = #2 (#2 (Proof.get_goal (Toplevel.proof_of (state ()))))
238.74 - handle Toplevel.UNDEF => error "No goal present";
238.75 -
238.76 -fun print () = Toplevel.print_state false (state ());
238.77 -
238.78 -
238.79 -(* history navigation *)
238.80 -
238.81 -local
238.82 -
238.83 -fun find_and_undo _ [] = error "Undo history exhausted"
238.84 - | find_and_undo which ((prev, tr) :: hist) =
238.85 - ((case Toplevel.init_of tr of SOME name => ThyInfo.kill_thy name | NONE => ());
238.86 - if which (Toplevel.name_of tr) then (prev, hist) else find_and_undo which hist);
238.87 -
238.88 -in
238.89 -
238.90 -fun linear_undo n = edit_history n (K (find_and_undo (K true)));
238.91 -
238.92 -fun undo n = edit_history n (fn st => fn hist =>
238.93 - find_and_undo (if Toplevel.is_proof st then K true else OuterKeyword.is_theory) hist);
238.94 -
238.95 -fun kill () = edit_history 1 (fn st => fn hist =>
238.96 - find_and_undo
238.97 - (if Toplevel.is_proof st then OuterKeyword.is_theory else OuterKeyword.is_theory_begin) hist);
238.98 -
238.99 -fun kill_proof () = edit_history 1 (fn st => fn hist =>
238.100 - if Toplevel.is_proof st then find_and_undo OuterKeyword.is_theory hist
238.101 - else raise Toplevel.UNDEF);
238.102 -
238.103 -end;
238.104 -
238.105 -
238.106 -(* interactive state transformations *)
238.107 -
238.108 -fun op >> tr =
238.109 - (case Toplevel.transition true tr (state ()) of
238.110 - NONE => false
238.111 - | SOME (_, SOME err) => (set_exn (SOME err); Toplevel.error_msg tr err; true)
238.112 - | SOME (st', NONE) =>
238.113 - let
238.114 - val name = Toplevel.name_of tr;
238.115 - val _ = if OuterKeyword.is_theory_begin name then init () else ();
238.116 - val _ =
238.117 - if OuterKeyword.is_regular name
238.118 - then edit_history 1 (fn st => fn hist => (st', (st, tr) :: hist)) else ();
238.119 - in true end);
238.120 -
238.121 -fun op >>> [] = ()
238.122 - | op >>> (tr :: trs) = if op >> tr then op >>> trs else ();
238.123 -
238.124 -
238.125 -(* toplevel loop *)
238.126 -
238.127 -val crashes = ref ([]: exn list);
238.128 -
238.129 -local
238.130 -
238.131 -fun raw_loop secure src =
238.132 - let
238.133 - fun check_secure () =
238.134 - (if secure then warning "Secure loop -- cannot exit to ML" else (); secure);
238.135 - in
238.136 - (case Source.get_single (Source.set_prompt Source.default_prompt src) of
238.137 - NONE => if secure then quit () else ()
238.138 - | SOME (tr, src') => if op >> tr orelse check_secure () then raw_loop secure src' else ())
238.139 - handle exn =>
238.140 - (Output.error_msg (Toplevel.exn_message exn)
238.141 - handle crash =>
238.142 - (CRITICAL (fn () => change crashes (cons crash));
238.143 - warning "Recovering from Isar toplevel crash -- see also Isar.crashes");
238.144 - raw_loop secure src)
238.145 - end;
238.146 -
238.147 -in
238.148 -
238.149 -fun toplevel_loop {init = do_init, welcome, sync, secure} =
238.150 - (Context.set_thread_data NONE;
238.151 - if do_init then init () else (); (* FIXME init editor model *)
238.152 - if welcome then writeln (Session.welcome ()) else ();
238.153 - uninterruptible (fn _ => fn () => raw_loop secure (OuterSyntax.isar sync)) ());
238.154 -
238.155 -end;
238.156 -
238.157 -fun loop () =
238.158 - toplevel_loop {init = false, welcome = false, sync = false, secure = Secure.is_secure ()};
238.159 -
238.160 -fun main () =
238.161 - toplevel_loop {init = true, welcome = true, sync = false, secure = Secure.is_secure ()};
238.162 -
238.163 -
238.164 -
238.165 -(** individual toplevel commands **)
238.166 -
238.167 -(* unique identification *)
238.168 -
238.169 -type id = string;
238.170 -val no_id : id = "";
238.171 -
238.172 -
238.173 -(* command category *)
238.174 -
238.175 -datatype category = Empty | Theory | Proof | Diag | Control;
238.176 -
238.177 -fun category_of tr =
238.178 - let val name = Toplevel.name_of tr in
238.179 - if name = "" then Empty
238.180 - else if OuterKeyword.is_theory name then Theory
238.181 - else if OuterKeyword.is_proof name then Proof
238.182 - else if OuterKeyword.is_diag name then Diag
238.183 - else Control
238.184 - end;
238.185 -
238.186 -val is_theory = fn Theory => true | _ => false;
238.187 -val is_proper = fn Theory => true | Proof => true | _ => false;
238.188 -val is_regular = fn Control => false | _ => true;
238.189 -
238.190 -
238.191 -(* command status *)
238.192 -
238.193 -datatype status =
238.194 - Unprocessed |
238.195 - Running |
238.196 - Failed of exn * string |
238.197 - Finished of Toplevel.state;
238.198 -
238.199 -fun status_markup Unprocessed = Markup.unprocessed
238.200 - | status_markup Running = (Markup.runningN, [])
238.201 - | status_markup (Failed _) = Markup.failed
238.202 - | status_markup (Finished _) = Markup.finished;
238.203 -
238.204 -fun run int tr state =
238.205 - (case Toplevel.transition int tr state of
238.206 - NONE => NONE
238.207 - | SOME (_, SOME err) => (Toplevel.error_msg tr err; SOME (Failed err))
238.208 - | SOME (state', NONE) => SOME (Finished state'));
238.209 -
238.210 -
238.211 -(* datatype command *)
238.212 -
238.213 -datatype command = Command of
238.214 - {category: category,
238.215 - transition: Toplevel.transition,
238.216 - status: status};
238.217 -
238.218 -fun make_command (category, transition, status) =
238.219 - Command {category = category, transition = transition, status = status};
238.220 -
238.221 -val empty_command =
238.222 - make_command (Empty, Toplevel.empty, Finished Toplevel.toplevel);
238.223 -
238.224 -fun map_command f (Command {category, transition, status}) =
238.225 - make_command (f (category, transition, status));
238.226 -
238.227 -fun map_status f = map_command (fn (category, transition, status) =>
238.228 - (category, transition, f status));
238.229 -
238.230 -
238.231 -(* global collection of identified commands *)
238.232 -
238.233 -fun err_dup id = sys_error ("Duplicate command " ^ quote id);
238.234 -fun err_undef id = sys_error ("Unknown command " ^ quote id);
238.235 -
238.236 -local val global_commands = ref (Graph.empty: command Graph.T) in
238.237 -
238.238 -fun change_commands f = NAMED_CRITICAL "Isar" (fn () => change global_commands f)
238.239 - handle Graph.DUP bad => err_dup bad | Graph.UNDEF bad => err_undef bad;
238.240 -
238.241 -fun get_commands () = NAMED_CRITICAL "Isar" (fn () => ! global_commands);
238.242 -
238.243 -end;
238.244 -
238.245 -fun add_edge (id1, id2) =
238.246 - if id1 = no_id orelse id2 = no_id then I else Graph.add_edge (id1, id2);
238.247 -
238.248 -
238.249 -fun init_commands () = change_commands (K Graph.empty);
238.250 -
238.251 -fun the_command id =
238.252 - let val Command cmd =
238.253 - if id = no_id then empty_command
238.254 - else (Graph.get_node (get_commands ()) id handle Graph.UNDEF bad => err_undef bad)
238.255 - in cmd end;
238.256 -
238.257 -fun prev_command id =
238.258 - if id = no_id then no_id
238.259 - else
238.260 - (case Graph.imm_preds (get_commands ()) id handle Graph.UNDEF bad => err_undef bad of
238.261 - [] => no_id
238.262 - | [prev] => prev
238.263 - | _ => sys_error ("Non-linear command dependency " ^ quote id));
238.264 -
238.265 -fun next_commands id =
238.266 - if id = no_id then []
238.267 - else Graph.imm_succs (get_commands ()) id handle Graph.UNDEF bad => err_undef bad;
238.268 -
238.269 -fun descendant_commands ids =
238.270 - Graph.all_succs (get_commands ()) (distinct (op =) (filter_out (fn id => id = no_id) ids))
238.271 - handle Graph.UNDEF bad => err_undef bad;
238.272 -
238.273 -
238.274 -(* maintain status *)
238.275 -
238.276 -fun report_status markup id = Toplevel.status (#transition (the_command id)) markup;
238.277 -
238.278 -fun update_status status id = change_commands (Graph.map_node id (map_status (K status)));
238.279 -
238.280 -fun report_update_status status id =
238.281 - change_commands (Graph.map_node id (map_status (fn old_status =>
238.282 - let val markup = status_markup status
238.283 - in if markup <> status_markup old_status then report_status markup id else (); status end)));
238.284 -
238.285 -
238.286 -(* create and dispose commands *)
238.287 -
238.288 -fun create_command raw_tr =
238.289 - let
238.290 - val (id, tr) =
238.291 - (case Toplevel.get_id raw_tr of
238.292 - SOME id => (id, raw_tr)
238.293 - | NONE =>
238.294 - let val id =
238.295 - if ! Toplevel.debug then "isabelle:" ^ Toplevel.name_of raw_tr ^ serial_string ()
238.296 - else "isabelle:" ^ serial_string ()
238.297 - in (id, Toplevel.put_id id raw_tr) end);
238.298 -
238.299 - val cmd = make_command (category_of tr, tr, Unprocessed);
238.300 - val _ = change_commands (Graph.new_node (id, cmd));
238.301 - in id end;
238.302 -
238.303 -fun dispose_commands ids =
238.304 - let
238.305 - val desc = descendant_commands ids;
238.306 - val _ = List.app (report_status Markup.disposed) desc;
238.307 - val _ = change_commands (Graph.del_nodes desc);
238.308 - in () end;
238.309 -
238.310 -
238.311 -(* final state *)
238.312 -
238.313 -fun the_state id =
238.314 - (case the_command id of
238.315 - {status = Finished state, ...} => state
238.316 - | {transition, ...} => error ("Unfinished command " ^ Toplevel.str_of transition));
238.317 -
238.318 -
238.319 -
238.320 -(** editor model **)
238.321 -
238.322 -(* run commands *)
238.323 -
238.324 -fun try_run id =
238.325 - (case try the_state (prev_command id) of
238.326 - NONE => ()
238.327 - | SOME state =>
238.328 - (case run true (#transition (the_command id)) state of
238.329 - NONE => ()
238.330 - | SOME status => report_update_status status id));
238.331 -
238.332 -fun rerun_commands ids =
238.333 - (List.app (report_update_status Unprocessed) ids; List.app try_run ids);
238.334 -
238.335 -
238.336 -(* modify document *)
238.337 -
238.338 -fun insert_command prev id = NAMED_CRITICAL "Isar" (fn () =>
238.339 - let
238.340 - val nexts = next_commands prev;
238.341 - val _ = change_commands
238.342 - (fold (fn next => Graph.del_edge (prev, next)) nexts #> add_edge (prev, id) #>
238.343 - fold (fn next => Graph.add_edge (id, next)) nexts);
238.344 - in descendant_commands [id] end) |> rerun_commands;
238.345 -
238.346 -fun remove_command id = NAMED_CRITICAL "Isar" (fn () =>
238.347 - let
238.348 - val prev = prev_command id;
238.349 - val nexts = next_commands id;
238.350 - val _ = change_commands
238.351 - (fold (fn next => Graph.del_edge (id, next)) nexts #>
238.352 - fold (fn next => add_edge (prev, next)) nexts);
238.353 - in descendant_commands nexts end) |> rerun_commands;
238.354 -
238.355 -
238.356 -(* concrete syntax *)
238.357 -
238.358 -local
238.359 -
238.360 -structure P = OuterParse;
238.361 -val op >> = Scan.>>;
238.362 -
238.363 -in
238.364 -
238.365 -val _ =
238.366 - OuterSyntax.internal_command "Isar.command"
238.367 - (P.string -- P.string >> (fn (id, text) =>
238.368 - Toplevel.imperative (fn () =>
238.369 - ignore (create_command (OuterSyntax.prepare_command (Position.id id) text)))));
238.370 -
238.371 -val _ =
238.372 - OuterSyntax.internal_command "Isar.insert"
238.373 - (P.string -- P.string >> (fn (prev, id) =>
238.374 - Toplevel.imperative (fn () => insert_command prev id)));
238.375 -
238.376 -val _ =
238.377 - OuterSyntax.internal_command "Isar.remove"
238.378 - (P.string >> (fn id => Toplevel.imperative (fn () => remove_command id)));
238.379 -
238.380 -end;
238.381 -
238.382 -end;
239.1 --- a/src/Pure/Isar/session.ML Wed Mar 04 11:05:02 2009 +0100
239.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
239.3 @@ -1,105 +0,0 @@
239.4 -(* Title: Pure/Isar/session.ML
239.5 - Author: Markus Wenzel, TU Muenchen
239.6 -
239.7 -Session management -- maintain state of logic images.
239.8 -*)
239.9 -
239.10 -signature SESSION =
239.11 -sig
239.12 - val id: unit -> string list
239.13 - val name: unit -> string
239.14 - val welcome: unit -> string
239.15 - val use_dir: string -> bool -> string list -> bool -> bool -> string -> bool -> string list ->
239.16 - string -> string -> bool * string -> string -> int -> bool -> int -> int -> bool -> unit
239.17 - val finish: unit -> unit
239.18 -end;
239.19 -
239.20 -structure Session: SESSION =
239.21 -struct
239.22 -
239.23 -
239.24 -(* session state *)
239.25 -
239.26 -val session = ref ([Context.PureN]: string list);
239.27 -val session_path = ref ([]: string list);
239.28 -val session_finished = ref false;
239.29 -val remote_path = ref (NONE: Url.T option);
239.30 -
239.31 -
239.32 -(* access path *)
239.33 -
239.34 -fun id () = ! session;
239.35 -fun path () = ! session_path;
239.36 -
239.37 -fun str_of [] = Context.PureN
239.38 - | str_of elems = space_implode "/" elems;
239.39 -
239.40 -fun name () = "Isabelle/" ^ str_of (path ());
239.41 -
239.42 -fun welcome () =
239.43 - if Distribution.is_official then
239.44 - "Welcome to " ^ name () ^ " (" ^ Distribution.version ^ ")"
239.45 - else
239.46 - "Unofficial version of " ^ name () ^ " (" ^ Distribution.version ^ ")" ^
239.47 - (if Distribution.changelog <> "" then "\nSee also " ^ Distribution.changelog else "");
239.48 -
239.49 -
239.50 -(* add_path *)
239.51 -
239.52 -fun add_path reset s =
239.53 - let val sess = ! session @ [s] in
239.54 - (case duplicates (op =) sess of
239.55 - [] => (session := sess; session_path := ((if reset then [] else ! session_path) @ [s]))
239.56 - | dups => error ("Duplicate session identifiers " ^ commas_quote dups ^ " in " ^ str_of sess))
239.57 - end;
239.58 -
239.59 -
239.60 -(* init *)
239.61 -
239.62 -fun init reset parent name =
239.63 - if not (member (op =) (! session) parent) orelse not (! session_finished) then
239.64 - error ("Unfinished parent session " ^ quote parent ^ " for " ^ quote name)
239.65 - else (add_path reset name; session_finished := false);
239.66 -
239.67 -
239.68 -(* finish *)
239.69 -
239.70 -fun finish () =
239.71 - (Output.accumulated_time ();
239.72 - ThyInfo.finish ();
239.73 - Present.finish ();
239.74 - Future.shutdown ();
239.75 - session_finished := true);
239.76 -
239.77 -
239.78 -(* use_dir *)
239.79 -
239.80 -fun get_rpath rpath =
239.81 - (if rpath = "" then () else
239.82 - if is_some (! remote_path) then
239.83 - error "Path for remote theory browsing information may only be set once"
239.84 - else
239.85 - remote_path := SOME (Url.explode rpath);
239.86 - (! remote_path, rpath <> ""));
239.87 -
239.88 -fun dumping (_, "") = NONE
239.89 - | dumping (cp, path) = SOME (cp, Path.explode path);
239.90 -
239.91 -fun use_dir root build modes reset info doc doc_graph doc_versions
239.92 - parent name dump rpath level verbose max_threads trace_threads parallel_proofs =
239.93 - ((fn () =>
239.94 - (init reset parent name;
239.95 - Present.init build info doc doc_graph doc_versions (path ()) name
239.96 - (dumping dump) (get_rpath rpath) verbose (map ThyInfo.get_theory (ThyInfo.get_names ()));
239.97 - use root;
239.98 - finish ()))
239.99 - |> setmp_noncritical Proofterm.proofs level
239.100 - |> setmp_noncritical print_mode (modes @ print_mode_value ())
239.101 - |> setmp_noncritical Goal.parallel_proofs parallel_proofs
239.102 - |> setmp_noncritical Multithreading.trace trace_threads
239.103 - |> setmp_noncritical Multithreading.max_threads
239.104 - (if Multithreading.available then max_threads
239.105 - else (if max_threads = 1 then () else warning "Multithreading support unavailable"; 1))) ()
239.106 - handle exn => (Output.error_msg (Toplevel.exn_message exn); exit 1);
239.107 -
239.108 -end;
240.1 --- a/src/Pure/ML-Systems/alice.ML Wed Mar 04 11:05:02 2009 +0100
240.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
240.3 @@ -1,220 +0,0 @@
240.4 -(* Title: Pure/ML-Systems/alice.ML
240.5 -
240.6 -Compatibility file for Alice 1.4.
240.7 -
240.8 -NOTE: there is no wrapper script; may run it interactively as follows:
240.9 -
240.10 -$ cd Isabelle/src/Pure
240.11 -$ env ALICE_JIT_MODE=0 ISABELLE_HOME=$(cd ../..; pwd) alice
240.12 -- val ml_system = "alice";
240.13 -- use "ML-Systems/exn.ML";
240.14 -- use "ML-Systems/universal.ML";
240.15 -- use "ML-Systems/multithreading.ML";
240.16 -- use "ML-Systems/time_limit.ML";
240.17 -- use "ML-Systems/alice.ML";
240.18 -- use "ROOT.ML";
240.19 -- Session.finish ();
240.20 -*)
240.21 -
240.22 -val ml_system_fix_ints = false;
240.23 -
240.24 -fun forget_structure _ = ();
240.25 -
240.26 -fun exit 0 = (OS.Process.exit OS.Process.success): unit
240.27 - | exit _ = OS.Process.exit OS.Process.failure;
240.28 -
240.29 -
240.30 -(** ML system related **)
240.31 -
240.32 -(*low-level pointer equality*)
240.33 -fun pointer_eq (_: 'a, _: 'a) = false;
240.34 -
240.35 -
240.36 -(* integer compatibility -- downgraded IntInf *)
240.37 -
240.38 -structure Time =
240.39 -struct
240.40 - open Time;
240.41 - val fromMilliseconds = Time.fromMilliseconds o IntInf.fromInt;
240.42 - val fromSeconds = Time.fromSeconds o IntInf.fromInt;
240.43 -end;
240.44 -
240.45 -structure IntInf =
240.46 -struct
240.47 - fun divMod (x, y) = (x div y, x mod y);
240.48 - open Int;
240.49 -end;
240.50 -
240.51 -
240.52 -(* restore old-style character / string functions *)
240.53 -
240.54 -exception Ord;
240.55 -fun ord "" = raise Ord
240.56 - | ord s = Char.ord (String.sub (s, 0));
240.57 -
240.58 -val chr = String.str o chr;
240.59 -val explode = map String.str o String.explode;
240.60 -val implode = String.concat;
240.61 -
240.62 -
240.63 -(* Poly/ML emulation *)
240.64 -
240.65 -fun quit () = exit 0;
240.66 -
240.67 -fun get_print_depth () = ! Print.depth;
240.68 -fun print_depth n = Print.depth := n;
240.69 -
240.70 -
240.71 -(* compiler-independent timing functions *)
240.72 -
240.73 -structure Timer =
240.74 -struct
240.75 - open Timer;
240.76 - type cpu_timer = unit;
240.77 - fun startCPUTimer () = ();
240.78 - fun checkCPUTimer () = {sys = Time.zeroTime, usr = Time.zeroTime};
240.79 - fun checkGCTime () = Time.zeroTime;
240.80 -end;
240.81 -
240.82 -fun start_timing () =
240.83 - let val CPUtimer = Timer.startCPUTimer();
240.84 - val time = Timer.checkCPUTimer(CPUtimer)
240.85 - in (CPUtimer,time) end;
240.86 -
240.87 -fun end_timing (CPUtimer, {sys,usr}) =
240.88 - let open Time (*...for Time.toString, Time.+ and Time.- *)
240.89 - val {sys=sys2,usr=usr2} = Timer.checkCPUTimer(CPUtimer)
240.90 - in "User " ^ toString (usr2-usr) ^
240.91 - " All "^ toString (sys2-sys + usr2-usr) ^
240.92 - " secs"
240.93 - handle Time => ""
240.94 - end;
240.95 -
240.96 -fun check_timer timer =
240.97 - let
240.98 - val {sys, usr} = Timer.checkCPUTimer timer;
240.99 - val gc = Timer.checkGCTime timer; (* FIXME already included in usr? *)
240.100 - in (sys, usr, gc) end;
240.101 -
240.102 -
240.103 -(*prompts*)
240.104 -fun ml_prompts p1 p2 = ();
240.105 -
240.106 -(*dummy implementation*)
240.107 -fun profile (n: int) f x = f x;
240.108 -
240.109 -(*dummy implementation*)
240.110 -fun exception_trace f = f ();
240.111 -
240.112 -(*dummy implementation*)
240.113 -fun print x = x;
240.114 -
240.115 -
240.116 -(* toplevel pretty printing (see also Pure/pure_setup.ML) *)
240.117 -
240.118 -fun make_pp path pprint = (path, pprint);
240.119 -fun install_pp (path, pp) = ();
240.120 -
240.121 -
240.122 -(* ML command execution *)
240.123 -
240.124 -fun use_text _ _ _ _ _ txt = (Compiler.eval txt; ());
240.125 -fun use_file _ _ _ _ name = use name;
240.126 -
240.127 -
240.128 -
240.129 -(** interrupts **)
240.130 -
240.131 -exception Interrupt;
240.132 -
240.133 -fun interruptible f x = f x;
240.134 -fun uninterruptible f x = f (fn (g: 'c -> 'd) => g) x;
240.135 -
240.136 -
240.137 -(* basis library fixes *)
240.138 -
240.139 -structure TextIO =
240.140 -struct
240.141 - open TextIO;
240.142 - fun inputLine is = TextIO.inputLine is
240.143 - handle IO.Io _ => raise Interrupt;
240.144 -end;
240.145 -
240.146 -
240.147 -
240.148 -(** OS related **)
240.149 -
240.150 -structure OS =
240.151 -struct
240.152 - open OS;
240.153 - structure FileSys =
240.154 - struct
240.155 - open FileSys;
240.156 - fun tmpName () =
240.157 - let val name = FileSys.tmpName () in
240.158 - if String.isSuffix "\000" name
240.159 - then String.substring (name, 0, size name - 1)
240.160 - else name
240.161 - end;
240.162 - end;
240.163 -end;
240.164 -
240.165 -val cd = OS.FileSys.chDir;
240.166 -val pwd = OS.FileSys.getDir;
240.167 -
240.168 -local
240.169 -
240.170 -fun read_file name =
240.171 - let val is = TextIO.openIn name
240.172 - in Exn.release (Exn.capture TextIO.inputAll is before TextIO.closeIn is) end;
240.173 -
240.174 -fun write_file name txt =
240.175 - let val os = TextIO.openOut name
240.176 - in Exn.release (Exn.capture TextIO.output (os, txt) before TextIO.closeOut os) end;
240.177 -
240.178 -in
240.179 -
240.180 -fun system_out script =
240.181 - let
240.182 - val script_name = OS.FileSys.tmpName ();
240.183 - val _ = write_file script_name script;
240.184 -
240.185 - val output_name = OS.FileSys.tmpName ();
240.186 -
240.187 - val status =
240.188 - OS.Process.system ("perl -w \"$ISABELLE_HOME/lib/scripts/system.pl\" nogroup " ^
240.189 - script_name ^ " /dev/null " ^ output_name);
240.190 - val rc = if OS.Process.isSuccess status then 0 else 1;
240.191 -
240.192 - val output = read_file output_name handle IO.Io _ => "";
240.193 - val _ = OS.FileSys.remove script_name handle OS.SysErr _ => ();
240.194 - val _ = OS.FileSys.remove output_name handle OS.SysErr _ => ();
240.195 - in (output, rc) end;
240.196 -
240.197 -end;
240.198 -
240.199 -structure OS =
240.200 -struct
240.201 - open OS;
240.202 - structure FileSys =
240.203 - struct
240.204 - fun fileId name =
240.205 - (case system_out ("perl -e '@_ = stat(q:" ^ name ^ ":); print $_[1]'") of
240.206 - ("", _) => raise Fail "OS.FileSys.fileId" (* FIXME IO.Io!? *)
240.207 - | (s, _) => (case Int.fromString s of NONE => raise Fail "OS.FileSys.fileId" | SOME i => i));
240.208 - val compare = Int.compare;
240.209 - fun fullPath name =
240.210 - (case system_out ("FILE='" ^ name ^
240.211 - "' && cd \"$(dirname \"$FILE\")\" && echo -n \"$(pwd -P)/$(basename \"$FILE\")\"") of
240.212 - ("", _) => raise SysErr ("Bad file", NONE)
240.213 - | (s, _) => s);
240.214 - open FileSys;
240.215 - end;
240.216 -end;
240.217 -
240.218 -fun process_id () = raise Fail "process_id undefined";
240.219 -
240.220 -fun getenv var =
240.221 - (case OS.Process.getEnv var of
240.222 - NONE => ""
240.223 - | SOME txt => txt);
241.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
241.2 +++ b/src/Pure/System/isabelle_process.ML Wed Mar 04 11:05:29 2009 +0100
241.3 @@ -0,0 +1,138 @@
241.4 +(* Title: Pure/System/isabelle_process.ML
241.5 + Author: Makarius
241.6 +
241.7 +Isabelle process wrapper -- interaction via external program.
241.8 +
241.9 +General format of process output:
241.10 +
241.11 + (1) unmarked stdout/stderr, no line structure (output should be
241.12 + processed immediately as it arrives);
241.13 +
241.14 + (2) properly marked-up messages, e.g. for writeln channel
241.15 +
241.16 + "\002A" ^ props ^ "\002,\n" ^ text ^ "\002.\n"
241.17 +
241.18 + where the props consist of name=value lines terminated by "\002,\n"
241.19 + each, and the remaining text is any number of lines (output is
241.20 + supposed to be processed in one piece);
241.21 +
241.22 + (3) special init message holds "pid" and "session" property;
241.23 +
241.24 + (4) message content is encoded in YXML format.
241.25 +*)
241.26 +
241.27 +signature ISABELLE_PROCESS =
241.28 +sig
241.29 + val isabelle_processN: string
241.30 + val init: string -> unit
241.31 +end;
241.32 +
241.33 +structure IsabelleProcess: ISABELLE_PROCESS =
241.34 +struct
241.35 +
241.36 +(* print modes *)
241.37 +
241.38 +val isabelle_processN = "isabelle_process";
241.39 +
241.40 +val _ = Output.add_mode isabelle_processN Output.default_output Output.default_escape;
241.41 +val _ = Markup.add_mode isabelle_processN YXML.output_markup;
241.42 +
241.43 +
241.44 +(* message markup *)
241.45 +
241.46 +fun special ch = Symbol.STX ^ ch;
241.47 +val special_sep = special ",";
241.48 +val special_end = special ".";
241.49 +
241.50 +local
241.51 +
241.52 +fun clean_string bad str =
241.53 + if exists_string (member (op =) bad) str then
241.54 + translate_string (fn c => if member (op =) bad c then Symbol.DEL else c) str
241.55 + else str;
241.56 +
241.57 +fun message_props props =
241.58 + let val clean = clean_string [Symbol.STX, "\n", "\r"]
241.59 + in implode (map (fn (x, y) => clean x ^ "=" ^ clean y ^ special_sep ^ "\n") props) end;
241.60 +
241.61 +fun message_pos trees = trees |> get_first
241.62 + (fn XML.Elem (name, atts, ts) =>
241.63 + if name = Markup.positionN then SOME (Position.of_properties atts)
241.64 + else message_pos ts
241.65 + | _ => NONE);
241.66 +
241.67 +fun output out_stream s = NAMED_CRITICAL "IO" (fn () =>
241.68 + (TextIO.output (out_stream, s); TextIO.output (out_stream, "\n")));
241.69 +
241.70 +in
241.71 +
241.72 +fun message _ _ "" = ()
241.73 + | message out_stream ch body =
241.74 + let
241.75 + val pos = the_default Position.none (message_pos (YXML.parse_body body));
241.76 + val props =
241.77 + Position.properties_of (Position.thread_data ())
241.78 + |> Position.default_properties pos;
241.79 + val txt = clean_string [Symbol.STX] body;
241.80 + in output out_stream (special ch ^ message_props props ^ txt ^ special_end) end;
241.81 +
241.82 +fun init_message out_stream =
241.83 + let
241.84 + val pid = (Markup.pidN, process_id ());
241.85 + val session = (Markup.sessionN, List.last (Session.id ()) handle List.Empty => "unknown");
241.86 + val text = Session.welcome ();
241.87 + in output out_stream (special "A" ^ message_props [pid, session] ^ text ^ special_end) end;
241.88 +
241.89 +end;
241.90 +
241.91 +
241.92 +(* channels *)
241.93 +
241.94 +local
241.95 +
241.96 +fun auto_flush stream =
241.97 + let
241.98 + val _ = TextIO.StreamIO.setBufferMode (TextIO.getOutstream stream, IO.BLOCK_BUF);
241.99 + fun loop () =
241.100 + (OS.Process.sleep (Time.fromMilliseconds 50); try TextIO.flushOut stream; loop ());
241.101 + in loop end;
241.102 +
241.103 +in
241.104 +
241.105 +fun setup_channels out =
241.106 + let
241.107 + val out_stream =
241.108 + if out = "-" then TextIO.stdOut
241.109 + else
241.110 + let
241.111 + val path = File.platform_path (Path.explode out);
241.112 + val out_stream = TextIO.openOut path; (*fifo blocks until reader is ready*)
241.113 + val _ = OS.FileSys.remove path; (*prevent alien access, indicate writer is ready*)
241.114 + val _ = SimpleThread.fork false (auto_flush TextIO.stdOut);
241.115 + in out_stream end;
241.116 + val _ = SimpleThread.fork false (auto_flush out_stream);
241.117 + val _ = SimpleThread.fork false (auto_flush TextIO.stdErr);
241.118 + in
241.119 + Output.status_fn := message out_stream "B";
241.120 + Output.writeln_fn := message out_stream "C";
241.121 + Output.priority_fn := message out_stream "D";
241.122 + Output.tracing_fn := message out_stream "E";
241.123 + Output.warning_fn := message out_stream "F";
241.124 + Output.error_fn := message out_stream "G";
241.125 + Output.debug_fn := message out_stream "H";
241.126 + Output.prompt_fn := ignore;
241.127 + out_stream
241.128 + end;
241.129 +
241.130 +end;
241.131 +
241.132 +
241.133 +(* init *)
241.134 +
241.135 +fun init out =
241.136 + (change print_mode (update (op =) isabelle_processN);
241.137 + setup_channels out |> init_message;
241.138 + OuterKeyword.report ();
241.139 + Isar.toplevel_loop {init = true, welcome = false, sync = true, secure = true});
241.140 +
241.141 +end;
242.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
242.2 +++ b/src/Pure/System/isabelle_process.scala Wed Mar 04 11:05:29 2009 +0100
242.3 @@ -0,0 +1,435 @@
242.4 +/* Title: Pure/System/isabelle_process.ML
242.5 + Author: Makarius
242.6 + Options: :folding=explicit:collapseFolds=1:
242.7 +
242.8 +Isabelle process management -- always reactive due to multi-threaded I/O.
242.9 +*/
242.10 +
242.11 +package isabelle
242.12 +
242.13 +import java.util.concurrent.LinkedBlockingQueue
242.14 +import java.io.{BufferedReader, BufferedWriter, InputStreamReader, OutputStreamWriter,
242.15 + InputStream, OutputStream, IOException}
242.16 +
242.17 +
242.18 +object IsabelleProcess {
242.19 +
242.20 + /* results */
242.21 +
242.22 + object Kind extends Enumeration {
242.23 + //{{{ values and codes
242.24 + // internal system notification
242.25 + val SYSTEM = Value("SYSTEM")
242.26 + // Posix channels/events
242.27 + val STDIN = Value("STDIN")
242.28 + val STDOUT = Value("STDOUT")
242.29 + val SIGNAL = Value("SIGNAL")
242.30 + val EXIT = Value("EXIT")
242.31 + // Isabelle messages
242.32 + val INIT = Value("INIT")
242.33 + val STATUS = Value("STATUS")
242.34 + val WRITELN = Value("WRITELN")
242.35 + val PRIORITY = Value("PRIORITY")
242.36 + val TRACING = Value("TRACING")
242.37 + val WARNING = Value("WARNING")
242.38 + val ERROR = Value("ERROR")
242.39 + val DEBUG = Value("DEBUG")
242.40 + // messages codes
242.41 + val code = Map(
242.42 + ('A' : Int) -> Kind.INIT,
242.43 + ('B' : Int) -> Kind.STATUS,
242.44 + ('C' : Int) -> Kind.WRITELN,
242.45 + ('D' : Int) -> Kind.PRIORITY,
242.46 + ('E' : Int) -> Kind.TRACING,
242.47 + ('F' : Int) -> Kind.WARNING,
242.48 + ('G' : Int) -> Kind.ERROR,
242.49 + ('H' : Int) -> Kind.DEBUG,
242.50 + ('0' : Int) -> Kind.SYSTEM,
242.51 + ('1' : Int) -> Kind.STDIN,
242.52 + ('2' : Int) -> Kind.STDOUT,
242.53 + ('3' : Int) -> Kind.SIGNAL,
242.54 + ('4' : Int) -> Kind.EXIT)
242.55 + // message markup
242.56 + val markup = Map(
242.57 + Kind.INIT -> Markup.INIT,
242.58 + Kind.STATUS -> Markup.STATUS,
242.59 + Kind.WRITELN -> Markup.WRITELN,
242.60 + Kind.PRIORITY -> Markup.PRIORITY,
242.61 + Kind.TRACING -> Markup.TRACING,
242.62 + Kind.WARNING -> Markup.WARNING,
242.63 + Kind.ERROR -> Markup.ERROR,
242.64 + Kind.DEBUG -> Markup.DEBUG,
242.65 + Kind.SYSTEM -> Markup.SYSTEM,
242.66 + Kind.STDIN -> Markup.STDIN,
242.67 + Kind.STDOUT -> Markup.STDOUT,
242.68 + Kind.SIGNAL -> Markup.SIGNAL,
242.69 + Kind.EXIT -> Markup.EXIT)
242.70 + //}}}
242.71 + def is_raw(kind: Value) =
242.72 + kind == STDOUT
242.73 + def is_control(kind: Value) =
242.74 + kind == SYSTEM ||
242.75 + kind == SIGNAL ||
242.76 + kind == EXIT
242.77 + def is_system(kind: Value) =
242.78 + kind == SYSTEM ||
242.79 + kind == STDIN ||
242.80 + kind == SIGNAL ||
242.81 + kind == EXIT ||
242.82 + kind == STATUS
242.83 + }
242.84 +
242.85 + class Result(val kind: Kind.Value, val props: List[(String, String)], val result: String) {
242.86 + override def toString = {
242.87 + val trees = YXML.parse_body_failsafe(result)
242.88 + val res =
242.89 + if (kind == Kind.STATUS) trees.map(_.toString).mkString
242.90 + else trees.flatMap(XML.content(_).mkString).mkString
242.91 + if (props.isEmpty)
242.92 + kind.toString + " [[" + res + "]]"
242.93 + else
242.94 + kind.toString + " " +
242.95 + (for ((x, y) <- props) yield x + "=" + y).mkString("{", ",", "}") + " [[" + res + "]]"
242.96 + }
242.97 + def is_raw = Kind.is_raw(kind)
242.98 + def is_control = Kind.is_control(kind)
242.99 + def is_system = Kind.is_system(kind)
242.100 + }
242.101 +
242.102 + def parse_message(isabelle_system: IsabelleSystem, result: Result) =
242.103 + {
242.104 + XML.Elem(Markup.MESSAGE, (Markup.CLASS, Kind.markup(result.kind)) :: result.props,
242.105 + YXML.parse_body_failsafe(isabelle_system.symbols.decode(result.result)))
242.106 + }
242.107 +}
242.108 +
242.109 +
242.110 +class IsabelleProcess(isabelle_system: IsabelleSystem,
242.111 + results: EventBus[IsabelleProcess.Result], args: String*)
242.112 +{
242.113 + import IsabelleProcess._
242.114 +
242.115 +
242.116 + /* demo constructor */
242.117 +
242.118 + def this(args: String*) =
242.119 + this(new IsabelleSystem, new EventBus[IsabelleProcess.Result] + Console.println, args: _*)
242.120 +
242.121 +
242.122 + /* process information */
242.123 +
242.124 + @volatile private var proc: Process = null
242.125 + @volatile private var closing = false
242.126 + @volatile private var pid: String = null
242.127 + @volatile private var the_session: String = null
242.128 + def session = the_session
242.129 +
242.130 +
242.131 + /* results */
242.132 +
242.133 + def parse_message(result: Result): XML.Tree =
242.134 + IsabelleProcess.parse_message(isabelle_system, result)
242.135 +
242.136 + private val result_queue = new LinkedBlockingQueue[Result]
242.137 +
242.138 + private def put_result(kind: Kind.Value, props: List[(String, String)], result: String)
242.139 + {
242.140 + if (kind == Kind.INIT) {
242.141 + val map = Map(props: _*)
242.142 + if (map.isDefinedAt(Markup.PID)) pid = map(Markup.PID)
242.143 + if (map.isDefinedAt(Markup.SESSION)) the_session = map(Markup.SESSION)
242.144 + }
242.145 + result_queue.put(new Result(kind, props, result))
242.146 + }
242.147 +
242.148 + private class ResultThread extends Thread("isabelle: results") {
242.149 + override def run() = {
242.150 + var finished = false
242.151 + while (!finished) {
242.152 + val result =
242.153 + try { result_queue.take }
242.154 + catch { case _: NullPointerException => null }
242.155 +
242.156 + if (result != null) {
242.157 + results.event(result)
242.158 + if (result.kind == Kind.EXIT) finished = true
242.159 + }
242.160 + else finished = true
242.161 + }
242.162 + }
242.163 + }
242.164 +
242.165 +
242.166 + /* signals */
242.167 +
242.168 + def interrupt() = synchronized {
242.169 + if (proc == null) error("Cannot interrupt Isabelle: no process")
242.170 + if (pid == null) put_result(Kind.SYSTEM, Nil, "Cannot interrupt: unknown pid")
242.171 + else {
242.172 + try {
242.173 + if (isabelle_system.execute(true, "kill", "-INT", pid).waitFor == 0)
242.174 + put_result(Kind.SIGNAL, Nil, "INT")
242.175 + else
242.176 + put_result(Kind.SYSTEM, Nil, "Cannot interrupt: kill command failed")
242.177 + }
242.178 + catch { case e: IOException => error("Cannot interrupt Isabelle: " + e.getMessage) }
242.179 + }
242.180 + }
242.181 +
242.182 + def kill() = synchronized {
242.183 + if (proc == 0) error("Cannot kill Isabelle: no process")
242.184 + else {
242.185 + try_close()
242.186 + Thread.sleep(500)
242.187 + put_result(Kind.SIGNAL, Nil, "KILL")
242.188 + proc.destroy
242.189 + proc = null
242.190 + pid = null
242.191 + }
242.192 + }
242.193 +
242.194 +
242.195 + /* output being piped into the process */
242.196 +
242.197 + private val output = new LinkedBlockingQueue[String]
242.198 +
242.199 + private def output_raw(text: String) = synchronized {
242.200 + if (proc == null) error("Cannot output to Isabelle: no process")
242.201 + if (closing) error("Cannot output to Isabelle: already closing")
242.202 + output.put(text)
242.203 + }
242.204 +
242.205 + def output_sync(text: String) =
242.206 + output_raw(" \\<^sync>\n; " + text + " \\<^sync>;\n")
242.207 +
242.208 +
242.209 + def command(text: String) =
242.210 + output_sync("Isabelle.command " + IsabelleSyntax.encode_string(text))
242.211 +
242.212 + def command(props: List[(String, String)], text: String) =
242.213 + output_sync("Isabelle.command " + IsabelleSyntax.encode_properties(props) + " " +
242.214 + IsabelleSyntax.encode_string(text))
242.215 +
242.216 + def ML(text: String) =
242.217 + output_sync("ML_val " + IsabelleSyntax.encode_string(text))
242.218 +
242.219 + def close() = synchronized { // FIXME watchdog/timeout
242.220 + output_raw("\u0000")
242.221 + closing = true
242.222 + }
242.223 +
242.224 + def try_close() = synchronized {
242.225 + if (proc != null && !closing) {
242.226 + try { close() }
242.227 + catch { case _: RuntimeException => }
242.228 + }
242.229 + }
242.230 +
242.231 +
242.232 + /* stdin */
242.233 +
242.234 + private class StdinThread(out_stream: OutputStream) extends Thread("isabelle: stdin") {
242.235 + override def run() = {
242.236 + val writer = new BufferedWriter(new OutputStreamWriter(out_stream, isabelle_system.charset))
242.237 + var finished = false
242.238 + while (!finished) {
242.239 + try {
242.240 + //{{{
242.241 + val s = output.take
242.242 + if (s == "\u0000") {
242.243 + writer.close
242.244 + finished = true
242.245 + }
242.246 + else {
242.247 + put_result(Kind.STDIN, Nil, s)
242.248 + writer.write(s)
242.249 + writer.flush
242.250 + }
242.251 + //}}}
242.252 + }
242.253 + catch {
242.254 + case e: IOException => put_result(Kind.SYSTEM, Nil, "Stdin thread: " + e.getMessage)
242.255 + }
242.256 + }
242.257 + put_result(Kind.SYSTEM, Nil, "Stdin thread terminated")
242.258 + }
242.259 + }
242.260 +
242.261 +
242.262 + /* stdout */
242.263 +
242.264 + private class StdoutThread(in_stream: InputStream) extends Thread("isabelle: stdout") {
242.265 + override def run() = {
242.266 + val reader = new BufferedReader(new InputStreamReader(in_stream, isabelle_system.charset))
242.267 + var result = new StringBuilder(100)
242.268 +
242.269 + var finished = false
242.270 + while (!finished) {
242.271 + try {
242.272 + //{{{
242.273 + var c = -1
242.274 + var done = false
242.275 + while (!done && (result.length == 0 || reader.ready)) {
242.276 + c = reader.read
242.277 + if (c >= 0) result.append(c.asInstanceOf[Char])
242.278 + else done = true
242.279 + }
242.280 + if (result.length > 0) {
242.281 + put_result(Kind.STDOUT, Nil, result.toString)
242.282 + result.length = 0
242.283 + }
242.284 + else {
242.285 + reader.close
242.286 + finished = true
242.287 + try_close()
242.288 + }
242.289 + //}}}
242.290 + }
242.291 + catch {
242.292 + case e: IOException => put_result(Kind.SYSTEM, Nil, "Stdout thread: " + e.getMessage)
242.293 + }
242.294 + }
242.295 + put_result(Kind.SYSTEM, Nil, "Stdout thread terminated")
242.296 + }
242.297 + }
242.298 +
242.299 +
242.300 + /* messages */
242.301 +
242.302 + private class MessageThread(fifo: String) extends Thread("isabelle: messages") {
242.303 + override def run() = {
242.304 + val reader = isabelle_system.fifo_reader(fifo)
242.305 + var kind: Kind.Value = null
242.306 + var props: List[(String, String)] = Nil
242.307 + var result = new StringBuilder
242.308 +
242.309 + var finished = false
242.310 + while (!finished) {
242.311 + try {
242.312 + if (kind == null) {
242.313 + //{{{ Char mode -- resync
242.314 + var c = -1
242.315 + do {
242.316 + c = reader.read
242.317 + if (c >= 0 && c != 2) result.append(c.asInstanceOf[Char])
242.318 + } while (c >= 0 && c != 2)
242.319 +
242.320 + if (result.length > 0) {
242.321 + put_result(Kind.SYSTEM, Nil, "Malformed message:\n" + result.toString)
242.322 + result.length = 0
242.323 + }
242.324 + if (c < 0) {
242.325 + reader.close
242.326 + finished = true
242.327 + try_close()
242.328 + }
242.329 + else {
242.330 + c = reader.read
242.331 + if (Kind.code.isDefinedAt(c)) kind = Kind.code(c)
242.332 + else kind = null
242.333 + }
242.334 + //}}}
242.335 + }
242.336 + else {
242.337 + //{{{ Line mode
242.338 + val line = reader.readLine
242.339 + if (line == null) {
242.340 + reader.close
242.341 + finished = true
242.342 + try_close()
242.343 + }
242.344 + else {
242.345 + val len = line.length
242.346 + // property
242.347 + if (line.endsWith("\u0002,")) {
242.348 + val i = line.indexOf('=')
242.349 + if (i > 0) {
242.350 + val name = line.substring(0, i)
242.351 + val value = line.substring(i + 1, len - 2)
242.352 + props = (name, value) :: props
242.353 + }
242.354 + }
242.355 + // last text line
242.356 + else if (line.endsWith("\u0002.")) {
242.357 + result.append(line.substring(0, len - 2))
242.358 + put_result(kind, props.reverse, result.toString)
242.359 + kind = null
242.360 + props = Nil
242.361 + result.length = 0
242.362 + }
242.363 + // text line
242.364 + else {
242.365 + result.append(line)
242.366 + result.append('\n')
242.367 + }
242.368 + }
242.369 + //}}}
242.370 + }
242.371 + }
242.372 + catch {
242.373 + case e: IOException => put_result(Kind.SYSTEM, Nil, "Message thread: " + e.getMessage)
242.374 + }
242.375 + }
242.376 + put_result(Kind.SYSTEM, Nil, "Message thread terminated")
242.377 + }
242.378 + }
242.379 +
242.380 +
242.381 +
242.382 + /** main **/
242.383 +
242.384 + {
242.385 + /* isabelle version */
242.386 +
242.387 + {
242.388 + val (msg, rc) = isabelle_system.isabelle_tool("version")
242.389 + if (rc != 0) error("Version check failed -- bad Isabelle installation:\n" + msg)
242.390 + put_result(Kind.SYSTEM, Nil, msg)
242.391 + }
242.392 +
242.393 +
242.394 + /* messages */
242.395 +
242.396 + val message_fifo = isabelle_system.mk_fifo()
242.397 + def rm_fifo() = isabelle_system.rm_fifo(message_fifo)
242.398 +
242.399 + val message_thread = new MessageThread(message_fifo)
242.400 + message_thread.start
242.401 +
242.402 + new ResultThread().start
242.403 +
242.404 +
242.405 + /* exec process */
242.406 +
242.407 + try {
242.408 + val cmdline =
242.409 + List(isabelle_system.getenv_strict("ISABELLE_PROCESS"), "-W", message_fifo) ++ args
242.410 + proc = isabelle_system.execute(true, cmdline: _*)
242.411 + }
242.412 + catch {
242.413 + case e: IOException =>
242.414 + rm_fifo()
242.415 + error("Failed to execute Isabelle process: " + e.getMessage)
242.416 + }
242.417 +
242.418 +
242.419 + /* stdin/stdout */
242.420 +
242.421 + new StdinThread(proc.getOutputStream).start
242.422 + new StdoutThread(proc.getInputStream).start
242.423 +
242.424 +
242.425 + /* exit */
242.426 +
242.427 + new Thread("isabelle: exit") {
242.428 + override def run() = {
242.429 + val rc = proc.waitFor()
242.430 + Thread.sleep(300)
242.431 + put_result(Kind.SYSTEM, Nil, "Exit thread terminated")
242.432 + put_result(Kind.EXIT, Nil, Integer.toString(rc))
242.433 + rm_fifo()
242.434 + }
242.435 + }.start
242.436 +
242.437 + }
242.438 +}
243.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
243.2 +++ b/src/Pure/System/isabelle_system.scala Wed Mar 04 11:05:29 2009 +0100
243.3 @@ -0,0 +1,158 @@
243.4 +/* Title: Pure/System/isabelle_system.scala
243.5 + Author: Makarius
243.6 +
243.7 +Isabelle system support -- basic Cygwin/Posix compatibility.
243.8 +*/
243.9 +
243.10 +package isabelle
243.11 +
243.12 +import java.util.regex.{Pattern, Matcher}
243.13 +import java.io.{BufferedReader, InputStreamReader, FileInputStream, File, IOException}
243.14 +
243.15 +import scala.io.Source
243.16 +
243.17 +
243.18 +class IsabelleSystem {
243.19 +
243.20 + val charset = "UTF-8"
243.21 +
243.22 +
243.23 + /* Isabelle environment settings */
243.24 +
243.25 + private val environment = System.getenv
243.26 +
243.27 + def getenv(name: String) = {
243.28 + val value = environment.get(if (name == "HOME") "HOME_JVM" else name)
243.29 + if (value != null) value else ""
243.30 + }
243.31 +
243.32 + def getenv_strict(name: String) = {
243.33 + val value = environment.get(name)
243.34 + if (value != "") value else error("Undefined environment variable: " + name)
243.35 + }
243.36 +
243.37 + val is_cygwin = Pattern.matches(".*-cygwin", getenv_strict("ML_PLATFORM"))
243.38 +
243.39 +
243.40 + /* file path specifications */
243.41 +
243.42 + private val cygdrive_pattern = Pattern.compile("/cygdrive/([a-zA-Z])($|/.*)")
243.43 +
243.44 + def platform_path(source_path: String) = {
243.45 + val result_path = new StringBuilder
243.46 +
243.47 + def init(path: String) = {
243.48 + val cygdrive = cygdrive_pattern.matcher(path)
243.49 + if (cygdrive.matches) {
243.50 + result_path.length = 0
243.51 + result_path.append(cygdrive.group(1))
243.52 + result_path.append(":")
243.53 + result_path.append(File.separator)
243.54 + cygdrive.group(2)
243.55 + }
243.56 + else if (path.startsWith("/")) {
243.57 + result_path.length = 0
243.58 + result_path.append(getenv_strict("ISABELLE_ROOT_JVM"))
243.59 + path.substring(1)
243.60 + }
243.61 + else path
243.62 + }
243.63 + def append(path: String) = {
243.64 + for (p <- init(path).split("/")) {
243.65 + if (p != "") {
243.66 + val len = result_path.length
243.67 + if (len > 0 && result_path(len - 1) != File.separatorChar)
243.68 + result_path.append(File.separator)
243.69 + result_path.append(p)
243.70 + }
243.71 + }
243.72 + }
243.73 + for (p <- init(source_path).split("/")) {
243.74 + if (p.startsWith("$")) append(getenv_strict(p.substring(1)))
243.75 + else if (p == "~") append(getenv_strict("HOME"))
243.76 + else if (p == "~~") append(getenv_strict("ISABELLE_HOME"))
243.77 + else append(p)
243.78 + }
243.79 + result_path.toString
243.80 + }
243.81 +
243.82 + def platform_file(path: String) =
243.83 + new File(platform_path(path))
243.84 +
243.85 +
243.86 + /* processes */
243.87 +
243.88 + def execute(redirect: Boolean, args: String*): Process = {
243.89 + val cmdline = new java.util.LinkedList[String]
243.90 + if (is_cygwin) cmdline.add(platform_path("/bin/env"))
243.91 + for (s <- args) cmdline.add(s)
243.92 +
243.93 + val proc = new ProcessBuilder(cmdline)
243.94 + proc.environment.clear
243.95 + proc.environment.putAll(environment)
243.96 + proc.redirectErrorStream(redirect)
243.97 + proc.start
243.98 + }
243.99 +
243.100 +
243.101 + /* Isabelle tools (non-interactive) */
243.102 +
243.103 + def isabelle_tool(args: String*) = {
243.104 + val proc =
243.105 + try { execute(true, (List(getenv_strict("ISABELLE_TOOL")) ++ args): _*) }
243.106 + catch { case e: IOException => error(e.getMessage) }
243.107 + proc.getOutputStream.close
243.108 + val output = Source.fromInputStream(proc.getInputStream, charset).mkString
243.109 + val rc = proc.waitFor
243.110 + (output, rc)
243.111 + }
243.112 +
243.113 +
243.114 + /* named pipes */
243.115 +
243.116 + def mk_fifo() = {
243.117 + val (result, rc) = isabelle_tool("mkfifo")
243.118 + if (rc == 0) result.trim
243.119 + else error(result)
243.120 + }
243.121 +
243.122 + def rm_fifo(fifo: String) = {
243.123 + val (result, rc) = isabelle_tool("rmfifo", fifo)
243.124 + if (rc != 0) error(result)
243.125 + }
243.126 +
243.127 + def fifo_reader(fifo: String) = {
243.128 + // blocks until writer is ready
243.129 + val stream =
243.130 + if (is_cygwin) execute(false, "cat", fifo).getInputStream
243.131 + else new FileInputStream(fifo)
243.132 + new BufferedReader(new InputStreamReader(stream, charset))
243.133 + }
243.134 +
243.135 +
243.136 + /* find logics */
243.137 +
243.138 + def find_logics() = {
243.139 + val ml_ident = getenv_strict("ML_IDENTIFIER")
243.140 + var logics: Set[String] = Set()
243.141 + for (dir <- getenv_strict("ISABELLE_PATH").split(":")) {
243.142 + val files = platform_file(dir + "/" + ml_ident).listFiles()
243.143 + if (files != null) {
243.144 + for (file <- files if file.isFile) logics += file.getName
243.145 + }
243.146 + }
243.147 + logics.toList.sort(_ < _)
243.148 + }
243.149 +
243.150 +
243.151 + /* symbols */
243.152 +
243.153 + private def read_symbols(path: String) = {
243.154 + val file = new File(platform_path(path))
243.155 + if (file.canRead) Source.fromFile(file).getLines
243.156 + else Iterator.empty
243.157 + }
243.158 + val symbols = new Symbol.Interpretation(
243.159 + read_symbols("$ISABELLE_HOME/etc/symbols") ++
243.160 + read_symbols("$ISABELLE_HOME_USER/etc/symbols"))
243.161 +}
244.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
244.2 +++ b/src/Pure/System/isar.ML Wed Mar 04 11:05:29 2009 +0100
244.3 @@ -0,0 +1,415 @@
244.4 +(* Title: Pure/System/isar.ML
244.5 + Author: Makarius
244.6 +
244.7 +The global Isabelle/Isar state and main read-eval-print loop.
244.8 +*)
244.9 +
244.10 +signature ISAR =
244.11 +sig
244.12 + val init: unit -> unit
244.13 + val exn: unit -> (exn * string) option
244.14 + val state: unit -> Toplevel.state
244.15 + val context: unit -> Proof.context
244.16 + val goal: unit -> thm
244.17 + val print: unit -> unit
244.18 + val >> : Toplevel.transition -> bool
244.19 + val >>> : Toplevel.transition list -> unit
244.20 + val linear_undo: int -> unit
244.21 + val undo: int -> unit
244.22 + val kill: unit -> unit
244.23 + val kill_proof: unit -> unit
244.24 + val crashes: exn list ref
244.25 + val toplevel_loop: {init: bool, welcome: bool, sync: bool, secure: bool} -> unit
244.26 + val loop: unit -> unit
244.27 + val main: unit -> unit
244.28 +
244.29 + type id = string
244.30 + val no_id: id
244.31 + val create_command: Toplevel.transition -> id
244.32 + val insert_command: id -> id -> unit
244.33 + val remove_command: id -> unit
244.34 +end;
244.35 +
244.36 +structure Isar: ISAR =
244.37 +struct
244.38 +
244.39 +
244.40 +(** TTY model -- SINGLE-THREADED! **)
244.41 +
244.42 +(* the global state *)
244.43 +
244.44 +type history = (Toplevel.state * Toplevel.transition) list;
244.45 + (*previous state, state transition -- regular commands only*)
244.46 +
244.47 +local
244.48 + val global_history = ref ([]: history);
244.49 + val global_state = ref Toplevel.toplevel;
244.50 + val global_exn = ref (NONE: (exn * string) option);
244.51 +in
244.52 +
244.53 +fun edit_history count f = NAMED_CRITICAL "Isar" (fn () =>
244.54 + let
244.55 + fun edit 0 (st, hist) = (global_history := hist; global_state := st; global_exn := NONE)
244.56 + | edit n (st, hist) = edit (n - 1) (f st hist);
244.57 + in edit count (! global_state, ! global_history) end);
244.58 +
244.59 +fun state () = NAMED_CRITICAL "Isar" (fn () => ! global_state);
244.60 +fun set_state state = NAMED_CRITICAL "Isar" (fn () => global_state := state);
244.61 +
244.62 +fun exn () = NAMED_CRITICAL "Isar" (fn () => ! global_exn);
244.63 +fun set_exn exn = NAMED_CRITICAL "Isar" (fn () => global_exn := exn);
244.64 +
244.65 +end;
244.66 +
244.67 +
244.68 +fun init () = edit_history 1 (K (K (Toplevel.toplevel, [])));
244.69 +
244.70 +fun context () = Toplevel.context_of (state ())
244.71 + handle Toplevel.UNDEF => error "Unknown context";
244.72 +
244.73 +fun goal () = #2 (#2 (Proof.get_goal (Toplevel.proof_of (state ()))))
244.74 + handle Toplevel.UNDEF => error "No goal present";
244.75 +
244.76 +fun print () = Toplevel.print_state false (state ());
244.77 +
244.78 +
244.79 +(* history navigation *)
244.80 +
244.81 +local
244.82 +
244.83 +fun find_and_undo _ [] = error "Undo history exhausted"
244.84 + | find_and_undo which ((prev, tr) :: hist) =
244.85 + ((case Toplevel.init_of tr of SOME name => ThyInfo.kill_thy name | NONE => ());
244.86 + if which (Toplevel.name_of tr) then (prev, hist) else find_and_undo which hist);
244.87 +
244.88 +in
244.89 +
244.90 +fun linear_undo n = edit_history n (K (find_and_undo (K true)));
244.91 +
244.92 +fun undo n = edit_history n (fn st => fn hist =>
244.93 + find_and_undo (if Toplevel.is_proof st then K true else OuterKeyword.is_theory) hist);
244.94 +
244.95 +fun kill () = edit_history 1 (fn st => fn hist =>
244.96 + find_and_undo
244.97 + (if Toplevel.is_proof st then OuterKeyword.is_theory else OuterKeyword.is_theory_begin) hist);
244.98 +
244.99 +fun kill_proof () = edit_history 1 (fn st => fn hist =>
244.100 + if Toplevel.is_proof st then find_and_undo OuterKeyword.is_theory hist
244.101 + else raise Toplevel.UNDEF);
244.102 +
244.103 +end;
244.104 +
244.105 +
244.106 +(* interactive state transformations *)
244.107 +
244.108 +fun op >> tr =
244.109 + (case Toplevel.transition true tr (state ()) of
244.110 + NONE => false
244.111 + | SOME (_, SOME err) => (set_exn (SOME err); Toplevel.error_msg tr err; true)
244.112 + | SOME (st', NONE) =>
244.113 + let
244.114 + val name = Toplevel.name_of tr;
244.115 + val _ = if OuterKeyword.is_theory_begin name then init () else ();
244.116 + val _ =
244.117 + if OuterKeyword.is_regular name
244.118 + then edit_history 1 (fn st => fn hist => (st', (st, tr) :: hist)) else ();
244.119 + in true end);
244.120 +
244.121 +fun op >>> [] = ()
244.122 + | op >>> (tr :: trs) = if op >> tr then op >>> trs else ();
244.123 +
244.124 +
244.125 +(* toplevel loop *)
244.126 +
244.127 +val crashes = ref ([]: exn list);
244.128 +
244.129 +local
244.130 +
244.131 +fun raw_loop secure src =
244.132 + let
244.133 + fun check_secure () =
244.134 + (if secure then warning "Secure loop -- cannot exit to ML" else (); secure);
244.135 + in
244.136 + (case Source.get_single (Source.set_prompt Source.default_prompt src) of
244.137 + NONE => if secure then quit () else ()
244.138 + | SOME (tr, src') => if op >> tr orelse check_secure () then raw_loop secure src' else ())
244.139 + handle exn =>
244.140 + (Output.error_msg (Toplevel.exn_message exn)
244.141 + handle crash =>
244.142 + (CRITICAL (fn () => change crashes (cons crash));
244.143 + warning "Recovering from Isar toplevel crash -- see also Isar.crashes");
244.144 + raw_loop secure src)
244.145 + end;
244.146 +
244.147 +in
244.148 +
244.149 +fun toplevel_loop {init = do_init, welcome, sync, secure} =
244.150 + (Context.set_thread_data NONE;
244.151 + if do_init then init () else (); (* FIXME init editor model *)
244.152 + if welcome then writeln (Session.welcome ()) else ();
244.153 + uninterruptible (fn _ => fn () => raw_loop secure (OuterSyntax.isar sync)) ());
244.154 +
244.155 +end;
244.156 +
244.157 +fun loop () =
244.158 + toplevel_loop {init = false, welcome = false, sync = false, secure = Secure.is_secure ()};
244.159 +
244.160 +fun main () =
244.161 + toplevel_loop {init = true, welcome = true, sync = false, secure = Secure.is_secure ()};
244.162 +
244.163 +
244.164 +
244.165 +(** individual toplevel commands **)
244.166 +
244.167 +(* unique identification *)
244.168 +
244.169 +type id = string;
244.170 +val no_id : id = "";
244.171 +
244.172 +
244.173 +(* command category *)
244.174 +
244.175 +datatype category = Empty | Theory | Proof | Diag | Control;
244.176 +
244.177 +fun category_of tr =
244.178 + let val name = Toplevel.name_of tr in
244.179 + if name = "" then Empty
244.180 + else if OuterKeyword.is_theory name then Theory
244.181 + else if OuterKeyword.is_proof name then Proof
244.182 + else if OuterKeyword.is_diag name then Diag
244.183 + else Control
244.184 + end;
244.185 +
244.186 +val is_theory = fn Theory => true | _ => false;
244.187 +val is_proper = fn Theory => true | Proof => true | _ => false;
244.188 +val is_regular = fn Control => false | _ => true;
244.189 +
244.190 +
244.191 +(* command status *)
244.192 +
244.193 +datatype status =
244.194 + Unprocessed |
244.195 + Running |
244.196 + Failed of exn * string |
244.197 + Finished of Toplevel.state;
244.198 +
244.199 +fun status_markup Unprocessed = Markup.unprocessed
244.200 + | status_markup Running = (Markup.runningN, [])
244.201 + | status_markup (Failed _) = Markup.failed
244.202 + | status_markup (Finished _) = Markup.finished;
244.203 +
244.204 +fun run int tr state =
244.205 + (case Toplevel.transition int tr state of
244.206 + NONE => NONE
244.207 + | SOME (_, SOME err) => (Toplevel.error_msg tr err; SOME (Failed err))
244.208 + | SOME (state', NONE) => SOME (Finished state'));
244.209 +
244.210 +
244.211 +(* datatype command *)
244.212 +
244.213 +datatype command = Command of
244.214 + {category: category,
244.215 + transition: Toplevel.transition,
244.216 + status: status};
244.217 +
244.218 +fun make_command (category, transition, status) =
244.219 + Command {category = category, transition = transition, status = status};
244.220 +
244.221 +val empty_command =
244.222 + make_command (Empty, Toplevel.empty, Finished Toplevel.toplevel);
244.223 +
244.224 +fun map_command f (Command {category, transition, status}) =
244.225 + make_command (f (category, transition, status));
244.226 +
244.227 +fun map_status f = map_command (fn (category, transition, status) =>
244.228 + (category, transition, f status));
244.229 +
244.230 +
244.231 +(* global collection of identified commands *)
244.232 +
244.233 +fun err_dup id = sys_error ("Duplicate command " ^ quote id);
244.234 +fun err_undef id = sys_error ("Unknown command " ^ quote id);
244.235 +
244.236 +local val global_commands = ref (Graph.empty: command Graph.T) in
244.237 +
244.238 +fun change_commands f = NAMED_CRITICAL "Isar" (fn () => change global_commands f)
244.239 + handle Graph.DUP bad => err_dup bad | Graph.UNDEF bad => err_undef bad;
244.240 +
244.241 +fun get_commands () = NAMED_CRITICAL "Isar" (fn () => ! global_commands);
244.242 +
244.243 +end;
244.244 +
244.245 +fun add_edge (id1, id2) =
244.246 + if id1 = no_id orelse id2 = no_id then I else Graph.add_edge (id1, id2);
244.247 +
244.248 +
244.249 +fun init_commands () = change_commands (K Graph.empty);
244.250 +
244.251 +fun the_command id =
244.252 + let val Command cmd =
244.253 + if id = no_id then empty_command
244.254 + else (Graph.get_node (get_commands ()) id handle Graph.UNDEF bad => err_undef bad)
244.255 + in cmd end;
244.256 +
244.257 +fun prev_command id =
244.258 + if id = no_id then no_id
244.259 + else
244.260 + (case Graph.imm_preds (get_commands ()) id handle Graph.UNDEF bad => err_undef bad of
244.261 + [] => no_id
244.262 + | [prev] => prev
244.263 + | _ => sys_error ("Non-linear command dependency " ^ quote id));
244.264 +
244.265 +fun next_commands id =
244.266 + if id = no_id then []
244.267 + else Graph.imm_succs (get_commands ()) id handle Graph.UNDEF bad => err_undef bad;
244.268 +
244.269 +fun descendant_commands ids =
244.270 + Graph.all_succs (get_commands ()) (distinct (op =) (filter_out (fn id => id = no_id) ids))
244.271 + handle Graph.UNDEF bad => err_undef bad;
244.272 +
244.273 +
244.274 +(* maintain status *)
244.275 +
244.276 +fun report_status markup id = Toplevel.status (#transition (the_command id)) markup;
244.277 +
244.278 +fun update_status status id = change_commands (Graph.map_node id (map_status (K status)));
244.279 +
244.280 +fun report_update_status status id =
244.281 + change_commands (Graph.map_node id (map_status (fn old_status =>
244.282 + let val markup = status_markup status
244.283 + in if markup <> status_markup old_status then report_status markup id else (); status end)));
244.284 +
244.285 +
244.286 +(* create and dispose commands *)
244.287 +
244.288 +fun create_command raw_tr =
244.289 + let
244.290 + val (id, tr) =
244.291 + (case Toplevel.get_id raw_tr of
244.292 + SOME id => (id, raw_tr)
244.293 + | NONE =>
244.294 + let val id =
244.295 + if ! Toplevel.debug then "isabelle:" ^ Toplevel.name_of raw_tr ^ serial_string ()
244.296 + else "isabelle:" ^ serial_string ()
244.297 + in (id, Toplevel.put_id id raw_tr) end);
244.298 +
244.299 + val cmd = make_command (category_of tr, tr, Unprocessed);
244.300 + val _ = change_commands (Graph.new_node (id, cmd));
244.301 + in id end;
244.302 +
244.303 +fun dispose_commands ids =
244.304 + let
244.305 + val desc = descendant_commands ids;
244.306 + val _ = List.app (report_status Markup.disposed) desc;
244.307 + val _ = change_commands (Graph.del_nodes desc);
244.308 + in () end;
244.309 +
244.310 +
244.311 +(* final state *)
244.312 +
244.313 +fun the_state id =
244.314 + (case the_command id of
244.315 + {status = Finished state, ...} => state
244.316 + | {transition, ...} => error ("Unfinished command " ^ Toplevel.str_of transition));
244.317 +
244.318 +
244.319 +
244.320 +(** editor model **)
244.321 +
244.322 +(* run commands *)
244.323 +
244.324 +fun try_run id =
244.325 + (case try the_state (prev_command id) of
244.326 + NONE => ()
244.327 + | SOME state =>
244.328 + (case run true (#transition (the_command id)) state of
244.329 + NONE => ()
244.330 + | SOME status => report_update_status status id));
244.331 +
244.332 +fun rerun_commands ids =
244.333 + (List.app (report_update_status Unprocessed) ids; List.app try_run ids);
244.334 +
244.335 +
244.336 +(* modify document *)
244.337 +
244.338 +fun insert_command prev id = NAMED_CRITICAL "Isar" (fn () =>
244.339 + let
244.340 + val nexts = next_commands prev;
244.341 + val _ = change_commands
244.342 + (fold (fn next => Graph.del_edge (prev, next)) nexts #> add_edge (prev, id) #>
244.343 + fold (fn next => Graph.add_edge (id, next)) nexts);
244.344 + in descendant_commands [id] end) |> rerun_commands;
244.345 +
244.346 +fun remove_command id = NAMED_CRITICAL "Isar" (fn () =>
244.347 + let
244.348 + val prev = prev_command id;
244.349 + val nexts = next_commands id;
244.350 + val _ = change_commands
244.351 + (fold (fn next => Graph.del_edge (id, next)) nexts #>
244.352 + fold (fn next => add_edge (prev, next)) nexts);
244.353 + in descendant_commands nexts end) |> rerun_commands;
244.354 +
244.355 +
244.356 +
244.357 +(** command syntax **)
244.358 +
244.359 +local
244.360 +
244.361 +structure P = OuterParse and K = OuterKeyword;
244.362 +val op >> = Scan.>>;
244.363 +
244.364 +in
244.365 +
244.366 +(* global history *)
244.367 +
244.368 +val _ =
244.369 + OuterSyntax.improper_command "init_toplevel" "init toplevel point-of-interest" K.control
244.370 + (Scan.succeed (Toplevel.no_timing o Toplevel.imperative init));
244.371 +
244.372 +val _ =
244.373 + OuterSyntax.improper_command "linear_undo" "undo commands" K.control
244.374 + (Scan.optional P.nat 1 >>
244.375 + (fn n => Toplevel.no_timing o Toplevel.imperative (fn () => linear_undo n)));
244.376 +
244.377 +val _ =
244.378 + OuterSyntax.improper_command "undo" "undo commands (skipping closed proofs)" K.control
244.379 + (Scan.optional P.nat 1 >>
244.380 + (fn n => Toplevel.no_timing o Toplevel.imperative (fn () => undo n)));
244.381 +
244.382 +val _ =
244.383 + OuterSyntax.improper_command "undos_proof" "undo commands (skipping closed proofs)" K.control
244.384 + (Scan.optional P.nat 1 >> (fn n => Toplevel.no_timing o
244.385 + Toplevel.keep (fn state =>
244.386 + if Toplevel.is_proof state then (undo n; print ()) else raise Toplevel.UNDEF)));
244.387 +
244.388 +val _ =
244.389 + OuterSyntax.improper_command "cannot_undo" "partial undo -- Proof General legacy" K.control
244.390 + (P.name >>
244.391 + (fn "end" => Toplevel.no_timing o Toplevel.imperative (fn () => undo 1)
244.392 + | txt => Toplevel.imperative (fn () => error ("Cannot undo " ^ quote txt))));
244.393 +
244.394 +val _ =
244.395 + OuterSyntax.improper_command "kill" "kill partial proof or theory development" K.control
244.396 + (Scan.succeed (Toplevel.no_timing o Toplevel.imperative kill));
244.397 +
244.398 +
244.399 +(* editor model *)
244.400 +
244.401 +val _ =
244.402 + OuterSyntax.internal_command "Isar.command"
244.403 + (P.string -- P.string >> (fn (id, text) =>
244.404 + Toplevel.imperative (fn () =>
244.405 + ignore (create_command (OuterSyntax.prepare_command (Position.id id) text)))));
244.406 +
244.407 +val _ =
244.408 + OuterSyntax.internal_command "Isar.insert"
244.409 + (P.string -- P.string >> (fn (prev, id) =>
244.410 + Toplevel.imperative (fn () => insert_command prev id)));
244.411 +
244.412 +val _ =
244.413 + OuterSyntax.internal_command "Isar.remove"
244.414 + (P.string >> (fn id => Toplevel.imperative (fn () => remove_command id)));
244.415 +
244.416 +end;
244.417 +
244.418 +end;
245.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
245.2 +++ b/src/Pure/System/session.ML Wed Mar 04 11:05:29 2009 +0100
245.3 @@ -0,0 +1,112 @@
245.4 +(* Title: Pure/System/session.ML
245.5 + Author: Markus Wenzel, TU Muenchen
245.6 +
245.7 +Session management -- maintain state of logic images.
245.8 +*)
245.9 +
245.10 +signature SESSION =
245.11 +sig
245.12 + val id: unit -> string list
245.13 + val name: unit -> string
245.14 + val welcome: unit -> string
245.15 + val use_dir: string -> bool -> string list -> bool -> bool -> string -> bool -> string list ->
245.16 + string -> string -> bool * string -> string -> int -> bool -> int -> int -> bool -> unit
245.17 + val finish: unit -> unit
245.18 +end;
245.19 +
245.20 +structure Session: SESSION =
245.21 +struct
245.22 +
245.23 +
245.24 +(* session state *)
245.25 +
245.26 +val session = ref ([Context.PureN]: string list);
245.27 +val session_path = ref ([]: string list);
245.28 +val session_finished = ref false;
245.29 +val remote_path = ref (NONE: Url.T option);
245.30 +
245.31 +
245.32 +(* access path *)
245.33 +
245.34 +fun id () = ! session;
245.35 +fun path () = ! session_path;
245.36 +
245.37 +fun str_of [] = Context.PureN
245.38 + | str_of elems = space_implode "/" elems;
245.39 +
245.40 +fun name () = "Isabelle/" ^ str_of (path ());
245.41 +
245.42 +
245.43 +(* welcome *)
245.44 +
245.45 +fun welcome () =
245.46 + if Distribution.is_official then
245.47 + "Welcome to " ^ name () ^ " (" ^ Distribution.version ^ ")"
245.48 + else
245.49 + "Unofficial version of " ^ name () ^ " (" ^ Distribution.version ^ ")" ^
245.50 + (if Distribution.changelog <> "" then "\nSee also " ^ Distribution.changelog else "");
245.51 +
245.52 +val _ =
245.53 + OuterSyntax.improper_command "welcome" "print welcome message" OuterKeyword.diag
245.54 + (Scan.succeed (Toplevel.no_timing o Toplevel.imperative (writeln o welcome)));
245.55 +
245.56 +
245.57 +(* add_path *)
245.58 +
245.59 +fun add_path reset s =
245.60 + let val sess = ! session @ [s] in
245.61 + (case duplicates (op =) sess of
245.62 + [] => (session := sess; session_path := ((if reset then [] else ! session_path) @ [s]))
245.63 + | dups => error ("Duplicate session identifiers " ^ commas_quote dups ^ " in " ^ str_of sess))
245.64 + end;
245.65 +
245.66 +
245.67 +(* init *)
245.68 +
245.69 +fun init reset parent name =
245.70 + if not (member (op =) (! session) parent) orelse not (! session_finished) then
245.71 + error ("Unfinished parent session " ^ quote parent ^ " for " ^ quote name)
245.72 + else (add_path reset name; session_finished := false);
245.73 +
245.74 +
245.75 +(* finish *)
245.76 +
245.77 +fun finish () =
245.78 + (Output.accumulated_time ();
245.79 + ThyInfo.finish ();
245.80 + Present.finish ();
245.81 + Future.shutdown ();
245.82 + session_finished := true);
245.83 +
245.84 +
245.85 +(* use_dir *)
245.86 +
245.87 +fun get_rpath rpath =
245.88 + (if rpath = "" then () else
245.89 + if is_some (! remote_path) then
245.90 + error "Path for remote theory browsing information may only be set once"
245.91 + else
245.92 + remote_path := SOME (Url.explode rpath);
245.93 + (! remote_path, rpath <> ""));
245.94 +
245.95 +fun dumping (_, "") = NONE
245.96 + | dumping (cp, path) = SOME (cp, Path.explode path);
245.97 +
245.98 +fun use_dir root build modes reset info doc doc_graph doc_versions
245.99 + parent name dump rpath level verbose max_threads trace_threads parallel_proofs =
245.100 + ((fn () =>
245.101 + (init reset parent name;
245.102 + Present.init build info doc doc_graph doc_versions (path ()) name
245.103 + (dumping dump) (get_rpath rpath) verbose (map ThyInfo.get_theory (ThyInfo.get_names ()));
245.104 + use root;
245.105 + finish ()))
245.106 + |> setmp_noncritical Proofterm.proofs level
245.107 + |> setmp_noncritical print_mode (modes @ print_mode_value ())
245.108 + |> setmp_noncritical Goal.parallel_proofs parallel_proofs
245.109 + |> setmp_noncritical Multithreading.trace trace_threads
245.110 + |> setmp_noncritical Multithreading.max_threads
245.111 + (if Multithreading.available then max_threads
245.112 + else (if max_threads = 1 then () else warning "Multithreading support unavailable"; 1))) ()
245.113 + handle exn => (Output.error_msg (Toplevel.exn_message exn); exit 1);
245.114 +
245.115 +end;
246.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
246.2 +++ b/src/Pure/Tools/find_consts.ML Wed Mar 04 11:05:29 2009 +0100
246.3 @@ -0,0 +1,169 @@
246.4 +(* Title: Pure/Tools/find_consts.ML
246.5 + Author: Timothy Bourke and Gerwin Klein, NICTA
246.6 +
246.7 +Hoogle-like (http://www-users.cs.york.ac.uk/~ndm/hoogle) searching by
246.8 +type over constants, but matching is not fuzzy.
246.9 +*)
246.10 +
246.11 +signature FIND_CONSTS =
246.12 +sig
246.13 + datatype criterion =
246.14 + Strict of string
246.15 + | Loose of string
246.16 + | Name of string
246.17 +
246.18 + val find_consts : Proof.context -> (bool * criterion) list -> unit
246.19 +end;
246.20 +
246.21 +structure FindConsts : FIND_CONSTS =
246.22 +struct
246.23 +
246.24 +(* search criteria *)
246.25 +
246.26 +datatype criterion =
246.27 + Strict of string
246.28 + | Loose of string
246.29 + | Name of string;
246.30 +
246.31 +(* matching types/consts *)
246.32 +
246.33 +fun add_tye (_, (_, t)) n = Term.size_of_typ t + n;
246.34 +
246.35 +fun matches_subtype thy typat =
246.36 + let
246.37 + val p = can (fn ty => Sign.typ_match thy (typat, ty) Vartab.empty);
246.38 +
246.39 + fun fs [] = false
246.40 + | fs (t :: ts) = f t orelse fs ts
246.41 +
246.42 + and f (t as Type (_, ars)) = p t orelse fs ars
246.43 + | f t = p t;
246.44 + in f end;
246.45 +
246.46 +fun check_const p (nm, (ty, _)) =
246.47 + if p (nm, ty)
246.48 + then SOME (Term.size_of_typ ty)
246.49 + else NONE;
246.50 +
246.51 +fun opt_not f (c as (_, (ty, _))) =
246.52 + if is_some (f c)
246.53 + then NONE else SOME (Term.size_of_typ ty);
246.54 +
246.55 +fun filter_const _ NONE = NONE
246.56 + | filter_const f (SOME (c, r)) =
246.57 + Option.map (pair c o (curry Int.min r)) (f c);
246.58 +
246.59 +
246.60 +(* pretty results *)
246.61 +
246.62 +fun pretty_criterion (b, c) =
246.63 + let
246.64 + fun prfx s = if b then s else "-" ^ s;
246.65 + in
246.66 + (case c of
246.67 + Strict pat => Pretty.str (prfx "strict: " ^ quote pat)
246.68 + | Loose pat => Pretty.str (prfx (quote pat))
246.69 + | Name name => Pretty.str (prfx "name: " ^ quote name))
246.70 + end;
246.71 +
246.72 +fun pretty_const ctxt (nm, ty) =
246.73 + let
246.74 + val ty' = Logic.unvarifyT ty;
246.75 + in
246.76 + Pretty.block
246.77 + [Pretty.quote (Pretty.str nm), Pretty.fbrk,
246.78 + Pretty.str "::", Pretty.brk 1,
246.79 + Pretty.quote (Syntax.pretty_typ ctxt ty')]
246.80 + end;
246.81 +
246.82 +(* find_consts *)
246.83 +
246.84 +fun find_consts ctxt raw_criteria =
246.85 + let
246.86 + val start = start_timing ();
246.87 +
246.88 + val thy = ProofContext.theory_of ctxt;
246.89 + val low_ranking = 10000;
246.90 +
246.91 + fun not_internal consts (nm, _) =
246.92 + if member (op =) (Consts.the_tags consts nm) Markup.property_internal
246.93 + then NONE else SOME low_ranking;
246.94 +
246.95 + fun make_pattern crit =
246.96 + let
246.97 + val raw_T = Syntax.parse_typ ctxt crit;
246.98 + val t = Syntax.check_term
246.99 + (ProofContext.set_mode ProofContext.mode_pattern ctxt)
246.100 + (Term.dummy_pattern raw_T);
246.101 + in Term.type_of t end;
246.102 +
246.103 + fun make_match (Strict arg) =
246.104 + let val qty = make_pattern arg; in
246.105 + fn (_, (ty, _)) =>
246.106 + let
246.107 + val tye = Sign.typ_match thy (qty, ty) Vartab.empty;
246.108 + val sub_size = Vartab.fold add_tye tye 0;
246.109 + in SOME sub_size end handle MATCH => NONE
246.110 + end
246.111 +
246.112 + | make_match (Loose arg) =
246.113 + check_const (matches_subtype thy (make_pattern arg) o snd)
246.114 +
246.115 + | make_match (Name arg) = check_const (match_string arg o fst);
246.116 +
246.117 + fun make_criterion (b, crit) = (if b then I else opt_not) (make_match crit);
246.118 + val criteria = map make_criterion raw_criteria;
246.119 +
246.120 + val consts = Sign.consts_of thy;
246.121 + val (_, consts_tab) = (#constants o Consts.dest) consts;
246.122 + fun eval_entry c = fold filter_const (not_internal consts::criteria)
246.123 + (SOME (c, low_ranking));
246.124 +
246.125 + val matches =
246.126 + Symtab.fold (cons o eval_entry) consts_tab []
246.127 + |> map_filter I
246.128 + |> sort (rev_order o int_ord o pairself snd)
246.129 + |> map ((apsnd fst) o fst);
246.130 +
246.131 + val end_msg = " in " ^ Time.toString (#all (end_timing start)) ^ " secs";
246.132 + in
246.133 + Pretty.big_list "searched for:" (map pretty_criterion raw_criteria)
246.134 + :: Pretty.str ""
246.135 + :: (Pretty.str o concat)
246.136 + (if null matches
246.137 + then ["nothing found", end_msg]
246.138 + else ["found ", (string_of_int o length) matches,
246.139 + " constants", end_msg, ":"])
246.140 + :: Pretty.str ""
246.141 + :: map (pretty_const ctxt) matches
246.142 + |> Pretty.chunks
246.143 + |> Pretty.writeln
246.144 + end;
246.145 +
246.146 +
246.147 +(* command syntax *)
246.148 +
246.149 +fun find_consts_cmd spec =
246.150 + Toplevel.unknown_theory o Toplevel.keep (fn state =>
246.151 + find_consts (Proof.context_of (Toplevel.enter_proof_body state)) spec);
246.152 +
246.153 +local
246.154 +
246.155 +structure P = OuterParse and K = OuterKeyword;
246.156 +
246.157 +val criterion =
246.158 + P.reserved "strict" |-- P.!!! (P.$$$ ":" |-- P.xname) >> Strict ||
246.159 + P.reserved "name" |-- P.!!! (P.$$$ ":" |-- P.xname) >> Name ||
246.160 + P.xname >> Loose;
246.161 +
246.162 +in
246.163 +
246.164 +val _ =
246.165 + OuterSyntax.improper_command "find_consts" "search constants by type pattern" K.diag
246.166 + (Scan.repeat (((Scan.option P.minus >> is_none) -- criterion))
246.167 + >> (Toplevel.no_timing oo find_consts_cmd));
246.168 +
246.169 +end;
246.170 +
246.171 +end;
246.172 +
247.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
247.2 +++ b/src/Pure/Tools/find_theorems.ML Wed Mar 04 11:05:29 2009 +0100
247.3 @@ -0,0 +1,424 @@
247.4 +(* Title: Pure/Tools/find_theorems.ML
247.5 + Author: Rafal Kolanski and Gerwin Klein, NICTA
247.6 +
247.7 +Retrieve theorems from proof context.
247.8 +*)
247.9 +
247.10 +signature FIND_THEOREMS =
247.11 +sig
247.12 + datatype 'term criterion =
247.13 + Name of string | Intro | Elim | Dest | Solves | Simp of 'term |
247.14 + Pattern of 'term
247.15 + val tac_limit: int ref
247.16 + val limit: int ref
247.17 + val find_theorems: Proof.context -> thm option -> bool ->
247.18 + (bool * string criterion) list -> (Facts.ref * thm) list
247.19 + val pretty_thm: Proof.context -> Facts.ref * thm -> Pretty.T
247.20 + val print_theorems: Proof.context -> thm option -> int option -> bool ->
247.21 + (bool * string criterion) list -> unit
247.22 +end;
247.23 +
247.24 +structure FindTheorems: FIND_THEOREMS =
247.25 +struct
247.26 +
247.27 +(** search criteria **)
247.28 +
247.29 +datatype 'term criterion =
247.30 + Name of string | Intro | Elim | Dest | Solves | Simp of 'term |
247.31 + Pattern of 'term;
247.32 +
247.33 +fun read_criterion _ (Name name) = Name name
247.34 + | read_criterion _ Intro = Intro
247.35 + | read_criterion _ Elim = Elim
247.36 + | read_criterion _ Dest = Dest
247.37 + | read_criterion _ Solves = Solves
247.38 + | read_criterion ctxt (Simp str) = Simp (ProofContext.read_term_pattern ctxt str)
247.39 + | read_criterion ctxt (Pattern str) = Pattern (ProofContext.read_term_pattern ctxt str);
247.40 +
247.41 +fun pretty_criterion ctxt (b, c) =
247.42 + let
247.43 + fun prfx s = if b then s else "-" ^ s;
247.44 + in
247.45 + (case c of
247.46 + Name name => Pretty.str (prfx "name: " ^ quote name)
247.47 + | Intro => Pretty.str (prfx "intro")
247.48 + | Elim => Pretty.str (prfx "elim")
247.49 + | Dest => Pretty.str (prfx "dest")
247.50 + | Solves => Pretty.str (prfx "solves")
247.51 + | Simp pat => Pretty.block [Pretty.str (prfx "simp:"), Pretty.brk 1,
247.52 + Pretty.quote (Syntax.pretty_term ctxt (Term.show_dummy_patterns pat))]
247.53 + | Pattern pat => Pretty.enclose (prfx " \"") "\""
247.54 + [Syntax.pretty_term ctxt (Term.show_dummy_patterns pat)])
247.55 + end;
247.56 +
247.57 +
247.58 +
247.59 +(** search criterion filters **)
247.60 +
247.61 +(*generated filters are to be of the form
247.62 + input: (Facts.ref * thm)
247.63 + output: (p:int, s:int) option, where
247.64 + NONE indicates no match
247.65 + p is the primary sorting criterion
247.66 + (eg. number of assumptions in the theorem)
247.67 + s is the secondary sorting criterion
247.68 + (eg. size of the substitution for intro, elim and dest)
247.69 + when applying a set of filters to a thm, fold results in:
247.70 + (biggest p, sum of all s)
247.71 + currently p and s only matter for intro, elim, dest and simp filters,
247.72 + otherwise the default ordering is used.
247.73 +*)
247.74 +
247.75 +
247.76 +(* matching theorems *)
247.77 +
247.78 +fun is_nontrivial thy = Term.is_Const o Term.head_of o ObjectLogic.drop_judgment thy;
247.79 +
247.80 +(*extract terms from term_src, refine them to the parts that concern us,
247.81 + if po try match them against obj else vice versa.
247.82 + trivial matches are ignored.
247.83 + returns: smallest substitution size*)
247.84 +fun is_matching_thm (extract_terms, refine_term) ctxt po obj term_src =
247.85 + let
247.86 + val thy = ProofContext.theory_of ctxt;
247.87 +
247.88 + fun matches pat =
247.89 + is_nontrivial thy pat andalso
247.90 + Pattern.matches thy (if po then (pat, obj) else (obj, pat));
247.91 +
247.92 + fun substsize pat =
247.93 + let val (_, subst) =
247.94 + Pattern.match thy (if po then (pat, obj) else (obj, pat)) (Vartab.empty, Vartab.empty)
247.95 + in Vartab.fold (fn (_, (_, t)) => fn n => size_of_term t + n) subst 0 end;
247.96 +
247.97 + fun bestmatch [] = NONE
247.98 + | bestmatch xs = SOME (foldr1 Int.min xs);
247.99 +
247.100 + val match_thm = matches o refine_term;
247.101 + in
247.102 + map (substsize o refine_term) (filter match_thm (extract_terms term_src))
247.103 + |> bestmatch
247.104 + end;
247.105 +
247.106 +
247.107 +(* filter_name *)
247.108 +
247.109 +fun filter_name str_pat (thmref, _) =
247.110 + if match_string str_pat (Facts.name_of_ref thmref)
247.111 + then SOME (0, 0) else NONE;
247.112 +
247.113 +
247.114 +(* filter intro/elim/dest/solves rules *)
247.115 +
247.116 +fun filter_dest ctxt goal (_, thm) =
247.117 + let
247.118 + val extract_dest =
247.119 + (fn thm => if Thm.no_prems thm then [] else [Thm.full_prop_of thm],
247.120 + hd o Logic.strip_imp_prems);
247.121 + val prems = Logic.prems_of_goal goal 1;
247.122 +
247.123 + fun try_subst prem = is_matching_thm extract_dest ctxt true prem thm;
247.124 + val successful = prems |> map_filter try_subst;
247.125 + in
247.126 + (*if possible, keep best substitution (one with smallest size)*)
247.127 + (*dest rules always have assumptions, so a dest with one
247.128 + assumption is as good as an intro rule with none*)
247.129 + if not (null successful)
247.130 + then SOME (Thm.nprems_of thm - 1, foldr1 Int.min successful) else NONE
247.131 + end;
247.132 +
247.133 +fun filter_intro ctxt goal (_, thm) =
247.134 + let
247.135 + val extract_intro = (single o Thm.full_prop_of, Logic.strip_imp_concl);
247.136 + val concl = Logic.concl_of_goal goal 1;
247.137 + val ss = is_matching_thm extract_intro ctxt true concl thm;
247.138 + in
247.139 + if is_some ss then SOME (Thm.nprems_of thm, the ss) else NONE
247.140 + end;
247.141 +
247.142 +fun filter_elim ctxt goal (_, thm) =
247.143 + if not (Thm.no_prems thm) then
247.144 + let
247.145 + val rule = Thm.full_prop_of thm;
247.146 + val prems = Logic.prems_of_goal goal 1;
247.147 + val goal_concl = Logic.concl_of_goal goal 1;
247.148 + val rule_mp = hd (Logic.strip_imp_prems rule);
247.149 + val rule_concl = Logic.strip_imp_concl rule;
247.150 + fun combine t1 t2 = Const ("*combine*", dummyT --> dummyT) $ (t1 $ t2);
247.151 + val rule_tree = combine rule_mp rule_concl;
247.152 + fun goal_tree prem = combine prem goal_concl;
247.153 + fun try_subst prem =
247.154 + is_matching_thm (single, I) ctxt true (goal_tree prem) rule_tree;
247.155 + val successful = prems |> map_filter try_subst;
247.156 + in
247.157 + (*elim rules always have assumptions, so an elim with one
247.158 + assumption is as good as an intro rule with none*)
247.159 + if is_nontrivial (ProofContext.theory_of ctxt) (Thm.major_prem_of thm)
247.160 + andalso not (null successful)
247.161 + then SOME (Thm.nprems_of thm - 1, foldr1 Int.min successful) else NONE
247.162 + end
247.163 + else NONE
247.164 +
247.165 +val tac_limit = ref 5;
247.166 +
247.167 +fun filter_solves ctxt goal =
247.168 + let
247.169 + val baregoal = Logic.get_goal (Thm.prop_of goal) 1;
247.170 +
247.171 + fun etacn thm i = Seq.take (! tac_limit) o etac thm i;
247.172 + fun try_thm thm =
247.173 + if Thm.no_prems thm then rtac thm 1 goal
247.174 + else (etacn thm THEN_ALL_NEW
247.175 + (Goal.norm_hhf_tac THEN' Method.assm_tac ctxt)) 1 goal;
247.176 + in
247.177 + fn (_, thm) =>
247.178 + if (is_some o Seq.pull o try_thm) thm
247.179 + then SOME (Thm.nprems_of thm, 0) else NONE
247.180 + end;
247.181 +
247.182 +
247.183 +(* filter_simp *)
247.184 +
247.185 +fun filter_simp ctxt t (_, thm) =
247.186 + let
247.187 + val (_, {mk_rews = {mk, ...}, ...}) =
247.188 + Simplifier.rep_ss (Simplifier.local_simpset_of ctxt);
247.189 + val extract_simp =
247.190 + (map Thm.full_prop_of o mk, #1 o Logic.dest_equals o Logic.strip_imp_concl);
247.191 + val ss = is_matching_thm extract_simp ctxt false t thm
247.192 + in
247.193 + if is_some ss then SOME (Thm.nprems_of thm, the ss) else NONE
247.194 + end;
247.195 +
247.196 +
247.197 +(* filter_pattern *)
247.198 +
247.199 +fun get_names t = (Term.add_const_names t []) union (Term.add_free_names t []);
247.200 +fun get_thm_names (_, thm) = get_names (Thm.full_prop_of thm);
247.201 +
247.202 +(*Including all constants and frees is only sound because
247.203 + matching uses higher-order patterns. If full matching
247.204 + were used, then constants that may be subject to
247.205 + beta-reduction after substitution of frees should
247.206 + not be included for LHS set because they could be
247.207 + thrown away by the substituted function.
247.208 + e.g. for (?F 1 2) do not include 1 or 2, if it were
247.209 + possible for ?F to be (% x y. 3)
247.210 + The largest possible set should always be included on
247.211 + the RHS.*)
247.212 +
247.213 +fun filter_pattern ctxt pat =
247.214 + let
247.215 + val pat_consts = get_names pat;
247.216 +
247.217 + fun check (t, NONE) = check (t, SOME (get_thm_names t))
247.218 + | check ((_, thm), c as SOME thm_consts) =
247.219 + (if pat_consts subset_string thm_consts
247.220 + andalso (Pattern.matches_subterm (ProofContext.theory_of ctxt)
247.221 + (pat, Thm.full_prop_of thm))
247.222 + then SOME (0, 0) else NONE, c);
247.223 + in check end;
247.224 +
247.225 +
247.226 +(* interpret criteria as filters *)
247.227 +
247.228 +local
247.229 +
247.230 +fun err_no_goal c =
247.231 + error ("Current goal required for " ^ c ^ " search criterion");
247.232 +
247.233 +val fix_goal = Thm.prop_of;
247.234 +val fix_goalo = Option.map fix_goal;
247.235 +
247.236 +fun filter_crit _ _ (Name name) = apfst (filter_name name)
247.237 + | filter_crit _ NONE Intro = err_no_goal "intro"
247.238 + | filter_crit _ NONE Elim = err_no_goal "elim"
247.239 + | filter_crit _ NONE Dest = err_no_goal "dest"
247.240 + | filter_crit _ NONE Solves = err_no_goal "solves"
247.241 + | filter_crit ctxt (SOME goal) Intro = apfst (filter_intro ctxt (fix_goal goal))
247.242 + | filter_crit ctxt (SOME goal) Elim = apfst (filter_elim ctxt (fix_goal goal))
247.243 + | filter_crit ctxt (SOME goal) Dest = apfst (filter_dest ctxt (fix_goal goal))
247.244 + | filter_crit ctxt (SOME goal) Solves = apfst (filter_solves ctxt goal)
247.245 + | filter_crit ctxt _ (Simp pat) = apfst (filter_simp ctxt pat)
247.246 + | filter_crit ctxt _ (Pattern pat) = filter_pattern ctxt pat;
247.247 +
247.248 +fun opt_not x = if is_some x then NONE else SOME (0, 0);
247.249 +
247.250 +fun opt_add (SOME (a, x)) (SOME (b, y)) = SOME (Int.max (a, b), x + y : int)
247.251 + | opt_add _ _ = NONE;
247.252 +
247.253 +fun app_filters thm =
247.254 + let
247.255 + fun app (NONE, _, _) = NONE
247.256 + | app (SOME v, consts, []) = SOME (v, thm)
247.257 + | app (r, consts, f :: fs) =
247.258 + let val (r', consts') = f (thm, consts)
247.259 + in app (opt_add r r', consts', fs) end;
247.260 + in app end;
247.261 +
247.262 +in
247.263 +
247.264 +fun filter_criterion ctxt opt_goal (b, c) =
247.265 + (if b then I else (apfst opt_not)) o filter_crit ctxt opt_goal c;
247.266 +
247.267 +fun all_filters filters thms =
247.268 + let
247.269 + fun eval_filters thm = app_filters thm (SOME (0, 0), NONE, filters);
247.270 +
247.271 + (*filters return: (number of assumptions, substitution size) option, so
247.272 + sort (desc. in both cases) according to number of assumptions first,
247.273 + then by the substitution size*)
247.274 + fun thm_ord (((p0, s0), _), ((p1, s1), _)) =
247.275 + prod_ord int_ord int_ord ((p1, s1), (p0, s0));
247.276 + in map_filter eval_filters thms |> sort thm_ord |> map #2 end;
247.277 +
247.278 +end;
247.279 +
247.280 +
247.281 +(* removing duplicates, preferring nicer names, roughly n log n *)
247.282 +
247.283 +local
247.284 +
247.285 +val index_ord = option_ord (K EQUAL);
247.286 +val hidden_ord = bool_ord o pairself NameSpace.is_hidden;
247.287 +val qual_ord = int_ord o pairself (length o NameSpace.explode);
247.288 +val txt_ord = int_ord o pairself size;
247.289 +
247.290 +fun nicer_name (x, i) (y, j) =
247.291 + (case hidden_ord (x, y) of EQUAL =>
247.292 + (case index_ord (i, j) of EQUAL =>
247.293 + (case qual_ord (x, y) of EQUAL => txt_ord (x, y) | ord => ord)
247.294 + | ord => ord)
247.295 + | ord => ord) <> GREATER;
247.296 +
247.297 +fun rem_cdups nicer xs =
247.298 + let
247.299 + fun rem_c rev_seen [] = rev rev_seen
247.300 + | rem_c rev_seen [x] = rem_c (x :: rev_seen) []
247.301 + | rem_c rev_seen ((x as ((n, t), _)) :: (y as ((n', t'), _)) :: xs) =
247.302 + if Thm.eq_thm_prop (t, t')
247.303 + then rem_c rev_seen ((if nicer n n' then x else y) :: xs)
247.304 + else rem_c (x :: rev_seen) (y :: xs)
247.305 + in rem_c [] xs end;
247.306 +
247.307 +in
247.308 +
247.309 +fun nicer_shortest ctxt =
247.310 + let
247.311 + (* FIXME global name space!? *)
247.312 + val space = Facts.space_of (PureThy.facts_of (ProofContext.theory_of ctxt));
247.313 +
247.314 + val shorten =
247.315 + NameSpace.extern_flags {long_names = false, short_names = false, unique_names = false} space;
247.316 +
247.317 + fun nicer (Facts.Named ((x, _), i)) (Facts.Named ((y, _), j)) =
247.318 + nicer_name (shorten x, i) (shorten y, j)
247.319 + | nicer (Facts.Fact _) (Facts.Named _) = true
247.320 + | nicer (Facts.Named _) (Facts.Fact _) = false;
247.321 + in nicer end;
247.322 +
247.323 +fun rem_thm_dups nicer xs =
247.324 + xs ~~ (1 upto length xs)
247.325 + |> sort (TermOrd.fast_term_ord o pairself (Thm.prop_of o #2 o #1))
247.326 + |> rem_cdups nicer
247.327 + |> sort (int_ord o pairself #2)
247.328 + |> map #1;
247.329 +
247.330 +end;
247.331 +
247.332 +
247.333 +(* print_theorems *)
247.334 +
247.335 +fun all_facts_of ctxt =
247.336 + maps Facts.selections
247.337 + (Facts.dest_static [] (PureThy.facts_of (ProofContext.theory_of ctxt)) @
247.338 + Facts.dest_static [] (ProofContext.facts_of ctxt));
247.339 +
247.340 +val limit = ref 40;
247.341 +
247.342 +fun find_theorems ctxt opt_goal rem_dups raw_criteria =
247.343 + let
247.344 + val add_prems = Seq.hd o (TRY (Method.insert_tac (Assumption.prems_of ctxt) 1));
247.345 + val opt_goal' = Option.map add_prems opt_goal;
247.346 +
247.347 + val criteria = map (apsnd (read_criterion ctxt)) raw_criteria;
247.348 + val filters = map (filter_criterion ctxt opt_goal') criteria;
247.349 +
247.350 + val raw_matches = all_filters filters (all_facts_of ctxt);
247.351 +
247.352 + val matches =
247.353 + if rem_dups
247.354 + then rem_thm_dups (nicer_shortest ctxt) raw_matches
247.355 + else raw_matches;
247.356 + in matches end;
247.357 +
247.358 +
247.359 +fun pretty_thm ctxt (thmref, thm) = Pretty.block
247.360 + [Pretty.str (Facts.string_of_ref thmref), Pretty.str ":", Pretty.brk 1,
247.361 + ProofContext.pretty_thm ctxt thm];
247.362 +
247.363 +fun print_theorems ctxt opt_goal opt_limit rem_dups raw_criteria =
247.364 + let
247.365 + val start = start_timing ();
247.366 +
247.367 + val criteria = map (apsnd (read_criterion ctxt)) raw_criteria;
247.368 + val matches = find_theorems ctxt opt_goal rem_dups raw_criteria;
247.369 +
247.370 + val len = length matches;
247.371 + val lim = the_default (! limit) opt_limit;
247.372 + val thms = Library.drop (len - lim, matches);
247.373 +
247.374 + val end_msg = " in " ^ Time.toString (#all (end_timing start)) ^ " secs";
247.375 + in
247.376 + Pretty.big_list "searched for:" (map (pretty_criterion ctxt) criteria)
247.377 + :: Pretty.str "" ::
247.378 + (if null thms then [Pretty.str ("nothing found" ^ end_msg)]
247.379 + else
247.380 + [Pretty.str ("found " ^ string_of_int len ^ " theorems" ^
247.381 + (if len <= lim then ""
247.382 + else " (" ^ string_of_int lim ^ " displayed)")
247.383 + ^ end_msg ^ ":"), Pretty.str ""] @
247.384 + map (pretty_thm ctxt) thms)
247.385 + |> Pretty.chunks |> Pretty.writeln
247.386 + end;
247.387 +
247.388 +
247.389 +
247.390 +(** command syntax **)
247.391 +
247.392 +fun find_theorems_cmd ((opt_lim, rem_dups), spec) =
247.393 + Toplevel.unknown_theory o Toplevel.keep (fn state =>
247.394 + let
247.395 + val proof_state = Toplevel.enter_proof_body state;
247.396 + val ctxt = Proof.context_of proof_state;
247.397 + val opt_goal = try Proof.get_goal proof_state |> Option.map (#2 o #2);
247.398 + in print_theorems ctxt opt_goal opt_lim rem_dups spec end);
247.399 +
247.400 +local
247.401 +
247.402 +structure P = OuterParse and K = OuterKeyword;
247.403 +
247.404 +val criterion =
247.405 + P.reserved "name" |-- P.!!! (P.$$$ ":" |-- P.xname) >> Name ||
247.406 + P.reserved "intro" >> K Intro ||
247.407 + P.reserved "elim" >> K Elim ||
247.408 + P.reserved "dest" >> K Dest ||
247.409 + P.reserved "solves" >> K Solves ||
247.410 + P.reserved "simp" |-- P.!!! (P.$$$ ":" |-- P.term) >> Simp ||
247.411 + P.term >> Pattern;
247.412 +
247.413 +val options =
247.414 + Scan.optional
247.415 + (P.$$$ "(" |--
247.416 + P.!!! (Scan.option P.nat -- Scan.optional (P.reserved "with_dups" >> K false) true
247.417 + --| P.$$$ ")")) (NONE, true);
247.418 +in
247.419 +
247.420 +val _ =
247.421 + OuterSyntax.improper_command "find_theorems" "print theorems meeting specified criteria" K.diag
247.422 + (options -- Scan.repeat (((Scan.option P.minus >> is_none) -- criterion))
247.423 + >> (Toplevel.no_timing oo find_theorems_cmd));
247.424 +
247.425 +end;
247.426 +
247.427 +end;
248.1 --- a/src/Pure/Tools/isabelle_process.ML Wed Mar 04 11:05:02 2009 +0100
248.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
248.3 @@ -1,138 +0,0 @@
248.4 -(* Title: Pure/Tools/isabelle_process.ML
248.5 - Author: Makarius
248.6 -
248.7 -Isabelle process wrapper -- interaction via external program.
248.8 -
248.9 -General format of process output:
248.10 -
248.11 - (1) unmarked stdout/stderr, no line structure (output should be
248.12 - processed immediately as it arrives);
248.13 -
248.14 - (2) properly marked-up messages, e.g. for writeln channel
248.15 -
248.16 - "\002A" ^ props ^ "\002,\n" ^ text ^ "\002.\n"
248.17 -
248.18 - where the props consist of name=value lines terminated by "\002,\n"
248.19 - each, and the remaining text is any number of lines (output is
248.20 - supposed to be processed in one piece);
248.21 -
248.22 - (3) special init message holds "pid" and "session" property;
248.23 -
248.24 - (4) message content is encoded in YXML format.
248.25 -*)
248.26 -
248.27 -signature ISABELLE_PROCESS =
248.28 -sig
248.29 - val isabelle_processN: string
248.30 - val init: string -> unit
248.31 -end;
248.32 -
248.33 -structure IsabelleProcess: ISABELLE_PROCESS =
248.34 -struct
248.35 -
248.36 -(* print modes *)
248.37 -
248.38 -val isabelle_processN = "isabelle_process";
248.39 -
248.40 -val _ = Output.add_mode isabelle_processN Output.default_output Output.default_escape;
248.41 -val _ = Markup.add_mode isabelle_processN YXML.output_markup;
248.42 -
248.43 -
248.44 -(* message markup *)
248.45 -
248.46 -fun special ch = Symbol.STX ^ ch;
248.47 -val special_sep = special ",";
248.48 -val special_end = special ".";
248.49 -
248.50 -local
248.51 -
248.52 -fun clean_string bad str =
248.53 - if exists_string (member (op =) bad) str then
248.54 - translate_string (fn c => if member (op =) bad c then Symbol.DEL else c) str
248.55 - else str;
248.56 -
248.57 -fun message_props props =
248.58 - let val clean = clean_string [Symbol.STX, "\n", "\r"]
248.59 - in implode (map (fn (x, y) => clean x ^ "=" ^ clean y ^ special_sep ^ "\n") props) end;
248.60 -
248.61 -fun message_pos trees = trees |> get_first
248.62 - (fn XML.Elem (name, atts, ts) =>
248.63 - if name = Markup.positionN then SOME (Position.of_properties atts)
248.64 - else message_pos ts
248.65 - | _ => NONE);
248.66 -
248.67 -fun output out_stream s = NAMED_CRITICAL "IO" (fn () =>
248.68 - (TextIO.output (out_stream, s); TextIO.output (out_stream, "\n")));
248.69 -
248.70 -in
248.71 -
248.72 -fun message _ _ "" = ()
248.73 - | message out_stream ch body =
248.74 - let
248.75 - val pos = the_default Position.none (message_pos (YXML.parse_body body));
248.76 - val props =
248.77 - Position.properties_of (Position.thread_data ())
248.78 - |> Position.default_properties pos;
248.79 - val txt = clean_string [Symbol.STX] body;
248.80 - in output out_stream (special ch ^ message_props props ^ txt ^ special_end) end;
248.81 -
248.82 -fun init_message out_stream =
248.83 - let
248.84 - val pid = (Markup.pidN, process_id ());
248.85 - val session = (Markup.sessionN, List.last (Session.id ()) handle List.Empty => "unknown");
248.86 - val text = Session.welcome ();
248.87 - in output out_stream (special "A" ^ message_props [pid, session] ^ text ^ special_end) end;
248.88 -
248.89 -end;
248.90 -
248.91 -
248.92 -(* channels *)
248.93 -
248.94 -local
248.95 -
248.96 -fun auto_flush stream =
248.97 - let
248.98 - val _ = TextIO.StreamIO.setBufferMode (TextIO.getOutstream stream, IO.BLOCK_BUF);
248.99 - fun loop () =
248.100 - (OS.Process.sleep (Time.fromMilliseconds 50); try TextIO.flushOut stream; loop ());
248.101 - in loop end;
248.102 -
248.103 -in
248.104 -
248.105 -fun setup_channels out =
248.106 - let
248.107 - val out_stream =
248.108 - if out = "-" then TextIO.stdOut
248.109 - else
248.110 - let
248.111 - val path = File.platform_path (Path.explode out);
248.112 - val out_stream = TextIO.openOut path; (*fifo blocks until reader is ready*)
248.113 - val _ = OS.FileSys.remove path; (*prevent alien access, indicate writer is ready*)
248.114 - val _ = SimpleThread.fork false (auto_flush TextIO.stdOut);
248.115 - in out_stream end;
248.116 - val _ = SimpleThread.fork false (auto_flush out_stream);
248.117 - val _ = SimpleThread.fork false (auto_flush TextIO.stdErr);
248.118 - in
248.119 - Output.status_fn := message out_stream "B";
248.120 - Output.writeln_fn := message out_stream "C";
248.121 - Output.priority_fn := message out_stream "D";
248.122 - Output.tracing_fn := message out_stream "E";
248.123 - Output.warning_fn := message out_stream "F";
248.124 - Output.error_fn := message out_stream "G";
248.125 - Output.debug_fn := message out_stream "H";
248.126 - Output.prompt_fn := ignore;
248.127 - out_stream
248.128 - end;
248.129 -
248.130 -end;
248.131 -
248.132 -
248.133 -(* init *)
248.134 -
248.135 -fun init out =
248.136 - (change print_mode (update (op =) isabelle_processN);
248.137 - setup_channels out |> init_message;
248.138 - OuterKeyword.report ();
248.139 - Isar.toplevel_loop {init = true, welcome = false, sync = true, secure = true});
248.140 -
248.141 -end;
249.1 --- a/src/Pure/Tools/isabelle_process.scala Wed Mar 04 11:05:02 2009 +0100
249.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
249.3 @@ -1,435 +0,0 @@
249.4 -/* Title: Pure/Tools/isabelle_process.ML
249.5 - Author: Makarius
249.6 - Options: :folding=explicit:collapseFolds=1:
249.7 -
249.8 -Isabelle process management -- always reactive due to multi-threaded I/O.
249.9 -*/
249.10 -
249.11 -package isabelle
249.12 -
249.13 -import java.util.concurrent.LinkedBlockingQueue
249.14 -import java.io.{BufferedReader, BufferedWriter, InputStreamReader, OutputStreamWriter,
249.15 - InputStream, OutputStream, IOException}
249.16 -
249.17 -
249.18 -object IsabelleProcess {
249.19 -
249.20 - /* results */
249.21 -
249.22 - object Kind extends Enumeration {
249.23 - //{{{ values and codes
249.24 - // internal system notification
249.25 - val SYSTEM = Value("SYSTEM")
249.26 - // Posix channels/events
249.27 - val STDIN = Value("STDIN")
249.28 - val STDOUT = Value("STDOUT")
249.29 - val SIGNAL = Value("SIGNAL")
249.30 - val EXIT = Value("EXIT")
249.31 - // Isabelle messages
249.32 - val INIT = Value("INIT")
249.33 - val STATUS = Value("STATUS")
249.34 - val WRITELN = Value("WRITELN")
249.35 - val PRIORITY = Value("PRIORITY")
249.36 - val TRACING = Value("TRACING")
249.37 - val WARNING = Value("WARNING")
249.38 - val ERROR = Value("ERROR")
249.39 - val DEBUG = Value("DEBUG")
249.40 - // messages codes
249.41 - val code = Map(
249.42 - ('A' : Int) -> Kind.INIT,
249.43 - ('B' : Int) -> Kind.STATUS,
249.44 - ('C' : Int) -> Kind.WRITELN,
249.45 - ('D' : Int) -> Kind.PRIORITY,
249.46 - ('E' : Int) -> Kind.TRACING,
249.47 - ('F' : Int) -> Kind.WARNING,
249.48 - ('G' : Int) -> Kind.ERROR,
249.49 - ('H' : Int) -> Kind.DEBUG,
249.50 - ('0' : Int) -> Kind.SYSTEM,
249.51 - ('1' : Int) -> Kind.STDIN,
249.52 - ('2' : Int) -> Kind.STDOUT,
249.53 - ('3' : Int) -> Kind.SIGNAL,
249.54 - ('4' : Int) -> Kind.EXIT)
249.55 - // message markup
249.56 - val markup = Map(
249.57 - Kind.INIT -> Markup.INIT,
249.58 - Kind.STATUS -> Markup.STATUS,
249.59 - Kind.WRITELN -> Markup.WRITELN,
249.60 - Kind.PRIORITY -> Markup.PRIORITY,
249.61 - Kind.TRACING -> Markup.TRACING,
249.62 - Kind.WARNING -> Markup.WARNING,
249.63 - Kind.ERROR -> Markup.ERROR,
249.64 - Kind.DEBUG -> Markup.DEBUG,
249.65 - Kind.SYSTEM -> Markup.SYSTEM,
249.66 - Kind.STDIN -> Markup.STDIN,
249.67 - Kind.STDOUT -> Markup.STDOUT,
249.68 - Kind.SIGNAL -> Markup.SIGNAL,
249.69 - Kind.EXIT -> Markup.EXIT)
249.70 - //}}}
249.71 - def is_raw(kind: Value) =
249.72 - kind == STDOUT
249.73 - def is_control(kind: Value) =
249.74 - kind == SYSTEM ||
249.75 - kind == SIGNAL ||
249.76 - kind == EXIT
249.77 - def is_system(kind: Value) =
249.78 - kind == SYSTEM ||
249.79 - kind == STDIN ||
249.80 - kind == SIGNAL ||
249.81 - kind == EXIT ||
249.82 - kind == STATUS
249.83 - }
249.84 -
249.85 - class Result(val kind: Kind.Value, val props: List[(String, String)], val result: String) {
249.86 - override def toString = {
249.87 - val trees = YXML.parse_body_failsafe(result)
249.88 - val res =
249.89 - if (kind == Kind.STATUS) trees.map(_.toString).mkString
249.90 - else trees.flatMap(XML.content(_).mkString).mkString
249.91 - if (props.isEmpty)
249.92 - kind.toString + " [[" + res + "]]"
249.93 - else
249.94 - kind.toString + " " +
249.95 - (for ((x, y) <- props) yield x + "=" + y).mkString("{", ",", "}") + " [[" + res + "]]"
249.96 - }
249.97 - def is_raw = Kind.is_raw(kind)
249.98 - def is_control = Kind.is_control(kind)
249.99 - def is_system = Kind.is_system(kind)
249.100 - }
249.101 -
249.102 - def parse_message(isabelle_system: IsabelleSystem, result: Result) =
249.103 - {
249.104 - XML.Elem(Markup.MESSAGE, (Markup.CLASS, Kind.markup(result.kind)) :: result.props,
249.105 - YXML.parse_body_failsafe(isabelle_system.symbols.decode(result.result)))
249.106 - }
249.107 -}
249.108 -
249.109 -
249.110 -class IsabelleProcess(isabelle_system: IsabelleSystem,
249.111 - results: EventBus[IsabelleProcess.Result], args: String*)
249.112 -{
249.113 - import IsabelleProcess._
249.114 -
249.115 -
249.116 - /* demo constructor */
249.117 -
249.118 - def this(args: String*) =
249.119 - this(new IsabelleSystem, new EventBus[IsabelleProcess.Result] + Console.println, args: _*)
249.120 -
249.121 -
249.122 - /* process information */
249.123 -
249.124 - @volatile private var proc: Process = null
249.125 - @volatile private var closing = false
249.126 - @volatile private var pid: String = null
249.127 - @volatile private var the_session: String = null
249.128 - def session = the_session
249.129 -
249.130 -
249.131 - /* results */
249.132 -
249.133 - def parse_message(result: Result): XML.Tree =
249.134 - IsabelleProcess.parse_message(isabelle_system, result)
249.135 -
249.136 - private val result_queue = new LinkedBlockingQueue[Result]
249.137 -
249.138 - private def put_result(kind: Kind.Value, props: List[(String, String)], result: String)
249.139 - {
249.140 - if (kind == Kind.INIT) {
249.141 - val map = Map(props: _*)
249.142 - if (map.isDefinedAt(Markup.PID)) pid = map(Markup.PID)
249.143 - if (map.isDefinedAt(Markup.SESSION)) the_session = map(Markup.SESSION)
249.144 - }
249.145 - result_queue.put(new Result(kind, props, result))
249.146 - }
249.147 -
249.148 - private class ResultThread extends Thread("isabelle: results") {
249.149 - override def run() = {
249.150 - var finished = false
249.151 - while (!finished) {
249.152 - val result =
249.153 - try { result_queue.take }
249.154 - catch { case _: NullPointerException => null }
249.155 -
249.156 - if (result != null) {
249.157 - results.event(result)
249.158 - if (result.kind == Kind.EXIT) finished = true
249.159 - }
249.160 - else finished = true
249.161 - }
249.162 - }
249.163 - }
249.164 -
249.165 -
249.166 - /* signals */
249.167 -
249.168 - def interrupt() = synchronized {
249.169 - if (proc == null) error("Cannot interrupt Isabelle: no process")
249.170 - if (pid == null) put_result(Kind.SYSTEM, Nil, "Cannot interrupt: unknown pid")
249.171 - else {
249.172 - try {
249.173 - if (isabelle_system.execute(true, "kill", "-INT", pid).waitFor == 0)
249.174 - put_result(Kind.SIGNAL, Nil, "INT")
249.175 - else
249.176 - put_result(Kind.SYSTEM, Nil, "Cannot interrupt: kill command failed")
249.177 - }
249.178 - catch { case e: IOException => error("Cannot interrupt Isabelle: " + e.getMessage) }
249.179 - }
249.180 - }
249.181 -
249.182 - def kill() = synchronized {
249.183 - if (proc == 0) error("Cannot kill Isabelle: no process")
249.184 - else {
249.185 - try_close()
249.186 - Thread.sleep(500)
249.187 - put_result(Kind.SIGNAL, Nil, "KILL")
249.188 - proc.destroy
249.189 - proc = null
249.190 - pid = null
249.191 - }
249.192 - }
249.193 -
249.194 -
249.195 - /* output being piped into the process */
249.196 -
249.197 - private val output = new LinkedBlockingQueue[String]
249.198 -
249.199 - private def output_raw(text: String) = synchronized {
249.200 - if (proc == null) error("Cannot output to Isabelle: no process")
249.201 - if (closing) error("Cannot output to Isabelle: already closing")
249.202 - output.put(text)
249.203 - }
249.204 -
249.205 - def output_sync(text: String) =
249.206 - output_raw(" \\<^sync>\n; " + text + " \\<^sync>;\n")
249.207 -
249.208 -
249.209 - def command(text: String) =
249.210 - output_sync("Isabelle.command " + IsabelleSyntax.encode_string(text))
249.211 -
249.212 - def command(props: List[(String, String)], text: String) =
249.213 - output_sync("Isabelle.command " + IsabelleSyntax.encode_properties(props) + " " +
249.214 - IsabelleSyntax.encode_string(text))
249.215 -
249.216 - def ML(text: String) =
249.217 - output_sync("ML_val " + IsabelleSyntax.encode_string(text))
249.218 -
249.219 - def close() = synchronized { // FIXME watchdog/timeout
249.220 - output_raw("\u0000")
249.221 - closing = true
249.222 - }
249.223 -
249.224 - def try_close() = synchronized {
249.225 - if (proc != null && !closing) {
249.226 - try { close() }
249.227 - catch { case _: RuntimeException => }
249.228 - }
249.229 - }
249.230 -
249.231 -
249.232 - /* stdin */
249.233 -
249.234 - private class StdinThread(out_stream: OutputStream) extends Thread("isabelle: stdin") {
249.235 - override def run() = {
249.236 - val writer = new BufferedWriter(new OutputStreamWriter(out_stream, isabelle_system.charset))
249.237 - var finished = false
249.238 - while (!finished) {
249.239 - try {
249.240 - //{{{
249.241 - val s = output.take
249.242 - if (s == "\u0000") {
249.243 - writer.close
249.244 - finished = true
249.245 - }
249.246 - else {
249.247 - put_result(Kind.STDIN, Nil, s)
249.248 - writer.write(s)
249.249 - writer.flush
249.250 - }
249.251 - //}}}
249.252 - }
249.253 - catch {
249.254 - case e: IOException => put_result(Kind.SYSTEM, Nil, "Stdin thread: " + e.getMessage)
249.255 - }
249.256 - }
249.257 - put_result(Kind.SYSTEM, Nil, "Stdin thread terminated")
249.258 - }
249.259 - }
249.260 -
249.261 -
249.262 - /* stdout */
249.263 -
249.264 - private class StdoutThread(in_stream: InputStream) extends Thread("isabelle: stdout") {
249.265 - override def run() = {
249.266 - val reader = new BufferedReader(new InputStreamReader(in_stream, isabelle_system.charset))
249.267 - var result = new StringBuilder(100)
249.268 -
249.269 - var finished = false
249.270 - while (!finished) {
249.271 - try {
249.272 - //{{{
249.273 - var c = -1
249.274 - var done = false
249.275 - while (!done && (result.length == 0 || reader.ready)) {
249.276 - c = reader.read
249.277 - if (c >= 0) result.append(c.asInstanceOf[Char])
249.278 - else done = true
249.279 - }
249.280 - if (result.length > 0) {
249.281 - put_result(Kind.STDOUT, Nil, result.toString)
249.282 - result.length = 0
249.283 - }
249.284 - else {
249.285 - reader.close
249.286 - finished = true
249.287 - try_close()
249.288 - }
249.289 - //}}}
249.290 - }
249.291 - catch {
249.292 - case e: IOException => put_result(Kind.SYSTEM, Nil, "Stdout thread: " + e.getMessage)
249.293 - }
249.294 - }
249.295 - put_result(Kind.SYSTEM, Nil, "Stdout thread terminated")
249.296 - }
249.297 - }
249.298 -
249.299 -
249.300 - /* messages */
249.301 -
249.302 - private class MessageThread(fifo: String) extends Thread("isabelle: messages") {
249.303 - override def run() = {
249.304 - val reader = isabelle_system.fifo_reader(fifo)
249.305 - var kind: Kind.Value = null
249.306 - var props: List[(String, String)] = Nil
249.307 - var result = new StringBuilder
249.308 -
249.309 - var finished = false
249.310 - while (!finished) {
249.311 - try {
249.312 - if (kind == null) {
249.313 - //{{{ Char mode -- resync
249.314 - var c = -1
249.315 - do {
249.316 - c = reader.read
249.317 - if (c >= 0 && c != 2) result.append(c.asInstanceOf[Char])
249.318 - } while (c >= 0 && c != 2)
249.319 -
249.320 - if (result.length > 0) {
249.321 - put_result(Kind.SYSTEM, Nil, "Malformed message:\n" + result.toString)
249.322 - result.length = 0
249.323 - }
249.324 - if (c < 0) {
249.325 - reader.close
249.326 - finished = true
249.327 - try_close()
249.328 - }
249.329 - else {
249.330 - c = reader.read
249.331 - if (Kind.code.isDefinedAt(c)) kind = Kind.code(c)
249.332 - else kind = null
249.333 - }
249.334 - //}}}
249.335 - }
249.336 - else {
249.337 - //{{{ Line mode
249.338 - val line = reader.readLine
249.339 - if (line == null) {
249.340 - reader.close
249.341 - finished = true
249.342 - try_close()
249.343 - }
249.344 - else {
249.345 - val len = line.length
249.346 - // property
249.347 - if (line.endsWith("\u0002,")) {
249.348 - val i = line.indexOf('=')
249.349 - if (i > 0) {
249.350 - val name = line.substring(0, i)
249.351 - val value = line.substring(i + 1, len - 2)
249.352 - props = (name, value) :: props
249.353 - }
249.354 - }
249.355 - // last text line
249.356 - else if (line.endsWith("\u0002.")) {
249.357 - result.append(line.substring(0, len - 2))
249.358 - put_result(kind, props.reverse, result.toString)
249.359 - kind = null
249.360 - props = Nil
249.361 - result.length = 0
249.362 - }
249.363 - // text line
249.364 - else {
249.365 - result.append(line)
249.366 - result.append('\n')
249.367 - }
249.368 - }
249.369 - //}}}
249.370 - }
249.371 - }
249.372 - catch {
249.373 - case e: IOException => put_result(Kind.SYSTEM, Nil, "Message thread: " + e.getMessage)
249.374 - }
249.375 - }
249.376 - put_result(Kind.SYSTEM, Nil, "Message thread terminated")
249.377 - }
249.378 - }
249.379 -
249.380 -
249.381 -
249.382 - /** main **/
249.383 -
249.384 - {
249.385 - /* isabelle version */
249.386 -
249.387 - {
249.388 - val (msg, rc) = isabelle_system.isabelle_tool("version")
249.389 - if (rc != 0) error("Version check failed -- bad Isabelle installation:\n" + msg)
249.390 - put_result(Kind.SYSTEM, Nil, msg)
249.391 - }
249.392 -
249.393 -
249.394 - /* messages */
249.395 -
249.396 - val message_fifo = isabelle_system.mk_fifo()
249.397 - def rm_fifo() = isabelle_system.rm_fifo(message_fifo)
249.398 -
249.399 - val message_thread = new MessageThread(message_fifo)
249.400 - message_thread.start
249.401 -
249.402 - new ResultThread().start
249.403 -
249.404 -
249.405 - /* exec process */
249.406 -
249.407 - try {
249.408 - val cmdline =
249.409 - List(isabelle_system.getenv_strict("ISABELLE_PROCESS"), "-W", message_fifo) ++ args
249.410 - proc = isabelle_system.execute(true, cmdline: _*)
249.411 - }
249.412 - catch {
249.413 - case e: IOException =>
249.414 - rm_fifo()
249.415 - error("Failed to execute Isabelle process: " + e.getMessage)
249.416 - }
249.417 -
249.418 -
249.419 - /* stdin/stdout */
249.420 -
249.421 - new StdinThread(proc.getOutputStream).start
249.422 - new StdoutThread(proc.getInputStream).start
249.423 -
249.424 -
249.425 - /* exit */
249.426 -
249.427 - new Thread("isabelle: exit") {
249.428 - override def run() = {
249.429 - val rc = proc.waitFor()
249.430 - Thread.sleep(300)
249.431 - put_result(Kind.SYSTEM, Nil, "Exit thread terminated")
249.432 - put_result(Kind.EXIT, Nil, Integer.toString(rc))
249.433 - rm_fifo()
249.434 - }
249.435 - }.start
249.436 -
249.437 - }
249.438 -}
250.1 --- a/src/Pure/Tools/isabelle_system.scala Wed Mar 04 11:05:02 2009 +0100
250.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
250.3 @@ -1,158 +0,0 @@
250.4 -/* Title: Pure/Tools/isabelle_system.scala
250.5 - Author: Makarius
250.6 -
250.7 -Isabelle system support -- basic Cygwin/Posix compatibility.
250.8 -*/
250.9 -
250.10 -package isabelle
250.11 -
250.12 -import java.util.regex.{Pattern, Matcher}
250.13 -import java.io.{BufferedReader, InputStreamReader, FileInputStream, File, IOException}
250.14 -
250.15 -import scala.io.Source
250.16 -
250.17 -
250.18 -class IsabelleSystem {
250.19 -
250.20 - val charset = "UTF-8"
250.21 -
250.22 -
250.23 - /* Isabelle environment settings */
250.24 -
250.25 - private val environment = System.getenv
250.26 -
250.27 - def getenv(name: String) = {
250.28 - val value = environment.get(if (name == "HOME") "HOME_JVM" else name)
250.29 - if (value != null) value else ""
250.30 - }
250.31 -
250.32 - def getenv_strict(name: String) = {
250.33 - val value = environment.get(name)
250.34 - if (value != "") value else error("Undefined environment variable: " + name)
250.35 - }
250.36 -
250.37 - val is_cygwin = Pattern.matches(".*-cygwin", getenv_strict("ML_PLATFORM"))
250.38 -
250.39 -
250.40 - /* file path specifications */
250.41 -
250.42 - private val cygdrive_pattern = Pattern.compile("/cygdrive/([a-zA-Z])($|/.*)")
250.43 -
250.44 - def platform_path(source_path: String) = {
250.45 - val result_path = new StringBuilder
250.46 -
250.47 - def init(path: String) = {
250.48 - val cygdrive = cygdrive_pattern.matcher(path)
250.49 - if (cygdrive.matches) {
250.50 - result_path.length = 0
250.51 - result_path.append(cygdrive.group(1))
250.52 - result_path.append(":")
250.53 - result_path.append(File.separator)
250.54 - cygdrive.group(2)
250.55 - }
250.56 - else if (path.startsWith("/")) {
250.57 - result_path.length = 0
250.58 - result_path.append(getenv_strict("ISABELLE_ROOT_JVM"))
250.59 - path.substring(1)
250.60 - }
250.61 - else path
250.62 - }
250.63 - def append(path: String) = {
250.64 - for (p <- init(path).split("/")) {
250.65 - if (p != "") {
250.66 - val len = result_path.length
250.67 - if (len > 0 && result_path(len - 1) != File.separatorChar)
250.68 - result_path.append(File.separator)
250.69 - result_path.append(p)
250.70 - }
250.71 - }
250.72 - }
250.73 - for (p <- init(source_path).split("/")) {
250.74 - if (p.startsWith("$")) append(getenv_strict(p.substring(1)))
250.75 - else if (p == "~") append(getenv_strict("HOME"))
250.76 - else if (p == "~~") append(getenv_strict("ISABELLE_HOME"))
250.77 - else append(p)
250.78 - }
250.79 - result_path.toString
250.80 - }
250.81 -
250.82 - def platform_file(path: String) =
250.83 - new File(platform_path(path))
250.84 -
250.85 -
250.86 - /* processes */
250.87 -
250.88 - def execute(redirect: Boolean, args: String*): Process = {
250.89 - val cmdline = new java.util.LinkedList[String]
250.90 - if (is_cygwin) cmdline.add(platform_path("/bin/env"))
250.91 - for (s <- args) cmdline.add(s)
250.92 -
250.93 - val proc = new ProcessBuilder(cmdline)
250.94 - proc.environment.clear
250.95 - proc.environment.putAll(environment)
250.96 - proc.redirectErrorStream(redirect)
250.97 - proc.start
250.98 - }
250.99 -
250.100 -
250.101 - /* Isabelle tools (non-interactive) */
250.102 -
250.103 - def isabelle_tool(args: String*) = {
250.104 - val proc =
250.105 - try { execute(true, (List(getenv_strict("ISABELLE_TOOL")) ++ args): _*) }
250.106 - catch { case e: IOException => error(e.getMessage) }
250.107 - proc.getOutputStream.close
250.108 - val output = Source.fromInputStream(proc.getInputStream, charset).mkString
250.109 - val rc = proc.waitFor
250.110 - (output, rc)
250.111 - }
250.112 -
250.113 -
250.114 - /* named pipes */
250.115 -
250.116 - def mk_fifo() = {
250.117 - val (result, rc) = isabelle_tool("mkfifo")
250.118 - if (rc == 0) result.trim
250.119 - else error(result)
250.120 - }
250.121 -
250.122 - def rm_fifo(fifo: String) = {
250.123 - val (result, rc) = isabelle_tool("rmfifo", fifo)
250.124 - if (rc != 0) error(result)
250.125 - }
250.126 -
250.127 - def fifo_reader(fifo: String) = {
250.128 - // blocks until writer is ready
250.129 - val stream =
250.130 - if (is_cygwin) execute(false, "cat", fifo).getInputStream
250.131 - else new FileInputStream(fifo)
250.132 - new BufferedReader(new InputStreamReader(stream, charset))
250.133 - }
250.134 -
250.135 -
250.136 - /* find logics */
250.137 -
250.138 - def find_logics() = {
250.139 - val ml_ident = getenv_strict("ML_IDENTIFIER")
250.140 - var logics: Set[String] = Set()
250.141 - for (dir <- getenv_strict("ISABELLE_PATH").split(":")) {
250.142 - val files = platform_file(dir + "/" + ml_ident).listFiles()
250.143 - if (files != null) {
250.144 - for (file <- files if file.isFile) logics += file.getName
250.145 - }
250.146 - }
250.147 - logics.toList.sort(_ < _)
250.148 - }
250.149 -
250.150 -
250.151 - /* symbols */
250.152 -
250.153 - private def read_symbols(path: String) = {
250.154 - val file = new File(platform_path(path))
250.155 - if (file.canRead) Source.fromFile(file).getLines
250.156 - else Iterator.empty
250.157 - }
250.158 - val symbols = new Symbol.Interpretation(
250.159 - read_symbols("$ISABELLE_HOME/etc/symbols") ++
250.160 - read_symbols("$ISABELLE_HOME_USER/etc/symbols"))
250.161 -}
251.1 --- a/src/Tools/code/code_funcgr_new.ML Wed Mar 04 11:05:02 2009 +0100
251.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
251.3 @@ -1,414 +0,0 @@
251.4 -(* Title: Tools/code/code_funcgr.ML
251.5 - ID: $Id$
251.6 - Author: Florian Haftmann, TU Muenchen
251.7 -
251.8 -Retrieving, well-sorting and structuring defining equations in graph
251.9 -with explicit dependencies.
251.10 -*)
251.11 -
251.12 -signature CODE_FUNCGR =
251.13 -sig
251.14 - type T
251.15 - val eqns: T -> string -> (thm * bool) list
251.16 - val typ: T -> string -> (string * sort) list * typ
251.17 - val all: T -> string list
251.18 - val pretty: theory -> T -> Pretty.T
251.19 - val make: theory -> string list
251.20 - -> ((sort -> sort) * Sorts.algebra) * T
251.21 - val eval_conv: theory
251.22 - -> (term -> term * (((sort -> sort) * Sorts.algebra) -> T -> thm)) -> cterm -> thm
251.23 - val eval_term: theory
251.24 - -> (term -> term * (((sort -> sort) * Sorts.algebra) -> T -> 'a)) -> term -> 'a
251.25 -end
251.26 -
251.27 -structure Code_Funcgr : CODE_FUNCGR =
251.28 -struct
251.29 -
251.30 -(** the graph type **)
251.31 -
251.32 -type T = (((string * sort) list * typ) * (thm * bool) list) Graph.T;
251.33 -
251.34 -fun eqns funcgr =
251.35 - these o Option.map snd o try (Graph.get_node funcgr);
251.36 -
251.37 -fun typ funcgr =
251.38 - fst o Graph.get_node funcgr;
251.39 -
251.40 -fun all funcgr = Graph.keys funcgr;
251.41 -
251.42 -fun pretty thy funcgr =
251.43 - AList.make (snd o Graph.get_node funcgr) (Graph.keys funcgr)
251.44 - |> (map o apfst) (Code_Unit.string_of_const thy)
251.45 - |> sort (string_ord o pairself fst)
251.46 - |> map (fn (s, thms) =>
251.47 - (Pretty.block o Pretty.fbreaks) (
251.48 - Pretty.str s
251.49 - :: map (Display.pretty_thm o fst) thms
251.50 - ))
251.51 - |> Pretty.chunks;
251.52 -
251.53 -
251.54 -(** generic combinators **)
251.55 -
251.56 -fun fold_consts f thms =
251.57 - thms
251.58 - |> maps (op :: o swap o apfst (snd o strip_comb) o Logic.dest_equals o Thm.plain_prop_of)
251.59 - |> (fold o fold_aterms) (fn Const c => f c | _ => I);
251.60 -
251.61 -fun consts_of (const, []) = []
251.62 - | consts_of (const, thms as _ :: _) =
251.63 - let
251.64 - fun the_const (c, _) = if c = const then I else insert (op =) c
251.65 - in fold_consts the_const (map fst thms) [] end;
251.66 -
251.67 -
251.68 -(** graph algorithm **)
251.69 -
251.70 -(* some nonsense -- FIXME *)
251.71 -
251.72 -fun lhs_rhss_of thy c =
251.73 - let
251.74 - val eqns = Code.these_eqns thy c
251.75 - |> burrow_fst (Code_Unit.norm_args thy)
251.76 - |> burrow_fst (Code_Unit.norm_varnames thy Code_Name.purify_tvar Code_Name.purify_var);
251.77 - val (lhs, _) = case eqns of [] => Code.default_typscheme thy c
251.78 - | ((thm, _) :: _) => (snd o Code_Unit.head_eqn thy) thm;
251.79 - val rhss = fold_consts (fn (c, ty) =>
251.80 - insert (op =) (c, Sign.const_typargs thy (c, Logic.unvarifyT ty))) (map fst eqns) [];
251.81 - in (lhs, rhss) end;
251.82 -
251.83 -fun inst_params thy tyco class =
251.84 - map (fn (c, _) => AxClass.param_of_inst thy (c, tyco))
251.85 - ((#params o AxClass.get_info thy) class);
251.86 -
251.87 -fun complete_proper_sort thy sort =
251.88 - Sign.complete_sort thy sort |> filter (can (AxClass.get_info thy));
251.89 -
251.90 -fun minimal_proper_sort thy sort =
251.91 - complete_proper_sort thy sort |> Sign.minimize_sort thy;
251.92 -
251.93 -fun dicts_of thy algebra (T, sort) =
251.94 - let
251.95 - fun class_relation (x, _) _ = x;
251.96 - fun type_constructor tyco xs class =
251.97 - inst_params thy tyco class @ (maps o maps) fst xs;
251.98 - fun type_variable (TFree (_, sort)) = map (pair []) sort;
251.99 - in
251.100 - flat (Sorts.of_sort_derivation (Syntax.pp_global thy) algebra
251.101 - { class_relation = class_relation, type_constructor = type_constructor,
251.102 - type_variable = type_variable } (T, minimal_proper_sort thy sort)
251.103 - handle Sorts.CLASS_ERROR _ => [] (*permissive!*))
251.104 - end;
251.105 -
251.106 -
251.107 -(* data structures *)
251.108 -
251.109 -datatype const = Fun of string | Inst of class * string;
251.110 -
251.111 -fun const_ord (Fun c1, Fun c2) = fast_string_ord (c1, c2)
251.112 - | const_ord (Inst class_tyco1, Inst class_tyco2) =
251.113 - prod_ord fast_string_ord fast_string_ord (class_tyco1, class_tyco2)
251.114 - | const_ord (Fun _, Inst _) = LESS
251.115 - | const_ord (Inst _, Fun _) = GREATER;
251.116 -
251.117 -type var = const * int;
251.118 -
251.119 -structure Vargraph =
251.120 - GraphFun(type key = var val ord = prod_ord const_ord int_ord);
251.121 -
251.122 -datatype styp = Tyco of string * styp list | Var of var;
251.123 -
251.124 -type vardeps = const list * ((string * styp list) list * class list) Vargraph.T;
251.125 -
251.126 -
251.127 -(* computing instantiations -- FIXME does not consider existing things *)
251.128 -
251.129 -fun add_classes thy c_k new_classes vardeps =
251.130 - let
251.131 - val _ = tracing "add_classes";
251.132 - val (styps, old_classes) = Vargraph.get_node (snd vardeps) c_k;
251.133 - val diff_classes = new_classes |> subtract (op =) old_classes;
251.134 - in if null diff_classes then vardeps
251.135 - else let
251.136 - val c_ks = Vargraph.imm_succs (snd vardeps) c_k |> insert (op =) c_k;
251.137 - in
251.138 - vardeps
251.139 - |> (apsnd o Vargraph.map_node c_k o apsnd) (append diff_classes)
251.140 - |> fold (fn styp => fold (add_typmatch_inst thy styp) new_classes) styps
251.141 - |> fold (fn c_k => add_classes thy c_k diff_classes) c_ks
251.142 - end end
251.143 -and add_styp thy c_k tyco_styps vardeps =
251.144 - let
251.145 - val _ = tracing "add_styp";
251.146 - val (old_styps, classes) = Vargraph.get_node (snd vardeps) c_k;
251.147 - in if member (op =) old_styps tyco_styps then vardeps
251.148 - else
251.149 - vardeps
251.150 - |> (apsnd o Vargraph.map_node c_k o apfst) (cons tyco_styps)
251.151 - |> fold (add_typmatch_inst thy tyco_styps) classes
251.152 - end
251.153 -and add_dep thy c_k c_k' vardeps =
251.154 - let
251.155 - val _ = tracing ("add_dep " ^ makestring c_k ^ " -> " ^ makestring c_k');
251.156 - val (_, classes) = Vargraph.get_node (snd vardeps) c_k;
251.157 - in
251.158 - vardeps
251.159 - |> add_classes thy c_k' classes
251.160 - |> apsnd (Vargraph.add_edge (c_k, c_k'))
251.161 - end
251.162 -and add_typmatch_inst thy (tyco, styps) class vardeps = if can (Sign.arity_sorts thy tyco) [class]
251.163 - then vardeps
251.164 - |> tap (fn _ => tracing "add_typmatch_inst")
251.165 - |> assert thy (Inst (class, tyco))
251.166 - |> fold_index (fn (k, styp) =>
251.167 - add_typmatch thy styp (Inst (class, tyco), k)) styps
251.168 - else vardeps (*permissive!*)
251.169 -and add_typmatch thy (Var c_k') c_k vardeps =
251.170 - vardeps
251.171 - |> tap (fn _ => tracing "add_typmatch (Inst)")
251.172 - |> add_dep thy c_k c_k'
251.173 - | add_typmatch thy (Tyco tyco_styps) c_k vardeps =
251.174 - vardeps
251.175 - |> tap (fn _ => tracing "add_typmatch (Tyco)")
251.176 - |> add_styp thy c_k tyco_styps
251.177 -and add_inst thy (class, tyco) vardeps =
251.178 - let
251.179 - val _ = tracing ("add_inst " ^ tyco ^ "::" ^ class);
251.180 - val superclasses = complete_proper_sort thy
251.181 - (Sign.super_classes thy class);
251.182 - val classess = map (complete_proper_sort thy)
251.183 - (Sign.arity_sorts thy tyco [class]);
251.184 - val inst_params = inst_params thy tyco class;
251.185 - in
251.186 - vardeps
251.187 - |> fold (fn superclass => assert thy (Inst (superclass, tyco))) superclasses
251.188 - |> fold (assert thy o Fun) inst_params
251.189 - |> fold_index (fn (k, classes) =>
251.190 - apsnd (Vargraph.default_node ((Inst (class, tyco), k), ([] ,[])))
251.191 - #> add_classes thy (Inst (class, tyco), k) classes
251.192 - #> fold (fn superclass =>
251.193 - add_dep thy (Inst (superclass, tyco), k)
251.194 - (Inst (class, tyco), k)) superclasses
251.195 - #> fold (fn inst_param =>
251.196 - add_dep thy (Fun inst_param, k)
251.197 - (Inst (class, tyco), k)
251.198 - ) inst_params
251.199 - ) classess
251.200 - end
251.201 -and add_const thy c vardeps =
251.202 - let
251.203 - val _ = tracing "add_const";
251.204 - val (lhs, rhss) = lhs_rhss_of thy c;
251.205 - fun styp_of (Type (tyco, tys)) = Tyco (tyco, map styp_of tys)
251.206 - | styp_of (TFree (v, _)) = Var (Fun c, find_index (fn (v', _) => v = v') lhs);
251.207 - val rhss' = (map o apsnd o map) styp_of rhss;
251.208 - in
251.209 - vardeps
251.210 - |> fold_index (fn (k, (_, sort)) =>
251.211 - apsnd (Vargraph.default_node ((Fun c, k), ([] ,[])))
251.212 - #> add_classes thy (Fun c, k) (complete_proper_sort thy sort)) lhs
251.213 - |> fold (assert thy o Fun o fst) rhss'
251.214 - |> fold (fn (c', styps) => fold_index (fn (k', styp) =>
251.215 - add_typmatch thy styp (Fun c', k')) styps) rhss'
251.216 - end
251.217 -and assert thy c (vardeps as (asserted, _)) =
251.218 - if member (op =) asserted c then vardeps
251.219 - else case c
251.220 - of Fun const => vardeps |> apfst (cons c) |> add_const thy const
251.221 - | Inst inst => vardeps |> apfst (cons c) |> add_inst thy inst;
251.222 -
251.223 -
251.224 -(* applying instantiations *)
251.225 -
251.226 -fun algebra_of thy vardeps =
251.227 - let
251.228 - val pp = Syntax.pp_global thy;
251.229 - val thy_algebra = Sign.classes_of thy;
251.230 - val is_proper = can (AxClass.get_info thy);
251.231 - val arities = Vargraph.fold (fn ((Fun _, _), _) => I
251.232 - | ((Inst (class, tyco), k), ((_, classes), _)) =>
251.233 - AList.map_default (op =)
251.234 - ((tyco, class), replicate (Sign.arity_number thy tyco) [])
251.235 - (nth_map k (K classes))) vardeps [];
251.236 - val classrels = Sorts.classrels_of thy_algebra
251.237 - |> filter (is_proper o fst)
251.238 - |> (map o apsnd) (filter is_proper);
251.239 - fun add_arity (tyco, class) = case AList.lookup (op =) arities (tyco, class)
251.240 - of SOME sorts => Sorts.add_arities pp (tyco, [(class, sorts)])
251.241 - | NONE => if Sign.arity_number thy tyco = 0
251.242 - then (tracing (tyco ^ "::" ^ class); Sorts.add_arities pp (tyco, [(class, [])]))
251.243 - else I;
251.244 - val instances = Sorts.instances_of thy_algebra
251.245 - |> filter (is_proper o snd)
251.246 - in
251.247 - Sorts.empty_algebra
251.248 - |> fold (Sorts.add_class pp) classrels
251.249 - |> fold add_arity instances
251.250 - end;
251.251 -
251.252 -fun add_eqs thy algebra vardeps c gr =
251.253 - let
251.254 - val eqns = Code.these_eqns thy c
251.255 - |> burrow_fst (Code_Unit.norm_args thy)
251.256 - |> burrow_fst (Code_Unit.norm_varnames thy Code_Name.purify_tvar Code_Name.purify_var);
251.257 - val (vs, _) = case eqns of [] => Code.default_typscheme thy c
251.258 - | ((thm, _) :: _) => (snd o Code_Unit.head_eqn thy) thm;
251.259 - val inst = Vartab.empty |> fold_index (fn (k, (v, _)) =>
251.260 - Vartab.update ((v, 0), snd (Vargraph.get_node vardeps (Fun c, k)))) vs;
251.261 - val eqns' = eqns
251.262 - |> (map o apfst) (Code_Unit.inst_thm thy inst);
251.263 - val tyscm = case eqns' of [] => Code.default_typscheme thy c
251.264 - | ((thm, _) :: _) => (snd o Code_Unit.head_eqn thy) thm;
251.265 - val _ = tracing ("tyscm " ^ makestring (map snd (fst tyscm)));
251.266 - val rhss = fold_consts (fn (c, ty) =>
251.267 - insert (op =) (c, Sign.const_typargs thy (c, Logic.unvarifyT ty))) (map fst eqns') [];
251.268 - in
251.269 - gr
251.270 - |> Graph.new_node (c, (tyscm, eqns'))
251.271 - |> fold (fn (c', Ts) => ensure_eqs_dep thy algebra vardeps c c'
251.272 - #-> (fn (vs, _) =>
251.273 - fold2 (ensure_match thy algebra vardeps c) Ts (map snd vs))) rhss
251.274 - |> pair tyscm
251.275 - end
251.276 -and ensure_match thy algebra vardeps c T sort gr =
251.277 - gr
251.278 - |> fold (fn c' => ensure_eqs_dep thy algebra vardeps c c' #> snd)
251.279 - (dicts_of thy algebra (T, sort))
251.280 -and ensure_eqs_dep thy algebra vardeps c c' gr =
251.281 - gr
251.282 - |> ensure_eqs thy algebra vardeps c'
251.283 - ||> Graph.add_edge (c, c')
251.284 -and ensure_eqs thy algebra vardeps c gr =
251.285 - case try (Graph.get_node gr) c
251.286 - of SOME (tyscm, _) => (tyscm, gr)
251.287 - | NONE => add_eqs thy algebra vardeps c gr;
251.288 -
251.289 -fun extend_graph thy cs gr =
251.290 - let
251.291 - val _ = tracing ("extending with " ^ commas cs);
251.292 - val _ = tracing "obtaining instantiations";
251.293 - val (_, vardeps) = fold (assert thy o Fun) cs ([], Vargraph.empty)
251.294 - val _ = tracing "obtaining algebra";
251.295 - val algebra = algebra_of thy vardeps;
251.296 - val _ = tracing "obtaining equations";
251.297 - val (_, gr) = fold_map (ensure_eqs thy algebra vardeps) cs gr;
251.298 - val _ = tracing "sort projection";
251.299 - val minimal_proper_sort = fn sort => sort
251.300 - |> Sorts.complete_sort (Sign.classes_of thy)
251.301 - |> filter (can (AxClass.get_info thy))
251.302 - |> Sorts.minimize_sort algebra;
251.303 - in ((minimal_proper_sort, algebra), gr) end;
251.304 -
251.305 -
251.306 -(** retrieval interfaces **)
251.307 -
251.308 -fun proto_eval thy cterm_of evaluator_lift evaluator proto_ct funcgr =
251.309 - let
251.310 - val ct = cterm_of proto_ct;
251.311 - val _ = Sign.no_vars (Syntax.pp_global thy) (Thm.term_of ct);
251.312 - val _ = Term.fold_types (Type.no_tvars #> K I) (Thm.term_of ct) ();
251.313 - fun consts_of t =
251.314 - fold_aterms (fn Const c_ty => cons c_ty | _ => I) t [];
251.315 - val thm = Code.preprocess_conv thy ct;
251.316 - val ct' = Thm.rhs_of thm;
251.317 - val t' = Thm.term_of ct';
251.318 - val consts = map fst (consts_of t');
251.319 - val (algebra', funcgr') = extend_graph thy consts funcgr;
251.320 - val (t'', evaluator_funcgr) = evaluator t';
251.321 - val consts' = consts_of t'';
251.322 - val const_matches = fold (fn (c, ty) =>
251.323 - insert (op =) (Sign.const_typargs thy (c, Logic.unvarifyT ty), c)) consts' [];
251.324 - val typ_matches = maps (fn (tys, c) => tys ~~ map snd (fst (fst (Graph.get_node funcgr' c))))
251.325 - const_matches;
251.326 - val dicts = maps (dicts_of thy (snd algebra')) typ_matches;
251.327 - val (algebra'', funcgr'') = extend_graph thy dicts funcgr';
251.328 - in (evaluator_lift (evaluator_funcgr algebra'') thm funcgr'', funcgr'') end;
251.329 -
251.330 -fun proto_eval_conv thy =
251.331 - let
251.332 - fun evaluator_lift evaluator thm1 funcgr =
251.333 - let
251.334 - val thm2 = evaluator funcgr;
251.335 - val thm3 = Code.postprocess_conv thy (Thm.rhs_of thm2);
251.336 - in
251.337 - Thm.transitive thm1 (Thm.transitive thm2 thm3) handle THM _ =>
251.338 - error ("could not construct evaluation proof:\n"
251.339 - ^ (cat_lines o map Display.string_of_thm) [thm1, thm2, thm3])
251.340 - end;
251.341 - in proto_eval thy I evaluator_lift end;
251.342 -
251.343 -fun proto_eval_term thy =
251.344 - let
251.345 - fun evaluator_lift evaluator _ funcgr = evaluator funcgr;
251.346 - in proto_eval thy (Thm.cterm_of thy) evaluator_lift end;
251.347 -
251.348 -structure Funcgr = CodeDataFun
251.349 -(
251.350 - type T = T;
251.351 - val empty = Graph.empty;
251.352 - fun purge _ cs funcgr =
251.353 - Graph.del_nodes ((Graph.all_preds funcgr
251.354 - o filter (can (Graph.get_node funcgr))) cs) funcgr;
251.355 -);
251.356 -
251.357 -fun make thy = Funcgr.change_yield thy o extend_graph thy;
251.358 -
251.359 -fun eval_conv thy f =
251.360 - fst o Funcgr.change_yield thy o proto_eval_conv thy f;
251.361 -
251.362 -fun eval_term thy f =
251.363 - fst o Funcgr.change_yield thy o proto_eval_term thy f;
251.364 -
251.365 -
251.366 -(** diagnostic commands **)
251.367 -
251.368 -fun code_depgr thy consts =
251.369 - let
251.370 - val (_, gr) = make thy consts;
251.371 - val select = Graph.all_succs gr consts;
251.372 - in
251.373 - gr
251.374 - |> not (null consts) ? Graph.subgraph (member (op =) select)
251.375 - |> Graph.map_nodes ((apsnd o map o apfst) (AxClass.overload thy))
251.376 - end;
251.377 -
251.378 -fun code_thms thy = Pretty.writeln o pretty thy o code_depgr thy;
251.379 -
251.380 -fun code_deps thy consts =
251.381 - let
251.382 - val gr = code_depgr thy consts;
251.383 - fun mk_entry (const, (_, (_, parents))) =
251.384 - let
251.385 - val name = Code_Unit.string_of_const thy const;
251.386 - val nameparents = map (Code_Unit.string_of_const thy) parents;
251.387 - in { name = name, ID = name, dir = "", unfold = true,
251.388 - path = "", parents = nameparents }
251.389 - end;
251.390 - val prgr = Graph.fold ((fn x => fn xs => xs @ [x]) o mk_entry) gr [];
251.391 - in Present.display_graph prgr end;
251.392 -
251.393 -local
251.394 -
251.395 -structure P = OuterParse
251.396 -and K = OuterKeyword
251.397 -
251.398 -fun code_thms_cmd thy = code_thms thy o op @ o Code_Name.read_const_exprs thy;
251.399 -fun code_deps_cmd thy = code_deps thy o op @ o Code_Name.read_const_exprs thy;
251.400 -
251.401 -in
251.402 -
251.403 -val _ =
251.404 - OuterSyntax.improper_command "code_thms" "print system of defining equations for code" OuterKeyword.diag
251.405 - (Scan.repeat P.term_group
251.406 - >> (fn cs => Toplevel.no_timing o Toplevel.unknown_theory
251.407 - o Toplevel.keep ((fn thy => code_thms_cmd thy cs) o Toplevel.theory_of)));
251.408 -
251.409 -val _ =
251.410 - OuterSyntax.improper_command "code_deps" "visualize dependencies of defining equations for code" OuterKeyword.diag
251.411 - (Scan.repeat P.term_group
251.412 - >> (fn cs => Toplevel.no_timing o Toplevel.unknown_theory
251.413 - o Toplevel.keep ((fn thy => code_deps_cmd thy cs) o Toplevel.theory_of)));
251.414 -
251.415 -end;
251.416 -
251.417 -end; (*struct*)
252.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
252.2 +++ b/src/Tools/code/code_wellsorted.ML Wed Mar 04 11:05:29 2009 +0100
252.3 @@ -0,0 +1,390 @@
252.4 +(* Title: Tools/code/code_wellsorted.ML
252.5 + Author: Florian Haftmann, TU Muenchen
252.6 +
252.7 +Producing well-sorted systems of code equations in a graph
252.8 +with explicit dependencies -- the Waisenhaus algorithm.
252.9 +*)
252.10 +
252.11 +signature CODE_WELLSORTED =
252.12 +sig
252.13 + type T
252.14 + val eqns: T -> string -> (thm * bool) list
252.15 + val typ: T -> string -> (string * sort) list * typ
252.16 + val all: T -> string list
252.17 + val pretty: theory -> T -> Pretty.T
252.18 + val make: theory -> string list
252.19 + -> ((sort -> sort) * Sorts.algebra) * T
252.20 + val eval_conv: theory
252.21 + -> (term -> term * (((sort -> sort) * Sorts.algebra) -> T -> thm)) -> cterm -> thm
252.22 + val eval_term: theory
252.23 + -> (term -> term * (((sort -> sort) * Sorts.algebra) -> T -> 'a)) -> term -> 'a
252.24 +end
252.25 +
252.26 +structure Code_Wellsorted : CODE_WELLSORTED =
252.27 +struct
252.28 +
252.29 +(** the equation graph type **)
252.30 +
252.31 +type T = (((string * sort) list * typ) * (thm * bool) list) Graph.T;
252.32 +
252.33 +fun eqns eqngr = these o Option.map snd o try (Graph.get_node eqngr);
252.34 +fun typ eqngr = fst o Graph.get_node eqngr;
252.35 +fun all eqngr = Graph.keys eqngr;
252.36 +
252.37 +fun pretty thy eqngr =
252.38 + AList.make (snd o Graph.get_node eqngr) (Graph.keys eqngr)
252.39 + |> (map o apfst) (Code_Unit.string_of_const thy)
252.40 + |> sort (string_ord o pairself fst)
252.41 + |> map (fn (s, thms) =>
252.42 + (Pretty.block o Pretty.fbreaks) (
252.43 + Pretty.str s
252.44 + :: map (Display.pretty_thm o fst) thms
252.45 + ))
252.46 + |> Pretty.chunks;
252.47 +
252.48 +
252.49 +(** the Waisenhaus algorithm **)
252.50 +
252.51 +(* auxiliary *)
252.52 +
252.53 +fun complete_proper_sort thy =
252.54 + Sign.complete_sort thy #> filter (can (AxClass.get_info thy));
252.55 +
252.56 +fun inst_params thy tyco =
252.57 + map (fn (c, _) => AxClass.param_of_inst thy (c, tyco))
252.58 + o maps (#params o AxClass.get_info thy);
252.59 +
252.60 +fun consts_of thy eqns = [] |> (fold o fold o fold_aterms)
252.61 + (fn Const (c, ty) => insert (op =) (c, Sign.const_typargs thy (c, Logic.unvarifyT ty)) | _ => I)
252.62 + (map (op :: o swap o apfst (snd o strip_comb) o Logic.dest_equals o Thm.plain_prop_of o fst) eqns);
252.63 +
252.64 +fun tyscm_rhss_of thy c eqns =
252.65 + let
252.66 + val tyscm = case eqns of [] => Code.default_typscheme thy c
252.67 + | ((thm, _) :: _) => (snd o Code_Unit.head_eqn thy) thm;
252.68 + val rhss = consts_of thy eqns;
252.69 + in (tyscm, rhss) end;
252.70 +
252.71 +
252.72 +(* data structures *)
252.73 +
252.74 +datatype const = Fun of string | Inst of class * string;
252.75 +
252.76 +fun const_ord (Fun c1, Fun c2) = fast_string_ord (c1, c2)
252.77 + | const_ord (Inst class_tyco1, Inst class_tyco2) =
252.78 + prod_ord fast_string_ord fast_string_ord (class_tyco1, class_tyco2)
252.79 + | const_ord (Fun _, Inst _) = LESS
252.80 + | const_ord (Inst _, Fun _) = GREATER;
252.81 +
252.82 +type var = const * int;
252.83 +
252.84 +structure Vargraph =
252.85 + GraphFun(type key = var val ord = prod_ord const_ord int_ord);
252.86 +
252.87 +datatype styp = Tyco of string * styp list | Var of var | Free;
252.88 +
252.89 +fun styp_of c_lhs (Type (tyco, tys)) = Tyco (tyco, map (styp_of c_lhs) tys)
252.90 + | styp_of c_lhs (TFree (v, _)) = case c_lhs
252.91 + of SOME (c, lhs) => Var (Fun c, find_index (fn (v', _) => v = v') lhs)
252.92 + | NONE => Free;
252.93 +
252.94 +type vardeps_data = ((string * styp list) list * class list) Vargraph.T
252.95 + * (((string * sort) list * (thm * bool) list) Symtab.table
252.96 + * (class * string) list);
252.97 +
252.98 +val empty_vardeps_data : vardeps_data =
252.99 + (Vargraph.empty, (Symtab.empty, []));
252.100 +
252.101 +(* retrieving equations and instances from the background context *)
252.102 +
252.103 +fun obtain_eqns thy eqngr c =
252.104 + case try (Graph.get_node eqngr) c
252.105 + of SOME ((lhs, _), eqns) => ((lhs, []), [])
252.106 + | NONE => let
252.107 + val eqns = Code.these_eqns thy c
252.108 + |> burrow_fst (Code_Unit.norm_args thy)
252.109 + |> burrow_fst (Code_Unit.norm_varnames thy Code_Name.purify_tvar Code_Name.purify_var);
252.110 + val ((lhs, _), rhss) = tyscm_rhss_of thy c eqns;
252.111 + in ((lhs, rhss), eqns) end;
252.112 +
252.113 +fun obtain_instance thy arities (inst as (class, tyco)) =
252.114 + case AList.lookup (op =) arities inst
252.115 + of SOME classess => (classess, ([], []))
252.116 + | NONE => let
252.117 + val all_classes = complete_proper_sort thy [class];
252.118 + val superclasses = remove (op =) class all_classes
252.119 + val classess = map (complete_proper_sort thy)
252.120 + (Sign.arity_sorts thy tyco [class]);
252.121 + val inst_params = inst_params thy tyco all_classes;
252.122 + in (classess, (superclasses, inst_params)) end;
252.123 +
252.124 +
252.125 +(* computing instantiations *)
252.126 +
252.127 +fun add_classes thy arities eqngr c_k new_classes vardeps_data =
252.128 + let
252.129 + val (styps, old_classes) = Vargraph.get_node (fst vardeps_data) c_k;
252.130 + val diff_classes = new_classes |> subtract (op =) old_classes;
252.131 + in if null diff_classes then vardeps_data
252.132 + else let
252.133 + val c_ks = Vargraph.imm_succs (fst vardeps_data) c_k |> insert (op =) c_k;
252.134 + in
252.135 + vardeps_data
252.136 + |> (apfst o Vargraph.map_node c_k o apsnd) (append diff_classes)
252.137 + |> fold (fn styp => fold (assert_typmatch_inst thy arities eqngr styp) new_classes) styps
252.138 + |> fold (fn c_k => add_classes thy arities eqngr c_k diff_classes) c_ks
252.139 + end end
252.140 +and add_styp thy arities eqngr c_k tyco_styps vardeps_data =
252.141 + let
252.142 + val (old_styps, classes) = Vargraph.get_node (fst vardeps_data) c_k;
252.143 + in if member (op =) old_styps tyco_styps then vardeps_data
252.144 + else
252.145 + vardeps_data
252.146 + |> (apfst o Vargraph.map_node c_k o apfst) (cons tyco_styps)
252.147 + |> fold (assert_typmatch_inst thy arities eqngr tyco_styps) classes
252.148 + end
252.149 +and add_dep thy arities eqngr c_k c_k' vardeps_data =
252.150 + let
252.151 + val (_, classes) = Vargraph.get_node (fst vardeps_data) c_k;
252.152 + in
252.153 + vardeps_data
252.154 + |> add_classes thy arities eqngr c_k' classes
252.155 + |> apfst (Vargraph.add_edge (c_k, c_k'))
252.156 + end
252.157 +and assert_typmatch_inst thy arities eqngr (tyco, styps) class vardeps_data =
252.158 + if can (Sign.arity_sorts thy tyco) [class]
252.159 + then vardeps_data
252.160 + |> assert_inst thy arities eqngr (class, tyco)
252.161 + |> fold_index (fn (k, styp) =>
252.162 + assert_typmatch thy arities eqngr styp (Inst (class, tyco), k)) styps
252.163 + else vardeps_data (*permissive!*)
252.164 +and assert_inst thy arities eqngr (inst as (class, tyco)) (vardeps_data as (_, (_, insts))) =
252.165 + if member (op =) insts inst then vardeps_data
252.166 + else let
252.167 + val (classess, (superclasses, inst_params)) =
252.168 + obtain_instance thy arities inst;
252.169 + in
252.170 + vardeps_data
252.171 + |> (apsnd o apsnd) (insert (op =) inst)
252.172 + |> fold_index (fn (k, _) =>
252.173 + apfst (Vargraph.new_node ((Inst (class, tyco), k), ([] ,[])))) classess
252.174 + |> fold (fn superclass => assert_inst thy arities eqngr (superclass, tyco)) superclasses
252.175 + |> fold (assert_fun thy arities eqngr) inst_params
252.176 + |> fold_index (fn (k, classes) =>
252.177 + add_classes thy arities eqngr (Inst (class, tyco), k) classes
252.178 + #> fold (fn superclass =>
252.179 + add_dep thy arities eqngr (Inst (superclass, tyco), k)
252.180 + (Inst (class, tyco), k)) superclasses
252.181 + #> fold (fn inst_param =>
252.182 + add_dep thy arities eqngr (Fun inst_param, k)
252.183 + (Inst (class, tyco), k)
252.184 + ) inst_params
252.185 + ) classess
252.186 + end
252.187 +and assert_typmatch thy arities eqngr (Tyco tyco_styps) c_k vardeps_data =
252.188 + vardeps_data
252.189 + |> add_styp thy arities eqngr c_k tyco_styps
252.190 + | assert_typmatch thy arities eqngr (Var c_k') c_k vardeps_data =
252.191 + vardeps_data
252.192 + |> add_dep thy arities eqngr c_k c_k'
252.193 + | assert_typmatch thy arities eqngr Free c_k vardeps_data =
252.194 + vardeps_data
252.195 +and assert_rhs thy arities eqngr (c', styps) vardeps_data =
252.196 + vardeps_data
252.197 + |> assert_fun thy arities eqngr c'
252.198 + |> fold_index (fn (k, styp) =>
252.199 + assert_typmatch thy arities eqngr styp (Fun c', k)) styps
252.200 +and assert_fun thy arities eqngr c (vardeps_data as (_, (eqntab, _))) =
252.201 + if Symtab.defined eqntab c then vardeps_data
252.202 + else let
252.203 + val ((lhs, rhss), eqns) = obtain_eqns thy eqngr c;
252.204 + val rhss' = (map o apsnd o map) (styp_of (SOME (c, lhs))) rhss;
252.205 + in
252.206 + vardeps_data
252.207 + |> (apsnd o apfst) (Symtab.update_new (c, (lhs, eqns)))
252.208 + |> fold_index (fn (k, _) =>
252.209 + apfst (Vargraph.new_node ((Fun c, k), ([] ,[])))) lhs
252.210 + |> fold_index (fn (k, (_, sort)) =>
252.211 + add_classes thy arities eqngr (Fun c, k) (complete_proper_sort thy sort)) lhs
252.212 + |> fold (assert_rhs thy arities eqngr) rhss'
252.213 + end;
252.214 +
252.215 +
252.216 +(* applying instantiations *)
252.217 +
252.218 +fun dicts_of thy (proj_sort, algebra) (T, sort) =
252.219 + let
252.220 + fun class_relation (x, _) _ = x;
252.221 + fun type_constructor tyco xs class =
252.222 + inst_params thy tyco (Sorts.complete_sort algebra [class])
252.223 + @ (maps o maps) fst xs;
252.224 + fun type_variable (TFree (_, sort)) = map (pair []) (proj_sort sort);
252.225 + in
252.226 + flat (Sorts.of_sort_derivation (Syntax.pp_global thy) algebra
252.227 + { class_relation = class_relation, type_constructor = type_constructor,
252.228 + type_variable = type_variable } (T, proj_sort sort)
252.229 + handle Sorts.CLASS_ERROR _ => [] (*permissive!*))
252.230 + end;
252.231 +
252.232 +fun add_arity thy vardeps (class, tyco) =
252.233 + AList.default (op =)
252.234 + ((class, tyco), map (fn k => (snd o Vargraph.get_node vardeps) (Inst (class, tyco), k))
252.235 + (0 upto Sign.arity_number thy tyco - 1));
252.236 +
252.237 +fun add_eqs thy (proj_sort, algebra) vardeps
252.238 + (c, (proto_lhs, proto_eqns)) (rhss, eqngr) =
252.239 + if can (Graph.get_node eqngr) c then (rhss, eqngr)
252.240 + else let
252.241 + val lhs = map_index (fn (k, (v, _)) =>
252.242 + (v, snd (Vargraph.get_node vardeps (Fun c, k)))) proto_lhs;
252.243 + val inst_tab = Vartab.empty |> fold (fn (v, sort) =>
252.244 + Vartab.update ((v, 0), sort)) lhs;
252.245 + val eqns = proto_eqns
252.246 + |> (map o apfst) (Code_Unit.inst_thm thy inst_tab);
252.247 + val (tyscm, rhss') = tyscm_rhss_of thy c eqns;
252.248 + val eqngr' = Graph.new_node (c, (tyscm, eqns)) eqngr;
252.249 + in (map (pair c) rhss' @ rhss, eqngr') end;
252.250 +
252.251 +fun extend_arities_eqngr thy cs cs_rhss (arities, eqngr) =
252.252 + let
252.253 + val cs_rhss' = (map o apsnd o map) (styp_of NONE) cs_rhss;
252.254 + val (vardeps, (eqntab, insts)) = empty_vardeps_data
252.255 + |> fold (assert_fun thy arities eqngr) cs
252.256 + |> fold (assert_rhs thy arities eqngr) cs_rhss';
252.257 + val arities' = fold (add_arity thy vardeps) insts arities;
252.258 + val pp = Syntax.pp_global thy;
252.259 + val is_proper_class = can (AxClass.get_info thy);
252.260 + val (proj_sort, algebra) = Sorts.subalgebra pp is_proper_class
252.261 + (AList.lookup (op =) arities') (Sign.classes_of thy);
252.262 + val (rhss, eqngr') = Symtab.fold
252.263 + (add_eqs thy (proj_sort, algebra) vardeps) eqntab ([], eqngr);
252.264 + fun deps_of (c, rhs) = c ::
252.265 + maps (dicts_of thy (proj_sort, algebra))
252.266 + (rhs ~~ (map snd o fst o fst o Graph.get_node eqngr') c);
252.267 + val eqngr'' = fold (fn (c, rhs) => fold
252.268 + (curry Graph.add_edge c) (deps_of rhs)) rhss eqngr';
252.269 + in ((proj_sort, algebra), (arities', eqngr'')) end;
252.270 +
252.271 +
252.272 +(** retrieval interfaces **)
252.273 +
252.274 +fun proto_eval thy cterm_of evaluator_lift evaluator proto_ct arities_eqngr =
252.275 + let
252.276 + val ct = cterm_of proto_ct;
252.277 + val _ = Sign.no_vars (Syntax.pp_global thy) (Thm.term_of ct);
252.278 + val _ = Term.fold_types (Type.no_tvars #> K I) (Thm.term_of ct) ();
252.279 + fun consts_of t =
252.280 + fold_aterms (fn Const c_ty => cons c_ty | _ => I) t [];
252.281 + val thm = Code.preprocess_conv thy ct;
252.282 + val ct' = Thm.rhs_of thm;
252.283 + val t' = Thm.term_of ct';
252.284 + val (t'', evaluator_eqngr) = evaluator t';
252.285 + val consts = map fst (consts_of t');
252.286 + val consts' = consts_of t'';
252.287 + val const_matches' = fold (fn (c, ty) =>
252.288 + insert (op =) (c, Sign.const_typargs thy (c, ty))) consts' [];
252.289 + val (algebra', arities_eqngr') =
252.290 + extend_arities_eqngr thy consts const_matches' arities_eqngr;
252.291 + in
252.292 + (evaluator_lift (evaluator_eqngr algebra') thm (snd arities_eqngr'),
252.293 + arities_eqngr')
252.294 + end;
252.295 +
252.296 +fun proto_eval_conv thy =
252.297 + let
252.298 + fun evaluator_lift evaluator thm1 eqngr =
252.299 + let
252.300 + val thm2 = evaluator eqngr;
252.301 + val thm3 = Code.postprocess_conv thy (Thm.rhs_of thm2);
252.302 + in
252.303 + Thm.transitive thm1 (Thm.transitive thm2 thm3) handle THM _ =>
252.304 + error ("could not construct evaluation proof:\n"
252.305 + ^ (cat_lines o map Display.string_of_thm) [thm1, thm2, thm3])
252.306 + end;
252.307 + in proto_eval thy I evaluator_lift end;
252.308 +
252.309 +fun proto_eval_term thy =
252.310 + let
252.311 + fun evaluator_lift evaluator _ eqngr = evaluator eqngr;
252.312 + in proto_eval thy (Thm.cterm_of thy) evaluator_lift end;
252.313 +
252.314 +structure Wellsorted = CodeDataFun
252.315 +(
252.316 + type T = ((string * class) * sort list) list * T;
252.317 + val empty = ([], Graph.empty);
252.318 + fun purge thy cs (arities, eqngr) =
252.319 + let
252.320 + val del_cs = ((Graph.all_preds eqngr
252.321 + o filter (can (Graph.get_node eqngr))) cs);
252.322 + val del_arities = del_cs
252.323 + |> map_filter (AxClass.inst_of_param thy)
252.324 + |> maps (fn (c, tyco) =>
252.325 + (map (rpair tyco) o Sign.complete_sort thy o the_list
252.326 + o AxClass.class_of_param thy) c);
252.327 + val arities' = fold (AList.delete (op =)) del_arities arities;
252.328 + val eqngr' = Graph.del_nodes del_cs eqngr;
252.329 + in (arities', eqngr') end;
252.330 +);
252.331 +
252.332 +fun make thy cs = apsnd snd
252.333 + (Wellsorted.change_yield thy (extend_arities_eqngr thy cs []));
252.334 +
252.335 +fun eval_conv thy f =
252.336 + fst o Wellsorted.change_yield thy o proto_eval_conv thy f;
252.337 +
252.338 +fun eval_term thy f =
252.339 + fst o Wellsorted.change_yield thy o proto_eval_term thy f;
252.340 +
252.341 +
252.342 +(** diagnostic commands **)
252.343 +
252.344 +fun code_depgr thy consts =
252.345 + let
252.346 + val (_, eqngr) = make thy consts;
252.347 + val select = Graph.all_succs eqngr consts;
252.348 + in
252.349 + eqngr
252.350 + |> not (null consts) ? Graph.subgraph (member (op =) select)
252.351 + |> Graph.map_nodes ((apsnd o map o apfst) (AxClass.overload thy))
252.352 + end;
252.353 +
252.354 +fun code_thms thy = Pretty.writeln o pretty thy o code_depgr thy;
252.355 +
252.356 +fun code_deps thy consts =
252.357 + let
252.358 + val eqngr = code_depgr thy consts;
252.359 + fun mk_entry (const, (_, (_, parents))) =
252.360 + let
252.361 + val name = Code_Unit.string_of_const thy const;
252.362 + val nameparents = map (Code_Unit.string_of_const thy) parents;
252.363 + in { name = name, ID = name, dir = "", unfold = true,
252.364 + path = "", parents = nameparents }
252.365 + end;
252.366 + val prgr = Graph.fold ((fn x => fn xs => xs @ [x]) o mk_entry) eqngr [];
252.367 + in Present.display_graph prgr end;
252.368 +
252.369 +local
252.370 +
252.371 +structure P = OuterParse
252.372 +and K = OuterKeyword
252.373 +
252.374 +fun code_thms_cmd thy = code_thms thy o op @ o Code_Name.read_const_exprs thy;
252.375 +fun code_deps_cmd thy = code_deps thy o op @ o Code_Name.read_const_exprs thy;
252.376 +
252.377 +in
252.378 +
252.379 +val _ =
252.380 + OuterSyntax.improper_command "code_thms" "print system of code equations for code" OuterKeyword.diag
252.381 + (Scan.repeat P.term_group
252.382 + >> (fn cs => Toplevel.no_timing o Toplevel.unknown_theory
252.383 + o Toplevel.keep ((fn thy => code_thms_cmd thy cs) o Toplevel.theory_of)));
252.384 +
252.385 +val _ =
252.386 + OuterSyntax.improper_command "code_deps" "visualize dependencies of code equations for code" OuterKeyword.diag
252.387 + (Scan.repeat P.term_group
252.388 + >> (fn cs => Toplevel.no_timing o Toplevel.unknown_theory
252.389 + o Toplevel.keep ((fn thy => code_deps_cmd thy cs) o Toplevel.theory_of)));
252.390 +
252.391 +end;
252.392 +
252.393 +end; (*struct*)
253.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
253.2 +++ b/src/Tools/coherent.ML Wed Mar 04 11:05:29 2009 +0100
253.3 @@ -0,0 +1,233 @@
253.4 +(* Title: Tools/coherent.ML
253.5 + Author: Stefan Berghofer, TU Muenchen
253.6 + Author: Marc Bezem, Institutt for Informatikk, Universitetet i Bergen
253.7 +
253.8 +Prover for coherent logic, see e.g.
253.9 +
253.10 + Marc Bezem and Thierry Coquand, Automating Coherent Logic, LPAR 2005
253.11 +
253.12 +for a description of the algorithm.
253.13 +*)
253.14 +
253.15 +signature COHERENT_DATA =
253.16 +sig
253.17 + val atomize_elimL: thm
253.18 + val atomize_exL: thm
253.19 + val atomize_conjL: thm
253.20 + val atomize_disjL: thm
253.21 + val operator_names: string list
253.22 +end;
253.23 +
253.24 +signature COHERENT =
253.25 +sig
253.26 + val verbose: bool ref
253.27 + val show_facts: bool ref
253.28 + val coherent_tac: thm list -> Proof.context -> int -> tactic
253.29 + val coherent_meth: thm list -> Proof.context -> Proof.method
253.30 + val setup: theory -> theory
253.31 +end;
253.32 +
253.33 +functor CoherentFun(Data: COHERENT_DATA) : COHERENT =
253.34 +struct
253.35 +
253.36 +val verbose = ref false;
253.37 +
253.38 +fun message f = if !verbose then tracing (f ()) else ();
253.39 +
253.40 +datatype cl_prf =
253.41 + ClPrf of thm * (Type.tyenv * Envir.tenv) * ((indexname * typ) * term) list *
253.42 + int list * (term list * cl_prf) list;
253.43 +
253.44 +val is_atomic = not o exists_Const (member (op =) Data.operator_names o #1);
253.45 +
253.46 +local open Conv in
253.47 +
253.48 +fun rulify_elim_conv ct =
253.49 + if is_atomic (Logic.strip_imp_concl (term_of ct)) then all_conv ct
253.50 + else concl_conv (length (Logic.strip_imp_prems (term_of ct)))
253.51 + (rewr_conv (symmetric Data.atomize_elimL) then_conv
253.52 + MetaSimplifier.rewrite true (map symmetric
253.53 + [Data.atomize_exL, Data.atomize_conjL, Data.atomize_disjL])) ct
253.54 +
253.55 +end;
253.56 +
253.57 +fun rulify_elim th = MetaSimplifier.norm_hhf (Conv.fconv_rule rulify_elim_conv th);
253.58 +
253.59 +(* Decompose elimination rule of the form
253.60 + A1 ==> ... ==> Am ==> (!!xs1. Bs1 ==> P) ==> ... ==> (!!xsn. Bsn ==> P) ==> P
253.61 +*)
253.62 +fun dest_elim prop =
253.63 + let
253.64 + val prems = Logic.strip_imp_prems prop;
253.65 + val concl = Logic.strip_imp_concl prop;
253.66 + val (prems1, prems2) =
253.67 + take_suffix (fn t => Logic.strip_assums_concl t = concl) prems;
253.68 + in
253.69 + (prems1,
253.70 + if null prems2 then [([], [concl])]
253.71 + else map (fn t =>
253.72 + (map snd (Logic.strip_params t), Logic.strip_assums_hyp t)) prems2)
253.73 + end;
253.74 +
253.75 +fun mk_rule th =
253.76 + let
253.77 + val th' = rulify_elim th;
253.78 + val (prems, cases) = dest_elim (prop_of th')
253.79 + in (th', prems, cases) end;
253.80 +
253.81 +fun mk_dom ts = fold (fn t =>
253.82 + Typtab.map_default (fastype_of t, []) (fn us => us @ [t])) ts Typtab.empty;
253.83 +
253.84 +val empty_env = (Vartab.empty, Vartab.empty);
253.85 +
253.86 +(* Find matcher that makes conjunction valid in given state *)
253.87 +fun valid_conj ctxt facts env [] = Seq.single (env, [])
253.88 + | valid_conj ctxt facts env (t :: ts) =
253.89 + Seq.maps (fn (u, x) => Seq.map (apsnd (cons x))
253.90 + (valid_conj ctxt facts
253.91 + (Pattern.match (ProofContext.theory_of ctxt) (t, u) env) ts
253.92 + handle Pattern.MATCH => Seq.empty))
253.93 + (Seq.of_list (sort (int_ord o pairself snd) (Net.unify_term facts t)));
253.94 +
253.95 +(* Instantiate variables that only occur free in conlusion *)
253.96 +fun inst_extra_vars ctxt dom cs =
253.97 + let
253.98 + val vs = fold Term.add_vars (maps snd cs) [];
253.99 + fun insts [] inst = Seq.single inst
253.100 + | insts ((ixn, T) :: vs') inst = Seq.maps
253.101 + (fn t => insts vs' (((ixn, T), t) :: inst))
253.102 + (Seq.of_list (case Typtab.lookup dom T of
253.103 + NONE => error ("Unknown domain: " ^
253.104 + Syntax.string_of_typ ctxt T ^ "\nfor term(s) " ^
253.105 + commas (maps (map (Syntax.string_of_term ctxt) o snd) cs))
253.106 + | SOME ts => ts))
253.107 + in Seq.map (fn inst =>
253.108 + (inst, map (apsnd (map (subst_Vars (map (apfst fst) inst)))) cs))
253.109 + (insts vs [])
253.110 + end;
253.111 +
253.112 +(* Check whether disjunction is valid in given state *)
253.113 +fun is_valid_disj ctxt facts [] = false
253.114 + | is_valid_disj ctxt facts ((Ts, ts) :: ds) =
253.115 + let val vs = rev (map_index (fn (i, T) => Var (("x", i), T)) Ts)
253.116 + in case Seq.pull (valid_conj ctxt facts empty_env
253.117 + (map (fn t => subst_bounds (vs, t)) ts)) of
253.118 + SOME _ => true
253.119 + | NONE => is_valid_disj ctxt facts ds
253.120 + end;
253.121 +
253.122 +val show_facts = ref false;
253.123 +
253.124 +fun string_of_facts ctxt s facts = space_implode "\n"
253.125 + (s :: map (Syntax.string_of_term ctxt)
253.126 + (map fst (sort (int_ord o pairself snd) (Net.content facts)))) ^ "\n\n";
253.127 +
253.128 +fun print_facts ctxt facts =
253.129 + if !show_facts then message (fn () => string_of_facts ctxt "Facts:" facts)
253.130 + else ();
253.131 +
253.132 +fun valid ctxt rules goal dom facts nfacts nparams =
253.133 + let val seq = Seq.of_list rules |> Seq.maps (fn (th, ps, cs) =>
253.134 + valid_conj ctxt facts empty_env ps |> Seq.maps (fn (env as (tye, _), is) =>
253.135 + let val cs' = map (fn (Ts, ts) =>
253.136 + (map (Envir.typ_subst_TVars tye) Ts, map (Envir.subst_vars env) ts)) cs
253.137 + in
253.138 + inst_extra_vars ctxt dom cs' |>
253.139 + Seq.map_filter (fn (inst, cs'') =>
253.140 + if is_valid_disj ctxt facts cs'' then NONE
253.141 + else SOME (th, env, inst, is, cs''))
253.142 + end))
253.143 + in
253.144 + case Seq.pull seq of
253.145 + NONE => (tracing (string_of_facts ctxt "Countermodel found:" facts); NONE)
253.146 + | SOME ((th, env, inst, is, cs), _) =>
253.147 + if cs = [([], [goal])] then SOME (ClPrf (th, env, inst, is, []))
253.148 + else
253.149 + (case valid_cases ctxt rules goal dom facts nfacts nparams cs of
253.150 + NONE => NONE
253.151 + | SOME prfs => SOME (ClPrf (th, env, inst, is, prfs)))
253.152 + end
253.153 +
253.154 +and valid_cases ctxt rules goal dom facts nfacts nparams [] = SOME []
253.155 + | valid_cases ctxt rules goal dom facts nfacts nparams ((Ts, ts) :: ds) =
253.156 + let
253.157 + val _ = message (fn () => "case " ^ commas (map (Syntax.string_of_term ctxt) ts));
253.158 + val params = rev (map_index (fn (i, T) =>
253.159 + Free ("par" ^ string_of_int (nparams + i), T)) Ts);
253.160 + val ts' = map_index (fn (i, t) =>
253.161 + (subst_bounds (params, t), nfacts + i)) ts;
253.162 + val dom' = fold (fn (T, p) =>
253.163 + Typtab.map_default (T, []) (fn ps => ps @ [p]))
253.164 + (Ts ~~ params) dom;
253.165 + val facts' = fold (fn (t, i) => Net.insert_term op =
253.166 + (t, (t, i))) ts' facts
253.167 + in
253.168 + case valid ctxt rules goal dom' facts'
253.169 + (nfacts + length ts) (nparams + length Ts) of
253.170 + NONE => NONE
253.171 + | SOME prf => (case valid_cases ctxt rules goal dom facts nfacts nparams ds of
253.172 + NONE => NONE
253.173 + | SOME prfs => SOME ((params, prf) :: prfs))
253.174 + end;
253.175 +
253.176 +(** proof replaying **)
253.177 +
253.178 +fun thm_of_cl_prf thy goal asms (ClPrf (th, (tye, env), insts, is, prfs)) =
253.179 + let
253.180 + val _ = message (fn () => space_implode "\n"
253.181 + ("asms:" :: map Display.string_of_thm asms) ^ "\n\n");
253.182 + val th' = Drule.implies_elim_list
253.183 + (Thm.instantiate
253.184 + (map (fn (ixn, (S, T)) =>
253.185 + (Thm.ctyp_of thy (TVar ((ixn, S))), Thm.ctyp_of thy T))
253.186 + (Vartab.dest tye),
253.187 + map (fn (ixn, (T, t)) =>
253.188 + (Thm.cterm_of thy (Var (ixn, Envir.typ_subst_TVars tye T)),
253.189 + Thm.cterm_of thy t)) (Vartab.dest env) @
253.190 + map (fn (ixnT, t) =>
253.191 + (Thm.cterm_of thy (Var ixnT), Thm.cterm_of thy t)) insts) th)
253.192 + (map (nth asms) is);
253.193 + val (_, cases) = dest_elim (prop_of th')
253.194 + in
253.195 + case (cases, prfs) of
253.196 + ([([], [_])], []) => th'
253.197 + | ([([], [_])], [([], prf)]) => thm_of_cl_prf thy goal (asms @ [th']) prf
253.198 + | _ => Drule.implies_elim_list
253.199 + (Thm.instantiate (Thm.match
253.200 + (Drule.strip_imp_concl (cprop_of th'), goal)) th')
253.201 + (map (thm_of_case_prf thy goal asms) (prfs ~~ cases))
253.202 + end
253.203 +
253.204 +and thm_of_case_prf thy goal asms ((params, prf), (_, asms')) =
253.205 + let
253.206 + val cparams = map (cterm_of thy) params;
253.207 + val asms'' = map (cterm_of thy o curry subst_bounds (rev params)) asms'
253.208 + in
253.209 + Drule.forall_intr_list cparams (Drule.implies_intr_list asms''
253.210 + (thm_of_cl_prf thy goal (asms @ map Thm.assume asms'') prf))
253.211 + end;
253.212 +
253.213 +
253.214 +(** external interface **)
253.215 +
253.216 +fun coherent_tac rules ctxt = SUBPROOF (fn {prems, concl, params, context, ...} =>
253.217 + rtac (rulify_elim_conv concl RS equal_elim_rule2) 1 THEN
253.218 + SUBPROOF (fn {prems = prems', concl, context, ...} =>
253.219 + let val xs = map term_of params @
253.220 + map (fn (_, s) => Free (s, the (Variable.default_type context s)))
253.221 + (Variable.fixes_of context)
253.222 + in
253.223 + case valid context (map mk_rule (prems' @ prems @ rules)) (term_of concl)
253.224 + (mk_dom xs) Net.empty 0 0 of
253.225 + NONE => no_tac
253.226 + | SOME prf =>
253.227 + rtac (thm_of_cl_prf (ProofContext.theory_of context) concl [] prf) 1
253.228 + end) context 1) ctxt;
253.229 +
253.230 +fun coherent_meth rules ctxt =
253.231 + Method.METHOD (fn facts => coherent_tac (facts @ rules) ctxt 1);
253.232 +
253.233 +val setup = Method.add_method
253.234 + ("coherent", Method.thms_ctxt_args coherent_meth, "prove coherent formula");
253.235 +
253.236 +end;
254.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
254.2 +++ b/src/Tools/eqsubst.ML Wed Mar 04 11:05:29 2009 +0100
254.3 @@ -0,0 +1,575 @@
254.4 +(* Title: Tools/eqsubst.ML
254.5 + Author: Lucas Dixon, University of Edinburgh
254.6 +
254.7 +A proof method to perform a substiution using an equation.
254.8 +*)
254.9 +
254.10 +signature EQSUBST =
254.11 +sig
254.12 + (* a type abbreviation for match information *)
254.13 + type match =
254.14 + ((indexname * (sort * typ)) list (* type instantiations *)
254.15 + * (indexname * (typ * term)) list) (* term instantiations *)
254.16 + * (string * typ) list (* fake named type abs env *)
254.17 + * (string * typ) list (* type abs env *)
254.18 + * term (* outer term *)
254.19 +
254.20 + type searchinfo =
254.21 + theory
254.22 + * int (* maxidx *)
254.23 + * Zipper.T (* focusterm to search under *)
254.24 +
254.25 + exception eqsubst_occL_exp of
254.26 + string * int list * Thm.thm list * int * Thm.thm
254.27 +
254.28 + (* low level substitution functions *)
254.29 + val apply_subst_in_asm :
254.30 + int ->
254.31 + Thm.thm ->
254.32 + Thm.thm ->
254.33 + (Thm.cterm list * int * 'a * Thm.thm) * match -> Thm.thm Seq.seq
254.34 + val apply_subst_in_concl :
254.35 + int ->
254.36 + Thm.thm ->
254.37 + Thm.cterm list * Thm.thm ->
254.38 + Thm.thm -> match -> Thm.thm Seq.seq
254.39 +
254.40 + (* matching/unification within zippers *)
254.41 + val clean_match_z :
254.42 + Context.theory -> Term.term -> Zipper.T -> match option
254.43 + val clean_unify_z :
254.44 + Context.theory -> int -> Term.term -> Zipper.T -> match Seq.seq
254.45 +
254.46 + (* skipping things in seq seq's *)
254.47 +
254.48 + (* skipping non-empty sub-sequences but when we reach the end
254.49 + of the seq, remembering how much we have left to skip. *)
254.50 + datatype 'a skipseq = SkipMore of int
254.51 + | SkipSeq of 'a Seq.seq Seq.seq;
254.52 +
254.53 + val skip_first_asm_occs_search :
254.54 + ('a -> 'b -> 'c Seq.seq Seq.seq) ->
254.55 + 'a -> int -> 'b -> 'c skipseq
254.56 + val skip_first_occs_search :
254.57 + int -> ('a -> 'b -> 'c Seq.seq Seq.seq) -> 'a -> 'b -> 'c Seq.seq
254.58 + val skipto_skipseq : int -> 'a Seq.seq Seq.seq -> 'a skipseq
254.59 +
254.60 + (* tactics *)
254.61 + val eqsubst_asm_tac :
254.62 + Proof.context ->
254.63 + int list -> Thm.thm list -> int -> Thm.thm -> Thm.thm Seq.seq
254.64 + val eqsubst_asm_tac' :
254.65 + Proof.context ->
254.66 + (searchinfo -> int -> Term.term -> match skipseq) ->
254.67 + int -> Thm.thm -> int -> Thm.thm -> Thm.thm Seq.seq
254.68 + val eqsubst_tac :
254.69 + Proof.context ->
254.70 + int list -> (* list of occurences to rewrite, use [0] for any *)
254.71 + Thm.thm list -> int -> Thm.thm -> Thm.thm Seq.seq
254.72 + val eqsubst_tac' :
254.73 + Proof.context -> (* proof context *)
254.74 + (searchinfo -> Term.term -> match Seq.seq) (* search function *)
254.75 + -> Thm.thm (* equation theorem to rewrite with *)
254.76 + -> int (* subgoal number in goal theorem *)
254.77 + -> Thm.thm (* goal theorem *)
254.78 + -> Thm.thm Seq.seq (* rewritten goal theorem *)
254.79 +
254.80 +
254.81 + val fakefree_badbounds :
254.82 + (string * Term.typ) list ->
254.83 + Term.term ->
254.84 + (string * Term.typ) list * (string * Term.typ) list * Term.term
254.85 +
254.86 + val mk_foo_match :
254.87 + (Term.term -> Term.term) ->
254.88 + ('a * Term.typ) list -> Term.term -> Term.term
254.89 +
254.90 + (* preparing substitution *)
254.91 + val prep_meta_eq : Proof.context -> Thm.thm -> Thm.thm list
254.92 + val prep_concl_subst :
254.93 + int -> Thm.thm -> (Thm.cterm list * Thm.thm) * searchinfo
254.94 + val prep_subst_in_asm :
254.95 + int -> Thm.thm -> int ->
254.96 + (Thm.cterm list * int * int * Thm.thm) * searchinfo
254.97 + val prep_subst_in_asms :
254.98 + int -> Thm.thm ->
254.99 + ((Thm.cterm list * int * int * Thm.thm) * searchinfo) list
254.100 + val prep_zipper_match :
254.101 + Zipper.T -> Term.term * ((string * Term.typ) list * (string * Term.typ) list * Term.term)
254.102 +
254.103 + (* search for substitutions *)
254.104 + val valid_match_start : Zipper.T -> bool
254.105 + val search_lr_all : Zipper.T -> Zipper.T Seq.seq
254.106 + val search_lr_valid : (Zipper.T -> bool) -> Zipper.T -> Zipper.T Seq.seq
254.107 + val searchf_lr_unify_all :
254.108 + searchinfo -> Term.term -> match Seq.seq Seq.seq
254.109 + val searchf_lr_unify_valid :
254.110 + searchinfo -> Term.term -> match Seq.seq Seq.seq
254.111 + val searchf_bt_unify_valid :
254.112 + searchinfo -> Term.term -> match Seq.seq Seq.seq
254.113 +
254.114 + (* syntax tools *)
254.115 + val ith_syntax : Args.T list -> int list * Args.T list
254.116 + val options_syntax : Args.T list -> bool * Args.T list
254.117 +
254.118 + (* Isar level hooks *)
254.119 + val eqsubst_asm_meth : Proof.context -> int list -> Thm.thm list -> Proof.method
254.120 + val eqsubst_meth : Proof.context -> int list -> Thm.thm list -> Proof.method
254.121 + val subst_meth : Method.src -> Proof.context -> Proof.method
254.122 + val setup : theory -> theory
254.123 +
254.124 +end;
254.125 +
254.126 +structure EqSubst
254.127 +: EQSUBST
254.128 += struct
254.129 +
254.130 +structure Z = Zipper;
254.131 +
254.132 +(* changes object "=" to meta "==" which prepares a given rewrite rule *)
254.133 +fun prep_meta_eq ctxt =
254.134 + let val (_, {mk_rews = {mk, ...}, ...}) = Simplifier.rep_ss (Simplifier.local_simpset_of ctxt)
254.135 + in mk #> map Drule.zero_var_indexes end;
254.136 +
254.137 +
254.138 + (* a type abriviation for match information *)
254.139 + type match =
254.140 + ((indexname * (sort * typ)) list (* type instantiations *)
254.141 + * (indexname * (typ * term)) list) (* term instantiations *)
254.142 + * (string * typ) list (* fake named type abs env *)
254.143 + * (string * typ) list (* type abs env *)
254.144 + * term (* outer term *)
254.145 +
254.146 + type searchinfo =
254.147 + theory
254.148 + * int (* maxidx *)
254.149 + * Zipper.T (* focusterm to search under *)
254.150 +
254.151 +
254.152 +(* skipping non-empty sub-sequences but when we reach the end
254.153 + of the seq, remembering how much we have left to skip. *)
254.154 +datatype 'a skipseq = SkipMore of int
254.155 + | SkipSeq of 'a Seq.seq Seq.seq;
254.156 +(* given a seqseq, skip the first m non-empty seq's, note deficit *)
254.157 +fun skipto_skipseq m s =
254.158 + let
254.159 + fun skip_occs n sq =
254.160 + case Seq.pull sq of
254.161 + NONE => SkipMore n
254.162 + | SOME (h,t) =>
254.163 + (case Seq.pull h of NONE => skip_occs n t
254.164 + | SOME _ => if n <= 1 then SkipSeq (Seq.cons h t)
254.165 + else skip_occs (n - 1) t)
254.166 + in (skip_occs m s) end;
254.167 +
254.168 +(* note: outerterm is the taget with the match replaced by a bound
254.169 + variable : ie: "P lhs" beocmes "%x. P x"
254.170 + insts is the types of instantiations of vars in lhs
254.171 + and typinsts is the type instantiations of types in the lhs
254.172 + Note: Final rule is the rule lifted into the ontext of the
254.173 + taget thm. *)
254.174 +fun mk_foo_match mkuptermfunc Ts t =
254.175 + let
254.176 + val ty = Term.type_of t
254.177 + val bigtype = (rev (map snd Ts)) ---> ty
254.178 + fun mk_foo 0 t = t
254.179 + | mk_foo i t = mk_foo (i - 1) (t $ (Bound (i - 1)))
254.180 + val num_of_bnds = (length Ts)
254.181 + (* foo_term = "fooabs y0 ... yn" where y's are local bounds *)
254.182 + val foo_term = mk_foo num_of_bnds (Bound num_of_bnds)
254.183 + in Abs("fooabs", bigtype, mkuptermfunc foo_term) end;
254.184 +
254.185 +(* T is outer bound vars, n is number of locally bound vars *)
254.186 +(* THINK: is order of Ts correct...? or reversed? *)
254.187 +fun fakefree_badbounds Ts t =
254.188 + let val (FakeTs,Ts,newnames) =
254.189 + List.foldr (fn ((n,ty),(FakeTs,Ts,usednames)) =>
254.190 + let val newname = Name.variant usednames n
254.191 + in ((RWTools.mk_fake_bound_name newname,ty)::FakeTs,
254.192 + (newname,ty)::Ts,
254.193 + newname::usednames) end)
254.194 + ([],[],[])
254.195 + Ts
254.196 + in (FakeTs, Ts, Term.subst_bounds (map Free FakeTs, t)) end;
254.197 +
254.198 +(* before matching we need to fake the bound vars that are missing an
254.199 +abstraction. In this function we additionally construct the
254.200 +abstraction environment, and an outer context term (with the focus
254.201 +abstracted out) for use in rewriting with RWInst.rw *)
254.202 +fun prep_zipper_match z =
254.203 + let
254.204 + val t = Z.trm z
254.205 + val c = Z.ctxt z
254.206 + val Ts = Z.C.nty_ctxt c
254.207 + val (FakeTs', Ts', t') = fakefree_badbounds Ts t
254.208 + val absterm = mk_foo_match (Z.C.apply c) Ts' t'
254.209 + in
254.210 + (t', (FakeTs', Ts', absterm))
254.211 + end;
254.212 +
254.213 +(* Matching and Unification with exception handled *)
254.214 +fun clean_match thy (a as (pat, t)) =
254.215 + let val (tyenv, tenv) = Pattern.match thy a (Vartab.empty, Vartab.empty)
254.216 + in SOME (Vartab.dest tyenv, Vartab.dest tenv)
254.217 + end handle Pattern.MATCH => NONE;
254.218 +
254.219 +(* given theory, max var index, pat, tgt; returns Seq of instantiations *)
254.220 +fun clean_unify thry ix (a as (pat, tgt)) =
254.221 + let
254.222 + (* type info will be re-derived, maybe this can be cached
254.223 + for efficiency? *)
254.224 + val pat_ty = Term.type_of pat;
254.225 + val tgt_ty = Term.type_of tgt;
254.226 + (* is it OK to ignore the type instantiation info?
254.227 + or should I be using it? *)
254.228 + val typs_unify =
254.229 + SOME (Sign.typ_unify thry (pat_ty, tgt_ty) (Vartab.empty, ix))
254.230 + handle Type.TUNIFY => NONE;
254.231 + in
254.232 + case typs_unify of
254.233 + SOME (typinsttab, ix2) =>
254.234 + let
254.235 + (* is it right to throw away the flexes?
254.236 + or should I be using them somehow? *)
254.237 + fun mk_insts env =
254.238 + (Vartab.dest (Envir.type_env env),
254.239 + Envir.alist_of env);
254.240 + val initenv = Envir.Envir {asol = Vartab.empty,
254.241 + iTs = typinsttab, maxidx = ix2};
254.242 + val useq = Unify.smash_unifiers thry [a] initenv
254.243 + handle UnequalLengths => Seq.empty
254.244 + | Term.TERM _ => Seq.empty;
254.245 + fun clean_unify' useq () =
254.246 + (case (Seq.pull useq) of
254.247 + NONE => NONE
254.248 + | SOME (h,t) => SOME (mk_insts h, Seq.make (clean_unify' t)))
254.249 + handle UnequalLengths => NONE
254.250 + | Term.TERM _ => NONE
254.251 + in
254.252 + (Seq.make (clean_unify' useq))
254.253 + end
254.254 + | NONE => Seq.empty
254.255 + end;
254.256 +
254.257 +(* Matching and Unification for zippers *)
254.258 +(* Note: Ts is a modified version of the original names of the outer
254.259 +bound variables. New names have been introduced to make sure they are
254.260 +unique w.r.t all names in the term and each other. usednames' is
254.261 +oldnames + new names. *)
254.262 +fun clean_match_z thy pat z =
254.263 + let val (t, (FakeTs,Ts,absterm)) = prep_zipper_match z in
254.264 + case clean_match thy (pat, t) of
254.265 + NONE => NONE
254.266 + | SOME insts => SOME (insts, FakeTs, Ts, absterm) end;
254.267 +(* ix = max var index *)
254.268 +fun clean_unify_z sgn ix pat z =
254.269 + let val (t, (FakeTs, Ts,absterm)) = prep_zipper_match z in
254.270 + Seq.map (fn insts => (insts, FakeTs, Ts, absterm))
254.271 + (clean_unify sgn ix (t, pat)) end;
254.272 +
254.273 +
254.274 +(* FOR DEBUGGING...
254.275 +type trace_subst_errT = int (* subgoal *)
254.276 + * thm (* thm with all goals *)
254.277 + * (Thm.cterm list (* certified free var placeholders for vars *)
254.278 + * thm) (* trivial thm of goal concl *)
254.279 + (* possible matches/unifiers *)
254.280 + * thm (* rule *)
254.281 + * (((indexname * typ) list (* type instantiations *)
254.282 + * (indexname * term) list ) (* term instantiations *)
254.283 + * (string * typ) list (* Type abs env *)
254.284 + * term) (* outer term *);
254.285 +
254.286 +val trace_subst_err = (ref NONE : trace_subst_errT option ref);
254.287 +val trace_subst_search = ref false;
254.288 +exception trace_subst_exp of trace_subst_errT;
254.289 +*)
254.290 +
254.291 +
254.292 +fun bot_left_leaf_of (l $ r) = bot_left_leaf_of l
254.293 + | bot_left_leaf_of (Abs(s,ty,t)) = bot_left_leaf_of t
254.294 + | bot_left_leaf_of x = x;
254.295 +
254.296 +(* Avoid considering replacing terms which have a var at the head as
254.297 + they always succeed trivially, and uninterestingly. *)
254.298 +fun valid_match_start z =
254.299 + (case bot_left_leaf_of (Z.trm z) of
254.300 + Var _ => false
254.301 + | _ => true);
254.302 +
254.303 +(* search from top, left to right, then down *)
254.304 +val search_lr_all = ZipperSearch.all_bl_ur;
254.305 +
254.306 +(* search from top, left to right, then down *)
254.307 +fun search_lr_valid validf =
254.308 + let
254.309 + fun sf_valid_td_lr z =
254.310 + let val here = if validf z then [Z.Here z] else [] in
254.311 + case Z.trm z
254.312 + of _ $ _ => [Z.LookIn (Z.move_down_left z)]
254.313 + @ here
254.314 + @ [Z.LookIn (Z.move_down_right z)]
254.315 + | Abs _ => here @ [Z.LookIn (Z.move_down_abs z)]
254.316 + | _ => here
254.317 + end;
254.318 + in Z.lzy_search sf_valid_td_lr end;
254.319 +
254.320 +(* search from bottom to top, left to right *)
254.321 +
254.322 +fun search_bt_valid validf =
254.323 + let
254.324 + fun sf_valid_td_lr z =
254.325 + let val here = if validf z then [Z.Here z] else [] in
254.326 + case Z.trm z
254.327 + of _ $ _ => [Z.LookIn (Z.move_down_left z),
254.328 + Z.LookIn (Z.move_down_right z)] @ here
254.329 + | Abs _ => [Z.LookIn (Z.move_down_abs z)] @ here
254.330 + | _ => here
254.331 + end;
254.332 + in Z.lzy_search sf_valid_td_lr end;
254.333 +
254.334 +fun searchf_unify_gen f (sgn, maxidx, z) lhs =
254.335 + Seq.map (clean_unify_z sgn maxidx lhs)
254.336 + (Z.limit_apply f z);
254.337 +
254.338 +(* search all unifications *)
254.339 +val searchf_lr_unify_all =
254.340 + searchf_unify_gen search_lr_all;
254.341 +
254.342 +(* search only for 'valid' unifiers (non abs subterms and non vars) *)
254.343 +val searchf_lr_unify_valid =
254.344 + searchf_unify_gen (search_lr_valid valid_match_start);
254.345 +
254.346 +val searchf_bt_unify_valid =
254.347 + searchf_unify_gen (search_bt_valid valid_match_start);
254.348 +
254.349 +(* apply a substitution in the conclusion of the theorem th *)
254.350 +(* cfvs are certified free var placeholders for goal params *)
254.351 +(* conclthm is a theorem of for just the conclusion *)
254.352 +(* m is instantiation/match information *)
254.353 +(* rule is the equation for substitution *)
254.354 +fun apply_subst_in_concl i th (cfvs, conclthm) rule m =
254.355 + (RWInst.rw m rule conclthm)
254.356 + |> IsaND.unfix_frees cfvs
254.357 + |> RWInst.beta_eta_contract
254.358 + |> (fn r => Tactic.rtac r i th);
254.359 +
254.360 +(* substitute within the conclusion of goal i of gth, using a meta
254.361 +equation rule. Note that we assume rule has var indicies zero'd *)
254.362 +fun prep_concl_subst i gth =
254.363 + let
254.364 + val th = Thm.incr_indexes 1 gth;
254.365 + val tgt_term = Thm.prop_of th;
254.366 +
254.367 + val sgn = Thm.theory_of_thm th;
254.368 + val ctermify = Thm.cterm_of sgn;
254.369 + val trivify = Thm.trivial o ctermify;
254.370 +
254.371 + val (fixedbody, fvs) = IsaND.fix_alls_term i tgt_term;
254.372 + val cfvs = rev (map ctermify fvs);
254.373 +
254.374 + val conclterm = Logic.strip_imp_concl fixedbody;
254.375 + val conclthm = trivify conclterm;
254.376 + val maxidx = Thm.maxidx_of th;
254.377 + val ft = ((Z.move_down_right (* ==> *)
254.378 + o Z.move_down_left (* Trueprop *)
254.379 + o Z.mktop
254.380 + o Thm.prop_of) conclthm)
254.381 + in
254.382 + ((cfvs, conclthm), (sgn, maxidx, ft))
254.383 + end;
254.384 +
254.385 +(* substitute using an object or meta level equality *)
254.386 +fun eqsubst_tac' ctxt searchf instepthm i th =
254.387 + let
254.388 + val (cvfsconclthm, searchinfo) = prep_concl_subst i th;
254.389 + val stepthms = Seq.of_list (prep_meta_eq ctxt instepthm);
254.390 + fun rewrite_with_thm r =
254.391 + let val (lhs,_) = Logic.dest_equals (Thm.concl_of r);
254.392 + in searchf searchinfo lhs
254.393 + |> Seq.maps (apply_subst_in_concl i th cvfsconclthm r) end;
254.394 + in stepthms |> Seq.maps rewrite_with_thm end;
254.395 +
254.396 +
254.397 +(* distinct subgoals *)
254.398 +fun distinct_subgoals th =
254.399 + the_default th (SINGLE distinct_subgoals_tac th);
254.400 +
254.401 +(* General substitution of multiple occurances using one of
254.402 + the given theorems*)
254.403 +
254.404 +
254.405 +exception eqsubst_occL_exp of
254.406 + string * (int list) * (thm list) * int * thm;
254.407 +fun skip_first_occs_search occ srchf sinfo lhs =
254.408 + case (skipto_skipseq occ (srchf sinfo lhs)) of
254.409 + SkipMore _ => Seq.empty
254.410 + | SkipSeq ss => Seq.flat ss;
254.411 +
254.412 +(* The occL is a list of integers indicating which occurence
254.413 +w.r.t. the search order, to rewrite. Backtracking will also find later
254.414 +occurences, but all earlier ones are skipped. Thus you can use [0] to
254.415 +just find all rewrites. *)
254.416 +
254.417 +fun eqsubst_tac ctxt occL thms i th =
254.418 + let val nprems = Thm.nprems_of th in
254.419 + if nprems < i then Seq.empty else
254.420 + let val thmseq = (Seq.of_list thms)
254.421 + fun apply_occ occ th =
254.422 + thmseq |> Seq.maps
254.423 + (fn r => eqsubst_tac'
254.424 + ctxt
254.425 + (skip_first_occs_search
254.426 + occ searchf_lr_unify_valid) r
254.427 + (i + ((Thm.nprems_of th) - nprems))
254.428 + th);
254.429 + val sortedoccL =
254.430 + Library.sort (Library.rev_order o Library.int_ord) occL;
254.431 + in
254.432 + Seq.map distinct_subgoals (Seq.EVERY (map apply_occ sortedoccL) th)
254.433 + end
254.434 + end
254.435 + handle THM _ => raise eqsubst_occL_exp ("THM",occL,thms,i,th);
254.436 +
254.437 +
254.438 +(* inthms are the given arguments in Isar, and treated as eqstep with
254.439 + the first one, then the second etc *)
254.440 +fun eqsubst_meth ctxt occL inthms =
254.441 + Method.SIMPLE_METHOD' (eqsubst_tac ctxt occL inthms);
254.442 +
254.443 +(* apply a substitution inside assumption j, keeps asm in the same place *)
254.444 +fun apply_subst_in_asm i th rule ((cfvs, j, ngoalprems, pth),m) =
254.445 + let
254.446 + val th2 = Thm.rotate_rule (j - 1) i th; (* put premice first *)
254.447 + val preelimrule =
254.448 + (RWInst.rw m rule pth)
254.449 + |> (Seq.hd o prune_params_tac)
254.450 + |> Thm.permute_prems 0 ~1 (* put old asm first *)
254.451 + |> IsaND.unfix_frees cfvs (* unfix any global params *)
254.452 + |> RWInst.beta_eta_contract; (* normal form *)
254.453 + (* val elimrule =
254.454 + preelimrule
254.455 + |> Tactic.make_elim (* make into elim rule *)
254.456 + |> Thm.lift_rule (th2, i); (* lift into context *)
254.457 + *)
254.458 + in
254.459 + (* ~j because new asm starts at back, thus we subtract 1 *)
254.460 + Seq.map (Thm.rotate_rule (~j) ((Thm.nprems_of rule) + i))
254.461 + (Tactic.dtac preelimrule i th2)
254.462 +
254.463 + (* (Thm.bicompose
254.464 + false (* use unification *)
254.465 + (true, (* elim resolution *)
254.466 + elimrule, (2 + (Thm.nprems_of rule)) - ngoalprems)
254.467 + i th2) *)
254.468 + end;
254.469 +
254.470 +
254.471 +(* prepare to substitute within the j'th premise of subgoal i of gth,
254.472 +using a meta-level equation. Note that we assume rule has var indicies
254.473 +zero'd. Note that we also assume that premt is the j'th premice of
254.474 +subgoal i of gth. Note the repetition of work done for each
254.475 +assumption, i.e. this can be made more efficient for search over
254.476 +multiple assumptions. *)
254.477 +fun prep_subst_in_asm i gth j =
254.478 + let
254.479 + val th = Thm.incr_indexes 1 gth;
254.480 + val tgt_term = Thm.prop_of th;
254.481 +
254.482 + val sgn = Thm.theory_of_thm th;
254.483 + val ctermify = Thm.cterm_of sgn;
254.484 + val trivify = Thm.trivial o ctermify;
254.485 +
254.486 + val (fixedbody, fvs) = IsaND.fix_alls_term i tgt_term;
254.487 + val cfvs = rev (map ctermify fvs);
254.488 +
254.489 + val asmt = nth (Logic.strip_imp_prems fixedbody) (j - 1);
254.490 + val asm_nprems = length (Logic.strip_imp_prems asmt);
254.491 +
254.492 + val pth = trivify asmt;
254.493 + val maxidx = Thm.maxidx_of th;
254.494 +
254.495 + val ft = ((Z.move_down_right (* trueprop *)
254.496 + o Z.mktop
254.497 + o Thm.prop_of) pth)
254.498 + in ((cfvs, j, asm_nprems, pth), (sgn, maxidx, ft)) end;
254.499 +
254.500 +(* prepare subst in every possible assumption *)
254.501 +fun prep_subst_in_asms i gth =
254.502 + map (prep_subst_in_asm i gth)
254.503 + ((fn l => Library.upto (1, length l))
254.504 + (Logic.prems_of_goal (Thm.prop_of gth) i));
254.505 +
254.506 +
254.507 +(* substitute in an assumption using an object or meta level equality *)
254.508 +fun eqsubst_asm_tac' ctxt searchf skipocc instepthm i th =
254.509 + let
254.510 + val asmpreps = prep_subst_in_asms i th;
254.511 + val stepthms = Seq.of_list (prep_meta_eq ctxt instepthm);
254.512 + fun rewrite_with_thm r =
254.513 + let val (lhs,_) = Logic.dest_equals (Thm.concl_of r)
254.514 + fun occ_search occ [] = Seq.empty
254.515 + | occ_search occ ((asminfo, searchinfo)::moreasms) =
254.516 + (case searchf searchinfo occ lhs of
254.517 + SkipMore i => occ_search i moreasms
254.518 + | SkipSeq ss =>
254.519 + Seq.append (Seq.map (Library.pair asminfo) (Seq.flat ss))
254.520 + (occ_search 1 moreasms))
254.521 + (* find later substs also *)
254.522 + in
254.523 + occ_search skipocc asmpreps |> Seq.maps (apply_subst_in_asm i th r)
254.524 + end;
254.525 + in stepthms |> Seq.maps rewrite_with_thm end;
254.526 +
254.527 +
254.528 +fun skip_first_asm_occs_search searchf sinfo occ lhs =
254.529 + skipto_skipseq occ (searchf sinfo lhs);
254.530 +
254.531 +fun eqsubst_asm_tac ctxt occL thms i th =
254.532 + let val nprems = Thm.nprems_of th
254.533 + in
254.534 + if nprems < i then Seq.empty else
254.535 + let val thmseq = (Seq.of_list thms)
254.536 + fun apply_occ occK th =
254.537 + thmseq |> Seq.maps
254.538 + (fn r =>
254.539 + eqsubst_asm_tac' ctxt (skip_first_asm_occs_search
254.540 + searchf_lr_unify_valid) occK r
254.541 + (i + ((Thm.nprems_of th) - nprems))
254.542 + th);
254.543 + val sortedoccs =
254.544 + Library.sort (Library.rev_order o Library.int_ord) occL
254.545 + in
254.546 + Seq.map distinct_subgoals
254.547 + (Seq.EVERY (map apply_occ sortedoccs) th)
254.548 + end
254.549 + end
254.550 + handle THM _ => raise eqsubst_occL_exp ("THM",occL,thms,i,th);
254.551 +
254.552 +(* inthms are the given arguments in Isar, and treated as eqstep with
254.553 + the first one, then the second etc *)
254.554 +fun eqsubst_asm_meth ctxt occL inthms =
254.555 + Method.SIMPLE_METHOD' (eqsubst_asm_tac ctxt occL inthms);
254.556 +
254.557 +(* syntax for options, given "(asm)" will give back true, without
254.558 + gives back false *)
254.559 +val options_syntax =
254.560 + (Args.parens (Args.$$$ "asm") >> (K true)) ||
254.561 + (Scan.succeed false);
254.562 +
254.563 +val ith_syntax =
254.564 + Scan.optional (Args.parens (Scan.repeat OuterParse.nat)) [0];
254.565 +
254.566 +(* combination method that takes a flag (true indicates that subst
254.567 +should be done to an assumption, false = apply to the conclusion of
254.568 +the goal) as well as the theorems to use *)
254.569 +fun subst_meth src =
254.570 + Method.syntax ((Scan.lift options_syntax) -- (Scan.lift ith_syntax) -- Attrib.thms) src
254.571 + #> (fn (((asmflag, occL), inthms), ctxt) =>
254.572 + (if asmflag then eqsubst_asm_meth else eqsubst_meth) ctxt occL inthms);
254.573 +
254.574 +
254.575 +val setup =
254.576 + Method.add_method ("subst", subst_meth, "single-step substitution");
254.577 +
254.578 +end;
255.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
255.2 +++ b/src/Tools/intuitionistic.ML Wed Mar 04 11:05:29 2009 +0100
255.3 @@ -0,0 +1,100 @@
255.4 +(* Title: Tools/intuitionistic.ML
255.5 + Author: Stefan Berghofer, TU Muenchen
255.6 +
255.7 +Simple intuitionistic proof search.
255.8 +*)
255.9 +
255.10 +signature INTUITIONISTIC =
255.11 +sig
255.12 + val prover_tac: Proof.context -> int option -> int -> tactic
255.13 + val method_setup: bstring -> theory -> theory
255.14 +end;
255.15 +
255.16 +structure Intuitionistic: INTUITIONISTIC =
255.17 +struct
255.18 +
255.19 +(* main tactic *)
255.20 +
255.21 +local
255.22 +
255.23 +val remdups_tac = SUBGOAL (fn (g, i) =>
255.24 + let val prems = Logic.strip_assums_hyp g in
255.25 + REPEAT_DETERM_N (length prems - length (distinct op aconv prems))
255.26 + (Tactic.ematch_tac [Drule.remdups_rl] i THEN Tactic.eq_assume_tac i)
255.27 + end);
255.28 +
255.29 +fun REMDUPS tac = tac THEN_ALL_NEW remdups_tac;
255.30 +
255.31 +val bires_tac = Tactic.biresolution_from_nets_tac ContextRules.orderlist;
255.32 +
255.33 +fun safe_step_tac ctxt =
255.34 + ContextRules.Swrap ctxt
255.35 + (eq_assume_tac ORELSE'
255.36 + bires_tac true (ContextRules.netpair_bang ctxt));
255.37 +
255.38 +fun unsafe_step_tac ctxt =
255.39 + ContextRules.wrap ctxt
255.40 + (assume_tac APPEND'
255.41 + bires_tac false (ContextRules.netpair_bang ctxt) APPEND'
255.42 + bires_tac false (ContextRules.netpair ctxt));
255.43 +
255.44 +fun step_tac ctxt i =
255.45 + REPEAT_DETERM1 (REMDUPS (safe_step_tac ctxt) i) ORELSE
255.46 + REMDUPS (unsafe_step_tac ctxt) i;
255.47 +
255.48 +fun intprover_tac ctxt gs d lim = SUBGOAL (fn (g, i) => if d > lim then no_tac else
255.49 + let
255.50 + val ps = Logic.strip_assums_hyp g;
255.51 + val c = Logic.strip_assums_concl g;
255.52 + in
255.53 + if member (fn ((ps1, c1), (ps2, c2)) =>
255.54 + c1 aconv c2 andalso
255.55 + length ps1 = length ps2 andalso
255.56 + gen_eq_set (op aconv) (ps1, ps2)) gs (ps, c) then no_tac
255.57 + else (step_tac ctxt THEN_ALL_NEW intprover_tac ctxt ((ps, c) :: gs) (d + 1) lim) i
255.58 + end);
255.59 +
255.60 +in
255.61 +
255.62 +fun prover_tac ctxt opt_lim =
255.63 + SELECT_GOAL (DEEPEN (2, the_default 20 opt_lim) (intprover_tac ctxt [] 0) 4 1);
255.64 +
255.65 +end;
255.66 +
255.67 +
255.68 +(* method setup *)
255.69 +
255.70 +local
255.71 +
255.72 +val introN = "intro";
255.73 +val elimN = "elim";
255.74 +val destN = "dest";
255.75 +val ruleN = "rule";
255.76 +
255.77 +fun modifier name kind kind' att =
255.78 + Args.$$$ name |-- (kind >> K NONE || kind' |-- OuterParse.nat --| Args.colon >> SOME)
255.79 + >> (pair (I: Proof.context -> Proof.context) o att);
255.80 +
255.81 +val modifiers =
255.82 + [modifier destN Args.bang_colon Args.bang ContextRules.dest_bang,
255.83 + modifier destN Args.colon (Scan.succeed ()) ContextRules.dest,
255.84 + modifier elimN Args.bang_colon Args.bang ContextRules.elim_bang,
255.85 + modifier elimN Args.colon (Scan.succeed ()) ContextRules.elim,
255.86 + modifier introN Args.bang_colon Args.bang ContextRules.intro_bang,
255.87 + modifier introN Args.colon (Scan.succeed ()) ContextRules.intro,
255.88 + Args.del -- Args.colon >> K (I, ContextRules.rule_del)];
255.89 +
255.90 +val method =
255.91 + Method.bang_sectioned_args' modifiers (Scan.lift (Scan.option OuterParse.nat))
255.92 + (fn n => fn prems => fn ctxt => Method.METHOD (fn facts =>
255.93 + HEADGOAL (Method.insert_tac (prems @ facts) THEN'
255.94 + ObjectLogic.atomize_prems_tac THEN' prover_tac ctxt n)));
255.95 +
255.96 +in
255.97 +
255.98 +fun method_setup name = Method.add_method (name, method, "intuitionistic proof search");
255.99 +
255.100 +end;
255.101 +
255.102 +end;
255.103 +
256.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
256.2 +++ b/src/Tools/project_rule.ML Wed Mar 04 11:05:29 2009 +0100
256.3 @@ -0,0 +1,65 @@
256.4 +(* Title: Tools/project_rule.ML
256.5 + Author: Makarius
256.6 +
256.7 +Transform mutual rule:
256.8 +
256.9 + HH ==> (x1:A1 --> P1 x1) & ... & (xn:An --> Pn xn)
256.10 +
256.11 +into projection:
256.12 +
256.13 + xi:Ai ==> HH ==> Pi xi
256.14 +*)
256.15 +
256.16 +signature PROJECT_RULE_DATA =
256.17 +sig
256.18 + val conjunct1: thm
256.19 + val conjunct2: thm
256.20 + val mp: thm
256.21 +end;
256.22 +
256.23 +signature PROJECT_RULE =
256.24 +sig
256.25 + val project: Proof.context -> int -> thm -> thm
256.26 + val projects: Proof.context -> int list -> thm -> thm list
256.27 + val projections: Proof.context -> thm -> thm list
256.28 +end;
256.29 +
256.30 +functor ProjectRuleFun(Data: PROJECT_RULE_DATA): PROJECT_RULE =
256.31 +struct
256.32 +
256.33 +fun conj1 th = th RS Data.conjunct1;
256.34 +fun conj2 th = th RS Data.conjunct2;
256.35 +fun imp th = th RS Data.mp;
256.36 +
256.37 +fun projects ctxt is raw_rule =
256.38 + let
256.39 + fun proj 1 th = the_default th (try conj1 th)
256.40 + | proj k th = proj (k - 1) (conj2 th);
256.41 + fun prems k th =
256.42 + (case try imp th of
256.43 + NONE => (k, th)
256.44 + | SOME th' => prems (k + 1) th');
256.45 + val ((_, [rule]), ctxt') = Variable.import_thms true [raw_rule] ctxt;
256.46 + fun result i =
256.47 + rule
256.48 + |> proj i
256.49 + |> prems 0 |-> (fn k =>
256.50 + Thm.permute_prems 0 (~ k)
256.51 + #> singleton (Variable.export ctxt' ctxt)
256.52 + #> Drule.zero_var_indexes
256.53 + #> RuleCases.save raw_rule
256.54 + #> RuleCases.add_consumes k);
256.55 + in map result is end;
256.56 +
256.57 +fun project ctxt i th = hd (projects ctxt [i] th);
256.58 +
256.59 +fun projections ctxt raw_rule =
256.60 + let
256.61 + fun projs k th =
256.62 + (case try conj2 th of
256.63 + NONE => k
256.64 + | SOME th' => projs (k + 1) th');
256.65 + val ((_, [rule]), _) = Variable.import_thms true [raw_rule] ctxt;
256.66 + in projects ctxt (1 upto projs 1 rule) raw_rule end;
256.67 +
256.68 +end;