Merged.
authorballarin
Tue, 30 Dec 2008 11:10:01 +0100
changeset 29252ea97aa6aeba2
parent 29251 8f84a608883d
parent 29205 7dc7a75033ea
child 29253 3c6cd80a4854
child 29254 ef3e2c3399d7
child 29332 edc1e2a56398
Merged.
etc/isar-keywords-ZF.el
etc/isar-keywords.el
src/HOL/Complex/Fundamental_Theorem_Algebra.thy
src/HOL/Complex/README.html
src/HOL/Complex/document/root.tex
src/HOL/Dense_Linear_Order.thy
src/HOL/Divides.thy
src/HOL/HahnBanach/Bounds.thy
src/HOL/HahnBanach/FunctionNorm.thy
src/HOL/HahnBanach/HahnBanach.thy
src/HOL/HahnBanach/HahnBanachExtLemmas.thy
src/HOL/HahnBanach/HahnBanachSupLemmas.thy
src/HOL/HahnBanach/Linearform.thy
src/HOL/HahnBanach/NormedSpace.thy
src/HOL/HahnBanach/Subspace.thy
src/HOL/HahnBanach/VectorSpace.thy
src/HOL/HahnBanach/ZornLemma.thy
src/HOL/Hyperreal/SEQ.thy
src/HOL/Library/Dense_Linear_Order.thy
src/HOL/Library/Multiset.thy
src/HOL/Real/HahnBanach/Bounds.thy
src/HOL/Real/HahnBanach/FunctionNorm.thy
src/HOL/Real/HahnBanach/FunctionOrder.thy
src/HOL/Real/HahnBanach/HahnBanach.thy
src/HOL/Real/HahnBanach/HahnBanachExtLemmas.thy
src/HOL/Real/HahnBanach/HahnBanachLemmas.thy
src/HOL/Real/HahnBanach/HahnBanachSupLemmas.thy
src/HOL/Real/HahnBanach/Linearform.thy
src/HOL/Real/HahnBanach/NormedSpace.thy
src/HOL/Real/HahnBanach/README.html
src/HOL/Real/HahnBanach/ROOT.ML
src/HOL/Real/HahnBanach/Subspace.thy
src/HOL/Real/HahnBanach/VectorSpace.thy
src/HOL/Real/HahnBanach/ZornLemma.thy
src/HOL/Real/HahnBanach/document/root.bib
src/HOL/Real/HahnBanach/document/root.tex
src/HOL/Real/RealVector.thy
src/HOL/RealVector.thy
src/HOL/ex/LexOrds.thy
src/HOLCF/Algebraic.thy
src/HOLCF/Bifinite.thy
src/HOLCF/CompactBasis.thy
src/HOLCF/Completion.thy
src/HOLCF/ConvexPD.thy
src/HOLCF/Deflation.thy
src/HOLCF/LowerPD.thy
src/HOLCF/Universal.thy
src/HOLCF/UpperPD.thy
src/Pure/Concurrent/schedule.ML
src/Pure/IsaMakefile
src/Pure/Isar/theory_target.ML
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/Admin/MacOS/README	Tue Dec 30 11:10:01 2008 +0100
     1.3 @@ -0,0 +1,17 @@
     1.4 +Isabelle application bundle for MacOS
     1.5 +=====================================
     1.6 +
     1.7 +Requirements:
     1.8 +
     1.9 +* CocoaDialog http://cocoadialog.sourceforge.net/
    1.10 +
    1.11 +* Platypus http://www.sveinbjorn.org/platypus
    1.12 +
    1.13 +* AppHack 1.1 http://www.sveinbjorn.org/apphack
    1.14 +
    1.15 +  Manual setup:
    1.16 +    File type: "Isabelle theory"
    1.17 +    Icon: "theory.icns"
    1.18 +    "Editor"
    1.19 +    Suffixes: "thy"
    1.20 +
     2.1 Binary file Admin/MacOS/isabelle.icns has changed
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/Admin/MacOS/mk	Tue Dec 30 11:10:01 2008 +0100
     3.3 @@ -0,0 +1,19 @@
     3.4 +#!/bin/bash
     3.5 +#
     3.6 +# Make Isabelle application bundle
     3.7 +
     3.8 +THIS="$(cd "$(dirname "$0")"; pwd)"
     3.9 +
    3.10 +PLATYPUS_APP="/Applications/Platypus-4.0/Platypus.app"
    3.11 +COCOADIALOG_APP="/Applications/CocoaDialog.app"
    3.12 +
    3.13 +"$PLATYPUS_APP/Contents/Resources/platypus" \
    3.14 +  -a Isabelle -u Isabelle \
    3.15 +  -I "de.tum.in.isabelle" \
    3.16 +  -i "$THIS/isabelle.icns" \
    3.17 +  -D -X thy \
    3.18 +  -p /bin/bash \
    3.19 +  -c "$THIS/script" \
    3.20 +  -o None \
    3.21 +  -f "$COCOADIALOG_APP" \
    3.22 +  "$PWD/Isabelle.app"
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/Admin/MacOS/script	Tue Dec 30 11:10:01 2008 +0100
     4.3 @@ -0,0 +1,78 @@
     4.4 +#!/bin/bash
     4.5 +#
     4.6 +# Author: Makarius
     4.7 +#
     4.8 +# Isabelle application wrapper
     4.9 +
    4.10 +THIS="$(cd "$(dirname "$0")"; pwd)"
    4.11 +THIS_APP="$(cd "$THIS/../.."; pwd)"
    4.12 +SUPER_APP="$(cd "$THIS/../../.."; pwd)"
    4.13 +
    4.14 +
    4.15 +# sane environment defaults
    4.16 +cd "$HOME"
    4.17 +PATH="$PATH:/opt/local/bin"
    4.18 +
    4.19 +
    4.20 +# settings support
    4.21 +
    4.22 +function choosefrom ()
    4.23 +{
    4.24 +  local RESULT=""
    4.25 +  local FILE=""
    4.26 +
    4.27 +  for FILE in "$@"
    4.28 +  do
    4.29 +    [ -z "$RESULT" -a -e "$FILE" ] && RESULT="$FILE"
    4.30 +  done
    4.31 +
    4.32 +  [ -z "$RESULT" ] && RESULT="$FILE"
    4.33 +  echo "$RESULT"
    4.34 +}
    4.35 +
    4.36 +
    4.37 +# Isabelle
    4.38 +
    4.39 +ISABELLE_TOOL="$(choosefrom \
    4.40 +  "$THIS/Isabelle/bin/isabelle" \
    4.41 +  "$SUPER_APP/Isabelle/bin/isabelle" \
    4.42 +  "$HOME/bin/isabelle" \
    4.43 +  isabelle)"
    4.44 +
    4.45 +
    4.46 +# Proof General / Emacs
    4.47 +
    4.48 +PROOFGENERAL_EMACS="$(choosefrom \
    4.49 +  "$THIS/Emacs.app/Contents/MacOS/Emacs" \
    4.50 +  "$SUPER_APP/Emacs.app/Contents/MacOS/Emacs" \
    4.51 +  /Applications/Emacs.app/Contents/MacOS/Emacs \
    4.52 +  "")"
    4.53 +
    4.54 +if [ -n "$PROOFGENERAL_EMACS" ]; then
    4.55 +  PROOFGENERAL_OPTIONS="-p $PROOFGENERAL_EMACS $PROOFGENERAL_OPTIONS"
    4.56 +fi
    4.57 +
    4.58 +
    4.59 +# run interface with error feedback
    4.60 +
    4.61 +OUTPUT="/tmp/isabelle$$.out"
    4.62 +
    4.63 +( "$HOME/bin/isabelle" emacs "$@" ) > "$OUTPUT" 2>&1
    4.64 +RC=$?
    4.65 +
    4.66 +if [ "$RC" != 0 ]; then
    4.67 +  echo >> "$OUTPUT"
    4.68 +  echo "Return code: $RC" >> "$OUTPUT"
    4.69 +fi
    4.70 +
    4.71 +if [ $(stat -f "%z" "$OUTPUT") != 0 ]; then
    4.72 +  "$THIS/CocoaDialog.app/Contents/MacOS/CocoaDialog" textbox \
    4.73 +    --title "Isabelle" \
    4.74 +    --informative-text "Isabelle output" \
    4.75 +    --text-from-file "$OUTPUT" \
    4.76 +    --button1 "OK"
    4.77 +fi
    4.78 +
    4.79 +rm -f "$OUTPUT"
    4.80 +
    4.81 +exit "$RC"
     5.1 Binary file Admin/MacOS/theory.icns has changed
     6.1 --- a/Admin/Mercurial/isabelle-style.diff	Tue Dec 30 08:18:54 2008 +0100
     6.2 +++ b/Admin/Mercurial/isabelle-style.diff	Tue Dec 30 11:10:01 2008 +0100
     6.3 @@ -13,23 +13,22 @@
     6.4  > <div class="files">
     6.5  > #files#
     6.6  > </div>
     6.7 -Only in isabelle: filelog.tmpl~
     6.8 +diff -r gitweb/changeset.tmpl isabelle/changeset.tmpl
     6.9 +19c19
    6.10 +< <a class="title" href="{url}raw-rev/#node|short#">#desc|strip|escape|firstline# <span class="logtags">{inbranch%inbranchtag}{branches%branchtag}{tags%tagtag}</span></a>
    6.11 +---
    6.12 +> <a class="title" href="{url}raw-rev/#node|short#">#desc|strip|escape# <span class="logtags">{inbranch%inbranchtag}{branches%branchtag}{tags%tagtag}</span></a>
    6.13  diff -r gitweb/map isabelle/map
    6.14 -56,57c56,57
    6.15 +29c29
    6.16 +< annotateline = '<tr style="font-family:monospace" class="parity#parity#"><td class="linenr" style="text-align: right;"><a href="#url#annotate/#node|short#/#file|urlescape#{sessionvars%urlparameter}#l{targetline}" title="{node|short}: {desc|escape|firstline}">#author|user#@#rev#</a></td><td><pre><a class="linenr" href="##lineid#" id="#lineid#">#linenumber#</a></pre></td><td><pre>#line|escape#</pre></td></tr>'
    6.17 +---
    6.18 +> annotateline = '<tr style="font-family:monospace" class="parity#parity#"><td class="linenr" style="text-align: right;"><a href="#url#annotate/#node|short#/#file|urlescape#{sessionvars%urlparameter}#l{targetline}" title="{node|short}: {desc|escape}">#author|user#@#rev#</a></td><td><pre><a class="linenr" href="##lineid#" id="#lineid#">#linenumber#</a></pre></td><td><pre>#line|escape#</pre></td></tr>'
    6.19 +59,60c59,60
    6.20  < shortlogentry = '<tr class="parity#parity#"><td class="age"><i>#date|age# ago</i></td><td><i>#author|person#</i></td><td><a class="list" href="{url}rev/#node|short#{sessionvars%urlparameter}"><b>#desc|strip|firstline|escape#</b> <span class="logtags">{inbranch%inbranchtag}{branches%branchtag}{tags%tagtag}</span></a></td><td class="link" nowrap><a href="{url}rev/#node|short#{sessionvars%urlparameter}">changeset</a> | <a href="{url}file/#node|short#{sessionvars%urlparameter}">files</a></td></tr>'
    6.21  < filelogentry = '<tr class="parity#parity#"><td class="age"><i>#date|age# ago</i></td><td><a class="list" href="{url}rev/#node|short#{sessionvars%urlparameter}"><b>#desc|strip|firstline|escape#</b></a></td><td class="link"><a href="{url}file/#node|short#/#file|urlescape#{sessionvars%urlparameter}">file</a>&nbsp;|&nbsp;<a href="{url}diff/#node|short#/#file|urlescape#{sessionvars%urlparameter}">diff</a>&nbsp;|&nbsp;<a href="{url}annotate/#node|short#/#file|urlescape#{sessionvars%urlparameter}">annotate</a> #rename%filelogrename#</td></tr>'
    6.22  ---
    6.23  > shortlogentry = '<tr class="parity#parity#"><td class="age"><i>#date|age# ago</i></td><td><i>#date|shortdate#</i></td><td><i>#author|person#</i></td><td><a class="list" href="{url}rev/#node|short#{sessionvars%urlparameter}"><b>#desc|strip|escape#</b> <span class="logtags">{inbranch%inbranchtag}{branches%branchtag}{tags%tagtag}</span></a></td><td class="link" nowrap><a href="{url}rev/#node|short#{sessionvars%urlparameter}">changeset</a> | <a href="{url}file/#node|short#{sessionvars%urlparameter}">files</a></td></tr>'
    6.24  > filelogentry = '<tr class="parity#parity#"><td class="age"><i>#date|age# ago</i></td><td><i>#date|shortdate#</i></td><td><i>#author|person#</i></td><td><a class="list" href="{url}rev/#node|short#{sessionvars%urlparameter}"><b>#desc|strip|escape#</b></a></td><td class="link"><a href="{url}file/#node|short#/#file|urlescape#{sessionvars%urlparameter}">file</a>&nbsp;|&nbsp;<a href="{url}diff/#node|short#/#file|urlescape#{sessionvars%urlparameter}">diff</a>&nbsp;|&nbsp;<a href="{url}annotate/#node|short#/#file|urlescape#{sessionvars%urlparameter}">annotate</a> #rename%filelogrename#</td></tr>'
    6.25 -Only in isabelle: map~
    6.26  diff -r gitweb/summary.tmpl isabelle/summary.tmpl
    6.27 -33d32
    6.28 +34d33
    6.29  < <tr><td>owner</td><td>#owner|obfuscate#</td></tr>
    6.30 -49,55d47
    6.31 -< <div><a class="title" href="#">branches</a></div>
    6.32 -< <table cellspacing="0">
    6.33 -< {branches%branchentry}
    6.34 -< <tr class="light">
    6.35 -<   <td colspan="4"><a class="list"  href="#">...</a></td>
    6.36 -< </tr>
    6.37 -< </table>
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/Admin/Mercurial/misc.diff	Tue Dec 30 11:10:01 2008 +0100
     7.3 @@ -0,0 +1,20 @@
     7.4 +diff -r hgweb/webcommands.py hgweb/webcommands.py
     7.5 +653c653
     7.6 +<         desc = templatefilters.firstline(ctx.description())
     7.7 +---
     7.8 +>         desc = ctx.description()
     7.9 +diff -r templates/atom/changelogentry.tmpl templates/atom/changelogentry.tmpl
    7.10 +2c2
    7.11 +<   <title>#desc|strip|firstline|strip|escape#</title>
    7.12 +---
    7.13 +>   <title>#desc|strip|escape#</title>
    7.14 +diff -r templates/rss/changelogentry.tmpl templates/rss/changelogentry.tmpl
    7.15 +2c2
    7.16 +<     <title>#desc|strip|firstline|strip|escape#</title>
    7.17 +---
    7.18 +>     <title>#desc|strip|escape#</title>
    7.19 +diff -r templates/rss/filelogentry.tmpl templates/rss/filelogentry.tmpl
    7.20 +2c2
    7.21 +<     <title>#desc|strip|firstline|strip|escape#</title>
    7.22 +---
    7.23 +>     <title>#desc|strip|escape#</title>
     8.1 --- a/Admin/build	Tue Dec 30 08:18:54 2008 +0100
     8.2 +++ b/Admin/build	Tue Dec 30 11:10:01 2008 +0100
     8.3 @@ -7,7 +7,7 @@
     8.4  #paranoia setting for sunbroy
     8.5  PATH="/usr/local/dist/DIR/j2sdk1.5.0/bin:$PATH"
     8.6  
     8.7 -PATH="/home/scala/scala/bin:$PATH"
     8.8 +PATH="/home/scala/current/bin:$PATH"
     8.9  
    8.10  
    8.11  ## directory layout
    8.12 @@ -101,15 +101,6 @@
    8.13    pushd "$ISABELLE_HOME/src/Pure" >/dev/null
    8.14    "$ISABELLE_TOOL" make jar || fail "Failed to build Pure.jar!"
    8.15    popd >/dev/null
    8.16 -
    8.17 -  if [ -d "$HOME/lib/jedit/current" ]; then
    8.18 -    pushd "$ISABELLE_HOME/lib/jedit/plugin" >/dev/null
    8.19 -    ./mk
    8.20 -    [ -f ../isabelle.jar ] || fail "Failed to build jEdit plugin!"
    8.21 -    popd >/dev/null
    8.22 -  else
    8.23 -    echo "Warning: skipping jedit plugin"
    8.24 -  fi
    8.25  }
    8.26  
    8.27  
     9.1 --- a/Admin/isatest/settings/at-mac-poly-5.1-para	Tue Dec 30 08:18:54 2008 +0100
     9.2 +++ b/Admin/isatest/settings/at-mac-poly-5.1-para	Tue Dec 30 11:10:01 2008 +0100
     9.3 @@ -4,7 +4,7 @@
     9.4    ML_SYSTEM="polyml-5.2.1"
     9.5    ML_PLATFORM="x86-darwin"
     9.6    ML_HOME="$POLYML_HOME/$ML_PLATFORM"
     9.7 -  ML_OPTIONS="-H 2000"
     9.8 +  ML_OPTIONS="--immutable 800 --mutable 1200"
     9.9  
    9.10  
    9.11  ISABELLE_HOME_USER=~/isabelle-at-mac-poly-e
    10.1 --- a/CONTRIBUTORS	Tue Dec 30 08:18:54 2008 +0100
    10.2 +++ b/CONTRIBUTORS	Tue Dec 30 11:10:01 2008 +0100
    10.3 @@ -7,6 +7,9 @@
    10.4  Contributions to this Isabelle version
    10.5  --------------------------------------
    10.6  
    10.7 +* December 2008: Armin Heller, TUM and Alexander Krauss, TUM
    10.8 +  Method "sizechange" for advanced termination proofs.
    10.9 +
   10.10  * November 2008: Timothy Bourke, NICTA
   10.11    Performance improvement (factor 50) for find_theorems.
   10.12  
   10.13 @@ -204,5 +207,3 @@
   10.14  * 2004/2005: Tjark Weber, TUM
   10.15    SAT solver method using zChaff.
   10.16    Improved version of HOL/refute.
   10.17 -
   10.18 -$Id$
    11.1 --- a/INSTALL	Tue Dec 30 08:18:54 2008 +0100
    11.2 +++ b/INSTALL	Tue Dec 30 11:10:01 2008 +0100
    11.3 @@ -85,6 +85,3 @@
    11.4  Note that the site-wide Isabelle installation may already provide
    11.5  Isabelle executables in some global bin directory (such as
    11.6  /usr/local/bin).
    11.7 -
    11.8 -
    11.9 -$Id$
    12.1 --- a/NEWS	Tue Dec 30 08:18:54 2008 +0100
    12.2 +++ b/NEWS	Tue Dec 30 11:10:01 2008 +0100
    12.3 @@ -42,6 +42,11 @@
    12.4  ISABELLE_HOME_USER can be changed in Isabelle/etc/settings of any
    12.5  Isabelle distribution.
    12.6  
    12.7 +* Proofs of fully specified statements are run in parallel on
    12.8 +multi-core systems.  A speedup factor of 2-3 can be expected on a
    12.9 +regular 4-core machine, if the initial heap space is made reasonably
   12.10 +large (cf. Poly/ML option -H).  [Poly/ML 5.2.1 or later]
   12.11 +
   12.12  * The Isabelle System Manual (system) has been updated, with formally
   12.13  checked references as hyperlinks.
   12.14  
   12.15 @@ -55,8 +60,8 @@
   12.16  * Removed exotic 'token_translation' command.  INCOMPATIBILITY, use ML
   12.17  interface instead.
   12.18  
   12.19 -* There is a new lexical item "float" with syntax ["-"] digit+ "." digit+,
   12.20 -without spaces.
   12.21 +* There is a new syntactic category "float_const" for signed decimal
   12.22 +fractions (e.g. 123.45 or -123.45).
   12.23  
   12.24  
   12.25  *** Pure ***
   12.26 @@ -152,11 +157,12 @@
   12.27  
   12.28  *** HOL ***
   12.29  
   12.30 -* Made repository layout more coherent with logical
   12.31 -distribution structure:
   12.32 +* Made source layout more coherent with logical distribution
   12.33 +structure:
   12.34  
   12.35      src/HOL/Library/RType.thy ~> src/HOL/Typerep.thy
   12.36      src/HOL/Library/Code_Message.thy ~> src/HOL/
   12.37 +    src/HOL/Library/Dense_Linear_Order.thy ~> src/HOL/
   12.38      src/HOL/Library/GCD.thy ~> src/HOL/
   12.39      src/HOL/Library/Order_Relation.thy ~> src/HOL/
   12.40      src/HOL/Library/Parity.thy ~> src/HOL/
   12.41 @@ -172,6 +178,7 @@
   12.42      src/HOL/Complex/Complex_Main.thy ~> src/HOL/
   12.43      src/HOL/Complex/Complex.thy ~> src/HOL/
   12.44      src/HOL/Complex/FrechetDeriv.thy ~> src/HOL/
   12.45 +    src/HOL/Complex/Fundamental_Theorem_Algebra.thy ~> src/HOL/
   12.46      src/HOL/Hyperreal/Deriv.thy ~> src/HOL/
   12.47      src/HOL/Hyperreal/Fact.thy ~> src/HOL/
   12.48      src/HOL/Hyperreal/Integration.thy ~> src/HOL/
   12.49 @@ -181,9 +188,12 @@
   12.50      src/HOL/Hyperreal/MacLaurin.thy ~> src/HOL/
   12.51      src/HOL/Hyperreal/NthRoot.thy ~> src/HOL/
   12.52      src/HOL/Hyperreal/Series.thy ~> src/HOL/
   12.53 +    src/HOL/Hyperreal/SEQ.thy ~> src/HOL/
   12.54      src/HOL/Hyperreal/Taylor.thy ~> src/HOL/
   12.55      src/HOL/Hyperreal/Transcendental.thy ~> src/HOL/
   12.56      src/HOL/Real/Float ~> src/HOL/Library/
   12.57 +    src/HOL/Real/HahnBanach ~> src/HOL/HahnBanach
   12.58 +    src/HOL/Real/RealVector.thy ~> src/HOL/
   12.59  
   12.60      src/HOL/arith_data.ML ~> src/HOL/Tools
   12.61      src/HOL/hologic.ML ~> src/HOL/Tools
   12.62 @@ -239,6 +249,10 @@
   12.63  mechanisms may be specified (currently, [SML], [code] or [nbe]).  See
   12.64  further src/HOL/ex/Eval_Examples.thy.
   12.65  
   12.66 +* New method "sizechange" to automate termination proofs using (a
   12.67 +modification of) the size-change principle. Requires SAT solver. See
   12.68 +src/HOL/ex/Termination.thy for examples.
   12.69 +
   12.70  * HOL/Orderings: class "wellorder" moved here, with explicit induction
   12.71  rule "less_induct" as assumption.  For instantiation of "wellorder" by
   12.72  means of predicate "wf", use rule wf_wellorderI.  INCOMPATIBILITY.
   12.73 @@ -388,6 +402,14 @@
   12.74  
   12.75  *** ML ***
   12.76  
   12.77 +* High-level support for concurrent ML programming, see
   12.78 +src/Pure/Cuncurrent.  The data-oriented model of "future values" is
   12.79 +particularly convenient to organize independent functional
   12.80 +computations.  The concept of "synchronized variables" provides a
   12.81 +higher-order interface for components with shared state, avoiding the
   12.82 +delicate details of mutexes and condition variables.  [Poly/ML 5.2.1
   12.83 +or later]
   12.84 +
   12.85  * Simplified ML oracle interface Thm.add_oracle promotes 'a -> cterm
   12.86  to 'a -> thm, while results are always tagged with an authentic oracle
   12.87  name.  The Isar command 'oracle' is now polymorphic, no argument type
   12.88 @@ -857,8 +879,8 @@
   12.89  print_mode_active, PrintMode.setmp etc.  INCOMPATIBILITY.
   12.90  
   12.91  * Functions system/system_out provide a robust way to invoke external
   12.92 -shell commands, with propagation of interrupts (requires Poly/ML 5.2).
   12.93 -Do not use OS.Process.system etc. from the basis library!
   12.94 +shell commands, with propagation of interrupts (requires Poly/ML
   12.95 +5.2.1).  Do not use OS.Process.system etc. from the basis library!
   12.96  
   12.97  
   12.98  *** System ***
   12.99 @@ -5953,6 +5975,3 @@
  12.100  types;
  12.101  
  12.102  :mode=text:wrap=hard:maxLineLen=72:
  12.103 -
  12.104 -
  12.105 -$Id$
    13.1 --- a/build	Tue Dec 30 08:18:54 2008 +0100
    13.2 +++ b/build	Tue Dec 30 11:10:01 2008 +0100
    13.3 @@ -1,6 +1,5 @@
    13.4  #!/usr/bin/env bash
    13.5  #
    13.6 -# $Id$
    13.7  # Author: Markus Wenzel, TU Muenchen
    13.8  #
    13.9  # build - compile the Isabelle system and object-logics
    14.1 --- a/doc-src/IsarAdvanced/Classes/style.sty	Tue Dec 30 08:18:54 2008 +0100
    14.2 +++ b/doc-src/IsarAdvanced/Classes/style.sty	Tue Dec 30 11:10:01 2008 +0100
    14.3 @@ -30,7 +30,7 @@
    14.4  
    14.5  \pagestyle{headings}
    14.6  \binperiod
    14.7 -\underscoreon
    14.8 +\underscoreoff
    14.9  
   14.10  \renewcommand{\isadigit}[1]{\isamath{#1}}
   14.11  
    15.1 --- a/doc-src/IsarAdvanced/Codegen/style.sty	Tue Dec 30 08:18:54 2008 +0100
    15.2 +++ b/doc-src/IsarAdvanced/Codegen/style.sty	Tue Dec 30 11:10:01 2008 +0100
    15.3 @@ -42,7 +42,7 @@
    15.4  
    15.5  \pagestyle{headings}
    15.6  \binperiod
    15.7 -\underscoreon
    15.8 +\underscoreoff
    15.9  
   15.10  \renewcommand{\isadigit}[1]{\isamath{#1}}
   15.11  
    16.1 --- a/doc-src/IsarImplementation/Thy/ML.thy	Tue Dec 30 08:18:54 2008 +0100
    16.2 +++ b/doc-src/IsarImplementation/Thy/ML.thy	Tue Dec 30 11:10:01 2008 +0100
    16.3 @@ -107,18 +107,23 @@
    16.4  section {* Thread-safe programming *}
    16.5  
    16.6  text {*
    16.7 -  Recent versions of Poly/ML (5.2 or later) support multithreaded
    16.8 -  execution based on native operating system threads of the underlying
    16.9 -  platform.  Thus threads will actually be executed in parallel on
   16.10 -  multi-core systems.  A speedup-factor of approximately 2--4 can be
   16.11 -  expected for large well-structured Isabelle sessions, where theories
   16.12 -  are organized as a graph with sufficiently many independent nodes.
   16.13 +  Recent versions of Poly/ML (5.2.1 or later) support robust
   16.14 +  multithreaded execution, based on native operating system threads of
   16.15 +  the underlying platform.  Thus threads will actually be executed in
   16.16 +  parallel on multi-core systems.  A speedup-factor of approximately
   16.17 +  1.5--3 can be expected on a regular 4-core machine.\footnote{There
   16.18 +  is some inherent limitation of the speedup factor due to garbage
   16.19 +  collection, which is still sequential.  It helps to provide initial
   16.20 +  heap space generously, using the \texttt{-H} option of Poly/ML.}
   16.21 +  Threads also help to organize advanced operations of the system,
   16.22 +  with explicit communication between sub-components, real-time
   16.23 +  conditions, time-outs etc.
   16.24  
   16.25 -  Threads lack the memory protection of separate processes, but
   16.26 +  Threads lack the memory protection of separate processes, and
   16.27    operate concurrently on shared heap memory.  This has the advantage
   16.28    that results of independent computations are immediately available
   16.29 -  to other threads, without requiring explicit communication,
   16.30 -  reloading, or even recoding of data.
   16.31 +  to other threads, without requiring untyped character streams,
   16.32 +  awkward serialization etc.
   16.33  
   16.34    On the other hand, some programming guidelines need to be observed
   16.35    in order to make unprotected parallelism work out smoothly.  While
   16.36 @@ -143,27 +148,29 @@
   16.37  
   16.38    \end{itemize}
   16.39  
   16.40 -  Note that ML bindings within the toplevel environment (@{verbatim
   16.41 -  "type"}, @{verbatim val}, @{verbatim "structure"} etc.) due to
   16.42 -  run-time invocation of the compiler are non-critical, because
   16.43 -  Isabelle/Isar incorporates such bindings within the theory or proof
   16.44 -  context.
   16.45 -
   16.46    The majority of tools implemented within the Isabelle/Isar framework
   16.47    will not require any of these critical elements: nothing special
   16.48    needs to be observed when staying in the purely functional fragment
   16.49    of ML.  Note that output via the official Isabelle channels does not
   16.50 -  even count as direct I/O in the above sense, so the operations @{ML
   16.51 -  "writeln"}, @{ML "warning"}, @{ML "tracing"} etc.\ are safe.
   16.52 +  count as direct I/O, so the operations @{ML "writeln"}, @{ML
   16.53 +  "warning"}, @{ML "tracing"} etc.\ are safe.
   16.54  
   16.55 -  \paragraph{Multithreading in Isabelle/Isar.}  Our parallel execution
   16.56 -  model is centered around the theory loader.  Whenever a given
   16.57 -  subgraph of theories needs to be updated, the system schedules a
   16.58 -  number of threads to process the sources as required, while
   16.59 -  observing their dependencies.  Thus concurrency is limited to
   16.60 -  independent nodes according to the theory import relation.
   16.61 +  Moreover, ML bindings within the toplevel environment (@{verbatim
   16.62 +  "type"}, @{verbatim val}, @{verbatim "structure"} etc.) due to
   16.63 +  run-time invocation of the compiler are also safe, because
   16.64 +  Isabelle/Isar manages this as part of the theory or proof context.
   16.65  
   16.66 -  Any user-code that works relatively to the present background theory
   16.67 +  \paragraph{Multithreading in Isabelle/Isar.}  The theory loader
   16.68 +  automatically exploits the overall parallelism of independent nodes
   16.69 +  in the development graph, as well as the inherent irrelevance of
   16.70 +  proofs for goals being fully specified in advance.  This means,
   16.71 +  checking of individual Isar proofs is parallelized by default.
   16.72 +  Beyond that, very sophisticated proof tools may use local
   16.73 +  parallelism internally, via the general programming model of
   16.74 +  ``future values'' (see also @{"file"
   16.75 +  "~~/src/Pure/Concurrent/future.ML"}).
   16.76 +
   16.77 +  Any ML code that works relatively to the present background theory
   16.78    is already safe.  Contextual data may be easily stored within the
   16.79    theory or proof context, thanks to the generic data concept of
   16.80    Isabelle/Isar (see \secref{sec:context-data}).  This greatly
   16.81 @@ -179,9 +186,13 @@
   16.82    quickly, otherwise parallel execution performance may degrade
   16.83    significantly.
   16.84  
   16.85 -  Despite this potential bottle-neck, we refrain from fine-grained
   16.86 -  locking mechanism within user-code: the restriction to a single lock
   16.87 -  prevents deadlocks without demanding special precautions.
   16.88 +  Despite this potential bottle-neck, centralized locking is
   16.89 +  convenient, because it prevents deadlocks without demanding special
   16.90 +  precautions.  Explicit communication demands other means, though.
   16.91 +  The high-level abstraction of synchronized variables @{"file"
   16.92 +  "~~/src/Pure/Concurrent/synchronized.ML"} enables parallel
   16.93 +  components to communicate via shared state; see also @{"file"
   16.94 +  "~~/src/Pure/Concurrent/mailbox.ML"} as canonical example.
   16.95  
   16.96    \paragraph{Good conduct of impure programs.} The following
   16.97    guidelines enable non-functional programs to participate in
    17.1 --- a/doc-src/IsarImplementation/Thy/document/ML.tex	Tue Dec 30 08:18:54 2008 +0100
    17.2 +++ b/doc-src/IsarImplementation/Thy/document/ML.tex	Tue Dec 30 11:10:01 2008 +0100
    17.3 @@ -128,18 +128,23 @@
    17.4  \isamarkuptrue%
    17.5  %
    17.6  \begin{isamarkuptext}%
    17.7 -Recent versions of Poly/ML (5.2 or later) support multithreaded
    17.8 -  execution based on native operating system threads of the underlying
    17.9 -  platform.  Thus threads will actually be executed in parallel on
   17.10 -  multi-core systems.  A speedup-factor of approximately 2--4 can be
   17.11 -  expected for large well-structured Isabelle sessions, where theories
   17.12 -  are organized as a graph with sufficiently many independent nodes.
   17.13 +Recent versions of Poly/ML (5.2.1 or later) support robust
   17.14 +  multithreaded execution, based on native operating system threads of
   17.15 +  the underlying platform.  Thus threads will actually be executed in
   17.16 +  parallel on multi-core systems.  A speedup-factor of approximately
   17.17 +  1.5--3 can be expected on a regular 4-core machine.\footnote{There
   17.18 +  is some inherent limitation of the speedup factor due to garbage
   17.19 +  collection, which is still sequential.  It helps to provide initial
   17.20 +  heap space generously, using the \texttt{-H} option of Poly/ML.}
   17.21 +  Threads also help to organize advanced operations of the system,
   17.22 +  with explicit communication between sub-components, real-time
   17.23 +  conditions, time-outs etc.
   17.24  
   17.25 -  Threads lack the memory protection of separate processes, but
   17.26 +  Threads lack the memory protection of separate processes, and
   17.27    operate concurrently on shared heap memory.  This has the advantage
   17.28    that results of independent computations are immediately available
   17.29 -  to other threads, without requiring explicit communication,
   17.30 -  reloading, or even recoding of data.
   17.31 +  to other threads, without requiring untyped character streams,
   17.32 +  awkward serialization etc.
   17.33  
   17.34    On the other hand, some programming guidelines need to be observed
   17.35    in order to make unprotected parallelism work out smoothly.  While
   17.36 @@ -163,25 +168,26 @@
   17.37  
   17.38    \end{itemize}
   17.39  
   17.40 -  Note that ML bindings within the toplevel environment (\verb|type|, \verb|val|, \verb|structure| etc.) due to
   17.41 -  run-time invocation of the compiler are non-critical, because
   17.42 -  Isabelle/Isar incorporates such bindings within the theory or proof
   17.43 -  context.
   17.44 -
   17.45    The majority of tools implemented within the Isabelle/Isar framework
   17.46    will not require any of these critical elements: nothing special
   17.47    needs to be observed when staying in the purely functional fragment
   17.48    of ML.  Note that output via the official Isabelle channels does not
   17.49 -  even count as direct I/O in the above sense, so the operations \verb|writeln|, \verb|warning|, \verb|tracing| etc.\ are safe.
   17.50 +  count as direct I/O, so the operations \verb|writeln|, \verb|warning|, \verb|tracing| etc.\ are safe.
   17.51  
   17.52 -  \paragraph{Multithreading in Isabelle/Isar.}  Our parallel execution
   17.53 -  model is centered around the theory loader.  Whenever a given
   17.54 -  subgraph of theories needs to be updated, the system schedules a
   17.55 -  number of threads to process the sources as required, while
   17.56 -  observing their dependencies.  Thus concurrency is limited to
   17.57 -  independent nodes according to the theory import relation.
   17.58 +  Moreover, ML bindings within the toplevel environment (\verb|type|, \verb|val|, \verb|structure| etc.) due to
   17.59 +  run-time invocation of the compiler are also safe, because
   17.60 +  Isabelle/Isar manages this as part of the theory or proof context.
   17.61  
   17.62 -  Any user-code that works relatively to the present background theory
   17.63 +  \paragraph{Multithreading in Isabelle/Isar.}  The theory loader
   17.64 +  automatically exploits the overall parallelism of independent nodes
   17.65 +  in the development graph, as well as the inherent irrelevance of
   17.66 +  proofs for goals being fully specified in advance.  This means,
   17.67 +  checking of individual Isar proofs is parallelized by default.
   17.68 +  Beyond that, very sophisticated proof tools may use local
   17.69 +  parallelism internally, via the general programming model of
   17.70 +  ``future values'' (see also \hyperlink{file.~~/src/Pure/Concurrent/future.ML}{\mbox{\isa{\isatt{{\isachartilde}{\isachartilde}{\isacharslash}src{\isacharslash}Pure{\isacharslash}Concurrent{\isacharslash}future{\isachardot}ML}}}}).
   17.71 +
   17.72 +  Any ML code that works relatively to the present background theory
   17.73    is already safe.  Contextual data may be easily stored within the
   17.74    theory or proof context, thanks to the generic data concept of
   17.75    Isabelle/Isar (see \secref{sec:context-data}).  This greatly
   17.76 @@ -197,9 +203,11 @@
   17.77    quickly, otherwise parallel execution performance may degrade
   17.78    significantly.
   17.79  
   17.80 -  Despite this potential bottle-neck, we refrain from fine-grained
   17.81 -  locking mechanism within user-code: the restriction to a single lock
   17.82 -  prevents deadlocks without demanding special precautions.
   17.83 +  Despite this potential bottle-neck, centralized locking is
   17.84 +  convenient, because it prevents deadlocks without demanding special
   17.85 +  precautions.  Explicit communication demands other means, though.
   17.86 +  The high-level abstraction of synchronized variables \hyperlink{file.~~/src/Pure/Concurrent/synchronized.ML}{\mbox{\isa{\isatt{{\isachartilde}{\isachartilde}{\isacharslash}src{\isacharslash}Pure{\isacharslash}Concurrent{\isacharslash}synchronized{\isachardot}ML}}}} enables parallel
   17.87 +  components to communicate via shared state; see also \hyperlink{file.~~/src/Pure/Concurrent/mailbox.ML}{\mbox{\isa{\isatt{{\isachartilde}{\isachartilde}{\isacharslash}src{\isacharslash}Pure{\isacharslash}Concurrent{\isacharslash}mailbox{\isachardot}ML}}}} as canonical example.
   17.88  
   17.89    \paragraph{Good conduct of impure programs.} The following
   17.90    guidelines enable non-functional programs to participate in
    18.1 --- a/doc-src/IsarRef/Thy/HOL_Specific.thy	Tue Dec 30 08:18:54 2008 +0100
    18.2 +++ b/doc-src/IsarRef/Thy/HOL_Specific.thy	Tue Dec 30 11:10:01 2008 +0100
    18.3 @@ -804,12 +804,15 @@
    18.4      @{command_def (HOL) "print_atps"}@{text "\<^sup>*"} & : & @{text "context \<rightarrow>"} \\
    18.5      @{command_def (HOL) "atp_info"}@{text "\<^sup>*"} & : & @{text "any \<rightarrow>"} \\
    18.6      @{command_def (HOL) "atp_kill"}@{text "\<^sup>*"} & : & @{text "any \<rightarrow>"} \\
    18.7 +    @{command_def (HOL) "atp_messages"}@{text "\<^sup>*"} & : & @{text "any \<rightarrow>"} \\
    18.8      @{method_def (HOL) metis} & : & @{text method} \\
    18.9    \end{matharray}
   18.10  
   18.11    \begin{rail}
   18.12    'sledgehammer' (nameref *)
   18.13    ;
   18.14 +  'atp\_messages' ('(' nat ')')?
   18.15 +  ;
   18.16  
   18.17    'metis' thmrefs
   18.18    ;
   18.19 @@ -842,6 +845,12 @@
   18.20    \item @{command (HOL) atp_kill} terminates all presently running
   18.21    provers.
   18.22  
   18.23 +  \item @{command (HOL) atp_messages} displays recent messages issued
   18.24 +  by automated theorem provers.  This allows to examine results that
   18.25 +  might have got lost due to the asynchronous nature of default
   18.26 +  @{command (HOL) sledgehammer} output.  An optional message limit may
   18.27 +  be specified (default 5).
   18.28 +
   18.29    \item @{method (HOL) metis}~@{text "facts"} invokes the Metis prover
   18.30    with the given facts.  Metis is an automated proof tool of medium
   18.31    strength, but is fully integrated into Isabelle/HOL, with explicit
    19.1 --- a/doc-src/IsarRef/Thy/Inner_Syntax.thy	Tue Dec 30 08:18:54 2008 +0100
    19.2 +++ b/doc-src/IsarRef/Thy/Inner_Syntax.thy	Tue Dec 30 11:10:01 2008 +0100
    19.3 @@ -683,17 +683,23 @@
    19.4      @{syntax_def (inner) tid} & = & @{syntax_ref typefree} \\
    19.5      @{syntax_def (inner) tvar} & = & @{syntax_ref typevar} \\
    19.6      @{syntax_def (inner) num} & = & @{syntax_ref nat}@{text "  |  "}@{verbatim "-"}@{syntax_ref nat} \\
    19.7 +    @{syntax_def (inner) float_token} & = & @{syntax_ref nat}@{verbatim "."}@{syntax_ref nat}@{text "  |  "}@{verbatim "-"}@{syntax_ref nat}@{verbatim "."}@{syntax_ref nat} \\
    19.8      @{syntax_def (inner) xnum} & = & @{verbatim "#"}@{syntax_ref nat}@{text "  |  "}@{verbatim "#-"}@{syntax_ref nat} \\
    19.9  
   19.10      @{syntax_def (inner) xstr} & = & @{verbatim "''"} @{text "\<dots>"} @{verbatim "''"} \\
   19.11    \end{supertabular}
   19.12    \end{center}
   19.13  
   19.14 -  The token categories @{syntax_ref (inner) num}, @{syntax_ref (inner)
   19.15 -  xnum}, and @{syntax_ref (inner) xstr} are not used in Pure.
   19.16 -  Object-logics may implement numerals and string constants by adding
   19.17 -  appropriate syntax declarations, together with some translation
   19.18 -  functions (e.g.\ see Isabelle/HOL).
   19.19 +  The token categories @{syntax (inner) num}, @{syntax (inner)
   19.20 +  float_token}, @{syntax (inner) xnum}, and @{syntax (inner) xstr} are
   19.21 +  not used in Pure.  Object-logics may implement numerals and string
   19.22 +  constants by adding appropriate syntax declarations, together with
   19.23 +  some translation functions (e.g.\ see Isabelle/HOL).
   19.24 +
   19.25 +  The derived categories @{syntax_def (inner) num_const} and
   19.26 +  @{syntax_def (inner) float_const} provide robust access to @{syntax
   19.27 +  (inner) num}, and @{syntax (inner) float_token}, respectively: the
   19.28 +  syntax tree holds a syntactic constant instead of a free variable.
   19.29  *}
   19.30  
   19.31  
    20.1 --- a/doc-src/IsarRef/Thy/document/HOL_Specific.tex	Tue Dec 30 08:18:54 2008 +0100
    20.2 +++ b/doc-src/IsarRef/Thy/document/HOL_Specific.tex	Tue Dec 30 11:10:01 2008 +0100
    20.3 @@ -814,12 +814,15 @@
    20.4      \indexdef{HOL}{command}{print\_atps}\hypertarget{command.HOL.print-atps}{\hyperlink{command.HOL.print-atps}{\mbox{\isa{\isacommand{print{\isacharunderscore}atps}}}}}\isa{{\isachardoublequote}\isactrlsup {\isacharasterisk}{\isachardoublequote}} & : & \isa{{\isachardoublequote}context\ {\isasymrightarrow}{\isachardoublequote}} \\
    20.5      \indexdef{HOL}{command}{atp\_info}\hypertarget{command.HOL.atp-info}{\hyperlink{command.HOL.atp-info}{\mbox{\isa{\isacommand{atp{\isacharunderscore}info}}}}}\isa{{\isachardoublequote}\isactrlsup {\isacharasterisk}{\isachardoublequote}} & : & \isa{{\isachardoublequote}any\ {\isasymrightarrow}{\isachardoublequote}} \\
    20.6      \indexdef{HOL}{command}{atp\_kill}\hypertarget{command.HOL.atp-kill}{\hyperlink{command.HOL.atp-kill}{\mbox{\isa{\isacommand{atp{\isacharunderscore}kill}}}}}\isa{{\isachardoublequote}\isactrlsup {\isacharasterisk}{\isachardoublequote}} & : & \isa{{\isachardoublequote}any\ {\isasymrightarrow}{\isachardoublequote}} \\
    20.7 +    \indexdef{HOL}{command}{atp\_messages}\hypertarget{command.HOL.atp-messages}{\hyperlink{command.HOL.atp-messages}{\mbox{\isa{\isacommand{atp{\isacharunderscore}messages}}}}}\isa{{\isachardoublequote}\isactrlsup {\isacharasterisk}{\isachardoublequote}} & : & \isa{{\isachardoublequote}any\ {\isasymrightarrow}{\isachardoublequote}} \\
    20.8      \indexdef{HOL}{method}{metis}\hypertarget{method.HOL.metis}{\hyperlink{method.HOL.metis}{\mbox{\isa{metis}}}} & : & \isa{method} \\
    20.9    \end{matharray}
   20.10  
   20.11    \begin{rail}
   20.12    'sledgehammer' (nameref *)
   20.13    ;
   20.14 +  'atp\_messages' ('(' nat ')')?
   20.15 +  ;
   20.16  
   20.17    'metis' thmrefs
   20.18    ;
   20.19 @@ -850,6 +853,12 @@
   20.20    \item \hyperlink{command.HOL.atp-kill}{\mbox{\isa{\isacommand{atp{\isacharunderscore}kill}}}} terminates all presently running
   20.21    provers.
   20.22  
   20.23 +  \item \hyperlink{command.HOL.atp-messages}{\mbox{\isa{\isacommand{atp{\isacharunderscore}messages}}}} displays recent messages issued
   20.24 +  by automated theorem provers.  This allows to examine results that
   20.25 +  might have got lost due to the asynchronous nature of default
   20.26 +  \hyperlink{command.HOL.sledgehammer}{\mbox{\isa{\isacommand{sledgehammer}}}} output.  An optional message limit may
   20.27 +  be specified (default 5).
   20.28 +
   20.29    \item \hyperlink{method.HOL.metis}{\mbox{\isa{metis}}}~\isa{{\isachardoublequote}facts{\isachardoublequote}} invokes the Metis prover
   20.30    with the given facts.  Metis is an automated proof tool of medium
   20.31    strength, but is fully integrated into Isabelle/HOL, with explicit
    21.1 --- a/doc-src/IsarRef/Thy/document/Inner_Syntax.tex	Tue Dec 30 08:18:54 2008 +0100
    21.2 +++ b/doc-src/IsarRef/Thy/document/Inner_Syntax.tex	Tue Dec 30 11:10:01 2008 +0100
    21.3 @@ -702,16 +702,21 @@
    21.4      \indexdef{inner}{syntax}{tid}\hypertarget{syntax.inner.tid}{\hyperlink{syntax.inner.tid}{\mbox{\isa{tid}}}} & = & \indexref{}{syntax}{typefree}\hyperlink{syntax.typefree}{\mbox{\isa{typefree}}} \\
    21.5      \indexdef{inner}{syntax}{tvar}\hypertarget{syntax.inner.tvar}{\hyperlink{syntax.inner.tvar}{\mbox{\isa{tvar}}}} & = & \indexref{}{syntax}{typevar}\hyperlink{syntax.typevar}{\mbox{\isa{typevar}}} \\
    21.6      \indexdef{inner}{syntax}{num}\hypertarget{syntax.inner.num}{\hyperlink{syntax.inner.num}{\mbox{\isa{num}}}} & = & \indexref{}{syntax}{nat}\hyperlink{syntax.nat}{\mbox{\isa{nat}}}\isa{{\isachardoublequote}\ \ {\isacharbar}\ \ {\isachardoublequote}}\verb|-|\indexref{}{syntax}{nat}\hyperlink{syntax.nat}{\mbox{\isa{nat}}} \\
    21.7 +    \indexdef{inner}{syntax}{float\_token}\hypertarget{syntax.inner.float-token}{\hyperlink{syntax.inner.float-token}{\mbox{\isa{float{\isacharunderscore}token}}}} & = & \indexref{}{syntax}{nat}\hyperlink{syntax.nat}{\mbox{\isa{nat}}}\verb|.|\indexref{}{syntax}{nat}\hyperlink{syntax.nat}{\mbox{\isa{nat}}}\isa{{\isachardoublequote}\ \ {\isacharbar}\ \ {\isachardoublequote}}\verb|-|\indexref{}{syntax}{nat}\hyperlink{syntax.nat}{\mbox{\isa{nat}}}\verb|.|\indexref{}{syntax}{nat}\hyperlink{syntax.nat}{\mbox{\isa{nat}}} \\
    21.8      \indexdef{inner}{syntax}{xnum}\hypertarget{syntax.inner.xnum}{\hyperlink{syntax.inner.xnum}{\mbox{\isa{xnum}}}} & = & \verb|#|\indexref{}{syntax}{nat}\hyperlink{syntax.nat}{\mbox{\isa{nat}}}\isa{{\isachardoublequote}\ \ {\isacharbar}\ \ {\isachardoublequote}}\verb|#-|\indexref{}{syntax}{nat}\hyperlink{syntax.nat}{\mbox{\isa{nat}}} \\
    21.9  
   21.10      \indexdef{inner}{syntax}{xstr}\hypertarget{syntax.inner.xstr}{\hyperlink{syntax.inner.xstr}{\mbox{\isa{xstr}}}} & = & \verb|''| \isa{{\isachardoublequote}{\isasymdots}{\isachardoublequote}} \verb|''| \\
   21.11    \end{supertabular}
   21.12    \end{center}
   21.13  
   21.14 -  The token categories \indexref{inner}{syntax}{num}\hyperlink{syntax.inner.num}{\mbox{\isa{num}}}, \indexref{inner}{syntax}{xnum}\hyperlink{syntax.inner.xnum}{\mbox{\isa{xnum}}}, and \indexref{inner}{syntax}{xstr}\hyperlink{syntax.inner.xstr}{\mbox{\isa{xstr}}} are not used in Pure.
   21.15 -  Object-logics may implement numerals and string constants by adding
   21.16 -  appropriate syntax declarations, together with some translation
   21.17 -  functions (e.g.\ see Isabelle/HOL).%
   21.18 +  The token categories \hyperlink{syntax.inner.num}{\mbox{\isa{num}}}, \hyperlink{syntax.inner.float-token}{\mbox{\isa{float{\isacharunderscore}token}}}, \hyperlink{syntax.inner.xnum}{\mbox{\isa{xnum}}}, and \hyperlink{syntax.inner.xstr}{\mbox{\isa{xstr}}} are
   21.19 +  not used in Pure.  Object-logics may implement numerals and string
   21.20 +  constants by adding appropriate syntax declarations, together with
   21.21 +  some translation functions (e.g.\ see Isabelle/HOL).
   21.22 +
   21.23 +  The derived categories \indexdef{inner}{syntax}{num\_const}\hypertarget{syntax.inner.num-const}{\hyperlink{syntax.inner.num-const}{\mbox{\isa{num{\isacharunderscore}const}}}} and
   21.24 +  \indexdef{inner}{syntax}{float\_const}\hypertarget{syntax.inner.float-const}{\hyperlink{syntax.inner.float-const}{\mbox{\isa{float{\isacharunderscore}const}}}} provide robust access to \hyperlink{syntax.inner.num}{\mbox{\isa{num}}}, and \hyperlink{syntax.inner.float-token}{\mbox{\isa{float{\isacharunderscore}token}}}, respectively: the
   21.25 +  syntax tree holds a syntactic constant instead of a free variable.%
   21.26  \end{isamarkuptext}%
   21.27  \isamarkuptrue%
   21.28  %
    22.1 --- a/etc/isar-keywords-ZF.el	Tue Dec 30 08:18:54 2008 +0100
    22.2 +++ b/etc/isar-keywords-ZF.el	Tue Dec 30 11:10:01 2008 +0100
    22.3 @@ -200,7 +200,6 @@
    22.4      "use"
    22.5      "use_thy"
    22.6      "using"
    22.7 -    "value"
    22.8      "welcome"
    22.9      "with"
   22.10      "{"
   22.11 @@ -323,7 +322,6 @@
   22.12      "typ"
   22.13      "unused_thms"
   22.14      "use_thy"
   22.15 -    "value"
   22.16      "welcome"))
   22.17  
   22.18  (defconst isar-keywords-theory-begin
    23.1 --- a/etc/isar-keywords.el	Tue Dec 30 08:18:54 2008 +0100
    23.2 +++ b/etc/isar-keywords.el	Tue Dec 30 11:10:01 2008 +0100
    23.3 @@ -32,6 +32,7 @@
    23.4      "atom_decl"
    23.5      "atp_info"
    23.6      "atp_kill"
    23.7 +    "atp_messages"
    23.8      "automaton"
    23.9      "ax_specification"
   23.10      "axclass"
   23.11 @@ -334,6 +335,7 @@
   23.12      "ML_val"
   23.13      "atp_info"
   23.14      "atp_kill"
   23.15 +    "atp_messages"
   23.16      "cd"
   23.17      "class_deps"
   23.18      "code_deps"
    24.1 --- a/etc/proofgeneral-settings.el	Tue Dec 30 08:18:54 2008 +0100
    24.2 +++ b/etc/proofgeneral-settings.el	Tue Dec 30 11:10:01 2008 +0100
    24.3 @@ -1,6 +1,3 @@
    24.4 -;;;
    24.5 -;;; $Id$
    24.6 -;;;
    24.7  ;;; Options for Proof General
    24.8  
    24.9  ;; Examples for sensible settings:
    25.1 --- a/etc/settings	Tue Dec 30 08:18:54 2008 +0100
    25.2 +++ b/etc/settings	Tue Dec 30 11:10:01 2008 +0100
    25.3 @@ -1,5 +1,4 @@
    25.4  # -*- shell-script -*- :mode=shellscript:
    25.5 -# $Id$
    25.6  #
    25.7  # Isabelle settings -- site defaults.
    25.8  #
    25.9 @@ -202,9 +201,8 @@
   25.10    "/opt/ProofGeneral" \
   25.11    "")
   25.12  
   25.13 -PROOFGENERAL_EMACS=$(choosefrom /Applications/Emacs.app/Contents/MacOS/Emacs emacs22)
   25.14 -PROOFGENERAL_OPTIONS="-p $PROOFGENERAL_EMACS"
   25.15 -#PROOFGENERAL_OPTIONS="-m no_brackets -m no_type_brackets -x true -p $PROOFGENERAL_EMACS"
   25.16 +PROOFGENERAL_OPTIONS=""
   25.17 +#PROOFGENERAL_OPTIONS="-m no_brackets -m no_type_brackets"
   25.18  
   25.19  # Automatic setup of remote fonts
   25.20  #XSYMBOL_INSTALLFONTS="xset fp+ tcp/isafonts.informatik.tu-muenchen.de:7200"
    26.1 --- a/etc/symbols	Tue Dec 30 08:18:54 2008 +0100
    26.2 +++ b/etc/symbols	Tue Dec 30 11:10:01 2008 +0100
    26.3 @@ -1,4 +1,3 @@
    26.4 -# $Id$
    26.5  # Default interpretation of some Isabelle symbols
    26.6  
    26.7  \<zero>                 code: 0x01d7ec  font: Isabelle
    27.1 --- a/etc/user-settings.sample	Tue Dec 30 08:18:54 2008 +0100
    27.2 +++ b/etc/user-settings.sample	Tue Dec 30 11:10:01 2008 +0100
    27.3 @@ -1,5 +1,4 @@
    27.4  # -*- shell-script -*-
    27.5 -# $Id$
    27.6  #
    27.7  # Isabelle user settings sample -- for use in ~/.isabelle/etc/settings
    27.8  
    28.1 --- a/lib/Tools/browser	Tue Dec 30 08:18:54 2008 +0100
    28.2 +++ b/lib/Tools/browser	Tue Dec 30 11:10:01 2008 +0100
    28.3 @@ -1,6 +1,5 @@
    28.4  #!/usr/bin/env bash
    28.5  #
    28.6 -# $Id$
    28.7  # Author: Markus Wenzel, TU Muenchen
    28.8  #
    28.9  # DESCRIPTION: Isabelle graph browser
    29.1 --- a/lib/Tools/codegen	Tue Dec 30 08:18:54 2008 +0100
    29.2 +++ b/lib/Tools/codegen	Tue Dec 30 11:10:01 2008 +0100
    29.3 @@ -1,6 +1,5 @@
    29.4  #!/usr/bin/env bash
    29.5  #
    29.6 -# $Id$
    29.7  # Author: Florian Haftmann, TUM
    29.8  #
    29.9  # DESCRIPTION: issue code generation from shell
    30.1 --- a/lib/Tools/dimacs2hol	Tue Dec 30 08:18:54 2008 +0100
    30.2 +++ b/lib/Tools/dimacs2hol	Tue Dec 30 11:10:01 2008 +0100
    30.3 @@ -1,8 +1,6 @@
    30.4  #!/usr/bin/env bash
    30.5  #
    30.6 -# $Id$
    30.7  # Author: Tjark Weber
    30.8 -# Copyright 2004
    30.9  #
   30.10  # DESCRIPTION: convert DIMACS CNF files into Isabelle/HOL theories
   30.11  
    31.1 --- a/lib/Tools/display	Tue Dec 30 08:18:54 2008 +0100
    31.2 +++ b/lib/Tools/display	Tue Dec 30 11:10:01 2008 +0100
    31.3 @@ -1,6 +1,5 @@
    31.4  #!/usr/bin/env bash
    31.5  #
    31.6 -# $Id$
    31.7  # Author: Markus Wenzel, TU Muenchen
    31.8  #
    31.9  # DESCRIPTION: display document (in DVI or PDF format)
    32.1 --- a/lib/Tools/doc	Tue Dec 30 08:18:54 2008 +0100
    32.2 +++ b/lib/Tools/doc	Tue Dec 30 11:10:01 2008 +0100
    32.3 @@ -1,6 +1,5 @@
    32.4  #!/usr/bin/env bash
    32.5  #
    32.6 -# $Id$
    32.7  # Author: Markus Wenzel, TU Muenchen
    32.8  #
    32.9  # DESCRIPTION: view Isabelle documentation
    33.1 --- a/lib/Tools/document	Tue Dec 30 08:18:54 2008 +0100
    33.2 +++ b/lib/Tools/document	Tue Dec 30 11:10:01 2008 +0100
    33.3 @@ -1,6 +1,5 @@
    33.4  #!/usr/bin/env bash
    33.5  #
    33.6 -# $Id$
    33.7  # Author: Markus Wenzel, TU Muenchen
    33.8  #
    33.9  # DESCRIPTION: prepare theory session document
    34.1 --- a/lib/Tools/emacs	Tue Dec 30 08:18:54 2008 +0100
    34.2 +++ b/lib/Tools/emacs	Tue Dec 30 11:10:01 2008 +0100
    34.3 @@ -1,6 +1,5 @@
    34.4  #!/usr/bin/env bash
    34.5  #
    34.6 -# $Id$
    34.7  # Author: Makarius
    34.8  #
    34.9  # DESCRIPTION: Proof General / Emacs interface wrapper
    35.1 --- a/lib/Tools/env	Tue Dec 30 08:18:54 2008 +0100
    35.2 +++ b/lib/Tools/env	Tue Dec 30 11:10:01 2008 +0100
    35.3 @@ -1,6 +1,5 @@
    35.4  #!/usr/bin/env bash
    35.5  #
    35.6 -# $Id$
    35.7  # Author: Markus Wenzel, TU Muenchen
    35.8  #
    35.9  # DESCRIPTION: run a program in a modified environment
    36.1 --- a/lib/Tools/findlogics	Tue Dec 30 08:18:54 2008 +0100
    36.2 +++ b/lib/Tools/findlogics	Tue Dec 30 11:10:01 2008 +0100
    36.3 @@ -1,6 +1,5 @@
    36.4  #!/usr/bin/env bash
    36.5  #
    36.6 -# $Id$
    36.7  # Author: Markus Wenzel, TU Muenchen
    36.8  #
    36.9  # DESCRIPTION: collect heap names from ISABELLE_PATH
    37.1 --- a/lib/Tools/getenv	Tue Dec 30 08:18:54 2008 +0100
    37.2 +++ b/lib/Tools/getenv	Tue Dec 30 11:10:01 2008 +0100
    37.3 @@ -1,6 +1,5 @@
    37.4  #!/usr/bin/env bash
    37.5  #
    37.6 -# $Id$
    37.7  # Author: Markus Wenzel, TU Muenchen
    37.8  #
    37.9  # DESCRIPTION: get values from Isabelle settings environment
    38.1 --- a/lib/Tools/install	Tue Dec 30 08:18:54 2008 +0100
    38.2 +++ b/lib/Tools/install	Tue Dec 30 11:10:01 2008 +0100
    38.3 @@ -1,6 +1,5 @@
    38.4  #!/usr/bin/env bash
    38.5  #
    38.6 -# $Id$
    38.7  # Author: Markus Wenzel, TU Muenchen
    38.8  #
    38.9  # DESCRIPTION: install standalone Isabelle executables
    39.1 --- a/lib/Tools/java	Tue Dec 30 08:18:54 2008 +0100
    39.2 +++ b/lib/Tools/java	Tue Dec 30 11:10:01 2008 +0100
    39.3 @@ -1,6 +1,5 @@
    39.4  #!/usr/bin/env bash
    39.5  #
    39.6 -# $Id$
    39.7  # Author: Makarius
    39.8  #
    39.9  # DESCRIPTION: invoke Java within the Isabelle environment
    40.1 --- a/lib/Tools/jedit	Tue Dec 30 08:18:54 2008 +0100
    40.2 +++ b/lib/Tools/jedit	Tue Dec 30 11:10:01 2008 +0100
    40.3 @@ -1,6 +1,5 @@
    40.4  #!/usr/bin/env bash
    40.5  #
    40.6 -# $Id$
    40.7  # Author: Makarius
    40.8  #
    40.9  # DESCRIPTION: Isabelle/jEdit interface wrapper
    41.1 --- a/lib/Tools/keywords	Tue Dec 30 08:18:54 2008 +0100
    41.2 +++ b/lib/Tools/keywords	Tue Dec 30 11:10:01 2008 +0100
    41.3 @@ -1,6 +1,5 @@
    41.4  #!/usr/bin/env bash
    41.5  #
    41.6 -# $Id$
    41.7  # Author: Makarius
    41.8  #
    41.9  # DESCRIPTION: generate outer syntax keyword files from session logs
    42.1 --- a/lib/Tools/latex	Tue Dec 30 08:18:54 2008 +0100
    42.2 +++ b/lib/Tools/latex	Tue Dec 30 11:10:01 2008 +0100
    42.3 @@ -1,6 +1,5 @@
    42.4  #!/usr/bin/env bash
    42.5  #
    42.6 -# $Id$
    42.7  # Author: Markus Wenzel, TU Muenchen
    42.8  #
    42.9  # DESCRIPTION: run LaTeX (and related tools)
    43.1 --- a/lib/Tools/logo	Tue Dec 30 08:18:54 2008 +0100
    43.2 +++ b/lib/Tools/logo	Tue Dec 30 11:10:01 2008 +0100
    43.3 @@ -1,6 +1,5 @@
    43.4  #!/usr/bin/env bash
    43.5  #
    43.6 -# $Id$
    43.7  # Author: Markus Wenzel, TU Muenchen
    43.8  #
    43.9  # DESCRIPTION: create an instance of the Isabelle logo
    44.1 --- a/lib/Tools/make	Tue Dec 30 08:18:54 2008 +0100
    44.2 +++ b/lib/Tools/make	Tue Dec 30 11:10:01 2008 +0100
    44.3 @@ -1,6 +1,5 @@
    44.4  #!/usr/bin/env bash
    44.5  #
    44.6 -# $Id$
    44.7  # Author: Markus Wenzel, TU Muenchen
    44.8  #
    44.9  # DESCRIPTION: Isabelle make utility
    45.1 --- a/lib/Tools/makeall	Tue Dec 30 08:18:54 2008 +0100
    45.2 +++ b/lib/Tools/makeall	Tue Dec 30 11:10:01 2008 +0100
    45.3 @@ -1,6 +1,5 @@
    45.4  #!/usr/bin/env bash
    45.5  #
    45.6 -# $Id$
    45.7  # Author: Markus Wenzel, TU Muenchen
    45.8  #
    45.9  # DESCRIPTION: apply make utility to all logics
    46.1 --- a/lib/Tools/mkdir	Tue Dec 30 08:18:54 2008 +0100
    46.2 +++ b/lib/Tools/mkdir	Tue Dec 30 11:10:01 2008 +0100
    46.3 @@ -1,6 +1,5 @@
    46.4  #!/usr/bin/env bash
    46.5  #
    46.6 -# $Id$
    46.7  # Author: Markus Wenzel, TU Muenchen
    46.8  #
    46.9  # DESCRIPTION: prepare logic session directory
    47.1 --- a/lib/Tools/mkfifo	Tue Dec 30 08:18:54 2008 +0100
    47.2 +++ b/lib/Tools/mkfifo	Tue Dec 30 11:10:01 2008 +0100
    47.3 @@ -1,6 +1,5 @@
    47.4  #!/usr/bin/env bash
    47.5  #
    47.6 -# $Id$
    47.7  # Author: Makarius
    47.8  #
    47.9  # DESCRIPTION: create named pipe
    48.1 --- a/lib/Tools/mkproject	Tue Dec 30 08:18:54 2008 +0100
    48.2 +++ b/lib/Tools/mkproject	Tue Dec 30 11:10:01 2008 +0100
    48.3 @@ -1,7 +1,6 @@
    48.4  #!/usr/bin/env bash
    48.5  #
    48.6 -# $Id$
    48.7 -# Author: David Aspinall and Makarius Wenzel
    48.8 +# Author: David Aspinall
    48.9  #
   48.10  # DESCRIPTION: prepare a session directory for PG-Eclipse
   48.11  
    49.1 --- a/lib/Tools/print	Tue Dec 30 08:18:54 2008 +0100
    49.2 +++ b/lib/Tools/print	Tue Dec 30 11:10:01 2008 +0100
    49.3 @@ -1,6 +1,5 @@
    49.4  #!/usr/bin/env bash
    49.5  #
    49.6 -# $Id$
    49.7  # Author: Markus Wenzel, TU Muenchen
    49.8  #
    49.9  # DESCRIPTION: print document
    50.1 --- a/lib/Tools/rmfifo	Tue Dec 30 08:18:54 2008 +0100
    50.2 +++ b/lib/Tools/rmfifo	Tue Dec 30 11:10:01 2008 +0100
    50.3 @@ -1,6 +1,5 @@
    50.4  #!/usr/bin/env bash
    50.5  #
    50.6 -# $Id$
    50.7  # Author: Makarius
    50.8  #
    50.9  # DESCRIPTION: remove named pipe
    51.1 --- a/lib/Tools/scala	Tue Dec 30 08:18:54 2008 +0100
    51.2 +++ b/lib/Tools/scala	Tue Dec 30 11:10:01 2008 +0100
    51.3 @@ -1,6 +1,5 @@
    51.4  #!/usr/bin/env bash
    51.5  #
    51.6 -# $Id$
    51.7  # Author: Makarius
    51.8  #
    51.9  # DESCRIPTION: invoke Scala within the Isabelle environment
    52.1 --- a/lib/Tools/tty	Tue Dec 30 08:18:54 2008 +0100
    52.2 +++ b/lib/Tools/tty	Tue Dec 30 11:10:01 2008 +0100
    52.3 @@ -1,6 +1,5 @@
    52.4  #!/usr/bin/env bash
    52.5  #
    52.6 -# $Id$
    52.7  # Author: Markus Wenzel, TU Muenchen
    52.8  #
    52.9  # DESCRIPTION: run Isabelle process with plain tty interaction
    53.1 --- a/lib/Tools/unsymbolize	Tue Dec 30 08:18:54 2008 +0100
    53.2 +++ b/lib/Tools/unsymbolize	Tue Dec 30 11:10:01 2008 +0100
    53.3 @@ -1,6 +1,5 @@
    53.4  #!/usr/bin/env bash
    53.5  #
    53.6 -# $Id$
    53.7  # Author: Markus Wenzel, TU Muenchen
    53.8  #
    53.9  # DESCRIPTION: remove unreadable symbol names from sources
    54.1 --- a/lib/Tools/usedir	Tue Dec 30 08:18:54 2008 +0100
    54.2 +++ b/lib/Tools/usedir	Tue Dec 30 11:10:01 2008 +0100
    54.3 @@ -1,6 +1,5 @@
    54.4  #!/usr/bin/env bash
    54.5  #
    54.6 -# $Id$
    54.7  # Author: Markus Wenzel, TU Muenchen
    54.8  #
    54.9  # DESCRIPTION: build object-logic or run examples
   54.10 @@ -40,6 +39,11 @@
   54.11    echo "  ISABELLE_USEDIR_OPTIONS=$ISABELLE_USEDIR_OPTIONS"
   54.12    echo "  HOL_USEDIR_OPTIONS=$HOL_USEDIR_OPTIONS"
   54.13    echo
   54.14 +  echo "  ML_PLATFORM=$ML_PLATFORM"
   54.15 +  echo "  ML_HOME=$ML_HOME"
   54.16 +  echo "  ML_SYSTEM=$ML_SYSTEM"
   54.17 +  echo "  ML_OPTIONS=$ML_OPTIONS"
   54.18 +  echo
   54.19    exit 1
   54.20  }
   54.21  
    55.1 --- a/lib/Tools/version	Tue Dec 30 08:18:54 2008 +0100
    55.2 +++ b/lib/Tools/version	Tue Dec 30 11:10:01 2008 +0100
    55.3 @@ -1,6 +1,5 @@
    55.4  #!/usr/bin/env bash
    55.5  #
    55.6 -# $Id$
    55.7  # Author: Stefan Berghofer, TU Muenchen
    55.8  #
    55.9  # DESCRIPTION: display Isabelle version
    56.1 --- a/lib/Tools/yxml	Tue Dec 30 08:18:54 2008 +0100
    56.2 +++ b/lib/Tools/yxml	Tue Dec 30 11:10:01 2008 +0100
    56.3 @@ -1,6 +1,5 @@
    56.4  #!/usr/bin/env bash
    56.5  #
    56.6 -# $Id$
    56.7  # Author: Makarius
    56.8  #
    56.9  # DESCRIPTION: simple XML to YXML converter
    57.1 --- a/lib/jedit/isabelle.xml	Tue Dec 30 08:18:54 2008 +0100
    57.2 +++ b/lib/jedit/isabelle.xml	Tue Dec 30 11:10:01 2008 +0100
    57.3 @@ -56,6 +56,7 @@
    57.4        <OPERATOR>atom_decl</OPERATOR>
    57.5        <LABEL>atp_info</LABEL>
    57.6        <LABEL>atp_kill</LABEL>
    57.7 +      <LABEL>atp_messages</LABEL>
    57.8        <KEYWORD4>attach</KEYWORD4>
    57.9        <OPERATOR>automaton</OPERATOR>
   57.10        <KEYWORD4>avoids</KEYWORD4>
   57.11 @@ -154,7 +155,6 @@
   57.12        <KEYWORD4>if</KEYWORD4>
   57.13        <KEYWORD4>imports</KEYWORD4>
   57.14        <KEYWORD4>in</KEYWORD4>
   57.15 -      <KEYWORD4>includes</KEYWORD4>
   57.16        <KEYWORD4>induction</KEYWORD4>
   57.17        <OPERATOR>inductive</OPERATOR>
   57.18        <KEYWORD1>inductive_cases</KEYWORD1>
   57.19 @@ -286,6 +286,7 @@
   57.20        <OPERATOR>statespace</OPERATOR>
   57.21        <KEYWORD4>structure</KEYWORD4>
   57.22        <OPERATOR>subclass</OPERATOR>
   57.23 +      <OPERATOR>sublocale</OPERATOR>
   57.24        <OPERATOR>subsect</OPERATOR>
   57.25        <OPERATOR>subsection</OPERATOR>
   57.26        <OPERATOR>subsubsect</OPERATOR>
    58.1 --- a/lib/scripts/dimacs2hol.pl	Tue Dec 30 08:18:54 2008 +0100
    58.2 +++ b/lib/scripts/dimacs2hol.pl	Tue Dec 30 11:10:01 2008 +0100
    58.3 @@ -1,5 +1,3 @@
    58.4 -#
    58.5 -# $Id$
    58.6  #
    58.7  # dimacs2hol.pl - convert files in DIMACS CNF format [1] into Isabelle/HOL
    58.8  #                 theories
    59.1 --- a/lib/scripts/feeder	Tue Dec 30 08:18:54 2008 +0100
    59.2 +++ b/lib/scripts/feeder	Tue Dec 30 11:10:01 2008 +0100
    59.3 @@ -1,6 +1,5 @@
    59.4  #!/usr/bin/env bash
    59.5  #
    59.6 -# $Id$
    59.7  # Author: Markus Wenzel, TU Muenchen
    59.8  #
    59.9  # feeder - feed isabelle session
    60.1 --- a/lib/scripts/feeder.pl	Tue Dec 30 08:18:54 2008 +0100
    60.2 +++ b/lib/scripts/feeder.pl	Tue Dec 30 11:10:01 2008 +0100
    60.3 @@ -1,5 +1,4 @@
    60.4  #
    60.5 -# $Id$
    60.6  # Author: Markus Wenzel, TU Muenchen
    60.7  #
    60.8  # feeder.pl - feed isabelle session
    61.1 --- a/lib/scripts/fileident	Tue Dec 30 08:18:54 2008 +0100
    61.2 +++ b/lib/scripts/fileident	Tue Dec 30 11:10:01 2008 +0100
    61.3 @@ -1,7 +1,5 @@
    61.4  #!/usr/bin/env bash
    61.5  #
    61.6 -# $Id$
    61.7 -#
    61.8  # fileident --- produce file identification based
    61.9  
   61.10  FILE="$1"
    62.1 --- a/lib/scripts/getsettings	Tue Dec 30 08:18:54 2008 +0100
    62.2 +++ b/lib/scripts/getsettings	Tue Dec 30 11:10:01 2008 +0100
    62.3 @@ -1,5 +1,5 @@
    62.4  # -*- shell-script -*- :mode=shellscript:
    62.5 -# $Id$
    62.6 +#
    62.7  # Author: Markus Wenzel, TU Muenchen
    62.8  #
    62.9  # getsettings - bash source script to augment current env.
    63.1 --- a/lib/scripts/keywords.pl	Tue Dec 30 08:18:54 2008 +0100
    63.2 +++ b/lib/scripts/keywords.pl	Tue Dec 30 11:10:01 2008 +0100
    63.3 @@ -1,5 +1,4 @@
    63.4  #
    63.5 -# $Id$
    63.6  # Author: Makarius
    63.7  #
    63.8  # keywords.pl - generate outer syntax keyword files from session logs
    63.9 @@ -79,8 +78,6 @@
   63.10    print ";; Generated from ${sessions}.\n";
   63.11    print ";; *** DO NOT EDIT *** DO NOT EDIT *** DO NOT EDIT ***\n";
   63.12    print ";;\n";
   63.13 -  print ";; \$", "Id\$\n";
   63.14 -  print ";;\n";
   63.15  
   63.16    for my $kind (@kinds) {
   63.17      my @names;
   63.18 @@ -154,7 +151,6 @@
   63.19  EOF
   63.20    print "<!-- Generated from ${sessions}. -->\n";
   63.21    print "<!-- *** DO NOT EDIT *** DO NOT EDIT *** DO NOT EDIT *** -->\n";
   63.22 -  print "<!-- \$", "Id\$ -->\n";
   63.23    print <<'EOF';
   63.24  <MODE>
   63.25    <PROPS>
    64.1 --- a/lib/scripts/polyml-platform	Tue Dec 30 08:18:54 2008 +0100
    64.2 +++ b/lib/scripts/polyml-platform	Tue Dec 30 11:10:01 2008 +0100
    64.3 @@ -1,7 +1,5 @@
    64.4  #!/usr/bin/env bash
    64.5  #
    64.6 -# $Id$
    64.7 -#
    64.8  # polyml-platform --- determine Poly/ML's idea of current hardware and
    64.9  # operating system type
   64.10  #
    65.1 --- a/lib/scripts/polyml-version	Tue Dec 30 08:18:54 2008 +0100
    65.2 +++ b/lib/scripts/polyml-version	Tue Dec 30 11:10:01 2008 +0100
    65.3 @@ -1,7 +1,5 @@
    65.4  #!/usr/bin/env bash
    65.5  #
    65.6 -# $Id$
    65.7 -#
    65.8  # polyml-version --- determine Poly/ML runtime system version
    65.9  
   65.10  echo -n polyml
    66.1 --- a/lib/scripts/run-mosml	Tue Dec 30 08:18:54 2008 +0100
    66.2 +++ b/lib/scripts/run-mosml	Tue Dec 30 11:10:01 2008 +0100
    66.3 @@ -1,6 +1,5 @@
    66.4  #!/usr/bin/env bash
    66.5  #
    66.6 -# $Id$
    66.7  # Author: Markus Wenzel, TU Muenchen
    66.8  #
    66.9  # Moscow ML 2.00 startup script
    67.1 --- a/lib/scripts/run-polyml	Tue Dec 30 08:18:54 2008 +0100
    67.2 +++ b/lib/scripts/run-polyml	Tue Dec 30 11:10:01 2008 +0100
    67.3 @@ -1,6 +1,5 @@
    67.4  #!/usr/bin/env bash
    67.5  #
    67.6 -# $Id$
    67.7  # Author: Makarius
    67.8  #
    67.9  # Poly/ML 5.1/5.2 startup script.
    68.1 --- a/lib/scripts/run-polyml-4.1.3	Tue Dec 30 08:18:54 2008 +0100
    68.2 +++ b/lib/scripts/run-polyml-4.1.3	Tue Dec 30 11:10:01 2008 +0100
    68.3 @@ -1,6 +1,5 @@
    68.4  #!/usr/bin/env bash
    68.5  #
    68.6 -# $Id$
    68.7  # Author: Markus Wenzel, TU Muenchen
    68.8  #
    68.9  # Poly/ML 4.x startup script.
    69.1 --- a/lib/scripts/run-polyml-4.1.4	Tue Dec 30 08:18:54 2008 +0100
    69.2 +++ b/lib/scripts/run-polyml-4.1.4	Tue Dec 30 11:10:01 2008 +0100
    69.3 @@ -1,6 +1,5 @@
    69.4  #!/usr/bin/env bash
    69.5  #
    69.6 -# $Id$
    69.7  # Author: Markus Wenzel, TU Muenchen
    69.8  #
    69.9  # Poly/ML 4.x startup script.
    70.1 --- a/lib/scripts/run-polyml-4.2.0	Tue Dec 30 08:18:54 2008 +0100
    70.2 +++ b/lib/scripts/run-polyml-4.2.0	Tue Dec 30 11:10:01 2008 +0100
    70.3 @@ -1,6 +1,5 @@
    70.4  #!/usr/bin/env bash
    70.5  #
    70.6 -# $Id$
    70.7  # Author: Markus Wenzel, TU Muenchen
    70.8  #
    70.9  # Poly/ML 4.x startup script.
    71.1 --- a/lib/scripts/run-polyml-5.0	Tue Dec 30 08:18:54 2008 +0100
    71.2 +++ b/lib/scripts/run-polyml-5.0	Tue Dec 30 11:10:01 2008 +0100
    71.3 @@ -1,6 +1,5 @@
    71.4  #!/usr/bin/env bash
    71.5  #
    71.6 -# $Id$
    71.7  # Author: Makarius
    71.8  #
    71.9  # Poly/ML 5.0 startup script.
    72.1 --- a/lib/scripts/run-smlnj	Tue Dec 30 08:18:54 2008 +0100
    72.2 +++ b/lib/scripts/run-smlnj	Tue Dec 30 11:10:01 2008 +0100
    72.3 @@ -1,6 +1,5 @@
    72.4  #!/usr/bin/env bash
    72.5  #
    72.6 -# $Id$
    72.7  # Author: Markus Wenzel, TU Muenchen
    72.8  #
    72.9  # SML/NJ startup script (for 110 or later).
    73.1 --- a/lib/scripts/system.pl	Tue Dec 30 08:18:54 2008 +0100
    73.2 +++ b/lib/scripts/system.pl	Tue Dec 30 11:10:01 2008 +0100
    73.3 @@ -1,5 +1,4 @@
    73.4  #
    73.5 -# $Id$
    73.6  # Author: Makarius
    73.7  #
    73.8  # system.pl - invoke shell command line (with robust signal handling)
    74.1 --- a/lib/scripts/timestart.bash	Tue Dec 30 08:18:54 2008 +0100
    74.2 +++ b/lib/scripts/timestart.bash	Tue Dec 30 11:10:01 2008 +0100
    74.3 @@ -1,5 +1,5 @@
    74.4  # -*- shell-script -*-
    74.5 -# $Id$
    74.6 +#
    74.7  # Author: Makarius
    74.8  #
    74.9  # timestart - setup bash environment for timing.
    75.1 --- a/lib/scripts/timestop.bash	Tue Dec 30 08:18:54 2008 +0100
    75.2 +++ b/lib/scripts/timestop.bash	Tue Dec 30 11:10:01 2008 +0100
    75.3 @@ -1,5 +1,5 @@
    75.4  # -*- shell-script -*-
    75.5 -# $Id$
    75.6 +#
    75.7  # Author: Makarius
    75.8  #
    75.9  # timestop - report timing based on environment (cf. timestart.bash)
    76.1 --- a/lib/scripts/unsymbolize.pl	Tue Dec 30 08:18:54 2008 +0100
    76.2 +++ b/lib/scripts/unsymbolize.pl	Tue Dec 30 11:10:01 2008 +0100
    76.3 @@ -1,5 +1,4 @@
    76.4  #
    76.5 -# $Id$
    76.6  # Author: Markus Wenzel, TU Muenchen
    76.7  #
    76.8  # unsymbolize.pl - remove unreadable symbol names from sources
    77.1 --- a/lib/scripts/yxml.pl	Tue Dec 30 08:18:54 2008 +0100
    77.2 +++ b/lib/scripts/yxml.pl	Tue Dec 30 11:10:01 2008 +0100
    77.3 @@ -1,5 +1,4 @@
    77.4  #
    77.5 -# $Id$
    77.6  # Author: Makarius
    77.7  #
    77.8  # yxml.pl - simple XML to YXML converter
    78.1 --- a/lib/texinputs/draft.tex	Tue Dec 30 08:18:54 2008 +0100
    78.2 +++ b/lib/texinputs/draft.tex	Tue Dec 30 11:10:01 2008 +0100
    78.3 @@ -1,5 +1,3 @@
    78.4 -%%
    78.5 -%% $Id$
    78.6  %%
    78.7  %% root for draft documents
    78.8  %%
    79.1 --- a/lib/texinputs/isabelle.sty	Tue Dec 30 08:18:54 2008 +0100
    79.2 +++ b/lib/texinputs/isabelle.sty	Tue Dec 30 11:10:01 2008 +0100
    79.3 @@ -1,5 +1,3 @@
    79.4 -%%
    79.5 -%% $Id$
    79.6  %%
    79.7  %% macros for Isabelle generated LaTeX output
    79.8  %%
    80.1 --- a/lib/texinputs/isabellesym.sty	Tue Dec 30 08:18:54 2008 +0100
    80.2 +++ b/lib/texinputs/isabellesym.sty	Tue Dec 30 11:10:01 2008 +0100
    80.3 @@ -1,5 +1,3 @@
    80.4 -%%
    80.5 -%% $Id$
    80.6  %%
    80.7  %% definitions of standard Isabelle symbols
    80.8  %%
    81.1 --- a/lib/texinputs/pdfsetup.sty	Tue Dec 30 08:18:54 2008 +0100
    81.2 +++ b/lib/texinputs/pdfsetup.sty	Tue Dec 30 11:10:01 2008 +0100
    81.3 @@ -1,5 +1,3 @@
    81.4 -%%
    81.5 -%% $Id$
    81.6  %%
    81.7  %% default hyperref setup (both for pdf and dvi output)
    81.8  %%
    82.1 --- a/src/HOL/Code_Setup.thy	Tue Dec 30 08:18:54 2008 +0100
    82.2 +++ b/src/HOL/Code_Setup.thy	Tue Dec 30 11:10:01 2008 +0100
    82.3 @@ -198,6 +198,10 @@
    82.4  
    82.5  subsection {* Evaluation and normalization by evaluation *}
    82.6  
    82.7 +setup {*
    82.8 +  Value.add_evaluator ("SML", Codegen.eval_term o ProofContext.theory_of)
    82.9 +*}
   82.10 +
   82.11  ML {*
   82.12  structure Eval_Method =
   82.13  struct
   82.14 @@ -240,6 +244,10 @@
   82.15  
   82.16  subsection {* Quickcheck *}
   82.17  
   82.18 +setup {*
   82.19 +  Quickcheck.add_generator ("SML", Codegen.test_term)
   82.20 +*}
   82.21 +
   82.22  quickcheck_params [size = 5, iterations = 50]
   82.23  
   82.24  end
    83.1 --- a/src/HOL/Complex/Fundamental_Theorem_Algebra.thy	Tue Dec 30 08:18:54 2008 +0100
    83.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    83.3 @@ -1,1329 +0,0 @@
    83.4 -(*  Title:       Fundamental_Theorem_Algebra.thy
    83.5 -    Author:      Amine Chaieb
    83.6 -*)
    83.7 -
    83.8 -header{*Fundamental Theorem of Algebra*}
    83.9 -
   83.10 -theory Fundamental_Theorem_Algebra
   83.11 -imports "~~/src/HOL/Univ_Poly" "~~/src/HOL/Library/Dense_Linear_Order" "~~/src/HOL/Complex"
   83.12 -begin
   83.13 -
   83.14 -subsection {* Square root of complex numbers *}
   83.15 -definition csqrt :: "complex \<Rightarrow> complex" where
   83.16 -"csqrt z = (if Im z = 0 then
   83.17 -            if 0 \<le> Re z then Complex (sqrt(Re z)) 0
   83.18 -            else Complex 0 (sqrt(- Re z))
   83.19 -           else Complex (sqrt((cmod z + Re z) /2))
   83.20 -                        ((Im z / abs(Im z)) * sqrt((cmod z - Re z) /2)))"
   83.21 -
   83.22 -lemma csqrt[algebra]: "csqrt z ^ 2 = z"
   83.23 -proof-
   83.24 -  obtain x y where xy: "z = Complex x y" by (cases z, simp_all)
   83.25 -  {assume y0: "y = 0"
   83.26 -    {assume x0: "x \<ge> 0" 
   83.27 -      then have ?thesis using y0 xy real_sqrt_pow2[OF x0]
   83.28 -	by (simp add: csqrt_def power2_eq_square)}
   83.29 -    moreover
   83.30 -    {assume "\<not> x \<ge> 0" hence x0: "- x \<ge> 0" by arith
   83.31 -      then have ?thesis using y0 xy real_sqrt_pow2[OF x0] 
   83.32 -	by (simp add: csqrt_def power2_eq_square) }
   83.33 -    ultimately have ?thesis by blast}
   83.34 -  moreover
   83.35 -  {assume y0: "y\<noteq>0"
   83.36 -    {fix x y
   83.37 -      let ?z = "Complex x y"
   83.38 -      from abs_Re_le_cmod[of ?z] have tha: "abs x \<le> cmod ?z" by auto
   83.39 -      hence "cmod ?z - x \<ge> 0" "cmod ?z + x \<ge> 0" by arith+ 
   83.40 -      hence "(sqrt (x * x + y * y) + x) / 2 \<ge> 0" "(sqrt (x * x + y * y) - x) / 2 \<ge> 0" by (simp_all add: power2_eq_square) }
   83.41 -    note th = this
   83.42 -    have sq4: "\<And>x::real. x^2 / 4 = (x / 2) ^ 2" 
   83.43 -      by (simp add: power2_eq_square) 
   83.44 -    from th[of x y]
   83.45 -    have sq4': "sqrt (((sqrt (x * x + y * y) + x)^2 / 4)) = (sqrt (x * x + y * y) + x) / 2" "sqrt (((sqrt (x * x + y * y) - x)^2 / 4)) = (sqrt (x * x + y * y) - x) / 2" unfolding sq4 by simp_all
   83.46 -    then have th1: "sqrt ((sqrt (x * x + y * y) + x) * (sqrt (x * x + y * y) + x) / 4) - sqrt ((sqrt (x * x + y * y) - x) * (sqrt (x * x + y * y) - x) / 4) = x"
   83.47 -      unfolding power2_eq_square by simp 
   83.48 -    have "sqrt 4 = sqrt (2^2)" by simp 
   83.49 -    hence sqrt4: "sqrt 4 = 2" by (simp only: real_sqrt_abs)
   83.50 -    have th2: "2 *(y * sqrt ((sqrt (x * x + y * y) - x) * (sqrt (x * x + y * y) + x) / 4)) / \<bar>y\<bar> = y"
   83.51 -      using iffD2[OF real_sqrt_pow2_iff sum_power2_ge_zero[of x y]] y0
   83.52 -      unfolding power2_eq_square 
   83.53 -      by (simp add: ring_simps real_sqrt_divide sqrt4)
   83.54 -     from y0 xy have ?thesis  apply (simp add: csqrt_def power2_eq_square)
   83.55 -       apply (simp add: real_sqrt_sum_squares_mult_ge_zero[of x y] real_sqrt_pow2[OF th(1)[of x y], unfolded power2_eq_square] real_sqrt_pow2[OF th(2)[of x y], unfolded power2_eq_square] real_sqrt_mult[symmetric])
   83.56 -      using th1 th2  ..}
   83.57 -  ultimately show ?thesis by blast
   83.58 -qed
   83.59 -
   83.60 -
   83.61 -subsection{* More lemmas about module of complex numbers *}
   83.62 -
   83.63 -lemma complex_of_real_power: "complex_of_real x ^ n = complex_of_real (x^n)"
   83.64 -  by (rule of_real_power [symmetric])
   83.65 -
   83.66 -lemma real_down2: "(0::real) < d1 \<Longrightarrow> 0 < d2 ==> EX e. 0 < e & e < d1 & e < d2"
   83.67 -  apply ferrack apply arith done
   83.68 -
   83.69 -text{* The triangle inequality for cmod *}
   83.70 -lemma complex_mod_triangle_sub: "cmod w \<le> cmod (w + z) + norm z"
   83.71 -  using complex_mod_triangle_ineq2[of "w + z" "-z"] by auto
   83.72 -
   83.73 -subsection{* Basic lemmas about complex polynomials *}
   83.74 -
   83.75 -lemma poly_bound_exists:
   83.76 -  shows "\<exists>m. m > 0 \<and> (\<forall>z. cmod z <= r \<longrightarrow> cmod (poly p z) \<le> m)"
   83.77 -proof(induct p)
   83.78 -  case Nil thus ?case by (rule exI[where x=1], simp) 
   83.79 -next
   83.80 -  case (Cons c cs)
   83.81 -  from Cons.hyps obtain m where m: "\<forall>z. cmod z \<le> r \<longrightarrow> cmod (poly cs z) \<le> m"
   83.82 -    by blast
   83.83 -  let ?k = " 1 + cmod c + \<bar>r * m\<bar>"
   83.84 -  have kp: "?k > 0" using abs_ge_zero[of "r*m"] norm_ge_zero[of c] by arith
   83.85 -  {fix z
   83.86 -    assume H: "cmod z \<le> r"
   83.87 -    from m H have th: "cmod (poly cs z) \<le> m" by blast
   83.88 -    from H have rp: "r \<ge> 0" using norm_ge_zero[of z] by arith
   83.89 -    have "cmod (poly (c # cs) z) \<le> cmod c + cmod (z* poly cs z)"
   83.90 -      using norm_triangle_ineq[of c "z* poly cs z"] by simp
   83.91 -    also have "\<dots> \<le> cmod c + r*m" using mult_mono[OF H th rp norm_ge_zero[of "poly cs z"]] by (simp add: norm_mult)
   83.92 -    also have "\<dots> \<le> ?k" by simp
   83.93 -    finally have "cmod (poly (c # cs) z) \<le> ?k" .}
   83.94 -  with kp show ?case by blast
   83.95 -qed
   83.96 -
   83.97 -
   83.98 -text{* Offsetting the variable in a polynomial gives another of same degree *}
   83.99 -  (* FIXME : Lemma holds also in locale --- fix it later *)
  83.100 -lemma  poly_offset_lemma:
  83.101 -  shows "\<exists>b q. (length q = length p) \<and> (\<forall>x. poly (b#q) (x::complex) = (a + x) * poly p x)"
  83.102 -proof(induct p)
  83.103 -  case Nil thus ?case by simp
  83.104 -next
  83.105 -  case (Cons c cs)
  83.106 -  from Cons.hyps obtain b q where 
  83.107 -    bq: "length q = length cs" "\<forall>x. poly (b # q) x = (a + x) * poly cs x"
  83.108 -    by blast
  83.109 -  let ?b = "a*c"
  83.110 -  let ?q = "(b+c)#q"
  83.111 -  have lg: "length ?q = length (c#cs)" using bq(1) by simp
  83.112 -  {fix x
  83.113 -    from bq(2)[rule_format, of x]
  83.114 -    have "x*poly (b # q) x = x*((a + x) * poly cs x)" by simp
  83.115 -    hence "poly (?b# ?q) x = (a + x) * poly (c # cs) x"
  83.116 -      by (simp add: ring_simps)}
  83.117 -  with lg  show ?case by blast 
  83.118 -qed
  83.119 -
  83.120 -    (* FIXME : This one too*)
  83.121 -lemma poly_offset: "\<exists> q. length q = length p \<and> (\<forall>x. poly q (x::complex) = poly p (a + x))"
  83.122 -proof (induct p)
  83.123 -  case Nil thus ?case by simp
  83.124 -next
  83.125 -  case (Cons c cs)
  83.126 -  from Cons.hyps obtain q where q: "length q = length cs" "\<forall>x. poly q x = poly cs (a + x)" by blast
  83.127 -  from poly_offset_lemma[of q a] obtain b p where 
  83.128 -    bp: "length p = length q" "\<forall>x. poly (b # p) x = (a + x) * poly q x"
  83.129 -    by blast
  83.130 -  thus ?case using q bp by - (rule exI[where x="(c + b)#p"], simp)
  83.131 -qed
  83.132 -
  83.133 -text{* An alternative useful formulation of completeness of the reals *}
  83.134 -lemma real_sup_exists: assumes ex: "\<exists>x. P x" and bz: "\<exists>z. \<forall>x. P x \<longrightarrow> x < z"
  83.135 -  shows "\<exists>(s::real). \<forall>y. (\<exists>x. P x \<and> y < x) \<longleftrightarrow> y < s"
  83.136 -proof-
  83.137 -  from ex bz obtain x Y where x: "P x" and Y: "\<And>x. P x \<Longrightarrow> x < Y"  by blast
  83.138 -  from ex have thx:"\<exists>x. x \<in> Collect P" by blast
  83.139 -  from bz have thY: "\<exists>Y. isUb UNIV (Collect P) Y" 
  83.140 -    by(auto simp add: isUb_def isLub_def setge_def setle_def leastP_def Ball_def order_le_less)
  83.141 -  from reals_complete[OF thx thY] obtain L where L: "isLub UNIV (Collect P) L"
  83.142 -    by blast
  83.143 -  from Y[OF x] have xY: "x < Y" .
  83.144 -  from L have L': "\<forall>x. P x \<longrightarrow> x \<le> L" by (auto simp add: isUb_def isLub_def setge_def setle_def leastP_def Ball_def)  
  83.145 -  from Y have Y': "\<forall>x. P x \<longrightarrow> x \<le> Y" 
  83.146 -    apply (clarsimp, atomize (full)) by auto 
  83.147 -  from L Y' have "L \<le> Y" by (auto simp add: isUb_def isLub_def setge_def setle_def leastP_def Ball_def)
  83.148 -  {fix y
  83.149 -    {fix z assume z: "P z" "y < z"
  83.150 -      from L' z have "y < L" by auto }
  83.151 -    moreover
  83.152 -    {assume yL: "y < L" "\<forall>z. P z \<longrightarrow> \<not> y < z"
  83.153 -      hence nox: "\<forall>z. P z \<longrightarrow> y \<ge> z" by auto
  83.154 -      from nox L have "y \<ge> L" by (auto simp add: isUb_def isLub_def setge_def setle_def leastP_def Ball_def) 
  83.155 -      with yL(1) have False  by arith}
  83.156 -    ultimately have "(\<exists>x. P x \<and> y < x) \<longleftrightarrow> y < L" by blast}
  83.157 -  thus ?thesis by blast
  83.158 -qed
  83.159 -
  83.160 -
  83.161 -subsection{* Some theorems about Sequences*}
  83.162 -text{* Given a binary function @{text "f:: nat \<Rightarrow> 'a \<Rightarrow> 'a"}, its values are uniquely determined by a function g *}
  83.163 -
  83.164 -lemma num_Axiom: "EX! g. g 0 = e \<and> (\<forall>n. g (Suc n) = f n (g n))"
  83.165 -  unfolding Ex1_def
  83.166 -  apply (rule_tac x="nat_rec e f" in exI)
  83.167 -  apply (rule conjI)+
  83.168 -apply (rule def_nat_rec_0, simp)
  83.169 -apply (rule allI, rule def_nat_rec_Suc, simp)
  83.170 -apply (rule allI, rule impI, rule ext)
  83.171 -apply (erule conjE)
  83.172 -apply (induct_tac x)
  83.173 -apply (simp add: nat_rec_0)
  83.174 -apply (erule_tac x="n" in allE)
  83.175 -apply (simp)
  83.176 -done
  83.177 -
  83.178 - text{* An equivalent formulation of monotony -- Not used here, but might be useful *}
  83.179 -lemma mono_Suc: "mono f = (\<forall>n. (f n :: 'a :: order) \<le> f (Suc n))"
  83.180 -unfolding mono_def
  83.181 -proof auto
  83.182 -  fix A B :: nat
  83.183 -  assume H: "\<forall>n. f n \<le> f (Suc n)" "A \<le> B"
  83.184 -  hence "\<exists>k. B = A + k" apply -  apply (thin_tac "\<forall>n. f n \<le> f (Suc n)") 
  83.185 -    by presburger
  83.186 -  then obtain k where k: "B = A + k" by blast
  83.187 -  {fix a k
  83.188 -    have "f a \<le> f (a + k)"
  83.189 -    proof (induct k)
  83.190 -      case 0 thus ?case by simp
  83.191 -    next
  83.192 -      case (Suc k)
  83.193 -      from Suc.hyps H(1)[rule_format, of "a + k"] show ?case by simp
  83.194 -    qed}
  83.195 -  with k show "f A \<le> f B" by blast
  83.196 -qed
  83.197 -
  83.198 -text{* for any sequence, there is a mootonic subsequence *}
  83.199 -lemma seq_monosub: "\<exists>f. subseq f \<and> monoseq (\<lambda> n. (s (f n)))"
  83.200 -proof-
  83.201 -  {assume H: "\<forall>n. \<exists>p >n. \<forall> m\<ge>p. s m \<le> s p"
  83.202 -    let ?P = "\<lambda> p n. p > n \<and> (\<forall>m \<ge> p. s m \<le> s p)"
  83.203 -    from num_Axiom[of "SOME p. ?P p 0" "\<lambda>p n. SOME p. ?P p n"]
  83.204 -    obtain f where f: "f 0 = (SOME p. ?P p 0)" "\<forall>n. f (Suc n) = (SOME p. ?P p (f n))" by blast
  83.205 -    have "?P (f 0) 0"  unfolding f(1) some_eq_ex[of "\<lambda>p. ?P p 0"]
  83.206 -      using H apply - 
  83.207 -      apply (erule allE[where x=0], erule exE, rule_tac x="p" in exI) 
  83.208 -      unfolding order_le_less by blast 
  83.209 -    hence f0: "f 0 > 0" "\<forall>m \<ge> f 0. s m \<le> s (f 0)" by blast+
  83.210 -    {fix n
  83.211 -      have "?P (f (Suc n)) (f n)" 
  83.212 -	unfolding f(2)[rule_format, of n] some_eq_ex[of "\<lambda>p. ?P p (f n)"]
  83.213 -	using H apply - 
  83.214 -      apply (erule allE[where x="f n"], erule exE, rule_tac x="p" in exI) 
  83.215 -      unfolding order_le_less by blast 
  83.216 -    hence "f (Suc n) > f n" "\<forall>m \<ge> f (Suc n). s m \<le> s (f (Suc n))" by blast+}
  83.217 -  note fSuc = this
  83.218 -    {fix p q assume pq: "p \<ge> f q"
  83.219 -      have "s p \<le> s(f(q))"  using f0(2)[rule_format, of p] pq fSuc
  83.220 -	by (cases q, simp_all) }
  83.221 -    note pqth = this
  83.222 -    {fix q
  83.223 -      have "f (Suc q) > f q" apply (induct q) 
  83.224 -	using f0(1) fSuc(1)[of 0] apply simp by (rule fSuc(1))}
  83.225 -    note fss = this
  83.226 -    from fss have th1: "subseq f" unfolding subseq_Suc_iff ..
  83.227 -    {fix a b 
  83.228 -      have "f a \<le> f (a + b)"
  83.229 -      proof(induct b)
  83.230 -	case 0 thus ?case by simp
  83.231 -      next
  83.232 -	case (Suc b)
  83.233 -	from fSuc(1)[of "a + b"] Suc.hyps show ?case by simp
  83.234 -      qed}
  83.235 -    note fmon0 = this
  83.236 -    have "monoseq (\<lambda>n. s (f n))" 
  83.237 -    proof-
  83.238 -      {fix n
  83.239 -	have "s (f n) \<ge> s (f (Suc n))" 
  83.240 -	proof(cases n)
  83.241 -	  case 0
  83.242 -	  assume n0: "n = 0"
  83.243 -	  from fSuc(1)[of 0] have th0: "f 0 \<le> f (Suc 0)" by simp
  83.244 -	  from f0(2)[rule_format, OF th0] show ?thesis  using n0 by simp
  83.245 -	next
  83.246 -	  case (Suc m)
  83.247 -	  assume m: "n = Suc m"
  83.248 -	  from fSuc(1)[of n] m have th0: "f (Suc m) \<le> f (Suc (Suc m))" by simp
  83.249 -	  from m fSuc(2)[rule_format, OF th0] show ?thesis by simp 
  83.250 -	qed}
  83.251 -      thus "monoseq (\<lambda>n. s (f n))" unfolding monoseq_Suc by blast 
  83.252 -    qed
  83.253 -    with th1 have ?thesis by blast}
  83.254 -  moreover
  83.255 -  {fix N assume N: "\<forall>p >N. \<exists> m\<ge>p. s m > s p"
  83.256 -    {fix p assume p: "p \<ge> Suc N" 
  83.257 -      hence pN: "p > N" by arith with N obtain m where m: "m \<ge> p" "s m > s p" by blast
  83.258 -      have "m \<noteq> p" using m(2) by auto 
  83.259 -      with m have "\<exists>m>p. s p < s m" by - (rule exI[where x=m], auto)}
  83.260 -    note th0 = this
  83.261 -    let ?P = "\<lambda>m x. m > x \<and> s x < s m"
  83.262 -    from num_Axiom[of "SOME x. ?P x (Suc N)" "\<lambda>m x. SOME y. ?P y x"]
  83.263 -    obtain f where f: "f 0 = (SOME x. ?P x (Suc N))" 
  83.264 -      "\<forall>n. f (Suc n) = (SOME m. ?P m (f n))" by blast
  83.265 -    have "?P (f 0) (Suc N)"  unfolding f(1) some_eq_ex[of "\<lambda>p. ?P p (Suc N)"]
  83.266 -      using N apply - 
  83.267 -      apply (erule allE[where x="Suc N"], clarsimp)
  83.268 -      apply (rule_tac x="m" in exI)
  83.269 -      apply auto
  83.270 -      apply (subgoal_tac "Suc N \<noteq> m")
  83.271 -      apply simp
  83.272 -      apply (rule ccontr, simp)
  83.273 -      done
  83.274 -    hence f0: "f 0 > Suc N" "s (Suc N) < s (f 0)" by blast+
  83.275 -    {fix n
  83.276 -      have "f n > N \<and> ?P (f (Suc n)) (f n)"
  83.277 -	unfolding f(2)[rule_format, of n] some_eq_ex[of "\<lambda>p. ?P p (f n)"]
  83.278 -      proof (induct n)
  83.279 -	case 0 thus ?case
  83.280 -	  using f0 N apply auto 
  83.281 -	  apply (erule allE[where x="f 0"], clarsimp) 
  83.282 -	  apply (rule_tac x="m" in exI, simp)
  83.283 -	  by (subgoal_tac "f 0 \<noteq> m", auto)
  83.284 -      next
  83.285 -	case (Suc n)
  83.286 -	from Suc.hyps have Nfn: "N < f n" by blast
  83.287 -	from Suc.hyps obtain m where m: "m > f n" "s (f n) < s m" by blast
  83.288 -	with Nfn have mN: "m > N" by arith
  83.289 -	note key = Suc.hyps[unfolded some_eq_ex[of "\<lambda>p. ?P p (f n)", symmetric] f(2)[rule_format, of n, symmetric]]
  83.290 -	
  83.291 -	from key have th0: "f (Suc n) > N" by simp
  83.292 -	from N[rule_format, OF th0]
  83.293 -	obtain m' where m': "m' \<ge> f (Suc n)" "s (f (Suc n)) < s m'" by blast
  83.294 -	have "m' \<noteq> f (Suc (n))" apply (rule ccontr) using m'(2) by auto
  83.295 -	hence "m' > f (Suc n)" using m'(1) by simp
  83.296 -	with key m'(2) show ?case by auto
  83.297 -      qed}
  83.298 -    note fSuc = this
  83.299 -    {fix n
  83.300 -      have "f n \<ge> Suc N \<and> f(Suc n) > f n \<and> s(f n) < s(f(Suc n))" using fSuc[of n] by auto 
  83.301 -      hence "f n \<ge> Suc N" "f(Suc n) > f n" "s(f n) < s(f(Suc n))" by blast+}
  83.302 -    note thf = this
  83.303 -    have sqf: "subseq f" unfolding subseq_Suc_iff using thf by simp
  83.304 -    have "monoseq (\<lambda>n. s (f n))"  unfolding monoseq_Suc using thf
  83.305 -      apply -
  83.306 -      apply (rule disjI1)
  83.307 -      apply auto
  83.308 -      apply (rule order_less_imp_le)
  83.309 -      apply blast
  83.310 -      done
  83.311 -    then have ?thesis  using sqf by blast}
  83.312 -  ultimately show ?thesis unfolding linorder_not_less[symmetric] by blast
  83.313 -qed
  83.314 -
  83.315 -lemma seq_suble: assumes sf: "subseq f" shows "n \<le> f n"
  83.316 -proof(induct n)
  83.317 -  case 0 thus ?case by simp
  83.318 -next
  83.319 -  case (Suc n)
  83.320 -  from sf[unfolded subseq_Suc_iff, rule_format, of n] Suc.hyps
  83.321 -  have "n < f (Suc n)" by arith 
  83.322 -  thus ?case by arith
  83.323 -qed
  83.324 -
  83.325 -subsection {* Fundamental theorem of algebra *}
  83.326 -lemma  unimodular_reduce_norm:
  83.327 -  assumes md: "cmod z = 1"
  83.328 -  shows "cmod (z + 1) < 1 \<or> cmod (z - 1) < 1 \<or> cmod (z + ii) < 1 \<or> cmod (z - ii) < 1"
  83.329 -proof-
  83.330 -  obtain x y where z: "z = Complex x y " by (cases z, auto)
  83.331 -  from md z have xy: "x^2 + y^2 = 1" by (simp add: cmod_def)
  83.332 -  {assume C: "cmod (z + 1) \<ge> 1" "cmod (z - 1) \<ge> 1" "cmod (z + ii) \<ge> 1" "cmod (z - ii) \<ge> 1"
  83.333 -    from C z xy have "2*x \<le> 1" "2*x \<ge> -1" "2*y \<le> 1" "2*y \<ge> -1"
  83.334 -      by (simp_all add: cmod_def power2_eq_square ring_simps)
  83.335 -    hence "abs (2*x) \<le> 1" "abs (2*y) \<le> 1" by simp_all
  83.336 -    hence "(abs (2 * x))^2 <= 1^2" "(abs (2 * y)) ^2 <= 1^2"
  83.337 -      by - (rule power_mono, simp, simp)+
  83.338 -    hence th0: "4*x^2 \<le> 1" "4*y^2 \<le> 1" 
  83.339 -      by (simp_all  add: power2_abs power_mult_distrib)
  83.340 -    from add_mono[OF th0] xy have False by simp }
  83.341 -  thus ?thesis unfolding linorder_not_le[symmetric] by blast
  83.342 -qed
  83.343 -
  83.344 -text{* Hence we can always reduce modulus of @{text "1 + b z^n"} if nonzero *}
  83.345 -lemma reduce_poly_simple:
  83.346 - assumes b: "b \<noteq> 0" and n: "n\<noteq>0"
  83.347 -  shows "\<exists>z. cmod (1 + b * z^n) < 1"
  83.348 -using n
  83.349 -proof(induct n rule: nat_less_induct)
  83.350 -  fix n
  83.351 -  assume IH: "\<forall>m<n. m \<noteq> 0 \<longrightarrow> (\<exists>z. cmod (1 + b * z ^ m) < 1)" and n: "n \<noteq> 0"
  83.352 -  let ?P = "\<lambda>z n. cmod (1 + b * z ^ n) < 1"
  83.353 -  {assume e: "even n"
  83.354 -    hence "\<exists>m. n = 2*m" by presburger
  83.355 -    then obtain m where m: "n = 2*m" by blast
  83.356 -    from n m have "m\<noteq>0" "m < n" by presburger+
  83.357 -    with IH[rule_format, of m] obtain z where z: "?P z m" by blast
  83.358 -    from z have "?P (csqrt z) n" by (simp add: m power_mult csqrt)
  83.359 -    hence "\<exists>z. ?P z n" ..}
  83.360 -  moreover
  83.361 -  {assume o: "odd n"
  83.362 -    from b have b': "b^2 \<noteq> 0" unfolding power2_eq_square by simp
  83.363 -    have "Im (inverse b) * (Im (inverse b) * \<bar>Im b * Im b + Re b * Re b\<bar>) +
  83.364 -    Re (inverse b) * (Re (inverse b) * \<bar>Im b * Im b + Re b * Re b\<bar>) = 
  83.365 -    ((Re (inverse b))^2 + (Im (inverse b))^2) * \<bar>Im b * Im b + Re b * Re b\<bar>" by algebra
  83.366 -    also have "\<dots> = cmod (inverse b) ^2 * cmod b ^ 2" 
  83.367 -      apply (simp add: cmod_def) using realpow_two_le_add_order[of "Re b" "Im b"]
  83.368 -      by (simp add: power2_eq_square)
  83.369 -    finally 
  83.370 -    have th0: "Im (inverse b) * (Im (inverse b) * \<bar>Im b * Im b + Re b * Re b\<bar>) +
  83.371 -    Re (inverse b) * (Re (inverse b) * \<bar>Im b * Im b + Re b * Re b\<bar>) =
  83.372 -    1" 
  83.373 -      apply (simp add: power2_eq_square norm_mult[symmetric] norm_inverse[symmetric])
  83.374 -      using right_inverse[OF b']
  83.375 -      by (simp add: power2_eq_square[symmetric] power_inverse[symmetric] ring_simps)
  83.376 -    have th0: "cmod (complex_of_real (cmod b) / b) = 1"
  83.377 -      apply (simp add: complex_Re_mult cmod_def power2_eq_square Re_complex_of_real Im_complex_of_real divide_inverse ring_simps )
  83.378 -      by (simp add: real_sqrt_mult[symmetric] th0)        
  83.379 -    from o have "\<exists>m. n = Suc (2*m)" by presburger+
  83.380 -    then obtain m where m: "n = Suc (2*m)" by blast
  83.381 -    from unimodular_reduce_norm[OF th0] o
  83.382 -    have "\<exists>v. cmod (complex_of_real (cmod b) / b + v^n) < 1"
  83.383 -      apply (cases "cmod (complex_of_real (cmod b) / b + 1) < 1", rule_tac x="1" in exI, simp)
  83.384 -      apply (cases "cmod (complex_of_real (cmod b) / b - 1) < 1", rule_tac x="-1" in exI, simp add: diff_def)
  83.385 -      apply (cases "cmod (complex_of_real (cmod b) / b + ii) < 1")
  83.386 -      apply (cases "even m", rule_tac x="ii" in exI, simp add: m power_mult)
  83.387 -      apply (rule_tac x="- ii" in exI, simp add: m power_mult)
  83.388 -      apply (cases "even m", rule_tac x="- ii" in exI, simp add: m power_mult diff_def)
  83.389 -      apply (rule_tac x="ii" in exI, simp add: m power_mult diff_def)
  83.390 -      done
  83.391 -    then obtain v where v: "cmod (complex_of_real (cmod b) / b + v^n) < 1" by blast
  83.392 -    let ?w = "v / complex_of_real (root n (cmod b))"
  83.393 -    from odd_real_root_pow[OF o, of "cmod b"]
  83.394 -    have th1: "?w ^ n = v^n / complex_of_real (cmod b)" 
  83.395 -      by (simp add: power_divide complex_of_real_power)
  83.396 -    have th2:"cmod (complex_of_real (cmod b) / b) = 1" using b by (simp add: norm_divide)
  83.397 -    hence th3: "cmod (complex_of_real (cmod b) / b) \<ge> 0" by simp
  83.398 -    have th4: "cmod (complex_of_real (cmod b) / b) *
  83.399 -   cmod (1 + b * (v ^ n / complex_of_real (cmod b)))
  83.400 -   < cmod (complex_of_real (cmod b) / b) * 1"
  83.401 -      apply (simp only: norm_mult[symmetric] right_distrib)
  83.402 -      using b v by (simp add: th2)
  83.403 -
  83.404 -    from mult_less_imp_less_left[OF th4 th3]
  83.405 -    have "?P ?w n" unfolding th1 . 
  83.406 -    hence "\<exists>z. ?P z n" .. }
  83.407 -  ultimately show "\<exists>z. ?P z n" by blast
  83.408 -qed
  83.409 -
  83.410 -
  83.411 -text{* Bolzano-Weierstrass type property for closed disc in complex plane. *}
  83.412 -
  83.413 -lemma metric_bound_lemma: "cmod (x - y) <= \<bar>Re x - Re y\<bar> + \<bar>Im x - Im y\<bar>"
  83.414 -  using real_sqrt_sum_squares_triangle_ineq[of "Re x - Re y" 0 0 "Im x - Im y" ]
  83.415 -  unfolding cmod_def by simp
  83.416 -
  83.417 -lemma bolzano_weierstrass_complex_disc:
  83.418 -  assumes r: "\<forall>n. cmod (s n) \<le> r"
  83.419 -  shows "\<exists>f z. subseq f \<and> (\<forall>e >0. \<exists>N. \<forall>n \<ge> N. cmod (s (f n) - z) < e)"
  83.420 -proof-
  83.421 -  from seq_monosub[of "Re o s"] 
  83.422 -  obtain f g where f: "subseq f" "monoseq (\<lambda>n. Re (s (f n)))" 
  83.423 -    unfolding o_def by blast
  83.424 -  from seq_monosub[of "Im o s o f"] 
  83.425 -  obtain g where g: "subseq g" "monoseq (\<lambda>n. Im (s(f(g n))))" unfolding o_def by blast  
  83.426 -  let ?h = "f o g"
  83.427 -  from r[rule_format, of 0] have rp: "r \<ge> 0" using norm_ge_zero[of "s 0"] by arith 
  83.428 -  have th:"\<forall>n. r + 1 \<ge> \<bar> Re (s n)\<bar>" 
  83.429 -  proof
  83.430 -    fix n
  83.431 -    from abs_Re_le_cmod[of "s n"] r[rule_format, of n]  show "\<bar>Re (s n)\<bar> \<le> r + 1" by arith
  83.432 -  qed
  83.433 -  have conv1: "convergent (\<lambda>n. Re (s ( f n)))"
  83.434 -    apply (rule Bseq_monoseq_convergent)
  83.435 -    apply (simp add: Bseq_def)
  83.436 -    apply (rule exI[where x= "r + 1"])
  83.437 -    using th rp apply simp
  83.438 -    using f(2) .
  83.439 -  have th:"\<forall>n. r + 1 \<ge> \<bar> Im (s n)\<bar>" 
  83.440 -  proof
  83.441 -    fix n
  83.442 -    from abs_Im_le_cmod[of "s n"] r[rule_format, of n]  show "\<bar>Im (s n)\<bar> \<le> r + 1" by arith
  83.443 -  qed
  83.444 -
  83.445 -  have conv2: "convergent (\<lambda>n. Im (s (f (g n))))"
  83.446 -    apply (rule Bseq_monoseq_convergent)
  83.447 -    apply (simp add: Bseq_def)
  83.448 -    apply (rule exI[where x= "r + 1"])
  83.449 -    using th rp apply simp
  83.450 -    using g(2) .
  83.451 -
  83.452 -  from conv1[unfolded convergent_def] obtain x where "LIMSEQ (\<lambda>n. Re (s (f n))) x" 
  83.453 -    by blast 
  83.454 -  hence  x: "\<forall>r>0. \<exists>n0. \<forall>n\<ge>n0. \<bar> Re (s (f n)) - x \<bar> < r" 
  83.455 -    unfolding LIMSEQ_def real_norm_def .
  83.456 -
  83.457 -  from conv2[unfolded convergent_def] obtain y where "LIMSEQ (\<lambda>n. Im (s (f (g n)))) y" 
  83.458 -    by blast 
  83.459 -  hence  y: "\<forall>r>0. \<exists>n0. \<forall>n\<ge>n0. \<bar> Im (s (f (g n))) - y \<bar> < r" 
  83.460 -    unfolding LIMSEQ_def real_norm_def .
  83.461 -  let ?w = "Complex x y"
  83.462 -  from f(1) g(1) have hs: "subseq ?h" unfolding subseq_def by auto 
  83.463 -  {fix e assume ep: "e > (0::real)"
  83.464 -    hence e2: "e/2 > 0" by simp
  83.465 -    from x[rule_format, OF e2] y[rule_format, OF e2]
  83.466 -    obtain N1 N2 where N1: "\<forall>n\<ge>N1. \<bar>Re (s (f n)) - x\<bar> < e / 2" and N2: "\<forall>n\<ge>N2. \<bar>Im (s (f (g n))) - y\<bar> < e / 2" by blast
  83.467 -    {fix n assume nN12: "n \<ge> N1 + N2"
  83.468 -      hence nN1: "g n \<ge> N1" and nN2: "n \<ge> N2" using seq_suble[OF g(1), of n] by arith+
  83.469 -      from add_strict_mono[OF N1[rule_format, OF nN1] N2[rule_format, OF nN2]]
  83.470 -      have "cmod (s (?h n) - ?w) < e" 
  83.471 -	using metric_bound_lemma[of "s (f (g n))" ?w] by simp }
  83.472 -    hence "\<exists>N. \<forall>n\<ge>N. cmod (s (?h n) - ?w) < e" by blast }
  83.473 -  with hs show ?thesis  by blast  
  83.474 -qed
  83.475 -
  83.476 -text{* Polynomial is continuous. *}
  83.477 -
  83.478 -lemma poly_cont:
  83.479 -  assumes ep: "e > 0" 
  83.480 -  shows "\<exists>d >0. \<forall>w. 0 < cmod (w - z) \<and> cmod (w - z) < d \<longrightarrow> cmod (poly p w - poly p z) < e"
  83.481 -proof-
  83.482 -  from poly_offset[of p z] obtain q where q: "length q = length p" "\<And>x. poly q x = poly p (z + x)" by blast
  83.483 -  {fix w
  83.484 -    note q(2)[of "w - z", simplified]}
  83.485 -  note th = this
  83.486 -  show ?thesis unfolding th[symmetric]
  83.487 -  proof(induct q)
  83.488 -    case Nil thus ?case  using ep by auto
  83.489 -  next
  83.490 -    case (Cons c cs)
  83.491 -    from poly_bound_exists[of 1 "cs"] 
  83.492 -    obtain m where m: "m > 0" "\<And>z. cmod z \<le> 1 \<Longrightarrow> cmod (poly cs z) \<le> m" by blast
  83.493 -    from ep m(1) have em0: "e/m > 0" by (simp add: field_simps)
  83.494 -    have one0: "1 > (0::real)"  by arith
  83.495 -    from real_lbound_gt_zero[OF one0 em0] 
  83.496 -    obtain d where d: "d >0" "d < 1" "d < e / m" by blast
  83.497 -    from d(1,3) m(1) have dm: "d*m > 0" "d*m < e" 
  83.498 -      by (simp_all add: field_simps real_mult_order)
  83.499 -    show ?case 
  83.500 -      proof(rule ex_forward[OF real_lbound_gt_zero[OF one0 em0]], clarsimp simp add: norm_mult)
  83.501 -	fix d w
  83.502 -	assume H: "d > 0" "d < 1" "d < e/m" "w\<noteq>z" "cmod (w-z) < d"
  83.503 -	hence d1: "cmod (w-z) \<le> 1" "d \<ge> 0" by simp_all
  83.504 -	from H(3) m(1) have dme: "d*m < e" by (simp add: field_simps)
  83.505 -	from H have th: "cmod (w-z) \<le> d" by simp 
  83.506 -	from mult_mono[OF th m(2)[OF d1(1)] d1(2) norm_ge_zero] dme
  83.507 -	show "cmod (w - z) * cmod (poly cs (w - z)) < e" by simp
  83.508 -      qed  
  83.509 -    qed
  83.510 -qed
  83.511 -
  83.512 -text{* Hence a polynomial attains minimum on a closed disc 
  83.513 -  in the complex plane. *}
  83.514 -lemma  poly_minimum_modulus_disc:
  83.515 -  "\<exists>z. \<forall>w. cmod w \<le> r \<longrightarrow> cmod (poly p z) \<le> cmod (poly p w)"
  83.516 -proof-
  83.517 -  {assume "\<not> r \<ge> 0" hence ?thesis unfolding linorder_not_le
  83.518 -      apply -
  83.519 -      apply (rule exI[where x=0]) 
  83.520 -      apply auto
  83.521 -      apply (subgoal_tac "cmod w < 0")
  83.522 -      apply simp
  83.523 -      apply arith
  83.524 -      done }
  83.525 -  moreover
  83.526 -  {assume rp: "r \<ge> 0"
  83.527 -    from rp have "cmod 0 \<le> r \<and> cmod (poly p 0) = - (- cmod (poly p 0))" by simp 
  83.528 -    hence mth1: "\<exists>x z. cmod z \<le> r \<and> cmod (poly p z) = - x"  by blast
  83.529 -    {fix x z
  83.530 -      assume H: "cmod z \<le> r" "cmod (poly p z) = - x" "\<not>x < 1"
  83.531 -      hence "- x < 0 " by arith
  83.532 -      with H(2) norm_ge_zero[of "poly p z"]  have False by simp }
  83.533 -    then have mth2: "\<exists>z. \<forall>x. (\<exists>z. cmod z \<le> r \<and> cmod (poly p z) = - x) \<longrightarrow> x < z" by blast
  83.534 -    from real_sup_exists[OF mth1 mth2] obtain s where 
  83.535 -      s: "\<forall>y. (\<exists>x. (\<exists>z. cmod z \<le> r \<and> cmod (poly p z) = - x) \<and> y < x) \<longleftrightarrow>(y < s)" by blast
  83.536 -    let ?m = "-s"
  83.537 -    {fix y
  83.538 -      from s[rule_format, of "-y"] have 
  83.539 -    "(\<exists>z x. cmod z \<le> r \<and> -(- cmod (poly p z)) < y) \<longleftrightarrow> ?m < y" 
  83.540 -	unfolding minus_less_iff[of y ] equation_minus_iff by blast }
  83.541 -    note s1 = this[unfolded minus_minus]
  83.542 -    from s1[of ?m] have s1m: "\<And>z x. cmod z \<le> r \<Longrightarrow> cmod (poly p z) \<ge> ?m" 
  83.543 -      by auto
  83.544 -    {fix n::nat
  83.545 -      from s1[rule_format, of "?m + 1/real (Suc n)"] 
  83.546 -      have "\<exists>z. cmod z \<le> r \<and> cmod (poly p z) < - s + 1 / real (Suc n)"
  83.547 -	by simp}
  83.548 -    hence th: "\<forall>n. \<exists>z. cmod z \<le> r \<and> cmod (poly p z) < - s + 1 / real (Suc n)" ..
  83.549 -    from choice[OF th] obtain g where 
  83.550 -      g: "\<forall>n. cmod (g n) \<le> r" "\<forall>n. cmod (poly p (g n)) <?m+1 /real(Suc n)" 
  83.551 -      by blast
  83.552 -    from bolzano_weierstrass_complex_disc[OF g(1)] 
  83.553 -    obtain f z where fz: "subseq f" "\<forall>e>0. \<exists>N. \<forall>n\<ge>N. cmod (g (f n) - z) < e"
  83.554 -      by blast    
  83.555 -    {fix w 
  83.556 -      assume wr: "cmod w \<le> r"
  83.557 -      let ?e = "\<bar>cmod (poly p z) - ?m\<bar>"
  83.558 -      {assume e: "?e > 0"
  83.559 -	hence e2: "?e/2 > 0" by simp
  83.560 -	from poly_cont[OF e2, of z p] obtain d where
  83.561 -	  d: "d>0" "\<forall>w. 0<cmod (w - z)\<and> cmod(w - z) < d \<longrightarrow> cmod(poly p w - poly p z) < ?e/2" by blast
  83.562 -	{fix w assume w: "cmod (w - z) < d"
  83.563 -	  have "cmod(poly p w - poly p z) < ?e / 2"
  83.564 -	    using d(2)[rule_format, of w] w e by (cases "w=z", simp_all)}
  83.565 -	note th1 = this
  83.566 -	
  83.567 -	from fz(2)[rule_format, OF d(1)] obtain N1 where 
  83.568 -	  N1: "\<forall>n\<ge>N1. cmod (g (f n) - z) < d" by blast
  83.569 -	from reals_Archimedean2[of "2/?e"] obtain N2::nat where
  83.570 -	  N2: "2/?e < real N2" by blast
  83.571 -	have th2: "cmod(poly p (g(f(N1 + N2))) - poly p z) < ?e/2"
  83.572 -	  using N1[rule_format, of "N1 + N2"] th1 by simp
  83.573 -	{fix a b e2 m :: real
  83.574 -	have "a < e2 \<Longrightarrow> abs(b - m) < e2 \<Longrightarrow> 2 * e2 <= abs(b - m) + a
  83.575 -          ==> False" by arith}
  83.576 -      note th0 = this
  83.577 -      have ath: 
  83.578 -	"\<And>m x e. m <= x \<Longrightarrow>  x < m + e ==> abs(x - m::real) < e" by arith
  83.579 -      from s1m[OF g(1)[rule_format]]
  83.580 -      have th31: "?m \<le> cmod(poly p (g (f (N1 + N2))))" .
  83.581 -      from seq_suble[OF fz(1), of "N1+N2"]
  83.582 -      have th00: "real (Suc (N1+N2)) \<le> real (Suc (f (N1+N2)))" by simp
  83.583 -      have th000: "0 \<le> (1::real)" "(1::real) \<le> 1" "real (Suc (N1+N2)) > 0"  
  83.584 -	using N2 by auto
  83.585 -      from frac_le[OF th000 th00] have th00: "?m +1 / real (Suc (f (N1 + N2))) \<le> ?m + 1 / real (Suc (N1 + N2))" by simp
  83.586 -      from g(2)[rule_format, of "f (N1 + N2)"]
  83.587 -      have th01:"cmod (poly p (g (f (N1 + N2)))) < - s + 1 / real (Suc (f (N1 + N2)))" .
  83.588 -      from order_less_le_trans[OF th01 th00]
  83.589 -      have th32: "cmod(poly p (g (f (N1 + N2)))) < ?m + (1/ real(Suc (N1 + N2)))" .
  83.590 -      from N2 have "2/?e < real (Suc (N1 + N2))" by arith
  83.591 -      with e2 less_imp_inverse_less[of "2/?e" "real (Suc (N1 + N2))"]
  83.592 -      have "?e/2 > 1/ real (Suc (N1 + N2))" by (simp add: inverse_eq_divide)
  83.593 -      with ath[OF th31 th32]
  83.594 -      have thc1:"\<bar>cmod(poly p (g (f (N1 + N2)))) - ?m\<bar>< ?e/2" by arith  
  83.595 -      have ath2: "\<And>(a::real) b c m. \<bar>a - b\<bar> <= c ==> \<bar>b - m\<bar> <= \<bar>a - m\<bar> + c" 
  83.596 -	by arith
  83.597 -      have th22: "\<bar>cmod (poly p (g (f (N1 + N2)))) - cmod (poly p z)\<bar>
  83.598 -\<le> cmod (poly p (g (f (N1 + N2))) - poly p z)" 
  83.599 -	by (simp add: norm_triangle_ineq3)
  83.600 -      from ath2[OF th22, of ?m]
  83.601 -      have thc2: "2*(?e/2) \<le> \<bar>cmod(poly p (g (f (N1 + N2)))) - ?m\<bar> + cmod (poly p (g (f (N1 + N2))) - poly p z)" by simp
  83.602 -      from th0[OF th2 thc1 thc2] have False .}
  83.603 -      hence "?e = 0" by auto
  83.604 -      then have "cmod (poly p z) = ?m" by simp  
  83.605 -      with s1m[OF wr]
  83.606 -      have "cmod (poly p z) \<le> cmod (poly p w)" by simp }
  83.607 -    hence ?thesis by blast}
  83.608 -  ultimately show ?thesis by blast
  83.609 -qed
  83.610 -
  83.611 -lemma "(rcis (sqrt (abs r)) (a/2)) ^ 2 = rcis (abs r) a"
  83.612 -  unfolding power2_eq_square
  83.613 -  apply (simp add: rcis_mult)
  83.614 -  apply (simp add: power2_eq_square[symmetric])
  83.615 -  done
  83.616 -
  83.617 -lemma cispi: "cis pi = -1" 
  83.618 -  unfolding cis_def
  83.619 -  by simp
  83.620 -
  83.621 -lemma "(rcis (sqrt (abs r)) ((pi + a)/2)) ^ 2 = rcis (- abs r) a"
  83.622 -  unfolding power2_eq_square
  83.623 -  apply (simp add: rcis_mult add_divide_distrib)
  83.624 -  apply (simp add: power2_eq_square[symmetric] rcis_def cispi cis_mult[symmetric])
  83.625 -  done
  83.626 -
  83.627 -text {* Nonzero polynomial in z goes to infinity as z does. *}
  83.628 -
  83.629 -instance complex::idom_char_0 by (intro_classes)
  83.630 -instance complex :: recpower_idom_char_0 by intro_classes
  83.631 -
  83.632 -lemma poly_infinity:
  83.633 -  assumes ex: "list_ex (\<lambda>c. c \<noteq> 0) p"
  83.634 -  shows "\<exists>r. \<forall>z. r \<le> cmod z \<longrightarrow> d \<le> cmod (poly (a#p) z)"
  83.635 -using ex
  83.636 -proof(induct p arbitrary: a d)
  83.637 -  case (Cons c cs a d) 
  83.638 -  {assume H: "list_ex (\<lambda>c. c\<noteq>0) cs"
  83.639 -    with Cons.hyps obtain r where r: "\<forall>z. r \<le> cmod z \<longrightarrow> d + cmod a \<le> cmod (poly (c # cs) z)" by blast
  83.640 -    let ?r = "1 + \<bar>r\<bar>"
  83.641 -    {fix z assume h: "1 + \<bar>r\<bar> \<le> cmod z"
  83.642 -      have r0: "r \<le> cmod z" using h by arith
  83.643 -      from r[rule_format, OF r0]
  83.644 -      have th0: "d + cmod a \<le> 1 * cmod(poly (c#cs) z)" by arith
  83.645 -      from h have z1: "cmod z \<ge> 1" by arith
  83.646 -      from order_trans[OF th0 mult_right_mono[OF z1 norm_ge_zero[of "poly (c#cs) z"]]]
  83.647 -      have th1: "d \<le> cmod(z * poly (c#cs) z) - cmod a"
  83.648 -	unfolding norm_mult by (simp add: ring_simps)
  83.649 -      from complex_mod_triangle_sub[of "z * poly (c#cs) z" a]
  83.650 -      have th2: "cmod(z * poly (c#cs) z) - cmod a \<le> cmod (poly (a#c#cs) z)" 
  83.651 -	by (simp add: diff_le_eq ring_simps) 
  83.652 -      from th1 th2 have "d \<le> cmod (poly (a#c#cs) z)"  by arith}
  83.653 -    hence ?case by blast}
  83.654 -  moreover
  83.655 -  {assume cs0: "\<not> (list_ex (\<lambda>c. c \<noteq> 0) cs)"
  83.656 -    with Cons.prems have c0: "c \<noteq> 0" by simp
  83.657 -    from cs0 have cs0': "list_all (\<lambda>c. c = 0) cs" 
  83.658 -      by (auto simp add: list_all_iff list_ex_iff)
  83.659 -    {fix z
  83.660 -      assume h: "(\<bar>d\<bar> + cmod a) / cmod c \<le> cmod z"
  83.661 -      from c0 have "cmod c > 0" by simp
  83.662 -      from h c0 have th0: "\<bar>d\<bar> + cmod a \<le> cmod (z*c)" 
  83.663 -	by (simp add: field_simps norm_mult)
  83.664 -      have ath: "\<And>mzh mazh ma. mzh <= mazh + ma ==> abs(d) + ma <= mzh ==> d <= mazh" by arith
  83.665 -      from complex_mod_triangle_sub[of "z*c" a ]
  83.666 -      have th1: "cmod (z * c) \<le> cmod (a + z * c) + cmod a"
  83.667 -	by (simp add: ring_simps)
  83.668 -      from ath[OF th1 th0] have "d \<le> cmod (poly (a # c # cs) z)" 
  83.669 -	using poly_0[OF cs0'] by simp}
  83.670 -    then have ?case  by blast}
  83.671 -  ultimately show ?case by blast
  83.672 -qed simp
  83.673 -
  83.674 -text {* Hence polynomial's modulus attains its minimum somewhere. *}
  83.675 -lemma poly_minimum_modulus:
  83.676 -  "\<exists>z.\<forall>w. cmod (poly p z) \<le> cmod (poly p w)"
  83.677 -proof(induct p)
  83.678 -  case (Cons c cs) 
  83.679 -  {assume cs0: "list_ex (\<lambda>c. c \<noteq> 0) cs"
  83.680 -    from poly_infinity[OF cs0, of "cmod (poly (c#cs) 0)" c]
  83.681 -    obtain r where r: "\<And>z. r \<le> cmod z \<Longrightarrow> cmod (poly (c # cs) 0) \<le> cmod (poly (c # cs) z)" by blast
  83.682 -    have ath: "\<And>z r. r \<le> cmod z \<or> cmod z \<le> \<bar>r\<bar>" by arith
  83.683 -    from poly_minimum_modulus_disc[of "\<bar>r\<bar>" "c#cs"] 
  83.684 -    obtain v where v: "\<And>w. cmod w \<le> \<bar>r\<bar> \<Longrightarrow> cmod (poly (c # cs) v) \<le> cmod (poly (c # cs) w)" by blast
  83.685 -    {fix z assume z: "r \<le> cmod z"
  83.686 -      from v[of 0] r[OF z] 
  83.687 -      have "cmod (poly (c # cs) v) \<le> cmod (poly (c # cs) z)"
  83.688 -	by simp }
  83.689 -    note v0 = this
  83.690 -    from v0 v ath[of r] have ?case by blast}
  83.691 -  moreover
  83.692 -  {assume cs0: "\<not> (list_ex (\<lambda>c. c\<noteq>0) cs)"
  83.693 -    hence th:"list_all (\<lambda>c. c = 0) cs" by (simp add: list_all_iff list_ex_iff)
  83.694 -    from poly_0[OF th] Cons.hyps have ?case by simp}
  83.695 -  ultimately show ?case by blast
  83.696 -qed simp
  83.697 -
  83.698 -text{* Constant function (non-syntactic characterization). *}
  83.699 -definition "constant f = (\<forall>x y. f x = f y)"
  83.700 -
  83.701 -lemma nonconstant_length: "\<not> (constant (poly p)) \<Longrightarrow> length p \<ge> 2"
  83.702 -  unfolding constant_def
  83.703 -  apply (induct p, auto)
  83.704 -  apply (unfold not_less[symmetric])
  83.705 -  apply simp
  83.706 -  apply (rule ccontr)
  83.707 -  apply auto
  83.708 -  done
  83.709 - 
  83.710 -lemma poly_replicate_append:
  83.711 -  "poly ((replicate n 0)@p) (x::'a::{recpower, comm_ring}) = x^n * poly p x"
  83.712 -  by(induct n, auto simp add: power_Suc ring_simps)
  83.713 -
  83.714 -text {* Decomposition of polynomial, skipping zero coefficients 
  83.715 -  after the first.  *}
  83.716 -
  83.717 -lemma poly_decompose_lemma:
  83.718 - assumes nz: "\<not>(\<forall>z. z\<noteq>0 \<longrightarrow> poly p z = (0::'a::{recpower,idom}))"
  83.719 -  shows "\<exists>k a q. a\<noteq>0 \<and> Suc (length q + k) = length p \<and> 
  83.720 -                 (\<forall>z. poly p z = z^k * poly (a#q) z)"
  83.721 -using nz
  83.722 -proof(induct p)
  83.723 -  case Nil thus ?case by simp
  83.724 -next
  83.725 -  case (Cons c cs)
  83.726 -  {assume c0: "c = 0"
  83.727 -    
  83.728 -    from Cons.hyps Cons.prems c0 have ?case apply auto
  83.729 -      apply (rule_tac x="k+1" in exI)
  83.730 -      apply (rule_tac x="a" in exI, clarsimp)
  83.731 -      apply (rule_tac x="q" in exI)
  83.732 -      by (auto simp add: power_Suc)}
  83.733 -  moreover
  83.734 -  {assume c0: "c\<noteq>0"
  83.735 -    hence ?case apply-
  83.736 -      apply (rule exI[where x=0])
  83.737 -      apply (rule exI[where x=c], clarsimp)
  83.738 -      apply (rule exI[where x=cs])
  83.739 -      apply auto
  83.740 -      done}
  83.741 -  ultimately show ?case by blast
  83.742 -qed
  83.743 -
  83.744 -lemma poly_decompose:
  83.745 -  assumes nc: "~constant(poly p)"
  83.746 -  shows "\<exists>k a q. a\<noteq>(0::'a::{recpower,idom}) \<and> k\<noteq>0 \<and>
  83.747 -               length q + k + 1 = length p \<and> 
  83.748 -              (\<forall>z. poly p z = poly p 0 + z^k * poly (a#q) z)"
  83.749 -using nc 
  83.750 -proof(induct p)
  83.751 -  case Nil thus ?case by (simp add: constant_def)
  83.752 -next
  83.753 -  case (Cons c cs)
  83.754 -  {assume C:"\<forall>z. z \<noteq> 0 \<longrightarrow> poly cs z = 0"
  83.755 -    {fix x y
  83.756 -      from C have "poly (c#cs) x = poly (c#cs) y" by (cases "x=0", auto)}
  83.757 -    with Cons.prems have False by (auto simp add: constant_def)}
  83.758 -  hence th: "\<not> (\<forall>z. z \<noteq> 0 \<longrightarrow> poly cs z = 0)" ..
  83.759 -  from poly_decompose_lemma[OF th] 
  83.760 -  show ?case 
  83.761 -    apply clarsimp    
  83.762 -    apply (rule_tac x="k+1" in exI)
  83.763 -    apply (rule_tac x="a" in exI)
  83.764 -    apply simp
  83.765 -    apply (rule_tac x="q" in exI)
  83.766 -    apply (auto simp add: power_Suc)
  83.767 -    done
  83.768 -qed
  83.769 -
  83.770 -text{* Fundamental theorem of algebral *}
  83.771 -
  83.772 -lemma fundamental_theorem_of_algebra:
  83.773 -  assumes nc: "~constant(poly p)"
  83.774 -  shows "\<exists>z::complex. poly p z = 0"
  83.775 -using nc
  83.776 -proof(induct n\<equiv> "length p" arbitrary: p rule: nat_less_induct)
  83.777 -  fix n fix p :: "complex list"
  83.778 -  let ?p = "poly p"
  83.779 -  assume H: "\<forall>m<n. \<forall>p. \<not> constant (poly p) \<longrightarrow> m = length p \<longrightarrow> (\<exists>(z::complex). poly p z = 0)" and nc: "\<not> constant ?p" and n: "n = length p"
  83.780 -  let ?ths = "\<exists>z. ?p z = 0"
  83.781 -
  83.782 -  from nonconstant_length[OF nc] have n2: "n\<ge> 2" by (simp add: n)
  83.783 -  from poly_minimum_modulus obtain c where 
  83.784 -    c: "\<forall>w. cmod (?p c) \<le> cmod (?p w)" by blast
  83.785 -  {assume pc: "?p c = 0" hence ?ths by blast}
  83.786 -  moreover
  83.787 -  {assume pc0: "?p c \<noteq> 0"
  83.788 -    from poly_offset[of p c] obtain q where
  83.789 -      q: "length q = length p" "\<forall>x. poly q x = ?p (c+x)" by blast
  83.790 -    {assume h: "constant (poly q)"
  83.791 -      from q(2) have th: "\<forall>x. poly q (x - c) = ?p x" by auto
  83.792 -      {fix x y
  83.793 -	from th have "?p x = poly q (x - c)" by auto 
  83.794 -	also have "\<dots> = poly q (y - c)" 
  83.795 -	  using h unfolding constant_def by blast
  83.796 -	also have "\<dots> = ?p y" using th by auto
  83.797 -	finally have "?p x = ?p y" .}
  83.798 -      with nc have False unfolding constant_def by blast }
  83.799 -    hence qnc: "\<not> constant (poly q)" by blast
  83.800 -    from q(2) have pqc0: "?p c = poly q 0" by simp
  83.801 -    from c pqc0 have cq0: "\<forall>w. cmod (poly q 0) \<le> cmod (?p w)" by simp 
  83.802 -    let ?a0 = "poly q 0"
  83.803 -    from pc0 pqc0 have a00: "?a0 \<noteq> 0" by simp 
  83.804 -    from a00 
  83.805 -    have qr: "\<forall>z. poly q z = poly (map (op * (inverse ?a0)) q) z * ?a0"
  83.806 -      by (simp add: poly_cmult_map)
  83.807 -    let ?r = "map (op * (inverse ?a0)) q"
  83.808 -    have lgqr: "length q = length ?r" by simp 
  83.809 -    {assume h: "\<And>x y. poly ?r x = poly ?r y"
  83.810 -      {fix x y
  83.811 -	from qr[rule_format, of x] 
  83.812 -	have "poly q x = poly ?r x * ?a0" by auto
  83.813 -	also have "\<dots> = poly ?r y * ?a0" using h by simp
  83.814 -	also have "\<dots> = poly q y" using qr[rule_format, of y] by simp
  83.815 -	finally have "poly q x = poly q y" .} 
  83.816 -      with qnc have False unfolding constant_def by blast}
  83.817 -    hence rnc: "\<not> constant (poly ?r)" unfolding constant_def by blast
  83.818 -    from qr[rule_format, of 0] a00  have r01: "poly ?r 0 = 1" by auto
  83.819 -    {fix w 
  83.820 -      have "cmod (poly ?r w) < 1 \<longleftrightarrow> cmod (poly q w / ?a0) < 1"
  83.821 -	using qr[rule_format, of w] a00 by simp
  83.822 -      also have "\<dots> \<longleftrightarrow> cmod (poly q w) < cmod ?a0"
  83.823 -	using a00 unfolding norm_divide by (simp add: field_simps)
  83.824 -      finally have "cmod (poly ?r w) < 1 \<longleftrightarrow> cmod (poly q w) < cmod ?a0" .}
  83.825 -    note mrmq_eq = this
  83.826 -    from poly_decompose[OF rnc] obtain k a s where 
  83.827 -      kas: "a\<noteq>0" "k\<noteq>0" "length s + k + 1 = length ?r" 
  83.828 -      "\<forall>z. poly ?r z = poly ?r 0 + z^k* poly (a#s) z" by blast
  83.829 -    {assume "k + 1 = n"
  83.830 -      with kas(3) lgqr[symmetric] q(1) n[symmetric] have s0:"s=[]" by auto
  83.831 -      {fix w
  83.832 -	have "cmod (poly ?r w) = cmod (1 + a * w ^ k)" 
  83.833 -	  using kas(4)[rule_format, of w] s0 r01 by (simp add: ring_simps)}
  83.834 -      note hth = this [symmetric]
  83.835 -	from reduce_poly_simple[OF kas(1,2)] 
  83.836 -      have "\<exists>w. cmod (poly ?r w) < 1" unfolding hth by blast}
  83.837 -    moreover
  83.838 -    {assume kn: "k+1 \<noteq> n"
  83.839 -      from kn kas(3) q(1) n[symmetric] have k1n: "k + 1 < n" by simp
  83.840 -      have th01: "\<not> constant (poly (1#((replicate (k - 1) 0)@[a])))" 
  83.841 -	unfolding constant_def poly_Nil poly_Cons poly_replicate_append
  83.842 -	using kas(1) apply simp 
  83.843 -	by (rule exI[where x=0], rule exI[where x=1], simp)
  83.844 -      from kas(2) have th02: "k+1 = length (1#((replicate (k - 1) 0)@[a]))" 
  83.845 -	by simp
  83.846 -      from H[rule_format, OF k1n th01 th02]
  83.847 -      obtain w where w: "1 + w^k * a = 0"
  83.848 -	unfolding poly_Nil poly_Cons poly_replicate_append
  83.849 -	using kas(2) by (auto simp add: power_Suc[symmetric, of _ "k - Suc 0"] 
  83.850 -	  mult_assoc[of _ _ a, symmetric])
  83.851 -      from poly_bound_exists[of "cmod w" s] obtain m where 
  83.852 -	m: "m > 0" "\<forall>z. cmod z \<le> cmod w \<longrightarrow> cmod (poly s z) \<le> m" by blast
  83.853 -      have w0: "w\<noteq>0" using kas(2) w by (auto simp add: power_0_left)
  83.854 -      from w have "(1 + w ^ k * a) - 1 = 0 - 1" by simp
  83.855 -      then have wm1: "w^k * a = - 1" by simp
  83.856 -      have inv0: "0 < inverse (cmod w ^ (k + 1) * m)" 
  83.857 -	using norm_ge_zero[of w] w0 m(1)
  83.858 -	  by (simp add: inverse_eq_divide zero_less_mult_iff)
  83.859 -      with real_down2[OF zero_less_one] obtain t where
  83.860 -	t: "t > 0" "t < 1" "t < inverse (cmod w ^ (k + 1) * m)" by blast
  83.861 -      let ?ct = "complex_of_real t"
  83.862 -      let ?w = "?ct * w"
  83.863 -      have "1 + ?w^k * (a + ?w * poly s ?w) = 1 + ?ct^k * (w^k * a) + ?w^k * ?w * poly s ?w" using kas(1) by (simp add: ring_simps power_mult_distrib)
  83.864 -      also have "\<dots> = complex_of_real (1 - t^k) + ?w^k * ?w * poly s ?w"
  83.865 -	unfolding wm1 by (simp)
  83.866 -      finally have "cmod (1 + ?w^k * (a + ?w * poly s ?w)) = cmod (complex_of_real (1 - t^k) + ?w^k * ?w * poly s ?w)" 
  83.867 -	apply -
  83.868 -	apply (rule cong[OF refl[of cmod]])
  83.869 -	apply assumption
  83.870 -	done
  83.871 -      with norm_triangle_ineq[of "complex_of_real (1 - t^k)" "?w^k * ?w * poly s ?w"] 
  83.872 -      have th11: "cmod (1 + ?w^k * (a + ?w * poly s ?w)) \<le> \<bar>1 - t^k\<bar> + cmod (?w^k * ?w * poly s ?w)" unfolding norm_of_real by simp 
  83.873 -      have ath: "\<And>x (t::real). 0\<le> x \<Longrightarrow> x < t \<Longrightarrow> t\<le>1 \<Longrightarrow> \<bar>1 - t\<bar> + x < 1" by arith
  83.874 -      have "t *cmod w \<le> 1 * cmod w" apply (rule mult_mono) using t(1,2) by auto
  83.875 -      then have tw: "cmod ?w \<le> cmod w" using t(1) by (simp add: norm_mult) 
  83.876 -      from t inv0 have "t* (cmod w ^ (k + 1) * m) < 1"
  83.877 -	by (simp add: inverse_eq_divide field_simps)
  83.878 -      with zero_less_power[OF t(1), of k] 
  83.879 -      have th30: "t^k * (t* (cmod w ^ (k + 1) * m)) < t^k * 1" 
  83.880 -	apply - apply (rule mult_strict_left_mono) by simp_all
  83.881 -      have "cmod (?w^k * ?w * poly s ?w) = t^k * (t* (cmod w ^ (k+1) * cmod (poly s ?w)))"  using w0 t(1)
  83.882 -	by (simp add: ring_simps power_mult_distrib norm_of_real norm_power norm_mult)
  83.883 -      then have "cmod (?w^k * ?w * poly s ?w) \<le> t^k * (t* (cmod w ^ (k + 1) * m))"
  83.884 -	using t(1,2) m(2)[rule_format, OF tw] w0
  83.885 -	apply (simp only: )
  83.886 -	apply auto
  83.887 -	apply (rule mult_mono, simp_all add: norm_ge_zero)+
  83.888 -	apply (simp add: zero_le_mult_iff zero_le_power)
  83.889 -	done
  83.890 -      with th30 have th120: "cmod (?w^k * ?w * poly s ?w) < t^k" by simp 
  83.891 -      from power_strict_mono[OF t(2), of k] t(1) kas(2) have th121: "t^k \<le> 1" 
  83.892 -	by auto
  83.893 -      from ath[OF norm_ge_zero[of "?w^k * ?w * poly s ?w"] th120 th121]
  83.894 -      have th12: "\<bar>1 - t^k\<bar> + cmod (?w^k * ?w * poly s ?w) < 1" . 
  83.895 -      from th11 th12
  83.896 -      have "cmod (1 + ?w^k * (a + ?w * poly s ?w)) < 1"  by arith 
  83.897 -      then have "cmod (poly ?r ?w) < 1" 
  83.898 -	unfolding kas(4)[rule_format, of ?w] r01 by simp 
  83.899 -      then have "\<exists>w. cmod (poly ?r w) < 1" by blast}
  83.900 -    ultimately have cr0_contr: "\<exists>w. cmod (poly ?r w) < 1" by blast
  83.901 -    from cr0_contr cq0 q(2)
  83.902 -    have ?ths unfolding mrmq_eq not_less[symmetric] by auto}
  83.903 -  ultimately show ?ths by blast
  83.904 -qed
  83.905 -
  83.906 -text {* Alternative version with a syntactic notion of constant polynomial. *}
  83.907 -
  83.908 -lemma fundamental_theorem_of_algebra_alt:
  83.909 -  assumes nc: "~(\<exists>a l. a\<noteq> 0 \<and> list_all(\<lambda>b. b = 0) l \<and> p = a#l)"
  83.910 -  shows "\<exists>z. poly p z = (0::complex)"
  83.911 -using nc
  83.912 -proof(induct p)
  83.913 -  case (Cons c cs)
  83.914 -  {assume "c=0" hence ?case by auto}
  83.915 -  moreover
  83.916 -  {assume c0: "c\<noteq>0"
  83.917 -    {assume nc: "constant (poly (c#cs))"
  83.918 -      from nc[unfolded constant_def, rule_format, of 0] 
  83.919 -      have "\<forall>w. w \<noteq> 0 \<longrightarrow> poly cs w = 0" by auto 
  83.920 -      hence "list_all (\<lambda>c. c=0) cs"
  83.921 -	proof(induct cs)
  83.922 -	  case (Cons d ds)
  83.923 -	  {assume "d=0" hence ?case using Cons.prems Cons.hyps by simp}
  83.924 -	  moreover
  83.925 -	  {assume d0: "d\<noteq>0"
  83.926 -	    from poly_bound_exists[of 1 ds] obtain m where 
  83.927 -	      m: "m > 0" "\<forall>z. \<forall>z. cmod z \<le> 1 \<longrightarrow> cmod (poly ds z) \<le> m" by blast
  83.928 -	    have dm: "cmod d / m > 0" using d0 m(1) by (simp add: field_simps)
  83.929 -	    from real_down2[OF dm zero_less_one] obtain x where 
  83.930 -	      x: "x > 0" "x < cmod d / m" "x < 1" by blast
  83.931 -	    let ?x = "complex_of_real x"
  83.932 -	    from x have cx: "?x \<noteq> 0"  "cmod ?x \<le> 1" by simp_all
  83.933 -	    from Cons.prems[rule_format, OF cx(1)]
  83.934 -	    have cth: "cmod (?x*poly ds ?x) = cmod d" by (simp add: eq_diff_eq[symmetric])
  83.935 -	    from m(2)[rule_format, OF cx(2)] x(1)
  83.936 -	    have th0: "cmod (?x*poly ds ?x) \<le> x*m"
  83.937 -	      by (simp add: norm_mult)
  83.938 -	    from x(2) m(1) have "x*m < cmod d" by (simp add: field_simps)
  83.939 -	    with th0 have "cmod (?x*poly ds ?x) \<noteq> cmod d" by auto
  83.940 -	    with cth  have ?case by blast}
  83.941 -	  ultimately show ?case by blast 
  83.942 -	qed simp}
  83.943 -      then have nc: "\<not> constant (poly (c#cs))" using Cons.prems c0 
  83.944 -	by blast
  83.945 -      from fundamental_theorem_of_algebra[OF nc] have ?case .}
  83.946 -  ultimately show ?case by blast  
  83.947 -qed simp
  83.948 -
  83.949 -subsection{* Nullstellenstatz, degrees and divisibility of polynomials *}
  83.950 -
  83.951 -lemma nullstellensatz_lemma:
  83.952 -  fixes p :: "complex list"
  83.953 -  assumes "\<forall>x. poly p x = 0 \<longrightarrow> poly q x = 0"
  83.954 -  and "degree p = n" and "n \<noteq> 0"
  83.955 -  shows "p divides (pexp q n)"
  83.956 -using prems
  83.957 -proof(induct n arbitrary: p q rule: nat_less_induct)
  83.958 -  fix n::nat fix p q :: "complex list"
  83.959 -  assume IH: "\<forall>m<n. \<forall>p q.
  83.960 -                 (\<forall>x. poly p x = (0::complex) \<longrightarrow> poly q x = 0) \<longrightarrow>
  83.961 -                 degree p = m \<longrightarrow> m \<noteq> 0 \<longrightarrow> p divides (q %^ m)"
  83.962 -    and pq0: "\<forall>x. poly p x = 0 \<longrightarrow> poly q x = 0" 
  83.963 -    and dpn: "degree p = n" and n0: "n \<noteq> 0"
  83.964 -  let ?ths = "p divides (q %^ n)"
  83.965 -  {fix a assume a: "poly p a = 0"
  83.966 -    {assume p0: "poly p = poly []" 
  83.967 -      hence ?ths unfolding divides_def  using pq0 n0
  83.968 -	apply - apply (rule exI[where x="[]"], rule ext)
  83.969 -	by (auto simp add: poly_mult poly_exp)}
  83.970 -    moreover
  83.971 -    {assume p0: "poly p \<noteq> poly []" 
  83.972 -      and oa: "order  a p \<noteq> 0"
  83.973 -      from p0 have pne: "p \<noteq> []" by auto
  83.974 -      let ?op = "order a p"
  83.975 -      from p0 have ap: "([- a, 1] %^ ?op) divides p" 
  83.976 -	"\<not> pexp [- a, 1] (Suc ?op) divides p" using order by blast+ 
  83.977 -      note oop = order_degree[OF p0, unfolded dpn]
  83.978 -      {assume q0: "q = []"
  83.979 -	hence ?ths using n0 unfolding divides_def 
  83.980 -	  apply simp
  83.981 -	  apply (rule exI[where x="[]"], rule ext)
  83.982 -	  by (simp add: divides_def poly_exp poly_mult)}
  83.983 -      moreover
  83.984 -      {assume q0: "q\<noteq>[]"
  83.985 -	from pq0[rule_format, OF a, unfolded poly_linear_divides] q0
  83.986 -	obtain r where r: "q = pmult [- a, 1] r" by blast
  83.987 -	from ap[unfolded divides_def] obtain s where
  83.988 -	  s: "poly p = poly (pmult (pexp [- a, 1] ?op) s)" by blast
  83.989 -	have s0: "poly s \<noteq> poly []"
  83.990 -	  using s p0 by (simp add: poly_entire)
  83.991 -	hence pns0: "poly (pnormalize s) \<noteq> poly []" and sne: "s\<noteq>[]" by auto
  83.992 -	{assume ds0: "degree s = 0"
  83.993 -	  from ds0 pns0 have "\<exists>k. pnormalize s = [k]" unfolding degree_def 
  83.994 -	    by (cases "pnormalize s", auto)
  83.995 -	  then obtain k where kpn: "pnormalize s = [k]" by blast
  83.996 -	  from pns0[unfolded poly_zero] kpn have k: "k \<noteq>0" "poly s = poly [k]"
  83.997 -	    using poly_normalize[of s] by simp_all
  83.998 -	  let ?w = "pmult (pmult [1/k] (pexp [-a,1] (n - ?op))) (pexp r n)"
  83.999 -	  from k r s oop have "poly (pexp q n) = poly (pmult p ?w)"
 83.1000 -	    by - (rule ext, simp add: poly_mult poly_exp poly_cmult poly_add power_add[symmetric] ring_simps power_mult_distrib[symmetric])
 83.1001 -	  hence ?ths unfolding divides_def by blast}
 83.1002 -	moreover
 83.1003 -	{assume ds0: "degree s \<noteq> 0"
 83.1004 -	  from ds0 s0 dpn degree_unique[OF s, unfolded linear_pow_mul_degree] oa
 83.1005 -	    have dsn: "degree s < n" by auto 
 83.1006 -	    {fix x assume h: "poly s x = 0"
 83.1007 -	      {assume xa: "x = a"
 83.1008 -		from h[unfolded xa poly_linear_divides] sne obtain u where
 83.1009 -		  u: "s = pmult [- a, 1] u" by blast
 83.1010 -		have "poly p = poly (pmult (pexp [- a, 1] (Suc ?op)) u)"
 83.1011 -		  unfolding s u
 83.1012 -		  apply (rule ext)
 83.1013 -		  by (simp add: ring_simps power_mult_distrib[symmetric] poly_mult poly_cmult poly_add poly_exp)
 83.1014 -		with ap(2)[unfolded divides_def] have False by blast}
 83.1015 -	      note xa = this
 83.1016 -	      from h s have "poly p x = 0" by (simp add: poly_mult)
 83.1017 -	      with pq0 have "poly q x = 0" by blast
 83.1018 -	      with r xa have "poly r x = 0"
 83.1019 -		by (auto simp add: poly_mult poly_add poly_cmult eq_diff_eq[symmetric])}
 83.1020 -	    note impth = this
 83.1021 -	    from IH[rule_format, OF dsn, of s r] impth ds0
 83.1022 -	    have "s divides (pexp r (degree s))" by blast
 83.1023 -	    then obtain u where u: "poly (pexp r (degree s)) = poly (pmult s u)"
 83.1024 -	      unfolding divides_def by blast
 83.1025 -	    hence u': "\<And>x. poly s x * poly u x = poly r x ^ degree s"
 83.1026 -	      by (simp add: poly_mult[symmetric] poly_exp[symmetric])
 83.1027 -	    let ?w = "pmult (pmult u (pexp [-a,1] (n - ?op))) (pexp r (n - degree s))"
 83.1028 -	    from u' s r oop[of a] dsn have "poly (pexp q n) = poly (pmult p ?w)"
 83.1029 -	      apply - apply (rule ext)
 83.1030 -	      apply (simp only:  power_mult_distrib power_add[symmetric] poly_add poly_mult poly_exp poly_cmult ring_simps)
 83.1031 -	      
 83.1032 -	      apply (simp add:  power_mult_distrib power_add[symmetric] poly_add poly_mult poly_exp poly_cmult mult_assoc[symmetric])
 83.1033 -	      done
 83.1034 -	    hence ?ths unfolding divides_def by blast}
 83.1035 -      ultimately have ?ths by blast }
 83.1036 -      ultimately have ?ths by blast}
 83.1037 -    ultimately have ?ths using a order_root by blast}
 83.1038 -  moreover
 83.1039 -  {assume exa: "\<not> (\<exists>a. poly p a = 0)"
 83.1040 -    from fundamental_theorem_of_algebra_alt[of p] exa obtain c cs where
 83.1041 -      ccs: "c\<noteq>0" "list_all (\<lambda>c. c = 0) cs" "p = c#cs" by blast
 83.1042 -    
 83.1043 -    from poly_0[OF ccs(2)] ccs(3) 
 83.1044 -    have pp: "\<And>x. poly p x =  c" by simp
 83.1045 -    let ?w = "pmult [1/c] (pexp q n)"
 83.1046 -    from pp ccs(1) 
 83.1047 -    have "poly (pexp q n) = poly (pmult p ?w) "
 83.1048 -      apply - apply (rule ext)
 83.1049 -      unfolding poly_mult_assoc[symmetric] by (simp add: poly_mult)
 83.1050 -    hence ?ths unfolding divides_def by blast}
 83.1051 -  ultimately show ?ths by blast
 83.1052 -qed
 83.1053 -
 83.1054 -lemma nullstellensatz_univariate:
 83.1055 -  "(\<forall>x. poly p x = (0::complex) \<longrightarrow> poly q x = 0) \<longleftrightarrow> 
 83.1056 -    p divides (q %^ (degree p)) \<or> (poly p = poly [] \<and> poly q = poly [])"
 83.1057 -proof-
 83.1058 -  {assume pe: "poly p = poly []"
 83.1059 -    hence eq: "(\<forall>x. poly p x = (0::complex) \<longrightarrow> poly q x = 0) \<longleftrightarrow> poly q = poly []"
 83.1060 -      apply auto
 83.1061 -      by (rule ext, simp)
 83.1062 -    {assume "p divides (pexp q (degree p))"
 83.1063 -      then obtain r where r: "poly (pexp q (degree p)) = poly (pmult p r)" 
 83.1064 -	unfolding divides_def by blast
 83.1065 -      from cong[OF r refl] pe degree_unique[OF pe]
 83.1066 -      have False by (simp add: poly_mult degree_def)}
 83.1067 -    with eq pe have ?thesis by blast}
 83.1068 -  moreover
 83.1069 -  {assume pe: "poly p \<noteq> poly []"
 83.1070 -    have p0: "poly [0] = poly []" by (rule ext, simp)
 83.1071 -    {assume dp: "degree p = 0"
 83.1072 -      then obtain k where "pnormalize p = [k]" using pe poly_normalize[of p]
 83.1073 -	unfolding degree_def by (cases "pnormalize p", auto)
 83.1074 -      hence k: "pnormalize p = [k]" "poly p = poly [k]" "k\<noteq>0"
 83.1075 -	using pe poly_normalize[of p] by (auto simp add: p0)
 83.1076 -      hence th1: "\<forall>x. poly p x \<noteq> 0" by simp
 83.1077 -      from k(2,3) dp have "poly (pexp q (degree p)) = poly (pmult p [1/k]) "
 83.1078 -	by - (rule ext, simp add: poly_mult poly_exp)
 83.1079 -      hence th2: "p divides (pexp q (degree p))" unfolding divides_def by blast
 83.1080 -      from th1 th2 pe have ?thesis by blast}
 83.1081 -    moreover
 83.1082 -    {assume dp: "degree p \<noteq> 0"
 83.1083 -      then obtain n where n: "degree p = Suc n " by (cases "degree p", auto)
 83.1084 -      {assume "p divides (pexp q (Suc n))"
 83.1085 -	then obtain u where u: "poly (pexp q (Suc n)) = poly (pmult p u)"
 83.1086 -	  unfolding divides_def by blast
 83.1087 -	hence u' :"\<And>x. poly (pexp q (Suc n)) x = poly (pmult p u) x" by simp_all
 83.1088 -	{fix x assume h: "poly p x = 0" "poly q x \<noteq> 0"
 83.1089 -	  hence "poly (pexp q (Suc n)) x \<noteq> 0" by (simp only: poly_exp) simp	  
 83.1090 -	  hence False using u' h(1) by (simp only: poly_mult poly_exp) simp}}
 83.1091 -	with n nullstellensatz_lemma[of p q "degree p"] dp 
 83.1092 -	have ?thesis by auto}
 83.1093 -    ultimately have ?thesis by blast}
 83.1094 -  ultimately show ?thesis by blast
 83.1095 -qed
 83.1096 -
 83.1097 -text{* Useful lemma *}
 83.1098 -
 83.1099 -lemma (in idom_char_0) constant_degree: "constant (poly p) \<longleftrightarrow> degree p = 0" (is "?lhs = ?rhs")
 83.1100 -proof
 83.1101 -  assume l: ?lhs
 83.1102 -  from l[unfolded constant_def, rule_format, of _ "zero"]
 83.1103 -  have th: "poly p = poly [poly p 0]" apply - by (rule ext, simp)
 83.1104 -  from degree_unique[OF th] show ?rhs by (simp add: degree_def)
 83.1105 -next
 83.1106 -  assume r: ?rhs
 83.1107 -  from r have "pnormalize p = [] \<or> (\<exists>k. pnormalize p = [k])"
 83.1108 -    unfolding degree_def by (cases "pnormalize p", auto)
 83.1109 -  then show ?lhs unfolding constant_def poly_normalize[of p, symmetric]
 83.1110 -    by (auto simp del: poly_normalize)
 83.1111 -qed
 83.1112 -
 83.1113 -(* It would be nicer to prove this without using algebraic closure...        *)
 83.1114 -
 83.1115 -lemma divides_degree_lemma: assumes dpn: "degree (p::complex list) = n"
 83.1116 -  shows "n \<le> degree (p *** q) \<or> poly (p *** q) = poly []"
 83.1117 -  using dpn
 83.1118 -proof(induct n arbitrary: p q)
 83.1119 -  case 0 thus ?case by simp
 83.1120 -next
 83.1121 -  case (Suc n p q)
 83.1122 -  from Suc.prems fundamental_theorem_of_algebra[of p] constant_degree[of p]
 83.1123 -  obtain a where a: "poly p a = 0" by auto
 83.1124 -  then obtain r where r: "p = pmult [-a, 1] r" unfolding poly_linear_divides
 83.1125 -    using Suc.prems by (auto simp add: degree_def)
 83.1126 -  {assume h: "poly (pmult r q) = poly []"
 83.1127 -    hence "poly (pmult p q) = poly []" using r
 83.1128 -      apply - apply (rule ext)  by (auto simp add: poly_entire poly_mult poly_add poly_cmult) hence ?case by blast}
 83.1129 -  moreover
 83.1130 -  {assume h: "poly (pmult r q) \<noteq> poly []" 
 83.1131 -    hence r0: "poly r \<noteq> poly []" and q0: "poly q \<noteq> poly []"
 83.1132 -      by (auto simp add: poly_entire)
 83.1133 -    have eq: "poly (pmult p q) = poly (pmult [-a, 1] (pmult r q))"
 83.1134 -      apply - apply (rule ext)
 83.1135 -      by (simp add: r poly_mult poly_add poly_cmult ring_simps)
 83.1136 -    from linear_mul_degree[OF h, of "- a"]
 83.1137 -    have dqe: "degree (pmult p q) = degree (pmult r q) + 1"
 83.1138 -      unfolding degree_unique[OF eq] .
 83.1139 -    from linear_mul_degree[OF r0, of "- a", unfolded r[symmetric]] r Suc.prems 
 83.1140 -    have dr: "degree r = n" by auto
 83.1141 -    from  Suc.hyps[OF dr, of q] have "Suc n \<le> degree (pmult p q)"
 83.1142 -      unfolding dqe using h by (auto simp del: poly.simps) 
 83.1143 -    hence ?case by blast}
 83.1144 -  ultimately show ?case by blast
 83.1145 -qed
 83.1146 -
 83.1147 -lemma divides_degree: assumes pq: "p divides (q:: complex list)"
 83.1148 -  shows "degree p \<le> degree q \<or> poly q = poly []"
 83.1149 -using pq  divides_degree_lemma[OF refl, of p]
 83.1150 -apply (auto simp add: divides_def poly_entire)
 83.1151 -apply atomize
 83.1152 -apply (erule_tac x="qa" in allE, auto)
 83.1153 -apply (subgoal_tac "degree q = degree (p *** qa)", simp)
 83.1154 -apply (rule degree_unique, simp)
 83.1155 -done
 83.1156 -
 83.1157 -(* Arithmetic operations on multivariate polynomials.                        *)
 83.1158 -
 83.1159 -lemma mpoly_base_conv: 
 83.1160 -  "(0::complex) \<equiv> poly [] x" "c \<equiv> poly [c] x" "x \<equiv> poly [0,1] x" by simp_all
 83.1161 -
 83.1162 -lemma mpoly_norm_conv: 
 83.1163 -  "poly [0] (x::complex) \<equiv> poly [] x" "poly [poly [] y] x \<equiv> poly [] x" by simp_all
 83.1164 -
 83.1165 -lemma mpoly_sub_conv: 
 83.1166 -  "poly p (x::complex) - poly q x \<equiv> poly p x + -1 * poly q x"
 83.1167 -  by (simp add: diff_def)
 83.1168 -
 83.1169 -lemma poly_pad_rule: "poly p x = 0 ==> poly (0#p) x = (0::complex)" by simp
 83.1170 -
 83.1171 -lemma poly_cancel_eq_conv: "p = (0::complex) \<Longrightarrow> a \<noteq> 0 \<Longrightarrow> (q = 0) \<equiv> (a * q - b * p = 0)" apply (atomize (full)) by auto
 83.1172 -
 83.1173 -lemma resolve_eq_raw:  "poly [] x \<equiv> 0" "poly [c] x \<equiv> (c::complex)" by auto
 83.1174 -lemma  resolve_eq_then: "(P \<Longrightarrow> (Q \<equiv> Q1)) \<Longrightarrow> (\<not>P \<Longrightarrow> (Q \<equiv> Q2))
 83.1175 -  \<Longrightarrow> Q \<equiv> P \<and> Q1 \<or> \<not>P\<and> Q2" apply (atomize (full)) by blast 
 83.1176 -lemma expand_ex_beta_conv: "list_ex P [c] \<equiv> P c" by simp
 83.1177 -
 83.1178 -lemma poly_divides_pad_rule: 
 83.1179 -  fixes p q :: "complex list"
 83.1180 -  assumes pq: "p divides q"
 83.1181 -  shows "p divides ((0::complex)#q)"
 83.1182 -proof-
 83.1183 -  from pq obtain r where r: "poly q = poly (p *** r)" unfolding divides_def by blast
 83.1184 -  hence "poly (0#q) = poly (p *** ([0,1] *** r))" 
 83.1185 -    by - (rule ext, simp add: poly_mult poly_cmult poly_add)
 83.1186 -  thus ?thesis unfolding divides_def by blast
 83.1187 -qed
 83.1188 -
 83.1189 -lemma poly_divides_pad_const_rule: 
 83.1190 -  fixes p q :: "complex list"
 83.1191 -  assumes pq: "p divides q"
 83.1192 -  shows "p divides (a %* q)"
 83.1193 -proof-
 83.1194 -  from pq obtain r where r: "poly q = poly (p *** r)" unfolding divides_def by blast
 83.1195 -  hence "poly (a %* q) = poly (p *** (a %* r))" 
 83.1196 -    by - (rule ext, simp add: poly_mult poly_cmult poly_add)
 83.1197 -  thus ?thesis unfolding divides_def by blast
 83.1198 -qed
 83.1199 -
 83.1200 -
 83.1201 -lemma poly_divides_conv0:  
 83.1202 -  fixes p :: "complex list"
 83.1203 -  assumes lgpq: "length q < length p" and lq:"last p \<noteq> 0"
 83.1204 -  shows "p divides q \<equiv> (\<not> (list_ex (\<lambda>c. c \<noteq> 0) q))" (is "?lhs \<equiv> ?rhs")
 83.1205 -proof-
 83.1206 -  {assume r: ?rhs 
 83.1207 -    hence eq: "poly q = poly []" unfolding poly_zero 
 83.1208 -      by (simp add: list_all_iff list_ex_iff)
 83.1209 -    hence "poly q = poly (p *** [])" by - (rule ext, simp add: poly_mult)
 83.1210 -    hence ?lhs unfolding divides_def  by blast}
 83.1211 -  moreover
 83.1212 -  {assume l: ?lhs
 83.1213 -    have ath: "\<And>lq lp dq::nat. lq < lp ==> lq \<noteq> 0 \<Longrightarrow> dq <= lq - 1 ==> dq < lp - 1"
 83.1214 -      by arith
 83.1215 -    {assume q0: "length q = 0"
 83.1216 -      hence "q = []" by simp
 83.1217 -      hence ?rhs by simp}
 83.1218 -    moreover
 83.1219 -    {assume lgq0: "length q \<noteq> 0"
 83.1220 -      from pnormalize_length[of q] have dql: "degree q \<le> length q - 1" 
 83.1221 -	unfolding degree_def by simp
 83.1222 -      from ath[OF lgpq lgq0 dql, unfolded pnormal_degree[OF lq, symmetric]] divides_degree[OF l] have "poly q = poly []" by auto
 83.1223 -      hence ?rhs unfolding poly_zero by (simp add: list_all_iff list_ex_iff)}
 83.1224 -    ultimately have ?rhs by blast }
 83.1225 -  ultimately show "?lhs \<equiv> ?rhs" by - (atomize (full), blast) 
 83.1226 -qed
 83.1227 -
 83.1228 -lemma poly_divides_conv1: 
 83.1229 -  assumes a0: "a\<noteq> (0::complex)" and pp': "(p::complex list) divides p'"
 83.1230 -  and qrp': "\<And>x. a * poly q x - poly p' x \<equiv> poly r x"
 83.1231 -  shows "p divides q \<equiv> p divides (r::complex list)" (is "?lhs \<equiv> ?rhs")
 83.1232 -proof-
 83.1233 -  {
 83.1234 -  from pp' obtain t where t: "poly p' = poly (p *** t)" 
 83.1235 -    unfolding divides_def by blast
 83.1236 -  {assume l: ?lhs
 83.1237 -    then obtain u where u: "poly q = poly (p *** u)" unfolding divides_def by blast
 83.1238 -     have "poly r = poly (p *** ((a %* u) +++ (-- t)))"
 83.1239 -       using u qrp' t
 83.1240 -       by - (rule ext, 
 83.1241 -	 simp add: poly_add poly_mult poly_cmult poly_minus ring_simps)
 83.1242 -     then have ?rhs unfolding divides_def by blast}
 83.1243 -  moreover
 83.1244 -  {assume r: ?rhs
 83.1245 -    then obtain u where u: "poly r = poly (p *** u)" unfolding divides_def by blast
 83.1246 -    from u t qrp' a0 have "poly q = poly (p *** ((1/a) %* (u +++ t)))"
 83.1247 -      by - (rule ext, atomize (full), simp add: poly_mult poly_add poly_cmult field_simps)
 83.1248 -    hence ?lhs  unfolding divides_def by blast}
 83.1249 -  ultimately have "?lhs = ?rhs" by blast }
 83.1250 -thus "?lhs \<equiv> ?rhs"  by - (atomize(full), blast) 
 83.1251 -qed
 83.1252 -
 83.1253 -lemma basic_cqe_conv1:
 83.1254 -  "(\<exists>x. poly p x = 0 \<and> poly [] x \<noteq> 0) \<equiv> False"
 83.1255 -  "(\<exists>x. poly [] x \<noteq> 0) \<equiv> False"
 83.1256 -  "(\<exists>x. poly [c] x \<noteq> 0) \<equiv> c\<noteq>0"
 83.1257 -  "(\<exists>x. poly [] x = 0) \<equiv> True"
 83.1258 -  "(\<exists>x. poly [c] x = 0) \<equiv> c = 0" by simp_all
 83.1259 -
 83.1260 -lemma basic_cqe_conv2: 
 83.1261 -  assumes l:"last (a#b#p) \<noteq> 0" 
 83.1262 -  shows "(\<exists>x. poly (a#b#p) x = (0::complex)) \<equiv> True"
 83.1263 -proof-
 83.1264 -  {fix h t
 83.1265 -    assume h: "h\<noteq>0" "list_all (\<lambda>c. c=(0::complex)) t"  "a#b#p = h#t"
 83.1266 -    hence "list_all (\<lambda>c. c= 0) (b#p)" by simp
 83.1267 -    moreover have "last (b#p) \<in> set (b#p)" by simp
 83.1268 -    ultimately have "last (b#p) = 0" by (simp add: list_all_iff)
 83.1269 -    with l have False by simp}
 83.1270 -  hence th: "\<not> (\<exists> h t. h\<noteq>0 \<and> list_all (\<lambda>c. c=0) t \<and> a#b#p = h#t)"
 83.1271 -    by blast
 83.1272 -  from fundamental_theorem_of_algebra_alt[OF th] 
 83.1273 -  show "(\<exists>x. poly (a#b#p) x = (0::complex)) \<equiv> True" by auto
 83.1274 -qed
 83.1275 -
 83.1276 -lemma  basic_cqe_conv_2b: "(\<exists>x. poly p x \<noteq> (0::complex)) \<equiv> (list_ex (\<lambda>c. c \<noteq> 0) p)"
 83.1277 -proof-
 83.1278 -  have "\<not> (list_ex (\<lambda>c. c \<noteq> 0) p) \<longleftrightarrow> poly p = poly []" 
 83.1279 -    by (simp add: poly_zero list_all_iff list_ex_iff)
 83.1280 -  also have "\<dots> \<longleftrightarrow> (\<not> (\<exists>x. poly p x \<noteq> 0))" by (auto intro: ext)
 83.1281 -  finally show "(\<exists>x. poly p x \<noteq> (0::complex)) \<equiv> (list_ex (\<lambda>c. c \<noteq> 0) p)"
 83.1282 -    by - (atomize (full), blast)
 83.1283 -qed
 83.1284 -
 83.1285 -lemma basic_cqe_conv3:
 83.1286 -  fixes p q :: "complex list"
 83.1287 -  assumes l: "last (a#p) \<noteq> 0" 
 83.1288 -  shows "(\<exists>x. poly (a#p) x =0 \<and> poly q x \<noteq> 0) \<equiv> \<not> ((a#p) divides (q %^ (length p)))"
 83.1289 -proof-
 83.1290 -  note np = pnormalize_eq[OF l]
 83.1291 -  {assume "poly (a#p) = poly []" hence False using l
 83.1292 -      unfolding poly_zero apply (auto simp add: list_all_iff del: last.simps)
 83.1293 -      apply (cases p, simp_all) done}
 83.1294 -  then have p0: "poly (a#p) \<noteq> poly []"  by blast
 83.1295 -  from np have dp:"degree (a#p) = length p" by (simp add: degree_def)
 83.1296 -  from nullstellensatz_univariate[of "a#p" q] p0 dp
 83.1297 -  show "(\<exists>x. poly (a#p) x =0 \<and> poly q x \<noteq> 0) \<equiv> \<not> ((a#p) divides (q %^ (length p)))"
 83.1298 -    by - (atomize (full), auto)
 83.1299 -qed
 83.1300 -
 83.1301 -lemma basic_cqe_conv4:
 83.1302 -  fixes p q :: "complex list"
 83.1303 -  assumes h: "\<And>x. poly (q %^ n) x \<equiv> poly r x"
 83.1304 -  shows "p divides (q %^ n) \<equiv> p divides r"
 83.1305 -proof-
 83.1306 -  from h have "poly (q %^ n) = poly r" by (auto intro: ext)  
 83.1307 -  thus "p divides (q %^ n) \<equiv> p divides r" unfolding divides_def by simp
 83.1308 -qed
 83.1309 -
 83.1310 -lemma pmult_Cons_Cons: "((a::complex)#b#p) *** q = (a %*q) +++ (0#((b#p) *** q))"
 83.1311 -  by simp
 83.1312 -
 83.1313 -lemma elim_neg_conv: "- z \<equiv> (-1) * (z::complex)" by simp
 83.1314 -lemma eqT_intr: "PROP P \<Longrightarrow> (True \<Longrightarrow> PROP P )" "PROP P \<Longrightarrow> True" by blast+
 83.1315 -lemma negate_negate_rule: "Trueprop P \<equiv> \<not> P \<equiv> False" by (atomize (full), auto)
 83.1316 -lemma last_simps: "last [x] = x" "last (x#y#ys) = last (y#ys)" by simp_all
 83.1317 -lemma length_simps: "length [] = 0" "length (x#y#xs) = length xs + 2" "length [x] = 1" by simp_all
 83.1318 -
 83.1319 -lemma complex_entire: "(z::complex) \<noteq> 0 \<and> w \<noteq> 0 \<equiv> z*w \<noteq> 0" by simp
 83.1320 -lemma resolve_eq_ne: "(P \<equiv> True) \<equiv> (\<not>P \<equiv> False)" "(P \<equiv> False) \<equiv> (\<not>P \<equiv> True)" 
 83.1321 -  by (atomize (full)) simp_all
 83.1322 -lemma cqe_conv1: "poly [] x = 0 \<longleftrightarrow> True"  by simp
 83.1323 -lemma cqe_conv2: "(p \<Longrightarrow> (q \<equiv> r)) \<equiv> ((p \<and> q) \<equiv> (p \<and> r))"  (is "?l \<equiv> ?r")
 83.1324 -proof
 83.1325 -  assume "p \<Longrightarrow> q \<equiv> r" thus "p \<and> q \<equiv> p \<and> r" apply - apply (atomize (full)) by blast
 83.1326 -next
 83.1327 -  assume "p \<and> q \<equiv> p \<and> r" "p"
 83.1328 -  thus "q \<equiv> r" apply - apply (atomize (full)) apply blast done
 83.1329 -qed
 83.1330 -lemma poly_const_conv: "poly [c] (x::complex) = y \<longleftrightarrow> c = y" by simp
 83.1331 -
 83.1332 -end
 83.1333 \ No newline at end of file
    84.1 --- a/src/HOL/Complex/README.html	Tue Dec 30 08:18:54 2008 +0100
    84.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    84.3 @@ -1,67 +0,0 @@
    84.4 -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    84.5 -
    84.6 -<!-- $Id$ -->
    84.7 -
    84.8 -<HTML>
    84.9 -
   84.10 -<HEAD>
   84.11 -  <meta http-equiv="content-type" content="text/html;charset=iso-8859-1">
   84.12 -  <TITLE>HOL/Complex/README</TITLE>
   84.13 -</HEAD>
   84.14 -
   84.15 -<BODY>
   84.16 -
   84.17 -<H1>Complex: The Complex Numbers</H1>
   84.18 -		<P>This directory defines the type <KBD>complex</KBD> of the complex numbers,
   84.19 -with numeric constants and some complex analysis.  The development includes
   84.20 -nonstandard analysis for the complex numbers.  Note that the image
   84.21 -<KBD>HOL-Complex</KBD> includes theories from the directories 
   84.22 -<KBD><a href="#Anchor-Real">HOL/Real</a></KBD>  and <KBD><a href="#Anchor-Hyperreal">HOL/Hyperreal</a></KBD>. They define other types including <kbd>real</kbd> (the real numbers) and <kbd>hypreal</kbd> (the hyperreal or non-standard reals).
   84.23 -
   84.24 -<ul>
   84.25 -<li><a href="CLim.html">CLim</a> Limits, continuous functions, and derivatives for the complex numbers
   84.26 -<li><a href="CSeries.html">CSeries</a> Finite summation and infinite series for the complex numbers
   84.27 -<li><a href="CStar.html">CStar</a> Star-transforms for the complex numbers, to form non-standard extensions of sets and functions
   84.28 -<li><a href="Complex.html">Complex</a> The complex numbers
   84.29 -<li><a href="NSCA.html">NSCA</a> Nonstandard complex analysis
   84.30 -<li><a href="NSComplex.html">NSComplex</a> Ultrapower construction of the nonstandard complex numbers
   84.31 -</ul>
   84.32 -
   84.33 -<h2><a name="Anchor-Real" id="Anchor-Real"></a>Real: Dedekind Cut Construction of the Real Line</h2>
   84.34 -
   84.35 -<ul>
   84.36 -<li><a href="Lubs.html">Lubs</a> Definition of upper bounds, lubs and so on, to support completeness proofs.
   84.37 -<li><a href="PReal.html">PReal</a> The positive reals constructed using Dedekind cuts
   84.38 -<li><a href="Rational.html">Rational</a> The rational numbers constructed as equivalence classes of integers
   84.39 -<li><a href="RComplete.html">RComplete</a> The reals are complete: they satisfy the supremum property. They also have the Archimedean property.
   84.40 -<li><a href="RealDef.html">RealDef</a> The real numbers, their ordering properties, and embedding of the integers and the natural numbers
   84.41 -<li><a href="RealPow.html">RealPow</a> Real numbers raised to natural number powers
   84.42 -</ul>
   84.43 -<h2><a name="Anchor-Hyperreal" id="Anchor-Hyperreal"></a>Hyperreal: Ultrafilter Construction of the Non-Standard Reals</h2>
   84.44 -See J. D. Fleuriot and L. C. Paulson. Mechanizing Nonstandard Real Analysis. LMS J. Computation and Mathematics 3 (2000), 140-190.
   84.45 -<ul>
   84.46 -<li><a href="Filter.html">Filter</a> Theory of Filters and Ultrafilters. Main result is a version of the Ultrafilter Theorem proved using Zorn's Lemma.
   84.47 -<li><a href="HLog.html">HLog</a> Non-standard logarithms
   84.48 -<li><a href="HSeries.html">HSeries</a> Non-standard theory of finite summation and infinite series
   84.49 -<li><a href="HTranscendental.html">HTranscendental</a> Non-standard extensions of transcendental functions
   84.50 -<li><a href="HyperDef.html">HyperDef</a> Ultrapower construction of the hyperreals
   84.51 -<li><a href="HyperNat.html">HyperNat</a> Ultrapower construction of the hypernaturals
   84.52 -<li><a href="HyperPow.html">HyperPow</a> Powers theory for the hyperreals
   84.53 -<!-- <li><a href="IntFloor.html">IntFloor</a> Floor and Ceiling functions relating the reals and integers -->
   84.54 -<li><a href="Integration.html">Integration</a> Gage integrals
   84.55 -<li><a href="Lim.html">Lim</a> Theory of limits, continuous functions, and derivatives
   84.56 -<li><a href="Log.html">Log</a> Logarithms for the reals
   84.57 -<li><a href="MacLaurin.html">MacLaurin</a> MacLaurin series
   84.58 -<li><a href="NatStar.html">NatStar</a> Star-transforms for the hypernaturals, to form non-standard extensions of sets and functions involving the naturals or reals
   84.59 -<li><a href="NthRoot.html">NthRoot</a> Existence of n-th roots of real numbers
   84.60 -<li><a href="NSA.html">NSA</a> Theory defining sets of infinite numbers, infinitesimals, the infinitely close relation, and their various algebraic properties.
   84.61 -<li><a href="Poly.html">Poly</a> Univariate real polynomials
   84.62 -<li><a href="SEQ.html">SEQ</a> Convergence of sequences and series using standard and nonstandard analysis
   84.63 -<li><a href="Series.html">Series</a> Finite summation and infinite series for the reals
   84.64 -<li><a href="Star.html">Star</a> Nonstandard extensions of real sets and real functions
   84.65 -<li><a href="Transcendental.html">Transcendental</a> Power series and transcendental functions
   84.66 -</ul>
   84.67 -<HR>
   84.68 -<P>Last modified $Date$
   84.69 -</BODY>
   84.70 -</HTML>
    85.1 --- a/src/HOL/Complex/document/root.tex	Tue Dec 30 08:18:54 2008 +0100
    85.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    85.3 @@ -1,32 +0,0 @@
    85.4 -
    85.5 -% $Id$
    85.6 -
    85.7 -\documentclass[11pt,a4paper]{article}
    85.8 -\usepackage{graphicx,isabelle,isabellesym,latexsym}
    85.9 -\usepackage[latin1]{inputenc}
   85.10 -\usepackage{pdfsetup}
   85.11 -
   85.12 -\urlstyle{rm}
   85.13 -\isabellestyle{it}
   85.14 -\pagestyle{myheadings}
   85.15 -
   85.16 -\begin{document}
   85.17 -
   85.18 -\title{Isabelle/HOL-Complex --- Higher-Order Logic with Complex Numbers}
   85.19 -\maketitle
   85.20 -
   85.21 -\tableofcontents
   85.22 -
   85.23 -\begin{center}
   85.24 -  \includegraphics[width=\textwidth,height=\textheight,keepaspectratio]{session_graph}
   85.25 -\end{center}
   85.26 -
   85.27 -\newpage
   85.28 -
   85.29 -\renewcommand{\isamarkupheader}[1]%
   85.30 -{\section{\isabellecontext: #1}\markright{THEORY~``\isabellecontext''}}
   85.31 -
   85.32 -\parindent 0pt\parskip 0.5ex
   85.33 -\input{session}
   85.34 -
   85.35 -\end{document}
    86.1 --- a/src/HOL/Complex_Main.thy	Tue Dec 30 08:18:54 2008 +0100
    86.2 +++ b/src/HOL/Complex_Main.thy	Tue Dec 30 11:10:01 2008 +0100
    86.3 @@ -9,7 +9,7 @@
    86.4  imports
    86.5    Main
    86.6    Real
    86.7 -  "~~/src/HOL/Complex/Fundamental_Theorem_Algebra"
    86.8 +  Fundamental_Theorem_Algebra
    86.9    Log
   86.10    Ln
   86.11    Taylor
    87.1 --- a/src/HOL/Datatype.thy	Tue Dec 30 08:18:54 2008 +0100
    87.2 +++ b/src/HOL/Datatype.thy	Tue Dec 30 11:10:01 2008 +0100
    87.3 @@ -578,7 +578,13 @@
    87.4  lemma Sumr_inject: "Sumr f = Sumr g ==> f = g"
    87.5    by (unfold Sumr_def) (erule sum_case_inject)
    87.6  
    87.7 -hide (open) const Suml Sumr
    87.8 +primrec Projl :: "'a + 'b => 'a"
    87.9 +where Projl_Inl: "Projl (Inl x) = x"
   87.10 +
   87.11 +primrec Projr :: "'a + 'b => 'b"
   87.12 +where Projr_Inr: "Projr (Inr x) = x"
   87.13 +
   87.14 +hide (open) const Suml Sumr Projl Projr
   87.15  
   87.16  
   87.17  subsection {* The option datatype *}
    88.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    88.2 +++ b/src/HOL/Dense_Linear_Order.thy	Tue Dec 30 11:10:01 2008 +0100
    88.3 @@ -0,0 +1,877 @@
    88.4 +(* Author: Amine Chaieb, TU Muenchen *)
    88.5 +
    88.6 +header {* Dense linear order without endpoints
    88.7 +  and a quantifier elimination procedure in Ferrante and Rackoff style *}
    88.8 +
    88.9 +theory Dense_Linear_Order
   88.10 +imports Plain Groebner_Basis
   88.11 +uses
   88.12 +  "~~/src/HOL/Tools/Qelim/langford_data.ML"
   88.13 +  "~~/src/HOL/Tools/Qelim/ferrante_rackoff_data.ML"
   88.14 +  ("~~/src/HOL/Tools/Qelim/langford.ML")
   88.15 +  ("~~/src/HOL/Tools/Qelim/ferrante_rackoff.ML")
   88.16 +begin
   88.17 +
   88.18 +setup {* Langford_Data.setup #> Ferrante_Rackoff_Data.setup *}
   88.19 +
   88.20 +context linorder
   88.21 +begin
   88.22 +
   88.23 +lemma less_not_permute: "\<not> (x < y \<and> y < x)" by (simp add: not_less linear)
   88.24 +
   88.25 +lemma gather_simps: 
   88.26 +  shows 
   88.27 +  "(\<exists>x. (\<forall>y \<in> L. y < x) \<and> (\<forall>y \<in> U. x < y) \<and> x < u \<and> P x) \<longleftrightarrow> (\<exists>x. (\<forall>y \<in> L. y < x) \<and> (\<forall>y \<in> (insert u U). x < y) \<and> P x)"
   88.28 +  and "(\<exists>x. (\<forall>y \<in> L. y < x) \<and> (\<forall>y \<in> U. x < y) \<and> l < x \<and> P x) \<longleftrightarrow> (\<exists>x. (\<forall>y \<in> (insert l L). y < x) \<and> (\<forall>y \<in> U. x < y) \<and> P x)"
   88.29 +  "(\<exists>x. (\<forall>y \<in> L. y < x) \<and> (\<forall>y \<in> U. x < y) \<and> x < u) \<longleftrightarrow> (\<exists>x. (\<forall>y \<in> L. y < x) \<and> (\<forall>y \<in> (insert u U). x < y))"
   88.30 +  and "(\<exists>x. (\<forall>y \<in> L. y < x) \<and> (\<forall>y \<in> U. x < y) \<and> l < x) \<longleftrightarrow> (\<exists>x. (\<forall>y \<in> (insert l L). y < x) \<and> (\<forall>y \<in> U. x < y))"  by auto
   88.31 +
   88.32 +lemma 
   88.33 +  gather_start: "(\<exists>x. P x) \<equiv> (\<exists>x. (\<forall>y \<in> {}. y < x) \<and> (\<forall>y\<in> {}. x < y) \<and> P x)" 
   88.34 +  by simp
   88.35 +
   88.36 +text{* Theorems for @{text "\<exists>z. \<forall>x. x < z \<longrightarrow> (P x \<longleftrightarrow> P\<^bsub>-\<infinity>\<^esub>)"}*}
   88.37 +lemma minf_lt:  "\<exists>z . \<forall>x. x < z \<longrightarrow> (x < t \<longleftrightarrow> True)" by auto
   88.38 +lemma minf_gt: "\<exists>z . \<forall>x. x < z \<longrightarrow>  (t < x \<longleftrightarrow>  False)"
   88.39 +  by (simp add: not_less) (rule exI[where x="t"], auto simp add: less_le)
   88.40 +
   88.41 +lemma minf_le: "\<exists>z. \<forall>x. x < z \<longrightarrow> (x \<le> t \<longleftrightarrow> True)" by (auto simp add: less_le)
   88.42 +lemma minf_ge: "\<exists>z. \<forall>x. x < z \<longrightarrow> (t \<le> x \<longleftrightarrow> False)"
   88.43 +  by (auto simp add: less_le not_less not_le)
   88.44 +lemma minf_eq: "\<exists>z. \<forall>x. x < z \<longrightarrow> (x = t \<longleftrightarrow> False)" by auto
   88.45 +lemma minf_neq: "\<exists>z. \<forall>x. x < z \<longrightarrow> (x \<noteq> t \<longleftrightarrow> True)" by auto
   88.46 +lemma minf_P: "\<exists>z. \<forall>x. x < z \<longrightarrow> (P \<longleftrightarrow> P)" by blast
   88.47 +
   88.48 +text{* Theorems for @{text "\<exists>z. \<forall>x. x < z \<longrightarrow> (P x \<longleftrightarrow> P\<^bsub>+\<infinity>\<^esub>)"}*}
   88.49 +lemma pinf_gt:  "\<exists>z . \<forall>x. z < x \<longrightarrow> (t < x \<longleftrightarrow> True)" by auto
   88.50 +lemma pinf_lt: "\<exists>z . \<forall>x. z < x \<longrightarrow>  (x < t \<longleftrightarrow>  False)"
   88.51 +  by (simp add: not_less) (rule exI[where x="t"], auto simp add: less_le)
   88.52 +
   88.53 +lemma pinf_ge: "\<exists>z. \<forall>x. z < x \<longrightarrow> (t \<le> x \<longleftrightarrow> True)" by (auto simp add: less_le)
   88.54 +lemma pinf_le: "\<exists>z. \<forall>x. z < x \<longrightarrow> (x \<le> t \<longleftrightarrow> False)"
   88.55 +  by (auto simp add: less_le not_less not_le)
   88.56 +lemma pinf_eq: "\<exists>z. \<forall>x. z < x \<longrightarrow> (x = t \<longleftrightarrow> False)" by auto
   88.57 +lemma pinf_neq: "\<exists>z. \<forall>x. z < x \<longrightarrow> (x \<noteq> t \<longleftrightarrow> True)" by auto
   88.58 +lemma pinf_P: "\<exists>z. \<forall>x. z < x \<longrightarrow> (P \<longleftrightarrow> P)" by blast
   88.59 +
   88.60 +lemma nmi_lt: "t \<in> U \<Longrightarrow> \<forall>x. \<not>True \<and> x < t \<longrightarrow>  (\<exists> u\<in> U. u \<le> x)" by auto
   88.61 +lemma nmi_gt: "t \<in> U \<Longrightarrow> \<forall>x. \<not>False \<and> t < x \<longrightarrow>  (\<exists> u\<in> U. u \<le> x)"
   88.62 +  by (auto simp add: le_less)
   88.63 +lemma  nmi_le: "t \<in> U \<Longrightarrow> \<forall>x. \<not>True \<and> x\<le> t \<longrightarrow>  (\<exists> u\<in> U. u \<le> x)" by auto
   88.64 +lemma  nmi_ge: "t \<in> U \<Longrightarrow> \<forall>x. \<not>False \<and> t\<le> x \<longrightarrow>  (\<exists> u\<in> U. u \<le> x)" by auto
   88.65 +lemma  nmi_eq: "t \<in> U \<Longrightarrow> \<forall>x. \<not>False \<and>  x = t \<longrightarrow>  (\<exists> u\<in> U. u \<le> x)" by auto
   88.66 +lemma  nmi_neq: "t \<in> U \<Longrightarrow>\<forall>x. \<not>True \<and> x \<noteq> t \<longrightarrow>  (\<exists> u\<in> U. u \<le> x)" by auto
   88.67 +lemma  nmi_P: "\<forall> x. ~P \<and> P \<longrightarrow>  (\<exists> u\<in> U. u \<le> x)" by auto
   88.68 +lemma  nmi_conj: "\<lbrakk>\<forall>x. \<not>P1' \<and> P1 x \<longrightarrow>  (\<exists> u\<in> U. u \<le> x) ;
   88.69 +  \<forall>x. \<not>P2' \<and> P2 x \<longrightarrow>  (\<exists> u\<in> U. u \<le> x)\<rbrakk> \<Longrightarrow>
   88.70 +  \<forall>x. \<not>(P1' \<and> P2') \<and> (P1 x \<and> P2 x) \<longrightarrow>  (\<exists> u\<in> U. u \<le> x)" by auto
   88.71 +lemma  nmi_disj: "\<lbrakk>\<forall>x. \<not>P1' \<and> P1 x \<longrightarrow>  (\<exists> u\<in> U. u \<le> x) ;
   88.72 +  \<forall>x. \<not>P2' \<and> P2 x \<longrightarrow>  (\<exists> u\<in> U. u \<le> x)\<rbrakk> \<Longrightarrow>
   88.73 +  \<forall>x. \<not>(P1' \<or> P2') \<and> (P1 x \<or> P2 x) \<longrightarrow>  (\<exists> u\<in> U. u \<le> x)" by auto
   88.74 +
   88.75 +lemma  npi_lt: "t \<in> U \<Longrightarrow> \<forall>x. \<not>False \<and>  x < t \<longrightarrow>  (\<exists> u\<in> U. x \<le> u)" by (auto simp add: le_less)
   88.76 +lemma  npi_gt: "t \<in> U \<Longrightarrow> \<forall>x. \<not>True \<and> t < x \<longrightarrow>  (\<exists> u\<in> U. x \<le> u)" by auto
   88.77 +lemma  npi_le: "t \<in> U \<Longrightarrow> \<forall>x. \<not>False \<and>  x \<le> t \<longrightarrow>  (\<exists> u\<in> U. x \<le> u)" by auto
   88.78 +lemma  npi_ge: "t \<in> U \<Longrightarrow> \<forall>x. \<not>True \<and> t \<le> x \<longrightarrow>  (\<exists> u\<in> U. x \<le> u)" by auto
   88.79 +lemma  npi_eq: "t \<in> U \<Longrightarrow> \<forall>x. \<not>False \<and>  x = t \<longrightarrow>  (\<exists> u\<in> U. x \<le> u)" by auto
   88.80 +lemma  npi_neq: "t \<in> U \<Longrightarrow> \<forall>x. \<not>True \<and> x \<noteq> t \<longrightarrow>  (\<exists> u\<in> U. x \<le> u )" by auto
   88.81 +lemma  npi_P: "\<forall> x. ~P \<and> P \<longrightarrow>  (\<exists> u\<in> U. x \<le> u)" by auto
   88.82 +lemma  npi_conj: "\<lbrakk>\<forall>x. \<not>P1' \<and> P1 x \<longrightarrow>  (\<exists> u\<in> U. x \<le> u) ;  \<forall>x. \<not>P2' \<and> P2 x \<longrightarrow>  (\<exists> u\<in> U. x \<le> u)\<rbrakk>
   88.83 +  \<Longrightarrow>  \<forall>x. \<not>(P1' \<and> P2') \<and> (P1 x \<and> P2 x) \<longrightarrow>  (\<exists> u\<in> U. x \<le> u)" by auto
   88.84 +lemma  npi_disj: "\<lbrakk>\<forall>x. \<not>P1' \<and> P1 x \<longrightarrow>  (\<exists> u\<in> U. x \<le> u) ; \<forall>x. \<not>P2' \<and> P2 x \<longrightarrow>  (\<exists> u\<in> U. x \<le> u)\<rbrakk>
   88.85 +  \<Longrightarrow> \<forall>x. \<not>(P1' \<or> P2') \<and> (P1 x \<or> P2 x) \<longrightarrow>  (\<exists> u\<in> U. x \<le> u)" by auto
   88.86 +
   88.87 +lemma lin_dense_lt: "t \<in> U \<Longrightarrow> \<forall>x l u. (\<forall> t. l < t \<and> t < u \<longrightarrow> t \<notin> U) \<and> l< x \<and> x < u \<and> x < t \<longrightarrow> (\<forall> y. l < y \<and> y < u \<longrightarrow> y < t)"
   88.88 +proof(clarsimp)
   88.89 +  fix x l u y  assume tU: "t \<in> U" and noU: "\<forall>t. l < t \<and> t < u \<longrightarrow> t \<notin> U" and lx: "l < x"
   88.90 +    and xu: "x<u"  and px: "x < t" and ly: "l<y" and yu:"y < u"
   88.91 +  from tU noU ly yu have tny: "t\<noteq>y" by auto
   88.92 +  {assume H: "t < y"
   88.93 +    from less_trans[OF lx px] less_trans[OF H yu]
   88.94 +    have "l < t \<and> t < u"  by simp
   88.95 +    with tU noU have "False" by auto}
   88.96 +  hence "\<not> t < y"  by auto hence "y \<le> t" by (simp add: not_less)
   88.97 +  thus "y < t" using tny by (simp add: less_le)
   88.98 +qed
   88.99 +
  88.100 +lemma lin_dense_gt: "t \<in> U \<Longrightarrow> \<forall>x l u. (\<forall> t. l < t \<and> t< u \<longrightarrow> t \<notin> U) \<and> l < x \<and> x < u \<and> t < x \<longrightarrow> (\<forall> y. l < y \<and> y < u \<longrightarrow> t < y)"
  88.101 +proof(clarsimp)
  88.102 +  fix x l u y
  88.103 +  assume tU: "t \<in> U" and noU: "\<forall>t. l < t \<and> t < u \<longrightarrow> t \<notin> U" and lx: "l < x" and xu: "x<u"
  88.104 +  and px: "t < x" and ly: "l<y" and yu:"y < u"
  88.105 +  from tU noU ly yu have tny: "t\<noteq>y" by auto
  88.106 +  {assume H: "y< t"
  88.107 +    from less_trans[OF ly H] less_trans[OF px xu] have "l < t \<and> t < u" by simp
  88.108 +    with tU noU have "False" by auto}
  88.109 +  hence "\<not> y<t"  by auto hence "t \<le> y" by (auto simp add: not_less)
  88.110 +  thus "t < y" using tny by (simp add:less_le)
  88.111 +qed
  88.112 +
  88.113 +lemma lin_dense_le: "t \<in> U \<Longrightarrow> \<forall>x l u. (\<forall> t. l < t \<and> t< u \<longrightarrow> t \<notin> U) \<and> l< x \<and> x < u \<and> x \<le> t \<longrightarrow> (\<forall> y. l < y \<and> y < u \<longrightarrow> y\<le> t)"
  88.114 +proof(clarsimp)
  88.115 +  fix x l u y
  88.116 +  assume tU: "t \<in> U" and noU: "\<forall>t. l < t \<and> t < u \<longrightarrow> t \<notin> U" and lx: "l < x" and xu: "x<u"
  88.117 +  and px: "x \<le> t" and ly: "l<y" and yu:"y < u"
  88.118 +  from tU noU ly yu have tny: "t\<noteq>y" by auto
  88.119 +  {assume H: "t < y"
  88.120 +    from less_le_trans[OF lx px] less_trans[OF H yu]
  88.121 +    have "l < t \<and> t < u" by simp
  88.122 +    with tU noU have "False" by auto}
  88.123 +  hence "\<not> t < y"  by auto thus "y \<le> t" by (simp add: not_less)
  88.124 +qed
  88.125 +
  88.126 +lemma lin_dense_ge: "t \<in> U \<Longrightarrow> \<forall>x l u. (\<forall> t. l < t \<and> t< u \<longrightarrow> t \<notin> U) \<and> l< x \<and> x < u \<and> t \<le> x \<longrightarrow> (\<forall> y. l < y \<and> y < u \<longrightarrow> t \<le> y)"
  88.127 +proof(clarsimp)
  88.128 +  fix x l u y
  88.129 +  assume tU: "t \<in> U" and noU: "\<forall>t. l < t \<and> t < u \<longrightarrow> t \<notin> U" and lx: "l < x" and xu: "x<u"
  88.130 +  and px: "t \<le> x" and ly: "l<y" and yu:"y < u"
  88.131 +  from tU noU ly yu have tny: "t\<noteq>y" by auto
  88.132 +  {assume H: "y< t"
  88.133 +    from less_trans[OF ly H] le_less_trans[OF px xu]
  88.134 +    have "l < t \<and> t < u" by simp
  88.135 +    with tU noU have "False" by auto}
  88.136 +  hence "\<not> y<t"  by auto thus "t \<le> y" by (simp add: not_less)
  88.137 +qed
  88.138 +lemma lin_dense_eq: "t \<in> U \<Longrightarrow> \<forall>x l u. (\<forall> t. l < t \<and> t< u \<longrightarrow> t \<notin> U) \<and> l< x \<and> x < u \<and> x = t   \<longrightarrow> (\<forall> y. l < y \<and> y < u \<longrightarrow> y= t)"  by auto
  88.139 +lemma lin_dense_neq: "t \<in> U \<Longrightarrow> \<forall>x l u. (\<forall> t. l < t \<and> t< u \<longrightarrow> t \<notin> U) \<and> l< x \<and> x < u \<and> x \<noteq> t   \<longrightarrow> (\<forall> y. l < y \<and> y < u \<longrightarrow> y\<noteq> t)"  by auto
  88.140 +lemma lin_dense_P: "\<forall>x l u. (\<forall> t. l < t \<and> t< u \<longrightarrow> t \<notin> U) \<and> l< x \<and> x < u \<and> P   \<longrightarrow> (\<forall> y. l < y \<and> y < u \<longrightarrow> P)"  by auto
  88.141 +
  88.142 +lemma lin_dense_conj:
  88.143 +  "\<lbrakk>\<forall>x l u. (\<forall> t. l < t \<and> t< u \<longrightarrow> t \<notin> U) \<and> l< x \<and> x < u \<and> P1 x
  88.144 +  \<longrightarrow> (\<forall> y. l < y \<and> y < u \<longrightarrow> P1 y) ;
  88.145 +  \<forall>x l u. (\<forall> t. l < t \<and> t< u \<longrightarrow> t \<notin> U) \<and> l< x \<and> x < u \<and> P2 x
  88.146 +  \<longrightarrow> (\<forall> y. l < y \<and> y < u \<longrightarrow> P2 y)\<rbrakk> \<Longrightarrow>
  88.147 +  \<forall>x l u. (\<forall> t. l < t \<and> t< u \<longrightarrow> t \<notin> U) \<and> l< x \<and> x < u \<and> (P1 x \<and> P2 x)
  88.148 +  \<longrightarrow> (\<forall> y. l < y \<and> y < u \<longrightarrow> (P1 y \<and> P2 y))"
  88.149 +  by blast
  88.150 +lemma lin_dense_disj:
  88.151 +  "\<lbrakk>\<forall>x l u. (\<forall> t. l < t \<and> t< u \<longrightarrow> t \<notin> U) \<and> l< x \<and> x < u \<and> P1 x
  88.152 +  \<longrightarrow> (\<forall> y. l < y \<and> y < u \<longrightarrow> P1 y) ;
  88.153 +  \<forall>x l u. (\<forall> t. l < t \<and> t< u \<longrightarrow> t \<notin> U) \<and> l< x \<and> x < u \<and> P2 x
  88.154 +  \<longrightarrow> (\<forall> y. l < y \<and> y < u \<longrightarrow> P2 y)\<rbrakk> \<Longrightarrow>
  88.155 +  \<forall>x l u. (\<forall> t. l < t \<and> t< u \<longrightarrow> t \<notin> U) \<and> l< x \<and> x < u \<and> (P1 x \<or> P2 x)
  88.156 +  \<longrightarrow> (\<forall> y. l < y \<and> y < u \<longrightarrow> (P1 y \<or> P2 y))"
  88.157 +  by blast
  88.158 +
  88.159 +lemma npmibnd: "\<lbrakk>\<forall>x. \<not> MP \<and> P x \<longrightarrow> (\<exists> u\<in> U. u \<le> x); \<forall>x. \<not>PP \<and> P x \<longrightarrow> (\<exists> u\<in> U. x \<le> u)\<rbrakk>
  88.160 +  \<Longrightarrow> \<forall>x. \<not> MP \<and> \<not>PP \<and> P x \<longrightarrow> (\<exists> u\<in> U. \<exists> u' \<in> U. u \<le> x \<and> x \<le> u')"
  88.161 +by auto
  88.162 +
  88.163 +lemma finite_set_intervals:
  88.164 +  assumes px: "P x" and lx: "l \<le> x" and xu: "x \<le> u" and linS: "l\<in> S"
  88.165 +  and uinS: "u \<in> S" and fS:"finite S" and lS: "\<forall> x\<in> S. l \<le> x" and Su: "\<forall> x\<in> S. x \<le> u"
  88.166 +  shows "\<exists> a \<in> S. \<exists> b \<in> S. (\<forall> y. a < y \<and> y < b \<longrightarrow> y \<notin> S) \<and> a \<le> x \<and> x \<le> b \<and> P x"
  88.167 +proof-
  88.168 +  let ?Mx = "{y. y\<in> S \<and> y \<le> x}"
  88.169 +  let ?xM = "{y. y\<in> S \<and> x \<le> y}"
  88.170 +  let ?a = "Max ?Mx"
  88.171 +  let ?b = "Min ?xM"
  88.172 +  have MxS: "?Mx \<subseteq> S" by blast
  88.173 +  hence fMx: "finite ?Mx" using fS finite_subset by auto
  88.174 +  from lx linS have linMx: "l \<in> ?Mx" by blast
  88.175 +  hence Mxne: "?Mx \<noteq> {}" by blast
  88.176 +  have xMS: "?xM \<subseteq> S" by blast
  88.177 +  hence fxM: "finite ?xM" using fS finite_subset by auto
  88.178 +  from xu uinS have linxM: "u \<in> ?xM" by blast
  88.179 +  hence xMne: "?xM \<noteq> {}" by blast
  88.180 +  have ax:"?a \<le> x" using Mxne fMx by auto
  88.181 +  have xb:"x \<le> ?b" using xMne fxM by auto
  88.182 +  have "?a \<in> ?Mx" using Max_in[OF fMx Mxne] by simp hence ainS: "?a \<in> S" using MxS by blast
  88.183 +  have "?b \<in> ?xM" using Min_in[OF fxM xMne] by simp hence binS: "?b \<in> S" using xMS by blast
  88.184 +  have noy:"\<forall> y. ?a < y \<and> y < ?b \<longrightarrow> y \<notin> S"
  88.185 +  proof(clarsimp)
  88.186 +    fix y   assume ay: "?a < y" and yb: "y < ?b" and yS: "y \<in> S"
  88.187 +    from yS have "y\<in> ?Mx \<or> y\<in> ?xM" by (auto simp add: linear)
  88.188 +    moreover {assume "y \<in> ?Mx" hence "y \<le> ?a" using Mxne fMx by auto with ay have "False" by (simp add: not_le[symmetric])}
  88.189 +    moreover {assume "y \<in> ?xM" hence "?b \<le> y" using xMne fxM by auto with yb have "False" by (simp add: not_le[symmetric])}
  88.190 +    ultimately show "False" by blast
  88.191 +  qed
  88.192 +  from ainS binS noy ax xb px show ?thesis by blast
  88.193 +qed
  88.194 +
  88.195 +lemma finite_set_intervals2:
  88.196 +  assumes px: "P x" and lx: "l \<le> x" and xu: "x \<le> u" and linS: "l\<in> S"
  88.197 +  and uinS: "u \<in> S" and fS:"finite S" and lS: "\<forall> x\<in> S. l \<le> x" and Su: "\<forall> x\<in> S. x \<le> u"
  88.198 +  shows "(\<exists> s\<in> S. P s) \<or> (\<exists> a \<in> S. \<exists> b \<in> S. (\<forall> y. a < y \<and> y < b \<longrightarrow> y \<notin> S) \<and> a < x \<and> x < b \<and> P x)"
  88.199 +proof-
  88.200 +  from finite_set_intervals[where P="P", OF px lx xu linS uinS fS lS Su]
  88.201 +  obtain a and b where
  88.202 +    as: "a\<in> S" and bs: "b\<in> S" and noS:"\<forall>y. a < y \<and> y < b \<longrightarrow> y \<notin> S"
  88.203 +    and axb: "a \<le> x \<and> x \<le> b \<and> P x"  by auto
  88.204 +  from axb have "x= a \<or> x= b \<or> (a < x \<and> x < b)" by (auto simp add: le_less)
  88.205 +  thus ?thesis using px as bs noS by blast
  88.206 +qed
  88.207 +
  88.208 +end
  88.209 +
  88.210 +section {* The classical QE after Langford for dense linear orders *}
  88.211 +
  88.212 +context dense_linear_order
  88.213 +begin
  88.214 +
  88.215 +lemma interval_empty_iff:
  88.216 +  "{y. x < y \<and> y < z} = {} \<longleftrightarrow> \<not> x < z"
  88.217 +  by (auto dest: dense)
  88.218 +
  88.219 +lemma dlo_qe_bnds: 
  88.220 +  assumes ne: "L \<noteq> {}" and neU: "U \<noteq> {}" and fL: "finite L" and fU: "finite U"
  88.221 +  shows "(\<exists>x. (\<forall>y \<in> L. y < x) \<and> (\<forall>y \<in> U. x < y)) \<equiv> (\<forall> l \<in> L. \<forall>u \<in> U. l < u)"
  88.222 +proof (simp only: atomize_eq, rule iffI)
  88.223 +  assume H: "\<exists>x. (\<forall>y\<in>L. y < x) \<and> (\<forall>y\<in>U. x < y)"
  88.224 +  then obtain x where xL: "\<forall>y\<in>L. y < x" and xU: "\<forall>y\<in>U. x < y" by blast
  88.225 +  {fix l u assume l: "l \<in> L" and u: "u \<in> U"
  88.226 +    have "l < x" using xL l by blast
  88.227 +    also have "x < u" using xU u by blast
  88.228 +    finally (less_trans) have "l < u" .}
  88.229 +  thus "\<forall>l\<in>L. \<forall>u\<in>U. l < u" by blast
  88.230 +next
  88.231 +  assume H: "\<forall>l\<in>L. \<forall>u\<in>U. l < u"
  88.232 +  let ?ML = "Max L"
  88.233 +  let ?MU = "Min U"  
  88.234 +  from fL ne have th1: "?ML \<in> L" and th1': "\<forall>l\<in>L. l \<le> ?ML" by auto
  88.235 +  from fU neU have th2: "?MU \<in> U" and th2': "\<forall>u\<in>U. ?MU \<le> u" by auto
  88.236 +  from th1 th2 H have "?ML < ?MU" by auto
  88.237 +  with dense obtain w where th3: "?ML < w" and th4: "w < ?MU" by blast
  88.238 +  from th3 th1' have "\<forall>l \<in> L. l < w" by auto
  88.239 +  moreover from th4 th2' have "\<forall>u \<in> U. w < u" by auto
  88.240 +  ultimately show "\<exists>x. (\<forall>y\<in>L. y < x) \<and> (\<forall>y\<in>U. x < y)" by auto
  88.241 +qed
  88.242 +
  88.243 +lemma dlo_qe_noub: 
  88.244 +  assumes ne: "L \<noteq> {}" and fL: "finite L"
  88.245 +  shows "(\<exists>x. (\<forall>y \<in> L. y < x) \<and> (\<forall>y \<in> {}. x < y)) \<equiv> True"
  88.246 +proof(simp add: atomize_eq)
  88.247 +  from gt_ex[of "Max L"] obtain M where M: "Max L < M" by blast
  88.248 +  from ne fL have "\<forall>x \<in> L. x \<le> Max L" by simp
  88.249 +  with M have "\<forall>x\<in>L. x < M" by (auto intro: le_less_trans)
  88.250 +  thus "\<exists>x. \<forall>y\<in>L. y < x" by blast
  88.251 +qed
  88.252 +
  88.253 +lemma dlo_qe_nolb: 
  88.254 +  assumes ne: "U \<noteq> {}" and fU: "finite U"
  88.255 +  shows "(\<exists>x. (\<forall>y \<in> {}. y < x) \<and> (\<forall>y \<in> U. x < y)) \<equiv> True"
  88.256 +proof(simp add: atomize_eq)
  88.257 +  from lt_ex[of "Min U"] obtain M where M: "M < Min U" by blast
  88.258 +  from ne fU have "\<forall>x \<in> U. Min U \<le> x" by simp
  88.259 +  with M have "\<forall>x\<in>U. M < x" by (auto intro: less_le_trans)
  88.260 +  thus "\<exists>x. \<forall>y\<in>U. x < y" by blast
  88.261 +qed
  88.262 +
  88.263 +lemma exists_neq: "\<exists>(x::'a). x \<noteq> t" "\<exists>(x::'a). t \<noteq> x" 
  88.264 +  using gt_ex[of t] by auto
  88.265 +
  88.266 +lemmas dlo_simps = order_refl less_irrefl not_less not_le exists_neq 
  88.267 +  le_less neq_iff linear less_not_permute
  88.268 +
  88.269 +lemma axiom: "dense_linear_order (op \<le>) (op <)" by (rule dense_linear_order_axioms)
  88.270 +lemma atoms:
  88.271 +  shows "TERM (less :: 'a \<Rightarrow> _)"
  88.272 +    and "TERM (less_eq :: 'a \<Rightarrow> _)"
  88.273 +    and "TERM (op = :: 'a \<Rightarrow> _)" .
  88.274 +
  88.275 +declare axiom[langford qe: dlo_qe_bnds dlo_qe_nolb dlo_qe_noub gather: gather_start gather_simps atoms: atoms]
  88.276 +declare dlo_simps[langfordsimp]
  88.277 +
  88.278 +end
  88.279 +
  88.280 +(* FIXME: Move to HOL -- together with the conj_aci_rule in langford.ML *)
  88.281 +lemma dnf:
  88.282 +  "(P & (Q | R)) = ((P&Q) | (P&R))" 
  88.283 +  "((Q | R) & P) = ((Q&P) | (R&P))"
  88.284 +  by blast+
  88.285 +
  88.286 +lemmas weak_dnf_simps = simp_thms dnf
  88.287 +
  88.288 +lemma nnf_simps:
  88.289 +    "(\<not>(P \<and> Q)) = (\<not>P \<or> \<not>Q)" "(\<not>(P \<or> Q)) = (\<not>P \<and> \<not>Q)" "(P \<longrightarrow> Q) = (\<not>P \<or> Q)"
  88.290 +    "(P = Q) = ((P \<and> Q) \<or> (\<not>P \<and> \<not> Q))" "(\<not> \<not>(P)) = P"
  88.291 +  by blast+
  88.292 +
  88.293 +lemma ex_distrib: "(\<exists>x. P x \<or> Q x) \<longleftrightarrow> ((\<exists>x. P x) \<or> (\<exists>x. Q x))" by blast
  88.294 +
  88.295 +lemmas dnf_simps = weak_dnf_simps nnf_simps ex_distrib
  88.296 +
  88.297 +use "~~/src/HOL/Tools/Qelim/langford.ML"
  88.298 +method_setup dlo = {*
  88.299 +  Method.ctxt_args (Method.SIMPLE_METHOD' o LangfordQE.dlo_tac)
  88.300 +*} "Langford's algorithm for quantifier elimination in dense linear orders"
  88.301 +
  88.302 +
  88.303 +section {* Contructive dense linear orders yield QE for linear arithmetic over ordered Fields -- see @{text "Arith_Tools.thy"} *}
  88.304 +
  88.305 +text {* Linear order without upper bounds *}
  88.306 +
  88.307 +class_locale linorder_stupid_syntax = linorder
  88.308 +begin
  88.309 +notation
  88.310 +  less_eq  ("op \<sqsubseteq>") and
  88.311 +  less_eq  ("(_/ \<sqsubseteq> _)" [51, 51] 50) and
  88.312 +  less  ("op \<sqsubset>") and
  88.313 +  less  ("(_/ \<sqsubset> _)"  [51, 51] 50)
  88.314 +
  88.315 +end
  88.316 +
  88.317 +class_locale linorder_no_ub = linorder_stupid_syntax +
  88.318 +  assumes gt_ex: "\<exists>y. less x y"
  88.319 +begin
  88.320 +lemma ge_ex: "\<exists>y. x \<sqsubseteq> y" using gt_ex by auto
  88.321 +
  88.322 +text {* Theorems for @{text "\<exists>z. \<forall>x. z \<sqsubset> x \<longrightarrow> (P x \<longleftrightarrow> P\<^bsub>+\<infinity>\<^esub>)"} *}
  88.323 +lemma pinf_conj:
  88.324 +  assumes ex1: "\<exists>z1. \<forall>x. z1 \<sqsubset> x \<longrightarrow> (P1 x \<longleftrightarrow> P1')"
  88.325 +  and ex2: "\<exists>z2. \<forall>x. z2 \<sqsubset> x \<longrightarrow> (P2 x \<longleftrightarrow> P2')"
  88.326 +  shows "\<exists>z. \<forall>x. z \<sqsubset>  x \<longrightarrow> ((P1 x \<and> P2 x) \<longleftrightarrow> (P1' \<and> P2'))"
  88.327 +proof-
  88.328 +  from ex1 ex2 obtain z1 and z2 where z1: "\<forall>x. z1 \<sqsubset> x \<longrightarrow> (P1 x \<longleftrightarrow> P1')"
  88.329 +     and z2: "\<forall>x. z2 \<sqsubset> x \<longrightarrow> (P2 x \<longleftrightarrow> P2')" by blast
  88.330 +  from gt_ex obtain z where z:"ord.max less_eq z1 z2 \<sqsubset> z" by blast
  88.331 +  from z have zz1: "z1 \<sqsubset> z" and zz2: "z2 \<sqsubset> z" by simp_all
  88.332 +  {fix x assume H: "z \<sqsubset> x"
  88.333 +    from less_trans[OF zz1 H] less_trans[OF zz2 H]
  88.334 +    have "(P1 x \<and> P2 x) \<longleftrightarrow> (P1' \<and> P2')"  using z1 zz1 z2 zz2 by auto
  88.335 +  }
  88.336 +  thus ?thesis by blast
  88.337 +qed
  88.338 +
  88.339 +lemma pinf_disj:
  88.340 +  assumes ex1: "\<exists>z1. \<forall>x. z1 \<sqsubset> x \<longrightarrow> (P1 x \<longleftrightarrow> P1')"
  88.341 +  and ex2: "\<exists>z2. \<forall>x. z2 \<sqsubset> x \<longrightarrow> (P2 x \<longleftrightarrow> P2')"
  88.342 +  shows "\<exists>z. \<forall>x. z \<sqsubset>  x \<longrightarrow> ((P1 x \<or> P2 x) \<longleftrightarrow> (P1' \<or> P2'))"
  88.343 +proof-
  88.344 +  from ex1 ex2 obtain z1 and z2 where z1: "\<forall>x. z1 \<sqsubset> x \<longrightarrow> (P1 x \<longleftrightarrow> P1')"
  88.345 +     and z2: "\<forall>x. z2 \<sqsubset> x \<longrightarrow> (P2 x \<longleftrightarrow> P2')" by blast
  88.346 +  from gt_ex obtain z where z:"ord.max less_eq z1 z2 \<sqsubset> z" by blast
  88.347 +  from z have zz1: "z1 \<sqsubset> z" and zz2: "z2 \<sqsubset> z" by simp_all
  88.348 +  {fix x assume H: "z \<sqsubset> x"
  88.349 +    from less_trans[OF zz1 H] less_trans[OF zz2 H]
  88.350 +    have "(P1 x \<or> P2 x) \<longleftrightarrow> (P1' \<or> P2')"  using z1 zz1 z2 zz2 by auto
  88.351 +  }
  88.352 +  thus ?thesis by blast
  88.353 +qed
  88.354 +
  88.355 +lemma pinf_ex: assumes ex:"\<exists>z. \<forall>x. z \<sqsubset> x \<longrightarrow> (P x \<longleftrightarrow> P1)" and p1: P1 shows "\<exists> x. P x"
  88.356 +proof-
  88.357 +  from ex obtain z where z: "\<forall>x. z \<sqsubset> x \<longrightarrow> (P x \<longleftrightarrow> P1)" by blast
  88.358 +  from gt_ex obtain x where x: "z \<sqsubset> x" by blast
  88.359 +  from z x p1 show ?thesis by blast
  88.360 +qed
  88.361 +
  88.362 +end
  88.363 +
  88.364 +text {* Linear order without upper bounds *}
  88.365 +
  88.366 +class_locale linorder_no_lb = linorder_stupid_syntax +
  88.367 +  assumes lt_ex: "\<exists>y. less y x"
  88.368 +begin
  88.369 +lemma le_ex: "\<exists>y. y \<sqsubseteq> x" using lt_ex by auto
  88.370 +
  88.371 +
  88.372 +text {* Theorems for @{text "\<exists>z. \<forall>x. x \<sqsubset> z \<longrightarrow> (P x \<longleftrightarrow> P\<^bsub>-\<infinity>\<^esub>)"} *}
  88.373 +lemma minf_conj:
  88.374 +  assumes ex1: "\<exists>z1. \<forall>x. x \<sqsubset> z1 \<longrightarrow> (P1 x \<longleftrightarrow> P1')"
  88.375 +  and ex2: "\<exists>z2. \<forall>x. x \<sqsubset> z2 \<longrightarrow> (P2 x \<longleftrightarrow> P2')"
  88.376 +  shows "\<exists>z. \<forall>x. x \<sqsubset>  z \<longrightarrow> ((P1 x \<and> P2 x) \<longleftrightarrow> (P1' \<and> P2'))"
  88.377 +proof-
  88.378 +  from ex1 ex2 obtain z1 and z2 where z1: "\<forall>x. x \<sqsubset> z1 \<longrightarrow> (P1 x \<longleftrightarrow> P1')"and z2: "\<forall>x. x \<sqsubset> z2 \<longrightarrow> (P2 x \<longleftrightarrow> P2')" by blast
  88.379 +  from lt_ex obtain z where z:"z \<sqsubset> ord.min less_eq z1 z2" by blast
  88.380 +  from z have zz1: "z \<sqsubset> z1" and zz2: "z \<sqsubset> z2" by simp_all
  88.381 +  {fix x assume H: "x \<sqsubset> z"
  88.382 +    from less_trans[OF H zz1] less_trans[OF H zz2]
  88.383 +    have "(P1 x \<and> P2 x) \<longleftrightarrow> (P1' \<and> P2')"  using z1 zz1 z2 zz2 by auto
  88.384 +  }
  88.385 +  thus ?thesis by blast
  88.386 +qed
  88.387 +
  88.388 +lemma minf_disj:
  88.389 +  assumes ex1: "\<exists>z1. \<forall>x. x \<sqsubset> z1 \<longrightarrow> (P1 x \<longleftrightarrow> P1')"
  88.390 +  and ex2: "\<exists>z2. \<forall>x. x \<sqsubset> z2 \<longrightarrow> (P2 x \<longleftrightarrow> P2')"
  88.391 +  shows "\<exists>z. \<forall>x. x \<sqsubset>  z \<longrightarrow> ((P1 x \<or> P2 x) \<longleftrightarrow> (P1' \<or> P2'))"
  88.392 +proof-
  88.393 +  from ex1 ex2 obtain z1 and z2 where z1: "\<forall>x. x \<sqsubset> z1 \<longrightarrow> (P1 x \<longleftrightarrow> P1')"and z2: "\<forall>x. x \<sqsubset> z2 \<longrightarrow> (P2 x \<longleftrightarrow> P2')" by blast
  88.394 +  from lt_ex obtain z where z:"z \<sqsubset> ord.min less_eq z1 z2" by blast
  88.395 +  from z have zz1: "z \<sqsubset> z1" and zz2: "z \<sqsubset> z2" by simp_all
  88.396 +  {fix x assume H: "x \<sqsubset> z"
  88.397 +    from less_trans[OF H zz1] less_trans[OF H zz2]
  88.398 +    have "(P1 x \<or> P2 x) \<longleftrightarrow> (P1' \<or> P2')"  using z1 zz1 z2 zz2 by auto
  88.399 +  }
  88.400 +  thus ?thesis by blast
  88.401 +qed
  88.402 +
  88.403 +lemma minf_ex: assumes ex:"\<exists>z. \<forall>x. x \<sqsubset> z \<longrightarrow> (P x \<longleftrightarrow> P1)" and p1: P1 shows "\<exists> x. P x"
  88.404 +proof-
  88.405 +  from ex obtain z where z: "\<forall>x. x \<sqsubset> z \<longrightarrow> (P x \<longleftrightarrow> P1)" by blast
  88.406 +  from lt_ex obtain x where x: "x \<sqsubset> z" by blast
  88.407 +  from z x p1 show ?thesis by blast
  88.408 +qed
  88.409 +
  88.410 +end
  88.411 +
  88.412 +
  88.413 +class_locale constr_dense_linear_order = linorder_no_lb + linorder_no_ub +
  88.414 +  fixes between
  88.415 +  assumes between_less: "less x y \<Longrightarrow> less x (between x y) \<and> less (between x y) y"
  88.416 +     and  between_same: "between x x = x"
  88.417 +
  88.418 +class_interpretation  constr_dense_linear_order < dense_linear_order 
  88.419 +  apply unfold_locales
  88.420 +  using gt_ex lt_ex between_less
  88.421 +    by (auto, rule_tac x="between x y" in exI, simp)
  88.422 +
  88.423 +context  constr_dense_linear_order
  88.424 +begin
  88.425 +
  88.426 +lemma rinf_U:
  88.427 +  assumes fU: "finite U"
  88.428 +  and lin_dense: "\<forall>x l u. (\<forall> t. l \<sqsubset> t \<and> t\<sqsubset> u \<longrightarrow> t \<notin> U) \<and> l\<sqsubset> x \<and> x \<sqsubset> u \<and> P x
  88.429 +  \<longrightarrow> (\<forall> y. l \<sqsubset> y \<and> y \<sqsubset> u \<longrightarrow> P y )"
  88.430 +  and nmpiU: "\<forall>x. \<not> MP \<and> \<not>PP \<and> P x \<longrightarrow> (\<exists> u\<in> U. \<exists> u' \<in> U. u \<sqsubseteq> x \<and> x \<sqsubseteq> u')"
  88.431 +  and nmi: "\<not> MP"  and npi: "\<not> PP"  and ex: "\<exists> x.  P x"
  88.432 +  shows "\<exists> u\<in> U. \<exists> u' \<in> U. P (between u u')"
  88.433 +proof-
  88.434 +  from ex obtain x where px: "P x" by blast
  88.435 +  from px nmi npi nmpiU have "\<exists> u\<in> U. \<exists> u' \<in> U. u \<sqsubseteq> x \<and> x \<sqsubseteq> u'" by auto
  88.436 +  then obtain u and u' where uU:"u\<in> U" and uU': "u' \<in> U" and ux:"u \<sqsubseteq> x" and xu':"x \<sqsubseteq> u'" by auto
  88.437 +  from uU have Une: "U \<noteq> {}" by auto
  88.438 +  term "linorder.Min less_eq"
  88.439 +  let ?l = "linorder.Min less_eq U"
  88.440 +  let ?u = "linorder.Max less_eq U"
  88.441 +  have linM: "?l \<in> U" using fU Une by simp
  88.442 +  have uinM: "?u \<in> U" using fU Une by simp
  88.443 +  have lM: "\<forall> t\<in> U. ?l \<sqsubseteq> t" using Une fU by auto
  88.444 +  have Mu: "\<forall> t\<in> U. t \<sqsubseteq> ?u" using Une fU by auto
  88.445 +  have th:"?l \<sqsubseteq> u" using uU Une lM by auto
  88.446 +  from order_trans[OF th ux] have lx: "?l \<sqsubseteq> x" .
  88.447 +  have th: "u' \<sqsubseteq> ?u" using uU' Une Mu by simp
  88.448 +  from order_trans[OF xu' th] have xu: "x \<sqsubseteq> ?u" .
  88.449 +  from finite_set_intervals2[where P="P",OF px lx xu linM uinM fU lM Mu]
  88.450 +  have "(\<exists> s\<in> U. P s) \<or>
  88.451 +      (\<exists> t1\<in> U. \<exists> t2 \<in> U. (\<forall> y. t1 \<sqsubset> y \<and> y \<sqsubset> t2 \<longrightarrow> y \<notin> U) \<and> t1 \<sqsubset> x \<and> x \<sqsubset> t2 \<and> P x)" .
  88.452 +  moreover { fix u assume um: "u\<in>U" and pu: "P u"
  88.453 +    have "between u u = u" by (simp add: between_same)
  88.454 +    with um pu have "P (between u u)" by simp
  88.455 +    with um have ?thesis by blast}
  88.456 +  moreover{
  88.457 +    assume "\<exists> t1\<in> U. \<exists> t2 \<in> U. (\<forall> y. t1 \<sqsubset> y \<and> y \<sqsubset> t2 \<longrightarrow> y \<notin> U) \<and> t1 \<sqsubset> x \<and> x \<sqsubset> t2 \<and> P x"
  88.458 +      then obtain t1 and t2 where t1M: "t1 \<in> U" and t2M: "t2\<in> U"
  88.459 +        and noM: "\<forall> y. t1 \<sqsubset> y \<and> y \<sqsubset> t2 \<longrightarrow> y \<notin> U" and t1x: "t1 \<sqsubset> x" and xt2: "x \<sqsubset> t2" and px: "P x"
  88.460 +        by blast
  88.461 +      from less_trans[OF t1x xt2] have t1t2: "t1 \<sqsubset> t2" .
  88.462 +      let ?u = "between t1 t2"
  88.463 +      from between_less t1t2 have t1lu: "t1 \<sqsubset> ?u" and ut2: "?u \<sqsubset> t2" by auto
  88.464 +      from lin_dense noM t1x xt2 px t1lu ut2 have "P ?u" by blast
  88.465 +      with t1M t2M have ?thesis by blast}
  88.466 +    ultimately show ?thesis by blast
  88.467 +  qed
  88.468 +
  88.469 +theorem fr_eq:
  88.470 +  assumes fU: "finite U"
  88.471 +  and lin_dense: "\<forall>x l u. (\<forall> t. l \<sqsubset> t \<and> t\<sqsubset> u \<longrightarrow> t \<notin> U) \<and> l\<sqsubset> x \<and> x \<sqsubset> u \<and> P x
  88.472 +   \<longrightarrow> (\<forall> y. l \<sqsubset> y \<and> y \<sqsubset> u \<longrightarrow> P y )"
  88.473 +  and nmibnd: "\<forall>x. \<not> MP \<and> P x \<longrightarrow> (\<exists> u\<in> U. u \<sqsubseteq> x)"
  88.474 +  and npibnd: "\<forall>x. \<not>PP \<and> P x \<longrightarrow> (\<exists> u\<in> U. x \<sqsubseteq> u)"
  88.475 +  and mi: "\<exists>z. \<forall>x. x \<sqsubset> z \<longrightarrow> (P x = MP)"  and pi: "\<exists>z. \<forall>x. z \<sqsubset> x \<longrightarrow> (P x = PP)"
  88.476 +  shows "(\<exists> x. P x) \<equiv> (MP \<or> PP \<or> (\<exists> u \<in> U. \<exists> u'\<in> U. P (between u u')))"
  88.477 +  (is "_ \<equiv> (_ \<or> _ \<or> ?F)" is "?E \<equiv> ?D")
  88.478 +proof-
  88.479 + {
  88.480 +   assume px: "\<exists> x. P x"
  88.481 +   have "MP \<or> PP \<or> (\<not> MP \<and> \<not> PP)" by blast
  88.482 +   moreover {assume "MP \<or> PP" hence "?D" by blast}
  88.483 +   moreover {assume nmi: "\<not> MP" and npi: "\<not> PP"
  88.484 +     from npmibnd[OF nmibnd npibnd]
  88.485 +     have nmpiU: "\<forall>x. \<not> MP \<and> \<not>PP \<and> P x \<longrightarrow> (\<exists> u\<in> U. \<exists> u' \<in> U. u \<sqsubseteq> x \<and> x \<sqsubseteq> u')" .
  88.486 +     from rinf_U[OF fU lin_dense nmpiU nmi npi px] have "?D" by blast}
  88.487 +   ultimately have "?D" by blast}
  88.488 + moreover
  88.489 + { assume "?D"
  88.490 +   moreover {assume m:"MP" from minf_ex[OF mi m] have "?E" .}
  88.491 +   moreover {assume p: "PP" from pinf_ex[OF pi p] have "?E" . }
  88.492 +   moreover {assume f:"?F" hence "?E" by blast}
  88.493 +   ultimately have "?E" by blast}
  88.494 + ultimately have "?E = ?D" by blast thus "?E \<equiv> ?D" by simp
  88.495 +qed
  88.496 +
  88.497 +lemmas minf_thms = minf_conj minf_disj minf_eq minf_neq minf_lt minf_le minf_gt minf_ge minf_P
  88.498 +lemmas pinf_thms = pinf_conj pinf_disj pinf_eq pinf_neq pinf_lt pinf_le pinf_gt pinf_ge pinf_P
  88.499 +
  88.500 +lemmas nmi_thms = nmi_conj nmi_disj nmi_eq nmi_neq nmi_lt nmi_le nmi_gt nmi_ge nmi_P
  88.501 +lemmas npi_thms = npi_conj npi_disj npi_eq npi_neq npi_lt npi_le npi_gt npi_ge npi_P
  88.502 +lemmas lin_dense_thms = lin_dense_conj lin_dense_disj lin_dense_eq lin_dense_neq lin_dense_lt lin_dense_le lin_dense_gt lin_dense_ge lin_dense_P
  88.503 +
  88.504 +lemma ferrack_axiom: "constr_dense_linear_order less_eq less between"
  88.505 +  by (rule constr_dense_linear_order_axioms)
  88.506 +lemma atoms:
  88.507 +  shows "TERM (less :: 'a \<Rightarrow> _)"
  88.508 +    and "TERM (less_eq :: 'a \<Rightarrow> _)"
  88.509 +    and "TERM (op = :: 'a \<Rightarrow> _)" .
  88.510 +
  88.511 +declare ferrack_axiom [ferrack minf: minf_thms pinf: pinf_thms
  88.512 +    nmi: nmi_thms npi: npi_thms lindense:
  88.513 +    lin_dense_thms qe: fr_eq atoms: atoms]
  88.514 +
  88.515 +declaration {*
  88.516 +let
  88.517 +fun simps phi = map (Morphism.thm phi) [@{thm "not_less"}, @{thm "not_le"}]
  88.518 +fun generic_whatis phi =
  88.519 + let
  88.520 +  val [lt, le] = map (Morphism.term phi) [@{term "op \<sqsubset>"}, @{term "op \<sqsubseteq>"}]
  88.521 +  fun h x t =
  88.522 +   case term_of t of
  88.523 +     Const("op =", _)$y$z => if term_of x aconv y then Ferrante_Rackoff_Data.Eq
  88.524 +                            else Ferrante_Rackoff_Data.Nox
  88.525 +   | @{term "Not"}$(Const("op =", _)$y$z) => if term_of x aconv y then Ferrante_Rackoff_Data.NEq
  88.526 +                            else Ferrante_Rackoff_Data.Nox
  88.527 +   | b$y$z => if Term.could_unify (b, lt) then
  88.528 +                 if term_of x aconv y then Ferrante_Rackoff_Data.Lt
  88.529 +                 else if term_of x aconv z then Ferrante_Rackoff_Data.Gt
  88.530 +                 else Ferrante_Rackoff_Data.Nox
  88.531 +             else if Term.could_unify (b, le) then
  88.532 +                 if term_of x aconv y then Ferrante_Rackoff_Data.Le
  88.533 +                 else if term_of x aconv z then Ferrante_Rackoff_Data.Ge
  88.534 +                 else Ferrante_Rackoff_Data.Nox
  88.535 +             else Ferrante_Rackoff_Data.Nox
  88.536 +   | _ => Ferrante_Rackoff_Data.Nox
  88.537 + in h end
  88.538 + fun ss phi = HOL_ss addsimps (simps phi)
  88.539 +in
  88.540 + Ferrante_Rackoff_Data.funs  @{thm "ferrack_axiom"}
  88.541 +  {isolate_conv = K (K (K Thm.reflexive)), whatis = generic_whatis, simpset = ss}
  88.542 +end
  88.543 +*}
  88.544 +
  88.545 +end
  88.546 +
  88.547 +use "~~/src/HOL/Tools/Qelim/ferrante_rackoff.ML"
  88.548 +
  88.549 +method_setup ferrack = {*
  88.550 +  Method.ctxt_args (Method.SIMPLE_METHOD' o FerranteRackoff.dlo_tac)
  88.551 +*} "Ferrante and Rackoff's algorithm for quantifier elimination in dense linear orders"
  88.552 +
  88.553 +subsection {* Ferrante and Rackoff algorithm over ordered fields *}
  88.554 +
  88.555 +lemma neg_prod_lt:"(c\<Colon>'a\<Colon>ordered_field) < 0 \<Longrightarrow> ((c*x < 0) == (x > 0))"
  88.556 +proof-
  88.557 +  assume H: "c < 0"
  88.558 +  have "c*x < 0 = (0/c < x)" by (simp only: neg_divide_less_eq[OF H] ring_simps)
  88.559 +  also have "\<dots> = (0 < x)" by simp
  88.560 +  finally show  "(c*x < 0) == (x > 0)" by simp
  88.561 +qed
  88.562 +
  88.563 +lemma pos_prod_lt:"(c\<Colon>'a\<Colon>ordered_field) > 0 \<Longrightarrow> ((c*x < 0) == (x < 0))"
  88.564 +proof-
  88.565 +  assume H: "c > 0"
  88.566 +  hence "c*x < 0 = (0/c > x)" by (simp only: pos_less_divide_eq[OF H] ring_simps)
  88.567 +  also have "\<dots> = (0 > x)" by simp
  88.568 +  finally show  "(c*x < 0) == (x < 0)" by simp
  88.569 +qed
  88.570 +
  88.571 +lemma neg_prod_sum_lt: "(c\<Colon>'a\<Colon>ordered_field) < 0 \<Longrightarrow> ((c*x + t< 0) == (x > (- 1/c)*t))"
  88.572 +proof-
  88.573 +  assume H: "c < 0"
  88.574 +  have "c*x + t< 0 = (c*x < -t)" by (subst less_iff_diff_less_0 [of "c*x" "-t"], simp)
  88.575 +  also have "\<dots> = (-t/c < x)" by (simp only: neg_divide_less_eq[OF H] ring_simps)
  88.576 +  also have "\<dots> = ((- 1/c)*t < x)" by simp
  88.577 +  finally show  "(c*x + t < 0) == (x > (- 1/c)*t)" by simp
  88.578 +qed
  88.579 +
  88.580 +lemma pos_prod_sum_lt:"(c\<Colon>'a\<Colon>ordered_field) > 0 \<Longrightarrow> ((c*x + t < 0) == (x < (- 1/c)*t))"
  88.581 +proof-
  88.582 +  assume H: "c > 0"
  88.583 +  have "c*x + t< 0 = (c*x < -t)"  by (subst less_iff_diff_less_0 [of "c*x" "-t"], simp)
  88.584 +  also have "\<dots> = (-t/c > x)" by (simp only: pos_less_divide_eq[OF H] ring_simps)
  88.585 +  also have "\<dots> = ((- 1/c)*t > x)" by simp
  88.586 +  finally show  "(c*x + t < 0) == (x < (- 1/c)*t)" by simp
  88.587 +qed
  88.588 +
  88.589 +lemma sum_lt:"((x::'a::pordered_ab_group_add) + t < 0) == (x < - t)"
  88.590 +  using less_diff_eq[where a= x and b=t and c=0] by simp
  88.591 +
  88.592 +lemma neg_prod_le:"(c\<Colon>'a\<Colon>ordered_field) < 0 \<Longrightarrow> ((c*x <= 0) == (x >= 0))"
  88.593 +proof-
  88.594 +  assume H: "c < 0"
  88.595 +  have "c*x <= 0 = (0/c <= x)" by (simp only: neg_divide_le_eq[OF H] ring_simps)
  88.596 +  also have "\<dots> = (0 <= x)" by simp
  88.597 +  finally show  "(c*x <= 0) == (x >= 0)" by simp
  88.598 +qed
  88.599 +
  88.600 +lemma pos_prod_le:"(c\<Colon>'a\<Colon>ordered_field) > 0 \<Longrightarrow> ((c*x <= 0) == (x <= 0))"
  88.601 +proof-
  88.602 +  assume H: "c > 0"
  88.603 +  hence "c*x <= 0 = (0/c >= x)" by (simp only: pos_le_divide_eq[OF H] ring_simps)
  88.604 +  also have "\<dots> = (0 >= x)" by simp
  88.605 +  finally show  "(c*x <= 0) == (x <= 0)" by simp
  88.606 +qed
  88.607 +
  88.608 +lemma neg_prod_sum_le: "(c\<Colon>'a\<Colon>ordered_field) < 0 \<Longrightarrow> ((c*x + t <= 0) == (x >= (- 1/c)*t))"
  88.609 +proof-
  88.610 +  assume H: "c < 0"
  88.611 +  have "c*x + t <= 0 = (c*x <= -t)"  by (subst le_iff_diff_le_0 [of "c*x" "-t"], simp)
  88.612 +  also have "\<dots> = (-t/c <= x)" by (simp only: neg_divide_le_eq[OF H] ring_simps)
  88.613 +  also have "\<dots> = ((- 1/c)*t <= x)" by simp
  88.614 +  finally show  "(c*x + t <= 0) == (x >= (- 1/c)*t)" by simp
  88.615 +qed
  88.616 +
  88.617 +lemma pos_prod_sum_le:"(c\<Colon>'a\<Colon>ordered_field) > 0 \<Longrightarrow> ((c*x + t <= 0) == (x <= (- 1/c)*t))"
  88.618 +proof-
  88.619 +  assume H: "c > 0"
  88.620 +  have "c*x + t <= 0 = (c*x <= -t)" by (subst le_iff_diff_le_0 [of "c*x" "-t"], simp)
  88.621 +  also have "\<dots> = (-t/c >= x)" by (simp only: pos_le_divide_eq[OF H] ring_simps)
  88.622 +  also have "\<dots> = ((- 1/c)*t >= x)" by simp
  88.623 +  finally show  "(c*x + t <= 0) == (x <= (- 1/c)*t)" by simp
  88.624 +qed
  88.625 +
  88.626 +lemma sum_le:"((x::'a::pordered_ab_group_add) + t <= 0) == (x <= - t)"
  88.627 +  using le_diff_eq[where a= x and b=t and c=0] by simp
  88.628 +
  88.629 +lemma nz_prod_eq:"(c\<Colon>'a\<Colon>ordered_field) \<noteq> 0 \<Longrightarrow> ((c*x = 0) == (x = 0))" by simp
  88.630 +lemma nz_prod_sum_eq: "(c\<Colon>'a\<Colon>ordered_field) \<noteq> 0 \<Longrightarrow> ((c*x + t = 0) == (x = (- 1/c)*t))"
  88.631 +proof-
  88.632 +  assume H: "c \<noteq> 0"
  88.633 +  have "c*x + t = 0 = (c*x = -t)" by (subst eq_iff_diff_eq_0 [of "c*x" "-t"], simp)
  88.634 +  also have "\<dots> = (x = -t/c)" by (simp only: nonzero_eq_divide_eq[OF H] ring_simps)
  88.635 +  finally show  "(c*x + t = 0) == (x = (- 1/c)*t)" by simp
  88.636 +qed
  88.637 +lemma sum_eq:"((x::'a::pordered_ab_group_add) + t = 0) == (x = - t)"
  88.638 +  using eq_diff_eq[where a= x and b=t and c=0] by simp
  88.639 +
  88.640 +
  88.641 +class_interpretation class_ordered_field_dense_linear_order: constr_dense_linear_order
  88.642 + ["op <=" "op <"
  88.643 +   "\<lambda> x y. 1/2 * ((x::'a::{ordered_field,recpower,number_ring}) + y)"]
  88.644 +proof (unfold_locales, dlo, dlo, auto)
  88.645 +  fix x y::'a assume lt: "x < y"
  88.646 +  from  less_half_sum[OF lt] show "x < (x + y) /2" by simp
  88.647 +next
  88.648 +  fix x y::'a assume lt: "x < y"
  88.649 +  from  gt_half_sum[OF lt] show "(x + y) /2 < y" by simp
  88.650 +qed
  88.651 +
  88.652 +declaration{*
  88.653 +let
  88.654 +fun earlier [] x y = false
  88.655 +        | earlier (h::t) x y =
  88.656 +    if h aconvc y then false else if h aconvc x then true else earlier t x y;
  88.657 +
  88.658 +fun dest_frac ct = case term_of ct of
  88.659 +   Const (@{const_name "HOL.divide"},_) $ a $ b=>
  88.660 +    Rat.rat_of_quotient (snd (HOLogic.dest_number a), snd (HOLogic.dest_number b))
  88.661 + | t => Rat.rat_of_int (snd (HOLogic.dest_number t))
  88.662 +
  88.663 +fun mk_frac phi cT x =
  88.664 + let val (a, b) = Rat.quotient_of_rat x
  88.665 + in if b = 1 then Numeral.mk_cnumber cT a
  88.666 +    else Thm.capply
  88.667 +         (Thm.capply (Drule.cterm_rule (instantiate' [SOME cT] []) @{cpat "op /"})
  88.668 +                     (Numeral.mk_cnumber cT a))
  88.669 +         (Numeral.mk_cnumber cT b)
  88.670 + end
  88.671 +
  88.672 +fun whatis x ct = case term_of ct of
  88.673 +  Const(@{const_name "HOL.plus"}, _)$(Const(@{const_name "HOL.times"},_)$_$y)$_ =>
  88.674 +     if y aconv term_of x then ("c*x+t",[(funpow 2 Thm.dest_arg1) ct, Thm.dest_arg ct])
  88.675 +     else ("Nox",[])
  88.676 +| Const(@{const_name "HOL.plus"}, _)$y$_ =>
  88.677 +     if y aconv term_of x then ("x+t",[Thm.dest_arg ct])
  88.678 +     else ("Nox",[])
  88.679 +| Const(@{const_name "HOL.times"}, _)$_$y =>
  88.680 +     if y aconv term_of x then ("c*x",[Thm.dest_arg1 ct])
  88.681 +     else ("Nox",[])
  88.682 +| t => if t aconv term_of x then ("x",[]) else ("Nox",[]);
  88.683 +
  88.684 +fun xnormalize_conv ctxt [] ct = reflexive ct
  88.685 +| xnormalize_conv ctxt (vs as (x::_)) ct =
  88.686 +   case term_of ct of
  88.687 +   Const(@{const_name HOL.less},_)$_$Const(@{const_name "HOL.zero"},_) =>
  88.688 +    (case whatis x (Thm.dest_arg1 ct) of
  88.689 +    ("c*x+t",[c,t]) =>
  88.690 +       let
  88.691 +        val cr = dest_frac c
  88.692 +        val clt = Thm.dest_fun2 ct
  88.693 +        val cz = Thm.dest_arg ct
  88.694 +        val neg = cr </ Rat.zero
  88.695 +        val cthp = Simplifier.rewrite (local_simpset_of ctxt)
  88.696 +               (Thm.capply @{cterm "Trueprop"}
  88.697 +                  (if neg then Thm.capply (Thm.capply clt c) cz
  88.698 +                    else Thm.capply (Thm.capply clt cz) c))
  88.699 +        val cth = equal_elim (symmetric cthp) TrueI
  88.700 +        val th = implies_elim (instantiate' [SOME (ctyp_of_term x)] (map SOME [c,x,t])
  88.701 +             (if neg then @{thm neg_prod_sum_lt} else @{thm pos_prod_sum_lt})) cth
  88.702 +        val rth = Conv.fconv_rule (Conv.arg_conv (Conv.binop_conv
  88.703 +                   (Normalizer.semiring_normalize_ord_conv ctxt (earlier vs)))) th
  88.704 +      in rth end
  88.705 +    | ("x+t",[t]) =>
  88.706 +       let
  88.707 +        val T = ctyp_of_term x
  88.708 +        val th = instantiate' [SOME T] [SOME x, SOME t] @{thm "sum_lt"}
  88.709 +        val rth = Conv.fconv_rule (Conv.arg_conv (Conv.binop_conv
  88.710 +              (Normalizer.semiring_normalize_ord_conv ctxt (earlier vs)))) th
  88.711 +       in  rth end
  88.712 +    | ("c*x",[c]) =>
  88.713 +       let
  88.714 +        val cr = dest_frac c
  88.715 +        val clt = Thm.dest_fun2 ct
  88.716 +        val cz = Thm.dest_arg ct
  88.717 +        val neg = cr </ Rat.zero
  88.718 +        val cthp = Simplifier.rewrite (local_simpset_of ctxt)
  88.719 +               (Thm.capply @{cterm "Trueprop"}
  88.720 +                  (if neg then Thm.capply (Thm.capply clt c) cz
  88.721 +                    else Thm.capply (Thm.capply clt cz) c))
  88.722 +        val cth = equal_elim (symmetric cthp) TrueI
  88.723 +        val th = implies_elim (instantiate' [SOME (ctyp_of_term x)] (map SOME [c,x])
  88.724 +             (if neg then @{thm neg_prod_lt} else @{thm pos_prod_lt})) cth
  88.725 +        val rth = th
  88.726 +      in rth end
  88.727 +    | _ => reflexive ct)
  88.728 +
  88.729 +
  88.730 +|  Const(@{const_name HOL.less_eq},_)$_$Const(@{const_name "HOL.zero"},_) =>
  88.731 +   (case whatis x (Thm.dest_arg1 ct) of
  88.732 +    ("c*x+t",[c,t]) =>
  88.733 +       let
  88.734 +        val T = ctyp_of_term x
  88.735 +        val cr = dest_frac c
  88.736 +        val clt = Drule.cterm_rule (instantiate' [SOME T] []) @{cpat "op <"}
  88.737 +        val cz = Thm.dest_arg ct
  88.738 +        val neg = cr </ Rat.zero
  88.739 +        val cthp = Simplifier.rewrite (local_simpset_of ctxt)
  88.740 +               (Thm.capply @{cterm "Trueprop"}
  88.741 +                  (if neg then Thm.capply (Thm.capply clt c) cz
  88.742 +                    else Thm.capply (Thm.capply clt cz) c))
  88.743 +        val cth = equal_elim (symmetric cthp) TrueI
  88.744 +        val th = implies_elim (instantiate' [SOME T] (map SOME [c,x,t])
  88.745 +             (if neg then @{thm neg_prod_sum_le} else @{thm pos_prod_sum_le})) cth
  88.746 +        val rth = Conv.fconv_rule (Conv.arg_conv (Conv.binop_conv
  88.747 +                   (Normalizer.semiring_normalize_ord_conv ctxt (earlier vs)))) th
  88.748 +      in rth end
  88.749 +    | ("x+t",[t]) =>
  88.750 +       let
  88.751 +        val T = ctyp_of_term x
  88.752 +        val th = instantiate' [SOME T] [SOME x, SOME t] @{thm "sum_le"}
  88.753 +        val rth = Conv.fconv_rule (Conv.arg_conv (Conv.binop_conv
  88.754 +              (Normalizer.semiring_normalize_ord_conv ctxt (earlier vs)))) th
  88.755 +       in  rth end
  88.756 +    | ("c*x",[c]) =>
  88.757 +       let
  88.758 +        val T = ctyp_of_term x
  88.759 +        val cr = dest_frac c
  88.760 +        val clt = Drule.cterm_rule (instantiate' [SOME T] []) @{cpat "op <"}
  88.761 +        val cz = Thm.dest_arg ct
  88.762 +        val neg = cr </ Rat.zero
  88.763 +        val cthp = Simplifier.rewrite (local_simpset_of ctxt)
  88.764 +               (Thm.capply @{cterm "Trueprop"}
  88.765 +                  (if neg then Thm.capply (Thm.capply clt c) cz
  88.766 +                    else Thm.capply (Thm.capply clt cz) c))
  88.767 +        val cth = equal_elim (symmetric cthp) TrueI
  88.768 +        val th = implies_elim (instantiate' [SOME (ctyp_of_term x)] (map SOME [c,x])
  88.769 +             (if neg then @{thm neg_prod_le} else @{thm pos_prod_le})) cth
  88.770 +        val rth = th
  88.771 +      in rth end
  88.772 +    | _ => reflexive ct)
  88.773 +
  88.774 +|  Const("op =",_)$_$Const(@{const_name "HOL.zero"},_) =>
  88.775 +   (case whatis x (Thm.dest_arg1 ct) of
  88.776 +    ("c*x+t",[c,t]) =>
  88.777 +       let
  88.778 +        val T = ctyp_of_term x
  88.779 +        val cr = dest_frac c
  88.780 +        val ceq = Thm.dest_fun2 ct
  88.781 +        val cz = Thm.dest_arg ct
  88.782 +        val cthp = Simplifier.rewrite (local_simpset_of ctxt)
  88.783 +            (Thm.capply @{cterm "Trueprop"}
  88.784 +             (Thm.capply @{cterm "Not"} (Thm.capply (Thm.capply ceq c) cz)))
  88.785 +        val cth = equal_elim (symmetric cthp) TrueI
  88.786 +        val th = implies_elim
  88.787 +                 (instantiate' [SOME T] (map SOME [c,x,t]) @{thm nz_prod_sum_eq}) cth
  88.788 +        val rth = Conv.fconv_rule (Conv.arg_conv (Conv.binop_conv
  88.789 +                   (Normalizer.semiring_normalize_ord_conv ctxt (earlier vs)))) th
  88.790 +      in rth end
  88.791 +    | ("x+t",[t]) =>
  88.792 +       let
  88.793 +        val T = ctyp_of_term x
  88.794 +        val th = instantiate' [SOME T] [SOME x, SOME t] @{thm "sum_eq"}
  88.795 +        val rth = Conv.fconv_rule (Conv.arg_conv (Conv.binop_conv
  88.796 +              (Normalizer.semiring_normalize_ord_conv ctxt (earlier vs)))) th
  88.797 +       in  rth end
  88.798 +    | ("c*x",[c]) =>
  88.799 +       let
  88.800 +        val T = ctyp_of_term x
  88.801 +        val cr = dest_frac c
  88.802 +        val ceq = Thm.dest_fun2 ct
  88.803 +        val cz = Thm.dest_arg ct
  88.804 +        val cthp = Simplifier.rewrite (local_simpset_of ctxt)
  88.805 +            (Thm.capply @{cterm "Trueprop"}
  88.806 +             (Thm.capply @{cterm "Not"} (Thm.capply (Thm.capply ceq c) cz)))
  88.807 +        val cth = equal_elim (symmetric cthp) TrueI
  88.808 +        val rth = implies_elim
  88.809 +                 (instantiate' [SOME T] (map SOME [c,x]) @{thm nz_prod_eq}) cth
  88.810 +      in rth end
  88.811 +    | _ => reflexive ct);
  88.812 +
  88.813 +local
  88.814 +  val less_iff_diff_less_0 = mk_meta_eq @{thm "less_iff_diff_less_0"}
  88.815 +  val le_iff_diff_le_0 = mk_meta_eq @{thm "le_iff_diff_le_0"}
  88.816 +  val eq_iff_diff_eq_0 = mk_meta_eq @{thm "eq_iff_diff_eq_0"}
  88.817 +in
  88.818 +fun field_isolate_conv phi ctxt vs ct = case term_of ct of
  88.819 +  Const(@{const_name HOL.less},_)$a$b =>
  88.820 +   let val (ca,cb) = Thm.dest_binop ct
  88.821 +       val T = ctyp_of_term ca
  88.822 +       val th = instantiate' [SOME T] [SOME ca, SOME cb] less_iff_diff_less_0
  88.823 +       val nth = Conv.fconv_rule
  88.824 +         (Conv.arg_conv (Conv.arg1_conv
  88.825 +              (Normalizer.semiring_normalize_ord_conv @{context} (earlier vs)))) th
  88.826 +       val rth = transitive nth (xnormalize_conv ctxt vs (Thm.rhs_of nth))
  88.827 +   in rth end
  88.828 +| Const(@{const_name HOL.less_eq},_)$a$b =>
  88.829 +   let val (ca,cb) = Thm.dest_binop ct
  88.830 +       val T = ctyp_of_term ca
  88.831 +       val th = instantiate' [SOME T] [SOME ca, SOME cb] le_iff_diff_le_0
  88.832 +       val nth = Conv.fconv_rule
  88.833 +         (Conv.arg_conv (Conv.arg1_conv
  88.834 +              (Normalizer.semiring_normalize_ord_conv @{context} (earlier vs)))) th
  88.835 +       val rth = transitive nth (xnormalize_conv ctxt vs (Thm.rhs_of nth))
  88.836 +   in rth end
  88.837 +
  88.838 +| Const("op =",_)$a$b =>
  88.839 +   let val (ca,cb) = Thm.dest_binop ct
  88.840 +       val T = ctyp_of_term ca
  88.841 +       val th = instantiate' [SOME T] [SOME ca, SOME cb] eq_iff_diff_eq_0
  88.842 +       val nth = Conv.fconv_rule
  88.843 +         (Conv.arg_conv (Conv.arg1_conv
  88.844 +              (Normalizer.semiring_normalize_ord_conv @{context} (earlier vs)))) th
  88.845 +       val rth = transitive nth (xnormalize_conv ctxt vs (Thm.rhs_of nth))
  88.846 +   in rth end
  88.847 +| @{term "Not"} $(Const("op =",_)$a$b) => Conv.arg_conv (field_isolate_conv phi ctxt vs) ct
  88.848 +| _ => reflexive ct
  88.849 +end;
  88.850 +
  88.851 +fun classfield_whatis phi =
  88.852 + let
  88.853 +  fun h x t =
  88.854 +   case term_of t of
  88.855 +     Const("op =", _)$y$z => if term_of x aconv y then Ferrante_Rackoff_Data.Eq
  88.856 +                            else Ferrante_Rackoff_Data.Nox
  88.857 +   | @{term "Not"}$(Const("op =", _)$y$z) => if term_of x aconv y then Ferrante_Rackoff_Data.NEq
  88.858 +                            else Ferrante_Rackoff_Data.Nox
  88.859 +   | Const(@{const_name HOL.less},_)$y$z =>
  88.860 +       if term_of x aconv y then Ferrante_Rackoff_Data.Lt
  88.861 +        else if term_of x aconv z then Ferrante_Rackoff_Data.Gt
  88.862 +        else Ferrante_Rackoff_Data.Nox
  88.863 +   | Const (@{const_name HOL.less_eq},_)$y$z =>
  88.864 +         if term_of x aconv y then Ferrante_Rackoff_Data.Le
  88.865 +         else if term_of x aconv z then Ferrante_Rackoff_Data.Ge
  88.866 +         else Ferrante_Rackoff_Data.Nox
  88.867 +   | _ => Ferrante_Rackoff_Data.Nox
  88.868 + in h end;
  88.869 +fun class_field_ss phi =
  88.870 +   HOL_basic_ss addsimps ([@{thm "linorder_not_less"}, @{thm "linorder_not_le"}])
  88.871 +   addsplits [@{thm "abs_split"},@{thm "split_max"}, @{thm "split_min"}]
  88.872 +
  88.873 +in
  88.874 +Ferrante_Rackoff_Data.funs @{thm "class_ordered_field_dense_linear_order.ferrack_axiom"}
  88.875 +  {isolate_conv = field_isolate_conv, whatis = classfield_whatis, simpset = class_field_ss}
  88.876 +end
  88.877 +*}
  88.878 +
  88.879 +
  88.880 +end 
    89.1 --- a/src/HOL/Deriv.thy	Tue Dec 30 08:18:54 2008 +0100
    89.2 +++ b/src/HOL/Deriv.thy	Tue Dec 30 11:10:01 2008 +0100
    89.3 @@ -20,12 +20,6 @@
    89.4            ("(DERIV (_)/ (_)/ :> (_))" [1000, 1000, 60] 60) where
    89.5    "DERIV f x :> D = ((%h. (f(x + h) - f x) / h) -- 0 --> D)"
    89.6  
    89.7 -definition
    89.8 -  differentiable :: "['a::real_normed_field \<Rightarrow> 'a, 'a] \<Rightarrow> bool"
    89.9 -    (infixl "differentiable" 60) where
   89.10 -  "f differentiable x = (\<exists>D. DERIV f x :> D)"
   89.11 -
   89.12 -
   89.13  consts
   89.14    Bolzano_bisect :: "[real*real=>bool, real, real, nat] => (real*real)"
   89.15  primrec
   89.16 @@ -316,63 +310,104 @@
   89.17  
   89.18  subsection {* Differentiability predicate *}
   89.19  
   89.20 +definition
   89.21 +  differentiable :: "['a::real_normed_field \<Rightarrow> 'a, 'a] \<Rightarrow> bool"
   89.22 +    (infixl "differentiable" 60) where
   89.23 +  "f differentiable x = (\<exists>D. DERIV f x :> D)"
   89.24 +
   89.25 +lemma differentiableE [elim?]:
   89.26 +  assumes "f differentiable x"
   89.27 +  obtains df where "DERIV f x :> df"
   89.28 +  using prems unfolding differentiable_def ..
   89.29 +
   89.30  lemma differentiableD: "f differentiable x ==> \<exists>D. DERIV f x :> D"
   89.31  by (simp add: differentiable_def)
   89.32  
   89.33  lemma differentiableI: "DERIV f x :> D ==> f differentiable x"
   89.34  by (force simp add: differentiable_def)
   89.35  
   89.36 -lemma differentiable_const: "(\<lambda>z. a) differentiable x"
   89.37 -  apply (unfold differentiable_def)
   89.38 -  apply (rule_tac x=0 in exI)
   89.39 -  apply simp
   89.40 -  done
   89.41 +lemma differentiable_ident [simp]: "(\<lambda>x. x) differentiable x"
   89.42 +  by (rule DERIV_ident [THEN differentiableI])
   89.43  
   89.44 -lemma differentiable_sum:
   89.45 +lemma differentiable_const [simp]: "(\<lambda>z. a) differentiable x"
   89.46 +  by (rule DERIV_const [THEN differentiableI])
   89.47 +
   89.48 +lemma differentiable_compose:
   89.49 +  assumes f: "f differentiable (g x)"
   89.50 +  assumes g: "g differentiable x"
   89.51 +  shows "(\<lambda>x. f (g x)) differentiable x"
   89.52 +proof -
   89.53 +  from `f differentiable (g x)` obtain df where "DERIV f (g x) :> df" ..
   89.54 +  moreover
   89.55 +  from `g differentiable x` obtain dg where "DERIV g x :> dg" ..
   89.56 +  ultimately
   89.57 +  have "DERIV (\<lambda>x. f (g x)) x :> df * dg" by (rule DERIV_chain2)
   89.58 +  thus ?thesis by (rule differentiableI)
   89.59 +qed
   89.60 +
   89.61 +lemma differentiable_sum [simp]:
   89.62    assumes "f differentiable x"
   89.63    and "g differentiable x"
   89.64    shows "(\<lambda>x. f x + g x) differentiable x"
   89.65  proof -
   89.66 -  from prems have "\<exists>D. DERIV f x :> D" by (unfold differentiable_def)
   89.67 -  then obtain df where "DERIV f x :> df" ..
   89.68 -  moreover from prems have "\<exists>D. DERIV g x :> D" by (unfold differentiable_def)
   89.69 -  then obtain dg where "DERIV g x :> dg" ..
   89.70 -  ultimately have "DERIV (\<lambda>x. f x + g x) x :> df + dg" by (rule DERIV_add)
   89.71 -  hence "\<exists>D. DERIV (\<lambda>x. f x + g x) x :> D" by auto
   89.72 -  thus ?thesis by (fold differentiable_def)
   89.73 +  from `f differentiable x` obtain df where "DERIV f x :> df" ..
   89.74 +  moreover
   89.75 +  from `g differentiable x` obtain dg where "DERIV g x :> dg" ..
   89.76 +  ultimately
   89.77 +  have "DERIV (\<lambda>x. f x + g x) x :> df + dg" by (rule DERIV_add)
   89.78 +  thus ?thesis by (rule differentiableI)
   89.79  qed
   89.80  
   89.81 -lemma differentiable_diff:
   89.82 +lemma differentiable_minus [simp]:
   89.83    assumes "f differentiable x"
   89.84 -  and "g differentiable x"
   89.85 -  shows "(\<lambda>x. f x - g x) differentiable x"
   89.86 +  shows "(\<lambda>x. - f x) differentiable x"
   89.87  proof -
   89.88 -  from prems have "f differentiable x" by simp
   89.89 -  moreover
   89.90 -  from prems have "\<exists>D. DERIV g x :> D" by (unfold differentiable_def)
   89.91 -  then obtain dg where "DERIV g x :> dg" ..
   89.92 -  then have "DERIV (\<lambda>x. - g x) x :> -dg" by (rule DERIV_minus)
   89.93 -  hence "\<exists>D. DERIV (\<lambda>x. - g x) x :> D" by auto
   89.94 -  hence "(\<lambda>x. - g x) differentiable x" by (fold differentiable_def)
   89.95 -  ultimately 
   89.96 -  show ?thesis
   89.97 -    by (auto simp: diff_def dest: differentiable_sum)
   89.98 +  from `f differentiable x` obtain df where "DERIV f x :> df" ..
   89.99 +  hence "DERIV (\<lambda>x. - f x) x :> - df" by (rule DERIV_minus)
  89.100 +  thus ?thesis by (rule differentiableI)
  89.101  qed
  89.102  
  89.103 -lemma differentiable_mult:
  89.104 +lemma differentiable_diff [simp]:
  89.105    assumes "f differentiable x"
  89.106 -  and "g differentiable x"
  89.107 +  assumes "g differentiable x"
  89.108 +  shows "(\<lambda>x. f x - g x) differentiable x"
  89.109 +  unfolding diff_minus using prems by simp
  89.110 +
  89.111 +lemma differentiable_mult [simp]:
  89.112 +  assumes "f differentiable x"
  89.113 +  assumes "g differentiable x"
  89.114    shows "(\<lambda>x. f x * g x) differentiable x"
  89.115  proof -
  89.116 -  from prems have "\<exists>D. DERIV f x :> D" by (unfold differentiable_def)
  89.117 -  then obtain df where "DERIV f x :> df" ..
  89.118 -  moreover from prems have "\<exists>D. DERIV g x :> D" by (unfold differentiable_def)
  89.119 -  then obtain dg where "DERIV g x :> dg" ..
  89.120 -  ultimately have "DERIV (\<lambda>x. f x * g x) x :> df * g x + dg * f x" by (simp add: DERIV_mult)
  89.121 -  hence "\<exists>D. DERIV (\<lambda>x. f x * g x) x :> D" by auto
  89.122 -  thus ?thesis by (fold differentiable_def)
  89.123 +  from `f differentiable x` obtain df where "DERIV f x :> df" ..
  89.124 +  moreover
  89.125 +  from `g differentiable x` obtain dg where "DERIV g x :> dg" ..
  89.126 +  ultimately
  89.127 +  have "DERIV (\<lambda>x. f x * g x) x :> df * g x + dg * f x" by (rule DERIV_mult)
  89.128 +  thus ?thesis by (rule differentiableI)
  89.129  qed
  89.130  
  89.131 +lemma differentiable_inverse [simp]:
  89.132 +  assumes "f differentiable x" and "f x \<noteq> 0"
  89.133 +  shows "(\<lambda>x. inverse (f x)) differentiable x"
  89.134 +proof -
  89.135 +  from `f differentiable x` obtain df where "DERIV f x :> df" ..
  89.136 +  hence "DERIV (\<lambda>x. inverse (f x)) x :> - (inverse (f x) * df * inverse (f x))"
  89.137 +    using `f x \<noteq> 0` by (rule DERIV_inverse')
  89.138 +  thus ?thesis by (rule differentiableI)
  89.139 +qed
  89.140 +
  89.141 +lemma differentiable_divide [simp]:
  89.142 +  assumes "f differentiable x"
  89.143 +  assumes "g differentiable x" and "g x \<noteq> 0"
  89.144 +  shows "(\<lambda>x. f x / g x) differentiable x"
  89.145 +  unfolding divide_inverse using prems by simp
  89.146 +
  89.147 +lemma differentiable_power [simp]:
  89.148 +  fixes f :: "'a::{recpower,real_normed_field} \<Rightarrow> 'a"
  89.149 +  assumes "f differentiable x"
  89.150 +  shows "(\<lambda>x. f x ^ n) differentiable x"
  89.151 +  by (induct n, simp, simp add: power_Suc prems)
  89.152 +
  89.153  
  89.154  subsection {* Nested Intervals and Bisection *}
  89.155  
  89.156 @@ -1722,4 +1757,60 @@
  89.157  apply (simp add: poly_entire del: pmult_Cons)
  89.158  done
  89.159  
  89.160 +
  89.161 +subsection {* Theorems about Limits *}
  89.162 +
  89.163 +(* need to rename second isCont_inverse *)
  89.164 +
  89.165 +lemma isCont_inv_fun:
  89.166 +  fixes f g :: "real \<Rightarrow> real"
  89.167 +  shows "[| 0 < d; \<forall>z. \<bar>z - x\<bar> \<le> d --> g(f(z)) = z;  
  89.168 +         \<forall>z. \<bar>z - x\<bar> \<le> d --> isCont f z |]  
  89.169 +      ==> isCont g (f x)"
  89.170 +by (rule isCont_inverse_function)
  89.171 +
  89.172 +lemma isCont_inv_fun_inv:
  89.173 +  fixes f g :: "real \<Rightarrow> real"
  89.174 +  shows "[| 0 < d;  
  89.175 +         \<forall>z. \<bar>z - x\<bar> \<le> d --> g(f(z)) = z;  
  89.176 +         \<forall>z. \<bar>z - x\<bar> \<le> d --> isCont f z |]  
  89.177 +       ==> \<exists>e. 0 < e &  
  89.178 +             (\<forall>y. 0 < \<bar>y - f(x)\<bar> & \<bar>y - f(x)\<bar> < e --> f(g(y)) = y)"
  89.179 +apply (drule isCont_inj_range)
  89.180 +prefer 2 apply (assumption, assumption, auto)
  89.181 +apply (rule_tac x = e in exI, auto)
  89.182 +apply (rotate_tac 2)
  89.183 +apply (drule_tac x = y in spec, auto)
  89.184 +done
  89.185 +
  89.186 +
  89.187 +text{*Bartle/Sherbert: Introduction to Real Analysis, Theorem 4.2.9, p. 110*}
  89.188 +lemma LIM_fun_gt_zero:
  89.189 +     "[| f -- c --> (l::real); 0 < l |]  
  89.190 +         ==> \<exists>r. 0 < r & (\<forall>x::real. x \<noteq> c & \<bar>c - x\<bar> < r --> 0 < f x)"
  89.191 +apply (auto simp add: LIM_def)
  89.192 +apply (drule_tac x = "l/2" in spec, safe, force)
  89.193 +apply (rule_tac x = s in exI)
  89.194 +apply (auto simp only: abs_less_iff)
  89.195 +done
  89.196 +
  89.197 +lemma LIM_fun_less_zero:
  89.198 +     "[| f -- c --> (l::real); l < 0 |]  
  89.199 +      ==> \<exists>r. 0 < r & (\<forall>x::real. x \<noteq> c & \<bar>c - x\<bar> < r --> f x < 0)"
  89.200 +apply (auto simp add: LIM_def)
  89.201 +apply (drule_tac x = "-l/2" in spec, safe, force)
  89.202 +apply (rule_tac x = s in exI)
  89.203 +apply (auto simp only: abs_less_iff)
  89.204 +done
  89.205 +
  89.206 +
  89.207 +lemma LIM_fun_not_zero:
  89.208 +     "[| f -- c --> (l::real); l \<noteq> 0 |] 
  89.209 +      ==> \<exists>r. 0 < r & (\<forall>x::real. x \<noteq> c & \<bar>c - x\<bar> < r --> f x \<noteq> 0)"
  89.210 +apply (cut_tac x = l and y = 0 in linorder_less_linear, auto)
  89.211 +apply (drule LIM_fun_less_zero)
  89.212 +apply (drule_tac [3] LIM_fun_gt_zero)
  89.213 +apply force+
  89.214 +done
  89.215 +
  89.216  end
    90.1 --- a/src/HOL/Divides.thy	Tue Dec 30 08:18:54 2008 +0100
    90.2 +++ b/src/HOL/Divides.thy	Tue Dec 30 11:10:01 2008 +0100
    90.3 @@ -127,7 +127,7 @@
    90.4    note that ultimately show thesis by blast
    90.5  qed
    90.6  
    90.7 -lemma dvd_eq_mod_eq_0 [code]: "a dvd b \<longleftrightarrow> b mod a = 0"
    90.8 +lemma dvd_eq_mod_eq_0 [code unfold]: "a dvd b \<longleftrightarrow> b mod a = 0"
    90.9  proof
   90.10    assume "b mod a = 0"
   90.11    with mod_div_equality [of b a] have "b div a * a = b" by simp
    91.1 --- a/src/HOL/FunDef.thy	Tue Dec 30 08:18:54 2008 +0100
    91.2 +++ b/src/HOL/FunDef.thy	Tue Dec 30 11:10:01 2008 +0100
    91.3 @@ -3,11 +3,13 @@
    91.4      Author:     Alexander Krauss, TU Muenchen
    91.5  *)
    91.6  
    91.7 -header {* General recursive function definitions *}
    91.8 +header {* Function Definitions and Termination Proofs *}
    91.9  
   91.10  theory FunDef
   91.11  imports Wellfounded
   91.12  uses
   91.13 +  "Tools/prop_logic.ML"
   91.14 +  "Tools/sat_solver.ML"
   91.15    ("Tools/function_package/fundef_lib.ML")
   91.16    ("Tools/function_package/fundef_common.ML")
   91.17    ("Tools/function_package/inductive_wrap.ML")
   91.18 @@ -22,9 +24,14 @@
   91.19    ("Tools/function_package/lexicographic_order.ML")
   91.20    ("Tools/function_package/fundef_datatype.ML")
   91.21    ("Tools/function_package/induction_scheme.ML")
   91.22 +  ("Tools/function_package/termination.ML")
   91.23 +  ("Tools/function_package/decompose.ML")
   91.24 +  ("Tools/function_package/descent.ML")
   91.25 +  ("Tools/function_package/scnp_solve.ML")
   91.26 +  ("Tools/function_package/scnp_reconstruct.ML")
   91.27  begin
   91.28  
   91.29 -text {* Definitions with default value. *}
   91.30 +subsection {* Definitions with default value. *}
   91.31  
   91.32  definition
   91.33    THE_default :: "'a \<Rightarrow> ('a \<Rightarrow> bool) \<Rightarrow> 'a" where
   91.34 @@ -97,9 +104,6 @@
   91.35    "wf R \<Longrightarrow> wfP (in_rel R)"
   91.36    by (simp add: wfP_def)
   91.37  
   91.38 -inductive is_measure :: "('a \<Rightarrow> nat) \<Rightarrow> bool"
   91.39 -where is_measure_trivial: "is_measure f"
   91.40 -
   91.41  use "Tools/function_package/fundef_lib.ML"
   91.42  use "Tools/function_package/fundef_common.ML"
   91.43  use "Tools/function_package/inductive_wrap.ML"
   91.44 @@ -110,19 +114,37 @@
   91.45  use "Tools/function_package/pattern_split.ML"
   91.46  use "Tools/function_package/auto_term.ML"
   91.47  use "Tools/function_package/fundef_package.ML"
   91.48 -use "Tools/function_package/measure_functions.ML"
   91.49 -use "Tools/function_package/lexicographic_order.ML"
   91.50  use "Tools/function_package/fundef_datatype.ML"
   91.51  use "Tools/function_package/induction_scheme.ML"
   91.52  
   91.53  setup {* 
   91.54    FundefPackage.setup 
   91.55 +  #> FundefDatatype.setup
   91.56    #> InductionScheme.setup
   91.57 -  #> MeasureFunctions.setup
   91.58 -  #> LexicographicOrder.setup 
   91.59 -  #> FundefDatatype.setup
   91.60  *}
   91.61  
   91.62 +subsection {* Measure Functions *}
   91.63 +
   91.64 +inductive is_measure :: "('a \<Rightarrow> nat) \<Rightarrow> bool"
   91.65 +where is_measure_trivial: "is_measure f"
   91.66 +
   91.67 +use "Tools/function_package/measure_functions.ML"
   91.68 +setup MeasureFunctions.setup
   91.69 +
   91.70 +lemma measure_size[measure_function]: "is_measure size"
   91.71 +by (rule is_measure_trivial)
   91.72 +
   91.73 +lemma measure_fst[measure_function]: "is_measure f \<Longrightarrow> is_measure (\<lambda>p. f (fst p))"
   91.74 +by (rule is_measure_trivial)
   91.75 +lemma measure_snd[measure_function]: "is_measure f \<Longrightarrow> is_measure (\<lambda>p. f (snd p))"
   91.76 +by (rule is_measure_trivial)
   91.77 +
   91.78 +use "Tools/function_package/lexicographic_order.ML"
   91.79 +setup LexicographicOrder.setup 
   91.80 +
   91.81 +
   91.82 +subsection {* Congruence Rules *}
   91.83 +
   91.84  lemma let_cong [fundef_cong]:
   91.85    "M = N \<Longrightarrow> (\<And>x. x = N \<Longrightarrow> f x = g x) \<Longrightarrow> Let M f = Let N g"
   91.86    unfolding Let_def by blast
   91.87 @@ -140,17 +162,7 @@
   91.88    "f (g x) = f' (g' x') \<Longrightarrow> (f o g) x = (f' o g') x'"
   91.89    unfolding o_apply .
   91.90  
   91.91 -subsection {* Setup for termination proofs *}
   91.92 -
   91.93 -text {* Rules for generating measure functions *}
   91.94 -
   91.95 -lemma [measure_function]: "is_measure size"
   91.96 -by (rule is_measure_trivial)
   91.97 -
   91.98 -lemma [measure_function]: "is_measure f \<Longrightarrow> is_measure (\<lambda>p. f (fst p))"
   91.99 -by (rule is_measure_trivial)
  91.100 -lemma [measure_function]: "is_measure f \<Longrightarrow> is_measure (\<lambda>p. f (snd p))"
  91.101 -by (rule is_measure_trivial)
  91.102 +subsection {* Simp rules for termination proofs *}
  91.103  
  91.104  lemma termination_basic_simps[termination_simp]:
  91.105    "x < (y::nat) \<Longrightarrow> x < y + z" 
  91.106 @@ -166,5 +178,150 @@
  91.107    "prod_size f g p = f (fst p) + g (snd p) + Suc 0"
  91.108  by (induct p) auto
  91.109  
  91.110 +subsection {* Decomposition *}
  91.111 +
  91.112 +lemma less_by_empty: 
  91.113 +  "A = {} \<Longrightarrow> A \<subseteq> B"
  91.114 +and  union_comp_emptyL:
  91.115 +  "\<lbrakk> A O C = {}; B O C = {} \<rbrakk> \<Longrightarrow> (A \<union> B) O C = {}"
  91.116 +and union_comp_emptyR:
  91.117 +  "\<lbrakk> A O B = {}; A O C = {} \<rbrakk> \<Longrightarrow> A O (B \<union> C) = {}"
  91.118 +and wf_no_loop: 
  91.119 +  "R O R = {} \<Longrightarrow> wf R"
  91.120 +by (auto simp add: wf_comp_self[of R])
  91.121 +
  91.122 +
  91.123 +subsection {* Reduction Pairs *}
  91.124 +
  91.125 +definition
  91.126 +  "reduction_pair P = (wf (fst P) \<and> snd P O fst P \<subseteq> fst P)"
  91.127 +
  91.128 +lemma reduction_pairI[intro]: "wf R \<Longrightarrow> S O R \<subseteq> R \<Longrightarrow> reduction_pair (R, S)"
  91.129 +unfolding reduction_pair_def by auto
  91.130 +
  91.131 +lemma reduction_pair_lemma:
  91.132 +  assumes rp: "reduction_pair P"
  91.133 +  assumes "R \<subseteq> fst P"
  91.134 +  assumes "S \<subseteq> snd P"
  91.135 +  assumes "wf S"
  91.136 +  shows "wf (R \<union> S)"
  91.137 +proof -
  91.138 +  from rp `S \<subseteq> snd P` have "wf (fst P)" "S O fst P \<subseteq> fst P"
  91.139 +    unfolding reduction_pair_def by auto
  91.140 +  with `wf S` have "wf (fst P \<union> S)" 
  91.141 +    by (auto intro: wf_union_compatible)
  91.142 +  moreover from `R \<subseteq> fst P` have "R \<union> S \<subseteq> fst P \<union> S" by auto
  91.143 +  ultimately show ?thesis by (rule wf_subset) 
  91.144 +qed
  91.145 +
  91.146 +definition
  91.147 +  "rp_inv_image = (\<lambda>(R,S) f. (inv_image R f, inv_image S f))"
  91.148 +
  91.149 +lemma rp_inv_image_rp:
  91.150 +  "reduction_pair P \<Longrightarrow> reduction_pair (rp_inv_image P f)"
  91.151 +  unfolding reduction_pair_def rp_inv_image_def split_def
  91.152 +  by force
  91.153 +
  91.154 +
  91.155 +subsection {* Concrete orders for SCNP termination proofs *}
  91.156 +
  91.157 +definition "pair_less = less_than <*lex*> less_than"
  91.158 +definition "pair_leq = pair_less^="
  91.159 +definition "max_strict = max_ext pair_less"
  91.160 +definition "max_weak = max_ext pair_leq \<union> {({}, {})}"
  91.161 +definition "min_strict = min_ext pair_less"
  91.162 +definition "min_weak = min_ext pair_leq \<union> {({}, {})}"
  91.163 +
  91.164 +lemma wf_pair_less[simp]: "wf pair_less"
  91.165 +  by (auto simp: pair_less_def)
  91.166 +
  91.167 +text {* Introduction rules for @{text pair_less}/@{text pair_leq} *}
  91.168 +lemma pair_leqI1: "a < b \<Longrightarrow> ((a, s), (b, t)) \<in> pair_leq"
  91.169 +  and pair_leqI2: "a \<le> b \<Longrightarrow> s \<le> t \<Longrightarrow> ((a, s), (b, t)) \<in> pair_leq"
  91.170 +  and pair_lessI1: "a < b  \<Longrightarrow> ((a, s), (b, t)) \<in> pair_less"
  91.171 +  and pair_lessI2: "a \<le> b \<Longrightarrow> s < t \<Longrightarrow> ((a, s), (b, t)) \<in> pair_less"
  91.172 +  unfolding pair_leq_def pair_less_def by auto
  91.173 +
  91.174 +text {* Introduction rules for max *}
  91.175 +lemma smax_emptyI: 
  91.176 +  "finite Y \<Longrightarrow> Y \<noteq> {} \<Longrightarrow> ({}, Y) \<in> max_strict" 
  91.177 +  and smax_insertI: 
  91.178 +  "\<lbrakk>y \<in> Y; (x, y) \<in> pair_less; (X, Y) \<in> max_strict\<rbrakk> \<Longrightarrow> (insert x X, Y) \<in> max_strict"
  91.179 +  and wmax_emptyI: 
  91.180 +  "finite X \<Longrightarrow> ({}, X) \<in> max_weak" 
  91.181 +  and wmax_insertI:
  91.182 +  "\<lbrakk>y \<in> YS; (x, y) \<in> pair_leq; (XS, YS) \<in> max_weak\<rbrakk> \<Longrightarrow> (insert x XS, YS) \<in> max_weak" 
  91.183 +unfolding max_strict_def max_weak_def by (auto elim!: max_ext.cases)
  91.184 +
  91.185 +text {* Introduction rules for min *}
  91.186 +lemma smin_emptyI: 
  91.187 +  "X \<noteq> {} \<Longrightarrow> (X, {}) \<in> min_strict" 
  91.188 +  and smin_insertI: 
  91.189 +  "\<lbrakk>x \<in> XS; (x, y) \<in> pair_less; (XS, YS) \<in> min_strict\<rbrakk> \<Longrightarrow> (XS, insert y YS) \<in> min_strict"
  91.190 +  and wmin_emptyI: 
  91.191 +  "(X, {}) \<in> min_weak" 
  91.192 +  and wmin_insertI: 
  91.193 +  "\<lbrakk>x \<in> XS; (x, y) \<in> pair_leq; (XS, YS) \<in> min_weak\<rbrakk> \<Longrightarrow> (XS, insert y YS) \<in> min_weak" 
  91.194 +by (auto simp: min_strict_def min_weak_def min_ext_def)
  91.195 +
  91.196 +text {* Reduction Pairs *}
  91.197 +
  91.198 +lemma max_ext_compat: 
  91.199 +  assumes "S O R \<subseteq> R"
  91.200 +  shows "(max_ext S \<union> {({},{})}) O max_ext R \<subseteq> max_ext R"
  91.201 +using assms 
  91.202 +apply auto
  91.203 +apply (elim max_ext.cases)
  91.204 +apply rule
  91.205 +apply auto[3]
  91.206 +apply (drule_tac x=xa in meta_spec)
  91.207 +apply simp
  91.208 +apply (erule bexE)
  91.209 +apply (drule_tac x=xb in meta_spec)
  91.210 +by auto
  91.211 +
  91.212 +lemma max_rpair_set: "reduction_pair (max_strict, max_weak)"
  91.213 +  unfolding max_strict_def max_weak_def 
  91.214 +apply (intro reduction_pairI max_ext_wf)
  91.215 +apply simp
  91.216 +apply (rule max_ext_compat)
  91.217 +by (auto simp: pair_less_def pair_leq_def)
  91.218 +
  91.219 +lemma min_ext_compat: 
  91.220 +  assumes "S O R \<subseteq> R"
  91.221 +  shows "(min_ext S \<union> {({},{})}) O min_ext R \<subseteq> min_ext R"
  91.222 +using assms 
  91.223 +apply (auto simp: min_ext_def)
  91.224 +apply (drule_tac x=ya in bspec, assumption)
  91.225 +apply (erule bexE)
  91.226 +apply (drule_tac x=xc in bspec)
  91.227 +apply assumption
  91.228 +by auto
  91.229 +
  91.230 +lemma min_rpair_set: "reduction_pair (min_strict, min_weak)"
  91.231 +  unfolding min_strict_def min_weak_def 
  91.232 +apply (intro reduction_pairI min_ext_wf)
  91.233 +apply simp
  91.234 +apply (rule min_ext_compat)
  91.235 +by (auto simp: pair_less_def pair_leq_def)
  91.236 +
  91.237 +
  91.238 +subsection {* Tool setup *}
  91.239 +
  91.240 +use "Tools/function_package/termination.ML"
  91.241 +use "Tools/function_package/decompose.ML"
  91.242 +use "Tools/function_package/descent.ML"
  91.243 +use "Tools/function_package/scnp_solve.ML"
  91.244 +use "Tools/function_package/scnp_reconstruct.ML"
  91.245 +
  91.246 +setup {* ScnpReconstruct.setup *}
  91.247 +(*
  91.248 +setup {*
  91.249 +  Context.theory_map (FundefCommon.set_termination_prover (ScnpReconstruct.decomp_scnp 
  91.250 +  [ScnpSolve.MAX, ScnpSolve.MIN, ScnpSolve.MS])) 
  91.251 +*}
  91.252 +*)
  91.253 +
  91.254 +
  91.255  
  91.256  end
    92.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    92.2 +++ b/src/HOL/Fundamental_Theorem_Algebra.thy	Tue Dec 30 11:10:01 2008 +0100
    92.3 @@ -0,0 +1,1327 @@
    92.4 +(* Author: Amine Chaieb, TU Muenchen *)
    92.5 +
    92.6 +header{*Fundamental Theorem of Algebra*}
    92.7 +
    92.8 +theory Fundamental_Theorem_Algebra
    92.9 +imports Univ_Poly Dense_Linear_Order Complex
   92.10 +begin
   92.11 +
   92.12 +subsection {* Square root of complex numbers *}
   92.13 +definition csqrt :: "complex \<Rightarrow> complex" where
   92.14 +"csqrt z = (if Im z = 0 then
   92.15 +            if 0 \<le> Re z then Complex (sqrt(Re z)) 0
   92.16 +            else Complex 0 (sqrt(- Re z))
   92.17 +           else Complex (sqrt((cmod z + Re z) /2))
   92.18 +                        ((Im z / abs(Im z)) * sqrt((cmod z - Re z) /2)))"
   92.19 +
   92.20 +lemma csqrt[algebra]: "csqrt z ^ 2 = z"
   92.21 +proof-
   92.22 +  obtain x y where xy: "z = Complex x y" by (cases z, simp_all)
   92.23 +  {assume y0: "y = 0"
   92.24 +    {assume x0: "x \<ge> 0" 
   92.25 +      then have ?thesis using y0 xy real_sqrt_pow2[OF x0]
   92.26 +	by (simp add: csqrt_def power2_eq_square)}
   92.27 +    moreover
   92.28 +    {assume "\<not> x \<ge> 0" hence x0: "- x \<ge> 0" by arith
   92.29 +      then have ?thesis using y0 xy real_sqrt_pow2[OF x0] 
   92.30 +	by (simp add: csqrt_def power2_eq_square) }
   92.31 +    ultimately have ?thesis by blast}
   92.32 +  moreover
   92.33 +  {assume y0: "y\<noteq>0"
   92.34 +    {fix x y
   92.35 +      let ?z = "Complex x y"
   92.36 +      from abs_Re_le_cmod[of ?z] have tha: "abs x \<le> cmod ?z" by auto
   92.37 +      hence "cmod ?z - x \<ge> 0" "cmod ?z + x \<ge> 0" by arith+ 
   92.38 +      hence "(sqrt (x * x + y * y) + x) / 2 \<ge> 0" "(sqrt (x * x + y * y) - x) / 2 \<ge> 0" by (simp_all add: power2_eq_square) }
   92.39 +    note th = this
   92.40 +    have sq4: "\<And>x::real. x^2 / 4 = (x / 2) ^ 2" 
   92.41 +      by (simp add: power2_eq_square) 
   92.42 +    from th[of x y]
   92.43 +    have sq4': "sqrt (((sqrt (x * x + y * y) + x)^2 / 4)) = (sqrt (x * x + y * y) + x) / 2" "sqrt (((sqrt (x * x + y * y) - x)^2 / 4)) = (sqrt (x * x + y * y) - x) / 2" unfolding sq4 by simp_all
   92.44 +    then have th1: "sqrt ((sqrt (x * x + y * y) + x) * (sqrt (x * x + y * y) + x) / 4) - sqrt ((sqrt (x * x + y * y) - x) * (sqrt (x * x + y * y) - x) / 4) = x"
   92.45 +      unfolding power2_eq_square by simp 
   92.46 +    have "sqrt 4 = sqrt (2^2)" by simp 
   92.47 +    hence sqrt4: "sqrt 4 = 2" by (simp only: real_sqrt_abs)
   92.48 +    have th2: "2 *(y * sqrt ((sqrt (x * x + y * y) - x) * (sqrt (x * x + y * y) + x) / 4)) / \<bar>y\<bar> = y"
   92.49 +      using iffD2[OF real_sqrt_pow2_iff sum_power2_ge_zero[of x y]] y0
   92.50 +      unfolding power2_eq_square 
   92.51 +      by (simp add: ring_simps real_sqrt_divide sqrt4)
   92.52 +     from y0 xy have ?thesis  apply (simp add: csqrt_def power2_eq_square)
   92.53 +       apply (simp add: real_sqrt_sum_squares_mult_ge_zero[of x y] real_sqrt_pow2[OF th(1)[of x y], unfolded power2_eq_square] real_sqrt_pow2[OF th(2)[of x y], unfolded power2_eq_square] real_sqrt_mult[symmetric])
   92.54 +      using th1 th2  ..}
   92.55 +  ultimately show ?thesis by blast
   92.56 +qed
   92.57 +
   92.58 +
   92.59 +subsection{* More lemmas about module of complex numbers *}
   92.60 +
   92.61 +lemma complex_of_real_power: "complex_of_real x ^ n = complex_of_real (x^n)"
   92.62 +  by (rule of_real_power [symmetric])
   92.63 +
   92.64 +lemma real_down2: "(0::real) < d1 \<Longrightarrow> 0 < d2 ==> EX e. 0 < e & e < d1 & e < d2"
   92.65 +  apply ferrack apply arith done
   92.66 +
   92.67 +text{* The triangle inequality for cmod *}
   92.68 +lemma complex_mod_triangle_sub: "cmod w \<le> cmod (w + z) + norm z"
   92.69 +  using complex_mod_triangle_ineq2[of "w + z" "-z"] by auto
   92.70 +
   92.71 +subsection{* Basic lemmas about complex polynomials *}
   92.72 +
   92.73 +lemma poly_bound_exists:
   92.74 +  shows "\<exists>m. m > 0 \<and> (\<forall>z. cmod z <= r \<longrightarrow> cmod (poly p z) \<le> m)"
   92.75 +proof(induct p)
   92.76 +  case Nil thus ?case by (rule exI[where x=1], simp) 
   92.77 +next
   92.78 +  case (Cons c cs)
   92.79 +  from Cons.hyps obtain m where m: "\<forall>z. cmod z \<le> r \<longrightarrow> cmod (poly cs z) \<le> m"
   92.80 +    by blast
   92.81 +  let ?k = " 1 + cmod c + \<bar>r * m\<bar>"
   92.82 +  have kp: "?k > 0" using abs_ge_zero[of "r*m"] norm_ge_zero[of c] by arith
   92.83 +  {fix z
   92.84 +    assume H: "cmod z \<le> r"
   92.85 +    from m H have th: "cmod (poly cs z) \<le> m" by blast
   92.86 +    from H have rp: "r \<ge> 0" using norm_ge_zero[of z] by arith
   92.87 +    have "cmod (poly (c # cs) z) \<le> cmod c + cmod (z* poly cs z)"
   92.88 +      using norm_triangle_ineq[of c "z* poly cs z"] by simp
   92.89 +    also have "\<dots> \<le> cmod c + r*m" using mult_mono[OF H th rp norm_ge_zero[of "poly cs z"]] by (simp add: norm_mult)
   92.90 +    also have "\<dots> \<le> ?k" by simp
   92.91 +    finally have "cmod (poly (c # cs) z) \<le> ?k" .}
   92.92 +  with kp show ?case by blast
   92.93 +qed
   92.94 +
   92.95 +
   92.96 +text{* Offsetting the variable in a polynomial gives another of same degree *}
   92.97 +  (* FIXME : Lemma holds also in locale --- fix it later *)
   92.98 +lemma  poly_offset_lemma:
   92.99 +  shows "\<exists>b q. (length q = length p) \<and> (\<forall>x. poly (b#q) (x::complex) = (a + x) * poly p x)"
  92.100 +proof(induct p)
  92.101 +  case Nil thus ?case by simp
  92.102 +next
  92.103 +  case (Cons c cs)
  92.104 +  from Cons.hyps obtain b q where 
  92.105 +    bq: "length q = length cs" "\<forall>x. poly (b # q) x = (a + x) * poly cs x"
  92.106 +    by blast
  92.107 +  let ?b = "a*c"
  92.108 +  let ?q = "(b+c)#q"
  92.109 +  have lg: "length ?q = length (c#cs)" using bq(1) by simp
  92.110 +  {fix x
  92.111 +    from bq(2)[rule_format, of x]
  92.112 +    have "x*poly (b # q) x = x*((a + x) * poly cs x)" by simp
  92.113 +    hence "poly (?b# ?q) x = (a + x) * poly (c # cs) x"
  92.114 +      by (simp add: ring_simps)}
  92.115 +  with lg  show ?case by blast 
  92.116 +qed
  92.117 +
  92.118 +    (* FIXME : This one too*)
  92.119 +lemma poly_offset: "\<exists> q. length q = length p \<and> (\<forall>x. poly q (x::complex) = poly p (a + x))"
  92.120 +proof (induct p)
  92.121 +  case Nil thus ?case by simp
  92.122 +next
  92.123 +  case (Cons c cs)
  92.124 +  from Cons.hyps obtain q where q: "length q = length cs" "\<forall>x. poly q x = poly cs (a + x)" by blast
  92.125 +  from poly_offset_lemma[of q a] obtain b p where 
  92.126 +    bp: "length p = length q" "\<forall>x. poly (b # p) x = (a + x) * poly q x"
  92.127 +    by blast
  92.128 +  thus ?case using q bp by - (rule exI[where x="(c + b)#p"], simp)
  92.129 +qed
  92.130 +
  92.131 +text{* An alternative useful formulation of completeness of the reals *}
  92.132 +lemma real_sup_exists: assumes ex: "\<exists>x. P x" and bz: "\<exists>z. \<forall>x. P x \<longrightarrow> x < z"
  92.133 +  shows "\<exists>(s::real). \<forall>y. (\<exists>x. P x \<and> y < x) \<longleftrightarrow> y < s"
  92.134 +proof-
  92.135 +  from ex bz obtain x Y where x: "P x" and Y: "\<And>x. P x \<Longrightarrow> x < Y"  by blast
  92.136 +  from ex have thx:"\<exists>x. x \<in> Collect P" by blast
  92.137 +  from bz have thY: "\<exists>Y. isUb UNIV (Collect P) Y" 
  92.138 +    by(auto simp add: isUb_def isLub_def setge_def setle_def leastP_def Ball_def order_le_less)
  92.139 +  from reals_complete[OF thx thY] obtain L where L: "isLub UNIV (Collect P) L"
  92.140 +    by blast
  92.141 +  from Y[OF x] have xY: "x < Y" .
  92.142 +  from L have L': "\<forall>x. P x \<longrightarrow> x \<le> L" by (auto simp add: isUb_def isLub_def setge_def setle_def leastP_def Ball_def)  
  92.143 +  from Y have Y': "\<forall>x. P x \<longrightarrow> x \<le> Y" 
  92.144 +    apply (clarsimp, atomize (full)) by auto 
  92.145 +  from L Y' have "L \<le> Y" by (auto simp add: isUb_def isLub_def setge_def setle_def leastP_def Ball_def)
  92.146 +  {fix y
  92.147 +    {fix z assume z: "P z" "y < z"
  92.148 +      from L' z have "y < L" by auto }
  92.149 +    moreover
  92.150 +    {assume yL: "y < L" "\<forall>z. P z \<longrightarrow> \<not> y < z"
  92.151 +      hence nox: "\<forall>z. P z \<longrightarrow> y \<ge> z" by auto
  92.152 +      from nox L have "y \<ge> L" by (auto simp add: isUb_def isLub_def setge_def setle_def leastP_def Ball_def) 
  92.153 +      with yL(1) have False  by arith}
  92.154 +    ultimately have "(\<exists>x. P x \<and> y < x) \<longleftrightarrow> y < L" by blast}
  92.155 +  thus ?thesis by blast
  92.156 +qed
  92.157 +
  92.158 +
  92.159 +subsection{* Some theorems about Sequences*}
  92.160 +text{* Given a binary function @{text "f:: nat \<Rightarrow> 'a \<Rightarrow> 'a"}, its values are uniquely determined by a function g *}
  92.161 +
  92.162 +lemma num_Axiom: "EX! g. g 0 = e \<and> (\<forall>n. g (Suc n) = f n (g n))"
  92.163 +  unfolding Ex1_def
  92.164 +  apply (rule_tac x="nat_rec e f" in exI)
  92.165 +  apply (rule conjI)+
  92.166 +apply (rule def_nat_rec_0, simp)
  92.167 +apply (rule allI, rule def_nat_rec_Suc, simp)
  92.168 +apply (rule allI, rule impI, rule ext)
  92.169 +apply (erule conjE)
  92.170 +apply (induct_tac x)
  92.171 +apply (simp add: nat_rec_0)
  92.172 +apply (erule_tac x="n" in allE)
  92.173 +apply (simp)
  92.174 +done
  92.175 +
  92.176 + text{* An equivalent formulation of monotony -- Not used here, but might be useful *}
  92.177 +lemma mono_Suc: "mono f = (\<forall>n. (f n :: 'a :: order) \<le> f (Suc n))"
  92.178 +unfolding mono_def
  92.179 +proof auto
  92.180 +  fix A B :: nat
  92.181 +  assume H: "\<forall>n. f n \<le> f (Suc n)" "A \<le> B"
  92.182 +  hence "\<exists>k. B = A + k" apply -  apply (thin_tac "\<forall>n. f n \<le> f (Suc n)") 
  92.183 +    by presburger
  92.184 +  then obtain k where k: "B = A + k" by blast
  92.185 +  {fix a k
  92.186 +    have "f a \<le> f (a + k)"
  92.187 +    proof (induct k)
  92.188 +      case 0 thus ?case by simp
  92.189 +    next
  92.190 +      case (Suc k)
  92.191 +      from Suc.hyps H(1)[rule_format, of "a + k"] show ?case by simp
  92.192 +    qed}
  92.193 +  with k show "f A \<le> f B" by blast
  92.194 +qed
  92.195 +
  92.196 +text{* for any sequence, there is a mootonic subsequence *}
  92.197 +lemma seq_monosub: "\<exists>f. subseq f \<and> monoseq (\<lambda> n. (s (f n)))"
  92.198 +proof-
  92.199 +  {assume H: "\<forall>n. \<exists>p >n. \<forall> m\<ge>p. s m \<le> s p"
  92.200 +    let ?P = "\<lambda> p n. p > n \<and> (\<forall>m \<ge> p. s m \<le> s p)"
  92.201 +    from num_Axiom[of "SOME p. ?P p 0" "\<lambda>p n. SOME p. ?P p n"]
  92.202 +    obtain f where f: "f 0 = (SOME p. ?P p 0)" "\<forall>n. f (Suc n) = (SOME p. ?P p (f n))" by blast
  92.203 +    have "?P (f 0) 0"  unfolding f(1) some_eq_ex[of "\<lambda>p. ?P p 0"]
  92.204 +      using H apply - 
  92.205 +      apply (erule allE[where x=0], erule exE, rule_tac x="p" in exI) 
  92.206 +      unfolding order_le_less by blast 
  92.207 +    hence f0: "f 0 > 0" "\<forall>m \<ge> f 0. s m \<le> s (f 0)" by blast+
  92.208 +    {fix n
  92.209 +      have "?P (f (Suc n)) (f n)" 
  92.210 +	unfolding f(2)[rule_format, of n] some_eq_ex[of "\<lambda>p. ?P p (f n)"]
  92.211 +	using H apply - 
  92.212 +      apply (erule allE[where x="f n"], erule exE, rule_tac x="p" in exI) 
  92.213 +      unfolding order_le_less by blast 
  92.214 +    hence "f (Suc n) > f n" "\<forall>m \<ge> f (Suc n). s m \<le> s (f (Suc n))" by blast+}
  92.215 +  note fSuc = this
  92.216 +    {fix p q assume pq: "p \<ge> f q"
  92.217 +      have "s p \<le> s(f(q))"  using f0(2)[rule_format, of p] pq fSuc
  92.218 +	by (cases q, simp_all) }
  92.219 +    note pqth = this
  92.220 +    {fix q
  92.221 +      have "f (Suc q) > f q" apply (induct q) 
  92.222 +	using f0(1) fSuc(1)[of 0] apply simp by (rule fSuc(1))}
  92.223 +    note fss = this
  92.224 +    from fss have th1: "subseq f" unfolding subseq_Suc_iff ..
  92.225 +    {fix a b 
  92.226 +      have "f a \<le> f (a + b)"
  92.227 +      proof(induct b)
  92.228 +	case 0 thus ?case by simp
  92.229 +      next
  92.230 +	case (Suc b)
  92.231 +	from fSuc(1)[of "a + b"] Suc.hyps show ?case by simp
  92.232 +      qed}
  92.233 +    note fmon0 = this
  92.234 +    have "monoseq (\<lambda>n. s (f n))" 
  92.235 +    proof-
  92.236 +      {fix n
  92.237 +	have "s (f n) \<ge> s (f (Suc n))" 
  92.238 +	proof(cases n)
  92.239 +	  case 0
  92.240 +	  assume n0: "n = 0"
  92.241 +	  from fSuc(1)[of 0] have th0: "f 0 \<le> f (Suc 0)" by simp
  92.242 +	  from f0(2)[rule_format, OF th0] show ?thesis  using n0 by simp
  92.243 +	next
  92.244 +	  case (Suc m)
  92.245 +	  assume m: "n = Suc m"
  92.246 +	  from fSuc(1)[of n] m have th0: "f (Suc m) \<le> f (Suc (Suc m))" by simp
  92.247 +	  from m fSuc(2)[rule_format, OF th0] show ?thesis by simp 
  92.248 +	qed}
  92.249 +      thus "monoseq (\<lambda>n. s (f n))" unfolding monoseq_Suc by blast 
  92.250 +    qed
  92.251 +    with th1 have ?thesis by blast}
  92.252 +  moreover
  92.253 +  {fix N assume N: "\<forall>p >N. \<exists> m\<ge>p. s m > s p"
  92.254 +    {fix p assume p: "p \<ge> Suc N" 
  92.255 +      hence pN: "p > N" by arith with N obtain m where m: "m \<ge> p" "s m > s p" by blast
  92.256 +      have "m \<noteq> p" using m(2) by auto 
  92.257 +      with m have "\<exists>m>p. s p < s m" by - (rule exI[where x=m], auto)}
  92.258 +    note th0 = this
  92.259 +    let ?P = "\<lambda>m x. m > x \<and> s x < s m"
  92.260 +    from num_Axiom[of "SOME x. ?P x (Suc N)" "\<lambda>m x. SOME y. ?P y x"]
  92.261 +    obtain f where f: "f 0 = (SOME x. ?P x (Suc N))" 
  92.262 +      "\<forall>n. f (Suc n) = (SOME m. ?P m (f n))" by blast
  92.263 +    have "?P (f 0) (Suc N)"  unfolding f(1) some_eq_ex[of "\<lambda>p. ?P p (Suc N)"]
  92.264 +      using N apply - 
  92.265 +      apply (erule allE[where x="Suc N"], clarsimp)
  92.266 +      apply (rule_tac x="m" in exI)
  92.267 +      apply auto
  92.268 +      apply (subgoal_tac "Suc N \<noteq> m")
  92.269 +      apply simp
  92.270 +      apply (rule ccontr, simp)
  92.271 +      done
  92.272 +    hence f0: "f 0 > Suc N" "s (Suc N) < s (f 0)" by blast+
  92.273 +    {fix n
  92.274 +      have "f n > N \<and> ?P (f (Suc n)) (f n)"
  92.275 +	unfolding f(2)[rule_format, of n] some_eq_ex[of "\<lambda>p. ?P p (f n)"]
  92.276 +      proof (induct n)
  92.277 +	case 0 thus ?case
  92.278 +	  using f0 N apply auto 
  92.279 +	  apply (erule allE[where x="f 0"], clarsimp) 
  92.280 +	  apply (rule_tac x="m" in exI, simp)
  92.281 +	  by (subgoal_tac "f 0 \<noteq> m", auto)
  92.282 +      next
  92.283 +	case (Suc n)
  92.284 +	from Suc.hyps have Nfn: "N < f n" by blast
  92.285 +	from Suc.hyps obtain m where m: "m > f n" "s (f n) < s m" by blast
  92.286 +	with Nfn have mN: "m > N" by arith
  92.287 +	note key = Suc.hyps[unfolded some_eq_ex[of "\<lambda>p. ?P p (f n)", symmetric] f(2)[rule_format, of n, symmetric]]
  92.288 +	
  92.289 +	from key have th0: "f (Suc n) > N" by simp
  92.290 +	from N[rule_format, OF th0]
  92.291 +	obtain m' where m': "m' \<ge> f (Suc n)" "s (f (Suc n)) < s m'" by blast
  92.292 +	have "m' \<noteq> f (Suc (n))" apply (rule ccontr) using m'(2) by auto
  92.293 +	hence "m' > f (Suc n)" using m'(1) by simp
  92.294 +	with key m'(2) show ?case by auto
  92.295 +      qed}
  92.296 +    note fSuc = this
  92.297 +    {fix n
  92.298 +      have "f n \<ge> Suc N \<and> f(Suc n) > f n \<and> s(f n) < s(f(Suc n))" using fSuc[of n] by auto 
  92.299 +      hence "f n \<ge> Suc N" "f(Suc n) > f n" "s(f n) < s(f(Suc n))" by blast+}
  92.300 +    note thf = this
  92.301 +    have sqf: "subseq f" unfolding subseq_Suc_iff using thf by simp
  92.302 +    have "monoseq (\<lambda>n. s (f n))"  unfolding monoseq_Suc using thf
  92.303 +      apply -
  92.304 +      apply (rule disjI1)
  92.305 +      apply auto
  92.306 +      apply (rule order_less_imp_le)
  92.307 +      apply blast
  92.308 +      done
  92.309 +    then have ?thesis  using sqf by blast}
  92.310 +  ultimately show ?thesis unfolding linorder_not_less[symmetric] by blast
  92.311 +qed
  92.312 +
  92.313 +lemma seq_suble: assumes sf: "subseq f" shows "n \<le> f n"
  92.314 +proof(induct n)
  92.315 +  case 0 thus ?case by simp
  92.316 +next
  92.317 +  case (Suc n)
  92.318 +  from sf[unfolded subseq_Suc_iff, rule_format, of n] Suc.hyps
  92.319 +  have "n < f (Suc n)" by arith 
  92.320 +  thus ?case by arith
  92.321 +qed
  92.322 +
  92.323 +subsection {* Fundamental theorem of algebra *}
  92.324 +lemma  unimodular_reduce_norm:
  92.325 +  assumes md: "cmod z = 1"
  92.326 +  shows "cmod (z + 1) < 1 \<or> cmod (z - 1) < 1 \<or> cmod (z + ii) < 1 \<or> cmod (z - ii) < 1"
  92.327 +proof-
  92.328 +  obtain x y where z: "z = Complex x y " by (cases z, auto)
  92.329 +  from md z have xy: "x^2 + y^2 = 1" by (simp add: cmod_def)
  92.330 +  {assume C: "cmod (z + 1) \<ge> 1" "cmod (z - 1) \<ge> 1" "cmod (z + ii) \<ge> 1" "cmod (z - ii) \<ge> 1"
  92.331 +    from C z xy have "2*x \<le> 1" "2*x \<ge> -1" "2*y \<le> 1" "2*y \<ge> -1"
  92.332 +      by (simp_all add: cmod_def power2_eq_square ring_simps)
  92.333 +    hence "abs (2*x) \<le> 1" "abs (2*y) \<le> 1" by simp_all
  92.334 +    hence "(abs (2 * x))^2 <= 1^2" "(abs (2 * y)) ^2 <= 1^2"
  92.335 +      by - (rule power_mono, simp, simp)+
  92.336 +    hence th0: "4*x^2 \<le> 1" "4*y^2 \<le> 1" 
  92.337 +      by (simp_all  add: power2_abs power_mult_distrib)
  92.338 +    from add_mono[OF th0] xy have False by simp }
  92.339 +  thus ?thesis unfolding linorder_not_le[symmetric] by blast
  92.340 +qed
  92.341 +
  92.342 +text{* Hence we can always reduce modulus of @{text "1 + b z^n"} if nonzero *}
  92.343 +lemma reduce_poly_simple:
  92.344 + assumes b: "b \<noteq> 0" and n: "n\<noteq>0"
  92.345 +  shows "\<exists>z. cmod (1 + b * z^n) < 1"
  92.346 +using n
  92.347 +proof(induct n rule: nat_less_induct)
  92.348 +  fix n
  92.349 +  assume IH: "\<forall>m<n. m \<noteq> 0 \<longrightarrow> (\<exists>z. cmod (1 + b * z ^ m) < 1)" and n: "n \<noteq> 0"
  92.350 +  let ?P = "\<lambda>z n. cmod (1 + b * z ^ n) < 1"
  92.351 +  {assume e: "even n"
  92.352 +    hence "\<exists>m. n = 2*m" by presburger
  92.353 +    then obtain m where m: "n = 2*m" by blast
  92.354 +    from n m have "m\<noteq>0" "m < n" by presburger+
  92.355 +    with IH[rule_format, of m] obtain z where z: "?P z m" by blast
  92.356 +    from z have "?P (csqrt z) n" by (simp add: m power_mult csqrt)
  92.357 +    hence "\<exists>z. ?P z n" ..}
  92.358 +  moreover
  92.359 +  {assume o: "odd n"
  92.360 +    from b have b': "b^2 \<noteq> 0" unfolding power2_eq_square by simp
  92.361 +    have "Im (inverse b) * (Im (inverse b) * \<bar>Im b * Im b + Re b * Re b\<bar>) +
  92.362 +    Re (inverse b) * (Re (inverse b) * \<bar>Im b * Im b + Re b * Re b\<bar>) = 
  92.363 +    ((Re (inverse b))^2 + (Im (inverse b))^2) * \<bar>Im b * Im b + Re b * Re b\<bar>" by algebra
  92.364 +    also have "\<dots> = cmod (inverse b) ^2 * cmod b ^ 2" 
  92.365 +      apply (simp add: cmod_def) using realpow_two_le_add_order[of "Re b" "Im b"]
  92.366 +      by (simp add: power2_eq_square)
  92.367 +    finally 
  92.368 +    have th0: "Im (inverse b) * (Im (inverse b) * \<bar>Im b * Im b + Re b * Re b\<bar>) +
  92.369 +    Re (inverse b) * (Re (inverse b) * \<bar>Im b * Im b + Re b * Re b\<bar>) =
  92.370 +    1" 
  92.371 +      apply (simp add: power2_eq_square norm_mult[symmetric] norm_inverse[symmetric])
  92.372 +      using right_inverse[OF b']
  92.373 +      by (simp add: power2_eq_square[symmetric] power_inverse[symmetric] ring_simps)
  92.374 +    have th0: "cmod (complex_of_real (cmod b) / b) = 1"
  92.375 +      apply (simp add: complex_Re_mult cmod_def power2_eq_square Re_complex_of_real Im_complex_of_real divide_inverse ring_simps )
  92.376 +      by (simp add: real_sqrt_mult[symmetric] th0)        
  92.377 +    from o have "\<exists>m. n = Suc (2*m)" by presburger+
  92.378 +    then obtain m where m: "n = Suc (2*m)" by blast
  92.379 +    from unimodular_reduce_norm[OF th0] o
  92.380 +    have "\<exists>v. cmod (complex_of_real (cmod b) / b + v^n) < 1"
  92.381 +      apply (cases "cmod (complex_of_real (cmod b) / b + 1) < 1", rule_tac x="1" in exI, simp)
  92.382 +      apply (cases "cmod (complex_of_real (cmod b) / b - 1) < 1", rule_tac x="-1" in exI, simp add: diff_def)
  92.383 +      apply (cases "cmod (complex_of_real (cmod b) / b + ii) < 1")
  92.384 +      apply (cases "even m", rule_tac x="ii" in exI, simp add: m power_mult)
  92.385 +      apply (rule_tac x="- ii" in exI, simp add: m power_mult)
  92.386 +      apply (cases "even m", rule_tac x="- ii" in exI, simp add: m power_mult diff_def)
  92.387 +      apply (rule_tac x="ii" in exI, simp add: m power_mult diff_def)
  92.388 +      done
  92.389 +    then obtain v where v: "cmod (complex_of_real (cmod b) / b + v^n) < 1" by blast
  92.390 +    let ?w = "v / complex_of_real (root n (cmod b))"
  92.391 +    from odd_real_root_pow[OF o, of "cmod b"]
  92.392 +    have th1: "?w ^ n = v^n / complex_of_real (cmod b)" 
  92.393 +      by (simp add: power_divide complex_of_real_power)
  92.394 +    have th2:"cmod (complex_of_real (cmod b) / b) = 1" using b by (simp add: norm_divide)
  92.395 +    hence th3: "cmod (complex_of_real (cmod b) / b) \<ge> 0" by simp
  92.396 +    have th4: "cmod (complex_of_real (cmod b) / b) *
  92.397 +   cmod (1 + b * (v ^ n / complex_of_real (cmod b)))
  92.398 +   < cmod (complex_of_real (cmod b) / b) * 1"
  92.399 +      apply (simp only: norm_mult[symmetric] right_distrib)
  92.400 +      using b v by (simp add: th2)
  92.401 +
  92.402 +    from mult_less_imp_less_left[OF th4 th3]
  92.403 +    have "?P ?w n" unfolding th1 . 
  92.404 +    hence "\<exists>z. ?P z n" .. }
  92.405 +  ultimately show "\<exists>z. ?P z n" by blast
  92.406 +qed
  92.407 +
  92.408 +
  92.409 +text{* Bolzano-Weierstrass type property for closed disc in complex plane. *}
  92.410 +
  92.411 +lemma metric_bound_lemma: "cmod (x - y) <= \<bar>Re x - Re y\<bar> + \<bar>Im x - Im y\<bar>"
  92.412 +  using real_sqrt_sum_squares_triangle_ineq[of "Re x - Re y" 0 0 "Im x - Im y" ]
  92.413 +  unfolding cmod_def by simp
  92.414 +
  92.415 +lemma bolzano_weierstrass_complex_disc:
  92.416 +  assumes r: "\<forall>n. cmod (s n) \<le> r"
  92.417 +  shows "\<exists>f z. subseq f \<and> (\<forall>e >0. \<exists>N. \<forall>n \<ge> N. cmod (s (f n) - z) < e)"
  92.418 +proof-
  92.419 +  from seq_monosub[of "Re o s"] 
  92.420 +  obtain f g where f: "subseq f" "monoseq (\<lambda>n. Re (s (f n)))" 
  92.421 +    unfolding o_def by blast
  92.422 +  from seq_monosub[of "Im o s o f"] 
  92.423 +  obtain g where g: "subseq g" "monoseq (\<lambda>n. Im (s(f(g n))))" unfolding o_def by blast  
  92.424 +  let ?h = "f o g"
  92.425 +  from r[rule_format, of 0] have rp: "r \<ge> 0" using norm_ge_zero[of "s 0"] by arith 
  92.426 +  have th:"\<forall>n. r + 1 \<ge> \<bar> Re (s n)\<bar>" 
  92.427 +  proof
  92.428 +    fix n
  92.429 +    from abs_Re_le_cmod[of "s n"] r[rule_format, of n]  show "\<bar>Re (s n)\<bar> \<le> r + 1" by arith
  92.430 +  qed
  92.431 +  have conv1: "convergent (\<lambda>n. Re (s ( f n)))"
  92.432 +    apply (rule Bseq_monoseq_convergent)
  92.433 +    apply (simp add: Bseq_def)
  92.434 +    apply (rule exI[where x= "r + 1"])
  92.435 +    using th rp apply simp
  92.436 +    using f(2) .
  92.437 +  have th:"\<forall>n. r + 1 \<ge> \<bar> Im (s n)\<bar>" 
  92.438 +  proof
  92.439 +    fix n
  92.440 +    from abs_Im_le_cmod[of "s n"] r[rule_format, of n]  show "\<bar>Im (s n)\<bar> \<le> r + 1" by arith
  92.441 +  qed
  92.442 +
  92.443 +  have conv2: "convergent (\<lambda>n. Im (s (f (g n))))"
  92.444 +    apply (rule Bseq_monoseq_convergent)
  92.445 +    apply (simp add: Bseq_def)
  92.446 +    apply (rule exI[where x= "r + 1"])
  92.447 +    using th rp apply simp
  92.448 +    using g(2) .
  92.449 +
  92.450 +  from conv1[unfolded convergent_def] obtain x where "LIMSEQ (\<lambda>n. Re (s (f n))) x" 
  92.451 +    by blast 
  92.452 +  hence  x: "\<forall>r>0. \<exists>n0. \<forall>n\<ge>n0. \<bar> Re (s (f n)) - x \<bar> < r" 
  92.453 +    unfolding LIMSEQ_def real_norm_def .
  92.454 +
  92.455 +  from conv2[unfolded convergent_def] obtain y where "LIMSEQ (\<lambda>n. Im (s (f (g n)))) y" 
  92.456 +    by blast 
  92.457 +  hence  y: "\<forall>r>0. \<exists>n0. \<forall>n\<ge>n0. \<bar> Im (s (f (g n))) - y \<bar> < r" 
  92.458 +    unfolding LIMSEQ_def real_norm_def .
  92.459 +  let ?w = "Complex x y"
  92.460 +  from f(1) g(1) have hs: "subseq ?h" unfolding subseq_def by auto 
  92.461 +  {fix e assume ep: "e > (0::real)"
  92.462 +    hence e2: "e/2 > 0" by simp
  92.463 +    from x[rule_format, OF e2] y[rule_format, OF e2]
  92.464 +    obtain N1 N2 where N1: "\<forall>n\<ge>N1. \<bar>Re (s (f n)) - x\<bar> < e / 2" and N2: "\<forall>n\<ge>N2. \<bar>Im (s (f (g n))) - y\<bar> < e / 2" by blast
  92.465 +    {fix n assume nN12: "n \<ge> N1 + N2"
  92.466 +      hence nN1: "g n \<ge> N1" and nN2: "n \<ge> N2" using seq_suble[OF g(1), of n] by arith+
  92.467 +      from add_strict_mono[OF N1[rule_format, OF nN1] N2[rule_format, OF nN2]]
  92.468 +      have "cmod (s (?h n) - ?w) < e" 
  92.469 +	using metric_bound_lemma[of "s (f (g n))" ?w] by simp }
  92.470 +    hence "\<exists>N. \<forall>n\<ge>N. cmod (s (?h n) - ?w) < e" by blast }
  92.471 +  with hs show ?thesis  by blast  
  92.472 +qed
  92.473 +
  92.474 +text{* Polynomial is continuous. *}
  92.475 +
  92.476 +lemma poly_cont:
  92.477 +  assumes ep: "e > 0" 
  92.478 +  shows "\<exists>d >0. \<forall>w. 0 < cmod (w - z) \<and> cmod (w - z) < d \<longrightarrow> cmod (poly p w - poly p z) < e"
  92.479 +proof-
  92.480 +  from poly_offset[of p z] obtain q where q: "length q = length p" "\<And>x. poly q x = poly p (z + x)" by blast
  92.481 +  {fix w
  92.482 +    note q(2)[of "w - z", simplified]}
  92.483 +  note th = this
  92.484 +  show ?thesis unfolding th[symmetric]
  92.485 +  proof(induct q)
  92.486 +    case Nil thus ?case  using ep by auto
  92.487 +  next
  92.488 +    case (Cons c cs)
  92.489 +    from poly_bound_exists[of 1 "cs"] 
  92.490 +    obtain m where m: "m > 0" "\<And>z. cmod z \<le> 1 \<Longrightarrow> cmod (poly cs z) \<le> m" by blast
  92.491 +    from ep m(1) have em0: "e/m > 0" by (simp add: field_simps)
  92.492 +    have one0: "1 > (0::real)"  by arith
  92.493 +    from real_lbound_gt_zero[OF one0 em0] 
  92.494 +    obtain d where d: "d >0" "d < 1" "d < e / m" by blast
  92.495 +    from d(1,3) m(1) have dm: "d*m > 0" "d*m < e" 
  92.496 +      by (simp_all add: field_simps real_mult_order)
  92.497 +    show ?case 
  92.498 +      proof(rule ex_forward[OF real_lbound_gt_zero[OF one0 em0]], clarsimp simp add: norm_mult)
  92.499 +	fix d w
  92.500 +	assume H: "d > 0" "d < 1" "d < e/m" "w\<noteq>z" "cmod (w-z) < d"
  92.501 +	hence d1: "cmod (w-z) \<le> 1" "d \<ge> 0" by simp_all
  92.502 +	from H(3) m(1) have dme: "d*m < e" by (simp add: field_simps)
  92.503 +	from H have th: "cmod (w-z) \<le> d" by simp 
  92.504 +	from mult_mono[OF th m(2)[OF d1(1)] d1(2) norm_ge_zero] dme
  92.505 +	show "cmod (w - z) * cmod (poly cs (w - z)) < e" by simp
  92.506 +      qed  
  92.507 +    qed
  92.508 +qed
  92.509 +
  92.510 +text{* Hence a polynomial attains minimum on a closed disc 
  92.511 +  in the complex plane. *}
  92.512 +lemma  poly_minimum_modulus_disc:
  92.513 +  "\<exists>z. \<forall>w. cmod w \<le> r \<longrightarrow> cmod (poly p z) \<le> cmod (poly p w)"
  92.514 +proof-
  92.515 +  {assume "\<not> r \<ge> 0" hence ?thesis unfolding linorder_not_le
  92.516 +      apply -
  92.517 +      apply (rule exI[where x=0]) 
  92.518 +      apply auto
  92.519 +      apply (subgoal_tac "cmod w < 0")
  92.520 +      apply simp
  92.521 +      apply arith
  92.522 +      done }
  92.523 +  moreover
  92.524 +  {assume rp: "r \<ge> 0"
  92.525 +    from rp have "cmod 0 \<le> r \<and> cmod (poly p 0) = - (- cmod (poly p 0))" by simp 
  92.526 +    hence mth1: "\<exists>x z. cmod z \<le> r \<and> cmod (poly p z) = - x"  by blast
  92.527 +    {fix x z
  92.528 +      assume H: "cmod z \<le> r" "cmod (poly p z) = - x" "\<not>x < 1"
  92.529 +      hence "- x < 0 " by arith
  92.530 +      with H(2) norm_ge_zero[of "poly p z"]  have False by simp }
  92.531 +    then have mth2: "\<exists>z. \<forall>x. (\<exists>z. cmod z \<le> r \<and> cmod (poly p z) = - x) \<longrightarrow> x < z" by blast
  92.532 +    from real_sup_exists[OF mth1 mth2] obtain s where 
  92.533 +      s: "\<forall>y. (\<exists>x. (\<exists>z. cmod z \<le> r \<and> cmod (poly p z) = - x) \<and> y < x) \<longleftrightarrow>(y < s)" by blast
  92.534 +    let ?m = "-s"
  92.535 +    {fix y
  92.536 +      from s[rule_format, of "-y"] have 
  92.537 +    "(\<exists>z x. cmod z \<le> r \<and> -(- cmod (poly p z)) < y) \<longleftrightarrow> ?m < y" 
  92.538 +	unfolding minus_less_iff[of y ] equation_minus_iff by blast }
  92.539 +    note s1 = this[unfolded minus_minus]
  92.540 +    from s1[of ?m] have s1m: "\<And>z x. cmod z \<le> r \<Longrightarrow> cmod (poly p z) \<ge> ?m" 
  92.541 +      by auto
  92.542 +    {fix n::nat
  92.543 +      from s1[rule_format, of "?m + 1/real (Suc n)"] 
  92.544 +      have "\<exists>z. cmod z \<le> r \<and> cmod (poly p z) < - s + 1 / real (Suc n)"
  92.545 +	by simp}
  92.546 +    hence th: "\<forall>n. \<exists>z. cmod z \<le> r \<and> cmod (poly p z) < - s + 1 / real (Suc n)" ..
  92.547 +    from choice[OF th] obtain g where 
  92.548 +      g: "\<forall>n. cmod (g n) \<le> r" "\<forall>n. cmod (poly p (g n)) <?m+1 /real(Suc n)" 
  92.549 +      by blast
  92.550 +    from bolzano_weierstrass_complex_disc[OF g(1)] 
  92.551 +    obtain f z where fz: "subseq f" "\<forall>e>0. \<exists>N. \<forall>n\<ge>N. cmod (g (f n) - z) < e"
  92.552 +      by blast    
  92.553 +    {fix w 
  92.554 +      assume wr: "cmod w \<le> r"
  92.555 +      let ?e = "\<bar>cmod (poly p z) - ?m\<bar>"
  92.556 +      {assume e: "?e > 0"
  92.557 +	hence e2: "?e/2 > 0" by simp
  92.558 +	from poly_cont[OF e2, of z p] obtain d where
  92.559 +	  d: "d>0" "\<forall>w. 0<cmod (w - z)\<and> cmod(w - z) < d \<longrightarrow> cmod(poly p w - poly p z) < ?e/2" by blast
  92.560 +	{fix w assume w: "cmod (w - z) < d"
  92.561 +	  have "cmod(poly p w - poly p z) < ?e / 2"
  92.562 +	    using d(2)[rule_format, of w] w e by (cases "w=z", simp_all)}
  92.563 +	note th1 = this
  92.564 +	
  92.565 +	from fz(2)[rule_format, OF d(1)] obtain N1 where 
  92.566 +	  N1: "\<forall>n\<ge>N1. cmod (g (f n) - z) < d" by blast
  92.567 +	from reals_Archimedean2[of "2/?e"] obtain N2::nat where
  92.568 +	  N2: "2/?e < real N2" by blast
  92.569 +	have th2: "cmod(poly p (g(f(N1 + N2))) - poly p z) < ?e/2"
  92.570 +	  using N1[rule_format, of "N1 + N2"] th1 by simp
  92.571 +	{fix a b e2 m :: real
  92.572 +	have "a < e2 \<Longrightarrow> abs(b - m) < e2 \<Longrightarrow> 2 * e2 <= abs(b - m) + a
  92.573 +          ==> False" by arith}
  92.574 +      note th0 = this
  92.575 +      have ath: 
  92.576 +	"\<And>m x e. m <= x \<Longrightarrow>  x < m + e ==> abs(x - m::real) < e" by arith
  92.577 +      from s1m[OF g(1)[rule_format]]
  92.578 +      have th31: "?m \<le> cmod(poly p (g (f (N1 + N2))))" .
  92.579 +      from seq_suble[OF fz(1), of "N1+N2"]
  92.580 +      have th00: "real (Suc (N1+N2)) \<le> real (Suc (f (N1+N2)))" by simp
  92.581 +      have th000: "0 \<le> (1::real)" "(1::real) \<le> 1" "real (Suc (N1+N2)) > 0"  
  92.582 +	using N2 by auto
  92.583 +      from frac_le[OF th000 th00] have th00: "?m +1 / real (Suc (f (N1 + N2))) \<le> ?m + 1 / real (Suc (N1 + N2))" by simp
  92.584 +      from g(2)[rule_format, of "f (N1 + N2)"]
  92.585 +      have th01:"cmod (poly p (g (f (N1 + N2)))) < - s + 1 / real (Suc (f (N1 + N2)))" .
  92.586 +      from order_less_le_trans[OF th01 th00]
  92.587 +      have th32: "cmod(poly p (g (f (N1 + N2)))) < ?m + (1/ real(Suc (N1 + N2)))" .
  92.588 +      from N2 have "2/?e < real (Suc (N1 + N2))" by arith
  92.589 +      with e2 less_imp_inverse_less[of "2/?e" "real (Suc (N1 + N2))"]
  92.590 +      have "?e/2 > 1/ real (Suc (N1 + N2))" by (simp add: inverse_eq_divide)
  92.591 +      with ath[OF th31 th32]
  92.592 +      have thc1:"\<bar>cmod(poly p (g (f (N1 + N2)))) - ?m\<bar>< ?e/2" by arith  
  92.593 +      have ath2: "\<And>(a::real) b c m. \<bar>a - b\<bar> <= c ==> \<bar>b - m\<bar> <= \<bar>a - m\<bar> + c" 
  92.594 +	by arith
  92.595 +      have th22: "\<bar>cmod (poly p (g (f (N1 + N2)))) - cmod (poly p z)\<bar>
  92.596 +\<le> cmod (poly p (g (f (N1 + N2))) - poly p z)" 
  92.597 +	by (simp add: norm_triangle_ineq3)
  92.598 +      from ath2[OF th22, of ?m]
  92.599 +      have thc2: "2*(?e/2) \<le> \<bar>cmod(poly p (g (f (N1 + N2)))) - ?m\<bar> + cmod (poly p (g (f (N1 + N2))) - poly p z)" by simp
  92.600 +      from th0[OF th2 thc1 thc2] have False .}
  92.601 +      hence "?e = 0" by auto
  92.602 +      then have "cmod (poly p z) = ?m" by simp  
  92.603 +      with s1m[OF wr]
  92.604 +      have "cmod (poly p z) \<le> cmod (poly p w)" by simp }
  92.605 +    hence ?thesis by blast}
  92.606 +  ultimately show ?thesis by blast
  92.607 +qed
  92.608 +
  92.609 +lemma "(rcis (sqrt (abs r)) (a/2)) ^ 2 = rcis (abs r) a"
  92.610 +  unfolding power2_eq_square
  92.611 +  apply (simp add: rcis_mult)
  92.612 +  apply (simp add: power2_eq_square[symmetric])
  92.613 +  done
  92.614 +
  92.615 +lemma cispi: "cis pi = -1" 
  92.616 +  unfolding cis_def
  92.617 +  by simp
  92.618 +
  92.619 +lemma "(rcis (sqrt (abs r)) ((pi + a)/2)) ^ 2 = rcis (- abs r) a"
  92.620 +  unfolding power2_eq_square
  92.621 +  apply (simp add: rcis_mult add_divide_distrib)
  92.622 +  apply (simp add: power2_eq_square[symmetric] rcis_def cispi cis_mult[symmetric])
  92.623 +  done
  92.624 +
  92.625 +text {* Nonzero polynomial in z goes to infinity as z does. *}
  92.626 +
  92.627 +instance complex::idom_char_0 by (intro_classes)
  92.628 +instance complex :: recpower_idom_char_0 by intro_classes
  92.629 +
  92.630 +lemma poly_infinity:
  92.631 +  assumes ex: "list_ex (\<lambda>c. c \<noteq> 0) p"
  92.632 +  shows "\<exists>r. \<forall>z. r \<le> cmod z \<longrightarrow> d \<le> cmod (poly (a#p) z)"
  92.633 +using ex
  92.634 +proof(induct p arbitrary: a d)
  92.635 +  case (Cons c cs a d) 
  92.636 +  {assume H: "list_ex (\<lambda>c. c\<noteq>0) cs"
  92.637 +    with Cons.hyps obtain r where r: "\<forall>z. r \<le> cmod z \<longrightarrow> d + cmod a \<le> cmod (poly (c # cs) z)" by blast
  92.638 +    let ?r = "1 + \<bar>r\<bar>"
  92.639 +    {fix z assume h: "1 + \<bar>r\<bar> \<le> cmod z"
  92.640 +      have r0: "r \<le> cmod z" using h by arith
  92.641 +      from r[rule_format, OF r0]
  92.642 +      have th0: "d + cmod a \<le> 1 * cmod(poly (c#cs) z)" by arith
  92.643 +      from h have z1: "cmod z \<ge> 1" by arith
  92.644 +      from order_trans[OF th0 mult_right_mono[OF z1 norm_ge_zero[of "poly (c#cs) z"]]]
  92.645 +      have th1: "d \<le> cmod(z * poly (c#cs) z) - cmod a"
  92.646 +	unfolding norm_mult by (simp add: ring_simps)
  92.647 +      from complex_mod_triangle_sub[of "z * poly (c#cs) z" a]
  92.648 +      have th2: "cmod(z * poly (c#cs) z) - cmod a \<le> cmod (poly (a#c#cs) z)" 
  92.649 +	by (simp add: diff_le_eq ring_simps) 
  92.650 +      from th1 th2 have "d \<le> cmod (poly (a#c#cs) z)"  by arith}
  92.651 +    hence ?case by blast}
  92.652 +  moreover
  92.653 +  {assume cs0: "\<not> (list_ex (\<lambda>c. c \<noteq> 0) cs)"
  92.654 +    with Cons.prems have c0: "c \<noteq> 0" by simp
  92.655 +    from cs0 have cs0': "list_all (\<lambda>c. c = 0) cs" 
  92.656 +      by (auto simp add: list_all_iff list_ex_iff)
  92.657 +    {fix z
  92.658 +      assume h: "(\<bar>d\<bar> + cmod a) / cmod c \<le> cmod z"
  92.659 +      from c0 have "cmod c > 0" by simp
  92.660 +      from h c0 have th0: "\<bar>d\<bar> + cmod a \<le> cmod (z*c)" 
  92.661 +	by (simp add: field_simps norm_mult)
  92.662 +      have ath: "\<And>mzh mazh ma. mzh <= mazh + ma ==> abs(d) + ma <= mzh ==> d <= mazh" by arith
  92.663 +      from complex_mod_triangle_sub[of "z*c" a ]
  92.664 +      have th1: "cmod (z * c) \<le> cmod (a + z * c) + cmod a"
  92.665 +	by (simp add: ring_simps)
  92.666 +      from ath[OF th1 th0] have "d \<le> cmod (poly (a # c # cs) z)" 
  92.667 +	using poly_0[OF cs0'] by simp}
  92.668 +    then have ?case  by blast}
  92.669 +  ultimately show ?case by blast
  92.670 +qed simp
  92.671 +
  92.672 +text {* Hence polynomial's modulus attains its minimum somewhere. *}
  92.673 +lemma poly_minimum_modulus:
  92.674 +  "\<exists>z.\<forall>w. cmod (poly p z) \<le> cmod (poly p w)"
  92.675 +proof(induct p)
  92.676 +  case (Cons c cs) 
  92.677 +  {assume cs0: "list_ex (\<lambda>c. c \<noteq> 0) cs"
  92.678 +    from poly_infinity[OF cs0, of "cmod (poly (c#cs) 0)" c]
  92.679 +    obtain r where r: "\<And>z. r \<le> cmod z \<Longrightarrow> cmod (poly (c # cs) 0) \<le> cmod (poly (c # cs) z)" by blast
  92.680 +    have ath: "\<And>z r. r \<le> cmod z \<or> cmod z \<le> \<bar>r\<bar>" by arith
  92.681 +    from poly_minimum_modulus_disc[of "\<bar>r\<bar>" "c#cs"] 
  92.682 +    obtain v where v: "\<And>w. cmod w \<le> \<bar>r\<bar> \<Longrightarrow> cmod (poly (c # cs) v) \<le> cmod (poly (c # cs) w)" by blast
  92.683 +    {fix z assume z: "r \<le> cmod z"
  92.684 +      from v[of 0] r[OF z] 
  92.685 +      have "cmod (poly (c # cs) v) \<le> cmod (poly (c # cs) z)"
  92.686 +	by simp }
  92.687 +    note v0 = this
  92.688 +    from v0 v ath[of r] have ?case by blast}
  92.689 +  moreover
  92.690 +  {assume cs0: "\<not> (list_ex (\<lambda>c. c\<noteq>0) cs)"
  92.691 +    hence th:"list_all (\<lambda>c. c = 0) cs" by (simp add: list_all_iff list_ex_iff)
  92.692 +    from poly_0[OF th] Cons.hyps have ?case by simp}
  92.693 +  ultimately show ?case by blast
  92.694 +qed simp
  92.695 +
  92.696 +text{* Constant function (non-syntactic characterization). *}
  92.697 +definition "constant f = (\<forall>x y. f x = f y)"
  92.698 +
  92.699 +lemma nonconstant_length: "\<not> (constant (poly p)) \<Longrightarrow> length p \<ge> 2"
  92.700 +  unfolding constant_def
  92.701 +  apply (induct p, auto)
  92.702 +  apply (unfold not_less[symmetric])
  92.703 +  apply simp
  92.704 +  apply (rule ccontr)
  92.705 +  apply auto
  92.706 +  done
  92.707 + 
  92.708 +lemma poly_replicate_append:
  92.709 +  "poly ((replicate n 0)@p) (x::'a::{recpower, comm_ring}) = x^n * poly p x"
  92.710 +  by(induct n, auto simp add: power_Suc ring_simps)
  92.711 +
  92.712 +text {* Decomposition of polynomial, skipping zero coefficients 
  92.713 +  after the first.  *}
  92.714 +
  92.715 +lemma poly_decompose_lemma:
  92.716 + assumes nz: "\<not>(\<forall>z. z\<noteq>0 \<longrightarrow> poly p z = (0::'a::{recpower,idom}))"
  92.717 +  shows "\<exists>k a q. a\<noteq>0 \<and> Suc (length q + k) = length p \<and> 
  92.718 +                 (\<forall>z. poly p z = z^k * poly (a#q) z)"
  92.719 +using nz
  92.720 +proof(induct p)
  92.721 +  case Nil thus ?case by simp
  92.722 +next
  92.723 +  case (Cons c cs)
  92.724 +  {assume c0: "c = 0"
  92.725 +    
  92.726 +    from Cons.hyps Cons.prems c0 have ?case apply auto
  92.727 +      apply (rule_tac x="k+1" in exI)
  92.728 +      apply (rule_tac x="a" in exI, clarsimp)
  92.729 +      apply (rule_tac x="q" in exI)
  92.730 +      by (auto simp add: power_Suc)}
  92.731 +  moreover
  92.732 +  {assume c0: "c\<noteq>0"
  92.733 +    hence ?case apply-
  92.734 +      apply (rule exI[where x=0])
  92.735 +      apply (rule exI[where x=c], clarsimp)
  92.736 +      apply (rule exI[where x=cs])
  92.737 +      apply auto
  92.738 +      done}
  92.739 +  ultimately show ?case by blast
  92.740 +qed
  92.741 +
  92.742 +lemma poly_decompose:
  92.743 +  assumes nc: "~constant(poly p)"
  92.744 +  shows "\<exists>k a q. a\<noteq>(0::'a::{recpower,idom}) \<and> k\<noteq>0 \<and>
  92.745 +               length q + k + 1 = length p \<and> 
  92.746 +              (\<forall>z. poly p z = poly p 0 + z^k * poly (a#q) z)"
  92.747 +using nc 
  92.748 +proof(induct p)
  92.749 +  case Nil thus ?case by (simp add: constant_def)
  92.750 +next
  92.751 +  case (Cons c cs)
  92.752 +  {assume C:"\<forall>z. z \<noteq> 0 \<longrightarrow> poly cs z = 0"
  92.753 +    {fix x y
  92.754 +      from C have "poly (c#cs) x = poly (c#cs) y" by (cases "x=0", auto)}
  92.755 +    with Cons.prems have False by (auto simp add: constant_def)}
  92.756 +  hence th: "\<not> (\<forall>z. z \<noteq> 0 \<longrightarrow> poly cs z = 0)" ..
  92.757 +  from poly_decompose_lemma[OF th] 
  92.758 +  show ?case 
  92.759 +    apply clarsimp    
  92.760 +    apply (rule_tac x="k+1" in exI)
  92.761 +    apply (rule_tac x="a" in exI)
  92.762 +    apply simp
  92.763 +    apply (rule_tac x="q" in exI)
  92.764 +    apply (auto simp add: power_Suc)
  92.765 +    done
  92.766 +qed
  92.767 +
  92.768 +text{* Fundamental theorem of algebral *}
  92.769 +
  92.770 +lemma fundamental_theorem_of_algebra:
  92.771 +  assumes nc: "~constant(poly p)"
  92.772 +  shows "\<exists>z::complex. poly p z = 0"
  92.773 +using nc
  92.774 +proof(induct n\<equiv> "length p" arbitrary: p rule: nat_less_induct)
  92.775 +  fix n fix p :: "complex list"
  92.776 +  let ?p = "poly p"
  92.777 +  assume H: "\<forall>m<n. \<forall>p. \<not> constant (poly p) \<longrightarrow> m = length p \<longrightarrow> (\<exists>(z::complex). poly p z = 0)" and nc: "\<not> constant ?p" and n: "n = length p"
  92.778 +  let ?ths = "\<exists>z. ?p z = 0"
  92.779 +
  92.780 +  from nonconstant_length[OF nc] have n2: "n\<ge> 2" by (simp add: n)
  92.781 +  from poly_minimum_modulus obtain c where 
  92.782 +    c: "\<forall>w. cmod (?p c) \<le> cmod (?p w)" by blast
  92.783 +  {assume pc: "?p c = 0" hence ?ths by blast}
  92.784 +  moreover
  92.785 +  {assume pc0: "?p c \<noteq> 0"
  92.786 +    from poly_offset[of p c] obtain q where
  92.787 +      q: "length q = length p" "\<forall>x. poly q x = ?p (c+x)" by blast
  92.788 +    {assume h: "constant (poly q)"
  92.789 +      from q(2) have th: "\<forall>x. poly q (x - c) = ?p x" by auto
  92.790 +      {fix x y
  92.791 +	from th have "?p x = poly q (x - c)" by auto 
  92.792 +	also have "\<dots> = poly q (y - c)" 
  92.793 +	  using h unfolding constant_def by blast
  92.794 +	also have "\<dots> = ?p y" using th by auto
  92.795 +	finally have "?p x = ?p y" .}
  92.796 +      with nc have False unfolding constant_def by blast }
  92.797 +    hence qnc: "\<not> constant (poly q)" by blast
  92.798 +    from q(2) have pqc0: "?p c = poly q 0" by simp
  92.799 +    from c pqc0 have cq0: "\<forall>w. cmod (poly q 0) \<le> cmod (?p w)" by simp 
  92.800 +    let ?a0 = "poly q 0"
  92.801 +    from pc0 pqc0 have a00: "?a0 \<noteq> 0" by simp 
  92.802 +    from a00 
  92.803 +    have qr: "\<forall>z. poly q z = poly (map (op * (inverse ?a0)) q) z * ?a0"
  92.804 +      by (simp add: poly_cmult_map)
  92.805 +    let ?r = "map (op * (inverse ?a0)) q"
  92.806 +    have lgqr: "length q = length ?r" by simp 
  92.807 +    {assume h: "\<And>x y. poly ?r x = poly ?r y"
  92.808 +      {fix x y
  92.809 +	from qr[rule_format, of x] 
  92.810 +	have "poly q x = poly ?r x * ?a0" by auto
  92.811 +	also have "\<dots> = poly ?r y * ?a0" using h by simp
  92.812 +	also have "\<dots> = poly q y" using qr[rule_format, of y] by simp
  92.813 +	finally have "poly q x = poly q y" .} 
  92.814 +      with qnc have False unfolding constant_def by blast}
  92.815 +    hence rnc: "\<not> constant (poly ?r)" unfolding constant_def by blast
  92.816 +    from qr[rule_format, of 0] a00  have r01: "poly ?r 0 = 1" by auto
  92.817 +    {fix w 
  92.818 +      have "cmod (poly ?r w) < 1 \<longleftrightarrow> cmod (poly q w / ?a0) < 1"
  92.819 +	using qr[rule_format, of w] a00 by simp
  92.820 +      also have "\<dots> \<longleftrightarrow> cmod (poly q w) < cmod ?a0"
  92.821 +	using a00 unfolding norm_divide by (simp add: field_simps)
  92.822 +      finally have "cmod (poly ?r w) < 1 \<longleftrightarrow> cmod (poly q w) < cmod ?a0" .}
  92.823 +    note mrmq_eq = this
  92.824 +    from poly_decompose[OF rnc] obtain k a s where 
  92.825 +      kas: "a\<noteq>0" "k\<noteq>0" "length s + k + 1 = length ?r" 
  92.826 +      "\<forall>z. poly ?r z = poly ?r 0 + z^k* poly (a#s) z" by blast
  92.827 +    {assume "k + 1 = n"
  92.828 +      with kas(3) lgqr[symmetric] q(1) n[symmetric] have s0:"s=[]" by auto
  92.829 +      {fix w
  92.830 +	have "cmod (poly ?r w) = cmod (1 + a * w ^ k)" 
  92.831 +	  using kas(4)[rule_format, of w] s0 r01 by (simp add: ring_simps)}
  92.832 +      note hth = this [symmetric]
  92.833 +	from reduce_poly_simple[OF kas(1,2)] 
  92.834 +      have "\<exists>w. cmod (poly ?r w) < 1" unfolding hth by blast}
  92.835 +    moreover
  92.836 +    {assume kn: "k+1 \<noteq> n"
  92.837 +      from kn kas(3) q(1) n[symmetric] have k1n: "k + 1 < n" by simp
  92.838 +      have th01: "\<not> constant (poly (1#((replicate (k - 1) 0)@[a])))" 
  92.839 +	unfolding constant_def poly_Nil poly_Cons poly_replicate_append
  92.840 +	using kas(1) apply simp 
  92.841 +	by (rule exI[where x=0], rule exI[where x=1], simp)
  92.842 +      from kas(2) have th02: "k+1 = length (1#((replicate (k - 1) 0)@[a]))" 
  92.843 +	by simp
  92.844 +      from H[rule_format, OF k1n th01 th02]
  92.845 +      obtain w where w: "1 + w^k * a = 0"
  92.846 +	unfolding poly_Nil poly_Cons poly_replicate_append
  92.847 +	using kas(2) by (auto simp add: power_Suc[symmetric, of _ "k - Suc 0"] 
  92.848 +	  mult_assoc[of _ _ a, symmetric])
  92.849 +      from poly_bound_exists[of "cmod w" s] obtain m where 
  92.850 +	m: "m > 0" "\<forall>z. cmod z \<le> cmod w \<longrightarrow> cmod (poly s z) \<le> m" by blast
  92.851 +      have w0: "w\<noteq>0" using kas(2) w by (auto simp add: power_0_left)
  92.852 +      from w have "(1 + w ^ k * a) - 1 = 0 - 1" by simp
  92.853 +      then have wm1: "w^k * a = - 1" by simp
  92.854 +      have inv0: "0 < inverse (cmod w ^ (k + 1) * m)" 
  92.855 +	using norm_ge_zero[of w] w0 m(1)
  92.856 +	  by (simp add: inverse_eq_divide zero_less_mult_iff)
  92.857 +      with real_down2[OF zero_less_one] obtain t where
  92.858 +	t: "t > 0" "t < 1" "t < inverse (cmod w ^ (k + 1) * m)" by blast
  92.859 +      let ?ct = "complex_of_real t"
  92.860 +      let ?w = "?ct * w"
  92.861 +      have "1 + ?w^k * (a + ?w * poly s ?w) = 1 + ?ct^k * (w^k * a) + ?w^k * ?w * poly s ?w" using kas(1) by (simp add: ring_simps power_mult_distrib)
  92.862 +      also have "\<dots> = complex_of_real (1 - t^k) + ?w^k * ?w * poly s ?w"
  92.863 +	unfolding wm1 by (simp)
  92.864 +      finally have "cmod (1 + ?w^k * (a + ?w * poly s ?w)) = cmod (complex_of_real (1 - t^k) + ?w^k * ?w * poly s ?w)" 
  92.865 +	apply -
  92.866 +	apply (rule cong[OF refl[of cmod]])
  92.867 +	apply assumption
  92.868 +	done
  92.869 +      with norm_triangle_ineq[of "complex_of_real (1 - t^k)" "?w^k * ?w * poly s ?w"] 
  92.870 +      have th11: "cmod (1 + ?w^k * (a + ?w * poly s ?w)) \<le> \<bar>1 - t^k\<bar> + cmod (?w^k * ?w * poly s ?w)" unfolding norm_of_real by simp 
  92.871 +      have ath: "\<And>x (t::real). 0\<le> x \<Longrightarrow> x < t \<Longrightarrow> t\<le>1 \<Longrightarrow> \<bar>1 - t\<bar> + x < 1" by arith
  92.872 +      have "t *cmod w \<le> 1 * cmod w" apply (rule mult_mono) using t(1,2) by auto
  92.873 +      then have tw: "cmod ?w \<le> cmod w" using t(1) by (simp add: norm_mult) 
  92.874 +      from t inv0 have "t* (cmod w ^ (k + 1) * m) < 1"
  92.875 +	by (simp add: inverse_eq_divide field_simps)
  92.876 +      with zero_less_power[OF t(1), of k] 
  92.877 +      have th30: "t^k * (t* (cmod w ^ (k + 1) * m)) < t^k * 1" 
  92.878 +	apply - apply (rule mult_strict_left_mono) by simp_all
  92.879 +      have "cmod (?w^k * ?w * poly s ?w) = t^k * (t* (cmod w ^ (k+1) * cmod (poly s ?w)))"  using w0 t(1)
  92.880 +	by (simp add: ring_simps power_mult_distrib norm_of_real norm_power norm_mult)
  92.881 +      then have "cmod (?w^k * ?w * poly s ?w) \<le> t^k * (t* (cmod w ^ (k + 1) * m))"
  92.882 +	using t(1,2) m(2)[rule_format, OF tw] w0
  92.883 +	apply (simp only: )
  92.884 +	apply auto
  92.885 +	apply (rule mult_mono, simp_all add: norm_ge_zero)+
  92.886 +	apply (simp add: zero_le_mult_iff zero_le_power)
  92.887 +	done
  92.888 +      with th30 have th120: "cmod (?w^k * ?w * poly s ?w) < t^k" by simp 
  92.889 +      from power_strict_mono[OF t(2), of k] t(1) kas(2) have th121: "t^k \<le> 1" 
  92.890 +	by auto
  92.891 +      from ath[OF norm_ge_zero[of "?w^k * ?w * poly s ?w"] th120 th121]
  92.892 +      have th12: "\<bar>1 - t^k\<bar> + cmod (?w^k * ?w * poly s ?w) < 1" . 
  92.893 +      from th11 th12
  92.894 +      have "cmod (1 + ?w^k * (a + ?w * poly s ?w)) < 1"  by arith 
  92.895 +      then have "cmod (poly ?r ?w) < 1" 
  92.896 +	unfolding kas(4)[rule_format, of ?w] r01 by simp 
  92.897 +      then have "\<exists>w. cmod (poly ?r w) < 1" by blast}
  92.898 +    ultimately have cr0_contr: "\<exists>w. cmod (poly ?r w) < 1" by blast
  92.899 +    from cr0_contr cq0 q(2)
  92.900 +    have ?ths unfolding mrmq_eq not_less[symmetric] by auto}
  92.901 +  ultimately show ?ths by blast
  92.902 +qed
  92.903 +
  92.904 +text {* Alternative version with a syntactic notion of constant polynomial. *}
  92.905 +
  92.906 +lemma fundamental_theorem_of_algebra_alt:
  92.907 +  assumes nc: "~(\<exists>a l. a\<noteq> 0 \<and> list_all(\<lambda>b. b = 0) l \<and> p = a#l)"
  92.908 +  shows "\<exists>z. poly p z = (0::complex)"
  92.909 +using nc
  92.910 +proof(induct p)
  92.911 +  case (Cons c cs)
  92.912 +  {assume "c=0" hence ?case by auto}
  92.913 +  moreover
  92.914 +  {assume c0: "c\<noteq>0"
  92.915 +    {assume nc: "constant (poly (c#cs))"
  92.916 +      from nc[unfolded constant_def, rule_format, of 0] 
  92.917 +      have "\<forall>w. w \<noteq> 0 \<longrightarrow> poly cs w = 0" by auto 
  92.918 +      hence "list_all (\<lambda>c. c=0) cs"
  92.919 +	proof(induct cs)
  92.920 +	  case (Cons d ds)
  92.921 +	  {assume "d=0" hence ?case using Cons.prems Cons.hyps by simp}
  92.922 +	  moreover
  92.923 +	  {assume d0: "d\<noteq>0"
  92.924 +	    from poly_bound_exists[of 1 ds] obtain m where 
  92.925 +	      m: "m > 0" "\<forall>z. \<forall>z. cmod z \<le> 1 \<longrightarrow> cmod (poly ds z) \<le> m" by blast
  92.926 +	    have dm: "cmod d / m > 0" using d0 m(1) by (simp add: field_simps)
  92.927 +	    from real_down2[OF dm zero_less_one] obtain x where 
  92.928 +	      x: "x > 0" "x < cmod d / m" "x < 1" by blast
  92.929 +	    let ?x = "complex_of_real x"
  92.930 +	    from x have cx: "?x \<noteq> 0"  "cmod ?x \<le> 1" by simp_all
  92.931 +	    from Cons.prems[rule_format, OF cx(1)]
  92.932 +	    have cth: "cmod (?x*poly ds ?x) = cmod d" by (simp add: eq_diff_eq[symmetric])
  92.933 +	    from m(2)[rule_format, OF cx(2)] x(1)
  92.934 +	    have th0: "cmod (?x*poly ds ?x) \<le> x*m"
  92.935 +	      by (simp add: norm_mult)
  92.936 +	    from x(2) m(1) have "x*m < cmod d" by (simp add: field_simps)
  92.937 +	    with th0 have "cmod (?x*poly ds ?x) \<noteq> cmod d" by auto
  92.938 +	    with cth  have ?case by blast}
  92.939 +	  ultimately show ?case by blast 
  92.940 +	qed simp}
  92.941 +      then have nc: "\<not> constant (poly (c#cs))" using Cons.prems c0 
  92.942 +	by blast
  92.943 +      from fundamental_theorem_of_algebra[OF nc] have ?case .}
  92.944 +  ultimately show ?case by blast  
  92.945 +qed simp
  92.946 +
  92.947 +subsection{* Nullstellenstatz, degrees and divisibility of polynomials *}
  92.948 +
  92.949 +lemma nullstellensatz_lemma:
  92.950 +  fixes p :: "complex list"
  92.951 +  assumes "\<forall>x. poly p x = 0 \<longrightarrow> poly q x = 0"
  92.952 +  and "degree p = n" and "n \<noteq> 0"
  92.953 +  shows "p divides (pexp q n)"
  92.954 +using prems
  92.955 +proof(induct n arbitrary: p q rule: nat_less_induct)
  92.956 +  fix n::nat fix p q :: "complex list"
  92.957 +  assume IH: "\<forall>m<n. \<forall>p q.
  92.958 +                 (\<forall>x. poly p x = (0::complex) \<longrightarrow> poly q x = 0) \<longrightarrow>
  92.959 +                 degree p = m \<longrightarrow> m \<noteq> 0 \<longrightarrow> p divides (q %^ m)"
  92.960 +    and pq0: "\<forall>x. poly p x = 0 \<longrightarrow> poly q x = 0" 
  92.961 +    and dpn: "degree p = n" and n0: "n \<noteq> 0"
  92.962 +  let ?ths = "p divides (q %^ n)"
  92.963 +  {fix a assume a: "poly p a = 0"
  92.964 +    {assume p0: "poly p = poly []" 
  92.965 +      hence ?ths unfolding divides_def  using pq0 n0
  92.966 +	apply - apply (rule exI[where x="[]"], rule ext)
  92.967 +	by (auto simp add: poly_mult poly_exp)}
  92.968 +    moreover
  92.969 +    {assume p0: "poly p \<noteq> poly []" 
  92.970 +      and oa: "order  a p \<noteq> 0"
  92.971 +      from p0 have pne: "p \<noteq> []" by auto
  92.972 +      let ?op = "order a p"
  92.973 +      from p0 have ap: "([- a, 1] %^ ?op) divides p" 
  92.974 +	"\<not> pexp [- a, 1] (Suc ?op) divides p" using order by blast+ 
  92.975 +      note oop = order_degree[OF p0, unfolded dpn]
  92.976 +      {assume q0: "q = []"
  92.977 +	hence ?ths using n0 unfolding divides_def 
  92.978 +	  apply simp
  92.979 +	  apply (rule exI[where x="[]"], rule ext)
  92.980 +	  by (simp add: divides_def poly_exp poly_mult)}
  92.981 +      moreover
  92.982 +      {assume q0: "q\<noteq>[]"
  92.983 +	from pq0[rule_format, OF a, unfolded poly_linear_divides] q0
  92.984 +	obtain r where r: "q = pmult [- a, 1] r" by blast
  92.985 +	from ap[unfolded divides_def] obtain s where
  92.986 +	  s: "poly p = poly (pmult (pexp [- a, 1] ?op) s)" by blast
  92.987 +	have s0: "poly s \<noteq> poly []"
  92.988 +	  using s p0 by (simp add: poly_entire)
  92.989 +	hence pns0: "poly (pnormalize s) \<noteq> poly []" and sne: "s\<noteq>[]" by auto
  92.990 +	{assume ds0: "degree s = 0"
  92.991 +	  from ds0 pns0 have "\<exists>k. pnormalize s = [k]" unfolding degree_def 
  92.992 +	    by (cases "pnormalize s", auto)
  92.993 +	  then obtain k where kpn: "pnormalize s = [k]" by blast
  92.994 +	  from pns0[unfolded poly_zero] kpn have k: "k \<noteq>0" "poly s = poly [k]"
  92.995 +	    using poly_normalize[of s] by simp_all
  92.996 +	  let ?w = "pmult (pmult [1/k] (pexp [-a,1] (n - ?op))) (pexp r n)"
  92.997 +	  from k r s oop have "poly (pexp q n) = poly (pmult p ?w)"
  92.998 +	    by - (rule ext, simp add: poly_mult poly_exp poly_cmult poly_add power_add[symmetric] ring_simps power_mult_distrib[symmetric])
  92.999 +	  hence ?ths unfolding divides_def by blast}
 92.1000 +	moreover
 92.1001 +	{assume ds0: "degree s \<noteq> 0"
 92.1002 +	  from ds0 s0 dpn degree_unique[OF s, unfolded linear_pow_mul_degree] oa
 92.1003 +	    have dsn: "degree s < n" by auto 
 92.1004 +	    {fix x assume h: "poly s x = 0"
 92.1005 +	      {assume xa: "x = a"
 92.1006 +		from h[unfolded xa poly_linear_divides] sne obtain u where
 92.1007 +		  u: "s = pmult [- a, 1] u" by blast
 92.1008 +		have "poly p = poly (pmult (pexp [- a, 1] (Suc ?op)) u)"
 92.1009 +		  unfolding s u
 92.1010 +		  apply (rule ext)
 92.1011 +		  by (simp add: ring_simps power_mult_distrib[symmetric] poly_mult poly_cmult poly_add poly_exp)
 92.1012 +		with ap(2)[unfolded divides_def] have False by blast}
 92.1013 +	      note xa = this
 92.1014 +	      from h s have "poly p x = 0" by (simp add: poly_mult)
 92.1015 +	      with pq0 have "poly q x = 0" by blast
 92.1016 +	      with r xa have "poly r x = 0"
 92.1017 +		by (auto simp add: poly_mult poly_add poly_cmult eq_diff_eq[symmetric])}
 92.1018 +	    note impth = this
 92.1019 +	    from IH[rule_format, OF dsn, of s r] impth ds0
 92.1020 +	    have "s divides (pexp r (degree s))" by blast
 92.1021 +	    then obtain u where u: "poly (pexp r (degree s)) = poly (pmult s u)"
 92.1022 +	      unfolding divides_def by blast
 92.1023 +	    hence u': "\<And>x. poly s x * poly u x = poly r x ^ degree s"
 92.1024 +	      by (simp add: poly_mult[symmetric] poly_exp[symmetric])
 92.1025 +	    let ?w = "pmult (pmult u (pexp [-a,1] (n - ?op))) (pexp r (n - degree s))"
 92.1026 +	    from u' s r oop[of a] dsn have "poly (pexp q n) = poly (pmult p ?w)"
 92.1027 +	      apply - apply (rule ext)
 92.1028 +	      apply (simp only:  power_mult_distrib power_add[symmetric] poly_add poly_mult poly_exp poly_cmult ring_simps)
 92.1029 +	      
 92.1030 +	      apply (simp add:  power_mult_distrib power_add[symmetric] poly_add poly_mult poly_exp poly_cmult mult_assoc[symmetric])
 92.1031 +	      done
 92.1032 +	    hence ?ths unfolding divides_def by blast}
 92.1033 +      ultimately have ?ths by blast }
 92.1034 +      ultimately have ?ths by blast}
 92.1035 +    ultimately have ?ths using a order_root by blast}
 92.1036 +  moreover
 92.1037 +  {assume exa: "\<not> (\<exists>a. poly p a = 0)"
 92.1038 +    from fundamental_theorem_of_algebra_alt[of p] exa obtain c cs where
 92.1039 +      ccs: "c\<noteq>0" "list_all (\<lambda>c. c = 0) cs" "p = c#cs" by blast
 92.1040 +    
 92.1041 +    from poly_0[OF ccs(2)] ccs(3) 
 92.1042 +    have pp: "\<And>x. poly p x =  c" by simp
 92.1043 +    let ?w = "pmult [1/c] (pexp q n)"
 92.1044 +    from pp ccs(1) 
 92.1045 +    have "poly (pexp q n) = poly (pmult p ?w) "
 92.1046 +      apply - apply (rule ext)
 92.1047 +      unfolding poly_mult_assoc[symmetric] by (simp add: poly_mult)
 92.1048 +    hence ?ths unfolding divides_def by blast}
 92.1049 +  ultimately show ?ths by blast
 92.1050 +qed
 92.1051 +
 92.1052 +lemma nullstellensatz_univariate:
 92.1053 +  "(\<forall>x. poly p x = (0::complex) \<longrightarrow> poly q x = 0) \<longleftrightarrow> 
 92.1054 +    p divides (q %^ (degree p)) \<or> (poly p = poly [] \<and> poly q = poly [])"
 92.1055 +proof-
 92.1056 +  {assume pe: "poly p = poly []"
 92.1057 +    hence eq: "(\<forall>x. poly p x = (0::complex) \<longrightarrow> poly q x = 0) \<longleftrightarrow> poly q = poly []"
 92.1058 +      apply auto
 92.1059 +      by (rule ext, simp)
 92.1060 +    {assume "p divides (pexp q (degree p))"
 92.1061 +      then obtain r where r: "poly (pexp q (degree p)) = poly (pmult p r)" 
 92.1062 +	unfolding divides_def by blast
 92.1063 +      from cong[OF r refl] pe degree_unique[OF pe]
 92.1064 +      have False by (simp add: poly_mult degree_def)}
 92.1065 +    with eq pe have ?thesis by blast}
 92.1066 +  moreover
 92.1067 +  {assume pe: "poly p \<noteq> poly []"
 92.1068 +    have p0: "poly [0] = poly []" by (rule ext, simp)
 92.1069 +    {assume dp: "degree p = 0"
 92.1070 +      then obtain k where "pnormalize p = [k]" using pe poly_normalize[of p]
 92.1071 +	unfolding degree_def by (cases "pnormalize p", auto)
 92.1072 +      hence k: "pnormalize p = [k]" "poly p = poly [k]" "k\<noteq>0"
 92.1073 +	using pe poly_normalize[of p] by (auto simp add: p0)
 92.1074 +      hence th1: "\<forall>x. poly p x \<noteq> 0" by simp
 92.1075 +      from k(2,3) dp have "poly (pexp q (degree p)) = poly (pmult p [1/k]) "
 92.1076 +	by - (rule ext, simp add: poly_mult poly_exp)
 92.1077 +      hence th2: "p divides (pexp q (degree p))" unfolding divides_def by blast
 92.1078 +      from th1 th2 pe have ?thesis by blast}
 92.1079 +    moreover
 92.1080 +    {assume dp: "degree p \<noteq> 0"
 92.1081 +      then obtain n where n: "degree p = Suc n " by (cases "degree p", auto)
 92.1082 +      {assume "p divides (pexp q (Suc n))"
 92.1083 +	then obtain u where u: "poly (pexp q (Suc n)) = poly (pmult p u)"
 92.1084 +	  unfolding divides_def by blast
 92.1085 +	hence u' :"\<And>x. poly (pexp q (Suc n)) x = poly (pmult p u) x" by simp_all
 92.1086 +	{fix x assume h: "poly p x = 0" "poly q x \<noteq> 0"
 92.1087 +	  hence "poly (pexp q (Suc n)) x \<noteq> 0" by (simp only: poly_exp) simp	  
 92.1088 +	  hence False using u' h(1) by (simp only: poly_mult poly_exp) simp}}
 92.1089 +	with n nullstellensatz_lemma[of p q "degree p"] dp 
 92.1090 +	have ?thesis by auto}
 92.1091 +    ultimately have ?thesis by blast}
 92.1092 +  ultimately show ?thesis by blast
 92.1093 +qed
 92.1094 +
 92.1095 +text{* Useful lemma *}
 92.1096 +
 92.1097 +lemma (in idom_char_0) constant_degree: "constant (poly p) \<longleftrightarrow> degree p = 0" (is "?lhs = ?rhs")
 92.1098 +proof
 92.1099 +  assume l: ?lhs
 92.1100 +  from l[unfolded constant_def, rule_format, of _ "zero"]
 92.1101 +  have th: "poly p = poly [poly p 0]" apply - by (rule ext, simp)
 92.1102 +  from degree_unique[OF th] show ?rhs by (simp add: degree_def)
 92.1103 +next
 92.1104 +  assume r: ?rhs
 92.1105 +  from r have "pnormalize p = [] \<or> (\<exists>k. pnormalize p = [k])"
 92.1106 +    unfolding degree_def by (cases "pnormalize p", auto)
 92.1107 +  then show ?lhs unfolding constant_def poly_normalize[of p, symmetric]
 92.1108 +    by (auto simp del: poly_normalize)
 92.1109 +qed
 92.1110 +
 92.1111 +(* It would be nicer to prove this without using algebraic closure...        *)
 92.1112 +
 92.1113 +lemma divides_degree_lemma: assumes dpn: "degree (p::complex list) = n"
 92.1114 +  shows "n \<le> degree (p *** q) \<or> poly (p *** q) = poly []"
 92.1115 +  using dpn
 92.1116 +proof(induct n arbitrary: p q)
 92.1117 +  case 0 thus ?case by simp
 92.1118 +next
 92.1119 +  case (Suc n p q)
 92.1120 +  from Suc.prems fundamental_theorem_of_algebra[of p] constant_degree[of p]
 92.1121 +  obtain a where a: "poly p a = 0" by auto
 92.1122 +  then obtain r where r: "p = pmult [-a, 1] r" unfolding poly_linear_divides
 92.1123 +    using Suc.prems by (auto simp add: degree_def)
 92.1124 +  {assume h: "poly (pmult r q) = poly []"
 92.1125 +    hence "poly (pmult p q) = poly []" using r
 92.1126 +      apply - apply (rule ext)  by (auto simp add: poly_entire poly_mult poly_add poly_cmult) hence ?case by blast}
 92.1127 +  moreover
 92.1128 +  {assume h: "poly (pmult r q) \<noteq> poly []" 
 92.1129 +    hence r0: "poly r \<noteq> poly []" and q0: "poly q \<noteq> poly []"
 92.1130 +      by (auto simp add: poly_entire)
 92.1131 +    have eq: "poly (pmult p q) = poly (pmult [-a, 1] (pmult r q))"
 92.1132 +      apply - apply (rule ext)
 92.1133 +      by (simp add: r poly_mult poly_add poly_cmult ring_simps)
 92.1134 +    from linear_mul_degree[OF h, of "- a"]
 92.1135 +    have dqe: "degree (pmult p q) = degree (pmult r q) + 1"
 92.1136 +      unfolding degree_unique[OF eq] .
 92.1137 +    from linear_mul_degree[OF r0, of "- a", unfolded r[symmetric]] r Suc.prems 
 92.1138 +    have dr: "degree r = n" by auto
 92.1139 +    from  Suc.hyps[OF dr, of q] have "Suc n \<le> degree (pmult p q)"
 92.1140 +      unfolding dqe using h by (auto simp del: poly.simps) 
 92.1141 +    hence ?case by blast}
 92.1142 +  ultimately show ?case by blast
 92.1143 +qed
 92.1144 +
 92.1145 +lemma divides_degree: assumes pq: "p divides (q:: complex list)"
 92.1146 +  shows "degree p \<le> degree q \<or> poly q = poly []"
 92.1147 +using pq  divides_degree_lemma[OF refl, of p]
 92.1148 +apply (auto simp add: divides_def poly_entire)
 92.1149 +apply atomize
 92.1150 +apply (erule_tac x="qa" in allE, auto)
 92.1151 +apply (subgoal_tac "degree q = degree (p *** qa)", simp)
 92.1152 +apply (rule degree_unique, simp)
 92.1153 +done
 92.1154 +
 92.1155 +(* Arithmetic operations on multivariate polynomials.                        *)
 92.1156 +
 92.1157 +lemma mpoly_base_conv: 
 92.1158 +  "(0::complex) \<equiv> poly [] x" "c \<equiv> poly [c] x" "x \<equiv> poly [0,1] x" by simp_all
 92.1159 +
 92.1160 +lemma mpoly_norm_conv: 
 92.1161 +  "poly [0] (x::complex) \<equiv> poly [] x" "poly [poly [] y] x \<equiv> poly [] x" by simp_all
 92.1162 +
 92.1163 +lemma mpoly_sub_conv: 
 92.1164 +  "poly p (x::complex) - poly q x \<equiv> poly p x + -1 * poly q x"
 92.1165 +  by (simp add: diff_def)
 92.1166 +
 92.1167 +lemma poly_pad_rule: "poly p x = 0 ==> poly (0#p) x = (0::complex)" by simp
 92.1168 +
 92.1169 +lemma poly_cancel_eq_conv: "p = (0::complex) \<Longrightarrow> a \<noteq> 0 \<Longrightarrow> (q = 0) \<equiv> (a * q - b * p = 0)" apply (atomize (full)) by auto
 92.1170 +
 92.1171 +lemma resolve_eq_raw:  "poly [] x \<equiv> 0" "poly [c] x \<equiv> (c::complex)" by auto
 92.1172 +lemma  resolve_eq_then: "(P \<Longrightarrow> (Q \<equiv> Q1)) \<Longrightarrow> (\<not>P \<Longrightarrow> (Q \<equiv> Q2))
 92.1173 +  \<Longrightarrow> Q \<equiv> P \<and> Q1 \<or> \<not>P\<and> Q2" apply (atomize (full)) by blast 
 92.1174 +lemma expand_ex_beta_conv: "list_ex P [c] \<equiv> P c" by simp
 92.1175 +
 92.1176 +lemma poly_divides_pad_rule: 
 92.1177 +  fixes p q :: "complex list"
 92.1178 +  assumes pq: "p divides q"
 92.1179 +  shows "p divides ((0::complex)#q)"
 92.1180 +proof-
 92.1181 +  from pq obtain r where r: "poly q = poly (p *** r)" unfolding divides_def by blast
 92.1182 +  hence "poly (0#q) = poly (p *** ([0,1] *** r))" 
 92.1183 +    by - (rule ext, simp add: poly_mult poly_cmult poly_add)
 92.1184 +  thus ?thesis unfolding divides_def by blast
 92.1185 +qed
 92.1186 +
 92.1187 +lemma poly_divides_pad_const_rule: 
 92.1188 +  fixes p q :: "complex list"
 92.1189 +  assumes pq: "p divides q"
 92.1190 +  shows "p divides (a %* q)"
 92.1191 +proof-
 92.1192 +  from pq obtain r where r: "poly q = poly (p *** r)" unfolding divides_def by blast
 92.1193 +  hence "poly (a %* q) = poly (p *** (a %* r))" 
 92.1194 +    by - (rule ext, simp add: poly_mult poly_cmult poly_add)
 92.1195 +  thus ?thesis unfolding divides_def by blast
 92.1196 +qed
 92.1197 +
 92.1198 +
 92.1199 +lemma poly_divides_conv0:  
 92.1200 +  fixes p :: "complex list"
 92.1201 +  assumes lgpq: "length q < length p" and lq:"last p \<noteq> 0"
 92.1202 +  shows "p divides q \<equiv> (\<not> (list_ex (\<lambda>c. c \<noteq> 0) q))" (is "?lhs \<equiv> ?rhs")
 92.1203 +proof-
 92.1204 +  {assume r: ?rhs 
 92.1205 +    hence eq: "poly q = poly []" unfolding poly_zero 
 92.1206 +      by (simp add: list_all_iff list_ex_iff)
 92.1207 +    hence "poly q = poly (p *** [])" by - (rule ext, simp add: poly_mult)
 92.1208 +    hence ?lhs unfolding divides_def  by blast}
 92.1209 +  moreover
 92.1210 +  {assume l: ?lhs
 92.1211 +    have ath: "\<And>lq lp dq::nat. lq < lp ==> lq \<noteq> 0 \<Longrightarrow> dq <= lq - 1 ==> dq < lp - 1"
 92.1212 +      by arith
 92.1213 +    {assume q0: "length q = 0"
 92.1214 +      hence "q = []" by simp
 92.1215 +      hence ?rhs by simp}
 92.1216 +    moreover
 92.1217 +    {assume lgq0: "length q \<noteq> 0"
 92.1218 +      from pnormalize_length[of q] have dql: "degree q \<le> length q - 1" 
 92.1219 +	unfolding degree_def by simp
 92.1220 +      from ath[OF lgpq lgq0 dql, unfolded pnormal_degree[OF lq, symmetric]] divides_degree[OF l] have "poly q = poly []" by auto
 92.1221 +      hence ?rhs unfolding poly_zero by (simp add: list_all_iff list_ex_iff)}
 92.1222 +    ultimately have ?rhs by blast }
 92.1223 +  ultimately show "?lhs \<equiv> ?rhs" by - (atomize (full), blast) 
 92.1224 +qed
 92.1225 +
 92.1226 +lemma poly_divides_conv1: 
 92.1227 +  assumes a0: "a\<noteq> (0::complex)" and pp': "(p::complex list) divides p'"
 92.1228 +  and qrp': "\<And>x. a * poly q x - poly p' x \<equiv> poly r x"
 92.1229 +  shows "p divides q \<equiv> p divides (r::complex list)" (is "?lhs \<equiv> ?rhs")
 92.1230 +proof-
 92.1231 +  {
 92.1232 +  from pp' obtain t where t: "poly p' = poly (p *** t)" 
 92.1233 +    unfolding divides_def by blast
 92.1234 +  {assume l: ?lhs
 92.1235 +    then obtain u where u: "poly q = poly (p *** u)" unfolding divides_def by blast
 92.1236 +     have "poly r = poly (p *** ((a %* u) +++ (-- t)))"
 92.1237 +       using u qrp' t
 92.1238 +       by - (rule ext, 
 92.1239 +	 simp add: poly_add poly_mult poly_cmult poly_minus ring_simps)
 92.1240 +     then have ?rhs unfolding divides_def by blast}
 92.1241 +  moreover
 92.1242 +  {assume r: ?rhs
 92.1243 +    then obtain u where u: "poly r = poly (p *** u)" unfolding divides_def by blast
 92.1244 +    from u t qrp' a0 have "poly q = poly (p *** ((1/a) %* (u +++ t)))"
 92.1245 +      by - (rule ext, atomize (full), simp add: poly_mult poly_add poly_cmult field_simps)
 92.1246 +    hence ?lhs  unfolding divides_def by blast}
 92.1247 +  ultimately have "?lhs = ?rhs" by blast }
 92.1248 +thus "?lhs \<equiv> ?rhs"  by - (atomize(full), blast) 
 92.1249 +qed
 92.1250 +
 92.1251 +lemma basic_cqe_conv1:
 92.1252 +  "(\<exists>x. poly p x = 0 \<and> poly [] x \<noteq> 0) \<equiv> False"
 92.1253 +  "(\<exists>x. poly [] x \<noteq> 0) \<equiv> False"
 92.1254 +  "(\<exists>x. poly [c] x \<noteq> 0) \<equiv> c\<noteq>0"
 92.1255 +  "(\<exists>x. poly [] x = 0) \<equiv> True"
 92.1256 +  "(\<exists>x. poly [c] x = 0) \<equiv> c = 0" by simp_all
 92.1257 +
 92.1258 +lemma basic_cqe_conv2: 
 92.1259 +  assumes l:"last (a#b#p) \<noteq> 0" 
 92.1260 +  shows "(\<exists>x. poly (a#b#p) x = (0::complex)) \<equiv> True"
 92.1261 +proof-
 92.1262 +  {fix h t
 92.1263 +    assume h: "h\<noteq>0" "list_all (\<lambda>c. c=(0::complex)) t"  "a#b#p = h#t"
 92.1264 +    hence "list_all (\<lambda>c. c= 0) (b#p)" by simp
 92.1265 +    moreover have "last (b#p) \<in> set (b#p)" by simp
 92.1266 +    ultimately have "last (b#p) = 0" by (simp add: list_all_iff)
 92.1267 +    with l have False by simp}
 92.1268 +  hence th: "\<not> (\<exists> h t. h\<noteq>0 \<and> list_all (\<lambda>c. c=0) t \<and> a#b#p = h#t)"
 92.1269 +    by blast
 92.1270 +  from fundamental_theorem_of_algebra_alt[OF th] 
 92.1271 +  show "(\<exists>x. poly (a#b#p) x = (0::complex)) \<equiv> True" by auto
 92.1272 +qed
 92.1273 +
 92.1274 +lemma  basic_cqe_conv_2b: "(\<exists>x. poly p x \<noteq> (0::complex)) \<equiv> (list_ex (\<lambda>c. c \<noteq> 0) p)"
 92.1275 +proof-
 92.1276 +  have "\<not> (list_ex (\<lambda>c. c \<noteq> 0) p) \<longleftrightarrow> poly p = poly []" 
 92.1277 +    by (simp add: poly_zero list_all_iff list_ex_iff)
 92.1278 +  also have "\<dots> \<longleftrightarrow> (\<not> (\<exists>x. poly p x \<noteq> 0))" by (auto intro: ext)
 92.1279 +  finally show "(\<exists>x. poly p x \<noteq> (0::complex)) \<equiv> (list_ex (\<lambda>c. c \<noteq> 0) p)"
 92.1280 +    by - (atomize (full), blast)
 92.1281 +qed
 92.1282 +
 92.1283 +lemma basic_cqe_conv3:
 92.1284 +  fixes p q :: "complex list"
 92.1285 +  assumes l: "last (a#p) \<noteq> 0" 
 92.1286 +  shows "(\<exists>x. poly (a#p) x =0 \<and> poly q x \<noteq> 0) \<equiv> \<not> ((a#p) divides (q %^ (length p)))"
 92.1287 +proof-
 92.1288 +  note np = pnormalize_eq[OF l]
 92.1289 +  {assume "poly (a#p) = poly []" hence False using l
 92.1290 +      unfolding poly_zero apply (auto simp add: list_all_iff del: last.simps)
 92.1291 +      apply (cases p, simp_all) done}
 92.1292 +  then have p0: "poly (a#p) \<noteq> poly []"  by blast
 92.1293 +  from np have dp:"degree (a#p) = length p" by (simp add: degree_def)
 92.1294 +  from nullstellensatz_univariate[of "a#p" q] p0 dp
 92.1295 +  show "(\<exists>x. poly (a#p) x =0 \<and> poly q x \<noteq> 0) \<equiv> \<not> ((a#p) divides (q %^ (length p)))"
 92.1296 +    by - (atomize (full), auto)
 92.1297 +qed
 92.1298 +
 92.1299 +lemma basic_cqe_conv4:
 92.1300 +  fixes p q :: "complex list"
 92.1301 +  assumes h: "\<And>x. poly (q %^ n) x \<equiv> poly r x"
 92.1302 +  shows "p divides (q %^ n) \<equiv> p divides r"
 92.1303 +proof-
 92.1304 +  from h have "poly (q %^ n) = poly r" by (auto intro: ext)  
 92.1305 +  thus "p divides (q %^ n) \<equiv> p divides r" unfolding divides_def by simp
 92.1306 +qed
 92.1307 +
 92.1308 +lemma pmult_Cons_Cons: "((a::complex)#b#p) *** q = (a %*q) +++ (0#((b#p) *** q))"
 92.1309 +  by simp
 92.1310 +
 92.1311 +lemma elim_neg_conv: "- z \<equiv> (-1) * (z::complex)" by simp
 92.1312 +lemma eqT_intr: "PROP P \<Longrightarrow> (True \<Longrightarrow> PROP P )" "PROP P \<Longrightarrow> True" by blast+
 92.1313 +lemma negate_negate_rule: "Trueprop P \<equiv> \<not> P \<equiv> False" by (atomize (full), auto)
 92.1314 +lemma last_simps: "last [x] = x" "last (x#y#ys) = last (y#ys)" by simp_all
 92.1315 +lemma length_simps: "length [] = 0" "length (x#y#xs) = length xs + 2" "length [x] = 1" by simp_all
 92.1316 +
 92.1317 +lemma complex_entire: "(z::complex) \<noteq> 0 \<and> w \<noteq> 0 \<equiv> z*w \<noteq> 0" by simp
 92.1318 +lemma resolve_eq_ne: "(P \<equiv> True) \<equiv> (\<not>P \<equiv> False)" "(P \<equiv> False) \<equiv> (\<not>P \<equiv> True)" 
 92.1319 +  by (atomize (full)) simp_all
 92.1320 +lemma cqe_conv1: "poly [] x = 0 \<longleftrightarrow> True"  by simp
 92.1321 +lemma cqe_conv2: "(p \<Longrightarrow> (q \<equiv> r)) \<equiv> ((p \<and> q) \<equiv> (p \<and> r))"  (is "?l \<equiv> ?r")
 92.1322 +proof
 92.1323 +  assume "p \<Longrightarrow> q \<equiv> r" thus "p \<and> q \<equiv> p \<and> r" apply - apply (atomize (full)) by blast
 92.1324 +next
 92.1325 +  assume "p \<and> q \<equiv> p \<and> r" "p"
 92.1326 +  thus "q \<equiv> r" apply - apply (atomize (full)) apply blast done
 92.1327 +qed
 92.1328 +lemma poly_const_conv: "poly [c] (x::complex) = y \<longleftrightarrow> c = y" by simp
 92.1329 +
 92.1330 +end
 92.1331 \ No newline at end of file
    93.1 --- a/src/HOL/HOL.thy	Tue Dec 30 08:18:54 2008 +0100
    93.2 +++ b/src/HOL/HOL.thy	Tue Dec 30 11:10:01 2008 +0100
    93.3 @@ -26,6 +26,7 @@
    93.4    "~~/src/Tools/atomize_elim.ML"
    93.5    "~~/src/Tools/induct.ML"
    93.6    ("~~/src/Tools/induct_tacs.ML")
    93.7 +  "~~/src/Tools/value.ML"
    93.8    "~~/src/Tools/code/code_name.ML"
    93.9    "~~/src/Tools/code/code_funcgr.ML"
   93.10    "~~/src/Tools/code/code_thingol.ML"
    94.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    94.2 +++ b/src/HOL/HahnBanach/Bounds.thy	Tue Dec 30 11:10:01 2008 +0100
    94.3 @@ -0,0 +1,82 @@
    94.4 +(*  Title:      HOL/Real/HahnBanach/Bounds.thy
    94.5 +    Author:     Gertrud Bauer, TU Munich
    94.6 +*)
    94.7 +
    94.8 +header {* Bounds *}
    94.9 +
   94.10 +theory Bounds
   94.11 +imports Main ContNotDenum
   94.12 +begin
   94.13 +
   94.14 +locale lub =
   94.15 +  fixes A and x
   94.16 +  assumes least [intro?]: "(\<And>a. a \<in> A \<Longrightarrow> a \<le> b) \<Longrightarrow> x \<le> b"
   94.17 +    and upper [intro?]: "a \<in> A \<Longrightarrow> a \<le> x"
   94.18 +
   94.19 +lemmas [elim?] = lub.least lub.upper
   94.20 +
   94.21 +definition
   94.22 +  the_lub :: "'a::order set \<Rightarrow> 'a" where
   94.23 +  "the_lub A = The (lub A)"
   94.24 +
   94.25 +notation (xsymbols)
   94.26 +  the_lub  ("\<Squnion>_" [90] 90)
   94.27 +
   94.28 +lemma the_lub_equality [elim?]:
   94.29 +  assumes "lub A x"
   94.30 +  shows "\<Squnion>A = (x::'a::order)"
   94.31 +proof -
   94.32 +  interpret lub A x by fact
   94.33 +  show ?thesis
   94.34 +  proof (unfold the_lub_def)
   94.35 +    from `lub A x` show "The (lub A) = x"
   94.36 +    proof
   94.37 +      fix x' assume lub': "lub A x'"
   94.38 +      show "x' = x"
   94.39 +      proof (rule order_antisym)
   94.40 +	from lub' show "x' \<le> x"
   94.41 +	proof
   94.42 +          fix a assume "a \<in> A"
   94.43 +          then show "a \<le> x" ..
   94.44 +	qed
   94.45 +	show "x \<le> x'"
   94.46 +	proof
   94.47 +          fix a assume "a \<in> A"
   94.48 +          with lub' show "a \<le> x'" ..
   94.49 +	qed
   94.50 +      qed
   94.51 +    qed
   94.52 +  qed
   94.53 +qed
   94.54 +
   94.55 +lemma the_lubI_ex:
   94.56 +  assumes ex: "\<exists>x. lub A x"
   94.57 +  shows "lub A (\<Squnion>A)"
   94.58 +proof -
   94.59 +  from ex obtain x where x: "lub A x" ..
   94.60 +  also from x have [symmetric]: "\<Squnion>A = x" ..
   94.61 +  finally show ?thesis .
   94.62 +qed
   94.63 +
   94.64 +lemma lub_compat: "lub A x = isLub UNIV A x"
   94.65 +proof -
   94.66 +  have "isUb UNIV A = (\<lambda>x. A *<= x \<and> x \<in> UNIV)"
   94.67 +    by (rule ext) (simp only: isUb_def)
   94.68 +  then show ?thesis
   94.69 +    by (simp only: lub_def isLub_def leastP_def setge_def setle_def) blast
   94.70 +qed
   94.71 +
   94.72 +lemma real_complete:
   94.73 +  fixes A :: "real set"
   94.74 +  assumes nonempty: "\<exists>a. a \<in> A"
   94.75 +    and ex_upper: "\<exists>y. \<forall>a \<in> A. a \<le> y"
   94.76 +  shows "\<exists>x. lub A x"
   94.77 +proof -
   94.78 +  from ex_upper have "\<exists>y. isUb UNIV A y"
   94.79 +    unfolding isUb_def setle_def by blast
   94.80 +  with nonempty have "\<exists>x. isLub UNIV A x"
   94.81 +    by (rule reals_complete)
   94.82 +  then show ?thesis by (simp only: lub_compat)
   94.83 +qed
   94.84 +
   94.85 +end
    95.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    95.2 +++ b/src/HOL/HahnBanach/FunctionNorm.thy	Tue Dec 30 11:10:01 2008 +0100
    95.3 @@ -0,0 +1,278 @@
    95.4 +(*  Title:      HOL/Real/HahnBanach/FunctionNorm.thy
    95.5 +    Author:     Gertrud Bauer, TU Munich
    95.6 +*)
    95.7 +
    95.8 +header {* The norm of a function *}
    95.9 +
   95.10 +theory FunctionNorm
   95.11 +imports NormedSpace FunctionOrder
   95.12 +begin
   95.13 +
   95.14 +subsection {* Continuous linear forms*}
   95.15 +
   95.16 +text {*
   95.17 +  A linear form @{text f} on a normed vector space @{text "(V, \<parallel>\<cdot>\<parallel>)"}
   95.18 +  is \emph{continuous}, iff it is bounded, i.e.
   95.19 +  \begin{center}
   95.20 +  @{text "\<exists>c \<in> R. \<forall>x \<in> V. \<bar>f x\<bar> \<le> c \<cdot> \<parallel>x\<parallel>"}
   95.21 +  \end{center}
   95.22 +  In our application no other functions than linear forms are
   95.23 +  considered, so we can define continuous linear forms as bounded
   95.24 +  linear forms:
   95.25 +*}
   95.26 +
   95.27 +locale continuous = var_V + norm_syntax + linearform +
   95.28 +  assumes bounded: "\<exists>c. \<forall>x \<in> V. \<bar>f x\<bar> \<le> c * \<parallel>x\<parallel>"
   95.29 +
   95.30 +declare continuous.intro [intro?] continuous_axioms.intro [intro?]
   95.31 +
   95.32 +lemma continuousI [intro]:
   95.33 +  fixes norm :: "_ \<Rightarrow> real"  ("\<parallel>_\<parallel>")
   95.34 +  assumes "linearform V f"
   95.35 +  assumes r: "\<And>x. x \<in> V \<Longrightarrow> \<bar>f x\<bar> \<le> c * \<parallel>x\<parallel>"
   95.36 +  shows "continuous V norm f"
   95.37 +proof
   95.38 +  show "linearform V f" by fact
   95.39 +  from r have "\<exists>c. \<forall>x\<in>V. \<bar>f x\<bar> \<le> c * \<parallel>x\<parallel>" by blast
   95.40 +  then show "continuous_axioms V norm f" ..
   95.41 +qed
   95.42 +
   95.43 +
   95.44 +subsection {* The norm of a linear form *}
   95.45 +
   95.46 +text {*
   95.47 +  The least real number @{text c} for which holds
   95.48 +  \begin{center}
   95.49 +  @{text "\<forall>x \<in> V. \<bar>f x\<bar> \<le> c \<cdot> \<parallel>x\<parallel>"}
   95.50 +  \end{center}
   95.51 +  is called the \emph{norm} of @{text f}.
   95.52 +
   95.53 +  For non-trivial vector spaces @{text "V \<noteq> {0}"} the norm can be
   95.54 +  defined as
   95.55 +  \begin{center}
   95.56 +  @{text "\<parallel>f\<parallel> = \<sup>x \<noteq> 0. \<bar>f x\<bar> / \<parallel>x\<parallel>"}
   95.57 +  \end{center}
   95.58 +
   95.59 +  For the case @{text "V = {0}"} the supremum would be taken from an
   95.60 +  empty set. Since @{text \<real>} is unbounded, there would be no supremum.
   95.61 +  To avoid this situation it must be guaranteed that there is an
   95.62 +  element in this set. This element must be @{text "{} \<ge> 0"} so that
   95.63 +  @{text fn_norm} has the norm properties. Furthermore it does not
   95.64 +  have to change the norm in all other cases, so it must be @{text 0},
   95.65 +  as all other elements are @{text "{} \<ge> 0"}.
   95.66 +
   95.67 +  Thus we define the set @{text B} where the supremum is taken from as
   95.68 +  follows:
   95.69 +  \begin{center}
   95.70 +  @{text "{0} \<union> {\<bar>f x\<bar> / \<parallel>x\<parallel>. x \<noteq> 0 \<and> x \<in> F}"}
   95.71 +  \end{center}
   95.72 +
   95.73 +  @{text fn_norm} is equal to the supremum of @{text B}, if the
   95.74 +  supremum exists (otherwise it is undefined).
   95.75 +*}
   95.76 +
   95.77 +locale fn_norm = norm_syntax +
   95.78 +  fixes B defines "B V f \<equiv> {0} \<union> {\<bar>f x\<bar> / \<parallel>x\<parallel> | x. x \<noteq> 0 \<and> x \<in> V}"
   95.79 +  fixes fn_norm ("\<parallel>_\<parallel>\<hyphen>_" [0, 1000] 999)
   95.80 +  defines "\<parallel>f\<parallel>\<hyphen>V \<equiv> \<Squnion>(B V f)"
   95.81 +
   95.82 +locale normed_vectorspace_with_fn_norm = normed_vectorspace + fn_norm
   95.83 +
   95.84 +lemma (in fn_norm) B_not_empty [intro]: "0 \<in> B V f"
   95.85 +  by (simp add: B_def)
   95.86 +
   95.87 +text {*
   95.88 +  The following lemma states that every continuous linear form on a
   95.89 +  normed space @{text "(V, \<parallel>\<cdot>\<parallel>)"} has a function norm.
   95.90 +*}
   95.91 +
   95.92 +lemma (in normed_vectorspace_with_fn_norm) fn_norm_works:
   95.93 +  assumes "continuous V norm f"
   95.94 +  shows "lub (B V f) (\<parallel>f\<parallel>\<hyphen>V)"
   95.95 +proof -
   95.96 +  interpret continuous V norm f by fact
   95.97 +  txt {* The existence of the supremum is shown using the
   95.98 +    completeness of the reals. Completeness means, that every
   95.99 +    non-empty bounded set of reals has a supremum. *}
  95.100 +  have "\<exists>a. lub (B V f) a"
  95.101 +  proof (rule real_complete)
  95.102 +    txt {* First we have to show that @{text B} is non-empty: *}
  95.103 +    have "0 \<in> B V f" ..
  95.104 +    then show "\<exists>x. x \<in> B V f" ..
  95.105 +
  95.106 +    txt {* Then we have to show that @{text B} is bounded: *}
  95.107 +    show "\<exists>c. \<forall>y \<in> B V f. y \<le> c"
  95.108 +    proof -
  95.109 +      txt {* We know that @{text f} is bounded by some value @{text c}. *}
  95.110 +      from bounded obtain c where c: "\<forall>x \<in> V. \<bar>f x\<bar> \<le> c * \<parallel>x\<parallel>" ..
  95.111 +
  95.112 +      txt {* To prove the thesis, we have to show that there is some
  95.113 +        @{text b}, such that @{text "y \<le> b"} for all @{text "y \<in>
  95.114 +        B"}. Due to the definition of @{text B} there are two cases. *}
  95.115 +
  95.116 +      def b \<equiv> "max c 0"
  95.117 +      have "\<forall>y \<in> B V f. y \<le> b"
  95.118 +      proof
  95.119 +        fix y assume y: "y \<in> B V f"
  95.120 +        show "y \<le> b"
  95.121 +        proof cases
  95.122 +          assume "y = 0"
  95.123 +          then show ?thesis unfolding b_def by arith
  95.124 +        next
  95.125 +          txt {* The second case is @{text "y = \<bar>f x\<bar> / \<parallel>x\<parallel>"} for some
  95.126 +            @{text "x \<in> V"} with @{text "x \<noteq> 0"}. *}
  95.127 +          assume "y \<noteq> 0"
  95.128 +          with y obtain x where y_rep: "y = \<bar>f x\<bar> * inverse \<parallel>x\<parallel>"
  95.129 +              and x: "x \<in> V" and neq: "x \<noteq> 0"
  95.130 +            by (auto simp add: B_def real_divide_def)
  95.131 +          from x neq have gt: "0 < \<parallel>x\<parallel>" ..
  95.132 +
  95.133 +          txt {* The thesis follows by a short calculation using the
  95.134 +            fact that @{text f} is bounded. *}
  95.135 +
  95.136 +          note y_rep
  95.137 +          also have "\<bar>f x\<bar> * inverse \<parallel>x\<parallel> \<le> (c * \<parallel>x\<parallel>) * inverse \<parallel>x\<parallel>"
  95.138 +          proof (rule mult_right_mono)
  95.139 +            from c x show "\<bar>f x\<bar> \<le> c * \<parallel>x\<parallel>" ..
  95.140 +            from gt have "0 < inverse \<parallel>x\<parallel>" 
  95.141 +              by (rule positive_imp_inverse_positive)
  95.142 +            then show "0 \<le> inverse \<parallel>x\<parallel>" by (rule order_less_imp_le)
  95.143 +          qed
  95.144 +          also have "\<dots> = c * (\<parallel>x\<parallel> * inverse \<parallel>x\<parallel>)"
  95.145 +            by (rule real_mult_assoc)
  95.146 +          also
  95.147 +          from gt have "\<parallel>x\<parallel> \<noteq> 0" by simp
  95.148 +          then have "\<parallel>x\<parallel> * inverse \<parallel>x\<parallel> = 1" by simp 
  95.149 +          also have "c * 1 \<le> b" by (simp add: b_def le_maxI1)
  95.150 +          finally show "y \<le> b" .
  95.151 +        qed
  95.152 +      qed
  95.153 +      then show ?thesis ..
  95.154 +    qed
  95.155 +  qed
  95.156 +  then show ?thesis unfolding fn_norm_def by (rule the_lubI_ex)
  95.157 +qed
  95.158 +
  95.159 +lemma (in normed_vectorspace_with_fn_norm) fn_norm_ub [iff?]:
  95.160 +  assumes "continuous V norm f"
  95.161 +  assumes b: "b \<in> B V f"
  95.162 +  shows "b \<le> \<parallel>f\<parallel>\<hyphen>V"
  95.163 +proof -
  95.164 +  interpret continuous V norm f by fact
  95.165 +  have "lub (B V f) (\<parallel>f\<parallel>\<hyphen>V)"
  95.166 +    using `continuous V norm f` by (rule fn_norm_works)
  95.167 +  from this and b show ?thesis ..
  95.168 +qed
  95.169 +
  95.170 +lemma (in normed_vectorspace_with_fn_norm) fn_norm_leastB:
  95.171 +  assumes "continuous V norm f"
  95.172 +  assumes b: "\<And>b. b \<in> B V f \<Longrightarrow> b \<le> y"
  95.173 +  shows "\<parallel>f\<parallel>\<hyphen>V \<le> y"
  95.174 +proof -
  95.175 +  interpret continuous V norm f by fact
  95.176 +  have "lub (B V f) (\<parallel>f\<parallel>\<hyphen>V)"
  95.177 +    using `continuous V norm f` by (rule fn_norm_works)
  95.178 +  from this and b show ?thesis ..
  95.179 +qed
  95.180 +
  95.181 +text {* The norm of a continuous function is always @{text "\<ge> 0"}. *}
  95.182 +
  95.183 +lemma (in normed_vectorspace_with_fn_norm) fn_norm_ge_zero [iff]:
  95.184 +  assumes "continuous V norm f"
  95.185 +  shows "0 \<le> \<parallel>f\<parallel>\<hyphen>V"
  95.186 +proof -
  95.187 +  interpret continuous V norm f by fact
  95.188 +  txt {* The function norm is defined as the supremum of @{text B}.
  95.189 +    So it is @{text "\<ge> 0"} if all elements in @{text B} are @{text "\<ge>
  95.190 +    0"}, provided the supremum exists and @{text B} is not empty. *}
  95.191 +  have "lub (B V f) (\<parallel>f\<parallel>\<hyphen>V)"
  95.192 +    using `continuous V norm f` by (rule fn_norm_works)
  95.193 +  moreover have "0 \<in> B V f" ..
  95.194 +  ultimately show ?thesis ..
  95.195 +qed
  95.196 +
  95.197 +text {*
  95.198 +  \medskip The fundamental property of function norms is:
  95.199 +  \begin{center}
  95.200 +  @{text "\<bar>f x\<bar> \<le> \<parallel>f\<parallel> \<cdot> \<parallel>x\<parallel>"}
  95.201 +  \end{center}
  95.202 +*}
  95.203 +
  95.204 +lemma (in normed_vectorspace_with_fn_norm) fn_norm_le_cong:
  95.205 +  assumes "continuous V norm f" "linearform V f"
  95.206 +  assumes x: "x \<in> V"
  95.207 +  shows "\<bar>f x\<bar> \<le> \<parallel>f\<parallel>\<hyphen>V * \<parallel>x\<parallel>"
  95.208 +proof -
  95.209 +  interpret continuous V norm f by fact
  95.210 +  interpret linearform V f .
  95.211 +  show ?thesis
  95.212 +  proof cases
  95.213 +    assume "x = 0"
  95.214 +    then have "\<bar>f x\<bar> = \<bar>f 0\<bar>" by simp
  95.215 +    also have "f 0 = 0" by rule unfold_locales
  95.216 +    also have "\<bar>\<dots>\<bar> = 0" by simp
  95.217 +    also have a: "0 \<le> \<parallel>f\<parallel>\<hyphen>V"
  95.218 +      using `continuous V norm f` by (rule fn_norm_ge_zero)
  95.219 +    from x have "0 \<le> norm x" ..
  95.220 +    with a have "0 \<le> \<parallel>f\<parallel>\<hyphen>V * \<parallel>x\<parallel>" by (simp add: zero_le_mult_iff)
  95.221 +    finally show "\<bar>f x\<bar> \<le> \<parallel>f\<parallel>\<hyphen>V * \<parallel>x\<parallel>" .
  95.222 +  next
  95.223 +    assume "x \<noteq> 0"
  95.224 +    with x have neq: "\<parallel>x\<parallel> \<noteq> 0" by simp
  95.225 +    then have "\<bar>f x\<bar> = (\<bar>f x\<bar> * inverse \<parallel>x\<parallel>) * \<parallel>x\<parallel>" by simp
  95.226 +    also have "\<dots> \<le>  \<parallel>f\<parallel>\<hyphen>V * \<parallel>x\<parallel>"
  95.227 +    proof (rule mult_right_mono)
  95.228 +      from x show "0 \<le> \<parallel>x\<parallel>" ..
  95.229 +      from x and neq have "\<bar>f x\<bar> * inverse \<parallel>x\<parallel> \<in> B V f"
  95.230 +	by (auto simp add: B_def real_divide_def)
  95.231 +      with `continuous V norm f` show "\<bar>f x\<bar> * inverse \<parallel>x\<parallel> \<le> \<parallel>f\<parallel>\<hyphen>V"
  95.232 +	by (rule fn_norm_ub)
  95.233 +    qed
  95.234 +    finally show ?thesis .
  95.235 +  qed
  95.236 +qed
  95.237 +
  95.238 +text {*
  95.239 +  \medskip The function norm is the least positive real number for
  95.240 +  which the following inequation holds:
  95.241 +  \begin{center}
  95.242 +    @{text "\<bar>f x\<bar> \<le> c \<cdot> \<parallel>x\<parallel>"}
  95.243 +  \end{center}
  95.244 +*}
  95.245 +
  95.246 +lemma (in normed_vectorspace_with_fn_norm) fn_norm_least [intro?]:
  95.247 +  assumes "continuous V norm f"
  95.248 +  assumes ineq: "\<forall>x \<in> V. \<bar>f x\<bar> \<le> c * \<parallel>x\<parallel>" and ge: "0 \<le> c"
  95.249 +  shows "\<parallel>f\<parallel>\<hyphen>V \<le> c"
  95.250 +proof -
  95.251 +  interpret continuous V norm f by fact
  95.252 +  show ?thesis
  95.253 +  proof (rule fn_norm_leastB [folded B_def fn_norm_def])
  95.254 +    fix b assume b: "b \<in> B V f"
  95.255 +    show "b \<le> c"
  95.256 +    proof cases
  95.257 +      assume "b = 0"
  95.258 +      with ge show ?thesis by simp
  95.259 +    next
  95.260 +      assume "b \<noteq> 0"
  95.261 +      with b obtain x where b_rep: "b = \<bar>f x\<bar> * inverse \<parallel>x\<parallel>"
  95.262 +        and x_neq: "x \<noteq> 0" and x: "x \<in> V"
  95.263 +	by (auto simp add: B_def real_divide_def)
  95.264 +      note b_rep
  95.265 +      also have "\<bar>f x\<bar> * inverse \<parallel>x\<parallel> \<le> (c * \<parallel>x\<parallel>) * inverse \<parallel>x\<parallel>"
  95.266 +      proof (rule mult_right_mono)
  95.267 +	have "0 < \<parallel>x\<parallel>" using x x_neq ..
  95.268 +	then show "0 \<le> inverse \<parallel>x\<parallel>" by simp
  95.269 +	from ineq and x show "\<bar>f x\<bar> \<le> c * \<parallel>x\<parallel>" ..
  95.270 +      qed
  95.271 +      also have "\<dots> = c"
  95.272 +      proof -
  95.273 +	from x_neq and x have "\<parallel>x\<parallel> \<noteq> 0" by simp
  95.274 +	then show ?thesis by simp
  95.275 +      qed
  95.276 +      finally show ?thesis .
  95.277 +    qed
  95.278 +  qed (insert `continuous V norm f`, simp_all add: continuous_def)
  95.279 +qed
  95.280 +
  95.281 +end
    96.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    96.2 +++ b/src/HOL/HahnBanach/FunctionOrder.thy	Tue Dec 30 11:10:01 2008 +0100
    96.3 @@ -0,0 +1,142 @@
    96.4 +(*  Title:      HOL/Real/HahnBanach/FunctionOrder.thy
    96.5 +    ID:         $Id$
    96.6 +    Author:     Gertrud Bauer, TU Munich
    96.7 +*)
    96.8 +
    96.9 +header {* An order on functions *}
   96.10 +
   96.11 +theory FunctionOrder
   96.12 +imports Subspace Linearform
   96.13 +begin
   96.14 +
   96.15 +subsection {* The graph of a function *}
   96.16 +
   96.17 +text {*
   96.18 +  We define the \emph{graph} of a (real) function @{text f} with
   96.19 +  domain @{text F} as the set
   96.20 +  \begin{center}
   96.21 +  @{text "{(x, f x). x \<in> F}"}
   96.22 +  \end{center}
   96.23 +  So we are modeling partial functions by specifying the domain and
   96.24 +  the mapping function. We use the term ``function'' also for its
   96.25 +  graph.
   96.26 +*}
   96.27 +
   96.28 +types 'a graph = "('a \<times> real) set"
   96.29 +
   96.30 +definition
   96.31 +  graph :: "'a set \<Rightarrow> ('a \<Rightarrow> real) \<Rightarrow> 'a graph" where
   96.32 +  "graph F f = {(x, f x) | x. x \<in> F}"
   96.33 +
   96.34 +lemma graphI [intro]: "x \<in> F \<Longrightarrow> (x, f x) \<in> graph F f"
   96.35 +  unfolding graph_def by blast
   96.36 +
   96.37 +lemma graphI2 [intro?]: "x \<in> F \<Longrightarrow> \<exists>t \<in> graph F f. t = (x, f x)"
   96.38 +  unfolding graph_def by blast
   96.39 +
   96.40 +lemma graphE [elim?]:
   96.41 +    "(x, y) \<in> graph F f \<Longrightarrow> (x \<in> F \<Longrightarrow> y = f x \<Longrightarrow> C) \<Longrightarrow> C"
   96.42 +  unfolding graph_def by blast
   96.43 +
   96.44 +
   96.45 +subsection {* Functions ordered by domain extension *}
   96.46 +
   96.47 +text {*
   96.48 +  A function @{text h'} is an extension of @{text h}, iff the graph of
   96.49 +  @{text h} is a subset of the graph of @{text h'}.
   96.50 +*}
   96.51 +
   96.52 +lemma graph_extI:
   96.53 +  "(\<And>x. x \<in> H \<Longrightarrow> h x = h' x) \<Longrightarrow> H \<subseteq> H'
   96.54 +    \<Longrightarrow> graph H h \<subseteq> graph H' h'"
   96.55 +  unfolding graph_def by blast
   96.56 +
   96.57 +lemma graph_extD1 [dest?]:
   96.58 +  "graph H h \<subseteq> graph H' h' \<Longrightarrow> x \<in> H \<Longrightarrow> h x = h' x"
   96.59 +  unfolding graph_def by blast
   96.60 +
   96.61 +lemma graph_extD2 [dest?]:
   96.62 +  "graph H h \<subseteq> graph H' h' \<Longrightarrow> H \<subseteq> H'"
   96.63 +  unfolding graph_def by blast
   96.64 +
   96.65 +
   96.66 +subsection {* Domain and function of a graph *}
   96.67 +
   96.68 +text {*
   96.69 +  The inverse functions to @{text graph} are @{text domain} and @{text
   96.70 +  funct}.
   96.71 +*}
   96.72 +
   96.73 +definition
   96.74 +  "domain" :: "'a graph \<Rightarrow> 'a set" where
   96.75 +  "domain g = {x. \<exists>y. (x, y) \<in> g}"
   96.76 +
   96.77 +definition
   96.78 +  funct :: "'a graph \<Rightarrow> ('a \<Rightarrow> real)" where
   96.79 +  "funct g = (\<lambda>x. (SOME y. (x, y) \<in> g))"
   96.80 +
   96.81 +text {*
   96.82 +  The following lemma states that @{text g} is the graph of a function
   96.83 +  if the relation induced by @{text g} is unique.
   96.84 +*}
   96.85 +
   96.86 +lemma graph_domain_funct:
   96.87 +  assumes uniq: "\<And>x y z. (x, y) \<in> g \<Longrightarrow> (x, z) \<in> g \<Longrightarrow> z = y"
   96.88 +  shows "graph (domain g) (funct g) = g"
   96.89 +  unfolding domain_def funct_def graph_def
   96.90 +proof auto  (* FIXME !? *)
   96.91 +  fix a b assume g: "(a, b) \<in> g"
   96.92 +  from g show "(a, SOME y. (a, y) \<in> g) \<in> g" by (rule someI2)
   96.93 +  from g show "\<exists>y. (a, y) \<in> g" ..
   96.94 +  from g show "b = (SOME y. (a, y) \<in> g)"
   96.95 +  proof (rule some_equality [symmetric])
   96.96 +    fix y assume "(a, y) \<in> g"
   96.97 +    with g show "y = b" by (rule uniq)
   96.98 +  qed
   96.99 +qed
  96.100 +
  96.101 +
  96.102 +subsection {* Norm-preserving extensions of a function *}
  96.103 +
  96.104 +text {*
  96.105 +  Given a linear form @{text f} on the space @{text F} and a seminorm
  96.106 +  @{text p} on @{text E}. The set of all linear extensions of @{text
  96.107 +  f}, to superspaces @{text H} of @{text F}, which are bounded by
  96.108 +  @{text p}, is defined as follows.
  96.109 +*}
  96.110 +
  96.111 +definition
  96.112 +  norm_pres_extensions ::
  96.113 +    "'a::{plus, minus, uminus, zero} set \<Rightarrow> ('a \<Rightarrow> real) \<Rightarrow> 'a set \<Rightarrow> ('a \<Rightarrow> real)
  96.114 +      \<Rightarrow> 'a graph set" where
  96.115 +    "norm_pres_extensions E p F f
  96.116 +      = {g. \<exists>H h. g = graph H h
  96.117 +          \<and> linearform H h
  96.118 +          \<and> H \<unlhd> E
  96.119 +          \<and> F \<unlhd> H
  96.120 +          \<and> graph F f \<subseteq> graph H h
  96.121 +          \<and> (\<forall>x \<in> H. h x \<le> p x)}"
  96.122 +
  96.123 +lemma norm_pres_extensionE [elim]:
  96.124 +  "g \<in> norm_pres_extensions E p F f
  96.125 +  \<Longrightarrow> (\<And>H h. g = graph H h \<Longrightarrow> linearform H h
  96.126 +        \<Longrightarrow> H \<unlhd> E \<Longrightarrow> F \<unlhd> H \<Longrightarrow> graph F f \<subseteq> graph H h
  96.127 +        \<Longrightarrow> \<forall>x \<in> H. h x \<le> p x \<Longrightarrow> C) \<Longrightarrow> C"
  96.128 +  unfolding norm_pres_extensions_def by blast
  96.129 +
  96.130 +lemma norm_pres_extensionI2 [intro]:
  96.131 +  "linearform H h \<Longrightarrow> H \<unlhd> E \<Longrightarrow> F \<unlhd> H
  96.132 +    \<Longrightarrow> graph F f \<subseteq> graph H h \<Longrightarrow> \<forall>x \<in> H. h x \<le> p x
  96.133 +    \<Longrightarrow> graph H h \<in> norm_pres_extensions E p F f"
  96.134 +  unfolding norm_pres_extensions_def by blast
  96.135 +
  96.136 +lemma norm_pres_extensionI:  (* FIXME ? *)
  96.137 +  "\<exists>H h. g = graph H h
  96.138 +    \<and> linearform H h
  96.139 +    \<and> H \<unlhd> E
  96.140 +    \<and> F \<unlhd> H
  96.141 +    \<and> graph F f \<subseteq> graph H h
  96.142 +    \<and> (\<forall>x \<in> H. h x \<le> p x) \<Longrightarrow> g \<in> norm_pres_extensions E p F f"
  96.143 +  unfolding norm_pres_extensions_def by blast
  96.144 +
  96.145 +end
    97.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    97.2 +++ b/src/HOL/HahnBanach/HahnBanach.thy	Tue Dec 30 11:10:01 2008 +0100
    97.3 @@ -0,0 +1,509 @@
    97.4 +(*  Title:      HOL/Real/HahnBanach/HahnBanach.thy
    97.5 +    Author:     Gertrud Bauer, TU Munich
    97.6 +*)
    97.7 +
    97.8 +header {* The Hahn-Banach Theorem *}
    97.9 +
   97.10 +theory HahnBanach
   97.11 +imports HahnBanachLemmas
   97.12 +begin
   97.13 +
   97.14 +text {*
   97.15 +  We present the proof of two different versions of the Hahn-Banach
   97.16 +  Theorem, closely following \cite[\S36]{Heuser:1986}.
   97.17 +*}
   97.18 +
   97.19 +subsection {* The Hahn-Banach Theorem for vector spaces *}
   97.20 +
   97.21 +text {*
   97.22 +  \textbf{Hahn-Banach Theorem.} Let @{text F} be a subspace of a real
   97.23 +  vector space @{text E}, let @{text p} be a semi-norm on @{text E},
   97.24 +  and @{text f} be a linear form defined on @{text F} such that @{text
   97.25 +  f} is bounded by @{text p}, i.e.  @{text "\<forall>x \<in> F. f x \<le> p x"}.  Then
   97.26 +  @{text f} can be extended to a linear form @{text h} on @{text E}
   97.27 +  such that @{text h} is norm-preserving, i.e. @{text h} is also
   97.28 +  bounded by @{text p}.
   97.29 +
   97.30 +  \bigskip
   97.31 +  \textbf{Proof Sketch.}
   97.32 +  \begin{enumerate}
   97.33 +
   97.34 +  \item Define @{text M} as the set of norm-preserving extensions of
   97.35 +  @{text f} to subspaces of @{text E}. The linear forms in @{text M}
   97.36 +  are ordered by domain extension.
   97.37 +
   97.38 +  \item We show that every non-empty chain in @{text M} has an upper
   97.39 +  bound in @{text M}.
   97.40 +
   97.41 +  \item With Zorn's Lemma we conclude that there is a maximal function
   97.42 +  @{text g} in @{text M}.
   97.43 +
   97.44 +  \item The domain @{text H} of @{text g} is the whole space @{text
   97.45 +  E}, as shown by classical contradiction:
   97.46 +
   97.47 +  \begin{itemize}
   97.48 +
   97.49 +  \item Assuming @{text g} is not defined on whole @{text E}, it can
   97.50 +  still be extended in a norm-preserving way to a super-space @{text
   97.51 +  H'} of @{text H}.
   97.52 +
   97.53 +  \item Thus @{text g} can not be maximal. Contradiction!
   97.54 +
   97.55 +  \end{itemize}
   97.56 +  \end{enumerate}
   97.57 +*}
   97.58 +
   97.59 +theorem HahnBanach:
   97.60 +  assumes E: "vectorspace E" and "subspace F E"
   97.61 +    and "seminorm E p" and "linearform F f"
   97.62 +  assumes fp: "\<forall>x \<in> F. f x \<le> p x"
   97.63 +  shows "\<exists>h. linearform E h \<and> (\<forall>x \<in> F. h x = f x) \<and> (\<forall>x \<in> E. h x \<le> p x)"
   97.64 +    -- {* Let @{text E} be a vector space, @{text F} a subspace of @{text E}, @{text p} a seminorm on @{text E}, *}
   97.65 +    -- {* and @{text f} a linear form on @{text F} such that @{text f} is bounded by @{text p}, *}
   97.66 +    -- {* then @{text f} can be extended to a linear form @{text h} on @{text E} in a norm-preserving way. \skp *}
   97.67 +proof -
   97.68 +  interpret vectorspace E by fact
   97.69 +  interpret subspace F E by fact
   97.70 +  interpret seminorm E p by fact
   97.71 +  interpret linearform F f by fact
   97.72 +  def M \<equiv> "norm_pres_extensions E p F f"
   97.73 +  then have M: "M = \<dots>" by (simp only:)
   97.74 +  from E have F: "vectorspace F" ..
   97.75 +  note FE = `F \<unlhd> E`
   97.76 +  {
   97.77 +    fix c assume cM: "c \<in> chain M" and ex: "\<exists>x. x \<in> c"
   97.78 +    have "\<Union>c \<in> M"
   97.79 +      -- {* Show that every non-empty chain @{text c} of @{text M} has an upper bound in @{text M}: *}
   97.80 +      -- {* @{text "\<Union>c"} is greater than any element of the chain @{text c}, so it suffices to show @{text "\<Union>c \<in> M"}. *}
   97.81 +      unfolding M_def
   97.82 +    proof (rule norm_pres_extensionI)
   97.83 +      let ?H = "domain (\<Union>c)"
   97.84 +      let ?h = "funct (\<Union>c)"
   97.85 +
   97.86 +      have a: "graph ?H ?h = \<Union>c"
   97.87 +      proof (rule graph_domain_funct)
   97.88 +        fix x y z assume "(x, y) \<in> \<Union>c" and "(x, z) \<in> \<Union>c"
   97.89 +        with M_def cM show "z = y" by (rule sup_definite)
   97.90 +      qed
   97.91 +      moreover from M cM a have "linearform ?H ?h"
   97.92 +        by (rule sup_lf)
   97.93 +      moreover from a M cM ex FE E have "?H \<unlhd> E"
   97.94 +        by (rule sup_subE)
   97.95 +      moreover from a M cM ex FE have "F \<unlhd> ?H"
   97.96 +        by (rule sup_supF)
   97.97 +      moreover from a M cM ex have "graph F f \<subseteq> graph ?H ?h"
   97.98 +        by (rule sup_ext)
   97.99 +      moreover from a M cM have "\<forall>x \<in> ?H. ?h x \<le> p x"
  97.100 +        by (rule sup_norm_pres)
  97.101 +      ultimately show "\<exists>H h. \<Union>c = graph H h
  97.102 +          \<and> linearform H h
  97.103 +          \<and> H \<unlhd> E
  97.104 +          \<and> F \<unlhd> H
  97.105 +          \<and> graph F f \<subseteq> graph H h
  97.106 +          \<and> (\<forall>x \<in> H. h x \<le> p x)" by blast
  97.107 +    qed
  97.108 +  }
  97.109 +  then have "\<exists>g \<in> M. \<forall>x \<in> M. g \<subseteq> x \<longrightarrow> g = x"
  97.110 +  -- {* With Zorn's Lemma we can conclude that there is a maximal element in @{text M}. \skp *}
  97.111 +  proof (rule Zorn's_Lemma)
  97.112 +      -- {* We show that @{text M} is non-empty: *}
  97.113 +    show "graph F f \<in> M"
  97.114 +      unfolding M_def
  97.115 +    proof (rule norm_pres_extensionI2)
  97.116 +      show "linearform F f" by fact
  97.117 +      show "F \<unlhd> E" by fact
  97.118 +      from F show "F \<unlhd> F" by (rule vectorspace.subspace_refl)
  97.119 +      show "graph F f \<subseteq> graph F f" ..
  97.120 +      show "\<forall>x\<in>F. f x \<le> p x" by fact
  97.121 +    qed
  97.122 +  qed
  97.123 +  then obtain g where gM: "g \<in> M" and gx: "\<forall>x \<in> M. g \<subseteq> x \<longrightarrow> g = x"
  97.124 +    by blast
  97.125 +  from gM obtain H h where
  97.126 +      g_rep: "g = graph H h"
  97.127 +    and linearform: "linearform H h"
  97.128 +    and HE: "H \<unlhd> E" and FH: "F \<unlhd> H"
  97.129 +    and graphs: "graph F f \<subseteq> graph H h"
  97.130 +    and hp: "\<forall>x \<in> H. h x \<le> p x" unfolding M_def ..
  97.131 +      -- {* @{text g} is a norm-preserving extension of @{text f}, in other words: *}
  97.132 +      -- {* @{text g} is the graph of some linear form @{text h} defined on a subspace @{text H} of @{text E}, *}
  97.133 +      -- {* and @{text h} is an extension of @{text f} that is again bounded by @{text p}. \skp *}
  97.134 +  from HE E have H: "vectorspace H"
  97.135 +    by (rule subspace.vectorspace)
  97.136 +
  97.137 +  have HE_eq: "H = E"
  97.138 +    -- {* We show that @{text h} is defined on whole @{text E} by classical contradiction. \skp *}
  97.139 +  proof (rule classical)
  97.140 +    assume neq: "H \<noteq> E"
  97.141 +      -- {* Assume @{text h} is not defined on whole @{text E}. Then show that @{text h} can be extended *}
  97.142 +      -- {* in a norm-preserving way to a function @{text h'} with the graph @{text g'}. \skp *}
  97.143 +    have "\<exists>g' \<in> M. g \<subseteq> g' \<and> g \<noteq> g'"
  97.144 +    proof -
  97.145 +      from HE have "H \<subseteq> E" ..
  97.146 +      with neq obtain x' where x'E: "x' \<in> E" and "x' \<notin> H" by blast
  97.147 +      obtain x': "x' \<noteq> 0"
  97.148 +      proof
  97.149 +        show "x' \<noteq> 0"
  97.150 +        proof
  97.151 +          assume "x' = 0"
  97.152 +          with H have "x' \<in> H" by (simp only: vectorspace.zero)
  97.153 +          with `x' \<notin> H` show False by contradiction
  97.154 +        qed
  97.155 +      qed
  97.156 +
  97.157 +      def H' \<equiv> "H + lin x'"
  97.158 +        -- {* Define @{text H'} as the direct sum of @{text H} and the linear closure of @{text x'}. \skp *}
  97.159 +      have HH': "H \<unlhd> H'"
  97.160 +      proof (unfold H'_def)
  97.161 +        from x'E have "vectorspace (lin x')" ..
  97.162 +        with H show "H \<unlhd> H + lin x'" ..
  97.163 +      qed
  97.164 +
  97.165 +      obtain xi where
  97.166 +        xi: "\<forall>y \<in> H. - p (y + x') - h y \<le> xi
  97.167 +          \<and> xi \<le> p (y + x') - h y"
  97.168 +        -- {* Pick a real number @{text \<xi>} that fulfills certain inequations; this will *}
  97.169 +        -- {* be used to establish that @{text h'} is a norm-preserving extension of @{text h}.
  97.170 +           \label{ex-xi-use}\skp *}
  97.171 +      proof -
  97.172 +        from H have "\<exists>xi. \<forall>y \<in> H. - p (y + x') - h y \<le> xi
  97.173 +            \<and> xi \<le> p (y + x') - h y"
  97.174 +        proof (rule ex_xi)
  97.175 +          fix u v assume u: "u \<in> H" and v: "v \<in> H"
  97.176 +          with HE have uE: "u \<in> E" and vE: "v \<in> E" by auto
  97.177 +          from H u v linearform have "h v - h u = h (v - u)"
  97.178 +            by (simp add: linearform.diff)
  97.179 +          also from hp and H u v have "\<dots> \<le> p (v - u)"
  97.180 +            by (simp only: vectorspace.diff_closed)
  97.181 +          also from x'E uE vE have "v - u = x' + - x' + v + - u"
  97.182 +            by (simp add: diff_eq1)
  97.183 +          also from x'E uE vE have "\<dots> = v + x' + - (u + x')"
  97.184 +            by (simp add: add_ac)
  97.185 +          also from x'E uE vE have "\<dots> = (v + x') - (u + x')"
  97.186 +            by (simp add: diff_eq1)
  97.187 +          also from x'E uE vE E have "p \<dots> \<le> p (v + x') + p (u + x')"
  97.188 +            by (simp add: diff_subadditive)
  97.189 +          finally have "h v - h u \<le> p (v + x') + p (u + x')" .
  97.190 +          then show "- p (u + x') - h u \<le> p (v + x') - h v" by simp
  97.191 +        qed
  97.192 +        then show thesis by (blast intro: that)
  97.193 +      qed
  97.194 +
  97.195 +      def h' \<equiv> "\<lambda>x. let (y, a) =
  97.196 +          SOME (y, a). x = y + a \<cdot> x' \<and> y \<in> H in h y + a * xi"
  97.197 +        -- {* Define the extension @{text h'} of @{text h} to @{text H'} using @{text \<xi>}. \skp *}
  97.198 +
  97.199 +      have "g \<subseteq> graph H' h' \<and> g \<noteq> graph H' h'"
  97.200 +        -- {* @{text h'} is an extension of @{text h} \dots \skp *}
  97.201 +      proof
  97.202 +        show "g \<subseteq> graph H' h'"
  97.203 +        proof -
  97.204 +          have  "graph H h \<subseteq> graph H' h'"
  97.205 +          proof (rule graph_extI)
  97.206 +            fix t assume t: "t \<in> H"
  97.207 +            from E HE t have "(SOME (y, a). t = y + a \<cdot> x' \<and> y \<in> H) = (t, 0)"
  97.208 +	      using `x' \<notin> H` `x' \<in> E` `x' \<noteq> 0` by (rule decomp_H'_H)
  97.209 +            with h'_def show "h t = h' t" by (simp add: Let_def)
  97.210 +          next
  97.211 +            from HH' show "H \<subseteq> H'" ..
  97.212 +          qed
  97.213 +          with g_rep show ?thesis by (simp only:)
  97.214 +        qed
  97.215 +
  97.216 +        show "g \<noteq> graph H' h'"
  97.217 +        proof -
  97.218 +          have "graph H h \<noteq> graph H' h'"
  97.219 +          proof
  97.220 +            assume eq: "graph H h = graph H' h'"
  97.221 +            have "x' \<in> H'"
  97.222 +	      unfolding H'_def
  97.223 +            proof
  97.224 +              from H show "0 \<in> H" by (rule vectorspace.zero)
  97.225 +              from x'E show "x' \<in> lin x'" by (rule x_lin_x)
  97.226 +              from x'E show "x' = 0 + x'" by simp
  97.227 +            qed
  97.228 +            then have "(x', h' x') \<in> graph H' h'" ..
  97.229 +            with eq have "(x', h' x') \<in> graph H h" by (simp only:)
  97.230 +            then have "x' \<in> H" ..
  97.231 +            with `x' \<notin> H` show False by contradiction
  97.232 +          qed
  97.233 +          with g_rep show ?thesis by simp
  97.234 +        qed
  97.235 +      qed
  97.236 +      moreover have "graph H' h' \<in> M"
  97.237 +        -- {* and @{text h'} is norm-preserving. \skp *}
  97.238 +      proof (unfold M_def)
  97.239 +        show "graph H' h' \<in> norm_pres_extensions E p F f"
  97.240 +        proof (rule norm_pres_extensionI2)
  97.241 +          show "linearform H' h'"
  97.242 +	    using h'_def H'_def HE linearform `x' \<notin> H` `x' \<in> E` `x' \<noteq> 0` E
  97.243 +	    by (rule h'_lf)
  97.244 +          show "H' \<unlhd> E"
  97.245 +	  unfolding H'_def
  97.246 +          proof
  97.247 +            show "H \<unlhd> E" by fact
  97.248 +            show "vectorspace E" by fact
  97.249 +            from x'E show "lin x' \<unlhd> E" ..
  97.250 +          qed
  97.251 +          from H `F \<unlhd> H` HH' show FH': "F \<unlhd> H'"
  97.252 +            by (rule vectorspace.subspace_trans)
  97.253 +          show "graph F f \<subseteq> graph H' h'"
  97.254 +          proof (rule graph_extI)
  97.255 +            fix x assume x: "x \<in> F"
  97.256 +            with graphs have "f x = h x" ..
  97.257 +            also have "\<dots> = h x + 0 * xi" by simp
  97.258 +            also have "\<dots> = (let (y, a) = (x, 0) in h y + a * xi)"
  97.259 +              by (simp add: Let_def)
  97.260 +            also have "(x, 0) =
  97.261 +                (SOME (y, a). x = y + a \<cdot> x' \<and> y \<in> H)"
  97.262 +	      using E HE
  97.263 +            proof (rule decomp_H'_H [symmetric])
  97.264 +              from FH x show "x \<in> H" ..
  97.265 +              from x' show "x' \<noteq> 0" .
  97.266 +	      show "x' \<notin> H" by fact
  97.267 +	      show "x' \<in> E" by fact
  97.268 +            qed
  97.269 +            also have
  97.270 +              "(let (y, a) = (SOME (y, a). x = y + a \<cdot> x' \<and> y \<in> H)
  97.271 +              in h y + a * xi) = h' x" by (simp only: h'_def)
  97.272 +            finally show "f x = h' x" .
  97.273 +          next
  97.274 +            from FH' show "F \<subseteq> H'" ..
  97.275 +          qed
  97.276 +          show "\<forall>x \<in> H'. h' x \<le> p x"
  97.277 +	    using h'_def H'_def `x' \<notin> H` `x' \<in> E` `x' \<noteq> 0` E HE
  97.278 +	      `seminorm E p` linearform and hp xi
  97.279 +	    by (rule h'_norm_pres)
  97.280 +        qed
  97.281 +      qed
  97.282 +      ultimately show ?thesis ..
  97.283 +    qed
  97.284 +    then have "\<not> (\<forall>x \<in> M. g \<subseteq> x \<longrightarrow> g = x)" by simp
  97.285 +      -- {* So the graph @{text g} of @{text h} cannot be maximal. Contradiction! \skp *}
  97.286 +    with gx show "H = E" by contradiction
  97.287 +  qed
  97.288 +
  97.289 +  from HE_eq and linearform have "linearform E h"
  97.290 +    by (simp only:)
  97.291 +  moreover have "\<forall>x \<in> F. h x = f x"
  97.292 +  proof
  97.293 +    fix x assume "x \<in> F"
  97.294 +    with graphs have "f x = h x" ..
  97.295 +    then show "h x = f x" ..
  97.296 +  qed
  97.297 +  moreover from HE_eq and hp have "\<forall>x \<in> E. h x \<le> p x"
  97.298 +    by (simp only:)
  97.299 +  ultimately show ?thesis by blast
  97.300 +qed
  97.301 +
  97.302 +
  97.303 +subsection  {* Alternative formulation *}
  97.304 +
  97.305 +text {*
  97.306 +  The following alternative formulation of the Hahn-Banach
  97.307 +  Theorem\label{abs-HahnBanach} uses the fact that for a real linear
  97.308 +  form @{text f} and a seminorm @{text p} the following inequations
  97.309 +  are equivalent:\footnote{This was shown in lemma @{thm [source]
  97.310 +  abs_ineq_iff} (see page \pageref{abs-ineq-iff}).}
  97.311 +  \begin{center}
  97.312 +  \begin{tabular}{lll}
  97.313 +  @{text "\<forall>x \<in> H. \<bar>h x\<bar> \<le> p x"} & and &
  97.314 +  @{text "\<forall>x \<in> H. h x \<le> p x"} \\
  97.315 +  \end{tabular}
  97.316 +  \end{center}
  97.317 +*}
  97.318 +
  97.319 +theorem abs_HahnBanach:
  97.320 +  assumes E: "vectorspace E" and FE: "subspace F E"
  97.321 +    and lf: "linearform F f" and sn: "seminorm E p"
  97.322 +  assumes fp: "\<forall>x \<in> F. \<bar>f x\<bar> \<le> p x"
  97.323 +  shows "\<exists>g. linearform E g
  97.324 +    \<and> (\<forall>x \<in> F. g x = f x)
  97.325 +    \<and> (\<forall>x \<in> E. \<bar>g x\<bar> \<le> p x)"
  97.326 +proof -
  97.327 +  interpret vectorspace E by fact
  97.328 +  interpret subspace F E by fact
  97.329 +  interpret linearform F f by fact
  97.330 +  interpret seminorm E p by fact
  97.331 +  have "\<exists>g. linearform E g \<and> (\<forall>x \<in> F. g x = f x) \<and> (\<forall>x \<in> E. g x \<le> p x)"
  97.332 +    using E FE sn lf
  97.333 +  proof (rule HahnBanach)
  97.334 +    show "\<forall>x \<in> F. f x \<le> p x"
  97.335 +      using FE E sn lf and fp by (rule abs_ineq_iff [THEN iffD1])
  97.336 +  qed
  97.337 +  then obtain g where lg: "linearform E g" and *: "\<forall>x \<in> F. g x = f x"
  97.338 +      and **: "\<forall>x \<in> E. g x \<le> p x" by blast
  97.339 +  have "\<forall>x \<in> E. \<bar>g x\<bar> \<le> p x"
  97.340 +    using _ E sn lg **
  97.341 +  proof (rule abs_ineq_iff [THEN iffD2])
  97.342 +    show "E \<unlhd> E" ..
  97.343 +  qed
  97.344 +  with lg * show ?thesis by blast
  97.345 +qed
  97.346 +
  97.347 +
  97.348 +subsection {* The Hahn-Banach Theorem for normed spaces *}
  97.349 +
  97.350 +text {*
  97.351 +  Every continuous linear form @{text f} on a subspace @{text F} of a
  97.352 +  norm space @{text E}, can be extended to a continuous linear form
  97.353 +  @{text g} on @{text E} such that @{text "\<parallel>f\<parallel> = \<parallel>g\<parallel>"}.
  97.354 +*}
  97.355 +
  97.356 +theorem norm_HahnBanach:
  97.357 +  fixes V and norm ("\<parallel>_\<parallel>")
  97.358 +  fixes B defines "\<And>V f. B V f \<equiv> {0} \<union> {\<bar>f x\<bar> / \<parallel>x\<parallel> | x. x \<noteq> 0 \<and> x \<in> V}"
  97.359 +  fixes fn_norm ("\<parallel>_\<parallel>\<hyphen>_" [0, 1000] 999)
  97.360 +  defines "\<And>V f. \<parallel>f\<parallel>\<hyphen>V \<equiv> \<Squnion>(B V f)"
  97.361 +  assumes E_norm: "normed_vectorspace E norm" and FE: "subspace F E"
  97.362 +    and linearform: "linearform F f" and "continuous F norm f"
  97.363 +  shows "\<exists>g. linearform E g
  97.364 +     \<and> continuous E norm g
  97.365 +     \<and> (\<forall>x \<in> F. g x = f x)
  97.366 +     \<and> \<parallel>g\<parallel>\<hyphen>E = \<parallel>f\<parallel>\<hyphen>F"
  97.367 +proof -
  97.368 +  interpret normed_vectorspace E norm by fact
  97.369 +  interpret normed_vectorspace_with_fn_norm E norm B fn_norm
  97.370 +    by (auto simp: B_def fn_norm_def) intro_locales
  97.371 +  interpret subspace F E by fact
  97.372 +  interpret linearform F f by fact
  97.373 +  interpret continuous F norm f by fact
  97.374 +  have E: "vectorspace E" by intro_locales
  97.375 +  have F: "vectorspace F" by rule intro_locales
  97.376 +  have F_norm: "normed_vectorspace F norm"
  97.377 +    using FE E_norm by (rule subspace_normed_vs)
  97.378 +  have ge_zero: "0 \<le> \<parallel>f\<parallel>\<hyphen>F"
  97.379 +    by (rule normed_vectorspace_with_fn_norm.fn_norm_ge_zero
  97.380 +      [OF normed_vectorspace_with_fn_norm.intro,
  97.381 +       OF F_norm `continuous F norm f` , folded B_def fn_norm_def])
  97.382 +  txt {* We define a function @{text p} on @{text E} as follows:
  97.383 +    @{text "p x = \<parallel>f\<parallel> \<cdot> \<parallel>x\<parallel>"} *}
  97.384 +  def p \<equiv> "\<lambda>x. \<parallel>f\<parallel>\<hyphen>F * \<parallel>x\<parallel>"
  97.385 +
  97.386 +  txt {* @{text p} is a seminorm on @{text E}: *}
  97.387 +  have q: "seminorm E p"
  97.388 +  proof
  97.389 +    fix x y a assume x: "x \<in> E" and y: "y \<in> E"
  97.390 +    
  97.391 +    txt {* @{text p} is positive definite: *}
  97.392 +    have "0 \<le> \<parallel>f\<parallel>\<hyphen>F" by (rule ge_zero)
  97.393 +    moreover from x have "0 \<le> \<parallel>x\<parallel>" ..
  97.394 +    ultimately show "0 \<le> p x"  
  97.395 +      by (simp add: p_def zero_le_mult_iff)
  97.396 +
  97.397 +    txt {* @{text p} is absolutely homogenous: *}
  97.398 +
  97.399 +    show "p (a \<cdot> x) = \<bar>a\<bar> * p x"
  97.400 +    proof -
  97.401 +      have "p (a \<cdot> x) = \<parallel>f\<parallel>\<hyphen>F * \<parallel>a \<cdot> x\<parallel>" by (simp only: p_def)
  97.402 +      also from x have "\<parallel>a \<cdot> x\<parallel> = \<bar>a\<bar> * \<parallel>x\<parallel>" by (rule abs_homogenous)
  97.403 +      also have "\<parallel>f\<parallel>\<hyphen>F * (\<bar>a\<bar> * \<parallel>x\<parallel>) = \<bar>a\<bar> * (\<parallel>f\<parallel>\<hyphen>F * \<parallel>x\<parallel>)" by simp
  97.404 +      also have "\<dots> = \<bar>a\<bar> * p x" by (simp only: p_def)
  97.405 +      finally show ?thesis .
  97.406 +    qed
  97.407 +
  97.408 +    txt {* Furthermore, @{text p} is subadditive: *}
  97.409 +
  97.410 +    show "p (x + y) \<le> p x + p y"
  97.411 +    proof -
  97.412 +      have "p (x + y) = \<parallel>f\<parallel>\<hyphen>F * \<parallel>x + y\<parallel>" by (simp only: p_def)
  97.413 +      also have a: "0 \<le> \<parallel>f\<parallel>\<hyphen>F" by (rule ge_zero)
  97.414 +      from x y have "\<parallel>x + y\<parallel> \<le> \<parallel>x\<parallel> + \<parallel>y\<parallel>" ..
  97.415 +      with a have " \<parallel>f\<parallel>\<hyphen>F * \<parallel>x + y\<parallel> \<le> \<parallel>f\<parallel>\<hyphen>F * (\<parallel>x\<parallel> + \<parallel>y\<parallel>)"
  97.416 +        by (simp add: mult_left_mono)
  97.417 +      also have "\<dots> = \<parallel>f\<parallel>\<hyphen>F * \<parallel>x\<parallel> + \<parallel>f\<parallel>\<hyphen>F * \<parallel>y\<parallel>" by (simp only: right_distrib)
  97.418 +      also have "\<dots> = p x + p y" by (simp only: p_def)
  97.419 +      finally show ?thesis .
  97.420 +    qed
  97.421 +  qed
  97.422 +
  97.423 +  txt {* @{text f} is bounded by @{text p}. *}
  97.424 +
  97.425 +  have "\<forall>x \<in> F. \<bar>f x\<bar> \<le> p x"
  97.426 +  proof
  97.427 +    fix x assume "x \<in> F"
  97.428 +    with `continuous F norm f` and linearform
  97.429 +    show "\<bar>f x\<bar> \<le> p x"
  97.430 +      unfolding p_def by (rule normed_vectorspace_with_fn_norm.fn_norm_le_cong
  97.431 +        [OF normed_vectorspace_with_fn_norm.intro,
  97.432 +         OF F_norm, folded B_def fn_norm_def])
  97.433 +  qed
  97.434 +
  97.435 +  txt {* Using the fact that @{text p} is a seminorm and @{text f} is bounded
  97.436 +    by @{text p} we can apply the Hahn-Banach Theorem for real vector
  97.437 +    spaces. So @{text f} can be extended in a norm-preserving way to
  97.438 +    some function @{text g} on the whole vector space @{text E}. *}
  97.439 +
  97.440 +  with E FE linearform q obtain g where
  97.441 +      linearformE: "linearform E g"
  97.442 +    and a: "\<forall>x \<in> F. g x = f x"
  97.443 +    and b: "\<forall>x \<in> E. \<bar>g x\<bar> \<le> p x"
  97.444 +    by (rule abs_HahnBanach [elim_format]) iprover
  97.445 +
  97.446 +  txt {* We furthermore have to show that @{text g} is also continuous: *}
  97.447 +
  97.448 +  have g_cont: "continuous E norm g" using linearformE
  97.449 +  proof
  97.450 +    fix x assume "x \<in> E"
  97.451 +    with b show "\<bar>g x\<bar> \<le> \<parallel>f\<parallel>\<hyphen>F * \<parallel>x\<parallel>"
  97.452 +      by (simp only: p_def)
  97.453 +  qed
  97.454 +
  97.455 +  txt {* To complete the proof, we show that @{text "\<parallel>g\<parallel> = \<parallel>f\<parallel>"}. *}
  97.456 +
  97.457 +  have "\<parallel>g\<parallel>\<hyphen>E = \<parallel>f\<parallel>\<hyphen>F"
  97.458 +  proof (rule order_antisym)
  97.459 +    txt {*
  97.460 +      First we show @{text "\<parallel>g\<parallel> \<le> \<parallel>f\<parallel>"}.  The function norm @{text
  97.461 +      "\<parallel>g\<parallel>"} is defined as the smallest @{text "c \<in> \<real>"} such that
  97.462 +      \begin{center}
  97.463 +      \begin{tabular}{l}
  97.464 +      @{text "\<forall>x \<in> E. \<bar>g x\<bar> \<le> c \<cdot> \<parallel>x\<parallel>"}
  97.465 +      \end{tabular}
  97.466 +      \end{center}
  97.467 +      \noindent Furthermore holds
  97.468 +      \begin{center}
  97.469 +      \begin{tabular}{l}
  97.470 +      @{text "\<forall>x \<in> E. \<bar>g x\<bar> \<le> \<parallel>f\<parallel> \<cdot> \<parallel>x\<parallel>"}
  97.471 +      \end{tabular}
  97.472 +      \end{center}
  97.473 +    *}
  97.474 +
  97.475 +    have "\<forall>x \<in> E. \<bar>g x\<bar> \<le> \<parallel>f\<parallel>\<hyphen>F * \<parallel>x\<parallel>"
  97.476 +    proof
  97.477 +      fix x assume "x \<in> E"
  97.478 +      with b show "\<bar>g x\<bar> \<le> \<parallel>f\<parallel>\<hyphen>F * \<parallel>x\<parallel>"
  97.479 +        by (simp only: p_def)
  97.480 +    qed
  97.481 +    from g_cont this ge_zero
  97.482 +    show "\<parallel>g\<parallel>\<hyphen>E \<le> \<parallel>f\<parallel>\<hyphen>F"
  97.483 +      by (rule fn_norm_least [of g, folded B_def fn_norm_def])
  97.484 +
  97.485 +    txt {* The other direction is achieved by a similar argument. *}
  97.486 +
  97.487 +    show "\<parallel>f\<parallel>\<hyphen>F \<le> \<parallel>g\<parallel>\<hyphen>E"
  97.488 +    proof (rule normed_vectorspace_with_fn_norm.fn_norm_least
  97.489 +	[OF normed_vectorspace_with_fn_norm.intro,
  97.490 +	 OF F_norm, folded B_def fn_norm_def])
  97.491 +      show "\<forall>x \<in> F. \<bar>f x\<bar> \<le> \<parallel>g\<parallel>\<hyphen>E * \<parallel>x\<parallel>"
  97.492 +      proof
  97.493 +	fix x assume x: "x \<in> F"
  97.494 +	from a x have "g x = f x" ..
  97.495 +	then have "\<bar>f x\<bar> = \<bar>g x\<bar>" by (simp only:)
  97.496 +	also from g_cont
  97.497 +	have "\<dots> \<le> \<parallel>g\<parallel>\<hyphen>E * \<parallel>x\<parallel>"
  97.498 +	proof (rule fn_norm_le_cong [of g, folded B_def fn_norm_def])
  97.499 +	  from FE x show "x \<in> E" ..
  97.500 +	qed
  97.501 +	finally show "\<bar>f x\<bar> \<le> \<parallel>g\<parallel>\<hyphen>E * \<parallel>x\<parallel>" .
  97.502 +      qed
  97.503 +      show "0 \<le> \<parallel>g\<parallel>\<hyphen>E"
  97.504 +	using g_cont
  97.505 +	by (rule fn_norm_ge_zero [of g, folded B_def fn_norm_def])
  97.506 +      show "continuous F norm f" by fact
  97.507 +    qed
  97.508 +  qed
  97.509 +  with linearformE a g_cont show ?thesis by blast
  97.510 +qed
  97.511 +
  97.512 +end
    98.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    98.2 +++ b/src/HOL/HahnBanach/HahnBanachExtLemmas.thy	Tue Dec 30 11:10:01 2008 +0100
    98.3 @@ -0,0 +1,280 @@
    98.4 +(*  Title:      HOL/Real/HahnBanach/HahnBanachExtLemmas.thy
    98.5 +    Author:     Gertrud Bauer, TU Munich
    98.6 +*)
    98.7 +
    98.8 +header {* Extending non-maximal functions *}
    98.9 +
   98.10 +theory HahnBanachExtLemmas
   98.11 +imports FunctionNorm
   98.12 +begin
   98.13 +
   98.14 +text {*
   98.15 +  In this section the following context is presumed.  Let @{text E} be
   98.16 +  a real vector space with a seminorm @{text q} on @{text E}. @{text
   98.17 +  F} is a subspace of @{text E} and @{text f} a linear function on
   98.18 +  @{text F}. We consider a subspace @{text H} of @{text E} that is a
   98.19 +  superspace of @{text F} and a linear form @{text h} on @{text
   98.20 +  H}. @{text H} is a not equal to @{text E} and @{text "x\<^sub>0"} is
   98.21 +  an element in @{text "E - H"}.  @{text H} is extended to the direct
   98.22 +  sum @{text "H' = H + lin x\<^sub>0"}, so for any @{text "x \<in> H'"}
   98.23 +  the decomposition of @{text "x = y + a \<cdot> x"} with @{text "y \<in> H"} is
   98.24 +  unique. @{text h'} is defined on @{text H'} by @{text "h' x = h y +
   98.25 +  a \<cdot> \<xi>"} for a certain @{text \<xi>}.
   98.26 +
   98.27 +  Subsequently we show some properties of this extension @{text h'} of
   98.28 +  @{text h}.
   98.29 +
   98.30 +  \medskip This lemma will be used to show the existence of a linear
   98.31 +  extension of @{text f} (see page \pageref{ex-xi-use}). It is a
   98.32 +  consequence of the completeness of @{text \<real>}. To show
   98.33 +  \begin{center}
   98.34 +  \begin{tabular}{l}
   98.35 +  @{text "\<exists>\<xi>. \<forall>y \<in> F. a y \<le> \<xi> \<and> \<xi> \<le> b y"}
   98.36 +  \end{tabular}
   98.37 +  \end{center}
   98.38 +  \noindent it suffices to show that
   98.39 +  \begin{center}
   98.40 +  \begin{tabular}{l}
   98.41 +  @{text "\<forall>u \<in> F. \<forall>v \<in> F. a u \<le> b v"}
   98.42 +  \end{tabular}
   98.43 +  \end{center}
   98.44 +*}
   98.45 +
   98.46 +lemma ex_xi:
   98.47 +  assumes "vectorspace F"
   98.48 +  assumes r: "\<And>u v. u \<in> F \<Longrightarrow> v \<in> F \<Longrightarrow> a u \<le> b v"
   98.49 +  shows "\<exists>xi::real. \<forall>y \<in> F. a y \<le> xi \<and> xi \<le> b y"
   98.50 +proof -
   98.51 +  interpret vectorspace F by fact
   98.52 +  txt {* From the completeness of the reals follows:
   98.53 +    The set @{text "S = {a u. u \<in> F}"} has a supremum, if it is
   98.54 +    non-empty and has an upper bound. *}
   98.55 +
   98.56 +  let ?S = "{a u | u. u \<in> F}"
   98.57 +  have "\<exists>xi. lub ?S xi"
   98.58 +  proof (rule real_complete)
   98.59 +    have "a 0 \<in> ?S" by blast
   98.60 +    then show "\<exists>X. X \<in> ?S" ..
   98.61 +    have "\<forall>y \<in> ?S. y \<le> b 0"
   98.62 +    proof
   98.63 +      fix y assume y: "y \<in> ?S"
   98.64 +      then obtain u where u: "u \<in> F" and y: "y = a u" by blast
   98.65 +      from u and zero have "a u \<le> b 0" by (rule r)
   98.66 +      with y show "y \<le> b 0" by (simp only:)
   98.67 +    qed
   98.68 +    then show "\<exists>u. \<forall>y \<in> ?S. y \<le> u" ..
   98.69 +  qed
   98.70 +  then obtain xi where xi: "lub ?S xi" ..
   98.71 +  {
   98.72 +    fix y assume "y \<in> F"
   98.73 +    then have "a y \<in> ?S" by blast
   98.74 +    with xi have "a y \<le> xi" by (rule lub.upper)
   98.75 +  } moreover {
   98.76 +    fix y assume y: "y \<in> F"
   98.77 +    from xi have "xi \<le> b y"
   98.78 +    proof (rule lub.least)
   98.79 +      fix au assume "au \<in> ?S"
   98.80 +      then obtain u where u: "u \<in> F" and au: "au = a u" by blast
   98.81 +      from u y have "a u \<le> b y" by (rule r)
   98.82 +      with au show "au \<le> b y" by (simp only:)
   98.83 +    qed
   98.84 +  } ultimately show "\<exists>xi. \<forall>y \<in> F. a y \<le> xi \<and> xi \<le> b y" by blast
   98.85 +qed
   98.86 +
   98.87 +text {*
   98.88 +  \medskip The function @{text h'} is defined as a @{text "h' x = h y
   98.89 +  + a \<cdot> \<xi>"} where @{text "x = y + a \<cdot> \<xi>"} is a linear extension of
   98.90 +  @{text h} to @{text H'}.
   98.91 +*}
   98.92 +
   98.93 +lemma h'_lf:
   98.94 +  assumes h'_def: "h' \<equiv> \<lambda>x. let (y, a) =
   98.95 +      SOME (y, a). x = y + a \<cdot> x0 \<and> y \<in> H in h y + a * xi"
   98.96 +    and H'_def: "H' \<equiv> H + lin x0"
   98.97 +    and HE: "H \<unlhd> E"
   98.98 +  assumes "linearform H h"
   98.99 +  assumes x0: "x0 \<notin> H"  "x0 \<in> E"  "x0 \<noteq> 0"
  98.100 +  assumes E: "vectorspace E"
  98.101 +  shows "linearform H' h'"
  98.102 +proof -
  98.103 +  interpret linearform H h by fact
  98.104 +  interpret vectorspace E by fact
  98.105 +  show ?thesis
  98.106 +  proof
  98.107 +    note E = `vectorspace E`
  98.108 +    have H': "vectorspace H'"
  98.109 +    proof (unfold H'_def)
  98.110 +      from `x0 \<in> E`
  98.111 +      have "lin x0 \<unlhd> E" ..
  98.112 +      with HE show "vectorspace (H + lin x0)" using E ..
  98.113 +    qed
  98.114 +    {
  98.115 +      fix x1 x2 assume x1: "x1 \<in> H'" and x2: "x2 \<in> H'"
  98.116 +      show "h' (x1 + x2) = h' x1 + h' x2"
  98.117 +      proof -
  98.118 +	from H' x1 x2 have "x1 + x2 \<in> H'"
  98.119 +          by (rule vectorspace.add_closed)
  98.120 +	with x1 x2 obtain y y1 y2 a a1 a2 where
  98.121 +          x1x2: "x1 + x2 = y + a \<cdot> x0" and y: "y \<in> H"
  98.122 +          and x1_rep: "x1 = y1 + a1 \<cdot> x0" and y1: "y1 \<in> H"
  98.123 +          and x2_rep: "x2 = y2 + a2 \<cdot> x0" and y2: "y2 \<in> H"
  98.124 +          unfolding H'_def sum_def lin_def by blast
  98.125 +	
  98.126 +	have ya: "y1 + y2 = y \<and> a1 + a2 = a" using E HE _ y x0
  98.127 +	proof (rule decomp_H') txt_raw {* \label{decomp-H-use} *}
  98.128 +          from HE y1 y2 show "y1 + y2 \<in> H"
  98.129 +            by (rule subspace.add_closed)
  98.130 +          from x0 and HE y y1 y2
  98.131 +          have "x0 \<in> E"  "y \<in> E"  "y1 \<in> E"  "y2 \<in> E" by auto
  98.132 +          with x1_rep x2_rep have "(y1 + y2) + (a1 + a2) \<cdot> x0 = x1 + x2"
  98.133 +            by (simp add: add_ac add_mult_distrib2)
  98.134 +          also note x1x2
  98.135 +          finally show "(y1 + y2) + (a1 + a2) \<cdot> x0 = y + a \<cdot> x0" .
  98.136 +	qed
  98.137 +	
  98.138 +	from h'_def x1x2 E HE y x0
  98.139 +	have "h' (x1 + x2) = h y + a * xi"
  98.140 +          by (rule h'_definite)
  98.141 +	also have "\<dots> = h (y1 + y2) + (a1 + a2) * xi"
  98.142 +          by (simp only: ya)
  98.143 +	also from y1 y2 have "h (y1 + y2) = h y1 + h y2"
  98.144 +          by simp
  98.145 +	also have "\<dots> + (a1 + a2) * xi = (h y1 + a1 * xi) + (h y2 + a2 * xi)"
  98.146 +          by (simp add: left_distrib)
  98.147 +	also from h'_def x1_rep E HE y1 x0
  98.148 +	have "h y1 + a1 * xi = h' x1"
  98.149 +          by (rule h'_definite [symmetric])
  98.150 +	also from h'_def x2_rep E HE y2 x0
  98.151 +	have "h y2 + a2 * xi = h' x2"
  98.152 +          by (rule h'_definite [symmetric])
  98.153 +	finally show ?thesis .
  98.154 +      qed
  98.155 +    next
  98.156 +      fix x1 c assume x1: "x1 \<in> H'"
  98.157 +      show "h' (c \<cdot> x1) = c * (h' x1)"
  98.158 +      proof -
  98.159 +	from H' x1 have ax1: "c \<cdot> x1 \<in> H'"
  98.160 +          by (rule vectorspace.mult_closed)
  98.161 +	with x1 obtain y a y1 a1 where
  98.162 +            cx1_rep: "c \<cdot> x1 = y + a \<cdot> x0" and y: "y \<in> H"
  98.163 +          and x1_rep: "x1 = y1 + a1 \<cdot> x0" and y1: "y1 \<in> H"
  98.164 +          unfolding H'_def sum_def lin_def by blast
  98.165 +	
  98.166 +	have ya: "c \<cdot> y1 = y \<and> c * a1 = a" using E HE _ y x0
  98.167 +	proof (rule decomp_H')
  98.168 +          from HE y1 show "c \<cdot> y1 \<in> H"
  98.169 +            by (rule subspace.mult_closed)
  98.170 +          from x0 and HE y y1
  98.171 +          have "x0 \<in> E"  "y \<in> E"  "y1 \<in> E" by auto
  98.172 +          with x1_rep have "c \<cdot> y1 + (c * a1) \<cdot> x0 = c \<cdot> x1"
  98.173 +            by (simp add: mult_assoc add_mult_distrib1)
  98.174 +          also note cx1_rep
  98.175 +          finally show "c \<cdot> y1 + (c * a1) \<cdot> x0 = y + a \<cdot> x0" .
  98.176 +	qed
  98.177 +	
  98.178 +	from h'_def cx1_rep E HE y x0 have "h' (c \<cdot> x1) = h y + a * xi"
  98.179 +          by (rule h'_definite)
  98.180 +	also have "\<dots> = h (c \<cdot> y1) + (c * a1) * xi"
  98.181 +          by (simp only: ya)
  98.182 +	also from y1 have "h (c \<cdot> y1) = c * h y1"
  98.183 +          by simp
  98.184 +	also have "\<dots> + (c * a1) * xi = c * (h y1 + a1 * xi)"
  98.185 +          by (simp only: right_distrib)
  98.186 +	also from h'_def x1_rep E HE y1 x0 have "h y1 + a1 * xi = h' x1"
  98.187 +          by (rule h'_definite [symmetric])
  98.188 +	finally show ?thesis .
  98.189 +      qed
  98.190 +    }
  98.191 +  qed
  98.192 +qed
  98.193 +
  98.194 +text {* \medskip The linear extension @{text h'} of @{text h}
  98.195 +  is bounded by the seminorm @{text p}. *}
  98.196 +
  98.197 +lemma h'_norm_pres:
  98.198 +  assumes h'_def: "h' \<equiv> \<lambda>x. let (y, a) =
  98.199 +      SOME (y, a). x = y + a \<cdot> x0 \<and> y \<in> H in h y + a * xi"
  98.200 +    and H'_def: "H' \<equiv> H + lin x0"
  98.201 +    and x0: "x0 \<notin> H"  "x0 \<in> E"  "x0 \<noteq> 0"
  98.202 +  assumes E: "vectorspace E" and HE: "subspace H E"
  98.203 +    and "seminorm E p" and "linearform H h"
  98.204 +  assumes a: "\<forall>y \<in> H. h y \<le> p y"
  98.205 +    and a': "\<forall>y \<in> H. - p (y + x0) - h y \<le> xi \<and> xi \<le> p (y + x0) - h y"
  98.206 +  shows "\<forall>x \<in> H'. h' x \<le> p x"
  98.207 +proof -
  98.208 +  interpret vectorspace E by fact
  98.209 +  interpret subspace H E by fact
  98.210 +  interpret seminorm E p by fact
  98.211 +  interpret linearform H h by fact
  98.212 +  show ?thesis
  98.213 +  proof
  98.214 +    fix x assume x': "x \<in> H'"
  98.215 +    show "h' x \<le> p x"
  98.216 +    proof -
  98.217 +      from a' have a1: "\<forall>ya \<in> H. - p (ya + x0) - h ya \<le> xi"
  98.218 +	and a2: "\<forall>ya \<in> H. xi \<le> p (ya + x0) - h ya" by auto
  98.219 +      from x' obtain y a where
  98.220 +          x_rep: "x = y + a \<cdot> x0" and y: "y \<in> H"
  98.221 +	unfolding H'_def sum_def lin_def by blast
  98.222 +      from y have y': "y \<in> E" ..
  98.223 +      from y have ay: "inverse a \<cdot> y \<in> H" by simp
  98.224 +      
  98.225 +      from h'_def x_rep E HE y x0 have "h' x = h y + a * xi"
  98.226 +	by (rule h'_definite)
  98.227 +      also have "\<dots> \<le> p (y + a \<cdot> x0)"
  98.228 +      proof (rule linorder_cases)
  98.229 +	assume z: "a = 0"
  98.230 +	then have "h y + a * xi = h y" by simp
  98.231 +	also from a y have "\<dots> \<le> p y" ..
  98.232 +	also from x0 y' z have "p y = p (y + a \<cdot> x0)" by simp
  98.233 +	finally show ?thesis .
  98.234 +      next
  98.235 +	txt {* In the case @{text "a < 0"}, we use @{text "a\<^sub>1"}
  98.236 +          with @{text ya} taken as @{text "y / a"}: *}
  98.237 +	assume lz: "a < 0" then have nz: "a \<noteq> 0" by simp
  98.238 +	from a1 ay
  98.239 +	have "- p (inverse a \<cdot> y + x0) - h (inverse a \<cdot> y) \<le> xi" ..
  98.240 +	with lz have "a * xi \<le>
  98.241 +          a * (- p (inverse a \<cdot> y + x0) - h (inverse a \<cdot> y))"
  98.242 +          by (simp add: mult_left_mono_neg order_less_imp_le)
  98.243 +	
  98.244 +	also have "\<dots> =
  98.245 +          - a * (p (inverse a \<cdot> y + x0)) - a * (h (inverse a \<cdot> y))"
  98.246 +	  by (simp add: right_diff_distrib)
  98.247 +	also from lz x0 y' have "- a * (p (inverse a \<cdot> y + x0)) =
  98.248 +          p (a \<cdot> (inverse a \<cdot> y + x0))"
  98.249 +          by (simp add: abs_homogenous)
  98.250 +	also from nz x0 y' have "\<dots> = p (y + a \<cdot> x0)"
  98.251 +          by (simp add: add_mult_distrib1 mult_assoc [symmetric])
  98.252 +	also from nz y have "a * (h (inverse a \<cdot> y)) =  h y"
  98.253 +          by simp
  98.254 +	finally have "a * xi \<le> p (y + a \<cdot> x0) - h y" .
  98.255 +	then show ?thesis by simp
  98.256 +      next
  98.257 +	txt {* In the case @{text "a > 0"}, we use @{text "a\<^sub>2"}
  98.258 +          with @{text ya} taken as @{text "y / a"}: *}
  98.259 +	assume gz: "0 < a" then have nz: "a \<noteq> 0" by simp
  98.260 +	from a2 ay
  98.261 +	have "xi \<le> p (inverse a \<cdot> y + x0) - h (inverse a \<cdot> y)" ..
  98.262 +	with gz have "a * xi \<le>
  98.263 +          a * (p (inverse a \<cdot> y + x0) - h (inverse a \<cdot> y))"
  98.264 +          by simp
  98.265 +	also have "\<dots> = a * p (inverse a \<cdot> y + x0) - a * h (inverse a \<cdot> y)"
  98.266 +	  by (simp add: right_diff_distrib)
  98.267 +	also from gz x0 y'
  98.268 +	have "a * p (inverse a \<cdot> y + x0) = p (a \<cdot> (inverse a \<cdot> y + x0))"
  98.269 +          by (simp add: abs_homogenous)
  98.270 +	also from nz x0 y' have "\<dots> = p (y + a \<cdot> x0)"
  98.271 +          by (simp add: add_mult_distrib1 mult_assoc [symmetric])
  98.272 +	also from nz y have "a * h (inverse a \<cdot> y) = h y"
  98.273 +          by simp
  98.274 +	finally have "a * xi \<le> p (y + a \<cdot> x0) - h y" .
  98.275 +	then show ?thesis by simp
  98.276 +      qed
  98.277 +      also from x_rep have "\<dots> = p x" by (simp only:)
  98.278 +      finally show ?thesis .
  98.279 +    qed
  98.280 +  qed
  98.281 +qed
  98.282 +
  98.283 +end
    99.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    99.2 +++ b/src/HOL/HahnBanach/HahnBanachLemmas.thy	Tue Dec 30 11:10:01 2008 +0100
    99.3 @@ -0,0 +1,4 @@
    99.4 +(*<*)
    99.5 +theory HahnBanachLemmas imports HahnBanachSupLemmas HahnBanachExtLemmas begin
    99.6 +end
    99.7 +(*>*)
    99.8 \ No newline at end of file
   100.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   100.2 +++ b/src/HOL/HahnBanach/HahnBanachSupLemmas.thy	Tue Dec 30 11:10:01 2008 +0100
   100.3 @@ -0,0 +1,446 @@
   100.4 +(*  Title:      HOL/Real/HahnBanach/HahnBanachSupLemmas.thy
   100.5 +    ID:         $Id$
   100.6 +    Author:     Gertrud Bauer, TU Munich
   100.7 +*)
   100.8 +
   100.9 +header {* The supremum w.r.t.~the function order *}
  100.10 +
  100.11 +theory HahnBanachSupLemmas
  100.12 +imports FunctionNorm ZornLemma
  100.13 +begin
  100.14 +
  100.15 +text {*
  100.16 +  This section contains some lemmas that will be used in the proof of
  100.17 +  the Hahn-Banach Theorem.  In this section the following context is
  100.18 +  presumed.  Let @{text E} be a real vector space with a seminorm
  100.19 +  @{text p} on @{text E}.  @{text F} is a subspace of @{text E} and
  100.20 +  @{text f} a linear form on @{text F}. We consider a chain @{text c}
  100.21 +  of norm-preserving extensions of @{text f}, such that @{text "\<Union>c =
  100.22 +  graph H h"}.  We will show some properties about the limit function
  100.23 +  @{text h}, i.e.\ the supremum of the chain @{text c}.
  100.24 +
  100.25 +  \medskip Let @{text c} be a chain of norm-preserving extensions of
  100.26 +  the function @{text f} and let @{text "graph H h"} be the supremum
  100.27 +  of @{text c}.  Every element in @{text H} is member of one of the
  100.28 +  elements of the chain.
  100.29 +*}
  100.30 +lemmas [dest?] = chainD
  100.31 +lemmas chainE2 [elim?] = chainD2 [elim_format, standard]
  100.32 +
  100.33 +lemma some_H'h't:
  100.34 +  assumes M: "M = norm_pres_extensions E p F f"
  100.35 +    and cM: "c \<in> chain M"
  100.36 +    and u: "graph H h = \<Union>c"
  100.37 +    and x: "x \<in> H"
  100.38 +  shows "\<exists>H' h'. graph H' h' \<in> c
  100.39 +    \<and> (x, h x) \<in> graph H' h'
  100.40 +    \<and> linearform H' h' \<and> H' \<unlhd> E
  100.41 +    \<and> F \<unlhd> H' \<and> graph F f \<subseteq> graph H' h'
  100.42 +    \<and> (\<forall>x \<in> H'. h' x \<le> p x)"
  100.43 +proof -
  100.44 +  from x have "(x, h x) \<in> graph H h" ..
  100.45 +  also from u have "\<dots> = \<Union>c" .
  100.46 +  finally obtain g where gc: "g \<in> c" and gh: "(x, h x) \<in> g" by blast
  100.47 +
  100.48 +  from cM have "c \<subseteq> M" ..
  100.49 +  with gc have "g \<in> M" ..
  100.50 +  also from M have "\<dots> = norm_pres_extensions E p F f" .
  100.51 +  finally obtain H' and h' where g: "g = graph H' h'"
  100.52 +    and * : "linearform H' h'"  "H' \<unlhd> E"  "F \<unlhd> H'"
  100.53 +      "graph F f \<subseteq> graph H' h'"  "\<forall>x \<in> H'. h' x \<le> p x" ..
  100.54 +
  100.55 +  from gc and g have "graph H' h' \<in> c" by (simp only:)
  100.56 +  moreover from gh and g have "(x, h x) \<in> graph H' h'" by (simp only:)
  100.57 +  ultimately show ?thesis using * by blast
  100.58 +qed
  100.59 +
  100.60 +text {*
  100.61 +  \medskip Let @{text c} be a chain of norm-preserving extensions of
  100.62 +  the function @{text f} and let @{text "graph H h"} be the supremum
  100.63 +  of @{text c}.  Every element in the domain @{text H} of the supremum
  100.64 +  function is member of the domain @{text H'} of some function @{text
  100.65 +  h'}, such that @{text h} extends @{text h'}.
  100.66 +*}
  100.67 +
  100.68 +lemma some_H'h':
  100.69 +  assumes M: "M = norm_pres_extensions E p F f"
  100.70 +    and cM: "c \<in> chain M"
  100.71 +    and u: "graph H h = \<Union>c"
  100.72 +    and x: "x \<in> H"
  100.73 +  shows "\<exists>H' h'. x \<in> H' \<and> graph H' h' \<subseteq> graph H h
  100.74 +    \<and> linearform H' h' \<and> H' \<unlhd> E \<and> F \<unlhd> H'
  100.75 +    \<and> graph F f \<subseteq> graph H' h' \<and> (\<forall>x \<in> H'. h' x \<le> p x)"
  100.76 +proof -
  100.77 +  from M cM u x obtain H' h' where
  100.78 +      x_hx: "(x, h x) \<in> graph H' h'"
  100.79 +    and c: "graph H' h' \<in> c"
  100.80 +    and * : "linearform H' h'"  "H' \<unlhd> E"  "F \<unlhd> H'"
  100.81 +      "graph F f \<subseteq> graph H' h'"  "\<forall>x \<in> H'. h' x \<le> p x"
  100.82 +    by (rule some_H'h't [elim_format]) blast
  100.83 +  from x_hx have "x \<in> H'" ..
  100.84 +  moreover from cM u c have "graph H' h' \<subseteq> graph H h"
  100.85 +    by (simp only: chain_ball_Union_upper)
  100.86 +  ultimately show ?thesis using * by blast
  100.87 +qed
  100.88 +
  100.89 +text {*
  100.90 +  \medskip Any two elements @{text x} and @{text y} in the domain
  100.91 +  @{text H} of the supremum function @{text h} are both in the domain
  100.92 +  @{text H'} of some function @{text h'}, such that @{text h} extends
  100.93 +  @{text h'}.
  100.94 +*}
  100.95 +
  100.96 +lemma some_H'h'2:
  100.97 +  assumes M: "M = norm_pres_extensions E p F f"
  100.98 +    and cM: "c \<in> chain M"
  100.99 +    and u: "graph H h = \<Union>c"
 100.100 +    and x: "x \<in> H"
 100.101 +    and y: "y \<in> H"
 100.102 +  shows "\<exists>H' h'. x \<in> H' \<and> y \<in> H'
 100.103 +    \<and> graph H' h' \<subseteq> graph H h
 100.104 +    \<and> linearform H' h' \<and> H' \<unlhd> E \<and> F \<unlhd> H'
 100.105 +    \<and> graph F f \<subseteq> graph H' h' \<and> (\<forall>x \<in> H'. h' x \<le> p x)"
 100.106 +proof -
 100.107 +  txt {* @{text y} is in the domain @{text H''} of some function @{text h''},
 100.108 +  such that @{text h} extends @{text h''}. *}
 100.109 +
 100.110 +  from M cM u and y obtain H' h' where
 100.111 +      y_hy: "(y, h y) \<in> graph H' h'"
 100.112 +    and c': "graph H' h' \<in> c"
 100.113 +    and * :
 100.114 +      "linearform H' h'"  "H' \<unlhd> E"  "F \<unlhd> H'"
 100.115 +      "graph F f \<subseteq> graph H' h'"  "\<forall>x \<in> H'. h' x \<le> p x"
 100.116 +    by (rule some_H'h't [elim_format]) blast
 100.117 +
 100.118 +  txt {* @{text x} is in the domain @{text H'} of some function @{text h'},
 100.119 +    such that @{text h} extends @{text h'}. *}
 100.120 +
 100.121 +  from M cM u and x obtain H'' h'' where
 100.122 +      x_hx: "(x, h x) \<in> graph H'' h''"
 100.123 +    and c'': "graph H'' h'' \<in> c"
 100.124 +    and ** :
 100.125 +      "linearform H'' h''"  "H'' \<unlhd> E"  "F \<unlhd> H''"
 100.126 +      "graph F f \<subseteq> graph H'' h''"  "\<forall>x \<in> H''. h'' x \<le> p x"
 100.127 +    by (rule some_H'h't [elim_format]) blast
 100.128 +
 100.129 +  txt {* Since both @{text h'} and @{text h''} are elements of the chain,
 100.130 +    @{text h''} is an extension of @{text h'} or vice versa. Thus both
 100.131 +    @{text x} and @{text y} are contained in the greater
 100.132 +    one. \label{cases1}*}
 100.133 +
 100.134 +  from cM c'' c' have "graph H'' h'' \<subseteq> graph H' h' \<or> graph H' h' \<subseteq> graph H'' h''"
 100.135 +    (is "?case1 \<or> ?case2") ..
 100.136 +  then show ?thesis
 100.137 +  proof
 100.138 +    assume ?case1
 100.139 +    have "(x, h x) \<in> graph H'' h''" by fact
 100.140 +    also have "\<dots> \<subseteq> graph H' h'" by fact
 100.141 +    finally have xh:"(x, h x) \<in> graph H' h'" .
 100.142 +    then have "x \<in> H'" ..
 100.143 +    moreover from y_hy have "y \<in> H'" ..
 100.144 +    moreover from cM u and c' have "graph H' h' \<subseteq> graph H h"
 100.145 +      by (simp only: chain_ball_Union_upper)
 100.146 +    ultimately show ?thesis using * by blast
 100.147 +  next
 100.148 +    assume ?case2
 100.149 +    from x_hx have "x \<in> H''" ..
 100.150 +    moreover {
 100.151 +      have "(y, h y) \<in> graph H' h'" by (rule y_hy)
 100.152 +      also have "\<dots> \<subseteq> graph H'' h''" by fact
 100.153 +      finally have "(y, h y) \<in> graph H'' h''" .
 100.154 +    } then have "y \<in> H''" ..
 100.155 +    moreover from cM u and c'' have "graph H'' h'' \<subseteq> graph H h"
 100.156 +      by (simp only: chain_ball_Union_upper)
 100.157 +    ultimately show ?thesis using ** by blast
 100.158 +  qed
 100.159 +qed
 100.160 +
 100.161 +text {*
 100.162 +  \medskip The relation induced by the graph of the supremum of a
 100.163 +  chain @{text c} is definite, i.~e.~t is the graph of a function.
 100.164 +*}
 100.165 +
 100.166 +lemma sup_definite:
 100.167 +  assumes M_def: "M \<equiv> norm_pres_extensions E p F f"
 100.168 +    and cM: "c \<in> chain M"
 100.169 +    and xy: "(x, y) \<in> \<Union>c"
 100.170 +    and xz: "(x, z) \<in> \<Union>c"
 100.171 +  shows "z = y"
 100.172 +proof -
 100.173 +  from cM have c: "c \<subseteq> M" ..
 100.174 +  from xy obtain G1 where xy': "(x, y) \<in> G1" and G1: "G1 \<in> c" ..
 100.175 +  from xz obtain G2 where xz': "(x, z) \<in> G2" and G2: "G2 \<in> c" ..
 100.176 +
 100.177 +  from G1 c have "G1 \<in> M" ..
 100.178 +  then obtain H1 h1 where G1_rep: "G1 = graph H1 h1"
 100.179 +    unfolding M_def by blast
 100.180 +
 100.181 +  from G2 c have "G2 \<in> M" ..
 100.182 +  then obtain H2 h2 where G2_rep: "G2 = graph H2 h2"
 100.183 +    unfolding M_def by blast
 100.184 +
 100.185 +  txt {* @{text "G\<^sub>1"} is contained in @{text "G\<^sub>2"}
 100.186 +    or vice versa, since both @{text "G\<^sub>1"} and @{text
 100.187 +    "G\<^sub>2"} are members of @{text c}. \label{cases2}*}
 100.188 +
 100.189 +  from cM G1 G2 have "G1 \<subseteq> G2 \<or> G2 \<subseteq> G1" (is "?case1 \<or> ?case2") ..
 100.190 +  then show ?thesis
 100.191 +  proof
 100.192 +    assume ?case1
 100.193 +    with xy' G2_rep have "(x, y) \<in> graph H2 h2" by blast
 100.194 +    then have "y = h2 x" ..
 100.195 +    also
 100.196 +    from xz' G2_rep have "(x, z) \<in> graph H2 h2" by (simp only:)
 100.197 +    then have "z = h2 x" ..
 100.198 +    finally show ?thesis .
 100.199 +  next
 100.200 +    assume ?case2
 100.201 +    with xz' G1_rep have "(x, z) \<in> graph H1 h1" by blast
 100.202 +    then have "z = h1 x" ..
 100.203 +    also
 100.204 +    from xy' G1_rep have "(x, y) \<in> graph H1 h1" by (simp only:)
 100.205 +    then have "y = h1 x" ..
 100.206 +    finally show ?thesis ..
 100.207 +  qed
 100.208 +qed
 100.209 +
 100.210 +text {*
 100.211 +  \medskip The limit function @{text h} is linear. Every element
 100.212 +  @{text x} in the domain of @{text h} is in the domain of a function
 100.213 +  @{text h'} in the chain of norm preserving extensions.  Furthermore,
 100.214 +  @{text h} is an extension of @{text h'} so the function values of
 100.215 +  @{text x} are identical for @{text h'} and @{text h}.  Finally, the
 100.216 +  function @{text h'} is linear by construction of @{text M}.
 100.217 +*}
 100.218 +
 100.219 +lemma sup_lf:
 100.220 +  assumes M: "M = norm_pres_extensions E p F f"
 100.221 +    and cM: "c \<in> chain M"
 100.222 +    and u: "graph H h = \<Union>c"
 100.223 +  shows "linearform H h"
 100.224 +proof
 100.225 +  fix x y assume x: "x \<in> H" and y: "y \<in> H"
 100.226 +  with M cM u obtain H' h' where
 100.227 +        x': "x \<in> H'" and y': "y \<in> H'"
 100.228 +      and b: "graph H' h' \<subseteq> graph H h"
 100.229 +      and linearform: "linearform H' h'"
 100.230 +      and subspace: "H' \<unlhd> E"
 100.231 +    by (rule some_H'h'2 [elim_format]) blast
 100.232 +
 100.233 +  show "h (x + y) = h x + h y"
 100.234 +  proof -
 100.235 +    from linearform x' y' have "h' (x + y) = h' x + h' y"
 100.236 +      by (rule linearform.add)
 100.237 +    also from b x' have "h' x = h x" ..
 100.238 +    also from b y' have "h' y = h y" ..
 100.239 +    also from subspace x' y' have "x + y \<in> H'"
 100.240 +      by (rule subspace.add_closed)
 100.241 +    with b have "h' (x + y) = h (x + y)" ..
 100.242 +    finally show ?thesis .
 100.243 +  qed
 100.244 +next
 100.245 +  fix x a assume x: "x \<in> H"
 100.246 +  with M cM u obtain H' h' where
 100.247 +        x': "x \<in> H'"
 100.248 +      and b: "graph H' h' \<subseteq> graph H h"
 100.249 +      and linearform: "linearform H' h'"
 100.250 +      and subspace: "H' \<unlhd> E"
 100.251 +    by (rule some_H'h' [elim_format]) blast
 100.252 +
 100.253 +  show "h (a \<cdot> x) = a * h x"
 100.254 +  proof -
 100.255 +    from linearform x' have "h' (a \<cdot> x) = a * h' x"
 100.256 +      by (rule linearform.mult)
 100.257 +    also from b x' have "h' x = h x" ..
 100.258 +    also from subspace x' have "a \<cdot> x \<in> H'"
 100.259 +      by (rule subspace.mult_closed)
 100.260 +    with b have "h' (a \<cdot> x) = h (a \<cdot> x)" ..
 100.261 +    finally show ?thesis .
 100.262 +  qed
 100.263 +qed
 100.264 +
 100.265 +text {*
 100.266 +  \medskip The limit of a non-empty chain of norm preserving
 100.267 +  extensions of @{text f} is an extension of @{text f}, since every
 100.268 +  element of the chain is an extension of @{text f} and the supremum
 100.269 +  is an extension for every element of the chain.
 100.270 +*}
 100.271 +
 100.272 +lemma sup_ext:
 100.273 +  assumes graph: "graph H h = \<Union>c"
 100.274 +    and M: "M = norm_pres_extensions E p F f"
 100.275 +    and cM: "c \<in> chain M"
 100.276 +    and ex: "\<exists>x. x \<in> c"
 100.277 +  shows "graph F f \<subseteq> graph H h"
 100.278 +proof -
 100.279 +  from ex obtain x where xc: "x \<in> c" ..
 100.280 +  from cM have "c \<subseteq> M" ..
 100.281 +  with xc have "x \<in> M" ..
 100.282 +  with M have "x \<in> norm_pres_extensions E p F f"
 100.283 +    by (simp only:)
 100.284 +  then obtain G g where "x = graph G g" and "graph F f \<subseteq> graph G g" ..
 100.285 +  then have "graph F f \<subseteq> x" by (simp only:)
 100.286 +  also from xc have "\<dots> \<subseteq> \<Union>c" by blast
 100.287 +  also from graph have "\<dots> = graph H h" ..
 100.288 +  finally show ?thesis .
 100.289 +qed
 100.290 +
 100.291 +text {*
 100.292 +  \medskip The domain @{text H} of the limit function is a superspace
 100.293 +  of @{text F}, since @{text F} is a subset of @{text H}. The
 100.294 +  existence of the @{text 0} element in @{text F} and the closure
 100.295 +  properties follow from the fact that @{text F} is a vector space.
 100.296 +*}
 100.297 +
 100.298 +lemma sup_supF:
 100.299 +  assumes graph: "graph H h = \<Union>c"
 100.300 +    and M: "M = norm_pres_extensions E p F f"
 100.301 +    and cM: "c \<in> chain M"
 100.302 +    and ex: "\<exists>x. x \<in> c"
 100.303 +    and FE: "F \<unlhd> E"
 100.304 +  shows "F \<unlhd> H"
 100.305 +proof
 100.306 +  from FE show "F \<noteq> {}" by (rule subspace.non_empty)
 100.307 +  from graph M cM ex have "graph F f \<subseteq> graph H h" by (rule sup_ext)
 100.308 +  then show "F \<subseteq> H" ..
 100.309 +  fix x y assume "x \<in> F" and "y \<in> F"
 100.310 +  with FE show "x + y \<in> F" by (rule subspace.add_closed)
 100.311 +next
 100.312 +  fix x a assume "x \<in> F"
 100.313 +  with FE show "a \<cdot> x \<in> F" by (rule subspace.mult_closed)
 100.314 +qed
 100.315 +
 100.316 +text {*
 100.317 +  \medskip The domain @{text H} of the limit function is a subspace of
 100.318 +  @{text E}.
 100.319 +*}
 100.320 +
 100.321 +lemma sup_subE:
 100.322 +  assumes graph: "graph H h = \<Union>c"
 100.323 +    and M: "M = norm_pres_extensions E p F f"
 100.324 +    and cM: "c \<in> chain M"
 100.325 +    and ex: "\<exists>x. x \<in> c"
 100.326 +    and FE: "F \<unlhd> E"
 100.327 +    and E: "vectorspace E"
 100.328 +  shows "H \<unlhd> E"
 100.329 +proof
 100.330 +  show "H \<noteq> {}"
 100.331 +  proof -
 100.332 +    from FE E have "0 \<in> F" by (rule subspace.zero)
 100.333 +    also from graph M cM ex FE have "F \<unlhd> H" by (rule sup_supF)
 100.334 +    then have "F \<subseteq> H" ..
 100.335 +    finally show ?thesis by blast
 100.336 +  qed
 100.337 +  show "H \<subseteq> E"
 100.338 +  proof
 100.339 +    fix x assume "x \<in> H"
 100.340 +    with M cM graph
 100.341 +    obtain H' h' where x: "x \<in> H'" and H'E: "H' \<unlhd> E"
 100.342 +      by (rule some_H'h' [elim_format]) blast
 100.343 +    from H'E have "H' \<subseteq> E" ..
 100.344 +    with x show "x \<in> E" ..
 100.345 +  qed
 100.346 +  fix x y assume x: "x \<in> H" and y: "y \<in> H"
 100.347 +  show "x + y \<in> H"
 100.348 +  proof -
 100.349 +    from M cM graph x y obtain H' h' where
 100.350 +          x': "x \<in> H'" and y': "y \<in> H'" and H'E: "H' \<unlhd> E"
 100.351 +        and graphs: "graph H' h' \<subseteq> graph H h"
 100.352 +      by (rule some_H'h'2 [elim_format]) blast
 100.353 +    from H'E x' y' have "x + y \<in> H'"
 100.354 +      by (rule subspace.add_closed)
 100.355 +    also from graphs have "H' \<subseteq> H" ..
 100.356 +    finally show ?thesis .
 100.357 +  qed
 100.358 +next
 100.359 +  fix x a assume x: "x \<in> H"
 100.360 +  show "a \<cdot> x \<in> H"
 100.361 +  proof -
 100.362 +    from M cM graph x
 100.363 +    obtain H' h' where x': "x \<in> H'" and H'E: "H' \<unlhd> E"
 100.364 +        and graphs: "graph H' h' \<subseteq> graph H h"
 100.365 +      by (rule some_H'h' [elim_format]) blast
 100.366 +    from H'E x' have "a \<cdot> x \<in> H'" by (rule subspace.mult_closed)
 100.367 +    also from graphs have "H' \<subseteq> H" ..
 100.368 +    finally show ?thesis .
 100.369 +  qed
 100.370 +qed
 100.371 +
 100.372 +text {*
 100.373 +  \medskip The limit function is bounded by the norm @{text p} as
 100.374 +  well, since all elements in the chain are bounded by @{text p}.
 100.375 +*}
 100.376 +
 100.377 +lemma sup_norm_pres:
 100.378 +  assumes graph: "graph H h = \<Union>c"
 100.379 +    and M: "M = norm_pres_extensions E p F f"
 100.380 +    and cM: "c \<in> chain M"
 100.381 +  shows "\<forall>x \<in> H. h x \<le> p x"
 100.382 +proof
 100.383 +  fix x assume "x \<in> H"
 100.384 +  with M cM graph obtain H' h' where x': "x \<in> H'"
 100.385 +      and graphs: "graph H' h' \<subseteq> graph H h"
 100.386 +      and a: "\<forall>x \<in> H'. h' x \<le> p x"
 100.387 +    by (rule some_H'h' [elim_format]) blast
 100.388 +  from graphs x' have [symmetric]: "h' x = h x" ..
 100.389 +  also from a x' have "h' x \<le> p x " ..
 100.390 +  finally show "h x \<le> p x" .
 100.391 +qed
 100.392 +
 100.393 +text {*
 100.394 +  \medskip The following lemma is a property of linear forms on real
 100.395 +  vector spaces. It will be used for the lemma @{text abs_HahnBanach}
 100.396 +  (see page \pageref{abs-HahnBanach}). \label{abs-ineq-iff} For real
 100.397 +  vector spaces the following inequations are equivalent:
 100.398 +  \begin{center}
 100.399 +  \begin{tabular}{lll}
 100.400 +  @{text "\<forall>x \<in> H. \<bar>h x\<bar> \<le> p x"} & and &
 100.401 +  @{text "\<forall>x \<in> H. h x \<le> p x"} \\
 100.402 +  \end{tabular}
 100.403 +  \end{center}
 100.404 +*}
 100.405 +
 100.406 +lemma abs_ineq_iff:
 100.407 +  assumes "subspace H E" and "vectorspace E" and "seminorm E p"
 100.408 +    and "linearform H h"
 100.409 +  shows "(\<forall>x \<in> H. \<bar>h x\<bar> \<le> p x) = (\<forall>x \<in> H. h x \<le> p x)" (is "?L = ?R")
 100.410 +proof
 100.411 +  interpret subspace H E by fact
 100.412 +  interpret vectorspace E by fact
 100.413 +  interpret seminorm E p by fact
 100.414 +  interpret linearform H h by fact
 100.415 +  have H: "vectorspace H" using `vectorspace E` ..
 100.416 +  {
 100.417 +    assume l: ?L
 100.418 +    show ?R
 100.419 +    proof
 100.420 +      fix x assume x: "x \<in> H"
 100.421 +      have "h x \<le> \<bar>h x\<bar>" by arith
 100.422 +      also from l x have "\<dots> \<le> p x" ..
 100.423 +      finally show "h x \<le> p x" .
 100.424 +    qed
 100.425 +  next
 100.426 +    assume r: ?R
 100.427 +    show ?L
 100.428 +    proof
 100.429 +      fix x assume x: "x \<in> H"
 100.430 +      show "\<And>a b :: real. - a \<le> b \<Longrightarrow> b \<le> a \<Longrightarrow> \<bar>b\<bar> \<le> a"
 100.431 +        by arith
 100.432 +      from `linearform H h` and H x
 100.433 +      have "- h x = h (- x)" by (rule linearform.neg [symmetric])
 100.434 +      also
 100.435 +      from H x have "- x \<in> H" by (rule vectorspace.neg_closed)
 100.436 +      with r have "h (- x) \<le> p (- x)" ..
 100.437 +      also have "\<dots> = p x"
 100.438 +	using `seminorm E p` `vectorspace E`
 100.439 +      proof (rule seminorm.minus)
 100.440 +        from x show "x \<in> E" ..
 100.441 +      qed
 100.442 +      finally have "- h x \<le> p x" .
 100.443 +      then show "- p x \<le> h x" by simp
 100.444 +      from r x show "h x \<le> p x" ..
 100.445 +    qed
 100.446 +  }
 100.447 +qed
 100.448 +
 100.449 +end
   101.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   101.2 +++ b/src/HOL/HahnBanach/Linearform.thy	Tue Dec 30 11:10:01 2008 +0100
   101.3 @@ -0,0 +1,60 @@
   101.4 +(*  Title:      HOL/Real/HahnBanach/Linearform.thy
   101.5 +    Author:     Gertrud Bauer, TU Munich
   101.6 +*)
   101.7 +
   101.8 +header {* Linearforms *}
   101.9 +
  101.10 +theory Linearform
  101.11 +imports VectorSpace
  101.12 +begin
  101.13 +
  101.14 +text {*
  101.15 +  A \emph{linear form} is a function on a vector space into the reals
  101.16 +  that is additive and multiplicative.
  101.17 +*}
  101.18 +
  101.19 +locale linearform =
  101.20 +  fixes V :: "'a\<Colon>{minus, plus, zero, uminus} set" and f
  101.21 +  assumes add [iff]: "x \<in> V \<Longrightarrow> y \<in> V \<Longrightarrow> f (x + y) = f x + f y"
  101.22 +    and mult [iff]: "x \<in> V \<Longrightarrow> f (a \<cdot> x) = a * f x"
  101.23 +
  101.24 +declare linearform.intro [intro?]
  101.25 +
  101.26 +lemma (in linearform) neg [iff]:
  101.27 +  assumes "vectorspace V"
  101.28 +  shows "x \<in> V \<Longrightarrow> f (- x) = - f x"
  101.29 +proof -
  101.30 +  interpret vectorspace V by fact
  101.31 +  assume x: "x \<in> V"
  101.32 +  then have "f (- x) = f ((- 1) \<cdot> x)" by (simp add: negate_eq1)
  101.33 +  also from x have "\<dots> = (- 1) * (f x)" by (rule mult)
  101.34 +  also from x have "\<dots> = - (f x)" by simp
  101.35 +  finally show ?thesis .
  101.36 +qed
  101.37 +
  101.38 +lemma (in linearform) diff [iff]:
  101.39 +  assumes "vectorspace V"
  101.40 +  shows "x \<in> V \<Longrightarrow> y \<in> V \<Longrightarrow> f (x - y) = f x - f y"
  101.41 +proof -
  101.42 +  interpret vectorspace V by fact
  101.43 +  assume x: "x \<in> V" and y: "y \<in> V"
  101.44 +  then have "x - y = x + - y" by (rule diff_eq1)
  101.45 +  also have "f \<dots> = f x + f (- y)" by (rule add) (simp_all add: x y)
  101.46 +  also have "f (- y) = - f y" using `vectorspace V` y by (rule neg)
  101.47 +  finally show ?thesis by simp
  101.48 +qed
  101.49 +
  101.50 +text {* Every linear form yields @{text 0} for the @{text 0} vector. *}
  101.51 +
  101.52 +lemma (in linearform) zero [iff]:
  101.53 +  assumes "vectorspace V"
  101.54 +  shows "f 0 = 0"
  101.55 +proof -
  101.56 +  interpret vectorspace V by fact
  101.57 +  have "f 0 = f (0 - 0)" by simp
  101.58 +  also have "\<dots> = f 0 - f 0" using `vectorspace V` by (rule diff) simp_all
  101.59 +  also have "\<dots> = 0" by simp
  101.60 +  finally show ?thesis .
  101.61 +qed
  101.62 +
  101.63 +end
   102.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   102.2 +++ b/src/HOL/HahnBanach/NormedSpace.thy	Tue Dec 30 11:10:01 2008 +0100
   102.3 @@ -0,0 +1,117 @@
   102.4 +(*  Title:      HOL/Real/HahnBanach/NormedSpace.thy
   102.5 +    Author:     Gertrud Bauer, TU Munich
   102.6 +*)
   102.7 +
   102.8 +header {* Normed vector spaces *}
   102.9 +
  102.10 +theory NormedSpace
  102.11 +imports Subspace
  102.12 +begin
  102.13 +
  102.14 +subsection {* Quasinorms *}
  102.15 +
  102.16 +text {*
  102.17 +  A \emph{seminorm} @{text "\<parallel>\<cdot>\<parallel>"} is a function on a real vector space
  102.18 +  into the reals that has the following properties: it is positive
  102.19 +  definite, absolute homogenous and subadditive.
  102.20 +*}
  102.21 +
  102.22 +locale norm_syntax =
  102.23 +  fixes norm :: "'a \<Rightarrow> real"    ("\<parallel>_\<parallel>")
  102.24 +
  102.25 +locale seminorm = var_V + norm_syntax +
  102.26 +  constrains V :: "'a\<Colon>{minus, plus, zero, uminus} set"
  102.27 +  assumes ge_zero [iff?]: "x \<in> V \<Longrightarrow> 0 \<le> \<parallel>x\<parallel>"
  102.28 +    and abs_homogenous [iff?]: "x \<in> V \<Longrightarrow> \<parallel>a \<cdot> x\<parallel> = \<bar>a\<bar> * \<parallel>x\<parallel>"
  102.29 +    and subadditive [iff?]: "x \<in> V \<Longrightarrow> y \<in> V \<Longrightarrow> \<parallel>x + y\<parallel> \<le> \<parallel>x\<parallel> + \<parallel>y\<parallel>"
  102.30 +
  102.31 +declare seminorm.intro [intro?]
  102.32 +
  102.33 +lemma (in seminorm) diff_subadditive:
  102.34 +  assumes "vectorspace V"
  102.35 +  shows "x \<in> V \<Longrightarrow> y \<in> V \<Longrightarrow> \<parallel>x - y\<parallel> \<le> \<parallel>x\<parallel> + \<parallel>y\<parallel>"
  102.36 +proof -
  102.37 +  interpret vectorspace V by fact
  102.38 +  assume x: "x \<in> V" and y: "y \<in> V"
  102.39 +  then have "x - y = x + - 1 \<cdot> y"
  102.40 +    by (simp add: diff_eq2 negate_eq2a)
  102.41 +  also from x y have "\<parallel>\<dots>\<parallel> \<le> \<parallel>x\<parallel> + \<parallel>- 1 \<cdot> y\<parallel>"
  102.42 +    by (simp add: subadditive)
  102.43 +  also from y have "\<parallel>- 1 \<cdot> y\<parallel> = \<bar>- 1\<bar> * \<parallel>y\<parallel>"
  102.44 +    by (rule abs_homogenous)
  102.45 +  also have "\<dots> = \<parallel>y\<parallel>" by simp
  102.46 +  finally show ?thesis .
  102.47 +qed
  102.48 +
  102.49 +lemma (in seminorm) minus:
  102.50 +  assumes "vectorspace V"
  102.51 +  shows "x \<in> V \<Longrightarrow> \<parallel>- x\<parallel> = \<parallel>x\<parallel>"
  102.52 +proof -
  102.53 +  interpret vectorspace V by fact
  102.54 +  assume x: "x \<in> V"
  102.55 +  then have "- x = - 1 \<cdot> x" by (simp only: negate_eq1)
  102.56 +  also from x have "\<parallel>\<dots>\<parallel> = \<bar>- 1\<bar> * \<parallel>x\<parallel>"
  102.57 +    by (rule abs_homogenous)
  102.58 +  also have "\<dots> = \<parallel>x\<parallel>" by simp
  102.59 +  finally show ?thesis .
  102.60 +qed
  102.61 +
  102.62 +
  102.63 +subsection {* Norms *}
  102.64 +
  102.65 +text {*
  102.66 +  A \emph{norm} @{text "\<parallel>\<cdot>\<parallel>"} is a seminorm that maps only the
  102.67 +  @{text 0} vector to @{text 0}.
  102.68 +*}
  102.69 +
  102.70 +locale norm = seminorm +
  102.71 +  assumes zero_iff [iff]: "x \<in> V \<Longrightarrow> (\<parallel>x\<parallel> = 0) = (x = 0)"
  102.72 +
  102.73 +
  102.74 +subsection {* Normed vector spaces *}
  102.75 +
  102.76 +text {*
  102.77 +  A vector space together with a norm is called a \emph{normed
  102.78 +  space}.
  102.79 +*}
  102.80 +
  102.81 +locale normed_vectorspace = vectorspace + norm
  102.82 +
  102.83 +declare normed_vectorspace.intro [intro?]
  102.84 +
  102.85 +lemma (in normed_vectorspace) gt_zero [intro?]:
  102.86 +  "x \<in> V \<Longrightarrow> x \<noteq> 0 \<Longrightarrow> 0 < \<parallel>x\<parallel>"
  102.87 +proof -
  102.88 +  assume x: "x \<in> V" and neq: "x \<noteq> 0"
  102.89 +  from x have "0 \<le> \<parallel>x\<parallel>" ..
  102.90 +  also have [symmetric]: "\<dots> \<noteq> 0"
  102.91 +  proof
  102.92 +    assume "\<parallel>x\<parallel> = 0"
  102.93 +    with x have "x = 0" by simp
  102.94 +    with neq show False by contradiction
  102.95 +  qed
  102.96 +  finally show ?thesis .
  102.97 +qed
  102.98 +
  102.99 +text {*
 102.100 +  Any subspace of a normed vector space is again a normed vectorspace.
 102.101 +*}
 102.102 +
 102.103 +lemma subspace_normed_vs [intro?]:
 102.104 +  fixes F E norm
 102.105 +  assumes "subspace F E" "normed_vectorspace E norm"
 102.106 +  shows "normed_vectorspace F norm"
 102.107 +proof -
 102.108 +  interpret subspace F E by fact
 102.109 +  interpret normed_vectorspace E norm by fact
 102.110 +  show ?thesis
 102.111 +  proof
 102.112 +    show "vectorspace F" by (rule vectorspace) unfold_locales
 102.113 +  next
 102.114 +    have "NormedSpace.norm E norm" ..
 102.115 +    with subset show "NormedSpace.norm F norm"
 102.116 +      by (simp add: norm_def seminorm_def norm_axioms_def)
 102.117 +  qed
 102.118 +qed
 102.119 +
 102.120 +end
   103.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   103.2 +++ b/src/HOL/HahnBanach/README.html	Tue Dec 30 11:10:01 2008 +0100
   103.3 @@ -0,0 +1,38 @@
   103.4 +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
   103.5 +
   103.6 +<!-- $Id$ -->
   103.7 +
   103.8 +<HTML>
   103.9 +
  103.10 +<HEAD>
  103.11 +  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
  103.12 +  <TITLE>HOL/Real/HahnBanach/README</TITLE>
  103.13 +</HEAD>
  103.14 +
  103.15 +<BODY>
  103.16 +
  103.17 +<H3>The Hahn-Banach Theorem for Real Vector Spaces (Isabelle/Isar)</H3>
  103.18 +
  103.19 +Author: Gertrud Bauer, Technische Universit&auml;t M&uuml;nchen<P>
  103.20 +
  103.21 +This directory contains the proof of the Hahn-Banach theorem for real vectorspaces,
  103.22 +following H. Heuser, Funktionalanalysis, p. 228 -232.
  103.23 +The Hahn-Banach theorem is one of the fundamental theorems of functioal analysis.
  103.24 +It is a conclusion of Zorn's lemma.<P>
  103.25 +
  103.26 +Two different formaulations of the theorem are presented, one for general real vectorspaces
  103.27 +and its application to normed vectorspaces. <P>
  103.28 +
  103.29 +The theorem says, that every continous linearform, defined on arbitrary subspaces
  103.30 +(not only one-dimensional subspaces), can be extended to a continous linearform on
  103.31 +the whole vectorspace.
  103.32 +
  103.33 +
  103.34 +<HR>
  103.35 +
  103.36 +<ADDRESS>
  103.37 +<A NAME="bauerg@in.tum.de" HREF="mailto:bauerg@in.tum.de">bauerg@in.tum.de</A>
  103.38 +</ADDRESS>
  103.39 +
  103.40 +</BODY>
  103.41 +</HTML>
   104.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   104.2 +++ b/src/HOL/HahnBanach/ROOT.ML	Tue Dec 30 11:10:01 2008 +0100
   104.3 @@ -0,0 +1,8 @@
   104.4 +(*  Title:      HOL/Real/HahnBanach/ROOT.ML
   104.5 +    ID:         $Id$
   104.6 +    Author:     Gertrud Bauer, TU Munich
   104.7 +
   104.8 +The Hahn-Banach theorem for real vector spaces (Isabelle/Isar).
   104.9 +*)
  104.10 +
  104.11 +time_use_thy "HahnBanach";
   105.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   105.2 +++ b/src/HOL/HahnBanach/Subspace.thy	Tue Dec 30 11:10:01 2008 +0100
   105.3 @@ -0,0 +1,513 @@
   105.4 +(*  Title:      HOL/Real/HahnBanach/Subspace.thy
   105.5 +    Author:     Gertrud Bauer, TU Munich
   105.6 +*)
   105.7 +
   105.8 +header {* Subspaces *}
   105.9 +
  105.10 +theory Subspace
  105.11 +imports VectorSpace
  105.12 +begin
  105.13 +
  105.14 +subsection {* Definition *}
  105.15 +
  105.16 +text {*
  105.17 +  A non-empty subset @{text U} of a vector space @{text V} is a
  105.18 +  \emph{subspace} of @{text V}, iff @{text U} is closed under addition
  105.19 +  and scalar multiplication.
  105.20 +*}
  105.21 +
  105.22 +locale subspace =
  105.23 +  fixes U :: "'a\<Colon>{minus, plus, zero, uminus} set" and V
  105.24 +  assumes non_empty [iff, intro]: "U \<noteq> {}"
  105.25 +    and subset [iff]: "U \<subseteq> V"
  105.26 +    and add_closed [iff]: "x \<in> U \<Longrightarrow> y \<in> U \<Longrightarrow> x + y \<in> U"
  105.27 +    and mult_closed [iff]: "x \<in> U \<Longrightarrow> a \<cdot> x \<in> U"
  105.28 +
  105.29 +notation (symbols)
  105.30 +  subspace  (infix "\<unlhd>" 50)
  105.31 +
  105.32 +declare vectorspace.intro [intro?] subspace.intro [intro?]
  105.33 +
  105.34 +lemma subspace_subset [elim]: "U \<unlhd> V \<Longrightarrow> U \<subseteq> V"
  105.35 +  by (rule subspace.subset)
  105.36 +
  105.37 +lemma (in subspace) subsetD [iff]: "x \<in> U \<Longrightarrow> x \<in> V"
  105.38 +  using subset by blast
  105.39 +
  105.40 +lemma subspaceD [elim]: "U \<unlhd> V \<Longrightarrow> x \<in> U \<Longrightarrow> x \<in> V"
  105.41 +  by (rule subspace.subsetD)
  105.42 +
  105.43 +lemma rev_subspaceD [elim?]: "x \<in> U \<Longrightarrow> U \<unlhd> V \<Longrightarrow> x \<in> V"
  105.44 +  by (rule subspace.subsetD)
  105.45 +
  105.46 +lemma (in subspace) diff_closed [iff]:
  105.47 +  assumes "vectorspace V"
  105.48 +  assumes x: "x \<in> U" and y: "y \<in> U"
  105.49 +  shows "x - y \<in> U"
  105.50 +proof -
  105.51 +  interpret vectorspace V by fact
  105.52 +  from x y show ?thesis by (simp add: diff_eq1 negate_eq1)
  105.53 +qed
  105.54 +
  105.55 +text {*
  105.56 +  \medskip Similar as for linear spaces, the existence of the zero
  105.57 +  element in every subspace follows from the non-emptiness of the
  105.58 +  carrier set and by vector space laws.
  105.59 +*}
  105.60 +
  105.61 +lemma (in subspace) zero [intro]:
  105.62 +  assumes "vectorspace V"
  105.63 +  shows "0 \<in> U"
  105.64 +proof -
  105.65 +  interpret V!: vectorspace V by fact
  105.66 +  have "U \<noteq> {}" by (rule non_empty)
  105.67 +  then obtain x where x: "x \<in> U" by blast
  105.68 +  then have "x \<in> V" .. then have "0 = x - x" by simp
  105.69 +  also from `vectorspace V` x x have "\<dots> \<in> U" by (rule diff_closed)
  105.70 +  finally show ?thesis .
  105.71 +qed
  105.72 +
  105.73 +lemma (in subspace) neg_closed [iff]:
  105.74 +  assumes "vectorspace V"
  105.75 +  assumes x: "x \<in> U"
  105.76 +  shows "- x \<in> U"
  105.77 +proof -
  105.78 +  interpret vectorspace V by fact
  105.79 +  from x show ?thesis by (simp add: negate_eq1)
  105.80 +qed
  105.81 +
  105.82 +text {* \medskip Further derived laws: every subspace is a vector space. *}
  105.83 +
  105.84 +lemma (in subspace) vectorspace [iff]:
  105.85 +  assumes "vectorspace V"
  105.86 +  shows "vectorspace U"
  105.87 +proof -
  105.88 +  interpret vectorspace V by fact
  105.89 +  show ?thesis
  105.90 +  proof
  105.91 +    show "U \<noteq> {}" ..
  105.92 +    fix x y z assume x: "x \<in> U" and y: "y \<in> U" and z: "z \<in> U"
  105.93 +    fix a b :: real
  105.94 +    from x y show "x + y \<in> U" by simp
  105.95 +    from x show "a \<cdot> x \<in> U" by simp
  105.96 +    from x y z show "(x + y) + z = x + (y + z)" by (simp add: add_ac)
  105.97 +    from x y show "x + y = y + x" by (simp add: add_ac)
  105.98 +    from x show "x - x = 0" by simp
  105.99 +    from x show "0 + x = x" by simp
 105.100 +    from x y show "a \<cdot> (x + y) = a \<cdot> x + a \<cdot> y" by (simp add: distrib)
 105.101 +    from x show "(a + b) \<cdot> x = a \<cdot> x + b \<cdot> x" by (simp add: distrib)
 105.102 +    from x show "(a * b) \<cdot> x = a \<cdot> b \<cdot> x" by (simp add: mult_assoc)
 105.103 +    from x show "1 \<cdot> x = x" by simp
 105.104 +    from x show "- x = - 1 \<cdot> x" by (simp add: negate_eq1)
 105.105 +    from x y show "x - y = x + - y" by (simp add: diff_eq1)
 105.106 +  qed
 105.107 +qed
 105.108 +
 105.109 +
 105.110 +text {* The subspace relation is reflexive. *}
 105.111 +
 105.112 +lemma (in vectorspace) subspace_refl [intro]: "V \<unlhd> V"
 105.113 +proof
 105.114 +  show "V \<noteq> {}" ..
 105.115 +  show "V \<subseteq> V" ..
 105.116 +  fix x y assume x: "x \<in> V" and y: "y \<in> V"
 105.117 +  fix a :: real
 105.118 +  from x y show "x + y \<in> V" by simp
 105.119 +  from x show "a \<cdot> x \<in> V" by simp
 105.120 +qed
 105.121 +
 105.122 +text {* The subspace relation is transitive. *}
 105.123 +
 105.124 +lemma (in vectorspace) subspace_trans [trans]:
 105.125 +  "U \<unlhd> V \<Longrightarrow> V \<unlhd> W \<Longrightarrow> U \<unlhd> W"
 105.126 +proof
 105.127 +  assume uv: "U \<unlhd> V" and vw: "V \<unlhd> W"
 105.128 +  from uv show "U \<noteq> {}" by (rule subspace.non_empty)
 105.129 +  show "U \<subseteq> W"
 105.130 +  proof -
 105.131 +    from uv have "U \<subseteq> V" by (rule subspace.subset)
 105.132 +    also from vw have "V \<subseteq> W" by (rule subspace.subset)
 105.133 +    finally show ?thesis .
 105.134 +  qed
 105.135 +  fix x y assume x: "x \<in> U" and y: "y \<in> U"
 105.136 +  from uv and x y show "x + y \<in> U" by (rule subspace.add_closed)
 105.137 +  from uv and x show "\<And>a. a \<cdot> x \<in> U" by (rule subspace.mult_closed)
 105.138 +qed
 105.139 +
 105.140 +
 105.141 +subsection {* Linear closure *}
 105.142 +
 105.143 +text {*
 105.144 +  The \emph{linear closure} of a vector @{text x} is the set of all
 105.145 +  scalar multiples of @{text x}.
 105.146 +*}
 105.147 +
 105.148 +definition
 105.149 +  lin :: "('a::{minus, plus, zero}) \<Rightarrow> 'a set" where
 105.150 +  "lin x = {a \<cdot> x | a. True}"
 105.151 +
 105.152 +lemma linI [intro]: "y = a \<cdot> x \<Longrightarrow> y \<in> lin x"
 105.153 +  unfolding lin_def by blast
 105.154 +
 105.155 +lemma linI' [iff]: "a \<cdot> x \<in> lin x"
 105.156 +  unfolding lin_def by blast
 105.157 +
 105.158 +lemma linE [elim]: "x \<in> lin v \<Longrightarrow> (\<And>a::real. x = a \<cdot> v \<Longrightarrow> C) \<Longrightarrow> C"
 105.159 +  unfolding lin_def by blast
 105.160 +
 105.161 +
 105.162 +text {* Every vector is contained in its linear closure. *}
 105.163 +
 105.164 +lemma (in vectorspace) x_lin_x [iff]: "x \<in> V \<Longrightarrow> x \<in> lin x"
 105.165 +proof -
 105.166 +  assume "x \<in> V"
 105.167 +  then have "x = 1 \<cdot> x" by simp
 105.168 +  also have "\<dots> \<in> lin x" ..
 105.169 +  finally show ?thesis .
 105.170 +qed
 105.171 +
 105.172 +lemma (in vectorspace) "0_lin_x" [iff]: "x \<in> V \<Longrightarrow> 0 \<in> lin x"
 105.173 +proof
 105.174 +  assume "x \<in> V"
 105.175 +  then show "0 = 0 \<cdot> x" by simp
 105.176 +qed
 105.177 +
 105.178 +text {* Any linear closure is a subspace. *}
 105.179 +
 105.180 +lemma (in vectorspace) lin_subspace [intro]:
 105.181 +  "x \<in> V \<Longrightarrow> lin x \<unlhd> V"
 105.182 +proof
 105.183 +  assume x: "x \<in> V"
 105.184 +  then show "lin x \<noteq> {}" by (auto simp add: x_lin_x)
 105.185 +  show "lin x \<subseteq> V"
 105.186 +  proof
 105.187 +    fix x' assume "x' \<in> lin x"
 105.188 +    then obtain a where "x' = a \<cdot> x" ..
 105.189 +    with x show "x' \<in> V" by simp
 105.190 +  qed
 105.191 +  fix x' x'' assume x': "x' \<in> lin x" and x'': "x'' \<in> lin x"
 105.192 +  show "x' + x'' \<in> lin x"
 105.193 +  proof -
 105.194 +    from x' obtain a' where "x' = a' \<cdot> x" ..
 105.195 +    moreover from x'' obtain a'' where "x'' = a'' \<cdot> x" ..
 105.196 +    ultimately have "x' + x'' = (a' + a'') \<cdot> x"
 105.197 +      using x by (simp add: distrib)
 105.198 +    also have "\<dots> \<in> lin x" ..
 105.199 +    finally show ?thesis .
 105.200 +  qed
 105.201 +  fix a :: real
 105.202 +  show "a \<cdot> x' \<in> lin x"
 105.203 +  proof -
 105.204 +    from x' obtain a' where "x' = a' \<cdot> x" ..
 105.205 +    with x have "a \<cdot> x' = (a * a') \<cdot> x" by (simp add: mult_assoc)
 105.206 +    also have "\<dots> \<in> lin x" ..
 105.207 +    finally show ?thesis .
 105.208 +  qed
 105.209 +qed
 105.210 +
 105.211 +
 105.212 +text {* Any linear closure is a vector space. *}
 105.213 +
 105.214 +lemma (in vectorspace) lin_vectorspace [intro]:
 105.215 +  assumes "x \<in> V"
 105.216 +  shows "vectorspace (lin x)"
 105.217 +proof -
 105.218 +  from `x \<in> V` have "subspace (lin x) V"
 105.219 +    by (rule lin_subspace)
 105.220 +  from this and vectorspace_axioms show ?thesis
 105.221 +    by (rule subspace.vectorspace)
 105.222 +qed
 105.223 +
 105.224 +
 105.225 +subsection {* Sum of two vectorspaces *}
 105.226 +
 105.227 +text {*
 105.228 +  The \emph{sum} of two vectorspaces @{text U} and @{text V} is the
 105.229 +  set of all sums of elements from @{text U} and @{text V}.
 105.230 +*}
 105.231 +
 105.232 +instantiation "fun" :: (type, type) plus
 105.233 +begin
 105.234 +
 105.235 +definition
 105.236 +  sum_def: "plus_fun U V = {u + v | u v. u \<in> U \<and> v \<in> V}"  (* FIXME not fully general!? *)
 105.237 +
 105.238 +instance ..
 105.239 +
 105.240 +end
 105.241 +
 105.242 +lemma sumE [elim]:
 105.243 +    "x \<in> U + V \<Longrightarrow> (\<And>u v. x = u + v \<Longrightarrow> u \<in> U \<Longrightarrow> v \<in> V \<Longrightarrow> C) \<Longrightarrow> C"
 105.244 +  unfolding sum_def by blast
 105.245 +
 105.246 +lemma sumI [intro]:
 105.247 +    "u \<in> U \<Longrightarrow> v \<in> V \<Longrightarrow> x = u + v \<Longrightarrow> x \<in> U + V"
 105.248 +  unfolding sum_def by blast
 105.249 +
 105.250 +lemma sumI' [intro]:
 105.251 +    "u \<in> U \<Longrightarrow> v \<in> V \<Longrightarrow> u + v \<in> U + V"
 105.252 +  unfolding sum_def by blast
 105.253 +
 105.254 +text {* @{text U} is a subspace of @{text "U + V"}. *}
 105.255 +
 105.256 +lemma subspace_sum1 [iff]:
 105.257 +  assumes "vectorspace U" "vectorspace V"
 105.258 +  shows "U \<unlhd> U + V"
 105.259 +proof -
 105.260 +  interpret vectorspace U by fact
 105.261 +  interpret vectorspace V by fact
 105.262 +  show ?thesis
 105.263 +  proof
 105.264 +    show "U \<noteq> {}" ..
 105.265 +    show "U \<subseteq> U + V"
 105.266 +    proof
 105.267 +      fix x assume x: "x \<in> U"
 105.268 +      moreover have "0 \<in> V" ..
 105.269 +      ultimately have "x + 0 \<in> U + V" ..
 105.270 +      with x show "x \<in> U + V" by simp
 105.271 +    qed
 105.272 +    fix x y assume x: "x \<in> U" and "y \<in> U"
 105.273 +    then show "x + y \<in> U" by simp
 105.274 +    from x show "\<And>a. a \<cdot> x \<in> U" by simp
 105.275 +  qed
 105.276 +qed
 105.277 +
 105.278 +text {* The sum of two subspaces is again a subspace. *}
 105.279 +
 105.280 +lemma sum_subspace [intro?]:
 105.281 +  assumes "subspace U E" "vectorspace E" "subspace V E"
 105.282 +  shows "U + V \<unlhd> E"
 105.283 +proof -
 105.284 +  interpret subspace U E by fact
 105.285 +  interpret vectorspace E by fact
 105.286 +  interpret subspace V E by fact
 105.287 +  show ?thesis
 105.288 +  proof
 105.289 +    have "0 \<in> U + V"
 105.290 +    proof
 105.291 +      show "0 \<in> U" using `vectorspace E` ..
 105.292 +      show "0 \<in> V" using `vectorspace E` ..
 105.293 +      show "(0::'a) = 0 + 0" by simp
 105.294 +    qed
 105.295 +    then show "U + V \<noteq> {}" by blast
 105.296 +    show "U + V \<subseteq> E"
 105.297 +    proof
 105.298 +      fix x assume "x \<in> U + V"
 105.299 +      then obtain u v where "x = u + v" and
 105.300 +	"u \<in> U" and "v \<in> V" ..
 105.301 +      then show "x \<in> E" by simp
 105.302 +    qed
 105.303 +    fix x y assume x: "x \<in> U + V" and y: "y \<in> U + V"
 105.304 +    show "x + y \<in> U + V"
 105.305 +    proof -
 105.306 +      from x obtain ux vx where "x = ux + vx" and "ux \<in> U" and "vx \<in> V" ..
 105.307 +      moreover
 105.308 +      from y obtain uy vy where "y = uy + vy" and "uy \<in> U" and "vy \<in> V" ..
 105.309 +      ultimately
 105.310 +      have "ux + uy \<in> U"
 105.311 +	and "vx + vy \<in> V"
 105.312 +	and "x + y = (ux + uy) + (vx + vy)"
 105.313 +	using x y by (simp_all add: add_ac)
 105.314 +      then show ?thesis ..
 105.315 +    qed
 105.316 +    fix a show "a \<cdot> x \<in> U + V"
 105.317 +    proof -
 105.318 +      from x obtain u v where "x = u + v" and "u \<in> U" and "v \<in> V" ..
 105.319 +      then have "a \<cdot> u \<in> U" and "a \<cdot> v \<in> V"
 105.320 +	and "a \<cdot> x = (a \<cdot> u) + (a \<cdot> v)" by (simp_all add: distrib)
 105.321 +      then show ?thesis ..
 105.322 +    qed
 105.323 +  qed
 105.324 +qed
 105.325 +
 105.326 +text{* The sum of two subspaces is a vectorspace. *}
 105.327 +
 105.328 +lemma sum_vs [intro?]:
 105.329 +    "U \<unlhd> E \<Longrightarrow> V \<unlhd> E \<Longrightarrow> vectorspace E \<Longrightarrow> vectorspace (U + V)"
 105.330 +  by (rule subspace.vectorspace) (rule sum_subspace)
 105.331 +
 105.332 +
 105.333 +subsection {* Direct sums *}
 105.334 +
 105.335 +text {*
 105.336 +  The sum of @{text U} and @{text V} is called \emph{direct}, iff the
 105.337 +  zero element is the only common element of @{text U} and @{text
 105.338 +  V}. For every element @{text x} of the direct sum of @{text U} and
 105.339 +  @{text V} the decomposition in @{text "x = u + v"} with
 105.340 +  @{text "u \<in> U"} and @{text "v \<in> V"} is unique.
 105.341 +*}
 105.342 +
 105.343 +lemma decomp:
 105.344 +  assumes "vectorspace E" "subspace U E" "subspace V E"
 105.345 +  assumes direct: "U \<inter> V = {0}"
 105.346 +    and u1: "u1 \<in> U" and u2: "u2 \<in> U"
 105.347 +    and v1: "v1 \<in> V" and v2: "v2 \<in> V"
 105.348 +    and sum: "u1 + v1 = u2 + v2"
 105.349 +  shows "u1 = u2 \<and> v1 = v2"
 105.350 +proof -
 105.351 +  interpret vectorspace E by fact
 105.352 +  interpret subspace U E by fact
 105.353 +  interpret subspace V E by fact
 105.354 +  show ?thesis
 105.355 +  proof
 105.356 +    have U: "vectorspace U"  (* FIXME: use interpret *)
 105.357 +      using `subspace U E` `vectorspace E` by (rule subspace.vectorspace)
 105.358 +    have V: "vectorspace V"
 105.359 +      using `subspace V E` `vectorspace E` by (rule subspace.vectorspace)
 105.360 +    from u1 u2 v1 v2 and sum have eq: "u1 - u2 = v2 - v1"
 105.361 +      by (simp add: add_diff_swap)
 105.362 +    from u1 u2 have u: "u1 - u2 \<in> U"
 105.363 +      by (rule vectorspace.diff_closed [OF U])
 105.364 +    with eq have v': "v2 - v1 \<in> U" by (simp only:)
 105.365 +    from v2 v1 have v: "v2 - v1 \<in> V"
 105.366 +      by (rule vectorspace.diff_closed [OF V])
 105.367 +    with eq have u': " u1 - u2 \<in> V" by (simp only:)
 105.368 +    
 105.369 +    show "u1 = u2"
 105.370 +    proof (rule add_minus_eq)
 105.371 +      from u1 show "u1 \<in> E" ..
 105.372 +      from u2 show "u2 \<in> E" ..
 105.373 +      from u u' and direct show "u1 - u2 = 0" by blast
 105.374 +    qed
 105.375 +    show "v1 = v2"
 105.376 +    proof (rule add_minus_eq [symmetric])
 105.377 +      from v1 show "v1 \<in> E" ..
 105.378 +      from v2 show "v2 \<in> E" ..
 105.379 +      from v v' and direct show "v2 - v1 = 0" by blast
 105.380 +    qed
 105.381 +  qed
 105.382 +qed
 105.383 +
 105.384 +text {*
 105.385 +  An application of the previous lemma will be used in the proof of
 105.386 +  the Hahn-Banach Theorem (see page \pageref{decomp-H-use}): for any
 105.387 +  element @{text "y + a \<cdot> x\<^sub>0"} of the direct sum of a
 105.388 +  vectorspace @{text H} and the linear closure of @{text "x\<^sub>0"}
 105.389 +  the components @{text "y \<in> H"} and @{text a} are uniquely
 105.390 +  determined.
 105.391 +*}
 105.392 +
 105.393 +lemma decomp_H':
 105.394 +  assumes "vectorspace E" "subspace H E"
 105.395 +  assumes y1: "y1 \<in> H" and y2: "y2 \<in> H"
 105.396 +    and x': "x' \<notin> H"  "x' \<in> E"  "x' \<noteq> 0"
 105.397 +    and eq: "y1 + a1 \<cdot> x' = y2 + a2 \<cdot> x'"
 105.398 +  shows "y1 = y2 \<and> a1 = a2"
 105.399 +proof -
 105.400 +  interpret vectorspace E by fact
 105.401 +  interpret subspace H E by fact
 105.402 +  show ?thesis
 105.403 +  proof
 105.404 +    have c: "y1 = y2 \<and> a1 \<cdot> x' = a2 \<cdot> x'"
 105.405 +    proof (rule decomp)
 105.406 +      show "a1 \<cdot> x' \<in> lin x'" ..
 105.407 +      show "a2 \<cdot> x' \<in> lin x'" ..
 105.408 +      show "H \<inter> lin x' = {0}"
 105.409 +      proof
 105.410 +	show "H \<inter> lin x' \<subseteq> {0}"
 105.411 +	proof
 105.412 +          fix x assume x: "x \<in> H \<inter> lin x'"
 105.413 +          then obtain a where xx': "x = a \<cdot> x'"
 105.414 +            by blast
 105.415 +          have "x = 0"
 105.416 +          proof cases
 105.417 +            assume "a = 0"
 105.418 +            with xx' and x' show ?thesis by simp
 105.419 +          next
 105.420 +            assume a: "a \<noteq> 0"
 105.421 +            from x have "x \<in> H" ..
 105.422 +            with xx' have "inverse a \<cdot> a \<cdot> x' \<in> H" by simp
 105.423 +            with a and x' have "x' \<in> H" by (simp add: mult_assoc2)
 105.424 +            with `x' \<notin> H` show ?thesis by contradiction
 105.425 +          qed
 105.426 +          then show "x \<in> {0}" ..
 105.427 +	qed
 105.428 +	show "{0} \<subseteq> H \<inter> lin x'"
 105.429 +	proof -
 105.430 +          have "0 \<in> H" using `vectorspace E` ..
 105.431 +          moreover have "0 \<in> lin x'" using `x' \<in> E` ..
 105.432 +          ultimately show ?thesis by blast
 105.433 +	qed
 105.434 +      qed
 105.435 +      show "lin x' \<unlhd> E" using `x' \<in> E` ..
 105.436 +    qed (rule `vectorspace E`, rule `subspace H E`, rule y1, rule y2, rule eq)
 105.437 +    then show "y1 = y2" ..
 105.438 +    from c have "a1 \<cdot> x' = a2 \<cdot> x'" ..
 105.439 +    with x' show "a1 = a2" by (simp add: mult_right_cancel)
 105.440 +  qed
 105.441 +qed
 105.442 +
 105.443 +text {*
 105.444 +  Since for any element @{text "y + a \<cdot> x'"} of the direct sum of a
 105.445 +  vectorspace @{text H} and the linear closure of @{text x'} the
 105.446 +  components @{text "y \<in> H"} and @{text a} are unique, it follows from
 105.447 +  @{text "y \<in> H"} that @{text "a = 0"}.
 105.448 +*}
 105.449 +
 105.450 +lemma decomp_H'_H:
 105.451 +  assumes "vectorspace E" "subspace H E"
 105.452 +  assumes t: "t \<in> H"
 105.453 +    and x': "x' \<notin> H"  "x' \<in> E"  "x' \<noteq> 0"
 105.454 +  shows "(SOME (y, a). t = y + a \<cdot> x' \<and> y \<in> H) = (t, 0)"
 105.455 +proof -
 105.456 +  interpret vectorspace E by fact
 105.457 +  interpret subspace H E by fact
 105.458 +  show ?thesis
 105.459 +  proof (rule, simp_all only: split_paired_all split_conv)
 105.460 +    from t x' show "t = t + 0 \<cdot> x' \<and> t \<in> H" by simp
 105.461 +    fix y and a assume ya: "t = y + a \<cdot> x' \<and> y \<in> H"
 105.462 +    have "y = t \<and> a = 0"
 105.463 +    proof (rule decomp_H')
 105.464 +      from ya x' show "y + a \<cdot> x' = t + 0 \<cdot> x'" by simp
 105.465 +      from ya show "y \<in> H" ..
 105.466 +    qed (rule `vectorspace E`, rule `subspace H E`, rule t, (rule x')+)
 105.467 +    with t x' show "(y, a) = (y + a \<cdot> x', 0)" by simp
 105.468 +  qed
 105.469 +qed
 105.470 +
 105.471 +text {*
 105.472 +  The components @{text "y \<in> H"} and @{text a} in @{text "y + a \<cdot> x'"}
 105.473 +  are unique, so the function @{text h'} defined by
 105.474 +  @{text "h' (y + a \<cdot> x') = h y + a \<cdot> \<xi>"} is definite.
 105.475 +*}
 105.476 +
 105.477 +lemma h'_definite:
 105.478 +  fixes H
 105.479 +  assumes h'_def:
 105.480 +    "h' \<equiv> (\<lambda>x. let (y, a) = SOME (y, a). (x = y + a \<cdot> x' \<and> y \<in> H)
 105.481 +                in (h y) + a * xi)"
 105.482 +    and x: "x = y + a \<cdot> x'"
 105.483 +  assumes "vectorspace E" "subspace H E"
 105.484 +  assumes y: "y \<in> H"
 105.485 +    and x': "x' \<notin> H"  "x' \<in> E"  "x' \<noteq> 0"
 105.486 +  shows "h' x = h y + a * xi"
 105.487 +proof -
 105.488 +  interpret vectorspace E by fact
 105.489 +  interpret subspace H E by fact
 105.490 +  from x y x' have "x \<in> H + lin x'" by auto
 105.491 +  have "\<exists>!p. (\<lambda>(y, a). x = y + a \<cdot> x' \<and> y \<in> H) p" (is "\<exists>!p. ?P p")
 105.492 +  proof (rule ex_ex1I)
 105.493 +    from x y show "\<exists>p. ?P p" by blast
 105.494 +    fix p q assume p: "?P p" and q: "?P q"
 105.495 +    show "p = q"
 105.496 +    proof -
 105.497 +      from p have xp: "x = fst p + snd p \<cdot> x' \<and> fst p \<in> H"
 105.498 +        by (cases p) simp
 105.499 +      from q have xq: "x = fst q + snd q \<cdot> x' \<and> fst q \<in> H"
 105.500 +        by (cases q) simp
 105.501 +      have "fst p = fst q \<and> snd p = snd q"
 105.502 +      proof (rule decomp_H')
 105.503 +        from xp show "fst p \<in> H" ..
 105.504 +        from xq show "fst q \<in> H" ..
 105.505 +        from xp and xq show "fst p + snd p \<cdot> x' = fst q + snd q \<cdot> x'"
 105.506 +          by simp
 105.507 +      qed (rule `vectorspace E`, rule `subspace H E`, (rule x')+)
 105.508 +      then show ?thesis by (cases p, cases q) simp
 105.509 +    qed
 105.510 +  qed
 105.511 +  then have eq: "(SOME (y, a). x = y + a \<cdot> x' \<and> y \<in> H) = (y, a)"
 105.512 +    by (rule some1_equality) (simp add: x y)
 105.513 +  with h'_def show "h' x = h y + a * xi" by (simp add: Let_def)
 105.514 +qed
 105.515 +
 105.516 +end
   106.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   106.2 +++ b/src/HOL/HahnBanach/VectorSpace.thy	Tue Dec 30 11:10:01 2008 +0100
   106.3 @@ -0,0 +1,419 @@
   106.4 +(*  Title:      HOL/Real/HahnBanach/VectorSpace.thy
   106.5 +    ID:         $Id$
   106.6 +    Author:     Gertrud Bauer, TU Munich
   106.7 +*)
   106.8 +
   106.9 +header {* Vector spaces *}
  106.10 +
  106.11 +theory VectorSpace
  106.12 +imports Real Bounds Zorn
  106.13 +begin
  106.14 +
  106.15 +subsection {* Signature *}
  106.16 +
  106.17 +text {*
  106.18 +  For the definition of real vector spaces a type @{typ 'a} of the
  106.19 +  sort @{text "{plus, minus, zero}"} is considered, on which a real
  106.20 +  scalar multiplication @{text \<cdot>} is declared.
  106.21 +*}
  106.22 +
  106.23 +consts
  106.24 +  prod  :: "real \<Rightarrow> 'a::{plus, minus, zero} \<Rightarrow> 'a"     (infixr "'(*')" 70)
  106.25 +
  106.26 +notation (xsymbols)
  106.27 +  prod  (infixr "\<cdot>" 70)
  106.28 +notation (HTML output)
  106.29 +  prod  (infixr "\<cdot>" 70)
  106.30 +
  106.31 +
  106.32 +subsection {* Vector space laws *}
  106.33 +
  106.34 +text {*
  106.35 +  A \emph{vector space} is a non-empty set @{text V} of elements from
  106.36 +  @{typ 'a} with the following vector space laws: The set @{text V} is
  106.37 +  closed under addition and scalar multiplication, addition is
  106.38 +  associative and commutative; @{text "- x"} is the inverse of @{text
  106.39 +  x} w.~r.~t.~addition and @{text 0} is the neutral element of
  106.40 +  addition.  Addition and multiplication are distributive; scalar
  106.41 +  multiplication is associative and the real number @{text "1"} is
  106.42 +  the neutral element of scalar multiplication.
  106.43 +*}
  106.44 +
  106.45 +locale var_V = fixes V
  106.46 +
  106.47 +locale vectorspace = var_V +
  106.48 +  assumes non_empty [iff, intro?]: "V \<noteq> {}"
  106.49 +    and add_closed [iff]: "x \<in> V \<Longrightarrow> y \<in> V \<Longrightarrow> x + y \<in> V"
  106.50 +    and mult_closed [iff]: "x \<in> V \<Longrightarrow> a \<cdot> x \<in> V"
  106.51 +    and add_assoc: "x \<in> V \<Longrightarrow> y \<in> V \<Longrightarrow> z \<in> V \<Longrightarrow> (x + y) + z = x + (y + z)"
  106.52 +    and add_commute: "x \<in> V \<Longrightarrow> y \<in> V \<Longrightarrow> x + y = y + x"
  106.53 +    and diff_self [simp]: "x \<in> V \<Longrightarrow> x - x = 0"
  106.54 +    and add_zero_left [simp]: "x \<in> V \<Longrightarrow> 0 + x = x"
  106.55 +    and add_mult_distrib1: "x \<in> V \<Longrightarrow> y \<in> V \<Longrightarrow> a \<cdot> (x + y) = a \<cdot> x + a \<cdot> y"
  106.56 +    and add_mult_distrib2: "x \<in> V \<Longrightarrow> (a + b) \<cdot> x = a \<cdot> x + b \<cdot> x"
  106.57 +    and mult_assoc: "x \<in> V \<Longrightarrow> (a * b) \<cdot> x = a \<cdot> (b \<cdot> x)"
  106.58 +    and mult_1 [simp]: "x \<in> V \<Longrightarrow> 1 \<cdot> x = x"
  106.59 +    and negate_eq1: "x \<in> V \<Longrightarrow> - x = (- 1) \<cdot> x"
  106.60 +    and diff_eq1: "x \<in> V \<Longrightarrow> y \<in> V \<Longrightarrow> x - y = x + - y"
  106.61 +
  106.62 +lemma (in vectorspace) negate_eq2: "x \<in> V \<Longrightarrow> (- 1) \<cdot> x = - x"
  106.63 +  by (rule negate_eq1 [symmetric])
  106.64 +
  106.65 +lemma (in vectorspace) negate_eq2a: "x \<in> V \<Longrightarrow> -1 \<cdot> x = - x"
  106.66 +  by (simp add: negate_eq1)
  106.67 +
  106.68 +lemma (in vectorspace) diff_eq2: "x \<in> V \<Longrightarrow> y \<in> V \<Longrightarrow> x + - y = x - y"
  106.69 +  by (rule diff_eq1 [symmetric])
  106.70 +
  106.71 +lemma (in vectorspace) diff_closed [iff]: "x \<in> V \<Longrightarrow> y \<in> V \<Longrightarrow> x - y \<in> V"
  106.72 +  by (simp add: diff_eq1 negate_eq1)
  106.73 +
  106.74 +lemma (in vectorspace) neg_closed [iff]: "x \<in> V \<Longrightarrow> - x \<in> V"
  106.75 +  by (simp add: negate_eq1)
  106.76 +
  106.77 +lemma (in vectorspace) add_left_commute:
  106.78 +  "x \<in> V \<Longrightarrow> y \<in> V \<Longrightarrow> z \<in> V \<Longrightarrow> x + (y + z) = y + (x + z)"
  106.79 +proof -
  106.80 +  assume xyz: "x \<in> V"  "y \<in> V"  "z \<in> V"
  106.81 +  then have "x + (y + z) = (x + y) + z"
  106.82 +    by (simp only: add_assoc)
  106.83 +  also from xyz have "\<dots> = (y + x) + z" by (simp only: add_commute)
  106.84 +  also from xyz have "\<dots> = y + (x + z)" by (simp only: add_assoc)
  106.85 +  finally show ?thesis .
  106.86 +qed
  106.87 +
  106.88 +theorems (in vectorspace) add_ac =
  106.89 +  add_assoc add_commute add_left_commute
  106.90 +
  106.91 +
  106.92 +text {* The existence of the zero element of a vector space
  106.93 +  follows from the non-emptiness of carrier set. *}
  106.94 +
  106.95 +lemma (in vectorspace) zero [iff]: "0 \<in> V"
  106.96 +proof -
  106.97 +  from non_empty obtain x where x: "x \<in> V" by blast
  106.98 +  then have "0 = x - x" by (rule diff_self [symmetric])
  106.99 +  also from x x have "\<dots> \<in> V" by (rule diff_closed)
 106.100 +  finally show ?thesis .
 106.101 +qed
 106.102 +
 106.103 +lemma (in vectorspace) add_zero_right [simp]:
 106.104 +  "x \<in> V \<Longrightarrow>  x + 0 = x"
 106.105 +proof -
 106.106 +  assume x: "x \<in> V"
 106.107 +  from this and zero have "x + 0 = 0 + x" by (rule add_commute)
 106.108 +  also from x have "\<dots> = x" by (rule add_zero_left)
 106.109 +  finally show ?thesis .
 106.110 +qed
 106.111 +
 106.112 +lemma (in vectorspace) mult_assoc2:
 106.113 +    "x \<in> V \<Longrightarrow> a \<cdot> b \<cdot> x = (a * b) \<cdot> x"
 106.114 +  by (simp only: mult_assoc)
 106.115 +
 106.116 +lemma (in vectorspace) diff_mult_distrib1:
 106.117 +    "x \<in> V \<Longrightarrow> y \<in> V \<Longrightarrow> a \<cdot> (x - y) = a \<cdot> x - a \<cdot> y"
 106.118 +  by (simp add: diff_eq1 negate_eq1 add_mult_distrib1 mult_assoc2)
 106.119 +
 106.120 +lemma (in vectorspace) diff_mult_distrib2:
 106.121 +  "x \<in> V \<Longrightarrow> (a - b) \<cdot> x = a \<cdot> x - (b \<cdot> x)"
 106.122 +proof -
 106.123 +  assume x: "x \<in> V"
 106.124 +  have " (a - b) \<cdot> x = (a + - b) \<cdot> x"
 106.125 +    by (simp add: real_diff_def)
 106.126 +  also from x have "\<dots> = a \<cdot> x + (- b) \<cdot> x"
 106.127 +    by (rule add_mult_distrib2)
 106.128 +  also from x have "\<dots> = a \<cdot> x + - (b \<cdot> x)"
 106.129 +    by (simp add: negate_eq1 mult_assoc2)
 106.130 +  also from x have "\<dots> = a \<cdot> x - (b \<cdot> x)"
 106.131 +    by (simp add: diff_eq1)
 106.132 +  finally show ?thesis .
 106.133 +qed
 106.134 +
 106.135 +lemmas (in vectorspace) distrib =
 106.136 +  add_mult_distrib1 add_mult_distrib2
 106.137 +  diff_mult_distrib1 diff_mult_distrib2
 106.138 +
 106.139 +
 106.140 +text {* \medskip Further derived laws: *}
 106.141 +
 106.142 +lemma (in vectorspace) mult_zero_left [simp]:
 106.143 +  "x \<in> V \<Longrightarrow> 0 \<cdot> x = 0"
 106.144 +proof -
 106.145 +  assume x: "x \<in> V"
 106.146 +  have "0 \<cdot> x = (1 - 1) \<cdot> x" by simp
 106.147 +  also have "\<dots> = (1 + - 1) \<cdot> x" by simp
 106.148 +  also from x have "\<dots> =  1 \<cdot> x + (- 1) \<cdot> x"
 106.149 +    by (rule add_mult_distrib2)
 106.150 +  also from x have "\<dots> = x + (- 1) \<cdot> x" by simp
 106.151 +  also from x have "\<dots> = x + - x" by (simp add: negate_eq2a)
 106.152 +  also from x have "\<dots> = x - x" by (simp add: diff_eq2)
 106.153 +  also from x have "\<dots> = 0" by simp
 106.154 +  finally show ?thesis .
 106.155 +qed
 106.156 +
 106.157 +lemma (in vectorspace) mult_zero_right [simp]:
 106.158 +  "a \<cdot> 0 = (0::'a)"
 106.159 +proof -
 106.160 +  have "a \<cdot> 0 = a \<cdot> (0 - (0::'a))" by simp
 106.161 +  also have "\<dots> =  a \<cdot> 0 - a \<cdot> 0"
 106.162 +    by (rule diff_mult_distrib1) simp_all
 106.163 +  also have "\<dots> = 0" by simp
 106.164 +  finally show ?thesis .
 106.165 +qed
 106.166 +
 106.167 +lemma (in vectorspace) minus_mult_cancel [simp]:
 106.168 +    "x \<in> V \<Longrightarrow> (- a) \<cdot> - x = a \<cdot> x"
 106.169 +  by (simp add: negate_eq1 mult_assoc2)
 106.170 +
 106.171 +lemma (in vectorspace) add_minus_left_eq_diff:
 106.172 +  "x \<in> V \<Longrightarrow> y \<in> V \<Longrightarrow> - x + y = y - x"
 106.173 +proof -
 106.174 +  assume xy: "x \<in> V"  "y \<in> V"
 106.175 +  then have "- x + y = y + - x" by (simp add: add_commute)
 106.176 +  also from xy have "\<dots> = y - x" by (simp add: diff_eq1)
 106.177 +  finally show ?thesis .
 106.178 +qed
 106.179 +
 106.180 +lemma (in vectorspace) add_minus [simp]:
 106.181 +    "x \<in> V \<Longrightarrow> x + - x = 0"
 106.182 +  by (simp add: diff_eq2)
 106.183 +
 106.184 +lemma (in vectorspace) add_minus_left [simp]:
 106.185 +    "x \<in> V \<Longrightarrow> - x + x = 0"
 106.186 +  by (simp add: diff_eq2 add_commute)
 106.187 +
 106.188 +lemma (in vectorspace) minus_minus [simp]:
 106.189 +    "x \<in> V \<Longrightarrow> - (- x) = x"
 106.190 +  by (simp add: negate_eq1 mult_assoc2)
 106.191 +
 106.192 +lemma (in vectorspace) minus_zero [simp]:
 106.193 +    "- (0::'a) = 0"
 106.194 +  by (simp add: negate_eq1)
 106.195 +
 106.196 +lemma (in vectorspace) minus_zero_iff [simp]:
 106.197 +  "x \<in> V \<Longrightarrow> (- x = 0) = (x = 0)"
 106.198 +proof
 106.199 +  assume x: "x \<in> V"
 106.200 +  {
 106.201 +    from x have "x = - (- x)" by (simp add: minus_minus)
 106.202 +    also assume "- x = 0"
 106.203 +    also have "- \<dots> = 0" by (rule minus_zero)
 106.204 +    finally show "x = 0" .
 106.205 +  next
 106.206 +    assume "x = 0"
 106.207 +    then show "- x = 0" by simp
 106.208 +  }
 106.209 +qed
 106.210 +
 106.211 +lemma (in vectorspace) add_minus_cancel [simp]:
 106.212 +    "x \<in> V \<Longrightarrow> y \<in> V \<Longrightarrow> x + (- x + y) = y"
 106.213 +  by (simp add: add_assoc [symmetric] del: add_commute)
 106.214 +
 106.215 +lemma (in vectorspace) minus_add_cancel [simp]:
 106.216 +    "x \<in> V \<Longrightarrow> y \<in> V \<Longrightarrow> - x + (x + y) = y"
 106.217 +  by (simp add: add_assoc [symmetric] del: add_commute)
 106.218 +
 106.219 +lemma (in vectorspace) minus_add_distrib [simp]:
 106.220 +    "x \<in> V \<Longrightarrow> y \<in> V \<Longrightarrow> - (x + y) = - x + - y"
 106.221 +  by (simp add: negate_eq1 add_mult_distrib1)
 106.222 +
 106.223 +lemma (in vectorspace) diff_zero [simp]:
 106.224 +    "x \<in> V \<Longrightarrow> x - 0 = x"
 106.225 +  by (simp add: diff_eq1)
 106.226 +
 106.227 +lemma (in vectorspace) diff_zero_right [simp]:
 106.228 +    "x \<in> V \<Longrightarrow> 0 - x = - x"
 106.229 +  by (simp add: diff_eq1)
 106.230 +
 106.231 +lemma (in vectorspace) add_left_cancel:
 106.232 +  "x \<in> V \<Longrightarrow> y \<in> V \<Longrightarrow> z \<in> V \<Longrightarrow> (x + y = x + z) = (y = z)"
 106.233 +proof
 106.234 +  assume x: "x \<in> V" and y: "y \<in> V" and z: "z \<in> V"
 106.235 +  {
 106.236 +    from y have "y = 0 + y" by simp
 106.237 +    also from x y have "\<dots> = (- x + x) + y" by simp
 106.238 +    also from x y have "\<dots> = - x + (x + y)"
 106.239 +      by (simp add: add_assoc neg_closed)
 106.240 +    also assume "x + y = x + z"
 106.241 +    also from x z have "- x + (x + z) = - x + x + z"
 106.242 +      by (simp add: add_assoc [symmetric] neg_closed)
 106.243 +    also from x z have "\<dots> = z" by simp
 106.244 +    finally show "y = z" .
 106.245 +  next
 106.246 +    assume "y = z"
 106.247 +    then show "x + y = x + z" by (simp only:)
 106.248 +  }
 106.249 +qed
 106.250 +
 106.251 +lemma (in vectorspace) add_right_cancel:
 106.252 +    "x \<in> V \<Longrightarrow> y \<in> V \<Longrightarrow> z \<in> V \<Longrightarrow> (y + x = z + x) = (y = z)"
 106.253 +  by (simp only: add_commute add_left_cancel)
 106.254 +
 106.255 +lemma (in vectorspace) add_assoc_cong:
 106.256 +  "x \<in> V \<Longrightarrow> y \<in> V \<Longrightarrow> x' \<in> V \<Longrightarrow> y' \<in> V \<Longrightarrow> z \<in> V
 106.257 +    \<Longrightarrow> x + y = x' + y' \<Longrightarrow> x + (y + z) = x' + (y' + z)"
 106.258 +  by (simp only: add_assoc [symmetric])
 106.259 +
 106.260 +lemma (in vectorspace) mult_left_commute:
 106.261 +    "x \<in> V \<Longrightarrow> a \<cdot> b \<cdot> x = b \<cdot> a \<cdot> x"
 106.262 +  by (simp add: real_mult_commute mult_assoc2)
 106.263 +
 106.264 +lemma (in vectorspace) mult_zero_uniq:
 106.265 +  "x \<in> V \<Longrightarrow> x \<noteq> 0 \<Longrightarrow> a \<cdot> x = 0 \<Longrightarrow> a = 0"
 106.266 +proof (rule classical)
 106.267 +  assume a: "a \<noteq> 0"
 106.268 +  assume x: "x \<in> V"  "x \<noteq> 0" and ax: "a \<cdot> x = 0"
 106.269 +  from x a have "x = (inverse a * a) \<cdot> x" by simp
 106.270 +  also from `x \<in> V` have "\<dots> = inverse a \<cdot> (a \<cdot> x)" by (rule mult_assoc)
 106.271 +  also from ax have "\<dots> = inverse a \<cdot> 0" by simp
 106.272 +  also have "\<dots> = 0" by simp
 106.273 +  finally have "x = 0" .
 106.274 +  with `x \<noteq> 0` show "a = 0" by contradiction
 106.275 +qed
 106.276 +
 106.277 +lemma (in vectorspace) mult_left_cancel:
 106.278 +  "x \<in> V \<Longrightarrow> y \<in> V \<Longrightarrow> a \<noteq> 0 \<Longrightarrow> (a \<cdot> x = a \<cdot> y) = (x = y)"
 106.279 +proof
 106.280 +  assume x: "x \<in> V" and y: "y \<in> V" and a: "a \<noteq> 0"
 106.281 +  from x have "x = 1 \<cdot> x" by simp
 106.282 +  also from a have "\<dots> = (inverse a * a) \<cdot> x" by simp
 106.283 +  also from x have "\<dots> = inverse a \<cdot> (a \<cdot> x)"
 106.284 +    by (simp only: mult_assoc)
 106.285 +  also assume "a \<cdot> x = a \<cdot> y"
 106.286 +  also from a y have "inverse a \<cdot> \<dots> = y"
 106.287 +    by (simp add: mult_assoc2)
 106.288 +  finally show "x = y" .
 106.289 +next
 106.290 +  assume "x = y"
 106.291 +  then show "a \<cdot> x = a \<cdot> y" by (simp only:)
 106.292 +qed
 106.293 +
 106.294 +lemma (in vectorspace) mult_right_cancel:
 106.295 +  "x \<in> V \<Longrightarrow> x \<noteq> 0 \<Longrightarrow> (a \<cdot> x = b \<cdot> x) = (a = b)"
 106.296 +proof
 106.297 +  assume x: "x \<in> V" and neq: "x \<noteq> 0"
 106.298 +  {
 106.299 +    from x have "(a - b) \<cdot> x = a \<cdot> x - b \<cdot> x"
 106.300 +      by (simp add: diff_mult_distrib2)
 106.301 +    also assume "a \<cdot> x = b \<cdot> x"
 106.302 +    with x have "a \<cdot> x - b \<cdot> x = 0" by simp
 106.303 +    finally have "(a - b) \<cdot> x = 0" .
 106.304 +    with x neq have "a - b = 0" by (rule mult_zero_uniq)
 106.305 +    then show "a = b" by simp
 106.306 +  next
 106.307 +    assume "a = b"
 106.308 +    then show "a \<cdot> x = b \<cdot> x" by (simp only:)
 106.309 +  }
 106.310 +qed
 106.311 +
 106.312 +lemma (in vectorspace) eq_diff_eq:
 106.313 +  "x \<in> V \<Longrightarrow> y \<in> V \<Longrightarrow> z \<in> V \<Longrightarrow> (x = z - y) = (x + y = z)"
 106.314 +proof
 106.315 +  assume x: "x \<in> V" and y: "y \<in> V" and z: "z \<in> V"
 106.316 +  {
 106.317 +    assume "x = z - y"
 106.318 +    then have "x + y = z - y + y" by simp
 106.319 +    also from y z have "\<dots> = z + - y + y"
 106.320 +      by (simp add: diff_eq1)
 106.321 +    also have "\<dots> = z + (- y + y)"
 106.322 +      by (rule add_assoc) (simp_all add: y z)
 106.323 +    also from y z have "\<dots> = z + 0"
 106.324 +      by (simp only: add_minus_left)
 106.325 +    also from z have "\<dots> = z"
 106.326 +      by (simp only: add_zero_right)
 106.327 +    finally show "x + y = z" .
 106.328 +  next
 106.329 +    assume "x + y = z"
 106.330 +    then have "z - y = (x + y) - y" by simp
 106.331 +    also from x y have "\<dots> = x + y + - y"
 106.332 +      by (simp add: diff_eq1)
 106.333 +    also have "\<dots> = x + (y + - y)"
 106.334 +      by (rule add_assoc) (simp_all add: x y)
 106.335 +    also from x y have "\<dots> = x" by simp
 106.336 +    finally show "x = z - y" ..
 106.337 +  }
 106.338 +qed
 106.339 +
 106.340 +lemma (in vectorspace) add_minus_eq_minus:
 106.341 +  "x \<in> V \<Longrightarrow> y \<in> V \<Longrightarrow> x + y = 0 \<Longrightarrow> x = - y"
 106.342 +proof -
 106.343 +  assume x: "x \<in> V" and y: "y \<in> V"
 106.344 +  from x y have "x = (- y + y) + x" by simp
 106.345 +  also from x y have "\<dots> = - y + (x + y)" by (simp add: add_ac)
 106.346 +  also assume "x + y = 0"
 106.347 +  also from y have "- y + 0 = - y" by simp
 106.348 +  finally show "x = - y" .
 106.349 +qed
 106.350 +
 106.351 +lemma (in vectorspace) add_minus_eq:
 106.352 +  "x \<in> V \<Longrightarrow> y \<in> V \<Longrightarrow> x - y = 0 \<Longrightarrow> x = y"
 106.353 +proof -
 106.354 +  assume x: "x \<in> V" and y: "y \<in> V"
 106.355 +  assume "x - y = 0"
 106.356 +  with x y have eq: "x + - y = 0" by (simp add: diff_eq1)
 106.357 +  with _ _ have "x = - (- y)"
 106.358 +    by (rule add_minus_eq_minus) (simp_all add: x y)
 106.359 +  with x y show "x = y" by simp
 106.360 +qed
 106.361 +
 106.362 +lemma (in vectorspace) add_diff_swap:
 106.363 +  "a \<in> V \<Longrightarrow> b \<in> V \<Longrightarrow> c \<in> V \<Longrightarrow> d \<in> V \<Longrightarrow> a + b = c + d
 106.364 +    \<Longrightarrow> a - c = d - b"
 106.365 +proof -
 106.366 +  assume vs: "a \<in> V"  "b \<in> V"  "c \<in> V"  "d \<in> V"
 106.367 +    and eq: "a + b = c + d"
 106.368 +  then have "- c + (a + b) = - c + (c + d)"
 106.369 +    by (simp add: add_left_cancel)
 106.370 +  also have "\<dots> = d" using `c \<in> V` `d \<in> V` by (rule minus_add_cancel)
 106.371 +  finally have eq: "- c + (a + b) = d" .
 106.372 +  from vs have "a - c = (- c + (a + b)) + - b"
 106.373 +    by (simp add: add_ac diff_eq1)
 106.374 +  also from vs eq have "\<dots>  = d + - b"
 106.375 +    by (simp add: add_right_cancel)
 106.376 +  also from vs have "\<dots> = d - b" by (simp add: diff_eq2)
 106.377 +  finally show "a - c = d - b" .
 106.378 +qed
 106.379 +
 106.380 +lemma (in vectorspace) vs_add_cancel_21:
 106.381 +  "x \<in> V \<Longrightarrow> y \<in> V \<Longrightarrow> z \<in> V \<Longrightarrow> u \<in> V
 106.382 +    \<Longrightarrow> (x + (y + z) = y + u) = (x + z = u)"
 106.383 +proof
 106.384 +  assume vs: "x \<in> V"  "y \<in> V"  "z \<in> V"  "u \<in> V"
 106.385 +  {
 106.386 +    from vs have "x + z = - y + y + (x + z)" by simp
 106.387 +    also have "\<dots> = - y + (y + (x + z))"
 106.388 +      by (rule add_assoc) (simp_all add: vs)
 106.389 +    also from vs have "y + (x + z) = x + (y + z)"
 106.390 +      by (simp add: add_ac)
 106.391 +    also assume "x + (y + z) = y + u"
 106.392 +    also from vs have "- y + (y + u) = u" by simp
 106.393 +    finally show "x + z = u" .
 106.394 +  next
 106.395 +    assume "x + z = u"
 106.396 +    with vs show "x + (y + z) = y + u"
 106.397 +      by (simp only: add_left_commute [of x])
 106.398 +  }
 106.399 +qed
 106.400 +
 106.401 +lemma (in vectorspace) add_cancel_end:
 106.402 +  "x \<in> V \<Longrightarrow> y \<in> V \<Longrightarrow> z \<in> V \<Longrightarrow> (x + (y + z) = y) = (x = - z)"
 106.403 +proof
 106.404 +  assume vs: "x \<in> V"  "y \<in> V"  "z \<in> V"
 106.405 +  {
 106.406 +    assume "x + (y + z) = y"
 106.407 +    with vs have "(x + z) + y = 0 + y"
 106.408 +      by (simp add: add_ac)
 106.409 +    with vs have "x + z = 0"
 106.410 +      by (simp only: add_right_cancel add_closed zero)
 106.411 +    with vs show "x = - z" by (simp add: add_minus_eq_minus)
 106.412 +  next
 106.413 +    assume eq: "x = - z"
 106.414 +    then have "x + (y + z) = - z + (y + z)" by simp
 106.415 +    also have "\<dots> = y + (- z + z)"
 106.416 +      by (rule add_left_commute) (simp_all add: vs)
 106.417 +    also from vs have "\<dots> = y"  by simp
 106.418 +    finally show "x + (y + z) = y" .
 106.419 +  }
 106.420 +qed
 106.421 +
 106.422 +end
   107.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   107.2 +++ b/src/HOL/HahnBanach/ZornLemma.thy	Tue Dec 30 11:10:01 2008 +0100
   107.3 @@ -0,0 +1,57 @@
   107.4 +(*  Title:      HOL/Real/HahnBanach/ZornLemma.thy
   107.5 +    Author:     Gertrud Bauer, TU Munich
   107.6 +*)
   107.7 +
   107.8 +header {* Zorn's Lemma *}
   107.9 +
  107.10 +theory ZornLemma
  107.11 +imports Zorn
  107.12 +begin
  107.13 +
  107.14 +text {*
  107.15 +  Zorn's Lemmas states: if every linear ordered subset of an ordered
  107.16 +  set @{text S} has an upper bound in @{text S}, then there exists a
  107.17 +  maximal element in @{text S}.  In our application, @{text S} is a
  107.18 +  set of sets ordered by set inclusion. Since the union of a chain of
  107.19 +  sets is an upper bound for all elements of the chain, the conditions
  107.20 +  of Zorn's lemma can be modified: if @{text S} is non-empty, it
  107.21 +  suffices to show that for every non-empty chain @{text c} in @{text
  107.22 +  S} the union of @{text c} also lies in @{text S}.
  107.23 +*}
  107.24 +
  107.25 +theorem Zorn's_Lemma:
  107.26 +  assumes r: "\<And>c. c \<in> chain S \<Longrightarrow> \<exists>x. x \<in> c \<Longrightarrow> \<Union>c \<in> S"
  107.27 +    and aS: "a \<in> S"
  107.28 +  shows "\<exists>y \<in> S. \<forall>z \<in> S. y \<subseteq> z \<longrightarrow> y = z"
  107.29 +proof (rule Zorn_Lemma2)
  107.30 +  show "\<forall>c \<in> chain S. \<exists>y \<in> S. \<forall>z \<in> c. z \<subseteq> y"
  107.31 +  proof
  107.32 +    fix c assume "c \<in> chain S"
  107.33 +    show "\<exists>y \<in> S. \<forall>z \<in> c. z \<subseteq> y"
  107.34 +    proof cases
  107.35 +
  107.36 +      txt {* If @{text c} is an empty chain, then every element in
  107.37 +	@{text S} is an upper bound of @{text c}. *}
  107.38 +
  107.39 +      assume "c = {}"
  107.40 +      with aS show ?thesis by fast
  107.41 +
  107.42 +      txt {* If @{text c} is non-empty, then @{text "\<Union>c"} is an upper
  107.43 +	bound of @{text c}, lying in @{text S}. *}
  107.44 +
  107.45 +    next
  107.46 +      assume "c \<noteq> {}"
  107.47 +      show ?thesis
  107.48 +      proof
  107.49 +        show "\<forall>z \<in> c. z \<subseteq> \<Union>c" by fast
  107.50 +        show "\<Union>c \<in> S"
  107.51 +        proof (rule r)
  107.52 +          from `c \<noteq> {}` show "\<exists>x. x \<in> c" by fast
  107.53 +	  show "c \<in> chain S" by fact
  107.54 +        qed
  107.55 +      qed
  107.56 +    qed
  107.57 +  qed
  107.58 +qed
  107.59 +
  107.60 +end
   108.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   108.2 +++ b/src/HOL/HahnBanach/document/root.bib	Tue Dec 30 11:10:01 2008 +0100
   108.3 @@ -0,0 +1,27 @@
   108.4 +
   108.5 +@Book{Heuser:1986,
   108.6 +  author = 	 {H. Heuser},
   108.7 +  title = 	 {Funktionalanalysis: Theorie und Anwendung},
   108.8 +  publisher = 	 {Teubner},
   108.9 +  year = 	 1986
  108.10 +}
  108.11 +
  108.12 +@InCollection{Narici:1996,
  108.13 +  author = 	 {L. Narici and E. Beckenstein},
  108.14 +  title = 	 {The {Hahn-Banach Theorem}: The Life and Times},
  108.15 +  booktitle = 	 {Topology Atlas},
  108.16 +  publisher =	 {York University, Toronto, Ontario, Canada},
  108.17 +  year =	 1996,
  108.18 +  note =	 {\url{http://at.yorku.ca/topology/preprint.htm} and
  108.19 +                  \url{http://at.yorku.ca/p/a/a/a/16.htm}}
  108.20 +}
  108.21 +
  108.22 +@Article{Nowak:1993,
  108.23 +  author =       {B. Nowak and A. Trybulec},
  108.24 +  title =	 {{Hahn-Banach} Theorem},
  108.25 +  journal =      {Journal of Formalized Mathematics},
  108.26 +  year =         {1993},
  108.27 +  volume =       {5},
  108.28 +  institution =  {University of Bialystok},
  108.29 +  note =         {\url{http://mizar.uwb.edu.pl/JFM/Vol5/hahnban.html}}
  108.30 +}
   109.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   109.2 +++ b/src/HOL/HahnBanach/document/root.tex	Tue Dec 30 11:10:01 2008 +0100
   109.3 @@ -0,0 +1,83 @@
   109.4 +\documentclass[10pt,a4paper,twoside]{article}
   109.5 +\usepackage{graphicx}
   109.6 +\usepackage{latexsym,theorem}
   109.7 +\usepackage{isabelle,isabellesym}
   109.8 +\usepackage{pdfsetup} %last one!
   109.9 +
  109.10 +\isabellestyle{it}
  109.11 +\urlstyle{rm}
  109.12 +
  109.13 +\newcommand{\isasymsup}{\isamath{\sup\,}}
  109.14 +\newcommand{\skp}{\smallskip}
  109.15 +
  109.16 +
  109.17 +\begin{document}
  109.18 +
  109.19 +\pagestyle{headings}
  109.20 +\pagenumbering{arabic}
  109.21 +
  109.22 +\title{The Hahn-Banach Theorem \\ for Real Vector Spaces}
  109.23 +\author{Gertrud Bauer \\ \url{http://www.in.tum.de/~bauerg/}}
  109.24 +\maketitle
  109.25 +
  109.26 +\begin{abstract}
  109.27 +  The Hahn-Banach Theorem is one of the most fundamental results in functional
  109.28 +  analysis. We present a fully formal proof of two versions of the theorem,
  109.29 +  one for general linear spaces and another for normed spaces.  This
  109.30 +  development is based on simply-typed classical set-theory, as provided by
  109.31 +  Isabelle/HOL.
  109.32 +\end{abstract}
  109.33 +
  109.34 +
  109.35 +\tableofcontents
  109.36 +\parindent 0pt \parskip 0.5ex
  109.37 +
  109.38 +\clearpage
  109.39 +\section{Preface}
  109.40 +
  109.41 +This is a fully formal proof of the Hahn-Banach Theorem. It closely follows
  109.42 +the informal presentation given in Heuser's textbook \cite[{\S} 36]{Heuser:1986}.
  109.43 +Another formal proof of the same theorem has been done in Mizar
  109.44 +\cite{Nowak:1993}.  A general overview of the relevance and history of the
  109.45 +Hahn-Banach Theorem is given by Narici and Beckenstein \cite{Narici:1996}.
  109.46 +
  109.47 +\medskip The document is structured as follows.  The first part contains
  109.48 +definitions of basic notions of linear algebra: vector spaces, subspaces,
  109.49 +normed spaces, continuous linear-forms, norm of functions and an order on
  109.50 +functions by domain extension.  The second part contains some lemmas about the
  109.51 +supremum (w.r.t.\ the function order) and extension of non-maximal functions.
  109.52 +With these preliminaries, the main proof of the theorem (in its two versions)
  109.53 +is conducted in the third part.  The dependencies of individual theories are
  109.54 +as follows.
  109.55 +
  109.56 +\begin{center}
  109.57 +  \includegraphics[scale=0.5]{session_graph}  
  109.58 +\end{center}
  109.59 +
  109.60 +\clearpage
  109.61 +\part {Basic Notions}
  109.62 +
  109.63 +\input{Bounds}
  109.64 +\input{VectorSpace}
  109.65 +\input{Subspace}
  109.66 +\input{NormedSpace}
  109.67 +\input{Linearform}
  109.68 +\input{FunctionOrder}
  109.69 +\input{FunctionNorm}
  109.70 +\input{ZornLemma}
  109.71 +
  109.72 +\clearpage
  109.73 +\part {Lemmas for the Proof}
  109.74 +
  109.75 +\input{HahnBanachSupLemmas}
  109.76 +\input{HahnBanachExtLemmas}
  109.77 +\input{HahnBanachLemmas}
  109.78 +
  109.79 +\clearpage
  109.80 +\part {The Main Proof}
  109.81 +
  109.82 +\input{HahnBanach}
  109.83 +\bibliographystyle{abbrv}
  109.84 +\bibliography{root}
  109.85 +
  109.86 +\end{document}
   110.1 --- a/src/HOL/Hyperreal/SEQ.thy	Tue Dec 30 08:18:54 2008 +0100
   110.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   110.3 @@ -1,1136 +0,0 @@
   110.4 -(*  Title       : SEQ.thy
   110.5 -    Author      : Jacques D. Fleuriot
   110.6 -    Copyright   : 1998  University of Cambridge
   110.7 -    Description : Convergence of sequences and series
   110.8 -    Conversion to Isar and new proofs by Lawrence C Paulson, 2004
   110.9 -    Additional contributions by Jeremy Avigad and Brian Huffman
  110.10 -*)
  110.11 -
  110.12 -header {* Sequences and Convergence *}
  110.13 -
  110.14 -theory SEQ
  110.15 -imports "../Real/RealVector" "../RComplete"
  110.16 -begin
  110.17 -
  110.18 -definition
  110.19 -  Zseq :: "[nat \<Rightarrow> 'a::real_normed_vector] \<Rightarrow> bool" where
  110.20 -    --{*Standard definition of sequence converging to zero*}
  110.21 -  [code del]: "Zseq X = (\<forall>r>0. \<exists>no. \<forall>n\<ge>no. norm (X n) < r)"
  110.22 -
  110.23 -definition
  110.24 -  LIMSEQ :: "[nat => 'a::real_normed_vector, 'a] => bool"
  110.25 -    ("((_)/ ----> (_))" [60, 60] 60) where
  110.26 -    --{*Standard definition of convergence of sequence*}
  110.27 -  [code del]: "X ----> L = (\<forall>r. 0 < r --> (\<exists>no. \<forall>n. no \<le> n --> norm (X n - L) < r))"
  110.28 -
  110.29 -definition
  110.30 -  lim :: "(nat => 'a::real_normed_vector) => 'a" where
  110.31 -    --{*Standard definition of limit using choice operator*}
  110.32 -  "lim X = (THE L. X ----> L)"
  110.33 -
  110.34 -definition
  110.35 -  convergent :: "(nat => 'a::real_normed_vector) => bool" where
  110.36 -    --{*Standard definition of convergence*}
  110.37 -  "convergent X = (\<exists>L. X ----> L)"
  110.38 -
  110.39 -definition
  110.40 -  Bseq :: "(nat => 'a::real_normed_vector) => bool" where
  110.41 -    --{*Standard definition for bounded sequence*}
  110.42 -  [code del]: "Bseq X = (\<exists>K>0.\<forall>n. norm (X n) \<le> K)"
  110.43 -
  110.44 -definition
  110.45 -  monoseq :: "(nat=>real)=>bool" where
  110.46 -    --{*Definition for monotonicity*}
  110.47 -  [code del]: "monoseq X = ((\<forall>m. \<forall>n\<ge>m. X m \<le> X n) | (\<forall>m. \<forall>n\<ge>m. X n \<le> X m))"
  110.48 -
  110.49 -definition
  110.50 -  subseq :: "(nat => nat) => bool" where
  110.51 -    --{*Definition of subsequence*}
  110.52 -  [code del]:   "subseq f = (\<forall>m. \<forall>n>m. (f m) < (f n))"
  110.53 -
  110.54 -definition
  110.55 -  Cauchy :: "(nat => 'a::real_normed_vector) => bool" where
  110.56 -    --{*Standard definition of the Cauchy condition*}
  110.57 -  [code del]: "Cauchy X = (\<forall>e>0. \<exists>M. \<forall>m \<ge> M. \<forall>n \<ge> M. norm (X m - X n) < e)"
  110.58 -
  110.59 -
  110.60 -subsection {* Bounded Sequences *}
  110.61 -
  110.62 -lemma BseqI': assumes K: "\<And>n. norm (X n) \<le> K" shows "Bseq X"
  110.63 -unfolding Bseq_def
  110.64 -proof (intro exI conjI allI)
  110.65 -  show "0 < max K 1" by simp
  110.66 -next
  110.67 -  fix n::nat
  110.68 -  have "norm (X n) \<le> K" by (rule K)
  110.69 -  thus "norm (X n) \<le> max K 1" by simp
  110.70 -qed
  110.71 -
  110.72 -lemma BseqE: "\<lbrakk>Bseq X; \<And>K. \<lbrakk>0 < K; \<forall>n. norm (X n) \<le> K\<rbrakk> \<Longrightarrow> Q\<rbrakk> \<Longrightarrow> Q"
  110.73 -unfolding Bseq_def by auto
  110.74 -
  110.75 -lemma BseqI2': assumes K: "\<forall>n\<ge>N. norm (X n) \<le> K" shows "Bseq X"
  110.76 -proof (rule BseqI')
  110.77 -  let ?A = "norm ` X ` {..N}"
  110.78 -  have 1: "finite ?A" by simp
  110.79 -  fix n::nat
  110.80 -  show "norm (X n) \<le> max K (Max ?A)"
  110.81 -  proof (cases rule: linorder_le_cases)
  110.82 -    assume "n \<ge> N"
  110.83 -    hence "norm (X n) \<le> K" using K by simp
  110.84 -    thus "norm (X n) \<le> max K (Max ?A)" by simp
  110.85 -  next
  110.86 -    assume "n \<le> N"
  110.87 -    hence "norm (X n) \<in> ?A" by simp
  110.88 -    with 1 have "norm (X n) \<le> Max ?A" by (rule Max_ge)
  110.89 -    thus "norm (X n) \<le> max K (Max ?A)" by simp
  110.90 -  qed
  110.91 -qed
  110.92 -
  110.93 -lemma Bseq_ignore_initial_segment: "Bseq X \<Longrightarrow> Bseq (\<lambda>n. X (n + k))"
  110.94 -unfolding Bseq_def by auto
  110.95 -
  110.96 -lemma Bseq_offset: "Bseq (\<lambda>n. X (n + k)) \<Longrightarrow> Bseq X"
  110.97 -apply (erule BseqE)
  110.98 -apply (rule_tac N="k" and K="K" in BseqI2')
  110.99 -apply clarify
 110.100 -apply (drule_tac x="n - k" in spec, simp)
 110.101 -done
 110.102 -
 110.103 -
 110.104 -subsection {* Sequences That Converge to Zero *}
 110.105 -
 110.106 -lemma ZseqI:
 110.107 -  "(\<And>r. 0 < r \<Longrightarrow> \<exists>no. \<forall>n\<ge>no. norm (X n) < r) \<Longrightarrow> Zseq X"
 110.108 -unfolding Zseq_def by simp
 110.109 -
 110.110 -lemma ZseqD:
 110.111 -  "\<lbrakk>Zseq X; 0 < r\<rbrakk> \<Longrightarrow> \<exists>no. \<forall>n\<ge>no. norm (X n) < r"
 110.112 -unfolding Zseq_def by simp
 110.113 -
 110.114 -lemma Zseq_zero: "Zseq (\<lambda>n. 0)"
 110.115 -unfolding Zseq_def by simp
 110.116 -
 110.117 -lemma Zseq_const_iff: "Zseq (\<lambda>n. k) = (k = 0)"
 110.118 -unfolding Zseq_def by force
 110.119 -
 110.120 -lemma Zseq_norm_iff: "Zseq (\<lambda>n. norm (X n)) = Zseq (\<lambda>n. X n)"
 110.121 -unfolding Zseq_def by simp
 110.122 -
 110.123 -lemma Zseq_imp_Zseq:
 110.124 -  assumes X: "Zseq X"
 110.125 -  assumes Y: "\<And>n. norm (Y n) \<le> norm (X n) * K"
 110.126 -  shows "Zseq (\<lambda>n. Y n)"
 110.127 -proof (cases)
 110.128 -  assume K: "0 < K"
 110.129 -  show ?thesis
 110.130 -  proof (rule ZseqI)
 110.131 -    fix r::real assume "0 < r"
 110.132 -    hence "0 < r / K"
 110.133 -      using K by (rule divide_pos_pos)
 110.134 -    then obtain N where "\<forall>n\<ge>N. norm (X n) < r / K"
 110.135 -      using ZseqD [OF X] by fast
 110.136 -    hence "\<forall>n\<ge>N. norm (X n) * K < r"
 110.137 -      by (simp add: pos_less_divide_eq K)
 110.138 -    hence "\<forall>n\<ge>N. norm (Y n) < r"
 110.139 -      by (simp add: order_le_less_trans [OF Y])
 110.140 -    thus "\<exists>N. \<forall>n\<ge>N. norm (Y n) < r" ..
 110.141 -  qed
 110.142 -next
 110.143 -  assume "\<not> 0 < K"
 110.144 -  hence K: "K \<le> 0" by (simp only: linorder_not_less)
 110.145 -  {
 110.146 -    fix n::nat
 110.147 -    have "norm (Y n) \<le> norm (X n) * K" by (rule Y)
 110.148 -    also have "\<dots> \<le> norm (X n) * 0"
 110.149 -      using K norm_ge_zero by (rule mult_left_mono)
 110.150 -    finally have "norm (Y n) = 0" by simp
 110.151 -  }
 110.152 -  thus ?thesis by (simp add: Zseq_zero)
 110.153 -qed
 110.154 -
 110.155 -lemma Zseq_le: "\<lbrakk>Zseq Y; \<forall>n. norm (X n) \<le> norm (Y n)\<rbrakk> \<Longrightarrow> Zseq X"
 110.156 -by (erule_tac K="1" in Zseq_imp_Zseq, simp)
 110.157 -
 110.158 -lemma Zseq_add:
 110.159 -  assumes X: "Zseq X"
 110.160 -  assumes Y: "Zseq Y"
 110.161 -  shows "Zseq (\<lambda>n. X n + Y n)"
 110.162 -proof (rule ZseqI)
 110.163 -  fix r::real assume "0 < r"
 110.164 -  hence r: "0 < r / 2" by simp
 110.165 -  obtain M where M: "\<forall>n\<ge>M. norm (X n) < r/2"
 110.166 -    using ZseqD [OF X r] by fast
 110.167 -  obtain N where N: "\<forall>n\<ge>N. norm (Y n) < r/2"
 110.168 -    using ZseqD [OF Y r] by fast
 110.169 -  show "\<exists>N. \<forall>n\<ge>N. norm (X n + Y n) < r"
 110.170 -  proof (intro exI allI impI)
 110.171 -    fix n assume n: "max M N \<le> n"
 110.172 -    have "norm (X n + Y n) \<le> norm (X n) + norm (Y n)"
 110.173 -      by (rule norm_triangle_ineq)
 110.174 -    also have "\<dots> < r/2 + r/2"
 110.175 -    proof (rule add_strict_mono)
 110.176 -      from M n show "norm (X n) < r/2" by simp
 110.177 -      from N n show "norm (Y n) < r/2" by simp
 110.178 -    qed
 110.179 -    finally show "norm (X n + Y n) < r" by simp
 110.180 -  qed
 110.181 -qed
 110.182 -
 110.183 -lemma Zseq_minus: "Zseq X \<Longrightarrow> Zseq (\<lambda>n. - X n)"
 110.184 -unfolding Zseq_def by simp
 110.185 -
 110.186 -lemma Zseq_diff: "\<lbrakk>Zseq X; Zseq Y\<rbrakk> \<Longrightarrow> Zseq (\<lambda>n. X n - Y n)"
 110.187 -by (simp only: diff_minus Zseq_add Zseq_minus)
 110.188 -
 110.189 -lemma (in bounded_linear) Zseq:
 110.190 -  assumes X: "Zseq X"
 110.191 -  shows "Zseq (\<lambda>n. f (X n))"
 110.192 -proof -
 110.193 -  obtain K where "\<And>x. norm (f x) \<le> norm x * K"
 110.194 -    using bounded by fast
 110.195 -  with X show ?thesis
 110.196 -    by (rule Zseq_imp_Zseq)
 110.197 -qed
 110.198 -
 110.199 -lemma (in bounded_bilinear) Zseq:
 110.200 -  assumes X: "Zseq X"
 110.201 -  assumes Y: "Zseq Y"
 110.202 -  shows "Zseq (\<lambda>n. X n ** Y n)"
 110.203 -proof (rule ZseqI)
 110.204 -  fix r::real assume r: "0 < r"
 110.205 -  obtain K where K: "0 < K"
 110.206 -    and norm_le: "\<And>x y. norm (x ** y) \<le> norm x * norm y * K"
 110.207 -    using pos_bounded by fast
 110.208 -  from K have K': "0 < inverse K"
 110.209 -    by (rule positive_imp_inverse_positive)
 110.210 -  obtain M where M: "\<forall>n\<ge>M. norm (X n) < r"
 110.211 -    using ZseqD [OF X r] by fast
 110.212 -  obtain N where N: "\<forall>n\<ge>N. norm (Y n) < inverse K"
 110.213 -    using ZseqD [OF Y K'] by fast
 110.214 -  show "\<exists>N. \<forall>n\<ge>N. norm (X n ** Y n) < r"
 110.215 -  proof (intro exI allI impI)
 110.216 -    fix n assume n: "max M N \<le> n"
 110.217 -    have "norm (X n ** Y n) \<le> norm (X n) * norm (Y n) * K"
 110.218 -      by (rule norm_le)
 110.219 -    also have "norm (X n) * norm (Y n) * K < r * inverse K * K"
 110.220 -    proof (intro mult_strict_right_mono mult_strict_mono' norm_ge_zero K)
 110.221 -      from M n show Xn: "norm (X n) < r" by simp
 110.222 -      from N n show Yn: "norm (Y n) < inverse K" by simp
 110.223 -    qed
 110.224 -    also from K have "r * inverse K * K = r" by simp
 110.225 -    finally show "norm (X n ** Y n) < r" .
 110.226 -  qed
 110.227 -qed
 110.228 -
 110.229 -lemma (in bounded_bilinear) Zseq_prod_Bseq:
 110.230 -  assumes X: "Zseq X"
 110.231 -  assumes Y: "Bseq Y"
 110.232 -  shows "Zseq (\<lambda>n. X n ** Y n)"
 110.233 -proof -
 110.234 -  obtain K where K: "0 \<le> K"
 110.235 -    and norm_le: "\<And>x y. norm (x ** y) \<le> norm x * norm y * K"
 110.236 -    using nonneg_bounded by fast
 110.237 -  obtain B where B: "0 < B"
 110.238 -    and norm_Y: "\<And>n. norm (Y n) \<le> B"
 110.239 -    using Y [unfolded Bseq_def] by fast
 110.240 -  from X show ?thesis
 110.241 -  proof (rule Zseq_imp_Zseq)
 110.242 -    fix n::nat
 110.243 -    have "norm (X n ** Y n) \<le> norm (X n) * norm (Y n) * K"
 110.244 -      by (rule norm_le)
 110.245 -    also have "\<dots> \<le> norm (X n) * B * K"
 110.246 -      by (intro mult_mono' order_refl norm_Y norm_ge_zero
 110.247 -                mult_nonneg_nonneg K)
 110.248 -    also have "\<dots> = norm (X n) * (B * K)"
 110.249 -      by (rule mult_assoc)
 110.250 -    finally show "norm (X n ** Y n) \<le> norm (X n) * (B * K)" .
 110.251 -  qed
 110.252 -qed
 110.253 -
 110.254 -lemma (in bounded_bilinear) Bseq_prod_Zseq:
 110.255 -  assumes X: "Bseq X"
 110.256 -  assumes Y: "Zseq Y"
 110.257 -  shows "Zseq (\<lambda>n. X n ** Y n)"
 110.258 -proof -
 110.259 -  obtain K where K: "0 \<le> K"
 110.260 -    and norm_le: "\<And>x y. norm (x ** y) \<le> norm x * norm y * K"
 110.261 -    using nonneg_bounded by fast
 110.262 -  obtain B where B: "0 < B"
 110.263 -    and norm_X: "\<And>n. norm (X n) \<le> B"
 110.264 -    using X [unfolded Bseq_def] by fast
 110.265 -  from Y show ?thesis
 110.266 -  proof (rule Zseq_imp_Zseq)
 110.267 -    fix n::nat
 110.268 -    have "norm (X n ** Y n) \<le> norm (X n) * norm (Y n) * K"
 110.269 -      by (rule norm_le)
 110.270 -    also have "\<dots> \<le> B * norm (Y n) * K"
 110.271 -      by (intro mult_mono' order_refl norm_X norm_ge_zero
 110.272 -                mult_nonneg_nonneg K)
 110.273 -    also have "\<dots> = norm (Y n) * (B * K)"
 110.274 -      by (simp only: mult_ac)
 110.275 -    finally show "norm (X n ** Y n) \<le> norm (Y n) * (B * K)" .
 110.276 -  qed
 110.277 -qed
 110.278 -
 110.279 -lemma (in bounded_bilinear) Zseq_left:
 110.280 -  "Zseq X \<Longrightarrow> Zseq (\<lambda>n. X n ** a)"
 110.281 -by (rule bounded_linear_left [THEN bounded_linear.Zseq])
 110.282 -
 110.283 -lemma (in bounded_bilinear) Zseq_right:
 110.284 -  "Zseq X \<Longrightarrow> Zseq (\<lambda>n. a ** X n)"
 110.285 -by (rule bounded_linear_right [THEN bounded_linear.Zseq])
 110.286 -
 110.287 -lemmas Zseq_mult = mult.Zseq
 110.288 -lemmas Zseq_mult_right = mult.Zseq_right
 110.289 -lemmas Zseq_mult_left = mult.Zseq_left
 110.290 -
 110.291 -
 110.292 -subsection {* Limits of Sequences *}
 110.293 -
 110.294 -lemma LIMSEQ_iff:
 110.295 -      "(X ----> L) = (\<forall>r>0. \<exists>no. \<forall>n \<ge> no. norm (X n - L) < r)"
 110.296 -by (rule LIMSEQ_def)
 110.297 -
 110.298 -lemma LIMSEQ_Zseq_iff: "((\<lambda>n. X n) ----> L) = Zseq (\<lambda>n. X n - L)"
 110.299 -by (simp only: LIMSEQ_def Zseq_def)
 110.300 -
 110.301 -lemma LIMSEQ_I:
 110.302 -  "(\<And>r. 0 < r \<Longrightarrow> \<exists>no. \<forall>n\<ge>no. norm (X n - L) < r) \<Longrightarrow> X ----> L"
 110.303 -by (simp add: LIMSEQ_def)
 110.304 -
 110.305 -lemma LIMSEQ_D:
 110.306 -  "\<lbrakk>X ----> L; 0 < r\<rbrakk> \<Longrightarrow> \<exists>no. \<forall>n\<ge>no. norm (X n - L) < r"
 110.307 -by (simp add: LIMSEQ_def)
 110.308 -
 110.309 -lemma LIMSEQ_const: "(\<lambda>n. k) ----> k"
 110.310 -by (simp add: LIMSEQ_def)
 110.311 -
 110.312 -lemma LIMSEQ_const_iff: "(\<lambda>n. k) ----> l = (k = l)"
 110.313 -by (simp add: LIMSEQ_Zseq_iff Zseq_const_iff)
 110.314 -
 110.315 -lemma LIMSEQ_norm: "X ----> a \<Longrightarrow> (\<lambda>n. norm (X n)) ----> norm a"
 110.316 -apply (simp add: LIMSEQ_def, safe)
 110.317 -apply (drule_tac x="r" in spec, safe)
 110.318 -apply (rule_tac x="no" in exI, safe)
 110.319 -apply (drule_tac x="n" in spec, safe)
 110.320 -apply (erule order_le_less_trans [OF norm_triangle_ineq3])
 110.321 -done
 110.322 -
 110.323 -lemma LIMSEQ_ignore_initial_segment:
 110.324 -  "f ----> a \<Longrightarrow> (\<lambda>n. f (n + k)) ----> a"
 110.325 -apply (rule LIMSEQ_I)
 110.326 -apply (drule (1) LIMSEQ_D)
 110.327 -apply (erule exE, rename_tac N)
 110.328 -apply (rule_tac x=N in exI)
 110.329 -apply simp
 110.330 -done
 110.331 -
 110.332 -lemma LIMSEQ_offset:
 110.333 -  "(\<lambda>n. f (n + k)) ----> a \<Longrightarrow> f ----> a"
 110.334 -apply (rule LIMSEQ_I)
 110.335 -apply (drule (1) LIMSEQ_D)
 110.336 -apply (erule exE, rename_tac N)
 110.337 -apply (rule_tac x="N + k" in exI)
 110.338 -apply clarify
 110.339 -apply (drule_tac x="n - k" in spec)
 110.340 -apply (simp add: le_diff_conv2)
 110.341 -done
 110.342 -
 110.343 -lemma LIMSEQ_Suc: "f ----> l \<Longrightarrow> (\<lambda>n. f (Suc n)) ----> l"
 110.344 -by (drule_tac k="1" in LIMSEQ_ignore_initial_segment, simp)
 110.345 -
 110.346 -lemma LIMSEQ_imp_Suc: "(\<lambda>n. f (Suc n)) ----> l \<Longrightarrow> f ----> l"
 110.347 -by (rule_tac k="1" in LIMSEQ_offset, simp)
 110.348 -
 110.349 -lemma LIMSEQ_Suc_iff: "(\<lambda>n. f (Suc n)) ----> l = f ----> l"
 110.350 -by (blast intro: LIMSEQ_imp_Suc LIMSEQ_Suc)
 110.351 -
 110.352 -lemma add_diff_add:
 110.353 -  fixes a b c d :: "'a::ab_group_add"
 110.354 -  shows "(a + c) - (b + d) = (a - b) + (c - d)"
 110.355 -by simp
 110.356 -
 110.357 -lemma minus_diff_minus:
 110.358 -  fixes a b :: "'a::ab_group_add"
 110.359 -  shows "(- a) - (- b) = - (a - b)"
 110.360 -by simp
 110.361 -
 110.362 -lemma LIMSEQ_add: "\<lbrakk>X ----> a; Y ----> b\<rbrakk> \<Longrightarrow> (\<lambda>n. X n + Y n) ----> a + b"
 110.363 -by (simp only: LIMSEQ_Zseq_iff add_diff_add Zseq_add)
 110.364 -
 110.365 -lemma LIMSEQ_minus: "X ----> a \<Longrightarrow> (\<lambda>n. - X n) ----> - a"
 110.366 -by (simp only: LIMSEQ_Zseq_iff minus_diff_minus Zseq_minus)
 110.367 -
 110.368 -lemma LIMSEQ_minus_cancel: "(\<lambda>n. - X n) ----> - a \<Longrightarrow> X ----> a"
 110.369 -by (drule LIMSEQ_minus, simp)
 110.370 -
 110.371 -lemma LIMSEQ_diff: "\<lbrakk>X ----> a; Y ----> b\<rbrakk> \<Longrightarrow> (\<lambda>n. X n - Y n) ----> a - b"
 110.372 -by (simp add: diff_minus LIMSEQ_add LIMSEQ_minus)
 110.373 -
 110.374 -lemma LIMSEQ_unique: "\<lbrakk>X ----> a; X ----> b\<rbrakk> \<Longrightarrow> a = b"
 110.375 -by (drule (1) LIMSEQ_diff, simp add: LIMSEQ_const_iff)
 110.376 -
 110.377 -lemma (in bounded_linear) LIMSEQ:
 110.378 -  "X ----> a \<Longrightarrow> (\<lambda>n. f (X n)) ----> f a"
 110.379 -by (simp only: LIMSEQ_Zseq_iff diff [symmetric] Zseq)
 110.380 -
 110.381 -lemma (in bounded_bilinear) LIMSEQ:
 110.382 -  "\<lbrakk>X ----> a; Y ----> b\<rbrakk> \<Longrightarrow> (\<lambda>n. X n ** Y n) ----> a ** b"
 110.383 -by (simp only: LIMSEQ_Zseq_iff prod_diff_prod
 110.384 -               Zseq_add Zseq Zseq_left Zseq_right)
 110.385 -
 110.386 -lemma LIMSEQ_mult:
 110.387 -  fixes a b :: "'a::real_normed_algebra"
 110.388 -  shows "[| X ----> a; Y ----> b |] ==> (%n. X n * Y n) ----> a * b"
 110.389 -by (rule mult.LIMSEQ)
 110.390 -
 110.391 -lemma inverse_diff_inverse:
 110.392 -  "\<lbrakk>(a::'a::division_ring) \<noteq> 0; b \<noteq> 0\<rbrakk>
 110.393 -   \<Longrightarrow> inverse a - inverse b = - (inverse a * (a - b) * inverse b)"
 110.394 -by (simp add: ring_simps)
 110.395 -
 110.396 -lemma Bseq_inverse_lemma:
 110.397 -  fixes x :: "'a::real_normed_div_algebra"
 110.398 -  shows "\<lbrakk>r \<le> norm x; 0 < r\<rbrakk> \<Longrightarrow> norm (inverse x) \<le> inverse r"
 110.399 -apply (subst nonzero_norm_inverse, clarsimp)
 110.400 -apply (erule (1) le_imp_inverse_le)
 110.401 -done
 110.402 -
 110.403 -lemma Bseq_inverse:
 110.404 -  fixes a :: "'a::real_normed_div_algebra"
 110.405 -  assumes X: "X ----> a"
 110.406 -  assumes a: "a \<noteq> 0"
 110.407 -  shows "Bseq (\<lambda>n. inverse (X n))"
 110.408 -proof -
 110.409 -  from a have "0 < norm a" by simp
 110.410 -  hence "\<exists>r>0. r < norm a" by (rule dense)
 110.411 -  then obtain r where r1: "0 < r" and r2: "r < norm a" by fast
 110.412 -  obtain N where N: "\<And>n. N \<le> n \<Longrightarrow> norm (X n - a) < r"
 110.413 -    using LIMSEQ_D [OF X r1] by fast
 110.414 -  show ?thesis
 110.415 -  proof (rule BseqI2' [rule_format])
 110.416 -    fix n assume n: "N \<le> n"
 110.417 -    hence 1: "norm (X n - a) < r" by (rule N)
 110.418 -    hence 2: "X n \<noteq> 0" using r2 by auto
 110.419 -    hence "norm (inverse (X n)) = inverse (norm (X n))"
 110.420 -      by (rule nonzero_norm_inverse)
 110.421 -    also have "\<dots> \<le> inverse (norm a - r)"
 110.422 -    proof (rule le_imp_inverse_le)
 110.423 -      show "0 < norm a - r" using r2 by simp
 110.424 -    next
 110.425 -      have "norm a - norm (X n) \<le> norm (a - X n)"
 110.426 -        by (rule norm_triangle_ineq2)
 110.427 -      also have "\<dots> = norm (X n - a)"
 110.428 -        by (rule norm_minus_commute)
 110.429 -      also have "\<dots> < r" using 1 .
 110.430 -      finally show "norm a - r \<le> norm (X n)" by simp
 110.431 -    qed
 110.432 -    finally show "norm (inverse (X n)) \<le> inverse (norm a - r)" .
 110.433 -  qed
 110.434 -qed
 110.435 -
 110.436 -lemma LIMSEQ_inverse_lemma:
 110.437 -  fixes a :: "'a::real_normed_div_algebra"
 110.438 -  shows "\<lbrakk>X ----> a; a \<noteq> 0; \<forall>n. X n \<noteq> 0\<rbrakk>
 110.439 -         \<Longrightarrow> (\<lambda>n. inverse (X n)) ----> inverse a"
 110.440 -apply (subst LIMSEQ_Zseq_iff)
 110.441 -apply (simp add: inverse_diff_inverse nonzero_imp_inverse_nonzero)
 110.442 -apply (rule Zseq_minus)
 110.443 -apply (rule Zseq_mult_left)
 110.444 -apply (rule mult.Bseq_prod_Zseq)
 110.445 -apply (erule (1) Bseq_inverse)
 110.446 -apply (simp add: LIMSEQ_Zseq_iff)
 110.447 -done
 110.448 -
 110.449 -lemma LIMSEQ_inverse:
 110.450 -  fixes a :: "'a::real_normed_div_algebra"
 110.451 -  assumes X: "X ----> a"
 110.452 -  assumes a: "a \<noteq> 0"
 110.453 -  shows "(\<lambda>n. inverse (X n)) ----> inverse a"
 110.454 -proof -
 110.455 -  from a have "0 < norm a" by simp
 110.456 -  then obtain k where "\<forall>n\<ge>k. norm (X n - a) < norm a"
 110.457 -    using LIMSEQ_D [OF X] by fast
 110.458 -  hence "\<forall>n\<ge>k. X n \<noteq> 0" by auto
 110.459 -  hence k: "\<forall>n. X (n + k) \<noteq> 0" by simp
 110.460 -
 110.461 -  from X have "(\<lambda>n. X (n + k)) ----> a"
 110.462 -    by (rule LIMSEQ_ignore_initial_segment)
 110.463 -  hence "(\<lambda>n. inverse (X (n + k))) ----> inverse a"
 110.464 -    using a k by (rule LIMSEQ_inverse_lemma)
 110.465 -  thus "(\<lambda>n. inverse (X n)) ----> inverse a"
 110.466 -    by (rule LIMSEQ_offset)
 110.467 -qed
 110.468 -
 110.469 -lemma LIMSEQ_divide:
 110.470 -  fixes a b :: "'a::real_normed_field"
 110.471 -  shows "\<lbrakk>X ----> a; Y ----> b; b \<noteq> 0\<rbrakk> \<Longrightarrow> (\<lambda>n. X n / Y n) ----> a / b"
 110.472 -by (simp add: LIMSEQ_mult LIMSEQ_inverse divide_inverse)
 110.473 -
 110.474 -lemma LIMSEQ_pow:
 110.475 -  fixes a :: "'a::{real_normed_algebra,recpower}"
 110.476 -  shows "X ----> a \<Longrightarrow> (\<lambda>n. (X n) ^ m) ----> a ^ m"
 110.477 -by (induct m) (simp_all add: power_Suc LIMSEQ_const LIMSEQ_mult)
 110.478 -
 110.479 -lemma LIMSEQ_setsum:
 110.480 -  assumes n: "\<And>n. n \<in> S \<Longrightarrow> X n ----> L n"
 110.481 -  shows "(\<lambda>m. \<Sum>n\<in>S. X n m) ----> (\<Sum>n\<in>S. L n)"
 110.482 -proof (cases "finite S")
 110.483 -  case True
 110.484 -  thus ?thesis using n
 110.485 -  proof (induct)
 110.486 -    case empty
 110.487 -    show ?case
 110.488 -      by (simp add: LIMSEQ_const)
 110.489 -  next
 110.490 -    case insert
 110.491 -    thus ?case
 110.492 -      by (simp add: LIMSEQ_add)
 110.493 -  qed
 110.494 -next
 110.495 -  case False
 110.496 -  thus ?thesis
 110.497 -    by (simp add: LIMSEQ_const)
 110.498 -qed
 110.499 -
 110.500 -lemma LIMSEQ_setprod:
 110.501 -  fixes L :: "'a \<Rightarrow> 'b::{real_normed_algebra,comm_ring_1}"
 110.502 -  assumes n: "\<And>n. n \<in> S \<Longrightarrow> X n ----> L n"
 110.503 -  shows "(\<lambda>m. \<Prod>n\<in>S. X n m) ----> (\<Prod>n\<in>S. L n)"
 110.504 -proof (cases "finite S")
 110.505 -  case True
 110.506 -  thus ?thesis using n
 110.507 -  proof (induct)
 110.508 -    case empty
 110.509 -    show ?case
 110.510 -      by (simp add: LIMSEQ_const)
 110.511 -  next
 110.512 -    case insert
 110.513 -    thus ?case
 110.514 -      by (simp add: LIMSEQ_mult)
 110.515 -  qed
 110.516 -next
 110.517 -  case False
 110.518 -  thus ?thesis
 110.519 -    by (simp add: setprod_def LIMSEQ_const)
 110.520 -qed
 110.521 -
 110.522 -lemma LIMSEQ_add_const: "f ----> a ==> (%n.(f n + b)) ----> a + b"
 110.523 -by (simp add: LIMSEQ_add LIMSEQ_const)
 110.524 -
 110.525 -(* FIXME: delete *)
 110.526 -lemma LIMSEQ_add_minus:
 110.527 -     "[| X ----> a; Y ----> b |] ==> (%n. X n + -Y n) ----> a + -b"
 110.528 -by (simp only: LIMSEQ_add LIMSEQ_minus)
 110.529 -
 110.530 -lemma LIMSEQ_diff_const: "f ----> a ==> (%n.(f n  - b)) ----> a - b"
 110.531 -by (simp add: LIMSEQ_diff LIMSEQ_const)
 110.532 -
 110.533 -lemma LIMSEQ_diff_approach_zero: 
 110.534 -  "g ----> L ==> (%x. f x - g x) ----> 0  ==>
 110.535 -     f ----> L"
 110.536 -  apply (drule LIMSEQ_add)
 110.537 -  apply assumption
 110.538 -  apply simp
 110.539 -done
 110.540 -
 110.541 -lemma LIMSEQ_diff_approach_zero2: 
 110.542 -  "f ----> L ==> (%x. f x - g x) ----> 0  ==>
 110.543 -     g ----> L";
 110.544 -  apply (drule LIMSEQ_diff)
 110.545 -  apply assumption
 110.546 -  apply simp
 110.547 -done
 110.548 -
 110.549 -text{*A sequence tends to zero iff its abs does*}
 110.550 -lemma LIMSEQ_norm_zero: "((\<lambda>n. norm (X n)) ----> 0) = (X ----> 0)"
 110.551 -by (simp add: LIMSEQ_def)
 110.552 -
 110.553 -lemma LIMSEQ_rabs_zero: "((%n. \<bar>f n\<bar>) ----> 0) = (f ----> (0::real))"
 110.554 -by (simp add: LIMSEQ_def)
 110.555 -
 110.556 -lemma LIMSEQ_imp_rabs: "f ----> (l::real) ==> (%n. \<bar>f n\<bar>) ----> \<bar>l\<bar>"
 110.557 -by (drule LIMSEQ_norm, simp)
 110.558 -
 110.559 -text{*An unbounded sequence's inverse tends to 0*}
 110.560 -
 110.561 -lemma LIMSEQ_inverse_zero:
 110.562 -  "\<forall>r::real. \<exists>N. \<forall>n\<ge>N. r < X n \<Longrightarrow> (\<lambda>n. inverse (X n)) ----> 0"
 110.563 -apply (rule LIMSEQ_I)
 110.564 -apply (drule_tac x="inverse r" in spec, safe)
 110.565 -apply (rule_tac x="N" in exI, safe)
 110.566 -apply (drule_tac x="n" in spec, safe)
 110.567 -apply (frule positive_imp_inverse_positive)
 110.568 -apply (frule (1) less_imp_inverse_less)
 110.569 -apply (subgoal_tac "0 < X n", simp)
 110.570 -apply (erule (1) order_less_trans)
 110.571 -done
 110.572 -
 110.573 -text{*The sequence @{term "1/n"} tends to 0 as @{term n} tends to infinity*}
 110.574 -
 110.575 -lemma LIMSEQ_inverse_real_of_nat: "(%n. inverse(real(Suc n))) ----> 0"
 110.576 -apply (rule LIMSEQ_inverse_zero, safe)
 110.577 -apply (cut_tac x = r in reals_Archimedean2)
 110.578 -apply (safe, rule_tac x = n in exI)
 110.579 -apply (auto simp add: real_of_nat_Suc)
 110.580 -done
 110.581 -
 110.582 -text{*The sequence @{term "r + 1/n"} tends to @{term r} as @{term n} tends to
 110.583 -infinity is now easily proved*}
 110.584 -
 110.585 -lemma LIMSEQ_inverse_real_of_nat_add:
 110.586 -     "(%n. r + inverse(real(Suc n))) ----> r"
 110.587 -by (cut_tac LIMSEQ_add [OF LIMSEQ_const LIMSEQ_inverse_real_of_nat], auto)
 110.588 -
 110.589 -lemma LIMSEQ_inverse_real_of_nat_add_minus:
 110.590 -     "(%n. r + -inverse(real(Suc n))) ----> r"
 110.591 -by (cut_tac LIMSEQ_add_minus [OF LIMSEQ_const LIMSEQ_inverse_real_of_nat], auto)
 110.592 -
 110.593 -lemma LIMSEQ_inverse_real_of_nat_add_minus_mult:
 110.594 -     "(%n. r*( 1 + -inverse(real(Suc n)))) ----> r"
 110.595 -by (cut_tac b=1 in
 110.596 -        LIMSEQ_mult [OF LIMSEQ_const LIMSEQ_inverse_real_of_nat_add_minus], auto)
 110.597 -
 110.598 -lemma LIMSEQ_le_const:
 110.599 -  "\<lbrakk>X ----> (x::real); \<exists>N. \<forall>n\<ge>N. a \<le> X n\<rbrakk> \<Longrightarrow> a \<le> x"
 110.600 -apply (rule ccontr, simp only: linorder_not_le)
 110.601 -apply (drule_tac r="a - x" in LIMSEQ_D, simp)
 110.602 -apply clarsimp
 110.603 -apply (drule_tac x="max N no" in spec, drule mp, rule le_maxI1)
 110.604 -apply (drule_tac x="max N no" in spec, drule mp, rule le_maxI2)
 110.605 -apply simp
 110.606 -done
 110.607 -
 110.608 -lemma LIMSEQ_le_const2:
 110.609 -  "\<lbrakk>X ----> (x::real); \<exists>N. \<forall>n\<ge>N. X n \<le> a\<rbrakk> \<Longrightarrow> x \<le> a"
 110.610 -apply (subgoal_tac "- a \<le> - x", simp)
 110.611 -apply (rule LIMSEQ_le_const)
 110.612 -apply (erule LIMSEQ_minus)
 110.613 -apply simp
 110.614 -done
 110.615 -
 110.616 -lemma LIMSEQ_le:
 110.617 -  "\<lbrakk>X ----> x; Y ----> y; \<exists>N. \<forall>n\<ge>N. X n \<le> Y n\<rbrakk> \<Longrightarrow> x \<le> (y::real)"
 110.618 -apply (subgoal_tac "0 \<le> y - x", simp)
 110.619 -apply (rule LIMSEQ_le_const)
 110.620 -apply (erule (1) LIMSEQ_diff)
 110.621 -apply (simp add: le_diff_eq)
 110.622 -done
 110.623 -
 110.624 -
 110.625 -subsection {* Convergence *}
 110.626 -
 110.627 -lemma limI: "X ----> L ==> lim X = L"
 110.628 -apply (simp add: lim_def)
 110.629 -apply (blast intro: LIMSEQ_unique)
 110.630 -done
 110.631 -
 110.632 -lemma convergentD: "convergent X ==> \<exists>L. (X ----> L)"
 110.633 -by (simp add: convergent_def)
 110.634 -
 110.635 -lemma convergentI: "(X ----> L) ==> convergent X"
 110.636 -by (auto simp add: convergent_def)
 110.637 -
 110.638 -lemma convergent_LIMSEQ_iff: "convergent X = (X ----> lim X)"
 110.639 -by (auto intro: theI LIMSEQ_unique simp add: convergent_def lim_def)
 110.640 -
 110.641 -lemma convergent_minus_iff: "(convergent X) = (convergent (%n. -(X n)))"
 110.642 -apply (simp add: convergent_def)
 110.643 -apply (auto dest: LIMSEQ_minus)
 110.644 -apply (drule LIMSEQ_minus, auto)
 110.645 -done
 110.646 -
 110.647 -
 110.648 -subsection {* Bounded Monotonic Sequences *}
 110.649 -
 110.650 -text{*Subsequence (alternative definition, (e.g. Hoskins)*}
 110.651 -
 110.652 -lemma subseq_Suc_iff: "subseq f = (\<forall>n. (f n) < (f (Suc n)))"
 110.653 -apply (simp add: subseq_def)
 110.654 -apply (auto dest!: less_imp_Suc_add)
 110.655 -apply (induct_tac k)
 110.656 -apply (auto intro: less_trans)
 110.657 -done
 110.658 -
 110.659 -lemma monoseq_Suc:
 110.660 -   "monoseq X = ((\<forall>n. X n \<le> X (Suc n))
 110.661 -                 | (\<forall>n. X (Suc n) \<le> X n))"
 110.662 -apply (simp add: monoseq_def)
 110.663 -apply (auto dest!: le_imp_less_or_eq)
 110.664 -apply (auto intro!: lessI [THEN less_imp_le] dest!: less_imp_Suc_add)
 110.665 -apply (induct_tac "ka")
 110.666 -apply (auto intro: order_trans)
 110.667 -apply (erule contrapos_np)
 110.668 -apply (induct_tac "k")
 110.669 -apply (auto intro: order_trans)
 110.670 -done
 110.671 -
 110.672 -lemma monoI1: "\<forall>m. \<forall> n \<ge> m. X m \<le> X n ==> monoseq X"
 110.673 -by (simp add: monoseq_def)
 110.674 -
 110.675 -lemma monoI2: "\<forall>m. \<forall> n \<ge> m. X n \<le> X m ==> monoseq X"
 110.676 -by (simp add: monoseq_def)
 110.677 -
 110.678 -lemma mono_SucI1: "\<forall>n. X n \<le> X (Suc n) ==> monoseq X"
 110.679 -by (simp add: monoseq_Suc)
 110.680 -
 110.681 -lemma mono_SucI2: "\<forall>n. X (Suc n) \<le> X n ==> monoseq X"
 110.682 -by (simp add: monoseq_Suc)
 110.683 -
 110.684 -text{*Bounded Sequence*}
 110.685 -
 110.686 -lemma BseqD: "Bseq X ==> \<exists>K. 0 < K & (\<forall>n. norm (X n) \<le> K)"
 110.687 -by (simp add: Bseq_def)
 110.688 -
 110.689 -lemma BseqI: "[| 0 < K; \<forall>n. norm (X n) \<le> K |] ==> Bseq X"
 110.690 -by (auto simp add: Bseq_def)
 110.691 -
 110.692 -lemma lemma_NBseq_def:
 110.693 -     "(\<exists>K > 0. \<forall>n. norm (X n) \<le> K) =
 110.694 -      (\<exists>N. \<forall>n. norm (X n) \<le> real(Suc N))"
 110.695 -apply auto
 110.696 - prefer 2 apply force
 110.697 -apply (cut_tac x = K in reals_Archimedean2, clarify)
 110.698 -apply (rule_tac x = n in exI, clarify)
 110.699 -apply (drule_tac x = na in spec)
 110.700 -apply (auto simp add: real_of_nat_Suc)
 110.701 -done
 110.702 -
 110.703 -text{* alternative definition for Bseq *}
 110.704 -lemma Bseq_iff: "Bseq X = (\<exists>N. \<forall>n. norm (X n) \<le> real(Suc N))"
 110.705 -apply (simp add: Bseq_def)
 110.706 -apply (simp (no_asm) add: lemma_NBseq_def)
 110.707 -done
 110.708 -
 110.709 -lemma lemma_NBseq_def2:
 110.710 -     "(\<exists>K > 0. \<forall>n. norm (X n) \<le> K) = (\<exists>N. \<forall>n. norm (X n) < real(Suc N))"
 110.711 -apply (subst lemma_NBseq_def, auto)
 110.712 -apply (rule_tac x = "Suc N" in exI)
 110.713 -apply (rule_tac [2] x = N in exI)
 110.714 -apply (auto simp add: real_of_nat_Suc)
 110.715 - prefer 2 apply (blast intro: order_less_imp_le)
 110.716 -apply (drule_tac x = n in spec, simp)
 110.717 -done
 110.718 -
 110.719 -(* yet another definition for Bseq *)
 110.720 -lemma Bseq_iff1a: "Bseq X = (\<exists>N. \<forall>n. norm (X n) < real(Suc N))"
 110.721 -by (simp add: Bseq_def lemma_NBseq_def2)
 110.722 -
 110.723 -subsubsection{*Upper Bounds and Lubs of Bounded Sequences*}
 110.724 -
 110.725 -lemma Bseq_isUb:
 110.726 -  "!!(X::nat=>real). Bseq X ==> \<exists>U. isUb (UNIV::real set) {x. \<exists>n. X n = x} U"
 110.727 -by (auto intro: isUbI setleI simp add: Bseq_def abs_le_iff)
 110.728 -
 110.729 -
 110.730 -text{* Use completeness of reals (supremum property)
 110.731 -   to show that any bounded sequence has a least upper bound*}
 110.732 -
 110.733 -lemma Bseq_isLub:
 110.734 -  "!!(X::nat=>real). Bseq X ==>
 110.735 -   \<exists>U. isLub (UNIV::real set) {x. \<exists>n. X n = x} U"
 110.736 -by (blast intro: reals_complete Bseq_isUb)
 110.737 -
 110.738 -subsubsection{*A Bounded and Monotonic Sequence Converges*}
 110.739 -
 110.740 -lemma lemma_converg1:
 110.741 -     "!!(X::nat=>real). [| \<forall>m. \<forall> n \<ge> m. X m \<le> X n;
 110.742 -                  isLub (UNIV::real set) {x. \<exists>n. X n = x} (X ma)
 110.743 -               |] ==> \<forall>n \<ge> ma. X n = X ma"
 110.744 -apply safe
 110.745 -apply (drule_tac y = "X n" in isLubD2)
 110.746 -apply (blast dest: order_antisym)+
 110.747 -done
 110.748 -
 110.749 -text{* The best of both worlds: Easier to prove this result as a standard
 110.750 -   theorem and then use equivalence to "transfer" it into the
 110.751 -   equivalent nonstandard form if needed!*}
 110.752 -
 110.753 -lemma Bmonoseq_LIMSEQ: "\<forall>n. m \<le> n --> X n = X m ==> \<exists>L. (X ----> L)"
 110.754 -apply (simp add: LIMSEQ_def)
 110.755 -apply (rule_tac x = "X m" in exI, safe)
 110.756 -apply (rule_tac x = m in exI, safe)
 110.757 -apply (drule spec, erule impE, auto)
 110.758 -done
 110.759 -
 110.760 -lemma lemma_converg2:
 110.761 -   "!!(X::nat=>real).
 110.762 -    [| \<forall>m. X m ~= U;  isLub UNIV {x. \<exists>n. X n = x} U |] ==> \<forall>m. X m < U"
 110.763 -apply safe
 110.764 -apply (drule_tac y = "X m" in isLubD2)
 110.765 -apply (auto dest!: order_le_imp_less_or_eq)
 110.766 -done
 110.767 -
 110.768 -lemma lemma_converg3: "!!(X ::nat=>real). \<forall>m. X m \<le> U ==> isUb UNIV {x. \<exists>n. X n = x} U"
 110.769 -by (rule setleI [THEN isUbI], auto)
 110.770 -
 110.771 -text{* FIXME: @{term "U - T < U"} is redundant *}
 110.772 -lemma lemma_converg4: "!!(X::nat=> real).
 110.773 -               [| \<forall>m. X m ~= U;
 110.774 -                  isLub UNIV {x. \<exists>n. X n = x} U;
 110.775 -                  0 < T;
 110.776 -                  U + - T < U
 110.777 -               |] ==> \<exists>m. U + -T < X m & X m < U"
 110.778 -apply (drule lemma_converg2, assumption)
 110.779 -apply (rule ccontr, simp)
 110.780 -apply (simp add: linorder_not_less)
 110.781 -apply (drule lemma_converg3)
 110.782 -apply (drule isLub_le_isUb, assumption)
 110.783 -apply (auto dest: order_less_le_trans)
 110.784 -done
 110.785 -
 110.786 -text{*A standard proof of the theorem for monotone increasing sequence*}
 110.787 -
 110.788 -lemma Bseq_mono_convergent:
 110.789 -     "[| Bseq X; \<forall>m. \<forall>n \<ge> m. X m \<le> X n |] ==> convergent (X::nat=>real)"
 110.790 -apply (simp add: convergent_def)
 110.791 -apply (frule Bseq_isLub, safe)
 110.792 -apply (case_tac "\<exists>m. X m = U", auto)
 110.793 -apply (blast dest: lemma_converg1 Bmonoseq_LIMSEQ)
 110.794 -(* second case *)
 110.795 -apply (rule_tac x = U in exI)
 110.796 -apply (subst LIMSEQ_iff, safe)
 110.797 -apply (frule lemma_converg2, assumption)
 110.798 -apply (drule lemma_converg4, auto)
 110.799 -apply (rule_tac x = m in exI, safe)
 110.800 -apply (subgoal_tac "X m \<le> X n")
 110.801 - prefer 2 apply blast
 110.802 -apply (drule_tac x=n and P="%m. X m < U" in spec, arith)
 110.803 -done
 110.804 -
 110.805 -lemma Bseq_minus_iff: "Bseq (%n. -(X n)) = Bseq X"
 110.806 -by (simp add: Bseq_def)
 110.807 -
 110.808 -text{*Main monotonicity theorem*}
 110.809 -lemma Bseq_monoseq_convergent: "[| Bseq X; monoseq X |] ==> convergent X"
 110.810 -apply (simp add: monoseq_def, safe)
 110.811 -apply (rule_tac [2] convergent_minus_iff [THEN ssubst])
 110.812 -apply (drule_tac [2] Bseq_minus_iff [THEN ssubst])
 110.813 -apply (auto intro!: Bseq_mono_convergent)
 110.814 -done
 110.815 -
 110.816 -subsubsection{*A Few More Equivalence Theorems for Boundedness*}
 110.817 -
 110.818 -text{*alternative formulation for boundedness*}
 110.819 -lemma Bseq_iff2: "Bseq X = (\<exists>k > 0. \<exists>x. \<forall>n. norm (X(n) + -x) \<le> k)"
 110.820 -apply (unfold Bseq_def, safe)
 110.821 -apply (rule_tac [2] x = "k + norm x" in exI)
 110.822 -apply (rule_tac x = K in exI, simp)
 110.823 -apply (rule exI [where x = 0], auto)
 110.824 -apply (erule order_less_le_trans, simp)
 110.825 -apply (drule_tac x=n in spec, fold diff_def)
 110.826 -apply (drule order_trans [OF norm_triangle_ineq2])
 110.827 -apply simp
 110.828 -done
 110.829 -
 110.830 -text{*alternative formulation for boundedness*}
 110.831 -lemma Bseq_iff3: "Bseq X = (\<exists>k > 0. \<exists>N. \<forall>n. norm(X(n) + -X(N)) \<le> k)"
 110.832 -apply safe
 110.833 -apply (simp add: Bseq_def, safe)
 110.834 -apply (rule_tac x = "K + norm (X N)" in exI)
 110.835 -apply auto
 110.836 -apply (erule order_less_le_trans, simp)
 110.837 -apply (rule_tac x = N in exI, safe)
 110.838 -apply (drule_tac x = n in spec)
 110.839 -apply (rule order_trans [OF norm_triangle_ineq], simp)
 110.840 -apply (auto simp add: Bseq_iff2)
 110.841 -done
 110.842 -
 110.843 -lemma BseqI2: "(\<forall>n. k \<le> f n & f n \<le> (K::real)) ==> Bseq f"
 110.844 -apply (simp add: Bseq_def)
 110.845 -apply (rule_tac x = " (\<bar>k\<bar> + \<bar>K\<bar>) + 1" in exI, auto)
 110.846 -apply (drule_tac x = n in spec, arith)
 110.847 -done
 110.848 -
 110.849 -
 110.850 -subsection {* Cauchy Sequences *}
 110.851 -
 110.852 -lemma CauchyI:
 110.853 -  "(\<And>e. 0 < e \<Longrightarrow> \<exists>M. \<forall>m\<ge>M. \<forall>n\<ge>M. norm (X m - X n) < e) \<Longrightarrow> Cauchy X"
 110.854 -by (simp add: Cauchy_def)
 110.855 -
 110.856 -lemma CauchyD:
 110.857 -  "\<lbrakk>Cauchy X; 0 < e\<rbrakk> \<Longrightarrow> \<exists>M. \<forall>m\<ge>M. \<forall>n\<ge>M. norm (X m - X n) < e"
 110.858 -by (simp add: Cauchy_def)
 110.859 -
 110.860 -subsubsection {* Cauchy Sequences are Bounded *}
 110.861 -
 110.862 -text{*A Cauchy sequence is bounded -- this is the standard
 110.863 -  proof mechanization rather than the nonstandard proof*}
 110.864 -
 110.865 -lemma lemmaCauchy: "\<forall>n \<ge> M. norm (X M - X n) < (1::real)
 110.866 -          ==>  \<forall>n \<ge> M. norm (X n :: 'a::real_normed_vector) < 1 + norm (X M)"
 110.867 -apply (clarify, drule spec, drule (1) mp)
 110.868 -apply (simp only: norm_minus_commute)
 110.869 -apply (drule order_le_less_trans [OF norm_triangle_ineq2])
 110.870 -apply simp
 110.871 -done
 110.872 -
 110.873 -lemma Cauchy_Bseq: "Cauchy X ==> Bseq X"
 110.874 -apply (simp add: Cauchy_def)
 110.875 -apply (drule spec, drule mp, rule zero_less_one, safe)
 110.876 -apply (drule_tac x="M" in spec, simp)
 110.877 -apply (drule lemmaCauchy)
 110.878 -apply (rule_tac k="M" in Bseq_offset)
 110.879 -apply (simp add: Bseq_def)
 110.880 -apply (rule_tac x="1 + norm (X M)" in exI)
 110.881 -apply (rule conjI, rule order_less_le_trans [OF zero_less_one], simp)
 110.882 -apply (simp add: order_less_imp_le)
 110.883 -done
 110.884 -
 110.885 -subsubsection {* Cauchy Sequences are Convergent *}
 110.886 -
 110.887 -axclass banach \<subseteq> real_normed_vector
 110.888 -  Cauchy_convergent: "Cauchy X \<Longrightarrow> convergent X"
 110.889 -
 110.890 -theorem LIMSEQ_imp_Cauchy:
 110.891 -  assumes X: "X ----> a" shows "Cauchy X"
 110.892 -proof (rule CauchyI)
 110.893 -  fix e::real assume "0 < e"
 110.894 -  hence "0 < e/2" by simp
 110.895 -  with X have "\<exists>N. \<forall>n\<ge>N. norm (X n - a) < e/2" by (rule LIMSEQ_D)
 110.896 -  then obtain N where N: "\<forall>n\<ge>N. norm (X n - a) < e/2" ..
 110.897 -  show "\<exists>N. \<forall>m\<ge>N. \<forall>n\<ge>N. norm (X m - X n) < e"
 110.898 -  proof (intro exI allI impI)
 110.899 -    fix m assume "N \<le> m"
 110.900 -    hence m: "norm (X m - a) < e/2" using N by fast
 110.901 -    fix n assume "N \<le> n"
 110.902 -    hence n: "norm (X n - a) < e/2" using N by fast
 110.903 -    have "norm (X m - X n) = norm ((X m - a) - (X n - a))" by simp
 110.904 -    also have "\<dots> \<le> norm (X m - a) + norm (X n - a)"
 110.905 -      by (rule norm_triangle_ineq4)
 110.906 -    also from m n have "\<dots> < e" by(simp add:field_simps)
 110.907 -    finally show "norm (X m - X n) < e" .
 110.908 -  qed
 110.909 -qed
 110.910 -
 110.911 -lemma convergent_Cauchy: "convergent X \<Longrightarrow> Cauchy X"
 110.912 -unfolding convergent_def
 110.913 -by (erule exE, erule LIMSEQ_imp_Cauchy)
 110.914 -
 110.915 -text {*
 110.916 -Proof that Cauchy sequences converge based on the one from
 110.917 -http://pirate.shu.edu/~wachsmut/ira/numseq/proofs/cauconv.html
 110.918 -*}
 110.919 -
 110.920 -text {*
 110.921 -  If sequence @{term "X"} is Cauchy, then its limit is the lub of
 110.922 -  @{term "{r::real. \<exists>N. \<forall>n\<ge>N. r < X n}"}
 110.923 -*}
 110.924 -
 110.925 -lemma isUb_UNIV_I: "(\<And>y. y \<in> S \<Longrightarrow> y \<le> u) \<Longrightarrow> isUb UNIV S u"
 110.926 -by (simp add: isUbI setleI)
 110.927 -
 110.928 -lemma real_abs_diff_less_iff:
 110.929 -  "(\<bar>x - a\<bar> < (r::real)) = (a - r < x \<and> x < a + r)"
 110.930 -by auto
 110.931 -
 110.932 -locale real_Cauchy =
 110.933 -  fixes X :: "nat \<Rightarrow> real"
 110.934 -  assumes X: "Cauchy X"
 110.935 -  fixes S :: "real set"
 110.936 -  defines S_def: "S \<equiv> {x::real. \<exists>N. \<forall>n\<ge>N. x < X n}"
 110.937 -
 110.938 -lemma real_CauchyI:
 110.939 -  assumes "Cauchy X"
 110.940 -  shows "real_Cauchy X"
 110.941 -  proof qed (fact assms)
 110.942 -
 110.943 -lemma (in real_Cauchy) mem_S: "\<forall>n\<ge>N. x < X n \<Longrightarrow> x \<in> S"
 110.944 -by (unfold S_def, auto)
 110.945 -
 110.946 -lemma (in real_Cauchy) bound_isUb:
 110.947 -  assumes N: "\<forall>n\<ge>N. X n < x"
 110.948 -  shows "isUb UNIV S x"
 110.949 -proof (rule isUb_UNIV_I)
 110.950 -  fix y::real assume "y \<in> S"
 110.951 -  hence "\<exists>M. \<forall>n\<ge>M. y < X n"
 110.952 -    by (simp add: S_def)
 110.953 -  then obtain M where "\<forall>n\<ge>M. y < X n" ..
 110.954 -  hence "y < X (max M N)" by simp
 110.955 -  also have "\<dots> < x" using N by simp
 110.956 -  finally show "y \<le> x"
 110.957 -    by (rule order_less_imp_le)
 110.958 -qed
 110.959 -
 110.960 -lemma (in real_Cauchy) isLub_ex: "\<exists>u. isLub UNIV S u"
 110.961 -proof (rule reals_complete)
 110.962 -  obtain N where "\<forall>m\<ge>N. \<forall>n\<ge>N. norm (X m - X n) < 1"
 110.963 -    using CauchyD [OF X zero_less_one] by fast
 110.964 -  hence N: "\<forall>n\<ge>N. norm (X n - X N) < 1" by simp
 110.965 -  show "\<exists>x. x \<in> S"
 110.966 -  proof
 110.967 -    from N have "\<forall>n\<ge>N. X N - 1 < X n"
 110.968 -      by (simp add: real_abs_diff_less_iff)
 110.969 -    thus "X N - 1 \<in> S" by (rule mem_S)
 110.970 -  qed
 110.971 -  show "\<exists>u. isUb UNIV S u"
 110.972 -  proof
 110.973 -    from N have "\<forall>n\<ge>N. X n < X N + 1"
 110.974 -      by (simp add: real_abs_diff_less_iff)
 110.975 -    thus "isUb UNIV S (X N + 1)"
 110.976 -      by (rule bound_isUb)
 110.977 -  qed
 110.978 -qed
 110.979 -
 110.980 -lemma (in real_Cauchy) isLub_imp_LIMSEQ:
 110.981 -  assumes x: "isLub UNIV S x"
 110.982 -  shows "X ----> x"
 110.983 -proof (rule LIMSEQ_I)
 110.984 -  fix r::real assume "0 < r"
 110.985 -  hence r: "0 < r/2" by simp
 110.986 -  obtain N where "\<forall>n\<ge>N. \<forall>m\<ge>N. norm (X n - X m) < r/2"
 110.987 -    using CauchyD [OF X r] by fast
 110.988 -  hence "\<forall>n\<ge>N. norm (X n - X N) < r/2" by simp
 110.989 -  hence N: "\<forall>n\<ge>N. X N - r/2 < X n \<and> X n < X N + r/2"
 110.990 -    by (simp only: real_norm_def real_abs_diff_less_iff)
 110.991 -
 110.992 -  from N have "\<forall>n\<ge>N. X N - r/2 < X n" by fast
 110.993 -  hence "X N - r/2 \<in> S" by (rule mem_S)
 110.994 -  hence 1: "X N - r/2 \<le> x" using x isLub_isUb isUbD by fast
 110.995 -
 110.996 -  from N have "\<forall>n\<ge>N. X n < X N + r/2" by fast
 110.997 -  hence "isUb UNIV S (X N + r/2)" by (rule bound_isUb)
 110.998 -  hence 2: "x \<le> X N + r/2" using x isLub_le_isUb by fast
 110.999 -
110.1000 -  show "\<exists>N. \<forall>n\<ge>N. norm (X n - x) < r"
110.1001 -  proof (intro exI allI impI)
110.1002 -    fix n assume n: "N \<le> n"
110.1003 -    from N n have "X n < X N + r/2" and "X N - r/2 < X n" by simp+
110.1004 -    thus "norm (X n - x) < r" using 1 2
110.1005 -      by (simp add: real_abs_diff_less_iff)
110.1006 -  qed
110.1007 -qed
110.1008 -
110.1009 -lemma (in real_Cauchy) LIMSEQ_ex: "\<exists>x. X ----> x"
110.1010 -proof -
110.1011 -  obtain x where "isLub UNIV S x"
110.1012 -    using isLub_ex by fast
110.1013 -  hence "X ----> x"
110.1014 -    by (rule isLub_imp_LIMSEQ)
110.1015 -  thus ?thesis ..
110.1016 -qed
110.1017 -
110.1018 -lemma real_Cauchy_convergent:
110.1019 -  fixes X :: "nat \<Rightarrow> real"
110.1020 -  shows "Cauchy X \<Longrightarrow> convergent X"
110.1021 -unfolding convergent_def
110.1022 -by (rule real_Cauchy.LIMSEQ_ex)
110.1023 - (rule real_CauchyI)
110.1024 -
110.1025 -instance real :: banach
110.1026 -by intro_classes (rule real_Cauchy_convergent)
110.1027 -
110.1028 -lemma Cauchy_convergent_iff:
110.1029 -  fixes X :: "nat \<Rightarrow> 'a::banach"
110.1030 -  shows "Cauchy X = convergent X"
110.1031 -by (fast intro: Cauchy_convergent convergent_Cauchy)
110.1032 -
110.1033 -
110.1034 -subsection {* Power Sequences *}
110.1035 -
110.1036 -text{*The sequence @{term "x^n"} tends to 0 if @{term "0\<le>x"} and @{term
110.1037 -"x<1"}.  Proof will use (NS) Cauchy equivalence for convergence and
110.1038 -  also fact that bounded and monotonic sequence converges.*}
110.1039 -
110.1040 -lemma Bseq_realpow: "[| 0 \<le> (x::real); x \<le> 1 |] ==> Bseq (%n. x ^ n)"
110.1041 -apply (simp add: Bseq_def)
110.1042 -apply (rule_tac x = 1 in exI)
110.1043 -apply (simp add: power_abs)
110.1044 -apply (auto dest: power_mono)
110.1045 -done
110.1046 -
110.1047 -lemma monoseq_realpow: "[| 0 \<le> x; x \<le> 1 |] ==> monoseq (%n. x ^ n)"
110.1048 -apply (clarify intro!: mono_SucI2)
110.1049 -apply (cut_tac n = n and N = "Suc n" and a = x in power_decreasing, auto)
110.1050 -done
110.1051 -
110.1052 -lemma convergent_realpow:
110.1053 -  "[| 0 \<le> (x::real); x \<le> 1 |] ==> convergent (%n. x ^ n)"
110.1054 -by (blast intro!: Bseq_monoseq_convergent Bseq_realpow monoseq_realpow)
110.1055 -
110.1056 -lemma LIMSEQ_inverse_realpow_zero_lemma:
110.1057 -  fixes x :: real
110.1058 -  assumes x: "0 \<le> x"
110.1059 -  shows "real n * x + 1 \<le> (x + 1) ^ n"
110.1060 -apply (induct n)
110.1061 -apply simp
110.1062 -apply simp
110.1063 -apply (rule order_trans)
110.1064 -prefer 2
110.1065 -apply (erule mult_left_mono)
110.1066 -apply (rule add_increasing [OF x], simp)
110.1067 -apply (simp add: real_of_nat_Suc)
110.1068 -apply (simp add: ring_distribs)
110.1069 -apply (simp add: mult_nonneg_nonneg x)
110.1070 -done
110.1071 -
110.1072 -lemma LIMSEQ_inverse_realpow_zero:
110.1073 -  "1 < (x::real) \<Longrightarrow> (\<lambda>n. inverse (x ^ n)) ----> 0"
110.1074 -proof (rule LIMSEQ_inverse_zero [rule_format])
110.1075 -  fix y :: real
110.1076 -  assume x: "1 < x"
110.1077 -  hence "0 < x - 1" by simp
110.1078 -  hence "\<forall>y. \<exists>N::nat. y < real N * (x - 1)"
110.1079 -    by (rule reals_Archimedean3)
110.1080 -  hence "\<exists>N::nat. y < real N * (x - 1)" ..
110.1081 -  then obtain N::nat where "y < real N * (x - 1)" ..
110.1082 -  also have "\<dots> \<le> real N * (x - 1) + 1" by simp
110.1083 -  also have "\<dots> \<le> (x - 1 + 1) ^ N"
110.1084 -    by (rule LIMSEQ_inverse_realpow_zero_lemma, cut_tac x, simp)
110.1085 -  also have "\<dots> = x ^ N" by simp
110.1086 -  finally have "y < x ^ N" .
110.1087 -  hence "\<forall>n\<ge>N. y < x ^ n"
110.1088 -    apply clarify
110.1089 -    apply (erule order_less_le_trans)
110.1090 -    apply (erule power_increasing)
110.1091 -    apply (rule order_less_imp_le [OF x])
110.1092 -    done
110.1093 -  thus "\<exists>N. \<forall>n\<ge>N. y < x ^ n" ..
110.1094 -qed
110.1095 -
110.1096 -lemma LIMSEQ_realpow_zero:
110.1097 -  "\<lbrakk>0 \<le> (x::real); x < 1\<rbrakk> \<Longrightarrow> (\<lambda>n. x ^ n) ----> 0"
110.1098 -proof (cases)
110.1099 -  assume "x = 0"
110.1100 -  hence "(\<lambda>n. x ^ Suc n) ----> 0" by (simp add: LIMSEQ_const)
110.1101 -  thus ?thesis by (rule LIMSEQ_imp_Suc)
110.1102 -next
110.1103 -  assume "0 \<le> x" and "x \<noteq> 0"
110.1104 -  hence x0: "0 < x" by simp
110.1105 -  assume x1: "x < 1"
110.1106 -  from x0 x1 have "1 < inverse x"
110.1107 -    by (rule real_inverse_gt_one)
110.1108 -  hence "(\<lambda>n. inverse (inverse x ^ n)) ----> 0"
110.1109 -    by (rule LIMSEQ_inverse_realpow_zero)
110.1110 -  thus ?thesis by (simp add: power_inverse)
110.1111 -qed
110.1112 -
110.1113 -lemma LIMSEQ_power_zero:
110.1114 -  fixes x :: "'a::{real_normed_algebra_1,recpower}"
110.1115 -  shows "norm x < 1 \<Longrightarrow> (\<lambda>n. x ^ n) ----> 0"
110.1116 -apply (drule LIMSEQ_realpow_zero [OF norm_ge_zero])
110.1117 -apply (simp only: LIMSEQ_Zseq_iff, erule Zseq_le)
110.1118 -apply (simp add: power_abs norm_power_ineq)
110.1119 -done
110.1120 -
110.1121 -lemma LIMSEQ_divide_realpow_zero:
110.1122 -  "1 < (x::real) ==> (%n. a / (x ^ n)) ----> 0"
110.1123 -apply (cut_tac a = a and x1 = "inverse x" in
110.1124 -        LIMSEQ_mult [OF LIMSEQ_const LIMSEQ_realpow_zero])
110.1125 -apply (auto simp add: divide_inverse power_inverse)
110.1126 -apply (simp add: inverse_eq_divide pos_divide_less_eq)
110.1127 -done
110.1128 -
110.1129 -text{*Limit of @{term "c^n"} for @{term"\<bar>c\<bar> < 1"}*}
110.1130 -
110.1131 -lemma LIMSEQ_rabs_realpow_zero: "\<bar>c\<bar> < (1::real) ==> (%n. \<bar>c\<bar> ^ n) ----> 0"
110.1132 -by (rule LIMSEQ_realpow_zero [OF abs_ge_zero])
110.1133 -
110.1134 -lemma LIMSEQ_rabs_realpow_zero2: "\<bar>c\<bar> < (1::real) ==> (%n. c ^ n) ----> 0"
110.1135 -apply (rule LIMSEQ_rabs_zero [THEN iffD1])
110.1136 -apply (auto intro: LIMSEQ_rabs_realpow_zero simp add: power_abs)
110.1137 -done
110.1138 -
110.1139 -end
   111.1 --- a/src/HOL/IsaMakefile	Tue Dec 30 08:18:54 2008 +0100
   111.2 +++ b/src/HOL/IsaMakefile	Tue Dec 30 11:10:01 2008 +0100
   111.3 @@ -112,6 +112,8 @@
   111.4    Tools/dseq.ML \
   111.5    Tools/function_package/auto_term.ML \
   111.6    Tools/function_package/context_tree.ML \
   111.7 +  Tools/function_package/decompose.ML \
   111.8 +  Tools/function_package/descent.ML \
   111.9    Tools/function_package/fundef_common.ML \
  111.10    Tools/function_package/fundef_core.ML \
  111.11    Tools/function_package/fundef_datatype.ML \
  111.12 @@ -123,8 +125,11 @@
  111.13    Tools/function_package/measure_functions.ML \
  111.14    Tools/function_package/mutual.ML \
  111.15    Tools/function_package/pattern_split.ML \
  111.16 +  Tools/function_package/scnp_reconstruct.ML \
  111.17 +  Tools/function_package/scnp_solve.ML \
  111.18    Tools/function_package/size.ML \
  111.19    Tools/function_package/sum_tree.ML \
  111.20 +  Tools/function_package/termination.ML \
  111.21    Tools/hologic.ML \
  111.22    Tools/inductive_codegen.ML \
  111.23    Tools/inductive_package.ML \
  111.24 @@ -179,6 +184,7 @@
  111.25    $(SRC)/Tools/code/code_thingol.ML \
  111.26    $(SRC)/Tools/induct.ML \
  111.27    $(SRC)/Tools/induct_tacs.ML \
  111.28 +  $(SRC)/Tools/value.ML \
  111.29    $(SRC)/Tools/nbe.ML \
  111.30    $(SRC)/Tools/random_word.ML \
  111.31    $(SRC)/Tools/rat.ML
  111.32 @@ -255,7 +261,7 @@
  111.33  $(OUT)/HOL: ROOT.ML $(MAIN_DEPENDENCIES) \
  111.34    Complex_Main.thy \
  111.35    Complex.thy \
  111.36 -  Complex/Fundamental_Theorem_Algebra.thy \
  111.37 +  Fundamental_Theorem_Algebra.thy \
  111.38    Deriv.thy \
  111.39    Fact.thy \
  111.40    FrechetDeriv.thy \
  111.41 @@ -265,11 +271,11 @@
  111.42    Log.thy \
  111.43    MacLaurin.thy \
  111.44    NthRoot.thy \
  111.45 -  Hyperreal/SEQ.thy \
  111.46 +  SEQ.thy \
  111.47    Series.thy \
  111.48    Taylor.thy \
  111.49    Transcendental.thy \
  111.50 -  Library/Dense_Linear_Order.thy \
  111.51 +  Dense_Linear_Order.thy \
  111.52    GCD.thy \
  111.53    Order_Relation.thy \
  111.54    Parity.thy \
  111.55 @@ -281,7 +287,7 @@
  111.56    RealDef.thy \
  111.57    RealPow.thy \
  111.58    Real.thy \
  111.59 -  Real/RealVector.thy \
  111.60 +  RealVector.thy \
  111.61    Tools/float_syntax.ML \
  111.62    Tools/rat_arith.ML \
  111.63    Tools/real_arith.ML \
  111.64 @@ -331,16 +337,16 @@
  111.65  HOL-HahnBanach: HOL $(LOG)/HOL-HahnBanach.gz
  111.66  
  111.67  $(LOG)/HOL-HahnBanach.gz: $(OUT)/HOL			\
  111.68 -  Real/HahnBanach/Bounds.thy Real/HahnBanach/FunctionNorm.thy		\
  111.69 -  Real/HahnBanach/FunctionOrder.thy Real/HahnBanach/HahnBanach.thy	\
  111.70 -  Real/HahnBanach/HahnBanachExtLemmas.thy				\
  111.71 -  Real/HahnBanach/HahnBanachSupLemmas.thy				\
  111.72 -  Real/HahnBanach/Linearform.thy Real/HahnBanach/NormedSpace.thy	\
  111.73 -  Real/HahnBanach/README.html Real/HahnBanach/ROOT.ML			\
  111.74 -  Real/HahnBanach/Subspace.thy Real/HahnBanach/VectorSpace.thy		\
  111.75 -  Real/HahnBanach/ZornLemma.thy Real/HahnBanach/document/root.bib	\
  111.76 -  Real/HahnBanach/document/root.tex
  111.77 -	@cd Real; $(ISABELLE_TOOL) usedir -g true $(OUT)/HOL HahnBanach
  111.78 +  HahnBanach/Bounds.thy HahnBanach/FunctionNorm.thy		\
  111.79 +  HahnBanach/FunctionOrder.thy HahnBanach/HahnBanach.thy	\
  111.80 +  HahnBanach/HahnBanachExtLemmas.thy				\
  111.81 +  HahnBanach/HahnBanachSupLemmas.thy				\
  111.82 +  HahnBanach/Linearform.thy HahnBanach/NormedSpace.thy	\
  111.83 +  HahnBanach/README.html HahnBanach/ROOT.ML			\
  111.84 +  HahnBanach/Subspace.thy HahnBanach/VectorSpace.thy		\
  111.85 +  HahnBanach/ZornLemma.thy HahnBanach/document/root.bib	\
  111.86 +  HahnBanach/document/root.tex
  111.87 +	@$(ISABELLE_TOOL) usedir -g true $(OUT)/HOL HahnBanach
  111.88  
  111.89  
  111.90  ## HOL-Subst
  111.91 @@ -776,20 +782,21 @@
  111.92    ex/Coherent.thy ex/Dense_Linear_Order_Ex.thy ex/Eval_Examples.thy	\
  111.93    ex/Groebner_Examples.thy ex/Random.thy ex/Quickcheck.thy		\
  111.94    ex/Codegenerator.thy ex/Codegenerator_Pretty.thy			\
  111.95 +  ex/CodegenSML_Test.thy 						\
  111.96    ex/Commutative_RingEx.thy ex/Efficient_Nat_examples.thy		\
  111.97    ex/Hex_Bin_Examples.thy ex/Commutative_Ring_Complete.thy		\
  111.98    ex/ExecutableContent.thy ex/Fundefs.thy ex/Guess.thy ex/Hebrew.thy	\
  111.99    ex/Binary.thy ex/Higher_Order_Logic.thy ex/Hilbert_Classical.thy	\
 111.100    ex/Induction_Scheme.thy ex/InductiveInvariant.thy			\
 111.101    ex/InductiveInvariant_examples.thy ex/Intuitionistic.thy		\
 111.102 -  ex/Lagrange.thy ex/LexOrds.thy ex/LocaleTest2.thy ex/MT.thy		\
 111.103 +  ex/Lagrange.thy ex/LocaleTest2.thy ex/MT.thy		\
 111.104    ex/MergeSort.thy ex/MonoidGroup.thy ex/Multiquote.thy ex/NatSum.thy	\
 111.105    ex/Numeral.thy ex/PER.thy ex/PresburgerEx.thy ex/Primrec.thy		\
 111.106    ex/Quickcheck_Examples.thy ex/Reflection.thy ex/reflection_data.ML	\
 111.107    ex/ReflectionEx.thy ex/ROOT.ML ex/Recdefs.thy ex/Records.thy		\
 111.108    ex/Reflected_Presburger.thy ex/coopertac.ML				\
 111.109    ex/Refute_Examples.thy ex/SAT_Examples.thy ex/SVC_Oracle.thy		\
 111.110 -  ex/Sudoku.thy ex/Tarski.thy ex/Term_Of_Syntax.thy			\
 111.111 +  ex/Sudoku.thy ex/Tarski.thy ex/Termination.thy ex/Term_Of_Syntax.thy			\
 111.112    ex/Unification.thy ex/document/root.bib			\
 111.113    ex/document/root.tex ex/Meson_Test.thy ex/reflection.ML ex/set.thy	\
 111.114    ex/svc_funcs.ML ex/svc_test.thy	\
   112.1 --- a/src/HOL/Library/Dense_Linear_Order.thy	Tue Dec 30 08:18:54 2008 +0100
   112.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   112.3 @@ -1,879 +0,0 @@
   112.4 -(*
   112.5 -    Author:     Amine Chaieb, TU Muenchen
   112.6 -*)
   112.7 -
   112.8 -header {* Dense linear order without endpoints
   112.9 -  and a quantifier elimination procedure in Ferrante and Rackoff style *}
  112.10 -
  112.11 -theory Dense_Linear_Order
  112.12 -imports Plain "~~/src/HOL/Groebner_Basis"
  112.13 -uses
  112.14 -  "~~/src/HOL/Tools/Qelim/langford_data.ML"
  112.15 -  "~~/src/HOL/Tools/Qelim/ferrante_rackoff_data.ML"
  112.16 -  ("~~/src/HOL/Tools/Qelim/langford.ML")
  112.17 -  ("~~/src/HOL/Tools/Qelim/ferrante_rackoff.ML")
  112.18 -begin
  112.19 -
  112.20 -setup {* Langford_Data.setup #> Ferrante_Rackoff_Data.setup *}
  112.21 -
  112.22 -context linorder
  112.23 -begin
  112.24 -
  112.25 -lemma less_not_permute: "\<not> (x < y \<and> y < x)" by (simp add: not_less linear)
  112.26 -
  112.27 -lemma gather_simps: 
  112.28 -  shows 
  112.29 -  "(\<exists>x. (\<forall>y \<in> L. y < x) \<and> (\<forall>y \<in> U. x < y) \<and> x < u \<and> P x) \<longleftrightarrow> (\<exists>x. (\<forall>y \<in> L. y < x) \<and> (\<forall>y \<in> (insert u U). x < y) \<and> P x)"
  112.30 -  and "(\<exists>x. (\<forall>y \<in> L. y < x) \<and> (\<forall>y \<in> U. x < y) \<and> l < x \<and> P x) \<longleftrightarrow> (\<exists>x. (\<forall>y \<in> (insert l L). y < x) \<and> (\<forall>y \<in> U. x < y) \<and> P x)"
  112.31 -  "(\<exists>x. (\<forall>y \<in> L. y < x) \<and> (\<forall>y \<in> U. x < y) \<and> x < u) \<longleftrightarrow> (\<exists>x. (\<forall>y \<in> L. y < x) \<and> (\<forall>y \<in> (insert u U). x < y))"
  112.32 -  and "(\<exists>x. (\<forall>y \<in> L. y < x) \<and> (\<forall>y \<in> U. x < y) \<and> l < x) \<longleftrightarrow> (\<exists>x. (\<forall>y \<in> (insert l L). y < x) \<and> (\<forall>y \<in> U. x < y))"  by auto
  112.33 -
  112.34 -lemma 
  112.35 -  gather_start: "(\<exists>x. P x) \<equiv> (\<exists>x. (\<forall>y \<in> {}. y < x) \<and> (\<forall>y\<in> {}. x < y) \<and> P x)" 
  112.36 -  by simp
  112.37 -
  112.38 -text{* Theorems for @{text "\<exists>z. \<forall>x. x < z \<longrightarrow> (P x \<longleftrightarrow> P\<^bsub>-\<infinity>\<^esub>)"}*}
  112.39 -lemma minf_lt:  "\<exists>z . \<forall>x. x < z \<longrightarrow> (x < t \<longleftrightarrow> True)" by auto
  112.40 -lemma minf_gt: "\<exists>z . \<forall>x. x < z \<longrightarrow>  (t < x \<longleftrightarrow>  False)"
  112.41 -  by (simp add: not_less) (rule exI[where x="t"], auto simp add: less_le)
  112.42 -
  112.43 -lemma minf_le: "\<exists>z. \<forall>x. x < z \<longrightarrow> (x \<le> t \<longleftrightarrow> True)" by (auto simp add: less_le)
  112.44 -lemma minf_ge: "\<exists>z. \<forall>x. x < z \<longrightarrow> (t \<le> x \<longleftrightarrow> False)"
  112.45 -  by (auto simp add: less_le not_less not_le)
  112.46 -lemma minf_eq: "\<exists>z. \<forall>x. x < z \<longrightarrow> (x = t \<longleftrightarrow> False)" by auto
  112.47 -lemma minf_neq: "\<exists>z. \<forall>x. x < z \<longrightarrow> (x \<noteq> t \<longleftrightarrow> True)" by auto
  112.48 -lemma minf_P: "\<exists>z. \<forall>x. x < z \<longrightarrow> (P \<longleftrightarrow> P)" by blast
  112.49 -
  112.50 -text{* Theorems for @{text "\<exists>z. \<forall>x. x < z \<longrightarrow> (P x \<longleftrightarrow> P\<^bsub>+\<infinity>\<^esub>)"}*}
  112.51 -lemma pinf_gt:  "\<exists>z . \<forall>x. z < x \<longrightarrow> (t < x \<longleftrightarrow> True)" by auto
  112.52 -lemma pinf_lt: "\<exists>z . \<forall>x. z < x \<longrightarrow>  (x < t \<longleftrightarrow>  False)"
  112.53 -  by (simp add: not_less) (rule exI[where x="t"], auto simp add: less_le)
  112.54 -
  112.55 -lemma pinf_ge: "\<exists>z. \<forall>x. z < x \<longrightarrow> (t \<le> x \<longleftrightarrow> True)" by (auto simp add: less_le)
  112.56 -lemma pinf_le: "\<exists>z. \<forall>x. z < x \<longrightarrow> (x \<le> t \<longleftrightarrow> False)"
  112.57 -  by (auto simp add: less_le not_less not_le)
  112.58 -lemma pinf_eq: "\<exists>z. \<forall>x. z < x \<longrightarrow> (x = t \<longleftrightarrow> False)" by auto
  112.59 -lemma pinf_neq: "\<exists>z. \<forall>x. z < x \<longrightarrow> (x \<noteq> t \<longleftrightarrow> True)" by auto
  112.60 -lemma pinf_P: "\<exists>z. \<forall>x. z < x \<longrightarrow> (P \<longleftrightarrow> P)" by blast
  112.61 -
  112.62 -lemma nmi_lt: "t \<in> U \<Longrightarrow> \<forall>x. \<not>True \<and> x < t \<longrightarrow>  (\<exists> u\<in> U. u \<le> x)" by auto
  112.63 -lemma nmi_gt: "t \<in> U \<Longrightarrow> \<forall>x. \<not>False \<and> t < x \<longrightarrow>  (\<exists> u\<in> U. u \<le> x)"
  112.64 -  by (auto simp add: le_less)
  112.65 -lemma  nmi_le: "t \<in> U \<Longrightarrow> \<forall>x. \<not>True \<and> x\<le> t \<longrightarrow>  (\<exists> u\<in> U. u \<le> x)" by auto
  112.66 -lemma  nmi_ge: "t \<in> U \<Longrightarrow> \<forall>x. \<not>False \<and> t\<le> x \<longrightarrow>  (\<exists> u\<in> U. u \<le> x)" by auto
  112.67 -lemma  nmi_eq: "t \<in> U \<Longrightarrow> \<forall>x. \<not>False \<and>  x = t \<longrightarrow>  (\<exists> u\<in> U. u \<le> x)" by auto
  112.68 -lemma  nmi_neq: "t \<in> U \<Longrightarrow>\<forall>x. \<not>True \<and> x \<noteq> t \<longrightarrow>  (\<exists> u\<in> U. u \<le> x)" by auto
  112.69 -lemma  nmi_P: "\<forall> x. ~P \<and> P \<longrightarrow>  (\<exists> u\<in> U. u \<le> x)" by auto
  112.70 -lemma  nmi_conj: "\<lbrakk>\<forall>x. \<not>P1' \<and> P1 x \<longrightarrow>  (\<exists> u\<in> U. u \<le> x) ;
  112.71 -  \<forall>x. \<not>P2' \<and> P2 x \<longrightarrow>  (\<exists> u\<in> U. u \<le> x)\<rbrakk> \<Longrightarrow>
  112.72 -  \<forall>x. \<not>(P1' \<and> P2') \<and> (P1 x \<and> P2 x) \<longrightarrow>  (\<exists> u\<in> U. u \<le> x)" by auto
  112.73 -lemma  nmi_disj: "\<lbrakk>\<forall>x. \<not>P1' \<and> P1 x \<longrightarrow>  (\<exists> u\<in> U. u \<le> x) ;
  112.74 -  \<forall>x. \<not>P2' \<and> P2 x \<longrightarrow>  (\<exists> u\<in> U. u \<le> x)\<rbrakk> \<Longrightarrow>
  112.75 -  \<forall>x. \<not>(P1' \<or> P2') \<and> (P1 x \<or> P2 x) \<longrightarrow>  (\<exists> u\<in> U. u \<le> x)" by auto
  112.76 -
  112.77 -lemma  npi_lt: "t \<in> U \<Longrightarrow> \<forall>x. \<not>False \<and>  x < t \<longrightarrow>  (\<exists> u\<in> U. x \<le> u)" by (auto simp add: le_less)
  112.78 -lemma  npi_gt: "t \<in> U \<Longrightarrow> \<forall>x. \<not>True \<and> t < x \<longrightarrow>  (\<exists> u\<in> U. x \<le> u)" by auto
  112.79 -lemma  npi_le: "t \<in> U \<Longrightarrow> \<forall>x. \<not>False \<and>  x \<le> t \<longrightarrow>  (\<exists> u\<in> U. x \<le> u)" by auto
  112.80 -lemma  npi_ge: "t \<in> U \<Longrightarrow> \<forall>x. \<not>True \<and> t \<le> x \<longrightarrow>  (\<exists> u\<in> U. x \<le> u)" by auto
  112.81 -lemma  npi_eq: "t \<in> U \<Longrightarrow> \<forall>x. \<not>False \<and>  x = t \<longrightarrow>  (\<exists> u\<in> U. x \<le> u)" by auto
  112.82 -lemma  npi_neq: "t \<in> U \<Longrightarrow> \<forall>x. \<not>True \<and> x \<noteq> t \<longrightarrow>  (\<exists> u\<in> U. x \<le> u )" by auto
  112.83 -lemma  npi_P: "\<forall> x. ~P \<and> P \<longrightarrow>  (\<exists> u\<in> U. x \<le> u)" by auto
  112.84 -lemma  npi_conj: "\<lbrakk>\<forall>x. \<not>P1' \<and> P1 x \<longrightarrow>  (\<exists> u\<in> U. x \<le> u) ;  \<forall>x. \<not>P2' \<and> P2 x \<longrightarrow>  (\<exists> u\<in> U. x \<le> u)\<rbrakk>
  112.85 -  \<Longrightarrow>  \<forall>x. \<not>(P1' \<and> P2') \<and> (P1 x \<and> P2 x) \<longrightarrow>  (\<exists> u\<in> U. x \<le> u)" by auto
  112.86 -lemma  npi_disj: "\<lbrakk>\<forall>x. \<not>P1' \<and> P1 x \<longrightarrow>  (\<exists> u\<in> U. x \<le> u) ; \<forall>x. \<not>P2' \<and> P2 x \<longrightarrow>  (\<exists> u\<in> U. x \<le> u)\<rbrakk>
  112.87 -  \<Longrightarrow> \<forall>x. \<not>(P1' \<or> P2') \<and> (P1 x \<or> P2 x) \<longrightarrow>  (\<exists> u\<in> U. x \<le> u)" by auto
  112.88 -
  112.89 -lemma lin_dense_lt: "t \<in> U \<Longrightarrow> \<forall>x l u. (\<forall> t. l < t \<and> t < u \<longrightarrow> t \<notin> U) \<and> l< x \<and> x < u \<and> x < t \<longrightarrow> (\<forall> y. l < y \<and> y < u \<longrightarrow> y < t)"
  112.90 -proof(clarsimp)
  112.91 -  fix x l u y  assume tU: "t \<in> U" and noU: "\<forall>t. l < t \<and> t < u \<longrightarrow> t \<notin> U" and lx: "l < x"
  112.92 -    and xu: "x<u"  and px: "x < t" and ly: "l<y" and yu:"y < u"
  112.93 -  from tU noU ly yu have tny: "t\<noteq>y" by auto
  112.94 -  {assume H: "t < y"
  112.95 -    from less_trans[OF lx px] less_trans[OF H yu]
  112.96 -    have "l < t \<and> t < u"  by simp
  112.97 -    with tU noU have "False" by auto}
  112.98 -  hence "\<not> t < y"  by auto hence "y \<le> t" by (simp add: not_less)
  112.99 -  thus "y < t" using tny by (simp add: less_le)
 112.100 -qed
 112.101 -
 112.102 -lemma lin_dense_gt: "t \<in> U \<Longrightarrow> \<forall>x l u. (\<forall> t. l < t \<and> t< u \<longrightarrow> t \<notin> U) \<and> l < x \<and> x < u \<and> t < x \<longrightarrow> (\<forall> y. l < y \<and> y < u \<longrightarrow> t < y)"
 112.103 -proof(clarsimp)
 112.104 -  fix x l u y
 112.105 -  assume tU: "t \<in> U" and noU: "\<forall>t. l < t \<and> t < u \<longrightarrow> t \<notin> U" and lx: "l < x" and xu: "x<u"
 112.106 -  and px: "t < x" and ly: "l<y" and yu:"y < u"
 112.107 -  from tU noU ly yu have tny: "t\<noteq>y" by auto
 112.108 -  {assume H: "y< t"
 112.109 -    from less_trans[OF ly H] less_trans[OF px xu] have "l < t \<and> t < u" by simp
 112.110 -    with tU noU have "False" by auto}
 112.111 -  hence "\<not> y<t"  by auto hence "t \<le> y" by (auto simp add: not_less)
 112.112 -  thus "t < y" using tny by (simp add:less_le)
 112.113 -qed
 112.114 -
 112.115 -lemma lin_dense_le: "t \<in> U \<Longrightarrow> \<forall>x l u. (\<forall> t. l < t \<and> t< u \<longrightarrow> t \<notin> U) \<and> l< x \<and> x < u \<and> x \<le> t \<longrightarrow> (\<forall> y. l < y \<and> y < u \<longrightarrow> y\<le> t)"
 112.116 -proof(clarsimp)
 112.117 -  fix x l u y
 112.118 -  assume tU: "t \<in> U" and noU: "\<forall>t. l < t \<and> t < u \<longrightarrow> t \<notin> U" and lx: "l < x" and xu: "x<u"
 112.119 -  and px: "x \<le> t" and ly: "l<y" and yu:"y < u"
 112.120 -  from tU noU ly yu have tny: "t\<noteq>y" by auto
 112.121 -  {assume H: "t < y"
 112.122 -    from less_le_trans[OF lx px] less_trans[OF H yu]
 112.123 -    have "l < t \<and> t < u" by simp
 112.124 -    with tU noU have "False" by auto}
 112.125 -  hence "\<not> t < y"  by auto thus "y \<le> t" by (simp add: not_less)
 112.126 -qed
 112.127 -
 112.128 -lemma lin_dense_ge: "t \<in> U \<Longrightarrow> \<forall>x l u. (\<forall> t. l < t \<and> t< u \<longrightarrow> t \<notin> U) \<and> l< x \<and> x < u \<and> t \<le> x \<longrightarrow> (\<forall> y. l < y \<and> y < u \<longrightarrow> t \<le> y)"
 112.129 -proof(clarsimp)
 112.130 -  fix x l u y
 112.131 -  assume tU: "t \<in> U" and noU: "\<forall>t. l < t \<and> t < u \<longrightarrow> t \<notin> U" and lx: "l < x" and xu: "x<u"
 112.132 -  and px: "t \<le> x" and ly: "l<y" and yu:"y < u"
 112.133 -  from tU noU ly yu have tny: "t\<noteq>y" by auto
 112.134 -  {assume H: "y< t"
 112.135 -    from less_trans[OF ly H] le_less_trans[OF px xu]
 112.136 -    have "l < t \<and> t < u" by simp
 112.137 -    with tU noU have "False" by auto}
 112.138 -  hence "\<not> y<t"  by auto thus "t \<le> y" by (simp add: not_less)
 112.139 -qed
 112.140 -lemma lin_dense_eq: "t \<in> U \<Longrightarrow> \<forall>x l u. (\<forall> t. l < t \<and> t< u \<longrightarrow> t \<notin> U) \<and> l< x \<and> x < u \<and> x = t   \<longrightarrow> (\<forall> y. l < y \<and> y < u \<longrightarrow> y= t)"  by auto
 112.141 -lemma lin_dense_neq: "t \<in> U \<Longrightarrow> \<forall>x l u. (\<forall> t. l < t \<and> t< u \<longrightarrow> t \<notin> U) \<and> l< x \<and> x < u \<and> x \<noteq> t   \<longrightarrow> (\<forall> y. l < y \<and> y < u \<longrightarrow> y\<noteq> t)"  by auto
 112.142 -lemma lin_dense_P: "\<forall>x l u. (\<forall> t. l < t \<and> t< u \<longrightarrow> t \<notin> U) \<and> l< x \<and> x < u \<and> P   \<longrightarrow> (\<forall> y. l < y \<and> y < u \<longrightarrow> P)"  by auto
 112.143 -
 112.144 -lemma lin_dense_conj:
 112.145 -  "\<lbrakk>\<forall>x l u. (\<forall> t. l < t \<and> t< u \<longrightarrow> t \<notin> U) \<and> l< x \<and> x < u \<and> P1 x
 112.146 -  \<longrightarrow> (\<forall> y. l < y \<and> y < u \<longrightarrow> P1 y) ;
 112.147 -  \<forall>x l u. (\<forall> t. l < t \<and> t< u \<longrightarrow> t \<notin> U) \<and> l< x \<and> x < u \<and> P2 x
 112.148 -  \<longrightarrow> (\<forall> y. l < y \<and> y < u \<longrightarrow> P2 y)\<rbrakk> \<Longrightarrow>
 112.149 -  \<forall>x l u. (\<forall> t. l < t \<and> t< u \<longrightarrow> t \<notin> U) \<and> l< x \<and> x < u \<and> (P1 x \<and> P2 x)
 112.150 -  \<longrightarrow> (\<forall> y. l < y \<and> y < u \<longrightarrow> (P1 y \<and> P2 y))"
 112.151 -  by blast
 112.152 -lemma lin_dense_disj:
 112.153 -  "\<lbrakk>\<forall>x l u. (\<forall> t. l < t \<and> t< u \<longrightarrow> t \<notin> U) \<and> l< x \<and> x < u \<and> P1 x
 112.154 -  \<longrightarrow> (\<forall> y. l < y \<and> y < u \<longrightarrow> P1 y) ;
 112.155 -  \<forall>x l u. (\<forall> t. l < t \<and> t< u \<longrightarrow> t \<notin> U) \<and> l< x \<and> x < u \<and> P2 x
 112.156 -  \<longrightarrow> (\<forall> y. l < y \<and> y < u \<longrightarrow> P2 y)\<rbrakk> \<Longrightarrow>
 112.157 -  \<forall>x l u. (\<forall> t. l < t \<and> t< u \<longrightarrow> t \<notin> U) \<and> l< x \<and> x < u \<and> (P1 x \<or> P2 x)
 112.158 -  \<longrightarrow> (\<forall> y. l < y \<and> y < u \<longrightarrow> (P1 y \<or> P2 y))"
 112.159 -  by blast
 112.160 -
 112.161 -lemma npmibnd: "\<lbrakk>\<forall>x. \<not> MP \<and> P x \<longrightarrow> (\<exists> u\<in> U. u \<le> x); \<forall>x. \<not>PP \<and> P x \<longrightarrow> (\<exists> u\<in> U. x \<le> u)\<rbrakk>
 112.162 -  \<Longrightarrow> \<forall>x. \<not> MP \<and> \<not>PP \<and> P x \<longrightarrow> (\<exists> u\<in> U. \<exists> u' \<in> U. u \<le> x \<and> x \<le> u')"
 112.163 -by auto
 112.164 -
 112.165 -lemma finite_set_intervals:
 112.166 -  assumes px: "P x" and lx: "l \<le> x" and xu: "x \<le> u" and linS: "l\<in> S"
 112.167 -  and uinS: "u \<in> S" and fS:"finite S" and lS: "\<forall> x\<in> S. l \<le> x" and Su: "\<forall> x\<in> S. x \<le> u"
 112.168 -  shows "\<exists> a \<in> S. \<exists> b \<in> S. (\<forall> y. a < y \<and> y < b \<longrightarrow> y \<notin> S) \<and> a \<le> x \<and> x \<le> b \<and> P x"
 112.169 -proof-
 112.170 -  let ?Mx = "{y. y\<in> S \<and> y \<le> x}"
 112.171 -  let ?xM = "{y. y\<in> S \<and> x \<le> y}"
 112.172 -  let ?a = "Max ?Mx"
 112.173 -  let ?b = "Min ?xM"
 112.174 -  have MxS: "?Mx \<subseteq> S" by blast
 112.175 -  hence fMx: "finite ?Mx" using fS finite_subset by auto
 112.176 -  from lx linS have linMx: "l \<in> ?Mx" by blast
 112.177 -  hence Mxne: "?Mx \<noteq> {}" by blast
 112.178 -  have xMS: "?xM \<subseteq> S" by blast
 112.179 -  hence fxM: "finite ?xM" using fS finite_subset by auto
 112.180 -  from xu uinS have linxM: "u \<in> ?xM" by blast
 112.181 -  hence xMne: "?xM \<noteq> {}" by blast
 112.182 -  have ax:"?a \<le> x" using Mxne fMx by auto
 112.183 -  have xb:"x \<le> ?b" using xMne fxM by auto
 112.184 -  have "?a \<in> ?Mx" using Max_in[OF fMx Mxne] by simp hence ainS: "?a \<in> S" using MxS by blast
 112.185 -  have "?b \<in> ?xM" using Min_in[OF fxM xMne] by simp hence binS: "?b \<in> S" using xMS by blast
 112.186 -  have noy:"\<forall> y. ?a < y \<and> y < ?b \<longrightarrow> y \<notin> S"
 112.187 -  proof(clarsimp)
 112.188 -    fix y   assume ay: "?a < y" and yb: "y < ?b" and yS: "y \<in> S"
 112.189 -    from yS have "y\<in> ?Mx \<or> y\<in> ?xM" by (auto simp add: linear)
 112.190 -    moreover {assume "y \<in> ?Mx" hence "y \<le> ?a" using Mxne fMx by auto with ay have "False" by (simp add: not_le[symmetric])}
 112.191 -    moreover {assume "y \<in> ?xM" hence "?b \<le> y" using xMne fxM by auto with yb have "False" by (simp add: not_le[symmetric])}
 112.192 -    ultimately show "False" by blast
 112.193 -  qed
 112.194 -  from ainS binS noy ax xb px show ?thesis by blast
 112.195 -qed
 112.196 -
 112.197 -lemma finite_set_intervals2:
 112.198 -  assumes px: "P x" and lx: "l \<le> x" and xu: "x \<le> u" and linS: "l\<in> S"
 112.199 -  and uinS: "u \<in> S" and fS:"finite S" and lS: "\<forall> x\<in> S. l \<le> x" and Su: "\<forall> x\<in> S. x \<le> u"
 112.200 -  shows "(\<exists> s\<in> S. P s) \<or> (\<exists> a \<in> S. \<exists> b \<in> S. (\<forall> y. a < y \<and> y < b \<longrightarrow> y \<notin> S) \<and> a < x \<and> x < b \<and> P x)"
 112.201 -proof-
 112.202 -  from finite_set_intervals[where P="P", OF px lx xu linS uinS fS lS Su]
 112.203 -  obtain a and b where
 112.204 -    as: "a\<in> S" and bs: "b\<in> S" and noS:"\<forall>y. a < y \<and> y < b \<longrightarrow> y \<notin> S"
 112.205 -    and axb: "a \<le> x \<and> x \<le> b \<and> P x"  by auto
 112.206 -  from axb have "x= a \<or> x= b \<or> (a < x \<and> x < b)" by (auto simp add: le_less)
 112.207 -  thus ?thesis using px as bs noS by blast
 112.208 -qed
 112.209 -
 112.210 -end
 112.211 -
 112.212 -section {* The classical QE after Langford for dense linear orders *}
 112.213 -
 112.214 -context dense_linear_order
 112.215 -begin
 112.216 -
 112.217 -lemma interval_empty_iff:
 112.218 -  "{y. x < y \<and> y < z} = {} \<longleftrightarrow> \<not> x < z"
 112.219 -  by (auto dest: dense)
 112.220 -
 112.221 -lemma dlo_qe_bnds: 
 112.222 -  assumes ne: "L \<noteq> {}" and neU: "U \<noteq> {}" and fL: "finite L" and fU: "finite U"
 112.223 -  shows "(\<exists>x. (\<forall>y \<in> L. y < x) \<and> (\<forall>y \<in> U. x < y)) \<equiv> (\<forall> l \<in> L. \<forall>u \<in> U. l < u)"
 112.224 -proof (simp only: atomize_eq, rule iffI)
 112.225 -  assume H: "\<exists>x. (\<forall>y\<in>L. y < x) \<and> (\<forall>y\<in>U. x < y)"
 112.226 -  then obtain x where xL: "\<forall>y\<in>L. y < x" and xU: "\<forall>y\<in>U. x < y" by blast
 112.227 -  {fix l u assume l: "l \<in> L" and u: "u \<in> U"
 112.228 -    have "l < x" using xL l by blast
 112.229 -    also have "x < u" using xU u by blast
 112.230 -    finally (less_trans) have "l < u" .}
 112.231 -  thus "\<forall>l\<in>L. \<forall>u\<in>U. l < u" by blast
 112.232 -next
 112.233 -  assume H: "\<forall>l\<in>L. \<forall>u\<in>U. l < u"
 112.234 -  let ?ML = "Max L"
 112.235 -  let ?MU = "Min U"  
 112.236 -  from fL ne have th1: "?ML \<in> L" and th1': "\<forall>l\<in>L. l \<le> ?ML" by auto
 112.237 -  from fU neU have th2: "?MU \<in> U" and th2': "\<forall>u\<in>U. ?MU \<le> u" by auto
 112.238 -  from th1 th2 H have "?ML < ?MU" by auto
 112.239 -  with dense obtain w where th3: "?ML < w" and th4: "w < ?MU" by blast
 112.240 -  from th3 th1' have "\<forall>l \<in> L. l < w" by auto
 112.241 -  moreover from th4 th2' have "\<forall>u \<in> U. w < u" by auto
 112.242 -  ultimately show "\<exists>x. (\<forall>y\<in>L. y < x) \<and> (\<forall>y\<in>U. x < y)" by auto
 112.243 -qed
 112.244 -
 112.245 -lemma dlo_qe_noub: 
 112.246 -  assumes ne: "L \<noteq> {}" and fL: "finite L"
 112.247 -  shows "(\<exists>x. (\<forall>y \<in> L. y < x) \<and> (\<forall>y \<in> {}. x < y)) \<equiv> True"
 112.248 -proof(simp add: atomize_eq)
 112.249 -  from gt_ex[of "Max L"] obtain M where M: "Max L < M" by blast
 112.250 -  from ne fL have "\<forall>x \<in> L. x \<le> Max L" by simp
 112.251 -  with M have "\<forall>x\<in>L. x < M" by (auto intro: le_less_trans)
 112.252 -  thus "\<exists>x. \<forall>y\<in>L. y < x" by blast
 112.253 -qed
 112.254 -
 112.255 -lemma dlo_qe_nolb: 
 112.256 -  assumes ne: "U \<noteq> {}" and fU: "finite U"
 112.257 -  shows "(\<exists>x. (\<forall>y \<in> {}. y < x) \<and> (\<forall>y \<in> U. x < y)) \<equiv> True"
 112.258 -proof(simp add: atomize_eq)
 112.259 -  from lt_ex[of "Min U"] obtain M where M: "M < Min U" by blast
 112.260 -  from ne fU have "\<forall>x \<in> U. Min U \<le> x" by simp
 112.261 -  with M have "\<forall>x\<in>U. M < x" by (auto intro: less_le_trans)
 112.262 -  thus "\<exists>x. \<forall>y\<in>U. x < y" by blast
 112.263 -qed
 112.264 -
 112.265 -lemma exists_neq: "\<exists>(x::'a). x \<noteq> t" "\<exists>(x::'a). t \<noteq> x" 
 112.266 -  using gt_ex[of t] by auto
 112.267 -
 112.268 -lemmas dlo_simps = order_refl less_irrefl not_less not_le exists_neq 
 112.269 -  le_less neq_iff linear less_not_permute
 112.270 -
 112.271 -lemma axiom: "dense_linear_order (op \<le>) (op <)" by (rule dense_linear_order_axioms)
 112.272 -lemma atoms:
 112.273 -  shows "TERM (less :: 'a \<Rightarrow> _)"
 112.274 -    and "TERM (less_eq :: 'a \<Rightarrow> _)"
 112.275 -    and "TERM (op = :: 'a \<Rightarrow> _)" .
 112.276 -
 112.277 -declare axiom[langford qe: dlo_qe_bnds dlo_qe_nolb dlo_qe_noub gather: gather_start gather_simps atoms: atoms]
 112.278 -declare dlo_simps[langfordsimp]
 112.279 -
 112.280 -end
 112.281 -
 112.282 -(* FIXME: Move to HOL -- together with the conj_aci_rule in langford.ML *)
 112.283 -lemma dnf:
 112.284 -  "(P & (Q | R)) = ((P&Q) | (P&R))" 
 112.285 -  "((Q | R) & P) = ((Q&P) | (R&P))"
 112.286 -  by blast+
 112.287 -
 112.288 -lemmas weak_dnf_simps = simp_thms dnf
 112.289 -
 112.290 -lemma nnf_simps:
 112.291 -    "(\<not>(P \<and> Q)) = (\<not>P \<or> \<not>Q)" "(\<not>(P \<or> Q)) = (\<not>P \<and> \<not>Q)" "(P \<longrightarrow> Q) = (\<not>P \<or> Q)"
 112.292 -    "(P = Q) = ((P \<and> Q) \<or> (\<not>P \<and> \<not> Q))" "(\<not> \<not>(P)) = P"
 112.293 -  by blast+
 112.294 -
 112.295 -lemma ex_distrib: "(\<exists>x. P x \<or> Q x) \<longleftrightarrow> ((\<exists>x. P x) \<or> (\<exists>x. Q x))" by blast
 112.296 -
 112.297 -lemmas dnf_simps = weak_dnf_simps nnf_simps ex_distrib
 112.298 -
 112.299 -use "~~/src/HOL/Tools/Qelim/langford.ML"
 112.300 -method_setup dlo = {*
 112.301 -  Method.ctxt_args (Method.SIMPLE_METHOD' o LangfordQE.dlo_tac)
 112.302 -*} "Langford's algorithm for quantifier elimination in dense linear orders"
 112.303 -
 112.304 -
 112.305 -section {* Contructive dense linear orders yield QE for linear arithmetic over ordered Fields -- see @{text "Arith_Tools.thy"} *}
 112.306 -
 112.307 -text {* Linear order without upper bounds *}
 112.308 -
 112.309 -class_locale linorder_stupid_syntax = linorder
 112.310 -begin
 112.311 -notation
 112.312 -  less_eq  ("op \<sqsubseteq>") and
 112.313 -  less_eq  ("(_/ \<sqsubseteq> _)" [51, 51] 50) and
 112.314 -  less  ("op \<sqsubset>") and
 112.315 -  less  ("(_/ \<sqsubset> _)"  [51, 51] 50)
 112.316 -
 112.317 -end
 112.318 -
 112.319 -class_locale linorder_no_ub = linorder_stupid_syntax +
 112.320 -  assumes gt_ex: "\<exists>y. less x y"
 112.321 -begin
 112.322 -lemma ge_ex: "\<exists>y. x \<sqsubseteq> y" using gt_ex by auto
 112.323 -
 112.324 -text {* Theorems for @{text "\<exists>z. \<forall>x. z \<sqsubset> x \<longrightarrow> (P x \<longleftrightarrow> P\<^bsub>+\<infinity>\<^esub>)"} *}
 112.325 -lemma pinf_conj:
 112.326 -  assumes ex1: "\<exists>z1. \<forall>x. z1 \<sqsubset> x \<longrightarrow> (P1 x \<longleftrightarrow> P1')"
 112.327 -  and ex2: "\<exists>z2. \<forall>x. z2 \<sqsubset> x \<longrightarrow> (P2 x \<longleftrightarrow> P2')"
 112.328 -  shows "\<exists>z. \<forall>x. z \<sqsubset>  x \<longrightarrow> ((P1 x \<and> P2 x) \<longleftrightarrow> (P1' \<and> P2'))"
 112.329 -proof-
 112.330 -  from ex1 ex2 obtain z1 and z2 where z1: "\<forall>x. z1 \<sqsubset> x \<longrightarrow> (P1 x \<longleftrightarrow> P1')"
 112.331 -     and z2: "\<forall>x. z2 \<sqsubset> x \<longrightarrow> (P2 x \<longleftrightarrow> P2')" by blast
 112.332 -  from gt_ex obtain z where z:"ord.max less_eq z1 z2 \<sqsubset> z" by blast
 112.333 -  from z have zz1: "z1 \<sqsubset> z" and zz2: "z2 \<sqsubset> z" by simp_all
 112.334 -  {fix x assume H: "z \<sqsubset> x"
 112.335 -    from less_trans[OF zz1 H] less_trans[OF zz2 H]
 112.336 -    have "(P1 x \<and> P2 x) \<longleftrightarrow> (P1' \<and> P2')"  using z1 zz1 z2 zz2 by auto
 112.337 -  }
 112.338 -  thus ?thesis by blast
 112.339 -qed
 112.340 -
 112.341 -lemma pinf_disj:
 112.342 -  assumes ex1: "\<exists>z1. \<forall>x. z1 \<sqsubset> x \<longrightarrow> (P1 x \<longleftrightarrow> P1')"
 112.343 -  and ex2: "\<exists>z2. \<forall>x. z2 \<sqsubset> x \<longrightarrow> (P2 x \<longleftrightarrow> P2')"
 112.344 -  shows "\<exists>z. \<forall>x. z \<sqsubset>  x \<longrightarrow> ((P1 x \<or> P2 x) \<longleftrightarrow> (P1' \<or> P2'))"
 112.345 -proof-
 112.346 -  from ex1 ex2 obtain z1 and z2 where z1: "\<forall>x. z1 \<sqsubset> x \<longrightarrow> (P1 x \<longleftrightarrow> P1')"
 112.347 -     and z2: "\<forall>x. z2 \<sqsubset> x \<longrightarrow> (P2 x \<longleftrightarrow> P2')" by blast
 112.348 -  from gt_ex obtain z where z:"ord.max less_eq z1 z2 \<sqsubset> z" by blast
 112.349 -  from z have zz1: "z1 \<sqsubset> z" and zz2: "z2 \<sqsubset> z" by simp_all
 112.350 -  {fix x assume H: "z \<sqsubset> x"
 112.351 -    from less_trans[OF zz1 H] less_trans[OF zz2 H]
 112.352 -    have "(P1 x \<or> P2 x) \<longleftrightarrow> (P1' \<or> P2')"  using z1 zz1 z2 zz2 by auto
 112.353 -  }
 112.354 -  thus ?thesis by blast
 112.355 -qed
 112.356 -
 112.357 -lemma pinf_ex: assumes ex:"\<exists>z. \<forall>x. z \<sqsubset> x \<longrightarrow> (P x \<longleftrightarrow> P1)" and p1: P1 shows "\<exists> x. P x"
 112.358 -proof-
 112.359 -  from ex obtain z where z: "\<forall>x. z \<sqsubset> x \<longrightarrow> (P x \<longleftrightarrow> P1)" by blast
 112.360 -  from gt_ex obtain x where x: "z \<sqsubset> x" by blast
 112.361 -  from z x p1 show ?thesis by blast
 112.362 -qed
 112.363 -
 112.364 -end
 112.365 -
 112.366 -text {* Linear order without upper bounds *}
 112.367 -
 112.368 -class_locale linorder_no_lb = linorder_stupid_syntax +
 112.369 -  assumes lt_ex: "\<exists>y. less y x"
 112.370 -begin
 112.371 -lemma le_ex: "\<exists>y. y \<sqsubseteq> x" using lt_ex by auto
 112.372 -
 112.373 -
 112.374 -text {* Theorems for @{text "\<exists>z. \<forall>x. x \<sqsubset> z \<longrightarrow> (P x \<longleftrightarrow> P\<^bsub>-\<infinity>\<^esub>)"} *}
 112.375 -lemma minf_conj:
 112.376 -  assumes ex1: "\<exists>z1. \<forall>x. x \<sqsubset> z1 \<longrightarrow> (P1 x \<longleftrightarrow> P1')"
 112.377 -  and ex2: "\<exists>z2. \<forall>x. x \<sqsubset> z2 \<longrightarrow> (P2 x \<longleftrightarrow> P2')"
 112.378 -  shows "\<exists>z. \<forall>x. x \<sqsubset>  z \<longrightarrow> ((P1 x \<and> P2 x) \<longleftrightarrow> (P1' \<and> P2'))"
 112.379 -proof-
 112.380 -  from ex1 ex2 obtain z1 and z2 where z1: "\<forall>x. x \<sqsubset> z1 \<longrightarrow> (P1 x \<longleftrightarrow> P1')"and z2: "\<forall>x. x \<sqsubset> z2 \<longrightarrow> (P2 x \<longleftrightarrow> P2')" by blast
 112.381 -  from lt_ex obtain z where z:"z \<sqsubset> ord.min less_eq z1 z2" by blast
 112.382 -  from z have zz1: "z \<sqsubset> z1" and zz2: "z \<sqsubset> z2" by simp_all
 112.383 -  {fix x assume H: "x \<sqsubset> z"
 112.384 -    from less_trans[OF H zz1] less_trans[OF H zz2]
 112.385 -    have "(P1 x \<and> P2 x) \<longleftrightarrow> (P1' \<and> P2')"  using z1 zz1 z2 zz2 by auto
 112.386 -  }
 112.387 -  thus ?thesis by blast
 112.388 -qed
 112.389 -
 112.390 -lemma minf_disj:
 112.391 -  assumes ex1: "\<exists>z1. \<forall>x. x \<sqsubset> z1 \<longrightarrow> (P1 x \<longleftrightarrow> P1')"
 112.392 -  and ex2: "\<exists>z2. \<forall>x. x \<sqsubset> z2 \<longrightarrow> (P2 x \<longleftrightarrow> P2')"
 112.393 -  shows "\<exists>z. \<forall>x. x \<sqsubset>  z \<longrightarrow> ((P1 x \<or> P2 x) \<longleftrightarrow> (P1' \<or> P2'))"
 112.394 -proof-
 112.395 -  from ex1 ex2 obtain z1 and z2 where z1: "\<forall>x. x \<sqsubset> z1 \<longrightarrow> (P1 x \<longleftrightarrow> P1')"and z2: "\<forall>x. x \<sqsubset> z2 \<longrightarrow> (P2 x \<longleftrightarrow> P2')" by blast
 112.396 -  from lt_ex obtain z where z:"z \<sqsubset> ord.min less_eq z1 z2" by blast
 112.397 -  from z have zz1: "z \<sqsubset> z1" and zz2: "z \<sqsubset> z2" by simp_all
 112.398 -  {fix x assume H: "x \<sqsubset> z"
 112.399 -    from less_trans[OF H zz1] less_trans[OF H zz2]
 112.400 -    have "(P1 x \<or> P2 x) \<longleftrightarrow> (P1' \<or> P2')"  using z1 zz1 z2 zz2 by auto
 112.401 -  }
 112.402 -  thus ?thesis by blast
 112.403 -qed
 112.404 -
 112.405 -lemma minf_ex: assumes ex:"\<exists>z. \<forall>x. x \<sqsubset> z \<longrightarrow> (P x \<longleftrightarrow> P1)" and p1: P1 shows "\<exists> x. P x"
 112.406 -proof-
 112.407 -  from ex obtain z where z: "\<forall>x. x \<sqsubset> z \<longrightarrow> (P x \<longleftrightarrow> P1)" by blast
 112.408 -  from lt_ex obtain x where x: "x \<sqsubset> z" by blast
 112.409 -  from z x p1 show ?thesis by blast
 112.410 -qed
 112.411 -
 112.412 -end
 112.413 -
 112.414 -
 112.415 -class_locale constr_dense_linear_order = linorder_no_lb + linorder_no_ub +
 112.416 -  fixes between
 112.417 -  assumes between_less: "less x y \<Longrightarrow> less x (between x y) \<and> less (between x y) y"
 112.418 -     and  between_same: "between x x = x"
 112.419 -
 112.420 -class_interpretation  constr_dense_linear_order < dense_linear_order 
 112.421 -  apply unfold_locales
 112.422 -  using gt_ex lt_ex between_less
 112.423 -    by (auto, rule_tac x="between x y" in exI, simp)
 112.424 -
 112.425 -context  constr_dense_linear_order
 112.426 -begin
 112.427 -
 112.428 -lemma rinf_U:
 112.429 -  assumes fU: "finite U"
 112.430 -  and lin_dense: "\<forall>x l u. (\<forall> t. l \<sqsubset> t \<and> t\<sqsubset> u \<longrightarrow> t \<notin> U) \<and> l\<sqsubset> x \<and> x \<sqsubset> u \<and> P x
 112.431 -  \<longrightarrow> (\<forall> y. l \<sqsubset> y \<and> y \<sqsubset> u \<longrightarrow> P y )"
 112.432 -  and nmpiU: "\<forall>x. \<not> MP \<and> \<not>PP \<and> P x \<longrightarrow> (\<exists> u\<in> U. \<exists> u' \<in> U. u \<sqsubseteq> x \<and> x \<sqsubseteq> u')"
 112.433 -  and nmi: "\<not> MP"  and npi: "\<not> PP"  and ex: "\<exists> x.  P x"
 112.434 -  shows "\<exists> u\<in> U. \<exists> u' \<in> U. P (between u u')"
 112.435 -proof-
 112.436 -  from ex obtain x where px: "P x" by blast
 112.437 -  from px nmi npi nmpiU have "\<exists> u\<in> U. \<exists> u' \<in> U. u \<sqsubseteq> x \<and> x \<sqsubseteq> u'" by auto
 112.438 -  then obtain u and u' where uU:"u\<in> U" and uU': "u' \<in> U" and ux:"u \<sqsubseteq> x" and xu':"x \<sqsubseteq> u'" by auto
 112.439 -  from uU have Une: "U \<noteq> {}" by auto
 112.440 -  term "linorder.Min less_eq"
 112.441 -  let ?l = "linorder.Min less_eq U"
 112.442 -  let ?u = "linorder.Max less_eq U"
 112.443 -  have linM: "?l \<in> U" using fU Une by simp
 112.444 -  have uinM: "?u \<in> U" using fU Une by simp
 112.445 -  have lM: "\<forall> t\<in> U. ?l \<sqsubseteq> t" using Une fU by auto
 112.446 -  have Mu: "\<forall> t\<in> U. t \<sqsubseteq> ?u" using Une fU by auto
 112.447 -  have th:"?l \<sqsubseteq> u" using uU Une lM by auto
 112.448 -  from order_trans[OF th ux] have lx: "?l \<sqsubseteq> x" .
 112.449 -  have th: "u' \<sqsubseteq> ?u" using uU' Une Mu by simp
 112.450 -  from order_trans[OF xu' th] have xu: "x \<sqsubseteq> ?u" .
 112.451 -  from finite_set_intervals2[where P="P",OF px lx xu linM uinM fU lM Mu]
 112.452 -  have "(\<exists> s\<in> U. P s) \<or>
 112.453 -      (\<exists> t1\<in> U. \<exists> t2 \<in> U. (\<forall> y. t1 \<sqsubset> y \<and> y \<sqsubset> t2 \<longrightarrow> y \<notin> U) \<and> t1 \<sqsubset> x \<and> x \<sqsubset> t2 \<and> P x)" .
 112.454 -  moreover { fix u assume um: "u\<in>U" and pu: "P u"
 112.455 -    have "between u u = u" by (simp add: between_same)
 112.456 -    with um pu have "P (between u u)" by simp
 112.457 -    with um have ?thesis by blast}
 112.458 -  moreover{
 112.459 -    assume "\<exists> t1\<in> U. \<exists> t2 \<in> U. (\<forall> y. t1 \<sqsubset> y \<and> y \<sqsubset> t2 \<longrightarrow> y \<notin> U) \<and> t1 \<sqsubset> x \<and> x \<sqsubset> t2 \<and> P x"
 112.460 -      then obtain t1 and t2 where t1M: "t1 \<in> U" and t2M: "t2\<in> U"
 112.461 -        and noM: "\<forall> y. t1 \<sqsubset> y \<and> y \<sqsubset> t2 \<longrightarrow> y \<notin> U" and t1x: "t1 \<sqsubset> x" and xt2: "x \<sqsubset> t2" and px: "P x"
 112.462 -        by blast
 112.463 -      from less_trans[OF t1x xt2] have t1t2: "t1 \<sqsubset> t2" .
 112.464 -      let ?u = "between t1 t2"
 112.465 -      from between_less t1t2 have t1lu: "t1 \<sqsubset> ?u" and ut2: "?u \<sqsubset> t2" by auto
 112.466 -      from lin_dense noM t1x xt2 px t1lu ut2 have "P ?u" by blast
 112.467 -      with t1M t2M have ?thesis by blast}
 112.468 -    ultimately show ?thesis by blast
 112.469 -  qed
 112.470 -
 112.471 -theorem fr_eq:
 112.472 -  assumes fU: "finite U"
 112.473 -  and lin_dense: "\<forall>x l u. (\<forall> t. l \<sqsubset> t \<and> t\<sqsubset> u \<longrightarrow> t \<notin> U) \<and> l\<sqsubset> x \<and> x \<sqsubset> u \<and> P x
 112.474 -   \<longrightarrow> (\<forall> y. l \<sqsubset> y \<and> y \<sqsubset> u \<longrightarrow> P y )"
 112.475 -  and nmibnd: "\<forall>x. \<not> MP \<and> P x \<longrightarrow> (\<exists> u\<in> U. u \<sqsubseteq> x)"
 112.476 -  and npibnd: "\<forall>x. \<not>PP \<and> P x \<longrightarrow> (\<exists> u\<in> U. x \<sqsubseteq> u)"
 112.477 -  and mi: "\<exists>z. \<forall>x. x \<sqsubset> z \<longrightarrow> (P x = MP)"  and pi: "\<exists>z. \<forall>x. z \<sqsubset> x \<longrightarrow> (P x = PP)"
 112.478 -  shows "(\<exists> x. P x) \<equiv> (MP \<or> PP \<or> (\<exists> u \<in> U. \<exists> u'\<in> U. P (between u u')))"
 112.479 -  (is "_ \<equiv> (_ \<or> _ \<or> ?F)" is "?E \<equiv> ?D")
 112.480 -proof-
 112.481 - {
 112.482 -   assume px: "\<exists> x. P x"
 112.483 -   have "MP \<or> PP \<or> (\<not> MP \<and> \<not> PP)" by blast
 112.484 -   moreover {assume "MP \<or> PP" hence "?D" by blast}
 112.485 -   moreover {assume nmi: "\<not> MP" and npi: "\<not> PP"
 112.486 -     from npmibnd[OF nmibnd npibnd]
 112.487 -     have nmpiU: "\<forall>x. \<not> MP \<and> \<not>PP \<and> P x \<longrightarrow> (\<exists> u\<in> U. \<exists> u' \<in> U. u \<sqsubseteq> x \<and> x \<sqsubseteq> u')" .
 112.488 -     from rinf_U[OF fU lin_dense nmpiU nmi npi px] have "?D" by blast}
 112.489 -   ultimately have "?D" by blast}
 112.490 - moreover
 112.491 - { assume "?D"
 112.492 -   moreover {assume m:"MP" from minf_ex[OF mi m] have "?E" .}
 112.493 -   moreover {assume p: "PP" from pinf_ex[OF pi p] have "?E" . }
 112.494 -   moreover {assume f:"?F" hence "?E" by blast}
 112.495 -   ultimately have "?E" by blast}
 112.496 - ultimately have "?E = ?D" by blast thus "?E \<equiv> ?D" by simp
 112.497 -qed
 112.498 -
 112.499 -lemmas minf_thms = minf_conj minf_disj minf_eq minf_neq minf_lt minf_le minf_gt minf_ge minf_P
 112.500 -lemmas pinf_thms = pinf_conj pinf_disj pinf_eq pinf_neq pinf_lt pinf_le pinf_gt pinf_ge pinf_P
 112.501 -
 112.502 -lemmas nmi_thms = nmi_conj nmi_disj nmi_eq nmi_neq nmi_lt nmi_le nmi_gt nmi_ge nmi_P
 112.503 -lemmas npi_thms = npi_conj npi_disj npi_eq npi_neq npi_lt npi_le npi_gt npi_ge npi_P
 112.504 -lemmas lin_dense_thms = lin_dense_conj lin_dense_disj lin_dense_eq lin_dense_neq lin_dense_lt lin_dense_le lin_dense_gt lin_dense_ge lin_dense_P
 112.505 -
 112.506 -lemma ferrack_axiom: "constr_dense_linear_order less_eq less between"
 112.507 -  by (rule constr_dense_linear_order_axioms)
 112.508 -lemma atoms:
 112.509 -  shows "TERM (less :: 'a \<Rightarrow> _)"
 112.510 -    and "TERM (less_eq :: 'a \<Rightarrow> _)"
 112.511 -    and "TERM (op = :: 'a \<Rightarrow> _)" .
 112.512 -
 112.513 -declare ferrack_axiom [ferrack minf: minf_thms pinf: pinf_thms
 112.514 -    nmi: nmi_thms npi: npi_thms lindense:
 112.515 -    lin_dense_thms qe: fr_eq atoms: atoms]
 112.516 -
 112.517 -declaration {*
 112.518 -let
 112.519 -fun simps phi = map (Morphism.thm phi) [@{thm "not_less"}, @{thm "not_le"}]
 112.520 -fun generic_whatis phi =
 112.521 - let
 112.522 -  val [lt, le] = map (Morphism.term phi) [@{term "op \<sqsubset>"}, @{term "op \<sqsubseteq>"}]
 112.523 -  fun h x t =
 112.524 -   case term_of t of
 112.525 -     Const("op =", _)$y$z => if term_of x aconv y then Ferrante_Rackoff_Data.Eq
 112.526 -                            else Ferrante_Rackoff_Data.Nox
 112.527 -   | @{term "Not"}$(Const("op =", _)$y$z) => if term_of x aconv y then Ferrante_Rackoff_Data.NEq
 112.528 -                            else Ferrante_Rackoff_Data.Nox
 112.529 -   | b$y$z => if Term.could_unify (b, lt) then
 112.530 -                 if term_of x aconv y then Ferrante_Rackoff_Data.Lt
 112.531 -                 else if term_of x aconv z then Ferrante_Rackoff_Data.Gt
 112.532 -                 else Ferrante_Rackoff_Data.Nox
 112.533 -             else if Term.could_unify (b, le) then
 112.534 -                 if term_of x aconv y then Ferrante_Rackoff_Data.Le
 112.535 -                 else if term_of x aconv z then Ferrante_Rackoff_Data.Ge
 112.536 -                 else Ferrante_Rackoff_Data.Nox
 112.537 -             else Ferrante_Rackoff_Data.Nox
 112.538 -   | _ => Ferrante_Rackoff_Data.Nox
 112.539 - in h end
 112.540 - fun ss phi = HOL_ss addsimps (simps phi)
 112.541 -in
 112.542 - Ferrante_Rackoff_Data.funs  @{thm "ferrack_axiom"}
 112.543 -  {isolate_conv = K (K (K Thm.reflexive)), whatis = generic_whatis, simpset = ss}
 112.544 -end
 112.545 -*}
 112.546 -
 112.547 -end
 112.548 -
 112.549 -use "~~/src/HOL/Tools/Qelim/ferrante_rackoff.ML"
 112.550 -
 112.551 -method_setup ferrack = {*
 112.552 -  Method.ctxt_args (Method.SIMPLE_METHOD' o FerranteRackoff.dlo_tac)
 112.553 -*} "Ferrante and Rackoff's algorithm for quantifier elimination in dense linear orders"
 112.554 -
 112.555 -subsection {* Ferrante and Rackoff algorithm over ordered fields *}
 112.556 -
 112.557 -lemma neg_prod_lt:"(c\<Colon>'a\<Colon>ordered_field) < 0 \<Longrightarrow> ((c*x < 0) == (x > 0))"
 112.558 -proof-
 112.559 -  assume H: "c < 0"
 112.560 -  have "c*x < 0 = (0/c < x)" by (simp only: neg_divide_less_eq[OF H] ring_simps)
 112.561 -  also have "\<dots> = (0 < x)" by simp
 112.562 -  finally show  "(c*x < 0) == (x > 0)" by simp
 112.563 -qed
 112.564 -
 112.565 -lemma pos_prod_lt:"(c\<Colon>'a\<Colon>ordered_field) > 0 \<Longrightarrow> ((c*x < 0) == (x < 0))"
 112.566 -proof-
 112.567 -  assume H: "c > 0"
 112.568 -  hence "c*x < 0 = (0/c > x)" by (simp only: pos_less_divide_eq[OF H] ring_simps)
 112.569 -  also have "\<dots> = (0 > x)" by simp
 112.570 -  finally show  "(c*x < 0) == (x < 0)" by simp
 112.571 -qed
 112.572 -
 112.573 -lemma neg_prod_sum_lt: "(c\<Colon>'a\<Colon>ordered_field) < 0 \<Longrightarrow> ((c*x + t< 0) == (x > (- 1/c)*t))"
 112.574 -proof-
 112.575 -  assume H: "c < 0"
 112.576 -  have "c*x + t< 0 = (c*x < -t)" by (subst less_iff_diff_less_0 [of "c*x" "-t"], simp)
 112.577 -  also have "\<dots> = (-t/c < x)" by (simp only: neg_divide_less_eq[OF H] ring_simps)
 112.578 -  also have "\<dots> = ((- 1/c)*t < x)" by simp
 112.579 -  finally show  "(c*x + t < 0) == (x > (- 1/c)*t)" by simp
 112.580 -qed
 112.581 -
 112.582 -lemma pos_prod_sum_lt:"(c\<Colon>'a\<Colon>ordered_field) > 0 \<Longrightarrow> ((c*x + t < 0) == (x < (- 1/c)*t))"
 112.583 -proof-
 112.584 -  assume H: "c > 0"
 112.585 -  have "c*x + t< 0 = (c*x < -t)"  by (subst less_iff_diff_less_0 [of "c*x" "-t"], simp)
 112.586 -  also have "\<dots> = (-t/c > x)" by (simp only: pos_less_divide_eq[OF H] ring_simps)
 112.587 -  also have "\<dots> = ((- 1/c)*t > x)" by simp
 112.588 -  finally show  "(c*x + t < 0) == (x < (- 1/c)*t)" by simp
 112.589 -qed
 112.590 -
 112.591 -lemma sum_lt:"((x::'a::pordered_ab_group_add) + t < 0) == (x < - t)"
 112.592 -  using less_diff_eq[where a= x and b=t and c=0] by simp
 112.593 -
 112.594 -lemma neg_prod_le:"(c\<Colon>'a\<Colon>ordered_field) < 0 \<Longrightarrow> ((c*x <= 0) == (x >= 0))"
 112.595 -proof-
 112.596 -  assume H: "c < 0"
 112.597 -  have "c*x <= 0 = (0/c <= x)" by (simp only: neg_divide_le_eq[OF H] ring_simps)
 112.598 -  also have "\<dots> = (0 <= x)" by simp
 112.599 -  finally show  "(c*x <= 0) == (x >= 0)" by simp
 112.600 -qed
 112.601 -
 112.602 -lemma pos_prod_le:"(c\<Colon>'a\<Colon>ordered_field) > 0 \<Longrightarrow> ((c*x <= 0) == (x <= 0))"
 112.603 -proof-
 112.604 -  assume H: "c > 0"
 112.605 -  hence "c*x <= 0 = (0/c >= x)" by (simp only: pos_le_divide_eq[OF H] ring_simps)
 112.606 -  also have "\<dots> = (0 >= x)" by simp
 112.607 -  finally show  "(c*x <= 0) == (x <= 0)" by simp
 112.608 -qed
 112.609 -
 112.610 -lemma neg_prod_sum_le: "(c\<Colon>'a\<Colon>ordered_field) < 0 \<Longrightarrow> ((c*x + t <= 0) == (x >= (- 1/c)*t))"
 112.611 -proof-
 112.612 -  assume H: "c < 0"
 112.613 -  have "c*x + t <= 0 = (c*x <= -t)"  by (subst le_iff_diff_le_0 [of "c*x" "-t"], simp)
 112.614 -  also have "\<dots> = (-t/c <= x)" by (simp only: neg_divide_le_eq[OF H] ring_simps)
 112.615 -  also have "\<dots> = ((- 1/c)*t <= x)" by simp
 112.616 -  finally show  "(c*x + t <= 0) == (x >= (- 1/c)*t)" by simp
 112.617 -qed
 112.618 -
 112.619 -lemma pos_prod_sum_le:"(c\<Colon>'a\<Colon>ordered_field) > 0 \<Longrightarrow> ((c*x + t <= 0) == (x <= (- 1/c)*t))"
 112.620 -proof-
 112.621 -  assume H: "c > 0"
 112.622 -  have "c*x + t <= 0 = (c*x <= -t)" by (subst le_iff_diff_le_0 [of "c*x" "-t"], simp)
 112.623 -  also have "\<dots> = (-t/c >= x)" by (simp only: pos_le_divide_eq[OF H] ring_simps)
 112.624 -  also have "\<dots> = ((- 1/c)*t >= x)" by simp
 112.625 -  finally show  "(c*x + t <= 0) == (x <= (- 1/c)*t)" by simp
 112.626 -qed
 112.627 -
 112.628 -lemma sum_le:"((x::'a::pordered_ab_group_add) + t <= 0) == (x <= - t)"
 112.629 -  using le_diff_eq[where a= x and b=t and c=0] by simp
 112.630 -
 112.631 -lemma nz_prod_eq:"(c\<Colon>'a\<Colon>ordered_field) \<noteq> 0 \<Longrightarrow> ((c*x = 0) == (x = 0))" by simp
 112.632 -lemma nz_prod_sum_eq: "(c\<Colon>'a\<Colon>ordered_field) \<noteq> 0 \<Longrightarrow> ((c*x + t = 0) == (x = (- 1/c)*t))"
 112.633 -proof-
 112.634 -  assume H: "c \<noteq> 0"
 112.635 -  have "c*x + t = 0 = (c*x = -t)" by (subst eq_iff_diff_eq_0 [of "c*x" "-t"], simp)
 112.636 -  also have "\<dots> = (x = -t/c)" by (simp only: nonzero_eq_divide_eq[OF H] ring_simps)
 112.637 -  finally show  "(c*x + t = 0) == (x = (- 1/c)*t)" by simp
 112.638 -qed
 112.639 -lemma sum_eq:"((x::'a::pordered_ab_group_add) + t = 0) == (x = - t)"
 112.640 -  using eq_diff_eq[where a= x and b=t and c=0] by simp
 112.641 -
 112.642 -
 112.643 -class_interpretation class_ordered_field_dense_linear_order: constr_dense_linear_order
 112.644 - ["op <=" "op <"
 112.645 -   "\<lambda> x y. 1/2 * ((x::'a::{ordered_field,recpower,number_ring}) + y)"]
 112.646 -proof (unfold_locales, dlo, dlo, auto)
 112.647 -  fix x y::'a assume lt: "x < y"
 112.648 -  from  less_half_sum[OF lt] show "x < (x + y) /2" by simp
 112.649 -next
 112.650 -  fix x y::'a assume lt: "x < y"
 112.651 -  from  gt_half_sum[OF lt] show "(x + y) /2 < y" by simp
 112.652 -qed
 112.653 -
 112.654 -declaration{*
 112.655 -let
 112.656 -fun earlier [] x y = false
 112.657 -        | earlier (h::t) x y =
 112.658 -    if h aconvc y then false else if h aconvc x then true else earlier t x y;
 112.659 -
 112.660 -fun dest_frac ct = case term_of ct of
 112.661 -   Const (@{const_name "HOL.divide"},_) $ a $ b=>
 112.662 -    Rat.rat_of_quotient (snd (HOLogic.dest_number a), snd (HOLogic.dest_number b))
 112.663 - | t => Rat.rat_of_int (snd (HOLogic.dest_number t))
 112.664 -
 112.665 -fun mk_frac phi cT x =
 112.666 - let val (a, b) = Rat.quotient_of_rat x
 112.667 - in if b = 1 then Numeral.mk_cnumber cT a
 112.668 -    else Thm.capply
 112.669 -         (Thm.capply (Drule.cterm_rule (instantiate' [SOME cT] []) @{cpat "op /"})
 112.670 -                     (Numeral.mk_cnumber cT a))
 112.671 -         (Numeral.mk_cnumber cT b)
 112.672 - end
 112.673 -
 112.674 -fun whatis x ct = case term_of ct of
 112.675 -  Const(@{const_name "HOL.plus"}, _)$(Const(@{const_name "HOL.times"},_)$_$y)$_ =>
 112.676 -     if y aconv term_of x then ("c*x+t",[(funpow 2 Thm.dest_arg1) ct, Thm.dest_arg ct])
 112.677 -     else ("Nox",[])
 112.678 -| Const(@{const_name "HOL.plus"}, _)$y$_ =>
 112.679 -     if y aconv term_of x then ("x+t",[Thm.dest_arg ct])
 112.680 -     else ("Nox",[])
 112.681 -| Const(@{const_name "HOL.times"}, _)$_$y =>
 112.682 -     if y aconv term_of x then ("c*x",[Thm.dest_arg1 ct])
 112.683 -     else ("Nox",[])
 112.684 -| t => if t aconv term_of x then ("x",[]) else ("Nox",[]);
 112.685 -
 112.686 -fun xnormalize_conv ctxt [] ct = reflexive ct
 112.687 -| xnormalize_conv ctxt (vs as (x::_)) ct =
 112.688 -   case term_of ct of
 112.689 -   Const(@{const_name HOL.less},_)$_$Const(@{const_name "HOL.zero"},_) =>
 112.690 -    (case whatis x (Thm.dest_arg1 ct) of
 112.691 -    ("c*x+t",[c,t]) =>
 112.692 -       let
 112.693 -        val cr = dest_frac c
 112.694 -        val clt = Thm.dest_fun2 ct
 112.695 -        val cz = Thm.dest_arg ct
 112.696 -        val neg = cr </ Rat.zero
 112.697 -        val cthp = Simplifier.rewrite (local_simpset_of ctxt)
 112.698 -               (Thm.capply @{cterm "Trueprop"}
 112.699 -                  (if neg then Thm.capply (Thm.capply clt c) cz
 112.700 -                    else Thm.capply (Thm.capply clt cz) c))
 112.701 -        val cth = equal_elim (symmetric cthp) TrueI
 112.702 -        val th = implies_elim (instantiate' [SOME (ctyp_of_term x)] (map SOME [c,x,t])
 112.703 -             (if neg then @{thm neg_prod_sum_lt} else @{thm pos_prod_sum_lt})) cth
 112.704 -        val rth = Conv.fconv_rule (Conv.arg_conv (Conv.binop_conv
 112.705 -                   (Normalizer.semiring_normalize_ord_conv ctxt (earlier vs)))) th
 112.706 -      in rth end
 112.707 -    | ("x+t",[t]) =>
 112.708 -       let
 112.709 -        val T = ctyp_of_term x
 112.710 -        val th = instantiate' [SOME T] [SOME x, SOME t] @{thm "sum_lt"}
 112.711 -        val rth = Conv.fconv_rule (Conv.arg_conv (Conv.binop_conv
 112.712 -              (Normalizer.semiring_normalize_ord_conv ctxt (earlier vs)))) th
 112.713 -       in  rth end
 112.714 -    | ("c*x",[c]) =>
 112.715 -       let
 112.716 -        val cr = dest_frac c
 112.717 -        val clt = Thm.dest_fun2 ct
 112.718 -        val cz = Thm.dest_arg ct
 112.719 -        val neg = cr </ Rat.zero
 112.720 -        val cthp = Simplifier.rewrite (local_simpset_of ctxt)
 112.721 -               (Thm.capply @{cterm "Trueprop"}
 112.722 -                  (if neg then Thm.capply (Thm.capply clt c) cz
 112.723 -                    else Thm.capply (Thm.capply clt cz) c))
 112.724 -        val cth = equal_elim (symmetric cthp) TrueI
 112.725 -        val th = implies_elim (instantiate' [SOME (ctyp_of_term x)] (map SOME [c,x])
 112.726 -             (if neg then @{thm neg_prod_lt} else @{thm pos_prod_lt})) cth
 112.727 -        val rth = th
 112.728 -      in rth end
 112.729 -    | _ => reflexive ct)
 112.730 -
 112.731 -
 112.732 -|  Const(@{const_name HOL.less_eq},_)$_$Const(@{const_name "HOL.zero"},_) =>
 112.733 -   (case whatis x (Thm.dest_arg1 ct) of
 112.734 -    ("c*x+t",[c,t]) =>
 112.735 -       let
 112.736 -        val T = ctyp_of_term x
 112.737 -        val cr = dest_frac c
 112.738 -        val clt = Drule.cterm_rule (instantiate' [SOME T] []) @{cpat "op <"}
 112.739 -        val cz = Thm.dest_arg ct
 112.740 -        val neg = cr </ Rat.zero
 112.741 -        val cthp = Simplifier.rewrite (local_simpset_of ctxt)
 112.742 -               (Thm.capply @{cterm "Trueprop"}
 112.743 -                  (if neg then Thm.capply (Thm.capply clt c) cz
 112.744 -                    else Thm.capply (Thm.capply clt cz) c))
 112.745 -        val cth = equal_elim (symmetric cthp) TrueI
 112.746 -        val th = implies_elim (instantiate' [SOME T] (map SOME [c,x,t])
 112.747 -             (if neg then @{thm neg_prod_sum_le} else @{thm pos_prod_sum_le})) cth
 112.748 -        val rth = Conv.fconv_rule (Conv.arg_conv (Conv.binop_conv
 112.749 -                   (Normalizer.semiring_normalize_ord_conv ctxt (earlier vs)))) th
 112.750 -      in rth end
 112.751 -    | ("x+t",[t]) =>
 112.752 -       let
 112.753 -        val T = ctyp_of_term x
 112.754 -        val th = instantiate' [SOME T] [SOME x, SOME t] @{thm "sum_le"}
 112.755 -        val rth = Conv.fconv_rule (Conv.arg_conv (Conv.binop_conv
 112.756 -              (Normalizer.semiring_normalize_ord_conv ctxt (earlier vs)))) th
 112.757 -       in  rth end
 112.758 -    | ("c*x",[c]) =>
 112.759 -       let
 112.760 -        val T = ctyp_of_term x
 112.761 -        val cr = dest_frac c
 112.762 -        val clt = Drule.cterm_rule (instantiate' [SOME T] []) @{cpat "op <"}
 112.763 -        val cz = Thm.dest_arg ct
 112.764 -        val neg = cr </ Rat.zero
 112.765 -        val cthp = Simplifier.rewrite (local_simpset_of ctxt)
 112.766 -               (Thm.capply @{cterm "Trueprop"}
 112.767 -                  (if neg then Thm.capply (Thm.capply clt c) cz
 112.768 -                    else Thm.capply (Thm.capply clt cz) c))
 112.769 -        val cth = equal_elim (symmetric cthp) TrueI
 112.770 -        val th = implies_elim (instantiate' [SOME (ctyp_of_term x)] (map SOME [c,x])
 112.771 -             (if neg then @{thm neg_prod_le} else @{thm pos_prod_le})) cth
 112.772 -        val rth = th
 112.773 -      in rth end
 112.774 -    | _ => reflexive ct)
 112.775 -
 112.776 -|  Const("op =",_)$_$Const(@{const_name "HOL.zero"},_) =>
 112.777 -   (case whatis x (Thm.dest_arg1 ct) of
 112.778 -    ("c*x+t",[c,t]) =>
 112.779 -       let
 112.780 -        val T = ctyp_of_term x
 112.781 -        val cr = dest_frac c
 112.782 -        val ceq = Thm.dest_fun2 ct
 112.783 -        val cz = Thm.dest_arg ct
 112.784 -        val cthp = Simplifier.rewrite (local_simpset_of ctxt)
 112.785 -            (Thm.capply @{cterm "Trueprop"}
 112.786 -             (Thm.capply @{cterm "Not"} (Thm.capply (Thm.capply ceq c) cz)))
 112.787 -        val cth = equal_elim (symmetric cthp) TrueI
 112.788 -        val th = implies_elim
 112.789 -                 (instantiate' [SOME T] (map SOME [c,x,t]) @{thm nz_prod_sum_eq}) cth
 112.790 -        val rth = Conv.fconv_rule (Conv.arg_conv (Conv.binop_conv
 112.791 -                   (Normalizer.semiring_normalize_ord_conv ctxt (earlier vs)))) th
 112.792 -      in rth end
 112.793 -    | ("x+t",[t]) =>
 112.794 -       let
 112.795 -        val T = ctyp_of_term x
 112.796 -        val th = instantiate' [SOME T] [SOME x, SOME t] @{thm "sum_eq"}
 112.797 -        val rth = Conv.fconv_rule (Conv.arg_conv (Conv.binop_conv
 112.798 -              (Normalizer.semiring_normalize_ord_conv ctxt (earlier vs)))) th
 112.799 -       in  rth end
 112.800 -    | ("c*x",[c]) =>
 112.801 -       let
 112.802 -        val T = ctyp_of_term x
 112.803 -        val cr = dest_frac c
 112.804 -        val ceq = Thm.dest_fun2 ct
 112.805 -        val cz = Thm.dest_arg ct
 112.806 -        val cthp = Simplifier.rewrite (local_simpset_of ctxt)
 112.807 -            (Thm.capply @{cterm "Trueprop"}
 112.808 -             (Thm.capply @{cterm "Not"} (Thm.capply (Thm.capply ceq c) cz)))
 112.809 -        val cth = equal_elim (symmetric cthp) TrueI
 112.810 -        val rth = implies_elim
 112.811 -                 (instantiate' [SOME T] (map SOME [c,x]) @{thm nz_prod_eq}) cth
 112.812 -      in rth end
 112.813 -    | _ => reflexive ct);
 112.814 -
 112.815 -local
 112.816 -  val less_iff_diff_less_0 = mk_meta_eq @{thm "less_iff_diff_less_0"}
 112.817 -  val le_iff_diff_le_0 = mk_meta_eq @{thm "le_iff_diff_le_0"}
 112.818 -  val eq_iff_diff_eq_0 = mk_meta_eq @{thm "eq_iff_diff_eq_0"}
 112.819 -in
 112.820 -fun field_isolate_conv phi ctxt vs ct = case term_of ct of
 112.821 -  Const(@{const_name HOL.less},_)$a$b =>
 112.822 -   let val (ca,cb) = Thm.dest_binop ct
 112.823 -       val T = ctyp_of_term ca
 112.824 -       val th = instantiate' [SOME T] [SOME ca, SOME cb] less_iff_diff_less_0
 112.825 -       val nth = Conv.fconv_rule
 112.826 -         (Conv.arg_conv (Conv.arg1_conv
 112.827 -              (Normalizer.semiring_normalize_ord_conv @{context} (earlier vs)))) th
 112.828 -       val rth = transitive nth (xnormalize_conv ctxt vs (Thm.rhs_of nth))
 112.829 -   in rth end
 112.830 -| Const(@{const_name HOL.less_eq},_)$a$b =>
 112.831 -   let val (ca,cb) = Thm.dest_binop ct
 112.832 -       val T = ctyp_of_term ca
 112.833 -       val th = instantiate' [SOME T] [SOME ca, SOME cb] le_iff_diff_le_0
 112.834 -       val nth = Conv.fconv_rule
 112.835 -         (Conv.arg_conv (Conv.arg1_conv
 112.836 -              (Normalizer.semiring_normalize_ord_conv @{context} (earlier vs)))) th
 112.837 -       val rth = transitive nth (xnormalize_conv ctxt vs (Thm.rhs_of nth))
 112.838 -   in rth end
 112.839 -
 112.840 -| Const("op =",_)$a$b =>
 112.841 -   let val (ca,cb) = Thm.dest_binop ct
 112.842 -       val T = ctyp_of_term ca
 112.843 -       val th = instantiate' [SOME T] [SOME ca, SOME cb] eq_iff_diff_eq_0
 112.844 -       val nth = Conv.fconv_rule
 112.845 -         (Conv.arg_conv (Conv.arg1_conv
 112.846 -              (Normalizer.semiring_normalize_ord_conv @{context} (earlier vs)))) th
 112.847 -       val rth = transitive nth (xnormalize_conv ctxt vs (Thm.rhs_of nth))
 112.848 -   in rth end
 112.849 -| @{term "Not"} $(Const("op =",_)$a$b) => Conv.arg_conv (field_isolate_conv phi ctxt vs) ct
 112.850 -| _ => reflexive ct
 112.851 -end;
 112.852 -
 112.853 -fun classfield_whatis phi =
 112.854 - let
 112.855 -  fun h x t =
 112.856 -   case term_of t of
 112.857 -     Const("op =", _)$y$z => if term_of x aconv y then Ferrante_Rackoff_Data.Eq
 112.858 -                            else Ferrante_Rackoff_Data.Nox
 112.859 -   | @{term "Not"}$(Const("op =", _)$y$z) => if term_of x aconv y then Ferrante_Rackoff_Data.NEq
 112.860 -                            else Ferrante_Rackoff_Data.Nox
 112.861 -   | Const(@{const_name HOL.less},_)$y$z =>
 112.862 -       if term_of x aconv y then Ferrante_Rackoff_Data.Lt
 112.863 -        else if term_of x aconv z then Ferrante_Rackoff_Data.Gt
 112.864 -        else Ferrante_Rackoff_Data.Nox
 112.865 -   | Const (@{const_name HOL.less_eq},_)$y$z =>
 112.866 -         if term_of x aconv y then Ferrante_Rackoff_Data.Le
 112.867 -         else if term_of x aconv z then Ferrante_Rackoff_Data.Ge
 112.868 -         else Ferrante_Rackoff_Data.Nox
 112.869 -   | _ => Ferrante_Rackoff_Data.Nox
 112.870 - in h end;
 112.871 -fun class_field_ss phi =
 112.872 -   HOL_basic_ss addsimps ([@{thm "linorder_not_less"}, @{thm "linorder_not_le"}])
 112.873 -   addsplits [@{thm "abs_split"},@{thm "split_max"}, @{thm "split_min"}]
 112.874 -
 112.875 -in
 112.876 -Ferrante_Rackoff_Data.funs @{thm "class_ordered_field_dense_linear_order.ferrack_axiom"}
 112.877 -  {isolate_conv = field_isolate_conv, whatis = classfield_whatis, simpset = class_field_ss}
 112.878 -end
 112.879 -*}
 112.880 -
 112.881 -
 112.882 -end 
   113.1 --- a/src/HOL/Library/Executable_Set.thy	Tue Dec 30 08:18:54 2008 +0100
   113.2 +++ b/src/HOL/Library/Executable_Set.thy	Tue Dec 30 11:10:01 2008 +0100
   113.3 @@ -28,6 +28,10 @@
   113.4  lemma [code]: "eq_set A B \<longleftrightarrow> A \<subseteq> B \<and> B \<subseteq> A"
   113.5    unfolding eq_set_def by auto
   113.6  
   113.7 +(* FIXME allow for Stefan's code generator:
   113.8 +declare set_eq_subset[code unfold]
   113.9 +*)
  113.10 +
  113.11  lemma [code]:
  113.12    "a \<in> A \<longleftrightarrow> (\<exists>x\<in>A. x = a)"
  113.13    unfolding bex_triv_one_point1 ..
  113.14 @@ -35,6 +39,8 @@
  113.15  definition filter_set :: "('a \<Rightarrow> bool) \<Rightarrow> 'a set \<Rightarrow> 'a set" where
  113.16    "filter_set P xs = {x\<in>xs. P x}"
  113.17  
  113.18 +declare filter_set_def[symmetric, code unfold] 
  113.19 +
  113.20  
  113.21  subsection {* Operations on lists *}
  113.22  
  113.23 @@ -269,5 +275,6 @@
  113.24    Ball ("{*Blall*}")
  113.25    Bex ("{*Blex*}")
  113.26    filter_set ("{*filter*}")
  113.27 +  fold ("{* foldl o flip *}")
  113.28  
  113.29  end
   114.1 --- a/src/HOL/Library/Library.thy	Tue Dec 30 08:18:54 2008 +0100
   114.2 +++ b/src/HOL/Library/Library.thy	Tue Dec 30 11:10:01 2008 +0100
   114.3 @@ -16,7 +16,6 @@
   114.4    Continuity
   114.5    ContNotDenum
   114.6    Countable
   114.7 -  Dense_Linear_Order
   114.8    Efficient_Nat
   114.9    Enum
  114.10    Eval_Witness
   115.1 --- a/src/HOL/Library/Multiset.thy	Tue Dec 30 08:18:54 2008 +0100
   115.2 +++ b/src/HOL/Library/Multiset.thy	Tue Dec 30 11:10:01 2008 +0100
   115.3 @@ -1481,4 +1481,155 @@
   115.4    @{term "{#x+x|x:#M. x<c#}"}.
   115.5  *}
   115.6  
   115.7 +
   115.8 +subsection {* Termination proofs with multiset orders *}
   115.9 +
  115.10 +lemma multi_member_skip: "x \<in># XS \<Longrightarrow> x \<in># {# y #} + XS"
  115.11 +  and multi_member_this: "x \<in># {# x #} + XS"
  115.12 +  and multi_member_last: "x \<in># {# x #}"
  115.13 +  by auto
  115.14 +
  115.15 +definition "ms_strict = mult pair_less"
  115.16 +definition "ms_weak = ms_strict \<union> Id"
  115.17 +
  115.18 +lemma ms_reduction_pair: "reduction_pair (ms_strict, ms_weak)"
  115.19 +unfolding reduction_pair_def ms_strict_def ms_weak_def pair_less_def
  115.20 +by (auto intro: wf_mult1 wf_trancl simp: mult_def)
  115.21 +
  115.22 +lemma smsI:
  115.23 +  "(set_of A, set_of B) \<in> max_strict \<Longrightarrow> (Z + A, Z + B) \<in> ms_strict"
  115.24 +  unfolding ms_strict_def
  115.25 +by (rule one_step_implies_mult) (auto simp add: max_strict_def pair_less_def elim!:max_ext.cases)
  115.26 +
  115.27 +lemma wmsI:
  115.28 +  "(set_of A, set_of B) \<in> max_strict \<or> A = {#} \<and> B = {#}
  115.29 +  \<Longrightarrow> (Z + A, Z + B) \<in> ms_weak"
  115.30 +unfolding ms_weak_def ms_strict_def
  115.31 +by (auto simp add: pair_less_def max_strict_def elim!:max_ext.cases intro: one_step_implies_mult)
  115.32 +
  115.33 +inductive pw_leq
  115.34 +where
  115.35 +  pw_leq_empty: "pw_leq {#} {#}"
  115.36 +| pw_leq_step:  "\<lbrakk>(x,y) \<in> pair_leq; pw_leq X Y \<rbrakk> \<Longrightarrow> pw_leq ({#x#} + X) ({#y#} + Y)"
  115.37 +
  115.38 +lemma pw_leq_lstep:
  115.39 +  "(x, y) \<in> pair_leq \<Longrightarrow> pw_leq {#x#} {#y#}"
  115.40 +by (drule pw_leq_step) (rule pw_leq_empty, simp)
  115.41 +
  115.42 +lemma pw_leq_split:
  115.43 +  assumes "pw_leq X Y"
  115.44 +  shows "\<exists>A B Z. X = A + Z \<and> Y = B + Z \<and> ((set_of A, set_of B) \<in> max_strict \<or> (B = {#} \<and> A = {#}))"
  115.45 +  using assms
  115.46 +proof (induct)
  115.47 +  case pw_leq_empty thus ?case by auto
  115.48 +next
  115.49 +  case (pw_leq_step x y X Y)
  115.50 +  then obtain A B Z where
  115.51 +    [simp]: "X = A + Z" "Y = B + Z" 
  115.52 +      and 1[simp]: "(set_of A, set_of B) \<in> max_strict \<or> (B = {#} \<and> A = {#})" 
  115.53 +    by auto
  115.54 +  from pw_leq_step have "x = y \<or> (x, y) \<in> pair_less" 
  115.55 +    unfolding pair_leq_def by auto
  115.56 +  thus ?case
  115.57 +  proof
  115.58 +    assume [simp]: "x = y"
  115.59 +    have
  115.60 +      "{#x#} + X = A + ({#y#}+Z) 
  115.61 +      \<and> {#y#} + Y = B + ({#y#}+Z)
  115.62 +      \<and> ((set_of A, set_of B) \<in> max_strict \<or> (B = {#} \<and> A = {#}))"
  115.63 +      by (auto simp: add_ac)
  115.64 +    thus ?case by (intro exI)
  115.65 +  next
  115.66 +    assume A: "(x, y) \<in> pair_less"
  115.67 +    let ?A' = "{#x#} + A" and ?B' = "{#y#} + B"
  115.68 +    have "{#x#} + X = ?A' + Z"
  115.69 +      "{#y#} + Y = ?B' + Z"
  115.70 +      by (auto simp add: add_ac)
  115.71 +    moreover have 
  115.72 +      "(set_of ?A', set_of ?B') \<in> max_strict"
  115.73 +      using 1 A unfolding max_strict_def 
  115.74 +      by (auto elim!: max_ext.cases)
  115.75 +    ultimately show ?thesis by blast
  115.76 +  qed
  115.77 +qed
  115.78 +
  115.79 +lemma 
  115.80 +  assumes pwleq: "pw_leq Z Z'"
  115.81 +  shows ms_strictI: "(set_of A, set_of B) \<in> max_strict \<Longrightarrow> (Z + A, Z' + B) \<in> ms_strict"
  115.82 +  and   ms_weakI1:  "(set_of A, set_of B) \<in> max_strict \<Longrightarrow> (Z + A, Z' + B) \<in> ms_weak"
  115.83 +  and   ms_weakI2:  "(Z + {#}, Z' + {#}) \<in> ms_weak"
  115.84 +proof -
  115.85 +  from pw_leq_split[OF pwleq] 
  115.86 +  obtain A' B' Z''
  115.87 +    where [simp]: "Z = A' + Z''" "Z' = B' + Z''"
  115.88 +    and mx_or_empty: "(set_of A', set_of B') \<in> max_strict \<or> (A' = {#} \<and> B' = {#})"
  115.89 +    by blast
  115.90 +  {
  115.91 +    assume max: "(set_of A, set_of B) \<in> max_strict"
  115.92 +    from mx_or_empty
  115.93 +    have "(Z'' + (A + A'), Z'' + (B + B')) \<in> ms_strict"
  115.94 +    proof
  115.95 +      assume max': "(set_of A', set_of B') \<in> max_strict"
  115.96 +      with max have "(set_of (A + A'), set_of (B + B')) \<in> max_strict"
  115.97 +        by (auto simp: max_strict_def intro: max_ext_additive)
  115.98 +      thus ?thesis by (rule smsI) 
  115.99 +    next
 115.100 +      assume [simp]: "A' = {#} \<and> B' = {#}"
 115.101 +      show ?thesis by (rule smsI) (auto intro: max)
 115.102 +    qed
 115.103 +    thus "(Z + A, Z' + B) \<in> ms_strict" by (simp add:add_ac)
 115.104 +    thus "(Z + A, Z' + B) \<in> ms_weak" by (simp add: ms_weak_def)
 115.105 +  }
 115.106 +  from mx_or_empty
 115.107 +  have "(Z'' + A', Z'' + B') \<in> ms_weak" by (rule wmsI)
 115.108 +  thus "(Z + {#}, Z' + {#}) \<in> ms_weak" by (simp add:add_ac)
 115.109 +qed
 115.110 +
 115.111 +lemma empty_idemp: "{#} + x = x" "x + {#} = x"
 115.112 +and nonempty_plus: "{# x #} + rs \<noteq> {#}"
 115.113 +and nonempty_single: "{# x #} \<noteq> {#}"
 115.114 +by auto
 115.115 +
 115.116 +setup {*
 115.117 +let
 115.118 +  fun msetT T = Type ("Multiset.multiset", [T]);
 115.119 +
 115.120 +  fun mk_mset T [] = Const (@{const_name Mempty}, msetT T)
 115.121 +    | mk_mset T [x] = Const (@{const_name single}, T --> msetT T) $ x
 115.122 +    | mk_mset T (x :: xs) =
 115.123 +          Const (@{const_name plus}, msetT T --> msetT T --> msetT T) $
 115.124 +                mk_mset T [x] $ mk_mset T xs
 115.125 +
 115.126 +  fun mset_member_tac m i =
 115.127 +      (if m <= 0 then
 115.128 +           rtac @{thm multi_member_this} i ORELSE rtac @{thm multi_member_last} i
 115.129 +       else
 115.130 +           rtac @{thm multi_member_skip} i THEN mset_member_tac (m - 1) i)
 115.131 +
 115.132 +  val mset_nonempty_tac =
 115.133 +      rtac @{thm nonempty_plus} ORELSE' rtac @{thm nonempty_single}
 115.134 +
 115.135 +  val regroup_munion_conv =
 115.136 +      FundefLib.regroup_conv @{const_name Multiset.Mempty} @{const_name plus}
 115.137 +        (map (fn t => t RS eq_reflection) (@{thms union_ac} @ @{thms empty_idemp}))
 115.138 +
 115.139 +  fun unfold_pwleq_tac i =
 115.140 +    (rtac @{thm pw_leq_step} i THEN (fn st => unfold_pwleq_tac (i + 1) st))
 115.141 +      ORELSE (rtac @{thm pw_leq_lstep} i)
 115.142 +      ORELSE (rtac @{thm pw_leq_empty} i)
 115.143 +
 115.144 +  val set_of_simps = [@{thm set_of_empty}, @{thm set_of_single}, @{thm set_of_union},
 115.145 +                      @{thm Un_insert_left}, @{thm Un_empty_left}]
 115.146 +in
 115.147 +  ScnpReconstruct.multiset_setup (ScnpReconstruct.Multiset 
 115.148 +  {
 115.149 +    msetT=msetT, mk_mset=mk_mset, mset_regroup_conv=regroup_munion_conv,
 115.150 +    mset_member_tac=mset_member_tac, mset_nonempty_tac=mset_nonempty_tac,
 115.151 +    mset_pwleq_tac=unfold_pwleq_tac, set_of_simps=set_of_simps,
 115.152 +    smsI'=@{thm ms_strictI}, wmsI2''=@{thm ms_weakI2}, wmsI1=@{thm ms_weakI1},
 115.153 +    reduction_pair=@{thm ms_reduction_pair}
 115.154 +  })
 115.155  end
 115.156 +*}
 115.157 +
 115.158 +end
   116.1 --- a/src/HOL/Lim.thy	Tue Dec 30 08:18:54 2008 +0100
   116.2 +++ b/src/HOL/Lim.thy	Tue Dec 30 11:10:01 2008 +0100
   116.3 @@ -7,7 +7,7 @@
   116.4  header{* Limits and Continuity *}
   116.5  
   116.6  theory Lim
   116.7 -imports "~~/src/HOL/Hyperreal/SEQ"
   116.8 +imports SEQ
   116.9  begin
  116.10  
  116.11  text{*Standard Definitions*}
   117.1 --- a/src/HOL/MacLaurin.thy	Tue Dec 30 08:18:54 2008 +0100
   117.2 +++ b/src/HOL/MacLaurin.thy	Tue Dec 30 11:10:01 2008 +0100
   117.3 @@ -58,129 +58,157 @@
   117.4  *}
   117.5  
   117.6  lemma Maclaurin_lemma2:
   117.7 -      "[| \<forall>m t. m < n \<and> 0\<le>t \<and> t\<le>h \<longrightarrow> DERIV (diff m) t :> diff (Suc m) t;
   117.8 -          n = Suc k;
   117.9 -        difg =
  117.10 +  assumes diff: "\<forall>m t. m < n \<and> 0\<le>t \<and> t\<le>h \<longrightarrow> DERIV (diff m) t :> diff (Suc m) t"
  117.11 +  assumes n: "n = Suc k"
  117.12 +  assumes difg: "difg =
  117.13          (\<lambda>m t. diff m t -
  117.14                 ((\<Sum>p = 0..<n - m. diff (m + p) 0 / real (fact p) * t ^ p) +
  117.15 -                B * (t ^ (n - m) / real (fact (n - m)))))|] ==>
  117.16 -        \<forall>m t. m < n & 0 \<le> t & t \<le> h -->
  117.17 -                    DERIV (difg m) t :> difg (Suc m) t"
  117.18 -apply clarify
  117.19 -apply (rule DERIV_diff)
  117.20 -apply (simp (no_asm_simp))
  117.21 -apply (tactic {* DERIV_tac @{context} *})
  117.22 -apply (tactic {* DERIV_tac @{context} *})
  117.23 -apply (rule_tac [2] lemma_DERIV_subst)
  117.24 -apply (rule_tac [2] DERIV_quotient)
  117.25 -apply (rule_tac [3] DERIV_const)
  117.26 -apply (rule_tac [2] DERIV_pow)
  117.27 -  prefer 3 apply (simp add: fact_diff_Suc)
  117.28 - prefer 2 apply simp
  117.29 -apply (frule_tac m = m in less_add_one, clarify)
  117.30 -apply (simp del: setsum_op_ivl_Suc)
  117.31 -apply (insert sumr_offset4 [of 1])
  117.32 -apply (simp del: setsum_op_ivl_Suc fact_Suc realpow_Suc)
  117.33 -apply (rule lemma_DERIV_subst)
  117.34 -apply (rule DERIV_add)
  117.35 -apply (rule_tac [2] DERIV_const)
  117.36 -apply (rule DERIV_sumr, clarify)
  117.37 - prefer 2 apply simp
  117.38 -apply (simp (no_asm) add: divide_inverse mult_assoc del: fact_Suc realpow_Suc)
  117.39 -apply (rule DERIV_cmult)
  117.40 -apply (rule lemma_DERIV_subst)
  117.41 -apply (best intro: DERIV_chain2 intro!: DERIV_intros)
  117.42 -apply (subst fact_Suc)
  117.43 -apply (subst real_of_nat_mult)
  117.44 -apply (simp add: mult_ac)
  117.45 +                B * (t ^ (n - m) / real (fact (n - m)))))"
  117.46 +  shows
  117.47 +      "\<forall>m t. m < n & 0 \<le> t & t \<le> h --> DERIV (difg m) t :> difg (Suc m) t"
  117.48 +unfolding difg
  117.49 + apply clarify
  117.50 + apply (rule DERIV_diff)
  117.51 +  apply (simp add: diff)
  117.52 + apply (simp only: n)
  117.53 + apply (rule DERIV_add)
  117.54 +  apply (rule_tac [2] DERIV_cmult)
  117.55 +  apply (rule_tac [2] lemma_DERIV_subst)
  117.56 +   apply (rule_tac [2] DERIV_quotient)
  117.57 +     apply (rule_tac [3] DERIV_const)
  117.58 +    apply (rule_tac [2] DERIV_pow)
  117.59 +   prefer 3 apply (simp add: fact_diff_Suc)
  117.60 +  prefer 2 apply simp
  117.61 + apply (frule less_iff_Suc_add [THEN iffD1], clarify)
  117.62 + apply (simp del: setsum_op_ivl_Suc)
  117.63 + apply (insert sumr_offset4 [of 1])
  117.64 + apply (simp del: setsum_op_ivl_Suc fact_Suc realpow_Suc)
  117.65 + apply (rule lemma_DERIV_subst)
  117.66 +  apply (rule DERIV_add)
  117.67 +   apply (rule_tac [2] DERIV_const)
  117.68 +  apply (rule DERIV_sumr, clarify)
  117.69 +  prefer 2 apply simp
  117.70 + apply (simp (no_asm) add: divide_inverse mult_assoc del: fact_Suc realpow_Suc)
  117.71 + apply (rule DERIV_cmult)
  117.72 + apply (rule lemma_DERIV_subst)
  117.73 +  apply (best intro: DERIV_chain2 intro!: DERIV_intros)
  117.74 + apply (subst fact_Suc)
  117.75 + apply (subst real_of_nat_mult)
  117.76 + apply (simp add: mult_ac)
  117.77  done
  117.78  
  117.79  
  117.80 -lemma Maclaurin_lemma3:
  117.81 -  fixes difg :: "nat => real => real" shows
  117.82 -     "[|\<forall>k t. k < Suc m \<and> 0\<le>t & t\<le>h \<longrightarrow> DERIV (difg k) t :> difg (Suc k) t;
  117.83 -        \<forall>k<Suc m. difg k 0 = 0; DERIV (difg n) t :> 0;  n < m; 0 < t;
  117.84 -        t < h|]
  117.85 -     ==> \<exists>ta. 0 < ta & ta < t & DERIV (difg (Suc n)) ta :> 0"
  117.86 -apply (rule Rolle, assumption, simp)
  117.87 -apply (drule_tac x = n and P="%k. k<Suc m --> difg k 0 = 0" in spec)
  117.88 -apply (rule DERIV_unique)
  117.89 -prefer 2 apply assumption
  117.90 -apply force
  117.91 -apply (metis DERIV_isCont dlo_simps(4) dlo_simps(9) less_trans_Suc nat_less_le not_less_eq real_le_trans)
  117.92 -apply (metis Suc_less_eq differentiableI dlo_simps(7) dlo_simps(8) dlo_simps(9)   real_le_trans xt1(8))
  117.93 -done
  117.94 -
  117.95  lemma Maclaurin:
  117.96 -   "[| 0 < h; n > 0; diff 0 = f;
  117.97 -       \<forall>m t. m < n & 0 \<le> t & t \<le> h --> DERIV (diff m) t :> diff (Suc m) t |]
  117.98 -    ==> \<exists>t. 0 < t &
  117.99 -              t < h &
 117.100 +  assumes h: "0 < h"
 117.101 +  assumes n: "0 < n"
 117.102 +  assumes diff_0: "diff 0 = f"
 117.103 +  assumes diff_Suc:
 117.104 +    "\<forall>m t. m < n & 0 \<le> t & t \<le> h --> DERIV (diff m) t :> diff (Suc m) t"
 117.105 +  shows
 117.106 +    "\<exists>t. 0 < t & t < h &
 117.107                f h =
 117.108                setsum (%m. (diff m 0 / real (fact m)) * h ^ m) {0..<n} +
 117.109                (diff n t / real (fact n)) * h ^ n"
 117.110 -apply (case_tac "n = 0", force)
 117.111 -apply (drule not0_implies_Suc)
 117.112 -apply (erule exE)
 117.113 -apply (frule_tac f=f and n=n and j="%m. diff m 0" in Maclaurin_lemma)
 117.114 -apply (erule exE)
 117.115 -apply (subgoal_tac "\<exists>g.
 117.116 -     g = (%t. f t - (setsum (%m. (diff m 0 / real(fact m)) * t^m) {0..<n} + (B * (t^n / real(fact n)))))")
 117.117 - prefer 2 apply blast
 117.118 -apply (erule exE)
 117.119 -apply (subgoal_tac "g 0 = 0 & g h =0")
 117.120 - prefer 2
 117.121 - apply (simp del: setsum_op_ivl_Suc)
 117.122 - apply (cut_tac n = m and k = 1 in sumr_offset2)
 117.123 - apply (simp add: eq_diff_eq' del: setsum_op_ivl_Suc)
 117.124 -apply (subgoal_tac "\<exists>difg. difg = (%m t. diff m t - (setsum (%p. (diff (m + p) 0 / real (fact p)) * (t ^ p)) {0..<n-m} + (B * ((t ^ (n - m)) / real (fact (n - m))))))")
 117.125 - prefer 2 apply blast
 117.126 -apply (erule exE)
 117.127 -apply (subgoal_tac "difg 0 = g")
 117.128 - prefer 2 apply simp
 117.129 -apply (frule Maclaurin_lemma2, assumption+)
 117.130 -apply (subgoal_tac "\<forall>ma. ma < n --> (\<exists>t. 0 < t & t < h & difg (Suc ma) t = 0) ")
 117.131 - apply (drule_tac x = m and P="%m. m<n --> (\<exists>t. ?QQ m t)" in spec)
 117.132 - apply (erule impE)
 117.133 -  apply (simp (no_asm_simp))
 117.134 - apply (erule exE)
 117.135 - apply (rule_tac x = t in exI)
 117.136 - apply (simp del: realpow_Suc fact_Suc)
 117.137 -apply (subgoal_tac "\<forall>m. m < n --> difg m 0 = 0")
 117.138 - prefer 2
 117.139 - apply clarify
 117.140 - apply simp
 117.141 - apply (frule_tac m = ma in less_add_one, clarify)
 117.142 - apply (simp del: setsum_op_ivl_Suc)
 117.143 -apply (insert sumr_offset4 [of 1])
 117.144 -apply (simp del: setsum_op_ivl_Suc fact_Suc realpow_Suc)
 117.145 -apply (subgoal_tac "\<forall>m. m < n --> (\<exists>t. 0 < t & t < h & DERIV (difg m) t :> 0) ")
 117.146 -apply (rule allI, rule impI)
 117.147 -apply (drule_tac x = ma and P="%m. m<n --> (\<exists>t. ?QQ m t)" in spec)
 117.148 -apply (erule impE, assumption)
 117.149 -apply (erule exE)
 117.150 -apply (rule_tac x = t in exI)
 117.151 -(* do some tidying up *)
 117.152 -apply (erule_tac [!] V= "difg = (%m t. diff m t - (setsum (%p. diff (m + p) 0 / real (fact p) * t ^ p) {0..<n-m} + B * (t ^ (n - m) / real (fact (n - m)))))"
 117.153 -       in thin_rl)
 117.154 -apply (erule_tac [!] V="g = (%t. f t - (setsum (%m. diff m 0 / real (fact m) * t ^ m) {0..<n} + B * (t ^ n / real (fact n))))"
 117.155 -       in thin_rl)
 117.156 -apply (erule_tac [!] V="f h = setsum (%m. diff m 0 / real (fact m) * h ^ m) {0..<n} + B * (h ^ n / real (fact n))"
 117.157 -       in thin_rl)
 117.158 -(* back to business *)
 117.159 -apply (simp (no_asm_simp))
 117.160 -apply (rule DERIV_unique)
 117.161 -prefer 2 apply blast
 117.162 -apply force
 117.163 -apply (rule allI, induct_tac "ma")
 117.164 -apply (rule impI, rule Rolle, assumption, simp, simp)
 117.165 -apply (metis DERIV_isCont zero_less_Suc)
 117.166 -apply (metis One_nat_def differentiableI dlo_simps(7))
 117.167 -apply safe
 117.168 -apply force
 117.169 -apply (frule Maclaurin_lemma3, assumption+, safe)
 117.170 -apply (rule_tac x = ta in exI, force)
 117.171 -done
 117.172 +proof -
 117.173 +  from n obtain m where m: "n = Suc m"
 117.174 +    by (cases n, simp add: n)
 117.175 +
 117.176 +  obtain B where f_h: "f h =
 117.177 +        (\<Sum>m = 0..<n. diff m (0\<Colon>real) / real (fact m) * h ^ m) +
 117.178 +        B * (h ^ n / real (fact n))"
 117.179 +    using Maclaurin_lemma [OF h] ..
 117.180 +
 117.181 +  obtain g where g_def: "g = (%t. f t -
 117.182 +    (setsum (%m. (diff m 0 / real(fact m)) * t^m) {0..<n}
 117.183 +      + (B * (t^n / real(fact n)))))" by blast
 117.184 +
 117.185 +  have g2: "g 0 = 0 & g h = 0"
 117.186 +    apply (simp add: m f_h g_def del: setsum_op_ivl_Suc)
 117.187 +    apply (cut_tac n = m and k = 1 in sumr_offset2)
 117.188 +    apply (simp add: eq_diff_eq' diff_0 del: setsum_op_ivl_Suc)
 117.189 +    done
 117.190 +
 117.191 +  obtain difg where difg_def: "difg = (%m t. diff m t -
 117.192 +    (setsum (%p. (diff (m + p) 0 / real (fact p)) * (t ^ p)) {0..<n-m}
 117.193 +      + (B * ((t ^ (n - m)) / real (fact (n - m))))))" by blast
 117.194 +
 117.195 +  have difg_0: "difg 0 = g"
 117.196 +    unfolding difg_def g_def by (simp add: diff_0)
 117.197 +
 117.198 +  have difg_Suc: "\<forall>(m\<Colon>nat) t\<Colon>real.
 117.199 +        m < n \<and> (0\<Colon>real) \<le> t \<and> t \<le> h \<longrightarrow> DERIV (difg m) t :> difg (Suc m) t"
 117.200 +    using diff_Suc m difg_def by (rule Maclaurin_lemma2)
 117.201 +
 117.202 +  have difg_eq_0: "\<forall>m. m < n --> difg m 0 = 0"
 117.203 +    apply clarify
 117.204 +    apply (simp add: m difg_def)
 117.205 +    apply (frule less_iff_Suc_add [THEN iffD1], clarify)
 117.206 +    apply (simp del: setsum_op_ivl_Suc)
 117.207 +    apply (insert sumr_offset4 [of 1])
 117.208 +    apply (simp del: setsum_op_ivl_Suc fact_Suc realpow_Suc)
 117.209 +    done
 117.210 +
 117.211 +  have isCont_difg: "\<And>m x. \<lbrakk>m < n; 0 \<le> x; x \<le> h\<rbrakk> \<Longrightarrow> isCont (difg m) x"
 117.212 +    by (rule DERIV_isCont [OF difg_Suc [rule_format]]) simp
 117.213 +
 117.214 +  have differentiable_difg:
 117.215 +    "\<And>m x. \<lbrakk>m < n; 0 \<le> x; x \<le> h\<rbrakk> \<Longrightarrow> difg m differentiable x"
 117.216 +    by (rule differentiableI [OF difg_Suc [rule_format]]) simp
 117.217 +
 117.218 +  have difg_Suc_eq_0: "\<And>m t. \<lbrakk>m < n; 0 \<le> t; t \<le> h; DERIV (difg m) t :> 0\<rbrakk>
 117.219 +        \<Longrightarrow> difg (Suc m) t = 0"
 117.220 +    by (rule DERIV_unique [OF difg_Suc [rule_format]]) simp
 117.221 +
 117.222 +  have "m < n" using m by simp
 117.223 +
 117.224 +  have "\<exists>t. 0 < t \<and> t < h \<and> DERIV (difg m) t :> 0"
 117.225 +  using `m < n`
 117.226 +  proof (induct m)
 117.227 +  case 0
 117.228 +    show ?case
 117.229 +    proof (rule Rolle)
 117.230 +      show "0 < h" by fact
 117.231 +      show "difg 0 0 = difg 0 h" by (simp add: difg_0 g2)
 117.232 +      show "\<forall>x. 0 \<le> x \<and> x \<le> h \<longrightarrow> isCont (difg (0\<Colon>nat)) x"
 117.233 +        by (simp add: isCont_difg n)
 117.234 +      show "\<forall>x. 0 < x \<and> x < h \<longrightarrow> difg (0\<Colon>nat) differentiable x"
 117.235 +        by (simp add: differentiable_difg n)
 117.236 +    qed
 117.237 +  next
 117.238 +  case (Suc m')
 117.239 +    hence "\<exists>t. 0 < t \<and> t < h \<and> DERIV (difg m') t :> 0" by simp
 117.240 +    then obtain t where t: "0 < t" "t < h" "DERIV (difg m') t :> 0" by fast
 117.241 +    have "\<exists>t'. 0 < t' \<and> t' < t \<and> DERIV (difg (Suc m')) t' :> 0"
 117.242 +    proof (rule Rolle)
 117.243 +      show "0 < t" by fact
 117.244 +      show "difg (Suc m') 0 = difg (Suc m') t"
 117.245 +        using t `Suc m' < n` by (simp add: difg_Suc_eq_0 difg_eq_0)
 117.246 +      show "\<forall>x. 0 \<le> x \<and> x \<le> t \<longrightarrow> isCont (difg (Suc m')) x"
 117.247 +        using `t < h` `Suc m' < n` by (simp add: isCont_difg)
 117.248 +      show "\<forall>x. 0 < x \<and> x < t \<longrightarrow> difg (Suc m') differentiable x"
 117.249 +        using `t < h` `Suc m' < n` by (simp add: differentiable_difg)
 117.250 +    qed
 117.251 +    thus ?case
 117.252 +      using `t < h` by auto
 117.253 +  qed
 117.254 +
 117.255 +  then obtain t where "0 < t" "t < h" "DERIV (difg m) t :> 0" by fast
 117.256 +
 117.257 +  hence "difg (Suc m) t = 0"
 117.258 +    using `m < n` by (simp add: difg_Suc_eq_0)
 117.259 +
 117.260 +  show ?thesis
 117.261 +  proof (intro exI conjI)
 117.262 +    show "0 < t" by fact
 117.263 +    show "t < h" by fact
 117.264 +    show "f h =
 117.265 +      (\<Sum>m = 0..<n. diff m 0 / real (fact m) * h ^ m) +
 117.266 +      diff n t / real (fact n) * h ^ n"
 117.267 +      using `difg (Suc m) t = 0`
 117.268 +      by (simp add: m f_h difg_def del: realpow_Suc fact_Suc)
 117.269 +  qed
 117.270 +
 117.271 +qed
 117.272  
 117.273  lemma Maclaurin_objl:
 117.274    "0 < h & n>0 & diff 0 = f &
   118.1 --- a/src/HOL/Nominal/Examples/CK_Machine.thy	Tue Dec 30 08:18:54 2008 +0100
   118.2 +++ b/src/HOL/Nominal/Examples/CK_Machine.thy	Tue Dec 30 11:10:01 2008 +0100
   118.3 @@ -1,5 +1,3 @@
   118.4 -(* $Id$ *)
   118.5 -
   118.6  theory CK_Machine 
   118.7    imports "../Nominal" 
   118.8  begin
   118.9 @@ -41,21 +39,21 @@
  118.10  
  118.11  section {* Capture-Avoiding Substitution *}
  118.12  
  118.13 -consts subst :: "lam \<Rightarrow> name \<Rightarrow> lam \<Rightarrow> lam"  ("_[_::=_]" [100,100,100] 100)
  118.14 -
  118.15  nominal_primrec
  118.16 +  subst :: "lam \<Rightarrow> name \<Rightarrow> lam \<Rightarrow> lam"  ("_[_::=_]" [100,100,100] 100)
  118.17 +where
  118.18    "(VAR x)[y::=s] = (if x=y then s else (VAR x))"
  118.19 -  "(APP t\<^isub>1 t\<^isub>2)[y::=s] = APP (t\<^isub>1[y::=s]) (t\<^isub>2[y::=s])"
  118.20 -  "x\<sharp>(y,s) \<Longrightarrow> (LAM [x].t)[y::=s] = LAM [x].(t[y::=s])"
  118.21 -  "(NUM n)[y::=s] = NUM n"
  118.22 -  "(t\<^isub>1 -- t\<^isub>2)[y::=s] = (t\<^isub>1[y::=s]) -- (t\<^isub>2[y::=s])"
  118.23 -  "(t\<^isub>1 ++ t\<^isub>2)[y::=s] = (t\<^isub>1[y::=s]) ++ (t\<^isub>2[y::=s])"
  118.24 -  "x\<sharp>(y,s) \<Longrightarrow> (FIX [x].t)[y::=s] = FIX [x].(t[y::=s])"
  118.25 -  "TRUE[y::=s] = TRUE"
  118.26 -  "FALSE[y::=s] = FALSE"
  118.27 -  "(IF t1 t2 t3)[y::=s] = IF (t1[y::=s]) (t2[y::=s]) (t3[y::=s])"
  118.28 -  "(ZET t)[y::=s] = ZET (t[y::=s])"
  118.29 -  "(EQI t1 t2)[y::=s] = EQI (t1[y::=s]) (t2[y::=s])"
  118.30 +| "(APP t\<^isub>1 t\<^isub>2)[y::=s] = APP (t\<^isub>1[y::=s]) (t\<^isub>2[y::=s])"
  118.31 +| "x\<sharp>(y,s) \<Longrightarrow> (LAM [x].t)[y::=s] = LAM [x].(t[y::=s])"
  118.32 +| "(NUM n)[y::=s] = NUM n"
  118.33 +| "(t\<^isub>1 -- t\<^isub>2)[y::=s] = (t\<^isub>1[y::=s]) -- (t\<^isub>2[y::=s])"
  118.34 +| "(t\<^isub>1 ++ t\<^isub>2)[y::=s] = (t\<^isub>1[y::=s]) ++ (t\<^isub>2[y::=s])"
  118.35 +| "x\<sharp>(y,s) \<Longrightarrow> (FIX [x].t)[y::=s] = FIX [x].(t[y::=s])"
  118.36 +| "TRUE[y::=s] = TRUE"
  118.37 +| "FALSE[y::=s] = FALSE"
  118.38 +| "(IF t1 t2 t3)[y::=s] = IF (t1[y::=s]) (t2[y::=s]) (t3[y::=s])"
  118.39 +| "(ZET t)[y::=s] = ZET (t[y::=s])"
  118.40 +| "(EQI t1 t2)[y::=s] = EQI (t1[y::=s]) (t2[y::=s])"
  118.41  apply(finite_guess)+
  118.42  apply(rule TrueI)+
  118.43  apply(simp add: abs_fresh)+
   119.1 --- a/src/HOL/Nominal/Examples/CR_Takahashi.thy	Tue Dec 30 08:18:54 2008 +0100
   119.2 +++ b/src/HOL/Nominal/Examples/CR_Takahashi.thy	Tue Dec 30 11:10:01 2008 +0100
   119.3 @@ -1,5 +1,3 @@
   119.4 -(* $Id$ *)
   119.5 -
   119.6  (* Authors: Christian Urban and Mathilde Arnaud                   *)
   119.7  (*                                                                *)
   119.8  (* A formalisation of the Church-Rosser proof by Masako Takahashi.*)
   119.9 @@ -20,12 +18,12 @@
  119.10    | App "lam" "lam"
  119.11    | Lam "\<guillemotleft>name\<guillemotright>lam" ("Lam [_]._" [100,100] 100)
  119.12  
  119.13 -consts subst :: "lam \<Rightarrow> name \<Rightarrow> lam \<Rightarrow> lam"  ("_[_::=_]" [100,100,100] 100)
  119.14 -
  119.15  nominal_primrec
  119.16 +  subst :: "lam \<Rightarrow> name \<Rightarrow> lam \<Rightarrow> lam"  ("_[_::=_]" [100,100,100] 100)
  119.17 +where
  119.18    "(Var x)[y::=s] = (if x=y then s else (Var x))"
  119.19 -  "(App t\<^isub>1 t\<^isub>2)[y::=s] = App (t\<^isub>1[y::=s]) (t\<^isub>2[y::=s])"
  119.20 -  "x\<sharp>(y,s) \<Longrightarrow> (Lam [x].t)[y::=s] = Lam [x].(t[y::=s])"
  119.21 +| "(App t\<^isub>1 t\<^isub>2)[y::=s] = App (t\<^isub>1[y::=s]) (t\<^isub>2[y::=s])"
  119.22 +| "x\<sharp>(y,s) \<Longrightarrow> (Lam [x].t)[y::=s] = Lam [x].(t[y::=s])"
  119.23  apply(finite_guess)+
  119.24  apply(rule TrueI)+
  119.25  apply(simp add: abs_fresh)
  119.26 @@ -54,14 +52,16 @@
  119.27  lemma substitution_lemma:  
  119.28    assumes a: "x\<noteq>y" "x\<sharp>u"
  119.29    shows "t[x::=s][y::=u] = t[y::=u][x::=s[y::=u]]"
  119.30 -using a by (nominal_induct t avoiding: x y s u rule: lam.strong_induct)
  119.31 -           (auto simp add: fresh_fact forget)
  119.32 +using a 
  119.33 +by (nominal_induct t avoiding: x y s u rule: lam.strong_induct)
  119.34 +   (auto simp add: fresh_fact forget)
  119.35  
  119.36  lemma subst_rename: 
  119.37    assumes a: "y\<sharp>t"
  119.38    shows "t[x::=s] = ([(y,x)]\<bullet>t)[y::=s]"
  119.39 -using a by (nominal_induct t avoiding: x y s rule: lam.strong_induct)
  119.40 -           (auto simp add: calc_atm fresh_atm abs_fresh)
  119.41 +using a 
  119.42 +by (nominal_induct t avoiding: x y s rule: lam.strong_induct)
  119.43 +   (auto simp add: swap_simps fresh_atm abs_fresh)
  119.44  
  119.45  section {* Beta-Reduction *}
  119.46  
  119.47 @@ -103,8 +103,9 @@
  119.48  lemma One_subst: 
  119.49    assumes a: "t1 \<longrightarrow>\<^isub>1 t2" "s1 \<longrightarrow>\<^isub>1 s2"
  119.50    shows "t1[x::=s1] \<longrightarrow>\<^isub>1 t2[x::=s2]" 
  119.51 -using a by (nominal_induct t1 t2 avoiding: s1 s2 x rule: One.strong_induct)
  119.52 -           (auto simp add: substitution_lemma fresh_atm fresh_fact)
  119.53 +using a 
  119.54 +by (nominal_induct t1 t2 avoiding: s1 s2 x rule: One.strong_induct)
  119.55 +   (auto simp add: substitution_lemma fresh_atm fresh_fact)
  119.56  
  119.57  lemma better_o4_intro:
  119.58    assumes a: "t1 \<longrightarrow>\<^isub>1 t2" "s1 \<longrightarrow>\<^isub>1 s2"
  119.59 @@ -202,35 +203,30 @@
  119.60  by (nominal_induct M rule: lam.strong_induct)
  119.61     (auto dest!: Dev_Lam intro: better_d4_intro)
  119.62  
  119.63 -(* needs fixing *)
  119.64  lemma Triangle:
  119.65    assumes a: "t \<longrightarrow>\<^isub>d t1" "t \<longrightarrow>\<^isub>1 t2"
  119.66    shows "t2 \<longrightarrow>\<^isub>1 t1"
  119.67  using a 
  119.68  proof(nominal_induct avoiding: t2 rule: Dev.strong_induct)
  119.69    case (d4 x s1 s2 t1 t1' t2) 
  119.70 -  have ih1: "\<And>t. t1 \<longrightarrow>\<^isub>1 t \<Longrightarrow>  t \<longrightarrow>\<^isub>1 t1'"
  119.71 -  and  ih2: "\<And>s. s1 \<longrightarrow>\<^isub>1 s \<Longrightarrow>  s \<longrightarrow>\<^isub>1 s2"
  119.72 -  and  fc: "x\<sharp>t2" "x\<sharp>s1" "x\<sharp>s2" by fact+ 
  119.73 +  have  fc: "x\<sharp>t2" "x\<sharp>s1" by fact+ 
  119.74    have "App (Lam [x].t1) s1 \<longrightarrow>\<^isub>1 t2" by fact
  119.75 -  then obtain t' s' where "(t2 = App (Lam [x].t') s' \<and> t1 \<longrightarrow>\<^isub>1 t' \<and> s1 \<longrightarrow>\<^isub>1 s') \<or> 
  119.76 -                           (t2 = t'[x::=s'] \<and> t1 \<longrightarrow>\<^isub>1 t' \<and> s1 \<longrightarrow>\<^isub>1 s')"
  119.77 +  then obtain t' s' where reds: 
  119.78 +             "(t2 = App (Lam [x].t') s' \<and> t1 \<longrightarrow>\<^isub>1 t' \<and> s1 \<longrightarrow>\<^isub>1 s') \<or> 
  119.79 +              (t2 = t'[x::=s'] \<and> t1 \<longrightarrow>\<^isub>1 t' \<and> s1 \<longrightarrow>\<^isub>1 s')"
  119.80    using fc by (auto dest!: One_Redex)
  119.81 -  then show "t2 \<longrightarrow>\<^isub>1 t1'[x::=s2]"
  119.82 -    apply -
  119.83 -    apply(erule disjE)
  119.84 -    apply(erule conjE)+
  119.85 -    apply(simp)
  119.86 -    apply(rule o4)
  119.87 -    using fc apply(simp)
  119.88 -    using ih1 apply(simp)
  119.89 -    using ih2 apply(simp)
  119.90 -    apply(erule conjE)+
  119.91 -    apply(simp)
  119.92 -    apply(rule One_subst)
  119.93 -    using ih1 apply(simp)
  119.94 -    using ih2 apply(simp)    
  119.95 -    done
  119.96 +  have ih1: "t1 \<longrightarrow>\<^isub>1 t' \<Longrightarrow>  t' \<longrightarrow>\<^isub>1 t1'" by fact
  119.97 +  have ih2: "s1 \<longrightarrow>\<^isub>1 s' \<Longrightarrow>  s' \<longrightarrow>\<^isub>1 s2" by fact
  119.98 +  { assume "t1 \<longrightarrow>\<^isub>1 t'" "s1 \<longrightarrow>\<^isub>1 s'"
  119.99 +    then have "App (Lam [x].t') s' \<longrightarrow>\<^isub>1 t1'[x::=s2]" 
 119.100 +      using ih1 ih2 by (auto intro: better_o4_intro)
 119.101 +  }
 119.102 +  moreover
 119.103 +  { assume "t1 \<longrightarrow>\<^isub>1 t'" "s1 \<longrightarrow>\<^isub>1 s'"
 119.104 +    then have "t'[x::=s'] \<longrightarrow>\<^isub>1 t1'[x::=s2]" 
 119.105 +      using ih1 ih2 by (auto intro: One_subst)
 119.106 +  }
 119.107 +  ultimately show "t2 \<longrightarrow>\<^isub>1 t1'[x::=s2]" using reds by auto 
 119.108  qed (auto dest!: One_Lam One_Var One_App)
 119.109  
 119.110  lemma Diamond_for_One:
 119.111 @@ -310,4 +306,6 @@
 119.112    then show "\<exists>t3. t1 \<longrightarrow>\<^isub>\<beta>\<^sup>* t3 \<and> t2 \<longrightarrow>\<^isub>\<beta>\<^sup>* t3" by (simp add: Beta_star_equals_One_star)
 119.113  qed
 119.114  
 119.115 +
 119.116 +
 119.117  end
   120.1 --- a/src/HOL/Nominal/Examples/Class.thy	Tue Dec 30 08:18:54 2008 +0100
   120.2 +++ b/src/HOL/Nominal/Examples/Class.thy	Tue Dec 30 11:10:01 2008 +0100
   120.3 @@ -1,5 +1,3 @@
   120.4 -(* $Id$ *)
   120.5 -
   120.6  theory Class
   120.7  imports "../Nominal" 
   120.8  begin
   120.9 @@ -17,16 +15,22 @@
  120.10    | OR   "ty" "ty"   ("_ OR _" [100,100] 100)
  120.11    | IMP  "ty" "ty"   ("_ IMP _" [100,100] 100)
  120.12  
  120.13 -instance ty :: size ..
  120.14 -
  120.15 -nominal_primrec
  120.16 +instantiation ty :: size
  120.17 +begin
  120.18 +
  120.19 +nominal_primrec size_ty
  120.20 +where
  120.21    "size (PR s)     = (1::nat)"
  120.22 -  "size (NOT T)     = 1 + size T"
  120.23 -  "size (T1 AND T2) = 1 + size T1 + size T2"
  120.24 -  "size (T1 OR T2)  = 1 + size T1 + size T2"
  120.25 -  "size (T1 IMP T2) = 1 + size T1 + size T2"
  120.26 +| "size (NOT T)     = 1 + size T"
  120.27 +| "size (T1 AND T2) = 1 + size T1 + size T2"
  120.28 +| "size (T1 OR T2)  = 1 + size T1 + size T2"
  120.29 +| "size (T1 IMP T2) = 1 + size T1 + size T2"
  120.30  by (rule TrueI)+
  120.31  
  120.32 +instance ..
  120.33 +
  120.34 +end
  120.35 +
  120.36  lemma ty_cases:
  120.37    fixes T::ty
  120.38    shows "(\<exists>s. T=PR s) \<or> (\<exists>T'. T=NOT T') \<or> (\<exists>S U. T=S OR U) \<or> (\<exists>S U. T=S AND U) \<or> (\<exists>S U. T=S IMP U)"
  120.39 @@ -66,25 +70,23 @@
  120.40  
  120.41  text {* renaming functions *}
  120.42  
  120.43 -consts
  120.44 -  nrename :: "trm \<Rightarrow> name \<Rightarrow> name \<Rightarrow> trm"      ("_[_\<turnstile>n>_]" [100,100,100] 100) 
  120.45 +nominal_primrec (freshness_context: "(d::coname,e::coname)") 
  120.46    crename :: "trm \<Rightarrow> coname \<Rightarrow> coname \<Rightarrow> trm"  ("_[_\<turnstile>c>_]" [100,100,100] 100) 
  120.47 -
  120.48 -nominal_primrec (freshness_context: "(d::coname,e::coname)") 
  120.49 +where
  120.50    "(Ax x a)[d\<turnstile>c>e] = (if a=d then Ax x e else Ax x a)" 
  120.51 -  "\<lbrakk>a\<sharp>(d,e,N);x\<sharp>M\<rbrakk> \<Longrightarrow> (Cut <a>.M (x).N)[d\<turnstile>c>e] = Cut <a>.(M[d\<turnstile>c>e]) (x).(N[d\<turnstile>c>e])" 
  120.52 -  "(NotR (x).M a)[d\<turnstile>c>e] = (if a=d then NotR (x).(M[d\<turnstile>c>e]) e else NotR (x).(M[d\<turnstile>c>e]) a)" 
  120.53 -  "a\<sharp>(d,e) \<Longrightarrow> (NotL <a>.M x)[d\<turnstile>c>e] = (NotL <a>.(M[d\<turnstile>c>e]) x)" 
  120.54 -  "\<lbrakk>a\<sharp>(d,e,N,c);b\<sharp>(d,e,M,c);b\<noteq>a\<rbrakk> \<Longrightarrow> (AndR <a>.M <b>.N c)[d\<turnstile>c>e] = 
  120.55 +| "\<lbrakk>a\<sharp>(d,e,N);x\<sharp>M\<rbrakk> \<Longrightarrow> (Cut <a>.M (x).N)[d\<turnstile>c>e] = Cut <a>.(M[d\<turnstile>c>e]) (x).(N[d\<turnstile>c>e])" 
  120.56 +| "(NotR (x).M a)[d\<turnstile>c>e] = (if a=d then NotR (x).(M[d\<turnstile>c>e]) e else NotR (x).(M[d\<turnstile>c>e]) a)" 
  120.57 +| "a\<sharp>(d,e) \<Longrightarrow> (NotL <a>.M x)[d\<turnstile>c>e] = (NotL <a>.(M[d\<turnstile>c>e]) x)" 
  120.58 +| "\<lbrakk>a\<sharp>(d,e,N,c);b\<sharp>(d,e,M,c);b\<noteq>a\<rbrakk> \<Longrightarrow> (AndR <a>.M <b>.N c)[d\<turnstile>c>e] = 
  120.59            (if c=d then AndR <a>.(M[d\<turnstile>c>e]) <b>.(N[d \<turnstile>c>e]) e else AndR <a>.(M[d\<turnstile>c>e]) <b>.(N[d\<turnstile>c>e]) c)" 
  120.60 -  "x\<sharp>y \<Longrightarrow> (AndL1 (x).M y)[d\<turnstile>c>e] = AndL1 (x).(M[d\<turnstile>c>e]) y"
  120.61 -  "x\<sharp>y \<Longrightarrow> (AndL2 (x).M y)[d\<turnstile>c>e] = AndL2 (x).(M[d\<turnstile>c>e]) y"
  120.62 -  "a\<sharp>(d,e,b) \<Longrightarrow> (OrR1 <a>.M b)[d\<turnstile>c>e] = (if b=d then OrR1 <a>.(M[d\<turnstile>c>e]) e else OrR1 <a>.(M[d\<turnstile>c>e]) b)"
  120.63 -  "a\<sharp>(d,e,b) \<Longrightarrow> (OrR2 <a>.M b)[d\<turnstile>c>e] = (if b=d then OrR2 <a>.(M[d\<turnstile>c>e]) e else OrR2 <a>.(M[d\<turnstile>c>e]) b)"
  120.64 -  "\<lbrakk>x\<sharp>(N,z);y\<sharp>(M,z);y\<noteq>x\<rbrakk> \<Longrightarrow> (OrL (x).M (y).N z)[d\<turnstile>c>e] = OrL (x).(M[d\<turnstile>c>e]) (y).(N[d\<turnstile>c>e]) z"
  120.65 -  "a\<sharp>(d,e,b) \<Longrightarrow> (ImpR (x).<a>.M b)[d\<turnstile>c>e] = 
  120.66 +| "x\<sharp>y \<Longrightarrow> (AndL1 (x).M y)[d\<turnstile>c>e] = AndL1 (x).(M[d\<turnstile>c>e]) y"
  120.67 +| "x\<sharp>y \<Longrightarrow> (AndL2 (x).M y)[d\<turnstile>c>e] = AndL2 (x).(M[d\<turnstile>c>e]) y"
  120.68 +| "a\<sharp>(d,e,b) \<Longrightarrow> (OrR1 <a>.M b)[d\<turnstile>c>e] = (if b=d then OrR1 <a>.(M[d\<turnstile>c>e]) e else OrR1 <a>.(M[d\<turnstile>c>e]) b)"
  120.69 +| "a\<sharp>(d,e,b) \<Longrightarrow> (OrR2 <a>.M b)[d\<turnstile>c>e] = (if b=d then OrR2 <a>.(M[d\<turnstile>c>e]) e else OrR2 <a>.(M[d\<turnstile>c>e]) b)"
  120.70 +| "\<lbrakk>x\<sharp>(N,z);y\<sharp>(M,z);y\<noteq>x\<rbrakk> \<Longrightarrow> (OrL (x).M (y).N z)[d\<turnstile>c>e] = OrL (x).(M[d\<turnstile>c>e]) (y).(N[d\<turnstile>c>e]) z"
  120.71 +| "a\<sharp>(d,e,b) \<Longrightarrow> (ImpR (x).<a>.M b)[d\<turnstile>c>e] = 
  120.72         (if b=d then ImpR (x).<a>.(M[d\<turnstile>c>e]) e else ImpR (x).<a>.(M[d\<turnstile>c>e]) b)"
  120.73 -  "\<lbrakk>a\<sharp>(d,e,N);x\<sharp>(M,y)\<rbrakk> \<Longrightarrow> (ImpL <a>.M (x).N y)[d\<turnstile>c>e] = ImpL <a>.(M[d\<turnstile>c>e]) (x).(N[d\<turnstile>c>e]) y"
  120.74 +| "\<lbrakk>a\<sharp>(d,e,N);x\<sharp>(M,y)\<rbrakk> \<Longrightarrow> (ImpL <a>.M (x).N y)[d\<turnstile>c>e] = ImpL <a>.(M[d\<turnstile>c>e]) (x).(N[d\<turnstile>c>e]) y"
  120.75  apply(finite_guess)+
  120.76  apply(rule TrueI)+
  120.77  apply(simp add: abs_fresh abs_supp fin_supp)+
  120.78 @@ -92,19 +94,21 @@
  120.79  done
  120.80  
  120.81  nominal_primrec (freshness_context: "(u::name,v::name)") 
  120.82 +  nrename :: "trm \<Rightarrow> name \<Rightarrow> name \<Rightarrow> trm"      ("_[_\<turnstile>n>_]" [100,100,100] 100) 
  120.83 +where
  120.84    "(Ax x a)[u\<turnstile>n>v] = (if x=u then Ax v a else Ax x a)" 
  120.85 -  "\<lbrakk>a\<sharp>N;x\<sharp>(u,v,M)\<rbrakk> \<Longrightarrow> (Cut <a>.M (x).N)[u\<turnstile>n>v] = Cut <a>.(M[u\<turnstile>n>v]) (x).(N[u\<turnstile>n>v])" 
  120.86 -  "x\<sharp>(u,v) \<Longrightarrow> (NotR (x).M a)[u\<turnstile>n>v] = NotR (x).(M[u\<turnstile>n>v]) a" 
  120.87 -  "(NotL <a>.M x)[u\<turnstile>n>v] = (if x=u then NotL <a>.(M[u\<turnstile>n>v]) v else NotL <a>.(M[u\<turnstile>n>v]) x)" 
  120.88 -  "\<lbrakk>a\<sharp>(N,c);b\<sharp>(M,c);b\<noteq>a\<rbrakk> \<Longrightarrow> (AndR <a>.M <b>.N c)[u\<turnstile>n>v] = AndR <a>.(M[u\<turnstile>n>v]) <b>.(N[u\<turnstile>n>v]) c" 
  120.89 -  "x\<sharp>(u,v,y) \<Longrightarrow> (AndL1 (x).M y)[u\<turnstile>n>v] = (if y=u then AndL1 (x).(M[u\<turnstile>n>v]) v else AndL1 (x).(M[u\<turnstile>n>v]) y)"
  120.90 -  "x\<sharp>(u,v,y) \<Longrightarrow> (AndL2 (x).M y)[u\<turnstile>n>v] = (if y=u then AndL2 (x).(M[u\<turnstile>n>v]) v else AndL2 (x).(M[u\<turnstile>n>v]) y)"
  120.91 -  "a\<sharp>b \<Longrightarrow> (OrR1 <a>.M b)[u\<turnstile>n>v] = OrR1 <a>.(M[u\<turnstile>n>v]) b"
  120.92 -  "a\<sharp>b \<Longrightarrow> (OrR2 <a>.M b)[u\<turnstile>n>v] = OrR2 <a>.(M[u\<turnstile>n>v]) b"
  120.93 -  "\<lbrakk>x\<sharp>(u,v,N,z);y\<sharp>(u,v,M,z);y\<noteq>x\<rbrakk> \<Longrightarrow> (OrL (x).M (y).N z)[u\<turnstile>n>v] = 
  120.94 +| "\<lbrakk>a\<sharp>N;x\<sharp>(u,v,M)\<rbrakk> \<Longrightarrow> (Cut <a>.M (x).N)[u\<turnstile>n>v] = Cut <a>.(M[u\<turnstile>n>v]) (x).(N[u\<turnstile>n>v])" 
  120.95 +| "x\<sharp>(u,v) \<Longrightarrow> (NotR (x).M a)[u\<turnstile>n>v] = NotR (x).(M[u\<turnstile>n>v]) a" 
  120.96 +| "(NotL <a>.M x)[u\<turnstile>n>v] = (if x=u then NotL <a>.(M[u\<turnstile>n>v]) v else NotL <a>.(M[u\<turnstile>n>v]) x)" 
  120.97 +| "\<lbrakk>a\<sharp>(N,c);b\<sharp>(M,c);b\<noteq>a\<rbrakk> \<Longrightarrow> (AndR <a>.M <b>.N c)[u\<turnstile>n>v] = AndR <a>.(M[u\<turnstile>n>v]) <b>.(N[u\<turnstile>n>v]) c" 
  120.98 +| "x\<sharp>(u,v,y) \<Longrightarrow> (AndL1 (x).M y)[u\<turnstile>n>v] = (if y=u then AndL1 (x).(M[u\<turnstile>n>v]) v else AndL1 (x).(M[u\<turnstile>n>v]) y)"
  120.99 +| "x\<sharp>(u,v,y) \<Longrightarrow> (AndL2 (x).M y)[u\<turnstile>n>v] = (if y=u then AndL2 (x).(M[u\<turnstile>n>v]) v else AndL2 (x).(M[u\<turnstile>n>v]) y)"
 120.100 +| "a\<sharp>b \<Longrightarrow> (OrR1 <a>.M b)[u\<turnstile>n>v] = OrR1 <a>.(M[u\<turnstile>n>v]) b"
 120.101 +| "a\<sharp>b \<Longrightarrow> (OrR2 <a>.M b)[u\<turnstile>n>v] = OrR2 <a>.(M[u\<turnstile>n>v]) b"
 120.102 +| "\<lbrakk>x\<sharp>(u,v,N,z);y\<sharp>(u,v,M,z);y\<noteq>x\<rbrakk> \<Longrightarrow> (OrL (x).M (y).N z)[u\<turnstile>n>v] = 
 120.103          (if z=u then OrL (x).(M[u\<turnstile>n>v]) (y).(N[u\<turnstile>n>v]) v else OrL (x).(M[u\<turnstile>n>v]) (y).(N[u\<turnstile>n>v]) z)"
 120.104 -  "\<lbrakk>a\<sharp>b; x\<sharp>(u,v)\<rbrakk> \<Longrightarrow> (ImpR (x).<a>.M b)[u\<turnstile>n>v] = ImpR (x).<a>.(M[u\<turnstile>n>v]) b"
 120.105 -  "\<lbrakk>a\<sharp>N;x\<sharp>(u,v,M,y)\<rbrakk> \<Longrightarrow> (ImpL <a>.M (x).N y)[u\<turnstile>n>v] = 
 120.106 +| "\<lbrakk>a\<sharp>b; x\<sharp>(u,v)\<rbrakk> \<Longrightarrow> (ImpR (x).<a>.M b)[u\<turnstile>n>v] = ImpR (x).<a>.(M[u\<turnstile>n>v]) b"
 120.107 +| "\<lbrakk>a\<sharp>N;x\<sharp>(u,v,M,y)\<rbrakk> \<Longrightarrow> (ImpL <a>.M (x).N y)[u\<turnstile>n>v] = 
 120.108          (if y=u then ImpL <a>.(M[u\<turnstile>n>v]) (x).(N[u\<turnstile>n>v]) v else ImpL <a>.(M[u\<turnstile>n>v]) (x).(N[u\<turnstile>n>v]) y)"
 120.109  apply(finite_guess)+
 120.110  apply(rule TrueI)+
 120.111 @@ -766,32 +770,30 @@
 120.112  apply(simp add: fin_supp)
 120.113  done
 120.114  
 120.115 -consts
 120.116 +nominal_primrec (freshness_context: "(y::name,c::coname,P::trm)")
 120.117    substn :: "trm \<Rightarrow> name   \<Rightarrow> coname \<Rightarrow> trm \<Rightarrow> trm" ("_{_:=<_>._}" [100,100,100,100] 100) 
 120.118 -  substc :: "trm \<Rightarrow> coname \<Rightarrow> name   \<Rightarrow> trm \<Rightarrow> trm" ("_{_:=(_)._}" [100,100,100,100] 100)
 120.119 -
 120.120 -nominal_primrec (freshness_context: "(y::name,c::coname,P::trm)")
 120.121 +where
 120.122    "(Ax x a){y:=<c>.P} = (if x=y then Cut <c>.P (y).Ax y a else Ax x a)" 
 120.123 -  "\<lbrakk>a\<sharp>(c,P,N);x\<sharp>(y,P,M)\<rbrakk> \<Longrightarrow> (Cut <a>.M (x).N){y:=<c>.P} = 
 120.124 +| "\<lbrakk>a\<sharp>(c,P,N);x\<sharp>(y,P,M)\<rbrakk> \<Longrightarrow> (Cut <a>.M (x).N){y:=<c>.P} = 
 120.125    (if M=Ax y a then Cut <c>.P (x).(N{y:=<c>.P}) else Cut <a>.(M{y:=<c>.P}) (x).(N{y:=<c>.P}))" 
 120.126 -  "x\<sharp>(y,P) \<Longrightarrow> (NotR (x).M a){y:=<c>.P} = NotR (x).(M{y:=<c>.P}) a" 
 120.127 -  "a\<sharp>(c,P) \<Longrightarrow> (NotL <a>.M x){y:=<c>.P} = 
 120.128 +| "x\<sharp>(y,P) \<Longrightarrow> (NotR (x).M a){y:=<c>.P} = NotR (x).(M{y:=<c>.P}) a" 
 120.129 +| "a\<sharp>(c,P) \<Longrightarrow> (NotL <a>.M x){y:=<c>.P} = 
 120.130    (if x=y then fresh_fun (\<lambda>x'. Cut <c>.P (x').NotL <a>.(M{y:=<c>.P}) x') else NotL <a>.(M{y:=<c>.P}) x)"
 120.131 -  "\<lbrakk>a\<sharp>(c,P,N,d);b\<sharp>(c,P,M,d);b\<noteq>a\<rbrakk> \<Longrightarrow> 
 120.132 +| "\<lbrakk>a\<sharp>(c,P,N,d);b\<sharp>(c,P,M,d);b\<noteq>a\<rbrakk> \<Longrightarrow> 
 120.133    (AndR <a>.M <b>.N d){y:=<c>.P} = AndR <a>.(M{y:=<c>.P}) <b>.(N{y:=<c>.P}) d" 
 120.134 -  "x\<sharp>(y,P,z) \<Longrightarrow> (AndL1 (x).M z){y:=<c>.P} = 
 120.135 +| "x\<sharp>(y,P,z) \<Longrightarrow> (AndL1 (x).M z){y:=<c>.P} = 
 120.136    (if z=y then fresh_fun (\<lambda>z'. Cut <c>.P (z').AndL1 (x).(M{y:=<c>.P}) z') 
 120.137     else AndL1 (x).(M{y:=<c>.P}) z)"
 120.138 -  "x\<sharp>(y,P,z) \<Longrightarrow> (AndL2 (x).M z){y:=<c>.P} = 
 120.139 +| "x\<sharp>(y,P,z) \<Longrightarrow> (AndL2 (x).M z){y:=<c>.P} = 
 120.140    (if z=y then fresh_fun (\<lambda>z'. Cut <c>.P (z').AndL2 (x).(M{y:=<c>.P}) z') 
 120.141     else AndL2 (x).(M{y:=<c>.P}) z)"
 120.142 -  "a\<sharp>(c,P,b) \<Longrightarrow> (OrR1 <a>.M b){y:=<c>.P} = OrR1 <a>.(M{y:=<c>.P}) b"
 120.143 -  "a\<sharp>(c,P,b) \<Longrightarrow> (OrR2 <a>.M b){y:=<c>.P} = OrR2 <a>.(M{y:=<c>.P}) b"
 120.144 -  "\<lbrakk>x\<sharp>(y,N,P,z);u\<sharp>(y,M,P,z);x\<noteq>u\<rbrakk> \<Longrightarrow> (OrL (x).M (u).N z){y:=<c>.P} = 
 120.145 +| "a\<sharp>(c,P,b) \<Longrightarrow> (OrR1 <a>.M b){y:=<c>.P} = OrR1 <a>.(M{y:=<c>.P}) b"
 120.146 +| "a\<sharp>(c,P,b) \<Longrightarrow> (OrR2 <a>.M b){y:=<c>.P} = OrR2 <a>.(M{y:=<c>.P}) b"
 120.147 +| "\<lbrakk>x\<sharp>(y,N,P,z);u\<sharp>(y,M,P,z);x\<noteq>u\<rbrakk> \<Longrightarrow> (OrL (x).M (u).N z){y:=<c>.P} = 
 120.148    (if z=y then fresh_fun (\<lambda>z'. Cut <c>.P (z').OrL (x).(M{y:=<c>.P}) (u).(N{y:=<c>.P}) z') 
 120.149     else OrL (x).(M{y:=<c>.P}) (u).(N{y:=<c>.P}) z)"
 120.150 -  "\<lbrakk>a\<sharp>(b,c,P); x\<sharp>(y,P)\<rbrakk> \<Longrightarrow> (ImpR (x).<a>.M b){y:=<c>.P} = ImpR (x).<a>.(M{y:=<c>.P}) b"
 120.151 -  "\<lbrakk>a\<sharp>(N,c,P);x\<sharp>(y,P,M,z)\<rbrakk> \<Longrightarrow> (ImpL <a>.M (x).N z){y:=<c>.P} = 
 120.152 +| "\<lbrakk>a\<sharp>(b,c,P); x\<sharp>(y,P)\<rbrakk> \<Longrightarrow> (ImpR (x).<a>.M b){y:=<c>.P} = ImpR (x).<a>.(M{y:=<c>.P}) b"
 120.153 +| "\<lbrakk>a\<sharp>(N,c,P);x\<sharp>(y,P,M,z)\<rbrakk> \<Longrightarrow> (ImpL <a>.M (x).N z){y:=<c>.P} = 
 120.154    (if y=z then fresh_fun (\<lambda>z'. Cut <c>.P (z').ImpL <a>.(M{y:=<c>.P}) (x).(N{y:=<c>.P}) z') 
 120.155     else ImpL <a>.(M{y:=<c>.P}) (x).(N{y:=<c>.P}) z)"
 120.156  apply(finite_guess)+
 120.157 @@ -842,27 +844,29 @@
 120.158  done
 120.159  
 120.160  nominal_primrec (freshness_context: "(d::name,z::coname,P::trm)")
 120.161 +  substc :: "trm \<Rightarrow> coname \<Rightarrow> name   \<Rightarrow> trm \<Rightarrow> trm" ("_{_:=(_)._}" [100,100,100,100] 100)
 120.162 +where
 120.163    "(Ax x a){d:=(z).P} = (if d=a then Cut <a>.(Ax x a) (z).P else Ax x a)" 
 120.164 -  "\<lbrakk>a\<sharp>(d,P,N);x\<sharp>(z,P,M)\<rbrakk> \<Longrightarrow> (Cut <a>.M (x).N){d:=(z).P} = 
 120.165 +| "\<lbrakk>a\<sharp>(d,P,N);x\<sharp>(z,P,M)\<rbrakk> \<Longrightarrow> (Cut <a>.M (x).N){d:=(z).P} = 
 120.166    (if N=Ax x d then Cut <a>.(M{d:=(z).P}) (z).P else Cut <a>.(M{d:=(z).P}) (x).(N{d:=(z).P}))" 
 120.167 -  "x\<sharp>(z,P) \<Longrightarrow> (NotR (x).M a){d:=(z).P} = 
 120.168 +| "x\<sharp>(z,P) \<Longrightarrow> (NotR (x).M a){d:=(z).P} = 
 120.169    (if d=a then fresh_fun (\<lambda>a'. Cut <a'>.NotR (x).(M{d:=(z).P}) a' (z).P) else NotR (x).(M{d:=(z).P}) a)" 
 120.170 -  "a\<sharp>(d,P) \<Longrightarrow> (NotL <a>.M x){d:=(z).P} = NotL <a>.(M{d:=(z).P}) x" 
 120.171 -  "\<lbrakk>a\<sharp>(P,c,N,d);b\<sharp>(P,c,M,d);b\<noteq>a\<rbrakk> \<Longrightarrow> (AndR <a>.M <b>.N c){d:=(z).P} = 
 120.172 +| "a\<sharp>(d,P) \<Longrightarrow> (NotL <a>.M x){d:=(z).P} = NotL <a>.(M{d:=(z).P}) x" 
 120.173 +| "\<lbrakk>a\<sharp>(P,c,N,d);b\<sharp>(P,c,M,d);b\<noteq>a\<rbrakk> \<Longrightarrow> (AndR <a>.M <b>.N c){d:=(z).P} = 
 120.174    (if d=c then fresh_fun (\<lambda>a'. Cut <a'>.(AndR <a>.(M{d:=(z).P}) <b>.(N{d:=(z).P}) a') (z).P)
 120.175     else AndR <a>.(M{d:=(z).P}) <b>.(N{d:=(z).P}) c)" 
 120.176 -  "x\<sharp>(y,z,P) \<Longrightarrow> (AndL1 (x).M y){d:=(z).P} = AndL1 (x).(M{d:=(z).P}) y"
 120.177 -  "x\<sharp>(y,P,z) \<Longrightarrow> (AndL2 (x).M y){d:=(z).P} = AndL2 (x).(M{d:=(z).P}) y"
 120.178 -  "a\<sharp>(d,P,b) \<Longrightarrow> (OrR1 <a>.M b){d:=(z).P} = 
 120.179 +| "x\<sharp>(y,z,P) \<Longrightarrow> (AndL1 (x).M y){d:=(z).P} = AndL1 (x).(M{d:=(z).P}) y"
 120.180 +| "x\<sharp>(y,P,z) \<Longrightarrow> (AndL2 (x).M y){d:=(z).P} = AndL2 (x).(M{d:=(z).P}) y"
 120.181 +| "a\<sharp>(d,P,b) \<Longrightarrow> (OrR1 <a>.M b){d:=(z).P} = 
 120.182    (if d=b then fresh_fun (\<lambda>a'. Cut <a'>.OrR1 <a>.(M{d:=(z).P}) a' (z).P) else OrR1 <a>.(M{d:=(z).P}) b)"
 120.183 -  "a\<sharp>(d,P,b) \<Longrightarrow> (OrR2 <a>.M b){d:=(z).P} = 
 120.184 +| "a\<sharp>(d,P,b) \<Longrightarrow> (OrR2 <a>.M b){d:=(z).P} = 
 120.185    (if d=b then fresh_fun (\<lambda>a'. Cut <a'>.OrR2 <a>.(M{d:=(z).P}) a' (z).P) else OrR2 <a>.(M{d:=(z).P}) b)"
 120.186 -  "\<lbrakk>x\<sharp>(N,z,P,u);y\<sharp>(M,z,P,u);x\<noteq>y\<rbrakk> \<Longrightarrow> (OrL (x).M (y).N u){d:=(z).P} = 
 120.187 +| "\<lbrakk>x\<sharp>(N,z,P,u);y\<sharp>(M,z,P,u);x\<noteq>y\<rbrakk> \<Longrightarrow> (OrL (x).M (y).N u){d:=(z).P} = 
 120.188    OrL (x).(M{d:=(z).P}) (y).(N{d:=(z).P}) u" 
 120.189 -  "\<lbrakk>a\<sharp>(b,d,P); x\<sharp>(z,P)\<rbrakk> \<Longrightarrow> (ImpR (x).<a>.M b){d:=(z).P} = 
 120.190 +| "\<lbrakk>a\<sharp>(b,d,P); x\<sharp>(z,P)\<rbrakk> \<Longrightarrow> (ImpR (x).<a>.M b){d:=(z).P} = 
 120.191    (if d=b then fresh_fun (\<lambda>a'. Cut <a'>.ImpR (x).<a>.(M{d:=(z).P}) a' (z).P) 
 120.192     else ImpR (x).<a>.(M{d:=(z).P}) b)"
 120.193 -  "\<lbrakk>a\<sharp>(N,d,P);x\<sharp>(y,z,P,M)\<rbrakk> \<Longrightarrow> (ImpL <a>.M (x).N y){d:=(z).P} = 
 120.194 +| "\<lbrakk>a\<sharp>(N,d,P);x\<sharp>(y,z,P,M)\<rbrakk> \<Longrightarrow> (ImpL <a>.M (x).N y){d:=(z).P} = 
 120.195    ImpL <a>.(M{d:=(z).P}) (x).(N{d:=(z).P}) y"
 120.196  apply(finite_guess)+
 120.197  apply(rule TrueI)+
 120.198 @@ -10305,11 +10309,10 @@
 120.199  lemma BINDINGc_decreasing:
 120.200    shows "X\<subseteq>Y \<Longrightarrow> BINDINGc B Y \<subseteq> BINDINGc B X"
 120.201  by (simp add: BINDINGc_def) (blast) 
 120.202 -
 120.203 -consts
 120.204 -  NOTRIGHT::"ty \<Rightarrow> ntrm set \<Rightarrow> ctrm set"
 120.205    
 120.206  nominal_primrec
 120.207 +  NOTRIGHT :: "ty \<Rightarrow> ntrm set \<Rightarrow> ctrm set"
 120.208 +where
 120.209   "NOTRIGHT (NOT B) X = { <a>:NotR (x).M a | a x M. fic (NotR (x).M a) a \<and> (x):M \<in> X }"
 120.210  apply(rule TrueI)+
 120.211  done
 120.212 @@ -10365,11 +10368,10 @@
 120.213  apply(drule pt_bij1[OF pt_coname_inst, OF at_coname_inst])
 120.214  apply(simp add: swap_simps)
 120.215  done
 120.216 -
 120.217 -consts
 120.218 -  NOTLEFT::"ty \<Rightarrow> ctrm set \<Rightarrow> ntrm set"
 120.219    
 120.220  nominal_primrec
 120.221 +  NOTLEFT :: "ty \<Rightarrow> ctrm set \<Rightarrow> ntrm set"
 120.222 +where
 120.223   "NOTLEFT (NOT B) X = { (x):NotL <a>.M x | a x M. fin (NotL <a>.M x) x \<and> <a>:M \<in> X }"
 120.224  apply(rule TrueI)+
 120.225  done
 120.226 @@ -10425,11 +10427,10 @@
 120.227  apply(drule pt_bij1[OF pt_coname_inst, OF at_coname_inst])
 120.228  apply(simp add: swap_simps)
 120.229  done
 120.230 -
 120.231 -consts
 120.232 -  ANDRIGHT::"ty \<Rightarrow> ctrm set \<Rightarrow> ctrm set \<Rightarrow> ctrm set"
 120.233    
 120.234  nominal_primrec
 120.235 +  ANDRIGHT :: "ty \<Rightarrow> ctrm set \<Rightarrow> ctrm set \<Rightarrow> ctrm set"
 120.236 +where
 120.237   "ANDRIGHT (B AND C) X Y = 
 120.238              { <c>:AndR <a>.M <b>.N c | c a b M N. fic (AndR <a>.M <b>.N c) c \<and> <a>:M \<in> X \<and> <b>:N \<in> Y }"
 120.239  apply(rule TrueI)+
 120.240 @@ -10505,10 +10506,9 @@
 120.241  apply(simp)
 120.242  done
 120.243  
 120.244 -consts
 120.245 -  ANDLEFT1::"ty \<Rightarrow> ntrm set \<Rightarrow> ntrm set"
 120.246 -
 120.247  nominal_primrec
 120.248 +  ANDLEFT1 :: "ty \<Rightarrow> ntrm set \<Rightarrow> ntrm set"
 120.249 +where
 120.250   "ANDLEFT1 (B AND C) X = { (y):AndL1 (x).M y | x y M. fin (AndL1 (x).M y) y \<and> (x):M \<in> X }"
 120.251  apply(rule TrueI)+
 120.252  done
 120.253 @@ -10565,10 +10565,9 @@
 120.254  apply(simp add: swap_simps)
 120.255  done
 120.256  
 120.257 -consts
 120.258 -  ANDLEFT2::"ty \<Rightarrow> ntrm set \<Rightarrow> ntrm set"
 120.259 -
 120.260  nominal_primrec
 120.261 +  ANDLEFT2 :: "ty \<Rightarrow> ntrm set \<Rightarrow> ntrm set"
 120.262 +where
 120.263   "ANDLEFT2 (B AND C) X = { (y):AndL2 (x).M y | x y M. fin (AndL2 (x).M y) y \<and> (x):M \<in> X }"
 120.264  apply(rule TrueI)+
 120.265  done
 120.266 @@ -10625,10 +10624,9 @@
 120.267  apply(simp add: swap_simps)
 120.268  done
 120.269  
 120.270 -consts
 120.271 -  ORLEFT::"ty \<Rightarrow> ntrm set \<Rightarrow> ntrm set \<Rightarrow> ntrm set"
 120.272 -  
 120.273  nominal_primrec
 120.274 +  ORLEFT :: "ty \<Rightarrow> ntrm set \<Rightarrow> ntrm set \<Rightarrow> ntrm set"
 120.275 +where
 120.276   "ORLEFT (B OR C) X Y = 
 120.277              { (z):OrL (x).M (y).N z | x y z M N. fin (OrL (x).M (y).N z) z \<and> (x):M \<in> X \<and> (y):N \<in> Y }"
 120.278  apply(rule TrueI)+
 120.279 @@ -10704,10 +10702,9 @@
 120.280  apply(simp add: swap_simps)
 120.281  done
 120.282  
 120.283 -consts
 120.284 -  ORRIGHT1::"ty \<Rightarrow> ctrm set \<Rightarrow> ctrm set"
 120.285 -
 120.286  nominal_primrec
 120.287 +  ORRIGHT1 :: "ty \<Rightarrow> ctrm set \<Rightarrow> ctrm set"
 120.288 +where
 120.289   "ORRIGHT1 (B OR C) X = { <b>:OrR1 <a>.M b | a b M. fic (OrR1 <a>.M b) b \<and> <a>:M \<in> X }"
 120.290  apply(rule TrueI)+
 120.291  done
 120.292 @@ -10764,10 +10761,9 @@
 120.293  apply(simp)
 120.294  done
 120.295  
 120.296 -consts
 120.297 -  ORRIGHT2::"ty \<Rightarrow> ctrm set \<Rightarrow> ctrm set"
 120.298 -
 120.299  nominal_primrec
 120.300 +  ORRIGHT2 :: "ty \<Rightarrow> ctrm set \<Rightarrow> ctrm set"
 120.301 +where
 120.302   "ORRIGHT2 (B OR C) X = { <b>:OrR2 <a>.M b | a b M. fic (OrR2 <a>.M b) b \<and> <a>:M \<in> X }"
 120.303  apply(rule TrueI)+
 120.304  done
 120.305 @@ -10824,10 +10820,9 @@
 120.306  apply(simp)
 120.307  done
 120.308  
 120.309 -consts
 120.310 -  IMPRIGHT::"ty \<Rightarrow> ntrm set \<Rightarrow> ctrm set \<Rightarrow> ntrm set \<Rightarrow> ctrm set \<Rightarrow> ctrm set"
 120.311 -
 120.312  nominal_primrec
 120.313 +  IMPRIGHT :: "ty \<Rightarrow> ntrm set \<Rightarrow> ctrm set \<Rightarrow> ntrm set \<Rightarrow> ctrm set \<Rightarrow> ctrm set"
 120.314 +where
 120.315   "IMPRIGHT (B IMP C) X Y Z U= 
 120.316          { <b>:ImpR (x).<a>.M b | x a b M. fic (ImpR (x).<a>.M b) b 
 120.317                                          \<and> (\<forall>z P. x\<sharp>(z,P) \<and> (z):P \<in> Z \<longrightarrow> (x):(M{a:=(z).P}) \<in> X)
 120.318 @@ -10954,10 +10949,9 @@
 120.319  apply(perm_simp add: nsubst_eqvt fresh_right)
 120.320  done
 120.321  
 120.322 -consts
 120.323 -  IMPLEFT::"ty \<Rightarrow> ctrm set \<Rightarrow> ntrm set \<Rightarrow> ntrm set"
 120.324 -
 120.325  nominal_primrec
 120.326 +  IMPLEFT :: "ty \<Rightarrow> ctrm set \<Rightarrow> ntrm set \<Rightarrow> ntrm set"
 120.327 +where
 120.328   "IMPLEFT (B IMP C) X Y = 
 120.329          { (y):ImpL <a>.M (x).N y | x a y M N. fin (ImpL <a>.M (x).N y) y \<and> <a>:M \<in> X \<and> (x):N \<in> Y }"
 120.330  apply(rule TrueI)+
 120.331 @@ -17800,23 +17794,21 @@
 120.332  apply(auto)
 120.333  done 
 120.334  
 120.335 -consts
 120.336 +nominal_primrec (freshness_context: "\<theta>n::(name\<times>coname\<times>trm)")
 120.337    stn :: "trm\<Rightarrow>(name\<times>coname\<times>trm) list\<Rightarrow>trm" 
 120.338 -  stc :: "trm\<Rightarrow>(coname\<times>name\<times>trm) list\<Rightarrow>trm" 
 120.339 -
 120.340 -nominal_primrec (freshness_context: "\<theta>n::(name\<times>coname\<times>trm)")
 120.341 +where
 120.342    "stn (Ax x a) \<theta>n = lookupc x a \<theta>n"
 120.343 -  "\<lbrakk>a\<sharp>(N,\<theta>n);x\<sharp>(M,\<theta>n)\<rbrakk> \<Longrightarrow> stn (Cut <a>.M (x).N) \<theta>n = (Cut <a>.M (x).N)" 
 120.344 -  "x\<sharp>\<theta>n \<Longrightarrow> stn (NotR (x).M a) \<theta>n = (NotR (x).M a)"
 120.345 -  "a\<sharp>\<theta>n \<Longrightarrow>stn (NotL <a>.M x) \<theta>n = (NotL <a>.M x)"
 120.346 -  "\<lbrakk>a\<sharp>(N,d,b,\<theta>n);b\<sharp>(M,d,a,\<theta>n)\<rbrakk> \<Longrightarrow> stn (AndR <a>.M <b>.N d) \<theta>n = (AndR <a>.M <b>.N d)"
 120.347 -  "x\<sharp>(z,\<theta>n) \<Longrightarrow> stn (AndL1 (x).M z) \<theta>n = (AndL1 (x).M z)"
 120.348 -  "x\<sharp>(z,\<theta>n) \<Longrightarrow> stn (AndL2 (x).M z) \<theta>n = (AndL2 (x).M z)"
 120.349 -  "a\<sharp>(b,\<theta>n) \<Longrightarrow> stn (OrR1 <a>.M b) \<theta>n = (OrR1 <a>.M b)"
 120.350 -  "a\<sharp>(b,\<theta>n) \<Longrightarrow> stn (OrR2 <a>.M b) \<theta>n = (OrR2 <a>.M b)"
 120.351 -  "\<lbrakk>x\<sharp>(N,z,u,\<theta>n);u\<sharp>(M,z,x,\<theta>n)\<rbrakk> \<Longrightarrow> stn (OrL (x).M (u).N z) \<theta>n = (OrL (x).M (u).N z)"
 120.352 -  "\<lbrakk>a\<sharp>(b,\<theta>n);x\<sharp>\<theta>n\<rbrakk> \<Longrightarrow> stn (ImpR (x).<a>.M b) \<theta>n = (ImpR (x).<a>.M b)"
 120.353 -  "\<lbrakk>a\<sharp>(N,\<theta>n);x\<sharp>(M,z,\<theta>n)\<rbrakk> \<Longrightarrow> stn (ImpL <a>.M (x).N z) \<theta>n = (ImpL <a>.M (x).N z)"
 120.354 +| "\<lbrakk>a\<sharp>(N,\<theta>n);x\<sharp>(M,\<theta>n)\<rbrakk> \<Longrightarrow> stn (Cut <a>.M (x).N) \<theta>n = (Cut <a>.M (x).N)" 
 120.355 +| "x\<sharp>\<theta>n \<Longrightarrow> stn (NotR (x).M a) \<theta>n = (NotR (x).M a)"
 120.356 +| "a\<sharp>\<theta>n \<Longrightarrow>stn (NotL <a>.M x) \<theta>n = (NotL <a>.M x)"
 120.357 +| "\<lbrakk>a\<sharp>(N,d,b,\<theta>n);b\<sharp>(M,d,a,\<theta>n)\<rbrakk> \<Longrightarrow> stn (AndR <a>.M <b>.N d) \<theta>n = (AndR <a>.M <b>.N d)"
 120.358 +| "x\<sharp>(z,\<theta>n) \<Longrightarrow> stn (AndL1 (x).M z) \<theta>n = (AndL1 (x).M z)"
 120.359 +| "x\<sharp>(z,\<theta>n) \<Longrightarrow> stn (AndL2 (x).M z) \<theta>n = (AndL2 (x).M z)"
 120.360 +| "a\<sharp>(b,\<theta>n) \<Longrightarrow> stn (OrR1 <a>.M b) \<theta>n = (OrR1 <a>.M b)"
 120.361 +| "a\<sharp>(b,\<theta>n) \<Longrightarrow> stn (OrR2 <a>.M b) \<theta>n = (OrR2 <a>.M b)"
 120.362 +| "\<lbrakk>x\<sharp>(N,z,u,\<theta>n);u\<sharp>(M,z,x,\<theta>n)\<rbrakk> \<Longrightarrow> stn (OrL (x).M (u).N z) \<theta>n = (OrL (x).M (u).N z)"
 120.363 +| "\<lbrakk>a\<sharp>(b,\<theta>n);x\<sharp>\<theta>n\<rbrakk> \<Longrightarrow> stn (ImpR (x).<a>.M b) \<theta>n = (ImpR (x).<a>.M b)"
 120.364 +| "\<lbrakk>a\<sharp>(N,\<theta>n);x\<sharp>(M,z,\<theta>n)\<rbrakk> \<Longrightarrow> stn (ImpL <a>.M (x).N z) \<theta>n = (ImpL <a>.M (x).N z)"
 120.365  apply(finite_guess)+
 120.366  apply(rule TrueI)+
 120.367  apply(simp add: abs_fresh abs_supp fin_supp)+
 120.368 @@ -17824,18 +17816,20 @@
 120.369  done
 120.370  
 120.371  nominal_primrec (freshness_context: "\<theta>c::(coname\<times>name\<times>trm)")
 120.372 +  stc :: "trm\<Rightarrow>(coname\<times>name\<times>trm) list\<Rightarrow>trm" 
 120.373 +where
 120.374    "stc (Ax x a) \<theta>c = lookupd x a \<theta>c"
 120.375 -  "\<lbrakk>a\<sharp>(N,\<theta>c);x\<sharp>(M,\<theta>c)\<rbrakk> \<Longrightarrow> stc (Cut <a>.M (x).N) \<theta>c = (Cut <a>.M (x).N)" 
 120.376 -  "x\<sharp>\<theta>c \<Longrightarrow> stc (NotR (x).M a) \<theta>c = (NotR (x).M a)"
 120.377 -  "a\<sharp>\<theta>c \<Longrightarrow> stc (NotL <a>.M x) \<theta>c = (NotL <a>.M x)"
 120.378 -  "\<lbrakk>a\<sharp>(N,d,b,\<theta>c);b\<sharp>(M,d,a,\<theta>c)\<rbrakk> \<Longrightarrow> stc (AndR <a>.M <b>.N d) \<theta>c = (AndR <a>.M <b>.N d)"
 120.379 -  "x\<sharp>(z,\<theta>c) \<Longrightarrow> stc (AndL1 (x).M z) \<theta>c = (AndL1 (x).M z)"
 120.380 -  "x\<sharp>(z,\<theta>c) \<Longrightarrow> stc (AndL2 (x).M z) \<theta>c = (AndL2 (x).M z)"
 120.381 -  "a\<sharp>(b,\<theta>c) \<Longrightarrow> stc (OrR1 <a>.M b) \<theta>c = (OrR1 <a>.M b)"
 120.382 -  "a\<sharp>(b,\<theta>c) \<Longrightarrow> stc (OrR2 <a>.M b) \<theta>c = (OrR2 <a>.M b)"
 120.383 -  "\<lbrakk>x\<sharp>(N,z,u,\<theta>c);u\<sharp>(M,z,x,\<theta>c)\<rbrakk> \<Longrightarrow> stc (OrL (x).M (u).N z) \<theta>c = (OrL (x).M (u).N z)"
 120.384 -  "\<lbrakk>a\<sharp>(b,\<theta>c);x\<sharp>\<theta>c\<rbrakk> \<Longrightarrow> stc (ImpR (x).<a>.M b) \<theta>c = (ImpR (x).<a>.M b)"
 120.385 -  "\<lbrakk>a\<sharp>(N,\<theta>c);x\<sharp>(M,z,\<theta>c)\<rbrakk> \<Longrightarrow> stc (ImpL <a>.M (x).N z) \<theta>c = (ImpL <a>.M (x).N z)"
 120.386 +| "\<lbrakk>a\<sharp>(N,\<theta>c);x\<sharp>(M,\<theta>c)\<rbrakk> \<Longrightarrow> stc (Cut <a>.M (x).N) \<theta>c = (Cut <a>.M (x).N)" 
 120.387 +| "x\<sharp>\<theta>c \<Longrightarrow> stc (NotR (x).M a) \<theta>c = (NotR (x).M a)"
 120.388 +| "a\<sharp>\<theta>c \<Longrightarrow> stc (NotL <a>.M x) \<theta>c = (NotL <a>.M x)"
 120.389 +| "\<lbrakk>a\<sharp>(N,d,b,\<theta>c);b\<sharp>(M,d,a,\<theta>c)\<rbrakk> \<Longrightarrow> stc (AndR <a>.M <b>.N d) \<theta>c = (AndR <a>.M <b>.N d)"
 120.390 +| "x\<sharp>(z,\<theta>c) \<Longrightarrow> stc (AndL1 (x).M z) \<theta>c = (AndL1 (x).M z)"
 120.391 +| "x\<sharp>(z,\<theta>c) \<Longrightarrow> stc (AndL2 (x).M z) \<theta>c = (AndL2 (x).M z)"
 120.392 +| "a\<sharp>(b,\<theta>c) \<Longrightarrow> stc (OrR1 <a>.M b) \<theta>c = (OrR1 <a>.M b)"
 120.393 +| "a\<sharp>(b,\<theta>c) \<Longrightarrow> stc (OrR2 <a>.M b) \<theta>c = (OrR2 <a>.M b)"
 120.394 +| "\<lbrakk>x\<sharp>(N,z,u,\<theta>c);u\<sharp>(M,z,x,\<theta>c)\<rbrakk> \<Longrightarrow> stc (OrL (x).M (u).N z) \<theta>c = (OrL (x).M (u).N z)"
 120.395 +| "\<lbrakk>a\<sharp>(b,\<theta>c);x\<sharp>\<theta>c\<rbrakk> \<Longrightarrow> stc (ImpR (x).<a>.M b) \<theta>c = (ImpR (x).<a>.M b)"
 120.396 +| "\<lbrakk>a\<sharp>(N,\<theta>c);x\<sharp>(M,z,\<theta>c)\<rbrakk> \<Longrightarrow> stc (ImpL <a>.M (x).N z) \<theta>c = (ImpL <a>.M (x).N z)"
 120.397  apply(finite_guess)+
 120.398  apply(rule TrueI)+
 120.399  apply(simp add: abs_fresh abs_supp fin_supp)+
 120.400 @@ -17926,51 +17920,50 @@
 120.401  apply(perm_simp)
 120.402  done
 120.403  
 120.404 -consts
 120.405 +nominal_primrec (freshness_context: "(\<theta>n::(name\<times>coname\<times>trm) list,\<theta>c::(coname\<times>name\<times>trm) list)")
 120.406    psubst :: "(name\<times>coname\<times>trm) list\<Rightarrow>(coname\<times>name\<times>trm) list\<Rightarrow>trm\<Rightarrow>trm" ("_,_<_>" [100,100,100] 100) 
 120.407 -
 120.408 -nominal_primrec (freshness_context: "(\<theta>n::(name\<times>coname\<times>trm) list,\<theta>c::(coname\<times>name\<times>trm) list)")
 120.409 +where
 120.410    "\<theta>n,\<theta>c<Ax x a> = lookup x a \<theta>n \<theta>c" 
 120.411 -  "\<lbrakk>a\<sharp>(N,\<theta>n,\<theta>c);x\<sharp>(M,\<theta>n,\<theta>c)\<rbrakk> \<Longrightarrow> \<theta>n,\<theta>c<Cut <a>.M (x).N> = 
 120.412 +| "\<lbrakk>a\<sharp>(N,\<theta>n,\<theta>c);x\<sharp>(M,\<theta>n,\<theta>c)\<rbrakk> \<Longrightarrow> \<theta>n,\<theta>c<Cut <a>.M (x).N> = 
 120.413     Cut <a>.(if \<exists>x. M=Ax x a then stn M \<theta>n else \<theta>n,\<theta>c<M>) 
 120.414         (x).(if \<exists>a. N=Ax x a then stc N \<theta>c else \<theta>n,\<theta>c<N>)" 
 120.415 -  "x\<sharp>(\<theta>n,\<theta>c) \<Longrightarrow> \<theta>n,\<theta>c<NotR (x).M a> = 
 120.416 +| "x\<sharp>(\<theta>n,\<theta>c) \<Longrightarrow> \<theta>n,\<theta>c<NotR (x).M a> = 
 120.417    (case (findc \<theta>c a) of 
 120.418         Some (u,P) \<Rightarrow> fresh_fun (\<lambda>a'. Cut <a'>.NotR (x).(\<theta>n,\<theta>c<M>) a' (u).P) 
 120.419       | None \<Rightarrow> NotR (x).(\<theta>n,\<theta>c<M>) a)"
 120.420 -  "a\<sharp>(\<theta>n,\<theta>c) \<Longrightarrow> \<theta>n,\<theta>c<NotL <a>.M x> = 
 120.421 +| "a\<sharp>(\<theta>n,\<theta>c) \<Longrightarrow> \<theta>n,\<theta>c<NotL <a>.M x> = 
 120.422    (case (findn \<theta>n x) of 
 120.423         Some (c,P) \<Rightarrow> fresh_fun (\<lambda>x'. Cut <c>.P (x').(NotL <a>.(\<theta>n,\<theta>c<M>) x')) 
 120.424       | None \<Rightarrow> NotL <a>.(\<theta>n,\<theta>c<M>) x)"
 120.425 -  "\<lbrakk>a\<sharp>(N,c,\<theta>n,\<theta>c);b\<sharp>(M,c,\<theta>n,\<theta>c);b\<noteq>a\<rbrakk> \<Longrightarrow> (\<theta>n,\<theta>c<AndR <a>.M <b>.N c>) = 
 120.426 +| "\<lbrakk>a\<sharp>(N,c,\<theta>n,\<theta>c);b\<sharp>(M,c,\<theta>n,\<theta>c);b\<noteq>a\<rbrakk> \<Longrightarrow> (\<theta>n,\<theta>c<AndR <a>.M <b>.N c>) = 
 120.427    (case (findc \<theta>c c) of 
 120.428         Some (x,P) \<Rightarrow> fresh_fun (\<lambda>a'. Cut <a'>.(AndR <a>.(\<theta>n,\<theta>c<M>) <b>.(\<theta>n,\<theta>c<N>) a') (x).P)
 120.429       | None \<Rightarrow> AndR <a>.(\<theta>n,\<theta>c<M>) <b>.(\<theta>n,\<theta>c<N>) c)"
 120.430 -  "x\<sharp>(z,\<theta>n,\<theta>c) \<Longrightarrow> (\<theta>n,\<theta>c<AndL1 (x).M z>) = 
 120.431 +| "x\<sharp>(z,\<theta>n,\<theta>c) \<Longrightarrow> (\<theta>n,\<theta>c<AndL1 (x).M z>) = 
 120.432    (case (findn \<theta>n z) of 
 120.433         Some (c,P) \<Rightarrow> fresh_fun (\<lambda>z'. Cut <c>.P (z').AndL1 (x).(\<theta>n,\<theta>c<M>) z') 
 120.434       | None \<Rightarrow> AndL1 (x).(\<theta>n,\<theta>c<M>) z)"
 120.435 -  "x\<sharp>(z,\<theta>n,\<theta>c) \<Longrightarrow> (\<theta>n,\<theta>c<AndL2 (x).M z>) = 
 120.436 +| "x\<sharp>(z,\<theta>n,\<theta>c) \<Longrightarrow> (\<theta>n,\<theta>c<AndL2 (x).M z>) = 
 120.437    (case (findn \<theta>n z) of 
 120.438         Some (c,P) \<Rightarrow> fresh_fun (\<lambda>z'. Cut <c>.P (z').AndL2 (x).(\<theta>n,\<theta>c<M>) z') 
 120.439       | None \<Rightarrow> AndL2 (x).(\<theta>n,\<theta>c<M>) z)"
 120.440 -  "\<lbrakk>x\<sharp>(N,z,\<theta>n,\<theta>c);u\<sharp>(M,z,\<theta>n,\<theta>c);x\<noteq>u\<rbrakk> \<Longrightarrow> (\<theta>n,\<theta>c<OrL (x).M (u).N z>) =
 120.441 +| "\<lbrakk>x\<sharp>(N,z,\<theta>n,\<theta>c);u\<sharp>(M,z,\<theta>n,\<theta>c);x\<noteq>u\<rbrakk> \<Longrightarrow> (\<theta>n,\<theta>c<OrL (x).M (u).N z>) =
 120.442    (case (findn \<theta>n z) of  
 120.443         Some (c,P) \<Rightarrow> fresh_fun (\<lambda>z'. Cut <c>.P (z').OrL (x).(\<theta>n,\<theta>c<M>) (u).(\<theta>n,\<theta>c<N>) z') 
 120.444       | None \<Rightarrow> OrL (x).(\<theta>n,\<theta>c<M>) (u).(\<theta>n,\<theta>c<N>) z)"
 120.445 -  "a\<sharp>(b,\<theta>n,\<theta>c) \<Longrightarrow> (\<theta>n,\<theta>c<OrR1 <a>.M b>) = 
 120.446 +| "a\<sharp>(b,\<theta>n,\<theta>c) \<Longrightarrow> (\<theta>n,\<theta>c<OrR1 <a>.M b>) = 
 120.447    (case (findc \<theta>c b) of
 120.448         Some (x,P) \<Rightarrow> fresh_fun (\<lambda>a'. Cut <a'>.OrR1 <a>.(\<theta>n,\<theta>c<M>) a' (x).P) 
 120.449       | None \<Rightarrow> OrR1 <a>.(\<theta>n,\<theta>c<M>) b)"
 120.450 -  "a\<sharp>(b,\<theta>n,\<theta>c) \<Longrightarrow> (\<theta>n,\<theta>c<OrR2 <a>.M b>) = 
 120.451 +| "a\<sharp>(b,\<theta>n,\<theta>c) \<Longrightarrow> (\<theta>n,\<theta>c<OrR2 <a>.M b>) = 
 120.452    (case (findc \<theta>c b) of
 120.453         Some (x,P) \<Rightarrow> fresh_fun (\<lambda>a'. Cut <a'>.OrR2 <a>.(\<theta>n,\<theta>c<M>) a' (x).P) 
 120.454       | None \<Rightarrow> OrR2 <a>.(\<theta>n,\<theta>c<M>) b)"
 120.455 -  "\<lbrakk>a\<sharp>(b,\<theta>n,\<theta>c); x\<sharp>(\<theta>n,\<theta>c)\<rbrakk> \<Longrightarrow> (\<theta>n,\<theta>c<ImpR (x).<a>.M b>) = 
 120.456 +| "\<lbrakk>a\<sharp>(b,\<theta>n,\<theta>c); x\<sharp>(\<theta>n,\<theta>c)\<rbrakk> \<Longrightarrow> (\<theta>n,\<theta>c<ImpR (x).<a>.M b>) = 
 120.457    (case (findc \<theta>c b) of
 120.458         Some (z,P) \<Rightarrow> fresh_fun (\<lambda>a'. Cut <a'>.ImpR (x).<a>.(\<theta>n,\<theta>c<M>) a' (z).P)
 120.459       | None \<Rightarrow> ImpR (x).<a>.(\<theta>n,\<theta>c<M>) b)"
 120.460 -  "\<lbrakk>a\<sharp>(N,\<theta>n,\<theta>c); x\<sharp>(z,M,\<theta>n,\<theta>c)\<rbrakk> \<Longrightarrow> (\<theta>n,\<theta>c<ImpL <a>.M (x).N z>) = 
 120.461 +| "\<lbrakk>a\<sharp>(N,\<theta>n,\<theta>c); x\<sharp>(z,M,\<theta>n,\<theta>c)\<rbrakk> \<Longrightarrow> (\<theta>n,\<theta>c<ImpL <a>.M (x).N z>) = 
 120.462    (case (findn \<theta>n z) of
 120.463         Some (c,P) \<Rightarrow> fresh_fun (\<lambda>z'. Cut <c>.P (z').ImpL <a>.(\<theta>n,\<theta>c<M>) (x).(\<theta>n,\<theta>c<N>) z') 
 120.464       | None \<Rightarrow> ImpL <a>.(\<theta>n,\<theta>c<M>) (x).(\<theta>n,\<theta>c<N>) z)"
   121.1 --- a/src/HOL/Nominal/Examples/Compile.thy	Tue Dec 30 08:18:54 2008 +0100
   121.2 +++ b/src/HOL/Nominal/Examples/Compile.thy	Tue Dec 30 11:10:01 2008 +0100
   121.3 @@ -1,5 +1,3 @@
   121.4 -(* $Id$ *)
   121.5 -
   121.6  (* The definitions for a challenge suggested by Adam Chlipala *)
   121.7  
   121.8  theory Compile
   121.9 @@ -92,20 +90,24 @@
  121.10  
  121.11  text {* capture-avoiding substitution *}
  121.12  
  121.13 -consts
  121.14 -  subst :: "'a \<Rightarrow> name \<Rightarrow> 'a \<Rightarrow> 'a"  ("_[_::=_]" [100,100,100] 100)
  121.15 +class subst =
  121.16 +  fixes subst :: "'a \<Rightarrow> name \<Rightarrow> 'a \<Rightarrow> 'a"  ("_[_::=_]" [100,100,100] 100)
  121.17  
  121.18 -nominal_primrec
  121.19 +instantiation trm :: subst
  121.20 +begin
  121.21 +
  121.22 +nominal_primrec subst_trm
  121.23 +where
  121.24    "(Var x)[y::=t'] = (if x=y then t' else (Var x))"
  121.25 -  "(App t1 t2)[y::=t'] = App (t1[y::=t']) (t2[y::=t'])"
  121.26 -  "\<lbrakk>x\<sharp>y; x\<sharp>t'\<rbrakk> \<Longrightarrow> (Lam [x].t)[y::=t'] = Lam [x].(t[y::=t'])"
  121.27 -  "(Const n)[y::=t'] = Const n"
  121.28 -  "(Pr e1 e2)[y::=t'] = Pr (e1[y::=t']) (e2[y::=t'])"
  121.29 -  "(Fst e)[y::=t'] = Fst (e[y::=t'])"
  121.30 -  "(Snd e)[y::=t'] = Snd (e[y::=t'])"
  121.31 -  "(InL e)[y::=t'] = InL (e[y::=t'])"
  121.32 -  "(InR e)[y::=t'] = InR (e[y::=t'])"
  121.33 -  "\<lbrakk>z\<noteq>x; x\<sharp>y; x\<sharp>e; x\<sharp>e2; z\<sharp>y; z\<sharp>e; z\<sharp>e1; x\<sharp>t'; z\<sharp>t'\<rbrakk> \<Longrightarrow>
  121.34 +| "(App t1 t2)[y::=t'] = App (t1[y::=t']) (t2[y::=t'])"
  121.35 +| "\<lbrakk>x\<sharp>y; x\<sharp>t'\<rbrakk> \<Longrightarrow> (Lam [x].t)[y::=t'] = Lam [x].(t[y::=t'])"
  121.36 +| "(Const n)[y::=t'] = Const n"
  121.37 +| "(Pr e1 e2)[y::=t'] = Pr (e1[y::=t']) (e2[y::=t'])"
  121.38 +| "(Fst e)[y::=t'] = Fst (e[y::=t'])"
  121.39 +| "(Snd e)[y::=t'] = Snd (e[y::=t'])"
  121.40 +| "(InL e)[y::=t'] = InL (e[y::=t'])"
  121.41 +| "(InR e)[y::=t'] = InR (e[y::=t'])"
  121.42 +| "\<lbrakk>z\<noteq>x; x\<sharp>y; x\<sharp>e; x\<sharp>e2; z\<sharp>y; z\<sharp>e; z\<sharp>e1; x\<sharp>t'; z\<sharp>t'\<rbrakk> \<Longrightarrow>
  121.43       (Case e of inl x \<rightarrow> e1 | inr z \<rightarrow> e2)[y::=t'] =
  121.44         (Case (e[y::=t']) of inl x \<rightarrow> (e1[y::=t']) | inr z \<rightarrow> (e2[y::=t']))"
  121.45    apply(finite_guess)+
  121.46 @@ -114,23 +116,35 @@
  121.47    apply(fresh_guess)+
  121.48    done
  121.49  
  121.50 -nominal_primrec (Isubst)
  121.51 +instance ..
  121.52 +
  121.53 +end
  121.54 +
  121.55 +instantiation trmI :: subst
  121.56 +begin
  121.57 +
  121.58 +nominal_primrec subst_trmI
  121.59 +where
  121.60    "(IVar x)[y::=t'] = (if x=y then t' else (IVar x))"
  121.61 -  "(IApp t1 t2)[y::=t'] = IApp (t1[y::=t']) (t2[y::=t'])"
  121.62 -  "\<lbrakk>x\<sharp>y; x\<sharp>t'\<rbrakk> \<Longrightarrow> (ILam [x].t)[y::=t'] = ILam [x].(t[y::=t'])"
  121.63 -  "(INat n)[y::=t'] = INat n"
  121.64 -  "(IUnit)[y::=t'] = IUnit"
  121.65 -  "(ISucc e)[y::=t'] = ISucc (e[y::=t'])"
  121.66 -  "(IAss e1 e2)[y::=t'] = IAss (e1[y::=t']) (e2[y::=t'])"
  121.67 -  "(IRef e)[y::=t'] = IRef (e[y::=t'])"
  121.68 -  "(ISeq e1 e2)[y::=t'] = ISeq (e1[y::=t']) (e2[y::=t'])"
  121.69 -  "(Iif e e1 e2)[y::=t'] = Iif (e[y::=t']) (e1[y::=t']) (e2[y::=t'])"
  121.70 +| "(IApp t1 t2)[y::=t'] = IApp (t1[y::=t']) (t2[y::=t'])"
  121.71 +| "\<lbrakk>x\<sharp>y; x\<sharp>t'\<rbrakk> \<Longrightarrow> (ILam [x].t)[y::=t'] = ILam [x].(t[y::=t'])"
  121.72 +| "(INat n)[y::=t'] = INat n"
  121.73 +| "(IUnit)[y::=t'] = IUnit"
  121.74 +| "(ISucc e)[y::=t'] = ISucc (e[y::=t'])"
  121.75 +| "(IAss e1 e2)[y::=t'] = IAss (e1[y::=t']) (e2[y::=t'])"
  121.76 +| "(IRef e)[y::=t'] = IRef (e[y::=t'])"
  121.77 +| "(ISeq e1 e2)[y::=t'] = ISeq (e1[y::=t']) (e2[y::=t'])"
  121.78 +| "(Iif e e1 e2)[y::=t'] = Iif (e[y::=t']) (e1[y::=t']) (e2[y::=t'])"
  121.79    apply(finite_guess)+
  121.80    apply(rule TrueI)+
  121.81    apply(simp add: abs_fresh)+
  121.82    apply(fresh_guess)+
  121.83    done
  121.84  
  121.85 +instance ..
  121.86 +
  121.87 +end
  121.88 +
  121.89  lemma Isubst_eqvt[eqvt]:
  121.90    fixes pi::"name prm"
  121.91    and   t1::"trmI"
  121.92 @@ -138,7 +152,7 @@
  121.93    and   x::"name"
  121.94    shows "pi\<bullet>(t1[x::=t2]) = ((pi\<bullet>t1)[(pi\<bullet>x)::=(pi\<bullet>t2)])"
  121.95    apply (nominal_induct t1 avoiding: x t2 rule: trmI.strong_induct)
  121.96 -  apply (simp_all add: Isubst.simps eqvts fresh_bij)
  121.97 +  apply (simp_all add: subst_trmI.simps eqvts fresh_bij)
  121.98    done
  121.99  
 121.100  lemma Isubst_supp:
 121.101 @@ -147,7 +161,7 @@
 121.102    and   x::"name"
 121.103    shows "((supp (t1[x::=t2]))::name set) \<subseteq> (supp t2)\<union>((supp t1)-{x})"
 121.104    apply (nominal_induct t1 avoiding: x t2 rule: trmI.strong_induct)
 121.105 -  apply (auto simp add: Isubst.simps trmI.supp supp_atm abs_supp supp_nat)
 121.106 +  apply (auto simp add: subst_trmI.simps trmI.supp supp_atm abs_supp supp_nat)
 121.107    apply blast+
 121.108    done
 121.109  
 121.110 @@ -198,29 +212,29 @@
 121.111  
 121.112  text {* Translation functions *}
 121.113  
 121.114 -consts trans :: "trm \<Rightarrow> trmI" 
 121.115 -
 121.116  nominal_primrec
 121.117 +  trans :: "trm \<Rightarrow> trmI"
 121.118 +where
 121.119    "trans (Var x) = (IVar x)"
 121.120 -  "trans (App e1 e2) = IApp (trans e1) (trans e2)"
 121.121 -  "trans (Lam [x].e) = ILam [x].(trans e)"
 121.122 -  "trans (Const n) = INat n"
 121.123 -  "trans (Pr e1 e2) = 
 121.124 +| "trans (App e1 e2) = IApp (trans e1) (trans e2)"
 121.125 +| "trans (Lam [x].e) = ILam [x].(trans e)"
 121.126 +| "trans (Const n) = INat n"
 121.127 +| "trans (Pr e1 e2) = 
 121.128         (let limit = IRef(INat 0) in 
 121.129          let v1 = (trans e1) in 
 121.130          let v2 = (trans e2) in 
 121.131          (((ISucc limit)\<mapsto>v1);;(ISucc(ISucc limit)\<mapsto>v2));;(INat 0 \<mapsto> ISucc(ISucc(limit))))"
 121.132 -  "trans (Fst e) = IRef (ISucc (trans e))"
 121.133 -  "trans (Snd e) = IRef (ISucc (ISucc (trans e)))"
 121.134 -  "trans (InL e) = 
 121.135 +| "trans (Fst e) = IRef (ISucc (trans e))"
 121.136 +| "trans (Snd e) = IRef (ISucc (ISucc (trans e)))"
 121.137 +| "trans (InL e) = 
 121.138          (let limit = IRef(INat 0) in 
 121.139           let v = (trans e) in 
 121.140           (((ISucc limit)\<mapsto>INat(0));;(ISucc(ISucc limit)\<mapsto>v));;(INat 0 \<mapsto> ISucc(ISucc(limit))))"
 121.141 -  "trans (InR e) = 
 121.142 +| "trans (InR e) = 
 121.143          (let limit = IRef(INat 0) in 
 121.144           let v = (trans e) in 
 121.145           (((ISucc limit)\<mapsto>INat(1));;(ISucc(ISucc limit)\<mapsto>v));;(INat 0 \<mapsto> ISucc(ISucc(limit))))"
 121.146 -  "\<lbrakk>x2\<noteq>x1; x1\<sharp>e; x1\<sharp>e2; x2\<sharp>e; x2\<sharp>e1\<rbrakk> \<Longrightarrow> 
 121.147 +| "\<lbrakk>x2\<noteq>x1; x1\<sharp>e; x1\<sharp>e2; x2\<sharp>e; x2\<sharp>e1\<rbrakk> \<Longrightarrow> 
 121.148     trans (Case e of inl x1 \<rightarrow> e1 | inr x2 \<rightarrow> e2) =
 121.149         (let v = (trans e) in
 121.150          let v1 = (trans e1) in
 121.151 @@ -232,11 +246,11 @@
 121.152    apply(fresh_guess add: Let_def)+
 121.153    done
 121.154  
 121.155 -consts trans_type :: "ty \<Rightarrow> tyI"
 121.156 -
 121.157  nominal_primrec
 121.158 +  trans_type :: "ty \<Rightarrow> tyI"
 121.159 +where
 121.160    "trans_type (Data \<sigma>) = DataI(NatI)"
 121.161 -  "trans_type (\<tau>1\<rightarrow>\<tau>2) = (trans_type \<tau>1)\<rightarrow>(trans_type \<tau>2)"
 121.162 +| "trans_type (\<tau>1\<rightarrow>\<tau>2) = (trans_type \<tau>1)\<rightarrow>(trans_type \<tau>2)"
 121.163    by (rule TrueI)+
 121.164  
 121.165  end
 121.166 \ No newline at end of file
   122.1 --- a/src/HOL/Nominal/Examples/Contexts.thy	Tue Dec 30 08:18:54 2008 +0100
   122.2 +++ b/src/HOL/Nominal/Examples/Contexts.thy	Tue Dec 30 11:10:01 2008 +0100
   122.3 @@ -1,5 +1,3 @@
   122.4 -(* $Id$ *)
   122.5 -
   122.6  theory Contexts
   122.7  imports "../Nominal"
   122.8  begin
   122.9 @@ -42,12 +40,12 @@
  122.10  
  122.11  text {* Capture-Avoiding Substitution *}
  122.12  
  122.13 -consts subst :: "lam \<Rightarrow> name \<Rightarrow> lam \<Rightarrow> lam"  ("_[_::=_]" [100,100,100] 100)
  122.14 -
  122.15  nominal_primrec
  122.16 +  subst :: "lam \<Rightarrow> name \<Rightarrow> lam \<Rightarrow> lam"  ("_[_::=_]" [100,100,100] 100)
  122.17 +where
  122.18    "(Var x)[y::=s] = (if x=y then s else (Var x))"
  122.19 -  "(App t\<^isub>1 t\<^isub>2)[y::=s] = App (t\<^isub>1[y::=s]) (t\<^isub>2[y::=s])"
  122.20 -  "x\<sharp>(y,s) \<Longrightarrow> (Lam [x].t)[y::=s] = Lam [x].(t[y::=s])"
  122.21 +| "(App t\<^isub>1 t\<^isub>2)[y::=s] = App (t\<^isub>1[y::=s]) (t\<^isub>2[y::=s])"
  122.22 +| "x\<sharp>(y,s) \<Longrightarrow> (Lam [x].t)[y::=s] = Lam [x].(t[y::=s])"
  122.23  apply(finite_guess)+
  122.24  apply(rule TrueI)+
  122.25  apply(simp add: abs_fresh)
  122.26 @@ -59,14 +57,13 @@
  122.27    This operation is possibly capturing.
  122.28  *}
  122.29  
  122.30 -consts 
  122.31 +nominal_primrec
  122.32    filling :: "ctx \<Rightarrow> lam \<Rightarrow> lam" ("_\<lbrakk>_\<rbrakk>" [100,100] 100)
  122.33 -
  122.34 -nominal_primrec
  122.35 +where
  122.36    "\<box>\<lbrakk>t\<rbrakk> = t"
  122.37 -  "(CAppL E t')\<lbrakk>t\<rbrakk> = App (E\<lbrakk>t\<rbrakk>) t'"
  122.38 -  "(CAppR t' E)\<lbrakk>t\<rbrakk> = App t' (E\<lbrakk>t\<rbrakk>)"
  122.39 -  "(CLam [x].E)\<lbrakk>t\<rbrakk> = Lam [x].(E\<lbrakk>t\<rbrakk>)" 
  122.40 +| "(CAppL E t')\<lbrakk>t\<rbrakk> = App (E\<lbrakk>t\<rbrakk>) t'"
  122.41 +| "(CAppR t' E)\<lbrakk>t\<rbrakk> = App t' (E\<lbrakk>t\<rbrakk>)"
  122.42 +| "(CLam [x].E)\<lbrakk>t\<rbrakk> = Lam [x].(E\<lbrakk>t\<rbrakk>)" 
  122.43  by (rule TrueI)+
  122.44  
  122.45  text {* 
  122.46 @@ -81,14 +78,13 @@
  122.47  
  122.48  text {* The composition of two contexts. *}
  122.49  
  122.50 -consts 
  122.51 +nominal_primrec
  122.52   ctx_compose :: "ctx \<Rightarrow> ctx \<Rightarrow> ctx" ("_ \<circ> _" [100,100] 100)
  122.53 -
  122.54 -nominal_primrec
  122.55 +where
  122.56    "\<box> \<circ> E' = E'"
  122.57 -  "(CAppL E t') \<circ> E' = CAppL (E \<circ> E') t'"
  122.58 -  "(CAppR t' E) \<circ> E' = CAppR t' (E \<circ> E')"
  122.59 -  "(CLam [x].E) \<circ> E' = CLam [x].(E \<circ> E')"
  122.60 +| "(CAppL E t') \<circ> E' = CAppL (E \<circ> E') t'"
  122.61 +| "(CAppR t' E) \<circ> E' = CAppR t' (E \<circ> E')"
  122.62 +| "(CLam [x].E) \<circ> E' = CLam [x].(E \<circ> E')"
  122.63  by (rule TrueI)+
  122.64    
  122.65  lemma ctx_compose:
   123.1 --- a/src/HOL/Nominal/Examples/Crary.thy	Tue Dec 30 08:18:54 2008 +0100
   123.2 +++ b/src/HOL/Nominal/Examples/Crary.thy	Tue Dec 30 11:10:01 2008 +0100
   123.3 @@ -1,4 +1,3 @@
   123.4 -(* "$Id$" *)
   123.5  (*                                                    *)
   123.6  (* Formalisation of the chapter on Logical Relations  *)
   123.7  (* and a Case Study in Equivalence Checking           *)
   123.8 @@ -47,14 +46,20 @@
   123.9    shows "(\<exists> T\<^isub>1 T\<^isub>2. T=T\<^isub>1\<rightarrow>T\<^isub>2) \<or> T=TUnit \<or> T=TBase"
  123.10  by (induct T rule:ty.induct) (auto)
  123.11  
  123.12 -instance ty :: size ..
  123.13 +instantiation ty :: size
  123.14 +begin
  123.15  
  123.16 -nominal_primrec
  123.17 +nominal_primrec size_ty
  123.18 +where
  123.19    "size (TBase) = 1"
  123.20 -  "size (TUnit) = 1"
  123.21 -  "size (T\<^isub>1\<rightarrow>T\<^isub>2) = size T\<^isub>1 + size T\<^isub>2"
  123.22 +| "size (TUnit) = 1"
  123.23 +| "size (T\<^isub>1\<rightarrow>T\<^isub>2) = size T\<^isub>1 + size T\<^isub>2"
  123.24  by (rule TrueI)+
  123.25  
  123.26 +instance ..
  123.27 +
  123.28 +end
  123.29 +
  123.30  lemma ty_size_greater_zero[simp]:
  123.31    fixes T::"ty"
  123.32    shows "size T > 0"
  123.33 @@ -87,16 +92,15 @@
  123.34  using a
  123.35  by (induct rule: lookup.induct)
  123.36     (auto simp add: fresh_list_cons fresh_prod fresh_atm)
  123.37 -
  123.38 -consts
  123.39 -  psubst :: "Subst \<Rightarrow> trm \<Rightarrow> trm"  ("_<_>" [100,100] 130)
  123.40   
  123.41  nominal_primrec
  123.42 +  psubst :: "Subst \<Rightarrow> trm \<Rightarrow> trm"  ("_<_>" [100,100] 130)
  123.43 +where
  123.44    "\<theta><(Var x)> = (lookup \<theta> x)"
  123.45 -  "\<theta><(App t\<^isub>1 t\<^isub>2)> = App \<theta><t\<^isub>1> \<theta><t\<^isub>2>"
  123.46 -  "x\<sharp>\<theta> \<Longrightarrow> \<theta><(Lam [x].t)> = Lam [x].(\<theta><t>)"
  123.47 -  "\<theta><(Const n)> = Const n"
  123.48 -  "\<theta><(Unit)> = Unit"
  123.49 +| "\<theta><(App t\<^isub>1 t\<^isub>2)> = App \<theta><t\<^isub>1> \<theta><t\<^isub>2>"
  123.50 +| "x\<sharp>\<theta> \<Longrightarrow> \<theta><(Lam [x].t)> = Lam [x].(\<theta><t>)"
  123.51 +| "\<theta><(Const n)> = Const n"
  123.52 +| "\<theta><(Unit)> = Unit"
  123.53  apply(finite_guess)+
  123.54  apply(rule TrueI)+
  123.55  apply(simp add: abs_fresh)+
   124.1 --- a/src/HOL/Nominal/Examples/Fsub.thy	Tue Dec 30 08:18:54 2008 +0100
   124.2 +++ b/src/HOL/Nominal/Examples/Fsub.thy	Tue Dec 30 11:10:01 2008 +0100
   124.3 @@ -1,5 +1,3 @@
   124.4 -(* $Id$ *)
   124.5 -
   124.6  (*<*)
   124.7  theory Fsub
   124.8  imports "../Nominal" 
   124.9 @@ -229,32 +227,26 @@
  124.10  
  124.11  section {* Size and Capture-Avoiding Substitution for Types *}
  124.12  
  124.13 -consts size_ty :: "ty \<Rightarrow> nat"
  124.14 -
  124.15  nominal_primrec
  124.16 +  size_ty :: "ty \<Rightarrow> nat"
  124.17 +where
  124.18    "size_ty (Tvar X) = 1"
  124.19 -  "size_ty (Top) = 1"
  124.20 -  "size_ty (T1 \<rightarrow> T2) = (size_ty T1) + (size_ty T2) + 1"
  124.21 -  "X\<sharp>T1 \<Longrightarrow> size_ty (\<forall>[X<:T1].T2) = (size_ty T1) + (size_ty T2) + 1"
  124.22 +| "size_ty (Top) = 1"
  124.23 +| "size_ty (T1 \<rightarrow> T2) = (size_ty T1) + (size_ty T2) + 1"
  124.24 +| "X\<sharp>T1 \<Longrightarrow> size_ty (\<forall>[X<:T1].T2) = (size_ty T1) + (size_ty T2) + 1"
  124.25    apply (finite_guess)+
  124.26    apply (rule TrueI)+
  124.27    apply (simp add: fresh_nat)
  124.28    apply (fresh_guess)+
  124.29    done
  124.30  
  124.31 -consts subst_ty :: "tyvrs \<Rightarrow> ty \<Rightarrow> ty \<Rightarrow> ty"
  124.32 -
  124.33 -syntax 
  124.34 - subst_ty_syn :: "ty \<Rightarrow> tyvrs \<Rightarrow> ty \<Rightarrow> ty" ("_[_:=_]\<^isub>t\<^isub>y" [100,100,100] 100)
  124.35 -
  124.36 -translations 
  124.37 -  "T1[Y:=T2]\<^isub>t\<^isub>y" \<rightleftharpoons> "subst_ty Y T2 T1"
  124.38 -
  124.39  nominal_primrec
  124.40 +  subst_ty :: "ty \<Rightarrow> tyvrs \<Rightarrow> ty \<Rightarrow> ty" ("_[_:=_]\<^isub>t\<^isub>y" [100,100,100] 100)
  124.41 +where
  124.42    "(Tvar X)[Y:=T]\<^isub>t\<^isub>y= (if X=Y then T else (Tvar X))"
  124.43 -  "(Top)[Y:=T]\<^isub>t\<^isub>y = Top"
  124.44 -  "(T\<^isub>1 \<rightarrow> T\<^isub>2)[Y:=T]\<^isub>t\<^isub>y = (T\<^isub>1[Y:=T]\<^isub>t\<^isub>y) \<rightarrow> (T\<^isub>2[Y:=T]\<^isub>t\<^isub>y)"
  124.45 -  "\<lbrakk>X\<sharp>(Y,T); X\<sharp>T\<^isub>1\<rbrakk> \<Longrightarrow> (\<forall>[X<:T\<^isub>1].T\<^isub>2)[Y:=T]\<^isub>t\<^isub>y = (\<forall>[X<:(T\<^isub>1[Y:=T]\<^isub>t\<^isub>y)].(T\<^isub>2[Y:=T]\<^isub>t\<^isub>y))"
  124.46 +| "(Top)[Y:=T]\<^isub>t\<^isub>y = Top"
  124.47 +| "(T\<^isub>1 \<rightarrow> T\<^isub>2)[Y:=T]\<^isub>t\<^isub>y = (T\<^isub>1[Y:=T]\<^isub>t\<^isub>y) \<rightarrow> (T\<^isub>2[Y:=T]\<^isub>t\<^isub>y)"
  124.48 +| "\<lbrakk>X\<sharp>(Y,T); X\<sharp>T\<^isub>1\<rbrakk> \<Longrightarrow> (\<forall>[X<:T\<^isub>1].T\<^isub>2)[Y:=T]\<^isub>t\<^isub>y = (\<forall>[X<:(T\<^isub>1[Y:=T]\<^isub>t\<^isub>y)].(T\<^isub>2[Y:=T]\<^isub>t\<^isub>y))"
  124.49    apply (finite_guess)+
  124.50    apply (rule TrueI)+
  124.51    apply (simp add: abs_fresh)
   125.1 --- a/src/HOL/Nominal/Examples/Height.thy	Tue Dec 30 08:18:54 2008 +0100
   125.2 +++ b/src/HOL/Nominal/Examples/Height.thy	Tue Dec 30 11:10:01 2008 +0100
   125.3 @@ -1,5 +1,3 @@
   125.4 -(* $Id$ *)
   125.5 -
   125.6  theory Height
   125.7    imports "../Nominal"
   125.8  begin
   125.9 @@ -17,13 +15,13 @@
  125.10    | Lam "\<guillemotleft>name\<guillemotright>lam" ("Lam [_]._" [100,100] 100)
  125.11  
  125.12  text {* Definition of the height-function on lambda-terms. *} 
  125.13 -consts 
  125.14 -  height :: "lam \<Rightarrow> int"
  125.15  
  125.16  nominal_primrec
  125.17 +  height :: "lam \<Rightarrow> int"
  125.18 +where
  125.19    "height (Var x) = 1"
  125.20 -  "height (App t1 t2) = (max (height t1) (height t2)) + 1"
  125.21 -  "height (Lam [a].t) = (height t) + 1"
  125.22 +| "height (App t1 t2) = (max (height t1) (height t2)) + 1"
  125.23 +| "height (Lam [a].t) = (height t) + 1"
  125.24    apply(finite_guess add: perm_int_def)+
  125.25    apply(rule TrueI)+
  125.26    apply(simp add: fresh_int)
  125.27 @@ -32,13 +30,12 @@
  125.28  
  125.29  text {* Definition of capture-avoiding substitution. *}
  125.30  
  125.31 -consts
  125.32 +nominal_primrec
  125.33    subst :: "lam \<Rightarrow> name \<Rightarrow> lam \<Rightarrow> lam"  ("_[_::=_]" [100,100,100] 100)
  125.34 -
  125.35 -nominal_primrec
  125.36 +where
  125.37    "(Var x)[y::=t'] = (if x=y then t' else (Var x))"
  125.38 -  "(App t1 t2)[y::=t'] = App (t1[y::=t']) (t2[y::=t'])"
  125.39 -  "\<lbrakk>x\<sharp>y; x\<sharp>t'\<rbrakk> \<Longrightarrow> (Lam [x].t)[y::=t'] = Lam [x].(t[y::=t'])"
  125.40 +| "(App t1 t2)[y::=t'] = App (t1[y::=t']) (t2[y::=t'])"
  125.41 +| "\<lbrakk>x\<sharp>y; x\<sharp>t'\<rbrakk> \<Longrightarrow> (Lam [x].t)[y::=t'] = Lam [x].(t[y::=t'])"
  125.42  apply(finite_guess)+
  125.43  apply(rule TrueI)+
  125.44  apply(simp add: abs_fresh)
   126.1 --- a/src/HOL/Nominal/Examples/Lam_Funs.thy	Tue Dec 30 08:18:54 2008 +0100
   126.2 +++ b/src/HOL/Nominal/Examples/Lam_Funs.thy	Tue Dec 30 11:10:01 2008 +0100
   126.3 @@ -1,5 +1,3 @@
   126.4 -(* $Id$ *)
   126.5 -
   126.6  theory Lam_Funs
   126.7    imports "../Nominal"
   126.8  begin
   126.9 @@ -18,13 +16,12 @@
  126.10  
  126.11  text {* The depth of a lambda-term. *}
  126.12  
  126.13 -consts 
  126.14 +nominal_primrec
  126.15    depth :: "lam \<Rightarrow> nat"
  126.16 -
  126.17 -nominal_primrec
  126.18 +where
  126.19    "depth (Var x) = 1"
  126.20 -  "depth (App t1 t2) = (max (depth t1) (depth t2)) + 1"
  126.21 -  "depth (Lam [a].t) = (depth t) + 1"
  126.22 +| "depth (App t1 t2) = (max (depth t1) (depth t2)) + 1"
  126.23 +| "depth (Lam [a].t) = (depth t) + 1"
  126.24    apply(finite_guess)+
  126.25    apply(rule TrueI)+
  126.26    apply(simp add: fresh_nat)
  126.27 @@ -38,13 +35,12 @@
  126.28    the invariant that frees always returns a finite set of names. 
  126.29  *}
  126.30  
  126.31 -consts 
  126.32 +nominal_primrec (invariant: "\<lambda>s::name set. finite s")
  126.33    frees :: "lam \<Rightarrow> name set"
  126.34 -
  126.35 -nominal_primrec (invariant: "\<lambda>s::name set. finite s")
  126.36 +where
  126.37    "frees (Var a) = {a}"
  126.38 -  "frees (App t1 t2) = (frees t1) \<union> (frees t2)"
  126.39 -  "frees (Lam [a].t) = (frees t) - {a}"
  126.40 +| "frees (App t1 t2) = (frees t1) \<union> (frees t2)"
  126.41 +| "frees (Lam [a].t) = (frees t) - {a}"
  126.42  apply(finite_guess)+
  126.43  apply(simp)+ 
  126.44  apply(simp add: fresh_def)
  126.45 @@ -78,14 +74,13 @@
  126.46    and   X::"name"
  126.47    shows "pi\<bullet>(lookup \<theta> X) = lookup (pi\<bullet>\<theta>) (pi\<bullet>X)"
  126.48  by (induct \<theta>) (auto simp add: eqvts)
  126.49 -
  126.50 -consts
  126.51 -  psubst :: "(name\<times>lam) list \<Rightarrow> lam \<Rightarrow> lam"  ("_<_>" [95,95] 105)
  126.52   
  126.53  nominal_primrec
  126.54 +  psubst :: "(name\<times>lam) list \<Rightarrow> lam \<Rightarrow> lam"  ("_<_>" [95,95] 105)
  126.55 +where
  126.56    "\<theta><(Var x)> = (lookup \<theta> x)"
  126.57 -  "\<theta><(App e\<^isub>1 e\<^isub>2)> = App (\<theta><e\<^isub>1>) (\<theta><e\<^isub>2>)"
  126.58 -  "x\<sharp>\<theta> \<Longrightarrow> \<theta><(Lam [x].e)> = Lam [x].(\<theta><e>)"
  126.59 +| "\<theta><(App e\<^isub>1 e\<^isub>2)> = App (\<theta><e\<^isub>1>) (\<theta><e\<^isub>2>)"
  126.60 +| "x\<sharp>\<theta> \<Longrightarrow> \<theta><(Lam [x].e)> = Lam [x].(\<theta><e>)"
  126.61  apply(finite_guess)+
  126.62  apply(rule TrueI)+
  126.63  apply(simp add: abs_fresh)+
  126.64 @@ -130,26 +125,24 @@
  126.65  
  126.66  text {* Filling a lambda-term into a context. *}
  126.67  
  126.68 -consts 
  126.69 +nominal_primrec
  126.70    filling :: "clam \<Rightarrow> lam \<Rightarrow> lam" ("_\<lbrakk>_\<rbrakk>" [100,100] 100)
  126.71 -
  126.72 -nominal_primrec
  126.73 +where
  126.74    "\<box>\<lbrakk>t\<rbrakk> = t"
  126.75 -  "(CAppL E t')\<lbrakk>t\<rbrakk> = App (E\<lbrakk>t\<rbrakk>) t'"
  126.76 -  "(CAppR t' E)\<lbrakk>t\<rbrakk> = App t' (E\<lbrakk>t\<rbrakk>)"
  126.77 -  "(CLam [x].E)\<lbrakk>t\<rbrakk> = Lam [x].(E\<lbrakk>t\<rbrakk>)" 
  126.78 +| "(CAppL E t')\<lbrakk>t\<rbrakk> = App (E\<lbrakk>t\<rbrakk>) t'"
  126.79 +| "(CAppR t' E)\<lbrakk>t\<rbrakk> = App t' (E\<lbrakk>t\<rbrakk>)"
  126.80 +| "(CLam [x].E)\<lbrakk>t\<rbrakk> = Lam [x].(E\<lbrakk>t\<rbrakk>)" 
  126.81  by (rule TrueI)+
  126.82  
  126.83  text {* Composition od two contexts *}
  126.84  
  126.85 -consts 
  126.86 +nominal_primrec
  126.87   clam_compose :: "clam \<Rightarrow> clam \<Rightarrow> clam" ("_ \<circ> _" [100,100] 100)
  126.88 -
  126.89 -nominal_primrec
  126.90 +where
  126.91    "\<box> \<circ> E' = E'"
  126.92 -  "(CAppL E t') \<circ> E' = CAppL (E \<circ> E') t'"
  126.93 -  "(CAppR t' E) \<circ> E' = CAppR t' (E \<circ> E')"
  126.94 -  "(CLam [x].E) \<circ> E' = CLam [x].(E \<circ> E')"
  126.95 +| "(CAppL E t') \<circ> E' = CAppL (E \<circ> E') t'"
  126.96 +| "(CAppR t' E) \<circ> E' = CAppR t' (E \<circ> E')"
  126.97 +| "(CLam [x].E) \<circ> E' = CLam [x].(E \<circ> E')"
  126.98  by (rule TrueI)+
  126.99    
 126.100  lemma clam_compose:
   127.1 --- a/src/HOL/Nominal/Examples/LocalWeakening.thy	Tue Dec 30 08:18:54 2008 +0100
   127.2 +++ b/src/HOL/Nominal/Examples/LocalWeakening.thy	Tue Dec 30 11:10:01 2008 +0100
   127.3 @@ -1,5 +1,3 @@
   127.4 -(* $Id$ *)
   127.5 -
   127.6  (* Formalisation of weakening using locally nameless    *)
   127.7  (* terms; the nominal infrastructure can also derive    *)
   127.8  (* strong induction principles for such representations *)
   127.9 @@ -29,13 +27,13 @@
  127.10  by (induct t rule: llam.induct)
  127.11     (auto simp add: llam.inject)
  127.12  
  127.13 -consts llam_size :: "llam \<Rightarrow> nat"
  127.14 -
  127.15  nominal_primrec
  127.16 - "llam_size (lPar a) = 1"
  127.17 - "llam_size (lVar n) = 1"
  127.18 - "llam_size (lApp t1 t2) = 1 + (llam_size t1) + (llam_size t2)"
  127.19 - "llam_size (lLam t) = 1 + (llam_size t)"
  127.20 +  llam_size :: "llam \<Rightarrow> nat"
  127.21 +where
  127.22 +  "llam_size (lPar a) = 1"
  127.23 +| "llam_size (lVar n) = 1"
  127.24 +| "llam_size (lApp t1 t2) = 1 + (llam_size t1) + (llam_size t2)"
  127.25 +| "llam_size (lLam t) = 1 + (llam_size t)"
  127.26  by (rule TrueI)+
  127.27  
  127.28  function  
   128.1 --- a/src/HOL/Nominal/Examples/SN.thy	Tue Dec 30 08:18:54 2008 +0100
   128.2 +++ b/src/HOL/Nominal/Examples/SN.thy	Tue Dec 30 11:10:01 2008 +0100
   128.3 @@ -1,5 +1,3 @@
   128.4 -(* $Id$ *)
   128.5 -
   128.6  theory SN
   128.7    imports Lam_Funs
   128.8  begin
   128.9 @@ -228,12 +226,11 @@
  128.10  
  128.11  section {* Candidates *}
  128.12  
  128.13 -consts
  128.14 +nominal_primrec
  128.15    RED :: "ty \<Rightarrow> lam set"
  128.16 -
  128.17 -nominal_primrec
  128.18 +where
  128.19    "RED (TVar X) = {t. SN(t)}"
  128.20 -  "RED (\<tau>\<rightarrow>\<sigma>) =   {t. \<forall>u. (u\<in>RED \<tau> \<longrightarrow> (App t u)\<in>RED \<sigma>)}"
  128.21 +| "RED (\<tau>\<rightarrow>\<sigma>) =   {t. \<forall>u. (u\<in>RED \<tau> \<longrightarrow> (App t u)\<in>RED \<sigma>)}"
  128.22  by (rule TrueI)+
  128.23  
  128.24  text {* neutral terms *}
  128.25 @@ -248,13 +245,12 @@
  128.26  where
  128.27    fst[intro!]:  "(App t s) \<guillemotright> t"
  128.28  
  128.29 -consts
  128.30 +nominal_primrec
  128.31    fst_app_aux::"lam\<Rightarrow>lam option"
  128.32 -
  128.33 -nominal_primrec
  128.34 +where
  128.35    "fst_app_aux (Var a)     = None"
  128.36 -  "fst_app_aux (App t1 t2) = Some t1"
  128.37 -  "fst_app_aux (Lam [x].t) = None"
  128.38 +| "fst_app_aux (App t1 t2) = Some t1"
  128.39 +| "fst_app_aux (Lam [x].t) = None"
  128.40  apply(finite_guess)+
  128.41  apply(rule TrueI)+
  128.42  apply(simp add: fresh_none)
   129.1 --- a/src/HOL/Nominal/Examples/SOS.thy	Tue Dec 30 08:18:54 2008 +0100
   129.2 +++ b/src/HOL/Nominal/Examples/SOS.thy	Tue Dec 30 11:10:01 2008 +0100
   129.3 @@ -1,4 +1,3 @@
   129.4 -(* "$Id$" *)
   129.5  (*                                                        *)
   129.6  (* Formalisation of some typical SOS-proofs.              *)
   129.7  (*                                                        *) 
   129.8 @@ -62,13 +61,12 @@
   129.9  
  129.10  (* parallel substitution *)
  129.11  
  129.12 -consts
  129.13 +nominal_primrec
  129.14    psubst :: "(name\<times>trm) list \<Rightarrow> trm \<Rightarrow> trm"  ("_<_>" [95,95] 105)
  129.15 - 
  129.16 -nominal_primrec
  129.17 +where
  129.18    "\<theta><(Var x)> = (lookup \<theta> x)"
  129.19 -  "\<theta><(App e\<^isub>1 e\<^isub>2)> = App (\<theta><e\<^isub>1>) (\<theta><e\<^isub>2>)"
  129.20 -  "x\<sharp>\<theta> \<Longrightarrow> \<theta><(Lam [x].e)> = Lam [x].(\<theta><e>)"
  129.21 +| "\<theta><(App e\<^isub>1 e\<^isub>2)> = App (\<theta><e\<^isub>1>) (\<theta><e\<^isub>2>)"
  129.22 +| "x\<sharp>\<theta> \<Longrightarrow> \<theta><(Lam [x].e)> = Lam [x].(\<theta><e>)"
  129.23  apply(finite_guess)+
  129.24  apply(rule TrueI)+
  129.25  apply(simp add: abs_fresh)+
  129.26 @@ -349,12 +347,12 @@
  129.27  using h by (induct) (auto)
  129.28  
  129.29  (* Valuation *)
  129.30 -consts
  129.31 -  V :: "ty \<Rightarrow> trm set" 
  129.32  
  129.33  nominal_primrec
  129.34 +  V :: "ty \<Rightarrow> trm set" 
  129.35 +where
  129.36    "V (TVar x) = {e. val e}"
  129.37 -  "V (T\<^isub>1 \<rightarrow> T\<^isub>2) = {Lam [x].e | x e. \<forall> v \<in> (V T\<^isub>1). \<exists> v'. e[x::=v] \<Down> v' \<and> v' \<in> V T\<^isub>2}"
  129.38 +| "V (T\<^isub>1 \<rightarrow> T\<^isub>2) = {Lam [x].e | x e. \<forall> v \<in> (V T\<^isub>1). \<exists> v'. e[x::=v] \<Down> v' \<and> v' \<in> V T\<^isub>2}"
  129.39    by (rule TrueI)+ 
  129.40  
  129.41  lemma V_eqvt:
   130.1 --- a/src/HOL/Nominal/Examples/Standardization.thy	Tue Dec 30 08:18:54 2008 +0100
   130.2 +++ b/src/HOL/Nominal/Examples/Standardization.thy	Tue Dec 30 11:10:01 2008 +0100
   130.3 @@ -1,5 +1,4 @@
   130.4  (*  Title:      HOL/Nominal/Examples/Standardization.thy
   130.5 -    ID:         $Id$
   130.6      Author:     Stefan Berghofer and Tobias Nipkow
   130.7      Copyright   2005, 2008 TU Muenchen
   130.8  *)
   130.9 @@ -24,24 +23,30 @@
  130.10  | App "lam" "lam" (infixl "\<degree>" 200)
  130.11  | Lam "\<guillemotleft>name\<guillemotright>lam" ("Lam [_]._" [0, 10] 10)
  130.12  
  130.13 -instance lam :: size ..
  130.14 +instantiation lam :: size
  130.15 +begin
  130.16  
  130.17 -nominal_primrec
  130.18 +nominal_primrec size_lam
  130.19 +where
  130.20    "size (Var n) = 0"
  130.21 -  "size (t \<degree> u) = size t + size u + 1"
  130.22 -  "size (Lam [x].t) = size t + 1"
  130.23 +| "size (t \<degree> u) = size t + size u + 1"
  130.24 +| "size (Lam [x].t) = size t + 1"
  130.25    apply finite_guess+
  130.26    apply (rule TrueI)+
  130.27    apply (simp add: fresh_nat)
  130.28    apply fresh_guess+
  130.29    done
  130.30  
  130.31 -consts subst :: "lam \<Rightarrow> name \<Rightarrow> lam \<Rightarrow> lam"  ("_[_::=_]" [300, 0, 0] 300)
  130.32 +instance ..
  130.33 +
  130.34 +end
  130.35  
  130.36  nominal_primrec
  130.37 +  subst :: "lam \<Rightarrow> name \<Rightarrow> lam \<Rightarrow> lam"  ("_[_::=_]" [300, 0, 0] 300)
  130.38 +where
  130.39    subst_Var: "(Var x)[y::=s] = (if x=y then s else (Var x))"
  130.40 -  subst_App: "(t\<^isub>1 \<degree> t\<^isub>2)[y::=s] = t\<^isub>1[y::=s] \<degree> t\<^isub>2[y::=s]"
  130.41 -  subst_Lam: "x \<sharp> (y, s) \<Longrightarrow> (Lam [x].t)[y::=s] = (Lam [x].(t[y::=s]))"
  130.42 +| subst_App: "(t\<^isub>1 \<degree> t\<^isub>2)[y::=s] = t\<^isub>1[y::=s] \<degree> t\<^isub>2[y::=s]"
  130.43 +| subst_Lam: "x \<sharp> (y, s) \<Longrightarrow> (Lam [x].t)[y::=s] = (Lam [x].(t[y::=s]))"
  130.44    apply(finite_guess)+
  130.45    apply(rule TrueI)+
  130.46    apply(simp add: abs_fresh)
   131.1 --- a/src/HOL/Nominal/Examples/Type_Preservation.thy	Tue Dec 30 08:18:54 2008 +0100
   131.2 +++ b/src/HOL/Nominal/Examples/Type_Preservation.thy	Tue Dec 30 11:10:01 2008 +0100
   131.3 @@ -1,5 +1,3 @@
   131.4 -(* $Id$ *)
   131.5 -
   131.6  theory Type_Preservation
   131.7    imports Nominal
   131.8  begin
   131.9 @@ -21,13 +19,12 @@
  131.10  
  131.11  text {* Capture-Avoiding Substitution *}
  131.12  
  131.13 -consts 
  131.14 +nominal_primrec
  131.15    subst :: "lam \<Rightarrow> name \<Rightarrow> lam \<Rightarrow> lam"  ("_[_::=_]")
  131.16 -
  131.17 -nominal_primrec
  131.18 +where
  131.19    "(Var x)[y::=s] = (if x=y then s else (Var x))"
  131.20 -  "(App t\<^isub>1 t\<^isub>2)[y::=s] = App (t\<^isub>1[y::=s]) (t\<^isub>2[y::=s])"
  131.21 -  "x\<sharp>(y,s) \<Longrightarrow> (Lam [x].t)[y::=s] = Lam [x].(t[y::=s])"
  131.22 +| "(App t\<^isub>1 t\<^isub>2)[y::=s] = App (t\<^isub>1[y::=s]) (t\<^isub>2[y::=s])"
  131.23 +| "x\<sharp>(y,s) \<Longrightarrow> (Lam [x].t)[y::=s] = Lam [x].(t[y::=s])"
  131.24  apply(finite_guess)+
  131.25  apply(rule TrueI)+
  131.26  apply(simp add: abs_fresh)
   132.1 --- a/src/HOL/Nominal/Examples/W.thy	Tue Dec 30 08:18:54 2008 +0100
   132.2 +++ b/src/HOL/Nominal/Examples/W.thy	Tue Dec 30 11:10:01 2008 +0100
   132.3 @@ -1,5 +1,3 @@
   132.4 -(* "$Id$" *)
   132.5 -
   132.6  theory W
   132.7  imports Nominal
   132.8  begin
   132.9 @@ -50,26 +48,68 @@
  132.10    Ctxt  = "(var\<times>tyS) list" 
  132.11  
  132.12  text {* free type variables *}
  132.13 -consts
  132.14 -  ftv    :: "'a \<Rightarrow> tvar list"
  132.15  
  132.16 -primrec (ftv_of_prod)
  132.17 - "ftv (x,y) = (ftv x)@(ftv y)"
  132.18 +class ftv = type +
  132.19 +  fixes ftv :: "'a \<Rightarrow> tvar list"
  132.20  
  132.21 -defs (overloaded)
  132.22 +instantiation * :: (ftv, ftv) ftv
  132.23 +begin
  132.24 +
  132.25 +primrec ftv_prod
  132.26 +where
  132.27 + "ftv (x::'a::ftv, y::'b::ftv) = (ftv x)@(ftv y)"
  132.28 +
  132.29 +instance ..
  132.30 +
  132.31 +end
  132.32 +
  132.33 +instantiation tvar :: ftv
  132.34 +begin
  132.35 +
  132.36 +definition
  132.37    ftv_of_tvar[simp]:  "ftv X \<equiv> [(X::tvar)]"
  132.38 +
  132.39 +instance ..
  132.40 +
  132.41 +end
  132.42 +
  132.43 +instantiation var :: ftv
  132.44 +begin
  132.45 +
  132.46 +definition
  132.47    ftv_of_var[simp]:   "ftv (x::var) \<equiv> []" 
  132.48  
  132.49 -primrec (ftv_of_list)
  132.50 +instance ..
  132.51 +
  132.52 +end
  132.53 +
  132.54 +instantiation list :: (ftv) ftv
  132.55 +begin
  132.56 +
  132.57 +primrec ftv_list
  132.58 +where
  132.59    "ftv [] = []"
  132.60 -  "ftv (x#xs) = (ftv x)@(ftv xs)"
  132.61 +| "ftv (x#xs) = (ftv x)@(ftv xs)"
  132.62 +
  132.63 +instance ..
  132.64 +
  132.65 +end
  132.66  
  132.67  (* free type-variables of types *)
  132.68 -nominal_primrec (ftv_ty)
  132.69 +
  132.70 +instantiation ty :: ftv
  132.71 +begin
  132.72 +
  132.73 +nominal_primrec ftv_ty
  132.74 +where
  132.75    "ftv (TVar X) = [X]"
  132.76 -  "ftv (T\<^isub>1\<rightarrow>T\<^isub>2) = (ftv T\<^isub>1)@(ftv T\<^isub>2)"
  132.77 +| "ftv (T\<^isub>1\<rightarrow>T\<^isub>2) = (ftv T\<^isub>1)@(ftv T\<^isub>2)"
  132.78  by (rule TrueI)+
  132.79  
  132.80 +instance ..
  132.81 +
  132.82 +end
  132.83 +
  132.84  lemma ftv_ty_eqvt[eqvt]:
  132.85    fixes pi::"tvar prm"
  132.86    and   T::"ty"
  132.87 @@ -77,9 +117,13 @@
  132.88  by (nominal_induct T rule: ty.strong_induct)
  132.89     (perm_simp add: append_eqvt)+
  132.90  
  132.91 -nominal_primrec (ftv_tyS)
  132.92 +instantiation tyS :: ftv
  132.93 +begin
  132.94 +
  132.95 +nominal_primrec ftv_tyS
  132.96 +where
  132.97    "ftv (Ty T)    = ftv T"
  132.98 -  "ftv (\<forall>[X].S) = (ftv S) - [X]"
  132.99 +| "ftv (\<forall>[X].S) = (ftv S) - [X]"
 132.100  apply(finite_guess add: ftv_ty_eqvt fs_tvar1)+
 132.101  apply(rule TrueI)+
 132.102  apply(rule difference_fresh)
 132.103 @@ -87,6 +131,10 @@
 132.104  apply(fresh_guess add: ftv_ty_eqvt fs_tvar1)+
 132.105  done
 132.106  
 132.107 +instance ..
 132.108 +
 132.109 +end
 132.110 +
 132.111  lemma ftv_tyS_eqvt[eqvt]:
 132.112    fixes pi::"tvar prm"
 132.113    and   S::"tyS"
 132.114 @@ -140,11 +188,11 @@
 132.115  
 132.116  types Subst = "(tvar\<times>ty) list"
 132.117  
 132.118 -consts
 132.119 - psubst :: "Subst \<Rightarrow> 'a \<Rightarrow> 'a"       ("_<_>" [100,60] 120)
 132.120 +class psubst =
 132.121 +  fixes psubst :: "Subst \<Rightarrow> 'a \<Rightarrow> 'a"       ("_<_>" [100,60] 120)
 132.122  
 132.123  abbreviation 
 132.124 -  subst :: "'a \<Rightarrow> tvar \<Rightarrow> ty \<Rightarrow> 'a"  ("_[_::=_]" [100,100,100] 100)
 132.125 +  subst :: "'a::psubst \<Rightarrow> tvar \<Rightarrow> ty \<Rightarrow> 'a"  ("_[_::=_]" [100,100,100] 100)
 132.126  where
 132.127    "smth[X::=T] \<equiv> ([(X,T)])<smth>" 
 132.128  
 132.129 @@ -159,11 +207,19 @@
 132.130    shows "pi\<bullet>(lookup \<theta> X) = lookup (pi\<bullet>\<theta>) (pi\<bullet>X)"
 132.131  by (induct \<theta>) (auto simp add: eqvts)
 132.132  
 132.133 -nominal_primrec (psubst_ty)
 132.134 +instantiation ty :: psubst
 132.135 +begin
 132.136 +
 132.137 +nominal_primrec psubst_ty
 132.138 +where
 132.139    "\<theta><TVar X>   = lookup \<theta> X"
 132.140 -  "\<theta><T\<^isub>1 \<rightarrow> T\<^isub>2> = (\<theta><T\<^isub>1>) \<rightarrow> (\<theta><T\<^isub>2>)"
 132.141 +| "\<theta><T\<^isub>1 \<rightarrow> T\<^isub>2> = (\<theta><T\<^isub>1>) \<rightarrow> (\<theta><T\<^isub>2>)"
 132.142  by (rule TrueI)+
 132.143  
 132.144 +instance ..
 132.145 +
 132.146 +end
 132.147 +
 132.148  lemma psubst_ty_eqvt[eqvt]:
 132.149    fixes pi1::"tvar prm"
 132.150    and   \<theta>::"Subst"
   133.1 --- a/src/HOL/Nominal/Nominal.thy	Tue Dec 30 08:18:54 2008 +0100
   133.2 +++ b/src/HOL/Nominal/Nominal.thy	Tue Dec 30 11:10:01 2008 +0100
   133.3 @@ -1262,19 +1262,21 @@
   133.4    apply (simp add: pt_rev_pi [OF pt at])
   133.5    done
   133.6  
   133.7 -lemma insert_eqvt:
   133.8 +lemma pt_insert_eqvt:
   133.9 +  fixes pi::"'x prm"
  133.10 +  and   x::"'a"
  133.11    assumes pt: "pt TYPE('a) TYPE('x)"
  133.12    and at: "at TYPE('x)" 
  133.13 -  shows "(pi::'x prm)\<bullet>(insert (x::'a) X) = insert (pi\<bullet>x) (pi\<bullet>X)"
  133.14 +  shows "(pi\<bullet>(insert x X)) = insert (pi\<bullet>x) (pi\<bullet>X)"
  133.15    by (auto simp add: perm_set_eq [OF pt at])
  133.16  
  133.17 -lemma set_eqvt:
  133.18 +lemma pt_set_eqvt:
  133.19    fixes pi :: "'x prm"
  133.20    and   xs :: "'a list"
  133.21    assumes pt: "pt TYPE('a) TYPE('x)"
  133.22    and at: "at TYPE('x)" 
  133.23    shows "pi\<bullet>(set xs) = set (pi\<bullet>xs)"
  133.24 -by (induct xs) (auto simp add: empty_eqvt insert_eqvt [OF pt at])
  133.25 +by (induct xs) (auto simp add: empty_eqvt pt_insert_eqvt [OF pt at])
  133.26  
  133.27  lemma supp_singleton:
  133.28    assumes pt: "pt TYPE('a) TYPE('x)"
  133.29 @@ -1568,10 +1570,10 @@
  133.30  apply(simp add: pt_fresh_left_ineq[OF pta, OF ptb, OF at, OF cp])
  133.31  apply(drule_tac x="pi\<bullet>xa" in bspec)
  133.32  apply(simp add: pt_set_bij1[OF ptb, OF at])
  133.33 -apply(simp add: set_eqvt [OF ptb at] pt_rev_pi[OF pt_list_inst[OF ptb], OF at])
  133.34 +apply(simp add: pt_set_eqvt [OF ptb at] pt_rev_pi[OF pt_list_inst[OF ptb], OF at])
  133.35  apply(simp add: pt_fresh_bij_ineq[OF pta, OF ptb, OF at, OF cp])
  133.36  apply(drule_tac x="(rev pi)\<bullet>xa" in bspec)
  133.37 -apply(simp add: pt_set_bij1[OF ptb, OF at] set_eqvt [OF ptb at])
  133.38 +apply(simp add: pt_set_bij1[OF ptb, OF at] pt_set_eqvt [OF ptb at])
  133.39  apply(simp add: pt_fresh_left_ineq[OF pta, OF ptb, OF at, OF cp])
  133.40  done
  133.41  
   134.1 --- a/src/HOL/Nominal/nominal_atoms.ML	Tue Dec 30 08:18:54 2008 +0100
   134.2 +++ b/src/HOL/Nominal/nominal_atoms.ML	Tue Dec 30 11:10:01 2008 +0100
   134.3 @@ -798,8 +798,8 @@
   134.4         val pt_perm_supp_ineq   = @{thm "Nominal.pt_perm_supp_ineq"};
   134.5         val pt_perm_supp        = @{thm "Nominal.pt_perm_supp"};
   134.6         val subseteq_eqvt       = @{thm "Nominal.pt_subseteq_eqvt"};
   134.7 -       val insert_eqvt         = @{thm "Nominal.insert_eqvt"};
   134.8 -       val set_eqvt            = @{thm "Nominal.set_eqvt"};
   134.9 +       val insert_eqvt         = @{thm "Nominal.pt_insert_eqvt"};
  134.10 +       val set_eqvt            = @{thm "Nominal.pt_set_eqvt"};
  134.11         val perm_set_eq         = @{thm "Nominal.perm_set_eq"};
  134.12  
  134.13         (* Now we collect and instantiate some lemmas w.r.t. all atom      *)
   135.1 --- a/src/HOL/Nominal/nominal_primrec.ML	Tue Dec 30 08:18:54 2008 +0100
   135.2 +++ b/src/HOL/Nominal/nominal_primrec.ML	Tue Dec 30 11:10:01 2008 +0100
   135.3 @@ -1,5 +1,4 @@
   135.4  (*  Title:      HOL/Nominal/nominal_primrec.ML
   135.5 -    ID:         $Id$
   135.6      Author:     Stefan Berghofer, TU Muenchen and Norbert Voelker, FernUni Hagen
   135.7  
   135.8  Package for defining functions on nominal datatypes by primitive recursion.
   135.9 @@ -8,14 +7,10 @@
  135.10  
  135.11  signature NOMINAL_PRIMREC =
  135.12  sig
  135.13 -  val add_primrec: string -> string list option -> string option ->
  135.14 -    ((Binding.T * string) * Attrib.src list) list -> theory -> Proof.state
  135.15 -  val add_primrec_unchecked: string -> string list option -> string option ->
  135.16 -    ((Binding.T * string) * Attrib.src list) list -> theory -> Proof.state
  135.17 -  val add_primrec_i: string -> term list option -> term option ->
  135.18 -    ((Binding.T * term) * attribute list) list -> theory -> Proof.state
  135.19 -  val add_primrec_unchecked_i: string -> term list option -> term option ->
  135.20 -    ((Binding.T * term) * attribute list) list -> theory -> Proof.state
  135.21 +  val add_primrec: term list option -> term option ->
  135.22 +    (Binding.T * typ option * mixfix) list ->
  135.23 +    (Binding.T * typ option * mixfix) list ->
  135.24 +    (Attrib.binding * term) list -> local_theory -> Proof.state
  135.25  end;
  135.26  
  135.27  structure NominalPrimrec : NOMINAL_PRIMREC =
  135.28 @@ -26,23 +21,31 @@
  135.29  exception RecError of string;
  135.30  
  135.31  fun primrec_err s = error ("Nominal primrec definition error:\n" ^ s);
  135.32 -fun primrec_eq_err thy s eq =
  135.33 -  primrec_err (s ^ "\nin\n" ^ quote (Syntax.string_of_term_global thy eq));
  135.34 +fun primrec_eq_err lthy s eq =
  135.35 +  primrec_err (s ^ "\nin\n" ^ quote (Syntax.string_of_term lthy eq));
  135.36  
  135.37  
  135.38  (* preprocessing of equations *)
  135.39  
  135.40 -fun process_eqn thy eq rec_fns = 
  135.41 +fun unquantify t =
  135.42    let
  135.43 +    val (vs, Ts) = split_list (strip_qnt_vars "all" t);
  135.44 +    val body = strip_qnt_body "all" t;
  135.45 +    val (vs', _) = Name.variants vs (Name.make_context (fold_aterms
  135.46 +      (fn Free (v, _) => insert (op =) v | _ => I) body []))
  135.47 +  in (curry subst_bounds (map2 (curry Free) vs' Ts |> rev) body) end;
  135.48 +
  135.49 +fun process_eqn lthy is_fixed spec rec_fns = 
  135.50 +  let
  135.51 +    val eq = unquantify spec;
  135.52      val (lhs, rhs) = 
  135.53 -      if null (term_vars eq) then
  135.54 -        HOLogic.dest_eq (HOLogic.dest_Trueprop (Logic.strip_imp_concl eq))
  135.55 -        handle TERM _ => raise RecError "not a proper equation"
  135.56 -      else raise RecError "illegal schematic variable(s)";
  135.57 +      HOLogic.dest_eq (HOLogic.dest_Trueprop (Logic.strip_imp_concl eq))
  135.58 +      handle TERM _ => raise RecError "not a proper equation";
  135.59  
  135.60      val (recfun, args) = strip_comb lhs;
  135.61 -    val fnameT = dest_Const recfun handle TERM _ => 
  135.62 -      raise RecError "function is not declared as constant in theory";
  135.63 +    val fname = case recfun of Free (v, _) => if is_fixed v then v
  135.64 +          else raise RecError "illegal head of function equation"
  135.65 +      | _ => raise RecError "illegal head of function equation";
  135.66  
  135.67      val (ls', rest)  = take_prefix is_Free args;
  135.68      val (middle, rs') = take_suffix is_Free rest;
  135.69 @@ -68,26 +71,28 @@
  135.70      else
  135.71       (check_vars "repeated variable names in pattern: " (duplicates (op =) lfrees);
  135.72        check_vars "extra variables on rhs: "
  135.73 -        (map dest_Free (term_frees rhs) \\ lfrees);
  135.74 -      case AList.lookup (op =) rec_fns fnameT of
  135.75 +        (map dest_Free (term_frees rhs) |> subtract (op =) lfrees
  135.76 +          |> filter_out (is_fixed o fst));
  135.77 +      case AList.lookup (op =) rec_fns fname of
  135.78          NONE =>
  135.79 -          (fnameT, (tname, rpos, [(cname, (ls, cargs, rs, rhs, eq))]))::rec_fns
  135.80 +          (fname, (tname, rpos, [(cname, (ls, cargs, rs, rhs, eq))]))::rec_fns
  135.81        | SOME (_, rpos', eqns) =>
  135.82            if AList.defined (op =) eqns cname then
  135.83              raise RecError "constructor already occurred as pattern"
  135.84            else if rpos <> rpos' then
  135.85              raise RecError "position of recursive argument inconsistent"
  135.86            else
  135.87 -            AList.update (op =) (fnameT, (tname, rpos, (cname, (ls, cargs, rs, rhs, eq))::eqns))
  135.88 +            AList.update (op =)
  135.89 +              (fname, (tname, rpos, (cname, (ls, cargs, rs, rhs, eq))::eqns))
  135.90                rec_fns)
  135.91    end
  135.92 -  handle RecError s => primrec_eq_err thy s eq;
  135.93 +  handle RecError s => primrec_eq_err lthy s spec;
  135.94  
  135.95  val param_err = "Parameters must be the same for all recursive functions";
  135.96  
  135.97 -fun process_fun thy descr rec_eqns (i, fnameT as (fname, _)) (fnameTs, fnss) =
  135.98 +fun process_fun lthy descr eqns (i, fname) (fnames, fnss) =
  135.99    let
 135.100 -    val (_, (tname, _, constrs)) = List.nth (descr, i);
 135.101 +    val (_, (tname, _, constrs)) = nth descr i;
 135.102  
 135.103      (* substitute "fname ls x rs" by "y" for (x, (_, y)) in subs *)
 135.104  
 135.105 @@ -100,16 +105,17 @@
 135.106            let
 135.107              val (f, ts) = strip_comb t;
 135.108            in
 135.109 -            if is_Const f andalso dest_Const f mem map fst rec_eqns then
 135.110 +            if is_Free f
 135.111 +              andalso member (fn ((v, _), (w, _)) => v = w) eqns (dest_Free f) then
 135.112                let
 135.113 -                val fnameT' as (fname', _) = dest_Const f;
 135.114 -                val (_, rpos, eqns) = the (AList.lookup (op =) rec_eqns fnameT');
 135.115 -                val ls = Library.take (rpos, ts);
 135.116 -                val rest = Library.drop (rpos, ts);
 135.117 -                val (x', rs) = (hd rest, tl rest)
 135.118 -                  handle Empty => raise RecError ("not enough arguments\
 135.119 -                   \ in recursive application\nof function " ^ quote fname' ^ " on rhs");
 135.120 -                val rs' = (case eqns of
 135.121 +                val (fname', _) = dest_Free f;
 135.122 +                val (_, rpos, eqns') = the (AList.lookup (op =) eqns fname');
 135.123 +                val (ls, rs'') = chop rpos ts
 135.124 +                val (x', rs) = case rs'' of
 135.125 +                    x' :: rs => (x', rs)
 135.126 +                  | [] => raise RecError ("not enough arguments in recursive application\n"
 135.127 +                      ^ "of function " ^ quote fname' ^ " on rhs");
 135.128 +                val rs' = (case eqns' of
 135.129                      (_, (ls', _, rs', _, _)) :: _ =>
 135.130                        let val (rs1, rs2) = chop (length rs') rs
 135.131                        in
 135.132 @@ -126,7 +132,7 @@
 135.133                  | SOME (i', y) =>
 135.134                      fs
 135.135                      |> fold_map (subst subs) (xs @ rs')
 135.136 -                    ||> process_fun thy descr rec_eqns (i', fnameT')
 135.137 +                    ||> process_fun lthy descr eqns (i', fname')
 135.138                      |-> (fn ts' => pair (list_comb (y, ts')))
 135.139                end
 135.140              else
 135.141 @@ -138,41 +144,39 @@
 135.142  
 135.143      (* translate rec equations into function arguments suitable for rec comb *)
 135.144  
 135.145 -    fun trans eqns (cname, cargs) (fnameTs', fnss', fns) =
 135.146 +    fun trans eqns (cname, cargs) (fnames', fnss', fns) =
 135.147        (case AList.lookup (op =) eqns cname of
 135.148            NONE => (warning ("No equation for constructor " ^ quote cname ^
 135.149              "\nin definition of function " ^ quote fname);
 135.150 -              (fnameTs', fnss', (Const (@{const_name undefined}, dummyT))::fns))
 135.151 +              (fnames', fnss', (Const (@{const_name undefined}, dummyT))::fns))
 135.152          | SOME (ls, cargs', rs, rhs, eq) =>
 135.153              let
 135.154                val recs = filter (is_rec_type o snd) (cargs' ~~ cargs);
 135.155                val rargs = map fst recs;
 135.156 -              val subs = map (rpair dummyT o fst) 
 135.157 +              val subs = map (rpair dummyT o fst)
 135.158                  (rev (rename_wrt_term rhs rargs));
 135.159 -              val (rhs', (fnameTs'', fnss'')) = 
 135.160 -                  (subst (map (fn ((x, y), z) =>
 135.161 -                               (Free x, (body_index y, Free z)))
 135.162 -                          (recs ~~ subs)) rhs (fnameTs', fnss'))
 135.163 -                  handle RecError s => primrec_eq_err thy s eq
 135.164 -            in (fnameTs'', fnss'', 
 135.165 +              val (rhs', (fnames'', fnss'')) = subst (map2 (fn (x, y) => fn z =>
 135.166 +                (Free x, (body_index y, Free z))) recs subs) rhs (fnames', fnss')
 135.167 +                  handle RecError s => primrec_eq_err lthy s eq
 135.168 +            in (fnames'', fnss'', 
 135.169                  (list_abs_free (cargs' @ subs, rhs'))::fns)
 135.170              end)
 135.171  
 135.172 -  in (case AList.lookup (op =) fnameTs i of
 135.173 +  in (case AList.lookup (op =) fnames i of
 135.174        NONE =>
 135.175 -        if exists (equal fnameT o snd) fnameTs then
 135.176 +        if exists (fn (_, v) => fname = v) fnames then
 135.177            raise RecError ("inconsistent functions for datatype " ^ quote tname)
 135.178          else
 135.179            let
 135.180 -            val SOME (_, _, eqns as (_, (ls, _, rs, _, _)) :: _) =
 135.181 -              AList.lookup (op =) rec_eqns fnameT;
 135.182 -            val (fnameTs', fnss', fns) = fold_rev (trans eqns) constrs
 135.183 -              ((i, fnameT)::fnameTs, fnss, []) 
 135.184 +            val SOME (_, _, eqns' as (_, (ls, _, rs, _, _)) :: _) =
 135.185 +              AList.lookup (op =) eqns fname;
 135.186 +            val (fnames', fnss', fns) = fold_rev (trans eqns') constrs
 135.187 +              ((i, fname)::fnames, fnss, []) 
 135.188            in
 135.189 -            (fnameTs', (i, (fname, ls, rs, fns))::fnss')
 135.190 +            (fnames', (i, (fname, ls, rs, fns))::fnss')
 135.191            end
 135.192 -    | SOME fnameT' =>
 135.193 -        if fnameT = fnameT' then (fnameTs, fnss)
 135.194 +    | SOME fname' =>
 135.195 +        if fname = fname' then (fnames, fnss)
 135.196          else raise RecError ("inconsistent functions for datatype " ^ quote tname))
 135.197    end;
 135.198  
 135.199 @@ -195,18 +199,21 @@
 135.200  
 135.201  (* make definition *)
 135.202  
 135.203 -fun make_def thy fs (fname, ls, rs, rec_name, tname) =
 135.204 +fun make_def ctxt fixes fs (fname, ls, rs, rec_name, tname) =
 135.205    let
 135.206      val used = map fst (fold Term.add_frees fs []);
 135.207      val x = (Name.variant used "x", dummyT);
 135.208      val frees = ls @ x :: rs;
 135.209 -    val rhs = list_abs_free (frees,
 135.210 +    val raw_rhs = list_abs_free (frees,
 135.211        list_comb (Const (rec_name, dummyT), fs @ [Free x]))
 135.212 -    val def_name = Sign.base_name fname ^ "_" ^ Sign.base_name tname ^ "_def";
 135.213 -    val def_prop as _ $ _ $ t =
 135.214 -      singleton (Syntax.check_terms (ProofContext.init thy))
 135.215 -        (Logic.mk_equals (Const (fname, dummyT), rhs));
 135.216 -  in ((def_name, def_prop), subst_bounds (rev (map Free frees), strip_abs_body t)) end;
 135.217 +    val def_name = Thm.def_name (Sign.base_name fname);
 135.218 +    val rhs = singleton (Syntax.check_terms ctxt) raw_rhs;
 135.219 +    val SOME var = get_first (fn ((b, _), mx) =>
 135.220 +      if Binding.base_name b = fname then SOME (b, mx) else NONE) fixes;
 135.221 +  in
 135.222 +    ((var, ((Binding.name def_name, []), rhs)),
 135.223 +     subst_bounds (rev (map Free frees), strip_abs_body rhs))
 135.224 +  end;
 135.225  
 135.226  
 135.227  (* find datatypes which contain all datatypes in tnames' *)
 135.228 @@ -227,27 +234,36 @@
 135.229  
 135.230  local
 135.231  
 135.232 -fun gen_primrec_i note def alt_name invs fctxt eqns_atts thy =
 135.233 +fun prepare_spec prep_spec ctxt raw_fixes raw_spec =
 135.234    let
 135.235 -    val (raw_eqns, atts) = split_list eqns_atts;
 135.236 -    val eqns = map (apfst Binding.base_name) raw_eqns;
 135.237 -    val dt_info = NominalPackage.get_nominal_datatypes thy;
 135.238 -    val rec_eqns = fold_rev (process_eqn thy o snd) eqns [];
 135.239 +    val ((fixes, spec), _) = prep_spec
 135.240 +      raw_fixes (map (single o apsnd single) raw_spec) ctxt
 135.241 +  in (fixes, map (apsnd the_single) spec) end;
 135.242 +
 135.243 +fun gen_primrec set_group prep_spec prep_term invs fctxt raw_fixes raw_params raw_spec lthy =
 135.244 +  let
 135.245 +    val (fixes', spec) = prepare_spec prep_spec lthy (raw_fixes @ raw_params) raw_spec;
 135.246 +    val fixes = List.take (fixes', length raw_fixes);
 135.247 +    val (names_atts, spec') = split_list spec;
 135.248 +    val eqns' = map unquantify spec'
 135.249 +    val eqns = fold_rev (process_eqn lthy (fn v => Variable.is_fixed lthy v
 135.250 +      orelse exists (fn ((w, _), _) => v = Binding.base_name w) fixes)) spec' [];
 135.251 +    val dt_info = NominalPackage.get_nominal_datatypes (ProofContext.theory_of lthy);
 135.252      val lsrs :: lsrss = maps (fn (_, (_, _, eqns)) =>
 135.253 -      map (fn (_, (ls, _, rs, _, _)) => ls @ rs) eqns) rec_eqns
 135.254 +      map (fn (_, (ls, _, rs, _, _)) => ls @ rs) eqns) eqns
 135.255      val _ =
 135.256        (if forall (curry eq_set lsrs) lsrss andalso forall
 135.257           (fn (_, (_, _, (_, (ls, _, rs, _, _)) :: eqns)) =>
 135.258                 forall (fn (_, (ls', _, rs', _, _)) =>
 135.259                   ls = ls' andalso rs = rs') eqns
 135.260 -           | _ => true) rec_eqns
 135.261 +           | _ => true) eqns
 135.262         then () else primrec_err param_err);
 135.263 -    val tnames = distinct (op =) (map (#1 o snd) rec_eqns);
 135.264 +    val tnames = distinct (op =) (map (#1 o snd) eqns);
 135.265      val dts = find_dts dt_info tnames tnames;
 135.266      val main_fns = 
 135.267        map (fn (tname, {index, ...}) =>
 135.268          (index, 
 135.269 -          (fst o the o find_first (fn f => (#1 o snd) f = tname)) rec_eqns))
 135.270 +          (fst o the o find_first (fn (_, x) => #1 x = tname)) eqns))
 135.271        dts;
 135.272      val {descr, rec_names, rec_rewrites, ...} = 
 135.273        if null dts then
 135.274 @@ -256,32 +272,32 @@
 135.275      val descr = map (fn (i, (tname, args, constrs)) => (i, (tname, args,
 135.276        map (fn (cname, cargs) => (cname, fold (fn (dTs, dT) => fn dTs' =>
 135.277          dTs' @ dTs @ [dT]) cargs [])) constrs))) descr;
 135.278 -    val (fnameTs, fnss) =
 135.279 -      fold_rev (process_fun thy descr rec_eqns) main_fns ([], []);
 135.280 +    val (fnames, fnss) = fold_rev (process_fun lthy descr eqns) main_fns ([], []);
 135.281      val (fs, defs) = fold_rev (get_fns fnss) (descr ~~ rec_names) ([], []);
 135.282 -    val defs' = map (make_def thy fs) defs;
 135.283 -    val nameTs1 = map snd fnameTs;
 135.284 -    val nameTs2 = map fst rec_eqns;
 135.285 -    val _ = if gen_eq_set (op =) (nameTs1, nameTs2) then ()
 135.286 -            else primrec_err ("functions " ^ commas_quote (map fst nameTs2) ^
 135.287 -              "\nare not mutually recursive");
 135.288 -    val primrec_name =
 135.289 -      if alt_name = "" then (space_implode "_" (map (Sign.base_name o #1) defs)) else alt_name;
 135.290 -    val (defs_thms', thy') =
 135.291 -      thy
 135.292 -      |> Sign.add_path primrec_name
 135.293 -      |> fold_map def (map (fn ((name, t), _) => ((name, []), t)) defs');
 135.294 -    val cert = cterm_of thy';
 135.295 +    val defs' = map (make_def lthy fixes fs) defs;
 135.296 +    val names1 = map snd fnames;
 135.297 +    val names2 = map fst eqns;
 135.298 +    val _ = if gen_eq_set (op =) (names1, names2) then ()
 135.299 +      else primrec_err ("functions " ^ commas_quote names2 ^
 135.300 +        "\nare not mutually recursive");
 135.301 +    val (defs_thms, lthy') = lthy |>
 135.302 +      set_group ? LocalTheory.set_group (serial_string ()) |>
 135.303 +      fold_map (apfst (snd o snd) oo
 135.304 +        LocalTheory.define Thm.definitionK o fst) defs';
 135.305 +    val qualify = Binding.qualify
 135.306 +      (space_implode "_" (map (Sign.base_name o #1) defs));
 135.307 +    val names_atts' = map (apfst qualify) names_atts;
 135.308 +    val cert = cterm_of (ProofContext.theory_of lthy');
 135.309  
 135.310      fun mk_idx eq =
 135.311        let
 135.312 -        val Const c = head_of (fst (HOLogic.dest_eq (HOLogic.dest_Trueprop
 135.313 +        val Free (name, _) = head_of (fst (HOLogic.dest_eq (HOLogic.dest_Trueprop
 135.314            (Logic.strip_imp_concl eq))));
 135.315 -        val SOME i = AList.lookup op = (map swap fnameTs) c;
 135.316 +        val SOME i = AList.lookup op = (map swap fnames) name;
 135.317          val SOME (_, _, constrs) = AList.lookup op = descr i;
 135.318 -        val SOME (_, _, eqns) = AList.lookup op = rec_eqns c;
 135.319 +        val SOME (_, _, eqns'') = AList.lookup op = eqns name;
 135.320          val SOME (cname, (_, cargs, _, _, _)) = find_first
 135.321 -          (fn (_, (_, _, _, _, eq')) => eq = eq') eqns
 135.322 +          (fn (_, (_, _, _, _, eq')) => eq = eq') eqns''
 135.323        in (i, find_index (fn (cname', _) => cname = cname') constrs, cargs) end;
 135.324  
 135.325      val rec_rewritess =
 135.326 @@ -296,19 +312,15 @@
 135.327        curry (List.take o swap) (length fvars) |> map cert;
 135.328      val invs' = (case invs of
 135.329          NONE => map (fn (i, _) =>
 135.330 -          let
 135.331 -            val SOME (_, T) = AList.lookup op = fnameTs i
 135.332 -            val (Ts, U) = strip_type T
 135.333 -          in
 135.334 -            Abs ("x", List.drop (Ts, length lsrs + 1) ---> U, HOLogic.true_const)
 135.335 -          end) descr
 135.336 -      | SOME invs' => invs');
 135.337 +          Abs ("x", fastype_of (snd (nth defs' i)), HOLogic.true_const)) descr
 135.338 +      | SOME invs' => map (prep_term lthy') invs');
 135.339      val inst = (map cert fvars ~~ cfs) @
 135.340        (map (cert o Var) pvars ~~ map cert invs') @
 135.341        (case ctxtvars of
 135.342 -         [ctxtvar] => [(cert (Var ctxtvar), cert (the_default HOLogic.unit fctxt))]
 135.343 +         [ctxtvar] => [(cert (Var ctxtvar),
 135.344 +           cert (the_default HOLogic.unit (Option.map (prep_term lthy') fctxt)))]
 135.345         | _ => []);
 135.346 -    val rec_rewrites' = map (fn (_, eq) =>
 135.347 +    val rec_rewrites' = map (fn eq =>
 135.348        let
 135.349          val (i, j, cargs) = mk_idx eq
 135.350          val th = nth (nth rec_rewritess i) j;
 135.351 @@ -317,8 +329,8 @@
 135.352            strip_comb |> snd
 135.353        in (cargs, Logic.strip_imp_prems eq,
 135.354          Drule.cterm_instantiate (inst @
 135.355 -          (map (cterm_of thy') cargs' ~~ map (cterm_of thy' o Free) cargs)) th)
 135.356 -      end) eqns;
 135.357 +          (map cert cargs' ~~ map (cert o Free) cargs)) th)
 135.358 +      end) eqns';
 135.359  
 135.360      val prems = foldr1 (common_prefix op aconv) (map (prems_of o #3) rec_rewrites');
 135.361      val cprems = map cert prems;
 135.362 @@ -346,64 +358,37 @@
 135.363      val rule = implies_intr_list rule_prems
 135.364        (Conjunction.intr_balanced (map mk_eqn (rec_rewrites' ~~ asmss)));
 135.365  
 135.366 -    val goals = map (fn ((cargs, _, _), (_, eqn)) =>
 135.367 -      (list_all_free (cargs, eqn), [])) (rec_rewrites' ~~ eqns);
 135.368 +    val goals = map (fn ((cargs, _, _), eqn) =>
 135.369 +      (list_all_free (cargs, eqn), [])) (rec_rewrites' ~~ eqns');
 135.370  
 135.371    in
 135.372 -    thy' |>
 135.373 -    ProofContext.init |>
 135.374 +    lthy' |>
 135.375 +    Variable.add_fixes (map fst lsrs) |> snd |>
 135.376      Proof.theorem_i NONE
 135.377 -      (fn thss => ProofContext.theory (fn thy =>
 135.378 +      (fn thss => fn goal_ctxt =>
 135.379           let
 135.380 -           val simps = map standard (flat thss);
 135.381 -           val (simps', thy') =
 135.382 -             fold_map note ((map fst eqns ~~ atts) ~~ map single simps) thy;
 135.383 -           val simps'' = maps snd simps'
 135.384 +           val simps = ProofContext.export goal_ctxt lthy' (flat thss);
 135.385 +           val (simps', lthy'') = fold_map (LocalTheory.note Thm.theoremK)
 135.386 +             (names_atts' ~~ map single simps) lthy'
 135.387           in
 135.388 -           thy'
 135.389 -           |> note (("simps", [Simplifier.simp_add]), simps'')
 135.390 +           lthy''
 135.391 +           |> LocalTheory.note Thm.theoremK ((qualify (Binding.name "simps"),
 135.392 +             [Attrib.internal (K Simplifier.simp_add)]), maps snd simps')
 135.393             |> snd
 135.394 -           |> Sign.parent_path
 135.395 -         end))
 135.396 +         end)
 135.397        [goals] |>
 135.398      Proof.apply (Method.Basic (fn _ => Method.RAW_METHOD (fn _ =>
 135.399 -      rewrite_goals_tac (map snd defs_thms') THEN
 135.400 +      rewrite_goals_tac defs_thms THEN
 135.401        compose_tac (false, rule, length rule_prems) 1), Position.none)) |>
 135.402      Seq.hd
 135.403    end;
 135.404  
 135.405 -fun gen_primrec note def alt_name invs fctxt eqns thy =
 135.406 -  let
 135.407 -    val ((names, strings), srcss) = apfst split_list (split_list eqns);
 135.408 -    val atts = map (map (Attrib.attribute thy)) srcss;
 135.409 -    val eqn_ts = map (fn s => Syntax.read_prop_global thy s
 135.410 -      handle ERROR msg => cat_error msg ("The error(s) above occurred for " ^ s)) strings;
 135.411 -    val rec_ts = map (fn eq => head_of (fst (HOLogic.dest_eq
 135.412 -      (HOLogic.dest_Trueprop (Logic.strip_imp_concl eq))))
 135.413 -      handle TERM _ => primrec_eq_err thy "not a proper equation" eq) eqn_ts;
 135.414 -    val (_, eqn_ts') = OldPrimrecPackage.unify_consts thy rec_ts eqn_ts
 135.415 -  in
 135.416 -    gen_primrec_i note def alt_name
 135.417 -      (Option.map (map (Syntax.read_term_global thy)) invs)
 135.418 -      (Option.map (Syntax.read_term_global thy) fctxt)
 135.419 -      (names ~~ eqn_ts' ~~ atts) thy
 135.420 -  end;
 135.421 -
 135.422 -fun thy_note ((name, atts), thms) =
 135.423 -  PureThy.add_thmss [((name, thms), atts)] #-> (fn [thms] => pair (name, thms));
 135.424 -fun thy_def false ((name, atts), t) =
 135.425 -      PureThy.add_defs false [((name, t), atts)] #-> (fn [thm] => pair (name, thm))
 135.426 -  | thy_def true ((name, atts), t) =
 135.427 -      PureThy.add_defs_unchecked false [((name, t), atts)] #-> (fn [thm] => pair (name, thm));
 135.428 -
 135.429  in
 135.430  
 135.431 -val add_primrec = gen_primrec thy_note (thy_def false);
 135.432 -val add_primrec_unchecked = gen_primrec thy_note (thy_def true);
 135.433 -val add_primrec_i = gen_primrec_i thy_note (thy_def false);
 135.434 -val add_primrec_unchecked_i = gen_primrec_i thy_note (thy_def true);
 135.435 +val add_primrec = gen_primrec false Specification.check_specification (K I);
 135.436 +val add_primrec_cmd = gen_primrec true Specification.read_specification Syntax.read_term;
 135.437  
 135.438 -end; (*local*)
 135.439 +end;
 135.440  
 135.441  
 135.442  (* outer syntax *)
 135.443 @@ -419,25 +404,26 @@
 135.444  val parser2 = (invariant -- P.$$$ ":") |--
 135.445      (Scan.repeat1 (unless_flag P.term) >> SOME) -- Scan.optional parser1 NONE ||
 135.446    (parser1 >> pair NONE);
 135.447 -val parser3 =
 135.448 -  unless_flag P.name -- Scan.optional parser2 (NONE, NONE) ||
 135.449 -  (parser2 >> pair "");
 135.450 -val parser4 =
 135.451 -  (P.$$$ "unchecked" >> K true) -- Scan.optional parser3 ("", (NONE, NONE)) ||
 135.452 -  (parser3 >> pair false);
 135.453  val options =
 135.454    Scan.optional (P.$$$ "(" |-- P.!!!
 135.455 -    (parser4 --| P.$$$ ")")) (false, ("", (NONE, NONE)));
 135.456 +    (parser2 --| P.$$$ ")")) (NONE, NONE);
 135.457  
 135.458 -val primrec_decl =
 135.459 -  options -- Scan.repeat1 (SpecParse.opt_thm_name ":" -- P.prop);
 135.460 +fun pipe_error t = P.!!! (Scan.fail_with (K
 135.461 +  (cat_lines ["Equations must be separated by " ^ quote "|", quote t])));
 135.462 +
 135.463 +val statement = SpecParse.opt_thm_name ":" -- P.prop --| Scan.ahead
 135.464 +  ((P.term :-- pipe_error) || Scan.succeed ("",""));
 135.465 +
 135.466 +val statements = P.enum1 "|" statement;
 135.467 +
 135.468 +val primrec_decl = P.opt_target -- options --
 135.469 +  P.fixes -- P.for_fixes --| P.$$$ "where" -- statements;
 135.470  
 135.471  val _ =
 135.472    OuterSyntax.command "nominal_primrec" "define primitive recursive functions on nominal datatypes" K.thy_goal
 135.473 -    (primrec_decl >> (fn ((unchecked, (alt_name, (invs, fctxt))), eqns) =>
 135.474 -      Toplevel.print o Toplevel.theory_to_proof
 135.475 -        ((if unchecked then add_primrec_unchecked else add_primrec) alt_name invs fctxt
 135.476 -          (map P.triple_swap eqns))));
 135.477 +    (primrec_decl >> (fn ((((opt_target, (invs, fctxt)), raw_fixes), raw_params), raw_spec) =>
 135.478 +      Toplevel.print o Toplevel.local_theory_to_proof opt_target
 135.479 +        (add_primrec_cmd invs fctxt raw_fixes raw_params raw_spec)));
 135.480  
 135.481  end;
 135.482  
   136.1 --- a/src/HOL/PReal.thy	Tue Dec 30 08:18:54 2008 +0100
   136.2 +++ b/src/HOL/PReal.thy	Tue Dec 30 11:10:01 2008 +0100
   136.3 @@ -9,7 +9,7 @@
   136.4  header {* Positive real numbers *}
   136.5  
   136.6  theory PReal
   136.7 -imports Rational "~~/src/HOL/Library/Dense_Linear_Order"
   136.8 +imports Rational Dense_Linear_Order
   136.9  begin
  136.10  
  136.11  text{*Could be generalized and moved to @{text Ring_and_Field}*}
   137.1 --- a/src/HOL/Real.thy	Tue Dec 30 08:18:54 2008 +0100
   137.2 +++ b/src/HOL/Real.thy	Tue Dec 30 11:10:01 2008 +0100
   137.3 @@ -1,5 +1,5 @@
   137.4  theory Real
   137.5 -imports "~~/src/HOL/Real/RealVector"
   137.6 +imports RComplete RealVector
   137.7  begin
   137.8  
   137.9  end
   138.1 --- a/src/HOL/Real/HahnBanach/Bounds.thy	Tue Dec 30 08:18:54 2008 +0100
   138.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   138.3 @@ -1,82 +0,0 @@
   138.4 -(*  Title:      HOL/Real/HahnBanach/Bounds.thy
   138.5 -    Author:     Gertrud Bauer, TU Munich
   138.6 -*)
   138.7 -
   138.8 -header {* Bounds *}
   138.9 -
  138.10 -theory Bounds
  138.11 -imports Main ContNotDenum
  138.12 -begin
  138.13 -
  138.14 -locale lub =
  138.15 -  fixes A and x
  138.16 -  assumes least [intro?]: "(\<And>a. a \<in> A \<Longrightarrow> a \<le> b) \<Longrightarrow> x \<le> b"
  138.17 -    and upper [intro?]: "a \<in> A \<Longrightarrow> a \<le> x"
  138.18 -
  138.19 -lemmas [elim?] = lub.least lub.upper
  138.20 -
  138.21 -definition
  138.22 -  the_lub :: "'a::order set \<Rightarrow> 'a" where
  138.23 -  "the_lub A = The (lub A)"
  138.24 -
  138.25 -notation (xsymbols)
  138.26 -  the_lub  ("\<Squnion>_" [90] 90)
  138.27 -
  138.28 -lemma the_lub_equality [elim?]:
  138.29 -  assumes "lub A x"
  138.30 -  shows "\<Squnion>A = (x::'a::order)"
  138.31 -proof -
  138.32 -  interpret lub A x by fact
  138.33 -  show ?thesis
  138.34 -  proof (unfold the_lub_def)
  138.35 -    from `lub A x` show "The (lub A) = x"
  138.36 -    proof
  138.37 -      fix x' assume lub': "lub A x'"
  138.38 -      show "x' = x"
  138.39 -      proof (rule order_antisym)
  138.40 -	from lub' show "x' \<le> x"
  138.41 -	proof
  138.42 -          fix a assume "a \<in> A"
  138.43 -          then show "a \<le> x" ..
  138.44 -	qed
  138.45 -	show "x \<le> x'"
  138.46 -	proof
  138.47 -          fix a assume "a \<in> A"
  138.48 -          with lub' show "a \<le> x'" ..
  138.49 -	qed
  138.50 -      qed
  138.51 -    qed
  138.52 -  qed
  138.53 -qed
  138.54 -
  138.55 -lemma the_lubI_ex:
  138.56 -  assumes ex: "\<exists>x. lub A x"
  138.57 -  shows "lub A (\<Squnion>A)"
  138.58 -proof -
  138.59 -  from ex obtain x where x: "lub A x" ..
  138.60 -  also from x have [symmetric]: "\<Squnion>A = x" ..
  138.61 -  finally show ?thesis .
  138.62 -qed
  138.63 -
  138.64 -lemma lub_compat: "lub A x = isLub UNIV A x"
  138.65 -proof -
  138.66 -  have "isUb UNIV A = (\<lambda>x. A *<= x \<and> x \<in> UNIV)"
  138.67 -    by (rule ext) (simp only: isUb_def)
  138.68 -  then show ?thesis
  138.69 -    by (simp only: lub_def isLub_def leastP_def setge_def setle_def) blast
  138.70 -qed
  138.71 -
  138.72 -lemma real_complete:
  138.73 -  fixes A :: "real set"
  138.74 -  assumes nonempty: "\<exists>a. a \<in> A"
  138.75 -    and ex_upper: "\<exists>y. \<forall>a \<in> A. a \<le> y"
  138.76 -  shows "\<exists>x. lub A x"
  138.77 -proof -
  138.78 -  from ex_upper have "\<exists>y. isUb UNIV A y"
  138.79 -    unfolding isUb_def setle_def by blast
  138.80 -  with nonempty have "\<exists>x. isLub UNIV A x"
  138.81 -    by (rule reals_complete)
  138.82 -  then show ?thesis by (simp only: lub_compat)
  138.83 -qed
  138.84 -
  138.85 -end
   139.1 --- a/src/HOL/Real/HahnBanach/FunctionNorm.thy	Tue Dec 30 08:18:54 2008 +0100
   139.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   139.3 @@ -1,278 +0,0 @@
   139.4 -(*  Title:      HOL/Real/HahnBanach/FunctionNorm.thy
   139.5 -    Author:     Gertrud Bauer, TU Munich
   139.6 -*)
   139.7 -
   139.8 -header {* The norm of a function *}
   139.9 -
  139.10 -theory FunctionNorm
  139.11 -imports NormedSpace FunctionOrder
  139.12 -begin
  139.13 -
  139.14 -subsection {* Continuous linear forms*}
  139.15 -
  139.16 -text {*
  139.17 -  A linear form @{text f} on a normed vector space @{text "(V, \<parallel>\<cdot>\<parallel>)"}
  139.18 -  is \emph{continuous}, iff it is bounded, i.e.
  139.19 -  \begin{center}
  139.20 -  @{text "\<exists>c \<in> R. \<forall>x \<in> V. \<bar>f x\<bar> \<le> c \<cdot> \<parallel>x\<parallel>"}
  139.21 -  \end{center}
  139.22 -  In our application no other functions than linear forms are
  139.23 -  considered, so we can define continuous linear forms as bounded
  139.24 -  linear forms:
  139.25 -*}
  139.26 -
  139.27 -locale continuous = var_V + norm_syntax + linearform +
  139.28 -  assumes bounded: "\<exists>c. \<forall>x \<in> V. \<bar>f x\<bar> \<le> c * \<parallel>x\<parallel>"
  139.29 -
  139.30 -declare continuous.intro [intro?] continuous_axioms.intro [intro?]
  139.31 -
  139.32 -lemma continuousI [intro]:
  139.33 -  fixes norm :: "_ \<Rightarrow> real"  ("\<parallel>_\<parallel>")
  139.34 -  assumes "linearform V f"
  139.35 -  assumes r: "\<And>x. x \<in> V \<Longrightarrow> \<bar>f x\<bar> \<le> c * \<parallel>x\<parallel>"
  139.36 -  shows "continuous V norm f"
  139.37 -proof
  139.38 -  show "linearform V f" by fact
  139.39 -  from r have "\<exists>c. \<forall>x\<in>V. \<bar>f x\<bar> \<le> c * \<parallel>x\<parallel>" by blast
  139.40 -  then show "continuous_axioms V norm f" ..
  139.41 -qed
  139.42 -
  139.43 -
  139.44 -subsection {* The norm of a linear form *}
  139.45 -
  139.46 -text {*
  139.47 -  The least real number @{text c} for which holds
  139.48 -  \begin{center}
  139.49 -  @{text "\<forall>x \<in> V. \<bar>f x\<bar> \<le> c \<cdot> \<parallel>x\<parallel>"}
  139.50 -  \end{center}
  139.51 -  is called the \emph{norm} of @{text f}.
  139.52 -
  139.53 -  For non-trivial vector spaces @{text "V \<noteq> {0}"} the norm can be
  139.54 -  defined as
  139.55 -  \begin{center}
  139.56 -  @{text "\<parallel>f\<parallel> = \<sup>x \<noteq> 0. \<bar>f x\<bar> / \<parallel>x\<parallel>"}
  139.57 -  \end{center}
  139.58 -
  139.59 -  For the case @{text "V = {0}"} the supremum would be taken from an
  139.60 -  empty set. Since @{text \<real>} is unbounded, there would be no supremum.
  139.61 -  To avoid this situation it must be guaranteed that there is an
  139.62 -  element in this set. This element must be @{text "{} \<ge> 0"} so that
  139.63 -  @{text fn_norm} has the norm properties. Furthermore it does not
  139.64 -  have to change the norm in all other cases, so it must be @{text 0},
  139.65 -  as all other elements are @{text "{} \<ge> 0"}.
  139.66 -
  139.67 -  Thus we define the set @{text B} where the supremum is taken from as
  139.68 -  follows:
  139.69 -  \begin{center}
  139.70 -  @{text "{0} \<union> {\<bar>f x\<bar> / \<parallel>x\<parallel>. x \<noteq> 0 \<and> x \<in> F}"}
  139.71 -  \end{center}
  139.72 -
  139.73 -  @{text fn_norm} is equal to the supremum of @{text B}, if the
  139.74 -  supremum exists (otherwise it is undefined).
  139.75 -*}
  139.76 -
  139.77 -locale fn_norm = norm_syntax +
  139.78 -  fixes B defines "B V f \<equiv> {0} \<union> {\<bar>f x\<bar> / \<parallel>x\<parallel> | x. x \<noteq> 0 \<and> x \<in> V}"
  139.79 -  fixes fn_norm ("\<parallel>_\<parallel>\<hyphen>_" [0, 1000] 999)
  139.80 -  defines "\<parallel>f\<parallel>\<hyphen>V \<equiv> \<Squnion>(B V f)"
  139.81 -
  139.82 -locale normed_vectorspace_with_fn_norm = normed_vectorspace + fn_norm
  139.83 -
  139.84 -lemma (in fn_norm) B_not_empty [intro]: "0 \<in> B V f"
  139.85 -  by (simp add: B_def)
  139.86 -
  139.87 -text {*
  139.88 -  The following lemma states that every continuous linear form on a
  139.89 -  normed space @{text "(V, \<parallel>\<cdot>\<parallel>)"} has a function norm.
  139.90 -*}
  139.91 -
  139.92 -lemma (in normed_vectorspace_with_fn_norm) fn_norm_works:
  139.93 -  assumes "continuous V norm f"
  139.94 -  shows "lub (B V f) (\<parallel>f\<parallel>\<hyphen>V)"
  139.95 -proof -
  139.96 -  interpret continuous V norm f by fact
  139.97 -  txt {* The existence of the supremum is shown using the
  139.98 -    completeness of the reals. Completeness means, that every
  139.99 -    non-empty bounded set of reals has a supremum. *}
 139.100 -  have "\<exists>a. lub (B V f) a"
 139.101 -  proof (rule real_complete)
 139.102 -    txt {* First we have to show that @{text B} is non-empty: *}
 139.103 -    have "0 \<in> B V f" ..
 139.104 -    then show "\<exists>x. x \<in> B V f" ..
 139.105 -
 139.106 -    txt {* Then we have to show that @{text B} is bounded: *}
 139.107 -    show "\<exists>c. \<forall>y \<in> B V f. y \<le> c"
 139.108 -    proof -
 139.109 -      txt {* We know that @{text f} is bounded by some value @{text c}. *}
 139.110 -      from bounded obtain c where c: "\<forall>x \<in> V. \<bar>f x\<bar> \<le> c * \<parallel>x\<parallel>" ..
 139.111 -
 139.112 -      txt {* To prove the thesis, we have to show that there is some
 139.113 -        @{text b}, such that @{text "y \<le> b"} for all @{text "y \<in>
 139.114 -        B"}. Due to the definition of @{text B} there are two cases. *}
 139.115 -
 139.116 -      def b \<equiv> "max c 0"
 139.117 -      have "\<forall>y \<in> B V f. y \<le> b"
 139.118 -      proof
 139.119 -        fix y assume y: "y \<in> B V f"
 139.120 -        show "y \<le> b"
 139.121 -        proof cases
 139.122 -          assume "y = 0"
 139.123 -          then show ?thesis unfolding b_def by arith
 139.124 -        next
 139.125 -          txt {* The second case is @{text "y = \<bar>f x\<bar> / \<parallel>x\<parallel>"} for some
 139.126 -            @{text "x \<in> V"} with @{text "x \<noteq> 0"}. *}
 139.127 -          assume "y \<noteq> 0"
 139.128 -          with y obtain x where y_rep: "y = \<bar>f x\<bar> * inverse \<parallel>x\<parallel>"
 139.129 -              and x: "x \<in> V" and neq: "x \<noteq> 0"
 139.130 -            by (auto simp add: B_def real_divide_def)
 139.131 -          from x neq have gt: "0 < \<parallel>x\<parallel>" ..
 139.132 -
 139.133 -          txt {* The thesis follows by a short calculation using the
 139.134 -            fact that @{text f} is bounded. *}
 139.135 -
 139.136 -          note y_rep
 139.137 -          also have "\<bar>f x\<bar> * inverse \<parallel>x\<parallel> \<le> (c * \<parallel>x\<parallel>) * inverse \<parallel>x\<parallel>"
 139.138 -          proof (rule mult_right_mono)
 139.139 -            from c x show "\<bar>f x\<bar> \<le> c * \<parallel>x\<parallel>" ..
 139.140 -            from gt have "0 < inverse \<parallel>x\<parallel>" 
 139.141 -              by (rule positive_imp_inverse_positive)
 139.142 -            then show "0 \<le> inverse \<parallel>x\<parallel>" by (rule order_less_imp_le)
 139.143 -          qed
 139.144 -          also have "\<dots> = c * (\<parallel>x\<parallel> * inverse \<parallel>x\<parallel>)"
 139.145 -            by (rule real_mult_assoc)
 139.146 -          also
 139.147 -          from gt have "\<parallel>x\<parallel> \<noteq> 0" by simp
 139.148 -          then have "\<parallel>x\<parallel> * inverse \<parallel>x\<parallel> = 1" by simp 
 139.149 -          also have "c * 1 \<le> b" by (simp add: b_def le_maxI1)
 139.150 -          finally show "y \<le> b" .
 139.151 -        qed
 139.152 -      qed
 139.153 -      then show ?thesis ..
 139.154 -    qed
 139.155 -  qed
 139.156 -  then show ?thesis unfolding fn_norm_def by (rule the_lubI_ex)
 139.157 -qed
 139.158 -
 139.159 -lemma (in normed_vectorspace_with_fn_norm) fn_norm_ub [iff?]:
 139.160 -  assumes "continuous V norm f"
 139.161 -  assumes b: "b \<in> B V f"
 139.162 -  shows "b \<le> \<parallel>f\<parallel>\<hyphen>V"
 139.163 -proof -
 139.164 -  interpret continuous V norm f by fact
 139.165 -  have "lub (B V f) (\<parallel>f\<parallel>\<hyphen>V)"
 139.166 -    using `continuous V norm f` by (rule fn_norm_works)
 139.167 -  from this and b show ?thesis ..
 139.168 -qed
 139.169 -
 139.170 -lemma (in normed_vectorspace_with_fn_norm) fn_norm_leastB:
 139.171 -  assumes "continuous V norm f"
 139.172 -  assumes b: "\<And>b. b \<in> B V f \<Longrightarrow> b \<le> y"
 139.173 -  shows "\<parallel>f\<parallel>\<hyphen>V \<le> y"
 139.174 -proof -
 139.175 -  interpret continuous V norm f by fact
 139.176 -  have "lub (B V f) (\<parallel>f\<parallel>\<hyphen>V)"
 139.177 -    using `continuous V norm f` by (rule fn_norm_works)
 139.178 -  from this and b show ?thesis ..
 139.179 -qed
 139.180 -
 139.181 -text {* The norm of a continuous function is always @{text "\<ge> 0"}. *}
 139.182 -
 139.183 -lemma (in normed_vectorspace_with_fn_norm) fn_norm_ge_zero [iff]:
 139.184 -  assumes "continuous V norm f"
 139.185 -  shows "0 \<le> \<parallel>f\<parallel>\<hyphen>V"
 139.186 -proof -
 139.187 -  interpret continuous V norm f by fact
 139.188 -  txt {* The function norm is defined as the supremum of @{text B}.
 139.189 -    So it is @{text "\<ge> 0"} if all elements in @{text B} are @{text "\<ge>
 139.190 -    0"}, provided the supremum exists and @{text B} is not empty. *}
 139.191 -  have "lub (B V f) (\<parallel>f\<parallel>\<hyphen>V)"
 139.192 -    using `continuous V norm f` by (rule fn_norm_works)
 139.193 -  moreover have "0 \<in> B V f" ..
 139.194 -  ultimately show ?thesis ..
 139.195 -qed
 139.196 -
 139.197 -text {*
 139.198 -  \medskip The fundamental property of function norms is:
 139.199 -  \begin{center}
 139.200 -  @{text "\<bar>f x\<bar> \<le> \<parallel>f\<parallel> \<cdot> \<parallel>x\<parallel>"}
 139.201 -  \end{center}
 139.202 -*}
 139.203 -
 139.204 -lemma (in normed_vectorspace_with_fn_norm) fn_norm_le_cong:
 139.205 -  assumes "continuous V norm f" "linearform V f"
 139.206 -  assumes x: "x \<in> V"
 139.207 -  shows "\<bar>f x\<bar> \<le> \<parallel>f\<parallel>\<hyphen>V * \<parallel>x\<parallel>"
 139.208 -proof -
 139.209 -  interpret continuous V norm f by fact
 139.210 -  interpret linearform V f .
 139.211 -  show ?thesis
 139.212 -  proof cases
 139.213 -    assume "x = 0"
 139.214 -    then have "\<bar>f x\<bar> = \<bar>f 0\<bar>" by simp
 139.215 -    also have "f 0 = 0" by rule unfold_locales
 139.216 -    also have "\<bar>\<dots>\<bar> = 0" by simp
 139.217 -    also have a: "0 \<le> \<parallel>f\<parallel>\<hyphen>V"
 139.218 -      using `continuous V norm f` by (rule fn_norm_ge_zero)
 139.219 -    from x have "0 \<le> norm x" ..
 139.220 -    with a have "0 \<le> \<parallel>f\<parallel>\<hyphen>V * \<parallel>x\<parallel>" by (simp add: zero_le_mult_iff)
 139.221 -    finally show "\<bar>f x\<bar> \<le> \<parallel>f\<parallel>\<hyphen>V * \<parallel>x\<parallel>" .
 139.222 -  next
 139.223 -    assume "x \<noteq> 0"
 139.224 -    with x have neq: "\<parallel>x\<parallel> \<noteq> 0" by simp
 139.225 -    then have "\<bar>f x\<bar> = (\<bar>f x\<bar> * inverse \<parallel>x\<parallel>) * \<parallel>x\<parallel>" by simp
 139.226 -    also have "\<dots> \<le>  \<parallel>f\<parallel>\<hyphen>V * \<parallel>x\<parallel>"
 139.227 -    proof (rule mult_right_mono)
 139.228 -      from x show "0 \<le> \<parallel>x\<parallel>" ..
 139.229 -      from x and neq have "\<bar>f x\<bar> * inverse \<parallel>x\<parallel> \<in> B V f"
 139.230 -	by (auto simp add: B_def real_divide_def)
 139.231 -      with `continuous V norm f` show "\<bar>f x\<bar> * inverse \<parallel>x\<parallel> \<le> \<parallel>f\<parallel>\<hyphen>V"
 139.232 -	by (rule fn_norm_ub)
 139.233 -    qed
 139.234 -    finally show ?thesis .
 139.235 -  qed
 139.236 -qed
 139.237 -
 139.238 -text {*
 139.239 -  \medskip The function norm is the least positive real number for
 139.240 -  which the following inequation holds:
 139.241 -  \begin{center}
 139.242 -    @{text "\<bar>f x\<bar> \<le> c \<cdot> \<parallel>x\<parallel>"}
 139.243 -  \end{center}
 139.244 -*}
 139.245 -
 139.246 -lemma (in normed_vectorspace_with_fn_norm) fn_norm_least [intro?]:
 139.247 -  assumes "continuous V norm f"
 139.248 -  assumes ineq: "\<forall>x \<in> V. \<bar>f x\<bar> \<le> c * \<parallel>x\<parallel>" and ge: "0 \<le> c"
 139.249 -  shows "\<parallel>f\<parallel>\<hyphen>V \<le> c"
 139.250 -proof -
 139.251 -  interpret continuous V norm f by fact
 139.252 -  show ?thesis
 139.253 -  proof (rule fn_norm_leastB [folded B_def fn_norm_def])
 139.254 -    fix b assume b: "b \<in> B V f"
 139.255 -    show "b \<le> c"
 139.256 -    proof cases
 139.257 -      assume "b = 0"
 139.258 -      with ge show ?thesis by simp
 139.259 -    next
 139.260 -      assume "b \<noteq> 0"
 139.261 -      with b obtain x where b_rep: "b = \<bar>f x\<bar> * inverse \<parallel>x\<parallel>"
 139.262 -        and x_neq: "x \<noteq> 0" and x: "x \<in> V"
 139.263 -	by (auto simp add: B_def real_divide_def)
 139.264 -      note b_rep
 139.265 -      also have "\<bar>f x\<bar> * inverse \<parallel>x\<parallel> \<le> (c * \<parallel>x\<parallel>) * inverse \<parallel>x\<parallel>"
 139.266 -      proof (rule mult_right_mono)
 139.267 -	have "0 < \<parallel>x\<parallel>" using x x_neq ..
 139.268 -	then show "0 \<le> inverse \<parallel>x\<parallel>" by simp
 139.269 -	from ineq and x show "\<bar>f x\<bar> \<le> c * \<parallel>x\<parallel>" ..
 139.270 -      qed
 139.271 -      also have "\<dots> = c"
 139.272 -      proof -
 139.273 -	from x_neq and x have "\<parallel>x\<parallel> \<noteq> 0" by simp
 139.274 -	then show ?thesis by simp
 139.275 -      qed
 139.276 -      finally show ?thesis .
 139.277 -    qed
 139.278 -  qed (insert `continuous V norm f`, simp_all add: continuous_def)
 139.279 -qed
 139.280 -
 139.281 -end
   140.1 --- a/src/HOL/Real/HahnBanach/FunctionOrder.thy	Tue Dec 30 08:18:54 2008 +0100
   140.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   140.3 @@ -1,142 +0,0 @@
   140.4 -(*  Title:      HOL/Real/HahnBanach/FunctionOrder.thy
   140.5 -    ID:         $Id$
   140.6 -    Author:     Gertrud Bauer, TU Munich
   140.7 -*)
   140.8 -
   140.9 -header {* An order on functions *}
  140.10 -
  140.11 -theory FunctionOrder
  140.12 -imports Subspace Linearform
  140.13 -begin
  140.14 -
  140.15 -subsection {* The graph of a function *}
  140.16 -
  140.17 -text {*
  140.18 -  We define the \emph{graph} of a (real) function @{text f} with
  140.19 -  domain @{text F} as the set
  140.20 -  \begin{center}
  140.21 -  @{text "{(x, f x). x \<in> F}"}
  140.22 -  \end{center}
  140.23 -  So we are modeling partial functions by specifying the domain and
  140.24 -  the mapping function. We use the term ``function'' also for its
  140.25 -  graph.
  140.26 -*}
  140.27 -
  140.28 -types 'a graph = "('a \<times> real) set"
  140.29 -
  140.30 -definition
  140.31 -  graph :: "'a set \<Rightarrow> ('a \<Rightarrow> real) \<Rightarrow> 'a graph" where
  140.32 -  "graph F f = {(x, f x) | x. x \<in> F}"
  140.33 -
  140.34 -lemma graphI [intro]: "x \<in> F \<Longrightarrow> (x, f x) \<in> graph F f"
  140.35 -  unfolding graph_def by blast
  140.36 -
  140.37 -lemma graphI2 [intro?]: "x \<in> F \<Longrightarrow> \<exists>t \<in> graph F f. t = (x, f x)"
  140.38 -  unfolding graph_def by blast
  140.39 -
  140.40 -lemma graphE [elim?]:
  140.41 -    "(x, y) \<in> graph F f \<Longrightarrow> (x \<in> F \<Longrightarrow> y = f x \<Longrightarrow> C) \<Longrightarrow> C"
  140.42 -  unfolding graph_def by blast
  140.43 -
  140.44 -
  140.45 -subsection {* Functions ordered by domain extension *}
  140.46 -
  140.47 -text {*
  140.48 -  A function @{text h'} is an extension of @{text h}, iff the graph of
  140.49 -  @{text h} is a subset of the graph of @{text h'}.
  140.50 -*}
  140.51 -
  140.52 -lemma graph_extI:
  140.53 -  "(\<And>x. x \<in> H \<Longrightarrow> h x = h' x) \<Longrightarrow> H \<subseteq> H'
  140.54 -    \<Longrightarrow> graph H h \<subseteq> graph H' h'"
  140.55 -  unfolding graph_def by blast
  140.56 -
  140.57 -lemma graph_extD1 [dest?]:
  140.58 -  "graph H h \<subseteq> graph H' h' \<Longrightarrow> x \<in> H \<Longrightarrow> h x = h' x"
  140.59 -  unfolding graph_def by blast
  140.60 -
  140.61 -lemma graph_extD2 [dest?]:
  140.62 -  "graph H h \<subseteq> graph H' h' \<Longrightarrow> H \<subseteq> H'"
  140.63 -  unfolding graph_def by blast
  140.64 -
  140.65 -
  140.66 -subsection {* Domain and function of a graph *}
  140.67 -
  140.68 -text {*
  140.69 -  The inverse functions to @{text graph} are @{text domain} and @{text
  140.70 -  funct}.
  140.71 -*}
  140.72 -
  140.73 -definition
  140.74 -  "domain" :: "'a graph \<Rightarrow> 'a set" where
  140.75 -  "domain g = {x. \<exists>y. (x, y) \<in> g}"
  140.76 -
  140.77 -definition
  140.78 -  funct :: "'a graph \<Rightarrow> ('a \<Rightarrow> real)" where
  140.79 -  "funct g = (\<lambda>x. (SOME y. (x, y) \<in> g))"
  140.80 -
  140.81 -text {*
  140.82 -  The following lemma states that @{text g} is the graph of a function
  140.83 -  if the relation induced by @{text g} is unique.
  140.84 -*}
  140.85 -
  140.86 -lemma graph_domain_funct:
  140.87 -  assumes uniq: "\<And>x y z. (x, y) \<in> g \<Longrightarrow> (x, z) \<in> g \<Longrightarrow> z = y"
  140.88 -  shows "graph (domain g) (funct g) = g"
  140.89 -  unfolding domain_def funct_def graph_def
  140.90 -proof auto  (* FIXME !? *)
  140.91 -  fix a b assume g: "(a, b) \<in> g"
  140.92 -  from g show "(a, SOME y. (a, y) \<in> g) \<in> g" by (rule someI2)
  140.93 -  from g show "\<exists>y. (a, y) \<in> g" ..
  140.94 -  from g show "b = (SOME y. (a, y) \<in> g)"
  140.95 -  proof (rule some_equality [symmetric])
  140.96 -    fix y assume "(a, y) \<in> g"
  140.97 -    with g show "y = b" by (rule uniq)
  140.98 -  qed
  140.99 -qed
 140.100 -
 140.101 -
 140.102 -subsection {* Norm-preserving extensions of a function *}
 140.103 -
 140.104 -text {*
 140.105 -  Given a linear form @{text f} on the space @{text F} and a seminorm
 140.106 -  @{text p} on @{text E}. The set of all linear extensions of @{text
 140.107 -  f}, to superspaces @{text H} of @{text F}, which are bounded by
 140.108 -  @{text p}, is defined as follows.
 140.109 -*}
 140.110 -
 140.111 -definition
 140.112 -  norm_pres_extensions ::
 140.113 -    "'a::{plus, minus, uminus, zero} set \<Rightarrow> ('a \<Rightarrow> real) \<Rightarrow> 'a set \<Rightarrow> ('a \<Rightarrow> real)
 140.114 -      \<Rightarrow> 'a graph set" where
 140.115 -    "norm_pres_extensions E p F f
 140.116 -      = {g. \<exists>H h. g = graph H h
 140.117 -          \<and> linearform H h
 140.118 -          \<and> H \<unlhd> E
 140.119 -          \<and> F \<unlhd> H
 140.120 -          \<and> graph F f \<subseteq> graph H h
 140.121 -          \<and> (\<forall>x \<in> H. h x \<le> p x)}"
 140.122 -
 140.123 -lemma norm_pres_extensionE [elim]:
 140.124 -  "g \<in> norm_pres_extensions E p F f
 140.125 -  \<Longrightarrow> (\<And>H h. g = graph H h \<Longrightarrow> linearform H h
 140.126 -        \<Longrightarrow> H \<unlhd> E \<Longrightarrow> F \<unlhd> H \<Longrightarrow> graph F f \<subseteq> graph H h
 140.127 -        \<Longrightarrow> \<forall>x \<in> H. h x \<le> p x \<Longrightarrow> C) \<Longrightarrow> C"
 140.128 -  unfolding norm_pres_extensions_def by blast
 140.129 -
 140.130 -lemma norm_pres_extensionI2 [intro]:
 140.131 -  "linearform H h \<Longrightarrow> H \<unlhd> E \<Longrightarrow> F \<unlhd> H
 140.132 -    \<Longrightarrow> graph F f \<subseteq> graph H h \<Longrightarrow> \<forall>x \<in> H. h x \<le> p x
 140.133 -    \<Longrightarrow> graph H h \<in> norm_pres_extensions E p F f"
 140.134 -  unfolding norm_pres_extensions_def by blast
 140.135 -
 140.136 -lemma norm_pres_extensionI:  (* FIXME ? *)
 140.137 -  "\<exists>H h. g = graph H h
 140.138 -    \<and> linearform H h
 140.139 -    \<and> H \<unlhd> E
 140.140 -    \<and> F \<unlhd> H
 140.141 -    \<and> graph F f \<subseteq> graph H h
 140.142 -    \<and> (\<forall>x \<in> H. h x \<le> p x) \<Longrightarrow> g \<in> norm_pres_extensions E p F f"
 140.143 -  unfolding norm_pres_extensions_def by blast
 140.144 -
 140.145 -end
   141.1 --- a/src/HOL/Real/HahnBanach/HahnBanach.thy	Tue Dec 30 08:18:54 2008 +0100
   141.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   141.3 @@ -1,509 +0,0 @@
   141.4 -(*  Title:      HOL/Real/HahnBanach/HahnBanach.thy
   141.5 -    Author:     Gertrud Bauer, TU Munich
   141.6 -*)
   141.7 -
   141.8 -header {* The Hahn-Banach Theorem *}
   141.9 -
  141.10 -theory HahnBanach
  141.11 -imports HahnBanachLemmas
  141.12 -begin
  141.13 -
  141.14 -text {*
  141.15 -  We present the proof of two different versions of the Hahn-Banach
  141.16 -  Theorem, closely following \cite[\S36]{Heuser:1986}.
  141.17 -*}
  141.18 -
  141.19 -subsection {* The Hahn-Banach Theorem for vector spaces *}
  141.20 -
  141.21 -text {*
  141.22 -  \textbf{Hahn-Banach Theorem.} Let @{text F} be a subspace of a real
  141.23 -  vector space @{text E}, let @{text p} be a semi-norm on @{text E},
  141.24 -  and @{text f} be a linear form defined on @{text F} such that @{text
  141.25 -  f} is bounded by @{text p}, i.e.  @{text "\<forall>x \<in> F. f x \<le> p x"}.  Then
  141.26 -  @{text f} can be extended to a linear form @{text h} on @{text E}
  141.27 -  such that @{text h} is norm-preserving, i.e. @{text h} is also
  141.28 -  bounded by @{text p}.
  141.29 -
  141.30 -  \bigskip
  141.31 -  \textbf{Proof Sketch.}
  141.32 -  \begin{enumerate}
  141.33 -
  141.34 -  \item Define @{text M} as the set of norm-preserving extensions of
  141.35 -  @{text f} to subspaces of @{text E}. The linear forms in @{text M}
  141.36 -  are ordered by domain extension.
  141.37 -
  141.38 -  \item We show that every non-empty chain in @{text M} has an upper
  141.39 -  bound in @{text M}.
  141.40 -
  141.41 -  \item With Zorn's Lemma we conclude that there is a maximal function
  141.42 -  @{text g} in @{text M}.
  141.43 -
  141.44 -  \item The domain @{text H} of @{text g} is the whole space @{text
  141.45 -  E}, as shown by classical contradiction:
  141.46 -
  141.47 -  \begin{itemize}
  141.48 -
  141.49 -  \item Assuming @{text g} is not defined on whole @{text E}, it can
  141.50 -  still be extended in a norm-preserving way to a super-space @{text
  141.51 -  H'} of @{text H}.
  141.52 -
  141.53 -  \item Thus @{text g} can not be maximal. Contradiction!
  141.54 -
  141.55 -  \end{itemize}
  141.56 -  \end{enumerate}
  141.57 -*}
  141.58 -
  141.59 -theorem HahnBanach:
  141.60 -  assumes E: "vectorspace E" and "subspace F E"
  141.61 -    and "seminorm E p" and "linearform F f"
  141.62 -  assumes fp: "\<forall>x \<in> F. f x \<le> p x"
  141.63 -  shows "\<exists>h. linearform E h \<and> (\<forall>x \<in> F. h x = f x) \<and> (\<forall>x \<in> E. h x \<le> p x)"
  141.64 -    -- {* Let @{text E} be a vector space, @{text F} a subspace of @{text E}, @{text p} a seminorm on @{text E}, *}
  141.65 -    -- {* and @{text f} a linear form on @{text F} such that @{text f} is bounded by @{text p}, *}
  141.66 -    -- {* then @{text f} can be extended to a linear form @{text h} on @{text E} in a norm-preserving way. \skp *}
  141.67 -proof -
  141.68 -  interpret vectorspace E by fact
  141.69 -  interpret subspace F E by fact
  141.70 -  interpret seminorm E p by fact
  141.71 -  interpret linearform F f by fact
  141.72 -  def M \<equiv> "norm_pres_extensions E p F f"
  141.73 -  then have M: "M = \<dots>" by (simp only:)
  141.74 -  from E have F: "vectorspace F" ..
  141.75 -  note FE = `F \<unlhd> E`
  141.76 -  {
  141.77 -    fix c assume cM: "c \<in> chain M" and ex: "\<exists>x. x \<in> c"
  141.78 -    have "\<Union>c \<in> M"
  141.79 -      -- {* Show that every non-empty chain @{text c} of @{text M} has an upper bound in @{text M}: *}
  141.80 -      -- {* @{text "\<Union>c"} is greater than any element of the chain @{text c}, so it suffices to show @{text "\<Union>c \<in> M"}. *}
  141.81 -      unfolding M_def
  141.82 -    proof (rule norm_pres_extensionI)
  141.83 -      let ?H = "domain (\<Union>c)"
  141.84 -      let ?h = "funct (\<Union>c)"
  141.85 -
  141.86 -      have a: "graph ?H ?h = \<Union>c"
  141.87 -      proof (rule graph_domain_funct)
  141.88 -        fix x y z assume "(x, y) \<in> \<Union>c" and "(x, z) \<in> \<Union>c"
  141.89 -        with M_def cM show "z = y" by (rule sup_definite)
  141.90 -      qed
  141.91 -      moreover from M cM a have "linearform ?H ?h"
  141.92 -        by (rule sup_lf)
  141.93 -      moreover from a M cM ex FE E have "?H \<unlhd> E"
  141.94 -        by (rule sup_subE)
  141.95 -      moreover from a M cM ex FE have "F \<unlhd> ?H"
  141.96 -        by (rule sup_supF)
  141.97 -      moreover from a M cM ex have "graph F f \<subseteq> graph ?H ?h"
  141.98 -        by (rule sup_ext)
  141.99 -      moreover from a M cM have "\<forall>x \<in> ?H. ?h x \<le> p x"
 141.100 -        by (rule sup_norm_pres)
 141.101 -      ultimately show "\<exists>H h. \<Union>c = graph H h
 141.102 -          \<and> linearform H h
 141.103 -          \<and> H \<unlhd> E
 141.104 -          \<and> F \<unlhd> H
 141.105 -          \<and> graph F f \<subseteq> graph H h
 141.106 -          \<and> (\<forall>x \<in> H. h x \<le> p x)" by blast
 141.107 -    qed
 141.108 -  }
 141.109 -  then have "\<exists>g \<in> M. \<forall>x \<in> M. g \<subseteq> x \<longrightarrow> g = x"
 141.110 -  -- {* With Zorn's Lemma we can conclude that there is a maximal element in @{text M}. \skp *}
 141.111 -  proof (rule Zorn's_Lemma)
 141.112 -      -- {* We show that @{text M} is non-empty: *}
 141.113 -    show "graph F f \<in> M"
 141.114 -      unfolding M_def
 141.115 -    proof (rule norm_pres_extensionI2)
 141.116 -      show "linearform F f" by fact
 141.117 -      show "F \<unlhd> E" by fact
 141.118 -      from F show "F \<unlhd> F" by (rule vectorspace.subspace_refl)
 141.119 -      show "graph F f \<subseteq> graph F f" ..
 141.120 -      show "\<forall>x\<in>F. f x \<le> p x" by fact
 141.121 -    qed
 141.122 -  qed
 141.123 -  then obtain g where gM: "g \<in> M" and gx: "\<forall>x \<in> M. g \<subseteq> x \<longrightarrow> g = x"
 141.124 -    by blast
 141.125 -  from gM obtain H h where
 141.126 -      g_rep: "g = graph H h"
 141.127 -    and linearform: "linearform H h"
 141.128 -    and HE: "H \<unlhd> E" and FH: "F \<unlhd> H"
 141.129 -    and graphs: "graph F f \<subseteq> graph H h"
 141.130 -    and hp: "\<forall>x \<in> H. h x \<le> p x" unfolding M_def ..
 141.131 -      -- {* @{text g} is a norm-preserving extension of @{text f}, in other words: *}
 141.132 -      -- {* @{text g} is the graph of some linear form @{text h} defined on a subspace @{text H} of @{text E}, *}
 141.133 -      -- {* and @{text h} is an extension of @{text f} that is again bounded by @{text p}. \skp *}
 141.134 -  from HE E have H: "vectorspace H"
 141.135 -    by (rule subspace.vectorspace)
 141.136 -
 141.137 -  have HE_eq: "H = E"
 141.138 -    -- {* We show that @{text h} is defined on whole @{text E} by classical contradiction. \skp *}
 141.139 -  proof (rule classical)
 141.140 -    assume neq: "H \<noteq> E"
 141.141 -      -- {* Assume @{text h} is not defined on whole @{text E}. Then show that @{text h} can be extended *}
 141.142 -      -- {* in a norm-preserving way to a function @{text h'} with the graph @{text g'}. \skp *}
 141.143 -    have "\<exists>g' \<in> M. g \<subseteq> g' \<and> g \<noteq> g'"
 141.144 -    proof -
 141.145 -      from HE have "H \<subseteq> E" ..
 141.146 -      with neq obtain x' where x'E: "x' \<in> E" and "x' \<notin> H" by blast
 141.147 -      obtain x': "x' \<noteq> 0"
 141.148 -      proof
 141.149 -        show "x' \<noteq> 0"
 141.150 -        proof
 141.151 -          assume "x' = 0"
 141.152 -          with H have "x' \<in> H" by (simp only: vectorspace.zero)
 141.153 -          with `x' \<notin> H` show False by contradiction
 141.154 -        qed
 141.155 -      qed
 141.156 -
 141.157 -      def H' \<equiv> "H + lin x'"
 141.158 -        -- {* Define @{text H'} as the direct sum of @{text H} and the linear closure of @{text x'}. \skp *}
 141.159 -      have HH': "H \<unlhd> H'"
 141.160 -      proof (unfold H'_def)
 141.161 -        from x'E have "vectorspace (lin x')" ..
 141.162 -        with H show "H \<unlhd> H + lin x'" ..
 141.163 -      qed
 141.164 -
 141.165 -      obtain xi where
 141.166 -        xi: "\<forall>y \<in> H. - p (y + x') - h y \<le> xi
 141.167 -          \<and> xi \<le> p (y + x') - h y"
 141.168 -        -- {* Pick a real number @{text \<xi>} that fulfills certain inequations; this will *}
 141.169 -        -- {* be used to establish that @{text h'} is a norm-preserving extension of @{text h}.
 141.170 -           \label{ex-xi-use}\skp *}
 141.171 -      proof -
 141.172 -        from H have "\<exists>xi. \<forall>y \<in> H. - p (y + x') - h y \<le> xi
 141.173 -            \<and> xi \<le> p (y + x') - h y"
 141.174 -        proof (rule ex_xi)
 141.175 -          fix u v assume u: "u \<in> H" and v: "v \<in> H"
 141.176 -          with HE have uE: "u \<in> E" and vE: "v \<in> E" by auto
 141.177 -          from H u v linearform have "h v - h u = h (v - u)"
 141.178 -            by (simp add: linearform.diff)
 141.179 -          also from hp and H u v have "\<dots> \<le> p (v - u)"
 141.180 -            by (simp only: vectorspace.diff_closed)
 141.181 -          also from x'E uE vE have "v - u = x' + - x' + v + - u"
 141.182 -            by (simp add: diff_eq1)
 141.183 -          also from x'E uE vE have "\<dots> = v + x' + - (u + x')"
 141.184 -            by (simp add: add_ac)
 141.185 -          also from x'E uE vE have "\<dots> = (v + x') - (u + x')"
 141.186 -            by (simp add: diff_eq1)
 141.187 -          also from x'E uE vE E have "p \<dots> \<le> p (v + x') + p (u + x')"
 141.188 -            by (simp add: diff_subadditive)
 141.189 -          finally have "h v - h u \<le> p (v + x') + p (u + x')" .
 141.190 -          then show "- p (u + x') - h u \<le> p (v + x') - h v" by simp
 141.191 -        qed
 141.192 -        then show thesis by (blast intro: that)
 141.193 -      qed
 141.194 -
 141.195 -      def h' \<equiv> "\<lambda>x. let (y, a) =
 141.196 -          SOME (y, a). x = y + a \<cdot> x' \<and> y \<in> H in h y + a * xi"
 141.197 -        -- {* Define the extension @{text h'} of @{text h} to @{text H'} using @{text \<xi>}. \skp *}
 141.198 -
 141.199 -      have "g \<subseteq> graph H' h' \<and> g \<noteq> graph H' h'"
 141.200 -        -- {* @{text h'} is an extension of @{text h} \dots \skp *}
 141.201 -      proof
 141.202 -        show "g \<subseteq> graph H' h'"
 141.203 -        proof -
 141.204 -          have  "graph H h \<subseteq> graph H' h'"
 141.205 -          proof (rule graph_extI)
 141.206 -            fix t assume t: "t \<in> H"
 141.207 -            from E HE t have "(SOME (y, a). t = y + a \<cdot> x' \<and> y \<in> H) = (t, 0)"
 141.208 -	      using `x' \<notin> H` `x' \<in> E` `x' \<noteq> 0` by (rule decomp_H'_H)
 141.209 -            with h'_def show "h t = h' t" by (simp add: Let_def)
 141.210 -          next
 141.211 -            from HH' show "H \<subseteq> H'" ..
 141.212 -          qed
 141.213 -          with g_rep show ?thesis by (simp only:)
 141.214 -        qed
 141.215 -
 141.216 -        show "g \<noteq> graph H' h'"
 141.217 -        proof -
 141.218 -          have "graph H h \<noteq> graph H' h'"
 141.219 -          proof
 141.220 -            assume eq: "graph H h = graph H' h'"
 141.221 -            have "x' \<in> H'"
 141.222 -	      unfolding H'_def
 141.223 -            proof
 141.224 -              from H show "0 \<in> H" by (rule vectorspace.zero)
 141.225 -              from x'E show "x' \<in> lin x'" by (rule x_lin_x)
 141.226 -              from x'E show "x' = 0 + x'" by simp
 141.227 -            qed
 141.228 -            then have "(x', h' x') \<in> graph H' h'" ..
 141.229 -            with eq have "(x', h' x') \<in> graph H h" by (simp only:)
 141.230 -            then have "x' \<in> H" ..
 141.231 -            with `x' \<notin> H` show False by contradiction
 141.232 -          qed
 141.233 -          with g_rep show ?thesis by simp
 141.234 -        qed
 141.235 -      qed
 141.236 -      moreover have "graph H' h' \<in> M"
 141.237 -        -- {* and @{text h'} is norm-preserving. \skp *}
 141.238 -      proof (unfold M_def)
 141.239 -        show "graph H' h' \<in> norm_pres_extensions E p F f"
 141.240 -        proof (rule norm_pres_extensionI2)
 141.241 -          show "linearform H' h'"
 141.242 -	    using h'_def H'_def HE linearform `x' \<notin> H` `x' \<in> E` `x' \<noteq> 0` E
 141.243 -	    by (rule h'_lf)
 141.244 -          show "H' \<unlhd> E"
 141.245 -	  unfolding H'_def
 141.246 -          proof
 141.247 -            show "H \<unlhd> E" by fact
 141.248 -            show "vectorspace E" by fact
 141.249 -            from x'E show "lin x' \<unlhd> E" ..
 141.250 -          qed
 141.251 -          from H `F \<unlhd> H` HH' show FH': "F \<unlhd> H'"
 141.252 -            by (rule vectorspace.subspace_trans)
 141.253 -          show "graph F f \<subseteq> graph H' h'"
 141.254 -          proof (rule graph_extI)
 141.255 -            fix x assume x: "x \<in> F"
 141.256 -            with graphs have "f x = h x" ..
 141.257 -            also have "\<dots> = h x + 0 * xi" by simp
 141.258 -            also have "\<dots> = (let (y, a) = (x, 0) in h y + a * xi)"
 141.259 -              by (simp add: Let_def)
 141.260 -            also have "(x, 0) =
 141.261 -                (SOME (y, a). x = y + a \<cdot> x' \<and> y \<in> H)"
 141.262 -	      using E HE
 141.263 -            proof (rule decomp_H'_H [symmetric])
 141.264 -              from FH x show "x \<in> H" ..
 141.265 -              from x' show "x' \<noteq> 0" .
 141.266 -	      show "x' \<notin> H" by fact
 141.267 -	      show "x' \<in> E" by fact
 141.268 -            qed
 141.269 -            also have
 141.270 -              "(let (y, a) = (SOME (y, a). x = y + a \<cdot> x' \<and> y \<in> H)
 141.271 -              in h y + a * xi) = h' x" by (simp only: h'_def)
 141.272 -            finally show "f x = h' x" .
 141.273 -          next
 141.274 -            from FH' show "F \<subseteq> H'" ..
 141.275 -          qed
 141.276 -          show "\<forall>x \<in> H'. h' x \<le> p x"
 141.277 -	    using h'_def H'_def `x' \<notin> H` `x' \<in> E` `x' \<noteq> 0` E HE
 141.278 -	      `seminorm E p` linearform and hp xi
 141.279 -	    by (rule h'_norm_pres)
 141.280 -        qed
 141.281 -      qed
 141.282 -      ultimately show ?thesis ..
 141.283 -    qed
 141.284 -    then have "\<not> (\<forall>x \<in> M. g \<subseteq> x \<longrightarrow> g = x)" by simp
 141.285 -      -- {* So the graph @{text g} of @{text h} cannot be maximal. Contradiction! \skp *}
 141.286 -    with gx show "H = E" by contradiction
 141.287 -  qed
 141.288 -
 141.289 -  from HE_eq and linearform have "linearform E h"
 141.290 -    by (simp only:)
 141.291 -  moreover have "\<forall>x \<in> F. h x = f x"
 141.292 -  proof
 141.293 -    fix x assume "x \<in> F"
 141.294 -    with graphs have "f x = h x" ..
 141.295 -    then show "h x = f x" ..
 141.296 -  qed
 141.297 -  moreover from HE_eq and hp have "\<forall>x \<in> E. h x \<le> p x"
 141.298 -    by (simp only:)
 141.299 -  ultimately show ?thesis by blast
 141.300 -qed
 141.301 -
 141.302 -
 141.303 -subsection  {* Alternative formulation *}
 141.304 -
 141.305 -text {*
 141.306 -  The following alternative formulation of the Hahn-Banach
 141.307 -  Theorem\label{abs-HahnBanach} uses the fact that for a real linear
 141.308 -  form @{text f} and a seminorm @{text p} the following inequations
 141.309 -  are equivalent:\footnote{This was shown in lemma @{thm [source]
 141.310 -  abs_ineq_iff} (see page \pageref{abs-ineq-iff}).}
 141.311 -  \begin{center}
 141.312 -  \begin{tabular}{lll}
 141.313 -  @{text "\<forall>x \<in> H. \<bar>h x\<bar> \<le> p x"} & and &
 141.314 -  @{text "\<forall>x \<in> H. h x \<le> p x"} \\
 141.315 -  \end{tabular}
 141.316 -  \end{center}
 141.317 -*}
 141.318 -
 141.319 -theorem abs_HahnBanach:
 141.320 -  assumes E: "vectorspace E" and FE: "subspace F E"
 141.321 -    and lf: "linearform F f" and sn: "seminorm E p"
 141.322 -  assumes fp: "\<forall>x \<in> F. \<bar>f x\<bar> \<le> p x"
 141.323 -  shows "\<exists>g. linearform E g
 141.324 -    \<and> (\<forall>x \<in> F. g x = f x)
 141.325 -    \<and> (\<forall>x \<in> E. \<bar>g x\<bar> \<le> p x)"
 141.326 -proof -
 141.327 -  interpret vectorspace E by fact
 141.328 -  interpret subspace F E by fact
 141.329 -  interpret linearform F f by fact
 141.330 -  interpret seminorm E p by fact
 141.331 -  have "\<exists>g. linearform E g \<and> (\<forall>x \<in> F. g x = f x) \<and> (\<forall>x \<in> E. g x \<le> p x)"
 141.332 -    using E FE sn lf
 141.333 -  proof (rule HahnBanach)
 141.334 -    show "\<forall>x \<in> F. f x \<le> p x"
 141.335 -      using FE E sn lf and fp by (rule abs_ineq_iff [THEN iffD1])
 141.336 -  qed
 141.337 -  then obtain g where lg: "linearform E g" and *: "\<forall>x \<in> F. g x = f x"
 141.338 -      and **: "\<forall>x \<in> E. g x \<le> p x" by blast
 141.339 -  have "\<forall>x \<in> E. \<bar>g x\<bar> \<le> p x"
 141.340 -    using _ E sn lg **
 141.341 -  proof (rule abs_ineq_iff [THEN iffD2])
 141.342 -    show "E \<unlhd> E" ..
 141.343 -  qed
 141.344 -  with lg * show ?thesis by blast
 141.345 -qed
 141.346 -
 141.347 -
 141.348 -subsection {* The Hahn-Banach Theorem for normed spaces *}
 141.349 -
 141.350 -text {*
 141.351 -  Every continuous linear form @{text f} on a subspace @{text F} of a
 141.352 -  norm space @{text E}, can be extended to a continuous linear form
 141.353 -  @{text g} on @{text E} such that @{text "\<parallel>f\<parallel> = \<parallel>g\<parallel>"}.
 141.354 -*}
 141.355 -
 141.356 -theorem norm_HahnBanach:
 141.357 -  fixes V and norm ("\<parallel>_\<parallel>")
 141.358 -  fixes B defines "\<And>V f. B V f \<equiv> {0} \<union> {\<bar>f x\<bar> / \<parallel>x\<parallel> | x. x \<noteq> 0 \<and> x \<in> V}"
 141.359 -  fixes fn_norm ("\<parallel>_\<parallel>\<hyphen>_" [0, 1000] 999)
 141.360 -  defines "\<And>V f. \<parallel>f\<parallel>\<hyphen>V \<equiv> \<Squnion>(B V f)"
 141.361 -  assumes E_norm: "normed_vectorspace E norm" and FE: "subspace F E"
 141.362 -    and linearform: "linearform F f" and "continuous F norm f"
 141.363 -  shows "\<exists>g. linearform E g
 141.364 -     \<and> continuous E norm g
 141.365 -     \<and> (\<forall>x \<in> F. g x = f x)
 141.366 -     \<and> \<parallel>g\<parallel>\<hyphen>E = \<parallel>f\<parallel>\<hyphen>F"
 141.367 -proof -
 141.368 -  interpret normed_vectorspace E norm by fact
 141.369 -  interpret normed_vectorspace_with_fn_norm E norm B fn_norm
 141.370 -    by (auto simp: B_def fn_norm_def) intro_locales
 141.371 -  interpret subspace F E by fact
 141.372 -  interpret linearform F f by fact
 141.373 -  interpret continuous F norm f by fact
 141.374 -  have E: "vectorspace E" by intro_locales
 141.375 -  have F: "vectorspace F" by rule intro_locales
 141.376 -  have F_norm: "normed_vectorspace F norm"
 141.377 -    using FE E_norm by (rule subspace_normed_vs)
 141.378 -  have ge_zero: "0 \<le> \<parallel>f\<parallel>\<hyphen>F"
 141.379 -    by (rule normed_vectorspace_with_fn_norm.fn_norm_ge_zero
 141.380 -      [OF normed_vectorspace_with_fn_norm.intro,
 141.381 -       OF F_norm `continuous F norm f` , folded B_def fn_norm_def])
 141.382 -  txt {* We define a function @{text p} on @{text E} as follows:
 141.383 -    @{text "p x = \<parallel>f\<parallel> \<cdot> \<parallel>x\<parallel>"} *}
 141.384 -  def p \<equiv> "\<lambda>x. \<parallel>f\<parallel>\<hyphen>F * \<parallel>x\<parallel>"
 141.385 -
 141.386 -  txt {* @{text p} is a seminorm on @{text E}: *}
 141.387 -  have q: "seminorm E p"
 141.388 -  proof
 141.389 -    fix x y a assume x: "x \<in> E" and y: "y \<in> E"
 141.390 -    
 141.391 -    txt {* @{text p} is positive definite: *}
 141.392 -    have "0 \<le> \<parallel>f\<parallel>\<hyphen>F" by (rule ge_zero)
 141.393 -    moreover from x have "0 \<le> \<parallel>x\<parallel>" ..
 141.394 -    ultimately show "0 \<le> p x"  
 141.395 -      by (simp add: p_def zero_le_mult_iff)
 141.396 -
 141.397 -    txt {* @{text p} is absolutely homogenous: *}
 141.398 -
 141.399 -    show "p (a \<cdot> x) = \<bar>a\<bar> * p x"
 141.400 -    proof -
 141.401 -      have "p (a \<cdot> x) = \<parallel>f\<parallel>\<hyphen>F * \<parallel>a \<cdot> x\<parallel>" by (simp only: p_def)
 141.402 -      also from x have "\<parallel>a \<cdot> x\<parallel> = \<bar>a\<bar> * \<parallel>x\<parallel>" by (rule abs_homogenous)
 141.403 -      also have "\<parallel>f\<parallel>\<hyphen>F * (\<bar>a\<bar> * \<parallel>x\<parallel>) = \<bar>a\<bar> * (\<parallel>f\<parallel>\<hyphen>F * \<parallel>x\<parallel>)" by simp
 141.404 -      also have "\<dots> = \<bar>a\<bar> * p x" by (simp only: p_def)
 141.405 -      finally show ?thesis .
 141.406 -    qed
 141.407 -
 141.408 -    txt {* Furthermore, @{text p} is subadditive: *}
 141.409 -
 141.410 -    show "p (x + y) \<le> p x + p y"
 141.411 -    proof -
 141.412 -      have "p (x + y) = \<parallel>f\<parallel>\<hyphen>F * \<parallel>x + y\<parallel>" by (simp only: p_def)
 141.413 -      also have a: "0 \<le> \<parallel>f\<parallel>\<hyphen>F" by (rule ge_zero)
 141.414 -      from x y have "\<parallel>x + y\<parallel> \<le> \<parallel>x\<parallel> + \<parallel>y\<parallel>" ..
 141.415 -      with a have " \<parallel>f\<parallel>\<hyphen>F * \<parallel>x + y\<parallel> \<le> \<parallel>f\<parallel>\<hyphen>F * (\<parallel>x\<parallel> + \<parallel>y\<parallel>)"
 141.416 -        by (simp add: mult_left_mono)
 141.417 -      also have "\<dots> = \<parallel>f\<parallel>\<hyphen>F * \<parallel>x\<parallel> + \<parallel>f\<parallel>\<hyphen>F * \<parallel>y\<parallel>" by (simp only: right_distrib)
 141.418 -      also have "\<dots> = p x + p y" by (simp only: p_def)
 141.419 -      finally show ?thesis .
 141.420 -    qed
 141.421 -  qed
 141.422 -
 141.423 -  txt {* @{text f} is bounded by @{text p}. *}
 141.424 -
 141.425 -  have "\<forall>x \<in> F. \<bar>f x\<bar> \<le> p x"
 141.426 -  proof
 141.427 -    fix x assume "x \<in> F"
 141.428 -    with `continuous F norm f` and linearform
 141.429 -    show "\<bar>f x\<bar> \<le> p x"
 141.430 -      unfolding p_def by (rule normed_vectorspace_with_fn_norm.fn_norm_le_cong
 141.431 -        [OF normed_vectorspace_with_fn_norm.intro,
 141.432 -         OF F_norm, folded B_def fn_norm_def])
 141.433 -  qed
 141.434 -
 141.435 -  txt {* Using the fact that @{text p} is a seminorm and @{text f} is bounded
 141.436 -    by @{text p} we can apply the Hahn-Banach Theorem for real vector
 141.437 -    spaces. So @{text f} can be extended in a norm-preserving way to
 141.438 -    some function @{text g} on the whole vector space @{text E}. *}
 141.439 -
 141.440 -  with E FE linearform q obtain g where
 141.441 -      linearformE: "linearform E g"
 141.442 -    and a: "\<forall>x \<in> F. g x = f x"
 141.443 -    and b: "\<forall>x \<in> E. \<bar>g x\<bar> \<le> p x"
 141.444 -    by (rule abs_HahnBanach [elim_format]) iprover
 141.445 -
 141.446 -  txt {* We furthermore have to show that @{text g} is also continuous: *}
 141.447 -
 141.448 -  have g_cont: "continuous E norm g" using linearformE
 141.449 -  proof
 141.450 -    fix x assume "x \<in> E"
 141.451 -    with b show "\<bar>g x\<bar> \<le> \<parallel>f\<parallel>\<hyphen>F * \<parallel>x\<parallel>"
 141.452 -      by (simp only: p_def)
 141.453 -  qed
 141.454 -
 141.455 -  txt {* To complete the proof, we show that @{text "\<parallel>g\<parallel> = \<parallel>f\<parallel>"}. *}
 141.456 -
 141.457 -  have "\<parallel>g\<parallel>\<hyphen>E = \<parallel>f\<parallel>\<hyphen>F"
 141.458 -  proof (rule order_antisym)
 141.459 -    txt {*
 141.460 -      First we show @{text "\<parallel>g\<parallel> \<le> \<parallel>f\<parallel>"}.  The function norm @{text
 141.461 -      "\<parallel>g\<parallel>"} is defined as the smallest @{text "c \<in> \<real>"} such that
 141.462 -      \begin{center}
 141.463 -      \begin{tabular}{l}
 141.464 -      @{text "\<forall>x \<in> E. \<bar>g x\<bar> \<le> c \<cdot> \<parallel>x\<parallel>"}
 141.465 -      \end{tabular}
 141.466 -      \end{center}
 141.467 -      \noindent Furthermore holds
 141.468 -      \begin{center}
 141.469 -      \begin{tabular}{l}
 141.470 -      @{text "\<forall>x \<in> E. \<bar>g x\<bar> \<le> \<parallel>f\<parallel> \<cdot> \<parallel>x\<parallel>"}
 141.471 -      \end{tabular}
 141.472 -      \end{center}
 141.473 -    *}
 141.474 -
 141.475 -    have "\<forall>x \<in> E. \<bar>g x\<bar> \<le> \<parallel>f\<parallel>\<hyphen>F * \<parallel>x\<parallel>"
 141.476 -    proof
 141.477 -      fix x assume "x \<in> E"
 141.478 -      with b show "\<bar>g x\<bar> \<le> \<parallel>f\<parallel>\<hyphen>F * \<parallel>x\<parallel>"
 141.479 -        by (simp only: p_def)
 141.480 -    qed
 141.481 -    from g_cont this ge_zero
 141.482 -    show "\<parallel>g\<parallel>\<hyphen>E \<le> \<parallel>f\<parallel>\<hyphen>F"
 141.483 -      by (rule fn_norm_least [of g, folded B_def fn_norm_def])
 141.484 -
 141.485 -    txt {* The other direction is achieved by a similar argument. *}
 141.486 -
 141.487 -    show "\<parallel>f\<parallel>\<hyphen>F \<le> \<parallel>g\<parallel>\<hyphen>E"
 141.488 -    proof (rule normed_vectorspace_with_fn_norm.fn_norm_least
 141.489 -	[OF normed_vectorspace_with_fn_norm.intro,
 141.490 -	 OF F_norm, folded B_def fn_norm_def])
 141.491 -      show "\<forall>x \<in> F. \<bar>f x\<bar> \<le> \<parallel>g\<parallel>\<hyphen>E * \<parallel>x\<parallel>"
 141.492 -      proof
 141.493 -	fix x assume x: "x \<in> F"
 141.494 -	from a x have "g x = f x" ..
 141.495 -	then have "\<bar>f x\<bar> = \<bar>g x\<bar>" by (simp only:)
 141.496 -	also from g_cont
 141.497 -	have "\<dots> \<le> \<parallel>g\<parallel>\<hyphen>E * \<parallel>x\<parallel>"
 141.498 -	proof (rule fn_norm_le_cong [of g, folded B_def fn_norm_def])
 141.499 -	  from FE x show "x \<in> E" ..
 141.500 -	qed
 141.501 -	finally show "\<bar>f x\<bar> \<le> \<parallel>g\<parallel>\<hyphen>E * \<parallel>x\<parallel>" .
 141.502 -      qed
 141.503 -      show "0 \<le> \<parallel>g\<parallel>\<hyphen>E"
 141.504 -	using g_cont
 141.505 -	by (rule fn_norm_ge_zero [of g, folded B_def fn_norm_def])
 141.506 -      show "continuous F norm f" by fact
 141.507 -    qed
 141.508 -  qed
 141.509 -  with linearformE a g_cont show ?thesis by blast
 141.510 -qed
 141.511 -
 141.512 -end
   142.1 --- a/src/HOL/Real/HahnBanach/HahnBanachExtLemmas.thy	Tue Dec 30 08:18:54 2008 +0100
   142.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   142.3 @@ -1,280 +0,0 @@
   142.4 -(*  Title:      HOL/Real/HahnBanach/HahnBanachExtLemmas.thy
   142.5 -    Author:     Gertrud Bauer, TU Munich
   142.6 -*)
   142.7 -
   142.8 -header {* Extending non-maximal functions *}
   142.9 -
  142.10 -theory HahnBanachExtLemmas
  142.11 -imports FunctionNorm
  142.12 -begin
  142.13 -
  142.14 -text {*
  142.15 -  In this section the following context is presumed.  Let @{text E} be
  142.16 -  a real vector space with a seminorm @{text q} on @{text E}. @{text
  142.17 -  F} is a subspace of @{text E} and @{text f} a linear function on
  142.18 -  @{text F}. We consider a subspace @{text H} of @{text E} that is a
  142.19 -  superspace of @{text F} and a linear form @{text h} on @{text
  142.20 -  H}. @{text H} is a not equal to @{text E} and @{text "x\<^sub>0"} is
  142.21 -  an element in @{text "E - H"}.  @{text H} is extended to the direct
  142.22 -  sum @{text "H' = H + lin x\<^sub>0"}, so for any @{text "x \<in> H'"}
  142.23 -  the decomposition of @{text "x = y + a \<cdot> x"} with @{text "y \<in> H"} is
  142.24 -  unique. @{text h'} is defined on @{text H'} by @{text "h' x = h y +
  142.25 -  a \<cdot> \<xi>"} for a certain @{text \<xi>}.
  142.26 -
  142.27 -  Subsequently we show some properties of this extension @{text h'} of
  142.28 -  @{text h}.
  142.29 -
  142.30 -  \medskip This lemma will be used to show the existence of a linear
  142.31 -  extension of @{text f} (see page \pageref{ex-xi-use}). It is a
  142.32 -  consequence of the completeness of @{text \<real>}. To show
  142.33 -  \begin{center}
  142.34 -  \begin{tabular}{l}
  142.35 -  @{text "\<exists>\<xi>. \<forall>y \<in> F. a y \<le> \<xi> \<and> \<xi> \<le> b y"}
  142.36 -  \end{tabular}
  142.37 -  \end{center}
  142.38 -  \noindent it suffices to show that
  142.39 -  \begin{center}
  142.40 -  \begin{tabular}{l}
  142.41 -  @{text "\<forall>u \<in> F. \<forall>v \<in> F. a u \<le> b v"}
  142.42 -  \end{tabular}
  142.43 -  \end{center}
  142.44 -*}
  142.45 -
  142.46 -lemma ex_xi:
  142.47 -  assumes "vectorspace F"
  142.48 -  assumes r: "\<And>u v. u \<in> F \<Longrightarrow> v \<in> F \<Longrightarrow> a u \<le> b v"
  142.49 -  shows "\<exists>xi::real. \<forall>y \<in> F. a y \<le> xi \<and> xi \<le> b y"
  142.50 -proof -
  142.51 -  interpret vectorspace F by fact
  142.52 -  txt {* From the completeness of the reals follows:
  142.53 -    The set @{text "S = {a u. u \<in> F}"} has a supremum, if it is
  142.54 -    non-empty and has an upper bound. *}
  142.55 -
  142.56 -  let ?S = "{a u | u. u \<in> F}"
  142.57 -  have "\<exists>xi. lub ?S xi"
  142.58 -  proof (rule real_complete)
  142.59 -    have "a 0 \<in> ?S" by blast
  142.60 -    then show "\<exists>X. X \<in> ?S" ..
  142.61 -    have "\<forall>y \<in> ?S. y \<le> b 0"
  142.62 -    proof
  142.63 -      fix y assume y: "y \<in> ?S"
  142.64 -      then obtain u where u: "u \<in> F" and y: "y = a u" by blast
  142.65 -      from u and zero have "a u \<le> b 0" by (rule r)
  142.66 -      with y show "y \<le> b 0" by (simp only:)
  142.67 -    qed
  142.68 -    then show "\<exists>u. \<forall>y \<in> ?S. y \<le> u" ..
  142.69 -  qed
  142.70 -  then obtain xi where xi: "lub ?S xi" ..
  142.71 -  {
  142.72 -    fix y assume "y \<in> F"
  142.73 -    then have "a y \<in> ?S" by blast
  142.74 -    with xi have "a y \<le> xi" by (rule lub.upper)
  142.75 -  } moreover {
  142.76 -    fix y assume y: "y \<in> F"
  142.77 -    from xi have "xi \<le> b y"
  142.78 -    proof (rule lub.least)
  142.79 -      fix au assume "au \<in> ?S"
  142.80 -      then obtain u where u: "u \<in> F" and au: "au = a u" by blast
  142.81 -      from u y have "a u \<le> b y" by (rule r)
  142.82 -      with au show "au \<le> b y" by (simp only:)
  142.83 -    qed
  142.84 -  } ultimately show "\<exists>xi. \<forall>y \<in> F. a y \<le> xi \<and> xi \<le> b y" by blast
  142.85 -qed
  142.86 -
  142.87 -text {*
  142.88 -  \medskip The function @{text h'} is defined as a @{text "h' x = h y
  142.89 -  + a \<cdot> \<xi>"} where @{text "x = y + a \<cdot> \<xi>"} is a linear extension of
  142.90 -  @{text h} to @{text H'}.
  142.91 -*}
  142.92 -
  142.93 -lemma h'_lf:
  142.94 -  assumes h'_def: "h' \<equiv> \<lambda>x. let (y, a) =
  142.95 -      SOME (y, a). x = y + a \<cdot> x0 \<and> y \<in> H in h y + a * xi"
  142.96 -    and H'_def: "H' \<equiv> H + lin x0"
  142.97 -    and HE: "H \<unlhd> E"
  142.98 -  assumes "linearform H h"
  142.99 -  assumes x0: "x0 \<notin> H"  "x0 \<in> E"  "x0 \<noteq> 0"
 142.100 -  assumes E: "vectorspace E"
 142.101 -  shows "linearform H' h'"
 142.102 -proof -
 142.103 -  interpret linearform H h by fact
 142.104 -  interpret vectorspace E by fact
 142.105 -  show ?thesis
 142.106 -  proof
 142.107 -    note E = `vectorspace E`
 142.108 -    have H': "vectorspace H'"
 142.109 -    proof (unfold H'_def)
 142.110 -      from `x0 \<in> E`
 142.111 -      have "lin x0 \<unlhd> E" ..
 142.112 -      with HE show "vectorspace (H + lin x0)" using E ..
 142.113 -    qed
 142.114 -    {
 142.115 -      fix x1 x2 assume x1: "x1 \<in> H'" and x2: "x2 \<in> H'"
 142.116 -      show "h' (x1 + x2) = h' x1 + h' x2"
 142.117 -      proof -
 142.118 -	from H' x1 x2 have "x1 + x2 \<in> H'"
 142.119 -          by (rule vectorspace.add_closed)
 142.120 -	with x1 x2 obtain y y1 y2 a a1 a2 where
 142.121 -          x1x2: "x1 + x2 = y + a \<cdot> x0" and y: "y \<in> H"
 142.122 -          and x1_rep: "x1 = y1 + a1 \<cdot> x0" and y1: "y1 \<in> H"
 142.123 -          and x2_rep: "x2 = y2 + a2 \<cdot> x0" and y2: "y2 \<in> H"
 142.124 -          unfolding H'_def sum_def lin_def by blast
 142.125 -	
 142.126 -	have ya: "y1 + y2 = y \<and> a1 + a2 = a" using E HE _ y x0
 142.127 -	proof (rule decomp_H') txt_raw {* \label{decomp-H-use} *}
 142.128 -          from HE y1 y2 show "y1 + y2 \<in> H"
 142.129 -            by (rule subspace.add_closed)
 142.130 -          from x0 and HE y y1 y2
 142.131 -          have "x0 \<in> E"  "y \<in> E"  "y1 \<in> E"  "y2 \<in> E" by auto
 142.132 -          with x1_rep x2_rep have "(y1 + y2) + (a1 + a2) \<cdot> x0 = x1 + x2"
 142.133 -            by (simp add: add_ac add_mult_distrib2)
 142.134 -          also note x1x2
 142.135 -          finally show "(y1 + y2) + (a1 + a2) \<cdot> x0 = y + a \<cdot> x0" .
 142.136 -	qed
 142.137 -	
 142.138 -	from h'_def x1x2 E HE y x0
 142.139 -	have "h' (x1 + x2) = h y + a * xi"
 142.140 -          by (rule h'_definite)
 142.141 -	also have "\<dots> = h (y1 + y2) + (a1 + a2) * xi"
 142.142 -          by (simp only: ya)
 142.143 -	also from y1 y2 have "h (y1 + y2) = h y1 + h y2"
 142.144 -          by simp
 142.145 -	also have "\<dots> + (a1 + a2) * xi = (h y1 + a1 * xi) + (h y2 + a2 * xi)"
 142.146 -          by (simp add: left_distrib)
 142.147 -	also from h'_def x1_rep E HE y1 x0
 142.148 -	have "h y1 + a1 * xi = h' x1"
 142.149 -          by (rule h'_definite [symmetric])
 142.150 -	also from h'_def x2_rep E HE y2 x0
 142.151 -	have "h y2 + a2 * xi = h' x2"
 142.152 -          by (rule h'_definite [symmetric])
 142.153 -	finally show ?thesis .
 142.154 -      qed
 142.155 -    next
 142.156 -      fix x1 c assume x1: "x1 \<in> H'"
 142.157 -      show "h' (c \<cdot> x1) = c * (h' x1)"
 142.158 -      proof -
 142.159 -	from H' x1 have ax1: "c \<cdot> x1 \<in> H'"
 142.160 -          by (rule vectorspace.mult_closed)
 142.161 -	with x1 obtain y a y1 a1 where
 142.162 -            cx1_rep: "c \<cdot> x1 = y + a \<cdot> x0" and y: "y \<in> H"
 142.163 -          and x1_rep: "x1 = y1 + a1 \<cdot> x0" and y1: "y1 \<in> H"
 142.164 -          unfolding H'_def sum_def lin_def by blast
 142.165 -	
 142.166 -	have ya: "c \<cdot> y1 = y \<and> c * a1 = a" using E HE _ y x0
 142.167 -	proof (rule decomp_H')
 142.168 -          from HE y1 show "c \<cdot> y1 \<in> H"
 142.169 -            by (rule subspace.mult_closed)
 142.170 -          from x0 and HE y y1
 142.171 -          have "x0 \<in> E"  "y \<in> E"  "y1 \<in> E" by auto
 142.172 -          with x1_rep have "c \<cdot> y1 + (c * a1) \<cdot> x0 = c \<cdot> x1"
 142.173 -            by (simp add: mult_assoc add_mult_distrib1)
 142.174 -          also note cx1_rep
 142.175 -          finally show "c \<cdot> y1 + (c * a1) \<cdot> x0 = y + a \<cdot> x0" .
 142.176 -	qed
 142.177 -	
 142.178 -	from h'_def cx1_rep E HE y x0 have "h' (c \<cdot> x1) = h y + a * xi"
 142.179 -          by (rule h'_definite)
 142.180 -	also have "\<dots> = h (c \<cdot> y1) + (c * a1) * xi"
 142.181 -          by (simp only: ya)
 142.182 -	also from y1 have "h (c \<cdot> y1) = c * h y1"
 142.183 -          by simp
 142.184 -	also have "\<dots> + (c * a1) * xi = c * (h y1 + a1 * xi)"
 142.185 -          by (simp only: right_distrib)
 142.186 -	also from h'_def x1_rep E HE y1 x0 have "h y1 + a1 * xi = h' x1"
 142.187 -          by (rule h'_definite [symmetric])
 142.188 -	finally show ?thesis .
 142.189 -      qed
 142.190 -    }
 142.191 -  qed
 142.192 -qed
 142.193 -
 142.194 -text {* \medskip The linear extension @{text h'} of @{text h}
 142.195 -  is bounded by the seminorm @{text p}. *}
 142.196 -
 142.197 -lemma h'_norm_pres:
 142.198 -  assumes h'_def: "h' \<equiv> \<lambda>x. let (y, a) =
 142.199 -      SOME (y, a). x = y + a \<cdot> x0 \<and> y \<in> H in h y + a * xi"
 142.200 -    and H'_def: "H' \<equiv> H + lin x0"
 142.201 -    and x0: "x0 \<notin> H"  "x0 \<in> E"  "x0 \<noteq> 0"
 142.202 -  assumes E: "vectorspace E" and HE: "subspace H E"
 142.203 -    and "seminorm E p" and "linearform H h"
 142.204 -  assumes a: "\<forall>y \<in> H. h y \<le> p y"
 142.205 -    and a': "\<forall>y \<in> H. - p (y + x0) - h y \<le> xi \<and> xi \<le> p (y + x0) - h y"
 142.206 -  shows "\<forall>x \<in> H'. h' x \<le> p x"
 142.207 -proof -
 142.208 -  interpret vectorspace E by fact
 142.209 -  interpret subspace H E by fact
 142.210 -  interpret seminorm E p by fact
 142.211 -  interpret linearform H h by fact
 142.212 -  show ?thesis
 142.213 -  proof
 142.214 -    fix x assume x': "x \<in> H'"
 142.215 -    show "h' x \<le> p x"
 142.216 -    proof -
 142.217 -      from a' have a1: "\<forall>ya \<in> H. - p (ya + x0) - h ya \<le> xi"
 142.218 -	and a2: "\<forall>ya \<in> H. xi \<le> p (ya + x0) - h ya" by auto
 142.219 -      from x' obtain y a where
 142.220 -          x_rep: "x = y + a \<cdot> x0" and y: "y \<in> H"
 142.221 -	unfolding H'_def sum_def lin_def by blast
 142.222 -      from y have y': "y \<in> E" ..
 142.223 -      from y have ay: "inverse a \<cdot> y \<in> H" by simp
 142.224 -      
 142.225 -      from h'_def x_rep E HE y x0 have "h' x = h y + a * xi"
 142.226 -	by (rule h'_definite)
 142.227 -      also have "\<dots> \<le> p (y + a \<cdot> x0)"
 142.228 -      proof (rule linorder_cases)
 142.229 -	assume z: "a = 0"
 142.230 -	then have "h y + a * xi = h y" by simp
 142.231 -	also from a y have "\<dots> \<le> p y" ..
 142.232 -	also from x0 y' z have "p y = p (y + a \<cdot> x0)" by simp
 142.233 -	finally show ?thesis .
 142.234 -      next
 142.235 -	txt {* In the case @{text "a < 0"}, we use @{text "a\<^sub>1"}
 142.236 -          with @{text ya} taken as @{text "y / a"}: *}
 142.237 -	assume lz: "a < 0" then have nz: "a \<noteq> 0" by simp
 142.238 -	from a1 ay
 142.239 -	have "- p (inverse a \<cdot> y + x0) - h (inverse a \<cdot> y) \<le> xi" ..
 142.240 -	with lz have "a * xi \<le>
 142.241 -          a * (- p (inverse a \<cdot> y + x0) - h (inverse a \<cdot> y))"
 142.242 -          by (simp add: mult_left_mono_neg order_less_imp_le)
 142.243 -	
 142.244 -	also have "\<dots> =
 142.245 -          - a * (p (inverse a \<cdot> y + x0)) - a * (h (inverse a \<cdot> y))"
 142.246 -	  by (simp add: right_diff_distrib)
 142.247 -	also from lz x0 y' have "- a * (p (inverse a \<cdot> y + x0)) =
 142.248 -          p (a \<cdot> (inverse a \<cdot> y + x0))"
 142.249 -          by (simp add: abs_homogenous)
 142.250 -	also from nz x0 y' have "\<dots> = p (y + a \<cdot> x0)"
 142.251 -          by (simp add: add_mult_distrib1 mult_assoc [symmetric])
 142.252 -	also from nz y have "a * (h (inverse a \<cdot> y)) =  h y"
 142.253 -          by simp
 142.254 -	finally have "a * xi \<le> p (y + a \<cdot> x0) - h y" .
 142.255 -	then show ?thesis by simp
 142.256 -      next
 142.257 -	txt {* In the case @{text "a > 0"}, we use @{text "a\<^sub>2"}
 142.258 -          with @{text ya} taken as @{text "y / a"}: *}
 142.259 -	assume gz: "0 < a" then have nz: "a \<noteq> 0" by simp
 142.260 -	from a2 ay
 142.261 -	have "xi \<le> p (inverse a \<cdot> y + x0) - h (inverse a \<cdot> y)" ..
 142.262 -	with gz have "a * xi \<le>
 142.263 -          a * (p (inverse a \<cdot> y + x0) - h (inverse a \<cdot> y))"
 142.264 -          by simp
 142.265 -	also have "\<dots> = a * p (inverse a \<cdot> y + x0) - a * h (inverse a \<cdot> y)"
 142.266 -	  by (simp add: right_diff_distrib)
 142.267 -	also from gz x0 y'
 142.268 -	have "a * p (inverse a \<cdot> y + x0) = p (a \<cdot> (inverse a \<cdot> y + x0))"
 142.269 -          by (simp add: abs_homogenous)
 142.270 -	also from nz x0 y' have "\<dots> = p (y + a \<cdot> x0)"
 142.271 -          by (simp add: add_mult_distrib1 mult_assoc [symmetric])
 142.272 -	also from nz y have "a * h (inverse a \<cdot> y) = h y"
 142.273 -          by simp
 142.274 -	finally have "a * xi \<le> p (y + a \<cdot> x0) - h y" .
 142.275 -	then show ?thesis by simp
 142.276 -      qed
 142.277 -      also from x_rep have "\<dots> = p x" by (simp only:)
 142.278 -      finally show ?thesis .
 142.279 -    qed
 142.280 -  qed
 142.281 -qed
 142.282 -
 142.283 -end
   143.1 --- a/src/HOL/Real/HahnBanach/HahnBanachLemmas.thy	Tue Dec 30 08:18:54 2008 +0100
   143.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   143.3 @@ -1,4 +0,0 @@
   143.4 -(*<*)
   143.5 -theory HahnBanachLemmas imports HahnBanachSupLemmas HahnBanachExtLemmas begin
   143.6 -end
   143.7 -(*>*)
   143.8 \ No newline at end of file
   144.1 --- a/src/HOL/Real/HahnBanach/HahnBanachSupLemmas.thy	Tue Dec 30 08:18:54 2008 +0100
   144.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   144.3 @@ -1,446 +0,0 @@
   144.4 -(*  Title:      HOL/Real/HahnBanach/HahnBanachSupLemmas.thy
   144.5 -    ID:         $Id$
   144.6 -    Author:     Gertrud Bauer, TU Munich
   144.7 -*)
   144.8 -
   144.9 -header {* The supremum w.r.t.~the function order *}
  144.10 -
  144.11 -theory HahnBanachSupLemmas
  144.12 -imports FunctionNorm ZornLemma
  144.13 -begin
  144.14 -
  144.15 -text {*
  144.16 -  This section contains some lemmas that will be used in the proof of
  144.17 -  the Hahn-Banach Theorem.  In this section the following context is
  144.18 -  presumed.  Let @{text E} be a real vector space with a seminorm
  144.19 -  @{text p} on @{text E}.  @{text F} is a subspace of @{text E} and
  144.20 -  @{text f} a linear form on @{text F}. We consider a chain @{text c}
  144.21 -  of norm-preserving extensions of @{text f}, such that @{text "\<Union>c =
  144.22 -  graph H h"}.  We will show some properties about the limit function
  144.23 -  @{text h}, i.e.\ the supremum of the chain @{text c}.
  144.24 -
  144.25 -  \medskip Let @{text c} be a chain of norm-preserving extensions of
  144.26 -  the function @{text f} and let @{text "graph H h"} be the supremum
  144.27 -  of @{text c}.  Every element in @{text H} is member of one of the
  144.28 -  elements of the chain.
  144.29 -*}
  144.30 -lemmas [dest?] = chainD
  144.31 -lemmas chainE2 [elim?] = chainD2 [elim_format, standard]
  144.32 -
  144.33 -lemma some_H'h't:
  144.34 -  assumes M: "M = norm_pres_extensions E p F f"
  144.35 -    and cM: "c \<in> chain M"
  144.36 -    and u: "graph H h = \<Union>c"
  144.37 -    and x: "x \<in> H"
  144.38 -  shows "\<exists>H' h'. graph H' h' \<in> c
  144.39 -    \<and> (x, h x) \<in> graph H' h'
  144.40 -    \<and> linearform H' h' \<and> H' \<unlhd> E
  144.41 -    \<and> F \<unlhd> H' \<and> graph F f \<subseteq> graph H' h'
  144.42 -    \<and> (\<forall>x \<in> H'. h' x \<le> p x)"
  144.43 -proof -
  144.44 -  from x have "(x, h x) \<in> graph H h" ..
  144.45 -  also from u have "\<dots> = \<Union>c" .
  144.46 -  finally obtain g where gc: "g \<in> c" and gh: "(x, h x) \<in> g" by blast
  144.47 -
  144.48 -  from cM have "c \<subseteq> M" ..
  144.49 -  with gc have "g \<in> M" ..
  144.50 -  also from M have "\<dots> = norm_pres_extensions E p F f" .
  144.51 -  finally obtain H' and h' where g: "g = graph H' h'"
  144.52 -    and * : "linearform H' h'"  "H' \<unlhd> E"  "F \<unlhd> H'"
  144.53 -      "graph F f \<subseteq> graph H' h'"  "\<forall>x \<in> H'. h' x \<le> p x" ..
  144.54 -
  144.55 -  from gc and g have "graph H' h' \<in> c" by (simp only:)
  144.56 -  moreover from gh and g have "(x, h x) \<in> graph H' h'" by (simp only:)
  144.57 -  ultimately show ?thesis using * by blast
  144.58 -qed
  144.59 -
  144.60 -text {*
  144.61 -  \medskip Let @{text c} be a chain of norm-preserving extensions of
  144.62 -  the function @{text f} and let @{text "graph H h"} be the supremum
  144.63 -  of @{text c}.  Every element in the domain @{text H} of the supremum
  144.64 -  function is member of the domain @{text H'} of some function @{text
  144.65 -  h'}, such that @{text h} extends @{text h'}.
  144.66 -*}
  144.67 -
  144.68 -lemma some_H'h':
  144.69 -  assumes M: "M = norm_pres_extensions E p F f"
  144.70 -    and cM: "c \<in> chain M"
  144.71 -    and u: "graph H h = \<Union>c"
  144.72 -    and x: "x \<in> H"
  144.73 -  shows "\<exists>H' h'. x \<in> H' \<and> graph H' h' \<subseteq> graph H h
  144.74 -    \<and> linearform H' h' \<and> H' \<unlhd> E \<and> F \<unlhd> H'
  144.75 -    \<and> graph F f \<subseteq> graph H' h' \<and> (\<forall>x \<in> H'. h' x \<le> p x)"
  144.76 -proof -
  144.77 -  from M cM u x obtain H' h' where
  144.78 -      x_hx: "(x, h x) \<in> graph H' h'"
  144.79 -    and c: "graph H' h' \<in> c"
  144.80 -    and * : "linearform H' h'"  "H' \<unlhd> E"  "F \<unlhd> H'"
  144.81 -      "graph F f \<subseteq> graph H' h'"  "\<forall>x \<in> H'. h' x \<le> p x"
  144.82 -    by (rule some_H'h't [elim_format]) blast
  144.83 -  from x_hx have "x \<in> H'" ..
  144.84 -  moreover from cM u c have "graph H' h' \<subseteq> graph H h"
  144.85 -    by (simp only: chain_ball_Union_upper)
  144.86 -  ultimately show ?thesis using * by blast
  144.87 -qed
  144.88 -
  144.89 -text {*
  144.90 -  \medskip Any two elements @{text x} and @{text y} in the domain
  144.91 -  @{text H} of the supremum function @{text h} are both in the domain
  144.92 -  @{text H'} of some function @{text h'}, such that @{text h} extends
  144.93 -  @{text h'}.
  144.94 -*}
  144.95 -
  144.96 -lemma some_H'h'2:
  144.97 -  assumes M: "M = norm_pres_extensions E p F f"
  144.98 -    and cM: "c \<in> chain M"
  144.99 -    and u: "graph H h = \<Union>c"
 144.100 -    and x: "x \<in> H"
 144.101 -    and y: "y \<in> H"
 144.102 -  shows "\<exists>H' h'. x \<in> H' \<and> y \<in> H'
 144.103 -    \<and> graph H' h' \<subseteq> graph H h
 144.104 -    \<and> linearform H' h' \<and> H' \<unlhd> E \<and> F \<unlhd> H'
 144.105 -    \<and> graph F f \<subseteq> graph H' h' \<and> (\<forall>x \<in> H'. h' x \<le> p x)"
 144.106 -proof -
 144.107 -  txt {* @{text y} is in the domain @{text H''} of some function @{text h''},
 144.108 -  such that @{text h} extends @{text h''}. *}
 144.109 -
 144.110 -  from M cM u and y obtain H' h' where
 144.111 -      y_hy: "(y, h y) \<in> graph H' h'"
 144.112 -    and c': "graph H' h' \<in> c"
 144.113 -    and * :
 144.114 -      "linearform H' h'"  "H' \<unlhd> E"  "F \<unlhd> H'"
 144.115 -      "graph F f \<subseteq> graph H' h'"  "\<forall>x \<in> H'. h' x \<le> p x"
 144.116 -    by (rule some_H'h't [elim_format]) blast
 144.117 -
 144.118 -  txt {* @{text x} is in the domain @{text H'} of some function @{text h'},
 144.119 -    such that @{text h} extends @{text h'}. *}
 144.120 -
 144.121 -  from M cM u and x obtain H'' h'' where
 144.122 -      x_hx: "(x, h x) \<in> graph H'' h''"
 144.123 -    and c'': "graph H'' h'' \<in> c"
 144.124 -    and ** :
 144.125 -      "linearform H'' h''"  "H'' \<unlhd> E"  "F \<unlhd> H''"
 144.126 -      "graph F f \<subseteq> graph H'' h''"  "\<forall>x \<in> H''. h'' x \<le> p x"
 144.127 -    by (rule some_H'h't [elim_format]) blast
 144.128 -
 144.129 -  txt {* Since both @{text h'} and @{text h''} are elements of the chain,
 144.130 -    @{text h''} is an extension of @{text h'} or vice versa. Thus both
 144.131 -    @{text x} and @{text y} are contained in the greater
 144.132 -    one. \label{cases1}*}
 144.133 -
 144.134 -  from cM c'' c' have "graph H'' h'' \<subseteq> graph H' h' \<or> graph H' h' \<subseteq> graph H'' h''"
 144.135 -    (is "?case1 \<or> ?case2") ..
 144.136 -  then show ?thesis
 144.137 -  proof
 144.138 -    assume ?case1
 144.139 -    have "(x, h x) \<in> graph H'' h''" by fact
 144.140 -    also have "\<dots> \<subseteq> graph H' h'" by fact
 144.141 -    finally have xh:"(x, h x) \<in> graph H' h'" .
 144.142 -    then have "x \<in> H'" ..
 144.143 -    moreover from y_hy have "y \<in> H'" ..
 144.144 -    moreover from cM u and c' have "graph H' h' \<subseteq> graph H h"
 144.145 -      by (simp only: chain_ball_Union_upper)
 144.146 -    ultimately show ?thesis using * by blast
 144.147 -  next
 144.148 -    assume ?case2
 144.149 -    from x_hx have "x \<in> H''" ..
 144.150 -    moreover {
 144.151 -      have "(y, h y) \<in> graph H' h'" by (rule y_hy)
 144.152 -      also have "\<dots> \<subseteq> graph H'' h''" by fact
 144.153 -      finally have "(y, h y) \<in> graph H'' h''" .
 144.154 -    } then have "y \<in> H''" ..
 144.155 -    moreover from cM u and c'' have "graph H'' h'' \<subseteq> graph H h"
 144.156 -      by (simp only: chain_ball_Union_upper)
 144.157 -    ultimately show ?thesis using ** by blast
 144.158 -  qed
 144.159 -qed
 144.160 -
 144.161 -text {*
 144.162 -  \medskip The relation induced by the graph of the supremum of a
 144.163 -  chain @{text c} is definite, i.~e.~t is the graph of a function.
 144.164 -*}
 144.165 -
 144.166 -lemma sup_definite:
 144.167 -  assumes M_def: "M \<equiv> norm_pres_extensions E p F f"
 144.168 -    and cM: "c \<in> chain M"
 144.169 -    and xy: "(x, y) \<in> \<Union>c"
 144.170 -    and xz: "(x, z) \<in> \<Union>c"
 144.171 -  shows "z = y"
 144.172 -proof -
 144.173 -  from cM have c: "c \<subseteq> M" ..
 144.174 -  from xy obtain G1 where xy': "(x, y) \<in> G1" and G1: "G1 \<in> c" ..
 144.175 -  from xz obtain G2 where xz': "(x, z) \<in> G2" and G2: "G2 \<in> c" ..
 144.176 -
 144.177 -  from G1 c have "G1 \<in> M" ..
 144.178 -  then obtain H1 h1 where G1_rep: "G1 = graph H1 h1"
 144.179 -    unfolding M_def by blast
 144.180 -
 144.181 -  from G2 c have "G2 \<in> M" ..
 144.182 -  then obtain H2 h2 where G2_rep: "G2 = graph H2 h2"
 144.183 -    unfolding M_def by blast
 144.184 -
 144.185 -  txt {* @{text "G\<^sub>1"} is contained in @{text "G\<^sub>2"}
 144.186 -    or vice versa, since both @{text "G\<^sub>1"} and @{text
 144.187 -    "G\<^sub>2"} are members of @{text c}. \label{cases2}*}
 144.188 -
 144.189 -  from cM G1 G2 have "G1 \<subseteq> G2 \<or> G2 \<subseteq> G1" (is "?case1 \<or> ?case2") ..
 144.190 -  then show ?thesis
 144.191 -  proof
 144.192 -    assume ?case1
 144.193 -    with xy' G2_rep have "(x, y) \<in> graph H2 h2" by blast
 144.194 -    then have "y = h2 x" ..
 144.195 -    also
 144.196 -    from xz' G2_rep have "(x, z) \<in> graph H2 h2" by (simp only:)
 144.197 -    then have "z = h2 x" ..
 144.198 -    finally show ?thesis .
 144.199 -  next
 144.200 -    assume ?case2
 144.201 -    with xz' G1_rep have "(x, z) \<in> graph H1 h1" by blast
 144.202 -    then have "z = h1 x" ..
 144.203 -    also
 144.204 -    from xy' G1_rep have "(x, y) \<in> graph H1 h1" by (simp only:)
 144.205 -    then have "y = h1 x" ..
 144.206 -    finally show ?thesis ..
 144.207 -  qed
 144.208 -qed
 144.209 -
 144.210 -text {*
 144.211 -  \medskip The limit function @{text h} is linear. Every element
 144.212 -  @{text x} in the domain of @{text h} is in the domain of a function
 144.213 -  @{text h'} in the chain of norm preserving extensions.  Furthermore,
 144.214 -  @{text h} is an extension of @{text h'} so the function values of
 144.215 -  @{text x} are identical for @{text h'} and @{text h}.  Finally, the
 144.216 -  function @{text h'} is linear by construction of @{text M}.
 144.217 -*}
 144.218 -
 144.219 -lemma sup_lf:
 144.220 -  assumes M: "M = norm_pres_extensions E p F f"
 144.221 -    and cM: "c \<in> chain M"
 144.222 -    and u: "graph H h = \<Union>c"
 144.223 -  shows "linearform H h"
 144.224 -proof
 144.225 -  fix x y assume x: "x \<in> H" and y: "y \<in> H"
 144.226 -  with M cM u obtain H' h' where
 144.227 -        x': "x \<in> H'" and y': "y \<in> H'"
 144.228 -      and b: "graph H' h' \<subseteq> graph H h"
 144.229 -      and linearform: "linearform H' h'"
 144.230 -      and subspace: "H' \<unlhd> E"
 144.231 -    by (rule some_H'h'2 [elim_format]) blast
 144.232 -
 144.233 -  show "h (x + y) = h x + h y"
 144.234 -  proof -
 144.235 -    from linearform x' y' have "h' (x + y) = h' x + h' y"
 144.236 -      by (rule linearform.add)
 144.237 -    also from b x' have "h' x = h x" ..
 144.238 -    also from b y' have "h' y = h y" ..
 144.239 -    also from subspace x' y' have "x + y \<in> H'"
 144.240 -      by (rule subspace.add_closed)
 144.241 -    with b have "h' (x + y) = h (x + y)" ..
 144.242 -    finally show ?thesis .
 144.243 -  qed
 144.244 -next
 144.245 -  fix x a assume x: "x \<in> H"
 144.246 -  with M cM u obtain H' h' where
 144.247 -        x': "x \<in> H'"
 144.248 -      and b: "graph H' h' \<subseteq> graph H h"
 144.249 -      and linearform: "linearform H' h'"
 144.250 -      and subspace: "H' \<unlhd> E"
 144.251 -    by (rule some_H'h' [elim_format]) blast
 144.252 -
 144.253 -  show "h (a \<cdot> x) = a * h x"
 144.254 -  proof -
 144.255 -    from linearform x' have "h' (a \<cdot> x) = a * h' x"
 144.256 -      by (rule linearform.mult)
 144.257 -    also from b x' have "h' x = h x" ..
 144.258 -    also from subspace x' have "a \<cdot> x \<in> H'"
 144.259 -      by (rule subspace.mult_closed)
 144.260 -    with b have "h' (a \<cdot> x) = h (a \<cdot> x)" ..
 144.261 -    finally show ?thesis .
 144.262 -  qed
 144.263 -qed
 144.264 -
 144.265 -text {*
 144.266 -  \medskip The limit of a non-empty chain of norm preserving
 144.267 -  extensions of @{text f} is an extension of @{text f}, since every
 144.268 -  element of the chain is an extension of @{text f} and the supremum
 144.269 -  is an extension for every element of the chain.
 144.270 -*}
 144.271 -
 144.272 -lemma sup_ext:
 144.273 -  assumes graph: "graph H h = \<Union>c"
 144.274 -    and M: "M = norm_pres_extensions E p F f"
 144.275 -    and cM: "c \<in> chain M"
 144.276 -    and ex: "\<exists>x. x \<in> c"
 144.277 -  shows "graph F f \<subseteq> graph H h"
 144.278 -proof -
 144.279 -  from ex obtain x where xc: "x \<in> c" ..
 144.280 -  from cM have "c \<subseteq> M" ..
 144.281 -  with xc have "x \<in> M" ..
 144.282 -  with M have "x \<in> norm_pres_extensions E p F f"
 144.283 -    by (simp only:)
 144.284 -  then obtain G g where "x = graph G g" and "graph F f \<subseteq> graph G g" ..
 144.285 -  then have "graph F f \<subseteq> x" by (simp only:)
 144.286 -  also from xc have "\<dots> \<subseteq> \<Union>c" by blast
 144.287 -  also from graph have "\<dots> = graph H h" ..
 144.288 -  finally show ?thesis .
 144.289 -qed
 144.290 -
 144.291 -text {*
 144.292 -  \medskip The domain @{text H} of the limit function is a superspace
 144.293 -  of @{text F}, since @{text F} is a subset of @{text H}. The
 144.294 -  existence of the @{text 0} element in @{text F} and the closure
 144.295 -  properties follow from the fact that @{text F} is a vector space.
 144.296 -*}
 144.297 -
 144.298 -lemma sup_supF:
 144.299 -  assumes graph: "graph H h = \<Union>c"
 144.300 -    and M: "M = norm_pres_extensions E p F f"
 144.301 -    and cM: "c \<in> chain M"
 144.302 -    and ex: "\<exists>x. x \<in> c"
 144.303 -    and FE: "F \<unlhd> E"
 144.304 -  shows "F \<unlhd> H"
 144.305 -proof
 144.306 -  from FE show "F \<noteq> {}" by (rule subspace.non_empty)
 144.307 -  from graph M cM ex have "graph F f \<subseteq> graph H h" by (rule sup_ext)
 144.308 -  then show "F \<subseteq> H" ..
 144.309 -  fix x y assume "x \<in> F" and "y \<in> F"
 144.310 -  with FE show "x + y \<in> F" by (rule subspace.add_closed)
 144.311 -next
 144.312 -  fix x a assume "x \<in> F"
 144.313 -  with FE show "a \<cdot> x \<in> F" by (rule subspace.mult_closed)
 144.314 -qed
 144.315 -
 144.316 -text {*
 144.317 -  \medskip The domain @{text H} of the limit function is a subspace of
 144.318 -  @{text E}.
 144.319 -*}
 144.320 -
 144.321 -lemma sup_subE:
 144.322 -  assumes graph: "graph H h = \<Union>c"
 144.323 -    and M: "M = norm_pres_extensions E p F f"
 144.324 -    and cM: "c \<in> chain M"
 144.325 -    and ex: "\<exists>x. x \<in> c"
 144.326 -    and FE: "F \<unlhd> E"
 144.327 -    and E: "vectorspace E"
 144.328 -  shows "H \<unlhd> E"
 144.329 -proof
 144.330 -  show "H \<noteq> {}"
 144.331 -  proof -
 144.332 -    from FE E have "0 \<in> F" by (rule subspace.zero)
 144.333 -    also from graph M cM ex FE have "F \<unlhd> H" by (rule sup_supF)
 144.334 -    then have "F \<subseteq> H" ..
 144.335 -    finally show ?thesis by blast
 144.336 -  qed
 144.337 -  show "H \<subseteq> E"
 144.338 -  proof
 144.339 -    fix x assume "x \<in> H"
 144.340 -    with M cM graph
 144.341 -    obtain H' h' where x: "x \<in> H'" and H'E: "H' \<unlhd> E"
 144.342 -      by (rule some_H'h' [elim_format]) blast
 144.343 -    from H'E have "H' \<subseteq> E" ..
 144.344 -    with x show "x \<in> E" ..
 144.345 -  qed
 144.346 -  fix x y assume x: "x \<in> H" and y: "y \<in> H"
 144.347 -  show "x + y \<in> H"
 144.348 -  proof -
 144.349 -    from M cM graph x y obtain H' h' where
 144.350 -          x': "x \<in> H'" and y': "y \<in> H'" and H'E: "H' \<unlhd> E"
 144.351 -        and graphs: "graph H' h' \<subseteq> graph H h"
 144.352 -      by (rule some_H'h'2 [elim_format]) blast
 144.353 -    from H'E x' y' have "x + y \<in> H'"
 144.354 -      by (rule subspace.add_closed)
 144.355 -    also from graphs have "H' \<subseteq> H" ..
 144.356 -    finally show ?thesis .
 144.357 -  qed
 144.358 -next
 144.359 -  fix x a assume x: "x \<in> H"
 144.360 -  show "a \<cdot> x \<in> H"
 144.361 -  proof -
 144.362 -    from M cM graph x
 144.363 -    obtain H' h' where x': "x \<in> H'" and H'E: "H' \<unlhd> E"
 144.364 -        and graphs: "graph H' h' \<subseteq> graph H h"
 144.365 -      by (rule some_H'h' [elim_format]) blast
 144.366 -    from H'E x' have "a \<cdot> x \<in> H'" by (rule subspace.mult_closed)
 144.367 -    also from graphs have "H' \<subseteq> H" ..
 144.368 -    finally show ?thesis .
 144.369 -  qed
 144.370 -qed
 144.371 -
 144.372 -text {*
 144.373 -  \medskip The limit function is bounded by the norm @{text p} as
 144.374 -  well, since all elements in the chain are bounded by @{text p}.
 144.375 -*}
 144.376 -
 144.377 -lemma sup_norm_pres:
 144.378 -  assumes graph: "graph H h = \<Union>c"
 144.379 -    and M: "M = norm_pres_extensions E p F f"
 144.380 -    and cM: "c \<in> chain M"
 144.381 -  shows "\<forall>x \<in> H. h x \<le> p x"
 144.382 -proof
 144.383 -  fix x assume "x \<in> H"
 144.384 -  with M cM graph obtain H' h' where x': "x \<in> H'"
 144.385 -      and graphs: "graph H' h' \<subseteq> graph H h"
 144.386 -      and a: "\<forall>x \<in> H'. h' x \<le> p x"
 144.387 -    by (rule some_H'h' [elim_format]) blast
 144.388 -  from graphs x' have [symmetric]: "h' x = h x" ..
 144.389 -  also from a x' have "h' x \<le> p x " ..
 144.390 -  finally show "h x \<le> p x" .
 144.391 -qed
 144.392 -
 144.393 -text {*
 144.394 -  \medskip The following lemma is a property of linear forms on real
 144.395 -  vector spaces. It will be used for the lemma @{text abs_HahnBanach}
 144.396 -  (see page \pageref{abs-HahnBanach}). \label{abs-ineq-iff} For real
 144.397 -  vector spaces the following inequations are equivalent:
 144.398 -  \begin{center}
 144.399 -  \begin{tabular}{lll}
 144.400 -  @{text "\<forall>x \<in> H. \<bar>h x\<bar> \<le> p x"} & and &
 144.401 -  @{text "\<forall>x \<in> H. h x \<le> p x"} \\
 144.402 -  \end{tabular}
 144.403 -  \end{center}
 144.404 -*}
 144.405 -
 144.406 -lemma abs_ineq_iff:
 144.407 -  assumes "subspace H E" and "vectorspace E" and "seminorm E p"
 144.408 -    and "linearform H h"
 144.409 -  shows "(\<forall>x \<in> H. \<bar>h x\<bar> \<le> p x) = (\<forall>x \<in> H. h x \<le> p x)" (is "?L = ?R")
 144.410 -proof
 144.411 -  interpret subspace H E by fact
 144.412 -  interpret vectorspace E by fact
 144.413 -  interpret seminorm E p by fact
 144.414 -  interpret linearform H h by fact
 144.415 -  have H: "vectorspace H" using `vectorspace E` ..
 144.416 -  {
 144.417 -    assume l: ?L
 144.418 -    show ?R
 144.419 -    proof
 144.420 -      fix x assume x: "x \<in> H"
 144.421 -      have "h x \<le> \<bar>h x\<bar>" by arith
 144.422 -      also from l x have "\<dots> \<le> p x" ..
 144.423 -      finally show "h x \<le> p x" .
 144.424 -    qed
 144.425 -  next
 144.426 -    assume r: ?R
 144.427 -    show ?L
 144.428 -    proof
 144.429 -      fix x assume x: "x \<in> H"
 144.430 -      show "\<And>a b :: real. - a \<le> b \<Longrightarrow> b \<le> a \<Longrightarrow> \<bar>b\<bar> \<le> a"
 144.431 -        by arith
 144.432 -      from `linearform H h` and H x
 144.433 -      have "- h x = h (- x)" by (rule linearform.neg [symmetric])
 144.434 -      also
 144.435 -      from H x have "- x \<in> H" by (rule vectorspace.neg_closed)
 144.436 -      with r have "h (- x) \<le> p (- x)" ..
 144.437 -      also have "\<dots> = p x"
 144.438 -	using `seminorm E p` `vectorspace E`
 144.439 -      proof (rule seminorm.minus)
 144.440 -        from x show "x \<in> E" ..
 144.441 -      qed
 144.442 -      finally have "- h x \<le> p x" .
 144.443 -      then show "- p x \<le> h x" by simp
 144.444 -      from r x show "h x \<le> p x" ..
 144.445 -    qed
 144.446 -  }
 144.447 -qed
 144.448 -
 144.449 -end
   145.1 --- a/src/HOL/Real/HahnBanach/Linearform.thy	Tue Dec 30 08:18:54 2008 +0100
   145.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   145.3 @@ -1,60 +0,0 @@
   145.4 -(*  Title:      HOL/Real/HahnBanach/Linearform.thy
   145.5 -    Author:     Gertrud Bauer, TU Munich
   145.6 -*)
   145.7 -
   145.8 -header {* Linearforms *}
   145.9 -
  145.10 -theory Linearform
  145.11 -imports VectorSpace
  145.12 -begin
  145.13 -
  145.14 -text {*
  145.15 -  A \emph{linear form} is a function on a vector space into the reals
  145.16 -  that is additive and multiplicative.
  145.17 -*}
  145.18 -
  145.19 -locale linearform =
  145.20 -  fixes V :: "'a\<Colon>{minus, plus, zero, uminus} set" and f
  145.21 -  assumes add [iff]: "x \<in> V \<Longrightarrow> y \<in> V \<Longrightarrow> f (x + y) = f x + f y"
  145.22 -    and mult [iff]: "x \<in> V \<Longrightarrow> f (a \<cdot> x) = a * f x"
  145.23 -
  145.24 -declare linearform.intro [intro?]
  145.25 -
  145.26 -lemma (in linearform) neg [iff]:
  145.27 -  assumes "vectorspace V"
  145.28 -  shows "x \<in> V \<Longrightarrow> f (- x) = - f x"
  145.29 -proof -
  145.30 -  interpret vectorspace V by fact
  145.31 -  assume x: "x \<in> V"
  145.32 -  then have "f (- x) = f ((- 1) \<cdot> x)" by (simp add: negate_eq1)
  145.33 -  also from x have "\<dots> = (- 1) * (f x)" by (rule mult)
  145.34 -  also from x have "\<dots> = - (f x)" by simp
  145.35 -  finally show ?thesis .
  145.36 -qed
  145.37 -
  145.38 -lemma (in linearform) diff [iff]:
  145.39 -  assumes "vectorspace V"
  145.40 -  shows "x \<in> V \<Longrightarrow> y \<in> V \<Longrightarrow> f (x - y) = f x - f y"
  145.41 -proof -
  145.42 -  interpret vectorspace V by fact
  145.43 -  assume x: "x \<in> V" and y: "y \<in> V"
  145.44 -  then have "x - y = x + - y" by (rule diff_eq1)
  145.45 -  also have "f \<dots> = f x + f (- y)" by (rule add) (simp_all add: x y)
  145.46 -  also have "f (- y) = - f y" using `vectorspace V` y by (rule neg)
  145.47 -  finally show ?thesis by simp
  145.48 -qed
  145.49 -
  145.50 -text {* Every linear form yields @{text 0} for the @{text 0} vector. *}
  145.51 -
  145.52 -lemma (in linearform) zero [iff]:
  145.53 -  assumes "vectorspace V"
  145.54 -  shows "f 0 = 0"
  145.55 -proof -
  145.56 -  interpret vectorspace V by fact
  145.57 -  have "f 0 = f (0 - 0)" by simp
  145.58 -  also have "\<dots> = f 0 - f 0" using `vectorspace V` by (rule diff) simp_all
  145.59 -  also have "\<dots> = 0" by simp
  145.60 -  finally show ?thesis .
  145.61 -qed
  145.62 -
  145.63 -end
   146.1 --- a/src/HOL/Real/HahnBanach/NormedSpace.thy	Tue Dec 30 08:18:54 2008 +0100
   146.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   146.3 @@ -1,117 +0,0 @@
   146.4 -(*  Title:      HOL/Real/HahnBanach/NormedSpace.thy
   146.5 -    Author:     Gertrud Bauer, TU Munich
   146.6 -*)
   146.7 -
   146.8 -header {* Normed vector spaces *}
   146.9 -
  146.10 -theory NormedSpace
  146.11 -imports Subspace
  146.12 -begin
  146.13 -
  146.14 -subsection {* Quasinorms *}
  146.15 -
  146.16 -text {*
  146.17 -  A \emph{seminorm} @{text "\<parallel>\<cdot>\<parallel>"} is a function on a real vector space
  146.18 -  into the reals that has the following properties: it is positive
  146.19 -  definite, absolute homogenous and subadditive.
  146.20 -*}
  146.21 -
  146.22 -locale norm_syntax =
  146.23 -  fixes norm :: "'a \<Rightarrow> real"    ("\<parallel>_\<parallel>")
  146.24 -
  146.25 -locale seminorm = var_V + norm_syntax +
  146.26 -  constrains V :: "'a\<Colon>{minus, plus, zero, uminus} set"
  146.27 -  assumes ge_zero [iff?]: "x \<in> V \<Longrightarrow> 0 \<le> \<parallel>x\<parallel>"
  146.28 -    and abs_homogenous [iff?]: "x \<in> V \<Longrightarrow> \<parallel>a \<cdot> x\<parallel> = \<bar>a\<bar> * \<parallel>x\<parallel>"
  146.29 -    and subadditive [iff?]: "x \<in> V \<Longrightarrow> y \<in> V \<Longrightarrow> \<parallel>x + y\<parallel> \<le> \<parallel>x\<parallel> + \<parallel>y\<parallel>"
  146.30 -
  146.31 -declare seminorm.intro [intro?]
  146.32 -
  146.33 -lemma (in seminorm) diff_subadditive:
  146.34 -  assumes "vectorspace V"
  146.35 -  shows "x \<in> V \<Longrightarrow> y \<in> V \<Longrightarrow> \<parallel>x - y\<parallel> \<le> \<parallel>x\<parallel> + \<parallel>y\<parallel>"
  146.36 -proof -
  146.37 -  interpret vectorspace V by fact
  146.38 -  assume x: "x \<in> V" and y: "y \<in> V"
  146.39 -  then have "x - y = x + - 1 \<cdot> y"
  146.40 -    by (simp add: diff_eq2 negate_eq2a)
  146.41 -  also from x y have "\<parallel>\<dots>\<parallel> \<le> \<parallel>x\<parallel> + \<parallel>- 1 \<cdot> y\<parallel>"
  146.42 -    by (simp add: subadditive)
  146.43 -  also from y have "\<parallel>- 1 \<cdot> y\<parallel> = \<bar>- 1\<bar> * \<parallel>y\<parallel>"
  146.44 -    by (rule abs_homogenous)
  146.45 -  also have "\<dots> = \<parallel>y\<parallel>" by simp
  146.46 -  finally show ?thesis .
  146.47 -qed
  146.48 -
  146.49 -lemma (in seminorm) minus:
  146.50 -  assumes "vectorspace V"
  146.51 -  shows "x \<in> V \<Longrightarrow> \<parallel>- x\<parallel> = \<parallel>x\<parallel>"
  146.52 -proof -
  146.53 -  interpret vectorspace V by fact
  146.54 -  assume x: "x \<in> V"
  146.55 -  then have "- x = - 1 \<cdot> x" by (simp only: negate_eq1)
  146.56 -  also from x have "\<parallel>\<dots>\<parallel> = \<bar>- 1\<bar> * \<parallel>x\<parallel>"
  146.57 -    by (rule abs_homogenous)
  146.58 -  also have "\<dots> = \<parallel>x\<parallel>" by simp
  146.59 -  finally show ?thesis .
  146.60 -qed
  146.61 -
  146.62 -
  146.63 -subsection {* Norms *}
  146.64 -
  146.65 -text {*
  146.66 -  A \emph{norm} @{text "\<parallel>\<cdot>\<parallel>"} is a seminorm that maps only the
  146.67 -  @{text 0} vector to @{text 0}.
  146.68 -*}
  146.69 -
  146.70 -locale norm = seminorm +
  146.71 -  assumes zero_iff [iff]: "x \<in> V \<Longrightarrow> (\<parallel>x\<parallel> = 0) = (x = 0)"
  146.72 -
  146.73 -
  146.74 -subsection {* Normed vector spaces *}
  146.75 -
  146.76 -text {*
  146.77 -  A vector space together with a norm is called a \emph{normed
  146.78 -  space}.
  146.79 -*}
  146.80 -
  146.81 -locale normed_vectorspace = vectorspace + norm
  146.82 -
  146.83 -declare normed_vectorspace.intro [intro?]
  146.84 -
  146.85 -lemma (in normed_vectorspace) gt_zero [intro?]:
  146.86 -  "x \<in> V \<Longrightarrow> x \<noteq> 0 \<Longrightarrow> 0 < \<parallel>x\<parallel>"
  146.87 -proof -
  146.88 -  assume x: "x \<in> V" and neq: "x \<noteq> 0"
  146.89 -  from x have "0 \<le> \<parallel>x\<parallel>" ..
  146.90 -  also have [symmetric]: "\<dots> \<noteq> 0"
  146.91 -  proof
  146.92 -    assume "\<parallel>x\<parallel> = 0"
  146.93 -    with x have "x = 0" by simp
  146.94 -    with neq show False by contradiction
  146.95 -  qed
  146.96 -  finally show ?thesis .
  146.97 -qed
  146.98 -
  146.99 -text {*
 146.100 -  Any subspace of a normed vector space is again a normed vectorspace.
 146.101 -*}
 146.102 -
 146.103 -lemma subspace_normed_vs [intro?]:
 146.104 -  fixes F E norm
 146.105 -  assumes "subspace F E" "normed_vectorspace E norm"
 146.106 -  shows "normed_vectorspace F norm"
 146.107 -proof -
 146.108 -  interpret subspace F E by fact
 146.109 -  interpret normed_vectorspace E norm by fact
 146.110 -  show ?thesis
 146.111 -  proof
 146.112 -    show "vectorspace F" by (rule vectorspace) unfold_locales
 146.113 -  next
 146.114 -    have "NormedSpace.norm E norm" ..
 146.115 -    with subset show "NormedSpace.norm F norm"
 146.116 -      by (simp add: norm_def seminorm_def norm_axioms_def)
 146.117 -  qed
 146.118 -qed
 146.119 -
 146.120 -end
   147.1 --- a/src/HOL/Real/HahnBanach/README.html	Tue Dec 30 08:18:54 2008 +0100
   147.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   147.3 @@ -1,38 +0,0 @@
   147.4 -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
   147.5 -
   147.6 -<!-- $Id$ -->
   147.7 -
   147.8 -<HTML>
   147.9 -
  147.10 -<HEAD>
  147.11 -  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
  147.12 -  <TITLE>HOL/Real/HahnBanach/README</TITLE>
  147.13 -</HEAD>
  147.14 -
  147.15 -<BODY>
  147.16 -
  147.17 -<H3>The Hahn-Banach Theorem for Real Vector Spaces (Isabelle/Isar)</H3>
  147.18 -
  147.19 -Author: Gertrud Bauer, Technische Universit&auml;t M&uuml;nchen<P>
  147.20 -
  147.21 -This directory contains the proof of the Hahn-Banach theorem for real vectorspaces,
  147.22 -following H. Heuser, Funktionalanalysis, p. 228 -232.
  147.23 -The Hahn-Banach theorem is one of the fundamental theorems of functioal analysis.
  147.24 -It is a conclusion of Zorn's lemma.<P>
  147.25 -
  147.26 -Two different formaulations of the theorem are presented, one for general real vectorspaces
  147.27 -and its application to normed vectorspaces. <P>
  147.28 -
  147.29 -The theorem says, that every continous linearform, defined on arbitrary subspaces
  147.30 -(not only one-dimensional subspaces), can be extended to a continous linearform on
  147.31 -the whole vectorspace.
  147.32 -
  147.33 -
  147.34 -<HR>
  147.35 -
  147.36 -<ADDRESS>
  147.37 -<A NAME="bauerg@in.tum.de" HREF="mailto:bauerg@in.tum.de">bauerg@in.tum.de</A>
  147.38 -</ADDRESS>
  147.39 -
  147.40 -</BODY>
  147.41 -</HTML>
   148.1 --- a/src/HOL/Real/HahnBanach/ROOT.ML	Tue Dec 30 08:18:54 2008 +0100
   148.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   148.3 @@ -1,8 +0,0 @@
   148.4 -(*  Title:      HOL/Real/HahnBanach/ROOT.ML
   148.5 -    ID:         $Id$
   148.6 -    Author:     Gertrud Bauer, TU Munich
   148.7 -
   148.8 -The Hahn-Banach theorem for real vector spaces (Isabelle/Isar).
   148.9 -*)
  148.10 -
  148.11 -time_use_thy "HahnBanach";
   149.1 --- a/src/HOL/Real/HahnBanach/Subspace.thy	Tue Dec 30 08:18:54 2008 +0100
   149.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   149.3 @@ -1,513 +0,0 @@
   149.4 -(*  Title:      HOL/Real/HahnBanach/Subspace.thy
   149.5 -    Author:     Gertrud Bauer, TU Munich
   149.6 -*)
   149.7 -
   149.8 -header {* Subspaces *}
   149.9 -
  149.10 -theory Subspace
  149.11 -imports VectorSpace
  149.12 -begin
  149.13 -
  149.14 -subsection {* Definition *}
  149.15 -
  149.16 -text {*
  149.17 -  A non-empty subset @{text U} of a vector space @{text V} is a
  149.18 -  \emph{subspace} of @{text V}, iff @{text U} is closed under addition
  149.19 -  and scalar multiplication.
  149.20 -*}
  149.21 -
  149.22 -locale subspace =
  149.23 -  fixes U :: "'a\<Colon>{minus, plus, zero, uminus} set" and V
  149.24 -  assumes non_empty [iff, intro]: "U \<noteq> {}"
  149.25 -    and subset [iff]: "U \<subseteq> V"
  149.26 -    and add_closed [iff]: "x \<in> U \<Longrightarrow> y \<in> U \<Longrightarrow> x + y \<in> U"
  149.27 -    and mult_closed [iff]: "x \<in> U \<Longrightarrow> a \<cdot> x \<in> U"
  149.28 -
  149.29 -notation (symbols)
  149.30 -  subspace  (infix "\<unlhd>" 50)
  149.31 -
  149.32 -declare vectorspace.intro [intro?] subspace.intro [intro?]
  149.33 -
  149.34 -lemma subspace_subset [elim]: "U \<unlhd> V \<Longrightarrow> U \<subseteq> V"
  149.35 -  by (rule subspace.subset)
  149.36 -
  149.37 -lemma (in subspace) subsetD [iff]: "x \<in> U \<Longrightarrow> x \<in> V"
  149.38 -  using subset by blast
  149.39 -
  149.40 -lemma subspaceD [elim]: "U \<unlhd> V \<Longrightarrow> x \<in> U \<Longrightarrow> x \<in> V"
  149.41 -  by (rule subspace.subsetD)
  149.42 -
  149.43 -lemma rev_subspaceD [elim?]: "x \<in> U \<Longrightarrow> U \<unlhd> V \<Longrightarrow> x \<in> V"
  149.44 -  by (rule subspace.subsetD)
  149.45 -
  149.46 -lemma (in subspace) diff_closed [iff]:
  149.47 -  assumes "vectorspace V"
  149.48 -  assumes x: "x \<in> U" and y: "y \<in> U"
  149.49 -  shows "x - y \<in> U"
  149.50 -proof -
  149.51 -  interpret vectorspace V by fact
  149.52 -  from x y show ?thesis by (simp add: diff_eq1 negate_eq1)
  149.53 -qed
  149.54 -
  149.55 -text {*
  149.56 -  \medskip Similar as for linear spaces, the existence of the zero
  149.57 -  element in every subspace follows from the non-emptiness of the
  149.58 -  carrier set and by vector space laws.
  149.59 -*}
  149.60 -
  149.61 -lemma (in subspace) zero [intro]:
  149.62 -  assumes "vectorspace V"
  149.63 -  shows "0 \<in> U"
  149.64 -proof -
  149.65 -  interpret V!: vectorspace V by fact
  149.66 -  have "U \<noteq> {}" by (rule non_empty)
  149.67 -  then obtain x where x: "x \<in> U" by blast
  149.68 -  then have "x \<in> V" .. then have "0 = x - x" by simp
  149.69 -  also from `vectorspace V` x x have "\<dots> \<in> U" by (rule diff_closed)
  149.70 -  finally show ?thesis .
  149.71 -qed
  149.72 -
  149.73 -lemma (in subspace) neg_closed [iff]:
  149.74 -  assumes "vectorspace V"
  149.75 -  assumes x: "x \<in> U"
  149.76 -  shows "- x \<in> U"
  149.77 -proof -
  149.78 -  interpret vectorspace V by fact
  149.79 -  from x show ?thesis by (simp add: negate_eq1)
  149.80 -qed
  149.81 -
  149.82 -text {* \medskip Further derived laws: every subspace is a vector space. *}
  149.83 -
  149.84 -lemma (in subspace) vectorspace [iff]:
  149.85 -  assumes "vectorspace V"
  149.86 -  shows "vectorspace U"
  149.87 -proof -
  149.88 -  interpret vectorspace V by fact
  149.89 -  show ?thesis
  149.90 -  proof
  149.91 -    show "U \<noteq> {}" ..
  149.92 -    fix x y z assume x: "x \<in> U" and y: "y \<in> U" and z: "z \<in> U"
  149.93 -    fix a b :: real
  149.94 -    from x y show "x + y \<in> U" by simp
  149.95 -    from x show "a \<cdot> x \<in> U" by simp
  149.96 -    from x y z show "(x + y) + z = x + (y + z)" by (simp add: add_ac)
  149.97 -    from x y show "x + y = y + x" by (simp add: add_ac)
  149.98 -    from x show "x - x = 0" by simp
  149.99 -    from x show "0 + x = x" by simp
 149.100 -    from x y show "a \<cdot> (x + y) = a \<cdot> x + a \<cdot> y" by (simp add: distrib)
 149.101 -    from x show "(a + b) \<cdot> x = a \<cdot> x + b \<cdot> x" by (simp add: distrib)
 149.102 -    from x show "(a * b) \<cdot> x = a \<cdot> b \<cdot> x" by (simp add: mult_assoc)
 149.103 -    from x show "1 \<cdot> x = x" by simp
 149.104 -    from x show "- x = - 1 \<cdot> x" by (simp add: negate_eq1)
 149.105 -    from x y show "x - y = x + - y" by (simp add: diff_eq1)
 149.106 -  qed
 149.107 -qed
 149.108 -
 149.109 -
 149.110 -text {* The subspace relation is reflexive. *}
 149.111 -
 149.112 -lemma (in vectorspace) subspace_refl [intro]: "V \<unlhd> V"
 149.113 -proof
 149.114 -  show "V \<noteq> {}" ..
 149.115 -  show "V \<subseteq> V" ..
 149.116 -  fix x y assume x: "x \<in> V" and y: "y \<in> V"
 149.117 -  fix a :: real
 149.118 -  from x y show "x + y \<in> V" by simp
 149.119 -  from x show "a \<cdot> x \<in> V" by simp
 149.120 -qed
 149.121 -
 149.122 -text {* The subspace relation is transitive. *}
 149.123 -
 149.124 -lemma (in vectorspace) subspace_trans [trans]:
 149.125 -  "U \<unlhd> V \<Longrightarrow> V \<unlhd> W \<Longrightarrow> U \<unlhd> W"
 149.126 -proof
 149.127 -  assume uv: "U \<unlhd> V" and vw: "V \<unlhd> W"
 149.128 -  from uv show "U \<noteq> {}" by (rule subspace.non_empty)
 149.129 -  show "U \<subseteq> W"
 149.130 -  proof -
 149.131 -    from uv have "U \<subseteq> V" by (rule subspace.subset)
 149.132 -    also from vw have "V \<subseteq> W" by (rule subspace.subset)
 149.133 -    finally show ?thesis .
 149.134 -  qed
 149.135 -  fix x y assume x: "x \<in> U" and y: "y \<in> U"
 149.136 -  from uv and x y show "x + y \<in> U" by (rule subspace.add_closed)
 149.137 -  from uv and x show "\<And>a. a \<cdot> x \<in> U" by (rule subspace.mult_closed)
 149.138 -qed
 149.139 -
 149.140 -
 149.141 -subsection {* Linear closure *}
 149.142 -
 149.143 -text {*
 149.144 -  The \emph{linear closure} of a vector @{text x} is the set of all
 149.145 -  scalar multiples of @{text x}.
 149.146 -*}
 149.147 -
 149.148 -definition
 149.149 -  lin :: "('a::{minus, plus, zero}) \<Rightarrow> 'a set" where
 149.150 -  "lin x = {a \<cdot> x | a. True}"
 149.151 -
 149.152 -lemma linI [intro]: "y = a \<cdot> x \<Longrightarrow> y \<in> lin x"
 149.153 -  unfolding lin_def by blast
 149.154 -
 149.155 -lemma linI' [iff]: "a \<cdot> x \<in> lin x"
 149.156 -  unfolding lin_def by blast
 149.157 -
 149.158 -lemma linE [elim]: "x \<in> lin v \<Longrightarrow> (\<And>a::real. x = a \<cdot> v \<Longrightarrow> C) \<Longrightarrow> C"
 149.159 -  unfolding lin_def by blast
 149.160 -
 149.161 -
 149.162 -text {* Every vector is contained in its linear closure. *}
 149.163 -
 149.164 -lemma (in vectorspace) x_lin_x [iff]: "x \<in> V \<Longrightarrow> x \<in> lin x"
 149.165 -proof -
 149.166 -  assume "x \<in> V"
 149.167 -  then have "x = 1 \<cdot> x" by simp
 149.168 -  also have "\<dots> \<in> lin x" ..
 149.169 -  finally show ?thesis .
 149.170 -qed
 149.171 -
 149.172 -lemma (in vectorspace) "0_lin_x" [iff]: "x \<in> V \<Longrightarrow> 0 \<in> lin x"
 149.173 -proof
 149.174 -  assume "x \<in> V"
 149.175 -  then show "0 = 0 \<cdot> x" by simp
 149.176 -qed
 149.177 -
 149.178 -text {* Any linear closure is a subspace. *}
 149.179 -
 149.180 -lemma (in vectorspace) lin_subspace [intro]:
 149.181 -  "x \<in> V \<Longrightarrow> lin x \<unlhd> V"
 149.182 -proof
 149.183 -  assume x: "x \<in> V"
 149.184 -  then show "lin x \<noteq> {}" by (auto simp add: x_lin_x)
 149.185 -  show "lin x \<subseteq> V"
 149.186 -  proof
 149.187 -    fix x' assume "x' \<in> lin x"
 149.188 -    then obtain a where "x' = a \<cdot> x" ..
 149.189 -    with x show "x' \<in> V" by simp
 149.190 -  qed
 149.191 -  fix x' x'' assume x': "x' \<in> lin x" and x'': "x'' \<in> lin x"
 149.192 -  show "x' + x'' \<in> lin x"
 149.193 -  proof -
 149.194 -    from x' obtain a' where "x' = a' \<cdot> x" ..
 149.195 -    moreover from x'' obtain a'' where "x'' = a'' \<cdot> x" ..
 149.196 -    ultimately have "x' + x'' = (a' + a'') \<cdot> x"
 149.197 -      using x by (simp add: distrib)
 149.198 -    also have "\<dots> \<in> lin x" ..
 149.199 -    finally show ?thesis .
 149.200 -  qed
 149.201 -  fix a :: real
 149.202 -  show "a \<cdot> x' \<in> lin x"
 149.203 -  proof -
 149.204 -    from x' obtain a' where "x' = a' \<cdot> x" ..
 149.205 -    with x have "a \<cdot> x' = (a * a') \<cdot> x" by (simp add: mult_assoc)
 149.206 -    also have "\<dots> \<in> lin x" ..
 149.207 -    finally show ?thesis .
 149.208 -  qed
 149.209 -qed
 149.210 -
 149.211 -
 149.212 -text {* Any linear closure is a vector space. *}
 149.213 -
 149.214 -lemma (in vectorspace) lin_vectorspace [intro]:
 149.215 -  assumes "x \<in> V"
 149.216 -  shows "vectorspace (lin x)"
 149.217 -proof -
 149.218 -  from `x \<in> V` have "subspace (lin x) V"
 149.219 -    by (rule lin_subspace)
 149.220 -  from this and vectorspace_axioms show ?thesis
 149.221 -    by (rule subspace.vectorspace)
 149.222 -qed
 149.223 -
 149.224 -
 149.225 -subsection {* Sum of two vectorspaces *}
 149.226 -
 149.227 -text {*
 149.228 -  The \emph{sum} of two vectorspaces @{text U} and @{text V} is the
 149.229 -  set of all sums of elements from @{text U} and @{text V}.
 149.230 -*}
 149.231 -
 149.232 -instantiation "fun" :: (type, type) plus
 149.233 -begin
 149.234 -
 149.235 -definition
 149.236 -  sum_def: "plus_fun U V = {u + v | u v. u \<in> U \<and> v \<in> V}"  (* FIXME not fully general!? *)
 149.237 -
 149.238 -instance ..
 149.239 -
 149.240 -end
 149.241 -
 149.242 -lemma sumE [elim]:
 149.243 -    "x \<in> U + V \<Longrightarrow> (\<And>u v. x = u + v \<Longrightarrow> u \<in> U \<Longrightarrow> v \<in> V \<Longrightarrow> C) \<Longrightarrow> C"
 149.244 -  unfolding sum_def by blast
 149.245 -
 149.246 -lemma sumI [intro]:
 149.247 -    "u \<in> U \<Longrightarrow> v \<in> V \<Longrightarrow> x = u + v \<Longrightarrow> x \<in> U + V"
 149.248 -  unfolding sum_def by blast
 149.249 -
 149.250 -lemma sumI' [intro]:
 149.251 -    "u \<in> U \<Longrightarrow> v \<in> V \<Longrightarrow> u + v \<in> U + V"
 149.252 -  unfolding sum_def by blast
 149.253 -
 149.254 -text {* @{text U} is a subspace of @{text "U + V"}. *}
 149.255 -
 149.256 -lemma subspace_sum1 [iff]:
 149.257 -  assumes "vectorspace U" "vectorspace V"
 149.258 -  shows "U \<unlhd> U + V"
 149.259 -proof -
 149.260 -  interpret vectorspace U by fact
 149.261 -  interpret vectorspace V by fact
 149.262 -  show ?thesis
 149.263 -  proof
 149.264 -    show "U \<noteq> {}" ..
 149.265 -    show "U \<subseteq> U + V"
 149.266 -    proof
 149.267 -      fix x assume x: "x \<in> U"
 149.268 -      moreover have "0 \<in> V" ..
 149.269 -      ultimately have "x + 0 \<in> U + V" ..
 149.270 -      with x show "x \<in> U + V" by simp
 149.271 -    qed
 149.272 -    fix x y assume x: "x \<in> U" and "y \<in> U"
 149.273 -    then show "x + y \<in> U" by simp
 149.274 -    from x show "\<And>a. a \<cdot> x \<in> U" by simp
 149.275 -  qed
 149.276 -qed
 149.277 -
 149.278 -text {* The sum of two subspaces is again a subspace. *}
 149.279 -
 149.280 -lemma sum_subspace [intro?]:
 149.281 -  assumes "subspace U E" "vectorspace E" "subspace V E"
 149.282 -  shows "U + V \<unlhd> E"
 149.283 -proof -
 149.284 -  interpret subspace U E by fact
 149.285 -  interpret vectorspace E by fact
 149.286 -  interpret subspace V E by fact
 149.287 -  show ?thesis
 149.288 -  proof
 149.289 -    have "0 \<in> U + V"
 149.290 -    proof
 149.291 -      show "0 \<in> U" using `vectorspace E` ..
 149.292 -      show "0 \<in> V" using `vectorspace E` ..
 149.293 -      show "(0::'a) = 0 + 0" by simp
 149.294 -    qed
 149.295 -    then show "U + V \<noteq> {}" by blast
 149.296 -    show "U + V \<subseteq> E"
 149.297 -    proof
 149.298 -      fix x assume "x \<in> U + V"
 149.299 -      then obtain u v where "x = u + v" and
 149.300 -	"u \<in> U" and "v \<in> V" ..
 149.301 -      then show "x \<in> E" by simp
 149.302 -    qed
 149.303 -    fix x y assume x: "x \<in> U + V" and y: "y \<in> U + V"
 149.304 -    show "x + y \<in> U + V"
 149.305 -    proof -
 149.306 -      from x obtain ux vx where "x = ux + vx" and "ux \<in> U" and "vx \<in> V" ..
 149.307 -      moreover
 149.308 -      from y obtain uy vy where "y = uy + vy" and "uy \<in> U" and "vy \<in> V" ..
 149.309 -      ultimately
 149.310 -      have "ux + uy \<in> U"
 149.311 -	and "vx + vy \<in> V"
 149.312 -	and "x + y = (ux + uy) + (vx + vy)"
 149.313 -	using x y by (simp_all add: add_ac)
 149.314 -      then show ?thesis ..
 149.315 -    qed
 149.316 -    fix a show "a \<cdot> x \<in> U + V"
 149.317 -    proof -
 149.318 -      from x obtain u v where "x = u + v" and "u \<in> U" and "v \<in> V" ..
 149.319 -      then have "a \<cdot> u \<in> U" and "a \<cdot> v \<in> V"
 149.320 -	and "a \<cdot> x = (a \<cdot> u) + (a \<cdot> v)" by (simp_all add: distrib)
 149.321 -      then show ?thesis ..
 149.322 -    qed
 149.323 -  qed
 149.324 -qed
 149.325 -
 149.326 -text{* The sum of two subspaces is a vectorspace. *}
 149.327 -
 149.328 -lemma sum_vs [intro?]:
 149.329 -    "U \<unlhd> E \<Longrightarrow> V \<unlhd> E \<Longrightarrow> vectorspace E \<Longrightarrow> vectorspace (U + V)"
 149.330 -  by (rule subspace.vectorspace) (rule sum_subspace)
 149.331 -
 149.332 -
 149.333 -subsection {* Direct sums *}
 149.334 -
 149.335 -text {*
 149.336 -  The sum of @{text U} and @{text V} is called \emph{direct}, iff the
 149.337 -  zero element is the only common element of @{text U} and @{text
 149.338 -  V}. For every element @{text x} of the direct sum of @{text U} and
 149.339 -  @{text V} the decomposition in @{text "x = u + v"} with
 149.340 -  @{text "u \<in> U"} and @{text "v \<in> V"} is unique.
 149.341 -*}
 149.342 -
 149.343 -lemma decomp:
 149.344 -  assumes "vectorspace E" "subspace U E" "subspace V E"
 149.345 -  assumes direct: "U \<inter> V = {0}"
 149.346 -    and u1: "u1 \<in> U" and u2: "u2 \<in> U"
 149.347 -    and v1: "v1 \<in> V" and v2: "v2 \<in> V"
 149.348 -    and sum: "u1 + v1 = u2 + v2"
 149.349 -  shows "u1 = u2 \<and> v1 = v2"
 149.350 -proof -
 149.351 -  interpret vectorspace E by fact
 149.352 -  interpret subspace U E by fact
 149.353 -  interpret subspace V E by fact
 149.354 -  show ?thesis
 149.355 -  proof
 149.356 -    have U: "vectorspace U"  (* FIXME: use interpret *)
 149.357 -      using `subspace U E` `vectorspace E` by (rule subspace.vectorspace)
 149.358 -    have V: "vectorspace V"
 149.359 -      using `subspace V E` `vectorspace E` by (rule subspace.vectorspace)
 149.360 -    from u1 u2 v1 v2 and sum have eq: "u1 - u2 = v2 - v1"
 149.361 -      by (simp add: add_diff_swap)
 149.362 -    from u1 u2 have u: "u1 - u2 \<in> U"
 149.363 -      by (rule vectorspace.diff_closed [OF U])
 149.364 -    with eq have v': "v2 - v1 \<in> U" by (simp only:)
 149.365 -    from v2 v1 have v: "v2 - v1 \<in> V"
 149.366 -      by (rule vectorspace.diff_closed [OF V])
 149.367 -    with eq have u': " u1 - u2 \<in> V" by (simp only:)
 149.368 -    
 149.369 -    show "u1 = u2"
 149.370 -    proof (rule add_minus_eq)
 149.371 -      from u1 show "u1 \<in> E" ..
 149.372 -      from u2 show "u2 \<in> E" ..
 149.373 -      from u u' and direct show "u1 - u2 = 0" by blast
 149.374 -    qed
 149.375 -    show "v1 = v2"
 149.376 -    proof (rule add_minus_eq [symmetric])
 149.377 -      from v1 show "v1 \<in> E" ..
 149.378 -      from v2 show "v2 \<in> E" ..
 149.379 -      from v v' and direct show "v2 - v1 = 0" by blast
 149.380 -    qed
 149.381 -  qed
 149.382 -qed
 149.383 -
 149.384 -text {*
 149.385 -  An application of the previous lemma will be used in the proof of
 149.386 -  the Hahn-Banach Theorem (see page \pageref{decomp-H-use}): for any
 149.387 -  element @{text "y + a \<cdot> x\<^sub>0"} of the direct sum of a
 149.388 -  vectorspace @{text H} and the linear closure of @{text "x\<^sub>0"}
 149.389 -  the components @{text "y \<in> H"} and @{text a} are uniquely
 149.390 -  determined.
 149.391 -*}
 149.392 -
 149.393 -lemma decomp_H':
 149.394 -  assumes "vectorspace E" "subspace H E"
 149.395 -  assumes y1: "y1 \<in> H" and y2: "y2 \<in> H"
 149.396 -    and x': "x' \<notin> H"  "x' \<in> E"  "x' \<noteq> 0"
 149.397 -    and eq: "y1 + a1 \<cdot> x' = y2 + a2 \<cdot> x'"
 149.398 -  shows "y1 = y2 \<and> a1 = a2"
 149.399 -proof -
 149.400 -  interpret vectorspace E by fact
 149.401 -  interpret subspace H E by fact
 149.402 -  show ?thesis
 149.403 -  proof
 149.404 -    have c: "y1 = y2 \<and> a1 \<cdot> x' = a2 \<cdot> x'"
 149.405 -    proof (rule decomp)
 149.406 -      show "a1 \<cdot> x' \<in> lin x'" ..
 149.407 -      show "a2 \<cdot> x' \<in> lin x'" ..
 149.408 -      show "H \<inter> lin x' = {0}"
 149.409 -      proof
 149.410 -	show "H \<inter> lin x' \<subseteq> {0}"
 149.411 -	proof
 149.412 -          fix x assume x: "x \<in> H \<inter> lin x'"
 149.413 -          then obtain a where xx': "x = a \<cdot> x'"
 149.414 -            by blast
 149.415 -          have "x = 0"
 149.416 -          proof cases
 149.417 -            assume "a = 0"
 149.418 -            with xx' and x' show ?thesis by simp
 149.419 -          next
 149.420 -            assume a: "a \<noteq> 0"
 149.421 -            from x have "x \<in> H" ..
 149.422 -            with xx' have "inverse a \<cdot> a \<cdot> x' \<in> H" by simp
 149.423 -            with a and x' have "x' \<in> H" by (simp add: mult_assoc2)
 149.424 -            with `x' \<notin> H` show ?thesis by contradiction
 149.425 -          qed
 149.426 -          then show "x \<in> {0}" ..
 149.427 -	qed
 149.428 -	show "{0} \<subseteq> H \<inter> lin x'"
 149.429 -	proof -
 149.430 -          have "0 \<in> H" using `vectorspace E` ..
 149.431 -          moreover have "0 \<in> lin x'" using `x' \<in> E` ..
 149.432 -          ultimately show ?thesis by blast
 149.433 -	qed
 149.434 -      qed
 149.435 -      show "lin x' \<unlhd> E" using `x' \<in> E` ..
 149.436 -    qed (rule `vectorspace E`, rule `subspace H E`, rule y1, rule y2, rule eq)
 149.437 -    then show "y1 = y2" ..
 149.438 -    from c have "a1 \<cdot> x' = a2 \<cdot> x'" ..
 149.439 -    with x' show "a1 = a2" by (simp add: mult_right_cancel)
 149.440 -  qed
 149.441 -qed
 149.442 -
 149.443 -text {*
 149.444 -  Since for any element @{text "y + a \<cdot> x'"} of the direct sum of a
 149.445 -  vectorspace @{text H} and the linear closure of @{text x'} the
 149.446 -  components @{text "y \<in> H"} and @{text a} are unique, it follows from
 149.447 -  @{text "y \<in> H"} that @{text "a = 0"}.
 149.448 -*}
 149.449 -
 149.450 -lemma decomp_H'_H:
 149.451 -  assumes "vectorspace E" "subspace H E"
 149.452 -  assumes t: "t \<in> H"
 149.453 -    and x': "x' \<notin> H"  "x' \<in> E"  "x' \<noteq> 0"
 149.454 -  shows "(SOME (y, a). t = y + a \<cdot> x' \<and> y \<in> H) = (t, 0)"
 149.455 -proof -
 149.456 -  interpret vectorspace E by fact
 149.457 -  interpret subspace H E by fact
 149.458 -  show ?thesis
 149.459 -  proof (rule, simp_all only: split_paired_all split_conv)
 149.460 -    from t x' show "t = t + 0 \<cdot> x' \<and> t \<in> H" by simp
 149.461 -    fix y and a assume ya: "t = y + a \<cdot> x' \<and> y \<in> H"
 149.462 -    have "y = t \<and> a = 0"
 149.463 -    proof (rule decomp_H')
 149.464 -      from ya x' show "y + a \<cdot> x' = t + 0 \<cdot> x'" by simp
 149.465 -      from ya show "y \<in> H" ..
 149.466 -    qed (rule `vectorspace E`, rule `subspace H E`, rule t, (rule x')+)
 149.467 -    with t x' show "(y, a) = (y + a \<cdot> x', 0)" by simp
 149.468 -  qed
 149.469 -qed
 149.470 -
 149.471 -text {*
 149.472 -  The components @{text "y \<in> H"} and @{text a} in @{text "y + a \<cdot> x'"}
 149.473 -  are unique, so the function @{text h'} defined by
 149.474 -  @{text "h' (y + a \<cdot> x') = h y + a \<cdot> \<xi>"} is definite.
 149.475 -*}
 149.476 -
 149.477 -lemma h'_definite:
 149.478 -  fixes H
 149.479 -  assumes h'_def:
 149.480 -    "h' \<equiv> (\<lambda>x. let (y, a) = SOME (y, a). (x = y + a \<cdot> x' \<and> y \<in> H)
 149.481 -                in (h y) + a * xi)"
 149.482 -    and x: "x = y + a \<cdot> x'"
 149.483 -  assumes "vectorspace E" "subspace H E"
 149.484 -  assumes y: "y \<in> H"
 149.485 -    and x': "x' \<notin> H"  "x' \<in> E"  "x' \<noteq> 0"
 149.486 -  shows "h' x = h y + a * xi"
 149.487 -proof -
 149.488 -  interpret vectorspace E by fact
 149.489 -  interpret subspace H E by fact
 149.490 -  from x y x' have "x \<in> H + lin x'" by auto
 149.491 -  have "\<exists>!p. (\<lambda>(y, a). x = y + a \<cdot> x' \<and> y \<in> H) p" (is "\<exists>!p. ?P p")
 149.492 -  proof (rule ex_ex1I)
 149.493 -    from x y show "\<exists>p. ?P p" by blast
 149.494 -    fix p q assume p: "?P p" and q: "?P q"
 149.495 -    show "p = q"
 149.496 -    proof -
 149.497 -      from p have xp: "x = fst p + snd p \<cdot> x' \<and> fst p \<in> H"
 149.498 -        by (cases p) simp
 149.499 -      from q have xq: "x = fst q + snd q \<cdot> x' \<and> fst q \<in> H"
 149.500 -        by (cases q) simp
 149.501 -      have "fst p = fst q \<and> snd p = snd q"
 149.502 -      proof (rule decomp_H')
 149.503 -        from xp show "fst p \<in> H" ..
 149.504 -        from xq show "fst q \<in> H" ..
 149.505 -        from xp and xq show "fst p + snd p \<cdot> x' = fst q + snd q \<cdot> x'"
 149.506 -          by simp
 149.507 -      qed (rule `vectorspace E`, rule `subspace H E`, (rule x')+)
 149.508 -      then show ?thesis by (cases p, cases q) simp
 149.509 -    qed
 149.510 -  qed
 149.511 -  then have eq: "(SOME (y, a). x = y + a \<cdot> x' \<and> y \<in> H) = (y, a)"
 149.512 -    by (rule some1_equality) (simp add: x y)
 149.513 -  with h'_def show "h' x = h y + a * xi" by (simp add: Let_def)
 149.514 -qed
 149.515 -
 149.516 -end
   150.1 --- a/src/HOL/Real/HahnBanach/VectorSpace.thy	Tue Dec 30 08:18:54 2008 +0100
   150.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   150.3 @@ -1,419 +0,0 @@
   150.4 -(*  Title:      HOL/Real/HahnBanach/VectorSpace.thy
   150.5 -    ID:         $Id$
   150.6 -    Author:     Gertrud Bauer, TU Munich
   150.7 -*)
   150.8 -
   150.9 -header {* Vector spaces *}
  150.10 -
  150.11 -theory VectorSpace
  150.12 -imports Real Bounds Zorn
  150.13 -begin
  150.14 -
  150.15 -subsection {* Signature *}
  150.16 -
  150.17 -text {*
  150.18 -  For the definition of real vector spaces a type @{typ 'a} of the
  150.19 -  sort @{text "{plus, minus, zero}"} is considered, on which a real
  150.20 -  scalar multiplication @{text \<cdot>} is declared.
  150.21 -*}
  150.22 -
  150.23 -consts
  150.24 -  prod  :: "real \<Rightarrow> 'a::{plus, minus, zero} \<Rightarrow> 'a"     (infixr "'(*')" 70)
  150.25 -
  150.26 -notation (xsymbols)
  150.27 -  prod  (infixr "\<cdot>" 70)
  150.28 -notation (HTML output)
  150.29 -  prod  (infixr "\<cdot>" 70)
  150.30 -
  150.31 -
  150.32 -subsection {* Vector space laws *}
  150.33 -
  150.34 -text {*
  150.35 -  A \emph{vector space} is a non-empty set @{text V} of elements from
  150.36 -  @{typ 'a} with the following vector space laws: The set @{text V} is
  150.37 -  closed under addition and scalar multiplication, addition is
  150.38 -  associative and commutative; @{text "- x"} is the inverse of @{text
  150.39 -  x} w.~r.~t.~addition and @{text 0} is the neutral element of
  150.40 -  addition.  Addition and multiplication are distributive; scalar
  150.41 -  multiplication is associative and the real number @{text "1"} is
  150.42 -  the neutral element of scalar multiplication.
  150.43 -*}
  150.44 -
  150.45 -locale var_V = fixes V
  150.46 -
  150.47 -locale vectorspace = var_V +
  150.48 -  assumes non_empty [iff, intro?]: "V \<noteq> {}"
  150.49 -    and add_closed [iff]: "x \<in> V \<Longrightarrow> y \<in> V \<Longrightarrow> x + y \<in> V"
  150.50 -    and mult_closed [iff]: "x \<in> V \<Longrightarrow> a \<cdot> x \<in> V"
  150.51 -    and add_assoc: "x \<in> V \<Longrightarrow> y \<in> V \<Longrightarrow> z \<in> V \<Longrightarrow> (x + y) + z = x + (y + z)"
  150.52 -    and add_commute: "x \<in> V \<Longrightarrow> y \<in> V \<Longrightarrow> x + y = y + x"
  150.53 -    and diff_self [simp]: "x \<in> V \<Longrightarrow> x - x = 0"
  150.54 -    and add_zero_left [simp]: "x \<in> V \<Longrightarrow> 0 + x = x"
  150.55 -    and add_mult_distrib1: "x \<in> V \<Longrightarrow> y \<in> V \<Longrightarrow> a \<cdot> (x + y) = a \<cdot> x + a \<cdot> y"
  150.56 -    and add_mult_distrib2: "x \<in> V \<Longrightarrow> (a + b) \<cdot> x = a \<cdot> x + b \<cdot> x"
  150.57 -    and mult_assoc: "x \<in> V \<Longrightarrow> (a * b) \<cdot> x = a \<cdot> (b \<cdot> x)"
  150.58 -    and mult_1 [simp]: "x \<in> V \<Longrightarrow> 1 \<cdot> x = x"
  150.59 -    and negate_eq1: "x \<in> V \<Longrightarrow> - x = (- 1) \<cdot> x"
  150.60 -    and diff_eq1: "x \<in> V \<Longrightarrow> y \<in> V \<Longrightarrow> x - y = x + - y"
  150.61 -
  150.62 -lemma (in vectorspace) negate_eq2: "x \<in> V \<Longrightarrow> (- 1) \<cdot> x = - x"
  150.63 -  by (rule negate_eq1 [symmetric])
  150.64 -
  150.65 -lemma (in vectorspace) negate_eq2a: "x \<in> V \<Longrightarrow> -1 \<cdot> x = - x"
  150.66 -  by (simp add: negate_eq1)
  150.67 -
  150.68 -lemma (in vectorspace) diff_eq2: "x \<in> V \<Longrightarrow> y \<in> V \<Longrightarrow> x + - y = x - y"
  150.69 -  by (rule diff_eq1 [symmetric])
  150.70 -
  150.71 -lemma (in vectorspace) diff_closed [iff]: "x \<in> V \<Longrightarrow> y \<in> V \<Longrightarrow> x - y \<in> V"
  150.72 -  by (simp add: diff_eq1 negate_eq1)
  150.73 -
  150.74 -lemma (in vectorspace) neg_closed [iff]: "x \<in> V \<Longrightarrow> - x \<in> V"
  150.75 -  by (simp add: negate_eq1)
  150.76 -
  150.77 -lemma (in vectorspace) add_left_commute:
  150.78 -  "x \<in> V \<Longrightarrow> y \<in> V \<Longrightarrow> z \<in> V \<Longrightarrow> x + (y + z) = y + (x + z)"
  150.79 -proof -
  150.80 -  assume xyz: "x \<in> V"  "y \<in> V"  "z \<in> V"
  150.81 -  then have "x + (y + z) = (x + y) + z"
  150.82 -    by (simp only: add_assoc)
  150.83 -  also from xyz have "\<dots> = (y + x) + z" by (simp only: add_commute)
  150.84 -  also from xyz have "\<dots> = y + (x + z)" by (simp only: add_assoc)
  150.85 -  finally show ?thesis .
  150.86 -qed
  150.87 -
  150.88 -theorems (in vectorspace) add_ac =
  150.89 -  add_assoc add_commute add_left_commute
  150.90 -
  150.91 -
  150.92 -text {* The existence of the zero element of a vector space
  150.93 -  follows from the non-emptiness of carrier set. *}
  150.94 -
  150.95 -lemma (in vectorspace) zero [iff]: "0 \<in> V"
  150.96 -proof -
  150.97 -  from non_empty obtain x where x: "x \<in> V" by blast
  150.98 -  then have "0 = x - x" by (rule diff_self [symmetric])
  150.99 -  also from x x have "\<dots> \<in> V" by (rule diff_closed)
 150.100 -  finally show ?thesis .
 150.101 -qed
 150.102 -
 150.103 -lemma (in vectorspace) add_zero_right [simp]:
 150.104 -  "x \<in> V \<Longrightarrow>  x + 0 = x"
 150.105 -proof -
 150.106 -  assume x: "x \<in> V"
 150.107 -  from this and zero have "x + 0 = 0 + x" by (rule add_commute)
 150.108 -  also from x have "\<dots> = x" by (rule add_zero_left)
 150.109 -  finally show ?thesis .
 150.110 -qed
 150.111 -
 150.112 -lemma (in vectorspace) mult_assoc2:
 150.113 -    "x \<in> V \<Longrightarrow> a \<cdot> b \<cdot> x = (a * b) \<cdot> x"
 150.114 -  by (simp only: mult_assoc)
 150.115 -
 150.116 -lemma (in vectorspace) diff_mult_distrib1:
 150.117 -    "x \<in> V \<Longrightarrow> y \<in> V \<Longrightarrow> a \<cdot> (x - y) = a \<cdot> x - a \<cdot> y"
 150.118 -  by (simp add: diff_eq1 negate_eq1 add_mult_distrib1 mult_assoc2)
 150.119 -
 150.120 -lemma (in vectorspace) diff_mult_distrib2:
 150.121 -  "x \<in> V \<Longrightarrow> (a - b) \<cdot> x = a \<cdot> x - (b \<cdot> x)"
 150.122 -proof -
 150.123 -  assume x: "x \<in> V"
 150.124 -  have " (a - b) \<cdot> x = (a + - b) \<cdot> x"
 150.125 -    by (simp add: real_diff_def)
 150.126 -  also from x have "\<dots> = a \<cdot> x + (- b) \<cdot> x"
 150.127 -    by (rule add_mult_distrib2)
 150.128 -  also from x have "\<dots> = a \<cdot> x + - (b \<cdot> x)"
 150.129 -    by (simp add: negate_eq1 mult_assoc2)
 150.130 -  also from x have "\<dots> = a \<cdot> x - (b \<cdot> x)"
 150.131 -    by (simp add: diff_eq1)
 150.132 -  finally show ?thesis .
 150.133 -qed
 150.134 -
 150.135 -lemmas (in vectorspace) distrib =
 150.136 -  add_mult_distrib1 add_mult_distrib2
 150.137 -  diff_mult_distrib1 diff_mult_distrib2
 150.138 -
 150.139 -
 150.140 -text {* \medskip Further derived laws: *}
 150.141 -
 150.142 -lemma (in vectorspace) mult_zero_left [simp]:
 150.143 -  "x \<in> V \<Longrightarrow> 0 \<cdot> x = 0"
 150.144 -proof -
 150.145 -  assume x: "x \<in> V"
 150.146 -  have "0 \<cdot> x = (1 - 1) \<cdot> x" by simp
 150.147 -  also have "\<dots> = (1 + - 1) \<cdot> x" by simp
 150.148 -  also from x have "\<dots> =  1 \<cdot> x + (- 1) \<cdot> x"
 150.149 -    by (rule add_mult_distrib2)
 150.150 -  also from x have "\<dots> = x + (- 1) \<cdot> x" by simp
 150.151 -  also from x have "\<dots> = x + - x" by (simp add: negate_eq2a)
 150.152 -  also from x have "\<dots> = x - x" by (simp add: diff_eq2)
 150.153 -  also from x have "\<dots> = 0" by simp
 150.154 -  finally show ?thesis .
 150.155 -qed
 150.156 -
 150.157 -lemma (in vectorspace) mult_zero_right [simp]:
 150.158 -  "a \<cdot> 0 = (0::'a)"
 150.159 -proof -
 150.160 -  have "a \<cdot> 0 = a \<cdot> (0 - (0::'a))" by simp
 150.161 -  also have "\<dots> =  a \<cdot> 0 - a \<cdot> 0"
 150.162 -    by (rule diff_mult_distrib1) simp_all
 150.163 -  also have "\<dots> = 0" by simp
 150.164 -  finally show ?thesis .
 150.165 -qed
 150.166 -
 150.167 -lemma (in vectorspace) minus_mult_cancel [simp]:
 150.168 -    "x \<in> V \<Longrightarrow> (- a) \<cdot> - x = a \<cdot> x"
 150.169 -  by (simp add: negate_eq1 mult_assoc2)
 150.170 -
 150.171 -lemma (in vectorspace) add_minus_left_eq_diff:
 150.172 -  "x \<in> V \<Longrightarrow> y \<in> V \<Longrightarrow> - x + y = y - x"
 150.173 -proof -
 150.174 -  assume xy: "x \<in> V"  "y \<in> V"
 150.175 -  then have "- x + y = y + - x" by (simp add: add_commute)
 150.176 -  also from xy have "\<dots> = y - x" by (simp add: diff_eq1)
 150.177 -  finally show ?thesis .
 150.178 -qed
 150.179 -
 150.180 -lemma (in vectorspace) add_minus [simp]:
 150.181 -    "x \<in> V \<Longrightarrow> x + - x = 0"
 150.182 -  by (simp add: diff_eq2)
 150.183 -
 150.184 -lemma (in vectorspace) add_minus_left [simp]:
 150.185 -    "x \<in> V \<Longrightarrow> - x + x = 0"
 150.186 -  by (simp add: diff_eq2 add_commute)
 150.187 -
 150.188 -lemma (in vectorspace) minus_minus [simp]:
 150.189 -    "x \<in> V \<Longrightarrow> - (- x) = x"
 150.190 -  by (simp add: negate_eq1 mult_assoc2)
 150.191 -
 150.192 -lemma (in vectorspace) minus_zero [simp]:
 150.193 -    "- (0::'a) = 0"
 150.194 -  by (simp add: negate_eq1)
 150.195 -
 150.196 -lemma (in vectorspace) minus_zero_iff [simp]:
 150.197 -  "x \<in> V \<Longrightarrow> (- x = 0) = (x = 0)"
 150.198 -proof
 150.199 -  assume x: "x \<in> V"
 150.200 -  {
 150.201 -    from x have "x = - (- x)" by (simp add: minus_minus)
 150.202 -    also assume "- x = 0"
 150.203 -    also have "- \<dots> = 0" by (rule minus_zero)
 150.204 -    finally show "x = 0" .
 150.205 -  next
 150.206 -    assume "x = 0"
 150.207 -    then show "- x = 0" by simp
 150.208 -  }
 150.209 -qed
 150.210 -
 150.211 -lemma (in vectorspace) add_minus_cancel [simp]:
 150.212 -    "x \<in> V \<Longrightarrow> y \<in> V \<Longrightarrow> x + (- x + y) = y"
 150.213 -  by (simp add: add_assoc [symmetric] del: add_commute)
 150.214 -
 150.215 -lemma (in vectorspace) minus_add_cancel [simp]:
 150.216 -    "x \<in> V \<Longrightarrow> y \<in> V \<Longrightarrow> - x + (x + y) = y"
 150.217 -  by (simp add: add_assoc [symmetric] del: add_commute)
 150.218 -
 150.219 -lemma (in vectorspace) minus_add_distrib [simp]:
 150.220 -    "x \<in> V \<Longrightarrow> y \<in> V \<Longrightarrow> - (x + y) = - x + - y"
 150.221 -  by (simp add: negate_eq1 add_mult_distrib1)
 150.222 -
 150.223 -lemma (in vectorspace) diff_zero [simp]:
 150.224 -    "x \<in> V \<Longrightarrow> x - 0 = x"
 150.225 -  by (simp add: diff_eq1)
 150.226 -
 150.227 -lemma (in vectorspace) diff_zero_right [simp]:
 150.228 -    "x \<in> V \<Longrightarrow> 0 - x = - x"
 150.229 -  by (simp add: diff_eq1)
 150.230 -
 150.231 -lemma (in vectorspace) add_left_cancel:
 150.232 -  "x \<in> V \<Longrightarrow> y \<in> V \<Longrightarrow> z \<in> V \<Longrightarrow> (x + y = x + z) = (y = z)"
 150.233 -proof
 150.234 -  assume x: "x \<in> V" and y: "y \<in> V" and z: "z \<in> V"
 150.235 -  {
 150.236 -    from y have "y = 0 + y" by simp
 150.237 -    also from x y have "\<dots> = (- x + x) + y" by simp
 150.238 -    also from x y have "\<dots> = - x + (x + y)"
 150.239 -      by (simp add: add_assoc neg_closed)
 150.240 -    also assume "x + y = x + z"
 150.241 -    also from x z have "- x + (x + z) = - x + x + z"
 150.242 -      by (simp add: add_assoc [symmetric] neg_closed)
 150.243 -    also from x z have "\<dots> = z" by simp
 150.244 -    finally show "y = z" .
 150.245 -  next
 150.246 -    assume "y = z"
 150.247 -    then show "x + y = x + z" by (simp only:)
 150.248 -  }
 150.249 -qed
 150.250 -
 150.251 -lemma (in vectorspace) add_right_cancel:
 150.252 -    "x \<in> V \<Longrightarrow> y \<in> V \<Longrightarrow> z \<in> V \<Longrightarrow> (y + x = z + x) = (y = z)"
 150.253 -  by (simp only: add_commute add_left_cancel)
 150.254 -
 150.255 -lemma (in vectorspace) add_assoc_cong:
 150.256 -  "x \<in> V \<Longrightarrow> y \<in> V \<Longrightarrow> x' \<in> V \<Longrightarrow> y' \<in> V \<Longrightarrow> z \<in> V
 150.257 -    \<Longrightarrow> x + y = x' + y' \<Longrightarrow> x + (y + z) = x' + (y' + z)"
 150.258 -  by (simp only: add_assoc [symmetric])
 150.259 -
 150.260 -lemma (in vectorspace) mult_left_commute:
 150.261 -    "x \<in> V \<Longrightarrow> a \<cdot> b \<cdot> x = b \<cdot> a \<cdot> x"
 150.262 -  by (simp add: real_mult_commute mult_assoc2)
 150.263 -
 150.264 -lemma (in vectorspace) mult_zero_uniq:
 150.265 -  "x \<in> V \<Longrightarrow> x \<noteq> 0 \<Longrightarrow> a \<cdot> x = 0 \<Longrightarrow> a = 0"
 150.266 -proof (rule classical)
 150.267 -  assume a: "a \<noteq> 0"
 150.268 -  assume x: "x \<in> V"  "x \<noteq> 0" and ax: "a \<cdot> x = 0"
 150.269 -  from x a have "x = (inverse a * a) \<cdot> x" by simp
 150.270 -  also from `x \<in> V` have "\<dots> = inverse a \<cdot> (a \<cdot> x)" by (rule mult_assoc)
 150.271 -  also from ax have "\<dots> = inverse a \<cdot> 0" by simp
 150.272 -  also have "\<dots> = 0" by simp
 150.273 -  finally have "x = 0" .
 150.274 -  with `x \<noteq> 0` show "a = 0" by contradiction
 150.275 -qed
 150.276 -
 150.277 -lemma (in vectorspace) mult_left_cancel:
 150.278 -  "x \<in> V \<Longrightarrow> y \<in> V \<Longrightarrow> a \<noteq> 0 \<Longrightarrow> (a \<cdot> x = a \<cdot> y) = (x = y)"
 150.279 -proof
 150.280 -  assume x: "x \<in> V" and y: "y \<in> V" and a: "a \<noteq> 0"
 150.281 -  from x have "x = 1 \<cdot> x" by simp
 150.282 -  also from a have "\<dots> = (inverse a * a) \<cdot> x" by simp
 150.283 -  also from x have "\<dots> = inverse a \<cdot> (a \<cdot> x)"
 150.284 -    by (simp only: mult_assoc)
 150.285 -  also assume "a \<cdot> x = a \<cdot> y"
 150.286 -  also from a y have "inverse a \<cdot> \<dots> = y"
 150.287 -    by (simp add: mult_assoc2)
 150.288 -  finally show "x = y" .
 150.289 -next
 150.290 -  assume "x = y"
 150.291 -  then show "a \<cdot> x = a \<cdot> y" by (simp only:)
 150.292 -qed
 150.293 -
 150.294 -lemma (in vectorspace) mult_right_cancel:
 150.295 -  "x \<in> V \<Longrightarrow> x \<noteq> 0 \<Longrightarrow> (a \<cdot> x = b \<cdot> x) = (a = b)"
 150.296 -proof
 150.297 -  assume x: "x \<in> V" and neq: "x \<noteq> 0"
 150.298 -  {
 150.299 -    from x have "(a - b) \<cdot> x = a \<cdot> x - b \<cdot> x"
 150.300 -      by (simp add: diff_mult_distrib2)
 150.301 -    also assume "a \<cdot> x = b \<cdot> x"
 150.302 -    with x have "a \<cdot> x - b \<cdot> x = 0" by simp
 150.303 -    finally have "(a - b) \<cdot> x = 0" .
 150.304 -    with x neq have "a - b = 0" by (rule mult_zero_uniq)
 150.305 -    then show "a = b" by simp
 150.306 -  next
 150.307 -    assume "a = b"
 150.308 -    then show "a \<cdot> x = b \<cdot> x" by (simp only:)
 150.309 -  }
 150.310 -qed
 150.311 -
 150.312 -lemma (in vectorspace) eq_diff_eq:
 150.313 -  "x \<in> V \<Longrightarrow> y \<in> V \<Longrightarrow> z \<in> V \<Longrightarrow> (x = z - y) = (x + y = z)"
 150.314 -proof
 150.315 -  assume x: "x \<in> V" and y: "y \<in> V" and z: "z \<in> V"
 150.316 -  {
 150.317 -    assume "x = z - y"
 150.318 -    then have "x + y = z - y + y" by simp
 150.319 -    also from y z have "\<dots> = z + - y + y"
 150.320 -      by (simp add: diff_eq1)
 150.321 -    also have "\<dots> = z + (- y + y)"
 150.322 -      by (rule add_assoc) (simp_all add: y z)
 150.323 -    also from y z have "\<dots> = z + 0"
 150.324 -      by (simp only: add_minus_left)
 150.325 -    also from z have "\<dots> = z"
 150.326 -      by (simp only: add_zero_right)
 150.327 -    finally show "x + y = z" .
 150.328 -  next
 150.329 -    assume "x + y = z"
 150.330 -    then have "z - y = (x + y) - y" by simp
 150.331 -    also from x y have "\<dots> = x + y + - y"
 150.332 -      by (simp add: diff_eq1)
 150.333 -    also have "\<dots> = x + (y + - y)"
 150.334 -      by (rule add_assoc) (simp_all add: x y)
 150.335 -    also from x y have "\<dots> = x" by simp
 150.336 -    finally show "x = z - y" ..
 150.337 -  }
 150.338 -qed
 150.339 -
 150.340 -lemma (in vectorspace) add_minus_eq_minus:
 150.341 -  "x \<in> V \<Longrightarrow> y \<in> V \<Longrightarrow> x + y = 0 \<Longrightarrow> x = - y"
 150.342 -proof -
 150.343 -  assume x: "x \<in> V" and y: "y \<in> V"
 150.344 -  from x y have "x = (- y + y) + x" by simp
 150.345 -  also from x y have "\<dots> = - y + (x + y)" by (simp add: add_ac)
 150.346 -  also assume "x + y = 0"
 150.347 -  also from y have "- y + 0 = - y" by simp
 150.348 -  finally show "x = - y" .
 150.349 -qed
 150.350 -
 150.351 -lemma (in vectorspace) add_minus_eq:
 150.352 -  "x \<in> V \<Longrightarrow> y \<in> V \<Longrightarrow> x - y = 0 \<Longrightarrow> x = y"
 150.353 -proof -
 150.354 -  assume x: "x \<in> V" and y: "y \<in> V"
 150.355 -  assume "x - y = 0"
 150.356 -  with x y have eq: "x + - y = 0" by (simp add: diff_eq1)
 150.357 -  with _ _ have "x = - (- y)"
 150.358 -    by (rule add_minus_eq_minus) (simp_all add: x y)
 150.359 -  with x y show "x = y" by simp
 150.360 -qed
 150.361 -
 150.362 -lemma (in vectorspace) add_diff_swap:
 150.363 -  "a \<in> V \<Longrightarrow> b \<in> V \<Longrightarrow> c \<in> V \<Longrightarrow> d \<in> V \<Longrightarrow> a + b = c + d
 150.364 -    \<Longrightarrow> a - c = d - b"
 150.365 -proof -
 150.366 -  assume vs: "a \<in> V"  "b \<in> V"  "c \<in> V"  "d \<in> V"
 150.367 -    and eq: "a + b = c + d"
 150.368 -  then have "- c + (a + b) = - c + (c + d)"
 150.369 -    by (simp add: add_left_cancel)
 150.370 -  also have "\<dots> = d" using `c \<in> V` `d \<in> V` by (rule minus_add_cancel)
 150.371 -  finally have eq: "- c + (a + b) = d" .
 150.372 -  from vs have "a - c = (- c + (a + b)) + - b"
 150.373 -    by (simp add: add_ac diff_eq1)
 150.374 -  also from vs eq have "\<dots>  = d + - b"
 150.375 -    by (simp add: add_right_cancel)
 150.376 -  also from vs have "\<dots> = d - b" by (simp add: diff_eq2)
 150.377 -  finally show "a - c = d - b" .
 150.378 -qed
 150.379 -
 150.380 -lemma (in vectorspace) vs_add_cancel_21:
 150.381 -  "x \<in> V \<Longrightarrow> y \<in> V \<Longrightarrow> z \<in> V \<Longrightarrow> u \<in> V
 150.382 -    \<Longrightarrow> (x + (y + z) = y + u) = (x + z = u)"
 150.383 -proof
 150.384 -  assume vs: "x \<in> V"  "y \<in> V"  "z \<in> V"  "u \<in> V"
 150.385 -  {
 150.386 -    from vs have "x + z = - y + y + (x + z)" by simp
 150.387 -    also have "\<dots> = - y + (y + (x + z))"
 150.388 -      by (rule add_assoc) (simp_all add: vs)
 150.389 -    also from vs have "y + (x + z) = x + (y + z)"
 150.390 -      by (simp add: add_ac)
 150.391 -    also assume "x + (y + z) = y + u"
 150.392 -    also from vs have "- y + (y + u) = u" by simp
 150.393 -    finally show "x + z = u" .
 150.394 -  next
 150.395 -    assume "x + z = u"
 150.396 -    with vs show "x + (y + z) = y + u"
 150.397 -      by (simp only: add_left_commute [of x])
 150.398 -  }
 150.399 -qed
 150.400 -
 150.401 -lemma (in vectorspace) add_cancel_end:
 150.402 -  "x \<in> V \<Longrightarrow> y \<in> V \<Longrightarrow> z \<in> V \<Longrightarrow> (x + (y + z) = y) = (x = - z)"
 150.403 -proof
 150.404 -  assume vs: "x \<in> V"  "y \<in> V"  "z \<in> V"
 150.405 -  {
 150.406 -    assume "x + (y + z) = y"
 150.407 -    with vs have "(x + z) + y = 0 + y"
 150.408 -      by (simp add: add_ac)
 150.409 -    with vs have "x + z = 0"
 150.410 -      by (simp only: add_right_cancel add_closed zero)
 150.411 -    with vs show "x = - z" by (simp add: add_minus_eq_minus)
 150.412 -  next
 150.413 -    assume eq: "x = - z"
 150.414 -    then have "x + (y + z) = - z + (y + z)" by simp
 150.415 -    also have "\<dots> = y + (- z + z)"
 150.416 -      by (rule add_left_commute) (simp_all add: vs)
 150.417 -    also from vs have "\<dots> = y"  by simp
 150.418 -    finally show "x + (y + z) = y" .
 150.419 -  }
 150.420 -qed
 150.421 -
 150.422 -end
   151.1 --- a/src/HOL/Real/HahnBanach/ZornLemma.thy	Tue Dec 30 08:18:54 2008 +0100
   151.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   151.3 @@ -1,57 +0,0 @@
   151.4 -(*  Title:      HOL/Real/HahnBanach/ZornLemma.thy
   151.5 -    Author:     Gertrud Bauer, TU Munich
   151.6 -*)
   151.7 -
   151.8 -header {* Zorn's Lemma *}
   151.9 -
  151.10 -theory ZornLemma
  151.11 -imports Zorn
  151.12 -begin
  151.13 -
  151.14 -text {*
  151.15 -  Zorn's Lemmas states: if every linear ordered subset of an ordered
  151.16 -  set @{text S} has an upper bound in @{text S}, then there exists a
  151.17 -  maximal element in @{text S}.  In our application, @{text S} is a
  151.18 -  set of sets ordered by set inclusion. Since the union of a chain of
  151.19 -  sets is an upper bound for all elements of the chain, the conditions
  151.20 -  of Zorn's lemma can be modified: if @{text S} is non-empty, it
  151.21 -  suffices to show that for every non-empty chain @{text c} in @{text
  151.22 -  S} the union of @{text c} also lies in @{text S}.
  151.23 -*}
  151.24 -
  151.25 -theorem Zorn's_Lemma:
  151.26 -  assumes r: "\<And>c. c \<in> chain S \<Longrightarrow> \<exists>x. x \<in> c \<Longrightarrow> \<Union>c \<in> S"
  151.27 -    and aS: "a \<in> S"
  151.28 -  shows "\<exists>y \<in> S. \<forall>z \<in> S. y \<subseteq> z \<longrightarrow> y = z"
  151.29 -proof (rule Zorn_Lemma2)
  151.30 -  show "\<forall>c \<in> chain S. \<exists>y \<in> S. \<forall>z \<in> c. z \<subseteq> y"
  151.31 -  proof
  151.32 -    fix c assume "c \<in> chain S"
  151.33 -    show "\<exists>y \<in> S. \<forall>z \<in> c. z \<subseteq> y"
  151.34 -    proof cases
  151.35 -
  151.36 -      txt {* If @{text c} is an empty chain, then every element in
  151.37 -	@{text S} is an upper bound of @{text c}. *}
  151.38 -
  151.39 -      assume "c = {}"
  151.40 -      with aS show ?thesis by fast
  151.41 -
  151.42 -      txt {* If @{text c} is non-empty, then @{text "\<Union>c"} is an upper
  151.43 -	bound of @{text c}, lying in @{text S}. *}
  151.44 -
  151.45 -    next
  151.46 -      assume "c \<noteq> {}"
  151.47 -      show ?thesis
  151.48 -      proof
  151.49 -        show "\<forall>z \<in> c. z \<subseteq> \<Union>c" by fast
  151.50 -        show "\<Union>c \<in> S"
  151.51 -        proof (rule r)
  151.52 -          from `c \<noteq> {}` show "\<exists>x. x \<in> c" by fast
  151.53 -	  show "c \<in> chain S" by fact
  151.54 -        qed
  151.55 -      qed
  151.56 -    qed
  151.57 -  qed
  151.58 -qed
  151.59 -
  151.60 -end
   152.1 --- a/src/HOL/Real/HahnBanach/document/root.bib	Tue Dec 30 08:18:54 2008 +0100
   152.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   152.3 @@ -1,27 +0,0 @@
   152.4 -
   152.5 -@Book{Heuser:1986,
   152.6 -  author = 	 {H. Heuser},
   152.7 -  title = 	 {Funktionalanalysis: Theorie und Anwendung},
   152.8 -  publisher = 	 {Teubner},
   152.9 -  year = 	 1986
  152.10 -}
  152.11 -
  152.12 -@InCollection{Narici:1996,
  152.13 -  author = 	 {L. Narici and E. Beckenstein},
  152.14 -  title = 	 {The {Hahn-Banach Theorem}: The Life and Times},
  152.15 -  booktitle = 	 {Topology Atlas},
  152.16 -  publisher =	 {York University, Toronto, Ontario, Canada},
  152.17 -  year =	 1996,
  152.18 -  note =	 {\url{http://at.yorku.ca/topology/preprint.htm} and
  152.19 -                  \url{http://at.yorku.ca/p/a/a/a/16.htm}}
  152.20 -}
  152.21 -
  152.22 -@Article{Nowak:1993,
  152.23 -  author =       {B. Nowak and A. Trybulec},
  152.24 -  title =	 {{Hahn-Banach} Theorem},
  152.25 -  journal =      {Journal of Formalized Mathematics},
  152.26 -  year =         {1993},
  152.27 -  volume =       {5},
  152.28 -  institution =  {University of Bialystok},
  152.29 -  note =         {\url{http://mizar.uwb.edu.pl/JFM/Vol5/hahnban.html}}
  152.30 -}
   153.1 --- a/src/HOL/Real/HahnBanach/document/root.tex	Tue Dec 30 08:18:54 2008 +0100
   153.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   153.3 @@ -1,83 +0,0 @@
   153.4 -\documentclass[10pt,a4paper,twoside]{article}
   153.5 -\usepackage{graphicx}
   153.6 -\usepackage{latexsym,theorem}
   153.7 -\usepackage{isabelle,isabellesym}
   153.8 -\usepackage{pdfsetup} %last one!
   153.9 -
  153.10 -\isabellestyle{it}
  153.11 -\urlstyle{rm}
  153.12 -
  153.13 -\newcommand{\isasymsup}{\isamath{\sup\,}}
  153.14 -\newcommand{\skp}{\smallskip}
  153.15 -
  153.16 -
  153.17 -\begin{document}
  153.18 -
  153.19 -\pagestyle{headings}
  153.20 -\pagenumbering{arabic}
  153.21 -
  153.22 -\title{The Hahn-Banach Theorem \\ for Real Vector Spaces}
  153.23 -\author{Gertrud Bauer \\ \url{http://www.in.tum.de/~bauerg/}}
  153.24 -\maketitle
  153.25 -
  153.26 -\begin{abstract}
  153.27 -  The Hahn-Banach Theorem is one of the most fundamental results in functional
  153.28 -  analysis. We present a fully formal proof of two versions of the theorem,
  153.29 -  one for general linear spaces and another for normed spaces.  This
  153.30 -  development is based on simply-typed classical set-theory, as provided by
  153.31 -  Isabelle/HOL.
  153.32 -\end{abstract}
  153.33 -
  153.34 -
  153.35 -\tableofcontents
  153.36 -\parindent 0pt \parskip 0.5ex
  153.37 -
  153.38 -\clearpage
  153.39 -\section{Preface}
  153.40 -
  153.41 -This is a fully formal proof of the Hahn-Banach Theorem. It closely follows
  153.42 -the informal presentation given in Heuser's textbook \cite[{\S} 36]{Heuser:1986}.
  153.43 -Another formal proof of the same theorem has been done in Mizar
  153.44 -\cite{Nowak:1993}.  A general overview of the relevance and history of the
  153.45 -Hahn-Banach Theorem is given by Narici and Beckenstein \cite{Narici:1996}.
  153.46 -
  153.47 -\medskip The document is structured as follows.  The first part contains
  153.48 -definitions of basic notions of linear algebra: vector spaces, subspaces,
  153.49 -normed spaces, continuous linear-forms, norm of functions and an order on
  153.50 -functions by domain extension.  The second part contains some lemmas about the
  153.51 -supremum (w.r.t.\ the function order) and extension of non-maximal functions.
  153.52 -With these preliminaries, the main proof of the theorem (in its two versions)
  153.53 -is conducted in the third part.  The dependencies of individual theories are
  153.54 -as follows.
  153.55 -
  153.56 -\begin{center}
  153.57 -  \includegraphics[scale=0.5]{session_graph}  
  153.58 -\end{center}
  153.59 -
  153.60 -\clearpage
  153.61 -\part {Basic Notions}
  153.62 -
  153.63 -\input{Bounds}
  153.64 -\input{VectorSpace}
  153.65 -\input{Subspace}
  153.66 -\input{NormedSpace}
  153.67 -\input{Linearform}
  153.68 -\input{FunctionOrder}
  153.69 -\input{FunctionNorm}
  153.70 -\input{ZornLemma}
  153.71 -
  153.72 -\clearpage
  153.73 -\part {Lemmas for the Proof}
  153.74 -
  153.75 -\input{HahnBanachSupLemmas}
  153.76 -\input{HahnBanachExtLemmas}
  153.77 -\input{HahnBanachLemmas}
  153.78 -
  153.79 -\clearpage
  153.80 -\part {The Main Proof}
  153.81 -
  153.82 -\input{HahnBanach}
  153.83 -\bibliographystyle{abbrv}
  153.84 -\bibliography{root}
  153.85 -
  153.86 -\end{document}
   154.1 --- a/src/HOL/Real/RealVector.thy	Tue Dec 30 08:18:54 2008 +0100
   154.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   154.3 @@ -1,841 +0,0 @@
   154.4 -(*  Title:      HOL/Real/RealVector.thy
   154.5 -    Author:     Brian Huffman
   154.6 -*)
   154.7 -
   154.8 -header {* Vector Spaces and Algebras over the Reals *}
   154.9 -
  154.10 -theory RealVector
  154.11 -imports "~~/src/HOL/RealPow"
  154.12 -begin
  154.13 -
  154.14 -subsection {* Locale for additive functions *}
  154.15 -
  154.16 -locale additive =
  154.17 -  fixes f :: "'a::ab_group_add \<Rightarrow> 'b::ab_group_add"
  154.18 -  assumes add: "f (x + y) = f x + f y"
  154.19 -begin
  154.20 -
  154.21 -lemma zero: "f 0 = 0"
  154.22 -proof -
  154.23 -  have "f 0 = f (0 + 0)" by simp
  154.24 -  also have "\<dots> = f 0 + f 0" by (rule add)
  154.25 -  finally show "f 0 = 0" by simp
  154.26 -qed
  154.27 -
  154.28 -lemma minus: "f (- x) = - f x"
  154.29 -proof -
  154.30 -  have "f (- x) + f x = f (- x + x)" by (rule add [symmetric])
  154.31 -  also have "\<dots> = - f x + f x" by (simp add: zero)
  154.32 -  finally show "f (- x) = - f x" by (rule add_right_imp_eq)
  154.33 -qed
  154.34 -
  154.35 -lemma diff: "f (x - y) = f x - f y"
  154.36 -by (simp add: diff_def add minus)
  154.37 -
  154.38 -lemma setsum: "f (setsum g A) = (\<Sum>x\<in>A. f (g x))"
  154.39 -apply (cases "finite A")
  154.40 -apply (induct set: finite)
  154.41 -apply (simp add: zero)
  154.42 -apply (simp add: add)
  154.43 -apply (simp add: zero)
  154.44 -done
  154.45 -
  154.46 -end
  154.47 -
  154.48 -subsection {* Vector spaces *}
  154.49 -
  154.50 -locale vector_space =
  154.51 -  fixes scale :: "'a::field \<Rightarrow> 'b::ab_group_add \<Rightarrow> 'b"
  154.52 -  assumes scale_right_distrib: "scale a (x + y) = scale a x + scale a y"
  154.53 -  and scale_left_distrib: "scale (a + b) x = scale a x + scale b x"
  154.54 -  and scale_scale [simp]: "scale a (scale b x) = scale (a * b) x"
  154.55 -  and scale_one [simp]: "scale 1 x = x"
  154.56 -begin
  154.57 -
  154.58 -lemma scale_left_commute:
  154.59 -  "scale a (scale b x) = scale b (scale a x)"
  154.60 -by (simp add: mult_commute)
  154.61 -
  154.62 -lemma scale_zero_left [simp]: "scale 0 x = 0"
  154.63 -  and scale_minus_left [simp]: "scale (- a) x = - (scale a x)"
  154.64 -  and scale_left_diff_distrib: "scale (a - b) x = scale a x - scale b x"
  154.65 -proof -
  154.66 -  interpret s: additive "\<lambda>a. scale a x"
  154.67 -    proof qed (rule scale_left_distrib)
  154.68 -  show "scale 0 x = 0" by (rule s.zero)
  154.69 -  show "scale (- a) x = - (scale a x)" by (rule s.minus)
  154.70 -  show "scale (a - b) x = scale a x - scale b x" by (rule s.diff)
  154.71 -qed
  154.72 -
  154.73 -lemma scale_zero_right [simp]: "scale a 0 = 0"
  154.74 -  and scale_minus_right [simp]: "scale a (- x) = - (scale a x)"
  154.75 -  and scale_right_diff_distrib: "scale a (x - y) = scale a x - scale a y"
  154.76 -proof -
  154.77 -  interpret s: additive "\<lambda>x. scale a x"
  154.78 -    proof qed (rule scale_right_distrib)
  154.79 -  show "scale a 0 = 0" by (rule s.zero)
  154.80 -  show "scale a (- x) = - (scale a x)" by (rule s.minus)
  154.81 -  show "scale a (x - y) = scale a x - scale a y" by (rule s.diff)
  154.82 -qed
  154.83 -
  154.84 -lemma scale_eq_0_iff [simp]:
  154.85 -  "scale a x = 0 \<longleftrightarrow> a = 0 \<or> x = 0"
  154.86 -proof cases
  154.87 -  assume "a = 0" thus ?thesis by simp
  154.88 -next
  154.89 -  assume anz [simp]: "a \<noteq> 0"
  154.90 -  { assume "scale a x = 0"
  154.91 -    hence "scale (inverse a) (scale a x) = 0" by simp
  154.92 -    hence "x = 0" by simp }
  154.93 -  thus ?thesis by force
  154.94 -qed
  154.95 -
  154.96 -lemma scale_left_imp_eq:
  154.97 -  "\<lbrakk>a \<noteq> 0; scale a x = scale a y\<rbrakk> \<Longrightarrow> x = y"
  154.98 -proof -
  154.99 -  assume nonzero: "a \<noteq> 0"
 154.100 -  assume "scale a x = scale a y"
 154.101 -  hence "scale a (x - y) = 0"
 154.102 -     by (simp add: scale_right_diff_distrib)
 154.103 -  hence "x - y = 0" by (simp add: nonzero)
 154.104 -  thus "x = y" by (simp only: right_minus_eq)
 154.105 -qed
 154.106 -
 154.107 -lemma scale_right_imp_eq:
 154.108 -  "\<lbrakk>x \<noteq> 0; scale a x = scale b x\<rbrakk> \<Longrightarrow> a = b"
 154.109 -proof -
 154.110 -  assume nonzero: "x \<noteq> 0"
 154.111 -  assume "scale a x = scale b x"
 154.112 -  hence "scale (a - b) x = 0"
 154.113 -     by (simp add: scale_left_diff_distrib)
 154.114 -  hence "a - b = 0" by (simp add: nonzero)
 154.115 -  thus "a = b" by (simp only: right_minus_eq)
 154.116 -qed
 154.117 -
 154.118 -lemma scale_cancel_left:
 154.119 -  "scale a x = scale a y \<longleftrightarrow> x = y \<or> a = 0"
 154.120 -by (auto intro: scale_left_imp_eq)
 154.121 -
 154.122 -lemma scale_cancel_right:
 154.123 -  "scale a x = scale b x \<longleftrightarrow> a = b \<or> x = 0"
 154.124 -by (auto intro: scale_right_imp_eq)
 154.125 -
 154.126 -end
 154.127 -
 154.128 -subsection {* Real vector spaces *}
 154.129 -
 154.130 -class scaleR = type +
 154.131 -  fixes scaleR :: "real \<Rightarrow> 'a \<Rightarrow> 'a" (infixr "*\<^sub>R" 75)
 154.132 -begin
 154.133 -
 154.134 -abbreviation
 154.135 -  divideR :: "'a \<Rightarrow> real \<Rightarrow> 'a" (infixl "'/\<^sub>R" 70)
 154.136 -where
 154.137 -  "x /\<^sub>R r == scaleR (inverse r) x"
 154.138 -
 154.139 -end
 154.140 -
 154.141 -instantiation real :: scaleR
 154.142 -begin
 154.143 -
 154.144 -definition
 154.145 -  real_scaleR_def [simp]: "scaleR a x = a * x"
 154.146 -
 154.147 -instance ..
 154.148 -
 154.149 -end
 154.150 -
 154.151 -class real_vector = scaleR + ab_group_add +
 154.152 -  assumes scaleR_right_distrib: "scaleR a (x + y) = scaleR a x + scaleR a y"
 154.153 -  and scaleR_left_distrib: "scaleR (a + b) x = scaleR a x + scaleR b x"
 154.154 -  and scaleR_scaleR [simp]: "scaleR a (scaleR b x) = scaleR (a * b) x"
 154.155 -  and scaleR_one [simp]: "scaleR 1 x = x"
 154.156 -
 154.157 -interpretation real_vector!:
 154.158 -  vector_space "scaleR :: real \<Rightarrow> 'a \<Rightarrow> 'a::real_vector"
 154.159 -apply unfold_locales
 154.160 -apply (rule scaleR_right_distrib)
 154.161 -apply (rule scaleR_left_distrib)
 154.162 -apply (rule scaleR_scaleR)
 154.163 -apply (rule scaleR_one)
 154.164 -done
 154.165 -
 154.166 -text {* Recover original theorem names *}
 154.167 -
 154.168 -lemmas scaleR_left_commute = real_vector.scale_left_commute
 154.169 -lemmas scaleR_zero_left = real_vector.scale_zero_left
 154.170 -lemmas scaleR_minus_left = real_vector.scale_minus_left
 154.171 -lemmas scaleR_left_diff_distrib = real_vector.scale_left_diff_distrib
 154.172 -lemmas scaleR_zero_right = real_vector.scale_zero_right
 154.173 -lemmas scaleR_minus_right = real_vector.scale_minus_right
 154.174 -lemmas scaleR_right_diff_distrib = real_vector.scale_right_diff_distrib
 154.175 -lemmas scaleR_eq_0_iff = real_vector.scale_eq_0_iff
 154.176 -lemmas scaleR_left_imp_eq = real_vector.scale_left_imp_eq
 154.177 -lemmas scaleR_right_imp_eq = real_vector.scale_right_imp_eq
 154.178 -lemmas scaleR_cancel_left = real_vector.scale_cancel_left
 154.179 -lemmas scaleR_cancel_right = real_vector.scale_cancel_right
 154.180 -
 154.181 -class real_algebra = real_vector + ring +
 154.182 -  assumes mult_scaleR_left [simp]: "scaleR a x * y = scaleR a (x * y)"
 154.183 -  and mult_scaleR_right [simp]: "x * scaleR a y = scaleR a (x * y)"
 154.184 -
 154.185 -class real_algebra_1 = real_algebra + ring_1
 154.186 -
 154.187 -class real_div_algebra = real_algebra_1 + division_ring
 154.188 -
 154.189 -class real_field = real_div_algebra + field
 154.190 -
 154.191 -instance real :: real_field
 154.192 -apply (intro_classes, unfold real_scaleR_def)
 154.193 -apply (rule right_distrib)
 154.194 -apply (rule left_distrib)
 154.195 -apply (rule mult_assoc [symmetric])
 154.196 -apply (rule mult_1_left)
 154.197 -apply (rule mult_assoc)
 154.198 -apply (rule mult_left_commute)
 154.199 -done
 154.200 -
 154.201 -interpretation scaleR_left!: additive "(\<lambda>a. scaleR a x::'a::real_vector)"
 154.202 -proof qed (rule scaleR_left_distrib)
 154.203 -
 154.204 -interpretation scaleR_right!: additive "(\<lambda>x. scaleR a x::'a::real_vector)"
 154.205 -proof qed (rule scaleR_right_distrib)
 154.206 -
 154.207 -lemma nonzero_inverse_scaleR_distrib:
 154.208 -  fixes x :: "'a::real_div_algebra" shows
 154.209 -  "\<lbrakk>a \<noteq> 0; x \<noteq> 0\<rbrakk> \<Longrightarrow> inverse (scaleR a x) = scaleR (inverse a) (inverse x)"
 154.210 -by (rule inverse_unique, simp)
 154.211 -
 154.212 -lemma inverse_scaleR_distrib:
 154.213 -  fixes x :: "'a::{real_div_algebra,division_by_zero}"
 154.214 -  shows "inverse (scaleR a x) = scaleR (inverse a) (inverse x)"
 154.215 -apply (case_tac "a = 0", simp)
 154.216 -apply (case_tac "x = 0", simp)
 154.217 -apply (erule (1) nonzero_inverse_scaleR_distrib)
 154.218 -done
 154.219 -
 154.220 -
 154.221 -subsection {* Embedding of the Reals into any @{text real_algebra_1}:
 154.222 -@{term of_real} *}
 154.223 -
 154.224 -definition
 154.225 -  of_real :: "real \<Rightarrow> 'a::real_algebra_1" where
 154.226 -  "of_real r = scaleR r 1"
 154.227 -
 154.228 -lemma scaleR_conv_of_real: "scaleR r x = of_real r * x"
 154.229 -by (simp add: of_real_def)
 154.230 -
 154.231 -lemma of_real_0 [simp]: "of_real 0 = 0"
 154.232 -by (simp add: of_real_def)
 154.233 -
 154.234 -lemma of_real_1 [simp]: "of_real 1 = 1"
 154.235 -by (simp add: of_real_def)
 154.236 -
 154.237 -lemma of_real_add [simp]: "of_real (x + y) = of_real x + of_real y"
 154.238 -by (simp add: of_real_def scaleR_left_distrib)
 154.239 -
 154.240 -lemma of_real_minus [simp]: "of_real (- x) = - of_real x"
 154.241 -by (simp add: of_real_def)
 154.242 -
 154.243 -lemma of_real_diff [simp]: "of_real (x - y) = of_real x - of_real y"
 154.244 -by (simp add: of_real_def scaleR_left_diff_distrib)
 154.245 -
 154.246 -lemma of_real_mult [simp]: "of_real (x * y) = of_real x * of_real y"
 154.247 -by (simp add: of_real_def mult_commute)
 154.248 -
 154.249 -lemma nonzero_of_real_inverse:
 154.250 -  "x \<noteq> 0 \<Longrightarrow> of_real (inverse x) =
 154.251 -   inverse (of_real x :: 'a::real_div_algebra)"
 154.252 -by (simp add: of_real_def nonzero_inverse_scaleR_distrib)
 154.253 -
 154.254 -lemma of_real_inverse [simp]:
 154.255 -  "of_real (inverse x) =
 154.256 -   inverse (of_real x :: 'a::{real_div_algebra,division_by_zero})"
 154.257 -by (simp add: of_real_def inverse_scaleR_distrib)
 154.258 -
 154.259 -lemma nonzero_of_real_divide:
 154.260 -  "y \<noteq> 0 \<Longrightarrow> of_real (x / y) =
 154.261 -   (of_real x / of_real y :: 'a::real_field)"
 154.262 -by (simp add: divide_inverse nonzero_of_real_inverse)
 154.263 -
 154.264 -lemma of_real_divide [simp]:
 154.265 -  "of_real (x / y) =
 154.266 -   (of_real x / of_real y :: 'a::{real_field,division_by_zero})"
 154.267 -by (simp add: divide_inverse)
 154.268 -
 154.269 -lemma of_real_power [simp]:
 154.270 -  "of_real (x ^ n) = (of_real x :: 'a::{real_algebra_1,recpower}) ^ n"
 154.271 -by (induct n) (simp_all add: power_Suc)
 154.272 -
 154.273 -lemma of_real_eq_iff [simp]: "(of_real x = of_real y) = (x = y)"
 154.274 -by (simp add: of_real_def scaleR_cancel_right)
 154.275 -
 154.276 -lemmas of_real_eq_0_iff [simp] = of_real_eq_iff [of _ 0, simplified]
 154.277 -
 154.278 -lemma of_real_eq_id [simp]: "of_real = (id :: real \<Rightarrow> real)"
 154.279 -proof
 154.280 -  fix r
 154.281 -  show "of_real r = id r"
 154.282 -    by (simp add: of_real_def)
 154.283 -qed
 154.284 -
 154.285 -text{*Collapse nested embeddings*}
 154.286 -lemma of_real_of_nat_eq [simp]: "of_real (of_nat n) = of_nat n"
 154.287 -by (induct n) auto
 154.288 -
 154.289 -lemma of_real_of_int_eq [simp]: "of_real (of_int z) = of_int z"
 154.290 -by (cases z rule: int_diff_cases, simp)
 154.291 -
 154.292 -lemma of_real_number_of_eq:
 154.293 -  "of_real (number_of w) = (number_of w :: 'a::{number_ring,real_algebra_1})"
 154.294 -by (simp add: number_of_eq)
 154.295 -
 154.296 -text{*Every real algebra has characteristic zero*}
 154.297 -instance real_algebra_1 < ring_char_0
 154.298 -proof
 154.299 -  fix m n :: nat
 154.300 -  have "(of_real (of_nat m) = (of_real (of_nat n)::'a)) = (m = n)"
 154.301 -    by (simp only: of_real_eq_iff of_nat_eq_iff)
 154.302 -  thus "(of_nat m = (of_nat n::'a)) = (m = n)"
 154.303 -    by (simp only: of_real_of_nat_eq)
 154.304 -qed
 154.305 -
 154.306 -instance real_field < field_char_0 ..
 154.307 -
 154.308 -
 154.309 -subsection {* The Set of Real Numbers *}
 154.310 -
 154.311 -definition
 154.312 -  Reals :: "'a::real_algebra_1 set" where
 154.313 -  [code del]: "Reals \<equiv> range of_real"
 154.314 -
 154.315 -notation (xsymbols)
 154.316 -  Reals  ("\<real>")
 154.317 -
 154.318 -lemma Reals_of_real [simp]: "of_real r \<in> Reals"
 154.319 -by (simp add: Reals_def)
 154.320 -
 154.321 -lemma Reals_of_int [simp]: "of_int z \<in> Reals"
 154.322 -by (subst of_real_of_int_eq [symmetric], rule Reals_of_real)
 154.323 -
 154.324 -lemma Reals_of_nat [simp]: "of_nat n \<in> Reals"
 154.325 -by (subst of_real_of_nat_eq [symmetric], rule Reals_of_real)
 154.326 -
 154.327 -lemma Reals_number_of [simp]:
 154.328 -  "(number_of w::'a::{number_ring,real_algebra_1}) \<in> Reals"
 154.329 -by (subst of_real_number_of_eq [symmetric], rule Reals_of_real)
 154.330 -
 154.331 -lemma Reals_0 [simp]: "0 \<in> Reals"
 154.332 -apply (unfold Reals_def)
 154.333 -apply (rule range_eqI)
 154.334 -apply (rule of_real_0 [symmetric])
 154.335 -done
 154.336 -
 154.337 -lemma Reals_1 [simp]: "1 \<in> Reals"
 154.338 -apply (unfold Reals_def)
 154.339 -apply (rule range_eqI)
 154.340 -apply (rule of_real_1 [symmetric])
 154.341 -done
 154.342 -
 154.343 -lemma Reals_add [simp]: "\<lbrakk>a \<in> Reals; b \<in> Reals\<rbrakk> \<Longrightarrow> a + b \<in> Reals"
 154.344 -apply (auto simp add: Reals_def)
 154.345 -apply (rule range_eqI)
 154.346 -apply (rule of_real_add [symmetric])
 154.347 -done
 154.348 -
 154.349 -lemma Reals_minus [simp]: "a \<in> Reals \<Longrightarrow> - a \<in> Reals"
 154.350 -apply (auto simp add: Reals_def)
 154.351 -apply (rule range_eqI)
 154.352 -apply (rule of_real_minus [symmetric])
 154.353 -done
 154.354 -
 154.355 -lemma Reals_diff [simp]: "\<lbrakk>a \<in> Reals; b \<in> Reals\<rbrakk> \<Longrightarrow> a - b \<in> Reals"
 154.356 -apply (auto simp add: Reals_def)
 154.357 -apply (rule range_eqI)
 154.358 -apply (rule of_real_diff [symmetric])
 154.359 -done
 154.360 -
 154.361 -lemma Reals_mult [simp]: "\<lbrakk>a \<in> Reals; b \<in> Reals\<rbrakk> \<Longrightarrow> a * b \<in> Reals"
 154.362 -apply (auto simp add: Reals_def)
 154.363 -apply (rule range_eqI)
 154.364 -apply (rule of_real_mult [symmetric])
 154.365 -done
 154.366 -
 154.367 -lemma nonzero_Reals_inverse:
 154.368 -  fixes a :: "'a::real_div_algebra"
 154.369 -  shows "\<lbrakk>a \<in> Reals; a \<noteq> 0\<rbrakk> \<Longrightarrow> inverse a \<in> Reals"
 154.370 -apply (auto simp add: Reals_def)
 154.371 -apply (rule range_eqI)
 154.372 -apply (erule nonzero_of_real_inverse [symmetric])
 154.373 -done
 154.374 -
 154.375 -lemma Reals_inverse [simp]:
 154.376 -  fixes a :: "'a::{real_div_algebra,division_by_zero}"
 154.377 -  shows "a \<in> Reals \<Longrightarrow> inverse a \<in> Reals"
 154.378 -apply (auto simp add: Reals_def)
 154.379 -apply (rule range_eqI)
 154.380 -apply (rule of_real_inverse [symmetric])
 154.381 -done
 154.382 -
 154.383 -lemma nonzero_Reals_divide:
 154.384 -  fixes a b :: "'a::real_field"
 154.385 -  shows "\<lbrakk>a \<in> Reals; b \<in> Reals; b \<noteq> 0\<rbrakk> \<Longrightarrow> a / b \<in> Reals"
 154.386 -apply (auto simp add: Reals_def)
 154.387 -apply (rule range_eqI)
 154.388 -apply (erule nonzero_of_real_divide [symmetric])
 154.389 -done
 154.390 -
 154.391 -lemma Reals_divide [simp]:
 154.392 -  fixes a b :: "'a::{real_field,division_by_zero}"
 154.393 -  shows "\<lbrakk>a \<in> Reals; b \<in> Reals\<rbrakk> \<Longrightarrow> a / b \<in> Reals"
 154.394 -apply (auto simp add: Reals_def)
 154.395 -apply (rule range_eqI)
 154.396 -apply (rule of_real_divide [symmetric])
 154.397 -done
 154.398 -
 154.399 -lemma Reals_power [simp]:
 154.400 -  fixes a :: "'a::{real_algebra_1,recpower}"
 154.401 -  shows "a \<in> Reals \<Longrightarrow> a ^ n \<in> Reals"
 154.402 -apply (auto simp add: Reals_def)
 154.403 -apply (rule range_eqI)
 154.404 -apply (rule of_real_power [symmetric])
 154.405 -done
 154.406 -
 154.407 -lemma Reals_cases [cases set: Reals]:
 154.408 -  assumes "q \<in> \<real>"
 154.409 -  obtains (of_real) r where "q = of_real r"
 154.410 -  unfolding Reals_def
 154.411 -proof -
 154.412 -  from `q \<in> \<real>` have "q \<in> range of_real" unfolding Reals_def .
 154.413 -  then obtain r where "q = of_real r" ..
 154.414 -  then show thesis ..
 154.415 -qed
 154.416 -
 154.417 -lemma Reals_induct [case_names of_real, induct set: Reals]:
 154.418 -  "q \<in> \<real> \<Longrightarrow> (\<And>r. P (of_real r)) \<Longrightarrow> P q"
 154.419 -  by (rule Reals_cases) auto
 154.420 -
 154.421 -
 154.422 -subsection {* Real normed vector spaces *}
 154.423 -
 154.424 -class norm = type +
 154.425 -  fixes norm :: "'a \<Rightarrow> real"
 154.426 -
 154.427 -instantiation real :: norm
 154.428 -begin
 154.429 -
 154.430 -definition
 154.431 -  real_norm_def [simp]: "norm r \<equiv> \<bar>r\<bar>"
 154.432 -
 154.433 -instance ..
 154.434 -
 154.435 -end
 154.436 -
 154.437 -class sgn_div_norm = scaleR + norm + sgn +
 154.438 -  assumes sgn_div_norm: "sgn x = x /\<^sub>R norm x"
 154.439 -
 154.440 -class real_normed_vector = real_vector + sgn_div_norm +
 154.441 -  assumes norm_ge_zero [simp]: "0 \<le> norm x"
 154.442 -  and norm_eq_zero [simp]: "norm x = 0 \<longleftrightarrow> x = 0"
 154.443 -  and norm_triangle_ineq: "norm (x + y) \<le> norm x + norm y"
 154.444 -  and norm_scaleR: "norm (scaleR a x) = \<bar>a\<bar> * norm x"
 154.445 -
 154.446 -class real_normed_algebra = real_algebra + real_normed_vector +
 154.447 -  assumes norm_mult_ineq: "norm (x * y) \<le> norm x * norm y"
 154.448 -
 154.449 -class real_normed_algebra_1 = real_algebra_1 + real_normed_algebra +
 154.450 -  assumes norm_one [simp]: "norm 1 = 1"
 154.451 -
 154.452 -class real_normed_div_algebra = real_div_algebra + real_normed_vector +
 154.453 -  assumes norm_mult: "norm (x * y) = norm x * norm y"
 154.454 -
 154.455 -class real_normed_field = real_field + real_normed_div_algebra
 154.456 -
 154.457 -instance real_normed_div_algebra < real_normed_algebra_1
 154.458 -proof
 154.459 -  fix x y :: 'a
 154.460 -  show "norm (x * y) \<le> norm x * norm y"
 154.461 -    by (simp add: norm_mult)
 154.462 -next
 154.463 -  have "norm (1 * 1::'a) = norm (1::'a) * norm (1::'a)"
 154.464 -    by (rule norm_mult)
 154.465 -  thus "norm (1::'a) = 1" by simp
 154.466 -qed
 154.467 -
 154.468 -instance real :: real_normed_field
 154.469 -apply (intro_classes, unfold real_norm_def real_scaleR_def)
 154.470 -apply (simp add: real_sgn_def)
 154.471 -apply (rule abs_ge_zero)
 154.472 -apply (rule abs_eq_0)
 154.473 -apply (rule abs_triangle_ineq)
 154.474 -apply (rule abs_mult)
 154.475 -apply (rule abs_mult)
 154.476 -done
 154.477 -
 154.478 -lemma norm_zero [simp]: "norm (0::'a::real_normed_vector) = 0"
 154.479 -by simp
 154.480 -
 154.481 -lemma zero_less_norm_iff [simp]:
 154.482 -  fixes x :: "'a::real_normed_vector"
 154.483 -  shows "(0 < norm x) = (x \<noteq> 0)"
 154.484 -by (simp add: order_less_le)
 154.485 -
 154.486 -lemma norm_not_less_zero [simp]:
 154.487 -  fixes x :: "'a::real_normed_vector"
 154.488 -  shows "\<not> norm x < 0"
 154.489 -by (simp add: linorder_not_less)
 154.490 -
 154.491 -lemma norm_le_zero_iff [simp]:
 154.492 -  fixes x :: "'a::real_normed_vector"
 154.493 -  shows "(norm x \<le> 0) = (x = 0)"
 154.494 -by (simp add: order_le_less)
 154.495 -
 154.496 -lemma norm_minus_cancel [simp]:
 154.497 -  fixes x :: "'a::real_normed_vector"
 154.498 -  shows "norm (- x) = norm x"
 154.499 -proof -
 154.500 -  have "norm (- x) = norm (scaleR (- 1) x)"
 154.501 -    by (simp only: scaleR_minus_left scaleR_one)
 154.502 -  also have "\<dots> = \<bar>- 1\<bar> * norm x"
 154.503 -    by (rule norm_scaleR)
 154.504 -  finally show ?thesis by simp
 154.505 -qed
 154.506 -
 154.507 -lemma norm_minus_commute:
 154.508 -  fixes a b :: "'a::real_normed_vector"
 154.509 -  shows "norm (a - b) = norm (b - a)"
 154.510 -proof -
 154.511 -  have "norm (- (b - a)) = norm (b - a)"
 154.512 -    by (rule norm_minus_cancel)
 154.513 -  thus ?thesis by simp
 154.514 -qed
 154.515 -
 154.516 -lemma norm_triangle_ineq2:
 154.517 -  fixes a b :: "'a::real_normed_vector"
 154.518 -  shows "norm a - norm b \<le> norm (a - b)"
 154.519 -proof -
 154.520 -  have "norm (a - b + b) \<le> norm (a - b) + norm b"
 154.521 -    by (rule norm_triangle_ineq)
 154.522 -  thus ?thesis by simp
 154.523 -qed
 154.524 -
 154.525 -lemma norm_triangle_ineq3:
 154.526 -  fixes a b :: "'a::real_normed_vector"
 154.527 -  shows "\<bar>norm a - norm b\<bar> \<le> norm (a - b)"
 154.528 -apply (subst abs_le_iff)
 154.529 -apply auto
 154.530 -apply (rule norm_triangle_ineq2)
 154.531 -apply (subst norm_minus_commute)
 154.532 -apply (rule norm_triangle_ineq2)
 154.533 -done
 154.534 -
 154.535 -lemma norm_triangle_ineq4:
 154.536 -  fixes a b :: "'a::real_normed_vector"
 154.537 -  shows "norm (a - b) \<le> norm a + norm b"
 154.538 -proof -
 154.539 -  have "norm (a + - b) \<le> norm a + norm (- b)"
 154.540 -    by (rule norm_triangle_ineq)
 154.541 -  thus ?thesis
 154.542 -    by (simp only: diff_minus norm_minus_cancel)
 154.543 -qed
 154.544 -
 154.545 -lemma norm_diff_ineq:
 154.546 -  fixes a b :: "'a::real_normed_vector"
 154.547 -  shows "norm a - norm b \<le> norm (a + b)"
 154.548 -proof -
 154.549 -  have "norm a - norm (- b) \<le> norm (a - - b)"
 154.550 -    by (rule norm_triangle_ineq2)
 154.551 -  thus ?thesis by simp
 154.552 -qed
 154.553 -
 154.554 -lemma norm_diff_triangle_ineq:
 154.555 -  fixes a b c d :: "'a::real_normed_vector"
 154.556 -  shows "norm ((a + b) - (c + d)) \<le> norm (a - c) + norm (b - d)"
 154.557 -proof -
 154.558 -  have "norm ((a + b) - (c + d)) = norm ((a - c) + (b - d))"
 154.559 -    by (simp add: diff_minus add_ac)
 154.560 -  also have "\<dots> \<le> norm (a - c) + norm (b - d)"
 154.561 -    by (rule norm_triangle_ineq)
 154.562 -  finally show ?thesis .
 154.563 -qed
 154.564 -
 154.565 -lemma abs_norm_cancel [simp]:
 154.566 -  fixes a :: "'a::real_normed_vector"
 154.567 -  shows "\<bar>norm a\<bar> = norm a"
 154.568 -by (rule abs_of_nonneg [OF norm_ge_zero])
 154.569 -
 154.570 -lemma norm_add_less:
 154.571 -  fixes x y :: "'a::real_normed_vector"
 154.572 -  shows "\<lbrakk>norm x < r; norm y < s\<rbrakk> \<Longrightarrow> norm (x + y) < r + s"
 154.573 -by (rule order_le_less_trans [OF norm_triangle_ineq add_strict_mono])
 154.574 -
 154.575 -lemma norm_mult_less:
 154.576 -  fixes x y :: "'a::real_normed_algebra"
 154.577 -  shows "\<lbrakk>norm x < r; norm y < s\<rbrakk> \<Longrightarrow> norm (x * y) < r * s"
 154.578 -apply (rule order_le_less_trans [OF norm_mult_ineq])
 154.579 -apply (simp add: mult_strict_mono')
 154.580 -done
 154.581 -
 154.582 -lemma norm_of_real [simp]:
 154.583 -  "norm (of_real r :: 'a::real_normed_algebra_1) = \<bar>r\<bar>"
 154.584 -unfolding of_real_def by (simp add: norm_scaleR)
 154.585 -
 154.586 -lemma norm_number_of [simp]:
 154.587 -  "norm (number_of w::'a::{number_ring,real_normed_algebra_1})
 154.588 -    = \<bar>number_of w\<bar>"
 154.589 -by (subst of_real_number_of_eq [symmetric], rule norm_of_real)
 154.590 -
 154.591 -lemma norm_of_int [simp]:
 154.592 -  "norm (of_int z::'a::real_normed_algebra_1) = \<bar>of_int z\<bar>"
 154.593 -by (subst of_real_of_int_eq [symmetric], rule norm_of_real)
 154.594 -
 154.595 -lemma norm_of_nat [simp]:
 154.596 -  "norm (of_nat n::'a::real_normed_algebra_1) = of_nat n"
 154.597 -apply (subst of_real_of_nat_eq [symmetric])
 154.598 -apply (subst norm_of_real, simp)
 154.599 -done
 154.600 -
 154.601 -lemma nonzero_norm_inverse:
 154.602 -  fixes a :: "'a::real_normed_div_algebra"
 154.603 -  shows "a \<noteq> 0 \<Longrightarrow> norm (inverse a) = inverse (norm a)"
 154.604 -apply (rule inverse_unique [symmetric])
 154.605 -apply (simp add: norm_mult [symmetric])
 154.606 -done
 154.607 -
 154.608 -lemma norm_inverse:
 154.609 -  fixes a :: "'a::{real_normed_div_algebra,division_by_zero}"
 154.610 -  shows "norm (inverse a) = inverse (norm a)"
 154.611 -apply (case_tac "a = 0", simp)
 154.612 -apply (erule nonzero_norm_inverse)
 154.613 -done
 154.614 -
 154.615 -lemma nonzero_norm_divide:
 154.616 -  fixes a b :: "'a::real_normed_field"
 154.617 -  shows "b \<noteq> 0 \<Longrightarrow> norm (a / b) = norm a / norm b"
 154.618 -by (simp add: divide_inverse norm_mult nonzero_norm_inverse)
 154.619 -
 154.620 -lemma norm_divide:
 154.621 -  fixes a b :: "'a::{real_normed_field,division_by_zero}"
 154.622 -  shows "norm (a / b) = norm a / norm b"
 154.623 -by (simp add: divide_inverse norm_mult norm_inverse)
 154.624 -
 154.625 -lemma norm_power_ineq:
 154.626 -  fixes x :: "'a::{real_normed_algebra_1,recpower}"
 154.627 -  shows "norm (x ^ n) \<le> norm x ^ n"
 154.628 -proof (induct n)
 154.629 -  case 0 show "norm (x ^ 0) \<le> norm x ^ 0" by simp
 154.630 -next
 154.631 -  case (Suc n)
 154.632 -  have "norm (x * x ^ n) \<le> norm x * norm (x ^ n)"
 154.633 -    by (rule norm_mult_ineq)
 154.634 -  also from Suc have "\<dots> \<le> norm x * norm x ^ n"
 154.635 -    using norm_ge_zero by (rule mult_left_mono)
 154.636 -  finally show "norm (x ^ Suc n) \<le> norm x ^ Suc n"
 154.637 -    by (simp add: power_Suc)
 154.638 -qed
 154.639 -
 154.640 -lemma norm_power:
 154.641 -  fixes x :: "'a::{real_normed_div_algebra,recpower}"
 154.642 -  shows "norm (x ^ n) = norm x ^ n"
 154.643 -by (induct n) (simp_all add: power_Suc norm_mult)
 154.644 -
 154.645 -
 154.646 -subsection {* Sign function *}
 154.647 -
 154.648 -lemma norm_sgn:
 154.649 -  "norm (sgn(x::'a::real_normed_vector)) = (if x = 0 then 0 else 1)"
 154.650 -by (simp add: sgn_div_norm norm_scaleR)
 154.651 -
 154.652 -lemma sgn_zero [simp]: "sgn(0::'a::real_normed_vector) = 0"
 154.653 -by (simp add: sgn_div_norm)
 154.654 -
 154.655 -lemma sgn_zero_iff: "(sgn(x::'a::real_normed_vector) = 0) = (x = 0)"
 154.656 -by (simp add: sgn_div_norm)
 154.657 -
 154.658 -lemma sgn_minus: "sgn (- x) = - sgn(x::'a::real_normed_vector)"
 154.659 -by (simp add: sgn_div_norm)
 154.660 -
 154.661 -lemma sgn_scaleR:
 154.662 -  "sgn (scaleR r x) = scaleR (sgn r) (sgn(x::'a::real_normed_vector))"
 154.663 -by (simp add: sgn_div_norm norm_scaleR mult_ac)
 154.664 -
 154.665 -lemma sgn_one [simp]: "sgn (1::'a::real_normed_algebra_1) = 1"
 154.666 -by (simp add: sgn_div_norm)
 154.667 -
 154.668 -lemma sgn_of_real:
 154.669 -  "sgn (of_real r::'a::real_normed_algebra_1) = of_real (sgn r)"
 154.670 -unfolding of_real_def by (simp only: sgn_scaleR sgn_one)
 154.671 -
 154.672 -lemma sgn_mult:
 154.673 -  fixes x y :: "'a::real_normed_div_algebra"
 154.674 -  shows "sgn (x * y) = sgn x * sgn y"
 154.675 -by (simp add: sgn_div_norm norm_mult mult_commute)
 154.676 -
 154.677 -lemma real_sgn_eq: "sgn (x::real) = x / \<bar>x\<bar>"
 154.678 -by (simp add: sgn_div_norm divide_inverse)
 154.679 -
 154.680 -lemma real_sgn_pos: "0 < (x::real) \<Longrightarrow> sgn x = 1"
 154.681 -unfolding real_sgn_eq by simp
 154.682 -
 154.683 -lemma real_sgn_neg: "(x::real) < 0 \<Longrightarrow> sgn x = -1"
 154.684 -unfolding real_sgn_eq by simp
 154.685 -
 154.686 -
 154.687 -subsection {* Bounded Linear and Bilinear Operators *}
 154.688 -
 154.689 -locale bounded_linear = additive +
 154.690 -  constrains f :: "'a::real_normed_vector \<Rightarrow> 'b::real_normed_vector"
 154.691 -  assumes scaleR: "f (scaleR r x) = scaleR r (f x)"
 154.692 -  assumes bounded: "\<exists>K. \<forall>x. norm (f x) \<le> norm x * K"
 154.693 -begin
 154.694 -
 154.695 -lemma pos_bounded:
 154.696 -  "\<exists>K>0. \<forall>x. norm (f x) \<le> norm x * K"
 154.697 -proof -
 154.698 -  obtain K where K: "\<And>x. norm (f x) \<le> norm x * K"
 154.699 -    using bounded by fast
 154.700 -  show ?thesis
 154.701 -  proof (intro exI impI conjI allI)
 154.702 -    show "0 < max 1 K"
 154.703 -      by (rule order_less_le_trans [OF zero_less_one le_maxI1])
 154.704 -  next
 154.705 -    fix x
 154.706 -    have "norm (f x) \<le> norm x * K" using K .
 154.707 -    also have "\<dots> \<le> norm x * max 1 K"
 154.708 -      by (rule mult_left_mono [OF le_maxI2 norm_ge_zero])
 154.709 -    finally show "norm (f x) \<le> norm x * max 1 K" .
 154.710 -  qed
 154.711 -qed
 154.712 -
 154.713 -lemma nonneg_bounded:
 154.714 -  "\<exists>K\<ge>0. \<forall>x. norm (f x) \<le> norm x * K"
 154.715 -proof -
 154.716 -  from pos_bounded
 154.717 -  show ?thesis by (auto intro: order_less_imp_le)
 154.718 -qed
 154.719 -
 154.720 -end
 154.721 -
 154.722 -locale bounded_bilinear =
 154.723 -  fixes prod :: "['a::real_normed_vector, 'b::real_normed_vector]
 154.724 -                 \<Rightarrow> 'c::real_normed_vector"
 154.725 -    (infixl "**" 70)
 154.726 -  assumes add_left: "prod (a + a') b = prod a b + prod a' b"
 154.727 -  assumes add_right: "prod a (b + b') = prod a b + prod a b'"
 154.728 -  assumes scaleR_left: "prod (scaleR r a) b = scaleR r (prod a b)"
 154.729 -  assumes scaleR_right: "prod a (scaleR r b) = scaleR r (prod a b)"
 154.730 -  assumes bounded: "\<exists>K. \<forall>a b. norm (prod a b) \<le> norm a * norm b * K"
 154.731 -begin
 154.732 -
 154.733 -lemma pos_bounded:
 154.734 -  "\<exists>K>0. \<forall>a b. norm (a ** b) \<le> norm a * norm b * K"
 154.735 -apply (cut_tac bounded, erule exE)
 154.736 -apply (rule_tac x="max 1 K" in exI, safe)
 154.737 -apply (rule order_less_le_trans [OF zero_less_one le_maxI1])
 154.738 -apply (drule spec, drule spec, erule order_trans)
 154.739 -apply (rule mult_left_mono [OF le_maxI2])
 154.740 -apply (intro mult_nonneg_nonneg norm_ge_zero)
 154.741 -done
 154.742 -
 154.743 -lemma nonneg_bounded:
 154.744 -  "\<exists>K\<ge>0. \<forall>a b. norm (a ** b) \<le> norm a * norm b * K"
 154.745 -proof -
 154.746 -  from pos_bounded
 154.747 -  show ?thesis by (auto intro: order_less_imp_le)
 154.748 -qed
 154.749 -
 154.750 -lemma additive_right: "additive (\<lambda>b. prod a b)"
 154.751 -by (rule additive.intro, rule add_right)
 154.752 -
 154.753 -lemma additive_left: "additive (\<lambda>a. prod a b)"
 154.754 -by (rule additive.intro, rule add_left)
 154.755 -
 154.756 -lemma zero_left: "prod 0 b = 0"
 154.757 -by (rule additive.zero [OF additive_left])
 154.758 -
 154.759 -lemma zero_right: "prod a 0 = 0"
 154.760 -by (rule additive.zero [OF additive_right])
 154.761 -
 154.762 -lemma minus_left: "prod (- a) b = - prod a b"
 154.763 -by (rule additive.minus [OF additive_left])
 154.764 -
 154.765 -lemma minus_right: "prod a (- b) = - prod a b"
 154.766 -by (rule additive.minus [OF additive_right])
 154.767 -
 154.768 -lemma diff_left:
 154.769 -  "prod (a - a') b = prod a b - prod a' b"
 154.770 -by (rule additive.diff [OF additive_left])
 154.771 -
 154.772 -lemma diff_right:
 154.773 -  "prod a (b - b') = prod a b - prod a b'"
 154.774 -by (rule additive.diff [OF additive_right])
 154.775 -
 154.776 -lemma bounded_linear_left:
 154.777 -  "bounded_linear (\<lambda>a. a ** b)"
 154.778 -apply (unfold_locales)
 154.779 -apply (rule add_left)
 154.780 -apply (rule scaleR_left)
 154.781 -apply (cut_tac bounded, safe)
 154.782 -apply (rule_tac x="norm b * K" in exI)
 154.783 -apply (simp add: mult_ac)
 154.784 -done
 154.785 -
 154.786 -lemma bounded_linear_right:
 154.787 -  "bounded_linear (\<lambda>b. a ** b)"
 154.788 -apply (unfold_locales)
 154.789 -apply (rule add_right)
 154.790 -apply (rule scaleR_right)
 154.791 -apply (cut_tac bounded, safe)
 154.792 -apply (rule_tac x="norm a * K" in exI)
 154.793 -apply (simp add: mult_ac)
 154.794 -done
 154.795 -
 154.796 -lemma prod_diff_prod:
 154.797 -  "(x ** y - a ** b) = (x - a) ** (y - b) + (x - a) ** b + a ** (y - b)"
 154.798 -by (simp add: diff_left diff_right)
 154.799 -
 154.800 -end
 154.801 -
 154.802 -interpretation mult!:
 154.803 -  bounded_bilinear "op * :: 'a \<Rightarrow> 'a \<Rightarrow> 'a::real_normed_algebra"
 154.804 -apply (rule bounded_bilinear.intro)
 154.805 -apply (rule left_distrib)
 154.806 -apply (rule right_distrib)
 154.807 -apply (rule mult_scaleR_left)
 154.808 -apply (rule mult_scaleR_right)
 154.809 -apply (rule_tac x="1" in exI)
 154.810 -apply (simp add: norm_mult_ineq)
 154.811 -done
 154.812 -
 154.813 -interpretation mult_left!:
 154.814 -  bounded_linear "(\<lambda>x::'a::real_normed_algebra. x * y)"
 154.815 -by (rule mult.bounded_linear_left)
 154.816 -
 154.817 -interpretation mult_right!:
 154.818 -  bounded_linear "(\<lambda>y::'a::real_normed_algebra. x * y)"
 154.819 -by (rule mult.bounded_linear_right)
 154.820 -
 154.821 -interpretation divide!:
 154.822 -  bounded_linear "(\<lambda>x::'a::real_normed_field. x / y)"
 154.823 -unfolding divide_inverse by (rule mult.bounded_linear_left)
 154.824 -
 154.825 -interpretation scaleR!: bounded_bilinear "scaleR"
 154.826 -apply (rule bounded_bilinear.intro)
 154.827 -apply (rule scaleR_left_distrib)
 154.828 -apply (rule scaleR_right_distrib)
 154.829 -apply simp
 154.830 -apply (rule scaleR_left_commute)
 154.831 -apply (rule_tac x="1" in exI)
 154.832 -apply (simp add: norm_scaleR)
 154.833 -done
 154.834 -
 154.835 -interpretation scaleR_left!: bounded_linear "\<lambda>r. scaleR r x"
 154.836 -by (rule scaleR.bounded_linear_left)
 154.837 -
 154.838 -interpretation scaleR_right!: bounded_linear "\<lambda>x. scaleR r x"
 154.839 -by (rule scaleR.bounded_linear_right)
 154.840 -
 154.841 -interpretation of_real!: bounded_linear "\<lambda>r. of_real r"
 154.842 -unfolding of_real_def by (rule scaleR.bounded_linear_left)
 154.843 -
 154.844 -end
   155.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   155.2 +++ b/src/HOL/RealVector.thy	Tue Dec 30 11:10:01 2008 +0100
   155.3 @@ -0,0 +1,841 @@
   155.4 +(*  Title:      HOL/RealVector.thy
   155.5 +    Author:     Brian Huffman
   155.6 +*)
   155.7 +
   155.8 +header {* Vector Spaces and Algebras over the Reals *}
   155.9 +
  155.10 +theory RealVector
  155.11 +imports RealPow
  155.12 +begin
  155.13 +
  155.14 +subsection {* Locale for additive functions *}
  155.15 +
  155.16 +locale additive =
  155.17 +  fixes f :: "'a::ab_group_add \<Rightarrow> 'b::ab_group_add"
  155.18 +  assumes add: "f (x + y) = f x + f y"
  155.19 +begin
  155.20 +
  155.21 +lemma zero: "f 0 = 0"
  155.22 +proof -
  155.23 +  have "f 0 = f (0 + 0)" by simp
  155.24 +  also have "\<dots> = f 0 + f 0" by (rule add)
  155.25 +  finally show "f 0 = 0" by simp
  155.26 +qed
  155.27 +
  155.28 +lemma minus: "f (- x) = - f x"
  155.29 +proof -
  155.30 +  have "f (- x) + f x = f (- x + x)" by (rule add [symmetric])
  155.31 +  also have "\<dots> = - f x + f x" by (simp add: zero)
  155.32 +  finally show "f (- x) = - f x" by (rule add_right_imp_eq)
  155.33 +qed
  155.34 +
  155.35 +lemma diff: "f (x - y) = f x - f y"
  155.36 +by (simp add: diff_def add minus)
  155.37 +
  155.38 +lemma setsum: "f (setsum g A) = (\<Sum>x\<in>A. f (g x))"
  155.39 +apply (cases "finite A")
  155.40 +apply (induct set: finite)
  155.41 +apply (simp add: zero)
  155.42 +apply (simp add: add)
  155.43 +apply (simp add: zero)
  155.44 +done
  155.45 +
  155.46 +end
  155.47 +
  155.48 +subsection {* Vector spaces *}
  155.49 +
  155.50 +locale vector_space =
  155.51 +  fixes scale :: "'a::field \<Rightarrow> 'b::ab_group_add \<Rightarrow> 'b"
  155.52 +  assumes scale_right_distrib: "scale a (x + y) = scale a x + scale a y"
  155.53 +  and scale_left_distrib: "scale (a + b) x = scale a x + scale b x"
  155.54 +  and scale_scale [simp]: "scale a (scale b x) = scale (a * b) x"
  155.55 +  and scale_one [simp]: "scale 1 x = x"
  155.56 +begin
  155.57 +
  155.58 +lemma scale_left_commute:
  155.59 +  "scale a (scale b x) = scale b (scale a x)"
  155.60 +by (simp add: mult_commute)
  155.61 +
  155.62 +lemma scale_zero_left [simp]: "scale 0 x = 0"
  155.63 +  and scale_minus_left [simp]: "scale (- a) x = - (scale a x)"
  155.64 +  and scale_left_diff_distrib: "scale (a - b) x = scale a x - scale b x"
  155.65 +proof -
  155.66 +  interpret s: additive "\<lambda>a. scale a x"
  155.67 +    proof qed (rule scale_left_distrib)
  155.68 +  show "scale 0 x = 0" by (rule s.zero)
  155.69 +  show "scale (- a) x = - (scale a x)" by (rule s.minus)
  155.70 +  show "scale (a - b) x = scale a x - scale b x" by (rule s.diff)
  155.71 +qed
  155.72 +
  155.73 +lemma scale_zero_right [simp]: "scale a 0 = 0"
  155.74 +  and scale_minus_right [simp]: "scale a (- x) = - (scale a x)"
  155.75 +  and scale_right_diff_distrib: "scale a (x - y) = scale a x - scale a y"
  155.76 +proof -
  155.77 +  interpret s: additive "\<lambda>x. scale a x"
  155.78 +    proof qed (rule scale_right_distrib)
  155.79 +  show "scale a 0 = 0" by (rule s.zero)
  155.80 +  show "scale a (- x) = - (scale a x)" by (rule s.minus)
  155.81 +  show "scale a (x - y) = scale a x - scale a y" by (rule s.diff)
  155.82 +qed
  155.83 +
  155.84 +lemma scale_eq_0_iff [simp]:
  155.85 +  "scale a x = 0 \<longleftrightarrow> a = 0 \<or> x = 0"
  155.86 +proof cases
  155.87 +  assume "a = 0" thus ?thesis by simp
  155.88 +next
  155.89 +  assume anz [simp]: "a \<noteq> 0"
  155.90 +  { assume "scale a x = 0"
  155.91 +    hence "scale (inverse a) (scale a x) = 0" by simp
  155.92 +    hence "x = 0" by simp }
  155.93 +  thus ?thesis by force
  155.94 +qed
  155.95 +
  155.96 +lemma scale_left_imp_eq:
  155.97 +  "\<lbrakk>a \<noteq> 0; scale a x = scale a y\<rbrakk> \<Longrightarrow> x = y"
  155.98 +proof -
  155.99 +  assume nonzero: "a \<noteq> 0"
 155.100 +  assume "scale a x = scale a y"
 155.101 +  hence "scale a (x - y) = 0"
 155.102 +     by (simp add: scale_right_diff_distrib)
 155.103 +  hence "x - y = 0" by (simp add: nonzero)
 155.104 +  thus "x = y" by (simp only: right_minus_eq)
 155.105 +qed
 155.106 +
 155.107 +lemma scale_right_imp_eq:
 155.108 +  "\<lbrakk>x \<noteq> 0; scale a x = scale b x\<rbrakk> \<Longrightarrow> a = b"
 155.109 +proof -
 155.110 +  assume nonzero: "x \<noteq> 0"
 155.111 +  assume "scale a x = scale b x"
 155.112 +  hence "scale (a - b) x = 0"
 155.113 +     by (simp add: scale_left_diff_distrib)
 155.114 +  hence "a - b = 0" by (simp add: nonzero)
 155.115 +  thus "a = b" by (simp only: right_minus_eq)
 155.116 +qed
 155.117 +
 155.118 +lemma scale_cancel_left:
 155.119 +  "scale a x = scale a y \<longleftrightarrow> x = y \<or> a = 0"
 155.120 +by (auto intro: scale_left_imp_eq)
 155.121 +
 155.122 +lemma scale_cancel_right:
 155.123 +  "scale a x = scale b x \<longleftrightarrow> a = b \<or> x = 0"
 155.124 +by (auto intro: scale_right_imp_eq)
 155.125 +
 155.126 +end
 155.127 +
 155.128 +subsection {* Real vector spaces *}
 155.129 +
 155.130 +class scaleR = type +
 155.131 +  fixes scaleR :: "real \<Rightarrow> 'a \<Rightarrow> 'a" (infixr "*\<^sub>R" 75)
 155.132 +begin
 155.133 +
 155.134 +abbreviation
 155.135 +  divideR :: "'a \<Rightarrow> real \<Rightarrow> 'a" (infixl "'/\<^sub>R" 70)
 155.136 +where
 155.137 +  "x /\<^sub>R r == scaleR (inverse r) x"
 155.138 +
 155.139 +end
 155.140 +
 155.141 +instantiation real :: scaleR
 155.142 +begin
 155.143 +
 155.144 +definition
 155.145 +  real_scaleR_def [simp]: "scaleR a x = a * x"
 155.146 +
 155.147 +instance ..
 155.148 +
 155.149 +end
 155.150 +
 155.151 +class real_vector = scaleR + ab_group_add +
 155.152 +  assumes scaleR_right_distrib: "scaleR a (x + y) = scaleR a x + scaleR a y"
 155.153 +  and scaleR_left_distrib: "scaleR (a + b) x = scaleR a x + scaleR b x"
 155.154 +  and scaleR_scaleR [simp]: "scaleR a (scaleR b x) = scaleR (a * b) x"
 155.155 +  and scaleR_one [simp]: "scaleR 1 x = x"
 155.156 +
 155.157 +interpretation real_vector!:
 155.158 +  vector_space "scaleR :: real \<Rightarrow> 'a \<Rightarrow> 'a::real_vector"
 155.159 +apply unfold_locales
 155.160 +apply (rule scaleR_right_distrib)
 155.161 +apply (rule scaleR_left_distrib)
 155.162 +apply (rule scaleR_scaleR)
 155.163 +apply (rule scaleR_one)
 155.164 +done
 155.165 +
 155.166 +text {* Recover original theorem names *}
 155.167 +
 155.168 +lemmas scaleR_left_commute = real_vector.scale_left_commute
 155.169 +lemmas scaleR_zero_left = real_vector.scale_zero_left
 155.170 +lemmas scaleR_minus_left = real_vector.scale_minus_left
 155.171 +lemmas scaleR_left_diff_distrib = real_vector.scale_left_diff_distrib
 155.172 +lemmas scaleR_zero_right = real_vector.scale_zero_right
 155.173 +lemmas scaleR_minus_right = real_vector.scale_minus_right
 155.174 +lemmas scaleR_right_diff_distrib = real_vector.scale_right_diff_distrib
 155.175 +lemmas scaleR_eq_0_iff = real_vector.scale_eq_0_iff
 155.176 +lemmas scaleR_left_imp_eq = real_vector.scale_left_imp_eq
 155.177 +lemmas scaleR_right_imp_eq = real_vector.scale_right_imp_eq
 155.178 +lemmas scaleR_cancel_left = real_vector.scale_cancel_left
 155.179 +lemmas scaleR_cancel_right = real_vector.scale_cancel_right
 155.180 +
 155.181 +class real_algebra = real_vector + ring +
 155.182 +  assumes mult_scaleR_left [simp]: "scaleR a x * y = scaleR a (x * y)"
 155.183 +  and mult_scaleR_right [simp]: "x * scaleR a y = scaleR a (x * y)"
 155.184 +
 155.185 +class real_algebra_1 = real_algebra + ring_1
 155.186 +
 155.187 +class real_div_algebra = real_algebra_1 + division_ring
 155.188 +
 155.189 +class real_field = real_div_algebra + field
 155.190 +
 155.191 +instance real :: real_field
 155.192 +apply (intro_classes, unfold real_scaleR_def)
 155.193 +apply (rule right_distrib)
 155.194 +apply (rule left_distrib)
 155.195 +apply (rule mult_assoc [symmetric])
 155.196 +apply (rule mult_1_left)
 155.197 +apply (rule mult_assoc)
 155.198 +apply (rule mult_left_commute)
 155.199 +done
 155.200 +
 155.201 +interpretation scaleR_left!: additive "(\<lambda>a. scaleR a x::'a::real_vector)"
 155.202 +proof qed (rule scaleR_left_distrib)
 155.203 +
 155.204 +interpretation scaleR_right!: additive "(\<lambda>x. scaleR a x::'a::real_vector)"
 155.205 +proof qed (rule scaleR_right_distrib)
 155.206 +
 155.207 +lemma nonzero_inverse_scaleR_distrib:
 155.208 +  fixes x :: "'a::real_div_algebra" shows
 155.209 +  "\<lbrakk>a \<noteq> 0; x \<noteq> 0\<rbrakk> \<Longrightarrow> inverse (scaleR a x) = scaleR (inverse a) (inverse x)"
 155.210 +by (rule inverse_unique, simp)
 155.211 +
 155.212 +lemma inverse_scaleR_distrib:
 155.213 +  fixes x :: "'a::{real_div_algebra,division_by_zero}"
 155.214 +  shows "inverse (scaleR a x) = scaleR (inverse a) (inverse x)"
 155.215 +apply (case_tac "a = 0", simp)
 155.216 +apply (case_tac "x = 0", simp)
 155.217 +apply (erule (1) nonzero_inverse_scaleR_distrib)
 155.218 +done
 155.219 +
 155.220 +
 155.221 +subsection {* Embedding of the Reals into any @{text real_algebra_1}:
 155.222 +@{term of_real} *}
 155.223 +
 155.224 +definition
 155.225 +  of_real :: "real \<Rightarrow> 'a::real_algebra_1" where
 155.226 +  "of_real r = scaleR r 1"
 155.227 +
 155.228 +lemma scaleR_conv_of_real: "scaleR r x = of_real r * x"
 155.229 +by (simp add: of_real_def)
 155.230 +
 155.231 +lemma of_real_0 [simp]: "of_real 0 = 0"
 155.232 +by (simp add: of_real_def)
 155.233 +
 155.234 +lemma of_real_1 [simp]: "of_real 1 = 1"
 155.235 +by (simp add: of_real_def)
 155.236 +
 155.237 +lemma of_real_add [simp]: "of_real (x + y) = of_real x + of_real y"
 155.238 +by (simp add: of_real_def scaleR_left_distrib)
 155.239 +
 155.240 +lemma of_real_minus [simp]: "of_real (- x) = - of_real x"
 155.241 +by (simp add: of_real_def)
 155.242 +
 155.243 +lemma of_real_diff [simp]: "of_real (x - y) = of_real x - of_real y"
 155.244 +by (simp add: of_real_def scaleR_left_diff_distrib)
 155.245 +
 155.246 +lemma of_real_mult [simp]: "of_real (x * y) = of_real x * of_real y"
 155.247 +by (simp add: of_real_def mult_commute)
 155.248 +
 155.249 +lemma nonzero_of_real_inverse:
 155.250 +  "x \<noteq> 0 \<Longrightarrow> of_real (inverse x) =
 155.251 +   inverse (of_real x :: 'a::real_div_algebra)"
 155.252 +by (simp add: of_real_def nonzero_inverse_scaleR_distrib)
 155.253 +
 155.254 +lemma of_real_inverse [simp]:
 155.255 +  "of_real (inverse x) =
 155.256 +   inverse (of_real x :: 'a::{real_div_algebra,division_by_zero})"
 155.257 +by (simp add: of_real_def inverse_scaleR_distrib)
 155.258 +
 155.259 +lemma nonzero_of_real_divide:
 155.260 +  "y \<noteq> 0 \<Longrightarrow> of_real (x / y) =
 155.261 +   (of_real x / of_real y :: 'a::real_field)"
 155.262 +by (simp add: divide_inverse nonzero_of_real_inverse)
 155.263 +
 155.264 +lemma of_real_divide [simp]:
 155.265 +  "of_real (x / y) =
 155.266 +   (of_real x / of_real y :: 'a::{real_field,division_by_zero})"
 155.267 +by (simp add: divide_inverse)
 155.268 +
 155.269 +lemma of_real_power [simp]:
 155.270 +  "of_real (x ^ n) = (of_real x :: 'a::{real_algebra_1,recpower}) ^ n"
 155.271 +by (induct n) (simp_all add: power_Suc)
 155.272 +
 155.273 +lemma of_real_eq_iff [simp]: "(of_real x = of_real y) = (x = y)"
 155.274 +by (simp add: of_real_def scaleR_cancel_right)
 155.275 +
 155.276 +lemmas of_real_eq_0_iff [simp] = of_real_eq_iff [of _ 0, simplified]
 155.277 +
 155.278 +lemma of_real_eq_id [simp]: "of_real = (id :: real \<Rightarrow> real)"
 155.279 +proof
 155.280 +  fix r
 155.281 +  show "of_real r = id r"
 155.282 +    by (simp add: of_real_def)
 155.283 +qed
 155.284 +
 155.285 +text{*Collapse nested embeddings*}
 155.286 +lemma of_real_of_nat_eq [simp]: "of_real (of_nat n) = of_nat n"
 155.287 +by (induct n) auto
 155.288 +
 155.289 +lemma of_real_of_int_eq [simp]: "of_real (of_int z) = of_int z"
 155.290 +by (cases z rule: int_diff_cases, simp)
 155.291 +
 155.292 +lemma of_real_number_of_eq:
 155.293 +  "of_real (number_of w) = (number_of w :: 'a::{number_ring,real_algebra_1})"
 155.294 +by (simp add: number_of_eq)
 155.295 +
 155.296 +text{*Every real algebra has characteristic zero*}
 155.297 +instance real_algebra_1 < ring_char_0
 155.298 +proof
 155.299 +  fix m n :: nat
 155.300 +  have "(of_real (of_nat m) = (of_real (of_nat n)::'a)) = (m = n)"
 155.301 +    by (simp only: of_real_eq_iff of_nat_eq_iff)
 155.302 +  thus "(of_nat m = (of_nat n::'a)) = (m = n)"
 155.303 +    by (simp only: of_real_of_nat_eq)
 155.304 +qed
 155.305 +
 155.306 +instance real_field < field_char_0 ..
 155.307 +
 155.308 +
 155.309 +subsection {* The Set of Real Numbers *}
 155.310 +
 155.311 +definition
 155.312 +  Reals :: "'a::real_algebra_1 set" where
 155.313 +  [code del]: "Reals \<equiv> range of_real"
 155.314 +
 155.315 +notation (xsymbols)
 155.316 +  Reals  ("\<real>")
 155.317 +
 155.318 +lemma Reals_of_real [simp]: "of_real r \<in> Reals"
 155.319 +by (simp add: Reals_def)
 155.320 +
 155.321 +lemma Reals_of_int [simp]: "of_int z \<in> Reals"
 155.322 +by (subst of_real_of_int_eq [symmetric], rule Reals_of_real)
 155.323 +
 155.324 +lemma Reals_of_nat [simp]: "of_nat n \<in> Reals"
 155.325 +by (subst of_real_of_nat_eq [symmetric], rule Reals_of_real)
 155.326 +
 155.327 +lemma Reals_number_of [simp]:
 155.328 +  "(number_of w::'a::{number_ring,real_algebra_1}) \<in> Reals"
 155.329 +by (subst of_real_number_of_eq [symmetric], rule Reals_of_real)
 155.330 +
 155.331 +lemma Reals_0 [simp]: "0 \<in> Reals"
 155.332 +apply (unfold Reals_def)
 155.333 +apply (rule range_eqI)
 155.334 +apply (rule of_real_0 [symmetric])
 155.335 +done
 155.336 +
 155.337 +lemma Reals_1 [simp]: "1 \<in> Reals"
 155.338 +apply (unfold Reals_def)
 155.339 +apply (rule range_eqI)
 155.340 +apply (rule of_real_1 [symmetric])
 155.341 +done
 155.342 +
 155.343 +lemma Reals_add [simp]: "\<lbrakk>a \<in> Reals; b \<in> Reals\<rbrakk> \<Longrightarrow> a + b \<in> Reals"
 155.344 +apply (auto simp add: Reals_def)
 155.345 +apply (rule range_eqI)
 155.346 +apply (rule of_real_add [symmetric])
 155.347 +done
 155.348 +
 155.349 +lemma Reals_minus [simp]: "a \<in> Reals \<Longrightarrow> - a \<in> Reals"
 155.350 +apply (auto simp add: Reals_def)
 155.351 +apply (rule range_eqI)
 155.352 +apply (rule of_real_minus [symmetric])
 155.353 +done
 155.354 +
 155.355 +lemma Reals_diff [simp]: "\<lbrakk>a \<in> Reals; b \<in> Reals\<rbrakk> \<Longrightarrow> a - b \<in> Reals"
 155.356 +apply (auto simp add: Reals_def)
 155.357 +apply (rule range_eqI)
 155.358 +apply (rule of_real_diff [symmetric])
 155.359 +done
 155.360 +
 155.361 +lemma Reals_mult [simp]: "\<lbrakk>a \<in> Reals; b \<in> Reals\<rbrakk> \<Longrightarrow> a * b \<in> Reals"
 155.362 +apply (auto simp add: Reals_def)
 155.363 +apply (rule range_eqI)
 155.364 +apply (rule of_real_mult [symmetric])
 155.365 +done
 155.366 +
 155.367 +lemma nonzero_Reals_inverse:
 155.368 +  fixes a :: "'a::real_div_algebra"
 155.369 +  shows "\<lbrakk>a \<in> Reals; a \<noteq> 0\<rbrakk> \<Longrightarrow> inverse a \<in> Reals"
 155.370 +apply (auto simp add: Reals_def)
 155.371 +apply (rule range_eqI)
 155.372 +apply (erule nonzero_of_real_inverse [symmetric])
 155.373 +done
 155.374 +
 155.375 +lemma Reals_inverse [simp]:
 155.376 +  fixes a :: "'a::{real_div_algebra,division_by_zero}"
 155.377 +  shows "a \<in> Reals \<Longrightarrow> inverse a \<in> Reals"
 155.378 +apply (auto simp add: Reals_def)
 155.379 +apply (rule range_eqI)
 155.380 +apply (rule of_real_inverse [symmetric])
 155.381 +done
 155.382 +
 155.383 +lemma nonzero_Reals_divide:
 155.384 +  fixes a b :: "'a::real_field"
 155.385 +  shows "\<lbrakk>a \<in> Reals; b \<in> Reals; b \<noteq> 0\<rbrakk> \<Longrightarrow> a / b \<in> Reals"
 155.386 +apply (auto simp add: Reals_def)
 155.387 +apply (rule range_eqI)
 155.388 +apply (erule nonzero_of_real_divide [symmetric])
 155.389 +done
 155.390 +
 155.391 +lemma Reals_divide [simp]:
 155.392 +  fixes a b :: "'a::{real_field,division_by_zero}"
 155.393 +  shows "\<lbrakk>a \<in> Reals; b \<in> Reals\<rbrakk> \<Longrightarrow> a / b \<in> Reals"
 155.394 +apply (auto simp add: Reals_def)
 155.395 +apply (rule range_eqI)
 155.396 +apply (rule of_real_divide [symmetric])
 155.397 +done
 155.398 +
 155.399 +lemma Reals_power [simp]:
 155.400 +  fixes a :: "'a::{real_algebra_1,recpower}"
 155.401 +  shows "a \<in> Reals \<Longrightarrow> a ^ n \<in> Reals"
 155.402 +apply (auto simp add: Reals_def)
 155.403 +apply (rule range_eqI)
 155.404 +apply (rule of_real_power [symmetric])
 155.405 +done
 155.406 +
 155.407 +lemma Reals_cases [cases set: Reals]:
 155.408 +  assumes "q \<in> \<real>"
 155.409 +  obtains (of_real) r where "q = of_real r"
 155.410 +  unfolding Reals_def
 155.411 +proof -
 155.412 +  from `q \<in> \<real>` have "q \<in> range of_real" unfolding Reals_def .
 155.413 +  then obtain r where "q = of_real r" ..
 155.414 +  then show thesis ..
 155.415 +qed
 155.416 +
 155.417 +lemma Reals_induct [case_names of_real, induct set: Reals]:
 155.418 +  "q \<in> \<real> \<Longrightarrow> (\<And>r. P (of_real r)) \<Longrightarrow> P q"
 155.419 +  by (rule Reals_cases) auto
 155.420 +
 155.421 +
 155.422 +subsection {* Real normed vector spaces *}
 155.423 +
 155.424 +class norm = type +
 155.425 +  fixes norm :: "'a \<Rightarrow> real"
 155.426 +
 155.427 +instantiation real :: norm
 155.428 +begin
 155.429 +
 155.430 +definition
 155.431 +  real_norm_def [simp]: "norm r \<equiv> \<bar>r\<bar>"
 155.432 +
 155.433 +instance ..
 155.434 +
 155.435 +end
 155.436 +
 155.437 +class sgn_div_norm = scaleR + norm + sgn +
 155.438 +  assumes sgn_div_norm: "sgn x = x /\<^sub>R norm x"
 155.439 +
 155.440 +class real_normed_vector = real_vector + sgn_div_norm +
 155.441 +  assumes norm_ge_zero [simp]: "0 \<le> norm x"
 155.442 +  and norm_eq_zero [simp]: "norm x = 0 \<longleftrightarrow> x = 0"
 155.443 +  and norm_triangle_ineq: "norm (x + y) \<le> norm x + norm y"
 155.444 +  and norm_scaleR: "norm (scaleR a x) = \<bar>a\<bar> * norm x"
 155.445 +
 155.446 +class real_normed_algebra = real_algebra + real_normed_vector +
 155.447 +  assumes norm_mult_ineq: "norm (x * y) \<le> norm x * norm y"
 155.448 +
 155.449 +class real_normed_algebra_1 = real_algebra_1 + real_normed_algebra +
 155.450 +  assumes norm_one [simp]: "norm 1 = 1"
 155.451 +
 155.452 +class real_normed_div_algebra = real_div_algebra + real_normed_vector +
 155.453 +  assumes norm_mult: "norm (x * y) = norm x * norm y"
 155.454 +
 155.455 +class real_normed_field = real_field + real_normed_div_algebra
 155.456 +
 155.457 +instance real_normed_div_algebra < real_normed_algebra_1
 155.458 +proof
 155.459 +  fix x y :: 'a
 155.460 +  show "norm (x * y) \<le> norm x * norm y"
 155.461 +    by (simp add: norm_mult)
 155.462 +next
 155.463 +  have "norm (1 * 1::'a) = norm (1::'a) * norm (1::'a)"
 155.464 +    by (rule norm_mult)
 155.465 +  thus "norm (1::'a) = 1" by simp
 155.466 +qed
 155.467 +
 155.468 +instance real :: real_normed_field
 155.469 +apply (intro_classes, unfold real_norm_def real_scaleR_def)
 155.470 +apply (simp add: real_sgn_def)
 155.471 +apply (rule abs_ge_zero)
 155.472 +apply (rule abs_eq_0)
 155.473 +apply (rule abs_triangle_ineq)
 155.474 +apply (rule abs_mult)
 155.475 +apply (rule abs_mult)
 155.476 +done
 155.477 +
 155.478 +lemma norm_zero [simp]: "norm (0::'a::real_normed_vector) = 0"
 155.479 +by simp
 155.480 +
 155.481 +lemma zero_less_norm_iff [simp]:
 155.482 +  fixes x :: "'a::real_normed_vector"
 155.483 +  shows "(0 < norm x) = (x \<noteq> 0)"
 155.484 +by (simp add: order_less_le)
 155.485 +
 155.486 +lemma norm_not_less_zero [simp]:
 155.487 +  fixes x :: "'a::real_normed_vector"
 155.488 +  shows "\<not> norm x < 0"
 155.489 +by (simp add: linorder_not_less)
 155.490 +
 155.491 +lemma norm_le_zero_iff [simp]:
 155.492 +  fixes x :: "'a::real_normed_vector"
 155.493 +  shows "(norm x \<le> 0) = (x = 0)"
 155.494 +by (simp add: order_le_less)
 155.495 +
 155.496 +lemma norm_minus_cancel [simp]:
 155.497 +  fixes x :: "'a::real_normed_vector"
 155.498 +  shows "norm (- x) = norm x"
 155.499 +proof -
 155.500 +  have "norm (- x) = norm (scaleR (- 1) x)"
 155.501 +    by (simp only: scaleR_minus_left scaleR_one)
 155.502 +  also have "\<dots> = \<bar>- 1\<bar> * norm x"
 155.503 +    by (rule norm_scaleR)
 155.504 +  finally show ?thesis by simp
 155.505 +qed
 155.506 +
 155.507 +lemma norm_minus_commute:
 155.508 +  fixes a b :: "'a::real_normed_vector"
 155.509 +  shows "norm (a - b) = norm (b - a)"
 155.510 +proof -
 155.511 +  have "norm (- (b - a)) = norm (b - a)"
 155.512 +    by (rule norm_minus_cancel)
 155.513 +  thus ?thesis by simp
 155.514 +qed
 155.515 +
 155.516 +lemma norm_triangle_ineq2:
 155.517 +  fixes a b :: "'a::real_normed_vector"
 155.518 +  shows "norm a - norm b \<le> norm (a - b)"
 155.519 +proof -
 155.520 +  have "norm (a - b + b) \<le> norm (a - b) + norm b"
 155.521 +    by (rule norm_triangle_ineq)
 155.522 +  thus ?thesis by simp
 155.523 +qed
 155.524 +
 155.525 +lemma norm_triangle_ineq3:
 155.526 +  fixes a b :: "'a::real_normed_vector"
 155.527 +  shows "\<bar>norm a - norm b\<bar> \<le> norm (a - b)"
 155.528 +apply (subst abs_le_iff)
 155.529 +apply auto
 155.530 +apply (rule norm_triangle_ineq2)
 155.531 +apply (subst norm_minus_commute)
 155.532 +apply (rule norm_triangle_ineq2)
 155.533 +done
 155.534 +
 155.535 +lemma norm_triangle_ineq4:
 155.536 +  fixes a b :: "'a::real_normed_vector"
 155.537 +  shows "norm (a - b) \<le> norm a + norm b"
 155.538 +proof -
 155.539 +  have "norm (a + - b) \<le> norm a + norm (- b)"
 155.540 +    by (rule norm_triangle_ineq)
 155.541 +  thus ?thesis
 155.542 +    by (simp only: diff_minus norm_minus_cancel)
 155.543 +qed
 155.544 +
 155.545 +lemma norm_diff_ineq:
 155.546 +  fixes a b :: "'a::real_normed_vector"
 155.547 +  shows "norm a - norm b \<le> norm (a + b)"
 155.548 +proof -
 155.549 +  have "norm a - norm (- b) \<le> norm (a - - b)"
 155.550 +    by (rule norm_triangle_ineq2)
 155.551 +  thus ?thesis by simp
 155.552 +qed
 155.553 +
 155.554 +lemma norm_diff_triangle_ineq:
 155.555 +  fixes a b c d :: "'a::real_normed_vector"
 155.556 +  shows "norm ((a + b) - (c + d)) \<le> norm (a - c) + norm (b - d)"
 155.557 +proof -
 155.558 +  have "norm ((a + b) - (c + d)) = norm ((a - c) + (b - d))"
 155.559 +    by (simp add: diff_minus add_ac)
 155.560 +  also have "\<dots> \<le> norm (a - c) + norm (b - d)"
 155.561 +    by (rule norm_triangle_ineq)
 155.562 +  finally show ?thesis .
 155.563 +qed
 155.564 +
 155.565 +lemma abs_norm_cancel [simp]:
 155.566 +  fixes a :: "'a::real_normed_vector"
 155.567 +  shows "\<bar>norm a\<bar> = norm a"
 155.568 +by (rule abs_of_nonneg [OF norm_ge_zero])
 155.569 +
 155.570 +lemma norm_add_less:
 155.571 +  fixes x y :: "'a::real_normed_vector"
 155.572 +  shows "\<lbrakk>norm x < r; norm y < s\<rbrakk> \<Longrightarrow> norm (x + y) < r + s"
 155.573 +by (rule order_le_less_trans [OF norm_triangle_ineq add_strict_mono])
 155.574 +
 155.575 +lemma norm_mult_less:
 155.576 +  fixes x y :: "'a::real_normed_algebra"
 155.577 +  shows "\<lbrakk>norm x < r; norm y < s\<rbrakk> \<Longrightarrow> norm (x * y) < r * s"
 155.578 +apply (rule order_le_less_trans [OF norm_mult_ineq])
 155.579 +apply (simp add: mult_strict_mono')
 155.580 +done
 155.581 +
 155.582 +lemma norm_of_real [simp]:
 155.583 +  "norm (of_real r :: 'a::real_normed_algebra_1) = \<bar>r\<bar>"
 155.584 +unfolding of_real_def by (simp add: norm_scaleR)
 155.585 +
 155.586 +lemma norm_number_of [simp]:
 155.587 +  "norm (number_of w::'a::{number_ring,real_normed_algebra_1})
 155.588 +    = \<bar>number_of w\<bar>"
 155.589 +by (subst of_real_number_of_eq [symmetric], rule norm_of_real)
 155.590 +
 155.591 +lemma norm_of_int [simp]:
 155.592 +  "norm (of_int z::'a::real_normed_algebra_1) = \<bar>of_int z\<bar>"
 155.593 +by (subst of_real_of_int_eq [symmetric], rule norm_of_real)
 155.594 +
 155.595 +lemma norm_of_nat [simp]:
 155.596 +  "norm (of_nat n::'a::real_normed_algebra_1) = of_nat n"
 155.597 +apply (subst of_real_of_nat_eq [symmetric])
 155.598 +apply (subst norm_of_real, simp)
 155.599 +done
 155.600 +
 155.601 +lemma nonzero_norm_inverse:
 155.602 +  fixes a :: "'a::real_normed_div_algebra"
 155.603 +  shows "a \<noteq> 0 \<Longrightarrow> norm (inverse a) = inverse (norm a)"
 155.604 +apply (rule inverse_unique [symmetric])
 155.605 +apply (simp add: norm_mult [symmetric])
 155.606 +done
 155.607 +
 155.608 +lemma norm_inverse:
 155.609 +  fixes a :: "'a::{real_normed_div_algebra,division_by_zero}"
 155.610 +  shows "norm (inverse a) = inverse (norm a)"
 155.611 +apply (case_tac "a = 0", simp)
 155.612 +apply (erule nonzero_norm_inverse)
 155.613 +done
 155.614 +
 155.615 +lemma nonzero_norm_divide:
 155.616 +  fixes a b :: "'a::real_normed_field"
 155.617 +  shows "b \<noteq> 0 \<Longrightarrow> norm (a / b) = norm a / norm b"
 155.618 +by (simp add: divide_inverse norm_mult nonzero_norm_inverse)
 155.619 +
 155.620 +lemma norm_divide:
 155.621 +  fixes a b :: "'a::{real_normed_field,division_by_zero}"
 155.622 +  shows "norm (a / b) = norm a / norm b"
 155.623 +by (simp add: divide_inverse norm_mult norm_inverse)
 155.624 +
 155.625 +lemma norm_power_ineq:
 155.626 +  fixes x :: "'a::{real_normed_algebra_1,recpower}"
 155.627 +  shows "norm (x ^ n) \<le> norm x ^ n"
 155.628 +proof (induct n)
 155.629 +  case 0 show "norm (x ^ 0) \<le> norm x ^ 0" by simp
 155.630 +next
 155.631 +  case (Suc n)
 155.632 +  have "norm (x * x ^ n) \<le> norm x * norm (x ^ n)"
 155.633 +    by (rule norm_mult_ineq)
 155.634 +  also from Suc have "\<dots> \<le> norm x * norm x ^ n"
 155.635 +    using norm_ge_zero by (rule mult_left_mono)
 155.636 +  finally show "norm (x ^ Suc n) \<le> norm x ^ Suc n"
 155.637 +    by (simp add: power_Suc)
 155.638 +qed
 155.639 +
 155.640 +lemma norm_power:
 155.641 +  fixes x :: "'a::{real_normed_div_algebra,recpower}"
 155.642 +  shows "norm (x ^ n) = norm x ^ n"
 155.643 +by (induct n) (simp_all add: power_Suc norm_mult)
 155.644 +
 155.645 +
 155.646 +subsection {* Sign function *}
 155.647 +
 155.648 +lemma norm_sgn:
 155.649 +  "norm (sgn(x::'a::real_normed_vector)) = (if x = 0 then 0 else 1)"
 155.650 +by (simp add: sgn_div_norm norm_scaleR)
 155.651 +
 155.652 +lemma sgn_zero [simp]: "sgn(0::'a::real_normed_vector) = 0"
 155.653 +by (simp add: sgn_div_norm)
 155.654 +
 155.655 +lemma sgn_zero_iff: "(sgn(x::'a::real_normed_vector) = 0) = (x = 0)"
 155.656 +by (simp add: sgn_div_norm)
 155.657 +
 155.658 +lemma sgn_minus: "sgn (- x) = - sgn(x::'a::real_normed_vector)"
 155.659 +by (simp add: sgn_div_norm)
 155.660 +
 155.661 +lemma sgn_scaleR:
 155.662 +  "sgn (scaleR r x) = scaleR (sgn r) (sgn(x::'a::real_normed_vector))"
 155.663 +by (simp add: sgn_div_norm norm_scaleR mult_ac)
 155.664 +
 155.665 +lemma sgn_one [simp]: "sgn (1::'a::real_normed_algebra_1) = 1"
 155.666 +by (simp add: sgn_div_norm)
 155.667 +
 155.668 +lemma sgn_of_real:
 155.669 +  "sgn (of_real r::'a::real_normed_algebra_1) = of_real (sgn r)"
 155.670 +unfolding of_real_def by (simp only: sgn_scaleR sgn_one)
 155.671 +
 155.672 +lemma sgn_mult:
 155.673 +  fixes x y :: "'a::real_normed_div_algebra"
 155.674 +  shows "sgn (x * y) = sgn x * sgn y"
 155.675 +by (simp add: sgn_div_norm norm_mult mult_commute)
 155.676 +
 155.677 +lemma real_sgn_eq: "sgn (x::real) = x / \<bar>x\<bar>"
 155.678 +by (simp add: sgn_div_norm divide_inverse)
 155.679 +
 155.680 +lemma real_sgn_pos: "0 < (x::real) \<Longrightarrow> sgn x = 1"
 155.681 +unfolding real_sgn_eq by simp
 155.682 +
 155.683 +lemma real_sgn_neg: "(x::real) < 0 \<Longrightarrow> sgn x = -1"
 155.684 +unfolding real_sgn_eq by simp
 155.685 +
 155.686 +
 155.687 +subsection {* Bounded Linear and Bilinear Operators *}
 155.688 +
 155.689 +locale bounded_linear = additive +
 155.690 +  constrains f :: "'a::real_normed_vector \<Rightarrow> 'b::real_normed_vector"
 155.691 +  assumes scaleR: "f (scaleR r x) = scaleR r (f x)"
 155.692 +  assumes bounded: "\<exists>K. \<forall>x. norm (f x) \<le> norm x * K"
 155.693 +begin
 155.694 +
 155.695 +lemma pos_bounded:
 155.696 +  "\<exists>K>0. \<forall>x. norm (f x) \<le> norm x * K"
 155.697 +proof -
 155.698 +  obtain K where K: "\<And>x. norm (f x) \<le> norm x * K"
 155.699 +    using bounded by fast
 155.700 +  show ?thesis
 155.701 +  proof (intro exI impI conjI allI)
 155.702 +    show "0 < max 1 K"
 155.703 +      by (rule order_less_le_trans [OF zero_less_one le_maxI1])
 155.704 +  next
 155.705 +    fix x
 155.706 +    have "norm (f x) \<le> norm x * K" using K .
 155.707 +    also have "\<dots> \<le> norm x * max 1 K"
 155.708 +      by (rule mult_left_mono [OF le_maxI2 norm_ge_zero])
 155.709 +    finally show "norm (f x) \<le> norm x * max 1 K" .
 155.710 +  qed
 155.711 +qed
 155.712 +
 155.713 +lemma nonneg_bounded:
 155.714 +  "\<exists>K\<ge>0. \<forall>x. norm (f x) \<le> norm x * K"
 155.715 +proof -
 155.716 +  from pos_bounded
 155.717 +  show ?thesis by (auto intro: order_less_imp_le)
 155.718 +qed
 155.719 +
 155.720 +end
 155.721 +
 155.722 +locale bounded_bilinear =
 155.723 +  fixes prod :: "['a::real_normed_vector, 'b::real_normed_vector]
 155.724 +                 \<Rightarrow> 'c::real_normed_vector"
 155.725 +    (infixl "**" 70)
 155.726 +  assumes add_left: "prod (a + a') b = prod a b + prod a' b"
 155.727 +  assumes add_right: "prod a (b + b') = prod a b + prod a b'"
 155.728 +  assumes scaleR_left: "prod (scaleR r a) b = scaleR r (prod a b)"
 155.729 +  assumes scaleR_right: "prod a (scaleR r b) = scaleR r (prod a b)"
 155.730 +  assumes bounded: "\<exists>K. \<forall>a b. norm (prod a b) \<le> norm a * norm b * K"
 155.731 +begin
 155.732 +
 155.733 +lemma pos_bounded:
 155.734 +  "\<exists>K>0. \<forall>a b. norm (a ** b) \<le> norm a * norm b * K"
 155.735 +apply (cut_tac bounded, erule exE)
 155.736 +apply (rule_tac x="max 1 K" in exI, safe)
 155.737 +apply (rule order_less_le_trans [OF zero_less_one le_maxI1])
 155.738 +apply (drule spec, drule spec, erule order_trans)
 155.739 +apply (rule mult_left_mono [OF le_maxI2])
 155.740 +apply (intro mult_nonneg_nonneg norm_ge_zero)
 155.741 +done
 155.742 +
 155.743 +lemma nonneg_bounded:
 155.744 +  "\<exists>K\<ge>0. \<forall>a b. norm (a ** b) \<le> norm a * norm b * K"
 155.745 +proof -
 155.746 +  from pos_bounded
 155.747 +  show ?thesis by (auto intro: order_less_imp_le)
 155.748 +qed
 155.749 +
 155.750 +lemma additive_right: "additive (\<lambda>b. prod a b)"
 155.751 +by (rule additive.intro, rule add_right)
 155.752 +
 155.753 +lemma additive_left: "additive (\<lambda>a. prod a b)"
 155.754 +by (rule additive.intro, rule add_left)
 155.755 +
 155.756 +lemma zero_left: "prod 0 b = 0"
 155.757 +by (rule additive.zero [OF additive_left])
 155.758 +
 155.759 +lemma zero_right: "prod a 0 = 0"
 155.760 +by (rule additive.zero [OF additive_right])
 155.761 +
 155.762 +lemma minus_left: "prod (- a) b = - prod a b"
 155.763 +by (rule additive.minus [OF additive_left])
 155.764 +
 155.765 +lemma minus_right: "prod a (- b) = - prod a b"
 155.766 +by (rule additive.minus [OF additive_right])
 155.767 +
 155.768 +lemma diff_left:
 155.769 +  "prod (a - a') b = prod a b - prod a' b"
 155.770 +by (rule additive.diff [OF additive_left])
 155.771 +
 155.772 +lemma diff_right:
 155.773 +  "prod a (b - b') = prod a b - prod a b'"
 155.774 +by (rule additive.diff [OF additive_right])
 155.775 +
 155.776 +lemma bounded_linear_left:
 155.777 +  "bounded_linear (\<lambda>a. a ** b)"
 155.778 +apply (unfold_locales)
 155.779 +apply (rule add_left)
 155.780 +apply (rule scaleR_left)
 155.781 +apply (cut_tac bounded, safe)
 155.782 +apply (rule_tac x="norm b * K" in exI)
 155.783 +apply (simp add: mult_ac)
 155.784 +done
 155.785 +
 155.786 +lemma bounded_linear_right:
 155.787 +  "bounded_linear (\<lambda>b. a ** b)"
 155.788 +apply (unfold_locales)
 155.789 +apply (rule add_right)
 155.790 +apply (rule scaleR_right)
 155.791 +apply (cut_tac bounded, safe)
 155.792 +apply (rule_tac x="norm a * K" in exI)
 155.793 +apply (simp add: mult_ac)
 155.794 +done
 155.795 +
 155.796 +lemma prod_diff_prod:
 155.797 +  "(x ** y - a ** b) = (x - a) ** (y - b) + (x - a) ** b + a ** (y - b)"
 155.798 +by (simp add: diff_left diff_right)
 155.799 +
 155.800 +end
 155.801 +
 155.802 +interpretation mult!:
 155.803 +  bounded_bilinear "op * :: 'a \<Rightarrow> 'a \<Rightarrow> 'a::real_normed_algebra"
 155.804 +apply (rule bounded_bilinear.intro)
 155.805 +apply (rule left_distrib)
 155.806 +apply (rule right_distrib)
 155.807 +apply (rule mult_scaleR_left)
 155.808 +apply (rule mult_scaleR_right)
 155.809 +apply (rule_tac x="1" in exI)
 155.810 +apply (simp add: norm_mult_ineq)
 155.811 +done
 155.812 +
 155.813 +interpretation mult_left!:
 155.814 +  bounded_linear "(\<lambda>x::'a::real_normed_algebra. x * y)"
 155.815 +by (rule mult.bounded_linear_left)
 155.816 +
 155.817 +interpretation mult_right!:
 155.818 +  bounded_linear "(\<lambda>y::'a::real_normed_algebra. x * y)"
 155.819 +by (rule mult.bounded_linear_right)
 155.820 +
 155.821 +interpretation divide!:
 155.822 +  bounded_linear "(\<lambda>x::'a::real_normed_field. x / y)"
 155.823 +unfolding divide_inverse by (rule mult.bounded_linear_left)
 155.824 +
 155.825 +interpretation scaleR!: bounded_bilinear "scaleR"
 155.826 +apply (rule bounded_bilinear.intro)
 155.827 +apply (rule scaleR_left_distrib)
 155.828 +apply (rule scaleR_right_distrib)
 155.829 +apply simp
 155.830 +apply (rule scaleR_left_commute)
 155.831 +apply (rule_tac x="1" in exI)
 155.832 +apply (simp add: norm_scaleR)
 155.833 +done
 155.834 +
 155.835 +interpretation scaleR_left!: bounded_linear "\<lambda>r. scaleR r x"
 155.836 +by (rule scaleR.bounded_linear_left)
 155.837 +
 155.838 +interpretation scaleR_right!: bounded_linear "\<lambda>x. scaleR r x"
 155.839 +by (rule scaleR.bounded_linear_right)
 155.840 +
 155.841 +interpretation of_real!: bounded_linear "\<lambda>r. of_real r"
 155.842 +unfolding of_real_def by (rule scaleR.bounded_linear_left)
 155.843 +
 155.844 +end
   156.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   156.2 +++ b/src/HOL/SEQ.thy	Tue Dec 30 11:10:01 2008 +0100
   156.3 @@ -0,0 +1,1136 @@
   156.4 +(*  Title       : SEQ.thy
   156.5 +    Author      : Jacques D. Fleuriot
   156.6 +    Copyright   : 1998  University of Cambridge
   156.7 +    Description : Convergence of sequences and series
   156.8 +    Conversion to Isar and new proofs by Lawrence C Paulson, 2004
   156.9 +    Additional contributions by Jeremy Avigad and Brian Huffman
  156.10 +*)
  156.11 +
  156.12 +header {* Sequences and Convergence *}
  156.13 +
  156.14 +theory SEQ
  156.15 +imports RealVector RComplete
  156.16 +begin
  156.17 +
  156.18 +definition
  156.19 +  Zseq :: "[nat \<Rightarrow> 'a::real_normed_vector] \<Rightarrow> bool" where
  156.20 +    --{*Standard definition of sequence converging to zero*}
  156.21 +  [code del]: "Zseq X = (\<forall>r>0. \<exists>no. \<forall>n\<ge>no. norm (X n) < r)"
  156.22 +
  156.23 +definition
  156.24 +  LIMSEQ :: "[nat => 'a::real_normed_vector, 'a] => bool"
  156.25 +    ("((_)/ ----> (_))" [60, 60] 60) where
  156.26 +    --{*Standard definition of convergence of sequence*}
  156.27 +  [code del]: "X ----> L = (\<forall>r. 0 < r --> (\<exists>no. \<forall>n. no \<le> n --> norm (X n - L) < r))"
  156.28 +
  156.29 +definition
  156.30 +  lim :: "(nat => 'a::real_normed_vector) => 'a" where
  156.31 +    --{*Standard definition of limit using choice operator*}
  156.32 +  "lim X = (THE L. X ----> L)"
  156.33 +
  156.34 +definition
  156.35 +  convergent :: "(nat => 'a::real_normed_vector) => bool" where
  156.36 +    --{*Standard definition of convergence*}
  156.37 +  "convergent X = (\<exists>L. X ----> L)"
  156.38 +
  156.39 +definition
  156.40 +  Bseq :: "(nat => 'a::real_normed_vector) => bool" where
  156.41 +    --{*Standard definition for bounded sequence*}
  156.42 +  [code del]: "Bseq X = (\<exists>K>0.\<forall>n. norm (X n) \<le> K)"
  156.43 +
  156.44 +definition
  156.45 +  monoseq :: "(nat=>real)=>bool" where
  156.46 +    --{*Definition for monotonicity*}
  156.47 +  [code del]: "monoseq X = ((\<forall>m. \<forall>n\<ge>m. X m \<le> X n) | (\<forall>m. \<forall>n\<ge>m. X n \<le> X m))"
  156.48 +
  156.49 +definition
  156.50 +  subseq :: "(nat => nat) => bool" where
  156.51 +    --{*Definition of subsequence*}
  156.52 +  [code del]:   "subseq f = (\<forall>m. \<forall>n>m. (f m) < (f n))"
  156.53 +
  156.54 +definition
  156.55 +  Cauchy :: "(nat => 'a::real_normed_vector) => bool" where
  156.56 +    --{*Standard definition of the Cauchy condition*}
  156.57 +  [code del]: "Cauchy X = (\<forall>e>0. \<exists>M. \<forall>m \<ge> M. \<forall>n \<ge> M. norm (X m - X n) < e)"
  156.58 +
  156.59 +
  156.60 +subsection {* Bounded Sequences *}
  156.61 +
  156.62 +lemma BseqI': assumes K: "\<And>n. norm (X n) \<le> K" shows "Bseq X"
  156.63 +unfolding Bseq_def
  156.64 +proof (intro exI conjI allI)
  156.65 +  show "0 < max K 1" by simp
  156.66 +next
  156.67 +  fix n::nat
  156.68 +  have "norm (X n) \<le> K" by (rule K)
  156.69 +  thus "norm (X n) \<le> max K 1" by simp
  156.70 +qed
  156.71 +
  156.72 +lemma BseqE: "\<lbrakk>Bseq X; \<And>K. \<lbrakk>0 < K; \<forall>n. norm (X n) \<le> K\<rbrakk> \<Longrightarrow> Q\<rbrakk> \<Longrightarrow> Q"
  156.73 +unfolding Bseq_def by auto
  156.74 +
  156.75 +lemma BseqI2': assumes K: "\<forall>n\<ge>N. norm (X n) \<le> K" shows "Bseq X"
  156.76 +proof (rule BseqI')
  156.77 +  let ?A = "norm ` X ` {..N}"
  156.78 +  have 1: "finite ?A" by simp
  156.79 +  fix n::nat
  156.80 +  show "norm (X n) \<le> max K (Max ?A)"
  156.81 +  proof (cases rule: linorder_le_cases)
  156.82 +    assume "n \<ge> N"
  156.83 +    hence "norm (X n) \<le> K" using K by simp
  156.84 +    thus "norm (X n) \<le> max K (Max ?A)" by simp
  156.85 +  next
  156.86 +    assume "n \<le> N"
  156.87 +    hence "norm (X n) \<in> ?A" by simp
  156.88 +    with 1 have "norm (X n) \<le> Max ?A" by (rule Max_ge)
  156.89 +    thus "norm (X n) \<le> max K (Max ?A)" by simp
  156.90 +  qed
  156.91 +qed
  156.92 +
  156.93 +lemma Bseq_ignore_initial_segment: "Bseq X \<Longrightarrow> Bseq (\<lambda>n. X (n + k))"
  156.94 +unfolding Bseq_def by auto
  156.95 +
  156.96 +lemma Bseq_offset: "Bseq (\<lambda>n. X (n + k)) \<Longrightarrow> Bseq X"
  156.97 +apply (erule BseqE)
  156.98 +apply (rule_tac N="k" and K="K" in BseqI2')
  156.99 +apply clarify
 156.100 +apply (drule_tac x="n - k" in spec, simp)
 156.101 +done
 156.102 +
 156.103 +
 156.104 +subsection {* Sequences That Converge to Zero *}
 156.105 +
 156.106 +lemma ZseqI:
 156.107 +  "(\<And>r. 0 < r \<Longrightarrow> \<exists>no. \<forall>n\<ge>no. norm (X n) < r) \<Longrightarrow> Zseq X"
 156.108 +unfolding Zseq_def by simp
 156.109 +
 156.110 +lemma ZseqD:
 156.111 +  "\<lbrakk>Zseq X; 0 < r\<rbrakk> \<Longrightarrow> \<exists>no. \<forall>n\<ge>no. norm (X n) < r"
 156.112 +unfolding Zseq_def by simp
 156.113 +
 156.114 +lemma Zseq_zero: "Zseq (\<lambda>n. 0)"
 156.115 +unfolding Zseq_def by simp
 156.116 +
 156.117 +lemma Zseq_const_iff: "Zseq (\<lambda>n. k) = (k = 0)"
 156.118 +unfolding Zseq_def by force
 156.119 +
 156.120 +lemma Zseq_norm_iff: "Zseq (\<lambda>n. norm (X n)) = Zseq (\<lambda>n. X n)"
 156.121 +unfolding Zseq_def by simp
 156.122 +
 156.123 +lemma Zseq_imp_Zseq:
 156.124 +  assumes X: "Zseq X"
 156.125 +  assumes Y: "\<And>n. norm (Y n) \<le> norm (X n) * K"
 156.126 +  shows "Zseq (\<lambda>n. Y n)"
 156.127 +proof (cases)
 156.128 +  assume K: "0 < K"
 156.129 +  show ?thesis
 156.130 +  proof (rule ZseqI)
 156.131 +    fix r::real assume "0 < r"
 156.132 +    hence "0 < r / K"
 156.133 +      using K by (rule divide_pos_pos)
 156.134 +    then obtain N where "\<forall>n\<ge>N. norm (X n) < r / K"
 156.135 +      using ZseqD [OF X] by fast
 156.136 +    hence "\<forall>n\<ge>N. norm (X n) * K < r"
 156.137 +      by (simp add: pos_less_divide_eq K)
 156.138 +    hence "\<forall>n\<ge>N. norm (Y n) < r"
 156.139 +      by (simp add: order_le_less_trans [OF Y])
 156.140 +    thus "\<exists>N. \<forall>n\<ge>N. norm (Y n) < r" ..
 156.141 +  qed
 156.142 +next
 156.143 +  assume "\<not> 0 < K"
 156.144 +  hence K: "K \<le> 0" by (simp only: linorder_not_less)
 156.145 +  {
 156.146 +    fix n::nat
 156.147 +    have "norm (Y n) \<le> norm (X n) * K" by (rule Y)
 156.148 +    also have "\<dots> \<le> norm (X n) * 0"
 156.149 +      using K norm_ge_zero by (rule mult_left_mono)
 156.150 +    finally have "norm (Y n) = 0" by simp
 156.151 +  }
 156.152 +  thus ?thesis by (simp add: Zseq_zero)
 156.153 +qed
 156.154 +
 156.155 +lemma Zseq_le: "\<lbrakk>Zseq Y; \<forall>n. norm (X n) \<le> norm (Y n)\<rbrakk> \<Longrightarrow> Zseq X"
 156.156 +by (erule_tac K="1" in Zseq_imp_Zseq, simp)
 156.157 +
 156.158 +lemma Zseq_add:
 156.159 +  assumes X: "Zseq X"
 156.160 +  assumes Y: "Zseq Y"
 156.161 +  shows "Zseq (\<lambda>n. X n + Y n)"
 156.162 +proof (rule ZseqI)
 156.163 +  fix r::real assume "0 < r"
 156.164 +  hence r: "0 < r / 2" by simp
 156.165 +  obtain M where M: "\<forall>n\<ge>M. norm (X n) < r/2"
 156.166 +    using ZseqD [OF X r] by fast
 156.167 +  obtain N where N: "\<forall>n\<ge>N. norm (Y n) < r/2"
 156.168 +    using ZseqD [OF Y r] by fast
 156.169 +  show "\<exists>N. \<forall>n\<ge>N. norm (X n + Y n) < r"
 156.170 +  proof (intro exI allI impI)
 156.171 +    fix n assume n: "max M N \<le> n"
 156.172 +    have "norm (X n + Y n) \<le> norm (X n) + norm (Y n)"
 156.173 +      by (rule norm_triangle_ineq)
 156.174 +    also have "\<dots> < r/2 + r/2"
 156.175 +    proof (rule add_strict_mono)
 156.176 +      from M n show "norm (X n) < r/2" by simp
 156.177 +      from N n show "norm (Y n) < r/2" by simp
 156.178 +    qed
 156.179 +    finally show "norm (X n + Y n) < r" by simp
 156.180 +  qed
 156.181 +qed
 156.182 +
 156.183 +lemma Zseq_minus: "Zseq X \<Longrightarrow> Zseq (\<lambda>n. - X n)"
 156.184 +unfolding Zseq_def by simp
 156.185 +
 156.186 +lemma Zseq_diff: "\<lbrakk>Zseq X; Zseq Y\<rbrakk> \<Longrightarrow> Zseq (\<lambda>n. X n - Y n)"
 156.187 +by (simp only: diff_minus Zseq_add Zseq_minus)
 156.188 +
 156.189 +lemma (in bounded_linear) Zseq:
 156.190 +  assumes X: "Zseq X"
 156.191 +  shows "Zseq (\<lambda>n. f (X n))"
 156.192 +proof -
 156.193 +  obtain K where "\<And>x. norm (f x) \<le> norm x * K"
 156.194 +    using bounded by fast
 156.195 +  with X show ?thesis
 156.196 +    by (rule Zseq_imp_Zseq)
 156.197 +qed
 156.198 +
 156.199 +lemma (in bounded_bilinear) Zseq:
 156.200 +  assumes X: "Zseq X"
 156.201 +  assumes Y: "Zseq Y"
 156.202 +  shows "Zseq (\<lambda>n. X n ** Y n)"
 156.203 +proof (rule ZseqI)
 156.204 +  fix r::real assume r: "0 < r"
 156.205 +  obtain K where K: "0 < K"
 156.206 +    and norm_le: "\<And>x y. norm (x ** y) \<le> norm x * norm y * K"
 156.207 +    using pos_bounded by fast
 156.208 +  from K have K': "0 < inverse K"
 156.209 +    by (rule positive_imp_inverse_positive)
 156.210 +  obtain M where M: "\<forall>n\<ge>M. norm (X n) < r"
 156.211 +    using ZseqD [OF X r] by fast
 156.212 +  obtain N where N: "\<forall>n\<ge>N. norm (Y n) < inverse K"
 156.213 +    using ZseqD [OF Y K'] by fast
 156.214 +  show "\<exists>N. \<forall>n\<ge>N. norm (X n ** Y n) < r"
 156.215 +  proof (intro exI allI impI)
 156.216 +    fix n assume n: "max M N \<le> n"
 156.217 +    have "norm (X n ** Y n) \<le> norm (X n) * norm (Y n) * K"
 156.218 +      by (rule norm_le)
 156.219 +    also have "norm (X n) * norm (Y n) * K < r * inverse K * K"
 156.220 +    proof (intro mult_strict_right_mono mult_strict_mono' norm_ge_zero K)
 156.221 +      from M n show Xn: "norm (X n) < r" by simp
 156.222 +      from N n show Yn: "norm (Y n) < inverse K" by simp
 156.223 +    qed
 156.224 +    also from K have "r * inverse K * K = r" by simp
 156.225 +    finally show "norm (X n ** Y n) < r" .
 156.226 +  qed
 156.227 +qed
 156.228 +
 156.229 +lemma (in bounded_bilinear) Zseq_prod_Bseq:
 156.230 +  assumes X: "Zseq X"
 156.231 +  assumes Y: "Bseq Y"
 156.232 +  shows "Zseq (\<lambda>n. X n ** Y n)"
 156.233 +proof -
 156.234 +  obtain K where K: "0 \<le> K"
 156.235 +    and norm_le: "\<And>x y. norm (x ** y) \<le> norm x * norm y * K"
 156.236 +    using nonneg_bounded by fast
 156.237 +  obtain B where B: "0 < B"
 156.238 +    and norm_Y: "\<And>n. norm (Y n) \<le> B"
 156.239 +    using Y [unfolded Bseq_def] by fast
 156.240 +  from X show ?thesis
 156.241 +  proof (rule Zseq_imp_Zseq)
 156.242 +    fix n::nat
 156.243 +    have "norm (X n ** Y n) \<le> norm (X n) * norm (Y n) * K"
 156.244 +      by (rule norm_le)
 156.245 +    also have "\<dots> \<le> norm (X n) * B * K"
 156.246 +      by (intro mult_mono' order_refl norm_Y norm_ge_zero
 156.247 +                mult_nonneg_nonneg K)
 156.248 +    also have "\<dots> = norm (X n) * (B * K)"
 156.249 +      by (rule mult_assoc)
 156.250 +    finally show "norm (X n ** Y n) \<le> norm (X n) * (B * K)" .
 156.251 +  qed
 156.252 +qed
 156.253 +
 156.254 +lemma (in bounded_bilinear) Bseq_prod_Zseq:
 156.255 +  assumes X: "Bseq X"
 156.256 +  assumes Y: "Zseq Y"
 156.257 +  shows "Zseq (\<lambda>n. X n ** Y n)"
 156.258 +proof -
 156.259 +  obtain K where K: "0 \<le> K"
 156.260 +    and norm_le: "\<And>x y. norm (x ** y) \<le> norm x * norm y * K"
 156.261 +    using nonneg_bounded by fast
 156.262 +  obtain B where B: "0 < B"
 156.263 +    and norm_X: "\<And>n. norm (X n) \<le> B"
 156.264 +    using X [unfolded Bseq_def] by fast
 156.265 +  from Y show ?thesis
 156.266 +  proof (rule Zseq_imp_Zseq)
 156.267 +    fix n::nat
 156.268 +    have "norm (X n ** Y n) \<le> norm (X n) * norm (Y n) * K"
 156.269 +      by (rule norm_le)
 156.270 +    also have "\<dots> \<le> B * norm (Y n) * K"
 156.271 +      by (intro mult_mono' order_refl norm_X norm_ge_zero
 156.272 +                mult_nonneg_nonneg K)
 156.273 +    also have "\<dots> = norm (Y n) * (B * K)"
 156.274 +      by (simp only: mult_ac)
 156.275 +    finally show "norm (X n ** Y n) \<le> norm (Y n) * (B * K)" .
 156.276 +  qed
 156.277 +qed
 156.278 +
 156.279 +lemma (in bounded_bilinear) Zseq_left:
 156.280 +  "Zseq X \<Longrightarrow> Zseq (\<lambda>n. X n ** a)"
 156.281 +by (rule bounded_linear_left [THEN bounded_linear.Zseq])
 156.282 +
 156.283 +lemma (in bounded_bilinear) Zseq_right:
 156.284 +  "Zseq X \<Longrightarrow> Zseq (\<lambda>n. a ** X n)"
 156.285 +by (rule bounded_linear_right [THEN bounded_linear.Zseq])
 156.286 +
 156.287 +lemmas Zseq_mult = mult.Zseq
 156.288 +lemmas Zseq_mult_right = mult.Zseq_right
 156.289 +lemmas Zseq_mult_left = mult.Zseq_left
 156.290 +
 156.291 +
 156.292 +subsection {* Limits of Sequences *}
 156.293 +
 156.294 +lemma LIMSEQ_iff:
 156.295 +      "(X ----> L) = (\<forall>r>0. \<exists>no. \<forall>n \<ge> no. norm (X n - L) < r)"
 156.296 +by (rule LIMSEQ_def)
 156.297 +
 156.298 +lemma LIMSEQ_Zseq_iff: "((\<lambda>n. X n) ----> L) = Zseq (\<lambda>n. X n - L)"
 156.299 +by (simp only: LIMSEQ_def Zseq_def)
 156.300 +
 156.301 +lemma LIMSEQ_I:
 156.302 +  "(\<And>r. 0 < r \<Longrightarrow> \<exists>no. \<forall>n\<ge>no. norm (X n - L) < r) \<Longrightarrow> X ----> L"
 156.303 +by (simp add: LIMSEQ_def)
 156.304 +
 156.305 +lemma LIMSEQ_D:
 156.306 +  "\<lbrakk>X ----> L; 0 < r\<rbrakk> \<Longrightarrow> \<exists>no. \<forall>n\<ge>no. norm (X n - L) < r"
 156.307 +by (simp add: LIMSEQ_def)
 156.308 +
 156.309 +lemma LIMSEQ_const: "(\<lambda>n. k) ----> k"
 156.310 +by (simp add: LIMSEQ_def)
 156.311 +
 156.312 +lemma LIMSEQ_const_iff: "(\<lambda>n. k) ----> l = (k = l)"
 156.313 +by (simp add: LIMSEQ_Zseq_iff Zseq_const_iff)
 156.314 +
 156.315 +lemma LIMSEQ_norm: "X ----> a \<Longrightarrow> (\<lambda>n. norm (X n)) ----> norm a"
 156.316 +apply (simp add: LIMSEQ_def, safe)
 156.317 +apply (drule_tac x="r" in spec, safe)
 156.318 +apply (rule_tac x="no" in exI, safe)
 156.319 +apply (drule_tac x="n" in spec, safe)
 156.320 +apply (erule order_le_less_trans [OF norm_triangle_ineq3])
 156.321 +done
 156.322 +
 156.323 +lemma LIMSEQ_ignore_initial_segment:
 156.324 +  "f ----> a \<Longrightarrow> (\<lambda>n. f (n + k)) ----> a"
 156.325 +apply (rule LIMSEQ_I)
 156.326 +apply (drule (1) LIMSEQ_D)
 156.327 +apply (erule exE, rename_tac N)
 156.328 +apply (rule_tac x=N in exI)
 156.329 +apply simp
 156.330 +done
 156.331 +
 156.332 +lemma LIMSEQ_offset:
 156.333 +  "(\<lambda>n. f (n + k)) ----> a \<Longrightarrow> f ----> a"
 156.334 +apply (rule LIMSEQ_I)
 156.335 +apply (drule (1) LIMSEQ_D)
 156.336 +apply (erule exE, rename_tac N)
 156.337 +apply (rule_tac x="N + k" in exI)
 156.338 +apply clarify
 156.339 +apply (drule_tac x="n - k" in spec)
 156.340 +apply (simp add: le_diff_conv2)
 156.341 +done
 156.342 +
 156.343 +lemma LIMSEQ_Suc: "f ----> l \<Longrightarrow> (\<lambda>n. f (Suc n)) ----> l"
 156.344 +by (drule_tac k="1" in LIMSEQ_ignore_initial_segment, simp)
 156.345 +
 156.346 +lemma LIMSEQ_imp_Suc: "(\<lambda>n. f (Suc n)) ----> l \<Longrightarrow> f ----> l"
 156.347 +by (rule_tac k="1" in LIMSEQ_offset, simp)
 156.348 +
 156.349 +lemma LIMSEQ_Suc_iff: "(\<lambda>n. f (Suc n)) ----> l = f ----> l"
 156.350 +by (blast intro: LIMSEQ_imp_Suc LIMSEQ_Suc)
 156.351 +
 156.352 +lemma add_diff_add:
 156.353 +  fixes a b c d :: "'a::ab_group_add"
 156.354 +  shows "(a + c) - (b + d) = (a - b) + (c - d)"
 156.355 +by simp
 156.356 +
 156.357 +lemma minus_diff_minus:
 156.358 +  fixes a b :: "'a::ab_group_add"
 156.359 +  shows "(- a) - (- b) = - (a - b)"
 156.360 +by simp
 156.361 +
 156.362 +lemma LIMSEQ_add: "\<lbrakk>X ----> a; Y ----> b\<rbrakk> \<Longrightarrow> (\<lambda>n. X n + Y n) ----> a + b"
 156.363 +by (simp only: LIMSEQ_Zseq_iff add_diff_add Zseq_add)
 156.364 +
 156.365 +lemma LIMSEQ_minus: "X ----> a \<Longrightarrow> (\<lambda>n. - X n) ----> - a"
 156.366 +by (simp only: LIMSEQ_Zseq_iff minus_diff_minus Zseq_minus)
 156.367 +
 156.368 +lemma LIMSEQ_minus_cancel: "(\<lambda>n. - X n) ----> - a \<Longrightarrow> X ----> a"
 156.369 +by (drule LIMSEQ_minus, simp)
 156.370 +
 156.371 +lemma LIMSEQ_diff: "\<lbrakk>X ----> a; Y ----> b\<rbrakk> \<Longrightarrow> (\<lambda>n. X n - Y n) ----> a - b"
 156.372 +by (simp add: diff_minus LIMSEQ_add LIMSEQ_minus)
 156.373 +
 156.374 +lemma LIMSEQ_unique: "\<lbrakk>X ----> a; X ----> b\<rbrakk> \<Longrightarrow> a = b"
 156.375 +by (drule (1) LIMSEQ_diff, simp add: LIMSEQ_const_iff)
 156.376 +
 156.377 +lemma (in bounded_linear) LIMSEQ:
 156.378 +  "X ----> a \<Longrightarrow> (\<lambda>n. f (X n)) ----> f a"
 156.379 +by (simp only: LIMSEQ_Zseq_iff diff [symmetric] Zseq)
 156.380 +
 156.381 +lemma (in bounded_bilinear) LIMSEQ:
 156.382 +  "\<lbrakk>X ----> a; Y ----> b\<rbrakk> \<Longrightarrow> (\<lambda>n. X n ** Y n) ----> a ** b"
 156.383 +by (simp only: LIMSEQ_Zseq_iff prod_diff_prod
 156.384 +               Zseq_add Zseq Zseq_left Zseq_right)
 156.385 +
 156.386 +lemma LIMSEQ_mult:
 156.387 +  fixes a b :: "'a::real_normed_algebra"
 156.388 +  shows "[| X ----> a; Y ----> b |] ==> (%n. X n * Y n) ----> a * b"
 156.389 +by (rule mult.LIMSEQ)
 156.390 +
 156.391 +lemma inverse_diff_inverse:
 156.392 +  "\<lbrakk>(a::'a::division_ring) \<noteq> 0; b \<noteq> 0\<rbrakk>
 156.393 +   \<Longrightarrow> inverse a - inverse b = - (inverse a * (a - b) * inverse b)"
 156.394 +by (simp add: ring_simps)
 156.395 +
 156.396 +lemma Bseq_inverse_lemma:
 156.397 +  fixes x :: "'a::real_normed_div_algebra"
 156.398 +  shows "\<lbrakk>r \<le> norm x; 0 < r\<rbrakk> \<Longrightarrow> norm (inverse x) \<le> inverse r"
 156.399 +apply (subst nonzero_norm_inverse, clarsimp)
 156.400 +apply (erule (1) le_imp_inverse_le)
 156.401 +done
 156.402 +
 156.403 +lemma Bseq_inverse:
 156.404 +  fixes a :: "'a::real_normed_div_algebra"
 156.405 +  assumes X: "X ----> a"
 156.406 +  assumes a: "a \<noteq> 0"
 156.407 +  shows "Bseq (\<lambda>n. inverse (X n))"
 156.408 +proof -
 156.409 +  from a have "0 < norm a" by simp
 156.410 +  hence "\<exists>r>0. r < norm a" by (rule dense)
 156.411 +  then obtain r where r1: "0 < r" and r2: "r < norm a" by fast
 156.412 +  obtain N where N: "\<And>n. N \<le> n \<Longrightarrow> norm (X n - a) < r"
 156.413 +    using LIMSEQ_D [OF X r1] by fast
 156.414 +  show ?thesis
 156.415 +  proof (rule BseqI2' [rule_format])
 156.416 +    fix n assume n: "N \<le> n"
 156.417 +    hence 1: "norm (X n - a) < r" by (rule N)
 156.418 +    hence 2: "X n \<noteq> 0" using r2 by auto
 156.419 +    hence "norm (inverse (X n)) = inverse (norm (X n))"
 156.420 +      by (rule nonzero_norm_inverse)
 156.421 +    also have "\<dots> \<le> inverse (norm a - r)"
 156.422 +    proof (rule le_imp_inverse_le)
 156.423 +      show "0 < norm a - r" using r2 by simp
 156.424 +    next
 156.425 +      have "norm a - norm (X n) \<le> norm (a - X n)"
 156.426 +        by (rule norm_triangle_ineq2)
 156.427 +      also have "\<dots> = norm (X n - a)"
 156.428 +        by (rule norm_minus_commute)
 156.429 +      also have "\<dots> < r" using 1 .
 156.430 +      finally show "norm a - r \<le> norm (X n)" by simp
 156.431 +    qed
 156.432 +    finally show "norm (inverse (X n)) \<le> inverse (norm a - r)" .
 156.433 +  qed
 156.434 +qed
 156.435 +
 156.436 +lemma LIMSEQ_inverse_lemma:
 156.437 +  fixes a :: "'a::real_normed_div_algebra"
 156.438 +  shows "\<lbrakk>X ----> a; a \<noteq> 0; \<forall>n. X n \<noteq> 0\<rbrakk>
 156.439 +         \<Longrightarrow> (\<lambda>n. inverse (X n)) ----> inverse a"
 156.440 +apply (subst LIMSEQ_Zseq_iff)
 156.441 +apply (simp add: inverse_diff_inverse nonzero_imp_inverse_nonzero)
 156.442 +apply (rule Zseq_minus)
 156.443 +apply (rule Zseq_mult_left)
 156.444 +apply (rule mult.Bseq_prod_Zseq)
 156.445 +apply (erule (1) Bseq_inverse)
 156.446 +apply (simp add: LIMSEQ_Zseq_iff)
 156.447 +done
 156.448 +
 156.449 +lemma LIMSEQ_inverse:
 156.450 +  fixes a :: "'a::real_normed_div_algebra"
 156.451 +  assumes X: "X ----> a"
 156.452 +  assumes a: "a \<noteq> 0"
 156.453 +  shows "(\<lambda>n. inverse (X n)) ----> inverse a"
 156.454 +proof -
 156.455 +  from a have "0 < norm a" by simp
 156.456 +  then obtain k where "\<forall>n\<ge>k. norm (X n - a) < norm a"
 156.457 +    using LIMSEQ_D [OF X] by fast
 156.458 +  hence "\<forall>n\<ge>k. X n \<noteq> 0" by auto
 156.459 +  hence k: "\<forall>n. X (n + k) \<noteq> 0" by simp
 156.460 +
 156.461 +  from X have "(\<lambda>n. X (n + k)) ----> a"
 156.462 +    by (rule LIMSEQ_ignore_initial_segment)
 156.463 +  hence "(\<lambda>n. inverse (X (n + k))) ----> inverse a"
 156.464 +    using a k by (rule LIMSEQ_inverse_lemma)
 156.465 +  thus "(\<lambda>n. inverse (X n)) ----> inverse a"
 156.466 +    by (rule LIMSEQ_offset)
 156.467 +qed
 156.468 +
 156.469 +lemma LIMSEQ_divide:
 156.470 +  fixes a b :: "'a::real_normed_field"
 156.471 +  shows "\<lbrakk>X ----> a; Y ----> b; b \<noteq> 0\<rbrakk> \<Longrightarrow> (\<lambda>n. X n / Y n) ----> a / b"
 156.472 +by (simp add: LIMSEQ_mult LIMSEQ_inverse divide_inverse)
 156.473 +
 156.474 +lemma LIMSEQ_pow:
 156.475 +  fixes a :: "'a::{real_normed_algebra,recpower}"
 156.476 +  shows "X ----> a \<Longrightarrow> (\<lambda>n. (X n) ^ m) ----> a ^ m"
 156.477 +by (induct m) (simp_all add: power_Suc LIMSEQ_const LIMSEQ_mult)
 156.478 +
 156.479 +lemma LIMSEQ_setsum:
 156.480 +  assumes n: "\<And>n. n \<in> S \<Longrightarrow> X n ----> L n"
 156.481 +  shows "(\<lambda>m. \<Sum>n\<in>S. X n m) ----> (\<Sum>n\<in>S. L n)"
 156.482 +proof (cases "finite S")
 156.483 +  case True
 156.484 +  thus ?thesis using n
 156.485 +  proof (induct)
 156.486 +    case empty
 156.487 +    show ?case
 156.488 +      by (simp add: LIMSEQ_const)
 156.489 +  next
 156.490 +    case insert
 156.491 +    thus ?case
 156.492 +      by (simp add: LIMSEQ_add)
 156.493 +  qed
 156.494 +next
 156.495 +  case False
 156.496 +  thus ?thesis
 156.497 +    by (simp add: LIMSEQ_const)
 156.498 +qed
 156.499 +
 156.500 +lemma LIMSEQ_setprod:
 156.501 +  fixes L :: "'a \<Rightarrow> 'b::{real_normed_algebra,comm_ring_1}"
 156.502 +  assumes n: "\<And>n. n \<in> S \<Longrightarrow> X n ----> L n"
 156.503 +  shows "(\<lambda>m. \<Prod>n\<in>S. X n m) ----> (\<Prod>n\<in>S. L n)"
 156.504 +proof (cases "finite S")
 156.505 +  case True
 156.506 +  thus ?thesis using n
 156.507 +  proof (induct)
 156.508 +    case empty
 156.509 +    show ?case
 156.510 +      by (simp add: LIMSEQ_const)
 156.511 +  next
 156.512 +    case insert
 156.513 +    thus ?case
 156.514 +      by (simp add: LIMSEQ_mult)
 156.515 +  qed
 156.516 +next
 156.517 +  case False
 156.518 +  thus ?thesis
 156.519 +    by (simp add: setprod_def LIMSEQ_const)
 156.520 +qed
 156.521 +
 156.522 +lemma LIMSEQ_add_const: "f ----> a ==> (%n.(f n + b)) ----> a + b"
 156.523 +by (simp add: LIMSEQ_add LIMSEQ_const)
 156.524 +
 156.525 +(* FIXME: delete *)
 156.526 +lemma LIMSEQ_add_minus:
 156.527 +     "[| X ----> a; Y ----> b |] ==> (%n. X n + -Y n) ----> a + -b"
 156.528 +by (simp only: LIMSEQ_add LIMSEQ_minus)
 156.529 +
 156.530 +lemma LIMSEQ_diff_const: "f ----> a ==> (%n.(f n  - b)) ----> a - b"
 156.531 +by (simp add: LIMSEQ_diff LIMSEQ_const)
 156.532 +
 156.533 +lemma LIMSEQ_diff_approach_zero: 
 156.534 +  "g ----> L ==> (%x. f x - g x) ----> 0  ==>
 156.535 +     f ----> L"
 156.536 +  apply (drule LIMSEQ_add)
 156.537 +  apply assumption
 156.538 +  apply simp
 156.539 +done
 156.540 +
 156.541 +lemma LIMSEQ_diff_approach_zero2: 
 156.542 +  "f ----> L ==> (%x. f x - g x) ----> 0  ==>
 156.543 +     g ----> L";
 156.544 +  apply (drule LIMSEQ_diff)
 156.545 +  apply assumption
 156.546 +  apply simp
 156.547 +done
 156.548 +
 156.549 +text{*A sequence tends to zero iff its abs does*}
 156.550 +lemma LIMSEQ_norm_zero: "((\<lambda>n. norm (X n)) ----> 0) = (X ----> 0)"
 156.551 +by (simp add: LIMSEQ_def)
 156.552 +
 156.553 +lemma LIMSEQ_rabs_zero: "((%n. \<bar>f n\<bar>) ----> 0) = (f ----> (0::real))"
 156.554 +by (simp add: LIMSEQ_def)
 156.555 +
 156.556 +lemma LIMSEQ_imp_rabs: "f ----> (l::real) ==> (%n. \<bar>f n\<bar>) ----> \<bar>l\<bar>"
 156.557 +by (drule LIMSEQ_norm, simp)
 156.558 +
 156.559 +text{*An unbounded sequence's inverse tends to 0*}
 156.560 +
 156.561 +lemma LIMSEQ_inverse_zero:
 156.562 +  "\<forall>r::real. \<exists>N. \<forall>n\<ge>N. r < X n \<Longrightarrow> (\<lambda>n. inverse (X n)) ----> 0"
 156.563 +apply (rule LIMSEQ_I)
 156.564 +apply (drule_tac x="inverse r" in spec, safe)
 156.565 +apply (rule_tac x="N" in exI, safe)
 156.566 +apply (drule_tac x="n" in spec, safe)
 156.567 +apply (frule positive_imp_inverse_positive)
 156.568 +apply (frule (1) less_imp_inverse_less)
 156.569 +apply (subgoal_tac "0 < X n", simp)
 156.570 +apply (erule (1) order_less_trans)
 156.571 +done
 156.572 +
 156.573 +text{*The sequence @{term "1/n"} tends to 0 as @{term n} tends to infinity*}
 156.574 +
 156.575 +lemma LIMSEQ_inverse_real_of_nat: "(%n. inverse(real(Suc n))) ----> 0"
 156.576 +apply (rule LIMSEQ_inverse_zero, safe)
 156.577 +apply (cut_tac x = r in reals_Archimedean2)
 156.578 +apply (safe, rule_tac x = n in exI)
 156.579 +apply (auto simp add: real_of_nat_Suc)
 156.580 +done
 156.581 +
 156.582 +text{*The sequence @{term "r + 1/n"} tends to @{term r} as @{term n} tends to
 156.583 +infinity is now easily proved*}
 156.584 +
 156.585 +lemma LIMSEQ_inverse_real_of_nat_add:
 156.586 +     "(%n. r + inverse(real(Suc n))) ----> r"
 156.587 +by (cut_tac LIMSEQ_add [OF LIMSEQ_const LIMSEQ_inverse_real_of_nat], auto)
 156.588 +
 156.589 +lemma LIMSEQ_inverse_real_of_nat_add_minus:
 156.590 +     "(%n. r + -inverse(real(Suc n))) ----> r"
 156.591 +by (cut_tac LIMSEQ_add_minus [OF LIMSEQ_const LIMSEQ_inverse_real_of_nat], auto)
 156.592 +
 156.593 +lemma LIMSEQ_inverse_real_of_nat_add_minus_mult:
 156.594 +     "(%n. r*( 1 + -inverse(real(Suc n)))) ----> r"
 156.595 +by (cut_tac b=1 in
 156.596 +        LIMSEQ_mult [OF LIMSEQ_const LIMSEQ_inverse_real_of_nat_add_minus], auto)
 156.597 +
 156.598 +lemma LIMSEQ_le_const:
 156.599 +  "\<lbrakk>X ----> (x::real); \<exists>N. \<forall>n\<ge>N. a \<le> X n\<rbrakk> \<Longrightarrow> a \<le> x"
 156.600 +apply (rule ccontr, simp only: linorder_not_le)
 156.601 +apply (drule_tac r="a - x" in LIMSEQ_D, simp)
 156.602 +apply clarsimp
 156.603 +apply (drule_tac x="max N no" in spec, drule mp, rule le_maxI1)
 156.604 +apply (drule_tac x="max N no" in spec, drule mp, rule le_maxI2)
 156.605 +apply simp
 156.606 +done
 156.607 +
 156.608 +lemma LIMSEQ_le_const2:
 156.609 +  "\<lbrakk>X ----> (x::real); \<exists>N. \<forall>n\<ge>N. X n \<le> a\<rbrakk> \<Longrightarrow> x \<le> a"
 156.610 +apply (subgoal_tac "- a \<le> - x", simp)
 156.611 +apply (rule LIMSEQ_le_const)
 156.612 +apply (erule LIMSEQ_minus)
 156.613 +apply simp
 156.614 +done
 156.615 +
 156.616 +lemma LIMSEQ_le:
 156.617 +  "\<lbrakk>X ----> x; Y ----> y; \<exists>N. \<forall>n\<ge>N. X n \<le> Y n\<rbrakk> \<Longrightarrow> x \<le> (y::real)"
 156.618 +apply (subgoal_tac "0 \<le> y - x", simp)
 156.619 +apply (rule LIMSEQ_le_const)
 156.620 +apply (erule (1) LIMSEQ_diff)
 156.621 +apply (simp add: le_diff_eq)
 156.622 +done
 156.623 +
 156.624 +
 156.625 +subsection {* Convergence *}
 156.626 +
 156.627 +lemma limI: "X ----> L ==> lim X = L"
 156.628 +apply (simp add: lim_def)
 156.629 +apply (blast intro: LIMSEQ_unique)
 156.630 +done
 156.631 +
 156.632 +lemma convergentD: "convergent X ==> \<exists>L. (X ----> L)"
 156.633 +by (simp add: convergent_def)
 156.634 +
 156.635 +lemma convergentI: "(X ----> L) ==> convergent X"
 156.636 +by (auto simp add: convergent_def)
 156.637 +
 156.638 +lemma convergent_LIMSEQ_iff: "convergent X = (X ----> lim X)"
 156.639 +by (auto intro: theI LIMSEQ_unique simp add: convergent_def lim_def)
 156.640 +
 156.641 +lemma convergent_minus_iff: "(convergent X) = (convergent (%n. -(X n)))"
 156.642 +apply (simp add: convergent_def)
 156.643 +apply (auto dest: LIMSEQ_minus)
 156.644 +apply (drule LIMSEQ_minus, auto)
 156.645 +done
 156.646 +
 156.647 +
 156.648 +subsection {* Bounded Monotonic Sequences *}
 156.649 +
 156.650 +text{*Subsequence (alternative definition, (e.g. Hoskins)*}
 156.651 +
 156.652 +lemma subseq_Suc_iff: "subseq f = (\<forall>n. (f n) < (f (Suc n)))"
 156.653 +apply (simp add: subseq_def)
 156.654 +apply (auto dest!: less_imp_Suc_add)
 156.655 +apply (induct_tac k)
 156.656 +apply (auto intro: less_trans)
 156.657 +done
 156.658 +
 156.659 +lemma monoseq_Suc:
 156.660 +   "monoseq X = ((\<forall>n. X n \<le> X (Suc n))
 156.661 +                 | (\<forall>n. X (Suc n) \<le> X n))"
 156.662 +apply (simp add: monoseq_def)
 156.663 +apply (auto dest!: le_imp_less_or_eq)
 156.664 +apply (auto intro!: lessI [THEN less_imp_le] dest!: less_imp_Suc_add)
 156.665 +apply (induct_tac "ka")
 156.666 +apply (auto intro: order_trans)
 156.667 +apply (erule contrapos_np)
 156.668 +apply (induct_tac "k")
 156.669 +apply (auto intro: order_trans)
 156.670 +done
 156.671 +
 156.672 +lemma monoI1: "\<forall>m. \<forall> n \<ge> m. X m \<le> X n ==> monoseq X"
 156.673 +by (simp add: monoseq_def)
 156.674 +
 156.675 +lemma monoI2: "\<forall>m. \<forall> n \<ge> m. X n \<le> X m ==> monoseq X"
 156.676 +by (simp add: monoseq_def)
 156.677 +
 156.678 +lemma mono_SucI1: "\<forall>n. X n \<le> X (Suc n) ==> monoseq X"
 156.679 +by (simp add: monoseq_Suc)
 156.680 +
 156.681 +lemma mono_SucI2: "\<forall>n. X (Suc n) \<le> X n ==> monoseq X"
 156.682 +by (simp add: monoseq_Suc)
 156.683 +
 156.684 +text{*Bounded Sequence*}
 156.685 +
 156.686 +lemma BseqD: "Bseq X ==> \<exists>K. 0 < K & (\<forall>n. norm (X n) \<le> K)"
 156.687 +by (simp add: Bseq_def)
 156.688 +
 156.689 +lemma BseqI: "[| 0 < K; \<forall>n. norm (X n) \<le> K |] ==> Bseq X"
 156.690 +by (auto simp add: Bseq_def)
 156.691 +
 156.692 +lemma lemma_NBseq_def:
 156.693 +     "(\<exists>K > 0. \<forall>n. norm (X n) \<le> K) =
 156.694 +      (\<exists>N. \<forall>n. norm (X n) \<le> real(Suc N))"
 156.695 +apply auto
 156.696 + prefer 2 apply force
 156.697 +apply (cut_tac x = K in reals_Archimedean2, clarify)
 156.698 +apply (rule_tac x = n in exI, clarify)
 156.699 +apply (drule_tac x = na in spec)
 156.700 +apply (auto simp add: real_of_nat_Suc)
 156.701 +done
 156.702 +
 156.703 +text{* alternative definition for Bseq *}
 156.704 +lemma Bseq_iff: "Bseq X = (\<exists>N. \<forall>n. norm (X n) \<le> real(Suc N))"
 156.705 +apply (simp add: Bseq_def)
 156.706 +apply (simp (no_asm) add: lemma_NBseq_def)
 156.707 +done
 156.708 +
 156.709 +lemma lemma_NBseq_def2:
 156.710 +     "(\<exists>K > 0. \<forall>n. norm (X n) \<le> K) = (\<exists>N. \<forall>n. norm (X n) < real(Suc N))"
 156.711 +apply (subst lemma_NBseq_def, auto)
 156.712 +apply (rule_tac x = "Suc N" in exI)
 156.713 +apply (rule_tac [2] x = N in exI)
 156.714 +apply (auto simp add: real_of_nat_Suc)
 156.715 + prefer 2 apply (blast intro: order_less_imp_le)
 156.716 +apply (drule_tac x = n in spec, simp)
 156.717 +done
 156.718 +
 156.719 +(* yet another definition for Bseq *)
 156.720 +lemma Bseq_iff1a: "Bseq X = (\<exists>N. \<forall>n. norm (X n) < real(Suc N))"
 156.721 +by (simp add: Bseq_def lemma_NBseq_def2)
 156.722 +
 156.723 +subsubsection{*Upper Bounds and Lubs of Bounded Sequences*}
 156.724 +
 156.725 +lemma Bseq_isUb:
 156.726 +  "!!(X::nat=>real). Bseq X ==> \<exists>U. isUb (UNIV::real set) {x. \<exists>n. X n = x} U"
 156.727 +by (auto intro: isUbI setleI simp add: Bseq_def abs_le_iff)
 156.728 +
 156.729 +
 156.730 +text{* Use completeness of reals (supremum property)
 156.731 +   to show that any bounded sequence has a least upper bound*}
 156.732 +
 156.733 +lemma Bseq_isLub:
 156.734 +  "!!(X::nat=>real). Bseq X ==>
 156.735 +   \<exists>U. isLub (UNIV::real set) {x. \<exists>n. X n = x} U"
 156.736 +by (blast intro: reals_complete Bseq_isUb)
 156.737 +
 156.738 +subsubsection{*A Bounded and Monotonic Sequence Converges*}
 156.739 +
 156.740 +lemma lemma_converg1:
 156.741 +     "!!(X::nat=>real). [| \<forall>m. \<forall> n \<ge> m. X m \<le> X n;
 156.742 +                  isLub (UNIV::real set) {x. \<exists>n. X n = x} (X ma)
 156.743 +               |] ==> \<forall>n \<ge> ma. X n = X ma"
 156.744 +apply safe
 156.745 +apply (drule_tac y = "X n" in isLubD2)
 156.746 +apply (blast dest: order_antisym)+
 156.747 +done
 156.748 +
 156.749 +text{* The best of both worlds: Easier to prove this result as a standard
 156.750 +   theorem and then use equivalence to "transfer" it into the
 156.751 +   equivalent nonstandard form if needed!*}
 156.752 +
 156.753 +lemma Bmonoseq_LIMSEQ: "\<forall>n. m \<le> n --> X n = X m ==> \<exists>L. (X ----> L)"
 156.754 +apply (simp add: LIMSEQ_def)
 156.755 +apply (rule_tac x = "X m" in exI, safe)
 156.756 +apply (rule_tac x = m in exI, safe)
 156.757 +apply (drule spec, erule impE, auto)
 156.758 +done
 156.759 +
 156.760 +lemma lemma_converg2:
 156.761 +   "!!(X::nat=>real).
 156.762 +    [| \<forall>m. X m ~= U;  isLub UNIV {x. \<exists>n. X n = x} U |] ==> \<forall>m. X m < U"
 156.763 +apply safe
 156.764 +apply (drule_tac y = "X m" in isLubD2)
 156.765 +apply (auto dest!: order_le_imp_less_or_eq)
 156.766 +done
 156.767 +
 156.768 +lemma lemma_converg3: "!!(X ::nat=>real). \<forall>m. X m \<le> U ==> isUb UNIV {x. \<exists>n. X n = x} U"
 156.769 +by (rule setleI [THEN isUbI], auto)
 156.770 +
 156.771 +text{* FIXME: @{term "U - T < U"} is redundant *}
 156.772 +lemma lemma_converg4: "!!(X::nat=> real).
 156.773 +               [| \<forall>m. X m ~= U;
 156.774 +                  isLub UNIV {x. \<exists>n. X n = x} U;
 156.775 +                  0 < T;
 156.776 +                  U + - T < U
 156.777 +               |] ==> \<exists>m. U + -T < X m & X m < U"
 156.778 +apply (drule lemma_converg2, assumption)
 156.779 +apply (rule ccontr, simp)
 156.780 +apply (simp add: linorder_not_less)
 156.781 +apply (drule lemma_converg3)
 156.782 +apply (drule isLub_le_isUb, assumption)
 156.783 +apply (auto dest: order_less_le_trans)
 156.784 +done
 156.785 +
 156.786 +text{*A standard proof of the theorem for monotone increasing sequence*}
 156.787 +
 156.788 +lemma Bseq_mono_convergent:
 156.789 +     "[| Bseq X; \<forall>m. \<forall>n \<ge> m. X m \<le> X n |] ==> convergent (X::nat=>real)"
 156.790 +apply (simp add: convergent_def)
 156.791 +apply (frule Bseq_isLub, safe)
 156.792 +apply (case_tac "\<exists>m. X m = U", auto)
 156.793 +apply (blast dest: lemma_converg1 Bmonoseq_LIMSEQ)
 156.794 +(* second case *)
 156.795 +apply (rule_tac x = U in exI)
 156.796 +apply (subst LIMSEQ_iff, safe)
 156.797 +apply (frule lemma_converg2, assumption)
 156.798 +apply (drule lemma_converg4, auto)
 156.799 +apply (rule_tac x = m in exI, safe)
 156.800 +apply (subgoal_tac "X m \<le> X n")
 156.801 + prefer 2 apply blast
 156.802 +apply (drule_tac x=n and P="%m. X m < U" in spec, arith)
 156.803 +done
 156.804 +
 156.805 +lemma Bseq_minus_iff: "Bseq (%n. -(X n)) = Bseq X"
 156.806 +by (simp add: Bseq_def)
 156.807 +
 156.808 +text{*Main monotonicity theorem*}
 156.809 +lemma Bseq_monoseq_convergent: "[| Bseq X; monoseq X |] ==> convergent X"
 156.810 +apply (simp add: monoseq_def, safe)
 156.811 +apply (rule_tac [2] convergent_minus_iff [THEN ssubst])
 156.812 +apply (drule_tac [2] Bseq_minus_iff [THEN ssubst])
 156.813 +apply (auto intro!: Bseq_mono_convergent)
 156.814 +done
 156.815 +
 156.816 +subsubsection{*A Few More Equivalence Theorems for Boundedness*}
 156.817 +
 156.818 +text{*alternative formulation for boundedness*}
 156.819 +lemma Bseq_iff2: "Bseq X = (\<exists>k > 0. \<exists>x. \<forall>n. norm (X(n) + -x) \<le> k)"
 156.820 +apply (unfold Bseq_def, safe)
 156.821 +apply (rule_tac [2] x = "k + norm x" in exI)
 156.822 +apply (rule_tac x = K in exI, simp)
 156.823 +apply (rule exI [where x = 0], auto)
 156.824 +apply (erule order_less_le_trans, simp)
 156.825 +apply (drule_tac x=n in spec, fold diff_def)
 156.826 +apply (drule order_trans [OF norm_triangle_ineq2])
 156.827 +apply simp
 156.828 +done
 156.829 +
 156.830 +text{*alternative formulation for boundedness*}
 156.831 +lemma Bseq_iff3: "Bseq X = (\<exists>k > 0. \<exists>N. \<forall>n. norm(X(n) + -X(N)) \<le> k)"
 156.832 +apply safe
 156.833 +apply (simp add: Bseq_def, safe)
 156.834 +apply (rule_tac x = "K + norm (X N)" in exI)
 156.835 +apply auto
 156.836 +apply (erule order_less_le_trans, simp)
 156.837 +apply (rule_tac x = N in exI, safe)
 156.838 +apply (drule_tac x = n in spec)
 156.839 +apply (rule order_trans [OF norm_triangle_ineq], simp)
 156.840 +apply (auto simp add: Bseq_iff2)
 156.841 +done
 156.842 +
 156.843 +lemma BseqI2: "(\<forall>n. k \<le> f n & f n \<le> (K::real)) ==> Bseq f"
 156.844 +apply (simp add: Bseq_def)
 156.845 +apply (rule_tac x = " (\<bar>k\<bar> + \<bar>K\<bar>) + 1" in exI, auto)
 156.846 +apply (drule_tac x = n in spec, arith)
 156.847 +done
 156.848 +
 156.849 +
 156.850 +subsection {* Cauchy Sequences *}
 156.851 +
 156.852 +lemma CauchyI:
 156.853 +  "(\<And>e. 0 < e \<Longrightarrow> \<exists>M. \<forall>m\<ge>M. \<forall>n\<ge>M. norm (X m - X n) < e) \<Longrightarrow> Cauchy X"
 156.854 +by (simp add: Cauchy_def)
 156.855 +
 156.856 +lemma CauchyD:
 156.857 +  "\<lbrakk>Cauchy X; 0 < e\<rbrakk> \<Longrightarrow> \<exists>M. \<forall>m\<ge>M. \<forall>n\<ge>M. norm (X m - X n) < e"
 156.858 +by (simp add: Cauchy_def)
 156.859 +
 156.860 +subsubsection {* Cauchy Sequences are Bounded *}
 156.861 +
 156.862 +text{*A Cauchy sequence is bounded -- this is the standard
 156.863 +  proof mechanization rather than the nonstandard proof*}
 156.864 +
 156.865 +lemma lemmaCauchy: "\<forall>n \<ge> M. norm (X M - X n) < (1::real)
 156.866 +          ==>  \<forall>n \<ge> M. norm (X n :: 'a::real_normed_vector) < 1 + norm (X M)"
 156.867 +apply (clarify, drule spec, drule (1) mp)
 156.868 +apply (simp only: norm_minus_commute)
 156.869 +apply (drule order_le_less_trans [OF norm_triangle_ineq2])
 156.870 +apply simp
 156.871 +done
 156.872 +
 156.873 +lemma Cauchy_Bseq: "Cauchy X ==> Bseq X"
 156.874 +apply (simp add: Cauchy_def)
 156.875 +apply (drule spec, drule mp, rule zero_less_one, safe)
 156.876 +apply (drule_tac x="M" in spec, simp)
 156.877 +apply (drule lemmaCauchy)
 156.878 +apply (rule_tac k="M" in Bseq_offset)
 156.879 +apply (simp add: Bseq_def)
 156.880 +apply (rule_tac x="1 + norm (X M)" in exI)
 156.881 +apply (rule conjI, rule order_less_le_trans [OF zero_less_one], simp)
 156.882 +apply (simp add: order_less_imp_le)
 156.883 +done
 156.884 +
 156.885 +subsubsection {* Cauchy Sequences are Convergent *}
 156.886 +
 156.887 +axclass banach \<subseteq> real_normed_vector
 156.888 +  Cauchy_convergent: "Cauchy X \<Longrightarrow> convergent X"
 156.889 +
 156.890 +theorem LIMSEQ_imp_Cauchy:
 156.891 +  assumes X: "X ----> a" shows "Cauchy X"
 156.892 +proof (rule CauchyI)
 156.893 +  fix e::real assume "0 < e"
 156.894 +  hence "0 < e/2" by simp
 156.895 +  with X have "\<exists>N. \<forall>n\<ge>N. norm (X n - a) < e/2" by (rule LIMSEQ_D)
 156.896 +  then obtain N where N: "\<forall>n\<ge>N. norm (X n - a) < e/2" ..
 156.897 +  show "\<exists>N. \<forall>m\<ge>N. \<forall>n\<ge>N. norm (X m - X n) < e"
 156.898 +  proof (intro exI allI impI)
 156.899 +    fix m assume "N \<le> m"
 156.900 +    hence m: "norm (X m - a) < e/2" using N by fast
 156.901 +    fix n assume "N \<le> n"
 156.902 +    hence n: "norm (X n - a) < e/2" using N by fast
 156.903 +    have "norm (X m - X n) = norm ((X m - a) - (X n - a))" by simp
 156.904 +    also have "\<dots> \<le> norm (X m - a) + norm (X n - a)"
 156.905 +      by (rule norm_triangle_ineq4)
 156.906 +    also from m n have "\<dots> < e" by(simp add:field_simps)
 156.907 +    finally show "norm (X m - X n) < e" .
 156.908 +  qed
 156.909 +qed
 156.910 +
 156.911 +lemma convergent_Cauchy: "convergent X \<Longrightarrow> Cauchy X"
 156.912 +unfolding convergent_def
 156.913 +by (erule exE, erule LIMSEQ_imp_Cauchy)
 156.914 +
 156.915 +text {*
 156.916 +Proof that Cauchy sequences converge based on the one from
 156.917 +http://pirate.shu.edu/~wachsmut/ira/numseq/proofs/cauconv.html
 156.918 +*}
 156.919 +
 156.920 +text {*
 156.921 +  If sequence @{term "X"} is Cauchy, then its limit is the lub of
 156.922 +  @{term "{r::real. \<exists>N. \<forall>n\<ge>N. r < X n}"}
 156.923 +*}
 156.924 +
 156.925 +lemma isUb_UNIV_I: "(\<And>y. y \<in> S \<Longrightarrow> y \<le> u) \<Longrightarrow> isUb UNIV S u"
 156.926 +by (simp add: isUbI setleI)
 156.927 +
 156.928 +lemma real_abs_diff_less_iff:
 156.929 +  "(\<bar>x - a\<bar> < (r::real)) = (a - r < x \<and> x < a + r)"
 156.930 +by auto
 156.931 +
 156.932 +locale real_Cauchy =
 156.933 +  fixes X :: "nat \<Rightarrow> real"
 156.934 +  assumes X: "Cauchy X"
 156.935 +  fixes S :: "real set"
 156.936 +  defines S_def: "S \<equiv> {x::real. \<exists>N. \<forall>n\<ge>N. x < X n}"
 156.937 +
 156.938 +lemma real_CauchyI:
 156.939 +  assumes "Cauchy X"
 156.940 +  shows "real_Cauchy X"
 156.941 +  proof qed (fact assms)
 156.942 +
 156.943 +lemma (in real_Cauchy) mem_S: "\<forall>n\<ge>N. x < X n \<Longrightarrow> x \<in> S"
 156.944 +by (unfold S_def, auto)
 156.945 +
 156.946 +lemma (in real_Cauchy) bound_isUb:
 156.947 +  assumes N: "\<forall>n\<ge>N. X n < x"
 156.948 +  shows "isUb UNIV S x"
 156.949 +proof (rule isUb_UNIV_I)
 156.950 +  fix y::real assume "y \<in> S"
 156.951 +  hence "\<exists>M. \<forall>n\<ge>M. y < X n"
 156.952 +    by (simp add: S_def)
 156.953 +  then obtain M where "\<forall>n\<ge>M. y < X n" ..
 156.954 +  hence "y < X (max M N)" by simp
 156.955 +  also have "\<dots> < x" using N by simp
 156.956 +  finally show "y \<le> x"
 156.957 +    by (rule order_less_imp_le)
 156.958 +qed
 156.959 +
 156.960 +lemma (in real_Cauchy) isLub_ex: "\<exists>u. isLub UNIV S u"
 156.961 +proof (rule reals_complete)
 156.962 +  obtain N where "\<forall>m\<ge>N. \<forall>n\<ge>N. norm (X m - X n) < 1"
 156.963 +    using CauchyD [OF X zero_less_one] by fast
 156.964 +  hence N: "\<forall>n\<ge>N. norm (X n - X N) < 1" by simp
 156.965 +  show "\<exists>x. x \<in> S"
 156.966 +  proof
 156.967 +    from N have "\<forall>n\<ge>N. X N - 1 < X n"
 156.968 +      by (simp add: real_abs_diff_less_iff)
 156.969 +    thus "X N - 1 \<in> S" by (rule mem_S)
 156.970 +  qed
 156.971 +  show "\<exists>u. isUb UNIV S u"
 156.972 +  proof
 156.973 +    from N have "\<forall>n\<ge>N. X n < X N + 1"
 156.974 +      by (simp add: real_abs_diff_less_iff)
 156.975 +    thus "isUb UNIV S (X N + 1)"
 156.976 +      by (rule bound_isUb)
 156.977 +  qed
 156.978 +qed
 156.979 +
 156.980 +lemma (in real_Cauchy) isLub_imp_LIMSEQ:
 156.981 +  assumes x: "isLub UNIV S x"
 156.982 +  shows "X ----> x"
 156.983 +proof (rule LIMSEQ_I)
 156.984 +  fix r::real assume "0 < r"
 156.985 +  hence r: "0 < r/2" by simp
 156.986 +  obtain N where "\<forall>n\<ge>N. \<forall>m\<ge>N. norm (X n - X m) < r/2"
 156.987 +    using CauchyD [OF X r] by fast
 156.988 +  hence "\<forall>n\<ge>N. norm (X n - X N) < r/2" by simp
 156.989 +  hence N: "\<forall>n\<ge>N. X N - r/2 < X n \<and> X n < X N + r/2"
 156.990 +    by (simp only: real_norm_def real_abs_diff_less_iff)
 156.991 +
 156.992 +  from N have "\<forall>n\<ge>N. X N - r/2 < X n" by fast
 156.993 +  hence "X N - r/2 \<in> S" by (rule mem_S)
 156.994 +  hence 1: "X N - r/2 \<le> x" using x isLub_isUb isUbD by fast
 156.995 +
 156.996 +  from N have "\<forall>n\<ge>N. X n < X N + r/2" by fast
 156.997 +  hence "isUb UNIV S (X N + r/2)" by (rule bound_isUb)
 156.998 +  hence 2: "x \<le> X N + r/2" using x isLub_le_isUb by fast
 156.999 +
156.1000 +  show "\<exists>N. \<forall>n\<ge>N. norm (X n - x) < r"
156.1001 +  proof (intro exI allI impI)
156.1002 +    fix n assume n: "N \<le> n"
156.1003 +    from N n have "X n < X N + r/2" and "X N - r/2 < X n" by simp+
156.1004 +    thus "norm (X n - x) < r" using 1 2
156.1005 +      by (simp add: real_abs_diff_less_iff)
156.1006 +  qed
156.1007 +qed
156.1008 +
156.1009 +lemma (in real_Cauchy) LIMSEQ_ex: "\<exists>x. X ----> x"
156.1010 +proof -
156.1011 +  obtain x where "isLub UNIV S x"
156.1012 +    using isLub_ex by fast
156.1013 +  hence "X ----> x"
156.1014 +    by (rule isLub_imp_LIMSEQ)
156.1015 +  thus ?thesis ..
156.1016 +qed
156.1017 +
156.1018 +lemma real_Cauchy_convergent:
156.1019 +  fixes X :: "nat \<Rightarrow> real"
156.1020 +  shows "Cauchy X \<Longrightarrow> convergent X"
156.1021 +unfolding convergent_def
156.1022 +by (rule real_Cauchy.LIMSEQ_ex)
156.1023 + (rule real_CauchyI)
156.1024 +
156.1025 +instance real :: banach
156.1026 +by intro_classes (rule real_Cauchy_convergent)
156.1027 +
156.1028 +lemma Cauchy_convergent_iff:
156.1029 +  fixes X :: "nat \<Rightarrow> 'a::banach"
156.1030 +  shows "Cauchy X = convergent X"
156.1031 +by (fast intro: Cauchy_convergent convergent_Cauchy)
156.1032 +
156.1033 +
156.1034 +subsection {* Power Sequences *}
156.1035 +
156.1036 +text{*The sequence @{term "x^n"} tends to 0 if @{term "0\<le>x"} and @{term
156.1037 +"x<1"}.  Proof will use (NS) Cauchy equivalence for convergence and
156.1038 +  also fact that bounded and monotonic sequence converges.*}
156.1039 +
156.1040 +lemma Bseq_realpow: "[| 0 \<le> (x::real); x \<le> 1 |] ==> Bseq (%n. x ^ n)"
156.1041 +apply (simp add: Bseq_def)
156.1042 +apply (rule_tac x = 1 in exI)
156.1043 +apply (simp add: power_abs)
156.1044 +apply (auto dest: power_mono)
156.1045 +done
156.1046 +
156.1047 +lemma monoseq_realpow: "[| 0 \<le> x; x \<le> 1 |] ==> monoseq (%n. x ^ n)"
156.1048 +apply (clarify intro!: mono_SucI2)
156.1049 +apply (cut_tac n = n and N = "Suc n" and a = x in power_decreasing, auto)
156.1050 +done
156.1051 +
156.1052 +lemma convergent_realpow:
156.1053 +  "[| 0 \<le> (x::real); x \<le> 1 |] ==> convergent (%n. x ^ n)"
156.1054 +by (blast intro!: Bseq_monoseq_convergent Bseq_realpow monoseq_realpow)
156.1055 +
156.1056 +lemma LIMSEQ_inverse_realpow_zero_lemma:
156.1057 +  fixes x :: real
156.1058 +  assumes x: "0 \<le> x"
156.1059 +  shows "real n * x + 1 \<le> (x + 1) ^ n"
156.1060 +apply (induct n)
156.1061 +apply simp
156.1062 +apply simp
156.1063 +apply (rule order_trans)
156.1064 +prefer 2
156.1065 +apply (erule mult_left_mono)
156.1066 +apply (rule add_increasing [OF x], simp)
156.1067 +apply (simp add: real_of_nat_Suc)
156.1068 +apply (simp add: ring_distribs)
156.1069 +apply (simp add: mult_nonneg_nonneg x)
156.1070 +done
156.1071 +
156.1072 +lemma LIMSEQ_inverse_realpow_zero:
156.1073 +  "1 < (x::real) \<Longrightarrow> (\<lambda>n. inverse (x ^ n)) ----> 0"
156.1074 +proof (rule LIMSEQ_inverse_zero [rule_format])
156.1075 +  fix y :: real
156.1076 +  assume x: "1 < x"
156.1077 +  hence "0 < x - 1" by simp
156.1078 +  hence "\<forall>y. \<exists>N::nat. y < real N * (x - 1)"
156.1079 +    by (rule reals_Archimedean3)
156.1080 +  hence "\<exists>N::nat. y < real N * (x - 1)" ..
156.1081 +  then obtain N::nat where "y < real N * (x - 1)" ..
156.1082 +  also have "\<dots> \<le> real N * (x - 1) + 1" by simp
156.1083 +  also have "\<dots> \<le> (x - 1 + 1) ^ N"
156.1084 +    by (rule LIMSEQ_inverse_realpow_zero_lemma, cut_tac x, simp)
156.1085 +  also have "\<dots> = x ^ N" by simp
156.1086 +  finally have "y < x ^ N" .
156.1087 +  hence "\<forall>n\<ge>N. y < x ^ n"
156.1088 +    apply clarify
156.1089 +    apply (erule order_less_le_trans)
156.1090 +    apply (erule power_increasing)
156.1091 +    apply (rule order_less_imp_le [OF x])
156.1092 +    done
156.1093 +  thus "\<exists>N. \<forall>n\<ge>N. y < x ^ n" ..
156.1094 +qed
156.1095 +
156.1096 +lemma LIMSEQ_realpow_zero:
156.1097 +  "\<lbrakk>0 \<le> (x::real); x < 1\<rbrakk> \<Longrightarrow> (\<lambda>n. x ^ n) ----> 0"
156.1098 +proof (cases)
156.1099 +  assume "x = 0"
156.1100 +  hence "(\<lambda>n. x ^ Suc n) ----> 0" by (simp add: LIMSEQ_const)
156.1101 +  thus ?thesis by (rule LIMSEQ_imp_Suc)
156.1102 +next
156.1103 +  assume "0 \<le> x" and "x \<noteq> 0"
156.1104 +  hence x0: "0 < x" by simp
156.1105 +  assume x1: "x < 1"
156.1106 +  from x0 x1 have "1 < inverse x"
156.1107 +    by (rule real_inverse_gt_one)
156.1108 +  hence "(\<lambda>n. inverse (inverse x ^ n)) ----> 0"
156.1109 +    by (rule LIMSEQ_inverse_realpow_zero)
156.1110 +  thus ?thesis by (simp add: power_inverse)
156.1111 +qed
156.1112 +
156.1113 +lemma LIMSEQ_power_zero:
156.1114 +  fixes x :: "'a::{real_normed_algebra_1,recpower}"
156.1115 +  shows "norm x < 1 \<Longrightarrow> (\<lambda>n. x ^ n) ----> 0"
156.1116 +apply (drule LIMSEQ_realpow_zero [OF norm_ge_zero])
156.1117 +apply (simp only: LIMSEQ_Zseq_iff, erule Zseq_le)
156.1118 +apply (simp add: power_abs norm_power_ineq)
156.1119 +done
156.1120 +
156.1121 +lemma LIMSEQ_divide_realpow_zero:
156.1122 +  "1 < (x::real) ==> (%n. a / (x ^ n)) ----> 0"
156.1123 +apply (cut_tac a = a and x1 = "inverse x" in
156.1124 +        LIMSEQ_mult [OF LIMSEQ_const LIMSEQ_realpow_zero])
156.1125 +apply (auto simp add: divide_inverse power_inverse)
156.1126 +apply (simp add: inverse_eq_divide pos_divide_less_eq)
156.1127 +done
156.1128 +
156.1129 +text{*Limit of @{term "c^n"} for @{term"\<bar>c\<bar> < 1"}*}
156.1130 +
156.1131 +lemma LIMSEQ_rabs_realpow_zero: "\<bar>c\<bar> < (1::real) ==> (%n. \<bar>c\<bar> ^ n) ----> 0"
156.1132 +by (rule LIMSEQ_realpow_zero [OF abs_ge_zero])
156.1133 +
156.1134 +lemma LIMSEQ_rabs_realpow_zero2: "\<bar>c\<bar> < (1::real) ==> (%n. c ^ n) ----> 0"
156.1135 +apply (rule LIMSEQ_rabs_zero [THEN iffD1])
156.1136 +apply (auto intro: LIMSEQ_rabs_realpow_zero simp add: power_abs)
156.1137 +done
156.1138 +
156.1139 +end
   157.1 --- a/src/HOL/Series.thy	Tue Dec 30 08:18:54 2008 +0100
   157.2 +++ b/src/HOL/Series.thy	Tue Dec 30 11:10:01 2008 +0100
   157.3 @@ -10,7 +10,7 @@
   157.4  header{*Finite Summation and Infinite Series*}
   157.5  
   157.6  theory Series
   157.7 -imports "~~/src/HOL/Hyperreal/SEQ"
   157.8 +imports SEQ
   157.9  begin
  157.10  
  157.11  definition
   158.1 --- a/src/HOL/Sum_Type.thy	Tue Dec 30 08:18:54 2008 +0100
   158.2 +++ b/src/HOL/Sum_Type.thy	Tue Dec 30 11:10:01 2008 +0100
   158.3 @@ -120,29 +120,6 @@
   158.4  by (blast dest!: Inr_inject)
   158.5  
   158.6  
   158.7 -subsection {* Projections *}
   158.8 -
   158.9 -definition 
  158.10 -  "sum_case f g x =
  158.11 -  (if (\<exists>!y. x = Inl y) 
  158.12 -  then f (THE y. x = Inl y) 
  158.13 -  else g (THE y. x = Inr y))"
  158.14 -definition "Projl x = sum_case id undefined x"
  158.15 -definition "Projr x = sum_case undefined id x"
  158.16 -
  158.17 -lemma sum_cases[simp]: 
  158.18 -  "sum_case f g (Inl x) = f x"
  158.19 -  "sum_case f g (Inr y) = g y"
  158.20 -  unfolding sum_case_def
  158.21 -  by auto
  158.22 -
  158.23 -lemma Projl_Inl[simp]: "Projl (Inl x) = x"
  158.24 -  unfolding Projl_def by simp
  158.25 -
  158.26 -lemma Projr_Inr[simp]: "Projr (Inr x) = x"
  158.27 -  unfolding Projr_def by simp
  158.28 -
  158.29 -
  158.30  subsection{*The Disjoint Sum of Sets*}
  158.31  
  158.32  (** Introduction rules for the injections **)
   159.1 --- a/src/HOL/Tools/atp_manager.ML	Tue Dec 30 08:18:54 2008 +0100
   159.2 +++ b/src/HOL/Tools/atp_manager.ML	Tue Dec 30 11:10:01 2008 +0100
   159.3 @@ -1,5 +1,4 @@
   159.4  (*  Title:      HOL/Tools/atp_manager.ML
   159.5 -    ID:         $Id$
   159.6      Author:     Fabian Immler, TU Muenchen
   159.7  
   159.8  ATP threads are registered here.
   159.9 @@ -19,6 +18,7 @@
  159.10    val set_timeout: int -> unit
  159.11    val kill: unit -> unit
  159.12    val info: unit -> unit
  159.13 +  val messages: int option -> unit
  159.14    type prover = int -> Proof.state -> bool * string
  159.15    val add_prover: string -> prover -> theory -> theory
  159.16    val print_provers: theory -> unit
  159.17 @@ -30,6 +30,9 @@
  159.18  
  159.19  (** preferences **)
  159.20  
  159.21 +val message_store_limit = 20;
  159.22 +val message_display_limit = 5;
  159.23 +
  159.24  local
  159.25  
  159.26  val atps = ref "e";
  159.27 @@ -85,13 +88,14 @@
  159.28   {timeout_heap: ThreadHeap.T,
  159.29    oldest_heap: ThreadHeap.T,
  159.30    active: (Thread.thread * (Time.time * Time.time * string)) list,
  159.31 -  cancelling: (Thread.thread * (Time.time * Time.time * string)) list};
  159.32 +  cancelling: (Thread.thread * (Time.time * Time.time * string)) list,
  159.33 +  messages: string list};
  159.34  
  159.35 -fun make_state timeout_heap oldest_heap active cancelling =
  159.36 +fun make_state timeout_heap oldest_heap active cancelling messages =
  159.37    State {timeout_heap = timeout_heap, oldest_heap = oldest_heap,
  159.38 -    active = active, cancelling = cancelling};
  159.39 +    active = active, cancelling = cancelling, messages = messages};
  159.40  
  159.41 -val state = Synchronized.var "atp_manager" (make_state ThreadHeap.empty ThreadHeap.empty [] []);
  159.42 +val state = Synchronized.var "atp_manager" (make_state ThreadHeap.empty ThreadHeap.empty [] [] []);
  159.43  
  159.44  
  159.45  (* the managing thread *)
  159.46 @@ -100,34 +104,31 @@
  159.47  val managing_thread = ref (NONE: Thread.thread option);
  159.48  
  159.49  
  159.50 -(* unregister thread from thread manager -- move to cancelling *)
  159.51 +(* unregister thread *)
  159.52  
  159.53  fun unregister (success, message) thread = Synchronized.change_result state
  159.54 -  (fn State {timeout_heap, oldest_heap, active, cancelling} =>
  159.55 -    let
  159.56 -      val info = lookup_thread active thread
  159.57 +  (fn state as State {timeout_heap, oldest_heap, active, cancelling, messages} =>
  159.58 +    (case lookup_thread active thread of
  159.59 +      SOME (birthtime, _, description) =>
  159.60 +        let
  159.61 +          val (group, active') =
  159.62 +            if success then List.partition (fn (_, (tb, _, _)) => tb = birthtime) active
  159.63 +            else List.partition (fn (th, _) => Thread.equal (th, thread)) active
  159.64 +          val others = delete_thread thread group
  159.65  
  159.66 -      (* get birthtime of unregistering thread if successful - for group-killing*)
  159.67 -      val birthtime = case info of NONE => Time.zeroTime
  159.68 -        | SOME (tb, _, _) => if success then tb else Time.zeroTime
  159.69 +          val now = Time.now ()
  159.70 +          val cancelling' =
  159.71 +            fold (fn (th, (tb, _, desc)) => update_thread (th, (tb, now, desc))) others cancelling
  159.72  
  159.73 -      (* move unregistering thread to cancelling *)
  159.74 -      val active' = delete_thread thread active
  159.75 -      val cancelling' = case info of NONE => cancelling
  159.76 -        | SOME (tb, _, desc) => update_thread (thread, (tb, Time.now (), desc)) cancelling
  159.77 -
  159.78 -      (* move all threads of the same group to cancelling *)
  159.79 -      val group_threads = active |> map_filter (fn (th, (tb, _, desc)) =>
  159.80 -          if tb = birthtime then SOME (th, (tb, Time.now (), desc)) else NONE)
  159.81 -      val active'' = filter_out (fn (_, (tb, _, _)) => tb = birthtime) active'
  159.82 -      val cancelling'' = append group_threads cancelling'
  159.83 -
  159.84 -      (* message for user *)
  159.85 -      val message' = case info of NONE => ""
  159.86 -        | SOME (_, _, desc) => "Sledgehammer: " ^ desc ^ "\n" ^ message ^
  159.87 -          (if null group_threads then ""
  159.88 -           else "\nInterrupted " ^ string_of_int (length group_threads - 1) ^ " other group members")
  159.89 -    in (message', make_state timeout_heap oldest_heap active'' cancelling'') end);
  159.90 +          val msg = description ^ "\n" ^ message
  159.91 +          val message' = "Sledgehammer: " ^ msg ^
  159.92 +            (if null others then ""
  159.93 +             else "\nInterrupted " ^ string_of_int (length others) ^ " other group members")
  159.94 +          val messages' = msg ::
  159.95 +            (if length messages <= message_store_limit then messages
  159.96 +             else #1 (chop message_store_limit messages))
  159.97 +        in (message', make_state timeout_heap oldest_heap active' cancelling' messages') end
  159.98 +    | NONE => ("", state)));
  159.99  
 159.100  
 159.101  (* kill excessive atp threads *)
 159.102 @@ -140,12 +141,13 @@
 159.103  
 159.104  fun kill_oldest () =
 159.105    let exception Unchanged in
 159.106 -    Synchronized.change_result state (fn State {timeout_heap, oldest_heap, active, cancelling} =>
 159.107 +    Synchronized.change_result state
 159.108 +      (fn State {timeout_heap, oldest_heap, active, cancelling, messages} =>
 159.109          if ThreadHeap.is_empty oldest_heap orelse not (excessive_atps active)
 159.110          then raise Unchanged
 159.111          else
 159.112            let val ((_, oldest_thread), oldest_heap') = ThreadHeap.min_elem oldest_heap
 159.113 -          in (oldest_thread, make_state timeout_heap oldest_heap' active cancelling) end)
 159.114 +          in (oldest_thread, make_state timeout_heap oldest_heap' active cancelling messages) end)
 159.115        |> (priority o unregister (false, "Interrupted (maximum number of ATPs exceeded)"))
 159.116      handle Unchanged => ()
 159.117    end;
 159.118 @@ -175,7 +177,7 @@
 159.119          | SOME (time, _) => SOME time)
 159.120  
 159.121        (* action: cancel find threads whose timeout is reached, and interrupt cancelling threads *)
 159.122 -      fun action (State {timeout_heap, oldest_heap, active, cancelling}) =
 159.123 +      fun action (State {timeout_heap, oldest_heap, active, cancelling, messages}) =
 159.124          let val (timeout_threads, timeout_heap') =
 159.125            ThreadHeap.upto (Time.now (), Thread.self ()) timeout_heap
 159.126          in
 159.127 @@ -185,7 +187,7 @@
 159.128              let
 159.129                val _ = List.app (SimpleThread.interrupt o #1) cancelling
 159.130                val cancelling' = filter (Thread.isActive o #1) cancelling
 159.131 -              val state' = make_state timeout_heap' oldest_heap active cancelling'
 159.132 +              val state' = make_state timeout_heap' oldest_heap active cancelling' messages
 159.133              in SOME (map #2 timeout_threads, state') end
 159.134          end
 159.135      in
 159.136 @@ -203,12 +205,13 @@
 159.137  
 159.138  fun register birthtime deadtime (thread, desc) =
 159.139   (check_thread_manager ();
 159.140 -  Synchronized.change state (fn State {timeout_heap, oldest_heap, active, cancelling} =>
 159.141 -    let
 159.142 -      val timeout_heap' = ThreadHeap.insert (deadtime, thread) timeout_heap
 159.143 -      val oldest_heap' = ThreadHeap.insert (birthtime, thread) oldest_heap
 159.144 -      val active' = update_thread (thread, (birthtime, deadtime, desc)) active
 159.145 -    in make_state timeout_heap' oldest_heap' active' cancelling end));
 159.146 +  Synchronized.change state
 159.147 +    (fn State {timeout_heap, oldest_heap, active, cancelling, messages} =>
 159.148 +      let
 159.149 +        val timeout_heap' = ThreadHeap.insert (deadtime, thread) timeout_heap
 159.150 +        val oldest_heap' = ThreadHeap.insert (birthtime, thread) oldest_heap
 159.151 +        val active' = update_thread (thread, (birthtime, deadtime, desc)) active
 159.152 +      in make_state timeout_heap' oldest_heap' active' cancelling messages end));
 159.153  
 159.154  
 159.155  
 159.156 @@ -217,16 +220,17 @@
 159.157  (* kill: move all threads to cancelling *)
 159.158  
 159.159  fun kill () = Synchronized.change state
 159.160 -  (fn State {timeout_heap, oldest_heap, active, cancelling} =>
 159.161 +  (fn State {timeout_heap, oldest_heap, active, cancelling, messages} =>
 159.162      let val formerly_active = map (fn (th, (tb, _, desc)) => (th, (tb, Time.now (), desc))) active
 159.163 -    in make_state timeout_heap oldest_heap [] (formerly_active @ cancelling) end);
 159.164 +    in make_state timeout_heap oldest_heap [] (formerly_active @ cancelling) messages end);
 159.165  
 159.166  
 159.167 -(* info: information on running threads *)
 159.168 +(* ATP info *)
 159.169  
 159.170  fun info () =
 159.171    let
 159.172 -    val State {timeout_heap, oldest_heap, active, cancelling} = Synchronized.value state
 159.173 +    val State {active, cancelling, ...} = Synchronized.value state
 159.174 +
 159.175      fun running_info (_, (birth_time, dead_time, desc)) = "Running: "
 159.176          ^ (string_of_int o Time.toSeconds) (Time.- (Time.now (), birth_time))
 159.177          ^ " s  --  "
 159.178 @@ -235,6 +239,7 @@
 159.179      fun cancelling_info (_, (_, dead_time, desc)) = "Trying to interrupt thread since "
 159.180          ^ (string_of_int o Time.toSeconds) (Time.- (Time.now (), dead_time))
 159.181          ^ " s:\n" ^ desc
 159.182 +
 159.183      val running =
 159.184        if null active then "No ATPs running."
 159.185        else space_implode "\n\n" ("Running ATPs:" :: map running_info active)
 159.186 @@ -242,8 +247,17 @@
 159.187        if null cancelling then ""
 159.188        else space_implode "\n\n"
 159.189          ("Trying to interrupt the following ATPs:" :: map cancelling_info cancelling)
 159.190 +
 159.191    in writeln (running ^ "\n" ^ interrupting) end;
 159.192  
 159.193 +fun messages opt_limit =
 159.194 +  let
 159.195 +    val limit = the_default message_display_limit opt_limit;
 159.196 +    val State {messages = msgs, ...} = Synchronized.value state
 159.197 +    val header = "Recent ATP messages" ^
 159.198 +      (if length msgs <= limit then ":" else " (" ^ string_of_int limit ^ " displayed):");
 159.199 +  in writeln (space_implode "\n\n" (header :: #1 (chop limit msgs))) end;
 159.200 +
 159.201  
 159.202  
 159.203  (** The Sledgehammer **)
 159.204 @@ -322,6 +336,11 @@
 159.205      (Scan.succeed (Toplevel.no_timing o Toplevel.imperative info));
 159.206  
 159.207  val _ =
 159.208 +  OuterSyntax.improper_command "atp_messages" "print recent messages issued by managed provers" K.diag
 159.209 +    (Scan.option (P.$$$ "(" |-- P.nat --| P.$$$ ")") >>
 159.210 +      (fn limit => Toplevel.no_timing o Toplevel.imperative (fn () => messages limit)));
 159.211 +
 159.212 +val _ =
 159.213    OuterSyntax.improper_command "print_atps" "print external provers" K.diag
 159.214      (Scan.succeed (Toplevel.no_timing o Toplevel.unknown_theory o
 159.215        Toplevel.keep (print_provers o Toplevel.theory_of)));
 159.216 @@ -329,7 +348,7 @@
 159.217  val _ =
 159.218    OuterSyntax.command "sledgehammer" "call all automatic theorem provers" K.diag
 159.219      (Scan.repeat P.xname >> (fn names => Toplevel.no_timing o Toplevel.unknown_proof o
 159.220 -    Toplevel.keep ((sledgehammer names) o Toplevel.proof_of)));
 159.221 +      Toplevel.keep ((sledgehammer names) o Toplevel.proof_of)));
 159.222  
 159.223  end;
 159.224  
   160.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   160.2 +++ b/src/HOL/Tools/function_package/decompose.ML	Tue Dec 30 11:10:01 2008 +0100
   160.3 @@ -0,0 +1,105 @@
   160.4 +(*  Title:       HOL/Tools/function_package/decompose.ML
   160.5 +    Author:      Alexander Krauss, TU Muenchen
   160.6 +
   160.7 +Graph decomposition using "Shallow Dependency Pairs".
   160.8 +*)
   160.9 +
  160.10 +signature DECOMPOSE =
  160.11 +sig
  160.12 +
  160.13 +  val derive_chains : Proof.context -> tactic
  160.14 +                      -> (Termination.data -> int -> tactic)
  160.15 +                      -> Termination.data -> int -> tactic
  160.16 +
  160.17 +  val decompose_tac : Proof.context -> tactic
  160.18 +                      -> Termination.ttac
  160.19 +
  160.20 +end
  160.21 +
  160.22 +structure Decompose : DECOMPOSE =
  160.23 +struct
  160.24 +
  160.25 +structure TermGraph = GraphFun(type key = term val ord = Term.fast_term_ord);
  160.26 +
  160.27 +
  160.28 +fun derive_chains ctxt chain_tac cont D = Termination.CALLS (fn (cs, i) =>
  160.29 +  let
  160.30 +      val thy = ProofContext.theory_of ctxt
  160.31 +
  160.32 +      fun prove_chain c1 c2 D =
  160.33 +          if is_some (Termination.get_chain D c1 c2) then D else
  160.34 +          let
  160.35 +            val goal = HOLogic.mk_eq (HOLogic.mk_binop @{const_name "Relation.rel_comp"} (c1, c2),
  160.36 +                                      Const (@{const_name "{}"}, fastype_of c1))
  160.37 +                       |> HOLogic.mk_Trueprop (* "C1 O C2 = {}" *)
  160.38 +
  160.39 +            val chain = case FundefLib.try_proof (cterm_of thy goal) chain_tac of
  160.40 +                          FundefLib.Solved thm => SOME thm
  160.41 +                        | _ => NONE
  160.42 +          in
  160.43 +            Termination.note_chain c1 c2 chain D
  160.44 +          end
  160.45 +  in
  160.46 +    cont (fold_product prove_chain cs cs D) i
  160.47 +  end)
  160.48 +
  160.49 +
  160.50 +fun mk_dgraph D cs =
  160.51 +    TermGraph.empty
  160.52 +    |> fold (fn c => TermGraph.new_node (c,())) cs
  160.53 +    |> fold_product (fn c1 => fn c2 =>
  160.54 +         if is_none (Termination.get_chain D c1 c2 |> the_default NONE)
  160.55 +         then TermGraph.add_edge (c1, c2) else I)
  160.56 +       cs cs
  160.57 +
  160.58 +
  160.59 +fun ucomp_empty_tac T =
  160.60 +    REPEAT_ALL_NEW (rtac @{thm union_comp_emptyR}
  160.61 +                    ORELSE' rtac @{thm union_comp_emptyL}
  160.62 +                    ORELSE' SUBGOAL (fn (_ $ (_ $ (_ $ c1 $ c2) $ _), i) => rtac (T c1 c2) i))
  160.63 +
  160.64 +fun regroup_calls_tac cs = Termination.CALLS (fn (cs', i) =>
  160.65 +   let
  160.66 +     val is = map (fn c => find_index (curry op aconv c) cs') cs
  160.67 +   in
  160.68 +     CONVERSION (Conv.arg_conv (Conv.arg_conv (FundefLib.regroup_union_conv is))) i
  160.69 +   end)
  160.70 +
  160.71 +
  160.72 +fun solve_trivial_tac D = Termination.CALLS
  160.73 +(fn ([c], i) =>
  160.74 +    (case Termination.get_chain D c c of
  160.75 +       SOME (SOME thm) => rtac @{thm wf_no_loop} i
  160.76 +                          THEN rtac thm i
  160.77 +     | _ => no_tac)
  160.78 +  | _ => no_tac)
  160.79 +
  160.80 +fun decompose_tac' ctxt cont err_cont D = Termination.CALLS (fn (cs, i) =>
  160.81 +    let
  160.82 +      val G = mk_dgraph D cs
  160.83 +      val sccs = TermGraph.strong_conn G
  160.84 +
  160.85 +      fun split [SCC] i = (solve_trivial_tac D i ORELSE cont D i)
  160.86 +        | split (SCC::rest) i =
  160.87 +            regroup_calls_tac SCC i
  160.88 +            THEN rtac @{thm wf_union_compatible} i
  160.89 +            THEN rtac @{thm less_by_empty} (i + 2)
  160.90 +            THEN ucomp_empty_tac (the o the oo Termination.get_chain D) (i + 2)
  160.91 +            THEN split rest (i + 1)
  160.92 +            THEN (solve_trivial_tac D i ORELSE cont D i)
  160.93 +    in
  160.94 +      if length sccs > 1 then split sccs i
  160.95 +      else solve_trivial_tac D i ORELSE err_cont D i
  160.96 +    end)
  160.97 +
  160.98 +fun decompose_tac ctxt chain_tac cont err_cont =
  160.99 +    derive_chains ctxt chain_tac
 160.100 +    (decompose_tac' ctxt cont err_cont)
 160.101 +
 160.102 +fun auto_decompose_tac ctxt =
 160.103 +    Termination.TERMINATION ctxt
 160.104 +      (decompose_tac ctxt (auto_tac (local_clasimpset_of ctxt))
 160.105 +                     (K (K all_tac)) (K (K no_tac)))
 160.106 +
 160.107 +
 160.108 +end
   161.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   161.2 +++ b/src/HOL/Tools/function_package/descent.ML	Tue Dec 30 11:10:01 2008 +0100
   161.3 @@ -0,0 +1,44 @@
   161.4 +(*  Title:       HOL/Tools/function_package/descent.ML
   161.5 +    Author:      Alexander Krauss, TU Muenchen
   161.6 +
   161.7 +Descent proofs for termination
   161.8 +*)
   161.9 +
  161.10 +
  161.11 +signature DESCENT =
  161.12 +sig
  161.13 +
  161.14 +  val derive_diag : Proof.context -> tactic -> (Termination.data -> int -> tactic)
  161.15 +                    -> Termination.data -> int -> tactic
  161.16 +
  161.17 +  val derive_all  : Proof.context -> tactic -> (Termination.data -> int -> tactic)
  161.18 +                    -> Termination.data -> int -> tactic
  161.19 +
  161.20 +end
  161.21 +
  161.22 +
  161.23 +structure Descent : DESCENT =
  161.24 +struct
  161.25 +
  161.26 +fun gen_descent diag ctxt tac cont D = Termination.CALLS (fn (cs, i) =>
  161.27 +  let
  161.28 +    val thy = ProofContext.theory_of ctxt
  161.29 +    val measures_of = Termination.get_measures D
  161.30 +
  161.31 +    fun derive c D =
  161.32 +      let
  161.33 +        val (_, p, _, q, _, _) = Termination.dest_call D c
  161.34 +      in
  161.35 +        if diag andalso p = q
  161.36 +        then fold (fn m => Termination.derive_descent thy tac c m m) (measures_of p) D
  161.37 +        else fold_product (Termination.derive_descent thy tac c)
  161.38 +               (measures_of p) (measures_of q) D
  161.39 +      end
  161.40 +  in
  161.41 +    cont (FundefCommon.PROFILE "deriving descents" (fold derive cs) D) i
  161.42 +  end)
  161.43 +
  161.44 +val derive_diag = gen_descent true
  161.45 +val derive_all = gen_descent false
  161.46 +
  161.47 +end
   162.1 --- a/src/HOL/Tools/function_package/fundef_lib.ML	Tue Dec 30 08:18:54 2008 +0100
   162.2 +++ b/src/HOL/Tools/function_package/fundef_lib.ML	Tue Dec 30 11:10:01 2008 +0100
   162.3 @@ -130,4 +130,50 @@
   162.4      | SOME st => if Thm.no_prems st then Solved (Goal.finish st) else Stuck st
   162.5  
   162.6  
   162.7 +fun dest_binop_list cn (t as (Const (n, _) $ a $ b)) = 
   162.8 +    if cn = n then dest_binop_list cn a @ dest_binop_list cn b else [ t ]
   162.9 +  | dest_binop_list _ t = [ t ]
  162.10 +
  162.11 +
  162.12 +(* separate two parts in a +-expression:
  162.13 +   "a + b + c + d + e" --> "(a + b + d) + (c + e)"
  162.14 +
  162.15 +   Here, + can be any binary operation that is AC.
  162.16 +
  162.17 +   cn - The name of the binop-constructor (e.g. @{const_name "op Un"})
  162.18 +   ac - the AC rewrite rules for cn
  162.19 +   is - the list of indices of the expressions that should become the first part
  162.20 +        (e.g. [0,1,3] in the above example)
  162.21 +*)
  162.22 +
  162.23 +fun regroup_conv neu cn ac is ct =
  162.24 + let
  162.25 +   val mk = HOLogic.mk_binop cn
  162.26 +   val t = term_of ct
  162.27 +   val xs = dest_binop_list cn t
  162.28 +   val js = 0 upto (length xs) - 1 \\ is
  162.29 +   val ty = fastype_of t
  162.30 +   val thy = theory_of_cterm ct
  162.31 + in
  162.32 +   Goal.prove_internal []
  162.33 +     (cterm_of thy
  162.34 +       (Logic.mk_equals (t,
  162.35 +          if is = []
  162.36 +          then mk (Const (neu, ty), foldr1 mk (map (nth xs) js))
  162.37 +          else if js = []
  162.38 +            then mk (foldr1 mk (map (nth xs) is), Const (neu, ty))
  162.39 +            else mk (foldr1 mk (map (nth xs) is), foldr1 mk (map (nth xs) js)))))
  162.40 +     (K (MetaSimplifier.rewrite_goals_tac ac
  162.41 +         THEN rtac Drule.reflexive_thm 1))
  162.42 + end
  162.43 +
  162.44 +(* instance for unions *)
  162.45 +fun regroup_union_conv t =
  162.46 +    regroup_conv (@{const_name "{}"})
  162.47 +                  @{const_name "op Un"}
  162.48 +       (map (fn t => t RS eq_reflection) (@{thms "Un_ac"} @
  162.49 +                                          @{thms "Un_empty_right"} @
  162.50 +                                          @{thms "Un_empty_left"})) t
  162.51 +
  162.52 +
  162.53  end
   163.1 --- a/src/HOL/Tools/function_package/induction_scheme.ML	Tue Dec 30 08:18:54 2008 +0100
   163.2 +++ b/src/HOL/Tools/function_package/induction_scheme.ML	Tue Dec 30 11:10:01 2008 +0100
   163.3 @@ -55,7 +55,7 @@
   163.4  fun meta thm = thm RS eq_reflection
   163.5  
   163.6  val sum_prod_conv = MetaSimplifier.rewrite true 
   163.7 -                    (map meta (@{thm split_conv} :: @{thms sum_cases}))
   163.8 +                    (map meta (@{thm split_conv} :: @{thms sum.cases}))
   163.9  
  163.10  fun term_conv thy cv t = 
  163.11      cv (cterm_of thy t)
  163.12 @@ -320,7 +320,7 @@
  163.13  
  163.14              val Pxs = cert (HOLogic.mk_Trueprop (P_comp $ x))
  163.15                       |> Goal.init
  163.16 -                     |> (MetaSimplifier.rewrite_goals_tac (map meta (branch_hyp :: @{thm split_conv} :: @{thms sum_cases}))
  163.17 +                     |> (MetaSimplifier.rewrite_goals_tac (map meta (branch_hyp :: @{thm split_conv} :: @{thms sum.cases}))
  163.18                           THEN CONVERSION ind_rulify 1)
  163.19                       |> Seq.hd
  163.20                       |> Thm.elim_implies (Conv.fconv_rule Drule.beta_eta_conversion bstep)
   164.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   164.2 +++ b/src/HOL/Tools/function_package/scnp_reconstruct.ML	Tue Dec 30 11:10:01 2008 +0100
   164.3 @@ -0,0 +1,426 @@
   164.4 +(*  Title:       HOL/Tools/function_package/scnp_reconstruct.ML
   164.5 +    Author:      Armin Heller, TU Muenchen
   164.6 +    Author:      Alexander Krauss, TU Muenchen
   164.7 +
   164.8 +Proof reconstruction for SCNP
   164.9 +*)
  164.10 +
  164.11 +signature SCNP_RECONSTRUCT =
  164.12 +sig
  164.13 +
  164.14 +  val decomp_scnp : ScnpSolve.label list -> Proof.context -> method
  164.15 +
  164.16 +  val setup : theory -> theory
  164.17 +
  164.18 +  datatype multiset_setup =
  164.19 +    Multiset of
  164.20 +    {
  164.21 +     msetT : typ -> typ,
  164.22 +     mk_mset : typ -> term list -> term,
  164.23 +     mset_regroup_conv : int list -> conv,
  164.24 +     mset_member_tac : int -> int -> tactic,
  164.25 +     mset_nonempty_tac : int -> tactic,
  164.26 +     mset_pwleq_tac : int -> tactic,
  164.27 +     set_of_simps : thm list,
  164.28 +     smsI' : thm,
  164.29 +     wmsI2'' : thm,
  164.30 +     wmsI1 : thm,
  164.31 +     reduction_pair : thm
  164.32 +    }
  164.33 +
  164.34 +
  164.35 +  val multiset_setup : multiset_setup -> theory -> theory
  164.36 +
  164.37 +end
  164.38 +
  164.39 +structure ScnpReconstruct : SCNP_RECONSTRUCT =
  164.40 +struct
  164.41 +
  164.42 +val PROFILE = FundefCommon.PROFILE
  164.43 +fun TRACE x = if ! FundefCommon.profile then Output.tracing x else ()
  164.44 +
  164.45 +open ScnpSolve
  164.46 +
  164.47 +val natT = HOLogic.natT
  164.48 +val nat_pairT = HOLogic.mk_prodT (natT, natT)
  164.49 +
  164.50 +(* Theory dependencies *)
  164.51 +
  164.52 +datatype multiset_setup =
  164.53 +  Multiset of
  164.54 +  {
  164.55 +   msetT : typ -> typ,
  164.56 +   mk_mset : typ -> term list -> term,
  164.57 +   mset_regroup_conv : int list -> conv,
  164.58 +   mset_member_tac : int -> int -> tactic,
  164.59 +   mset_nonempty_tac : int -> tactic,
  164.60 +   mset_pwleq_tac : int -> tactic,
  164.61 +   set_of_simps : thm list,
  164.62 +   smsI' : thm,
  164.63 +   wmsI2'' : thm,
  164.64 +   wmsI1 : thm,
  164.65 +   reduction_pair : thm
  164.66 +  }
  164.67 +
  164.68 +structure MultisetSetup = TheoryDataFun
  164.69 +(
  164.70 +  type T = multiset_setup option
  164.71 +  val empty = NONE
  164.72 +  val copy = I;
  164.73 +  val extend = I;
  164.74 +  fun merge _ (v1, v2) = if is_some v2 then v2 else v1
  164.75 +)
  164.76 +
  164.77 +val multiset_setup = MultisetSetup.put o SOME
  164.78 +
  164.79 +fun undef x = error "undef"
  164.80 +fun get_multiset_setup thy = MultisetSetup.get thy
  164.81 +  |> the_default (Multiset
  164.82 +{ msetT = undef, mk_mset=undef,
  164.83 +  mset_regroup_conv=undef, mset_member_tac = undef,
  164.84 +  mset_nonempty_tac = undef, mset_pwleq_tac = undef,
  164.85 +  set_of_simps = [],reduction_pair = refl,
  164.86 +  smsI'=refl, wmsI2''=refl, wmsI1=refl })
  164.87 +
  164.88 +fun order_rpair _ MAX = @{thm max_rpair_set}
  164.89 +  | order_rpair msrp MS  = msrp
  164.90 +  | order_rpair _ MIN = @{thm min_rpair_set}
  164.91 +
  164.92 +fun ord_intros_max true =
  164.93 +    (@{thm smax_emptyI}, @{thm smax_insertI})
  164.94 +  | ord_intros_max false =
  164.95 +    (@{thm wmax_emptyI}, @{thm wmax_insertI})
  164.96 +fun ord_intros_min true =
  164.97 +    (@{thm smin_emptyI}, @{thm smin_insertI})
  164.98 +  | ord_intros_min false =
  164.99 +    (@{thm wmin_emptyI}, @{thm wmin_insertI})
 164.100 +
 164.101 +fun gen_probl D cs =
 164.102 +  let
 164.103 +    val n = Termination.get_num_points D
 164.104 +    val arity = length o Termination.get_measures D
 164.105 +    fun measure p i = nth (Termination.get_measures D p) i
 164.106 +
 164.107 +    fun mk_graph c =
 164.108 +      let
 164.109 +        val (_, p, _, q, _, _) = Termination.dest_call D c
 164.110 +
 164.111 +        fun add_edge i j =
 164.112 +          case Termination.get_descent D c (measure p i) (measure q j)
 164.113 +           of SOME (Termination.Less _) => cons (i, GTR, j)
 164.114 +            | SOME (Termination.LessEq _) => cons (i, GEQ, j)
 164.115 +            | _ => I
 164.116 +
 164.117 +        val edges =
 164.118 +          fold_product add_edge (0 upto arity p - 1) (0 upto arity q - 1) []
 164.119 +      in
 164.120 +        G (p, q, edges)
 164.121 +      end
 164.122 +  in
 164.123 +    GP (map arity (0 upto n - 1), map mk_graph cs)
 164.124 +  end
 164.125 +
 164.126 +(* General reduction pair application *)
 164.127 +fun rem_inv_img ctxt =
 164.128 +  let
 164.129 +    val unfold_tac = LocalDefs.unfold_tac ctxt
 164.130 +  in
 164.131 +    rtac @{thm subsetI} 1
 164.132 +    THEN etac @{thm CollectE} 1
 164.133 +    THEN REPEAT (etac @{thm exE} 1)
 164.134 +    THEN unfold_tac @{thms inv_image_def}
 164.135 +    THEN rtac @{thm CollectI} 1
 164.136 +    THEN etac @{thm conjE} 1
 164.137 +    THEN etac @{thm ssubst} 1
 164.138 +    THEN unfold_tac (@{thms split_conv} @ @{thms triv_forall_equality}
 164.139 +                     @ @{thms sum.cases})
 164.140 +  end
 164.141 +
 164.142 +(* Sets *)
 164.143 +
 164.144 +val setT = HOLogic.mk_setT
 164.145 +
 164.146 +fun mk_set T [] = Const (@{const_name "{}"}, setT T)
 164.147 +  | mk_set T (x :: xs) =
 164.148 +      Const (@{const_name insert}, T --> setT T --> setT T) $
 164.149 +            x $ mk_set T xs
 164.150 +
 164.151 +fun set_member_tac m i =
 164.152 +  if m = 0 then rtac @{thm insertI1} i
 164.153 +  else rtac @{thm insertI2} i THEN set_member_tac (m - 1) i
 164.154 +
 164.155 +val set_nonempty_tac = rtac @{thm insert_not_empty}
 164.156 +
 164.157 +fun set_finite_tac i =
 164.158 +  rtac @{thm finite.emptyI} i
 164.159 +  ORELSE (rtac @{thm finite.insertI} i THEN (fn st => set_finite_tac i st))
 164.160 +
 164.161 +
 164.162 +(* Reconstruction *)
 164.163 +
 164.164 +fun reconstruct_tac ctxt D cs (gp as GP (_, gs)) certificate =
 164.165 +  let
 164.166 +    val thy = ProofContext.theory_of ctxt
 164.167 +    val Multiset
 164.168 +          { msetT, mk_mset,
 164.169 +            mset_regroup_conv, mset_member_tac,
 164.170 +            mset_nonempty_tac, mset_pwleq_tac, set_of_simps,
 164.171 +            smsI', wmsI2'', wmsI1, reduction_pair=ms_rp } 
 164.172 +        = get_multiset_setup thy
 164.173 +
 164.174 +    fun measure_fn p = nth (Termination.get_measures D p)
 164.175 +
 164.176 +    fun get_desc_thm cidx m1 m2 bStrict =
 164.177 +      case Termination.get_descent D (nth cs cidx) m1 m2
 164.178 +       of SOME (Termination.Less thm) =>
 164.179 +          if bStrict then thm
 164.180 +          else (thm COMP (Thm.lift_rule (cprop_of thm) @{thm less_imp_le}))
 164.181 +        | SOME (Termination.LessEq (thm, _))  =>
 164.182 +          if not bStrict then thm
 164.183 +          else sys_error "get_desc_thm"
 164.184 +        | _ => sys_error "get_desc_thm"
 164.185 +
 164.186 +    val (label, lev, sl, covering) = certificate
 164.187 +
 164.188 +    fun prove_lev strict g =
 164.189 +      let
 164.190 +        val G (p, q, el) = nth gs g
 164.191 +
 164.192 +        fun less_proof strict (j, b) (i, a) =
 164.193 +          let
 164.194 +            val tag_flag = b < a orelse (not strict andalso b <= a)
 164.195 +
 164.196 +            val stored_thm =
 164.197 +              get_desc_thm g (measure_fn p i) (measure_fn q j)
 164.198 +                             (not tag_flag)
 164.199 +              |> Conv.fconv_rule (Thm.beta_conversion true)
 164.200 +
 164.201 +            val rule = if strict
 164.202 +              then if b < a then @{thm pair_lessI2} else @{thm pair_lessI1}
 164.203 +              else if b <= a then @{thm pair_leqI2} else @{thm pair_leqI1}
 164.204 +          in
 164.205 +            rtac rule 1 THEN PRIMITIVE (Thm.elim_implies stored_thm)
 164.206 +            THEN (if tag_flag then arith_tac ctxt 1 else all_tac)
 164.207 +          end
 164.208 +
 164.209 +        fun steps_tac MAX strict lq lp =
 164.210 +          let
 164.211 +            val (empty, step) = ord_intros_max strict
 164.212 +          in
 164.213 +            if length lq = 0
 164.214 +            then rtac empty 1 THEN set_finite_tac 1
 164.215 +                 THEN (if strict then set_nonempty_tac 1 else all_tac)
 164.216 +            else
 164.217 +              let
 164.218 +                val (j, b) :: rest = lq
 164.219 +                val (i, a) = the (covering g strict j)
 164.220 +                fun choose xs = set_member_tac (Library.find_index (curry op = (i, a)) xs) 1
 164.221 +                val solve_tac = choose lp THEN less_proof strict (j, b) (i, a)
 164.222 +              in
 164.223 +                rtac step 1 THEN solve_tac THEN steps_tac MAX strict rest lp
 164.224 +              end
 164.225 +          end
 164.226 +          | steps_tac MIN strict lq lp =
 164.227 +          let
 164.228 +            val (empty, step) = ord_intros_min strict
 164.229 +          in
 164.230 +            if length lp = 0
 164.231 +            then rtac empty 1
 164.232 +                 THEN (if strict then set_nonempty_tac 1 else all_tac)
 164.233 +            else
 164.234 +              let
 164.235 +                val (i, a) :: rest = lp
 164.236 +                val (j, b) = the (covering g strict i)
 164.237 +                fun choose xs = set_member_tac (Library.find_index (curry op = (j, b)) xs) 1
 164.238 +                val solve_tac = choose lq THEN less_proof strict (j, b) (i, a)
 164.239 +              in
 164.240 +                rtac step 1 THEN solve_tac THEN steps_tac MIN strict lq rest
 164.241 +              end
 164.242 +          end
 164.243 +          | steps_tac MS strict lq lp =
 164.244 +          let
 164.245 +            fun get_str_cover (j, b) =
 164.246 +              if is_some (covering g true j) then SOME (j, b) else NONE
 164.247 +            fun get_wk_cover (j, b) = the (covering g false j)
 164.248 +
 164.249 +            val qs = lq \\ map_filter get_str_cover lq
 164.250 +            val ps = map get_wk_cover qs
 164.251 +
 164.252 +            fun indices xs ys = map (fn y => Library.find_index (curry op = y) xs) ys
 164.253 +            val iqs = indices lq qs
 164.254 +            val ips = indices lp ps
 164.255 +
 164.256 +            local open Conv in
 164.257 +            fun t_conv a C =
 164.258 +              params_conv ~1 (K ((concl_conv ~1 o arg_conv o arg1_conv o a) C)) ctxt
 164.259 +            val goal_rewrite =
 164.260 +                t_conv arg1_conv (mset_regroup_conv iqs)
 164.261 +                then_conv t_conv arg_conv (mset_regroup_conv ips)
 164.262 +            end
 164.263 +          in
 164.264 +            CONVERSION goal_rewrite 1
 164.265 +            THEN (if strict then rtac smsI' 1
 164.266 +                  else if qs = lq then rtac wmsI2'' 1
 164.267 +                  else rtac wmsI1 1)
 164.268 +            THEN mset_pwleq_tac 1
 164.269 +            THEN EVERY (map2 (less_proof false) qs ps)
 164.270 +            THEN (if strict orelse qs <> lq
 164.271 +                  then LocalDefs.unfold_tac ctxt set_of_simps
 164.272 +                       THEN steps_tac MAX true (lq \\ qs) (lp \\ ps)
 164.273 +                  else all_tac)
 164.274 +          end
 164.275 +      in
 164.276 +        rem_inv_img ctxt
 164.277 +        THEN steps_tac label strict (nth lev q) (nth lev p)
 164.278 +      end
 164.279 +
 164.280 +    val (mk_set, setT) = if label = MS then (mk_mset, msetT) else (mk_set, setT)
 164.281 +
 164.282 +    fun tag_pair p (i, tag) =
 164.283 +      HOLogic.pair_const natT natT $
 164.284 +        (measure_fn p i $ Bound 0) $ HOLogic.mk_number natT tag
 164.285 +
 164.286 +    fun pt_lev (p, lm) = Abs ("x", Termination.get_types D p,
 164.287 +                           mk_set nat_pairT (map (tag_pair p) lm))
 164.288 +
 164.289 +    val level_mapping =
 164.290 +      map_index pt_lev lev
 164.291 +        |> Termination.mk_sumcases D (setT nat_pairT)
 164.292 +        |> cterm_of thy
 164.293 +    in
 164.294 +      PROFILE "Proof Reconstruction"
 164.295 +        (CONVERSION (Conv.arg_conv (Conv.arg_conv (FundefLib.regroup_union_conv sl))) 1
 164.296 +         THEN (rtac @{thm reduction_pair_lemma} 1)
 164.297 +         THEN (rtac @{thm rp_inv_image_rp} 1)
 164.298 +         THEN (rtac (order_rpair ms_rp label) 1)
 164.299 +         THEN PRIMITIVE (instantiate' [] [SOME level_mapping])
 164.300 +         THEN unfold_tac @{thms rp_inv_image_def} (simpset_of thy)
 164.301 +         THEN LocalDefs.unfold_tac ctxt
 164.302 +           (@{thms split_conv} @ @{thms fst_conv} @ @{thms snd_conv})
 164.303 +         THEN REPEAT (SOMEGOAL (resolve_tac [@{thm Un_least}, @{thm empty_subsetI}]))
 164.304 +         THEN EVERY (map (prove_lev true) sl)
 164.305 +         THEN EVERY (map (prove_lev false) ((0 upto length cs - 1) \\ sl)))
 164.306 +    end
 164.307 +
 164.308 +
 164.309 +
 164.310 +local open Termination in
 164.311 +fun print_cell (SOME (Less _)) = "<"
 164.312 +  | print_cell (SOME (LessEq _)) = "\<le>"
 164.313 +  | print_cell (SOME (None _)) = "-"
 164.314 +  | print_cell (SOME (False _)) = "-"
 164.315 +  | print_cell (NONE) = "?"
 164.316 +
 164.317 +fun print_error ctxt D = CALLS (fn (cs, i) =>
 164.318 +  let
 164.319 +    val np = get_num_points D
 164.320 +    val ms = map (get_measures D) (0 upto np - 1)
 164.321 +    val tys = map (get_types D) (0 upto np - 1)
 164.322 +    fun index xs = (1 upto length xs) ~~ xs
 164.323 +    fun outp s t f xs = map (fn (x, y) => s ^ Int.toString x ^ t ^ f y ^ "\n") xs
 164.324 +    val ims = index (map index ms)
 164.325 +    val _ = Output.tracing (concat (outp "fn #" ":\n" (concat o outp "\tmeasure #" ": " (Syntax.string_of_term ctxt)) ims))
 164.326 +    fun print_call (k, c) =
 164.327 +      let
 164.328 +        val (_, p, _, q, _, _) = dest_call D c
 164.329 +        val _ = Output.tracing ("call table for call #" ^ Int.toString k ^ ": fn " ^ 
 164.330 +                                Int.toString (p + 1) ^ " ~> fn " ^ Int.toString (q + 1))
 164.331 +        val caller_ms = nth ms p
 164.332 +        val callee_ms = nth ms q
 164.333 +        val entries = map (fn x => map (pair x) (callee_ms)) (caller_ms)
 164.334 +        fun print_ln (i : int, l) = concat (Int.toString i :: "   " :: map (enclose " " " " o print_cell o (uncurry (get_descent D c))) l)
 164.335 +        val _ = Output.tracing (concat (Int.toString (p + 1) ^ "|" ^ Int.toString (q + 1) ^ 
 164.336 +                                        " " :: map (enclose " " " " o Int.toString) (1 upto length callee_ms)) ^ "\n" 
 164.337 +                                ^ cat_lines (map print_ln ((1 upto (length entries)) ~~ entries)))
 164.338 +      in
 164.339 +        true
 164.340 +      end
 164.341 +    fun list_call (k, c) =
 164.342 +      let
 164.343 +        val (_, p, _, q, _, _) = dest_call D c
 164.344 +        val _ = Output.tracing ("call #" ^ (Int.toString k) ^ ": fn " ^
 164.345 +                                Int.toString (p + 1) ^ " ~> fn " ^ Int.toString (q + 1) ^ "\n" ^ 
 164.346 +                                (Syntax.string_of_term ctxt c))
 164.347 +      in true end
 164.348 +    val _ = forall list_call ((1 upto length cs) ~~ cs)
 164.349 +    val _ = forall print_call ((1 upto length cs) ~~ cs)
 164.350 +  in
 164.351 +    all_tac
 164.352 +  end)
 164.353 +end
 164.354 +
 164.355 +
 164.356 +fun single_scnp_tac use_tags orders ctxt cont err_cont D = Termination.CALLS (fn (cs, i) =>
 164.357 +  let
 164.358 +    val gp = gen_probl D cs
 164.359 +(*    val _ = TRACE ("SCNP instance: " ^ makestring gp)*)
 164.360 +    val certificate = generate_certificate use_tags orders gp
 164.361 +(*    val _ = TRACE ("Certificate: " ^ makestring certificate)*)
 164.362 +
 164.363 +    val ms_configured = is_some (MultisetSetup.get (ProofContext.theory_of ctxt))
 164.364 +    in
 164.365 +    case certificate
 164.366 +     of NONE => err_cont D i
 164.367 +      | SOME cert =>
 164.368 +        if not ms_configured andalso #1 cert = MS
 164.369 +        then err_cont D i
 164.370 +        else SELECT_GOAL (reconstruct_tac ctxt D cs gp cert) i
 164.371 +             THEN (rtac @{thm wf_empty} i ORELSE cont D i)
 164.372 +  end)
 164.373 +
 164.374 +fun decomp_scnp_tac orders autom_tac ctxt err_cont =
 164.375 +  let
 164.376 +    open Termination
 164.377 +    val derive_diag = Descent.derive_diag ctxt autom_tac
 164.378 +    val derive_all = Descent.derive_all ctxt autom_tac
 164.379 +    val decompose = Decompose.decompose_tac ctxt autom_tac
 164.380 +    val scnp_no_tags = single_scnp_tac false orders ctxt
 164.381 +    val scnp_full = single_scnp_tac true orders ctxt
 164.382 +
 164.383 +    fun first_round c e =
 164.384 +        derive_diag (REPEAT scnp_no_tags c e)
 164.385 +
 164.386 +    val second_round =
 164.387 +        REPEAT (fn c => fn e => decompose (scnp_no_tags c c) e)
 164.388 +
 164.389 +    val third_round =
 164.390 +        derive_all oo
 164.391 +        REPEAT (fn c => fn e =>
 164.392 +          scnp_full (decompose c c) e)
 164.393 +
 164.394 +    fun Then s1 s2 c e = s1 (s2 c c) (s2 c e)
 164.395 +
 164.396 +    val strategy = Then (Then first_round second_round) third_round
 164.397 +
 164.398 +  in
 164.399 +    TERMINATION ctxt (strategy err_cont err_cont)
 164.400 +  end
 164.401 +
 164.402 +fun decomp_scnp orders ctxt =
 164.403 +  let
 164.404 +    val extra_simps = FundefCommon.TerminationSimps.get ctxt
 164.405 +    val autom_tac = auto_tac (local_clasimpset_of ctxt addsimps2 extra_simps)
 164.406 +  in
 164.407 +    Method.SIMPLE_METHOD
 164.408 +      (TRY (FundefCommon.apply_termination_rule ctxt 1)
 164.409 +       THEN TRY Termination.wf_union_tac
 164.410 +       THEN
 164.411 +         (rtac @{thm wf_empty} 1
 164.412 +          ORELSE decomp_scnp_tac orders autom_tac ctxt (print_error ctxt) 1))
 164.413 +  end
 164.414 +
 164.415 +
 164.416 +(* Method setup *)
 164.417 +
 164.418 +val orders =
 164.419 +  (Scan.repeat1
 164.420 +    ((Args.$$$ "max" >> K MAX) ||
 164.421 +     (Args.$$$ "min" >> K MIN) ||
 164.422 +     (Args.$$$ "ms" >> K MS))
 164.423 +  || Scan.succeed [MAX, MS, MIN])
 164.424 +
 164.425 +val setup = Method.add_method
 164.426 +  ("sizechange", Method.sectioned_args (Scan.lift orders) clasimp_modifiers decomp_scnp,
 164.427 +   "termination prover with graph decomposition and the NP subset of size change termination")
 164.428 +
 164.429 +end
   165.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   165.2 +++ b/src/HOL/Tools/function_package/scnp_solve.ML	Tue Dec 30 11:10:01 2008 +0100
   165.3 @@ -0,0 +1,257 @@
   165.4 +(*  Title:       HOL/Tools/function_package/scnp_solve.ML
   165.5 +    Author:      Armin Heller, TU Muenchen
   165.6 +    Author:      Alexander Krauss, TU Muenchen
   165.7 +
   165.8 +Generate certificates for SCNP using a SAT solver
   165.9 +*)
  165.10 +
  165.11 +
  165.12 +signature SCNP_SOLVE =
  165.13 +sig
  165.14 +
  165.15 +  datatype edge = GTR | GEQ
  165.16 +  datatype graph = G of int * int * (int * edge * int) list
  165.17 +  datatype graph_problem = GP of int list * graph list
  165.18 +
  165.19 +  datatype label = MIN | MAX | MS
  165.20 +
  165.21 +  type certificate =
  165.22 +    label                   (* which order *)
  165.23 +    * (int * int) list list (* (multi)sets *)
  165.24 +    * int list              (* strictly ordered calls *)
  165.25 +    * (int -> bool -> int -> (int * int) option) (* covering function *)
  165.26 +
  165.27 +  val generate_certificate : bool -> label list -> graph_problem -> certificate option
  165.28 +
  165.29 +  val solver : string ref
  165.30 +end
  165.31 +
  165.32 +structure ScnpSolve : SCNP_SOLVE =
  165.33 +struct
  165.34 +
  165.35 +(** Graph problems **)
  165.36 +
  165.37 +datatype edge = GTR | GEQ ;
  165.38 +datatype graph = G of int * int * (int * edge * int) list ;
  165.39 +datatype graph_problem = GP of int list * graph list ;
  165.40 +
  165.41 +datatype label = MIN | MAX | MS ;
  165.42 +type certificate =
  165.43 +  label
  165.44 +  * (int * int) list list
  165.45 +  * int list
  165.46 +  * (int -> bool -> int -> (int * int) option)
  165.47 +
  165.48 +fun graph_at (GP (_, gs), i) = nth gs i ;
  165.49 +fun num_prog_pts (GP (arities, _)) = length arities ;
  165.50 +fun num_graphs (GP (_, gs)) = length gs ;
  165.51 +fun arity (GP (arities, gl)) i = nth arities i ;
  165.52 +fun ndigits (GP (arities, _)) = IntInf.log2 (foldl (op +) 0 arities) + 1
  165.53 +
  165.54 +
  165.55 +(** Propositional formulas **)
  165.56 +
  165.57 +val Not = PropLogic.Not and And = PropLogic.And and Or = PropLogic.Or
  165.58 +val BoolVar = PropLogic.BoolVar
  165.59 +fun Implies (p, q) = Or (Not p, q)
  165.60 +fun Equiv (p, q) = And (Implies (p, q), Implies (q, p))
  165.61 +val all = PropLogic.all
  165.62 +
  165.63 +(* finite indexed quantifiers:
  165.64 +
  165.65 +iforall n f   <==>      /\
  165.66 +                       /  \  f i
  165.67 +                      0<=i<n
  165.68 + *)
  165.69 +fun iforall n f = all (map f (0 upto n - 1))
  165.70 +fun iexists n f = PropLogic.exists (map f (0 upto n - 1))
  165.71 +fun iforall2 n m f = all (map_product f (0 upto n - 1) (0 upto m - 1))
  165.72 +
  165.73 +fun the_one var n x = all (var x :: map (Not o var) ((0 upto n - 1) \\ [x]))
  165.74 +fun exactly_one n f = iexists n (the_one f n)
  165.75 +
  165.76 +(* SAT solving *)
  165.77 +val solver = ref "auto";
  165.78 +fun sat_solver x =
  165.79 +  FundefCommon.PROFILE "sat_solving..." (SatSolver.invoke_solver (!solver)) x
  165.80 +
  165.81 +(* "Virtual constructors" for various propositional variables *)
  165.82 +fun var_constrs (gp as GP (arities, gl)) =
  165.83 +  let
  165.84 +    val n = Int.max (num_graphs gp, num_prog_pts gp)
  165.85 +    val k = foldl Int.max 1 arities
  165.86 +
  165.87 +    (* Injective, provided  a < 8, x < n, and i < k. *)
  165.88 +    fun prod a x i j = ((j * k + i) * n + x) * 8 + a + 1
  165.89 +
  165.90 +    fun ES (g, i, j) = BoolVar (prod 0 g i j)
  165.91 +    fun EW (g, i, j) = BoolVar (prod 1 g i j)
  165.92 +    fun WEAK g       = BoolVar (prod 2 g 0 0)
  165.93 +    fun STRICT g     = BoolVar (prod 3 g 0 0)
  165.94 +    fun P (p, i)     = BoolVar (prod 4 p i 0)
  165.95 +    fun GAM (g, i, j)= BoolVar (prod 5 g i j)
  165.96 +    fun EPS (g, i)   = BoolVar (prod 6 g i 0)
  165.97 +    fun TAG (p, i) b = BoolVar (prod 7 p i b)
  165.98 +  in
  165.99 +    (ES,EW,WEAK,STRICT,P,GAM,EPS,TAG)
 165.100 +  end
 165.101 +
 165.102 +
 165.103 +fun graph_info gp g =
 165.104 +  let
 165.105 +    val G (p, q, edgs) = graph_at (gp, g)
 165.106 +  in
 165.107 +    (g, p, q, arity gp p, arity gp q, edgs)
 165.108 +  end
 165.109 +
 165.110 +
 165.111 +(* Order-independent part of encoding *)
 165.112 +
 165.113 +fun encode_graphs bits gp =
 165.114 +  let
 165.115 +    val ng = num_graphs gp
 165.116 +    val (ES,EW,_,_,_,_,_,TAG) = var_constrs gp
 165.117 +
 165.118 +    fun encode_constraint_strict 0 (x, y) = PropLogic.False
 165.119 +      | encode_constraint_strict k (x, y) =
 165.120 +        Or (And (TAG x (k - 1), Not (TAG y (k - 1))),
 165.121 +            And (Equiv (TAG x (k - 1), TAG y (k - 1)),
 165.122 +                 encode_constraint_strict (k - 1) (x, y)))
 165.123 +
 165.124 +    fun encode_constraint_weak k (x, y) =
 165.125 +        Or (encode_constraint_strict k (x, y),
 165.126 +            iforall k (fn i => Equiv (TAG x i, TAG y i)))
 165.127 +
 165.128 +    fun encode_graph (g, p, q, n, m, edges) =
 165.129 +      let
 165.130 +        fun encode_edge i j =
 165.131 +          if exists (fn x => x = (i, GTR, j)) edges then
 165.132 +            And (ES (g, i, j), EW (g, i, j))
 165.133 +          else if not (exists (fn x => x = (i, GEQ, j)) edges) then
 165.134 +            And (Not (ES (g, i, j)), Not (EW (g, i, j)))
 165.135 +          else
 165.136 +            And (
 165.137 +              Equiv (ES (g, i, j),
 165.138 +                     encode_constraint_strict bits ((p, i), (q, j))),
 165.139 +              Equiv (EW (g, i, j),
 165.140 +                     encode_constraint_weak bits ((p, i), (q, j))))
 165.141 +       in
 165.142 +        iforall2 n m encode_edge
 165.143 +      end
 165.144 +  in
 165.145 +    iforall ng (encode_graph o graph_info gp)
 165.146 +  end
 165.147 +
 165.148 +
 165.149 +(* Order-specific part of encoding *)
 165.150 +
 165.151 +fun encode bits gp mu =
 165.152 +  let
 165.153 +    val ng = num_graphs gp
 165.154 +    val (ES,EW,WEAK,STRICT,P,GAM,EPS,_) = var_constrs gp
 165.155 +
 165.156 +    fun encode_graph MAX (g, p, q, n, m, _) =
 165.157 +        all [
 165.158 +          Equiv (WEAK g,
 165.159 +            iforall m (fn j =>
 165.160 +              Implies (P (q, j),
 165.161 +                iexists n (fn i =>
 165.162 +                  And (P (p, i), EW (g, i, j)))))),
 165.163 +          Equiv (STRICT g,
 165.164 +            iforall m (fn j =>
 165.165 +              Implies (P (q, j),
 165.166 +                iexists n (fn i =>
 165.167 +                  And (P (p, i), ES (g, i, j)))))),
 165.168 +          iexists n (fn i => P (p, i))
 165.169 +        ]
 165.170 +      | encode_graph MIN (g, p, q, n, m, _) =
 165.171 +        all [
 165.172 +          Equiv (WEAK g,
 165.173 +            iforall n (fn i =>
 165.174 +              Implies (P (p, i),
 165.175 +                iexists m (fn j =>
 165.176 +                  And (P (q, j), EW (g, i, j)))))),
 165.177 +          Equiv (STRICT g,
 165.178 +            iforall n (fn i =>
 165.179 +              Implies (P (p, i),
 165.180 +                iexists m (fn j =>
 165.181 +                  And (P (q, j), ES (g, i, j)))))),
 165.182 +          iexists m (fn j => P (q, j))
 165.183 +        ]
 165.184 +      | encode_graph MS (g, p, q, n, m, _) =
 165.185 +        all [
 165.186 +          Equiv (WEAK g,
 165.187 +            iforall m (fn j =>
 165.188 +              Implies (P (q, j),
 165.189 +                iexists n (fn i => GAM (g, i, j))))),
 165.190 +          Equiv (STRICT g,
 165.191 +            iexists n (fn i =>
 165.192 +              And (P (p, i), Not (EPS (g, i))))),
 165.193 +          iforall2 n m (fn i => fn j =>
 165.194 +            Implies (GAM (g, i, j),
 165.195 +              all [
 165.196 +                P (p, i),
 165.197 +                P (q, j),
 165.198 +                EW (g, i, j),
 165.199 +                Equiv (Not (EPS (g, i)), ES (g, i, j))])),
 165.200 +          iforall n (fn i =>
 165.201 +            Implies (And (P (p, i), EPS (g, i)),
 165.202 +              exactly_one m (fn j => GAM (g, i, j))))
 165.203 +        ]
 165.204 +  in
 165.205 +    all [
 165.206 +      encode_graphs bits gp,
 165.207 +      iforall ng (encode_graph mu o graph_info gp),
 165.208 +      iforall ng (fn x => WEAK x),
 165.209 +      iexists ng (fn x => STRICT x)
 165.210 +    ]
 165.211 +  end
 165.212 +
 165.213 +
 165.214 +(*Generieren des level-mapping und diverser output*)
 165.215 +fun mk_certificate bits label gp f =
 165.216 +  let
 165.217 +    val (ES,EW,WEAK,STRICT,P,GAM,EPS,TAG) = var_constrs gp
 165.218 +    fun assign (PropLogic.BoolVar v) = the_default false (f v)
 165.219 +    fun assignTag i j =
 165.220 +      (fold (fn x => fn y => 2 * y + (if assign (TAG (i, j) x) then 1 else 0))
 165.221 +        (bits - 1 downto 0) 0)
 165.222 +
 165.223 +    val level_mapping =
 165.224 +      let fun prog_pt_mapping p =
 165.225 +            map_filter (fn x => if assign (P(p, x)) then SOME (x, assignTag p x) else NONE)
 165.226 +              (0 upto (arity gp p) - 1)
 165.227 +      in map prog_pt_mapping (0 upto num_prog_pts gp - 1) end
 165.228 +
 165.229 +    val strict_list = filter (assign o STRICT) (0 upto num_graphs gp - 1)
 165.230 +
 165.231 +    fun covering_pair g bStrict j =
 165.232 +      let
 165.233 +        val (_, p, q, n, m, _) = graph_info gp g
 165.234 +
 165.235 +        fun cover        MAX j = find_index (fn i => assign (P (p, i))      andalso      assign (EW  (g, i, j))) (0 upto n - 1)
 165.236 +          | cover        MS  k = find_index (fn i =>                                     assign (GAM (g, i, k))) (0 upto n - 1)
 165.237 +          | cover        MIN i = find_index (fn j => assign (P (q, j))      andalso      assign (EW  (g, i, j))) (0 upto m - 1)
 165.238 +        fun cover_strict MAX j = find_index (fn i => assign (P (p, i))      andalso      assign (ES  (g, i, j))) (0 upto n - 1)
 165.239 +          | cover_strict MS  k = find_index (fn i => assign (GAM (g, i, k)) andalso not (assign (EPS (g, i)  ))) (0 upto n - 1)
 165.240 +          | cover_strict MIN i = find_index (fn j => assign (P (q, j))      andalso      assign (ES  (g, i, j))) (0 upto m - 1)
 165.241 +        val i = if bStrict then cover_strict label j else cover label j
 165.242 +      in
 165.243 +        find_first (fn x => fst x = i) (nth level_mapping (if label = MIN then q else p))
 165.244 +      end
 165.245 +  in
 165.246 +    (label, level_mapping, strict_list, covering_pair)
 165.247 +  end
 165.248 +
 165.249 +(*interface for the proof reconstruction*)
 165.250 +fun generate_certificate use_tags labels gp =
 165.251 +  let
 165.252 +    val bits = if use_tags then ndigits gp else 0
 165.253 +  in
 165.254 +    get_first
 165.255 +      (fn l => case sat_solver (encode bits gp l) of
 165.256 +                 SatSolver.SATISFIABLE f => SOME (mk_certificate bits l gp f)
 165.257 +               | _ => NONE)
 165.258 +      labels
 165.259 +  end
 165.260 +end
   166.1 --- a/src/HOL/Tools/function_package/sum_tree.ML	Tue Dec 30 08:18:54 2008 +0100
   166.2 +++ b/src/HOL/Tools/function_package/sum_tree.ML	Tue Dec 30 11:10:01 2008 +0100
   166.3 @@ -9,8 +9,8 @@
   166.4  struct
   166.5  
   166.6  (* Theory dependencies *)
   166.7 -val proj_in_rules = [thm "Sum_Type.Projl_Inl", thm "Sum_Type.Projr_Inr"]
   166.8 -val sumcase_split_ss = HOL_basic_ss addsimps (@{thm "Product_Type.split"} :: @{thms "Sum_Type.sum_cases"})
   166.9 +val proj_in_rules = [@{thm "Datatype.Projl_Inl"}, @{thm "Datatype.Projr_Inr"}]
  166.10 +val sumcase_split_ss = HOL_basic_ss addsimps (@{thm "Product_Type.split"} :: @{thms "sum.cases"})
  166.11  
  166.12  (* top-down access in balanced tree *)
  166.13  fun access_top_down {left, right, init} len i =
  166.14 @@ -18,7 +18,7 @@
  166.15  
  166.16  (* Sum types *)
  166.17  fun mk_sumT LT RT = Type ("+", [LT, RT])
  166.18 -fun mk_sumcase TL TR T l r = Const (@{const_name "Sum_Type.sum_case"}, (TL --> T) --> (TR --> T) --> mk_sumT TL TR --> T) $ l $ r
  166.19 +fun mk_sumcase TL TR T l r = Const (@{const_name "sum.sum_case"}, (TL --> T) --> (TR --> T) --> mk_sumT TL TR --> T) $ l $ r
  166.20  
  166.21  val App = curry op $
  166.22  
  166.23 @@ -32,8 +32,8 @@
  166.24  fun mk_proj ST n i = 
  166.25      access_top_down 
  166.26      { init = (ST, I : term -> term),
  166.27 -      left = (fn (T as Type ("+", [LT, RT]), proj) => (LT, App (Const (@{const_name "Projl"}, T --> LT)) o proj)),
  166.28 -      right =(fn (T as Type ("+", [LT, RT]), proj) => (RT, App (Const (@{const_name "Projr"}, T --> RT)) o proj))} n i
  166.29 +      left = (fn (T as Type ("+", [LT, RT]), proj) => (LT, App (Const (@{const_name "Datatype.Projl"}, T --> LT)) o proj)),
  166.30 +      right =(fn (T as Type ("+", [LT, RT]), proj) => (RT, App (Const (@{const_name "Datatype.Projr"}, T --> RT)) o proj))} n i
  166.31      |> snd
  166.32  
  166.33  fun mk_sumcases T fs =
   167.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   167.2 +++ b/src/HOL/Tools/function_package/termination.ML	Tue Dec 30 11:10:01 2008 +0100
   167.3 @@ -0,0 +1,324 @@
   167.4 +(*  Title:       HOL/Tools/function_package/termination_data.ML
   167.5 +    Author:      Alexander Krauss, TU Muenchen
   167.6 +
   167.7 +Context data for termination proofs
   167.8 +*)
   167.9 +
  167.10 +
  167.11 +signature TERMINATION =
  167.12 +sig
  167.13 +
  167.14 +  type data
  167.15 +  datatype cell = Less of thm | LessEq of (thm * thm) | None of (thm * thm) | False of thm
  167.16 +
  167.17 +  val mk_sumcases : data -> typ -> term list -> term
  167.18 +
  167.19 +  val note_measure : int -> term -> data -> data
  167.20 +  val note_chain   : term -> term -> thm option -> data -> data
  167.21 +  val note_descent : term -> term -> term -> cell -> data -> data
  167.22 +
  167.23 +  val get_num_points : data -> int
  167.24 +  val get_types      : data -> int -> typ
  167.25 +  val get_measures   : data -> int -> term list
  167.26 +
  167.27 +  (* read from cache *)
  167.28 +  val get_chain      : data -> term -> term -> thm option option
  167.29 +  val get_descent    : data -> term -> term -> term -> cell option
  167.30 +
  167.31 +  (* writes *)
  167.32 +  val derive_descent  : theory -> tactic -> term -> term -> term -> data -> data
  167.33 +  val derive_descents : theory -> tactic -> term -> data -> data
  167.34 +
  167.35 +  val dest_call : data -> term -> ((string * typ) list * int * term * int * term * term)
  167.36 +
  167.37 +  val CALLS : (term list * int -> tactic) -> int -> tactic
  167.38 +
  167.39 +  (* Termination tactics. Sequential composition via continuations. (2nd argument is the error continuation) *)
  167.40 +  type ttac = (data -> int -> tactic) -> (data -> int -> tactic) -> data -> int -> tactic
  167.41 +
  167.42 +  val TERMINATION : Proof.context -> (data -> int -> tactic) -> int -> tactic
  167.43 +
  167.44 +  val REPEAT : ttac -> ttac
  167.45 +
  167.46 +  val wf_union_tac : tactic
  167.47 +end
  167.48 +
  167.49 +
  167.50 +
  167.51 +structure Termination : TERMINATION =
  167.52 +struct
  167.53 +
  167.54 +open FundefLib
  167.55 +
  167.56 +val term2_ord = prod_ord Term.fast_term_ord Term.fast_term_ord
  167.57 +structure Term2tab = TableFun(type key = term * term val ord = term2_ord);
  167.58 +structure Term3tab = TableFun(type key = term * (term * term) val ord = prod_ord Term.fast_term_ord term2_ord);
  167.59 +
  167.60 +(** Analyzing binary trees **)
  167.61 +
  167.62 +(* Skeleton of a tree structure *)
  167.63 +
  167.64 +datatype skel =
  167.65 +  SLeaf of int (* index *)
  167.66 +| SBranch of (skel * skel)
  167.67 +
  167.68 +
  167.69 +(* abstract make and dest functions *)
  167.70 +fun mk_tree leaf branch =
  167.71 +  let fun mk (SLeaf i) = leaf i
  167.72 +        | mk (SBranch (s, t)) = branch (mk s, mk t)
  167.73 +  in mk end
  167.74 +
  167.75 +
  167.76 +fun dest_tree split =
  167.77 +  let fun dest (SLeaf i) x = [(i, x)]
  167.78 +        | dest (SBranch (s, t)) x =
  167.79 +          let val (l, r) = split x
  167.80 +          in dest s l @ dest t r end
  167.81 +  in dest end
  167.82 +
  167.83 +
  167.84 +(* concrete versions for sum types *)
  167.85 +fun is_inj (Const ("Sum_Type.Inl", _) $ _) = true
  167.86 +  | is_inj (Const ("Sum_Type.Inr", _) $ _) = true
  167.87 +  | is_inj _ = false
  167.88 +
  167.89 +fun dest_inl (Const ("Sum_Type.Inl", _) $ t) = SOME t
  167.90 +  | dest_inl _ = NONE
  167.91 +
  167.92 +fun dest_inr (Const ("Sum_Type.Inr", _) $ t) = SOME t
  167.93 +  | dest_inr _ = NONE
  167.94 +
  167.95 +
  167.96 +fun mk_skel ps =
  167.97 +  let
  167.98 +    fun skel i ps =
  167.99 +      if forall is_inj ps andalso not (null ps)
 167.100 +      then let
 167.101 +          val (j, s) = skel i (map_filter dest_inl ps)
 167.102 +          val (k, t) = skel j (map_filter dest_inr ps)
 167.103 +        in (k, SBranch (s, t)) end
 167.104 +      else (i + 1, SLeaf i)
 167.105 +  in
 167.106 +    snd (skel 0 ps)
 167.107 +  end
 167.108 +
 167.109 +(* compute list of types for nodes *)
 167.110 +fun node_types sk T = dest_tree (fn Type ("+", [LT, RT]) => (LT, RT)) sk T |> map snd
 167.111 +
 167.112 +(* find index and raw term *)
 167.113 +fun dest_inj (SLeaf i) trm = (i, trm)
 167.114 +  | dest_inj (SBranch (s, t)) trm =
 167.115 +    case dest_inl trm of
 167.116 +      SOME trm' => dest_inj s trm'
 167.117 +    | _ => dest_inj t (the (dest_inr trm))
 167.118 +
 167.119 +
 167.120 +
 167.121 +(** Matrix cell datatype **)
 167.122 +
 167.123 +datatype cell = Less of thm | LessEq of (thm * thm) | None of (thm * thm) | False of thm;
 167.124 +
 167.125 +
 167.126 +type data =
 167.127 +  skel                            (* structure of the sum type encoding "program points" *)
 167.128 +  * (int -> typ)                  (* types of program points *)
 167.129 +  * (term list Inttab.table)      (* measures for program points *)
 167.130 +  * (thm option Term2tab.table)   (* which calls form chains? *)
 167.131 +  * (cell Term3tab.table)         (* local descents *)
 167.132 +
 167.133 +
 167.134 +fun map_measures f (p, T, M, C, D) = (p, T, f M, C, D)
 167.135 +fun map_chains f   (p, T, M, C, D) = (p, T, M, f C, D)
 167.136 +fun map_descent f  (p, T, M, C, D) = (p, T, M, C, f D)
 167.137 +
 167.138 +fun note_measure p m = map_measures (Inttab.insert_list (op aconv) (p, m))
 167.139 +fun note_chain c1 c2 res = map_chains (Term2tab.update ((c1, c2), res))
 167.140 +fun note_descent c m1 m2 res = map_descent (Term3tab.update ((c,(m1, m2)), res))
 167.141 +
 167.142 +(* Build case expression *)
 167.143 +fun mk_sumcases (sk, _, _, _, _) T fs =
 167.144 +  mk_tree (fn i => (nth fs i, domain_type (fastype_of (nth fs i))))
 167.145 +          (fn ((f, fT), (g, gT)) => (SumTree.mk_sumcase fT gT T f g, SumTree.mk_sumT fT gT))
 167.146 +          sk
 167.147 +  |> fst
 167.148 +
 167.149 +fun mk_sum_skel rel =
 167.150 +  let
 167.151 +    val cs = FundefLib.dest_binop_list @{const_name "op Un"} rel
 167.152 +    fun collect_pats (Const ("Collect", _) $ Abs (_, _, c)) =
 167.153 +      let
 167.154 +        val (Const ("op &", _) $ (Const ("op =", _) $ _ $ (Const ("Pair", _) $ r $ l)) $ Gam)
 167.155 +          = Term.strip_qnt_body "Ex" c
 167.156 +      in cons r o cons l end
 167.157 +  in
 167.158 +    mk_skel (fold collect_pats cs [])
 167.159 +  end
 167.160 +
 167.161 +fun create ctxt T rel =
 167.162 +  let
 167.163 +    val sk = mk_sum_skel rel
 167.164 +    val Ts = node_types sk T
 167.165 +    val M = Inttab.make (map_index (apsnd (MeasureFunctions.get_measure_functions ctxt)) Ts)
 167.166 +  in
 167.167 +    (sk, nth Ts, M, Term2tab.empty, Term3tab.empty)
 167.168 +  end
 167.169 +
 167.170 +fun get_num_points (sk, _, _, _, _) =
 167.171 +  let
 167.172 +    fun num (SLeaf i) = i + 1
 167.173 +      | num (SBranch (s, t)) = num t
 167.174 +  in num sk end
 167.175 +
 167.176 +fun get_types (_, T, _, _, _) = T
 167.177 +fun get_measures (_, _, M, _, _) = Inttab.lookup_list M
 167.178 +
 167.179 +fun get_chain (_, _, _, C, _) c1 c2 =
 167.180 +  Term2tab.lookup C (c1, c2)
 167.181 +
 167.182 +fun get_descent (_, _, _, _, D) c m1 m2 =
 167.183 +  Term3tab.lookup D (c, (m1, m2))
 167.184 +
 167.185 +fun dest_call D (Const ("Collect", _) $ Abs (_, _, c)) =
 167.186 +  let
 167.187 +    val n = get_num_points D
 167.188 +    val (sk, _, _, _, _) = D
 167.189 +    val vs = Term.strip_qnt_vars "Ex" c
 167.190 +
 167.191 +    (* FIXME: throw error "dest_call" for malformed terms *)
 167.192 +    val (Const ("op &", _) $ (Const ("op =", _) $ _ $ (Const ("Pair", _) $ r $ l)) $ Gam)
 167.193 +      = Term.strip_qnt_body "Ex" c
 167.194 +    val (p, l') = dest_inj sk l
 167.195 +    val (q, r') = dest_inj sk r
 167.196 +  in
 167.197 +    (vs, p, l', q, r', Gam)
 167.198 +  end
 167.199 +  | dest_call D t = error "dest_call"
 167.200 +
 167.201 +
 167.202 +fun derive_desc_aux thy tac c (vs, p, l', q, r', Gam) m1 m2 D =
 167.203 +  case get_descent D c m1 m2 of
 167.204 +    SOME _ => D
 167.205 +  | NONE => let
 167.206 +    fun cgoal rel =
 167.207 +      Term.list_all (vs,
 167.208 +        Logic.mk_implies (HOLogic.mk_Trueprop Gam,
 167.209 +          HOLogic.mk_Trueprop (Const (rel, @{typ "nat => nat => bool"})
 167.210 +            $ (m2 $ r') $ (m1 $ l'))))
 167.211 +      |> cterm_of thy
 167.212 +    in
 167.213 +      note_descent c m1 m2
 167.214 +        (case try_proof (cgoal @{const_name HOL.less}) tac of
 167.215 +           Solved thm => Less thm
 167.216 +         | Stuck thm =>
 167.217 +           (case try_proof (cgoal @{const_name HOL.less_eq}) tac of
 167.218 +              Solved thm2 => LessEq (thm2, thm)
 167.219 +            | Stuck thm2 =>
 167.220 +              if prems_of thm2 = [HOLogic.Trueprop $ HOLogic.false_const]
 167.221 +              then False thm2 else None (thm2, thm)
 167.222 +            | _ => raise Match) (* FIXME *)
 167.223 +         | _ => raise Match) D
 167.224 +      end
 167.225 +
 167.226 +fun derive_descent thy tac c m1 m2 D =
 167.227 +  derive_desc_aux thy tac c (dest_call D c) m1 m2 D
 167.228 +
 167.229 +(* all descents in one go *)
 167.230 +fun derive_descents thy tac c D =
 167.231 +  let val cdesc as (vs, p, l', q, r', Gam) = dest_call D c
 167.232 +  in fold_product (derive_desc_aux thy tac c cdesc)
 167.233 +       (get_measures D p) (get_measures D q) D
 167.234 +  end
 167.235 +
 167.236 +fun CALLS tac i st =
 167.237 +  if Thm.no_prems st then all_tac st
 167.238 +  else case Thm.term_of (Thm.cprem_of st i) of
 167.239 +    (_ $ (_ $ rel)) => tac (FundefLib.dest_binop_list @{const_name "op Un"} rel, i) st
 167.240 +  |_ => no_tac st
 167.241 +
 167.242 +type ttac = (data -> int -> tactic) -> (data -> int -> tactic) -> data -> int -> tactic
 167.243 +
 167.244 +fun TERMINATION ctxt tac =
 167.245 +  SUBGOAL (fn (_ $ (Const (@{const_name "wf"}, wfT) $ rel), i) =>
 167.246 +  let
 167.247 +    val (T, _) = HOLogic.dest_prodT (HOLogic.dest_setT (domain_type wfT))
 167.248 +  in
 167.249 +    tac (create ctxt T rel) i
 167.250 +  end)
 167.251 +
 167.252 +
 167.253 +(* A tactic to convert open to closed termination goals *)
 167.254 +local
 167.255 +fun dest_term (t : term) = (* FIXME, cf. Lexicographic order *)
 167.256 +    let
 167.257 +      val (vars, prop) = FundefLib.dest_all_all t
 167.258 +      val (prems, concl) = Logic.strip_horn prop
 167.259 +      val (lhs, rhs) = concl
 167.260 +                         |> HOLogic.dest_Trueprop
 167.261 +                         |> HOLogic.dest_mem |> fst
 167.262 +                         |> HOLogic.dest_prod
 167.263 +    in
 167.264 +      (vars, prems, lhs, rhs)
 167.265 +    end
 167.266 +
 167.267 +fun mk_pair_compr (T, qs, l, r, conds) =
 167.268 +    let
 167.269 +      val pT = HOLogic.mk_prodT (T, T)
 167.270 +      val n = length qs
 167.271 +      val peq = HOLogic.eq_const pT $ Bound n $ (HOLogic.pair_const T T $ l $ r)
 167.272 +      val conds' = if null conds then [HOLogic.true_const] else conds
 167.273 +    in
 167.274 +      HOLogic.Collect_const pT $
 167.275 +      Abs ("uu_", pT,
 167.276 +           (foldr1 HOLogic.mk_conj (peq :: conds')
 167.277 +            |> fold_rev (fn v => fn t => HOLogic.exists_const (fastype_of v) $ lambda v t) qs))
 167.278 +    end
 167.279 +
 167.280 +in
 167.281 +
 167.282 +fun wf_union_tac st =
 167.283 +    let
 167.284 +      val thy = theory_of_thm st
 167.285 +      val cert = cterm_of (theory_of_thm st)
 167.286 +      val ((trueprop $ (wf $ rel)) :: ineqs) = prems_of st
 167.287 +
 167.288 +      fun mk_compr ineq =
 167.289 +          let
 167.290 +            val (vars, prems, lhs, rhs) = dest_term ineq
 167.291 +          in
 167.292 +            mk_pair_compr (fastype_of lhs, vars, lhs, rhs, map (ObjectLogic.atomize_term thy) prems)
 167.293 +          end
 167.294 +
 167.295 +      val relation =
 167.296 +          if null ineqs then
 167.297 +              Const (@{const_name "{}"}, fastype_of rel)
 167.298 +          else
 167.299 +              foldr1 (HOLogic.mk_binop @{const_name "op Un"}) (map mk_compr ineqs)
 167.300 +
 167.301 +      fun solve_membership_tac i =
 167.302 +          (EVERY' (replicate (i - 2) (rtac @{thm UnI2}))  (* pick the right component of the union *)
 167.303 +          THEN' (fn j => TRY (rtac @{thm UnI1} j))
 167.304 +          THEN' (rtac @{thm CollectI})                    (* unfold comprehension *)
 167.305 +          THEN' (fn i => REPEAT (rtac @{thm exI} i))      (* Turn existentials into schematic Vars *)
 167.306 +          THEN' ((rtac @{thm refl})                       (* unification instantiates all Vars *)
 167.307 +                 ORELSE' ((rtac @{thm conjI})
 167.308 +                          THEN' (rtac @{thm refl})
 167.309 +                          THEN' (CLASET' blast_tac)))     (* Solve rest of context... not very elegant *)
 167.310 +          ) i
 167.311 +    in
 167.312 +      ((PRIMITIVE (Drule.cterm_instantiate [(cert rel, cert relation)])
 167.313 +      THEN ALLGOALS (fn i => if i = 1 then all_tac else solve_membership_tac i))) st
 167.314 +    end
 167.315 +
 167.316 +
 167.317 +end
 167.318 +
 167.319 +
 167.320 +(* continuation passing repeat combinator *)
 167.321 +fun REPEAT ttac cont err_cont =
 167.322 +    ttac (fn D => fn i => (REPEAT ttac cont cont D i)) err_cont
 167.323 +
 167.324 +
 167.325 +
 167.326 +
 167.327 +end
   168.1 --- a/src/HOL/Transcendental.thy	Tue Dec 30 08:18:54 2008 +0100
   168.2 +++ b/src/HOL/Transcendental.thy	Tue Dec 30 11:10:01 2008 +0100
   168.3 @@ -11,7 +11,7 @@
   168.4  imports Fact Series Deriv NthRoot
   168.5  begin
   168.6  
   168.7 -subsection{*Properties of Power Series*}
   168.8 +subsection {* Properties of Power Series *}
   168.9  
  168.10  lemma lemma_realpow_diff:
  168.11    fixes y :: "'a::recpower"
  168.12 @@ -26,8 +26,8 @@
  168.13    fixes y :: "'a::{recpower,comm_semiring_0}" shows
  168.14       "(\<Sum>p=0..<Suc n. (x ^ p) * y ^ (Suc n - p)) =  
  168.15        y * (\<Sum>p=0..<Suc n. (x ^ p) * y ^ (n - p))"
  168.16 -by (auto simp add: setsum_right_distrib lemma_realpow_diff mult_ac
  168.17 -  simp del: setsum_op_ivl_Suc cong: strong_setsum_cong)
  168.18 +by (simp add: setsum_right_distrib lemma_realpow_diff mult_ac
  168.19 +         del: setsum_op_ivl_Suc cong: strong_setsum_cong)
  168.20  
  168.21  lemma lemma_realpow_diff_sumr2:
  168.22    fixes y :: "'a::{recpower,comm_ring}" shows
  168.23 @@ -114,7 +114,7 @@
  168.24  by (rule powser_insidea [THEN summable_norm_cancel])
  168.25  
  168.26  
  168.27 -subsection{*Term-by-Term Differentiability of Power Series*}
  168.28 +subsection {* Term-by-Term Differentiability of Power Series *}
  168.29  
  168.30  definition
  168.31    diffs :: "(nat => 'a::ring_1) => nat => 'a" where
  168.32 @@ -124,33 +124,22 @@
  168.33  lemma diffs_minus: "diffs (%n. - c n) = (%n. - diffs c n)"
  168.34  by (simp add: diffs_def)
  168.35  
  168.36 -text{*Show that we can shift the terms down one*}
  168.37 -lemma lemma_diffs:
  168.38 -     "(\<Sum>n=0..<n. (diffs c)(n) * (x ^ n)) =  
  168.39 -      (\<Sum>n=0..<n. of_nat n * c(n) * (x ^ (n - Suc 0))) +  
  168.40 -      (of_nat n * c(n) * x ^ (n - Suc 0))"
  168.41 -apply (induct "n")
  168.42 -apply (auto simp add: mult_assoc add_assoc [symmetric] diffs_def)
  168.43 +lemma sums_Suc_imp:
  168.44 +  assumes f: "f 0 = 0"
  168.45 +  shows "(\<lambda>n. f (Suc n)) sums s \<Longrightarrow> (\<lambda>n. f n) sums s"
  168.46 +unfolding sums_def
  168.47 +apply (rule LIMSEQ_imp_Suc)
  168.48 +apply (subst setsum_shift_lb_Suc0_0_upt [where f=f, OF f, symmetric])
  168.49 +apply (simp only: setsum_shift_bounds_Suc_ivl)
  168.50  done
  168.51  
  168.52 -lemma lemma_diffs2:
  168.53 -     "(\<Sum>n=0..<n. of_nat n * c(n) * (x ^ (n - Suc 0))) =  
  168.54 -      (\<Sum>n=0..<n. (diffs c)(n) * (x ^ n)) -  
  168.55 -      (of_nat n * c(n) * x ^ (n - Suc 0))"
  168.56 -by (auto simp add: lemma_diffs)
  168.57 -
  168.58 -
  168.59  lemma diffs_equiv:
  168.60       "summable (%n. (diffs c)(n) * (x ^ n)) ==>  
  168.61        (%n. of_nat n * c(n) * (x ^ (n - Suc 0))) sums  
  168.62           (\<Sum>n. (diffs c)(n) * (x ^ n))"
  168.63 -apply (subgoal_tac " (%n. of_nat n * c (n) * (x ^ (n - Suc 0))) ----> 0")
  168.64 -apply (rule_tac [2] LIMSEQ_imp_Suc)
  168.65 -apply (drule summable_sums) 
  168.66 -apply (auto simp add: sums_def)
  168.67 -apply (drule_tac X="(\<lambda>n. \<Sum>n = 0..<n. diffs c n * x ^ n)" in LIMSEQ_diff)
  168.68 -apply (auto simp add: lemma_diffs2 [symmetric] diffs_def [symmetric])
  168.69 -apply (simp add: diffs_def summable_LIMSEQ_zero)
  168.70 +unfolding diffs_def
  168.71 +apply (drule summable_sums)
  168.72 +apply (rule sums_Suc_imp, simp_all)
  168.73  done
  168.74  
  168.75  lemma lemma_termdiff1:
  168.76 @@ -160,12 +149,6 @@
  168.77  by (auto simp add: right_distrib diff_minus power_add [symmetric] mult_ac
  168.78    cong: strong_setsum_cong)
  168.79  
  168.80 -lemma less_add_one: "m < n ==> (\<exists>d. n = m + d + Suc 0)"
  168.81 -by (simp add: less_iff_Suc_add)
  168.82 -
  168.83 -lemma sumdiff: "a + b - (c + d) = a - c + b - (d::real)"
  168.84 -by arith
  168.85 -
  168.86  lemma sumr_diff_mult_const2:
  168.87    "setsum f {0..<n} - of_nat n * (r::'a::ring_1) = (\<Sum>i = 0..<n. f i - r)"
  168.88  by (simp add: setsum_subtractf)
  168.89 @@ -252,15 +235,15 @@
  168.90    assumes k: "0 < (k::real)"
  168.91    assumes le: "\<And>h. \<lbrakk>h \<noteq> 0; norm h < k\<rbrakk> \<Longrightarrow> norm (f h) \<le> K * norm h"
  168.92    shows "f -- 0 --> 0"
  168.93 -proof (simp add: LIM_def, safe)
  168.94 +unfolding LIM_def diff_0_right
  168.95 +proof (safe)
  168.96 +  let ?h = "of_real (k / 2)::'a"
  168.97 +  have "?h \<noteq> 0" and "norm ?h < k" using k by simp_all
  168.98 +  hence "norm (f ?h) \<le> K * norm ?h" by (rule le)
  168.99 +  hence "0 \<le> K * norm ?h" by (rule order_trans [OF norm_ge_zero])
 168.100 +  hence zero_le_K: "0 \<le> K" using k by (simp add: zero_le_mult_iff)
 168.101 +
 168.102    fix r::real assume r: "0 < r"
 168.103 -  have zero_le_K: "0 \<le> K"
 168.104 -    apply (cut_tac k)
 168.105 -    apply (cut_tac h="of_real (k/2)" in le, simp)
 168.106 -    apply (simp del: of_real_divide)
 168.107 -    apply (drule order_trans [OF norm_ge_zero])
 168.108 -    apply (simp add: zero_le_mult_iff)
 168.109 -    done
 168.110    show "\<exists>s. 0 < s \<and> (\<forall>x. x \<noteq> 0 \<and> norm x < s \<longrightarrow> norm (f x) < r)"
 168.111    proof (cases)
 168.112      assume "K = 0"
 168.113 @@ -392,11 +375,12 @@
 168.114    assumes 3: "summable (\<lambda>n. (diffs (diffs c)) n * K ^ n)"
 168.115    assumes 4: "norm x < norm K"
 168.116    shows "DERIV (\<lambda>x. \<Sum>n. c n * x ^ n) x :> (\<Sum>n. (diffs c) n * x ^ n)"
 168.117 -proof (simp add: deriv_def, rule LIM_zero_cancel)
 168.118 +unfolding deriv_def
 168.119 +proof (rule LIM_zero_cancel)
 168.120    show "(\<lambda>h. (suminf (\<lambda>n. c n * (x + h) ^ n) - suminf (\<lambda>n. c n * x ^ n)) / h
 168.121              - suminf (\<lambda>n. diffs c n * x ^ n)) -- 0 --> 0"
 168.122    proof (rule LIM_equal2)
 168.123 -    show "0 < norm K - norm x" by (simp add: less_diff_eq 4)
 168.124 +    show "0 < norm K - norm x" using 4 by (simp add: less_diff_eq)
 168.125    next
 168.126      fix h :: 'a
 168.127      assume "h \<noteq> 0"
 168.128 @@ -421,8 +405,7 @@
 168.129        apply (rule summable_divide)
 168.130        apply (rule summable_diff [OF B A])
 168.131        apply (rule sums_summable [OF diffs_equiv [OF C]])
 168.132 -      apply (rule_tac f="suminf" in arg_cong)
 168.133 -      apply (rule ext)
 168.134 +      apply (rule arg_cong [where f="suminf"], rule ext)
 168.135        apply (simp add: ring_simps)
 168.136        done
 168.137    next
 168.138 @@ -433,22 +416,12 @@
 168.139  qed
 168.140  
 168.141  
 168.142 -subsection{*Exponential Function*}
 168.143 +subsection {* Exponential Function *}
 168.144  
 168.145  definition
 168.146    exp :: "'a \<Rightarrow> 'a::{recpower,real_normed_field,banach}" where
 168.147    "exp x = (\<Sum>n. x ^ n /\<^sub>R real (fact n))"
 168.148  
 168.149 -definition
 168.150 -  sin :: "real => real" where
 168.151 -  "sin x = (\<Sum>n. (if even(n) then 0 else
 168.152 -             (-1 ^ ((n - Suc 0) div 2))/(real (fact n))) * x ^ n)"
 168.153 - 
 168.154 -definition
 168.155 -  cos :: "real => real" where
 168.156 -  "cos x = (\<Sum>n. (if even(n) then (-1 ^ (n div 2))/(real (fact n)) 
 168.157 -                            else 0) * x ^ n)"
 168.158 -
 168.159  lemma summable_exp_generic:
 168.160    fixes x :: "'a::{real_normed_algebra_1,recpower,banach}"
 168.161    defines S_def: "S \<equiv> \<lambda>n. x ^ n /\<^sub>R real (fact n)"
 168.162 @@ -493,66 +466,9 @@
 168.163  lemma summable_exp: "summable (%n. inverse (real (fact n)) * x ^ n)"
 168.164  by (insert summable_exp_generic [where x=x], simp)
 168.165  
 168.166 -lemma summable_sin: 
 168.167 -     "summable (%n.  
 168.168 -           (if even n then 0  
 168.169 -           else -1 ^ ((n - Suc 0) div 2)/(real (fact n))) *  
 168.170 -                x ^ n)"
 168.171 -apply (rule_tac g = "(%n. inverse (real (fact n)) * \<bar>x\<bar> ^ n)" in summable_comparison_test)
 168.172 -apply (rule_tac [2] summable_exp)
 168.173 -apply (rule_tac x = 0 in exI)
 168.174 -apply (auto simp add: divide_inverse abs_mult power_abs [symmetric] zero_le_mult_iff)
 168.175 -done
 168.176 -
 168.177 -lemma summable_cos: 
 168.178 -      "summable (%n.  
 168.179 -           (if even n then  
 168.180 -           -1 ^ (n div 2)/(real (fact n)) else 0) * x ^ n)"
 168.181 -apply (rule_tac g = "(%n. inverse (real (fact n)) * \<bar>x\<bar> ^ n)" in summable_comparison_test)
 168.182 -apply (rule_tac [2] summable_exp)
 168.183 -apply (rule_tac x = 0 in exI)
 168.184 -apply (auto simp add: divide_inverse abs_mult power_abs [symmetric] zero_le_mult_iff)
 168.185 -done
 168.186 -
 168.187 -lemma lemma_STAR_sin:
 168.188 -     "(if even n then 0  
 168.189 -       else -1 ^ ((n - Suc 0) div 2)/(real (fact n))) * 0 ^ n = 0"
 168.190 -by (induct "n", auto)
 168.191 -
 168.192 -lemma lemma_STAR_cos:
 168.193 -     "0 < n -->  
 168.194 -      -1 ^ (n div 2)/(real (fact n)) * 0 ^ n = 0"
 168.195 -by (induct "n", auto)
 168.196 -
 168.197 -lemma lemma_STAR_cos1:
 168.198 -     "0 < n -->  
 168.199 -      (-1) ^ (n div 2)/(real (fact n)) * 0 ^ n = 0"
 168.200 -by (induct "n", auto)
 168.201 -
 168.202 -lemma lemma_STAR_cos2:
 168.203 -  "(\<Sum>n=1..<n. if even n then -1 ^ (n div 2)/(real (fact n)) *  0 ^ n 
 168.204 -                         else 0) = 0"
 168.205 -apply (induct "n")
 168.206 -apply (case_tac [2] "n", auto)
 168.207 -done
 168.208 -
 168.209  lemma exp_converges: "(\<lambda>n. x ^ n /\<^sub>R real (fact n)) sums exp x"
 168.210  unfolding exp_def by (rule summable_exp_generic [THEN summable_sums])
 168.211  
 168.212 -lemma sin_converges: 
 168.213 -      "(%n. (if even n then 0  
 168.214 -            else -1 ^ ((n - Suc 0) div 2)/(real (fact n))) *  
 168.215 -                 x ^ n) sums sin(x)"
 168.216 -unfolding sin_def by (rule summable_sin [THEN summable_sums])
 168.217 -
 168.218 -lemma cos_converges: 
 168.219 -      "(%n. (if even n then  
 168.220 -           -1 ^ (n div 2)/(real (fact n))  
 168.221 -           else 0) * x ^ n) sums cos(x)"
 168.222 -unfolding cos_def by (rule summable_cos [THEN summable_sums])
 168.223 -
 168.224 -
 168.225 -subsection{*Formal Derivatives of Exp, Sin, and Cos Series*} 
 168.226  
 168.227  lemma exp_fdiffs: 
 168.228        "diffs (%n. inverse(real (fact n))) = (%n. inverse(real (fact n)))"
 168.229 @@ -562,48 +478,6 @@
 168.230  lemma diffs_of_real: "diffs (\<lambda>n. of_real (f n)) = (\<lambda>n. of_real (diffs f n))"
 168.231  by (simp add: diffs_def)
 168.232  
 168.233 -lemma sin_fdiffs: 
 168.234 -      "diffs(%n. if even n then 0  
 168.235 -           else -1 ^ ((n - Suc 0) div 2)/(real (fact n)))  
 168.236 -       = (%n. if even n then  
 168.237 -                 -1 ^ (n div 2)/(real (fact n))  
 168.238 -              else 0)"
 168.239 -by (auto intro!: ext 
 168.240 -         simp add: diffs_def divide_inverse real_of_nat_def of_nat_mult
 168.241 -         simp del: mult_Suc of_nat_Suc)
 168.242 -
 168.243 -lemma sin_fdiffs2: 
 168.244 -       "diffs(%n. if even n then 0  
 168.245 -           else -1 ^ ((n - Suc 0) div 2)/(real (fact n))) n  
 168.246 -       = (if even n then  
 168.247 -                 -1 ^ (n div 2)/(real (fact n))  
 168.248 -              else 0)"
 168.249 -by (simp only: sin_fdiffs)
 168.250 -
 168.251 -lemma cos_fdiffs: 
 168.252 -      "diffs(%n. if even n then  
 168.253 -                 -1 ^ (n div 2)/(real (fact n)) else 0)  
 168.254 -       = (%n. - (if even n then 0  
 168.255 -           else -1 ^ ((n - Suc 0)div 2)/(real (fact n))))"
 168.256 -by (auto intro!: ext 
 168.257 -         simp add: diffs_def divide_inverse odd_Suc_mult_two_ex real_of_nat_def of_nat_mult
 168.258 -         simp del: mult_Suc of_nat_Suc)
 168.259 -
 168.260 -
 168.261 -lemma cos_fdiffs2: 
 168.262 -      "diffs(%n. if even n then  
 168.263 -                 -1 ^ (n div 2)/(real (fact n)) else 0) n 
 168.264 -       = - (if even n then 0  
 168.265 -           else -1 ^ ((n - Suc 0)div 2)/(real (fact n)))"
 168.266 -by (simp only: cos_fdiffs)
 168.267 -
 168.268 -text{*Now at last we can get the derivatives of exp, sin and cos*}
 168.269 -
 168.270 -lemma lemma_sin_minus:
 168.271 -     "- sin x = (\<Sum>n. - ((if even n then 0 
 168.272 -                  else -1 ^ ((n - Suc 0) div 2)/(real (fact n))) * x ^ n))"
 168.273 -by (auto intro!: sums_unique sums_minus sin_converges)
 168.274 -
 168.275  lemma lemma_exp_ext: "exp = (\<lambda>x. \<Sum>n. x ^ n /\<^sub>R real (fact n))"
 168.276  by (auto intro!: ext simp add: exp_def)
 168.277  
 168.278 @@ -617,45 +491,11 @@
 168.279  apply (simp del: of_real_add)
 168.280  done
 168.281  
 168.282 -lemma lemma_sin_ext:
 168.283 -     "sin = (%x. \<Sum>n. 
 168.284 -                   (if even n then 0  
 168.285 -                       else -1 ^ ((n - Suc 0) div 2)/(real (fact n))) *  
 168.286 -                   x ^ n)"
 168.287 -by (auto intro!: ext simp add: sin_def)
 168.288 -
 168.289 -lemma lemma_cos_ext:
 168.290 -     "cos = (%x. \<Sum>n. 
 168.291 -                   (if even n then -1 ^ (n div 2)/(real (fact n)) else 0) *
 168.292 -                   x ^ n)"
 168.293 -by (auto intro!: ext simp add: cos_def)
 168.294 -
 168.295 -lemma DERIV_sin [simp]: "DERIV sin x :> cos(x)"
 168.296 -apply (simp add: cos_def)
 168.297 -apply (subst lemma_sin_ext)
 168.298 -apply (auto simp add: sin_fdiffs2 [symmetric])
 168.299 -apply (rule_tac K = "1 + \<bar>x\<bar>" in termdiffs)
 168.300 -apply (auto intro: sin_converges cos_converges sums_summable intro!: sums_minus [THEN sums_summable] simp add: cos_fdiffs sin_fdiffs)
 168.301 -done
 168.302 -
 168.303 -lemma DERIV_cos [simp]: "DERIV cos x :> -sin(x)"
 168.304 -apply (subst lemma_cos_ext)
 168.305 -apply (auto simp add: lemma_sin_minus cos_fdiffs2 [symmetric] minus_mult_left)
 168.306 -apply (rule_tac K = "1 + \<bar>x\<bar>" in termdiffs)
 168.307 -apply (auto intro: sin_converges cos_converges sums_summable intro!: sums_minus [THEN sums_summable] simp add: cos_fdiffs sin_fdiffs diffs_minus)
 168.308 -done
 168.309 -
 168.310  lemma isCont_exp [simp]: "isCont exp x"
 168.311  by (rule DERIV_exp [THEN DERIV_isCont])
 168.312  
 168.313 -lemma isCont_sin [simp]: "isCont sin x"
 168.314 -by (rule DERIV_sin [THEN DERIV_isCont])
 168.315  
 168.316 -lemma isCont_cos [simp]: "isCont cos x"
 168.317 -by (rule DERIV_cos [THEN DERIV_isCont])
 168.318 -
 168.319 -
 168.320 -subsection{*Properties of the Exponential Function*}
 168.321 +subsubsection {* Properties of the Exponential Function *}
 168.322  
 168.323  lemma powser_zero:
 168.324    fixes f :: "nat \<Rightarrow> 'a::{real_normed_algebra_1,recpower}"
 168.325 @@ -724,6 +564,9 @@
 168.326  unfolding exp_def
 168.327  by (simp only: Cauchy_product summable_norm_exp exp_series_add)
 168.328  
 168.329 +lemma mult_exp_exp: "exp x * exp y = exp (x + y)"
 168.330 +by (rule exp_add [symmetric])
 168.331 +
 168.332  lemma exp_of_real: "exp (of_real x) = of_real (exp x)"
 168.333  unfolding exp_def
 168.334  apply (subst of_real.suminf)
 168.335 @@ -731,6 +574,51 @@
 168.336  apply (simp add: scaleR_conv_of_real)
 168.337  done
 168.338  
 168.339 +lemma exp_not_eq_zero [simp]: "exp x \<noteq> 0"
 168.340 +proof
 168.341 +  have "exp x * exp (- x) = 1" by (simp add: mult_exp_exp)
 168.342 +  also assume "exp x = 0"
 168.343 +  finally show "False" by simp
 168.344 +qed
 168.345 +
 168.346 +lemma exp_minus: "exp (- x) = inverse (exp x)"
 168.347 +by (rule inverse_unique [symmetric], simp add: mult_exp_exp)
 168.348 +
 168.349 +lemma exp_diff: "exp (x - y) = exp x / exp y"
 168.350 +  unfolding diff_minus divide_inverse
 168.351 +  by (simp add: exp_add exp_minus)
 168.352 +
 168.353 +
 168.354 +subsubsection {* Properties of the Exponential Function on Reals *}
 168.355 +
 168.356 +text {* Comparisons of @{term "exp x"} with zero. *}
 168.357 +
 168.358 +text{*Proof: because every exponential can be seen as a square.*}
 168.359 +lemma exp_ge_zero [simp]: "0 \<le> exp (x::real)"
 168.360 +proof -
 168.361 +  have "0 \<le> exp (x/2) * exp (x/2)" by simp
 168.362 +  thus ?thesis by (simp add: exp_add [symmetric])
 168.363 +qed
 168.364 +
 168.365 +lemma exp_gt_zero [simp]: "0 < exp (x::real)"
 168.366 +by (simp add: order_less_le)
 168.367 +
 168.368 +lemma not_exp_less_zero [simp]: "\<not> exp (x::real) < 0"
 168.369 +by (simp add: not_less)
 168.370 +
 168.371 +lemma not_exp_le_zero [simp]: "\<not> exp (x::real) \<le> 0"
 168.372 +by (simp add: not_le)
 168.373 +
 168.374 +lemma abs_exp_cancel [simp]: "\<bar>exp x::real\<bar> = exp x"
 168.375 +by simp
 168.376 +
 168.377 +lemma exp_real_of_nat_mult: "exp(real n * x) = exp(x) ^ n"
 168.378 +apply (induct "n")
 168.379 +apply (auto simp add: real_of_nat_Suc right_distrib exp_add mult_commute)
 168.380 +done
 168.381 +
 168.382 +text {* Strict monotonicity of exponential. *}
 168.383 +
 168.384  lemma exp_ge_add_one_self_aux: "0 \<le> (x::real) ==> (1 + x) \<le> exp(x)"
 168.385  apply (drule order_le_imp_less_or_eq, auto)
 168.386  apply (simp add: exp_def)
 168.387 @@ -739,114 +627,61 @@
 168.388  apply (auto intro: summable_exp simp add: numeral_2_eq_2 zero_le_mult_iff)
 168.389  done
 168.390  
 168.391 -lemma exp_gt_one [simp]: "0 < (x::real) ==> 1 < exp x"
 168.392 -apply (rule order_less_le_trans)
 168.393 -apply (rule_tac [2] exp_ge_add_one_self_aux, auto)
 168.394 -done
 168.395 -
 168.396 -lemma DERIV_exp_add_const: "DERIV (%x. exp (x + y)) x :> exp(x + y)"
 168.397 +lemma exp_gt_one: "0 < (x::real) \<Longrightarrow> 1 < exp x"
 168.398  proof -
 168.399 -  have "DERIV (exp \<circ> (\<lambda>x. x + y)) x :> exp (x + y) * (1+0)"
 168.400 -    by (fast intro: DERIV_chain DERIV_add DERIV_exp DERIV_ident DERIV_const) 
 168.401 -  thus ?thesis by (simp add: o_def)
 168.402 +  assume x: "0 < x"
 168.403 +  hence "1 < 1 + x" by simp
 168.404 +  also from x have "1 + x \<le> exp x"
 168.405 +    by (simp add: exp_ge_add_one_self_aux)
 168.406 +  finally show ?thesis .
 168.407  qed
 168.408  
 168.409 -lemma DERIV_exp_minus [simp]: "DERIV (%x. exp (-x)) x :> - exp(-x)"
 168.410 -proof -
 168.411 -  have "DERIV (exp \<circ> uminus) x :> exp (- x) * - 1"
 168.412 -    by (fast intro: DERIV_chain DERIV_minus DERIV_exp DERIV_ident)
 168.413 -  thus ?thesis by (simp add: o_def)
 168.414 -qed
 168.415 -
 168.416 -lemma DERIV_exp_exp_zero [simp]: "DERIV (%x. exp (x + y) * exp (- x)) x :> 0"
 168.417 -proof -
 168.418 -  have "DERIV (\<lambda>x. exp (x + y) * exp (- x)) x
 168.419 -       :> exp (x + y) * exp (- x) + - exp (- x) * exp (x + y)"
 168.420 -    by (fast intro: DERIV_exp_add_const DERIV_exp_minus DERIV_mult) 
 168.421 -  thus ?thesis by (simp add: mult_commute)
 168.422 -qed
 168.423 -
 168.424 -lemma exp_add_mult_minus [simp]: "exp(x + y)*exp(-x) = exp(y::real)"
 168.425 -proof -
 168.426 -  have "\<forall>x. DERIV (%x. exp (x + y) * exp (- x)) x :> 0" by simp
 168.427 -  hence "exp (x + y) * exp (- x) = exp (0 + y) * exp (- 0)" 
 168.428 -    by (rule DERIV_isconst_all) 
 168.429 -  thus ?thesis by simp
 168.430 -qed
 168.431 -
 168.432 -lemma exp_mult_minus [simp]: "exp x * exp(-x) = 1"
 168.433 -by (simp add: exp_add [symmetric])
 168.434 -
 168.435 -lemma exp_mult_minus2 [simp]: "exp(-x)*exp(x) = 1"
 168.436 -by (simp add: mult_commute)
 168.437 -
 168.438 -
 168.439 -lemma exp_minus: "exp(-x) = inverse(exp(x))"
 168.440 -by (auto intro: inverse_unique [symmetric])
 168.441 -
 168.442 -text{*Proof: because every exponential can be seen as a square.*}
 168.443 -lemma exp_ge_zero [simp]: "0 \<le> exp (x::real)"
 168.444 -apply (rule_tac t = x in real_sum_of_halves [THEN subst])
 168.445 -apply (subst exp_add, auto)
 168.446 -done
 168.447 -
 168.448 -lemma exp_not_eq_zero [simp]: "exp x \<noteq> 0"
 168.449 -apply (cut_tac x = x in exp_mult_minus2)
 168.450 -apply (auto simp del: exp_mult_minus2)
 168.451 -done
 168.452 -
 168.453 -lemma exp_gt_zero [simp]: "0 < exp (x::real)"
 168.454 -by (simp add: order_less_le)
 168.455 -
 168.456 -lemma inv_exp_gt_zero [simp]: "0 < inverse(exp x::real)"
 168.457 -by (auto intro: positive_imp_inverse_positive)
 168.458 -
 168.459 -lemma abs_exp_cancel [simp]: "\<bar>exp x::real\<bar> = exp x"
 168.460 -by auto
 168.461 -
 168.462 -lemma exp_real_of_nat_mult: "exp(real n * x) = exp(x) ^ n"
 168.463 -apply (induct "n")
 168.464 -apply (auto simp add: real_of_nat_Suc right_distrib exp_add mult_commute)
 168.465 -done
 168.466 -
 168.467 -lemma exp_diff: "exp(x - y) = exp(x)/(exp y)"
 168.468 -apply (simp add: diff_minus divide_inverse)
 168.469 -apply (simp (no_asm) add: exp_add exp_minus)
 168.470 -done
 168.471 -
 168.472 -
 168.473  lemma exp_less_mono:
 168.474    fixes x y :: real
 168.475 -  assumes xy: "x < y" shows "exp x < exp y"
 168.476 +  assumes "x < y" shows "exp x < exp y"
 168.477  proof -
 168.478 -  from xy have "1 < exp (y + - x)"
 168.479 -    by (rule real_less_sum_gt_zero [THEN exp_gt_one])
 168.480 -  hence "exp x * inverse (exp x) < exp y * inverse (exp x)"
 168.481 -    by (auto simp add: exp_add exp_minus)
 168.482 -  thus ?thesis
 168.483 -    by (simp add: divide_inverse [symmetric] pos_less_divide_eq
 168.484 -             del: divide_self_if)
 168.485 +  from `x < y` have "0 < y - x" by simp
 168.486 +  hence "1 < exp (y - x)" by (rule exp_gt_one)
 168.487 +  hence "1 < exp y / exp x" by (simp only: exp_diff)
 168.488 +  thus "exp x < exp y" by simp
 168.489  qed
 168.490  
 168.491  lemma exp_less_cancel: "exp (x::real) < exp y ==> x < y"
 168.492 -apply (simp add: linorder_not_le [symmetric]) 
 168.493 -apply (auto simp add: order_le_less exp_less_mono) 
 168.494 +apply (simp add: linorder_not_le [symmetric])
 168.495 +apply (auto simp add: order_le_less exp_less_mono)
 168.496  done
 168.497  
 168.498 -lemma exp_less_cancel_iff [iff]: "(exp(x::real) < exp(y)) = (x < y)"
 168.499 +lemma exp_less_cancel_iff [iff]: "exp (x::real) < exp y \<longleftrightarrow> x < y"
 168.500  by (auto intro: exp_less_mono exp_less_cancel)
 168.501  
 168.502 -lemma exp_le_cancel_iff [iff]: "(exp(x::real) \<le> exp(y)) = (x \<le> y)"
 168.503 +lemma exp_le_cancel_iff [iff]: "exp (x::real) \<le> exp y \<longleftrightarrow> x \<le> y"
 168.504  by (auto simp add: linorder_not_less [symmetric])
 168.505  
 168.506 -lemma exp_inj_iff [iff]: "(exp (x::real) = exp y) = (x = y)"
 168.507 +lemma exp_inj_iff [iff]: "exp (x::real) = exp y \<longleftrightarrow> x = y"
 168.508  by (simp add: order_eq_iff)
 168.509  
 168.510 +text {* Comparisons of @{term "exp x"} with one. *}
 168.511 +
 168.512 +lemma one_less_exp_iff [simp]: "1 < exp (x::real) \<longleftrightarrow> 0 < x"
 168.513 +  using exp_less_cancel_iff [where x=0 and y=x] by simp
 168.514 +
 168.515 +lemma exp_less_one_iff [simp]: "exp (x::real) < 1 \<longleftrightarrow> x < 0"
 168.516 +  using exp_less_cancel_iff [where x=x and y=0] by simp
 168.517 +
 168.518 +lemma one_le_exp_iff [simp]: "1 \<le> exp (x::real) \<longleftrightarrow> 0 \<le> x"
 168.519 +  using exp_le_cancel_iff [where x=0 and y=x] by simp
 168.520 +
 168.521 +lemma exp_le_one_iff [simp]: "exp (x::real) \<le> 1 \<longleftrightarrow> x \<le> 0"
 168.522 +  using exp_le_cancel_iff [where x=x and y=0] by simp
 168.523 +
 168.524 +lemma exp_eq_one_iff [simp]: "exp (x::real) = 1 \<longleftrightarrow> x = 0"
 168.525 +  using exp_inj_iff [where x=x and y=0] by simp
 168.526 +
 168.527  lemma lemma_exp_total: "1 \<le> y ==> \<exists>x. 0 \<le> x & x \<le> y - 1 & exp(x::real) = y"
 168.528  apply (rule IVT)
 168.529  apply (auto intro: isCont_exp simp add: le_diff_eq)
 168.530  apply (subgoal_tac "1 + (y - 1) \<le> exp (y - 1)") 
 168.531 -apply simp 
 168.532 +apply simp
 168.533  apply (rule exp_ge_add_one_self_aux, simp)
 168.534  done
 168.535  
 168.536 @@ -861,7 +696,7 @@
 168.537  done
 168.538  
 168.539  
 168.540 -subsection{*Properties of the Logarithmic Function*}
 168.541 +subsection {* Natural Logarithm *}
 168.542  
 168.543  definition
 168.544    ln :: "real => real" where
 168.545 @@ -873,59 +708,46 @@
 168.546  lemma exp_ln [simp]: "0 < x \<Longrightarrow> exp (ln x) = x"
 168.547  by (auto dest: exp_total)
 168.548  
 168.549 -lemma exp_ln_iff [simp]: "(exp (ln x) = x) = (0 < x)"
 168.550 -apply (auto dest: exp_total)
 168.551 -apply (erule subst, simp) 
 168.552 +lemma exp_ln_iff [simp]: "exp (ln x) = x \<longleftrightarrow> 0 < x"
 168.553 +apply (rule iffI)
 168.554 +apply (erule subst, rule exp_gt_zero)
 168.555 +apply (erule exp_ln)
 168.556  done
 168.557  
 168.558 -lemma ln_mult: "[| 0 < x; 0 < y |] ==> ln(x * y) = ln(x) + ln(y)"
 168.559 -apply (rule exp_inj_iff [THEN iffD1])
 168.560 -apply (simp add: exp_add exp_ln mult_pos_pos)
 168.561 +lemma ln_unique: "exp y = x \<Longrightarrow> ln x = y"
 168.562 +by (erule subst, rule ln_exp)
 168.563 +
 168.564 +lemma ln_one [simp]: "ln 1 = 0"
 168.565 +by (rule ln_unique, simp)
 168.566 +
 168.567 +lemma ln_mult: "\<lbrakk>0 < x; 0 < y\<rbrakk> \<Longrightarrow> ln (x * y) = ln x + ln y"
 168.568 +by (rule ln_unique, simp add: exp_add)
 168.569 +
 168.570 +lemma ln_inverse: "0 < x \<Longrightarrow> ln (inverse x) = - ln x"
 168.571 +by (rule ln_unique, simp add: exp_minus)
 168.572 +
 168.573 +lemma ln_div: "\<lbrakk>0 < x; 0 < y\<rbrakk> \<Longrightarrow> ln (x / y) = ln x - ln y"
 168.574 +by (rule ln_unique, simp add: exp_diff)
 168.575 +
 168.576 +lemma ln_realpow: "0 < x \<Longrightarrow> ln (x ^ n) = real n * ln x"
 168.577 +by (rule ln_unique, simp add: exp_real_of_nat_mult)
 168.578 +
 168.579 +lemma ln_less_cancel_iff [simp]: "\<lbrakk>0 < x; 0 < y\<rbrakk> \<Longrightarrow> ln x < ln y \<longleftrightarrow> x < y"
 168.580 +by (subst exp_less_cancel_iff [symmetric], simp)
 168.581 +
 168.582 +lemma ln_le_cancel_iff [simp]: "\<lbrakk>0 < x; 0 < y\<rbrakk> \<Longrightarrow> ln x \<le> ln y \<longleftrightarrow> x \<le> y"
 168.583 +by (simp add: linorder_not_less [symmetric])
 168.584 +
 168.585 +lemma ln_inj_iff [simp]: "\<lbrakk>0 < x; 0 < y\<rbrakk> \<Longrightarrow> ln x = ln y \<longleftrightarrow> x = y"
 168.586 +by (simp add: order_eq_iff)
 168.587 +
 168.588 +lemma ln_add_one_self_le_self [simp]: "0 \<le> x \<Longrightarrow> ln (1 + x) \<le> x"
 168.589 +apply (rule exp_le_cancel_iff [THEN iffD1])
 168.590 +apply (simp add: exp_ge_add_one_self_aux)
 168.591  done
 168.592  
 168.593 -lemma ln_inj_iff[simp]: "[| 0 < x; 0 < y |] ==> (ln x = ln y) = (x = y)"
 168.594 -apply (simp only: exp_ln_iff [symmetric])
 168.595 -apply (erule subst)+
 168.596 -apply simp 
 168.597 -done
 168.598 -
 168.599 -lemma ln_one[simp]: "ln 1 = 0"
 168.600 -by (rule exp_inj_iff [THEN iffD1], auto)
 168.601 -
 168.602 -lemma ln_inverse: "0 < x ==> ln(inverse x) = - ln x"
 168.603 -apply (rule_tac a1 = "ln x" in add_left_cancel [THEN iffD1])
 168.604 -apply (auto simp add: positive_imp_inverse_positive ln_mult [symmetric])
 168.605 -done
 168.606 -
 168.607 -lemma ln_div: 
 168.608 -    "[|0 < x; 0 < y|] ==> ln(x/y) = ln x - ln y"
 168.609 -apply (simp add: divide_inverse)
 168.610 -apply (auto simp add: positive_imp_inverse_positive ln_mult ln_inverse)
 168.611 -done
 168.612 -
 168.613 -lemma ln_less_cancel_iff[simp]: "[| 0 < x; 0 < y|] ==> (ln x < ln y) = (x < y)"
 168.614 -apply (simp only: exp_ln_iff [symmetric])
 168.615 -apply (erule subst)+
 168.616 -apply simp 
 168.617 -done
 168.618 -
 168.619 -lemma ln_le_cancel_iff[simp]: "[| 0 < x; 0 < y|] ==> (ln x \<le> ln y) = (x \<le> y)"
 168.620 -by (auto simp add: linorder_not_less [symmetric])
 168.621 -
 168.622 -lemma ln_realpow: "0 < x ==> ln(x ^ n) = real n * ln(x)"
 168.623 -by (auto dest!: exp_total simp add: exp_real_of_nat_mult [symmetric])
 168.624 -
 168.625 -lemma ln_add_one_self_le_self [simp]: "0 \<le> x ==> ln(1 + x) \<le> x"
 168.626 -apply (rule ln_exp [THEN subst])
 168.627 -apply (rule ln_le_cancel_iff [THEN iffD2]) 
 168.628 -apply (auto simp add: exp_ge_add_one_self_aux)
 168.629 -done
 168.630 -
 168.631 -lemma ln_less_self [simp]: "0 < x ==> ln x < x"
 168.632 -apply (rule order_less_le_trans)
 168.633 -apply (rule_tac [2] ln_add_one_self_le_self)
 168.634 -apply (rule ln_less_cancel_iff [THEN iffD2], auto)
 168.635 -done
 168.636 +lemma ln_less_self [simp]: "0 < x \<Longrightarrow> ln x < x"
 168.637 +by (rule order_less_le_trans [where y="ln (1 + x)"]) simp_all
 168.638  
 168.639  lemma ln_ge_zero [simp]:
 168.640    assumes x: "1 \<le> x" shows "0 \<le> ln x"
 168.641 @@ -992,7 +814,151 @@
 168.642  done
 168.643  
 168.644  
 168.645 -subsection{*Basic Properties of the Trigonometric Functions*}
 168.646 +subsection {* Sine and Cosine *}
 168.647 +
 168.648 +definition
 168.649 +  sin :: "real => real" where
 168.650 +  "sin x = (\<Sum>n. (if even(n) then 0 else
 168.651 +             (-1 ^ ((n - Suc 0) div 2))/(real (fact n))) * x ^ n)"
 168.652 + 
 168.653 +definition
 168.654 +  cos :: "real => real" where
 168.655 +  "cos x = (\<Sum>n. (if even(n) then (-1 ^ (n div 2))/(real (fact n)) 
 168.656 +                            else 0) * x ^ n)"
 168.657 +
 168.658 +lemma summable_sin: 
 168.659 +     "summable (%n.  
 168.660 +           (if even n then 0  
 168.661 +           else -1 ^ ((n - Suc 0) div 2)/(real (fact n))) *  
 168.662 +                x ^ n)"
 168.663 +apply (rule_tac g = "(%n. inverse (real (fact n)) * \<bar>x\<bar> ^ n)" in summable_comparison_test)
 168.664 +apply (rule_tac [2] summable_exp)
 168.665 +apply (rule_tac x = 0 in exI)
 168.666 +apply (auto simp add: divide_inverse abs_mult power_abs [symmetric] zero_le_mult_iff)
 168.667 +done
 168.668 +
 168.669 +lemma summable_cos: 
 168.670 +      "summable (%n.  
 168.671 +           (if even n then  
 168.672 +           -1 ^ (n div 2)/(real (fact n)) else 0) * x ^ n)"
 168.673 +apply (rule_tac g = "(%n. inverse (real (fact n)) * \<bar>x\<bar> ^ n)" in summable_comparison_test)
 168.674 +apply (rule_tac [2] summable_exp)
 168.675 +apply (rule_tac x = 0 in exI)
 168.676 +apply (auto simp add: divide_inverse abs_mult power_abs [symmetric] zero_le_mult_iff)
 168.677 +done
 168.678 +
 168.679 +lemma lemma_STAR_sin:
 168.680 +     "(if even n then 0  
 168.681 +       else -1 ^ ((n - Suc 0) div 2)/(real (fact n))) * 0 ^ n = 0"
 168.682 +by (induct "n", auto)
 168.683 +
 168.684 +lemma lemma_STAR_cos:
 168.685 +     "0 < n -->  
 168.686 +      -1 ^ (n div 2)/(real (fact n)) * 0 ^ n = 0"
 168.687 +by (induct "n", auto)
 168.688 +
 168.689 +lemma lemma_STAR_cos1:
 168.690 +     "0 < n -->  
 168.691 +      (-1) ^ (n div 2)/(real (fact n)) * 0 ^ n = 0"
 168.692 +by (induct "n", auto)
 168.693 +
 168.694 +lemma lemma_STAR_cos2:
 168.695 +  "(\<Sum>n=1..<n. if even n then -1 ^ (n div 2)/(real (fact n)) *  0 ^ n 
 168.696 +                         else 0) = 0"
 168.697 +apply (induct "n")
 168.698 +apply (case_tac [2] "n", auto)
 168.699 +done
 168.700 +
 168.701 +lemma sin_converges: 
 168.702 +      "(%n. (if even n then 0  
 168.703 +            else -1 ^ ((n - Suc 0) div 2)/(real (fact n))) *  
 168.704 +                 x ^ n) sums sin(x)"
 168.705 +unfolding sin_def by (rule summable_sin [THEN summable_sums])
 168.706 +
 168.707 +lemma cos_converges: 
 168.708 +      "(%n. (if even n then  
 168.709 +           -1 ^ (n div 2)/(real (fact n))  
 168.710 +           else 0) * x ^ n) sums cos(x)"
 168.711 +unfolding cos_def by (rule summable_cos [THEN summable_sums])
 168.712 +
 168.713 +lemma sin_fdiffs: 
 168.714 +      "diffs(%n. if even n then 0  
 168.715 +           else -1 ^ ((n - Suc 0) div 2)/(real (fact n)))  
 168.716 +       = (%n. if even n then  
 168.717 +                 -1 ^ (n div 2)/(real (fact n))  
 168.718 +              else 0)"
 168.719 +by (auto intro!: ext 
 168.720 +         simp add: diffs_def divide_inverse real_of_nat_def of_nat_mult
 168.721 +         simp del: mult_Suc of_nat_Suc)
 168.722 +
 168.723 +lemma sin_fdiffs2: 
 168.724 +       "diffs(%n. if even n then 0  
 168.725 +           else -1 ^ ((n - Suc 0) div 2)/(real (fact n))) n  
 168.726 +       = (if even n then  
 168.727 +                 -1 ^ (n div 2)/(real (fact n))  
 168.728 +              else 0)"
 168.729 +by (simp only: sin_fdiffs)
 168.730 +
 168.731 +lemma cos_fdiffs: 
 168.732 +      "diffs(%n. if even n then  
 168.733 +                 -1 ^ (n div 2)/(real (fact n)) else 0)  
 168.734 +       = (%n. - (if even n then 0  
 168.735 +           else -1 ^ ((n - Suc 0)div 2)/(real (fact n))))"
 168.736 +by (auto intro!: ext 
 168.737 +         simp add: diffs_def divide_inverse odd_Suc_mult_two_ex real_of_nat_def of_nat_mult
 168.738 +         simp del: mult_Suc of_nat_Suc)
 168.739 +
 168.740 +
 168.741 +lemma cos_fdiffs2: 
 168.742 +      "diffs(%n. if even n then  
 168.743 +                 -1 ^ (n div 2)/(real (fact n)) else 0) n 
 168.744 +       = - (if even n then 0  
 168.745 +           else -1 ^ ((n - Suc 0)div 2)/(real (fact n)))"
 168.746 +by (simp only: cos_fdiffs)
 168.747 +
 168.748 +text{*Now at last we can get the derivatives of exp, sin and cos*}
 168.749 +
 168.750 +lemma lemma_sin_minus:
 168.751 +     "- sin x = (\<Sum>n. - ((if even n then 0 
 168.752 +                  else -1 ^ ((n - Suc 0) div 2)/(real (fact n))) * x ^ n))"
 168.753 +by (auto intro!: sums_unique sums_minus sin_converges)
 168.754 +
 168.755 +lemma lemma_sin_ext:
 168.756 +     "sin = (%x. \<Sum>n. 
 168.757 +                   (if even n then 0  
 168.758 +                       else -1 ^ ((n - Suc 0) div 2)/(real (fact n))) *  
 168.759 +                   x ^ n)"
 168.760 +by (auto intro!: ext simp add: sin_def)
 168.761 +
 168.762 +lemma lemma_cos_ext:
 168.763 +     "cos = (%x. \<Sum>n. 
 168.764 +                   (if even n then -1 ^ (n div 2)/(real (fact n)) else 0) *
 168.765 +                   x ^ n)"
 168.766 +by (auto intro!: ext simp add: cos_def)
 168.767 +
 168.768 +lemma DERIV_sin [simp]: "DERIV sin x :> cos(x)"
 168.769 +apply (simp add: cos_def)
 168.770 +apply (subst lemma_sin_ext)
 168.771 +apply (auto simp add: sin_fdiffs2 [symmetric])
 168.772 +apply (rule_tac K = "1 + \<bar>x\<bar>" in termdiffs)
 168.773 +apply (auto intro: sin_converges cos_converges sums_summable intro!: sums_minus [THEN sums_summable] simp add: cos_fdiffs sin_fdiffs)
 168.774 +done
 168.775 +
 168.776 +lemma DERIV_cos [simp]: "DERIV cos x :> -sin(x)"
 168.777 +apply (subst lemma_cos_ext)
 168.778 +apply (auto simp add: lemma_sin_minus cos_fdiffs2 [symmetric] minus_mult_left)
 168.779 +apply (rule_tac K = "1 + \<bar>x\<bar>" in termdiffs)
 168.780 +apply (auto intro: sin_converges cos_converges sums_summable intro!: sums_minus [THEN sums_summable] simp add: cos_fdiffs sin_fdiffs diffs_minus)
 168.781 +done
 168.782 +
 168.783 +lemma isCont_sin [simp]: "isCont sin x"
 168.784 +by (rule DERIV_sin [THEN DERIV_isCont])
 168.785 +
 168.786 +lemma isCont_cos [simp]: "isCont cos x"
 168.787 +by (rule DERIV_cos [THEN DERIV_isCont])
 168.788 +
 168.789 +
 168.790 +subsection {* Properties of Sine and Cosine *}
 168.791  
 168.792  lemma sin_zero [simp]: "sin 0 = 0"
 168.793  unfolding sin_def by (simp add: powser_zero)
 168.794 @@ -1088,9 +1054,6 @@
 168.795  apply (simp del: realpow_Suc)
 168.796  done
 168.797  
 168.798 -lemma real_gt_one_ge_zero_add_less: "[| 1 < x; 0 \<le> y |] ==> 1 < x + (y::real)"
 168.799 -by arith
 168.800 -
 168.801  lemma abs_sin_le_one [simp]: "\<bar>sin x\<bar> \<le> 1"
 168.802  by (rule power2_le_imp_le, simp_all add: sin_squared_eq)
 168.803  
 168.804 @@ -1187,7 +1150,7 @@
 168.805  apply (auto simp add: diff_minus left_distrib right_distrib mult_ac add_ac)
 168.806  done
 168.807  
 168.808 -lemma sin_cos_minus [simp]: 
 168.809 +lemma sin_cos_minus: 
 168.810      "(sin(-x) + (sin x)) ^ 2 + (cos(-x) - (cos x)) ^ 2 = 0"
 168.811  apply (cut_tac y = 0 and x = x 
 168.812         in lemma_DERIV_sin_cos_minus [THEN DERIV_isconst_all])
 168.813 @@ -1195,14 +1158,10 @@
 168.814  done
 168.815  
 168.816  lemma sin_minus [simp]: "sin (-x) = -sin(x)"
 168.817 -apply (cut_tac x = x in sin_cos_minus)
 168.818 -apply (simp del: sin_cos_minus)
 168.819 -done
 168.820 +  using sin_cos_minus [where x=x] by simp
 168.821  
 168.822  lemma cos_minus [simp]: "cos (-x) = cos(x)"
 168.823 -apply (cut_tac x = x in sin_cos_minus)
 168.824 -apply (simp del: sin_cos_minus)
 168.825 -done
 168.826 +  using sin_cos_minus [where x=x] by simp
 168.827  
 168.828  lemma sin_diff: "sin (x - y) = sin x * cos y - cos x * sin y"
 168.829  by (simp add: diff_minus sin_add)
 168.830 @@ -1217,16 +1176,14 @@
 168.831  by (simp add: cos_diff mult_commute)
 168.832  
 168.833  lemma sin_double [simp]: "sin(2 * x) = 2* sin x * cos x"
 168.834 -by (cut_tac x = x and y = x in sin_add, auto)
 168.835 -
 168.836 +  using sin_add [where x=x and y=x] by simp
 168.837  
 168.838  lemma cos_double: "cos(2* x) = ((cos x)\<twosuperior>) - ((sin x)\<twosuperior>)"
 168.839 -apply (cut_tac x = x and y = x in cos_add)
 168.840 -apply (simp add: power2_eq_square)
 168.841 -done
 168.842 +  using cos_add [where x=x and y=x]
 168.843 +  by (simp add: power2_eq_square)
 168.844  
 168.845  
 168.846 -subsection{*The Constant Pi*}
 168.847 +subsection {* The Constant Pi *}
 168.848  
 168.849  definition
 168.850    pi :: "real" where
 168.851 @@ -1401,8 +1358,8 @@
 168.852  lemma pi_not_less_zero [simp]: "\<not> pi < 0"
 168.853  by (simp add: linorder_not_less)
 168.854  
 168.855 -lemma minus_pi_half_less_zero [simp]: "-(pi/2) < 0"
 168.856 -by auto
 168.857 +lemma minus_pi_half_less_zero: "-(pi/2) < 0"
 168.858 +by simp
 168.859  
 168.860  lemma sin_pi_half [simp]: "sin(pi/2) = 1"
 168.861  apply (cut_tac x = "pi/2" in sin_cos_squared_add2)
 168.862 @@ -1614,7 +1571,7 @@
 168.863  done
 168.864  
 168.865  
 168.866 -subsection{*Tangent*}
 168.867 +subsection {* Tangent *}
 168.868  
 168.869  definition
 168.870    tan :: "real => real" where
 168.871 @@ -2139,11 +2096,6 @@
 168.872  lemma sin_zero_abs_cos_one: "sin x = 0 ==> \<bar>cos x\<bar> = 1"
 168.873  by (auto simp add: sin_zero_iff even_mult_two_ex)
 168.874  
 168.875 -lemma exp_eq_one_iff [simp]: "(exp (x::real) = 1) = (x = 0)"
 168.876 -apply auto
 168.877 -apply (drule_tac f = ln in arg_cong, auto)
 168.878 -done
 168.879 -
 168.880  lemma cos_one_sin_zero: "cos x = 1 ==> sin x = 0"
 168.881  by (cut_tac x = x in sin_cos_squared_add3, auto)
 168.882  
 168.883 @@ -2190,60 +2142,4 @@
 168.884  apply (erule polar_ex2)
 168.885  done
 168.886  
 168.887 -
 168.888 -subsection {* Theorems about Limits *}
 168.889 -
 168.890 -(* need to rename second isCont_inverse *)
 168.891 -
 168.892 -lemma isCont_inv_fun:
 168.893 -  fixes f g :: "real \<Rightarrow> real"
 168.894 -  shows "[| 0 < d; \<forall>z. \<bar>z - x\<bar> \<le> d --> g(f(z)) = z;  
 168.895 -         \<forall>z. \<bar>z - x\<bar> \<le> d --> isCont f z |]  
 168.896 -      ==> isCont g (f x)"
 168.897 -by (rule isCont_inverse_function)
 168.898 -
 168.899 -lemma isCont_inv_fun_inv:
 168.900 -  fixes f g :: "real \<Rightarrow> real"
 168.901 -  shows "[| 0 < d;  
 168.902 -         \<forall>z. \<bar>z - x\<bar> \<le> d --> g(f(z)) = z;  
 168.903 -         \<forall>z. \<bar>z - x\<bar> \<le> d --> isCont f z |]  
 168.904 -       ==> \<exists>e. 0 < e &  
 168.905 -             (\<forall>y. 0 < \<bar>y - f(x)\<bar> & \<bar>y - f(x)\<bar> < e --> f(g(y)) = y)"
 168.906 -apply (drule isCont_inj_range)
 168.907 -prefer 2 apply (assumption, assumption, auto)
 168.908 -apply (rule_tac x = e in exI, auto)
 168.909 -apply (rotate_tac 2)
 168.910 -apply (drule_tac x = y in spec, auto)
 168.911 -done
 168.912 -
 168.913 -
 168.914 -text{*Bartle/Sherbert: Introduction to Real Analysis, Theorem 4.2.9, p. 110*}
 168.915 -lemma LIM_fun_gt_zero:
 168.916 -     "[| f -- c --> (l::real); 0 < l |]  
 168.917 -         ==> \<exists>r. 0 < r & (\<forall>x::real. x \<noteq> c & \<bar>c - x\<bar> < r --> 0 < f x)"
 168.918 -apply (auto simp add: LIM_def)
 168.919 -apply (drule_tac x = "l/2" in spec, safe, force)
 168.920 -apply (rule_tac x = s in exI)
 168.921 -apply (auto simp only: abs_less_iff)
 168.922 -done
 168.923 -
 168.924 -lemma LIM_fun_less_zero:
 168.925 -     "[| f -- c --> (l::real); l < 0 |]  
 168.926 -      ==> \<exists>r. 0 < r & (\<forall>x::real. x \<noteq> c & \<bar>c - x\<bar> < r --> f x < 0)"
 168.927 -apply (auto simp add: LIM_def)
 168.928 -apply (drule_tac x = "-l/2" in spec, safe, force)
 168.929 -apply (rule_tac x = s in exI)
 168.930 -apply (auto simp only: abs_less_iff)
 168.931 -done
 168.932 -
 168.933 -
 168.934 -lemma LIM_fun_not_zero:
 168.935 -     "[| f -- c --> (l::real); l \<noteq> 0 |] 
 168.936 -      ==> \<exists>r. 0 < r & (\<forall>x::real. x \<noteq> c & \<bar>c - x\<bar> < r --> f x \<noteq> 0)"
 168.937 -apply (cut_tac x = l and y = 0 in linorder_less_linear, auto)
 168.938 -apply (drule LIM_fun_less_zero)
 168.939 -apply (drule_tac [3] LIM_fun_gt_zero)
 168.940 -apply force+
 168.941 -done
 168.942 -  
 168.943  end 
   169.1 --- a/src/HOL/Wellfounded.thy	Tue Dec 30 08:18:54 2008 +0100
   169.2 +++ b/src/HOL/Wellfounded.thy	Tue Dec 30 11:10:01 2008 +0100
   169.3 @@ -842,6 +842,11 @@
   169.4    qed
   169.5  qed
   169.6  
   169.7 +lemma max_ext_additive: 
   169.8 + "(A, B) \<in> max_ext R \<Longrightarrow> (C, D) \<in> max_ext R \<Longrightarrow>
   169.9 +  (A \<union> C, B \<union> D) \<in> max_ext R"
  169.10 +by (force elim!: max_ext.cases)
  169.11 +
  169.12  
  169.13  definition
  169.14    min_ext :: "('a \<times> 'a) set \<Rightarrow> ('a set \<times> 'a set) set" 
   170.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   170.2 +++ b/src/HOL/ex/CodegenSML_Test.thy	Tue Dec 30 11:10:01 2008 +0100
   170.3 @@ -0,0 +1,54 @@
   170.4 +(*  Title:      Test file for Stefan Berghofer's SML code generator
   170.5 +    Author:     Tobias Nipkow, TU Muenchen
   170.6 +*)
   170.7 +
   170.8 +theory CodegenSML_Test
   170.9 +imports Executable_Set
  170.10 +begin
  170.11 +
  170.12 +lemma "True : {False, True} & False ~: {True}"
  170.13 +by evaluation
  170.14 +
  170.15 +lemma
  170.16 +"eq_set ({1::nat,2,3,2} \<union> {3,1,2,1}) {2,2,3,1} &
  170.17 + eq_set ({1::nat,2,3,2} \<union> {4,1,5,1}) {4,4,5,1,2,3}"
  170.18 +by evaluation
  170.19 +
  170.20 +lemma
  170.21 +"eq_set ({1::nat,2,3,2} \<inter> {3,1,2,1}) {2,2,3,1} & 
  170.22 + eq_set ({1::nat,2,3,2} \<inter> {4,1,5,2}) {2,1,2}"
  170.23 +by evaluation
  170.24 +
  170.25 +lemma
  170.26 +"eq_set ({1::nat,2,3,2} - {3,1,2,1}) {} & 
  170.27 + eq_set ({1::nat,2,3,2} - {4,1,5,2}) {3}"
  170.28 +by evaluation
  170.29 +
  170.30 +lemma
  170.31 +"eq_set (Union{{1::nat,2,3,2}, {3,1,2,1}}) {2,2,3,1} &
  170.32 + eq_set (Union{{1::nat,2,3,2}, {4,1,5,1}}) {4,4,5,1,2,3}"
  170.33 +by evaluation
  170.34 +
  170.35 +lemma
  170.36 +"eq_set (Inter{{1::nat,2,3,2}, {3,1,2,1}}) {2,2,3,1} & 
  170.37 + eq_set (Inter{{1::nat,2,3,2}, {4,1,5,2}}) {2,1,2}"
  170.38 +by evaluation
  170.39 +
  170.40 +lemma "eq_set ((%x. x+2) ` {1::nat,2,3,2}) {4,5,3,3}"
  170.41 +by evaluation
  170.42 +
  170.43 +lemma
  170.44 +"(ALL x:{1::nat,2,3,2}. EX y : {4,5,2}. x < y) &
  170.45 + (EX x:{1::nat,2,3,2}. ALL y : {4,5,6}. x < y)"
  170.46 +by evaluation
  170.47 +
  170.48 +lemma
  170.49 +"eq_set {x : {4::nat,7,10}. 2 dvd x } {4,10}"
  170.50 +by evaluation
  170.51 +
  170.52 +lemma
  170.53 +"fold (op +) (5::int) {3,7,9} = 24 &
  170.54 + fold_image (op *) id (2::int) {3,4,5} = 120"
  170.55 +by evaluation
  170.56 +
  170.57 +end
   171.1 --- a/src/HOL/ex/ExecutableContent.thy	Tue Dec 30 08:18:54 2008 +0100
   171.2 +++ b/src/HOL/ex/ExecutableContent.thy	Tue Dec 30 11:10:01 2008 +0100
   171.3 @@ -24,4 +24,11 @@
   171.4    "~~/src/HOL/ex/Records"
   171.5  begin
   171.6  
   171.7 +text {* However, some aren't executable *}
   171.8 +
   171.9 +declare pair_leq_def[code del]
  171.10 +declare max_weak_def[code del]
  171.11 +declare min_weak_def[code del]
  171.12 +declare ms_weak_def[code del]
  171.13 +
  171.14  end
   172.1 --- a/src/HOL/ex/LexOrds.thy	Tue Dec 30 08:18:54 2008 +0100
   172.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   172.3 @@ -1,182 +0,0 @@
   172.4 -(* Title:       HOL/ex/LexOrds.thy
   172.5 -   ID:          $Id$
   172.6 -   Author:      Lukas Bulwahn, TU Muenchen
   172.7 -*)
   172.8 -
   172.9 -header {* Examples and regression tests for method lexicographic order. *}
  172.10 - 
  172.11 -theory LexOrds
  172.12 -imports Main
  172.13 -begin
  172.14 -
  172.15 -subsection {* Trivial examples *}
  172.16 -
  172.17 -fun identity :: "nat \<Rightarrow> nat"
  172.18 -where
  172.19 -  "identity n = n"
  172.20 -
  172.21 -fun yaSuc :: "nat \<Rightarrow> nat"
  172.22 -where 
  172.23 -  "yaSuc 0 = 0"
  172.24 -| "yaSuc (Suc n) = Suc (yaSuc n)"
  172.25 -
  172.26 -
  172.27 -subsection {* Examples on natural numbers *}
  172.28 -
  172.29 -fun bin :: "(nat * nat) \<Rightarrow> nat"
  172.30 -where
  172.31 -  "bin (0, 0) = 1"
  172.32 -| "bin (Suc n, 0) = 0"
  172.33 -| "bin (0, Suc m) = 0"
  172.34 -| "bin (Suc n, Suc m) = bin (n, m) + bin (Suc n, m)"
  172.35 -
  172.36 -
  172.37 -fun t :: "(nat * nat) \<Rightarrow> nat"
  172.38 -where
  172.39 -  "t (0,n) = 0"
  172.40 -| "t (n,0) = 0"
  172.41 -| "t (Suc n, Suc m) = (if (n mod 2 = 0) then (t (Suc n, m)) else (t (n, Suc m)))" 
  172.42 -
  172.43 -
  172.44 -fun k :: "(nat * nat) * (nat * nat) \<Rightarrow> nat"
  172.45 -where
  172.46 -  "k ((0,0),(0,0)) = 0"
  172.47 -| "k ((Suc z, y), (u,v)) = k((z, y), (u, v))" (* z is descending *)
  172.48 -| "k ((0, Suc y), (u,v)) = k((1, y), (u, v))" (* y is descending *)
  172.49 -| "k ((0,0), (Suc u, v)) = k((1, 1), (u, v))" (* u is descending *)
  172.50 -| "k ((0,0), (0, Suc v)) = k((1,1), (1,v))"   (* v is descending *)
  172.51 -
  172.52 -
  172.53 -fun gcd2 :: "nat \<Rightarrow> nat \<Rightarrow> nat"
  172.54 -where
  172.55 -  "gcd2 x 0 = x"
  172.56 -| "gcd2 0 y = y"
  172.57 -| "gcd2 (Suc x) (Suc y) = (if x < y then gcd2 (Suc x) (y - x)
  172.58 -                                    else gcd2 (x - y) (Suc y))"
  172.59 -
  172.60 -fun ack :: "(nat * nat) \<Rightarrow> nat"
  172.61 -where
  172.62 -  "ack (0, m) = Suc m"
  172.63 -| "ack (Suc n, 0) = ack(n, 1)"
  172.64 -| "ack (Suc n, Suc m) = ack (n, ack (Suc n, m))"
  172.65 -
  172.66 -
  172.67 -fun greedy :: "nat * nat * nat * nat * nat => nat"
  172.68 -where
  172.69 -  "greedy (Suc a, Suc b, Suc c, Suc d, Suc e) =
  172.70 -  (if (a < 10) then greedy (Suc a, Suc b, c, d + 2, Suc e) else
  172.71 -  (if (a < 20) then greedy (Suc a, b, Suc c, d, Suc e) else
  172.72 -  (if (a < 30) then greedy (Suc a, b, Suc c, d, Suc e) else
  172.73 -  (if (a < 40) then greedy (Suc a, b, Suc c, d, Suc e) else
  172.74 -  (if (a < 50) then greedy (Suc a, b, Suc c, d, Suc e) else
  172.75 -  (if (a < 60) then greedy (a, Suc b, Suc c, d, Suc e) else
  172.76 -  (if (a < 70) then greedy (a, Suc b, Suc c, d, Suc e) else
  172.77 -  (if (a < 80) then greedy (a, Suc b, Suc c, d, Suc e) else
  172.78 -  (if (a < 90) then greedy (Suc a, Suc b, Suc c, d, e) else
  172.79 -  greedy (Suc a, Suc b, Suc c, d, e))))))))))"
  172.80 -| "greedy (a, b, c, d, e) = 0"
  172.81 -
  172.82 -
  172.83 -fun blowup :: "nat => nat => nat => nat => nat => nat => nat => nat => nat => nat"
  172.84 -where
  172.85 -  "blowup 0 0 0 0 0 0 0 0 0 = 0"
  172.86 -| "blowup 0 0 0 0 0 0 0 0 (Suc i) = Suc (blowup i i i i i i i i i)"
  172.87 -| "blowup 0 0 0 0 0 0 0 (Suc h) i = Suc (blowup h h h h h h h h i)"
  172.88 -| "blowup 0 0 0 0 0 0 (Suc g) h i = Suc (blowup g g g g g g g h i)"
  172.89 -| "blowup 0 0 0 0 0 (Suc f) g h i = Suc (blowup f f f f f f g h i)"
  172.90 -| "blowup 0 0 0 0 (Suc e) f g h i = Suc (blowup e e e e e f g h i)"
  172.91 -| "blowup 0 0 0 (Suc d) e f g h i = Suc (blowup d d d d e f g h i)"
  172.92 -| "blowup 0 0 (Suc c) d e f g h i = Suc (blowup c c c d e f g h i)"
  172.93 -| "blowup 0 (Suc b) c d e f g h i = Suc (blowup b b c d e f g h i)"
  172.94 -| "blowup (Suc a) b c d e f g h i = Suc (blowup a b c d e f g h i)"
  172.95 -
  172.96 -  
  172.97 -subsection {* Simple examples with other datatypes than nat, e.g. trees and lists *}
  172.98 -
  172.99 -datatype tree = Node | Branch tree tree
 172.100 -
 172.101 -fun g_tree :: "tree * tree \<Rightarrow> tree"
 172.102 -where
 172.103 -  "g_tree (Node, Node) = Node"
 172.104 -| "g_tree (Node, Branch a b) = Branch Node (g_tree (a,b))"
 172.105 -| "g_tree (Branch a b, Node) = Branch (g_tree (a,Node)) b"
 172.106 -| "g_tree (Branch a b, Branch c d) = Branch (g_tree (a,c)) (g_tree (b,d))"
 172.107 -
 172.108 -
 172.109 -fun acklist :: "'a list * 'a list \<Rightarrow> 'a list"
 172.110 -where
 172.111 -  "acklist ([], m) = ((hd m)#m)"
 172.112 -|  "acklist (n#ns, []) = acklist (ns, [n])"
 172.113 -|  "acklist ((n#ns), (m#ms)) = acklist (ns, acklist ((n#ns), ms))"
 172.114 -
 172.115 -
 172.116 -subsection {* Examples with mutual recursion *}
 172.117 -
 172.118 -fun evn od :: "nat \<Rightarrow> bool"
 172.119 -where
 172.120 -  "evn 0 = True"
 172.121 -| "od 0 = False"
 172.122 -| "evn (Suc n) = od (Suc n)"
 172.123 -| "od (Suc n) = evn n"
 172.124 -
 172.125 -
 172.126 -fun sizechange_f :: "'a list => 'a list => 'a list" and
 172.127 -sizechange_g :: "'a list => 'a list => 'a list => 'a list"
 172.128 -where
 172.129 -  "sizechange_f i x = (if i=[] then x else sizechange_g (tl i) x i)"
 172.130 -| "sizechange_g a b c = sizechange_f a (b @ c)"
 172.131 -
 172.132 -
 172.133 -fun
 172.134 -  prod :: "nat => nat => nat => nat" and
 172.135 -  eprod :: "nat => nat => nat => nat" and
 172.136 -  oprod :: "nat => nat => nat => nat"
 172.137 -where
 172.138 -  "prod x y z = (if y mod 2 = 0 then eprod x y z else oprod x y z)"
 172.139 -| "oprod x y z = eprod x (y - 1) (z+x)"
 172.140 -| "eprod x y z = (if y=0 then z else prod (2*x) (y div 2) z)"
 172.141 -
 172.142 -
 172.143 -fun
 172.144 -  pedal :: "nat => nat => nat => nat"
 172.145 -and
 172.146 -  coast :: "nat => nat => nat => nat"
 172.147 -where
 172.148 -  "pedal 0 m c = c"
 172.149 -| "pedal n 0 c = c"
 172.150 -| "pedal n m c =
 172.151 -     (if n < m then coast (n - 1) (m - 1) (c + m)
 172.152 -               else pedal (n - 1) m (c + m))"
 172.153 -
 172.154 -| "coast n m c =
 172.155 -     (if n < m then coast n (m - 1) (c + n)
 172.156 -               else pedal n m (c + n))"
 172.157 -
 172.158 -
 172.159 -subsection {*Examples for an unprovable termination *}
 172.160 -
 172.161 -text {* If termination cannot be proven, the tactic gives further information about unprovable subgoals on the arguments *}
 172.162 -
 172.163 -function noterm :: "(nat * nat) \<Rightarrow> nat"
 172.164 -where
 172.165 -  "noterm (a,b) = noterm(b,a)"
 172.166 -by pat_completeness auto
 172.167 -(* termination by apply lexicographic_order*)
 172.168 -
 172.169 -function term_but_no_prove :: "nat * nat \<Rightarrow> nat"
 172.170 -where
 172.171 -  "term_but_no_prove (0,0) = 1"
 172.172 -| "term_but_no_prove (0, Suc b) = 0"
 172.173 -| "term_but_no_prove (Suc a, 0) = 0"
 172.174 -| "term_but_no_prove (Suc a, Suc b) = term_but_no_prove (b, a)"
 172.175 -by pat_completeness auto
 172.176 -(* termination by lexicographic_order *)
 172.177 -
 172.178 -text{* The tactic distinguishes between N = not provable AND F = False *}
 172.179 -function no_proof :: "nat \<Rightarrow> nat"
 172.180 -where
 172.181 -  "no_proof m = no_proof (Suc m)"
 172.182 -by pat_completeness auto
 172.183 -(* termination by lexicographic_order *)
 172.184 -
 172.185 -end
 172.186 \ No newline at end of file
   173.1 --- a/src/HOL/ex/Quickcheck.thy	Tue Dec 30 08:18:54 2008 +0100
   173.2 +++ b/src/HOL/ex/Quickcheck.thy	Tue Dec 30 11:10:01 2008 +0100
   173.3 @@ -1,11 +1,9 @@
   173.4 -(*  ID:         $Id$
   173.5 -    Author:     Florian Haftmann, TU Muenchen
   173.6 -*)
   173.7 +(* Author: Florian Haftmann, TU Muenchen *)
   173.8  
   173.9  header {* A simple counterexample generator *}
  173.10  
  173.11  theory Quickcheck
  173.12 -imports Random Code_Eval
  173.13 +imports Random Code_Eval Map
  173.14  begin
  173.15  
  173.16  subsection {* The @{text random} class *}
  173.17 @@ -25,166 +23,6 @@
  173.18  
  173.19  end
  173.20  
  173.21 -text {* Datatypes *}
  173.22 -
  173.23 -definition
  173.24 -  collapse :: "('a \<Rightarrow> ('a \<Rightarrow> 'b \<times> 'a) \<times> 'a) \<Rightarrow> 'a \<Rightarrow> 'b \<times> 'a" where
  173.25 -  "collapse f = (do g \<leftarrow> f; g done)"
  173.26 -
  173.27 -ML {*
  173.28 -structure StateMonad =
  173.29 -struct
  173.30 -
  173.31 -fun liftT T sT = sT --> HOLogic.mk_prodT (T, sT);
  173.32 -fun liftT' sT = sT --> sT;
  173.33 -
  173.34 -fun return T sT x = Const (@{const_name return}, T --> liftT T sT) $ x;
  173.35 -
  173.36 -fun scomp T1 T2 sT f g = Const (@{const_name scomp},
  173.37 -  liftT T1 sT --> (T1 --> liftT T2 sT) --> liftT T2 sT) $ f $ g;
  173.38 -
  173.39 -end;
  173.40 -*}
  173.41 -
  173.42 -lemma random'_if:
  173.43 -  fixes random' :: "index \<Rightarrow> index \<Rightarrow> seed \<Rightarrow> ('a \<times> (unit \<Rightarrow> term)) \<times> seed"
  173.44 -  assumes "random' 0 j = (\<lambda>s. undefined)"
  173.45 -    and "\<And>i. random' (Suc_index i) j = rhs2 i"
  173.46 -  shows "random' i j s = (if i = 0 then undefined else rhs2 (i - 1) s)"
  173.47 -  by (cases i rule: index.exhaust) (insert assms, simp_all)
  173.48 -
  173.49 -setup {*
  173.50 -let
  173.51 -  exception REC of string;
  173.52 -  fun mk_collapse thy ty = Sign.mk_const thy
  173.53 -    (@{const_name collapse}, [@{typ seed}, ty]);
  173.54 -  fun term_ty ty = HOLogic.mk_prodT (ty, @{typ "unit \<Rightarrow> term"});
  173.55 -  fun mk_split thy ty ty' = Sign.mk_const thy
  173.56 -    (@{const_name split}, [ty, @{typ "unit \<Rightarrow> term"}, StateMonad.liftT (term_ty ty') @{typ seed}]);
  173.57 -  fun mk_scomp_split thy ty ty' t t' =
  173.58 -    StateMonad.scomp (term_ty ty) (term_ty ty') @{typ seed} t
  173.59 -      (mk_split thy ty ty' $ Abs ("", ty, Abs ("", @{typ "unit \<Rightarrow> term"}, t')))
  173.60 -  fun mk_cons thy this_ty (c, args) =
  173.61 -    let
  173.62 -      val tys = map (fst o fst) args;
  173.63 -      val c_ty = tys ---> this_ty;
  173.64 -      val c = Const (c, tys ---> this_ty);
  173.65 -      val t_indices = map (curry ( op * ) 2) (length tys - 1 downto 0);
  173.66 -      val c_indices = map (curry ( op + ) 1) t_indices;
  173.67 -      val c_t = list_comb (c, map Bound c_indices);
  173.68 -      val t_t = Abs ("", @{typ unit}, Eval.mk_term Free Typerep.typerep
  173.69 -        (list_comb (c, map (fn k => Bound (k + 1)) t_indices))
  173.70 -        |> map_aterms (fn t as Bound _ => t $ @{term "()"} | t => t));
  173.71 -      val return = StateMonad.return (term_ty this_ty) @{typ seed}
  173.72 -        (HOLogic.mk_prod (c_t, t_t));
  173.73 -      val t = fold_rev (fn ((ty, _), random) =>
  173.74 -        mk_scomp_split thy ty this_ty random)
  173.75 -          args return;
  173.76 -      val is_rec = exists (snd o fst) args;
  173.77 -    in (is_rec, t) end;
  173.78 -  fun mk_conss thy ty [] = NONE
  173.79 -    | mk_conss thy ty [(_, t)] = SOME t
  173.80 -    | mk_conss thy ty ts = SOME (mk_collapse thy (term_ty ty) $
  173.81 -          (Sign.mk_const thy (@{const_name select}, [StateMonad.liftT (term_ty ty) @{typ seed}]) $
  173.82 -            HOLogic.mk_list (StateMonad.liftT (term_ty ty) @{typ seed}) (map snd ts)));
  173.83 -  fun mk_clauses thy ty (tyco, (ts_rec, ts_atom)) = 
  173.84 -    let
  173.85 -      val SOME t_atom = mk_conss thy ty ts_atom;
  173.86 -    in case mk_conss thy ty ts_rec
  173.87 -     of SOME t_rec => mk_collapse thy (term_ty ty) $
  173.88 -          (Sign.mk_const thy (@{const_name select_default}, [StateMonad.liftT (term_ty ty) @{typ seed}]) $
  173.89 -             @{term "i\<Colon>index"} $ t_rec $ t_atom)
  173.90 -      | NONE => t_atom
  173.91 -    end;
  173.92 -  fun mk_random_eqs thy vs tycos =
  173.93 -    let
  173.94 -      val this_ty = Type (hd tycos, map TFree vs);
  173.95 -      val this_ty' = StateMonad.liftT (term_ty this_ty) @{typ seed};
  173.96 -      val random_name = NameSpace.base @{const_name random};
  173.97 -      val random'_name = random_name ^ "_" ^ Class.type_name (hd tycos) ^ "'";
  173.98 -      fun random ty = Sign.mk_const thy (@{const_name random}, [ty]);
  173.99 -      val random' = Free (random'_name,
 173.100 -        @{typ index} --> @{typ index} --> this_ty');
 173.101 -      fun atom ty = ((ty, false), random ty $ @{term "j\<Colon>index"});
 173.102 -      fun dtyp tyco = ((this_ty, true), random' $ @{term "i\<Colon>index"} $ @{term "j\<Colon>index"});
 173.103 -      fun rtyp tyco tys = raise REC
 173.104 -        ("Will not generate random elements for mutual recursive type " ^ quote (hd tycos));
 173.105 -      val rhss = DatatypePackage.construction_interpretation thy
 173.106 -            { atom = atom, dtyp = dtyp, rtyp = rtyp } vs tycos
 173.107 -        |> (map o apsnd o map) (mk_cons thy this_ty) 
 173.108 -        |> (map o apsnd) (List.partition fst)
 173.109 -        |> map (mk_clauses thy this_ty)
 173.110 -      val eqss = map ((apsnd o map) (HOLogic.mk_Trueprop o HOLogic.mk_eq) o (fn rhs => ((this_ty, random'), [
 173.111 -          (random' $ @{term "0\<Colon>index"} $ @{term "j\<Colon>index"}, Abs ("s", @{typ seed},
 173.112 -            Const (@{const_name undefined}, HOLogic.mk_prodT (term_ty this_ty, @{typ seed})))),
 173.113 -          (random' $ @{term "Suc_index i"} $ @{term "j\<Colon>index"}, rhs)
 173.114 -        ]))) rhss;
 173.115 -    in eqss end;
 173.116 -  fun random_inst [tyco] thy =
 173.117 -        let
 173.118 -          val (raw_vs, _) = DatatypePackage.the_datatype_spec thy tyco;
 173.119 -          val vs = (map o apsnd)
 173.120 -            (curry (Sorts.inter_sort (Sign.classes_of thy)) @{sort random}) raw_vs;
 173.121 -          val { descr, index, ... } = DatatypePackage.the_datatype thy tyco;
 173.122 -          val ((this_ty, random'), eqs') = singleton (mk_random_eqs thy vs) tyco;
 173.123 -          val eq = (HOLogic.mk_Trueprop o HOLogic.mk_eq)
 173.124 -            (Sign.mk_const thy (@{const_name random}, [this_ty]) $ @{term "i\<Colon>index"},
 173.125 -               random' $ @{term "i\<Colon>index"} $ @{term "i\<Colon>index"})
 173.126 -          val del_func = Attrib.internal (fn _ => Thm.declaration_attribute
 173.127 -            (fn thm => Context.mapping (Code.del_eqn thm) I));
 173.128 -          fun add_code simps lthy =
 173.129 -            let
 173.130 -              val thy = ProofContext.theory_of lthy;
 173.131 -              val thm = @{thm random'_if}
 173.132 -                |> Drule.instantiate' [SOME (Thm.ctyp_of thy this_ty)] [SOME (Thm.cterm_of thy random')]
 173.133 -                |> (fn thm => thm OF simps)
 173.134 -                |> singleton (ProofContext.export lthy (ProofContext.init thy));
 173.135 -              val c = (fst o dest_Const o fst o strip_comb o fst
 173.136 -                o HOLogic.dest_eq o HOLogic.dest_Trueprop o Thm.prop_of) thm;
 173.137 -            in
 173.138 -              lthy
 173.139 -              |> LocalTheory.theory (Code.del_eqns c
 173.140 -                   #> PureThy.add_thm ((fst (dest_Free random') ^ "_code", thm), [Thm.kind_internal])
 173.141 -                   #-> Code.add_eqn)
 173.142 -            end;
 173.143 -        in
 173.144 -          thy
 173.145 -          |> TheoryTarget.instantiation ([tyco], vs, @{sort random})
 173.146 -          |> PrimrecPackage.add_primrec
 173.147 -               [(Binding.name (fst (dest_Free random')), SOME (snd (dest_Free random')), NoSyn)]
 173.148 -                 (map (fn eq => ((Binding.empty, [del_func]), eq)) eqs')
 173.149 -          |-> add_code
 173.150 -          |> `(fn lthy => Syntax.check_term lthy eq)
 173.151 -          |-> (fn eq => Specification.definition (NONE, (Attrib.empty_binding, eq)))
 173.152 -          |> snd
 173.153 -          |> Class.prove_instantiation_instance (K (Class.intro_classes_tac []))
 173.154 -          |> LocalTheory.exit_global
 173.155 -        end
 173.156 -    | random_inst tycos thy = raise REC
 173.157 -        ("Will not generate random elements for mutual recursive type(s) " ^ commas (map quote tycos));
 173.158 -  fun add_random_inst tycos thy = random_inst tycos thy
 173.159 -     handle REC msg => (warning msg; thy);
 173.160 -in DatatypePackage.interpretation add_random_inst end
 173.161 -*}
 173.162 -
 173.163 -text {* Type @{typ int} *}
 173.164 -
 173.165 -instantiation int :: random
 173.166 -begin
 173.167 -
 173.168 -definition
 173.169 -  "random n = (do
 173.170 -     (b, _) \<leftarrow> random n;
 173.171 -     (m, t) \<leftarrow> random n;
 173.172 -     return (if b then (int m, \<lambda>u. Code_Eval.App (Code_Eval.Const (STR ''Int.int'') TYPEREP(nat \<Rightarrow> int)) (t ()))
 173.173 -       else (- int m, \<lambda>u. Code_Eval.App (Code_Eval.Const (STR ''HOL.uminus_class.uminus'') TYPEREP(int \<Rightarrow> int))
 173.174 -         (Code_Eval.App (Code_Eval.Const (STR ''Int.int'') TYPEREP(nat \<Rightarrow> int)) (t ()))))
 173.175 -   done)"
 173.176 -
 173.177 -instance ..
 173.178 -
 173.179 -end
 173.180 -
 173.181  text {* Type @{typ "'a \<Rightarrow> 'b"} *}
 173.182  
 173.183  ML {*
 173.184 @@ -240,6 +78,170 @@
 173.185  
 173.186  code_reserved SML Random_Engine
 173.187  
 173.188 +text {* Datatypes *}
 173.189 +
 173.190 +definition
 173.191 +  collapse :: "('a \<Rightarrow> ('a \<Rightarrow> 'b \<times> 'a) \<times> 'a) \<Rightarrow> 'a \<Rightarrow> 'b \<times> 'a" where
 173.192 +  "collapse f = (do g \<leftarrow> f; g done)"
 173.193 +
 173.194 +ML {*
 173.195 +structure StateMonad =
 173.196 +struct
 173.197 +
 173.198 +fun liftT T sT = sT --> HOLogic.mk_prodT (T, sT);
 173.199 +fun liftT' sT = sT --> sT;
 173.200 +
 173.201 +fun return T sT x = Const (@{const_name return}, T --> liftT T sT) $ x;
 173.202 +
 173.203 +fun scomp T1 T2 sT f g = Const (@{const_name scomp},
 173.204 +  liftT T1 sT --> (T1 --> liftT T2 sT) --> liftT T2 sT) $ f $ g;
 173.205 +
 173.206 +end;
 173.207 +*}
 173.208 +
 173.209 +lemma random'_if:
 173.210 +  fixes random' :: "index \<Rightarrow> index \<Rightarrow> seed \<Rightarrow> ('a \<times> (unit \<Rightarrow> term)) \<times> seed"
 173.211 +  assumes "random' 0 j = (\<lambda>s. undefined)"
 173.212 +    and "\<And>i. random' (Suc_index i) j = rhs2 i"
 173.213 +  shows "random' i j s = (if i = 0 then undefined else rhs2 (i - 1) s)"
 173.214 +  by (cases i rule: index.exhaust) (insert assms, simp_all)
 173.215 +
 173.216 +setup {*
 173.217 +let
 173.218 +  exception REC of string;
 173.219 +  exception TYP of string;
 173.220 +  fun mk_collapse thy ty = Sign.mk_const thy
 173.221 +    (@{const_name collapse}, [@{typ seed}, ty]);
 173.222 +  fun term_ty ty = HOLogic.mk_prodT (ty, @{typ "unit \<Rightarrow> term"});
 173.223 +  fun mk_split thy ty ty' = Sign.mk_const thy
 173.224 +    (@{const_name split}, [ty, @{typ "unit \<Rightarrow> term"}, StateMonad.liftT (term_ty ty') @{typ seed}]);
 173.225 +  fun mk_scomp_split thy ty ty' t t' =
 173.226 +    StateMonad.scomp (term_ty ty) (term_ty ty') @{typ seed} t
 173.227 +      (mk_split thy ty ty' $ Abs ("", ty, Abs ("", @{typ "unit \<Rightarrow> term"}, t')))
 173.228 +  fun mk_cons thy this_ty (c, args) =
 173.229 +    let
 173.230 +      val tys = map (fst o fst) args;
 173.231 +      val c_ty = tys ---> this_ty;
 173.232 +      val c = Const (c, tys ---> this_ty);
 173.233 +      val t_indices = map (curry ( op * ) 2) (length tys - 1 downto 0);
 173.234 +      val c_indices = map (curry ( op + ) 1) t_indices;
 173.235 +      val c_t = list_comb (c, map Bound c_indices);
 173.236 +      val t_t = Abs ("", @{typ unit}, Eval.mk_term Free Typerep.typerep
 173.237 +        (list_comb (c, map (fn k => Bound (k + 1)) t_indices))
 173.238 +        |> map_aterms (fn t as Bound _ => t $ @{term "()"} | t => t));
 173.239 +      val return = StateMonad.return (term_ty this_ty) @{typ seed}
 173.240 +        (HOLogic.mk_prod (c_t, t_t));
 173.241 +      val t = fold_rev (fn ((ty, _), random) =>
 173.242 +        mk_scomp_split thy ty this_ty random)
 173.243 +          args return;
 173.244 +      val is_rec = exists (snd o fst) args;
 173.245 +    in (is_rec, t) end;
 173.246 +  fun mk_conss thy ty [] = NONE
 173.247 +    | mk_conss thy ty [(_, t)] = SOME t
 173.248 +    | mk_conss thy ty ts = SOME (mk_collapse thy (term_ty ty) $
 173.249 +          (Sign.mk_const thy (@{const_name select}, [StateMonad.liftT (term_ty ty) @{typ seed}]) $
 173.250 +            HOLogic.mk_list (StateMonad.liftT (term_ty ty) @{typ seed}) (map snd ts)));
 173.251 +  fun mk_clauses thy ty (tyco, (ts_rec, ts_atom)) = 
 173.252 +    let
 173.253 +      val SOME t_atom = mk_conss thy ty ts_atom;
 173.254 +    in case mk_conss thy ty ts_rec
 173.255 +     of SOME t_rec => mk_collapse thy (term_ty ty) $
 173.256 +          (Sign.mk_const thy (@{const_name select_default}, [StateMonad.liftT (term_ty ty) @{typ seed}]) $
 173.257 +             @{term "i\<Colon>index"} $ t_rec $ t_atom)
 173.258 +      | NONE => t_atom
 173.259 +    end;
 173.260 +  fun mk_random_eqs thy vs tycos =
 173.261 +    let
 173.262 +      val this_ty = Type (hd tycos, map TFree vs);
 173.263 +      val this_ty' = StateMonad.liftT (term_ty this_ty) @{typ seed};
 173.264 +      val random_name = NameSpace.base @{const_name random};
 173.265 +      val random'_name = random_name ^ "_" ^ Class.type_name (hd tycos) ^ "'";
 173.266 +      fun random ty = Sign.mk_const thy (@{const_name random}, [ty]);
 173.267 +      val random' = Free (random'_name,
 173.268 +        @{typ index} --> @{typ index} --> this_ty');
 173.269 +      fun atom ty = if Sign.of_sort thy (ty, @{sort random})
 173.270 +        then ((ty, false), random ty $ @{term "j\<Colon>index"})
 173.271 +        else raise TYP
 173.272 +          ("Will not generate random elements for type(s) " ^ quote (hd tycos));
 173.273 +      fun dtyp tyco = ((this_ty, true), random' $ @{term "i\<Colon>index"} $ @{term "j\<Colon>index"});
 173.274 +      fun rtyp tyco tys = raise REC
 173.275 +        ("Will not generate random elements for mutual recursive type " ^ quote (hd tycos));
 173.276 +      val rhss = DatatypePackage.construction_interpretation thy
 173.277 +            { atom = atom, dtyp = dtyp, rtyp = rtyp } vs tycos
 173.278 +        |> (map o apsnd o map) (mk_cons thy this_ty) 
 173.279 +        |> (map o apsnd) (List.partition fst)
 173.280 +        |> map (mk_clauses thy this_ty)
 173.281 +      val eqss = map ((apsnd o map) (HOLogic.mk_Trueprop o HOLogic.mk_eq) o (fn rhs => ((this_ty, random'), [
 173.282 +          (random' $ @{term "0\<Colon>index"} $ @{term "j\<Colon>index"}, Abs ("s", @{typ seed},
 173.283 +            Const (@{const_name undefined}, HOLogic.mk_prodT (term_ty this_ty, @{typ seed})))),
 173.284 +          (random' $ @{term "Suc_index i"} $ @{term "j\<Colon>index"}, rhs)
 173.285 +        ]))) rhss;
 173.286 +    in eqss end;
 173.287 +  fun random_inst [tyco] thy =
 173.288 +        let
 173.289 +          val (raw_vs, _) = DatatypePackage.the_datatype_spec thy tyco;
 173.290 +          val vs = (map o apsnd)
 173.291 +            (curry (Sorts.inter_sort (Sign.classes_of thy)) @{sort random}) raw_vs;
 173.292 +          val ((this_ty, random'), eqs') = singleton (mk_random_eqs thy vs) tyco;
 173.293 +          val eq = (HOLogic.mk_Trueprop o HOLogic.mk_eq)
 173.294 +            (Sign.mk_const thy (@{const_name random}, [this_ty]) $ @{term "i\<Colon>index"},
 173.295 +               random' $ @{term "i\<Colon>index"} $ @{term "i\<Colon>index"})
 173.296 +          val del_func = Attrib.internal (fn _ => Thm.declaration_attribute
 173.297 +            (fn thm => Context.mapping (Code.del_eqn thm) I));
 173.298 +          fun add_code simps lthy =
 173.299 +            let
 173.300 +              val thy = ProofContext.theory_of lthy;
 173.301 +              val thm = @{thm random'_if}
 173.302 +                |> Drule.instantiate' [SOME (Thm.ctyp_of thy this_ty)] [SOME (Thm.cterm_of thy random')]
 173.303 +                |> (fn thm => thm OF simps)
 173.304 +                |> singleton (ProofContext.export lthy (ProofContext.init thy));
 173.305 +              val c = (fst o dest_Const o fst o strip_comb o fst
 173.306 +                o HOLogic.dest_eq o HOLogic.dest_Trueprop o Thm.prop_of) thm;
 173.307 +            in
 173.308 +              lthy
 173.309 +              |> LocalTheory.theory (Code.del_eqns c
 173.310 +                   #> PureThy.add_thm ((fst (dest_Free random') ^ "_code", thm), [Thm.kind_internal])
 173.311 +                   #-> Code.add_eqn)
 173.312 +            end;
 173.313 +        in
 173.314 +          thy
 173.315 +          |> TheoryTarget.instantiation ([tyco], vs, @{sort random})
 173.316 +          |> PrimrecPackage.add_primrec
 173.317 +               [(Binding.name (fst (dest_Free random')), SOME (snd (dest_Free random')), NoSyn)]
 173.318 +                 (map (fn eq => ((Binding.empty, [del_func]), eq)) eqs')
 173.319 +          |-> add_code
 173.320 +          |> `(fn lthy => Syntax.check_term lthy eq)
 173.321 +          |-> (fn eq => Specification.definition (NONE, (Attrib.empty_binding, eq)))
 173.322 +          |> snd
 173.323 +          |> Class.prove_instantiation_instance (K (Class.intro_classes_tac []))
 173.324 +          |> LocalTheory.exit_global
 173.325 +        end
 173.326 +    | random_inst tycos thy = raise REC
 173.327 +        ("Will not generate random elements for mutual recursive type(s) " ^ commas (map quote tycos));
 173.328 +  fun add_random_inst tycos thy = random_inst tycos thy
 173.329 +     handle REC msg => (warning msg; thy)
 173.330 +          | TYP msg => (warning msg; thy)
 173.331 +in DatatypePackage.interpretation add_random_inst end
 173.332 +*}
 173.333 +
 173.334 +text {* Type @{typ int} *}
 173.335 +
 173.336 +instantiation int :: random
 173.337 +begin
 173.338 +
 173.339 +definition
 173.340 +  "random n = (do
 173.341 +     (b, _) \<leftarrow> random n;
 173.342 +     (m, t) \<leftarrow> random n;
 173.343 +     return (if b then (int m, \<lambda>u. Code_Eval.App (Code_Eval.Const (STR ''Int.int'') TYPEREP(nat \<Rightarrow> int)) (t ()))
 173.344 +       else (- int m, \<lambda>u. Code_Eval.App (Code_Eval.Const (STR ''HOL.uminus_class.uminus'') TYPEREP(int \<Rightarrow> int))
 173.345 +         (Code_Eval.App (Code_Eval.Const (STR ''Int.int'') TYPEREP(nat \<Rightarrow> int)) (t ()))))
 173.346 +   done)"
 173.347 +
 173.348 +instance ..
 173.349 +
 173.350 +end
 173.351 +
 173.352  
 173.353  subsection {* Quickcheck generator *}
 173.354  
   174.1 --- a/src/HOL/ex/ROOT.ML	Tue Dec 30 08:18:54 2008 +0100
   174.2 +++ b/src/HOL/ex/ROOT.ML	Tue Dec 30 11:10:01 2008 +0100
   174.3 @@ -56,7 +56,7 @@
   174.4    "set",
   174.5    "Meson_Test",
   174.6    "Code_Antiq",
   174.7 -  "LexOrds",
   174.8 +  "Termination",
   174.9    "Coherent"
  174.10  ];
  174.11  
   175.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   175.2 +++ b/src/HOL/ex/Termination.thy	Tue Dec 30 11:10:01 2008 +0100
   175.3 @@ -0,0 +1,212 @@
   175.4 +(* Title:       HOL/ex/Termination.thy
   175.5 +   ID:          $Id$
   175.6 +   Author:      Lukas Bulwahn, TU Muenchen
   175.7 +   Author:      Alexander Krauss, TU Muenchen
   175.8 +*)
   175.9 +
  175.10 +header {* Examples and regression tests for automated termination proofs *}
  175.11 + 
  175.12 +theory Termination
  175.13 +imports Main Multiset
  175.14 +begin
  175.15 +
  175.16 +text {*
  175.17 +  The @{text fun} command uses the method @{text lexicographic_order} by default.
  175.18 +*}
  175.19 +
  175.20 +subsection {* Trivial examples *}
  175.21 +
  175.22 +fun identity :: "nat \<Rightarrow> nat"
  175.23 +where
  175.24 +  "identity n = n"
  175.25 +
  175.26 +fun yaSuc :: "nat \<Rightarrow> nat"
  175.27 +where 
  175.28 +  "yaSuc 0 = 0"
  175.29 +| "yaSuc (Suc n) = Suc (yaSuc n)"
  175.30 +
  175.31 +
  175.32 +subsection {* Examples on natural numbers *}
  175.33 +
  175.34 +fun bin :: "(nat * nat) \<Rightarrow> nat"
  175.35 +where
  175.36 +  "bin (0, 0) = 1"
  175.37 +| "bin (Suc n, 0) = 0"
  175.38 +| "bin (0, Suc m) = 0"
  175.39 +| "bin (Suc n, Suc m) = bin (n, m) + bin (Suc n, m)"
  175.40 +
  175.41 +
  175.42 +fun t :: "(nat * nat) \<Rightarrow> nat"
  175.43 +where
  175.44 +  "t (0,n) = 0"
  175.45 +| "t (n,0) = 0"
  175.46 +| "t (Suc n, Suc m) = (if (n mod 2 = 0) then (t (Suc n, m)) else (t (n, Suc m)))" 
  175.47 +
  175.48 +
  175.49 +fun k :: "(nat * nat) * (nat * nat) \<Rightarrow> nat"
  175.50 +where
  175.51 +  "k ((0,0),(0,0)) = 0"
  175.52 +| "k ((Suc z, y), (u,v)) = k((z, y), (u, v))" (* z is descending *)
  175.53 +| "k ((0, Suc y), (u,v)) = k((1, y), (u, v))" (* y is descending *)
  175.54 +| "k ((0,0), (Suc u, v)) = k((1, 1), (u, v))" (* u is descending *)
  175.55 +| "k ((0,0), (0, Suc v)) = k((1,1), (1,v))"   (* v is descending *)
  175.56 +
  175.57 +
  175.58 +fun gcd2 :: "nat \<Rightarrow> nat \<Rightarrow> nat"
  175.59 +where
  175.60 +  "gcd2 x 0 = x"
  175.61 +| "gcd2 0 y = y"
  175.62 +| "gcd2 (Suc x) (Suc y) = (if x < y then gcd2 (Suc x) (y - x)
  175.63 +                                    else gcd2 (x - y) (Suc y))"
  175.64 +
  175.65 +fun ack :: "(nat * nat) \<Rightarrow> nat"
  175.66 +where
  175.67 +  "ack (0, m) = Suc m"
  175.68 +| "ack (Suc n, 0) = ack(n, 1)"
  175.69 +| "ack (Suc n, Suc m) = ack (n, ack (Suc n, m))"
  175.70 +
  175.71 +
  175.72 +fun greedy :: "nat * nat * nat * nat * nat => nat"
  175.73 +where
  175.74 +  "greedy (Suc a, Suc b, Suc c, Suc d, Suc e) =
  175.75 +  (if (a < 10) then greedy (Suc a, Suc b, c, d + 2, Suc e) else
  175.76 +  (if (a < 20) then greedy (Suc a, b, Suc c, d, Suc e) else
  175.77 +  (if (a < 30) then greedy (Suc a, b, Suc c, d, Suc e) else
  175.78 +  (if (a < 40) then greedy (Suc a, b, Suc c, d, Suc e) else
  175.79 +  (if (a < 50) then greedy (Suc a, b, Suc c, d, Suc e) else
  175.80 +  (if (a < 60) then greedy (a, Suc b, Suc c, d, Suc e) else
  175.81 +  (if (a < 70) then greedy (a, Suc b, Suc c, d, Suc e) else
  175.82 +  (if (a < 80) then greedy (a, Suc b, Suc c, d, Suc e) else
  175.83 +  (if (a < 90) then greedy (Suc a, Suc b, Suc c, d, e) else
  175.84 +  greedy (Suc a, Suc b, Suc c, d, e))))))))))"
  175.85 +| "greedy (a, b, c, d, e) = 0"
  175.86 +
  175.87 +
  175.88 +fun blowup :: "nat => nat => nat => nat => nat => nat => nat => nat => nat => nat"
  175.89 +where
  175.90 +  "blowup 0 0 0 0 0 0 0 0 0 = 0"
  175.91 +| "blowup 0 0 0 0 0 0 0 0 (Suc i) = Suc (blowup i i i i i i i i i)"
  175.92 +| "blowup 0 0 0 0 0 0 0 (Suc h) i = Suc (blowup h h h h h h h h i)"
  175.93 +| "blowup 0 0 0 0 0 0 (Suc g) h i = Suc (blowup g g g g g g g h i)"
  175.94 +| "blowup 0 0 0 0 0 (Suc f) g h i = Suc (blowup f f f f f f g h i)"
  175.95 +| "blowup 0 0 0 0 (Suc e) f g h i = Suc (blowup e e e e e f g h i)"
  175.96 +| "blowup 0 0 0 (Suc d) e f g h i = Suc (blowup d d d d e f g h i)"
  175.97 +| "blowup 0 0 (Suc c) d e f g h i = Suc (blowup c c c d e f g h i)"
  175.98 +| "blowup 0 (Suc b) c d e f g h i = Suc (blowup b b c d e f g h i)"
  175.99 +| "blowup (Suc a) b c d e f g h i = Suc (blowup a b c d e f g h i)"
 175.100 +
 175.101 +  
 175.102 +subsection {* Simple examples with other datatypes than nat, e.g. trees and lists *}
 175.103 +
 175.104 +datatype tree = Node | Branch tree tree
 175.105 +
 175.106 +fun g_tree :: "tree * tree \<Rightarrow> tree"
 175.107 +where
 175.108 +  "g_tree (Node, Node) = Node"
 175.109 +| "g_tree (Node, Branch a b) = Branch Node (g_tree (a,b))"
 175.110 +| "g_tree (Branch a b, Node) = Branch (g_tree (a,Node)) b"
 175.111 +| "g_tree (Branch a b, Branch c d) = Branch (g_tree (a,c)) (g_tree (b,d))"
 175.112 +
 175.113 +
 175.114 +fun acklist :: "'a list * 'a list \<Rightarrow> 'a list"
 175.115 +where
 175.116 +  "acklist ([], m) = ((hd m)#m)"
 175.117 +|  "acklist (n#ns, []) = acklist (ns, [n])"
 175.118 +|  "acklist ((n#ns), (m#ms)) = acklist (ns, acklist ((n#ns), ms))"
 175.119 +
 175.120 +
 175.121 +subsection {* Examples with mutual recursion *}
 175.122 +
 175.123 +fun evn od :: "nat \<Rightarrow> bool"
 175.124 +where
 175.125 +  "evn 0 = True"
 175.126 +| "od 0 = False"
 175.127 +| "evn (Suc n) = od (Suc n)"
 175.128 +| "od (Suc n) = evn n"
 175.129 +
 175.130 +
 175.131 +fun sizechange_f :: "'a list => 'a list => 'a list" and
 175.132 +sizechange_g :: "'a list => 'a list => 'a list => 'a list"
 175.133 +where
 175.134 +  "sizechange_f i x = (if i=[] then x else sizechange_g (tl i) x i)"
 175.135 +| "sizechange_g a b c = sizechange_f a (b @ c)"
 175.136 +
 175.137 +fun
 175.138 +  pedal :: "nat => nat => nat => nat"
 175.139 +and
 175.140 +  coast :: "nat => nat => nat => nat"
 175.141 +where
 175.142 +  "pedal 0 m c = c"
 175.143 +| "pedal n 0 c = c"
 175.144 +| "pedal n m c =
 175.145 +     (if n < m then coast (n - 1) (m - 1) (c + m)
 175.146 +               else pedal (n - 1) m (c + m))"
 175.147 +
 175.148 +| "coast n m c =
 175.149 +     (if n < m then coast n (m - 1) (c + n)
 175.150 +               else pedal n m (c + n))"
 175.151 +
 175.152 +
 175.153 +
 175.154 +subsection {* Refined analysis: The @{text sizechange} method *}
 175.155 +
 175.156 +text {* Unsolvable for @{text lexicographic_order} *}
 175.157 +
 175.158 +function fun1 :: "nat * nat \<Rightarrow> nat"
 175.159 +where
 175.160 +  "fun1 (0,0) = 1"
 175.161 +| "fun1 (0, Suc b) = 0"
 175.162 +| "fun1 (Suc a, 0) = 0"
 175.163 +| "fun1 (Suc a, Suc b) = fun1 (b, a)"
 175.164 +by pat_completeness auto
 175.165 +termination by sizechange
 175.166 +
 175.167 +
 175.168 +text {* 
 175.169 +  @{text lexicographic_order} can do the following, but it is much slower. 
 175.170 +*}
 175.171 +
 175.172 +function
 175.173 +  prod :: "nat => nat => nat => nat" and
 175.174 +  eprod :: "nat => nat => nat => nat" and
 175.175 +  oprod :: "nat => nat => nat => nat"
 175.176 +where
 175.177 +  "prod x y z = (if y mod 2 = 0 then eprod x y z else oprod x y z)"
 175.178 +| "oprod x y z = eprod x (y - 1) (z+x)"
 175.179 +| "eprod x y z = (if y=0 then z else prod (2*x) (y div 2) z)"
 175.180 +by pat_completeness auto
 175.181 +termination by sizechange
 175.182 +
 175.183 +text {* 
 175.184 +  Permutations of arguments:
 175.185 +*}
 175.186 +
 175.187 +function perm :: "nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat"
 175.188 +where
 175.189 +  "perm m n r = (if r > 0 then perm m (r - 1) n
 175.190 +                  else if n > 0 then perm r (n - 1) m
 175.191 +                  else m)"
 175.192 +by auto
 175.193 +termination by sizechange
 175.194 +
 175.195 +text {*
 175.196 +  Artificial examples and regression tests:
 175.197 +*}
 175.198 +
 175.199 +function
 175.200 +  fun2 :: "nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat"
 175.201 +where
 175.202 +  "fun2 x y z =
 175.203 +      (if x > 1000 \<and> z > 0 then
 175.204 +           fun2 (min x y) y (z - 1)
 175.205 +       else if y > 0 \<and> x > 100 then
 175.206 +           fun2 x (y - 1) (2 * z)
 175.207 +       else if z > 0 then
 175.208 +           fun2 (min y (z - 1)) x x
 175.209 +       else
 175.210 +           0
 175.211 +      )"
 175.212 +by pat_completeness auto
 175.213 +termination by sizechange -- {* requires Multiset *}
 175.214 +
 175.215 +end
   176.1 --- a/src/HOLCF/Adm.thy	Tue Dec 30 08:18:54 2008 +0100
   176.2 +++ b/src/HOLCF/Adm.thy	Tue Dec 30 11:10:01 2008 +0100
   176.3 @@ -1,5 +1,4 @@
   176.4  (*  Title:      HOLCF/Adm.thy
   176.5 -    ID:         $Id$
   176.6      Author:     Franz Regensburger and Brian Huffman
   176.7  *)
   176.8  
   177.1 --- a/src/HOLCF/Cfun.thy	Tue Dec 30 08:18:54 2008 +0100
   177.2 +++ b/src/HOLCF/Cfun.thy	Tue Dec 30 11:10:01 2008 +0100
   177.3 @@ -1,5 +1,4 @@
   177.4  (*  Title:      HOLCF/Cfun.thy
   177.5 -    ID:         $Id$
   177.6      Author:     Franz Regensburger
   177.7  
   177.8  Definition of the type ->  of continuous functions.
   178.1 --- a/src/HOLCF/Cont.thy	Tue Dec 30 08:18:54 2008 +0100
   178.2 +++ b/src/HOLCF/Cont.thy	Tue Dec 30 11:10:01 2008 +0100
   178.3 @@ -1,8 +1,5 @@
   178.4  (*  Title:      HOLCF/Cont.thy
   178.5 -    ID:         $Id$
   178.6      Author:     Franz Regensburger
   178.7 -
   178.8 -Results about continuity and monotonicity.
   178.9  *)
  178.10  
  178.11  header {* Continuity and monotonicity *}
   179.1 --- a/src/HOLCF/Cprod.thy	Tue Dec 30 08:18:54 2008 +0100
   179.2 +++ b/src/HOLCF/Cprod.thy	Tue Dec 30 11:10:01 2008 +0100
   179.3 @@ -1,8 +1,5 @@
   179.4  (*  Title:      HOLCF/Cprod.thy
   179.5 -    ID:         $Id$
   179.6      Author:     Franz Regensburger
   179.7 -
   179.8 -Partial ordering for cartesian product of HOL products.
   179.9  *)
  179.10  
  179.11  header {* The cpo of cartesian products *}
   180.1 --- a/src/HOLCF/Discrete.thy	Tue Dec 30 08:18:54 2008 +0100
   180.2 +++ b/src/HOLCF/Discrete.thy	Tue Dec 30 11:10:01 2008 +0100
   180.3 @@ -1,8 +1,5 @@
   180.4  (*  Title:      HOLCF/Discrete.thy
   180.5 -    ID:         $Id$
   180.6      Author:     Tobias Nipkow
   180.7 -
   180.8 -Discrete CPOs.
   180.9  *)
  180.10  
  180.11  header {* Discrete cpo types *}
   181.1 --- a/src/HOLCF/Domain.thy	Tue Dec 30 08:18:54 2008 +0100
   181.2 +++ b/src/HOLCF/Domain.thy	Tue Dec 30 11:10:01 2008 +0100
   181.3 @@ -1,5 +1,4 @@
   181.4  (*  Title:      HOLCF/Domain.thy
   181.5 -    ID:         $Id$
   181.6      Author:     Brian Huffman
   181.7  *)
   181.8  
   182.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   182.2 +++ b/src/HOLCF/Dsum.thy	Tue Dec 30 11:10:01 2008 +0100
   182.3 @@ -0,0 +1,251 @@
   182.4 +(*  Title:      HOLCF/Dsum.thy
   182.5 +    Author:     Brian Huffman
   182.6 +*)
   182.7 +
   182.8 +header {* The cpo of disjoint sums *}
   182.9 +
  182.10 +theory Dsum
  182.11 +imports Bifinite
  182.12 +begin
  182.13 +
  182.14 +subsection {* Ordering on type @{typ "'a + 'b"} *}
  182.15 +
  182.16 +instantiation "+" :: (sq_ord, sq_ord) sq_ord
  182.17 +begin
  182.18 +
  182.19 +definition
  182.20 +  less_sum_def: "x \<sqsubseteq> y \<equiv> case x of
  182.21 +         Inl a \<Rightarrow> (case y of Inl b \<Rightarrow> a \<sqsubseteq> b | Inr b \<Rightarrow> False) |
  182.22 +         Inr a \<Rightarrow> (case y of Inl b \<Rightarrow> False | Inr b \<Rightarrow> a \<sqsubseteq> b)"
  182.23 +
  182.24 +instance ..
  182.25 +end
  182.26 +
  182.27 +lemma Inl_less_iff [simp]: "Inl x \<sqsubseteq> Inl y = x \<sqsubseteq> y"
  182.28 +unfolding less_sum_def by simp
  182.29 +
  182.30 +lemma Inr_less_iff [simp]: "Inr x \<sqsubseteq> Inr y = x \<sqsubseteq> y"
  182.31 +unfolding less_sum_def by simp
  182.32 +
  182.33 +lemma Inl_less_Inr [simp]: "\<not> Inl x \<sqsubseteq> Inr y"
  182.34 +unfolding less_sum_def by simp
  182.35 +
  182.36 +lemma Inr_less_Inl [simp]: "\<not> Inr x \<sqsubseteq> Inl y"
  182.37 +unfolding less_sum_def by simp
  182.38 +
  182.39 +lemma Inl_mono: "x \<sqsubseteq> y \<Longrightarrow> Inl x \<sqsubseteq> Inl y"
  182.40 +by simp
  182.41 +
  182.42 +lemma Inr_mono: "x \<sqsubseteq> y \<Longrightarrow> Inr x \<sqsubseteq> Inr y"
  182.43 +by simp
  182.44 +
  182.45 +lemma Inl_lessE: "\<lbrakk>Inl a \<sqsubseteq> x; \<And>b. \<lbrakk>x = Inl b; a \<sqsubseteq> b\<rbrakk> \<Longrightarrow> R\<rbrakk> \<Longrightarrow> R"
  182.46 +by (cases x, simp_all)
  182.47 +
  182.48 +lemma Inr_lessE: "\<lbrakk>Inr a \<sqsubseteq> x; \<And>b. \<lbrakk>x = Inr b; a \<sqsubseteq> b\<rbrakk> \<Longrightarrow> R\<rbrakk> \<Longrightarrow> R"
  182.49 +by (cases x, simp_all)
  182.50 +
  182.51 +lemmas sum_less_elims = Inl_lessE Inr_lessE
  182.52 +
  182.53 +lemma sum_less_cases:
  182.54 +  "\<lbrakk>x \<sqsubseteq> y;
  182.55 +    \<And>a b. \<lbrakk>x = Inl a; y = Inl b; a \<sqsubseteq> b\<rbrakk> \<Longrightarrow> R;
  182.56 +    \<And>a b. \<lbrakk>x = Inr a; y = Inr b; a \<sqsubseteq> b\<rbrakk> \<Longrightarrow> R\<rbrakk>
  182.57 +      \<Longrightarrow> R"
  182.58 +by (cases x, safe elim!: sum_less_elims, auto)
  182.59 +
  182.60 +subsection {* Sum type is a complete partial order *}
  182.61 +
  182.62 +instance "+" :: (po, po) po
  182.63 +proof
  182.64 +  fix x :: "'a + 'b"
  182.65 +  show "x \<sqsubseteq> x"
  182.66 +    by (induct x, simp_all)
  182.67 +next
  182.68 +  fix x y :: "'a + 'b"
  182.69 +  assume "x \<sqsubseteq> y" and "y \<sqsubseteq> x" thus "x = y"
  182.70 +    by (induct x, auto elim!: sum_less_elims intro: antisym_less)
  182.71 +next
  182.72 +  fix x y z :: "'a + 'b"
  182.73 +  assume "x \<sqsubseteq> y" and "y \<sqsubseteq> z" thus "x \<sqsubseteq> z"
  182.74 +    by (induct x, auto elim!: sum_less_elims intro: trans_less)
  182.75 +qed
  182.76 +
  182.77 +lemma monofun_inv_Inl: "monofun (\<lambda>p. THE a. p = Inl a)"
  182.78 +by (rule monofunI, erule sum_less_cases, simp_all)
  182.79 +
  182.80 +lemma monofun_inv_Inr: "monofun (\<lambda>p. THE b. p = Inr b)"
  182.81 +by (rule monofunI, erule sum_less_cases, simp_all)
  182.82 +
  182.83 +lemma sum_chain_cases:
  182.84 +  assumes Y: "chain Y"
  182.85 +  assumes A: "\<And>A. \<lbrakk>chain A; Y = (\<lambda>i. Inl (A i))\<rbrakk> \<Longrightarrow> R"
  182.86 +  assumes B: "\<And>B. \<lbrakk>chain B; Y = (\<lambda>i. Inr (B i))\<rbrakk> \<Longrightarrow> R"
  182.87 +  shows "R"
  182.88 + apply (cases "Y 0")
  182.89 +  apply (rule A)
  182.90 +   apply (rule ch2ch_monofun [OF monofun_inv_Inl Y])
  182.91 +  apply (rule ext)
  182.92 +  apply (cut_tac j=i in chain_mono [OF Y le0], simp)
  182.93 +  apply (erule Inl_lessE, simp)
  182.94 + apply (rule B)
  182.95 +  apply (rule ch2ch_monofun [OF monofun_inv_Inr Y])
  182.96 + apply (rule ext)
  182.97 + apply (cut_tac j=i in chain_mono [OF Y le0], simp)
  182.98 + apply (erule Inr_lessE, simp)
  182.99 +done
 182.100 +
 182.101 +lemma is_lub_Inl: "range S <<| x \<Longrightarrow> range (\<lambda>i. Inl (S i)) <<| Inl x"
 182.102 + apply (rule is_lubI)
 182.103 +  apply (rule ub_rangeI)
 182.104 +  apply (simp add: is_ub_lub)
 182.105 + apply (frule ub_rangeD [where i=arbitrary])
 182.106 + apply (erule Inl_lessE, simp)
 182.107 + apply (erule is_lub_lub)
 182.108 + apply (rule ub_rangeI)
 182.109 + apply (drule ub_rangeD, simp)
 182.110 +done
 182.111 +
 182.112 +lemma is_lub_Inr: "range S <<| x \<Longrightarrow> range (\<lambda>i. Inr (S i)) <<| Inr x"
 182.113 + apply (rule is_lubI)
 182.114 +  apply (rule ub_rangeI)
 182.115 +  apply (simp add: is_ub_lub)
 182.116 + apply (frule ub_rangeD [where i=arbitrary])
 182.117 + apply (erule Inr_lessE, simp)
 182.118 + apply (erule is_lub_lub)
 182.119 + apply (rule ub_rangeI)
 182.120 + apply (drule ub_rangeD, simp)
 182.121 +done
 182.122 +
 182.123 +instance "+" :: (cpo, cpo) cpo
 182.124 + apply intro_classes
 182.125 + apply (erule sum_chain_cases, safe)
 182.126 +  apply (rule exI)
 182.127 +  apply (rule is_lub_Inl)
 182.128 +  apply (erule cpo_lubI)
 182.129 + apply (rule exI)
 182.130 + apply (rule is_lub_Inr)
 182.131 + apply (erule cpo_lubI)
 182.132 +done
 182.133 +
 182.134 +subsection {* Continuity of @{term Inl}, @{term Inr}, @{term sum_case} *}
 182.135 +
 182.136 +lemma cont2cont_Inl [simp]: "cont f \<Longrightarrow> cont (\<lambda>x. Inl (f x))"
 182.137 +by (fast intro: contI is_lub_Inl elim: contE)
 182.138 +
 182.139 +lemma cont2cont_Inr [simp]: "cont f \<Longrightarrow> cont (\<lambda>x. Inr (f x))"
 182.140 +by (fast intro: contI is_lub_Inr elim: contE)
 182.141 +
 182.142 +lemma cont_Inl: "cont Inl"
 182.143 +by (rule cont2cont_Inl [OF cont_id])
 182.144 +
 182.145 +lemma cont_Inr: "cont Inr"
 182.146 +by (rule cont2cont_Inr [OF cont_id])
 182.147 +
 182.148 +lemmas ch2ch_Inl [simp] = ch2ch_cont [OF cont_Inl]
 182.149 +lemmas ch2ch_Inr [simp] = ch2ch_cont [OF cont_Inr]
 182.150 +
 182.151 +lemmas lub_Inl = cont2contlubE [OF cont_Inl, symmetric]
 182.152 +lemmas lub_Inr = cont2contlubE [OF cont_Inr, symmetric]
 182.153 +
 182.154 +lemma cont_sum_case1:
 182.155 +  assumes f: "\<And>a. cont (\<lambda>x. f x a)"
 182.156 +  assumes g: "\<And>b. cont (\<lambda>x. g x b)"
 182.157 +  shows "cont (\<lambda>x. case y of Inl a \<Rightarrow> f x a | Inr b \<Rightarrow> g x b)"
 182.158 +by (induct y, simp add: f, simp add: g)
 182.159 +
 182.160 +lemma cont_sum_case2: "\<lbrakk>cont f; cont g\<rbrakk> \<Longrightarrow> cont (sum_case f g)"
 182.161 +apply (rule contI)
 182.162 +apply (erule sum_chain_cases)
 182.163 +apply (simp add: cont2contlubE [OF cont_Inl, symmetric] contE)
 182.164 +apply (simp add: cont2contlubE [OF cont_Inr, symmetric] contE)
 182.165 +done
 182.166 +
 182.167 +lemma cont2cont_sum_case [simp]:
 182.168 +  assumes f1: "\<And>a. cont (\<lambda>x. f x a)" and f2: "\<And>x. cont (\<lambda>a. f x a)"
 182.169 +  assumes g1: "\<And>b. cont (\<lambda>x. g x b)" and g2: "\<And>x. cont (\<lambda>b. g x b)"
 182.170 +  assumes h: "cont (\<lambda>x. h x)"
 182.171 +  shows "cont (\<lambda>x. case h x of Inl a \<Rightarrow> f x a | Inr b \<Rightarrow> g x b)"
 182.172 +apply (rule cont2cont_app2 [OF cont2cont_lambda _ h])
 182.173 +apply (rule cont_sum_case1 [OF f1 g1])
 182.174 +apply (rule cont_sum_case2 [OF f2 g2])
 182.175 +done
 182.176 +
 182.177 +subsection {* Compactness and chain-finiteness *}
 182.178 +
 182.179 +lemma compact_Inl: "compact a \<Longrightarrow> compact (Inl a)"
 182.180 +apply (rule compactI2)
 182.181 +apply (erule sum_chain_cases, safe)
 182.182 +apply (simp add: lub_Inl)
 182.183 +apply (erule (2) compactD2)
 182.184 +apply (simp add: lub_Inr)
 182.185 +done
 182.186 +
 182.187 +lemma compact_Inr: "compact a \<Longrightarrow> compact (Inr a)"
 182.188 +apply (rule compactI2)
 182.189 +apply (erule sum_chain_cases, safe)
 182.190 +apply (simp add: lub_Inl)
 182.191 +apply (simp add: lub_Inr)
 182.192 +apply (erule (2) compactD2)
 182.193 +done
 182.194 +
 182.195 +lemma compact_Inl_rev: "compact (Inl a) \<Longrightarrow> compact a"
 182.196 +unfolding compact_def
 182.197 +by (drule adm_subst [OF cont_Inl], simp)
 182.198 +
 182.199 +lemma compact_Inr_rev: "compact (Inr a) \<Longrightarrow> compact a"
 182.200 +unfolding compact_def
 182.201 +by (drule adm_subst [OF cont_Inr], simp)
 182.202 +
 182.203 +lemma compact_Inl_iff [simp]: "compact (Inl a) = compact a"
 182.204 +by (safe elim!: compact_Inl compact_Inl_rev)
 182.205 +
 182.206 +lemma compact_Inr_iff [simp]: "compact (Inr a) = compact a"
 182.207 +by (safe elim!: compact_Inr compact_Inr_rev)
 182.208 +
 182.209 +instance "+" :: (chfin, chfin) chfin
 182.210 +apply intro_classes
 182.211 +apply (erule compact_imp_max_in_chain)
 182.212 +apply (case_tac "\<Squnion>i. Y i", simp_all)
 182.213 +done
 182.214 +
 182.215 +instance "+" :: (finite_po, finite_po) finite_po ..
 182.216 +
 182.217 +instance "+" :: (discrete_cpo, discrete_cpo) discrete_cpo
 182.218 +by intro_classes (simp add: less_sum_def split: sum.split)
 182.219 +
 182.220 +subsection {* Sum type is a bifinite domain *}
 182.221 +
 182.222 +instantiation "+" :: (profinite, profinite) profinite
 182.223 +begin
 182.224 +
 182.225 +definition
 182.226 +  approx_sum_def: "approx =
 182.227 +    (\<lambda>n. \<Lambda> x. case x of Inl a \<Rightarrow> Inl (approx n\<cdot>a) | Inr b \<Rightarrow> Inr (approx n\<cdot>b))"
 182.228 +
 182.229 +lemma approx_Inl [simp]: "approx n\<cdot>(Inl x) = Inl (approx n\<cdot>x)"
 182.230 +  unfolding approx_sum_def by simp
 182.231 +
 182.232 +lemma approx_Inr [simp]: "approx n\<cdot>(Inr x) = Inr (approx n\<cdot>x)"
 182.233 +  unfolding approx_sum_def by simp
 182.234 +
 182.235 +instance proof
 182.236 +  fix i :: nat and x :: "'a + 'b"
 182.237 +  show "chain (approx :: nat \<Rightarrow> 'a + 'b \<rightarrow> 'a + 'b)"
 182.238 +    unfolding approx_sum_def
 182.239 +    by (rule ch2ch_LAM, case_tac x, simp_all)
 182.240 +  show "(\<Squnion>i. approx i\<cdot>x) = x"
 182.241 +    by (induct x, simp_all add: lub_Inl lub_Inr)
 182.242 +  show "approx i\<cdot>(approx i\<cdot>x) = approx i\<cdot>x"
 182.243 +    by (induct x, simp_all)
 182.244 +  have "{x::'a + 'b. approx i\<cdot>x = x} \<subseteq>
 182.245 +        {x::'a. approx i\<cdot>x = x} <+> {x::'b. approx i\<cdot>x = x}"
 182.246 +    by (rule subsetI, case_tac x, simp_all add: InlI InrI)
 182.247 +  thus "finite {x::'a + 'b. approx i\<cdot>x = x}"
 182.248 +    by (rule finite_subset,
 182.249 +        intro finite_Plus finite_fixes_approx)
 182.250 +qed
 182.251 +
 182.252 +end
 182.253 +
 182.254 +end
   183.1 --- a/src/HOLCF/Ffun.thy	Tue Dec 30 08:18:54 2008 +0100
   183.2 +++ b/src/HOLCF/Ffun.thy	Tue Dec 30 11:10:01 2008 +0100
   183.3 @@ -1,10 +1,5 @@
   183.4  (*  Title:      HOLCF/FunCpo.thy
   183.5 -    ID:         $Id$
   183.6      Author:     Franz Regensburger
   183.7 -
   183.8 -Definition of the partial ordering for the type of all functions => (fun)
   183.9 -
  183.10 -Class instance of  => (fun) for class pcpo.
  183.11  *)
  183.12  
  183.13  header {* Class instances for the full function space *}
   184.1 --- a/src/HOLCF/Fix.thy	Tue Dec 30 08:18:54 2008 +0100
   184.2 +++ b/src/HOLCF/Fix.thy	Tue Dec 30 11:10:01 2008 +0100
   184.3 @@ -1,8 +1,5 @@
   184.4  (*  Title:      HOLCF/Fix.thy
   184.5 -    ID:         $Id$
   184.6      Author:     Franz Regensburger
   184.7 -
   184.8 -Definitions for fixed point operator and admissibility.
   184.9  *)
  184.10  
  184.11  header {* Fixed point operator and admissibility *}
   185.1 --- a/src/HOLCF/Fixrec.thy	Tue Dec 30 08:18:54 2008 +0100
   185.2 +++ b/src/HOLCF/Fixrec.thy	Tue Dec 30 11:10:01 2008 +0100
   185.3 @@ -1,5 +1,4 @@
   185.4  (*  Title:      HOLCF/Fixrec.thy
   185.5 -    ID:         $Id$
   185.6      Author:     Amber Telfer and Brian Huffman
   185.7  *)
   185.8  
   185.9 @@ -17,13 +16,13 @@
  185.10  pcpodef (open) 'a maybe = "UNIV::(one ++ 'a u) set"
  185.11  by simp_all
  185.12  
  185.13 -constdefs
  185.14 -  fail :: "'a maybe"
  185.15 -  "fail \<equiv> Abs_maybe (sinl\<cdot>ONE)"
  185.16 +definition
  185.17 +  fail :: "'a maybe" where
  185.18 +  "fail = Abs_maybe (sinl\<cdot>ONE)"
  185.19  
  185.20 -constdefs
  185.21 +definition
  185.22    return :: "'a \<rightarrow> 'a maybe" where
  185.23 -  "return \<equiv> \<Lambda> x. Abs_maybe (sinr\<cdot>(up\<cdot>x))"
  185.24 +  "return = (\<Lambda> x. Abs_maybe (sinr\<cdot>(up\<cdot>x)))"
  185.25  
  185.26  definition
  185.27    maybe_when :: "'b \<rightarrow> ('a \<rightarrow> 'b) \<rightarrow> 'a maybe \<rightarrow> 'b::pcpo" where
  185.28 @@ -59,7 +58,8 @@
  185.29                    cont_Abs_maybe Abs_maybe_inverse Rep_maybe_strict)
  185.30  
  185.31  translations
  185.32 -  "case m of fail \<Rightarrow> t1 | return\<cdot>x \<Rightarrow> t2" == "CONST maybe_when\<cdot>t1\<cdot>(\<Lambda> x. t2)\<cdot>m"
  185.33 +  "case m of XCONST fail \<Rightarrow> t1 | XCONST return\<cdot>x \<Rightarrow> t2"
  185.34 +    == "CONST maybe_when\<cdot>t1\<cdot>(\<Lambda> x. t2)\<cdot>m"
  185.35  
  185.36  
  185.37  subsubsection {* Monadic bind operator *}
  185.38 @@ -164,8 +164,8 @@
  185.39  
  185.40  subsection {* Case branch combinator *}
  185.41  
  185.42 -constdefs
  185.43 -  branch :: "('a \<rightarrow> 'b maybe) \<Rightarrow> ('b \<rightarrow> 'c) \<rightarrow> ('a \<rightarrow> 'c maybe)"
  185.44 +definition
  185.45 +  branch :: "('a \<rightarrow> 'b maybe) \<Rightarrow> ('b \<rightarrow> 'c) \<rightarrow> ('a \<rightarrow> 'c maybe)" where
  185.46    "branch p \<equiv> \<Lambda> r x. bind\<cdot>(p\<cdot>x)\<cdot>(\<Lambda> y. return\<cdot>(r\<cdot>y))"
  185.47  
  185.48  lemma branch_rews:
   186.1 --- a/src/HOLCF/HOLCF.thy	Tue Dec 30 08:18:54 2008 +0100
   186.2 +++ b/src/HOLCF/HOLCF.thy	Tue Dec 30 11:10:01 2008 +0100
   186.3 @@ -1,12 +1,12 @@
   186.4  (*  Title:      HOLCF/HOLCF.thy
   186.5 -    ID:         $Id$
   186.6      Author:     Franz Regensburger
   186.7  
   186.8  HOLCF -- a semantic extension of HOL by the LCF logic.
   186.9  *)
  186.10  
  186.11  theory HOLCF
  186.12 -imports Sprod Ssum Up Lift Discrete One Tr Domain ConvexPD Algebraic Universal Main
  186.13 +imports
  186.14 +  Domain ConvexPD Algebraic Universal Dsum Main
  186.15  uses
  186.16    "holcf_logic.ML"
  186.17    "Tools/cont_consts.ML"
   187.1 --- a/src/HOLCF/IsaMakefile	Tue Dec 30 08:18:54 2008 +0100
   187.2 +++ b/src/HOLCF/IsaMakefile	Tue Dec 30 11:10:01 2008 +0100
   187.3 @@ -41,6 +41,7 @@
   187.4    Discrete.thy \
   187.5    Deflation.thy \
   187.6    Domain.thy \
   187.7 +  Dsum.thy \
   187.8    Eventual.thy \
   187.9    Ffun.thy \
  187.10    Fixrec.thy \
   188.1 --- a/src/HOLCF/Lift.thy	Tue Dec 30 08:18:54 2008 +0100
   188.2 +++ b/src/HOLCF/Lift.thy	Tue Dec 30 11:10:01 2008 +0100
   188.3 @@ -1,5 +1,4 @@
   188.4  (*  Title:      HOLCF/Lift.thy
   188.5 -    ID:         $Id$
   188.6      Author:     Olaf Mueller
   188.7  *)
   188.8  
   189.1 --- a/src/HOLCF/One.thy	Tue Dec 30 08:18:54 2008 +0100
   189.2 +++ b/src/HOLCF/One.thy	Tue Dec 30 11:10:01 2008 +0100
   189.3 @@ -1,8 +1,5 @@
   189.4  (*  Title:      HOLCF/One.thy
   189.5 -    ID:         $Id$
   189.6      Author:     Oscar Slotosch
   189.7 -
   189.8 -The unit domain.
   189.9  *)
  189.10  
  189.11  header {* The unit domain *}
  189.12 @@ -15,8 +12,9 @@
  189.13  translations
  189.14    "one" <= (type) "unit lift" 
  189.15  
  189.16 -constdefs
  189.17 +definition
  189.18    ONE :: "one"
  189.19 +where
  189.20    "ONE == Def ()"
  189.21  
  189.22  text {* Exhaustion and Elimination for type @{typ one} *}
   190.1 --- a/src/HOLCF/Pcpo.thy	Tue Dec 30 08:18:54 2008 +0100
   190.2 +++ b/src/HOLCF/Pcpo.thy	Tue Dec 30 11:10:01 2008 +0100
   190.3 @@ -1,5 +1,4 @@
   190.4  (*  Title:      HOLCF/Pcpo.thy
   190.5 -    ID:         $Id$
   190.6      Author:     Franz Regensburger
   190.7  *)
   190.8  
   191.1 --- a/src/HOLCF/Pcpodef.thy	Tue Dec 30 08:18:54 2008 +0100
   191.2 +++ b/src/HOLCF/Pcpodef.thy	Tue Dec 30 11:10:01 2008 +0100
   191.3 @@ -1,5 +1,4 @@
   191.4  (*  Title:      HOLCF/Pcpodef.thy
   191.5 -    ID:         $Id$
   191.6      Author:     Brian Huffman
   191.7  *)
   191.8  
   192.1 --- a/src/HOLCF/Porder.thy	Tue Dec 30 08:18:54 2008 +0100
   192.2 +++ b/src/HOLCF/Porder.thy	Tue Dec 30 11:10:01 2008 +0100
   192.3 @@ -1,5 +1,4 @@
   192.4  (*  Title:      HOLCF/Porder.thy
   192.5 -    ID:         $Id$
   192.6      Author:     Franz Regensburger and Brian Huffman
   192.7  *)
   192.8  
   193.1 --- a/src/HOLCF/Sprod.thy	Tue Dec 30 08:18:54 2008 +0100
   193.2 +++ b/src/HOLCF/Sprod.thy	Tue Dec 30 11:10:01 2008 +0100
   193.3 @@ -1,8 +1,5 @@
   193.4  (*  Title:      HOLCF/Sprod.thy
   193.5 -    ID:         $Id$
   193.6      Author:     Franz Regensburger and Brian Huffman
   193.7 -
   193.8 -Strict product with typedef.
   193.9  *)
  193.10  
  193.11  header {* The type of strict products *}
   194.1 --- a/src/HOLCF/Ssum.thy	Tue Dec 30 08:18:54 2008 +0100
   194.2 +++ b/src/HOLCF/Ssum.thy	Tue Dec 30 11:10:01 2008 +0100
   194.3 @@ -1,8 +1,5 @@
   194.4  (*  Title:      HOLCF/Ssum.thy
   194.5 -    ID:         $Id$
   194.6      Author:     Franz Regensburger and Brian Huffman
   194.7 -
   194.8 -Strict sum with typedef.
   194.9  *)
  194.10  
  194.11  header {* The type of strict sums *}
   195.1 --- a/src/HOLCF/Tr.thy	Tue Dec 30 08:18:54 2008 +0100
   195.2 +++ b/src/HOLCF/Tr.thy	Tue Dec 30 11:10:01 2008 +0100
   195.3 @@ -1,8 +1,5 @@
   195.4  (*  Title:      HOLCF/Tr.thy
   195.5 -    ID:         $Id$
   195.6      Author:     Franz Regensburger
   195.7 -
   195.8 -Introduce infix if_then_else_fi and boolean connectives andalso, orelse.
   195.9  *)
  195.10  
  195.11  header {* The type of lifted booleans *}
   196.1 --- a/src/HOLCF/Up.thy	Tue Dec 30 08:18:54 2008 +0100
   196.2 +++ b/src/HOLCF/Up.thy	Tue Dec 30 11:10:01 2008 +0100
   196.3 @@ -1,8 +1,5 @@
   196.4  (*  Title:      HOLCF/Up.thy
   196.5 -    ID:         $Id$
   196.6      Author:     Franz Regensburger and Brian Huffman
   196.7 -
   196.8 -Lifting.
   196.9  *)
  196.10  
  196.11  header {* The type of lifted values *}
   197.1 --- a/src/HOLCF/document/root.tex	Tue Dec 30 08:18:54 2008 +0100
   197.2 +++ b/src/HOLCF/document/root.tex	Tue Dec 30 11:10:01 2008 +0100
   197.3 @@ -1,5 +1,5 @@
   197.4  
   197.5 -% $Id$
   197.6 +% HOLCF/document/root.tex
   197.7  
   197.8  \documentclass[11pt,a4paper]{article}
   197.9  \usepackage{graphicx,isabelle,isabellesym,latexsym}
  197.10 @@ -21,7 +21,7 @@
  197.11  \tableofcontents
  197.12  
  197.13  \begin{center}
  197.14 -  \includegraphics[scale=0.7]{session_graph}
  197.15 +  \includegraphics[scale=0.5]{session_graph}
  197.16  \end{center}
  197.17  
  197.18  \newpage
   198.1 --- a/src/Pure/Concurrent/ROOT.ML	Tue Dec 30 08:18:54 2008 +0100
   198.2 +++ b/src/Pure/Concurrent/ROOT.ML	Tue Dec 30 11:10:01 2008 +0100
   198.3 @@ -1,15 +1,12 @@
   198.4  (*  Title:      Pure/Concurrent/ROOT.ML
   198.5 -    ID:         $Id$
   198.6 +    Author:     Makarius
   198.7  
   198.8  Concurrency within the ML runtime.
   198.9  *)
  198.10  
  198.11 -val future_scheduler = ref true;
  198.12 -
  198.13  use "simple_thread.ML";
  198.14  use "synchronized.ML";
  198.15  use "mailbox.ML";
  198.16 -use "schedule.ML";
  198.17  use "task_queue.ML";
  198.18  use "future.ML";
  198.19  use "par_list.ML";
   199.1 --- a/src/Pure/Concurrent/future.ML	Tue Dec 30 08:18:54 2008 +0100
   199.2 +++ b/src/Pure/Concurrent/future.ML	Tue Dec 30 11:10:01 2008 +0100
   199.3 @@ -1,5 +1,4 @@
   199.4  (*  Title:      Pure/Concurrent/future.ML
   199.5 -    ID:         $Id$
   199.6      Author:     Makarius
   199.7  
   199.8  Future values.
   199.9 @@ -28,8 +27,8 @@
  199.10  signature FUTURE =
  199.11  sig
  199.12    val enabled: unit -> bool
  199.13 -  type task = TaskQueue.task
  199.14 -  type group = TaskQueue.group
  199.15 +  type task = Task_Queue.task
  199.16 +  type group = Task_Queue.group
  199.17    val thread_data: unit -> (string * task) option
  199.18    type 'a future
  199.19    val task_of: 'a future -> task
  199.20 @@ -40,12 +39,11 @@
  199.21    val fork: (unit -> 'a) -> 'a future
  199.22    val fork_group: group -> (unit -> 'a) -> 'a future
  199.23    val fork_deps: 'b future list -> (unit -> 'a) -> 'a future
  199.24 -  val fork_background: (unit -> 'a) -> 'a future
  199.25 +  val fork_pri: int -> (unit -> 'a) -> 'a future
  199.26    val join_results: 'a future list -> 'a Exn.result list
  199.27    val join_result: 'a future -> 'a Exn.result
  199.28    val join: 'a future -> 'a
  199.29    val map: ('a -> 'b) -> 'a future -> 'b future
  199.30 -  val focus: task list -> unit
  199.31    val interrupt_task: string -> unit
  199.32    val cancel: 'a future -> unit
  199.33    val shutdown: unit -> unit
  199.34 @@ -57,14 +55,14 @@
  199.35  (** future values **)
  199.36  
  199.37  fun enabled () =
  199.38 -  ! future_scheduler andalso Multithreading.enabled () andalso
  199.39 +  Multithreading.enabled () andalso
  199.40      not (Multithreading.self_critical ());
  199.41  
  199.42  
  199.43  (* identifiers *)
  199.44  
  199.45 -type task = TaskQueue.task;
  199.46 -type group = TaskQueue.group;
  199.47 +type task = Task_Queue.task;
  199.48 +type group = Task_Queue.group;
  199.49  
  199.50  local val tag = Universal.tag () : (string * task) option Universal.tag in
  199.51    fun thread_data () = the_default NONE (Thread.getLocal tag);
  199.52 @@ -86,8 +84,8 @@
  199.53  fun is_finished x = is_some (peek x);
  199.54  
  199.55  fun value x = Future
  199.56 - {task = TaskQueue.new_task (),
  199.57 -  group = TaskQueue.new_group (),
  199.58 + {task = Task_Queue.new_task 0,
  199.59 +  group = Task_Queue.new_group (),
  199.60    result = ref (SOME (Exn.Result x))};
  199.61  
  199.62  
  199.63 @@ -96,12 +94,12 @@
  199.64  
  199.65  (* global state *)
  199.66  
  199.67 -val queue = ref TaskQueue.empty;
  199.68 +val queue = ref Task_Queue.empty;
  199.69  val next = ref 0;
  199.70  val workers = ref ([]: (Thread.thread * bool) list);
  199.71  val scheduler = ref (NONE: Thread.thread option);
  199.72  val excessive = ref 0;
  199.73 -val canceled = ref ([]: TaskQueue.group list);
  199.74 +val canceled = ref ([]: Task_Queue.group list);
  199.75  val do_shutdown = ref false;
  199.76  
  199.77  
  199.78 @@ -114,15 +112,11 @@
  199.79  
  199.80  fun SYNCHRONIZED name = SimpleThread.synchronized name lock;
  199.81  
  199.82 -fun wait name = (*requires SYNCHRONIZED*)
  199.83 - (Multithreading.tracing 3 (fn () => name ^ ": wait ...");
  199.84 +fun wait () = (*requires SYNCHRONIZED*)
  199.85    ConditionVar.wait (cond, lock);
  199.86 -  Multithreading.tracing 3 (fn () => name ^ ": ... continue"));
  199.87  
  199.88 -fun wait_timeout name timeout = (*requires SYNCHRONIZED*)
  199.89 - (Multithreading.tracing 3 (fn () => name ^ ": wait ...");
  199.90 +fun wait_timeout timeout = (*requires SYNCHRONIZED*)
  199.91    ConditionVar.waitUntil (cond, lock, Time.+ (Time.now (), timeout));
  199.92 -  Multithreading.tracing 3 (fn () => name ^ ": ... continue"));
  199.93  
  199.94  fun notify_all () = (*requires SYNCHRONIZED*)
  199.95    ConditionVar.broadcast cond;
  199.96 @@ -150,9 +144,9 @@
  199.97      val _ = trace_active ();
  199.98      val ok = setmp_thread_data (name, task) run ();
  199.99      val _ = SYNCHRONIZED "execute" (fn () =>
 199.100 -     (change queue (TaskQueue.finish task);
 199.101 +     (change queue (Task_Queue.finish task);
 199.102        if ok then ()
 199.103 -      else if TaskQueue.cancel (! queue) group then ()
 199.104 +      else if Task_Queue.cancel (! queue) group then ()
 199.105        else change canceled (cons group);
 199.106        notify_all ()));
 199.107    in () end;
 199.108 @@ -160,23 +154,23 @@
 199.109  
 199.110  (* worker threads *)
 199.111  
 199.112 -fun worker_wait name = (*requires SYNCHRONIZED*)
 199.113 -  (change_active false; wait name; change_active true);
 199.114 +fun worker_wait () = (*requires SYNCHRONIZED*)
 199.115 +  (change_active false; wait (); change_active true);
 199.116  
 199.117 -fun worker_next name = (*requires SYNCHRONIZED*)
 199.118 +fun worker_next () = (*requires SYNCHRONIZED*)
 199.119    if ! excessive > 0 then
 199.120      (dec excessive;
 199.121       change workers (filter_out (fn (thread, _) => Thread.equal (thread, Thread.self ())));
 199.122       notify_all ();
 199.123       NONE)
 199.124    else
 199.125 -    (case change_result queue TaskQueue.dequeue of
 199.126 -      NONE => (worker_wait name; worker_next name)
 199.127 +    (case change_result queue Task_Queue.dequeue of
 199.128 +      NONE => (worker_wait (); worker_next ())
 199.129      | some => some);
 199.130  
 199.131  fun worker_loop name =
 199.132 -  (case SYNCHRONIZED name (fn () => worker_next name) of
 199.133 -    NONE => Multithreading.tracing 3 (fn () => name ^ ": exit")
 199.134 +  (case SYNCHRONIZED name worker_next of
 199.135 +    NONE => ()
 199.136    | SOME work => (execute name work; worker_loop name));
 199.137  
 199.138  fun worker_start name = (*requires SYNCHRONIZED*)
 199.139 @@ -204,27 +198,25 @@
 199.140        else ();
 199.141  
 199.142      (*canceled groups*)
 199.143 -    val _ =  change canceled (filter_out (TaskQueue.cancel (! queue)));
 199.144 +    val _ =  change canceled (filter_out (Task_Queue.cancel (! queue)));
 199.145  
 199.146      (*shutdown*)
 199.147      val continue = not (! do_shutdown andalso null (! workers));
 199.148      val _ = if continue then () else scheduler := NONE;
 199.149  
 199.150      val _ = notify_all ();
 199.151 -    val _ = wait_timeout "scheduler" (Time.fromSeconds 3);
 199.152 +    val _ = wait_timeout (Time.fromSeconds 3);
 199.153    in continue end;
 199.154  
 199.155  fun scheduler_loop () =
 199.156 - (while SYNCHRONIZED "scheduler" scheduler_next do ();
 199.157 -  Multithreading.tracing 3 (fn () => "scheduler: exit"));
 199.158 +  while SYNCHRONIZED "scheduler" scheduler_next do ();
 199.159  
 199.160  fun scheduler_active () = (*requires SYNCHRONIZED*)
 199.161    (case ! scheduler of NONE => false | SOME thread => Thread.isActive thread);
 199.162  
 199.163  fun scheduler_check name = SYNCHRONIZED name (fn () =>
 199.164    if not (scheduler_active ()) then
 199.165 -    (Multithreading.tracing 3 (fn () => "scheduler: fork");
 199.166 -     do_shutdown := false; scheduler := SOME (SimpleThread.fork false scheduler_loop))
 199.167 +    (do_shutdown := false; scheduler := SOME (SimpleThread.fork false scheduler_loop))
 199.168    else if ! do_shutdown then error "Scheduler shutdown in progress"
 199.169    else ());
 199.170  
 199.171 @@ -235,7 +227,7 @@
 199.172    let
 199.173      val _ = scheduler_check "future check";
 199.174  
 199.175 -    val group = (case opt_group of SOME group => group | NONE => TaskQueue.new_group ());
 199.176 +    val group = (case opt_group of SOME group => group | NONE => Task_Queue.new_group ());
 199.177  
 199.178      val result = ref (NONE: 'a Exn.result option);
 199.179      val run = Multithreading.with_attributes (Thread.getAttributes ())
 199.180 @@ -246,18 +238,18 @@
 199.181            val res_ok =
 199.182              (case res of
 199.183                Exn.Result _ => true
 199.184 -            | Exn.Exn Exn.Interrupt => (TaskQueue.invalidate_group group; true)
 199.185 +            | Exn.Exn Exn.Interrupt => (Task_Queue.invalidate_group group; true)
 199.186              | _ => false);
 199.187          in res_ok end);
 199.188  
 199.189      val task = SYNCHRONIZED "future" (fn () =>
 199.190 -      change_result queue (TaskQueue.enqueue group deps pri run) before notify_all ());
 199.191 +      change_result queue (Task_Queue.enqueue group deps pri run) before notify_all ());
 199.192    in Future {task = task, group = group, result = result} end;
 199.193  
 199.194 -fun fork e = future NONE [] true e;
 199.195 -fun fork_group group e = future (SOME group) [] true e;
 199.196 -fun fork_deps deps e = future NONE (map task_of deps) true e;
 199.197 -fun fork_background e = future NONE [] false e;
 199.198 +fun fork e = future NONE [] 0 e;
 199.199 +fun fork_group group e = future (SOME group) [] 0 e;
 199.200 +fun fork_deps deps e = future NONE (map task_of deps) 0 e;
 199.201 +fun fork_pri pri e = future NONE [] pri e;
 199.202  
 199.203  
 199.204  (* join: retrieve results *)
 199.205 @@ -273,7 +265,7 @@
 199.206          fun join_loop _ [] = ()
 199.207            | join_loop name tasks =
 199.208                (case SYNCHRONIZED name (fn () =>
 199.209 -                  change_result queue (TaskQueue.dequeue_towards tasks)) of
 199.210 +                  change_result queue (Task_Queue.dequeue_towards tasks)) of
 199.211                  NONE => ()
 199.212                | SOME (work, tasks') => (execute name work; join_loop name tasks'));
 199.213          val _ =
 199.214 @@ -281,18 +273,18 @@
 199.215              NONE =>
 199.216                (*alien thread -- refrain from contending for resources*)
 199.217                while exists (not o is_finished) xs
 199.218 -              do SYNCHRONIZED "join_thread" (fn () => wait "join_thread")
 199.219 +              do SYNCHRONIZED "join_thread" (fn () => wait ())
 199.220            | SOME (name, task) =>
 199.221                (*proper task -- actively work towards results*)
 199.222                let
 199.223                  val unfinished = xs |> map_filter
 199.224                    (fn Future {task, result = ref NONE, ...} => SOME task | _ => NONE);
 199.225                  val _ = SYNCHRONIZED "join" (fn () =>
 199.226 -                  (change queue (TaskQueue.depend unfinished task); notify_all ()));
 199.227 +                  (change queue (Task_Queue.depend unfinished task); notify_all ()));
 199.228                  val _ = join_loop ("join_loop: " ^ name) unfinished;
 199.229                  val _ =
 199.230                    while exists (not o is_finished) xs
 199.231 -                  do SYNCHRONIZED "join_task" (fn () => worker_wait "join_task");
 199.232 +                  do SYNCHRONIZED "join_task" (fn () => worker_wait ());
 199.233                in () end);
 199.234  
 199.235        in xs |> map (fn Future {result = ref (SOME res), ...} => res) end) ();
 199.236 @@ -300,18 +292,16 @@
 199.237  fun join_result x = singleton join_results x;
 199.238  fun join x = Exn.release (join_result x);
 199.239  
 199.240 -fun map f x = fork_deps [x] (fn () => f (join x));
 199.241 +fun map f x =
 199.242 +  let val task = task_of x
 199.243 +  in future NONE [task] (Task_Queue.pri_of_task task) (fn () => f (join x)) end;
 199.244  
 199.245  
 199.246  (* misc operations *)
 199.247  
 199.248 -(*focus: collection of high-priority task*)
 199.249 -fun focus tasks = SYNCHRONIZED "focus" (fn () =>
 199.250 -  change queue (TaskQueue.focus tasks));
 199.251 -
 199.252  (*interrupt: permissive signal, may get ignored*)
 199.253  fun interrupt_task id = SYNCHRONIZED "interrupt"
 199.254 -  (fn () => TaskQueue.interrupt_external (! queue) id);
 199.255 +  (fn () => Task_Queue.interrupt_external (! queue) id);
 199.256  
 199.257  (*cancel: present and future group members will be interrupted eventually*)
 199.258  fun cancel x =
 199.259 @@ -324,12 +314,12 @@
 199.260    if Multithreading.available then
 199.261     (scheduler_check "shutdown check";
 199.262      SYNCHRONIZED "shutdown" (fn () =>
 199.263 -     (while not (scheduler_active ()) do wait "shutdown: scheduler inactive";
 199.264 -      while not (TaskQueue.is_empty (! queue)) do wait "shutdown: join";
 199.265 +     (while not (scheduler_active ()) do wait ();
 199.266 +      while not (Task_Queue.is_empty (! queue)) do wait ();
 199.267        do_shutdown := true;
 199.268        notify_all ();
 199.269 -      while not (null (! workers)) do wait "shutdown: workers";
 199.270 -      while scheduler_active () do wait "shutdown: scheduler still active";
 199.271 +      while not (null (! workers)) do wait ();
 199.272 +      while scheduler_active () do wait ();
 199.273        OS.Process.sleep (Time.fromMilliseconds 300))))
 199.274    else ();
 199.275  
   200.1 --- a/src/Pure/Concurrent/par_list.ML	Tue Dec 30 08:18:54 2008 +0100
   200.2 +++ b/src/Pure/Concurrent/par_list.ML	Tue Dec 30 11:10:01 2008 +0100
   200.3 @@ -30,7 +30,7 @@
   200.4  fun raw_map f xs =
   200.5    if Future.enabled () then
   200.6      let
   200.7 -      val group = TaskQueue.new_group ();
   200.8 +      val group = Task_Queue.new_group ();
   200.9        val futures = map (fn x => Future.fork_group group (fn () => f x)) xs;
  200.10        val _ = List.app (ignore o Future.join_result) futures;
  200.11      in Future.join_results futures end
   201.1 --- a/src/Pure/Concurrent/schedule.ML	Tue Dec 30 08:18:54 2008 +0100
   201.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   201.3 @@ -1,85 +0,0 @@
   201.4 -(*  Title:      Pure/Concurrent/schedule.ML
   201.5 -    ID:         $Id$
   201.6 -    Author:     Makarius
   201.7 -
   201.8 -Scheduling -- multiple threads working on a queue of tasks.
   201.9 -*)
  201.10 -
  201.11 -signature SCHEDULE =
  201.12 -sig
  201.13 -  datatype 'a task =
  201.14 -    Task of {body: unit -> unit, cont: 'a -> 'a, fail: 'a -> 'a} | Wait | Terminate;
  201.15 -  val schedule: int -> ('a -> 'a task * 'a) -> 'a -> exn list
  201.16 -end;
  201.17 -
  201.18 -structure Schedule: SCHEDULE =
  201.19 -struct
  201.20 -
  201.21 -datatype 'a task =
  201.22 -  Task of {body: unit -> unit, cont: 'a -> 'a, fail: 'a -> 'a} | Wait | Terminate;
  201.23 -
  201.24 -fun schedule n next_task = uninterruptible (fn restore_attributes => fn tasks =>
  201.25 -  let
  201.26 -    (*synchronized execution*)
  201.27 -    val lock = Mutex.mutex ();
  201.28 -    fun SYNCHRONIZED e =
  201.29 -      let
  201.30 -        val _ = Mutex.lock lock;
  201.31 -        val res = Exn.capture e ();
  201.32 -        val _ = Mutex.unlock lock;
  201.33 -      in Exn.release res end;
  201.34 -
  201.35 -    (*wakeup condition*)
  201.36 -    val wakeup = ConditionVar.conditionVar ();
  201.37 -    fun wakeup_all () = ConditionVar.broadcast wakeup;
  201.38 -    fun wait () = ConditionVar.wait (wakeup, lock);
  201.39 -    fun wait_timeout () =
  201.40 -      ConditionVar.waitUntil (wakeup, lock, Time.+ (Time.now (), Time.fromSeconds 1));
  201.41 -
  201.42 -    (*queue of tasks*)
  201.43 -    val queue = ref tasks;
  201.44 -    val active = ref 0;
  201.45 -    fun trace_active () = Multithreading.tracing 1 (fn () =>
  201.46 -      "SCHEDULE: " ^ string_of_int (! active) ^ " active");
  201.47 -    fun dequeue () =
  201.48 -      (case change_result queue next_task of
  201.49 -        Wait =>
  201.50 -          (dec active; trace_active ();
  201.51 -            wait ();
  201.52 -            inc active; trace_active ();
  201.53 -            dequeue ())
  201.54 -      | next => next);
  201.55 -
  201.56 -    (*pool of running threads*)
  201.57 -    val status = ref ([]: exn list);
  201.58 -    val running = ref ([]: Thread.thread list);
  201.59 -    fun start f = (inc active; change running (cons (SimpleThread.fork false f)));
  201.60 -    fun stop () = (dec active; change running (remove Thread.equal (Thread.self ())));
  201.61 -
  201.62 -    (*worker thread*)
  201.63 -    fun worker () =
  201.64 -      (case SYNCHRONIZED dequeue of
  201.65 -        Task {body, cont, fail} =>
  201.66 -          (case Exn.capture (restore_attributes body) () of
  201.67 -            Exn.Result () =>
  201.68 -              (SYNCHRONIZED (fn () => (change queue cont; wakeup_all ())); worker ())
  201.69 -          | Exn.Exn exn =>
  201.70 -              SYNCHRONIZED (fn () =>
  201.71 -                (change status (cons exn); change queue fail; stop (); wakeup_all ())))
  201.72 -      | Terminate => SYNCHRONIZED (fn () => (stop (); wakeup_all ())));
  201.73 -
  201.74 -    (*main control: fork and wait*)
  201.75 -    fun fork 0 = ()
  201.76 -      | fork k = (start worker; fork (k - 1));
  201.77 -    val _ = SYNCHRONIZED (fn () =>
  201.78 -     (fork (Int.max (n, 1));
  201.79 -      while not (null (! running)) do
  201.80 -      (trace_active ();
  201.81 -       if not (null (! status))
  201.82 -       then (List.app SimpleThread.interrupt (! running))
  201.83 -       else ();
  201.84 -       wait_timeout ())));
  201.85 -
  201.86 -  in ! status end);
  201.87 -
  201.88 -end;
   202.1 --- a/src/Pure/Concurrent/task_queue.ML	Tue Dec 30 08:18:54 2008 +0100
   202.2 +++ b/src/Pure/Concurrent/task_queue.ML	Tue Dec 30 11:10:01 2008 +0100
   202.3 @@ -1,5 +1,4 @@
   202.4  (*  Title:      Pure/Concurrent/task_queue.ML
   202.5 -    ID:         $Id$
   202.6      Author:     Makarius
   202.7  
   202.8  Ordered queue of grouped tasks.
   202.9 @@ -8,7 +7,8 @@
  202.10  signature TASK_QUEUE =
  202.11  sig
  202.12    eqtype task
  202.13 -  val new_task: unit -> task
  202.14 +  val new_task: int -> task
  202.15 +  val pri_of_task: task -> int
  202.16    val str_of_task: task -> string
  202.17    eqtype group
  202.18    val new_group: unit -> group
  202.19 @@ -17,9 +17,8 @@
  202.20    type queue
  202.21    val empty: queue
  202.22    val is_empty: queue -> bool
  202.23 -  val enqueue: group -> task list -> bool -> (bool -> bool) -> queue -> task * queue
  202.24 +  val enqueue: group -> task list -> int -> (bool -> bool) -> queue -> task * queue
  202.25    val depend: task list -> task -> queue -> queue
  202.26 -  val focus: task list -> queue -> queue
  202.27    val dequeue: queue -> (task * group * (unit -> bool)) option * queue
  202.28    val dequeue_towards: task list -> queue ->
  202.29      (((task * group * (unit -> bool)) * task list) option * queue)
  202.30 @@ -29,20 +28,27 @@
  202.31    val cancel: queue -> group -> bool
  202.32  end;
  202.33  
  202.34 -structure TaskQueue: TASK_QUEUE =
  202.35 +structure Task_Queue: TASK_QUEUE =
  202.36  struct
  202.37  
  202.38 -(* identifiers *)
  202.39 +(* tasks *)
  202.40  
  202.41 -datatype task = Task of serial;
  202.42 -fun new_task () = Task (serial ());
  202.43 +datatype task = Task of int * serial;
  202.44 +fun new_task pri = Task (pri, serial ());
  202.45  
  202.46 -fun str_of_task (Task i) = string_of_int i;
  202.47 +fun pri_of_task (Task (pri, _)) = pri;
  202.48 +fun str_of_task (Task (_, i)) = string_of_int i;
  202.49  
  202.50 +fun task_ord (Task t1, Task t2) = prod_ord (rev_order o int_ord) int_ord (t1, t2);
  202.51 +structure Task_Graph = GraphFun(type key = task val ord = task_ord);
  202.52 +
  202.53 +
  202.54 +(* groups *)
  202.55  
  202.56  datatype group = Group of serial * bool ref;
  202.57  
  202.58  fun new_group () = Group (serial (), ref true);
  202.59 +
  202.60  fun invalidate_group (Group (_, ok)) = ok := false;
  202.61  
  202.62  fun str_of_group (Group (i, ref ok)) =
  202.63 @@ -52,50 +58,46 @@
  202.64  (* jobs *)
  202.65  
  202.66  datatype job =
  202.67 -  Job of bool * (bool -> bool) |   (*priority, job: status -> status*)
  202.68 +  Job of bool -> bool |
  202.69    Running of Thread.thread;
  202.70  
  202.71 -type jobs = (group * job) IntGraph.T;
  202.72 +type jobs = (group * job) Task_Graph.T;
  202.73  
  202.74 -fun get_group (jobs: jobs) (Task id) = #1 (IntGraph.get_node jobs id);
  202.75 -fun get_job (jobs: jobs) (Task id) = #2 (IntGraph.get_node jobs id);
  202.76 -fun map_job (Task id) f (jobs: jobs) = IntGraph.map_node id (apsnd f) jobs;
  202.77 +fun get_group (jobs: jobs) task = #1 (Task_Graph.get_node jobs task);
  202.78 +fun get_job (jobs: jobs) task = #2 (Task_Graph.get_node jobs task);
  202.79 +fun map_job task f (jobs: jobs) = Task_Graph.map_node task (apsnd f) jobs;
  202.80  
  202.81 -fun add_job (Task id) (Task dep) (jobs: jobs) =
  202.82 -  IntGraph.add_edge_acyclic (dep, id) jobs handle IntGraph.UNDEF _ => jobs;
  202.83 +fun add_job task dep (jobs: jobs) =
  202.84 +  Task_Graph.add_edge (dep, task) jobs handle Task_Graph.UNDEF _ => jobs;
  202.85  
  202.86 -fun check_job (jobs: jobs) (task as Task id) =
  202.87 -  if can (IntGraph.get_node jobs) id then SOME task else NONE;
  202.88 +fun add_job_acyclic task dep (jobs: jobs) =
  202.89 +  Task_Graph.add_edge_acyclic (dep, task) jobs handle Task_Graph.UNDEF _ => jobs;
  202.90  
  202.91  
  202.92  (* queue of grouped jobs *)
  202.93  
  202.94  datatype queue = Queue of
  202.95   {groups: task list Inttab.table,   (*groups with presently active members*)
  202.96 -  jobs: jobs,                       (*job dependency graph*)
  202.97 -  focus: task list};                (*particular collection of high-priority tasks*)
  202.98 +  jobs: jobs};                      (*job dependency graph*)
  202.99  
 202.100 -fun make_queue groups jobs focus = Queue {groups = groups, jobs = jobs, focus = focus};
 202.101 +fun make_queue groups jobs = Queue {groups = groups, jobs = jobs};
 202.102  
 202.103 -val empty = make_queue Inttab.empty IntGraph.empty [];
 202.104 -fun is_empty (Queue {jobs, ...}) = IntGraph.is_empty jobs;
 202.105 +val empty = make_queue Inttab.empty Task_Graph.empty;
 202.106 +fun is_empty (Queue {jobs, ...}) = Task_Graph.is_empty jobs;
 202.107  
 202.108  
 202.109  (* enqueue *)
 202.110  
 202.111 -fun enqueue (group as Group (gid, _)) deps pri job (Queue {groups, jobs, focus}) =
 202.112 +fun enqueue (group as Group (gid, _)) deps pri job (Queue {groups, jobs}) =
 202.113    let
 202.114 -    val task as Task id = new_task ();
 202.115 +    val task = new_task pri;
 202.116      val groups' = Inttab.cons_list (gid, task) groups;
 202.117      val jobs' = jobs
 202.118 -      |> IntGraph.new_node (id, (group, Job (pri, job))) |> fold (add_job task) deps;
 202.119 -  in (task, make_queue groups' jobs' focus) end;
 202.120 +      |> Task_Graph.new_node (task, (group, Job job)) |> fold (add_job task) deps;
 202.121 +  in (task, make_queue groups' jobs') end;
 202.122  
 202.123 -fun depend deps task (Queue {groups, jobs, focus}) =
 202.124 -  make_queue groups (fold (add_job task) deps jobs) focus;
 202.125 -
 202.126 -fun focus tasks (Queue {groups, jobs, ...}) =
 202.127 -  make_queue groups jobs (map_filter (check_job jobs) tasks);
 202.128 +fun depend deps task (Queue {groups, jobs}) =
 202.129 +  make_queue groups (fold (add_job_acyclic task) deps jobs);
 202.130  
 202.131  
 202.132  (* dequeue *)
 202.133 @@ -103,38 +105,30 @@
 202.134  local
 202.135  
 202.136  fun dequeue_result NONE queue = (NONE, queue)
 202.137 -  | dequeue_result (SOME (result as (task, _, _))) (Queue {groups, jobs, focus}) =
 202.138 -      (SOME result, make_queue groups (map_job task (K (Running (Thread.self ()))) jobs) focus);
 202.139 -
 202.140 -fun dequeue_global req_pri (queue as Queue {jobs, ...}) =
 202.141 -  let
 202.142 -    fun ready (id, ((group as Group (_, ref ok), Job (pri, job)), ([], _))) =
 202.143 -          if pri = req_pri then SOME (Task id, group, (fn () => job ok)) else NONE
 202.144 -      | ready _ = NONE;
 202.145 -  in dequeue_result (IntGraph.get_first ready jobs) queue end;
 202.146 -
 202.147 -fun dequeue_local focus (queue as Queue {jobs, ...}) =
 202.148 -  let
 202.149 -    fun ready id =
 202.150 -      (case IntGraph.get_node jobs id of
 202.151 -        (group as Group (_, ref ok), Job (_, job)) =>
 202.152 -          if null (IntGraph.imm_preds jobs id) then SOME (Task id, group, (fn () => job ok))
 202.153 -          else NONE
 202.154 -      | _ => NONE);
 202.155 -    val ids = map (fn Task id => id) focus;
 202.156 -  in dequeue_result (get_first ready (IntGraph.all_preds jobs ids)) queue end;
 202.157 +  | dequeue_result (SOME (result as (task, _, _))) (Queue {groups, jobs}) =
 202.158 +      (SOME result, make_queue groups (map_job task (K (Running (Thread.self ()))) jobs));
 202.159  
 202.160  in
 202.161  
 202.162 -fun dequeue (queue as Queue {focus, ...}) =
 202.163 -  (case dequeue_local focus queue of
 202.164 -    (NONE, _) =>
 202.165 -      (case dequeue_global true queue of (NONE, _) => dequeue_global false queue | res => res)
 202.166 -  | res => res);
 202.167 +fun dequeue (queue as Queue {jobs, ...}) =
 202.168 +  let
 202.169 +    fun ready (task, ((group as Group (_, ref ok), Job job), ([], _))) =
 202.170 +          SOME (task, group, (fn () => job ok))
 202.171 +      | ready _ = NONE;
 202.172 +  in dequeue_result (Task_Graph.get_first ready jobs) queue end;
 202.173  
 202.174  fun dequeue_towards tasks (queue as Queue {jobs, ...}) =
 202.175 -  let val tasks' = map_filter (check_job jobs) tasks in
 202.176 -    (case dequeue_local tasks' queue of
 202.177 +  let
 202.178 +    val tasks' = filter (can (Task_Graph.get_node jobs)) tasks;
 202.179 +
 202.180 +    fun ready task =
 202.181 +      (case Task_Graph.get_node jobs task of
 202.182 +        (group as Group (_, ref ok), Job job) =>
 202.183 +          if null (Task_Graph.imm_preds jobs task) then SOME (task, group, (fn () => job ok))
 202.184 +          else NONE
 202.185 +      | _ => NONE);
 202.186 +  in
 202.187 +    (case dequeue_result (get_first ready (Task_Graph.all_preds jobs tasks')) queue of
 202.188        (NONE, queue') => (NONE, queue')
 202.189      | (SOME work, queue') => (SOME (work, tasks'), queue'))
 202.190    end;
 202.191 @@ -147,8 +141,13 @@
 202.192  fun interrupt (Queue {jobs, ...}) task =
 202.193    (case try (get_job jobs) task of SOME (Running thread) => SimpleThread.interrupt thread | _ => ());
 202.194  
 202.195 -fun interrupt_external queue str =
 202.196 -  (case Int.fromString str of SOME id => interrupt queue (Task id) | NONE => ());
 202.197 +fun interrupt_external (queue as Queue {jobs, ...}) str =
 202.198 +  (case Int.fromString str of
 202.199 +    SOME i =>
 202.200 +      (case Task_Graph.get_first
 202.201 +          (fn (task as Task (_, j), _) => if i = j then SOME task else NONE) jobs
 202.202 +        of SOME task => interrupt queue task | NONE => ())
 202.203 +  | NONE => ());
 202.204  
 202.205  
 202.206  (* misc operations *)
 202.207 @@ -161,12 +160,11 @@
 202.208      val _ = List.app SimpleThread.interrupt running;
 202.209    in null running end;
 202.210  
 202.211 -fun finish (task as Task id) (Queue {groups, jobs, focus}) =
 202.212 +fun finish task (Queue {groups, jobs}) =
 202.213    let
 202.214      val Group (gid, _) = get_group jobs task;
 202.215      val groups' = Inttab.remove_list (op =) (gid, task) groups;
 202.216 -    val jobs' = IntGraph.del_node id jobs;
 202.217 -    val focus' = remove (op =) task focus;
 202.218 -  in make_queue groups' jobs' focus' end;
 202.219 +    val jobs' = Task_Graph.del_node task jobs;
 202.220 +  in make_queue groups' jobs' end;
 202.221  
 202.222  end;
   203.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   203.2 +++ b/src/Pure/General/event_bus.scala	Tue Dec 30 11:10:01 2008 +0100
   203.3 @@ -0,0 +1,38 @@
   203.4 +/*  Title:      Pure/General/event_bus.scala
   203.5 +    Author:     Makarius
   203.6 +
   203.7 +Generic event bus with multiple handlers and optional exception
   203.8 +logging.
   203.9 +*/
  203.10 +
  203.11 +package isabelle
  203.12 +
  203.13 +import scala.collection.mutable.ListBuffer
  203.14 +
  203.15 +
  203.16 +class EventBus[Event]
  203.17 +{
  203.18 +  /* event handlers */
  203.19 +
  203.20 +  type Handler = Event => Unit
  203.21 +  private val handlers = new ListBuffer[Handler]
  203.22 +
  203.23 +  def += (h: Handler) = synchronized { handlers += h }
  203.24 +  def + (h: Handler) = { this += h; this }
  203.25 +
  203.26 +  def -= (h: Handler) = synchronized { handlers -= h }
  203.27 +  def - (h: Handler) = { this -= h; this }
  203.28 +
  203.29 +
  203.30 +  /* event invocation */
  203.31 +
  203.32 +  var logger: Throwable => Unit = throw _
  203.33 +
  203.34 +  def event(x: Event) = {
  203.35 +    val log = logger
  203.36 +    for (h <- synchronized { handlers.toList }) {
  203.37 +      try { h(x) }
  203.38 +      catch { case e: Throwable => log(e) }
  203.39 +    }
  203.40 +  }
  203.41 +}
   204.1 --- a/src/Pure/General/markup.scala	Tue Dec 30 08:18:54 2008 +0100
   204.2 +++ b/src/Pure/General/markup.scala	Tue Dec 30 11:10:01 2008 +0100
   204.3 @@ -1,5 +1,4 @@
   204.4  /*  Title:      Pure/General/markup.scala
   204.5 -    ID:         $Id$
   204.6      Author:     Makarius
   204.7  
   204.8  Common markup elements.
   204.9 @@ -9,6 +8,12 @@
  204.10  
  204.11  object Markup {
  204.12  
  204.13 +  /* name */
  204.14 +
  204.15 +  val NAME = "name"
  204.16 +  val KIND = "kind"
  204.17 +
  204.18 +
  204.19    /* position */
  204.20  
  204.21    val LINE = "line"
  204.22 @@ -20,12 +25,105 @@
  204.23    val FILE = "file"
  204.24    val ID = "id"
  204.25  
  204.26 +  val POSITION_PROPERTIES = Set(LINE, COLUMN, OFFSET, END_LINE, END_COLUMN, END_OFFSET, FILE, ID)
  204.27 +
  204.28 +  val POSITION = "position"
  204.29 +  val LOCATION = "location"
  204.30 +
  204.31 +
  204.32 +  /* logical entities */
  204.33 +
  204.34 +  val TCLASS = "tclass"
  204.35 +  val TYCON = "tycon"
  204.36 +  val FIXED_DECL = "fixed_decl"
  204.37 +  val FIXED = "fixed"
  204.38 +  val CONST_DECL = "const_decl"
  204.39 +  val CONST = "const"
  204.40 +  val FACT_DECL = "fact_decl"
  204.41 +  val FACT = "fact"
  204.42 +  val DYNAMIC_FACT = "dynamic_fact"
  204.43 +  val LOCAL_FACT_DECL = "local_fact_decl"
  204.44 +  val LOCAL_FACT = "local_fact"
  204.45 +
  204.46 +
  204.47 +  /* inner syntax */
  204.48 +
  204.49 +  val TFREE = "tfree"
  204.50 +  val TVAR = "tvar"
  204.51 +  val FREE = "free"
  204.52 +  val SKOLEM = "skolem"
  204.53 +  val BOUND = "bound"
  204.54 +  val VAR = "var"
  204.55 +  val NUM = "num"
  204.56 +  val FLOAT = "float"
  204.57 +  val XNUM = "xnum"
  204.58 +  val XSTR = "xstr"
  204.59 +  val LITERAL = "literal"
  204.60 +  val INNER_COMMENT = "inner_comment"
  204.61 +
  204.62 +  val SORT = "sort"
  204.63 +  val TYP = "typ"
  204.64 +  val TERM = "term"
  204.65 +  val PROP = "prop"
  204.66 +
  204.67 +  val ATTRIBUTE = "attribute"
  204.68 +  val METHOD = "method"
  204.69 +
  204.70 +
  204.71 +  /* embedded source text */
  204.72 +
  204.73 +  val ML_SOURCE = "ML_source"
  204.74 +  val DOC_SOURCE = "doc_source"
  204.75 +
  204.76 +  val ANTIQ = "antiq"
  204.77 +  val ML_ANTIQ = "ML_antiq"
  204.78 +  val DOC_ANTIQ = "doc_antiq"
  204.79 +
  204.80 +
  204.81 +  /* outer syntax */
  204.82 +
  204.83 +  val KEYWORD_DECL = "keyword_decl"
  204.84 +  val COMMAND_DECL = "command_decl"
  204.85 +
  204.86 +  val KEYWORD = "keyword"
  204.87 +  val COMMAND = "command"
  204.88 +  val IDENT = "ident"
  204.89 +  val STRING = "string"
  204.90 +  val ALTSTRING = "altstring"
  204.91 +  val VERBATIM = "verbatim"
  204.92 +  val COMMENT = "comment"
  204.93 +  val CONTROL = "control"
  204.94 +  val MALFORMED = "malformed"
  204.95 +
  204.96 +  val COMMAND_SPAN = "command_span"
  204.97 +  val IGNORED_SPAN = "ignored_span"
  204.98 +  val MALFORMED_SPAN = "malformed_span"
  204.99 +
 204.100 +
 204.101 +  /* toplevel */
 204.102 +
 204.103 +  val STATE = "state"
 204.104 +  val SUBGOAL = "subgoal"
 204.105 +  val SENDBACK = "sendback"
 204.106 +  val HILITE = "hilite"
 204.107 +
 204.108 +
 204.109 +  /* command status */
 204.110 +
 204.111 +  val UNPROCESSED = "unprocessed"
 204.112 +  val RUNNING = "running"
 204.113 +  val FAILED = "failed"
 204.114 +  val FINISHED = "finished"
 204.115 +  val DISPOSED = "disposed"
 204.116 +
 204.117  
 204.118    /* messages */
 204.119  
 204.120    val PID = "pid"
 204.121    val SESSION = "session"
 204.122  
 204.123 +  val MESSAGE = "message"
 204.124 +
 204.125  
 204.126    /* content */
 204.127  
   205.1 --- a/src/Pure/General/position.scala	Tue Dec 30 08:18:54 2008 +0100
   205.2 +++ b/src/Pure/General/position.scala	Tue Dec 30 11:10:01 2008 +0100
   205.3 @@ -1,5 +1,4 @@
   205.4  /*  Title:      Pure/General/position.scala
   205.5 -    ID:         $Id$
   205.6      Author:     Makarius
   205.7  
   205.8  Position properties.
   206.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   206.2 +++ b/src/Pure/General/swing.scala	Tue Dec 30 11:10:01 2008 +0100
   206.3 @@ -0,0 +1,18 @@
   206.4 +/*  Title:      Pure/General/swing.scala
   206.5 +    Author:     Makarius
   206.6 +
   206.7 +Swing utilities.
   206.8 +*/
   206.9 +
  206.10 +package isabelle
  206.11 +
  206.12 +import javax.swing.SwingUtilities
  206.13 +
  206.14 +object Swing
  206.15 +{
  206.16 +  def now(body: => Unit) =
  206.17 +    SwingUtilities.invokeAndWait(new Runnable { def run = body })
  206.18 +
  206.19 +  def later(body: => Unit) =
  206.20 +    SwingUtilities.invokeLater(new Runnable { def run = body })
  206.21 +}
   207.1 --- a/src/Pure/General/symbol.scala	Tue Dec 30 08:18:54 2008 +0100
   207.2 +++ b/src/Pure/General/symbol.scala	Tue Dec 30 11:10:01 2008 +0100
   207.3 @@ -1,5 +1,4 @@
   207.4  /*  Title:      Pure/General/symbol.scala
   207.5 -    ID:         $Id$
   207.6      Author:     Makarius
   207.7  
   207.8  Detecting and recoding Isabelle symbols.
   207.9 @@ -79,7 +78,7 @@
  207.10  
  207.11    /** Symbol interpretation **/
  207.12  
  207.13 -  class Interpretation {
  207.14 +  class Interpretation(isabelle_system: IsabelleSystem) {
  207.15  
  207.16      private var symbols = new HashMap[String, HashMap[String, String]]
  207.17      private var decoder: Recoder = null
  207.18 @@ -126,7 +125,7 @@
  207.19      }
  207.20  
  207.21      private def read_symbols(path: String) = {
  207.22 -      val file = new File(IsabelleSystem.platform_path(path))
  207.23 +      val file = new File(isabelle_system.platform_path(path))
  207.24        if (file.canRead) {
  207.25          for (line <- Source.fromFile(file).getLines) read_line(line)
  207.26        }
   208.1 --- a/src/Pure/General/xml.scala	Tue Dec 30 08:18:54 2008 +0100
   208.2 +++ b/src/Pure/General/xml.scala	Tue Dec 30 11:10:01 2008 +0100
   208.3 @@ -1,5 +1,4 @@
   208.4  /*  Title:      Pure/General/xml.scala
   208.5 -    ID:         $Id$
   208.6      Author:     Makarius
   208.7  
   208.8  Simple XML tree values.
   208.9 @@ -11,16 +10,56 @@
  208.10  import javax.xml.parsers.DocumentBuilderFactory
  208.11  
  208.12  
  208.13 -object XML {
  208.14 +object XML
  208.15 +{
  208.16    /* datatype representation */
  208.17  
  208.18    type Attributes = List[(String, String)]
  208.19  
  208.20 -  abstract class Tree
  208.21 +  abstract class Tree {
  208.22 +    override def toString = {
  208.23 +      val s = new StringBuilder
  208.24 +      append_tree(this, s)
  208.25 +      s.toString
  208.26 +    }
  208.27 +  }
  208.28    case class Elem(name: String, attributes: Attributes, body: List[Tree]) extends Tree
  208.29    case class Text(content: String) extends Tree
  208.30  
  208.31  
  208.32 +  /* string representation */
  208.33 +
  208.34 +  private def append_text(text: String, s: StringBuilder) {
  208.35 +    for (c <- text.elements) c match {
  208.36 +      case '<' => s.append("&lt;")
  208.37 +      case '>' => s.append("&gt;")
  208.38 +      case '&' => s.append("&amp;")
  208.39 +      case '"' => s.append("&quot;")
  208.40 +      case '\'' => s.append("&apos;")
  208.41 +      case _ => s.append(c)
  208.42 +    }
  208.43 +  }
  208.44 +
  208.45 +  private def append_elem(name: String, atts: Attributes, s: StringBuilder) {
  208.46 +    s.append(name)
  208.47 +    for ((a, x) <- atts) {
  208.48 +      s.append(" "); s.append(a); s.append("=\""); append_text(x, s); s.append("\"")
  208.49 +    }
  208.50 +  }
  208.51 +
  208.52 +  private def append_tree(tree: Tree, s: StringBuilder) {
  208.53 +    tree match {
  208.54 +      case Elem(name, atts, Nil) =>
  208.55 +        s.append("<"); append_elem(name, atts, s); s.append("/>")
  208.56 +      case Elem(name, atts, ts) =>
  208.57 +        s.append("<"); append_elem(name, atts, s); s.append(">")
  208.58 +        for (t <- ts) append_tree(t, s)
  208.59 +        s.append("</"); s.append(name); s.append(">")
  208.60 +      case Text(text) => append_text(text, s)
  208.61 +    }
  208.62 +  }
  208.63 +
  208.64 +
  208.65    /* iterate over content */
  208.66  
  208.67    private type State = Option[(String, List[Tree])]
   209.1 --- a/src/Pure/General/yxml.scala	Tue Dec 30 08:18:54 2008 +0100
   209.2 +++ b/src/Pure/General/yxml.scala	Tue Dec 30 11:10:01 2008 +0100
   209.3 @@ -1,5 +1,4 @@
   209.4  /*  Title:      Pure/General/yxml.scala
   209.5 -    ID:         $Id$
   209.6      Author:     Makarius
   209.7  
   209.8  Efficient text representation of XML trees.
   209.9 @@ -70,7 +69,7 @@
  209.10  
  209.11      var stack: List[((String, XML.Attributes), List[XML.Tree])] = null
  209.12  
  209.13 -    def add(x: XML.Tree) = stack match {
  209.14 +    def add(x: XML.Tree) = (stack: @unchecked) match {
  209.15        case ((elem, body) :: pending) => stack = (elem, x :: body) :: pending
  209.16      }
  209.17  
  209.18 @@ -78,7 +77,7 @@
  209.19        if (name == "") err_element()
  209.20        else stack = ((name, atts), Nil) :: stack
  209.21  
  209.22 -    def pop() = stack match {
  209.23 +    def pop() = (stack: @unchecked) match {
  209.24        case ((("", _), _) :: _) => err_unbalanced("")
  209.25        case (((name, atts), body) :: pending) =>
  209.26          stack = pending; add(XML.Elem(name, atts, body.reverse))
   210.1 --- a/src/Pure/IsaMakefile	Tue Dec 30 08:18:54 2008 +0100
   210.2 +++ b/src/Pure/IsaMakefile	Tue Dec 30 11:10:01 2008 +0100
   210.3 @@ -23,27 +23,24 @@
   210.4  
   210.5  $(OUT)/Pure: Concurrent/ROOT.ML Concurrent/future.ML			\
   210.6    Concurrent/mailbox.ML Concurrent/par_list.ML				\
   210.7 -  Concurrent/par_list_dummy.ML Concurrent/schedule.ML			\
   210.8 -  Concurrent/simple_thread.ML Concurrent/synchronized.ML		\
   210.9 -  Concurrent/task_queue.ML General/ROOT.ML General/alist.ML		\
  210.10 -  General/balanced_tree.ML General/basics.ML General/binding.ML         \
  210.11 -  General/buffer.ML		\
  210.12 -  General/file.ML General/graph.ML General/heap.ML General/integer.ML	\
  210.13 -  General/lazy.ML General/markup.ML General/name_space.ML		\
  210.14 -  General/ord_list.ML General/output.ML General/path.ML			\
  210.15 -  General/position.ML General/pretty.ML General/print_mode.ML		\
  210.16 -  General/properties.ML General/queue.ML General/scan.ML		\
  210.17 -  General/secure.ML General/seq.ML General/source.ML General/stack.ML	\
  210.18 -  General/symbol.ML General/symbol_pos.ML General/table.ML		\
  210.19 -  General/url.ML General/xml.ML General/yxml.ML Isar/ROOT.ML		\
  210.20 -  Isar/antiquote.ML Isar/args.ML Isar/attrib.ML Isar/auto_bind.ML	\
  210.21 -  Isar/calculation.ML Isar/class.ML Isar/code.ML Isar/code_unit.ML	\
  210.22 -  Isar/constdefs.ML Isar/context_rules.ML Isar/element.ML		\
  210.23 -  Isar/expression.ML							\
  210.24 -  Isar/find_theorems.ML Isar/instance.ML Isar/isar.ML Isar/isar_cmd.ML	\
  210.25 -  Isar/isar_syn.ML Isar/local_defs.ML Isar/local_syntax.ML		\
  210.26 -  Isar/local_theory.ML Isar/locale.ML Isar/method.ML Isar/net_rules.ML	\
  210.27 -  Isar/new_locale.ML    \
  210.28 +  Concurrent/par_list_dummy.ML Concurrent/simple_thread.ML		\
  210.29 +  Concurrent/synchronized.ML Concurrent/task_queue.ML General/ROOT.ML	\
  210.30 +  General/alist.ML General/balanced_tree.ML General/basics.ML		\
  210.31 +  General/buffer.ML General/file.ML General/graph.ML General/heap.ML	\
  210.32 +  General/integer.ML General/lazy.ML General/markup.ML			\
  210.33 +  General/name_space.ML General/ord_list.ML General/output.ML		\
  210.34 +  General/path.ML General/position.ML General/pretty.ML			\
  210.35 +  General/print_mode.ML General/properties.ML General/queue.ML		\
  210.36 +  General/scan.ML General/secure.ML General/seq.ML General/source.ML	\
  210.37 +  General/stack.ML General/symbol.ML General/symbol_pos.ML		\
  210.38 +  General/table.ML General/url.ML General/xml.ML General/yxml.ML	\
  210.39 +  Isar/ROOT.ML Isar/antiquote.ML Isar/args.ML Isar/attrib.ML		\
  210.40 +  Isar/auto_bind.ML Isar/calculation.ML Isar/class.ML Isar/code.ML	\
  210.41 +  Isar/code_unit.ML Isar/constdefs.ML Isar/context_rules.ML		\
  210.42 +  Isar/element.ML Isar/expression.ML Isar/find_theorems.ML		\
  210.43 +  Isar/instance.ML Isar/isar.ML Isar/isar_cmd.ML Isar/isar_syn.ML	\
  210.44 +  Isar/local_defs.ML Isar/local_syntax.ML Isar/local_theory.ML		\
  210.45 +  Isar/locale.ML Isar/method.ML Isar/net_rules.ML Isar/new_locale.ML	\
  210.46    Isar/object_logic.ML Isar/obtain.ML Isar/outer_keyword.ML		\
  210.47    Isar/outer_lex.ML Isar/outer_parse.ML Isar/outer_syntax.ML		\
  210.48    Isar/overloading.ML Isar/proof.ML Isar/proof_context.ML		\
  210.49 @@ -77,17 +74,16 @@
  210.50    Syntax/syn_trans.ML Syntax/syntax.ML Syntax/type_ext.ML Thy/html.ML	\
  210.51    Thy/latex.ML Thy/present.ML Thy/term_style.ML Thy/thm_deps.ML		\
  210.52    Thy/thy_edit.ML Thy/thy_header.ML Thy/thy_info.ML Thy/thy_load.ML	\
  210.53 -  Thy/thy_output.ML Tools/ROOT.ML Tools/invoke.ML 	\
  210.54 -  Tools/isabelle_process.ML Tools/named_thms.ML		\
  210.55 -  Tools/xml_syntax.ML assumption.ML axclass.ML codegen.ML config.ML	\
  210.56 -  conjunction.ML consts.ML context.ML context_position.ML conv.ML	\
  210.57 -  defs.ML display.ML drule.ML envir.ML facts.ML goal.ML			\
  210.58 -  interpretation.ML library.ML logic.ML meta_simplifier.ML more_thm.ML	\
  210.59 -  morphism.ML name.ML net.ML old_goals.ML pattern.ML primitive_defs.ML	\
  210.60 -  proofterm.ML pure_setup.ML pure_thy.ML search.ML sign.ML		\
  210.61 -  simplifier.ML sorts.ML subgoal.ML tactic.ML tctical.ML term.ML	\
  210.62 -  term_subst.ML theory.ML thm.ML type.ML type_infer.ML unify.ML		\
  210.63 -  variable.ML ../Tools/value.ML ../Tools/quickcheck.ML
  210.64 +  Thy/thy_output.ML Tools/ROOT.ML Tools/invoke.ML			\
  210.65 +  Tools/isabelle_process.ML Tools/named_thms.ML Tools/xml_syntax.ML	\
  210.66 +  assumption.ML axclass.ML codegen.ML config.ML conjunction.ML		\
  210.67 +  consts.ML context.ML context_position.ML conv.ML defs.ML display.ML	\
  210.68 +  drule.ML envir.ML facts.ML goal.ML interpretation.ML library.ML	\
  210.69 +  logic.ML meta_simplifier.ML more_thm.ML morphism.ML name.ML net.ML	\
  210.70 +  old_goals.ML pattern.ML primitive_defs.ML proofterm.ML pure_setup.ML	\
  210.71 +  pure_thy.ML search.ML sign.ML simplifier.ML sorts.ML subgoal.ML	\
  210.72 +  tactic.ML tctical.ML term.ML term_subst.ML theory.ML thm.ML type.ML	\
  210.73 +  type_infer.ML unify.ML variable.ML ../Tools/quickcheck.ML
  210.74  	@./mk
  210.75  
  210.76  
  210.77 @@ -125,9 +121,10 @@
  210.78  
  210.79  ## Scala material
  210.80  
  210.81 -SCALA_FILES = General/markup.scala General/position.scala		\
  210.82 -  General/symbol.scala General/xml.scala General/yxml.scala		\
  210.83 -  Isar/isar.scala Thy/thy_header.scala Tools/isabelle_process.scala	\
  210.84 +SCALA_FILES = General/event_bus.scala General/markup.scala		\
  210.85 +  General/position.scala General/swing.scala General/symbol.scala	\
  210.86 +  General/xml.scala General/yxml.scala Isar/isar.scala			\
  210.87 +  Thy/thy_header.scala Tools/isabelle_process.scala			\
  210.88    Tools/isabelle_syntax.scala Tools/isabelle_system.scala
  210.89  
  210.90  
   211.1 --- a/src/Pure/Isar/class.ML	Tue Dec 30 08:18:54 2008 +0100
   211.2 +++ b/src/Pure/Isar/class.ML	Tue Dec 30 11:10:01 2008 +0100
   211.3 @@ -60,6 +60,59 @@
   211.4  structure Class : CLASS =
   211.5  struct
   211.6  
   211.7 +(*temporary adaption code to mediate between old and new locale code*)
   211.8 +
   211.9 +structure Old_Locale =
  211.10 +struct
  211.11 +
  211.12 +val intro_locales_tac = Locale.intro_locales_tac; (*already forked!*)
  211.13 +
  211.14 +val interpretation = Locale.interpretation;
  211.15 +val interpretation_in_locale = Locale.interpretation_in_locale;
  211.16 +val get_interpret_morph = Locale.get_interpret_morph;
  211.17 +val Locale = Locale.Locale;
  211.18 +val extern = Locale.extern;
  211.19 +val intros = Locale.intros;
  211.20 +val dests = Locale.dests;
  211.21 +val init = Locale.init;
  211.22 +val Merge = Locale.Merge;
  211.23 +val parameters_of_expr = Locale.parameters_of_expr;
  211.24 +val empty = Locale.empty;
  211.25 +val cert_expr = Locale.cert_expr;
  211.26 +val read_expr = Locale.read_expr;
  211.27 +val parameters_of = Locale.parameters_of;
  211.28 +val add_locale = Locale.add_locale;
  211.29 +
  211.30 +end;
  211.31 +
  211.32 +structure New_Locale =
  211.33 +struct
  211.34 +
  211.35 +val intro_locales_tac = Locale.intro_locales_tac; (*already forked!*)
  211.36 +
  211.37 +val interpretation = Locale.interpretation; (*!*)
  211.38 +val interpretation_in_locale = Locale.interpretation_in_locale; (*!*)
  211.39 +val get_interpret_morph = Locale.get_interpret_morph; (*!*)
  211.40 +fun Locale loc = ([(loc, ("", Expression.Positional []))], []);
  211.41 +val extern = NewLocale.extern;
  211.42 +val intros = Locale.intros; (*!*)
  211.43 +val dests = Locale.dests; (*!*)
  211.44 +val init = NewLocale.init;
  211.45 +fun Merge locs = (map (fn loc => (loc, ("", Expression.Positional []))) locs, []);
  211.46 +val parameters_of_expr = Locale.parameters_of_expr; (*!*)
  211.47 +val empty = ([], []);
  211.48 +val cert_expr = Locale.cert_expr; (*!"*)
  211.49 +val read_expr = Locale.read_expr; (*!"*)
  211.50 +val parameters_of = NewLocale.params_of; (*why typ option?*)
  211.51 +val add_locale = Expression.add_locale;
  211.52 +
  211.53 +end;
  211.54 +
  211.55 +structure Locale = Old_Locale;
  211.56 +
  211.57 +(*proper code again*)
  211.58 +
  211.59 +
  211.60  (** auxiliary **)
  211.61  
  211.62  fun prove_interpretation tac prfx_atts expr inst =
  211.63 @@ -542,7 +595,7 @@
  211.64      val suplocales = map Locale.Locale sups;
  211.65      val supexpr = Locale.Merge suplocales;
  211.66      val supparams = (map fst o Locale.parameters_of_expr thy) supexpr;
  211.67 -    val mergeexpr = Locale.Merge (suplocales);
  211.68 +    val mergeexpr = Locale.Merge suplocales;
  211.69      val constrain = Element.Constrains ((map o apsnd o map_atyps)
  211.70        (K (TFree (Name.aT, base_sort))) supparams);
  211.71      fun fork_syn (Element.Fixes xs) =
   212.1 --- a/src/Pure/Isar/isar.scala	Tue Dec 30 08:18:54 2008 +0100
   212.2 +++ b/src/Pure/Isar/isar.scala	Tue Dec 30 11:10:01 2008 +0100
   212.3 @@ -1,7 +1,5 @@
   212.4  /*  Title:      Pure/Isar/isar.scala
   212.5 -    ID:         $Id$
   212.6      Author:     Makarius
   212.7 -    Options:    :folding=explicit:collapseFolds=1:
   212.8  
   212.9  Isar toplevel editor model.
  212.10  */
  212.11 @@ -11,7 +9,9 @@
  212.12  import java.util.Properties
  212.13  
  212.14  
  212.15 -class Isar(args: String*) extends IsabelleProcess(args: _*) {
  212.16 +class Isar(isabelle_system: IsabelleSystem, results: EventBus[IsabelleProcess.Result], args: String*)
  212.17 +  extends IsabelleProcess(isabelle_system, results, args: _*)
  212.18 +{
  212.19  
  212.20    /* basic editor commands */
  212.21  
   213.1 --- a/src/Pure/Isar/local_theory.ML	Tue Dec 30 08:18:54 2008 +0100
   213.2 +++ b/src/Pure/Isar/local_theory.ML	Tue Dec 30 11:10:01 2008 +0100
   213.3 @@ -1,5 +1,4 @@
   213.4  (*  Title:      Pure/Isar/local_theory.ML
   213.5 -    ID:         $Id$
   213.6      Author:     Makarius
   213.7  
   213.8  Local theory operations, with abstract target context.
   214.1 --- a/src/Pure/Isar/proof.ML	Tue Dec 30 08:18:54 2008 +0100
   214.2 +++ b/src/Pure/Isar/proof.ML	Tue Dec 30 11:10:01 2008 +0100
   214.3 @@ -1,5 +1,4 @@
   214.4  (*  Title:      Pure/Isar/proof.ML
   214.5 -    ID:         $Id$
   214.6      Author:     Markus Wenzel, TU Muenchen
   214.7  
   214.8  The Isar/VM proof language interpreter: maintains a structured flow of
   214.9 @@ -826,7 +825,7 @@
  214.10      |> null props ? (refine (Method.Basic (Method.assumption, Position.none)) #> Seq.hd)
  214.11    end;
  214.12  
  214.13 -fun generic_qed state =
  214.14 +fun generic_qed after_ctxt state =
  214.15    let
  214.16      val (goal_ctxt, {statement, goal, after_qed, ...}) = current_goal state;
  214.17      val outer_state = state |> close_block;
  214.18 @@ -845,7 +844,7 @@
  214.19      fun after_global' x y = Position.setmp_thread_data pos (fn () => after_global x y) ();
  214.20    in
  214.21      outer_state
  214.22 -    |> map_context (ProofContext.auto_bind_facts props)
  214.23 +    |> map_context (after_ctxt props)
  214.24      |> pair ((after_local', after_global'), results)
  214.25    end;
  214.26  
  214.27 @@ -872,7 +871,8 @@
  214.28  
  214.29  fun local_qed txt =
  214.30    end_proof false txt #>
  214.31 -  Seq.maps (generic_qed #-> (fn ((after_qed, _), results) => after_qed results));
  214.32 +  Seq.maps (generic_qed ProofContext.auto_bind_facts #->
  214.33 +    (fn ((after_qed, _), results) => after_qed results));
  214.34  
  214.35  
  214.36  (* global goals *)
  214.37 @@ -892,7 +892,7 @@
  214.38  
  214.39  fun global_qeds txt =
  214.40    end_proof true txt
  214.41 -  #> Seq.map (generic_qed #> (fn (((_, after_qed), results), state) =>
  214.42 +  #> Seq.map (generic_qed (K I) #> (fn (((_, after_qed), results), state) =>
  214.43      after_qed results (context_of state)))
  214.44    |> Seq.DETERM;   (*backtracking may destroy theory!*)
  214.45  
   215.1 --- a/src/Pure/Isar/theory_target.ML	Tue Dec 30 08:18:54 2008 +0100
   215.2 +++ b/src/Pure/Isar/theory_target.ML	Tue Dec 30 11:10:01 2008 +0100
   215.3 @@ -1,6 +1,4 @@
   215.4  (*  Title:      Pure/Isar/theory_target.ML
   215.5 -    ID:         $Id$
   215.6 -    ID:         $Id$
   215.7      Author:     Makarius
   215.8  
   215.9  Common theory/locale/class/instantiation/overloading targets.
   216.1 --- a/src/Pure/Isar/toplevel.ML	Tue Dec 30 08:18:54 2008 +0100
   216.2 +++ b/src/Pure/Isar/toplevel.ML	Tue Dec 30 11:10:01 2008 +0100
   216.3 @@ -718,7 +718,7 @@
   216.4  
   216.5          val future_proof = Proof.future_proof
   216.6            (fn prf =>
   216.7 -            Future.fork_background (fn () =>
   216.8 +            Future.fork_pri 1 (fn () =>
   216.9                let val (states, State (result_node, _)) =
  216.10                  (case st' of State (SOME (Proof (_, (_, orig_gthy)), exit), prev)
  216.11                    => State (SOME (Proof (ProofNode.init prf, (finish, orig_gthy)), exit), prev))
   217.1 --- a/src/Pure/ROOT.ML	Tue Dec 30 08:18:54 2008 +0100
   217.2 +++ b/src/Pure/ROOT.ML	Tue Dec 30 11:10:01 2008 +0100
   217.3 @@ -87,8 +87,6 @@
   217.4  
   217.5  cd "Tools"; use "ROOT.ML"; cd "..";
   217.6  
   217.7 -use "../Tools/value.ML";
   217.8 -use "../Tools/quickcheck.ML";
   217.9  use "codegen.ML";
  217.10  
  217.11  (*configuration for Proof General*)
   218.1 --- a/src/Pure/Syntax/lexicon.ML	Tue Dec 30 08:18:54 2008 +0100
   218.2 +++ b/src/Pure/Syntax/lexicon.ML	Tue Dec 30 11:10:01 2008 +0100
   218.3 @@ -145,8 +145,18 @@
   218.4  val tidT = Type ("tid", []);
   218.5  val tvarT = Type ("tvar", []);
   218.6  
   218.7 -val terminals =
   218.8 -  ["id", "longid", "var", "tid", "tvar", "num", "float", "xnum", "xstr"];
   218.9 +val terminal_kinds =
  218.10 + [("id", IdentSy),
  218.11 +  ("longid", LongIdentSy),
  218.12 +  ("var", VarSy),
  218.13 +  ("tid", TFreeSy),
  218.14 +  ("tvar", TVarSy),
  218.15 +  ("num", NumSy),
  218.16 +  ("float_token", FloatSy),
  218.17 +  ("xnum", XNumSy),
  218.18 +  ("xstr", StrSy)];
  218.19 +
  218.20 +val terminals = map #1 terminal_kinds;
  218.21  val is_terminal = member (op =) terminals;
  218.22  
  218.23  
  218.24 @@ -186,16 +196,10 @@
  218.25  
  218.26  (* predef_term *)
  218.27  
  218.28 -fun predef_term "id" = SOME (Token (IdentSy, "id", Position.no_range))
  218.29 -  | predef_term "longid" = SOME (Token (LongIdentSy, "longid", Position.no_range))
  218.30 -  | predef_term "var" = SOME (Token (VarSy, "var", Position.no_range))
  218.31 -  | predef_term "tid" = SOME (Token (TFreeSy, "tid", Position.no_range))
  218.32 -  | predef_term "tvar" = SOME (Token (TVarSy, "tvar", Position.no_range))
  218.33 -  | predef_term "num" = SOME (Token (NumSy, "num", Position.no_range))
  218.34 -  | predef_term "float" = SOME (Token (FloatSy, "float", Position.no_range))
  218.35 -  | predef_term "xnum" = SOME (Token (XNumSy, "xnum", Position.no_range))
  218.36 -  | predef_term "xstr" = SOME (Token (StrSy, "xstr", Position.no_range))
  218.37 -  | predef_term _ = NONE;
  218.38 +fun predef_term s =
  218.39 +  (case AList.lookup (op =) terminal_kinds s of
  218.40 +    SOME sy => SOME (Token (sy, s, Position.no_range))
  218.41 +  | NONE => NONE);
  218.42  
  218.43  
  218.44  (* xstr tokens *)
  218.45 @@ -382,21 +386,27 @@
  218.46        | "0" :: "b" :: cs => (1, 2, cs)
  218.47        | "-" :: cs => (~1, 10, cs)
  218.48        | cs => (1, 10, cs));
  218.49 -    val value = sign * #1 (Library.read_radix_int radix digs);
  218.50 -  in {radix = radix, leading_zeros = leading_zeros digs, value = value} end;
  218.51 +  in
  218.52 +   {radix = radix,
  218.53 +    leading_zeros = leading_zeros digs,
  218.54 +    value = sign * #1 (Library.read_radix_int radix digs)}
  218.55 +  end;
  218.56  
  218.57  end;
  218.58  
  218.59  fun read_float str =
  218.60    let
  218.61      val (sign, cs) =
  218.62 -      (case Symbol.explode str of  "-" :: cs => (~1, cs) | cs => (1, cs));
  218.63 -    val (intpart,fracpart) =
  218.64 +      (case Symbol.explode str of
  218.65 +        "-" :: cs => (~1, cs)
  218.66 +      | cs => (1, cs));
  218.67 +    val (intpart, fracpart) =
  218.68        (case take_prefix Symbol.is_digit cs of
  218.69 -        (intpart, "." :: fracpart) => (intpart,fracpart)
  218.70 -      | _ =>  sys_error "read_float")
  218.71 -  in {mant = sign * #1 (Library.read_int (intpart@fracpart)),
  218.72 -      exp = length fracpart}
  218.73 +        (intpart, "." :: fracpart) => (intpart, fracpart)
  218.74 +      | _ => raise Fail "read_float");
  218.75 +  in
  218.76 +   {mant = sign * #1 (Library.read_int (intpart @ fracpart)),
  218.77 +    exp = length fracpart}
  218.78    end
  218.79  
  218.80  end;
   219.1 --- a/src/Pure/Syntax/syntax.ML	Tue Dec 30 08:18:54 2008 +0100
   219.2 +++ b/src/Pure/Syntax/syntax.ML	Tue Dec 30 11:10:01 2008 +0100
   219.3 @@ -1,5 +1,4 @@
   219.4  (*  Title:      Pure/Syntax/syntax.ML
   219.5 -    ID:         $Id$
   219.6      Author:     Tobias Nipkow and Markus Wenzel, TU Muenchen
   219.7  
   219.8  Standard Isabelle syntax, based on arbitrary context-free grammars
   220.1 --- a/src/Pure/Thy/thy_header.scala	Tue Dec 30 08:18:54 2008 +0100
   220.2 +++ b/src/Pure/Thy/thy_header.scala	Tue Dec 30 11:10:01 2008 +0100
   220.3 @@ -1,5 +1,4 @@
   220.4  /*  Title:      Pure/Thy/thy_header.scala
   220.5 -    ID:         $Id$
   220.6      Author:     Makarius
   220.7  
   220.8  Theory header keywords.
   221.1 --- a/src/Pure/Thy/thy_info.ML	Tue Dec 30 08:18:54 2008 +0100
   221.2 +++ b/src/Pure/Thy/thy_info.ML	Tue Dec 30 11:10:01 2008 +0100
   221.3 @@ -315,7 +315,13 @@
   221.4  datatype task = Task of (unit -> unit) | Finished | Running;
   221.5  fun task_finished Finished = true | task_finished _ = false;
   221.6  
   221.7 -fun future_schedule task_graph =
   221.8 +local
   221.9 +
  221.10 +fun schedule_seq tasks =
  221.11 +  Graph.topological_order tasks
  221.12 +  |> List.app (fn name => (case Graph.get_node tasks name of Task body => body () | _ => ()));
  221.13 +
  221.14 +fun schedule_futures task_graph =
  221.15    let
  221.16      val tasks = Graph.topological_order task_graph |> map_filter (fn name =>
  221.17        (case Graph.get_node task_graph name of Task body => SOME (name, body) | _ => NONE));
  221.18 @@ -339,45 +345,14 @@
  221.19      val proof_results = PureThy.join_proofs (map_filter (try get_theory o #1) tasks);
  221.20    in ignore (Exn.release_all (thy_results @ proof_results)) end;
  221.21  
  221.22 -local
  221.23 -
  221.24 -fun max_task (name, (Task body, m)) NONE = SOME (name: string, (body, m))
  221.25 -  | max_task (name, (Task body, m)) (task' as SOME (name', (_, m'))) =
  221.26 -      if m > m' orelse m = m' andalso name < name' then SOME (name, (body, m)) else task'
  221.27 -  | max_task _ task' = task';
  221.28 -
  221.29 -fun next_task G =
  221.30 -  let
  221.31 -    val tasks = Graph.minimals G |> map (fn name =>
  221.32 -      (name, (Graph.get_node G name, length (Graph.imm_succs G name))));
  221.33 -    val finished = filter (task_finished o fst o snd) tasks;
  221.34 -  in
  221.35 -    if not (null finished) then next_task (Graph.del_nodes (map fst finished) G)
  221.36 -    else if null tasks then (Schedule.Terminate, G)
  221.37 -    else
  221.38 -      (case fold max_task tasks NONE of
  221.39 -        NONE => (Schedule.Wait, G)
  221.40 -      | SOME (name, (body, _)) =>
  221.41 -         (Schedule.Task {body = PrintMode.closure body,
  221.42 -           cont = Graph.del_nodes [name], fail = K Graph.empty},
  221.43 -          Graph.map_node name (K Running) G))
  221.44 -  end;
  221.45 -
  221.46 -fun schedule_seq tasks =
  221.47 -  Graph.topological_order tasks
  221.48 -  |> List.app (fn name => (case Graph.get_node tasks name of Task body => body () | _ => ()));
  221.49 -
  221.50  in
  221.51  
  221.52  fun schedule_tasks tasks n =
  221.53 -  let val m = Multithreading.max_threads_value () in
  221.54 -    if m <= 1 then schedule_seq tasks
  221.55 -    else if Multithreading.self_critical () then
  221.56 +  if not (Multithreading.enabled ()) then schedule_seq tasks
  221.57 +  else if Multithreading.self_critical () then
  221.58       (warning (loader_msg "no multithreading within critical section" []);
  221.59        schedule_seq tasks)
  221.60 -    else if Future.enabled () then future_schedule tasks
  221.61 -    else ignore (Exn.release_all (map Exn.Exn (Schedule.schedule (Int.min (m, n)) next_task tasks)))
  221.62 -  end;
  221.63 +  else schedule_futures tasks;
  221.64  
  221.65  end;
  221.66  
   222.1 --- a/src/Pure/Tools/ROOT.ML	Tue Dec 30 08:18:54 2008 +0100
   222.2 +++ b/src/Pure/Tools/ROOT.ML	Tue Dec 30 11:10:01 2008 +0100
   222.3 @@ -11,3 +11,6 @@
   222.4  
   222.5  (*derived theory and proof elements*)
   222.6  use "invoke.ML";
   222.7 +
   222.8 +(*quickcheck needed here because of pg preferences*)
   222.9 +use "../../Tools/quickcheck.ML"
   223.1 --- a/src/Pure/Tools/isabelle_process.scala	Tue Dec 30 08:18:54 2008 +0100
   223.2 +++ b/src/Pure/Tools/isabelle_process.scala	Tue Dec 30 11:10:01 2008 +0100
   223.3 @@ -1,5 +1,4 @@
   223.4  /*  Title:      Pure/Tools/isabelle_process.ML
   223.5 -    ID:         $Id$
   223.6      Author:     Makarius
   223.7      Options:    :folding=explicit:collapseFolds=1:
   223.8  
   223.9 @@ -13,8 +12,6 @@
  223.10  import java.io.{BufferedReader, BufferedWriter, InputStreamReader, OutputStreamWriter,
  223.11    InputStream, OutputStream, IOException}
  223.12  
  223.13 -import isabelle.{Symbol, XML}
  223.14 -
  223.15  
  223.16  object IsabelleProcess {
  223.17  
  223.18 @@ -70,21 +67,28 @@
  223.19  
  223.20    class Result(val kind: Kind.Value, val props: Properties, val result: String) {
  223.21      override def toString = {
  223.22 -      val res = XML.content(YXML.parse_failsafe(result)).mkString("")
  223.23 +      val res = XML.content(YXML.parse_failsafe(result)).mkString
  223.24        if (props == null) kind.toString + " [[" + res + "]]"
  223.25        else kind.toString + " " + props.toString + " [[" + res + "]]"
  223.26      }
  223.27 -    def is_raw() = Kind.is_raw(kind)
  223.28 -    def is_control() = Kind.is_control(kind)
  223.29 -    def is_system() = Kind.is_system(kind)
  223.30 +    def is_raw = Kind.is_raw(kind)
  223.31 +    def is_control = Kind.is_control(kind)
  223.32 +    def is_system = Kind.is_system(kind)
  223.33    }
  223.34  
  223.35  }
  223.36  
  223.37  
  223.38 -class IsabelleProcess(args: String*) {
  223.39 +class IsabelleProcess(isabelle_system: IsabelleSystem,
  223.40 +  results: EventBus[IsabelleProcess.Result], args: String*)
  223.41 +{
  223.42 +  import IsabelleProcess._
  223.43  
  223.44 -  import IsabelleProcess._
  223.45 +
  223.46 +  /* demo constructor */
  223.47 +
  223.48 +  def this(args: String*) =
  223.49 +    this(new IsabelleSystem, new EventBus[IsabelleProcess.Result] + Console.println, args: _*)
  223.50  
  223.51  
  223.52    /* process information */
  223.53 @@ -98,21 +102,31 @@
  223.54  
  223.55    /* results */
  223.56  
  223.57 -  private val results = new LinkedBlockingQueue[Result]
  223.58 +  private val result_queue = new LinkedBlockingQueue[Result]
  223.59  
  223.60    private def put_result(kind: Kind.Value, props: Properties, result: String) {
  223.61      if (kind == Kind.INIT && props != null) {
  223.62        pid = props.getProperty(Markup.PID)
  223.63        the_session = props.getProperty(Markup.SESSION)
  223.64      }
  223.65 -    results.put(new Result(kind, props, result))
  223.66 +    result_queue.put(new Result(kind, props, result))
  223.67    }
  223.68  
  223.69 -  def get_result() = results.take
  223.70 +  private class ResultThread extends Thread("isabelle: results") {
  223.71 +    override def run() = {
  223.72 +      var finished = false
  223.73 +      while (!finished) {
  223.74 +        val result =
  223.75 +          try { result_queue.take }
  223.76 +          catch { case _: NullPointerException => null }
  223.77  
  223.78 -  def try_result() = {
  223.79 -    val res = results.poll
  223.80 -    if (res != null) Some(res) else None
  223.81 +        if (result != null) {
  223.82 +          results.event(result)  // FIXME try/catch (!??)
  223.83 +          if (result.kind == Kind.EXIT) finished = true
  223.84 +        }
  223.85 +        else finished = true
  223.86 +      }
  223.87 +    }
  223.88    }
  223.89  
  223.90  
  223.91 @@ -123,7 +137,7 @@
  223.92      if (pid == null) put_result(Kind.SYSTEM, null, "Cannot interrupt: unknown pid")
  223.93      else {
  223.94        try {
  223.95 -        if (IsabelleSystem.exec("kill", "-INT", pid).waitFor == 0)
  223.96 +        if (isabelle_system.execute(true, "kill", "-INT", pid).waitFor == 0)
  223.97            put_result(Kind.SIGNAL, null, "INT")
  223.98          else
  223.99            put_result(Kind.SYSTEM, null, "Cannot interrupt: kill command failed")
 223.100 @@ -186,7 +200,7 @@
 223.101  
 223.102    private class StdinThread(out_stream: OutputStream) extends Thread("isabelle: stdin") {
 223.103      override def run() = {
 223.104 -      val writer = new BufferedWriter(new OutputStreamWriter(out_stream, IsabelleSystem.charset))
 223.105 +      val writer = new BufferedWriter(new OutputStreamWriter(out_stream, isabelle_system.charset))
 223.106        var finished = false
 223.107        while (!finished) {
 223.108          try {
 223.109 @@ -216,7 +230,7 @@
 223.110  
 223.111    private class StdoutThread(in_stream: InputStream) extends Thread("isabelle: stdout") {
 223.112      override def run() = {
 223.113 -      val reader = new BufferedReader(new InputStreamReader(in_stream, IsabelleSystem.charset))
 223.114 +      val reader = new BufferedReader(new InputStreamReader(in_stream, isabelle_system.charset))
 223.115        var result = new StringBuilder(100)
 223.116  
 223.117        var finished = false
 223.118 @@ -254,7 +268,7 @@
 223.119  
 223.120    private class MessageThread(fifo: String) extends Thread("isabelle: messages") {
 223.121      override def run() = {
 223.122 -      val reader = IsabelleSystem.fifo_reader(fifo)
 223.123 +      val reader = isabelle_system.fifo_reader(fifo)
 223.124        var kind: Kind.Value = null
 223.125        var props: Properties = null
 223.126        var result = new StringBuilder
 223.127 @@ -332,33 +346,36 @@
 223.128    }
 223.129  
 223.130  
 223.131 +
 223.132    /** main **/
 223.133  
 223.134    {
 223.135      /* isabelle version */
 223.136  
 223.137      {
 223.138 -      val (msg, rc) = IsabelleSystem.isabelle_tool("version")
 223.139 +      val (msg, rc) = isabelle_system.isabelle_tool("version")
 223.140        if (rc != 0) error("Version check failed -- bad Isabelle installation:\n" + msg)
 223.141        put_result(Kind.SYSTEM, null, msg)
 223.142      }
 223.143  
 223.144  
 223.145 -    /* message fifo */
 223.146 +    /* messages */
 223.147  
 223.148 -    val message_fifo = IsabelleSystem.mk_fifo()
 223.149 -    def rm_fifo() = IsabelleSystem.rm_fifo(message_fifo)
 223.150 +    val message_fifo = isabelle_system.mk_fifo()
 223.151 +    def rm_fifo() = isabelle_system.rm_fifo(message_fifo)
 223.152  
 223.153      val message_thread = new MessageThread(message_fifo)
 223.154      message_thread.start
 223.155  
 223.156 +    new ResultThread().start
 223.157 +
 223.158  
 223.159      /* exec process */
 223.160  
 223.161      try {
 223.162        val cmdline =
 223.163 -        List(IsabelleSystem.getenv_strict("ISABELLE_PROCESS"), "-W", message_fifo) ++ args
 223.164 -      proc = IsabelleSystem.exec2(cmdline: _*)
 223.165 +        List(isabelle_system.getenv_strict("ISABELLE_PROCESS"), "-W", message_fifo) ++ args
 223.166 +      proc = isabelle_system.execute(true, cmdline: _*)
 223.167      }
 223.168      catch {
 223.169        case e: IOException =>
 223.170 @@ -386,5 +403,4 @@
 223.171      }.start
 223.172  
 223.173    }
 223.174 -
 223.175  }
   224.1 --- a/src/Pure/Tools/isabelle_syntax.scala	Tue Dec 30 08:18:54 2008 +0100
   224.2 +++ b/src/Pure/Tools/isabelle_syntax.scala	Tue Dec 30 11:10:01 2008 +0100
   224.3 @@ -1,5 +1,4 @@
   224.4  /*  Title:      Pure/Tools/isabelle_syntax.scala
   224.5 -    ID:         $Id$
   224.6      Author:     Makarius
   224.7  
   224.8  Isabelle outer syntax.
   225.1 --- a/src/Pure/Tools/isabelle_system.scala	Tue Dec 30 08:18:54 2008 +0100
   225.2 +++ b/src/Pure/Tools/isabelle_system.scala	Tue Dec 30 11:10:01 2008 +0100
   225.3 @@ -1,5 +1,4 @@
   225.4  /*  Title:      Pure/Tools/isabelle_system.scala
   225.5 -    ID:         $Id$
   225.6      Author:     Makarius
   225.7  
   225.8  Isabelle system support -- basic Cygwin/Posix compatibility.
   225.9 @@ -13,24 +12,26 @@
  225.10  import scala.io.Source
  225.11  
  225.12  
  225.13 -object IsabelleSystem {
  225.14 +class IsabelleSystem {
  225.15  
  225.16    val charset = "UTF-8"
  225.17  
  225.18  
  225.19    /* Isabelle environment settings */
  225.20  
  225.21 +  private val environment = System.getenv
  225.22 +
  225.23    def getenv(name: String) = {
  225.24 -    val value = System.getenv(if (name == "HOME") "HOME_JVM" else name)
  225.25 +    val value = environment.get(if (name == "HOME") "HOME_JVM" else name)
  225.26      if (value != null) value else ""
  225.27    }
  225.28  
  225.29    def getenv_strict(name: String) = {
  225.30 -    val value = getenv(name)
  225.31 +    val value = environment.get(name)
  225.32      if (value != "") value else error("Undefined environment variable: " + name)
  225.33    }
  225.34  
  225.35 -  def is_cygwin() = Pattern.matches(".*-cygwin", getenv_strict("ML_PLATFORM"))
  225.36 +  val is_cygwin = Pattern.matches(".*-cygwin", getenv_strict("ML_PLATFORM"))
  225.37  
  225.38  
  225.39    /* file path specifications */
  225.40 @@ -75,17 +76,22 @@
  225.41      result_path.toString
  225.42    }
  225.43  
  225.44 +  def platform_file(path: String) =
  225.45 +    new File(platform_path(path))
  225.46 +
  225.47  
  225.48    /* processes */
  225.49  
  225.50 -  private def posix_prefix() = if (is_cygwin()) List(platform_path("/bin/env")) else Nil
  225.51 +  def execute(redirect: Boolean, args: String*): Process = {
  225.52 +    val cmdline = new java.util.LinkedList[String]
  225.53 +    if (is_cygwin) cmdline.add(platform_path("/bin/env"))
  225.54 +    for (s <- args) cmdline.add(s)
  225.55  
  225.56 -  def exec(args: String*): Process = Runtime.getRuntime.exec((posix_prefix() ++ args).toArray)
  225.57 -
  225.58 -  def exec2(args: String*): Process = {
  225.59 -    val cmdline = new java.util.LinkedList[String]
  225.60 -    for (s <- posix_prefix() ++ args) cmdline.add(s)
  225.61 -    new ProcessBuilder(cmdline).redirectErrorStream(true).start
  225.62 +    val proc = new ProcessBuilder(cmdline)
  225.63 +    proc.environment.clear
  225.64 +    proc.environment.putAll(environment)
  225.65 +    proc.redirectErrorStream(redirect)
  225.66 +    proc.start
  225.67    }
  225.68  
  225.69  
  225.70 @@ -93,10 +99,10 @@
  225.71  
  225.72    def isabelle_tool(args: String*) = {
  225.73      val proc =
  225.74 -      try { exec2((List(getenv_strict("ISABELLE_TOOL")) ++ args): _*) }
  225.75 +      try { execute(true, (List(getenv_strict("ISABELLE_TOOL")) ++ args): _*) }
  225.76        catch { case e: IOException => error(e.getMessage) }
  225.77      proc.getOutputStream.close
  225.78 -    val output = Source.fromInputStream(proc.getInputStream, charset).mkString("")
  225.79 +    val output = Source.fromInputStream(proc.getInputStream, charset).mkString
  225.80      val rc = proc.waitFor
  225.81      (output, rc)
  225.82    }
  225.83 @@ -115,9 +121,26 @@
  225.84      if (rc != 0) error(result)
  225.85    }
  225.86  
  225.87 -  def fifo_reader(fifo: String) =  // blocks until writer is ready
  225.88 -    if (is_cygwin()) new BufferedReader(new InputStreamReader(Runtime.getRuntime.exec(
  225.89 -      Array(platform_path("/bin/cat"), fifo)).getInputStream, charset))
  225.90 -    else new BufferedReader(new InputStreamReader(new FileInputStream(fifo), charset))
  225.91 +  def fifo_reader(fifo: String) = {
  225.92 +    // blocks until writer is ready
  225.93 +    val stream =
  225.94 +      if (is_cygwin) execute(false, "cat", fifo).getInputStream
  225.95 +      else new FileInputStream(fifo)
  225.96 +    new BufferedReader(new InputStreamReader(stream, charset))
  225.97 +  }
  225.98  
  225.99 +
 225.100 +  /* find logics */
 225.101 +
 225.102 +  def find_logics() = {
 225.103 +    val ml_ident = getenv_strict("ML_IDENTIFIER")
 225.104 +    var logics: Set[String] = Set()
 225.105 +    for (dir <- getenv_strict("ISABELLE_PATH").split(":")) {
 225.106 +      val files = platform_file(dir + "/" + ml_ident).listFiles()
 225.107 +      if (files != null) {
 225.108 +        for (file <- files if file.isFile) logics += file.getName
 225.109 +      }
 225.110 +    }
 225.111 +    logics.toList.sort(_ < _)
 225.112 +  }
 225.113  }
   226.1 --- a/src/Pure/codegen.ML	Tue Dec 30 08:18:54 2008 +0100
   226.2 +++ b/src/Pure/codegen.ML	Tue Dec 30 11:10:01 2008 +0100
   226.3 @@ -1025,8 +1025,6 @@
   226.4  
   226.5  val setup = add_codegen "default" default_codegen
   226.6    #> add_tycodegen "default" default_tycodegen
   226.7 -  #> Value.add_evaluator ("SML", eval_term o ProofContext.theory_of)
   226.8 -  #> Quickcheck.add_generator ("SML", test_term)
   226.9    #> Code.add_attribute ("unfold", Scan.succeed (Thm.declaration_attribute
  226.10         (fn thm => Context.mapping (add_unfold thm #> Code.add_inline thm) I)))
  226.11    #> add_preprocessor unfold_preprocessor;
   227.1 --- a/src/Pure/context.ML	Tue Dec 30 08:18:54 2008 +0100
   227.2 +++ b/src/Pure/context.ML	Tue Dec 30 11:10:01 2008 +0100
   227.3 @@ -21,11 +21,10 @@
   227.4    val ancestors_of: theory -> theory list
   227.5    val theory_name: theory -> string
   227.6    val is_stale: theory -> bool
   227.7 -  val PureN: string
   227.8    val is_draft: theory -> bool
   227.9    val reject_draft: theory -> theory
  227.10 -  val exists_name: string -> theory -> bool
  227.11 -  val names_of: theory -> string list
  227.12 +  val PureN: string
  227.13 +  val display_names: theory -> string list
  227.14    val pretty_thy: theory -> Pretty.T
  227.15    val string_of_thy: theory -> string
  227.16    val pprint_thy: theory -> pprint_args -> unit
  227.17 @@ -144,17 +143,18 @@
  227.18  datatype theory =
  227.19    Theory of
  227.20     (*identity*)
  227.21 -   {self: theory ref option,            (*dynamic self reference -- follows theory changes*)
  227.22 -    id: serial * (string * int),        (*identifier/name of this theory node*)
  227.23 -    ids: (string * int) Inttab.table} * (*ancestors and checkpoints*)
  227.24 +   {self: theory ref option,      (*dynamic self reference -- follows theory changes*)
  227.25 +    draft: bool,                  (*draft mode -- linear destructive changes*)
  227.26 +    id: serial,                   (*identifier*)
  227.27 +    ids: unit Inttab.table} *     (*cumulative identifiers of non-drafts -- symbolic body content*)
  227.28     (*data*)
  227.29 -   Object.T Datatab.table *
  227.30 +   Object.T Datatab.table *       (*body content*)
  227.31     (*ancestry*)
  227.32 -   {parents: theory list,               (*immediate predecessors*)
  227.33 -    ancestors: theory list} *           (*all predecessors*)
  227.34 +   {parents: theory list,         (*immediate predecessors*)
  227.35 +    ancestors: theory list} *     (*all predecessors -- canonical reverse order*)
  227.36     (*history*)
  227.37 -   {name: string,                       (*prospective name of finished theory*)
  227.38 -    version: int};                      (*checkpoint counter*)
  227.39 +   {name: string,                 (*official theory name*)
  227.40 +    stage: int};                  (*checkpoint counter*)
  227.41  
  227.42  exception THEORY of string * theory list;
  227.43  
  227.44 @@ -165,9 +165,9 @@
  227.45  val ancestry_of = #3 o rep_theory;
  227.46  val history_of  = #4 o rep_theory;
  227.47  
  227.48 -fun make_identity self id ids = {self = self, id = id, ids = ids};
  227.49 +fun make_identity self draft id ids = {self = self, draft = draft, id = id, ids = ids};
  227.50  fun make_ancestry parents ancestors = {parents = parents, ancestors = ancestors};
  227.51 -fun make_history name version = {name = name, version = version};
  227.52 +fun make_history name stage = {name = name, stage = stage};
  227.53  
  227.54  val the_self = the o #self o identity_of;
  227.55  val parents_of = #parents o ancestry_of;
  227.56 @@ -177,7 +177,7 @@
  227.57  
  227.58  (* staleness *)
  227.59  
  227.60 -fun eq_id ((i: int, _), (j, _)) = (i = j);
  227.61 +fun eq_id (i: int, j) = i = j;
  227.62  
  227.63  fun is_stale
  227.64      (Theory ({self = SOME (ref (Theory ({id = id', ...}, _, _, _))), id, ...}, _, _, _)) =
  227.65 @@ -185,47 +185,46 @@
  227.66    | is_stale (Theory ({self = NONE, ...}, _, _, _)) = true;
  227.67  
  227.68  fun vitalize (thy as Theory ({self = SOME r, ...}, _, _, _)) = (r := thy; thy)
  227.69 -  | vitalize (thy as Theory ({self = NONE, id, ids}, data, ancestry, history)) =
  227.70 +  | vitalize (thy as Theory ({self = NONE, draft, id, ids}, data, ancestry, history)) =
  227.71        let
  227.72          val r = ref thy;
  227.73 -        val thy' = Theory (make_identity (SOME r) id ids, data, ancestry, history);
  227.74 +        val thy' = Theory (make_identity (SOME r) draft id ids, data, ancestry, history);
  227.75        in r := thy'; thy' end;
  227.76  
  227.77  
  227.78 -(* names *)
  227.79 +(* draft mode *)
  227.80  
  227.81 -val PureN = "Pure";
  227.82 -
  227.83 -val draftN = "#";
  227.84 -val draft_name = (draftN, ~1);
  227.85 -
  227.86 -fun draft_id (_, (name, _)) = (name = draftN);
  227.87 -val is_draft = draft_id o #id o identity_of;
  227.88 +val is_draft = #draft o identity_of;
  227.89  
  227.90  fun reject_draft thy =
  227.91    if is_draft thy then raise THEORY ("Illegal draft theory -- stable checkpoint required", [thy])
  227.92    else thy;
  227.93  
  227.94 -fun exists_name name (thy as Theory ({id = (_, (a, _)), ids, ...}, _, _, _)) =
  227.95 -  name = theory_name thy orelse
  227.96 -  name = a orelse
  227.97 -  Inttab.exists (fn (_, (b, _)) => b = name) ids;
  227.98  
  227.99 -fun name_of (a, ~1) = a
 227.100 -  | name_of (a, i) = a ^ ":" ^ string_of_int i;
 227.101 +(* names *)
 227.102  
 227.103 -fun names_of (Theory ({id = (_, a), ids, ...}, _, _, _)) =
 227.104 -  rev (name_of a :: Inttab.fold (fn (_, (b, ~1)) => cons b | _ => I) ids []);
 227.105 +val PureN = "Pure";
 227.106 +val draftN = "#";
 227.107 +val finished = ~1;
 227.108  
 227.109 -fun pretty_thy thy =
 227.110 -  Pretty.str_list "{" "}" (names_of thy @ (if is_stale thy then ["!"] else []));
 227.111 +fun display_names thy =
 227.112 +  let
 227.113 +    val draft = if is_draft thy then [draftN] else [];
 227.114 +    val {stage, ...} = history_of thy;
 227.115 +    val name =
 227.116 +      if stage = finished then theory_name thy
 227.117 +      else theory_name thy ^ ":" ^ string_of_int stage;
 227.118 +    val ancestor_names = map theory_name (ancestors_of thy);
 227.119 +    val stale = if is_stale thy then ["!"] else [];
 227.120 +  in rev (stale @ draft @ [name] @ ancestor_names) end;
 227.121  
 227.122 +val pretty_thy = Pretty.str_list "{" "}" o display_names;
 227.123  val string_of_thy = Pretty.string_of o pretty_thy;
 227.124  val pprint_thy = Pretty.pprint o pretty_thy;
 227.125  
 227.126  fun pretty_abbrev_thy thy =
 227.127    let
 227.128 -    val names = names_of thy;
 227.129 +    val names = display_names thy;
 227.130      val n = length names;
 227.131      val abbrev = if n > 5 then "..." :: List.drop (names, n - 5) else names;
 227.132    in Pretty.str_list "{" "}" abbrev end;
 227.133 @@ -252,20 +251,18 @@
 227.134  val pprint_thy_ref = Pretty.pprint o pretty_thy o deref;
 227.135  
 227.136  
 227.137 -(* consistency *)
 227.138 +(* build ids *)
 227.139  
 227.140 -fun check_insert id ids =
 227.141 -  if draft_id id orelse Inttab.defined ids (#1 id) then ids
 227.142 -  else if Inttab.exists (fn (_, a) => a = #2 id) ids then
 227.143 -    error ("Different versions of theory component " ^ quote (name_of (#2 id)))
 227.144 -  else Inttab.update id ids;
 227.145 +fun insert_id draft id ids =
 227.146 +  if draft then ids
 227.147 +  else Inttab.update (id, ()) ids;
 227.148  
 227.149 -fun check_merge
 227.150 -    (Theory ({id = id1, ids = ids1, ...}, _, _, _))
 227.151 -    (Theory ({id = id2, ids = ids2, ...}, _, _, _)) =
 227.152 -  Inttab.fold check_insert ids2 ids1
 227.153 -  |> check_insert id1
 227.154 -  |> check_insert id2;
 227.155 +fun merge_ids
 227.156 +    (Theory ({draft = draft1, id = id1, ids = ids1, ...}, _, _, _))
 227.157 +    (Theory ({draft = draft2, id = id2, ids = ids2, ...}, _, _, _)) =
 227.158 +  Inttab.merge (K true) (ids1, ids2)
 227.159 +  |> insert_id draft1 id1
 227.160 +  |> insert_id draft2 id2;
 227.161  
 227.162  
 227.163  (* equality and inclusion *)
 227.164 @@ -273,22 +270,35 @@
 227.165  val eq_thy = eq_id o pairself (#id o identity_of);
 227.166  
 227.167  fun proper_subthy (Theory ({id, ...}, _, _, _), Theory ({ids, ...}, _, _, _)) =
 227.168 -  Inttab.defined ids (#1 id);
 227.169 +  Inttab.defined ids id;
 227.170  
 227.171  fun subthy thys = eq_thy thys orelse proper_subthy thys;
 227.172  
 227.173  fun joinable (thy1, thy2) = subthy (thy1, thy2) orelse subthy (thy2, thy1);
 227.174  
 227.175  
 227.176 +(* consistent ancestors *)
 227.177 +
 227.178 +fun extend_ancestors thy thys =
 227.179 +  if member eq_thy thys thy then raise THEORY ("Duplicate theory node", thy :: thys)
 227.180 +  else thy :: thys;
 227.181 +
 227.182 +fun extend_ancestors_of thy = extend_ancestors thy (ancestors_of thy);
 227.183 +
 227.184 +val merge_ancestors = merge (fn (thy1, thy2) =>
 227.185 +  eq_thy (thy1, thy2) orelse
 227.186 +    theory_name thy1 = theory_name thy2 andalso
 227.187 +      raise THEORY ("Inconsistent theory versions", [thy1, thy2]));
 227.188 +
 227.189 +
 227.190  (* trivial merge *)
 227.191  
 227.192  fun merge (thy1, thy2) =
 227.193    if eq_thy (thy1, thy2) then thy1
 227.194    else if proper_subthy (thy2, thy1) then thy1
 227.195    else if proper_subthy (thy1, thy2) then thy2
 227.196 -  else (check_merge thy1 thy2;
 227.197 -    error (cat_lines ["Attempt to perform non-trivial merge of theories:",
 227.198 -      str_of_thy thy1, str_of_thy thy2]));
 227.199 +  else error (cat_lines ["Attempt to perform non-trivial merge of theories:",
 227.200 +    str_of_thy thy1, str_of_thy thy2]);
 227.201  
 227.202  fun merge_refs (ref1, ref2) =
 227.203    if ref1 = ref2 then ref1
 227.204 @@ -300,41 +310,38 @@
 227.205  
 227.206  (* primitives *)
 227.207  
 227.208 -fun create_thy name self id ids data ancestry history =
 227.209 +fun create_thy self draft ids data ancestry history =
 227.210 +  let val identity = make_identity self draft (serial ()) ids;
 227.211 +  in vitalize (Theory (identity, data, ancestry, history)) end;
 227.212 +
 227.213 +fun change_thy draft' f thy =
 227.214    let
 227.215 -    val {version, ...} = history;
 227.216 -    val ids' = check_insert id ids;
 227.217 -    val id' = (serial (), name);
 227.218 -    val _ = check_insert id' ids';
 227.219 -    val identity' = make_identity self id' ids';
 227.220 -  in vitalize (Theory (identity', data, ancestry, history)) end;
 227.221 -
 227.222 -fun change_thy name f thy =
 227.223 -  let
 227.224 -    val Theory ({self, id, ids}, data, ancestry, history) = thy;
 227.225 +    val Theory ({self, draft, id, ids}, data, ancestry, history) = thy;
 227.226      val (self', data', ancestry') =
 227.227 -      if is_draft thy then (self, data, ancestry)    (*destructive change!*)
 227.228 -      else if #version history > 0
 227.229 +      if draft then (self, data, ancestry)    (*destructive change!*)
 227.230 +      else if #stage history > 0
 227.231        then (NONE, copy_data data, ancestry)
 227.232 -      else (NONE, extend_data data, make_ancestry [thy] (thy :: #ancestors ancestry));
 227.233 +      else (NONE, extend_data data, make_ancestry [thy] (extend_ancestors_of thy));
 227.234 +    val ids' = insert_id draft id ids;
 227.235      val data'' = f data';
 227.236      val thy' = NAMED_CRITICAL "theory" (fn () =>
 227.237 -      (check_thy thy; create_thy name self' id ids data'' ancestry' history));
 227.238 +      (check_thy thy; create_thy self' draft' ids' data'' ancestry' history));
 227.239    in thy' end;
 227.240  
 227.241 -fun name_thy name = change_thy name I;
 227.242 -val modify_thy = change_thy draft_name;
 227.243 -val extend_thy = modify_thy I;
 227.244 +val name_thy = change_thy false I;
 227.245 +val extend_thy = change_thy true I;
 227.246 +val modify_thy = change_thy true;
 227.247  
 227.248  fun copy_thy thy =
 227.249    let
 227.250 -    val Theory ({id, ids, ...}, data, ancestry, history) = thy;
 227.251 +    val Theory ({draft, id, ids, ...}, data, ancestry, history) = thy;
 227.252 +    val ids' = insert_id draft id ids;
 227.253      val data' = copy_data data;
 227.254      val thy' = NAMED_CRITICAL "theory" (fn () =>
 227.255 -      (check_thy thy; create_thy draft_name NONE id ids data' ancestry history));
 227.256 +      (check_thy thy; create_thy NONE true ids' data' ancestry history));
 227.257    in thy' end;
 227.258  
 227.259 -val pre_pure_thy = create_thy draft_name NONE (serial (), draft_name) Inttab.empty
 227.260 +val pre_pure_thy = create_thy NONE true Inttab.empty
 227.261    Datatab.empty (make_ancestry [] []) (make_history PureN 0);
 227.262  
 227.263  
 227.264 @@ -342,56 +349,56 @@
 227.265  
 227.266  fun merge_thys pp (thy1, thy2) =
 227.267    let
 227.268 -    val ids = check_merge thy1 thy2;
 227.269 +    val ids = merge_ids thy1 thy2;
 227.270      val data = merge_data (pp thy1) (data_of thy1, data_of thy2);
 227.271      val ancestry = make_ancestry [] [];
 227.272      val history = make_history "" 0;
 227.273      val thy' = NAMED_CRITICAL "theory" (fn () =>
 227.274 -     (check_thy thy1; check_thy thy2;
 227.275 -      create_thy draft_name NONE (serial (), draft_name) ids data ancestry history));
 227.276 +     (check_thy thy1; check_thy thy2; create_thy NONE true ids data ancestry history));
 227.277    in thy' end;
 227.278  
 227.279  fun maximal_thys thys =
 227.280    thys |> filter_out (fn thy => exists (fn thy' => proper_subthy (thy, thy')) thys);
 227.281  
 227.282  fun begin_thy pp name imports =
 227.283 -  if name = draftN then error ("Illegal theory name: " ^ quote draftN)
 227.284 +  if name = "" orelse name = draftN then error ("Bad theory name: " ^ quote name)
 227.285    else
 227.286      let
 227.287        val parents = maximal_thys (distinct eq_thy imports);
 227.288 -      val ancestors = distinct eq_thy (parents @ maps ancestors_of parents);
 227.289 -      val Theory ({id, ids, ...}, data, _, _) =
 227.290 +      val ancestors =
 227.291 +        Library.foldl merge_ancestors ([], map ancestors_of parents)
 227.292 +        |> fold extend_ancestors parents;
 227.293 +
 227.294 +      val Theory ({ids, ...}, data, _, _) =
 227.295          (case parents of
 227.296            [] => error "No parent theories"
 227.297          | [thy] => extend_thy thy
 227.298          | thy :: thys => Library.foldl (merge_thys pp) (thy, thys));
 227.299 +
 227.300        val ancestry = make_ancestry parents ancestors;
 227.301        val history = make_history name 0;
 227.302        val thy' = NAMED_CRITICAL "theory" (fn () =>
 227.303 -        (map check_thy imports; create_thy draft_name NONE id ids data ancestry history));
 227.304 +        (map check_thy imports; create_thy NONE true ids data ancestry history));
 227.305      in thy' end;
 227.306  
 227.307  
 227.308 -(* persistent checkpoints *)
 227.309 +(* history stages *)
 227.310 +
 227.311 +fun history_stage f thy =
 227.312 +  let
 227.313 +    val {name, stage} = history_of thy;
 227.314 +    val _ = stage = finished andalso raise THEORY ("Theory already finished", [thy]);
 227.315 +    val history' = make_history name (f stage);
 227.316 +    val thy' as Theory (identity', data', ancestry', _) = name_thy thy;
 227.317 +    val thy'' = NAMED_CRITICAL "theory" (fn () =>
 227.318 +      (check_thy thy'; vitalize (Theory (identity', data', ancestry', history'))));
 227.319 +  in thy'' end;
 227.320  
 227.321  fun checkpoint_thy thy =
 227.322 -  if not (is_draft thy) then thy
 227.323 -  else
 227.324 -    let
 227.325 -      val {name, version} = history_of thy;
 227.326 -      val thy' as Theory (identity', data', ancestry', _) = name_thy (name, version) thy;
 227.327 -      val history' = make_history name (version + 1);
 227.328 -      val thy'' = NAMED_CRITICAL "theory" (fn () =>
 227.329 -        (check_thy thy'; vitalize (Theory (identity', data', ancestry', history'))));
 227.330 -    in thy'' end;
 227.331 +  if is_draft thy then history_stage (fn stage => stage + 1) thy
 227.332 +  else thy;
 227.333  
 227.334 -fun finish_thy thy = NAMED_CRITICAL "theory" (fn () =>
 227.335 -  let
 227.336 -    val name = theory_name thy;
 227.337 -    val Theory (identity', data', ancestry', _) = name_thy (name, ~1) thy;
 227.338 -    val history' = make_history name 0;
 227.339 -    val thy' = vitalize (Theory (identity', data', ancestry', history'));
 227.340 -  in thy' end);
 227.341 +val finish_thy = history_stage (fn _ => finished);
 227.342  
 227.343  
 227.344  (* theory data *)
   228.1 --- a/src/Pure/display.ML	Tue Dec 30 08:18:54 2008 +0100
   228.2 +++ b/src/Pure/display.ML	Tue Dec 30 11:10:01 2008 +0100
   228.3 @@ -213,7 +213,7 @@
   228.4        ||> List.partition (Defs.plain_args o #2 o #1);
   228.5      val rests = restricts |> map (apfst (apfst extern_const)) |> sort_wrt (#1 o #1);
   228.6    in
   228.7 -    [Pretty.strs ("names:" :: Context.names_of thy)] @
   228.8 +    [Pretty.strs ("names:" :: Context.display_names thy)] @
   228.9      [Pretty.strs ["name prefix:", NameSpace.path_of naming],
  228.10        Pretty.big_list "classes:" (map pretty_classrel clsses),
  228.11        pretty_default default,
   229.1 --- a/src/Pure/goal.ML	Tue Dec 30 08:18:54 2008 +0100
   229.2 +++ b/src/Pure/goal.ML	Tue Dec 30 11:10:01 2008 +0100
   229.3 @@ -179,7 +179,7 @@
   229.4      val res =
   229.5        if immediate orelse #maxidx (Thm.rep_cterm stmt) >= 0 orelse not (Future.enabled ())
   229.6        then result ()
   229.7 -      else future_result ctxt' (Future.fork_background result) (Thm.term_of stmt);
   229.8 +      else future_result ctxt' (Future.fork_pri 1 result) (Thm.term_of stmt);
   229.9    in
  229.10      Conjunction.elim_balanced (length props) res
  229.11      |> map (Assumption.export false ctxt' ctxt)
   230.1 --- a/src/Pure/old_goals.ML	Tue Dec 30 08:18:54 2008 +0100
   230.2 +++ b/src/Pure/old_goals.ML	Tue Dec 30 11:10:01 2008 +0100
   230.3 @@ -127,7 +127,7 @@
   230.4  
   230.5  (*Generates the list of new theories when the proof state's theory changes*)
   230.6  fun thy_error (thy,thy') =
   230.7 -  let val names = Context.names_of thy' \\ Context.names_of thy
   230.8 +  let val names = Context.display_names thy' \\ Context.display_names thy
   230.9    in  case names of
  230.10          [name] => "\nNew theory: " ^ name
  230.11        | _       => "\nNew theories: " ^ space_implode ", " names
   231.1 --- a/src/Pure/pure_setup.ML	Tue Dec 30 08:18:54 2008 +0100
   231.2 +++ b/src/Pure/pure_setup.ML	Tue Dec 30 11:10:01 2008 +0100
   231.3 @@ -1,5 +1,4 @@
   231.4  (*  Title:      Pure/pure_setup.ML
   231.5 -    ID:         $Id$
   231.6      Author:     Makarius
   231.7  
   231.8  Pure theory and ML toplevel setup.
   231.9 @@ -28,12 +27,13 @@
  231.10  
  231.11  (* ML toplevel pretty printing *)
  231.12  
  231.13 -install_pp (make_pp ["TaskQueue", "task"] (Pretty.pprint o Pretty.str o TaskQueue.str_of_task));
  231.14 -install_pp (make_pp ["TaskQueue", "group"] (Pretty.pprint o Pretty.str o TaskQueue.str_of_group));
  231.15 +install_pp (make_pp ["Task_Queue", "task"] (Pretty.pprint o Pretty.str o Task_Queue.str_of_task));
  231.16 +install_pp (make_pp ["Task_Queue", "group"] (Pretty.pprint o Pretty.str o Task_Queue.str_of_group));
  231.17  install_pp (make_pp ["Position", "T"] (Pretty.pprint o Pretty.enum "," "{" "}" o
  231.18    map (fn (x, y) => Pretty.str (x ^ "=" ^ y)) o Position.properties_of));
  231.19  install_pp (make_pp ["Thm", "thm"] ProofDisplay.pprint_thm);
  231.20  install_pp (make_pp ["Thm", "cterm"] ProofDisplay.pprint_cterm);
  231.21 +install_pp (make_pp ["Binding", "T"] (Pretty.pprint o Pretty.str o Binding.display));
  231.22  install_pp (make_pp ["Thm", "ctyp"] ProofDisplay.pprint_ctyp);
  231.23  install_pp (make_pp ["Context", "theory"] Context.pprint_thy);
  231.24  install_pp (make_pp ["Context", "theory_ref"] Context.pprint_thy_ref);
   232.1 --- a/src/Pure/pure_thy.ML	Tue Dec 30 08:18:54 2008 +0100
   232.2 +++ b/src/Pure/pure_thy.ML	Tue Dec 30 11:10:01 2008 +0100
   232.3 @@ -322,7 +322,7 @@
   232.4      ("",            typ "var => logic",                Delimfix "_"),
   232.5      ("_DDDOT",      typ "logic",                       Delimfix "..."),
   232.6      ("_constify",   typ "num => num_const",            Delimfix "_"),
   232.7 -    ("_constify",   typ "float => float_const",        Delimfix "_"),
   232.8 +    ("_constify",   typ "float_token => float_const",  Delimfix "_"),
   232.9      ("_indexnum",   typ "num_const => index",          Delimfix "\\<^sub>_"),
  232.10      ("_index",      typ "logic => index",              Delimfix "(00\\<^bsub>_\\<^esub>)"),
  232.11      ("_indexdefault", typ "index",                     Delimfix ""),
   233.1 --- a/src/Pure/theory.ML	Tue Dec 30 08:18:54 2008 +0100
   233.2 +++ b/src/Pure/theory.ML	Tue Dec 30 11:10:01 2008 +0100
   233.3 @@ -68,7 +68,7 @@
   233.4  val copy = Context.copy_thy;
   233.5  
   233.6  fun requires thy name what =
   233.7 -  if Context.exists_name name thy then ()
   233.8 +  if exists (fn thy' => Context.theory_name thy' = name) (thy :: ancestors_of thy) then ()
   233.9    else error ("Require theory " ^ quote name ^ " as an ancestor for " ^ what);
  233.10  
  233.11  
   234.1 --- a/src/Tools/code/code_haskell.ML	Tue Dec 30 08:18:54 2008 +0100
   234.2 +++ b/src/Tools/code/code_haskell.ML	Tue Dec 30 11:10:01 2008 +0100
   234.3 @@ -414,7 +414,10 @@
   234.4                  o NameSpace.explode) modlname;
   234.5          val pathname = Path.append destination filename;
   234.6          val _ = File.mkdir (Path.dir pathname);
   234.7 -      in File.write pathname (Code_Target.code_of_pretty content) end
   234.8 +      in File.write pathname
   234.9 +        ("{-# OPTIONS_GHC -fglasgow-exts #-}\n\n"
  234.10 +          ^ Code_Target.code_of_pretty content)
  234.11 +      end
  234.12    in
  234.13      Code_Target.mk_serialization target NONE
  234.14        (fn NONE => K () o map (Code_Target.code_writeln o snd) | SOME file => K () o map (write_module file))
   235.1 --- a/src/Tools/code/code_ml.ML	Tue Dec 30 08:18:54 2008 +0100
   235.2 +++ b/src/Tools/code/code_ml.ML	Tue Dec 30 11:10:01 2008 +0100
   235.3 @@ -1,5 +1,4 @@
   235.4  (*  Title:      Tools/code/code_ml.ML
   235.5 -    ID:         $Id$
   235.6      Author:     Florian Haftmann, TU Muenchen
   235.7  
   235.8  Serializer for SML and OCaml.
   235.9 @@ -25,17 +24,21 @@
  235.10  val target_OCaml = "OCaml";
  235.11  
  235.12  datatype ml_stmt =
  235.13 -    MLFuns of (string * (typscheme * ((iterm list * iterm) * (thm * bool)) list)) list
  235.14 +    MLExc of string * int
  235.15 +  | MLVal of string * ((typscheme * iterm) * (thm * bool))
  235.16 +  | MLFuns of (string * (typscheme * ((iterm list * iterm) * (thm * bool)) list)) list * string list
  235.17    | MLDatas of (string * ((vname * sort) list * (string * itype list) list)) list
  235.18    | MLClass of string * (vname * ((class * string) list * (string * itype) list))
  235.19    | MLClassinst of string * ((class * (string * (vname * sort) list))
  235.20          * ((class * (string * (string * dict list list))) list
  235.21        * ((string * const) * (thm * bool)) list));
  235.22  
  235.23 -fun stmt_names_of (MLFuns fs) = map fst fs
  235.24 +fun stmt_names_of (MLExc (name, _)) = [name]
  235.25 +  | stmt_names_of (MLVal (name, _)) = [name]
  235.26 +  | stmt_names_of (MLFuns (fs, _)) = map fst fs
  235.27    | stmt_names_of (MLDatas ds) = map fst ds
  235.28 -  | stmt_names_of (MLClass (c, _)) = [c]
  235.29 -  | stmt_names_of (MLClassinst (i, _)) = [i];
  235.30 +  | stmt_names_of (MLClass (name, _)) = [name]
  235.31 +  | stmt_names_of (MLClassinst (name, _)) = [name];
  235.32  
  235.33  
  235.34  (** SML serailizer **)
  235.35 @@ -81,144 +84,159 @@
  235.36           of NONE => pr_tycoexpr fxy (tyco, tys)
  235.37            | SOME (i, pr) => pr pr_typ fxy tys)
  235.38        | pr_typ fxy (ITyVar v) = str ("'" ^ v);
  235.39 -    fun pr_term thm vars fxy (IConst c) =
  235.40 -          pr_app thm vars fxy (c, [])
  235.41 -      | pr_term thm vars fxy (IVar v) =
  235.42 +    fun pr_term is_closure thm vars fxy (IConst c) =
  235.43 +          pr_app is_closure thm vars fxy (c, [])
  235.44 +      | pr_term is_closure thm vars fxy (IVar v) =
  235.45            str (Code_Name.lookup_var vars v)
  235.46 -      | pr_term thm vars fxy (t as t1 `$ t2) =
  235.47 +      | pr_term is_closure thm vars fxy (t as t1 `$ t2) =
  235.48            (case Code_Thingol.unfold_const_app t
  235.49 -           of SOME c_ts => pr_app thm vars fxy c_ts
  235.50 -            | NONE =>
  235.51 -                brackify fxy [pr_term thm vars NOBR t1, pr_term thm vars BR t2])
  235.52 -      | pr_term thm vars fxy (t as _ `|-> _) =
  235.53 +           of SOME c_ts => pr_app is_closure thm vars fxy c_ts
  235.54 +            | NONE => brackify fxy
  235.55 +               [pr_term is_closure thm vars NOBR t1, pr_term is_closure thm vars BR t2])
  235.56 +      | pr_term is_closure thm vars fxy (t as _ `|-> _) =
  235.57            let
  235.58              val (binds, t') = Code_Thingol.unfold_abs t;
  235.59              fun pr ((v, pat), ty) =
  235.60 -              pr_bind thm NOBR ((SOME v, pat), ty)
  235.61 +              pr_bind is_closure thm NOBR ((SOME v, pat), ty)
  235.62                #>> (fn p => concat [str "fn", p, str "=>"]);
  235.63              val (ps, vars') = fold_map pr binds vars;
  235.64 -          in brackets (ps @ [pr_term thm vars' NOBR t']) end
  235.65 -      | pr_term thm vars fxy (ICase (cases as (_, t0))) =
  235.66 +          in brackets (ps @ [pr_term is_closure thm vars' NOBR t']) end
  235.67 +      | pr_term is_closure thm vars fxy (ICase (cases as (_, t0))) =
  235.68            (case Code_Thingol.unfold_const_app t0
  235.69             of SOME (c_ts as ((c, _), _)) => if is_none (syntax_const c)
  235.70 -                then pr_case thm vars fxy cases
  235.71 -                else pr_app thm vars fxy c_ts
  235.72 -            | NONE => pr_case thm vars fxy cases)
  235.73 -    and pr_app' thm vars (app as ((c, (iss, tys)), ts)) =
  235.74 -      if is_cons c then let
  235.75 -        val k = length tys
  235.76 -      in if k < 2 then 
  235.77 -        (str o deresolve) c :: map (pr_term thm vars BR) ts
  235.78 -      else if k = length ts then
  235.79 -        [(str o deresolve) c, Pretty.enum "," "(" ")" (map (pr_term thm vars NOBR) ts)]
  235.80 -      else [pr_term thm vars BR (Code_Thingol.eta_expand k app)] end else
  235.81 +                then pr_case is_closure thm vars fxy cases
  235.82 +                else pr_app is_closure thm vars fxy c_ts
  235.83 +            | NONE => pr_case is_closure thm vars fxy cases)
  235.84 +    and pr_app' is_closure thm vars (app as ((c, (iss, tys)), ts)) =
  235.85 +      if is_cons c then
  235.86 +        let
  235.87 +          val k = length tys
  235.88 +        in if k < 2 then 
  235.89 +          (str o deresolve) c :: map (pr_term is_closure thm vars BR) ts
  235.90 +        else if k = length ts then
  235.91 +          [(str o deresolve) c, Pretty.enum "," "(" ")" (map (pr_term is_closure thm vars NOBR) ts)]
  235.92 +        else [pr_term is_closure thm vars BR (Code_Thingol.eta_expand k app)] end
  235.93 +      else if is_closure c
  235.94 +        then (str o deresolve) c @@ str "()"
  235.95 +      else
  235.96          (str o deresolve) c
  235.97 -          :: (map (pr_dicts BR) o filter_out null) iss @ map (pr_term thm vars BR) ts
  235.98 -    and pr_app thm vars = gen_pr_app pr_app' pr_term syntax_const naming thm vars
  235.99 +          :: (map (pr_dicts BR) o filter_out null) iss @ map (pr_term is_closure thm vars BR) ts
 235.100 +    and pr_app is_closure thm vars = gen_pr_app (pr_app' is_closure) (pr_term is_closure)
 235.101 +      syntax_const naming thm vars
 235.102      and pr_bind' ((NONE, NONE), _) = str "_"
 235.103        | pr_bind' ((SOME v, NONE), _) = str v
 235.104        | pr_bind' ((NONE, SOME p), _) = p
 235.105        | pr_bind' ((SOME v, SOME p), _) = concat [str v, str "as", p]
 235.106 -    and pr_bind thm = gen_pr_bind pr_bind' pr_term thm
 235.107 -    and pr_case thm vars fxy (cases as ((_, [_]), _)) =
 235.108 +    and pr_bind is_closure = gen_pr_bind pr_bind' (pr_term is_closure)
 235.109 +    and pr_case is_closure thm vars fxy (cases as ((_, [_]), _)) =
 235.110            let
 235.111              val (binds, t') = Code_Thingol.unfold_let (ICase cases);
 235.112              fun pr ((pat, ty), t) vars =
 235.113                vars
 235.114 -              |> pr_bind thm NOBR ((NONE, SOME pat), ty)
 235.115 -              |>> (fn p => semicolon [str "val", p, str "=", pr_term thm vars NOBR t])
 235.116 +              |> pr_bind is_closure thm NOBR ((NONE, SOME pat), ty)
 235.117 +              |>> (fn p => semicolon [str "val", p, str "=", pr_term is_closure thm vars NOBR t])
 235.118              val (ps, vars') = fold_map pr binds vars;
 235.119            in
 235.120              Pretty.chunks [
 235.121                [str ("let"), Pretty.fbrk, Pretty.chunks ps] |> Pretty.block,
 235.122 -              [str ("in"), Pretty.fbrk, pr_term thm vars' NOBR t'] |> Pretty.block,
 235.123 +              [str ("in"), Pretty.fbrk, pr_term is_closure thm vars' NOBR t'] |> Pretty.block,
 235.124                str ("end")
 235.125              ]
 235.126            end
 235.127 -      | pr_case thm vars fxy (((td, ty), b::bs), _) =
 235.128 +      | pr_case is_closure thm vars fxy (((td, ty), b::bs), _) =
 235.129            let
 235.130              fun pr delim (pat, t) =
 235.131                let
 235.132 -                val (p, vars') = pr_bind thm NOBR ((NONE, SOME pat), ty) vars;
 235.133 +                val (p, vars') = pr_bind is_closure thm NOBR ((NONE, SOME pat), ty) vars;
 235.134                in
 235.135 -                concat [str delim, p, str "=>", pr_term thm vars' NOBR t]
 235.136 +                concat [str delim, p, str "=>", pr_term is_closure thm vars' NOBR t]
 235.137                end;
 235.138            in
 235.139              (Pretty.enclose "(" ")" o single o brackify fxy) (
 235.140                str "case"
 235.141 -              :: pr_term thm vars NOBR td
 235.142 +              :: pr_term is_closure thm vars NOBR td
 235.143                :: pr "of" b
 235.144                :: map (pr "|") bs
 235.145              )
 235.146            end
 235.147 -      | pr_case thm vars fxy ((_, []), _) = str "raise Fail \"empty case\"";
 235.148 -    fun pr_stmt (MLFuns (funns as (funn :: funns'))) =
 235.149 +      | pr_case is_closure thm vars fxy ((_, []), _) = str "raise Fail \"empty case\"";
 235.150 +    fun pr_stmt (MLExc (name, n)) =
 235.151            let
 235.152 -            val definer =
 235.153 +            val exc_str =
 235.154 +              (ML_Syntax.print_string o NameSpace.base o NameSpace.qualifier) name;
 235.155 +          in
 235.156 +            concat (
 235.157 +              str (if n = 0 then "val" else "fun")
 235.158 +              :: (str o deresolve) name
 235.159 +              :: map str (replicate n "_")
 235.160 +              @ str "="
 235.161 +              :: str "raise"
 235.162 +              :: str "(Fail"
 235.163 +              @@ str (exc_str ^ ")")
 235.164 +            )
 235.165 +          end
 235.166 +      | pr_stmt (MLVal (name, (((vs, ty), t), (thm, _)))) =
 235.167 +          let
 235.168 +            val consts = map_filter
 235.169 +              (fn c => if (is_some o syntax_const) c
 235.170 +                then NONE else (SOME o NameSpace.base o deresolve) c)
 235.171 +                (Code_Thingol.fold_constnames (insert (op =)) t []);
 235.172 +            val vars = reserved_names
 235.173 +              |> Code_Name.intro_vars consts;
 235.174 +          in
 235.175 +            concat [
 235.176 +              str "val",
 235.177 +              (str o deresolve) name,
 235.178 +              str ":",
 235.179 +              pr_typ NOBR ty,
 235.180 +              str "=",
 235.181 +              pr_term (K false) thm vars NOBR t
 235.182 +            ]
 235.183 +          end
 235.184 +      | pr_stmt (MLFuns (funn :: funns, pseudo_funs)) =
 235.185 +          let
 235.186 +            fun pr_funn definer (name, ((vs, ty), eqs as eq :: eqs')) =
 235.187                let
 235.188 -                fun no_args _ (((ts, _), _) :: _) = length ts
 235.189 -                  | no_args ty [] = (length o fst o Code_Thingol.unfold_fun) ty;
 235.190 -                fun mk 0 [] = "val"
 235.191 -                  | mk 0 vs = if (null o filter_out (null o snd)) vs
 235.192 -                      then "val" else "fun"
 235.193 -                  | mk k _ = "fun";
 235.194 -                fun chk (_, ((vs, ty), eqs)) NONE = SOME (mk (no_args ty eqs) vs)
 235.195 -                  | chk (_, ((vs, ty), eqs)) (SOME defi) =
 235.196 -                      if defi = mk (no_args ty eqs) vs then SOME defi
 235.197 -                      else error ("Mixing simultaneous vals and funs not implemented: "
 235.198 -                        ^ commas (map (labelled_name o fst) funns));
 235.199 -              in the (fold chk funns NONE) end;
 235.200 -            fun pr_funn definer (name, ((vs, ty), [])) =
 235.201 +                val vs_dict = filter_out (null o snd) vs;
 235.202 +                val shift = if null eqs' then I else
 235.203 +                  map (Pretty.block o single o Pretty.block o single);
 235.204 +                fun pr_eq definer ((ts, t), (thm, _)) =
 235.205                    let
 235.206 -                    val vs_dict = filter_out (null o snd) vs;
 235.207 -                    val n = length vs_dict + (length o fst o Code_Thingol.unfold_fun) ty;
 235.208 -                    val exc_str =
 235.209 -                      (ML_Syntax.print_string o NameSpace.base o NameSpace.qualifier) name;
 235.210 +                    val consts = map_filter
 235.211 +                      (fn c => if (is_some o syntax_const) c
 235.212 +                        then NONE else (SOME o NameSpace.base o deresolve) c)
 235.213 +                        ((fold o Code_Thingol.fold_constnames) (insert (op =)) (t :: ts) []);
 235.214 +                    val vars = reserved_names
 235.215 +                      |> Code_Name.intro_vars consts
 235.216 +                      |> Code_Name.intro_vars ((fold o Code_Thingol.fold_unbound_varnames)
 235.217 +                           (insert (op =)) ts []);
 235.218                    in
 235.219                      concat (
 235.220                        str definer
 235.221                        :: (str o deresolve) name
 235.222 -                      :: map str (replicate n "_")
 235.223 +                      :: (if member (op =) pseudo_funs name then [str "()"]
 235.224 +                          else pr_tyvar_dicts vs_dict
 235.225 +                            @ map (pr_term (member (op =) pseudo_funs) thm vars BR) ts)
 235.226                        @ str "="
 235.227 -                      :: str "raise"
 235.228 -                      :: str "(Fail"
 235.229 -                      @@ str (exc_str ^ ")")
 235.230 +                      @@ pr_term (member (op =) pseudo_funs) thm vars NOBR t
 235.231                      )
 235.232                    end
 235.233 -              | pr_funn definer (name, ((vs, ty), eqs as eq :: eqs')) =
 235.234 -                  let
 235.235 -                    val vs_dict = filter_out (null o snd) vs;
 235.236 -                    val shift = if null eqs' then I else
 235.237 -                      map (Pretty.block o single o Pretty.block o single);
 235.238 -                    fun pr_eq definer ((ts, t), (thm, _)) =
 235.239 -                      let
 235.240 -                        val consts = map_filter
 235.241 -                          (fn c => if (is_some o syntax_const) c
 235.242 -                            then NONE else (SOME o NameSpace.base o deresolve) c)
 235.243 -                            ((fold o Code_Thingol.fold_constnames) (insert (op =)) (t :: ts) []);
 235.244 -                        val vars = reserved_names
 235.245 -                          |> Code_Name.intro_vars consts
 235.246 -                          |> Code_Name.intro_vars ((fold o Code_Thingol.fold_unbound_varnames)
 235.247 -                               (insert (op =)) ts []);
 235.248 -                      in
 235.249 -                        concat (
 235.250 -                          [str definer, (str o deresolve) name]
 235.251 -                          @ (if null ts andalso null vs_dict
 235.252 -                             then [str ":", pr_typ NOBR ty]
 235.253 -                             else
 235.254 -                               pr_tyvar_dicts vs_dict
 235.255 -                               @ map (pr_term thm vars BR) ts)
 235.256 -                       @ [str "=", pr_term thm vars NOBR t]
 235.257 -                        )
 235.258 -                      end
 235.259 -                  in
 235.260 -                    (Pretty.block o Pretty.fbreaks o shift) (
 235.261 -                      pr_eq definer eq
 235.262 -                      :: map (pr_eq "|") eqs'
 235.263 -                    )
 235.264 -                  end;
 235.265 -            val (ps, p) = split_last (pr_funn definer funn :: map (pr_funn "and") funns');
 235.266 -          in Pretty.chunks (ps @ [Pretty.block ([p, str ";"])]) end
 235.267 +              in
 235.268 +                (Pretty.block o Pretty.fbreaks o shift) (
 235.269 +                  pr_eq definer eq
 235.270 +                  :: map (pr_eq "|") eqs'
 235.271 +                )
 235.272 +              end;
 235.273 +            fun pr_pseudo_fun name = concat [
 235.274 +                str "val",
 235.275 +                (str o deresolve) name,
 235.276 +                str "=",
 235.277 +                (str o deresolve) name,
 235.278 +                str "();"
 235.279 +              ];
 235.280 +            val (ps, p) = split_last (pr_funn "fun" funn :: map (pr_funn "and") funns);
 235.281 +            val pseudo_ps = map pr_pseudo_fun pseudo_funs;
 235.282 +          in Pretty.chunks (ps @ Pretty.block ([p, str ";"]) :: pseudo_ps) end
 235.283       | pr_stmt (MLDatas (datas as (data :: datas'))) =
 235.284            let
 235.285              fun pr_co (co, []) =
 235.286 @@ -245,7 +263,7 @@
 235.287                    );
 235.288              val (ps, p) = split_last
 235.289                (pr_data "datatype" data :: map (pr_data "and") datas');
 235.290 -          in Pretty.chunks (ps @ [Pretty.block ([p, str ";"])]) end
 235.291 +          in Pretty.chunks (ps @| Pretty.block ([p, str ";"])) end
 235.292       | pr_stmt (MLClass (class, (v, (superclasses, classparams)))) =
 235.293            let
 235.294              val w = Code_Name.first_upper v ^ "_";
 235.295 @@ -301,7 +319,7 @@
 235.296                concat [
 235.297                  (str o pr_label_classparam) classparam,
 235.298                  str "=",
 235.299 -                pr_app thm reserved_names NOBR (c_inst, [])
 235.300 +                pr_app (K false) thm reserved_names NOBR (c_inst, [])
 235.301                ];
 235.302            in
 235.303              semicolon ([
 235.304 @@ -374,68 +392,71 @@
 235.305           of NONE => pr_tycoexpr fxy (tyco, tys)
 235.306            | SOME (i, pr) => pr pr_typ fxy tys)
 235.307        | pr_typ fxy (ITyVar v) = str ("'" ^ v);
 235.308 -    fun pr_term thm vars fxy (IConst c) =
 235.309 -          pr_app thm vars fxy (c, [])
 235.310 -      | pr_term thm vars fxy (IVar v) =
 235.311 +    fun pr_term is_closure thm vars fxy (IConst c) =
 235.312 +          pr_app is_closure thm vars fxy (c, [])
 235.313 +      | pr_term is_closure thm vars fxy (IVar v) =
 235.314            str (Code_Name.lookup_var vars v)
 235.315 -      | pr_term thm vars fxy (t as t1 `$ t2) =
 235.316 +      | pr_term is_closure thm vars fxy (t as t1 `$ t2) =
 235.317            (case Code_Thingol.unfold_const_app t
 235.318 -           of SOME c_ts => pr_app thm vars fxy c_ts
 235.319 +           of SOME c_ts => pr_app is_closure thm vars fxy c_ts
 235.320              | NONE =>
 235.321 -                brackify fxy [pr_term thm vars NOBR t1, pr_term thm vars BR t2])
 235.322 -      | pr_term thm vars fxy (t as _ `|-> _) =
 235.323 +                brackify fxy [pr_term is_closure thm vars NOBR t1, pr_term is_closure thm vars BR t2])
 235.324 +      | pr_term is_closure thm vars fxy (t as _ `|-> _) =
 235.325            let
 235.326              val (binds, t') = Code_Thingol.unfold_abs t;
 235.327 -            fun pr ((v, pat), ty) = pr_bind thm BR ((SOME v, pat), ty);
 235.328 +            fun pr ((v, pat), ty) = pr_bind is_closure thm BR ((SOME v, pat), ty);
 235.329              val (ps, vars') = fold_map pr binds vars;
 235.330 -          in brackets (str "fun" :: ps @ str "->" @@ pr_term thm vars' NOBR t') end
 235.331 -      | pr_term thm vars fxy (ICase (cases as (_, t0))) = (case Code_Thingol.unfold_const_app t0
 235.332 +          in brackets (str "fun" :: ps @ str "->" @@ pr_term is_closure thm vars' NOBR t') end
 235.333 +      | pr_term is_closure thm vars fxy (ICase (cases as (_, t0))) = (case Code_Thingol.unfold_const_app t0
 235.334             of SOME (c_ts as ((c, _), _)) => if is_none (syntax_const c)
 235.335 -                then pr_case thm vars fxy cases
 235.336 -                else pr_app thm vars fxy c_ts
 235.337 -            | NONE => pr_case thm vars fxy cases)
 235.338 -    and pr_app' thm vars (app as ((c, (iss, tys)), ts)) =
 235.339 +                then pr_case is_closure thm vars fxy cases
 235.340 +                else pr_app is_closure thm vars fxy c_ts
 235.341 +            | NONE => pr_case is_closure thm vars fxy cases)
 235.342 +    and pr_app' is_closure thm vars (app as ((c, (iss, tys)), ts)) =
 235.343        if is_cons c then
 235.344          if length tys = length ts
 235.345          then case ts
 235.346           of [] => [(str o deresolve) c]
 235.347 -          | [t] => [(str o deresolve) c, pr_term thm vars BR t]
 235.348 +          | [t] => [(str o deresolve) c, pr_term is_closure thm vars BR t]
 235.349            | _ => [(str o deresolve) c, Pretty.enum "," "(" ")"
 235.350 -                    (map (pr_term thm vars NOBR) ts)]
 235.351 -        else [pr_term thm vars BR (Code_Thingol.eta_expand (length tys) app)]
 235.352 +                    (map (pr_term is_closure thm vars NOBR) ts)]
 235.353 +        else [pr_term is_closure thm vars BR (Code_Thingol.eta_expand (length tys) app)]
 235.354 +      else if is_closure c
 235.355 +        then (str o deresolve) c @@ str "()"
 235.356        else (str o deresolve) c
 235.357 -        :: ((map (pr_dicts BR) o filter_out null) iss @ map (pr_term thm vars BR) ts)
 235.358 -    and pr_app thm vars = gen_pr_app pr_app' pr_term syntax_const naming thm vars
 235.359 +        :: ((map (pr_dicts BR) o filter_out null) iss @ map (pr_term is_closure thm vars BR) ts)
 235.360 +    and pr_app is_closure = gen_pr_app (pr_app' is_closure) (pr_term is_closure)
 235.361 +      syntax_const naming
 235.362      and pr_bind' ((NONE, NONE), _) = str "_"
 235.363        | pr_bind' ((SOME v, NONE), _) = str v
 235.364        | pr_bind' ((NONE, SOME p), _) = p
 235.365        | pr_bind' ((SOME v, SOME p), _) = brackets [p, str "as", str v]
 235.366 -    and pr_bind thm = gen_pr_bind pr_bind' pr_term thm
 235.367 -    and pr_case thm vars fxy (cases as ((_, [_]), _)) =
 235.368 +    and pr_bind is_closure = gen_pr_bind pr_bind' (pr_term is_closure)
 235.369 +    and pr_case is_closure thm vars fxy (cases as ((_, [_]), _)) =
 235.370            let
 235.371              val (binds, t') = Code_Thingol.unfold_let (ICase cases);
 235.372              fun pr ((pat, ty), t) vars =
 235.373                vars
 235.374 -              |> pr_bind thm NOBR ((NONE, SOME pat), ty)
 235.375 +              |> pr_bind is_closure thm NOBR ((NONE, SOME pat), ty)
 235.376                |>> (fn p => concat
 235.377 -                  [str "let", p, str "=", pr_term thm vars NOBR t, str "in"])
 235.378 +                  [str "let", p, str "=", pr_term is_closure thm vars NOBR t, str "in"])
 235.379              val (ps, vars') = fold_map pr binds vars;
 235.380 -          in Pretty.chunks (ps @| pr_term thm vars' NOBR t') end
 235.381 -      | pr_case thm vars fxy (((td, ty), b::bs), _) =
 235.382 +          in Pretty.chunks (ps @| pr_term is_closure thm vars' NOBR t') end
 235.383 +      | pr_case is_closure thm vars fxy (((td, ty), b::bs), _) =
 235.384            let
 235.385              fun pr delim (pat, t) =
 235.386                let
 235.387 -                val (p, vars') = pr_bind thm NOBR ((NONE, SOME pat), ty) vars;
 235.388 -              in concat [str delim, p, str "->", pr_term thm vars' NOBR t] end;
 235.389 +                val (p, vars') = pr_bind is_closure thm NOBR ((NONE, SOME pat), ty) vars;
 235.390 +              in concat [str delim, p, str "->", pr_term is_closure thm vars' NOBR t] end;
 235.391            in
 235.392              (Pretty.enclose "(" ")" o single o brackify fxy) (
 235.393                str "match"
 235.394 -              :: pr_term thm vars NOBR td
 235.395 +              :: pr_term is_closure thm vars NOBR td
 235.396                :: pr "with" b
 235.397                :: map (pr "|") bs
 235.398              )
 235.399            end
 235.400 -      | pr_case thm vars fxy ((_, []), _) = str "failwith \"empty case\"";
 235.401 +      | pr_case is_closure thm vars fxy ((_, []), _) = str "failwith \"empty case\"";
 235.402      fun fish_params vars eqs =
 235.403        let
 235.404          fun fish_param _ (w as SOME _) = w
 235.405 @@ -449,7 +470,39 @@
 235.406          val (fished3, _) = Name.variants fished2 Name.context;
 235.407          val vars' = Code_Name.intro_vars fished3 vars;
 235.408        in map (Code_Name.lookup_var vars') fished3 end;
 235.409 -    fun pr_stmt (MLFuns (funns as funn :: funns')) =
 235.410 +    fun pr_stmt (MLExc (name, n)) =
 235.411 +          let
 235.412 +            val exc_str =
 235.413 +              (ML_Syntax.print_string o NameSpace.base o NameSpace.qualifier) name;
 235.414 +          in
 235.415 +            concat (
 235.416 +              str "let"
 235.417 +              :: (str o deresolve) name
 235.418 +              :: map str (replicate n "_")
 235.419 +              @ str "="
 235.420 +              :: str "failwith"
 235.421 +              @@ str exc_str
 235.422 +            )
 235.423 +          end
 235.424 +      | pr_stmt (MLVal (name, (((vs, ty), t), (thm, _)))) =
 235.425 +          let
 235.426 +            val consts = map_filter
 235.427 +              (fn c => if (is_some o syntax_const) c
 235.428 +                then NONE else (SOME o NameSpace.base o deresolve) c)
 235.429 +                (Code_Thingol.fold_constnames (insert (op =)) t []);
 235.430 +            val vars = reserved_names
 235.431 +              |> Code_Name.intro_vars consts;
 235.432 +          in
 235.433 +            concat [
 235.434 +              str "let",
 235.435 +              (str o deresolve) name,
 235.436 +              str ":",
 235.437 +              pr_typ NOBR ty,
 235.438 +              str "=",
 235.439 +              pr_term (K false) thm vars NOBR t
 235.440 +            ]
 235.441 +          end
 235.442 +      | pr_stmt (MLFuns (funn :: funns, pseudo_funs)) =
 235.443            let
 235.444              fun pr_eq ((ts, t), (thm, _)) =
 235.445                let
 235.446 @@ -462,24 +515,12 @@
 235.447                    |> Code_Name.intro_vars ((fold o Code_Thingol.fold_unbound_varnames)
 235.448                        (insert (op =)) ts []);
 235.449                in concat [
 235.450 -                (Pretty.block o Pretty.commas) (map (pr_term thm vars NOBR) ts),
 235.451 +                (Pretty.block o Pretty.commas)
 235.452 +                  (map (pr_term (member (op =) pseudo_funs) thm vars NOBR) ts),
 235.453                  str "->",
 235.454 -                pr_term thm vars NOBR t
 235.455 +                pr_term (member (op =) pseudo_funs) thm vars NOBR t
 235.456                ] end;
 235.457 -            fun pr_eqs name ty [] =
 235.458 -                  let
 235.459 -                    val n = (length o fst o Code_Thingol.unfold_fun) ty;
 235.460 -                    val exc_str =
 235.461 -                      (ML_Syntax.print_string o NameSpace.base o NameSpace.qualifier) name;
 235.462 -                  in
 235.463 -                    concat (
 235.464 -                      map str (replicate n "_")
 235.465 -                      @ str "="
 235.466 -                      :: str "failwith"
 235.467 -                      @@ str exc_str
 235.468 -                    )
 235.469 -                  end
 235.470 -              | pr_eqs _ _ [((ts, t), (thm, _))] =
 235.471 +            fun pr_eqs is_pseudo [((ts, t), (thm, _))] =
 235.472                    let
 235.473                      val consts = map_filter
 235.474                        (fn c => if (is_some o syntax_const) c
 235.475 @@ -491,12 +532,13 @@
 235.476                            (insert (op =)) ts []);
 235.477                    in
 235.478                      concat (
 235.479 -                      map (pr_term thm vars BR) ts
 235.480 +                      (if is_pseudo then [str "()"]
 235.481 +                        else map (pr_term (member (op =) pseudo_funs) thm vars BR) ts)
 235.482                        @ str "="
 235.483 -                      @@ pr_term thm vars NOBR t
 235.484 +                      @@ pr_term (member (op =) pseudo_funs) thm vars NOBR t
 235.485                      )
 235.486                    end
 235.487 -              | pr_eqs _ _ (eqs as (eq as (([_], _), _)) :: eqs') =
 235.488 +              | pr_eqs _ (eqs as (eq as (([_], _), _)) :: eqs') =
 235.489                    Pretty.block (
 235.490                      str "="
 235.491                      :: Pretty.brk 1
 235.492 @@ -506,7 +548,7 @@
 235.493                      :: maps (append [Pretty.fbrk, str "|", Pretty.brk 1]
 235.494                            o single o pr_eq) eqs'
 235.495                    )
 235.496 -              | pr_eqs _ _ (eqs as eq :: eqs') =
 235.497 +              | pr_eqs _ (eqs as eq :: eqs') =
 235.498                    let
 235.499                      val consts = map_filter
 235.500                        (fn c => if (is_some o syntax_const) c
 235.501 @@ -538,11 +580,20 @@
 235.502                  str definer
 235.503                  :: (str o deresolve) name
 235.504                  :: pr_tyvar_dicts (filter_out (null o snd) vs)
 235.505 -                @| pr_eqs name ty eqs
 235.506 +                @| pr_eqs (member (op =) pseudo_funs name) eqs
 235.507                );
 235.508 +            fun pr_pseudo_fun name = concat [
 235.509 +                str "let",
 235.510 +                (str o deresolve) name,
 235.511 +                str "=",
 235.512 +                (str o deresolve) name,
 235.513 +                str "();;"
 235.514 +              ];
 235.515 +            val (ps, p) = split_last (pr_funn "fun" funn :: map (pr_funn "and") funns);
 235.516              val (ps, p) = split_last
 235.517 -              (pr_funn "let rec" funn :: map (pr_funn "and") funns');
 235.518 -          in Pretty.chunks (ps @ [Pretty.block ([p, str ";;"])]) end
 235.519 +              (pr_funn "let rec" funn :: map (pr_funn "and") funns);
 235.520 +            val pseudo_ps = map pr_pseudo_fun pseudo_funs;
 235.521 +          in Pretty.chunks (ps @ Pretty.block ([p, str ";;"]) :: pseudo_ps) end
 235.522       | pr_stmt (MLDatas (datas as (data :: datas'))) =
 235.523            let
 235.524              fun pr_co (co, []) =
 235.525 @@ -569,7 +620,7 @@
 235.526                    );
 235.527              val (ps, p) = split_last
 235.528                (pr_data "type" data :: map (pr_data "and") datas');
 235.529 -          in Pretty.chunks (ps @ [Pretty.block ([p, str ";;"])]) end
 235.530 +          in Pretty.chunks (ps @| Pretty.block ([p, str ";;"])) end
 235.531       | pr_stmt (MLClass (class, (v, (superclasses, classparams)))) =
 235.532            let
 235.533              val w = "_" ^ Code_Name.first_upper v;
 235.534 @@ -613,7 +664,7 @@
 235.535                concat [
 235.536                  (str o deresolve) classparam,
 235.537                  str "=",
 235.538 -                pr_app thm reserved_names NOBR (c_inst, [])
 235.539 +                pr_app (K false) thm reserved_names NOBR (c_inst, [])
 235.540                ];
 235.541            in
 235.542              concat (
 235.543 @@ -721,15 +772,33 @@
 235.544          val base' = if upper then Code_Name.first_upper base else base;
 235.545          val ([base''], nsp') = Name.variants [base'] nsp;
 235.546        in (base'', nsp') end;
 235.547 -    fun add_funs stmts =
 235.548 -      fold_map
 235.549 +    fun rearrange_fun name (tysm as (vs, ty), raw_eqs) =
 235.550 +      let
 235.551 +        val eqs = filter (snd o snd) raw_eqs;
 235.552 +        val (eqs', is_value) = if null (filter_out (null o snd) vs) then case eqs
 235.553 +         of [(([], t), thm)] => if (not o null o fst o Code_Thingol.unfold_fun) ty
 235.554 +            then ([(([IVar "x"], t `$ IVar "x"), thm)], false)
 235.555 +            else (eqs, not (Code_Thingol.fold_constnames
 235.556 +              (fn name' => fn b => b orelse name = name') t false))
 235.557 +          | _ => (eqs, false)
 235.558 +          else (eqs, false)
 235.559 +      in ((name, (tysm, eqs')), is_value) end;
 235.560 +    fun check_kind [((name, (tysm, [(([], t), thm)])), true)] = MLVal (name, ((tysm, t), thm))
 235.561 +      | check_kind [((name, ((vs, ty), [])), _)] =
 235.562 +          MLExc (name, (length o filter_out (null o snd)) vs + (length o fst o Code_Thingol.unfold_fun) ty)
 235.563 +      | check_kind funns =
 235.564 +          MLFuns (map fst funns, map_filter
 235.565 +            (fn ((name, ((vs, _), [(([], _), _)])), _) =>
 235.566 +                  if null (filter_out (null o snd) vs) then SOME name else NONE
 235.567 +              | _ => NONE) funns);
 235.568 +    fun add_funs stmts = fold_map
 235.569          (fn (name, Code_Thingol.Fun (_, stmt)) =>
 235.570 -              map_nsp_fun_yield (mk_name_stmt false name) #>>
 235.571 -                rpair (name, stmt |> apsnd (filter (snd o snd)))
 235.572 +              map_nsp_fun_yield (mk_name_stmt false name)
 235.573 +              #>> rpair (rearrange_fun name stmt)
 235.574            | (name, _) =>
 235.575                error ("Function block containing illegal statement: " ^ labelled_name name)
 235.576          ) stmts
 235.577 -      #>> (split_list #> apsnd MLFuns);
 235.578 +      #>> (split_list #> apsnd check_kind);
 235.579      fun add_datatypes stmts =
 235.580        fold_map
 235.581          (fn (name, Code_Thingol.Datatype (_, stmt)) =>